Examples
These examples show current DCA and Trading LiSA Script patterns. The first two examples are complete strategy documents; the remaining examples are smaller DCA snippets.
Complete DCA strategy
{
"version": 2,
"type": "strategy",
"category": "dca",
"name": "Daily BTC accumulator",
"compact_description": "Adds and deploys 50 quote cash each day.",
"description": "A minimal daily DCA strategy.",
"labels": ["btc", "dca"],
"market": "BTC",
"timeframe": "1d",
"portfolio": {
"quote_asset": "USDC",
"starting_cash": 0
},
"execution": {
"price": "next_candle_open",
"fee_bps": 5,
"slippage_bps": 5
},
"indicators": [],
"external_series": [],
"rules": [
{
"name": "Add daily contribution",
"action": {
"name": "Add daily contribution",
"type": "cashflow",
"amount": 50
}
},
{
"name": "Buy BTC daily",
"conditions": [
{
"name": "Cash is available",
"left": "get('cash')",
"op": ">",
"right": 0
}
],
"action": {
"name": "Buy BTC daily",
"type": "buy",
"asset": "BTC",
"price": "price()",
"sizing": {
"type": "quote_amount",
"amount": 50
}
}
}
],
"constraints": {
"start_time": null,
"end_time": null,
"stop_when_budget_spent": false
}
} Complete Trading strategy
{
"version": 5,
"type": "strategy",
"category": "trading",
"name": "BTC protected timed long",
"compact_description": "Opens one protected BTC long at a fixed time.",
"description": "A minimal 4h Trading strategy with required position protection.",
"labels": ["btc", "trading", "long"],
"market": "BTC",
"timeframe": "4h",
"account": {
"collateral_asset": "USDC",
"starting_balance": 10000
},
"execution": {
"price": "next_candle_open",
"fee_bps": 4.5
},
"indicators": [],
"rules": [
{
"name": "Open the timed long",
"conditions": [
{
"name": "Position is flat",
"left": "position_state()",
"op": "==",
"right": "flat"
},
{
"name": "Year is 2026",
"left": "time('year', 'UTC')",
"op": "==",
"right": 2026
},
{
"name": "4h candle opens at 12:00 UTC",
"left": "time('hour', 'UTC')",
"op": "==",
"right": 12
}
],
"action": {
"name": "Open long",
"type": "open_position",
"side": "long",
"sizing": {
"type": "percent_equity",
"amount": 100
},
"leverage": 1,
"protection": {
"take_profit": {
"type": "percent_from_entry",
"amount": 1
},
"stop_loss": {
"type": "percent_from_entry",
"amount": 2
}
}
}
}
],
"constraints": {
"start_time": null,
"end_time": null
}
} The same contract accepts "timeframe": "1d". A selected action fills at the exact next tradable candle open for its strategy timeframe. A source interval with no Kraken trades contributes a previous-close value to a 4h indicator window but cannot evaluate a rule or execute an action.
Every Trading open_position action requires both entry-relative protection
levels. A separate close_position rule can still close the full position
when its condition is selected first. An open action can instead bind optional
named exit_conditions to the position.
ATR-based Trading protection
{
"name": "Open ATR long",
"type": "open_position",
"side": "long",
"sizing": {
"type": "risk_percent_equity_at_stop",
"amount": 2
},
"protection": {
"take_profit": {
"type": "price_distance_from_entry",
"amount": "atr(14)"
},
"stop_loss": {
"type": "price_distance_from_entry",
"amount": "atr(14) * 1.5"
}
}
} The matching indicator declaration is:
{ "type": "atr", "period": 14, "name": "ATR 14" } Both distances are resolved on the completed signal candle. The next genuine candle open supplies the entry price and the resulting absolute levels remain fixed until the position closes. This example sizes BTC so planned stop-price loss is 2% of positive pre-entry equity; fees remain separate.
Supertrend flip and bound exit
{
"name": "Open long on bullish Supertrend flip",
"conditions": [
{ "name": "Position is flat", "left": "position_state()", "op": "==", "right": "flat" },
{ "name": "Previous state is bearish", "left": "supertrend_bearish(10, 3, 1)", "op": "==", "right": 1 },
{ "name": "Current state is bullish", "left": "supertrend_bullish(10, 3)", "op": "==", "right": 1 }
],
"action": {
"name": "Open Long",
"type": "open_position",
"side": "long",
"sizing": { "type": "risk_percent_equity_at_stop", "amount": 2 },
"protection": {
"take_profit": { "type": "price_distance_from_entry", "amount": "atr(14) * 1.0" },
"stop_loss": { "type": "price_distance_from_entry", "amount": "atr(14) * 1.5" }
},
"exit_conditions": [
{
"name": "Exit long while Supertrend is bearish",
"conditions": [
{ "name": "Supertrend is bearish", "left": "supertrend_bearish(10, 3)", "op": "==", "right": 1 }
]
}
]
}
} Matching declarations use { "type": "supertrend", "period": 10, "factor": 3, "name": "Supertrend 10 / 3" } and { "type": "atr", "period": 14, "name": "ATR 14" }.
Daily cashflow
{
"name": "Add daily contribution",
"action": {
"name": "Add daily contribution",
"type": "cashflow",
"amount": 50
}
} Buy when cash is available
{
"name": "Buy BTC daily",
"conditions": [
{ "name": "Cash is available", "left": "get('cash')", "op": ">", "right": 0 }
],
"action": {
"name": "Buy BTC daily",
"type": "buy",
"asset": "BTC",
"price": "price()",
"sizing": { "type": "quote_amount", "amount": 50 }
}
} Deploy reserve below a moving average
{
"name": "Deploy reserve below 200W MA",
"conditions": [
{ "name": "BTC is below 200W MA", "left": "price()", "op": "<", "right": "ma(200, '1w')" }
],
"action": {
"name": "Deploy reserve cash",
"type": "buy",
"asset": "BTC",
"price": "price()",
"sizing": { "type": "quote_amount", "amount": "get('cash')" }
}
} The matching indicator declaration is:
{ "type": "ma", "mode": "simple", "period": 200, "interval": "1w", "name": "200W MA" } Buy when RSI is below 50
{
"name": "Buy below RSI 50",
"conditions": [
{ "name": "RSI 14 is below 50", "left": "rsi(14)", "op": "<", "right": 50 },
{ "name": "Cash is available", "left": "get('cash')", "op": ">=", "right": 50 }
],
"action": {
"name": "Buy BTC",
"type": "buy",
"asset": "BTC",
"price": "price()",
"sizing": { "type": "quote_amount", "amount": 50 }
}
} The matching indicator declaration is:
{ "type": "rsi", "period": 14, "name": "RSI 14" } Read multi-output indicators
{ "left": "macd(12, 26, 9, 'line')", "op": ">", "right": "macd(12, 26, 9, 'signal')" }
{ "left": "price()", "op": "<", "right": "bollinger_bands(20, 2, 'lower')" }
{ "left": "stochastic(14, 3, 3, 'k')", "op": "<", "right": 20 }
{ "left": "adx(14)", "op": ">", "right": 25 }
{ "left": "plus_di(14)", "op": ">", "right": "minus_di(14)" }
{ "left": "price()", "op": ">", "right": "parabolic_sar(0.02, 0.2)" }
{ "left": "cci(20)", "op": "<", "right": -100 }
{ "left": "williams_r(14)", "op": "<", "right": -80 }
{ "left": "price()", "op": ">", "right": "ichimoku(9, 26, 52, 'senkou_a')" } Each expression needs the matching top-level technical indicator declaration. External series use external_series and series(id) instead.
Update a state variable after a buy
{
"name": "Buy and track average entry",
"conditions": [
{ "name": "Cash is available", "left": "get('cash')", "op": ">", "right": 0 }
],
"actions": [
{
"name": "Buy BTC",
"type": "buy",
"asset": "BTC",
"price": "price()",
"sizing": { "type": "quote_amount", "amount": 50 }
},
{
"name": "Track average entry",
"type": "set",
"values": {
"total_entry_cost": "get('total_entry_cost') + get('last_buy.cash_spent')",
"total_btc_acquired": "get('total_btc_acquired') + get('last_buy.btc_bought')",
"avg_entry": "get('total_entry_cost') / get('total_btc_acquired')"
}
}
]
} The matching state variable line declaration is:
{ "type": "state", "variable": "avg_entry", "name": "Average entry" }