Полезные функции от KimIV - страница 86

 

Игорь! Может подскажите? Что-то из индикатора (iMA) в советник значения с 4 знаками после запятой приходят, а надобно для работы 5 !? Попробовал NormalizeDouble(iMA,Digits) - всё равно 4 знака. Неужто надо весь индикатор переписывать в подпрограмму-функцию эксперта, чтобы 5 знаков получить?!!!

 

Справко: Alert(), Comment(), Print()

Данные типа double выводятся с 4 десятичными цифрами после точки.

Для вывода чисел с большей точностью используйте функцию DoubleToStr().

 

Добрый вечер,

Не могу справиться с правильным закрытием позиций. По условиям существует два условия закрытия: 1. если открыта одна позиция; 2. если открыто две (или больше позиций). В обоих случаях объём лота = 0.03. В первом случае лот закрывается раздельно по 0.01 (отработано в постах выше). Во втором случае два лота должны закрыться оба по 0.03. Соответственно если:

if (OrderType()==OP_BUY && BuyTotalOp==1)

то первый вариант закрытия и если:

if (OrderType()==OP_BUY && BuyTotalOp>1)

то другой (в моём варианте (предварительно) если сумма профита обоих позиций > 0, то должны закрываться обе позиции). Выглядит это так:

   extern double Lots=0.03;           // Жестко заданное колич. лотов
.................................
   // Учёт количества имеющихся ордеров
   Symb=Symbol();                               // Название фин.инстр.
   BuyTotalOp=0;                                // Количество Buy ордеров
   SellTotalOp=0;                               // Количество Sell ордеров
   for (int i=1; i<=OrdersTotal(); i++)         // Цикл перебора ордер
      {
      if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий
        {                                       // Анализ ордеров:
         if (OrderSymbol()!=Symb)continue;      // Не наш фин. инструм
         if (OrderType()>1)                     // Попался отложенный
           {
            Alert("Обнаружен отложенный ордер. Эксперт не работает.");
            return;                             // Выход из start()
           }
         if (OrderType()==OP_BUY)
           {
            BuyTotalOp++;                         // Счётчик ордеров Buy
......................................
   //Проверка если открыто несколько БАЙ-позиций
   if (OrderType()==OP_BUY && BuyTotalOp>1)        // Тип ордера бай и ордеров по циклу "с начала" = 1
     {
//....................................     
      //---- если условия закрытия нескольких лотов БАЙ
      if (BuyOrdProf>0)
        {
         //---- закрываем 1-ю часть позиции
         Alert("Попытка закрыть Buy ",TicketCl,". Ожидание ответа..");
         RefreshRates();                            // Обновление данных
         Ans=OrderClose(CloseTicketCl,Lots,Bid,0,Red);          // Закрытие Buy
         if (Ans==true)                             // Получилось :)
           { 
            Alert ("Закрыт ордер Buy ",TicketCl);
            break;                                  // Выход из цикла закр
           }
         if (Fun_Error(GetLastError())==1)          // Обработка ошибок
            continue;                               // Повторная попытка
         return;                                    // Выход из start()
        }
     }
//.........................................
   //Проверка если открыта одна БАЙ-позиция
   if (OrderType()==OP_BUY && BuyTotalOp==1)        // Тип ордера бай и ордеров по циклу "с начала" = 1
     {
//....................................     
      //---- если условия закрытия одного лота БАЙ
      if (BUYCLOSE_1PART && BuyClLot==Lots)
        {
         //---- закрываем 1-ю часть позиции
         Alert("Попытка закрыть Buy ",TicketCl,". Ожидание ответа..");
         RefreshRates();                            // Обновление данных
         Ans=OrderClose(CloseTicketCl,LotCloseBuy/3,Bid,0,Red);          // Закрытие Buy
         if (Ans==true)                             // Получилось :)
           { 
            Alert ("Закрыт ордер Buy ",TicketCl);
            break;                                  // Выход из цикла закр
           }
         if (Fun_Error(GetLastError())==1)          // Обработка ошибок
            continue;                               // Повторная попытка
         return;                                    // Выход из start()
        }
 

На деле получается, что при появлении условий для закрытия обоих лотов, первый закрывается полностью, а второй "принимает" на себя условия закртия BuyTotalOp==1 и закрывается по своим условиям.

Подскажите, что неправильно в условиях закрытия и как заставить закрыться оба лота одновременно? Заранее благодарен.

 
Попробовал и OrderTicket() и Lots подсчитывать и плюсовать в цикле перебора ордеров - безрезультатно... Может, как всегда, "истина где-то рядом", но не улавливается...
 

отделите мух от котлет.. напишите несколько полезных функций..

например, подсчет количества открытых ордеров по типу ордера, закрытие ордеров по типу ордера и т.п.

тогда все будет проще..

if (ordersTotal(SYMBOL,OP_BUY)==1) closeAllOrders(SLIPPAGE,TRY,TRADESLEEP,SHOWERRORS,SYMBOL,OP_BUY);
if (ordersTotal(SYMBOL,OP_BUY) > 1) closeAllOrders(SLIPPAGE,TRY,TRADESLEEP,SHOWERRORS,SYMBOL,OP_BUY);

а то у вас не хватает где-то } и становится вообще непонятно что именно делается.. то ли вы пытаетесь одно временно подсчитывать количества ордеров и тут же их удалять, то ли что ? отложенные ордера может имеет смысл пропускать, а не прерывать код при их наличии ?

хорошим вариантом будет функция, которая по заданным условиям будет формировать массив с параметрами открытых ордеров, пробежав по которому можно их и закрыть..в общем поработайте над структурой..

 

Спасибо keekkenen, я как раз всё последнее время думаю о создании массива. Просто ни разу не работал с ним и надеялся, что есть решение проще, что у меня уже "зашоренный" взгляд, а кто-нибудь со свежими глазами, посмотрев, скажет " да елки-палки, а где у тебя подсчёт такой-то...". Ведь есть же подсчёт всех ордеров бай в цикле:

   // Учёт количества имеющихся ордеров от начала к концу
   Symb=Symbol();                               // Название фин.инстр.
   BuyTotalOp=0;                                // Количество Buy ордеров
   SellTotalOp=0;                               // Количество Sell ордеров
   for (int i=1; i<=OrdersTotal(); i++)         // Цикл перебора ордер
      {
      if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий
        {                                       // Анализ ордеров:
         if (OrderSymbol()!=Symb)continue;      // Не наш фин. инструм
         if (OrderType()>1)                     // Попался отложенный
           {
            Alert("Обнаружен отложенный ордер. Эксперт не работает.");
            return;                             // Выход из start()
           }
         if (OrderType()==OP_BUY)
           {
            BuyTotalOp++;                         // Счётчик ордеров Buy
....................................

а OrderClose по ним не идёт...

   //Проверка если открыто несколько БАЙ-позиций
   if (OrderType()==OP_BUY && BuyTotalOp>1)        // Тип ордера бай и ордеров по циклу "с начала" = 1
     {
//....................................     
      //---- если условия закрытия нескольких лотов БАЙ
      if (BuyOrdProf>0)
        {
         //---- закрываем 1-ю часть позиции
         Alert("Попытка закрыть Buy ",TicketCl,". Ожидание ответа..");
         RefreshRates();                            // Обновление данных
         Ans=OrderClose(CloseTicketCl,BuyTotalOp,Bid,0,Red);          // Закрытие Buy
...................................................................
ну да это видно "перемудрение".......
 

и честно говоря я не понял вот этого

Ans=OrderClose(CloseTicketCl,Lots,Bid,0,Red);          // Закрытие Buy

и вот этого, особенно деление лота на 3 ?? ордер закрывается тем же лотом что и открывается..

Ans=OrderClose(CloseTicketCl,LotCloseBuy/3,Bid,0,Red);          // Закрытие Buy

почему не так в обоих случаях ?

Ans=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Red);          // Закрытие Buy
 

почему не так в обоих случаях ?

Ans=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Red);          // Закрытие Buy

CloseTicketCl = OrderTicket() в общем можно и так...

и вот этого, особенно деление лота на 3 ?? ордер закрывается тем же лотом что и открывается..

Ans=OrderClose(CloseTicketCl,LotCloseBuy/3,Bid,0,Red);          // Закрытие Buy

не тем же. Закрывается треть лота (по одному из условий - допустим цена достигла +150 пп). Вторая треть закроется, допустим, когда +300 пп от открытия и т.д..

и честно говоря я не понял вот этого

Ans=OrderClose(CloseTicketCl,Lots,Bid,0,Red);          // Закрытие Buy
здесь Lots и OrderLots() да, одно и то же.
 
hope >>:не тем же. Закрывается треть лота (по одному из условий - допустим цена достигла +150 пп). Вторая треть закроется, допустим, когда +300 пп от открытия и т.д..

нет, так не получится.. один ордер - один лот, если отрыли ордер лотом 3, то нельзя дробить лот как вы хотите - сначала 1, потом 1 и еще потом 1 - оредер закрывается целиком, т.е.ордер закрывает тем же лотом что и открывался, нельзя закрывать ордера частями..