Skip to main content

Writing Strategies: Basic Structure

A strategy consists of two main parts:

  1. Indicator registration
  2. The onBar function

Here's a minimal example:

// 1. Register any indicators you need
registerIndicator("SMA", "BUILTIN", {
period: 20,
field: "close"
}, "SMA_20_CLOSE"); // Custom ID for this instance

// 2. Define your strategy logic
function onBar(data, indicators, positions, trades) {
const rowCount = data.close.length;
const signals = new Array(rowCount).fill("HOLD");

for (let i = 0; i < rowCount; i++) {
const token = data.token_address[i];
const sma = indicators.getValue("SMA_20_CLOSE", token);

if (data.close[i] > sma) {
signals[i] = "BUY";
} else if (data.close[i] < sma) {
signals[i] = "SELL";
}
}

return signals;
}

The onBar function receives four parameters:

  • data: Object containing arrays for each price/volume field
  • indicators: The indicator manager for accessing indicator values
  • positions: Array of current open positions with their quantities and average costs
  • trades: Array of all historical trades with realized PnL

Each position object contains:

interface Position {
token: string; // Token identifier
quantity: number; // Current quantity held
avgCost: number; // Average purchase price
}

Each trade record contains:

interface TradeRecord {
token: string;
timestamp: string; // e.g., "2024-06-01 12:00"
action: 'BUY' | 'SELL';
price: number; // includes slippage
quantity: number;
realizedPnl: number; // if any, on partial or full close
}