天勤的技术支持,
你好!我是专业版会员用户,现在发现在进行期权回测时;
1)有时候找不到相应的期权合约, 找不到期权合约就会导致无法下单。查找期权我用的函数是api.query_options()
2)但是用其他工具在模拟交易模式验证期权合约其实是存在的, 注意是在期权模拟交易模式下测试,用的函数也是api.query_options()
3) 发现有问题的数据,如回测到2021年5~6月份时,查询DEC.p2111的所有期权,返回数据实值期权合约、平值期权合约和虚值期权合约都是空的; 但是回测到6月18日后,却又可以查得到了相应的期权合约,且下单也是正常的;
4)程序较为庞大不方便都贴出来;
5)请问是因为5~6月上旬期间,DEC.p2111的期权都还没有生效的原因的,还是其他什么原因?
拜托处理下,谢谢!
a. 这是部分代码:
elif TEST_DESTINATION_OPTIONS == 1: # 如果期权回测模式 # 先处理空单的平仓: 查询该期货所有的待平仓方向期权; 再逐一平仓 ls = api.query_options(SYMBOL, option_class="PUT") numOfOpt = len(ls) for ki in range(0, numOfOpt, 1): #先对空头合约逐个清仓 SYMBOL_OPTION_P = ls[ki] pos_optionP = api.get_position(SYMBOL_OPTION_P) # 这两行是调试代码 if pos_optionP.pos_long > 0: print("pos_long=", pos_optionP.pos_long) if pos_optionP.pos_long != 0: #PUT期权的持仓数参数为pos_long target_pos_optionP = TargetPosTask(api,SYMBOL_OPTION_P) # TargetPosTask 是按照目标持仓手数自动调整 账户持仓中某合约的净持仓的工具 OPERATION_COUNT_P = pos_optionP.pos_long # 应该是pos_long target_pos_optionP.set_target_volume(0) # 设置目标持仓为正数表示多头,负数表示空头,0表示空仓 mytrdlog.AddAndLogOneTradeRecord(mode=1, symbol=SYMBOL_OPTION_P, callput=-1, #空单平仓 direction=2, nlot=OPERATION_COUNT_P, \ price=klines['close'].iloc[-1], time=klines['datetime_dt'].iloc[-1], balance=account["balance"]) #end of for ki in range(0, numOfOpt, 1) #sleep(2) #等待2s等平仓先完成? #再处理做多 #这里不能每次都直接创建一个对象,应先查询有无存在的对象;因为之前可能已经做多买过了. ls = api.query_options(SYMBOL, option_class="CALL") numOfOpt = len(ls) posC_long_total: int = 0 for ki in range(0, numOfOpt, 1): #先对空头合约逐个清仓 SYMBOL_OPTION_C = ls[ki] pos_optionC = api.get_position(SYMBOL_OPTION_C) posC_long_total = posC_long_total+pos_optionC.pos_long #end of for ki in range(0, numOfOpt, 1) #如果已持仓的合约数量未达到目标值,则继续下单; 但不是简单补仓,而是根据当前价格重新找实值step档的合约下单, if posC_long_total < basicInfo.optionCallLotQty[i1]: SYMBOL_OPTION_C = GetTheOptionToOperate(api, SYMBOL, direction="CALL",price=klines['close'].iloc[-1], step=6, mode=1) #debug code #SYMBOL_OPTION_C = "DCE.p2111-C-7200" #for test only if SYMBOL_OPTION_C != "NULL": target_pos_optionC = TargetPosTask(api,SYMBOL_OPTION_C) # TargetPosTask 是按照目标持仓手数自动调整 账户持仓中某合约的净持仓的工具 OPERATION_COUNT_C = basicInfo.optionCallLotQty[i1] - posC_long_total target_pos_optionC.set_target_volume(OPERATION_COUNT_C) # 设置目标持仓为正数表示多头,负数表示空头,0表示空仓 mytrdlog.AddAndLogOneTradeRecord(mode=1, symbol=SYMBOL_OPTION_C, callput=1, #多单开仓 direction=1, nlot=OPERATION_COUNT_C, \ price=klines['close'].iloc[-1], time=klines['datetime_dt'].iloc[-1], balance=account["balance"]) #end of if SYMBOL_OPTION_C != "NULL": else: print("Cannot find related Symbol_Option") #end of if pos_long_total < OPERATION_COUNT_C:
b) 这是查找查找期权合约的函数的代码:
# 计算找出一个对应的最合适的期权合约 # 新方法 # direction: 合约类型, "CALL", "PUT" # price: 行权价 # step: 几档, =0 平值合约; > 0, 实值合约,档位为step; < 0,虚值合约,档位为|step| # mode: 匹配模式: =0, 精确匹配step这一档的合约; =1, 模糊匹配step, 即如果没有step这一档的合约,就尽量找最接近的合约 # 输出结果:self.symOptionCall 或 self.symOptionPut (由direction决定) def GetTheOptionToOperate(api, symbol1, direction: str, price: float, step: int, mode: int): if direction == "CALL": in_money_options, at_money_options, out_of_money_options = \ api.query_all_level_options(symbol1, price, "CALL") else: in_money_options, at_money_options, out_of_money_options = \ api.query_all_level_options(symbol1, price, "PUT") print("symbol=%s, dirt=%s, price=%.1f, step=%d, mode=%d"%(symbol1,direction,price,step, mode)) #print("in money option:") #print(in_money_options) # 实值期权列表 #print("at money option:") #print(at_money_options) # 平值期权列表 #print("out of money option:") #print(out_of_money_options) # 虚值期权列表 if step == 0: #找平值合约 num1 = len(at_money_options) if (num1 == 0): return "NULL" else: return at_money_options[0] elif step > 0: #找实值合约 num1 = len(in_money_options) if num1 == 0: print("No option_symbol available.") return "NULL" if step > num1: #超范围了,返回"NULL" if mode == 0: #精确匹配 return "NULL" elif mode == 1: #模糊匹配 return in_money_options[0] else: return in_money_options[num1 - step] else: # 找虚值合约 step = 0-step num1 = len(out_of_money_options) if num1 == 0: return "NULL" if step > num1: # 超范围了,返回"NULL" if mode == 0: # 精确匹配 return "NULL" elif mode == 1: # 模糊匹配 return out_of_money_options[0] else: return out_of_money_options[num1 - step]
先更新下tqsdk,query函数我记得最新的版本是有回测时的bug修复的,然后如果还有问题你可以加我好友qq532428198
yanfengcun0668 发表新评论 2022年7月8日
感谢李工的大力支持。
查清楚了,DCE.p的期权是个品种,6月18日才上市的,所以6月18日之后才能查询得到相关合约;之前日期查询都是返回空数据。
点个赞!
补充说明:前面表述有误,查询期权用的函数应该是 api.query_all_level_options()