| Overall Statistics |
|
Total Orders 6532 Average Win 2.49% Average Loss -1.08% Compounding Annual Return 680.195% Drawdown 99.300% Expectancy 0.419 Start Equity 1000000.00 End Equity 259614601308.34 Net Profit 25961360.131% Sharpe Ratio 5.239 Sortino Ratio 10.159 Probabilistic Sharpe Ratio 99.699% Loss Rate 57% Win Rate 43% Profit-Loss Ratio 2.30 Alpha 6.246 Beta -0.382 Annual Standard Deviation 1.186 Annual Variance 1.407 Information Ratio 5.074 Tracking Error 1.208 Treynor Ratio -16.275 Total Fees $148931329464.95 Estimated Strategy Capacity $35000.00 Lowest Capacity Asset LTCUSD 10B Portfolio Turnover 256.12% Drawdown Recovery 1511 |
#region imports
from AlgorithmImports import *
#endregion
#
# Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)
# https://creativecommons.org/licenses/by-nc-nd/4.0/
# CandleStick.py -- Pivot(s) calculator.
#
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.5.0.0.10862. Copyright 2014 QuantConnect Corporation.
#
########################################################
# Developed by Anastasios N. Bikos. ©DeepConscius All Rights Reserved.
# # mpikos@live.com
# # Copyright ~ ~ ~ 16/3/2023
# # Version ~ ~ ~ a26.5
# # ~ ~ ~
########################################################
import numpy as np
BULLISH = 1
BEARISH = 0
class CandleStick:
def __init__(self, o, c, h, l, time):
self.o = o
self.c = c
self.h = h
self.l = l
self.body = c - o
self.range = h - l
if self.body < 0:
self.direction = BEARISH
self.us = h - o
self.ls = c - l
elif self.body == 0:
self.body = np.mean([o, c])
self.direction = BULLISH
self.us = h - c
self.ls = o - l
else:
self.direction = BULLISH
self.us = h - c
self.ls = o - l
if self.range == 0:
self.range = np.mean([l, h])
self.time = time
#region imports
from AlgorithmImports import *
#endregion
#
# Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)
# https://creativecommons.org/licenses/by-nc-nd/4.0/
# ChartAnalysis.py -- Utility function(s) to estimate volume swings patterns and volatility trends.
#
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.5.0.0.10862. Copyright 2014 QuantConnect Corporation.
#
########################################################
# Developed by Anastasios N. Bikos. ©DeepConscius All Rights Reserved.
# # mpikos@live.com
# # Copyright ~ ~ ~ 16/3/2023
# # Version ~ ~ ~ a26.5
# # ~ ~ ~
########################################################
BULLISH = 1
BEARISH = 0
def hammer(cs0, cs1):
if cs0.direction == BEARISH:
return False, 0x00
elif cs0.us/abs(cs0.body) > .4:
return False, 0x00
elif abs(cs0.body)/cs0.range > .2:
return False, 0x00
# elif cs0.l > cs1.l:
# return False, 0
return True, 0x01
def star(cs0, cs1):
if cs0.direction == BULLISH:
return False, 0x00
elif cs0.ls/abs(cs0.body) > .2:
return False, 0x00
elif abs(cs0.body)/cs0.range > .3:
return False, 0x00
# elif cs0.h < cs1.h:
# return False, 0
return True, 0x02
def bearish_engulfing(cs0, cs1):
if cs0.direction == BULLISH:
return False, 0
elif cs1.direction == BEARISH:
return False, 0
elif cs1.c > cs0.o:
return False, 0
elif cs1.o < cs0.c:
return False, 0
elif cs1.h > cs0.h:
return False, 0
elif cs1.l < cs0.l:
return False, 0
return True, 0x20
def bullish_engulfing(cs0, cs1):
if cs0.direction == BEARISH:
return False, 0
elif cs1.direction == BULLISH:
return False, 0
elif cs1.o > cs0.c:
return False, 0
elif cs1.c < cs0.o:
return False, 0
elif cs1.h > cs0.h:
return False, 0
elif cs1.l < cs0.l:
return False, 0
return True, 0x040
def piercing_line(cs0, cs1):
if cs0.direction == BEARISH:
return False, 0
elif cs1.direction == BULLISH:
return False, 0
elif cs1.o < cs0.o:
return False, 0
elif cs1.c < cs0.c:
return False, 0
elif cs1.h < cs0.h:
return False, 0
elif cs1.l < cs0.l:
return False, 0
elif cs0.c < (cs1.range/2 + cs1.c):
return False, 0
return True, 0x80
def threeBears(bar1, bar2, bar3):
if bar1.o > bar2.open:
return False, 0
elif bar2.high > bar3.high:
return False, 0
return True
def get_avg_range(data):
sum = 0
count = 0
length = 0
for cs in data:
if count > 2:
sum = sum + (float(cs[1]) - float(cs[2]))
length += 1
count += 1
return sum/length
def major_move(cs, atr):
if abs(cs.body) < atr:
return False, 0
elif cs.us/abs(cs.body) > .15:
return False, 0
elif cs.ls/abs(cs.body) > .15:
return False, 0
return True, 0x004
def gap_up(cs0, cs1):
if cs1.h < cs0.l:
return True, 0x008
else:
return False, 0
def gap_down(cs0, cs1):
if cs1.l > cs0.h:
return True, 0x010
else:
return False, 0
def black_marubozu(cs, atr):
if cs.h != cs.o:
return False, 0
elif cs.l != cs.c:
return False, 0
elif cs.range < atr:
return False, 0
return True, 0x100
def white_marubozu(cs, atr):
if cs.h != cs.c:
return False, 0
elif cs.l != cs.o:
return False, 0
elif cs.range < atr:
return False, 0
return True, 0x200
def bearish_doji(cs0, cs1):
if abs(cs0.o-cs0.c)/cs0.range > .05:
return False, 0
elif abs(cs0.h - cs0.c)/cs0.range < .7:
return False, 0
elif abs(cs0.c - cs0.l)/cs0.range > .3:
return False, 0
elif cs0.h < cs1.h:
return False, 0
return True, 0x400
def bullish_doji(cs0, cs1):
if abs(cs0.o-cs0.c)/cs0.range > .05:
return False, 0
elif abs(cs0.h - cs0.c)/cs0.range > .3:
return False, 0
elif abs(cs0.c - cs0.l)/cs0.range < .7:
return False, 0
elif cs0.l > cs1.l:
return False, 0
return True,0x800#region imports
from AlgorithmImports import *
#endregion
#
# Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)
# https://creativecommons.org/licenses/by-nc-nd/4.0/
# RecvQuotes.py -- Main (volume) swing decision calculator.
#
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.5.0.0.10862. Copyright 2014 QuantConnect Corporation.
#
########################################################
# Developed by Anastasios N. Bikos. ©DeepConscius All Rights Reserved.
# # mpikos@live.com
# # Copyright ~ ~ ~ 16/3/2023
# # Version ~ ~ ~ a26.5
# # ~ ~ ~
########################################################
import pandas as pd
import datetime as datetime
import CandleStick as cs
import ChartAnalysis as analyze
import csv
def make_decision(value, time):
if value:
print ("OPEN TRADE")
verbage = ''
if value & 0x1:
print("HAMMER")
verbage += "HAMMER "
if value & 0x2:
print("STAR")
verbage += "STAR "
if value & 0x4:
print("MAJOR MOVE")
verbage += "MAJOR MOVE "
if value & 0x8:
print("GAP UP")
verbage += "GAP UP "
if value & 0x10:
print("GAP DOWN")
verbage += "GAP DOWN "
if value & 0x20:
print("BEARISH ENGULFING")
verbage += "BEARISH ENGULFING "
if value & 0x40:
print("BULLISH ENGULFING")
verbage += "BULLISH ENGULFING "
if value & 0x80:
print("PIERCING LINE")
verbage += "PIERCING LINE "
if value & 0x100:
print("BLACK MARUBOZU")
verbage += "BLACK MARUBOZU "
if value & 0x200:
print("WHITE MARUBOZU")
verbage += "WHITE MARUBOZU "
if value & 0x400:
print("BEARISH DOJI")
verbage += "BEARISH DOJI "
if value & 0x800:
print("BULLISH DOJI")
verbage += "BULLISH DOJI "
return verbage
def analyze_data(cs_0, cs_1, cs_2, atr):
a, av = analyze.hammer(cs_0, cs_1)
b, bv = analyze.star(cs_0, cs_1)
c, cv = analyze.major_move(cs_0, atr)
d, dv = analyze.gap_up(cs_0, cs_1)
e, ev = analyze.gap_down(cs_0, cs_1)
f, fv = analyze.bearish_engulfing(cs_0, cs_1)
g, gv = analyze.bullish_engulfing(cs_0, cs_1)
h, hv = analyze.piercing_line(cs_0, cs_1)
i, iv = analyze.black_marubozu(cs_0, atr)
j, jv = analyze.white_marubozu(cs_0, atr)
k, kv = analyze.bearish_doji(cs_0, cs_1)
l, lv = analyze.bullish_doji(cs_0, cs_1)
# print(cs_0.time, "\t", a, "\t", b, "\t", c, "\t", d, "\t", e, "\t", f, "\t", g, "\t", h, "\t", i, "\t", j, "\t", k, "\t", l)
value = av | bv | cv | dv | ev | fv | gv | hv | iv | jv | kv | lv
verbage = make_decision(value, cs_0.time)
return verbage
def get_last_three(fn):
#allData = csv.reader(fn)
atr = analyze.get_avg_range(fn)
lines = fn
row0 = lines[-1]
row1 = lines[-2]
row2 = lines[-3]
return atr, row0, row1, row2
def get_daily(fn):
atr, row0, row1, row2 = get_last_three(fn)
line = row0
a = float(line[3])
b = float(line[4])
c = float(line[1])
d = float(line[2])
e = line[0]
cs_0 = cs.CandleStick(a,b,c,d,e)
line = row1
a = float(line[3])
b = float(line[4])
c = float(line[1])
d = float(line[2])
e = line[0]
cs_1 = cs.CandleStick(a,b,c,d,e)
line = row2
a = float(line[3])
b = float(line[4])
c = float(line[1])
d = float(line[2])
e = line[0]
cs_2 = cs.CandleStick(a,b,c,d,e)
verbage = analyze_data(cs_0, cs_1, cs_2, atr)
return verbage#
# Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)
# https://creativecommons.org/licenses/by-nc-nd/4.0/
# System.py -- Main API core.
#
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.5.0.0.10862. Copyright 2014 QuantConnect Corporation.
#
########################################################
# Developed by Anastasios N. Bikos. ©DeepConscius All Rights Reserved.
# # mpikos@live.com
# # Copyright ~ ~ ~ 15/10/2023
# # Version ~ ~ ~ a33.0
# # ~ ~ ~
########################################################
from System import *
from QuantConnect.Data import *
from QuantConnect.Algorithm import *
from QuantConnect.Indicators import *
from QuantConnect.Securities import *
from QuantConnect.Data.Consolidators import *
from QuantConnect.Orders import OrderStatus
from QuantConnect import *
from QuantConnect.Orders import *
from QuantConnect.Algorithm.Framework import *
from QuantConnect.Algorithm.Framework.Alphas import *
from QuantConnect.Data.Market import TradeBar
from AlgorithmImports import *
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Algorithm.Framework")
import math
from math import floor
import random
import pandas as pd
import numpy as np
from datetime import timedelta, datetime
from datetime import timedelta
from collections import deque
from sklearn.preprocessing import MinMaxScaler
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import talib as ta
from statistics import mode
# Binary Classification with Sonar Dataset: Baseline
import xgboost as xgb
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC, LinearSVC, NuSVC, SVR, NuSVR, OneClassSVM
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn import preprocessing
from collections import Counter
import RecvQuotes as RQ
class MarketDynamics(QCAlgorithm):
global X
X = 60
global xn
xn = int(float(60)/float(X))
global daily_trades_allowance_quant
daily_trades_allowance_quant = 0
global minute_trades_allowance_quant_thresh
minute_trades_allowance_quant_thresh = 1
global daily_trades_allowance_quant_thresh
daily_trades_allowance_quant_thresh = minute_trades_allowance_quant_thresh *24 *xn
global minute_trades_allowance_quant
minute_trades_allowance_quant = 0
global daily_trade_flag_en
daily_trade_flag_en = False
global hourly_trade_flag_en
hourly_trade_flag_en = False
global bet_arr
bet_arr = [0, 0]
global hist_arr
hist_arr = [0, 0]
global trading_quantum
trading_quantum = 1.0
global start_equity_amount
start_equity_amount = 50000
global total_equity
total_equity = [(0.01 *start_equity_amount)]
global min_border
min_border = -1
global max_border
max_border = +1
global margins_border
margins_border = [[-0, -1], [+0, +1]]
global scaler
global arr1
arr1 = [-1,-1]
global arr2
arr2 = [-1,-1]
global dataset
dataset = [-1]
global stopPriceBuy
stopPriceBuy = -1
global profit_factor
profit_factor = 0.1
global closeness_factor
closeness_factor = 0.05
global normalized
normalized = []
global comp_price
comp_price = []
global projected_price
projected_price = []
global __quantity
__quantity = 0
global day_close_price_arr
day_close_price_arr = [-1, -1]
global high_price_arr
high_price_arr = [-1, -1]
global low_price_arr
low_price_arr = [-1, -1]
global volume_arr
volume_arr = [-1, -1]
global open_price_arr
open_price_arr = [-1, -1]
global close_price_arr
close_price_arr = [-1, -1]
global datetime_arr
datetime_arr = []
global loss_factor
loss_factor = 0.0125
global rsi_interval
rsi_interval = 14
global U
U = 12
global Z
Z = 1
global scheduled_event_1
scheduled_event_1 = None
global symbol_minimum_trade_order_size
symbol_minimum_trade_order_size = 0.5
global verbage
verbage = "None"
global t_indicator_arr
t_indicator_arr = []
global delta_prediction_arr
delta_prediction_arr = []
global real
global last_trade_order
last_trade_order = "Null"
global a0_arr
a0_arr = []
global offset
offset = 1000
global sign
sign = +1
global sign_
sign_ = +1
global _sign
_sign = +1
global weekly_stockprices_arr
weekly_stockprices_arr = [[], [], [], []]
global weekly_stockprices_arr1
weekly_stockprices_arr1 = []
global weekly_stockprices_arr2
weekly_stockprices_arr2 = []
global weekly_stockprices_arr3
weekly_stockprices_arr3 = []
global weekly_stockprices_arr4
weekly_stockprices_arr4 = []
global high_price_arr1
high_price_arr1 = []
global high_price_arr2
high_price_arr2 = []
global high_price_arr3
high_price_arr3 = []
global high_price_arr4
high_price_arr4 = []
global low_price_arr1
low_price_arr1 = []
global low_price_arr2
low_price_arr2 = []
global low_price_arr3
low_price_arr3 = []
global low_price_arr4
low_price_arr4 = []
global volume_arr1
volume_arr1 = []
global volume_arr2
volume_arr2 = []
global volume_arr3
volume_arr3 = []
global volume_arr4
volume_arr4 = []
global open_price_arr1
open_price_arr1 = []
global open_price_arr2
open_price_arr2 = []
global open_price_arr3
open_price_arr3 = []
global open_price_arr4
open_price_arr4 = []
global close_price_arr1
close_price_arr1 = []
global close_price_arr2
close_price_arr2 = []
global close_price_arr3
close_price_arr3 = []
global close_price_arr4
close_price_arr4 = []
global day_close_price_arr1
day_close_price_arr1 = []
global day_close_price_arr2
day_close_price_arr2 = []
global day_close_price_arr3
day_close_price_arr3 = []
global day_close_price_arr4
day_close_price_arr4 = []
global btcusd_a0
btcusd_a0 = 0
global ethusd_a0
ethusd_a0 = 0
global dotusd_a0
dotusd_a0 = 0
global ltcusd_a0
ltcusd_a0 = 0
global DD_arr
DD_arr = []
global total_equity_
total_equity_ = [(0.01 *start_equity_amount)]
global out_DD
out_DD = [-1, -1]
global sign_inp_arr
sign_inp_arr = []
global rsi_intra_daily
rsi_intra_daily = 50
global exp_factor
exp_factor = 1.0
global no_ctr
no_ctr = [6, 6, 6, 6]
global enable_live_mode
enable_live_mode = True
global take_profit_factor
take_profit_factor = 0.30
global mom_array
mom_array = [[], [], [], []]
global rsi_intra_daily_array
rsi_intra_daily_array = [[], [], [], []]
global exposure_risk_factor
exposure_risk_factor = 0.1
global dayscounter
dayscounter = 0
global episode_list
episode_list = []
global sign_arr
sign_arr = []
FastEmaPeriod = 12
SlowEmaPeriod = 26
def TakeProfit(self):
global take_profit_factor
if self.Portfolio.TotalUnrealizedProfit > 0 and self.Portfolio.TotalUnrealizedProfit >= (take_profit_factor *self.Portfolio.TotalPortfolioValue):
for ticker in self.tickers:
self.EmitInsights(
# Creates an insight for our symbol, predicting that it will move down within the fast ema period number of days
Insight.Price(ticker, timedelta(self.FastEmaPeriod), InsightDirection.Down)
)
self.Liquidate(ticker)
self.SetHoldings(ticker, 0)
self.Debug("Take Profit!")
def ControlExposureLevel(self):
global total_equity_
global exp_factor
global _sign
global no_ctr
delta_total_equity = (total_equity_[-1] - total_equity_[-2]) / total_equity_[-2]
if delta_total_equity < 0 and np.abs(delta_total_equity) > 0.0125:
_sign = 0
no_ctr = [6, 6, 6, 6]
else:
_sign = +1
no_ctr = [0, 0, 0, 0]
for ticker in self.tickers:
if self.Portfolio[ticker].UnrealizedProfit < 0 and np.abs(self.Portfolio[ticker].UnrealizedProfit) >= (loss_factor *self.Portfolio.TotalPortfolioValue):
if ticker == self.targets1:
no_ctr[0] = 6
elif ticker == self.targets2:
no_ctr[1] = 6
elif ticker == self.targets3:
no_ctr[2] = 6
elif ticker == self.targets4:
no_ctr[3] = 6
else:
if ticker == self.targets1:
no_ctr[0] = 0
elif ticker == self.targets2:
no_ctr[1] = 0
elif ticker == self.targets3:
no_ctr[2] = 0
elif ticker == self.targets4:
no_ctr[3] = 0
def ControlDrawdownLevel(self):
global total_equity_
global DD_arr
self.account_leverage = self.Portfolio.TotalHoldingsValue / self.Portfolio.TotalPortfolioValue
total_equity_ = np.append(total_equity_, self.Portfolio.TotalPortfolioValue)
if total_equity_[-1] != 0 and self.account_leverage != 0:
diff = float(np.abs(total_equity_[-1] - total_equity_[-2])) / float(total_equity_[-1])
drawdown = float(diff) / float(self.account_leverage)
DD_arr = np.append(DD_arr, self.truncate(drawdown, 2))
if drawdown >= 0.10:
self.Debug("Leverage control ahead!")
for ticker in self.tickers:
self.EmitInsights(
# Creates an insight for our symbol, predicting that it will move down within the fast ema period number of days
Insight.Price(ticker, timedelta(self.FastEmaPeriod), InsightDirection.Down)
)
self.Liquidate(ticker)
self.SetHoldings(ticker, 0)
def truncate(self, number, decimals=0):
"""
Returns a value truncated to a specific number of decimal places.
"""
if not isinstance(decimals, int):
raise TypeError("decimal places must be an integer.")
elif decimals < 0:
raise ValueError("decimal places has to be 0 or more.")
elif decimals == 0:
return math.trunc(number)
factor = 10.0 ** decimals
return math.trunc(number * factor) / factor
def create_dataset(self, dataset, look_back=1):
dataX, dataY = [], []
for i in range(len(dataset)-look_back-1):
a = dataset[i:(i+look_back), 0]
dataX.append(a)
dataY.append(dataset[i + look_back, 0])
return np.array(dataX), np.array(dataY)
def scale(self, X, x_min, x_max):
nom = (X-X.min(axis=0))*(x_max-x_min)
denom = X.max(axis=0) - X.min(axis=0)
denom[denom==0] = 1
return x_min + nom/denom
def LSTM(self, dataset, scaler_factor):
dataset = dataset.reshape(-1, 1)
# split into train and test sets
train_size = int(len(dataset) * 0.67)
test_size = len(dataset) - train_size
train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]
# reshape into X=t and Y=t+1
look_back = 10
trainX, trainY = self.create_dataset(train, look_back)
testX, testY = self.create_dataset(test, look_back)
# reshape input to be [samples, time steps, features]
trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1]))
testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1]))
# create and fit the LSTM network
model = Sequential()
model.add(LSTM(36, input_shape=(1, look_back)))
model.add(Dense(1))
model.compile(loss='binary_crossentropy', optimizer='adam')
model.fit(trainX, trainY, epochs=10, batch_size=1000, verbose=0)
# make predictions
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
# invert predictions
trainPredict = scaler_factor.inverse_transform(trainPredict)
trainY = scaler_factor.inverse_transform([trainY])
testPredict = scaler_factor.inverse_transform(testPredict)
testY = scaler_factor.inverse_transform([testY])
# calculate root mean squared error
trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0]))
print('Train Score: %.2f RMSE' % (trainScore))
testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:,0]))
print('Test Score: %.2f RMSE' % (testScore))
return [np.mean(testPredict[:, 0])]
def ML_engine(self, history):
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
# load pima indians dataset
#print(history)
dataset = history
# create {Classifier} model
model = xgb.XGBClassifier(learning_rate=0.1, n_estimators=100, max_depth=4,
min_child_weight=6, gamma=0, subsample=0.8, colsample_bytree=0.8, reg_alpha=0.005,
objective= 'binary:logistic', nthread=4, scale_pos_weight=1, seed=27)
X = np.array(dataset[0:(len(dataset) - 1):2]).reshape(-1, 1).tolist()
Y = np.array(dataset[1:(len(dataset) - 0):2]).reshape(-1, 1).tolist()
X = pd.DataFrame(X)
y = pd.DataFrame(Y)
data_dmatrix = xgb.DMatrix(data=X, label=y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=None)
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y_train = le.fit_transform(y_train)
model.fit(X_train, y_train)
kfold = KFold(n_splits=2, random_state=None)
results = cross_val_score(model, X_train, y_train, cv=kfold)
#self.calc_net_perf(model, X_train, X_test, y_train, y_test, prediction)
if np.isnan(np.mean(results)):
# calculate predictions
prediction = model.predict(pd.DataFrame(np.array(X_test).reshape(-1, 1).tolist()))
print(prediction)
else:
prediction = results
prediction = int(np.round(np.mean(prediction)))
return prediction
def ML_engine1(self, history):
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
# load pima indians dataset
#print(history)
dataset = history
# create {Classifier} model
model = xgb.XGBRegressor(base_score=0.5, booster='gblinear', colsample_bylevel=None,
colsample_bynode=None, colsample_bytree=None, gamma=None,
gpu_id=-1, importance_type='gain', interaction_constraints=None,
learning_rate=0.15, max_delta_step=None, max_depth=15,
min_child_weight=3, monotone_constraints=None,
n_estimators=100, n_jobs=16, num_parallel_tree=None,
random_state=0, reg_alpha=0, reg_lambda=0, scale_pos_weight=1,
subsample=None, tree_method=None, validate_parameters=1,
verbosity=None)
X = np.array(dataset[0:(len(dataset) - 1):2]).reshape(-1, 1).tolist()
Y = np.array(dataset[1:(len(dataset) - 0):2]).reshape(-1, 1).tolist()
X = pd.DataFrame(X)
y = pd.DataFrame(Y)
data_dmatrix = xgb.DMatrix(data=X, label=y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=None)
model.fit(X_train, y_train)
kfold = KFold(n_splits=10, random_state=None)
results = cross_val_score(model, X_train, y_train, cv=kfold)
# calculate predictions
prediction = np.mean(results)
#self.calc_net_perf(model, X_train, X_test, y_train, y_test, prediction)
return prediction
def LinearRegr(self, history):
# Fitting Linear Regression to the dataset
from sklearn.linear_model import LinearRegression
# load pima indians dataset
dataset = history
#minimum = np.min(dataset)
#maximum = np.max(dataset)
X = np.array(dataset[0:(len(dataset) - 1):2]).reshape(-1, 1).tolist()
y = np.array(dataset[1:(len(dataset) - 0):2]).reshape(-1, 1).tolist()
lin_reg = LinearRegression()
lin_reg.fit(X, y)
# Predicting a new result with Linear Regression
out = lin_reg.predict([[dataset[-1]]])
return out
def GetCloseProfit(self):
global profit_factor
for ticker in self.tickers:
if self.Portfolio[ticker].UnrealizedProfit > 0 and self.Portfolio[ticker].UnrealizedProfit >= (profit_factor *self.Portfolio.TotalPortfolioValue):
self.Log("{Manually} closing open order(s)..")
self.Liquidate(ticker)
self.SetHoldings(ticker, 0)
def GetCloseLoss(self):
global loss_factor
for ticker in self.tickers:
if self.Portfolio[ticker].UnrealizedProfit < 0 and np.abs(self.Portfolio[ticker].UnrealizedProfit) >= (loss_factor *self.Portfolio.TotalPortfolioValue):
self.Log("{Manually} closing open order(s)..")
self.Liquidate(ticker)
self.SetHoldings(ticker, 0)
def GetClose(self):
for ticker in self.tickers:
self.Liquidate(ticker)
self.SetHoldings(ticker, 0)
self.Log("Liquidating..")
def AdaptEquityInvestement(self):
global trading_quantum
trading_quantum += 1.0
self.Log("Month change!")
self.Log("Portfolio invested cash (current):: " + str(self.Portfolio.TotalMarginUsed))
def GetWeekData(self):
global weekly_stockprices_arr
global weekly_stockprices_arr1
global weekly_stockprices_arr2
global weekly_stockprices_arr3
global weekly_stockprices_arr4
global btcusd_a0
global ethusd_a0
global dotusd_a0
global ltcusd_a0
weekly_stockprices_arr1 = np.append(weekly_stockprices_arr1, btcusd_a0)
weekly_stockprices_arr2 = np.append(weekly_stockprices_arr2, ethusd_a0)
weekly_stockprices_arr3 = np.append(weekly_stockprices_arr3, dotusd_a0)
weekly_stockprices_arr4 = np.append(weekly_stockprices_arr4, ltcusd_a0)
weekly_stockprices_arr = [weekly_stockprices_arr1, weekly_stockprices_arr2, weekly_stockprices_arr3, weekly_stockprices_arr4]
def Initialize(self):
global X
global U
global Z
global scheduled_event_1
#Brokerage model and account type:
self.SetBrokerageModel(BrokerageName.ALPHA_STREAMS, AccountType.Margin)
self.SetStartDate(2020, 1, 1) # Set Start Date
self.SetCash(1000000)
#self.SetCash("BTC", start_equity_amount) # Set Strategy Cash
# Select asset data
self.tickers = ["BTCUSD", "ETHUSD", "BTCEUR", "LTCUSD"]
self.leverage_targets1 = 10.0
self.leverage_targets2 = 5.0
self.leverage_targets3 = 3.3
self.leverage_targets4 = 5.0
self.leverage_targets_default = 1.0
self.btcusd = self.AddCrypto(self.tickers[0], Resolution.HOUR, Market.KRAKEN, leverage=self.leverage_targets1).Symbol
self.targets1 = "BTCUSD"
self.ethusd = self.AddCrypto(self.tickers[1], Resolution.HOUR, Market.KRAKEN, leverage=self.leverage_targets2).Symbol
self.targets2 = "ETHUSD"
self.dotusd = self.AddCrypto(self.tickers[2], Resolution.HOUR, Market.KRAKEN, leverage=self.leverage_targets3).Symbol
self.targets3 = "BTCEUR"
self.ltcusd = self.AddCrypto(self.tickers[3], Resolution.HOUR, Market.KRAKEN, leverage=self.leverage_targets4).Symbol
self.targets4 = "LTCUSD"
self.max_portfolio_leverage = 1.5 # for crypto margin accounts; set 1.0 for cash-like behavior
self.min_free_margin_ratio = 0.10 # stop opening new risk if remaining margin < 10% of total
self.last_reject_time = {} # Symbol -> datetime, for cooldown
self.reject_cooldown_minutes = 60
# Create a Rolling Window to keep the 1440 decimal
self.closeWindow1 = RollingWindow[float](1440)
self.closeWindow2 = RollingWindow[float](1440)
self.closeWindow3 = RollingWindow[float](1440)
self.closeWindow4 = RollingWindow[float](1440)
# the scheduling methods return the ScheduledEvent object which can be used
# for other things here I set the event up to check the portfolio value every
# X minutes, and liquidate if we have too many losses
scheduled_event_1 = self.Schedule.On(self.DateRules.EveryDay(), \
self.TimeRules.Every(timedelta(minutes=U *X)), \
self.ChangeHourFlag)
self.Schedule.On(self.DateRules.WeekStart("BTCUSD"), \
self.TimeRules.At(0, 0, 0), \
self.GetWeekData)
self.Schedule.On(self.DateRules.WeekStart("ETHUSD"), \
self.TimeRules.At(0, 0, 0), \
self.GetWeekData)
self.Schedule.On(self.DateRules.WeekStart("BTCEUR"), \
self.TimeRules.At(0, 0, 0), \
self.GetWeekData)
self.Schedule.On(self.DateRules.WeekStart("LTCUSD"), \
self.TimeRules.At(0, 0, 0), \
self.GetWeekData)
self.Schedule.On(self.DateRules.MonthStart("BTCUSD"), \
self.TimeRules.At(0, 0, 0), \
self.AdaptEquityInvestement)
self.Schedule.On(self.DateRules.MonthStart("ETHUSD"), \
self.TimeRules.At(0, 0, 0), \
self.AdaptEquityInvestement)
self.Schedule.On(self.DateRules.MonthStart("BTCEUR"), \
self.TimeRules.At(0, 0, 0), \
self.AdaptEquityInvestement)
self.Schedule.On(self.DateRules.MonthStart("LTCUSD"), \
self.TimeRules.At(0, 0, 0), \
self.AdaptEquityInvestement)
self.Schedule.On(self.DateRules.EveryDay(), \
self.TimeRules.Every(timedelta(minutes=(U *X))), \
self.ControlDrawdownLevel)
self.Schedule.On(self.DateRules.EveryDay(), \
self.TimeRules.Every(timedelta(minutes=(U *X))), \
self.ControlExposureLevel)
'''
self.Schedule.On(self.DateRules.EveryDay(), \
self.TimeRules.Every(timedelta(minutes=(Z *X))), \
self.GetCloseLoss)
'''
self.Schedule.On(self.DateRules.EveryDay(), \
self.TimeRules.Every(timedelta(minutes=(U *X))), \
self.TakeProfit)
self.Schedule.On(self.DateRules.EveryDay(),
self.TimeRules.At(9, 31),
Action(self.One))
# Feed in 1440 bars before start date:
self.SetWarmup(1440)
self.warmup_period = 1440
consolidator1 = TradeBarConsolidator(timedelta(1))
consolidator1.DataConsolidated += self.OnDailyData
self.SubscriptionManager.AddConsolidator("BTCUSD", consolidator1)
consolidator2 = TradeBarConsolidator(timedelta(1))
consolidator2.DataConsolidated += self.OnDailyData
self.SubscriptionManager.AddConsolidator("ETHUSD", consolidator2)
consolidator3 = TradeBarConsolidator(timedelta(1))
consolidator3.DataConsolidated += self.OnDailyData
self.SubscriptionManager.AddConsolidator("BTCEUR", consolidator3)
consolidator4 = TradeBarConsolidator(timedelta(1))
consolidator4.DataConsolidated += self.OnDailyData
self.SubscriptionManager.AddConsolidator("LTCUSD", consolidator4)
consolidatorm1 = TradeBarConsolidator(60)
consolidatorm1.DataConsolidated += self.OnMinuteData
self.SubscriptionManager.AddConsolidator("BTCUSD", consolidatorm1)
consolidatorm2 = TradeBarConsolidator(60)
consolidatorm2.DataConsolidated += self.OnMinuteData
self.SubscriptionManager.AddConsolidator("ETHUSD", consolidatorm2)
consolidatorm3 = TradeBarConsolidator(60)
consolidatorm3.DataConsolidated += self.OnMinuteData
self.SubscriptionManager.AddConsolidator("BTCEUR", consolidatorm3)
consolidatorm4 = TradeBarConsolidator(60)
consolidatorm4.DataConsolidated += self.OnMinuteData
self.SubscriptionManager.AddConsolidator("LTCUSD", consolidatorm4)
self.daily1 = RollingWindow[TradeBar](2)
self.minute1 = RollingWindow[TradeBar](2)
self.window1 = RollingWindow[TradeBar](2)
self.daily2 = RollingWindow[TradeBar](2)
self.minute2 = RollingWindow[TradeBar](2)
self.window2 = RollingWindow[TradeBar](2)
self.daily3 = RollingWindow[TradeBar](2)
self.minute3 = RollingWindow[TradeBar](2)
self.window3 = RollingWindow[TradeBar](2)
self.daily4 = RollingWindow[TradeBar](2)
self.minute4 = RollingWindow[TradeBar](2)
self.window4 = RollingWindow[TradeBar](2)
self._newHour = False
self._newDay = False
global daily_trade_flag_en
daily_trade_flag_en = False
global hourly_trade_flag_en
hourly_trade_flag_en = False
self.dayswarmup = 14
self.conf_swing_level = 0.0
self.dataframe = [[], [], [], []]
self.trainsignaldatabase = [[], [], [], []]
self.deltapricesdatabase = [[], [], [], []]
self.feature_window = (((2 *U) - 1) *60)
self.mom_arr = []
def One(self):
if not (self.window1.IsReady and self.daily1.IsReady and self.minute1.IsReady): return
if not (self.window2.IsReady and self.daily2.IsReady and self.minute2.IsReady): return
if not (self.window3.IsReady and self.daily3.IsReady and self.minute3.IsReady): return
if not (self.window4.IsReady and self.daily4.IsReady and self.minute4.IsReady): return
currBar1 = self.window1[0].Close
yesterdayc1 = self.daily1[1].Close
minuteBarC1 = self.minute1[1].Close
minuteBar01 = self.minute1[1].Open
currBar2 = self.window2[0].Close
yesterdayc2 = self.daily2[1].Close
minuteBarC2 = self.minute2[1].Close
minuteBar02 = self.minute2[1].Open
currBar3 = self.window3[0].Close
yesterdayc3 = self.daily3[1].Close
minuteBarC3 = self.minute3[1].Close
minuteBar03 = self.minute3[1].Open
currBar4 = self.window4[0].Close
yesterdayc4 = self.daily4[1].Close
minuteBarC4 = self.minute4[1].Close
minuteBar04 = self.minute4[1].Open
# Add daily bar to daily rolling window
def OnDailyData(self, sender, bar):
self.daily1.Add(bar)
self.daily2.Add(bar)
self.daily3.Add(bar)
self.daily4.Add(bar)
def OnMinuteData(self, sender, bar):
self.minute1.Add(bar)
self.minute2.Add(bar)
self.minute3.Add(bar)
self.minute4.Add(bar)
def ChangeHourFlag(self):
self._newHour = True
def OnEndOfDay(self):
self._newDay = True
def SafeMarketOrder(self, symbol, target_percent, tag="rebalance"):
# 1) avoid stacking orders (keep your edited guard style)
if self.Transactions.GetOpenOrders(symbol):
return None
sec = self.Securities[symbol]
if not sec.HasData or sec.Price <= 0:
return None
# 2) (optional) don’t trade during warmup
if self.IsWarmingUp:
return None
# 3) hard cap the target exposure (adjust to taste)
# for cash-like crypto, keep <= 1.0; for margin, you can allow >1 but be careful
max_abs_target = 1.0
target_percent = max(-max_abs_target, min(max_abs_target, float(target_percent)))
# 4) get the *order quantity* that matches the target % and respects buying power
qty = self.CalculateOrderQuantity(symbol, target_percent) # QC helper
if qty is None or abs(qty) < 1e-8:
return None
# 5) place the order (delta quantity)
return self.MarketOrder(symbol, qty, tag=tag)
def OnOrderEvent(self, orderEvent: OrderEvent):
if orderEvent.Status == OrderStatus.Invalid:
self.last_reject_time[orderEvent.Symbol] = self.Time
if orderEvent.Status == OrderStatus.Canceled:
# sometimes buying power rejections show as canceled in certain models
self.last_reject_time[orderEvent.Symbol] = self.Time
def OnData(self, data):
global daily_trades_allowance_quant
global daily_trades_allowance_quant_thresh
global minute_trades_allowance_quant
global minute_trades_allowance_quant_thresh
global daily_trade_flag_en
global hourly_trade_flag_en
global bet_arr
global hist_arr
global arr1
global arr2
global min_border
global max_border
global trading_quantum
global X
global scaler
global margins_border
global dataset
global profit_factor
global normalized
global projected_price
global rsi_interval
global __quantity
global total_equity
global day_close_price_arr
global high_price_arr1
global high_price_arr2
global high_price_arr3
global high_price_arr4
global low_price_arr1
global low_price_arr2
global low_price_arr3
global low_price_arr4
global volume_arr1
global volume_arr2
global volume_arr3
global volume_arr4
global datetime_arr
global open_price_arr1
global open_price_arr2
global open_price_arr3
global open_price_arr4
global close_price_arr1
global close_price_arr2
global close_price_arr3
global close_price_arr4
global day_close_price_arr1
global day_close_price_arr2
global day_close_price_arr3
global day_close_price_arr4
global verbage
global DD_arr
global t_indicator_arr
global delta_prediction_arr
global real
global last_trade_order
global a0_arr
global btcusd_a0
global ethusd_a0
global dotusd_a0
global ltcusd_a0
global offset
global sign
global sign_
global weekly_stockprices_arr
global out_DD
global sign_inp_arr
global rsi_intra_daily
global exp_factor
global no_ctr
global episode_list
global sign_arr
global _sign
global mom_array
global rsi_intra_daily_array
global exposure_risk_factor
global dayscounter
global enable_live_mode
for ticker in self.tickers:
if data.ContainsKey(ticker):
# Add crypto bar close in the rolling window
if ticker == "BTCUSD":
self.closeWindow1.Add(data["BTCUSD"].Close)
elif ticker == "ETHUSD":
self.closeWindow2.Add(data["ETHUSD"].Close)
elif ticker == "BTCEUR":
self.closeWindow3.Add(data["BTCEUR"].Close)
elif ticker == "LTCUSD":
self.closeWindow4.Add(data["LTCUSD"].Close)
for ticker in self.tickers:
if data[ticker] is None : return
# Wait for window(s) to be ready.
if not self.closeWindow1.IsReady: return
if not self.closeWindow2.IsReady: return
if not self.closeWindow3.IsReady: return
if not self.closeWindow4.IsReady: return
for ticker in self.tickers:
if data.Bars.ContainsKey(ticker):
if ticker == "BTCUSD":
self.window1.Add(data.Bars["BTCUSD"])
elif ticker == "ETHUSD":
self.window2.Add(data.Bars["ETHUSD"])
elif ticker == "BTCEUR":
self.window3.Add(data.Bars["BTCEUR"])
elif ticker == "LTCUSD":
self.window4.Add(data.Bars["LTCUSD"])
if not (self.window1.IsReady and self.daily1.IsReady): return
if not (self.window2.IsReady and self.daily2.IsReady): return
if not (self.window3.IsReady and self.daily3.IsReady): return
if not (self.window4.IsReady and self.daily4.IsReady): return
# fix random seed for reproducibility
np.random.seed(7)
'''
self.GetCloseLoss()
self.GetCloseProfit()
'''
if self._newDay == True:
daily_trades_allowance_quant = 0
daily_trade_flag_en = True
self._newDay = False
dayscounter += 1
if dayscounter >= self.dayswarmup:
'''enable_live_mode = True'''
exposure_risk_factor += 0.1
if exposure_risk_factor > 4.0:
exposure_risk_factor = 4.0
self.Log("Day change!")
if self._newHour == True:
minute_trades_allowance_quant = 0
hourly_trade_flag_en = True
self._newHour = False
open_1 = np.array(self.daily1[1].Open, float).ravel()
open_price_arr1 = np.append(open_price_arr1, open_1)
open_price_arr1 = open_price_arr1[-self.warmup_period:]
open_2 = np.array(self.daily2[1].Open, float).ravel()
open_price_arr2 = np.append(open_price_arr2, open_2)
open_price_arr2 = open_price_arr2[-self.warmup_period:]
open_3 = np.array(self.daily3[1].Open, float).ravel()
open_price_arr3 = np.append(open_price_arr3, open_3)
open_price_arr3 = open_price_arr3[-self.warmup_period:]
open_4 = np.array(self.daily4[1].Open, float).ravel()
open_price_arr4 = np.append(open_price_arr4, open_4)
open_price_arr4 = open_price_arr4[-self.warmup_period:]
close_1 = np.array(self.daily1[1].Close, float).ravel()
close_price_arr1 = np.append(close_price_arr1, close_1)
close_price_arr1 = close_price_arr1[-self.warmup_period:]
close_2 = np.array(self.daily2[1].Close, float).ravel()
close_price_arr2 = np.append(close_price_arr2, close_2)
close_price_arr2 = close_price_arr2[-self.warmup_period:]
close_3 = np.array(self.daily3[1].Close, float).ravel()
close_price_arr3 = np.append(close_price_arr3, close_3)
close_price_arr3 = close_price_arr3[-self.warmup_period:]
close_4 = np.array(self.daily4[1].Close, float).ravel()
close_price_arr4 = np.append(close_price_arr4, close_4)
close_price_arr4 = close_price_arr4[-self.warmup_period:]
high_1 = self.daily1[1].High
high_price_arr1 = np.append(high_price_arr1, high_1)
high_price_arr1 = high_price_arr1[-self.warmup_period:]
high_2 = self.daily2[1].High
high_price_arr2 = np.append(high_price_arr2, high_2)
high_price_arr2 = high_price_arr2[-self.warmup_period:]
high_3 = self.daily3[1].High
high_price_arr3 = np.append(high_price_arr3, high_3)
high_price_arr3 = high_price_arr3[-self.warmup_period:]
high_4 = self.daily4[1].High
high_price_arr4 = np.append(high_price_arr4, high_4)
high_price_arr4 = high_price_arr4[-self.warmup_period:]
low_1 = self.daily1[1].Low
low_price_arr1 = np.append(low_price_arr1, low_1)
low_price_arr1 = low_price_arr1[-self.warmup_period:]
low_2 = self.daily2[1].Low
low_price_arr2 = np.append(low_price_arr2, low_2)
low_price_arr2 = low_price_arr2[-self.warmup_period:]
low_3 = self.daily3[1].Low
low_price_arr3 = np.append(low_price_arr3, low_3)
low_price_arr3 = low_price_arr3[-self.warmup_period:]
low_4 = self.daily4[1].Low
low_price_arr4 = np.append(low_price_arr4, low_4)
low_price_arr4 = low_price_arr4[-self.warmup_period:]
yesterdayc1 = self.daily1[1].Close
day_close_price_arr1 = np.append(day_close_price_arr1, yesterdayc1)
day_close_price_arr1 = day_close_price_arr1[-self.warmup_period:]
yesterdayc2 = self.daily2[1].Close
day_close_price_arr2 = np.append(day_close_price_arr2, yesterdayc2)
day_close_price_arr2 = day_close_price_arr2[-self.warmup_period:]
yesterdayc3 = self.daily3[1].Close
day_close_price_arr3 = np.append(day_close_price_arr3, yesterdayc3)
day_close_price_arr3 = day_close_price_arr3[-self.warmup_period:]
yesterdayc4 = self.daily4[1].Close
day_close_price_arr4 = np.append(day_close_price_arr4, yesterdayc4)
day_close_price_arr4 = day_close_price_arr4[-self.warmup_period:]
volume1 = self.daily1[1].Volume
volume_arr1 = np.append(volume_arr1, volume1)
volume_arr1 = volume_arr1[-self.warmup_period:]
volume2 = self.daily2[1].Volume
volume_arr2 = np.append(volume_arr2, volume2)
volume_arr2 = volume_arr2[-self.warmup_period:]
volume3 = self.daily3[1].Volume
volume_arr3 = np.append(volume_arr3, volume3)
volume_arr3 = volume_arr3[-self.warmup_period:]
volume4 = self.daily4[1].Volume
volume_arr4 = np.append(volume_arr4, volume4)
volume_arr4 = volume_arr4[-self.warmup_period:]
self.Log("(Virtual) Hour change!")
else:
return
day_close_price_arr = [day_close_price_arr1, day_close_price_arr2, day_close_price_arr3, day_close_price_arr4]
open_price_arr = [open_price_arr1, open_price_arr2, open_price_arr3, open_price_arr4]
high_price_arr = [high_price_arr1, high_price_arr2, high_price_arr3, high_price_arr4]
low_price_arr = [low_price_arr1, low_price_arr2, low_price_arr3, low_price_arr4]
close_price_arr = [close_price_arr1, close_price_arr2, close_price_arr3, close_price_arr4]
volume_arr = [volume_arr1, volume_arr2, volume_arr3, volume_arr4]
self.Debug("Current trade date:" + "\t" + str(self.Time))
self.Log(str(self.Portfolio.TotalPortfolioValue))
self.closeWindow = [self.closeWindow1, self.closeWindow2, self.closeWindow3, self.closeWindow4]
datetime_arr = np.append(datetime_arr, self.Time.strftime('%Y-%m-%d'))
ticker_idx = 0
for ticker in self.tickers:
tmp_arr_values = []
tmp_arr_values1 = []
tmp_arr_values2 = []
for index in range(1439, 0, -1):
tmp_arr_values = np.append(tmp_arr_values, self.closeWindow[ticker_idx][index])
delta = (self.closeWindow[ticker_idx][(index - 1)] - self.closeWindow[ticker_idx][index])
tmp_arr_values1 = np.append(tmp_arr_values1, delta)
if self.closeWindow[ticker_idx][index] <= self.closeWindow[ticker_idx][(index - 1)]:
signal = 1
else:
signal = 0
tmp_arr_values1 = np.append(tmp_arr_values1, signal)
self.dataframe[ticker_idx] = tmp_arr_values
self.deltapricesdatabase[ticker_idx] = tmp_arr_values1
self.trainsignaldatabase[ticker_idx] = tmp_arr_values2
self.hist = self.dataframe[ticker_idx]
historical_train_data = self.hist
a0_arr = np.append(a0_arr, np.mean(historical_train_data))
stockprices = historical_train_data
upperband, middleband, lowerband = ta.BBANDS(np.array(stockprices).ravel()*100000, timeperiod=90, nbdevup=2, nbdevdn=2,matype=0)
upVal = upperband[-1]/100000
middleVal = middleband[-1]/100000
lowVal = lowerband[-1]/100000
a = np.array([upVal, middleVal, lowVal])
a0 = self.closeWindow[ticker_idx][0]
projected_price = a.flat[np.abs(a - a0).argmin()]
projected_price = projected_price[np.logical_not(np.isnan(projected_price))]
if len(datetime_arr) >= 5:
# Correct column extraction + 1D flatten
hp = np.asarray(high_price_arr)[:, ticker_idx].ravel()
lp = np.asarray(low_price_arr)[:, ticker_idx].ravel()
op = np.asarray(open_price_arr)[:, ticker_idx].ravel()
cp = np.asarray(close_price_arr)[:, ticker_idx].ravel()
vol = np.asarray(volume_arr)[:, ticker_idx].ravel()
dcp = np.asarray(day_close_price_arr)[:, ticker_idx].ravel()
dt = np.asarray(datetime_arr).ravel()
# Make all vectors same length (trim to shortest)
n = min(len(dt), len(hp), len(lp), len(op), len(cp), len(vol), len(dcp))
dt, hp, lp, op, cp, vol, dcp = dt[:n], hp[:n], lp[:n], op[:n], cp[:n], vol[:n], dcp[:n]
attribute = np.column_stack((dt, hp, lp, op, cp, vol, dcp)).tolist()
if np.asarray(attribute).ndim > 1:
verbage = RQ.get_daily(np.asarray(attribute))
else:
verbage = "NONE"
self.Debug(str(verbage))
if len(day_close_price_arr) >= 14:
real1 = ta.AD(np.array(high_price_arr[ticker_idx][-14:], float).ravel(), np.array(low_price_arr[ticker_idx][-14:], float).ravel(), np.array(day_close_price_arr[ticker_idx][-14:], float).ravel(), np.array(volume_arr[ticker_idx][-14:], float).ravel())
real1 = np.mean(real1[np.logical_not(np.isnan(real1))])
else:
real1 = -1.0
if len(day_close_price_arr) >= 14:
real2 = ta.MFI(high_price_arr[ticker_idx], low_price_arr[ticker_idx], close_price_arr[ticker_idx], volume_arr[ticker_idx], timeperiod=14)
real2 = np.mean(real2[np.logical_not(np.isnan(real2))])
else:
real2 = -1
arr1 = np.append(arr1, self.truncate(a0, 4))
bet_arr = np.append(bet_arr, projected_price)
arr2 = np.append(arr2, self.truncate(np.abs(bet_arr[-1]), 4))
close = arr1[-1]
stopPriceBuy = close * .99 # Trigger stop limit when price falls 1%.
stopPriceSell = close * 1.01 # Trigger stop limit when price falls 1%.
if len(stockprices) > rsi_interval:
_data_ = np.array(stockprices, float)
rsi = ta.RSI(_data_.ravel(), timeperiod=rsi_interval)
rsi = rsi[np.logical_not(np.isnan(rsi))][-1]
else:
return
if len(weekly_stockprices_arr[ticker_idx]) > rsi_interval:
_data_ = np.array(weekly_stockprices_arr[ticker_idx], float)
rsi_intra_daily = ta.RSI(_data_.ravel(), timeperiod=rsi_interval)
rsi_intra_daily = rsi_intra_daily[np.logical_not(np.isnan(rsi_intra_daily))][-1]
else:
rsi_intra_daily = 50
rsi_intra_daily_array[ticker_idx] = np.append(rsi_intra_daily_array[ticker_idx], rsi_intra_daily)
real = ta.MOM(stockprices, timeperiod=10)
real = np.mean(real[np.logical_not(np.isnan(real))])
prices = historical_train_data
price_hist = historical_train_data[-240:]
ma1 = np.mean(price_hist)
price_hist = historical_train_data[-1200:]
ma2 = np.mean(price_hist)
start_bar = self.feature_window
price_list = prices
X = [] # list of feature sets
y = [] # list of labels, one for each feature set
bar = start_bar
# feature creation
while bar < len(price_list)-1:
try:
end_price = price_list[bar+1] # "tomorrow"'s price'
begin_price = price_list[bar] # today's price
pricing_list = []
xx = 0
for _ in range(self.feature_window):
price = price_list[bar-(self.feature_window-xx)]
pricing_list.append(price)
xx += 1
# get the % change in daily prices of last 10 days
features = np.around(np.diff(pricing_list) / pricing_list[:-1] * 100.0, 1)
# if tomorrow's price is more than today's price
# label the feature set (% change in last 10 days)
# a 1 (strong outlook, buy) else -1 (weak outlook, sell)
if end_price > begin_price:
label = 1
else:
label = -1
bar += 1
X.append(features)
y.append(label)
# print(features)
except Exception as e:
bar += 1
print(('feature creation',str(e)))
clf1 = RandomForestClassifier()
clf2 = LinearSVC()
##clf3 = NuSVC()
#clf3 = SVC()
clf3 = OneClassSVM()
clf4 = LogisticRegression()
# now we get the prices and features for the last 10 days
last_prices = price_list[-self.feature_window:]
current_features = np.around(np.diff(last_prices) / last_prices[:-1] * 100.0, 1)
# append the last 10 days feature set
# scale the data (mean becomes zero, SD = 0), necessary for ML algo to work
X.append(current_features)
X = preprocessing.scale(np.reshape(X, (-1, 1)))
# the current feature will be the last SCALED feature set
# X will be all the feature sets, excluding the most recent one,
# this is the feature set which we will be using to predict
current_features = X[-1]
X = X[:-1]
if len(np.unique(np.reshape(y, (-1, 1)))) == 1:
return
# create {XGB Classification} model
clf5 = xgb.XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,
colsample_bynode=1, colsample_bytree=1, eval_metric='mlogloss',
gamma=0, gpu_id=-1, importance_type='gain',
interaction_constraints='', learning_rate=0.300000012,
max_delta_step=0, max_depth=6, min_child_weight=1, missing=1,
monotone_constraints='()', n_estimators=100, n_jobs=16,
num_parallel_tree=1, objective='binary:hinge', random_state=0,
reg_alpha=0, reg_lambda=1, scale_pos_weight=None, subsample=1,
tree_method='exact', use_label_encoder=False,
validate_parameters=1, verbosity=None)
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y_train = le.fit_transform(np.reshape(y, (-1, 1)))
clf1.fit(X[-len(np.reshape(y, (-1, 1))):], np.reshape(y, (-1, 1)))
clf2.fit(X[-len(np.reshape(y, (-1, 1))):], np.reshape(y, (-1, 1)))
clf3.fit(X[-len(np.reshape(y, (-1, 1))):], np.reshape(y, (-1, 1)))
clf4.fit(X[-len(np.reshape(y, (-1, 1))):], np.reshape(y, (-1, 1)))
clf5.fit(X[-len(np.reshape(y, (-1, 1))):], y_train)
p1 = clf1.predict(np.reshape(current_features, (-1, 1)))[0]
p2 = clf2.predict(np.reshape(current_features, (-1, 1)))[0]
p3 = clf3.predict(np.reshape(current_features, (-1, 1)))[0]
p4 = clf4.predict(np.reshape(current_features, (-1, 1)))[0]
p5 = clf5.predict(np.reshape(current_features, (-1, 1)))[0]
if Counter([p1,p2,p3,p4,p5]).most_common(1)[0][1] >= no_ctr[ticker_idx]:
p = Counter([p1,p2,p3,p4,p5]).most_common(1)[0][0]
else:
p = 0
print(('ma1_d: ',ma1))
print(('ma2_d :',ma2))
print(('p1 :',p1))
print(('p2 :',p2))
print(('p3 :',p3))
print(('p4 :',p4))
print(('p5 :',p5))
self.Debug('Prediction' + "\t" + str(p))
if p == 1:
t_indicator = +1
elif p == -1:
t_indicator = -1
else:
t_indicator = 0
t_indicator_arr = np.append(t_indicator_arr, t_indicator)
if trading_quantum == 0 or trading_quantum < 0.00000001:
self.Log("Too low trade order size")
return
if ticker == "BTCUSD":
leverage = self.leverage_targets1
elif ticker == "ETHUSD":
leverage = self.leverage_targets2
elif ticker == "BTCEUR":
leverage = self.leverage_targets3
elif ticker == "LTCUSD":
leverage = self.leverage_targets4
buying_power = self.Portfolio.MarginRemaining
if buying_power <= 0:
return
if self.Transactions.GetOpenOrders(ticker):
return
if verbage == "HAMMER ":
self.conf_swing_level = -1.0
if verbage == "STAR ":
self.conf_swing_level = +1.0
if verbage == "MAJOR MOVE ":
'''
if mom_array[ticker_idx][-1] >= 0:
self.conf_swing_level = -1.0
self.SafeMarketOrder(ticker, leverage, tag="rebalance")
ticker_idx += 1
continue
elif mom_array[ticker_idx][-1] < 0:
self.conf_swing_level = +1.0
self.SafeMarketOrder(ticker, +leverage, tag="rebalance")
ticker_idx += 1
continue
'''
self.conf_swing_level = 0.0
if verbage == "GAP UP ":
self.conf_swing_level = -1.0
if verbage == "GAP DOWN ":
self.conf_swing_level = +1.0
if verbage == "BEARISH ENGULFING ":
self.conf_swing_level = -1.0
if verbage == "BULLISH ENGULFING ":
self.conf_swing_level = +1.0
if verbage == "PIERCING LINE ":
'''
if mom_array[ticker_idx][-1] >= 0:
self.SafeMarketOrder(ticker, +leverage, tag="rebalance")
ticker_idx += 1
continue
elif mom_array[ticker_idx][-1] < 0:
self.SafeMarketOrder(ticker, leverage, tag="rebalance")
ticker_idx += 1
continue
'''
self.conf_swing_level = 0.0
if verbage == "BLACK MARUBOZU ":
self.conf_swing_level = +1.0
if verbage == "WHITE MARUBOZU ":
self.conf_swing_level = -1.0
if verbage == "BEARISH DOJI ":
self.conf_swing_level = -1.0
if verbage == "BULLISH DOJI ":
self.conf_swing_level = -1.0
else:
self.conf_swing_level = 0.0
self.mom_arr = np.append(self.mom_arr, real1)
mom_array[ticker_idx] = np.append(mom_array[ticker_idx], self.mom_arr[-1])
if mode(t_indicator_arr[-1:]) == +1 and mom_array[ticker_idx][-1] >= 0 and rsi < 30 and projected_price >= np.max(a0_arr[-offset:]):
sign = -1
elif mode(t_indicator_arr[-1:]) == -1 and mom_array[ticker_idx][-1] < 0 and rsi > 70 and projected_price < np.min(a0_arr[-offset:]):
sign = +1
else:
if rsi_intra_daily_array[ticker_idx][-1] < 30:
sign = -1
elif rsi_intra_daily_array[ticker_idx][-1] > 70:
sign = 0
else:
sign = +1
if sign == -1 and mom_array[ticker_idx][-1] < 0 and rsi > 70:
exp_factor = 1.0
sign_ = +1
if real2 >= 50 and real2 <= 60:
exp_factor = 0.10
sign_ = -1
else:
if real2 < 30:
exp_factor = 1.0
sign_ = +1
elif real2 > 70:
exp_factor = 1.0
sign_ = -1
t_indicator_arr_ = t_indicator_arr[-16:]
count_minus1 = t_indicator_arr_[::-4].tolist().count(-1)
count_zero = t_indicator_arr_[::-4].tolist().count(0)
count_plus1 = t_indicator_arr_[::-4].tolist().count(+1)
if count_minus1 == 4:
sign__ = -1
if count_zero == 4:
sign__ = 0
if count_plus1 == 4:
sign__ = +1
else:
sign__ = +1
sign = sign__ *sign_ *sign
____quantity = (exposure_risk_factor *(exp_factor *(0.5 *leverage)))
_quantity = (exposure_risk_factor *(exp_factor *(0.33 *leverage)))
__quantity = (exposure_risk_factor *(exp_factor *(leverage)))
___quantity = (exposure_risk_factor *(exp_factor *(0.42 *leverage)))
if len(sign_inp_arr) > 10:
try:
sign_dec_1 = self.ML_engine(sign_inp_arr)
except:
sign_dec_1 = -sign
sign_dec_2 = sign
if sign_dec_1 != sign_dec_2:
sign = sign_dec_1
if mom_array[ticker_idx][-1] > 0:
_sign = -1
else:
_sign = +1
sign = _sign * sign
if enable_live_mode == True:
if rsi < 30 and t_indicator == -1:
for ticker in self.tickers:
if ticker == "BTCUSD":
leverage = self.leverage_targets1
elif ticker == "ETHUSD":
leverage = self.leverage_targets2
elif ticker == "BTCEUR":
leverage = self.leverage_targets3
elif ticker == "LTCUSD":
leverage = self.leverage_targets4
if self.Portfolio.MarginRemaining < 50:
return
if self.Transactions.GetOpenOrders(ticker):
return
# place orders here
self.SafeMarketOrder(ticker, +sign *leverage, tag="rebalance")
elif rsi > 70 and t_indicator == +1:
for ticker in self.tickers:
if ticker == "BTCUSD":
leverage = self.leverage_targets1
elif ticker == "ETHUSD":
leverage = self.leverage_targets2
elif ticker == "BTCEUR":
leverage = self.leverage_targets3
elif ticker == "LTCUSD":
leverage = self.leverage_targets4
if self.Portfolio.MarginRemaining < 50:
return
if self.Transactions.GetOpenOrders(ticker):
return
# place orders here
self.SafeMarketOrder(ticker, -sign *leverage, tag="rebalance")
else:
self.Liquidate(ticker)
self.SetHoldings(ticker, 0)
if self.Portfolio[ticker].UnrealizedProfit > 0 and self.Portfolio[ticker].UnrealizedProfit >= (profit_factor *self.Portfolio.TotalPortfolioValue):
sign_inp_arr = np.append(sign_inp_arr, sign)
exp_factor = 1.0
sign_ = +1
self.Liquidate(ticker)
self.SetHoldings(ticker, 0)
self.Log("Liquidating..")
ticker_idx += 1