AJAY KASU commited on
Commit
247775e
·
1 Parent(s): 939a045

Fix: Robust Regex for Sentiment Guard

Browse files
.DS_Store CHANGED
Binary files a/.DS_Store and b/.DS_Store differ
 
README.md CHANGED
@@ -128,3 +128,5 @@ graph TD
128
  <!-- Deployed Check 3: Fri Feb 6 10:18:09 EST 2026 -->
129
 
130
  # Force Rebuild: Thu Feb 12 19:43:51 EST 2026
 
 
 
128
  <!-- Deployed Check 3: Fri Feb 6 10:18:09 EST 2026 -->
129
 
130
  # Force Rebuild: Thu Feb 12 19:43:51 EST 2026
131
+
132
+ # Force Rebuild: Thu Feb 12 19:46:23 EST 2026
__pycache__/config.cpython-39.pyc CHANGED
Binary files a/__pycache__/config.cpython-39.pyc and b/__pycache__/config.cpython-39.pyc differ
 
__pycache__/main.cpython-39.pyc ADDED
Binary file (4.1 kB). View file
 
ai/__pycache__/ai_reporter.cpython-39.pyc CHANGED
Binary files a/ai/__pycache__/ai_reporter.cpython-39.pyc and b/ai/__pycache__/ai_reporter.cpython-39.pyc differ
 
ai/__pycache__/prompts.cpython-39.pyc CHANGED
Binary files a/ai/__pycache__/prompts.cpython-39.pyc and b/ai/__pycache__/prompts.cpython-39.pyc differ
 
analytics/__pycache__/attribution.cpython-39.pyc CHANGED
Binary files a/analytics/__pycache__/attribution.cpython-39.pyc and b/analytics/__pycache__/attribution.cpython-39.pyc differ
 
api/__pycache__/app.cpython-39.pyc ADDED
Binary file (1.75 kB). View file
 
api/static/index.html CHANGED
@@ -426,13 +426,9 @@
426
  for (const [sector, keywords] of Object.entries(sectorKeywords)) {
427
  if (keywords.some(k => lowerInput.includes(k))) {
428
  // SENTIMENT GUARD: Check if the user specifically asked to KEEP this sector
429
- const isKept = includeKeywords.some(inc =>
430
- lowerInput.includes(`${inc} the ${sector.toLowerCase()}`) ||
431
- lowerInput.includes(`${inc} ${sector.toLowerCase()}`) ||
432
- // Check for common short nicknames like "tech"
433
- keywords.some(key => lowerInput.includes(`${inc} the ${key}`)) ||
434
- keywords.some(key => lowerInput.includes(`${inc} ${key}`))
435
- );
436
 
437
  if (!isKept) {
438
  excluded.push(sector);
@@ -445,12 +441,8 @@
445
  // Check Tickers
446
  for (const [ticker, keywords] of Object.entries(stockKeywords)) {
447
  if (keywords.some(k => lowerInput.includes(k))) {
448
- const isKept = includeKeywords.some(inc =>
449
- lowerInput.includes(`${inc} the ${ticker.toLowerCase()}`) ||
450
- lowerInput.includes(`${inc} ${ticker.toLowerCase()}`) ||
451
- keywords.some(key => lowerInput.includes(`${inc} the ${key}`)) ||
452
- keywords.some(key => lowerInput.includes(`${inc} ${key}`))
453
- );
454
 
455
  if (!isKept) {
456
  excludedTickers.push(ticker);
 
426
  for (const [sector, keywords] of Object.entries(sectorKeywords)) {
427
  if (keywords.some(k => lowerInput.includes(k))) {
428
  // SENTIMENT GUARD: Check if the user specifically asked to KEEP this sector
429
+ // Refined Regex to handle newlines (\s+) and "the"
430
+ const incPattern = new RegExp(`(${includeKeywords.join('|')})\\s+(the\\s+)?(${[sector, ...keywords].join('|')})`, 'i');
431
+ const isKept = incPattern.test(lowerInput);
 
 
 
 
432
 
433
  if (!isKept) {
434
  excluded.push(sector);
 
441
  // Check Tickers
442
  for (const [ticker, keywords] of Object.entries(stockKeywords)) {
443
  if (keywords.some(k => lowerInput.includes(k))) {
444
+ const incPattern = new RegExp(`(${includeKeywords.join('|')})\\s+(the\\s+)?(${[ticker, ...keywords].join('|')})`, 'i');
445
+ const isKept = incPattern.test(lowerInput);
 
 
 
 
446
 
447
  if (!isKept) {
448
  excludedTickers.push(ticker);
core/__pycache__/schema.cpython-39.pyc CHANGED
Binary files a/core/__pycache__/schema.cpython-39.pyc and b/core/__pycache__/schema.cpython-39.pyc differ
 
data/__pycache__/data_manager.cpython-39.pyc CHANGED
Binary files a/data/__pycache__/data_manager.cpython-39.pyc and b/data/__pycache__/data_manager.cpython-39.pyc differ
 
data/__pycache__/optimizer.cpython-39.pyc CHANGED
Binary files a/data/__pycache__/optimizer.cpython-39.pyc and b/data/__pycache__/optimizer.cpython-39.pyc differ
 
data/market_cap_cache.json CHANGED
@@ -3,66 +3,66 @@
3
  "MSFT": 3100000000000.0,
4
  "NVDA": 2800000000000.0,
5
  "AVGO": 650000000000.0,
6
- "ADBE": 42384694525.49608,
7
- "CRM": 332720339691.098,
8
- "CSCO": 61874224046.67981,
9
- "AMD": 59106289019.057335,
10
- "INTC": 66577013521.18813,
11
  "AMZN": 1900000000000.0,
12
  "TSLA": 700000000000.0,
13
- "HD": 19368111931.893402,
14
- "MCD": 19454648254.100174,
15
- "NKE": 44525557135.20009,
16
- "LOW": 82611073939.0812,
17
- "SBUX": 277485568678.1106,
18
  "GOOGL": 2100000000000.0,
19
  "GOOG": 2100000000000.0,
20
  "META": 1200000000000.0,
21
- "NFLX": 12111892900.178375,
22
- "DIS": 345814130576.47894,
23
- "CMCSA": 55059824790.15329,
24
- "VZ": 86046893609.6006,
25
- "T": 72747203477.04614,
26
  "BRK-B": 900000000000.0,
27
  "JPM": 600000000000.0,
28
  "V": 550000000000.0,
29
- "MA": 65861563152.13996,
30
- "BAC": 214644152207.0726,
31
- "WFC": 26065846069.167625,
32
- "MS": 44125078832.28906,
33
- "GS": 305866763003.6593,
34
- "BLK": 29498682361.329647,
35
- "UNH": 83463957830.33588,
36
  "LLY": 800000000000.0,
37
- "JNJ": 42458213110.69444,
38
- "MRK": 20187483165.597073,
39
- "ABBV": 348023037636.62866,
40
- "PFE": 93012971548.51999,
41
- "AMGN": 73591140859.02563,
42
- "TMO": 81477700112.99718,
43
- "PG": 19144855626.819138,
44
- "COST": 63229050560.13275,
45
- "PEP": 26125770115.64057,
46
- "KO": 61709192627.2379,
47
  "WMT": 500000000000.0,
48
- "PM": 89202982618.90544,
49
  "XOM": 500000000000.0,
50
- "CVX": 311575553463.81396,
51
- "COP": 41972864310.211395,
52
- "SLB": 11845649877.082544,
53
- "EOG": 33207394291.77144,
54
- "MPC": 85798165689.38318,
55
- "LIN": 41904082582.88991,
56
- "SHW": 44829224034.26446,
57
- "FCX": 13395522317.62616,
58
- "CAT": 13979722126.510677,
59
- "UNP": 98730076232.17259,
60
- "GE": 22390164045.587906,
61
- "HON": 48722920437.00011,
62
- "NEE": 83607612972.46426,
63
- "DUK": 370932640109.1507,
64
- "SO": 65449510477.87339,
65
- "PLD": 359667289326.14886,
66
- "AMT": 83836563062.66002,
67
- "EQIX": 45350966765.38244
68
  }
 
3
  "MSFT": 3100000000000.0,
4
  "NVDA": 2800000000000.0,
5
  "AVGO": 650000000000.0,
6
+ "ADBE": 98685249194.80624,
7
+ "CRM": 176958988181.20627,
8
+ "CSCO": 79897335857.15396,
9
+ "AMD": 93870026870.40092,
10
+ "INTC": 140388808767.35385,
11
  "AMZN": 1900000000000.0,
12
  "TSLA": 700000000000.0,
13
+ "HD": 30553601374.409096,
14
+ "MCD": 210501902251.45813,
15
+ "NKE": 26859174131.30948,
16
+ "LOW": 63381814105.97686,
17
+ "SBUX": 260231034207.87015,
18
  "GOOGL": 2100000000000.0,
19
  "GOOG": 2100000000000.0,
20
  "META": 1200000000000.0,
21
+ "NFLX": 77557345691.41638,
22
+ "DIS": 129110732388.39822,
23
+ "CMCSA": 91995647200.45721,
24
+ "VZ": 60752893076.022736,
25
+ "T": 381105510903.90454,
26
  "BRK-B": 900000000000.0,
27
  "JPM": 600000000000.0,
28
  "V": 550000000000.0,
29
+ "MA": 69356004552.00458,
30
+ "BAC": 35355754382.54754,
31
+ "WFC": 85954657019.77243,
32
+ "MS": 140352226135.4272,
33
+ "GS": 24908031609.597923,
34
+ "BLK": 94669709991.03517,
35
+ "UNH": 58810098509.2966,
36
  "LLY": 800000000000.0,
37
+ "JNJ": 16760465913.343477,
38
+ "MRK": 88432365800.31184,
39
+ "ABBV": 87122670349.1162,
40
+ "PFE": 117520034589.25716,
41
+ "AMGN": 75816868090.95624,
42
+ "TMO": 13621928959.079372,
43
+ "PG": 385349678710.27545,
44
+ "COST": 323531585195.3025,
45
+ "PEP": 82893223095.88101,
46
+ "KO": 63998164429.44551,
47
  "WMT": 500000000000.0,
48
+ "PM": 51948253935.36545,
49
  "XOM": 500000000000.0,
50
+ "CVX": 31418882770.800144,
51
+ "COP": 74244167177.00555,
52
+ "SLB": 77075307143.2632,
53
+ "EOG": 172069907141.0196,
54
+ "MPC": 39545750520.08103,
55
+ "LIN": 129094943650.88142,
56
+ "SHW": 54744430101.96956,
57
+ "FCX": 92216991260.7321,
58
+ "CAT": 39092883594.19859,
59
+ "UNP": 34142698328.82819,
60
+ "GE": 391609766813.7217,
61
+ "HON": 45493892417.99228,
62
+ "NEE": 13158141261.2655,
63
+ "DUK": 52062666024.52597,
64
+ "SO": 46176393322.901566,
65
+ "PLD": 81097926720.10149,
66
+ "AMT": 181107409655.0327,
67
+ "EQIX": 72131494695.10237
68
  }
debug_attribution_logic.py CHANGED
@@ -48,12 +48,21 @@ def test_attribution_logic():
48
 
49
  msft = next((x for x in report.top_detractors if x['Ticker'] == 'MSFT'), None)
50
  if msft:
 
 
 
 
 
 
 
 
 
51
  if msft['Status'] == "Excluded" and float(msft['Active_Contribution']) < 0:
52
- print("\nSUCCESS: MSFT correctly identified as Excluded Detractor.")
53
  else:
54
- print(f"\nFAILURE: MSFT status/logic wrong: {msft}")
55
  else:
56
- print("\nFAILURE: MSFT not found in detractors.")
57
 
58
  # AAPL Active Weight = 0.05 - 0.04 = +0.01
59
  # AAPL Active Contrib = +0.01 * 0.10 = +0.001 (Contributor)
@@ -64,5 +73,18 @@ def test_attribution_logic():
64
  else:
65
  print(f"FAILURE: AAPL logic wrong. {aapl}")
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  if __name__ == "__main__":
68
  test_attribution_logic()
 
48
 
49
  msft = next((x for x in report.top_detractors if x['Ticker'] == 'MSFT'), None)
50
  if msft:
51
+ # Signage Logic Verification
52
+ # MSFT is Excluded and Return is +10%. This is BAD. Should be 'Drag' or 'Missed Rally'
53
+ print(f"MSFT Reasoning: {msft.get('Reasoning', 'N/A')}")
54
+
55
+ if "Drag" in msft.get('Reasoning', '') or "Missed" in msft.get('Reasoning', ''):
56
+ print("SUCCESS: MSFT correctly identified as Missed Rally (Drag).")
57
+ else:
58
+ print(f"FAILURE: MSFT reasoning wrong: {msft}")
59
+
60
  if msft['Status'] == "Excluded" and float(msft['Active_Contribution']) < 0:
61
+ print("SUCCESS: MSFT correctly identified as Excluded Detractor.")
62
  else:
63
+ print(f"FAILURE: MSFT status/logic wrong: {msft}")
64
  else:
65
+ print("FAILURE: MSFT not found in detractors.")
66
 
67
  # AAPL Active Weight = 0.05 - 0.04 = +0.01
68
  # AAPL Active Contrib = +0.01 * 0.10 = +0.001 (Contributor)
 
73
  else:
74
  print(f"FAILURE: AAPL logic wrong. {aapl}")
75
 
76
+ # VERIFICATION: Sector Exposure Truth Table
77
+ print("\n[Sector Exposure Truth Table]")
78
+ tech_exposure = next((x for x in report.sector_exposure if x['Sector'] == 'Technology'), None)
79
+ if tech_exposure:
80
+ print(f"Technology Exposure: {tech_exposure}")
81
+ # We hold AAPL (5%) vs Bench AAPL+MSFT (10%) -> Underweight
82
+ if tech_exposure['Status'] == "Underweight":
83
+ print("SUCCESS: Technology correctly identified as UNDERWEIGHT (not Excluded).")
84
+ else:
85
+ print(f"FAILURE: Technology status wrong: {tech_exposure['Status']}")
86
+ else:
87
+ print("FAILURE: Technology sector missing from report.")
88
+
89
  if __name__ == "__main__":
90
  test_attribution_logic()
debug_startup.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ from main import QuantScaleSystem
2
+ import time
3
+
4
+ print("Instantiating System...")
5
+ start = time.time()
6
+ try:
7
+ s = QuantScaleSystem()
8
+ print(f"Instantiation complete in {time.time() - start:.2f}s")
9
+ except Exception as e:
10
+ print(f"Instantiation failed: {e}")