Questions about ApplyStop (Volatile)

Hello everyone and @Tomasz

I am trying to get a better understanding of how the Volatile option works in the ApplyStop() formula so I can experiment with new things. However, before I do I like to understand the ins-and-outs. It's better to understand a formula perfectly before moving on.

First, I tried matching up points and percent without volatile and with these two match the trade list is exactly the same.

#1ApplyStop(stopTypeProfit,stopModePercent,5,1,0);
#2ApplyStop(stopTypeProfit,stopModePoint,BuyPrice*0.05,1,0);

After that I tried using a "dummy" volatile to match the orders above... the idea is to keep the stop the same at execution price plus 5%... I know it's the same, just trying to understand the inner-works to build on that knowledge to improve my strategies.

#3ApplyStop(stopTypeProfit,stopModePoint,IIf(Ref(Buy,-1),Open*0.05,BuyPrice*0.05),1,1);
#4ApplyStop(stopTypeProfit,stopModePoint,IIf(Buy,Open*0.05,BuyPrice*0.05),1,1);

However #3 or #4 don't match with #1 and #2... would you be able to explain what I am doing wrong in this case? I would like to understand this exactly before I move on to more elaborate things with the Volatile option. Thank you for the help!

I also tried using ValueWhen() just in case... but again different that #1 #2 and #3 #4

This is the code :point_down:
I used QQQ from 1-1-2010 → 12-31-2023 for testing

SetOption("ActivateStopsImmediately",True);
SetOption("AllowSameBarExit",True);	

SetPositionSize(100,spsPercentOfEquity);

SetTradeDelays(1,1,1,1);

Short=Cover=False;

Buy=Cross(RSI(10),50);
BuyPrice=Open;

Sell=False;
SellPrice=False;

// uncomment below one at a time

//ApplyStop(stopTypeProfit,stopModePercent,5,1,0);
//ApplyStop(stopTypeProfit,stopModePoint,BuyPrice*0.05,1,0);
//ApplyStop(stopTypeProfit,stopModePoint,IIf(Ref(Buy,-1),Open*0.05,BuyPrice*0.05),1,True);
//ApplyStop(stopTypeProfit,stopModePoint,IIf(Buy,Open*0.05,BuyPrice*0.05),1,True);

//ApplyStop(stopTypeProfit,stopModePoint,IIf(Buy,Open*0.05,ValueWhen(Buy,Open*0.05)),1,1);
//ApplyStop(stopTypeProfit,stopModePoint,IIf(Ref(Buy,-1),Open*0.05,ValueWhen(Ref(Buy,-1),Open*0.05)),1,1);

The "volatile" means that stop amount is not constant and changes every bar.
Normally (without "volatile") the amount is sampled at entry and HELD for entire course of the trade.
With "volatile" the amount parameter is NOT sampled at the entry and NOT held. So with 'volatile', if you pass 0.05 * BuyPrice the amount IS NOT 5% of entry price.

It is 5% of whatever price array is used - in your case it is 5% of OPEN price (since you did assignment BuyPrice = Open) and it changes EVERY BAR to the value OF OPENING PRICE at given bar.

2 Likes

Thank you, this helps a lot. I want to understand exactly how Volatile works before I incorporate in my strategies.

So since with volatile the amount change bar-by-bar then if we need to look back to buy signal to keep it constant?

ApplyStop(stopTypeProfit,stopModePoint,ValueWhen(Ref(Buy,-1),Open*0.05),1,1);

With this, we look back at the bar where the signal was executed (next open) per trade delays and recalculate this amount with each new bar. Of course, it will stay the same.

However it still doesn't seem to match exactly and I don't seem to be able to pinpoint what might be causing the different trades with any of these:

//ApplyStop(stopTypeProfit,stopModePercent,5,1,0);
//ApplyStop(stopTypeProfit,stopModePoint,BuyPrice*0.05,1,0);

I used QQQ from 1-1-2010 → 12-31-2023 for testing

If you want to keep it constant -> don't use volatile mode.

It is that simple - if you want amount to be set at trade entry and KEPT throughout the trade set Volatile to False.

BuyPrice is INPUT array for AmIBroker, so you should WRITE to BuyPrice, not something that you use to "READ".

You SET BuyPrice and it is used by backtester.
If you do this:

BuyPrice = Open;

You inform AmiBroker to use OPEN PRICE as for buys.

Once you do the assignment BuyPrice simply EQUALS Open. Nothing more.
It does NOT become magically "sampled and held" for trade duration.

So this:

BuyPrice = Open;
ApplyStop(stopTypeProfit,stopModePoint,BuyPrice*0.05,1,0);

is TOTALLY THE SAME as:

ApplyStop(stopTypeProfit,stopModePoint,Open*0.05,1,0);
1 Like

You are probably getting another Buy signal while you're in the trade, which is why your stop amount changes when you set Volatile to True. An Exploration should easily confirm this.

2 Likes

Hi @Tomasz - thank you, all clear regarding volatile and BuyPrice but I still don't exactly understand why the following two return different trades:

ApplyStop(stopTypeProfit,stopModePoint,ValueWhen(Ref(Buy,-1),Open*0.05),1,1);
Volatile, so changes on a per-bar basis but in this case looks back to the execution bar and gets the open times 5% so it should match exactly with:

//ApplyStop(stopTypeProfit,stopModePercent,5,1,0);
Not volatile, so sampled at the Buy bar...

Hi @mradtke - yes, there are buy signals in between but unless I am completely off here I don't think they interfere. So on the chart below, I am comparing the two ApplyStop exits to the same buy signal.

When using ApplyStop(stopTypeProfit,stopModePercent,5,1,0); the code has us exit at $158.55 whereas where we use the volatile option above (#2) it has us exit at another bar that is very close in price to the exit #1. Any of the buy signals in between would has resulted in different stop prices.

Basically, I use Conditional orders (OTO) at lot with all my brokers and was trying to mimic this in AFL ApplyStop(). I know how to do this with loops but just test-driving ApplyStop().

Conditionals OTO are useful because it allows a stop or limit to be entered when the main trade is filled with estimated stops or targets and then adjusted later on.

How would one code for this situation exactly in AFL using ApplyStop() ?

Bar 0
RSI crosses above 50 - a buy signal is generated for execution next market at the Open

Bar 1
Buy signal executed at the Open

Bar 1
Limit placed at Close of Bar 0 x 1.05
We use the close of the previous bar because that is what is known at the close of price 0

Bar 2 onward
Adjust Limit to Open of Bar 1 x 1.05

Would this be a correct way of doing this or I am overcomplicating things here for nothing?

ApplyStop(stopTypeProfit,stopModePoint,IIf(Ref(Buy,-1),Ref(Close,-1)*0.05,ValueWhen(Ref(Buy,-1),Open*0.05)),1,1);

In your 2nd scenario, the most recent Buy signal before the stop occurs on 2018-01-02. The next day's Open is 158.527, and 5% of that is 7.92635. Add that to your actual entry price of 151.001 and you get 158.92735, which is the exact price that your stop exited the trade. So yes, the intervening Buy signals ARE affecting your stop price.

2 Likes

Oh I understand now... so the intervening buy signals change the array the ApplyStop() without resetting the cost basis. Clear. I misunderstood initially, my bad,

1 Like

I would give the advice to NOT use volatile. It can increase your risk, especially when you have multiple concurrent positions on. Also, you can't capture volatility expansion, that occurs when markets move. You could set a different variable that is volatile, to compare the current to that of the fixed position volatility, for stuff like margin requirement changes (Futures) etc. Just some thoughts.

I have explained it 2 times already:
ONLY when using Volatile = False, the amount is sampled at trade entry and held.

ValueWhen is NOT equivalent to this because ValueWhen does NOT know when trade ends and does not know whenever last "when" is during already existing trade or not.

Exactly this happens in your case:

I understand what you said about Volatile and @mradtke about the ValueWhen().

With that being said, how would you use apply stop to code for this:

First bar, exit at previous close * 1.05

Second bar onward and for duration of trade: actual buy price of trade * 1.05

Is this possible with ApplyStop() or should I resort to loops?

For first exit you don't need apply stop, since it is just normal (regular) exit executed the same bar if High > 1.05 * Ref( C, -1 ).

Second Stop is just ApplyStop without volatile but with ValidFrom argument set to 1.

Everything is covered in the Users Guide:

https://www.amibroker.com/guide/afl/applystop.html