Results differs a lot after converted code from Tradesim/Metastock to AMibroker

Results differs a lot from Tradesim to AMibroker. Do someone see some errors?

I have converted code from Tradesim/Metastock to Amibroker and here is the result:

Code in AMibroker:

period = 20; 
ChannelBreakUp = H > Ref( HHV( High, period ), -1 );
Buy = ChannelBreakUp;
period2 = 20;  
ChannelBreakUpDown = L < Ref( LLV( Low, period2 ), -1 );
Sell = ChannelBreakUpDown;

// trade on next bar open
SetTradeDelays( 1, 1, 1, 1 );
BuyPrice = SellPrice = Open; 

PositionSize = -1 * BuyPrice/(1.5*ATR(10));

ApplyStop( stopTypeLoss, stopModePoint, Open-1.5*ATR(10), True );

Code in Tradesim/Metastock:


ExtFml( "TradeSim.Initialize"); { Initialize internal variables}
ExtFml("TradeSim.DisablePriceFilter");
ExtFml( "TradeSim.EnableDelayOfEntryByOneBar");
ExtFml( "TradeSim.EnableDelayOfAllExitsByOneBar");
{---------------------- Trading System - Long ---------------------}
EntryTrigger:=H>Ref(HHV(H,20),-1); { Entry Trigger }
EntryPrice:=OPEN; { Entry Price }
InitialStop:=OPEN - 1.5*ATR(10); { Initial Stop }
ExitTrigger:=L<Ref(LLV(L,20),-1); { Exit Trigger }
ExitPrice:=OPEN; { Exit Price }
Tally:=Tally + ExtFml( "TradeSim.RecordTrades",
"channelbreakout", { Trade Data Filename }
LONG, { Trade Position Type }
EntryTrigger, { Entry Trigger }
EntryPrice, { Entry Price }
InitialStop, { Initial Stop }
ExitTrigger, { Exit Trigger }
ExitPrice2, { Exit Price }
START); { Trade Recorder Control }

After one second look I can see that ApplyStop statement is incorrect. The "amount" argument is wrong. Amount is the distance from entry not absolute price level. It should be ATR alone. To use price level http://www.amibroker.com/kb/2014/10/17/using-price-levels-with-applystop-function/

There are probably other things that may likely to be wrong too but since your Tradesim formula links to "External Formulas" and postion sizing that are not given, it is guessing game that can't be won without magical mirror.

Hehe, yes, the magic is 1 percent also in Tradesim. In Tradesim it is "Fraction of capital risked pr trade". In Tradesim you have Profits Pyramid(on or off).
From the usermanual for Tradesim:
Pyramid Profits
When this parameter is not checked then we aim to maintain the total trading capital at an amount specified by the Initial Capital parameter. However in the course of trading we may have a situation where we have many losing trades so that the total capital has fallen below the initial capital in which case the total trading capital will be less than the initial capital. If the trading system produces too many losing trades so that the total capital falls below what can reliably be traded then any simulation in progress will abort and a ‘bankrupt’ condition will be reported.
If there are enough profitable trades so that the total capital exceeds the initial capital then the total trading capital will be ‘clamped’ or held at the initial capital and the rest of the trading profits are put aside to be used later when the total trade capital starts to fall due to losing trades.
When this parameter is checked any profits that are returned by profitable trades are added to the total equity and trade capital. The effect of this on the trading strategy will depend on what position size model is used. However it should be noted that a trading system that is profitable without profit compounding should benefit from using profit compounding. How much of an improvement will depend on other factors of course but the position size model used will have the most profound effect. Position size models which size trades according to a proportion of the total trading capital will benefit the most from profit compounding.

How does it work in Amibroker?

Ok, so without stops this code is correct I pressume?

period = 20; 
ChannelBreakUp = H > Ref( HHV( High, period ), -1 );
Buy = ChannelBreakUp;
period2 = 20;  
ChannelBreakUpDown = L < Ref( LLV( Low, period2 ), -1 );
Sell = ChannelBreakUpDown;

SetTradeDelays( 1, 1, 1, 1 );

BuyPrice = SellPrice = Open; 

PositionSize = -1 * BuyPrice/(1.5*ATR(10));

Can someone please answer my question above?

Are you a timetraveller?
You are buying a breakout on a specific level at open price while the breakout happens during the following day - but this is future. Therefore you have to know in advance that today there will be eventually a breakout! Same with the sell of your position. This gives a nice backtest, but...
I would suggest one of this possibilities:

If you want to buy at next Open, then the code should be like this:

ChannelBreakUp = Ref(H,-1) > Ref( HHV( High, period ), -2 );

or you want to buy directly at the breakout and then your buyprice should look like this:

BuyPrice = Ref( HHV( High, period ), -1 );

It is very important to never look in the future while making backtests. This would only work if you are a real timetraveller.

1 Like

Hehe, yes, it seems so:) a lot to work on I guess. Thanks for direct communication!

No. He is buying the breakout but he is also delaying the entry by one bar thus open prices can work.
@herbertioz to really understand what is happening wiht your code run a simplified version of a exploration:

Filter = 1;
ChannelBreakUp = H > Ref( HHV( High, 20 ), -1 ); 
 
AddColumn( ChannelBreakUp, "ChannelBreakUp", 1 );

and run a backtest of a simplified version of your code:

period = 20; 
ChannelBreakUp = H > Ref( HHV( High, period ), -1 );
Buy = ChannelBreakUp;
Sell = 0;

SetTradeDelays( 1, 1, 1, 1 );

ApplyStop( stopTypeNBar, stopModeBars, 1 );  

BuyPrice = SellPrice = Open; 

to see the difference.

1 Like

By the way, I got better results when I used your code:


ChannelBreakUp = Ref(H,-1) > Ref( HHV( High, period ), -2 );

Thanks for help. I have used 5 hours of analysis of the code with manual checking with excel and now finally I have the right one:

period = 20; 
ChannelBreakUp = H > Ref( HHV( High, period ), -1 );
Buy = ChannelBreakUp;
period2 = 20;  
ChannelBreakUpDown = L < Ref( LLV( Low, period2 ), -1 );
Sell = ChannelBreakUpDown;

SetTradeDelays( 1, 1, 1, 1 );

BuyPrice = SellPrice = Open; 

PositionSize = -1 * BuyPrice/(1.5*ATR(10));

Amibroker is now my new favorite application:) Thanks all for trigging me to do the work!