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 [email protected], "Markus Witzler" <funny...@...> wrote: > > Hello TJ et al., > > may I ask once again? > > Thanks > > Markus > ----- Original Message ----- > From: Markus Witzler > To: [email protected] > 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: [email protected] > 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: [email protected] > 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); >
