Советник с трейлингстопом не работает - страница 4

 
WHRoeder:
Он думает, что может просто вырезать и вставить, и ему не нужно учиться кодировать. Он даже не может исправить эту простую ошибку без просьбы:
'MySelect' - функция может быть объявлена только в глобальной области видимости Trailing_v26.mq4 31 13


Я очень ценю помощь, которую вы и все остальные оказываете. За последние пару дней я перепробовал все, чтобы скомпилировать этот код, и прошу прощения, что не спросил. Большинство из вас предложили мне отказаться от использования собственного кода и использовать чужой код, но я не собираюсь учиться, если не понимаю, что делаю неправильно. На мой взгляд, мой код выглядит разумно. Я прошу его подсчитать ордера по позициям и выбрать только те, которые соответствуют моим критериям, а затем изменить эту конкретную сделку. Пока, после 4 страниц, никто не указал, какая строка моего кода нарушена. Пока я не увижу и не пойму, что я делаю неправильно, мне не поможет обучение с помощью чужого кода. Моя цель сейчас не в том, чтобы получить работающий советник Trailingstop, потому что их там много, а в том, чтобы научиться кодировать, чтобы я мог двигаться дальше. На самом деле, мой код был почти идентичен коду, который Jimdandy разместил в своем Youtube Tutorial по трейлингстопам. Поскольку он практически идентичен его коду, я скопировал его почти дословно (за исключением того, что я хочу торговать вручную), но его код работает только иногда.

Я распечатал некоторые материалы. Эта сделка находится почти на 300 пунктов дальше точки, где я указал, что трейлингстоп срабатывает (это было 150 пунктов):

2016.04.22 00:18:02.301 Trailing_v33 EURAUD,M15: OrderModify = false

2016.04.22 00:18:02.301 Trailing_v33 EURAUD,M15: Ask = 1.45926

2016.04.22 00:18:02.301 Trailing_v33 EURAUD,M15: Selectbypos = 0

2016.04.22 00:18:02.301 Trailing_v33 EURAUD,M15: Selectbyticket = 1

2016.04.22 00:18:02.301 Trailing_v33 EURAUD,M15: OrderTicket = 50381828

2016.04.22 00:18:02.301 Trailing_v33 EURAUD,M15: ticket = 0

2016.04.22 00:18:02.301 Trailing_v33 EURAUD,M15: OrderSelect = true

2016.04.22 00:18:02.301 Trailing_v33 EURAUD,M15: OrdersTotal = 16

2016.04.22 00:18:02.301 Trailing_v33 EURAUD,M15: OrderSymbol = EURUSD

2016.04.22 00:18:02.301 Trailing_v33 EURAUD,M15: OrderTicket = 50381828

2016.04.22 00:17:58.934 Trailing_v33 EURAUD,M15: OrderModify = false

Этот советник установлен только на EURAUD. Как вы можете видеть, есть 16 ордеров, открытых на 9 других графиках. Номер выбранного билета для этой пары совершенно неправильный, и OrderSymbol совершенно неправильный. Оба предназначены для открытого ордера EURUSD. Основываясь на вышеизложенном, мой цикл for выбрал позицию 0 в этом случае, тогда как EURAUD, который он должен был выбрать, был в позиции 14 (15-1). Почему? Я сказал ему игнорировать это.

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

int OpenOrdersThisPair(string pair){
   int total=0;
      for(int s= OrdersTotal()-1; s>= 0; s--){
         OrderSelect(s,SELECT_BY_POS,MODE_TRADES);
           if(OrderSymbol()==pair) total++;
       }
   return(total);  
}

Мой код сейчас выглядит так. Кто-нибудь, пожалуйста, проанализируйте мой код, чтобы я мог извлечь из него уроки, и скажите мне, почему он не работает на нескольких графиках. Я знаю, что он не может быть настолько плохим, потому что иногда он работает идеально. Спасибо.

#property strict;
extern string Label_TrailingStart="Pip threshold to activate TrailingStop";
extern int TrailingStart=10;
extern string Label_TrailingStop="Pips trailing behind";
extern int TrailingStop=5;
double stoplevel=(MarketInfo(Symbol(),MODE_STOPLEVEL))/10,Pip=Point*10;
int TS=TrailingStart-TrailingStop;
bool UseTrailingStop=true,UseAutotrading=true;
//+------------------------------------------------------------------+
//|  Expert initialization function                                  |
//+------------------------------------------------------------------+
int init(){
   if(TS<stoplevel){
    MessageBox("Please note: Your inputs cannot be less than the minimum levels required"+
            "\nby your broker. Please reload the EA and either increase the value of the"+
            "\nTrailingStart and/or decrease the value of the TrailingStop so that "+
            "\nTrailingStart-TrailingStop >= "+StringConcatenate(stoplevel)+" pips");
     } 
   return(0);
  }
//+------------------------------------------------------------------+
//|    Expert deinitialization function                              |
//+------------------------------------------------------------------+
int deinit(){
   return(0);
  }
//+------------------------------------------------------------------+
//|   Expert start function                                          |
//+------------------------------------------------------------------+
int start(){
   if(UseTrailingStop) Trailing(); 
   if(UseAutotrading) Autotrading();  
   return(0);
}
//+------------------------------------------------------------------+
void Trailing(){
for(int b=OrdersTotal()-1; b>=0; b--){
      if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol())
            if(OrderType()==OP_BUY)
                  if((Bid-OrderOpenPrice())>(TrailingStart*Pip))
                     if(OrderStopLoss()<Bid-(TrailingStop*Pip))
                        OrderModify(OrderTicket(),OrderOpenPrice(),Bid-(TrailingStop*Pip),OrderTakeProfit(),Blue);
   }     
   for(int s=OrdersTotal()-1; s>=0; s--){
     if(OrderSelect(s,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol())
            if(OrderType()==OP_SELL)
                  if((OrderOpenPrice()-Ask)>(TrailingStart*Pip))
                     if(OrderStopLoss()>Ask+(TrailingStop*Pip) || OrderStopLoss()==0)
                        OrderModify(OrderTicket(),OrderOpenPrice(),Ask+(TrailingStop*Pip),OrderTakeProfit(),Red);
   }
}
void Autotrading(){
   if(!IsTradeAllowed()){
      MessageBox("This Expert Advisor requires Auto Trading. Please reload the EA or right click on"+
                 "\nthe chart to bring up the inputs window. Under the common tab check the box to"+
                 "\nallow live trading");
      Sleep(50000);
     }
   if(!IsExpertEnabled()){
      MessageBox("This Expert Advisor requires Auto Trading. Please click the button at the top");
      Sleep(50000);
     } 
}


 
Trader3000:

До сих пор, после 4 страниц, никто не указал, какая строка моего кода нарушена.

Неправда! Мы описали ваши ошибки и предложили решения для них во многих вариантах и альтернативах. Но вы игнорируете их и продолжаете делать все по-своему. Мало того, теперь вы даже ухудшили ситуацию, добавив еще больше ошибок.

Когда художник учится рисовать, он делает это, сначала копируя технику других людей, которые овладели ею. Только после того, как он освоит эти техники, он начинает создавать свой собственный способ рисования.

Вот краткий список "моей критики":

  1. Используйте скобки ("фигурные" скобки). Не пытайтесь экономить на них. Пока ваш код не будет полностью функциональным и отлаженным, добавляйте их, даже если в блоке содержится всего одна строка. Поместите их также на отдельной строке. Не волнуйтесь, если у вас много белого пространства. Вы всегда сможете вернуться и убрать его, но в начале вы хотите убедиться, что все находится в правильном блоке кода, а скобки и круглые скобки сбалансированы. Выстраивание нескольких операторов "if" в последовательность - это рецепт катастрофы, так как это очень трудно отладить, особенно с таким привередливым компилятором, как этот.
  2. В вашем исходном коде был только один цикл, который теперь вы превратили в два без видимой причины, кроме как для того, чтобы сделать ваш код еще медленнее и повторить места, которые вам придется исправлять при обнаружении ошибок.
  3. Используйте переменные для хранения результатов выражений! Вы повторяете одни и те же выражения несколько раз, что делает ваш код не только медленнее, но и более подверженным ошибкам и более сложным для чтения и исправления, потому что вам приходится менять их в нескольких местах.

Я мог бы перечислить еще много вещей, но исправьте хотя бы эти, раз и навсегда!

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

 
FMIC:

Вот краткий список "моей критики":

Ок, большое спасибо за это. На самом деле я изначально поставил скобки для всех моих утверждений 'if' в соответствии с кодом, который я разместил здесь ранее, но поскольку этот код не работал, я попробовал различные другие вещи, которые включали копирование кода, который я вставил в свое предыдущее сообщение. Как я уже говорил, это даже не мой код, но он также не работает на всех парах. Однако я снова заменю скобки и последую другим советам. Тем временем я узнал, что OrderSelect выводит в терминале символ первого ордера, а не того, на котором находится советник, так что это не было ошибкой.

EDIT: Спасибо за предложение #3!!!!!!! Я думаю, что проблема была в этом, потому что ордер сначала должен быть выбран по символу, а ПОТОМ значение должно быть сохранено. Поэтому я переместил переменную ниже этих функций, как показано ниже, и, кажется, это работает сейчас (но требуется больше тестирования, прежде чем я буду знать с уверенностью).

int start(){
      for(int i=OrdersTotal()-1; i>=0; i--) {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
            if(OrderSymbol()!= Symbol()) continue;
               double Pip=Point*10,TSTP=TrailingStart*Pip,Trail=TrailingStop*Pip,SL=StopLoss*Pip;               
                  if(OrderType()==OP_BUY){
                     if(Bid-OrderOpenPrice()>TSTP){
                        if(OrderStopLoss()<Bid-Trail){
                           if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Trail,OrderTakeProfit(),Orange))
                              Print("Error Buy TrailingStop: ",GetLastError());
            }
         }
 
Trader3000:

Ок, большое спасибо за это. На самом деле, я изначально поставил скобки для всех моих утверждений 'if' в соответствии с кодом, который я разместил здесь ранее, но поскольку этот код не работал, я попробовал различные другие вещи, которые включали копирование кода, который я вставил в свое предыдущее сообщение. Как я уже говорил, это даже не мой код, но он также не работает на всех парах. Однако я снова заменю скобки и последую другим советам. Тем временем я узнал, что OrderSelect выводит в терминале символ первого ордера, а не того, на котором находится советник, так что это не было ошибкой.

EDIT: Спасибо за предложение #3!!!!!!! Я думаю, что проблема была в этом, потому что ордер сначала должен быть выбран по символу, а ПОТОМ значение должно быть сохранено. Поэтому я переместил переменную ниже этих функций, как показано ниже, и, кажется, это работает сейчас (но требуется больше тестирования, прежде чем я буду знать с уверенностью).

Взглянув на ваш последний код, я хочу сказать - Я СДАЮСЬ! (Вы отказываетесь идти до конца)!
 
FMIC: Посмотрев на ваш последний код, я могу сказать следующее - Я СДАЮСЬ! (Вы отказываетесь следовать дальше)!
Теперь, возможно, вы понимаете мою "жесткую критику", когда они тратят время каждого. Хотя я понимаю "простые вещи", которые они считают приемлемыми, чтобы тратить время каждого, я не понимаю.

Trader3000: Я думаю, в этом и была проблема,...
int start(){
      for(int i=OrdersTotal()-1; i>=0; i--) {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
            if(OrderSymbol()!= Symbol()) continue;
               double Pip=Point*10, TSTP=TrailingStart*Pip, Trail=TrailingStop*Pip, SL=StopLoss*Pip;
                  if(OrderType()==OP_BUY){
                     if(Bid-OrderOpenPrice()>TSTP){
                        if(OrderStopLoss()<Bid-Trail){
                           if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Trail, OrderTakeProfit(), Orange))
                              Print("Error Buy TrailingStop: ",GetLastError());
            }
         }
Ваша проблема в том, что вы не думаете.
int start(){
   for(int i=OrdersTotal()-1; i>=0; i--) {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) if(OrderSymbol()!= Symbol()) continue;
// Everything below is executed if NO order is selected or a selected order is symbol
      double Pip=Point*10, TSTP=TrailingStart*Pip, Trail=TrailingStop*Pip,SL=StopLoss*Pip;
      if(OrderType()==OP_BUY)
      && Bid-OrderOpenPrice()>TSTP)
      && OrderStopLoss()<Bid-Trail){
         if(!OrderModify(OrderTicket(), OrderOpenPrice(), Bid-Trail, OrderTakeProfit(), Orange))
            Print("Error Buy TrailingStop: ",GetLastError());
      }
   :
 
WHRoeder:
Теперь, возможно, вы понимаете мою "жесткую критику", когда они тратят время каждого. Хотя я понимаю "простые вещи", которые они считают приемлемыми для того, чтобы тратить время каждого, я не понимаю.

Да! К сожалению, похоже, вы правы!

 

Спасибо за ответы. Итак, я изменил код на более раннюю версию, как показано ниже. В таком виде он отлично работает на всех парах, где уровень стоплосса равен 50 пунктам, но не работает на парах, где уровень стоплосса выше, например, EURAUD, даже если внешние переменные выше уровня стоплосса. Так что это странно.

extern int TrailingStart=15;
extern int TrailingStop=5;
double stoplevel=(MarketInfo(Symbol(),MODE_STOPLEVEL))/10;
int TS=TrailingStart-TrailingStop;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init(){
   if(TS<stoplevel){
      MessageBox("Please note: Your inputs for TrailingStart and/or TrailingStop cannot"+
                 "\nbe less than the minimum levels required by your broker and the"+
                 "\nTrailingStart has been increased automatically to "+StringConcatenate(stoplevel+TrailingStop)+" pips");
     } 
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int deinit(){
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start(){
   double Pip=Point*10;
   if(TS<stoplevel) TrailingStart=(int)stoplevel+TrailingStop;
           
   if(!IsTradeAllowed()){
      MessageBox("This Expert Advisor requires Auto Trading. Please reload the EA or right click on"+
                 "\nthe chart to bring up the inputs window. Under the common tab check the box to"+
                 "\nallow live trading");
      Sleep(50000);
     }
   if(!IsExpertEnabled()){
      MessageBox("This Expert Advisor requires Auto Trading. Please click the button at the top");
      Sleep(50000);
     } 
   int ticket=0,buy_ticket=0,sell_ticket=0;  
   for(int i=OrdersTotal()-1; i>=0; i--)
      if(OrderSelect(i,SELECT_BY_POS) && OrderSymbol()==Symbol()){
      ticket++;
      if(OrderType()==OP_BUY) buy_ticket=OrderTicket();
      if(OrderType()==OP_SELL) sell_ticket=OrderTicket();
      }
            if(OrderType()==OP_BUY){
               if(OrderSelect(buy_ticket,SELECT_BY_TICKET)){
                  if((Bid-OrderOpenPrice())>(TrailingStart*Pip)){
                     if(OrderStopLoss()<Bid-(TrailingStop*Pip)){
                        if(OrderModify(OrderTicket(),OrderOpenPrice(),Bid-(TrailingStop*Pip),OrderTakeProfit(),Blue))
                        Print("Buy = ",GetLastError());
                        return(0);
                        RefreshRates();
                        }     
                     }  
                  }     
               }
            if(OrderType()==OP_SELL){
               if(OrderSelect(sell_ticket,SELECT_BY_TICKET)){
                  if((OrderOpenPrice()-Ask)>(TrailingStart*Pip)){
                     if(OrderStopLoss()>Ask+(TrailingStop*Pip) || OrderStopLoss()==0){
                        if(OrderModify(OrderTicket(),OrderOpenPrice(),Ask+(TrailingStop*Pip),OrderTakeProfit(),Red))
                        Print("Sell = ",GetLastError());
                        return(0);
                        RefreshRates();
                        }
                     }
                  }  
               }
             
  return(0);
}
//+------------------------------------------------------------------+
 

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

1. инкременты вместо декрементов

2. умножает все на Point вместо Point*10

3. он складывает Trailingstop и Trailingstep вместе, затем вычитает один и модифицирует ордер с помощью Trailingstep. Если я правильно понимаю, Trailingstart активируется после движения на 15 пунктов (150 пунктов). В моем советнике цена отстанет на 5 пунктов и будет остановлена, если цена снова упадет и достигнет этого уровня в 5 пунктов. В его советнике он также активируется после 15 пунктов, но количество пунктов, на которое он отстает, составляет 19 (15+5-1), поэтому цена должна упасть на 19 пунктов, чтобы быть остановленной. В качестве примера: цена открытия ордера 1.50000. Цена поднимается на 150 пунктов до 1.50150, что активирует трейлингстоп. Если цена затем упадет обратно до 1.50100, она будет остановлена с прибылью в 5 пунктов. В его советнике трейлингстоп также активирован на отметке 1.50150, но трейл находится на отметке 1.49960, что, как мне кажется, приведет кошибке 130, так как стоп находится слишком близко к уровню стопа. Или я неправильно понимаю?

Может ли моя проблема быть связана с одним или несколькими из этих пунктов?

//+------------------------------------------------------------------+
//|                                                   e-Trailing.mq4 |
//|                                           Êèì Èãîðü Â. aka KimIV |
//|                                              http://www.kimiv.ru |
//|                                                                  |
//| 12.09.2005 Àâòîìàòè÷åñêèé Trailing Stop âñåõ îòêðûòûõ ïîçèöèé    |
//|            Âåøàòü òîëüêî íà îäèí ãðàôèê                          |
//+------------------------------------------------------------------+
#property copyright "Êèì Èãîðü Â. aka KimIV"
#property link      "http://www.kimiv.ru"

//------- Âíåøíèå ïàðàìåòðû ------------------------------------------
extern bool   ProfitTrailing = True;  // Òðàëèòü òîëüêî ïðîôèò
extern int    TrailingStop   = 15;     // Ôèêñèðîâàííûé ðàçìåð òðàëà
extern int    TrailingStep   = 5;     // Øàã òðàëà
extern bool   UseSound       = True;  // Èñïîëüçîâàòü çâóêîâîé ñèãíàë
extern string NameFileSound  = "expert.wav";  // Íàèìåíîâàíèå çâóêîâîãî ôàéëà

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
void start() {
  for (int i=0; i<OrdersTotal(); i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      TrailingPositions();
    }
  }
}

//+------------------------------------------------------------------+
//| Ñîïðîâîæäåíèå ïîçèöèè ïðîñòûì òðàëîì                             |
//+------------------------------------------------------------------+
void TrailingPositions() {
  double pBid, pAsk, pp;

  pp = MarketInfo(OrderSymbol(), MODE_POINT);
  if (OrderType()==OP_BUY) {
    pBid = MarketInfo(OrderSymbol(), MODE_BID);
    if (!ProfitTrailing || (pBid-OrderOpenPrice())>TrailingStop*pp) {
      if (OrderStopLoss()<pBid-(TrailingStop+TrailingStep-1)*pp) {
        ModifyStopLoss(pBid-TrailingStop*pp);
        return;
      }
    }
  }
  if (OrderType()==OP_SELL) {
    pAsk = MarketInfo(OrderSymbol(), MODE_ASK);
    if (!ProfitTrailing || OrderOpenPrice()-pAsk>TrailingStop*pp) {
      if (OrderStopLoss()>pAsk+(TrailingStop+TrailingStep-1)*pp || OrderStopLoss()==0) {
        ModifyStopLoss(pAsk+TrailingStop*pp);
        return;
      }
    }
  }
}

//+------------------------------------------------------------------+
//| Ïåðåíîñ óðîâíÿ StopLoss                                          |
//| Ïàðàìåòðû:                                                       |
//|   ldStopLoss - óðîâåíü StopLoss                                  |
//+------------------------------------------------------------------+
void ModifyStopLoss(double ldStopLoss) {
  bool fm;

  fm=OrderModify(OrderTicket(),OrderOpenPrice(),ldStopLoss,OrderTakeProfit(),0,CLR_NONE);
  if (fm && UseSound) PlaySound(NameFileSound);
}
//+------------------------------------------------------------------+
 
Trader3000:

Я также нашел другого эксперта, у которого код очень похож на мой, и сравнил их.

Посмотрим, пойму ли я вашу логику! Вы готовы найти другого советника неизвестно откуда и готовы включить его код в свой, НО ВЫ НЕ ХОТИТЕ взять код, который был специально написан, чтобы помочь вам и исправить ваши проблемы!!!

WOW! Как логично с вашей стороны! Где СПОК, когда он так нужен!

СПОК, пусть ты покоишься с миром! Мы все скучаем по тебе!

 
FMIC:

Давайте посмотрим, смогу ли я понять вашу логику! Вы готовы найти другой советник от кого-то другого неизвестно откуда и готовы включить этот код в свой, НО ВЫ НЕ ХОТИТЕ взять код, который был специально написан, чтобы помочь вам и исправить ваши проблемы!!!

WOW! Как логично с вашей стороны! Где СПОК, когда он так нужен!

СПОК, пусть ты покоишься с миром! Мы все скучаем по тебе!

Я наконец-то разобрался с этим, так что спасибо всем за помощь (и критику). Вернувшись к коду, который вы с Майком разместили на первой странице, я увидел свою ошибку. Возможно, я не заметил ее, потому что она была настолько тонкой, но в основном потому, что я не понимал логику кода должным образом. Проблема была в том, что я думал, что количество пунктов для TrailingStop - это количество пунктов, за которыми он идет. Но на самом деле количество пунктов, которые он отслеживает, это TrailingStart-TrailingStop. Поэтому мои настройки были ниже уровня для таких пар, как gbpjpy, потому что я ввел 15 и 5. Поскольку 5 ниже уровня 8. Просто увеличив TrailingStop, теперь он работает на всех парах. Спасибо!!!
Причина обращения: