A charting method that organizes price by how much time the market spent at each level, building the familiar bell-shaped profile.
Market Profile is a charting technique developed by J. Peter Steidlmayer at the Chicago Board of Trade in the 1980s. Instead of plotting price against time left-to-right, it stacks time against price: each half-hour period of the session is assigned a letter (a Time Price Opportunity, or TPO), and every price the market touched during that period gets that letter printed next to it. Stacking the letters produces a horizontal distribution showing where the market spent the most and least time. This is the key difference from Volume Profile, which people often confuse it with: Market Profile measures time at price (how long the market traded at each level), while Volume Profile measures volume at price (how many contracts or shares actually changed hands there). The two often look similar but can diverge meaningfully — a level can be touched for many periods on thin volume, or absorb heavy volume in a single brief visit. Market Profile is a way of organizing what already happened in a session; it is descriptive, not predictive, and is presented here for education only. No charting method forecasts price, and all trading carries risk of loss.
A session is divided into fixed periods, traditionally 30 minutes each, labeled A, B, C and so on. For each period, one letter is printed at every price increment the market traded through. As the session progresses, letters accumulate: prices visited in many periods build long horizontal rows, and prices visited briefly show only one or two letters. From this distribution several standard references are derived. The Point of Control (POC) is the price with the most TPOs — where the market spent the most time. The Value Area is the range around the POC containing roughly 70% of all TPOs (an analogy to one standard deviation of a normal distribution). Single prints, where only one letter appears, mark levels the market moved through quickly. The Initial Balance is the range of the first two periods. One honesty note that matters for platform users: most charting platforms, including TradingView, do not carry true TPO period data for every instrument — profile tools there frequently reconstruct an approximation from bar highs and lows at some chart resolution, or substitute a volume-based profile entirely. An approximation built from bar ranges assumes the market traded every price within each bar's range for the whole bar, which is not literally true, so reconstructed profiles are estimates, not exchange-grade TPO records.
The traditional configuration is 30-minute TPO periods over one full exchange session, with a 70% Value Area. Intraday traders sometimes use shorter periods (such as 15 minutes) for finer profiles, or merge multiple days into composite profiles for longer-term structure. The price row size (tick increment per row) materially changes the profile's shape — coarse rows smooth detail away, fine rows fragment it — so row sizing should be stated explicitly when comparing profiles. On platforms without true TPO data, check whether the tool is building the profile from lower-timeframe bar ranges and at what resolution, because that choice changes every level the profile reports.
//@version=6
indicator("Time-at-Price POC (TPO approximation)", overlay = true)
// Approximates a time-at-price profile from bar ranges over a lookback
// window. Honest caveat: this assumes price traded through each bar's
// full range, so it is an estimate, not exchange-grade TPO data.
lookback = input.int(120, "Lookback Bars", minval = 10)
rows = input.int(24, "Price Rows", minval = 5, maxval = 50)
hi = ta.highest(high, lookback)
lo = ta.lowest(low, lookback)
step = (hi - lo) / rows
float pocPrice = na
int bestCount = 0
if step > 0
for i = 0 to rows - 1
rowLo = lo + step * i
rowHi = rowLo + step
int cnt = 0
for j = 0 to lookback - 1
if high[j] >= rowLo and low[j] <= rowHi
cnt += 1
if cnt > bestCount
bestCount := cnt
pocPrice := rowLo + step / 2
plot(pocPrice, "Time-at-price POC", color = color.orange, linewidth = 2)Pro tip: Before leaning on any profile level, find out exactly what your platform is counting: true 30-minute TPO letters, a bar-range reconstruction, or volume at price. A POC computed three different ways gives three different prices, and treating an approximation as exchange data is how phantom 'key levels' get traded. Note also that the developing profile migrates all session, so intraday POC reads are provisional. This is educational material only, not financial advice — profiles describe past trading, and all trading carries risk of loss.
Educational only — not financial advice, not a recommendation to trade. No indicator is predictive; trading involves substantial risk of loss.