|
| 1 | +""" |
| 2 | +Analyze if the 26 winners are truly unique strategies |
| 3 | +""" |
| 4 | + |
| 5 | +import json |
| 6 | +import os |
| 7 | +from collections import defaultdict |
| 8 | + |
| 9 | +WINNERS_DIR = 'src/data/rbi_auto/winners/' |
| 10 | + |
| 11 | +# Load all winners |
| 12 | +winners = [] |
| 13 | +for filename in os.listdir(WINNERS_DIR): |
| 14 | + if filename.endswith('.json'): |
| 15 | + with open(os.path.join(WINNERS_DIR, filename), 'r') as f: |
| 16 | + winner = json.load(f) |
| 17 | + winners.append(winner) |
| 18 | + |
| 19 | +print("=" * 90) |
| 20 | +print("🔍 WINNER STRATEGY UNIQUENESS ANALYSIS") |
| 21 | +print("=" * 90) |
| 22 | +print(f"\nTotal winner files: {len(winners)}") |
| 23 | + |
| 24 | +# Create unique signature for each strategy |
| 25 | +unique_configs = {} |
| 26 | +duplicates = defaultdict(list) |
| 27 | + |
| 28 | +for winner in winners: |
| 29 | + strat = winner['strategy'] |
| 30 | + |
| 31 | + # Create signature from key parameters |
| 32 | + signature = ( |
| 33 | + strat.get('fast_ma'), |
| 34 | + strat.get('slow_ma'), |
| 35 | + strat.get('use_ema'), |
| 36 | + strat.get('leverage'), |
| 37 | + strat.get('stop_loss_pct'), |
| 38 | + strat.get('take_profit_pct'), |
| 39 | + strat.get('rsi_min'), |
| 40 | + strat.get('use_volume'), |
| 41 | + strat.get('volume_mult'), |
| 42 | + ) |
| 43 | + |
| 44 | + config_str = f"MA {strat.get('fast_ma')}/{strat.get('slow_ma')} {'EMA' if strat.get('use_ema') else 'SMA'} | " \ |
| 45 | + f"Lev {strat.get('leverage')}x | RSI >{strat.get('rsi_min')} | " \ |
| 46 | + f"Vol {strat.get('volume_mult')}x" if strat.get('use_volume') else "NoVol" |
| 47 | + |
| 48 | + if signature in unique_configs: |
| 49 | + duplicates[signature].append({ |
| 50 | + 'name': strat.get('name'), |
| 51 | + 'return': winner['results']['return'], |
| 52 | + 'config': config_str |
| 53 | + }) |
| 54 | + else: |
| 55 | + unique_configs[signature] = { |
| 56 | + 'name': strat.get('name'), |
| 57 | + 'return': winner['results']['return'], |
| 58 | + 'max_dd': winner['results']['max_dd'], |
| 59 | + 'sharpe': winner['results']['sharpe'], |
| 60 | + 'config': config_str, |
| 61 | + 'full_config': strat |
| 62 | + } |
| 63 | + |
| 64 | +print(f"\n✅ Truly unique strategies: {len(unique_configs)}") |
| 65 | +print(f"❌ Duplicate configurations: {len(duplicates)}") |
| 66 | + |
| 67 | +if duplicates: |
| 68 | + print(f"\n{'='*90}") |
| 69 | + print("DUPLICATE CONFIGURATIONS FOUND") |
| 70 | + print(f"{'='*90}\n") |
| 71 | + |
| 72 | + for signature, dups in duplicates.items(): |
| 73 | + config = unique_configs.get(signature) |
| 74 | + if config: |
| 75 | + print(f"Configuration: {config['config']}") |
| 76 | + print(f" Original: {config['name']} - {config['return']:.2f}%") |
| 77 | + for dup in dups: |
| 78 | + print(f" Duplicate: {dup['name']} - {dup['return']:.2f}%") |
| 79 | + print() |
| 80 | + |
| 81 | +print(f"\n{'='*90}") |
| 82 | +print("UNIQUE STRATEGIES") |
| 83 | +print(f"{'='*90}\n") |
| 84 | + |
| 85 | +# Sort by return |
| 86 | +sorted_unique = sorted(unique_configs.values(), key=lambda x: x['return'], reverse=True) |
| 87 | + |
| 88 | +print(f"{'Rank':<6} {'Return':<10} {'MaxDD':<10} {'Sharpe':<8} {'Configuration':<60}") |
| 89 | +print("-" * 90) |
| 90 | + |
| 91 | +for rank, strat in enumerate(sorted_unique, 1): |
| 92 | + print(f"#{rank:<5} {strat['return']:>7.2f}% {strat['max_dd']:>8.2f}% {strat['sharpe']:>6.2f} {strat['config']}") |
| 93 | + |
| 94 | +print(f"\n{'='*90}") |
| 95 | +print("SUMMARY") |
| 96 | +print(f"{'='*90}\n") |
| 97 | + |
| 98 | +print(f"Total files: {len(winners)}") |
| 99 | +print(f"Unique strategies: {len(unique_configs)}") |
| 100 | +print(f"Duplicates: {len(winners) - len(unique_configs)}") |
| 101 | + |
| 102 | +if len(unique_configs) < len(winners): |
| 103 | + pct_unique = (len(unique_configs) / len(winners)) * 100 |
| 104 | + print(f"\nPercentage unique: {pct_unique:.1f}%") |
| 105 | + print(f"\n⚠️ The system generated variations around successful configurations,") |
| 106 | + print(f" resulting in some identical parameter sets.") |
| 107 | +else: |
| 108 | + print(f"\n✅ All 26 strategies are unique!") |
| 109 | + |
| 110 | +print(f"\n{'='*90}\n") |
0 commit comments