institutional-trader/TRADE_PLAN_CALCULATION.md

9.7 KiB
Raw Permalink Blame History

Trade Plan Calculation - Data Flow & Sources

Overview

The trade plan is automatically generated for every options flow signal with a rocket score >= 3. It calculates entry prices, stop losses, profit targets, and risk/reward ratios based on real-time price data.

Entry Point

File: backend/src/routes/optionsFlow.js (line 228-233)

if (rocketScore >= 3) {
  const tradePlan = generateTradePlan(enrichedRow);
  enrichedRow.tradePlan = tradePlan;
  enrichedRow.tradePlanDisplay = formatTradePlanDisplay(tradePlan);
}

Data Sources

1. Current Price (Primary Reference)

Sources (in priority order):

  • flow.yahooPriceData.currentPrice - REAL-TIME from Yahoo Finance API (PRIMARY)
  • flow.spot_num - Spot price from flow data (fallback)
  • flow.u_close - Close price at signal time (from database, may be stale)
  • flow.last_px - Last price (fallback)
  • flow.Price - Fallback price field

Yahoo Finance API: https://query1.finance.yahoo.com/v8/finance/chart/{symbol}?interval=1d&range=5d

  • Returns real-time regularMarketPrice or previousClose
  • This is the PRIMARY source for current price (not database)

2. VWAP (Volume Weighted Average Price)

Sources:

  • flow.vwap_at_signal - VWAP calculated at signal time (from Python service)
  • flow.vwap_lb - VWAP from SQL query
  • flow.vwap - Fallback

Calculation:

  • Sum of (price × volume) from RTH open to signal time / Sum of volume
  • Note: VWAP may still come from database/Python service, but entry prices use Yahoo Finance current price

3. RTH Open (Regular Trading Hours Open)

Sources (in priority order):

  • flow.yahooPriceData.open - REAL-TIME from Yahoo Finance API (PRIMARY)
  • flow.rth_open - From database (fallback, may be stale)
  • Falls back to current price if unavailable

Yahoo Finance API: Returns regularMarketOpen for today

4. Opening Range (OR High/Low)

Sources (in priority order):

  • flow.yahooPriceData.high / flow.yahooPriceData.low - REAL-TIME from Yahoo Finance API (PRIMARY)
    • Uses today's high/low as OR levels (more accurate than stale database data)
  • flow.or_high / flow.or_low - From database (fallback, may be stale)
  • Calculated fallback: currentPrice * 1.01 (high) or currentPrice * 0.99 (low)

Yahoo Finance API: Returns regularMarketDayHigh and regularMarketDayLow for today

  • Validation: Only used if within 10% of current price (to avoid stale data)

5. Prior High

Sources (in priority order):

  • flow.yahooPriceData.volumeHistory[1].high - REAL-TIME from Yahoo Finance API (PRIMARY)
    • Gets yesterday's high from volumeHistory (last 5 days data)
  • flow.prior_high - From database (fallback, may be stale)
  • flow.priorHigh - Alternative field name
  • Fallback: currentPrice * 1.02 (2% above current)

Yahoo Finance API: Returns volumeHistory with last 5 days including high/low/close

  • Validation: Only used if above current price and within 10% above

6. Prior Close

Sources (in priority order):

  • flow.yahooPriceData.previousClose - REAL-TIME from Yahoo Finance API (PRIMARY)
  • flow.prior_close or flow.priorClose - From database (fallback, may be stale)

Yahoo Finance API: Returns previousClose for previous trading day

7. Strike Price

Sources:

  • flow.strike_num - Strike price from options flow
  • flow.Strike - Alternative field name
  • Validation: Only used for T3 target if within 20% of current price

Calculation Flow

Step 1: Determine Signal (BUY/SELL/WAIT)

Function: determineSignal(flowData)

  • Based on badges (🟢/🔴, 💎, , 💰, )
  • Checks tape alignment
  • Checks rocket score

Step 2: Generate Entry Strategy

Function: generateEntryStrategy(flowData, signal)

For BUY Signals:

  • Primary Entry: VWAP (if available) OR current price
  • Aggressive Entry: OR high (if reasonable) OR current price * 1.005
  • Conditional Triggers:
    • VWAP reclaim (if price < VWAP)
    • Prior high break (if price < prior high)
    • OR breakout (if price < OR high)

For SELL Signals:

  • Primary Entry: VWAP (if available) OR current price
  • Aggressive Entry: OR low (if reasonable) OR current price * 0.995
  • Conditional Triggers:
    • VWAP rejection (if price > VWAP)
    • OR breakdown (if price > OR low)

For WAIT Signals:

  • Primary Entry: null (no entry yet)
  • Conditional Triggers:
    • Price breaks prior high (if within 10% above current)
    • OR breakout (if within 5% above current)
    • VWAP reclaim (if within 5% of current)
    • Tape alignment turns positive
    • Flow resumes (if flow is dead/stale)

Step 3: Calculate Stop Loss

Function: calculateStopLoss(flow, entryPrice)

Reference Price:

  • Uses entryPrice if available (for BUY/SELL)
  • Uses currentPrice if no entry (for WAIT signals)

For BULL/BUY Signals:

  • Tight Stop: referencePrice * 0.985 (-1.5%)
  • Wide Stop:
    • OR low (if within 5% of reference price) OR
    • referencePrice * 0.975 (-2.5%)

For BEAR/SELL Signals:

  • Tight Stop: referencePrice * 1.015 (+1.5%)
  • Wide Stop:
    • OR high (if within 5% of reference price) OR
    • referencePrice * 1.025 (+2.5%)

Step 4: Calculate Profit Targets

Function: calculateTargets(flow, entryPrice, signal)

Reference Price:

  • Uses entryPrice if available
  • Uses currentPrice if no entry (for WAIT signals)

For BUY/BULL Signals:

  • T1: referencePrice * 1.015 (+1.5%) - Take 50%
  • T2: referencePrice * 1.025 (+2.5%) - Take 30%
  • T3:
    • Strike price (if within 20% above reference) OR
    • referencePrice * 1.04 (+4%) - Runner 20%

For SELL/BEAR Signals:

  • T1: referencePrice * 0.985 (-1.5%) - Take 50%
  • T2: referencePrice * 0.975 (-2.5%) - Take 30%
  • T3:
    • Strike price (if within 20% below reference) OR
    • referencePrice * 0.96 (-4%) - Runner 20%

Step 5: Calculate Risk/Reward

Function: calculateRiskReward(entry, stop, target)

Formula:

  • Risk = |stop - entry| / entry * 100
  • Reward = |target - entry| / entry * 100
  • Ratio = reward / risk

Step 6: Calculate Readiness (WAIT signals only)

Function: calculateReadiness(plan)

Scoring:

  • Confidence * 0.6 (60% weight)
  • Entry strategy exists: +15 points
  • Stop loss exists: +10 points
  • Targets exist: +10 points
  • Reasoning exists: +5 points
  • Max: 100%

Key Validations

Price Level Validation

All price levels are validated against current price to avoid stale data:

  1. OR High/Low: Only used if within 10% of current price
  2. Prior High: Only used if above current and within 10% above
  3. VWAP: Only used if within 5% of current price
  4. Strike Price: Only used for T3 if within 20% of current price

Fallback Logic

If any price data is missing or stale:

  • Uses current price as base
  • Calculates percentage-based levels (e.g., +1.5%, -2.5%)
  • Never uses unreasonable/stale data

Example Calculation

Given:

  • Current Price: $131.81
  • VWAP: $130.50
  • OR High: $132.00
  • OR Low: $130.00
  • Strike: $155.00 (too far, ignored)
  • Signal: WAIT (BULL direction)

Entry Strategy:

  • Primary: null (WAIT signal)
  • Conditional Triggers:
    • VWAP reclaim at $130.50 (if price < VWAP)
    • OR breakout at $132.00 (if price < OR high)

Stop Loss (using current price $131.81):

  • Tight: $131.81 * 0.985 = $129.83 (-1.5%)
  • Wide: $130.00 (OR low, within 5%)

Targets (using current price $131.81):

  • T1: $131.81 * 1.015 = $133.79 (+1.5%)
  • T2: $131.81 * 1.025 = $135.11 (+2.5%)
  • T3: $131.81 * 1.04 = $137.08 (+4%) - Strike $155 ignored (too far)

Data Fetching

Yahoo Finance API (PRIMARY SOURCE)

Service: backend/src/services/yahooFinanceService.js Function: batchFetchYahooFinanceData(symbols)

API Endpoint:

https://query1.finance.yahoo.com/v8/finance/chart/{symbol}?interval=1d&range=5d

Returns:

  • currentPrice - Real-time market price
  • previousClose - Previous day's close
  • open - Today's open
  • high - Today's high
  • low - Today's low
  • volume - Today's volume
  • volumeHistory - Last 5 days with high/low/close/volume

When Fetched:

  • Fetched in optionsFlow.js route before trade plan generation
  • Passed to trade plan generator as yahooPriceData or stockPriceData
  • This is the PRIMARY source - database is only used as fallback

Database Queries (FALLBACK ONLY)

Note: Database queries are only used if Yahoo Finance data is unavailable

Price at Signal Time (Fallback)

SELECT close, high, low, volume, ts
FROM prices_intraday_1m
WHERE UPPER(symbol) = UPPER($1)
  AND ts <= $2  -- signal time
ORDER BY ts DESC
LIMIT 1

RTH Open (Fallback)

SELECT open, ts
FROM prices_intraday_1m
WHERE UPPER(symbol) = UPPER($1)
  AND (timezone('America/Chicago', ts))::date = $2  -- flow date
  AND (timezone('America/Chicago', ts))::time >= time '09:30:00'
ORDER BY ts ASC
LIMIT 1

Prior Close (Fallback)

SELECT close
FROM prices_daily
WHERE UPPER(symbol) = UPPER($1)
  AND "Date" = $2 - INTERVAL '1 day'  -- prior day
ORDER BY "Date" DESC
LIMIT 1

Summary

Entry Prices: Derived from VWAP, OR levels, or current price (from Yahoo Finance) Stop Loss: Percentage-based (-1.5% tight, -2.5% wide) with OR level fallback (from Yahoo Finance) Targets: Percentage-based (+1.5%, +2.5%, +4%) with strike price option All calculations:

  • PRIMARY: Use Yahoo Finance real-time data (currentPrice, open, high, low, previousClose, volumeHistory)
  • FALLBACK: Use database data only if Yahoo Finance unavailable
  • Validate all levels against current price to avoid stale data

Key Change: Trade plans now use Yahoo Finance API as the primary data source for all price calculations, ensuring real-time accuracy instead of stale database data.