diff --git a/vnpy/app/spread_trading/base.py b/vnpy/app/spread_trading/base.py index 9717b740..2d00579a 100644 --- a/vnpy/app/spread_trading/base.py +++ b/vnpy/app/spread_trading/base.py @@ -4,6 +4,7 @@ from datetime import datetime from vnpy.trader.object import TickData, PositionData, TradeData from vnpy.trader.constant import Direction, Offset, Exchange +from vnpy.trader.utility import floor_to EVENT_SPREAD_DATA = "eSpreadData" @@ -94,6 +95,8 @@ class SpreadData: self.active_leg: LegData = None self.passive_legs: List[LegData] = [] + self.min_volume = 0.1 + # For calculating spread price self.price_multipliers: Dict[str, int] = price_multipliers @@ -168,15 +171,23 @@ class SpreadData: leg.ask_volume, leg.ask_price, leg.size) if trading_multiplier > 0: - adjusted_bid_volume = floor( - leg_bid_volume / trading_multiplier) - adjusted_ask_volume = floor( - leg_ask_volume / trading_multiplier) + adjusted_bid_volume = floor_to( + leg_bid_volume / trading_multiplier, + self.min_volume + ) + adjusted_ask_volume = floor_to( + leg_ask_volume / trading_multiplier, + self.min_volume + ) else: - adjusted_bid_volume = floor( - leg_bid_volume / abs(trading_multiplier)) - adjusted_ask_volume = floor( - leg_ask_volume / abs(trading_multiplier)) + adjusted_bid_volume = floor_to( + leg_bid_volume / abs(trading_multiplier), + self.min_volume + ) + adjusted_ask_volume = floor_to( + leg_ask_volume / abs(trading_multiplier), + self.min_volume + ) # For the first leg, just initialize if not n: diff --git a/vnpy/app/spread_trading/engine.py b/vnpy/app/spread_trading/engine.py index 325552ee..7d0c639f 100644 --- a/vnpy/app/spread_trading/engine.py +++ b/vnpy/app/spread_trading/engine.py @@ -128,11 +128,13 @@ class SpreadDataEngine: for leg in spread.legs.values(): price_multiplier = spread.price_multipliers[leg.vt_symbol] trading_multiplier = spread.trading_multipliers[leg.vt_symbol] + inverse_contract = spread.inverse_contracts[leg.vt_symbol] leg_setting = { "vt_symbol": leg.vt_symbol, "price_multiplier": price_multiplier, - "trading_multiplier": trading_multiplier + "trading_multiplier": trading_multiplier, + "inverse_contract": inverse_contract } leg_settings.append(leg_setting) @@ -268,7 +270,7 @@ class SpreadDataEngine: legs.append(leg) price_multipliers[vt_symbol] = leg_setting["price_multiplier"] trading_multipliers[vt_symbol] = leg_setting["trading_multiplier"] - inverse_contracts[vt_symbol] = leg_setting.get("inverse_contracts", False) + inverse_contracts[vt_symbol] = leg_setting.get("inverse_contract", False) spread = SpreadData( name, diff --git a/vnpy/trader/utility.py b/vnpy/trader/utility.py index 51471b70..54afc881 100644 --- a/vnpy/trader/utility.py +++ b/vnpy/trader/utility.py @@ -7,6 +7,7 @@ import logging from pathlib import Path from typing import Callable, Dict from decimal import Decimal +from math import floor import numpy as np import talib @@ -124,6 +125,16 @@ def round_to(value: float, target: float) -> float: return rounded +def floor_to(value: float, target: float) -> float: + """ + Similar to math.floor function, but to target float number. + """ + value = Decimal(str(value)) + target = Decimal(str(target)) + result = float(int(floor(value / target)) * target) + return result + + class BarGenerator: """ For: