#!/usr/bin/env python

coding:utf-8

from PoboAPI import *
import datetime
import math
from copy import deepcopy

从期权列表中移除A期权

def RemoveAoptionInList(oplist):
del_list = []
for i in range(len(oplist)):
op = oplist[i]
info = GetContractInfo(op)
if info['合约乘数'] != 10000:
del_list.append(i)
del_list.sort(reverse=True)
for i in del_list:
del oplist[i]
return oplist

获取深度实值期权

def GetDeepITMOptions(call_oplist, put_oplist):
call_oplist.sort(key=lambda x: GetContractInfo(x)['行权价格'])
put_oplist.sort(key=lambda x: GetContractInfo(x)['行权价格'], reverse=True)
return call_oplist[0], put_oplist[0]

开始时间,用于初始化一些参数

def OnStart(context):
print("I'm starting...")
# 设置全局变量,作为是否已经平仓的标志
g.close = True
# 设置德尔塔中性阈值
g.delta_threshold = 0.01
# 获取当前期权的到期日列表
last = GetOptionsLastDates('510050.SHSE')
# 获取最远期到期日的期权列表
farthest_expiry = last[-1]
call_oplist = GetOptionContracts('510050.SHSE', farthest_expiry, 0)
put_oplist = GetOptionContracts('510050.SHSE', farthest_expiry, 1)
call_oplist = RemoveAoptionInList(call_oplist)
put_oplist = RemoveAoptionInList(put_oplist)
g.call_option, g.put_option = GetDeepITMOptions(call_oplist, put_oplist)
g.code = [g.call_option, g.put_option]
print("当前套利期权组合初始化为" + str(g.code))
SubscribeQuote(g.code[0])
SubscribeQuote(g.code[1])
# 登录期权账号
if "回测期权" in context.accounts:
print("登录交易账号 回测期权")
if context.accounts["回测期权"].Login():
context.myacc = context.accounts["回测期权"]

def OnMarketQuotationInitialEx(context, exchange, daynight):
if exchange == 'SHSE' and g.close == True:
last = GetOptionsLastDates('510050.SHSE')
farthest_expiry = last[-1]
call_oplist = GetOptionContracts('510050.SHSE', farthest_expiry, 0)
put_oplist = GetOptionContracts('510050.SHSE', farthest_expiry, 1)
call_oplist = RemoveAoptionInList(call_oplist)
put_oplist = RemoveAoptionInList(put_oplist)
UnsubscribeQuote(g.code)
g.call_option, g.put_option = GetDeepITMOptions(call_oplist, put_oplist)
g.code = [g.call_option, g.put_option]
SubscribeQuote(g.code[0])
SubscribeQuote(g.code[1])
print("当前套利期权组合重置为" + str(g.code))

实时行情事件

def OnQuote(context, code):
print("调用到OnQuote事件")
# 获取期权组合的最新价
C = GetQuote(g.call_option).now
P = GetQuote(g.put_option).now
# 获取期权组合的德尔塔
call_delta = GetOptionGreeks(g.call_option).delta
put_delta = GetOptionGreeks(g.put_option).delta
total_delta = call_delta + put_delta # 跨式组合的总德尔塔
print("当前德尔塔为:" + str(total_delta))

# 保持德尔塔中性
if abs(total_delta) > g.delta_threshold:
# 平掉绝对值较大的合约1手
if abs(call_delta) > abs(put_delta):
QuickInsertOrder(context.myacc, g.call_option, 'sell', 'close', PriceType(PbPriceType.Limit), 1)
else:
QuickInsertOrder(context.myacc, g.put_option, 'sell', 'close', PriceType(PbPriceType.Limit), 1)

# 更新德尔塔值
call_delta = GetOptionGreeks(g.call_option).delta
put_delta = GetOptionGreeks(g.put_option).delta
total_delta = call_delta + put_delta
print("调整后的德尔塔为:" + str(total_delta))

# 再次检查是否满足调整条件,如果满足则开仓绝对值较小的合约1手
if abs(total_delta) > g.delta_threshold:
if abs(call_delta) < abs(put_delta):
QuickInsertOrder(context.myacc, g.call_option, 'buy', 'open', PriceType(PbPriceType.Limit), 1)
else:
QuickInsertOrder(context.myacc, g.put_option, 'buy', 'open', PriceType(PbPriceType.Limit), 1)
print("再次调整德尔塔完成")

# 移到新合约
last = GetOptionsLastDates('510050.SHSE')
farthest_expiry = last[-1]
if GetContractInfo(g.call_option)['行权到期日'] != farthest_expiry:
print("切换到新合约")
call_oplist = GetOptionContracts('510050.SHSE', farthest_expiry, 0)
put_oplist = GetOptionContracts('510050.SHSE', farthest_expiry, 1)
call_oplist = RemoveAoptionInList(call_oplist)
put_oplist = RemoveAoptionInList(put_oplist)
g.call_option, g.put_option = GetDeepITMOptions(call_oplist, put_oplist)
g.code = [g.call_option, g.put_option]
SubscribeQuote(g.code[0])
SubscribeQuote(g.code[1])
print("新合约套利期权组合为" + str(g.code))