Il mio approccio. Il nucleo è il motore. - pagina 92

 
Maxim Kuznetsov:

Le sole e uniche variabili globali e i file per lo scambio di dati tra EA, indicatori e script sono

Tutti e 4 i punti di cui sopra sono "hack" locali per mancanza di pesce. Tutti e 4 i punti precedenti usano meccanismi non progettati per lo scambio di dati arbitrari, tanto meno di matrici di dati.

Si potrebbe pensare che GlobalVariables sia stato progettato specificamente per la messaggistica. È una cosa stupida da dire. In effetti è lo stesso hack di qualsiasi altro oggetto.

 
fxsaber:


...Approssimativamente,un ciclo completo di scrittura/lettura attraverso una risorsa funziona ad una velocità di 4 milioni di tick al secondo.

La lettura/scrittura della risorsa è molto veloce. Ma fino a che punto questo è adatto per una tale trasmissione:

1. Linea A. Evento Timer. Raccoglie tutti i valori dei parametri che sono stati cambiati all'evento e li traduce in una stringa. Tradurre la stringa in Char, scrivere nella risorsa. Invia un messaggio al lato B.

2. Partito B. L'evento OnChartEvent(), riceve un segnale di messaggio, apre la risorsa, la legge, riempie il kernel dei parametri con nuovi valori, ridisegna gli elementi richiesti.

Cosa succede se questo evento viene eseguito continuamente, alla frequenza del timer?

La questione è come utilizzare al meglio le risorse per questo, se ci sono altre opzioni.

//---------------------------------------------------------------------------------------------------------------------

  • L'opzione EventChartCustom() ha due svantaggi.

  1. Il pacco diventa nella coda degli eventi.
  2. Il pacco non può essere più lungo di 127 caratteri. Di conseguenza, un messaggio di 1000 caratteri deve essere diviso e poi riassemblato. E ogni parte del messaggio sarà nella coda degli eventi.
  • La variante con il passaggio attraverso oggetti grafici, richiede di dividere il messaggio in fasci di 64 caratteri, scriverli in descrizioni di oggetti e poi riassemblarli. È interessante che questa variante è la più veloce, ma all'aumentare della lunghezza della stringa, la sua velocità diminuisce. Cioè, ogni chiamata a ObjectSetString() richiede 3 microsecondi. Ma se una stringa è lunga 1000 caratteri, dobbiamo dividerla in 64 caratteri, il che significa che dobbiamo chiamare ObjectSetString() circa 8 volte. 8*3 = 24 ms. Poi ci vuole la stessa quantità di tempo per assemblare la stringa. Ecco perché se la stringa fosse lunga 10 000 caratteri, questo metodo si avvicinerebbe sicuramente alla velocità del metodo che lavora attraverso le risorse. (Sto parlando del tempo di salvataggio e lettura della risorsa + il trasferimento delle stringhe in uint e ritorno).
La variante della risorsa rimane non testata fino alla fine. Lo proverò oggi nel tester e sarà finalmente chiaro se può essere universale.
 
Реter Konow:

Cosa succede se questo evento viene eseguito continuamente, alla frequenza del timer?

La questione è come utilizzare al meglio le risorse per questo, se ci sono altre opzioni.

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

Scambio di dati tra programmi

fxsaber, 2018.11.21 13:12

Probabilmente hanno un sacco di tempo per descrivere in modo così dettagliato le varie opzioni per le interazioni. Sfortunatamente, non possiedo una tale risorsa.

Qui c'è un articolo sull'argomento dove c'è un'interazione completa. Ogni edificio è costruito con mattoni e per compiti specifici. Tutti i mattoni possibili sono mostrati all'inizio del thread. Il resto spetta al costruttore.

 
fxsaber:

L'articolo non testa la comunicazione di due programmi tramite risorse, una delle quali è nel tester.

 

Qual è il problema del sindacato? Per favore, un esempio:

union UZ{
   double d;
   int i[2];
};

void OnStart(){

   UZ u1;
   UZ u2;
   
   u1.d=12345.678;
   
   ArrayCopy(u2.i,u1.i);
   
   Alert(u2.d);

}
 
Реter Konow:

L'articolo non testa la comunicazione di due programmi tramite risorse, una delle quali è nel tester.

Leggi la frase sui mattoni.

 
fxsaber:

...

Questo articolo sta sparando un cannone contro i passeri. Come molti articoli. Farei prima a risolvere il problema da solo che a capire l'articolo.

Tutto può essere fatto 10 volte più facile e più chiaro. Ma l'articolo è molto più semplice...


E a cosa serve l'articolo se dite che non avete controllato il funzionamento delle risorse nel tester?

 
Реter Konow:

E a cosa serve questo articolo se dite che non avete controllato il funzionamento delle risorse nel tester?

Sono uscito dalla discussione.

 

C'è qualcosa di sbagliato in questa soluzione. Forse sto facendo qualcosa di sbagliato.

Per farla breve:

La funzione StringToCharArray() prende SOLO un array di char.

La funzione ResourceCreate() accetta SOLO un array di uint.

Quindi, è necessario riscrivere in modo intermedio il contenuto dell'array char (riempito con la stringa convertita), nell'array uint.

 
//+------------------------------------------------------------------+
//|                                                    Tester EA.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   //----------------------------------------------
   ObjectCreate(0,"Resource",OBJ_BITMAP_LABEL,0,0,0);
   ObjectSetString(0,"Resource",OBJPROP_BMPFILE,"::Resource");
   //----------------------------------------------
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   
      
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   uchar Arr[];
   uint  Data[];
   //---------------------------
   string price = (string)Bid;
   //---------------------------
   int width = StringToCharArray(price,Arr);
   //---------------------------
   ArrayResize(Data,width);
   //---------------------------
   ArrayCopy(Arr,Data);
   //---------------------------
   if(!ResourceCreate("::Resource",Data,width,1,0,0,0,COLOR_FORMAT_XRGB_NOALPHA))Print("Resource is not created!");
   //---------------------------
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+

Indicatore su un grafico normale:

//+------------------------------------------------------------------+
//|                                              Resource reader.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   EventSetMillisecondTimer(25); 
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   uint Data[50],width,height;
   //-----------------------------
   if(!ResourceReadImage("::Resource",Data,width,height))Print("Failed to read resource!");
   else Print("Resource is readable!");
   //-----------------------------
   
  }
//+------------------------------------------------------------------+