Files
gogo2/test_profitability_reward_system.py
2025-07-20 18:08:37 +03:00

294 lines
11 KiB
Python

#!/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)