Twiggs Money Flow: gaps and buying pressure
Twiggs Money Flow (TMF) estimates buying or selling pressure from closing position and volume. It extends each bar's range to include the previous close, then smooths flow and volume separately. That gap adjustment can reverse a bar's contribution compared with Chaikin Money Flow (CMF).
Same gap bar, opposite contributions
Previous close 100; high 110; low 106; close 107. TMF's multiplier is +0.4. CMF's is -0.5. The full indicator also depends on earlier bars and volume.
Educational calculations, not investment advice. TMF is a price and volume proxy, not measured fund flows or a return forecast.
The formula and its smoothing definition
Colin Twiggs' published method uses true-range bounds and Wilder smoothing. Let Cprev be the previous close and N the number of chart bars:
TRH = max(high, Cprev)
TRL = min(low, Cprev)
m = (2 × close − TRH − TRL) / (TRH − TRL)
F = m × volume
Seed SF = sum(first N eligible F values)
Seed SV = sum(the same N volume values)
Next SF = SFprev × (N − 1) / N + F
Next SV = SVprev × (N − 1) / N + volume
TMF = SF / SVThe example below uses a ratio scale: 0.25 is 25% on a percentage display. Dividing both smoothed sums by N leaves their ratio unchanged. An equivalent Wilder average has alpha = 1/N; a standard EMA of length N uses alpha = 2/(N+1). They are different filters.
Seed choice matters. A recurrence that starts both sums at zero and plots immediately does not match an N-bar sum seed at the beginning of the chart. This example waits for the seed and explicitly restarts it after invalid data.
For valid OHLC and nonnegative volume, each multiplier lies between -1 and +1. Positive smoothing weights make TMF a weighted average in that same interval, provided its denominator is positive. This mathematical bound does not make +0.5 an automatic sell level or -0.5 an automatic buy level.
A gap example you can recalculate
These are synthetic bars, not a backtest. Volume uses the same arbitrary units throughout. Use N = 3 for this calculation; the copyable script defaults to 21. The first row has a known prior close of 100.
| Bar | Prev close | High | Low | Close | Volume | TMF m | TMF flow | CMF flow |
|---|---|---|---|---|---|---|---|---|
| 1: gap up | 100 | 110 | 106 | 107 | 1,200 | +0.4 | +480 | -600 |
| 2 | 107 | 109 | 105 | 106 | 600 | -0.5 | -300 | -300 |
| 3: seed | 106 | 108 | 104 | 107 | 900 | +0.5 | +450 | +450 |
| 4: update | 107 | 109 | 105 | 105 | 900 | -1.0 | -900 | -900 |
On bar 1, TRH = 110 and TRL = 100, so m = (214 − 110 − 100)/10 = +0.4 and flow = +480. CMF instead uses (214 − 110 − 106)/4 = -0.5 and flow = -600. The close is below the current bar's midpoint but above the midpoint of the range extended to the prior close.
At bar 3, TMF seeds SF = 480 − 300 + 450 = 630 and SV = 1,200 + 600 + 900 = 2,700. TMF = 630/2,700 = +0.233333. Three-bar CMF is (-600 − 300 + 450)/2,700 = -0.166667.
At bar 4, TMF updates SF = 630 × 2/3 − 900 = -480 and SV = 2,700 × 2/3 + 900 = 2,700. TMF = -0.177778. CMF drops bar 1 entirely: (-300 + 450 − 900)/(600 + 900 + 900) = -0.3125.
The sign disagreement at bar 3 and the different bar-4 values follow from the formulas. They do not show that one indicator predicts the next price move better.
TMF versus CMF: what actually changes
| Property | TMF | CMF |
|---|---|---|
| Range for each contribution | Current high/low extended to the previous close | Current high minus current low |
| History weighting | Wilder recurrence after an initial seed | Equal weights inside a rolling window |
| A large bar ages | Its influence decays gradually | Its contribution leaves the window at once |
| No gap outside current range | Same raw multiplier as CMF | Same raw multiplier as TMF |
| What neither measures | Actual cash inflows or buyer identity | Actual cash inflows or buyer identity |
Even without gaps, final readings can differ because the smoothing differs. For the rolling-window calculation, see the CMF guide and TradingView's formula.
Pine Script v6 with explicit startup and missing-data rules
Paste this indicator into TradingView's Pine Editor, add it to a standard candle chart, and check the feed's volume type. It plots the ratio, a zero line and confirmed crossover markers. It places no trades. Create a TradingView alert from one of its named conditions if you want notifications.
//@version=6
indicator("Twiggs Money Flow: explicit seed", shorttitle="TMF", overlay=false)
length = input.int(21, "Wilder length (bars)", minval=1)
// Colin Twiggs' true-range flow and Wilder-smoothed sum ratio.
// Seed with length consecutive eligible bars; do not invent missing volume.
validPrices = not na(close[1]) and not na(high) and not na(low) and not na(close) and high >= low and close >= low and close <= high
validVolume = not na(volume) and volume >= 0
eligible = validPrices and validVolume
trHigh = math.max(high, close[1])
trLow = math.min(low, close[1])
trRange = trHigh - trLow
multiplier = trRange == 0 ? 0.0 : (2.0 * close - trHigh - trLow) / trRange
flow = multiplier * volume
var int seedCount = 0
var float flowSum = 0.0
var float volumeSum = 0.0
if not eligible
seedCount := 0
flowSum := 0.0
volumeSum := 0.0
else if seedCount < length
flowSum += flow
volumeSum += volume
seedCount += 1
else
decay = (length - 1.0) / length
flowSum := decay * flowSum + flow
volumeSum := decay * volumeSum + volume
ready = eligible and seedCount == length and volumeSum > 0
float tmf = ready ? flowSum / volumeSum : na
crossUp = ta.crossover(tmf, 0.0)
crossDown = ta.crossunder(tmf, 0.0)
confirmedUp = barstate.isconfirmed and volume > 0 and crossUp
confirmedDown = barstate.isconfirmed and volume > 0 and crossDown
plot(tmf, "TMF (ratio)", color=color.blue, linewidth=2, style=plot.style_linebr)
hline(0, "Zero", color=color.gray)
plotshape(confirmedUp, title="Positive cross", style=shape.triangleup, location=location.bottom, color=color.green, size=size.tiny)
plotshape(confirmedDown, title="Negative cross", style=shape.triangledown, location=location.top, color=color.red, size=size.tiny)
alertcondition(confirmedUp, "TMF positive cross", "TMF crossed above zero on a closed bar with positive volume.")
alertcondition(confirmedDown, "TMF negative cross", "TMF crossed below zero on a closed bar with positive volume.")
var table status = table.new(position.top_right, 1, 1)
if barstate.islast
message = not eligible ? "Invalid price/volume: seed reset" : not ready ? "Waiting for seed or positive volume sum" : volume == 0 ? "Zero volume: no new flow evidence" : "TMF ready: check this feed's volume type"
table.cell(status, 0, 0, message, text_color=color.white, bgcolor=color.new(color.black, 15))Copy Pine Script
- The first chart bar has no previous close and is excluded. After N eligible bars, both sums are seeded over identical observations.
- Missing prices, malformed ranges, or missing/negative volume reset the seed. The script does not replace unavailable volume with 1 or fabricate a neutral reading.
- A zero true range gets a zero multiplier but retains its reported volume weight. This is an explicit convention for an otherwise undefined division.
- Zero-volume bars contribute zero to both sums. After startup, with N > 1, both sums decay equally and the ratio stays flat; an all-zero denominator returns na.
- The line updates intrabar. Markers and alert conditions require
barstate.isconfirmedand positive current volume. Closing confirmation does not remove feed revisions or prove profitability.
Read the feed before reading the signal
TradingView may receive traded volume, tick volume, or no volume for a symbol. Tick volume counts price updates. A numerical TMF result cannot tell you whether those updates represent executed trades. Confirm the exchange, provider, timeframe and units before comparing charts.
A trading halt can leave no chart bars for the inactive period. The recurrence does not advance through absent bars; the next observed bar uses the previous available close. If the feed inserts zero-volume bars instead, the sums decay before trading resumes. Those two histories can produce different post-halt readings. Do not fill missing sessions with invented volume.
A large volume observation can dominate the weighted history. Subsequent movement toward zero can reflect that observation losing weight as new bars arrive. Check the underlying bars before calling the slope a divergence. A zero crossing can also reverse on the next bar; no success rate is established here.
A reproducible chart check
- Match symbol, provider, standard candles, session and price adjustments. Record N and whether the display uses a ratio or percent.
- Choose a completed gap bar. Recalculate TRH, TRL, the multiplier and volume contribution, then compare with the CMF multiplier.
- Use matching starting history and seed rules. Check one update of each smoothed sum, not just the final plotted line.
- Test zero-range, zero-volume and unavailable-volume cases. A flat line during inactivity is not new evidence of buying pressure.
- For strategy testing, define entries, exits, costs and sizing before evaluating later data. A visual divergence needs a rule for when both swings become known.
Twiggs Money Flow FAQ
Turn a defined TMF rule into code
Pineify's Pine Script AI Coding Agent can help draft or modify a TMF script from explicit requirements. Supply the formula, seed, volume policy and confirmation rule, then request a syntax check and compare the output with your chart data. Syntax validation does not verify a trading edge or repair a missing data feed.
Adapt this TMF example to a 21-bar Wilder sum seed. Preserve the invalid-volume reset. Add an optional price-trend filter to closed-bar zero crossings and label filtered versus unfiltered events separately. Check the resulting Pine Script syntax.Explore Pine Script AI Coding Agent
Sources and related calculations
Sources checked October 17, 2026. Worked data is synthetic; startup and missing-data policies are stated choices for this example.
- Colin Twiggs / Incredible Charts: original TMF formula and smoothing
- TradingView: Chaikin Money Flow formula and gap limitation
- TradingView: missing, zero and tick volume
- Pine Script documentation: chart prices, volume and sessions
- Pine Script documentation: confirmed bar states
Compare CMF's rolling window, PVT's cumulative return-weighted volume, or return to TradingView indicator guides.