чем Ваш код лучше "тикалки" из скрипта period_converter ?
сделал так:
#property indicator_chart_window #import "user32.dll" int RegisterWindowMessageA(string lpString); int SetTimer(int hWnd,int nIDEvent,int uElapse,int& lpTimerFunc[]); bool KillTimer(int hWnd,int uIDEvent); #import "kernel32.dll" int GetModuleHandleA(string lpModuleName); int GetProcAddress(int hModule,string lpProcName); int TimerId=666; //+------------------------------------------------------------------+ int init(){ SetMyTimer(1000); // интервал в миллисекундах return(0); } //+------------------------------------------------------------------+ int deinit(){ KillMyTimer(); Comment(""); return(0); } //+------------------------------------------------------------------+ int start(){ int i,limit; limit = 1000; for(i=limit; i>=0; i--){ Comment("i = ",i); } Print("цикл завершен...."); return(0); } int SetMyTimer(int interval) { int MT4InternalMsg= RegisterWindowMessageA("MetaTrader4_Internal_Message"); int hWnd= WindowHandle(Symbol(),Period()); int PostMsgAddr= GetProcAddress(GetModuleHandleA("user32.dll"),"PostMessageA"); int code[]; AddBytes(code,0x55); // push ebp AddBytes(code,0x8B); // move ebp,esp AddBytes(code,0xEC); AddBytes(code,0x6A); // push 01 AddBytes(code,0x01); AddBytes(code,0x6A); // push 02 AddBytes(code,0x02); AddBytes(code,0x68); // push MT4InternalMsg AddBytes(code,MT4InternalMsg,4); AddBytes(code,0x68); // push hWnd AddBytes(code,hWnd,4); AddBytes(code,0xB8); // mov eax, PostMsgAddr AddBytes(code,PostMsgAddr,4); AddBytes(code,0xFF); // call eax AddBytes(code,0xD0); AddBytes(code,0x33); // xor eax, eax AddBytes(code,0xC0); AddBytes(code,0x5D); // pop ebp AddBytes(code,0xC3); // ret return (SetTimer(hWnd, TimerId, interval, code) ); } //--------------------------------------------------- bool KillMyTimer() { return( KillTimer(WindowHandle(Symbol(),Period()), TimerId) ); } //+------------------------------------------------------------------+ int AddBytes(int& code[], int value, int bytescount=1) { static int pos=0; // текущая позиция (в байтах) if (ArraySize(code)==0) pos=0; for (int i=0; i<bytescount; i++, pos++) { int cell=pos/4; if (cell>=ArraySize(code)) ArrayResize(code,cell+1); int byte=pos%4; code[cell] &= ~(0xFF<<(byte*8)); // обнуляем место под байт code[cell] |= value&0xFF<<(byte*8); // записываем байт value>>=8; } return(pos); }
в логе один раз:
11:02:31 test USDCHF,H1: loaded successfully
11:02:31 test USDCHF,H1: initialized
11:02:31 test USDCHF,H1: цикл завершен....
комментарий остался: i = 0
чёт не так ((((
Не фига себе кода сколько! Для индикатора достаточно одной строки.
#property indicator_chart_window #include <WinUser32.mqh> int nCounter = 0; void start() { int hwndChart = WindowHandle(Symbol(), 0); SendMessageA(hwndChart, WM_COMMAND, 0x822C, NULL); // <-- Этой строки. nCounter++; Comment(nCounter); }
Не фига себе кода сколько! Для индикатора достаточно одной строки.
В Вашем коде, во-первых, идёт не просто эмуляция тика, а принудительное обновление графика с соответствующей подгрузкой истории на каждом тике. Вы хоть в лог журнала заглядываете иногда? Загляните на досуге и посмотрите что там творится. И прикиньте что там будет через денёк например. Особенно если запущено несколько копий индикатора. Я уж молчу про нагрузку системы и интернет-канала.
Если же в вашем коде вместо обновления графика сделать именно эмуляцию тика, то это приведёт к зацикливанию (т.е. индикатор будет запускаться без остановки), а соответственно к подвисанию терминала.
IgorM, у меня Print выводится каждую секунду, как и положено. Не знаю почему у вас только один раз... Может из-за различий в операционках... У меня XP стоит.
А в журнале не выдаётся какая-нибудь ошибка? И проверьте, чему у вас равен PostMsgAddr, не нулю?
IgorM, у меня Print выводится каждую секунду, как и положено. Не знаю почему у вас только один раз... Может из-за различий в операционках... У меня XP стоит.
А в журнале не выдаётся какая-нибудь ошибка? И проверьте, чему у вас равен PostMsgAddr, не нулю?
у меня вин7, в журнале нет ошибок, сейчас занят, может чуть позже перезагружу комп в хр - у меня 2 операционки
Да можете не напрягаться, я сам только что у себя запустил семёрку (Ultimate). Всё отлично на ней пашет. Так что не знаю, почему не работает у Вас...
Да можете не напрягаться, я сам только что у себя запустил семёрку (Ultimate). Всё отлично на ней пашет. Так что не знаю, почему не работает у Вас...
...так что не знаю почему работает у Вас....
Значит нам нужно услышать ещё чей-нибудь отзыв по поводу семёрки, чтоб окончательно определиться, кто прав, кто виноват :)
Кстати, а что насчёт PostMsgAddr, о котором я писал выше? Он не равен нулю?
поставил после
int SetMyTimer(int interval) { int MT4InternalMsg= RegisterWindowMessageA("MetaTrader4_Internal_Message"); int hWnd= WindowHandle(Symbol(),Period()); int PostMsgAddr= GetProcAddress(GetModuleHandleA("user32.dll"),"PostMessageA"); Print("PostMsgAddr =",PostMsgAddr); int code[];в логе получил:
23:39:01 test EURUSD,H1: loaded successfully
23:39:01 test EURUSD,H1: PostMsgAddr =1977398342
23:39:01 test EURUSD,H1: initialized
23:39:01 test EURUSD,H1: цикл завершен....
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Давно задавался целью реализовать автоматическую эмуляцию тиков из советника/индикатора (т.е. чтобы он сам себя мог "тикать"), не прибегая к использованию самописных DLL или запуску скриптов. Чисто спортивный интерес, так сказать :) Хотя возможно кому-то это будет очень полезно, если стоит задача не выходить за рамки файла MQL, а зацикливать код нельзя (в частности индикаторы).
В общем обычными путями это сделать невозможно, поэтому пришлось частично писать в машинном коде. Ниже выкладываю получившийся вариант.
Советник устанавливает таймер, который через заданные промежутки времени генерирует тик на своём графике.