Order flow footprint indicator - Strategies

TDU FootPrint Plots - Developer Guide

Complete API reference for building NinjaScript strategies with the TradeDevils Order Flow Footprint indicator

1. Overview & Architecture

The TDU FootPrint indicator provides two distinct APIs for strategy developers:

Standard Plots API (Beginner-Friendly)

Uses the TDUFootPrintPlots indicator which exposes 101 named plots as standard NinjaTrader Series<double> values. Works in custom indicators, strategies, and Algo Studio Pro.

Advanced IFootPrintBar API (NinjaScript Only)

Access the IFootPrintBar interface directly to get the full internal state of each footprint bar: bid/ask dictionaries at every price level, imbalance lists, and all computed signals.

Available Indicator Classes

Class Purpose Usage
TDUFootPrintPlots Exposes 101 plots for strategies/indicators TDUFootPrintPlots()
TDUFootPrint Main footprint rendering indicator (chart overlay) TDUFootPrint()
TDUFootPrintPullBack Pullback footprint variant TDUFootPrintPullBack()

2. Getting Started

Required Using Directives

When you create a new strategy via the NinjaScript Editor, NinjaTrader auto-generates the standard using block. All examples in this guide assume these are present. The full block looks like this:

#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
using NinjaTrader.NinjaScript.Indicators.TDU;
#endregion

The #region block above is auto-generated by NinjaTrader when you create a new strategy. You must also add the following using directive to use TDU FootPrint:

using NinjaTrader.NinjaScript.Indicators.TDU;

This is required for both the Plots API and the IFootPrintBar API. Without it, your code will not compile. When calling GetFootPrintBar(), always use var to capture the result. This avoids CS0266 compile errors that can occur when TDUFootPrintTrader.dll is also installed (see examples in Sections 5 and 10).

Required: You Must Add the Tick Data Series

The TDU FootPrint indicator requires a 1-tick data series. When hosting it inside your own strategy or indicator, you must add this yourself in State.Configure:

else if (State == State.Configure)
{
    AddDataSeries(BarsPeriodType.Tick, 1);
}

Without this, the indicator will not receive tick data and will not produce any signals.

BarsInProgress Check

Because you added a 1-tick data series, your OnBarUpdate will fire for both your primary series (BarsInProgress == 0) and the tick series (BarsInProgress == 1). Always guard your strategy logic with if (BarsInProgress != 0) return; to avoid processing tick updates in your signal logic.

Order Submission on Tick Series for Immediate Fills

To get orders filled immediately (on the next tick) instead of waiting for the next primary bar close, submit orders on the 1-tick data series by using the BarsInProgress overload. See the sample strategies below for examples.

Configurable Settings

All public properties below can be set programmatically (see next section) or via the NinjaTrader indicator properties dialog. UI-only properties (colors, fonts, rendering) are omitted.

General Settings

Property Type Default Description
CalculationMethod FootPrintDeltaCalculation BidAsk How delta is calculated: BidAsk, UpDownTick, or TickCount.
TickGroupCount int 0 Groups multiple price levels into a single row. 0 = no grouping (one row per tick). E.g., 2 on ES groups two 0.25-tick levels into one 0.50-level row.
ExtremeDeltaMultiplier double 1.5 StdDev multiplier for dynamic extreme delta threshold. Higher = fewer delta signals, lower = more sensitive.
RefreshRate int 200 Chart refresh rate in milliseconds.

Volume Filter

Property Type Default Description
EnableBigTradesFilter bool false Enable filtering of large volume trades.
MinVolumeFilter int 500 Minimum volume threshold for the volume filter.
TradesExtend FootPrintBarExtend UntilTested How long to extend volume filter marks.
TradesBarCount int 5 Number of bars to extend (when TradesExtend = Bars).

Delta Filter

Property Type Default Description
MinimumDeltaFilter int 0 Minimum absolute delta required for signals. 0 = no filter.

Bar POC

Property Type Default Description
POCExtendType FootPrintPocExtend Bullish_Bearish_POCs Which types of POCs to extend on chart.
POCExtend FootPrintBarExtend Bars How long to extend POC lines.
POCBarCount int 0 Number of bars to extend POC (when POCExtend = Bars).
BullishBearishPOCLookbackPeriod int 0 Lookback period for bullish/bearish POC detection.
BullishBearishPOCTicksOffset int 3 Ticks offset for bullish/bearish POC classification.

Bar Value Area

Property Type Default Description
BarValueAreaPercentage double 70 Percentage of volume for bar value area (e.g., 70 = 70%).
BarValueAreaMinVolume int 0 Minimum volume required for bar value area calculation.
BarValueAreaMinDelta int 0 Minimum delta required for bar value area calculation.
ValueAreaExtend FootPrintBarExtend Bars How long to extend value area zones.
ValueAreaBarCount int 0 Number of bars to extend value area.

Imbalances

Property Type Default Description
ImbalancePercentage double 400 Minimum percentage for an imbalance (400 = ask must be 4x the bid).
ImbalanceDeltaMethod FootPrintDeltaMethod Diagonal How imbalances are calculated: Diagonal (ask at price vs bid one level below) or horizontal.
MinImbalanceVolume double 0 Minimum volume required on both bid and ask for an imbalance.
MinimumMultipleImbalanceCount int 3 Minimum number of imbalances needed for a "Multiple Imbalance" signal.
OversizedImbalancePercentage double 1000 Percentage threshold for oversized imbalances (1000 = 10x).
BigImbalanceLevel int 1300 Minimum volume on bid or ask for a "Big Imbalance".

Fat Prints

Property Type Default Description
FatPrintThreshold int 1000 Volume threshold for a fat print (unusually high volume at a price level).
FatPrintExtend FootPrintBarExtend Bars How long to extend fat print marks.
FatPrintBarCount int 0 Number of bars to extend fat prints.

Big Delta

Property Type Default Description
BigDeltaThreshold int 600 Volume threshold for a big delta signal at a price level.
BigDeltaExtend FootPrintBarExtend Bars How long to extend big delta marks.
BigDeltaBarCount int 0 Number of bars to extend big delta.

Zero Prints

Property Type Default Description
ZeroPrintExtend FootPrintBarExtend Bars How long to extend zero print marks.
ZeroPrintBarCount int 0 Number of bars to extend zero prints.

Thin Prints

Property Type Default Description
ThinPrintMaxVolume int 0 Maximum volume to qualify as a thin print. 0 = disabled.
ThinPrintExtend FootPrintBarExtend Bars How long to extend thin print marks.
ThinPrintBarCount int 0 Number of bars to extend thin prints.

Exhaustion Prints

Property Type Default Description
ExhaustionPrintThreshold int 8 Number of consecutive levels needed for an exhaustion print.
ExhaustionPrintExtend FootPrintBarExtend Bars How long to extend exhaustion print marks.
ExhaustionPrintBarCount int 0 Number of bars to extend exhaustion prints.

Volume Sequencing

Property Type Default Description
VolumeSequenceType StackedImbalancesTypes All Which volume sequences to show: All or AtCandleHighLow.
VolumeSequencingThreshold int 5 Minimum consecutive levels needed for a volume sequence.
VolumeSequencingExtend FootPrintBarExtend Bars How long to extend volume sequence marks.
VolumeSequencingBarCount int 0 Number of bars to extend volume sequences.

Stacked Imbalances

Property Type Default Description
StackedImbalanceType StackedImbalancesTypes All Which stacked imbalances to show: All or AtCandleHighLow.
MinimumStackedImbalanceCount int 3 Minimum consecutive imbalances for a stacked imbalance cluster.
StackedImbalanceExtend FootPrintBarExtend UntilTested How long to extend stacked imbalance zones.
StackedImbalanceBarCount int 5 Number of bars to extend stacked imbalances.

Imbalance Reversals

Property Type Default Description
MinImbalanceReversalVolume int 10 Minimum volume at a level for a reversal imbalance.
ImbalanceReversalExtend FootPrintBarExtend UntilTested How long to extend reversal imbalance zones.
ImbalanceReversalBarCount int 5 Number of bars to extend reversal imbalances.

Inverse Imbalances

Property Type Default Description
MinimumInverseImbalanceCount int 2 Minimum consecutive inverse imbalances needed.
InverseImbalanceExtend FootPrintBarExtend UntilTested How long to extend inverse imbalance zones.
InverseImbalanceBarCount int 5 Number of bars to extend inverse imbalances.

Market Sweep

Property Type Default Description
MaxMarketSweepVolume int 5 Maximum volume per level to qualify as a market sweep (thin aggressive orders).
MinMarketSweepLevels int 3 Minimum number of consecutive levels for a sweep.
MarketSweepType StackedImbalancesTypes All Which sweeps to show: All or AtCandleHighLow.
MarketSweepExtend FootPrintBarExtend Bars How long to extend sweep marks.
MarketSweepBarCount int 0 Number of bars to extend sweeps.

Unfinished Business

Property Type Default Description
HideFinishedBusiness bool true Hide unfinished business marks once they are resolved.
UnfinishedBusinessExtend FootPrintBarExtend UntilTested How long to extend unfinished business zones.
UnfinishedBusinessBarCount int 5 Number of bars to extend unfinished business.

Fading Momentum

Property Type Default Description
FadingMomentumLookBackPeriod int 3 Lookback period in bars for fading momentum detection.
FadingMomentumExtend FootPrintBarExtend UntilTested How long to extend fading momentum marks.
FadingMomentumBarCount int 0 Number of bars to extend fading momentum.

Stopping Volume

Property Type Default Description
StoppingVolumeLookBackPeriod int 3 Lookback period in bars for stopping volume detection.
StoppingVolumeExtend FootPrintBarExtend UntilTested How long to extend stopping volume marks.
StoppingVolumeBarCount int 0 Number of bars to extend stopping volume.

Absorption

Property Type Default Description
AbsorptionLookBackPeriod int 4 Lookback period in bars for absorption detection.
AbsorptionExtend FootPrintBarExtend UntilTested How long to extend absorption marks.
AbsorptionBarCount int 0 Number of bars to extend absorption.

Delta Divergence

Property Type Default Description
DeltaDivergenceType DeltaDivergenceType Type of delta divergence to detect.
DeltaDivergencePeriod int 5 Lookback period for divergence detection.
DeltaDivergenceExtend FootPrintBarExtend Bars How long to extend divergence marks.
DeltaDivergenceBarCount int 0 Number of bars to extend divergence.

Delta Price Divergence

Property Type Default Description
ShowDeltaPriceDivergence bool false Enable delta-price divergence signal.
DeltaPriceDivergenceExtend FootPrintBarExtend Bars How long to extend divergence marks.
DeltaPriceDivergenceBarCount int 0 Number of bars to extend divergence.

POC Momentum Wave

Property Type Default Description
ShowPocMomentumWave bool false Enable POC momentum wave signal.
PocMomentumWaveExtend FootPrintBarExtend Bars How long to extend POC momentum wave marks.
PocMomentumWaveBarCount int 0 Number of bars to extend.

Bid/Ask Fade

Property Type Default Description
ShowBidAskFade bool false Enable bid/ask fade signal.
BidAskFadeExtend FootPrintBarExtend Bars How long to extend bid/ask fade marks.
BidAskFadeBarCount int 0 Number of bars to extend.

Passive Absorption

Property Type Default Description
ShowPassiveAbsorption bool false Enable passive absorption signal.
PassiveAbsorptionExtend FootPrintBarExtend Bars How long to extend passive absorption marks.
PassiveAbsorptionBarCount int 0 Number of bars to extend.
PassiveAbsorptionMinLevels int 0 Minimum consecutive levels for passive absorption.

POC Gap

Property Type Default Description
PocGapExtend FootPrintBarExtend Bars How long to extend POC gap marks.
PocGapBarCount int 0 Number of bars to extend POC gaps.

Delta Rate

Property Type Default Description
DeltaRateType FootPrintDeltaRateType Tick How delta rate is measured: per tick or per time interval.
DeltaRateValue long 100 Value for delta rate calculation (tick count or milliseconds).

Custom Stripe Expressions

Property Type Default Description
Custom1StripeExpression string (see below) Custom expression for stripe #1. Uses footprint variables like Ratio, Delta, etc.
Custom2StripeExpressionCustom5StripeExpression string "" Custom expressions for stripes #2–#5. Empty = disabled.

Default for Custom1StripeExpression: if ( Ratio>=30 || (Ratio>0 && Ratio<=0.7) ) { Opacity=30; BackgroundColor= "Cyan"; }

Volume Profile

Property Type Default Description
ValueAreaPercentage double 70 Percentage of volume for the session volume profile value area.

Session Detection

Property Type Default Description
S_AsiaSessionStart string "18:00" Asia session start time (hh:mm).
S_AsiaSessionEnd string "02:00" Asia session end time.
S_EuropeSessionStart string "02:00" Europe session start time.
S_EuropeSessionEnd string "08:00" Europe session end time.
S_NewYorkSessionStart string "08:00" New York session start time.
S_NewYorkSessionEnd string "17:00" New York session end time.

Swing Filter

The swing filter suppresses signals that occur outside of swing highs/lows, reducing noise. Set SwingPeriod to control the lookback, then enable individual signal filters below.

Property Type Default Description
SwingPeriod int 5 Lookback period (in bars) for swing detection.
RatioSwingFilter bool false Filter Ratio signal by swing.
ZeroPrintSwingFilter bool false Filter Zero Prints by swing.
ThinPrintSwingFilter bool false Filter Thin Prints by swing.
FatPrintSwingFilter bool false Filter Fat Prints by swing.
BigDeltaSignalSwingFilter bool false Filter Big Delta by swing.
EngulfingValueAreaSwingFilter bool false Filter Engulfing Value Area by swing.
VolumeSequencingSwingFilter bool false Filter Volume Sequencing by swing.
BigImbalanceSwingFilter bool false Filter Big Imbalance by swing.
OversizedImbalanceSwingFilter bool false Filter Oversized Imbalance by swing.
SecondSlotImbalanceSwingFilter bool false Filter 2nd Slot Imbalance by swing.
ConsecutivePocSwingFilter bool false Filter Consecutive POC by swing.
ConsecutiveImbalancesSwingFilter bool false Filter Consecutive Imbalances by swing.
BullishBearishPocSwingFilter bool false Filter Bullish/Bearish POC by swing.
PocInWickSwingFilter bool false Filter POC In Wick by swing.
ExhaustionPrintSwingFilter bool false Filter Exhaustion Print by swing.
StoppingVolumeSwingFilter bool false Filter Stopping Volume by swing.
FadingMomentumSwingFilter bool false Filter Fading Momentum by swing.
MarketSweepSwingFilter bool false Filter Market Sweep by swing.
MultipleImbalancesSwingFilter bool false Filter Multiple Imbalances by swing.
ReversalImbalanceSwingFilter bool false Filter Reversal Imbalance by swing.
InverseImbalanceSwingFilter bool false Filter Inverse Imbalance by swing.
StackedImbalanceSwingFilter bool false Filter Stacked Imbalance by swing.
UnfinishedBusinessSwingFilter bool false Filter Unfinished Business by swing.
AboveBelowPocSwingFilter bool false Filter Above/Below POC by swing.
DeltaRiseSwingFilter bool false Filter Delta Rise by swing.
DeltaDropSwingFilter bool false Filter Delta Drop by swing.
DeltaDivergenceSwingFilter bool false Filter Delta Divergence by swing.
DeltaFlipSwingFilter bool false Filter Delta Flip by swing.
DeltaTailSwingFilter bool false Filter Delta Tail by swing.
DeltaReversalSwingFilter bool false Filter Delta Reversal by swing.
DeltaTrapSwingFilter bool false Filter Delta Trap by swing.
DeltaContinuousPocSwingFilter bool false Filter Delta Continuous POC by swing.
DeltaSweepSwingFilter bool false Filter Delta Sweep by swing.
DeltaCloseAtMinMaxDeltaSwingFilter bool false Filter Delta Close At Min/Max by swing.
DeltaSlingshotSwingFilter bool false Filter Delta Slingshot by swing.
TrappedTradersSwingFilter bool false Filter Trapped Traders by swing.
ValueAreaGapSwingFilter bool false Filter Value Area Gap by swing.
PocGapSwingFilter bool false Filter POC Gap by swing.
AbsorptionSwingFilter bool false Filter Absorption by swing.
DeltaPriceDivergenceSwingFilter bool false Filter Delta Price Divergence by swing.
PocMomentumWaveSwingFilter bool false Filter POC Momentum Wave by swing.
BidAskFadeSwingFilter bool false Filter Bid/Ask Fade by swing.
PassiveAbsorptionSwingFilter bool false Filter Passive Absorption by swing.
VolumeBubbleSwingFilter bool false Filter Volume Bubbles by swing.

Setting Parameters Programmatically

Properties Must Be Set Immediately After Instantiation

The auto-generated TDUFootPrintPlots() method accepts no input parameters. To customize settings, set properties on the returned instance immediately after calling TDUFootPrintPlots() in State.DataLoaded, before any bars are processed:

else if (State == State.DataLoaded)
{
    _fp = TDUFootPrintPlots();
    _fp.TickGroupCount = 2;
    _fp.SwingPeriod = 20;
    _fp.RatioSwingFilter = true;
    _fp.ImbalancePercentage = 300;
}

Using Plots API in a Strategy

private TDUFootPrintPlots _fp;

protected override void OnStateChange()
{
    if (State == State.SetDefaults)
    {
        Name = "My Footprint Strategy";
        Calculate = Calculate.OnEachTick;
    }
    else if (State == State.Configure)
    {
        AddDataSeries(BarsPeriodType.Tick, 1);
    }
    else if (State == State.DataLoaded)
    {
        _fp = TDUFootPrintPlots();
    }
}

protected override void OnBarUpdate()
{
    if (BarsInProgress != 0) return;
    if (CurrentBar < 5) return;

    double delta = _fp.Delta[0];
    double volume = _fp.TotalVolume[0];
    bool hasDeltaRise = _fp.DeltaRise[0] == 1;
}

Using IFootPrintBar API in a Strategy (with custom settings)

private TDUFootPrintPlots _fp;

protected override void OnStateChange()
{
    if (State == State.SetDefaults)
    {
        Name = "Advanced Footprint Strategy";
        Calculate = Calculate.OnEachTick;
    }
    else if (State == State.Configure)
    {
        AddDataSeries(BarsPeriodType.Tick, 1);
    }
    else if (State == State.DataLoaded)
    {
        _fp = TDUFootPrintPlots();
        _fp.TickGroupCount = 2;         // group 2 price levels per row
        _fp.SwingPeriod = 20;            // larger swing lookback
        _fp.ImbalancePercentage = 300;  // more sensitive imbalances
    }
}

protected override void OnBarUpdate()
{
    if (BarsInProgress != 0) return;
    if (CurrentBar < 5) return;

    var bar = _fp.GetFootPrintBar(0);
    if (bar == null) return;

    foreach (var kvp in bar.Asks)
    {
        double priceLevel = kvp.Key;
        double askVolume = kvp.Value;
    }

    int stackedBuys = bar.StackedBuyImbalances.Count;
    bool hasBullDiv = bar.HasBullishDeltaDivergence;
}

3. Plots API (Standard Method)

The TDUFootPrintPlots indicator exposes 101 plots (indices 0-100). Each plot is a Series<double> accessible by name or by index via Values[n].

Plot Value Conventions

Convention Meaning Example
0 / 1 Boolean signal: 0 = false, 1 = true DeltaRise[0] == 1
-1 / 0 / 1 Directional: -1 = bearish, 0 = none, 1 = bullish Absorption[0] == 1
count Integer count of occurrences BuyImbalances[0] > 3
numeric Continuous value (price, volume, ratio, etc.) Delta[0] > 500

4. Complete Plots Reference (101 Plots)

Delta Signals

Plot Name C# Property Type Description
Delta Rise DeltaRise bool 1 when delta is rising (positive momentum).
Delta Flip DeltaFlip bool 1 when delta flips sign from previous bar.
Delta Divergence DeltaDivergence bool 1 when price and delta diverge.
Delta Tail DeltaTail bool 1 when a delta tail is detected.
Delta Reversal DeltaReversal bool 1 when a delta reversal pattern is detected.
Delta Drop DeltaDrop bool 1 when delta drops sharply.
Delta Trap DeltaTrap dir 1 = bullish trap, -1 = bearish trap.
Delta Sweep DeltaSweep bool 1 when delta sweeps from min to max or vice versa.
Delta Continuous POC DeltaContinuousPoc dir 1 = bullish, -1 = bearish. POC stays at same level for consecutive bars.
Delta Close at Min Delta DeltaCloseAtMinDelta bool 1 when red bar closes at/near its minimum delta.
Delta Close at Max Delta DeltaCloseAtMaxDelta bool 1 when green bar closes at/near its maximum delta.
Bullish Delta Slingshot BullishDeltaSlingShot bool 1 on green bars where delta slingshots.
Bearish Delta Slingshot BearishDeltaSlingShot dir -1 on red bars where delta slingshots.
Delta Percentage DeltaPercentage num Delta as percentage of total volume.
Delta Move DeltaMove num Magnitude of delta move.
Delta Efficiency DeltaEfficiency num How efficiently delta is moving price.

Imbalance Signals

Plot Name C# Property Type Description
Buy Imbalances BuyImbalances count Number of buy (ask) imbalances in the bar.
Sell Imbalances SellImbalances count Number of sell (bid) imbalances in the bar.
Stacked Buy Imbalances StackedBuyImbalances count Number of consecutive (stacked) buy imbalances. 3+ = strong buying signal.
Stacked Sell Imbalances StackedSellImbalances count Number of consecutive (stacked) sell imbalances.
2nd Slot Buy Imbalance SecondSlotBuyImbalance bool 1 when buy imbalance at 2nd price level from low.
2nd Slot Sell Imbalance SecondSlotSellImbalance bool 1 when sell imbalance at 2nd price level from high.
Reversal Imbalance Count ReversalImbalanceCount count Number of reversal imbalances in the bar.
Inverse Imbalance Count InverseImbalanceCount count Number of inverse imbalances in the bar.
Consecutive Imbalances ConsecutiveImbalances bool 1 when continuous imbalances detected across price levels.
Big Imbalance BigImbalance count Count of big buy + big sell imbalances.
Oversized Imbalance OversizedImbalance count Count of oversized buy + sell imbalances.
Multiple Imbalances MultipleImbalances count Total count of all buy + sell imbalances.

Volume & Metrics

Plot Name C# Property Type Description
Volume TotalVolume num Total volume of the footprint bar.
Delta Delta num Bar delta (Ask volume - Bid volume).
Min Delta MinDelta num Minimum delta during bar formation.
Max Delta MaxDelta num Maximum delta during bar formation.
Cumulative Delta CumulativeDelta num Running cumulative delta across session.
Cumulative Delta Volume CumulativeDeltaVolume num Running cumulative volume across session.
Bid Bid num Total bid (sell) volume.
Ask Ask num Total ask (buy) volume.
Trades Trades num Total number of individual trades.
Duration (sec) BarDuration num How long the bar took to form.
Ratio Ratio num Ask/Bid volume ratio.
Delta Rate DeltaRate num Rate of delta change per unit time.
Volume/Sec VolumePerSec num Volume per second (intensity).
Delta Volume DeltaVolume num Volume change from previous bar.
Delta Standard Deviation DeltaStdDev num Standard deviation of delta values.
Volume Standard Deviation VolumeStdDev num Standard deviation of volume.
Trades Standard Deviation TradesStdDev num Standard deviation of trade count.
Bid/Ask Ratio BidAskRatio num Ratio of bid to ask volume.
Delta Change DeltaChange num Bar-to-bar change in delta.
Delta Change % DeltaChangePercentage num Bar-to-bar percentage change in delta.
Cumulative Volume CumulativeVolumePlot num Running cumulative volume across session.
Buy Volume BuyVolume num Total buy (ask) volume.
Sell Volume SellVolume num Total sell (bid) volume.
Volume Change % VolumeChangePercentage num Percentage change in volume from previous bar.

POC & Value Area

Plot Name C# Property Type Description
Open & Close above POC OpenCloseAbovePOC bool 1 when both open and close are above POC.
Open & Close below POC OpenCloseBelowPOC dir -1 when both open and close are below POC.
POC Price POCPrice price Point of Control price level.
Value Area High ValueAreaHigh price Upper boundary of value area (70% of volume).
Value Area Low ValueAreaLow price Lower boundary of value area.
COT High COTHigh num Commitment of Traders High — cumulative delta (ask − bid volume) since price last made a new or equal high. Resets each time the bar's high is touched or exceeded.
COT Low COTLow num Commitment of Traders Low — cumulative delta (ask − bid volume) since price last made a new or equal low. Resets each time the bar's low is touched or exceeded.
Volume Profile VAH VolumeProfileValueAreaHigh price Session VP value area high.
Volume Profile VAL VolumeProfileValueAreaLow price Session VP value area low.
Volume Profile POC VolumeProfilePOC price Session VP point of control.
Value Area Gap ValueAreaGap bool 1 when value area gaps from previous bar's.
Engulfing Value Area EngulfingValueArea bool 1 when current bar's VA engulfs previous bar's.
POC Gap POCGap bool 1 when POC has gap from prior bar's POC.
POC In Wick POCInWick bool 1 when POC is in the bar's wick. Potential reversal.
Bullish/Bearish POC BullishBearishPOC dir 1 = bullish POC, -1 = bearish POC.
Extreme POC ExtremePOC bool 1 when POC is at bar high or low.
POC Delta POCDelta num Delta at the POC price level.
POC Volume POCVolume num Volume at the POC price level.
Consecutive POC ConsecutivePoc bool 1 when POC at same price as previous bar.
Above/Below POC AboveBelowPoc dir 1 = above POC, -1 = below.
Previous Session VP VAH PreviousSessionVPVAH price Previous session's VP VAH.
Previous Session VP VAL PreviousSessionVPVAL price Previous session's VP VAL.
Previous Session VP POC PreviousSessionVPPOC price Previous session's VP POC.

Advanced Signals

Plot Name C# Property Type Description
Bullish Volume Sequencing BullishVolumeSequencing count Count of bullish (ask) volume sequences.
Bearish Volume Sequencing BearishVolumeSequencing count Count of bearish (bid) volume sequences.
Bullish Exhaustion Print BullishExhaustionPrint bool 1 when bullish exhaustion print detected.
Bearish Exhaustion Print BearishExhaustionPrint dir -1 when bearish exhaustion print detected.
Sweep Count MarketSweepCount count Number of market sweeps.
Thin Print Count ThinPrintCount count Price levels with very low volume.
Zero Print Count ZeroPrintCount count Price levels with zero volume.
Bullish Trapped Traders BullishTrappedTraders bool 1 when sellers are trapped (bullish).
Bearish Trapped Traders BearishTrappedTraders dir -1 when buyers are trapped (bearish).
Stopping Volume StoppingVolume dir 1 = bullish, -1 = bearish.
Fading Momentum FadingMomentum dir 1 = bullish fading, -1 = bearish fading.
Absorption Absorption dir 1 = bullish absorption, -1 = bearish.
Big Delta Count BigDeltaCount count Price levels with unusually large delta.
Fat Print Count FatPrintCount count Price levels with unusually high volume.
Min Delta Volume MinDeltaVolume num Minimum volume change from previous bar.
Max Delta Volume MaxDeltaVolume num Maximum volume change from previous bar.
Unfinished Business UnfinishedBusiness dir 1 = bullish, -1 = bearish. Price likely to return.
Delta Price Divergence DeltaPriceDivergence dir 1 = bullish, -1 = bearish.
POC Momentum Wave PocMomentumWave dir 1 = bullish, -1 = bearish.
Bid/Ask Fade BidAskFade dir 1 = bullish, -1 = bearish.
Passive Absorption PassiveAbsorption dir 1 = bullish, -1 = bearish.

Previous Day OHLC & Session

Plot Name C# Property Type Description
Previous Day Open PreviousDayOpen price Previous trading day's open.
Previous Day High PreviousDayHigh price Previous trading day's high.
Previous Day Low PreviousDayLow price Previous trading day's low.
Previous Day Close PreviousDayClose price Previous trading day's close.
Current Session CurrentSession num 0 = Asia, 1 = Europe, 2 = New York, -1 = none.

5. IFootPrintBar Interface (Advanced API)

Access via _fp.GetFootPrintBar(barsAgo). Uses the standard NinjaTrader bars-ago convention: 0 = current bar, 1 = previous bar, 2 = two bars back, etc. Returns null when the bar has no footprint data yet.

Price-Level Dictionaries

Property Type Description
Asks Dictionary<double, double> Ask volume at each price level (key=price, value=volume).
Bids Dictionary<double, double> Bid volume at each price level.
TradesAsk Dictionary<double, double> Ask trade count at each price level.
TradesBids Dictionary<double, double> Bid trade count at each price level.
RawAsks ConcurrentDictionary<double, double> Thread-safe raw ask volume data.
RawBids ConcurrentDictionary<double, double> Thread-safe raw bid volume data.

OHLCV & Core Metrics

Property Type Description
Open, High, Low, Close double Bar OHLC prices.
Volume double Total bar volume.
Delta double Net delta (Ask - Bid volume).
MinDelta, MaxDelta double Min/max delta during bar formation.
TotalBuyVolume double Total buy (ask) volume.
TotalSellVolume double Total sell (bid) volume.
CumulativeDelta double Running session cumulative delta.
CumulativeVolume double Running session cumulative volume.
Trades long Total individual trades.
Ratio double Ask/Bid volume ratio.
DeltaPercentage double Delta as percentage of volume.
DeltaRate double Rate of delta change.
VolumePerSecond double Volume per second (intensity).
DeltaChange, DeltaChangePercentage double Bar-to-bar delta change and percentage.
VolumeChange, VolumePercentage double Volume change and percentage.
DeltaMove double Magnitude of delta movement.
DeltaEfficiency double How efficiently delta converts to price movement.
BidAskRatio double Bid to ask ratio.
Duration TimeSpan Time taken to form bar.
Bar int Bar index.
Time DateTime Bar time.
IsGreenBar, IsRedBar bool Bar direction (close vs open).

POC & Value Area

Property Type Description
POC double Point of Control price.
POCDelta double Delta at POC price.
POCVolume double Volume at POC price.
PocVolumes List<double> Volumes at POC prices.
ValueAreaHigh, ValueAreaLow double Value area boundaries.
COTHigh, COTLow double Commitment of Traders — cumulative delta (ask − bid volume) since price last made a new/equal high or low. Resets at each new extreme.
OpenAndCloseAbovePOC bool Both open and close above POC.
OpenAndCloseBelowPOC bool Both open and close below POC.
HasBullishPOC, HasBearishPOC bool POC positioning signals.
HasBullishPOCInWick, HasBearishPOCInWick bool POC in wick signals.
HasExtremePOC bool True when POC is at the bar's high or low (within one tick step).
HasPOCGap bool Gap between current and previous POC.
HasBullishContinuousPocSignal, HasBearishContinuousPocSignal bool Continuous POC signals.
HasEngulfingValueArea bool Current VA engulfs previous VA.

Imbalance Lists

Property Type Description
BuyImbalances List<double> Price levels with buy imbalances.
SellImbalances List<double> Price levels with sell imbalances.
StackedBuyImbalances List<double> Price levels with stacked buy imbalances.
StackedSellImbalances List<double> Price levels with stacked sell imbalances.
BigBuyImbalances, BigSellImbalances List<double> Big imbalance price levels.
OverSizedBuyImbalances, OverSizedSellImbalances List<double> Oversized imbalance price levels.
AskVolumeSequences List<Imbalance> Bullish volume sequences (ask side).
BidVolumeSequences List<Imbalance> Bearish volume sequences (bid side).
ReversalImbalances List<IImbalance> Reversal imbalance zones.
InverseImbalances List<IImbalance> Inverse imbalance zones.

Boolean Signal Properties

Property Description
DeltaRise, DeltaDrop Delta rising / dropping.
DeltaFlip Delta sign change.
DeltaTail, DeltaReversal Delta tail / reversal patterns.
DeltaSweep, DeltaSlingShot Delta sweep / slingshot patterns.
CloseAtMaxDelta Green bar closes at/near its maximum delta (bullish).
CloseAtMinDelta Red bar closes at/near its minimum delta (bearish).
HasBullishDeltaDivergence, HasBearishDeltaDivergence Delta-price divergence.
HasBullishDeltaTrap, HasBearishDeltaTrap Trapped traders via delta.
HasBullishTrappedTraders, HasBearishTrappedTraders General trapped traders signal.
HasBullishAbsorption, HasBearishAbsorption Volume absorption.
HasBullishPassiveAbsorption, HasBearishPassiveAbsorption Passive limit order absorption.
HasBullishStoppingVolume, HasBearishStoppingVolume Stopping volume at extremes.
HasBullishFadingMomentum, HasBearishFadingMomentum Momentum fading.
HasBullishReversalImbalance, HasBearishReversalImbalance Reversal imbalance signals.
HasBullishInverseImbalance, HasBearishInverseImbalance Inverse imbalance signals.
HasBullishThinPrint, HasBearishThinPrint Thin print direction.
HasBullishUnfinishedBusiness, HasBearishUnfinishedBusiness Unfinished auction.
HasBullishExhaustionPrint, HasBearishExhaustionPrint Exhaustion print signals.
HasBuyExhaustionPrint, HasSellExhaustionPrint Exhaustion print by side.
HasBullishDeltaPriceDivergence, HasBearishDeltaPriceDivergence Delta-price divergence.
HasBullishPocMomentumWave, HasBearishPocMomentumWave POC momentum wave.
HasBullishBidAskFade, HasBearishBidAskFade Bid/Ask fade.
HasContinuousImbalance Continuous imbalance across levels.

Count Properties

Property Type Description
MarketSweepCount int Number of market sweeps.
ExhaustionPrintCount int Number of exhaustion prints.
BigDeltaCount int Count of big delta levels.
FatPrintCount int Count of fat print levels.
ThinPrintCount int Count of thin print levels.
ZeroPrintCount int Count of zero print levels.

Standard Deviation & Max-At-Price

Property Type Description
DeltaStandardDeviation double Std dev of delta.
VolumeStandardDeviation double Std dev of volume.
TradesStandardDeviation double Std dev of trade count.
MaxAskAtPriceLevel double Highest ask volume at any single level.
MaxBidAtPriceLevel double Highest bid volume at any single level.
MaxTradesAsk, MaxTradesBid double Max ask/bid trades at a level.
MaxTradesAtPriceLevel double Max trades at any price level.
MaxVolumePriceLevel double Price level with highest volume.
MaxHorizontalDeltaAtPriceLevel double Max horizontal delta at any level.
MaxDiagonalDeltaAtPriceLevel double Max diagonal delta at any level.

Methods

Method Returns Description
get_ask(double price) double Get ask volume at a specific price level.
get_bid(double price) double Get bid volume at a specific price level.
is_buy_imbalance(double price) bool Check if buy imbalance exists at price.
is_sell_imbalance(double price) bool Check if sell imbalance exists at price.
Has2NdSlotBuyImbalance(MasterInstrument, tickStep) bool Check for 2nd slot buy imbalance.
Has2NdSlotSellImbalance(MasterInstrument, tickStep) bool Check for 2nd slot sell imbalance.
HasBuyVolumeSequencing() bool Check for bullish volume sequencing.
HasSellVolumeSequencing() bool Check for bearish volume sequencing.
IsVisible(Indicator) bool Check if bar is visible on chart.
Aggregate(double rawPrice) double Aggregate raw price to tick group.

6. IImbalance Interface

Used by ReversalImbalances, InverseImbalances, and volume sequence objects.

Property Type Description
PriceLow double Low price of the imbalance zone.
PriceHigh double High price of the imbalance zone.
IsHigh bool Whether imbalance is at bar high area.
StartDate, EndDate DateTime Time boundaries of the imbalance.
StartBar, EndBar int Bar index boundaries.
IsBroken bool Whether the imbalance has been broken.
TestedLow, TestedHigh bool Whether zone low/high has been tested.
IsBuyImbalance bool Whether it is a buy-side imbalance.

7. Enumerations Reference

FootPrintBarTypes

Value Description
None No footprint bars displayed.
AllBars Show footprint for all bars.
CurrentBarOnly Show footprint for current bar only.

FootPrintDeltaCalculation

Value Description
BidAsk Delta calculated from bid/ask volume.
UpDownTick Delta calculated from up/down ticks.
TickCount Delta calculated from tick count.

StackedImbalancesTypes

Value Description
All Show all stacked imbalances.
AtCandleHighLow Only at bar high/low.

FootPrintBarExtend

Value Description
Bars Extend for a fixed number of bars.
UntilBroken Extend until the level is broken.
UntilTested Extend until the level is tested.

FootPrintAlertType (All Alerts)

None, Absorption, BigDelta, BigImbalance, BullishBearishPoc, ConsecutivePoc, ConsecutiveImbalances, AboveBelowPoc, DeltaCloseAtMinMaxDelta, DeltaContinuousPoc, DeltaDrop, DeltaDivergence, DeltaFlip, DeltaReversal, DeltaRise, DeltaSlingshot, DeltaSweep, DeltaTail, DeltaTrap, EngulfingValueArea, ExhaustionPrint, FadingMomentum, FatPrint, InverseImbalance, MarketSweep, MultipleImbalances, OversizedImbalance, PocGap, Ratio, ReversalImbalance, StackedImbalance, StoppingVolume, SecondSlotImbalance, ThinPrint, TrappedTraders, UnfinishedBusiness, ValueAreaGap, VolumeSequencing, ZeroPrint, DeltaPriceDivergence, PocMomentumWave, BidAskFade, PassiveAbsorption, Custom1-Custom5.

8. Signals & Concepts Explained

Delta Signals

Delta = Ask volume minus Bid volume. Positive delta = net buying aggression, negative = net selling.

  • Delta Rise/Drop - Delta increasing or decreasing, showing momentum direction.
  • Delta Flip - Delta changes sign. Can signal trend exhaustion.
  • Delta Divergence - Price makes a new high/low but delta does not confirm.
  • Delta Tail - Delta reverses significantly from its intra-bar extreme. Shows rejection.
  • Delta Reversal - Complete reversal of delta direction within the bar.
  • Delta Sweep - Delta sweeps from minimum to maximum (or vice versa) within one bar.
  • Delta Slingshot - Delta reverses then accelerates past its prior extreme. Momentum breakout signal.
  • Delta Trap - Traders caught on the wrong side. E.g., heavy buying but price drops.

Imbalances

An imbalance at a price level means one side has significantly more volume than the other side at the adjacent price.

  • Buy Imbalance - Ask volume at price X >> Bid volume at price X-1 (by ratio).
  • Sell Imbalance - Bid volume at price X >> Ask volume at price X+1 (by ratio).
  • Stacked Imbalances - 3+ consecutive imbalances in the same direction. Strong aggressive signal.
  • Reversal Imbalance - Imbalance that forms at the point of price reversal.
  • Inverse Imbalance - Imbalance in the opposite direction of the current trend.

Volume Profile Concepts

  • POC (Point of Control) - Price level with the most volume. Fair value for that bar/session.
  • Value Area - Price range containing ~70% of the bar's volume. VAH = top, VAL = bottom.
  • Unfinished Business - Zero bid or zero ask at bar high/low = auction not complete. Price tends to revisit.
  • Thin Prints - Very low volume at a price level. Price moved through quickly, may revisit.
  • Zero Prints - No volume at a level. Price gapped through, very likely to revisit.
  • Fat Prints - Unusually high volume at a level. Strong acceptance/rejection zone.

Absorption & Stopping Volume

  • Absorption - Passive limit orders absorbing aggressive market orders. Price stops moving despite heavy volume.
  • Stopping Volume - High volume at bar extreme that stops the move.
  • Passive Absorption - Specifically detecting passive limit order absorption patterns.

9. Sample Strategies - Plots API

All strategies below include required boilerplate:

AddDataSeries(BarsPeriodType.Tick, 1) in Configure, BarsInProgress != 0 guard in OnBarUpdate, and order submission on the tick series for immediate fills.

Strategy 1: Stacked Imbalance Breakout

#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
using NinjaTrader.NinjaScript.Indicators.TDU;
#endregion

namespace NinjaTrader.NinjaScript.Strategies
{
    public class StackedImbalanceStrategy : Strategy
    {
        private TDUFootPrintPlots _fp;

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name = "Stacked Imbalance Breakout";
                Calculate = Calculate.OnEachTick;
                EntriesPerDirection = 1;
                StopTargetHandling = StopTargetHandling.PerEntryExecution;
            }
            else if (State == State.Configure)
            {
                AddDataSeries(BarsPeriodType.Tick, 1);
            }
            else if (State == State.DataLoaded)
            {
                _fp = TDUFootPrintPlots();
            }
        }

        protected override void OnBarUpdate()
        {
            if (BarsInProgress != 0) return;
            if (CurrentBar < 10) return;

            double stackedBuys  = _fp.StackedBuyImbalances[0];
            double stackedSells = _fp.StackedSellImbalances[0];
            double delta        = _fp.Delta[0];

            if (stackedBuys >= 1 && delta > 0 && Position.MarketPosition == MarketPosition.Flat)
            {
                EnterLong(1, 1, "StackedBuy");
                SetStopLoss("StackedBuy", CalculationMode.Ticks, 20, false);
                SetProfitTarget("StackedBuy", CalculationMode.Ticks, 40);
            }

            if (stackedSells >= 1 && delta < 0 && Position.MarketPosition == MarketPosition.Flat)
            {
                EnterShort(1, 1, "StackedSell");
                SetStopLoss("StackedSell", CalculationMode.Ticks, 20, false);
                SetProfitTarget("StackedSell", CalculationMode.Ticks, 40);
            }
        }
    }
}

Strategy 2: Delta Divergence Reversal

#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
using NinjaTrader.NinjaScript.Indicators.TDU;
#endregion

namespace NinjaTrader.NinjaScript.Strategies
{
    public class DeltaDivergenceReversal : Strategy
    {
        private TDUFootPrintPlots _fp;

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name = "Delta Divergence Reversal";
                Calculate = Calculate.OnEachTick;
                EntriesPerDirection = 1;
            }
            else if (State == State.Configure)
            {
                AddDataSeries(BarsPeriodType.Tick, 1);
            }
            else if (State == State.DataLoaded)
            {
                _fp = TDUFootPrintPlots();
            }
        }

        protected override void OnBarUpdate()
        {
            if (BarsInProgress != 0) return;
            if (CurrentBar < 20 || Position.MarketPosition != MarketPosition.Flat) return;

            bool hasDivergence = _fp.DeltaDivergence[0] == 1;
            double absorption  = _fp.Absorption[0];
            double stoppingVol = _fp.StoppingVolume[0];
            double delta       = _fp.Delta[0];

            // Bullish reversal
            if (hasDivergence && delta < 0 && (absorption == 1 || stoppingVol == 1))
            {
                EnterLong(1, 1, "DivLong");
                SetStopLoss(CalculationMode.Ticks, 30);
                SetProfitTarget(CalculationMode.Ticks, 45);
            }

            // Bearish reversal
            if (hasDivergence && delta > 0 && (absorption == -1 || stoppingVol == -1))
            {
                EnterShort(1, 1, "DivShort");
                SetStopLoss(CalculationMode.Ticks, 30);
                SetProfitTarget(CalculationMode.Ticks, 45);
            }
        }
    }
}

Strategy 3: Exhaustion Print + Trapped Traders

#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
using NinjaTrader.NinjaScript.Indicators.TDU;
#endregion

namespace NinjaTrader.NinjaScript.Strategies
{
    public class ExhaustionTrappedStrategy : Strategy
    {
        private TDUFootPrintPlots _fp;

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name = "Exhaustion + Trapped Traders";
                Calculate = Calculate.OnEachTick;
            }
            else if (State == State.Configure)
                AddDataSeries(BarsPeriodType.Tick, 1);
            else if (State == State.DataLoaded)
                _fp = TDUFootPrintPlots();
        }

        protected override void OnBarUpdate()
        {
            if (BarsInProgress != 0) return;
            if (CurrentBar < 10 || Position.MarketPosition != MarketPosition.Flat) return;

            // Bullish: sellers exhausted + trapped sellers
            if (_fp.BearishExhaustionPrint[0] == -1 && _fp.BullishTrappedTraders[0] == 1)
            {
                EnterLong(1, 1, "ExhaustLong");
                SetStopLoss(CalculationMode.Ticks, 25);
                SetProfitTarget(CalculationMode.Ticks, 50);
            }

            // Bearish: buyers exhausted + trapped buyers
            if (_fp.BullishExhaustionPrint[0] == 1 && _fp.BearishTrappedTraders[0] == -1)
            {
                EnterShort(1, 1, "ExhaustShort");
                SetStopLoss(CalculationMode.Ticks, 25);
                SetProfitTarget(CalculationMode.Ticks, 50);
            }
        }
    }
}

Strategy 4: Session-Filtered Volume Profile

#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
using NinjaTrader.NinjaScript.Indicators.TDU;
#endregion

namespace NinjaTrader.NinjaScript.Strategies
{
    public class SessionVPStrategy : Strategy
    {
        private TDUFootPrintPlots _fp;

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name = "Session VP Strategy";
                Calculate = Calculate.OnEachTick;
            }
            else if (State == State.Configure)
                AddDataSeries(BarsPeriodType.Tick, 1);
            else if (State == State.DataLoaded)
                _fp = TDUFootPrintPlots();
        }

        protected override void OnBarUpdate()
        {
            if (BarsInProgress != 0) return;
            if (CurrentBar < 20) return;
            if (_fp.CurrentSession[0] != 2) return; // NY session only
            if (Position.MarketPosition != MarketPosition.Flat) return;

            double vpVAH = _fp.VolumeProfileValueAreaHigh[0];
            double vpVAL = _fp.VolumeProfileValueAreaLow[0];
            double vpPOC = _fp.VolumeProfilePOC[0];

            // Long: price bounces off VP VAL with positive delta
            if (Low[0] <= vpVAL && Close[0] > vpVAL && _fp.Delta[0] > 0)
            {
                EnterLong(1, 1, "VPBounce");
                SetStopLoss(CalculationMode.Price, vpVAL - 10 * TickSize);
                SetProfitTarget(CalculationMode.Price, vpPOC);
            }

            // Short: price rejected at VP VAH with negative delta
            if (High[0] >= vpVAH && Close[0] < vpVAH && _fp.Delta[0] < 0)
            {
                EnterShort(1, 1, "VPReject");
                SetStopLoss(CalculationMode.Price, vpVAH + 10 * TickSize);
                SetProfitTarget(CalculationMode.Price, vpPOC);
            }
        }
    }
}

10. Sample Strategies - IFootPrintBar API

Strategy 5: Price-Level Imbalance Scanner

#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
using NinjaTrader.NinjaScript.Indicators.TDU;
#endregion

namespace NinjaTrader.NinjaScript.Strategies
{
    public class PriceLevelImbalanceStrategy : Strategy
    {
        private TDUFootPrintPlots _fp;
        private double _imbalanceRatio = 3.0;

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name = "Price Level Imbalance Scanner";
                Calculate = Calculate.OnEachTick;
            }
            else if (State == State.Configure)
                AddDataSeries(BarsPeriodType.Tick, 1);
            else if (State == State.DataLoaded)
                _fp = TDUFootPrintPlots();
        }

        protected override void OnBarUpdate()
        {
            if (BarsInProgress != 0) return;
            if (CurrentBar < 10) return;

            var bar = _fp.GetFootPrintBar(0);
            if (bar == null) return;

            double strongestBuyLevel = 0, strongestBuyRatio = 0;
            double strongestSellLevel = 0, strongestSellRatio = 0;

            foreach (var kvp in bar.Asks)
            {
                double price = kvp.Key;
                double askVol = kvp.Value;
                double bidVol = bar.Bids.ContainsKey(price) ? bar.Bids[price] : 0;

                if (bidVol > 0 && askVol / bidVol > strongestBuyRatio)
                {
                    strongestBuyRatio = askVol / bidVol;
                    strongestBuyLevel = price;
                }
                if (askVol > 0 && bidVol / askVol > strongestSellRatio)
                {
                    strongestSellRatio = bidVol / askVol;
                    strongestSellLevel = price;
                }
            }

            if (Position.MarketPosition != MarketPosition.Flat) return;

            if (strongestBuyRatio >= _imbalanceRatio
                && strongestBuyLevel <= bar.Low + 3 * TickSize
                && bar.Delta > 0)
            {
                EnterLong(1, 1, "ImbalanceLong");
                SetStopLoss(CalculationMode.Ticks, 20);
                SetProfitTarget(CalculationMode.Ticks, 40);
            }

            if (strongestSellRatio >= _imbalanceRatio
                && strongestSellLevel >= bar.High - 3 * TickSize
                && bar.Delta < 0)
            {
                EnterShort(1, 1, "ImbalanceShort");
                SetStopLoss(CalculationMode.Ticks, 20);
                SetProfitTarget(CalculationMode.Ticks, 40);
            }
        }
    }
}

Strategy 6: Multi-Signal Confluence

#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
using NinjaTrader.NinjaScript.Indicators.TDU;
#endregion

namespace NinjaTrader.NinjaScript.Strategies
{
    public class MultiSignalConfluenceStrategy : Strategy
    {
        private TDUFootPrintPlots _fp;
        [NinjaScriptProperty]
        public int MinConfluenceScore { get; set; } = 3;

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name = "Multi-Signal Confluence";
                Calculate = Calculate.OnEachTick;
            }
            else if (State == State.Configure)
                AddDataSeries(BarsPeriodType.Tick, 1);
            else if (State == State.DataLoaded)
                _fp = TDUFootPrintPlots();
        }

        protected override void OnBarUpdate()
        {
            if (BarsInProgress != 0) return;
            if (CurrentBar < 20 || Position.MarketPosition != MarketPosition.Flat) return;

            var bar = _fp.GetFootPrintBar(0);
            if (bar == null) return;

            int bullScore = 0;
            if (bar.StackedBuyImbalances.Count > 0)  bullScore++;
            if (bar.HasBullishAbsorption)             bullScore++;
            if (bar.HasBullishStoppingVolume)          bullScore++;
            if (bar.HasBullishTrappedTraders)          bullScore++;
            if (bar.HasBullishDeltaDivergence)         bullScore++;
            if (bar.OpenAndCloseAbovePOC)              bullScore++;
            if (bar.HasBuyVolumeSequencing())          bullScore++;
            if (bar.HasBullishUnfinishedBusiness)      bullScore++;

            int bearScore = 0;
            if (bar.StackedSellImbalances.Count > 0) bearScore++;
            if (bar.HasBearishAbsorption)             bearScore++;
            if (bar.HasBearishStoppingVolume)          bearScore++;
            if (bar.HasBearishTrappedTraders)          bearScore++;
            if (bar.HasBearishDeltaDivergence)         bearScore++;
            if (bar.OpenAndCloseBelowPOC)              bearScore++;
            if (bar.HasSellVolumeSequencing())         bearScore++;
            if (bar.HasBearishUnfinishedBusiness)      bearScore++;

            if (bullScore >= MinConfluenceScore && bar.Delta > 0)
            {
                EnterLong(1, 1, "Confluence");
                SetStopLoss(CalculationMode.Ticks, 30);
                SetProfitTarget(CalculationMode.Ticks, 60);
            }
            else if (bearScore >= MinConfluenceScore && bar.Delta < 0)
            {
                EnterShort(1, 1, "Confluence");
                SetStopLoss(CalculationMode.Ticks, 30);
                SetProfitTarget(CalculationMode.Ticks, 60);
            }
        }
    }
}

Strategy 7: Unfinished Business Magnet

#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
using NinjaTrader.NinjaScript.Indicators.TDU;
#endregion

namespace NinjaTrader.NinjaScript.Strategies
{
    public class UnfinishedBusinessMagnet : Strategy
    {
        private TDUFootPrintPlots _fp;

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name = "Unfinished Business Magnet";
                Calculate = Calculate.OnEachTick;
            }
            else if (State == State.Configure)
                AddDataSeries(BarsPeriodType.Tick, 1);
            else if (State == State.DataLoaded)
                _fp = TDUFootPrintPlots();
        }

        protected override void OnBarUpdate()
        {
            if (BarsInProgress != 0) return;
            if (CurrentBar < 20 || Position.MarketPosition != MarketPosition.Flat) return;

            var bar = _fp.GetFootPrintBar(0);
            var prevBar = _fp.GetFootPrintBar(1);
            if (bar == null || prevBar == null) return;

            // Bullish: previous had unfinished business at high, enter long
            if (prevBar.HasBearishUnfinishedBusiness
                && bar.Delta > 0
                && bar.StackedBuyImbalances.Count > 0)
            {
                EnterLong(1, 1, "UFBLong");
                SetStopLoss(CalculationMode.Ticks, 20);
                SetProfitTarget(CalculationMode.Price, prevBar.High);
            }

            // Bearish: previous had unfinished business at low, enter short
            if (prevBar.HasBullishUnfinishedBusiness
                && bar.Delta < 0
                && bar.StackedSellImbalances.Count > 0)
            {
                EnterShort(1, 1, "UFBShort");
                SetStopLoss(CalculationMode.Ticks, 20);
                SetProfitTarget(CalculationMode.Price, prevBar.Low);
            }
        }
    }
}

Strategy 8: CSV Data Export (Utility)

#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
using NinjaTrader.NinjaScript.Indicators.TDU;
#endregion

// Inside OnBarUpdate (after BarsInProgress == 0 check):
var fp = _fp.GetFootPrintBar(0);
if (fp == null) return;

// In State.Realtime, export all bars to CSV (oldest to newest):
using var file = System.IO.File.CreateText(@"c:\footprint_export.csv");
file.WriteLine("Date,Open,High,Low,Close,Volume,Delta,MinDelta,MaxDelta,POC,"
    + "StackedBuys,StackedSells,BuyVolSeq,SellVolSeq");

for (var i = CurrentBars[0]; i >= 0; i--)
{
    var b = _fp.GetFootPrintBar(i);
    if (b == null) continue;
    file.WriteLine(string.Join(",",
        b.Time, b.Open, b.High, b.Low, b.Close,
        b.Volume, b.Delta, b.MinDelta, b.MaxDelta, b.POC,
        b.StackedBuyImbalances.Count > 0 ? 1 : 0,
        b.StackedSellImbalances.Count > 0 ? 1 : 0,
        b.HasBuyVolumeSequencing() ? 1 : 0,
        b.HasSellVolumeSequencing() ? 1 : 0
    ));
}

11. Tips, Gotchas & Best Practices

Always Add the Tick Data Series

Your strategy/indicator must call AddDataSeries(BarsPeriodType.Tick, 1) in State.Configure. The footprint indicator does NOT add this when hosted inside another strategy or indicator.

Guard with BarsInProgress

The tick data series fires OnBarUpdate on every tick (BarsInProgress == 1). Your strategy logic should only run on your primary series: if (BarsInProgress != 0) return;

Submit Orders on Tick Series

To get immediate fills instead of waiting for the next primary bar, submit orders on BarsInProgress = 1 (the tick series). Use the overload: EnterLong(1, 1, "SignalName") where the first parameter is quantity and second is the BarsInProgress index.

No Need to Call .Update()

You do not need to call _fp.Update() manually. GetFootPrintBar() calls Update() internally before returning data, and NinjaTrader's plot indexers (e.g. _fp.Delta[0]) trigger Update() automatically when accessed.

Always Check for Null

When using GetFootPrintBar(), always check for null. Early bars may not have footprint data.

Plot Value Conventions Differ!

Some boolean plots use 0/1, others use -1/0/1 for directional signals. For example, BearishExhaustionPrint returns -1 (not 1) when active.

Accessing Historical Bars

Both APIs use the same bars-ago convention: _fp.Delta[0] = current bar, _fp.Delta[1] = previous. Likewise, GetFootPrintBar(0) = current bar, GetFootPrintBar(1) = previous bar.

Performance Considerations
  • The Plots indicator sets MaximumBarsLookBack = Infinite for full history.
  • Iterating over Asks/Bids dictionaries every tick can be expensive. Cache results when possible.
Combining Signals for Higher Probability
  • Entry confirmation: Stacked imbalance + positive delta + absorption
  • Reversal setup: Delta divergence + exhaustion print + stopping volume
  • Trend continuation: Volume sequencing + delta rise + open/close above POC
  • Session filter: Use CurrentSession to trade only during active sessions
Algo Studio Pro

All 101 plots are available in Algo Studio Pro as standard NinjaTrader plots. Add the "TDU Footprint Plots" indicator and reference plots by name. No coding required for basic strategies.

Quick Reference: How to Choose Your API

Need Use
Simple signal checks (delta rise, stacked imbalances, etc.) Plots API
Volume at specific price levels IFootPrintBar
Custom imbalance ratio calculations IFootPrintBar
Algo Studio Pro (strategy builder) Plots API (only option)
Scoring/combining many signals IFootPrintBar (cleaner code)
Checking imbalance zones (broken, tested) IFootPrintBar + IImbalance
Export data to CSV/database IFootPrintBar