#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
extern double Lots = 0.01;
extern int Magic = 12345;
extern int Slippage = 30;
extern int Lots_Step = 50;
extern int Profit_Dist = 50;
extern int Profit_Dist_Step = 20;
extern int TryCount = 10;
double price_1, price_2;
double buy_up_1, buy_up_2, buy_up_3, buy_down_1, buy_down_2, buy_down_3, sell_up_1, sell_up_2, sell_up_3, sell_down_1, sell_down_2, sell_down_3;
double buy_lots, sell_lots, sl;
int err, aticket;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
price_1 = NormalizeDouble(Bid, 3);
if(Bid - price_1 < 0) // Это добавлено на случай округления в большую сторону
{ // например: 1,20285 округляется как 1,203, а нужно, чтобы
price_1 = price_1 - 0.001; // 1,202
}
buy_up_1 = NormalizeDouble(price_1 + Lots_Step * Point, Digits);
buy_up_2 = NormalizeDouble(buy_up_1 + Lots_Step * Point, Digits);
buy_up_3 = NormalizeDouble(buy_up_2 + Lots_Step * Point, Digits);
buy_down_1 = NormalizeDouble(buy_up_1 - Lots_Step * Point, Digits);
buy_down_2 = NormalizeDouble(buy_down_1 - Lots_Step * Point, Digits);
buy_down_3 = NormalizeDouble(buy_down_2 - Lots_Step * Point, Digits);
sell_up_1 = NormalizeDouble(buy_up_1 + (Lots_Step / 2) * Point, Digits);
sell_up_2 = NormalizeDouble(sell_up_1 + Lots_Step * Point, Digits);
sell_up_3 = NormalizeDouble(sell_up_2 + Lots_Step * Point, Digits);
sell_down_1 = NormalizeDouble(sell_up_1 - Lots_Step * Point, Digits);
sell_down_2 = NormalizeDouble(sell_down_1 - Lots_Step * Point, Digits);
sell_down_1 = NormalizeDouble(sell_down_2 - Lots_Step * Point, Digits);
if(ExistPosByPrice(Symbol(), OP_BUYSTOP, Magic, buy_up_1) == False)
OrderSendX(Symbol(), OP_BUYSTOP, Lots, buy_up_1, Slippage, 0, 0, "", Magic, 0, clrNONE);
if(ExistPosByPrice(Symbol(), OP_BUYSTOP, Magic, buy_up_2) == False)
OrderSendX(Symbol(), OP_BUYSTOP, Lots, buy_up_2, Slippage, 0, 0, "", Magic, 0, clrNONE);
if(ExistPosByPrice(Symbol(), OP_BUYSTOP, Magic, buy_up_3) == False)
OrderSendX(Symbol(), OP_BUYSTOP, Lots, buy_up_3, Slippage, 0, 0, "", Magic, 0, clrNONE);
if(ExistPosByPrice(Symbol(), OP_BUYLIMIT, Magic, buy_down_1) == False)
OrderSendX(Symbol(), OP_BUYLIMIT, Lots, buy_down_1, Slippage, 0, 0, "", Magic, 0, clrNONE);
if(ExistPosByPrice(Symbol(), OP_BUYLIMIT, Magic, buy_down_2) == False)
OrderSendX(Symbol(), OP_BUYLIMIT, Lots, buy_down_2, Slippage, 0, 0, "", Magic, 0, clrNONE);
if(ExistPosByPrice(Symbol(), OP_BUYLIMIT, Magic, buy_down_3) == False)
OrderSendX(Symbol(), OP_BUYLIMIT, Lots, buy_down_3, Slippage, 0, 0, "", Magic, 0, clrNONE);
if(ExistPosByPrice(Symbol(), OP_SELLLIMIT, Magic, sell_up_1) == False)
OrderSendX(Symbol(), OP_SELLLIMIT, Lots, sell_up_1, Slippage, 0, 0, "", Magic, 0, clrNONE);
if(ExistPosByPrice(Symbol(), OP_SELLLIMIT, Magic, sell_up_2) == False)
OrderSendX(Symbol(), OP_SELLLIMIT, Lots, sell_up_2, Slippage, 0, 0, "", Magic, 0, clrNONE);
if(ExistPosByPrice(Symbol(), OP_SELLLIMIT, Magic, sell_up_3) == False)
OrderSendX(Symbol(), OP_SELLLIMIT, Lots, sell_up_3, Slippage, 0, 0, "", Magic, 0, clrNONE);
if(ExistPosByPrice(Symbol(), OP_SELLSTOP, Magic, sell_down_1) == False)
OrderSendX(Symbol(), OP_SELLSTOP, Lots, sell_down_1, Slippage, 0, 0, "", Magic, 0, clrNONE);
if(ExistPosByPrice(Symbol(), OP_SELLSTOP, Magic, sell_down_2) == False)
OrderSendX(Symbol(), OP_SELLSTOP, Lots, sell_down_2, Slippage, 0, 0, "", Magic, 0, clrNONE);
if(ExistPosByPrice(Symbol(), OP_SELLSTOP, Magic, sell_down_3) == False)
OrderSendX(Symbol(), OP_SELLSTOP, Lots, sell_down_3, Slippage, 0, 0, "", Magic, 0, clrNONE);
for(int b = 0; b <= OrdersTotal() - 1; b ++)
{
if(OrderSelect(b, SELECT_BY_POS, MODE_TRADES))
{
if(OrderType() == OP_BUY)
{
if(Bid - OrderOpenPrice() > (Profit_Dist + Profit_Dist_Step) * Point)
{
sl = NormalizeDouble(OrderOpenPrice() + Profit_Dist * Point, Digits);
if(!OrderModifyX(OrderTicket(), OrderOpenPrice(), sl, 0, 0, clrNONE))
Print("Не удалось модифицировать ордер на покупку!");
}
}
if(OrderType() == OP_SELL)
{
if(OrderOpenPrice() - Ask > (Profit_Dist + Profit_Dist_Step) * Point)
{
sl = NormalizeDouble(OrderOpenPrice() - Profit_Dist * Point, Digits);
if(!OrderModifyX(OrderTicket(), OrderOpenPrice(), sl, 0, 0, clrNONE))
Print("Не удалось модифицировать ордер на продажу!");
}
}
}
}
for(int c = 0; c <= OrdersTotal() - 1; c ++)
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if(OrderType() == OP_BUY)
buy_lots = buy_lots + OrderLots();
if(OrderType() == OP_SELL)
sell_lots = sell_lots + OrderLots();
}
}
Comment("buy_lots = ", buy_lots, " sell_lots = ", sell_lots);
return;
}
//+------------------------------------------------------------------+
int OrderSendX(string symbol, // символ
int cmd, // торговая операция
double volume, // количество лотов
double price, // цена
int slippage, // проскальзывание
double stoploss, // stop loss
double takeprofit, // take profit
string comment=NULL, // комментарий
int magic=0, // идентификатор
datetime expiration=0, // срок истечения ордера
color arrow_color=clrNONE // цвет
)
{
err = GetLastError();
err = 0;
bool exit_loop = false;
int cnt = 0;
while(!exit_loop)
{
if(IsTradeAllowed())
{
aticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic, expiration, arrow_color);
err = GetLastError();
}
switch(err)
{
case ERR_NO_ERROR: exit_loop = true; break;
case ERR_SERVER_BUSY:
case ERR_NO_CONNECTION:
case ERR_INVALID_PRICE:
case ERR_OFF_QUOTES:
case ERR_BROKER_BUSY:
case ERR_TRADE_CONTEXT_BUSY:
case ERR_TRADE_TIMEOUT:
cnt++;
break;
case ERR_PRICE_CHANGED:
case ERR_REQUOTE:
RefreshRates();
continue;
default: exit_loop = true;
break;
} // switch(err)
if (cnt > TryCount)
exit_loop = true;
if(!exit_loop)
{
Sleep(1000);
RefreshRates();
}
if(exit_loop)
{
if(err != ERR_NO_ERROR)
{
Print ("Ошибка: " + IntegerToString(err));
}
}
if (err == ERR_NO_ERROR)
{
if (OrderSelect(aticket, SELECT_BY_TICKET, MODE_TRADES))
return (aticket);
else return (-1);
Print("Ошибка открытия ордера после " + IntegerToString(cnt) + " попыток.");
Print("Ошибка: " + IntegerToString(err));
}
} // while(!exit_loop)
return(-1);
} // OrderSendX()
//+------------------------------------------------------------------+
bool OrderModifyX (int ticket, // номер ордера
double price, // цена открытия
double stoploss, // stop loss
double takeprofit, // take profit
datetime expiration, // время истечения ордера
color arrow_color)
{
if(IsStopped())
{
Print("Ошибка: советник остановлен, IsStopped == true");
return(false);
}
int cnt = 0;
while(!IsTradeAllowed() && cnt <TryCount)
{
Sleep(500);
cnt++;
}
if(!IsTradeAllowed())
{
Print("Ошибка: операция недопустима - IsTradeAllowed() == false.");
return(false);
}
if(OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES))
{
string sym = OrderSymbol();
int digits = int (MarketInfo(sym, MODE_DIGITS));
if(digits > 0)
{
price = NormalizeDouble(price, digits);
stoploss = NormalizeDouble(stoploss, digits);
takeprofit = NormalizeDouble(takeprofit, digits);
}
}
err = GetLastError();
err = 0;
bool exit_loop = false;
bool result = false;
while(!exit_loop)
{
result = OrderModify(ticket, price, stoploss, takeprofit, expiration, arrow_color);
err = GetLastError();
if(result == true)
return(true);
switch(err)
{
case ERR_NO_ERROR:
case ERR_NO_RESULT:
exit_loop = true;
break;
case ERR_SERVER_BUSY:
case ERR_NO_CONNECTION:
case ERR_INVALID_PRICE:
case ERR_OFF_QUOTES:
case ERR_BROKER_BUSY:
case ERR_TRADE_CONTEXT_BUSY:
case ERR_TRADE_TIMEOUT:
cnt++;
break;
case ERR_PRICE_CHANGED:
case ERR_REQUOTE:
RefreshRates();
continue;
default: exit_loop = true;
break;
} // switch(err)
if(cnt > TryCount)
exit_loop = true;
if(!exit_loop)
{
Print("Ошибка! Попыток: " + IntegerToString(cnt) + "/" + IntegerToString(TryCount));
Sleep(500);
RefreshRates();
}
if(exit_loop)
{
if(err != ERR_NO_ERROR && err != ERR_NO_RESULT)
Print("Ошибка: " + IntegerToString(err));
}
} // while(!exit_loop)
if(err == ERR_NO_RESULT)
{
return(true);
}
Print("Ошибка модификации после " + IntegerToString(cnt) + " попыток.");
return(false);
} // bool OrderModifyX
//+------------------------------------------------------------------+
bool ExistPosByPrice(string sy, int op, int mn, double pp)
{
double px, py;
int d, i, k=OrdersTotal();
for (i=0; i<k; i++)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if ((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op))
{
// if (OrderType()==OP_BUY || OrderType()==OP_SELL) // Это условие посчитал не нужным.
// {
if (mn<0 || OrderMagicNumber()==mn)
{
d=MarketInfo(OrderSymbol(), MODE_DIGITS);
px=NormalizeDouble(pp, d);
py=NormalizeDouble(OrderOpenPrice(), d);
if (pp<=0 || px==py)
return(True);
}
// }
}
}
}
return(False);
}
//+------------------------------------------------------------------+