PureBytes Links
Trading Reference Links
|
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@xxxxxxxxxxxxxxx, "Markus Witzler" <funnybiz@xxx> wrote:
>
> Hello TJ et al.,
>
> may I ask once again?
>
> Thanks
>
> Markus
> ----- Original Message -----
> From: Markus Witzler
> To: amibroker@xxxxxxxxxxxxxxx
> 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@xxxxxxxxxxxxxxx
> 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@xxxxxxxxxxxxxxx
> 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);
>
------------------------------------
**** IMPORTANT PLEASE READ ****
This group is for the discussion between users only.
This is *NOT* technical support channel.
TO GET TECHNICAL SUPPORT send an e-mail directly to
SUPPORT {at} amibroker.com
TO SUBMIT SUGGESTIONS please use FEEDBACK CENTER at
http://www.amibroker.com/feedback/
(submissions sent via other channels won't be considered)
For NEW RELEASE ANNOUNCEMENTS and other news always check DEVLOG:
http://www.amibroker.com/devlog/
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/amibroker/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/amibroker/join
(Yahoo! ID required)
<*> To change settings via email:
mailto:amibroker-digest@xxxxxxxxxxxxxxx
mailto:amibroker-fullfeatured@xxxxxxxxxxxxxxx
<*> To unsubscribe from this group, send an email to:
amibroker-unsubscribe@xxxxxxxxxxxxxxx
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|