Harmonic Frequency Visualizer [BackQuant]Harmonic Frequency Visualizer
Overview
Harmonic Frequency Visualizer is a cycle-analysis and cross-asset resonance tool that uses a simplified Discrete Fourier Transform (DFT) to measure how strongly specific cycle periods are present in price. It is not a “trend indicator” and it is not trying to predict direction by itself. Its job is to quantify rhythm: which repeating periods (in bars) are currently dominant, whether those cycles are expanding or contracting (phase direction), and whether multiple instruments are sharing the same dominant periods at the same time (resonance).
This indicator has two main output modes:
Spectrum : a frequency “snapshot” showing amplitude at each tested period for up to five instruments.
Spectrogram : a history heatmap showing how the spectrum evolves through time (for the chart instrument).
Spectrum
Spectrogram
On top of that, it produces a Dominant Cycle Oscillator derived from the dominant cycle’s phase, which gives a continuous cycle position metric (peak/trough style zones) without repainting.
This is designed for traders who want cycle context the same way they want volatility context: not as a magic signal, but as structure.
What “frequency” and “cycles” mean in trading terms
A cycle period (say 21 bars) means: “a repeating pattern that tends to complete one full oscillation every 21 bars.” If price contains such a pattern, the DFT will detect a strong correlation between price and a 21-bar sine/cosine wave.
Markets do not have perfectly stable periodic motion, but they often show:
Mean-reverting swings around value.
Trend pulses with pullback cadence.
Volatility clustering that creates rhythmic expansions and contractions.
Cycle tools are trying to measure those repeating components, and DFT is the standard mathematical way to do it.
Where DFT comes from (the core idea)
The Discrete Fourier Transform comes from Fourier analysis, a foundational signal processing concept:
Fourier’s idea : any sufficiently well-behaved signal can be expressed as a sum of sine and cosine waves at different frequencies, each with:
An amplitude (how strong that wave is).
A phase (where you are within the wave cycle).
In continuous math you get the Fourier Transform. In sampled data (like candles) you use the Discrete Fourier Transform. It converts a time series (price over time) into a frequency description (strength of different cycles).
In markets:
Time domain: candles and price series.
Frequency domain: cycle periods and their strengths.
Why sine and cosine, not just sine
A sine wave alone cannot represent every phase alignment cleanly. DFT uses both cosine and sine components because together they form an orthogonal basis that can represent any phase shift.
You can think of it like this:
Cosine component captures “in-phase” alignment with the cycle.
Sine component captures “quadrature” (90-degree shifted) alignment.
Combining them gives full information: amplitude + phase.
Mathematically, a single frequency component can be written as:
A * cos(ωt + φ)
But DFT estimates A and φ by separately accumulating cosine and sine projections.
How this script implements the DFT (and what it is actually measuring)
This is not a full-spectrum FFT across every frequency. It is a targeted DFT across a fixed set of cycle periods:
Tested periods
The script tests 8 predefined periods:
5, 8, 13, 21, 34, 55, 89, 120
These are Fibonacci-like cycle candidates commonly used in cycle/market structure work. The point is not that Fibonacci is magic. The point is that these represent a reasonable spread from short to long rhythms without needing hundreds of frequencies (which would be heavy in Pine).
Normalization step (important)
Before computing the DFT, the script normalizes the series:
mn = SMA(src, lookback)
sd = stdev(src, lookback)
norm = (src - mn) / sd (if sd != 0)
Why normalize:
DFT amplitude depends on the scale of the input series.
If you compare BTC and TLT raw prices, the magnitude is meaningless.
Z-score normalization makes amplitude more comparable across instruments and regimes.
So the spectrum is measuring “cyclical structure in standardized deviations,” not raw dollars.
Projection onto cosine and sine
For each tested period P:
ω = 2π / P (angular frequency for that period)
Compute:
- sCos = Σ(norm * cos(ωk))
- sSin = Σ(norm * sin(ωk))
Interpretation:
You are correlating the last window of normalized price with a cosine wave of period P.
And also correlating it with a sine wave of period P.
If the price has a strong P-bar rhythm, these sums grow in magnitude.
Window length detail
The script uses:
window = min(lookback - 1, 99)
So even if lookback is 200, the internal DFT accumulation caps at 100 bars for performance stability. This is a deliberate trade: stable computation in Pine, while still letting you define normalization lookback and overall context.
Amplitude computation
Once sCos and sSin are computed:
raw magnitude = sqrt(sCos² + sSin²)
This is the length of the vector (sCos, sSin). That vector length is the standard way to combine the orthogonal components into one strength metric.
Then it scales it into a 0–100 “display amplitude”:
amp = sqrt(sCos² + sSin²) / lookback * 100 * sensitivity
amp is capped to 100
So:
Higher amplitude means stronger alignment with that cycle period.
Sensitivity is a user control to amplify or damp the display scaling.
Important: amplitude here is not a probability, and it is not guaranteed “signal quality.” It is a standardized “how much of that cycle exists in the recent window” metric.
Phase computation
Phase is computed using atan2(sSin, sCos). That matters because:
A simple atan(sin/cos) fails in different quadrants.
atan2 correctly resolves the angle from -π to +π.
Phase tells you where you are within the cycle:
Two cycles can have same amplitude but opposite phase.
Phase is what lets you infer “approaching peak vs trough” behavior.
Dominant cycle selection
The script chooses the dominant cycle as the period with the highest amplitude among the tested periods:
domIdx = argmax(amp )
domAmp = max amplitude
domPhase = phase at domIdx
This dominant cycle is used for:
Spectrogram history matrix (chart symbol).
Dominant cycle oscillator.
Data window outputs (dominant period, oscillator value).
Spectrum View: what you see and how to read it
In Spectrum mode, the indicator draws a frequency snapshot for up to five instruments. Each instrument gets a spectrum line (or bars/area depending on style) plotted across the 8 periods on the x-axis, with amplitude (0–100) on the y-axis.
X-axis meaning
Each x position corresponds to a period (5 → 120 bars). You are not looking at “frequency in Hz.” You are looking at “period in bars,” which is more intuitive in trading.
Y-axis meaning
Amplitude is a scaled measure of how strongly that period is present in the recent normalized data. Higher means stronger.
Plot styles
Waveform: connects amplitude points into a continuous shape, best for seeing spectrum shape.
Bars: draws vertical bars per period, best for quick comparison.
Area: similar to waveform but filled toward baseline for emphasis.
Dominant peaks and phase direction labels
The script highlights dominant cycles per symbol (if enabled):
If max amplitude > 20, it labels that peak with the symbol name.
If Show Phase Direction is enabled, it appends ▲ or ▼.
Phase direction logic:
rising = sin(phase) < 0
▲ means cycle is in a “rising” phase segment
▼ means cycle is in a “falling” phase segment
This is not “price will rise now.” It is “the dominant cycle’s instantaneous phase suggests you are on the upward vs downward half of that oscillation.” In real markets, you use this as context, not as a standalone trade trigger.
It also draws small ▲/▼ markers on secondary peaks (amp > 15) to show phase direction of other meaningful cycles, giving you a richer picture than “one dominant period.”
Resonance Zones: cross-asset harmonic alignment
Resonance is where this tool becomes more than a single-chart curiosity.
What resonance means here
A resonance zone is flagged when at least 3 out of 5 instruments have strong amplitude at the same tested period. Mechanically:
For each period i:
- Count instruments with amp > 30
- If count >= 3, mark resonance at that period
When resonance is detected:
A vertical highlight box is drawn behind that period.
A ⚡ marker is printed at the top.
Interpretation:
Multiple assets are expressing a similar cycle length at the same time.
This can indicate macro rhythm, shared liquidity timing, or cross-market synchronization.
This is especially useful when your instrument set includes:
Rates proxy (TLT), commodities (oil, gold), and crypto indices.
You can visually spot when markets are “vibrating” together at a shared period.
Resonance is not automatically bullish or bearish. It is telling you “cycle length agreement,” which can help with timing models and contextual trade planning.
Spectrogram View: frequency over time
Spectrum mode is a snapshot. Spectrogram mode adds time evolution.
What a spectrogram is
A spectrogram is a 2D heatmap where:
Rows = different periods (frequency bands).
Columns = time history (bars ago → now).
Color = amplitude strength.
This allows you to see:
Which cycles are persistent vs fleeting.
When dominant cycle shifts occur (energy moves from one period to another).
Cycle regime transitions (short cycles dominating in chop vs longer cycles dominating in trend).
How the script builds the spectrogram matrix
It maintains a matrix with:
NUM_PERIODS rows (8 periods)
histBars columns (history length)
Each bar:
Remove the oldest column.
Append the newest amplitude array from chartSpec.
So the spectrogram is always a rolling history of the chart symbol’s cycle amplitudes. It does not attempt to store five symbols (too heavy), it focuses on the active chart for time evolution.
Heat coloring
Amplitude values map to a custom gradient:
Low = dark blue
Mid = blue/cyan to orange
High = yellow
This makes dominant energy bands visually obvious. A stable bright band means persistent cycle dominance.
Dominant Cycle Oscillator: phase mapped to a 0–100 oscillator
The oscillator is derived from the dominant cycle phase (chart symbol):
oscRaw = cos(domPhase)
oscValue = 50 + 50 * oscRaw (maps -1..1 into 0..100)
Interpretation:
When cos(phase) ≈ +1, oscillator near 100 (cycle peak zone).
When cos(phase) ≈ -1, oscillator near 0 (cycle trough zone).
Midline 50 corresponds to the quarter-cycle transition points.
It also colors the oscillator by phase direction:
oscRising = sin(domPhase) < 0
Rising phase = green-ish
Falling phase = red-ish
This gives you a clean timing reference:
The dominant period tells you the cycle length.
The oscillator tells you where you are within that cycle.
It is not forecasting price. It is telling you the current phase position of the strongest detected cycle component.
Alerts and practical timing usage
Alerts are based on the oscillator:
Cross above 80: dominant cycle entering peak zone.
Cross below 20: dominant cycle entering trough zone.
Cross 50: midline cross (phase transition).
In practice, you use these as “timing context” alerts, for example:
If your trend model is bullish and cycle oscillator enters trough zone, it can hint at a favorable pullback timing window.
If you are mean-reversion trading and cycle peak zone aligns with resistance, that confluence matters.
Again: cycle timing needs structure confirmation. The oscillator alone is not a trade system.
Multi-instrument design and non-repaint behavior
The indicator requests five external instruments via request.security. It uses:
close with lookahead_on
This forces the data to be “previous confirmed close” so the spectral calculations do not repaint intra-bar. That matters because cycle measures can change drastically within a bar if you let them use live values.
So:
Spectra for external symbols are based on confirmed historical closes.
Chart symbol spectrogram and oscillator are also stable in the sense they depend on confirmed series values (dominant phase updates bar-to-bar).
Key parameters and how they change behavior
Analysis Lookback
Affects normalization and the DFT window cap:
Higher lookback stabilizes mean/stdev normalization and reduces random shifts.
Lower lookback makes the tool more reactive but more prone to regime noise.
Because the inner DFT accumulation caps at 100 bars, very high lookback mostly affects normalization rather than the raw projection length.
Sensitivity
Scales displayed amplitude:
Higher sensitivity makes peaks stand out more.
Lower sensitivity compresses amplitude.
It is a display control, not a physics constant.
View Mode
Spectrum: cross-asset snapshot comparison, resonance detection.
Spectrogram: time evolution of cycle energy for chart symbol.
Show Phase Direction
Adds ▲/▼ markers derived from sin(phase). Useful for quick cycle position intuition, but do not treat ▲ as “buy.”
Show Resonance Zones
Marks periods where many instruments share strong energy. Useful for macro rhythm alignment.
Highlight Dominant Cycles
Labels peaks. If you disable it, the chart becomes cleaner but less informative.
Spectrogram History
Controls how many columns are stored. Higher makes a longer heatmap but costs more drawing.
Limitations and what not to assume
This tool is honest DSP applied to market data, but market data is not a stationary sine wave generator. Key limitations:
Cycles drift. Dominant period can shift as regime changes.
The tool only tests 8 candidate periods. If the true dominant period is 30, it will express as energy near 34 or distributed across neighbors.
Normalization helps comparability, but does not make amplitude “absolute truth.”
DFT assumes a stable frequency over the window. Markets often violate that.
Phase-based oscillators are timing aids, not predictors.
This is why the indicator is best used as:
Context for entries/exits, not a standalone system.
A way to see when cycle energy concentrates or disperses.
A way to detect when multiple markets share a timing rhythm.
How to use it properly (workflows)
1) Cycle regime identification
If short periods (5–13) dominate, market is often choppy, reactive, and mean-reverting.
If mid periods (21–55) dominate, market often shows swing structure.
If long periods (89–120) dominate, market can be in slower macro drift, trend legs, or compressed volatility regimes.
2) Timing layer for an existing strategy
Use your trend model to decide direction.
Use dominant cycle oscillator to decide timing within that direction.
Use spectrogram to avoid trading when dominant period is unstable or flipping rapidly.
3) Cross-asset confirmation
If you see resonance at a period, watch whether your main instrument is also showing strength there.
Resonance can justify holding a cycle-based timing thesis with more confidence because it is not isolated.
4) Expectation management
If the spectrum is flat (no peaks above threshold), that is information:
No clean dominant cycle, randomness dominates.
Cycle-based timing will be unreliable.
Summary
Harmonic Frequency Visualizer uses a targeted Discrete Fourier Transform across predefined cycle periods to measure amplitude and phase of cyclical components in price. It supports multi-instrument spectrum comparison, resonance detection when several markets share strong energy at the same periods, and a spectrogram heatmap for the chart instrument showing how cycle dominance evolves over time. A dominant cycle oscillator maps phase into a 0–100 timing readout with alerts for peak/trough/midline transitions. It is a cycle context engine designed to complement trend, structure, and risk models, not replace them. Indicator

PaddingThe Padding library is a comprehensive and flexible toolkit designed to extend time series data within PulseWire, making it an indispensable resource for advanced signal processing tasks such as FFT, filtering, convolution, and wavelet analysis. At its core, the library addresses the common challenge of edge effects by "padding" your data—that is, by appending additional data points beyond the natural boundaries of your original dataset. This extension not only mitigates the distortions that can occur at the endpoints but also helps to maintain the integrity of various transformations and calculations performed on the series. The library accomplishes this while preserving the ordering of your data, ensuring that the most recent point always resides at index 0.
Central to the functionality of this library are two key enumerations: Direction and PaddingType. The Direction enum determines where the padding will be applied. You can choose to extend the data in the forward direction (ahead of the current values), in the backward direction (behind the current values), or in both directions simultaneously. The PaddingType enum defines the specific method used for extending the data. The library supports several methods—including symmetric, reflect, periodic, antisymmetric, antireflect, smooth, constant, and zero padding—each of which has been implemented to suit different analytical scenarios. For instance, symmetric padding mirrors the original data across its boundaries, while reflect padding continues the trend by reflecting around endpoint values. Periodic padding repeats the data, and antisymmetric padding mirrors the data with alternating signs to counterbalance it. The antireflect and smooth methods take into account the derivatives of your data, thereby extending the series in a way that preserves or smoothly continues these derivative values. Constant and zero padding simply extend the series using fixed endpoint values or zeros. Together, these enums allow you to fine-tune how your data is extended, ensuring that the padding method aligns with the specific requirements of your analysis.
The library is designed to work with both single variable inputs and array inputs. When using array-based methods—particularly with the antireflect and smooth padding types—please note that the implementation intentionally discards the last data point as a result of the delta computation process. This behavior is an important consideration when integrating the library into your PulseWire studies, as it affects the overall data length of the padded series. Despite this, the library’s structure and documentation make it straightforward to incorporate into your existing scripts. You simply provide your data source, define the length of your data window, and select the desired padding type and direction, along with any optional parameters to control the extent of the padding (using both_period, forward_period, or backward_period).
In practical application, the Padding library enables you to extend historical data beyond its original range in a controlled and predictable manner. This is particularly useful when preparing datasets for further signal processing, as it helps to reduce artifacts that can otherwise compromise the results of your analytical routines. Whether you are an experienced Pine Script developer or a trader exploring advanced data analysis techniques, this library offers a robust solution that enhances the reliability and accuracy of your studies by ensuring your algorithms operate on a more complete and well-prepared dataset.
Library "Padding"
A comprehensive library for padding time series data with various methods. Supports both single variable and array inputs, with flexible padding directions and periods. Designed for signal processing applications including FFT, filtering, convolution, and wavelets. All methods maintain data ordering with most recent point at index 0.
symmetric(source, series_length, direction, both_period, forward_period, backward_period)
Applies symmetric padding by mirroring the input data across boundaries
Parameters:
source (float) : Input value to pad from
series_length (int) : Length of the data window
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to series_length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to series_length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with symmetric padding applied
method symmetric(source, direction, both_period, forward_period, backward_period)
Applies symmetric padding to an array by mirroring the data across boundaries
Namespace types: array
Parameters:
source (array) : Array of values to pad
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to array length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to array length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with symmetric padding applied
reflect(source, series_length, direction, both_period, forward_period, backward_period)
Applies reflect padding by continuing trends through reflection around endpoint values
Parameters:
source (float) : Input value to pad from
series_length (int) : Length of the data window
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to series_length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to series_length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with reflect padding applied
method reflect(source, direction, both_period, forward_period, backward_period)
Applies reflect padding to an array by continuing trends through reflection around endpoint values
Namespace types: array
Parameters:
source (array) : Array of values to pad
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to array length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to array length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with reflect padding applied
periodic(source, series_length, direction, both_period, forward_period, backward_period)
Applies periodic padding by repeating the input data
Parameters:
source (float) : Input value to pad from
series_length (int) : Length of the data window
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to series_length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to series_length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with periodic padding applied
method periodic(source, direction, both_period, forward_period, backward_period)
Applies periodic padding to an array by repeating the data
Namespace types: array
Parameters:
source (array) : Array of values to pad
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to array length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to array length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with periodic padding applied
antisymmetric(source, series_length, direction, both_period, forward_period, backward_period)
Applies antisymmetric padding by mirroring data and alternating signs
Parameters:
source (float) : Input value to pad from
series_length (int) : Length of the data window
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to series_length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to series_length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with antisymmetric padding applied
method antisymmetric(source, direction, both_period, forward_period, backward_period)
Applies antisymmetric padding to an array by mirroring data and alternating signs
Namespace types: array
Parameters:
source (array) : Array of values to pad
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to array length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to array length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with antisymmetric padding applied
antireflect(source, series_length, direction, both_period, forward_period, backward_period)
Applies antireflect padding by reflecting around endpoints while preserving derivatives
Parameters:
source (float) : Input value to pad from
series_length (int) : Length of the data window
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to series_length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to series_length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with antireflect padding applied
method antireflect(source, direction, both_period, forward_period, backward_period)
Applies antireflect padding to an array by reflecting around endpoints while preserving derivatives
Namespace types: array
Parameters:
source (array) : Array of values to pad
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to array length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to array length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with antireflect padding applied. Note: Last data point is lost when using array input
smooth(source, series_length, direction, both_period, forward_period, backward_period)
Applies smooth padding by extending with constant derivatives from endpoints
Parameters:
source (float) : Input value to pad from
series_length (int) : Length of the data window
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to series_length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to series_length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with smooth padding applied
method smooth(source, direction, both_period, forward_period, backward_period)
Applies smooth padding to an array by extending with constant derivatives from endpoints
Namespace types: array
Parameters:
source (array) : Array of values to pad
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to array length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to array length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with smooth padding applied. Note: Last data point is lost when using array input
constant(source, series_length, direction, both_period, forward_period, backward_period)
Applies constant padding by extending endpoint values
Parameters:
source (float) : Input value to pad from
series_length (int) : Length of the data window
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to series_length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to series_length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with constant padding applied
method constant(source, direction, both_period, forward_period, backward_period)
Applies constant padding to an array by extending endpoint values
Namespace types: array
Parameters:
source (array) : Array of values to pad
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to array length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to array length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with constant padding applied
zero(source, series_length, direction, both_period, forward_period, backward_period)
Applies zero padding by extending with zeros
Parameters:
source (float) : Input value to pad from
series_length (int) : Length of the data window
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to series_length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to series_length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with zero padding applied
method zero(source, direction, both_period, forward_period, backward_period)
Applies zero padding to an array by extending with zeros
Namespace types: array
Parameters:
source (array) : Array of values to pad
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to array length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to array length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with zero padding applied
pad_data(source, series_length, padding_type, direction, both_period, forward_period, backward_period)
Generic padding function that applies specified padding type to input data
Parameters:
source (float) : Input value to pad from
series_length (int) : Length of the data window
padding_type (series PaddingType) : Type of padding to apply (see PaddingType enum)
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to series_length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to series_length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with specified padding applied
method pad_data(source, padding_type, direction, both_period, forward_period, backward_period)
Generic padding function that applies specified padding type to array input
Namespace types: array
Parameters:
source (array) : Array of values to pad
padding_type (series PaddingType) : Type of padding to apply (see PaddingType enum)
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to array length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to array length if not specified
Returns: Array ordered with most recent point at index 0, containing original data with specified padding applied. Note: Last data point is lost when using antireflect or smooth padding types
make_padded_data(source, series_length, padding_type, direction, both_period, forward_period, backward_period)
Creates a window-based padded data series that updates with each new value. WARNING: Function must be called on every bar for consistency. Do not use in scopes where it may not execute on every bar.
Parameters:
source (float) : Input value to pad from
series_length (int) : Length of the data window
padding_type (series PaddingType) : Type of padding to apply (see PaddingType enum)
direction (series Direction) : Direction to apply padding
both_period (int) : Optional - periods to pad in both directions. Overrides forward_period and backward_period if specified
forward_period (int) : Optional - periods to pad forward. Defaults to series_length if not specified
backward_period (int) : Optional - periods to pad backward. Defaults to series_length if not specified
Returns: Array ordered with most recent point at index 0, containing windowed data with specified padding applied Library

Discrete Fourier Transformed Money Flow IndexThe Discrete Fourier Transform Money Flow Index indicator integrates the Money Flow Index (MFI) with Discrete Fourier Transform (credit to author wbburgin - May 26 2023 ) smoothing to offer a refined and smoothed depiction of the MFI's underlying trend. The MFI is calculated using the formula: MFI = 100 - (100 / (1 + MR)), where a high MFI value indicates robust buying pressure (signaling an overbought condition), and a low MFI value indicates substantial selling pressure (signaling an oversold condition).
Why is the DFT and MFI combined?
The aim of this combination between DFT and MFI is to effectively filter out short-term fluctuations and noise, enabling a clearer assessment of the overall trend. This smoothing process enhances the reliability of the MFI by emphasizing dominant and sustained buying or selling pressures. This script executes a full DFT but only uses filtering from one frequency component. The choice to focus on the magnitude at index 0 is significant as it captures the dominant or fundamental frequency in the data. By analyzing this primary cyclic behavior, we can identify recurring patterns and potential turning points more easily. This streamlined approach simplifies interpretation and enhances efficiency by reducing complexity associated with multiple frequency components. Overall, focusing on the dominant frequency and applying it to the MFI provides a concise and actionable assessment of the underlying data.
Note: The FMFI indicator provides both smoothed and non-smoothed versions of the MFI, with the option to toggle the original non-smoothed MFI on or off in the settings.
Application
FMFI functions as a trend-following indicator. Bullish trends are denoted by the color white, while bearish trends are represented by the color purple. Circles plotted on the FMFI indicate regular bull and bear signals. Additionally, red arrows indicate a strong negative trend, while green arrows indicate a strong positive trend. These arrows are calculated based on the presence of regular bull and bear signals within overbought and oversold zones. To enhance its effectiveness, it is recommended to combine this indicator with other complementary technical analysis tools and integrate it into a comprehensive trading strategy. Traders are encouraged to explore a wide range of settings and timeframes to align the indicator with their unique trading preferences and adapt it to the current market conditions. By doing so, traders can optimize the indicator's performance and increase their potential for successful trading outcomes.
Utility
Traders and investors can employ this indicator to enhance their trend-following strategies. The white-colored components of the FMFI can help identify potential buying zones, while the purple-colored components can assist in identifying potential selling points. The red and green arrows can be used to pinpoint moments of strong bull or bear momentum, allowing traders to position themselves advantageously in their trading activities. Please note that future performance of any trading strategy is fundamentally unknowable, and past results do not guarantee future performance. Indicator

Adaptive Average Vortex Index [lastguru]As a longtime fan of ADX, looking at Vortex Indicator I often wondered, where is the third line. I have rarely seen that anybody is calculating it. So, here it is: Average Vortex Index - an ADX calculated from Vortex Indicator. I interpret it similarly to the ADX indicator: higher values show stronger trend. If you discover other interpretation or have suggestions, comments are welcome.
Both VI+ and VI- lines are also drawn. As I use adaptive length calculation in my other scripts (based on the libraries I've developed and published), I have also included the possibility to have an adaptive length here, so if you hate the idea of calculating ADX from VI, you can disable that line and just look at the adaptive Vortex Indicator.
Note that as with all my oscillators, all the lines here are renormalized to -1..1 range unlike the original Vortex Indicator computation. To do that for VI+ and VI- lines, I subtract 1 from their values. It does not change the shape or the amplitude of the lines.
Adaptation algorithms are roughly subdivided in two categories: classic Length Adaptations and Cycle Estimators (they are also implemented in separate libraries), all are selected in Adaptation dropdown. Length Adaptation used in the Adaptive Moving Averages and the Adaptive Oscillators try to follow price movements and accelerate/decelerate accordingly (usually quite rapidly with a huge range). Cycle Estimators, on the other hand, try to measure the cycle period of the current market, which does not reflect price movement or the rate of change (the rate of change may also differ depending on the cycle phase, but the cycle period itself usually changes slowly).
VIDYA - based on VIDYA algorithm. The period oscillates from the Lower Bound up (slow)
VIDYA-RS - based on Vitali Apirine's modification of VIDYA algorithm (he calls it Relative Strength Moving Average). The period oscillates from the Upper Bound down (fast)
Kaufman Efficiency Scaling - based on Efficiency Ratio calculation originally used in KAMA
Fractal Adaptation - based on FRAMA by John F. Ehlers
MESA MAMA Cycle - based on MESA Adaptive Moving Average by John F. Ehlers
Pearson Autocorrelation* - based on Pearson Autocorrelation Periodogram by John F. Ehlers
DFT Cycle* - based on Discrete Fourier Transform Spectrum estimator by John F. Ehlers
Phase Accumulation* - based on Dominant Cycle from Phase Accumulation by John F. Ehlers
Length Adaptation usually take two parameters: Bound From (lower bound) and To (upper bound). These are the limits for Adaptation values. Note that the Cycle Estimators marked with asterisks(*) are very computationally intensive, so the bounds should not be set much higher than 50, otherwise you may receive a timeout error (also, it does not seem to be a useful thing to do, but you may correct me if I'm wrong).
The Cycle Estimators marked with asterisks(*) also have 3 checkboxes: HP (Highpass Filter), SS (Super Smoother) and HW (Hann Window). These enable or disable their internal prefilters, which are recommended by their author - John F. Ehlers . I do not know, which combination works best, so you can experiment.
If no Adaptation is selected ( None option), you can set Length directly. If an Adaptation is selected, then Cycle multiplier can be set.
The oscillator also has the option to configure the internal smoothing function with Window setting. By default, RMA is used (like in ADX calculation). Fast Default option is using half the length for smoothing. Triangle , Hamming and Hann Window algorithms are some better smoothers suggested by John F. Ehlers.
After the oscillator a Moving Average can be applied. The following Moving Averages are included: SMA , RMA, EMA , HMA , VWMA , 2-pole Super Smoother, 3-pole Super Smoother, Filt11, Triangle Window, Hamming Window, Hann Window, Lowpass, DSSS.
Postfilter options are applied last:
Stochastic - Stochastic
Super Smooth Stochastic - Super Smooth Stochastic (part of MESA Stochastic ) by John F. Ehlers
Inverse Fisher Transform - Inverse Fisher Transform
Noise Elimination Technology - a simplified Kendall correlation algorithm "Noise Elimination Technology" by John F. Ehlers
Momentum - momentum (derivative)
Except for Inverse Fisher Transform , all Postfilter algorithms can have Length parameter. If it is not specified (set to 0), then the calculated Slow MA Length is used. If Filter/MA Length is less than 2 or Postfilter Length is less than 1, they are calculated as a multiplier of the calculated oscillator length.
More information on the algorithms is given in the code for the libraries used. I am also very grateful to other PulseWire community members (they are also mentioned in the library code) without whom this script would not have been possible. Indicator

Indicator

Adaptive Oscillator constructor [lastguru]Adaptive Oscillators use the same principle as Adaptive Moving Averages. This is an experiment to separate length generation from oscillators, offering multiple alternatives to be combined. Some of the combinations are widely known, some are not. Note that all Oscillators here are normalized to -1..1 range. This indicator is based on my previously published public libraries and also serve as a usage demonstration for them. I will try to expand the collection (suggestions are welcome), however it is not meant as an encyclopaedic resource , so you are encouraged to experiment yourself: by looking on the source code of this indicator, I am sure you will see how trivial it is to use the provided libraries and expand them with your own ideas and combinations. I give no recommendation on what settings to use, but if you find some useful setting, combination or application ideas (or bugs in my code), I would be happy to read about them in the comments section.
The indicator works in three stages: Prefiltering, Length Adaptation and Oscillators.
Prefiltering is a fast smoothing to get rid of high-frequency (2, 3 or 4 bar) noise.
Adaptation algorithms are roughly subdivided in two categories: classic Length Adaptations and Cycle Estimators (they are also implemented in separate libraries), all are selected in Adaptation dropdown. Length Adaptation used in the Adaptive Moving Averages and the Adaptive Oscillators try to follow price movements and accelerate/decelerate accordingly (usually quite rapidly with a huge range). Cycle Estimators, on the other hand, try to measure the cycle period of the current market, which does not reflect price movement or the rate of change (the rate of change may also differ depending on the cycle phase, but the cycle period itself usually changes slowly).
Chande (Price) - based on Chande's Dynamic Momentum Index (CDMI or DYMOI), which is dynamic RSI with this length
Chande (Volume) - a variant of Chande's algorithm, where volume is used instead of price
VIDYA - based on VIDYA algorithm. The period oscillates from the Lower Bound up (slow)
VIDYA-RS - based on Vitali Apirine's modification of VIDYA algorithm (he calls it Relative Strength Moving Average). The period oscillates from the Upper Bound down (fast)
Kaufman Efficiency Scaling - based on Efficiency Ratio calculation originally used in KAMA
Deviation Scaling - based on DSSS by John F. Ehlers
Median Average - based on Median Average Adaptive Filter by John F. Ehlers
Fractal Adaptation - based on FRAMA by John F. Ehlers
MESA MAMA Alpha - based on MESA Adaptive Moving Average by John F. Ehlers
MESA MAMA Cycle - based on MESA Adaptive Moving Average by John F. Ehlers , but unlike Alpha calculation, this adaptation estimates cycle period
Pearson Autocorrelation* - based on Pearson Autocorrelation Periodogram by John F. Ehlers
DFT Cycle* - based on Discrete Fourier Transform Spectrum estimator by John F. Ehlers
Phase Accumulation* - based on Dominant Cycle from Phase Accumulation by John F. Ehlers
Length Adaptation usually take two parameters: Bound From (lower bound) and To (upper bound). These are the limits for Adaptation values. Note that the Cycle Estimators marked with asterisks(*) are very computationally intensive, so the bounds should not be set much higher than 50, otherwise you may receive a timeout error (also, it does not seem to be a useful thing to do, but you may correct me if I'm wrong).
The Cycle Estimators marked with asterisks(*) also have 3 checkboxes: HP (Highpass Filter), SS (Super Smoother) and HW (Hann Window). These enable or disable their internal prefilters, which are recommended by their author - John F. Ehlers . I do not know, which combination works best, so you can experiment.
Chande's Adaptations also have 3 additional parameters: SD Length (lookback length of Standard deviation), Smooth (smoothing length of Standard deviation) and Power ( exponent of the length adaptation - lower is smaller variation). These are internal tweaks for the calculation.
Oscillators section offer you a choice of Oscillator algorithms:
Stochastic - Stochastic
Super Smooth Stochastic - Super Smooth Stochastic (part of MESA Stochastic) by John F. Ehlers
CMO - Chande Momentum Oscillator
RSI - Relative Strength Index
Volume-scaled RSI - my own version of RSI. It scales price movements by the proportion of RMS of volume
Momentum RSI - RSI of price momentum
Rocket RSI - inspired by RocketRSI by John F. Ehlers (not an exact implementation)
MFI - Money Flow Index
LRSI - Laguerre RSI by John F. Ehlers
LRSI with Fractal Energy - a combo oscillator that uses Fractal Energy to tune LRSI gamma
Fractal Energy - Fractal Energy or Choppiness Index by E. W. Dreiss
Efficiency ratio - based on Kaufman Adaptive Moving Average calculation
DMI - Directional Movement Index (only ADX is drawn)
Fast DMI - same as DMI, but without secondary smoothing
If no Adaptation is selected (None option), you can set Length directly. If an Adaptation is selected, then Cycle multiplier can be set.
Before an Oscillator, a High Pass filter may be executed to remove cyclic components longer than the provided Highpass Length (no High Pass filter, if Highpass Length = 0). Both before and after the Oscillator a Moving Average can be applied. The following Moving Averages are included: SMA, RMA, EMA, HMA , VWMA, 2-pole Super Smoother, 3-pole Super Smoother, Filt11, Triangle Window, Hamming Window, Hann Window, Lowpass, DSSS. For more details on these Moving Averages, you can check my other Adaptive Constructor indicator:
The Oscillator output may be renormalized and postprocessed with the following Normalization algorithms:
Stochastic - Stochastic
Super Smooth Stochastic - Super Smooth Stochastic (part of MESA Stochastic) by John F. Ehlers
Inverse Fisher Transform - Inverse Fisher Transform
Noise Elimination Technology - a simplified Kendall correlation algorithm "Noise Elimination Technology" by John F. Ehlers
Except for Inverse Fisher Transform, all Normalization algorithms can have Length parameter. If it is not specified (set to 0), then the calculated Oscillator length is used.
More information on the algorithms is given in the code for the libraries used. I am also very grateful to other PulseWire community members (they are also mentioned in the library code) without whom this script would not have been possible. Indicator

Adaptive MA constructor [lastguru]Adaptive Moving Averages are nothing new, however most of them use EMA as their MA of choice once the preferred smoothing length is determined. I have decided to make an experiment and separate length generation from smoothing, offering multiple alternatives to be combined. Some of the combinations are widely known, some are not. This indicator is based on my previously published public libraries and also serve as a usage demonstration for them. I will try to expand the collection (suggestions are welcome), however it is not meant as an encyclopaedic resource, so you are encouraged to experiment yourself: by looking on the source code of this indicator, I am sure you will see how trivial it is to use the provided libraries and expand them with your own ideas and combinations. I give no recommendation on what settings to use, but if you find some useful setting, combination or application ideas (or bugs in my code), I would be happy to read about them in the comments section.
The indicator works in three stages: Prefiltering, Length Adaptation and Moving Averages.
Prefiltering is a fast smoothing to get rid of high-frequency (2, 3 or 4 bar) noise.
Adaptation algorithms are roughly subdivided in two categories: classic Length Adaptations and Cycle Estimators (they are also implemented in separate libraries), all are selected in Adaptation dropdown. Length Adaptation used in the Adaptive Moving Averages and the Adaptive Oscillators try to follow price movements and accelerate/decelerate accordingly (usually quite rapidly with a huge range). Cycle Estimators, on the other hand, try to measure the cycle period of the current market, which does not reflect price movement or the rate of change (the rate of change may also differ depending on the cycle phase, but the cycle period itself usually changes slowly).
Chande (Price) - based on Chande's Dynamic Momentum Index (CDMI or DYMOI), which is dynamic RSI with this length
Chande (Volume) - a variant of Chande's algorithm, where volume is used instead of price
VIDYA - based on VIDYA algorithm. The period oscillates from the Lower Bound up (slow)
VIDYA-RS - based on Vitali Apirine's modification of VIDYA algorithm (he calls it Relative Strength Moving Average). The period oscillates from the Upper Bound down (fast)
Kaufman Efficiency Scaling - based on Efficiency Ratio calculation originally used in KAMA
Deviation Scaling - based on DSSS by John F. Ehlers
Median Average - based on Median Average Adaptive Filter by John F. Ehlers
Fractal Adaptation - based on FRAMA by John F. Ehlers
MESA MAMA Alpha - based on MESA Adaptive Moving Average by John F. Ehlers
MESA MAMA Cycle - based on MESA Adaptive Moving Average by John F. Ehlers, but unlike Alpha calculation, this adaptation estimates cycle period
Pearson Autocorrelation* - based on Pearson Autocorrelation Periodogram by John F. Ehlers
DFT Cycle* - based on Discrete Fourier Transform Spectrum estimator by John F. Ehlers
Phase Accumulation* - based on Dominant Cycle from Phase Accumulation by John F. Ehlers
Length Adaptation usually take two parameters: Bound From (lower bound) and To (upper bound). These are the limits for Adaptation values. Note that the Cycle Estimators marked with asterisks(*) are very computationally intensive, so the bounds should not be set much higher than 50, otherwise you may receive a timeout error (also, it does not seem to be a useful thing to do, but you may correct me if I'm wrong).
The Cycle Estimators marked with asterisks(*) also have 3 checkboxes: HP (Highpass Filter), SS (Super Smoother) and HW (Hann Window). These enable or disable their internal prefilters, which are recommended by their author - John F. Ehlers. I do not know, which combination works best, so you can experiment.
Chande's Adaptations also have 3 additional parameters: SD Length (lookback length of Standard deviation), Smooth (smoothing length of Standard deviation) and Power (exponent of the length adaptation - lower is smaller variation). These are internal tweaks for the calculation.
Length Adaptaton section offer you a choice of Moving Average algorithms. Most of the Adaptations are originally used with EMA, so this is a good starting point for exploration.
SMA - Simple Moving Average
RMA - Running Moving Average
EMA - Exponential Moving Average
HMA - Hull Moving Average
VWMA - Volume Weighted Moving Average
2-pole Super Smoother - 2-pole Super Smoother by John F. Ehlers
3-pole Super Smoother - 3-pole Super Smoother by John F. Ehlers
Filt11 -a variant of 2-pole Super Smoother with error averaging for zero-lag response by John F. Ehlers
Triangle Window - Triangle Window Filter by John F. Ehlers
Hamming Window - Hamming Window Filter by John F. Ehlers
Hann Window - Hann Window Filter by John F. Ehlers
Lowpass - removes cyclic components shorter than length (Price - Highpass)
DSSS - Derivation Scaled Super Smoother by John F. Ehlers
There are two Moving Averages that are drown on the chart, so length for both needs to be selected. If no Adaptation is selected ( None option), you can set Fast Length and Slow Length directly. If an Adaptation is selected, then Cycle multiplier can be selected for Fast and Slow MA.
More information on the algorithms is given in the code for the libraries used. I am also very grateful to other PulseWire community members (they are also mentioned in the library code) without whom this script would not have been possible. Indicator

DominantCycleCollection of Dominant Cycle estimators. Length adaptation used in the Adaptive Moving Averages and the Adaptive Oscillators try to follow price movements and accelerate/decelerate accordingly (usually quite rapidly with a huge range). Cycle estimators, on the other hand, try to measure the cycle period of the current market, which does not reflect price movement or the rate of change (the rate of change may also differ depending on the cycle phase, but the cycle period itself usually changes slowly). This collection may become encyclopaedic, so if you have any working cycle estimator, drop me a line in the comments below. Suggestions are welcome. Currently included estimators are based on the work of John F. Ehlers
mamaPeriod(src, dynLow, dynHigh) MESA Adaptation - MAMA Cycle
Parameters:
src : Series to use
dynLow : Lower bound for the dynamic length
dynHigh : Upper bound for the dynamic length
Returns: Calculated period
Based on MESA Adaptive Moving Average by John F. Ehlers
Performs Hilbert Transform Homodyne Discriminator cycle measurement
Unlike MAMA Alpha function (in LengthAdaptation library), this does not compute phase rate of change
Introduced in the September 2001 issue of Stocks and Commodities
Inspired by the @everget implementation:
Inspired by the @anoojpatel implementation:
paPeriod(src, dynLow, dynHigh, preHP, preSS, preHP) Pearson Autocorrelation
Parameters:
src : Series to use
dynLow : Lower bound for the dynamic length
dynHigh : Upper bound for the dynamic length
preHP : Use High Pass prefilter (default)
preSS : Use Super Smoother prefilter (default)
preHP : Use Hann Windowing prefilter
Returns: Calculated period
Based on Pearson Autocorrelation Periodogram by John F. Ehlers
Introduced in the September 2016 issue of Stocks and Commodities
Inspired by the @blackcat1402 implementation:
Inspired by the @rumpypumpydumpy implementation:
Corrected many errors, and made small speed optimizations, so this could be the best implementation to date (still slow, though, so may revisit in future)
High Pass and Super Smoother prefilters are used in the original implementation
dftPeriod(src, dynLow, dynHigh, preHP, preSS, preHP) Discrete Fourier Transform
Parameters:
src : Series to use
dynLow : Lower bound for the dynamic length
dynHigh : Upper bound for the dynamic length
preHP : Use High Pass prefilter (default)
preSS : Use Super Smoother prefilter (default)
preHP : Use Hann Windowing prefilter
Returns: Calculated period
Based on Spectrum from Discrete Fourier Transform by John F. Ehlers
Inspired by the @blackcat1402 implementation:
High Pass, Super Smoother and Hann Windowing prefilters are used in the original implementation
phasePeriod(src, dynLow, dynHigh, preHP, preSS, preHP) Phase Accumulation
Parameters:
src : Series to use
dynLow : Lower bound for the dynamic length
dynHigh : Upper bound for the dynamic length
preHP : Use High Pass prefilter (default)
preSS : Use Super Smoother prefilter (default)
preHP : Use Hamm Windowing prefilter
Returns: Calculated period
Based on Dominant Cycle from Phase Accumulation by John F. Ehlers
High Pass and Super Smoother prefilters are used in the original implementation
doAdapt(type, src, len, dynLow, dynHigh, chandeSDLen, chandeSmooth, chandePower, preHP, preSS, preHP) Execute a particular Length Adaptation or Dominant Cycle Estimator from the list
Parameters:
type : Length Adaptation or Dominant Cycle Estimator type to use
src : Series to use
len : Reference lookback length
dynLow : Lower bound for the dynamic length
dynHigh : Upper bound for the dynamic length
chandeSDLen : Lookback length of Standard deviation for Chande's Dynamic Length
chandeSmooth : Smoothing length of Standard deviation for Chande's Dynamic Length
chandePower : Exponent of the length adaptation for Chande's Dynamic Length (lower is smaller variation)
preHP : Use High Pass prefilter for the Estimators that support it (default)
preSS : Use Super Smoother prefilter for the Estimators that support it (default)
preHP : Use Hann Windowing prefilter for the Estimators that support it
Returns: Calculated period (float, not limited)
doEstimate(type, src, dynLow, dynHigh, preHP, preSS, preHP) Execute a particular Dominant Cycle Estimator from the list
Parameters:
type : Dominant Cycle Estimator type to use
src : Series to use
dynLow : Lower bound for the dynamic length
dynHigh : Upper bound for the dynamic length
preHP : Use High Pass prefilter for the Estimators that support it (default)
preSS : Use Super Smoother prefilter for the Estimators that support it (default)
preHP : Use Hann Windowing prefilter for the Estimators that support it
Returns: Calculated period (float, not limited) Library

JohnEhlersFourierTransformLibrary "JohnEhlersFourierTransform"
Fourier Transform for Traders By John Ehlers, slightly modified to allow to inspect other than the 8-50 frequency spectrum.
reference:
www.mesasoftware.com
high_pass_filter(source) Detrended version of the data by High Pass Filtering with a 40 Period cutoff
Parameters:
source : float, data source.
Returns: float.
transformed_dft(source, start_frequency, end_frequency) DFT by John Elhers.
Parameters:
source : float, data source.
start_frequency : int, lower bound of the frequency window, must be a positive number >= 0, window must be less than or 30.
end_frequency : int, upper bound of the frequency window, must be a positive number >= 0, window must be less than or 30.
Returns: tuple with float, float array.
db_to_rgb(db, transparency) converts the frequency decibels to rgb.
Parameters:
db : float, decibels value.
transparency : float, transparency value.
Returns: color. Library

Library

[blackcat] L2 Ehlers DFT-Adapted RSILevel: 2
Background
John F. Ehlers introuced his DFT-ADAPTED RELATIVE STRENGTH INDEX (RSI) in Jan, 2007.
Function
In "Fourier Transform For Traders" in Jan, 2007, John Ehlers presented an interesting technique of improving the resolution of spectral analysis that could be used to effectively measure market cycles. Better resolution is obtained by a surprisingly simple modification of the discrete Fourier transform. John Ehlers suggests using the discrete Fourier transform (DFT) to tune indicators. Here, I demonstrate this by building a DFT-adapted relative strength index (RSI) strategy.
Rather than display the RSI for a single cycle length across the entire chart, Ehlers DFT adaptive RSI value reflects the DFT-calculated dominant cycle length RSI. If the dominant cycle changes from 14 to 18 bars, the RSI length parameter changes accordingly. Computationally, this requires the strategy to continuously update values for all possible RSI cycle lengths via a "for" loop and array.
In details, a full-featured formula that implements a high-pass filter (HP) and a six-tap low-pass finite impulse response (FIR) filter on input, then does discrete Fourier transform calculations. I has taken liberty of adding extra parameters so the user can modify the analysis window length and the high-pass filter cutoff frequency in real time using the parameters window. Once the suite of possible RSI values is calculated, we use the DFT to select the relevant RSI for the current bar. The strategy then trades according to J. Welles Wilder's original rules for the RSI.
Key Signal
fastline--> DFT-ADAPTED RELATIVE STRENGTH INDEX (RSI) fast line
slowline--> DFT-ADAPTED RELATIVE STRENGTH INDEX (RSI) slow line
Pros and Cons
100% John F. Ehlers definition translation, even variable names are the same. This help readers who would like to use pine to read his book.
Remarks
The 71th script for Blackcat1402 John F. Ehlers Week publication.
Based on original work of Ehlers, I added ALMA smoothing on DFT-adapted relative strength index (RSI) so that clearer trend can be observed.
Readme
In real life, I am a prolific inventor. I have successfully applied for more than 60 international and regional patents in the past 12 years. But in the past two years or so, I have tried to transfer my creativity to the development of trading strategies. Tradingview is the ideal platform for me. I am selecting and contributing some of the hundreds of scripts to publish in Tradingview community. Welcome everyone to interact with me to discuss these interesting pine scripts.
The scripts posted are categorized into 5 levels according to my efforts or manhours put into these works.
Level 1 : interesting script snippets or distinctive improvement from classic indicators or strategy. Level 1 scripts can usually appear in more complex indicators as a function module or element.
Level 2 : composite indicator/strategy. By selecting or combining several independent or dependent functions or sub indicators in proper way, the composite script exhibits a resonance phenomenon which can filter out noise or fake trading signal to enhance trading confidence level.
Level 3 : comprehensive indicator/strategy. They are simple trading systems based on my strategies. They are commonly containing several or all of entry signal, close signal, stop loss, take profit, re-entry, risk management, and position sizing techniques. Even some interesting fundamental and mass psychological aspects are incorporated.
Level 4 : script snippets or functions that do not disclose source code. Interesting element that can reveal market laws and work as raw material for indicators and strategies. If you find Level 1~2 scripts are helpful, Level 4 is a private version that took me far more efforts to develop.
Level 5 : indicator/strategy that do not disclose source code. private version of Level 3 script with my accumulated script processing skills or a large number of custom functions. I had a private function library built in past two years. Level 5 scripts use many of them to achieve private trading strategy. Indicator

[blackcat] L2 Ehlers DFT Spectral EstimateLevel: 2
Background
John F. Ehlers introduced DFT Spectral Estimate in his "Cycle Analytics for Traders" chapter 9 on 2013.
Function
The DFT is accomplished by correlating the data with the cosine and sine of each period of interest over the selected window period. The sum of the squares of each of these correlated values represents the relative power at each period. The only user input is whether to select Spectral Dilation compensation. The default selection is NOT to use the compensation.
The spectrum values vary between 0 and 1 after being normalized. These values are converted to colors. When the spectrum is greater than 0.5 the colors combine red and yellow, with yellow being the result when spectrum = 1 and red being the result when the spectrum = 0.5. When the spectrum is less than 0.5, the red saturation is decreased, with the result that the color is black when spectrum = 0.
Key Signal
DominantCycle --> Dominant Cycle signal
Pros and Cons
100% John F. Ehlers definition translation of original work, even variable names are the same. This help readers who would like to use pine to read his book. If you had read his works, then you will be quite familiar with my code style.
Remarks
The 51th script for Blackcat1402 John F. Ehlers Week publication.
Readme
In real life, I am a prolific inventor. I have successfully applied for more than 60 international and regional patents in the past 12 years. But in the past two years or so, I have tried to transfer my creativity to the development of trading strategies. Tradingview is the ideal platform for me. I am selecting and contributing some of the hundreds of scripts to publish in Tradingview community. Welcome everyone to interact with me to discuss these interesting pine scripts.
The scripts posted are categorized into 5 levels according to my efforts or manhours put into these works.
Level 1 : interesting script snippets or distinctive improvement from classic indicators or strategy. Level 1 scripts can usually appear in more complex indicators as a function module or element.
Level 2 : composite indicator/strategy. By selecting or combining several independent or dependent functions or sub indicators in proper way, the composite script exhibits a resonance phenomenon which can filter out noise or fake trading signal to enhance trading confidence level.
Level 3 : comprehensive indicator/strategy. They are simple trading systems based on my strategies. They are commonly containing several or all of entry signal, close signal, stop loss, take profit, re-entry, risk management, and position sizing techniques. Even some interesting fundamental and mass psychological aspects are incorporated.
Level 4 : script snippets or functions that do not disclose source code. Interesting element that can reveal market laws and work as raw material for indicators and strategies. If you find Level 1~2 scripts are helpful, Level 4 is a private version that took me far more efforts to develop.
Level 5 : indicator/strategy that do not disclose source code. private version of Level 3 script with my accumulated script processing skills or a large number of custom functions. I had a private function library built in past two years. Level 5 scripts use many of them to achieve private trading strategy. Indicator

Indicator

Indicator

Filter Amplitude Response Estimator - A Simple CalculationIn digital signal processing knowing how a system interact with the frequency content of an input signal is extremely important, the mathematical tool that give you this information is called "frequency response". The frequency response regroup two elements, the amplitude response, and the phase response. The amplitude response tells you how the system modify the amplitude of the frequency components in the input signal, the phase response tells you how the system modify the phase of the frequency components in the signal, each being a function of the frequency.
The today proposed tool aim to give a low resolution representation of the amplitude response of any filter.
What Is The Amplitude Response Of A Filter ?
Remember that filters allow to interact with the frequency content of a signal by amplifying, attenuating and/or removing certain frequency components in the input signal, the amplitude (also called magnitude) response of a filter let you know exactly how your filter change the amplitude of the frequency components in the input signal, another way to see the amplitude response is as a tool that tell you what is the peak amplitude of a filter using a sinusoid of a certain frequency as input signal.
For example if the amplitude response of a filter give you a value of 0.9 at frequency 0.5, it means that the filter peak amplitude using a sinusoid of frequency 0.5 is equal to 0.9.
There are several ways to calculate the frequency response of a filter, when our filter is a FIR filter (the filter impulse response is finite), the frequency response of the filter is the absolute value of the discrete Fourier transform (DFT) of the filter impulse response.
If you are curious about this process, know that the DFT of a N samples signal return N values, so if our FIR filter coefficients are composed of only 5 values we would get a frequency response of 5 values...which would not be useful, this is why we "pad" our coefficients with zeros, that is we add zeros to the start and end of our series of coefficients, this process is called "zero-padding", so if our series of coefficients is: (1,2,3,4,5), applying zero padding would give (0,0...1,2,3,4,5,...0,0) while keeping a certain symmetry. This is related to the concept of resolution, a low resolution amplitude response would be composed of a low number of values and would not be useful, this is why we use zero-padding to add more values thus increasing the resolution.
Making a Fourier transform in Pinescript is not doable, as you need the complex number i for computing a DFT, but thats not even the only problem, a DFT would not be that useful anyway (as the processes to make it useful in a trading context would be way too complex) . So how can we calculate a filter amplitude response without using a DFT ? The simple answer is by taking the peak amplitude of a filter using a sinusoid of a certain frequency as input, this is what the proposed tool do.
Using The Tool
The proposed tool give you a 50 point amplitude response from frequency 0.005 to 0.25 by default. the setting "Range Divisor" allow you to see the amplitude response by using a different range of frequency, for example if the range divisor is equal to 2 the filter amplitude response will be evaluated from frequency 0.0025 to 0.125.
In the script, filt hold the filter you want to see the frequency response, by default a simple moving average.
The position of the frequency response is defined by the "Show Amplitude Response At Bar Number" setting, if you want the frequency response to start at bar number 5000 then enter 5000, by default 10000. If you are not a premium set the number at 4000 and it should work.
amplitude response of a simple moving average of period 14, res = 2.
By default the amplitude response use an amplitude scale, a value of 1 represent an unchanged amplitude. You can use Dbfs (decibel full scale) instead by checking the "To Decibels (Full Scale)" setting.
Dbfs amplitude response, a value of 0 represent an unchanged amplitude.
Some Amplitude Responses
In order to prove the accuracy of the proposed tool we can compare the amplitude response given by the proposed tool with the mathematical function of the amplitude response of a simple moving average, that is:
abs(sin(pi*f*length)/(length*sin(pi*f)))
In cyan the amplitude response given by the proposed tool and in blue the above function. Below are the amplitude responses of some moving averages with period 14.
Amplitude response of an EMA, the EMA is a IIR filter, therefore the amplitude response can't be made by taking the DFT of the impulse response (as this ones has infinite length), however our tool can give its frequency response.
Amplitude response of the Hull MA, as you can see some frequencies are amplified, this is common with low-lag filters.
Gaussian moving average (ALMA), with offset = 0.5 and sigma = 6.
Simple moving average high-pass filter amplitude response
Center of gravity bandpass filter amplitude response
Center of gravity bandreject filter.
IMPORTANT!: The amplitude response of adaptive moving averages is not stationary and might change over time.
Conclusion
A tool giving the amplitude response of any filter has been presented, of course this method is not efficient at all and has a low resolution of 50 points (the common resolution is of 512 points) and is difficult to work with, but has the merit to work on Tradingview and can give the frequency response of IIR filters, if you really need to see the frequency response of a filter then i recommend you to use the function freqz from the scipy package.
I still hope you will enjoy using this tool to have a look at the amplitude responses of your favorite moving averages.
I'am aware of the current situation, however i'am somehow feeling left out from the pinescript community, let me know via PM if i have done something to you and i'll do my best to fix any problems i might have caused (or i might be being parano xD)
Indicator

Indicator
