前面写了一篇将通达信T0公式翻译成QMT代码的文章(QMT小练习——翻译一个通达信T0指标),今天我们设置买入一只股票并进行回测,看一下效果如何。
比上一篇文章的代码多了:
1、init函数中增加了几个全局变量,分别为下单函数的必要参数和买底仓的开关。
2、买入底仓的操作
3、买入和卖出的下单操作。
4、“基本信息”一栏中的“默认品种”改成交易标的,这样回测完成后,看的效果才更加准确,因为这儿默认是沪深300指数。
代码如下:
#encoding:gbk
import pandas as pd
import numpy as np
def init(C):
#设置标的
C.trade_code='300750.SZ'
#这个变量是买入代码,为下单公式的参数之一
C.buy_code = 23
#这个变量是卖出代码,为下单公式的参数之一
C.sell_code = 24
#这个变量是账号名称,为下单公式的参数之一
C.acct = '666'
#买底仓的开关
C.first_buy = True
def handlebar(C):
#只在第一次运行时买入底仓20手
if C.first_buy == True:
print('买入底仓')
passorder(C.buy_code, 1101, C.acct, C.trade_code, 14, -1, 2000, '通达信T0', 1 , '', C)
C.first_buy = False
#K线当天的日期
day = timetag_to_datetime(C.get_bar_timetag(C.barpos),'%Y%m%d')
#K线当天的时间
minute = timetag_to_datetime(C.get_bar_timetag(C.barpos),'%Y%m%d%H%M%S')
#从这一天开始获取数据
C.start_time = '20240401'
#获取数据到这一天结束
C.end_time = '20240726'
#获取分钟K线的收盘价
price_m = C.get_market_data_ex(fields=['close'],stock_code=[C.trade_code],period='1m',start_time=C.start_time,end_time=minute,count=50,dividend_type='front',fill_data=True,subscribe=True)
#获取日K线的收盘价、最高价和最低价
price_d = C.get_market_data_ex(fields=['close','high','low'],stock_code=[C.trade_code],period='1d',start_time=C.start_time,end_time=day,count=50,dividend_type='front',fill_data=True,subscribe=True)
#日K收盘价数组
DYNAINFO_3 = price_d[C.trade_code]['close'].values
#日K最高价数组
DYNAINFO_5 = price_d[C.trade_code]['high'].values
#日K最低价数组
DYNAINFO_6 = price_d[C.trade_code]['low'].values
#以下为与通达信公式一致
H1 = MAX(DYNAINFO_3,DYNAINFO_5)
L1 = MIN(DYNAINFO_3,DYNAINFO_6)
P1 = H1 - L1
zuli = L1+P1*7/8
zhicheng = L1+P1*0.5/8
#发出买入信号
if LONGCROSS(zhicheng[-21:],price_m[C.trade_code]['close'].values[-21:],2)[-1]:
print(minute,'买入')
#买入一手
passorder(C.buy_code, 1101, C.acct, C.trade_code, 14, -1, 100, '通达信T0', 1 , '', C)
#发出卖出信号
if LONGCROSS(price_m[C.trade_code]['close'].values[-21:],zuli[-21:],2)[-1]:
print(minute,'卖出')
#卖出1手
passorder(C.sell_code, 1101, C.acct, C.trade_code, 14, -1, 100, '通达信T0', 1 , '', C)
def MAX(S1,S2): return np.maximum(S1,S2)
def MIN(S1,S2): return np.minimum(S1,S2) #序列min
def LAST(S, A, B): #从前A日到前B日一直满足S_BOOL条件, 要求A>B & A>0 & B>=0
return np.array(pd.Series(S).rolling(A+1).apply(lambda x:np.all(x[::-1][B:])),dtype=bool)
def LONGCROSS(S1,S2,N): #两条线维持一定周期后交叉,S1在N周期内都小于S2,本周期从S1下方向上穿过S2时返回1,否则返回0
return np.array(np.logical_and(LAST(S1<S2,N,1),(S1>S2)),dtype=bool) # N=1时等同于CROSS(S1, S2)
难点没有,代码几乎都注释了,可以参考一下。
回测结果(回测时间7月1-26日):

黄线是标的走势,白线是策略净值,看起来两条线是从相互交错到白线胜出。表面看起来是策略有效,我们接着往下看。下图显示,最后持仓已经达到了45手(初始为20手),像不像T0失败变补仓(不知道你们干没干过这事,反正我干过)。

所以,策略还需要改进,必须要做到持仓不变才行。
发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/129433
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!