Series[TpoProfile] and use their Point of Control, Initial Balance, price rows and block
metadata in an indicator.
TPO is platform-provided data for the instrument of the current chart. It needs no URL or user-defined schema and does
not make the indicator an external-data indicator.
Plot the daily Point of Control
Request the profiles once in__init__, then read the most recent profile with [0] in calc:
Daily TPO Point of Control
sources.Tpo() includes the main session, pre-market and post-market by default and merges them into one profile for
each requested period. The time_frame belongs to request_series, not to the source: TPO supports day, week and
month units such as 1D, 1W and 1M.
The series is aligned by profile end time. On each chart bar, [0] is the latest TPO profile available at that time;
larger offsets access earlier profiles.
TPO always uses the instrument of the chart where the indicator is running. It cannot be used to select another
exchange or ticker.
Compare Point of Control with the Initial Balance
This example plots the distance between the Point of Control and the midpoint of the Initial Balance. Positive values place the Point of Control above that midpoint; negative values place it below.TPO Point of Control vs Initial Balance
block_size='1h' makes each TPO block one hour long, while row_size_ticks=1 fixes every profile row to one
instrument tick. Set row_size_ticks=0 (the default) to let the service choose the row size automatically. Supported
block sizes are 30m, 1h, 2h and 4h.
Use tpo_merge_sessions.MERGE_ALL to combine the selected sessions into one profile, or
tpo_merge_sessions.GROUP_BY_TYPE to keep the session types in separate profiles.
Value area
A profile does not carry its value area:TpoProfile exposes the Point of Control and the Initial Balance, but no
VAH, VAL or value-area ratio. The value area you see on the TPO chart type
is not part of the data either — the chart works it out itself, from the same rows and Point of Control you get here plus
its own Value area percentage, 70% by default. An indicator cannot read that chart setting, so whatever you build has
to name the percentage it wants.
You can derive it in the indicator instead, the same way the chart does. Every price row lists the blocks that traded
at it, so len(row.block_indexes) is the TPO count of that row. Start at the Point of Control and widen the range one
row at a time, always taking the richer of the two neighbours, until the accumulated count covers the share of the
profile you treat as value:
TPO value area high and low
- The value area stays one continuous price range. You cannot simply take the busiest rows in the profile — they have to be added outwards from the Point of Control, neighbour by neighbour.
- Ties are broken by distance. When the row above and the row below hold the same number of blocks, the chart takes the one closer to the Point of Control, and the upper row when both are equally far.
price is the lower bound of a row, so
the top of the value area is rows[high_index].price + profile.row_size if you want the row’s upper edge. And the
chart’s own value area is built with its Value area setting, which defaults to 70% — keep value_area_ratio
in step with it if the two are meant to agree.
The same rows also carry volume_buy and volume_sell, so the identical walk over volume_buy + volume_sell instead
of the block count gives you a volume-weighted value area rather than a time-based one.
For the complete source signature and all read-only profile fields, see
sources.Tpo and
TpoProfile in the Library Reference.