Momentum Ghost Machine [ChartPrime]

ChartPrime · study · 256 行 · 点赞 5,555 · TradingView 原页

本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。

Pine Script

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ChartPrime
 
//@version=5
indicator("Momentum Ghost Machine [ChartPrime]", overlay = false, explicit_plot_zorder = true)
 
method is_even(simple int n)=> n % 2 == 0
sinc(float x)=> x == 0 ? 1 : math.sin(math.pi * x) / (math.pi * x)
blackman(float n, int length)=> 0.42 - 0.5 * math.cos((2 * math.pi * n) / (length - 1)) + 0.08 * math.cos((4 * math.pi * n) / (length - 1))
mid_point(int x)=> (x - 1) / 2
offset(simple int length)=> (length - 1) / 2
 
get_data(float source, simple int length)=>
    var float[] data = array.new<float>()
    if data.size() < length
        data.unshift(source)
        data
 
    else
        data.unshift(source)
        data.pop()
        data
 
sinc_coefficients(simple int length, float fc)=>
    float[] coefficients = array.new<float>()
    int mid = mid_point(length)
    float cutoff = 1 / fc
    for i = 0 to length - 1
        int n = i - mid
        int k = i
        int M = length
        if length.is_even()
            float coefficient = sinc(2 * cutoff * n) * blackman(k + 0.5, M)
            coefficients.push(coefficient)
        else
            float coefficient = sinc(2 * cutoff * n) * blackman(k, M)
            coefficients.push(coefficient)
    coefficients
 
toeplitz_matrix_valid(float[] coefficients, int M)=>
    int N = coefficients.size()
    int rows = M - N + 1
    matrix<float> toeplitz = matrix.new<float>(rows, M, 0)
 
    for r = 0 to rows - 1
        for c = 0 to N - 1
            if (c + r) < M
                toeplitz.set(r, c + r, coefficients.get(c))
            else
                break
 
    toeplitz
 
convolution(float[] data, float[] coefficients)=>
    var float normalize = coefficients.sum()
    var matrix<float> toeplitz_matrix = toeplitz_matrix_valid(coefficients, data.size())
    float convolved = matrix.mult(toeplitz_matrix, data).first()
    convolved / normalize
 
lti_sinc(series float source, simple int length, simple float fc = 100)=>
    float[] data = get_data(source, length)
    var float[] coefficients = sinc_coefficients(length, fc)
 
    if bar_index > length
        convolved = convolution(data, coefficients)
    else
        float(na)
 
ema(series float source, simple float length)=>
    float alpha = 2.0 / (length + 1)
    var float smoothed = na
    smoothed := alpha * source + (1.0 - alpha) * nz(smoothed[1], source)
 
dema(series float source, simple float length)=>
    float ema1 = ema(source, length)
    float ema2 = ema(ema1, length)
    2.0 * ema1 - ema2
 
tema(series float source, simple float length)=>
    float ema1 = ema(source, length)
    float ema2 = ema(ema1, length)
    float ema3 = ema(ema2, length)
    (ema1 - ema2) * 3.0 + ema3
 
wma(series float source, simple int length)=>
    var float weight_sum = length * 0.5 * (length + 1)
    float sum = 0.0
    for int i=0 to length - 1
        sum += source[i] * (length - i)
    sum / weight_sum
 
sma(series float source, simple int length)=>
    float sum = ta.cum(source)
    if bar_index < length - 1
        sum / (bar_index + 1)
    else
        (sum - sum[length]) / length
 
filter(series float source, simple int length, simple string style)=>
    if length > 1
        switch style
            "EMA"  =>  ema(source, length)
            "DEMA" => dema(source, length)
            "TEMA" => tema(source, length)
            "WMA"  =>  wma(source, length)
            =>         sma(source, length)
    else
        source
 
color_changer(color source, bool direction)=>
    float r = color.r(source)
    float g = color.g(source)
    float b = color.b(source)
    if direction
        color.rgb((255 - r) / 3 + r, (255 - g) / 3 + g, (255 - b) / 3 + b)
    else
        color.rgb(r / 1.5, g / 1.5, b / 1.5)
 
const string settings = "Settings"
float source = input.source(close, "Source", group = settings)
int momentum_length = input.int(50, "Momentum Length", minval = 1, group = settings)
float momentum_smoothing = input.float(50, "Momentum Smoothing", tooltip = "Adjust the level of smoothing for the momentum length. The longer the momentum length the more you can smooth it.", minval = 1, group = settings)
int post_smoothing = input.int(4, "Post Smoothing", minval = 1, tooltip = "Adjust the level of smoothing for the indicator.", group = settings)
string post_smoothing_style = input.string("WMA", "Post Smoothing Style", ["EMA", "DEMA", "TEMA", "WMA", "SMA"], group = settings)
int ma_length = input.int(24, "MA Length", minval = 2, group = settings)
string ma_style = input.string("EMA", "MA Style", ["EMA", "DEMA", "TEMA", "WMA", "SMA"], group = settings)
const string style = "Style"
bool enable_projection = input.bool(true, "Ghost Mode", group = style)
int cd_alpha = input.int(25, "MA Difference Alpha", minval = 0, maxval = 100, group = style)
string candle_color_style = input.string("Both", "Candle Color Style", ["MA", "Direct", "Both", "None"]
 , tooltip = "MA: Use the moving average convergance divergance to color the candles."
 + "\n\n" + "Direct: Use the momentum as a source of color. When the momentum is positive it will be the bullish color and when its negative it will be the bearish color."
 + "\n\n" + "Both: Color the candles bassed on the ma and the polarity of the momentum. The bullish color will be darker if the momentum is negative and the bearish color will be lighter if the momentum is positive."
 + "\n\n" + "None: Dont color the candles.", group = style)
 
color momentum_color = input.color(#ffffff, "Momentum Color", group = style)
color ma_color = input.color(#f7a000, "MA Color", group = style)
color cd_up_over = input.color(#2ac075, "Bullish Up", group = style)
color cd_up_under = input.color(#d5fce9, "Bullish Down", group = style)
color cd_down_under = input.color(#f82934, "Bearish Down", group = style)
color cd_down_over = input.color(#ffc8cb, "Bearish Up", group = style)
bool glow = input.bool(true, "Glow", group = style)
 
 
int length_correction = momentum_length * 2
float sinc = lti_sinc(source, length_correction, momentum_smoothing)
int offset = offset(length_correction)
float delta = filter((source - sinc) / offset, post_smoothing, post_smoothing_style)
float projection = math.avg(delta - delta[1], (delta - delta[2]) / 2)
float ma = filter(filter(delta, 2, ma_style), ma_length, ma_style)
float ma_project = math.avg(ma - ma[1], (ma - ma[2]) / 2)
 
float momo = delta - ma
var color momo_color = na
if momo > 0
    if momo > momo[1]
        momo_color := cd_up_over
    else
        momo_color := cd_up_under
else
    if momo < momo[1]
        momo_color := cd_down_under
    else
        momo_color := cd_down_over
 
var color direct_color = na
 
if candle_color_style == "Both"
    if delta > 0
        if momo < 0
            direct_color := color_changer(momo_color, true)
        else
            direct_color := momo_color
    else
        if momo > 0
            direct_color := color_changer(momo_color, false)
        else
            direct_color := momo_color
else
    if delta > 0
        if delta > delta[1]
            direct_color := cd_up_over
        else
            direct_color := cd_up_under
 
    else
        if delta < delta[1]
            direct_color := cd_down_under
        else
            direct_color := cd_down_over
 
hline(0)
plot(momo, "Convergance Divergence", color.new(momo_color, cd_alpha), 5, glow ? plot.style_histogram : plot.style_columns)
plot(glow ? momo : na, "Convergance Divergence Glow", color.new(momo_color, cd_alpha + (100 - cd_alpha) / 2), 1, plot.style_columns, display = display.pane)
plot(ma, "MA", ma_color)
a = plot(glow ? ma : na, "MA Glow", color.new(ma_color, 80), 4, display = display.pane)
plot(delta, "Momentum", momentum_color)
b = plot(glow ? delta : na, "Momentum Glow", color.new(momentum_color, 80), 4, display = display.pane)
fill(a, b, color.new(delta > ma ? momentum_color : ma_color, 90), "Momentum Fill", editable = true)
 
var float p_ma1 = na
var float p_ma2 = na
var float p_m1 = na
var float p_m2 = na
 
if enable_projection
    p_ma1 := ma + ma_project
    p_m1 := delta + projection
    p_ma2 := ma + ma_project * 2
    p_m2 := delta + projection * 2
    var line project_delta = line.new(na, na, na, na, color = momentum_color, style = line.style_dotted)
    var line project_ma = line.new(na, na, na, na, color = ma_color, style = line.style_dotted)
    project_ma.set_xy1(bar_index, ma)
    project_ma.set_xy2(bar_index + 2, p_ma2)
    project_delta.set_xy1(bar_index, delta)
    project_delta.set_xy2(bar_index + 2, p_m2)
    linefill.new(project_delta, project_ma, color.new(p_ma2 > p_m2 ? ma_color : momentum_color, 90))
 
float d1 = p_m1 - p_ma1
float d2 = p_m2 - p_ma2
 
color dc1 = na
color dc2 = na
 
if d1 > 0
    if d1 > momo
        dc1 := cd_up_over
    else
        dc1 := cd_up_under
else
    if d1 < momo
        dc1 := cd_down_under
    else
        dc1 := cd_down_over
 
if d2 > 0
    if d2 > d1
        dc2 := cd_up_over
    else
        dc2 := cd_up_under
else
    if d2 < d1
        dc2 := cd_down_under
    else
        dc2 := cd_down_over
 
plot(d1, "Projected Delta", color.new(dc1, 60), 1, plot.style_columns, offset = 1, show_last = 1)
plot(d2, "Projected Delta", color.new(dc2, 60), 1, plot.style_columns, offset = 2, show_last = 1)
 
bar_color = switch candle_color_style
    "MA" => momo_color
    "Both" => direct_color
    "Direct" => direct_color
    "None" => na
 
barcolor(bar_color)

← 返回列表