"""
不要用来跑实盘, CuatroStrategy可迭代处还有很多, 以下代码仅供学习参考使用
"""
from vnpy.app.cta_strategy import (
CtaTemplate,
BarGenerator,
ArrayManager,
TickData,
BarData,
OrderData,
TradeData,
StopOrder
)
from typing import Any
from vnpy.app.cta_strategy.base import EngineType
class CuatroStrategy(CtaTemplate):
""""""
boll_window = 20
boll_dev = 2
rsi_window = 14
rsi_signal = 30
fast_window = 5
slow_window = 20
trailing_long = 1
trailing_short = 1
fixed_size = 1
boll_up = 0
boll_down = 0
rsi_value = 0
rsi_long = 0
rsi_short = 0
fast_ma = 0
slow_ma = 0
ma_trent = 0
intra_trade_high = 0
intra_trade_low = 0
long_stop = 0
short_stop = 0
author = "Post-Truth"
parameters = [
"boll_window",
"boll_dev",
"rsi_window",
"rsi_signal",
"fast_window",
"slow_window",
"trailing_long",
"trailing_short",
"fixed_size",
]
variables = [
"boll_up",
"boll_down",
"rsi_value",
"rsi_long",
"rsi_short",
"fast_ma",
"slow_ma",
"ma_trent",
"intra_trade_high",
"intra_trade_low",
"long_stop",
"short_stop ",
]
def __init__(
self,
cta_engine: Any,
strategy_name: str,
vt_symbol: str,
setting: dict,
):
""""""
super().__init__(cta_engine, strategy_name, vt_symbol, setting)
self.rsi_long = 50 + self.rsi_signal
self.rsi_short = 50 - self.rsi_signal
self.bar_generator_5 = BarGenerator(
on_bar=self.on_bar,
window=5,
on_window_bar=self.on_5min_bar,
interval=Interval.MINUTE
)
self.array_manager_5 = ArrayManager()
self.bar_generator_15 = BarGenerator(
on_bar=self.on_bar,
window=15,
on_window_bar=self.on_15min_bar,
interval=Interval.MINUTE
)
self.array_manager_15 = ArrayManager()
def on_init(self):
"""
Callback when strategy is inited.
"""
self.write_log("策略初始化")
def on_start(self):
"""
Callback when strategy is started.
"""
self.write_log("策略启动")
def on_stop(self):
"""
Callback when strategy is stopped.
"""
self.write_log("策略停止")
def on_tick(self, tick: TickData):
"""
Callback of new tick data update.
"""
self.bar_generator_5.update_tick(tick)
def on_bar(self, bar: BarData):
"""
Callback of new bar data update.
"""
self.bar_generator_15.update_bar(bar)
self.bar_generator_5.update_bar(bar)
def on_5min_bar(self, bar: BarData):
"""
Callback when a new 5 minute is gone.
"""
self.cancel_all()
# 将 新收到的 5 min k线 更新到 array_manager_5 里面;
self.array_manager_5.update_bar(bar)
if self.array_manager_5.inited is False or self.array_manager_15.inited is False:
return
self.boll_up, self.boll_down = self.array_manager_5.boll(self.boll_window, self.boll_dev)
self.rsi_value = self.array_manager_5.rsi(self.rsi_window)
boll_width = self.boll_up - self.boll_down
engine_type = self.get_engine_type()
if self.pos == 0:
self.intra_trade_high = bar.high_price
self.intra_trade_low = bar.low_price
if self.ma_trent > 0 and self.rsi_value >= self.rsi_long:
if engine_type == EngineType.BACKTESTING:
self.buy(self.boll_up, self.fixed_size, stop=True)
elif engine_type == EngineType.LIVE:
self.buy(self.boll_up, self.fixed_size, stop=True, lock=True)
if self.ma_trent < 0 and self.rsi_value <= self.rsi_short:
if engine_type == EngineType.BACKTESTING:
self.short(self.boll_down, self.fixed_size, stop=True)
elif engine_type == EngineType.LIVE:
self.short(self.boll_down, self.fixed_size, stop=True, lock=True)
elif self.pos > 0:
self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
self.long_stop = (self.intra_trade_high - self.trailing_long * boll_width)
self.sell(self.long_stop, abs(self.pos), stop=True)
elif self.pos < 0:
self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
self.short_stop = (self.intra_trade_low - self.trailing_short * boll_width)
self.cover(self.short_stop, abs(self.pos), stop=True)
self.put_event()
def on_15min_bar(self, bar: BarData):
"""
Callback when a new 15 minute is gone.
"""
# 将 新收到的 15 min k线 更新到 array_manager_15 里面;
self.array_manager_15.update_bar(bar)
if self.array_manager_15.inited is False:
return
self.fast_ma = self.array_manager_15.sma(self.fast_window)
self.slow_ma = self.array_manager_15.sma(self.slow_window)
if self.fast_ma > self.slow_ma:
self.ma_trent = 1
elif self.fast_ma < self.slow_ma:
self.ma_trent = -1
else:
self.ma_trent = 0
self.put_event()
def on_trade(self, trade: TradeData):
"""
Callback of new trade data update.
"""
self.put_event()
message = f'新的成交, 策略 {self.strategy_name}, 方向{trade.direction}, 开平 {trade.offset}, 当前仓位{self.pos}'
self.send_email(message)
def on_order(self, order: OrderData):
"""
Callback of new order data update.
"""
pass
def on_stop_order(self, stop_order: StopOrder):
"""
Callback of stop order update.
"""
pass