Australian (ASX) Stock Market Forum

Amibroker FAQ

Does anyone know how to use the monte carlo analysis in AB?

I use the code shown below for Monte Carlo analysis. I usually set the monte carlo figure to 0.5. ie. there is a 50% chance I may miss this trade or I won't like the buy signal generated for whatever reason. You may set the figure lower if you were more confident about your system and your ability to place all the trades it produces. Regardless, a graph of CAR vs MaxSysDD (for example) should ideally show a tight spread of results, if it doesn't perhaps your system is not as robust as you first thought.

You can also go further. For example, export your optimized monte carlo run into excel and work out the standard deviation for various results, and work out various probabilities. eg. the average CAR of 1000 monte carlo runs is 30%, with a standard deviation of 5% (approx 70% of the runs lie in the 25% to 35% range), and I have a 90% chance of having a CAR > 20%.

I find this methodology to be beneficial in system testing / evaluation.

Mark

Code:
 runs = Param("# runs", 1000, 0, 10000, 500);
monteCarlo = Param("monteCarlo", 0, 0, 1.00, 0.01);
if(monteCarlo)
  Optimize("monteCarlo", 1, 1, runs, 1);

if(monteCarlo)
  Buy = Buy AND mtRandom() >= monteCarlo;
else
  Buy = Buy;
 
I use the code shown below for Monte Carlo analysis. I usually set the monte carlo figure to 0.5. ie. there is a 50% chance I may miss this trade or I won't like the buy signal generated for whatever reason. You may set the figure lower if you were more confident about your system and your ability to place all the trades it produces. Regardless, a graph of CAR vs MaxSysDD (for example) should ideally show a tight spread of results, if it doesn't perhaps your system is not as robust as you first thought.

Mark

Hi Mark --

If I interpret your post and your code correctly, you start with a fully determined trading system that has no random component. That is, if you run several backtests on it with the same parameters and same watchlist, you get the same trade list each time. You then use the Monte Carlo code to examine what would happen if a portion of the buy signals are randomly blocked.

Two responses come to my mind.

One is that when one of the original buy signals is blocked, the funds that would have been available for that position are in cash instead, at least for a short time. If the system is being run on a universe of potential tradables, using a watchlist rather than a single issue, then those funds are available to take a position in an issue that was not originally selected. If I think about it from a rotational trading point of view, it has the effect of passing on the highest ranked choice and selecting the second or third ranked choice. The result is a different system -- one arrived at using a random process -- tending toward throwing darts.

The other is that a different condition results if the system is being applied to a single issue. Some of the trades are not being taken and the funds remain in cash until the next Buy signal. (It may be that the next buy signal is one that would not have been available in the original buy array. That is, there might have been successive buys before the sell. Ignore this for the time being.) The more important issue is that the system is now taking only a portion of the trades. In the terminology of fixed fractional position sizing, it it trading a lower fraction, f. If the system was properly leveraged when the first runs were made, then it is undertrading with the randomly selected trades removed. Reducing f below optimal reduces drawdown linearly, but reduces profit geometrically.

Thanks for listening,
Howard
 
Hi Howard thanks for taking the time to respond. Your assumptions were all correct. Due to my inability to develop a system where I would happily and blindly enter all buy signals I still "eyeball" the signal on a chart. Perhaps it is just about to hit resistance etc, or some other condition that I am unable (or forgotten) to code for. That is my main motivation for "blocking buy signals" and generating a different / random trade list. The substitute trade still has to meet my original buy criteria so I have to assume that it will still be better than a random entry or "throwing darts". Speaking of which, I do test my systems with a random entry (thanks for the code from Q.T.S) to check the system robustness. I also maintain that it is your exits / risk management / position sizing that matters, not your entry.

I think you need to decide why you would do a form of monte carlo analysis, and what your expectations are. For my purposes, I believe my application to be an adequate representation of potential real world results, as I do get to see the effect of missing big trades, or the best case for this system.

Mark
 
Does anyone know how, if its possible, to get the difference between the high and low from the trading day and export it with Ami? Or at least just get it somehow rather than going through each day manually? or know where I could get something of the sort? :)

Cheers
 
Hi Sam --

See if this is what you want --

// ExportRange.afl
Filter = 1;
Range = H - L;
AddColumn(Range, "Range", 10.2);
// End of afl program

Here is how to use it -----------------
Select the category of symbols you want to check -- a watchlist, for example.
Select the date range you want to check -- n last days = 1, for example
Click Explore
The results will be displayed in the results window.
Click File > Export, select the output file name and path.

The output file is a csv file with three columns -- Ticker, Date, Range.

Hope this helps,
Howard
 
Hi Sam --

See if this is what you want --

// ExportRange.afl
Filter = 1;
Range = H - L;
AddColumn(Range, "Range", 10.2);
// End of afl program

Here is how to use it -----------------
Select the category of symbols you want to check -- a watchlist, for example.
Select the date range you want to check -- n last days = 1, for example
Click Explore
The results will be displayed in the results window.
Click File > Export, select the output file name and path.

The output file is a csv file with three columns -- Ticker, Date, Range.

Hope this helps,
Howard

Thats it! Perfect :) Thanks heaps Howard!! :)

Actually, on 2nd thoughts Howard, I think its including the overnight session as well? Is it possible to make it from 9:20am till 4pm?

Cheers!
 
Hi Sam --

You can export anything you have data for. Assuming you have the data in your database, assign the values you want exported to variables, then use the same procedure I described.

In other words -- the question you asked most recently is more about the database than the export.

Thanks,
Howard
 
Hi All

I would now like to throw in the following to my existing formula to my reversal day:

To only go long when EMA 4 is above EMA 9 (we'll call this 'x') and 'x' must be above the EMA 18

The opposite for a short, to only go short when EMA 9 above EMA 4 (we'll call this 'y') and 'y' must be below the EMA 18

(2 attachments to show you what i am trying to achieve. I just want to go be in the position the following day and that is all. Buy at open, sell at close or short at open and cover at close. No stops at this stage.

THIS IS THE FORMULA I HAVE SO FAR, but i am stuck on how i would add the EMA crossovers to it





gapclosingfromupope n =Open > Ref(H,-1) AND C > Ref(L,-1) AND C < Ref(H,-1);

gapclosingfromdowno pen=Open < Ref(L,-1) AND C > Ref(L,-1) AND C < Ref(H,-1);

Color= IIf(gapclosingfromupop en,colorYellow,IIf(gapclosingfromdown open,colorRed,ParamColor("color",colorBlack)));

_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", color , styleNoTitle | ParamStyle("Style") | GetPriceStyle() );

_SECTION_END();



Filter= gapclosingfromupope n OR gapclosingfromdowno pen;

AddColumn(C,"");

AddColumn(gapclosingfromupop en,"up");

AddColumn(gapclosingfromdown Open,"down");



AND

Buy = ( EMA( Close , 4 ) > EMA( Close , 9 ) ) > EMA( Close , 18 ) > Close




Assitance would be great
 

Attachments

  • LONG Example.gif
    LONG Example.gif
    27.7 KB · Views: 3
  • SHORT Example.gif
    SHORT Example.gif
    23.3 KB · Views: 95
To only go long when EMA 4 is above EMA 9 (we'll call this 'x') and 'x' must be above the EMA 18

Buy = ( EMA( Close , 4 ) > EMA( Close , 9 ) ) > EMA( Close , 18 ) > Close

ST,
The EMA crossover conditions that you specified does not make sense.
As an example, the condition that you call 'x', EMA( Close , 4 ) > EMA( Close , 9 ) is OK and will return a boolean result, ie a 1 for true or 0 for false. With only 2 possible results for x, it does not make sense to then have a condition that says x > EMA( Close , 18 ).

Unfortunately the charts that you attached is not sufficiently clear (well for me anyway) on how these crossovers work. Happy to help but you'll need to get it clearer in your mind as to precisely you want
 
ST,
The EMA crossover conditions that you specified does not make sense.
As an example, the condition that you call 'x', EMA( Close , 4 ) > EMA( Close , 9 ) is OK and will return a boolean result, ie a 1 for true or 0 for false. With only 2 possible results for x, it does not make sense to then have a condition that says x > EMA( Close , 18 ).

Unfortunately the charts that you attached is not sufficiently clear (well for me anyway) on how these crossovers work. Happy to help but you'll need to get it clearer in your mind as to precisely you want

Hi Bingk6

Its not really the crossover i want to be entering in at or exiting out at.

Its a system where i hold stocks for one day, and i hold nothing overnight. There are no stops at this stage. All i am merely looking at doing is entering a long position (buy on open, sell at close) or a short position (short-sell on open and cover at close).

In the first chart, for example, I would be entering (and exiting) the day after the bar which has been highlighted in green. The significance of the green bar is that it gaps down on open, yet goes back into the previous day's trading range, thereby signalling a potential reversal day. So i would enter on open the very next day.

The exact opposite for a short. Look at second chart.

Now I already have this formula which i have included and it seems to be working fine. But i would like to add some strength to this set up. In this case, only entering a long position if the market is in a definitive up trend.

My definition of uptrend is when EMA 4 (green line) > EMA 9 (red line), but both of these need to be above the EMA 18 (black line, which is the main trend line). If this is occurring, as per example, then safe to enter the long position the next day.

The opposite holds true for a short trade.

I hope this is much clearer.

ST
 
OK, try this

Code:
settradedelays( 1, 1, 1, 1 );
gapclosingfromupopen =Open > Ref(H,-1) AND C > Ref(L,-1) AND C < Ref(H,-1);
gapclosingfromdownopen=Open < Ref(L,-1) AND C > Ref(L,-1) AND C < Ref(H,-1);

Buy =   EMA(  Close , 4 ) > EMA(  Close , 9 )  and  EMA(  Close , 9 ) > EMA(  Close , 18 ) and gapclosingfromdownopen;
buyprice = O;
Sell = buy;
sellprice = C;
Short =   EMA(  Close , 4 ) < EMA(  Close , 9 )  and  EMA(  Close , 9 ) < EMA(  Close , 18 ) and gapclosingfromupopen;
Shortprice = O;
Cover = short;
Shortprice = C;
 
From the AFL reference manual:

graphxspace defines percentage extra space added at the top and the bottom of the chart
Example:

graphxspace=5; //this adds 5% extra space to top and bottom of the chart.
 
You may wish to make it adjustable via the parameters box.

Code:
zoom=Param("zoom",5,5,50,5);
GraphXSpace=zoom;
Insert into your indicator formula, open the parameters box and adjust as required.
 
say i run backtest, and on any given month, the scanner generates 4 ASX stocks, is there something in the Settings menu that will allow me to take all of those trades? instead of just the one - which the backtest seems to be doing. Specifically, it defaults to taking the first one in the list generated

The reason I ask is that when I generated a trade list i noticed there was quite a large number of ASX stocks starting with the letter A. Out of 1,200 odd trades over the 10 year period, about 500 were starting with A.

I found this to be a little peculiar.

Anyway, upon looking further into this, I realized that if the scanner generated say 4 ASX stocks to go long on then it would pick the first one:

ie.

ALL
BHP
NAB (lets say NAB has the best set up)
WOW

The system would pick ALL, becuase its first on list. And if in the next month the same list was generated only this time, there was no ALL, then BHP would be picked. And so on.

Thanks for your help on this
 
The number of trades taken is dependent upon how you set the "PositionSize" function.

eg.
pq =10;
PosQty = pq;
PositionSize = -100 / posqty;

This will allow 10 positions with 10% of equity invested in each. (brokerage may affect this).

Amibroker will take trades alphabetically unless you assign something to "PostionScore".

The portfolio backtesting tutorial explains both functions in depth.

http://www.amibroker.com/guide/h_portfolio.html
 
Excellent , i was playing around with that and it all seems to work fine

What about this scenario:

Say i was happy with 10 positions and risking 10% each time. And lets say my scanner generates 10 signals on average, but there are some days it only generates 4 (or 2, or 7 or as high as 15).

Lets use 4 as an example. On those days is it possible to now take those 4 positions but instead of them representing 40% of equity, (60% idle), can i have it so that they each represent 25% of equity so that 100% is invested the whole time?

And if it were to jump 20 signals a few days later, then the system would take them all thereby investing 5% of equity in each case?

Thanks again
 
You may wish to make it adjustable via the parameters box.

Code:
zoom=Param("zoom",5,5,50,5);
GraphXSpace=zoom;
Insert into your indicator formula, open the parameters box and adjust as required.

Cheers mate. No wonder I could never find it in the AFL reference.
 
Top