Files
atm/docs/claude-master-design-20260415-atm-trading.md
Claude Agent 9207197a56 initial: scaffold atm trading monitor (Faza 1)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 22:03:36 +00:00

150 lines
9.3 KiB
Markdown

# 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.