Results 1 to 7 of 7
  1. #1
    Senior Member
    Join Date
    May 2014
    Posts
    145

    Default Error When chart periodicity is changed

    Hello

    I am facing trouble when changing chart periodicity with my custom indicator, which is attached

    When periodicity is changed many a times it works accurately without any error in journal tab of terminal. However this was not so initially. When chart periodicity is changed it showed up errors in journal log. So I checked what is going wrong when periodicity is changed and deducted that many a times when periodicity is changed, there is still functions like onTick executing and changing periodicity triggers the script again from scratch before onTick ends execution and variables lose their values and errors are thrown. So I created global variables onTickEnded, mainEnded and onCalculateEnded to check if they are ended before executing Main, onTick and onCalculate. This solved the issue to a gr8 extent, however sometimes (rarely) the error still happens.

    What i see with printData log is that when periodicity is changed, first "OnCalculate" fires, (here it fires even if onTick or onCalculate from prior event is still executing, this is causing the error ?). Then the script starts up again initializing the parameters a couple of times. These are my deductions, may not be correct.

    Even if there is errors when periodicity is changed, finally when data is loaded fully in chart, the indicators works properly, if it was removed from chart due to error, then again it gets attached and working. This leads me to the conclusion that there is something fishy in the internal process that handles change chart periodicity.

    Can you check the code and suggest some remedy ? This happens in many vtl scripts, not alone in this one. Further more, the script uses a mode parameter and it identifies calls from onTick and onCalculate with this mode parameter, and when onTick triggers calculation, calculations are done on last bar only.

    Thanks and Regards


    Code:
    '''#####################################################################################
    '''####     Script Name: Volatility Channe Stop                                   ######
    '''####     Author     : Joy Sebastian                                            ######
    '''####     e-mail     : joy.edakad@gmail.com                                     ######
    '''####     Date       : 14/10/2014 19:11:03                                      ######
    '''####     Description: Volatiliy Channel Stop indicator is a volatility based   ######
    '''####           stop and reverse indicator. The blue circle indicates trend     ######
    '''####              reversal from down trend to up trend (Buy) and red circle marks ######
    '''####          trend reversal from uptrend to down trend (Sell)                 ######
    '''#####################################################################################
    
    
    '''################## Parameters @ Line No. 57-66 ######################################
    
    ''' User Input Variable Declarations
    
    dim MA_Price                 ''' Applied Price
    dim MA_Length                ''' MA's Period
    dim MA_Mode                  ''' MA Method
    dim ATR_Length               ''' ATR Period
    dim Kv                       ''' Volatality Factor or Multiplier
    dim MoneyRisk                ''' Offset Factor
    dim usePrice_HiLoBreak       
    dim useMA_HiLoEnvelope
    dim AlertMode                ''' 0-alert off,1-on
    dim VisualMode               ''' 0-lines,1-dots
    
    ''' Indicator Buffers
    
    dim UpBuffer(), DnBuffer(), UpSignal(), DnSignal(), smin(), smax(), trend()
                                ''' Variables for Alert finction
    Dim AlertobjID
    Dim fontSize
    Dim objColor
    dim alertText
    
    ''' Global Variables
    
    dim UpTrendAlert, DownTrendAlert
    dim aryPrice                 ''' Price array depending on parameter MA_Price, Applied Price
    dim aryATR                   ''' ATR array
    dim HighAry(), LowAry(), CloseAry(), OpenAry()  ''' Price Arrays used in ATR sub
    dim counted_bars
    
    dim arybprice(), arysprice(), aryHigh(), aryLow()
    
    dim indKeyUpBuffer, indKeyDnBuffer, indKeyUpSignal, indKeyDnSignal
    
    dim mainEnded, onTickEnded, onCalculateEnded
    
    
    
    Public Sub OnInit()
    
    
    '''################  User Input Parameters #######################################################################
                                                                                                    
    MA_Price              = 0      ''' Applied Price. 0-Close,1-OPen,2-High,3-Low,4-Median,5-Typical,6-Weighted
    MA_Length             = 1      ''' MA Period
    MA_Mode               = 0      ''' MA Method. 0-SMA,1-EMA,2-Weighted Moving Average
    ATR_Length            = 10     ''' ATR Period
    Kv                    = 4      ''' Volatility Factor or Multiple
    MoneyRisk             = 1      ''' Offset Factor
    usePrice_HiLoBreak    = true
    usePrice_HiLoEnvelope = false
    AlertMode             = 0      ''' 0 - Alert off, 1- Alert on
    VisualMode            = 0      ''' Chart Plot. 0 - Lines, 1 - Dots
    
    '''################################################################################################################    
    
    
    if MA_Length < 1 then
        MA_Length = 1
    end if 
    
    if Bars(0) > 0 then
        counted_bars       = 0
    else
        counted_bars      = -1
    end if
    
    mainEnded = true
    onTickEnded = true
    onCalculateEnded = true
    
    End Sub
    
    PRIVATE SUB Alert(alertText)
    
    call deleteAlert()
    
    PlayBeep()
    fontSize=8
    CreateObjectLabel 0,0,CSTR(AlertobjID),20,30, alertText
    objColor=RGBColor(229,172,77)
    ObjectSetText 0,CSTR(AlertobjID),CINT(fontSize),,CLNG(objColor)
    IntervalTimer 3000
    EnableTimer True
    
    tf = chartPeriod(0)
    
    END SUB
    
    
    
    PRIVATE SUB deleteAlert()
    
    alertExits = objectFind(0,CSTR(AlertobjID))
    
    if alertExits then
        ObjectDelete 0,CSTR(AlertobjID)
        EnableTimer false
    end if
    
    END SUB
    
    
    
    private sub MyPriceArray(mode)          ''' This sub populates the global variable aryPrice with selected price field.
                                            ''' Mode parameter is used to identify the calling routine. 0-from OnTick, 1- from OnCalculate
                                            ''' When called from Ontick, only the last bar data is to be updated 
        
        lastBar = Bars(0)
    
        select case CINT(MA_Price)      
    
            case 0
                if mode = 0 then
                    aryPrice(lastBar) = GetClose(0,CINT(lastBar))            
                else
                    CopyClose 0,1,Bars(0),aryPrice
                end if
            case 1
                if mode = 0 then
                    aryPrice(lastBar) = GetOpen(0,CINT(lastBar))
                else
                    CopyOpen 0,1,Bars(0),aryPrice
                end if
            case 2
                if mode = 0 then
                    aryPrice(lastBar) = GetHigh(0,CINT(lastBar))
                else
                    CopyHigh 0,1,Bars(0),aryPrice
                end if
            case 3
                if mode = 0 then
                    aryPrice(lastBar) = GetLow(0,CINT(lastBar))
                else
                    CopyLow 0,1,Bars(0),aryPrice
                end if
            case 4
                if mode = 0 then
                    aryPrice(lastBar) = (GetHigh(0,CINT(lastBar))+GetLow(0,CINT(lastBar)))/2
                else
                    x1 = CopyHigh(0,1,Bars(0),aryHigh)
                    x2 = CopyLow(0,1,Bars(0),aryLow)
                    CopyClose 0,1,Bars(0),aryPrice
                    for i = 1 to bars(0)
                        aryPrice(i) = (aryHigh(i) + aryLow(i))/2
                    next
                end if
            case 5
                if mode = 0 then
                    aryPrice(lastBar) = (GetHigh(0,CINT(lastBar))+GetLow(0,CINT(lastBar))+GetClose(0,CINT(lastBar)))/3
                else
                    x1 = CopyHigh(0,1,Bars(0),aryHigh)
                    x2 = CopyLow(0,1,Bars(0),aryLow)
                    x3 = CopyClose(0,1,Bars(0),aryClose)
                    CopyClose 0,1,Bars(0),aryPrice
                    for i = 1 to bars(0)
                        aryPrice(i) = (aryHigh(i) + aryLow(i) + aryClose(i))/3
                    next
                end if
            case 6
                if mode = 0 then
                    aryPrice(lastBar) = (GetOpen(0,CINT(lastBar))+GetHigh(0,CINT(lastBar))+GetLow(0,CINT(lastBar))+GetClose(0,CINT(lastBar)))/4
                else
                    x1 = CopyHigh(0,1,Bars(0),aryHigh)
                    x2 = CopyLow(0,1,Bars(0),aryLow)
                    x3 = CopyClose(0,1,Bars(0),aryClose)
                    x4 = CopyOpen(0,1,Bars(0),aryOpen)
                    CopyClose 0,1,Bars(0),aryPrice
                    
                    for i = 1 to bars(0)
                        aryPrice(i) = (aryHigh(i) + aryLow(i) + aryClose(i) + aryOpen(i))/4
                    next
                end if
        end select
    
    end sub
    
    
    private sub MyATR(mode,Period)   ''' VTL AverageTrueRange function returns only the True Range
                                     ''' ATR is calculates as MA of true range
                                     ''' Mode parameter is used to identify the calling routine. 0-from OnTick, 1- from OnCalculate
                                     ''' When called from Ontick, only the last bar data is to be updated
    
    dim aryTR 
    
    if mode = 0 then 
        HighAry(Bars(0)) = GetHigh(0, Bars(0))
        LowAry(Bars(0)) = GetLow(0,Bars(0))
        CloseAry(Bars(0)) = GetClose(0,Bars(0))
        OpenAry(Bars(0)) = GetOpen(0,Bars(0))
    else
        x1 = CopyHigh(0,1,Bars(0),HighAry )
        x2 = CopyLow(0,1,Bars(0),LowAry  )
        x3 = CopyClose(0,1,Bars(0),CloseAry )
        x4 = CopyOpen(0,1,Bars(0),OpenAry )
    end if
    
    AverageTrueRangeOnArray OpenAry,HighAry,LowAry,CloseAry,aryTR  
    SimpleMovingAverageOnArray aryTR, CINT(Period), aryATR
     
    end sub
    
    
    private Sub myVCS(mode)          ''' Mode parameter is used to identify the calling routine. 0-from OnTick, 1- from OnCalculate
                                      ''' When called from Ontick, only the last bar data is to be updated
    
    
    MyPriceArray(mode)
    
    ''' First generate the high low envelops arrays. Later in loop, elements from these arrays are used.
    
        if useMA_HiLoEnvelope then
            
            if mode = 0 then
                aryHigh(bars(0)) = GetHigh(0, Bars(0))
                aryLow(bars(0)) = GetLow(0, Bars(0))
            else         
                CopyHigh 0,1,Bars(0),aryHigh
                CopyLow 0,1,Bars(0),aryLow
            end if
    
            select case CINT(MA_Mode) 
                case 0
                    SimpleMovingAverageOnArray aryHigh, CINT(MA_Length), arybprice
                    SimpleMovingAverageOnArray aryLow, CINT(MA_Length), arysprice
                case 1
                    ExponentialMovingAverageOnArray aryHigh, CINT(MA_Length), arybprice
                    ExponentialMovingAverageOnArray aryLow, CINT(MA_Length), arysprice
                case 2
                    IWMAOnArray aryHigh, CINT(MA_Length), arybprice
                    IWMAOnArray aryLow, CINT(MA_Length), arysprice
            end select    
    
        else
    
            select case CINT(MA_Mode) 
                case 0
                    SimpleMovingAverageOnArray aryPrice, CINT(MA_Length), arybprice
                    SimpleMovingAverageOnArray aryPrice, CINT(MA_Length), arysprice
                case 1
                    ExponentialMovingAverageOnArray aryPrice, CINT(MA_Length), arybprice
                    ExponentialMovingAverageOnArray aryPrice, CINT(MA_Length), arysprice
                case 2
                    IWMAOnArray aryPrice, CINT(MA_Length), arybprice
                    IWMAOnArray aryPrice, CINT(MA_Length), arysprice
            end select    
        end if
    
                        
    
    
    dim shift, limit
    
    if mode = 1 then
        redim smax(bars(0)-1),smin(bars(0)-1), trend(Bars(0)-1), UpBuffer(bars(0)-1), DnBuffer(bars(0)-1)
        redim UpSignal(bars(0)-1), DnSignal(bars(0)-1)
                           ''' These arrays are of 0 base index, unlike arybprice etc.
    end if
    
    if mode = 0 then
        limit = bars(0)-1    ''' Limit is start bar for iteration in loop. 
    else 
        limit = MA_Length + 1
    end if
    
    if Bars(0) < MA_Length then
        exit sub
    end if
    
    MyATR mode,CINT(ATR_Length) 
    
    
    
    for shift = limit to bars(0)
        
        bprice = arybprice(shift)   
        sprice = arysprice(shift)
        
        smax(shift-1) = bprice + Kv * aryATR(shift)    ''' smax is 0 base index but arybprice etc are 1 base indexed
        smin(shift-1) = sprice - Kv * aryATR(shift)
        trend(shift-1) = trend(shift-2)                ''' trend array is zero base indexed
        
        if usePrice_HiLoBreak then
    
            if GetHigh(0, CINT(shift)) > smax(shift-2) then
                trend(shift-1) = 1
            end if
            if GetLow(0,CINT(shift)) < smin(shift-2) then
                trend(shift-1) = -1
            end if
        else
            if bprice > smax(shift-2) then
                trend(shift-1) = 1
            end if
            if sprice < smin(shift-2) then
                trend(shift-1) = -1
            end if
        end if
    
        if trend(shift-1) > 0 then
            if smin(shift-1) < smin(shift-2) then
                smin(shift-1) = smin(shift-2)
                
            end if
            UpBuffer(shift-1) = smin(shift-1) - (MoneyRisk - 1)*aryATR(shift)
    
            if UpBuffer(shift-1) < UpBuffer(shift-2) and  IsEmptyExpression(UpBuffer(shift-2)) = false then
                upBuffer(shift-1) = Upbuffer(shift-2)
            end if
            if trend(shift-2) <> trend(shift-1) then
                UpSignal(Shift-1) = upBuffer(shift-1)
            else
                UpSignal(shift-1) = 0
            end if
            DnBuffer(shift-1) = -987654321
            DnSignal(shift-1) = 0
        else
            if trend(shift-1) < 0 then
                if smax(shift-1) > smax(shift-2) then
                    smax(shift-1) = smax(shift-2)
                end if
                DnBuffer(shift-1) = smax(shift-1) + (MoneyRisk-1)*aryATR(shift)
                
                if DnBuffer(shift-1) > DnBuffer(shift-2) and DnBuffer(shift-2) <> -987654321  then
                    DnBuffer(shift-1) = DnBuffer(shift-2)
                end if
                 
                if trend(shift-2) <> trend(shift-1) then
                    DnSignal(shift-1) = DnBuffer(Shift-1)
                else
                    DnSignal(shift-1) = 0
                end if
                UpBuffer(shift-1) = -987654321
                UpSignal(shift-1) = 0
            end if
    
        end if
    
    next
    
    dim Message
    message = ""
    if trend(bars(0)-3) < 0 and trend(bars(0)-2) > 0 and UpTrendAlert = false then
        Message = " " +curTime() + " " + ChartSymbol(0) + " VCS Alert : Buy Signal"
        if AlertMode > 0 then
            deleteAlert
            Alert Message
            UpTrendAlert   = true
            DownTrendAlert = false
        end if
    end if
    
    if trend(bars(0)-3) > 0 and trend(bars(0)-2) < 0 and DownTrendAlert = false then
        Message = " " + curTime() + " " + ChartSymbol(0) + " VCS Alert : Sell Signal"
        if AlertMode > 0 then
            deleteAlert
            Alert Message
            UpTrendAlert   = false
            DownTrendAlert = true
        end if
    
    end if
    
    
    end sub
    
    Public Sub main()
    
    if mainEnded = true and onTickEnded = true and onCalculateEnded = true then
    
    mainEnded = false
    
    deleteAlert
    myVCS(1)
    
    indKeyUpBuffer = AddCustomIndicator(0, UpBuffer, 0, false)
    LineColor 0, CSTR(indKeyUpBuffer), RGBColor(0, 0, 255)
    
    indKeyDnBuffer = AddCustomIndicator(0, DnBuffer, 0, false)
    LineColor 0, CSTR(indKeyDnBuffer), RGBColor(255, 0, 0)
    
    indKeyUpSignal = AddCustomIndicator(0, UpSignal, 0, false)
    SetDrawingStyle 0,CSTR(indKeyUpSignal) ,DRAW_ARROWS
    SetArrowStyle CLNG(0), CSTR(indKeyUpSignal) ,CINT(108) 
    LineColor 0, CSTR(indKeyUpSignal), RGBColor(0, 0, 255)
    
    indKeyDnSignal = AddCustomIndicator(0, DnSignal, 0, false)
    SetDrawingStyle 0,CSTR(indKeyDnSignal) ,DRAW_ARROWS
    SetArrowStyle CLNG(0), CSTR(indKeyDnSignal) ,CINT(108) 
    LineColor 0, CSTR(indKeyDnSignal), RGBColor(255, 0, 0)
    
    if VisualMode <> 0 then
        SetDrawingStyle 0,CSTR(indKeyUpBuffer) ,DRAW_DOTS
        SetDrawingStyle 0,CSTR(indKeyDnBuffer) ,DRAW_DOTS
    end if
    
    mainEnded = true
    
    end if
    
    End Sub
    
    
    
    Public Sub OnTick(symbolName)
    
    if symbolName = ChartSymbol(0) and mainEnded = true and onTickEnded = true and onCalculateEnded = true then
    
        onTickended = false
        myVCS(0)
    
        ObjectSeriesSetValue 0, CSTR(indKeyUpBuffer),CLNG(bars(0)),CDBL(UpBuffer(bars(0)-1))
        ObjectSeriesSetValue 0, CSTR(indKeyDnBuffer),CLNG(bars(0)),CDBL(DnBuffer(bars(0)-1))
        ObjectSeriesSetValue 0, CSTR(indKeyUpSignal),CLNG(bars(0)),CDBL(UpSignal(bars(0)-1))
        ObjectSeriesSetValue 0, CSTR(indKeyDnSignal),CLNG(bars(0)),CDBL(DnSignal(bars(0)-1))
    
        onTickEnded = true
    
    end if
    
    
    End Sub
    
    
    Public Sub OnDeInit()
    
    ObjectDeleteAll(0)
    
    End Sub
    
    
    
    '
    Public Sub OnCalculate(symbol, symbolPeriod, openVal, highVal, lowVal, closeVal)
    
    
        if symbol = chartSymbol(0) and mainEnded = true and onTickEnded = true and onCalculateEnded = true  then
            
        onCalculateEnded = false
        
            myVCS(1)
        
            SetIndicatorData 0, CSTR(indKeyUpBuffer), CDBL(UpBuffer(bars(0)-1))
            SetIndicatorData 0, CSTR(indKeyDnBuffer), CDBL(DnBuffer(bars(0)-1))
            SetIndicatorData 0, CSTR(indKeyUpSignal), CDBL(UpSignal(bars(0)-1))
            SetIndicatorData 0, CSTR(indKeyDnSignal), CDBL(DnSignal(bars(0)-1))
    
        onCalculateEnded = true
    
        end if
    
    End Sub

  2. #2
    Senior Member
    Join Date
    May 2014
    Posts
    145

    Default

    The error happens rarely with the code attached, when markets are active and changing from higher time frame like hourly to 1 minute may trigger error sometime

  3. #3
    Administrator Hassan-HS's Avatar
    Join Date
    Jun 2013
    Posts
    795

    Default

    Dear Edakad,

    We are studying your issue, we will keep you updated.

    Please standby.

  4. #4
    Administrator Hassan-HS's Avatar
    Join Date
    Jun 2013
    Posts
    795

    Default

    Dear Edkad,

    I've fixed your code...

    Code:
    '''#####################################################################################
    '''####     Script Name: Volatility Channe Stop                                   ######
    '''####     Author     : Joy Sebastian                                            ######
    '''####     e-mail     : joy.edakad@gmail.com                                     ######
    '''####     Date       : 14/10/2014 19:11:03                                      ######
    '''####     Description: Volatiliy Channel Stop indicator is a volatility based   ######
    '''####           stop and reverse indicator. The blue circle indicates trend     ######
    '''####              reversal from down trend to up trend (Buy) and red circle marks ######
    '''####          trend reversal from uptrend to down trend (Sell)                 ######
    '''#####################################################################################
    
    
    
    
    '''################## Parameters @ Line No. 57-66 ######################################
    
    
    ''' User Input Variable Declarations
    
    
    dim MA_Price                 ''' Applied Price
    dim MA_Length                ''' MA's Period
    dim MA_Mode                  ''' MA Method
    dim ATR_Length               ''' ATR Period
    dim Kv                       ''' Volatality Factor or Multiplier
    dim MoneyRisk                ''' Offset Factor
    dim usePrice_HiLoBreak       
    dim useMA_HiLoEnvelope
    dim AlertMode                ''' 0-alert off,1-on
    dim VisualMode               ''' 0-lines,1-dots
    
    
    ''' Indicator Buffers
    
    
    dim UpBuffer(), DnBuffer(), UpSignal(), DnSignal(), smin(), smax(), trend()
                                ''' Variables for Alert finction
    Dim AlertobjID
    Dim fontSize
    Dim objColor
    dim alertText
    
    
    ''' Global Variables
    
    
    dim UpTrendAlert, DownTrendAlert
    dim aryPrice                 ''' Price array depending on parameter MA_Price, Applied Price
    dim aryATR                   ''' ATR array
    dim HighAry(), LowAry(), CloseAry(), OpenAry()  ''' Price Arrays used in ATR sub
    dim counted_bars
    
    
    dim arybprice(), arysprice(), aryHigh(), aryLow()
    
    
    dim indKeyUpBuffer, indKeyDnBuffer, indKeyUpSignal, indKeyDnSignal
    
    
    dim mainEnded, onTickEnded, onCalculateEnded
    Dim Bars0
    
    
    
    
    
    
    Public Sub OnInit()
    
    
    
    
    '''################  User Input Parameters #######################################################################
                                                                                                    
    MA_Price              = 0      ''' Applied Price. 0-Close,1-OPen,2-High,3-Low,4-Median,5-Typical,6-Weighted
    MA_Length             = 1      ''' MA Period
    MA_Mode               = 0      ''' MA Method. 0-SMA,1-EMA,2-Weighted Moving Average
    ATR_Length            = 10     ''' ATR Period
    Kv                    = 4      ''' Volatility Factor or Multiple
    MoneyRisk             = 1      ''' Offset Factor
    usePrice_HiLoBreak    = true
    usePrice_HiLoEnvelope = false
    AlertMode             = 0      ''' 0 - Alert off, 1- Alert on
    VisualMode            = 0      ''' Chart Plot. 0 - Lines, 1 - Dots
    Bars0=Bars(0)
    
    
    '''################################################################################################################    
    
    
    
    
    if MA_Length < 1 then
        MA_Length = 1
    end if 
    
    
    if Cint(Bars0) > 0 then
        counted_bars       = 0
    else
        counted_bars      = -1
    end if
    
    
    mainEnded = true
    onTickEnded = false
    onCalculateEnded = false
    
    
    End Sub
    
    
    PRIVATE SUB Alert(alertText)
    
    
    call deleteAlert()
    
    
    PlayBeep()
    fontSize=8
    CreateObjectLabel 0,0,CSTR(AlertobjID),20,30, alertText
    objColor=RGBColor(229,172,77)
    ObjectSetText 0,CSTR(AlertobjID),CINT(fontSize),,CLNG(objColor)
    IntervalTimer 3000
    EnableTimer True
    
    
    tf = chartPeriod(0)
    
    
    END SUB
    
    
    
    
    
    
    PRIVATE SUB deleteAlert()
    
    
    alertExits = objectFind(0,CSTR(AlertobjID))
    
    
    if alertExits then
        ObjectDelete 0,CSTR(AlertobjID)
        EnableTimer false
    end if
    
    
    END SUB
    
    
    
    
    
    
    private sub MyPriceArray(mode)          ''' This sub populates the global variable aryPrice with selected price field.
                                            ''' Mode parameter is used to identify the calling routine. 0-from OnTick, 1- from OnCalculate
                                            ''' When called from Ontick, only the last bar data is to be updated 
        
        lastBar = Cint(Bars0)
    
    
        select case CINT(MA_Price)      
    
    
            case 0
                if mode = 0 then
                    aryPrice(lastBar) = GetClose(0,CINT(lastBar))            
                else
                    CopyClose 0,1,Cint(Bars0),aryPrice
                end if
            case 1
                if mode = 0 then
                    aryPrice(lastBar) = GetOpen(0,CINT(lastBar))
                else
                    CopyOpen 0,1,Cint(Bars0),aryPrice
                end if
            case 2
                if mode = 0 then
                    aryPrice(lastBar) = GetHigh(0,CINT(lastBar))
                else
                    CopyHigh 0,1,Cint(Bars0),aryPrice
                end if
            case 3
                if mode = 0 then
                    aryPrice(lastBar) = GetLow(0,CINT(lastBar))
                else
                    CopyLow 0,1,Cint(Bars0),aryPrice
                end if
            case 4
                if mode = 0 then
                    aryPrice(lastBar) = (GetHigh(0,CINT(lastBar))+GetLow(0,CINT(lastBar)))/2
                else
                    x1 = CopyHigh(0,1,Cint(Bars0),aryHigh)
                    x2 = CopyLow(0,1,Cint(Bars0),aryLow)
                    CopyClose 0,1,Cint(Bars0),aryPrice
                    for i = 1 to Cint(Bars0)
                        aryPrice(i) = (aryHigh(i) + aryLow(i))/2
                    next
                end if
            case 5
                if mode = 0 then
                    aryPrice(lastBar) = (GetHigh(0,CINT(lastBar))+GetLow(0,CINT(lastBar))+GetClose(0,CINT(lastBar)))/3
                else
                    x1 = CopyHigh(0,1,Cint(Bars0),aryHigh)
                    x2 = CopyLow(0,1,Cint(Bars0),aryLow)
                    x3 = CopyClose(0,1,Cint(Bars0),aryClose)
                    CopyClose 0,1,Cint(Bars0),aryPrice
                    for i = 1 to Cint(Bars0)
                        aryPrice(i) = (aryHigh(i) + aryLow(i) + aryClose(i))/3
                    next
                end if
            case 6
                if mode = 0 then
                    aryPrice(lastBar) = (GetOpen(0,CINT(lastBar))+GetHigh(0,CINT(lastBar))+GetLow(0,CINT(lastBar))+GetClose(0,CINT(lastBar)))/4
                else
                    x1 = CopyHigh(0,1,Cint(Bars0),aryHigh)
                    x2 = CopyLow(0,1,Cint(Bars0),aryLow)
                    x3 = CopyClose(0,1,Cint(Bars0),aryClose)
                    x4 = CopyOpen(0,1,Cint(Bars0),aryOpen)
                    CopyClose 0,1,Cint(Bars0),aryPrice
                    
                    for i = 1 to Cint(Bars0)
                        aryPrice(i) = (aryHigh(i) + aryLow(i) + aryClose(i) + aryOpen(i))/4
                    next
                end if
        end select
    
    
    end sub
    
    
    
    
    private sub MyATR(mode,Period)   ''' VTL AverageTrueRange function returns only the True Range
                                     ''' ATR is calculates as MA of true range
                                     ''' Mode parameter is used to identify the calling routine. 0-from OnTick, 1- from OnCalculate
                                     ''' When called from Ontick, only the last bar data is to be updated
    
    
    dim aryTR 
    
    
    if mode = 0 then 
        HighAry(Cint(Bars0)) = GetHigh(0, Cint(Bars0))
        LowAry(Cint(Bars0)) = GetLow(0,Cint(Bars0))
        CloseAry(Cint(Bars0)) = GetClose(0,Cint(Bars0))
        OpenAry(Cint(Bars0)) = GetOpen(0,Cint(Bars0))
    else
        x1 = CopyHigh(0,1,Cint(Bars0),HighAry )
        x2 = CopyLow(0,1,Cint(Bars0),LowAry  )
        x3 = CopyClose(0,1,Cint(Bars0),CloseAry )
        x4 = CopyOpen(0,1,Cint(Bars0),OpenAry )
    end if
    
    
    AverageTrueRangeOnArray OpenAry,HighAry,LowAry,CloseAry,aryTR  
    SimpleMovingAverageOnArray aryTR, CINT(Period), aryATR
     
    end sub
    
    
    
    
    private Sub myVCS(mode)          ''' Mode parameter is used to identify the calling routine. 0-from OnTick, 1- from OnCalculate
                                      ''' When called from Ontick, only the last bar data is to be updated
    
    
    
    
    MyPriceArray(mode)
    
    
    ''' First generate the high low envelops arrays. Later in loop, elements from these arrays are used.
    
    
        if useMA_HiLoEnvelope then
            
            if mode = 0 then
                aryHigh(Cint(Bars0)) = GetHigh(0, Cint(Bars0))
                aryLow(Cint(Bars0)) = GetLow(0, Cint(Bars0))
            else         
                CopyHigh 0,1,Cint(Bars0),aryHigh
                CopyLow 0,1,Cint(Bars0),aryLow
            end if
    
    
            select case CINT(MA_Mode) 
                case 0
                    SimpleMovingAverageOnArray aryHigh, CINT(MA_Length), arybprice
                    SimpleMovingAverageOnArray aryLow, CINT(MA_Length), arysprice
                case 1
                    ExponentialMovingAverageOnArray aryHigh, CINT(MA_Length), arybprice
                    ExponentialMovingAverageOnArray aryLow, CINT(MA_Length), arysprice
                case 2
                    IWMAOnArray aryHigh, CINT(MA_Length), arybprice
                    IWMAOnArray aryLow, CINT(MA_Length), arysprice
            end select    
    
    
        else
    
    
            select case CINT(MA_Mode) 
                case 0
                    SimpleMovingAverageOnArray aryPrice, CINT(MA_Length), arybprice
                    SimpleMovingAverageOnArray aryPrice, CINT(MA_Length), arysprice
                case 1
                    ExponentialMovingAverageOnArray aryPrice, CINT(MA_Length), arybprice
                    ExponentialMovingAverageOnArray aryPrice, CINT(MA_Length), arysprice
                case 2
                    IWMAOnArray aryPrice, CINT(MA_Length), arybprice
                    IWMAOnArray aryPrice, CINT(MA_Length), arysprice
            end select    
        end if
    
    
                        
    
    
    
    
    dim shift, limit
    
    
    if mode = 1 then
        redim smax(Cint(Bars0)-1),smin(Cint(Bars0)-1), trend(Cint(Bars0)-1), UpBuffer(Cint(Bars0)-1), DnBuffer(Cint(Bars0)-1)
        redim UpSignal(Cint(Bars0)-1), DnSignal(Cint(Bars0)-1)
                           ''' These arrays are of 0 base index, unlike arybprice etc.
    end if
    
    
    if mode = 0 then
        limit = Cint(Bars0)-1    ''' Limit is start bar for iteration in loop. 
    else 
        limit = MA_Length + 1
    end if
    
    
    if Cint(Bars0) < MA_Length then
        exit sub
    end if
    
    
    MyATR mode,CINT(ATR_Length) 
    
    
    
    
    
    
    for shift = limit to Cint(Bars0)
        
        bprice = arybprice(shift)   
        sprice = arysprice(shift)
        
        smax(shift-1) = bprice + Kv * aryATR(shift)    ''' smax is 0 base index but arybprice etc are 1 base indexed
        smin(shift-1) = sprice - Kv * aryATR(shift)
        trend(shift-1) = trend(shift-2)                ''' trend array is zero base indexed
        
        if usePrice_HiLoBreak then
    
    
            if GetHigh(0, CINT(shift)) > smax(shift-2) then
                trend(shift-1) = 1
            end if
            if GetLow(0,CINT(shift)) < smin(shift-2) then
                trend(shift-1) = -1
            end if
        else
            if bprice > smax(shift-2) then
                trend(shift-1) = 1
            end if
            if sprice < smin(shift-2) then
                trend(shift-1) = -1
            end if
        end if
    
    
        if trend(shift-1) > 0 then
            if smin(shift-1) < smin(shift-2) then
                smin(shift-1) = smin(shift-2)
                
            end if
            UpBuffer(shift-1) = smin(shift-1) - (MoneyRisk - 1)*aryATR(shift)
    
    
            if UpBuffer(shift-1) < UpBuffer(shift-2) and  IsEmptyExpression(UpBuffer(shift-2)) = false then
                upBuffer(shift-1) = Upbuffer(shift-2)
            end if
            if trend(shift-2) <> trend(shift-1) then
                UpSignal(Shift-1) = upBuffer(shift-1)
            else
                UpSignal(shift-1) = 0
            end if
            DnBuffer(shift-1) = -987654321
            DnSignal(shift-1) = 0
        else
            if trend(shift-1) < 0 then
                if smax(shift-1) > smax(shift-2) then
                    smax(shift-1) = smax(shift-2)
                end if
                DnBuffer(shift-1) = smax(shift-1) + (MoneyRisk-1)*aryATR(shift)
                
                if DnBuffer(shift-1) > DnBuffer(shift-2) and DnBuffer(shift-2) <> -987654321  then
                    DnBuffer(shift-1) = DnBuffer(shift-2)
                end if
                 
                if trend(shift-2) <> trend(shift-1) then
                    DnSignal(shift-1) = DnBuffer(Shift-1)
                else
                    DnSignal(shift-1) = 0
                end if
                UpBuffer(shift-1) = -987654321
                UpSignal(shift-1) = 0
            end if
    
    
        end if
    
    
    next
    
    
    dim Message
    message = ""
    if trend(Cint(Bars0)-3) < 0 and trend(Cint(Bars0)-2) > 0 and UpTrendAlert = false then
        Message = " " +curTime() + " " + ChartSymbol(0) + " VCS Alert : Buy Signal"
        if AlertMode > 0 then
            deleteAlert
            Alert Message
            UpTrendAlert   = true
            DownTrendAlert = false
        end if
    end if
    
    
    if trend(Cint(Bars0)-3) > 0 and trend(Cint(Bars0)-2) < 0 and DownTrendAlert = false then
        Message = " " + curTime() + " " + ChartSymbol(0) + " VCS Alert : Sell Signal"
        if AlertMode > 0 then
            deleteAlert
            Alert Message
            UpTrendAlert   = false
            DownTrendAlert = true
        end if
    
    
    end if
    
    
    
    
    end sub
    
    
    Public Sub main()
    
    
    if mainEnded = true  then
    
    
    mainEnded = false
    
    
    deleteAlert
    myVCS(1)
    
    
    indKeyUpBuffer = AddCustomIndicator(0, UpBuffer, 0, false)
    LineColor 0, CSTR(indKeyUpBuffer), RGBColor(0, 0, 255)
    
    
    indKeyDnBuffer = AddCustomIndicator(0, DnBuffer, 0, false)
    LineColor 0, CSTR(indKeyDnBuffer), RGBColor(255, 0, 0)
    
    
    indKeyUpSignal = AddCustomIndicator(0, UpSignal, 0, false)
    SetDrawingStyle 0,CSTR(indKeyUpSignal) ,DRAW_ARROWS
    SetArrowStyle CLNG(0), CSTR(indKeyUpSignal) ,CINT(108) 
    LineColor 0, CSTR(indKeyUpSignal), RGBColor(0, 0, 255)
    
    
    indKeyDnSignal = AddCustomIndicator(0, DnSignal, 0, false)
    SetDrawingStyle 0,CSTR(indKeyDnSignal) ,DRAW_ARROWS
    SetArrowStyle CLNG(0), CSTR(indKeyDnSignal) ,CINT(108) 
    LineColor 0, CSTR(indKeyDnSignal), RGBColor(255, 0, 0)
    
    
    if VisualMode <> 0 then
        SetDrawingStyle 0,CSTR(indKeyUpBuffer) ,DRAW_DOTS
        SetDrawingStyle 0,CSTR(indKeyDnBuffer) ,DRAW_DOTS
    end if
    
    
    mainEnded = true
    onTickEnded = true
    onCalculateEnded = true
    end if
    
    
    End Sub
    
    
    
    
    
    
    Public Sub OnTick(symbolName)
    
    
    if symbolName = ChartSymbol(0) and mainEnded = true and onTickEnded = true and onCalculateEnded = true then
    
    
        onTickended = false
        myVCS(0)
    
    
        ObjectSeriesSetValue 0, CSTR(indKeyUpBuffer),CLNG(Cint(Bars0)),CDBL(UpBuffer(Cint(Bars0)-1))
        ObjectSeriesSetValue 0, CSTR(indKeyDnBuffer),CLNG(Cint(Bars0)),CDBL(DnBuffer(Cint(Bars0)-1))
        ObjectSeriesSetValue 0, CSTR(indKeyUpSignal),CLNG(Cint(Bars0)),CDBL(UpSignal(Cint(Bars0)-1))
        ObjectSeriesSetValue 0, CSTR(indKeyDnSignal),CLNG(Cint(Bars0)),CDBL(DnSignal(Cint(Bars0)-1))
    
    
        onTickEnded = true
    
    
    end if
    
    
    End Sub
    
    
    
    
    Public Sub OnDeInit()
    
    
    ObjectDeleteAll(0)
    
    
    End Sub
    
    
    
    
    
    
    '
    Public Sub OnCalculate(symbol, symbolPeriod, openVal, highVal, lowVal, closeVal)
    
    
    
    
        if symbol = chartSymbol(0) and mainEnded = true and onTickEnded = true and onCalculateEnded = true  then
        Bars0=Bars(0)        
        onCalculateEnded = false
        
            myVCS(1)
        
            SetIndicatorData 0, CSTR(indKeyUpBuffer), CDBL(UpBuffer(Cint(Bars0)-1))
            SetIndicatorData 0, CSTR(indKeyDnBuffer), CDBL(DnBuffer(Cint(Bars0)-1))
            SetIndicatorData 0, CSTR(indKeyUpSignal), CDBL(UpSignal(Cint(Bars0)-1))
            SetIndicatorData 0, CSTR(indKeyDnSignal), CDBL(DnSignal(Cint(Bars0)-1))
    
    
        onCalculateEnded = true
    
    
        end if
    
    
    End Sub

  5. #5
    Administrator Hassan-HS's Avatar
    Join Date
    Jun 2013
    Posts
    795

    Default

    Dear Edakad,
    Some things you need to know:

    When the period is changed the client terminal draws the buffered candles initially on the chart and attach your script to the chart also...(ex: in this moment Bars(0) will be 1000), then the terminal requests the remaining bars from our servers (ex: there is a new 30 bars) to re-draw them.

    when the terminal is updated (ex: bars(0) will be in this moment 1030), it's stop the old script to re- attach the same script to the chart again.
    but the script should finish the current procedure which is Ontick to be stopped.(the exception occurs in this section because the bars(0) equal 1030 not 1000 and the upper bound of your arrays is 1000)


    So you have to hold the bars count on a global variable and update it on onCalculate event.

  6. #6
    Senior Member
    Join Date
    May 2014
    Posts
    145

    Default

    Thank you very much Hassan for the explanation

  7. #7
    Administrator Hassan-HS's Avatar
    Join Date
    Jun 2013
    Posts
    795

    Default

    You are welcome

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Error in Update SL/TP
    By Birju in forum VertexFX API/VTL Forum
    Replies: 1
    Last Post: 02-11-2014, 03:26 PM
  2. Time shown on Chart and Trade not same
    By nhasan in forum VertexFX API/VTL Forum
    Replies: 5
    Last Post: 09-24-2013, 04:39 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •