天勤的技术支持,
你好!我是专业版会员用户,现在发现在进行期权回测时;
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()