Полезная штука. Давно стоило кому-то выложить, я вот никак не созрею =)
Поскольку тестировать тут вряд ли кто-нибудь будет, а если будет, то не скоро, то я решил, что сначала вылизать, а потом выложить. А времени нет.
зы: в лог-файле удобнее, если строка начинается с Локалтайма - тогда и хронологию проследить можно. А символ с периодом в имя файла вынести.
зызы: Понравилась идея "уровней", т.е. приритетов сообщений. Надо бы и у себя сделать... А ещё можно сделать ф-цию отправки мыла и ф-цию вывода на экран в текстлейбл.
Когда же я возмусь за работу?..... =)))
Поскольку тестировать тут вряд ли кто-нибудь будет, а если будет, то не скоро, то я решил, что сначала вылизать, а потом выложить. А времени нет.
зы: в лог-файле удобнее, если строка начинается с Локалтайма - тогда и хронологию проследить можно. А символ с периодом в имя файла вынести.
зызы: Понравилась идея "уровней", т.е. приритетов сообщений. Надо бы и у себя сделать... А ещё можно сделать ф-цию отправки мыла и ф-цию вывода на экран в текстлейбл.
Когда же я возмусь за работу?..... =)))
зы: в лог-файле удобнее, если строка начинается с Локалтайма - тогда и хронологию проследить можно.
Согласен, я у себя уже поправил.
А символ с периодом в имя файла вынести.
Не согласен, удобно в имя файла добавить Локалтайм.
зызы: Понравилась идея "уровней", т.е. приритетов сообщений. Надо бы и у себя сделать... А ещё можно сделать ф-цию отправки мыла и ф-цию вывода на экран в текстлейбл.
Насчет уровней идея старая, и наверняка не моя :))
Не согласен, удобно в имя файла добавить Локалтайм.
Локалтайм само собой =))) я сделал структуру папок, и одна из них - символ, а другая ТФ
Локалтайм само собой =))) я сделал структуру папок, и одна из них - символ, а другая ТФ
Да, наверное.
Убрал у себя символ из лога и добавил время.
А символ и таймфрейм перенес в название файла.
Так вроде бы удобнее .. :))
Mak, не смотрел ещё - "Сообщество Экспертописателей" ??? Там я свою "информашку" вчера выложил, достаточно громоздко, конечно, да и наверняка с ошибками =) , но тоже вариант..
Смотрел.
Но для меня слишком сложно ...
Или свое всегда кажется проще ..? :))
Я кстати думал что отладка будет сильно тормозить,
но вот смотрю сейчас - индикатор на 2000 баров с отладочным выводом на несколько сот кило успевает эти бары в пределах 1 секунды обработать :))
Нормальная скорость!
Но для меня слишком сложно ...
Или свое всегда кажется проще ..? :))
Я кстати думал что отладка будет сильно тормозить,
но вот смотрю сейчас - индикатор на 2000 баров с отладочным выводом на несколько сот кило успевает эти бары в пределах 1 секунды обработать :))
Нормальная скорость!
Но для меня слишком сложно ...
там не сложно, там просто криво написано =)
и задача другая - сопровождать работу эксперта полноценным выводом инфы.
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Основное в ней - это средства отладки,
т.е. просто вывод диагностики в файл или лог эксперта.
С ее помощью я у себя в скриптах много удивительного обнаружил :))
Многое работает не так, как я ожидал при написании экспертов ...
Только не спрашивайте что там и зачем.
Разжевывать все детали времени нет, приведу только некоторые примеры.
//+------------------------------------------------------------------+ //| Util.mq4 | //| Copyright © 2005, Yuri Makarov | //| http://mak.tradersmind.com | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005, Yuri Makarov" #property link "http://mak.tradersmind.com" #include "WinUser32.mqh" #include <stdlib.mqh> // Обработчик Тиков. // Генерирует события newBar и newTick. int _prevTime = 0; // Время предыдущего тика int start() { int curTime = Time[0]; if (_prevTime != curTime) { newBar(); _prevTime = curTime; } newTick(); } // Устранение подвисания терминала при расчете индикаторов. // Функция Idle вставляется в цикл расчета индикатора. int _hwnd = 0; int Idle() { if (_hwnd == 0) _hwnd = WindowHandle(Symbol(),Period()); if (_hwnd != 0) SendMessageA(_hwnd,0,0,0); } // Iff - функция условного выбора double Iff(bool check, double TrueValue, double FalseValue) { if (check) return(TrueValue); else return(FalseValue); } //----------------------------------------------------------- // Функции отладки. //----------------------------------------------------------- string _LogFile = ""; // Имя лог файла. int _LogHandle = -1; // Хандлер лог файла. int _LogLevel = 0; // Уровень отладки. // Возвращает уровень отладки int LogLevel() { return (_LogLevel); } // Открытие лог файла и установка уровня отладки. int LogOpen(string Name = "", int Level = 1) { LogClose(); _LogFile = Name; _LogLevel = Iff(Level < 0,0,Level); if (Name != "") { _LogHandle = FileOpen(Name,FILE_WRITE); if (Check(_LogHandle <= 0, "Ошибка открытия Лог файла")) MessageBox("" + GetLastError() + ": " + ErrorDescription(GetLastError()), "Ошибка открытия Лог файла", MB_OK|MB_ICONWARNING); } else _LogHandle = -1; } // Закрытие лог файла. int LogClose() { if (_LogHandle > 0) { LogFlush(); FileClose(_LogHandle); } _LogLevel = 0; } // Сбросить буфер лог файла. int LogFlush() { if (_LogHandle > 0) FileFlush(_LogHandle); } // Вывод сообщения в лог. // Level = 0 - выводится всегда, при любом уровне отладки. int Log(int Level, string mes = "") { if (LogLevel() >= Level) { string sLevel = ""; for (int i = 0; i < Level; i++) sLevel = sLevel + " "; if (_LogHandle > 0) FileWrite(_LogHandle, Symbol()+" ("+Period()+") " + sLevel + mes); else Print(sLevel + mes); } } // Проверка условия истинности. bool Check(bool Cond, string mes) { if (Cond) Log(0, mes); return (Cond); } //======================================================== //======================================================== //------------------ В рабочей версии закомментировать. //int newTick(){if (LogLevel() > 0) Check(false,"***");Idle();} //int newBar(){LogOpen(); LogFlush(); LogClose();}При использовании библиотеки нужно убрать из скриптов функцию start().
Вместо нее нужно использовать события
int newBar() {} int newTick() {}Первая функция вызывается при формировании нового бара,
вторая это и есть аналог start(), т.е. она вызывается на каждом тике.
Если комуто это не нравится, можно закоментировать в тексте библиотеки функцию start() и использовать ее в скриптах как и раньше.
LogOpen(File = "", Level = 0) - Открытие лога
-- File - имя файла куда пишется лог, если = "", то лог выдается в закладку эксперта в МТ
-- Level - уровень отладки, будут выводиться только строки с уровнем меньше или равным Level.
LogClose() - закрытие лога.
Закрывается файл лога на диске и устанавливается вывод уровня 0 в закладку МТ.
Log(Level, Message) - вывод Message в лог, если Level <= заданному уровню отладки.
Check(Condition, Message) - вывод Message в лог, если выполнено условие Condition.
Возвращает Condition.
Использование.
Пример.
int init() { LogOpen("log.txt",5); Log(0,"Init --- "+TimeToStr(LocalTime(),TIME_SECONDS)); .............. } int deinit() { Log(0,"DeInit --- "+TimeToStr(LocalTime(),TIME_SECONDS)); LogClose(); } int newBar() { Log(1,"NewBar "+TimeToStr(LocalTime(),TIME_SECONDS)); } int newTick() { Log(2,"NewTick, Ask = "+Ask+" Bid = "+Bid); int counted_bars=IndicatorCounted(); if ( Bars <= 100 ) return(-1); .............. }Общее правило,
Чем детальнее и обильнее вывод (например в цикле),
тем больше ставится Level в функции Log().
Задавая уровень отладки в LogOpen(),
вы можем управлять глубиной отладки.
Т.е.
LogOpen("", 0) - вывод только самых основных сообщений.
LogOpen("", 1) - более детальный вывод.
LogOpen("", 2) - еще более детальный вывод.
и т.д.
Функция Check() используется для проверки некоторых условий,
например входных параметров на допустимые значения,
инвариантов в циклах (см. Вирта) и пр.
Check выводит в лог всегда, независимо от установленного уровня отладки.
Вот пример лог файла