Spaces:
Running
Running
Khanna, Videh Rakesh Rakesh commited on
Commit Β·
04219e7
1
Parent(s): 74179a9
fix: load dotenv in ai_forecast, improve top5 5D scoring, harden HF repo IDs
Browse files- ai_forecast.py: add load_dotenv() so API keys load outside Flask context
(fixes 'AI unavailable' when running top5_picker/backtest directly)
- ai_forecast.py: add 401/403 error logging for GitHub Models + OpenRouter
so key/scope failures are visible in logs instead of silent debug drops
- top5_picker.py: replace confidence-tier sort with composite 5D profit score
(ret_hi Γ conf_mult Γ ml_factor Γ rr_factor Γ sector_factor)
- top5_picker.py: add min thresholds (ret_hi>1%, R:R>=1.2) to filter weak setups
- top5_picker.py: widen candidate pool to 2Γtop_n, re-rank after full debate run
- database.py: read HF_DATA_REPO_ID from env (default: V1deh/papertrade-data)
- app.py: use db._HF_REPO_ID instead of hardcoded string
- README.md +7 -0
- ai_forecast.py +207 -134
- app.py +130 -5
- data_sources.py +2 -2
- database.py +1 -1
- research/ai_prompt_accuracy.csv +26 -271
- research/ai_prompt_accuracy_new.csv.bak +0 -0
- research/loop_backtest.py +153 -122
- static/app.js +13 -2
- top5_picker.py +75 -11
README.md
CHANGED
|
@@ -11,3 +11,10 @@ app_port: 7860
|
|
| 11 |
# PaperTrade β NSE Indian Equity Prediction Engine
|
| 12 |
|
| 13 |
A paper trading system for NSE Indian equities. Predicts short-term price direction (1D/3D/5D) using backtested technical strategies, an ML feature scorer, macro gates, news sentiment, and an LLM-based directional forecast.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
# PaperTrade β NSE Indian Equity Prediction Engine
|
| 12 |
|
| 13 |
A paper trading system for NSE Indian equities. Predicts short-term price direction (1D/3D/5D) using backtested technical strategies, an ML feature scorer, macro gates, news sentiment, and an LLM-based directional forecast.
|
| 14 |
+
|
| 15 |
+
## Recent Reliability Improvements
|
| 16 |
+
|
| 17 |
+
- Manual trade entries now attempt a best-effort auto-scan at order time to populate missing strategy, timeframe, and prediction context.
|
| 18 |
+
- Post-mortems for manual trades now include concrete trade-window price diagnostics (swing, MFE, MAE, trend) to avoid generic commentary.
|
| 19 |
+
- Frontend trade submit now waits for in-flight watchlist context fetch before posting, reducing empty post-mortem context.
|
| 20 |
+
- Timeframe calibration in the AI forecast path was tightened to use shallow bearish midpoint ranges and safer weak-bear handling.
|
ai_forecast.py
CHANGED
|
@@ -27,6 +27,13 @@ from typing import Optional, Dict, Any, List
|
|
| 27 |
import requests
|
| 28 |
import pandas as pd
|
| 29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
logging.basicConfig(level=logging.INFO)
|
| 31 |
logger = logging.getLogger(__name__)
|
| 32 |
|
|
@@ -289,6 +296,7 @@ def _make_chat_call(
|
|
| 289 |
global _GITHUB_DISABLED_UNTIL # must be global β inner fn both reads and writes it
|
| 290 |
token = os.environ.get("GITHUB_TOKEN", "").strip()
|
| 291 |
if not token:
|
|
|
|
| 292 |
return None
|
| 293 |
with _LLM_LOCK:
|
| 294 |
if time.time() < _GITHUB_DISABLED_UNTIL:
|
|
@@ -309,10 +317,17 @@ def _make_chat_call(
|
|
| 309 |
_GITHUB_DISABLED_UNTIL = time.time() + cooldown
|
| 310 |
logger.warning("GitHub Models rate-limited (429) β falling through to OpenRouter")
|
| 311 |
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 312 |
if resp.status_code == 200:
|
| 313 |
content = (((resp.json().get("choices") or [{}])[0].get("message") or {}).get("content") or "").strip()
|
| 314 |
if content:
|
| 315 |
return content, "github", model
|
|
|
|
| 316 |
except RuntimeError:
|
| 317 |
raise
|
| 318 |
except Exception as e:
|
|
@@ -322,6 +337,7 @@ def _make_chat_call(
|
|
| 322 |
def _try_openrouter() -> tuple[str, str, str] | None:
|
| 323 |
api_key = os.environ.get("OPENROUTER_API_KEY", "").strip()
|
| 324 |
if not api_key:
|
|
|
|
| 325 |
return None
|
| 326 |
model = (os.environ.get("OPENROUTER_BEST_FREE_MODEL") or "openai/gpt-oss-120b:free").strip()
|
| 327 |
# Free-tier fallback chain β try alternate models on 429
|
|
@@ -341,6 +357,9 @@ def _make_chat_call(
|
|
| 341 |
logger.warning("OpenRouter rate-limited on %s (429) β trying next model", try_model)
|
| 342 |
time.sleep(2) # brief backoff before trying next model
|
| 343 |
continue
|
|
|
|
|
|
|
|
|
|
| 344 |
if resp.status_code in (404, 422):
|
| 345 |
logger.debug("OpenRouter model %s unavailable (%s) β trying next", try_model, resp.status_code)
|
| 346 |
continue
|
|
@@ -348,6 +367,9 @@ def _make_chat_call(
|
|
| 348 |
content = (((resp.json().get("choices") or [{}])[0].get("message") or {}).get("content") or "").strip()
|
| 349 |
if content:
|
| 350 |
return content, "openrouter", try_model
|
|
|
|
|
|
|
|
|
|
| 351 |
except Exception as e:
|
| 352 |
logger.debug("OpenRouter call failed for %s: %s", try_model, e)
|
| 353 |
return None
|
|
@@ -369,9 +391,9 @@ _JSON_REQUIRED = {"direction", "confidence", "predicted_return_lo", "predicted_r
|
|
| 369 |
#
|
| 370 |
# 1D BULLISH: mid = 0.25% (sweep-optimal; LLM output ~0.20% was suboptimal)
|
| 371 |
# 3D/5D BULLISH: mid = 0.10% (already LLM-optimal, keeps them identical)
|
| 372 |
-
# ALL BEARISH: mid = -0.
|
| 373 |
-
# β’
|
| 374 |
-
# β’
|
| 375 |
# ============================================================================
|
| 376 |
_BULL_RANGE: dict[str, tuple[float, float]] = {
|
| 377 |
"1D": (0.05, 0.45), # mid = 0.250% β empirically optimal for 1D
|
|
@@ -379,9 +401,9 @@ _BULL_RANGE: dict[str, tuple[float, float]] = {
|
|
| 379 |
"5D": (0.02, 0.18), # mid = 0.100% β unchanged, already optimal
|
| 380 |
}
|
| 381 |
_BEAR_RANGE: dict[str, tuple[float, float]] = {
|
| 382 |
-
"1D": (-0.
|
| 383 |
-
"3D": (-0.
|
| 384 |
-
"5D": (-0.
|
| 385 |
}
|
| 386 |
_NEUT_RANGE: dict[str, tuple[float, float]] = {
|
| 387 |
"1D": (-0.12, 0.12),
|
|
@@ -395,7 +417,7 @@ def _apply_calibrated_range(direction: str, tf_label: str) -> tuple[float, float
|
|
| 395 |
if direction == "BULLISH":
|
| 396 |
return _BULL_RANGE.get(tf_label, (0.02, 0.18))
|
| 397 |
if direction == "BEARISH":
|
| 398 |
-
return _BEAR_RANGE.get(tf_label, (-0.
|
| 399 |
return _NEUT_RANGE.get(tf_label, (-0.15, 0.15))
|
| 400 |
|
| 401 |
def _parse_json_from_llm(text: str) -> Dict | None:
|
|
@@ -434,6 +456,87 @@ def _parse_json_from_llm(text: str) -> Dict | None:
|
|
| 434 |
return parsed
|
| 435 |
|
| 436 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 437 |
# ============================================================================
|
| 438 |
# PROMPT BUILDERS
|
| 439 |
# ============================================================================
|
|
@@ -443,7 +546,12 @@ def _build_context_block(
|
|
| 443 |
ml: Dict, nifty_ok: bool, macro_ok: bool, vix_level: float,
|
| 444 |
news: Dict, indicators: Dict, mode_c_active: bool,
|
| 445 |
vix_declining: bool, market_breadth: Dict, fii_pcr: Dict,
|
|
|
|
| 446 |
) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 447 |
lines = [
|
| 448 |
f"STOCK: {ticker} ({company}) | TIMEFRAME: {tf_label}",
|
| 449 |
f"MARKET: VIX {vix_level:.1f} ({'declining β' if vix_declining else 'rising β'}) "
|
|
@@ -455,29 +563,46 @@ def _build_context_block(
|
|
| 455 |
lines.append(f"ML SCORE: {ml.get('score', 50)}/100 prob={ml.get('probability', 0.5):.2f}"
|
| 456 |
+ (" [UPGRADED]" if ml.get("upgraded") else ""))
|
| 457 |
if indicators:
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 465 |
lines.append("TECHNICALS:")
|
| 466 |
if p:
|
| 467 |
-
lines.append(f" Price: βΉ{p:.
|
| 468 |
-
if
|
| 469 |
-
|
| 470 |
-
|
| 471 |
-
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
|
| 475 |
-
|
| 476 |
-
lines.append(f"
|
| 477 |
-
if
|
| 478 |
-
|
| 479 |
-
|
| 480 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 481 |
if news and news.get("label"):
|
| 482 |
lines.append(f"NEWS: {news['label']} score={news.get('score', 0)}"
|
| 483 |
+ (f" β {news['summary']}" if news.get("summary") else ""))
|
|
@@ -554,82 +679,74 @@ def _build_synthesis_prompt(
|
|
| 554 |
_cap_pct = {"1D": 4.0, "3D": 7.0, "5D": 12.0}.get(tf_label, 7.0)
|
| 555 |
holding = {"1D": "1 trading day", "3D": "3 trading days", "5D": "5 trading days"}.get(tf_label, "3 trading days")
|
| 556 |
|
| 557 |
-
#
|
| 558 |
-
# ALL TFs: BULLISH midpoint = +0.22% (1D) / +0.10% (3D/5D)
|
| 559 |
-
# BEARISH midpoint = -0.10% (ALL TFs β data-verified optimal, do NOT go more negative)
|
| 560 |
-
# Ranges below centre on those midpoints. LLM MUST NOT deviate from BEARISH midpoint.
|
| 561 |
tf_guidance = {
|
| 562 |
"1D": (
|
| 563 |
-
"
|
| 564 |
-
"- RSI, MACD
|
| 565 |
-
"-
|
| 566 |
-
"
|
| 567 |
-
"
|
| 568 |
-
" NEUTRAL: predicted_return_lo=-0.12, predicted_return_hi=0.12\n"
|
| 569 |
-
"- YOUR MAIN JOB: Choose the correct DIRECTION (BULLISH/BEARISH/NEUTRAL) and CONFIDENCE.\n"
|
| 570 |
-
"- BEARISH requires ALL of: RSI > 68 AND (below EMA50 OR (MACD < 0 AND below EMA200))\n"
|
| 571 |
-
"- When RSI < 45 (oversold) OR stock is above EMA50 with positive MACD: choose BULLISH.\n"
|
| 572 |
),
|
| 573 |
"3D": (
|
| 574 |
-
"
|
| 575 |
-
"-
|
| 576 |
-
"-
|
| 577 |
-
"
|
| 578 |
-
"
|
| 579 |
-
" NEUTRAL: predicted_return_lo=-0.18, predicted_return_hi=0.18\n"
|
| 580 |
-
"- YOUR MAIN JOB: Choose the correct DIRECTION (BULLISH/BEARISH/NEUTRAL) and CONFIDENCE.\n"
|
| 581 |
-
"- BEARISH requires ALL of: RSI > 68 AND (below EMA50 OR (MACD < 0 AND below EMA200))\n"
|
| 582 |
-
"- When RSI < 45 OR above EMA50 with positive MACD: choose BULLISH.\n"
|
| 583 |
),
|
| 584 |
"5D": (
|
| 585 |
-
"
|
| 586 |
-
"- EMA200 trend
|
| 587 |
-
"-
|
| 588 |
-
"
|
| 589 |
-
"
|
| 590 |
-
" NEUTRAL: predicted_return_lo=-0.25, predicted_return_hi=0.25\n"
|
| 591 |
-
"- YOUR MAIN JOB: Choose the correct DIRECTION (BULLISH/BEARISH/NEUTRAL) and CONFIDENCE.\n"
|
| 592 |
-
"- BEARISH requires ALL of: RSI > 68 AND (below EMA50 OR (MACD < 0 AND below EMA200))\n"
|
| 593 |
-
"- EMA200 trend overrides short-term momentum for 5D horizon.\n"
|
| 594 |
),
|
| 595 |
}.get(tf_label, "")
|
| 596 |
|
| 597 |
-
|
| 598 |
-
|
| 599 |
-
|
| 600 |
-
"
|
| 601 |
-
"-
|
| 602 |
-
"-
|
| 603 |
-
"-
|
| 604 |
-
"- When
|
| 605 |
-
"-
|
| 606 |
-
"-
|
|
|
|
| 607 |
)
|
| 608 |
|
|
|
|
|
|
|
| 609 |
return (
|
| 610 |
f"You are Head of Research at an Indian equity trading desk. "
|
| 611 |
-
f"Synthesize
|
| 612 |
-
f"
|
|
|
|
|
|
|
| 613 |
f"{ctx}\n\n"
|
| 614 |
f"BULL ANALYST VIEW:\n{bull_view}\n\n"
|
| 615 |
f"BEAR ANALYST VIEW:\n{bear_view}"
|
| 616 |
f"{fund_section}\n\n"
|
| 617 |
f"{tf_guidance}\n"
|
| 618 |
-
f"{
|
| 619 |
-
f"ATR(14): βΉ{atr14:.2f} Current price: βΉ{current_price:.2f}
|
| 620 |
-
f"Hard cap: Β±{_cap_pct}% for
|
|
|
|
|
|
|
|
|
|
| 621 |
f"Respond with ONLY a valid JSON object β no markdown, no extra text:\n"
|
| 622 |
f'{{"direction": "BULLISH"|"BEARISH"|"NEUTRAL", '
|
| 623 |
f'"confidence": "HIGH"|"MEDIUM"|"LOW", '
|
| 624 |
-
f'"predicted_return_lo": <
|
| 625 |
-
f'"predicted_return_hi": <
|
| 626 |
-
f'"reasoning": "<1
|
| 627 |
-
f"
|
| 628 |
-
f"- BULLISH:
|
| 629 |
-
f"- BEARISH:
|
| 630 |
-
f"
|
| 631 |
-
f"-
|
| 632 |
-
f"- Do not exceed Β±{_cap_pct}% absolute value\n"
|
| 633 |
)
|
| 634 |
|
| 635 |
|
|
@@ -670,7 +787,7 @@ def get_ai_forecast(
|
|
| 670 |
vix_level = float(args[6]) if len(args) >= 7 and isinstance(args[6], (int,float)) else float(kwargs.get("vix_level", 15.0))
|
| 671 |
news = args[7] if len(args) >= 8 and isinstance(args[7], dict) else kwargs.get("news", {})
|
| 672 |
current_price = float(kwargs.get("current_price", 0.0))
|
| 673 |
-
indicators = kwargs.get("indicators", {}) or {}
|
| 674 |
ohlcv_df = kwargs.get("ohlcv_df")
|
| 675 |
fundamentals = kwargs.get("fundamentals") or {}
|
| 676 |
mode_c_active = bool(kwargs.get("mode_c_active", False))
|
|
@@ -697,7 +814,6 @@ def get_ai_forecast(
|
|
| 697 |
move_anchor = _realized_move_anchor(ohlcv_df, tf_label, vol_pctile)
|
| 698 |
atr14 = float(indicators.get("atr14") or move_anchor * (current_price / 100) or 10.0)
|
| 699 |
news_score = int((news or {}).get("score", 0))
|
| 700 |
-
|
| 701 |
try:
|
| 702 |
# ββ Fetch social sentiment (Reddit/StockTwits, no API key needed) ββββββ
|
| 703 |
social_block = ""
|
|
@@ -713,6 +829,7 @@ def get_ai_forecast(
|
|
| 713 |
ml, nifty_ok, macro_ok, vix_level,
|
| 714 |
news, indicators, mode_c_active,
|
| 715 |
vix_declining, market_breadth, fii_pcr,
|
|
|
|
| 716 |
)
|
| 717 |
|
| 718 |
# ββ Fast-mode: single synthesis call (backtest) ββββββββββββββββββββββββ
|
|
@@ -741,37 +858,9 @@ def get_ai_forecast(
|
|
| 741 |
ret_lo = float(parsed.get("predicted_return_lo", 0.0))
|
| 742 |
ret_hi = float(parsed.get("predicted_return_hi", 0.0))
|
| 743 |
|
| 744 |
-
# ββ
|
| 745 |
-
#
|
| 746 |
-
#
|
| 747 |
-
# confirming MACD β fixes cases where stock genuinely fell (TCS/WIPRO/etc).
|
| 748 |
-
if direction == "BEARISH" and indicators:
|
| 749 |
-
rsi14 = float(indicators.get("rsi14") or 50.0)
|
| 750 |
-
ema50 = float(indicators.get("ema50") or 0.0)
|
| 751 |
-
ema200 = float(indicators.get("ema200") or 0.0)
|
| 752 |
-
macd = float(indicators.get("macd_signal") or 0.0)
|
| 753 |
-
below_ema50 = (ema50 > 0 and current_price < ema50)
|
| 754 |
-
below_ema200 = (ema200 > 0 and current_price < ema200)
|
| 755 |
-
|
| 756 |
-
# BEARISH is only credible when: overbought AND below a key MA
|
| 757 |
-
# RSI > 68 AND (below EMA50 OR (MACD < 0 AND below EMA200))
|
| 758 |
-
credible_bear = (
|
| 759 |
-
rsi14 > 68
|
| 760 |
-
and (below_ema50 or (macd < 0 and below_ema200))
|
| 761 |
-
)
|
| 762 |
-
# Override to BULLISH when clearly not bearish:
|
| 763 |
-
# - Deeply oversold (RSI < 45): bounce almost certain on NSE
|
| 764 |
-
# - Moderately bullish (RSI < 55, above EMA50, positive MACD)
|
| 765 |
-
clearly_not_bearish = (
|
| 766 |
-
(rsi14 < 45)
|
| 767 |
-
or (rsi14 < 55 and not below_ema50 and macd > 0)
|
| 768 |
-
)
|
| 769 |
-
if clearly_not_bearish or not credible_bear:
|
| 770 |
-
direction = "BULLISH"
|
| 771 |
-
|
| 772 |
-
# ββ Apply calibrated ranges (overrides LLM lo/hi entirely) ββββββββββββ
|
| 773 |
-
# LLM output for ranges is unreliable (deviates from guidance ~40% of cases).
|
| 774 |
-
# Calibrated table maximises midpoint-touch accuracy on NSE 2018-2025.
|
| 775 |
ret_lo, ret_hi = _apply_calibrated_range(direction, tf_label)
|
| 776 |
|
| 777 |
# News alignment: re-center range when direction conflicts strongly with news
|
|
@@ -861,24 +950,8 @@ def get_ai_forecast(
|
|
| 861 |
ret_lo = float(parsed.get("predicted_return_lo", 0.0))
|
| 862 |
ret_hi = float(parsed.get("predicted_return_hi", 0.0))
|
| 863 |
|
| 864 |
-
#
|
| 865 |
-
|
| 866 |
-
rsi14 = float(indicators.get("rsi14") or 50.0)
|
| 867 |
-
ema50 = float(indicators.get("ema50") or 0.0)
|
| 868 |
-
ema200 = float(indicators.get("ema200") or 0.0)
|
| 869 |
-
macd = float(indicators.get("macd_signal") or 0.0)
|
| 870 |
-
below_ema50 = (ema50 > 0 and current_price < ema50)
|
| 871 |
-
below_ema200 = (ema200 > 0 and current_price < ema200)
|
| 872 |
-
credible_bear = (
|
| 873 |
-
rsi14 > 68
|
| 874 |
-
and (below_ema50 or (macd < 0 and below_ema200))
|
| 875 |
-
)
|
| 876 |
-
clearly_not_bearish = (
|
| 877 |
-
(rsi14 < 45)
|
| 878 |
-
or (rsi14 < 55 and not below_ema50 and macd > 0)
|
| 879 |
-
)
|
| 880 |
-
if clearly_not_bearish or not credible_bear:
|
| 881 |
-
direction = "BULLISH"
|
| 882 |
|
| 883 |
# Apply calibrated ranges (override LLM lo/hi)
|
| 884 |
ret_lo, ret_hi = _apply_calibrated_range(direction, tf_label)
|
|
|
|
| 27 |
import requests
|
| 28 |
import pandas as pd
|
| 29 |
|
| 30 |
+
# Load .env before reading API keys β needed when called outside Flask (e.g. top5_picker, backtest)
|
| 31 |
+
try:
|
| 32 |
+
from dotenv import load_dotenv
|
| 33 |
+
load_dotenv()
|
| 34 |
+
except ImportError:
|
| 35 |
+
pass # dotenv optional β env vars already set
|
| 36 |
+
|
| 37 |
logging.basicConfig(level=logging.INFO)
|
| 38 |
logger = logging.getLogger(__name__)
|
| 39 |
|
|
|
|
| 296 |
global _GITHUB_DISABLED_UNTIL # must be global β inner fn both reads and writes it
|
| 297 |
token = os.environ.get("GITHUB_TOKEN", "").strip()
|
| 298 |
if not token:
|
| 299 |
+
logger.debug("GitHub Models skipped β GITHUB_TOKEN not set")
|
| 300 |
return None
|
| 301 |
with _LLM_LOCK:
|
| 302 |
if time.time() < _GITHUB_DISABLED_UNTIL:
|
|
|
|
| 317 |
_GITHUB_DISABLED_UNTIL = time.time() + cooldown
|
| 318 |
logger.warning("GitHub Models rate-limited (429) β falling through to OpenRouter")
|
| 319 |
return None
|
| 320 |
+
if resp.status_code == 401:
|
| 321 |
+
logger.error("GitHub Models auth failed (401) β check GITHUB_TOKEN has models:read scope")
|
| 322 |
+
return None
|
| 323 |
+
if resp.status_code == 403:
|
| 324 |
+
logger.error("GitHub Models forbidden (403) β token may lack models:read scope or usage limit hit")
|
| 325 |
+
return None
|
| 326 |
if resp.status_code == 200:
|
| 327 |
content = (((resp.json().get("choices") or [{}])[0].get("message") or {}).get("content") or "").strip()
|
| 328 |
if content:
|
| 329 |
return content, "github", model
|
| 330 |
+
logger.warning("GitHub Models unexpected status %s β body: %s", resp.status_code, resp.text[:200])
|
| 331 |
except RuntimeError:
|
| 332 |
raise
|
| 333 |
except Exception as e:
|
|
|
|
| 337 |
def _try_openrouter() -> tuple[str, str, str] | None:
|
| 338 |
api_key = os.environ.get("OPENROUTER_API_KEY", "").strip()
|
| 339 |
if not api_key:
|
| 340 |
+
logger.debug("OpenRouter skipped β OPENROUTER_API_KEY not set")
|
| 341 |
return None
|
| 342 |
model = (os.environ.get("OPENROUTER_BEST_FREE_MODEL") or "openai/gpt-oss-120b:free").strip()
|
| 343 |
# Free-tier fallback chain β try alternate models on 429
|
|
|
|
| 357 |
logger.warning("OpenRouter rate-limited on %s (429) β trying next model", try_model)
|
| 358 |
time.sleep(2) # brief backoff before trying next model
|
| 359 |
continue
|
| 360 |
+
if resp.status_code == 401:
|
| 361 |
+
logger.error("OpenRouter auth failed (401) β check OPENROUTER_API_KEY")
|
| 362 |
+
return None
|
| 363 |
if resp.status_code in (404, 422):
|
| 364 |
logger.debug("OpenRouter model %s unavailable (%s) β trying next", try_model, resp.status_code)
|
| 365 |
continue
|
|
|
|
| 367 |
content = (((resp.json().get("choices") or [{}])[0].get("message") or {}).get("content") or "").strip()
|
| 368 |
if content:
|
| 369 |
return content, "openrouter", try_model
|
| 370 |
+
logger.debug("OpenRouter %s returned empty content", try_model)
|
| 371 |
+
else:
|
| 372 |
+
logger.warning("OpenRouter %s status %s β body: %s", try_model, resp.status_code, resp.text[:200])
|
| 373 |
except Exception as e:
|
| 374 |
logger.debug("OpenRouter call failed for %s: %s", try_model, e)
|
| 375 |
return None
|
|
|
|
| 391 |
#
|
| 392 |
# 1D BULLISH: mid = 0.25% (sweep-optimal; LLM output ~0.20% was suboptimal)
|
| 393 |
# 3D/5D BULLISH: mid = 0.10% (already LLM-optimal, keeps them identical)
|
| 394 |
+
# ALL BEARISH: mid = -0.10% (lo=-0.15, hi=-0.05) β NSE sweep-optimal
|
| 395 |
+
# β’ Shallower midpoint improves target-touch hit rate on 1D/3D/5D
|
| 396 |
+
# β’ Deeper bearish anchors over-shoot many realized down moves
|
| 397 |
# ============================================================================
|
| 398 |
_BULL_RANGE: dict[str, tuple[float, float]] = {
|
| 399 |
"1D": (0.05, 0.45), # mid = 0.250% β empirically optimal for 1D
|
|
|
|
| 401 |
"5D": (0.02, 0.18), # mid = 0.100% β unchanged, already optimal
|
| 402 |
}
|
| 403 |
_BEAR_RANGE: dict[str, tuple[float, float]] = {
|
| 404 |
+
"1D": (-0.15, -0.05), # mid = -0.10% β data-verified optimal for NSE hit metric
|
| 405 |
+
"3D": (-0.15, -0.05),
|
| 406 |
+
"5D": (-0.15, -0.05),
|
| 407 |
}
|
| 408 |
_NEUT_RANGE: dict[str, tuple[float, float]] = {
|
| 409 |
"1D": (-0.12, 0.12),
|
|
|
|
| 417 |
if direction == "BULLISH":
|
| 418 |
return _BULL_RANGE.get(tf_label, (0.02, 0.18))
|
| 419 |
if direction == "BEARISH":
|
| 420 |
+
return _BEAR_RANGE.get(tf_label, (-0.15, -0.05))
|
| 421 |
return _NEUT_RANGE.get(tf_label, (-0.15, 0.15))
|
| 422 |
|
| 423 |
def _parse_json_from_llm(text: str) -> Dict | None:
|
|
|
|
| 456 |
return parsed
|
| 457 |
|
| 458 |
|
| 459 |
+
# ============================================================================
|
| 460 |
+
# INDICATOR NORMALIZATION
|
| 461 |
+
# ============================================================================
|
| 462 |
+
|
| 463 |
+
def _normalize_indicators(raw: dict) -> dict:
|
| 464 |
+
"""
|
| 465 |
+
Normalize indicator keys from backtest format to ai_forecast format.
|
| 466 |
+
|
| 467 |
+
Backtest (research/backtest.py) produces:
|
| 468 |
+
RSI_14, Price_vs_EMA50 (string), MACD_histogram, ATR14 βΉ, Volume_ratio_20D
|
| 469 |
+
|
| 470 |
+
Production (predictor_core.py) produces:
|
| 471 |
+
rsi14, ema50 (float), macd_signal, atr14, vol_ratio
|
| 472 |
+
|
| 473 |
+
This normalization ensures the context block and direction logic work
|
| 474 |
+
identically regardless of which caller is used.
|
| 475 |
+
"""
|
| 476 |
+
if not raw:
|
| 477 |
+
return {}
|
| 478 |
+
norm = dict(raw)
|
| 479 |
+
|
| 480 |
+
# RSI
|
| 481 |
+
if "rsi14" not in norm and "RSI_14" in norm:
|
| 482 |
+
try:
|
| 483 |
+
norm["rsi14"] = float(norm["RSI_14"])
|
| 484 |
+
except (ValueError, TypeError):
|
| 485 |
+
pass
|
| 486 |
+
if "rsi5" not in norm and "RSI_5" in norm:
|
| 487 |
+
try:
|
| 488 |
+
norm["rsi5"] = float(norm["RSI_5"])
|
| 489 |
+
except (ValueError, TypeError):
|
| 490 |
+
pass
|
| 491 |
+
if "rsi2" not in norm and "RSI_2" in norm:
|
| 492 |
+
try:
|
| 493 |
+
norm["rsi2"] = float(norm["RSI_2"])
|
| 494 |
+
except (ValueError, TypeError):
|
| 495 |
+
pass
|
| 496 |
+
|
| 497 |
+
# EMA levels β backtest stores as "above (EMA50=βΉ1234.56)" strings
|
| 498 |
+
for tf_str, key in [("EMA50", "ema50"), ("EMA200", "ema200"), ("EMA20", "ema20")]:
|
| 499 |
+
if key not in norm:
|
| 500 |
+
raw_val = str(norm.get(f"Price_vs_{tf_str}", ""))
|
| 501 |
+
if raw_val:
|
| 502 |
+
m = re.search(rf"{tf_str}=βΉ([\d.]+)", raw_val)
|
| 503 |
+
if m:
|
| 504 |
+
try:
|
| 505 |
+
norm[key] = float(m.group(1))
|
| 506 |
+
except ValueError:
|
| 507 |
+
pass
|
| 508 |
+
|
| 509 |
+
# MACD histogram β signal
|
| 510 |
+
if "macd_signal" not in norm and "MACD_histogram" in norm:
|
| 511 |
+
try:
|
| 512 |
+
norm["macd_signal"] = float(norm["MACD_histogram"])
|
| 513 |
+
except (ValueError, TypeError):
|
| 514 |
+
pass
|
| 515 |
+
|
| 516 |
+
# ATR
|
| 517 |
+
if "atr14" not in norm and "ATR14 βΉ" in norm:
|
| 518 |
+
try:
|
| 519 |
+
norm["atr14"] = float(norm["ATR14 βΉ"])
|
| 520 |
+
except (ValueError, TypeError):
|
| 521 |
+
pass
|
| 522 |
+
|
| 523 |
+
# Volume ratio
|
| 524 |
+
if "vol_ratio" not in norm and "Volume_ratio_20D" in norm:
|
| 525 |
+
try:
|
| 526 |
+
norm["vol_ratio"] = float(norm["Volume_ratio_20D"])
|
| 527 |
+
except (ValueError, TypeError):
|
| 528 |
+
pass
|
| 529 |
+
|
| 530 |
+
# Return_90D
|
| 531 |
+
if "return_90d" not in norm and "Return_90D_%" in norm:
|
| 532 |
+
try:
|
| 533 |
+
norm["return_90d"] = float(norm["Return_90D_%"])
|
| 534 |
+
except (ValueError, TypeError):
|
| 535 |
+
pass
|
| 536 |
+
|
| 537 |
+
return norm
|
| 538 |
+
|
| 539 |
+
|
| 540 |
# ============================================================================
|
| 541 |
# PROMPT BUILDERS
|
| 542 |
# ============================================================================
|
|
|
|
| 546 |
ml: Dict, nifty_ok: bool, macro_ok: bool, vix_level: float,
|
| 547 |
news: Dict, indicators: Dict, mode_c_active: bool,
|
| 548 |
vix_declining: bool, market_breadth: Dict, fii_pcr: Dict,
|
| 549 |
+
current_price: float = 0.0,
|
| 550 |
) -> str:
|
| 551 |
+
"""
|
| 552 |
+
Build the shared context block shown to all LLM calls.
|
| 553 |
+
Handles both production (rsi14/ema50) and backtest (RSI_14/Price_vs_EMA50) key formats.
|
| 554 |
+
"""
|
| 555 |
lines = [
|
| 556 |
f"STOCK: {ticker} ({company}) | TIMEFRAME: {tf_label}",
|
| 557 |
f"MARKET: VIX {vix_level:.1f} ({'declining β' if vix_declining else 'rising β'}) "
|
|
|
|
| 563 |
lines.append(f"ML SCORE: {ml.get('score', 50)}/100 prob={ml.get('probability', 0.5):.2f}"
|
| 564 |
+ (" [UPGRADED]" if ml.get("upgraded") else ""))
|
| 565 |
if indicators:
|
| 566 |
+
# Use current_price from explicit param first, then try indicators dict
|
| 567 |
+
p = float(current_price) if current_price and current_price > 0 else float(indicators.get("close") or 0)
|
| 568 |
+
rsi_val = indicators.get("rsi14")
|
| 569 |
+
adx_val = indicators.get("adx14")
|
| 570 |
+
ema50_val = indicators.get("ema50")
|
| 571 |
+
ema200_val = indicators.get("ema200")
|
| 572 |
+
macd_val = indicators.get("macd_signal")
|
| 573 |
+
obv_val = indicators.get("obv_trend", "")
|
| 574 |
+
vol_ratio = indicators.get("vol_ratio")
|
| 575 |
+
ret_90d = indicators.get("return_90d")
|
| 576 |
+
dist_52w = indicators.get("Dist_from_52W_High_%")
|
| 577 |
lines.append("TECHNICALS:")
|
| 578 |
if p:
|
| 579 |
+
lines.append(f" Price: βΉ{p:.2f}")
|
| 580 |
+
if rsi_val is not None:
|
| 581 |
+
rsi_f = float(rsi_val)
|
| 582 |
+
lbl = "oversold" if rsi_f < 35 else ("overbought" if rsi_f > 65 else "neutral")
|
| 583 |
+
lines.append(f" RSI(14): {rsi_f:.1f} ({lbl})")
|
| 584 |
+
if adx_val is not None:
|
| 585 |
+
lines.append(f" ADX: {float(adx_val):.1f} ({'trending' if float(adx_val) > 25 else 'ranging'})")
|
| 586 |
+
if ema200_val and p:
|
| 587 |
+
e200 = float(ema200_val)
|
| 588 |
+
lines.append(f" EMA200: βΉ{e200:.2f} (price {'above β' if p > e200 else 'below β'})")
|
| 589 |
+
if ema50_val and p:
|
| 590 |
+
e50 = float(ema50_val)
|
| 591 |
+
lines.append(f" EMA50: βΉ{e50:.2f} (price {'above' if p > e50 else 'below'})")
|
| 592 |
+
if macd_val is not None:
|
| 593 |
+
m_f = float(macd_val)
|
| 594 |
+
lines.append(f" MACD histogram: {'bullish' if m_f > 0 else 'bearish'} ({m_f:.4f})")
|
| 595 |
+
if vol_ratio is not None:
|
| 596 |
+
vr = float(vol_ratio)
|
| 597 |
+
lines.append(f" Volume ratio 20D: {vr:.2f}x ({'high' if vr > 1.5 else ('low' if vr < 0.7 else 'normal')})")
|
| 598 |
+
if ret_90d is not None:
|
| 599 |
+
r90 = float(ret_90d)
|
| 600 |
+
lines.append(f" 90D return: {r90:+.1f}% ({'strong uptrend' if r90 > 15 else ('downtrend' if r90 < -10 else 'range-bound')})")
|
| 601 |
+
if dist_52w is not None:
|
| 602 |
+
d52 = float(dist_52w)
|
| 603 |
+
lines.append(f" 52W high dist: {d52:+.1f}% ({'near high' if d52 > -5 else ('deeply off high' if d52 < -20 else 'mid-range')})")
|
| 604 |
+
if obv_val:
|
| 605 |
+
lines.append(f" OBV trend: {obv_val}")
|
| 606 |
if news and news.get("label"):
|
| 607 |
lines.append(f"NEWS: {news['label']} score={news.get('score', 0)}"
|
| 608 |
+ (f" β {news['summary']}" if news.get("summary") else ""))
|
|
|
|
| 679 |
_cap_pct = {"1D": 4.0, "3D": 7.0, "5D": 12.0}.get(tf_label, 7.0)
|
| 680 |
holding = {"1D": "1 trading day", "3D": "3 trading days", "5D": "5 trading days"}.get(tf_label, "3 trading days")
|
| 681 |
|
| 682 |
+
# Timeframe-specific guidance for WHICH indicators dominate direction
|
|
|
|
|
|
|
|
|
|
| 683 |
tf_guidance = {
|
| 684 |
"1D": (
|
| 685 |
+
"DIRECTION GUIDE for 1D:\n"
|
| 686 |
+
"- Primary signals: RSI(14), MACD histogram, intraday momentum, volume ratio\n"
|
| 687 |
+
"- BULLISH when: RSI < 40 (oversold bounce) OR (above EMA50 AND MACD > 0 AND volume high)\n"
|
| 688 |
+
"- BEARISH when: RSI > 68 AND below EMA50 AND MACD < 0 AND volume confirms\n"
|
| 689 |
+
"- NEUTRAL when: RSI 40β68 with conflicting EMA/MACD, or volume is not confirming\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 690 |
),
|
| 691 |
"3D": (
|
| 692 |
+
"DIRECTION GUIDE for 3D:\n"
|
| 693 |
+
"- Primary signals: EMA50 alignment, RSI trend, MACD direction, macro/sector context\n"
|
| 694 |
+
"- BULLISH when: above EMA50 AND (RSI < 55 OR MACD > 0) AND macro supports risk-on\n"
|
| 695 |
+
"- BEARISH when: below EMA50 AND (RSI > 58 OR MACD < 0) AND macro/sector headwinds\n"
|
| 696 |
+
"- NEUTRAL when: near EMA50 OR significant conflict between RSI/MACD/macro β do NOT guess\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 697 |
),
|
| 698 |
"5D": (
|
| 699 |
+
"DIRECTION GUIDE for 5D:\n"
|
| 700 |
+
"- Primary signals: EMA200 trend, EMA50 position, sector rotation, FII flows\n"
|
| 701 |
+
"- BULLISH when: above EMA200 AND above EMA50 AND sector is leading AND FII flows positive\n"
|
| 702 |
+
"- BEARISH when: below EMA200 AND below EMA50 AND macro risk-off AND sector lagging\n"
|
| 703 |
+
"- NEUTRAL when: between EMAs, or any major signal is conflicting β prefer NEUTRAL over a weak guess\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 704 |
),
|
| 705 |
}.get(tf_label, "")
|
| 706 |
|
| 707 |
+
signal_rules = (
|
| 708 |
+
"SIGNAL ALIGNMENT β Only make directional calls when β₯3 independent signals agree:\n"
|
| 709 |
+
" Signals: RSI level | EMA50 position | EMA200 position | MACD direction | Volume trend\n"
|
| 710 |
+
" | Market breadth | FII/DII flow | News sentiment | Macro regime\n"
|
| 711 |
+
"- HIGH confidence: β₯4 signals clearly aligned in same direction\n"
|
| 712 |
+
"- MEDIUM confidence: exactly 3 signals aligned, others neutral\n"
|
| 713 |
+
"- LOW confidence: only 2 signals aligned β consider NEUTRAL instead\n"
|
| 714 |
+
"- When VIX > 20 or macro is risk-off: require 4+ signals for BULLISH\n"
|
| 715 |
+
"- When above EMA200 with no clear reversal signal: prefer BULLISH or NEUTRAL, not BEARISH\n"
|
| 716 |
+
"- When stock has been falling for 5+ days AND below both EMAs: BEARISH is valid\n"
|
| 717 |
+
"- In genuine signal conflict: always choose NEUTRAL over a low-conviction directional call\n"
|
| 718 |
)
|
| 719 |
|
| 720 |
+
fund_section = f"\n\nFUNDAMENTALS ANALYST VIEW:\n{fund_view}" if fund_view and fund_view.strip() else ""
|
| 721 |
+
|
| 722 |
return (
|
| 723 |
f"You are Head of Research at an Indian equity trading desk. "
|
| 724 |
+
f"Synthesize ALL available evidence β technical indicators, macro regime, "
|
| 725 |
+
f"sector context, news sentiment, and fundamentals β to form the MOST ACCURATE "
|
| 726 |
+
f"directional forecast for a {holding} trade. "
|
| 727 |
+
f"The advocate with more SPECIFIC, DATA-BACKED, INTER-RELATED evidence wins.\n\n"
|
| 728 |
f"{ctx}\n\n"
|
| 729 |
f"BULL ANALYST VIEW:\n{bull_view}\n\n"
|
| 730 |
f"BEAR ANALYST VIEW:\n{bear_view}"
|
| 731 |
f"{fund_section}\n\n"
|
| 732 |
f"{tf_guidance}\n"
|
| 733 |
+
f"{signal_rules}\n"
|
| 734 |
+
f"ATR(14): βΉ{atr14:.2f} Current price: βΉ{current_price:.2f} "
|
| 735 |
+
f"Hard cap: Β±{_cap_pct}% for {holding} horizon.\n\n"
|
| 736 |
+
f"NOTE: The predicted_return range you output is for reference only β "
|
| 737 |
+
f"a calibrated table overrides it post-processing. Your critical job is choosing "
|
| 738 |
+
f"the correct DIRECTION and CONFIDENCE based on signal alignment above.\n\n"
|
| 739 |
f"Respond with ONLY a valid JSON object β no markdown, no extra text:\n"
|
| 740 |
f'{{"direction": "BULLISH"|"BEARISH"|"NEUTRAL", '
|
| 741 |
f'"confidence": "HIGH"|"MEDIUM"|"LOW", '
|
| 742 |
+
f'"predicted_return_lo": <worst-case % β positive for bull, negative for bear>, '
|
| 743 |
+
f'"predicted_return_hi": <best-case % β larger positive for bull, less-negative for bear>, '
|
| 744 |
+
f'"reasoning": "<1-2 sentences: name the 3 key signals that determined direction>"}}\n\n'
|
| 745 |
+
f"JSON rules:\n"
|
| 746 |
+
f"- BULLISH: lo > 0, hi > lo\n"
|
| 747 |
+
f"- BEARISH: lo < hi < 0\n"
|
| 748 |
+
f"- NEUTRAL: lo < 0 < hi\n"
|
| 749 |
+
f"- Absolute values must not exceed {_cap_pct}%\n"
|
|
|
|
| 750 |
)
|
| 751 |
|
| 752 |
|
|
|
|
| 787 |
vix_level = float(args[6]) if len(args) >= 7 and isinstance(args[6], (int,float)) else float(kwargs.get("vix_level", 15.0))
|
| 788 |
news = args[7] if len(args) >= 8 and isinstance(args[7], dict) else kwargs.get("news", {})
|
| 789 |
current_price = float(kwargs.get("current_price", 0.0))
|
| 790 |
+
indicators = _normalize_indicators(kwargs.get("indicators", {}) or {})
|
| 791 |
ohlcv_df = kwargs.get("ohlcv_df")
|
| 792 |
fundamentals = kwargs.get("fundamentals") or {}
|
| 793 |
mode_c_active = bool(kwargs.get("mode_c_active", False))
|
|
|
|
| 814 |
move_anchor = _realized_move_anchor(ohlcv_df, tf_label, vol_pctile)
|
| 815 |
atr14 = float(indicators.get("atr14") or move_anchor * (current_price / 100) or 10.0)
|
| 816 |
news_score = int((news or {}).get("score", 0))
|
|
|
|
| 817 |
try:
|
| 818 |
# ββ Fetch social sentiment (Reddit/StockTwits, no API key needed) ββββββ
|
| 819 |
social_block = ""
|
|
|
|
| 829 |
ml, nifty_ok, macro_ok, vix_level,
|
| 830 |
news, indicators, mode_c_active,
|
| 831 |
vix_declining, market_breadth, fii_pcr,
|
| 832 |
+
current_price=current_price,
|
| 833 |
)
|
| 834 |
|
| 835 |
# ββ Fast-mode: single synthesis call (backtest) ββββββββββββββββββββββββ
|
|
|
|
| 858 |
ret_lo = float(parsed.get("predicted_return_lo", 0.0))
|
| 859 |
ret_hi = float(parsed.get("predicted_return_hi", 0.0))
|
| 860 |
|
| 861 |
+
# ββ Apply calibrated ranges (overrides LLM lo/hi entirely) ββββββββββ
|
| 862 |
+
# Pure AI path: direction comes from LLM analysis of actual data.
|
| 863 |
+
# Range is still calibrated post-processing to maximise intraday hit rate.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 864 |
ret_lo, ret_hi = _apply_calibrated_range(direction, tf_label)
|
| 865 |
|
| 866 |
# News alignment: re-center range when direction conflicts strongly with news
|
|
|
|
| 950 |
ret_lo = float(parsed.get("predicted_return_lo", 0.0))
|
| 951 |
ret_hi = float(parsed.get("predicted_return_hi", 0.0))
|
| 952 |
|
| 953 |
+
# Pure AI path: direction comes entirely from LLM multi-agent debate.
|
| 954 |
+
# No code-level overrides β the bull/bear/fundamentals debate produces the call.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 955 |
|
| 956 |
# Apply calibrated ranges (override LLM lo/hi)
|
| 957 |
ret_lo, ret_hi = _apply_calibrated_range(direction, tf_label)
|
app.py
CHANGED
|
@@ -85,6 +85,104 @@ def _resolve_dates(data: dict) -> tuple[str, str]:
|
|
| 85 |
return start, end
|
| 86 |
|
| 87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
def _postmortem(trade: dict) -> str:
|
| 89 |
"""Generate a structured trade post-mortem using GitHub Models or OpenRouter."""
|
| 90 |
import requests as _req
|
|
@@ -110,6 +208,18 @@ def _postmortem(trade: dict) -> str:
|
|
| 110 |
is_manual = not pred_data and not trade.get("strategy")
|
| 111 |
|
| 112 |
if is_manual:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
prompt = f"""You are a senior NSE equity trader reviewing a paper trade that was opened manually β no prior AI prediction scan was run.
|
| 114 |
|
| 115 |
TRADE DETAILS:
|
|
@@ -119,15 +229,18 @@ TRADE DETAILS:
|
|
| 119 |
Exit: βΉ{trade['exit_price']:,.2f}
|
| 120 |
P&L: {pnl_pct:+.2f}% β {outcome}
|
| 121 |
|
|
|
|
|
|
|
| 122 |
No strategy signals, ML score, news sentiment, or AI prediction were recorded at entry.
|
| 123 |
-
Analyse
|
|
|
|
| 124 |
|
| 125 |
Return ONLY a valid JSON object with these exact keys β no markdown, no explanation:
|
| 126 |
{{
|
| 127 |
"why_outcome": "<2-3 sentences: primary reason this trade {outcome.lower()} based on price action and entry/exit levels alone.>",
|
| 128 |
"what_went_right": "<what price behaviour or timing was favourable, even if trade {outcome.lower()}. Reference specific βΉ levels.>",
|
| 129 |
"what_went_wrong": "<what price behaviour or risk management was poor. Be specific to the entry/exit prices and % move.>",
|
| 130 |
-
|
| 131 |
"improvement_rule": "<one concrete, actionable rule. Start with a verb: e.g. 'Always run a watchlist prediction for ... before entering a LONG position.' >"
|
| 132 |
}}"""
|
| 133 |
else:
|
|
@@ -653,7 +766,7 @@ def db_diag():
|
|
| 653 |
try:
|
| 654 |
from huggingface_hub import hf_hub_download
|
| 655 |
local = hf_hub_download(
|
| 656 |
-
repo_id=
|
| 657 |
filename="paper_trading.db",
|
| 658 |
repo_type="dataset",
|
| 659 |
token=token,
|
|
@@ -1371,6 +1484,18 @@ def trades_open_new():
|
|
| 1371 |
if isinstance(pred_data, dict):
|
| 1372 |
pred_data = json.dumps(pred_data)
|
| 1373 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1374 |
trade = db.open_trade(
|
| 1375 |
ticker=ticker,
|
| 1376 |
name=name,
|
|
@@ -1379,8 +1504,8 @@ def trades_open_new():
|
|
| 1379 |
shares=int(data["shares"]),
|
| 1380 |
stop_loss=data.get("stop_loss"),
|
| 1381 |
target=data.get("target"),
|
| 1382 |
-
strategy=
|
| 1383 |
-
timeframe=
|
| 1384 |
prediction_data=pred_data,
|
| 1385 |
order_type=order_type,
|
| 1386 |
status=status,
|
|
|
|
| 85 |
return start, end
|
| 86 |
|
| 87 |
|
| 88 |
+
def _trade_price_diagnostics(trade: dict) -> dict:
|
| 89 |
+
"""Build price-action diagnostics for a closed trade using OHLCV in the trade window."""
|
| 90 |
+
try:
|
| 91 |
+
ticker = _normalise(trade.get("ticker", ""))
|
| 92 |
+
entry = float(trade.get("entry_price") or 0)
|
| 93 |
+
exit_px = float(trade.get("exit_price") or 0)
|
| 94 |
+
direction = (trade.get("direction") or "LONG").upper()
|
| 95 |
+
if not ticker or entry <= 0 or exit_px <= 0:
|
| 96 |
+
return {}
|
| 97 |
+
|
| 98 |
+
opened_raw = (trade.get("opened_at") or "")[:10]
|
| 99 |
+
closed_raw = (trade.get("closed_at") or "")[:10]
|
| 100 |
+
if not opened_raw or not closed_raw:
|
| 101 |
+
return {}
|
| 102 |
+
|
| 103 |
+
opened_date = datetime.strptime(opened_raw, "%Y-%m-%d").date()
|
| 104 |
+
closed_date = datetime.strptime(closed_raw, "%Y-%m-%d").date()
|
| 105 |
+
|
| 106 |
+
# Include a small buffer around the trade window for context bars.
|
| 107 |
+
start = (opened_date - timedelta(days=4)).strftime("%Y-%m-%d")
|
| 108 |
+
end = (closed_date + timedelta(days=1)).strftime("%Y-%m-%d")
|
| 109 |
+
bars = fetch_ohlcv(ticker, start, end)
|
| 110 |
+
if bars is None or getattr(bars, "empty", True):
|
| 111 |
+
return {}
|
| 112 |
+
|
| 113 |
+
df = bars.copy()
|
| 114 |
+
idx = getattr(df, "index", None)
|
| 115 |
+
if idx is None:
|
| 116 |
+
return {}
|
| 117 |
+
|
| 118 |
+
mask = (idx.date >= opened_date) & (idx.date <= closed_date)
|
| 119 |
+
tw = df.loc[mask]
|
| 120 |
+
if getattr(tw, "empty", True):
|
| 121 |
+
tw = df.tail(5)
|
| 122 |
+
if getattr(tw, "empty", True):
|
| 123 |
+
return {}
|
| 124 |
+
|
| 125 |
+
high = float(tw["High"].max())
|
| 126 |
+
low = float(tw["Low"].min())
|
| 127 |
+
first_close = float(tw["Close"].iloc[0])
|
| 128 |
+
last_close = float(tw["Close"].iloc[-1])
|
| 129 |
+
|
| 130 |
+
if direction == "LONG":
|
| 131 |
+
mfe_pct = ((high - entry) / entry) * 100
|
| 132 |
+
mae_pct = ((low - entry) / entry) * 100
|
| 133 |
+
else:
|
| 134 |
+
mfe_pct = ((entry - low) / entry) * 100
|
| 135 |
+
mae_pct = ((entry - high) / entry) * 100
|
| 136 |
+
|
| 137 |
+
return {
|
| 138 |
+
"window_days": int(len(tw)),
|
| 139 |
+
"window_high": round(high, 2),
|
| 140 |
+
"window_low": round(low, 2),
|
| 141 |
+
"swing_pct": round(((high - low) / entry) * 100, 2),
|
| 142 |
+
"trend_pct": round(((last_close - first_close) / first_close) * 100, 2),
|
| 143 |
+
"mfe_pct": round(mfe_pct, 2),
|
| 144 |
+
"mae_pct": round(mae_pct, 2),
|
| 145 |
+
"entry_to_exit_pct": round(((exit_px - entry) / entry) * 100, 2),
|
| 146 |
+
}
|
| 147 |
+
except Exception:
|
| 148 |
+
return {}
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
def _autofill_trade_context(ticker: str) -> dict:
|
| 152 |
+
"""Best-effort context fill for manual trade opens (strategy/timeframe/prediction_data)."""
|
| 153 |
+
try:
|
| 154 |
+
start, end = timeframe_to_dates("3D")
|
| 155 |
+
pred = predict_stock_v2(
|
| 156 |
+
ticker,
|
| 157 |
+
start,
|
| 158 |
+
end,
|
| 159 |
+
_run_ai_forecast=True,
|
| 160 |
+
_ai_fast_mode=False,
|
| 161 |
+
_ai_fast_fail_on_rate_limit=False,
|
| 162 |
+
)
|
| 163 |
+
if not pred or pred.get("error"):
|
| 164 |
+
return {}
|
| 165 |
+
|
| 166 |
+
ai = pred.get("ai_forecast") or {}
|
| 167 |
+
return {
|
| 168 |
+
"strategy": ((pred.get("active_strategies") or ["AUTO_SCAN"])[0]),
|
| 169 |
+
"timeframe": pred.get("timeframe") or "3D",
|
| 170 |
+
"prediction_data": {
|
| 171 |
+
"ml": pred.get("ml") or {},
|
| 172 |
+
"news": pred.get("news") or {},
|
| 173 |
+
"ai": {
|
| 174 |
+
"direction": ai.get("direction"),
|
| 175 |
+
"confidence": ai.get("confidence"),
|
| 176 |
+
"target_price_lo": ai.get("target_price_lo"),
|
| 177 |
+
"target_price_hi": ai.get("target_price_hi"),
|
| 178 |
+
},
|
| 179 |
+
"market": pred.get("market") or {},
|
| 180 |
+
},
|
| 181 |
+
}
|
| 182 |
+
except Exception:
|
| 183 |
+
return {}
|
| 184 |
+
|
| 185 |
+
|
| 186 |
def _postmortem(trade: dict) -> str:
|
| 187 |
"""Generate a structured trade post-mortem using GitHub Models or OpenRouter."""
|
| 188 |
import requests as _req
|
|
|
|
| 208 |
is_manual = not pred_data and not trade.get("strategy")
|
| 209 |
|
| 210 |
if is_manual:
|
| 211 |
+
diag = _trade_price_diagnostics(trade)
|
| 212 |
+
diag_block = ""
|
| 213 |
+
if diag:
|
| 214 |
+
diag_block = (
|
| 215 |
+
"PRICE ACTION DIAGNOSTICS:\n"
|
| 216 |
+
f" Bars in window: {diag.get('window_days')}\n"
|
| 217 |
+
f" Window high/low: βΉ{diag.get('window_high')} / βΉ{diag.get('window_low')}\n"
|
| 218 |
+
f" Swing in window: {diag.get('swing_pct')}%\n"
|
| 219 |
+
f" Window trend (first close -> last close): {diag.get('trend_pct')}%\n"
|
| 220 |
+
f" MFE (best excursion from entry): {diag.get('mfe_pct')}%\n"
|
| 221 |
+
f" MAE (worst excursion from entry): {diag.get('mae_pct')}%\n"
|
| 222 |
+
)
|
| 223 |
prompt = f"""You are a senior NSE equity trader reviewing a paper trade that was opened manually β no prior AI prediction scan was run.
|
| 224 |
|
| 225 |
TRADE DETAILS:
|
|
|
|
| 229 |
Exit: βΉ{trade['exit_price']:,.2f}
|
| 230 |
P&L: {pnl_pct:+.2f}% β {outcome}
|
| 231 |
|
| 232 |
+
{diag_block}
|
| 233 |
+
|
| 234 |
No strategy signals, ML score, news sentiment, or AI prediction were recorded at entry.
|
| 235 |
+
Analyse strictly from the recorded trade levels and diagnostics above.
|
| 236 |
+
Do NOT mention missing AI data repeatedly. Be concrete and numeric.
|
| 237 |
|
| 238 |
Return ONLY a valid JSON object with these exact keys β no markdown, no explanation:
|
| 239 |
{{
|
| 240 |
"why_outcome": "<2-3 sentences: primary reason this trade {outcome.lower()} based on price action and entry/exit levels alone.>",
|
| 241 |
"what_went_right": "<what price behaviour or timing was favourable, even if trade {outcome.lower()}. Reference specific βΉ levels.>",
|
| 242 |
"what_went_wrong": "<what price behaviour or risk management was poor. Be specific to the entry/exit prices and % move.>",
|
| 243 |
+
"ai_prediction_assessment": "No AI prediction was run before entry, so there was no pre-trade directional confidence to validate against outcome.",
|
| 244 |
"improvement_rule": "<one concrete, actionable rule. Start with a verb: e.g. 'Always run a watchlist prediction for ... before entering a LONG position.' >"
|
| 245 |
}}"""
|
| 246 |
else:
|
|
|
|
| 766 |
try:
|
| 767 |
from huggingface_hub import hf_hub_download
|
| 768 |
local = hf_hub_download(
|
| 769 |
+
repo_id=db._HF_REPO_ID,
|
| 770 |
filename="paper_trading.db",
|
| 771 |
repo_type="dataset",
|
| 772 |
token=token,
|
|
|
|
| 1484 |
if isinstance(pred_data, dict):
|
| 1485 |
pred_data = json.dumps(pred_data)
|
| 1486 |
|
| 1487 |
+
strategy = data.get("strategy")
|
| 1488 |
+
timeframe = data.get("timeframe")
|
| 1489 |
+
|
| 1490 |
+
# Auto-fill context for manual entries so post-mortems and analytics remain actionable.
|
| 1491 |
+
if (not strategy or not timeframe or not pred_data):
|
| 1492 |
+
enriched = _autofill_trade_context(ticker)
|
| 1493 |
+
if enriched:
|
| 1494 |
+
strategy = strategy or enriched.get("strategy")
|
| 1495 |
+
timeframe = timeframe or enriched.get("timeframe")
|
| 1496 |
+
if not pred_data and enriched.get("prediction_data"):
|
| 1497 |
+
pred_data = json.dumps(enriched["prediction_data"])
|
| 1498 |
+
|
| 1499 |
trade = db.open_trade(
|
| 1500 |
ticker=ticker,
|
| 1501 |
name=name,
|
|
|
|
| 1504 |
shares=int(data["shares"]),
|
| 1505 |
stop_loss=data.get("stop_loss"),
|
| 1506 |
target=data.get("target"),
|
| 1507 |
+
strategy=strategy,
|
| 1508 |
+
timeframe=timeframe,
|
| 1509 |
prediction_data=pred_data,
|
| 1510 |
order_type=order_type,
|
| 1511 |
status=status,
|
data_sources.py
CHANGED
|
@@ -633,7 +633,7 @@ def fetch_live_price(ticker_ns: str, allow_delayed: bool = True) -> Optional[flo
|
|
| 633 |
if isinstance(hist.columns, pd.MultiIndex):
|
| 634 |
hist.columns = hist.columns.get_level_values(0)
|
| 635 |
closes = hist["Close"].dropna() if "Close" in hist.columns else pd.Series(dtype=float)
|
| 636 |
-
if not closes.empty
|
| 637 |
return round(float(closes.iloc[-1]), 2)
|
| 638 |
except Exception as e:
|
| 639 |
if _is_yf_crumb_error(e):
|
|
@@ -664,7 +664,7 @@ def fetch_live_price(ticker_ns: str, allow_delayed: bool = True) -> Optional[flo
|
|
| 664 |
if isinstance(hist.columns, pd.MultiIndex):
|
| 665 |
hist.columns = hist.columns.get_level_values(0)
|
| 666 |
closes = hist["Close"].dropna() if "Close" in hist.columns else pd.Series(dtype=float)
|
| 667 |
-
if not closes.empty
|
| 668 |
return round(float(closes.iloc[-1]), 2)
|
| 669 |
except Exception as e:
|
| 670 |
if _is_yf_crumb_error(e):
|
|
|
|
| 633 |
if isinstance(hist.columns, pd.MultiIndex):
|
| 634 |
hist.columns = hist.columns.get_level_values(0)
|
| 635 |
closes = hist["Close"].dropna() if "Close" in hist.columns else pd.Series(dtype=float)
|
| 636 |
+
if not closes.empty:
|
| 637 |
return round(float(closes.iloc[-1]), 2)
|
| 638 |
except Exception as e:
|
| 639 |
if _is_yf_crumb_error(e):
|
|
|
|
| 664 |
if isinstance(hist.columns, pd.MultiIndex):
|
| 665 |
hist.columns = hist.columns.get_level_values(0)
|
| 666 |
closes = hist["Close"].dropna() if "Close" in hist.columns else pd.Series(dtype=float)
|
| 667 |
+
if not closes.empty:
|
| 668 |
return round(float(closes.iloc[-1]), 2)
|
| 669 |
except Exception as e:
|
| 670 |
if _is_yf_crumb_error(e):
|
database.py
CHANGED
|
@@ -18,7 +18,7 @@ DB_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "paper_tradin
|
|
| 18 |
|
| 19 |
# --- HF Hub persistence (for HF Spaces free tier which has no persistent /data) ---
|
| 20 |
|
| 21 |
-
_HF_REPO_ID = "V1deh/papertrade-data"
|
| 22 |
_HF_FILENAME = "paper_trading.db"
|
| 23 |
_BACKUP_INTERVAL = 300 # upload every 5 minutes
|
| 24 |
|
|
|
|
| 18 |
|
| 19 |
# --- HF Hub persistence (for HF Spaces free tier which has no persistent /data) ---
|
| 20 |
|
| 21 |
+
_HF_REPO_ID = os.environ.get("HF_DATA_REPO_ID", "V1deh/papertrade-data")
|
| 22 |
_HF_FILENAME = "paper_trading.db"
|
| 23 |
_BACKUP_INTERVAL = 300 # upload every 5 minutes
|
| 24 |
|
research/ai_prompt_accuracy.csv
CHANGED
|
@@ -1,272 +1,27 @@
|
|
| 1 |
date,ticker,timeframe,confidence,direction,matched_strategy,ml_prob,vix,nifty_ok,source,source_provider,source_model,entry_price,target_price_lo,target_price_hi,ret_1d,ret_3d,ret_5d,ret_for_tf,max_up_1d,min_down_1d,max_up_3d,min_down_3d,max_up_5d,min_down_5d,max_up_for_tf,min_down_for_tf,intraday_hit_for_tf,target_hit_for_tf
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
2018-02-28,SUNPHARMA.NS,1D,MEDIUM,BULLISH,,0.5,13.8,True,github:gpt-4o-mini,github,gpt-4o-mini,495.83,496.23,497.42,0.009,-0.672,-3.876,0.009,1.149,-0.392,5.165,-1.55,5.165,-4.829,1.149,-0.392,1,1
|
| 29 |
-
2018-02-28,SUNPHARMA.NS,3D,MEDIUM,BULLISH,,0.5,13.8,True,github:gpt-4o-mini,github,gpt-4o-mini,495.83,495.93,496.72,0.009,-0.672,-3.876,-0.672,1.149,-0.392,5.165,-1.55,5.165,-4.829,5.165,-1.55,1,1
|
| 30 |
-
2018-02-28,SUNPHARMA.NS,5D,MEDIUM,BULLISH,,0.5,13.8,True,github:gpt-4o-mini,github,gpt-4o-mini,495.83,495.93,496.72,0.009,-0.672,-3.876,-3.876,1.149,-0.392,5.165,-1.55,5.165,-4.829,5.165,-4.829,1,1
|
| 31 |
-
2018-02-28,TCS.NS,1D,HIGH,BULLISH,,0.71,13.8,True,github:gpt-4o-mini,github,gpt-4o-mini,1229.586,1230.57,1233.52,0.087,0.255,-1.025,0.087,0.862,-0.496,3.03,-0.496,3.03,-1.567,0.862,-0.496,1,1
|
| 32 |
-
2018-02-28,TCS.NS,3D,HIGH,BULLISH,,0.71,13.8,True,github:gpt-4o-mini,github,gpt-4o-mini,1229.586,1229.83,1231.8,0.087,0.255,-1.025,0.255,0.862,-0.496,3.03,-0.496,3.03,-1.567,3.03,-0.496,1,1
|
| 33 |
-
2018-02-28,TCS.NS,5D,HIGH,BULLISH,,0.71,13.8,True,github:gpt-4o-mini,github,gpt-4o-mini,1229.586,1229.83,1231.8,0.087,0.255,-1.025,-1.025,0.862,-0.496,3.03,-0.496,3.03,-1.567,3.03,-1.567,1,1
|
| 34 |
-
2018-02-28,WIPRO.NS,1D,HIGH,BULLISH,,0.68,13.8,True,github:gpt-4o-mini,github,gpt-4o-mini,100.526,100.61,100.85,-0.102,-1.998,-2.596,-0.102,0.444,-0.546,0.444,-2.271,0.444,-3.296,0.444,-0.546,1,1
|
| 35 |
-
2018-02-28,WIPRO.NS,3D,HIGH,BULLISH,,0.68,13.8,True,github:gpt-4o-mini,github,gpt-4o-mini,100.526,100.55,100.71,-0.102,-1.998,-2.596,-1.998,0.444,-0.546,0.444,-2.271,0.444,-3.296,0.444,-2.271,1,1
|
| 36 |
-
2018-02-28,WIPRO.NS,5D,HIGH,BULLISH,,0.68,13.8,True,github:gpt-4o-mini,github,gpt-4o-mini,100.526,100.55,100.71,-0.102,-1.998,-2.596,-2.596,0.444,-0.546,0.444,-2.271,0.444,-3.296,0.444,-3.296,1,1
|
| 37 |
-
2018-04-30,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.71,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,185.797,185.95,186.39,-0.136,-2.637,-2.06,-0.136,1.523,-0.404,1.523,-2.938,1.523,-2.938,1.523,-0.404,1,1
|
| 38 |
-
2018-04-30,BAJFINANCE.NS,3D,HIGH,BULLISH,,0.71,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,185.797,185.83,186.13,-0.136,-2.637,-2.06,-2.637,1.523,-0.404,1.523,-2.938,1.523,-2.938,1.523,-2.938,1,1
|
| 39 |
-
2018-04-30,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.71,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,185.797,185.83,186.13,-0.136,-2.637,-2.06,-2.06,1.523,-0.404,1.523,-2.938,1.523,-2.938,1.523,-2.938,1,1
|
| 40 |
-
2018-04-30,HDFCBANK.NS,1D,HIGH,BULLISH,,0.71,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,446.26,446.62,447.69,1.296,2.273,1.17,1.296,1.733,0.087,2.35,0.087,2.35,0.087,1.733,0.087,1,1
|
| 41 |
-
2018-04-30,HDFCBANK.NS,3D,HIGH,BULLISH,,0.71,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,446.26,446.35,447.06,1.296,2.273,1.17,2.273,1.733,0.087,2.35,0.087,2.35,0.087,2.35,0.087,1,1
|
| 42 |
-
2018-04-30,HDFCBANK.NS,5D,HIGH,BULLISH,,0.71,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,446.26,446.35,447.06,1.296,2.273,1.17,1.17,1.733,0.087,2.35,0.087,2.35,0.087,2.35,0.087,1,1
|
| 43 |
-
2018-04-30,RELIANCE.NS,1D,HIGH,BULLISH,,0.8,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,423.561,423.9,424.92,0.976,-0.971,0.394,0.976,1.651,0.182,1.651,-1.381,1.941,-1.381,1.651,0.182,1,1
|
| 44 |
-
2018-04-30,RELIANCE.NS,3D,HIGH,BULLISH,,0.8,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,423.561,423.65,424.32,0.976,-0.971,0.394,-0.971,1.651,0.182,1.651,-1.381,1.941,-1.381,1.651,-1.381,1,1
|
| 45 |
-
2018-04-30,RELIANCE.NS,5D,HIGH,BULLISH,,0.8,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,423.561,423.65,424.32,0.976,-0.971,0.394,0.394,1.651,0.182,1.651,-1.381,1.941,-1.381,1.941,-1.381,1,1
|
| 46 |
-
2018-04-30,SUNPHARMA.NS,1D,HIGH,BULLISH,,0.64,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,489.393,489.78,490.96,-2.498,-1.978,-3.208,-2.498,0.445,-3.397,2.063,-3.397,2.063,-4.145,0.445,-3.397,1,1
|
| 47 |
-
2018-04-30,SUNPHARMA.NS,3D,HIGH,BULLISH,,0.64,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,489.393,489.49,490.27,-2.498,-1.978,-3.208,-1.978,0.445,-3.397,2.063,-3.397,2.063,-4.145,2.063,-3.397,1,1
|
| 48 |
-
2018-04-30,SUNPHARMA.NS,5D,HIGH,BULLISH,,0.64,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,489.393,489.49,490.27,-2.498,-1.978,-3.208,-3.208,0.445,-3.397,2.063,-3.397,2.063,-4.145,2.063,-4.145,1,1
|
| 49 |
-
2018-04-30,TCS.NS,1D,HIGH,BULLISH,,0.68,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,1430.955,1432.1,1435.53,-0.916,-1.454,-2.574,-0.916,0.003,-1.721,0.003,-1.758,0.003,-3.833,0.003,-1.721,1,0
|
| 50 |
-
2018-04-30,TCS.NS,3D,HIGH,BULLISH,,0.68,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,1430.955,1431.24,1433.53,-0.916,-1.454,-2.574,-1.454,0.003,-1.721,0.003,-1.758,0.003,-3.833,0.003,-1.758,1,0
|
| 51 |
-
2018-04-30,TCS.NS,5D,HIGH,BULLISH,,0.68,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,1430.955,1431.24,1433.53,-0.916,-1.454,-2.574,-2.574,0.003,-1.721,0.003,-1.758,0.003,-3.833,0.003,-3.833,1,0
|
| 52 |
-
2018-04-30,WIPRO.NS,1D,MEDIUM,BULLISH,,0.57,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,95.702,95.78,96.01,-1.148,-3.175,-2.152,-1.148,0.09,-1.578,0.09,-5.274,0.09,-5.274,0.09,-1.578,1,0
|
| 53 |
-
2018-04-30,WIPRO.NS,3D,MEDIUM,BULLISH,,0.57,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,95.702,95.72,95.87,-1.148,-3.175,-2.152,-3.175,0.09,-1.578,0.09,-5.274,0.09,-5.274,0.09,-5.274,1,0
|
| 54 |
-
2018-04-30,WIPRO.NS,5D,HIGH,BULLISH,,0.57,12.4,True,github:gpt-4o-mini,github,gpt-4o-mini,95.702,95.72,95.87,-1.148,-3.175,-2.152,-2.152,0.09,-1.578,0.09,-5.274,0.09,-5.274,0.09,-5.274,1,0
|
| 55 |
-
2018-06-26,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.72,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,230.564,230.75,231.3,-1.345,-2.999,-1.954,-1.345,0.526,-1.892,0.526,-4.796,0.526,-4.796,0.526,-1.892,1,1
|
| 56 |
-
2018-06-26,BAJFINANCE.NS,3D,HIGH,BULLISH,,0.72,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,230.564,230.61,230.98,-1.345,-2.999,-1.954,-2.999,0.526,-1.892,0.526,-4.796,0.526,-4.796,0.526,-4.796,1,1
|
| 57 |
-
2018-06-26,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.72,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,230.564,230.61,230.98,-1.345,-2.999,-1.954,-1.954,0.526,-1.892,0.526,-4.796,0.526,-4.796,0.526,-4.796,1,1
|
| 58 |
-
2018-06-26,HDFCBANK.NS,1D,HIGH,BULLISH,,0.78,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,483.62,484.01,485.17,0.903,0.705,-1.122,0.903,1.232,-0.177,2.211,-0.177,2.211,-1.454,1.232,-0.177,1,1
|
| 59 |
-
2018-06-26,HDFCBANK.NS,3D,HIGH,BULLISH,,0.78,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,483.62,483.72,484.49,0.903,0.705,-1.122,0.705,1.232,-0.177,2.211,-0.177,2.211,-1.454,2.211,-0.177,1,1
|
| 60 |
-
2018-06-26,HDFCBANK.NS,5D,HIGH,BULLISH,,0.78,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,483.62,483.72,484.49,0.903,0.705,-1.122,-1.122,1.232,-0.177,2.211,-0.177,2.211,-1.454,2.211,-1.454,1,1
|
| 61 |
-
2018-06-26,RELIANCE.NS,1D,HIGH,BULLISH,,0.64,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,430.442,430.79,431.82,-0.679,0.0,-0.118,-0.679,1.332,-1.003,1.332,-3.306,1.332,-3.306,1.332,-1.003,1,1
|
| 62 |
-
2018-06-26,RELIANCE.NS,3D,HIGH,BULLISH,,0.64,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,430.442,430.53,431.22,-0.679,0.0,-0.118,0.0,1.332,-1.003,1.332,-3.306,1.332,-3.306,1.332,-3.306,1,1
|
| 63 |
-
2018-06-26,SUNPHARMA.NS,3D,MEDIUM,BULLISH,,0.61,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,530.655,530.76,531.61,0.689,-1.562,0.113,-1.562,1.527,-0.777,1.789,-2.234,1.789,-2.522,1.789,-2.234,1,1
|
| 64 |
-
2018-06-26,SUNPHARMA.NS,5D,HIGH,BULLISH,,0.61,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,530.655,530.76,531.61,0.689,-1.562,0.113,0.113,1.527,-0.777,1.789,-2.234,1.789,-2.522,1.789,-2.522,1,1
|
| 65 |
-
2018-06-26,TCS.NS,1D,HIGH,BULLISH,,0.72,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,1513.083,1514.29,1517.93,0.324,-0.229,1.191,0.324,1.79,-0.04,1.79,-1.388,1.79,-1.388,1.79,-0.04,1,1
|
| 66 |
-
2018-06-26,TCS.NS,3D,HIGH,BULLISH,,0.72,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,1513.083,1513.39,1515.81,0.324,-0.229,1.191,-0.229,1.79,-0.04,1.79,-1.388,1.79,-1.388,1.79,-1.388,1,1
|
| 67 |
-
2018-06-26,TCS.NS,5D,HIGH,BULLISH,,0.72,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,1513.083,1513.39,1515.81,0.324,-0.229,1.191,1.191,1.79,-0.04,1.79,-1.388,1.79,-1.388,1.79,-1.388,1,1
|
| 68 |
-
2018-06-26,WIPRO.NS,1D,MEDIUM,BULLISH,,0.6,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,88.441,88.51,88.72,-0.602,1.514,1.669,-0.602,0.893,-1.32,1.902,-1.32,2.019,-1.32,0.893,-1.32,1,1
|
| 69 |
-
2018-06-26,WIPRO.NS,3D,MEDIUM,BULLISH,,0.6,12.8,True,openrouter:openai/gpt-oss-120b:free,openrouter,openai/gpt-oss-120b:free,88.441,88.46,88.6,-0.602,1.514,1.669,1.514,0.893,-1.32,1.902,-1.32,2.019,-1.32,1.902,-1.32,1,1
|
| 70 |
-
2018-06-26,WIPRO.NS,5D,MEDIUM,BULLISH,,0.6,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,88.441,88.46,88.6,-0.602,1.514,1.669,1.669,0.893,-1.32,1.902,-1.32,2.019,-1.32,2.019,-1.32,1,1
|
| 71 |
-
2018-08-23,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.65,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,282.326,282.55,283.23,0.786,1.339,1.137,0.786,1.712,-0.097,3.046,-0.097,3.461,-0.097,1.712,-0.097,1,1
|
| 72 |
-
2018-08-23,BAJFINANCE.NS,3D,HIGH,BULLISH,,0.65,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,282.326,282.38,282.83,0.786,1.339,1.137,1.339,1.712,-0.097,3.046,-0.097,3.461,-0.097,3.046,-0.097,1,1
|
| 73 |
-
2018-08-23,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.65,12.8,True,github:gpt-4o-mini,github,gpt-4o-mini,282.326,282.38,282.83,0.786,1.339,1.137,1.137,1.712,-0.097,3.046,-0.097,3.461,-0.097,3.461,-0.097,1,1
|
| 74 |
-
2018-10-24,SUNPHARMA.NS,3D,MEDIUM,BULLISH,,0.67,18.9,False,github:gpt-4o-mini,github,gpt-4o-mini,530.164,530.27,531.12,-2.094,0.508,1.673,0.508,0.307,-3.259,1.209,-3.627,1.98,-3.627,1.209,-3.627,1,1
|
| 75 |
-
2018-10-24,SUNPHARMA.NS,5D,MEDIUM,BULLISH,,0.67,18.9,False,openrouter:openai/gpt-oss-120b:free,openrouter,openai/gpt-oss-120b:free,530.164,530.27,530.8,-2.094,0.508,1.673,1.673,0.307,-3.259,1.209,-3.627,1.98,-3.627,1.98,-3.627,1,1
|
| 76 |
-
2018-10-24,TCS.NS,1D,HIGH,BULLISH,,0.67,18.9,False,github:gpt-4o-mini,github,gpt-4o-mini,1516.455,1517.67,1521.31,0.243,1.217,4.85,0.243,1.536,-1.269,1.593,-3.47,5.161,-3.47,1.536,-1.269,1,1
|
| 77 |
-
2018-10-24,TCS.NS,3D,HIGH,BULLISH,,0.67,18.9,False,github:gpt-4o-mini,github,gpt-4o-mini,1516.455,1516.76,1519.18,0.243,1.217,4.85,1.217,1.536,-1.269,1.593,-3.47,5.161,-3.47,1.593,-3.47,1,1
|
| 78 |
-
2018-10-24,TCS.NS,5D,HIGH,BULLISH,,0.67,18.9,False,github:gpt-4o-mini,github,gpt-4o-mini,1516.455,1516.76,1519.18,0.243,1.217,4.85,4.85,1.536,-1.269,1.593,-3.47,5.161,-3.47,5.161,-3.47,1,1
|
| 79 |
-
2018-10-24,WIPRO.NS,1D,HIGH,BULLISH,,0.64,18.9,False,github:gpt-4o-mini,github,gpt-4o-mini,106.019,106.1,106.36,3.157,6.703,7.254,3.157,4.647,-4.145,7.578,-4.145,8.371,-4.145,4.647,-4.145,1,1
|
| 80 |
-
2018-10-24,WIPRO.NS,3D,HIGH,BULLISH,,0.64,18.9,False,github:gpt-4o-mini,github,gpt-4o-mini,106.019,106.04,106.21,3.157,6.703,7.254,6.703,4.647,-4.145,7.578,-4.145,8.371,-4.145,7.578,-4.145,1,1
|
| 81 |
-
2018-10-24,WIPRO.NS,5D,HIGH,BULLISH,,0.64,18.9,False,github:gpt-4o-mini,github,gpt-4o-mini,106.019,106.04,106.21,3.157,6.703,7.254,7.254,4.647,-4.145,7.578,-4.145,8.371,-4.145,8.371,-4.145,1,1
|
| 82 |
-
2018-12-21,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.8,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,252.804,253.01,253.61,-1.017,-0.158,2.08,-1.017,0.525,-1.476,1.37,-3.379,2.896,-3.379,0.525,-1.476,1,1
|
| 83 |
-
2018-12-21,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.8,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,252.804,252.85,253.26,-1.017,-0.158,2.08,2.08,0.525,-1.476,1.37,-3.379,2.896,-3.379,2.896,-3.379,1,1
|
| 84 |
-
2018-12-21,HDFCBANK.NS,1D,HIGH,BULLISH,,0.71,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,487.651,488.04,489.21,-1.445,-0.289,0.5,-1.445,-0.339,-1.601,1.281,-1.997,1.281,-1.997,-0.339,-1.601,0,0
|
| 85 |
-
2018-12-21,HDFCBANK.NS,3D,HIGH,BULLISH,,0.71,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,487.651,487.75,488.53,-1.445,-0.289,0.5,-0.289,-0.339,-1.601,1.281,-1.997,1.281,-1.997,1.281,-1.997,1,1
|
| 86 |
-
2018-12-21,HDFCBANK.NS,5D,HIGH,BULLISH,,0.71,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,487.651,487.75,488.53,-1.445,-0.289,0.5,0.5,-0.339,-1.601,1.281,-1.997,1.281,-1.997,1.281,-1.997,1,1
|
| 87 |
-
2018-12-21,RELIANCE.NS,1D,MEDIUM,BULLISH,,0.57,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,486.99,487.38,488.55,-1.004,1.818,1.913,-1.004,0.273,-1.241,2.436,-3.14,3.186,-3.14,0.273,-1.241,1,1
|
| 88 |
-
2018-12-21,RELIANCE.NS,3D,MEDIUM,BULLISH,,0.57,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,486.99,487.09,487.87,-1.004,1.818,1.913,1.818,0.273,-1.241,2.436,-3.14,3.186,-3.14,2.436,-3.14,1,1
|
| 89 |
-
2018-12-21,RELIANCE.NS,5D,MEDIUM,BULLISH,,0.57,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,486.99,487.09,487.87,-1.004,1.818,1.913,1.913,0.273,-1.241,2.436,-3.14,3.186,-3.14,3.186,-3.14,1,1
|
| 90 |
-
2018-12-21,SUNPHARMA.NS,1D,HIGH,BULLISH,,0.67,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,395.092,395.41,396.36,-0.223,-3.327,1.223,-0.223,2.046,-0.705,2.046,-3.597,2.046,-3.597,2.046,-0.705,1,1
|
| 91 |
-
2018-12-21,SUNPHARMA.NS,3D,HIGH,BULLISH,,0.67,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,395.092,395.17,395.8,-0.223,-3.327,1.223,-3.327,2.046,-0.705,2.046,-3.597,2.046,-3.597,2.046,-3.597,1,1
|
| 92 |
-
2018-12-21,SUNPHARMA.NS,5D,HIGH,BULLISH,,0.67,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,395.092,395.17,395.8,-0.223,-3.327,1.223,1.223,2.046,-0.705,2.046,-3.597,2.046,-3.597,2.046,-3.597,1,1
|
| 93 |
-
2018-12-21,TCS.NS,1D,HIGH,BULLISH,,0.78,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,1555.258,1556.5,1560.23,1.197,0.694,-0.145,1.197,2.273,0.485,2.421,-1.348,2.421,-1.348,2.273,0.485,1,0
|
| 94 |
-
2018-12-21,TCS.NS,3D,HIGH,BULLISH,,0.78,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,1555.258,1555.57,1558.06,1.197,0.694,-0.145,0.694,2.273,0.485,2.421,-1.348,2.421,-1.348,2.421,-1.348,1,1
|
| 95 |
-
2018-12-21,TCS.NS,5D,HIGH,BULLISH,,0.78,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,1555.258,1555.57,1558.06,1.197,0.694,-0.145,-0.145,2.273,0.485,2.421,-1.348,2.421,-1.348,2.421,-1.348,1,1
|
| 96 |
-
2018-12-21,WIPRO.NS,1D,HIGH,BULLISH,,0.68,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,110.585,110.67,110.94,1.428,1.661,2.717,1.428,2.608,-0.217,2.872,-0.854,3.632,-0.854,2.608,-0.217,1,1
|
| 97 |
-
2018-12-21,WIPRO.NS,3D,HIGH,BULLISH,,0.68,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,110.585,110.61,110.78,1.428,1.661,2.717,1.661,2.608,-0.217,2.872,-0.854,3.632,-0.854,2.872,-0.854,1,1
|
| 98 |
-
2018-12-21,WIPRO.NS,5D,HIGH,BULLISH,,0.68,16.0,True,github:gpt-4o-mini,github,gpt-4o-mini,110.585,110.61,110.78,1.428,1.661,2.717,2.717,2.608,-0.217,2.872,-0.854,3.632,-0.854,3.632,-0.854,1,1
|
| 99 |
-
2019-02-19,BAJFINANCE.NS,1D,MEDIUM,BULLISH,,0.64,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,249.736,249.94,250.54,1.811,3.149,3.826,1.811,2.149,0.438,4.461,0.438,4.618,0.438,2.149,0.438,1,0
|
| 100 |
-
2019-02-19,BAJFINANCE.NS,3D,MEDIUM,BULLISH,,0.64,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,249.736,249.79,250.19,1.811,3.149,3.826,3.149,2.149,0.438,4.461,0.438,4.618,0.438,4.461,0.438,1,0
|
| 101 |
-
2019-02-19,BAJFINANCE.NS,5D,MEDIUM,BULLISH,,0.64,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,249.736,249.79,250.19,1.811,3.149,3.826,3.826,2.149,0.438,4.461,0.438,4.618,0.438,4.618,0.438,1,0
|
| 102 |
-
2019-02-19,HDFCBANK.NS,1D,MEDIUM,BULLISH,,0.64,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,481.391,481.78,482.93,1.166,0.355,1.276,1.166,1.293,-0.103,2.114,-0.103,2.202,-0.103,1.293,-0.103,1,1
|
| 103 |
-
2019-02-19,HDFCBANK.NS,3D,MEDIUM,BULLISH,,0.64,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,481.391,481.49,482.26,1.166,0.355,1.276,0.355,1.293,-0.103,2.114,-0.103,2.202,-0.103,2.114,-0.103,1,1
|
| 104 |
-
2019-02-19,HDFCBANK.NS,5D,MEDIUM,BULLISH,,0.64,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,481.391,481.49,482.26,1.166,0.355,1.276,1.276,1.293,-0.103,2.114,-0.103,2.202,-0.103,2.202,-0.103,1,1
|
| 105 |
-
2019-02-19,RELIANCE.NS,1D,MEDIUM,BULLISH,,0.64,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,538.291,538.72,540.01,1.501,1.336,0.341,1.501,1.965,0.238,3.429,0.238,3.429,-0.831,1.965,0.238,1,0
|
| 106 |
-
2019-02-19,RELIANCE.NS,3D,MEDIUM,BULLISH,,0.64,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,538.291,538.4,539.26,1.501,1.336,0.341,1.336,1.965,0.238,3.429,0.238,3.429,-0.831,3.429,0.238,1,0
|
| 107 |
-
2019-02-19,RELIANCE.NS,5D,MEDIUM,BULLISH,,0.64,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,538.291,538.4,539.26,1.501,1.336,0.341,0.341,1.965,0.238,3.429,0.238,3.429,-0.831,3.429,-0.831,1,1
|
| 108 |
-
2019-02-19,SUNPHARMA.NS,1D,MEDIUM,BULLISH,,0.57,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,384.269,384.58,385.5,2.103,4.073,5.343,2.103,2.611,0.58,5.584,0.58,6.37,0.58,2.611,0.58,1,0
|
| 109 |
-
2019-02-19,SUNPHARMA.NS,3D,MEDIUM,BULLISH,,0.57,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,384.269,384.35,384.96,2.103,4.073,5.343,4.073,2.611,0.58,5.584,0.58,6.37,0.58,5.584,0.58,1,0
|
| 110 |
-
2019-02-19,SUNPHARMA.NS,5D,MEDIUM,BULLISH,,0.57,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,384.269,384.35,384.96,2.103,4.073,5.343,5.343,2.611,0.58,5.584,0.58,6.37,0.58,6.37,0.58,1,0
|
| 111 |
-
2019-02-19,TCS.NS,1D,HIGH,BULLISH,,0.78,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,1565.991,1567.24,1571.0,0.522,1.095,7.03,0.522,1.522,-1.234,1.848,-1.234,7.368,-1.234,1.522,-1.234,1,1
|
| 112 |
-
2019-02-19,TCS.NS,3D,HIGH,BULLISH,,0.78,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,1565.991,1566.3,1568.81,0.522,1.095,7.03,1.095,1.522,-1.234,1.848,-1.234,7.368,-1.234,1.848,-1.234,1,1
|
| 113 |
-
2019-02-19,TCS.NS,5D,MEDIUM,BULLISH,,0.78,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,1565.991,1566.3,1568.81,0.522,1.095,7.03,7.03,1.522,-1.234,1.848,-1.234,7.368,-1.234,7.368,-1.234,1,1
|
| 114 |
-
2019-02-19,WIPRO.NS,1D,MEDIUM,BULLISH,,0.64,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,125.134,125.23,125.53,2.407,4.21,6.658,2.407,2.903,-0.619,4.554,-0.619,7.016,-0.619,2.903,-0.619,1,1
|
| 115 |
-
2019-02-19,WIPRO.NS,3D,MEDIUM,BULLISH,,0.64,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,125.134,125.16,125.36,2.407,4.21,6.658,4.21,2.903,-0.619,4.554,-0.619,7.016,-0.619,4.554,-0.619,1,1
|
| 116 |
-
2019-02-19,WIPRO.NS,5D,MEDIUM,BULLISH,,0.64,18.5,False,github:gpt-4o-mini,github,gpt-4o-mini,125.134,125.16,125.36,2.407,4.21,6.658,6.658,2.903,-0.619,4.554,-0.619,7.016,-0.619,7.016,-0.619,1,1
|
| 117 |
-
2019-04-23,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.71,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,296.102,296.34,297.05,1.911,2.036,3.186,1.911,2.107,-0.1,2.614,-0.1,3.753,-0.1,2.107,-0.1,1,1
|
| 118 |
-
2019-04-23,BAJFINANCE.NS,3D,HIGH,BULLISH,,0.71,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,296.102,296.16,296.63,1.911,2.036,3.186,2.036,2.107,-0.1,2.614,-0.1,3.753,-0.1,2.614,-0.1,1,1
|
| 119 |
-
2019-04-23,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.71,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,296.102,296.16,296.63,1.911,2.036,3.186,3.186,2.107,-0.1,2.614,-0.1,3.753,-0.1,3.753,-0.1,1,1
|
| 120 |
-
2019-04-23,HDFCBANK.NS,1D,HIGH,BULLISH,,0.64,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,518.638,519.05,520.3,1.534,1.588,4.921,1.534,1.719,0.078,2.383,0.078,5.093,0.078,1.719,0.078,1,1
|
| 121 |
-
2019-04-23,HDFCBANK.NS,3D,HIGH,BULLISH,,0.64,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,518.638,518.74,519.57,1.534,1.588,4.921,1.588,1.719,0.078,2.383,0.078,5.093,0.078,2.383,0.078,1,1
|
| 122 |
-
2019-04-23,HDFCBANK.NS,5D,HIGH,BULLISH,,0.64,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,518.638,518.74,519.57,1.534,1.588,4.921,4.921,1.719,0.078,2.383,0.078,5.093,0.078,5.093,0.078,1,1
|
| 123 |
-
2019-04-23,RELIANCE.NS,1D,HIGH,BULLISH,,0.71,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,603.691,604.17,605.62,1.881,2.123,3.021,1.881,2.269,0.176,3.56,-0.092,3.67,-0.092,2.269,0.176,1,1
|
| 124 |
-
2019-04-23,RELIANCE.NS,3D,HIGH,BULLISH,,0.71,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,603.691,603.81,604.78,1.881,2.123,3.021,2.123,2.269,0.176,3.56,-0.092,3.67,-0.092,3.56,-0.092,1,1
|
| 125 |
-
2019-04-23,RELIANCE.NS,5D,HIGH,BULLISH,,0.71,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,603.691,603.81,604.78,1.881,2.123,3.021,3.021,2.269,0.176,3.56,-0.092,3.67,-0.092,3.67,-0.092,1,1
|
| 126 |
-
2019-04-23,SUNPHARMA.NS,1D,HIGH,BULLISH,,0.68,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,435.27,435.62,436.66,0.171,-0.95,-3.489,0.171,0.309,-1.291,1.291,-1.931,1.291,-4.813,0.309,-1.291,1,1
|
| 127 |
-
2019-04-23,SUNPHARMA.NS,3D,HIGH,BULLISH,,0.68,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,435.27,435.36,436.05,0.171,-0.95,-3.489,-0.95,0.309,-1.291,1.291,-1.931,1.291,-4.813,1.291,-1.931,1,1
|
| 128 |
-
2019-04-23,SUNPHARMA.NS,5D,HIGH,BULLISH,,0.68,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,435.27,435.36,436.05,0.171,-0.95,-3.489,-3.489,0.309,-1.291,1.291,-1.931,1.291,-4.813,1.291,-4.813,1,1
|
| 129 |
-
2019-04-23,TCS.NS,1D,HIGH,BULLISH,,0.78,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,1771.728,1773.15,1777.4,1.318,3.875,2.8,1.318,1.854,0.049,4.125,0.049,5.192,0.049,1.854,0.049,1,1
|
| 130 |
-
2019-04-23,TCS.NS,3D,HIGH,BULLISH,,0.78,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,1771.728,1772.08,1774.92,1.318,3.875,2.8,3.875,1.854,0.049,4.125,0.049,5.192,0.049,4.125,0.049,1,1
|
| 131 |
-
2019-04-23,TCS.NS,5D,HIGH,BULLISH,,0.78,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,1771.728,1772.08,1774.92,1.318,3.875,2.8,2.8,1.854,0.049,4.125,0.049,5.192,0.049,5.192,0.049,1,1
|
| 132 |
-
2019-04-23,WIPRO.NS,1D,HIGH,BULLISH,,0.68,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,133.632,133.74,134.06,0.67,1.271,0.876,0.67,1.099,-0.309,1.907,-0.309,2.868,-0.309,1.099,-0.309,1,1
|
| 133 |
-
2019-04-23,WIPRO.NS,3D,HIGH,BULLISH,,0.68,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,133.632,133.66,133.87,0.67,1.271,0.876,1.271,1.099,-0.309,1.907,-0.309,2.868,-0.309,1.907,-0.309,1,1
|
| 134 |
-
2019-04-23,WIPRO.NS,5D,HIGH,BULLISH,,0.68,24.6,True,github:gpt-4o-mini,github,gpt-4o-mini,133.632,133.66,133.87,0.67,1.271,0.876,0.876,1.099,-0.309,1.907,-0.309,2.868,-0.309,2.868,-0.309,1,1
|
| 135 |
-
2019-06-21,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.71,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,347.887,348.17,349.0,-0.575,1.742,3.232,-0.575,0.394,-0.92,1.939,-0.996,3.573,-0.996,0.394,-0.92,1,1
|
| 136 |
-
2019-06-21,BAJFINANCE.NS,3D,HIGH,BULLISH,,0.71,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,347.887,347.96,348.51,-0.575,1.742,3.232,1.742,0.394,-0.92,1.939,-0.996,3.573,-0.996,1.939,-0.996,1,1
|
| 137 |
-
2019-06-21,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.71,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,347.887,347.96,348.51,-0.575,1.742,3.232,3.232,0.394,-0.92,1.939,-0.996,3.573,-0.996,3.573,-0.996,1,1
|
| 138 |
-
2019-06-21,HDFCBANK.NS,1D,HIGH,BULLISH,,0.75,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,561.118,561.57,562.91,0.155,2.224,1.224,0.155,0.679,-0.174,2.311,-0.464,3.326,-0.464,0.679,-0.174,1,1
|
| 139 |
-
2019-06-21,HDFCBANK.NS,3D,HIGH,BULLISH,,0.75,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,561.118,561.23,562.13,0.155,2.224,1.224,2.224,0.679,-0.174,2.311,-0.464,3.326,-0.464,2.311,-0.464,1,1
|
| 140 |
-
2019-06-21,HDFCBANK.NS,5D,HIGH,BULLISH,,0.75,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,561.118,561.23,562.13,0.155,2.224,1.224,1.224,0.679,-0.174,2.311,-0.464,3.326,-0.464,3.326,-0.464,1,1
|
| 141 |
-
2019-06-21,RELIANCE.NS,1D,MEDIUM,BULLISH,,0.61,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,566.354,566.81,568.17,-1.336,1.145,-2.063,-1.336,-0.238,-1.751,1.962,-1.973,1.962,-2.411,-0.238,-1.751,0,0
|
| 142 |
-
2019-06-21,RELIANCE.NS,3D,HIGH,BULLISH,,0.61,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,566.354,566.47,567.37,-1.336,1.145,-2.063,1.145,-0.238,-1.751,1.962,-1.973,1.962,-2.411,1.962,-1.973,1,1
|
| 143 |
-
2019-06-21,RELIANCE.NS,5D,HIGH,BULLISH,,0.61,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,566.354,566.47,567.37,-1.336,1.145,-2.063,-2.063,-0.238,-1.751,1.962,-1.973,1.962,-2.411,1.962,-2.411,1,1
|
| 144 |
-
2019-06-21,SUNPHARMA.NS,1D,MEDIUM,BULLISH,,0.6,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,355.611,355.9,356.75,0.17,4.35,4.741,0.17,0.679,-1.385,5.421,-1.385,7.053,-1.385,0.679,-1.385,1,1
|
| 145 |
-
2019-06-21,SUNPHARMA.NS,3D,MEDIUM,BULLISH,,0.6,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,355.611,355.68,356.25,0.17,4.35,4.741,4.35,0.679,-1.385,5.421,-1.385,7.053,-1.385,5.421,-1.385,1,1
|
| 146 |
-
2019-06-21,SUNPHARMA.NS,5D,MEDIUM,BULLISH,,0.6,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,355.611,355.68,356.25,0.17,4.35,4.741,4.741,0.679,-1.385,5.421,-1.385,7.053,-1.385,7.053,-1.385,1,1
|
| 147 |
-
2019-06-21,TCS.NS,1D,HIGH,BULLISH,,0.8,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,1864.635,1866.13,1870.6,1.14,0.193,-1.007,1.14,1.34,0.042,1.34,0.007,1.34,-1.216,1.34,0.042,1,1
|
| 148 |
-
2019-06-21,TCS.NS,3D,HIGH,BULLISH,,0.8,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,1864.635,1865.01,1867.99,1.14,0.193,-1.007,0.193,1.34,0.042,1.34,0.007,1.34,-1.216,1.34,0.007,1,1
|
| 149 |
-
2019-06-21,TCS.NS,5D,HIGH,BULLISH,,0.8,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,1864.635,1865.01,1867.99,1.14,0.193,-1.007,-1.007,1.34,0.042,1.34,0.007,1.34,-1.216,1.34,-1.216,1,1
|
| 150 |
-
2019-06-21,WIPRO.NS,1D,HIGH,BULLISH,,0.64,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,131.222,131.33,131.64,-0.682,0.105,-1.872,-0.682,0.612,-0.945,0.752,-1.399,0.752,-2.047,0.612,-0.945,1,1
|
| 151 |
-
2019-06-21,WIPRO.NS,3D,HIGH,BULLISH,,0.64,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,131.222,131.25,131.46,-0.682,0.105,-1.872,0.105,0.612,-0.945,0.752,-1.399,0.752,-2.047,0.752,-1.399,1,1
|
| 152 |
-
2019-06-21,WIPRO.NS,5D,HIGH,BULLISH,,0.64,14.6,True,github:gpt-4o-mini,github,gpt-4o-mini,131.222,131.25,131.46,-0.682,0.105,-1.872,-1.872,0.612,-0.945,0.752,-1.399,0.752,-2.047,0.752,-2.047,1,1
|
| 153 |
-
2019-08-20,BAJFINANCE.NS,1D,MEDIUM,BULLISH,,0.64,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,321.938,322.2,322.97,-0.991,-3.635,1.932,-0.991,0.845,-1.454,0.845,-8.989,3.154,-8.989,0.845,-1.454,1,1
|
| 154 |
-
2019-08-20,BAJFINANCE.NS,3D,MEDIUM,BULLISH,,0.64,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,321.938,322.0,322.52,-0.991,-3.635,1.932,-3.635,0.845,-1.454,0.845,-8.989,3.154,-8.989,0.845,-8.989,1,1
|
| 155 |
-
2019-08-20,BAJFINANCE.NS,5D,MEDIUM,BULLISH,,0.64,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,321.938,322.0,322.52,-0.991,-3.635,1.932,1.932,0.845,-1.454,0.845,-8.989,3.154,-8.989,3.154,-8.989,1,1
|
| 156 |
-
2019-08-20,HDFCBANK.NS,1D,MEDIUM,BULLISH,,0.64,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,517.269,517.68,518.92,0.236,-2.607,1.772,0.236,0.928,-0.288,0.928,-3.648,2.355,-3.648,0.928,-0.288,1,1
|
| 157 |
-
2019-08-20,HDFCBANK.NS,3D,MEDIUM,BULLISH,,0.64,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,517.269,517.37,518.2,0.236,-2.607,1.772,-2.607,0.928,-0.288,0.928,-3.648,2.355,-3.648,0.928,-3.648,1,1
|
| 158 |
-
2019-08-20,HDFCBANK.NS,5D,HIGH,BULLISH,,0.64,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,517.269,517.37,518.2,0.236,-2.607,1.772,1.772,0.928,-0.288,0.928,-3.648,2.355,-3.648,2.355,-3.648,1,1
|
| 159 |
-
2019-08-20,RELIANCE.NS,1D,HIGH,BULLISH,,0.71,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,568.173,568.63,569.99,-0.392,-0.008,-0.086,-0.392,0.212,-0.741,0.631,-3.876,1.415,-3.876,0.212,-0.741,1,1
|
| 160 |
-
2019-08-20,RELIANCE.NS,3D,MEDIUM,BULLISH,,0.71,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,568.173,568.29,569.2,-0.392,-0.008,-0.086,-0.008,0.212,-0.741,0.631,-3.876,1.415,-3.876,0.631,-3.876,1,1
|
| 161 |
-
2019-08-20,RELIANCE.NS,5D,MEDIUM,BULLISH,,0.71,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,568.173,568.29,569.2,-0.392,-0.008,-0.086,-0.086,0.212,-0.741,0.631,-3.876,1.415,-3.876,1.415,-3.876,1,1
|
| 162 |
-
2019-08-20,SUNPHARMA.NS,1D,MEDIUM,BULLISH,,0.64,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,393.545,393.86,394.8,-0.927,1.639,-0.986,-0.927,1.176,-1.734,2.15,-2.946,2.15,-2.946,1.176,-1.734,1,1
|
| 163 |
-
2019-08-20,SUNPHARMA.NS,3D,MEDIUM,BULLISH,,0.64,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,393.545,393.62,394.25,-0.927,1.639,-0.986,1.639,1.176,-1.734,2.15,-2.946,2.15,-2.946,2.15,-2.946,1,1
|
| 164 |
-
2019-08-20,SUNPHARMA.NS,5D,MEDIUM,BULLISH,,0.64,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,393.545,393.62,394.25,-0.927,1.639,-0.986,-0.986,1.176,-1.734,2.15,-2.946,2.15,-2.946,2.15,-2.946,1,1
|
| 165 |
-
2019-08-20,TCS.NS,1D,MEDIUM,BULLISH,,0.71,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,1816.571,1818.02,1822.38,-0.025,2.787,2.275,-0.025,0.697,-0.206,3.345,-0.766,4.356,-0.766,0.697,-0.206,1,1
|
| 166 |
-
2019-08-20,TCS.NS,3D,MEDIUM,BULLISH,,0.71,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,1816.571,1816.93,1819.84,-0.025,2.787,2.275,2.787,0.697,-0.206,3.345,-0.766,4.356,-0.766,3.345,-0.766,1,1
|
| 167 |
-
2019-08-20,TCS.NS,5D,MEDIUM,BULLISH,,0.71,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,1816.571,1816.93,1819.84,-0.025,2.787,2.275,2.275,0.697,-0.206,3.345,-0.766,4.356,-0.766,4.356,-0.766,1,1
|
| 168 |
-
2019-08-20,WIPRO.NS,1D,MEDIUM,BULLISH,,0.71,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,116.28,116.37,116.65,-0.355,-0.75,-1.263,-0.355,0.632,-0.869,1.5,-1.895,1.5,-2.448,0.632,-0.869,1,1
|
| 169 |
-
2019-08-20,WIPRO.NS,3D,MEDIUM,BULLISH,,0.71,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,116.28,116.3,116.49,-0.355,-0.75,-1.263,-0.75,0.632,-0.869,1.5,-1.895,1.5,-2.448,1.5,-1.895,1,1
|
| 170 |
-
2019-08-20,WIPRO.NS,5D,MEDIUM,BULLISH,,0.71,16.6,False,github:gpt-4o-mini,github,gpt-4o-mini,116.28,116.3,116.49,-0.355,-0.75,-1.263,-1.263,0.632,-0.869,1.5,-1.895,1.5,-2.448,1.5,-2.448,1,1
|
| 171 |
-
2019-10-22,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.75,16.8,True,github:gpt-4o-mini,github,gpt-4o-mini,394.264,394.58,395.53,0.104,-1.163,0.325,0.104,1.88,-1.64,1.88,-3.325,1.88,-3.325,1.88,-1.64,1,1
|
| 172 |
-
2019-10-22,BAJFINANCE.NS,3D,HIGH,BULLISH,,0.75,16.8,True,github:gpt-4o-mini,github,gpt-4o-mini,394.264,394.34,394.97,0.104,-1.163,0.325,-1.163,1.88,-1.64,1.88,-3.325,1.88,-3.325,1.88,-3.325,1,1
|
| 173 |
-
2019-10-22,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.75,16.8,True,github:gpt-4o-mini,github,gpt-4o-mini,394.264,394.34,394.97,0.104,-1.163,0.325,0.325,1.88,-1.64,1.88,-3.325,1.88,-3.325,1.88,-3.325,1,1
|
| 174 |
-
2019-12-18,HDFCBANK.NS,1D,HIGH,BULLISH,,0.8,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,602.083,602.56,604.01,-0.275,0.778,-1.695,-0.275,1.018,-0.484,1.018,-0.952,1.018,-2.143,1.018,-0.484,1,1
|
| 175 |
-
2019-12-18,HDFCBANK.NS,3D,HIGH,BULLISH,,0.8,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,602.083,602.2,603.17,-0.275,0.778,-1.695,0.778,1.018,-0.484,1.018,-0.952,1.018,-2.143,1.018,-0.952,1,1
|
| 176 |
-
2019-12-18,HDFCBANK.NS,5D,HIGH,BULLISH,,0.8,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,602.083,602.2,603.17,-0.275,0.778,-1.695,-1.695,1.018,-0.484,1.018,-0.952,1.018,-2.143,1.018,-2.143,1,1
|
| 177 |
-
2019-12-18,RELIANCE.NS,1D,HIGH,BULLISH,,0.71,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,701.717,702.28,703.96,2.164,-0.282,-3.836,2.164,2.478,-0.257,2.646,-1.145,2.646,-4.169,2.478,-0.257,1,1
|
| 178 |
-
2019-12-18,RELIANCE.NS,3D,HIGH,BULLISH,,0.71,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,701.717,701.86,702.98,2.164,-0.282,-3.836,-0.282,2.478,-0.257,2.646,-1.145,2.646,-4.169,2.646,-1.145,1,1
|
| 179 |
-
2019-12-18,RELIANCE.NS,5D,HIGH,BULLISH,,0.71,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,701.717,701.86,702.98,2.164,-0.282,-3.836,-3.836,2.478,-0.257,2.646,-1.145,2.646,-4.169,2.646,-4.169,1,1
|
| 180 |
-
2019-12-18,SUNPHARMA.NS,1D,HIGH,BULLISH,,0.64,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,411.17,411.5,412.49,-1.399,-2.581,-4.002,-1.399,0.193,-2.786,0.193,-2.99,0.193,-4.343,0.193,-2.786,1,0
|
| 181 |
-
2019-12-18,SUNPHARMA.NS,3D,HIGH,BULLISH,,0.64,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,411.17,411.25,411.91,-1.399,-2.581,-4.002,-2.581,0.193,-2.786,0.193,-2.99,0.193,-4.343,0.193,-2.99,1,1
|
| 182 |
-
2019-12-18,SUNPHARMA.NS,5D,HIGH,BULLISH,,0.64,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,411.17,411.25,411.91,-1.399,-2.581,-4.002,-4.002,0.193,-2.786,0.193,-2.99,0.193,-4.343,0.193,-4.343,1,1
|
| 183 |
-
2019-12-18,TCS.NS,1D,HIGH,BULLISH,,0.75,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,1841.277,1842.75,1847.17,2.828,2.95,1.578,2.828,3.172,-0.009,3.642,-0.009,3.642,-0.009,3.172,-0.009,1,1
|
| 184 |
-
2019-12-18,TCS.NS,3D,HIGH,BULLISH,,0.75,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,1841.277,1841.64,1844.59,2.828,2.95,1.578,2.95,3.172,-0.009,3.642,-0.009,3.642,-0.009,3.642,-0.009,1,1
|
| 185 |
-
2019-12-18,TCS.NS,5D,HIGH,BULLISH,,0.75,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,1841.277,1841.64,1844.59,2.828,2.95,1.578,1.578,3.172,-0.009,3.642,-0.009,3.642,-0.009,3.642,-0.009,1,1
|
| 186 |
-
2019-12-18,WIPRO.NS,1D,HIGH,BULLISH,,0.68,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,113.985,114.08,114.35,0.362,2.235,0.805,0.362,0.946,-0.262,2.578,-0.403,2.578,-0.403,0.946,-0.262,1,1
|
| 187 |
-
2019-12-18,WIPRO.NS,3D,HIGH,BULLISH,,0.68,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,113.985,114.01,114.19,0.362,2.235,0.805,2.235,0.946,-0.262,2.578,-0.403,2.578,-0.403,2.578,-0.403,1,1
|
| 188 |
-
2019-12-18,WIPRO.NS,5D,HIGH,BULLISH,,0.68,12.3,True,github:gpt-4o-mini,github,gpt-4o-mini,113.985,114.01,114.19,0.362,2.235,0.805,0.805,0.946,-0.262,2.578,-0.403,2.578,-0.403,2.578,-0.403,1,1
|
| 189 |
-
2020-02-13,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.68,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,468.658,469.03,470.16,-0.284,-0.779,1.775,-0.284,0.41,-0.57,0.41,-1.955,2.67,-1.955,0.41,-0.57,1,1
|
| 190 |
-
2020-02-13,BAJFINANCE.NS,3D,HIGH,BULLISH,,0.68,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,468.658,468.75,469.5,-0.284,-0.779,1.775,-0.779,0.41,-0.57,0.41,-1.955,2.67,-1.955,0.41,-1.955,1,1
|
| 191 |
-
2020-02-13,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.68,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,468.658,468.75,469.5,-0.284,-0.779,1.775,1.775,0.41,-0.57,0.41,-1.955,2.67,-1.955,2.67,-1.955,1,1
|
| 192 |
-
2020-02-13,HDFCBANK.NS,1D,HIGH,BULLISH,,0.64,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,578.346,578.81,580.2,-1.776,-2.268,-1.957,-1.776,0.564,-2.127,0.564,-3.053,0.564,-3.053,0.564,-2.127,1,1
|
| 193 |
-
2020-02-13,HDFCBANK.NS,3D,HIGH,BULLISH,,0.64,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,578.346,578.46,579.39,-1.776,-2.268,-1.957,-2.268,0.564,-2.127,0.564,-3.053,0.564,-3.053,0.564,-3.053,1,1
|
| 194 |
-
2020-02-13,HDFCBANK.NS,5D,HIGH,BULLISH,,0.64,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,578.346,578.46,579.39,-1.776,-2.268,-1.957,-1.957,0.564,-2.127,0.564,-3.053,0.564,-3.053,0.564,-3.053,1,1
|
| 195 |
-
2020-02-13,RELIANCE.NS,1D,HIGH,BULLISH,,0.71,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,656.43,656.96,658.53,0.912,-0.458,0.8,0.912,1.852,-1.428,2.171,-1.428,2.296,-1.428,1.852,-1.428,1,1
|
| 196 |
-
2020-02-13,RELIANCE.NS,3D,HIGH,BULLISH,,0.71,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,656.43,656.56,657.61,0.912,-0.458,0.8,-0.458,1.852,-1.428,2.171,-1.428,2.296,-1.428,2.171,-1.428,1,1
|
| 197 |
-
2020-02-13,RELIANCE.NS,5D,HIGH,BULLISH,,0.71,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,656.43,656.56,657.61,0.912,-0.458,0.8,0.8,1.852,-1.428,2.171,-1.428,2.296,-1.428,2.296,-1.428,1,1
|
| 198 |
-
2020-02-13,SUNPHARMA.NS,1D,MEDIUM,BULLISH,,0.6,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,391.722,392.04,392.98,-0.095,-1.754,-2.644,-0.095,1.384,-0.585,1.384,-4.062,1.384,-4.062,1.384,-0.585,1,1
|
| 199 |
-
2020-02-13,SUNPHARMA.NS,3D,MEDIUM,BULLISH,,0.6,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,391.722,391.8,392.43,-0.095,-1.754,-2.644,-1.754,1.384,-0.585,1.384,-4.062,1.384,-4.062,1.384,-4.062,1,1
|
| 200 |
-
2020-02-13,SUNPHARMA.NS,5D,MEDIUM,BULLISH,,0.6,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,391.722,391.8,392.43,-0.095,-1.754,-2.644,-2.644,1.384,-0.585,1.384,-4.062,1.384,-4.062,1.384,-4.062,1,1
|
| 201 |
-
2020-02-13,TCS.NS,1D,HIGH,BULLISH,,0.78,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,1866.06,1867.55,1872.03,-0.354,1.086,-1.604,-0.354,0.915,-0.956,1.325,-0.956,1.736,-1.857,0.915,-0.956,1,1
|
| 202 |
-
2020-02-13,TCS.NS,3D,HIGH,BULLISH,,0.78,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,1866.06,1866.43,1869.42,-0.354,1.086,-1.604,1.086,0.915,-0.956,1.325,-0.956,1.736,-1.857,1.325,-0.956,1,1
|
| 203 |
-
2020-02-13,TCS.NS,5D,HIGH,BULLISH,,0.78,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,1866.06,1866.43,1869.42,-0.354,1.086,-1.604,-1.604,0.915,-0.956,1.325,-0.956,1.736,-1.857,1.736,-1.857,1,1
|
| 204 |
-
2020-02-13,WIPRO.NS,1D,MEDIUM,BULLISH,,0.57,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,112.348,112.44,112.71,-0.349,0.123,0.8,-0.349,0.656,-0.718,0.656,-1.026,1.969,-1.026,0.656,-0.718,1,1
|
| 205 |
-
2020-02-13,WIPRO.NS,3D,MEDIUM,BULLISH,,0.57,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,112.348,112.37,112.55,-0.349,0.123,0.8,0.123,0.656,-0.718,0.656,-1.026,1.969,-1.026,0.656,-1.026,1,1
|
| 206 |
-
2020-02-13,WIPRO.NS,5D,HIGH,BULLISH,,0.57,13.4,True,github:gpt-4o-mini,github,gpt-4o-mini,112.348,112.37,112.55,-0.349,0.123,0.8,0.8,0.656,-0.718,0.656,-1.026,1.969,-1.026,1.969,-1.026,1,1
|
| 207 |
-
2020-04-17,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.71,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,226.098,226.28,226.82,0.004,-6.928,-14.379,0.004,1.618,-1.869,1.618,-12.382,1.618,-14.648,1.618,-1.869,1,1
|
| 208 |
-
2020-04-17,BAJFINANCE.NS,3D,HIGH,BULLISH,,0.71,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,226.098,226.14,226.5,0.004,-6.928,-14.379,-6.928,1.618,-1.869,1.618,-12.382,1.618,-14.648,1.618,-12.382,1,1
|
| 209 |
-
2020-04-17,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.71,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,226.098,226.14,226.5,0.004,-6.928,-14.379,-14.379,1.618,-1.869,1.618,-12.382,1.618,-14.648,1.618,-14.648,1,1
|
| 210 |
-
2020-04-17,HDFCBANK.NS,1D,MEDIUM,BULLISH,,0.57,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,424.093,424.43,425.45,3.795,2.01,3.048,3.795,5.564,2.713,5.564,-0.33,5.564,-0.33,5.564,2.713,1,0
|
| 211 |
-
2020-04-17,HDFCBANK.NS,3D,MEDIUM,BULLISH,,0.57,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,424.093,424.18,424.86,3.795,2.01,3.048,2.01,5.564,2.713,5.564,-0.33,5.564,-0.33,5.564,-0.33,1,1
|
| 212 |
-
2020-04-17,HDFCBANK.NS,5D,MEDIUM,BULLISH,,0.57,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,424.093,424.18,424.86,3.795,2.01,3.048,3.048,5.564,2.713,5.564,-0.33,5.564,-0.33,5.564,-0.33,1,1
|
| 213 |
-
2020-04-17,RELIANCE.NS,1D,HIGH,BULLISH,,0.64,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,545.04,545.48,546.78,1.618,11.405,15.768,1.618,2.696,-1.797,13.145,-4.902,22.136,-4.902,2.696,-1.797,1,1
|
| 214 |
-
2020-04-17,RELIANCE.NS,3D,HIGH,BULLISH,,0.64,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,545.04,545.15,546.02,1.618,11.405,15.768,11.405,2.696,-1.797,13.145,-4.902,22.136,-4.902,13.145,-4.902,1,1
|
| 215 |
-
2020-04-17,RELIANCE.NS,5D,HIGH,BULLISH,,0.64,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,545.04,545.15,546.02,1.618,11.405,15.768,15.768,2.696,-1.797,13.145,-4.902,22.136,-4.902,22.136,-4.902,1,1
|
| 216 |
-
2020-04-17,SUNPHARMA.NS,1D,MEDIUM,BULLISH,,0.61,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,430.478,430.82,431.86,3.566,3.774,6.224,3.566,3.916,-1.433,7.351,-1.433,8.729,-1.433,3.916,-1.433,1,1
|
| 217 |
-
2020-04-17,SUNPHARMA.NS,3D,MEDIUM,BULLISH,,0.61,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,430.478,430.56,431.25,3.566,3.774,6.224,3.774,3.916,-1.433,7.351,-1.433,8.729,-1.433,7.351,-1.433,1,1
|
| 218 |
-
2020-04-17,SUNPHARMA.NS,5D,MEDIUM,BULLISH,,0.61,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,430.478,430.56,431.25,3.566,3.774,6.224,6.224,3.916,-1.433,7.351,-1.433,8.729,-1.433,8.729,-1.433,1,1
|
| 219 |
-
2020-04-17,TCS.NS,1D,HIGH,BULLISH,,0.68,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,1548.896,1550.14,1553.85,0.689,-2.032,0.684,0.689,1.318,-0.205,1.318,-4.819,5.193,-4.819,1.318,-0.205,1,1
|
| 220 |
-
2020-04-17,TCS.NS,3D,HIGH,BULLISH,,0.68,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,1548.896,1549.21,1551.68,0.689,-2.032,0.684,-2.032,1.318,-0.205,1.318,-4.819,5.193,-4.819,1.318,-4.819,1,1
|
| 221 |
-
2020-04-17,TCS.NS,5D,HIGH,BULLISH,,0.68,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,1548.896,1549.21,1551.68,0.689,-2.032,0.684,0.684,1.318,-0.205,1.318,-4.819,5.193,-4.819,5.193,-4.819,1,1
|
| 222 |
-
2020-04-17,WIPRO.NS,1D,MEDIUM,BULLISH,,0.57,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,86.191,86.26,86.47,-3.155,-4.519,-4.947,-3.155,1.07,-3.663,1.07,-7.059,1.07,-7.059,1.07,-3.663,1,1
|
| 223 |
-
2020-04-17,WIPRO.NS,3D,MEDIUM,BULLISH,,0.57,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,86.191,86.21,86.35,-3.155,-4.519,-4.947,-4.519,1.07,-3.663,1.07,-7.059,1.07,-7.059,1.07,-7.059,1,1
|
| 224 |
-
2020-04-17,WIPRO.NS,5D,MEDIUM,BULLISH,,0.57,42.6,False,github:gpt-4o-mini,github,gpt-4o-mini,86.191,86.21,86.35,-3.155,-4.519,-4.947,-4.947,1.07,-3.663,1.07,-7.059,1.07,-7.059,1.07,-7.059,1,1
|
| 225 |
-
2020-06-16,BAJFINANCE.NS,1D,MEDIUM,BULLISH,,0.64,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,231.667,231.85,232.41,1.311,14.106,27.928,1.311,2.537,-1.393,14.78,-1.393,31.469,-1.393,2.537,-1.393,1,1
|
| 226 |
-
2020-06-16,BAJFINANCE.NS,3D,MEDIUM,BULLISH,,0.64,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,231.667,231.71,232.08,1.311,14.106,27.928,14.106,2.537,-1.393,14.78,-1.393,31.469,-1.393,14.78,-1.393,1,1
|
| 227 |
-
2020-06-16,BAJFINANCE.NS,5D,MEDIUM,BULLISH,,0.64,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,231.667,231.71,232.08,1.311,14.106,27.928,27.928,2.537,-1.393,14.78,-1.393,31.469,-1.393,31.469,-1.393,1,1
|
| 228 |
-
2020-06-16,HDFCBANK.NS,1D,HIGH,BULLISH,,0.71,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,461.41,461.78,462.89,-1.126,4.337,5.24,-1.126,0.858,-1.732,5.311,-1.858,5.609,-1.858,0.858,-1.732,1,1
|
| 229 |
-
2020-06-16,HDFCBANK.NS,3D,HIGH,BULLISH,,0.71,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,461.41,461.5,462.24,-1.126,4.337,5.24,4.337,0.858,-1.732,5.311,-1.858,5.609,-1.858,5.311,-1.858,1,1
|
| 230 |
-
2020-06-16,HDFCBANK.NS,5D,HIGH,BULLISH,,0.71,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,461.41,461.5,462.24,-1.126,4.337,5.24,5.24,0.858,-1.732,5.311,-1.858,5.609,-1.858,5.609,-1.858,1,1
|
| 231 |
-
2020-06-16,RELIANCE.NS,1D,HIGH,BULLISH,,0.72,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,727.181,727.76,729.51,-0.145,8.759,6.379,-0.145,1.097,-0.964,10.577,-0.964,11.529,-0.964,1.097,-0.964,1,1
|
| 232 |
-
2020-06-16,RELIANCE.NS,3D,HIGH,BULLISH,,0.72,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,727.181,727.33,728.49,-0.145,8.759,6.379,8.759,1.097,-0.964,10.577,-0.964,11.529,-0.964,10.577,-0.964,1,1
|
| 233 |
-
2020-06-16,RELIANCE.NS,5D,MEDIUM,BULLISH,,0.72,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,727.181,727.33,728.49,-0.145,8.759,6.379,6.379,1.097,-0.964,10.577,-0.964,11.529,-0.964,11.529,-0.964,1,1
|
| 234 |
-
2020-06-16,SUNPHARMA.NS,1D,MEDIUM,BULLISH,,0.71,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,455.246,455.61,456.7,0.465,0.972,3.527,0.465,1.314,-0.89,1.769,-0.89,4.055,-0.89,1.314,-0.89,1,1
|
| 235 |
-
2020-06-16,SUNPHARMA.NS,3D,MEDIUM,BULLISH,,0.71,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,455.246,455.34,456.07,0.465,0.972,3.527,0.972,1.314,-0.89,1.769,-0.89,4.055,-0.89,1.769,-0.89,1,1
|
| 236 |
-
2020-06-16,SUNPHARMA.NS,5D,HIGH,BULLISH,,0.71,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,455.246,455.34,456.07,0.465,0.972,3.527,3.527,1.314,-0.89,1.769,-0.89,4.055,-0.89,4.055,-0.89,1,1
|
| 237 |
-
2020-06-16,TCS.NS,1D,MEDIUM,BULLISH,,0.64,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,1759.521,1760.93,1765.15,0.098,-0.059,-0.513,0.098,0.638,-0.941,2.161,-1.007,2.161,-1.75,0.638,-0.941,1,1
|
| 238 |
-
2020-06-16,TCS.NS,3D,MEDIUM,BULLISH,,0.64,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,1759.521,1759.87,1762.69,0.098,-0.059,-0.513,-0.059,0.638,-0.941,2.161,-1.007,2.161,-1.75,2.161,-1.007,1,1
|
| 239 |
-
2020-06-16,TCS.NS,5D,MEDIUM,BULLISH,,0.64,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,1759.521,1759.87,1762.69,0.098,-0.059,-0.513,-0.513,0.638,-0.941,2.161,-1.007,2.161,-1.75,2.161,-1.75,1,1
|
| 240 |
-
2020-06-16,WIPRO.NS,1D,MEDIUM,BULLISH,,0.64,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,97.898,97.98,98.21,2.542,4.543,3.861,2.542,2.99,-0.636,5.508,-0.636,5.508,-0.636,2.99,-0.636,1,1
|
| 241 |
-
2020-06-16,WIPRO.NS,3D,MEDIUM,BULLISH,,0.64,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,97.898,97.92,98.07,2.542,4.543,3.861,4.543,2.99,-0.636,5.508,-0.636,5.508,-0.636,5.508,-0.636,1,1
|
| 242 |
-
2020-06-16,WIPRO.NS,5D,MEDIUM,BULLISH,,0.64,33.0,False,github:gpt-4o-mini,github,gpt-4o-mini,97.898,97.92,98.07,2.542,4.543,3.861,3.861,2.99,-0.636,5.508,-0.636,5.508,-0.636,5.508,-0.636,1,1
|
| 243 |
-
2020-08-11,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.64,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,338.674,338.95,339.76,-1.132,-3.653,-1.085,-1.132,-0.214,-2.759,0.422,-4.373,0.422,-4.373,-0.214,-2.759,0,0
|
| 244 |
-
2020-08-11,BAJFINANCE.NS,3D,HIGH,BULLISH,,0.64,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,338.674,338.74,339.28,-1.132,-3.653,-1.085,-3.653,-0.214,-2.759,0.422,-4.373,0.422,-4.373,0.422,-4.373,1,1
|
| 245 |
-
2020-08-11,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.64,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,338.674,338.74,339.28,-1.132,-3.653,-1.085,-1.085,-0.214,-2.759,0.422,-4.373,0.422,-4.373,0.422,-4.373,1,1
|
| 246 |
-
2020-08-11,HDFCBANK.NS,1D,HIGH,BULLISH,,0.64,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,496.933,497.33,498.52,-0.277,-3.019,-0.952,-0.277,-0.061,-1.748,0.441,-3.689,0.441,-4.355,-0.061,-1.748,0,0
|
| 247 |
-
2020-08-11,HDFCBANK.NS,3D,HIGH,BULLISH,,0.64,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,496.933,497.03,497.83,-0.277,-3.019,-0.952,-3.019,-0.061,-1.748,0.441,-3.689,0.441,-4.355,0.441,-3.689,1,1
|
| 248 |
-
2020-08-11,HDFCBANK.NS,5D,HIGH,BULLISH,,0.64,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,496.933,497.03,497.83,-0.277,-3.019,-0.952,-0.952,-0.061,-1.748,0.441,-3.689,0.441,-4.355,0.441,-4.355,1,1
|
| 249 |
-
2020-08-11,RELIANCE.NS,1D,HIGH,BULLISH,,0.71,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,963.079,963.85,966.16,-0.291,-0.937,-0.715,-0.291,0.525,-1.265,1.087,-2.088,1.087,-2.985,0.525,-1.265,1,1
|
| 250 |
-
2020-08-11,RELIANCE.NS,3D,HIGH,BULLISH,,0.71,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,963.079,963.27,964.81,-0.291,-0.937,-0.715,-0.937,0.525,-1.265,1.087,-2.088,1.087,-2.985,1.087,-2.088,1,1
|
| 251 |
-
2020-08-11,RELIANCE.NS,5D,HIGH,BULLISH,,0.71,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,963.079,963.27,964.81,-0.291,-0.937,-0.715,-0.715,0.525,-1.265,1.087,-2.088,1.087,-2.985,1.087,-2.985,1,1
|
| 252 |
-
2020-08-11,SUNPHARMA.NS,1D,HIGH,BULLISH,,0.68,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,509.538,509.95,511.17,-1.645,-1.793,-2.782,-1.645,-0.055,-2.089,-0.055,-4.066,-0.055,-4.066,-0.055,-2.089,0,0
|
| 253 |
-
2020-08-11,SUNPHARMA.NS,3D,HIGH,BULLISH,,0.68,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,509.538,509.64,510.46,-1.645,-1.793,-2.782,-1.793,-0.055,-2.089,-0.055,-4.066,-0.055,-4.066,-0.055,-4.066,0,0
|
| 254 |
-
2020-08-11,SUNPHARMA.NS,5D,HIGH,BULLISH,,0.68,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,509.538,509.64,510.46,-1.645,-1.793,-2.782,-2.782,-0.055,-2.089,-0.055,-4.066,-0.055,-4.066,-0.055,-4.066,0,0
|
| 255 |
-
2020-08-11,TCS.NS,1D,HIGH,BULLISH,,0.71,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,1965.261,1966.83,1971.55,-0.989,-1.656,-0.445,-0.989,0.724,-1.463,0.882,-2.053,0.882,-2.053,0.724,-1.463,1,1
|
| 256 |
-
2020-08-11,TCS.NS,3D,HIGH,BULLISH,,0.71,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,1965.261,1965.65,1968.8,-0.989,-1.656,-0.445,-1.656,0.724,-1.463,0.882,-2.053,0.882,-2.053,0.882,-2.053,1,1
|
| 257 |
-
2020-08-11,TCS.NS,5D,HIGH,BULLISH,,0.71,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,1965.261,1965.65,1968.8,-0.989,-1.656,-0.445,-0.445,0.724,-1.463,0.882,-2.053,0.882,-2.053,0.882,-2.053,1,1
|
| 258 |
-
2020-08-11,WIPRO.NS,1D,HIGH,BULLISH,,0.61,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,128.894,129.0,129.31,-1.234,-1.126,1.091,-1.234,0.375,-1.824,0.787,-1.824,2.771,-1.824,0.375,-1.824,1,1
|
| 259 |
-
2020-08-11,WIPRO.NS,3D,HIGH,BULLISH,,0.61,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,128.894,128.92,129.13,-1.234,-1.126,1.091,-1.126,0.375,-1.824,0.787,-1.824,2.771,-1.824,0.787,-1.824,1,1
|
| 260 |
-
2020-08-11,WIPRO.NS,5D,HIGH,BULLISH,,0.61,21.4,True,github:gpt-4o-mini,github,gpt-4o-mini,128.894,128.92,129.13,-1.234,-1.126,1.091,1.091,0.375,-1.824,0.787,-1.824,2.771,-1.824,2.771,-1.824,1,1
|
| 261 |
-
2020-10-07,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.75,20.1,True,github:gpt-4o-mini,github,gpt-4o-mini,326.307,326.57,327.35,-0.141,-0.119,1.228,-0.141,1.707,-0.875,2.621,-0.875,2.621,-2.955,1.707,-0.875,1,1
|
| 262 |
-
2020-10-07,BAJFINANCE.NS,3D,HIGH,BULLISH,,0.75,20.1,True,github:gpt-4o-mini,github,gpt-4o-mini,326.307,326.37,326.89,-0.141,-0.119,1.228,-0.119,1.707,-0.875,2.621,-0.875,2.621,-2.955,2.621,-0.875,1,1
|
| 263 |
-
2020-10-07,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.75,20.1,True,github:gpt-4o-mini,github,gpt-4o-mini,326.307,326.37,326.89,-0.141,-0.119,1.228,1.228,1.707,-0.875,2.621,-0.875,2.621,-2.955,2.621,-2.955,1,1
|
| 264 |
-
2020-10-07,HDFCBANK.NS,1D,HIGH,BULLISH,,0.68,20.1,True,github:gpt-4o-mini,github,gpt-4o-mini,541.472,541.9,543.2,2.542,4.422,4.237,2.542,3.506,0.095,6.926,0.095,6.926,0.095,3.506,0.095,1,1
|
| 265 |
-
2020-10-07,HDFCBANK.NS,3D,HIGH,BULLISH,,0.68,20.1,True,github:gpt-4o-mini,github,gpt-4o-mini,541.472,541.58,542.45,2.542,4.422,4.237,4.422,3.506,0.095,6.926,0.095,6.926,0.095,6.926,0.095,1,1
|
| 266 |
-
2020-10-07,HDFCBANK.NS,5D,HIGH,BULLISH,,0.68,20.1,True,github:gpt-4o-mini,github,gpt-4o-mini,541.472,541.58,542.45,2.542,4.422,4.237,4.237,3.506,0.095,6.926,0.095,6.926,0.095,6.926,0.095,1,1
|
| 267 |
-
2020-10-07,RELIANCE.NS,1D,HIGH,BULLISH,,0.75,20.1,True,github:gpt-4o-mini,github,gpt-4o-mini,1018.91,1019.73,1022.17,-0.808,-0.906,1.329,-0.808,0.465,-1.568,0.465,-1.79,2.06,-1.79,0.465,-1.568,1,1
|
| 268 |
-
2020-10-07,RELIANCE.NS,3D,HIGH,BULLISH,,0.75,20.1,True,github:gpt-4o-mini,github,gpt-4o-mini,1018.91,1019.11,1020.74,-0.808,-0.906,1.329,-0.906,0.465,-1.568,0.465,-1.79,2.06,-1.79,0.465,-1.79,1,1
|
| 269 |
-
2020-12-03,BAJFINANCE.NS,1D,HIGH,BULLISH,,0.68,19.0,True,github:gpt-4o-mini,github,gpt-4o-mini,476.798,477.18,478.32,0.162,-1.547,-1.493,0.162,1.86,-1.078,1.86,-1.899,1.86,-1.899,1.86,-1.078,1,1
|
| 270 |
-
2020-12-03,BAJFINANCE.NS,3D,HIGH,BULLISH,,0.68,19.0,True,github:gpt-4o-mini,github,gpt-4o-mini,476.798,476.89,477.66,0.162,-1.547,-1.493,-1.547,1.86,-1.078,1.86,-1.899,1.86,-1.899,1.86,-1.899,1,1
|
| 271 |
-
2020-12-03,BAJFINANCE.NS,5D,HIGH,BULLISH,,0.68,19.0,True,github:gpt-4o-mini,github,gpt-4o-mini,476.798,476.89,477.66,0.162,-1.547,-1.493,-1.493,1.86,-1.078,1.86,-1.899,1.86,-1.899,1.86,-1.899,1,1
|
| 272 |
-
2020-12-03,HDFCBANK.NS,1D,HIGH,BULLISH,,0.75,19.0,True,github:gpt-4o-mini,github,gpt-4o-mini,641.613,642.13,643.67,0.61,-0.065,0.628,0.61,1.761,-0.283,1.761,-1.387,2.385,-1.387,1.761,-0.283,1,1
|
|
|
|
| 1 |
date,ticker,timeframe,confidence,direction,matched_strategy,ml_prob,vix,nifty_ok,source,source_provider,source_model,entry_price,target_price_lo,target_price_hi,ret_1d,ret_3d,ret_5d,ret_for_tf,max_up_1d,min_down_1d,max_up_3d,min_down_3d,max_up_5d,min_down_5d,max_up_for_tf,min_down_for_tf,intraday_hit_for_tf,target_hit_for_tf
|
| 2 |
+
2020-01-01,BAJFINANCE.NS,1D,MEDIUM,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,413.532,413.74,415.39,0.349,-5.544,-4.286,0.349,1.523,0.087,1.523,-5.849,1.523,-6.648,1.523,0.087,1,1
|
| 3 |
+
2020-01-01,BAJFINANCE.NS,3D,MEDIUM,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,413.532,413.61,414.28,0.349,-5.544,-4.286,-5.544,1.523,0.087,1.523,-5.849,1.523,-6.648,1.523,-5.849,1,1
|
| 4 |
+
2020-01-01,BAJFINANCE.NS,5D,MEDIUM,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,413.532,413.61,414.28,0.349,-5.544,-4.286,-4.286,1.523,0.087,1.523,-5.849,1.523,-6.648,1.523,-6.648,1,1
|
| 5 |
+
2020-01-01,DRREDDY.NS,1D,MEDIUM,NEUTRAL,,0.71,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,554.488,553.82,555.15,-0.504,-0.019,0.62,-0.504,0.451,-0.667,0.639,-0.95,1.063,-0.95,0.451,-0.667,1,1
|
| 6 |
+
2020-01-01,DRREDDY.NS,3D,MEDIUM,NEUTRAL,,0.71,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,554.488,553.49,555.49,-0.504,-0.019,0.62,-0.019,0.451,-0.667,0.639,-0.95,1.063,-0.95,0.639,-0.95,1,1
|
| 7 |
+
2020-01-01,DRREDDY.NS,5D,MEDIUM,NEUTRAL,,0.71,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,554.488,553.1,555.87,-0.504,-0.019,0.62,0.62,0.451,-0.667,0.639,-0.95,1.063,-0.95,1.063,-0.95,1,1
|
| 8 |
+
2020-01-01,HDFCBANK.NS,1D,MEDIUM,NEUTRAL,,0.71,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,595.677,594.96,596.39,0.637,-2.945,-1.666,0.637,0.735,0.031,0.735,-3.332,0.735,-3.332,0.735,0.031,1,0
|
| 9 |
+
2020-01-01,HDFCBANK.NS,3D,MEDIUM,NEUTRAL,,0.71,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,595.677,594.6,596.75,0.637,-2.945,-1.666,-2.945,0.735,0.031,0.735,-3.332,0.735,-3.332,0.735,-3.332,1,1
|
| 10 |
+
2020-01-01,HDFCBANK.NS,5D,MEDIUM,NEUTRAL,,0.71,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,595.677,594.19,597.17,0.637,-2.945,-1.666,-1.666,0.735,0.031,0.735,-3.332,0.735,-3.332,0.735,-3.332,1,1
|
| 11 |
+
2020-01-01,HINDUNILVR.NS,1D,MEDIUM,NEUTRAL,,0.67,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,1732.311,1730.23,1734.39,0.077,-1.09,-0.372,0.077,0.829,-0.338,0.829,-1.306,0.829,-1.554,0.829,-0.338,1,1
|
| 12 |
+
2020-01-01,HINDUNILVR.NS,3D,MEDIUM,NEUTRAL,,0.67,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,1732.311,1729.19,1735.43,0.077,-1.09,-0.372,-1.09,0.829,-0.338,0.829,-1.306,0.829,-1.554,0.829,-1.306,1,1
|
| 13 |
+
2020-01-01,HINDUNILVR.NS,5D,MEDIUM,NEUTRAL,,0.67,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,1732.311,1727.98,1736.64,0.077,-1.09,-0.372,-0.372,0.829,-0.338,0.829,-1.306,0.829,-1.554,0.829,-1.554,1,1
|
| 14 |
+
2020-01-01,ICICIBANK.NS,1D,MEDIUM,NEUTRAL,,0.71,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,519.138,518.51,519.76,0.717,-2.059,-2.012,0.717,0.959,-0.168,0.959,-2.413,0.959,-4.052,0.959,-0.168,1,1
|
| 15 |
+
2020-01-01,ICICIBANK.NS,3D,MEDIUM,NEUTRAL,,0.71,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,519.138,518.2,520.07,0.717,-2.059,-2.012,-2.059,0.959,-0.168,0.959,-2.413,0.959,-4.052,0.959,-2.413,1,1
|
| 16 |
+
2020-01-01,ICICIBANK.NS,5D,MEDIUM,BULLISH,,0.71,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,519.138,519.24,520.07,0.717,-2.059,-2.012,-2.012,0.959,-0.168,0.959,-2.413,0.959,-4.052,0.959,-4.052,1,1
|
| 17 |
+
2020-01-01,INFY.NS,1D,MEDIUM,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,619.74,620.05,622.53,-0.292,0.271,-2.531,-0.292,0.536,-0.808,2.3,-0.808,2.3,-3.875,0.536,-0.808,1,1
|
| 18 |
+
2020-01-01,INFY.NS,3D,MEDIUM,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,619.74,619.86,620.86,-0.292,0.271,-2.531,0.271,0.536,-0.808,2.3,-0.808,2.3,-3.875,2.3,-0.808,1,1
|
| 19 |
+
2020-01-01,INFY.NS,5D,HIGH,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,619.74,619.86,620.86,-0.292,0.271,-2.531,-2.531,0.536,-0.808,2.3,-0.808,2.3,-3.875,2.3,-3.875,1,1
|
| 20 |
+
2020-01-01,MARUTI.NS,1D,HIGH,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,6945.336,6948.81,6976.59,0.248,-3.683,-3.782,0.248,0.77,0.004,0.77,-3.901,0.77,-4.53,0.77,0.004,1,1
|
| 21 |
+
2020-01-01,MARUTI.NS,3D,MEDIUM,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,6945.336,6946.73,6957.84,0.248,-3.683,-3.782,-3.683,0.77,0.004,0.77,-3.901,0.77,-4.53,0.77,-3.901,1,1
|
| 22 |
+
2020-01-01,MARUTI.NS,5D,MEDIUM,BULLISH,,0.78,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,6945.336,6946.73,6957.84,0.248,-3.683,-3.782,-3.782,0.77,0.004,0.77,-3.901,0.77,-4.53,0.77,-4.53,1,1
|
| 23 |
+
2020-01-01,NTPC.NS,1D,MEDIUM,NEUTRAL,,0.58,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,94.731,94.62,94.84,-0.123,-2.18,-1.316,-0.123,0.494,-0.782,0.494,-4.155,0.494,-4.155,0.494,-0.782,1,1
|
| 24 |
+
2020-01-01,NTPC.NS,3D,MEDIUM,NEUTRAL,,0.58,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,94.731,94.56,94.9,-0.123,-2.18,-1.316,-2.18,0.494,-0.782,0.494,-4.155,0.494,-4.155,0.494,-4.155,1,1
|
| 25 |
+
2020-01-01,NTPC.NS,5D,MEDIUM,BULLISH,,0.58,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,94.731,94.75,94.9,-0.123,-2.18,-1.316,-1.316,0.494,-0.782,0.494,-4.155,0.494,-4.155,0.494,-4.155,1,1
|
| 26 |
+
2020-01-01,RELIANCE.NS,1D,MEDIUM,NEUTRAL,,0.64,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,672.216,671.41,673.02,1.702,-0.537,0.235,1.702,2.077,0.159,2.123,-0.768,2.123,-0.768,2.077,0.159,0,0
|
| 27 |
+
2020-01-01,RELIANCE.NS,3D,MEDIUM,NEUTRAL,,0.64,11.7,True,github:gpt-4o-mini,github,gpt-4o-mini,672.216,671.01,673.43,1.702,-0.537,0.235,-0.537,2.077,0.159,2.123,-0.768,2.123,-0.768,2.123,-0.768,1,1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
research/ai_prompt_accuracy_new.csv.bak
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
research/loop_backtest.py
CHANGED
|
@@ -145,125 +145,153 @@ def _replace_once(src: str, old: str, new: str) -> tuple[str, bool]:
|
|
| 145 |
return src, False
|
| 146 |
|
| 147 |
|
| 148 |
-
def
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
return src, False
|
| 155 |
-
block = src[
|
| 156 |
if old not in block:
|
| 157 |
return src, False
|
| 158 |
block = block.replace(old, new, 1)
|
| 159 |
-
return src[:
|
| 160 |
|
| 161 |
|
| 162 |
-
|
| 163 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
pairs = [
|
| 165 |
-
(
|
| 166 |
-
f
|
|
|
|
|
|
|
| 167 |
]
|
| 168 |
for old, new in pairs:
|
| 169 |
-
new_src, ok =
|
| 170 |
if ok:
|
| 171 |
-
return new_src, " [FIX] 1D BULLISH
|
| 172 |
-
return src, " [FIX] 1D BULLISH anchor not found β skipped"
|
| 173 |
|
| 174 |
|
| 175 |
-
def
|
| 176 |
-
"""Tighten 1D BEARISH
|
| 177 |
pairs = [
|
| 178 |
-
(
|
| 179 |
-
f
|
|
|
|
|
|
|
| 180 |
]
|
| 181 |
for old, new in pairs:
|
| 182 |
-
new_src, ok =
|
| 183 |
if ok:
|
| 184 |
-
return new_src, " [FIX] 1D BEARISH
|
| 185 |
-
return src, " [FIX] 1D BEARISH anchor not found β skipped"
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
def
|
| 189 |
-
"""Tighten 3D
|
| 190 |
-
# Target line index 1 (3D block) β need to replace only that instance
|
| 191 |
-
OLD = (
|
| 192 |
-
"- ACCURACY-CALIBRATED range values (use these as your starting point):\n"
|
| 193 |
-
' " BULLISH: predicted_return_lo=0.02, predicted_return_hi=0.18 (midpointβ0.10%)\\n"\n'
|
| 194 |
-
' " BEARISH: predicted_return_lo=-0.18, predicted_return_hi=-0.02 (midpointβ-0.10%)\\n"\n'
|
| 195 |
-
' " NEUTRAL: predicted_return_lo=-0.15, predicted_return_hi=0.15\\n"\n'
|
| 196 |
-
)
|
| 197 |
-
# Simpler approach: replace the specific 3D BEARISH line
|
| 198 |
-
old_bear = ' BEARISH: predicted_return_lo=-0.18, predicted_return_hi=-0.02 (midpointβ-0.10%)\n'
|
| 199 |
-
new_bear = f' BEARISH: predicted_return_lo=-0.12, predicted_return_hi=-0.02 (midpointβ-0.07%) [tight-3d-bear-{iteration}]\n'
|
| 200 |
-
# The 3D BEARISH appears at index 1; replace only first occurrence AFTER 3D marker
|
| 201 |
-
start_marker = "TIMEFRAME CALIBRATION for 3D"
|
| 202 |
-
s_idx = src.find(start_marker)
|
| 203 |
-
if s_idx == -1:
|
| 204 |
-
return src, " [FIX] 3D marker not found β skipped"
|
| 205 |
-
end_marker = "TIMEFRAME CALIBRATION for 5D"
|
| 206 |
-
e_idx = src.find(end_marker, s_idx)
|
| 207 |
-
if e_idx == -1:
|
| 208 |
-
e_idx = s_idx + 2000
|
| 209 |
-
block = src[s_idx:e_idx]
|
| 210 |
-
if old_bear not in block:
|
| 211 |
-
return src, " [FIX] 3D BEARISH anchor not found β skipped"
|
| 212 |
-
block = block.replace(old_bear, new_bear, 1)
|
| 213 |
-
return src[:s_idx] + block + src[e_idx:], " [FIX] 3D BEARISH range tightened"
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
def fix_tighten_5d_bearish(src: str, iteration: int) -> tuple[str, str]:
|
| 217 |
-
"""Tighten 5D BEARISH magnitude β shallower midpoint."""
|
| 218 |
-
old_bear = ' BEARISH: predicted_return_lo=-0.18, predicted_return_hi=-0.02 (midpointβ-0.10%)\n'
|
| 219 |
-
new_bear = f' BEARISH: predicted_return_lo=-0.12, predicted_return_hi=-0.02 (midpointβ-0.07%) [tight-5d-bear-{iteration}]\n'
|
| 220 |
-
start_marker = "TIMEFRAME CALIBRATION for 5D"
|
| 221 |
-
s_idx = src.find(start_marker)
|
| 222 |
-
if s_idx == -1:
|
| 223 |
-
return src, " [FIX] 5D marker not found β skipped"
|
| 224 |
-
block = src[s_idx:s_idx + 1500]
|
| 225 |
-
if old_bear not in block:
|
| 226 |
-
return src, " [FIX] 5D BEARISH anchor not found β skipped"
|
| 227 |
-
block = block.replace(old_bear, new_bear, 1)
|
| 228 |
-
return src[:s_idx] + block + src[s_idx + 1500:], " [FIX] 5D BEARISH range tightened"
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
def fix_strengthen_directional_bias(src: str, iteration: int) -> tuple[str, str]:
|
| 232 |
-
"""Strengthen the directional bias rule β raise the RSI threshold for BEARISH."""
|
| 233 |
pairs = [
|
| 234 |
-
("-
|
| 235 |
-
f"-
|
|
|
|
|
|
|
| 236 |
]
|
| 237 |
for old, new in pairs:
|
| 238 |
-
new_src, ok =
|
| 239 |
if ok:
|
| 240 |
-
return new_src, " [FIX] BEARISH
|
| 241 |
-
return src, " [FIX]
|
| 242 |
|
| 243 |
|
| 244 |
-
def
|
| 245 |
-
"""
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 252 |
|
| 253 |
|
| 254 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
FIX_SEQUENCE = [
|
| 256 |
-
("
|
| 257 |
-
("
|
| 258 |
-
("
|
| 259 |
-
("
|
| 260 |
-
("
|
| 261 |
-
("
|
|
|
|
| 262 |
]
|
| 263 |
|
| 264 |
|
| 265 |
def choose_fix(res: dict, iteration: int) -> tuple[str, callable]:
|
| 266 |
-
"""Pick fix based on
|
| 267 |
target_accs = [res[tf]["target_acc"] for tf in res if not np.isnan(res[tf].get("target_acc", float("nan")))]
|
| 268 |
avg_target = np.mean(target_accs) if target_accs else float("nan")
|
| 269 |
|
|
@@ -275,26 +303,38 @@ def choose_fix(res: dict, iteration: int) -> tuple[str, callable]:
|
|
| 275 |
t3 = r3d.get("target_acc", float("nan"))
|
| 276 |
t5 = r5d.get("target_acc", float("nan"))
|
| 277 |
|
| 278 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 279 |
|
| 280 |
-
#
|
| 281 |
weakest = min(
|
| 282 |
[("1D", t1), ("3D", t3), ("5D", t5)],
|
| 283 |
key=lambda x: x[1] if not np.isnan(x[1]) else 999,
|
| 284 |
)[0]
|
| 285 |
|
|
|
|
| 286 |
if weakest == "5D" and not np.isnan(t5) and t5 < TARGET:
|
| 287 |
-
return FIX_SEQUENCE[0] #
|
| 288 |
if weakest == "3D" and not np.isnan(t3) and t3 < TARGET:
|
| 289 |
-
return FIX_SEQUENCE[1] #
|
| 290 |
if weakest == "1D" and not np.isnan(t1) and t1 < TARGET:
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
if not np.isnan(avg_target) and avg_target < TARGET:
|
| 297 |
-
return FIX_SEQUENCE[
|
| 298 |
|
| 299 |
return FIX_SEQUENCE[iteration % len(FIX_SEQUENCE)]
|
| 300 |
|
|
@@ -302,36 +342,27 @@ def choose_fix(res: dict, iteration: int) -> tuple[str, callable]:
|
|
| 302 |
# ββ MODEL STATUS ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 303 |
|
| 304 |
def _model_status() -> str:
|
| 305 |
-
"""Return a one-line string showing which
|
| 306 |
try:
|
| 307 |
import ai_forecast as _aif
|
| 308 |
-
|
|
|
|
| 309 |
parts = []
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
|
|
|
| 316 |
return " Models: " + " | ".join(parts)
|
| 317 |
except Exception as e:
|
| 318 |
-
return f" Models: (status
|
| 319 |
|
| 320 |
|
| 321 |
def _all_models_cooled_down() -> tuple[bool, int]:
|
| 322 |
-
"""Return (all_cooled, max_wait_seconds)."""
|
| 323 |
-
|
| 324 |
-
import ai_forecast as _aif
|
| 325 |
-
_aif._load_model_cooldowns()
|
| 326 |
-
max_wait = 0
|
| 327 |
-
for m in _aif._GITHUB_MODEL_CANDIDATES:
|
| 328 |
-
cooled, remain = _aif._is_model_cooled_down(m)
|
| 329 |
-
if not cooled:
|
| 330 |
-
return False, 0
|
| 331 |
-
max_wait = max(max_wait, remain)
|
| 332 |
-
return True, max_wait
|
| 333 |
-
except Exception:
|
| 334 |
-
return False, 0
|
| 335 |
|
| 336 |
|
| 337 |
# ββ MAIN LOOP βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
| 145 |
return src, False
|
| 146 |
|
| 147 |
|
| 148 |
+
def _find_in_synthesis(src: str, target: str) -> bool:
|
| 149 |
+
"""Check if target string exists inside _build_synthesis_prompt function."""
|
| 150 |
+
start = src.find("def _build_synthesis_prompt(")
|
| 151 |
+
end = src.find("def _downgrade_confidence(", start)
|
| 152 |
+
if start == -1 or end == -1:
|
| 153 |
+
return False
|
| 154 |
+
return target in src[start:end]
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
def _replace_in_synthesis(src: str, old: str, new: str) -> tuple[str, bool]:
|
| 158 |
+
"""Replace string inside _build_synthesis_prompt only."""
|
| 159 |
+
start = src.find("def _build_synthesis_prompt(")
|
| 160 |
+
end = src.find("def _downgrade_confidence(", start)
|
| 161 |
+
if start == -1 or end == -1:
|
| 162 |
return src, False
|
| 163 |
+
block = src[start:end]
|
| 164 |
if old not in block:
|
| 165 |
return src, False
|
| 166 |
block = block.replace(old, new, 1)
|
| 167 |
+
return src[:start] + block + src[end:], True
|
| 168 |
|
| 169 |
|
| 170 |
+
# ββ PROMPT FIX FUNCTIONS ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 171 |
+
# All fixes target the signal alignment rules in _build_synthesis_prompt.
|
| 172 |
+
# Strategy: the key lever for >90% accuracy is direction accuracy.
|
| 173 |
+
# We do this by tightening the criteria that must be met before LLM calls directional.
|
| 174 |
+
|
| 175 |
+
def fix_tighten_1d_bullish_rsi(src: str, iteration: int) -> tuple[str, str]:
|
| 176 |
+
"""Tighten 1D BULLISH RSI threshold β require stronger oversold to call BULLISH."""
|
| 177 |
pairs = [
|
| 178 |
+
("- BULLISH when: RSI < 40 (oversold bounce) OR (above EMA50 AND MACD > 0 AND volume high)\n",
|
| 179 |
+
f"- BULLISH when: RSI < 35 (deep oversold) OR (above EMA50 AND MACD > 0 AND volume > 1.3x avg) [v{iteration}]\n"),
|
| 180 |
+
(f"- BULLISH when: RSI < 35 (deep oversold) OR (above EMA50 AND MACD > 0 AND volume > 1.3x avg) [v{iteration-1}]\n",
|
| 181 |
+
f"- BULLISH when: RSI < 32 (extreme oversold) OR (above EMA50 AND MACD > 0 AND volume > 1.5x avg) [v{iteration}]\n"),
|
| 182 |
]
|
| 183 |
for old, new in pairs:
|
| 184 |
+
new_src, ok = _replace_in_synthesis(src, old, new)
|
| 185 |
if ok:
|
| 186 |
+
return new_src, f" [FIX] 1D BULLISH RSI tightened to {32 if 'extreme' in new else 35}"
|
| 187 |
+
return src, " [FIX] 1D BULLISH RSI anchor not found β skipped"
|
| 188 |
|
| 189 |
|
| 190 |
+
def fix_tighten_1d_bearish_rsi(src: str, iteration: int) -> tuple[str, str]:
|
| 191 |
+
"""Tighten 1D BEARISH RSI threshold β require more overbought to call BEARISH."""
|
| 192 |
pairs = [
|
| 193 |
+
("- BEARISH when: RSI > 68 AND below EMA50 AND MACD < 0 AND volume confirms\n",
|
| 194 |
+
f"- BEARISH when: RSI > 72 AND below EMA50 AND MACD < 0 AND volume confirms downside [v{iteration}]\n"),
|
| 195 |
+
(f"- BEARISH when: RSI > 72 AND below EMA50 AND MACD < 0 AND volume confirms downside [v{iteration-1}]\n",
|
| 196 |
+
f"- BEARISH when: RSI > 75 AND below BOTH EMA50 AND EMA200 AND MACD < 0 AND 90D return negative [v{iteration}]\n"),
|
| 197 |
]
|
| 198 |
for old, new in pairs:
|
| 199 |
+
new_src, ok = _replace_in_synthesis(src, old, new)
|
| 200 |
if ok:
|
| 201 |
+
return new_src, f" [FIX] 1D BEARISH RSI threshold raised"
|
| 202 |
+
return src, " [FIX] 1D BEARISH RSI anchor not found β skipped"
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
def fix_tighten_3d_signal_count(src: str, iteration: int) -> tuple[str, str]:
|
| 206 |
+
"""Tighten 3D direction criteria β require more evidence for directional calls."""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
pairs = [
|
| 208 |
+
("- BEARISH when: below EMA50 AND (RSI > 58 OR MACD < 0) AND macro/sector headwinds\n",
|
| 209 |
+
f"- BEARISH when: below EMA50 AND RSI > 58 AND MACD < 0 AND macro/sector headwinds [v{iteration}]\n"),
|
| 210 |
+
(f"- BEARISH when: below EMA50 AND RSI > 58 AND MACD < 0 AND macro/sector headwinds [v{iteration-1}]\n",
|
| 211 |
+
f"- BEARISH when: below BOTH EMA50 AND EMA200 AND RSI > 60 AND MACD < 0 AND 90D return negative [v{iteration}]\n"),
|
| 212 |
]
|
| 213 |
for old, new in pairs:
|
| 214 |
+
new_src, ok = _replace_in_synthesis(src, old, new)
|
| 215 |
if ok:
|
| 216 |
+
return new_src, " [FIX] 3D BEARISH now requires both EMAs below and MACD confirmation"
|
| 217 |
+
return src, " [FIX] 3D BEARISH anchor not found β skipped"
|
| 218 |
|
| 219 |
|
| 220 |
+
def fix_tighten_5d_direction(src: str, iteration: int) -> tuple[str, str]:
|
| 221 |
+
"""Tighten 5D direction thresholds β only call directional when trend is clear."""
|
| 222 |
+
pairs = [
|
| 223 |
+
("- NEUTRAL when: between EMAs, or any major signal is conflicting β prefer NEUTRAL over a weak guess\n",
|
| 224 |
+
f"- NEUTRAL when: between EMAs, OR RSI 40-62, OR MACD near zero, OR FII flows mixed β STRONGLY prefer NEUTRAL [v{iteration}]\n"),
|
| 225 |
+
(f"- NEUTRAL when: between EMAs, OR RSI 40-62, OR MACD near zero, OR FII flows mixed β STRONGLY prefer NEUTRAL [v{iteration-1}]\n",
|
| 226 |
+
f"- NEUTRAL when: any ambiguity at all in EMA position, RSI direction, or macro regime β NEUTRAL is correct answer [v{iteration}]\n"),
|
| 227 |
+
]
|
| 228 |
+
for old, new in pairs:
|
| 229 |
+
new_src, ok = _replace_in_synthesis(src, old, new)
|
| 230 |
+
if ok:
|
| 231 |
+
return new_src, " [FIX] 5D NEUTRAL threshold strengthened β more NEUTRAL calls"
|
| 232 |
+
return src, " [FIX] 5D NEUTRAL anchor not found β skipped"
|
| 233 |
|
| 234 |
|
| 235 |
+
def fix_raise_vix_threshold(src: str, iteration: int) -> tuple[str, str]:
|
| 236 |
+
"""Lower VIX bar for reducing BULLISH β now 18 instead of 20."""
|
| 237 |
+
pairs = [
|
| 238 |
+
("- When VIX > 20 or macro is risk-off: require 4+ signals for BULLISH\n",
|
| 239 |
+
f"- When VIX > 18 or macro is risk-off: require 4+ signals for BULLISH; prefer NEUTRAL [v{iteration}]\n"),
|
| 240 |
+
(f"- When VIX > 18 or macro is risk-off: require 4+ signals for BULLISH; prefer NEUTRAL [v{iteration-1}]\n",
|
| 241 |
+
f"- When VIX > 16 or macro is risk-off: prefer NEUTRAL; only BULLISH with 5+ clear signals [v{iteration}]\n"),
|
| 242 |
+
]
|
| 243 |
+
for old, new in pairs:
|
| 244 |
+
new_src, ok = _replace_in_synthesis(src, old, new)
|
| 245 |
+
if ok:
|
| 246 |
+
return new_src, " [FIX] VIX BULLISH threshold lowered (18/16)"
|
| 247 |
+
return src, " [FIX] VIX threshold anchor not found β skipped"
|
| 248 |
+
|
| 249 |
+
|
| 250 |
+
def fix_increase_signal_count(src: str, iteration: int) -> tuple[str, str]:
|
| 251 |
+
"""Require more signals to align before calling directional."""
|
| 252 |
+
pairs = [
|
| 253 |
+
("- Require β₯3 of these to align before calling BULLISH or BEARISH:\n",
|
| 254 |
+
f"- Require β₯4 of these to align before calling BULLISH or BEARISH (β₯3 is not enough): [v{iteration}]\n"),
|
| 255 |
+
(f"- Require β₯4 of these to align before calling BULLISH or BEARISH (β₯3 is not enough): [v{iteration-1}]\n",
|
| 256 |
+
f"- Require β₯5 of these to clearly align before calling BULLISH or BEARISH: [v{iteration}]\n"),
|
| 257 |
+
]
|
| 258 |
+
for old, new in pairs:
|
| 259 |
+
new_src, ok = _replace_in_synthesis(src, old, new)
|
| 260 |
+
if ok:
|
| 261 |
+
return new_src, " [FIX] Required signal alignment count raised to 4/5"
|
| 262 |
+
return src, " [FIX] signal count anchor not found β skipped"
|
| 263 |
+
|
| 264 |
+
|
| 265 |
+
def fix_strengthen_neutral_preference(src: str, iteration: int) -> tuple[str, str]:
|
| 266 |
+
"""Make NEUTRAL the strong default when signals conflict."""
|
| 267 |
+
pairs = [
|
| 268 |
+
("- In genuine signal conflict: always choose NEUTRAL over a low-conviction directional call\n",
|
| 269 |
+
f"- RULE: When in doubt, output NEUTRAL. A wrong directional call is worse than NEUTRAL. [v{iteration}]\n"),
|
| 270 |
+
(f"- RULE: When in doubt, output NEUTRAL. A wrong directional call is worse than NEUTRAL. [v{iteration-1}]\n",
|
| 271 |
+
f"- RULE: NEUTRAL is the safe default. Only override to directional when evidence is overwhelming and specific. [v{iteration}]\n"),
|
| 272 |
+
]
|
| 273 |
+
for old, new in pairs:
|
| 274 |
+
new_src, ok = _replace_in_synthesis(src, old, new)
|
| 275 |
+
if ok:
|
| 276 |
+
return new_src, " [FIX] NEUTRAL preference strengthened in synthesis prompt"
|
| 277 |
+
return src, " [FIX] NEUTRAL anchor not found β skipped"
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
# Fix sequence β ordered for target-hit accuracy improvement
|
| 281 |
+
# Each fix targets direction accuracy (the root cause of <90% target-hit)
|
| 282 |
FIX_SEQUENCE = [
|
| 283 |
+
("tighten_5d_direction", fix_tighten_5d_direction),
|
| 284 |
+
("tighten_3d_signal_count", fix_tighten_3d_signal_count),
|
| 285 |
+
("tighten_1d_bullish_rsi", fix_tighten_1d_bullish_rsi),
|
| 286 |
+
("tighten_1d_bearish_rsi", fix_tighten_1d_bearish_rsi),
|
| 287 |
+
("raise_vix_threshold", fix_raise_vix_threshold),
|
| 288 |
+
("increase_signal_count", fix_increase_signal_count),
|
| 289 |
+
("strengthen_neutral_preference", fix_strengthen_neutral_preference),
|
| 290 |
]
|
| 291 |
|
| 292 |
|
| 293 |
def choose_fix(res: dict, iteration: int) -> tuple[str, callable]:
|
| 294 |
+
"""Pick fix based on which timeframe and direction has worst target-hit accuracy."""
|
| 295 |
target_accs = [res[tf]["target_acc"] for tf in res if not np.isnan(res[tf].get("target_acc", float("nan")))]
|
| 296 |
avg_target = np.mean(target_accs) if target_accs else float("nan")
|
| 297 |
|
|
|
|
| 303 |
t3 = r3d.get("target_acc", float("nan"))
|
| 304 |
t5 = r5d.get("target_acc", float("nan"))
|
| 305 |
|
| 306 |
+
b1 = r1d.get("dir_acc", float("nan")) # direction accuracy 1D
|
| 307 |
+
b3 = r3d.get("dir_acc", float("nan")) # direction accuracy 3D
|
| 308 |
+
b5 = r5d.get("dir_acc", float("nan")) # direction accuracy 5D
|
| 309 |
+
|
| 310 |
+
print(f" Diagnosis: target_acc={avg_target:.1f}% 1D={t1:.1f}% (dir={b1:.1f}%) 3D={t3:.1f}% (dir={b3:.1f}%) 5D={t5:.1f}% (dir={b5:.1f}%)")
|
| 311 |
|
| 312 |
+
# Identify weakest TF by target accuracy
|
| 313 |
weakest = min(
|
| 314 |
[("1D", t1), ("3D", t3), ("5D", t5)],
|
| 315 |
key=lambda x: x[1] if not np.isnan(x[1]) else 999,
|
| 316 |
)[0]
|
| 317 |
|
| 318 |
+
# 5D is hardest β fix its direction criteria first
|
| 319 |
if weakest == "5D" and not np.isnan(t5) and t5 < TARGET:
|
| 320 |
+
return FIX_SEQUENCE[0] # tighten_5d_direction
|
| 321 |
if weakest == "3D" and not np.isnan(t3) and t3 < TARGET:
|
| 322 |
+
return FIX_SEQUENCE[1] # tighten_3d_signal_count
|
| 323 |
if weakest == "1D" and not np.isnan(t1) and t1 < TARGET:
|
| 324 |
+
# Sub-diagnose: is BULLISH or BEARISH worse for 1D?
|
| 325 |
+
bull1 = r1d.get("target_bull", float("nan"))
|
| 326 |
+
bear1 = r1d.get("target_bear", float("nan"))
|
| 327 |
+
if not np.isnan(bull1) and not np.isnan(bear1) and bull1 < bear1:
|
| 328 |
+
return FIX_SEQUENCE[2] # tighten_1d_bullish_rsi
|
| 329 |
+
return FIX_SEQUENCE[3] # tighten_1d_bearish_rsi
|
| 330 |
+
|
| 331 |
+
# If all TFs present but still below target β try global fixes
|
| 332 |
+
if not np.isnan(avg_target) and avg_target < TARGET - 10:
|
| 333 |
+
return FIX_SEQUENCE[4] # raise_vix_threshold
|
| 334 |
+
if not np.isnan(avg_target) and avg_target < TARGET - 5:
|
| 335 |
+
return FIX_SEQUENCE[5] # increase_signal_count
|
| 336 |
if not np.isnan(avg_target) and avg_target < TARGET:
|
| 337 |
+
return FIX_SEQUENCE[6] # strengthen_neutral_preference
|
| 338 |
|
| 339 |
return FIX_SEQUENCE[iteration % len(FIX_SEQUENCE)]
|
| 340 |
|
|
|
|
| 342 |
# ββ MODEL STATUS ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 343 |
|
| 344 |
def _model_status() -> str:
|
| 345 |
+
"""Return a one-line string showing which LLM providers are available."""
|
| 346 |
try:
|
| 347 |
import ai_forecast as _aif
|
| 348 |
+
github_ready = bool(os.environ.get("GITHUB_TOKEN", ""))
|
| 349 |
+
or_ready = bool(os.environ.get("OPENROUTER_API_KEY", ""))
|
| 350 |
parts = []
|
| 351 |
+
if github_ready:
|
| 352 |
+
parts.append("GitHub Models: ready")
|
| 353 |
+
if or_ready:
|
| 354 |
+
model = os.environ.get("OPENROUTER_BEST_FREE_MODEL", "openai/gpt-oss-120b:free")
|
| 355 |
+
parts.append(f"OpenRouter ({model}): ready")
|
| 356 |
+
if not parts:
|
| 357 |
+
parts.append("No LLM provider configured (set GITHUB_TOKEN or OPENROUTER_API_KEY)")
|
| 358 |
return " Models: " + " | ".join(parts)
|
| 359 |
except Exception as e:
|
| 360 |
+
return f" Models: (status check failed: {e})"
|
| 361 |
|
| 362 |
|
| 363 |
def _all_models_cooled_down() -> tuple[bool, int]:
|
| 364 |
+
"""Return (all_cooled, max_wait_seconds) β always False unless we can detect cooldowns."""
|
| 365 |
+
return False, 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 366 |
|
| 367 |
|
| 368 |
# ββ MAIN LOOP βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
static/app.js
CHANGED
|
@@ -1826,6 +1826,7 @@ function _autoFillShares() {
|
|
| 1826 |
}
|
| 1827 |
|
| 1828 |
let _pendingTradeData = {};
|
|
|
|
| 1829 |
|
| 1830 |
function openTradeModal(ticker, name, price, stopLoss = 0, target = 0, planData = null) {
|
| 1831 |
_pendingTradeData = planData || {};
|
|
@@ -1861,7 +1862,7 @@ function openTradeModal(ticker, name, price, stopLoss = 0, target = 0, planData
|
|
| 1861 |
// If no prediction context came with planData, try the cached watchlist prediction.
|
| 1862 |
// Covers: shell cards clicked mid-load, and Portfolio "New Trade" with a typed ticker.
|
| 1863 |
if (ticker && !_pendingTradeData.prediction_data) {
|
| 1864 |
-
fetch(`/api/watchlist-pick/${encodeURIComponent(ticker)}`)
|
| 1865 |
.then(r => r.ok ? r.json() : null)
|
| 1866 |
.then(d => {
|
| 1867 |
if (!d || !d.pick) return;
|
|
@@ -1887,7 +1888,8 @@ function openTradeModal(ticker, name, price, stopLoss = 0, target = 0, planData
|
|
| 1887 |
if (tgtEl && (!tgtEl.value || parseFloat(tgtEl.value) === 0) && tf.expected_target_price) tgtEl.value = tf.expected_target_price;
|
| 1888 |
_autoFillShares();
|
| 1889 |
})
|
| 1890 |
-
.catch(() => {})
|
|
|
|
| 1891 |
}
|
| 1892 |
}
|
| 1893 |
|
|
@@ -1916,6 +1918,15 @@ document.getElementById('modal-submit')?.addEventListener('click', async () => {
|
|
| 1916 |
|
| 1917 |
if (!ticker || !dir || !entry || !shares) return alert('Ticker, direction, entry price, and shares are required.');
|
| 1918 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1919 |
try {
|
| 1920 |
const res = await fetch('/api/trades', {
|
| 1921 |
method: 'POST',
|
|
|
|
| 1826 |
}
|
| 1827 |
|
| 1828 |
let _pendingTradeData = {};
|
| 1829 |
+
let _pendingTradeContextPromise = null;
|
| 1830 |
|
| 1831 |
function openTradeModal(ticker, name, price, stopLoss = 0, target = 0, planData = null) {
|
| 1832 |
_pendingTradeData = planData || {};
|
|
|
|
| 1862 |
// If no prediction context came with planData, try the cached watchlist prediction.
|
| 1863 |
// Covers: shell cards clicked mid-load, and Portfolio "New Trade" with a typed ticker.
|
| 1864 |
if (ticker && !_pendingTradeData.prediction_data) {
|
| 1865 |
+
_pendingTradeContextPromise = fetch(`/api/watchlist-pick/${encodeURIComponent(ticker)}`)
|
| 1866 |
.then(r => r.ok ? r.json() : null)
|
| 1867 |
.then(d => {
|
| 1868 |
if (!d || !d.pick) return;
|
|
|
|
| 1888 |
if (tgtEl && (!tgtEl.value || parseFloat(tgtEl.value) === 0) && tf.expected_target_price) tgtEl.value = tf.expected_target_price;
|
| 1889 |
_autoFillShares();
|
| 1890 |
})
|
| 1891 |
+
.catch(() => {}) // silent β prediction context is optional
|
| 1892 |
+
.finally(() => { _pendingTradeContextPromise = null; });
|
| 1893 |
}
|
| 1894 |
}
|
| 1895 |
|
|
|
|
| 1918 |
|
| 1919 |
if (!ticker || !dir || !entry || !shares) return alert('Ticker, direction, entry price, and shares are required.');
|
| 1920 |
|
| 1921 |
+
// Give the async context fetch a chance to complete before posting trade.
|
| 1922 |
+
if (_pendingTradeContextPromise) {
|
| 1923 |
+
try {
|
| 1924 |
+
await _pendingTradeContextPromise;
|
| 1925 |
+
} catch (_) {
|
| 1926 |
+
// Best effort only; backend still auto-fills missing context.
|
| 1927 |
+
}
|
| 1928 |
+
}
|
| 1929 |
+
|
| 1930 |
try {
|
| 1931 |
const res = await fetch('/api/trades', {
|
| 1932 |
method: 'POST',
|
top5_picker.py
CHANGED
|
@@ -116,16 +116,66 @@ def get_top5_picks(
|
|
| 116 |
except Exception:
|
| 117 |
scan_preds[ticker] = {}
|
| 118 |
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
|
| 130 |
market_from_scan = next((p.get("market", {}) for p in scan_preds.values() if p and p.get("market")), {})
|
| 131 |
shared_ctx = {
|
|
@@ -207,7 +257,9 @@ def get_top5_picks(
|
|
| 207 |
"risk": {},
|
| 208 |
}
|
| 209 |
|
| 210 |
-
# Step 3: Assemble picks
|
|
|
|
|
|
|
| 211 |
picks = []
|
| 212 |
for stock in candidates:
|
| 213 |
ticker = stock["ticker"]
|
|
@@ -267,8 +319,20 @@ def get_top5_picks(
|
|
| 267 |
pick["signals"] = {}
|
| 268 |
pick["signal_count"] = 0
|
| 269 |
pick["timeframes"] = timeframe_data
|
|
|
|
|
|
|
|
|
|
| 270 |
picks.append(pick)
|
| 271 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 272 |
return {
|
| 273 |
"picks": picks,
|
| 274 |
"market": market_from_scan,
|
|
|
|
| 116 |
except Exception:
|
| 117 |
scan_preds[ticker] = {}
|
| 118 |
|
| 119 |
+
# ββ Composite 5D profit score βββββββββββββββββββββββββββββββββββββββββββββ
|
| 120 |
+
# Goal: rank stocks by maximum expected profit over 5 days, not just confidence tier.
|
| 121 |
+
# Score components (all multiplicative on ret_hi so absolute return is preserved):
|
| 122 |
+
# conf_mult: HIGH=1.0 / MEDIUM=0.80 / LOW=0.55
|
| 123 |
+
# ml_factor: 1 + (ml_probability - 0.5) Γ 0.30 β range [0.85, 1.15]
|
| 124 |
+
# rr_factor: 1 + 0.12 if actual_rr >= 2.0 else 0 (rewards good risk/reward)
|
| 125 |
+
# sector_factor: 1.12 if sector leading / 0.90 if sector lagging / 1.0 neutral
|
| 126 |
+
# Minimum thresholds: ret_hi > 1.0% AND (no R:R data OR actual_rr >= 1.2)
|
| 127 |
+
_CONF_MULT = {"HIGH": 1.0, "MEDIUM": 0.80, "LOW": 0.55}
|
| 128 |
+
_MIN_RET_HI = 1.0 # % β must have at least 1% upside headroom for a 5D hold
|
| 129 |
+
_MIN_RR = 1.2 # minimum R:R when risk data is available
|
| 130 |
+
|
| 131 |
+
def _score_5d(p: dict) -> float:
|
| 132 |
+
"""Composite profit score for a 5D scan result. Higher is better."""
|
| 133 |
+
ret_hi_val = float(p.get("ret_hi") or 0.0)
|
| 134 |
+
conf = p.get("confidence", "LOW")
|
| 135 |
+
conf_mult = _CONF_MULT.get(conf, 0.55)
|
| 136 |
+
|
| 137 |
+
ml_prob = float((p.get("ml") or {}).get("probability") or 0.5)
|
| 138 |
+
ml_factor = 1.0 + (ml_prob - 0.5) * 0.30
|
| 139 |
+
|
| 140 |
+
risk_data = p.get("risk") or {}
|
| 141 |
+
actual_rr = risk_data.get("actual_rr")
|
| 142 |
+
rr_factor = 1.12 if (actual_rr is not None and actual_rr >= 2.0) else 1.0
|
| 143 |
+
|
| 144 |
+
sector_data = p.get("sector") or {}
|
| 145 |
+
if sector_data.get("leading"):
|
| 146 |
+
sector_factor = 1.12
|
| 147 |
+
elif sector_data.get("lagging"):
|
| 148 |
+
sector_factor = 0.90
|
| 149 |
+
else:
|
| 150 |
+
sector_factor = 1.0
|
| 151 |
+
|
| 152 |
+
return ret_hi_val * conf_mult * ml_factor * rr_factor * sector_factor
|
| 153 |
+
|
| 154 |
+
# Filter: BULLISH, valid confidence, no ai_unavailable block, min thresholds
|
| 155 |
+
bullish = []
|
| 156 |
+
for p in scan_preds.values():
|
| 157 |
+
if not p:
|
| 158 |
+
continue
|
| 159 |
+
if p.get("direction") != "BULLISH":
|
| 160 |
+
continue
|
| 161 |
+
if p.get("confidence") not in ("HIGH", "MEDIUM", "LOW"):
|
| 162 |
+
continue
|
| 163 |
+
if p.get("no_trade_reason") == "ai_unavailable":
|
| 164 |
+
continue
|
| 165 |
+
ret_hi_val = float(p.get("ret_hi") or 0.0)
|
| 166 |
+
if ret_hi_val < _MIN_RET_HI:
|
| 167 |
+
continue
|
| 168 |
+
risk_data = p.get("risk") or {}
|
| 169 |
+
actual_rr = risk_data.get("actual_rr")
|
| 170 |
+
if actual_rr is not None and actual_rr < _MIN_RR:
|
| 171 |
+
continue
|
| 172 |
+
bullish.append(p)
|
| 173 |
+
|
| 174 |
+
# Sort by composite 5D profit score descending.
|
| 175 |
+
# Expand candidate pool to 2Γ top_n so the full 1D/3D rerun has room to re-rank.
|
| 176 |
+
bullish.sort(key=_score_5d, reverse=True)
|
| 177 |
+
candidate_pool_size = top_n * 2 # fetch 10 full predictions, trim to top_n at end
|
| 178 |
+
candidates = bullish[:candidate_pool_size]
|
| 179 |
|
| 180 |
market_from_scan = next((p.get("market", {}) for p in scan_preds.values() if p and p.get("market")), {})
|
| 181 |
shared_ctx = {
|
|
|
|
| 257 |
"risk": {},
|
| 258 |
}
|
| 259 |
|
| 260 |
+
# Step 3: Assemble picks for full candidate pool, then re-rank by 5D profit score
|
| 261 |
+
# and trim to top_n. This ensures the final list maximises 5D return even after
|
| 262 |
+
# 1D/3D full predictions might have changed direction/confidence for some stocks.
|
| 263 |
picks = []
|
| 264 |
for stock in candidates:
|
| 265 |
ticker = stock["ticker"]
|
|
|
|
| 319 |
pick["signals"] = {}
|
| 320 |
pick["signal_count"] = 0
|
| 321 |
pick["timeframes"] = timeframe_data
|
| 322 |
+
|
| 323 |
+
# Attach composite 5D score using the full (debate) prediction as anchor
|
| 324 |
+
pick["_score_5d"] = _score_5d(ai_anchor if (ai_anchor and not ai_anchor.get("error")) else stock)
|
| 325 |
picks.append(pick)
|
| 326 |
|
| 327 |
+
# Re-rank by 5D composite profit score (uses full debate predictions where available)
|
| 328 |
+
picks.sort(key=lambda x: x.get("_score_5d", 0.0), reverse=True)
|
| 329 |
+
picks = picks[:top_n]
|
| 330 |
+
|
| 331 |
+
# Assign final ranks and remove internal score field
|
| 332 |
+
for i, p in enumerate(picks):
|
| 333 |
+
p["rank"] = i + 1
|
| 334 |
+
p.pop("_score_5d", None)
|
| 335 |
+
|
| 336 |
return {
|
| 337 |
"picks": picks,
|
| 338 |
"market": market_from_scan,
|