This workspace now contains two independent bot paths:
mt5_signal_bot.py: MT5 EUR/USD signal botpocket_signal_bot/: PocketOption hybrid signal bot (paper+demo)
The PocketOption bot is designed around:
- EMA + RSI signal engine (
CALL/PUT/NO_TRADE) - Risk controls (daily stops, max losses, max trades/day, min payout)
- Hybrid adapters:
- Unofficial API adapter (primary)
- Browser adapter fallback
- Structured event logs with timing fields
pocket_signal_bot/config.pypocket_signal_bot/strategy.pypocket_signal_bot/risk.pypocket_signal_bot/paper_simulator.pypocket_signal_bot/adapters/api_adapter.pypocket_signal_bot/adapters/browser_adapter.pypocket_signal_bot/runner.pypocket_signal_bot/logger.py
pip install -r requirements.txtIf using browser fallback, also install browser runtime:
python -m playwright install chromium- Set in
.env:PO_HEADLESS=falseandPO_BROWSER_STARTUP_WAIT_SEC=15(or higher on slow PCs). - Run
python -m pocket_signal_bot.runner. A Chromium window opens on the quick-trading URL. - Log in if you see a login page; wait until the live quote is visible.
- In normal Chrome on the same page: F12 → Elements → select tool → click the price number → right‑click element → Copy → Copy selector.
- Put that string in
.envasPO_PRICE_SELECTOR=...(use|between multiple selectors to try in order). - Run the bot again. If API still fails, browser candles will work once the selector matches.
The bot no longer exits the whole process when browser price read fails once; it logs data_error and retries on the next poll.
If the chart price is drawn on a canvas (no numeric <span>), keep PO_USE_WS_QUOTES=true (default). The browser adapter listens to the page WebSocket (e.g. update_quotes) and extracts the last price for PO_SYMBOL without needing PO_PRICE_SELECTOR.
Copy the sample and edit:
copy .env.example .envpocket_signal_bot/config.py loads .env automatically when python-dotenv is installed.
Set environment variables before running (or put them in .env):
PO_SESSION-> session token from PocketOption web auth flowPO_UID-> your account uidPO_IS_DEMO=truePO_MODE=paper|demo|live(live = real money; requiresPO_LIVE_CONFIRMED=true)- Optional symbol/time controls:
PO_SYMBOL=EURUSD_otcPO_TIMEFRAME_SEC=60PO_EXPIRY_SEC=60
Paper mode (safe):
set PO_MODE=paper
python -m pocket_signal_bot.runnerDemo mode (PocketOption demo account):
set PO_MODE=demo
set PO_SESSION=your_session
set PO_UID=your_uid
python -m pocket_signal_bot.runnerLive mode (real money — same code path as demo, but api_is_demo=false and real cabinet URL for browser):
set PO_MODE=live
set PO_LIVE_CONFIRMED=true
set PO_SESSION=your_real_session
set PO_UID=your_real_uid
set PO_IS_DEMO=false
python -m pocket_signal_bot.runnerThe bot refuses to start PO_MODE=live unless PO_LIVE_CONFIRMED=true.
Event output goes to the terminal when PO_CONSOLE_LOG=true (no log files are written).
Each run stores trades in data/trading_history.json. After every settled trade (if PO_CHARTS_AUTO=true), PNG charts are written to data/charts/:
| File | Content |
|---|---|
latest_pnl.png |
Cumulative PnL + per-trade bars (current session) |
latest_winrate.png |
Win rate over trade number |
compare_setups.png |
Compare 15/15, 30/30, 60/60, M5/M3 sessions |
dashboard.png |
All sessions’ PnL curves overlaid |
A/B test workflow — change Pocket Option + .env for each setup, run demo, stop bot (Ctrl+C), repeat:
# Example: 15s candle + 15s bet
PO_TIMEFRAME_SEC=15
PO_EXPIRY_SEC=15Regenerate charts anytime:
python -m pocket_signal_bot.chartsOptional: PO_EXPERIMENT_LABEL=15/15 overrides the auto label used in comparison charts.
- At least 200+ demo trades logged
- Positive expectancy with realistic payout conditions
- No recurring adapter disconnect loop
- Latency and failover behavior verified in logs
- Risk limits tested (daily stop, max losses, max trades)
No strategy guarantees profit. Treat this as research/automation infrastructure and validate on demo first.