Overall Statistics |
Total Orders 9720 Average Win 0.10% Average Loss -0.09% Compounding Annual Return 8.752% Drawdown 22.900% Expectancy 0.198 Start Equity 100000 End Equity 169113.25 Net Profit 69.113% Sharpe Ratio 0.312 Sortino Ratio 0.313 Probabilistic Sharpe Ratio 8.261% Loss Rate 45% Win Rate 55% Profit-Loss Ratio 1.19 Alpha 0.005 Beta 0.421 Annual Standard Deviation 0.121 Annual Variance 0.015 Information Ratio -0.293 Tracking Error 0.137 Treynor Ratio 0.089 Total Fees $9827.69 Estimated Strategy Capacity $890000.00 Lowest Capacity Asset SST V2245V5VOQQT Portfolio Turnover 16.80% |
# region imports from AlgorithmImports import * # endregion import numpy as np import pandas as pd from keras.layers import LSTM from keras.layers import Dense from keras.layers import Dropout from keras.models import Sequential from sklearn.preprocessing import MinMaxScaler class MyLSTM: def __init__(self): self.model = None self.scaler = MinMaxScaler(feature_range = (0, 1)) def ProcessData(self, data, n = 60): # Split the data training_data = data[:1260] test_data = data[1260:] # Transform data training_data_array = np.array(training_data).reshape((len(training_data), 1)) training_data_scaled = self.scaler.fit_transform(training_data_array) # Get features and labels features_set = [] labels = [] for i in range(60, 1260): features_set.append(training_data_scaled[i-60:i, 0]) labels.append(training_data_scaled[i, 0]) features_set, labels = np.array(features_set), np.array(labels) features_set = np.reshape(features_set, (features_set.shape[0], features_set.shape[1], 1)) return features_set, labels, training_data, test_data def CreateModel(self, features_set, labels): # Create Model self.model = Sequential() self.model.add(LSTM(units = 50, return_sequences=True, input_shape=(features_set.shape[1], 1))) self.model.add(Dropout(0.2)) self.model.add(LSTM(units=50, return_sequences=True)) self.model.add(Dropout(0.2)) self.model.add(LSTM(units=50, return_sequences=True)) self.model.add(Dropout(0.2)) self.model.add(LSTM(units=50)) self.model.add(Dropout(0.2)) self.model.add(Dense(units = 1)) self.model.compile(optimizer = 'adam', loss = 'mean_squared_error') def FitModel(self, features_set, labels): self.model.fit(features_set, labels, epochs = 50, batch_size = 32) def PredictFromModel(self, test_data): test_inputs = test_data[-80:].values test_inputs = test_inputs.reshape(-1,1) test_inputs = self.scaler.transform(test_inputs) test_features = [] for i in range(60, 80): test_features.append(test_inputs[i-60:i, 0]) test_features = np.array(test_features) test_features = np.reshape(test_features, (test_features.shape[0], test_features.shape[1], 1)) predictions = self.model.predict(test_features) predictions = self.scaler.inverse_transform(predictions) return predictions
# region imports from AlgorithmImports import * # endregion from MyLSTM import MyLSTM class MultidimensionalHorizontalFlange(QCAlgorithm): def Initialize(self): self.SetStartDate(2019, 1, 4) # Set Start Date self.SetCash(100000) # Set Strategy Cash self.SetBrokerageModel(AlphaStreamsBrokerageModel()) self.SetExecution(ImmediateExecutionModel()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.UniverseSettings.Resolution = Resolution.Minute self.SetUniverseSelection(LiquidETFUniverse()) # Helper dictionaries self.macro_symbols = {'Bull' : Symbol.Create('SPY', SecurityType.Equity, Market.USA)} self.models = {'Bull': None, 'Bear': None} # Use Train() method to avoid runtime error self.Train(self.TrainMyModel) self.Train(self.DateRules.MonthEnd(), self.TimeRules.At(8,0), self.TrainMyModel) # Schedule prediction and plotting self.AddEquity('SPY') self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.AfterMarketOpen('SPY', 5), self.Predict) self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.AfterMarketOpen('SPY', 6), self.PlotMe) # Create custom charts prediction = Chart('Prediction Plot') prediction.AddSeries(Series('Actual Bull', SeriesType.Line, 0)) prediction.AddSeries(Series('Predicted Bull', SeriesType.Line, 0)) prediction.AddSeries(Series('Actual Bear', SeriesType.Line, 1)) prediction.AddSeries(Series('Predicted Bear', SeriesType.Line, 1)) def TrainMyModel(self): qb = self # Fetch history history = qb.History([symbol for key, symbol in self.macro_symbols.items()], 1280, Resolution.Daily) # Iterate over macro symbols for key, symbol in self.macro_symbols.items(): # Initialize LSTM class instance lstm = MyLSTM() # Prepare data features_set, labels, training_data, test_data = lstm.ProcessData(history.loc[symbol].close) # Build model layers lstm.CreateModel(features_set, labels) # Fit model lstm.FitModel(features_set, labels) # Add LSTM class to dictionary to store later self.models[key] = lstm def Predict(self): delta = {} qb = self for key, symbol in self.macro_symbols.items(): # Fetch LSTM class lstm = self.models[key] # Fetch history history = qb.History([symbol for key, symbol in self.macro_symbols.items()], 80, Resolution.Daily) # Predict predictions = lstm.PredictFromModel(history.loc[symbol].close) # Grab latest prediction and calculate if predict symbol to go up or down delta[key] = ( predictions[-1] / self.Securities[symbol].Price ) - 1 # Plot prediction self.Plot('Prediction Plot', f'Predicted {key}', predictions[-1]) insights = [] # Iterate over macro symbols for key, change in delta.items(): if key == 'Bull': insights += [Insight.Price(symbol, timedelta(1), InsightDirection.Up if change > 0 else InsightDirection.Flat) for symbol in LiquidETFUniverse.SP500Sectors.Long if self.Securities.ContainsKey(symbol)] insights += [Insight.Price(symbol, timedelta(1), InsightDirection.Up if change > 0 else InsightDirection.Flat) for symbol in LiquidETFUniverse.Treasuries.Inverse if self.Securities.ContainsKey(symbol)] insights += [Insight.Price(symbol, timedelta(1), InsightDirection.Flat if change > 0 else InsightDirection.Up) for symbol in LiquidETFUniverse.Treasuries.Long if self.Securities.ContainsKey(symbol)] self.EmitInsights(insights) def PlotMe(self): # Plot current price of symbols to match against prediction for key, symbol in self.macro_symbols.items(): self.Plot('Prediction Plot', f'Actual {key}', self.Securities[symbol].Price)