Эмуляция тиков из советника/индикатора - страница 8

 
expertboss, так а нужен ли вам вообще 2008 сервер? По-моему, возможностей 2003 вполне хватает, к тому же он менее требователен к ресурсам, а значит можно выбрать более дешёвое железо.
 
Meat:

Если эти ваши часы являются экспертом (не индикатором), то по всей видимости они просто зациклены, поэтому без проблем получают инфу по множеству символов. Я об этом и писал ранее, что в эксперте действительно нет большой проблемы с тиками, т.к. его можно сделать зацикленным. А вот с индикатором такой номер не пройдёт.

Что касается различных ОС, то для меня самого это до сих пор загадка. Как я уже писал выше, у меня на семёрке пашет нормально, а у других людей почему-то нет. Возможно там что-то связанное с правами доступа...

Кстати, что касается "замены библиотек", попробуйте взять файлы user32 и kernel32 от WinXP(2003) и засунуть их в папку Experts\libraries на том компе, где установлена Vista(2008). Вдруг заработает? :)  ...хотя сомневаюсь...

Скажу прямо на по поводу тиков я на"Вашей стороне"  вот по поводу часов судя по ответу Вы не поняли мою мысль попробую с кодом :

int init()

  {

 ObjectCreate( "ServerTime", OBJ_LABEL, 0,0,0,0,0,0,0);

 ObjectSet( "ServerTime", OBJPROP_CORNER, 3);

 ObjectSet( "ServerTime", OBJPROP_XDISTANCE, 10);

 ObjectSet( "ServerTime", OBJPROP_YDISTANCE, 37);

 ObjectSetText(  "ServerTime", "", 20, "Arial", Green);

    return;

  } 

    int start()

    {

   ObjectSetText("ServerTime", TimeToStr( TimeCurrent(), TIME_SECONDS )); 

...

    return;

  } 

тикают они как понятно с новым тиком для этого графика И ЕСЛИ в окне  "обзор рынка" только один инструмент по которому создан график, то время и обновление его этого времени тоже совпадает по тику на графике и соответственно по работе эксперта, А вот если в окне "обзор рынка" стоит несколько инструментов , пусть все, то на маленьких часиках которые отображаются в шапке "обзор рынка : 22:59:58" , то часики эти почти не останавливаются тикают со всеми котировками по всем инструментам, там онигде-то тикают и как котировка сменилась у меня на паре так мои часы сравнялись тс теми .Вот и мысль """"можно ли эти все тики сложить и применить к моему эксперту или окошку где работает эксперт"""  в итоге и получится что тиков будет намного больше чаще чем котировка только одной пары.

Александр. 

 Зацикливать не хочется ресурсы ...  То есть свести все тики со всех котировок в один график? 

 

А с чего вы господа решили что это агрессия? Это всего лишь напоминание о принципах вежливости. Прежде чем что то предлагать, надо что то вложить взамен. А если у вас ничего нет, то вы можете только просить, и это есть истина.

Я вот небольшой спец в 64 битных системах, но эта тема меня очень интересует, но так как я ничем здесь помочь не могу , мне остается попросить людей знающих. И ничего в этом зазорного я не вижу. 

 
FAQ:

А с чего вы господа решили что это агрессия? Это всего лишь напоминание о принципах вежливости. Прежде чем что то предлагать, надо что то вложить взамен. А если у вас ничего нет, то вы можете только просить, и это есть истина.

Я вот небольшой спец в 64 битных системах, но эта тема меня очень интересует, но так как я ничем здесь помочь не могу , мне остается попросить людей знающих. И ничего в этом зазорного я не вижу. 


Наверно все в запарке и эмоциях получилось но ведь Вы модератор и следите за словами спасибо за замечание постараюсь охладить свой пыл. 

С Ув. Александр. 

 
expertboss:

Вот и мысль """"можно ли эти все тики сложить и применить к моему эксперту или окошку где работает эксперт"""  в итоге и получится что тиков будет намного больше чаще чем котировка только одной пары.

Александр. 

 Зацикливать не хочется ресурсы ...  То есть свести все тики со всех котировок в один график? 

Советник реагирует только на свои тики, поэтому "сложить" вы ничего не сможете.  Вариантов всего два: либо ставить таймер (как предложил я), либо запускать параллельно зацикленный советник на другом чарте, который будет "тикать" вашего советника. И вот в этом зацикленном советнике вы как-раз таки можете прописать условия, при которых требуется "тикать". Например если изменилось значение TimeCurrent(), как в описанном вами случае.  Хотя, опять же, не вижу смысла в дополнительном советнике, если можно с тем же успехом зациклить исходный советник (т.е. ваши часики).

 
Вообще, имхо, решением всех проблем было бы отыскать в памяти адрес функции Старт :)  Тогда можно было бы много чего придумать, вплоть до многопоточного выполнения программы.
 
Столкнулся с проблемкой такого плана когда на терминал не поступают штатные тики а таймер работает соответственно советник прорабатывает код и в какой то момент советник начинает посылать ложные запросы к примеру на закрытие ордера, там получается в итоге сервер присылает общую ошибку "2" потом ошибку "3" и может так же выдать по номеру ордера и т. п. я вышел из положения таким образом """""""""""" if (OrdersTotal()==0){Alert (" Нечего удалять ");Sleep(1000);break;} // Если орд. нет выход из цикла закр.""""""""""""" (выход из while), но сами понимаете немного не корректно. Вопрос : можно ли как то сделать так чтобы была какая-то команда или оператор(даже не знаю как назвать), чтобы была возможность приостанавливать тики пока допустим не прийдет ответ с сервера true (пример true=OrderClose (OrderTicket(),....) потом дальше как обычно. Конечно же это просьба, на сколько это возможно. И еще одно наблюдение (в выходные заметил) - если сдвинуть график - то при тике он возвращается на место от генератора или штатного тика, кнопка "советники" отжата выходные тиков нет, а график все равно возвращается на место, удалил советника с графика все прекратилось. С Ув. Александр.
 
Meat:

В общем вот окончательный вариант функции:

// push ebp; move ebp,esp; push 01; push 02; push MT4InternMsg; push hWnd; mov eax,PostMsgAddr; call eax; pop ebp; ret 0010;

Насколько я понял, Вы используете команду PostMessageA(hwnd, RegisterWindowMessageA("MetaTrader4_Internal_Message"), 2, 1). Эта команда эмулирует тики для эксперта (судя по описанию в WinUser32.h). Для индикаторов тики не эмулируются, соответственно и индикатор не обновляется. К сожалению нету WinXP для проверки, но если для индикатора тики все же под ХР эмулируются, то я удивлен.

И еще, проверил Ваш алгоритм

  for (int i=0;  i<ArraySize(value);  i++)
    for (int j=0;  j<len[i];  j++, byte++)
      TimerCode[byte/4] |= value[i]>>(8*j)&0xFF<<(byte%4*8);

под дебагером VisualStudio и то что я получил в результате в массиве TimerCode совсем не соответствовало ожидаемому результату. Вы уверены, что данный алгоритм не содержит ошибок? Могу привести код и скриншот результата что получилось. Если есть желание, можем разобрать более детально.

 

Хоть эта тема теперь не очень актуальна, но всё-же я думаю имеются те, кто не торопится переходить на новые билды :) Поэтому если у кого не работает тиковый таймер в Win7/Win8, то надо либо отключить средство DEP, либо добавить такую функцию:

#import "kernel32.dll"
  bool  VirtualProtect(int lpAddress[], int dwSize, int flNewProtect, int& lpflOldProtect[]);

И в итоге такой вариант:

int SetMyTimer(int interval=1000, int timerId=0)
{    
  int MT4InternMsg= RegisterWindowMessageA("MetaTrader4_Internal_Message");
  int hWnd= WindowHandle(Symbol(),Period());
  int PostMsgAddr= GetProcAddress(GetModuleHandleA("user32.dll"),"PostMessageA");
  if (PostMsgAddr==0 || hWnd==0) return(0);
  static int TimerCode[7];  ArrayInitialize(TimerCode,0);
  int oldprotect[1]; 
  VirtualProtect(TimerCode, ArraySize(TimerCode)*4, 0x40, oldprotect);  // PAGE_EXECUTE_READWRITE
  // push ebp; move ebp,esp; push 01; push 02; push MT4InternMsg; push hWnd; mov eax,PostMsgAddr; call eax; pop ebp; ret 0010;    
  int bytes[]={ 0x55, 0x8B,0xEC, 0x6A,01, 0x6A,02, 0x68,0000, 0x68,0000, 0xB8,0000, 0xFF,0xD0, 0x5D, 0xC2,0x10 };
  int len[]=  { 1,    1,   1,    1,   1,  1,   1,  1,   4,    1,   4,    1,   4,    1,   1,    1,    1,   2 };
  bytes[8]=MT4InternMsg;  bytes[10]=hWnd;  bytes[12]=PostMsgAddr;
  int nbyte=0;  
  for (int i=0;  i<ArraySize(bytes);  i++)
    for (int j=0;  j<len[i];  j++, nbyte++)
      TimerCode[nbyte/4] |= bytes[i]>>(8*j)&0xFF<<(nbyte%4*8);
  timerId= SetTimer(hWnd, timerId, interval, TimerCode);
  return (timerId);
}
Причина обращения: