Erreurs, bugs, questions - page 936

 
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input string symbol1="AUDUSD";
input string symbol2="NZDUSD";
input double mass_of_symbol1=1;
input double mass_of_symbol2=1;


int i,r1,r2,j;
double S,prs,k1,k2,d1,d2;
//--- indicator buffers
double        ind1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ind1,INDICATOR_DATA);
//---
   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[])
  {
//---
   ArraySetAsSeries(time,true);ArraySetAsSeries(open,true);ArraySetAsSeries(high,true);ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);ArraySetAsSeries(tick_volume,true);ArraySetAsSeries(volume,true);ArraySetAsSeries(spread,true);

   ArraySetAsSeries(ind1,true);
   MqlRates rates1[]; ArraySetAsSeries(rates1,true);
   MqlRates rates2[]; ArraySetAsSeries(rates2,true);

   if(prev_calculated<rates_total)
     {
      for(i=0;i<rates_total;i++)
     // for(i=prev_calculated-1;i<rates_total;i++)
        {
         CopyRates(symbol1,0,time[i],1,rates1);
         CopyRates(symbol2,0,time[i],1,rates2);
         ind1[i]=mass_of_symbol1*rates1[0].close-mass_of_symbol2*rates2[0].close;
        }
     }



//--- return value of prev_calculated for next call
   return(rates_total);
 

Le code ci-dessus de l'indicateur Spread_of_symbols ... J'ai décidé de le réécrire pour le faire fonctionner plus rapidement.... et le code est apparu, voir ci-dessous ... les données ne sont pas copiées ... si vous copiez les données de 1 à 0 dans le code, l'indicateur dessine très rapidement mais une erreur out of range se produit ... qu'est-ce qui ne va pas dans le code voir ci-dessous ... ?

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input string symbol1="AUDUSD";
input string symbol2="NZDUSD";
input double mass_of_symbol1=1;
input double mass_of_symbol2=1;


int i,r1,r2,j;
double S,prs,k1,k2,d1,d2;
//--- indicator buffers
double        ind1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ind1,INDICATOR_DATA);
//---
   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[])
  {
//---
   ArraySetAsSeries(time,true);ArraySetAsSeries(open,true);ArraySetAsSeries(high,true);ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);ArraySetAsSeries(tick_volume,true);ArraySetAsSeries(volume,true);ArraySetAsSeries(spread,true);

   ArraySetAsSeries(ind1,true);
   MqlRates rates1[]; ArraySetAsSeries(rates1,true);
   MqlRates rates2[]; ArraySetAsSeries(rates2,true);
   
   int to_copy;
   if(prev_calculated>rates_total || prev_calculated<0) to_copy=rates_total;
   else
     {
      to_copy=rates_total-prev_calculated;
      if(prev_calculated>0) 
      to_copy++;   
     }
   if(CopyRates(symbol1,0,0,to_copy,rates1)<=0)
     {
      Print("Данные по первому символу не скопированы, ошибка  ",GetLastError());
      return(0);
     }
   if(CopyRates(symbol2,0,0,to_copy,rates2)<=0)
     {
      Print("Данные по второму символу не скопированы, ошибка ",GetLastError());
      return(0);
     }
   if(prev_calculated<rates_total)
     {
     int limit;
   if(prev_calculated==0)
      limit=0;
   else limit=prev_calculated-1;
   for(int i=limit;i<rates_total;i++)
        {
         ind1[i]=mass_of_symbol1*rates1[i].close-mass_of_symbol2*rates2[i].close;
        }
     }
   return(rates_total);
  }
 
FinEngineer:
Voir le Guide de référence MQL5 / Accès aux séries temporelles et aux indicateurs / Organiser l'accès aux données
 
FinEngineer: mais une erreur hors de portée apparaît... qu'est-ce qui ne va pas dans le code voir ci-dessous... ?
Vérifie si les valeurs de to_copy et limit correspondent l'une à l'autre.
 
En mode visualisation, lors de la négociation sur deux symboles, après avoir fermé les transactions en même temps, seules les données du symbole sur lequel le conseiller expert est en cours d'exécution apparaissent dans l'historique. Les données de l'autre symbole n'apparaissent dans l'onglet historique qu'après avoir ouvert d'autres transactions. Par conséquent, il y a une période pendant laquelle les données sur les onglets commerce et historique sont différentes.
 
JF 0 Trades 19:31:10 '***' : annuler l'ordre #3694236 buy stop 1.10 AUDJPY.m à 95.679<br / translate="no">DS 0 Trades 19:31:10 '***' : annuler l'ordre #3694238 buy limit 1.10 AUDJPY.m à 93.876
DH 0 Trades 19:31:10 '***' : annuler l'ordre #3694237 buy stop 0.36 AUDJPY.m à 95.679
FI 0 Trades 19:31:10 '***' : annuler l'ordre #3694239 limite d'achat 0.36 AUDJPY.m à 93.876
FP 0 Trades 19:31:10 '***' : annuler l'ordre #3694236 buy stop 1.10 AUDJPY.m at 95.679 done
QE 0 Trades 19:31:11 '***' : annuler l'ordre #3694238 buy limit 1.10 AUDJPY.m at 93.876 done
CG 0 Trades 19:31:11 '***' : annuler l'ordre #3694237 buy stop 0.36 AUDJPY.m at 95.679 done
OL 0 Trades 19:31:11 '***' : annuler l'ordre #3694239 buy limit 0.36 AUDJPY.m at 93.876 done

Quatre ordres en attente, selon le journal, semblent avoir été supprimés rapidement. Mais surTradeTransaction, les réponses sont arrivées en 15 secondes environ, les ticks arrivaient dans cette période.

KH 0 prp5 (EURUSD.m,M1) 19:31:23 TS=6 cancel sl _ OnTrade PENDING id=84 m=3 b/s=SELL Err=Ordre exécuté
***

JG 0 prp5 (EURUSD.m,M1) 19:31:26 TS=6 Delete tp _ OnTrade PENDING id=85 m=3 b/s=SELL Err=Bid completed
***
RL 0 prp5 (EURUSD.m,M1) 19:31:26 TS=6 Delete sl _ OnTrade PENDING id=86 m=3 b/s=SELL Err=Bid completed
***

HK 0 prp5 (EURUSD.m,M1) 19:31:26 TS=6 Delete tp _ OnTrade PENDING id=87 m=3 b/s=SELL Err=Ordre exécuté

Cependant, il y a quelque chose d'étrange ici aussi.

IE 0 prp5 (EURUSD.m,M1) 19:31:26 TS=6 =O= Deal close/reverse price=95.648 m=3 b/s=SELL ... ==>Temps avant OrderSendAsync
ES 0 prp5 (EURUSD.m,M1) 19:31:29 TS=6 case 8(real) m=3 b/s=SELL Err=Order placed ==>Après OrderSendAsync, 3 sec semble être trop long.

P.S. Il semble qu'il y ait eu des décalages dans l'exécution d'Expert, mais je me demande combien de temps les paquets pour OnTradeTransaction peuvent rester dans la file d'attente.

 
fyords:

De la référence :

Référence MQL5 / Bibliothèque standard / Classes pour la création de panneaux et de boîtes de dialogue / CWnd / StateFlagsSet

Quelles propriétés ?

StateFlagsSet non pas les propriétés, mais l'état. Une méthode de groupe pour changer l'état. Juste au-dessus des méthodes de changement des drapeaux d'état individuels.

A utiliser séparément.

 

J'ai regardé l'"organisation d'accès aux données", j'ai regardé l'exemple de script qui pompe les données et j'ai tout compris, les questions suivantes se sont posées :

1. Pourquoi ne puis-je pas écrire ce code dans l'indicateur dans la fonction OnInit, pour qu'au démarrage l'indicateur télécharge son propre historique et prépare la série temporelle ? Puis-je écrire un tel chèque dans mon conseiller expert ?

2. A quelle fréquence dois-je faire ce contrôle pour : 1 pour les conseillers experts et 2 pour les indicateurs ? Si je ne prépare qu'une seule fois l'historique et les séries chronologiques pour la copie, les erreurs de copie ne se produiront pas à l'avenir ? Ou dois-je vérifier à chaque fois ou de temps en temps si l'historique et les séries chronologiques sont prêts ?

3. cette vérification est-elle nécessaire uniquement pour les indicateurs et les conseillers experts qui utilisent plusieurs délais et symboles, ou est-elle souhaitable pour tous ?

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Основы языка / Функции / Функции обработки событий - Документация по MQL5
 
Les processus de swap sont asynchrones et l'indicateur n'est pas autorisé à attendre les données. Il est donc possible d'interroger en inite, en aucun cas d'attendre ou de ralentir et seulement en oncalculate pour vérifier la disponibilité et le nombre.

Veuillez noter - l'indicateur n'a pas le droit d'attendre ou de boucler, sinon il tuera le calcul des indicateurs suivants.
 
Renat:
Les processus de swap sont asynchrones et l'indicateur n'est pas autorisé à attendre les données. Vous pouvez donc interroger dans l'inite, en aucun cas attendre ou ralentir et seulement dans l'oncalculer pour vérifier la disponibilité et le nombre.

Veuillez noter - l'indicateur n'a pas le droit d'attendre ou de boucler, sinon il tuera le calcul des indicateurs suivants.

1 Alors où dois-je paginer les données ? Si je veux faire un indicateur avec un panier de paires de devises, de nombreux symboles... pour chacun d'eux, je dois vérifier et échanger les données... dois-je exécuter un script à partir de l'indicateur ? Pourquoi un indicateur tuerait-il les calculs des indicateurs suivants ? Dans les indicateurs suivants, il suffit d'utiliser la vérification du calcul de l'indicateur précédent par BarsCalculated(indicator1_Handle), de le laisser calculer et de télécharger les données, ou je me trompe ?

2 Une autre question, d'un autre genre - lorsque je déclare le manche de l'indicateur dans la fonction, il commence à compter ? Ou bien commence-t-il à compter avant que je donne l'ordre de le copier ?