Helix / Documentation
v3 spec v3.0 · MVP V1.1 · last updated 2026-05-15

Build a safe, signal-driven crypto trading bot.

Helix Auto-Trader receives signals from TradingView via webhook, validates them through a hard risk layer, executes on Binance or Kraken (one active per deploy), and reports every state change to Telegram. This documentation covers the architecture, integration points, deployment steps, and every safety guarantee the bot ships with.

FastAPI · Python 3.11+ CCXT async SQLite · WAL Docker Testnet default Dubai region
§ 01 — Quickstart

From clone to first signal in 5 minutes.

Helix ships as a single Python service. Default settings are safe — no real funds are at risk until you explicitly opt in. Always run 7+ days in testnet (or Paper for Kraken) before flipping to live.

bash
# 1. Clone
git clone git@github.com:aminbassam/Auto-Trader.git
cd Auto-Trader

# 2. Configure
cp .env.example .env
$EDITOR .env          # set ACTIVE_EXCHANGE, API keys, Telegram, secret

# 3. Boot (testnet by default)
docker-compose up -d

# 4. Verify
curl http://localhost:8000/health | jq
# → "status": "ok", "active_exchange": "binance", "trading_mode": "testnet"

# 5. Point TradingView at your endpoint
#    Webhook URL:  https://your-vps/webhook
#    Header:       X-Webhook-Secret: $WEBHOOK_SECRET
Safe defaults. TRADING_MODE is testnet by default. Risk per trade is capped at 1% of equity, daily loss at 3%, and the circuit breaker is armed. You must opt in to live mode.
§ 02 — Overview

A signal executor — not a strategy engine.

Indicators live in TradingView (Pine Script v5). Helix's only job is to receive validated signals, gate them through risk, and execute safely. That separation keeps the bot simple and the strategy iterable.

01

Risk before alpha

Daily loss cap, drawdown kill switch, consecutive-loss pause. The bot halts itself before it can blow up.

02

Defaults to safe

Boots in testnet. Switching to live requires confirmation. Withdraw permission on API keys is disabled and verified.

03

No orphan positions

State reconciler compares DB vs exchange on every boot. Mismatch → halt + Telegram alert. Humans decide.

At a glance

Repositoryaminbassam/Auto-Trader
Pair (MVP)BTC/USDT (CCXT-normalised)
Timeframe5-minute candles
ExchangesBinance · Kraken (single-active per deploy)
HostingVPS · Dubai or Frankfurt · Docker
Target uptime99.9%
Signal → fill< 2s
Max drawdown target< 15% (kill switch)
§ 03 — Architecture

Layered, async, and exchange-agnostic.

The factory pattern is the key v1.1 change: the rest of the codebase never references Binance or Kraken directly — only the abstract ExchangeClient interface. Adding Bybit or OKX in v2 means writing one new class.

data flow
TradingView Pine Script
   │  (alert fires)
   ▼
HTTPS POST → FastAPI /webhook    [X-Webhook-Secret header]
   │  (Pydantic parse)
   ▼
SignalHandler.dedup(signal_id, 60s window)
   
   ▼
RiskManager.validate(signal)     [7 pre-trade checks]
   │  (pass)
   ▼
ExchangeFactory.get_client()     [reads ACTIVE_EXCHANGE]
   
   ▼
ExchangeClient.place_market_order(symbol, side, qty)
ExchangeClient.place_stop_loss()  [OCO or conditional close]
   
   ▼
SQLite trade log  +  Telegram notify

Abstract interface

Every exchange client implements the same surface. Callers code against the interface — never the concrete class.

python
class AbstractExchangeClient(ABC):
    @abstractmethod async def connect(): ...
    @abstractmethod async def disconnect(): ...
    @abstractmethod async def get_balance(): ...
    @abstractmethod async def get_ticker(symbol): ...
    @abstractmethod async def place_market_order(symbol, side, qty): ...
    @abstractmethod async def place_oco_order(symbol, side, qty, stop_price): ...
    @abstractmethod async def get_open_positions(): ...
    @abstractmethod async def cancel_order(order_id): ...

class BinanceClient(AbstractExchangeClient):  # spot · OCO · testnet
class KrakenClient(AbstractExchangeClient):   # spot · conditional close · paper
§ 04 — Trading flow

Every signal travels the same path.

Any check can veto. Rejected signals are logged with a reason and a Telegram alert. Successful trades are persisted, summarised, and tracked toward the daily loss budget.

  1. Webhook arrives
    POST /webhook with X-Webhook-Secret header. Rate-limited at 10/min.
  2. Payload validates
    Pydantic checks signal, symbol, price, signal_id. Malformed → 422.
  3. Deduplication
    If the same signal_id was seen in the last 60s, drop silently and log signal_deduplicated.
  4. Pre-trade risk checks
    Seven gates run. Failure → reject with reason, Telegram alert, no order placed.
  5. Position sizing
    size = (balance × risk_pct) ÷ stop_pct. Below the exchange's min notional → reject.
  6. Exchange dispatch
    Factory returns the BinanceClient or KrakenClient based on ACTIVE_EXCHANGE.
  7. Market order placed
    With retry × 3 (exponential backoff) on transient network errors.
  8. Stop loss attached
    OCO (Binance) or conditional close (Kraken). Exchange-side — survives bot crashes.
  9. Persist + notify
    SQLite WAL write, Telegram message, daily P&L counter incremented.
One position at a time. Max concurrent positions is locked at 1 in MVP. Additional signals are rejected with reason position_already_open while a trade is live. Pyramiding ships in v2.
§ 05 — Strategy & signals

EMA cross with RSI filter, on 5m BTC/USDT.

The default strategy is a clean trend-following signal: EMA(9/21) crossover, gated by an RSI(14) momentum filter. The bot does not compute indicators — they all run in TradingView Pine v5 and arrive pre-computed.

BUY signal
EMA 9 crosses above EMA 21
AND
RSI(14) > 50
action: open LONG
SELL signal
EMA 9 crosses below EMA 21
AND
RSI(14) < 50
action: close position
SourceTradingView Pine Script v5
Timeframe5m (must match the alert's chart)
PairBTC/USDT
IndicatorsEMA(9), EMA(21), RSI(14)
Take profitDeferred for MVP — exit via reverse signal or stop loss. v2
§ 06 — Webhook payload

Paste this into your TradingView alert.

TradingView fires alerts at the bot's webhook endpoint. The alert's "Message" field must contain this exact JSON shape, with placeholders for live values.

application/json
{
  "signal":    "BUY",
  "symbol":    "BTC/USDT",
  "price":     {{close}},
  "timestamp": {{timenow}},
  "strategy":  "ema_crossover",
  "signal_id": {{strategy.order.id}}
}
FieldRequiredNotes
signalrequired"BUY" or "SELL"
symbolrequiredCCXT-normalised, e.g. "BTC/USDT"
pricerequiredLogged for audit; bot uses live exchange price for sizing.
timestampoptionalTradingView server time at alert fire.
strategyoptionalFree-form identifier — logged for analytics.
signal_idrequiredCritical for dedup. Must be unique per signal — bot drops same-id within 60s.
Required header. Every request must include X-Webhook-Secret: $WEBHOOK_SECRET. Missing or wrong → 401. Rotate the secret periodically.
§ 07 — Order execution

Fixed-fraction sizing, market orders, exchange-side stops.

Position size is calculated from account equity and stop-loss distance. Market orders for MVP — limit orders ship in v2. Stop losses live on the exchange, not in the bot, so they survive crashes.

Position sizing

formula
position_size = (account_balance × risk_pct) ÷ stop_loss_distance_pct

# Example with $10,000 equity, 1% risk, 2% stop:
position_size = (10000 × 0.01) ÷ 0.02
              = $5,000 notional0.078 BTC  at $64,210

# Risk per trade (USD)
$ at risk = account_balance × risk_pct = $100
Order typeMARKET
Position modeone-way
Max concurrent1 position (pyramiding in v2)
Risk per trade1.0% of equity · env RISK_PER_TRADE_PCT
Stop loss2.0% · env STOP_LOSS_PCT
Min notional$10 — queried from exchange at startup, cached
Retry policy3 retries · exponential backoff on transient errors
Stops survive crashes. Binance OCO and Kraken conditional-close orders are placed on the exchange itself — if the bot dies between order entry and exit, the exchange still enforces your stop.
§ 08 — Exchanges

Single-active per deploy.

Pick one exchange per deployment via the ACTIVE_EXCHANGE env var. The factory loads the right client at boot — only that venue's credentials need to be set. Switching exchanges is one env edit + restart.

Binance
Binance.com (international) · ACTIVE_EXCHANGE=binance
CCXT idbinance
Native symbolBTCUSDT
Maker / Taker0.10% / 0.10%
Rate limit1200 weight/min · 10 ord/s
Stop lossOCO (native)
Testnettestnet.binance.vision
QuirkNative BTCUSDT, CCXT normalises
Kraken
Kraken Spot · ACTIVE_EXCHANGE=kraken
CCXT idkraken
Native symbolXXBTZUSD
Maker / Taker0.16% / 0.26%
Rate limit15 calls / 3s · decays 1/3s
Stop lossConditional close
Testnetnone — use paper mode
QuirkUses XBT, CCXT maps to BTC

Kraken-specific notes

  • No public testnet API. The bot ships with a paper mode that simulates fills against live order-book prices. Same risk-management behaviour as live — only the orders are never sent.
  • Conditional close orders. Kraken's equivalent to Binance OCO. Attached to the opening order via the close param.
  • Stricter rate limits. CCXT's enableRateLimit is on by default, with extra delay between calls.
  • XBT vs BTC. Kraken uses XBT for Bitcoin internally; CCXT normalises everything to BTC. You always write BTC/USDT.
  • Nonce-based auth. Handled automatically by CCXT.
§ 09 — Risk management

Seven gates between a signal and an order.

Risk has veto power over every trade. If any check fails, the signal is rejected with a reason and a Telegram alert. The circuit breaker is armed by default and trips on daily loss limit OR max consecutive losses.

1
Max concurrent positions
Reject if a position is already open (MVP cap = 1).
2
Daily loss limit
Reject if cumulative P&L since 00:00 UTC ≤ −3%. Trips circuit breaker.
3
Duplicate signal
Reject if signal_id seen in last 60s.
4
Min account balance
Reject if balance < $50.
5
Active exchange reachable
Health-check ACTIVE_EXCHANGE before every order.
6
Min notional ($10)
Position size below exchange minimum → reject. Varies per venue.
7
Pair available
Reject if symbol not in active exchange's catalogue.

Circuit-breaker thresholds

Risk per trade1.0%
Max daily loss3.0% — halts until 00:00 UTC reset
Max drawdown15.0% — permanent halt, requires manual restart
Max consecutive losses5 → auto-pause
Auto-resumeOFF — require manual /resume via Telegram
Kill-switch math. At 1% risk per trade and a 2% stop, you could lose ~50 consecutive trades before hitting the 15% drawdown kill switch. Robust against noise-driven false signals — but never run it without monitoring.
§ 10 — Telegram alerts

All bot ↔ human communication through Telegram.

Outbound events fire on every state change. Inbound /commands let you query and control the bot from your phone. Only the configured TELEGRAM_CHAT_ID can issue commands — all others are silently ignored.

Event templates

trade_opened
🟢 OPENED: BUY BTC/USDT @ 64210.50 | Size: 0.0084 | SL: 62926.30
trade_closed
🔴 CLOSED: BTC/USDT @ 64055.40 | P&L: +$28.97 (+0.55%)
stop_loss_triggered
⛔ STOP LOSS: BTC/USDT @ 63812.50 | Loss: −$101.82
daily_limit_hit
🚨 DAILY LOSS LIMIT HIT: −3.02% | Trading halted
signal_rejected
⚠️ SIGNAL REJECTED: Position already open
error
❌ ERROR: ccxt.NetworkError — connection reset
daily_summary
📊 DAILY SUMMARY: Trades: 7 | P&L: +$132.18 | WR: 86%
bot_startup
🤖 BOT STARTED · Mode: TESTNET · Exchange: Binance

Commands

/status   Bot state, open positions, daily P&L
/balance   Current account balance from exchange
/today   Today's trade summary
/stop   Emergency halt — closes positions, stops trading
/resume   Resume trading after manual halt
Only the configured TELEGRAM_CHAT_ID can execute commands. All others are silently ignored.

Daily summary scheduled at 23:59 UTC.

§ 11 — API endpoints

Three HTTP endpoints.

/webhook is the only externally-facing route. /health is consumed by Docker and uptime monitors. /status is internal.

POST /webhook auth: X-Webhook-Secret header
Receives TradingView alerts. Returns 200 with trade_id, or 4xx with rejection reason. Rate-limited at 10/min.
GET /health auth: none (or basic token)
Health check for Docker and monitors. Returns active_exchange, exchange_connected, open_positions, daily_pnl_pct, trading_mode.
GET /status auth: internal only
Detailed bot status — consumed by the Telegram /status command.

GET /health response

200 OK · application/json
{
  "status":             "ok",            // ok | degraded | halted
  "uptime_seconds":     184302,
  "active_exchange":    "binance",       // binance | kraken
  "exchange_connected": true,
  "last_signal_time":   "2026-05-15T08:14:32Z",
  "open_positions":     1,
  "daily_pnl_pct":      1.13,
  "trading_mode":       "testnet"        // testnet | live | paper
}
§ 12 — Database schema

Three SQLite tables. WAL mode.

SQLAlchemy 2.0 async ORM. The schema migrates to Postgres in v2 — same shape, different backend.

trades

idINTEGER PK AUTOINC
signal_idTEXT UNIQUE NOT NULL
exchangeTEXT NOT NULL · binance | kraken v3
symbolTEXT NOT NULL
sideTEXT NOT NULL · BUY | SELL
entry_priceREAL
exit_priceREAL
quantityREAL
stop_loss_priceREAL
statusTEXT · open | closed | stopped_out | cancelled
pnlREAL
pnl_pctREAL
exchange_order_idTEXT
opened_atTIMESTAMP
closed_atTIMESTAMP
close_reasonTEXT · signal | stop_loss | manual | circuit_breaker

signals

idINTEGER PK AUTOINC
signal_idTEXT NOT NULL
payloadTEXT · raw JSON
actionTEXT · accepted | rejected | deduplicated
rejection_reasonTEXT
received_atTIMESTAMP

daily_stats

dateTEXT PRIMARY KEY
trades_countINTEGER
winsINTEGER
lossesINTEGER
total_pnlREAL
total_pnl_pctREAL
max_drawdown_pctREAL
daily_loss_limit_hitBOOLEAN
§ 13 — Environment variables

All config from .env.

Loaded via pydantic-settings. Never hardcoded. Never logged. .env is gitignored; .env.example is committed as a template.

Required core

VariableRequiredDescription
ACTIVE_EXCHANGErequiredbinance | kraken — picks ExchangeClient at boot
TRADING_MODErequiredtestnet | live | paper — paper required for Kraken
TELEGRAM_BOT_TOKENrequiredFrom @BotFather
TELEGRAM_CHAT_IDrequiredYour personal chat ID
WEBHOOK_SECRETrequiredRandom string passed in X-Webhook-Secret

Exchange credentials (only the active venue is read)

BINANCE_API_KEYif binanceTrade-only permissions; never Withdraw.
BINANCE_API_SECRETif binanceTreat as password.
KRAKEN_API_KEYif krakenFrom Kraken API settings.
KRAKEN_API_SECRETif krakenBase64-encoded private key.

Optional tuning (defaults applied)

TRADING_PAIRoptionaldefault: BTC/USDT
LOG_LEVELoptionalDEBUG | INFO | WARNING · default: INFO
RISK_PER_TRADE_PCToptionaldefault: 1.0
MAX_DAILY_LOSS_PCToptionaldefault: 3.0
MAX_DRAWDOWN_PCToptionaldefault: 15.0
STOP_LOSS_PCToptionaldefault: 2.0
MAX_CONSECUTIVE_LOSSESoptionaldefault: 5
HOSToptionaldefault: 0.0.0.0
PORToptionaldefault: 8000
§ 14 — Tech stack

Pinned, async-first Python.

Every exchange call is awaited; every webhook is non-blocking. Dependencies are pinned in requirements.txt.

LanguagePython 3.11+
FrameworkFastAPI
Async serverUvicorn
Exchange libraryccxt (async mode)
DatabaseSQLite with WAL mode
ORMSQLAlchemy 2.0 (async)
ValidationPydantic v2
Configpydantic-settings (.env loader)
Alertspython-telegram-bot (async)
Rate limitingslowapi
DeploymentDocker · docker-compose
HostingVPS · Hetzner / DigitalOcean / Vultr · Frankfurt or Dubai
Charts & signalsTradingView Pine Script v5
§ 15 — Folder structure

Strict module boundaries.

Risk has veto power. Exchange clients are interchangeable behind the factory. Tests live alongside the modules they protect.

tree
Auto-Trader/
├── main.py                  — FastAPI app entry · Uvicorn runner
├── requirements.txt         — Pinned deps
├── Dockerfile
├── docker-compose.yml
├── .env.example             — Template (committed)
├── .env                     — Secrets (gitignored)
├── .gitignore
├── README.md
│
├── app/
│   ├── config.py            — Pydantic settings, loads .env
│   ├── models.py            — Trade, Signal, DailyStats
│   └── database.py          — Async engine, WAL init
│
├── app/api/
│   ├── webhook.py           — POST /webhook · dedup · validation
│   └── health.py            — GET /health
│
├── app/strategy/
│   ├── signal_handler.py    — Parse · validate · deduplicate
│   └── signal_models.py     — Pydantic payload models
│
├── app/execution/           — ⭐ factory pattern (v3)
│   ├── base_client.py       — AbstractExchangeClient ABC
│   ├── exchange_factory.py  — Reads ACTIVE_EXCHANGE → client
│   ├── binance_client.py    — OCO orders · testnet support
│   ├── kraken_client.py     — Conditional close · paper mode
│   └── order_manager.py     — Exchange-agnostic dispatch
│
├── app/risk/                — ⭐ VETO power
│   ├── risk_manager.py      — Pre-trade checks · sizing
│   └── circuit_breaker.py   — Daily loss · drawdown · cooldown
│
├── app/alerts/
│   ├── telegram_bot.py      — Notifications · /commands
│   └── templates.py
│
├── app/recovery/
│   └── state_reconciler.py  — DB ↔ exchange on boot
│
├── tests/
│   ├── test_risk_manager.py
│   ├── test_exchange_factory.py
│   ├── test_binance_client.py
│   ├── test_kraken_client.py
│   ├── test_signal_handler.py
│   ├── test_webhook.py
│   └── conftest.py          — Mock exchanges (both)
│
└── logs/                    — Runtime logs (gitignored)
§ 16 — Security

Withdraw is OFF. Always.

API keys never touch code or the database. The bot's exchange key must have Withdraw permission disabled — verified on startup. Anything less and the bot refuses to boot.

Encrypted secrets

Loaded from .env via pydantic-settings · never hardcoded · never appears in logs.

IP whitelisting

Configure in your exchange's API settings. Restrict to the VPS IP only.

Withdraw disabled

The bot probes permissions on save. If Withdraw is enabled, the bot refuses to start.

Webhook secret

Every /webhook request must include X-Webhook-Secret. Missing or wrong → 401. Rotate periodically.

Rate limiting

SlowAPI · /webhook 10/min · /health 30/min.

Audit log

All sensitive config changes appended to /var/log/audit.log with actor + timestamp.

§ 17 — State recovery

Zero orphan tolerance.

On every boot, the reconciler compares the SQLite trade log with the exchange's open positions. Orphans halt the bot and notify — never auto-closed. Humans decide.

  1. Read ACTIVE_EXCHANGE from config
    Instantiate that client. No multi-exchange ambiguity at boot.
  2. Query open positions
    Via get_open_positions() on the active exchange.
  3. Cross-reference with DB
    Compare exchange-side state with the last known DB snapshot.
  4. If orphan found → halt + alert
    Log a WARNING, fire a Telegram alert, stop trading. The user decides whether to keep, exit, or reconcile.
  5. Load daily P&L from DB
    So the daily-loss limit picks up where it left off — restarts don't reset the budget.
  6. Verify pair availability
    Confirm the trading pair is still listed on the active exchange before resuming.
The bot will not auto-close orphan positions. Auto-closing on an inconsistent state is how bots accidentally liquidate accounts. The conservative default is to halt, alert, and wait for a human.
§ 18 — Deployment

Docker on a VPS near the exchange.

Recommended hosting: Hetzner, DigitalOcean, or Vultr in Frankfurt or Dubai. Lower latency to Binance Frankfurt = faster signal-to-fill.

docker-compose

docker-compose.yml
services:
  bot:
    build: .
    env_file: .env
    ports: ["8000:8000"]
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout:  5s
      retries:  3
    volumes:
      - ./data:/app/data        # SQLite + logs
      - ./logs:/app/logs

Going live

  1. Run 7+ consecutive days in testnet (or paper for Kraken) with the strategy you intend to use live.
  2. Verify Telegram alerts fire on every state change.
  3. Confirm circuit breakers are armed — try forcing a daily loss in testnet to watch them trip.
  4. Set TRADING_MODE=live in .env. The bot will prompt you to type I-UNDERSTAND-THE-RISK to confirm.
  5. Restart. The bot will report live mode in /health and the Telegram startup message.
Live mode is destructive. Real funds, real losses. Start with the smallest meaningful balance, watch for a week, then scale.
§ 19 — Roadmap

Three-phase delivery plan.

v1 ships reliable execution. v2 adds professional features (multi-pair, futures, dashboards, monitoring). v3 evolves into an AI quant platform.

V1

Reliable Execution

Weeks 1–3 · ● NOW
  • Single pair BTC/USDT
  • TradingView webhook → FastAPI
  • Binance + Kraken via CCXT (single-active)
  • Exchange factory pattern
  • OCO / conditional close stop loss
  • Risk manager with pre-trade checks
  • Daily loss circuit breaker
  • Telegram alerts + /commands
  • State recovery on restart
  • Health check endpoint
  • Docker deployment · testnet default
V2

Professional Trading System

Months 2–3
  • Multi-pair support
  • Futures / perpetual trading
  • Trailing stop loss
  • Take profit (fixed + trailing)
  • Web dashboard (FastAPI + React)
  • PostgreSQL migration
  • Trade history + analytics
  • Multi-exchange (Bybit, OKX)
  • Grafana + Prometheus monitoring
  • Auto-restart with systemd
V3

AI Quant Platform

Months 4–6+
  • Market regime detection (ML)
  • Sentiment analysis (news + social)
  • AI strategy optimization
  • Reinforcement learning signals
  • Adaptive position sizing
  • Portfolio balancing
  • Order book analytics
  • Volatility engine
  • Backtesting cluster
§ 20 — Changelog

Spec revisions.

Newest first. Backwards-incompatible changes are flagged.

spec v3.0 · MVP V1.1 2026-05-15 01:30 UTC latest

Added Kraken as a second supported exchange.

  • Exchange factory pattern (AbstractExchangeClient → BinanceClient, KrakenClient)
  • Single-active per deploy via ACTIVE_EXCHANGE env var
  • Kraken specifics: conditional close, paper-trade mode (no public testnet), stricter rate limit
  • 3 new tasks (T15–T17 factory split) — task count: 34 → 37
  • New env vars: ACTIVE_EXCHANGE, KRAKEN_API_KEY, KRAKEN_API_SECRET, TRADING_PAIR
  • trades table gains an exchange column
  • /health returns active_exchange + trading_mode (testnet | live | paper)
spec v2.0 2026-05-15 00:00 UTC

Project spec finalized. 34-task plan defined.

  • Framework: Flask → FastAPI (async-native)
  • Max daily loss: 5% → 3%
  • Stop loss expanded: boolean → full OCO config
  • Deferred Bybit / OKX / BingX to v2 roadmap
  • Added testnet default, signal dedup (60s), state recovery, /health, rate limiting
  • Added 8 clarifying questions for build kickoff
§ 21 — FAQ

Common questions.

Can I run Binance and Kraken at the same time?
Not in v1.1. The MVP supports one active exchange per deploy. To run both, deploy two instances with different ACTIVE_EXCHANGE values. True multi-exchange in a single process ships in v2.
Why is there no public testnet for Kraken?
Kraken doesn't offer one. The bot ships with a paper trading mode that simulates fills against live Kraken market data — same risk-management behaviour, but no orders are actually placed. Use TRADING_MODE=paper on Kraken.
What happens if the bot crashes mid-trade?
Stop losses are placed on the exchange (OCO on Binance, conditional close on Kraken) — they survive bot crashes, restarts, and network loss. On restart, the state reconciler compares DB vs exchange and halts on orphans for manual review.
Does the bot calculate indicators?
No. All indicator logic lives in TradingView Pine Script v5. The bot only receives validated signals via webhook and executes them. This keeps the bot simple and lets you iterate on strategy in TradingView's chart UI.
How is position size calculated?
Fixed-fraction. position_size = (account_balance × risk_pct) ÷ stop_loss_distance_pct. With $10,000, 1% risk, and a 2% stop, that's $5,000 notional — about 0.078 BTC at $64,210. The actual at-risk amount per trade is just $100 (1% of equity).
Can I add take-profit targets?
Take profit is deferred for MVP. v1 exits on reverse signal or stop loss only. Fixed and trailing TP arrive in v2.
What does the circuit breaker actually do?
When the daily loss limit (−3%) is hit, or 5 consecutive losses occur, the bot halts all trading and fires a Telegram alert. Auto-resume is off by default — you must run /resume in Telegram to start trading again. The drawdown kill switch (−15%) is permanent: it requires a manual restart.
How do I know my API key permissions are safe?
On startup, the bot probes the key and refuses to boot if Withdraw is enabled. The Dashboard's Settings → Exchange tab also shows a live audit of permissions (Spot trading ON, Read ON, Withdraw OFF, Futures OFF).
Where is the bot hosted in production?
Recommended: Dubai or Frankfurt VPS (Hetzner, DigitalOcean, or Vultr). Closer to the exchange = lower signal-to-fill latency. Target is < 2s end-to-end.
How do I report a bug or contribute?
Open an issue on the GitHub repo: github.com/aminbassam/Auto-Trader. Commits follow the type: short description format (feat, fix, refactor, test, docs, chore, risk).

Ready to deploy?

Spin up the live dashboard to see every screen in action, or jump straight to the repository.

Open dashboard View on GitHub