🎁 WIN A FREE TDU MARKET STRUCTURE INDICATOR! Join today's live 101 beginner webinar on Market Structure: BOS, ChoCh & Fibonacci Levels. Learn how the TDU Market Structure indicator automatically detects Break of Structure and Change of Character, and how to use auto-drawn Fib levels to pinpoint clean, repeatable entries in the golden zone. ⏳ Strictly limited to 100 attendees! 👉 Register Here Before It Fills Up 👈
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.
Custom2StripeExpression – Custom5StripeExpression
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:
private TDUFootPrintPlots _fp;
protected override voidOnStateChange()
{
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 voidOnBarUpdate()
{
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 voidOnStateChange()
{
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 voidOnBarUpdate()
{
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).
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;
#endregionnamespace NinjaTrader.NinjaScript.Strategies
{
public classStackedImbalanceStrategy : Strategy
{
private TDUFootPrintPlots _fp;
protected override voidOnStateChange()
{
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 voidOnBarUpdate()
{
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;
#endregionnamespace NinjaTrader.NinjaScript.Strategies
{
public classDeltaDivergenceReversal : Strategy
{
private TDUFootPrintPlots _fp;
protected override voidOnStateChange()
{
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 voidOnBarUpdate()
{
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 reversalif (hasDivergence && delta < 0 && (absorption == 1 || stoppingVol == 1))
{
EnterLong(1, 1, "DivLong");
SetStopLoss(CalculationMode.Ticks, 30);
SetProfitTarget(CalculationMode.Ticks, 45);
}
// Bearish reversalif (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;
#endregionnamespace NinjaTrader.NinjaScript.Strategies
{
public classExhaustionTrappedStrategy : Strategy
{
private TDUFootPrintPlots _fp;
protected override voidOnStateChange()
{
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 voidOnBarUpdate()
{
if (BarsInProgress != 0) return;
if (CurrentBar < 10 || Position.MarketPosition != MarketPosition.Flat) return;
// Bullish: sellers exhausted + trapped sellersif (_fp.BearishExhaustionPrint[0] == -1 && _fp.BullishTrappedTraders[0] == 1)
{
EnterLong(1, 1, "ExhaustLong");
SetStopLoss(CalculationMode.Ticks, 25);
SetProfitTarget(CalculationMode.Ticks, 50);
}
// Bearish: buyers exhausted + trapped buyersif (_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;
#endregionnamespace NinjaTrader.NinjaScript.Strategies
{
public classSessionVPStrategy : Strategy
{
private TDUFootPrintPlots _fp;
protected override voidOnStateChange()
{
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 voidOnBarUpdate()
{
if (BarsInProgress != 0) return;
if (CurrentBar < 20) return;
if (_fp.CurrentSession[0] != 2) return; // NY session onlyif (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 deltaif (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 deltaif (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;
#endregionnamespace NinjaTrader.NinjaScript.Strategies
{
public classPriceLevelImbalanceStrategy : Strategy
{
private TDUFootPrintPlots _fp;
private double _imbalanceRatio = 3.0;
protected override voidOnStateChange()
{
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 voidOnBarUpdate()
{
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;
#endregionnamespace NinjaTrader.NinjaScript.Strategies
{
public classMultiSignalConfluenceStrategy : Strategy
{
private TDUFootPrintPlots _fp;
[NinjaScriptProperty]
public int MinConfluenceScore { get; set; } = 3;
protected override voidOnStateChange()
{
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 voidOnBarUpdate()
{
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;
#endregionnamespace NinjaTrader.NinjaScript.Strategies
{
public classUnfinishedBusinessMagnet : Strategy
{
private TDUFootPrintPlots _fp;
protected override voidOnStateChange()
{
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 voidOnBarUpdate()
{
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 longif (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 shortif (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.
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.)