Trading Engine
Overview
Milo's trading engine executes swaps on Solana through Jupiter, the leading DEX aggregator. Every trade — whether placed manually or triggered by Milo's auto-trader — is routed through Jupiter to get the best price across all Solana liquidity sources.
There is no centralized order book. No custodial exchange. Your tokens stay in your wallet until the moment a swap settles on-chain.
For the full endpoint reference, see the Partner API docs.
Architecture
┌──────────┐ ┌──────────────┐ ┌──────────┐ ┌──────────┐
│ Partner │────►│ Milo Order │────►│ Jupiter │────►│ Solana │
│ API │ │ Engine │ │ Routing │ │ Chain │
└──────────┘ └──────────────┘ └──────────┘ └──────────┘
│ │
┌─────┴──────┐ │
│ Turnkey │◄─────────────────────────────┘
│ Signer │ transaction confirmation
└────────────┘You create an order via the Partner API (or Milo's auto-trader creates one)
The engine monitors trigger conditions (price thresholds)
When the trigger fires, the engine requests a quote from Jupiter
Jupiter finds the best route across all Solana DEXs and AMMs
The transaction is signed via Turnkey (non-custodial — your keys, your wallet)
The signed transaction is submitted to Solana for on-chain settlement
Order status updates to
fulfilledwith the transaction signature
Fully Decentralized
Milo never takes custody of your funds.
Non-custodial wallets — Each user gets a Solana wallet powered by Turnkey. The signing key belongs to you, not Milo. Milo receives delegated permission to execute trades on your behalf.
On-chain settlement — Every swap is a Solana transaction. You can verify it on any block explorer.
Jupiter routing — Trades are routed through Jupiter's aggregator, which splits across Raydium, Orca, Meteora, Phoenix, and dozens of other Solana DEXs to find the best price.
No counterparty risk — Milo doesn't hold your tokens, doesn't run an order book, and doesn't match trades internally. Every trade settles peer-to-pool on Solana.
Order Types
All orders are created through POST /api/v1/wallets/{walletId}/orders. The order type is determined by the combination of type, trigger, and amount in the payload. See the Partner API — Orders section for the full endpoint reference.
Market Order
Execute immediately at the best available price. Uses the trigger { "operator": "gte", "value": 0 } — a condition that is always true.
Limit Order
Execute when the token reaches a specific price.
Buy when price drops to $0.50:
Sell when price rises to $2.00:
Stop-Loss
Sell when the price drops by a percentage. Uses a relative trigger with the drop operator.
Sells 100% of the position if the price drops 15%.
Take-Profit
Sell when the price rises by a percentage. Uses a relative trigger with the rise operator.
Sells 50% of the position when the price rises 30%.
TP/SL Ladders
Create a buy order with multiple take-profit and stop-loss levels attached. Pass takeProfits and stopLosses arrays alongside the main order payload — the engine creates them as draft dependant sell orders linked to the parent.
This example:
Sells 25% at +20% profit
Sells 25% at +50% profit
Sells 50% at +100% profit
Sells 100% if price drops 15% (stop-loss)
Trailing Stop
DCA (Dollar-Cost Averaging)
TWAP (Time-Weighted Average Price)
Triggers
Every order has a trigger that defines when it executes.
Absolute
Fire when the token price hits a specific USD value.
gte
Price >= value
Market order (value: 0), sell above target
lte
Price <= value
Limit buy at dip
Relative
Fire when the token price moves by a percentage from a reference point.
rise
Price rose by X%
Take-profit
drop
Price dropped by X% (max 100)
Stop-loss
Amount Types
absolute
amount
Raw token amount (base units)
Buy, Sell
absolute_usd
amount
USD equivalent
Buy, Sell
relative
percentage
% of current position (1-100)
Sell only
Execution Options
Fine-tune how your order executes on-chain. All fields are optional — sensible defaults are applied.
slippagePercentage
number
3%
Max allowable slippage (0-100)
priorityFee
number
auto
Priority fee in SOL lamports for faster block inclusion
platformFeeBps
number
90-100 bps
Milo platform fee in basis points
Higher slippage tolerance increases fill probability for volatile tokens. Higher priority fees get your transaction included faster by Solana validators.
Order Lifecycle
draft
Created but not monitoring. TP/SL dependants start here.
active
Engine is monitoring the trigger condition
fulfilling
Trigger fired, swap is executing on-chain
fulfilled
Swap confirmed on Solana
paused
Temporarily stopped — resume with the activate endpoint
error
Execution failed after retries
archived
Soft-deleted by user
You can manage order state through the Partner API:
Pause —
POST /api/v1/users/{userId}/orders/{orderId}/pauseResume —
POST /api/v1/users/{userId}/orders/{orderId}/activateDelete —
DELETE /api/v1/users/{userId}/orders/{orderId}List —
GET /api/v1/users/{userId}/ordersDetails —
GET /api/v1/users/{userId}/orders/{orderId}
See Partner API — Orders for full details.
Error Handling
When an order fails, the executionSummary field contains the reason. Common errors:
no_route_found
Jupiter couldn't find a swap path — token may have no liquidity
not_enough_token_balance
Insufficient tokens in wallet to fill the sell
not_enough_sol
Not enough SOL to cover transaction fees
slippage_too_low
Price moved beyond your slippage tolerance during execution
swap_not_supported
Token pair cannot be swapped
network_error
Solana RPC or network issue
Failed orders are retried with exponential backoff (up to 5 attempts). If all retries fail, the order moves to error status.
Roadmap
Market orders
Live
Limit orders (absolute price triggers)
Live
Stop-loss (relative % drop)
Live
Take-profit (relative % rise)
Live
TP/SL ladders (multi-level dependants)
Live
Order pause / resume / delete
Live
Position close / close-all
Live
Trailing stop
Coming soon
DCA (dollar-cost averaging)
Coming soon
TWAP (time-weighted average price)
Coming soon
Conditional chains (if X then Y)
Planned
Last updated