Ta4j Wiki

Documentation, examples and further information of the ta4j project

View the Wiki On GitHub

This project is maintained by ta4j Organization

Live Candle vs Closed Candle Evaluation

This page explains one of the most common first live-trading pitfalls in ta4j: repeated buys (or sells) while the same candle is still open.

Short answer

Why repeated entries happen

Repeated entries usually come from one or more integration issues:

  1. Calling strategy.shouldEnter(index) instead of strategy.shouldEnter(index, tradingRecord)
  2. Placing exchange orders but not recording confirmed fills in tradingRecord
  3. Evaluating many times on the same live bar without a de-duplication guard

When this happens, ta4j can keep seeing the entry rule as true and still think no position is open.

Closed-candle mode (simple and stable)

Use this mode if you want less noise and one decision per completed bar:

int index = series.getEndIndex(); // latest closed bar
if (strategy.shouldEnter(index, tradingRecord)) {
    submitBuyOrder();
}

Live-candle mode (faster but needs safeguards)

Use this mode if you want intra-candle reactions:

int lastEntryBarIndex = -1;
while (true) {
    int index = series.getEndIndex();
    if (strategy.shouldEnter(index, tradingRecord) && index != lastEntryBarIndex) {
        submitBuyOrder();
        lastEntryBarIndex = index;
    }
}

Fill synchronization rule

This is critical:

After your exchange confirms execution, write it into ta4j (enter/exit or operate(fill)), so strategy state and broker state stay aligned.

if (strategy.shouldEnter(index, tradingRecord)) {
    ExchangeOrder order = submitBuyOrder();
    if (order.isFilled()) {
        tradingRecord.enter(index, fillPrice, fillAmount);
    }
}

If your venue gives partial fills, use TradingRecord.operate(fill) as fills arrive.

Practical checklist before going live