Quant.Math.Oscillators (quant v0.1.0-alpha.1)
Momentum oscillators and technical indicators for financial time series analysis.
This module provides implementations of popular momentum indicators including:
- MACD (Moving Average Convergence Divergence)
- RSI (Relative Strength Index)
All functions are DataFrame-first and integrate seamlessly with Explorer DataFrames.
Summary
Functions
Add MACD (Moving Average Convergence Divergence) to a DataFrame.
Add RSI (Relative Strength Index) to a DataFrame.
Detect MACD crossovers in a DataFrame.
Identify RSI overbought and oversold conditions.
Functions
Add MACD (Moving Average Convergence Divergence) to a DataFrame.
MACD is a trend-following momentum indicator that shows the relationship between two moving averages of a security's price. The MACD is calculated by subtracting the 26-period Exponential Moving Average (EMA) from the 12-period EMA.
Components
- MACD Line: Fast EMA - Slow EMA
- Signal Line: EMA of the MACD Line (typically 9-period)
- Histogram: MACD Line - Signal Line
Parameters
dataframe- Explorer DataFrame with financial datacolumn- Column name to calculate MACD on (typically :close)opts- Options keyword list::fast_period- Fast EMA period (default: 12):slow_period- Slow EMA period (default: 26):signal_period- Signal EMA period (default: 9):macd_column- MACD line column name (default: auto-generated):signal_column- Signal line column name (default: auto-generated):histogram_column- Histogram column name (default: auto-generated)
Examples
iex> df = Explorer.DataFrame.new(%{
...> close: [10.0, 11.0, 12.0, 11.5, 13.0, 12.8, 14.0, 13.5, 15.0, 14.2,
...> 16.0, 15.5, 17.0, 16.8, 18.0, 17.5, 19.0, 18.2, 20.0, 19.5,
...> 21.0, 20.8, 22.0, 21.5, 23.0, 22.2, 24.0, 23.8, 25.0, 24.5]
...> })
iex> result = Quant.Math.Oscillators.add_macd!(df, :close)
iex> result |> Explorer.DataFrame.names() |> Enum.sort()
["close", "close_histogram_12_26_9", "close_macd_12_26", "close_signal_9"]
# Custom parameters
iex> df = Explorer.DataFrame.new(%{close: [1.0, 2.0, 3.0, 4.0, 5.0]})
iex> result = Quant.Math.Oscillators.add_macd!(df, :close, fast_period: 2, slow_period: 3, signal_period: 2)
iex> Explorer.DataFrame.names(result) |> Enum.member?("close_macd_2_3")
true
Add RSI (Relative Strength Index) to a DataFrame.
RSI is a momentum oscillator that measures the speed and change of price movements. It oscillates between 0 and 100 and is typically used to identify overbought and oversold conditions in a security.
Algorithm
RSI uses Wilder's smoothing method (different from standard EMA):
- Calculate daily price changes (gains and losses)
- Apply Wilder's smoothing to average gains and losses
- RSI = 100 - (100 / (1 + RS)) where RS = Average Gain / Average Loss
Parameters
dataframe- Explorer DataFrame with financial datacolumn- Column name to calculate RSI on (typically :close)opts- Options keyword list::period- RSI period (default: 14):column_name- Output column name (default: auto-generated):overbought- Overbought threshold for analysis (default: 70):oversold- Oversold threshold for analysis (default: 30)
Returns
DataFrame with additional RSI column
Examples
iex> df = Explorer.DataFrame.new(%{
...> close: [44.0, 44.3, 44.1, 44.2, 44.5, 43.4, 44.0, 44.25, 44.8, 45.1,
...> 45.4, 45.8, 46.0, 45.9, 45.2, 44.8, 44.6, 44.4, 44.2, 44.0]
...> })
iex> result = Quant.Math.Oscillators.add_rsi!(df, :close)
iex> "close_rsi_14" in Explorer.DataFrame.names(result)
true
# Custom parameters
iex> df = Explorer.DataFrame.new(%{close: [10.0, 11.0, 12.0, 11.5, 13.0, 12.8, 14.0, 13.5, 15.0, 14.2]})
iex> result = Quant.Math.Oscillators.add_rsi!(df, :close, period: 5, column_name: "custom_rsi")
iex> "custom_rsi" in Explorer.DataFrame.names(result)
true
@spec detect_macd_crossovers( Explorer.DataFrame.t(), String.t(), String.t(), keyword() ) :: Explorer.DataFrame.t()
Detect MACD crossovers in a DataFrame.
Identifies bullish and bearish crossovers between MACD line and Signal line:
- Bullish Crossover: MACD line crosses above Signal line (buy signal)
- Bearish Crossover: MACD line crosses below Signal line (sell signal)
Parameters
dataframe- DataFrame with MACD and Signal columnsmacd_column- MACD line column namesignal_column- Signal line column nameopts- Options::crossover_column- Output column name (default: "macd_crossover")
Returns
DataFrame with additional crossover column containing:
1for bullish crossover (MACD crosses above Signal)-1for bearish crossover (MACD crosses below Signal)0for no crossover
Examples
iex> df = Explorer.DataFrame.new(%{
...> macd: [0.1, 0.2, 0.15, -0.1, -0.2, 0.05, 0.15],
...> signal: [0.05, 0.15, 0.25, 0.1, -0.05, -0.1, 0.05]
...> })
iex> result = Quant.Math.Oscillators.detect_macd_crossovers(df, "macd", "signal")
iex> crossovers = result |> Explorer.DataFrame.pull("macd_crossover") |> Explorer.Series.to_list()
iex> Enum.any?(crossovers, fn x -> x != 0 end)
true
Identify RSI overbought and oversold conditions.
Analyzes RSI values to identify potential trading signals based on traditional overbought (>70) and oversold (<30) levels.
Parameters
dataframe- DataFrame with RSI columnrsi_column- RSI column nameopts- Options::overbought- Overbought threshold (default: 70):oversold- Oversold threshold (default: 30):signal_column- Output column name (default: "rsi_signal")
Returns
DataFrame with additional signal column containing:
1for oversold condition (potential buy signal)-1for overbought condition (potential sell signal)0for neutral condition
Examples
iex> df = Explorer.DataFrame.new(%{rsi: [20, 40, 60, 80, 50, 25, 75]})
iex> result = Quant.Math.Oscillators.rsi_signals(df, "rsi")
iex> signals = result |> Explorer.DataFrame.pull("rsi_signal") |> Explorer.Series.to_list()
iex> Enum.member?(signals, 1) and Enum.member?(signals, -1)
true