Navigation:Home > Content >

Spreader_v2.mq4

Time: 2010-03-28 | Download file:Spreader_v2.mq4

//+------------------------------------------------------------------+
//|                                                  Spreader_v2.mq4 |
//|                               Copyright © 2010, Yury V. Reshetov |
//|                                         http://spreader.heigh.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2010, Yury V. Reshetov"
#property link      "http://spreader.heigh.ru"

extern string seconds_instrument = "GBPUSD";
extern double lots = 1; // Объем позиции для текущей пары
extern double profit = 100;

static int prevtime = 0;
static bool openbarspriceonly = true;
static int period = 30;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   prevtime = Time[0];
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   if (Period() != PERIOD_M1) {
      Alert("Change timeframe for " + Symbol() + " to M1");
      return(0);
   }

   if ((Time[0] == prevtime) && openbarspriceonly) {
      return(0);
   }
   
   if (! IsTradeAllowed()) {
      Comment("Trades disallow");
      return(0);
   }
   
   prevtime = Time[0];

   int total = OrdersTotal();
   int currentticket = -1;
   int secondticket = -1;
   
   // Направление позиции для текущего инструмента
   int currenttype = OP_SELL;
   // Направление позиции для второго инструмента
   int secondtype = OP_BUY;

   double currentprofit = 0;
   
    double secondlots = 0;

   for (int i = 0; i < total; i++) {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() == Symbol()) {
         currentticket = OrderTicket();
         currentprofit = currentprofit + OrderProfit();
         currenttype = OrderType();
      }
      if (OrderSymbol() == seconds_instrument) {
         secondticket = OrderTicket();
         secondtype = OrderType();
         currentprofit = currentprofit + OrderProfit();
         secondlots = OrderLots();
      }
   }


   if ((secondticket < 0) && (currentticket >= 0)) {
      Comment("Try close positon for " + Symbol());
      if (currenttype == OP_BUY) {
         if (OrderClose(currentticket, lots, Bid, 2, Blue)) {
            openbarspriceonly = true;
         }
         return(0);
      } else {
         if (OrderClose(currentticket, lots, Ask, 2, Red)) {
            openbarspriceonly = true;
         }
         return(0);
      }
   }

   if ((secondticket >= 0) && (currentticket >= 0)) {
      openbarspriceonly = false;
      if (currentprofit > profit) {
         if (secondtype == OP_BUY) {
            OrderClose(secondticket, secondlots, MarketInfo(seconds_instrument, MODE_BID), 2, Blue);
            return(0);
         } else {
            OrderClose(secondticket, secondlots, MarketInfo(seconds_instrument, MODE_ASK), 2, Red);
            return(0);
         }
      }
      // Позиции по обоим инструментам уже открыты
      Comment("Positions for " + Symbol() + " and " + seconds_instrument + " is open.\nTotal profit: $" + currentprofit);
      return(0);
   }

   openbarspriceonly = true;

   if ((secondticket >= 0) && (currentticket < 0)) {
      Comment("Try open positon for " + Symbol());
      // Открываем позицию для текущего символа 
      // в противоположном направлении позиции второго инструмента
      if (secondtype == OP_SELL) {
         currentticket = OrderSend(Symbol(), OP_BUY, lots, Ask, 2, 0, 0, WindowExpertName(), 0, 0, Blue); 
      } else {
         currentticket = OrderSend(Symbol(), OP_SELL, lots, Bid, 2, 0, 0, WindowExpertName(), 0, 0, Red); 
      }
      return(0);
   }
   
   if (MarketInfo(Symbol(), MODE_LOTSIZE) != MarketInfo(seconds_instrument, MODE_LOTSIZE)) {
      Alert("Contracts size not equals. Change instruments");
      return(0);
   }

   // Ищем первые разности для двух периодов обоих инструментов

   double x1 = Close[0] - Close[period]; 
   double x2 = Close[period] - Close[period * 2]; 
   double y1 = iClose(seconds_instrument, Period(), 0) - iClose(seconds_instrument, Period(), period); 
   double y2 = iClose(seconds_instrument, Period(), period) - iClose(seconds_instrument, Period(), period * 2); 
//----

   // Ищем условия для корреляции
   
   if ((x1 * x2) > 0) {
      // На обоих участках однонаправленный тренд
      // корреляции вычислить не удается
      Comment(Symbol() + " trend found");
      return(0); 
   }

   if ((y1 * y2) > 0) {
      // На обоих участках однонаправленный тренд
      // корреляции вычислить не удается
      Comment(seconds_instrument + " trend found");
      return(0);
   }
   
   // Направление позиции для текущего инструмента

   if ((x1 * y1) > 0) {
      
      // Имеем дело с положительной корреляцией
      
      double a = MathAbs(x1) + MathAbs(x2);
      double b = MathAbs(y1) + MathAbs(y2);
      
      if ((a / b) > 3.0) {
         return(0);
      }
      
      if ((a / b) < 0.3) {
         return(0);
      }

      // Объем позиции для второго инструмента
      secondlots = NormalizeDouble(a  * lots / b, 2);
      
      // Считаем диапазоны за последние 24 часа
      double x3 = Close[0] - Close[1440];
      double y3 = iClose(seconds_instrument, Period(), 0) - iClose(seconds_instrument, Period(), 1440);
      
      // Выбираем направление позиций для инструментов
      if ((x1 * b) > (y1 * a)) {
         // Дополнительная проверка за последние 24 часа
         if ((x3 * b) < (y3 * a)) {
            Comment("False testimony");
            return(0); // Ложный сигнал
         }
         currenttype = OP_BUY;
      } else {
         // Дополнительная проверка за последние 24 часа
         if ((x3 * b) > (y3 * a)) {
            Comment("False testimony");
            return(0);  // Ложный сигнал
         }
      }
   } else {
      // Имеем дело с отрицательной корреляцией
      Comment("Negative correlation found");
      return(0);
   }

   // Открываем позицию для второго инструмента
   
   if (currenttype == OP_SELL) {
      secondticket = OrderSend(seconds_instrument, OP_BUY, secondlots, MarketInfo(seconds_instrument, MODE_ASK), 2, 0, 0, WindowExpertName(), 0, 0, Blue); 
   } else {
      secondticket = OrderSend(seconds_instrument, OP_SELL, secondlots, MarketInfo(seconds_instrument, MODE_BID), 2, 0, 0, WindowExpertName(), 0, 0, Red); 
   }
   
   if (secondticket >= 0) {
      openbarspriceonly = false;
   }

   return(0);
  }
//+------------------------------------------------------------------+

Recommend