Pine Script_Calmar Ratio Custom Range

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #246216 quote
    David1998P
    Participant
    New

    This indicator aims to provide a risk-adjusted return statistic for a security over a selected period. Return is measured as CAGR and risk as Max Drawdown. The ratio of these two gives the Calmar Ratio. It works on any timeframe or range.

    Calmar Ratio Custom Range on TradingView (open-source script)

    It would be great if someone could convert it to ProBuilder.

    #246329 quote
    Iván González
    Moderator
    Master

    Here you have:

    //-------------------------------------------------------//
    //PRC_Calmar Ratio
    //version = 0
    //23.04.25
    //Iván González @ www.prorealcode.com
    //Sharing ProRealTime knowledge
    defparam drawonlastbaronly=true
    //-----------------------------------------------//
    // Inputs
    //-----------------------------------------------//
    startDate=20250207
    startTime=100000
    endDate=20250407
    endTime=150000
    //-----------------------------------------------//
    // Calculate x1,y1 and x2,y2
    //-----------------------------------------------//
    tm = gettimeframe
    if tm >= 86400 then
    if opendate=startdate then
    idxStart=barindex
    ValueStart=close
    endif
    if opendate=endDate then
    idxEnd=barindex
    ValueEnd=close
    endif
    else
    if opendate=startdate and opentime=startTime then
    idxStart=barindex
    ValueStart=close
    endif
    if opendate=endDate and opentime=endTime then
    idxEnd=barindex
    ValueEnd=close
    endif
    endif
    if ValueEnd>ValueStart then
    r=0
    g=255
    b=0
    else
    r=255
    g=0
    b=0
    endif
    //-----------------------------------------------//
    // Draw and calculations
    //-----------------------------------------------//
    if startDate>=EndDate then
    drawtext("You need more than 1 day between 2 points",0,-100)anchor(top,xshift,yshift)
    elsif ValueStart=0 or ValueEnd=0 then
    drawtext("Check the start date you entered. It might be that you don’t have enough bars loaded.Or maybe you entered a day/time when the market was closed",0,-100)anchor(top,xshift,yshift)
    else
    if islastbarupdate then
    n1=barindex-idxStart
    n2=barindex-idxEnd
    //-----------------------------------------------//
    drawpoint(idxStart,ValueStart,5)coloured(r,g,b,30)
    drawpoint(idxEnd,ValueEnd,5)coloured(r,g,b,30)
    drawpoint(idxStart,ValueStart,2)coloured(r,g,b)
    drawpoint(idxEnd,ValueEnd,2)coloured(r,g,b)
    drawsegment(idxStart,ValueStart,idxEnd,ValueEnd)coloured(r,g,b)
    //-----------------------------------------------//
    drawvline(barindex[n1])style(dottedline)
    drawvline(barindex[n2])style(dottedline)
    //-----------------------------------------------//
    daysBetween=endDate-startDate
    iYears=daysBetween/365
    cagr = round((pow(ValueEnd/ValueStart,(1/iyears))-1)*100,2)
    //-----------------------------------------------//
    peak=ValueStart
    maxDD=0
    for i=n1 downto n2 do
    if close[i]>peak then
    peak=close[i]
    endif
    dd=(peak-close[i])/peak*100
    if dd>maxDD then
    maxDD=dd
    endif
    next
    //-----------------------------------------------//
    MaxDrawDown=round(-maxDD,2)
    Calmar=round(cagr/maxDD,2)
    drawtext("CAGR=#cagr#%",-100,-100)anchor(topright,xshift,yshift)
    drawtext("MaxDD=#MaxDrawDown#%",-100,-120)anchor(topright,xshift,yshift)
    drawtext("Calmar=#Calmar#",-100,-140)anchor(topright,xshift,yshift)
    endif
    endif
    return
    
    #246347 quote
    Iván González
    Moderator
    Master

    Now it’s better than the previous one.

    //-------------------------------------------------------//
    //PRC_Calmar Ratio
    //version = 0
    //23.04.25
    //Iván González @ www.prorealcode.com
    //Sharing ProRealTime knowledge
    //-------------------------------------------------------//
    defparam drawonlastbaronly=true
    //-----------------------------------------------//
    // Inputs
    //-----------------------------------------------//
    startDate=20250207
    startTime=100000
    endDate=20250407
    endTime=150000
    //-----------------------------------------------//
    // Calculate x1,y1 and x2,y2
    //-----------------------------------------------//
    tm = gettimeframe
    if tm >= 86400 then
    if opendate=startdate then
    idxStart=barindex
    ValueStart=close
    endif
    if opendate=endDate then
    idxEnd=barindex
    ValueEnd=close
    endif
    else
    if opendate=startdate and opentime=startTime then
    idxStart=barindex
    ValueStart=close
    endif
    if opendate=endDate and opentime=endTime then
    idxEnd=barindex
    ValueEnd=close
    endif
    endif
    if ValueEnd>ValueStart then
    r=0
    g=255
    b=0
    else
    r=255
    g=0
    b=0
    endif
    //-----------------------------------------------//
    // Draw and calculations
    //-----------------------------------------------//
    if startDate>=EndDate then
    drawtext("You need more than 1 day between 2 points",0,-100)anchor(top,xshift,yshift)
    elsif ValueStart=0 or ValueEnd=0 then
    drawtext("Check the start date you entered. It might be that you don’t have enough bars loaded.Or maybe you entered a day/time when the market was closed",0,-100)anchor(top,xshift,yshift)
    else
    if islastbarupdate then
    n1=barindex-idxStart
    n2=barindex-idxEnd
    //-----------------------------------------------//
    drawpoint(idxStart,ValueStart,5)coloured(r,g,b,30)
    drawpoint(idxEnd,ValueEnd,5)coloured(r,g,b,30)
    drawpoint(idxStart,ValueStart,2)coloured(r,g,b)
    drawpoint(idxEnd,ValueEnd,2)coloured(r,g,b)
    drawsegment(idxStart,ValueStart,idxEnd,ValueEnd)coloured(r,g,b)
    //-----------------------------------------------//
    drawvline(barindex[n1])style(dottedline)
    drawvline(barindex[n2])style(dottedline)
    //-----------------------------------------------//
    peak=ValueStart
    maxDD=0
    bars=0
    for i=n1 downto n2 do
    if tm>=86400 then
    bars=bars+1
    else
    if openday[i]<>openday[i+1] then//intradaybarindex[i]=0 then
    bars=bars+1
    else
    bars=bars
    endif
    endif
    if close[i]>peak then
    peak=close[i]
    endif
    dd=(peak-close[i])/peak*100
    if dd>maxDD then
    maxDD=dd
    endif
    next
    //-----------------------------------------------//
    //---Check timeframe for CAGR calculation--------//
    if tm = 2592000 then //monthly timeframe
    n = 12
    elsif tm = 604800 then //weekly timeframe
    n = 52
    elsif tm <=86400 then //Other timeframes (daily or less)
    n = 252
    endif
    iYears=bars/n
    cagr = round((pow(ValueEnd/ValueStart,(1/iyears))-1)*100,2)
    //-----------------------------------------------//
    MaxDrawDown=round(-maxDD,2)
    Calmar=round(cagr/maxDD,2)
    drawtext("CAGR=#cagr#%",-100,-100)anchor(topright,xshift,yshift)
    drawtext("MaxDD=#MaxDrawDown#%",-100,-120)anchor(topright,xshift,yshift)
    drawtext("Calmar=#Calmar#",-100,-140)anchor(topright,xshift,yshift)
    endif
    endif
    return
    
    #246468 quote
    David1998P
    Participant
    New

    Thank you Iván for the conversion — I have a few suggestions:

    • The indicator currently has 4 manual inputs, while the TradingView version uses just 2 and allows easy selection of  dates by directly clicking on the candles.

    • It only works on the daily timeframe; on others, it shows ‘n/d’ or this message: “Check the start date you entered. It might be that you don’t have enough bars loaded. Or maybe you entered a day/time when the market was closed.”

    In the Pine Script version, date selection is straightforward on any timeframe. It also offers the ability to divide the CAGR by the Max DD since inception.

    I recommend checking how it works on TradingView to see it in action.

    #246477 quote
    Iván González
    Moderator
    Master
    If you want to perform the calculation from the beginning, then you need to add the boolean variable showbeg and change it depending on whether we want to select 2 dates or take all historical data. Regarding selecting dates from the chart by clicking on the candlestick, this is not possible in ProRealTime.
    //-------------------------------------------------------//
    //PRC_Calmar Ratio
    //version = 0
    //23.04.25
    //Iván González @ www.prorealcode.com
    //Sharing ProRealTime knowledge
    //-------------------------------------------------------//
    defparam drawonlastbaronly=true
    //-----------------------------------------------//
    // Inputs
    //-----------------------------------------------//
    startDate=20250207
    startTime=100000
    endDate=20250407
    endTime=150000
    showbeg=1
    //-----------------------------------------------//
    // Calculate x1,y1 and x2,y2
    //-----------------------------------------------//
    tm = gettimeframe
    if showbeg then
    idxStart=0
    ValueStart=close[barindex]
    idxEnd=barindex
    ValueEnd=close
    else
    if tm >= 86400 then
    if opendate=startdate then
    idxStart=barindex
    ValueStart=close
    endif
    if opendate=endDate then
    idxEnd=barindex
    ValueEnd=close
    endif
    else
    if opendate=startdate and opentime=startTime then
    idxStart=barindex
    ValueStart=close
    endif
    if opendate=endDate and opentime=endTime then
    idxEnd=barindex
    ValueEnd=close
    endif
    endif
    endif
    if ValueEnd>ValueStart then
    r=0
    g=255
    b=0
    else
    r=255
    g=0
    b=0
    endif
    //-----------------------------------------------//
    // Draw and calculations
    //-----------------------------------------------//
    if startDate>=EndDate then
    drawtext("You need more than 1 day between 2 points",0,-100)anchor(top,xshift,yshift)
    elsif ValueStart=0 or ValueEnd=0 then
    drawtext("Check the start date you entered. It might be that you don’t have enough bars loaded.Or maybe you entered a day/time when the market was closed",0,-100)anchor(top,xshift,yshift)
    else
    if islastbarupdate then
    n1=barindex-idxStart
    n2=barindex-idxEnd
    //-----------------------------------------------//
    drawpoint(idxStart,ValueStart,5)coloured(r,g,b,30)
    drawpoint(idxEnd,ValueEnd,5)coloured(r,g,b,30)
    drawpoint(idxStart,ValueStart,2)coloured(r,g,b)
    drawpoint(idxEnd,ValueEnd,2)coloured(r,g,b)
    drawsegment(idxStart,ValueStart,idxEnd,ValueEnd)coloured(r,g,b)
    //-----------------------------------------------//
    drawvline(barindex[n1])style(dottedline)
    drawvline(barindex[n2])style(dottedline)
    //-----------------------------------------------//
    peak=ValueStart
    maxDD=0
    bars=0
    for i=n1 downto n2 do
    if tm>=86400 then
    bars=bars+1
    else
    if openday[i]<>openday[i+1] then//intradaybarindex[i]=0 then
    bars=bars+1
    else
    bars=bars
    endif
    endif
    if close[i]>peak then
    peak=close[i]
    endif
    dd=(peak-close[i])/peak*100
    if dd>maxDD then
    maxDD=dd
    endif
    next
    //-----------------------------------------------//
    //---Check timeframe for CAGR calculation--------//
    if tm = 2592000 then //monthly timeframe
    n = 12
    elsif tm = 604800 then //weekly timeframe
    n = 52
    elsif tm <=86400 then //Other timeframes (daily or less)
    n = 252
    endif
    iYears=bars/n
    cagr = round((pow(ValueEnd/ValueStart,(1/iyears))-1)*100,2)
    //-----------------------------------------------//
    MaxDrawDown=round(-maxDD,2)
    Calmar=round(cagr/maxDD,2)
    drawtext("CAGR=#cagr#%",-100,-100)anchor(topright,xshift,yshift)
    drawtext("MaxDD=#MaxDrawDown#%",-100,-120)anchor(topright,xshift,yshift)
    drawtext("Calmar=#Calmar#",-100,-140)anchor(topright,xshift,yshift)
    endif
    endif
    return
    
    #246495 quote
    David1998P
    Participant
    New

    I understand that choosing start and end dates by candle is not feasible in ProRealTime. I also believe there might be a quicker way than using 4 inputs — maybe just 2 would be enough (with hours either predefined or detected based on the timeframe?).

    The next step would be to screen for it (calculating a rolling Calmar Ratio with a custom lookback period in ProScreener).

    This could help identify the best-performing stocks over the last 1M, 3M, or 6M periods (for example) on a risk-adjusted basis — similar to a momentum strategy, but adjusting raw returns by risk (where risk is = Max DD here).

    Let me know what you think about it.

    Note: Yesterday, when I was changing inputs on the daily timeframe, it was working fine. Now, it no longer works (even when trying with the previous code). I change the date, but nothing happens. I’m new to this platform, and I don’t really understand how it could work yesterday but not today…

    #246507 quote
    Iván González
    Moderator
    Master
    Of course, you can set a predefined time and only modify the dates. You can adapt it however you want. Regarding the screener, when you start working on it, keep in mind that depending on whether you have the complete version or the premium version, you will be able to reference back 255 bars or 1024 bars, respectively.
Viewing 7 posts - 1 through 7 (of 7 total)
  • You must be logged in to reply to this topic.

Pine Script_Calmar Ratio Custom Range


ProBuilder: Indicators & Custom Tools

New Reply
Author
author-avatar
David1998P @david1998p Participant
Summary

This topic contains 6 replies,
has 2 voices, and was last updated by Iván González
9 months, 1 week ago.

Topic Details
Forum: ProBuilder: Indicators & Custom Tools
Language: English
Started: 04/22/2025
Status: Active
Attachments: 3 files
Logo Logo
Loading...