test_period_stats_consistency.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #!/usr/bin/env python3
  2. """
  3. Test script to verify period stats consistency (daily, weekly, monthly).
  4. This test ensures that the stats show consistent time periods regardless of trading activity.
  5. """
  6. import sys
  7. import os
  8. import tempfile
  9. from datetime import datetime, timedelta
  10. # Add src directory to path
  11. sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
  12. from src.stats import TradingStats
  13. def test_period_stats_consistency():
  14. """Test that period stats show consistent time periods."""
  15. # Create temporary stats file
  16. with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
  17. temp_file = f.name
  18. try:
  19. # Initialize TradingStats
  20. stats = TradingStats(temp_file)
  21. stats.set_initial_balance(10000.0)
  22. print("Testing Period Stats Consistency")
  23. print("=" * 40)
  24. # Test Case 1: No trades - should still show 10 periods
  25. print("\n1. Testing with no trades:")
  26. daily_stats = stats.get_daily_stats(10)
  27. weekly_stats = stats.get_weekly_stats(10)
  28. monthly_stats = stats.get_monthly_stats(10)
  29. print(f" Daily periods: {len(daily_stats)} (should be 10)")
  30. print(f" Weekly periods: {len(weekly_stats)} (should be 10)")
  31. print(f" Monthly periods: {len(monthly_stats)} (should be 10)")
  32. # Verify all periods have has_trades = False
  33. daily_no_trades = sum(1 for day in daily_stats if not day['has_trades'])
  34. weekly_no_trades = sum(1 for week in weekly_stats if not week['has_trades'])
  35. monthly_no_trades = sum(1 for month in monthly_stats if not month['has_trades'])
  36. print(f" Days with no trades: {daily_no_trades}/10")
  37. print(f" Weeks with no trades: {weekly_no_trades}/10")
  38. print(f" Months with no trades: {monthly_no_trades}/10")
  39. # Test Case 2: Add some trades on specific days
  40. print("\n2. Testing with selective trades:")
  41. # Add trade today
  42. today = datetime.now()
  43. stats.record_trade_with_enhanced_tracking("BTC/USDC", "buy", 0.1, 50000.0, "test1")
  44. stats.record_trade_with_enhanced_tracking("BTC/USDC", "sell", 0.1, 51000.0, "test2")
  45. # Add trade 3 days ago
  46. three_days_ago = today - timedelta(days=3)
  47. stats.record_trade_with_enhanced_tracking("ETH/USDC", "buy", 1.0, 3000.0, "test3")
  48. stats.record_trade_with_enhanced_tracking("ETH/USDC", "sell", 1.0, 3100.0, "test4")
  49. # Get updated stats
  50. daily_stats = stats.get_daily_stats(10)
  51. weekly_stats = stats.get_weekly_stats(10)
  52. monthly_stats = stats.get_monthly_stats(10)
  53. print(f" Daily periods: {len(daily_stats)} (should still be 10)")
  54. print(f" Weekly periods: {len(weekly_stats)} (should still be 10)")
  55. print(f" Monthly periods: {len(monthly_stats)} (should still be 10)")
  56. # Count periods with trades
  57. daily_with_trades = sum(1 for day in daily_stats if day['has_trades'])
  58. weekly_with_trades = sum(1 for week in weekly_stats if week['has_trades'])
  59. monthly_with_trades = sum(1 for month in monthly_stats if month['has_trades'])
  60. print(f" Days with trades: {daily_with_trades} (should be 2)")
  61. print(f" Weeks with trades: {weekly_with_trades}")
  62. print(f" Months with trades: {monthly_with_trades}")
  63. # Test Case 3: Check date consistency
  64. print("\n3. Testing date consistency:")
  65. today_str = datetime.now().strftime('%Y-%m-%d')
  66. # Today should be the first entry (index 0)
  67. if daily_stats[0]['date'] == today_str:
  68. print(f" ✅ Today ({today_str}) is first in daily stats")
  69. else:
  70. print(f" ❌ Today mismatch: expected {today_str}, got {daily_stats[0]['date']}")
  71. # Check that dates are consecutive going backwards
  72. dates_correct = True
  73. for i in range(1, len(daily_stats)):
  74. expected_date = (datetime.now().date() - timedelta(days=i)).strftime('%Y-%m-%d')
  75. if daily_stats[i]['date'] != expected_date:
  76. dates_correct = False
  77. print(f" ❌ Date mismatch at index {i}: expected {expected_date}, got {daily_stats[i]['date']}")
  78. break
  79. if dates_correct:
  80. print(f" ✅ All daily dates are consecutive and correct")
  81. # Test Case 4: Verify P&L calculations only for trading periods
  82. print("\n4. Testing P&L calculations:")
  83. total_pnl = 0
  84. trading_days = 0
  85. for day in daily_stats:
  86. if day['has_trades']:
  87. total_pnl += day['pnl']
  88. trading_days += 1
  89. print(f" Trading day {day['date_formatted']}: P&L ${day['pnl']:.2f}")
  90. else:
  91. # Should have zero P&L and zero trades
  92. if day['pnl'] == 0 and day['trades'] == 0:
  93. print(f" No-trade day {day['date_formatted']}: ✅ Correctly shows $0.00")
  94. else:
  95. print(f" No-trade day {day['date_formatted']}: ❌ Should show $0.00")
  96. print(f" Total P&L from trading days: ${total_pnl:.2f}")
  97. print(f" Trading days count: {trading_days}")
  98. print("\n✅ Period stats consistency test completed!")
  99. print("📊 All periods now show consistent time ranges")
  100. print("🎯 Days/weeks/months with no trades are properly displayed")
  101. return True
  102. except Exception as e:
  103. print(f"❌ Test failed: {e}")
  104. import traceback
  105. traceback.print_exc()
  106. return False
  107. finally:
  108. # Clean up temp file
  109. if os.path.exists(temp_file):
  110. os.unlink(temp_file)
  111. if __name__ == "__main__":
  112. success = test_period_stats_consistency()
  113. exit(0 if success else 1)