VeighNa量化社区
你的开源社区量化交易平台
wangmingwei's Avatar
Member
离线
23 帖子
声望: 0

如题,
谢谢

我们都知道常说的dual thrust策略是根据开盘价加减range得到一个上下轨的范围,突破之后进行入场

vnpy的DT策略,有些 不同,它是设置只要比开盘价高就用上轨的价格一直发出买入信号,反之卖空。

我想知道这样做的好处是什么?有什么优势吗?

MTF wrote:

停止策略的时候(或者发生成交)才会触发该文件的写入更新,检查下你是否直接关闭了程序吧
感谢回答
我没有主动在盘中关闭程序。
今天开盘又有更新了,我在观察观察吧。谢谢大佬

我比较惊奇的是,刚开始他自己用np和pd写的。
后来我把我们的官网给了它,它自己看了后,就用vnpy的框架写出来了

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

class ChatGptDt(CtaTemplate):
    """"""

    author = "vn.py"

    vt_symbol = "IF2305.CFFEX"
    fixed_size = 1
    atr_length = 22
    atr_ma_length = 10
    k1 = 0.5
    k2 = 0.5
    trading_window = 30

    atr_value = 0
    atr_ma_value = 0
    range_up = 0
    range_down = 0
    long_entry = 0
    long_exit = 0
    short_entry = 0
    short_exit = 0
    trading_window_high = 0
    trading_window_low = 0
    exit_long = False
    exit_short = False

    parameters = [
        "fixed_size",
        "atr_length",
        "atr_ma_length",
        "k1",
        "k2",
        "trading_window",
    ]
    variables = [
        "atr_value",
        "atr_ma_value",
        "range_up",
        "range_down",
        "long_entry",
        "long_exit",
        "short_entry",
        "short_exit",
        "trading_window_high",
        "trading_window_low",
        "exit_long",
        "exit_short",
    ]

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

        self.bg = BarGenerator(self.on_bar)
        self.am = 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.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.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """
        self.am.update_bar(bar)
        if not self.am.inited:
            return

        self.calculate_atr()
        self.calculate_range()
        self.calculate_entry_exit()
        self.calculate_trading_window()
        self.calculate_exit()

        if self.pos == 0:
            self.entry_long()
            self.entry_short()
        elif self.pos > 0:
            self.exit_long()
            self.entry_short()
        elif self.pos < 0:
            self.exit_short()
            self.entry_long()

        self.put_variables_event()

    def calculate_atr(self):
        """"""
        atr_array = self.am.atr(self.atr_length, array=True)
        self.atr_value = atr_array[-1]
        self.atr_ma_value = atr_array[-self.atr_ma_length:].mean()

    def calculate_range(self):
        """"""
        self.range_up = self.k1 * self.atr_value +self.am.high_array[-self.trading_window:].max()
        self.range_down = self.k2 * self.atr_value - self.am.low_array[-self.trading_window:].min()

    def calculate_entry_exit(self):
        """"""
        self.long_entry = self.range_up
        self.long_exit = self.atr_ma_value
        self.short_entry = self.range_down
        self.short_exit = self.atr_ma_value

    def calculate_trading_window(self):
        """"""
        self.trading_window_high = self.am.high_array[
            -self.trading_window:
        ].max()
        self.trading_window_low = self.am.low_array[
            -self.trading_window:
        ].min()

    def calculate_exit(self):
        """"""
        self.exit_long = (
            self.pos > 0
            and self.am.low_array[-1] < self.trading_window_low
        )
        self.exit_short = (
            self.pos < 0
            and self.am.high_array[-1] > self.trading_window_high
        )

    def entry_long(self):
        """"""
        if self.close_price > self.long_entry:
            self.buy(self.long_entry, self.fixed_size, True)

    def exit_long(self):
        """"""
        if self.exit_long:
            self.sell(self.long_exit, abs(self.pos), True)

    def entry_short(self):
        """"""
        if self.close_price < self.short_entry:
            self.short(self.short_entry, self.fixed_size, True)

    def exit_short(self):
        """"""
        if self.exit_short:
            self.cover(self.short_exit, abs(self.pos), True)

description

据理解,这个json文件是缓存策略初始化数据的,每次策略启动会读取这个文件内容。
现在遇到的问题是它(最上面这个)这个数据已经三天没有变化了,
下面两个是我做对照,在最新一天添加的策略。
请问这是什么原因导致的呢?

夜盘的日k线是怎么合成的?
vnpy的BG 会自己根据有夜盘的品种合成相应的日k线吗?

000

已解决

wangmingwei wrote:

想写个突破均线开仓的策略
但是获取k线收盘价不知道如何操作了
我的想法是从arrarymanager里面提取最新的k线收盘价
但是它好像是ndarray数列还是什么的,请问能从这里面取到吗?用什么方法呢?
或者有没有其他更好的方法取到最新几根k线收盘价呢?

是用bar.close_price 还是用am.close_array?

想写个突破均线开仓的策略
但是获取k线收盘价不知道如何操作了
我的想法是从arrarymanager里面提取最新的k线收盘价
但是它好像是ndarray数列还是什么的,请问能从这里面取到吗?用什么方法呢?
或者有没有其他更好的方法取到最新几根k线收盘价呢?
折腾了两天,实在不知道怎么做了
谢谢

VN神经蛙 wrote:

BarData是有datetime属性的,可以尝试用bar.datetime访问最新一根K线的时间,代替TIME_NOW进行> 判断

谢谢回答
这个问题解决了。是用的bar.datetime
回测成交记录为空,是因为我的判断语句写的逻辑错了。原本写的else,现在重新把不在交易时间的情况写在elif里面了。给遇到同样问题的小伙伴做个参考。

可喜可贺!

之前搜索,总会把盗版的排在前面,导致很多新人绕了很多弯路

它里面很多代码,简直就是shit!而且背离了python代码崇尚的简单、优雅

xiaohe wrote:

回测的时候你这个TIME_NOW就是回测的时间点不是按你所想的收到每根K线的时间
感谢回复
是的,我也发现了,就是我电脑当前时间

但是,我直接实盘模拟的时候 也是没有交易委托提交。是不是我这个循环判断放的地方不对呀

初衷:(基于双均线策略)想规避开盘前后的剧烈波动,不想持隔夜仓。想加入交易时间段的方法
我是这样写的:

设置交易时间参数,我想在9:15-14:45 和21:15-22:45 这段时间交易

DAY_START = time(9, 15)
DAY_END = time(14, 45)

NIGHT_START = time(21, 15)
NIGHT_END = time(22, 45)
TIME_NOW = datetime.now().time()

其他内容没改,就加入了个判断:

判断交易时间

    if DAY_END >= TIME_NOW >= DAY_START or NIGHT_END >= TIME_NOW >= NIGHT_START:

        if cross_over:
            if self.pos == 0:
                self.buy(bar.close_price, 1,stop=True)
            elif self.pos < 0:
                self.cover(bar.close_price, 1,stop=True)
                self.buy(bar.close_price, 1,stop=True)

        elif cross_below:
            if self.pos == 0:
                self.short(bar.close_price, 1,stop=True)
            elif self.pos > 0:
                self.sell(bar.close_price, 1,stop=True)
                self.short(bar.close_price, 1,stop=True)

        self.put_event()
    # 如果不在交易时间,停止交易并且清仓
    else:
        if  self.pos > 0:
            self.cover(bar.close_price, 1,stop=True)

        elif self.pos < 0:
            self.short(bar.close_price, 1,stop=True)

        else:            
            self.cancel_all()

        self.put_event()

我遇到的问题是:既没有报错,也能运行到最底部。但是回测的时候显示成交记录为空。不知道哪里写错了。
是不是我判断的逻辑,或者放的位置不正确?请大佬指点一下。

xiaohe wrote:

  1. 可以具体描述一下你的应用场景和出现的问题;
    比如,做夜盘的螺纹,第二天加载策略初始化的时候(双均线策略),fast_ma 和slow_ma的均线数值 与第二天开盘时的数值对不上,它显示的是昨天白天15:00的数值,而不是夜盘21:00的数值。

xiaohe wrote:

对于国内期货市场来说,应该在交易时段开始前,启动策略的自动交易,然后直到收盘后,再关闭自动交易。因为现在CTP夜盘收盘后也会关闭系统,早上开盘前重启,所以夜盘收盘后也需要停止策略,关闭VeighNa Trader。如果不想手动关闭,可以使用no_ui脚本定时关闭重启
https://gitee.com/vnpy/vnpy/blob/master/examples/no_ui/run.py
谢谢

有没有在的大神呀

MTF wrote:

夜盘属于第二个交易日,所以上午建的多头,是昨仓了。但是注意这个切换要在重启系统后才会生效
您好,请问,如果24小时挂机不关机,假如自动交易白天建仓,到了晚上出现了卖点,是不是不会委托成功呢?谢谢

© 2015-2022 微信 18391752892
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

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