Combining TrailingStop and SMA is not a good combination but it suits to illustrate how to script combinations of strategies.
Trailing Stop, Trailing Step and SMA are optional.
Having Trailing Stop and SMA optional means that they can be tested individually or combined.
The strategy also allows to set Trading Periods e.g. 2012/1/1 to 2015/12/31 and a Daily Trading Time Frame e.g. 12:00 to 16:00 GMT.
To monitor StopLoss adjustments and Trading results popup windows for each can be activated.
Popup windows are useful when making modifications to the strategy.
Code: Select all
library TrailingPeriodsSMA;
//TrailingStop and SMA strategy with the ability to trade in trading periods (days, month, years) and daily times frames (hours, minutes).
//Trailing Stop and Trailing Step are optional.
//Trailing Step option "Yes" means that the user can declare a TrailingStep.
//Trailing Step option "No" means that the TrailingStep is automatically set at Bidgain (Bid minus PreviousBid).
//SMA option exist for buying an order and selling an existing order.
uses
SysUtils,
StrategyInterfaceUnit,
DateUtils,
Windows,
Math;
var
//Trading variables
SymbolName: PAnsiChar = nil;
lot: double = 1;
StopLoss: integer = 3000;
TakeProfit: integer = 10000;
TrailingTrigger:integer = 5;
TrailingStep:integer = 5;
Timeframe: integer;
OrderHandle: integer;
//Variables for Time Periods
BeginYear:Integer = 2002;
BeginMonth:Integer = 1;
BeginDay:Integer = 1;
EndYear:Integer = 2015;
EndMonth:Integer = 12;
EndDay:Integer = 31;
//Variables for daily time frames
StartHour:Integer = 12;
StartMinute:Integer = 0;
StartSecond:Integer = 0;
StartMillisecond:Integer = 0;
StopHour:Integer = 16;
StopMinute:Integer = 0;
StopSecond:Integer = 0;
StopMillisecond:Integer = 0;
//TS procedure variables
StopLossNew, StopLossCurrent, StopLossOriginal, StopLossTotal:Double;
BidPrevious, BidGain:Double;
TrailingValue:Double;
TrailingBoolean, TStepBoolean:Boolean;
//Variable for Popup Windows
Mmagic:Integer;
Ccomment:string;
Hhour, Mminute, Ssecond, Mmillisecond:Integer;
PreHhour, PreMminute, PreSsecond, PreMmillisecond:Integer;
vBoolean:Boolean;
tsBoolean:Boolean;
//SMA variables
BuySMABoolean:Boolean;
SellSMABoolean:Boolean;
period1:Integer = 5;
period2:Integer = 10;
//Misc variables
j:Integer = 0;
x:Integer = 0;
{-----Init strategy---------------------------------------------------------}
procedure InitStrategy; stdcall;
begin
// set strategy name and description
StrategyShortName('TrailingStop, Periods and SMAs');
StrategyDescription('Trailing Stop and SMA Strategy for Trading within specified Periods');
// register parameters
AddSeparator('Trade settings');
RegOption('Symbol', ot_Currency, SymbolName);
ReplaceStr(SymbolName, 'USDJPY');
RegOption('Lot', lot, 2, 0.01, 10);
RegOption('Take Profit', TakeProfit, 1, 100000);
RegOption('Stop Loss', StopLoss, 1, 100000);
RegOption('Trailing Stop option (if No the below 3 are not used)',TrailingBoolean);
RegOption('Trailing Trigger', TrailingTrigger, 1, 100000);
RegOption('Trailing Step option (if No the below 1 is not used. Instead Bid-PreviousBid is used.)',TStepBoolean);
RegOption('Trailing Step', TrailingStep, 1, 10000);
AddSeparator('Time frame for FT calculations and graph settings');
RegOption('Timeframe', ot_TimeFrame, Timeframe);
Timeframe := PERIOD_M1;
AddSeparator('Trading Period');
RegOption('Begin year', BeginYear);
SetOptionRange('Begin year', 2000, 2050);
RegOption('Begin month', BeginMonth);
SetOptionRange('Begin month', 1, 12);
RegOption('Begin day', BeginDay);
SetOptionRange('Begin day', 1, 31);
RegOption('End year', EndYear);
SetOptionRange('End year', 2000, 2050);
RegOption('End month', EndMonth);
SetOptionRange('End month', 1, 12);
RegOption('End day', EndDay);
SetOptionRange('End day', 1, 31);
AddSeparator('Trading Daily TimeFrame (For continues trading set: 0,0,0,0 to 23,59,59,999)');
RegOption('Start hour', StartHour);
SetOptionRange('Start hour', 0, 23);
RegOption('Start minute', StartMinute);
SetOptionRange('Start minute', 0, 59);
RegOption('Start second', StartSecond);
SetOptionRange('Start second', 0, 59);
RegOption('Start millisecond', StartMillisecond);
SetOptionRange('Start millisecond', 0, 999);
RegOption('Stop hour', StopHour);
SetOptionRange('Stop hour', 0, 23);
RegOption('Stop minute', StopMinute);
SetOptionRange('Stop minute', 0, 59);
RegOption('Stop second', StopSecond);
SetOptionRange('Stop second', 0, 59);
RegOption('Stop millisecond', StopMillisecond);
SetOptionRange('Stop millisecond', 0, 999);
AddSeparator('Simple moving average (SMA)');
RegOption('Do you want to use SMA to buy orders?', ot_Boolean, BuySMABoolean);
RegOption('Do you want to use SMA to sell orders?', ot_Boolean, SellSMABoolean);
RegOption('Period1', period1);
SetOptionRange('Period1', 5, 200);
RegOption('Period2', period2);
SetOptionRange('Period2', 5, 200);
AddSeparator('Message Boxes');
RegOption('Trade Summary Window (appears when trade is closed)', ot_Boolean, vBoolean);
RegOption('Trailing Stop Summary Window (appears when Trailing Trigger was hit)', ot_Boolean, tsBoolean);
end;
{-----Done strategy---------------------------------------------------------}
procedure DoneStrategy; stdcall;
begin
FreeMem(SymbolName);
end;
{-----Reset strategy--------------------------------------------------------}
procedure ResetStrategy; stdcall;
begin
end;
{------Trailing Stop Summary Popup Window-----------------------------------}
procedure TSSW;
begin
Pause();
MessageBox(0, PChar('Initial StopLoss: '+FloatToStr(StopLossOriginal)+#13#10+
'Previous StopLoss: '+FloatToStr(StopLossCurrent)+#13#10+
'New StopLoss: '+FloatToStr(StopLossNew)+#13#10+
'Bid gain: '+FloatToStr(RoundTo(BidGain,-4))+#13#10+
'# of S/L moves: '+IntToStr(x)+#13#10+
'Total StopLoss move: '+FloatToStr(RoundTo(StopLossTotal,-4))+#13#10+
'Previous Time: '+IntToStr(PreHhour)+':'+IntToStr(PreMminute)+':'+IntToStr(PreSsecond)+':'+IntToStr(PreMmillisecond)+#13#10+
'Current Time: '+IntToStr(Hhour)+':'+IntToStr(Mminute)+':'+IntToStr(Ssecond)+':'+IntToStr(Mmillisecond)+#13#10+
'MagicNumber: '+IntToStr(Mmagic)+#13#10+
'OrderComment: '+(Ccomment)),PChar('TrailingStop Summary'), MB_OK);
Resume();
end;
{-----Trade Summary Popup Window--------------------------------------------}
procedure TSW;
var
Oprice,Cprice, Ppips, Otime, Ctime, Pprofit, OStopLoss, OTakeProfit, Llot:Double;
Hhistory, Hhandle, i:Integer;
Ssymbol:string;
begin
i:=HistoryTotal;
if OrderSelect(i-1, SELECT_BY_TICKET, MODE_TRADES) then
begin
Oprice := OrderOpenPrice;
Cprice := OrderClosePrice;
Ppips := OrderProfitPips;
Otime := OrderOpenTime;
Ctime := OrderCloseTime;
Pprofit:= OrderProfit;
OStopLoss:=OrderStopLoss;
OTakeProfit:=OrderTakeProfit;
Hhistory:=HistoryTotal;
Llot:=OrderLots;
Hhandle:=OrderTicket;
Ssymbol:=OrderSymbol;
Mmagic:=OrderMagicNumber;
Ccomment:=OrderComment;
Pause();
MessageBox(0, PChar('Open time: '+DateTimeToStr(Otime)+#13#10+
'Close time: '+DateTimeToStr(Ctime)+#13#10+
'-------------------------------------'+#13#10+
'Open price: '+FloatToStr(Oprice)+#13#10+
'Close price: '+FloatToStr(Cprice)+#13#10+
'-------------------------------------'+#13#10+
'Pips: '+FloatToStr(Ppips)+#13#10+
'Profit/Loss: '+FloatToStr(RoundTo(Pprofit,-4))+#13#10+
'-------------------------------------'+#13#10+
'Initial StopLoss: '+FloatToStr(StopLossOriginal)+#13#10+
'# of S/L moves: '+IntToStr(x)+#13#10+
'Total StopLoss move: '+FloatToStr(RoundTo(StopLossTotal,-4))+#13#10+
'-------------------------------------'+#13#10+
'StopLoss: '+FloatToStr(OStopLoss)+#13#10+
'TakeProfit: '+FloatToStr(OTakeProfit)+#13#10+
'-------------------------------------'+#13#10+
'Records in History: '+IntToStr(Hhistory)+#13#10+
'Handle/Ticket: '+IntToStr(Hhandle)+#13#10+
'-------------------------------------'+#13#10+
'OrderHandle: '+IntToStr(OrderHandle)+#13#10+
'MagicNumber: '+IntToStr(Mmagic)+#13#10+
'OrderComment: '+(Ccomment)+#13#10+
'-------------------------------------'+#13#10+
'Symbol: '+(Ssymbol)+#13#10+
'Lot size: ' +FloatToStr(Llot)),PChar('Trade Summary'), MB_OK);
Resume();
end;
end;
{-----Adjust Trailing Stop--------------------------------------------------}
Procedure TS;
begin
if (OrdersTotal > 0) then
Begin
if (j > 0) then
begin
if (Bid-BidPrevious>=TrailingTrigger*Point) then
Begin
Hhour := HourOf(TimeCurrent);
Mminute := MinuteOf(TimeCurrent);
Ssecond := SecondOf(TimeCurrent);
Mmillisecond := MilliSecondOf(TimeCurrent);
BidGain:=Bid-BidPrevious;
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
if (x = 0) then StopLossOriginal := OrderStopLoss;
StopLossCurrent:=OrderStopLoss;
if not TStepBoolean then TrailingValue := BidGain;
if TStepBoolean then TrailingValue := TrailingStep*Point;
ModifyOrder(OrderTicket,OrderOpenPrice,OrderStopLoss+TrailingValue,OrderTakeProfit);
OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
StopLossNew:=OrderStopLoss;
StopLossTotal:=StopLossNew-StopLossOriginal;
x:=x+1;
if tsBoolean=True then TSSW;
end;
end;
PreHhour := Hhour;
PreMminute := Mminute;
PreSsecond := Ssecond;
PreMmillisecond := Mmillisecond;
BidPrevious:=Bid;
j:=j+1;
end;
end;
{-----Calculate SMA---------------------------------------------------------}
function GetSMA(period: integer): double;
var
i: integer;
sum: double;
begin
sum := 0;
for i:=0 to period - 1 do
sum := sum + Close(i);
result := sum/period;
end;
{-----Process single tick---------------------------------------------------}
procedure GetSingleTick; stdcall;
var
tm, BeginDateTime, EndDateTime, StartDayTime, StopDayTime: TDateTime;
sma1, sma2: Double;
begin
SetCurrencyAndTimeFrame(SymbolName, Timeframe);
if BuySMABoolean or SellSMABoolean then
Begin
if (Bars > period1) and (Bars > period2) then
begin
sma1 := GetSMA(period1);
sma2 := GetSMA(period2);
if SellSMABoolean and (sma1 < sma2) then CloseOrder(OrderHandle);
end;
end;
if TrailingBoolean then TS;
tm := Time(0);
BeginDateTime := EncodeDate(BeginYear, BeginMonth, BeginDay);
EndDateTime := EncodeDate(EndYear, EndMonth, EndDay);
StartDayTime := EncodeTime(StartHour, StartMinute, StartSecond, StartMillisecond);
StopDayTime := EncodeTime(StopHour, StopMinute, StopSecond, StopMillisecond);
if (OrdersTotal = 0) then
begin
if BuySMABoolean and (sma1 > sma2) then
begin
if (DateOf(tm) >= BeginDateTime) and (DateOf(tm) <= EndDateTime) then //Time Period
Begin
if (TimeOf(tm) >= StartDayTime) and (TimeOf(tm) <= StopDayTime) then //Daily trading hours
begin
SendInstantOrder(SymbolName, op_Buy, Lot, Ask - StopLoss*Point, Ask + TakeProfit*Point, 'Test', 7, OrderHandle);
if vBoolean=True then TSW;
j:=0;
x:=0;
end;
end;
end;
if not BuySMABoolean then
begin
if (DateOf(tm) >= BeginDateTime) and (DateOf(tm) <= EndDateTime) then //Time Period
Begin
if (TimeOf(tm) >= StartDayTime) and (TimeOf(tm) <= StopDayTime) then //Daily trading hours
begin
SendInstantOrder(SymbolName, op_Buy, Lot, Ask - StopLoss*Point, Ask + TakeProfit*Point, 'Test', 7, OrderHandle);
if vBoolean=True then TSW;
j:=0;
x:=0;
end;
end;
end;
end;
end;
exports
InitStrategy,
DoneStrategy,
ResetStrategy,
GetSingleTick;
Begin
end.