MQL4 및 MQL5에 대한 초보자 질문, 알고리즘 및 코드에 대한 도움말 및 토론 - 페이지 1549

 
MakarFX :

할줄알았을때 얘기하는게 좋은데..

"최대한 유용한 정보를 끌어내는" 방법에 대한 조언을 돕습니다.

나는 이미 모든 것을 충분히 명확하게 말했습니다. 음, 개인적으로 묻겠습니다.

여기에 두 가지 기능이 있으며 둘 다 과거 주문 을 반복합니다.

 //+------------------------------------------------------------------+
//|  Возвращает пункты убытка закрытых ордеров с начала цикла        |
//+------------------------------------------------------------------+
 //+------------------------------------------------------------------+
//|  Возвращает кол-во серии убыточных ордеров                       |
//+------------------------------------------------------------------+

동일한 주문에 대한 두 개의 사이클. 이 함수가 한 사이클에서 반환하는 모든 것을 얻을 수 있는 방법이 있습니까?

 

안녕하세요!

나는 올빼미에게 거래의 쿠데타를 고정하려고합니다. 지침에 표시된 대로 수행합니다: https://www.mql5.com/en/forum/128200

컴파일할 때 오류는 없지만 테스터에서는 플립이 작동하지 않습니다.

로그에 오류가 표시됩니다.

2021.07.29 20:06:34.316 2015.01.08 22:10:00 코드 AUDUSD,M5를 통한 플립이 있는 SMA: OrderSend 오류 130

2021.07.29 20:06:34.316 2015.01.08 22:05:45 코드 AUDUSD,M5를 통한 플립이 있는 SMA: OrderSend 오류 4107

2021.07.29 20:06:34.316 2015.01.08 22:05:45 코드 AUDUSD,M5를 통한 반전이 있는 SMA: OrderSend 기능에 대한 유효하지 않은 정지 손실

제발 말해줘, 여기 무슨 일이야?

내 생각에 변수에 지정된

int ReversOrderSend (문자열 기호, int cmd, 이중 볼륨, 이중 가격, int 슬리피지, 이중 손절매, 이중 이익실현, 문자열 주석, int magic=0,datetime 만료=0, color arrow_color=CLR_NONE)

메인 코드와 관련이 없습니다.

다른 터미널, 4 및 5 기호에서 시도했습니다. 오류는 어디에서나 동일합니다.

전체 코드는 다음과 같습니다.

 //+-----------------------------------------------------------------------------------------------+
//|                                                                     Simple Moving Average.mq4 |
//|                                                                 Copyright 2016, Andrey Minaev |
//|                                                     https://www.mql5.com/ru/users/id.scorpion |
//+-----------------------------------------------------------------------------------------------+
#property copyright "Copyright 2016, Andrey Minaev"
#property link        " https://www.mql5.com/ru/users/id.scorpion "
#property version    "1.00"
#property strict

// Параметры советника
extern string sParametersEA = "" ;     // Параметры советника
extern double dLots         = 0.01 ;   // Количество лотов
extern int     iStopLoss     = 30 ;     // Уровень убытка (в пунктах)
extern int     iTakeProfit   = 30 ;     // Уровень прибыли (в пунктах)
extern int     iSlippage     = 3 ;       // Проскальзование (в пунктах)
extern int     iMagic        = 1 ;       // Индентификатор советника
extern double K_Martin     = 2.0 ;
extern int     OrdersClose  = 5 ;
extern int     DigitsLot    = 2 ;
extern int     ReversOrder  = 0 ;             // Переворот сделок 1-да; 0-нет;
// Параметры индикатора
extern string sParametersMA = "" ;     // Параметры индикатора
extern int     iPeriodMA     = 14 ;     // Период усреднения
// Глобальные переменные
double dMA;
//+-----------------------------------------------------------------------------------------------+
int OnInit ()
  {
// Если брокер использует 3 или 5 знаков после запятой, то умножаем на 10
   if ( Digits == 3 || Digits == 5 )
     {
      iStopLoss   *= 10 ;
      iTakeProfit *= 10 ;
      iSlippage   *= 10 ;
     }

   return ( INIT_SUCCEEDED );
  }
//+-----------------------------------------------------------------------------------------------+
void OnDeinit ( const int reason)
  {

  }
//+-----------------------------------------------------------------------------------------------+
void OnTick ()
  {
// Получим значение индикатора
   dMA = iMA ( Symbol (), 0 , iPeriodMA, 0 , MODE_SMA , PRICE_CLOSE , 0 );

// Если нет открытых ордеров, то входим в условие
   if (bCheckOrders() == true )
     {
       // Если появился сигнал на покупку, то откроем ордер на покупку
       if (bSignalBuy() == true )
         vOrderOpenBuy();

       // Если появился сигнал на продажу, то откроем ордер на продажу
       if (bSignalSell() == true )
         vOrderOpenSell();
     }
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция проверки открытых оредров |
//+-----------------------------------------------------------------------------------------------+
bool bCheckOrders()
  {
// Переберем в цикле ордера, для проверки открытых ордеров данным советником
   for ( int i = 0 ; i <= OrdersTotal (); i++)
       if ( OrderSelect (i, SELECT_BY_POS, MODE_TRADES))
         if (OrderSymbol() == Symbol () && OrderMagicNumber() == iMagic)
             return ( false );

   return ( true );
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на покупку |
//+-----------------------------------------------------------------------------------------------+
bool bSignalBuy()
  {
   if (dMA > Open[ 1 ] && dMA < Close[ 1 ])
       return ( true );

   return ( false );
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на продажу |
//+-----------------------------------------------------------------------------------------------+
bool bSignalSell()
  {
   if (dMA < Open[ 1 ] && dMA > Close[ 1 ])
       return ( true );

   return ( false );
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на покупку |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenBuy()
  {
   int iOTi = 0 ;   // Тикет ордера

   iOTi = ReversOrderSend( Symbol (), OP_BUY, LOT(), Ask, iSlippage, 0 , 0 , "" , iMagic, 0 , clrNONE );

// Проверим открылся ли ордер
   if (iOTi > 0 )
       // Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
       // Если нет, то получим ошибку
      vError( GetLastError ());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на продажу |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenSell()
  {
   int iOTi = 0 ;   // Тикет ордера

   iOTi = ReversOrderSend( Symbol (), OP_SELL, LOT(), Bid, iSlippage, 0 , 0 , "" , iMagic, 0 , clrNONE );

// Проверим открылся ли ордер
   if (iOTi > 0 )
       // Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
       // Если нет, то получим ошибку
      vError( GetLastError ());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                    Функция модификации ордера |
//+-----------------------------------------------------------------------------------------------+
void vOrderModify( int iOTi)
  {
   int     iOTy = - 1 ;   // Тип ордера
   double dOOP = 0 ;     // Цена открытия ордера
   double dOSL = 0 ;     // Стоп Лосс
   int     iMag = 0 ;     // Идентификатор советника

   double dSL = 0 ;     // Уровень убытка
   double dTP = 0 ;     // Уровень прибыли

// Выберем по тикету открытый ордер, получим некоторые значения
   if ( OrderSelect (iOTi, SELECT_BY_TICKET, MODE_TRADES))
     {
      iOTy = OrderType();
      dOOP = OrderOpenPrice();
      dOSL = OrderStopLoss();
      iMag = OrderMagicNumber();
     }

// Если ордер открыл данный советник, то входим в условие
   if (OrderSymbol() == Symbol () && OrderMagicNumber() == iMag)
     {
       // Если Стоп Лосс текущего ордера равен нулю, то модифицируем ордер
       if (dOSL == 0 )
        {
         if (iOTy == OP_BUY)
           {
            dSL = NormalizeDouble (dOOP - iStopLoss * Point , Digits );
            dTP = NormalizeDouble (dOOP + iTakeProfit * Point , Digits );

             bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0 , clrNONE );
           }

         if (iOTy == OP_SELL)
           {
            dSL = NormalizeDouble (dOOP + iStopLoss * Point , Digits );
            dTP = NormalizeDouble (dOOP - iTakeProfit * Point , Digits );

             bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0 , clrNONE );
           }
        }
     }
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                      Функция обработки ошибок |
//+-----------------------------------------------------------------------------------------------+
void vError( int iErr)
  {
   switch (iErr)
     {
       case 129 :   // Неправильная цена
       case 135 :   // Цена изменилась
       case 136 :   // Нет цен
       case 138 :   // Новые цены
         Sleep ( 1000 );
         RefreshRates();
         break ;

       case 137 :   // Брокер занят
       case 146 :   // Подсистема торговли занята
         Sleep ( 3000 );
         RefreshRates();
         break ;
     }
  }
//+-----------------------------------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double LOT()
  {
   int n= 0 ;
   double OL=dLots;
   for ( int j = OrdersHistoryTotal()- 1 ; j >= 0 ; j--)
     {
       if ( OrderSelect (j, SELECT_BY_POS,MODE_HISTORY))
        {
         if (OrderSymbol() == Symbol () && OrderMagicNumber() == iMagic)
           {
             if (OrderProfit()< 0 )
              {
               if (n== 0 )
                  OL= NormalizeDouble (OrderLots()*K_Martin,DigitsLot);
               n++;
               if (n>=OrdersClose)
                 {
                   Comment ( "1" );
                   return (dLots);
                 }
              }
             else
              {
               if (n== 0 )
                 {
                   Comment ( "2" );
                   return (dLots);
                 }
               else
                 {
                   Comment ( "3" );
                   return (OL);
                 }
              }
           }
        }
     }
   return (OL);
  }
//------------------------------------------------------------------
int ReversOrderSend ( string symbol, int cmd, double volume, double price, int slippage, double stoploss, double takeprofit, string comment, int magic= 0 , datetime expiration= 0 , color arrow_color=CLR_NONE)
{
int Ret= 0 ;
double sprd=MarketInfo(symbol, MODE_SPREAD )* Point ;
//Print ("----------------------------",sprd);
if (ReversOrder== 0 ) // Открываем ордера без разворота
{
Ret= OrderSend (symbol,cmd,volume,price,slippage,stoploss,takeprofit,comment,magic,expiration,arrow_color);
}
if (ReversOrder== 1 )
{
///////////////
if (cmd==OP_SELLSTOP) // Переворачиваем ордера OP_SELLSTOP
{
Ret= OrderSend (symbol,OP_BUYLIMIT,volume,price+sprd,slippage,takeprofit-sprd,stoploss-sprd,comment,magic,expiration,arrow_color);
}
if (cmd==OP_BUYSTOP) // Переворачиваем ордера OP_BUYSTOP
{
Ret= OrderSend (symbol,OP_SELLLIMIT,volume,price-sprd,slippage,takeprofit+sprd,stoploss+sprd,comment,magic,expiration,arrow_color);
}
///////////////
if (cmd==OP_SELL) // Переворачиваем ордера OP_SELL
{
Ret= OrderSend (symbol,OP_BUY,volume,price+sprd,slippage,takeprofit-sprd,stoploss-sprd,comment,magic,expiration,arrow_color);
}
if (cmd==OP_BUY) // Переворачиваем ордера OP_BUY
{
Ret= OrderSend (symbol,OP_SELL,volume,price-sprd,slippage,takeprofit+sprd,stoploss+sprd,comment,magic,expiration,arrow_color);
}
//////////////
if (cmd==OP_SELLLIMIT) // Переворачиваем ордера OP_SELLLIMIT
{
Ret= OrderSend (symbol,OP_BUYSTOP,volume,price+sprd,slippage,takeprofit-sprd,stoploss-sprd,comment,magic,expiration,arrow_color);
}
if (cmd==OP_BUYLIMIT) // Переворачиваем ордера OP_BUYLIMIT
{
Ret= OrderSend (symbol,OP_SELLSTOP,volume,price-sprd,slippage,takeprofit+sprd,stoploss+sprd,comment,magic,expiration,arrow_color);
}
}
return (Ret);
}
Предлагаю функцию реверса ордеров, для сливающих советников.
Предлагаю функцию реверса ордеров, для сливающих советников.
  • 2010.08.24
  • www.mql5.com
Помню, поначалу сталкивался с вопросом, как грамотно "перевернуть" ордера с покупки на продажу и наоборот...
 
Alexey Viktorov :

나는 이미 모든 것을 충분히 명확하게 말했습니다. 음, 개인적으로 묻겠습니다.

여기에 두 가지 기능이 있으며 둘 다 과거 주문 을 반복합니다.

동일한 주문에 대한 두 개의 사이클. 이 함수가 한 사이클에서 반환하는 모든 것을 얻을 수 있는 방법이 있습니까?

Alexey, 나는 이미 썼습니다. 당신이 좋은 프로그래머라는 것을 압니다!

그러나 나는 프로그래머가 아니며 당신에게 "충분히 분명한" 것은 나에게 어두운 숲입니다...

그리고 약 2주기 동안 " 한주기에 모든 것을 얻으 려면"이 절대 아닙니다. 왜냐하면. 그들은 다른 유형의 데이터를 반환합니다.

 
MakarFX :

Alexey, 나는 이미 썼습니다. 당신이 훌륭한 프로그래머라는 것을 압니다!

그러나 나는 프로그래머가 아니며 당신에게 "충분히 분명한" 것은 나에게 어두운 숲입니다...

그리고 약 2주기 동안 " 한주기에 모든 것을 얻으 려면"이 절대 아닙니다. 왜냐하면. 그들은 다른 유형의 데이터를 반환합니다.

반환 유형은 그것과 아무 관련이 없습니다. 다른 검사와 필터를 사용하여 동일한 데이터에 대해 2개의 주기가 있는 경우 항상 모든 것을 하나의 주기에 넣을 수 있지만 코드가 명확하게 읽히지는 않지만 더 빠르게 작동해야 합니다.) 디버깅 단계에서는 하지 않습니다. 한 사이클의 모든 것. 다른 버그에서는 찾기가 더 쉽습니다.

 
MakarFX :

Alexey, 나는 이미 썼습니다. 당신이 훌륭한 프로그래머라는 것을 압니다!

그러나 나는 프로그래머가 아니며 당신에게 "충분히 분명한" 것은 나에게 어두운 숲입니다...

그리고 약 2주기 동안 " 한주기에 모든 것을 얻으 려면"이 절대 아닙니다. 왜냐하면. 그들은 다른 유형의 데이터를 반환합니다.

두 가지 옵션이 있습니다.

  1. 전역 수준에서 수행할 변수입니다. 그러면 모든 기능에서 사용할 수 있습니다.
  2. 참조로 지역 변수 를 전달합니다. 그런 다음 이 변수가 변경되면 해당 지역 변수도 변경됩니다.
     /********************Script program start function*******************/
    void OnStart ()
     {
       int a = 0 ;
      f_0(a);
       Print (a);
     } /******************************************************************/
    
    void f_0( int & b)
     {
      b = 100 ;
     }
    그리고 그런 변수가 최대 64개까지 있을 수 있습니다. 그렇지 않으면 누군가가 저를 수정해 줄 것입니다.
  3. 문서를 주의 깊게 자주 읽으십시오. 그것에 대해 모든 세부 사항이 기록되어 있습니다.
 
MakarFX :

시도, 질문

첫 번째 결과입니다. 고문이 보류 중인 주문 을 할 때 통화 쌍 간에 충돌이 있습니다. 예를 들어 EURUSD에 지연을 던졌습니다. 어드바이저는 알고리즘에 따라 작업했습니다(1.18901의 가격에 거래가 열렸고, 어드바이저는 1.18751에 스탑을 설정하고 1.19051의 테이크를 설정 하고 가격에 매도를 위한 지연을 설정했습니다. 1.18751 ) 모든 것이 계획대로 괜찮습니다.

그러나 가격이 다르고 고문이 보류 중인 주문을 하는 것을 제외하고 모든 것을 올바르게 수행하는 GBPUSD에서 거래를 시작할 때입니다. 보류 중인 판매 1.39393이 작동하고 EA가 작동하기 시작하여 1.39633에서 정지하고 1.39153의 테이크를 설정했지만 EURUSD로 1.39633의 가격으로 보류 중인 구매를 완전히 복제하고 1.18751의 가격 으로 보류 중인 판매를 넣었습니다)

방금 또 다른 문제를 발견했습니다. EURUSD의 미결 거래에서 1.18751에서 스탑이 발생하고 EA가 1.18901에서 스탑을 설정하고 1.18595를 테이크하는 판매 보류 주문이 열렸습니다. EA는 기록에 있는 목표에 트리거된 중지를 추가하지 않았습니다.

이것이 문제입니다.

 
законопослушный гражданин :

안녕하세요!

나는 올빼미에게 거래의 쿠데타 를 고정하려고합니다.

무슨 뜻이에요? 매수/매도하는 특정 가격 범위 무역 고문은 "반전"합니다.

 
SGarnov :

안녕하세요. 고문과 함께하십시오. 전략에 따르면 스톱이 트리거되면 어드바이저는 이를 다음 테이크에 추가해야 합니다(포인트 수).
아이디로 히스토리에서 가져오지만 어떤 이유로 추가되지 않습니다.

코드에서 옳지 않은 것은?

 if (isLimitOn && OrderSelect ( OrderMagicNumber() , SELECT_BY_TICKET, MODE_HISTORY)){
            tpc += stop_loss;
             if ( OrderSelect (lastMagic, SELECT_BY_TICKET)){
               if (OrderType() == OP_BUY) {
                   double tp_price = NormalizeDouble ((OrderOpenPrice() + Point () * (tp + tpc)), Digits );
                   if (!OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp_price, OrderExpiration()))
                     Print ( "Ошибка модификации ордера:" , GetLastError ());
               } else if (OrderType() == OP_SELL){
                   double tp_price = NormalizeDouble ((OrderOpenPrice() - Point () * (tp + tpc)), Digits );
                   if (!OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp_price, OrderExpiration()))
                     Print ( "Ошибка модификации ордера:" , GetLastError ());
               }
            }
               
            isLimitOn = false ;
         }

Makar는 OrderMagicNumber()에 올바르게 주의를 끌었지만 오류를 잘못 이해했습니다. 문서에서 이 함수의 구문을 읽으십시오... 주문 목록에 색인이 있거나 특정 주문에 대한 티켓 이 있어야 하지만 마법은 없습니다. 그리고 OrderTicket()은 여기서 도움이 되지 않습니다. 거기에 넣으려고 하지 마세요.

 
SGarnov :

무슨 뜻이에요? 매수/매도하는 특정 가격 범위 무역 고문은 "반전"합니다.

코드 작성자는 내가 이해한 대로 다음을 제안했습니다.

올빼미가 스탑과 테이크를 사용하여 구매 거래를 시작하면 해당 코드 조각은 구매 거래 대신 스탑 및 테이크를 사용 하여 같은 장소(스프레드 고려)에서 동시에 판매 거래를 엽니다.

따라서 EA의 진입점을 찾는 논리는 변경되지 않고 확산을 고려하여 방향만 변경됩니다.

그게 바로 내가 필요한 것입니다

 
MakarFX :

이 조언자에게 바라는 점(작업 논리)을 간단히 설명하십시오.

그렇지 않으면 코드에 추가 항목이 많이 있거나 이해하지 못하는 것 같습니다.

올빼미는 알고리즘에 따라 거래를 시작해야 합니다.

중지인 경우 다음 트랜잭션은 마틴과 함께 하는 식으로 지정된 곱셈 횟수까지 계속됩니다(함수 - OrdersClose = ..... ;).

올빼미라면 더. 터미널과 함께 꺼지고 "자동 거래"버튼, 다른 올빼미 있으면 다음 작업 시작이 시작 로트에서 시작되며 마틴게일에 의해 증가된 마지막 로트에서는 시작되지 않습니다.

일정을 '첨부'하는 것도 좋겠지만, 문득 이 생각이 떠올랐다.

예를 들어 월요일 시작 로트에서 10-00시에 켜지고, 특정 결과에 도달한 날에는 꺼지고, 화요일 아침 10-00시에 다시 켜서 시작 로트에서 다시 시작되었습니다.

모두.

사유: