from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
from datetime import datetime
from datetime import timedelta
import pandas as pd
import numpy as np
class TransdimensionalTachyonCompensator(QCAlgorithm):
month = 0
def Initialize(self):
self.SetStartDate(2020, 1, 1) # Set Start Date
self.SetEndDate(2020, 10, 27)
self.SetCash(100000) # Set Strategy Cash
self.trading_symbols = []
self.UniverseSettings.Resolution = Resolution.Minute
self.AddUniverse(self.CoarseSelectionFunction)
self.lookback_period = 60
self.spy = self.AddEquity("SPY").Symbol
# self.Train(self.DateRules.MonthStart(), self.TimeRules.AfterMarketOpen(self.spy, 0), self.train)
self.Schedule.On(self.DateRules.MonthStart(), self.TimeRules.AfterMarketOpen(self.spy, 0), self.train)
def CoarseSelectionFunction(self, coarse):
if self.Time.month == self.month:
return Universe.Unchanged
self.month = self.Time.month
sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
self.trading_symbols = [ x.Symbol for x in sortedByDollarVolume if x.HasFundamentalData ][:20]
return self.trading_symbols
def train(self):
if not self.trading_symbols: return
price_history = self.History(self.trading_symbols , self.lookback_period , Resolution.Daily)
symbol1 = [self.trading_symbols[0] for i in range(self.lookback_period)]
symbol2 = [self.trading_symbols[1] for i in range(self.lookback_period)]
symbol3 = [self.trading_symbols[2] for i in range(self.lookback_period)]
symbol4 = [self.trading_symbols[3] for i in range(self.lookback_period)]
symbol5 = [self.trading_symbols[4] for i in range(self.lookback_period)]
symbol6 = [self.trading_symbols[5] for i in range(self.lookback_period)]
symbol7 = [self.trading_symbols[6] for i in range(self.lookback_period)]
symbol8 = [self.trading_symbols[7] for i in range(self.lookback_period)]
symbol9 = [self.trading_symbols[8] for i in range(self.lookback_period)]
symbol10 = [self.trading_symbols[9] for i in range(self.lookback_period)]
symbol11 = [self.trading_symbols[10] for i in range(self.lookback_period)]
symbol12 = [self.trading_symbols[11] for i in range(self.lookback_period)]
symbol13 = [self.trading_symbols[12] for i in range(self.lookback_period)]
symbol14 = [self.trading_symbols[13] for i in range(self.lookback_period)]
symbol15 = [self.trading_symbols[14] for i in range(self.lookback_period)]
symbol16 = [self.trading_symbols[15] for i in range(self.lookback_period)]
symbol17 = [self.trading_symbols[16] for i in range(self.lookback_period)]
symbol18 = [self.trading_symbols[17] for i in range(self.lookback_period)]
symbol19 = [self.trading_symbols[18] for i in range(self.lookback_period)]
symbol20 = [self.trading_symbols[19] for i in range(self.lookback_period)]
close_list = []
open_list = []
high_list = []
low_list = []
volume_list = []
date_list = [ str(price_history.index[i][1]).split(" ")[0] for i in range(price_history.shape[0]) ]
for i in range(price_history.shape[0]):
close_list.append(price_history.close.iloc[i])
open_list.append(price_history.open.iloc[i])
high_list.append(price_history.high.iloc[i])
low_list.append(price_history.low.iloc[i])
volume_list.append(price_history.volume.iloc[i])
d = {'symbol': symbol1 + symbol2 + symbol3 + symbol4 + symbol5 + symbol6 + symbol7 + symbol8 + symbol9 \
+ symbol10 + symbol11 + symbol12 + symbol13 + symbol14 + symbol15 + symbol16 + symbol17 + symbol18 + \
symbol19 + symbol20,
'datetime': date_list,
'close': close_list,
'high': high_list,
'low': low_list,
'open': open_list,
'volume': volume_list
}
self.price_data = pd.DataFrame(data=d)
self.price_data = self.price_data[['symbol','datetime','close','high','low','open','volume']]
# sort the values by symbol and then date
self.price_data.sort_values(by = ['symbol','datetime'], inplace = True)
# calculate the change in price
self.price_data['change_in_price'] = self.price_data['close'].diff()
# identify rows where the symbol changes
mask = self.price_data['symbol'] != self.price_data['symbol'].shift(1)
# For those rows, let's make the value null
self.price_data['change_in_price'] = np.where(mask == True, np.nan, self.price_data['change_in_price'])
# print the rows that have a null value, should only be 5
self.price_data[self.price_data.isna().any(axis = 1)]
# Calculate the 14 day RSI
n = 14
# First make a copy of the data frame twice
up_df, down_df = self.price_data[['symbol','change_in_price']].copy(), self.price_data[['symbol','change_in_price']].copy()
# For up days, if the change is less than 0 set to 0.
up_df.loc['change_in_price'] = up_df.loc[(up_df['change_in_price'] < 0), 'change_in_price'] = 0
# For down days, if the change is greater than 0 set to 0.
down_df.loc['change_in_price'] = down_df.loc[(down_df['change_in_price'] > 0), 'change_in_price'] = 0
# We need change in price to be absolute.
down_df['change_in_price'] = down_df['change_in_price'].abs()
# Calculate the EWMA (Exponential Weighted Moving Average), meaning older values are given less weight compared to newer values.
ewma_up = up_df.groupby('symbol')['change_in_price'].transform(lambda x: x.ewm(span = n).mean())
ewma_down = down_df.groupby('symbol')['change_in_price'].transform(lambda x: x.ewm(span = n).mean())
Hi guys, I've been trying to apply a lambda transform to my "change in price" column values, sorted by symbol values.
However, I'm being thrown the error:
"2020-04-01 09:31:00 Runtime Error: In Scheduled Event 'MonthStart: SPY: 0 min after MarketOpen', TypeError : Cannot get managed object
at train in main.py:line 160 :: ewma_up = up_df.groupby(\'symbol\')[\'change_in_price\'].transform(lambda x: x.ewm(span = n).mean())
TypeError : Cannot get managed object"
This does not seem to be a common issue as well, and the solutions provided in other threads do not help for me.
Any help will be greatly appreciated, thank you!
Adam W
I have not run the code, but this part here looks a bit strange
# For up days, if the change is less than 0 set to 0. up_df.loc['change_in_price'] = up_df.loc[(up_df['change_in_price'] < 0), 'change_in_price'] = 0 # For down days, if the change is greater than 0 set to 0. down_df.loc['change_in_price'] = down_df.loc[(down_df['change_in_price'] > 0), 'change_in_price'] = 0
Maybe print out the shape/first few rows of the data structures to make sure they are what you expect. You can also just do something like
up_df['change_in_price'] = up_df['change_in_price'].apply(lambda x: max(x, 0)) down_df['change_in_price'] = down_df['change_in_price'].apply(lambda x: min(0, x))
Derek Melchin
Hi Wei,
As explained above, this is an issue related to the handling of the pandas objects. To simplify this algorithm, we can just use two ExponentialMovingAverage indicators inside the `train` method. For example,
emas_by_symbol[symbol] = {'up': ExponentialMovingAverage(14), 'down': ExponentialMovingAverage(14)} for time, price_change in price_changes[symbol].iteritems(): emas_by_symbol[symbol]['up'].Update(time, price_change if price_change > 0 else 0) emas_by_symbol[symbol]['down'].Update(time, abs(price_change) if price_change < 0 else 0)
See the attached backtest for reference. To extend this algorithm so that we can have access to historical indicator values, we just need to add some RollingWindows.
Best,
Derek Melchin
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Wei li
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!