dynamic profitabiliy reward
This commit is contained in:
@ -1985,6 +1985,53 @@ class TradingOrchestrator:
|
|||||||
self.trading_executor = trading_executor
|
self.trading_executor = trading_executor
|
||||||
logger.info("Trading executor set for position tracking and P&L feedback")
|
logger.info("Trading executor set for position tracking and P&L feedback")
|
||||||
|
|
||||||
|
def get_profitability_reward_multiplier(self) -> float:
|
||||||
|
"""Get the current profitability reward multiplier from trading executor
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
float: Current profitability reward multiplier (0.0 to 2.0)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if self.trading_executor and hasattr(self.trading_executor, 'get_profitability_reward_multiplier'):
|
||||||
|
multiplier = self.trading_executor.get_profitability_reward_multiplier()
|
||||||
|
logger.debug(f"Current profitability reward multiplier: {multiplier:.2f}")
|
||||||
|
return multiplier
|
||||||
|
return 0.0
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error getting profitability reward multiplier: {e}")
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
def calculate_enhanced_reward(self, base_pnl: float, confidence: float = 1.0) -> float:
|
||||||
|
"""Calculate enhanced reward with profitability multiplier
|
||||||
|
|
||||||
|
Args:
|
||||||
|
base_pnl: Base P&L from the trade
|
||||||
|
confidence: Confidence level of the prediction (0.0 to 1.0)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
float: Enhanced reward with profitability multiplier applied
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Get the dynamic profitability multiplier
|
||||||
|
profitability_multiplier = self.get_profitability_reward_multiplier()
|
||||||
|
|
||||||
|
# Base reward is the P&L
|
||||||
|
base_reward = base_pnl
|
||||||
|
|
||||||
|
# Apply profitability multiplier only to positive P&L (profitable trades)
|
||||||
|
if base_pnl > 0 and profitability_multiplier > 0:
|
||||||
|
# Enhance profitable trades with the multiplier
|
||||||
|
enhanced_reward = base_pnl * (1.0 + profitability_multiplier)
|
||||||
|
logger.debug(f"Enhanced reward: ${base_pnl:.2f} → ${enhanced_reward:.2f} (multiplier: {profitability_multiplier:.2f})")
|
||||||
|
return enhanced_reward
|
||||||
|
else:
|
||||||
|
# No enhancement for losing trades or when multiplier is 0
|
||||||
|
return base_reward
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error calculating enhanced reward: {e}")
|
||||||
|
return base_pnl
|
||||||
|
|
||||||
def _check_signal_confirmation(self, symbol: str, signal_data: Dict) -> Optional[str]:
|
def _check_signal_confirmation(self, symbol: str, signal_data: Dict) -> Optional[str]:
|
||||||
"""Check if we have enough signal confirmations for trend confirmation with rate limiting"""
|
"""Check if we have enough signal confirmations for trend confirmation with rate limiting"""
|
||||||
try:
|
try:
|
||||||
|
@ -176,13 +176,25 @@ class TradingExecutor:
|
|||||||
self.simulation_balance = self.trading_config.get('simulation_account_usd', 100.0)
|
self.simulation_balance = self.trading_config.get('simulation_account_usd', 100.0)
|
||||||
self.simulation_positions = {} # symbol -> position data with real entry prices
|
self.simulation_positions = {} # symbol -> position data with real entry prices
|
||||||
|
|
||||||
# Trading fees configuration (0.1% for both open and close)
|
# Trading fees configuration (0.1% for both open and close - REVERTED TO NORMAL)
|
||||||
self.trading_fees = {
|
self.trading_fees = {
|
||||||
'open_fee_percent': 0.001, # 0.1% fee when opening position
|
'open_fee_percent': 0.001, # 0.1% fee when opening position
|
||||||
'close_fee_percent': 0.001, # 0.1% fee when closing position
|
'close_fee_percent': 0.001, # 0.1% fee when closing position
|
||||||
'total_round_trip_fee': 0.002 # 0.2% total for round trip
|
'total_round_trip_fee': 0.002 # 0.2% total for round trip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Dynamic profitability reward parameter - starts at 0, adjusts based on success rate
|
||||||
|
self.profitability_reward_multiplier = 0.0 # Starts at 0, can be increased
|
||||||
|
self.min_profitability_multiplier = 0.0 # Minimum value
|
||||||
|
self.max_profitability_multiplier = 2.0 # Maximum 2x multiplier
|
||||||
|
self.profitability_adjustment_step = 0.1 # Adjust by 0.1 each time
|
||||||
|
|
||||||
|
# Success rate tracking for profitability adjustment
|
||||||
|
self.recent_trades_window = 20 # Look at last 20 trades
|
||||||
|
self.success_rate_increase_threshold = 0.60 # Increase multiplier if >60% success
|
||||||
|
self.success_rate_decrease_threshold = 0.51 # Decrease multiplier if <51% success
|
||||||
|
self.last_profitability_adjustment = datetime.now()
|
||||||
|
|
||||||
logger.info(f"TradingExecutor initialized - Trading: {self.trading_enabled}, Mode: {self.trading_mode}")
|
logger.info(f"TradingExecutor initialized - Trading: {self.trading_enabled}, Mode: {self.trading_mode}")
|
||||||
logger.info(f"Simulation balance: ${self.simulation_balance:.2f}")
|
logger.info(f"Simulation balance: ${self.simulation_balance:.2f}")
|
||||||
|
|
||||||
@ -622,6 +634,83 @@ class TradingExecutor:
|
|||||||
logger.error(f"Error cancelling open orders for {symbol}: {e}")
|
logger.error(f"Error cancelling open orders for {symbol}: {e}")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def _calculate_recent_success_rate(self) -> float:
|
||||||
|
"""Calculate success rate of recent closed trades
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
float: Success rate (0.0 to 1.0) of recent trades
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if len(self.trade_records) < 5: # Need at least 5 trades
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
# Get recent trades (up to the window size)
|
||||||
|
recent_trades = self.trade_records[-self.recent_trades_window:]
|
||||||
|
|
||||||
|
if not recent_trades:
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
# Count winning trades (net PnL > 0)
|
||||||
|
winning_trades = sum(1 for trade in recent_trades if trade.net_pnl > 0)
|
||||||
|
success_rate = winning_trades / len(recent_trades)
|
||||||
|
|
||||||
|
logger.debug(f"Recent success rate: {success_rate:.2%} ({winning_trades}/{len(recent_trades)} trades)")
|
||||||
|
return success_rate
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error calculating success rate: {e}")
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
def _adjust_profitability_reward_multiplier(self):
|
||||||
|
"""Adjust profitability reward multiplier based on recent success rate"""
|
||||||
|
try:
|
||||||
|
# Only adjust every 5 minutes to avoid too frequent changes
|
||||||
|
current_time = datetime.now()
|
||||||
|
time_since_last_adjustment = (current_time - self.last_profitability_adjustment).total_seconds()
|
||||||
|
|
||||||
|
if time_since_last_adjustment < 300: # 5 minutes
|
||||||
|
return
|
||||||
|
|
||||||
|
success_rate = self._calculate_recent_success_rate()
|
||||||
|
|
||||||
|
# Only adjust if we have enough trades
|
||||||
|
if len(self.trade_records) < 10:
|
||||||
|
return
|
||||||
|
|
||||||
|
old_multiplier = self.profitability_reward_multiplier
|
||||||
|
|
||||||
|
# Increase multiplier if success rate > 60%
|
||||||
|
if success_rate > self.success_rate_increase_threshold:
|
||||||
|
self.profitability_reward_multiplier = min(
|
||||||
|
self.max_profitability_multiplier,
|
||||||
|
self.profitability_reward_multiplier + self.profitability_adjustment_step
|
||||||
|
)
|
||||||
|
logger.info(f"🎯 SUCCESS RATE HIGH ({success_rate:.1%}) - Increased profitability multiplier: {old_multiplier:.1f} → {self.profitability_reward_multiplier:.1f}")
|
||||||
|
|
||||||
|
# Decrease multiplier if success rate < 51%
|
||||||
|
elif success_rate < self.success_rate_decrease_threshold:
|
||||||
|
self.profitability_reward_multiplier = max(
|
||||||
|
self.min_profitability_multiplier,
|
||||||
|
self.profitability_reward_multiplier - self.profitability_adjustment_step
|
||||||
|
)
|
||||||
|
logger.info(f"⚠️ SUCCESS RATE LOW ({success_rate:.1%}) - Decreased profitability multiplier: {old_multiplier:.1f} → {self.profitability_reward_multiplier:.1f}")
|
||||||
|
|
||||||
|
else:
|
||||||
|
logger.debug(f"Success rate {success_rate:.1%} in acceptable range - keeping multiplier at {self.profitability_reward_multiplier:.1f}")
|
||||||
|
|
||||||
|
self.last_profitability_adjustment = current_time
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error adjusting profitability reward multiplier: {e}")
|
||||||
|
|
||||||
|
def get_profitability_reward_multiplier(self) -> float:
|
||||||
|
"""Get current profitability reward multiplier
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
float: Current profitability reward multiplier
|
||||||
|
"""
|
||||||
|
return self.profitability_reward_multiplier
|
||||||
|
|
||||||
def _can_reenable_live_trading(self) -> bool:
|
def _can_reenable_live_trading(self) -> bool:
|
||||||
"""Check if trading performance has improved enough to re-enable live trading
|
"""Check if trading performance has improved enough to re-enable live trading
|
||||||
|
|
||||||
@ -1198,7 +1287,11 @@ class TradingExecutor:
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.trade_history.append(trade_record)
|
self.trade_history.append(trade_record)
|
||||||
|
self.trade_records.append(trade_record) # Add to trade records for success rate tracking
|
||||||
self.daily_loss += max(0, -pnl) # Add to daily loss if negative
|
self.daily_loss += max(0, -pnl) # Add to daily loss if negative
|
||||||
|
|
||||||
|
# Adjust profitability reward multiplier based on recent performance
|
||||||
|
self._adjust_profitability_reward_multiplier()
|
||||||
|
|
||||||
# Update consecutive losses
|
# Update consecutive losses
|
||||||
if pnl < -0.001: # A losing trade
|
if pnl < -0.001: # A losing trade
|
||||||
@ -1289,8 +1382,12 @@ class TradingExecutor:
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.trade_history.append(trade_record)
|
self.trade_history.append(trade_record)
|
||||||
|
self.trade_records.append(trade_record) # Add to trade records for success rate tracking
|
||||||
self.daily_loss += max(0, -(pnl - fees)) # Add to daily loss if negative
|
self.daily_loss += max(0, -(pnl - fees)) # Add to daily loss if negative
|
||||||
|
|
||||||
|
# Adjust profitability reward multiplier based on recent performance
|
||||||
|
self._adjust_profitability_reward_multiplier()
|
||||||
|
|
||||||
# Update consecutive losses
|
# Update consecutive losses
|
||||||
if pnl < -0.001: # A losing trade
|
if pnl < -0.001: # A losing trade
|
||||||
self.consecutive_losses += 1
|
self.consecutive_losses += 1
|
||||||
@ -1356,7 +1453,11 @@ class TradingExecutor:
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.trade_history.append(trade_record)
|
self.trade_history.append(trade_record)
|
||||||
|
self.trade_records.append(trade_record) # Add to trade records for success rate tracking
|
||||||
self.daily_loss += max(0, -pnl) # Add to daily loss if negative
|
self.daily_loss += max(0, -pnl) # Add to daily loss if negative
|
||||||
|
|
||||||
|
# Adjust profitability reward multiplier based on recent performance
|
||||||
|
self._adjust_profitability_reward_multiplier()
|
||||||
|
|
||||||
# Update consecutive losses
|
# Update consecutive losses
|
||||||
if pnl < -0.001: # A losing trade
|
if pnl < -0.001: # A losing trade
|
||||||
@ -1428,8 +1529,12 @@ class TradingExecutor:
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.trade_history.append(trade_record)
|
self.trade_history.append(trade_record)
|
||||||
|
self.trade_records.append(trade_record) # Add to trade records for success rate tracking
|
||||||
self.daily_loss += max(0, -(pnl - fees)) # Add to daily loss if negative
|
self.daily_loss += max(0, -(pnl - fees)) # Add to daily loss if negative
|
||||||
|
|
||||||
|
# Adjust profitability reward multiplier based on recent performance
|
||||||
|
self._adjust_profitability_reward_multiplier()
|
||||||
|
|
||||||
# Update consecutive losses
|
# Update consecutive losses
|
||||||
if pnl < -0.001: # A losing trade
|
if pnl < -0.001: # A losing trade
|
||||||
self.consecutive_losses += 1
|
self.consecutive_losses += 1
|
||||||
|
294
test_profitability_reward_system.py
Normal file
294
test_profitability_reward_system.py
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Test script for the dynamic profitability reward system
|
||||||
|
|
||||||
|
This script tests:
|
||||||
|
1. Fee reversion to normal 0.1% (0.001)
|
||||||
|
2. Dynamic profitability reward multiplier adjustment
|
||||||
|
3. Success rate calculation
|
||||||
|
4. Integration with dashboard display
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
# Add project root to path
|
||||||
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
from core.trading_executor import TradingExecutor, TradeRecord
|
||||||
|
from core.orchestrator import TradingOrchestrator
|
||||||
|
from core.data_provider import DataProvider
|
||||||
|
|
||||||
|
def test_fee_configuration():
|
||||||
|
"""Test that fees are reverted to normal 0.1%"""
|
||||||
|
print("=" * 60)
|
||||||
|
print("🧪 TESTING FEE CONFIGURATION")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
executor = TradingExecutor()
|
||||||
|
|
||||||
|
# Check fee configuration
|
||||||
|
expected_open_fee = 0.001 # 0.1%
|
||||||
|
expected_close_fee = 0.001 # 0.1%
|
||||||
|
expected_total_fee = 0.002 # 0.2%
|
||||||
|
|
||||||
|
actual_open_fee = executor.trading_fees['open_fee_percent']
|
||||||
|
actual_close_fee = executor.trading_fees['close_fee_percent']
|
||||||
|
actual_total_fee = executor.trading_fees['total_round_trip_fee']
|
||||||
|
|
||||||
|
print(f"Expected Open Fee: {expected_open_fee} (0.1%)")
|
||||||
|
print(f"Actual Open Fee: {actual_open_fee} (0.1%)")
|
||||||
|
print(f"✅ Open Fee: {'PASS' if actual_open_fee == expected_open_fee else 'FAIL'}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
print(f"Expected Close Fee: {expected_close_fee} (0.1%)")
|
||||||
|
print(f"Actual Close Fee: {actual_close_fee} (0.1%)")
|
||||||
|
print(f"✅ Close Fee: {'PASS' if actual_close_fee == expected_close_fee else 'FAIL'}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
print(f"Expected Total Fee: {expected_total_fee} (0.2%)")
|
||||||
|
print(f"Actual Total Fee: {actual_total_fee} (0.2%)")
|
||||||
|
print(f"✅ Total Fee: {'PASS' if actual_total_fee == expected_total_fee else 'FAIL'}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
return actual_open_fee == expected_open_fee and actual_close_fee == expected_close_fee
|
||||||
|
|
||||||
|
def test_profitability_multiplier_initialization():
|
||||||
|
"""Test profitability multiplier initialization"""
|
||||||
|
print("=" * 60)
|
||||||
|
print("🧪 TESTING PROFITABILITY MULTIPLIER INITIALIZATION")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
executor = TradingExecutor()
|
||||||
|
|
||||||
|
# Check initial values
|
||||||
|
initial_multiplier = executor.profitability_reward_multiplier
|
||||||
|
min_multiplier = executor.min_profitability_multiplier
|
||||||
|
max_multiplier = executor.max_profitability_multiplier
|
||||||
|
adjustment_step = executor.profitability_adjustment_step
|
||||||
|
|
||||||
|
print(f"Initial Multiplier: {initial_multiplier} (should be 0.0)")
|
||||||
|
print(f"Min Multiplier: {min_multiplier} (should be 0.0)")
|
||||||
|
print(f"Max Multiplier: {max_multiplier} (should be 2.0)")
|
||||||
|
print(f"Adjustment Step: {adjustment_step} (should be 0.1)")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Check thresholds
|
||||||
|
increase_threshold = executor.success_rate_increase_threshold
|
||||||
|
decrease_threshold = executor.success_rate_decrease_threshold
|
||||||
|
trades_window = executor.recent_trades_window
|
||||||
|
|
||||||
|
print(f"Increase Threshold: {increase_threshold:.1%} (should be 60%)")
|
||||||
|
print(f"Decrease Threshold: {decrease_threshold:.1%} (should be 51%)")
|
||||||
|
print(f"Trades Window: {trades_window} (should be 20)")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Test getter method
|
||||||
|
multiplier_from_getter = executor.get_profitability_reward_multiplier()
|
||||||
|
print(f"Multiplier via getter: {multiplier_from_getter}")
|
||||||
|
print(f"✅ Getter method: {'PASS' if multiplier_from_getter == initial_multiplier else 'FAIL'}")
|
||||||
|
|
||||||
|
return (initial_multiplier == 0.0 and
|
||||||
|
min_multiplier == 0.0 and
|
||||||
|
max_multiplier == 2.0 and
|
||||||
|
adjustment_step == 0.1)
|
||||||
|
|
||||||
|
def simulate_trades_and_test_adjustment(executor, winning_trades, total_trades):
|
||||||
|
"""Simulate trades and test multiplier adjustment"""
|
||||||
|
print(f"📊 Simulating {winning_trades}/{total_trades} winning trades ({winning_trades/total_trades:.1%} success rate)")
|
||||||
|
|
||||||
|
# Clear existing trade records
|
||||||
|
executor.trade_records = []
|
||||||
|
|
||||||
|
# Create simulated trade records
|
||||||
|
base_time = datetime.now() - timedelta(hours=1)
|
||||||
|
|
||||||
|
for i in range(total_trades):
|
||||||
|
# Create winning or losing trade based on ratio
|
||||||
|
is_winning = i < winning_trades
|
||||||
|
pnl = 10.0 if is_winning else -5.0 # $10 profit or $5 loss
|
||||||
|
|
||||||
|
trade_record = TradeRecord(
|
||||||
|
symbol="ETH/USDT",
|
||||||
|
side="LONG",
|
||||||
|
quantity=0.01,
|
||||||
|
entry_price=3000.0,
|
||||||
|
exit_price=3010.0 if is_winning else 2995.0,
|
||||||
|
entry_time=base_time + timedelta(minutes=i*2),
|
||||||
|
exit_time=base_time + timedelta(minutes=i*2+1),
|
||||||
|
pnl=pnl,
|
||||||
|
fees=2.0,
|
||||||
|
confidence=0.8,
|
||||||
|
net_pnl=pnl - 2.0 # After fees
|
||||||
|
)
|
||||||
|
|
||||||
|
executor.trade_records.append(trade_record)
|
||||||
|
|
||||||
|
# Force adjustment by setting last adjustment time to past
|
||||||
|
executor.last_profitability_adjustment = datetime.now() - timedelta(minutes=10)
|
||||||
|
|
||||||
|
# Get initial multiplier
|
||||||
|
initial_multiplier = executor.get_profitability_reward_multiplier()
|
||||||
|
|
||||||
|
# Calculate success rate
|
||||||
|
success_rate = executor._calculate_recent_success_rate()
|
||||||
|
print(f"Calculated success rate: {success_rate:.1%}")
|
||||||
|
|
||||||
|
# Trigger adjustment
|
||||||
|
executor._adjust_profitability_reward_multiplier()
|
||||||
|
|
||||||
|
# Get new multiplier
|
||||||
|
new_multiplier = executor.get_profitability_reward_multiplier()
|
||||||
|
|
||||||
|
print(f"Initial multiplier: {initial_multiplier:.1f}")
|
||||||
|
print(f"New multiplier: {new_multiplier:.1f}")
|
||||||
|
|
||||||
|
# Determine expected change
|
||||||
|
if success_rate > executor.success_rate_increase_threshold:
|
||||||
|
expected_change = "increase"
|
||||||
|
expected_new = min(executor.max_profitability_multiplier, initial_multiplier + executor.profitability_adjustment_step)
|
||||||
|
elif success_rate < executor.success_rate_decrease_threshold:
|
||||||
|
expected_change = "decrease"
|
||||||
|
expected_new = max(executor.min_profitability_multiplier, initial_multiplier - executor.profitability_adjustment_step)
|
||||||
|
else:
|
||||||
|
expected_change = "no change"
|
||||||
|
expected_new = initial_multiplier
|
||||||
|
|
||||||
|
print(f"Expected change: {expected_change}")
|
||||||
|
print(f"Expected new value: {expected_new:.1f}")
|
||||||
|
|
||||||
|
success = abs(new_multiplier - expected_new) < 0.01
|
||||||
|
print(f"✅ Adjustment: {'PASS' if success else 'FAIL'}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
return success
|
||||||
|
|
||||||
|
def test_orchestrator_integration():
|
||||||
|
"""Test orchestrator integration with profitability multiplier"""
|
||||||
|
print("=" * 60)
|
||||||
|
print("🧪 TESTING ORCHESTRATOR INTEGRATION")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# Create components
|
||||||
|
data_provider = DataProvider()
|
||||||
|
executor = TradingExecutor()
|
||||||
|
orchestrator = TradingOrchestrator(data_provider=data_provider)
|
||||||
|
|
||||||
|
# Connect executor to orchestrator
|
||||||
|
orchestrator.set_trading_executor(executor)
|
||||||
|
|
||||||
|
# Set a test multiplier
|
||||||
|
executor.profitability_reward_multiplier = 1.5
|
||||||
|
|
||||||
|
# Test getting multiplier through orchestrator
|
||||||
|
multiplier = orchestrator.get_profitability_reward_multiplier()
|
||||||
|
print(f"Multiplier via orchestrator: {multiplier}")
|
||||||
|
print(f"✅ Orchestrator getter: {'PASS' if multiplier == 1.5 else 'FAIL'}")
|
||||||
|
|
||||||
|
# Test enhanced reward calculation
|
||||||
|
base_pnl = 100.0 # $100 profit
|
||||||
|
confidence = 0.8
|
||||||
|
|
||||||
|
enhanced_reward = orchestrator.calculate_enhanced_reward(base_pnl, confidence)
|
||||||
|
expected_enhanced = base_pnl * (1.0 + 1.5) # 100 * 2.5 = 250
|
||||||
|
|
||||||
|
print(f"Base P&L: ${base_pnl:.2f}")
|
||||||
|
print(f"Enhanced reward: ${enhanced_reward:.2f}")
|
||||||
|
print(f"Expected: ${expected_enhanced:.2f}")
|
||||||
|
print(f"✅ Enhanced reward: {'PASS' if abs(enhanced_reward - expected_enhanced) < 0.01 else 'FAIL'}")
|
||||||
|
|
||||||
|
# Test with losing trade (should not be enhanced)
|
||||||
|
losing_pnl = -50.0
|
||||||
|
enhanced_losing = orchestrator.calculate_enhanced_reward(losing_pnl, confidence)
|
||||||
|
print(f"Losing P&L: ${losing_pnl:.2f}")
|
||||||
|
print(f"Enhanced losing: ${enhanced_losing:.2f}")
|
||||||
|
print(f"✅ No enhancement for losses: {'PASS' if enhanced_losing == losing_pnl else 'FAIL'}")
|
||||||
|
|
||||||
|
return multiplier == 1.5 and abs(enhanced_reward - expected_enhanced) < 0.01
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Run all tests"""
|
||||||
|
print("🚀 DYNAMIC PROFITABILITY REWARD SYSTEM TEST")
|
||||||
|
print("Testing fee reversion and dynamic reward adjustment")
|
||||||
|
print()
|
||||||
|
|
||||||
|
all_tests_passed = True
|
||||||
|
|
||||||
|
# Test 1: Fee configuration
|
||||||
|
try:
|
||||||
|
fee_test_passed = test_fee_configuration()
|
||||||
|
all_tests_passed = all_tests_passed and fee_test_passed
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fee configuration test failed: {e}")
|
||||||
|
all_tests_passed = False
|
||||||
|
|
||||||
|
# Test 2: Profitability multiplier initialization
|
||||||
|
try:
|
||||||
|
init_test_passed = test_profitability_multiplier_initialization()
|
||||||
|
all_tests_passed = all_tests_passed and init_test_passed
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Initialization test failed: {e}")
|
||||||
|
all_tests_passed = False
|
||||||
|
|
||||||
|
# Test 3: Multiplier adjustment scenarios
|
||||||
|
print("=" * 60)
|
||||||
|
print("🧪 TESTING MULTIPLIER ADJUSTMENT SCENARIOS")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
executor = TradingExecutor()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Scenario 1: High success rate (should increase multiplier)
|
||||||
|
print("Scenario 1: High success rate (65% - should increase)")
|
||||||
|
high_success_test = simulate_trades_and_test_adjustment(executor, 13, 20) # 65%
|
||||||
|
all_tests_passed = all_tests_passed and high_success_test
|
||||||
|
|
||||||
|
# Scenario 2: Low success rate (should decrease multiplier)
|
||||||
|
print("Scenario 2: Low success rate (45% - should decrease)")
|
||||||
|
low_success_test = simulate_trades_and_test_adjustment(executor, 9, 20) # 45%
|
||||||
|
all_tests_passed = all_tests_passed and low_success_test
|
||||||
|
|
||||||
|
# Scenario 3: Medium success rate (should not change)
|
||||||
|
print("Scenario 3: Medium success rate (55% - should not change)")
|
||||||
|
medium_success_test = simulate_trades_and_test_adjustment(executor, 11, 20) # 55%
|
||||||
|
all_tests_passed = all_tests_passed and medium_success_test
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Adjustment scenario tests failed: {e}")
|
||||||
|
all_tests_passed = False
|
||||||
|
|
||||||
|
# Test 4: Orchestrator integration
|
||||||
|
try:
|
||||||
|
orchestrator_test_passed = test_orchestrator_integration()
|
||||||
|
all_tests_passed = all_tests_passed and orchestrator_test_passed
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Orchestrator integration test failed: {e}")
|
||||||
|
all_tests_passed = False
|
||||||
|
|
||||||
|
# Final results
|
||||||
|
print("=" * 60)
|
||||||
|
print("📋 TEST RESULTS SUMMARY")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
if all_tests_passed:
|
||||||
|
print("🎉 ALL TESTS PASSED!")
|
||||||
|
print("✅ Fees reverted to normal 0.1%")
|
||||||
|
print("✅ Dynamic profitability multiplier working")
|
||||||
|
print("✅ Success rate calculation accurate")
|
||||||
|
print("✅ Orchestrator integration functional")
|
||||||
|
print()
|
||||||
|
print("🚀 System ready for trading with dynamic profitability rewards!")
|
||||||
|
print("📈 The model will learn to prioritize more profitable trades over time")
|
||||||
|
print("🎯 Success rate >60% → increase reward multiplier")
|
||||||
|
print("⚠️ Success rate <51% → decrease reward multiplier")
|
||||||
|
else:
|
||||||
|
print("❌ SOME TESTS FAILED!")
|
||||||
|
print("Please check the error messages above and fix issues before trading.")
|
||||||
|
|
||||||
|
return all_tests_passed
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
success = main()
|
||||||
|
sys.exit(0 if success else 1)
|
@ -496,6 +496,7 @@ class CleanTradingDashboard:
|
|||||||
Output('current-position', 'children'),
|
Output('current-position', 'children'),
|
||||||
Output('trade-count', 'children'),
|
Output('trade-count', 'children'),
|
||||||
Output('portfolio-value', 'children'),
|
Output('portfolio-value', 'children'),
|
||||||
|
Output('profitability-multiplier', 'children'),
|
||||||
Output('mexc-status', 'children')],
|
Output('mexc-status', 'children')],
|
||||||
[Input('interval-component', 'n_intervals')]
|
[Input('interval-component', 'n_intervals')]
|
||||||
)
|
)
|
||||||
@ -600,6 +601,20 @@ class CleanTradingDashboard:
|
|||||||
portfolio_value = current_balance + total_session_pnl # Live balance + unrealized P&L
|
portfolio_value = current_balance + total_session_pnl # Live balance + unrealized P&L
|
||||||
portfolio_str = f"${portfolio_value:.2f}"
|
portfolio_str = f"${portfolio_value:.2f}"
|
||||||
|
|
||||||
|
# Profitability multiplier - get from trading executor
|
||||||
|
profitability_multiplier = 0.0
|
||||||
|
success_rate = 0.0
|
||||||
|
if self.trading_executor and hasattr(self.trading_executor, 'get_profitability_reward_multiplier'):
|
||||||
|
profitability_multiplier = self.trading_executor.get_profitability_reward_multiplier()
|
||||||
|
if hasattr(self.trading_executor, '_calculate_recent_success_rate'):
|
||||||
|
success_rate = self.trading_executor._calculate_recent_success_rate()
|
||||||
|
|
||||||
|
# Format profitability multiplier display
|
||||||
|
if profitability_multiplier > 0:
|
||||||
|
multiplier_str = f"+{profitability_multiplier:.1f}x ({success_rate:.0%})"
|
||||||
|
else:
|
||||||
|
multiplier_str = f"0.0x ({success_rate:.0%})" if success_rate > 0 else "0.0x"
|
||||||
|
|
||||||
# MEXC status - enhanced with sync status
|
# MEXC status - enhanced with sync status
|
||||||
mexc_status = "SIM"
|
mexc_status = "SIM"
|
||||||
if self.trading_executor:
|
if self.trading_executor:
|
||||||
@ -607,11 +622,11 @@ class CleanTradingDashboard:
|
|||||||
if hasattr(self.trading_executor, 'simulation_mode') and not self.trading_executor.simulation_mode:
|
if hasattr(self.trading_executor, 'simulation_mode') and not self.trading_executor.simulation_mode:
|
||||||
mexc_status = "LIVE+SYNC" # Indicate live trading with position sync
|
mexc_status = "LIVE+SYNC" # Indicate live trading with position sync
|
||||||
|
|
||||||
return price_str, session_pnl_str, position_str, trade_str, portfolio_str, mexc_status
|
return price_str, session_pnl_str, position_str, trade_str, portfolio_str, multiplier_str, mexc_status
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error updating metrics: {e}")
|
logger.error(f"Error updating metrics: {e}")
|
||||||
return "Error", "$0.00", "Error", "0", "$100.00", "ERROR"
|
return "Error", "$0.00", "Error", "0", "$100.00", "0.0x", "ERROR"
|
||||||
|
|
||||||
@self.app.callback(
|
@self.app.callback(
|
||||||
Output('recent-decisions', 'children'),
|
Output('recent-decisions', 'children'),
|
||||||
|
@ -93,6 +93,7 @@ class DashboardLayoutManager:
|
|||||||
# ("leverage-info", "Leverage", "text-primary"),
|
# ("leverage-info", "Leverage", "text-primary"),
|
||||||
("trade-count", "Trades", "text-warning"),
|
("trade-count", "Trades", "text-warning"),
|
||||||
("portfolio-value", "Portfolio", "text-secondary"),
|
("portfolio-value", "Portfolio", "text-secondary"),
|
||||||
|
("profitability-multiplier", "Profit Boost", "text-primary"),
|
||||||
("mexc-status", f"{exchange_name} API", "text-info")
|
("mexc-status", f"{exchange_name} API", "text-info")
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user