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);
>