Category Archives: trading software

7 Winning Trading Systems Reviewed – 3 Day High/Low

Back in 2009 Larry Connors and Cesar Alvarez published several short term trading systems in their book “High Probability ETF Trading”. They described 7 mean reverting strategies. 
What happens, then once a strategy becomes public domain? Do they loose their edge?


All tests are performed on a set of 20 ETFs:

DIA,EEM,EFA,EWH,EWJ,EWT,EWZ,FXI,GLD,ILF,IWM,IYR,QQQQ,SPY,XHB,XLB,XLE,XLF,XLI,XLV


Tthe strategy can hold  up to 10 ETFs at any time. Commissions at  $0.005 a share.


Strategy 1: 3 Day High/Low


The rules:
1. ETF is above MA(200)
2. ETF is below MA(5)
3. ETF has made three consecutive lower lows
4. ETF has made three consecutive lower highs

BUY on the close of the day these criteria are met.
SELL on the close of the day the ETF closes above its MA(5).



The exact opposite for SHORT/COVER.




“In-Sample”         2002-2009: CAR/MDD=1.22 .
Profit = 77728.30 (77.73%), CAR = 8.56%, MaxSysDD = -10319.40 (-7.00%), CAR/MDD = 1.22,
 # winners = 649 (75.20%), # losers = 214 (24.80%) 


“Out-of-sample”  2009-2012: CAR/MDD=0.38
Profit = 22155.67 (22.16%), CAR = 5.74%, MaxSysDD = -18627.71 (-15.19%), CAR/MDD = 0.38,
 # winners = 381 (71.48%), # losers = 152 (28.52%) 


The strategy holds up fairly well even after 2009 but under-performs compared to it’s 2002-2009 smooth equity, especially after 2011.Keep in mind that 2009-2011 has been a good bull run for the market in general.
During the difficult  2011 it does not perform so well.

Still, if someone bought the book and traded this strategy, they would come out with a 25.17% profit and a 15.35% draw-down.



a. Simple version, 20 ETFs – Jan 1,2002 – Aug.1,2012




Jan 1,2002 – Aug.1,2012
Profit = 112084.70 (112.08%), CAR = 7.36%, MaxSysDD = -32323.67 (-15.19%), CAR/MDD = 0.48, # winners = 1025 (73.79%), # losers = 364 (26.21%) 

Jan 1,2009- Aug.1,2012
Profit = 22155.67 (22.16%), CAR = 5.74%, MaxSysDD = -18627.71 (-15.19%), CAR/MDD = 0.38, # winners = 381 (71.48%), # losers = 152 (28.52%) 


b. Aggresive version, 20 ETFs – Jan 1,2002 – Aug.1,2012 (Scale In position uses up to x2 leverage)



Jan 1,2002 – Aug.1,2012:
Profit = 183182.36 (183.18%), CAR = 10.33%, MaxSysDD = -55801.39 (-19.73%), CAR/MDD = 0.52, # winners = 1092 (76.42%), # losers = 337 (23.58%) 

Jan 1,2009- Aug.1,2012:
Profit = 32036.25 (32.04%), CAR = 8.06%, MaxSysDD = -25999.34 (-19.71%), CAR/MDD = 0.41, # winners = 406 (74.50%), # losers = 139 (25.50%) 


Detailed Stats:





Here are the detailed stats for the Non aggressive versions

2002-2012

Statistics
All trades Long trades Short trades
Initial capital 100000.00 100000.00 100000.00
Ending capital 212084.70 153151.01 158933.69
Net Profit 112084.70 53151.01 58933.69
Net Profit % 112.08 % 53.15 % 58.93 %
Exposure % 8.91 % 5.44 % 3.47 %
Net Risk Adjusted Return % 1258.07 % 977.38 % 1697.80 %
Annual Return % 7.36 % 4.11 % 4.47 %
Risk Adjusted Return % 82.57 % 75.51 % 128.81 %

All trades 1389 886 (63.79 %) 503 (36.21 %)
Avg. Profit/Loss 80.69 59.99 117.16
Avg. Profit/Loss % 0.57 % 0.48 % 0.74 %
Avg. Bars Held 4.56 4.40 4.84

Winners 1025 (73.79 %) 665 (47.88 %) 360 (25.92 %)
Total Profit 266745.82 145768.63 120977.19
Avg. Profit 260.24 219.20 336.05
Avg. Profit % 1.73 % 1.50 % 2.16 %
Avg. Bars Held 3.44 3.36 3.58
Max. Consecutive 26 26 28
Largest win 3369.36 1449.04 3369.36
# bars in largest win 3 2 3

Losers 364 (26.21 %) 221 (15.91 %) 143 (10.30 %)
Total Loss -154661.12 -92617.62 -62043.50
Avg. Loss -424.89 -419.08 -433.87
Avg. Loss % -2.69 % -2.60 % -2.83 %
Avg. Bars Held 7.71 7.50 8.03
Max. Consecutive 10 10 10
Largest loss -3070.01 -3070.01 -2365.74
# bars in largest loss 13 13 13

Max. trade drawdown -3944.05 -3944.05 -2993.90
Max. trade % drawdown -18.94 % -18.92 % -18.94 %
Max. system drawdown -32323.67 -33724.74 -13937.44
Max. system % drawdown -15.19 % -18.97 % -9.20 %
Recovery Factor 3.47 1.58 4.23
CAR/MaxDD 0.48 0.22 0.49
RAR/MaxDD 5.43 3.98 14.01
Profit Factor 1.72 1.57 1.95
Payoff Ratio 0.61 0.52 0.77
Standard Error 10672.47 6650.99 8080.77
Risk-Reward Ratio 1.18 1.14 0.62
Ulcer Index 2.06 4.21 2.53
Ulcer Performance Index 0.95 -0.31 -0.37
Sharpe Ratio of trades 1.60 1.49 1.79
K-Ratio 0.0699 0.0677 0.0365


Out-of Sample 2009-2012



Statistics
All trades Long trades Short trades
Initial capital 100000.00 100000.00 100000.00
Ending capital 122155.67 104344.90 117810.77
Net Profit 22155.67 4344.90 17810.77
Net Profit % 22.16 % 4.34 % 17.81 %
Exposure % 11.07 % 6.02 % 5.05 %
Net Risk Adjusted Return % 200.07 % 72.15 % 352.54 %
Annual Return % 5.74 % 1.19 % 4.68 %
Risk Adjusted Return % 51.82 % 19.81 % 92.56 %

All trades 533 300 (56.29 %) 233 (43.71 %)
Avg. Profit/Loss 41.57 14.48 76.44
Avg. Profit/Loss % 0.41 % 0.17 % 0.73 %
Avg. Bars Held 4.91 4.79 5.08

Winners 381 (71.48 %) 216 (40.53 %) 165 (30.96 %)
Total Profit 76958.35 38256.95 38701.39
Avg. Profit 201.99 177.12 234.55
Avg. Profit % 1.83 % 1.58 % 2.17 %
Avg. Bars Held 3.62 3.47 3.82
Max. Consecutive 24 23 28
Largest win 948.27 835.21 948.27
# bars in largest win 3 2 3

Losers 152 (28.52 %) 84 (15.76 %) 68 (12.76 %)
Total Loss -54802.67 -33912.05 -20890.62
Avg. Loss -360.54 -403.71 -307.21
Avg. Loss % -3.15 % -3.45 % -2.77 %
Avg. Bars Held 8.15 8.18 8.12
Max. Consecutive 10 10 10
Largest loss -1767.74 -1767.74 -1361.94
# bars in largest loss 13 13 13

Max. trade drawdown -2277.55 -2277.55 -1726.40
Max. trade % drawdown -18.92 % -18.92 % -16.66 %
Max. system drawdown -18627.71 -19432.71 -8024.43
Max. system % drawdown -15.19 % -16.39 % -7.07 %
Recovery Factor 1.19 0.22 2.22
CAR/MaxDD 0.38 0.07 0.66
RAR/MaxDD 3.41 1.21 13.10
Profit Factor 1.40 1.13 1.85
Payoff Ratio 0.56 0.44 0.76
Standard Error 3221.90 5001.76 2781.37
Risk-Reward Ratio 1.33 0.35 0.91
Ulcer Index 2.70 5.92 2.31
Ulcer Performance Index 0.13 -0.71 -0.31
Sharpe Ratio of trades 1.05 0.41 1.75
K-Ratio 0.0459 0.0121 0.0314



Amibroker code:



//Code by VangelisM. (aka – sanzprophet )
//Part of Code taken by afl from Library – Paul’s “Connors TPS – ETFs.afl”


Plot( C, “Close”, ParamColor(“Color”, colorBlack ), styleNoTitle | ParamStyle(“Style”) | GetPriceStyle() ); 
SetBacktestMode( backtestRegularRaw );
aggresive=ParamToggle(“Agreesive?”,”NO|YES”,0);
Buy=Sell=Cover=Short=0;
SetTradeDelays(0,0,0,0);
BuyPrice=SellPrice=CoverPrice=ShortPrice=C;
qty=Param(“PositionScoretions”,1,1,50,1);
SetOption( “MaxOpenPositions”, qty );


if(!aggresive)
{
aboveMA=C>MA(C,200);
belowMA5=C<MA(C,5);
Low3= H<Ref(H,-1) AND Ref(H,-1)<Ref(H,-2) AND Ref(H,-2)<Ref(H,-3)
AND L<Ref(L,-1) AND Ref(L,-1)<Ref(L,-2) AND Ref(L,-2)<Ref(L,-3);


Buy1=aboveMA AND belowMA5 AND Low3;
Buy=Buy1;
Sell=!belowMA5;
Sell=ExRem(Sell,Buy);


High3= H>Ref(H,-1) AND Ref(H,-1)>Ref(H,-2) AND Ref(H,-2)>Ref(H,-3)
AND L>Ref(L,-1) AND Ref(L,-1)>Ref(L,-2) AND Ref(L,-2)>Ref(L,-3);


Short1=C<MA(C,200) AND !belowMA5 AND High3;
Short=Short1;
Cover=belowMA5;


PositionSize=-98/qty;
PositionScore=IIf(Buy,100-RSI(3),RSI(3));


}


if(aggresive)
{


aboveMA=C>MA(C,200);
belowMA5=C<MA(C,5);
Low3= H<Ref(H,-1) AND Ref(H,-1)<Ref(H,-2) AND Ref(H,-2)<Ref(H,-3)
AND L<Ref(L,-1) AND Ref(L,-1)<Ref(L,-2) AND Ref(L,-2)<Ref(L,-3);


Buy1=aboveMA AND belowMA5 AND Low3;
Sell=!belowMA5;




High3= H>Ref(H,-1) AND Ref(H,-1)>Ref(H,-2) AND Ref(H,-2)>Ref(H,-3)
AND L>Ref(L,-1) AND Ref(L,-1)>Ref(L,-2) AND Ref(L,-2)>Ref(L,-3);
Short1=C<MA(C,200) AND !belowMA5 AND High3;
Cover=belowMA5;




BarsSinceSell = BarsSince(Sell);
InFirstPos =Flip(Buy1,Sell);
FirstTrigger = ExRem(InFirstPos, Sell);
BarsSinceFirstTrigger = BarsSince(FirstTrigger);
FirstTriggerPrice = IIf(BarsSinceFirstTrigger < BarsSinceSell,Ref(C,-BarsSinceFirstTrigger), 0 );


SecondEntry = aboveMA AND C < FirstTriggerPrice AND InFirstPos AND Ref(InFirstPos,-1);
InSecondPos = Flip(SecondEntry, Sell);
SecondTrigger = ExRem(InSecondPos, Sell);
BarsSinceSecondTrigger = BarsSince(SecondTrigger);
SecondTriggerPrice = IIf(BarsSinceSecondTrigger < BarsSinceSell,
Ref(C,-BarsSinceSecondTrigger), 0);


BarsSinceCover = BarsSince(Cover);


FirstShortEntry = Short1; ;
InFirstShortPos = Flip(FirstShortEntry, Cover );
FirstShortTrigger = ExRem(InFirstShortPos, Cover );
BarsSinceFirstShortTrigger = BarsSince(FirstShortTrigger);
FirstShortTriggerPrice = IIf(BarsSinceFirstShortTrigger < BarsSinceCover ,Ref(C,-BarsSinceFirstShortTrigger), 0 );
//FirstTriggerPrice = IIf(BarsSinceFirstTrigger < BarsSinceSell,Ref(O,-BarsSinceFirstTrigger+1), 0 );




SecondShortEntry = !aboveMA AND C > FirstShortTriggerPrice AND InFirstShortPos AND Ref(InFirstShortPos,-1);
InSecondShortPos = Flip(SecondShortEntry, Cover );
SecondShortTrigger = ExRem(InSecondShortPos, Cover );
BarsSinceSecondShortTrigger = BarsSince(SecondShortTrigger);
SecondShortTriggerPrice = IIf(BarsSinceSecondShortTrigger < BarsSinceCover,
Ref(C,-BarsSinceSecondShortTrigger), 0);


PositionSize=-98/qty;
PositionScore=IIf(Buy OR SecondEntry ,100-RSI(3),RSI(3));


Buy=IIf(Buy1,1,IIf(SecondEntry AND Sum(Secondentry,BarsSinceSell)==1 ,sigScaleIn,0));
Short=IIf(Short1,1,IIf(SecondShortEntry AND Sum(SecondShortentry,BarsSinceCover)==1 ,sigScaleIn,0));
}


GfxSelectPen( colorBlack, 2 ); 
GfxSelectFont(“Times New Roman”, 12, 200, False ); 
GfxTextOut(“3 Day High/Low”,10,20);




shape = Buy * shapeUpArrow + Sell * shapeDownArrow;


PlotShapes( shape, IIf( Buy, colorGreen, colorYellow ), 0,C );


Matlab for Amibroker Users – Backtesting Functions for Matlab

The point of this post is to provide some basic functions to non professional Matlab users that may help backtest a simple long only system the way Amibroker (and  most other software) backtest.

If you are an Amibroker user you are used to something this easy:

sma9=ma(close,9);
sma21=ma(close,21);
buy=Cross(sma9,sma21);  
sell=Cross(sma21,sma9); 
Wish you could do that in Matlab?
Here’s the Matlab Code for a simple Moving Average Crossover system using some custom functions

%START CODE
%You need these files in the “Path”  for the code to work
%sma.m, iif.m, Cross.m, backtestlongAmount.m, GetTickerV.m, stock.m
%Download SPY from Yahoo, 5 years history, daily bars. We get a “fints” object
% Function TickerV() is similar to function stock() except that 
%it adjusts for OHLC to Adjusted Close Data.

ticker_fints=GetTickerV(‘SPY’,’5y’,’d’);
%%Get the close price from fints and make it a vector
close=fts2mat(ticker_fints.close);
open=fts2mat(ticker_fints.open);
sma9=sma(close,9);
sma21=sma(close,21);
buy=Cross(sma9,sma21);  % custom function, NOT Matlab’s native cross( ) 
sell=Cross(sma21,sma9); 
%Signal should be 1 for Buy, -1 for Sell and 0 for noAction (or Hold)
signal= iif(buy==1,1,iif(sell==1,-1,0));
% Buy and Sell on next bar Open 
 [pnl,pnlvector, sh]= backtestlongAmount(close,signal,open,1,100000);
% [pnl,pnlvector, sh]= backtestlongAmount(close,signal,close,0,100000);
plot(pnl,’DisplayName’,’pnl’,’YDataSource’,’pnl’);figure(gcf)
%END CODE

You are free to copy the code and download the functions. I am not a professional coder. Most functions include pre-existing code that I combined and edited. It’s very probable that mistakes exist.
I am sharing these m files in hope others will check and improve them.

Disclaimer: This code may not provide accurate results. You will have to check yourself to make sure the code works as it should.

The function are:
sma.m
iif.m
Cross.m
backtestlongAmount.m
GetTickerV.m
stock.m

here’s the link:
Custom Functions


Basic Backtest Function for Matlab

[pnl,pnlvector, sh]= backtestlongAmount(data,signal,buyprice,delay,amount$$);

This is a very basic function for backtesting a strategy in Matlab.
All you need is a vector with 1s for Buy, -1’s for Sell and 0’s for Hold.

To use it we need
1. A vector of prices,i.e. SPY close prices
2. Signal: A vector of  1 for BUY, -1 for SELL and 0 for HOLD
3. Buyprice: A vector of Close prices if we buy at close or Open prices if we buy at Open
4. Delay: 0 if we buy “Today” – 1 if we buy tomorrow. So to Buy Tomorrow on Open:
backtestlongAmount(data,signal,open,1,amount$$);
4. Amount :i.e., 100,000

backtestlongAmount.m

Please report any bugs or inaccuracies you find. Improvements are welcome.

Amibroker on Amazon’s EC2

This post is a technical description on how to set up Amibroker on EC2. For licencing Amibroker running on EC2 or another VPS contact amibroker.com

This is a rough guide on how to setup Amibroker to run on an Amazon EC2 micro instance.
Turns out, Amibroker runs fast even on this tiny micro instance.

Amazon provides one year free access to a basic micro instance to new users. It’s their way to let new people try out their services.
In a nutshell, setting up an EC2 instance is like setting up a small PC on the cloud. You can install anything on this PC. You can choose the base OS and then configure this virtual PC as needed.
I wanted to setup a “virtual” PC that would use Amibroker to run analysis and generate signals  for my EOD trading as well as auto-trade some paper systems on YoutualFunds.com. It would replace my laptop at home that does that every night.
I also wanted to try an alternative to running trading systems through Scripts on Google Docs.

Steps:
1.
You need to sign up for an account with Amazon.com unless you already have one. Even if you run the free  micro instance, you will need to give out your credit card to Amazon.
Please review Amazon’s offering. It should be enough to run free for a year.
If you exceed the quota they give you, you will be charged. 
2.
Sett up the instance. I personally used the Windows 2008 32bit AMI, but I guess you can use the Windows 2008  64bit R2 one. The lighter the package, the better since the micro instance has minimal RAM and CPU power. Please watch this video. It will guide you through the steps:
http://www.youtube.com/watch?v=ZAB8wCg9MyE
(Start from the middle of the video where he sets up the actual instance).
If you don’t like videos you can read this how to guide:
http://docs.amazonwebservices.com/AWSEC2/latest/WindowsGuide/EC2Win_GetStarted.html


The default Security Group does not allow Remote Desktop Connection.
When you get at the part of setting security groups, edit the default group and add port 3389 inside the “Port Range”. Press “Add Rule’. This will open up the port for Remote Desktop Connection which is the non-programmer’s way of controlling your remote PC. You can leave Source as is unless you have a static IP and are concerned over security.

Once you have set up port 3389 access you have the minimum to continue. Optionally you can open additional ports (SSH, FTP, etc).

Assuming you have followed the video tutorial you have now a micro instance running on EC2.

 1. Connect to the instance using Remote Desktop Connection. Best way is to go to the AWS control panel, right click on the instance and choose Connect. This will download a file and fire up RDC with the right settings. Alternatively, start RDC (Start—>search “remote”) and point it to the instance’s public IP address.

Choose “options” and type “Administrator” under User. Connect. Type in your instance’s administrator password when asked. A window should open with your new desktop.







2. At this point, I was asked to setup my network as Home, Work or Public. I chose Public. That brought problems and caused Internet Explorer to refuse to download stuff… So… I downloaded Firefox.

3. Get Firefox: Start Internet Explorer from the Start Menu. Navigate to “http://www.mozilla.org/en-US/” and download Firefox. If IE refuses, try adding www.mozilla.org to the trusted sites.

4. Get Amibroker: After you install Firefox, launch it and go to http://www.amibroker.com/download.html. Download the official version. Go to the Download folder and launch the installer. Amibroker will install as usual.

7. * Please check with amibroker.com for proper licencing terms.
Send a LostKey request to Amibroker: Assuming you have a valid license, go back to your regular computer (hide the RDC window). Navigate to http://www.amibroker.com/lostkey.html and fill the form. Check your email. Copy the address that was sent to you (highlight it and right click copy).

8. License Amibroker: Now go back to the instance window. Open Firefox (in the instance) if it’s not open. Paste the address that was send on the email. Hit Enter. Check your Download folder for a small file. Double click it. This will authorize Amibroker under you existing license.

That’s it.

Now if you want to transfer files from your computer to your instance, the easiest way is by copy/paste. Select a file (or folder) in your computer desktop and right-click “Copy”. Now go to the instance desktop, right-click “Paste”. That simple.

If you have large files/folders to transfer, copy /paste takes forever. Another way is to set up a Dropbox or SugarSync account and upload your files there. Then from the Instance, turn your browser to that account and download into the instance (at a faster speed since you are using Amazon bandwidth ). Keep in mind that incoming traffic seems to be free, but you do get charged for outward traffic, after a certain quota is reached.

If you want to schedule tasks or custom Jscripts or VBScripts you will have to use the Windows Task Scheduler. Setting that up is more complicated than in your home PC. 

Note1:  For JScripts,”WScript.Echo()” does not seem to work as expected. You can use:
var WshShell= new ActiveXObject(“Wscript.Shell”);
WshShell.Popup (“Backtest has run”, 5);

Note2: If you are sending emails from the instance, keep in mind Amazon has restrictions on outgoing emails. My Jscript that calls CDO to email, failed because of that. Check Amazon’s aws FAQ for more info.

Note 3: For the Task Scheduler: I am still working on the setup. So far I can advise you that you will need to:
a. Provide a static “computer name” to your instance since the assigned name (i.e. IP-xxxx)  changes every time you reboot. Here’s how to do that:
http://myonecent.wordpress.com/2010/11/26/how-to-get-rid-of-windows-task-scheduler-password-issue-with-amazon-ec2-instance/
b. Test the tasks using the default basic settings “Run only if User is logged In”  This way you can “see” them running and check the Popup messages.
c. Eventually, the instance should run unattended whether logged in or not. You need to change the settings so that the Task runs “Wether User Logged In or Not” and use “Highest Privileges”.

Now, here’s the tricky part: If you try to test a JScript with these settings, you may not see any feedback or Popups while you are logged in. This does not mean it is not running! You may need other ways to monitor. Feel free to contribute on how to do that…

What is left to do:
The initial idea was to set up a EC2 instance that would START up, run for 1 hour ONLY, update quotes, run backtests/exploration, email the trading signals and then STOP. That would translate into less than 30 hours/month EC2 usage time or less than $5 for a Small Windows instance. And even less for a micro. 
Turns out, there is no easy way to schedule the instance to START at a certain time (the stopping part can be scheduled inside the instance). I hope a solution is found before the free tier offer expires. The cloud can get very expensive…

Any ideas or suggestions are welcome.

Trading Log for Amibroker

I have been looking into software to log my trades and keep track of actual trade performance. I was looking for:

1.  Simple import process from Interactive Brokers TWS Log Files.
2.  Be able to code and run custom statistics on portfolio level trades, not just per instrument.
3.  Be able to see my entry and exit on a price chart.
4.  Visualize Portfolio Equity Curve.

There are some great commercial software out there but they mostly lack the ability to visualize entry and exit points. I liked trading diary pro as it works well with IB. But it’s more of a bookkeeping tool than a custom analysis tool.
 I also tried Excel to no avail.

So I wrote my own script for Amibroker (mostly based on an existing script in the AB library written by Herman).
The scripts reads the trades from IB’s TWS export.
Here is a screenshot:
Note: The equity curve is for ALL instruments traded.

There’s still a lot to be done:
1. Export sorted trades and make  backup copy to Excel.
2. Append TWS daily .csv files automatically.
3. Equity Curve taking into account daily prices, not just entry and exit. (Hard).
4. Equity Curves per Instrument.
5. More Stats: Drawdown, CAR/MDD, etc.