Path: blob/master/ invest-robot-contest_TradingCompetition2022-main/models/ARIMAdeMarkLong.py
5925 views
from models.TradingModel import (TradingModel, ModelChecks)1from datetime import (date, timedelta, datetime)2import statsmodels.api as sm3import pandas as pd456class ARIMAdeMarkLong(TradingModel):7"""8Trading Model ARIMA + DeMark9ARIMA model forecasting trend and target10DeMark - find point for open position (if the price falls below the point of low DeMark11and come back to this point it will open position)12"""1314# { Model checks name15_LOW_POINT = 'FALLS_BELOW_LOW_POINT' # Price falls below low point of DeMark16_IS_BACK_LOW_POINT = 'BACK_TO_LOW_POINT' # Price come back to low point of DeMark17_HIGH_POINT = 'UP_TO_HIGH_POINT' # Price up to high point of DeMark18# Model checks name }1920def __init__(self, ticker, config):21super(ARIMAdeMarkLong, self).__init__(ticker, config)22# DeMark Low and High level23self._DeMark_low = None24self._DeMark_high = None25self._arima_predict_close = None2627# This model available only for LONG orders28self._long_available = True29self._short_available = False3031def custom_init(self):32super(ARIMAdeMarkLong, self).custom_init()33self._calculate_model()34# Check calc of model is ok or not35if self._check_model() is False:36self._long_available = False3738def _check_model(self):39""" Check model """40if self._DeMark_low is None or self._DeMark_high is None:41return False42if self._DeMark_low > self._DeMark_high:43return False44if self._DeMark_low > self._arima_predict_close:45return False46return True4748def _calculate_model(self):49""" Calculate ARIMA DeMark Model """50prev_date = date.today() - timedelta(20)51self._download_hist_data(start_date=prev_date, end_date=date.today())52if len(self._hist_data) > 0:53last_day = self._hist_data.iloc[-1]54pivot = None55if last_day.Close < last_day.Open:56pivot = (last_day.High + (last_day.Low * 2) + last_day.Close)57elif last_day.Close > last_day.Open:58pivot = ((last_day.High * 2) + last_day.Low + last_day.Close)59elif last_day.Close == last_day.Open:60pivot = (last_day.High + last_day.Low + (last_day.Close * 2))61if pivot:62self._DeMark_high = pivot / 2 - last_day.Low63self._DeMark_low = pivot / 2 - last_day.High64self._arima_predict_close = self.__calc_arima()6566def __calc_arima(self):67""" Calculate ARIMA """68# Diff for Stationary69fit_data = self._hist_data.Close.copy()70fit_data = fit_data.diff(periods=1).dropna()7172all_date_index = pd.date_range(fit_data.index[0],73fit_data.index[-1],74freq="D")75fit_data = fit_data.reindex(all_date_index)76fit_data = fit_data.fillna(method='ffill')7778# Fit ARIMA79arima_model = sm.tsa.ARIMA(fit_data, order=(1, 1, 1))80arima_model_fited = arima_model.fit()8182# Predict for next day83predict_date = datetime.today().date()84arima_predict = arima_model_fited.predict(start=predict_date, end=predict_date, dynamic=False)8586# Convert Stationary back87predict_date = str(predict_date.strftime('%Y-%m-%d'))88prev_close = self._hist_data.Close[-1]89arima_predict = arima_predict[predict_date] + prev_close9091return arima_predict9293def _generate_check(self):94""" Specifying all checks """9596check = self._check_handler97# Adding check for OPEN LONG orders98# Check 1 (OPEN LONG) Is price falls below LOW POINT of DeMark?99check.add_check(ModelChecks.OPEN_LONG, self._LOW_POINT, self._is_price_low_point)100# Check 2 (OPEN LONG) Is price come back to LOW POINT of DeMark?101check.add_check(ModelChecks.OPEN_LONG, self._IS_BACK_LOW_POINT, self._is_price_back_to_low_point)102103# Adding check for CLOSE LONG orders104# Check 1 (CLOSE LONG) Is price up to below LOW POINT of DeMark?105check.add_check(ModelChecks.CLOSE_LONG, self._HIGH_POINT, self._is_price_high_point)106107def _is_price_low_point(self):108""" Check 1 (OPEN LONG) Is price falls below LOW POINT of DeMark? """109if self._last_price < self._DeMark_low:110return True111return False112113def _is_price_back_to_low_point(self):114""" Check 2 (OPEN LONG) Is price come back to LOW POINT of DeMark? """115checks = self._check_handler.checks116is_ready = checks[ModelChecks.OPEN_LONG][self._LOW_POINT][ModelChecks.IS_READY]117if is_ready is True and self._last_price >= self._DeMark_low:118return True119return False120121def _is_price_high_point(self):122""" Check 1 (CLOSE LONG) Is price up to below LOW POINT of DeMark or ARIMA close? """123if self._last_price >= self._DeMark_high:124return True125if self._last_price >= self._arima_predict_close:126return True127return False128129130