Эвента на изменение таблицы "Клиентский портфель"

Страницы: Пред. 1 2
RSS
Эвента на изменение таблицы "Клиентский портфель"
 
Цитата
swerg написал:
но QUIK совершенно без задержек реагирует
Дайте угадаю, в мейне есть вызов какой-то сишной функции? Так-то, если в нем один луа-цикл без никто, мейн лок захватит и все, квик на первом же колбеке встанет колом, о чем тут и сообщают.

Цитата
Михаил Филимонов написал:
PostMessage(HWND_BROADCAST
Цитата
swerg написал:
минимальные задержки
Что такое минимальные задержки, это каждый понимал по-своему ) ну, ежли задача стоит показать, как "квик тормозит в сравнении с метатрейдером", то верной дорогой пойдено.
 
Цитата
Anton написал:
Дайте угадаю, в мейне есть вызов какой-то сишной функции? Так-то, если в нем один луа-цикл без никто, мейн лок захватит и все, квик на первом же колбеке встанет колом, о чем тут и сообщают.

Не надо ничего угадывать.
Я взял буквально тот скрипт, который здесь был приведён.
Вот полный текст:

Код
function     OnStop ()
  is_run    =       false
end

function     main ()
  is_run    =       true   
  a   =      0   
  while    is_run    do   
    a   =   a   +      1   
  end   
end   
 
swerg, дайте угадаю, QUIK 7.x  :lol:
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата

Что такое минимальные задержки, это каждый понимал по-своему ) ну, ежли задача стоит показать, как "квик тормозит в сравнении с метатрейдером", то верной дорогой пойдено.
При чем тут задача показать как "квик тормозит в сравнении с метатрейдером"?

Я реально торгую на Е-Б-С счете через квик,
Выводил данные через DDE в свое приложение (работало очень медленно),
поэтому я и решил брать данные из МТ5 Стало гораздо быстрее...
 
Цитата
swerg написал:
Я взял буквально тот скрипт, который здесь был приведён.

Уточню: QUIK 8.11.0.66
Для запуска скрипта используется Lua 5.3.5

ЗЫ
Попробовал запустить на Lua 5.4 - в самом деле QUIK завис насмерть...
гыгыгы :))) Вот вам и хвалёная Lua 5.4 где "все стабильнее"
 
Цитата
swerg написал:
Вот вам и хвалёная Lua 5.4 где "все стабильнее"
Я сейчас и на 5.3 повесил, с одной модификацией (и открытой таблицей параметров, чтобы подписка была)

Код
function OnStop()
  is_run = false
end

function OnParam()
end

function main()
  is_run = true
  a = 0
  while is_run do
    a = a + 1
  end
end
А вот OnStop отрабатывает нормально, паче чаяния. Видимо, правили косяк с зависанием окон в OnStop, а поправили нечто совершенно иное.

Цитата
Михаил Филимонов написал:
При чем тут задача показать как "квик тормозит в сравнении с метатрейдером"?
Очень прожорливо из колбеков бродкасты отправлять. Оно ж буквально все окна в системе обходит в каждом колбеке.
 
Два Квика каких-то версий, несколько раз обновлённых, а какая там версия Lua - ваще без понятия,  где её смотреть. О, в "компонентах" какая-то qlua.dll 3.0.3.2 - это, штоле? И мне абсолютно пофиг, подвесит этот пример мою ласточку или нет. Торгует (тьфу-тьфу, в обоих Квиках успешно) - и слава Богу!  :smile:  
 
Цитата
Anton написал:
Очень прожорливо из колбеков бродкасты отправлять. Оно ж буквально все окна в системе обходит в каждом колбеке.
Прожорливо, если используется 1 робот. Я использую 42 робота.
Гораздо прожорливее будет запускать в Квике 42 скрипта да еще заморачиваться, чтобы указать handle принимающего приложения (как это реализовано
в экспорте в МТ5, но там все просто)
Потом PostMessage() тем и хорош, что он не ждет ответа - отослал и "забыл" о ней, а все 42 робота получат данные.
"Прожорливо", так это с какой стороны смотреть :)  
 
СОРОК ДВА РОБОТА?! Куда уж прожорливее - хоть с какой стороны смотреть. У меня как-то и один скрипт справляется. Думаю, как и у всех нормальных людей. Ресурсов практически не жрёт - ему же не надо рассылать данные по 42 направлениям. :smile:  
 
Цитата
Владимир написал:
СОРОК ДВА РОБОТА?! Куда уж прожорливее - хоть с какой стороны смотреть. У меня как-то и один скрипт справляется. Думаю, как и у всех нормальных людей. Ресурсов практически не жрёт - ему же не надо рассылать данные по 42 направлениям. ::  
"Нормальных" людей?
Вы себя к ним опрометчиво причислили.
Кстати, у меня на ФОРТС,  работают 2 терминала МТ5, в сумме 86 роботов, и ничего не виснет...
 
Михаил Филимонов, А Вы себя к каким людям относите? :smile:

Я когда-то работал техническим директором компьютерной фирмы. Так за "86 роботов" я бы уволил любого своего программера, ни секунды не задумываясь! Ах, какая прелесть: "не виснет"!
 
Цитата
Михаил Филимонов написал:
запускать в Квике 42
Ну это как-то в лоб решение. Клиенты могут раз в секунду, скажем, рассылать бродкаст WM_APP_QUIK_CLIENT_CONNECT (название условное) с хэндлом своего окна в wparam, скрипт (один) в квике их слушает, сохраняет хэндл клиента в список подписантов и отвечает WM_APP_QUIK_SERVER_CONNECT со своим хэндлом. И все, клиент прекращает спамить, а сервер в колбеках шлет PostMessage по списку. Ну то есть стырить идею в том же дде, чуть поправив.
 
Цитата
Anton написал:
Цитата
Михаил Филимонов написал:
запускать в Квике 42
Ну это как-то в лоб решение. Клиенты могут раз в секунду, скажем, рассылать бродкаст WM_APP_QUIK_CLIENT_CONNECT (название условное) с хэндлом своего окна в wparam, скрипт (один) в квике их слушает, сохраняет хэндл клиента в список подписантов и отвечает WM_APP_QUIK_SERVER_CONNECT со своим хэндлом. И все, клиент прекращает спамить, а сервер в колбеках шлет PostMessage по списку. Ну то есть стырить идею в том же дде, чуть поправив.
X-mmm.
Вы сами-то торгуете несколькими роботами?
Сделки от разных роботов совершаются достаточно часто, а средства для всех роботов одни.
Перед сделкой роботы проверяют достаточность средств на счете для совершения оных.
Поэтому каждый робот должен "мгновенно" получать инфу о состоянии счете (наличие свободных средств)
 
Михаил Филимонов,
Цитата
Вы сами-то торгуете несколькими роботами?
О, классный вопрос! Народ, кто-нибудь ещё торгует целой шоблой роботов? Я имею в виду, в количестве более одного?
 
Цитата
Михаил Филимонов написал:
"мгновенно"
Он и будет получать настолько же "мгновенно", как и в случае бродкаста, не заваливая всю систему кучами бесполезных сообщений. Перечитайте еще раз, "раз в секунду" это процесс обнаружения клиента, как только он обнаружен, сообщения посылаются ему немедленно из колбеков. Если думаете, что пройтись по своему списку окон медленнее, чем винда пройдется по списку всех окон, то это заблуждение.
 
Цитата
Владимир написал:
шоблой роботов
Клиенты не обязаны быть именно роботами и именно торговать. Кто-то статистику ведет, кто-то какие-то события отслеживает, упихивать все это разнородье в один процесс глупо как-то. Так что сама постановка вопроса "один квик - кучка подписантов" вполне себе нормальная. Есть еще вариант "кучка квиков - кучка подписантов".
 
Цитата
Anton написал:
Цитата
Михаил Филимонов написал:
"мгновенно"
Он и будет получать настолько же "мгновенно", как и в случае бродкаста, не заваливая всю систему кучами бесполезных сообщений. Перечитайте еще раз, "раз в секунду" это процесс обнаружения клиента, как только он обнаружен, сообщения посылаются ему немедленно из колбеков. Если думаете, что пройтись по  своему  списку окон медленнее, чем винда пройдется по списку  всех  окон, то это заблуждение.
Антон!
То, что Вы предлагаете - очень здорово, но как мой скрипт (LUA) будет принимать сообщения от клиентов?
 
И желать список рассылки?
 
делать
 
GetMessage или PeekMessage ?
 
Посмотрел список функций w32 и эти функции там есть.
Беда в том, что я с LUA познакомился 2 дня назад...
 
Anton, У меня нормальная постановка вопроса "один квик - один брокер". Мало того: один Квик - один счёт. Или, как минимум, один код клиента. Вести же статистику или события отслеживать одним процессом проблемы не представляет. По крайней мере, это в 100500 раз меньшие проблемы, чем использовать для этого "86 роботов".
 
Можете "набросать" схему как организовать список хендлов и запись в этот список так, как Вы понимаете этот механизм?
 
Цитата
Михаил Филимонов написал:
Посмотрел список функций w32 и эти функции там есть.
Я тоже сейчас посмотрел внутрь (скачал сорцы у swerg) и есть подозрения, что работать эти функции не будут через w32. Например, PeekMessage
Код
static int global_PeekMessage(lua_State *L) {
    MSG msg;
    BOOL rc;
    long lwnd = MYP2HCAST luaL_optinteger( L, 1, 0); // раз косяк
    UINT mfmin = ( UINT) luaL_optinteger( L, 2, 0);
    UINT mfmax = ( UINT) luaL_optinteger( L, 3, 0);
    UINT rmmsg = ( UINT) luaL_optinteger( L, 4, PM_NOREMOVE);

    rc = PeekMessage( &msg, ( HWND) lwnd, mfmin, mfmax, rmmsg);

    lua_pushnumber( L, rc);
    if( rc) {
        lua_pushnumber( L, ( long) msg.hwnd); // два косяк
        lua_pushnumber( L, msg.message);
        lua_pushnumber( L, msg.wParam); // три косяк
        lua_pushnumber( L, msg.lParam); // четыре косяк
        lua_pushnumber( L, msg.time);
        lua_pushnumber( L, msg.pt.x);
        lua_pushnumber( L, msg.pt.y);
    } else {
        lua_pushnil( L);
        lua_pushnil( L);
        lua_pushnil( L);
        lua_pushnil( L);
        lua_pushnil( L);
        lua_pushnil( L);
        lua_pushnil( L);
    }

    return( 8);
}
На 64 битах HWND это void *, WPARAM и LPARAM - uintptr_t и intptr_t соответственно. Тут их режут до 32 бит и потом еще в даблы упихивают. Так что с использованием w32 я, видимо, ничего набрасывать не стану, во избежание последующих глюков, лучше тогда сразу в своей длл все и делать.

В мейне создаем невидимое окно hwndServer и затем обычный цикл сообщений. В оконной процедуре как-то типа
Код
   switch(msg)
   {
   case WM_QUIK_CLIENT_CONNECT:
      if(connections_allowed)
      {
         HWND hwndClient = (HWND)wparam;
         client_list.push_back(hwndClient);
         SendMessage(hwndClient, WM_QUIK_SERVER_CONNECT, (WPARAM)hwndServer, 0);
      }
      return 0;
   case WM_QUIK_SERVER_STOP:
      connections_allowed = false;
      foreach(hwndClient in client_list)
         SendMessage(hwndClient, WM_QUIK_SERVER_DISCONNECT, (WPARAM)hwndServer, 0);
      client_list.clear();
      DestroyWindow(hwndServer);
      return 0;
   case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
   // и так далее
   }
В колбеках проходим по списку client_list и каждому hwndClient из него PostMessage(hwndClient, ...), точно так же, как в оригинале, только не бродкаст.
В OnStop PostMessage(hwndServer, WM_QUIK_SERVER_STOP, 0, 0);
Вроде и вся механика, помнить только о разных потоках для мейна и колбеков.
 
Цитата
Anton написал:
Спасибо, Антон!
Только нельзя использовать SendMessage(), т.к она ожидает ответа.
Странно, что PeekMessage не будет работать,
PostMessage() работатет исправно.
И еще...
Думается, что так как я написал в разы проще будет... :)
 
Цитата
Anton написал:
Цитата
Михаил Филимонов написал:
"мгновенно"
Он и будет получать настолько же "мгновенно", как и в случае бродкаста, не заваливая всю систему кучами бесполезных сообщений. Перечитайте еще раз, "раз в секунду" это процесс обнаружения клиента, как только он обнаружен, сообщения посылаются ему немедленно из колбеков. Если думаете, что пройтись по  своему  списку окон медленнее, чем винда пройдется по списку  всех  окон, то это заблуждение.
Учтя Вашу критику, переделал LUA скрипт (проверил - все работает)
Спасибо!
//=========================================================
w32 = require("w32")

is_run = false
HWND_BROADCAST = 0xFFFF
A_double = 0.0
WParam = 2
lpParam = 1

WM_EBS_MONEY = w32.RegisterWindowMessage("WM_EBS_MONEY")

if WM_EBS_MONEY >= 0xC000 then
 is_run = true
else
 message("Message not registered!")
end
--начальная отсылка денежных средств
 a_table = getPortfolioInfoEx("MCXXXXXXXXXX", "XXXXX", 2)  
 A_double = a_table.limit_open_pos
 lpParam = math.floor(A_double * 100)
 w32.PostMessage(HWND_BROADCAST, WM_EBS_MONEY, WParam, lpParam)

function OnStop()
 is_run = false
end
-- Отсылка по изменению средств
function OnMoneyLimit(m_limit)
 a_table = getPortfolioInfoEx("MCXXXXXXXXXX", "XXXXX", 2)  
 A_double = a_table.limit_open_pos
 lpParam = math.floor(A_double * 100)
 w32.PostMessage(HWND_BROADCAST, WM_EBS_MONEY, WParam, lpParam)
end

function OnDepoLimit(d_limit)
 a_table = getPortfolioInfoEx("MCXXXXXXXXXX", "XXXXX", 2)  
 A_double = a_table.limit_open_pos
 lpParam = math.floor(A_double * 100)
 w32.PostMessage(HWND_BROADCAST, WM_EBS_MONEY, WParam, lpParam)
end

function OnFuturesClientHolding(f_holding)
 a_table = getPortfolioInfoEx("MCXXXXXXXXXX", "XXXXX", 2)  
 A_double = a_table.limit_open_pos
 lpParam = math.floor(A_double * 100)
 w32.PostMessage(HWND_BROADCAST, WM_EBS_MONEY, WParam, lpParam)  
-- message("Working!")
end


function OnFuturesLimitChange(f_change)
 a_table = getPortfolioInfoEx("MCXXXXXXXXXX", "XXXXX", 2)  
 A_double = a_table.limit_open_pos
 lpParam = math.floor(A_double * 100)
 w32.PostMessage(HWND_BROADCAST, WM_EBS_MONEY, WParam, lpParam)
end

function main()
while is_run do
  sleep(1)
 end
end
 
Цитата
Михаил Филимонов написал:
Учтя Вашу критику
Но все равно по-своему ) В общем, если устраивает, то и хорошо.

В этом варианте в мейне ничего не происходит, можно слип увеличить до 1000.
 
Цитата
Anton написал:
Цитата
Михаил Филимонов написал:
Учтя Вашу критику
Но все равно по-своему ) В общем, если устраивает, то и хорошо.

В этом варианте в мейне ничего не происходит, можно слип увеличить до 1000.

Еще раз спасибо, Антон.
Пусть мое решение не очень элегантное, но будет работать, как Вы хотели :)
 
Цитата
Anton написал:
Я тоже сейчас посмотрел внутрь (скачал сорцы у swerg) и есть подозрения, что работать эти функции не будут через w32. Например, PeekMessage
Код
    long lwnd  =  MYP2HCAST luaL_optinteger( L,  1 ,  0 ); // раз косяк
        lua_pushnumber( L, ( long) msg.hwnd); // два косяк
        lua_pushnumber( L, msg.wParam); // три косяк
        lua_pushnumber( L, msg.lParam); // четыре косяк

  
На 64 битах HWND это void *, WPARAM и LPARAM - uintptr_t и intptr_t соответственно. Тут их режут до 32 бит и потом еще в даблы упихивают.

Каждый может поправить и дополнить https://github.com/swerg/qlua-w32/
Ну или хотя бы завести баг про правку нужной функции https://github.com/swerg/qlua-w32/issues
Сколько ж можно мне-то за всех отдуваться.

Часть функций после появления Int64 для Lua в QUIK я поправил (PostMessage, SendMessage), функции типа PeekMessage мне не нужны, их и не правил пока.

Ноги у либы растут из Lua 5.1 и x86, очевидно, и видимо автору хватало lua_number (который, как известно, в зависимости от сборки Lua может быть int или double; в QUIK это было double).
Для Lua5.1 на x64 в этих функциях по уму надо был переходить на user data, чтобы не терять ничего, но после появления нормального int64 в Lua5.3 в QUIK надобность в этих извращениях, по счастью, отпала.
Страницы: Пред. 1 2
Читают тему
Наверх