mql5 언어의 특징, 미묘함 및 작업 방법 - 페이지 32

 

이와 같이 표시기의 준비 상태를 확인합니다( OnCalculate 시작 시).

   int calculated= BarsCalculated (IND_handle);
   if (calculated<= 0 || ! SymbolIsSynchronized ( _Symbol ) || rates_total<= 0 || rates_total-prev_calculated< 0 ) 
      { 
       Comment ( "Calculate..." );
       return ( 0 );
      }

기간 확인을 추가할 수도 있습니다.

 SeriesInfoInteger ( _Symbol ,ind_period, SERIES_SYNCHRONIZED )
 
알렉세이 빅토로프 :

1. 그냥 설명입니다. 이제 우리가 같은 것에 대해 이야기하고 있다는 것이 분명합니다.

2. 나는 이것을 이해했지만 이것을 위해 어레이를 뒤집을 필요가 있다는 데 동의하지 않습니다. 두 개의 터미널에 대해 하나의 표시기가 필요합니까??? 2in1 낫과 도끼를 만드는 것과 거의 같습니다.

3. Buffer[] 는 CopyBuffer() 함수 에서 수신자가 1개의 표시기 값만 가져오는 데 사용하는 것으로 이해합니다.

4. 가장 중요한 것에 주의를 기울이지 않았습니다. 지표 값의 복사 시작은 막대 인덱스가 아니라 i번째 막대의 시간으로 결정해야 합니다.

1. 좋다.

2. 네 개의 표시기를 다시 작성 하기 때문에 어레이를 뒤집습니다. 모든 것이 제대로 작동하고 모든 데이터가 올바르게 얻어집니다. 그 안에 있는 모든 것은 루프에서 읽은 정확한 순서대로 데이터를 수신하는 것과 관련이 있습니다. 버퍼를 뒤집지 않으면 지표를 처음부터 작성해야 합니다. 이유는 무엇입니까? 꽤 복잡합니다. 이 표시기는 네이티브가 아닌 TF에서 데이터를 가져올 때 발생하는 오류의 예로서만 제공되었습니다.

3. 아니요. 데이터는 루프의 Buffer[]에 한 번에 하나씩 입력됩니다. 루프가 반복될 때마다 AO()에서 얻은 값이 하나씩 입력됩니다.

4. "복사 시작"이란 무엇을 의미합니까?

 
Artyom Trishkin :

1. 좋다.

2. 네 개의 표시기를 다시 작성 하기 때문에 어레이를 뒤집습니다. 모든 것이 제대로 작동하고 모든 데이터가 올바르게 얻어집니다. 그 안에 있는 모든 것은 루프에서 읽은 정확한 순서대로 데이터를 수신하는 것과 관련이 있습니다. 버퍼를 뒤집지 않으면 지표를 처음부터 작성해야 합니다. 이유는 무엇입니까? 꽤 복잡합니다. 이 표시기는 네이티브가 아닌 TF에서 데이터를 가져올 때 발생하는 오류의 예로서만 제공되었습니다.

3. 아니요. 데이터는 루프의 Buffer[]에 한 번에 하나씩 입력됩니다. 루프가 반복될 때마다 AO()에서 얻은 값이 하나씩 입력됩니다.

4. "복사 시작"이란 무엇을 의미합니까?

2. 0에서 Rates_total-1까지의 주기를 만드는 것을 막는 것은 없습니다.

3. 예, 어딘가에서 섞었습니다.

4. 코드에서

 double AO( int shift ){
   double array[];
   ArrayResize (array, 1 );
   ArrayInitialize (array, EMPTY_VALUE );
   error= ERR_SUCCESS ;
   ResetLastError ();
   if ( CopyBuffer (handle, 0 , shift , 1 ,array)== 1 ) {
       ArraySetAsSeries (array, false );
       return (array[ 0 ]);
      }
   else error= GetLastError ();
   return ( EMPTY_VALUE );
}


 int    CopyBuffer (
   int        indicator_handle,     // handle индикатора
   int        buffer_num,           // номер буфера индикатора
   int        start_pos,             // откуда начнем 
   int        count,                 // сколько копируем
   double     buffer[]               // массив, куда будут скопированы данные
   );

로 대체되어야 합니다

 int    CopyBuffer ( 
   int        indicator_handle,     // handle индикатора 
   int        buffer_num,           // номер буфера индикатора 
   datetime   start_time,           // с какой даты 
   int        count,                 // сколько копируем 
   double     buffer[]               // массив, куда будут скопированы данные 
   );

"어디서부터 시작합니까" 또는 "언제부터"는 표시기 값을 수신기 배열에 복사하는 시작입니다.


 
알렉세이 빅토로프 :

3. 예, 어딘가에서 섞었습니다.

4. 코드에서


로 대체되어야 합니다

"어디서부터 시작합니까" 또는 "언제부터"는 표시기 값을 수신기 배열에 복사하는 시작입니다.


루프 인덱스로 값을 읽는 경우 날짜를 전달하는 이유는 무엇입니까? 이 테스트 표시기를 실행하셨습니까? 그는 항상 설정에서 주어진 TF 하나만에서 AO를 뽑습니다. 현재 TF를 어떻게 전환하든 AO 그래프는 항상 설정에서 지정된 TF에 해당합니다.

그리고 바로 그때 모든 데이터가 반으로 죄와 함께 반환되지만 내가 다시 만들고 있는 내 표시기에서 데이터는 네이티브가 아닌 TF에서 반환되지 않으며 적어도 크랙 ...

이 테스트 표시기는 더 이상 필요하지 않습니다. 이미 네이티브가 아닌 TF에서 데이터를 반환합니다. 하지만 내 경우에는 - 아니요. 하지만 정확히 같은 방식으로 데이터를 얻습니다.


 
Artyom Trishkin :

루프 인덱스로 값을 읽는 경우 날짜를 전달하는 이유는 무엇입니까? 이 테스트 표시기를 실행하셨습니까? 그는 항상 설정에서 주어진 TF 하나만으로 AO를 뽑습니다. 현재 TF를 어떻게 전환하든 AO 그래프는 항상 설정에서 지정된 TF에 해당합니다.

그리고 바로 그때 모든 데이터가 반으로 죄와 함께 반환되지만 내가 다시 만들고 있는 내 표시기에서 데이터는 네이티브가 아닌 TF에서 반환되지 않으며 적어도 크랙 ...

이 테스트 표시기는 더 이상 필요하지 않습니다. 이미 네이티브가 아닌 TF에서 데이터를 반환합니다. 하지만 내 경우에는 - 아니요. 하지만 정확히 같은 방식으로 데이터를 얻습니다.


제로 막대 H4에는 4개의 막대 H1이 포함되어 있기 때문입니다. 그리고 H1 기간의 인덱스 2로 H4 기간에 대한 지표 값을 요청하면 H4 기간에 대한 막대 2에 지표 값을 얻습니다.

제가 쓴글이 이해하기 힘드네요...

현재 시간은 13:35입니다. 현재 막대 H1 의 개방 시간 = 13:00. 막대 인덱스 =1, 즉 현재 H1 기간의 막대 12:00으로 표시기 값을 복사하려고 합니다. 그리고 당신은 8:00 기간의 H4 시간에 12:00 대신에 얻습니다.

H1 퍼스트 바 12:00분

H4 퍼스트 바 8:00분

그리고 여기 저기 막대의 인덱스가 첫 번째 ...

 
일반 ArrayCopy는 동일한 연산자를 우회합니다.
 

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

이전 TF에서 지표 데이터를 가져올 수 없습니다.

Artyom Trishkin , 2017.04.14 01:23

표시기의 네 번째 날 동안 더 높은 시간대에서 표준 AO 표시기의 데이터를 가져오려고 했지만 여전히 아무것도...

주기에서 AO 데이터를 읽었지만 기록 데이터가 없는 주기입니다. 현재 막대에 데이터가 있습니다. 캐치가 뭐에요? 내가 무엇을 잘못하고 있지?

 //+------------------------------------------------------------------+
//|                                                       MTF AO.mq5 |
//|              Copyright 2017, Artem A. Trishkin, Skype artmedia70 |
//|                       https://login.mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Artem A. Trishkin, Skype artmedia70"
#property link        "https://login.mql5.com/ru/users/artmedia70"
#property version    "1.00"

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots    1
//--- plot AO
#property indicator_label1   "AO MTF"
#property indicator_type1   DRAW_SECTION
#property indicator_color1   clrRed
#property indicator_style1   STYLE_SOLID
#property indicator_width1   1

//--- indicator buffers
double          BufferAO[];
//+------------------------------------------------------------------+
//|  Enums                                                           |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|  Input Variables                                                 |
//+------------------------------------------------------------------+
sinput    ENUM_TIMEFRAMES    PeriodForWork  =   PERIOD_M5 ;   // Таймфрейм, на котором искать дивергенции
//+------------------------------------------------------------------+
//|  Global Variables                                                |
//+------------------------------------------------------------------+
string             Prefix, symbol;
int                handle_ao;                 // Хэндл AO
int                size_ao= 0 ;                 // Количество скопированных данных AO
double             array_ao[];                 // Массив данных АО
ENUM_TIMEFRAMES    periodForWork;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
//--- indicator buffers mapping
   SetIndexBuffer ( 0 ,BufferAO);
   PlotIndexSetDouble ( 0 , PLOT_EMPTY_VALUE , 0 );
   ArrayInitialize (BufferAO, 0 );
   
   //--- проверка рабочего периода и его смена, если выбран рабочий период меньше текущего
   periodForWork=PeriodForWork;
   if ( Period ()>periodForWork && PeriodForWork!= PERIOD_CURRENT ) {
       Alert ( "Выбран не корректный период: " ,GetNameTF(PeriodForWork), "\nМеняю рабочий период на " ,GetNameTF( Period ()));
      periodForWork= PERIOD_CURRENT ; //GetTFasEnum(Period());
      }

   //--- имена
   symbol= Symbol ();                                                         // Symbol()
   Prefix= "MTFdiv" ;                                                         // Префикс имён объектов
   IndicatorSetString ( INDICATOR_SHORTNAME ,Prefix);                         // Короткое имя индикатора
   
   //--- хэндл AO
   handle_ao= iAO (symbol,periodForWork);
   if (handle_ao== INVALID_HANDLE ) {
       Print ( "Не удалось создать хэндл AO" );
       return ( INIT_FAILED );
      }
   int count=( int ) SeriesInfoInteger (symbol,periodForWork, SERIES_BARS_COUNT );
   size_ao= CopyBuffer (handle_ao, 0 , 0 ,count,array_ao);
//---
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason)
  {
//--- delete graphics
   ObjectsDeleteAll ( 0 ,Prefix);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   ArraySetAsSeries (BufferAO, true );
   ArraySetAsSeries (array_ao, true );
   //---
   ArraySetAsSeries (open, true );
   ArraySetAsSeries (high, true );
   ArraySetAsSeries (low, true );
   ArraySetAsSeries (close, true );
   
   int count=( int ) SeriesInfoInteger (symbol,periodForWork, SERIES_BARS_COUNT );
   //---
   if (rates_total< 1 ) return ( 0 );
   //---
   int limit=rates_total-prev_calculated;
   if (limit> 1 ) {
      limit=rates_total- 1 ;
       ArrayInitialize (BufferAO, 0 );
      }
   
   int periodSeconds= PeriodSeconds (periodForWork); // Количество секунд в рабочем периоде
   static datetime lastTime= 0 ;
   int bar_first= TerminalInfoInteger ( TERMINAL_MAXBARS );
   //--- основной цикл индикатора
   for ( int i=limit; i>= 0 ; i--) {
       //--- Пропускаем отсутствующие бары
       if (i>bar_first) continue ;
      
       //--- Получаем данные АО
       ResetLastError ();
      size_ao= CopyBuffer (handle_ao, 0 , 0 ,count,array_ao);
       if (size_ao< 0 ) Print ( "Ошибка копирования данных AO " , GetLastError ());
      
       //--- время открытия бара на рабочем периоде, соответствующее времени бара i на текущем периоде
       datetime timePeriod=GetTimeOpen(symbol,periodForWork,i);
       //--- если нашли открытие нового бара на рабочем таймфрейме (текущее время больше прошлого)
       if (timePeriod> 0 && timePeriod>lastTime) { 
         //---
         datetime time_work=GetTimeOpen(symbol,periodForWork,i);                 // время открытия i на рабочем таймфрейме
         int bar_work_to_current=GetBarShift(symbol, PERIOD_CURRENT ,time_work);   // бар открытия времени time_work на текущем периоде графика
         double ao_work=GetDataAO(time_work);                                     // значение АО на баре i
         //---
         if (i< 5 ) {
             Print ( "Work period: " ,GetNameTF(periodForWork),
                   ",i=" ,i, ", bar_work_to_current=" ,bar_work_to_current,
                   ", time_work=" , TimeToString (time_work, TIME_MINUTES ),
                   ", ao_work=" , DoubleToString (ao_work, Digits ())
                 );
            }
         BufferAO[bar_work_to_current]=ao_work;
         //--- конец обработки текущего бара
         lastTime=timePeriod; // запомним прошлое время для дальнейшего сравнения с временем следующего бара
         }
       //--- конец цикла индикатора
      }
//--- return value of prev_calculated for next call
   return (rates_total);
  }
//+------------------------------------------------------------------+
//| Functions                                                        |
//+------------------------------------------------------------------+
double GetDataAO( int shift) {
   double array[ 1 ];
   if ( CopyBuffer (handle_ao, 0 ,shift, 1 ,array)== 1 ) return (array[ 0 ]);
   return ( 0 );
}
//+------------------------------------------------------------------+
double GetDataAO( datetime shift) {
   double array[ 1 ];
   if ( CopyBuffer (handle_ao, 0 ,shift, 1 ,array)== 1 ) return (array[ 0 ]);
   return ( 0 );
}
//+------------------------------------------------------------------+
datetime GetTimeOpen( string symbol_name, ENUM_TIMEFRAMES timeframe, int index) {
   datetime array[ 1 ]={- 1 };
   ResetLastError ();
   if ( CopyTime (symbol_name,timeframe,index, 1 ,array)== 1 ) return (array[ 0 ]);
   Print ( __FUNCTION__ , " > Ошибка получения времени бара " ,index, "(" ,GetNameTF(timeframe), "): " , GetLastError ());
   return (- 1 );
}
//+------------------------------------------------------------------+
int GetBarShift( const string symbol_name, const ENUM_TIMEFRAMES timeframe, const datetime time) {
   int res=- 1 ;
   datetime last_bar;
   if ( SeriesInfoInteger (symbol_name,timeframe, SERIES_LASTBAR_DATE ,last_bar)) {
       if (time>last_bar) res= 0 ;
       else {
         const int shift= Bars (symbol_name,timeframe,time,last_bar);
         if (shift> 0 ) res=shift- 1 ;
         }
      }
   return (res);
}
//+------------------------------------------------------------------+
string GetNameTF( int timeframe= PERIOD_CURRENT ) {
   if (timeframe== PERIOD_CURRENT ) timeframe= Period ();
   switch (timeframe) {
       //--- MQL4
       case 1 : return ( "M1" );
       case 5 : return ( "M5" );
       case 15 : return ( "M15" );
       case 30 : return ( "M30" );
       case 60 : return ( "H1" );
       case 240 : return ( "H4" );
       case 1440 : return ( "D1" );
       case 10080 : return ( "W1" );
       case 43200 : return ( "MN" );
       //--- MQL5
       case 2 : return ( "M2" );
       case 3 : return ( "M3" );
       case 4 : return ( "M4" );      
       case 6 : return ( "M6" );
       case 10 : return ( "M10" );
       case 12 : return ( "M12" );
       case 16385 : return ( "H1" );
       case 16386 : return ( "H2" );
       case 16387 : return ( "H3" );
       case 16388 : return ( "H4" );
       case 16390 : return ( "H6" );
       case 16392 : return ( "H8" );
       case 16396 : return ( "H12" );
       case 16408 : return ( "D1" );
       case 32769 : return ( "W1" );
       case 49153 : return ( "MN" );      
       default : return ( "UnknownPeriod" );
   }
}
//+------------------------------------------------------------------+


 
Artyom Trishkin :

나에 관해서는, 당신은 "잘못된" 일을 많이 하고 있습니다. 수행해야 할 작업을 설명하십시오. 순차적으로, 한 점씩.
 

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

mql5 언어의 특징, 미묘함 및 작업 방법

fxsaber , 2017.02.27 18:40

팁 고마워! 야생에서 이것은 SymbolInfoMarginRate입니다. 그래서 지금은
// Размер свободных средств, необходимых для открытия 1 лота на покупку
double GetMarginRequired( const string Symb )
{
   MqlTick Tick;
   double MarginInit, MarginMain;

   return (( SymbolInfoTick (Symb, Tick) && SymbolInfoMarginRate (Symb, ORDER_TYPE_BUY , MarginInit, MarginMain)) ? MarginInit * Tick.ask *
           SymbolInfoDouble (Symb, SYMBOL_TRADE_TICK_VALUE ) / ( SymbolInfoDouble (Symb, SYMBOL_TRADE_TICK_SIZE ) * AccountInfoInteger ( ACCOUNT_LEVERAGE ) ) : 0 );
}

MT5에서는 다른 방향에서 완전히 다른 마진 요구 사항이 있을 수 있음을 분명히 이해해야 합니다. 저것들. 단일 MT4 옵션은 롤링되지 않을 수 있습니다. Forex는 물론 이런 일이 발생하지 않습니다. 하지만 기억해야 합니다. 따라서 일반적으로 다음과 같이 작성해야 합니다.
// Альтернатива OrderCalcMargin
bool MyOrderCalcMargin(  const ENUM_ORDER_TYPE action, const string symbol, const double volume, const double price, double &margin )
{
   double MarginInit, MarginMain;

   const bool Res = SymbolInfoMarginRate (symbol, action, MarginInit, MarginMain);
  
  margin = Res ? MarginInit * price * volume * SymbolInfoDouble (symbol, SYMBOL_TRADE_TICK_VALUE ) /
                 ( SymbolInfoDouble (symbol, SYMBOL_TRADE_TICK_SIZE ) * AccountInfoInteger ( ACCOUNT_LEVERAGE )) : 0 ;
  
   return (Res);  
}

선택 항목 은 0을 반환할 수 있습니다. BCS가 충돌했습니다.

다음과 같이 했습니다.

 //+------------------------------------------------------------------+
//| Альтернатива стандартному OrderCalcMargin()                      |
//+------------------------------------------------------------------+
//--- 
bool CGetClass:: OrderCalcMargin ( const ENUM_ORDER_TYPE action, const string symbol_name, const double volume, const double price, double &margin){
   double margin_init= 0 ,margin_main= 0 ;
   const bool res= SymbolInfoMarginRate (symbol_name,action,margin_init,margin_main);
   int liverage= int ( AccountInfoInteger ( ACCOUNT_LEVERAGE )== 0 ? 1 : AccountInfoInteger ( ACCOUNT_LEVERAGE ));
   margin=res?margin_init*price*volume* SymbolInfoDouble (symbol_name, SYMBOL_TRADE_TICK_VALUE )/
                 ( SymbolInfoDouble (symbol_name, SYMBOL_TRADE_TICK_SIZE ) *liverage ): 0 ;
   
   return (res);  
}
//+------------------------------------------------------------------+


 
알렉세이 코지친 :
나에 관해서는, 당신은 "잘못된" 일을 많이 하고 있습니다. 수행해야 할 작업을 설명하십시오. 순차적으로, 한 점씩.

정확히 무엇이 잘못 되었습니까? 그것은 들린 질문이었습니다. 기본이 아닌 시간 프레임에서 지표 데이터를 가져오기 위해 내가 무엇을 잘못하고 있습니까?

예: 표시기는 M1에서 시작되고 AO의 데이터는 M5에서 수신되어야 합니다. 따라서 한계>1(이력을 다시 계산해야 함)이 있는 동안 M5가 있는 AO는 데이터 부족 오류와 함께 0을 반환합니다. 전체 기록이 계산되자마자(limit==0) M5가 있는 AO의 데이터가 도착하기 시작합니다.