wrong ATR value in exploration mode

#1
Hi,

I am porting a system from another platform to Amibroker and I am running into problems with the ATR / position sizing part of the code.

I nshort: the ATR values seem to be wrong hence the position sizing, stop loss and risk rewards are all wrong.

When I output the ATR from outside the code (I call AddColumn(ATR(20), "ATR"); directly ), the correct ATR value shows. When I call the variable storing the ATR value inside the code it is incorrect.

Any idea as per why?

Thanks

Code:
#include "C:\Program Files\AmiBroker\Formulas\Custom\RSI_Solver.afl"


//Filter = Status( "LastBarInTest" );


risk = 0.05;

/* Position sizing */
Account_Size = 10000;
Risk_Lvl = Account_Size * risk;
	

// --- detect watchlist ---
wlnumber     = GetOption( "FilterIncludeWatchlist" );
symlist      = GetCategorySymbols( categoryWatchlist, wlnumber );


	
if ( Status( "stocknum" ) == 0 )
{	
	// delete static variables


// fill input static arrays

	for ( i = 0; ( sym = StrExtract( symlist, i ) ) != ""; i++ )
	{
    SetForeign( sym );
    GSPC = Foreign("GSPC", "C");
    
    vol = ATR(20); 
    Ratio = (C / GSPC);
    MA_Ratio = MA(ratio, 20);
    Sdev_Ratio = StDev(Ratio, 20);
    Diff20 = Ratio - MA_Ratio;
    ZScore20 = Diff20 / Sdev_Ratio;

	B1 = Zscore20 < 0;
	B2 = barssince( Zscore20 > 0 ) > 3;
	//B3 = L < BBandBot(10,2);
	B4 = C > MA(C, 100);
	B5 = RSI(2) < 15;

	Cond = B1 AND B2 /*AND B3*/ AND B4 AND B5;
	
	
	/* Entry Price based on targeted RSI */
	Limit_Entry = Min (C , ReverseRSI(2,5) );

	
	//StaticVarSet("vol" + sym, vol);
	//vol =	StaticVarGet ("vol" + sym);
	
	/* Stop price based on ATR */
	Stop_Amt = 2 * vol;
	Stop_Price = Limit_Entry - Stop_Amt;
	//ApplyStop(stopTypeLoss , stopModePoint, Stop_Price);

	/* Number of shares */
	Shares = Risk_Lvl / (vol / C) / C ;
	
	Position_Size = Limit_Entry * Shares;
	
    /*DETERMINE THE REWARD-TO-RISK RATIO BASED ON THE PROFIT TARGET AT RSI(2) = 90*/
	Reward = ( ReverseRSI(2,90) - Limit_Entry ) * Shares;
	RR = Reward / Risk_Lvl;
	
	RestorePriceArrays();
	
	StaticVarSet("vol" + sym, vol);

	StaticVarSet("zscore" + sym, ZScore20);
	StaticVarSet("shares" + sym, Shares);
	StaticVarSet("limit_entry" + sym, Limit_Entry);
	StaticVarSet("stop_price" + sym, Stop_Price);
	StaticVarSet("cond" + sym, Cond);
	StaticVarSet("rr" + sym, rr);
	}
}

sym = Name();
cond = StaticVarGet("cond" + sym);	

Filter=1 AND cond == 1 ;

vol = StaticVarGet("vol" + sym);

zscore = StaticVarGet("zscore" + sym);
shares = StaticVarGet("shares" + sym);
limit_entry = StaticVarGet("limit_entry" + sym);
stop_price = StaticVarGet("stop_price" + sym);	
rr = StaticVarGet("rr" + sym);

//AddColumn(zscore,"Zscore");
//AddColumn(cond, "Cond");
AddColumn(RSI(2), "RSI2");
AddColumn(ATR(20), "ATR(20)");  //Correct ATR value
AddColumn(vol, "ATR in code");  // incorrect ATR value (the one used inside the code)
AddColumn(C, "Closing Price");
AddColumn(shares, "Shares to Buy");
AddColumn(limit_entry,"Limit Entry");
AddColumn(reverseRSI(2,90),"Profit Target");
AddColumn(stop_price,"Stop Loss");
AddColumn(100*rr,"Risk/Reward");

SetSortColumns( -10 );
//AddRankColumn();


/*
AddColumn(Shares, "Shares to Buy");

AddColumn(RR,"Risk/Reward");

SetSortColumns( -11 );
AddRankColumn();


AddColumn(Position_Size,"Position Size");
*/
 

trash

Well-Known Member
#2
The values are not wrong. You just don't understand what happens.
If the symbol that has stocknum 0 has i.e. just 100 bars but all other symbols of the watchlist have 1000 bars then since the loop is executed for stocknum 0 it just uses those 100 bars to calculate ATR with values of foreign symbol (in your case the ones where SetForeign is used) being at same date position as stocknum 0. You got it?

BTW, stop polluting every forum with the same question. You've already asked the same question at AB official forum and whatever other forum. Imagine you already got response in other forum but people giving response in different forum don't know about that. In short latter ones are wasting their time. It's pretty selfish attitude of yours. Simply go to AB support or use just one forum instead of hunting for responses in each and every available forum.
 
#3
Hi Trash,

Thanks for the explanation re stocknum. Makes sense.

As you can see I came back to traderji to say that I had the response and provide the corrected code in case it would be of any use to others.
I guess, this is unlike many who would just let the post die...

I post on 2 different places for obvious reasons : you wont find the same people on traderji and AB's official channel. Also: most forums looks like dead places (unlike NinjaTrader's forums) so asking some questions and getting people a bit more "involved" may not be too bad an idea, what do you think?


Anyways: here is the code:

Code:
/*
The original code was created by a Stockfetcher user.
I ported it (with some help!) to Amibroker.

This exploration identifies weakness of a stock against an index
if score  < 0 for at least 3 bars & if price still above MT Moving average & and RSI(2) is oversold : stock is shortlisted and 
AB calculates the # shares to buy, price target, stop loss and Risk/Reward.

RSI_Solver can be easily found here: http://mysimplequant.blogspot.sg/2010/11/rsi-predictor-for-amibroker.html
*/


#include "C:\Program Files\AmiBroker\Formulas\Custom\RSI_Solver.afl"

wlnumber     = GetOption( "FilterIncludeWatchlist" );

GSPC = Foreign( "GSPC", "C" );

Ratio = ( C / GSPC );
MA_Ratio = MA( ratio, 20 );
Sdev_Ratio = StDev( Ratio, 20 );
Diff20 = Ratio - MA_Ratio;
ZScore20 = Diff20 / Sdev_Ratio;

B1 = Zscore20 < 0;
B2 = barssince( Zscore20 > 0 ) > 3;
//B3 = L < BBandBot(10,2);
B4 = C > MA( C, 100 );
B5 = RSI( 2 ) < 15;

Cond = B1 AND B2 /*AND B3*/ AND B4 AND B5;

Filter = InWatchList( wlnumber ) AND Cond;

risk = 0.05;

/* Position sizing */
Account_Size = 10000;
Risk_Lvl = Account_Size * risk;
	

/* Entry Price based on targeted RSI */
Limit_Entry = Min (C , ReverseRSI(2,5) );
vol = ATR(20);
	
	
/* Stop price based on ATR */
Stop_Amt = 2 * vol;
Stop_Price = Limit_Entry - Stop_Amt;
//ApplyStop(stopTypeLoss , stopModePoint, Stop_Price);

/* Number of shares */
Shares = floor( Risk_Lvl / (Stop_Amt / C) / C );
	
Position_Size = Limit_Entry * Shares;
	
/*DETERMINE THE REWARD-TO-RISK RATIO BASED ON THE PROFIT TARGET AT RSI(2) = 90*/
Reward = ( ReverseRSI(2,90) - Limit_Entry ) * Shares;
RR = (Reward / Risk_Lvl) ;
	

AddColumn(RSI(2), "RSI2");
AddColumn(ATR(20), "Vol[20]");
AddColumn((vol / C) * 100 , "Vol[20] %");
AddColumn(C, "Closing Price");
AddColumn(limit_entry,"Limit Entry");
AddColumn(Shares, "Shares to Buy");
AddColumn(reverseRSI(2,90),"Profit Target");
AddColumn(Stop_Price,"Stop Loss");
AddColumn(100*RR,"Risk/Reward %");

SetSortColumns( -11 );
//AddRankColumn();
 

trash

Well-Known Member
#4
Well, you already said it. People hunting for responses in several forums mostly disappear and won't come back with "solution" they got in the other forum(s). I doubt you would have come back if I would not have responded here (together with provocative comment).

AB official forum or this one are dead places? You're kidding?
The reason NT forum might have more (useless) posts is that free junk always gets more attention just like McDonalds enjoys larger clientele than a 5-star French restaurant.
 
#5
Believe it or not: I would have come back, regardless of the comment. (plus, I appreciate your feedback)

AB official forum is not a dead place (and many contributors are pretty good) BUT the format doesnt make it very easy to navigate (unlike a forum like traderji). Overall, I think AB doesnt get the credit and attention it deserves.
I have been shocked at how simple (and fast) some stuff I was trying to achieve was done in AFL.

I think NT is a more active place because of their marketing policy which is pretty smart. Basically they are like coke dealers. On the + side, the community is pretty large and looks active.
 

toptrader

Active Member
#6
Well, you already said it. People hunting for responses in several forums mostly disappear and won't come back with "solution" they got in the other forum(s). I doubt you would have come back if I would not have responded here (together with provocative comment).

AB official forum or this one are dead places? You're kidding?
The reason NT forum might have more (useless) posts is that free junk always gets more attention just like McDonalds enjoys larger clientele than a 5-star French restaurant.

but did you ever? you're always breaking balls :lol::lol:
 

trash

Well-Known Member
#7
but did you ever? you're always breaking balls :lol::lol:
Not sure what you mean by "but did you ever?".

FYI, in general I'm a problem solver but not a solution seeker. In 90% of cases I use my own brain.

But if I would ever want to ask for a solution to a problem then I would never hunt for responses in hundreds of forums at the same time for sure. Also I would rather go to the most competent source first. In the case of AB it would be AB support.

In a parallel universe if I would have asked the identical question in several forums and I would have gotten a response in one of them then for sure I would provide the solution in every thread of the other forums I posted. Just like in this universe in such parallel universe I would not be a lazy selfish guy (in contrast to 90% of people out there). How do I know? I phoned my other self through a wormhole.
 

Similar threads