David Chan Mun POON (SG) commited on
Commit
2d12f96
·
1 Parent(s): 21fa768

feat: add absorption/scalper to vision analysis + show advanced summary in screenshot mode

Browse files
Files changed (2) hide show
  1. app.py +3 -0
  2. src/ai_analyst.py +38 -2
app.py CHANGED
@@ -441,7 +441,10 @@ else:
441
  image_bytes=image_bytes,
442
  provider=ai_provider,
443
  timeframe=tf_label,
 
 
444
  )
 
445
  _display_ai_result(ai_result, ai_provider)
446
  else:
447
  if st.button(f"Analyze {ticker}", key=f"ai_{ticker}"):
 
441
  image_bytes=image_bytes,
442
  provider=ai_provider,
443
  timeframe=tf_label,
444
+ absorption=r.get("absorption"),
445
+ scalper=r.get("scalper"),
446
  )
447
+ _show_advanced_summary(r.get("absorption", {}), r.get("scalper", {}))
448
  _display_ai_result(ai_result, ai_provider)
449
  else:
450
  if st.button(f"Analyze {ticker}", key=f"ai_{ticker}"):
src/ai_analyst.py CHANGED
@@ -274,17 +274,24 @@ def _call_huggingface(prompt: str) -> str:
274
  VISION_PROMPT = """You are an expert technical analyst. You have been given:
275
  1. A chart screenshot to visually analyze
276
  2. Pre-computed indicator data from a live scanner
 
277
 
278
  Combine BOTH the visual chart patterns you see AND the indicator data to provide a comprehensive analysis.
279
 
280
  **Live Scanner Data:**
281
  {scanner_data}
282
 
 
 
 
283
  **Instructions:**
284
  - Identify visual patterns (support/resistance lines, chart patterns, candlestick formations)
285
  - Confirm or contradict the scanner's indicator readings with what you see on the chart
286
  - Look for things the scanner can't detect: trendlines, channels, divergences, volume profile
287
- - Provide specific entry, stop loss, and target prices
 
 
 
288
 
289
  **Respond in this exact JSON format (NO comments):**
290
  ```json
@@ -311,6 +318,8 @@ def analyze_with_screenshot(
311
  image_bytes: bytes,
312
  provider: str = "google",
313
  timeframe: str = "Daily",
 
 
314
  ) -> dict:
315
  """Analyze a ticker using both live data AND a chart screenshot (vision)."""
316
  import base64
@@ -327,7 +336,34 @@ def analyze_with_screenshot(
327
  f"Confluence Score: {score}/10 | Timeframe: {timeframe}"
328
  )
329
 
330
- prompt = VISION_PROMPT.format(scanner_data=scanner_data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
 
332
  # Encode image
333
  b64_image = base64.b64encode(image_bytes).decode("utf-8")
 
274
  VISION_PROMPT = """You are an expert technical analyst. You have been given:
275
  1. A chart screenshot to visually analyze
276
  2. Pre-computed indicator data from a live scanner
277
+ 3. Advanced indicator signals (Absorption Bubbles + Pro Scalper)
278
 
279
  Combine BOTH the visual chart patterns you see AND the indicator data to provide a comprehensive analysis.
280
 
281
  **Live Scanner Data:**
282
  {scanner_data}
283
 
284
+ **Advanced Indicators:**
285
+ {advanced_data}
286
+
287
  **Instructions:**
288
  - Identify visual patterns (support/resistance lines, chart patterns, candlestick formations)
289
  - Confirm or contradict the scanner's indicator readings with what you see on the chart
290
  - Look for things the scanner can't detect: trendlines, channels, divergences, volume profile
291
+ - Use Absorption Bubbles data to identify support/resistance zones where volume was absorbed
292
+ - Use Pro Scalper signal to confirm trend direction and overbought/oversold zones
293
+ - CRITICAL: entry_price must NOT be the current price. Use EMA pullback levels, absorption zones, or visual support/resistance from the chart
294
+ - Provide specific entry, stop loss, and target prices based on chart levels + indicator data
295
 
296
  **Respond in this exact JSON format (NO comments):**
297
  ```json
 
318
  image_bytes: bytes,
319
  provider: str = "google",
320
  timeframe: str = "Daily",
321
+ absorption: dict = None,
322
+ scalper: dict = None,
323
  ) -> dict:
324
  """Analyze a ticker using both live data AND a chart screenshot (vision)."""
325
  import base64
 
336
  f"Confluence Score: {score}/10 | Timeframe: {timeframe}"
337
  )
338
 
339
+ # Build advanced indicators summary
340
+ advanced_parts = []
341
+ if absorption:
342
+ abs_detected = absorption.get("absorption_detected", False)
343
+ abs_score = absorption.get("absorption_score", 0)
344
+ abs_bias = absorption.get("signal_bias", "neutral")
345
+ abs_events = absorption.get("events", [])
346
+ if abs_detected or abs_score > 0:
347
+ advanced_parts.append(
348
+ f"Absorption Bubbles: {abs_bias.title()} (score: {abs_score}), "
349
+ f"Events: {', '.join(abs_events) if abs_events else 'none'}"
350
+ )
351
+ else:
352
+ advanced_parts.append("Absorption Bubbles: No significant absorption detected")
353
+ if scalper:
354
+ sc_signal = scalper.get("signal", "neutral")
355
+ sc_conf = scalper.get("confidence", 0)
356
+ sc_dir = scalper.get("direction", "neutral")
357
+ sc_zone = scalper.get("zone", "neutral")
358
+ sc_reversal = scalper.get("reversal")
359
+ sc_str = f"Pro Scalper: {sc_signal.upper()} (confidence: {int(sc_conf*100)}%), Direction: {sc_dir}, Zone: {sc_zone}"
360
+ if sc_reversal:
361
+ sc_str += f", Reversal: {sc_reversal.replace('_', ' ')}"
362
+ advanced_parts.append(sc_str)
363
+
364
+ advanced_data = "\n".join(advanced_parts) if advanced_parts else "No advanced indicator data available"
365
+
366
+ prompt = VISION_PROMPT.format(scanner_data=scanner_data, advanced_data=advanced_data)
367
 
368
  # Encode image
369
  b64_image = base64.b64encode(image_bytes).decode("utf-8")