MQL5: 검증:-(이미 그것이 무엇인지, 그리고 어떻게 해결되는지에 대한 검색으로 내 두뇌를 곤두박질쳤습니다. - 페이지 5

 
//+-----------------------------------------------------------------------------------------------+
//| Функция закрывает позицию Sell                                                                |
//+-----------------------------------------------------------------------------------------------+
void CloseSell(void)
{
   if(trd.PositionClose(sell.ticket))
   {
      /*Print(STR_TIME,"Закрыта позиция Sell, тикет: ",sell.ticket,
                     ", об: ",DoubleToString(sell.volume,2),
                     ", цо: ",DoubleToString(sell.openPrice,symb.Digits()),
                     ", сл: ",DoubleToString(sell.stopLoss,symb.Digits()),
                     ", тп: ",DoubleToString(sell.takeProfit,symb.Digits()));*/
                     
      Print(STR_TIME,"Sell position closed, ticket: ",sell.ticket,
                     ", vl: ",DoubleToString(sell.volume,2),
                     ", op: ",DoubleToString(sell.openPrice,symb.Digits()),
                     ", sl: ",DoubleToString(sell.stopLoss,symb.Digits()),
                     ", tp: ",DoubleToString(sell.takeProfit,symb.Digits()));
      
      ZeroMemory(sell);
      line.Attach(0,"Sell SL",0,1);
      line.Delete();
      line.Attach(0,"Sell TP",0,1);
      line.Delete();
      fiboDn.Delete();
 
Andrey Minaev :

매수 포지션을 청산해야 합니다 .

 
//+-----------------------------------------------------------------------------------------------+
//| Функция закрывает позицию Buy                                                                 |
//+-----------------------------------------------------------------------------------------------+
void CloseBuy(void)
{
   if(trd.PositionClose(buy.ticket))
   {
      /*Print(STR_TIME,"Закрыта позиция Buy, тикет: ",buy.ticket,
                     ", об: ",DoubleToString(buy.volume,2),
                     ", цо: ",DoubleToString(buy.openPrice,symb.Digits()),
                     ", сл: ",DoubleToString(buy.stopLoss,symb.Digits()),
                     ", тп: ",DoubleToString(buy.takeProfit,symb.Digits()));*/
                     
      Print(STR_TIME,"Buy position closed, ticket: ",buy.ticket,
                     ", vl: ",DoubleToString(buy.volume,2),
                     ", op: ",DoubleToString(buy.openPrice,symb.Digits()),
                     ", sl: ",DoubleToString(buy.stopLoss,symb.Digits()),
                     ", tp: ",DoubleToString(buy.takeProfit,symb.Digits()));
      
      
      ZeroMemory(buy);
      line.Attach(0,"Buy SL",0,1);
      line.Delete();
      line.Attach(0,"Buy TP",0,1);
      line.Delete();
      fiboUp.Delete();
 
Andrey Minaev :

가정: 위의 코드에서 거래량을 잘못 계산했습니다(더 정확하게는 그러한 거래량으로 개설 가능성을 잘못 확인함) - 포지션을 연 후 여유 증거금 대신 총 여유 증거금을 사용합니다. 또한 먼저 m_symbol.LotsLimit()에 무엇이 설정되어 있는지 확인해야 합니다.

Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
 
//+-----------------------------------------------------------------------------------------------+
//| Функция рассчитывает объем позиции                                                            |
//+-----------------------------------------------------------------------------------------------+
double CalculateVolume( ENUM_ORDER_TYPE type)
{
   double volume= 0 ;
   
   double size=cndl.high-cndl.low;
   double sl=(size*inpStopLoss* 0.01 )/symb. Point ();
   double risk= AccountInfoDouble ( ACCOUNT_BALANCE )*inpRisk* 0.01 ;
   
   if (sl== 0 || symb.TickValue()== 0 )
       return 0 ;
   
   volume=(risk/sl)/symb.TickValue();
   
   if (inpMaxVolume> 0 && inpMaxVolume<volume)
   {
      volume=inpMaxVolume;
       //Print(STR_TIME,"Установлен максимальный объем установленный в настройках");
       //Print(STR_TIME,"The maximum volume set in the settings is set");
   }
   
   double minVolume=symb.LotsMin();
   double maxVolume=symb.LotsMax();
   
   if (volume<minVolume)
   {
      volume=minVolume;
       //Print(STR_TIME,"Установлен минимальный объем допустимый брокером");
       //Print(STR_TIME,"The minimum volume allowed by the broker is set");
   }
   if (volume>maxVolume)
   {
      volume=maxVolume;
       //Print(STR_TIME,"Установлен максимальный объем допустимый брокером");
       //Print(STR_TIME,"The maximum volume allowed by the broker is set");
   }
   double mVolume=symb.LotsLimit();
   double tVolume=buy.volume+sell.volume;

   if (mVolume> 0 && mVolume-tVolume-volume<= 0 )
       return 0 ;
   
   if (!CheckMoneyForTrade(volume,type))
       return 0 ;
   
   return NormalizeDouble (volume,DigitsLots());
}

저도 예전에 사용했는데 같은 에러가 나는데 하단에 한도가 체크되어 있습니다.

 

나는 특별히 테스트 어드바이저를 만들었고, 이 어드바이저는 검증 중입니다.

 //+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version    "1.00"

#include <Trade\Trade.mqh>
CTrade trd;

input double inpVolume= 0.01234 ;

bool allowOpen;
bool allowClose;
ulong posTicket;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit ( void )
{
   return INIT_SUCCEEDED ;
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason)
{
   
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick ( void )
{
   if (CheckNewCandle())
   {
       if ( PositionSelect ( _Symbol ))
         allowClose= true ;
      
      allowOpen= true ;
   }
   
   if (allowClose)
      ClosePosition();
   
   if (allowOpen && !allowClose)
      OpenPosition();
}
//+------------------------------------------------------------------+
bool CheckNewCandle( void )
{
   static datetime prevTime= 0 ;
           datetime currTime= iTime ( _Symbol , PERIOD_CURRENT , 0 );
   
   if (prevTime!=currTime)
   {
      prevTime=currTime;
       return true ;
   }
   return false ;
}
//+------------------------------------------------------------------+
void ClosePosition( void )
{
   if (trd.PositionClose(posTicket))
   {
      allowClose= false ;
      posTicket= 0 ;
   }
}
//+------------------------------------------------------------------+
void OpenPosition( void )
{
   double volume=inpVolume;
   volume= NormalizeDouble (volume,DigitsLots());
   volume=CheckVolumeValue(volume);
   if (!CheckMoneyForTrade( _Symbol ,volume, ORDER_TYPE_BUY ))
   {
      allowOpen= false ;
       return ;
   }
   
   if (trd.Buy(volume))
   {
      allowOpen= false ;
      posTicket=trd.ResultOrder();
   }
}
//+------------------------------------------------------------------+
bool CheckMoneyForTrade( string symb, double lots, ENUM_ORDER_TYPE type)
  {
//--- получим цену открытия
   MqlTick mqltick;
   SymbolInfoTick (symb,mqltick);
   double price=mqltick.ask;
   if (type== ORDER_TYPE_SELL )
      price=mqltick.bid;
//--- значения необходимой и свободной маржи
   double margin,free_margin= AccountInfoDouble ( ACCOUNT_MARGIN_FREE );
   //--- вызовем функцию проверки
   if (! OrderCalcMargin (type,symb,lots,price,margin))
     {
       //--- что-то пошло не так, сообщим и вернем false
       Print ( "Error in " , __FUNCTION__ , " code=" , GetLastError ());
       return ( false );
     }
   //--- если не хватает средств на проведение операции
   if (margin>free_margin)
     {
       //--- сообщим об ошибке и вернем false
       Print ( "Not enough money for " , EnumToString (type), " " ,lots, " " ,symb, " Error code=" , GetLastError ());
       return ( false );
     }
//--- проверка прошла успешно
   return ( true );
  }
//+------------------------------------------------------------------+
double CheckVolumeValue( double volume)
  {
//--- минимально допустимый объем для торговых операций
   double min_volume= SymbolInfoDouble ( Symbol (), SYMBOL_VOLUME_MIN );
   if (volume<min_volume)
     {
       PrintFormat ( "SYMBOL_VOLUME_MIN=%.2f" ,min_volume);
      volume=min_volume;
     }

//--- максимально допустимый объем для торговых операций
   double max_volume= SymbolInfoDouble ( Symbol (), SYMBOL_VOLUME_MAX );
   if (volume>max_volume)
     {
       PrintFormat ( "SYMBOL_VOLUME_MAX=%.2f" ,max_volume);
      volume=max_volume;
     }

//--- получим минимальную градацию объема
   double volume_step= SymbolInfoDouble ( Symbol (), SYMBOL_VOLUME_STEP );

   int ratio=( int ) MathRound (volume/volume_step);
   if ( MathAbs (ratio*volume_step-volume)> 0.0000001 )
     {
       PrintFormat ( "SYMBOL_VOLUME_STEP=%.2f, %.2f" ,
                               volume_step,ratio*volume_step);
                               volume=ratio*volume_step;
     }
   return volume;
  }
//+------------------------------------------------------------------+  
int DigitsLots( void ) 
{
   return ( int )( MathLog ( 1.0 / SymbolInfoDouble ( _Symbol , SYMBOL_VOLUME_STEP ))/ MathLog ( 10.0 ));
}
//+------------------------------------------------------------------+

필요한 고문에 대해 동일한 검사를 수행하면 오류가 발생합니다.

 
Andrey Minaev :

나는 특별히 테스트 어드바이저를 만들었고, 이 어드바이저는 검증 중입니다.

필요한 고문에 대해 동일한 검사를 수행하면 오류가 발생합니다.

당신은 전혀 읽지 않습니다: 포지션을 연 후 자유 마진 대신에 모든 자유 마진을 사용하는 이유 .

일반적으로 기사를 읽고 다시 읽으십시오.


추가됨: 방금 마지막 코드를 확인했습니다 - 특별히 거래 신호 기능에 계수 를 추가했습니다 - LotCheck를 사용하기 위해

 //+------------------------------------------------------------------+
//| Search trading signals                                           |
//+------------------------------------------------------------------+
bool SearchTradingSignals( void )
  {
   double fast[],slow[];
   MqlRates rates[];
   ArraySetAsSeries (fast, true );
   ArraySetAsSeries (slow, true );
   ArraySetAsSeries (rates, true );
   int start_pos= 0 ,count= 6 ;
   string name=Inp_MA_Symbol;
   if (!iGetArray(handle_iMA_Fast, 0 ,start_pos,count,fast) ||
      !iGetArray(handle_iMA_Slow, 0 ,start_pos,count,slow) ||
       CopyRates (name,Inp_MA_period,start_pos,count,rates)!=count)
     {
       return ( false );
     }
   int size_need_position= ArraySize (SPosition);
   if (fast[m_bar_current+ 1 ]<slow[m_bar_current+ 1 ] &&fast[m_bar_current]>slow[m_bar_current])
       if (fast[m_bar_current]-slow[m_bar_current]>=m_min_intersections_height)
        {
         if (m_prev_bars==m_last_deal_in) // on one bar - only one deal
             return ( true );
         if (!InpReverse)
           {
             ArrayResize (SPosition,size_need_position+ 1 );
            SPosition[size_need_position].pos_type= POSITION_TYPE_BUY ;
            SPosition[size_need_position].lot_coefficient= 1.087 ;
             if (InpPrintLog)
               Print ( __FILE__ , " " , __FUNCTION__ , ", OK: " , "Signal BUY" );
             return ( true );
           }
         else
           {
             ArrayResize (SPosition,size_need_position+ 1 );
            SPosition[size_need_position].pos_type= POSITION_TYPE_SELL ;
            SPosition[size_need_position].lot_coefficient= 1.087 ;
             if (InpPrintLog)
               Print ( __FILE__ , " " , __FUNCTION__ , ", OK: " , "Signal SELL" );
             return ( true );
           }
        }
   if (fast[m_bar_current+ 1 ]>slow[m_bar_current+ 1 ] &&fast[m_bar_current]<slow[m_bar_current])
       if (slow[m_bar_current]-fast[m_bar_current]>=m_min_intersections_height)
        {
         if (m_prev_bars==m_last_deal_in) // on one bar - only one deal
             return ( true );
         if (!InpReverse)
           {
             ArrayResize (SPosition,size_need_position+ 1 );
            SPosition[size_need_position].pos_type= POSITION_TYPE_SELL ;
            SPosition[size_need_position].lot_coefficient= 1.087 ;
             if (InpPrintLog)
               Print ( __FILE__ , " " , __FUNCTION__ , ", OK: " , "Signal SELL" );
             return ( true );
           }
         else
           {
             ArrayResize (SPosition,size_need_position+ 1 );
            SPosition[size_need_position].pos_type= POSITION_TYPE_BUY ;
            SPosition[size_need_position].lot_coefficient= 1.087 ;
             if (InpPrintLog)
               Print ( __FILE__ , " " , __FUNCTION__ , ", OK: " , "Signal BUY" );
             return ( true );
           }
        }
//---
   return ( true );
  }

EA는 휘파람과 함께 유효성 검사를 통과했습니다.

 
이러한 오류에 대해 읽을 수 있는 위치와 일반적으로 어떤 종류의 오류인지.
 

.

불분명

 
Andrey Minaev :

.

불분명

작성: 거대한 로그 파일. 디스크에 맞지 않아 테스트가 중단되었습니다. 번역기를 사용하십시오.