盘口策略 | 交易中最重要的是什么?

 量化策略开发,高质量社群,交易思路分享等相关内容

『正文』

ˇ

交易中最重要的是什么?

当然是Timing啊~~~

“时机是这个世界上最难得到,又最容易失去的东西”夫难得而易失者,时也;时至而不旋踵者,机也,故圣人常顺时而动,智者必因机而发.原文出自《九州春秋》        

被套不是最难受的,难受的是你止损后行情来了,就差一点你就见到黎明的太阳了。这叫什么?Timing啊~~~

A大架狙一分钟没人来,刚切道具人就拉出来把你秒了,这叫什么?Timing啊~~~

桓温枋头撤军,以精兵叠后,谨慎小心了一路,马上就要回到东晋了松懈了,被慕容垂8000精骑兵突袭死伤过半。这叫什么?Timing啊~~~

人生有太多timing时刻,不是你抓别人的,就是别人抓你的。这个市场何尝不是,我也想抓抓市场的timing,不知可否。

言归正传,我们想抓市场的机会需要有具体的方法和既定规则,我们是做量化的所以每一步都要能说明清楚。

几年前接触到订单流觉得很有意思,它是从微观角度来描述这个市场的,使用最小颗粒的数据计算出主动买卖的指标,找到价格的支撑,阻力,哪个K线主动买入多,哪个是主动卖出多,整个市场主动买卖力量是如何分布的等等之类,它最吸引我的地方是可以用数量描述清楚市场的多空力量。这一点儿对于做量化策略非常关键,可以编写一个完整的交易条件,而不是像某些主观理论存在模棱两可的地方。《订单流图表与普通K线的不同》

订单流不会错吗?错,会经常错。不怕它错,有对应的止损止盈,做的是一个盈亏比。

(图表来源:松鼠沙盘)

(图表来源:松鼠沙盘)

图中的红绿横线就是由多个失衡造成的堆积,分为多头堆积和空头堆积。也就是在某一个K线上出现了供需矛盾极大的情况,有一方占有绝对优势,

这是一个交易的信号。当出现信号时,可以尝试把握这种机会。止损设置在信号K线的最低价或者空头的最高价。以小的试错成本等待一个较大盈亏比的机会。也就是说你要抓主力的timing~哈哈

策略逻辑

1.开仓条件:多头堆积次数大于X做多,空头堆积次数大于X做空.互为正反手。

2.固定止损:以开仓价格的百分比计算止损价。

3.跟踪止盈:以吊灯方法跟踪价格计算出场线。

策略逻辑非常简单,没有那么多弯弯绕。这也是我非常喜欢它的地方,不用动脑子。订单流策略不同于传统技术指标策略,它无法预测信号。如果是MACD或者KDJ,你甚至可以预判到是否会交叉,但是订单流不行。它是基于最小颗粒度计算的主动买卖力量,只能等到它出现你才知道。

策略模块

1.通过tick(或逐笔)数据计算of数据

2.基于of数据计算堆积信号或其他指标

3.合成堆积信号为bar数据进行回测

4.基于CTP实时生成OF数据及信号(实盘版)

盘口策略我们分为俩个版本:回测版实盘版,今天讲的是回测版本,俱乐部里拿到源码后,群友一定会问很多的问题,策略代码实现较为复杂。我们先消化了回测版,然后7月初发布CTP实盘版。

tick生成of数据:

def orderflow_df_new(df_tick,df_min):    df_of=pd.DataFrame({})    t1 = time.time()    startArray = pd.to_datetime(df_min['starttime']).values    voluememin= df_min['volume'].values    highs=df_min['high'].values    lows=df_min['low'].values    opens=df_min['open'].values    closes=df_min['close'].values    endArray = pd.to_datetime(df_min['datetime']).values    tTickArray = pd.to_datetime(df_tick['datetime']).values    bp1TickArray = df_tick['bid_p'].values    ap1TickArray = df_tick['ask_p'].values    lastTickArray = df_tick['lastprice'].values    volumeTickArray = df_tick['volume'].values    symbolarray = df_tick['symbol'].values    indexFinal = 0    for index,tEnd in enumerate(endArray):        start = startArray[index]        bidDict = {}        askDict = {}         bar_vol=voluememin[index]        bar_close=closes[index]        bar_open=opens[index]        bar_low=lows[index]        bar_high=highs[index]        bar_symbol=symbolarray[index]        dt=endArray[index]        for indexTick in range(indexFinal,len(df_tick)):            #.........................        bidDictResult,askDictResult = process(bidDict,askDict)        bidDictResult=dict(sorted(bidDictResult.items(),key=operator.itemgetter(0)))        askDictResult=dict(sorted(askDictResult.items(),key=operator.itemgetter(0)))        prinslist=list(bidDictResult.keys())        asklist=list(askDictResult.values())        bidlist=list(bidDictResult.values())        delta=(sum(askDictResult.values()) - sum(bidDictResult.values()))        df=pd.DataFrame({'price':pd.Series([prinslist]),'Ask':pd.Series([asklist]),'Bid':pd.Series([bidlist])})        df['symbol']=bar_symbol        df['datetime']=dt        df['delta']=str(delta)        df['close']=bar_close        df['open']=bar_open        df['high']=bar_high        df['low']=bar_low        df['volume']=bar_vol        df['ticktime']=tTickArray[indexTick]        df['dj']=GetOrderFlow_dj(df)        print(df)        df_of = pd.concat([df_of, df], ignore_index=True)    print(time.time() - t1)    return df_of

计算好订单流数据后,输出是这样:

price,Ask,Bid这三列就是订单流K线里的核心数据,入下图:

有了这个脚本,你就可以源源不断的生成orderflow数据用于研究。然后我们在计算每个K线的失衡,堆积。我们的交易条件是基于堆积的,因此我们只要算出堆积列就可以实现Bar级别回测了。如下图:

sig列就是这个bar的堆积次数,正数是多头堆积,负数是空头堆积。

计算堆积的代码:

            order= {
   
                                       "Price":price_s[i],                 "Ask":{ "Value":Bid_s[i]},                "Bid":{ "Value":Ask_s[i]}            }                             if i>=1 and i<len(price_s)-1:                if (order["Ask"]["Value"]>Ask_s[i+1]*int(Config['Value1'])):                    order["Ask"]["Color"]=itemAskBG[1]                    gxx+=1                    gj+=1                    if gj>=int(Config['Value2']) and Config['Value4']==True:                        duiji['price']=price_s[i]                        duiji['time']=dtime                        duiji['longshort']=-1                        duiji['cout']=gj                        duiji['color']='rgba(0,139,0,0.45)'#绿色                        if float(duiji['price'])>0:                            djcout+=1                else :                    gj=0                if (order["Bid"]["Value"]>Bid_s[i-1]*int(Config['Value1'])):                    xq+=1                    xxx+=1                    order["Bid"]["Color"]=itemBidBG[1]                     if xq>=int(Config['Value2']) and Config['Value4']==True:                        duiji['price']=price_s[i]                        duiji['time']=dtime                        duiji['longshort']=1                        duiji['cout']=xq                        duiji['color']='rgba(255,0,0,0.45)' #红色                        if float(duiji['price'])>0:                            djcout+=-1                else :                    xq=0

为什么要用Bar级别去回测订单流策略?

我们之前开发过很多orderflow策略脚本,详情可以查看orderflow系列。都是逐Tick回测,说实话太慢了,6个月的逐tick回测要好几个小时,这么慢的速度很难做研究,如果你的机器内存小,还有中途崩溃的问题。于是我们改变思路,在数据生成时讲信号计算好,我们只要回测含有信号的Bar就可以了。数据生成+回测用时有了质的飞跃,不到2分钟就可以完成这些工作,如下图:

用时78秒生成了orderflow数据+信号。

然后我们在用10秒回测一下:

回测已经调整好了手续费和滑点,具体品种要针对设置,这也是BackTrader麻烦的地方。为了避免偷价,我们用上一个Bar固定的信号判断,用本根bar的开盘价进行交易。这个回测是沪镍1分钟,回测的时间是2023年1月-6月。

条件设置是:堆积大于5次,正反手,固定止损0.005,固定止盈0.01

还有螺纹5M:

条件设置是:堆积大于0次,正反手,固定止损0.005,固定止盈0.01

关于收益率为什么这么少,因为我下单是1手,初始资金设置的是100W。

我回测了不同品种在同周期参数下的情况,数据较多我就不一一发了,我传到俱乐部后台了,可以下载慢慢看。

另外,要着重说一下,我目前回测没有参数寻优,这种策略逻辑非常特别,不能硬套CTA逻辑。需要针对具体的品种设置参数,如下图:

这是镍的1分钟。

这是螺纹1分钟的信号图,为什么信号数量差距这么大?因为每个品种的盘口特征,活跃度有本质的区别。要对症下药,别动不动就一个套参数打天下,一招鲜吃遍天,你以为是青霉素还是板蓝根?

生成订单流的脚本是基于国内商品的,也可以生成股票,BTC,外盘等标的数据,反正脚本是通用的,关于用什么数据没有要求,只要表头修改好就行。

我们盘口策略会在7月实盘测试,其实群里早就有朋友开始手动操作了,只是今天我们把它做成了全自动。订单流的方方面面还有很大的研究空间,我们提供了最素的版本,大家拿到源码后可以自己玩耍,比传统CTA策略更有意思。

OK,如何使用及完整代码我会录制视频讲解,大家拿到源码后可以在群里发问,想必会有很多问题,我在俱乐部群里等大家。

最后问一句:

你知木知咩叫timing啊?

本策略仅作学习交流使用,实盘交易盈亏投资者个人负责。

猜你喜欢

转载自blog.csdn.net/m0_56236921/article/details/131509948