fixed trading and leverage
This commit is contained in:
@ -50,11 +50,12 @@ exchanges:
|
|||||||
bybit:
|
bybit:
|
||||||
enabled: true
|
enabled: true
|
||||||
test_mode: false # Use mainnet (your credentials are for live trading)
|
test_mode: false # Use mainnet (your credentials are for live trading)
|
||||||
trading_mode: "simulation" # simulation, testnet, live - SWITCHED TO SIMULATION FOR TRAINING
|
trading_mode: "live" # simulation, testnet, live - SWITCHED TO SIMULATION FOR TRAINING
|
||||||
supported_symbols: ["BTCUSDT", "ETHUSDT"] # Bybit perpetual format
|
supported_symbols: ["BTCUSDT", "ETHUSDT"] # Bybit perpetual format
|
||||||
base_position_percent: 5.0
|
base_position_percent: 5.0
|
||||||
max_position_percent: 20.0
|
max_position_percent: 20.0
|
||||||
leverage: 10.0 # Conservative leverage for safety
|
leverage: 10.0 # Conservative leverage for safety
|
||||||
|
leverage_applied_by_exchange: true # Broker already applies leverage to P&L
|
||||||
trading_fees:
|
trading_fees:
|
||||||
maker_fee: 0.0001 # 0.01% maker fee
|
maker_fee: 0.0001 # 0.01% maker fee
|
||||||
taker_fee: 0.0006 # 0.06% taker fee
|
taker_fee: 0.0006 # 0.06% taker fee
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
ETHUSDT
|
||||||
|
0.01 3,832.79 3,839.34 Close Short -0.1076 Loss 38.32 38.39 0.0210 0.0211 0.0000 2025-07-28 16:35:46
|
||||||
|
ETHUSDT
|
||||||
|
0.01 3,874.99 3,829.44 Close Short +0.4131 Win 38.74 38.29 0.0213 0.0210 0.0000 2025-07-28 16:33:52
|
||||||
|
ETHUSDT
|
||||||
|
0.11 3,874.41 3,863.37 Close Short +0.7473 Win 426.18 424.97 0.2344 0.2337 0.0000 2025-07-28 16:03:32
|
||||||
|
ETHUSDT
|
||||||
|
0.01 3,875.28 3,868.43 Close Short +0.0259 Win 38.75 38.68 0.0213 0.0212 0.0000 2025-07-28 16:01:40
|
||||||
|
ETHUSDT
|
||||||
|
0.01 3,875.70 3,871.28 Close Short +0.0016 Win 38.75 38.71 0.0213 0.0212 0.0000 2025-07-28 15:59:53
|
||||||
|
ETHUSDT
|
||||||
|
0.01 3,879.87 3,879.79 Close Short -0.0418 Loss 38.79 38.79 0.0213 0.0213 0.0000 2025-07-28 15:54:47
|
||||||
|
ETHUSDT
|
||||||
|
-0.05 3,887.50 3,881.04 Close Long -0.5366 Loss 194.37 194.05 0.1069 0.1067 0.0000 2025-07-28 15:46:06
|
||||||
|
ETHUSDT
|
||||||
|
-0.06 3,880.08 3,884.00 Close Long -0.0210 Loss 232.80 233.04 0.1280 0.1281 0.0000 2025-07-28 15:14:38
|
||||||
|
ETHUSDT
|
||||||
|
0.11 3,877.69 3,876.83 Close Short -0.3737 Loss 426.54 426.45 0.2346 0.2345 0.0000 2025-07-28 15:07:26
|
||||||
|
ETHUSDT
|
||||||
|
0.01 3,878.70 3,877.75 Close Short -0.0330 Loss 38.78 38.77 0.0213 0.0213 0.0000 2025-07-28 15:01:41
|
@ -40,13 +40,14 @@ class Position:
|
|||||||
order_id: str
|
order_id: str
|
||||||
unrealized_pnl: float = 0.0
|
unrealized_pnl: float = 0.0
|
||||||
|
|
||||||
def calculate_pnl(self, current_price: float, leverage: float = 1.0, include_fees: bool = True) -> float:
|
def calculate_pnl(self, current_price: float, leverage: float = 1.0, include_fees: bool = True, leverage_applied_by_exchange: bool = False) -> float:
|
||||||
"""Calculate unrealized P&L for the position with leverage and fees
|
"""Calculate unrealized P&L for the position with leverage and fees
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
current_price: Current market price
|
current_price: Current market price
|
||||||
leverage: Leverage multiplier (default: 1.0)
|
leverage: Leverage multiplier (default: 1.0)
|
||||||
include_fees: Whether to subtract fees from PnL (default: True)
|
include_fees: Whether to subtract fees from PnL (default: True)
|
||||||
|
leverage_applied_by_exchange: Whether leverage is already applied by broker (default: False)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
float: Unrealized PnL including leverage and fees
|
float: Unrealized PnL including leverage and fees
|
||||||
@ -60,8 +61,13 @@ class Position:
|
|||||||
else: # SHORT
|
else: # SHORT
|
||||||
base_pnl = (self.entry_price - current_price) * self.quantity
|
base_pnl = (self.entry_price - current_price) * self.quantity
|
||||||
|
|
||||||
# Apply leverage
|
# Apply leverage only if not already applied by exchange
|
||||||
leveraged_pnl = base_pnl * leverage
|
if leverage_applied_by_exchange:
|
||||||
|
# Broker already applies leverage, so use base PnL
|
||||||
|
leveraged_pnl = base_pnl
|
||||||
|
else:
|
||||||
|
# Apply leverage locally
|
||||||
|
leveraged_pnl = base_pnl * leverage
|
||||||
|
|
||||||
# Calculate fees (0.1% open + 0.1% close = 0.2% total)
|
# Calculate fees (0.1% open + 0.1% close = 0.2% total)
|
||||||
fees = 0.0
|
fees = 0.0
|
||||||
@ -2074,7 +2080,21 @@ class TradingExecutor:
|
|||||||
"""Update position P&L with current market price"""
|
"""Update position P&L with current market price"""
|
||||||
if symbol in self.positions:
|
if symbol in self.positions:
|
||||||
with self.lock:
|
with self.lock:
|
||||||
self.positions[symbol].calculate_pnl(current_price)
|
# Get leverage configuration from primary exchange
|
||||||
|
leverage_applied_by_exchange = False
|
||||||
|
if hasattr(self, 'primary_config'):
|
||||||
|
leverage_applied_by_exchange = self.primary_config.get('leverage_applied_by_exchange', False)
|
||||||
|
|
||||||
|
# Get configured leverage
|
||||||
|
leverage = 1.0
|
||||||
|
if hasattr(self, 'primary_config'):
|
||||||
|
leverage = self.primary_config.get('leverage', 1.0)
|
||||||
|
|
||||||
|
self.positions[symbol].calculate_pnl(
|
||||||
|
current_price,
|
||||||
|
leverage=leverage,
|
||||||
|
leverage_applied_by_exchange=leverage_applied_by_exchange
|
||||||
|
)
|
||||||
|
|
||||||
def get_positions(self) -> Dict[str, Position]:
|
def get_positions(self) -> Dict[str, Position]:
|
||||||
"""Get current positions"""
|
"""Get current positions"""
|
||||||
|
@ -824,37 +824,14 @@ class CleanTradingDashboard:
|
|||||||
else: # SHORT or SELL
|
else: # SHORT or SELL
|
||||||
raw_pnl_per_unit = entry_price - current_price
|
raw_pnl_per_unit = entry_price - current_price
|
||||||
|
|
||||||
# Apply current leverage to unrealized P&L
|
# Apply leverage only if not already applied by exchange
|
||||||
leveraged_unrealized_pnl = raw_pnl_per_unit * size * self.current_leverage
|
leverage_applied_by_exchange = self._get_leverage_applied_by_exchange()
|
||||||
total_session_pnl += leveraged_unrealized_pnl
|
if leverage_applied_by_exchange:
|
||||||
|
# Broker already applies leverage, so use base P&L
|
||||||
side = self.current_position.get('side', 'UNKNOWN')
|
leveraged_unrealized_pnl = raw_pnl_per_unit * size
|
||||||
size = self.current_position.get('size', 0)
|
else:
|
||||||
entry_price = self.current_position.get('price', 0)
|
# Apply leverage locally
|
||||||
|
leveraged_unrealized_pnl = raw_pnl_per_unit * size * self.current_leverage
|
||||||
if entry_price and size > 0:
|
|
||||||
# Calculate unrealized P&L with current leverage
|
|
||||||
if side.upper() == 'LONG' or side.upper() == 'BUY':
|
|
||||||
raw_pnl_per_unit = current_price - entry_price
|
|
||||||
else: # SHORT or SELL
|
|
||||||
raw_pnl_per_unit = entry_price - current_price
|
|
||||||
|
|
||||||
# Apply current leverage to unrealized P&L
|
|
||||||
leveraged_unrealized_pnl = raw_pnl_per_unit * size * self.current_leverage
|
|
||||||
total_session_pnl += leveraged_unrealized_pnl
|
|
||||||
side = self.current_position.get('side', 'UNKNOWN')
|
|
||||||
size = self.current_position.get('size', 0)
|
|
||||||
entry_price = self.current_position.get('price', 0)
|
|
||||||
|
|
||||||
if entry_price and size > 0:
|
|
||||||
# Calculate unrealized P&L with current leverage
|
|
||||||
if side.upper() == 'LONG' or side.upper() == 'BUY':
|
|
||||||
raw_pnl_per_unit = current_price - entry_price
|
|
||||||
else: # SHORT or SELL
|
|
||||||
raw_pnl_per_unit = entry_price - current_price
|
|
||||||
|
|
||||||
# Apply current leverage to unrealized P&L
|
|
||||||
leveraged_unrealized_pnl = raw_pnl_per_unit * size * self.current_leverage
|
|
||||||
total_session_pnl += leveraged_unrealized_pnl
|
total_session_pnl += leveraged_unrealized_pnl
|
||||||
|
|
||||||
session_pnl_str = f"${total_session_pnl:.2f}"
|
session_pnl_str = f"${total_session_pnl:.2f}"
|
||||||
@ -879,10 +856,15 @@ class CleanTradingDashboard:
|
|||||||
else: # SHORT or SELL
|
else: # SHORT or SELL
|
||||||
raw_pnl_per_unit = entry_price - current_price
|
raw_pnl_per_unit = entry_price - current_price
|
||||||
|
|
||||||
# Apply current leverage to P&L calculation
|
# Apply leverage only if not already applied by exchange
|
||||||
# With leverage, P&L is amplified by the leverage factor
|
leverage_applied_by_exchange = self._get_leverage_applied_by_exchange()
|
||||||
leveraged_pnl_per_unit = raw_pnl_per_unit * self.current_leverage
|
if leverage_applied_by_exchange:
|
||||||
unrealized_pnl = leveraged_pnl_per_unit * size
|
# Broker already applies leverage, so use base P&L
|
||||||
|
unrealized_pnl = raw_pnl_per_unit * size
|
||||||
|
else:
|
||||||
|
# Apply leverage locally
|
||||||
|
leveraged_pnl_per_unit = raw_pnl_per_unit * self.current_leverage
|
||||||
|
unrealized_pnl = leveraged_pnl_per_unit * size
|
||||||
|
|
||||||
# Format P&L string with color
|
# Format P&L string with color
|
||||||
if unrealized_pnl >= 0:
|
if unrealized_pnl >= 0:
|
||||||
@ -1334,6 +1316,16 @@ class CleanTradingDashboard:
|
|||||||
# logger.error(f"Error updating cold start mode: {e}")
|
# logger.error(f"Error updating cold start mode: {e}")
|
||||||
# return "ERROR", "fw-bold text-danger"
|
# return "ERROR", "fw-bold text-danger"
|
||||||
|
|
||||||
|
def _get_leverage_applied_by_exchange(self) -> bool:
|
||||||
|
"""Check if leverage is already applied by the exchange"""
|
||||||
|
try:
|
||||||
|
if self.trading_executor and hasattr(self.trading_executor, 'primary_config'):
|
||||||
|
return self.trading_executor.primary_config.get('leverage_applied_by_exchange', False)
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"Error checking leverage_applied_by_exchange: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
def _get_current_price(self, symbol: str) -> Optional[float]:
|
def _get_current_price(self, symbol: str) -> Optional[float]:
|
||||||
"""Get current price for symbol - ONLY using our data providers"""
|
"""Get current price for symbol - ONLY using our data providers"""
|
||||||
try:
|
try:
|
||||||
@ -4101,8 +4093,14 @@ class CleanTradingDashboard:
|
|||||||
else: # SHORT
|
else: # SHORT
|
||||||
raw_pnl_per_unit = entry_price - current_price
|
raw_pnl_per_unit = entry_price - current_price
|
||||||
|
|
||||||
# Apply current leverage to P&L calculation
|
# Apply leverage only if not already applied by exchange
|
||||||
leveraged_unrealized_pnl = raw_pnl_per_unit * size * self.current_leverage
|
leverage_applied_by_exchange = self._get_leverage_applied_by_exchange()
|
||||||
|
if leverage_applied_by_exchange:
|
||||||
|
# Broker already applies leverage, so use base P&L
|
||||||
|
leveraged_unrealized_pnl = raw_pnl_per_unit * size
|
||||||
|
else:
|
||||||
|
# Apply leverage locally
|
||||||
|
leveraged_unrealized_pnl = raw_pnl_per_unit * size * self.current_leverage
|
||||||
|
|
||||||
# Calculate profit incentive - bigger profits create stronger incentive to close
|
# Calculate profit incentive - bigger profits create stronger incentive to close
|
||||||
if leveraged_unrealized_pnl > 0:
|
if leveraged_unrealized_pnl > 0:
|
||||||
|
Reference in New Issue
Block a user