Comment modifier la structure de la variable globale de l'indicateur lors du passage à une autre période ? - page 4

 
Nikolai Semko:
Personnellement, j'utilise les ressources via le syndicat.
Même les réseaux de structures sont facilement transférés entre les TF sans avoir à écrire dans un fichier.

Pouvez-vous nous en dire plus ? Merci.

 
Mikhail Nazarenko:

Pouvez-vous nous en dire plus ? Merci.

Je l'écrirai dans le QB un jour.
En fait, voici la classe pour ça.
Et il suffit d'ajouter deux lignes à l'indicateur :
.

  • Créez une instance de cette classe avant le OnInit, en liant votre tableau de structures à passer entre les TFs. S'il ne s'agit pas de la première initialisation, le tableau de structures sera rempli avec les données du TF précédent.
  • A OnDeinit, sauvegardez votre tableau via une seule méthode dans cette classe.

template <typename T>
class CStructArr {
 private:
   union StructUint {
      T st;
      uint u[1+sizeof(T)/4];
   };
   string            Name;
   uint              Var[];
   int               w;
   int               h;
   StructUint        su;
   int               size;

 public:
   CStructArr(const string name,T &var[]);
   ~CStructArr();
   bool              Set(T &var[]);
   //bool              Save();
   T                 value[];
};
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
template <typename T>
CStructArr::CStructArr(const string name,T &var[]) {
   //ulong tt=GetMicrosecondCount();
   size = ArraySize(var);
   w=1+size*sizeof(T)/4;
   ArrayResize(Var,w);
   h=1;
   Name="::"+name+ IntegerToString(ChartGetInteger(0,CHART_WINDOW_HANDLE));
   if(ResourceReadImage(Name,Var,w,h)) {
      size = 4*(w-1)/sizeof(T);
      ArrayResize(value,size);
      ArrayResize(var,size);
      for (int j=0; j<size; j++) {
         for(int i=0; i<sizeof(T)/4; i++) su.u[i]=Var[j*sizeof(T)/4+i];
         value[j]=su.st;
         var[j]=value[j];
      }
   } else {
      for (int j=0; j<size; j++) {
         su.st=var[j];
         for(int i=0; i<sizeof(T)/4; i++) Var[j*sizeof(T)/4+i]=su.u[i];
         value[j]=var[j];
      }
      if(!ResourceCreate(Name,Var,w,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA)) printf("Error create Resource: "+DoubleToString(GetLastError(),0));
   }
   //tt=GetMicrosecondCount()-tt;
   //Print("!!!!!!!!  =  "+string(tt));
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
template <typename T>
CStructArr::~CStructArr() {
   if(_UninitReason!=REASON_RECOMPILE && _UninitReason!=REASON_CHARTCHANGE) ResourceFree(Name);
}
//+------------------------------------------------------------------+
template <typename T>
bool CStructArr::Set(T &var[]) {
   size = ArraySize(var);
   ArrayResize(value,size);
   w=1+size*sizeof(T)/4;
   ArrayResize(Var,w);
   for (int j=0; j<size; j++) {
      su.st=var[j];
      for(int i=0; i<sizeof(T)/4; i++) Var[j*sizeof(T)/4+i]=su.u[i];
      value[j]=var[j];
   }
   if(!ResourceCreate(Name,Var,w,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA)) {
      printf("Error create Resource: "+DoubleToString(GetLastError(),0));
      return(false);
   } else return(true);
}
//+------------------------------------------------------------------+
L'utilisation de variables globales terminales pour passer des paramètres entre les TF est une solution très maladroite à mon avis.
 
Nikolai Semko:

Je l'écrirai dans le QB un jour.
En fait, voici la classe pour ça.
Et dans l'indicateur, il suffit d'ajouter deux lignes :
.

  • Créez une instance de cette classe avant OnInit et liez votre tableau de structures à passer entre les TFs. S'il ne s'agit pas de la première initialisation, le tableau de structures sera rempli avec les données de la TF précédente.
  • Dans OnDeinit, sauvegardez votre tableau via une seule méthode dans cette classe.

Je pense que l'utilisation de variables globales de terminal pour passer des paramètres entre les TF est une solution très tordue.

Merci, c'est tout à fait ça.

 
Nikolai Semko:

En fait, voici la classe pour ça.

À première vue, la mise en œuvre de la conversion T[]<->uint[] n'est pas optimale.
 
fxsaber:
À première vue, la mise en œuvre de la conversion T[]<->uint[] n'est pas optimale.

J'ai écrit ce code il y a longtemps. C'est possible.
Il n'y a cependant pas grand-chose à optimiser dans ce domaine. Peut-être seulement dans certaines petites choses.
Quoi qu'il en soit, cette classe peut être essayée dans mon dernier produit gratuit sur le marché.

Je vous serais reconnaissant si vous pouviez suggérer une meilleure mise en œuvre.

 
Nikolai Semko:

Je vous serais reconnaissant si vous pouviez suggérer une meilleure mise en œuvre.

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

Bibliothèques : TradeTransactions

fxsaber, 2019.03.15 07:36

// Быстрый кастинг массивов.
#include <fxsaber\TradeTransactions\Convert.mqh> // https://www.mql5.com/ru/code/22166

void OnStart()
{
  MqlTick Ticks[];

  MqlRates Rates[];  
  CopyRates(_Symbol, PERIOD_CURRENT, 0, 10, Rates); // Получили котировки.
  CONVERT::ArrayToArray(Rates, Ticks);              // Кастинг MqlRates[] -> MqlTick[].

  MqlRates Rates2[];    
  CONVERT::ArrayToArray(Ticks, Rates2);             // Кастинг MqlTick[] -> MqlRates[].
  ArrayPrint(Rates2);                               // Убедились, что все корректно.
}
Dossiers :
Convert.mqh  4 kb
 
Mikhail Nazarenko:
Comment transférer une variable globale, une structure, un objet dans un indicateur lors du passage à un autre timeframe ? Je l'ai cherché sur Google et je ne l'ai pas trouvé.

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

Bibliothèques : TradeTransactions

fxsaber, 2018.12.17 23:48

Vous pouvez échanger n'importe quoi par le biais des ressources.

// Пример обмена любыми данными (включая строковые массивы).

#include <fxsaber\TradeTransactions\ResourceData.mqh> // https://www.mql5.com/ru/code/22166

#define  PRINT(A) Print(#A + " = " + (string)(A));

void OnStart()
{    
  // Произвольные данные для примера
  string Str[] = {"123", "Hello World!"};
  double Num = 5;
  MqlTick Tick = {0};
  Tick.bid = 1.23456;

  const RESOURCEDATA<uint> Resource; // Ресурс для обмена данными
  CONTAINER<uint> Container;         // Создаем контейнер - все будет храниться в массиве простого типа (в примере выбран uint)
  
  // Заполняем контейнер разными данными
  Container[0] = Str;
  Container[1] = Num;
  Container[2] = Tick;
    
  // Распечатаем типы хранимых в контейнере данных
  for (int i = 0; i < Container.GetAmount(); i++)
    PRINT(Container[i].GetType())

  Resource = Container.Data;  // Отправили данные на обмен
  
  CONTAINER<uint> Container2; // Сюда будем получать данные
  
  Resource.Get(Container2.Data); // Получили данные
      
  // Получим данные в исходном виде
  string Str2[];
  Container[0].Get(Str2);                // Получили массив
  ArrayPrint(Str2);

  PRINT(Container[1].Get<double>())      // Получили число
  PRINT(Container[2].Get<MqlTick>().bid) // Получили структуру  
}
 
fxsaber:

Pas, malheureusement, à visage découvert. Je ne vais pas entrer dans vos bibles.
J'ai déjà essayé de regarder dans votre code et j'ai réalisé que je ne suis pas assez mature. :))

De toute façon, si vous ouvrez tous les inluders, votre code sera plus long en code source et en exécutable.

Aussi, quelques fois brûlé, quand j'ai utilisé vos libs, et ensuite trouvé la source des freins pendant une longue période, jusqu'à ce qu'ils soient démolis. Après ça, j'ai abandonné.

La principale difficulté de l'utilisation de votre code, qui se compose de nombreux inludes, est la grande complexité du débogage, lorsqu'à chaque étape de nouvelles classes, définitions ou macros sont créées.
Et je réserve du temps pour le test, car je comprends qu'il n'est guère possible d'accélérer considérablement mon algorithme.
Le seul bogue que je vois maintenant est l'utilisation de boucles au lieu de CopyArray à certains endroits. Après cette correction, mon code sera presque parfait en termes de performances et de lisibilité.

 
Nikolai Semko:

Le seul bogue que je vois maintenant est que j'utilise des boucles à certains endroits au lieu de CopyArray. Après cette correction, mon code sera presque parfait en termes de performances et de lisibilité.

Si vous écrivez une mesure de performance, il serait intéressant de la comparer.

 

:)

Il est étrange que personne ne parle de "béquilles", de "réinvention d'une roue", de "difficultés de transfert des données vers un autre terminal", de"le problème doit être résolu par des moyens MQL "...
Il s'avère que les solutions basées sur les métacitations sont des béquilles et des mauvais tons).

Raison: