VeighNa量化社区
你的开源社区量化交易平台 | vn.py | vnpy
Member
avatar
加入于:
帖子: 6
声望: 0

如题,以下是源码,请帮忙看看,非常感谢
from vnpy_ctastrategy import (
CtaTemplate,
StopOrder,
TickData,
BarData,
TradeData,
OrderData,
BarGenerator,
ArrayManager,
)
from vnpy.trader.constant import Interval
from datetime import time

class BollBand(CtaTemplate):
""""""

author = "wangshuai"

boll_window: float = 30
boll_dev: float = 1.75
fixed_size: int = 3
lookback_period: int = 40
adaptive_min: int = 10  # 自适应均线最小周期
liqlength: int = 60  # 自适应出场均线参数

boll_up: float = 0
boll_down: float = 0
max_close: float = 0
min_close: float = 0
intra_trade_high: float = 0
intra_trade_low: float = 0
liqpoint: float = 0.0  # 自适应的出场均线

parameters = [
    "boll_window",
    "boll_dev",
    "fixed_size",
    "lookback_period",
    "adaptive_min",
    "liqlength",
]
variables = [
    "boll_up",
    "boll_down",
    "max_close",
    "min_close",
    "intra_trade_high",
    "intra_trade_low",
    "liqpoint",
]

def on_init(self) -> None:
    """
    Callback when strategy is inited.
    """
    self.write_log("策略初始化")

    self.bg = BarGenerator(
        on_bar=self.on_bar,
        window=1,
        on_window_bar=self.on_daily_bar,
        interval=Interval.DAILY,
        daily_end=time(14, 59),
    )

    self.am = ArrayManager(100)

    self.load_bar(100)

def on_start(self) -> None:
    """
    Callback when strategy is started.
    """
    self.write_log("策略启动")

def on_stop(self) -> None:
    """
    Callback when strategy is stopped.
    """
    self.write_log("策略停止")

def on_tick(self, tick: TickData) -> None:
    """
    Callback of new tick data update.
    """
    self.bg.update_tick(tick)

def on_bar(self, bar: BarData) -> None:
    """
    Callback of new bar data update.
    """
    self.bg.update_bar(bar)

def on_daily_bar(self, bar: BarData) -> None:
    """"""
    self.cancel_all()

    am = self.am
    am.update_bar(bar)
    if not am.inited:
        return

    # 计算布林带上轨下轨和中轨
    self.boll_up, self.boll_down = am.boll(self.boll_window, self.boll_dev)

    # 计算过滤器周期最高价和最低价
    self.max_close = am.close[-self.lookback_period :].max()
    self.min_close = am.close[-self.lookback_period :].min()

    # 更新自适应周期(带衰减限制)
    if self.pos != 0:
        self.adaptive_days = max(self.adaptive_min, self.adaptive_days - 1)
    else:
        self.adaptive_days = self.liqlength

    # 自适应均线
    self.liqpoint = self.am.ema(self.adaptive_days, array=False)

    if self.pos == 0:
        self.intra_trade_high = bar.high_price
        self.intra_trade_low = bar.low_price

        if (
            self.intra_trade_high >= self.boll_up
            and self.intra_trade_high >= self.max_close
        ):
            self.buy(self.boll_up, self.fixed_size, True)
        elif (
            self.intra_trade_low <= self.boll_down
            and self.intra_trade_low <= self.min_close
        ):
            self.short(self.boll_down, -self.fixed_size, True)

    elif self.pos > 0:
        self.intra_trade_low = min(self.intra_trade_low, bar.low_price)

        if self.liqpoint < self.boll_up and self.intra_trade_low <= self.liqpoint:
            self.sell(self.intra_trade_low, abs(self.pos), True)

    elif self.pos < 0:
        self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
        if (
            self.liqpoint > self.boll_down
            and self.intra_trade_high >= self.liqpoint
        ):
            self.cover(self.intra_trade_high, abs(self.pos), True)

    self.put_event()

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

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

def on_stop_order(self, stop_order: StopOrder) -> None:
    """
    Callback of stop order update.
    """
    pass
Super Moderator
avatar
加入于:
帖子: 77
声望: 8

根据您提供的代码,策略在1分钟级别有信号,但在日线级别没有信号,可能由以下原因导致。以下是详细分析和解决方法:


1. BarGenerator配置问题

  • 您在on_init函数中配置了BarGenerator,用于合成日线K线,但window参数设置为1,这会导致BarGenerator只合成1分钟K线,而不是日线K线。
  • 解决方法:
    • window参数设置为0,并确保interval参数为Interval.DAILY,以正确合成日线K线。
    • 修改代码如下:
      self.bg = BarGenerator(
          on_bar=self.on_bar,
          window=0,  # 设置为0,表示合成日线
          on_window_bar=self.on_daily_bar,
          interval=Interval.DAILY,
          daily_end=time(14, 59),
      )
      

2. 数据加载问题

  • 您在on_init函数中调用self.load_bar(100)加载历史数据,但未指定K线周期,默认加载的是1分钟K线。
  • 解决方法:
    • load_bar函数中指定K线周期为Interval.DAILY,以加载日线数据。
    • 修改代码如下:
      self.load_bar(100, interval=Interval.DAILY)
      

3. on_daily_bar函数逻辑问题

  • on_daily_bar函数中,您使用了self.intra_trade_highself.intra_trade_low来判断开仓信号,但这些变量在日线级别可能未正确更新。
  • 解决方法:

    • 确保self.intra_trade_highself.intra_trade_low在日线级别正确更新。
    • 修改代码如下:

      if self.pos == 0:
          self.intra_trade_high = bar.high_price
          self.intra_trade_low = bar.low_price
      
          if (
              bar.high_price >= self.boll_up
              and bar.high_price >= self.max_close
          ):
              self.buy(self.boll_up, self.fixed_size, True)
          elif (
              bar.low_price <= self.boll_down
              and bar.low_price <= self.min_close
          ):
              self.short(self.boll_down, -self.fixed_size, True)
      

4. ArrayManager初始化问题

  • 您在on_init函数中初始化了ArrayManager,但未检查其是否已初始化。
  • 解决方法:
    • on_daily_bar函数中,确保ArrayManager已初始化后再执行后续逻辑。
    • 修改代码如下:
      am = self.am
      am.update_bar(bar)
      if not am.inited:
          return
      

5. 日志输出问题

  • 如果策略未输出日志,可能无法确认on_daily_bar函数是否被调用。
  • 解决方法:
    • on_daily_bar函数中添加日志输出,确认函数是否被调用。
    • 修改代码如下:
      def on_daily_bar(self, bar: BarData) -> None:
          self.write_log(f"日线K线更新: {bar.datetime}")
          self.cancel_all()
          ...
      

6. 回测数据问题

  • 如果回测数据中没有日线数据,策略将无法生成日线信号。
  • 解决方法:
    • 确保回测数据中包含日线数据,并在回测时选择日线周期。

总结

建议按照以下步骤逐一排查:

  1. 修改BarGenerator配置,确保正确合成日线K线。
  2. load_bar函数中指定K线周期为Interval.DAILY
  3. 确保self.intra_trade_highself.intra_trade_low在日线级别正确更新。
  4. 检查ArrayManager是否已初始化。
  5. on_daily_bar函数中添加日志输出,确认函数是否被调用。
  6. 确保回测数据中包含日线数据。

如果问题仍然存在,可以提供更多详细信息(如日志输出、回测数据等),以便进一步分析。

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

非常感谢您的答复

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

很奇怪 按您的答复修改代码后再次回测,仍然是在1分钟级别有交易信号,在日线级别没有生成一个交易信号。我用的是米筐的试用账号,1分钟线数据和日线数据都下载完了的,测试的是rb88.SHFE 2010-2025年的数据。

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

description

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

哈哈,暂时帮不上忙,但是楼上回答的好像是个AI....

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

哈哈 你不说我还没注意 确实是个AI 我提的这个问题难住我半个月了 一直找不到原因

Member
avatar
加入于:
帖子: 5419
声望: 328

就自行在策略里打印排查就好

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

沪公网安备 31011502017034号

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