Running error on Indicator using an array in a function  [SOLVED]

Questions about MultiCharts and user contributed studies.
arjfca
Posts: 1292
Joined: 23 Nov 2010
Has thanked: 725 times
Been thanked: 223 times

Running error on Indicator using an array in a function

Postby arjfca » 15 Mar 2014

Hello

2 questions:

Question 1:
A function is called from an indicator
The function will be use to create a series of trendline
I want to keep the trend line number in an array

Every time I'm running the indicator, MC report an error Array Index bound. Wrong Index value


Question 2:
When defining the array, why can't I give the lenght the value of the input received by the function

Function :
Input: Box (Numericsimple)

Array: Intrabarpersist TLNum[box](0); The Length define by the input value Box give a compilation error

Code: Select all

//DrawSqare on the right space of the chart

Input:
Box (Numeric);

Vars:
Intrabarpersist Box_Size (0),
Intrabarpersist R_Highest (0),
Intrabarpersist R_Lowest (0),
Intrabarpersist R_DateTime (0),
Intrabarpersist R_Space (0),
Intrabarpersist LeftLine (0),
Intrabarpersist RightLine (0),
Intrabarpersist R_Range (0),
Intrabarpersist BC (box),
intrabarpersist Counter (0),
NL (0);
Print (BC);

Array: Intrabarpersist TLNum[box](0);


DrawSquare = False;
once begin
IF BC = 0 then BC = 1;
Leftline = TL_New_Dt(R_DateTime, R_Highest, R_Datetime, R_Lowest);
TL_Setcolor(LeftLine,blue);

Counter =1;
while counter < box begin
Print ("in");
NL = TL_New_bn(barnumber +1 , R_Highest, barnumber +5,r_Highest);
Print (NL:0:0, " C: ", counter);
TLNUm[Counter] = NL;
counter = counter +1;
end;
end;
Martin

User avatar
ABC
Posts: 718
Joined: 16 Dec 2006
Location: www.abctradinggroup.com
Has thanked: 125 times
Been thanked: 408 times
Contact:

Re: Running error on Indicator using an array in a function

Postby ABC » 15 Mar 2014

Question 2:
When defining the array, why can't I give the lenght the value of the input received by the function
Martin,

because you are declaring a static array and the compiler probably prevents you from doing that as your input could be dynamic.
There are two ways around it, either create the array in the indicator and reference it to the function or create a dynamic array within the function and set the length using your box input.

Regarding question 1, the array bounds error will come up when you try to write to an index that would be outside your array.

Regards,
ABC

arjfca
Posts: 1292
Joined: 23 Nov 2010
Has thanked: 725 times
Been thanked: 223 times

Re: Running error on Indicator using an array in a function

Postby arjfca » 15 Mar 2014

create a dynamic array within the function and set the length using your box input.
Hello Sir

I tried that using a variable and it give the same error
A) BC = Box // Box is the input value
B) BC = Box +1 // incase Box = 0
C) BC = 5

Array: Intrabarpersist TLNum[BC](0);

My idea is that when compiling a function, the variable are not defined by the compiler before it tried to compile the Array section of code. Since the variable are not pre defined by the compiler, compiling the array section report an error.

When I give a fix value to the definition Array: Intrabarpersist TLNum[5](0) it compile without problem

Martin

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Re: Running error on Indicator using an array in a function

Postby bowlesj3 » 15 Mar 2014

I think the best thing to do is to pass the array to the function after having defined the array in the indicator. I do not think it would matter if the array is dynamic or fixed. However I have never had the need to use a dynamic array let alone pass one to a function so I could be wrong. With 8 gig+ of memory in MC (64 bit) or even 3 gig of memory in MC (32 bit) I don't worry about this. I just create it as big as it could possibly go and I use an index (sometimes called a subscript) to make sure I know the last element that has been loaded. I also will send the length so I do not go off the end of the array if it seems appropriate.

Here is an example of passing a whole bunch of arrays to a function (the call and the function). It is directly from my code. In this case the arrays are always 2 elements (0 and 1) so there is no need to send the number of elements loaded nor the size of the array. In your case you would need to send both of these to the function. Again, I suspect the function will automatically pick up on whatever size the array is at the point of calling the function. Just try it defined as fixed (inside the indicator) and then once everything is good try switching that array definition to dynamic (variable length) and if you function call fails maybe they can't handle them. Just double check the syntax for defining the array before you come to that conclusion. I am sure someone can answer the simple question "has anyone successfully passed a dynamic array to a function? If so can I see an example?". If functions can not handle dynamic arrays just have your function test against the length of the array you have passed to the function and notify you if you need a longer length then recompile with that bigger length. This value should be stored in only two places (in your array definition in the indicator and in a variable). Only hard code the length if you are 100% sure it will never change. In my case below I was 100% sure it would never change so I hard coded the length in the "for" statement.

Ignore the comments in this code (they are related to my trading system and have nothing to do with the syntax of the computer language)

Code: Select all

value2 = A_MyA1_ProjByArw10Sec_ZeroClones(COLSD,
COLST,
COLSV,
COLSO,
COL_ID,
COLED,
COLET,
COLEV,
CCL_ID,
CCLED,
CCLET,
CCLEV,
COLBS,
CCLEUV,

ACL_ID,
ACLED,
ACLET,
ACLEV,
AOLSO,
ACLEUV,
AOLBS

);

Code: Select all

{A_MyA1_ProjByArw10Sec_ZeroClones =================================================}

inputs:
{These start items are exactly the same for element #2 Original and Clone. Note that the clone angle is based upon element 1 original}
COLSD[M] (NumericArrayRef), {Clone Original/Copy Line Start Date}
COLST[M] (NumericArrayRef), {Clone Original/Copy Line Start Time}
COLSV[M] (NumericArrayRef), {Clone Original/Copy Line Start Value}
COLSO[M] (NumericArrayRef), {Clone Original/Copy Line Start Offset}

{These end items have to be duplicated for each element of the table since the original and clone off element #2 run at different angle}
COL_ID[M] (NumericArrayRef),
COLED[M] (NumericArrayRef), {Clone Copy Line End Date}
COLET[M] (NumericArrayRef), {Clone Copy Line End Time}
COLEV[M] (NumericArrayRef), {Clone Copy Line End Value}
CCL_ID[M] (NumericArrayRef),
CCLED[M] (NumericArrayRef), {Clone Copy Line End Date}
CCLET[M] (NumericArrayRef), {Clone Copy Line End Time}
CCLEV[M] (NumericArrayRef), {Clone Copy Line End Value}


{these are the two rate of change items}
COLBS[M] (NumericArrayRef), {Clone Original Line Bar Size In Terms of Bars of Change - OriginalCloneBarCnt}
{Clone Original Line Bar Size - the number of bars needed once the copy line is fully extended}
{TR: COLBS[X] is used we get at it by calculating by X -1 off start time and start price}
CCLEUV[M] (NumericArrayRef),

{Start of ArrowHead arrays - AOL means ArrowHead Original Line and ACL means ArrowHead Copy Line |AH|}
ACL_ID[M](NumericArrayRef), {TR: keep, you use ACL_ID[X] for copy and ACL_ID[X - 1] for original}
ACLED[M](NumericArrayRef), {ArrowHead Copy Line End Date}
ACLET[M](NumericArrayRef), {ArrowHead Copy Line End Time}
ACLEV[M](NumericArrayRef), {ArrowHead Copy Line End Value}
AOLSO[M] (NumericArrayRef), {ArrowHead Copy Line Start Offset}
ACLEUV[M](NumericArrayRef), {ArrowHead Copy Line Units Value change for every new bar}
AOLBS[M] (NumericArrayRef); {ArrowHead Original Line Bar Size In Terms of Bars of Change - Number of bars if fully extended}
{END of ArrowHead arrays |AH|}



variables:
X(0);

for X = 0 to 1
begin
COLSD[X] = 0;
COLST[X] = 0;
COLSV[X] = 0;
COLSO[X] = 0;

{
COL_ID[X] = 0;
}
COLED[X] = 0;
COLET[X] = 0;
COLEV[X] = 0;
{
CCL_ID[X] = 0;
}
CCLED[X] = 0;
CCLET[X] = 0;
CCLEV[X] = 0;
COLBS[X] = 0;
CCLEUV[X] = 0;

{
ACL_ID[X] = 0; {TR: keep, you use ACL_ID[X] for copy and ACL_ID[X - 1] for original}
}
ACLED[X] = 0; {ArrowHead Copy Line End Date}
ACLET[X] = 0; {ArrowHead Copy Line End Time}
ACLEV[X] = 0; {ArrowHead Copy Line End Value}
AOLSO[X] = 0; {ArrowHead Copy Line Start Offset}
ACLEUV[X] = 0; {ArrowHead Copy Line Units Value change for every new bar}
AOLBS[X] = 0; {ArrowHead Original Line Bar Size In Terms of Bars of Change - Number of bars if fully extended}

end;



A_MyA1_ProjByArw10Sec_ZeroClones = 0;




bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Re: Running error on Indicator using an array in a function

Postby bowlesj3 » 15 Mar 2014

One more thing. The good thing about passing the whole array to the function from the indicator is that once the function is completed and you are back to running code in the indicator you can pick up the new values in the array that the function has changed. It just occurred to me that maybe this was what you intended. If so you have to define the array in the indicator and pass it to the function.

arjfca
Posts: 1292
Joined: 23 Nov 2010
Has thanked: 725 times
Been thanked: 223 times

Re: Running error on Indicator using an array in a function

Postby arjfca » 15 Mar 2014

Hello John

My goal is to use a new function to draw lines on the right margin to simulate box's

A click from the mouse in these box triggered different functionalities like

- Capture trend line
- Copy trend line ( from the capture one ) to another chart
- Center a chart over an arrow ( help to see a one hour bar in a five minute scale)
- Erase arrow

All these function already in use, my goal is to draw box's to better defined the region that I need to click.
Attachments
Bloc area.jpg
(299.15 KiB) Downloaded 1303 times

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Re: Running error on Indicator using an array in a function  [SOLVED]

Postby bowlesj3 » 16 Mar 2014

Hi Martin,

I have never used the new command to capture bar data at the mouse click point. I would actually have to go look it up. Long before they had that command I came up with a work around that actually worked better for me (dropping 6 arrows to mark the waves as I saw them in the market, grabbing that data and sending it to my external program). I can have two sets of these arrows on each chart (1min, 5min, 10min, 15min, 30min an 60min). I made a mistake and only put one on the 10 second bars and I kick myself often for making that mistake. It would probably take me a month of solid programming and debugging to fix that error (8am to 8pm 7 days a week) so I keep putting it off.

As far as instructing MC as to what to do, I use the drawing object text box with a single letter in it to represent the command and I highlight it using the MC_Text_GetActive command to pick up my instruction to do something. I think you have seen that script. I have those drawing object text boxes along the top of the chart and use logic to make sure they are always out of the way regardless of how I adjust the vertical squeeze of the chart. Right now I have only 4 command text I can send to MC. I tend to use only one of them but MC can detect if it is behind the last bar of the chart or before the last bar of the chart and decide what to do based upon that (it just depends on your logic). So I use highlighted and none highlighted in various locations (above/below price and before/after last bar of chart). It works but it takes a while to get it to work correctly. Good old fashion debugging. So you could easily stack two rows of maybe 8 or 10 commands across the top and the same across the bottom and that is a lot of commands to send to MC. I refer to it as interactive programming. The trick is having the code to keep those text boxes out of the way at all times and the logic for that. For anyone first reading about this technique here is the link.
viewtopic.php?f=5&t=7764
It does not have the logic to keep the text boxes at the top or bottom of the chart regardless of squeeze. To do that you need to capture the top and bottom price and calculate a percentage distance from the top or bottom. Here is the code for that.

Code: Select all

{This is normal processing. Your arrow has not had a "highlighted then unhighlighted command sequence" yet}
{The constant positioning of the arrow can only be done here. Once it is highlighted these commands must not execute}
{Note: Locating the arrow must be executed on every tick so manual chart scale adjustments can be detected for repositioning it again}
ArrowLoc = MinutesToTime(TimeToMinutes(Time) - (ArrowSpace * ArrowNum)); {Space the arrows horizontally}
ScreenValHighest = GetAppInfo(aiHighestDispValue);
ScreenValLowest = GetAppInfo(aiLowestDispValue);
IntractiveArrow_Location = ScreenValHighest - ((ScreenValHighest - ScreenValLowest) * .03); {If close above screen middle}
value1 = Arw_SetLocation(Arw_ID[ArrowNum],Date,ArrowLoc,IntractiveArrow_Location);
I have code sort of similar to the above that places a set of vertical lines at the left side of the chart at the top or bottom depending on how close the prices are to the top or the bottom of that chart. It keeps those lines fairly short. They are different colors. I copy one of them and move the copy to mark a trade location. Different colors and line types mean different things. The logic for that is more complex than the above.

John

arjfca
Posts: 1292
Joined: 23 Nov 2010
Has thanked: 725 times
Been thanked: 223 times

Re: Running error on Indicator using an array in a function

Postby arjfca » 16 Mar 2014

Hello John

All the logic to mouse capture and all fancy thing are already done and working.
When I'm Shift clicking
- Over a bar, I capture it's data
- In the right margin of the chart, I have coded 5 regions that act like a button. When clicking in a region, a special function is triggered.
region 1: Capture all trend line
region 2: undefined
region 3: Center the chart over an arrow **
Region 4: Erase an arrow
Region 5: Copy all trend line to the chart

The last task that I wanted to do was simply, using a function, to create lines in the right margins to better highlight the button regions.

** I use the center over an arrow when looking like 4h bar charts. I place an arrow over a bar that I want to investigate, Switch the scale to 5 minutes and click on the button. My screen is center over the region that I had spotted in the 4h bar chart.

To allow me to go ahead in my task, I have decided to put aside the array coding. Since it was use only for 5 regions, individuals variables will do the job

Martin

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Re: Running error on Indicator using an array in a function

Postby bowlesj3 » 16 Mar 2014

I think arrays are fine. I think I would only consider a dynamic array if it was going to be over 200 elements and likely to vary a lot. If it is going to vary from 50 to 200 max I would just make if fixed. That is such a tiny amount of memory it is not worth the extra code. If it was going to run between 100 and 5000 for sure I would consider it. My code above just shows you that a lot of arrays can be passed to a function to have their values manipulated for later processing back in the indicator. That zero function above gets called from about 5 places in my indicator and even called from another function that the indicator is calling. I have some of those arrays being passed to other functions to do other types of updates. I use a lot of arrays. the biggest definition is 200 long. I have two arrays that are both 100 by 10 (multi level arrays). A lot of times I do not bother using the zero element of the array. I just prefer to go from 1 to 200 since it makes the coding easier to understand. It is a lot wiser I think to do everything you can to make your code easier to understand when you come back to it later since time spent trying to figure it out if it is not easy to understand can really add up. When I was young and first started coding I thought it was fun making my code complex and small. I have long since unloaded that novelty type of thinking. The simpler and easier to understand the better. I find that the logic alone of some of the things I have coded up, alone is enough to force me to think hard to get it to run properly. I don't want to make it any harder than it needs to be. I worry that too much smoke coming out the ears might set off the smoke detectors :-)
Last edited by bowlesj3 on 16 Mar 2014, edited 1 time in total.

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Re: Running error on Indicator using an array in a function

Postby bowlesj3 » 16 Mar 2014

In the right margin of the chart, I have coded 5 regions that act like a button. When clicking in a region, a special function is triggered.
I was thinking about this. I use a big right margin area too. (in the 1 minute bars especially but also in the 10 second bars). In the 1 minute bars it is 57 bars of space right of the last bar on chart. I have all sorts of stuff out there. Basically everything to the right of the last bar on chart is tied in with price. For example text boxes which mark exactly where one of the Bollinger bands are located for a larger bar chart such as the 15 minute bars or 5 minute bars. I have wave projections text boxes. I have a NET projection text box. I have target, stop and entry lines out there. I have band target and stop lines out there. I used Interactive broker bracket orders. I have lines out there that match where the brackets are set (dotted ones for before transmit making it easier to check and they become solid once I press transmit). It is all out there so I can see where it is relative to current price and where everything is relative to each other at a glance. I also have arrows out front of price up at the top. I can move those to a location and get text markers then the arrows move themselves back into position for the next text market I might want to drop somewhere. So what I am thinking is this. If I was to try to do what you are trying to do in the quotes above I simply would not have room for those big box areas since I have already used up all that right margin space with other stuff (very useful stuff). Instead of having those big boxes I have drawing object text boxes in the top region that act like a button which are much smaller. (so much smaller that I probably could fit about 20 of them yet they perform that same button function). You can also give them short form labels in 1 or more characters so you remember what they are for if you have a lot of them. I am still young enough that I can pretty much click on any one of them I select without missing (very rarely missing). If that becomes a problem all I have to do is increase the font size. So I am wondering if by using the small text boxes as buttons (rather than the big boxes marked out by lines) if it would not free you up to use that right margin space for other price based stuff you think of that is useful in the future. Right off the top I can think that the target line, stop line and entry line are useful for every single trader reading this. I think it is better to have it out front rather than blocking the price bars. One of these lines could by chance get hidden behind a box line. I can only think of one negative in the MC_Text_GetActive technique. It is the fact that it is a two click operation. You click the text you want then you wait for the beep and then click the background of the chart to actually trigger the action. Just something to consider.

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Re: Running error on Indicator using an array in a function

Postby bowlesj3 » 16 Mar 2014

Here is a box idea Martin that has all the advantages of my MC_Text_GetActive system and your system combined. You place text boxes across the top of the chart (bottom too if you want) and click between them rather than on them using your same mouse routines. You get the Text Box Codes to remind you of what they mean as well. You use the location of the text boxes to know what to do (maybe always clicking to the right of the one you want). Maybe you want to limit it to clicks above the text box so you can use the mouse technique for other clicks near the chart price bars (clicks below the text boxes if you have them on the bottom). You position the text box so the anchor points is at the bottom of the text so clicking between them anywhere works. You sound a beep so you know it picked up your click. You still get all that space to the right to work with yet you can have a lot more of these text boxes giving you more functions. It is a lot easier to program too. I gather you only need to do one click to signal it. All you have to do really is on every barstatus=2 is move the text boxes one bar forward so they are always in position.

It is too bad they did not have the mouse commands when I wrote the MC_Text_GetActive system. I might have thought of this back then. However with my system you can convert the idea to an arrow rather than text and move it somewhere on the chart to signal something to happen there and depending on what arrow you drag you can have any number of things. So the MC_Arw_GetActive version of the method is still useful. You can't do this with the mouse click routine alone. The advantage of moving an arrow is you may not get the location correct immediately and have to adjust it and it only signals to act once you remove the highlight (it gives you a chance to verify it).

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Re: Running error on Indicator using an array in a function

Postby bowlesj3 » 18 Mar 2014

I just created a little dynamic array test. At the very bottom are the print results. Using the input parameter of the indicator I set the array size to 10 (changing it from the default value of 9) then inside the function it changed the array size to 20. I assigned the values to the array itself inside the function and printed the contents outside the function after it had completed. It did not abort and it printed the results I expected so I would assume it worked. I am not sure I will ever use it but it was interesting.

Updated:
see the next post for a better test run of a dynamic array being updated then both extended and updated by a function.
Last edited by bowlesj3 on 19 Mar 2014, edited 4 times in total.

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Re: Running error on Indicator using an array in a function

Postby bowlesj3 » 19 Mar 2014

I missed a test. This test shows that the data already in the dynamic array is kept when you increase the size of the dynamic array.

I suppose you could use a dynamic array to prevent your Power Language code from aborting if you are unsure of how much data will be loaded in the array and the amount exceeds your estimate. I would be tempted to (in the event of an increase in the size of the array) set a global variable indicating that this occurred and test it after trading hours to create an abort so I am aware this occurred and so I know the new size. I would then increase the original allocation. In some instances it may be important to actually know this new size.

The Test Indicator:

Code: Select all

Inputs: MyArraySize(10);

Array: MyArray[](0);

variables:
logPath(""),
MyArraySizeWork(0),
X(0);

if currentbar = 1 then
Begin
Array_SetMaxIndex(MyArray,MyArraySize);
end;


If lastbaronchart then
begin
MyArraySizeWork = MyArraySize;
MyArray[9] = 9; {Place a value in the array before it was extended by the function. Print it after extending the array.}
value1 = A_Test_ArrayDynamicFunction(MyArraySizeWork,MyArray);
Print (MyArraySizeWork, MyArray[MyArraySizeWork]);
LogPath = "C:\Test_ArrayDynamic.txt";
Print(File(logPath),
" MyArraySizeWork=",
MyArraySizeWork,
" MyArray[MyArraySizeWork]=",
MyArray[MyArraySizeWork],
" ");
{Print the value in the array which was placed there before it was extended.}
Print(File(logPath),
" MyArraySizeWork=",
MyArraySizeWork,
" MyArray[9]=",
MyArray[9],
" ");
end;
The test function:

Code: Select all

{A_Test_ArrayDynamicFunction =================================================}

inputs:
MyArraySize(Numericref),
MyArray[M] (NumericArrayRef);

variables:
X(0);

if MyArraySize = 10 then
begin
MyArraySize = 20;
Array_SetMaxIndex(MyArray,MyArraySize);
end;

for X = 0 to MyArraySize
begin
MyArray[x] = X;
end;

A_Test_ArrayDynamicFunction = 0;
The result:
MyArraySizeWork= 20.00 MyArray[MyArraySizeWork]= 20.00 <<<This value was placed after size increase.
MyArraySizeWork= 20.00 MyArray[9]= 9.00 <<<This shows the original value is still there.
Last edited by bowlesj3 on 19 Mar 2014, edited 1 time in total.

arjfca
Posts: 1292
Joined: 23 Nov 2010
Has thanked: 725 times
Been thanked: 223 times

Re: Running error on Indicator using an array in a function

Postby arjfca » 19 Mar 2014

I missed a test. This test shows that the data already in the dynamic array is kept when you increase the size of the dynamic array.
You bring me deep in new knowledge John

Martin :)

bowlesj3
Posts: 2180
Joined: 21 Jul 2007
Has thanked: 227 times
Been thanked: 429 times

Re: Running error on Indicator using an array in a function

Postby bowlesj3 » 19 Mar 2014

LOL, thanks Martin. As long as you are a good swimmer in deep waters that is okay. Its fun learning new things. John


Return to “MultiCharts”