Writing Strategies: Basic Structure
A strategy consists of two main parts:
- Indicator registration
- 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 fieldindicators
: The indicator manager for accessing indicator valuespositions
: Array of current open positions with their quantities and average coststrades
: 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
}