Commit Graph
27 Commits
Author SHA1 Message Date
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 6df44520fa Merge pull request 'Add trailing stops and parameter sweeps' (#6) from feat/trailing-stops-sweep into main
CI/CD / backend (push) Successful in 5m51s
CI/CD / frontend (push) Successful in 5m4s
CI/CD / build (push) Successful in 18s
CI/CD / cleanup (push) Successful in 4s
CI/CD / deploy (push) Successful in 31s
2026-09-20 01:18:51 +02: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 d80e7b155e Merge pull request 'Make the API token fully optional' (#5) from fix/optional-api-token into main
CI/CD / backend (push) Successful in 5m30s
CI/CD / frontend (push) Successful in 5m5s
CI/CD / build (push) Successful in 25s
CI/CD / cleanup (push) Successful in 5s
CI/CD / deploy (push) Successful in 34s
2026-09-19 16:35:35 +02: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 ba7a69c1ce Merge pull request 'Add a friendly GET /api/ws response' (#4) from chore/retrigger-deploy into main
CI/CD / backend (push) Successful in 5m24s
CI/CD / frontend (push) Successful in 5m14s
CI/CD / build (push) Successful in 54s
CI/CD / cleanup (push) Successful in 7s
CI/CD / deploy (push) Failing after 12s
2026-09-19 15:58:16 +02: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 c9ee3e3aef Merge pull request 'Serve /api/ws without Basic auth so the live feed connects' (#3) from fix/websocket-basic-auth into main
CI/CD / backend (push) Canceled after 0s
CI/CD / frontend (push) Canceled after 0s
CI/CD / build (push) Canceled after 0s
CI/CD / deploy (push) Canceled after 0s
CI/CD / cleanup (push) Canceled after 0s
2026-09-19 15:11:16 +02: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 97fbd5901e Merge pull request 'Bitcoin favicon, more strategies, default timeframe 5m' (#2) from feat/strategies-favicon-5m into main
CI/CD / backend (push) Successful in 5m23s
CI/CD / frontend (push) Successful in 5m3s
CI/CD / build (push) Successful in 16s
CI/CD / cleanup (push) Successful in 4s
CI/CD / deploy (push) Successful in 23s
2026-09-18 22:14:39 +02: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 186a6949ee Merge pull request 'Risk controls, alerts, API token, more exchanges, presets' (#1) from feat/risk-notify-exchanges-presets into main
CI/CD / backend (push) Successful in 5m16s
CI/CD / frontend (push) Successful in 4m58s
CI/CD / build (push) Successful in 23s
CI/CD / cleanup (push) Successful in 4s
CI/CD / deploy (push) Successful in 23s
2026-09-18 21:39:05 +02: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
matitos 98028248c2 Initial commit 2026-09-18 19:01:49 +02:00