extern double lot = 0.1; // открываемый лот
extern int workLimit = 10; // уровень отклонения
extern int openSet = 1; // открываемая серия
extern int slippage = 2; // проскальзывание
// массив валютных пар, по которым откроются ордера
string pairs[28] = {"AUDUSD", "NZDJPY", "GBPCHF"};-----дописать пары
int pairsOpen[28], // кол-во открытых ордеров по каждой валютной паре
totalPairs; // кол-во валютных пар в массиве
// цена открытия текущего бара для всех валютных пар
double openPrice[28];
int number, // множитель для 5 или 4 знаков после запятой
magic, // магическое число
lastError, // код последней ошибки
count, // кол-во открытых ордеров
orderType; // тип ордера (Buy или Sell)
bool work; // флаг работы
void init()
{
// чтобы не путаться с пунктами
if (Digits == 3 || Digits == 5)
{
number = 10;
}
else
{
number = 1;
}
totalPairs = 0;
int i,
size = ArraySize(pairs); // ранг массива
for (i = 0; i < size; i++)
{
if (StringLen(pairs) > 0) // если элемент не пустой
{
totalPairs++; // увеличиваем кол-во пар
}
else
{
break; // иначе выходим из цикла
}
}
orderType = 0; // тип ордера Buy (рыночный)-если 1 то Sell
magic = 100101; // магическое число советника
lastError = 0; // код последней ошибки
work = true; // флаг, разрешающий работу
count = 0; // кол-во открытых ордеров
setOpenPrices();
loadOrders();
return;
}
void start()
{
loadOrders(); // обновляем список ордеров
criteria(); // проверяем условия
return;
}
void criteria()
{
if (checkOpenPrices() && work) // если новый бар и работа разрешена
{
openOrders(); // открываем ордера
}
else if (count < totalPairs // если кол-во ордеров меньше пар
&& work == false) // и работа запрещена
{
openOrders(); // также открываем ордера
}
}
void openOrders()
{
int i, total;
for (i = 0; i < totalPairs; i++) // проход по всем вал. парам
{
if (pairsOpen < openSet) // если номер сета не задан
{
if (openOrder(orderType, i)) // открываем ордер
{
pairsOpen = openSet; // записываем номер сета
total++; // увеличиваем счетчик
}
}
}
Alert("Buy X: всего открыто - " + total); // выводим сообщение
work = false; // запрещаем работу
setOpenPrices(); // обновляем цены открытия
}
bool openOrder(int type, int pairNumber)
{
int ticket = -1; // номер тикета
double bid, // цена Bid
price, // цена, по к-й будет открытие ордера
open, // цена открытия бара
pt, // размер пункта
SL = 0; // стоп-лосс
string symb = pairs[pairNumber]; // финансовый инструмент
open = iOpen(symb, 0, 0); // узнаем цену открытия
pt = MarketInfo(symb, MODE_POINT); // узнаем размер пункта, примеру (0.0001)
while (ticket < 0) // пока открытие ордера не будет успешным
{
switch(type) // тип ордера Buy или Sell
{
// Buy
case 0:
price = MarketInfo(symb, MODE_ASK); // цена Ask
bid = MarketInfo(symb, MODE_BID); // цена Bid
if ((bid - open) / pt > workLimit * number) // если цена ушла от
{ // цены открытия бара
return (false); // на расстояние
} // больше заданного в
// workLimit, выходим
break;
// Sell
case 1:
price = MarketInfo(symb, MODE_BID); // цена Bid
if ((open - price) / pt > workLimit * number)
{
return (false);
}
break;
}
// отправляем запрос
ticket = OrderSend(symb, type, lot, price, slippage * number, SL, 0,
DoubleToStr(openSet, 0), magic);
if (ticket < 0) // если ордер не открыт, ищем ошибку
{
lastError = GetLastError(); // получаем код последней ошибки
if (checkError() == false) // если ошибка критичная, выходим
{
return (false);
}
}
else // ордер успешно открыт
{
// успешно открыли позицию
return (true);
}
}
}
bool checkError()
{
if (lastError == 0)
{
return(false);
}
switch (lastError)
{
// Преодолимые ошибки
case 128: // Истек срок ожидания совершения сделки
case 129: // Неправильная цена
case 135: // Цена изменилась
case 138: // Новые цены
RefreshRates();
return(true);
case 136: // Нет цен
while (RefreshRates() == false)
{
Sleep(1);
}
return(true);
case 4: // Торговый сервер занят
case 6: // Нет связи с торговым сервером
case 137: // Брокер занят
case 146: // Подсистема торговли занята
Sleep(500);
RefreshRates();
return(true);
// Критические ошибки
case 2: // Общая ошибка
case 5: // Старая версия торгового терминала
case 64: // Счет заблокирован
case 133: // Торговля запрещена
default:
return(false);
}
}
void loadOrders()
{
ArrayInitialize(pairsOpen, 0); // обнуляем массив
count = 0;
int i,
totalOrders = OrdersTotal(), // всего ордеров
pairNumber; // номер вал. пары
for (i = 0; i < totalOrders; i++)
{
if (OrderSelect(i, SELECT_BY_POS) == true && // есть следующий ордер
OrderType() == orderType && // ордер нашего типа
OrderMagicNumber() == magic && // наше маг. число
StrToDouble(OrderComment()) == openSet) // наш сет
{
count++;
pairNumber = getPairNumber(OrderSymbol()); // получаем номер вал. пары
pairsOpen[pairNumber] = openSet; // обновляем кол-во отк. ордеров
}
}
if (count > 0) // если есть ордера на Buy
{
work = false; // запрещаем работу
}
}
void setOpenPrices()
{
int i;
for (i = 0; i < totalPairs; i++)
{
openPrice = iOpen(pairs, 0, 0);
}
}
bool checkOpenPrices()
{
int i;
for (i = 0; i < totalPairs; i++)
{
if (iOpen(pairs, 0, 0) != openPrice) // равна ли цена открытия
{ // в массиве openPrice[]
return (true); // текущей цене открытия
}
}
return (false);
}
int getPairNumber(string pair)
{
int i;
for (i = 0; i < totalPairs; i++)
{
if (pairs == pair) // если наша пара
{
return (i); // выходим из цикла
} // и функции
}
}
void deinit()
{
return;
}