feat: complete Faza 1 implementation (105 tests green)
All 12 modules built per reviewed plan: - detector, state_machine (5-state phased FSM), canary, levels Phase B - notifier fanout (Discord + Telegram, bounded queue, retry, dead-letter) - audit (JSONL daily rotation), journal, report (weekly R-multiple PnL) - calibrate + labeler (Tk, lazy-imported), dryrun with acceptance gate - unified CLI: atm calibrate|label|dryrun|run|journal|report README + Phase 2 prop-firm TOS audit checklist included. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
179
README.md
Normal file
179
README.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# ATM — Automated Trading Monitor
|
||||
|
||||
Personal tool for the **M2D strategy** on TradeStation DIA/GLD charts with US30/XAUUSD execution on TradeLocker. The bot watches the colored dot strip produced by the *M2D MAPS* custom indicator and sends a Telegram/Discord notification (with chart screenshot + SL/TP levels) when a BUY or SELL trigger fires — so you execute the trade manually in TradeLocker instead of watching two screens.
|
||||
|
||||
**Current phase: Faza 1 — notification-only.** No auto-execution until prop firm TOS has been audited (see `docs/phase2-prop-firm-audit.md`).
|
||||
|
||||
---
|
||||
|
||||
## Project structure
|
||||
|
||||
```
|
||||
atm/
|
||||
├── pyproject.toml
|
||||
├── configs/ # calibration configs (YYYY-MM-DD-HHMM.toml + current.txt)
|
||||
├── logs/ # audit JSONL + dead-letter queue
|
||||
├── samples/ # screenshots for dry-run validation
|
||||
└── src/atm/
|
||||
├── config.py # Config dataclass + loader
|
||||
├── detector.py # screenshot → color → state machine
|
||||
├── state_machine.py
|
||||
├── vision.py # color matching helpers
|
||||
├── levels.py # SL/TP pixel-to-price
|
||||
├── calibrate.py # Tkinter calibration wizard
|
||||
├── labeler.py # Tkinter sample labeler
|
||||
├── journal.py # trade journal (JSONL)
|
||||
├── report.py # weekly performance report
|
||||
├── audit.py # structured audit log
|
||||
├── canary.py # layout drift detection
|
||||
├── dryrun.py # replay saved screenshots
|
||||
├── notifier/
|
||||
│ ├── discord.py
|
||||
│ └── telegram.py
|
||||
└── main.py # unified CLI
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Python 3.11+
|
||||
- Windows 10/11 (required for live capture; dry-run works on any OS)
|
||||
- TradeStation running with a 3-minute DIA or GLD chart open
|
||||
|
||||
### Install
|
||||
|
||||
```bash
|
||||
# Clone (internal repo)
|
||||
git clone git@gitea.romfast.ro:romfast/atm.git
|
||||
cd atm
|
||||
|
||||
# Create venv and install
|
||||
python -m venv .venv
|
||||
.venv\Scripts\activate # Windows
|
||||
pip install -e .
|
||||
|
||||
# Windows-only extras (screen capture, window detection)
|
||||
pip install -e ".[windows]"
|
||||
```
|
||||
|
||||
### Environment variables (notifiers)
|
||||
|
||||
Create a `.env` file or set these in your shell before running:
|
||||
|
||||
```
|
||||
ATM_DISCORD_WEBHOOK=https://discord.com/api/webhooks/...
|
||||
ATM_TELEGRAM_TOKEN=123456789:AABBcc...
|
||||
ATM_TELEGRAM_CHAT_ID=-100123456789
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Calibration workflow
|
||||
|
||||
Calibration maps the TradeStation window layout to the config that drives detection. **Redo calibration whenever you resize the chart window, change DPI, or switch monitors.**
|
||||
|
||||
### Step-by-step
|
||||
|
||||
1. **Open TradeStation** with the 3-minute DIA chart. Maximise or snap to a fixed position. Do not resize it during the session.
|
||||
|
||||
2. **Run the calibration wizard:**
|
||||
|
||||
```bash
|
||||
atm calibrate
|
||||
```
|
||||
|
||||
3. **Pick window title** — type the exact string that appears in the TradeStation title bar (e.g. `DIA - 3 Min`). The bot uses this to locate the window via `pygetwindow`.
|
||||
|
||||
4. **Mark the dot ROI** — a screenshot of the current window is shown. Click the top-left corner and the bottom-right corner of the M2D MAPS dot strip to define the region of interest.
|
||||
|
||||
5. **Sample dot colours** — for each of the 7 dot colours (turquoise, yellow, dark green, dark red, light green, light red, gray), click a representative dot in the screenshot. The wizard records the RGB value and sets an initial tolerance of 30.
|
||||
|
||||
6. **Set y-axis calibration points** — click on two price levels that appear as visible horizontal gridlines on the chart, then type the corresponding price for each. This calibrates the pixel-y → price mapping for SL/TP extraction.
|
||||
|
||||
7. **Select canary region** — drag a small rectangle over a stable, unchanging part of the chart border (title bar strip works well). This becomes the baseline for canary drift detection.
|
||||
|
||||
8. **Save** — the wizard writes `configs/YYYY-MM-DD-HHMM.toml` and updates `configs/current.txt`. Future runs load this config automatically.
|
||||
|
||||
### Verify calibration
|
||||
|
||||
```bash
|
||||
atm dryrun --dir samples/
|
||||
```
|
||||
|
||||
Review the dry-run output. Every sample should classify to the expected dot colour. If misclassifications appear, re-run the calibration wizard or adjust tolerances manually in the TOML file.
|
||||
|
||||
---
|
||||
|
||||
## Per-session operating checklist
|
||||
|
||||
Before each trading window (NY open 16:30 RO, NY close 21:00 RO):
|
||||
|
||||
- [ ] TradeStation open on 3-minute DIA chart, window not minimised
|
||||
- [ ] Chart window is in the same position/size as when calibrated
|
||||
- [ ] TradeLocker open in browser, instrument US30 loaded, position sizing ready
|
||||
- [ ] Telegram / Discord notification channel visible on mobile or second screen
|
||||
- [ ] Run `atm canary-check` — confirm no drift alert before starting the bot
|
||||
- [ ] Start the monitor: `atm run`
|
||||
- [ ] After the session: `atm journal add` to record trade outcome (or leave `outcome=open` to fill later)
|
||||
- [ ] At week end: `atm report --week YYYY-WW` to review win rate and PnL in R
|
||||
|
||||
---
|
||||
|
||||
## DPI and multi-monitor notes
|
||||
|
||||
- **High-DPI displays:** Windows DPI scaling can shift pixel coordinates. Set TradeStation to "System (Enhanced)" DPI compatibility mode (right-click EXE → Properties → Compatibility → Change high DPI settings) OR set Python to DPI-unaware via `SetProcessDPIAware()` in the manifest. The calibration wizard and capture code both call `SetProcessDPIAware()` on start.
|
||||
|
||||
- **Multiple monitors:** `mss` captures the monitor that contains the target window. The ROI offsets in the config are relative to the window's own top-left, so moving the window between sessions (but not resizing) is usually safe. Moving to a different monitor with a different DPI **requires recalibration**.
|
||||
|
||||
- **Virtual desktops / remote desktop:** Screen capture via `mss` does not work through RDP (the window reports on-screen but the pixel data is black). Run the bot locally on the same physical machine as TradeStation.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Window not found
|
||||
|
||||
```
|
||||
WindowNotFoundError: No window matching 'DIA - 3 Min'
|
||||
```
|
||||
|
||||
**Causes and fixes:**
|
||||
|
||||
- TradeStation is minimised — restore it to a visible state.
|
||||
- The window title has changed — re-run `atm calibrate` and provide the exact current title string. Copy-paste from the title bar.
|
||||
- DPI scaling changed the reported title encoding — confirm the title in `pygetwindow.getWindowsWithTitle("")` output.
|
||||
|
||||
### Canary drift alert
|
||||
|
||||
```
|
||||
CanaryDriftAlert: phash distance 12 > threshold 8
|
||||
```
|
||||
|
||||
The chart layout has shifted (e.g., chart scroll, zoom change, indicator redraw). **Do not trade until this is resolved.**
|
||||
|
||||
1. Check TradeStation — scroll or zoom may have shifted the DOT ROI out of frame.
|
||||
2. Reset the chart to the calibrated state (same zoom/scroll as during calibration).
|
||||
3. If the layout change was intentional, re-run calibration.
|
||||
4. To suppress a single false alarm without recalibrating, run `atm canary-reset` which re-samples the canary region baseline from the current screenshot.
|
||||
|
||||
### Low confidence warnings
|
||||
|
||||
```
|
||||
LowConfidence: cycle 5 — best match 'gray' dist=0.27 (threshold 0.20)
|
||||
```
|
||||
|
||||
The sampled pixel is near the edge of a colour tolerance zone. Usually caused by:
|
||||
|
||||
- Screenshot timing during a dot colour transition (rare on 3-min chart).
|
||||
- Chart re-render artifact (scaling seam at ROI boundary).
|
||||
|
||||
If this persists for more than 3 consecutive cycles, an alert is sent automatically. Verify the dot strip is fully visible and not clipped by another window.
|
||||
|
||||
### Notification not received
|
||||
|
||||
1. Check `logs/audit.jsonl` for the last cycle — look for `"notification_sent": false` and the `reason` field.
|
||||
2. Verify webhook/token: `atm test-notify`.
|
||||
3. Check network connectivity from the Windows machine to Discord/Telegram endpoints.
|
||||
Reference in New Issue
Block a user