Help need debugging simple Amibroker AFL code

Discussion in 'Programming' started by curiouscat, May 7, 2013.

  1. Hi,

    Can anyone help me debug following code.


    SetBarsRequired( sbrAll, sbrAll );
    printf("BarCount is %f\n", BarCount);
    printf("Close[Barcount-1] is %f\n", Close[BarCount-1]);
    printf("Close[0] is %f\n", Close[0]);
    printf("Close[20] is %f\n", Close[20]);
    printf("Close[200] is %f\n", Close[200]);


    I am encountering error in 6th line when accessing the array Close beyond a certain index. The error encountered is following:
    Error 10. Array subscript out of range. You must not access array elements outside 0..(BarCount-1) range. You attempted to access non-existing 200-th element of array.

    I have run this on two symbol databases (NIFTY, NiftyEOD). Both give the same error (but for different index range).
    Database NIFTY ---- cannot access indices 21 and beyond
    Database NiftyEOD --- cannot access indices 200 and beyond.

    I have turned off quickAFL in first line. I printed value of BarCount in 2nd line to be sure that I am not trying to access non-existing index. What is bizzare is that I am able to access these same indices by putting suitable value of x in the notation Close[BarCount-x], but not by directly writing the index value. For example, for database NiftyEOD, BarCount is 373. So I cannot directly access Close[200] but can access it by writing Close[BarCount-173].

    Same error is encountered when accessing other array like Open, High etc. Other lines in code give correct output when I remove the 6th line. Following is output for database NiftyEOD with 6th line of code removed.

    BarCount is 373.000000
    Close[Barcount-1] is 5904.100098
    Close[0] is 5257.950195
    Close[20] is 4936.850098


    Following are the links to database files I am using so that you can reproduce the error.
    NIFTY: https://docs.google.com/file/d/0B86aDguWp8SrUFpELWZUbnlPZ28/edit?usp=sharing
    NiftyEOD: https://docs.google.com/file/d/0B86aDguWp8SrekV4c1B0N2FRb0U/edit?usp=sharing


    P.S. This is my first attempt writing code for Amibroker, so pardon me if I have made some obvious mistakes. :)[/QUOTE]
     
  2. I have never programmed with this language but the error message seems pretty clear. An array of 200 elements goes from element 0 to 199. There is no element 200. So the program doesn't like printing the 201th entry in a 200 element array.

    Modify printf("Close[200] is %f\n", Close[200]); to

    printf("Close[200] is %f\n", Close[199]);

    and see if the error goes away.
     
  3. This is programming language for technical analysis sofware Amibroker (now I realize I forgot to mention that in thread title :(). In Amibroker, the symbol/ticker quotes are in form of arrays like Close, High, Open etc. They are all of same size which is given by system variable BarCount. So actually the size of array Close is 373 for symbol NiftyEOD. You are right, I can access index 199. Thats not the problem. And I can also access Close[200] by using syntax Close[BarCount-173]. But why I am not able to access through more direct syntax?
     
  4. Use this one

    Code:
    SetBarsRequired( sbrAll, sbrAll );
    
    bar = Min( BarCount - 1, 200 );
    myC = Close[ bar ];
    
    printf( "bar is %g\n", bar );
    printf( "Close[200] is %g\n", myC );
    Here is the quote by Marcin of AmiBroker

    BTW that message only appears if you click "Apply indicator" in the formula editor but not if using "Insert linked" or double click of the AFL in the "Charts" sidebar.
     
  5. Array's can be allocated in two ways in languages - runtime and compile time. Some languages (especially script type languages) can't be dynamically runtime size allocated or changed at runtime and the size must be set at compile time. So the next thing I would do is use a sizeof(ARRAY) type function and print that out to see if it is really 373 size. Some interpreters will create two variables one the array size (compile time) and the other a second variable runtime type

    If the variable is similar to a BASIC undefined type and has a dynamic runtime typing then the act of printing a variable as a float in the line above ( strictly speaking an error in your program since arrays have integer sizes and the compiler may set a float type to the variable Barcount. Arrays require integer type addressing. Perhaps that is an issue. There may be a function to change types and you can use it to print Array[tointeger[BarCount]] as another test.

    The act of getting BarCount - 137 may end up cast to integer type and make the code work, in spite of the minor programming flaw confusing integer and float types.

    Note that there are many confusing things in programming. Your printf for example prints 200 in two different ways, one is a numerical symbol and the other is a float type variable. Programmers must understand those things and use them correctly since compilers are pretty literal. If the variable Barcount is reset in the program somewhere, it may not be possible to change its type.

    Just some suggestions.

    I see you have other answers so I will step aside and leave this more general comment for clues. Good luck
     
  6. Thank you all for your replies.


    @GeorgeClueney: Putting the code inside the If condition works! Although there were other discrepencies in array access which I would like to have cleared up but that would be more out of curiosity than necessity. Meanwhile, this works as an acceptable solution. I will use the If condition and move on.

    And Stardust9182, thanks for your suggestions. I will keep them in mind while coding.
     
  7. Hi. I am trying to create an index whose value is collected every 2 min and then
    displayed in a 1 hour OHLC format based on three stocks using the ff formula.

    Myindex= ((aapl/10)+ (1/goog)+ csco)/3

    I created indx.afl with the ff code.

    n = Name();
    array = 0;
    if( n == "aapl" ) array = Close/10;
    if( n == "csco" ) array = Close;
    if( n == "goog" ) array = 1/Close;
    AddToComposite(array/3, "~MyComposite","X");
    Buy = 0;

    I saved it, then sent to analysis window , used a filter of "stox" watchlist
    containing the 3 stocks. I ran the scan 5 times 3 minutes apart thinking that
    ~mycomposite would have 5 single values derived from ((aapl/10)+ (1/goog)+ csco)/3 AND timestamped 3 minutes apart which could then be compressed into a higher interval OHLC. I went into quote editor and saw 3 values for today, 3
    values for yesterday, 3 values 2 days ago,etc w strange random timestamps.
    Furthermore, the 3 values per day represented individual closings of
    goog,aapl,csco and not the composite value I needed using ((aapl/10)+ (1/goog)+
    csco)/3. Appreciate it if you guys could lead me to the right path for I 've
    been at this for hours, reading documentation that is like 7 years old. I just
    bought the latest pro version and have IB as my data source. Thanks.