Traslate code TV to Prorealtime: Markov Chain Trend Probability

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #261462 quote
    Barrabas15
    Participant
    Master

    I would like the following TradingView code to be converted into Prorealtime. Would that be possible?


    //Developed by Henrique Centieiro

    //Inspired by the great Andrey Markov

    //@version=5

    indicator(“Markov Chain Trend Probability”, overlay=false)


    // Input parameters

    lookback_period = input.int(14, title=”Lookback Period (n)”, minval=1, maxval=50)

    atr_threshold = input.float(0.5, title=”ATR Threshold Multiplier (X)”, minval=0.1, maxval=2.0, step=0.1)

    history_length = input.int(33, title=”Historical Periods for Probability”, minval=1, maxval=100)

    atr_length = input.int(14, title=”ATR Length”, minval=1, maxval=50)

    brier_lookback = input.int(20, title=”Brier Score Lookback”, minval=1, maxval=100)


    // Colors

    uptrend_color = input.color(color.green, title=”Uptrend Color”)

    downtrend_color = input.color(color.red, title=”Downtrend Color”)

    brier_color = input.color(color.orange, title=”Brier Score Color”)


    // Brier Score line settings

    show_brier = input.bool(true, title=”Show Brier Score”)

    brier_style = input.string(“Dashed”, title=”Brier Score Line Style”, options=[“Solid”, “Dashed”, “Dotted”])

    brier_width = input.int(1, title=”Brier Score Line Width”, minval=1, maxval=4)


    // Calculate ATR

    atr_value = ta.atr(atr_length)


    // Define states based on price movement and ATR

    price_change = close – close[lookback_period]

    atr_normalized_change = price_change / atr_value


    // State identification (removed sideways state)

    var int UPTREND = 1

    var int DOWNTREND = -1


    // Variable to store current state

    var int current_state = UPTREND


    // Update state logic

    if atr_normalized_change > atr_threshold

      current_state := UPTREND

    else if atr_normalized_change < -atr_threshold

      current_state := DOWNTREND

    // If within threshold, keep previous state (no change to current_state)


    // Store historical states

    var array<int> state_history = array.new<int>()


    if barstate.isconfirmed

      array.unshift(state_history, current_state)

      if array.size(state_history) > history_length

        array.pop(state_history)


    // Calculate transition probabilities

    calculate_transition_probability(from_state, to_state) =>

      transitions = 0

      total_from_state = 0

       

      if array.size(state_history) >= 2

        for i = 0 to array.size(state_history) – 2

          current = array.get(state_history, i)

          next = array.get(state_history, i + 1)

           

          if current == from_state

            total_from_state += 1

            if next == to_state

              transitions += 1

       

      total_from_state > 0 ? transitions / total_from_state : 0.0


    // Calculate all transition probabilities

    p_up_to_up = calculate_transition_probability(UPTREND, UPTREND)

    p_up_to_down = calculate_transition_probability(UPTREND, DOWNTREND)

    p_down_to_up = calculate_transition_probability(DOWNTREND, UPTREND)

    p_down_to_down = calculate_transition_probability(DOWNTREND, DOWNTREND)


    // Calculate steady-state probabilities (probability of being in each state)

    calculate_state_probability(target_state) =>

      count = 0

      total = array.size(state_history)

       

      if total > 0

        for i = 0 to total – 1

          if array.get(state_history, i) == target_state

            count += 1

       

      total > 0 ? count / total : 0.0


    prob_uptrend = calculate_state_probability(UPTREND)

    prob_downtrend = calculate_state_probability(DOWNTREND)


    // Brier Score calculation variables

    var array<float> predictions = array.new<float>()

    var array<int> actuals = array.new<int>()


    // Store predictions and actual outcomes for Brier Score

    if barstate.isconfirmed and array.size(state_history) >= 2

      // Store the probability prediction made in the previous bar

      array.unshift(predictions, prob_uptrend[1])

       

      // Store the actual outcome (what actually happened)

      actual_outcome = current_state == UPTREND ? 1 : 0

      array.unshift(actuals, actual_outcome)

       

      // Keep only recent data

      if array.size(predictions) > brier_lookback

        array.pop(predictions)

        array.pop(actuals)


    // Calculate Brier Score

    calculate_brier_score() =>

      if array.size(predictions) < 1

        na

      else

        sum_squared_diff = 0.0

        size = array.size(predictions)

        for i = 0 to size – 1

          pred = array.get(predictions, i)

          actual = array.get(actuals, i)

          sum_squared_diff += math.pow(pred – actual, 2)

        sum_squared_diff / size


    brier_score = calculate_brier_score()


    // Functions to classify Brier Score accuracy

    get_brier_text(score) =>

      if na(score)

        “Calculating…”

      else if score < 0.10

        “Exceptional”

      else if score < 0.15

        “Excellent”

      else if score < 0.20

        “Very Good”

      else if score < 0.25

        “Good”

      else if score < 0.30

        “Fair”

      else

        “Poor”


    get_brier_color(score) =>

      if na(score)

        color.gray

      else if score < 0.10

        color.new(color.lime, 0)

      else if score < 0.15

        color.new(color.green, 0)

      else if score < 0.20

        color.new(color.blue, 0)

      else if score < 0.25

        color.new(color.orange, 0)

      else if score < 0.30

        color.new(color.yellow, 0)

      else

        color.new(color.red, 0)


    // Convert to percentage values for proper scaling (0-100 instead of 0-1)

    prob_uptrend_pct = prob_uptrend * 100

    prob_downtrend_pct = prob_downtrend * 100

    brier_score_pct = na(brier_score) ? na : brier_score * 100


    // Background color based on current state

    bg_color = current_state == UPTREND ? color.new(uptrend_color, 95) : color.new(downtrend_color, 95)

    bgcolor(bg_color, title=”State Background”)


    // Create table for current information

    var table info_table = table.new(position.middle_left, 2, 6, bgcolor=color.white, border_width=1)


    if barstate.islast

      table.cell(info_table, 0, 0, “Current State”, text_color=color.black, bgcolor=color.gray)

      state_text = current_state == UPTREND ? “UPTREND” : “DOWNTREND”

      state_color = current_state == UPTREND ? uptrend_color : downtrend_color

      table.cell(info_table, 1, 0, state_text, text_color=color.white, bgcolor=state_color)

       

      table.cell(info_table, 0, 1, “ATR Change”, text_color=color.black)

      table.cell(info_table, 1, 1, str.tostring(atr_normalized_change, “#.##”), text_color=color.black)

       

      table.cell(info_table, 0, 2, “P(Uptrend)”, text_color=color.black)

      table.cell(info_table, 1, 2, str.tostring(prob_uptrend * 100, “#.#”) + “%”, text_color=uptrend_color)

       

      table.cell(info_table, 0, 3, “P(Downtrend)”, text_color=color.black)

      table.cell(info_table, 1, 3, str.tostring(prob_downtrend * 100, “#.#”) + “%”, text_color=downtrend_color)

       

      table.cell(info_table, 0, 4, “P(Up→Up) | P(Down→Down)”, text_color=color.black)

      table.cell(info_table, 1, 4, str.tostring(p_up_to_up * 100, “#.#”) + “% | ” + str.tostring(p_down_to_down * 100, “#.#”) + “%”, text_color=color.black)

       

      // Brier Score classification

      table.cell(info_table, 0, 5, “Model Accuracy (Brier Score)”, text_color=color.black)

      table.cell(info_table, 1, 5, get_brier_text(brier_score), text_color=get_brier_color(brier_score))


    // Convert line style string to Pine Script constant

    get_line_style(style_str) =>

      switch style_str

        “Solid” => plot.style_line

        “Dashed” => plot.style_stepline

        “Dotted” => plot.style_circles

        => plot.style_circles


    // Plot probabilities as percentages (0-100 scale)

    plot(prob_uptrend_pct, title=”Uptrend Probability”, color=uptrend_color, linewidth=2)

    plot(prob_downtrend_pct, title=”Downtrend Probability”, color=downtrend_color, linewidth=2)


    // Plot Brier Score as a line (scaled to 0-100 for visibility)

    plot(show_brier ? brier_score_pct : na, title=”Brier Score (%)”, color=brier_color, linewidth=brier_width, style=get_line_style(brier_style))


    // Add horizontal reference lines (now in percentage scale 0-100)

    hline(50, title=”50% Line”, color=color.gray, linestyle=hline.style_dashed)

    hline(30, title=”30% Line”, color=color.gray, linestyle=hline.style_dotted)

    hline(70, title=”70% Line”, color=color.gray, linestyle=hline.style_dotted)

    hline(10, title=”10% Line”, color=color.gray, linestyle=hline.style_dotted)

    hline(90, title=”90% Line”, color=color.gray, linestyle=hline.style_dotted)

    hline(25, title=”Random Baseline (25%)”, color=color.yellow, linestyle=hline.style_dashed)

    hline(15, title=”Excellent Threshold (15%)”, color=color.lime, linestyle=hline.style_dotted)


    // Alerts (using original 0-1 scale for logic)

    alertcondition(prob_uptrend > 0.7, title=”High Uptrend Probability”, message=”Uptrend probability > 70%”)

    alertcondition(prob_downtrend > 0.7, title=”High Downtrend Probability”, message=”Downtrend probability > 70%”)

    alertcondition(ta.crossover(prob_uptrend, prob_downtrend), title=”Uptrend Probability Crossover”, message=”Uptrend probability crossed above downtrend probability”)

    alertcondition(ta.crossover(prob_downtrend, prob_uptrend), title=”Downtrend Probability Crossover”, message=”Downtrend probability crossed above uptrend probability”)

    alertcondition(not na(brier_score) and brier_score < 0.15, title=”Excellent Model Accuracy”, message=”Brier Score indicates excellent prediction accuracy”)

    alertcondition(not na(brier_score) and brier_score > 0.3, title=”Poor Model Accuracy”, message=”Brier Score indicates poor prediction accuracy”)

    #261463 quote
    Barrabas15
    Participant
    Master
    #261466 quote
    Iván González
    Moderator
    Legend

    Here you have:

    //----------------------------------------------
    //PRC_Markov Chain Trend Probability
    //version = 0
    //22.05.26
    //Iván González @ www.prorealcode.com
    //Traducido de "Markov Chain Trend Probability" (PineScript v5)
    //Autor original: Henrique Centieiro
    //Sharing ProRealTime knowledge
    //----------------------------------------------
    // === Inputs ===
    lookbackPeriod = 14    // n: ventana de cambio de precio
    atrThreshold = 0.5     // X: umbral en multiplos de ATR
    historyLength = 33     // historico de estados para probabilidades
    atrLength = 14         // periodo del ATR
    brierLB = 20           // ventana para Brier Score
    
    // Constantes de estado
    UPTREND = 1
    DOWNTREND = -1
    //----------------------------------------------
    // === ATR y cambio normalizado ===
    //----------------------------------------------
    atrValue = averagetruerange[atrLength]
    priceChange = close - close[lookbackPeriod]
    
    if atrValue > 0 then
       atrNormChange = priceChange / atrValue
    else
       atrNormChange = 0
    endif
    //----------------------------------------------
    // === State machine UPTREND / DOWNTREND con carry-over ===
    //----------------------------------------------
    warmup = max(lookbackPeriod, atrLength)
    
    if barindex < warmup then
       currentState = UPTREND
    elsif atrNormChange > atrThreshold then
       currentState = UPTREND
    elsif atrNormChange < 0 - atrThreshold then
       currentState = DOWNTREND
    else
       currentState = currentState[1]
    endif
    //----------------------------------------------
    // === Buffer FIFO de estados (slot[0] = mas reciente) ===
    //----------------------------------------------
    once stateCount = 0
    
    for k = historyLength - 1 downto 1 do
       $stateHist[k] = $stateHist[k - 1]
    next
    $stateHist[0] = currentState
    
    if stateCount < historyLength then
       stateCount = stateCount + 1
    endif
    //----------------------------------------------
    // === Probabilidades de transicion ===
    // (cronologicas: slot[i+1] = anterior, slot[i] = siguiente)
    //----------------------------------------------
    upToUp = 0
    upTotal = 0
    downToDown = 0
    downTotal = 0
    
    if stateCount >= 2 then
       for i = 0 to stateCount - 2 do
          fromState = $stateHist[i + 1]
          toState = $stateHist[i]
          
          if fromState = UPTREND then
             upTotal = upTotal + 1
             if toState = UPTREND then
                upToUp = upToUp + 1
             endif
          elsif fromState = DOWNTREND then
             downTotal = downTotal + 1
             if toState = DOWNTREND then
                downToDown = downToDown + 1
             endif
          endif
       next
    endif
    
    if upTotal > 0 then
       pUpToUp = upToUp / upTotal
    else
       pUpToUp = 0
    endif
    
    if downTotal > 0 then
       pDownToDown = downToDown / downTotal
    else
       pDownToDown = 0
    endif
    //----------------------------------------------
    // === Probabilidades estacionarias ===
    //----------------------------------------------
    upCount = 0
    if stateCount > 0 then
       for i = 0 to stateCount - 1 do
          if $stateHist[i] = UPTREND then
             upCount = upCount + 1
          endif
       next
       probUp = upCount / stateCount
       probDown = 1 - probUp
    else
       probUp = 0
       probDown = 0
    endif
    //----------------------------------------------
    // === Brier Score ===
    // Prediccion en t-1 vs outcome observado en t
    //----------------------------------------------
    once brierCount = 0
    
    if stateCount >= 2 then
       for k = brierLB - 1 downto 1 do
          $predHist[k] = $predHist[k - 1]
          $actHist[k] = $actHist[k - 1]
       next
       $predHist[0] = probUp[1]
       if currentState = UPTREND then
          $actHist[0] = 1
       else
          $actHist[0] = 0
       endif
       
       if brierCount < brierLB then
          brierCount = brierCount + 1
       endif
    endif
    
    if brierCount > 0 then
       sumSq = 0
       for i = 0 to brierCount - 1 do
          diff = $predHist[i] - $actHist[i]
          sumSq = sumSq + diff * diff
       next
       brierPct = sumSq / brierCount * 100
    else
       brierPct = undefined
    endif
    //----------------------------------------------
    // === Salidas (escala 0..100) ===
    //----------------------------------------------
    pUpPct = probUp * 100
    pDnPct = probDown * 100
    
    // Lineas horizontales de referencia
    linMid = 50
    linBaseline = 25
    linExcel = 15
    
    return pUpPct coloured(76, 175, 80, 255) as "P(Up) %", pDnPct coloured(244, 67, 54, 255) as "P(Down) %", brierPct coloured(255, 152, 0, 255) style(dottedline, 2) as "Brier Score %", linMid coloured(150, 150, 150, 150) style(dottedline2, 1) as "Neutral 50%", linBaseline coloured(255, 235, 59, 200) style(dottedline2, 1) as "Random Baseline 25%", linExcel coloured(76, 175, 80, 200) style(dottedline, 1) as "Excellent 15%"
    



    BTCUSD-Diario-2.png BTCUSD-Diario-2.png
    #261479 quote
    Barrabas15
    Participant
    Master

    Muchas gracias, Iván. ¡Eres un crack!

    Iván González thanked this post
Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.

TradingView to ProRealTime Translation Center

New Reply
Author
author-avatar
Barrabas15 @barrabas15 Participant
Summary

This topic contains 3 replies,
has 2 voices, and was last updated by Barrabas15
1 week ago.

Topic Details
Forum: TradingView to ProRealTime Translation Center Forum
Started: 05/21/2026
Status: Active
Attachments: 1 files
Logo Logo
Loading...