Commit Graph
48 Commits
Author SHA1 Message Date
matitos 9d6028fbbf Add the Williams %R strategy
CI/CD / backend (push) Successful in 9m58s
CI/CD / frontend (push) Successful in 9m32s
CI/CD / build (push) Successful in 30s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 34s
2026-09-26 18:44:00 +00:00
matitos d92f152f9b Add the Williams %R strategy
New williams_r indicator (in [-100, 0]) exposed as ctx.williams_r(period), and a
long-only mean-reversion strategy: enter when %R is at/below the oversold level,
exit when it reaches the overbought level, with an optional ATR stop. 11
strategies total. Adds indicator and strategy tests; smoke-tested on live
BTC/USDT 5m (backtest + parameter sweep).
2026-09-26 18:44:00 +00:00
matitos ef895b6b9c Aggregate the top status cards across strategies
CI/CD / backend (push) Successful in 9m59s
CI/CD / frontend (push) Successful in 9m32s
CI/CD / build (push) Successful in 20s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 1m8s
2026-09-22 23:11:19 +00:00
matitos 57dcfe7adb Aggregate the top status cards across strategies
With several strategies the header cards showed only the first one. Expose
day_pnl and drawdown_pct per strategy and add aggregateStatus() (frontend) so the
cards show the whole account: summed cash/equity/P&L/trades/positions, worst
drawdown, and any halt. Single-strategy runs are unchanged. Adds tests.
2026-09-22 23:11:18 +00:00
matitos 657c473e82 Merge the single and multi strategy panels into one
CI/CD / backend (push) Successful in 10m2s
CI/CD / frontend (push) Successful in 9m31s
CI/CD / build (push) Successful in 15s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 33s
2026-09-22 17:57:10 +00:00
matitos 50b22df948 Merge the single and multi strategy panels into one
The single "Strategy" panel and "Strategies (multi)" were redundant: the multi
panel with one row is exactly the single-strategy behaviour. Remove StrategyPanel
and make "Strategies" the one trading panel. Presets move into it (load adds a
row, per-row Save), and the header now reports "N strategies" when several run
instead of only the first. Deletes the obsolete component and its test; adds
preset tests to the multi-strategy suite.
2026-09-22 17:57:10 +00:00
matitos d4d864dc5c Observability: Prometheus metrics, log panel, runbook
CI/CD / backend (push) Successful in 9m56s
CI/CD / frontend (push) Successful in 9m31s
CI/CD / build (push) Successful in 19s
CI/CD / cleanup (push) Successful in 6s
CI/CD / deploy (push) Successful in 42s
2026-09-22 17:10:39 +00:00
matitos ac92dd5ac4 Observability: Prometheus metrics, log panel, runbook
- GET /api/metrics renders Prometheus text (equity, P&L, per-strategy
  equity/pnl/allocation/halted, info) with no client library.
- In-memory ring log handler (app/logs.py) exposed at GET /api/logs and a
  dashboard "Server logs" panel; Runtime mirrors bot events into the logger.
- docs/runbook.md covers deploys, the kill switch, resetting paper state and
  going live. Adds tests for metrics rendering and the log ring.
2026-09-22 17:10:38 +00:00
matitos c605a0f316 Add Supertrend and VWAP strategies plus a short-side example
CI/CD / backend (push) Successful in 5m49s
CI/CD / frontend (push) Successful in 5m19s
CI/CD / build (push) Successful in 14s
CI/CD / cleanup (push) Successful in 7s
CI/CD / deploy (push) Successful in 1m1s
2026-09-22 14:14:13 +00:00
matitos d1f66c95c4 Add Supertrend and VWAP strategies plus a short-side example
- New indicators: vwap (rolling/cumulative) and supertrend (line + direction),
  exposed on StrategyContext.
- New strategies: supertrend (flip-based, optional shorts), vwap_reversion
  (mean reversion below a rolling VWAP) and ema_cross_short (short-side
  example, mirroring the long EMA cross). 10 strategies total.
- Adds indicator and strategy tests; smoke-tested all three on live BTC/USDT
  5m data.
2026-09-22 14:14:12 +00:00
matitos c1a7fb9c6b Notification upgrades: lifecycle, configurable levels, summaries
CI/CD / backend (push) Successful in 6m14s
CI/CD / frontend (push) Successful in 5m7s
CI/CD / build (push) Successful in 18s
CI/CD / cleanup (push) Successful in 6s
CI/CD / deploy (push) Successful in 1m26s
2026-09-22 13:18:04 +00:00
matitos 2ca5032e7e Notification upgrades: lifecycle, configurable levels, summaries
- NOTIFY_LEVELS chooses which event levels are sent (default trade,error).
- NOTIFY_LIFECYCLE sends explicit start/stop messages; the kill switch always
  notifies at error level.
- SUMMARY_INTERVAL_MINUTES sends a periodic portfolio summary (equity, per
  strategy P&L, allocation, halted state) via a background task started with
  the run and stopped on stop/kill/shutdown.
- Wires the new vars plus the go-live vars through both compose files and the
  deploy workflow. Adds tests.
2026-09-22 13:18:02 +00:00
matitos ef3e6f346c Go-live gate: refuse unsafe live trading
CI/CD / backend (push) Successful in 6m9s
CI/CD / frontend (push) Successful in 5m14s
CI/CD / build (push) Successful in 22s
CI/CD / cleanup (push) Successful in 6s
CI/CD / deploy (push) Successful in 39s
2026-09-22 12:55:13 +00:00
matitos 0173e46cfb Go-live gate: refuse unsafe live trading
Setting MODE=live alone no longer starts trading. check_live_ready requires an
active risk limit, MAX_POSITION_PCT < 1.0, LIVE_CONFIRMATION exactly
"I UNDERSTAND THE RISK", a minimum balance, and exchange credentials. Enforced
in Runtime.start_many (both start paths) and surfaced at GET /api/live-check;
the dashboard shows a banner and blocks the start buttons. Adds tests.
2026-09-22 12:55:12 +00:00
matitos b60cddf13d Multi-strategy UI
CI/CD / backend (push) Successful in 7m12s
CI/CD / frontend (push) Successful in 5m8s
CI/CD / build (push) Successful in 18s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 38s
2026-09-22 11:59:21 +00:00
matitos ce2b11a803 Multi-strategy UI
Adds a "Strategies (multi)" panel: add/remove strategy rows (strategy, symbol,
timeframe, per-strategy params and weight), start all, stop all and kill all,
plus a per-strategy status table (allocation, equity, P&L, halted). Polls
/api/bot/status alongside the existing status. Includes component tests.
2026-09-22 11:59:21 +00:00
matitos 3229a0e2aa Multi-strategy engine with per-strategy capital allocation
CI/CD / frontend (push) Successful in 5m21s
CI/CD / backend (push) Successful in 5m21s
CI/CD / build (push) Successful in 13s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 49s
2026-09-21 20:10:28 +00:00
matitos 8b6cf8130c Multi-strategy engine with per-strategy capital allocation
Adds MultiStrategyManager: it runs several strategies concurrently, each with
its own TradingEngine seeded with starting_balance * allocation, so one
strategy's losses cannot eat into another's capital. Weights are normalised
across the run ([1,3] -> 25%/75%). Risk limits stay per strategy (each engine
owns a RiskManager).

New API: POST /api/bot/start-many and GET /api/bot/status. The existing
single-strategy endpoints delegate to the manager, so their behaviour is
unchanged. Adds manager tests (allocation, isolation, duplicate keys) and API
tests.
2026-09-21 20:10:28 +00:00
matitos e07536542f Show a loading state in the strategy dropdown
CI/CD / backend (push) Successful in 5m27s
CI/CD / frontend (push) Successful in 5m4s
CI/CD / build (push) Successful in 17s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 51s
2026-09-21 18:26:02 +00:00
matitos 5a8c7ecc58 Show a loading state in the strategy dropdown
While the strategy list is being fetched the dropdown now shows a disabled
"Loading strategies…" option instead of an empty select, and "No strategies
available" once loading finishes with no results. Applies to the strategy,
backtest and sweep panels via a loading prop. Adds tests.
2026-09-21 18:26:01 +00:00
matitos def86d7f56 Retry the strategy list and make collapse obvious
CI/CD / backend (push) Successful in 5m14s
CI/CD / frontend (push) Successful in 5m16s
CI/CD / build (push) Successful in 17s
CI/CD / cleanup (push) Successful in 4s
CI/CD / deploy (push) Successful in 50s
2026-09-21 17:11:18 +00:00
matitos b9c69c546c Retry the strategy list and make collapse obvious
- The strategy/preset lists were loaded once with failures swallowed, so a
  single failed first request left the strategy dropdown empty forever. They
  are now retried every 3s until populated.
- Clearer collapse affordance: hover highlight, a hide/show hint, and a
  tooltip; Backtest and Parameter sweep start collapsed so the strategy
  selector and status are immediately visible.
- Adds an integration test that the strategy dropdown is populated and the
  panel actually collapses.
2026-09-21 17:11:18 +00:00
matitos 9eddd66a82 Collapse the strategy, backtest and sweep panels
CI/CD / backend (push) Successful in 5m14s
CI/CD / frontend (push) Successful in 5m9s
CI/CD / build (push) Successful in 17s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 50s
2026-09-21 16:40:54 +00:00
matitos 1b44e456c6 Collapse the strategy, backtest and sweep panels
Adds a reusable CollapsiblePanel (chevron header, optional summary shown when
collapsed, state persisted in localStorage) and wraps the Strategy, Backtest
and Parameter sweep panels with it, so any single part of the dashboard can be
focused on quickly. Panels stay mounted (v-show) so their form/results state is
preserved across collapse. Includes component tests.
2026-09-21 16:40:48 +00:00
matitos fedcd07ffd Don't let a failing initial fetch block the socket/polling fallback
CI/CD / backend (push) Successful in 5m32s
CI/CD / frontend (push) Successful in 5m7s
CI/CD / build (push) Successful in 20s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 40s
2026-09-21 15:57:51 +00:00
matitos cf54ff8b45 Don't let a failing initial fetch block the socket/polling fallback
onMounted awaited the initial REST calls before setting up the socket and the
6s polling fallback, so any rejected request aborted the handler and left the
badge stuck on "connecting". Set up the socket and fallback first, make the
initial loads best-effort, and log [ws] connect/open/close for debugging.
2026-09-21 15:57:50 +00:00
matitos 7057a5999e Show client and server build versions in the footer
CI/CD / backend (push) Successful in 5m20s
CI/CD / frontend (push) Successful in 5m6s
CI/CD / build (push) Successful in 19s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 40s
2026-09-21 14:47:04 +00:00
matitos cc602423b9 Show client and server build versions in the footer
Adds a footer with the client build SHA and the server /api/version value, a
mismatch warning, and the socket error text, so it is unambiguous whether the
browser is running a stale bundle and why the live feed fell back to polling.
2026-09-21 14:47:03 +00:00
matitos 2b8f6bf385 Force-recreate containers on deploy and verify the served build
CI/CD / backend (push) Successful in 6m8s
CI/CD / frontend (push) Successful in 4m59s
CI/CD / build (push) Successful in 19s
CI/CD / cleanup (push) Successful in 7s
CI/CD / deploy (push) Successful in 1m31s
2026-09-21 12:12:29 +00:00
matitos c121a4190a Force-recreate containers on deploy and verify the served build
The frontend container was serving the very first build (498-byte index.html)
through every later deploy: `docker compose up -d` did not replace a
config-identical service. Deploy now uses `build --pull` and
`up --force-recreate`, the frontend image writes a .build-version marker, and
the workflow fails the deploy if the served marker != the commit SHA.
2026-09-21 12:12:28 +00:00
matitos 1428220210 Self-heal a stale cached bundle via a build version
CI/CD / frontend (push) Successful in 5m15s
CI/CD / backend (push) Successful in 5m26s
CI/CD / build (push) Successful in 39s
CI/CD / cleanup (push) Successful in 7s
CI/CD / deploy (push) Successful in 1m22s
2026-09-21 00:16:49 +00:00
matitos 7b97f010c9 Self-heal a stale cached bundle via a build version
Phones kept running old JS because their cached index.html pointed at an old
hashed asset. Both images now bake the commit SHA as BUILD_VERSION; the backend
exposes it at GET /api/version and the client reloads once with a cache-busting
query when its own baked version differs. Guarded by sessionStorage so it cannot
loop. /api/version is unauthenticated like /api/health.
2026-09-21 00:16:43 +00:00
matitos 7ad14449ce Never hang on connecting: time out the socket and fall back
CI/CD / backend (push) Successful in 5m53s
CI/CD / frontend (push) Successful in 5m11s
CI/CD / build (push) Successful in 21s
CI/CD / cleanup (push) Successful in 6s
CI/CD / deploy (push) Successful in 20s
2026-09-20 23:43:13 +00:00
matitos ed14019052 Never hang on "connecting": time out the socket and fall back
iOS Safari can leave a blocked wss:// upgrade hanging without firing
onclose/onerror, so the badge sat on "connecting". The socket now times out a
slow handshake after 5s, reports at most one failure per attempt, and the app
commits to polling after a 6s grace period if the socket never opens.
2026-09-20 23:43:12 +00:00
matitos 5af879bc2f Present REST polling as a normal live state
CI/CD / backend (push) Successful in 5m23s
CI/CD / frontend (push) Successful in 4m55s
CI/CD / build (push) Successful in 13s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 24s
2026-09-20 14:01:38 +00:00
matitos 8bb2836d7e Present REST polling as a normal live state
Some browsers (notably iOS Safari on an auth-gated page) abort the wss://
upgrade even though the server accepts it. Rather than showing a perpetual
"reconnecting", stop retrying after three failures, poll every 3s, and label
the badge "live (polling)" in green. The socket error is kept as a tooltip.
2026-09-20 13:47:42 +00:00
matitos 43831d31f6 Merge pull request: Fall back to REST polling when the WebSocket cannot connect
CI/CD / backend (push) Successful in 6m1s
CI/CD / frontend (push) Successful in 5m18s
CI/CD / build (push) Successful in 16s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 17s
2026-09-20 13:00:52 +00:00
matitos bf7eda3f6a Fall back to REST polling when the WebSocket cannot connect
CI/CD / backend (pull_request) Successful in 6m6s
CI/CD / frontend (pull_request) Successful in 5m15s
CI/CD / build (pull_request) Skipped
CI/CD / deploy (pull_request) Skipped
CI/CD / cleanup (pull_request) Skipped
On some mobile networks/browsers the wss:// upgrade is blocked even though the
page loads (the server side is verified working: a browser-style handshake gets
101). After three socket failures the header now shows "polling (5s)" instead
of a misleading perpetual "reconnecting", since the 5s REST poll keeps all data
correct. The socket error handler also surfaces the browser's message.
2026-09-20 12:48:10 +00:00
matitos 07c17fbd2c Merge pull request #7: Stop caching index.html and speed up socket reconnect
CI/CD / backend (push) Successful in 5m42s
CI/CD / frontend (push) Successful in 5m15s
CI/CD / build (push) Successful in 17s
CI/CD / cleanup (push) Successful in 4s
CI/CD / deploy (push) Successful in 16s
2026-09-20 00:10:52 +00:00
matitos c63753e592 Stop caching index.html and speed up socket reconnect
CI/CD / backend (pull_request) Successful in 5m41s
CI/CD / frontend (pull_request) Successful in 5m18s
CI/CD / build (pull_request) Skipped
CI/CD / deploy (pull_request) Skipped
CI/CD / cleanup (pull_request) Skipped
Phones offer no easy hard-refresh, so a cached index.html kept serving an old
bundle after a deploy (the live feed showed "reconnecting"). index.html and the
SPA catch-all now send Cache-Control: no-store, while hashed /assets stay
immutable. Also retry the first socket reconnect after 1s (was 2s) and surface
the close code in the header so a failure is actionable on a phone.
2026-09-19 23:52:54 +00:00
matitos 9dc00eba95 Add trailing stops and parameter sweeps
CI/CD / backend (pull_request) Successful in 6m6s
CI/CD / frontend (pull_request) Successful in 5m17s
CI/CD / build (pull_request) Skipped
CI/CD / deploy (pull_request) Skipped
CI/CD / cleanup (pull_request) Skipped
Trailing stops: strategies can pass trailing_stop_pct to enter_long/enter_short.
advance_trailing_stop in app/engine/portfolio.py ratchets the stop with the price
(up for longs, down for shorts) and never loosens; the engine persists the
ratcheted level and the backtester applies the same logic. Position gains a
trailing_stop_pct column (additive migration). momentum exposes it as a param.

Parameter sweeps: app/backtest/sweep.py runs a cartesian grid through the same
backtester and ranks by return minus max drawdown. POST /api/sweep plus a
dashboard Parameter sweep panel.
2026-09-19 23:04:20 +00:00
matitos 2a88f55689 Make the API token fully optional
CI/CD / backend (pull_request) Successful in 5m36s
CI/CD / frontend (pull_request) Successful in 5m12s
CI/CD / build (pull_request) Skipped
CI/CD / deploy (pull_request) Skipped
CI/CD / cleanup (pull_request) Skipped
The deploy job hard-failed without CRYPTO_API_TOKEN, and /api/ws (which skips
Basic auth) relied on that token. Drop the requirement: the app now works with
no token at all, matching the backend guard that was always a no-op when unset.
When a token is configured it still protects /api and /api/ws; when it is not,
/api/ws is as open as the rest of the API, which the Traefik Basic auth still
guards for everything else. Adds tests for the tokenless API and WebSocket.
2026-09-19 14:31:42 +00:00
matitos 386137c90e Add a friendly GET /api/ws response
CI/CD / backend (pull_request) Canceled after 0s
CI/CD / frontend (pull_request) Canceled after 0s
CI/CD / build (pull_request) Canceled after 0s
CI/CD / deploy (pull_request) Canceled after 0s
CI/CD / cleanup (pull_request) Canceled after 0s
A plain browser hit on the socket URL now returns a JSON hint instead of a
confusing 404/426. Companion to the Basic-auth bypass on /api/ws.
2026-09-19 13:41:55 +00:00
matitos d0b941e305 chore: trigger deploy after WS auth fix 2026-09-19 13:14:11 +00:00
matitos 3e19612cc0 Serve /api/ws without Basic auth so the live feed connects
CI/CD / backend (pull_request) Successful in 5m58s
CI/CD / frontend (pull_request) Successful in 5m3s
CI/CD / build (pull_request) Skipped
CI/CD / deploy (pull_request) Skipped
CI/CD / cleanup (pull_request) Skipped
Browsers don't reliably replay Basic-auth credentials on a WebSocket upgrade,
so the dashboard's live feed was stuck on "reconnecting" (only the 5s REST
poll worked). Give /api/ws a higher-priority Traefik router that skips Basic
auth; the backend still requires API_TOKEN, which nginx injects on the
handshake. The deploy now fails closed unless CRYPTO_API_TOKEN is set.

Also: split the nginx /api/ws block so upgrade headers are only set there, and
add reconnect backoff (2s -> 30s) so a failing socket stops hammering.
2026-09-19 12:52:06 +00:00
matitos c500fb7572 Bitcoin favicon, more strategies, default timeframe 5m
CI/CD / backend (pull_request) Successful in 5m21s
CI/CD / frontend (pull_request) Successful in 5m4s
CI/CD / build (pull_request) Skipped
CI/CD / deploy (pull_request) Skipped
CI/CD / cleanup (pull_request) Skipped
- Add an SVG Bitcoin favicon and link it in index.html.
- New indicators: macd() and roc().
- Five new strategies: macd_trend, bollinger_reversion, donchian_breakout,
  ema_cross, momentum (plus the existing sma_cross, rsi_reversion).
- Default TIMEFRAME is now 5m (config, .env.example, compose, workflow, UI).
2026-09-18 20:03:30 +00:00
matitos 03dfa369e5 Risk controls, alerts, API token, more exchanges, presets
CI/CD / backend (pull_request) Successful in 6m18s
CI/CD / frontend (pull_request) Successful in 4m55s
CI/CD / build (pull_request) Skipped
CI/CD / deploy (pull_request) Skipped
CI/CD / cleanup (pull_request) Skipped
- RiskManager halts + flattens on max daily loss / drawdown, caps position
  size and trades per day; adds a manual kill switch (POST /api/bot/kill).
- Telegram and webhook notifications on trades, errors and halts.
- Optional API bearer token on /api, injected server-side by the frontend
  nginx so the browser never sees it.
- Kraken and Coinbase market data (public); Coinbase live broker. Live on an
  unsupported exchange now errors instead of silently falling back to paper.
- Strategy presets backed by the StrategyConfig table (CRUD API + UI).
- Idempotent additive-column migration so existing SQLite databases upgrade in
  place (fixes the new strategy_configs.name column).
2026-09-18 19:26:29 +00:00
matitos 9c3bee87ac Crypto trading bot: engine, brokers, backtester, dashboard, deploy
CI/CD / backend (push) Successful in 5m18s
CI/CD / frontend (push) Successful in 5m2s
CI/CD / build (push) Successful in 34s
CI/CD / cleanup (push) Successful in 6s
CI/CD / deploy (push) Successful in 22s
FastAPI backend with a single-strategy async engine, paper and Binance
brokers, pure-python indicators, a backtester that shares the engine's
portfolio math, and a Vue dashboard with a live WebSocket feed. Adds the
Gitea Actions CI/CD workflow that deploys to Traefik via docker_default.
2026-09-18 17:02:33 +00:00