def xtrdChkFlag(account): ''' 检查是不是有效交易 Args: account: zwQuantX数据包 #account.stkNum,>0,买入股票;<0,卖出股票;-1;卖出全部股票 #预设参数:account.qxUsr Return: xfg,True,有效交易;False,无效交易 b2:有效交易的数据包 Bar :ivar xnum (int): 用户持有资产总数 ''' kfg = False b2 = None account.trdNilFlag = False dcash9 = account.qxUsr['cash'] dnum = account.stkNum dnum5 = abs(dnum) numFg = zwt.xinEQ(dnum5, account.stkNum0, account.stkNum9) if dnum > 0: kprice = stkGetVars(account, account.priceBuy) dsum = kprice * (dnum - divmod(dnum, 100)[1]) #股票买入股票总数,必须在限额内:100-2w手,总值不能超过现金数,买空需修改此处 if numFg: if dsum < dcash9: account.stkNum = int(dnum - divmod(dnum, 100)[1]) kfg = True elif (dsum - kprice * 100) < dcash9: account.stkNum = int(dnum - divmod(dnum, 100)[1] - 100) dsum = dsum - kprice * 100 kfg = True else: account.trdNilFlag = True else: if account.stkCode in account.qxUsrStk: xnum = account.qxUsrStk[account.stkCode] if dnum == -1: account.stkNum = -xnum kfg = True else: kfg = zwt.iff2(dnum5 <= xnum, True, False) # account.trdNilFlag = not kfg elif dnum != -1: account.trdNilFlag = True # if kfg or account.trdNilFlag: b2 = xtrdObjSet(account) #设置交易节点 else: account.stkNum = 0 return kfg, b2
def zwBackTest(qx): ''' zwQuant,回溯测试主程序 【输入】 qx (zwQuantx): zwQuantx数据包 【输出】 无 ''' # 增加数据源波动率参数 zwx.stkLibSetDVix() # 计算回溯时间周期,也可以在此,根据nday调整回溯周期长度 # 或者在 qt_init数据初始化时,通过qx.qxTimSet(xtim0,xtim9),设置回溯周期长度 nday = qx.periodNDay if qx.debugMod > 0: xcod = zw.stkLibCode[0] print(zw.stkLib[xcod].tail()) print('nday', nday) # nday=3; fss = 'tmp\\' + qx.prjName + '_' + xcod + '.csv' zw.stkLib[xcod].to_csv(fss) # -------------- # 按时间循环,进行回溯测试 for tc in range(nday): tim5 = qx.DTxtim0 + dt.timedelta(days=tc) xtim = tim5.strftime('%Y-%m-%d') # print('tc',tc,xtim) # 每个测试时间点,开始时,清除qx相关参数 qx.qxTim0SetVar(xtim) # qx.prQxUsr();#qx.xtim=xtim; xpriceFlag = False # 有效交易标志Flag # 按设定的股票代码列表,循环进行回溯测试 for xcod in zw.stkLibCode: qx.stkCode = xcod # print('xcod',xcod) # xdatWrk是当前xcod,=stkLib[xcod] # xbarWrk是当前时间点的stkLib[xcod] # 注意,已经包括了,qt_init里面的扩充数据列 qx.xbarWrk, qx.xdatWrk = zwx.xbarGet8TimExt(xcod, qx.xtim) # print(xcod,'xbar\n',qx.xbarWrk) if not qx.xbarWrk[qx.priceWrk].empty: # -----dvix 波动率检查 dvix = zwx.stkGetVars(qx, 'dvix') # dvixFlag=False; dvixFlag = zwt.xinEQ(dvix, qx.dvix_k0, qx.dvix_k9) or (dvix == 0) or (np.isnan(dvix)) if dvixFlag: xpriceFlag = True # 调用回溯子程序,如果是有效交易,设置成功交易标志xtrdFlag zwBackTest100(qx) else: print('@dvix', xcod, xtim, dvix) pass # 如果所有股票代码列表循环完毕,成功交易标志为真 # 在当前测试时间点终止,设置有关交易参数 if xpriceFlag: qx.wrkNDay += 1 qx.qxTim9SetVar(qx.xtim)
def zwBackTest(qx): ''' zwQuant,回溯测试主程序 【输入】 qx (zwQuantx): zwQuantx数据包 【输出】 无 ''' # 增加数据源波动率参数 # 就是增加一列dvix数据 zwx.stkLibSetDVix() # 计算回溯时间周期,也可以在此,根据nday调整回溯周期长度 # 或者在 qt_init数据初始化时,通过qx.qxTimSet(xtim0,xtim9),设置回溯周期长度 nday = qx.periodNDay if qx.debugMod > 0: xcod = zw.stkLibCode[0] print(zw.stkLib[xcod].tail()) print('nday', nday) fss = 'tmp\\' + qx.prjName + '_' + xcod + '.csv' zw.stkLib[xcod].to_csv(fss) # -------------- # 按时间循环,进行回溯测试 for tc in range(nday): tim5 = qx.DTxtim0 + dt.timedelta(days=tc) if hasattr(qx,'timFun'): qx.timFun(qx,tim5) # 运行绑定的关于某个时间点的主函数 xtim = tim5.strftime('%Y-%m-%d') # print('tc',tc,xtim) # 每个测试时间点,开始时,清除qx相关参数 qx.qxTim0SetVar(xtim) # qx.prQxUsr() #qx.xtim=xtim xpriceFlag = False # 有效交易标志Flag # 按设定的股票代码列表,循环进行回溯测试 for xcod in zw.stkLibCode: qx.stkCode = xcod # print('xcod',xcod) # xdatWrk是当前xcod,=stkLib[xcod] # xbarWrk是当前时间点的stkLib[xcod] # 注意,已经包括了,qt_init里面的扩充数据列 qx.xbarWrk, qx.xdatWrk = zwx.xbarGet8TimExt(xcod, qx.xtim) # print(xcod,'xbar\n',qx.xbarWrk) if not qx.xbarWrk[qx.priceWrk].empty: # -----dvix 波动率检查 dvix = zwx.stkGetVars(qx, 'dvix') # dvixFlag=False dvixFlag = zwt.xinEQ(dvix, qx.dvix_k0, qx.dvix_k9) or (dvix == 0) or (np.isnan(dvix)) if dvixFlag: xpriceFlag = True # 调用回溯子程序,如果是有效交易,设置成功交易标志xtrdFlag zwBackTest100(qx) else: print('@dvix', xcod, xtim, dvix) pass # 如果所有股票代码列表循环完毕,成功交易标志为真 # 在当前测试时间点终止,设置有关交易参数 if xpriceFlag: qx.wrkNDay += 1 qx.qxTim9SetVar(qx.xtim) # print('') qx.update_usr_qxLib(qx,qx.qxLib)
def zwBackTest(qx): ''' zwQuant,回溯測試主程式 【輸入】 qx (zwQuantx): zwQuantx封包 【輸出】 無 ''' # 增加資料來源波動率參數 # 就是增加一列dvix資料 zwx.stkLibSetDVix() # 計算回溯時間週期,也可以在此,根據nday調整回溯週期長度 # 或者在 qt_init資料初始化時,通過qx.qxTimSet(xtim0,xtim9),設定回溯週期長度 nday = qx.periodNDay if qx.debugMod > 0: xcod = zw.stkLibCode[0] print(zw.stkLib[xcod].tail()) print('nday', nday) fss = 'tmp\\' + qx.prjName + '_' + xcod + '.csv' zw.stkLib[xcod].to_csv(fss) # -------------- # 按時間迴圈,進行回溯測試 for tc in range(nday): tim5 = qx.DTxtim0 + dt.timedelta(days=tc) if hasattr(qx,'timFun'): qx.timFun(qx,tim5) # 運行綁定的關於某個時間點的主函數 xtim = tim5.strftime('%Y-%m-%d') # print('tc',tc,xtim) # 每個測試時間點,開始時,清除qx相關參數 qx.qxTim0SetVar(xtim) # qx.prQxUsr() #qx.xtim=xtim xpriceFlag = False # 有效交易標誌Flag # 按設定的股票代碼列表,迴圈進行回溯測試 for xcod in zw.stkLibCode: qx.stkCode = xcod # print('xcod',xcod) # xdatWrk是當前xcod,=stkLib[xcod] # xbarWrk是當前時間點的stkLib[xcod] # 注意,已經包括了,qt_init裡面的擴充資料列 qx.xbarWrk, qx.xdatWrk = zwx.xbarGet8TimExt(xcod, qx.xtim) # print(xcod,'xbar\n',qx.xbarWrk) if not qx.xbarWrk[qx.priceWrk].empty: # -----dvix 波動率檢查 dvix = zwx.stkGetVars(qx, 'dvix') # dvixFlag=False dvixFlag = zwt.xinEQ(dvix, qx.dvix_k0, qx.dvix_k9) or (dvix == 0) or (np.isnan(dvix)) if dvixFlag: xpriceFlag = True # 調用回溯副程式,如果是有效交易,設定成功交易標誌xtrdFlag zwBackTest100(qx) else: print('@dvix', xcod, xtim, dvix) pass # 如果所有股票代碼清單迴圈完畢,成功交易標誌為真 # 在當前測試時間點終止,設定有關交易參數 if xpriceFlag: qx.wrkNDay += 1 qx.qxTim9SetVar(qx.xtim) # print('') qx.update_usr_qxLib(qx,qx.qxLib)
def xtrdChkFlag(qx): ''' 检查是不是有效交易 Args: qx (zwQuantX): zwQuantX数据包 #qx.stkNum,>0,买入股票;<0,卖出股票;-1;卖出全部股票 #预设参数:qx.qxUsr Return: xfg,True,有效交易;False,无效交易 b2:有效交易的数据包 Bar :ivar xnum (int): 用户持有资产总数 ''' kfg = False b2 = None qx.trdNilFlag = False dcash9 = qx.qxUsr['cash'] dnum = qx.stkNum dnum5 = abs(dnum) numFg = zwt.xinEQ(dnum5, qx.stkNum0, qx.stkNum9) # -------- # b2=xtrdObjSet(qx); #print('::b2\n',b2) if dnum > 0: # dsum=b2['sum']; kprice = stkGetVars(qx, qx.priceBuy) dsum = kprice * dnum # 股票买入股票总数,必须在限额内:100-2w手,总值不能超过现金数,买空需修改此处 if numFg: if dsum < dcash9: kfg = True else: qx.trdNilFlag = True else: if qx.stkCode in qx.qxUsrStk: # print('@',qx.stkCode,dnum) xnum = qx.qxUsrStk[qx.stkCode] if dnum == -1: qx.stkNum = -xnum kfg = True else: kfg = zwt.iff2(dnum5 <= xnum, True, False) # qx.trdNilFlag = not kfg elif dnum != -1: qx.trdNilFlag = True # if kfg or qx.trdNilFlag: b2 = xtrdObjSet(qx) # 设置交易节点 else: qx.stkNum = 0 return kfg, b2
def xtrdChkFlag(qx): ''' 檢查是不是有效交易 Args: qx (zwQuantX): zwQuantX數據包 #qx.stkNum,>0,買入股票;<0,賣出股票;-1;賣出全部股票 #預設參數:qx.qxUsr Return: xfg,True,有效交易;False,無效交易 b2:有效交易的資料包 Bar :ivar xnum (int): 用戶持有資產總數 ''' kfg = False b2 = None qx.trdNilFlag = False dcash9 = qx.qxUsr['cash'] dnum = qx.stkNum dnum5 = abs(dnum) numFg = zwt.xinEQ(dnum5, qx.stkNum0, qx.stkNum9) # -------- # b2=xtrdObjSet(qx) #print('::b2\n',b2) if dnum > 0: # dsum=b2['sum'] kprice = stkGetVars(qx, qx.priceBuy) dsum = kprice * dnum # 股票買入股票總數,必須在限額內:100-2w手,總值不能超過現金數,買空需修改此處 if numFg: if dsum < dcash9: kfg = True else: qx.trdNilFlag = True else: if qx.stkCode in qx.qxUsrStk: # print('@',qx.stkCode,dnum) xnum = qx.qxUsrStk[qx.stkCode] if dnum == -1: qx.stkNum = -xnum kfg = True else: kfg = zwt.iff2(dnum5 <= xnum, True, False) # qx.trdNilFlag = not kfg elif dnum != -1: qx.trdNilFlag = True # if kfg or qx.trdNilFlag: b2 = xtrdObjSet(qx) # 設定交易節點 else: qx.stkNum = 0 return kfg, b2
def xtrdChkFlag(qx): ''' 检查是不是有效交易 Args: qx (zwQuantX): zwQuantX数据包 #qx.stkNum,>0,买入股票;<0,卖出股票;-1;卖出全部股票 #预设参数:qx.qxUsr Return: xfg,True,有效交易;False,无效交易 b2:有效交易的数据包 Bar :ivar xnum (int): 用户持有资产总数 ''' kfg = False b2 = None qx.trdNilFlag = False dcash9 = qx.qxUsr['cash'] dnum = qx.stkNum dnum5 = abs(dnum) numFg = zwt.xinEQ(dnum5, qx.stkNum0, qx.stkNum9) # -------- # b2=xtrdObjSet(qx) #print('::b2\n',b2) if dnum > 0: # dsum=b2['sum'] kprice = stkGetVars(qx, qx.priceBuy) dsum = kprice * dnum # 股票买入股票总数,必须在限额内:100-2w手,总值不能超过现金数,买空需修改此处 if numFg: if dsum < dcash9: kfg = True else: qx.trdNilFlag = True else: if qx.stkCode in qx.qxUsrStk: # print('@',qx.stkCode,dnum) xnum = qx.qxUsrStk[qx.stkCode] if dnum == -1: qx.stkNum = -xnum kfg = True else: kfg = zwt.iff2(dnum5 <= xnum, True, False) # qx.trdNilFlag = not kfg elif dnum != -1: qx.trdNilFlag = True # if kfg or qx.trdNilFlag: b2 = xtrdObjSet(qx) # 设置交易节点 else: qx.stkNum = 0 return kfg, b2
def xtrdChkFlag00(qx): ''' 检查是不是有效交易 Args: qx (zwQuantX): zwQuantX数据包 #qx.stkNum,>0,买入股票;<0,卖出股票;-1;卖出全部股票 #预设参数:qx.qxUsr Return: xfg,True,有效交易;False,无效交易 b2:有效交易的数据包 Bar :ivar xnum (int): 用户持有资产总数 ''' kfg = False b2 = None dcash9 = qx.qxUsr['cash'] #-------- #b2=xtrdObjSet(qx); #print('::b2\n',b2) if qx.stkNum > 0: #dsum=b2['sum']; kprice = stkGetVars(qx, qx.priceBuy) dsum = kprice * qx.stkNum #股票买入股票总数,必须在限额内:100-2w手,总值不能超过现金数,买空需修改此处 kfg = (zwt.xinEQ(qx.stkNum, qx.stkNum0, qx.stkNum9) and (dsum < dcash9)) else: if qx.stkCode in qx.qxUsrStk: xnum = qx.qxUsrStk[qx.stkCode] if (qx.stkNum == -1) or (abs(qx.stkNum) >= xnum): qx.stkNum = -xnum kfg = True elif abs(qx.stkNum) < xnum: kfg = True # if kfg: b2 = xtrdObjSet(qx) #设置交易节点 else: qx.stkNum = 0 return kfg, b2
def xtrdChkFlag00(qx): ''' 檢查是不是有效交易 Args: qx (zwQuantX): zwQuantX數據包 #qx.stkNum,>0,買入股票;<0,賣出股票;-1;賣出全部股票 #預設參數:qx.qxUsr Return: xfg,True,有效交易;False,無效交易 b2:有效交易的資料包 Bar :ivar xnum (int): 用戶持有資產總數 ''' kfg = False b2 = None dcash9 = qx.qxUsr['cash'] # -------- # b2=xtrdObjSet(qx) #print('::b2\n',b2) if qx.stkNum > 0: # dsum=b2['sum'] kprice = stkGetVars(qx, qx.priceBuy) dsum = kprice * qx.stkNum # 股票買入股票總數,必須在限額內:100-2w手,總值不能超過現金數,買空需修改此處 kfg = (zwt.xinEQ(qx.stkNum, qx.stkNum0, qx.stkNum9) and (dsum < dcash9)) else: if qx.stkCode in qx.qxUsrStk: xnum = qx.qxUsrStk[qx.stkCode] if (qx.stkNum == -1) or (abs(qx.stkNum) >= xnum): qx.stkNum = -xnum kfg = True elif abs(qx.stkNum) < xnum: kfg = True # if kfg: b2 = xtrdObjSet(qx) # 設定交易節點 else: qx.stkNum = 0 return kfg, b2
def xtrdChkFlag00(qx): ''' 检查是不是有效交易 Args: qx (zwQuantX): zwQuantX数据包 #qx.stkNum,>0,买入股票;<0,卖出股票;-1;卖出全部股票 #预设参数:qx.qxUsr Return: xfg,True,有效交易;False,无效交易 b2:有效交易的数据包 Bar :ivar xnum (int): 用户持有资产总数 ''' kfg = False b2 = None dcash9 = qx.qxUsr['cash'] # -------- # b2=xtrdObjSet(qx) #print('::b2\n',b2) if qx.stkNum > 0: # dsum=b2['sum'] kprice = stkGetVars(qx, qx.priceBuy) dsum = kprice * qx.stkNum # 股票买入股票总数,必须在限额内:100-2w手,总值不能超过现金数,买空需修改此处 kfg = (zwt.xinEQ(qx.stkNum, qx.stkNum0, qx.stkNum9) and (dsum < dcash9)) else: if qx.stkCode in qx.qxUsrStk: xnum = qx.qxUsrStk[qx.stkCode] if (qx.stkNum == -1) or (abs(qx.stkNum) >= xnum): qx.stkNum = -xnum kfg = True elif abs(qx.stkNum) < xnum: kfg = True # if kfg: b2 = xtrdObjSet(qx) # 设置交易节点 else: qx.stkNum = 0 return kfg, b2
def gdufBackTest(account, day): ''' 回溯测试主程序 【输入】 account 【输出】 无 ''' # 增加数据源波动率参数 stkLibSetDVix() #计算回溯时间周期,也可以在此,根据nday调整回溯周期长度 #或者在 qt_init数据初始化时,通过qx.qxTimSet(xtim0,xtim9),设置回溯周期长度 nday = account.periodNDay if account.debugMod > 0: xcod = zw.stkLibCode[0] fss = 'tmp\\' + account.prjName + '_' + xcod + '.csv' zw.stkLib[xcod].to_csv(fss) #-------------- #按时间循环,进行回溯测试 for tc in range(0, nday, day): #这里的20用于调仓频率 xtim = account.cal[0 + tc] #每个测试时间点,开始时,清除qx相关参数 account.qxTim0SetVar(xtim) xpriceFlag = False #有效交易标志Flag #按设定的股票代码列表,循环进行回溯测试 Code = [] if len(account.AllACode.index) > len(zw.stkLibCode): Code1 = list(account.AllACode[account.AllACode[xtim] == 1].index) Code2 = zw.stkLibCode Code = [i for i in Code1 if i in Code2] else: Code = list(account.AllACode[account.AllACode[xtim] == 1].index) #选择当天开市的股票 #STcode=list(account.ST[account.ST['secShortName'].str.contains('S')==True].index)#剔除ST股 #Code=[i for i in Code if i not in STcode] account.buylist, account.selllist = account.handle_data(account, Code) print(xtim) for xcod in account.selllist: account.stkCode = str(xcod) #xdatWrk是当前xcod,=stkLib[xcod] #xbarWrk是当前时间点的stkLib[xcod] #注意,已经包括了,qt_init里面的扩充数据列 if account.stkCode in list( account.AllACode[account.AllACode[xtim] == 1].index): account.xbarWrk, account.xdatWrk = xbarGet8TimExt( account.stkCode, account.xtim) if not account.xbarWrk[account.priceWrk].empty: #-----dvix 波动率检查 dvix = stkGetVars(account, 'dvix') dvixFlag = zwt.xinEQ( dvix, account.dvix_k0, account.dvix_k9) or (dvix == 0) or (np.isnan(dvix)) if dvixFlag: xpriceFlag = True # 调用回溯子程序,如果是有效交易,设置成功交易标志xtrdFlag gdufBackTestSonsell(account) else: pass if len(account.xtrdLib['cash']) != 0: account.money = account.xtrdLib['cash'].values[-1] for xcod in account.buylist: account.stkCode = str(xcod) #xdatWrk是当前xcod,=stkLib[xcod] #xbarWrk是当前时间点的stkLib[xcod] #注意,已经包括了,qt_init里面的扩充数据列 account.xbarWrk, account.xdatWrk = xbarGet8TimExt( account.stkCode, account.xtim) if not account.xbarWrk[account.priceWrk].empty: #-----dvix 波动率检查 dvix = stkGetVars(account, 'dvix') dvixFlag = zwt.xinEQ( dvix, account.dvix_k0, account.dvix_k9) or (dvix == 0) or (np.isnan(dvix)) if dvixFlag: xpriceFlag = True # 调用回溯子程序,如果是有效交易,设置成功交易标志xtrdFlag gdufBackTestSonbuy(account) else: pass account.money = account.xtrdLib['cash'].values[-1] securityMinus( account, list(account.xtrdLib['code'][account.xtrdLib['chichangnum'] <= 0][ account.xtrdLib['date'] == xtim])) securityADD( account, list(account.xtrdLib['code'][account.xtrdLib['num'] > 0][ account.xtrdLib['date'] == xtim])) #如果所有股票代码列表循环完毕,成功交易标志为真 #在当前测试时间点终止,设置有关交易参数 if xpriceFlag: account.wrkNDay += 1 account.qxTim9SetVar(account.xtim) print(account.xtrdLib) #交易记录
#----如果是有效交易,加入交易列表 zwx.xtrdLibAdd(qx) elif qx.trdNilFlag: zwx.xtrdLibNilAdd(qx) def zwBackTest(qx):回溯测试主程序 '增加数据源波动率参数:dvix ' '计算回溯时间周期,也可以在此,根据nday调整回溯周期长度。或者在qt_init数据初始化时,通过qx.qxTimSet(xtim0,xtim9),设置回溯周期长度' '按时间循环,进行回溯测试' for tc in range(nday) '每个测试时间点,开始时,清除qx相关参数' '按设定的股票代码列表,循环进行回溯测试' for xcod in zw.stkLibCode: qx.stkCode=xcod qx.xbarWrk = qx.stkLib[xcod][xtim] qx.xdatWrk = qx.stkLib[xcod] if not qx.xbarWrk[qx.priceWrk].empty: dvixFlag=zwt.xinEQ(dvix,qx.dvix_k0,qx.dvix_k9)or(dvix==0)or(np.isnan(dvix)) # np.isnan(dvix)是在考虑缺失值的情况,dvix==0 这个老大估计是搞错了。 if dvixFlag: xpriceFlag=True # 调用回溯子程序,如果是有效交易,设置成功交易标志xtrdFlag zwBackTest100(qx) else: print('@dvix',xcod,xtim,dvix); '如果所有股票代码列表循环完毕,成功交易标志为真' '在当前测试时间点终止,设置有关交易参数' if xpriceFlag: qx.wrkNDay+=1 qx.qxTim9SetVar(qx.xtim); # zwStrategy 策略工具函数