| Overall Statistics |
|
Total Trades 3591 Average Win 0.34% Average Loss -0.26% Compounding Annual Return 0.675% Drawdown 33.800% Expectancy 0.009 Net Profit 0.726% Sharpe Ratio 0.161 Probabilistic Sharpe Ratio 16.847% Loss Rate 56% Win Rate 44% Profit-Loss Ratio 1.28 Alpha -0.082 Beta 0.585 Annual Standard Deviation 0.285 Annual Variance 0.081 Information Ratio -0.615 Tracking Error 0.281 Treynor Ratio 0.078 Total Fees $77770.85 |
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 custom function
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.UniverseSettings.Resolution = Resolution.Minute
self.AddUniverse(self.CoarseSelectionFunction)
self.SetBrokerageModel(AlphaStreamsBrokerageModel())
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
self.SetExecution(ImmediateExecutionModel())
self.AddEquity('SPY')
self.SetBenchmark('SPY')
self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.AfterMarketOpen("SPY", 5), self.Recalibrate)
self.symbols = []
def CoarseSelectionFunction(self, coarse):
sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
return [ x.Symbol for x in sortedByDollarVolume ][:100]
def Recalibrate(self):
insights = [Insight.Price(symbol, timedelta(5), InsightDirection.Up, 0.03)
for symbol in self.symbols]
self.EmitInsights(insights)
def OnSecuritiesChanged(self, changes):
symbols = [x.Symbol for x in self.ActiveSecurities.Values
if x.Symbol not in changes.RemovedSecurities]
qb = self
# Copied from research notebook
#---------------------------------------------------------------------------
# Fetch history
history = qb.History(symbols, 150, Resolution.Hour)
# Get hourly returns
returns = history.unstack(level = 1).close.transpose().pct_change().dropna()
# Get 5 assets with least overall correlation
selected = GetUncorrelatedAssets(returns, 5)
#---------------------------------------------------------------------------
# Add to symbol dictionary for use in Recalibrate
self.symbols = [symbol for symbol, corr_rank in selected]
# Emit flat insights for invested securities that were not selected above
insights = [Insight.Price(x.Symbol, timedelta(5), InsightDirection.Flat)
for x in self.Portfolio.Values if x.Invested and x.Symbol not in self.symbols]
self.EmitInsights(insights)