Skip to content

Commit

Permalink
refactor: Fix trading rules initialization for derivatives
Browse files Browse the repository at this point in the history
  • Loading branch information
gianlucapagliara committed Jan 7, 2025
1 parent 6b59c97 commit 3833acf
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 8 deletions.
12 changes: 12 additions & 0 deletions financepype/markets/market.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ def validate_fields(self) -> Self:
raise ValueError("Expiry date is required for futures")
return self

@property
def is_spot(self) -> bool:
return self.instrument_type.is_spot

@property
def is_derivative(self) -> bool:
return self.instrument_type.is_derivative
Expand All @@ -154,6 +158,14 @@ def is_future(self) -> bool:
def is_option(self) -> bool:
return self.instrument_type.is_option

@property
def is_linear(self) -> bool:
return self.instrument_type.is_linear

@property
def is_inverse(self) -> bool:
return self.instrument_type.is_inverse

@classmethod
def get_timeframe_type(
cls,
Expand Down
23 changes: 23 additions & 0 deletions financepype/rules/trading_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,29 @@ class DerivativeTradingRule(TradingRule):
>>> print(future.perpetual) # True
"""

@model_validator(mode="after")
def fix_collateral_tokens(self) -> Self:
"""Set default collateral tokens if not specified.
For linear instruments, uses quote currency as collateral
For inverse instruments, uses base currency as collateral
Returns:
Self: The validated instance
"""
instrument_info = self.trading_pair.instrument_info
if instrument_info.is_linear:
if self.buy_order_collateral_token is None:
self.buy_order_collateral_token = instrument_info.quote
if self.sell_order_collateral_token is None:
self.sell_order_collateral_token = instrument_info.quote
elif instrument_info.is_inverse:
if self.buy_order_collateral_token is None:
self.buy_order_collateral_token = instrument_info.base
if self.sell_order_collateral_token is None:
self.sell_order_collateral_token = instrument_info.base
return self

@field_serializer("strike_price")
def serialize_strike_price(self, strike_price: Decimal | None) -> str | None:
return str(strike_price) if strike_price is not None else None
Expand Down
25 changes: 17 additions & 8 deletions financepype/simulations/balances/engines/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from financepype.operations.fees import OperationFee as Fee
from financepype.operations.orders.models import OrderType, PositionAction, TradeType
from financepype.platforms.platform import Platform
from financepype.rules.trading_rule import TradingRule
from financepype.rules.trading_rule import DerivativeTradingRule, TradingRule
from financepype.simulations.balances.engines.models import AssetCashflow, OrderDetails
from financepype.simulations.balances.engines.multiengine import BalanceMultiEngine

Expand All @@ -29,13 +29,22 @@ def create_sample_order(

trading_pair_obj = TradingPair(name=trading_pair)

trading_rule = TradingRule(
trading_pair=trading_pair_obj,
min_order_size=Decimal("0.0001"),
min_price_increment=Decimal("0.01"),
min_notional_size=Decimal("10"),
supports_market_orders=True,
)
if trading_pair_obj.instrument_info.is_spot:
trading_rule = TradingRule(
trading_pair=trading_pair_obj,
min_order_size=Decimal("0.0001"),
min_price_increment=Decimal("0.01"),
min_notional_size=Decimal("10"),
supports_market_orders=True,
)
else:
trading_rule = DerivativeTradingRule(
trading_pair=trading_pair_obj,
min_order_size=Decimal("0.0001"),
min_price_increment=Decimal("0.01"),
min_notional_size=Decimal("10"),
supports_market_orders=True,
)

return OrderDetails(
platform=platform,
Expand Down

0 comments on commit 3833acf

Please sign in to comment.