import pandas
from op_forex.model.bar_model import BarModel
from op_forex.model.symbol_info import SymbolInfo
from op_forex.strategy.template_strategy import TemplateStrategy
from tqz_extern.tqz_constant import StrategyDirect
class DoubleMaStrategy(TemplateStrategy):
author: str = 'Erwin'
def __init__(
self,
fast_windows: int,
slow_windows: int,
daily_fast_windows: int,
daily_slow_windows: int
):
super().__init__()
self.fast_windows: int = fast_windows
self.slow_windows: int = slow_windows
self.daily_fast_windows: int = daily_fast_windows
self.daily_slow_windows: int = daily_slow_windows
self.daily_bars_df = None
self.hour_bars_df = pandas.DataFrame(columns=['time', 'high', 'open', 'low', 'close', 'volume'])
self.stop_loss_price: float = None
self.lots: float = 0
def on_init(self, symbol_info: SymbolInfo, strategy_direct: StrategyDirect):
self.strategy_direct = strategy_direct
self.symbol_info = symbol_info
self.lots = self.symbol_info.volume_min
def on_bar(self, bar: BarModel = None):
self.hour_bars_df.loc[len(self.hour_bars_df)] = [bar.time, bar.high, bar.open, bar.low, bar.close, bar.volume]
if len(self.daily_bars_df) < self.daily_slow_windows:
return
if len(self.hour_bars_df) < (self.slow_windows + 1):
return
# - calculate signals.
daily_fast_ma_value = self.daily_bars_df[-self.daily_fast_windows:].close.mean()
daily_slow_ma_value = self.daily_bars_df[-self.daily_slow_windows:].close.mean()
hour_pre_fast_ma_value = self.hour_bars_df[-self.fast_windows-1:-1].close.mean()
hour_pre_slow_ma_value = self.hour_bars_df[-self.slow_windows-1:-1].close.mean()
hour_fast_ma_value = self.hour_bars_df[-self.fast_windows:].close.mean()
hour_slow_ma_value = self.hour_bars_df[-self.slow_windows:].close.mean()
# - modify pos.
if 0 == self.pos:
if daily_fast_ma_value > daily_slow_ma_value:
if hour_fast_ma_value > hour_slow_ma_value and hour_pre_fast_ma_value < hour_pre_slow_ma_value: # <- send new buy order.
self.buy(symbol=self.symbol_info.name, date_time=bar.time, lots=self.lots, price=bar.close)
atr_range_value = (self.daily_bars_df[-self.daily_slow_windows:].high - self.daily_bars_df[-self.daily_slow_windows:].low).mean() * 2
self.stop_loss_price = bar.close - atr_range_value
# print(f'[DoubleMaStrategy signal]: buy order, time: {bar.time}, lots: {self.lots}, price: {bar.close}, cur_pos: {self.pos}.')
elif daily_fast_ma_value < daily_slow_ma_value:
if hour_fast_ma_value < hour_slow_ma_value and hour_pre_fast_ma_value > hour_pre_slow_ma_value: # <- send new sell order.
self.sell(symbol=self.symbol_info.name, date_time=bar.time, lots=self.lots, price=bar.close)
atr_range_value = (self.daily_bars_df[-self.daily_slow_windows:].high - self.daily_bars_df[-self.daily_slow_windows:].low).mean() * 2
self.stop_loss_price = bar.close + atr_range_value
# print(f'[DoubleMaStrategy signal]: sell order, time: {bar.time}, lots: {self.lots}, price: {bar.close}, cur_pos: {self.pos}.')
elif self.pos > 0:
if bar.low <= self.stop_loss_price: # <- hold long pos, out of stop loss limit.
self.sell(symbol=self.symbol_info.name, date_time=bar.time, lots=self.pos, price=self.stop_loss_price)
# print(f'[DoubleMaStrategy signal]: sell order, time: {bar.time}, lots: {self.lots}, stop_loss_price: {self.stop_loss_price}, cur_pos: {self.pos}.')
self.stop_loss_price = None
else:
if hour_fast_ma_value < hour_slow_ma_value and hour_pre_fast_ma_value > hour_pre_slow_ma_value: # <- hold long pos, close pos signal appear.
self.sell(symbol=self.symbol_info.name, date_time=bar.time, lots=self.pos, price=bar.close)
# print(f'[DoubleMaStrategy signal]: sell order, time: {bar.time}, lots: {self.lots}, price: {bar.close}, cur_pos: {self.pos}.')
self.stop_loss_price = None
if daily_fast_ma_value < daily_slow_ma_value: # <- send new sell order.
self.sell(symbol=self.symbol_info.name, date_time=bar.time, lots=self.lots, price=bar.close)
atr_range_value = (self.daily_bars_df[-self.daily_slow_windows:].high - self.daily_bars_df[-self.daily_slow_windows:].low).mean() * 2
self.stop_loss_price = bar.close + atr_range_value
# print(f'[DoubleMaStrategy signal]: sell order, time: {bar.time}, lots: {self.lots}, price: {bar.close}, cur_pos: {self.pos}.')
elif self.pos < 0:
if bar.high >= self.stop_loss_price: # <- hold short pos, out of stop loss limit.
self.buy(symbol=self.symbol_info.name, date_time=bar.time, lots=abs(self.pos), price=self.stop_loss_price)
# print(f'[DoubleMaStrategy signal]: buy order, time: {bar.time}, lots: {self.lots}, stop_loss_price: {self.stop_loss_price}, cur_pos: {self.pos}.')
self.stop_loss_price = None
else:
if hour_fast_ma_value > hour_slow_ma_value and hour_pre_fast_ma_value < hour_pre_slow_ma_value: # <- hold short pos, close pos signal appear.
self.buy(symbol=self.symbol_info.name, date_time=bar.time, lots=abs(self.pos), price=bar.close)
# print(f'[DoubleMaStrategy signal]: buy order, time: {bar.time}, lots: {self.lots}, price: {bar.close}, cur_pos: {self.pos}')
self.stop_loss_price = None
if daily_fast_ma_value > daily_slow_ma_value: # <- send new buy order.
self.buy(symbol=self.symbol_info.name, date_time=bar.time, lots=self.lots, price=bar.close)
atr_range_value = (self.daily_bars_df[-self.daily_slow_windows:].high - self.daily_bars_df[-self.daily_slow_windows:].low).mean() * 2
self.stop_loss_price = bar.close - atr_range_value
# print(f'[DoubleMaStrategy signal]: buy order, time: {bar.time}, lots: {self.lots}, price: {bar.close}, cur_pos: {self.pos}.')
def on_daily_bar(self, daily_bars_df: pandas.DataFrame = None):
self.daily_bars_df = daily_bars_df
def on_stop(self):
self.daily_bars_df = None
12-20
671
08-18
08-18