Add implementation plan for /ES multi-timeframe confluence chart
Planning-only commit: no application code yet. The plan specifies a realtime /ES chart that derives moving averages and trendlines across multiple timeframes, projects them onto one chart in a shared (time, price) plane, and alerts when levels from different timeframes converge. Key findings that shaped it, all verified against source rather than assumed: - Schwab streams realtime futures fine (CHART_FUTURES, LEVEL_ONE_FUTURES) but provides no futures price *history* at all. An account does not change this; it is an API-surface limit. - Yahoo's chart endpoint needs no key and has exactly what Schwab lacks: ~730d of hourly ES=F (~750 sessions), enough to warm a 200DMA from startup. So it serves as both the no-keys dev source and the history seeder, behind one MarketDataSource protocol. - Yahoo anchors daily bars to midnight ET while the CME session runs 18:00-17:00 ET, so daily bars are built from hourly using our own session rules instead. - Lightweight Charts v5 replaced addCandlestickSeries() with addSeries(CandlestickSeries, ...); most tutorials online are v4. Build order defers judgment-heavy work: moving averages first (fully deterministic), then confluence scoring, then hand-drawn trendlines. Automatic trendline detection comes last, tuned against the hand-drawn lines as ground truth. Includes a real trimmed Yahoo response as a test fixture; it contains a null in the OHLC arrays, which is the parsing case that needs handling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
3cc682d63a
commit
8e50d5cbc2
3 changed files with 1518 additions and 0 deletions
|
|
@ -5,6 +5,11 @@ FastAPI backend + Vue 3 (from CDN, no build step) served at
|
||||||
|
|
||||||
Currently a placeholder: the frontend calls `/api/hello` and prints the JSON.
|
Currently a placeholder: the frontend calls `/api/hello` and prints the JSON.
|
||||||
|
|
||||||
|
**Where this is going:** a realtime `/ES` chart that derives trendlines and moving
|
||||||
|
averages across many timeframes and alerts when they converge. The full spec lives in
|
||||||
|
[`docs/IMPLEMENTATION_PLAN.md`](docs/IMPLEMENTATION_PLAN.md) — read it before writing
|
||||||
|
code; it records decisions and verified API facts that are expensive to rediscover.
|
||||||
|
|
||||||
## Local development
|
## Local development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
1145
docs/IMPLEMENTATION_PLAN.md
Normal file
1145
docs/IMPLEMENTATION_PLAN.md
Normal file
File diff suppressed because it is too large
Load diff
368
tests/fixtures/yahoo_es_1h.json
vendored
Normal file
368
tests/fixtures/yahoo_es_1h.json
vendored
Normal file
|
|
@ -0,0 +1,368 @@
|
||||||
|
{
|
||||||
|
"chart": {
|
||||||
|
"result": [
|
||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"currency": "USD",
|
||||||
|
"symbol": "ES=F",
|
||||||
|
"exchangeName": "CME",
|
||||||
|
"fullExchangeName": "CME",
|
||||||
|
"instrumentType": "FUTURE",
|
||||||
|
"firstTradeDate": 969249600,
|
||||||
|
"regularMarketTime": 1786324854,
|
||||||
|
"hasPrePostMarketData": false,
|
||||||
|
"gmtoffset": -14400,
|
||||||
|
"timezone": "EDT",
|
||||||
|
"exchangeTimezoneName": "America/New_York",
|
||||||
|
"regularMarketPrice": 7778.0,
|
||||||
|
"fiftyTwoWeekHigh": 7820.25,
|
||||||
|
"fiftyTwoWeekLow": 6353.25,
|
||||||
|
"regularMarketDayHigh": 7779.25,
|
||||||
|
"regularMarketDayLow": 7763.0,
|
||||||
|
"regularMarketVolume": 25260,
|
||||||
|
"shortName": "E-Mini S&P 500 Sep 26",
|
||||||
|
"chartPreviousClose": 7765.5,
|
||||||
|
"previousClose": 7779.75,
|
||||||
|
"scale": 3,
|
||||||
|
"priceHint": 2,
|
||||||
|
"currentTradingPeriod": {
|
||||||
|
"pre": {
|
||||||
|
"timezone": "EDT",
|
||||||
|
"end": 1786248000,
|
||||||
|
"start": 1786248000,
|
||||||
|
"gmtoffset": -14400
|
||||||
|
},
|
||||||
|
"regular": {
|
||||||
|
"timezone": "EDT",
|
||||||
|
"end": 1786334340,
|
||||||
|
"start": 1786248000,
|
||||||
|
"gmtoffset": -14400
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"timezone": "EDT",
|
||||||
|
"end": 1786334340,
|
||||||
|
"start": 1786334340,
|
||||||
|
"gmtoffset": -14400
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tradingPeriods": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"timezone": "EDT",
|
||||||
|
"end": 1785902340,
|
||||||
|
"start": 1785816000,
|
||||||
|
"gmtoffset": -14400
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"timezone": "EDT",
|
||||||
|
"end": 1785988740,
|
||||||
|
"start": 1785902400,
|
||||||
|
"gmtoffset": -14400
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"timezone": "EDT",
|
||||||
|
"end": 1786075140,
|
||||||
|
"start": 1785988800,
|
||||||
|
"gmtoffset": -14400
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"timezone": "EDT",
|
||||||
|
"end": 1786161540,
|
||||||
|
"start": 1786075200,
|
||||||
|
"gmtoffset": -14400
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"timezone": "EDT",
|
||||||
|
"end": 1786334340,
|
||||||
|
"start": 1786248000,
|
||||||
|
"gmtoffset": -14400
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"dataGranularity": "1h",
|
||||||
|
"range": "5d",
|
||||||
|
"validRanges": [
|
||||||
|
"1d",
|
||||||
|
"5d",
|
||||||
|
"1mo",
|
||||||
|
"3mo",
|
||||||
|
"6mo",
|
||||||
|
"1y",
|
||||||
|
"2y",
|
||||||
|
"5y",
|
||||||
|
"10y",
|
||||||
|
"ytd",
|
||||||
|
"max"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"timestamp": [
|
||||||
|
1785816000,
|
||||||
|
1785819600,
|
||||||
|
1785823200,
|
||||||
|
1785826800,
|
||||||
|
1785830400,
|
||||||
|
1785834000,
|
||||||
|
1785837600,
|
||||||
|
1785841200,
|
||||||
|
1785844800,
|
||||||
|
1785848400,
|
||||||
|
1785852000,
|
||||||
|
1785855600,
|
||||||
|
1785859200,
|
||||||
|
1785862800,
|
||||||
|
1785866400,
|
||||||
|
1785870000,
|
||||||
|
1785873600,
|
||||||
|
1785877200,
|
||||||
|
1785880800,
|
||||||
|
1785884400,
|
||||||
|
1785888000,
|
||||||
|
1785891600,
|
||||||
|
1785895200,
|
||||||
|
1785898800,
|
||||||
|
1785902400,
|
||||||
|
1785906000,
|
||||||
|
1785909600,
|
||||||
|
1785913200,
|
||||||
|
1785916800,
|
||||||
|
1785920400,
|
||||||
|
1785924000,
|
||||||
|
1785927600,
|
||||||
|
1785931200,
|
||||||
|
1785934800,
|
||||||
|
1785938400,
|
||||||
|
1785942000,
|
||||||
|
1785945600,
|
||||||
|
1785949200,
|
||||||
|
1785952800,
|
||||||
|
1785956400
|
||||||
|
],
|
||||||
|
"indicators": {
|
||||||
|
"quote": [
|
||||||
|
{
|
||||||
|
"open": [
|
||||||
|
7644.0,
|
||||||
|
7645.25,
|
||||||
|
7647.75,
|
||||||
|
7644.5,
|
||||||
|
7643.5,
|
||||||
|
7637.0,
|
||||||
|
7637.75,
|
||||||
|
7643.25,
|
||||||
|
7654.5,
|
||||||
|
7651.0,
|
||||||
|
7685.25,
|
||||||
|
7715.5,
|
||||||
|
7736.5,
|
||||||
|
7755.25,
|
||||||
|
7768.25,
|
||||||
|
7773.0,
|
||||||
|
7763.75,
|
||||||
|
null,
|
||||||
|
7772.0,
|
||||||
|
7780.75,
|
||||||
|
7777.25,
|
||||||
|
7784.25,
|
||||||
|
7784.5,
|
||||||
|
7786.75,
|
||||||
|
7792.75,
|
||||||
|
7791.25,
|
||||||
|
7798.5,
|
||||||
|
7798.25,
|
||||||
|
7792.75,
|
||||||
|
7784.25,
|
||||||
|
7788.5,
|
||||||
|
7797.5,
|
||||||
|
7798.0,
|
||||||
|
7799.5,
|
||||||
|
7818.75,
|
||||||
|
7786.5,
|
||||||
|
7757.75,
|
||||||
|
7769.75,
|
||||||
|
7767.0,
|
||||||
|
7765.5
|
||||||
|
],
|
||||||
|
"close": [
|
||||||
|
7645.5,
|
||||||
|
7647.5,
|
||||||
|
7644.5,
|
||||||
|
7643.5,
|
||||||
|
7637.25,
|
||||||
|
7637.5,
|
||||||
|
7643.0,
|
||||||
|
7654.5,
|
||||||
|
7651.0,
|
||||||
|
7685.5,
|
||||||
|
7715.25,
|
||||||
|
7736.5,
|
||||||
|
7755.25,
|
||||||
|
7768.25,
|
||||||
|
7773.0,
|
||||||
|
7764.75,
|
||||||
|
7774.5,
|
||||||
|
null,
|
||||||
|
7780.75,
|
||||||
|
7777.5,
|
||||||
|
7784.25,
|
||||||
|
7784.25,
|
||||||
|
7786.75,
|
||||||
|
7792.0,
|
||||||
|
7791.25,
|
||||||
|
7798.75,
|
||||||
|
7798.0,
|
||||||
|
7793.0,
|
||||||
|
7784.25,
|
||||||
|
7788.5,
|
||||||
|
7797.5,
|
||||||
|
7798.0,
|
||||||
|
7799.5,
|
||||||
|
7819.25,
|
||||||
|
7786.25,
|
||||||
|
7758.0,
|
||||||
|
7769.5,
|
||||||
|
7767.0,
|
||||||
|
7765.5,
|
||||||
|
7748.25
|
||||||
|
],
|
||||||
|
"low": [
|
||||||
|
7641.75,
|
||||||
|
7642.75,
|
||||||
|
7642.75,
|
||||||
|
7641.5,
|
||||||
|
7635.25,
|
||||||
|
7631.75,
|
||||||
|
7635.5,
|
||||||
|
7641.5,
|
||||||
|
7651.0,
|
||||||
|
7649.25,
|
||||||
|
7682.5,
|
||||||
|
7714.0,
|
||||||
|
7733.25,
|
||||||
|
7754.25,
|
||||||
|
7763.5,
|
||||||
|
7761.25,
|
||||||
|
7761.25,
|
||||||
|
null,
|
||||||
|
7771.0,
|
||||||
|
7775.75,
|
||||||
|
7776.0,
|
||||||
|
7777.75,
|
||||||
|
7783.0,
|
||||||
|
7786.5,
|
||||||
|
7788.25,
|
||||||
|
7790.5,
|
||||||
|
7791.0,
|
||||||
|
7788.0,
|
||||||
|
7780.25,
|
||||||
|
7782.5,
|
||||||
|
7787.5,
|
||||||
|
7792.5,
|
||||||
|
7795.5,
|
||||||
|
7795.0,
|
||||||
|
7776.0,
|
||||||
|
7754.5,
|
||||||
|
7750.5,
|
||||||
|
7761.75,
|
||||||
|
7763.25,
|
||||||
|
7745.75
|
||||||
|
],
|
||||||
|
"volume": [
|
||||||
|
0,
|
||||||
|
5511,
|
||||||
|
7319,
|
||||||
|
14850,
|
||||||
|
18165,
|
||||||
|
14744,
|
||||||
|
19853,
|
||||||
|
29305,
|
||||||
|
21498,
|
||||||
|
205567,
|
||||||
|
243043,
|
||||||
|
187171,
|
||||||
|
123068,
|
||||||
|
152916,
|
||||||
|
128635,
|
||||||
|
293219,
|
||||||
|
80121,
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
6231,
|
||||||
|
8543,
|
||||||
|
8701,
|
||||||
|
8414,
|
||||||
|
7996,
|
||||||
|
4935,
|
||||||
|
6946,
|
||||||
|
9271,
|
||||||
|
15543,
|
||||||
|
21633,
|
||||||
|
12652,
|
||||||
|
12910,
|
||||||
|
14971,
|
||||||
|
28403,
|
||||||
|
203055,
|
||||||
|
265756,
|
||||||
|
189580,
|
||||||
|
148224,
|
||||||
|
81542,
|
||||||
|
72103,
|
||||||
|
207321
|
||||||
|
],
|
||||||
|
"high": [
|
||||||
|
7646.5,
|
||||||
|
7649.5,
|
||||||
|
7650.0,
|
||||||
|
7648.0,
|
||||||
|
7645.75,
|
||||||
|
7638.5,
|
||||||
|
7647.75,
|
||||||
|
7657.75,
|
||||||
|
7656.25,
|
||||||
|
7686.5,
|
||||||
|
7716.5,
|
||||||
|
7741.25,
|
||||||
|
7755.75,
|
||||||
|
7783.75,
|
||||||
|
7777.25,
|
||||||
|
7786.0,
|
||||||
|
7781.25,
|
||||||
|
null,
|
||||||
|
7783.25,
|
||||||
|
7782.75,
|
||||||
|
7785.5,
|
||||||
|
7786.0,
|
||||||
|
7788.75,
|
||||||
|
7792.5,
|
||||||
|
7792.75,
|
||||||
|
7800.0,
|
||||||
|
7799.5,
|
||||||
|
7799.5,
|
||||||
|
7796.75,
|
||||||
|
7792.0,
|
||||||
|
7798.0,
|
||||||
|
7799.75,
|
||||||
|
7805.25,
|
||||||
|
7820.25,
|
||||||
|
7818.75,
|
||||||
|
7791.5,
|
||||||
|
7773.75,
|
||||||
|
7773.0,
|
||||||
|
7774.5,
|
||||||
|
7771.5
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"error": null
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue