Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wiseplat
GitHub Repository: wiseplat/python-code
Path: blob/master/ invest-robot-contest_TradingCompetition2022-main/models/ARIMAdeMarkLong.py
5925 views
1
from models.TradingModel import (TradingModel, ModelChecks)
2
from datetime import (date, timedelta, datetime)
3
import statsmodels.api as sm
4
import pandas as pd
5
6
7
class ARIMAdeMarkLong(TradingModel):
8
"""
9
Trading Model ARIMA + DeMark
10
ARIMA model forecasting trend and target
11
DeMark - find point for open position (if the price falls below the point of low DeMark
12
and come back to this point it will open position)
13
"""
14
15
# { Model checks name
16
_LOW_POINT = 'FALLS_BELOW_LOW_POINT' # Price falls below low point of DeMark
17
_IS_BACK_LOW_POINT = 'BACK_TO_LOW_POINT' # Price come back to low point of DeMark
18
_HIGH_POINT = 'UP_TO_HIGH_POINT' # Price up to high point of DeMark
19
# Model checks name }
20
21
def __init__(self, ticker, config):
22
super(ARIMAdeMarkLong, self).__init__(ticker, config)
23
# DeMark Low and High level
24
self._DeMark_low = None
25
self._DeMark_high = None
26
self._arima_predict_close = None
27
28
# This model available only for LONG orders
29
self._long_available = True
30
self._short_available = False
31
32
def custom_init(self):
33
super(ARIMAdeMarkLong, self).custom_init()
34
self._calculate_model()
35
# Check calc of model is ok or not
36
if self._check_model() is False:
37
self._long_available = False
38
39
def _check_model(self):
40
""" Check model """
41
if self._DeMark_low is None or self._DeMark_high is None:
42
return False
43
if self._DeMark_low > self._DeMark_high:
44
return False
45
if self._DeMark_low > self._arima_predict_close:
46
return False
47
return True
48
49
def _calculate_model(self):
50
""" Calculate ARIMA DeMark Model """
51
prev_date = date.today() - timedelta(20)
52
self._download_hist_data(start_date=prev_date, end_date=date.today())
53
if len(self._hist_data) > 0:
54
last_day = self._hist_data.iloc[-1]
55
pivot = None
56
if last_day.Close < last_day.Open:
57
pivot = (last_day.High + (last_day.Low * 2) + last_day.Close)
58
elif last_day.Close > last_day.Open:
59
pivot = ((last_day.High * 2) + last_day.Low + last_day.Close)
60
elif last_day.Close == last_day.Open:
61
pivot = (last_day.High + last_day.Low + (last_day.Close * 2))
62
if pivot:
63
self._DeMark_high = pivot / 2 - last_day.Low
64
self._DeMark_low = pivot / 2 - last_day.High
65
self._arima_predict_close = self.__calc_arima()
66
67
def __calc_arima(self):
68
""" Calculate ARIMA """
69
# Diff for Stationary
70
fit_data = self._hist_data.Close.copy()
71
fit_data = fit_data.diff(periods=1).dropna()
72
73
all_date_index = pd.date_range(fit_data.index[0],
74
fit_data.index[-1],
75
freq="D")
76
fit_data = fit_data.reindex(all_date_index)
77
fit_data = fit_data.fillna(method='ffill')
78
79
# Fit ARIMA
80
arima_model = sm.tsa.ARIMA(fit_data, order=(1, 1, 1))
81
arima_model_fited = arima_model.fit()
82
83
# Predict for next day
84
predict_date = datetime.today().date()
85
arima_predict = arima_model_fited.predict(start=predict_date, end=predict_date, dynamic=False)
86
87
# Convert Stationary back
88
predict_date = str(predict_date.strftime('%Y-%m-%d'))
89
prev_close = self._hist_data.Close[-1]
90
arima_predict = arima_predict[predict_date] + prev_close
91
92
return arima_predict
93
94
def _generate_check(self):
95
""" Specifying all checks """
96
97
check = self._check_handler
98
# Adding check for OPEN LONG orders
99
# Check 1 (OPEN LONG) Is price falls below LOW POINT of DeMark?
100
check.add_check(ModelChecks.OPEN_LONG, self._LOW_POINT, self._is_price_low_point)
101
# Check 2 (OPEN LONG) Is price come back to LOW POINT of DeMark?
102
check.add_check(ModelChecks.OPEN_LONG, self._IS_BACK_LOW_POINT, self._is_price_back_to_low_point)
103
104
# Adding check for CLOSE LONG orders
105
# Check 1 (CLOSE LONG) Is price up to below LOW POINT of DeMark?
106
check.add_check(ModelChecks.CLOSE_LONG, self._HIGH_POINT, self._is_price_high_point)
107
108
def _is_price_low_point(self):
109
""" Check 1 (OPEN LONG) Is price falls below LOW POINT of DeMark? """
110
if self._last_price < self._DeMark_low:
111
return True
112
return False
113
114
def _is_price_back_to_low_point(self):
115
""" Check 2 (OPEN LONG) Is price come back to LOW POINT of DeMark? """
116
checks = self._check_handler.checks
117
is_ready = checks[ModelChecks.OPEN_LONG][self._LOW_POINT][ModelChecks.IS_READY]
118
if is_ready is True and self._last_price >= self._DeMark_low:
119
return True
120
return False
121
122
def _is_price_high_point(self):
123
""" Check 1 (CLOSE LONG) Is price up to below LOW POINT of DeMark or ARIMA close? """
124
if self._last_price >= self._DeMark_high:
125
return True
126
if self._last_price >= self._arima_predict_close:
127
return True
128
return False
129
130