Skip to content

Detrended Price Oscillator (DPO)

Detrended Price Oscillator depicts the difference between price and an offset simple moving average. It is used to identify trend cycles and duration. [Discuss] 💬

csharp
// C# usage syntax
IReadOnlyList<DpoResult> results =
  bars.ToDpo(lookbackPeriods);

Parameters

paramtypedescription
lookbackPeriodsintNumber of periods (N) in the moving average. Must be greater than 0.

Historical price bars requirements

You must have at least N historical price bars to cover the warmup periods.

bars is a collection of generic TBar historical price bars. It should have a consistent frequency (day, hour, minute, etc). See the Guide for more information.

Response

csharp
IReadOnlyList<DpoResult>
  • This method returns a time series of all available indicator values for the bars provided.
  • It always returns the same number of elements as there are in the historical price bars.
  • It does not return a single incremental indicator value.
  • The first N/2-2 and last N/2+1 periods will be null since they cannot be calculated.

DpoResult

propertytypedescription
TimestampDateTimeDate from evaluated TBar
SmadoubleSimple moving average offset by N/2+1 periods
DpodoubleDetrended Price Oscillator (DPO)

Utilities

See Utilities and helpers for more information.

Chaining

This indicator may be generated from any chain-enabled indicator or method.

csharp
// example
var results = bars
    .Use(CandlePart.HL2)
    .ToDpo(..);

Results can be further processed on Dpo with additional chain-enabled indicators.

csharp
// example
var results = bars
    .ToDpo(..)
    .ToRsi(..);

See Chaining indicators for more.

Streaming

Use the buffer-style List<T> when you need incremental calculations without a hub:

csharp
DpoList dpoList = new(lookbackPeriods);

foreach (IBar bar in bars)  // simulating stream
{
  dpoList.Add(bar);
}

// based on `ICollection<DpoResult>`
IReadOnlyList<DpoResult> results = dpoList;

Subscribe to a BarHub for advanced streaming scenarios:

csharp
BarHub barHub = new();
DpoHub observer = barHub.ToDpoHub(lookbackPeriods);

foreach (IBar bar in bars)  // simulating stream
{
  barHub.Add(bar);
}

IReadOnlyList<DpoResult> results = observer.Results;

Note: DPO has a lookahead requirement (offset = N/2+1 periods), which means results are calculated when sufficient future data becomes available. This introduces a delay in real-time scenarios but maintains mathematical accuracy with the series implementation.

See Buffer lists and Stream hubs for full usage guides.