From 07e0e0709a172eb349c5a417eb0681927664c884 Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Tue, 22 Oct 2019 15:45:27 +0800 Subject: [PATCH] [Mod] support inverse contract with size not equal to 1 (like HBDM) --- vnpy/app/spread_trading/base.py | 23 ++++++++++++++++++----- vnpy/app/spread_trading/engine.py | 8 +++++++- vnpy/app/spread_trading/template.py | 10 +++++++--- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/vnpy/app/spread_trading/base.py b/vnpy/app/spread_trading/base.py index d9589817..9717b740 100644 --- a/vnpy/app/spread_trading/base.py +++ b/vnpy/app/spread_trading/base.py @@ -35,6 +35,9 @@ class LegData: # Tick data buf self.tick: TickData = None + # Contract size + self.size: float = 0 + def update_tick(self, tick: TickData): """""" self.bid_price = tick.bid_price_1 @@ -160,9 +163,9 @@ class SpreadData: leg_ask_volume = leg.ask_volume else: 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, leg.ask_price) + leg.ask_volume, leg.ask_price, leg.size) if trading_multiplier > 0: adjusted_bid_volume = floor( @@ -202,7 +205,8 @@ class SpreadData: if not inverse_contract: net_pos = leg.net_pos 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 @@ -273,9 +277,18 @@ class SpreadData: inverse_contract = self.inverse_contracts[vt_symbol] 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: return 0 - return original_volume / price + return original_volume * size / price diff --git a/vnpy/app/spread_trading/engine.py b/vnpy/app/spread_trading/engine.py index 15c58c75..325552ee 100644 --- a/vnpy/app/spread_trading/engine.py +++ b/vnpy/app/spread_trading/engine.py @@ -194,8 +194,12 @@ class SpreadDataEngine: def process_contract_event(self, event: Event) -> None: """""" 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( contract.symbol, contract.exchange ) @@ -222,6 +226,8 @@ class SpreadDataEngine: # Subscribe market data contract = self.main_engine.get_contract(vt_symbol) if contract: + leg.size = contract.size + req = SubscribeRequest( contract.symbol, contract.exchange diff --git a/vnpy/app/spread_trading/template.py b/vnpy/app/spread_trading/template.py index faf4fa02..c88ef10a 100644 --- a/vnpy/app/spread_trading/template.py +++ b/vnpy/app/spread_trading/template.py @@ -121,9 +121,12 @@ class SpreadAlgoTemplate: # record coin trading volume as leg trading volume, # not contract volume! if self.spread.is_inverse(trade.vt_symbol): + size = self.spread.get_leg_size(trade.vt_symbol) + trade_volume = calculate_inverse_volume( trade.volume, - trade.price + trade.price, + size ) else: trade_volume = trade.volume @@ -189,9 +192,10 @@ class SpreadAlgoTemplate: ): """""" # 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): - volume = volume * price + size = self.spread.get_leg_size(vt_symbol) + volume = volume * price / size vt_orderids = self.algo_engine.send_order( self,