| 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 selectedimport 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)