Overall Statistics |
Total Trades 2185 Average Win 0.35% Average Loss -0.22% Compounding Annual Return 62.795% Drawdown 9.600% Expectancy 0.319 Net Profit 77.318% Sharpe Ratio 2.284 Probabilistic Sharpe Ratio 86.551% Loss Rate 48% Win Rate 52% Profit-Loss Ratio 1.54 Alpha 0.512 Beta 0.135 Annual Standard Deviation 0.235 Annual Variance 0.055 Information Ratio 1.026 Tracking Error 0.339 Treynor Ratio 3.967 Total Fees $2273.22 Estimated Strategy Capacity $2300000.00 |
from sklearn.linear_model import LinearRegression import numpy as np import pandas as pd class CalibratedHorizontalThrustAssembly(QCAlgorithm): def Initialize(self): self.SetTimeZone("America/New_York") self.SetStartDate(2020, 1, 1) # self.SetEndDate(2020,2,5) self.SetCash(100000) self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) self.AddEquity("SPY", Resolution.Minute) self.SetBenchmark("SPY") # self.AddAlpha( EmaCrossAlphaModel() ) self.UniverseSettings.Resolution = Resolution.Minute self.AddUniverse(self.CoarseSelectionFilter, self.SelectFine) self.Schedule.On(self.DateRules.Every(DayOfWeek.Wednesday), self.TimeRules.At(12, 15), self.handle_trade) self.betas = [] self.SetPortfolioConstruction( InsightWeightingPortfolioConstructionModel() ) self.SetExecution( ImmediateExecutionModel() ) self.SetExecution( StandardDeviationExecutionModel( deviations = 1, period = 60, resolution=Resolution.Minute ) ) # self.SetRiskManagement(TrailingStopRiskManagementModel()) def CoarseSelectionFilter(self, coarse): sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True) filteredByPrice = [x.Symbol for x in sortedByDollarVolume if x.Price > 10 and x.HasFundamentalData == True] return filteredByPrice[:10] def beta(self, asset_return, market_return): asset_return = np.array(asset_return, dtype=np.float32) market_return = np.array(market_return, dtype=np.float32) corr = np.cov(asset_return, market_return)[0][1]/(np.std(asset_return)*np.std(market_return)) return (np.cov(asset_return, market_return)[0][1]/np.var(market_return))*abs(1/corr) def merge_DataFrame_to_timeindex(self, array_1, array_2): array_1["time"] = pd.to_datetime(array_1.index, unit='s').to_frame() array_2["time.two"] = pd.to_datetime(array_2.index, unit='s').to_frame() data = pd.concat([array_1, array_2], axis=1).dropna() array_1 = data.iloc[:, 0] array_2 = data.iloc[:, 1] return array_1, array_2 def SelectFine(self, fine): beta_values = {} for x in fine: ticker = x.Symbol market = self.History(["SPY"], 200, Resolution.Daily) market = market.loc[("SPY"), "close"] df_multi = self.History(ticker, 200, Resolution.Daily) df_single = df_multi.loc[ticker, "close"] df_single, market = self.merge_DataFrame_to_timeindex(df_single,market) beta_values[x] = self.beta(df_single, market) sorted_by_beta = sorted(beta_values, key = lambda x: beta_values[x]) sorted_by_beta = [i.Symbol for i in sorted_by_beta] window = int(self.GetParameter("window")) self.betas = sorted_by_beta return sorted_by_beta def OnSecuritiesChanged(self, changes): self.changes = changes for security in changes.AddedSecurities: self.AddEquity(security.Symbol) def handle_trade(self): weight_insight = 0.20 insights_long = [] for security in self.betas[0:4]: insights_long.append(Insight.Price(security, timedelta(5), InsightDirection.Down, None, None, None, weight_insight)) self.EmitInsights(Insight.Group(insights_long)) insights_short = [] for security in self.betas[-5:]: insights_short.append(Insight.Price(security, timedelta(5), InsightDirection.Up, None, None, None, weight_insight)) self.EmitInsights(Insight.Group(insights_short)) def handle_trade_sell(self): invested = [] for security in self.betas: if self.Portfolio[security].Invested == False: invested.append(security) portfolio_invested = [x.Symbol.Value for x in self.Portfolio.Values if x.Invested] deinvest_list = np.setdiff1d(invested, portfolio_invested) insights_sell = [] if not len(deinvest_list) == 0: for deinvest in deinvest_list: self.Debug(deinvest) self.Liquidate(str(deinvest)) #insights_sell.append(Insight.Price(str(deinvest), timedelta(3), InsightDirection.Flat)) #self.EmitInsights(Insight.Group(insights_sell)) def OnData(self, data): pass
from sklearn.linear_model import LinearRegression import numpy as np import pandas as pd class CalibratedHorizontalThrustAssembly(QCAlgorithm): def Initialize(self): self.SetTimeZone("America/New_York") self.SetStartDate(2017, 1, 1) # self.SetEndDate(2020,2,5) self.SetCash(100000) self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) self.AddEquity("SPY", Resolution.Hour) self.UniverseSettings.Resolution = Resolution.Hour self.AddUniverse(self.CoarseSelectionFilter, self.SelectFine) self.Schedule.On(self.DateRules.Every(DayOfWeek.Wednesday), self.TimeRules.At(10, 0), self.handle_trade) self.betas = [] self.wait = True # self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(0.02)) def CoarseSelectionFilter(self, coarse): sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True) filteredByPrice = [x.Symbol for x in sortedByDollarVolume if x.Price > 10 and x.HasFundamentalData == True] return filteredByPrice[:40] def beta(self, asset_return, market_return): asset_return = np.array(asset_return, dtype=np.float32) market_return = np.array(market_return, dtype=np.float32) return np.cov(asset_return, market_return)[0][1]/np.var(market_return) def merge_DataFrame_to_timeindex(self, array_1, array_2): array_1["time"] = pd.to_datetime(array_1.index, unit='s').to_frame() array_2["time.two"] = pd.to_datetime(array_2.index, unit='s').to_frame() data = pd.concat([array_1, array_2], axis=1).dropna() array_1 = data.iloc[:, 0] array_2 = data.iloc[:, 1] return array_1, array_2 def SelectFine(self, fine): beta_values = {} for x in fine: ticker = x.Symbol market = self.History(["SPY"], 20, Resolution.Daily) market = market.loc[("SPY"), "close"] df_multi = self.History(ticker, 20, Resolution.Daily) df_single = df_multi.loc[ticker, "close"] df_single, market = self.merge_DataFrame_to_timeindex(df_single,market) beta_values[x] = self.beta(df_single, market) sorted_by_beta = sorted(beta_values, key = lambda x: beta_values[x]) sorted_by_beta = [i.Symbol for i in sorted_by_beta] self.betas = sorted_by_beta[-20:] return sorted_by_beta[-20:] def OnSecuritiesChanged(self, changes): self.changes = changes for security in changes.AddedSecurities: self.AddEquity(security.Symbol) def handle_trade(self): invested = [] for security in self.betas: if self.Portfolio[security].Invested == False: weight = 1 / 20 self.SetHoldings(security, weight) invested.append(security) portfolio_invested = [x.Symbol.Value for x in self.Portfolio.Values if x.Invested] deinvest_list = np.setdiff1d(invested, portfolio_invested) if self.wait == False: if not len(deinvest_list) == 0: for deinvest in deinvest_list: self.Liquidate(str(deinvest)) self.wait = False def OnData(self, data): pass