//+------------------------------------------------------------------+ //| Spreader_v1.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"); 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); // Выбираем направление позиций для инструментов if ((x1 * b) > (y1 * a)) { currenttype = OP_BUY; } } 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); } //+------------------------------------------------------------------+