FORTS Veuillez nous aider - page 6

 
Serj_Che:
Pourquoi répéter dans OnCalculate ce qui était dans OnInit ? Est-ce un tel sort ?)

C'est un simple copier/coller magique))

OK, je vais vous l'expliquer de manière populaire. Il ne suffit pas de vérifier l'état des données une fois sur place. Les données étant générées de manière asynchrone (afin de ne pas ralentir le processus principal), il est possible d'obtenir une erreur de données au moment de la vérification dans l'init (cela dépend de nombreux facteurs).

Par conséquent, vous devez vérifier et (ou seulement) dans calculer et ne pas commencer les calculs principaux avant que toutes les données requises soient disponibles - c'est-à-dire vérifier jusqu'à ce qu'elles soient prêtes à chaque tick.

 
Dima_S:

C'est un simple copier/coller magique))

OK, je vais vous l'expliquer de manière populaire. Il ne suffit pas de vérifier l'état des données une fois sur place. Comme les données sont générées de manière asynchrone (afin de ne pas ralentir le processus principal), au moment de la vérification dans l'init, il est tout à fait possible d'obtenir une erreur de données (cela dépend de nombreux facteurs).

C'est pourquoi la vérification doit être faite et(ou seulement) dans le calcul et ne pas commencer les calculs principaux avant que toutes les données nécessaires soient disponibles - c'est-à-dire vérifier jusqu'à ce qu'il soit prêt à chaque tick.

C'est de cela qu'il s'agit, la fonction OnInit de l'indicateur est une imposture, ou les développeurs ne font pas leur travail.

Le copier/coller est une excellente chose, je le fais moi-même ;)).

 

On a crié et appelé les Tchouktches, mais le problème n'a pas été résolu !

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//
bool is_failed = false;
datetime start_time;
datetime end_time;
int mix_bars, rts_bars, si_bars;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
    start_time = StringToTime( "2015.03.17" );
    end_time = TimeCurrent();
//--- indicator buffers mapping
  mix_bars = GetBars( "MIX-6.15" , PERIOD_CURRENT, start_time, end_time ); 
  if ( mix_bars < 1 )
  {
    is_failed = true;
    Print( "Init failed. MIX-6.15 ");
  }
  rts_bars = GetBars( "RTS-6.15" , PERIOD_CURRENT, start_time, end_time ); 
  if ( rts_bars < 1 )
  {
    is_failed = true;
    Print( "Init failed. RTS-6.15 ");
  }
  si_bars = GetBars( "Si-6.15" , PERIOD_CURRENT, start_time, end_time ); 
  if ( si_bars < 1 )
  {
    is_failed = true;
    Print( "Init failed. Si-6.15 ");
  }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator Get bars function                               |
//+------------------------------------------------------------------+
int GetBars( string symbol, ENUM_TIMEFRAMES period, const datetime start_date, const datetime end_date )
{
  if ( !SymbolInfoInteger( symbol, SYMBOL_SELECT ) )
  {
    ResetLastError();
//---    
    if ( GetLastError() != ERR_MARKET_UNKNOWN_SYMBOL )
    {
      SymbolSelect( symbol, true );
    }
    else
    {
      Print( "GetBars: Неизвестный символ - ", symbol );
      return( 0 );
    }    
  }
//---  
  if ( MQL5InfoInteger( MQL5_PROGRAM_TYPE ) == PROGRAM_INDICATOR && Period() == period && Symbol() == symbol )
  {
    Print( "GetBars: Не пройдена проверка типа программы!" );
    return( 0 );
  }  
//---
  if ( SymbolIsSynchronized( symbol ) )
  {
    return( Bars( symbol, period, start_date, end_date ) );
  }
  else
  {
    long first_date = 0;
    datetime times[1];
//---    
    if ( SeriesInfoInteger( symbol, PERIOD_M1, SERIES_TERMINAL_FIRSTDATE, first_date ) )
    {
      if ( first_date > 0 )
      {
//--- force timeseries build
        CopyTime( symbol, period, datetime( first_date ) + PeriodSeconds( period ), 1, times );
//--- check date
        if ( SeriesInfoInteger( symbol, period, SERIES_FIRSTDATE, first_date ) )
//---        
        if ( first_date > 0 && first_date <= long( start_date ) )
        {
          return( Bars( symbol, period, start_date, end_date ) );
        } 
      }
    }
    Print( "Необходима загрузка истории с сервера!");
  }       
//---  
  return( 0 );
}  
//+------------------------------------------------------------------+
//| 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 ( is_failed )
   {
     Print( "Sorry! Get Bars failed." );
   }
   else Print( "Bingo! We done.");
//--- return value of prev_calculated for next call
   return(rates_total);
  }

Je n'ai pas encore écrit le téléchargement de l'historique, mais les données sont dans le terminal, et elles n'en sortent PAS du premier coup !

2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Необходима загрузка истории с сервера!
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Init failed. RTS-6.15 
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Необходима загрузка истории с сервера!
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Init failed. Si-6.15 
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Sorry! Get Bars failed.
 
Serj_Che:

OK, intéressant !

Les indicateurs fonctionnent dans leur propre fil, les EA dans leur propre fil. Sauf bien sûr si c'est une pierre à noyau unique.

Tout se passe exactement comme il est écrit dans la documentation. :)

J'ai esquissé un indicateur et un EA pour le test + le résultat dans la vidéo.

1) Tout d'abord, je trace un conseiller expert sur un graphique avec la fonction OnTick exécutée pendant 20 secondes.

Le résultat est que le graphique continue de fonctionner et affiche tout comme il se doit. Le graphique fonctionne également comme prévu.

2) Ensuite, nous appliquons au graphique l'indicateur qui a la fonctionOnCalculate pendant 20 secondes.

Résultat : le chat se bloque. En même temps, le prochain chat portant le même symbole et ayant une période différente est également suspendu. Le verre continue de fonctionner comme il le devrait. Une fois que la fonction a fonctionné, tout revient à la normale.

3) La vidéo ne le montre pas - mais si vous lancez l'indicateur sur un chat (réglé sur 60 sec), et l'expert sur l'autre - l'expert ne commence pas à fonctionner avant que l'indicateur sur l'autre chat ne se bloque !

J'ai joint la vidéo séparément - c'est lent dans mon navigateur.

 
MigVRN:

Tout se passe exactement comme indiqué dans la documentation. :)

Esquisse d'un indicateur et d'un Expert Advisor pour vérification + le résultat sur la vidéo.

1) Tout d'abord, je l'envoie sur le graphique du conseiller expert qui contient la fonction OnTick qui fonctionne pendant 20 secondes.

Le résultat est que le graphique continue de fonctionner et affiche tout comme il se doit. Le graphique fonctionne également comme prévu.

2) Ensuite, nous appliquons au graphique l'indicateur qui a la fonctionOnCalculate pendant 20 secondes.

Résultat : le chat se bloque. En même temps, le prochain chat portant le même symbole et ayant une période différente est également suspendu. Le verre continue de fonctionner comme il le devrait. Une fois que la fonction a fonctionné, tout revient à la normale.

3) La vidéo ne le montre pas - mais si vous lancez un indicateur sur un chat (réglé sur 60 sec), et un EA sur l'autre - l'EA ne commence pas à fonctionner jusqu'à ce que l'indicateur fonctionne mal sur un autre chat !

J'ai joint la vidéo séparément - mon navigateur est lent.

Merci, je n'arrive pas à avoir une vidéo à regarder, je vais me renseigner.

 

Si vous essayez d'obtenir des données de l'environnement de négociation lorsque vous travaillez à partir de l'indicateur, n'essayez même pas de définir des requêtes dans OnInit(). Faites des requêtes et vérifiez la réponse dans OnCalculate(). Lorsque vous recevez des données d'un autre symbole ou d'une autre période, il est presque garanti que, même dans OnCalculate, vous ne réussirez pas à recevoir les données de la première fois. C'est pourquoi vous devez vérifier le retour des valeurs. Si aucune valeur n'est obtenue, essayez d'obtenir des données au prochain tick dans OnCalculate().


Il est également déjà intéressant de voir la réponse de Servicedesk - le code qui a été fourni.

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie

FORTS Veuillez nous aider

alexvd, 2015.03.26 15:48

Le code source vous a été donné par Servisdesk. Essayez de mettre votre dernier code dans la fonction Test().

Intérêt déjà sportif - l'auteur continue à écrire son propre code et ignore le code servicedesk ?

 
barabashkakvn:

Si vous essayez d'obtenir des données de l'environnement de négociation lorsque vous travaillez à partir de l'indicateur, n'essayez même pas de définir des requêtes dans OnInit(). Faites des requêtes et vérifiez la réponse dans OnCalculate(). Lorsque vous recevez des données d'un autre symbole ou d'une autre période, il est presque garanti que, même dans OnCalculate, vous ne réussirez pas à recevoir les données de la première fois. C'est pourquoi vous devez vérifier si les valeurs sont retournées. Si aucune valeur n'est reçue, essayez de recevoir des données au prochain tick dans OnCalculate().

+++ et ainsi de suite. C'est-à-dire s'il n'y a pas de données - retour ;
 
MigVRN:
+++ et ainsi de suite jusqu'à la fin. C'est-à-dire que s'il n'y a pas de données, retour ;
Cela dépend de ce que vous voulez interroger. Et le nombre de requêtes à effectuer dépend entièrement des préférences de l'auteur du code.
 
barabashkakvn:
Cela dépend de ce qu'il faut interroger. Et combien de requêtes - cela dépend entièrement des préférences de l'auteur du code.

Vous comprenez que

S'il y a des données dans le terminal, alors la fonction

SeriesInfoInteger( symbol, PERIOD_M1, SERIES_TERMINAL_FIRSTDATE, first_date )

ne devrait pas retourner FALSE ?

P/S le code SD ne fonctionne pas non plus dès la première fois !

 

UNE FOIS DE PLUS.

de l'aide :

SeriesInfoInteger

Renvoie des informations sur l'état des données historiques. Il existe 2 variantes de cette fonction.

Deuxième variante :

bool  SeriesInfoInteger(
   string                     symbol_name,     // имя символа
   ENUM_TIMEFRAMES            timeframe,       // период
   ENUM_SERIES_INFO_INTEGER   prop_id,         // идентификатор свойства
   long&                      long_var         // переменная для получения информации
   );

SÉRIE_TERMINAL_FIRSTDATE.

Première date dans l'historique selon le symbole dans le terminal du client sans tenir compte de la période.

datetime

LA FONCTION NE DEVRAIT PAS RETOURNER FALSE SI IL Y A DES DONNÉES DANS LE TERMINAL !!!

Peu importe d'où vous l'appelez !