9.7 KiB
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
regularMarketPriceorpreviousClose - 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 queryflow.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) orcurrentPrice * 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_closeorflow.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 flowflow.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
entryPriceif available (for BUY/SELL) - Uses
currentPriceif 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
entryPriceif available - Uses
currentPriceif 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:
- OR High/Low: Only used if within 10% of current price
- Prior High: Only used if above current and within 10% above
- VWAP: Only used if within 5% of current price
- 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 pricepreviousClose- Previous day's closeopen- Today's openhigh- Today's highlow- Today's lowvolume- Today's volumevolumeHistory- Last 5 days with high/low/close/volume
When Fetched:
- Fetched in
optionsFlow.jsroute before trade plan generation - Passed to trade plan generator as
yahooPriceDataorstockPriceData - 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.