Hello Mike,

I appreciate the suggestion.

Your approach may not work since "y" in your example was generated by using atc 
function, thus cutting of the "needed information" (i.e.digits).

For example:

AtrExpLag (before using atc) was 3.115.

Then I transfered it into atc function, thus becoming 3.

If I used your code, it would become prec (3+0.005, 2), thus 3.01 whereas it 
actually was 3.115

Reading your suggestion, I just thought of another approach:

Multiplying the variable ATRExpLag (BEFORE using atc) with 1000 to get rid of 
the digits, then creating atc, thereafter dividing it by 1000 once again "to 
get the digits right".

This is a pain, but it might work.

I´ll try.

If I don´t succeed, "I´ll be back".

Many thanks to all for your assistance!!!!!!!

Markus




  ----- Original Message ----- 
  From: Mike 
  To: amibroker@yahoogroups.com 
  Sent: Saturday, July 25, 2009 5:30 AM
  Subject: [amibroker] Re: Still - using CBT the first time


    If you don't find what you're looking for, you can use the Prec function.

  e.g. to round 'y' to 2 decimal places such that 3rd decimal at or above 0.005 
bumps up 2nd decimal place, 3rd decimal below 0.005 leaves 2nd decimal 
unchanged:

  x = Prec(y + 0.005, 2);

  Mike

  --- In amibroker@yahoogroups.com, "Markus Witzler" <funny...@...> wrote:
  >
  > Hello TJ et al.,
  > 
  > may I ask once again?
  > 
  > Thanks
  > 
  > Markus
  > ----- Original Message ----- 
  > From: Markus Witzler 
  > To: amibroker@yahoogroups.com 
  > Sent: Thursday, July 23, 2009 1:36 PM
  > Subject: Re: [amibroker] Still - using CBT the first time
  > 
  > 
  > 
  > Hello Tomasz,
  > 
  > thanks for the heads up.
  > 
  > Floor () doesn´t do want I want: rounding down if first digit is smaller 
than 5, rounding up if it´s equal to or bigger than 5.
  > 
  > Anyway, I found the flaw in my code but I don´t know how to correct it:
  > 
  > In regular AFL code, I use the following to compute "ATRExpLag". Then I 
round it to the 3rd digit ("ATRExpLagRounded"). Thereafter, I create an 
artificial ticker, labeled "test" to be later able to call it in CBT:
  > for( i = 1; i < BarCount; i++ ) // here, the Average True Range (20 days) 
is coded by using a loop
  > 
  > { 
  > 
  > trhelp[i]= Max(High[i]-Low[i],High[i]-Close[i-1]); //trhelp is a helping 
variable for calculating ATRcombined. ATR() function cannot be used.
  > 
  > TRcombined[i]= Max(Close[i-1]-Low[i],trhelp[i]); //TRcombined is the actual 
TrueRange. 
  > 
  > ATRExpLag[i]=ATRExpLag [i-1]+ (TRcombined[i]-ATRExpLag[i-1])/x; // This is 
the 20-day expon. moving average of the ATR
  > 
  > }
  > 
  > ATRExpLagRounded=round(ATRExpLag*1000)/1000; //here, I round on the 3rd 
digit.
  > 
  > test=AddToComposite(ATRExpLagRounded, "~ATRExpLagRounded_"+Name(), "V", 
atcFlagDefaults | atcFlagEnableInBacktest);
  > 
  > 
  > Here comes the CBT part. When I run an Exploration to see what´s in "test", 
it always returns "1" instead of the values it got from "ATRExpLagRounded". But 
it should hold the values of "ATRExpLagRounded", right?! Incidentally, I 
introduced "y" to be able to use previous days values for ATRExpLagRounded 
except for the first day (otherwhise value would be out of range). The 
"-200-sharesize" thing works fine though:
  > 
  > for (sig = bo.GetFirstSignal(i); sig; sig = bo.GetNextSignal(i))
  > 
  > { // Loop through all signals at this bar
  > 
  > // Long trades
  > 
  > ATRexRounded = Foreign("~ATRExpLagRounded_"+sig.Symbol, "V"); // Get 
symbol's AtrExpLagRounded array
  > 
  > ATRex = ATRexRounded[i]; // Reference a value in the array
  > 
  > 
  > { 
  > 
  > if (i<=0) 
  > 
  > y=ATRexRounded[i];
  > 
  > else 
  > 
  > y=ATRexRounded[i-1]; 
  > 
  > 
  > }
  > 
  > if (sig.IsEntry() && sig.IsLong()) // Process long entries
  > 
  > 
  > {
  > 
  > sharesize=round(((Heat*bo.cash)/(y*ATRmultiplier))/250)*250; // i.e. 
computing # of shares/contracts
  > 
  > // sig.possize=sharesize*sig.price;
  > 
  > 
  > //Sharesize formula needs to be modified for stocks if lot size differs!!
  > 
  > 
  > sig.possize=-2000 - sharesize; // i.e. setting back # of shares into signal 
object!! Possize must be < "-2000"
  > 
  > // to mean # of shares (see "Setpositionsize")!! 
  > 
  > bo.EnterTrade(i, sig.Symbol, True, sig.Price, sig.PosSize);
  > 
  > 
  > 
  > ----- Original Message ----- 
  > From: Tomasz Janeczko 
  > To: amibroker@yahoogroups.com 
  > Sent: Wednesday, July 22, 2009 7:33 PM
  > Subject: Re: [amibroker] Still - using CBT the first time
  > 
  > 
  > 
  > 
  > Use floor() function instead of round().
  > 
  > http://www.amibroker.com/f?floor
  > 
  > Best regards,
  > Tomasz Janeczko
  > amibroker.com
  > ----- Original Message ----- 
  > From: Markus Witzler 
  > To: amibroker@yahoogroups.com 
  > Sent: Wednesday, July 22, 2009 7:17 PM
  > Subject: [amibroker] Still - using CBT the first time
  > 
  > 
  > Hello all,
  > 
  > I intend to use CBT to compute proprietary position size (number shares 
instead of percentage of equity or amount of money) as I wrote before.
  > 
  > Now that AB has been told (thru assistance of Bruce, Mike and TJ ) to use 
"number of shares", I still don´t know why it doesn´t output the proper size:
  > 
  > The formula for computing sharesize is as follows (entire code see further 
below):
  > 
  > sharesize=round(((Heat*bo.cash)/(y*ATRmultiplier))/250)*250
  > 
  > According to my data, I read for a specific day
  > 
  > where y=3.115 ATR multiplier=5 heat=0.1 bo.cash=1000000.00
  > 
  > which should result in a sharesize of 6,500. But instead, AB computes a 
sharesize of 6,750. Thus, I´m off by one unit of 250 lots.
  > 
  > Maybe it´s due to the calculation of y? Could someone please help me with 
this? It probably caused by the AB´s rounding but I just can´t figure it out.
  > 
  > If so, I will provide the data for the S&P contract I use so that the 
results I get could be reproduced.
  > 
  > Thanks very much
  > 
  > Markus
  > 
  > - - - - - - - - - - - - - - - - - - - - - - - - - -
  > 
  > /*Setting different options to clarify or override backtester settings*/
  > 
  > //SetOption("InitialEquity", 1000000.00);
  > 
  > SetOption("UsePrevBarEquityForPosSizing", True);
  > 
  > //SetOption("MinShares", 250);
  > 
  > SetOption("CommissionMode", 2); //$$ per trade
  > 
  > SetOption("Marginrequirement", 100);
  > 
  > SetOption("InterestRate",0); // account doesn´t earn interest for cash 
balance!
  > 
  > SetTradeDelays( 1, 1, 1, 1 );
  > 
  > 
  > 
  > //RoundLotSize = 250;
  > 
  > Heat= 0.1; // provided by ED
  > 
  > ATRMultiplier=5; //provided by ED
  > 
  > TC150=150;
  > 
  > TC15=15;
  > 
  > n=20; // Time Constant used in ATR lag computation
  > 
  > x=(n+1)/2;
  > 
  > 
  > 
  > /* Calculation of TC150 EMA and TC15 EMA*/
  > 
  > SetBarsRequired( sbrAll, sbrAll ); 
  > 
  > EMA150[0]=Close[0]; 
  > 
  > EMA15[0]=Close[0];
  > 
  > for( i = 1; i < BarCount; i++ ) 
  > 
  > { 
  > 
  > EMA150[i]=EMA150[i-1]+(Close[i]-EMA150[i-1])*2/(TC150+1); 
  > 
  > EMA15[i]=EMA15[i-1]+(Close[i]-EMA15[i-1])*2/(TC15+1);
  > 
  > 
  > 
  > } 
  > 
  > 
  > 
  > /* Controlling trade price*/
  > 
  > BuyPrice=Open+(High-Open)/2; //i.e. 50% slippage
  > 
  > SellPrice=Open-(Open-Low)/2; //i.e. 50% slippage 
  > 
  > 
  > 
  > /*Trading rules and optimization*/
  > 
  > 
  > 
  > Buy= Cum(1)>=25 AND Cross(EMA15, EMA150);
  > 
  > Sell= Cross(EMA150, EMA15);
  > 
  > /* Graphic output*/
  > 
  > Plot(EMA150, "My expon. Lag 150", colorGreen, styleLine);
  > 
  > Plot(EMA15, "My expon. Lag 15", colorRed, styleLine);
  > 
  > Plot (Close, "Bar Chart", colorBlue, styleBar);
  > 
  > EMA15 = Optimize("EMASlow", 50, 1, 150, 1 ); 
  > 
  > EMA150 = Optimize("EMAFast", 150, 20,400, 1); 
  > 
  > Buy = ExRem( Buy, Sell ); // to exclude redundant signals
  > 
  > Sell = ExRem( Sell, Buy );// to exclude redundant signals
  > 
  > 
  > 
  > /* Position sizing - volatility based*/
  > 
  > trhelp[0]=0; // trhelp is being initialized
  > 
  > TRcombined[0]=0; // TRcombined is being initialized
  > 
  > ATRExpLag[0]=High[0]-Low[0]; // ATRExpLag is being initialized; seed value 
is the 1st day´s high-low range per Ed´s definition
  > 
  > 
  > 
  > for( i = 1; i < BarCount; i++ ) // here, the Average True Range (20 days) 
is coded by using a loop
  > 
  > { 
  > 
  > trhelp[i]= Max(High[i]-Low[i],High[i]-Close[i-1]); //trhelp is a helping 
variable for calculating ATRcombined. ATR() function cannot be used.
  > 
  > TRcombined[i]= Max(Close[i-1]-Low[i],trhelp[i]); //TRcombined is the actual 
TrueRange. 
  > 
  > ATRExpLag[i]=ATRExpLag [i-1]+ (TRcombined[i]-ATRExpLag[i-1])/x; // This is 
the 20-day expon. moving average of the ATR
  > 
  > 
  > 
  > }
  > 
  > ATRExpLagRounded=round(ATRExpLag*1000)/1000; //here, I round on the 3rd 
digit.
  > 
  > AddToComposite(ATRExpLagRounded, "~ATRExpLagRounded_"+Name(), "V", 
atcFlagDefaults | atcFlagEnableInBacktest);
  > 
  > 
  > 
  > Filter = GroupID() != 253; // Exclude "group 253" in which composites are 
being saved/
  > 
  > 
  > 
  > SetCustomBacktestProc("");
  > 
  > if (Status("action") == actionPortfolio)
  > 
  > {
  > 
  > bo = GetBacktesterObject(); // Get backtester object
  > 
  > bo.PreProcess(); // Do pre-processing
  > 
  > 
  > bo.cash=1000000; // muß das hier stehen oder im indexierten loop; dann aber 
wäre doch bei jeder iteration das
  > 
  > // initial equity UND DAMIT auch das old cash immer wieder 1000000.00!!??
  > 
  > My_total_equity=0; 
  > 
  > Value_open_positions=0;
  > 
  > Heat=0.1;
  > 
  > ATRmultiplier=5;
  > 
  > 
  > for (i = 0; i < BarCount; i++) // Loop through all bars
  > 
  > 
  > {
  > 
  > for (sig = bo.GetFirstSignal(i); sig; sig = bo.GetNextSignal(i))
  > 
  > { // Loop through all signals at this bar
  > 
  > // Long trades
  > 
  > ATRexRounded = Foreign("~ATRExpLagRounded_"+sig.Symbol, "V"); // Get 
symbol's AtrExpLagRounded array
  > 
  > ATRex = ATRexRounded[i]; // Reference a value in the array
  > 
  > 
  > { 
  > 
  > if (i<=0) 
  > 
  > y=ATRexRounded[i];
  > 
  > else 
  > 
  > y=ATRexRounded[i-1]; 
  > 
  > 
  > }
  > 
  > if (sig.IsEntry() && sig.IsLong()) // Process long entries
  > 
  > 
  > {
  > 
  > sharesize=round(((Heat*bo.cash)/(y*ATRmultiplier))/250)*250; // i.e. 
computing # of shares/contracts
  > 
  > 
  > 
  > // sig.possize=sharesize*sig.price;
  > 
  > 
  > //Sharesize formula needs to be modified for stocks if lot size differs!!
  > 
  > 
  > sig.possize=-2000 - sharesize; // i.e. setting back # of shares into signal 
object!! Possize must be < "-2000"
  > 
  > // to mean # of shares (see "Setpositionsize")!!
  > 
  > 
  > bo.EnterTrade(i, sig.Symbol, True, sig.Price, sig.PosSize);
  > 
  > // wird hier die cash position durch Eingehen des Trades bereits autom. auf 
neuen Stand gebrachtoder muß das eigens codiert werden?
  > 
  > //Das mittels addcustometric (cash position prüfen)!
  > 
  > // oder müßten die Adcustommetric erst nach sämtl. long- und short signalen 
stehen??
  > 
  > /*
  > 
  > trade.AddCustomMetric("initial equity", initial_equity); //zur Kontrolle 
und graphische Aufbereitung
  > 
  > trade.AddCustomMetric("Cash position", bo.cash); 
  > 
  > trade.AddcustomMetric("Position size [shares]", trade.shares);
  > 
  > trade.AddCustomMetric("Position Value", sig.possize);
  > 
  > */
  > 
  > 
  > }
  > 
  > else
  > 
  > { if (sig.IsExit() && sig.IsLong()) // Process long exits (cover longs)
  > 
  > 
  > //die position size muß doch hier nicht angegeben werden, da vom system 
bekannt, oder?
  > 
  > 
  > bo.ExitTrade(i, sig.Symbol, sig.Price);
  > 
  > // Achtung, daß bei Exits die Cash position korrekt ausgewiesen wird, oder 
ob man das manuell codieren muß
  > 
  > }
  > 
  > 
  > // bo.HandleStops(i); // Process programmed stops or applystop at this bar
  > 
  > } // End of for loop over signals at this bar
  > 
  > 
  > bo.UpdateStats(i, 1); // Update MAE/MFE stats for bar
  > 
  > bo.UpdateStats(i, 2); // Update stats at bar's end
  > 
  > } // End of for loop over bars
  > 
  > bo.PostProcess(); // Do post-processing
  > 
  > /*AddToComposite( My_total_equity, "~~~My_total_equity", "X", 
atcFlagEnableInPortfolio | atcFlagDefaults );
  > 
  > AddToComposite( trade.shares,"~~~Position size [shares]", "X", 
atcFlagEnableInPortfolio | atcFlagDefaults );
  > 
  > AddToComposite( sig.possize, "~~~Position Value", "X", 
atcFlagEnableInPortfolio | atcFlagDefaults );
  > 
  > AddToComposite( bo.cash, "~~~Cash position", "X", atcFlagEnableInPortfolio 
| atcFlagDefaults );
  > 
  > AddToComposite( Value_open_positions, "~~~Value of open positions", "X", 
atcFlagEnableInPortfolio | atcFlagDefaults );
  > 
  > */
  > 
  > }
  > 
  > /* Exploration output*/
  > 
  > AddColumn(ATRExpLagRounded,"ATRExpLagRounded",1.5);
  >



  

Reply via email to