Como posso mudar a estrutura global de variáveis no indicador ao passar para outro período de tempo? - página 4

 
Nikolai Semko:
Pessoalmente, utilizo recursos via sindicato.
Mesmo os conjuntos de estruturas são facilmente transferidos entre as TFs sem escrever em um arquivo.

Poderia explicar melhor. Obrigado.

 
Mikhail Nazarenko:

Você pode explicar melhor isso? Obrigado.

Vou escrevê-lo no QB em algum momento.
Na verdade, aqui está a classe para isso.
E você só precisa adicionar duas linhas ao indicador:

  • Crie uma instância desta classe antes do OnInit, ligando seu conjunto de estruturas, que você quer passar entre as TFs. Se não for a primeira inicialização, o conjunto de estruturas será preenchido com dados da TF anterior.
  • Na OnDeinit, salve seu array através de um único método nesta 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);
}
//+------------------------------------------------------------------+
Acho o uso de variáveis terminais globais para transferir parâmetros entre as TFs uma solução muito incômoda.
 
Nikolai Semko:

Vou escrevê-lo no QB em algum momento.
Na verdade, aqui está a classe para isso.
E no indicador você só precisa acrescentar duas linhas:

  • Crie uma instância desta classe antes do OnInit e vincule seu conjunto de estruturas a serem passadas entre as TFs. Se não for a primeira inicialização, o conjunto de estruturas será preenchido com dados da TF anterior.
  • No OnDeinit, salve sua matriz através de um único método nesta classe.

Acho que o uso de variáveis terminais globais para passar parâmetros entre as TFs é uma solução muito tortuosa.

Obrigado, tudo isso está em questão.

 
Nikolai Semko:

Na verdade, aqui está a classe para isso.

À primeira vista, a implementação da conversão T[]<->uint[] não é ótima.
 
fxsaber:
À primeira vista, a implementação da conversão T[]<->uint[] não é ótima.

escreveu este código há muito tempo. Pode ser.
No entanto, não há muito a ser otimizado. Talvez apenas em algumas pequenas coisas.
De qualquer forma, esta classe pode ser experimentada em meu último produto gratuito no mercado.

Eu ficaria grato se você pudesse sugerir uma melhor implementação.

 
Nikolai Semko:

Eu ficaria grato se você pudesse sugerir uma melhor implementação.

Fórum sobre comércio, sistemas automatizados de comércio e testes de estratégia comercial

Bibliotecas: 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);                               // Убедились, что все корректно.
}
Arquivos anexados:
Convert.mqh  4 kb
 
Mikhail Nazarenko:
Como transferir uma variável global, estrutura, objeto em um indicador ao passar para outro período de tempo? Procurei no Google e não consegui encontrá-lo.

Fórum sobre comércio, sistemas comerciais automatizados e estratégias comerciais de teste

Bibliotecas: TradeTransactions

fxsaber, 2018.12.17 23:48

Você pode negociar qualquer coisa através de Recursos.

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

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

Não, infelizmente, um descalço. Eu não entrarei em suas bíblias.
Já tentei analisar seu código e percebi que não sou maduro o suficiente. :))

De qualquer forma, se você abrir todos os inluders, seu código será mais longo em código fonte e executável.

Além disso, algumas vezes queimei, quando usei suas libras, e depois encontrei a fonte dos freios por um longo tempo, até que eles foram demolidos. Depois disso, eu desisti.

A principal dificuldade de usar seu código, que consiste em muitos inlúdios, é a alta complexidade da depuração, quando a cada passo uma nova classe, define ou macros.
E eu poupo tempo para o teste, porque entendo que dificilmente é possível acelerar meu algoritmo consideravelmente.
O único bug que vejo agora é o uso de loops em vez do CopyArray em alguns lugares. Depois desta correção, meu código será quase perfeito em termos de desempenho e legibilidade.

 
Nikolai Semko:

O único bug que vejo agora é que uso loops em alguns lugares em vez de CopyArray. Depois desta correção, meu código será quase perfeito em termos de desempenho e legibilidade.

Se você escrever uma medida de desempenho, seria interessante comparar.

 

:)

É estranho que ninguém escreva sobre "muletas", "reinvenção de uma roda", "dificuldades de transferência de dados para outro terminal","o problema deve ser resolvido por meios MQL "...
Acontece que as soluções baseadas em metaquotas são muletas e mauvais ton)