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 -----
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@xxxxxxxxxps.com,
"Markus Witzler" <funnybiz@xx.>
wrote: > > Hello TJ et al., > > may I ask once
again? > > Thanks > > Markus > ----- Original
Message ----- > From: Markus Witzler > To: amibroker@xxxxxxxxxps.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@xxxxxxxxxps.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@xxxxxxxxxps.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); >
__._,_.___
**** 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/
__,_._,___
|