Machine Learning Momentum Index (MLMI) [Zeiierman]

Zeiierman · study · 104 行 · 点赞 5,103 · 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/
// © Zeiierman
 
//@version=5
indicator(title='Machine Learning Momentum Index (MLMI) [Zeiierman]', shorttitle='Machine Learning Momentum Index (MLMI)', overlay=false, precision=1)
 
// ~~ ToolTips {
t1 ="This parameter controls the number of neighbors to consider while making a prediction using the k-Nearest Neighbors (k-NN) algorithm. By modifying the value of k, you can change how sensitive the prediction is to local fluctuations in the data. \n\nA smaller value of k will make the prediction more sensitive to local variations and can lead to a more erratic prediction line. \n\nA larger value of k will consider more neighbors, thus making the prediction more stable but potentially less responsive to sudden changes."
t2 ="The parameter controls the length of the trend used in computing the momentum. This length refers to the number of periods over which the momentum is calculated, affecting how quickly the indicator reacts to changes in the underlying price movements. \n\nA shorter trend length (smaller momentumWindow) will make the indicator more responsive to short-term price changes, potentially generating more signals but at the risk of more false alarms. \n\nA longer trend length (larger momentumWindow) will make the indicator smoother and less responsive to short-term noise, but it may lag in reacting to significant price changes."
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ Input Parameters {
numNeighbors   = input(200, title='Prediction Data (k)', tooltip=t1)
momentumWindow = input.int(20, step=2, minval=10, maxval=200, title='Trend Length', tooltip=t2)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ Moving Averages & RSI {
MA_quick    = ta.wma(close, 5)
MA_slow     = ta.wma(close, 20)
rsi_quick   = ta.wma(ta.rsi(close, 5),momentumWindow)
rsi_slow    = ta.wma(ta.rsi(close, 20),momentumWindow)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ Crossover Conditions {
pos  = ta.crossover(MA_quick, MA_slow)
neg  = ta.crossunder(MA_quick, MA_slow)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ Type Definition {
type Data
    array<float> parameter1
    array<float> parameter2
    array<float> priceArray
    array<float> resultArray
 
// Create a Data object
var data = Data.new(array.new_float(1, 0), array.new_float(1, 0), array.new_float(1, 0), array.new_float(1, 0))
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ Method that saves the last trade and temporarily holds the current one. {
method storePreviousTrade(Data d, p1, p2) =>
    d.parameter1.push(d.parameter1.get(d.parameter1.size() - 1))
    d.parameter2.push(d.parameter2.get(d.parameter2.size() - 1))
    d.priceArray.push(d.priceArray.get(d.priceArray.size() - 1))
    d.resultArray.push(close >= d.priceArray.get(d.priceArray.size() - 1) ? 1 : -1)
 
    d.parameter1.set(d.parameter1.size() - 1, p1)
    d.parameter2.set(d.parameter2.size() - 1, p2)
    d.priceArray.set(d.priceArray.size() - 1, close)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ Method to Make Prediction {
method knnPredict(Data d, p1, p2, k) =>
    // Create a Distance Array
    distances = array.new_float(0)
    n = d.parameter1.size() - 1
    for i = 0 to n
        distance = math.sqrt(math.pow(p1 - d.parameter1.get(i), 2) + math.pow(p2 - d.parameter2.get(i), 2))
        distances.push(distance)
 
    // Get Neighbors
    sortedDistances = distances.copy()
    sortedDistances.sort()
    selectedDistances = sortedDistances.slice( 0, math.min(k, sortedDistances.size()))
    maxDist  = selectedDistances.max()
    neighbors = array.new_float(0)
    for i = 0 to distances.size() - 1
        if distances.get(i) <= maxDist
            neighbors.push(d.resultArray.get(i))
 
    // Return Prediction
    prediction = neighbors.sum()
    prediction
 
if pos or neg
    data.storePreviousTrade(rsi_slow, rsi_quick)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~} 
 
// ~~ Plots {
prediction = data.knnPredict(rsi_slow, rsi_quick, numNeighbors)
prediction_= plot(prediction, color=color.new(#426eff, 0), title="MLMI Prediction")
plot(ta.wma(prediction, 20), color=color.new(#31ffc8, 0), title="WMA of MLMI Prediction")
hline(0, title="Mid Level")
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ Gradient Fill {
upper         = ta.highest(prediction,2000)
lower         = ta.lowest(prediction,2000) 
upper_        = upper - ta.ema(ta.stdev(prediction,20),20)
lower_        = lower + ta.ema(ta.stdev(prediction,20),20)
channel_upper = plot(upper, color = na, editable = false, display = display.none)
channel_lower = plot(lower, color = na, editable = false, display = display.none)
channel_mid   = plot(0, color = na, editable = false, display = display.none)
 
// ~~ Channel Gradient Fill {
fill(channel_mid, channel_upper, top_value =  upper, bottom_value = 0, bottom_color = na, top_color = color.new(color.lime,75),title = "Channel Gradient Fill")
fill(channel_mid, channel_lower, top_value =  0, bottom_value = lower, bottom_color = color.new(color.red,75) , top_color = na,title = "Channel Gradient Fill")
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 
// ~~ Overbought/Oversold Gradient Fill {
fill(prediction_, channel_mid, upper, upper_, top_color = color.new(color.lime, 0), bottom_color = color.new(color.green, 100),title = "Overbought Gradient Fill")
fill(prediction_, channel_mid, lower_,  lower,  top_color = color.new(color.red, 100), bottom_color = color.new(color.red, 0),title = "Oversold Gradient Fill")
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}

← 返回列表