Проблема множественных заказов - страница 2

 

Привет, Раптор;

Если в Тестере все ордера закрываются при закрытии TrailingStop, то на Демо закрывается только ордер, закрытый по TrailingStop, любой открытый ордер остается открытым.

Используя следующий код поверх того, что вы посоветовали, логика выглядит следующим образом;

"Выяснить состояние последнего ордера, если он был закрыт, то выполнить код для начала закрытия всех оставшихся открытых ордеров."

Подскажите, почему так происходит?

С наилучшими пожеланиями

Луис

int OrdType, GLError;
   double OrderClosed;
   RefreshRates();
   
    for(int Closed = OrdersTotal()-1;Closed >= 0; Closed--) 
      if(OrderSelect(Closed,SELECT_BY_POS,MODE_HISTORY)
        && OrderMagicNumber()== MagicNumber
        && OrderSymbol()== Symbol())
        {//29
        OrderClosed = OrderCloseTime();
        if(OrderClosed!=0)
           {//30                                  
   for(int OrderPos = OrdersTotal()-1; OrderPos >= 0; OrderPos--)       
      if(OrderSelect(OrderPos, SELECT_BY_POS, MODE_TRADES)
         && OrderMagicNumber()== MagicNumber 
         && OrderSymbol()== Symbol())                                       
         {//31
         OrdType = OrderType();
         if(OrdType == OP_BUY || OrdType==OP_SELL)
           {//32
           if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),RealSlippage, Yellow))
               GLError = GetLastError();
           }//32                                         
          }//31
       }//30
     }//29 
    
  if(GLError > 0) Print("Error Closing/Deleting Order, error # ", GLError, " for ticket: ", OrderTicket());           
  return(0);
  }//0 
 
luisneves:

Привет, Раптор;

Если в Тестере все ордера закрываются при закрытии TrailingStop, то на Демо закрывается только ордер, закрытый по TrailingStop, любой открытый ордер остается открытым.

Используя следующий код поверх того, что вы посоветовали, логика выглядит следующим образом;

"Выяснить состояние последнего ордера, если он был закрыт, то выполнить код, чтобы начать закрывать все оставшиеся открытые ордера."

Подскажите, почему так происходит?

Так делать нельзя...

    for(int Closed = OrdersTotal()-1;Closed >= 0; Closed--)    // OrdersTotal is the total of open orders
      if(OrderSelect(Closed,SELECT_BY_POS,MODE_HISTORY)        //  this is looping through the closed orders

... нет смысла использовать количество открытых ордеров в качестве начального условия цикла для перебора закрытых ордеров. Может быть, вы хотели использоватьOrderssHistoryTotal()? но OrderCloseTime() закрытого ордера никогда не будет == 0.

 
luisneves:

.....

Я использую BuyTicket и SellTicket в коде, чтобы избежать открытия нескольких ордеров, но, похоже, это не правильный метод...

.....

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

Я понимаю, что вы немного изменили первоначальную тему и, возможно, первый вопрос обсуждается до конца (для меня это нормально).
Если вы все еще хотите продолжить начальную тему, вам нужно объяснить это немного иначе, потому что я не очень понимаю, что вы ищете.

Первый фрагмент, который я подправил, не позволяет коду открывать несколько ордеров. Вам показалось, что он вас не устраивает, поэтому вы его убрали (или просто не добавили), но сделали аналогичную вещь, используя BuyTicket и SellTicket.
Затем вы говорите о третьем ордере... Вы ищете что-то вроде этого?

Покупка->Продажа->Покупка->Продажа->Покупка
но не допускайте
Купить->Купить->Продать->Купить->Купить

Другими словами, если последний открытый ордер является ордером на покупку, то следующий должен быть на продажу и наоборот?

Или какое максимальное количество ордеров должен открыть ваш советник? Это 2, один на продажу, и если условие для противоположного ордера выполнено, покупка, но больше не продажа, если он отскакивает от триггера покупки снова?
Если это так, то в чем проблема со счетчиком OpenOpposite, который я добавил в ваш первоначальный код?

редактировать:

Третий вариант, который я могу себе представить, это то, что вы хотите открыть другой противоположный ордер, если первый противоположный ордер был остановлен?
Вот так:

Buy->Sell->если Sell был остановлен->Sell->если Sell был остановлен->Sell

 
kronin:

Я понимаю, что вы немного изменили первоначальную тему и, возможно, первый вопрос обсуждается до конца (для меня это нормально).
Если вы все еще хотите продолжить начальную тему, вам нужно объяснить это немного иначе, потому что я не совсем понимаю, что вы ищете.

Первый фрагмент, который я подправил, не позволяет коду открывать несколько ордеров. Вам показалось, что он вас не устраивает, поэтому вы его убрали (или просто не добавили), но сделали аналогичную вещь, используя BuyTicket и SellTicket.
Затем вы говорите о третьем ордере... Вы ищете что-то вроде этого?

Покупка->Продажа->Покупка->Продажа->Покупка
но не допускайте
Купить->Купить->Продать->Купить->Купить

Другими словами, если последний открытый ордер - это ордер на покупку, то следующий должен быть на продажу и наоборот?

Или какое максимальное количество ордеров должен открыть ваш советник? Это 2, один на продажу, и если условие для противоположного ордера выполнено, покупка, но больше не продажа, если он отскакивает от триггера покупки снова?
Если это так, то в чем проблема со счетчиком OpenOpposite, который я добавил в ваш первоначальный код?

редактировать:

Третий вариант, который я могу себе представить, это то, что вы хотите открыть другой противоположный ордер, если первый противоположный ордер был остановлен?
Вот так:

Buy->Sell->если Sell был остановлен->Sell->если Sell был остановлен->Sell


Привет Кронин,

Заранее благодарю вас за то, что уделили мне время и поддержали в этом вопросе.

В стратегии соблюдается следующая логика;

Допустим, первый ордер открывается на покупку, затем он ищет возможность закрыться по трейлинг-стопу, но если Bid отскочит вниз на несколько пунктов нижеOrderOpenPrice(ReturnDistance), откроется Sell и ищет возможность закрыться по трейлинг-стопу, и снова, если Ask отскочит вверх на несколько пунктов выше OrderOpenPrice, откроется покупка. Этот процесс пинг-понга закончится, когда последний открытый ордер закроется по среднему значению TrailingStop или достигнет максимального количества ордеров, равного 7 (это можно настроить внешним образом).

Проблема с множественными открытиями возникает, когда цена идет вверх и вниз, пересекая OrderOpenPrice. Таким образом, если у нас есть покупка, следующий ордер может быть просто продажей и так далее.

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

С наилучшими пожеланиями

Луис

 

Луис, я потратил довольно много времени на ваш код, но, честно говоря, я не совсем уверен, что он делает то, что вы хотите.

Доработайте/измените его, протестируйте, поймите его.... и скажите мне, что он работает хотя бы близко, похож или полностью соответствует тому, что вы ищете. Я еще не совсем уверен в стратегии.
Пожалуйста, пока не добавляйте новую функцию (не добавляйте мартингейл заново). Код достаточно большой, и у вас впереди еще много работы, чтобы добиться его надежной работы.
Я должен сказать, что код не намного более четко организован. Я не хотел менять ваши работающие части (даже вам нужна лучшая обработка ошибок). Я закомментировал и переместил некоторые части, но все это осталось на месте...


Развлекайтесь...

 
kronin:

Луис, я потратил довольно много времени на ваш код, но, честно говоря, я не совсем уверен, что он делает то, что вы хотите.

Смотрите прикрепленный файл. Доработайте/измените его, протестируйте, поймите его.... и скажите мне, по крайней мере, что он работает близко, похож или полностью другой, к тому, что вы ищете. Я еще не совсем уверен в стратегии.
Пожалуйста, пока не добавляйте новую функцию (не добавляйте мартингейл заново). Код достаточно большой, и у вас впереди еще много работы, чтобы добиться его надежной работы.
Я должен сказать, что код не намного более четко организован. Я не хотел менять ваши работающие части (даже вам нужна лучшая обработка ошибок). Я закомментировал и переместил некоторые части, но все это осталось на месте...


Развлекайтесь...


Привет, Кронин,

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

Хотя я считаю, что вы сделали все возможное, чтобы понять стратегию, некоторые вещи не совсем отвечают (конечно, из-за моего непонимания в этом вопросе).

Я сделал несколько модификаций, купив ваш совет, но не уверен, что все сделано правильно.

Две проблемы;

1 - Идея заключается в том, что после закрытия сделки с помощью TrailingStop все оставшиеся открытые ордера должны закрыться. Ордера не должны закрываться по TakeProfit (этот TakeProfit там просто потому, что я хочу быть уверен, что он находится в зоне Freeze Zone). Поэтому я решил сделать это, используя закрытие последнего ордера для запуска функции CloseAll (при попытке сделать это возникают некоторые глупости...). Вы используете Last Closed Ticket для запуска закрытия повторных открытых ордеров, но я не понимаю, происходит ли это, когда сделка закрывается по TrailingStop...

2 - "Пинг-понг" не работает, по крайней мере в Тестере.

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

Заранее благодарю за терпение и потраченное время. (подробнее в личном сообщении)

С наилучшими пожеланиями

Луис

 

Хорошо, я изменил алгоритм, чтобы закрывать все ордера на SL вместо TP. (Изменение заключалось в замене '<' на '>' - вы должны найти где).

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

Он начинает с начального ордера (я изменил оператор print()), а затем делает противоположные ордера.

EURUSD,M1: open #1 buy 0.01 EURUSD at 1.43310 ok
EURUSD,M1: выставлен первоначальный ордер на покупку # 1
EURUSD,M1: изменить #1 купить 0.01 EURUSD по 1.43310 sl: 1.42810 tp: 1.43510 ok
EURUSD,M1: open #2 sell 0.01 EURUSD по 1.43200 ok
EURUSD,M1: Установлен противоположный ордер на продажу # 2
EURUSD,M1: изменить #2 sell 0.01 EURUSD по 1.43200 sl: 1.43700 tp: 1.43000 ok
EURUSD,M1: open #3 buy 0.01 EURUSD at 1.43300 ok
EURUSD,M1: Размещен противоположный ордер на покупку # 3
EURUSD,M1: изменить #3 buy 0.01 EURUSD по 1.43300 sl: 1.42800 tp: 1.43500 ok

Я добавил return в OpenOppositeOrder(), когда я действительно открыл ордер. Вместе с настройками можно было открыть ордер на покупку и в том же тике ордер на продажу. Этот вывод в MaxOrder не является надежным.
Возможно, лучший подход - разделить его на 2 функции или дать функции параметр, чтобы она выполнялась только для ордеров на продажу или только для ордеров на покупку.

btw. код, который вы загрузили, не торговал! Все сделки провалились из-за 'invalid LotSize'.....

 

Привет, Кронин,

Спасибо за время, потраченное на поддержку.

Что касается проблемы "код, который вы загрузили, не торгует! Все сделки не удались из-за 'invalid LotSize'.... ", это произошло после того, как я переместил MM код в конец файла. Я сделал вызов функции с помощью MM(); в начале кода, кажется, что такое действие не работает, но последний код, который вы прислали, работает, и функция MM() находится на том же месте и работает, так что здесь я заблуждаюсь.....

Насчет открытия ордера на том же тике;

Когда советник попадает на график, он должен пройти путь до цены больше (или меньше), чем цена в этот момент, то есть, когда цена идет вверх (или вниз), OpenDistance ордер на покупку (или продажу) имеет место. Отсюда следующее открытие может произойти только при отскоке цены вниз (если последний ордер был на покупку) от OrderOpenPrice минус ReturnDistance. Та же логика в случае, если последним ордером был sell. Возможно, необходимо установить лимит, чтобы избежать любого открытия ордера вне этой логики.

С наилучшими пожеланиями

Луис

 
//mine
LotSize = (RiskAmount / StopLoss) / TickValue;              //Phil: LotSize is defined in global scope

//yours
double LotSize = (RiskAmount / StopLoss) / TickValue;


Вы определили LotSize в глобальной области видимости и инициализировали ее значением 0. В функции void MM() вы вычислили LotSize, действительный только в этой функции. Я удалил только инициализацию, поэтому переменная в глобальной области видимости обновляется.

Не могли бы вы прокомментировать каждое из этих значений, значение в пунктах, пожалуйста?

extern double StopLoss       =  50;
extern double TakeProfit     =  20;
extern double TrailingStop   =   2;
extern int    MinimumProfit  =   3;
extern int    Slippage       =   3;
extern double OpenDistance   =   2;
extern double ReturnDist     =   1;
extern double MinStop        =   1;

Каков спред для символа, на котором вы хотите запустить советника?

Но я подправил ваши входные параметры, чтобы не все ордера открывались практически в одно и то же время.Возможно, вам нужно проверить параметры по умолчанию.

Попробуйте сделать то же самое и запустить его в тестере в визуальном режиме.

 
kronin:


Вы определили LotSize в глобальной области видимости и инициализировали ее значением 0. В функции void MM() вы вычислили LotSize, действительный только в этой функции. Я удалил только инициализацию, поэтому переменная в глобальной области видимости обновляется.

Не могли бы вы прокомментировать каждое из этих значений, значение в пунктах, пожалуйста?

Каков спред для символа, на котором вы хотите запустить советника?

Но я подправил ваши входные параметры, чтобы не все ордера открывались практически в одно и то же время.Возможно, вам нужно проверить параметры по умолчанию.

Попробуйте сделать то же самое и запустить советник в тестере в визуальном режиме.


Привет, Кронин,

Да, мне есть чему поучиться....Ныне понимаю, что когда есть необходимость получить доступ к значению извне функции, которое должно быть в Global.

Значения, которые находятся на внешних умножается на 10, потому что советник должен также работать на 5 цифр брокеров. Я использую этот блок кода, чтобы получить это автоматически, но получаю совет от WHRoeder, который не совместим с металлами.

int init ()// Adjust for 4 or 5 digits.
   {
   if (Digits == 2 || Digits == 4) <------- not compatible with metals
      {
      pt = Point;
      RealSlippage = Slippage;
      }    
   if (Digits == 3 || Digits == 5) 
      {
      pt = Point * 10;
      RealSlippage = Slippage * 10;
      }

Спред пары может быть переменным. Поэтому я использую код для выхода за пределы уровня Stop.

Что касается этого вопроса "Но я подправил ваши входные параметры, чтобы не все ордера открывались практически в одно и то же время. Возможно, вам нужно проверить параметры по умолчанию."

Насколько я могу судить (извините, если это не так...), OpenDistance поддерживается как 2 пункта и ReturnDistance теперь тоже с 2. Сейчас я вижу, что ордер открывается, но не при разнице в 2 пункта. Это работает с тестером на платформе ECN брокера (IC Markets). Может ли это иметь какое-то значение?

На самом деле ордера открываются не одновременно, но похоже, что Open Distance и ReturnDist не учитываются, чтобы получить правильное расстояние для открытия ордеров.

У вас в коде написано, что;

OTLastTick=OTCurrentTick;                      //shift OrderTotal
  OTCurrentTick=OrdersTotal();                   //reinit OrderTotal
  if(OTCurrentTick>0)Trail();                    //Trail
  if(OTLastTick>=2                               //if OrderTotal has changed
     &&OTCurrentTick<OTLastTick
     &&OTCurrentTick>0){CloseAllOnSL();return;}  //Check order closed on SL level
  if(OTCurrentTick>=MaxOrders)return;            //Dont open more orders. Trail and return.
                                                 //Actually we have nothing more to do.
                                                 //Only call opposite if the initial order of the serie is open
  if(OTCurrentTick>0)OpenOppositeOrder(); //<--------------------- include this line to call function (not sure if this the right method to do it...)
  MM();                //<--------------------- include this line to call function (not sure if this the right method to do it...)
                        
  if(OTCurrentTick==0){//init serie
     BuyAllowed=true;
     SellAllowed=true; 

Я включил строку, выделенную жирным шрифтом, чтобы вызвать функцию OpenOppositeOrder и здесь не уверен, что это правильно. С другой стороны, не могу понять, где происходит сравнение текущего тика с последним тиком, который произошел за 2 пункта до этого (OpenDistance).

Извините, если я начинаю утомлять вас своими вопросами.

С наилучшими пожеланиями

Луис

Причина обращения: