Please help with combined MACD and TradeProtector strategy

Posted By AlexBlack Monday, December 02, 2013
Add to Favorites0
Author Message
AlexBlack
 Posted Monday, December 02, 2013
Supreme Being

Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)

Group: Forum Members
Last Active: Monday, February 02, 2015
Posts: 8, Visits: 58
Please help to figure out the problems wit combined MACD and TadeProtector strategy. The script is:

const
StrategyName = 'TradeProtector MACD Combined Clean';
StrategyVersion = '1.2';

var
History: TCandleHistory;
Account: TAccount;
Amount,point: Double;
TraderRange: Integer;
Trades: array of TTrade;
TradePropSLActive: array of boolean;
TradeMaxVal: array of double;
CountTrades: integer;
temp:string;
TrailingStop: integer; //nTrailingStop [pips] - initial trailing stop. It will be used until your trade will reach profit = nPropSLThreshold
PropSLThreshold: integer; //nPropSLThreshold [pips] - after reaching this profit proportional trailing stop will be used
PropSLRatio: double; //dPropSLRatio [decimal] - multiplying factor ( PropSL = Profit * dPropSLRatio - Spred )
MACD: TIndicatorScript;

procedure OnCreate;
begin
Settings.AddCandleHistory(@History, 'Candle History', 'USDJPY', CI_5_minutes, 100);
History.OnNewCandleEvent := @OnNewCandle;
History.OnNewRateEvent := @OnNewRate;
Settings.AddAccount(@Account, 'Account', '');
Settings.AddFloat(@Amount, 'Amount(Lots)', 1); //the number of lots
Settings.AddInteger(@TrailingStop,'Trailing Stop (pips)',110);
Settings.SetIntegerRestrictions(@TrailingStop, 1, 9999, 1);
Settings.AddInteger(@PropSLThreshold,'Proportional stop starting profit (pips)',10);
Settings.SetIntegerRestrictions(@PropSLThreshold, 1, 9999, 1);
Settings.AddFloat(@PropSLRatio,'Proportional stop ratio',0.2);
Settings.SetFloatRestrictions(@PropSLRatio, 0, 99999, 0.01);
Settings.AddInteger(@TraderRange, 'Trader Range', 2); //setting up the trader range in pips
Settings.SetIntegerRestrictions(@TraderRange, 0, 100, 1);
ShowMessage('Please, note that Condition distance must be < (Proportional stop ratio) * (Proportional stop starting profit)',);

MACD:= TIndicatorScript.Create(History, 'MACD/OsMA', 'MACD/OsMA'); //creating the MACD indicator
MACD.SetVariableValue('ShortPeriod', 12);
MACD.SetVariableValue('LongPeriod', 26);
MACD.SetVariableValue('SignalPeriod', 9);
MACD.SetVariableValue('AT', 'Exponential');
MACD.SetVariableValue('CalculationType', cbClose); //setting up the MACD indicator periods
end;

procedure OnStart;
var i: integer;
begin
point := History.Instrument.Pointsize;
CountTrades := Tradelist.Count;
SetLength(Trades,CountTrades);
SetLength(TradePropSLActive,CountTrades);
SetLength(TradeMaxVal,CountTrades);
for i:= 0 to CountTrades-1 do
if TradeList.Get(i).Instrument = History.Instrument then
if (TradeList.Get(i).StopOrder = nil) or (TradeList.Get(i).StopOrder.TrailDistance = 0) then
SetTrailingStop(TradeList.Get(i), TrailingStop, 'Stop');
end;

procedure OnNewRate;
var i: integer;
begin
log('Trades count on new rate '+ inttostr(CountTrades));
if CountTrades>0 then
for i:=CountTrades-1 downto 0 do
if TradeList.Get(i).Instrument = History.Instrument then
begin
if TradeList.Get(i).BuySell = bsBuy then
begin
if not TradePropSLActive[i] then
if History.Instrument.Sell - TradeList.Get(i).OpenRate >= PropSLThreshold * point then
begin
TradePropSLActive[i] := true;
TradeMaxVal[i] := History.Instrument.Sell;
end;
if (TradePropSLActive[i]) and (TradeMaxVal[i] <= History.Instrument.Sell) then
begin
Log('Trade'+inttostr(i)+' Buy is processed');
TradeMaxVal[i] := History.Instrument.Sell;
if (TradeList.Get(i).StopOrder <> nil) and (TradeList.Get(i).StopOrder.TrailDistance > 0) then SetTrailingStop(TradeList.Get(i), Round((TradeMaxVal[i]-TradeList.Get(i).OpenRate)*PropSLRatio/Point), 'Stop'); // (TradeMaxVal[i]-(TradeMaxVal[i]-TradeList.Get(i).OpenRate)*PropSLRatio);
end;
end
else if TradeList.Get(i).BuySell = bsSell then
begin
if not TradePropSLActive[i] then
if TradeList.Get(i).OpenRate - History.Instrument.Buy >= PropSLThreshold * point then
begin
TradePropSLActive[i] := true;
TradeMaxVal[i] := History.Instrument.Buy;
end;
if (TradePropSLActive[i]) and (TradeMaxVal[i] >= History.Instrument.Buy) then
begin
Log('Trade'+inttostr(i)+' Sell is processed');
TradeMaxVal[i] := History.Instrument.Buy;
if (TradeList.Get(i).StopOrder <> nil) and (TradeList.Get(i).StopOrder.TrailDistance > 0) then SetTrailingStop(TradeList.Get(i), Round((TradeList.Get(i).OpenRate-TradeMaxVal[i])*PropSLRatio/Point), 'Stop'); // can be done with abs
end;
end
end
end;

// this procedure runs when a new candle opens
procedure OnNewCandle;
begin

Point := History.Instrument.PointSize;
// if the MACD rises above its Signal line
if (MACD.GetGraph(0).Last(1) > MACD.GetGraph(1).Last(1)) and (MACD.GetGraph(0).Last(2) < MACD.GetGraph(1).Last(2)) then
begin
// output the message into the log
log ('The MACD crossed the Signal line bottom-up. A Buy position opened.');
// open a Buy position
CreateOrder(History.Instrument, Account, Amount, bsBuy,
NullRate,
NullRate, TraderRange, 'MACDTrade');;
end;
// if the MACD falls below its Signal line
if (MACD.GetGraph(0).Last(1) < MACD.GetGraph(1).Last(1)) and (MACD.GetGraph(0).Last(2) > MACD.GetGraph(1).Last(2)) then
begin
// output the message into the log
log ('The MACD crossed the Signal line top-down. A Sell position opened.');
// open a Sell position
CreateOrder(History.Instrument, Account, Amount, bsSell,
NullRate,
NullRate, TraderRange, 'MACDTrade');
end;
end;

procedure OnTradeChange(const Action: TDataModificationType; const Trade: TTrade);
var i,k: integer;
begin
if Action = dmtInsert then
if CountTrades < Tradelist.Count then
begin
CountTrades := Tradelist.Count;
SetLength(Trades,CountTrades);
SetLength(TradePropSLActive,CountTrades);
SetLength(TradeMaxVal,CountTrades);
log('Trades count on trade insert '+ inttostr(TradeList.Count)+' '+inttostr(CountTrades) );
Trades[CountTrades-1] := Trade;
TradePropSLActive[CountTrades-1] := false;
if Trade.Instrument = History.Instrument then
SetTrailingStop(Trade, TrailingStop, 'Stop');
end;
if Action = dmtDelete then
if CountTrades > Tradelist.Count then
begin
log('Trades on delete'+ inttostr(TradeList.Count) + ', count now' + inttostr(CountTrades));
for i:= 0 to CountTrades-2 do
if Trades[i] = Trade then
begin
log('Same trade found try to delete');
for k := i to CountTrades-2 do
begin
Trades[i] := Trades[i+1];
TradePropSLActive[i] := TradePropSLActive[i+1];
TradeMaxVal[i] := TradeMaxVal[i+1];
end;
break;
end;
CountTrades := CountTrades - 1;
SetLength(Trades,CountTrades);
SetLength(TradePropSLActive,CountTrades);
SetLength(TradeMaxVal,CountTrades);
log('All deleted now'+ inttostr(TradeList.Count) + ', Count now' + inttostr(CountTrades));
end;
end;

When running in tester after first trade got closed it stops and issues the error:

EXCEPTION
EListError in TStrategyProcessor
CODE

MESSAGE
Exception at trading strategy "TradeProtector MACD Combined Clean" in routine OnNewRate at Line:Column 65:7
List index out of bounds (1)
DETAILS

CALL STACK
fx_client.exe=>TradeData.pas=>TTradeData.GetTrade=>660
fx_client.exe=>TradeData.pas=>TTradeData.GetTrade=>659
fx_client.exe=>StrategiesCallMethods.pas=>TStrategiesCallMethods.CM_TradeData=>459
fx_client.exe=>fs_iinterpreter.pas=>TfsMethodHelper.GetValue=>1372
fx_client.exe=>fs_iinterpreter.pas=>TfsDesignator.DoCalc=>1959
fx_client.exe=>fs_iinterpreter.pas=>TfsDesignator.DoCalc=>1903
fx_client.exe=>fs_iinterpreter.pas=>TfsDesignator.GetValue=>2000
fx_client.exe=>fs_iexpression.pas=>TfsDesignatorNode.GetValue=>559
fx_client.exe=>fs_iexpression.pas=>TEqNode.GetValue=>288
fx_client.exe=>fs_iexpression.pas=>TfsExpression.GetValue=>606
fx_client.exe=>fs_iinterpreter.pas=>TfsIfStmt.Execute=>3064
fx_client.exe=>fs_iinterpreter.pas=>TfsStatement.Execute=>2952
fx_client.exe=>fs_iinterpreter.pas=>TfsStatement.Execute=>2948
fx_client.exe=>fs_iinterpreter.pas=>TfsForStmt.Execute=>3139
fx_client.exe=>fs_iinterpreter.pas=>TfsStatement.Execute=>2952
fx_client.exe=>fs_iinterpreter.pas=>TfsStatement.Execute=>2948
fx_client.exe=>fs_iinterpreter.pas=>TfsIfStmt.Execute=>3065
fx_client.exe=>fs_iinterpreter.pas=>TfsStatement.Execute=>2952
fx_client.exe=>fs_iinterpreter.pas=>TfsProcVariable.GetValue=>1153
fx_client.exe=>fs_iinterpreter.pas=>TfsScript.CallFunction=>2568
fx_client.exe=>fs_iinterpreter.pas=>TfsScript.CallFunction=>2559
fx_client.exe=>StrategyProcessor.pas=>TStrategyProcessor.CallFSFunction=>756
fx_client.exe=>StrategyProcessor.pas=>TStrategyProcessor.CallFSFunction=>751
fx_client.exe=>StrategyProcessor.pas=>TStrategyProcessor.SendVisualizerCommand=>1143
USER32.dll=>=>CallNextHookEx=>0
fx_client.exe=>cxContainer.pas=>ApplicationGetMessageMsgHookProc=>6353
USER32.dll=>=>DispatchMessageW=>0
USER32.dll=>=>DispatchMessageW=>0
fx_client.exe=>Fx_Client.dpr=>=>484
...
fx_client.exe=>StrategyProcessor.pas=>TStrategyProcessor.SendSynchronizedCommand=>1122
fx_client.exe=>StrategyProcessor.pas=>TStrategyProcessor.SendSynchronizedCommand=>1120
fx_client.exe=>StrategyProcessor.pas=>TStrategyProcessor.Execute=>806

WINDOWS VERSION
5.1.2600 Service Pack 3
APPLICATION INFO
fx_client.exe 4.7.223.27/4.7.223
http://demo10.sysfx.com:8036/xml/; edforex36; TRADER: demo1026405
RAISE TIME
2013-12-02 20:06:00
Server Time: 15:05:51

Seems like OnNewRate after the first closed traade triggers earlier than OnTradeChande.
Please help!
black
 Posted Sunday, December 08, 2013
Supreme Being

Supreme Being - (100,741 reputation)Supreme Being - (100,741 reputation)Supreme Being - (100,741 reputation)Supreme Being - (100,741 reputation)Supreme Being - (100,741 reputation)Supreme Being - (100,741 reputation)Supreme Being - (100,741 reputation)Supreme Being - (100,741 reputation)Supreme Being - (100,741 reputation)

Group: Forum Members
Last Active: Sunday, July 13, 2014
Posts: 520, Visits: 1,004
SetLength(TradeMaxVal,CountTrades+1);

?

Smile
AlexBlack
 Posted Sunday, December 08, 2013
Supreme Being

Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)

Group: Forum Members
Last Active: Monday, February 02, 2015
Posts: 8, Visits: 58
Thanks for the reply, but at which place? There are several where it could be done...
Admin
 Posted Monday, December 23, 2013
Administrator

Administrator - (130,491 reputation)

Group: Administrators
Last Active: Friday, June 02, 2017
Posts: 548, Visits: 3,295
Dear AlexBlack,

Please attach the source of the strategy as a file, thanks.


Best regards

-ACTFX© Forum Administrator
Monday, December 23, 2013 by Admin
AlexBlack
 Posted Monday, December 30, 2013
Supreme Being

Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)Supreme Being - (1,989 reputation)

Group: Forum Members
Last Active: Monday, February 02, 2015
Posts: 8, Visits: 58
Dear Admin,

Here it is.

Thank you in advance!
 TradeProtectorMACDcombinedClean.acts (1 view, 8.38 KB)
Admin
 Posted Monday, January 06, 2014
Administrator

Administrator - (130,491 reputation)

Group: Administrators
Last Active: Friday, June 02, 2017
Posts: 548, Visits: 3,295

Dear AlexBlack,


The problem described above occurs when the strategy tries to check the position that has been closed on the current rate.

There are several ways to avoid this situation:

  1. The most simple is to add the check of cycle index value and number of the open positions in the tradelist. This variant is presented in the attached file.
  2. Modify the logic of CountTrades variable calculation –create separate function that will check and count the number of positions opened by the current strategy.
We hope that this explanation will help you.

Please note that we haven’t checked the logic of the strategy. We have only corrected the error.


Happy holidays.



Best regards

-ACTFX© Forum Administrator
 TradeProtectorMACDcombinedClean_v1.3.acts (3 views, 8.38 KB)
Monday, January 06, 2014 by Admin

Similar Topics

Expand / Collapse

Reading This Topic

Expand / Collapse

Back To Top