Indicateur : Volume profile fixe PRC pour ProRealTime

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #259114 quote
    larouedegann
    Participant
    Master

    Bonjour,

    Vous trouverez ci-dessous le code Volume profile tel qu’il est dans la bibliothèque.

    // ----------------------------------------------
    // PRC_Volume Profile / Fixed Range (by LonesomeTheBlue)
    // version = 0
    // 30.09.2024
    // Iván González @ www.prorealcode.com
    // Sharing ProRealTime knowledge
    // ----------------------------------------------
    defparam drawonlastbaronly = true
    // ----------------------------------------------
    // === PARAMETERS ===
    // ----------------------------------------------
    bbars = 150       // Number of bars to analyze
    cnum = 24         // Number of rows (channels)
    pctVA = 70        // Value Area Volume %
    showPOC = 1       // Show POC label (1=yes, 0=no)
    showVAHL = 1      // Show VAH/VAL labels (1=yes, 0=no)
    pocExtend = 50    // POC/VAH/VAL line extension in bars
    // ----------------------------------------------
    // === COLOR SETTINGS (RGB + Alpha) ===
    // ----------------------------------------------
    // POC line (red)
    pocR = 255
    pocG = 0
    pocB = 0
    
    
    
    
    // VAH/VAL lines (grey)
    vaLineR = 128
    vaLineG = 128
    vaLineB = 128
    
    
    
    
    // Value Area Up volume (blue, 70% opaque)
    vaUpR = 33
    vaUpG = 150
    vaUpB = 243
    vaUpA = 178
    
    
    
    
    // Value Area Down volume (orange, 70% opaque)
    vaDnR = 255
    vaDnG = 152
    vaDnB = 0
    vaDnA = 178
    
    
    
    
    // Up Volume outside VA (blue, 25% opaque)
    upVolR = 33
    upVolG = 150
    upVolB = 243
    upVolA = 64
    
    
    
    
    // Down Volume outside VA (orange, 25% opaque)
    dnVolR = 255
    dnVolG = 152
    dnVolB = 0
    dnVolA = 64
    // ----------------------------------------------
    // === ATR for label offset ===
    // ----------------------------------------------
    atr = averagetruerange[14]
    
    
    
    
    // ----------------------------------------------
    // MAIN CALCULATION (only on last bar)
    // ----------------------------------------------
    if barindex >= bbars and islastbarupdate then
    
    
    
    
    topPrice = highest[bbars](high)
    botPrice = lowest[bbars](low)
    gap = (topPrice - botPrice) / 500
    stepSize = (topPrice - botPrice) / cnum
    
    
    
    
    // --- Store channel levels ---
    for x = 0 to cnum do
    $levels[x] = botPrice + stepSize * x
    next
    
    
    
    
    // --- Initialize volume arrays ---
    // $vol[0..cnum-1] = up (green) volume
    // $vol[cnum..2*cnum-1] = down (red) volume
    for x = 0 to cnum * 2 - 1 do
    $vol[x] = 0
    next
    
    
    
    
    // --- Distribute volume across channels ---
    for b = 0 to bbars - 1 do
    bTop = max(close[b], open[b])
    bBot = min(close[b], open[b])
    
    
    
    
    if close[b] >= open[b] then
    isGreen = 1
    else
    isGreen = 0
    endif
    
    
    
    
    tw = high[b] - bTop
    bw = bBot - low[b]
    bd = bTop - bBot
    denom = 2 * tw + 2 * bw + bd
    
    
    
    
    if denom > 0 then
    bdVol = bd * volume[b] / denom
    twVol = 2 * tw * volume[b] / denom
    bwVol = 2 * bw * volume[b] / denom
    else
    bdVol = 0
    twVol = 0
    bwVol = 0
    endif
    
    
    
    
    for x = 0 to cnum - 1 do
    lLo = $levels[x]
    lHi = $levels[x + 1]
    
    
    
    
    // Body overlap
    if bd > 0 then
    bdOvlp = max(0, min(lHi, bTop) - max(lLo, bBot))
    bdC = bdOvlp * bdVol / bd
    else
    bdC = 0
    endif
    
    
    
    
    // Top wick overlap
    if tw > 0 then
    twOvlp = max(0, min(lHi, high[b]) - max(lLo, bTop))
    twC = twOvlp * twVol / tw
    else
    twC = 0
    endif
    
    
    
    
    // Bottom wick overlap
    if bw > 0 then
    bwOvlp = max(0, min(lHi, bBot) - max(lLo, low[b]))
    bwC = bwOvlp * bwVol / bw
    else
    bwC = 0
    endif
    
    
    
    
    // Accumulate up volume (green body + half wicks)
    if isGreen = 1 then
    $vol[x] = $vol[x] + bdC + twC / 2 + bwC / 2
    else
    $vol[x] = $vol[x] + twC / 2 + bwC / 2
    endif
    
    
    
    
    // Accumulate down volume (red body + half wicks)
    if isGreen = 1 then
    $vol[x + cnum] = $vol[x + cnum] + twC / 2 + bwC / 2
    else
    $vol[x + cnum] = $vol[x + cnum] + bdC + twC / 2 + bwC / 2
    endif
    next
    next
    
    
    
    
    // --- Find POC and totals ---
    maxVol = 0
    pocIdx = 0
    totalSum = 0
    
    
    
    
    for x = 0 to cnum - 1 do
    $totals[x] = $vol[x] + $vol[x + cnum]
    totalSum = totalSum + $totals[x]
    if $totals[x] > maxVol then
    maxVol = $totals[x]
    pocIdx = x
    endif
    next
    
    
    
    
    // --- Calculate Value Area ---
    vaTotal = $totals[pocIdx]
    vaThreshold = totalSum * pctVA / 100
    vaUp = pocIdx
    vaDown = pocIdx
    vaDone = 0
    
    
    
    
    for x = 0 to cnum - 1 do
    if vaDone = 0 then
    if vaTotal >= vaThreshold then
    vaDone = 1
    else
    if vaUp < cnum - 1 then
    upperV = $totals[vaUp + 1]
    else
    upperV = 0
    endif
    
    
    
    
    if vaDown > 0 then
    lowerV = $totals[vaDown - 1]
    else
    lowerV = 0
    endif
    
    
    
    
    if upperV = 0 and lowerV = 0 then
    vaDone = 1
    else
    if upperV >= lowerV then
    vaTotal = vaTotal + upperV
    vaUp = vaUp + 1
    else
    vaTotal = vaTotal + lowerV
    vaDown = vaDown - 1
    endif
    endif
    endif
    endif
    next
    
    
    
    
    // --- Scale volumes for display width ---
    if maxVol > 0 then
    for x = 0 to cnum * 2 - 1 do
    $vol[x] = $vol[x] * bbars / (3 * maxVol)
    next
    endif
    
    
    
    
    // --- Draw volume profile rectangles ---
    startX = barindex - bbars + 1
    
    
    
    
    for x = 0 to cnum - 1 do
    upW = round($vol[x])
    dnW = round($vol[x + cnum])
    y1 = $levels[x + 1] - gap
    y2 = $levels[x] + gap
    
    
    
    
    if x >= vaDown and x <= vaUp then
    // Inside Value Area
    if upW > 0 then
    drawrectangle(startX, y1, startX + upW, y2) coloured(vaUpR, vaUpG, vaUpB, 0) fillcolor(vaUpR, vaUpG, vaUpB, vaUpA)
    endif
    if dnW > 0 then
    drawrectangle(startX + upW, y1, startX + upW + dnW, y2) coloured(vaDnR, vaDnG, vaDnB, 0) fillcolor(vaDnR, vaDnG, vaDnB, vaDnA)
    endif
    else
    // Outside Value Area
    if upW > 0 then
    drawrectangle(startX, y1, startX + upW, y2) coloured(upVolR, upVolG, upVolB, 0) fillcolor(upVolR, upVolG, upVolB, upVolA)
    endif
    if dnW > 0 then
    drawrectangle(startX + upW, y1, startX + upW + dnW, y2) coloured(dnVolR, dnVolG, dnVolB, 0) fillcolor(dnVolR, dnVolG, dnVolB, dnVolA)
    endif
    endif
    next
    
    
    
    
    // --- Draw POC line + label ---
    pocLevel = ($levels[pocIdx] + $levels[pocIdx + 1]) / 2
    drawsegment(startX, pocLevel, barindex + pocExtend, pocLevel) coloured(pocR, pocG, pocB) style(line, 2)
    
    
    
    
    if showPOC = 1 then
    drawtext("POC: #pocLevel#", barindex + 15, pocLevel + 0.25 * atr) coloured(pocR, pocG, pocB)
    endif
    
    
    
    
    // --- Draw VAH line + label ---
    vahLevel = $levels[vaUp + 1]
    drawsegment(startX, vahLevel, barindex + pocExtend, vahLevel) coloured(vaLineR, vaLineG, vaLineB) style(dottedline, 1)
    
    
    
    
    if showVAHL = 1 then
    drawtext("VAH: #vahLevel#", barindex + 15, vahLevel + 0.25 * atr) coloured(vaLineR, vaLineG, vaLineB)
    endif
    
    
    
    
    // --- Draw VAL line + label ---
    valLevel = $levels[vaDown]
    drawsegment(startX, valLevel, barindex + pocExtend, valLevel) coloured(vaLineR, vaLineG, vaLineB) style(dottedline, 1)
    
    
    
    
    if showVAHL = 1 then
    drawtext("VAL: #valLevel#", barindex + 15, valLevel - 0.25 * atr) coloured(vaLineR, vaLineG, vaLineB)
    endif
    
    
    
    
    endif
    // --------------------------------------------
    RETURN
    

    Mes questions sont : pour la cas d’un graphique daily

    1/ Est-il possible de conserver l’antériorité de la VAH VAL (donc de la VA) sous forme de trait du début du calcul jusqu’à la fin.

    2/ Plutôt que de mettre des BBARS, mettre une heure de début et une heure de fin , ce qui permettrait de cadrer le marché asiatique,europe et US.en mettant 3 fois le code.Chose qui n’est pas possible avec celui de la bibliothèque.

    Merci

    #259127 quote
    Iván González
    Moderator
    Master

    Buenas!

    El primer punto es posible pero computacionalmente hablando no. Tiene demasiados bucles.

    Respecto al segundo punto, se puede poner hora de chequeo, eso sí, sería necesario poner un mensaje de advertencia para que el timeframe utilizado sea menor del diario.

    defparam drawonlastbaronly = true
    // ----------------------------------------------
    // === TIMEFRAME CHECK ===
    // ----------------------------------------------
    dailyOrHigher = 0
    if GetTimeFrame >= 86400 then
    dailyOrHigher = 1
    drawtext("This indicator requires an intraday timeframe. Please switch to a timeframe below Daily.", barindex, close) coloured(255, 0, 0)
    endif
    // ----------------------------------------------
    // === SESSION PARAMETERS ===
    // ----------------------------------------------
    // Enter times in HHMM format (e.g. 800 = 08:00, 1600 = 16:00)
    //   Asian:    startHHMM=2200, endHHMM=800
    //   European: startHHMM=800,  endHHMM=1530
    //   US:       startHHMM=1530, endHHMM=2200
    startHHMM = 800
    endHHMM = 1600
    cnum = 40             // Number of rows (channels)
    pctVA = 70            // Value Area Volume %
    showPOC = 1           // Show POC label (1=yes, 0=no)
    showVAHL = 1          // Show VAH/VAL labels (1=yes, 0=no)
    pocExtend = 50        // POC/VAH/VAL line extension in bars
    maxScanBars = 500     // Max bars to scan backwards
    // ----------------------------------------------
    // === COLOR SETTINGS (RGB + Alpha) ===
    // ----------------------------------------------
    // POC line (red)
    pocR = 255
    pocG = 0
    pocB = 0
    
    
    // VAH/VAL lines (grey)
    vaLineR = 128
    vaLineG = 128
    vaLineB = 128
    
    
    // Value Area Up volume (blue, 70% opaque)
    vaUpR = 33
    vaUpG = 150
    vaUpB = 243
    vaUpA = 178
    
    
    // Value Area Down volume (orange, 70% opaque)
    vaDnR = 255
    vaDnG = 152
    vaDnB = 0
    vaDnA = 178
    
    
    // Up Volume outside VA (blue, 25% opaque)
    upVolR = 33
    upVolG = 150
    upVolB = 243
    upVolA = 64
    
    
    // Down Volume outside VA (orange, 25% opaque)
    dnVolR = 255
    dnVolG = 152
    dnVolB = 0
    dnVolA = 64
    // ----------------------------------------------
    // === ATR for label offset ===
    // ----------------------------------------------
    atr = averagetruerange[14]
    
    
    // Convert HHMM to HHMMSS for time comparison
    startT = startHHMM * 100
    endT = endHHMM * 100
    
    
    // ----------------------------------------------
    // MAIN CALCULATION (intraday only, last bar only)
    // ----------------------------------------------
    if dailyOrHigher = 0 and islastbarupdate then
    
    
    // =============================================
    // Phase 1: Find session bar range
    // Scans backwards from current bar.
    // endOff   = offset of NEWEST bar in session
    // startOff = offset of OLDEST bar in session
    // =============================================
    endOff = -1
    startOff = -1
    scanDone = 0
    
    
    for i = 0 to maxScanBars
    if scanDone = 0 then
    bt = time[i]
    
    
    // Determine if bar is inside session
    inSess = 0
    if startT <= endT then
    // Normal session (no midnight crossing)
    if bt >= startT and bt <= endT then
    inSess = 1
    endif
    else
    // Midnight-crossing session (e.g. 22:00 to 08:00)
    if bt >= startT or bt <= endT then
    inSess = 1
    endif
    endif
    
    
    if endOff < 0 then
    // Still looking for first session bar
    if inSess = 1 then
    endOff = i
    startOff = i
    endif
    else
    // Already found session
    if inSess = 1 then
    startOff = i
    else
    scanDone = 1
    endif
    endif
    endif
    next
    
    
    // =============================================
    // Phase 2: Calculate Volume Profile
    // =============================================
    if endOff >= 0 and startOff >= endOff then
    sessionBars = startOff - endOff + 1
    
    
    // --- Find highest/lowest in session ---
    topPrice = high[endOff]
    botPrice = low[endOff]
    for i = endOff + 1 to startOff do
    if high[i] > topPrice then
    topPrice = high[i]
    endif
    if low[i] < botPrice then
    botPrice = low[i]
    endif
    next
    
    
    gap = (topPrice - botPrice) / 500
    stepSize = (topPrice - botPrice) / cnum
    
    
    // --- Store channel levels ---
    for x = 0 to cnum do
    $levels[x] = botPrice + stepSize * x
    next
    
    
    // --- Initialize volume arrays ---
    // $vol[0..cnum-1]       = up (green) volume
    // $vol[cnum..2*cnum-1]  = down (red) volume
    for x = 0 to cnum * 2 - 1 do
    $vol[x] = 0
    next
    
    
    // --- Distribute volume across channels ---
    for b = endOff to startOff do
    bTop = max(close[b], open[b])
    bBot = min(close[b], open[b])
    
    
    if close[b] >= open[b] then
    isGreen = 1
    else
    isGreen = 0
    endif
    
    
    tw = high[b] - bTop
    bw = bBot - low[b]
    bd = bTop - bBot
    denom = 2 * tw + 2 * bw + bd
    
    
    if denom > 0 then
    bdVol = bd * volume[b] / denom
    twVol = 2 * tw * volume[b] / denom
    bwVol = 2 * bw * volume[b] / denom
    else
    bdVol = 0
    twVol = 0
    bwVol = 0
    endif
    
    
    for x = 0 to cnum - 1 do
    lLo = $levels[x]
    lHi = $levels[x + 1]
    
    
    // Body overlap
    if bd > 0 then
    bdOvlp = max(0, min(lHi, bTop) - max(lLo, bBot))
    bdC = bdOvlp * bdVol / bd
    else
    bdC = 0
    endif
    
    
    // Top wick overlap
    if tw > 0 then
    twOvlp = max(0, min(lHi, high[b]) - max(lLo, bTop))
    twC = twOvlp * twVol / tw
    else
    twC = 0
    endif
    
    
    // Bottom wick overlap
    if bw > 0 then
    bwOvlp = max(0, min(lHi, bBot) - max(lLo, low[b]))
    bwC = bwOvlp * bwVol / bw
    else
    bwC = 0
    endif
    
    
    // Accumulate up volume (green body + half wicks)
    if isGreen = 1 then
    $vol[x] = $vol[x] + bdC + twC / 2 + bwC / 2
    else
    $vol[x] = $vol[x] + twC / 2 + bwC / 2
    endif
    
    
    // Accumulate down volume (red body + half wicks)
    if isGreen = 1 then
    $vol[x + cnum] = $vol[x + cnum] + twC / 2 + bwC / 2
    else
    $vol[x + cnum] = $vol[x + cnum] + bdC + twC / 2 + bwC / 2
    endif
    next
    next
    
    
    // --- Find POC and totals ---
    maxVol = 0
    pocIdx = 0
    totalSum = 0
    
    
    for x = 0 to cnum - 1 do
    $totals[x] = $vol[x] + $vol[x + cnum]
    totalSum = totalSum + $totals[x]
    if $totals[x] > maxVol then
    maxVol = $totals[x]
    pocIdx = x
    endif
    next
    
    
    // --- Calculate Value Area ---
    vaTotal = $totals[pocIdx]
    vaThreshold = totalSum * pctVA / 100
    vaUp = pocIdx
    vaDown = pocIdx
    vaDone = 0
    
    
    for x = 0 to cnum - 1 do
    if vaDone = 0 then
    if vaTotal >= vaThreshold then
    vaDone = 1
    else
    if vaUp < cnum - 1 then
    upperV = $totals[vaUp + 1]
    else
    upperV = 0
    endif
    
    
    if vaDown > 0 then
    lowerV = $totals[vaDown - 1]
    else
    lowerV = 0
    endif
    
    
    if upperV = 0 and lowerV = 0 then
    vaDone = 1
    else
    if upperV >= lowerV then
    vaTotal = vaTotal + upperV
    vaUp = vaUp + 1
    else
    vaTotal = vaTotal + lowerV
    vaDown = vaDown - 1
    endif
    endif
    endif
    endif
    next
    
    
    // --- Scale volumes for display width ---
    if maxVol > 0 then
    for x = 0 to cnum * 2 - 1 do
    $vol[x] = $vol[x] * sessionBars / (3 * maxVol)
    next
    endif
    
    
    // --- Draw volume profile rectangles ---
    startX = barindex - startOff
    
    
    for x = 0 to cnum - 1 do
    upW = round($vol[x])
    dnW = round($vol[x + cnum])
    y1 = $levels[x + 1] - gap
    y2 = $levels[x] + gap
    
    
    if x >= vaDown and x <= vaUp then
    // Inside Value Area
    if upW > 0 then
    drawrectangle(startX, y1, startX + upW, y2) coloured(vaUpR, vaUpG, vaUpB, 0) fillcolor(vaUpR, vaUpG, vaUpB, vaUpA)
    endif
    if dnW > 0 then
    drawrectangle(startX + upW, y1, startX + upW + dnW, y2) coloured(vaDnR, vaDnG, vaDnB, 0) fillcolor(vaDnR, vaDnG, vaDnB, vaDnA)
    endif
    else
    // Outside Value Area
    if upW > 0 then
    drawrectangle(startX, y1, startX + upW, y2) coloured(upVolR, upVolG, upVolB, 0) fillcolor(upVolR, upVolG, upVolB, upVolA)
    endif
    if dnW > 0 then
    drawrectangle(startX + upW, y1, startX + upW + dnW, y2) coloured(dnVolR, dnVolG, dnVolB, 0) fillcolor(dnVolR, dnVolG, dnVolB, dnVolA)
    endif
    endif
    next
    
    
    // --- Draw POC line + label ---
    pocLevel = ($levels[pocIdx] + $levels[pocIdx + 1]) / 2
    drawsegment(startX, pocLevel, barindex + pocExtend, pocLevel) coloured(pocR, pocG, pocB) style(line, 2)
    
    
    if showPOC = 1 then
    drawtext("POC: #pocLevel#", barindex + 15, pocLevel + 0.25 * atr) coloured(pocR, pocG, pocB)
    endif
    
    
    // --- Draw VAH line + label ---
    vahLevel = $levels[vaUp + 1]
    drawsegment(startX, vahLevel, barindex + pocExtend, vahLevel) coloured(vaLineR, vaLineG, vaLineB) style(dottedline, 1)
    
    
    if showVAHL = 1 then
    drawtext("VAH: #vahLevel#", barindex + 15, vahLevel + 0.25 * atr) coloured(vaLineR, vaLineG, vaLineB)
    endif
    
    
    // --- Draw VAL line + label ---
    valLevel = $levels[vaDown]
    drawsegment(startX, valLevel, barindex + pocExtend, valLevel) coloured(vaLineR, vaLineG, vaLineB) style(dottedline, 1)
    
    
    if showVAHL = 1 then
    drawtext("VAL: #valLevel#", barindex + 15, valLevel - 0.25 * atr) coloured(vaLineR, vaLineG, vaLineB)
    endif
    
    
    endif
    endif
    // ----------------------------------------------
    RETURN
    


    #259151 quote
    larouedegann
    Participant
    Master

    MERCI

Viewing 3 posts - 1 through 3 (of 3 total)
  • You must be logged in to reply to this topic.

Indicateur : Volume profile fixe PRC pour ProRealTime


ProBuilder : Indicateurs & Outils Personnalisés

New Reply
Author
Summary

This topic contains 2 replies,
has 2 voices, and was last updated by larouedegann
4 hours, 7 minutes ago.

Topic Details
Forum: ProBuilder : Indicateurs & Outils Personnalisés
Language: French
Started: 03/18/2026
Status: Active
Attachments: No files
Logo Logo
Loading...