VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 16
声望: 0

我的策略是这样的计算3分钟和15分钟的两次ema,点击启动策略调用on_start发现通过 self.load_bar(10)数据计算的[ "double_ema_15_previous","double_ema_15_current", "double_ema_3_previous", "double_ema_3_current",]和在文华上面计算的几乎一模一样,但是随着实盘测试传入新的bar之后就开始偏移,停止策略点击开始调用on_start发现通过 self.load_bar(10)计算的又正确了。请问这个是什么原因?非常感谢。

`from vnpy_ctastrategy import (
CtaTemplate,
StopOrder,
TickData,
BarData,
TradeData,
OrderData,
BarGenerator,
ArrayManager,
)
from datetime import datetime
import talib

class DoubleEmaStrategy_3min_15min(CtaTemplate):
""""""
author = "用Python的交易员"

ema_period = 20
pos_size = 1
price_unit=1
double_ema_15_current = 0.0
double_ema_15_previous = 0.0
double_ema_3_current = 0.0
double_ema_3_previous = 0.0
last_double_ema_3_up = None  # 用于保存上一个周期的3分钟双EMA趋势方向
last_double_ema_15_up = None  # 用于保存上一个周期的15分钟双EMA趋势方向

parameters = ["ema_period",  "pos_size","price_unit"]
variables = [ "double_ema_15_previous","double_ema_15_current",  "double_ema_3_previous", "double_ema_3_current",]

def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
    """"""
    super().__init__(cta_engine, strategy_name, vt_symbol, setting)

    self.bg15 = BarGenerator(self.on_bar, 15, self.on_15min_bar)
    self.am15 = ArrayManager()

    self.bg3 = BarGenerator(self.on_bar, 3, self.on_3min_bar)
    self.am3 = ArrayManager()


def on_init(self):
    """
    Callback when strategy is inited.
    """
    self.write_log("策略初始化")
    self.load_bar(10)

def on_start(self):
    """
    Callback when strategy is started.
    """
    self.load_bar(10)

    # 计算第一次EMA
    ema_3_array = self.am3.ema(self.ema_period, array=True)
    # 更新到am3以便计算第二次EMA
    double_ema_3 =  talib.EMA(ema_3_array, self.ema_period)

    self.double_ema_3_previous = double_ema_3[-2]
    self.double_ema_3_current = double_ema_3[-1]
    # 计算第一次EMA
    ema_15_array = self.am15.ema(self.ema_period, array=True)
    # 更新到am15以便计算第二次EMA
    double_ema_15 =  talib.EMA(ema_15_array, self.ema_period)
    self.double_ema_15_previous = double_ema_15[-2]
    self.double_ema_15_current = double_ema_15[-1]
    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.bg3.update_tick(tick)
    self.bg15.update_tick(tick)

def on_bar(self, bar: BarData):
    """
    Callback of new bar data update.
    """

    self.bg3.update_bar(bar)
    self.bg15.update_bar(bar)
    self.put_event()

def on_3min_bar(self, bar: BarData):
    """"""
    self.cancel_all()

    self.am3.update_bar(bar)
    if not self.am3.inited:
        return

    self.update_ema_3(bar)

    # 判断双EMA趋势
    self.check_trend_and_execute(bar)

    self.put_event()

def on_15min_bar(self, bar: BarData):
    """"""
    self.am15.update_bar(bar)
    if not self.am15.inited:
        return

    self.update_ema_15(bar)

    self.put_event()

def update_ema_3(self, bar: BarData):
    """
    更新3分钟双EMA
    """
    ema_3_array = self.am3.ema(self.ema_period, array=True)
    double_ema_3 = talib.EMA(ema_3_array, self.ema_period)


    self.double_ema_3_previous =  double_ema_3[-2]
    self.double_ema_3_current = double_ema_3[-1]

def update_ema_15(self, bar: BarData):
    """
    更新15分钟双EMA
    """
    ema_15_array = self.am15.ema(self.ema_period, array=True)
    double_ema_15 = talib.EMA(ema_15_array, self.ema_period)


    self.double_ema_15_previous = double_ema_15[-2]
    self.double_ema_15_current = double_ema_15[-1]

def check_trend_and_execute(self, bar: BarData):
    """
    根据双EMA趋势判断执行交易
    """
    double_ema_3_up = self.double_ema_3_current > self.double_ema_3_previous
    double_ema_3_down = self.double_ema_3_current < self.double_ema_3_previous
    double_ema_15_up = self.double_ema_15_current > self.double_ema_15_previous
    double_ema_15_down = self.double_ema_15_current < self.double_ema_15_previous

    # 3分钟EMA方向变化时记录日志
    if self.last_double_ema_3_up is not None and self.last_double_ema_3_up != double_ema_3_up:
        if double_ema_3_up:
            print(f"在{bar.datetime}, 3分钟EMA从下降变为上升")
        else:
            print(f"在{bar.datetime}, 3分钟EMA从上升变为下降")

    # 15分钟EMA方向变化时记录日志
    if self.last_double_ema_15_up is not None and self.last_double_ema_15_up != double_ema_15_up:
        if double_ema_15_up:
            print(f"在{bar.datetime}, 15分钟EMA从下降变为上升")
        else:
            print(f"在{bar.datetime}, 15分钟EMA从上升变为下降")

    # 保存当前趋势方向用于下一个周期比较
    self.last_double_ema_3_up = double_ema_3_up
    self.last_double_ema_15_up = double_ema_15_up

    # 执行交易逻辑
    # 平空单
    if double_ema_3_up and self.pos < 0:
        self.cover(bar.close_price, abs(self.pos))

    # 平多单
    if double_ema_3_down and self.pos > 0:
        self.sell(bar.close_price, abs(self.pos))

    # 开多仓
    if double_ema_3_up and double_ema_15_up:
        if self.pos < 0:
            self.cover(bar.close_price, abs(self.pos))
        if self.pos == 0:
            self.buy(bar.close_price - self.price_unit, self.pos_size,True)
            print(f"多开{self.pos_size}")


    # 开空仓
    if double_ema_3_down and double_ema_15_down:
        if self.pos > 0:
            self.sell(bar.close_price, abs(self.pos))
        if self.pos == 0:
            self.short(bar.close_price + self.price_unit, self.pos_size,True)
            print(f"空开{self.pos_size}")

def on_order(self, order: OrderData):
    """
    Callback of new order data update.
    """
    pass

def on_trade(self, trade: TradeData):
    """
    Callback of new trade data update.
    """
    self.put_event()

def on_stop_order(self, stop_order: StopOrder):
    """
    Callback of stop order update.
    """
    pass

`

Member
avatar
加入于:
帖子: 5133
声望: 308

可以把.vntrader文件夹里的cta_strategy_data.json删掉以后再试试看

Member
avatar
加入于:
帖子: 16
声望: 0

xiaohe wrote:

可以把.vntrader文件夹里的cta_strategy_data.json删掉以后再试试看

删了之后也没有用,策略启动一段时间后就和实际的偏离的,怀疑是存储到json出问题了,就是那个三分钟的算出来显示的就不对了。就是过了几个三分钟以后就偏的很多了,再次启动策略加载过去的指标又正常了

Member
avatar
加入于:
帖子: 16
声望: 0

xiaohe wrote:

可以把.vntrader文件夹里的cta_strategy_data.json删掉以后再试试看

通过打印self.am3.close_array我发现随着新的数据传入,实际数据会重复。开始重复的时候就是策略开始不用历史数据而用实盘数据之后,请问为什么会有这么奇怪的am3构成。

description

Member
avatar
加入于:
帖子: 5133
声望: 308

update_tick只要调一次
多时期建议参考示例策略multi_timeframe_strategy

Member
avatar
加入于:
帖子: 16
声望: 0

xiaohe wrote:

update_tick只要调一次
多时期建议参考示例策略multi_timeframe_strategy

非常感谢,问题解决了

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】