Bar
Bar
A single OHLCV candle: its time (epoch ms) plus open, high, low, close, and volume. Every field is readonly, so the bars handed to your strategy are immutable. The per-field columns are exposed over time through MarketSeries.
Signature
export interface Bar { readonly time: number; readonly open: number; readonly high: number; readonly low: number; readonly close: number; readonly volume: number;}Example
import { defineStrategy } from '@nexpips/sdk-trading';
/** * Cycle de vie complet : tous les hooks optionnels et les contextes qu'ils * reçoivent — `InitContext` (init), `BarContext` (onBar), `TickContext` * (onTick), `EventContext` + `Fill` / `Rejection` / `ClosedPosition` (events). */export default defineStrategy({ symbol: 'EURUSD', timeframe: 'M5', risk: { maxRiskPercentPerTrade: 0.5, maxOpenPositions: 1, maxDailyLossPercent: 3, maxConsecutiveRejects: 5, }, setup: () => ({ init(ctx) { ctx.log.info('strategy started', { balance: ctx.account.balance, at: ctx.clock.now }); },
onBar(ctx) { if (ctx.position.isFlat && !ctx.position.hasPendingOrder) { ctx.order.marketBuy({ riskPercent: 0.5, stopLoss: { type: 'pips', value: 20 }, takeProfit: { type: 'rr', value: 2 }, }); } },
onTick(ctx) { const spread = ctx.ask - ctx.bid; if (spread > 0.0005) ctx.log.debug('wide spread', { spread }); },
onOrderFilled(ctx, fill) { ctx.log.info('filled', { side: fill.side, price: fill.price, size: fill.size }); },
onOrderRejected(ctx, rejection) { // rejection.reason est un RejectReason (union fermée). ctx.log.warn('order rejected', { reason: rejection.reason, message: rejection.message }); },
onPositionClosed(ctx, closed) { ctx.log.info('position closed', { pnl: closed.realizedPnl }); }, }),});Each closed bar drives the strategy lifecycle.