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
from op_forex.model.renko_block_model import RenkoBlockModel, RenkoColor
from op_forex.model.renko_wave_model import RenkoWaveModel
class SinglePeriodRenkoStrategy2(TemplateStrategy):
author: str = 'Erwin'
def __init__(self, fast_windows: int, slow_windows: int, renko_ticks: int):
super().__init__()
self.fast_windows: int = fast_windows
self.slow_windows: int = slow_windows
self.renko_ticks: int = renko_ticks
self.atr_range_multi: int = 3
self.hour_bars_df = pandas.DataFrame(columns=['time', 'high', 'open', 'low', 'close', 'volume'])
self.his_renko_blocks: [RenkoBlockModel] = []
self.his_renko_waves: [RenkoWaveModel] = []
self.start_renko_price: float = None
self.renko_size: float = None
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
self.renko_size = self.symbol_info.trade_tick_size * self.renko_ticks
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.hour_bars_df) < self.slow_windows:
return
# - calculate part.
fast_ma_value = self.hour_bars_df[-self.fast_windows:].close.mean()
slow_ma_value = self.hour_bars_df[-self.slow_windows:].close.mean()
atr_value = (self.hour_bars_df[-self.slow_windows:].high - self.hour_bars_df[-self.slow_windows:].low).mean() * self.atr_range_multi
# - update renko_block, renko_wave.
self.update_renko_block_renko_wave(cur_bar=bar)
if len(self.his_renko_blocks) < 2:
return
if len(self.his_renko_waves) < 4: # 如果是空间背驰, 则 self.his_renko_waves 至少有四个元素;
return
cur_renko, pre_renko = self.his_renko_blocks[-1], self.his_renko_blocks[-2]
# - 策略逻辑
if fast_ma_value > slow_ma_value:
if self.pos < 0:
self.buy(symbol=self.symbol_info.name, date_time=bar.time, price=bar.close, lots=abs(self.pos))
self.stop_loss_price = None
if 0 == self.pos:
if RenkoColor.GREEN == pre_renko.renko_color and RenkoColor.RED == cur_renko.renko_color: # 低点产生
if abs(self.his_renko_waves[-1].renko_wave_price - self.his_renko_waves[-2].renko_wave_price) < abs(self.his_renko_waves[-3].renko_wave_price - self.his_renko_waves[-4].renko_wave_price): # 下降段 空间背驰.
self.buy(symbol=self.symbol_info.name, date_time=bar.time, price=bar.close, lots=self.lots)
self.stop_loss_price = bar.close - atr_value
elif self.pos > 0:
if bar.low <= self.stop_loss_price: # 扫到止损
self.sell(symbol=self.symbol_info.name, date_time=bar.time, price=self.stop_loss_price, lots=self.pos)
self.stop_loss_price = None
elif RenkoColor.RED == pre_renko.renko_color and RenkoColor.GREEN == cur_renko.renko_color: # 高点产生
if abs(self.his_renko_waves[-1].renko_wave_price - self.his_renko_waves[-2].renko_wave_price) < abs(self.his_renko_waves[-3].renko_wave_price - self.his_renko_waves[-4].renko_wave_price): # 上涨段 空间背驰.
self.sell(symbol=self.symbol_info.name, date_time=bar.time, price=bar.close, lots=self.pos)
self.stop_loss_price = None
elif fast_ma_value < slow_ma_value:
if self.pos > 0:
self.sell(symbol=self.symbol_info.name, date_time=bar.time, price=bar.close, lots=self.pos)
self.stop_loss_price = None
if 0 == self.pos:
if RenkoColor.RED == pre_renko.renko_color and RenkoColor.GREEN == cur_renko.renko_color: # 高点
if abs(self.his_renko_waves[-1].renko_wave_price - self.his_renko_waves[-2].renko_wave_price) < abs(self.his_renko_waves[-3].renko_wave_price - self.his_renko_waves[-4].renko_wave_price): # 上涨段 空间背驰.
self.sell(symbol=self.symbol_info.name, date_time=bar.time, price=bar.close, lots=self.lots)
self.stop_loss_price = bar.close + atr_value
elif self.pos < 0:
if bar.high >= self.stop_loss_price:
self.buy(symbol=self.symbol_info.name, date_time=bar.time, price=self.stop_loss_price, lots=abs(self.pos))
self.stop_loss_price = None
elif RenkoColor.GREEN == pre_renko.renko_color and RenkoColor.RED == cur_renko.renko_color: # 低点
if abs(self.his_renko_waves[-1].renko_wave_price - self.his_renko_waves[-2].renko_wave_price) < abs(self.his_renko_waves[-3].renko_wave_price - self.his_renko_waves[-4].renko_wave_price): # 下降段 空间背驰.
self.buy(symbol=self.symbol_info.name, date_time=bar.time, price=bar.close, lots=abs(self.pos))
self.stop_loss_price = None
def on_daily_bar(self, daily_bars_df: pandas.DataFrame = None):
pass
def on_stop(self):
pass
def update_renko_block_renko_wave(self, cur_bar: BarModel):
if 0 == len(self.his_renko_blocks):
if self.start_renko_price is None:
self.start_renko_price = cur_bar.close
else:
if (self.start_renko_price + self.renko_size) <= cur_bar.close: # new red renko
self.his_renko_blocks.append(
RenkoBlockModel(
renko_price=self.start_renko_price + ((cur_bar.close - self.start_renko_price) / self.renko_size) * self.renko_size,
renko_color=RenkoColor.RED,
renko_size=self.renko_size
)
)
elif (self.start_renko_price - self.renko_size) >= cur_bar.close: # new green renko
self.his_renko_blocks.append(
RenkoBlockModel(
renko_price=self.start_renko_price - ((self.start_renko_price - cur_bar.close) / self.renko_size) * self.renko_size,
renko_color=RenkoColor.GREEN,
renko_size=self.renko_size
)
)
else:
last_renko: RenkoBlockModel = self.his_renko_blocks[-1]
if RenkoColor.RED == last_renko.renko_color:
if (last_renko.renko_price + self.renko_size) <= cur_bar.close: # new red renko
self.his_renko_blocks.append(
RenkoBlockModel(
renko_price=last_renko.renko_price + ((cur_bar.close - last_renko.renko_price) / self.renko_size) * self.renko_size,
renko_color=RenkoColor.RED,
renko_size=self.renko_size
)
)
elif (last_renko.renko_price - 2 * self.renko_size) >= cur_bar.close: # new green renko
self.his_renko_waves.append(
RenkoWaveModel(
renko_wave_price=last_renko.renko_price,
renko_color=RenkoColor.RED,
renko_size=self.renko_size
)
)
self.his_renko_blocks.append(
RenkoBlockModel(
renko_price=last_renko.renko_price - ((last_renko.renko_price - cur_bar.close) / self.renko_size) * self.renko_size,
renko_color=RenkoColor.GREEN,
renko_size=self.renko_size
)
)
elif RenkoColor.GREEN == last_renko.renko_color:
if (last_renko.renko_price + 2 * self.renko_size) <= cur_bar.close: # new red renko
self.his_renko_waves.append(
RenkoWaveModel(
renko_wave_price=last_renko.renko_price,
renko_color=RenkoColor.GREEN,
renko_size=self.renko_size
)
)
self.his_renko_blocks.append(
RenkoBlockModel(
renko_price=last_renko.renko_price + ((cur_bar.close - last_renko.renko_price) / self.renko_size) * self.renko_size,
renko_color=RenkoColor.RED,
renko_size=self.renko_size
)
)
elif (last_renko.renko_price - self.renko_size) >= cur_bar.close: # new green renko
self.his_renko_blocks.append(
RenkoBlockModel(
renko_price=last_renko.renko_price - ((last_renko.renko_price - cur_bar.close) / self.renko_size) * self.renko_size,
renko_color=RenkoColor.GREEN,
renko_size=self.renko_size
)
)
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.