MACD Based Price Forecasting [LuxAlgo]

LuxAlgo · study · 157 行 · 点赞 8,460 · TradingView 原页

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

Pine Script

// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo
 
//@version=5
indicator("MACD Based Price Forecasting [LuxAlgo]", "LuxAlgo - MACD Based Price Forecasting", overlay = true, max_lines_count = 500)
//---------------------------------------------------------------------------------------------------------------------}
//Settings
//---------------------------------------------------------------------------------------------------------------------{
//MACD
fast = input.int(12, 'Fast Length', minval = 2, group = 'MACD')
slow = input.int(26, 'Slow Length', minval = 2, group = 'MACD')
sigLen = input.int(9, 'Signal Length', minval = 2, group = 'MACD')
 
trend = input.string('MACD - Signal', 'Trend Determination',
  options = ['MACD', 'MACD - Signal'],
  group = 'MACD')
 
//Forecast
maxMemory = input.int(50, 'Maximum Memory', minval = 2, group = 'Forecast')
fcast = input.int(100, 'Forecasting Length', minval = 1, group = 'Forecast')
upPer = input(80, 'Top Percentile', group = 'Forecast')
midPer = input(50, 'Average Percentage', group = 'Forecast')
dnPer = input(20, 'Bottom Percentile', group = 'Forecast')
 
//Style
upLine = input(#3179f5, 'Line Color', inline = 'css', group = 'Style')
dnLine = input(#ff5d00, '', inline = 'css', group = 'Style')
 
upArea = input(color.new(#3179f5, 80), 'Areas', inline = 'areas', group = 'Style')
dnArea = input(color.new(#ff5d00, 80), '', inline = 'areas', group = 'Style')
 
signalArea = input(true, 'Signal Area', inline = 'signal', group = 'Style')
signalBull = input(color.new(#089981, 50), '', inline = 'signal', group = 'Style')
signalBear = input(color.new(#f23645, 50), '', inline = 'signal', group = 'Style')
 
//---------------------------------------------------------------------------------------------------------------------}
//Types
//---------------------------------------------------------------------------------------------------------------------{
type vector
    array<float> id
 
type holder
    array<vector> id
 
//---------------------------------------------------------------------------------------------------------------------}
//Methods/Functions
//---------------------------------------------------------------------------------------------------------------------{
n = bar_index
 
method populate(holder get_holder, idx, init_price)=>
    if get_holder.id.size() < idx+1
        get_holder.id.push(vector.new(array.new<float>(0)))
 
    get_holder.id.get(idx).id.unshift(close - init_price)
    
    //Remove last element if array size is greater than specified limit
    if get_holder.id.get(idx).id.size() > maxMemory
        get_holder.id.get(idx).id.pop()
 
method forecast(holder get_holder, idx, init_price, upper_coords, mid_coords, lower_coords)=>
    max_horizon = get_holder.id.size()
 
    x = 0
    for i = idx-1 to math.min(idx+fcast, max_horizon-1)
        get_vector = get_holder.id.get(i)
        
        //Compute forecasts
        upper = init_price + get_vector.id.percentile_linear_interpolation(upPer)
        mid   = init_price + get_vector.id.percentile_linear_interpolation(midPer)
        lower = init_price + get_vector.id.percentile_linear_interpolation(dnPer)
 
        //Append coordinates
        upper_coords.push(chart.point.from_index(n+x, upper))
        mid_coords.push(chart.point.from_index(n+x, mid))
        lower_coords.unshift(chart.point.from_index(n+x, lower))
        x += 1
 
//---------------------------------------------------------------------------------------------------------------------}
//Calculations
//---------------------------------------------------------------------------------------------------------------------{
var memory = map.new<int, holder>()
var up_idx = 0
var dn_idx = 0
var uptrend_init_price = close
var downtrend_init_price = close
 
//Compute MACD
[macd, signal, _] = ta.macd(close, fast, slow, sigLen)
 
//Populate map
if barstate.isfirst
    memory.put(1, holder.new(array.new<vector>(0)))
    memory.put(0, holder.new(array.new<vector>(0)))
 
trigger = switch trend
    'MACD' => ta.cross(macd, 0)
    => ta.cross(macd, signal)
 
uptrend = trend == 'MACD' ? macd > 0 : macd > signal
downtrend = trend == 'MACD' ? macd < 0 : macd < signal
 
//Reference prices
uptrend_init_price := uptrend and not uptrend[1] ? close : uptrend_init_price
downtrend_init_price := downtrend and not downtrend[1] ? close : downtrend_init_price
init_value = uptrend ? uptrend_init_price : downtrend_init_price
 
//Uptrend
if uptrend
    get_holder = memory.get(1)
    get_holder.populate(up_idx, uptrend_init_price)
 
//Downtrend
if downtrend
    get_holder = memory.get(0)
    get_holder.populate(dn_idx, downtrend_init_price)
 
//Indices
up_idx := not uptrend ? 0 : up_idx + 1
dn_idx := not downtrend ? 0 : dn_idx + 1
 
if trigger
    upper_coords = array.new<chart.point>(0)
    mid_coords = array.new<chart.point>(0)
    lower_coords = array.new<chart.point>(0)
 
    if uptrend
        get_holder = memory.get(1)
        get_holder.forecast(up_idx, uptrend_init_price, upper_coords, mid_coords, lower_coords)
    else
        get_holder = memory.get(0)
        get_holder.forecast(dn_idx, downtrend_init_price, upper_coords, mid_coords, lower_coords)
    
    polyline.delete(polyline.new(mid_coords, line_color = uptrend ? upLine : dnLine)[1])
 
    //Area
    polyline.delete(polyline.new(array.concat(upper_coords, lower_coords)
      , line_color = na
      , fill_color = uptrend ? upArea : dnArea)
      [1])
 
//---------------------------------------------------------------------------------------------------------------------}
//Plots
//---------------------------------------------------------------------------------------------------------------------{
init_plot = plot(init_value, "Reference Price", init_value != init_value[1] ? na : color.gray)
price_plot = plot(close, editable = false, display = display.none)
 
top_css = not signalArea ? na : uptrend ? signalBull : color.new(chart.bg_color, 100)
btm_css = not signalArea ? na : uptrend ? color.new(chart.bg_color, 100) : signalBear
 
//Price to Reference Area
fill(init_plot, price_plot,
  top_value = math.max(close, uptrend ? uptrend_init_price : downtrend_init_price),
  bottom_value = math.min(close, uptrend ? uptrend_init_price : downtrend_init_price),
  top_color = top_css,
  bottom_color = btm_css)
 
//---------------------------------------------------------------------------------------------------------------------}

← 返回列表