This week EQUIS sent the new Dev 9.1 to me and by looking for a good starting/learning project I decided to write a new Equity function.
The Equity function is a kind of quick and dirty system tester. It plots the Equity of a given trading system into a chart and writes some info about all trades and statistics into a text file, which is located in the folder of the security. Optional this text file is automatically opened with notepad after the indicator is dropped on the chart.
The output of the equity function is nearly the same as you get, when you make a system test with the enhanced system tester, the reason for the small difference is, that EQUIS calculates the number of shares on the basis of the open price before the trade and I do my calculations on the really entry price.
The indictor call is a little bit complex, so here's a brief description:
ExtFml( "TMW.Equity", Latch, Wrapper: EL CL ES CS Delay Show, Entry/Exit Commission in $, Portfolio in $, Shares in % of Portfolio, Contracts, Point Multiplier)
In total there an actually 7 function input parameters:
1) Latch
The latch is a binary Signal, which gives you the actual state of a trading system. You can find further information in den doc of the forumdll.
2) Wrapper: EL CL ES CS Delay Show
In this string are stored 6 information’s
EL => At which price do you want to enter a long trade, valid entries are: O, H, L, C
CL => At which price do you want to close a long trade, valid entries are: O, H, L, C
ES => At which price do you want to enter a short trade, valid entries are: O, H, L, C
EL => At which price do you want to close a short trade, valid entries are: O, H, L, C
Delay => Here you can specify the delay for EL, CL, ES and EL, valid entries are 0,1,2,3
Show => after the indicator is plotted on the chart (or refreshed), a result file is opened. If you don't like this, you must enter N or n.
Examples:
oOhl1y ==> Valid
hHlL2j ==> Valid
OOHH7u ==> invalid, fifth character is not in the range of 0 to 3
KOOO1n => invalid, for the first four characters are only O,H,L or C allowed.
Default value should be OOOO1Y what means: Buy and sell with a delay of one bar
3) Entry/Exit Commission in $
Valid all numbers greater 0, trades without commissions are not allowed.
4) Portfolio in $
Enter the $ value of your initial portfolio, valid all numbers greater than 1000
5) Shares in % of Portfolio
Enter a number, which part of your Portfolio (Initial portfolio + net profit - commission) you want to invest in every new trade. Valid entries are all number greater than 0 and less or equal 100.
6) Contracts
If you want to do a points only test, then you can set contracts to a number greater than 0. If contracts are 0, the number of current shares is new calculated by the value in No. 5, if contracts is greater than 0, No. 5 is ignored.
7) Point Multiplier
Every gain or loss is multiplied with this number, default value should be 1. Valid are all numbers greater or equal than 1.
Although this thing sounds very complicated, it's very easy to handle. See the following two examples:
Sample 1: The PS Aroon System
{Sample Code 1 Start}
Buy:=AroonUp(14)=100 AND AroonDown(14)=0;
Sell:=AroonUp(14)=0 AND AroonDown(14)=100;
InitialEquity:=Input("Initial Equity in $",1000,10000000,100000);
Commi:=Input("Entry/Exit Commission in $",1,1000,10);
PercShares:=Input("Shares/Contracts in % of Portfolio",1,10000,10);
Contracts:=Input("Number of Contracts",0,50,0);
MultiPly:=Input("Point Multiplyer",1,50,1);
ExtFml( "TMW.Equity", Latch, "OOOO1Y", Commi, InitialEquity, PercShares, Contracts,MultiPly)
Buy:=AroonUp(14)=100 AND AroonDown(14)=0;
Sell:=AroonUp(14)=0 AND AroonDown(14)=100;
EL:= buy;
CL:= sell;
ES:= sell;
CS:= buy;
Latch:=ExtFml( "tmw.Latch", EL, CL, ES, CS);
ExtFml( "TMW.Equity", Latch, "OOOO1Y", Commi, InitialEquity, PercShares, Contracts,MultiPly)
{Sample Code 1 End}
Just copy the code above in the indicator builder and drop it on a chart.
Sample 2: Henry's famous MACD with case Stop 3 System
{Sample Code 2, Part 1 Start: Name:_MACD System with Case Stop}
ShortMA:= Input("Short EMA",1,200,12);
LongMA:= Input("Long EMA",1,200,26);
MovAvg:=Input("Mov",1,200,9);
periods:=30;
hlperiod:=20;
cMACD:=Mov(C,ShortMA,E) - Mov(C,LongMA,E);
cTrigger:=Mov(Mov(C,ShortMA,E) - Mov(C,LongMA,E),MovAvg,E);
RWH:=(H-Ref(L,-periods))/(ATR(periods)*Sqrt(periods));
RWL:=(Ref(H,-periods)-L)/(ATR(periods)*Sqrt(periods));
Pk:=Mov((RWH-RWL),3,W);
AVTR:=Mov(HHV(H,2) - LLV(L,2), hlperiod, S);
SD:=Stdev(HHV(H,2) - LLV(L,2), hlperiod);
Val3:=If(Pk>0,HHV(H-AVTR-2*SD, hlperiod),LLV(L+AVTR+2*SD, hlperiod));
EL:= (cTrigger <cMACD) AND (Val3<C);
CL:= (Val3>C) OR ((cTrigger>cMACD) AND Val3>C);
ES:= (cTrigger>cMACD) AND (Val3>C);
CS:= (Val3<C) OR ((cTrigger <cMACD) AND Val3<C);
state:=ExtFml( "tmw.Latch", EL, CL, ES, CS);
State
{Sample Code 2, Part 1 End}
Just copy the code above in the indicator builder and give it the name _MACD System with Case Stop
{Sample Code 2, Part 2 Start, Name:_TMW Equity}
InitialEquity:=Input("Initial Equity in $",1000,10000000,100000);
Commi:=Input("Entry/Exit Commission in $",1,1000,10);
PercShares:=Input("Shares/Contracts in % of Portfolio",1,10000,10);
Contracts:=Input("Number of Contracts",0,50,0);
MultiPly:=Input("Point Multiplyer",1,50,1);
Latch:=Fml("_MACD System with Case Stop");
ExtFml( "TMW.Equity", Latch, "OOOO1Y", Commi, InitialEquity, PercShares, Contracts,MultiPly)
{Sample Code 2, Part 2 End}
Just copy the code above in the indicator builder and give it the name _TMW Equity
Sample 3: Use of the indicator in exploration
{Sample Code 3 Start}
Fml("_TMW Equity")
{Sample Code 3 End}
Important: By using this formula in an exploration the string input should look like this "OOOO1N" or "OOOO1n". The sixth letter is N or n, which means that no text file is opened!!! This exploration over all stocks the NASDAQ 100 takes about 10 seconds, which is quite okay I think.
Further examples for Settings:
InitialEquity := 10000;
Commi := 10;
PercShares:= 10;
Contracts := 0;
MultiPly := 3;
==> You trade an initial portfolio of 10.000 $, your trading size is 10% of the available equity, the net profit is multiplied with 3.
InitialEquity := 100000;
Commi := 10;
PercShares:= 5;
Contracts := 0;
MultiPly := 1;
==> You trade an initial portfolio of 100.000 $, your trading size is 5% of the available equity, the round turn per Trade is 20$, the net profit is multiplied with 1.
InitialEquity := 10000;
Commi := 5;
PercShares:= 10;
Contracts := 1;
MultiPly := 5;
==> Point only test, because Contracts is set to 1, you always trade 1 contract, the round turn per Trade is 10$, the net profit is multiplied with 5. The initial Equity is only for the Buy and Hold Statistic.
InitialEquity := 10000;
Commi := 5;
PercShares:= 10;
Contracts := 100000;
MultiPly := 1;
==> Point only test, because Contracts is set to 100000, you always trade 100000 contract/shares, the round turn per Trade is 10$, the net profit is multiplied with 1. The initial Equity is only for the Buy and Hold Statistic.
If you want the commission set to 7.95$, you had to enter this value manually or per variable, because decimals are not possible in the Input Function of the Indicator Builder.
The second function in the dll, the Latch function, is nearly the same as in the forum dll, for further information look there.
Because this is my first project with the DevKit I don't know, on which versions of MetaStock it works fine. I use the dll on a Pentium 4, XPPro with service pack 2 and MetaStock Pro 9.1 without problems. The dll is written in the actual version of Visual C++ .Net. I think, the results are correct, but if anyone find some mistakes, please tell me and I try to correct them.
If anyone likes to have some other trade statistics like Sharpe ratio or monthly/weekly stats, then I can implement it. To avoid mistakes, the correct mathematical formula would be nice.
The text file output, the format and the information in it can easily be modified, if there's any interest.
Currently I would call the version a pre release version and I would be happy, if anyone can make some more tests with it. If the dll is stable and all (eventually) user wishes are implemented I give the code to Patrick, so he can put it in the forum dll. If possible, I like to join the MSX Programmers Group.
If you have any questions, problems or wishes please write it in this thread.
Any comments are welcome
Chris