Australian (ASX) Stock Market Forum

Amibroker FAQ

I am trying to learn AmiBroker AFL. I have code from an indicator that I am trying to understand.

See my comments that begin with "//"

Please check my interpretation for each line of code.

I am lost on the 5th line of code.

// Set the variable "BarColor" equal to Color (Is "Color a variable also?)
BarColor = Color;

// Set the variable "Range" equal to the current bar's High minus the current bar's Low
Range = High - Low;

// Set the variable "Value1" equal to the current bar's Volume
Value1 = Volume;

// Set the variable "Value2" equal to the current bar's Volume multiplied by the current bar's calculated Range
Value2 = Volume * Range;

// Here is the line of code that I need help interpreting
Value3 = IIf(Range < Ref(Range, -1) OR Range > Ref(Range, -1), V, IIf(Range == Ref(Range, -1), V / Range , 0));

Thank you...

Don
 
Hi Don --

From the AmiBroker User's Guide:
----------------
IIF
- immediate IF function Trading system toolbox



SYNTAX iif( EXPRESSION, TRUE_PART, FALSE_PART )


RETURNS ARRAY


FUNCTION "Immediate-IF" - a conditional function that returns the value of the second parameter (TRUE_PART) if the conditional expression defined by the first parameter (EXPRESSION) is true; otherwise, the value of third parameter is returned (FALSE_PART). Please note that IIF is a function - so the result of evaluation is returned by that function and should be assigned to some variable. IIf always evaluates both TRUE_PART and FALSE_PART, even though it returns only one of them. Because of this, you should watch for undesirable side effects. The following example shows one common error made with IIF function: IIF( condition, result = 7, result = 9 ); // THIS IS WRONG Correct usage is: result = IIF( condition, 7, 9 ); /* 7 or 9 is *returned* and assigned to a variable depending on condition */


EXAMPLE The formula result = iif( macd()<signal(), Volume, -Volume) will assign positive volume values to the result variable on days when macd was below its signal line, and negative volume values on theother days.

---------------------

The line of code you are asking about has IIF nested within IIF.

----------
Value3 = IIf(Range < Ref(Range, -1) OR Range > Ref(Range, -1), V, IIf(Range == Ref(Range, -1), V / Range , 0));
-----------

The statement is computing some value that will be assigned to variable Value3. This is an array function. It accepts arrays as inputs and returns an array as output.

It is easy to confuse the Function IIF with the Control Statement IF. Read up on both.

The sequence AmiBroker takes is to make the tests in order.

If Range < Range one bar ago, use V. (The remainder of the statement is executed, but no matter what the result is, V will be used for the assignment.)

If not, make the test that is in the false_part.
If Range is exactly equal to Range one bar ago, use V / Range
If not, use 0

Assign whichever value is to be used to variable Value3.

-----------------------

The code in line 5 makes little sense to me. After execution of line 5, Value3 will have one of three values:
V, V / Range, or 0.
These three do not even have the same dimension, so the code is immediately suspect.

Thanks,
Howard
 
Hello

Im trying to find out if I am able to set 2 different sell conditions so that 50% will sell at a close below the trail and 50% will sell at a close below the 50 EMA. Can someone tell me if this is possible and maybe tell me what has to be done. Ive hunted around and I havent seen any existing formula that has 2 exits.

Thanks :)

The formula is



_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorBlack ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );

//Bull Bear Trail
function vstop_func(trBull,trBear)
{
trailArray[0]=C[0]; // initialize
for( i=1;i<BarCount; i++ )
{
prev=trailArray[i-1];
if(C>prev AND C[i-1]>prev)
{
trailArray=Max(prev,C-trBull);
}
else if (C<prev AND C[i-1]<prev)
{
trailArray=Min(prev,C+trBear);
}
else if (C>prev)
{
trailArray=C-trBull;
}
else
{
trailArray=C+trBear;
}
}
return trailArray;
}

per=Param("per",20,1,150,1);
multBull=Optimize("multBull",2.5,1,7,0.05);
multBear=Optimize("multBear",2.5,1,7,0.05);



trBull=multBull*ATR(per);
trBear=multBear*ATR(per);

trailArray=vstop_func(trBull,trBear);
bullTrail=IIf(trailArray<C,trailArray,Null);
bearTrail=IIf(trailArray>C,trailArray,Null);
Buy=C>trailArray ;BuyPrice=C;



Sell=Cross(trailArray,C);SellPrice=C;
Buy=ExRem(Buy,Sell);
Sell=ExRem(Sell,Buy);


GraphXSpace=5;


Plot(bearTrail,"\ntrailShort",ParamColor("ColorTrailShort",ColorRGB(255,0,0)),styleStaircase);
Plot(bullTrail,"\ntrailLong",ParamColor("ColorTrailLong",ColorRGB(0,255,0)),styleStaircase);
PlotShapes(IIf(Buy,shapeUpArrow,shapeNone),colorDarkGreen,0,L,-15);

PlotShapes(IIf(Sell,shapeDownArrow,shapeNone),colorRed,0,H,-15);
 
Hi Art27 --

Read up on sigScaleIn and sigScaleOut in the AmiBroker User's Guide. There is an explanation and some examples.

Thanks,
Howard
 
Im still having trouble with this formula. Can someone please tell me what I have wrong. I intend to trade this on a weekly timeframe. The trigger bar to buy is a close above the Buystop trail. The entry is made on the following weeks open.
The trigger bar to sell is a close below the trailstop. The exit is made on the following weeks open.

When I backtest the formula on a weekly setting between 1/3/09 and 10/11/11 I get the following longs.
27/3/09 3408.10
18/6/10 4516.80
01/4/11 4832.60
15/07/11 4703.90
09/09/11 4302.10

What I cant work out is these dates dont coincide with the buy arrows on the chart and some buy signals on the chart dont even appear in the backtest results.

On the chart the AORD closed above the Buystop trail on week ending 20/3/09 so a buy would be on open the following week - the week of 27/3/09 yet the buy arrow is pointing at 20/3/09.

The next buy arrow on the chart is on the week 5/3/10 yet the back test said the next buy was 18/6/10 This seems to coincide with the third buy arrow. The AORD closed above the BuyStop trail on week 11/6/10 so a buy is the following weeks open on 18/6/10. Somehow the buy arrow is pointing at 11/6/10.


WHAT IS HAPPENING HERE :banghead:

If someone can please help me I would really appreciate it.


Thank you

The formula is

------------------------------------------------------------------------



function vstop_func(trSell,trBuy)
{
trailArray[0]=C[0]; // initialize
for( i=1;i<BarCount; i++ )
{
prev=trailArray[i-1];
if(C>prev AND C[i-1]>prev)
{
trailArray=Max(prev,C-trSell);
}
else if (C<prev AND C[i-1]<prev)
{
trailArray=Min(prev,C+trBuy);
}
else if (C>prev)
{
trailArray=C-trSell;
}
else
{
trailArray=C+trBuy;
}
}
return trailArray;
}

per=Param("per",10,1,20,1);
multSell=Optimize("Trail Stop Value",2.5,1,7,0.05);
multBuy=Optimize("Buy Stop Value",1,1,3,0.05);


trSell=multSell*ATR(per);
trBuy=multBuy*ATR(per);

trailArray=vstop_func(trSell,trBuy);
TrailStop=IIf(trailArray<C,trailArray,Null);
BuyStop=IIf(trailArray>C,trailArray,Null);

SetTradeDelays( 1, 1, 1, 1 ); /* delay entry/exit by one bar */
Buy=Cross(Close,trailArray) ; BuyPrice=Open;
Sell=Cross(trailArray,C); SellPrice=Open;



GraphXSpace=5;


Plot(BuyStop,"BuyStop",colorDarkGreen,styleStaircase);
Plot(TrailStop,"TrailStop",colorRed,styleStaircase);
PlotShapes(IIf(Buy,shapeUpArrow,shapeNone),colorDarkGreen,0,L,-15);

PlotShapes(IIf(Sell,shapeDownArrow,shapeNone),colorRed,0,H,-15);

BuySell.png
 

Attachments

  • BuySell.png
    BuySell.png
    92.8 KB · Views: 0
The Buy arrows appear on the bar the signal is generated on. Because you have TradeDelays set to 1 the backtester will not show the buy as having been made until the next week.

I can see no reason for the backtester skipping trades. Check your equity and other parameters in the settings dialog box.
 
Thanks elbee.

I will try that. I think I have worked out what is happening when arrows appear on the chart but not the backtester. It must be something to do with how amibroker saves the formula because if I right click on the chart and save the formula as a different name then close the program and reopen it. If I then open the formula that I just saved everything is ok. Ive also noticed this happening in parameters sometimes. Deleted param files still show in parameters. Weird.
 
Hi Don --

The line of code you are asking about has IIF nested within IIF.

----------
Value3 = IIf(Range < Ref(Range, -1) OR Range > Ref(Range, -1), V, IIf(Range == Ref(Range, -1), V / Range , 0));
-----------

The statement is computing some value that will be assigned to variable Value3. This is an array function. It accepts arrays as inputs and returns an array as output.

It is easy to confuse the Function IIF with the Control Statement IF. Read up on both.

The sequence AmiBroker takes is to make the tests in order.

If Range < Range one bar ago, use V. (The remainder of the statement is executed, but no matter what the result is, V will be used for the assignment.)

If not, make the test that is in the false_part.
If Range is exactly equal to Range one bar ago, use V / Range
If not, use 0

Assign whichever value is to be used to variable Value3.

-----------------------

The code in line 5 makes little sense to me. After execution of line 5, Value3 will have one of three values:
V, V / Range, or 0.
These three do not even have the same dimension, so the code is immediately suspect.

Thanks,
Howard

Thank you for your response Howard. I have both of your books and it is a privlige to coorespond with you.

I agree that the way this line is written the result will always be the left (1st True) condition, which in this case is volume. So Value3 always = Volume.

Could it be that the right side {IIf(range == Ref(range, -1), V /Range , 0));} could be meant as a "unless" statement. In other words: Value3 will equal Volume "unless" today's range and yesterday's range are exactly the same. Then we divide volume by range (just spitballing here).

A little context: I am working with a piece of code that is attempting to replicate the Better Volume Indicator.

Value3 appears to be used for testing for a low churn bar.

Here is the code:
Code:
SetChartBkColor( ParamColor("Chart Back Color",colorBlack));
Color=(colorGrey50); //=(colorAqua)== BarColor(Cyan)
LowColor=(colorYellow);
ClimaxColor=(colorRed);
ChurnColor=(colorGreen);
ClimaxChurnColor=(colorCustom12);
LowChurnColor=(colorWhite);
//AvgColor(Red);
//Variables: BarColor(Cyan);

// Set the variable "BarColor" equal to Color (Is "Color a variable also?)
BarColor = Color;

// Set the variable "Range" equal to the current bar's High minus the current bar's Low
Range = High - Low;

// Set the variable "Value1" equal to the current bar's Volume
Value1 = Volume;

// Set the variable "Value2" equal to the current bar's Volume multiplied by the the current bar's calculated Range
Value2 = Volume * Range;

/* Here is the line of code that I need help interpretting
Value3 = IIf(Range < Ref(Range, -1) OR Range > Ref(Range, -1), V, IIf(Range == Ref(Range, -1), V / Range , 0));

Plot(Value3,"Volume, Volume/Range, or Zero",colorWhite);
Plot(Range,"Range",colorGreen);
Plot(Volume / Range,"Volume/Range",colorRed);

// if Range <> 0 then Value3 = V/Range;

// Set the variable "Value4" equal to the 30-day moving average of Value1
Value4 = MA(Value1,30);

Color12=
// LowColor = Yellow
IIf (Value1 == LLV(Value1,20), LowColor,
// ClimaxColor = Red
IIf (Value2 == HHV(Value2,20), ClimaxColor,
// ChurnColor = Green
IIf (Value3 == HHV(Value3,20), ChurnColor,
// ClimaxChurnColor = Custom12
IIf (Value2 == HHV(Value2,20) AND Value3 == HHV(Value3,20), ClimaxChurnColor,
// LowChurnColor = White
IIf (Value3 == LLV(Value3,20) ,LowChurnColor,Color)))));

Plot(Value1,"Volume",Color12,2+4);
Plot(Value4,"Avg",colorYellow);
_SECTION_END();

Thank you...
 
Hi

I have noticed in the backtest results that when prices crosses below my trailstop the sellprice is the close because I have written

Buy=Cross(Close,trailArray) ; BuyPrice=C;
Sell=Cross(trailArray,Low) ; SellPrice = C;

Could someone please tell me what I have to write to have "sellprice= the price when the intraday low crosses the trailing stop level" so that when I backtest the sell price is my trailstop level?


Thanks

The formula is

function vstop_func(trSell,trBuy)
{
trailArray[0]=C[0]; // initialize
for( i=1;i<BarCount; i++ )
{
prev=trailArray[i-1];
if(C>prev AND C[i-1]>prev)
{
trailArray=Max(prev,C-trSell);
}
else if (C<prev AND C[i-1]<prev)
{
trailArray=Min(prev,C+trBuy);
}
else if (C>prev)
{
trailArray=C-trSell;
}
else
{
trailArray=C+trBuy;
}
}
return trailArray;
}

per=Param("per",10,1,20,1);
multSell=Optimize("Trail Stop Value",2,1,7,0.05);
multBuy=Param("Buy Stop Value",2,1,3,0.05);


trSell=multSell*ATR(per);
trBuy=multBuy*ATR(per);

trailArray=vstop_func(trSell,trBuy);
TrailStop=IIf(trailArray<C,trailArray,Null);
BuyStop=IIf(trailArray>C,trailArray,Null);

Buy=Cross(C,trailarray) ;BuyPrice=C;
Sell=Cross(trailArray,C);SellPrice=C;

Buy=ExRem(Buy,Sell);
Sell=ExRem(Sell,Buy);
 
Hi

I have noticed in the backtest results that when prices crosses below my trailstop the sellprice is the close because I have written

Buy=Cross(Close,trailArray) ; BuyPrice=C;
Sell=Cross(trailArray,Low) ; SellPrice = C;

Could someone please tell me what I have to write to have "sellprice= the price when the intraday low crosses the trailing stop level" so that when I backtest the sell price is my trailstop level?
Well on daily quotes you only have the Open, High, Low and Close prices to work with. Your "intraday low crosses the trailing stop level" price is known only to you after it has happened so you could sell on the close that day or the open following day if EOD trading.
 
Fixed it rnr

Thanks heaps

Sell=Cross(trailArray,C);SellPrice=Ref(trailArray,-1);

My appologies as I should have spent a bit more time reviewing your initial question and code before posting a response.

art27 said:
I have noticed in the backtest results that when prices crosses below my trailstop the sellprice is the close because I have written

Buy=Cross(Close,trailArray) ; BuyPrice=C;
Sell=Cross(trailArray,Low) ; SellPrice = C;

Could someone please tell me what I have to write to have "sellprice= the price when the intraday low crosses the trailing stop level" so that when I backtest the sell price is my trailstop level?


Therefore code should be

Sell=Cross(Ref(trailArray,-1),Low) ; SellPrice = Ref(trailArray,-1);

Your code for "Buy" is using forward referencing.
One example of an alternative is

Buy=Ref(Cross(Close,trailArray),-1) ; BuyPrice=O;
 
Hi Art --


You wrote ---

Could someone please tell me what I have to write to have "sellprice= the price when the intraday low crosses the trailing stop level" so that when I backtest the sell price is my trailstop level?

----

Your question is fairly easy. At the end of today, calculate the price at which the trailing stop will be activated in tomorrow's trading.

Your backtest code will look something like this:

TrailingStopPrice = xxx;
Sell = L<Ref(TrailingStopPrice,-1);
SellPrice = Ref(TrailingStopPrice,-1);

And the corresponding live trading order look something like this:
Sell 100 shares of xyz to Close at (whatever the trailingstop price that was calculated last evening is), stop, day order.

-------------

If you want to exit using more complex calculations, the backtest is handled as described above. The price at which the live order will be placed is a little trickier.

The price at which almost anything will happen can be determined, even if you do not know the formula to compute it directly. The only restriction is that there must be only one price at which this can happen.

I explain in more detail, including AmiBroker code, in Chapter 13, Anticipating Signals, of "Quantitative Trading Systems."

Thanks,
Howard
 
I'm trying to set up a manual EMA.

The first bar of data for the EMA is just a simple average of the first x bars.

After that the EMA relies on the EMA for the previous day.

I'd like to know how to identify the first day of data, to calculate the initial average.
And i've got no idea how to reference the previous days EMA.

Cheers
 
Top