Overall Statistics |
Total Trades 771 Average Win 0.08% Average Loss -0.10% Compounding Annual Return 10.186% Drawdown 17.900% Expectancy 0.361 Net Profit 14.018% Sharpe Ratio 0.813 Probabilistic Sharpe Ratio 39.679% Loss Rate 26% Win Rate 74% Profit-Loss Ratio 0.85 Alpha 0.023 Beta 0.47 Annual Standard Deviation 0.138 Annual Variance 0.019 Information Ratio -0.503 Tracking Error 0.155 Treynor Ratio 0.239 Total Fees $1924.95 |
import numpy as np import pandas as pd def GetUncorrelatedAssets(returns, num_assets): # Get correlation correlation = returns.corr() # Find assets with lowest mean correlation, scaled by STD selected = [] for index, row in correlation.iteritems(): corr_rank = row.abs().mean()/row.abs().std() selected.append((index, corr_rank)) # Sort and take the top num_assets selected = sorted(selected, key = lambda x: x[1])[:num_assets] return selected
import pandas as pd from GetUncorrelatedAssets import GetUncorrelatedAssets class ModulatedOptimizedEngine(QCAlgorithm): def Initialize(self): self.SetStartDate(2019, 1, 1) # Set Start Date self.SetCash(1000000) # Set Strategy Cash self.AddEquity("SPY", Resolution.Minute) self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.AfterMarketOpen("SPY", 5), self.Recalibrate) self.UniverseSettings.Resolution = Resolution.Minute self.tickers = ["SPY", "FXI", "EWI", "VGK", "GLD", "SHY"] self.symbols = [Symbol.Create(t, SecurityType.Equity, Market.USA) for t in self.tickers] self.AddUniverseSelection( ManualUniverseSelectionModel(self.symbols) ) self.Settings.RebalancePortfolioOnInsightChanges = False self.Settings.RebalancePortfolioOnSecurityChanges = False self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.SetExecution(ImmediateExecutionModel()) def Recalibrate(self): history = self.History(self.symbols, 122, Resolution.Daily) returns = history.unstack(level = 1).close.transpose().pct_change().dropna() rolling=10 tickers=self.tickers corr_history = [] for i in range(rolling, len(returns), 1): correlations = {} correlations['time'] = returns.index[i] spy = returns["SPY R735QTJ8XC9X"][i-rolling:i] for j in range(0, len(tickers)): asset = returns[returns.columns[j]][i-rolling:i] correlations[returns.columns[j]] = spy.corr(asset) corr_history.append(correlations) latest = pd.DataFrame(corr_history[len(corr_history)-1], index=[corr_history[len(corr_history)-1]['time']] ) # Get the minimum of the most recent row. asset = "" minimum = 2 for c in latest.columns: if c == "time": continue if latest[c][0] < minimum: asset = c minimum = latest[c][0] #most uncorrelated uncor = asset correlation = abs(minimum) spyweight = 1 - correlation insights = [Insight.Price("SPY", timedelta(5), InsightDirection.Up, None, None, None, spyweight), Insight.Price(self.Symbol(uncor), timedelta(5), InsightDirection.Up, None, None, None, correlation)] self.EmitInsights(insights)