TrailingStop and SMA combo strategy with Trading Periods

Examples step by step how to make your own automated strategy or user indicator
Message
Author
Lonesome
Posts: 28
Joined: Fri Oct 21, 2016 9:04 am

TrailingStop and SMA combo strategy with Trading Periods

#1 Postby Lonesome » Sat Nov 26, 2016 9:45 am

Below is a strategy that allows you to test the dependency of trading results on TrailingStop, TrailingStep, StopLoss, TakeProfit and SMA.
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.

Return to “Programming lessons”

Who is online

Users browsing this forum: No registered users and 30 guests