|
@@ -136,6 +136,7 @@ class Strategy:
|
|
|
logger.addHandler(handler)
|
|
logger.addHandler(handler)
|
|
|
return logger
|
|
return logger
|
|
|
|
|
|
|
|
|
|
+ # TODO 目前看来是开仓前的一些准备,对本地数据状态进行更新
|
|
|
# @utils.timeit
|
|
# @utils.timeit
|
|
|
def _update_data(self, data:model.TraderMsg):
|
|
def _update_data(self, data:model.TraderMsg):
|
|
|
'''更新本地数据'''
|
|
'''更新本地数据'''
|
|
@@ -151,7 +152,8 @@ class Strategy:
|
|
|
if self.pos.shortPos != data.position.shortPos:
|
|
if self.pos.shortPos != data.position.shortPos:
|
|
|
self.pos.shortPos = data.position.shortPos
|
|
self.pos.shortPos = data.position.shortPos
|
|
|
self.pos.shortAvg = data.position.shortAvg
|
|
self.pos.shortAvg = data.position.shortAvg
|
|
|
- # bp ap
|
|
|
|
|
|
|
+ # TODO data.market里面是组合盘口信息,所以此处的bp和ap都是从组合盘口里拿出来的
|
|
|
|
|
+ # bp ap
|
|
|
self.bp = data.market[utils.BP_INDEX]
|
|
self.bp = data.market[utils.BP_INDEX]
|
|
|
self.ap = data.market[utils.AP_INDEX]
|
|
self.ap = data.market[utils.AP_INDEX]
|
|
|
# trade mp
|
|
# trade mp
|
|
@@ -170,6 +172,8 @@ class Strategy:
|
|
|
########### 当前持仓价值 ###########
|
|
########### 当前持仓价值 ###########
|
|
|
self.long_hold_value = self.pos.longPos * self.mp
|
|
self.long_hold_value = self.pos.longPos * self.mp
|
|
|
self.short_hold_value = self.pos.shortPos * self.mp
|
|
self.short_hold_value = self.pos.shortPos * self.mp
|
|
|
|
|
+
|
|
|
|
|
+ # TODO 177-186计算单边最大持仓数量
|
|
|
########### 现货 ###########
|
|
########### 现货 ###########
|
|
|
if 'spot' in self.exchange:
|
|
if 'spot' in self.exchange:
|
|
|
### 计算总保证金情况
|
|
### 计算总保证金情况
|
|
@@ -180,11 +184,14 @@ class Strategy:
|
|
|
### 计算总保证金情况
|
|
### 计算总保证金情况
|
|
|
self.max_long_value = self.equity * self.leverrate * self.adjust_leverrate
|
|
self.max_long_value = self.equity * self.leverrate * self.adjust_leverrate
|
|
|
self.max_short_value = self.max_long_value
|
|
self.max_short_value = self.max_long_value
|
|
|
|
|
+
|
|
|
|
|
+ # TODO 做市模式识别
|
|
|
###### maker mode ######
|
|
###### maker mode ######
|
|
|
if self.ref_name[self.ref_index] == self.trade_name:
|
|
if self.ref_name[self.ref_index] == self.trade_name:
|
|
|
self.maker_mode = 'free'
|
|
self.maker_mode = 'free'
|
|
|
else:
|
|
else:
|
|
|
self.maker_mode = 'follow'
|
|
self.maker_mode = 'follow'
|
|
|
|
|
+
|
|
|
###### ref price ######
|
|
###### ref price ######
|
|
|
if data.ref_price == None:
|
|
if data.ref_price == None:
|
|
|
self.ref_bp = self.bp
|
|
self.ref_bp = self.bp
|
|
@@ -194,12 +201,14 @@ class Strategy:
|
|
|
self.ref_bp = data.ref_price[self.ref_index][0]
|
|
self.ref_bp = data.ref_price[self.ref_index][0]
|
|
|
self.ref_ap = data.ref_price[self.ref_index][1]
|
|
self.ref_ap = data.ref_price[self.ref_index][1]
|
|
|
self.ref_price = (self.ref_bp+self.ref_ap)*0.5
|
|
self.ref_price = (self.ref_bp+self.ref_ap)*0.5
|
|
|
|
|
+
|
|
|
# spread
|
|
# spread
|
|
|
self.predict = utils.clip(data.predict*self.predict_alpha, -self.trade_open_dist, self.trade_open_dist)
|
|
self.predict = utils.clip(data.predict*self.predict_alpha, -self.trade_open_dist, self.trade_open_dist)
|
|
|
# is base spread normal ? can take but can't move too far
|
|
# is base spread normal ? can take but can't move too far
|
|
|
# if abs(self.ref_price - self.mp)/self.mp > self.trade_open_dist*3:
|
|
# if abs(self.ref_price - self.mp)/self.mp > self.trade_open_dist*3:
|
|
|
# back to pure market making strategy
|
|
# back to pure market making strategy
|
|
|
# self.ref_price = self.mp
|
|
# self.ref_price = self.mp
|
|
|
|
|
+
|
|
|
# equity 当前账户可用cash和coin
|
|
# equity 当前账户可用cash和coin
|
|
|
self.coin = data.coin
|
|
self.coin = data.coin
|
|
|
self.cash = data.cash
|
|
self.cash = data.cash
|
|
@@ -383,24 +392,24 @@ class Strategy:
|
|
|
pkAmount = 0.0
|
|
pkAmount = 0.0
|
|
|
pkOrderNum = 0
|
|
pkOrderNum = 0
|
|
|
# 计算
|
|
# 计算
|
|
|
- cond1 = self.close_dist[0]
|
|
|
|
|
- cond2 = self.close_dist[1]
|
|
|
|
|
- cond3 = self.close_dist[2]
|
|
|
|
|
- cond4 = self.close_dist[3]
|
|
|
|
|
|
|
+ long_upper = self.close_dist[0]
|
|
|
|
|
+ long_lower = self.close_dist[1]
|
|
|
|
|
+ short_lower = self.close_dist[2]
|
|
|
|
|
+ short_upper = self.close_dist[3]
|
|
|
# # 获取当前挂单
|
|
# # 获取当前挂单
|
|
|
for cid in self.local_orders:
|
|
for cid in self.local_orders:
|
|
|
i = self.local_orders[cid]
|
|
i = self.local_orders[cid]
|
|
|
if i['side'] == 'pk':
|
|
if i['side'] == 'pk':
|
|
|
- c1 = i['price'] > cond1
|
|
|
|
|
- c2 = i['price'] < cond2
|
|
|
|
|
|
|
+ c1 = i['price'] > long_upper
|
|
|
|
|
+ c2 = i['price'] < long_lower
|
|
|
if c1 or c2:
|
|
if c1 or c2:
|
|
|
signals[f'Cancel{cid}'] = [i['client_id'], i['order_id']]
|
|
signals[f'Cancel{cid}'] = [i['client_id'], i['order_id']]
|
|
|
# else:
|
|
# else:
|
|
|
pkAmount += i['amount']
|
|
pkAmount += i['amount']
|
|
|
pkOrderNum += 1
|
|
pkOrderNum += 1
|
|
|
elif i['side'] == 'pd':
|
|
elif i['side'] == 'pd':
|
|
|
- c1 = i['price'] < cond3
|
|
|
|
|
- c2 = i['price'] > cond4
|
|
|
|
|
|
|
+ c1 = i['price'] < short_lower
|
|
|
|
|
+ c2 = i['price'] > short_upper
|
|
|
if c1 or c2:
|
|
if c1 or c2:
|
|
|
signals[f'Cancel{cid}'] = [i['client_id'], i['order_id']]
|
|
signals[f'Cancel{cid}'] = [i['client_id'], i['order_id']]
|
|
|
# else:
|
|
# else:
|
|
@@ -420,7 +429,7 @@ class Strategy:
|
|
|
### 需要平多的价值大于最小交易价值 执行平多逻辑
|
|
### 需要平多的价值大于最小交易价值 执行平多逻辑
|
|
|
if self.pos.longPos * self.mp > self._min_amount_value:
|
|
if self.pos.longPos * self.mp > self._min_amount_value:
|
|
|
if pdOrderNum == 0: # 需要更新平仓挂单
|
|
if pdOrderNum == 0: # 需要更新平仓挂单
|
|
|
- price = (cond3 + cond4)*0.5
|
|
|
|
|
|
|
+ price = (short_lower + short_upper)*0.5
|
|
|
price = utils.clip(price, self.bp*0.9995, self.ap*1.03)
|
|
price = utils.clip(price, self.bp*0.9995, self.ap*1.03)
|
|
|
price = utils.fix_price(price, self.tickSize)
|
|
price = utils.fix_price(price, self.tickSize)
|
|
|
amount = self.pos.longPos
|
|
amount = self.pos.longPos
|
|
@@ -434,7 +443,7 @@ class Strategy:
|
|
|
])
|
|
])
|
|
|
if self.pos.shortPos > self._min_amount_value:
|
|
if self.pos.shortPos > self._min_amount_value:
|
|
|
if pkOrderNum == 0: # 需要更新平仓挂单
|
|
if pkOrderNum == 0: # 需要更新平仓挂单
|
|
|
- price = (cond1 + cond2)*0.5
|
|
|
|
|
|
|
+ price = (long_upper + long_lower)*0.5
|
|
|
price = utils.clip(price, self.bp*0.97, self.ap*1.0005)
|
|
price = utils.clip(price, self.bp*0.97, self.ap*1.0005)
|
|
|
price = utils.fix_price(price, self.tickSize)
|
|
price = utils.fix_price(price, self.tickSize)
|
|
|
amount = self.pos.shortPos
|
|
amount = self.pos.shortPos
|
|
@@ -449,7 +458,7 @@ class Strategy:
|
|
|
else:
|
|
else:
|
|
|
if self.pos.longPos > 0.0: # 正常平多
|
|
if self.pos.longPos > 0.0: # 正常平多
|
|
|
if pdOrderNum == 0: # 需要更新平仓挂单
|
|
if pdOrderNum == 0: # 需要更新平仓挂单
|
|
|
- price = cond3*0.5 + cond4*0.5
|
|
|
|
|
|
|
+ price = short_lower*0.5 + short_upper*0.5
|
|
|
price = utils.clip(price, self.bp*0.9995, self.ap*1.03)
|
|
price = utils.clip(price, self.bp*0.9995, self.ap*1.03)
|
|
|
price = utils.fix_price(price, self.tickSize)
|
|
price = utils.fix_price(price, self.tickSize)
|
|
|
signals['Limits_close'].append([
|
|
signals['Limits_close'].append([
|
|
@@ -460,7 +469,7 @@ class Strategy:
|
|
|
])
|
|
])
|
|
|
if self.pos.shortPos > 0.0: # 正常平空
|
|
if self.pos.shortPos > 0.0: # 正常平空
|
|
|
if pkOrderNum == 0: # 需要更新平仓挂单
|
|
if pkOrderNum == 0: # 需要更新平仓挂单
|
|
|
- price = cond1*0.5 + cond2*0.5
|
|
|
|
|
|
|
+ price = long_upper*0.5 + long_lower*0.5
|
|
|
price = utils.clip(price, self.bp*0.97, self.ap*1.0005)
|
|
price = utils.clip(price, self.bp*0.97, self.ap*1.0005)
|
|
|
price = utils.fix_price(price, self.tickSize)
|
|
price = utils.fix_price(price, self.tickSize)
|
|
|
signals['Limits_close'].append([
|
|
signals['Limits_close'].append([
|
|
@@ -478,26 +487,28 @@ class Strategy:
|
|
|
# 准备命令
|
|
# 准备命令
|
|
|
signals = dict()
|
|
signals = dict()
|
|
|
# 计算挂单范围
|
|
# 计算挂单范围
|
|
|
- cond1 = self.open_dist[0]
|
|
|
|
|
- cond2 = self.open_dist[1]
|
|
|
|
|
- cond3 = self.open_dist[2]
|
|
|
|
|
- cond4 = self.open_dist[3]
|
|
|
|
|
|
|
+ long_upper = self.open_dist[0] # long upper--------高风险
|
|
|
|
|
+ long_lower = self.open_dist[1] # long lower--------低风险
|
|
|
|
|
+ short_lower = self.open_dist[2] # short lower------高风险
|
|
|
|
|
+ short_upper = self.open_dist[3] # short upper------低风险
|
|
|
# # 获取当前挂单
|
|
# # 获取当前挂单
|
|
|
for cid in self.local_orders:
|
|
for cid in self.local_orders:
|
|
|
i = self.local_orders[cid]
|
|
i = self.local_orders[cid]
|
|
|
if i['side'] == 'kd':
|
|
if i['side'] == 'kd':
|
|
|
|
|
+ # TODO 在挂单范围之外时
|
|
|
# 撤开多单
|
|
# 撤开多单
|
|
|
- c1 = i['price'] > cond1
|
|
|
|
|
- c2 = i['price'] < cond2
|
|
|
|
|
- # c3 = i['price'] > cond1*(1-self.long_hold_rate) + cond2*self.long_hold_rate
|
|
|
|
|
|
|
+ c1 = i['price'] > long_upper
|
|
|
|
|
+ c2 = i['price'] < long_lower
|
|
|
|
|
+ # c3 = i['price'] > long_upper*(1-self.long_hold_rate) + long_lower*self.long_hold_rate
|
|
|
# if c1 or c2 or c3:
|
|
# if c1 or c2 or c3:
|
|
|
if c1 or c2:
|
|
if c1 or c2:
|
|
|
signals[f'Cancel{cid}'] = [i['client_id'], i['order_id']]
|
|
signals[f'Cancel{cid}'] = [i['client_id'], i['order_id']]
|
|
|
elif i['side'] == 'kk':
|
|
elif i['side'] == 'kk':
|
|
|
|
|
+ # TODO 在挂单范围之外时
|
|
|
# 撤开空单
|
|
# 撤开空单
|
|
|
- c1 = i['price'] < cond3
|
|
|
|
|
- c2 = i['price'] > cond4
|
|
|
|
|
- # c3 = i['price'] < cond3*(1-self.short_hold_rate) + cond4*self.short_hold_rate
|
|
|
|
|
|
|
+ c1 = i['price'] < short_lower
|
|
|
|
|
+ c2 = i['price'] > short_upper
|
|
|
|
|
+ # c3 = i['price'] < short_lower*(1-self.short_hold_rate) + short_upper*self.short_hold_rate
|
|
|
# if c1 or c2 or c3:
|
|
# if c1 or c2 or c3:
|
|
|
if c1 or c2:
|
|
if c1 or c2:
|
|
|
signals[f'Cancel{cid}'] = [i['client_id'], i['order_id']]
|
|
signals[f'Cancel{cid}'] = [i['client_id'], i['order_id']]
|
|
@@ -512,10 +523,10 @@ class Strategy:
|
|
|
signals = dict()
|
|
signals = dict()
|
|
|
signals['Limits_open'] = []
|
|
signals['Limits_open'] = []
|
|
|
# 计算挂单范围
|
|
# 计算挂单范围
|
|
|
- cond1 = self.open_dist[0]
|
|
|
|
|
- cond2 = self.open_dist[1]
|
|
|
|
|
- cond3 = self.open_dist[2]
|
|
|
|
|
- cond4 = self.open_dist[3]
|
|
|
|
|
|
|
+ long_upper = self.open_dist[0]
|
|
|
|
|
+ long_lower = self.open_dist[1]
|
|
|
|
|
+ short_lower = self.open_dist[2]
|
|
|
|
|
+ short_upper = self.open_dist[3]
|
|
|
# # 获取当前挂单
|
|
# # 获取当前挂单
|
|
|
buyP = []
|
|
buyP = []
|
|
|
sellP = []
|
|
sellP = []
|
|
@@ -529,6 +540,7 @@ class Strategy:
|
|
|
if i['side'] in ['kk']:
|
|
if i['side'] in ['kk']:
|
|
|
sellP.append(i['price'])
|
|
sellP.append(i['price'])
|
|
|
sell_value += i['amount'] * i['price']
|
|
sell_value += i['amount'] * i['price']
|
|
|
|
|
+ # TODO 计算可开价值
|
|
|
########### 现货 ###########
|
|
########### 现货 ###########
|
|
|
if 'spot' in self.exchange:
|
|
if 'spot' in self.exchange:
|
|
|
### 计算当前持币和持u ###
|
|
### 计算当前持币和持u ###
|
|
@@ -548,25 +560,29 @@ class Strategy:
|
|
|
########### 挂多单 ###########
|
|
########### 挂多单 ###########
|
|
|
if self.post_side >= 0:
|
|
if self.post_side >= 0:
|
|
|
if len(buyP) == 0:
|
|
if len(buyP) == 0:
|
|
|
|
|
+ # TODO 计算开单价格,并限定范围,要求价格有效,截取小数位数。
|
|
|
# 1
|
|
# 1
|
|
|
- targit_buy_price = cond1 * 0.5 + cond2 * 0.5
|
|
|
|
|
|
|
+ targit_buy_price = long_upper * 0.5 + long_lower * 0.5
|
|
|
targit_buy_price = utils.clip(targit_buy_price, self.bp*0.97, self.ap*1.0005)
|
|
targit_buy_price = utils.clip(targit_buy_price, self.bp*0.97, self.ap*1.0005)
|
|
|
targit_buy_price = utils.fix_price(targit_buy_price, self.tickSize)
|
|
targit_buy_price = utils.fix_price(targit_buy_price, self.tickSize)
|
|
|
value = min(one_hand_long_value, long_free_value)
|
|
value = min(one_hand_long_value, long_free_value)
|
|
|
amount = utils.fix_amount(value/self.mp, self.stepSize)
|
|
amount = utils.fix_amount(value/self.mp, self.stepSize)
|
|
|
amount_value = float(amount) * self.mp
|
|
amount_value = float(amount) * self.mp
|
|
|
|
|
+ # TODO 下单前最后检测
|
|
|
if amount_value >= self._min_amount_value and amount_value <= long_free_value:
|
|
if amount_value >= self._min_amount_value and amount_value <= long_free_value:
|
|
|
signals['Limits_open'].append([amount, 'kd', targit_buy_price, utils.get_cid(self.broker_id)])
|
|
signals['Limits_open'].append([amount, 'kd', targit_buy_price, utils.get_cid(self.broker_id)])
|
|
|
########### 挂空单 ###########
|
|
########### 挂空单 ###########
|
|
|
if self.post_side <= 0:
|
|
if self.post_side <= 0:
|
|
|
if len(sellP) == 0:
|
|
if len(sellP) == 0:
|
|
|
|
|
+ # TODO 计算开单价格,并限定范围,要求价格有效,截取小数位数。
|
|
|
# 1
|
|
# 1
|
|
|
- targit_sell_price = cond3 * 0.5 + cond4 * 0.5
|
|
|
|
|
|
|
+ targit_sell_price = short_lower * 0.5 + short_upper * 0.5
|
|
|
targit_sell_price = utils.clip(targit_sell_price, self.bp*0.9995, self.ap*1.03)
|
|
targit_sell_price = utils.clip(targit_sell_price, self.bp*0.9995, self.ap*1.03)
|
|
|
targit_sell_price = utils.fix_price(targit_sell_price, self.tickSize)
|
|
targit_sell_price = utils.fix_price(targit_sell_price, self.tickSize)
|
|
|
value = min(one_hand_short_value, short_free_value)
|
|
value = min(one_hand_short_value, short_free_value)
|
|
|
amount = utils.fix_amount(value/self.mp, self.stepSize)
|
|
amount = utils.fix_amount(value/self.mp, self.stepSize)
|
|
|
amount_value = float(amount) * self.mp
|
|
amount_value = float(amount) * self.mp
|
|
|
|
|
+ # TODO 下单前最后检测
|
|
|
if amount_value >= self._min_amount_value and amount_value <= short_free_value:
|
|
if amount_value >= self._min_amount_value and amount_value <= short_free_value:
|
|
|
signals['Limits_open'].append([amount, 'kk', targit_sell_price, utils.get_cid(self.broker_id)])
|
|
signals['Limits_open'].append([amount, 'kk', targit_sell_price, utils.get_cid(self.broker_id)])
|
|
|
return signals
|
|
return signals
|
|
@@ -830,6 +846,7 @@ class Strategy:
|
|
|
self.logger.info("预热中")
|
|
self.logger.info("预热中")
|
|
|
# 更新状态
|
|
# 更新状态
|
|
|
if self._update_data(data):
|
|
if self._update_data(data):
|
|
|
|
|
+ # TODO 我吐了啊,准备不充分才执行下面的,准备充分是直接return
|
|
|
# 检查是否准备充分
|
|
# 检查是否准备充分
|
|
|
if self.check_ready():
|
|
if self.check_ready():
|
|
|
return dict()
|
|
return dict()
|
|
@@ -866,8 +883,10 @@ class Strategy:
|
|
|
signals.update(self._cancel_open())
|
|
signals.update(self._cancel_open())
|
|
|
# 获取开仓信号 整点时刻前后不报单
|
|
# 获取开仓信号 整点时刻前后不报单
|
|
|
if self.check_allow_post_open():
|
|
if self.check_allow_post_open():
|
|
|
|
|
+ # TODO 报单延迟检测
|
|
|
if self.local_time - self.post_open_time > self.post_open_interval:
|
|
if self.local_time - self.post_open_time > self.post_open_interval:
|
|
|
self.post_open_time = self.local_time
|
|
self.post_open_time = self.local_time
|
|
|
|
|
+ # TODO 开仓指令获取
|
|
|
signals.update(self._post_open())
|
|
signals.update(self._post_open())
|
|
|
# 获取平仓信号
|
|
# 获取平仓信号
|
|
|
signals.update(self._post_close())
|
|
signals.update(self._post_close())
|