GoshawkVortexAI commited on
Commit
714a018
·
verified ·
1 Parent(s): fb4d43c

Delete scorer.py

Browse files
Files changed (1) hide show
  1. scorer.py +0 -144
scorer.py DELETED
@@ -1,144 +0,0 @@
1
- """
2
- scorer.py — Multi-factor scoring with regime confidence as 4th dimension.
3
-
4
- Key fixes vs prior version:
5
- - WEIGHT_CONFIDENCE (0.15) added as explicit 4th score axis
6
- - Absorption hard-zeroes volume_score regardless of other signals
7
- - Failed breakout penalty applied at scoring level (defence in depth)
8
- - Structure score uses ADX to weight trend quality, not just HH/HL
9
- - format_score_bar returns richer display with quality tier label
10
- """
11
-
12
- from typing import Dict, Any, List, Tuple
13
-
14
- import numpy as np
15
-
16
- from config import (
17
- WEIGHT_REGIME,
18
- WEIGHT_VOLUME,
19
- WEIGHT_STRUCTURE,
20
- WEIGHT_CONFIDENCE,
21
- ADX_TREND_THRESHOLD,
22
- ADX_STRONG_THRESHOLD,
23
- REGIME_CONFIDENCE_MIN,
24
- )
25
-
26
-
27
- def compute_structure_score(regime_data: Dict[str, Any]) -> float:
28
- trend = regime_data.get("trend", "ranging")
29
- structure = regime_data.get("structure", 0)
30
- vol_expanding = regime_data.get("vol_expanding", False)
31
- vol_contracting = regime_data.get("vol_contracting", False)
32
- adx = regime_data.get("adx", 0.0)
33
- vol_expanding_from_base = regime_data.get("vol_expanding_from_base", False)
34
-
35
- if trend == "bullish":
36
- base = 0.75
37
- elif trend == "ranging":
38
- base = 0.35
39
- else:
40
- base = 0.10
41
-
42
- # ADX quality modifier
43
- if adx >= ADX_STRONG_THRESHOLD:
44
- base = min(1.0, base + 0.15)
45
- elif adx < ADX_TREND_THRESHOLD:
46
- base = max(0.0, base - 0.20)
47
-
48
- # Structure alignment
49
- if structure == 1 and trend == "bullish":
50
- base = min(1.0, base + 0.12)
51
- elif structure == -1 and trend == "bullish":
52
- base = max(0.0, base - 0.20)
53
- elif structure == -1 and trend == "bearish":
54
- base = min(1.0, base + 0.12)
55
-
56
- # Volatility context
57
- if vol_expanding_from_base:
58
- base = min(1.0, base + 0.08)
59
- if vol_expanding and not vol_expanding_from_base:
60
- base = max(0.0, base - 0.10)
61
- if vol_contracting:
62
- base = max(0.0, base - 0.05)
63
-
64
- return float(np.clip(base, 0.0, 1.0))
65
-
66
-
67
- def score_token(
68
- regime_data: Dict[str, Any],
69
- volume_data: Dict[str, Any],
70
- vetoed: bool,
71
- ) -> Dict[str, float]:
72
- if vetoed:
73
- return {
74
- "regime_score": 0.0,
75
- "volume_score": 0.0,
76
- "structure_score": 0.0,
77
- "confidence_score": 0.0,
78
- "total_score": 0.0,
79
- }
80
-
81
- regime_score = float(np.clip(regime_data.get("regime_score", 0.0), 0.0, 1.0))
82
- confidence_score = float(np.clip(regime_data.get("regime_confidence", 0.0), 0.0, 1.0))
83
- structure_score = compute_structure_score(regime_data)
84
-
85
- raw_volume_score = float(np.clip(volume_data.get("volume_score", 0.0), 0.0, 1.0))
86
-
87
- # Absorption hard-zeroes the volume signal regardless of other factors
88
- if volume_data.get("absorption", False):
89
- volume_score = 0.0
90
- elif volume_data.get("failed_breakout", False):
91
- # Failed breakout halves the volume score
92
- volume_score = raw_volume_score * 0.5
93
- else:
94
- volume_score = raw_volume_score
95
-
96
- # Climax penalty (not a veto here — defence in depth after veto layer)
97
- if volume_data.get("climax", False):
98
- volume_score = min(volume_score, 0.30)
99
-
100
- total_score = (
101
- regime_score * WEIGHT_REGIME
102
- + volume_score * WEIGHT_VOLUME
103
- + structure_score * WEIGHT_STRUCTURE
104
- + confidence_score * WEIGHT_CONFIDENCE
105
- )
106
-
107
- # Confidence multiplier: low confidence compresses total score
108
- if confidence_score < REGIME_CONFIDENCE_MIN:
109
- total_score *= confidence_score / REGIME_CONFIDENCE_MIN
110
-
111
- return {
112
- "regime_score": round(regime_score, 4),
113
- "volume_score": round(volume_score, 4),
114
- "structure_score": round(structure_score, 4),
115
- "confidence_score": round(confidence_score, 4),
116
- "total_score": round(float(np.clip(total_score, 0.0, 1.0)), 4),
117
- }
118
-
119
-
120
- def rank_tokens(scored_map: Dict[str, Dict[str, Any]]) -> List[Tuple[str, Dict[str, Any]]]:
121
- return sorted(
122
- scored_map.items(),
123
- key=lambda item: item[1].get("total_score", 0.0),
124
- reverse=True,
125
- )
126
-
127
-
128
- def quality_tier(score: float) -> str:
129
- if score >= 0.80:
130
- return "A+"
131
- if score >= 0.65:
132
- return "A"
133
- if score >= 0.50:
134
- return "B"
135
- if score >= 0.35:
136
- return "C"
137
- return "D"
138
-
139
-
140
- def format_score_bar(score: float, width: int = 18) -> str:
141
- filled = int(round(score * width))
142
- bar = "█" * filled + "░" * (width - filled)
143
- tier = quality_tier(score)
144
- return f"[{bar}] {score:.3f} ({tier})"