initial: scaffold atm trading monitor (Faza 1)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
149
docs/claude-master-design-20260415-atm-trading.md
Normal file
149
docs/claude-master-design-20260415-atm-trading.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# Design: ATM — Automated Trading Monitor (M2D Strategy)
|
||||
|
||||
Generated by /office-hours on 2026-04-15
|
||||
Branch: master
|
||||
Repo: /workspace/atm (greenfield)
|
||||
Status: APPROVED
|
||||
Mode: Builder (personal live-trading tool, high-stakes)
|
||||
|
||||
## Problem Statement
|
||||
|
||||
User trades the M2D strategy on DIA (TradeStation chart with custom indicator) with execution on TradeLocker US30 CFD (prop firm account). Same strategy also applies to GLD → XAUUSD. Bridging signal source (TradeStation Windows app) with execution (TradeLocker web) currently requires user to watch both screens for 4 hours per evening. Goal: bot detects the trigger signal automatically and notifies user via Telegram/Discord with chart screenshot + SL/TP levels so user can execute the trade in TradeLocker.
|
||||
|
||||
## Strategy M2D — Full Spec
|
||||
|
||||
**Setup:** TradeStation, 3-minute chart, DIA (or GLD) symbol, custom indicator "M2D MAPS" that renders a horizontal strip of colored dots below the price panel. Dots are indexed by time, y-position is fixed.
|
||||
|
||||
### BUY sequence (sequential in time, rightmost N dots):
|
||||
1. **Turquoise dot** — 15-minute buy trigger
|
||||
2. **Dark green dot** — 3-minute sell
|
||||
3. **Light green dot** — 3-minute buy → **TRIGGER**
|
||||
|
||||
At trigger:
|
||||
- Execute BUY on TradeLocker, instrument US30 CFD
|
||||
- Stop Loss 0.6%
|
||||
- Volume 0.1 lots maximum
|
||||
- TP1, TP2, SL are drawn automatically as horizontal lines on the TradeStation chart after entry
|
||||
- User manual lifecycle: at TP1 close half, move SL to ~breakeven; at TP2 close remaining half
|
||||
|
||||
### SELL sequence (mirror):
|
||||
1. **Yellow dot** — 15-minute sell (red 15min candle)
|
||||
2. **Dark red dot** — 3-minute buy
|
||||
3. **Light red dot** — 3-minute sell → **TRIGGER**
|
||||
|
||||
Same size (0.1 lots), same SL %, same TP management.
|
||||
|
||||
### Instrument mapping (intentional asymmetry):
|
||||
- DIA chart (TradeStation) ↔ US30 CFD (TradeLocker)
|
||||
- GLD chart (TradeStation) ↔ XAUUSD CFD (TradeLocker)
|
||||
|
||||
### Trading window:
|
||||
- NY open first 2 hours + NY close last 2 hours
|
||||
- RO summer time: 16:30-18:30 and 21:00-23:00
|
||||
- Typical frequency: 1 trade per evening
|
||||
|
||||
## Constraints
|
||||
|
||||
- **Prop firm account on TradeLocker.** Faza 2 (auto-execution) requires reading prop TOS first — many prop firms prohibit automation or detect robotic timing patterns.
|
||||
- No API on TradeLocker. No signal export on TradeStation for compiled custom indicator.
|
||||
- Bot runs on the same Windows machine as TradeStation. Cross-machine (RDP/VNC) screenshot adds latency and fragility.
|
||||
|
||||
## Premises (agreed)
|
||||
|
||||
1. Screenshot + visual detection is the only viable bridge.
|
||||
2. Notification-first (Faza 1) is the right sequencing. Zero-click MVP removes all financial bug risk.
|
||||
3. M2D MAPS dot strip has stable y-position on fixed TradeStation layout → ROI color sampling is the right detection method.
|
||||
4. DIA→US30 price divergence is acceptable risk (user's judgment, has been trading this pairing live).
|
||||
5. Bot runs on the same Windows machine as TradeStation.
|
||||
|
||||
## Recommended Approach — B: Structured Service with Dry-Run and Audit Log
|
||||
|
||||
Python package on Windows, structured for clean extension to Faza 2.
|
||||
|
||||
### Components:
|
||||
- **Detector core:** `mss` screenshot of TradeStation window (located by title via `pygetwindow`) → crop M2D MAPS ROI → scan rightmost N dot positions → classify each by closest-color match with tolerance → feed into state machine that tracks 3-dot sequences (turquoise→dark-green→light-green = BUY trigger; yellow→dark-red→light-red = SELL trigger).
|
||||
- **Level extractor:** after trigger, scan chart region for horizontal colored lines (SL/TP1/TP2). Convert pixel y to price via calibration of y-axis scale.
|
||||
- **Calibration tool (Tkinter):** interactive — user clicks on each dot color sample, captures RGB + tolerance, clicks on ROI corners, captures y-axis price references. Writes to `config.toml`.
|
||||
- **Dry-run mode:** runs detector against a folder of saved screenshots (recorded during normal operation). Shows what notification WOULD have been sent for each. Used to validate new color thresholds or strategy tweaks without live risk.
|
||||
- **Notifier abstraction:** interface with Discord webhook and Telegram bot implementations. Sends: annotated screenshot + decoded SL/TP1/TP2 prices + signal type (BUY/SELL) + timestamp.
|
||||
- **Audit log (JSONL):** every detection cycle — timestamp, detected dots, classification, decision, notification sent y/n. Replayable, debuggable.
|
||||
- **Scheduler:** Windows Task Scheduler entry, auto-start/stop at 16:30 / 18:30 / 21:00 / 23:00 local time (summer/winter offset aware).
|
||||
|
||||
### Structure:
|
||||
```
|
||||
atm/
|
||||
├── pyproject.toml
|
||||
├── config.toml # populated by calibration tool
|
||||
├── src/atm/
|
||||
│ ├── detector.py # screenshot + color classification + state machine
|
||||
│ ├── levels.py # SL/TP1/TP2 pixel-to-price extraction
|
||||
│ ├── notifier/
|
||||
│ │ ├── __init__.py # abstract Notifier
|
||||
│ │ ├── discord.py
|
||||
│ │ └── telegram.py
|
||||
│ ├── audit.py # JSONL logger
|
||||
│ ├── calibrate.py # Tkinter UI
|
||||
│ ├── dryrun.py # replay on saved screenshots
|
||||
│ └── main.py # orchestration + scheduler hooks
|
||||
├── samples/ # saved screenshots for dry-run corpus
|
||||
└── logs/ # JSONL audit
|
||||
```
|
||||
|
||||
### Detection algorithm (core loop):
|
||||
1. Every 1 second during trading window:
|
||||
- Locate TradeStation window
|
||||
- If not foreground or minimized, log + skip
|
||||
- Screenshot M2D MAPS ROI (fixed offsets from window bounds)
|
||||
- For rightmost N=5 dot positions, sample center pixel, classify to nearest labeled color within tolerance
|
||||
- Update rolling window of last 10 dots with their timestamps
|
||||
- Evaluate state machine: did the last 3 classified dots (within a bounded time window) complete a BUY or SELL sequence?
|
||||
- If trigger fired AND not already fired for this bar: extract SL/TP1/TP2 levels, send notification, log, mark fired.
|
||||
|
||||
### Anti-duplicate logic:
|
||||
- Each trigger dot is keyed by (x-pixel position at capture, color). Once fired, stored in "recently fired" set with 10-minute TTL. Prevents re-fire if same dot persists across cycles.
|
||||
|
||||
### Sanity guards:
|
||||
- If classification confidence (color distance) low for 3+ cycles in a row → push "bot lost sight" alert to user. Layout may have changed.
|
||||
- If TradeStation window not found for 60 seconds → push "bot cannot find chart" alert.
|
||||
|
||||
## Open Questions (non-blocking)
|
||||
|
||||
- Exact color tolerance values — determined during calibration session, not a design question.
|
||||
- GLD/XAUUSD: same M2D indicator on GLD chart? Assume yes, confirm during calibration.
|
||||
- Multi-symbol monitoring — single window switched manually, or two TradeStation windows side by side? Defer; v1 = single chart at a time, user switches manually.
|
||||
|
||||
## Success Criteria (Faza 1)
|
||||
|
||||
- Over 20 live trading sessions, bot detects ≥95% of signals user also spotted manually.
|
||||
- Zero false-positive notifications during the bot's first 5 sessions (tune tolerances aggressively).
|
||||
- Notification delivered within 3 seconds of trigger dot appearing.
|
||||
- Audit log lets user reproduce "why was no notification sent" for any missed signal.
|
||||
|
||||
## Distribution Plan
|
||||
|
||||
Personal tool, single user. No distribution channel needed — runs locally on user's Windows box. Git repo at `/workspace/atm`. `pyproject.toml` + `pip install -e .` for local dev. No CI/CD; user's own `scheduled task` starts/stops it.
|
||||
|
||||
## Risk Flag — Faza 2 (deferred)
|
||||
|
||||
Before extending to auto-execution in TradeLocker:
|
||||
1. Read prop firm TOS (search for "EA", "automation", "bot", "copy trading", "external signal"). If prohibited, **Faza 2 is off the table** — tool stays notification-only.
|
||||
2. If permitted, implement via Playwright browser automation against TradeLocker web UI.
|
||||
3. Add human-like click timing randomization (100-400ms jitter) to avoid robotic detection.
|
||||
4. Dry-run mode then becomes: "click coordinates resolved, action NOT sent" — user reviews the intended click before enabling live.
|
||||
|
||||
## Next Steps (concrete)
|
||||
|
||||
1. Init `/workspace/atm` as Python project. `pyproject.toml`, basic structure.
|
||||
2. Build calibration tool first. Without calibrated config, nothing works.
|
||||
3. Record 20-30 sample screenshots across several trading sessions (can start this today — doesn't need any code yet; just `mss` screenshot on a 5-second timer dumping to disk).
|
||||
4. Build detector + state machine. Validate against recorded screenshots in dry-run mode.
|
||||
5. Wire Discord webhook first (simpler than Telegram bot). Test end-to-end on live session.
|
||||
6. Add audit log.
|
||||
7. Schedule Windows task for trading hours.
|
||||
|
||||
## What I noticed about how you think
|
||||
|
||||
- You explicitly asked for dry-run before writing a line of code. "Să verific dacă vrea să apese corect, fără să apese efectiv." That's not a common instinct for someone building their own tool; it's the instinct of someone who has already had something break expensively.
|
||||
- You phased the project yourself — "faza 2 după ce mă conving că merge." That's the right ordering and you arrived at it unprompted.
|
||||
- When I challenged the API premise, you answered with specifics: the indicator is custom, the account doesn't support API. You knew the constraint, not guessed it.
|
||||
- You flagged the prop account almost casually at the end. A lot of builders would have skipped that detail. It turned out to be the most important constraint in the entire design.
|
||||
Reference in New Issue
Block a user