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

description
如上图所示,策略在2022-12-08 22:35:00发出信号。
description
然后上图是委托信息,显示在22:37:23进行委托了4次,每次2手,但是我的代码里是一个单子,开的数量2手,
description
上图是成交信息,显示成交了5次。
我不大懂了,为什么会出现这种情况呢,策略是多标的的,先产生信号,记录下target手数,然后判断current_pos与target的差值进行委托,如果是重复委托的话,为什么是在同一个时间上呢,每次运行on_bar,有concel不成交的订单,感觉也不是重复提交的问题。这样的话要怎么办呢?是不是要判断一下成交状态呢,怎么判断?

Member
avatar
加入于:
帖子: 726
声望: 38

贴下具体的策略代码?

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

MTF wrote:

贴下具体的策略代码?
```
def on_tick(self, tick: TickData):

    # self.cancel_all()
    self.pbg.update_tick(tick)
    nm = tick.symbol+'.'+str(tick.exchange).split('.')[1]  

    self.last_tick_price[nm] = tick.last_price ##后期可以加上时间限制,不用一直记录 
    if self.pre_close[nm]==0:
        self.pre_close[nm] = tick.pre_close

    # pos =  self.strategy_engine.main_engine.get_all_positions()
    # print(pd.DataFrame(pos)) 

    # print('nm',nm,self.pre_close[nm])
    # while self.circle>0:
    #     print('nmpreclose',self.pre_close[nm])
    #     self.circle -= 1

def on_bars(self, bars: Dict[str, BarData]):
    # print(bars.items())
    self.cancel_all()
    for vt_symbol, bar in bars.items():
        am: ArrayManager = self.ams[vt_symbol]
        am.update_bar(bar)

    for vt_symbol, bar in bars.items():
        am: ArrayManager = self.ams[vt_symbol]
        if not am.inited:
            return

        # vt_symbol = bar.symbol+'.'+str(bar.exchange).split('.')[1]
        ava_cash = self.percent*5000000 #0.1*(self.get_account(self).balance-self.get_account(self).frosen)#

        #self.cta_engine.main_engine.get_account("12345.CTP")
            #self.get_account(self).balance-self.get_account(self).frosen  
        if vt_symbol in self.vt_symbols:
            if len(self.pdata[vt_symbol])<20:
                self.pdata[vt_symbol].append(bar.close_price)
            else:
                self.pdata[vt_symbol].pop(0)
                self.pdata[vt_symbol].append(bar.close_price)

        # pos_data = pd.DataFrame(self.strategy_engine.main_engine.get_all_positions())#self.get_pos(vt_symbol)
        # pos_dict = dict(zip(list(pos)))
        current_pos = self.get_pos(vt_symbol)

        print(vt_symbol,"当前持仓:",current_pos,self.sig[vt_symbol])

        if current_pos==0 and self.sig[vt_symbol]==0:#self.sig[vt_symbol]==0:    
            #self.sig[vt_symbol]==0 
            #判断是否开仓  
            if (bar.datetime.time() >= datetime.time(10,0) and bar.datetime.time()<= datetime.time(15,0))\
                or (bar.datetime.time() >= datetime.time(21,10)):  
                if vt_symbol in self.up_pool:
                    # print("一些信息:",vt_symbol,bar.close_price,self.up_threshold[vt_symbol])
                    if bar.close_price>self.up_threshold[vt_symbol]:# and (self.pre_close[vt_symbol]<self.up_threshold[vt_symbol]):
                        # print(vt_symbol,'cross') #and self.pre_close[vt_symbol]<=self.up_threshold[vt_symbol]:
                        # print(max(self.pdata[vt_symbol]),self.up_threshold[vt_symbol])
                        bid_price =  bar.close_price
                        #np.ceil(bar.close_price + min(self.orderstep*self.get_pricetick(vt_symbol),np.mean(np.diff(self.pdata[vt_symbol]))))
                        bid_vol = math.floor(self.percent*ava_cash/(self.get_size(vt_symbol)*bid_price*self.up_margin[vt_symbol]))
                        self.buy_price[vt_symbol] = bid_price
                        print('信号值:',self.sig[vt_symbol])
                        self.sig[vt_symbol] = 1
                        self.targets[vt_symbol] = bid_vol
                        # order = self.buy(vt_symbol, bid_price, max(1,bid_vol))  
                        print(bar.datetime,'做多:',vt_symbol,'当前仓位:',current_pos,'开仓手数',bid_vol,'开仓价格:',bid_price,'信号值:',self.sig[vt_symbol])

                elif vt_symbol in self.dn_pool:
                    if bar.close_price<self.dn_threshold[vt_symbol]:# and (self.pre_close[vt_symbol]>self.dn_threshold[vt_symbol]):
                        # print(min(self.pdata[vt_symbol]),self.up_threshold[vt_symbol])
                        # ask_price = math.ceil(tick.last_price - min(self.orderstep*self.get_pricetick(vt_symbol),np.mean(np.diff(self.pdata[vt_symbol]))))
                        ask_price = bar.close_price
                        ask_vol = math.floor(self.percent*ava_cash/(self.get_size(vt_symbol)*ask_price*self.dn_margin[vt_symbol]))
                        self.targets[vt_symbol] = -ask_vol
                        self.sell_price[vt_symbol] = ask_price
                        # self.short(vt_symbol, ask_price, max(ask_vol,1))
                        print('信号值:',self.sig[vt_symbol])
                        self.sig[vt_symbol] = -1
                        print(bar.datetime,'做空:',vt_symbol,'当前仓位:',current_pos,'开仓手数:',ask_vol,'开仓价格:',ask_price,'信号值:',self.sig[vt_symbol])

        elif current_pos > 0 and self.sig[vt_symbol]>0:
            if len(self.pdata[vt_symbol])>5:
                long_profit = bar.close_price/self.buy_price[vt_symbol]-1
                ask_price = math.ceil(bar.close_price - min(self.orderstep*self.get_pricetick(vt_symbol),np.mean(np.diff(self.pdata[vt_symbol]))))
                if long_profit<self.start_stop:
                    if bar.close_price < 0.95*self.up_threshold[vt_symbol] and min(self.pdata[vt_symbol][-5:-1])>self.up_threshold[vt_symbol]:
                        self.targets[vt_symbol] = 0
                        print('平多1')
                        # self.sig[vt_symbol] = 0
                else:
                    ma_new = (self.ma[vt_symbol]+bar.close_price)/self.period_2
                    if long_profit>1.5*self.start_stop:
                        self.targets[vt_symbol] = 0
                        print('平多2')
                        # self.sig[vt_symbol] = 0
                    elif bar.close_price < ma_new and min(self.pdata[vt_symbol][-5:-1])>ma_new and self.sell_signal[vt_symbol]==1:
                        self.targets[vt_symbol] = 0
                        print('平多3')
                        # self.sig[vt_symbol] = 0

        elif current_pos < 0 and self.sig[vt_symbol] < 0: 
            print('当前仓位:',current_pos,'信号值:',self.sig[vt_symbol])
            if len(self.pdata[vt_symbol])>5:
                short_profit = self.sell_price[vt_symbol]/bar.close_price-1
                bid_price = math.ceil(bar.close_price + min(self.orderstep*self.get_pricetick(vt_symbol),np.mean(np.diff(self.pdata[vt_symbol]))))
                if short_profit<self.start_stop:
                    if bar.close_price > 1.05*self.dn_threshold[vt_symbol] and max(self.pdata[vt_symbol][-5:-1])<=self.dn_threshold[vt_symbol]:
                        self.targets[vt_symbol] = 0
                        print('平空1')
                        # self.sig[vt_symbol] = 0
                else:
                    ma_new = (self.ma[vt_symbol]+bar.close_price)/self.period_2
                    if short_profit>1.5*self.start_stop:
                        self.targets[vt_symbol] = 0
                        print('平空2')
                        # self.sig[vt_symbol] = 0
                    elif bar.close_price > ma_new and max(self.pdata[vt_symbol][-5:-1])<=ma_new and self.buy_signal[vt_symbol]==1:
                        self.targets[vt_symbol] = 0
                        print('平空3')
                        # self.sig[vt_symbol] = 0




        #判断是否平仓
    for vt_symbol in self.vt_symbols:
        target_pos = self.targets[vt_symbol]
        current_pos = self.get_pos(vt_symbol)

        pos_diff = target_pos - current_pos
        volume = abs(pos_diff)
        price = self.last_tick_price[vt_symbol]
        if pos_diff > 0:#开多或平空  
            # price = bars[vt_symbol].close_price   
            if current_pos < 0:
                self.cover(vt_symbol, price, volume)
                self.sig[vt_symbol] = 0

            else:
                self.buy(vt_symbol, price, volume)
                # self.sig[vt_symbol] = 1

        elif pos_diff < 0:
            # price = bars[vt_symbol].close_price
            if current_pos > 0:
                self.sell(vt_symbol, price, volume)
                self.sig[vt_symbol] = 0
            else:
                self.short(vt_symbol,price, volume)
                # self.sig[vt_symbol] = -1

    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()

```

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

MTF wrote:

贴下具体的策略代码?
代码贴上了,麻烦了,谢谢哦~~

Member
avatar
加入于:
帖子: 726
声望: 38
        #判断是否平仓
    for vt_symbol in self.vt_symbols:
        target_pos = self.targets[vt_symbol]
        current_pos = self.get_pos(vt_symbol)

        pos_diff = target_pos - current_pos
        volume = abs(pos_diff)
        price = self.last_tick_price[vt_symbol]
        if pos_diff > 0:#开多或平空  
            # price = bars[vt_symbol].close_price   
            if current_pos < 0:
                self.cover(vt_symbol, price, volume)
                self.sig[vt_symbol] = 0

            else:
                self.buy(vt_symbol, price, volume)
                # self.sig[vt_symbol] = 1

        elif pos_diff < 0:
            # price = bars[vt_symbol].close_price
            if current_pos > 0:
                self.sell(vt_symbol, price, volume)
                self.sig[vt_symbol] = 0
            else:
                self.short(vt_symbol,price, volume)
                # self.sig[vt_symbol] = -1

    self.put_event()

看了下你的buy函数调用,只出现在了这个目标仓位交易操作里,on_bars函数头部也调用了cancel_all全撤之前的委托。

之前截图里看不到委托号信息,如果是不一样的话,建议排查下你的on_tick函数里的那个pbg(看着应该是K线合成器?),看看是否同一个时间点重复推送了多次。

排查方式可以在on_bars函数头部,加一个self.write_log(str(datetime.now())),打印输出下on_bars被调用的本地时间

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

MTF wrote:

```

之前截图里看不到委托号信息,如果是不一样的话,建议排查下你的on_tick函数里的那个pbg(看着应该是K线合成器?),看看是否同一个时间点重复推送了多次。

排查方式可以在on_bars函数头部,加一个self.write_log(str(datetime.now())),打印输出下on_bars被调用的本地时间

委托号信息的话,委托单号是不一样的,但是时间点是一样的。
如果是K线合成器同一时间重复推送的话,产生这种情况的原因是什么呢?

Member
avatar
加入于:
帖子: 726
声望: 38

通常应该是合成bars推送的条件判断不严谨导致的了

Member
avatar
加入于:
帖子: 3698
声望: 238

可以参考一下全实战进阶系列【超越海龟策略精析】的第51课时的内容

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

xiaohe wrote:

可以参考一下全实战进阶系列【超越海龟策略精析】的第51课时的内容
https://appszu5scwd6134.h5.xiaoeknow.com/v1/goods/goods_detail/p_6236e363e4b09dda124fcdb1?type=3
您说的是这个链接里边的课程吗?

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

MTF wrote:

通常应该是合成bars推送的条件判断不严谨导致的了

description
在init函数里定义了K线生成器,然后在on_tick里面update,我没有进行条件判断,是不是在这里以标的为key去分别定义K线生成器才对。

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

MTF wrote:

通常应该是合成bars推送的条件判断不严谨导致的了
能不能麻烦你看下图片里的代码,init里边创建了bargenerator,on_tick里边update了一下,on_bars里边进行了使用,我需要在哪里完善优化?
description

description

Member
avatar
加入于:
帖子: 3698
声望: 238

许冉 wrote:

xiaohe wrote:

可以参考一下全实战进阶系列【超越海龟策略精析】的第51课时的内容
https://appszu5scwd6134.h5.xiaoeknow.com/v1/goods/goods_detail/p_6236e363e4b09dda124fcdb1?type=3
您说的是这个链接里边的课程吗?
是的

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

沪公网安备 31011502017034号

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