Come posso cambiare la struttura della variabile globale nell'indicatore quando mi sposto in un altro timeframe? - pagina 4

 
Nikolai Semko:
Personalmente, uso le risorse via sindacato.
Anche gli array di strutture sono facilmente trasferiti tra i TF senza scrivere su un file.

Potrebbe approfondire questo aspetto. Grazie.

 
Mikhail Nazarenko:

Può spiegarsi meglio? Grazie.

Prima o poi lo scriverò nel QB.
In realtà, qui c'è la classe per questo.
E devi solo aggiungere due linee all'indicatore:

  • Crea un'istanza di questa classe prima dell'OnInit, collegando il tuo array di strutture da passare tra i TF. Se non è la prima inizializzazione, l'array di strutture sarà riempito con i dati della precedente TF.
  • A OnDeinit, salvate il vostro array tramite un singolo metodo in questa 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);
}
//+------------------------------------------------------------------+
Usare le variabili terminali globali per passare i parametri tra i TF è una soluzione molto scomoda secondo me.
 
Nikolai Semko:

Prima o poi lo scriverò nel QB.
In realtà, qui c'è la classe per questo.
E nell'indicatore dovete aggiungere solo due linee:

  • Crea un'istanza di questa classe prima di OnInit e lega il tuo array di strutture da passare tra i TF. Se non è la prima inizializzazione, l'array di strutture sarà riempito con i dati della precedente TF.
  • In OnDeinit salvate il vostro array attraverso un singolo metodo in questa classe.

Penso che usare le variabili terminali globali per passare i parametri tra i TF sia una soluzione molto storta.

Grazie, è tutto a posto.

 
Nikolai Semko:

Infatti, ecco la classe per questo.

A prima vista, l'implementazione della conversione T[]<->uint[] non è ottimale.
 
fxsaber:
A prima vista, l'implementazione della conversione T[]<->uint[] non è ottimale.

ha scritto questo codice molto tempo fa. Può essere.
Però non c'è molto da ottimizzare lì. Forse solo in alcune piccole cose.
Comunque, questa classe può essere provata nel mio ultimo prodotto gratuito nel Mercato.

Vi sarei grato se poteste suggerire un'implementazione migliore.

 
Nikolai Semko:

Vi sarei grato se poteste suggerire un'implementazione migliore.

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Biblioteche: 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);                               // Убедились, что все корректно.
}
File:
Convert.mqh  4 kb
 
Mikhail Nazarenko:
Come trasferire una variabile globale, una struttura, un oggetto in un indicatore quando ci si sposta in un altro timeframe? L'ho cercato su Google e non l'ho trovato.

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Biblioteche: TradeTransactions

fxsaber, 2018.12.17 23:48

Puoi scambiare qualsiasi cosa attraverso le Risorse.

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

#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:

Non, purtroppo, a viso scoperto. Non entrerò nelle vostre bibbie.
Ho già provato a guardare il tuo codice e mi sono reso conto di non essere abbastanza maturo. :))

Comunque, se aprite tutti gli inluders, il vostro codice sarà più lungo in codice sorgente ed eseguibile.

Inoltre, un paio di volte bruciato, quando ho usato il tuo libs, e poi trovato la fonte di freni per molto tempo, fino a quando sono stati abbattuti. Dopo di che ho rinunciato.

La difficoltà principale dell'uso del vostro codice, che consiste di molti inludi, è l'alta complessità del debugging, quando ad ogni passo si creano nuove classi, definizioni o macro.
E risparmio tempo per il test, perché capisco che è difficilmente possibile accelerare considerevolmente il mio algoritmo.
L'unico bug che vedo ora è l'uso di loop invece di CopyArray in alcuni punti. Dopo questa correzione il mio codice sarà quasi perfetto in termini di prestazioni e leggibilità.

 
Nikolai Semko:

L'unico bug che vedo ora è che uso i loop in alcuni punti invece di CopyArray. Dopo questa correzione il mio codice sarà quasi perfetto in termini di prestazioni e leggibilità.

Se si scrive una misurazione delle prestazioni, sarebbe interessante confrontare.

 

:)

È strano che nessuno scriva di "stampelle", "reinvenzione di una ruota", "difficoltà di trasferimento dei dati a un altro terminale","il problema deve essere risolto con mezzi MQL "...
Si scopre che le soluzioni basate su meta-citazioni sono stampelle e mauvais ton)

Motivazione: