Documentation Index
Fetch the complete documentation index at: https://docs.renesis.fi/llms.txt
Use this file to discover all available pages before exploring further.
Algorithms API
The Algorithms API provides execution algorithms that break large orders into smaller slices to minimize market impact and achieve better average prices.
Key Features
- Time-sliced execution: TWAP and TimePace spread orders evenly over time
- Multi-level orders: Ladder places limit orders at multiple price levels
- Aggressive fills: Sweep uses IOC orders for immediate execution
- Spread trading: Two-leg execution for basis/arb trades with risk management
- Anti-gaming: Randomization of size and timing to avoid detection
- Limit price guardrails: Won’t execute beyond your price limit
- TCA metrics: Arrival price, VWAP, slippage tracking
- Full lifecycle: Start, pause, resume, cancel algorithms
Algorithm Types
| Algorithm | Status | Description |
|---|
twap | Available | Time-Weighted Average Price - executes evenly over time |
ladder | Available | Places limit orders at multiple price levels |
sweep | Available | Aggressive fill - hits all available liquidity with IOC orders |
timepace | Available | Fixed quantity per interval, no catch-up |
spread | Available | Two-leg spread/basis trade execution |
POST /oems/algorithms/start
Start a new execution algorithm.
Request Body (JSON)
| Parameter | Type | Required | Description |
|---|
algorithm_type | string | Yes | Algorithm type: twap, ladder, sweep, timepace, spread |
symbol | string | Yes | Trading pair (e.g., “BTC/USDC”) |
side | string | Yes | buy or sell |
quantity | number | Yes | Total quantity to execute |
exchange_account_ids | array | Yes | List of exchange account IDs |
limit_price | number | No | Won’t execute beyond this price |
params | object | Yes | Algorithm-specific parameters (see below) |
TWAP Parameters
| Parameter | Type | Default | Description |
|---|
duration_seconds | int | required | Total execution time in seconds |
interval_seconds | int | required | Time between slices |
aggression | string | "neutral" | passive, neutral, aggressive, auto |
randomize_size | bool | true | +/-20% size randomization |
randomize_timing | bool | true | +/-30% timing randomization |
catch_up_enabled | bool | true | Catch up if falling behind |
max_catch_up_pct | int | 200 | Max catch-up as % of interval size |
Request Example
curl -X POST "http://localhost:8082/oems/algorithms/start" \
-H "Content-Type: application/json" \
-d '{
"algorithm_type": "twap",
"symbol": "BTC/USDC",
"side": "buy",
"quantity": 0.001,
"exchange_account_ids": ["binance-001"],
"params": {
"duration_seconds": 60,
"interval_seconds": 10,
"aggression": "neutral"
}
}'
Response Example
{
"isError": false,
"message": "Algorithm started successfully.",
"statusCode": 200,
"data": {
"order_id": "893dc6ba-3b13-407a-a06c-41dcdd39d1ee",
"algorithm_type": "twap",
"symbol": "BTC/USDC",
"side": "buy",
"total_quantity": 0.001,
"status": "RUNNING",
"arrival_price": 78836.00,
"arrival_spread_bps": 10,
"estimated_completion": "2026-02-02T23:42:58.862514",
"progress": {
"filled_quantity": 0.0,
"remaining_quantity": 0.001,
"fill_percentage": 0.0,
"vwap": null,
"child_orders_filled": 0,
"total_fees": 0.0
},
"state": {
"current_interval": 1,
"total_intervals": 6,
"base_quantity_per_interval": 0.000166
}
}
}
Best Practices
- Use
passive aggression for large orders to minimize market impact
- Enable
catch_up_enabled to ensure full quantity is executed
- Set
limit_price as a safety guardrail
- Longer durations reduce market impact but increase timing risk
Ladder Parameters
| Parameter | Type | Default | Description |
|---|
num_levels | int | required | Number of price levels (1-20) |
price_spacing_bps | number | 10 | Spacing between levels in basis points |
size_distribution | string | "equal" | equal, linear, exponential |
start_price | number | market mid | Starting price for the ladder |
end_price | number | - | End price (overrides spacing if set) |
cancel_on_fill_pct | number | - | Cancel remaining levels when X% filled |
cancel_on_price_move_bps | number | - | Cancel all if mid-price moves X bps |
reprice_on_move_bps | number | - | Recalculate levels if mid moves X bps |
Size Distributions
| Distribution | Behavior | Use Case |
|---|
equal | Same quantity at each level | Standard ladder |
linear | More quantity at better prices | Favor fills near mid-price |
exponential | Much more at best prices | Aggressive near-touch accumulation |
Request Example
curl -X POST "http://localhost:8082/oems/algorithms/start" \
-H "Content-Type: application/json" \
-d '{
"algorithm_type": "ladder",
"symbol": "BTC/USDT",
"side": "buy",
"quantity": 0.01,
"exchange_account_ids": ["binance-sandbox-001"],
"params": {
"num_levels": 5,
"price_spacing_bps": 20,
"size_distribution": "linear",
"cancel_on_fill_pct": 80,
"reprice_on_move_bps": 50
}
}'
Response Example
{
"isError": false,
"message": "Algorithm started successfully.",
"statusCode": 200,
"data": {
"order_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"algorithm_type": "ladder",
"symbol": "BTC/USDT",
"side": "buy",
"total_quantity": 0.01,
"status": "RUNNING",
"arrival_price": 95000.00,
"state": {
"levels": [
{"level_number": 1, "price": 95000.00, "quantity": 0.0033, "status": "active"},
{"level_number": 2, "price": 94981.00, "quantity": 0.0027, "status": "active"},
{"level_number": 3, "price": 94962.00, "quantity": 0.0020, "status": "active"},
{"level_number": 4, "price": 94943.00, "quantity": 0.0013, "status": "active"},
{"level_number": 5, "price": 94924.00, "quantity": 0.0007, "status": "active"}
],
"total_filled": 0.0,
"active_orders": 5,
"initial_mid_price": 95000.00
}
}
}
Best Practices
- Use
linear distribution to concentrate size near market price
- Set
cancel_on_fill_pct to 70-80% to capture most fills without overfilling
- Use
reprice_on_move_bps for volatile markets to keep levels relevant
- Keep
num_levels at 3-10 for most use cases
Sweep Parameters
| Parameter | Type | Default | Description |
|---|
urgency | string | "aggressive" | Aggression level for pricing |
limit_price | number | - | Maximum price for buys, minimum for sells |
use_sor | bool | true | Route across multiple venues via SOR |
max_slippage_bps | number | 50 | Max slippage from arrival price before blocking |
max_retries | int | 3 | Number of retry rounds if not fully filled |
Request Example
curl -X POST "http://localhost:8082/oems/algorithms/start" \
-H "Content-Type: application/json" \
-d '{
"algorithm_type": "sweep",
"symbol": "BTC/USDT",
"side": "buy",
"quantity": 0.01,
"exchange_account_ids": ["binance-sandbox-001"],
"params": {
"max_slippage_bps": 30,
"max_retries": 5
}
}'
Response Example
{
"isError": false,
"message": "Algorithm started successfully.",
"statusCode": 200,
"data": {
"order_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"algorithm_type": "sweep",
"symbol": "BTC/USDT",
"side": "buy",
"total_quantity": 0.01,
"status": "RUNNING",
"arrival_price": 95000.00,
"state": {
"sweep_round": 0,
"total_rounds": 6,
"remaining_after_round": 0.0,
"arrival_price": 95000.00
}
}
}
Best Practices
- Sweep is the simplest algorithm - use it when you need immediate fills
- All slices are IOC (Immediate-or-Cancel) - unfilled portions cancel immediately
- Set
max_slippage_bps to protect against adverse price movement
- Use
max_retries > 0 for illiquid markets where one pass may not fill
TimePace Parameters
| Parameter | Type | Default | Description |
|---|
quantity_per_interval | number | required | Fixed quantity per interval |
interval_seconds | int | required | Seconds between intervals |
limit_price | number | - | Skip interval if price is beyond limit |
aggression | string | "neutral" | passive, neutral, aggressive |
randomize_size | bool | true | Randomize quantity per interval |
randomize_size_pct | number | 10 | Randomization percentage |
Key Difference from TWAP: TimePace has no catch-up logic. If an interval is skipped (due to limit price breach), that quantity is lost. TWAP catches up on missed quantity.
Request Example
curl -X POST "http://localhost:8082/oems/algorithms/start" \
-H "Content-Type: application/json" \
-d '{
"algorithm_type": "timepace",
"symbol": "BTC/USDT",
"side": "buy",
"quantity": 0.01,
"exchange_account_ids": ["binance-sandbox-001"],
"params": {
"quantity_per_interval": 0.002,
"interval_seconds": 30,
"aggression": "neutral",
"randomize_size": true
}
}'
Response Example
{
"isError": false,
"message": "Algorithm started successfully.",
"statusCode": 200,
"data": {
"order_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"algorithm_type": "timepace",
"symbol": "BTC/USDT",
"side": "buy",
"total_quantity": 0.01,
"status": "RUNNING",
"arrival_price": 95000.00,
"state": {
"current_interval": 1,
"intervals_completed": 0,
"intervals_skipped": 0,
"quantity_per_interval_actual": 0.002
}
}
}
Best Practices
- Use TimePace when you want predictable, fixed-size executions
- Set
limit_price to skip intervals during adverse price moves
- Unlike TWAP, skipped intervals do NOT accumulate - choose TimePace for strict pacing
- Runs until total_quantity is filled or the algorithm is cancelled
Spread Parameters
| Parameter | Type | Default | Description |
|---|
anchor_symbol | string | required | Primary leg symbol |
contra_symbol | string | required | Hedge leg symbol |
anchor_exchange_account_ids | array | required | Exchange accounts for anchor leg |
contra_exchange_account_ids | array | required | Exchange accounts for contra leg |
risk_quantity | number | required | Max unhedged exposure |
lead_mode | string | "anchor" | Which leg posts first: anchor or contra |
aggression | string | "neutral" | Aggression for posting leg |
sweep_trigger_mode | string | "immediate" | Hedge trigger: immediate, disabled, threshold |
sweep_threshold_pct | number | 0 | Spread % threshold for threshold mode |
pause_offset_pct | number | - | Pause if spread exceeds this % |
reprice_increment_bps | number | 10 | Reprice increment in bps |
spread_offset_pct | number | 0 | Target spread offset |
Sweep Trigger Modes
| Mode | Behavior |
|---|
immediate | Hedge with IOC order as soon as lead leg fills |
disabled | Hedge with limit order (passive) |
threshold | Use IOC only when spread exceeds sweep_threshold_pct |
Request Example (BTC spot vs perp basis trade)
curl -X POST "http://localhost:8082/oems/algorithms/start" \
-H "Content-Type: application/json" \
-d '{
"algorithm_type": "spread",
"symbol": "BTC/USDT",
"side": "buy",
"quantity": 0.01,
"exchange_account_ids": ["binance-sandbox-001"],
"params": {
"anchor_symbol": "BTC/USDT",
"contra_symbol": "BTC/USDT:USDT",
"anchor_exchange_account_ids": ["binance-sandbox-001"],
"contra_exchange_account_ids": ["bybit-001"],
"risk_quantity": 0.005,
"lead_mode": "anchor",
"aggression": "neutral",
"sweep_trigger_mode": "immediate",
"pause_offset_pct": 2.0
}
}'
Response Example
{
"isError": false,
"message": "Algorithm started successfully.",
"statusCode": 200,
"data": {
"order_id": "d4e5f6a7-b8c9-0123-def0-234567890123",
"algorithm_type": "spread",
"symbol": "BTC/USDT",
"side": "buy",
"total_quantity": 0.01,
"status": "RUNNING",
"arrival_price": 95000.00,
"state": {
"anchor_filled": 0.0,
"contra_filled": 0.0,
"current_spread_pct": 0.05,
"unhedged_quantity": 0.0,
"is_spread_paused": false
}
}
}
Best Practices
- Set
risk_quantity conservatively - it limits max unhedged exposure
- Use
immediate sweep trigger for tight risk management
- Set
pause_offset_pct to stop trading when the spread widens beyond tolerance
- The algorithm completes when BOTH legs are fully filled
- Use different exchange accounts for each leg for cross-venue basis trades
Aggression Levels
Applies to TWAP, Ladder, TimePace, and Spread algorithms.
| Level | Description | Use Case |
|---|
passive | 25% into spread | Minimize market impact, patient execution |
neutral | Midpoint | Balanced approach |
aggressive | 75% into spread | Prioritize fills over price |
auto | Dynamic (TWAP only) | Adjusts based on fill progress |
GET /oems/algorithms/
Get the status and progress of an algorithm.
Path Parameters
| Parameter | Type | Description |
|---|
order_id | string | Algorithm order ID |
Request Example
curl "http://localhost:8082/oems/algorithms/893dc6ba-3b13-407a-a06c-41dcdd39d1ee"
Response Example
{
"isError": false,
"message": "Success",
"statusCode": 200,
"data": {
"order_id": "893dc6ba-3b13-407a-a06c-41dcdd39d1ee",
"algorithm_type": "twap",
"symbol": "BTC/USDC",
"side": "buy",
"total_quantity": 0.001,
"status": "RUNNING",
"arrival_price": 78836.00,
"progress": {
"filled_quantity": 0.0006,
"remaining_quantity": 0.0004,
"fill_percentage": 60.0,
"vwap": 78842.50,
"child_orders_filled": 3,
"child_orders_failed": 0,
"total_fees": 0.000045
},
"state": {
"current_interval": 4,
"total_intervals": 6,
"behind_by": 0.0
},
"recent_slices": [
{
"slice_id": "abc123",
"status": "filled",
"quantity": 0.0002,
"fill_price": 78840.00,
"arrival_price": 78836.00,
"slippage_bps": 0.51
}
]
}
}
POST /oems/algorithms//pause
Pause a running algorithm. Stops generating new slices but keeps open orders.
Request Example
curl -X POST "http://localhost:8082/oems/algorithms/893dc6ba-3b13-407a-a06c-41dcdd39d1ee/pause"
Response Example
{
"isError": false,
"message": "Algorithm paused successfully.",
"statusCode": 200,
"data": {
"order_id": "893dc6ba-3b13-407a-a06c-41dcdd39d1ee",
"status": "PAUSED",
"paused_at": "2026-02-02T23:45:00Z"
}
}
POST /oems/algorithms//resume
Resume a paused algorithm.
Request Example
curl -X POST "http://localhost:8082/oems/algorithms/893dc6ba-3b13-407a-a06c-41dcdd39d1ee/resume"
Response Example
{
"isError": false,
"message": "Algorithm resumed successfully.",
"statusCode": 200,
"data": {
"order_id": "893dc6ba-3b13-407a-a06c-41dcdd39d1ee",
"status": "RUNNING"
}
}
POST /oems/algorithms//cancel
Cancel an algorithm. Cancels all open child orders.
Request Example
curl -X POST "http://localhost:8082/oems/algorithms/893dc6ba-3b13-407a-a06c-41dcdd39d1ee/cancel"
Response Example
{
"isError": false,
"message": "Algorithm cancelled successfully.",
"statusCode": 200,
"data": {
"order_id": "893dc6ba-3b13-407a-a06c-41dcdd39d1ee",
"status": "CANCELLED",
"cancelled_at": "2026-02-02T23:47:00Z",
"child_orders_cancelled": 2,
"final_progress": {
"filled_quantity": 0.0008,
"fill_percentage": 80.0,
"vwap": 78855.46,
"total_fees": 0.000058
}
}
}
GET /oems/algorithms//slices
Get all child orders (slices) for an algorithm.
Request Example
curl "http://localhost:8082/oems/algorithms/893dc6ba-3b13-407a-a06c-41dcdd39d1ee/slices"
Response Example
{
"isError": false,
"message": "Success",
"statusCode": 200,
"data": {
"order_id": "893dc6ba-3b13-407a-a06c-41dcdd39d1ee",
"slices": [
{
"slice_id": "slice-001",
"interval_number": 1,
"status": "filled",
"quantity": 0.0002,
"filled_quantity": 0.0002,
"price": 78830.00,
"fill_price": 78832.50,
"arrival_price": 78836.00,
"slippage_bps": -0.44,
"fees": 0.000015,
"fee_currency": "BNB",
"submitted_at": "2026-02-02T23:42:10Z",
"filled_at": "2026-02-02T23:42:10Z",
"venue": "binance"
}
]
}
}
GET /oems/algorithms
List all algorithms.
Query Parameters
| Parameter | Type | Description |
|---|
status | string | Filter by status: RUNNING, PAUSED, COMPLETED, CANCELLED, FAILED |
algorithm_type | string | Filter by type: twap, ladder, sweep, timepace, spread |
symbol | string | Filter by trading pair |
side | string | Filter by buy or sell |
limit | int | Max results (default: 50, max: 200) |
offset | int | Pagination offset |
Request Example
# List all
curl "http://localhost:8082/oems/algorithms"
# List running only
curl "http://localhost:8082/oems/algorithms?status=RUNNING"
# List ladder algorithms
curl "http://localhost:8082/oems/algorithms?algorithm_type=ladder"
GET /oems/algorithms/by-status/
List algorithms by status.
Request Example
curl "http://localhost:8082/oems/algorithms/by-status/RUNNING"
curl "http://localhost:8082/oems/algorithms/by-status/COMPLETED"
GET /oems/algorithms/by-account/
List algorithms for a specific exchange account.
Request Example
curl "http://localhost:8082/oems/algorithms/by-account/binance-001"
Algorithm Status Lifecycle
PENDING -> RUNNING -> COMPLETED
|
PAUSED -> RUNNING (resume)
|
CANCELLED
|
FAILED
| Status | Description |
|---|
PENDING | Created but not started |
RUNNING | Actively executing slices |
PAUSED | Temporarily stopped by user |
COMPLETED | All quantity filled |
CANCELLED | Stopped by user |
FAILED | Error occurred |
TCA Metrics (Transaction Cost Analysis)
Each algorithm tracks execution quality metrics:
| Metric | Description |
|---|
arrival_price | Market mid-price when algorithm started |
vwap | Volume-weighted average fill price |
slippage_bps | Difference between arrival and fill price (basis points) |
fill_percentage | Percentage of order filled |
total_fees | Total trading fees incurred |
Calculating Implementation Shortfall
Implementation Shortfall = (VWAP - Arrival Price) / Arrival Price * 10000 bps
Positive = paid more than arrival (for buys), negative = got better price.
Error Handling
| Error | Cause | Resolution |
|---|
DAILY_LIMIT_EXCEEDED | Order would exceed daily limit | Reduce quantity or wait until tomorrow |
MIN_ORDER_SIZE | Slice below exchange minimum | Algorithm skips tiny slices automatically |
SYMBOL_NOT_PERMITTED | Account can’t trade this pair | Check exchange account permissions |
EXCHANGE_ERROR | Exchange rejected order | Check error message for details |
Daily Limit Behavior
When an algorithm hits the daily trading limit:
- Remaining slices are rejected
- Algorithm is paused automatically
- Check
/oems/execution/daily-limit for current limit status
Choosing an Algorithm
| Scenario | Algorithm | Why |
|---|
| Minimize market impact over time | twap | Spreads execution evenly, catches up if behind |
| Fixed-pace execution, no catch-up | timepace | Predictable pacing, skipped intervals stay skipped |
| Fill entire order NOW | sweep | IOC execution with retry logic |
| Accumulate at multiple price levels | ladder | Posts limit orders across a price range |
| Basis/arb trade across venues | spread | Two-leg execution with risk management |
TWAP vs TimePace
| Feature | TWAP | TimePace |
|---|
| Catch-up on missed intervals | Yes | No |
| Fixed end time | Yes (duration-based) | No (runs until filled) |
| Size per interval | Calculated from total/intervals | User-specified |
| Use case | Fill X quantity in Y time | Send Z quantity every N seconds |