Category Archives: Amibroker

Quiz System

Here’s the  Equity curve:

And here’s the code:


What’s happening here?

This is a variation of Jay Kaeppel’s post at optionetics but using some extra ETFs that have exhibited the same kind of behavior. Original article:

It buys equal amounts of each of these 6 etfs: WOOD,GDX,EPU,IDX,PALL,JJG.
It buys on the close of the U.S.session, holds overnight and sells on the open the next day.

That’s it.

Would you invest in this strategy

Backtest Multiple Strategies

If you are serious about trading and/or investing and are willing to commit a good amount of your net worth, you may choose not to follow just one strategy. You may be better off splitting your capital amongst not just different asset classes or stocks or etfs but also different strategies that trade those assets.

How can we simulate this?

One way is not to. You can develop good strategies independent of one another and invest in them as you see fit.
The other way is to simulate a multi-asset, multi-strategy portfolio as a whole.

You can think of a strategy as a time-series. SPY is a time-series. So is GLD, so is IBM. Just a sequence of numbers. So a strategy is it’s equity curve, an artificially made time series. You can invest in one or in multiple ones, just as if they were “assets” also.
20 years ago we should have diversified in different asset classes, now we may have to diversify in different strategies, as well.

So how can you do that? What tools to use?
There are many choices. I will briefly go through the ones I have tried. Others exists that might be better but I haven’t tried myself (NinjaTrader, TradingBlox, etc.)


As you know I am a big fan of Amibroker. It is not an obvious choice for backtesting a multi-asset, multi-strategy portfolio. But as usual there’s many ways to do things in AB. The obvious choice is to backtest each strategy and export the individual equities. Then trade those equity curves as buy & hold. The downside is that it takes two steps to do this. The upside is that you can write a new script and develop rules or allocation schemes on when and how much to trade in each strategy. Another choice is to program multiple strategies in one afl script, so that both available funds as well as compound profits are taken into consideration.
This  can be done, with some limitations. If someone is interested, I can do a post with the afl code and logic.

The more I work with this software, the more I like it.
In QuantShare, you first develop individual strategies. Each can trade it’s own specific basket of assets.  You can then combine strategies by using the combine-trading-systems plug-in.
 It asks you to choose which strategies to test, then combines them and returns stats and equity curves. By listing the stats of all the possible combinations, you can quickly see which combinations of strategies are better without going through a correlation analysis.
Another way to backtest multiple strategies is to write a MoneyManagment script. Using such a script (in C# or JScript) you can control multiple “categories” that have their own rules.
In the next post I will go briefly through an adaptive multi-strategy script.


I downloaded a 30-day trial and so far I am very impressed, especially with the ease it communicates with Interactive Brokers (as well as many other brokers and feeds) and the potential to run ATS (automated trading strategies) with many different brokers. I was able to set up a simple ATS system in less than 10 minutes and run it. This is definitively a contender when it comes to intra-day ATS systems.
That said, MultiChart can also backtest multi-strategy,multi-assets portfolios.


Now, this is a very interesting piece of software.
a. You can perform multi-asset, multi-strategy backtesting by using “Accounts”. Each Portfolio has one or more accounts. Each account has each own instrument list, strategy, money managment script, as well as commissions and broker connection (for autotrading).
b. You can have a Master money managment script that “sees” all accounts under the portfolio and reallocates funds according to set rules.
c. You can have a Master risk-controlling script that “sees” all accounts and ,for example, rejects positions if different strategies tend to buy the same one stock. You can automate all this, not just backtest. As an exampe: Let’s say you have two brokers: Interactive Brokers and MB Trading. Under Portfolio I can create two Accounts: InteractiveBrokers_1 and MBTrading_1. Both can be auto-traded from IQ.  So even if you are a bit paranoid and don’t trust your broker,  you can execute through them only half your strategy! 🙂
e.IQBroker uses C# and allows you to import dll references.
f. It’s currently free for individuals.
So, what’s the downside?
A bit of a steep learning curve and no support (unless you pay).

Amibroker – From Backtest to Trading – Going Live

Going Into Production 

So you have a system in Amibroker that you backtested and you are happy with. You now want to go “into production”.
How do you get your signals? How do you keep track of open orders, position sizes, ranking rules, etc. It’s not as easy as it may seem.

Explore or Scan?

If you try to run scans or explorations you will get Buy/Sell signals but how many? If you have 500 symbols and you trade the top 10 and your size varies with each stock’s ATR, you will have to rank the first 10 and compute, atr’s and position sizes and bla..bla..bla.. Do that day in day out… You will make a mistake.

Just Backtest!

In every Backtested system there are assumptions. Position Sizing, Ranking rules, skipping signals or not, etc. One way to keep track of all those things is to let Amibroker do it for you.

The following example assumes 
a. You use no stops
b You trade End Of Day at tommorow’s open or tommorow’s close.

Here are the steps.
1. Go to Amibroker and backtest your formula as usual. Check everything is ok, Commisions, Initial Equity, etc… Check that your backtested equity curve is what it should be.

2.Open the Backtester Setting.

3. In the Portfolio Tab, check the “Add artificial future bar” box.

** If you are trading ETF’s you might want to set “Limit trade size as % of entry bar volume” to 0.

4. Under Report select “Detailed  Log”.

5. From to Dates: Start today or a month ago depending on wether you are starting from 0 or synching with the current state of your system** (i.e. it is a long term system that holds Gold for 3 years now).
End day can be sometime in the far future: 1/1/2020

6. Check your margin if you are trading stocks. Max should be 50 (i.e.2x leverage) or higher if your broker allows for that. If you want no leverage set it to 100.

6a. Run the backtest. You should see a list. The last item should be for tommorow’s trade.

Here you have the orders ready for you to follow. The Position sizing rules and ranking are done for you. All you have to do is synch to the system (the first time) and then follow it every day (or week or month depending on your system).

Automating it

7. Save the .apx file that incorporates all your setting.
While the Analysis Window is selected and you are happy with all the settings go to Amibroker menu, and select File—>Save As.  A window will ask you where to save the file. Choose the folder where your AFL system formula is (or any other folder you want). Give it a name (My_System_1_Live) and save it as .apx, the default. Now you should have a My_System_1_Live.apx file that is all you need to backtest this strategy.

8. Write a Jscript.
a. Create a new NotePad test document
b. Paste this code and save it not as txt but as .js. Replace the file locations with your own.

//——-Code adapted form Thomaz’s code

var WshShell= new ActiveXObject(“Wscript.Shell”);
AB = new ActiveXObject( “Broker.Application” ); // creates AmiBroker object
// opens previously saved analysis project file
    NewA = AB.AnalysisDocs.Open(“C:Program FilesAmiBrokerFormulasMy_System_1_Live.apx ” );
    // NewA represents the instance of New Analysis document/window
    if ( NewA )
         NewA.Run( 2 ); // start backtest asynchronously
         while ( NewA.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second
        NewA.Export( “C:UsersUserMeDesktopLiveSystemsMy_System_1_Live .csv” );
         NewA.Close(); // close new Analysis
     WshShell.Popup (“NewA problem”, 3,”Active X problem”,0);
catch ( err )

   //Email_Event(” failed to run”,”Exception: ” + err.message);
     WshShell.Popup (“Active X problem”+”Exception: ” + err.message, 3,”Active X problem”,0);
//end code

For example save it as “Run_Backtest_Sys_1.js
Saving it as a “.js” make it an executable JScript under windows.

9. Double clicking on it will run run it. It will launch Amibroker, open the .apx file you specified, backtest your system and export a report at the location you also specify.

10. Open the .csv file. You should see the backtester’s results. The last lines should be tommorow’s trades.

11. (Oprional) Parse the .csv file.
If you are good at jScript or VBscript you can write a script that will go to tommorow’s entries and parse them into arrays. You can then export clean csv’s or e-mail yourself the signals or drive a virtual system at Collective 2 or email your broker.

What about Stops?  
Using the Custom Backtester Object.

There’s many ways to do teh same thing. Here’s teh code for retrieving tommorow’s trades (and stops or other variables) using Amibroker’s Custom Backtester.

//-One way to get tommorow’s signals – 
//Make sure “Add artificial bar for tommorow”, under Backtest Settings–>Portfolio Tab is checked to //get tommorow’s trade
///////////////Put your system HERE/////////////////////
/////////////////////End System ///////////////////

////////////Variable that you need to report/////////////
StaticVarSet(Name()+”SL”,(stoploss));//place the stoploss inside a staticvar array. Include Name!

////////////////////////////Code for custom report///////////
//Make sure “Add artificial bar for tommorow”, under Backtest Settings–>Portfolio Tab is checked to //get tommorow’s trade
idx = BarIndex();
d = Day();
m = Month();
y = Year();

SetCustomBacktestProc( “” );
if ( Status( “action” ) == actionPortfolio )
    bo = GetBacktesterObject();
    for ( bar = 0; bar < BarCount; bar++ )
        bo.ProcessTradeSignals( bar );
        CurEquity = bo.Equity;
//if bar is the last bar on the chart set Date
     if(bar==BarCount-1)  Datestr= “n” + “n” + d[bar] + “/” + m[bar] + “/” + y[bar] ;

        for ( openpos = bo.GetFirstOpenPos(); openpos; openpos = bo.GetNextOpenPos() )
SL=LastValue(Nz(StaticVarGet(Openpos.Symbol()+”SL”))); // Get the stop loss from the static array
if(Openpos.IsLong()) action=”Buy”; else action=”Sell”;

              if(bar==BarCount-1)  //only continue if we are at the last bar (i.e tommorow’s trade)
report= action+”  “+Openpos.Symbol()+ ”  “+ openpos.Shares()+” shares”+” Set Stop Loss @: “+ SL+”n” ;

PopupWindow(datestr+” n “+report,”Your Trades”,10);
Say(report+” and please remember to enjoy the rest of your day”, purge = True) ;
//AlertIf( True, “EMAIL”, datestr+” n “+report, 1 );


    bo.PostProcess(); // Finalize backtester

Uncover Hidden Market Relationships Using Fuzzy Logic

In the previous posts (pt1, pt.2,  pt.3) we talked a bit about how to take various indicators and fuzzify them.

Now I will show how we can quickly test for relationships in indicators.
So the question is: Can we only use RSI(3) and RSI(14) (short term and medium term Relative Strength Index) to trade the S&P500?
So in the Fuzzy Model afl script that I wrote, we input rsi3 and rsi14 as inputs and “Low,Neutral,High” as qualifiers.

We then let it optimize using the  CM-AES non-exhaustive optimizer (with all default settings). After a couple of minutes we get the results:

So the rules that the optimizer came up with are:

rule   0   rsi3  Low  AND  rsi14   Low  Then  SELL
rule   1   rsi3  Low  AND  rsi14   Neutral  Then  Do NOTHING
rule   2   rsi3  Low  AND  rsi14   High  Then  BUY
rule   3   rsi3  Neutral  AND  rsi14   Low  Then  Do NOTHING
rule   4   rsi3  Neutral  AND  rsi14   Neutral  Then  BUY
rule   5   rsi3  Neutral  AND  rsi14   High  Then  Do NOTHING
rule   6   rsi3  High  AND  rsi14   Low  Then  Do NOTHING
rule   7   rsi3  High  AND  rsi14   Neutral  Then  SELL
rule   8   rsi3  High  AND  rsi14   High  Then  SELL

Do these make sense? Unlike Neural Networks, these rules can be read and checked by common sense. What the above rules tell us is that:

Rule 2:
Buy when rsi14 is high (meaning we are in a mid-term bullish move) and rsi3 is low (meaning we are at a short-term correction). That does make sense!
rule   4 :
  rsi3  Neutral  AND  rsi14   Neutral  Then  BUY – Hmmm… This is another way of saying that SPY has a positive bias overall.

Many more possibilities

No-ones restricts us to a 2 input model (although complexity goes up extremely fast). No one also restricts us to oscillator-type of indicators. One can try the same with COT (commitment of traders) data or with the price of Gold vs Price of Bonds ratio or whatever. The bottom line is that this tool can help you search for fairly robust and linguistic base strategies that can be cross-checked with common sense.

Here is some interesting links:

* I am neither a programmer nor a fuzzy logic expert. The information given is to the best of my ability/knowledge and meant to un-intimidate and motivate self directed investors to use tools that proffesional Quants use. The information is not necessarily written with accuracy in mind but with practical usability for someone who trades.

Fuzzy Logic Optimization -The “WOO-FOO-SMASH-EFIS-MEE-COPT” model

Fuzzy Logic pt.3: Auto-generate model parameters

I often tire of reading these complicated academic papers that are filled with impossible jargon only to make my life harder. I have found that often times the difficult terminology only hides the simple concepts that lie behind.

So here I will use a difficult term myself,  just to sound smarter than I am. In today’s post I will implement a WFCMAESFISMICOPT( pronounced  “woo-foo-smash-efis-mee-copt”) model.
It stands for: A Walk-Forward Covariance-Matrix-Adaptation-Evolution-Strategy on a Fuzzy-Inference System On Multiple Instruments and A Custom Optimization Target. How is that for a title!

You think that’s complicated? It’s not. We ‘ll start with Matlab’s standard ANFIS model to see where the idea comes from.

Matlab’s Fuzzy Logic module includes what is called ANFIS or Adaptive Neuro-Fuzzy Inference Systems.
Now that sounds complicated too. Well it is, if you were to built it. But the concept behind it is simple.

An ANFIS system is a fuzzy model where the parameters are not set by an “expert” but are found using Neural Networks.
In a normal Fuzzy Model an “expert” is invited to give statements like
1. “I consider RSI  to be Low when  it is between 0 and 40. The closer to 0 the “Lower” it is”.
2. “A Low RSI(3) gives a possible Buy signal”.

read part 1 and part 2 of this article.

An ANFIS system needs no expert. Given a optimizing target (i.e.,profit), it comes up with both the membership functions and the rules. So in theory it can expose relationships that humans may not be able to see. One can argue, why not use Neural Networks directly? Anfis has the advantage that once we get the results, the results are translatable to Human understandable concepts like “Buy at Low RSI and Mid-month”.                  

ANFIS models get bogged down at 5+ Inputs and the optimization target is usually tomorrow’s return. Matlab’s ANFIS cannot (without custom code) optimize for Profit% or CAR/MDD or Sharpe Ratio.

Now Amibroker (a Software for under $300) can do that. It may not have Neural Nets but has something possibly better for optimizing the parameters: the CMA-ES optimizer. And it’s fast.

That means we can build the Fuzzy model in an Amibroker script and optimize all the parameters, using whatever optimizing target we want (i.e., the default CARMDD or our own custom). We can also run it on a portfolio of multiple instruments as well as Walk-Forward it so that we know it has no “prior knowledge” built into it.

You may want to read part 1 and part 2 of this article.

Let’s look at the TRIANGULAR memberships we build before. This basically says that
if RSI(3) is between 0 and 40 it is “Low”. The close to 0 the lower it is.
if RSI(3) is between 10 and 90, its “Mid” where it’s most “Mid” at RSI(3)=50
if RSI(3) is between 60 and 100, its “High”. The closer to 100 the higher it is.

Here’s the  TRIMember function:
TRIMember(variable, leftBottom, MidHigh, RightBottom)
So these can be written as

 SetMember(  “rsi3”, “Low”, TRIMember( rsi3, 0, 0, 40 ) );
 SetMember(  “rsi3”, “Neutral”, TRIMember( rsi3, 10, 50, 90 ) );
 SetMember(  “rsi3”, “High”, TRIMember( rsi3, 60, 100, 100 )  );
or for that matter

 SetMember(  “rsi3”, “Low”, TRIMember( rsi3, a, a+b, a+b+c) );
 SetMember(  “rsi3”, “Neutral”, TRIMember( rsi3, d, d+e, d+e+f) );
 SetMember(  “rsi3”, “High”, TRIMember( rsi3, g, g+k, g+k+m)  );

and as Amibroker users know we can do this:

We do have a practical problem here: Too many overlaping parameters. We can help a bit by using Membership Function with 2 parameters like Gaussian Membership Function and Sigmoid Membership function.  Or we can forget about optimizing the membership functions and just optimize the rules.

That we will do in the next post:
How to uncover hidden relationships in the markets in under 5 minutes.

* I am neither a programmer nor a fuzzy logic expert. The information given is to the best of my ability/knowledge and meant to un-intimidate and motivate self directed investors to use tools that proffesional Quants use. The information is not necessarily written with accuracy in mind but with practical usability for someone who trades.