Files

75 lines
3.1 KiB
Plaintext

// Licensed under the Apache License, Version 2.0
// © mihakralj
//@version=6
indicator("Moving Average Convergence Divergence (MACD)", "MACD", overlay=false)
//@function Calculates MACD with fast and slow EMAs and signal line
//@param src Source series to calculate MACD from
//@param fast_length Period for fast EMA
//@param slow_length Period for slow EMA
//@param signal_length Period for signal line EMA
//@returns Tuple [macd, signal, histogram] values
//@optimized for performance and dirty data with embedded EMA calculations
macd(series float src, simple int fast_length, simple int slow_length, simple int signal_length) =>
if fast_length <= 0 or slow_length <= 0 or signal_length <= 0
runtime.error("All periods must be greater than 0")
if fast_length >= slow_length
runtime.error("Fast length must be less than slow length")
float alpha_fast = 2.0 / (fast_length + 1)
float alpha_slow = 2.0 / (slow_length + 1)
float alpha_signal = 2.0 / (signal_length + 1)
float beta_fast = 1.0 - alpha_fast
float beta_slow = 1.0 - alpha_slow
float beta_signal = 1.0 - alpha_signal
var bool warmup = true
var float e_fast = 1.0
var float e_slow = 1.0
var float e_signal = 1.0
var float ema_fast = 0.0
var float ema_slow = 0.0
var float ema_signal = 0.0
var float result_fast = src
var float result_slow = src
var float result_signal = 0.0
ema_fast := alpha_fast * (src - ema_fast) + ema_fast
ema_slow := alpha_slow * (src - ema_slow) + ema_slow
if warmup
e_fast *= beta_fast
e_slow *= beta_slow
e_signal *= beta_signal
float c_fast = 1.0 / (1.0 - e_fast)
float c_slow = 1.0 / (1.0 - e_slow)
float c_signal = 1.0 / (1.0 - e_signal)
result_fast := c_fast * ema_fast
result_slow := c_slow * ema_slow
float macd_line = result_fast - result_slow
ema_signal := alpha_signal * (macd_line - ema_signal) + ema_signal
result_signal := c_signal * ema_signal
warmup := e_fast > 1e-10 or e_slow > 1e-10 or e_signal > 1e-10
else
result_fast := ema_fast
result_slow := ema_slow
float macd_line = result_fast - result_slow
ema_signal := alpha_signal * (macd_line - ema_signal) + ema_signal
result_signal := ema_signal
float macd_line = result_fast - result_slow
float histogram = macd_line - result_signal
[macd_line, result_signal, histogram]
// ---------- Main loop ----------
// Inputs
i_fast = input.int(12, "Fast Length", minval=1)
i_slow = input.int(26, "Slow Length", minval=2)
i_signal = input.int(9, "Signal Length", minval=1)
i_source = input.source(close, "Source")
// Calculation
[macd_line, signal_line, histogram] = macd(i_source, i_fast, i_slow, i_signal)
// Plot
hline(0, "Zero Line", color=color.gray)
plot(histogram, "Histogram", style=plot.style_columns, color=histogram >= 0 ? (histogram[1] < histogram ? color.green : color.green) : (histogram[1] < histogram ? color.red : color.red))
plot(macd_line, "MACD", color=color.blue, linewidth=2)
plot(signal_line, "Signal", color=color.red, linewidth=2)