123 lines
3.4 KiB
Python
123 lines
3.4 KiB
Python
|
|
"""Futures and leverage trading support with margin calculations."""
|
||
|
|
|
||
|
|
from decimal import Decimal
|
||
|
|
from typing import Dict, Optional
|
||
|
|
from src.core.logger import get_logger
|
||
|
|
|
||
|
|
logger = get_logger(__name__)
|
||
|
|
|
||
|
|
|
||
|
|
class FuturesManager:
|
||
|
|
"""Manages futures and leverage trading."""
|
||
|
|
|
||
|
|
def __init__(self):
|
||
|
|
"""Initialize futures manager."""
|
||
|
|
self.logger = get_logger(__name__)
|
||
|
|
|
||
|
|
def calculate_margin(
|
||
|
|
self,
|
||
|
|
quantity: Decimal,
|
||
|
|
price: Decimal,
|
||
|
|
leverage: int,
|
||
|
|
margin_type: str = "isolated"
|
||
|
|
) -> Decimal:
|
||
|
|
"""Calculate required margin.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
quantity: Position quantity
|
||
|
|
price: Entry price
|
||
|
|
leverage: Leverage multiplier
|
||
|
|
margin_type: "isolated" or "cross"
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Required margin
|
||
|
|
"""
|
||
|
|
position_value = quantity * price
|
||
|
|
margin = position_value / Decimal(leverage)
|
||
|
|
return margin
|
||
|
|
|
||
|
|
def calculate_liquidation_price(
|
||
|
|
self,
|
||
|
|
entry_price: Decimal,
|
||
|
|
leverage: int,
|
||
|
|
side: str, # "long" or "short"
|
||
|
|
maintenance_margin: Decimal = Decimal("0.01") # 1%
|
||
|
|
) -> Decimal:
|
||
|
|
"""Calculate liquidation price.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
entry_price: Entry price
|
||
|
|
leverage: Leverage multiplier
|
||
|
|
side: Position side
|
||
|
|
maintenance_margin: Maintenance margin rate
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Liquidation price
|
||
|
|
"""
|
||
|
|
if side == "long":
|
||
|
|
# For long: liquidation when price drops too much
|
||
|
|
liquidation = entry_price * (1 - (1 / leverage) + maintenance_margin)
|
||
|
|
else:
|
||
|
|
# For short: liquidation when price rises too much
|
||
|
|
liquidation = entry_price * (1 + (1 / leverage) - maintenance_margin)
|
||
|
|
|
||
|
|
return liquidation
|
||
|
|
|
||
|
|
def calculate_funding_rate(
|
||
|
|
self,
|
||
|
|
mark_price: Decimal,
|
||
|
|
index_price: Decimal
|
||
|
|
) -> Decimal:
|
||
|
|
"""Calculate funding rate for perpetual futures.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
mark_price: Mark price
|
||
|
|
index_price: Index price
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Funding rate (8-hour rate)
|
||
|
|
"""
|
||
|
|
premium = (mark_price - index_price) / index_price
|
||
|
|
funding_rate = premium * Decimal("0.01") # Simplified
|
||
|
|
return funding_rate
|
||
|
|
|
||
|
|
def calculate_unrealized_pnl(
|
||
|
|
self,
|
||
|
|
entry_price: Decimal,
|
||
|
|
current_price: Decimal,
|
||
|
|
quantity: Decimal,
|
||
|
|
side: str,
|
||
|
|
leverage: int = 1
|
||
|
|
) -> Decimal:
|
||
|
|
"""Calculate unrealized P&L for futures position.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
entry_price: Entry price
|
||
|
|
current_price: Current mark price
|
||
|
|
quantity: Position quantity
|
||
|
|
side: "long" or "short"
|
||
|
|
leverage: Leverage multiplier
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Unrealized P&L
|
||
|
|
"""
|
||
|
|
if side == "long":
|
||
|
|
pnl = (current_price - entry_price) * quantity * leverage
|
||
|
|
else:
|
||
|
|
pnl = (entry_price - current_price) * quantity * leverage
|
||
|
|
|
||
|
|
return pnl
|
||
|
|
|
||
|
|
|
||
|
|
# Global futures manager
|
||
|
|
_futures_manager: Optional[FuturesManager] = None
|
||
|
|
|
||
|
|
|
||
|
|
def get_futures_manager() -> FuturesManager:
|
||
|
|
"""Get global futures manager instance."""
|
||
|
|
global _futures_manager
|
||
|
|
if _futures_manager is None:
|
||
|
|
_futures_manager = FuturesManager()
|
||
|
|
return _futures_manager
|
||
|
|
|