Skip to content

Add WaveTrend Oscillator indicator#9424

Closed
AlexCatarino wants to merge 1 commit intoQuantConnect:masterfrom
AlexCatarino:feature-6411-wavetrend-oscillator
Closed

Add WaveTrend Oscillator indicator#9424
AlexCatarino wants to merge 1 commit intoQuantConnect:masterfrom
AlexCatarino:feature-6411-wavetrend-oscillator

Conversation

@AlexCatarino
Copy link
Copy Markdown
Member

Description

Implements WaveTrendOscillator (a BarIndicator consuming IBaseDataBar) per the linked issue. Adds the indicator class, the WTO helper on QCAlgorithm.Indicators.cs, unit tests inheriting CommonIndicatorTests<IBaseDataBar>, and the reference CSV spy_wto.csv under Tests/TestData/.

The indicator produces two lines:

  • WT1 (primary Current.Value) — EMA(CI, averagePeriod)
  • WT2 (exposed via the Signal sub-indicator) — SMA(WT1, signalPeriod)

where

HLC3 = (High + Low + Close) / 3
ESA  = EMA(HLC3, channelPeriod)
D    = EMA(|HLC3 - ESA|, channelPeriod)   # fed only after ESA is ready
CI   = (HLC3 - ESA) / (0.015 * D)

IsReady tracks Signal.IsReady; WarmUpPeriod = 2 * channelPeriod + averagePeriod + signalPeriod - 3 (42 with the (10, 21, 4) defaults from the original LazyBear TradingView script). The division is guarded so that bars with no intra-channel variation (e.g. flat volume-renko bars) return 0 instead of dividing by a near-zero D.

Related Issue

Closes #6411

Motivation and Context

Requested via #6411 (and the linked forum thread) to bring the WaveTrend Oscillator — popularized by LazyBear on TradingView — to LEAN's indicator library. It is a widely used momentum oscillator for spotting overbought/oversold conditions and WT1/WT2 crossovers; users following TradingView-style strategies currently have no built-in equivalent and have to re-implement it in every algorithm.

Requires Documentation Change

Yes — add the following entry to Documentation/Resources/indicators/IndicatorImageGenerator.py (in the indicators dict):

'Wave-Trend-Oscillator': IndicatorInfo(
    WaveTrendOscillator(10, 21, 4),
    'WaveTrendOscillator(10, 21, 4)',
    'WTO(_symbol, 10, 21, 4)',
    'self.wto(self._symbol, 10, 21, 4)'
),

All parameters are integer periods, so no m suffix is required on the C# entries.

How Has This Been Tested?

  • dotnet build QuantConnect.Lean.sln — 0 errors.
  • dotnet test Tests/QuantConnect.Tests.csproj --filter "FullyQualifiedName~WaveTrendOscillatorTests"15/15 passing.
  • Reference values in spy_wto.csv were generated via TA-Lib (talib.EMA, talib.SMA) from the public SPY daily data shipped in Data/equity/usa/daily/spy.zip, matching the generator script posted by @LouisSzeto in the issue comment thread. CommonIndicatorTests.ComparesAgainstExternalData verifies LEAN's WT1 matches within 1e-3 and the additional ComparesWithExternalDataSignal test verifies WT2.

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist:

  • My code follows the code style of this project.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • My branch follows the naming convention feature-<N>-<description>

Implements WaveTrendOscillator (BarIndicator consuming IBaseDataBar) per
issue QuantConnect#6411. Adds the indicator class, the WTO helper on
QCAlgorithm.Indicators.cs, unit tests inheriting
CommonIndicatorTests<IBaseDataBar>, and the reference CSV spy_wto.csv
under Tests/TestData/.

The indicator produces two lines:
- WT1 (primary Current.Value) -- EMA(CI, averagePeriod)
- WT2 (exposed via the Signal sub-indicator) -- SMA(WT1, signalPeriod)

where

    HLC3 = (High + Low + Close) / 3
    ESA  = EMA(HLC3, channelPeriod)
    D    = EMA(|HLC3 - ESA|, channelPeriod)   (fed only after ESA is ready)
    CI   = (HLC3 - ESA) / (0.015 * D)

IsReady tracks Signal.IsReady; WarmUpPeriod =
2 * channelPeriod + averagePeriod + signalPeriod - 3 (42 with the
(10, 21, 4) defaults from the original LazyBear TradingView script). The
division is guarded so that bars with no intra-channel variation (e.g.
flat volume-renko bars) return 0 instead of dividing by a near-zero D.

Reference values were generated via TA-Lib (talib.EMA, talib.SMA) on the
public SPY daily data shipped in Data/equity/usa/daily/spy.zip, matching
the generator script from the issue comment thread.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@AlexCatarino AlexCatarino deleted the feature-6411-wavetrend-oscillator branch April 21, 2026 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement WaveTrend Oscillator Indicator

1 participant