最简单情形的自动对冲
简介
本自动对冲是与策略下单相互独立
,策略下单所需要的下单中保持对冲会集成在策略下单的代码中,本章的自动对冲适用于在未触发策略信号时的额外对冲操作,如果有其他自动交易的策略触发时,应该停止对应的合约的自动对冲操作。
选用近月或次月(可选)离合成期货最近的行权价对应的合成期货对作为对冲合约; 手动填入本次的目标$delta以及可以接受的一个上下范围区间,对冲必须要达到目标$delta一次后才会考虑上下范围; 例子:当前实际$delta为5%,目标$delta为20%,给定的上下容忍范围为10%,那么刚开始对冲的情形下,$delta必须到达一次20%才停止进入等待状态,后续才会判断$delta出了目标$delta20%上下10%去做对冲,也就是低于10%或高于30%.
$vega方面,不同于$delta我们给定的是目标$delta,$vega我们会给一个本次$vega,$vega我们会实时计算从本次对冲开始下的单对应的$vega,该$vega未到设定的本次要做的$vega前我们只用call或者put去做对冲,在该$vega达到本次要做的$vega后我们只会用合成期货去进行对冲;下的单对应的$vega到过一次本次要做的$vega后就再也不考虑$vega这一希腊值了
TODO:追价类型目前是'aT|b|c|M/C'的形式, 后续希望能够有更多的自定义操作,如作为买方时每次以min(对手价+2T, 前一笔+2T)的价格进行追价,待讨论
流程图
GUI代码部分
需要模块 icetcore, loguru
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File : hedger_vanilla.py
@Time : 2023/02/15 20:55:33
@Author : DingWenjie
@Contact : 359582058@qq.com
@Desc : ### 独立自动对冲模块 ###
对冲合约: 平值合成期货
需要输入: 对冲月份: 近月/次月
目标delta: 百分值
目标delta容忍范围: 正百分值
本次对冲vega: 万分值
下单模式: 可选 本方价+1/对手价-1/中间价
相邻单间隔: int,秒
追价模式:
每笔单数: int
### 对冲逻辑 ###
以目标delta为主, 首次对冲(first_time)必须delta达到目标delta,
非首次时delta必须达到目标delta的容忍范围内,
vega则是以本次对冲为准, 不看总仓位的vega, 未达到本次对冲vega时,
只买(卖)不卖(买), 到达本次对冲vega后, 使用合成期货对冲
'''
import warnings
import datetime
import os
from loguru import logger
from tkinter import ttk, Tk, Label, Entry, StringVar, Button
from copy import deepcopy
from icetcore import TCoreAPI, QuoteEvent, TradeEvent, OrderStruct
from functools import partial
from threading import Thread
from time import sleep
now = datetime.datetime.now()
TODAY_STR = datetime.date.today().strftime('%Y%m%d')
if not os.path.exists('log'):
os.mkdir('log')
warnings.simplefilter('ignore')
logger.add(f"log/runtime_{now.strftime('%Y%m%d_%H_%M_%S')}.log")
type_list = ['本方+1', '中间价', '对手-1']
interval_list = ['1秒', '2秒', '3秒', '4秒', '5秒', '6秒',
'7秒', '8秒', '9秒', '10秒', '15秒', '20秒', '30秒']
qty_list = [str(i+1) for i in range(30)]
chase_list = ['1T|1|2|M', '1T|2|2|M', '2T|1|2|M', '2T|2|2|M', '1T|2|10|M']
class APIEvent(TradeEvent, QuoteEvent):
def __init__(self):
super().__init__()
def onconnected(self, apitype: str):
pass
def ondisconnected(self, apitype: str):
pass
def ongreeksreal(self, datatype, symbol, data):
global greeks_dict
try:
greeks_dict[data['Symbol']] = data
except:
return
def onbar(self, datatype, interval, symbol, data, isreal):
pass
def onfilledreportreal(self, data):
global filled_report_dict
temp_key = '.'.join(data['Symbol'].split('.')[
2:4])
if 'A' in temp_key:
temp_key = temp_key[:-1]
filled_report_dict[temp_key][data['Symbol'].split(
'.')[4]][data['DetailReportID']] = data
def onmargin(self, accmask, data):
global cash
global initial_cash
cash = data[0]['MarketPremium']
if not cash:
try:
cash = initial_cash
except NameError:
return
def onATM(self, datatype, symbol, data):
global atm_dict
try:
if data['ATM'] == '.'.join(data['OTM-1C'].split('.')[6:]):
atm_dict['.'.join(data['Symbol'].split('.')[2:5])] = {
'call': data['OTM-1C'],
'put': '.'.join(data['OTM-1C'].split('.')[:5])+'.P.'+data['ATM']
}
else:
atm_dict['.'.join(data['Symbol'].split('.')[2:5])] = {
'put': data['OTM-1P'],
'call': '.'.join(data['OTM-1P'].split('.')[:5])+'.C.'+data['ATM']
}
except:
return
def onpositionmoniter(self, data):
global und_list
global position_dict
try:
und_list
except:
return
try:
position_dict[und_list[0]]
except:
for und in und_list:
position_dict[und] = {
'Total': {'delta': 0, 'vega': 0},
month_list[0]: {'delta': 0, 'vega': 0},
month_list[1]: {'delta': 0, 'vega': 0}
}
for und in und_list:
for position in data:
if und in position['Symbol']:
position_dict[und][position['SubKey']
]['delta'] = position['$Delta']
position_dict[und][position['SubKey']
]['vega'] = position['$Vega']
class HedgerVanilla():
def __init__(self, account, brokerid):
self.account = account
self.brokerid = brokerid
logger.warning(f'当前登录的账户为{self.account},请确认后再继续!')
global cash
global initial_cash
cash = 0
while not cash:
cash = api.getaccmargin(
self.brokerid+'-'+self.account)['MarketPremium']
initial_cash = cash
@staticmethod
def _get_0and1_symbols_and_quote():
'''根据und_list订阅该标的对应的近月次月合约greeks及atm
'''
global und_list
global greeks_dict
global atm_dict
global symbol_dict
global month_list
atm_dict = {}
greeks_dict = {}
symbol_dict = {}
for und in und_list:
all_symbol = api.getallsymbol('OPT', und.split('.')[0])
symbol_dict[und] = all_symbol
month_list = list(set([int(symbol.split('.')[4])
for symbol in all_symbol]))
month_list.sort()
month_list = [str(month) for month in month_list[:2]]
for month in month_list:
api.subATM('TC.O.'+und+'.'+month+'.GET.ATM')
for symbol in all_symbol:
if und in symbol and (month_list[0] in symbol or month_list[1] in symbol):
api.subgreeksreal(symbol)
@staticmethod
def _calculate_cashvega_given_und(und, month):
'''根据已成交的单计算给定标的本次对冲(not vega_done)已做的cashvega
'''
global filled_report_dict
vega = 0
temp_symbol = {}
for order, data in filled_report_dict[und][month].items():
if data['Symbol'] not in temp_symbol:
temp_symbol[data['Symbol']] = int(
(data['Side']*(-2)+3)*data['MatchedQty'])
else:
temp_symbol[data['Symbol']
] += int((data['Side']*(-2)+3)*data['MatchedQty'])
for symbol, data in temp_symbol.items():
try:
vega += data*greeks_dict[symbol]['Vega']*10000
except TypeError:
print(f'data:{data}')
print('vega:', greeks_dict[symbol]['Vega']*10000)
print('\n'*50)
continue
return vega/cash*10000
@staticmethod
def _get_order_given_side_and_type(order, side, type_):
'''根据买卖方向和价格类型给出order_obj
'''
global order_obj
order_obj = deepcopy(order)
order_obj.Side = side
if side == 1:
if type_ == '本方+1':
order_obj.Price = 'BID+1T'
elif type_ == '对手-1':
order_obj.Price = 'ASK-1T'
else:
order_obj.OrderType = 15
order_obj.Synthetic = 1
else:
if type_ == '本方+1':
order_obj.Price = 'ASK-1T'
elif type_ == '对手-1':
order_obj.Price = 'BID+1T'
else:
order_obj.OrderType = 15
order_obj.Synthetic = 1
return order_obj
def _do_hedging_thread(self, und, month):
'''进行对冲子线程
'''
global hedging_state_dict
global filled_report_dict
global done_vega_dict
global atm_dict
global order_type_dict
global order_interval_dict
global order_qty_dict
global chase_type_dict
done_vega_dict[und][month] = 0
logger.debug(f'当前开始{und}_{month}的对冲子线程')
if globals()['delta_entry'].get() == '':
globals()[f'warning_tag_{month}']['text'] = '请输入目标delta!'
logger.debug(f'{und}_{month}对冲子线程因未输入终止')
hedging_state_dict[und][month] = 0
return
target_delta = float(globals()['delta_entry'].get())
if globals()['delta_tol'].get() == '':
globals()[f'warning_tag_{month}']['text'] = '请输入delta范围!'
logger.debug(f'{und}_{month}对冲子线程因未输入终止')
hedging_state_dict[und][month] = 0
return
delta_tol = float(globals()['delta_tol'].get())
if globals()[f'vega_entry_{month}'].get() == '':
globals()[f'warning_tag_{month}']['text'] = '请输入本次vega!'
logger.debug(f'{und}_{month}对冲子线程因未输入终止')
hedging_state_dict[und][month] = 0
return
globals()[f'warning_tag_{month}']['text'] = ''
target_vega = float(globals()[f'vega_entry_{month}'].get())
vega_done = False
first_time = True
delta_direction_for_first_time = 0
filled_report_dict[und][month] = {}
while hedging_state_dict[und][month]:
try:
temp_order_type = order_type_dict[und][month]
temp_order_interval = int(
order_interval_dict[und][month].split('秒')[0])
temp_order_qty = int(order_qty_dict[und][month])
temp_chase_type = chase_type_dict[und][month]
logger.debug(f'当前在{und}_{month}的对冲子线程中')
logger.debug(
f'目标delta为{target_delta}, 容忍范围是{delta_tol}, 要做的vega是{target_vega}, 月份为{month}, 下单间隔为{temp_order_interval}, 每笔手数为{temp_order_qty}, 下单类型为{temp_order_type}')
temp_delta = position_dict[und]['Total']['delta']
logger.debug(
f'当前{month}月份temp_delta为{temp_delta:.0f}, 当前目标delta为{target_delta/100*cash}')
hedger_symbol_call = atm_dict[und+'.'+month]['call']
hedger_symbol_put = atm_dict[und+'.'+month]['put']
if not vega_done: # 之前未做到过vega, 则先判断当前vega是否已到
done_vega_dict[und][month] = self._calculate_cashvega_given_und(
und, month)
logger.info(
f'当前已做的vega为 {done_vega_dict[und][month]: .1f}')
if abs(done_vega_dict[und][month]) >= abs(target_vega):
logger.success('当前首次到达目标vega, 后续做合成期货!')
vega_done = True
if first_time: # 若未到达过目标delta, 则判断所做delta方向(首次)/当前是否到达目标delta
if not delta_direction_for_first_time:
if temp_delta > target_delta/100*cash >= 0 or (temp_delta > target_delta/100*cash and 0 >= target_delta):
delta_direction_for_first_time = -1
else:
delta_direction_for_first_time = 1
logger.debug(
f'初次对冲, 判断对冲方向为{delta_direction_for_first_time}')
elif (temp_delta-target_delta/100*cash)*delta_direction_for_first_time > 0:
logger.info(
f'当前first_time,当前delta与目标delta之差为{temp_delta-target_delta/100*cash}')
first_time = False
continue
order_obj = OrderStruct(Account=self.account,
BrokerID=self.brokerid,
OrderQty=temp_order_qty,
OrderType=2, # 默认限价单
Symbol='',
Side=1,
TimeInForce=1,
PositionEffect=4,
SelfTradePrevention=3,
ChasePrice=temp_chase_type)
if (first_time and temp_delta < target_delta/100*cash) or (not first_time and temp_delta < (target_delta-delta_tol)/100*cash): # 做正delta
logger.info('判断本次做正delta')
if not vega_done: # 买call or 卖put
if target_vega > 0: # 买call
order = self._get_order_given_side_and_type(
order=order_obj, side=1, type_=temp_order_type)
order.Symbol = hedger_symbol_call
else: # 卖put
order = self._get_order_given_side_and_type(
order=order_obj, side=2, type_=temp_order_type)
order.Symbol = hedger_symbol_put
order_response, _ = api.neworder(order)
else: # 买合成期货
order_call = self._get_order_given_side_and_type(
order=order_obj, side=1, type_=temp_order_type)
order_call.Symbol = hedger_symbol_call
order_put = self._get_order_given_side_and_type(
order=order_obj, side=2, type_=temp_order_type)
order_put.Symbol = hedger_symbol_put
order_response_call, _ = api.neworder(order_call)
order_response_put, _ = api.neworder(order_put)
elif (first_time and temp_delta > target_delta/100*cash) or (not first_time and temp_delta > (target_delta+delta_tol)/100*cash): # 做负delta
logger.info('判断本次做负delta')
if not vega_done: # 卖call or 买put
if target_vega < 0: # 卖call
order = self._get_order_given_side_and_type(
order=order_obj, side=2, type_=temp_order_type)
order.Symbol = hedger_symbol_call
else: # 买put
order = self._get_order_given_side_and_type(
order=order_obj, side=1, type_=temp_order_type)
order.Symbol = hedger_symbol_put
order_response, _ = api.neworder(order)
else: # 卖合成期货
order_call = self._get_order_given_side_and_type(
order=order_obj, side=2, type_=temp_order_type)
order_call.Symbol = hedger_symbol_call
order_put = self._get_order_given_side_and_type(
order=order_obj, side=1, type_=temp_order_type)
order_put.Symbol = hedger_symbol_put
order_response_call, _ = api.neworder(order_call)
order_response_put, _ = api.neworder(order_put)
else:
logger.debug('当前delta满足要求, 不做对冲')
sleep(temp_order_interval)
except Exception as error:
logger.exception(error)
hedging_state_dict[und][month] = 0
logger.success(f'{und}对冲子线程已结束!')
filled_report_dict[und][month] = {}
done_vega_dict[und][month] = '-'
def _do_hedging(self, month):
'''tk.Button绑定开始对冲按键
'''
global hedging_state_dict
if hedging_state_dict[csd_und][month]:
logger.warning(f'{csd_und}_{month}已在对冲中')
return
global target_delta_dict
global target_delta_tol_dict
global target_vega_dict
global order_type_dict
global order_interval_dict
global order_qty_dict
global chase_type_dict
target_delta_dict[csd_und] = globals()['delta_entry'].get()
target_delta_tol_dict[csd_und] = globals()['delta_tol'].get()
target_vega_dict[csd_und][month] = globals()[
f'vega_entry_{month}'].get()
order_type_dict[csd_und][month] = globals(
)[f'csd_order_type_{month}'].get()
order_interval_dict[csd_und][month] = globals(
)[f'csd_order_interval_{month}'].get()
order_qty_dict[csd_und][month] = globals(
)[f'csd_order_qty_{month}'].get()
chase_type_dict[csd_und][month] = globals(
)[f'csd_chase_type_{month}'].get()
logger.debug(f'开始对冲{csd_und}-{month}')
hedging_state_dict[csd_und][month] = 1
globals()[f'hedging_subprocess_{csd_und}_{month}'] = Thread(
target=self._do_hedging_thread, args=(csd_und, month), daemon=True)
globals()[f'hedging_subprocess_{csd_und}_{month}'].start()
def _stop_hedging(self, month):
'''tk.Button绑定停止对冲按键
'''
global hedging_state_dict
if not hedging_state_dict[csd_und][month]:
logger.warning(f'{csd_und}_{month}未在对冲')
return
global target_delta_dict
global target_delta_tol_dict
global target_vega_dict
target_delta_dict[csd_und] = ''
target_delta_tol_dict[csd_und] = ''
target_vega_dict[csd_und][month] = ''
hedging_state_dict[csd_und][month] = 0
logger.debug(f'停止对冲{csd_und}_{month}')
def main_window(self):
'''GUI窗口
'''
def go(*args):
pass
global position_dict
global und_list
global month_list
global hedging_state_dict
global hedging_state_list
global done_vega_dict
global filled_report_dict
global order_report_dict
global csd_und
global target_delta_dict
global target_vega_dict
global target_delta_tol_dict
global order_type_dict
global order_interval_dict
global order_qty_dict
global chase_type_dict
chase_type_dict = {}
order_qty_dict = {}
order_interval_dict = {}
order_type_dict = {}
target_delta_tol_dict = {}
target_vega_dict = {}
target_delta_dict = {}
csd_und = und_list[0]
order_report_dict = {}
filled_report_dict = {}
done_vega_dict = {}
hedging_state_list = ['未运行', '对冲中']
hedging_state_dict = {}
position_dict = {}
self._get_0and1_symbols_and_quote()
sleep(3)
window = Tk()
window.title('ETF期权自动对冲初版')
account_tag = Label(text='当前账户:')
account_tag.grid(row=0, column=0)
account_tag_ = Label(text=self.account)
account_tag_.grid(row=0, column=1)
cash_tag = Label(text='当前资金:')
cash_tag.grid(row=1, column=0)
cash_tag_ = Label(text=f'{cash:.2f}')
cash_tag_.grid(row=1, column=1)
for i, und in enumerate(und_list):
order_report_dict[und] = {}
done_vega_dict[und] = {
month_list[0]: '',
month_list[1]: ''
}
hedging_state_dict[und] = {
month_list[0]: 0,
month_list[1]: 0
}
filled_report_dict[und] = {
month_list[0]: {},
month_list[1]: {}
}
target_delta_dict[und] = ''
target_delta_tol_dict[und] = ''
target_vega_dict[und] = {
month_list[0]: '',
month_list[1]: ''
}
order_type_dict[und] = {
month_list[0]: 1,
month_list[1]: 1
}
order_interval_dict[und] = {
month_list[0]: 1,
month_list[1]: 1,
}
order_qty_dict[und] = {
month_list[0]: 1,
month_list[1]: 1,
}
chase_type_dict[und] = {
month_list[0]: 0,
month_list[1]: 0,
}
crt_row = 2
text_tag = Label(text='当前总体$delta(百分之):')
text_tag.grid(row=crt_row, column=0)
try:
globals()['crt_delta_total'] = Label(
text=str(round(position_dict[csd_und]['Total']['delta']/cash*100, 1)), width=9)
except KeyError:
globals()['crt_delta_total'] = Label(
text=str('-'), width=8)
globals()['crt_delta_total'].grid(row=crt_row, column=1)
text_tag = Label(text='', width=8)
text_tag.grid(row=crt_row, column=2)
crt_row += 1
crt_vega = Label(text='当前总体$vega(万分之):')
crt_vega.grid(row=crt_row, column=0)
try:
globals()['crt_vega_total'] = Label(
text=str(round(position_dict[csd_und]['Total']['vega']/cash*10000, 1)), width=9)
except KeyError:
globals()['crt_vega_total'] = Label(
text=str('-'), width=8)
globals()['crt_vega_total'].grid(row=crt_row, column=1)
crt_row += 1
def choose_und(*args):
global csd_und
global target_delta_dict
global target_delta_tol_dict
global target_vega_dict
global order_type_dict
global order_interval_dict
global order_qty_dict
global chase_type_dict
csd_und = globals()['choose_csd_und'].get()
globals()['delta_entry'].delete(0, 5)
globals()['delta_entry'].insert(0, str(target_delta_dict[csd_und]))
globals()['delta_tol'].delete(0, 5)
globals()['delta_tol'].insert(
0, str(target_delta_tol_dict[csd_und]))
for month in month_list:
globals()[f'vega_entry_{month}'].delete(0, 5)
globals()[f'vega_entry_{month}'].insert(
0, str(target_vega_dict[csd_und][month]))
if hedging_state_dict[csd_und][month]:
globals()[f'csd_order_type_{month}'].current(
type_list.index(order_type_dict[csd_und][month]))
globals()[f'csd_order_interval_{month}'].current(
interval_list.index(order_interval_dict[csd_und][month]))
globals()[f'csd_order_qty_{month}'].current(
qty_list.index(order_qty_dict[csd_und][month]))
globals()[f'csd_chase_type_{month}'].current(
chase_list.index(chase_type_dict[csd_und][month]))
text_tag = Label(text='选择对冲合约:')
text_tag.grid(row=crt_row, column=0)
globals()['choose_csd_und'] = ttk.Combobox(
window, textvariable=StringVar(), width=11)
globals()['choose_csd_und']['values'] = und_list
globals()['choose_csd_und'].current(0)
globals()['choose_csd_und'].bind('<<ComboboxSelected>>', choose_und)
globals()['choose_csd_und'].grid(row=crt_row, column=1)
crt_row += 1
text_tag = Label(text='')
text_tag.grid(row=crt_row, column=0)
crt_row += 1
text_tag = Label(text='对冲设置')
text_tag.grid(row=crt_row, column=0)
fixed_row_num = crt_row
col_num = 4
for i, month in enumerate(month_list):
crt_row = fixed_row_num
text_tag = Label(text='考虑月份')
text_tag.grid(row=crt_row, column=i*col_num)
text_tag = Label(text=month, fg='red')
text_tag.grid(row=crt_row, column=i*col_num+1)
crt_row += 1
text_tag = Label(text='该月$delta(百分之):')
text_tag.grid(row=crt_row, column=i*col_num)
try:
globals()[f'crt_delta_{month}'] = Label(
text=str(round(position_dict[csd_und][month]['delta']/cash*100, 1)), width=9)
except KeyError:
globals()[f'crt_delta_{month}'] = Label(
text=str('-'), width=8)
globals()[f'crt_delta_{month}'].grid(
row=crt_row, column=1+i*col_num)
text_tag = Label(text='', width=8)
text_tag.grid(row=crt_row, column=2+i*col_num)
crt_row += 1
crt_vega = Label(text='该月$vega(万分之):')
crt_vega.grid(row=crt_row, column=i*col_num)
try:
globals()[f'crt_vega_{month}'] = Label(
text=str(round(position_dict[csd_und][month]['vega']/cash*10000, 1)), width=9)
except KeyError:
globals()[f'crt_vega_{month}'] = Label(
text=str('-'), width=8)
globals()[f'crt_vega_{month}'].grid(
row=crt_row, column=1+i*col_num)
crt_row += 1
globals()[f'warning_tag_{month}'] = Label(text='', fg='red')
globals()[f'warning_tag_{month}'].grid(
row=crt_row, column=1+i*col_num)
crt_row += 1
if not i:
text_tag = Label(text='目标总delta(百分之):')
text_tag.grid(row=crt_row, column=i*col_num)
globals()['delta_entry'] = Entry(window, width=10)
globals()['delta_entry'].grid(
row=crt_row, column=1+i*col_num)
crt_row += 1
if not i:
text_tag = Label(text='delta范围(百分之):')
text_tag.grid(row=crt_row, column=i*col_num)
globals()['delta_tol'] = Entry(window, width=10)
globals()['delta_tol'].grid(
row=crt_row, column=1+i*col_num)
crt_row += 1
text_tag = Label(text='本次vega(万分之):')
text_tag.grid(row=crt_row, column=i*col_num)
globals()[f'vega_entry_{month}'] = Entry(window, width=10)
globals()[f'vega_entry_{month}'].grid(
row=crt_row, column=1+i*col_num)
crt_row += 1
text_tag = Label(text='选择对冲下单模式:')
text_tag.grid(row=crt_row, column=i*col_num)
globals()[f'csd_order_type_{month}'] = ttk.Combobox(
window, textvariable=StringVar(), width=7)
globals()[f'csd_order_type_{month}']['values'] = type_list
globals()[f'csd_order_type_{month}'].current(0)
globals()[f'csd_order_type_{month}'].bind(
'<<ComboboxSelected>>', go)
globals()[f'csd_order_type_{month}'].grid(
row=crt_row, column=1+i*col_num)
crt_row += 1
text_tag = Label(text='选择下单相邻间隔:')
text_tag.grid(row=crt_row, column=i*col_num)
globals()[f'csd_order_interval_{month}'] = ttk.Combobox(
window, textvariable=StringVar(), width=7)
globals()[f'csd_order_interval_{month}']['values'] = interval_list
globals()[f'csd_order_interval_{month}'].current(1)
globals()[f'csd_order_interval_{month}'].bind(
'<<ComboboxSelected>>', go)
globals()[f'csd_order_interval_{month}'].grid(
row=crt_row, column=1+i*col_num)
crt_row += 1
text_tag = Label(text='对冲每笔下单单数:')
text_tag.grid(row=crt_row, column=i*col_num)
globals()[f'csd_order_qty_{month}'] = ttk.Combobox(
window, textvariable=StringVar(), width=7)
globals()[f'csd_order_qty_{month}']['values'] = qty_list
globals()[f'csd_order_qty_{month}'].current(0)
globals()[f'csd_order_qty_{month}'].bind(
'<<ComboboxSelected>>', go)
globals()[f'csd_order_qty_{month}'].grid(
row=crt_row, column=1+i*col_num)
crt_row += 1
text_tag = Label(text='选择对冲追价方式:')
text_tag.grid(row=crt_row, column=i*col_num)
globals()[f'csd_chase_type_{month}'] = ttk.Combobox(
window, textvariable=StringVar(), width=7)
globals()[f'csd_chase_type_{month}']['values'] = chase_list
globals()[f'csd_chase_type_{month}'].current(3)
globals()[f'csd_chase_type_{month}'].bind(
'<<ComboboxSelected>>', go)
globals()[f'csd_chase_type_{month}'].grid(
row=crt_row, column=1+i*col_num)
crt_row += 1
text_tag = Label(text='')
text_tag.grid(row=crt_row, column=i*col_num)
crt_row += 1
text_tag = Label(text='当前对冲状态:')
text_tag.grid(row=crt_row, column=i*col_num)
globals()[f'hedging_state_{month}'] = Label(
text=hedging_state_list[hedging_state_dict[und][month]], fg='red')
globals()[f'hedging_state_{month}'].grid(
row=crt_row, column=1+i*col_num)
crt_row += 1
text_tag = Label(text='当前已做vega:')
text_tag.grid(row=crt_row, column=i*col_num)
globals()[f'done_vega_{month}'] = Label(text='0')
globals()[f'done_vega_{month}'].grid(
row=crt_row, column=1+i*col_num)
crt_row += 1
Button(window, text="开始对冲", width=10, command=partial(
self._do_hedging, month)).grid(row=crt_row, column=i*col_num, padx=1, pady=1)
crt_row += 1
Button(window, text="停止对冲", width=10, command=partial(
self._stop_hedging, month)).grid(row=crt_row, column=i*col_num, padx=1, pady=1)
crt_row += 1
text_tag = Label(text='')
text_tag.grid(row=crt_row, column=0)
crt_row += 1
text_tag = Label(text='注意事项:', fg='red')
text_tag.grid(row=crt_row, column=0)
crt_row += 1
text_tag = Label(
text='目标delta, delta范围, 本次vega三个输出栏不可在对冲中进行更改!(待更改)', fg='red')
text_tag.grid(row=crt_row, column=0, columnspan=6)
crt_row += 1
text_tag = Label(
text='追价方式参数为"递增tick|追几次|每次几秒|M"', fg='red')
text_tag.grid(row=crt_row, column=0, columnspan=5)
def update():
while True:
sleep(0.5)
cash_tag_['text'] = f'{cash:.2f}'
try:
globals()['crt_delta_total']['text'] = str(
round(position_dict[csd_und]['Total']['delta']/cash*100, 1))
except KeyError:
globals()['crt_delta_total']['text'] = str('-')
try:
globals()['crt_vega_total']['text'] = str(
round(position_dict[csd_und]['Total']['vega']/cash*10000, 1))
except KeyError:
globals()['crt_vega_total']['text'] = str('-')
for month in month_list:
try:
globals()[f'crt_delta_{month}']['text'] = str(
round(position_dict[csd_und][month]['delta']/cash*100, 1))
except KeyError:
globals()[f'crt_delta_{month}']['text'] = str('-')
try:
globals()[f'crt_vega_{month}']['text'] = str(
round(position_dict[csd_und][month]['vega']/cash*10000, 1))
except KeyError:
globals()[f'crt_vega_{month}']['text'] = str('-')
globals()[
f'hedging_state_{month}']['text'] = hedging_state_list[hedging_state_dict[csd_und][month]]
try:
globals()[f'done_vega_{month}']['text'] = str(
round(done_vega_dict[csd_und][month], 1))
except TypeError:
globals()[f'done_vega_{month}']['text'] = '-'
if hedging_state_dict[csd_und][month]:
order_type_dict[csd_und][month] = globals(
)[f'csd_order_type_{month}'].get()
order_interval_dict[csd_und][month] = globals(
)[f'csd_order_interval_{month}'].get()
order_qty_dict[csd_und][month] = globals(
)[f'csd_order_qty_{month}'].get()
chase_type_dict[csd_und][month] = globals(
)[f'csd_chase_type_{month}'].get()
def monitor(window):
window.after(100, update())
update_thread = Thread(
target=update, daemon=True, name='update_thread')
monitor_thread = Thread(
target=monitor, args=(window), daemon=True, name='monitor_thread')
update_thread.start()
monitor_thread.start()
window.mainloop()
if __name__ == '__main__':
api = TCoreAPI(APIEvent)
re = api.connect()
account_info = api.getaccountlist()
account = account_info[0]['Account']
brokerid = account_info[0]['BrokerID']
global und_list
und_list = ['SSE.510050', 'SSE.510300', 'SSE.510500', 'SZSE.159915']
hedger = HedgerVanilla(account=account, brokerid=brokerid)
hedger.main_window()