SAR Trading v2





//+------------------------------------------------------------------+
//|                                               SAR Trading v2.mq4 |
//|                                        Copyright © 2005, Cronex. |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Cronex"
#include <stdlib.mqh>
#include <stderror.mqh>
//----
extern double Lots           = 0.1;
extern double MaximumLots    = 0.5;
extern double TakeProfit     = 100;
extern double StopLoss       = 15;
extern double TrailingStep   = 1;
extern double MaximumRisk    = 0.025;
extern double DecreaseFactor = 20;
extern double MAPeriod       = 18;
extern double MAShift        = 2;
//----
#define MAGICSAR  19680213
//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int Buys = 0, Sells = 0;
//----
   for(int i = 0; i < OrdersTotal(); i++)
     {
       if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) 
           break;
       //----
       if(OrderSymbol() == Symbol() && OrderMagicNumber() == MAGICSAR)
         {
           if(OrderType() == OP_BUY)  
               Buys++;
           //----
           if(OrderType()==OP_SELL) 
               Sells++;
         }
     }
//---- return orders volume
   if(Buys > 0) 
       return(Buys);
   else
       return(-Sells);
  }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double LotsOptimized()
  {
   double Lot = Lots;
   int    orders = HistoryTotal();     // history orders total
   int    losses = 0;                  // number of losses orders without a break
//---- select lot size
   Lot = NormalizeDouble(AccountFreeMargin()*MaximumRisk / 1000.0, 1);
//---- calcuulate number of losses orders without a break
   if(DecreaseFactor > 0)
     {
       for(int i = orders - 1; i >= 0; i--)
         {
           if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) == false) 
             { 
               Print("Error in history!"); 
               break; 
             }
           //----
           if(OrderSymbol() != Symbol() || OrderType() > OP_SELL) 
               continue;
           //----
           if(OrderProfit() > 0) 
               break;
           //----
           if(OrderProfit() < 0) 
               losses++;
         }
       if(losses > 1) 
           Lot = NormalizeDouble(Lot - Lot*losses / DecreaseFactor, 1);
     }
//---- return lot size
   if(Lot < 0.1) 
       Lot = 0.1;
   if(MaximumLots != 0 && Lot > MaximumLots) 
       Lot = MaximumLots;
   return(Lot);
  }  
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OrderTrailingStop()
  {
   if(StopLoss > 0)
     {
       for(int i = 0; i < OrdersTotal(); i++)
         {
           if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) 
               break;
           if(OrderSymbol() == Symbol() && OrderMagicNumber() == MAGICSAR)
             {
               if(OrderType() == OP_BUY)
                 {
                   if(Bid - OrderOpenPrice() > Point*(StopLoss + TrailingStep) && 
                      OrderStopLoss()<Bid-Point*(StopLoss+TrailingStep))
                       ErrorCheckOut(OrderModify(OrderTicket(), 0, Bid - Point*(StopLoss), 
                                     OrderTakeProfit(), 0, Blue));
                 }
               if(OrderType() == OP_SELL)
                 {
                   if(OrderOpenPrice() - Ask > Point*(StopLoss+TrailingStep) && 
                      OrderStopLoss() > Ask + Point*(StopLoss + TrailingStep))
                       ErrorCheckOut(OrderModify(OrderTicket(), 0, Ask + Point*(StopLoss), 
                                     OrderTakeProfit(), 0, Blue));
                 }
             }
         }
     }
//----
  }  
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
  {
   double SAR,MA;
   SAR = iSAR(NULL, 0, 0.02, 0.2, 0);
   MA = iMA(NULL, 0, MAPeriod, MAShift, MODE_SMA, PRICE_MEDIAN, 0);
//============================== Ïîêóïêà ============================     
   if(SAR < MA || iClose(NULL, 0, MAShift) < MA)
     {
       ErrorCheckOut(OrderSend(Symbol(), OP_BUY, LotsOptimized(), Ask, 3, 
                     Bid - StopLoss*Point, Ask + TakeProfit*Point, "", MAGICSAR, 
                     0, Lime));
     }
//============================== Ïðîäàæà ============================
   else     
       if(SAR > MA || iClose(NULL, 0, MAShift) > MA)
         {
           ErrorCheckOut(OrderSend(Symbol(), OP_SELL, LotsOptimized(), Bid, 3, 
                         Ask + StopLoss*Point, Bid - TakeProfit*Point , "", 
                         MAGICSAR, 0, DarkOrange));
         }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ErrorCheckOut(bool LastErr)
  {
    int Error;
    if(LastErr != TRUE) 
      { 
        Error = GetLastError(); 
        if(Error != 0)
            Print("LastError = ",Error," : ",ErrorDescription(Error)); 
      }
  }    
//+------------------------------------------------------------------+
//| Start of expert                                                  |
//+------------------------------------------------------------------+
int start()
  {
   if(Bars < 100 || IsTradeAllowed() == false) 
       return;
   if(CalculateCurrentOrders(Symbol()) == 0) 
       CheckForOpen();
   else
       OrderTrailingStop(); 
  }
//+------------------------------------------------------------------+



Sample





Analysis



Market Information Used:

Series array that contains close prices for each bar


Indicator Curves created:


Indicators Used:

Parabolic Stop and Reverse system
Moving average indicator


Custom Indicators Used:

Order Management characteristics:
Checks for the total of open orders

It can change open orders parameters, due to possible stepping strategy

Other Features: