오류, 버그, 질문 - 페이지 3143

 
Wizard # :
안녕하세요! 코드에 PositionSelectByTicket ... 행이 필요합니까? 미리 감사합니다!

무례하게 받아들이지 마세요... 하지만 문서에 분명히 명시되어 있지 않습니까?

함수는 열린 위치 목록에서 인덱스로 위치 티켓을 반환하고 추가 작업을 위해 이 위치를 자동으로 선택합니다.


위치가 이미 선택되어 있는 경우 PositionSelectByTicket 함수로 다시 선택해야 하는 이유

 
Alexey Viktorov # :

무례하게 받아들이지 마세요... 하지만 문서에 분명히 명시되어 있지 않습니까?

위치가 이미 선택되어 있는 경우 PositionSelectByTicket 함수로 다시 선택해야 하는 이유

당신의 답변에 감사드립니다! <Trade/Trade.mqh> 라이브러리를 살펴보니 PositionSelectByTicket이 PositionClose(const ulong ticket,const ulong 편차) 함수에서도 사용되기 때문에 스스로에게 질문을 던졌습니다. 그리고 PositionClose( const ulong ticket,const ulong 편차 ) 함수 자체는 모든 위치를 통과하는 for(int i = PositionsTotal()-1; i >= 0; i--) 루프와 함께 코더에서 자주 사용됩니다. 그리고 나는 그것이 불필요한 곳에서 사용되는지 여부를 생각합니다.
 
Wizard # :
안녕하세요! 코드에 PositionSelectByTicket ... 행이 필요합니까? 미리 감사합니다!
 int IsPositions()
{
   int pos = 0 ;     
   
   int total = PositionsTotal ();
   for ( int i = total- 1 ; i >= 0 ; i--)
   {
       if (! PositionGetTicket (i))
         continue ;        
          
       if ( PositionGetString ( POSITION_SYMBOL ) == Symbol_T && PositionGetInteger ( POSITION_MAGIC ) == EXPERT_MAGIC)
         pos = ( PositionGetInteger ( POSITION_TYPE ) == POSITION_TYPE_BUY ) ? 1 : ( PositionGetInteger ( POSITION_TYPE ) == POSITION_TYPE_SELL ) ? - 1 : 0 ;
   }
   
   return (pos);
}
 
Roman # :
덕분에! 따라서 PositionGetTicket(i)이면 충분하고 PositionSelectByTicket은 필요하지 않습니다.
 
Wizard # :
당신의 답변에 감사드립니다! <Trade/Trade.mqh> 라이브러리를 살펴보니 PositionSelectByTicket이 PositionClose(const ulong ticket,const ulong 편차) 함수에서도 사용되기 때문에 스스로에게 질문을 던졌습니다. 그리고 PositionClose( const ulong ticket,const ulong 편차 ) 함수 자체는 모든 위치를 통과하는 for(int i = PositionsTotal()-1; i >= 0; i--) 루프와 함께 코더에서 자주 사용됩니다. 그리고 나는 그것이 불필요한 곳에서 사용되는지 여부를 생각합니다.

라이브러리에서 PositionClose( const ulong ticket,const ulong 편차 ) 함수는 닫히는 위치의 티켓을 받지만 티켓이 어떻게 수신되었고 위치가 존재하는지 여부는 아무도 모릅니다.

따라서 PositionSelectByTicket은 기껏해야 닫을 것이 있는지 확인하는 역할을 합니다. 그리고 주기의 모든 포지션을 자주 청산하기로 결정한 이유는 무엇입니까? 전혀 필요하지 않습니다...

 
Alexey Viktorov # :

라이브러리에서 PositionClose( const ulong ticket,const ulong 편차 ) 함수는 닫히는 위치의 티켓을 받지만 티켓이 어떻게 수신되었고 위치가 존재하는지 여부는 아무도 모릅니다.

따라서 PositionSelectByTicket은 기껏해야 닫을 것이 있는지 확인하는 역할을 합니다. 그리고 주기의 모든 포지션을 자주 청산하기로 결정한 이유는 무엇입니까? 전혀 필요하지 않습니다...

예, 이제 모든 것을 이해합니다. 나는 최근에 한 명의 고문을 얻었고 Timur Mashnin의 코드와 결합하여 한 포럼에서 귀하의 예(평균 포함)에 따라 작성했습니다. 이제 나는 라이브러리 없이 시스템 기능으로 모든 것을 교체하고 다시 작성하여 조건을 약간 변경하기로 결정했습니다. 간단한 PositionSelect를 사용하면 모든 것이 매우 간단하고 하나의 위치, 하나의 선택, 사이클이 있는 경우 더 많은 고려 사항과 논리를 적용해야 합니다.
 

여보세요

도와주세요, 제발

코드로

테스터의 표시기가 올바르게 작동하도록 했습니다.

그래프에 넣어 잘못된 표시

나는 이유를 알 수 없다

 //+------------------------------------------------------------------+
//|                                                        Oscil.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link        " https://www.mql5.com "
#property version    "1.00"
#property indicator_separate_window
#property   indicator_buffers 5
#property indicator_plots    5

#property   indicator_color1    clrNONE
#property   indicator_color2    clrRoyalBlue
#property   indicator_color3    clrPink
#property   indicator_color4    clrAqua
#property   indicator_color5    clrYellow

#property   indicator_width1 1
#property   indicator_width2 5
#property   indicator_width3 5
#property   indicator_width4 5
#property   indicator_width5 5

double MainLine[];
double UpLine[];
double DnLine[];
double muls[];
double x,y,z;
double price;
double mulSum= 0 ;
double Pi   = 3.1415926535 ;
bool LastUp = false ;
bool GoUp   = false ;
input bool otl    = false ;
/***********Range***************/
int     Length             = 3 ;
int     MajorRangeStrength = 4 ;


double MajorRangeBuy[];
double MajorRangeSell[];


double RangePrice  = 0.0 ,
       SweepB      = 0.0 ;
int     Switch2     = 0 ,
         SwitchB     = 0 ;
double Price2BuyA  = 0.0 ;
int     Price2BuyB  = 1.0 ;
double Price2SellA = 0.0 ;
int     Price2SellB = 0.0 ;
bool    BuySwitchB  = false ,
       SellSwitchB = false ;
       
int hendlMA_1;
double MA_1[];

int hendlMA_2;
double MA_2[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
//--- indicator buffers mapping
   SetIndexBuffer ( 0 ,MainLine, INDICATOR_DATA );
   PlotIndexSetDouble ( 0 , PLOT_EMPTY_VALUE , 0 );
   PlotIndexSetInteger ( 0 , PLOT_DRAW_TYPE , DRAW_HISTOGRAM ); 
   ArraySetAsSeries (MainLine, true );
   
   SetIndexBuffer ( 1 ,UpLine, INDICATOR_DATA );
   PlotIndexSetDouble ( 1 , PLOT_EMPTY_VALUE , 0 );
   PlotIndexSetInteger ( 1 , PLOT_DRAW_TYPE , DRAW_HISTOGRAM ); 
   ArraySetAsSeries (UpLine, true );
   
   SetIndexBuffer ( 2 ,DnLine, INDICATOR_DATA );
   PlotIndexSetDouble ( 2 , PLOT_EMPTY_VALUE , 0 );
   PlotIndexSetInteger ( 2 , PLOT_DRAW_TYPE , DRAW_HISTOGRAM ); 
   ArraySetAsSeries (DnLine, true );
   
   SetIndexBuffer ( 3 ,MajorRangeBuy, INDICATOR_DATA );
   PlotIndexSetDouble ( 3 , PLOT_EMPTY_VALUE , 0 );
   PlotIndexSetInteger ( 3 , PLOT_DRAW_TYPE , DRAW_HISTOGRAM ); 
   ArraySetAsSeries (MajorRangeBuy, true );
   
   SetIndexBuffer ( 4 ,MajorRangeSell, INDICATOR_DATA );
   PlotIndexSetDouble ( 4 , PLOT_EMPTY_VALUE , 0 );
   PlotIndexSetInteger ( 4 , PLOT_DRAW_TYPE , DRAW_HISTOGRAM ); 
   ArraySetAsSeries (MajorRangeSell, true );
   
   hendlMA_1= iMA ( Symbol (), 0 , 1 , 0 , MODE_LWMA , PRICE_CLOSE );
   ArraySetAsSeries (MA_1, true );
   
   hendlMA_2= iMA ( Symbol (), 0 , 1 , 0 , MODE_SMMA , PRICE_CLOSE );
   ArraySetAsSeries (MA_2, true );
   
   ArrayResize (muls, 99 );
   
   mulSum = 0 ;
   
   for ( int i0 = 0 ; i0 < 98 ; i0++) { //повторяем в цикле 98 раз
       if (i0 <= 18 ) y = 1.0 * i0 / 18 ; //если это первые 18 повторений
       else y = (i0 - 18 ) * 7.0 / 79.0 + 1.0 ; //иначе
      
      x = MathCos (Pi * y);
      z = 1.0 / ( 3.0 * Pi * y + 1.0 );
       if (y <= 0.5 ) z = 1 ;
      
      muls[i0] = z * x;
      mulSum += muls[i0];
   }
   if (otl) Print ( " Распределение создано muls[20]=" ,muls[ 20 ]);
//---
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate ( const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[])
  {
//---
   if ( PeriodSeconds () < 60 * 60 || PeriodSeconds () > 10080 * 60 ) return ( 0 );
   int depth= 0 ;

   int l_ind_counted_8 = prev_calculated; //Возвращает количество баров, не измененных после последнего вызова индикатора.
   
   int bars= Bars ( Symbol (), PERIOD_CURRENT );
   if (l_ind_counted_8 < 0 ) return ( 0 );
   if (l_ind_counted_8 == 0 )
      {
         depth = bars - 98 ;
         for ( int a= 0 ;a<bars;a++)
            {
               MainLine[a] = 0 ;
               UpLine[a] = 0 ;
               DnLine[a] = 0 ;
               MajorRangeBuy[a]= 0 ;
               MajorRangeSell[a]= 0 ;
            }
      }
   if (l_ind_counted_8 > 0 )  depth = bars - l_ind_counted_8;
   if (otl) Print ( " количество баров, не измененных после последнего вызова индикатора= " ,l_ind_counted_8, "  Количество баров на текущем графике Bars=" ,bars, "  depth= " ,depth);
   if (l_ind_counted_8 < 1 ) {
       for ( int i2 = 1 ; i2 < 100 ; i2++) {
         MainLine[bars - i2] = 0 ;
         UpLine[bars - i2] = 0 ;
         DnLine[bars - i2] = 0 ;
      }
   }
   
   for ( int i1 = depth; i1 >= 0 ; i1--) 
   {
      price = 0 ;
          
           CopyBuffer (hendlMA_1, 0 , 0 ,bars,MA_1);
          
       for ( int i2 = 0 ; i2 <= 98 ; i2++) 
         {
             if (i2 + i1>=bars) break ;
            price += muls[i2] * MA_1[i2 + i1];
         }
          
       if (mulSum > 0.0 ) MainLine[i1] = price / mulSum;

     GoUp=MainLine[i1 + 1 ] > MainLine[i1] ;
     
       if (GoUp) 
      {
         if (!LastUp) DnLine[i1+ 1 ] = MainLine[i1+ 1 ];
         DnLine[i1] = MainLine[i1];
         UpLine[i1] = 0 ;
      }
         else
      {
         if (LastUp) UpLine[i1+ 1 ] = MainLine[i1+ 1 ];
         UpLine[i1] = MainLine[i1];
         DnLine[i1] = 0 ;
      }
      LastUp=GoUp; 

   } //  for (int i1

 //  return (0);

/***************** Range **********************/

   int counted_bars=prev_calculated;
   if (otl) Print ( " Range counted_bars = " , counted_bars);
   if (counted_bars< 0 ) return (- 1 );
   int position=bars-counted_bars;
   if (position< 0 ) position= 0 ;
   if (position== 0 ) position= 1 ;
   int rnglength = 250 ;
   double range = 0.0 , srange = 0.0 ;
   if (otl) Print ( " position=" ,position);
   
   for ( int pos = position; pos >= 0 ; pos--)
   { /***************** MAIN Range **********************/
      srange = 0.0 ;
       int j = 0 ;
       for ( int i= 0 ;i<rnglength;i++)
      {
         j++;
         int posr = pos + i;
         if (posr >= bars) break ; 
         srange = srange + (High(posr) - Low(posr));
      }
      range = srange / j * Length;
       int BarNumber = bars-pos; //??????????
       if (BarNumber < 0 )  BarNumber = 0 ;
          
           CopyBuffer (hendlMA_2, 0 , 0 ,bars,MA_2);
           //Print(bars," - ",pos);
       if (pos<bars)RangePrice = MA_2[pos];   //Moving Average MODE_SMMA
       else RangePrice = MA_2[pos- 1 ];

       if (BarNumber == 1 )
      {
         SweepB  = range *  MajorRangeStrength;
         Price2BuyA = RangePrice;
         Price2SellA = RangePrice;
      }     

       if (BarNumber > 1 )
      {

         if (Switch2  >  - 1 ) //проверка цикла на покупку
         {
             if (RangePrice < Price2BuyA) //если средняя цена ниже
            {
if (BuySwitchB ) MajorRangeBuy [pos +BarNumber - Price2BuyB] = 0 ;                                                                 //OUT
                           Price2BuyA = RangePrice;
               Price2BuyB = BarNumber;
               BuySwitchB = true ;
            } 
             else if (RangePrice > Price2BuyA)
            {
                            SwitchB = BarNumber - Price2BuyB;
MajorRangeBuy [pos +SwitchB] = MainLine[pos + SwitchB]* 1.0005 ;                                                                                                                           //OUT
                BuySwitchB = true ;

                               if (RangePrice - MA_2[pos + SwitchB] >= SweepB && SwitchB >= 1 )
                              {
                     Switch2 =  - 1 ;
                     Price2SellA = RangePrice;
                     Price2SellB = BarNumber;
                     SellSwitchB = false ;
                     BuySwitchB = false ;
               }
            }
         }
         if (Switch2  < 1 ) //проверка цикла на продажу
         {
             if (RangePrice  > Price2SellA )
            {
if (pos +BarNumber - Price2SellB<bars&&SellSwitchB ) MajorRangeSell [pos +BarNumber - Price2SellB] = 0 ;                                                         //OUT
                           Price2SellA = RangePrice;
               Price2SellB = BarNumber;
               SellSwitchB = true ;
                    }
                       else if (RangePrice < Price2SellA)
                    {
               SwitchB = BarNumber - Price2SellB ;

         if (pos+ SwitchB<bars)MajorRangeSell[pos + SwitchB] =MainLine[pos + SwitchB]* 1.0005 ;                                                                                                                             //OUT
                SellSwitchB = true ;             
        
                               if (pos + SwitchB<bars&&MA_2[pos + SwitchB] - RangePrice >= SweepB && SwitchB >= 1 )
                              {
                                     Switch2 = 1 ;
                     Price2BuyA = RangePrice;
                     Price2BuyB = BarNumber;
                     SellSwitchB = false ;
                     BuySwitchB = false ;
                                  }
            }
         }
      }

   //   MajorRangeSell[pos] = 0;
     //  MajorRangeBuy[pos]  = 0;  
    }
//--- return value of prev_calculated for next call
   return (rates_total);
  }
//+------------------------------------------------------------------+
//========================================================================================
double High( int index)
{   
   if (index < 0 ) return (- 1 );
   double Arr[];
   ENUM_TIMEFRAMES timeframe= PERIOD_CURRENT ;
   if ( CopyHigh ( Symbol (),timeframe, index, 1 , Arr)> 0 ) 
         return (Arr[ 0 ]);
   else return (- 1 );
}
//========================================================================================
double Low( int index)
{   
   if (index < 0 ) return (- 1 );
   double Arr[];
   ENUM_TIMEFRAMES timeframe= PERIOD_CURRENT ;
   if ( CopyLow ( Symbol (),timeframe, index, 1 , Arr)> 0 ) 
         return (Arr[ 0 ]);
   else return (- 1 );
}
 

MqlTradeCheckResult 구조에서 반환되는 것은 무엇입니까?

문서 에는 " 필요한 거래에 필요한 증거금 금액 "이라고 나와 있습니다.

설명

재코드

반환 코드

균형

거래 실행 후 잔액의 가치

형평성

거래 실행 후의 자체 자금 가치

이익

거래 실행 후 발생할 유동 이익의 가치

여유

필요한 거래 작업에 필요한 증거금

margin_free

필요한 거래 작업 실행 후 남아 있는 무료 자체 자금의 양

margin_level

필요한 거래 작업이 완료된 후 설정되는 증거금 수준

논평

응답 코드에 대한 주석, 오류 설명


그러나 실제로는 총 여백의 크기, 현재 및 이 작업이 수행된 후 취할 추가 여백의 크기가 나타납니다.

스크립트는 다음과 같습니다.

 #include <Trade\Trade.mqh>
CTrade trade;
   MqlTradeRequest            my_request;
   MqlTradeCheckResult        my_check_result;
   MqlTick                    mqlTick;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
 {
   SymbolInfoTick ( _Symbol , mqlTick);
  CheckOrder( 0.01 , ORDER_TYPE_SELL );
   Print (my_check_result.margin);
//---
  trade.PositionOpen( _Symbol , ORDER_TYPE_SELL , 0.01 , mqlTick.bid, 0.0 , 0.0 );
//---
  CheckOrder( 0.01 , ORDER_TYPE_SELL );
   Print (my_check_result.margin);
 } /******************************************************************/

/********************************************************************\
||
\********************************************************************/
bool CheckOrder( double volume, ENUM_ORDER_TYPE order_type)
 {
   if (order_type != ORDER_TYPE_BUY && order_type != ORDER_TYPE_SELL )
     return false ;
   ZeroMemory (my_request);
   ZeroMemory (my_check_result);
   bool checkOrder = false ;
//--- setting my_request
  my_request.action = TRADE_ACTION_DEAL ;
  my_request.symbol = _Symbol ;
  my_request.volume = volume;
  my_request.type   = order_type;
  my_request.price  = order_type == ORDER_TYPE_BUY ? mqlTick.ask : mqlTick.bid;
  checkOrder = :: OrderCheck (my_request, my_check_result);
   if (my_check_result.retcode != 0 )
     return ( false );
//---
   return ( true );
 } /******************************************************************/

그리고 실행 결과

 2022.02 . 01 10 : 11 : 28.002 Test bag (EURUSD,H1)     2.25
2022.02 . 01 10 : 11 : 28.108 Test bag (EURUSD,H1)     4.5

my_check_result.margin 계정에는 미결 포지션이 없지만 로트 0.01이 있는 미결 포지션의 마진과 동일하고 계정에 이미 0.01 포지션이 있는 경우 마진은 이미 0.02 로트에 대한 것입니다.

파일:
Test_bag.mq5  5 kb
 
Alexey Viktorov # :

그러나 실제로는 총 여백의 크기, 현재 및 이 작업이 수행된 후 취할 추가 여백의 크기가 나타납니다.

권리.

MarginOpen = CheckResult.margin - :: AccountInfoDouble ( ACCOUNT_MARGIN ); // Маржа для открытия.
 
fxsaber # :

권리.

그렇게 하도록 내버려 두십시오. 그러나 문서는 동일한 방식으로 작성되어야 합니다.

If balans — 거래 실행 후 잔액의 가치

마진은 다음과 같아야 합니다. 거래 실행 후 마진 금액