def train_lgb_model(future_name): # Data munging df = pd.read_csv(f"./tickerData/{future_name}.txt") # Limit to 31st Dec 2019 data df['DATE'] = pd.to_datetime(df['DATE'], format='%Y%m%d') df = df[df['DATE'] <= '2019-12-31'] df['ADI'] = ADI(df['HIGH'], df['LOW'], df['CLOSE'], df['VOL']) # Volume df['WilliamsR'] = WilliamsR(df['HIGH'], df['LOW'], df['CLOSE']) # Momentum BBs = BB(df['CLOSE'], 10) df['BB_high_crosses'] = BBs[0] # Volatility df['BB_low_crosses'] = BBs[1] # Volatility df['CCI'] = CCI(df['HIGH'], df['LOW'], df['CLOSE'], 10) # Trend df['label'] = np.where(df['CLOSE'].shift(periods=-1) - df['CLOSE'] < 0, -1, 1) # If change is too small, don't take position returns = abs(df['CLOSE'].shift(periods=-1) - df['CLOSE']) change_limit = 0.5 * returns.mean() df.loc[abs(df['CLOSE'].shift(periods=-1) - df['CLOSE']) < change_limit, 'label'] = 0 # Assume stocks have pacf of 2-timestep significance df['LAG_1'] = df['CLOSE'].shift(periods=1) df['LAG_2'] = df['CLOSE'].shift(periods=2) df['LABEL_var'] = df['CLOSE'].shift(periods=-1) data = df.iloc[2:][[ 'OPEN', 'HIGH', 'LOW', 'CLOSE', 'VOL', 'ADI', 'WilliamsR', 'BB_high_crosses', 'BB_low_crosses', 'CCI', 'LAG_1', 'LAG_2', 'label' ]] # Split test-train set train_df, test_df = train_test_split(data, test_size=0.2, shuffle=False) train_X = train_df[[ 'OPEN', 'HIGH', 'LOW', 'CLOSE', 'VOL', 'ADI', 'WilliamsR', 'BB_high_crosses', 'BB_low_crosses', 'CCI', 'LAG_1', 'LAG_2' ]].to_numpy() train_Y = train_df['label'].to_numpy() test_X = test_df[[ 'OPEN', 'HIGH', 'LOW', 'CLOSE', 'VOL', 'ADI', 'WilliamsR', 'BB_high_crosses', 'BB_low_crosses', 'CCI', 'LAG_1', 'LAG_2' ]].to_numpy() test_Y = test_df['label'].to_numpy() # Create lgb model lgb_clf = lgb.LGBMClassifier(objective='multiclass', num_leaves=75, learning_rate=0.05, max_depth=10, n_estimators=100) lgb_clf.fit(train_X, train_Y, eval_set=[(test_X, test_Y)], early_stopping_rounds=50, verbose=False) test_accuracy = np.sum(lgb_clf.predict(test_X) == test_Y) / len(test_Y) if test_accuracy > 0.65: lgb_clf.booster_.save_model(f'./data/lgb_models/{future_name}_model') print( f"Successfully trained {future_name}. Test accuracy: {test_accuracy:.3f}" ) print(f"Saved as {future_name}_model under /data/lgb_models.")
def test_run(): Traindates = pd.date_range('2008-1-1', '2009-12-31') TestDates = pd.date_range('2010-1-1', '2011-12-31') syms = ['AAPL'] prices_train = get_data(syms, Traindates) prices_test = get_data(syms, TestDates) prices_train = prices_train[syms] prices_test = prices_test[syms] bb_train = BB(prices_train, lookback=20) bb_train = bb_train.fillna(method='bfill') bb_test = BB(prices_test, lookback=20) bb_test = bb_test.fillna(method='bfill') macd_train = MACD(prices_train) macd_test = MACD(prices_test) rsi_train = RSI(prices_train, lookback=14) rsi_test = RSI(prices_test, lookback=14) df_train = pd.concat([prices_train, bb_train, macd_train, rsi_train], axis=1) df_train = df_train.fillna(method='bfill') df_test = pd.concat([prices_test, bb_test, macd_test, rsi_test], axis=1) df_test = df_test.fillna(method='bfill') indicators_train = pd.DataFrame(columns=[ 'MACD_ZERO', 'MACD_SIGNAL', 'ACROSS_BAND', 'BB_value', 'RSI', 'Decision' ]) indicators_test = pd.DataFrame(columns=[ 'MACD_ZERO', 'MACD_SIGNAL', 'ACROSS_BAND', 'BB_value', 'RSI', 'Decision' ]) indicators_train['BB_value'] = (df_train[syms[0]] - bb_train['Middle Band'] ) / (bb_train['Upper Band'] - bb_train['Middle Band']) indicators_train['MACD_ZERO'] = macd_train['MACD Line'] indicators_train['MACD_SIGNAL'] = macd_train['Signal Line'] indicators_train['ACROSS_BAND'] = bb_train['Middle Band'] indicators_train['RSI'] = rsi_train['RSI'] indicators_train = (indicators_train - indicators_train.mean(axis=0) ) / indicators_train.std(axis=0) indicators_test['BB_value'] = ( df_test[syms[0]] - bb_test['Middle Band']) / (bb_test['Upper Band'] - bb_test['Middle Band']) indicators_test['MACD_ZERO'] = macd_test['MACD Line'] indicators_test['MACD_SIGNAL'] = macd_test['Signal Line'] indicators_test['ACROSS_BAND'] = bb_test['Middle Band'] indicators_test['RSI'] = rsi_test['RSI'] indicators_test = (indicators_test - indicators_test.mean(axis=0) ) / indicators_test.std(axis=0) YBUY = 0.05 YSELL = -0.05 for (i_row, row), (i_future, future) in zip(df_train.iterrows(), df_train.shift(-21).iterrows()): if (future[syms[0]] / row[syms[0]] - 1 ) > YBUY: # if 21 days return exceed YBUY, then BUY Decision=1 indicators_train.ix[i_row, 'Decision'] = 1 if ( future[syms[0]] / row[syms[0]] - 1 ) < YSELL: # if 21 days return less than YSELL, then SELL Decision=-1 indicators_train.ix[i_row, 'Decision'] = -1 indicators_train = indicators_train.fillna(0) for (i_row, row), (i_future, future) in zip(df_test.iterrows(), df_test.shift(-21).iterrows()): if (future[syms[0]] / row[syms[0]] - 1 ) > YBUY: # if 21 days return exceed YBUY, then BUY Decision=1 indicators_test.ix[i_row, 'Decision'] = 1 if ( future[syms[0]] / row[syms[0]] - 1 ) < YSELL: # if 21 days return less than YSELL, then SELL Decision=-1 indicators_test.ix[i_row, 'Decision'] = -1 indicators_test = indicators_test.fillna(0) #print indicators file_dir_train = os.path.join('orders', 'indicators_train.csv') file_dir_test = os.path.join('orders', 'indicators_test.csv') indicators_train.to_csv(file_dir_train, header=False, index=False) indicators_test.to_csv(file_dir_test, header=False, index=False) inf_train = open('orders/indicators_train.csv') inf_test = open('orders/indicators_test.csv') data_train = np.array( [map(float, s.strip().split(',')) for s in inf_train.readlines()]) data_test = np.array( [map(float, s.strip().split(',')) for s in inf_test.readlines()]) predY_list = [0] * data_test.shape[0] for i in range(10): # bag 10 times learner = dt.DTclass(leaf_size=5, verbose=False) train_rows = int(round(1.0 * data_train.shape[0])) test_rows = int(round(1.0 * data_test.shape[0])) Xtrain = data_train[:train_rows, 0:-1] Ytrain = data_train[:train_rows, -1] Xtest = data_test[:train_rows, 0:-1] Ytest = data_test[:train_rows, -1] learner.addEvidence(Xtrain, Ytrain) # training step predY = learner.query(Xtest) # query predY_list = predY_list + predY predY = predY_list / 10.0 prices_test['decision'] = predY #print prices_port orders = pd.DataFrame(columns=['Date', 'Symbol', 'Order', 'Shares']) holding = 0 # holding =200 long; holding=-200 short window = date.datetime(2008, 1, 1) # window should more than 21 for (i_row, row) in prices_test.iterrows(): if row['decision'] < 0 and (i_row - window).days > 21 and holding > -200: orders.loc[len(orders)] = [ i_row, syms[0], 'SELL', str(200 + holding) ] holding -= 200 + holding window = i_row plt.axvline(i_row, color='r') if row['decision'] > 0 and (i_row - window).days > 21 and holding < 200: orders.loc[len(orders)] = [ i_row, syms[0], 'BUY', str(200 - holding) ] # max buy holding += 200 - holding window = i_row plt.axvline(i_row, color='g') file_dir = os.path.join('orders', 'orders_ML_test.csv') orders.to_csv(file_dir) of_ML_test = "./orders/orders_ML_test.csv" #of = "./orders/orders.csv" sv = 100000 #calculate benchmark of testing data dfprices = pd.DataFrame(prices_test) dfprices['Cash'] = sv - 200 * dfprices.ix[0, 'AAPL'] dfprices['Holding'] = 200 dfprices['Stock values'] = dfprices['Holding'] * dfprices['AAPL'] dfprices['Port_val'] = dfprices['Cash'] + dfprices['Stock values'] dfprices['Benchmark'] = dfprices['Port_val'] / dfprices['Port_val'].ix[ 0, :] benchmark = dfprices['Benchmark'] #calculate rule based on test period orders_test = pd.DataFrame(columns=['Date', 'Symbol', 'Order', 'Shares']) holding_RB = 0 # holding =200 long; holding=-200 short window_RB = date.datetime(2010, 1, 1) # window should more than 21 for (i_row, row), (i_prev, prev) in zip(df_test.iterrows(), df_test.shift(1).iterrows()): if prev['MACD Line'] >= 0 and row['MACD Line'] < 0 and ( i_row - window_RB).days > 21 and holding_RB > -200: orders_test.loc[len(orders_test)] = [ i_row, syms[0], 'SELL', str(200 + holding_RB) ] holding_RB -= 200 + holding_RB window_RB = i_row if prev['MACD Line'] <= 0 and row['MACD Line'] > 0 and ( i_row - window_RB).days > 21 and holding_RB < 200: orders_test.loc[len(orders_test)] = [ i_row, syms[0], 'BUY', str(200 - holding_RB) ] # max buy holding_RB += 200 - holding_RB window_RB = i_row if prev['MACD Line'] >= prev['Signal Line'] and row['MACD Line'] < row[ 'Signal Line'] and ( i_row - window_RB ).days > 21 and holding_RB > -200 and row['RSI'] > 70: orders_test.loc[len(orders_test)] = [ i_row, syms[0], 'SELL', str(200 + holding_RB) ] holding_RB -= 200 + holding_RB window_RB = i_row if prev['MACD Line'] <= prev['Signal Line'] and row['MACD Line'] > row[ 'Signal Line'] and (i_row - window_RB).days > 21 and holding_RB < 200: orders_test.loc[len(orders_test)] = [ i_row, syms[0], 'BUY', str(200 - holding_RB) ] # max buy holding_RB += 200 - holding_RB window_RB = i_row if prev[syms[0]] <= prev['Lower Band'] and row[ syms[0]] > row['Lower Band'] and ( i_row - window_RB ).days > 21 and holding_RB < 200: # cross up Lower Band orders_test.loc[len(orders_test)] = [ i_row, syms[0], 'BUY', str(200 - holding_RB) ] # max buy holding_RB += 200 - holding_RB window_RB = i_row if prev[syms[0]] <= prev['Middle Band'] and row[ syms[0]] > row['Middle Band'] and ( i_row - window_RB).days > 21 and holding_RB > -200 and row[ 'RSI'] > 70: # cross up Middle Band orders_test.loc[len(orders_test)] = [ i_row, syms[0], 'SELL', str(200 + holding_RB) ] holding_RB -= 200 + holding_RB window_RB = i_row # if prev[syms[0]] >= prev['Upper Band'] and row[syms[0]] < row['Upper Band'] and (i_row-window).days>21 and holding>-200 and row['RSI']>70: # cross down Upper Band # orders.loc[len(orders)] = [i_row, syms[0], 'SELL', str(200+holding)] # holding -= 200+holding # window = i_row # plt.axvline(i_row, color='r') if prev[syms[0]] >= prev['Middle Band'] and row[ syms[0]] < row['Middle Band'] and ( i_row - window_RB ).days > 21 and holding_RB < 200: # cross down Middle Band orders_test.loc[len(orders_test)] = [ i_row, syms[0], 'BUY', str(200 - holding_RB) ] holding_RB += 200 - holding_RB window_RB = i_row file_dir_RB_test = os.path.join('orders', 'orders_RB_test.csv') orders_test.to_csv(file_dir_RB_test) portvals_RB = compute_portvals(start_date=date.datetime(2010, 1, 1), end_date=date.datetime(2011, 12, 31), orders_file=file_dir_RB_test, start_val=sv) portvals_RB = portvals_RB / portvals_RB.ix[0, :] benchmark = benchmark / benchmark.ix[0, :] portvals_ML = compute_portvals(start_date=date.datetime(2010, 1, 1), end_date=date.datetime(2011, 12, 31), orders_file=of_ML_test, start_val=sv) portvals_ML = portvals_ML / portvals_ML.ix[0, :] prices_test = prices_test / prices_test.ix[0, :] plt.plot(prices_test.index, portvals_RB, label='Rule-based portfolio', color='b') plt.plot(prices_test.index, portvals_ML, label='ML-based portfolio Out of Sample', color='g') #plt.plot(prices_port.index, prices_port, label='APPL', color='m') plt.plot(benchmark.index, benchmark, label='Benchmark', color='k') plt.xlabel('Date') plt.ylabel('Price') plt.legend(loc='upper left') plt.show()
except FileNotFoundError as fnfe: continue listener = open("../txt_files/data.txt", "w") listener.close() candles = [] for line in new_reader: candles.append(line) capital = 100 private_client = AuthenticatedClient(Data.API_Public_Key, Data.API_Secret_Key, Data.Passphrase) new_order = Order(private_client) position = OpenPosition(new_order) indicator = Indicator() bands_1dev = BB(ndbevup=1, nbdevdn=1) indicator_list = [indicator, bands_1dev] for new_indicator in indicator_list: new_indicator.candles = candles[1:] new_indicator.get_data_set() new_indicator.reverse_data() new_indicator.get_dates() new_indicator.get_np_array() new_indicator.set_indicator() # verifies that the data and dates was extracted successfully h = 0 y = -1 while h < len(indicator.candles): if indicator.date_array[h] == indicator.candles[y][0]:
def test_run(): # Read data dates = pd.date_range('2008-1-1', '2009-12-31') syms = ['AAPL'] prices_all = get_data(syms, dates) prices_port = prices_all[syms] # only price of each stock in portfolio prices_SPY = prices_all['SPY'] # only SPY, for comparison later bb = BB(prices_port, lookback=20) macd = MACD(prices_port) rsi = RSI(prices_port, lookback=14) df = pd.concat([prices_port, bb, macd, rsi], axis=1) df = df.fillna(method='bfill') #print df #plot_data(df, title="Bollinger Bands and stock price", ylabel="Stock price", xlabel="Date") orders = pd.DataFrame(columns=['Date', 'Symbol', 'Order', 'Shares']) holding = 0 #holding =200 long; holding=-200 short window = dt.datetime(2008, 1, 1) # window should more than 21 for (i_row, row), (i_prev, prev) in zip(df.iterrows(), df.shift(1).iterrows()): if prev['MACD Line'] >= 0 and row['MACD Line'] < 0 and ( i_row - window).days > 21 and holding > -200: orders.loc[len(orders)] = [ i_row, syms[0], 'SELL', str(200 + holding) ] holding -= 200 + holding window = i_row plt.axvline(i_row, color='r') if prev['MACD Line'] <= 0 and row['MACD Line'] > 0 and ( i_row - window).days > 21 and holding < 200: orders.loc[len(orders)] = [ i_row, syms[0], 'BUY', str(200 - holding) ] #max buy holding += 200 - holding window = i_row plt.axvline(i_row, color='g') if prev['MACD Line'] >= prev['Signal Line'] and row['MACD Line'] < row[ 'Signal Line'] and ( i_row - window).days > 21 and holding > -200 and row['RSI'] > 70: orders.loc[len(orders)] = [ i_row, syms[0], 'SELL', str(200 + holding) ] holding -= 200 + holding window = i_row plt.axvline(i_row, color='r') if prev['MACD Line'] <= prev['Signal Line'] and row['MACD Line'] > row[ 'Signal Line'] and (i_row - window).days > 21 and holding < 200: orders.loc[len(orders)] = [ i_row, syms[0], 'BUY', str(200 - holding) ] #max buy holding += 200 - holding window = i_row plt.axvline(i_row, color='g') if prev[syms[0]] <= prev['Lower Band'] and row[ syms[0]] > row['Lower Band'] and ( i_row - window).days > 21 and holding < 200: # cross up Lower Band orders.loc[len(orders)] = [ i_row, syms[0], 'BUY', str(200 - holding) ] #max buy holding += 200 - holding window = i_row plt.axvline(i_row, color='g') if prev[syms[0]] <= prev['Middle Band'] and row[ syms[0]] > row['Middle Band'] and ( i_row - window).days > 21 and holding > -200 and row[ 'RSI'] > 70: # cross up Middle Band orders.loc[len(orders)] = [ i_row, syms[0], 'SELL', str(200 + holding) ] holding -= 200 + holding window = i_row plt.axvline(i_row, color='r') # if prev[syms[0]] >= prev['Upper Band'] and row[syms[0]] < row['Upper Band'] and (i_row-window).days>21 and holding>-200 and row['RSI']>70: # cross down Upper Band # orders.loc[len(orders)] = [i_row, syms[0], 'SELL', str(200+holding)] # holding -= 200+holding # window = i_row # plt.axvline(i_row, color='r') if prev[syms[0]] >= prev['Middle Band'] and row[ syms[0]] < row['Middle Band'] and ( i_row - window ).days > 21 and holding < 200: # cross down Middle Band orders.loc[len(orders)] = [ i_row, syms[0], 'BUY', str(200 - holding) ] holding += 200 - holding window = i_row plt.axvline(i_row, color='g') file_dir = os.path.join('orders', 'orders.csv') orders.to_csv(file_dir) Compare_df = BestPossible() benchmark = Compare_df['Benchmark'] of = "./orders/orders.csv" sv = 100000 portvals = compute_portvals(orders_file=of, start_val=sv) portvals = portvals / portvals.ix[0, :] benchmark = benchmark / benchmark.ix[0, :] #plot_data(plot_df, title="Benchmark vs. Rule-based portfolio", ylabel="Normalized price", xlabel="Date") prices_port = prices_port / prices_port.ix[0, :] plt.plot(prices_port.index, portvals, label='Rule-based portfolio', color='b') plt.plot(prices_port.index, prices_port, label='APPL', color='m') plt.plot(benchmark.index, benchmark, label='Benchmark', color='k') plt.title('Benchmark vs. Rule-based portfolio') plt.xlabel('Date') plt.ylabel('Price') plt.legend(loc='lower right') plt.show()
def myTradingSystem( DATE, OPEN, HIGH, LOW, CLOSE, VOL, USA_ADP, USA_EARN, USA_HRS, USA_BOT, USA_BC, USA_BI, USA_CU, USA_CF, USA_CHJC, USA_CFNAI, USA_CP, USA_CCR, USA_CPI, USA_CCPI, USA_CINF, USA_DFMI, USA_DUR, USA_DURET, USA_EXPX, USA_EXVOL, USA_FRET, USA_FBI, USA_GBVL, USA_GPAY, USA_HI, USA_IMPX, USA_IMVOL, USA_IP, USA_IPMOM, USA_CPIC, USA_CPICM, USA_JBO, USA_LFPR, USA_LEI, USA_MPAY, USA_MP, USA_NAHB, USA_NLTTF, USA_NFIB, USA_NFP, USA_NMPMI, USA_NPP, USA_EMPST, USA_PHS, USA_PFED, USA_PP, USA_PPIC, USA_RSM, USA_RSY, USA_RSEA, USA_RFMI, USA_TVS, USA_UNR, USA_WINV, exposure, equity, settings): nMarkets = CLOSE.shape[1] lookback = settings['lookback'] pos = np.zeros(nMarkets) markets = settings['markets'] w = settings['market_factor_weights'] lweights, sweights = econ_long_short_allocation( markets, DATE[0], DATE[-1], w, activate=settings['dynamic_portfolio_allocation']) sentiment_data = settings['sentiment_data'] covid_data = settings['covid_data'] # to understand how this system works print("Using data from {} onwards to predict/take position in {}".format( DATE[0], DATE[-1])) OPEN = np.transpose(OPEN)[1:] HIGH = np.transpose(HIGH)[1:] LOW = np.transpose(LOW)[1:] CLOSE = np.transpose(CLOSE)[1:] VOL = np.transpose(VOL)[1:] if settings['model'] == 'TA': ''' Based on factors from https://www.investing.com/technical/us-spx-500-futures-technical-analysis ################ TREND FOLOWING ################ Simple Moving Average (SMA) crosses, period 5,10,20,50,100,200 ''' # indicators SMA5s = [SMA(close, 5) for close in CLOSE] SMA10s = [SMA(close, 10) for close in CLOSE] SMA20s = [SMA(close, 20) for close in CLOSE] SMA50s = [SMA(close, 50) for close in CLOSE] SMA100s = [SMA(close, 100) for close in CLOSE] SMA200s = [SMA(close, 200) for close in CLOSE] # signals def buy_condition(close, sma): return (close[-1] > sma[-1]) and (close[-2] <= sma[-2]) def sell_condition(close, sma): return (close[-1] < sma[-1]) and (close[-2] >= sma[-2]) SMA5_cross_buys = [ True if buy_condition(close, sma) else False for close, sma in zip(CLOSE, SMA5s) ] SMA5_cross_sells = [ True if sell_condition(close, sma) else False for close, sma in zip(CLOSE, SMA5s) ] SMA10_cross_buys = [ True if buy_condition(close, sma) else False for close, sma in zip(CLOSE, SMA10s) ] SMA10_cross_sells = [ True if sell_condition(close, sma) else False for close, sma in zip(CLOSE, SMA10s) ] SMA20_cross_buys = [ True if buy_condition(close, sma) else False for close, sma in zip(CLOSE, SMA20s) ] SMA20_cross_sells = [ True if sell_condition(close, sma) else False for close, sma in zip(CLOSE, SMA20s) ] SMA50_cross_buys = [ True if buy_condition(close, sma) else False for close, sma in zip(CLOSE, SMA50s) ] SMA50_cross_sells = [ True if sell_condition(close, sma) else False for close, sma in zip(CLOSE, SMA50s) ] SMA100_cross_buys = [ True if buy_condition(close, sma) else False for close, sma in zip(CLOSE, SMA100s) ] SMA100_cross_sells = [ True if sell_condition(close, sma) else False for close, sma in zip(CLOSE, SMA100s) ] SMA200_cross_buys = [ True if buy_condition(close, sma) else False for close, sma in zip(CLOSE, SMA200s) ] SMA200_cross_sells = [ True if sell_condition(close, sma) else False for close, sma in zip(CLOSE, SMA200s) ] ''' Exponential Moving Average (EMA) crosses, period 5,10,20,50,100,200 ''' # indicators EMA5s = [EMA(close, 5) for close in CLOSE] EMA10s = [EMA(close, 10) for close in CLOSE] EMA20s = [EMA(close, 20) for close in CLOSE] EMA50s = [EMA(close, 50) for close in CLOSE] EMA100s = [EMA(close, 100) for close in CLOSE] EMA200s = [EMA(close, 200) for close in CLOSE] # signals # def condition(close, ema): # return (close[-1] > ema[-1]) and (close[-2] <= ema[-2]) def buy_condition(close, ema): return (close[-1] > ema[-1]) and (close[-2] <= ema[-2]) def sell_condition(close, ema): return (close[-1] < ema[-1]) and (close[-2] >= ema[-2]) EMA5_cross_buys = [ True if buy_condition(close, ema) else False for close, ema in zip(CLOSE, EMA5s) ] EMA5_cross_sells = [ True if sell_condition(close, ema) else False for close, ema in zip(CLOSE, EMA5s) ] EMA10_cross_buys = [ True if buy_condition(close, ema) else False for close, ema in zip(CLOSE, EMA10s) ] EMA10_cross_sells = [ True if sell_condition(close, ema) else False for close, ema in zip(CLOSE, EMA10s) ] EMA20_cross_buys = [ True if buy_condition(close, ema) else False for close, ema in zip(CLOSE, EMA20s) ] EMA20_cross_sells = [ True if sell_condition(close, ema) else False for close, ema in zip(CLOSE, EMA20s) ] EMA50_cross_buys = [ True if buy_condition(close, ema) else False for close, ema in zip(CLOSE, EMA50s) ] EMA50_cross_sells = [ True if sell_condition(close, ema) else False for close, ema in zip(CLOSE, EMA50s) ] EMA100_cross_buys = [ True if buy_condition(close, ema) else False for close, ema in zip(CLOSE, EMA100s) ] EMA100_cross_sells = [ True if sell_condition(close, ema) else False for close, ema in zip(CLOSE, EMA100s) ] EMA200_cross_buys = [ True if buy_condition(close, ema) else False for close, ema in zip(CLOSE, EMA200s) ] EMA200_cross_sells = [ True if sell_condition(close, ema) else False for close, ema in zip(CLOSE, EMA200s) ] ''' Average Directional Movement Index (ADX), period 14 ''' # indicators ADXs = [ ADX(high, low, close, 14) for high, low, close in zip(HIGH, LOW, CLOSE) ] # signals # adx[0] is mDI, adx[1] is pDI, adx[2] is actual ADX def bullish_condition(adx): # Bullish strong trend cross return (adx[2][-1] > 20) and (adx[1][-1] > adx[0][-1]) and ( adx[1][-2] <= adx[0][-2]) def bearish_condition(adx): # Bearish strong trend cross return (adx[2][-1] > 20) and (adx[1][-1] < adx[0][-1]) and ( adx[1][-2] >= adx[0][-2]) ADX_bullish_crosses = [ True if bullish_condition(adx) else False for adx in ADXs ] ADX_bearish_crosses = [ True if bearish_condition(adx) else False for adx in ADXs ] ''' Moving Average Convergence Divergence (MACD) fast=12, slow=26 ''' # indicator EMA12s = [EMA(close, 12) for close in CLOSE] EMA26s = [EMA(close, 26) for close in CLOSE] MACDs = [[(a - b) if b is not None else None for a, b in zip(EMA12, EMA26)] for EMA12, EMA26 in zip(EMA12s, EMA26s)] # signals def bullish_condition(MACD): # Bullish zero cross which sustains for 2 days (reduce false signals) return (MACD[-3] <= 0) and (MACD[-2] > 0) and (MACD[-1] > 0) def bearish_condition(MACD): # Bearish zero cross return (MACD[-3] >= 0) and (MACD[-2] < 0) and (MACD[-1] < 0) MACD_bullish_zero_cross = [ True if bullish_condition(MACD) else False for MACD in MACDs ] MACD_bearish_zero_cross = [ True if bearish_condition(MACD) else False for MACD in MACDs ] ''' Commodity Channel Index (CCI), period 14 ''' # indicator CCIs = [ CCI(high, low, close, 14) for high, low, close in zip(HIGH, LOW, CLOSE) ] # signals def bullish_condition(CCI): return (CCI[-1] > 100) and (CCI[-2] <= 100) def bearish_condition(CCI): return (CCI[-1] < -100) and (CCI[-2] >= -100) CCI_emerging_bulls = [ True if bullish_condition(CCI) else False for CCI in CCIs ] CCI_emerging_bears = [ True if bearish_condition(CCI) else False for CCI in CCIs ] ''' ################ MOMENTUM ################ Relative Strength Index (RSI), period 14 ''' # indicator RSIs = [RSI(close) for close in CLOSE] # signals def bullish_reversal(rsi, sma200, close): # Uptrend and cross 30 to become oversold (Bullish) return (close[-1] > sma200[-1]) and (rsi[-2] >= 30) and (rsi[-1] < 30) def bearish_reversal(rsi, sma200, close): # Downtrend and cross 70 to become overbought (Bearish) return (close[-1] < sma200[-1]) and (rsi[-2] <= 70) and (rsi[-1] > 70) def underbought_uptrend(rsi, sma200, close): # Uptrend and underbought return (close[-1] > sma200[-1]) and (rsi[-1] < 50) def undersold_downtrend(rsi, sma200, close): # Downtrend and undersold return (close[-1] < sma200[-1]) and (rsi[-1] > 50) RSI_bullish_reversal = [ True if bullish_reversal(rsi, sma200, close) else False for rsi, sma200, close in zip(RSIs, SMA200s, CLOSE) ] RSI_bearish_reversal = [ True if bearish_reversal(rsi, sma200, close) else False for rsi, sma200, close in zip(RSIs, SMA200s, CLOSE) ] RSI_underbought_uptrend = [ True if underbought_uptrend(rsi, sma200, close) else False for rsi, sma200, close in zip(RSIs, SMA200s, CLOSE) ] RSI_undersold_downtrend = [ True if undersold_downtrend(rsi, sma200, close) else False for rsi, sma200, close in zip(RSIs, SMA200s, CLOSE) ] ''' Stochastic Oscillator, fast 14, slow 3 ''' # indicators StochOscs = [ StochOsc(close, high, low, 14, 3) for close, high, low in zip(CLOSE, HIGH, LOW) ] # signals # stochosc[0] is Ks, stochosc[1] is Ds def bullish_cross(stochosc): # K (fast) cross D (slow) from below return (stochosc[0][-2] <= stochosc[1][-2]) and (stochosc[0][-1] > stochosc[1][-1]) def bearish_cross(stochosc): # K (fast) cross D (slow) from above return (stochosc[0][-2] >= stochosc[1][-2]) and (stochosc[0][-1] < stochosc[1][-1]) StochOsc_bullish_cross = [ True if bullish_cross(stochosc) else False for stochosc in StochOscs ] StochOsc_bearish_cross = [ True if bearish_cross(stochosc) else False for stochosc in StochOscs ] ''' Williams %R, 14 period ''' # indicator WilliamsRs = [ WilliamsR(high, low, close) for high, low, close in zip(HIGH, LOW, CLOSE) ] # signals def bullish(wr, close, sma100): # Overbought price action return (wr[-1] > -20) and (close[-1] > sma100[-1]) and ( close[-2] <= sma100[-2]) def bearish(wr, close, sma100): # Oversold price action return (wr[-1] < -80) and (close[-1] < sma100[-1]) and ( close[-2] >= sma100[-2]) WilliamsR_uptrend = [ True if bullish(wr, close, sma100) else False for wr, close, sma100 in zip(WilliamsRs, CLOSE, SMA100s) ] WilliamsR_downtrend = [ True if bearish(wr, close, sma100) else False for wr, close, sma100 in zip(WilliamsRs, CLOSE, SMA100s) ] ''' Ultimate Oscillator, periods 20,40,80 ''' # indicator UltiOscs = [ UltiOsc(high, low, close, 20, 40, 80) for high, low, close in zip(HIGH, LOW, CLOSE) ] # signals def bullish_cross(ultiosc): # Bullish center cross return (ultiosc[-1] > 50) and (ultiosc[-2] <= 50) def bearish_cross(ultiosc): # Bearish center cross return (ultiosc[-1] < 50) and (ultiosc[-2] >= 50) def bullish_reversal(ultiosc): # Bullish reversal from oversold return (ultiosc[-1] < 30) and (ultiosc[-2] >= 30) def bearish_reversal(ultiosc): # Bearish reversal from overbought return (ultiosc[-1] > 70) and (ultiosc[-2] >= 70) UltiOsc_bullish_cross = [ True if bullish_cross(ultiosc) else False for ultiosc in UltiOscs ] UltiOsc_bearish_cross = [ True if bearish_cross(ultiosc) else False for ultiosc in UltiOscs ] UltiOsc_bullish_reversal = [ True if bullish_reversal(ultiosc) else False for ultiosc in UltiOscs ] UltiOsc_bearish_reversal = [ True if bearish_reversal(ultiosc) else False for ultiosc in UltiOscs ] ''' ################ VOLUME ################ Accumulation / Distribution Index (ADI) ''' # indicator ADIs = [ ADI(high, low, close, vol) for high, low, close, vol in zip(HIGH, LOW, CLOSE, VOL) ] def bullish_trend(close, adi, sma200): # bullish trend confirmation return (close[-1] > sma200[-1]) and (close[-2] <= sma200[-2]) and ( adi[-1] > adi[-2]) def bearish_trend(close, adi, sma200): # bearish trend confirmation return (close[-1] < sma200[-1]) and (close[-2] >= sma200[-2]) and ( adi[-1] < adi[-2]) ADI_bullish_trend_confo = [ True if bullish_trend(close, adi, sma200) else False for close, adi, sma200 in zip(CLOSE, ADIs, SMA200s) ] ADI_bearish_trend_confo = [ True if bearish_trend(close, adi, sma200) else False for close, adi, sma200 in zip(CLOSE, ADIs, SMA200s) ] ''' On-Balance Volume (OBV) ''' # indicator OBVs = [OBV(close, vol) for close, vol in zip(CLOSE, VOL)] # signals def bullish_trend(obv): return (obv[-1] > obv[-2]) and (obv[-2] > obv[-3]) def bearish_trend(obv): return (obv[-1] < obv[-2]) and (obv[-2] < obv[-3]) OBV_bullish_trend_confo = [ True if bullish_trend(obv) else False for obv in OBVs ] OBV_bearish_trend_confo = [ True if bearish_trend(obv) else False for obv in OBVs ] ''' ################ VOLATILITY ################ Bollinger Bands (BB), 20 period ''' # indicator + signal BBs = [BB(close, 20) for close in CLOSE] BB_bullish_reversal = [True if bb[1][-1] == 1 else False for bb in BBs] BB_bearish_reversal = [True if bb[0][-1] == 1 else False for bb in BBs] ''' Execution ''' for i in range(0, nMarkets - 1): future_name = markets[i + 1] # # Trend following # if (SMA5_cross_buys[i] == True) or (SMA10_cross_buys[i] == True) or (SMA20_cross_buys[i] == True) or (SMA50_cross_buys[i] == True) or (SMA100_cross_buys[i] == True) or (SMA200_cross_buys == True): # pos[i+1] = 1 # if (SMA5_cross_sells[i] == True) or (SMA10_cross_sells[i] == True) or (SMA20_cross_sells[i] == True) or (SMA50_cross_sells[i] == True) or (SMA100_cross_sells[i] == True) or (SMA200_cross_sells == True): # pos[i+1] = -1 # Mean reverting # if (SMA5_cross_buys[i] == True) or (SMA10_cross_buys[i] == True) or (SMA20_cross_buys[i] == True) or (SMA50_cross_buys[i] == True) or (SMA100_cross_buys[i] == True) or (SMA200_cross_buys == True): # pos[i+1] = -1 # if (SMA5_cross_sells[i] == True) or (SMA10_cross_sells[i] == True) or (SMA20_cross_sells[i] == True) or (SMA50_cross_sells[i] == True) or (SMA100_cross_sells[i] == True) or (SMA200_cross_sells == True): # pos[i+1] = 1 # # Trend following # if (EMA5_cross_buys[i] == True) or (EMA10_cross_buys[i] == True) or (EMA20_cross_buys[i] == True) or (EMA50_cross_buys[i] == True) or (EMA100_cross_buys[i] == True) or (EMA200_cross_buys == True): # pos[i+1] = 1 # if (EMA5_cross_sells[i] == True) or (EMA10_cross_sells[i] == True) or (EMA20_cross_sells[i] == True) or (EMA50_cross_sells[i] == True) or (EMA100_cross_sells[i] == True) or (EMA200_cross_sells == True): # pos[i+1] = -1 # # Mean-reverting # if (EMA5_cross_buys[i] == True) or (EMA10_cross_buys[i] == True) or (EMA20_cross_buys[i] == True) or (EMA50_cross_buys[i] == True) or (EMA100_cross_buys[i] == True) or (EMA200_cross_buys == True): # pos[i+1] = -1 # if (EMA5_cross_sells[i] == True) or (EMA10_cross_sells[i] == True) or (EMA20_cross_sells[i] == True) or (EMA50_cross_sells[i] == True) or (EMA100_cross_sells[i] == True) or (EMA200_cross_sells == True): # pos[i+1] = 1 # if ADX_bullish_crosses[i] == True: # pos[i+1] = 1 # elif ADX_bearish_crosses[i] == True: # pos[i+1] = -1 # if MACD_bullish_zero_cross[i] == True: # pos[i+1] = 1 # elif MACD_bearish_zero_cross[i] == True: # pos[i+1] = -1 # if CCI_emerging_bulls[i] == True: # pos[i+1] = 1 # elif CCI_emerging_bears[i] == True: # pos[i+1] = -1 # if RSI_bullish_reversal[i] == True: # pos[i+1] = 1 # elif RSI_bearish_reversal[i] == True: # pos[i+1] = -1 # if StochOsc_bullish_cross[i] == True: # pos[i+1] = 1 # elif StochOsc_bearish_cross[i] == True: # pos[i+1] = -1 # if WilliamsR_uptrend[i] == True: # pos[i+1] = 1 # elif WilliamsR_downtrend[i] == True: # pos[i+1] = -1 # if UltiOsc_bullish_cross[i] == True: # pos[i+1] = 1 # elif UltiOsc_bearish_cross[i] == True: # pos[i+1] = -1 # if UltiOsc_bullish_reversal[i] == True: # pos[i+1] = 1 # elif UltiOsc_bearish_reversal[i] == True: # pos[i+1] = -1 # if ADI_bullish_trend_confo[i] == True: # pos[i+1] = lweights[future_name] # elif ADI_bearish_trend_confo[i] == True: # pos[i+1] = sweights[future_name] # if OBV_bullish_trend_confo[i] == True: # pos[i+1] = 1 # elif OBV_bearish_trend_confo[i] == True: # pos[i+1] = -1 # # Mean-reverting # if BB_bullish_reversal[i] == True: # pos[i+1] = 1 # elif BB_bearish_reversal[i] == True: # pos[i+1] = -1 # # Trend-following if BB_bullish_reversal[i] == True: pos[i + 1] = sweights[future_name] elif BB_bearish_reversal[i] == True: pos[i + 1] = lweights[future_name] elif settings['model'] == 'LIGHTGBM': for i in range(0, nMarkets - 1): future_name = markets[i + 1] if future_name in [ "CASH", "F_ED", "F_UZ", "F_SS", "F_ZQ", "F_EB", "F_VW", "F_F" ]: feature_ADI = ADI(HIGH[i], LOW[i], CLOSE[i], VOL[i]) feature_WilliamsR = WilliamsR(HIGH[i], LOW[i], CLOSE[i]) feature_BB_high_crosses, feature_BB_low_crosses = BB( CLOSE[i], 10) feature_CCI = CCI(LOW[i], CLOSE[i], VOL[i], 10) features = np.array([[ OPEN[i][-1], HIGH[i][-1], LOW[i][-1], CLOSE[i][-1], VOL[i][-1], feature_ADI[-1], feature_WilliamsR[-1], feature_BB_high_crosses[-1], feature_BB_low_crosses[-1], feature_CCI[-1], CLOSE[i][-2], CLOSE[i][-3], ]]) model_dir = f"./data/lgb_models/{markets[i+1]}_model" prediction = get_lgb_prediction(model_dir, features)[0] if prediction == 1: pos[i + 1] = lweights[future_name] elif prediction == -1: pos[i + 1] = sweights[future_name] elif settings['model'] == 'sentiment': ''' How sentiment of tweets from Bloomberg/Trump affect VIX, Gold and Treasuries ''' for i in range(0, nMarkets - 1): future_name = markets[i + 1] if future_name in ['F_GC']: #'F_VX','F_GC','F_TU' sentiment = sentiment_data[future_name] today = datetime.strptime(str(DATE[-1]), '%Y%m%d').date() if (today - sentiment['DATE'].tolist()[0] ).days > 30: # at least 30 days for training train = sentiment[sentiment['DATE'] < today] test = sentiment[sentiment['DATE'] == today] trainY = train['CLOSE'] del train['DATE'], train['CLOSE'] trainX = train del test['DATE'], test['CLOSE'] model = RandomForestRegressor() model.fit(trainX, trainY) pred_CLOSE = model.predict(test)[0] if pred_CLOSE > CLOSE[i][-2]: pos[i + 1] = 1 else: pos[i + 1] = -1 elif settings['model'] == 'covid': ''' How no. of covid cases in each country affects their overall markets 'sharpe': 1.3048, 'sortino': 2.3477, avg longs per day: 1.35 , avg shorts per day: 6.6 ''' for i in range(0, nMarkets - 1): country = None future_name = markets[i + 1] if future_name in ['F_ES', 'F_MD', 'F_NQ', 'F_RU', 'F_XX', 'F_YM']: country = 'US' elif future_name in ['F_AX', 'F_DM', 'F_DZ']: country = 'Germany' elif future_name == 'F_CA': country = 'France' elif future_name == 'F_LX': country = 'United Kingdom' elif future_name == 'F_FP': country = 'Finland' elif future_name == 'F_NY': country = 'Japan' elif future_name == 'F_PQ': country = 'Portugal' elif future_name in ['F_SH', 'F_SX']: country = 'Switzerland' if country: df = covid_data[covid_data['Country/Region'] == country].T.sum( axis=1).reset_index() df = df.iloc[1:] df['index'] = df['index'].apply(lambda x: x + "20") df['index'] = df['index'].apply( lambda x: datetime.strptime(x, '%m/%d/%Y').date()) future = pd.DataFrame({'DATE': DATE, 'CLOSE': CLOSE[i]}) future['CLOSE'] = future['CLOSE'].shift(-1) future['DATE'] = future['DATE'].apply( lambda x: datetime.strptime(str(x), '%Y%m%d').date()) df = pd.merge(df, future, left_on='index', right_on='DATE') df = df[df[0] != 0][[0, 'CLOSE']].rename(columns={0: "count"}) if len(df) > 10: reg = LinearRegression().fit( np.array(df['count'].values[:-1]).reshape(-1, 1), df['CLOSE'].values[:-1]) pred_CLOSE = reg.predict( np.array(df['count'].values[-1]).reshape(1, -1))[0] if pred_CLOSE > CLOSE[i][-2]: pos[i + 1] = 1 else: pos[i + 1] = -1 elif settings['model'] == 'ARIMA': for i in range(0, nMarkets - 1): try: if markets[i + 1] not in ARIMA_MODELS: model = auto_arima(np.log(CLOSE[i][:-1]), trace=False, error_action='ignore', suppress_warnings=True) ARIMA_MODELS[markets[i + 1]] = model.fit( np.log(CLOSE[i][:-1])) model = ARIMA_MODELS[markets[i + 1]].fit(np.log(CLOSE[i][:-1])) pred = model.predict(n_periods=1)[0] # print(markets[i+1],pred, np.log(CLOSE[i][-1])) pos[i + 1] = 1 if pred > np.log(CLOSE[i][-1]) else -1 except: pos[i + 1] = 0 print(f"Today's position in the {len(markets)} futures: {pos}") elif settings['model'] == 'GARCH': # Log return of the closing data #Prameters bound1 = 1 bound2 = 1 cor_dir = f'./data/garch_models/correlation.txt' with open(cor_dir) as f: cor_dict = json.load(f) log_return = np.diff(np.log(CLOSE)) #print(log_return) #log_return = log_return[~np.isnan(log_return)] #print(log_return[1]) for i in range(0, nMarkets - 1): train_Xs = log_return[i][:-1] #test_Xs = log_return[i][-1] sd = np.var(train_Xs) # define model model_dir = f'./data/garch_models/{markets[i+1]}_garch_model.txt' with open(model_dir) as f: params_dict = json.load(f) p = params_dict['order'][0] q = params_dict['order'][1] model = arch_model(train_Xs, p=p, q=q) model_fixed = model.fix(params_dict['params']) # forecast the test set forecasts = model_fixed.forecast() #expected = forecasts.mean.iloc[-1:]['h.1'] var = forecasts.variance.iloc[-1:]['h.1'] #print(type(variance)) if (cor_dict[markets[i + 1]] > 0.03): if (float(np.sqrt(var)) > bound1 * np.std(train_Xs)): pos[i] = 1 elif (float(np.sqrt(var)) < bound2 * np.std(train_Xs)): pos[i] = -1 else: pos[i] = 0 elif (cor_dict[markets[i + 1]] < -0.03): if (float(np.sqrt(var)) > bound1 * np.std(train_Xs)): pos[i] = -1 elif (float(np.sqrt(var)) < bound2 * np.std(train_Xs)): pos[i] = 1 else: pos[i] = 0 else: pos[i] = 0 # With the estimated return and variance, we can apply portfolio optimization #print((np.array(result) * np.array(truth)).sum() / len(result)) elif settings['model'] == 'fourier': #Parameters that filter the signal with specific range of signals #Note that the lower bound should be larger than 0 and upper bound smaller than 1 filter_type = 'customed' my_frequency_bound = [0.05, 0.2] filter_type = 'low' #Specify high/mid/low/customed for weekly signals, weekly to monthly signals, above monthly signals or customed frequency range if filter_type == 'high': frequency_bound = [0.2, 1] elif filter_type == 'mid': frequency_bound = [0.05, 0.2] elif filter_type == 'low': frequency_bound = [0, 0.05] elif filter_type == 'customed': frequency_bound = my_frequency_bound #Transform the close data by fourier filtering, only signals within the specific range remains transformed_close = [] for i in range(0, nMarkets - 1): signal = CLOSE[i][:-1] fft = np.fft.rfft(signal) T = 1 # sampling interval N = len(signal) f = np.linspace(0, 1 / T, N) fft_filtered = [] for j in range(int(N / 2)): if f[j] > frequency_bound[0] and f[j] < frequency_bound[1]: fft_filtered.append(fft[j]) else: fft_filtered.append(0) signal_filtered = np.fft.irfft(fft_filtered) transformed_close.append(list(signal_filtered)) periodLonger = 200 periodShorter = 40 smaLongerPeriod = np.nansum( np.array(transformed_close)[:, -periodLonger:], axis=1) / periodLonger smaShorterPeriod = np.nansum( np.array(transformed_close)[:, -periodShorter:], axis=1) / periodShorter longEquity = smaShorterPeriod > smaLongerPeriod shortEquity = ~longEquity pos_1 = np.zeros(nMarkets - 1) pos_1[longEquity] = 1 pos_1[shortEquity] = -1 pos = np.array([0] + list(pos_1)) elif settings['model'] == 'pearson': ''' Pairwise correlation, taking position based on the greatest variation from average of the past 50 periods of 50 days ''' #'sharpe': 0.57939, 'sortino': 0.9027189, 'returnYearly': 0.076509, 'volaYearly': 0.13205 # with allocation #avg longs per day: 6.343 , avg shorts per day: 6.746 d = {} ##Name of future : Close of all 88 futures names = [] ##names of all 88 future for i in range(0, nMarkets - 1): n = markets[i + 1] names.append(n) d[n] = (CLOSE[i]) d_corr = settings['historic_corr'] ## key = tuple of name of 2 futures, value = position to take for ((future1,future2),difference) d_position = {} for i in list(d_corr.keys()): f = i[0] s = i[1] tup = d_corr[i] l1 = d[f][-49:-1] ##take last 50 close l2 = d[s][-49:-1] ##take last 50 close corr, _ = pearsonr(l1, l2) change_f = d[f][-2] - d[f][-49] change_s = d[s][-2] - d[s][-49] diff = tup - corr if diff > 0.3: if change_f > change_s: d_position[i] = ( (-1, 1), diff ) ##assuming -1 means short while 1 means long else: d_position[i] = ((1, -1), diff) for i in range( len(names)): ##find position based on greatest variation diff = 0 pair = tuple() name = names[i] counter = 0 for k in list(d_position.keys()): if name in k: counter += 1 pair = k if counter == 1: if name == k[0]: if d_position[k][0][0] > 0: pos[i + 1] = lweights[name] else: pos[i + 1] = sweights[name] else: if d_position[k][0][1] > 0: pos[i + 1] = lweights[name] else: pos[i + 1] = sweights[name] elif settings['model'] == 'FASTDTW': #'sharpe': 4.8632971, 'sortino': 17.09129, 'returnYearly': 1.216714, 'volaYearly': 0.25018 # no allocation # avg longs per day: 0.328 , avg shorts per day: 0.281 d = {} ##Name of future : Close of all 88 futures names = [] ##names of all 88 future for i in range(0, nMarkets - 1): n = markets[i + 1] names.append(n) d[n] = (CLOSE[i]) d_dist = settings[ 'historic_dist'] ## key = tuple of name of 2 futures, value = average distance d_position = {} for i in list(d_dist.keys()): f = i[0] s = i[1] tup = d_dist[i] l1 = d[f][-49:-1] ##take last 50 close l2 = d[s][-49:-1] ##take last 50 close distance, _ = fastdtw(l1, l2) distance = distance / 50 change_f = d[f][-2] - d[f][-49] change_s = d[s][-2] - d[s][-49] diff = distance - tup threshold = 16 * tup if distance > threshold: if change_f > change_s: d_position[i] = ( (-1, 1), diff ) ##assuming -1 means short while 1 means long else: d_position[i] = ((1, -1), diff) for i in range( len(names)): ##find position based on greatest variation diff = 0 name = names[i] for k in list(d_position.keys()): if name in k: if d_position[k][1] > diff: diff = d_position[k][1] if name == k[0]: if d_position[k][0][0] > 0: pos[i + 1] = lweights[name] else: pos[i + 1] = sweights[name] else: if d_position[k][0][1] > 0: pos[i + 1] = lweights[name] else: pos[i + 1] = sweights[name] # check if latest economic data suggests downturn then activate short only strats print("Positions:", pos) if np.nansum(pos) > 0: pos = pos / np.nansum(abs(pos)) settings['longs'] = settings['longs'] + sum(1 for x in pos if x > 0) settings['shorts'] = settings['shorts'] + sum(1 for x in pos if x < 0) settings['days'] = settings['days'] + 1 return pos, settings
def application(): if request.method == 'POST': new_request = request.get_json(force=True) new_ticker = get_ticker(new_request) private_client = AuthenticatedClient(Data.API_Public_Key, Data.API_Secret_Key, Data.Passphrase) new_order = Order(private_client) position = OpenPosition(new_order) funds = Capital(private_client) indicator = Indicator() macd = MACD() candle_ticker: str stop_time: int candle_gra = int if position.get_position() and last_instance(): candle_ticker = new_order.get_key("product_id") stop_time = get_time(27976) candle_gra = 300 writer = open(Data.Time, "w") writer.write(str(time.time() + 5.0)) writer.close() elif position.get_position() is False: candle_ticker = new_ticker stop_time = get_time(83925) candle_gra = 900 try: indicator.set_candles(product=candle_ticker, callback=stop_time, begin=get_time(0), granularity=candle_gra) except ValueError as ve: print(ve.with_traceback()) except NameError as ne: print(ne.with_traceback()) indicator_list = [indicator, macd] try: for value in indicator_list: value.candles = indicator.candles value.set_indicator() value.set_dates() except Exception as e: print(e.with_traceback()) indicator_5m = Indicator() macd_5m = MACD() if position.get_position() is False: if macd.hist[-1] > macd.hist[-2]: try: indicator_5m.set_candles(product=new_ticker, callback=get_time(27976), begin=get_time(0), granularity=900) except ValueError as ve: print(ve.with_traceback()) else: indicator_5m = indicator macd_5m = macd volume_5m = VolSMA(timeperiod=20) bands2dev_5m = BB() bands1dev_5m = BB(ndbevup=1, nbdevdn=1) rsi_5m = RSI() ema_5m = EMA() momentum_5m = Momentum() indicators = [ indicator_5m, macd_5m, volume_5m, bands1dev_5m, bands2dev_5m, rsi_5m, ema_5m, momentum_5m ] try: for value in indicators: value.candles = indicator_5m.candles value.set_indicator() value.set_dates() except Exception as e: print(e.with_traceback()) strategy_5m = Strategy(indicator_5m, macd_5m, bands1dev_5m, bands2dev_5m, volume_5m, rsi_5m, ema_5m, new_order) try: strategy_5m.strategy(-1) except Exception as e: print(e.with_traceback()) trade_side: str trade_product: str trade_funds: str if (new_order.is_bottom()) and (position.get_position() is False): trade_side = "buy" trade_product = new_ticker trade_funds = funds.get_capital() elif (new_order.is_top()) and (position.get_position()): trade_side = "sell" trade_product = new_order.get_key("product_id") trade_funds = get_size(trade_product, new_order.get_key("filled_size")) try: new_trade = private_client.place_market_order( product_id=trade_product, side=trade_side, funds=trade_funds) writer = open(Data.Path, "w") writer.write(new_trade['id']) writer.close() writer = open(Data.Time, "w") writer.write(new_trade['done_at']) writer.close() except NameError as ne: print(ne.with_traceback()) except KeyError as ke: print(ke.with_traceback()) return 'success', 200 elif request.method == 'GET': return redirect('http://3.218.228.129/login') else: abort(400)
def __init__(self, indicator=Indicator(), bol=BB(), order=Order()): super(Bollinger, self).__init__(indicator=indicator, bands_2dev=bol, order=order)
def test_run(): #construct indicator and decision dates = pd.date_range('2008-1-1', '2009-12-31') syms = ['AAPL'] prices_all = get_data(syms, dates) prices_port = prices_all[syms] # only price of each stock in portfolio bb = BB(prices_port, lookback=20) bb=bb.fillna(method='bfill') macd = MACD(prices_port) rsi = RSI(prices_port, lookback=14) df = pd.concat([prices_port, bb, macd, rsi], axis=1) df = df.fillna(method='bfill') indicators = pd.DataFrame(columns=['MACD_ZERO', 'MACD_SIGNAL', 'ACROSS_BAND', 'BB_value', 'RSI','Decision']) indicators['BB_value'] = (df[syms[0]] - bb['Middle Band']) / (bb['Upper Band'] - bb['Middle Band']) indicators['MACD_ZERO']=macd['MACD Line'] indicators['MACD_SIGNAL'] = macd['Signal Line'] indicators['ACROSS_BAND'] = bb['Middle Band'] indicators['RSI'] = rsi['RSI'] indicators2 = indicators[['MACD_SIGNAL', 'MACD_ZERO']] indicators2 = (indicators2 - indicators2.mean(axis=0)) / indicators2.std(axis=0) indicators2['Color']='k' # construct indicators # for (i_row, row), (i_prev, prev) in zip(df.iterrows(), df.shift(1).iterrows()): # if prev['MACD Line'] >= 0 and row['MACD Line'] < 0: # MACD prev>0,now<0, SELL MACD_ZERO=-1 # indicators.ix[i_row,'MACD_ZERO']=-1 # if prev['MACD Line'] <= 0 and row['MACD Line'] > 0: # MACD prev<0,now>0, BUY MACD_ZERO=1 # indicators.ix[i_row, 'MACD_ZERO'] = 1 # if prev['MACD Line'] >= prev['Signal Line'] and row['MACD Line'] < row['Signal Line']: # MACD prev>Signal Line,now<Signal line, SELL MACD_Signal=-1 # indicators.ix[i_row,'MACD_SIGNAL']=-1 # if prev['MACD Line'] <= prev['Signal Line'] and row['MACD Line'] > row['Signal Line']: # MACD prev<Signal Line,now>Signal line, BUY MACD_Signal=1 # indicators.ix[i_row, 'MACD_SIGNAL'] = 1 # if prev[syms[0]] <= prev['Lower Band'] and row[syms[0]] > row['Lower Band']: # cross up Lower Band, BUY Acroo_band=1 # indicators.ix[i_row, 'ACROSS_BAND'] = 1 # if prev[syms[0]] >= prev['Upper Band'] and row[syms[0]] < row['Upper Band']: # cross down Upper Band SELL Acroo_band=-1 # indicators.ix[i_row, 'ACROSS_BAND'] = -1 # if row['RSI']>70: #RSI>70 overbought, likely to sell it # indicators.ix[i_row, 'RSI'] = -1 # if row['RSI'] < 30: #RSI<30, oversold, likely to buy it. # indicators.ix[i_row, 'RSI'] = 1 # construct decision indicators = (indicators - indicators.mean(axis=0)) / indicators.std(axis=0) YBUY=0.05 YSELL=-0.05 for (i_row, row), (i_future, future) in zip(df.iterrows(), df.shift(-21).iterrows()): if (future[syms[0]]/row[syms[0]]-1)> YBUY: # if 21 days return exceed YBUY, then BUY Decision=1 indicators.ix[i_row, 'Decision'] = 1 indicators2.ix[i_row, 'Color'] = 'g' if (future[syms[0]] / row[syms[0]] - 1) < YSELL: # if 21 days return less than YSELL, then SELL Decision=-1 indicators.ix[i_row, 'Decision'] = -1 indicators2.ix[i_row, 'Color'] = 'r' indicators=indicators.fillna(0) #print indicators file_dir = os.path.join('orders', 'indicators.csv') file_dir2 = os.path.join('orders', 'Training data.csv') indicators.to_csv(file_dir, header=False, index=False) indicators2.to_csv(file_dir2)