vn.py量化社区
By Traders, For Traders.
Member
avatar
加入于:
帖子: 46
声望: 2

description

description

自己写的一个策略,跑回测的时候提示出错。
按照百度的提示,有的说是通过dataframe的类对象的方法得到numpy数组,也有的说可能是内部函数被用作变量名。
请问这个应该怎么修改呢?

Administrator
avatar
加入于:
帖子: 4228
声望: 241

am5.volume,这个volume是一个numpy.ndarray,不能直接用圆括号()的方式来调用。

你这里的需求,直接写:

volume_array = am5.volume

即可

Member
avatar
加入于:
帖子: 46
声望: 2

description

修改了代码之后,CTA回测时显示 “成交记录为空,无法计算”,请问这是我内部的代码出错了吗?

我将策略代码附上,能麻烦老师帮我看看哪里不对吗?

from vnpy.app.cta_strategy import (
CtaTemplate,
BarGenerator,
ArrayManager,
TickData,
BarData,
OrderData,
TradeData,
StopOrder
)

class pptest_15min_ma (CtaTemplate):
""""""

author = "pengpeng"

entry_window = 5
fast_window = 30
slow_window = 130
atr_length = 20
atr_ma_length = 10
volume_length = 20
volume_ma_length = 10
fixed_size = 1
fixed_sl = 300

entry_up = 0.0
entry_down = 0.0
fast_ma = 0.0
slow_ma = 0.0
ma_trend = 0
intra_trade_high = 0.0
intra_trade_low = 0.0
long_stop = 0.0
short_stop = 0.0

parameters = [
    "entry_window",
    "fast_window",
    "slow_window",
    "atr_length",
    "atr_ma_length",
    "volume_length",
    "volume_ma_length",
    "fixed_size",
    "fixed_sl"
]

variables = [
    "entry_up",
    "entry_down",
    "fast_ma",
    "slow_ma",
    " ma_trend",
    "intra_trade_high",
    "intra_trade_low",
    "long_stop",
    "short_stop"
]

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

    self.bg5 = BarGenerator(self.on_bar, 5, self.on_5min_bar)
    self.bg15 = BarGenerator(self.on_bar, 15, self.on_15min_bar)

    self.am5 = ArrayManager()
    self.am15 = ArrayManager()

def on_init(self):
    """
    策略初始化
    """
    self.write_log("策略初始化")

    self.load_bar(10)

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.bg5.update_tick(tick)      # 将tick数据推进去,并更新一下,放到bg5中。 因为tick是需要合成bar,所以合成一个就行;

def on_bar(self, bar: BarData):
    """
    Callback of new bar data update.
    """
    self.bg15.update_bar(bar)      # 分别合成两个时间周期要用的数据
    self.bg5.update_bar(bar)       # 分别合成两个时间周期要用的数据

def on_5min_bar(self, bar: BarData):

    self.cancel_all()

    am5 = self.am5
    self.am5.update_bar(bar)

    if not self.am5.inited or not self.am15.inited:
        return

    # 计算atr和10日atr的均值
    atr_array = am5.atr(self.atr_length, array=True)   # atr的计算方法
    self.atr_value = atr_array[-1]    # 计算atr的最新值,也就是最新的一个。 注意,用self.
    self.atr_ma = atr_array[-self.atr_ma_length:].mean() 

    # 计算成交量和成交量的均值
    volume_array = am5.volume
    self.volume_value = volume_array[-1]
    self.volume_ma = volume_array[-self.volume_ma_length:].mean()

    # 当前无持仓
    if self.pos == 0:

        self.intra_trade_high = bar.high_price
        self.intra_trade_low = bar.low_price
        self.long_stop = 0
        self.short_stop = 0

        if self.ma_trend > 0 and self.bar.close_price >= entry_up and \
            self.atr_value >= self.atr_ma and self.volume_value >= self.volume_ma:
            self.buy(self.bar.close_price + 10, self.fixed_size, stop=True)

        elif self.ma_trend < 0 and self.bar.close_price <= entry_down and \
            self.atr_value >= self.atr_ma and self.volume_value >= self.volue_ma:
            self.short(self.bar.close_price - 10, self.fixed_size, stop=True)

    # 持有多仓
    elif self.pos > 0:

        self.intra_trade_high = max(self.intra_trade_high, bar.high_price)
        self.intra_trade_low = bar.low_price
        self.long_stop =self.intra_trade_high - self.fixed_sl

        self.sell(self.long_stop, abs(self.pos), stop=True)

    # 持有空仓
    else:

        self.intra_trade_low = min(self.intra_trade_low, bar.low_price)
        self.intra_trade_high = bar.high_price
        self.short_stop = self.intra_trade_low + self.fixed_sl

        self.cover(self.short_stop, abs(self.pos), stop=True)

    self.put_event() 

def on_15min_bar(self, bar: BarData):

    self.am15.update_bar(bar)

    if not self.am15.inited:
        return

    self.fast_ma = self.am15.sma(self.fast_window)
    self.slow_ma = self.am15.sma(self.slow_window)

    if self.fast_ma > self.slow_ma:
        self.ma_trend = 1

    elif self.fast_ma < self.slow_ma:
        self.ma_trend = -1

    else:
        self.ma_trend = 0

    self.put_event()

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
Administrator
avatar
加入于:
帖子: 4228
声望: 241

没有成交记录,说明回测过程中没有触发过委托成家了,通常两个可能:

  1. 没有触发信号发出过委托
  2. 发出的委托始终没有成交过

请在on_bar对应的逻辑上加上print输出来排查下吧,通常1的原因居多,print输出内容需要在cmd中查看了。

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