[Mod] support inverse contract with size not equal to 1 (like HBDM)

This commit is contained in:
vn.py 2019-10-22 15:45:27 +08:00
parent 44bd65b502
commit 07e0e0709a
3 changed files with 32 additions and 9 deletions

View File

@ -35,6 +35,9 @@ class LegData:
# Tick data buf # Tick data buf
self.tick: TickData = None self.tick: TickData = None
# Contract size
self.size: float = 0
def update_tick(self, tick: TickData): def update_tick(self, tick: TickData):
"""""" """"""
self.bid_price = tick.bid_price_1 self.bid_price = tick.bid_price_1
@ -160,9 +163,9 @@ class SpreadData:
leg_ask_volume = leg.ask_volume leg_ask_volume = leg.ask_volume
else: else:
leg_bid_volume = calculate_inverse_volume( leg_bid_volume = calculate_inverse_volume(
leg.bid_volume, leg.bid_price) leg.bid_volume, leg.bid_price, leg.size)
leg_ask_volume = calculate_inverse_volume( leg_ask_volume = calculate_inverse_volume(
leg.ask_volume, leg.ask_price) leg.ask_volume, leg.ask_price, leg.size)
if trading_multiplier > 0: if trading_multiplier > 0:
adjusted_bid_volume = floor( adjusted_bid_volume = floor(
@ -202,7 +205,8 @@ class SpreadData:
if not inverse_contract: if not inverse_contract:
net_pos = leg.net_pos net_pos = leg.net_pos
else: else:
net_pos = calculate_inverse_volume(leg.net_pos, leg.last_price) net_pos = calculate_inverse_volume(
leg.net_pos, leg.last_price, leg.size)
adjusted_net_pos = net_pos / trading_multiplier adjusted_net_pos = net_pos / trading_multiplier
@ -273,9 +277,18 @@ class SpreadData:
inverse_contract = self.inverse_contracts[vt_symbol] inverse_contract = self.inverse_contracts[vt_symbol]
return inverse_contract return inverse_contract
def get_leg_size(self, vt_symbol: str) -> float:
""""""
leg = self.legs[vt_symbol]
return leg.size
def calculate_inverse_volume(original_volume: float, price: float) -> float:
def calculate_inverse_volume(
original_volume: float,
price: float,
size: float,
) -> float:
"""""" """"""
if not price: if not price:
return 0 return 0
return original_volume / price return original_volume * size / price

View File

@ -194,8 +194,12 @@ class SpreadDataEngine:
def process_contract_event(self, event: Event) -> None: def process_contract_event(self, event: Event) -> None:
"""""" """"""
contract = event.data contract = event.data
leg = self.legs.get(contract.vt_symbol, None)
if leg:
# Update contract size data
leg.size = contract.size
if contract.vt_symbol in self.legs:
req = SubscribeRequest( req = SubscribeRequest(
contract.symbol, contract.exchange contract.symbol, contract.exchange
) )
@ -222,6 +226,8 @@ class SpreadDataEngine:
# Subscribe market data # Subscribe market data
contract = self.main_engine.get_contract(vt_symbol) contract = self.main_engine.get_contract(vt_symbol)
if contract: if contract:
leg.size = contract.size
req = SubscribeRequest( req = SubscribeRequest(
contract.symbol, contract.symbol,
contract.exchange contract.exchange

View File

@ -121,9 +121,12 @@ class SpreadAlgoTemplate:
# record coin trading volume as leg trading volume, # record coin trading volume as leg trading volume,
# not contract volume! # not contract volume!
if self.spread.is_inverse(trade.vt_symbol): if self.spread.is_inverse(trade.vt_symbol):
size = self.spread.get_leg_size(trade.vt_symbol)
trade_volume = calculate_inverse_volume( trade_volume = calculate_inverse_volume(
trade.volume, trade.volume,
trade.price trade.price,
size
) )
else: else:
trade_volume = trade.volume trade_volume = trade.volume
@ -189,9 +192,10 @@ class SpreadAlgoTemplate:
): ):
"""""" """"""
# For inverse contract: # For inverse contract:
# contract trading volume = coin trading volume * trading price # calculate contract trading volume from coin trading volume
if self.spread.is_inverse(vt_symbol): if self.spread.is_inverse(vt_symbol):
volume = volume * price size = self.spread.get_leg_size(vt_symbol)
volume = volume * price / size
vt_orderids = self.algo_engine.send_order( vt_orderids = self.algo_engine.send_order(
self, self,