OOP, templates et macros dans mql5, subtilités et utilisations - page 27

 
Vladimir Simakov:

Un pointeur vers un objet.

Ne le prenez pas mal, mais c'est trop tôt pour vous avec des macros comme ça, vous allez vous enliser. Tout d'abord, vous devez comprendre pourquoi j'ai procédé de cette façon :

Et que faire avec ce pointeur d'objet à l'intérieur de la classe où le passer.

Quant aux macros, elles sont beaucoup plus faciles à utiliser.

 
Seric29:

Et que faire avec ce pointeur vers un objet à l'intérieur de la classe, où le passer.

Quant aux macros, elles sont beaucoup plus faciles à utiliser.

Vous pouvez l'utiliser pour faire référence à un objet créé n'importe où. Dans mon exemple, le pointeur vers l'objet créé globalement est passé au constructeur, mais cette classe peut elle-même être imbriquée dans une autre (dans laquelle l'objet est créé).

Voici un exemple de l'utilisation de votre macro :

#define  foor1(a,b,v,g) \
for(;Funkziya(a,b,v)&&g;b++)

...

foor(a,b,c,isSomething?a>b:b>c){
    DoSomething();
}
...

Voyez ce que ça donne, j'ajoute des parenthèses pour plus de clarté :

for(;( Funkziya(a,b,c)&&isSomething)?a>b:b>c;b++){
    DoSomething();
}

En conséquence, vous avez un code absolument valide pour le compilateur, mais le comportement du programme est catégoriquement différent de ce qui était prévu. Et maintenant, vous ne remarquez pas vraiment l'erreur, le code fonctionne, et ensuite vous fixez le terminal et vous vous demandez pourquoi le robot s'est connecté avec tout le dépôt et a perdu votre compte ? ))))).

Je suis très doué pour les macros, mais c'est la raison pour laquelle et pourquoi je les déteste autant (développeurs, encore une fois s'il vous plaît constexpr et SFINAE en même temps). Je vous conseille donc de ne pas les utiliser pour réduire les lettres dans votre code. Il s'agit en fait, même dans une version mql dépouillée, d'un outil puissant, mais qui nécessite une approche très disciplinée.

 

Développeurs, ajoutez la possibilité d'utiliser un nombre illimité d'arguments dans les macros et les fonctions. J'en ai assez de cette absurdité statique. Qu'est-ce que 8 arguments pour une macro et si vous avez besoin de 108 quoi alors, faites-en au moins 10. Et aussi permettre de surcharger les macros pour ne pas avoir à multiplier les nouveaux noms avec les macros. Ce serait aussi cool si vous pouviez faire

#define  Znah 0
#define  PrmI int    Peremen=6;
#define  PrmD double Peremen=3.345;

#if  Znah//если больше 0 то появится переменная int Peremen
   PrmI
#else
    PrmD//иначе появится переменная double Peremen
#endif

macro#if

 
Vladimir Simakov:

Mais le comportement du programme est catégoriquement différent de ce qui était prévu. Maintenant, il n'est pas certain que vous remarquiez l'erreur, que le code fonctionne, et qu'ensuite vous regardiez bêtement dans le terminal en vous demandant pourquoi le robot est entré avec tout son dépôt et a perdu votre compte ? ))))).

Je suis très doué pour les macros, mais c'est pour cela que je ne les aime pas tellement (développeurs, demandez une fois de plus constexpr et SFINAE en même temps). Je vous conseille donc de ne pas les utiliser pour réduire les lettres dans votre code. Il s'agit en fait, même dans une version mql dépouillée, d'un outil puissant, mais qui nécessite une approche très disciplinée.

Je ne vais pas deviner quoi que ce soit, je fais mon travail de manière fiable.

CDataManager*  m_data;

Que faites-vous avec le pointeur m_data ? Accédez-vous à l'élémentm_data ? Qu'en tirez-vous ? Je comprends que ça arrive ici.

   CNewBar(CDataManager* data=NULL):m_data(!data?new CDataManager:data),cIsDelData(!data){}
   CNewBar(string symbol,ENUM_TIMEFRAMES frame):m_data(new CDataManager(symbol,frame)),cIsDelData(true){}

Ce que vous essayez d'obtenir n'est pas clair (très compliqué).

Que se passerait-il si cette ligne

CDataManager*  m_data;

serait écrit en public.

Les cours sont un mystère pour moi. Après deux ans, je ne sais toujours pas comment les gérer.

 

Il est nécessaire d'écrire les statistiques des résultats des tests dans une table de base de données,

La base de données est créée au préalable, les passes d'intérêt sont écrites en incluant la variable sinput dans les paramètres de l'EA.

BASE DE DONNEES :

CREATE TABLE "TesterStatistics" (
        "id"    INTEGER,
        "MD5"   TEXT,
        "STAT_PROFIT"   REAL,
        "STAT_GROSS_PROFIT"     REAL,
        "STAT_GROSS_LOSS"       REAL,
        "STAT_MAX_PROFITTRADE"  REAL,
        "STAT_MAX_LOSSTRADE"    REAL,
        "STAT_CONPROFITMAX"     REAL,
        "STAT_CONPROFITMAX_TRADES"      INTEGER,
        "STAT_MAX_CONWINS"      REAL,
        "STAT_MAX_CONPROFIT_TRADES"     INTEGER,
        "STAT_CONLOSSMAX"       REAL,
        "STAT_CONLOSSMAX_TRADES"        INTEGER,
        "STAT_MAX_CONLOSSES"    REAL,
        "STAT_MAX_CONLOSS_TRADES"       INTEGER,
        "STAT_BALANCEMIN"       REAL,
        "STAT_BALANCE_DD"       REAL,
        "STAT_BALANCEDD_PERCENT"        REAL,
        "STAT_BALANCE_DDREL_PERCENT"    REAL,
        "STAT_BALANCE_DD_RELATIVE"      REAL,
        "STAT_EQUITYMIN"        REAL,
        "STAT_EQUITY_DD"        REAL,
        "STAT_EQUITYDD_PERCENT" REAL,
        "STAT_EQUITY_DDREL_PERCENT"     REAL,
        "STAT_EQUITY_DD_RELATIVE"       REAL,
        "STAT_EXPECTED_PAYOFF"  REAL,
        "STAT_PROFIT_FACTOR"    REAL,
        "STAT_RECOVERY_FACTOR"  REAL,
        "STAT_SHARPE_RATIO"     REAL,
        "STAT_MIN_MARGINLEVEL"  REAL,
        "STAT_CUSTOM_ONTESTER"  REAL,
        "STAT_DEALS"    INTEGER,
        "STAT_TRADES"   INTEGER,
        "STAT_PROFIT_TRADES"    INTEGER,
        "STAT_LOSS_TRADES"      INTEGER,
        "STAT_SHORT_TRADES"     INTEGER,
        "STAT_LONG_TRADES"      INTEGER,
        "STAT_PROFIT_SHORTTRADES"       INTEGER,
        "STAT_PROFIT_LONGTRADES"        INTEGER,
        "STAT_PROFITTRADES_AVGCON"      INTEGER,
        "STAT_LOSSTRADES_AVGCON"        INTEGER,
        PRIMARY KEY("id" AUTOINCREMENT)
)

J'écris dans cette table avec ce code :

DatabaseExecute(handleDB, StringFormat("INSERT INTO \"TesterStatistics\" "
                                             "VALUES (NULL, \'%s\',%G, %G, %G, %G, %G, %G, %d, %G, %d, %G, %d, %G, %d, "
                                             "%G, %G, %G, %G, %G, %G, %G, %G, %G, %G, %G, %G, %G, %G, %G, %G, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d);",
                                             md5txt, TesterStatistics(STAT_PROFIT),             TesterStatistics(STAT_GROSS_PROFIT),
                                             TesterStatistics(STAT_GROSS_LOSS),                 TesterStatistics(STAT_MAX_PROFITTRADE),
                                             TesterStatistics(STAT_MAX_LOSSTRADE),              TesterStatistics(STAT_CONPROFITMAX),
                                             (int)TesterStatistics(STAT_CONPROFITMAX_TRADES),   TesterStatistics(STAT_MAX_CONWINS),
                                             (int)TesterStatistics(STAT_MAX_CONPROFIT_TRADES),  TesterStatistics(STAT_CONLOSSMAX),
                                             (int)TesterStatistics(STAT_CONLOSSMAX_TRADES),     TesterStatistics(STAT_MAX_CONLOSSES),
                                             (int)TesterStatistics(STAT_MAX_CONLOSS_TRADES),    TesterStatistics(STAT_BALANCEMIN),
                                             TesterStatistics(STAT_BALANCE_DD),                 TesterStatistics(STAT_BALANCEDD_PERCENT),
                                             TesterStatistics(STAT_BALANCE_DDREL_PERCENT),      TesterStatistics(STAT_BALANCE_DD_RELATIVE),
                                             TesterStatistics(STAT_EQUITYMIN),                  TesterStatistics(STAT_EQUITY_DD),
                                             TesterStatistics(STAT_EQUITYDD_PERCENT),           TesterStatistics(STAT_EQUITY_DDREL_PERCENT),
                                             TesterStatistics(STAT_EQUITY_DD_RELATIVE),         TesterStatistics(STAT_EXPECTED_PAYOFF),
                                             TesterStatistics(STAT_PROFIT_FACTOR),              TesterStatistics(STAT_RECOVERY_FACTOR),
                                             TesterStatistics(STAT_SHARPE_RATIO),               TesterStatistics(STAT_MIN_MARGINLEVEL),
                                             TesterStatistics(STAT_CUSTOM_ONTESTER),            (int)TesterStatistics(STAT_DEALS),
                                             (int)TesterStatistics(STAT_TRADES),                (int)TesterStatistics(STAT_PROFIT_TRADES),
                                             (int)TesterStatistics(STAT_LOSS_TRADES),           (int)TesterStatistics(STAT_SHORT_TRADES),
                                             (int)TesterStatistics(STAT_LONG_TRADES),           (int)TesterStatistics(STAT_PROFIT_SHORTTRADES),
                                             (int)TesterStatistics(STAT_PROFIT_LONGTRADES),     (int)TesterStatistics(STAT_PROFITTRADES_AVGCON),
                                             (int)TesterStatistics(STAT_LOSSTRADES_AVGCON)));


L'énumération ENUM_STATISTICS a un ordre comme dans l'aide, script à vérifier :

void OnStart()
{
   for(int i = 0; i <= (int)STAT_LOSSTRADES_AVGCON; i++)
      printf("%d ^ %s", i, EnumToString(( ENUM_STATISTICS)i));
}


tout fonctionne,MAIS le texte du code est assez volumineux, forte probabilité d'une faute de frappe, comment obtenir cette requête à la base de données d'une manière plus fiable - le problème principal est comment entrer dansStringFormat

 
Igor Makanu:

Il est nécessaire d'écrire les statistiques des résultats des tests dans une table de base de données,

La base de données est créée au préalable, les passes d'intérêt sont écrites en incluant la variable sinput dans les paramètres de l'EA.

DB :

J'écris dans cette table avec ce code :


L'énumération ENUM_STATISTICS a un ordre comme dans l'aide, script à vérifier :


tout fonctionne,MAIS le texte du code est assez volumineux, forte probabilité d'une faute de frappe, comment obtenir cette requête à la base de données d'une manière plus fiable - le problème principal est comment entrer dansStringFormat

Définir ! !! (bien qu'une surcharge normale fasse l'affaire ici)

Et quel est l'intérêt de ce StringFormat ?

Il n'est pas plus rapide qu'un add.... normal. (J'ai fait des dizaines de gigaoctets de fichiers texte =) .... même un add-on normal est plus rapide, c'est comme ça...


Si vous voulez le faire par le biais de cette fonction régulière, je ne comprends pas le problème non plus ;))

 
Alexandr Andreev:

Et quel est l'intérêt de ce format de chaîne ?

Il n'est jamais plus rapide qu'un add.... normal. (J'ai fait des dizaines de gigaoctets de fichiers texte =....) même un add-on normal est plus rapide, c'est ça le truc...

Je ne sais pas.

J'ai lu l'aide et l'article et j'ai créé une requête de base de données en utilisant les exemples.

Cela semble fonctionner, mais je soupçonne que si j'utilise une partie de ce code, je risque de faire des fautes de frappe

Tout cela peut sembler étrange, c'est pourquoi je me demande comment le rendre plus compact sans bousiller )))).

 
Igor Makanu:

Il est nécessaire d'écrire les statistiques des résultats des tests dans une table de base de données,

La base de données est créée au préalable, les passes d'intérêt sont écrites en incluant la variable sinput dans les paramètres de l'EA.

DB :

J'écris dans cette table avec ce code :


L'énumération ENUM_STATISTICS a un ordre comme dans l'aide, script à vérifier :


tout fonctionne,mais le texte du code est assez vaste, il y a une forte probabilité d'une coquille, comment obtenir cette requête à la base de données d'une manière plus fiable - le problème principal est commentobtenir StringFormat

Rappelez-vous, tout d'abord, les types de champs sont facultatifs dans SQLite et vous n'avez pas à vous soucier du typage et du casting. C'est "Lite" pour une raison.

une longue requête peut être divisée en 3-4-5 parties :-)

BEGIN TRANSACTION

INSERT INTO myTable VALUES (...); --- тут можно получить PrimaryKey

UPDATE myTable .... ; --- обновить по Primary

UPDATE myTable ...  ; --- ещё...

COMMIT ; --- это если все запросы удачны.. иначе ROLLBACK

Ceci est de mémoire ancienne, c'est à dire que vous devriez vérifier avec l'aide

 
Igor Makanu:

Je ne sais pas.

J'ai lu l'aide et l'article, j'ai créé une requête de base de données en utilisant les exemples.

Cela semble fonctionner, mais je pense que si j'utilise partiellement ce code, je risque de faire des erreurs d'impression.

Je voudrais demander comment le rendre plus compact sans bousiller )))).

Votre tâche devrait être résolue comme suit :

string MakeRequest(string md5txt){
   static ENUM_STATISTICS intIndex[]={STAT_CONPROFITMAX_TRADES,
                                      STAT_MAX_CONPROFIT_TRADES,
                                      STAT_CONLOSSMAX_TRADES,
                                      STAT_MAX_CONLOSS_TRADES,
                                      STAT_DEALS,
                                      STAT_TRADES,
                                      STAT_PROFIT_TRADES,
                                      STAT_LOSS_TRADES,
                                      STAT_SHORT_TRADES,
                                      STAT_LONG_TRADES,
                                      STAT_PROFIT_SHORTTRADES,
                                      STAT_PROFIT_LONGTRADES,
                                      STAT_PROFITTRADES_AVGCON,
                                      STAT_LOSSTRADES_AVGCON};
   string ret="INSERT INTO \"TesterStatistics\" VALUES (NULL,"+md5txt;
   for (int i=0,ii=0;i<=STAT_LOSSTRADES_AVGCON;++i){
      ret+=",";
      if (i==intIndex[ii]){
         ret+=StringFormat("%d",(int)TesterStatistics((ENUM_STATISTICS)i));
         ++ii;}
      else ret+=StringFormat("%G",TesterStatistics((ENUM_STATISTICS)i));}
   return ret;}
   
DatabaseExecute(handleDB, MakeRequest("md5txt"));
 
Vladimir Simakov:

Votre problème particulier devrait être résolu comme suit :

Merde !

C'est vrai ! Les tableaux !

MERCI !!!!!