#property strict
// Следующая задача.
// Нужно написать советник, который подсчитывает и выводит (через Comment)
// количество открытых ордеров соответствующих инструменту своего графика.
// Пример: советник запущен на графике EURUSD, подсчитываем только ордера EURUSD,
// а другие игнорируем. Если открытых ордеров нет, то советник открывает один ордер.
// Направление открытия (buy/sell) советник определяет следующим образом:
// если Close[1] > Close[3]+N*Point, то открывается ордер Buy, а если Close[1] < Close[3]-N*Point,
// то открывается ордер Sell. Значение переменной N (в пунктах), а также MagicNumber, StopLoss и TakeProfit
// нужно вывести во входные параметры (input).
// Советник нужно протестировать в тестере стратегий.
//+------------------------------------------------------------------+
input double Lots = 0.01; // Lots:
input int Delta_N = 25; // Delta:
input double TakeProfit = 300; // Take Profit:
input double StopLoss = 100; // Stop Loss:
input int Magic = 12345; // Magic Number:
input int Slippage = 3; // Slippage:
//+------------------------------------------------------------------+
int slipp, del, ticket;
double point, lot, SL, TP;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//----Определение пяти значного брокера
point = _Point;
if(_Digits == 3 || _Digits == 5)
{
point = 10.0 * point;
slipp = Slippage * 10;
}
//---
lot = Lots;
del = Delta_N;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
int OT=0;
//--- получим минимальное значение Stop level
double minstoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
Print("Minimum Stop Level=",minstoplevel," points");
//--- вычисленные значения цен SL и TP должны быть нормализованы
// double stoploss=NormalizeDouble(Bid-minstoplevel*Point,Digits);
// if (StopLoss<stoploss) StopLoss=stoploss;
// double takeprofit=NormalizeDouble(Bid+minstoplevel*Point,Digits);
// if (TakeProfit<takeprofit) TakeProfit=takeprofit;
double minlot = MarketInfo(Symbol(),MODE_MINLOT); // узнаем каков минимальный размер лота
Print("Minimal lot=",minlot," lots");
double maxlot = MarketInfo(Symbol(),MODE_MAXLOT); // узнаем каков максимальный размер лота
Print("Maximal lot=",maxlot," lots");
//---
// функциz OrdersCount()написана правильно, а вот использована нет.
// Что бы правильно использовать функцию, не обязательно знать как она устроена. Важно знать что она делает, что возвращает, какие аргументы.
// Первый аргумент у неё тип ордера. Вы указали 0, а это OP_BUY. Соответственно, она только Buy и считает.
// Нужно понимать что функция это программа, которая выполняется компьютером. На это уходят ресурсы компьютера.
// А переменная это кусочек памяти, для обращения к ней ресурсов практически не надо.
/*if (OrdersCount(0,Magic)>=0) Comment (OrdersCount(0,Magic));
else
if (OrdersCount(0,Magic)<1)*/
// Вы тут трижды вызвали функцию. А можно было один раз вызвать, результат загнать в переменную,
// потом обращаться к ней сколько угодно раз. К экономии ресурсов надо привыкать с самого начала.
int OrdersBuy=OrdersCount(OP_BUY,Magic); //Посчитали Buy ордера
int OrdersSell=OrdersCount(OP_SELL,Magic);//Посчитали Sell ордера
OT = OrdersBuy+OrdersSell; // Сумировали ордера BUY и SELL
Comment("Buy Orders ",OrdersBuy,"\nSell Orders ",OrdersSell);
// В условиях открытия ордеров использовано OrdersTotal()<1. А OrdersTotal() возвращает количество ордеров
// независимо от типа, символа и маджика. А между тем уже есть посчитанные ордера с учётом символа и маджика функцией OrdersCount().
// Стоит использовать эти данные, а не OrdersTotal().
for(int i=0;i<OT;i++)
{
{
if (lot >= minlot && lot <= maxlot )
{
//--- размещаем рыночный ордер на покупку 1 лота
// if (OrdersTotal()<1 && Close[1] > Close[3]+Delta_N*Point)
if (OT==0 && Close[i+1] > Close[i+3]+Delta_N*Point)
{
ticket=OrderSend(Symbol(),OP_BUY,lot,Ask,Slippage,0,0,"My order BUY",Magic,0,clrGreen);
if(ticket<0)
{
SL = NormalizeDouble(Ask - StopLoss*Point,Digits);
TP = NormalizeDouble(Ask + TakeProfit*Point,Digits);
if (OrderSelect(ticket,SELECT_BY_TICKET))
if (OrderModify(ticket,OrderOpenPrice(),SL,TP,0,clrRed) == true)
Print ("Ошибка модификации ордера на продажу");
} else Print("Ошибка открытия ордера на продажу");
}
//--- размещаем рыночный ордер на продажу 1 лота
if (OT==0 && Close[i+1] < Close[i+3]-Delta_N*Point)
{
ticket=OrderSend(Symbol(),OP_SELL,lot,Bid,Slippage,0,0,"My order BUY",Magic,0,clrGreen);
if(ticket<0)
{
SL = NormalizeDouble(Bid + StopLoss*Point,Digits);
TP = NormalizeDouble(Bid - TakeProfit*Point,Digits);
if (OrderSelect(ticket,SELECT_BY_TICKET))
if (OrderModify(ticket,OrderOpenPrice(),SL,TP,0,clrRed) == true)
Print ("Ошибка модификации ордера на продажу");
} else Print("Ошибка открытия ордера на продажу");
}
//else {return;}
}
}
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Подсчет ордеров по символу |
//+------------------------------------------------------------------+
int OrdersCount(int type, int MagicNum)
{
int orders = 0;
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == _Symbol && OrderMagicNumber() == MagicNum)
{
if(OrderType() == type)orders++;
}
}
}
return orders;
}