konar est. 2026
CASE STUDY · 06
ALGORITHMIC TRADING · DISTRIBUTION PLATFORM  ·  2025 — NOW  ·  SOLE ENGINEER

CompoundFox: live algo trading with a public, defensible performance record.

Autowealth is a SaaS platform that distributes algorithmic trading strategies to followers across Bybit, Binance, and Hyperliquid. CompoundFox is the flagship strategy, live since November 2025 with a logic revision shipped in February 2026 and a risk-per-trade increase currently rolling out. Live performance is published at stats.autowealth.trade: equity curve, Sharpe, deposit-adjusted drawdown, and TWR calculated in real time from actual Bybit trade history. No backtest, no screenshot. Per-community ECS containers, an on-chain fee Splitter, and an AUM circuit breaker make the platform multi-tenant and production-grade.

STATUS
live
stats.autowealth.trade · public dashboard · daily
AUM SNAPSHOTS
288/day
every 5 min · circuit breaker after 3 failures
EXCHANGES
3
bybit · binance · hyperliquid
ON-CHAIN BILLING
on-chain
solidity splitter · bsc + arbitrum · hd wallets
DEPLOYMENT
aws ecs
cdk · one container per community id
SURFACES
4
web dashboard · mobile · telegram bot · mini-app

Most algo strategies are sold on backtests or cherry-picked screenshots. Autowealth publishes live performance: full equity curve, Sharpe, drawdown, and TWR pulled from real Bybit trade history and updated daily on a public dashboard. Anyone can check it before committing capital. CompoundFox is the flagship strategy. Autowealth is the platform behind it: copy trading across three exchanges, per-community deployment, and on-chain fee invoicing.

  ┌─ Turborepo monorepo
  │
  ├── apps/
  │   ├── backend              [ Bun · TypeScript · Drizzle · PostgreSQL ]
  │   │      Bybit API integration · AUM snapshotting · performance calculation
  │   │      on-chain fee invoicing · position deduplication
  │   │      notification router (Expo push + Telegram fallback)
  │   │      community auto-provisioning (HD wallet + splitter approval worker)
  │   │
  │   ├── telegram-bot         [ Telegraf · TypeScript ]
  │   │      strategy signals · performance alerts · follower management
  │   │
  │   ├── telegram-mini-app    [ Next.js 16 · React 19 · Recharts ]
  │   │      in-Telegram dashboard · deep-linked from bot commands
  │   │
  │   ├── performance-page     [ Next.js · React Query ]
  │   │      live equity curve · Sharpe · deposit-adjusted drawdown · TWR
  │   │      startBalanceReliable flag: hides metrics it can't defend
  │   │
  │   └── mobile               [ Expo · React Native · Clerk · MMKV ]
  │          strategy overview · performance charts · push notifications
  │          App Store build via EAS
  │
  ├── packages/
  │   ├── database             [ Drizzle · PostgreSQL · 7 migrations ]
  │   ├── wallet-service       [ ethers v6 · HD derivation · async-mutex ]
  │   │      gas station per chain · refill below threshold
  │   │      deterministic community wallets via keccak256(id + secret)
  │   └── sweep-service        [ Solidity Splitter · Hardhat · BSC + Arbitrum ]
  │          atomic distribution to provider / platform / referral
  │
  └── cdk/                     [ TypeScript · AWS CDK ]
         ExchangeBotStack per community · shared VPC/cluster via CF exports
         512MB / 0.25 CPU per bot · VPS Docker alternative
01  ·  DECISION
Deposit-adjusted drawdown with 3-day attribution

Raw AUM drawdown inflates whenever a deposit lands: AUM spikes, then the strategy looks like it immediately lost capital. The performance engine walks a 3-day attribution window to match transaction amounts to AUM jumps before computing peak-to-trough. The window exists because of a production failure: late-day deposits landing after the daily snapshot produced phantom -100% drawdowns until the attribution logic was added.

02  ·  DECISION
Reliability tiers: hide numbers that can't be defended

The performance API returns a startBalanceReliable flag when there is no AUM snapshot before the first trade. When the flag is false, the UI hides annualized return and average monthly return entirely. The dashboard doesn't fill in a guess; it shows fewer numbers. Accounts that connected mid-strategy get a smaller metrics set until a full pre-trade snapshot exists.

03  ·  DECISION
AUM circuit breaker isolates dead API keys

A snapshot job that retries every failing account wastes cycles on expired keys and slows down active ones. The AUM snapshot worker tracks consecutive failures per account in a Map<string, number>, skips accounts with 3+ consecutive failures, and resets the count hourly. An isRunning guard prevents concurrent execution without a lock library. One expired API key has no effect on the snapshot cadence of live accounts. The job runs every 5 minutes (288 snapshots/day per active account).

04  ·  DECISION
Position deduplication via 8-decimal-place PnL fingerprint

Not all exchange APIs return stable order IDs across paginated history endpoints. Bybit's position history in particular doesn't guarantee idempotent IDs. The closed-position worker uses a 5-field composite key: exchange + account UID + symbol + side + timestamp + PnL formatted to 8 decimal places via formatToPrecision8(), matching the decimal(18,8) DB column. The fingerprint check in positionExists() runs before every write. Positions are fetched in 7-day chunks with 100ms rate-limit delays to stay within Bybit's pagination limits.

05  ·  DECISION
Per-community ECS containers via CDK

Each trading community gets its own exchange-bot container, not a shared bot with multi-tenant config. The CDK stack (ExchangeBotStack) takes a communityId as a prop and deploys into a shared ECS cluster imported via CloudFormation cross-stack exports (InfrastructureClusterArn, InfrastructureVPCId). Adding a community is a deploy-exchange-bot.sh COMMUNITY_ID TOKEN call. For operators who want lower AWS costs, a Docker VPS alternative runs the same container at 512MB / 0.25 CPU with the same isolation guarantee per community ID.

06  ·  DECISION
On-chain fee settlement via Solidity Splitter

Trading fees invoiced to followers go into a Hardhat-tested Solidity Splitter contract on BSC and Arbitrum that distributes to provider, platform, and referral wallets atomically. Each trader's wallet is derived deterministically via BSCWalletService.deriveTraderWallet(traderId, communityId), so wallets don't need manual provisioning per follower. The pipeline runs fully automated: position close triggers invoice, invoice triggers on-chain sweep. Coverage data shows 40+ contract statements exercised in tests.

07  ·  DECISION
Multi-chain gas station with mutex-serialized refills

On-chain operations stall when a wallet runs out of native gas. The wallet-service package runs a gas station per chain (BSC and Arbitrum): it monitors every operational wallet, refills below threshold (0.0002 BNB / 0.0001 ETH) from a dedicated funding wallet, and uses async-mutex to serialize refills so concurrent operations never trigger duplicate transfers. Two modes: withGas() waits for the refill to confirm before the dependent transaction; withGasHybrid() releases the caller as soon as gas lands on-chain. If the funding wallet itself is depleted, callers get a clean error instead of a silent stall.

08  ·  DECISION
Zero-touch community wallet provisioning

Creating a community is one POST /communities call. The backend derives a deterministic HD branch from keccak256(communityId + WALLET_DERIVATION_SECRET) mod 2^31, persists the address, and queues splitter approval. A background worker then approves the Splitter contract on BSC and Arbitrum for that wallet, gated by an AUM threshold so dormant communities don't burn gas. The splitter_approved and arb_splitter_approved flags in community_bsc_wallets make the worker idempotent. No operator ever touches a key, and the derivation is deterministic, so the address is reproducible from communityId alone if state is ever lost.

09  ·  DECISION
Dual-channel notifications for security-critical events

The notification router fans events out by user preference (Expo push, Telegram, or both), but security-critical events (API key changes, withdrawals, delinquency) always go to both channels regardless of preference. Push tokens flagged as invalid by Expo get deactivated automatically on the next send failure, so dead devices don't accumulate and concurrent sends don't waste retry budget. Critical alerts never depend on a single transport.

COMPONENT STACK ROLE
Trading backend bun · typescript · drizzle · postgresql · bybit api sole
Performance engine typescript · sharpe · twr · sortino · calmar sole
Performance page next.js · react query · live equity curve · reliability tiers sole
Telegram bot telegraf · typescript · strategy signals · follower management sole
Mobile app expo · react native · clerk · mmkv · wagmi-charts · app store via eas sole
Telegram mini-app next.js 16 · react 19 · recharts · bot deep links sole
Wallet service ethers v6 · async-mutex · gas station · deterministic hd derivation sole
Sweep service solidity splitter · hardhat · bsc + arbitrum sole
Notification router expo push sdk · telegram bot api · dual-channel for critical events sole
AWS infrastructure typescript · aws cdk · ecs · cloudwatch · rds sole

CompoundFox is running live on Bybit with performance published at stats.autowealth.trade. Equity curve, Sharpe, deposit-adjusted drawdown, and TWR are calculated from real position history by a metrics engine built from scratch. The numbers on the dashboard are either defensible or hidden: the startBalanceReliable flag suppresses annualized return on accounts without a pre-trade AUM snapshot. Autowealth as a platform handles multi-tenant copy trading across three exchanges, per-community ECS deployment via CDK, on-chain fee settlement with a multi-chain gas station keeping operational wallets funded, zero-touch HD wallet provisioning when a community is created, and a notification router that fans security-critical events to push and Telegram in parallel. Four user surfaces ship from one monorepo: web dashboard, Expo mobile app, Telegram bot, and an in-Telegram mini-app.