ООП, шаблоны и макросы в mql5, тонкости и приёмы использования - страница 27

 
Vladimir Simakov:

Указатель на объект.

Без обид, но с подобными макросами Вам еще рано, нахлебаетесь. Для начала поймите, зачем я вот так сделал:

И что с ним делать с этим указателем на объект который внутри класса куда его передавать.

А что касается макросов так с ними намного проще работать.

 
Seric29:

И что с ним делать с этим указателем на объект который внутри класса куда его передавать.

А что касается макросов так с ними намного проще работать.

По нему обращаешься к объекту созданному где угодно. В моем примере в конструктор передается указатель на объект, созданный на глобальном уровне, но данный класс может быть сам вложен в другой (в котором и создается объект).

Вот Вам пример применения Вашего макроса:

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

...

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

Смотри во что он развернется, скобки добавляю для наглядности:

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

В результате, Вы получили абсолютно валидный для компилятора код, но поведение программы категорично отличается от задуманного. А теперь не факт, что ошибку заметишь, код-то работает, а потом будешь тупо смотреть в терминал и гадать: а почему робот зашел всем депозитом и слил счет?)))))

Я макросы очень хорошо умею, но именно поэтому и очень сильно не люблю (разработчики, еще раз прошу constexpr, а заодно и SFINAE). Так, что мой тебе совет - не надо их использовать для уменьшения букв в коде. Это, на самом деле, даже в урезанной mql-версии, мощный инструмент, но требует к себе очень дисциплинированного подхода.

 

Разработчики добавьте возможность использовать неограниченное количество аргументов внутри макросов и функций.  Надоела эта статическая ерунда. Что такое 8 аргументов для макроса а если надо 108 что тогда, сделайте хотя бы 10. А также сделайте возможность перегружать макросы чтобы не нужно было плодить новые имена с макросами. Также было бы классно если бы организовали

#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

макрос #if 

 
Vladimir Simakov:

но поведение программы категорично отличается от задуманного. А теперь не факт, что ошибку заметишь, код-то работает, а потом будешь тупо смотреть в терминал и гадать: а почему робот зашел всем депозитом и слил счет?)))))

Я макросы очень хорошо умею, но именно поэтому и очень сильно не люблю (разработчики, еще раз прошу constexpr, а заодно и SFINAE). Так, что мой тебе совет - не надо их использовать для уменьшения букв в коде. Это, на самом деле, даже в урезанной mql-версии, мощный инструмент, но требует к себе очень дисциплинированного подхода.

Я ничего не буду гадать я делаю свою работу надёжно.

CDataManager*  m_data;

Что вы делаете с указателем m_data? Вы обращаетесь к элементу m_data? И что это вам даёт? Я так понимаю что это происходит здесь

   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){}

Только непонятно(очень сложно) что вы этим добиваетесь?

Что бы было если бы эта строка

CDataManager*  m_data;

Была бы записана в public

Класы для меня тёмный лес. За 2 года так и не понял как с ними обращаться.

 

есть необходимость писать статистику результатов тестирования в таблицу БД,

БД создана заранее, интересующие проходы пишу включением sinput переменной в настройках ЕА

БД:

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)
)

пишу в эту таблицу таким кодом:

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)));


перечисление  ENUM_STATISTICS имеет очередность как в справке, скрипт для проверки:

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


все работает, НО текст кода довольно обьемный, высока вероятность опечатки, как бы получить этот запрос к БД  более надежным способом - основная проблема как в  StringFormat попасть

 
Igor Makanu:

есть необходимость писать статистику результатов тестирования в таблицу БД,

БД создана заранее, интересующие проходы пишу включением sinput переменной в настройках ЕА

БД:

пишу в эту таблицу таким кодом:


перечисление  ENUM_STATISTICS имеет очередность как в справке, скрипт для проверки:


все работает, НО текст кода довольно обьемный, высока вероятность опечатки, как бы получить этот запрос к БД  более надежным способом - основная проблема как в  StringFormat попасть

За дефайнить!!! (хотя тут обычная перегруза пойдет)

И зачем нужен этот стринг формат?

Он ни разу не быстрее чем обычное добавление.... (я делал текстовики на десятки гигов =).... даже обычное добавление быстрее получается, такие дела...


Если прям принципиально делать через эту штатную функцию то тоже не понятна проблема ))

 
Alexandr Andreev:

И зачем нужен этот стринг формат?

Он ни разу не быстрее чем обычное добавление.... (я делал текстовики на десятки гигов =).... даже обычное добавление быстрее получается, такие дела...

не знаю

прочитал справку и статью, создал запрос к БД по примерам

вроде все работает, но подозреваю, что если буду частично использовать этот код, то могу сделать опечатки

в общем стремно выглядит эта конструкция, вот и спрашиваю, как бы сделать компактнее и не накосячить )))

 
Igor Makanu:

есть необходимость писать статистику результатов тестирования в таблицу БД,

БД создана заранее, интересующие проходы пишу включением sinput переменной в настройках ЕА

БД:

пишу в эту таблицу таким кодом:


перечисление  ENUM_STATISTICS имеет очередность как в справке, скрипт для проверки:


все работает, НО текст кода довольно обьемный, высока вероятность опечатки, как бы получить этот запрос к БД  более надежным способом - основная проблема как в  StringFormat попасть

помниться что во первых что в SQLite типы полей опциональны и можно не упарываться над указаниями и приведением типов. Он-же не спроста "Lite"

длинный запрос можно разбить на 3-4-5 :-)

BEGIN TRANSACTION

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

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

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

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

это по старой памяти, то есть надо уточнять в справке

 
Igor Makanu:

не знаю

прочитал справку и статью, создал запрос к БД по примерам

вроде все работает, но подозреваю, что если буду частично использовать этот код, то могу сделать опечатки

в общем стремно выглядит эта конструкция, вот и спрашиваю, как бы сделать компактнее и не накосячить )))

Конкретно твоя задача, примерно так должна решаться:

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:

Конкретно твоя задача, примерно так должна решаться:

блин!

точно! массивы!

СПАСИБО!!!!!

Причина обращения: