PDA

View Full Version : Error When chart periodicity is changed



Edakad
11-10-2014, 05:39 AM
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



'''############################################### ######################################
'''#### 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(b ars(0)-1))
ObjectSeriesSetValue 0, CSTR(indKeyDnBuffer),CLNG(bars(0)),CDBL(DnBuffer(b ars(0)-1))
ObjectSeriesSetValue 0, CSTR(indKeyUpSignal),CLNG(bars(0)),CDBL(UpSignal(b ars(0)-1))
ObjectSeriesSetValue 0, CSTR(indKeyDnSignal),CLNG(bars(0)),CDBL(DnSignal(b ars(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

Edakad
11-10-2014, 05:53 AM
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

Hassan-HS
11-10-2014, 03:39 PM
Dear Edakad,

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

Please standby.

Hassan-HS
11-12-2014, 02:26 PM
Dear Edkad,

I've fixed your 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(UpBuff er(Cint(Bars0)-1))
ObjectSeriesSetValue 0, CSTR(indKeyDnBuffer),CLNG(Cint(Bars0)),CDBL(DnBuff er(Cint(Bars0)-1))
ObjectSeriesSetValue 0, CSTR(indKeyUpSignal),CLNG(Cint(Bars0)),CDBL(UpSign al(Cint(Bars0)-1))
ObjectSeriesSetValue 0, CSTR(indKeyDnSignal),CLNG(Cint(Bars0)),CDBL(DnSign al(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

Hassan-HS
11-13-2014, 08:10 AM
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.

Edakad
11-21-2014, 11:20 AM
Thank you very much Hassan for the explanation

Hassan-HS
12-10-2014, 12:23 PM
You are welcome :D