Виталий А
Виталий А личный блог
27 марта 2020, 18:37

Скрипт lua читающий таблицу обезличенных сделок.

Всем привет. Может кому пригодится. Скрипт читает ленту сделок и раз в минуту подсчитывает разницу между покупками и продажами. Часть кода нашел в интернете часть кода написал сам. Не знаю может уже есть что то подобное. Цель была не написать что то оригинальное, а наработать навыки программирования на lua.
TICER = "SBER";
CLASS_CODE = "TQBR";

stopped = false;
t_id = nil
H = -1;
M = -1;
VSELL = 0;
VBUY  = 0;

function OnInit()
        CreateTable();
end 

function main() 
  while not stopped do 
     if IsWindowClosed(t_id) then
        stopped = true;
     end        
     sleep(100);
  end
end

function CreateTable()
   t_id = AllocTable(); 
   AddColumn(t_id, 0, "Время", true, QTABLE_STRING_TYPE, 10);
   AddColumn(t_id, 1, "BUY", true, QTABLE_INT_TYPE, 15);
   AddColumn(t_id, 2, "SELL", true, QTABLE_INT_TYPE, 15);
   AddColumn(t_id, 3, "Дельта V", true, QTABLE_INT_TYPE, 15);   
   AddColumn(t_id, 4, "Цена", true, QTABLE_DOUBLE_TYPE, 15);
   tab = CreateWindow(t_id);
   SetWindowCaption(t_id, TICER.." Баланс покупок/продаж");
   SetTableNotificationCallback(t_id, EventCallBack);
end

function OnAllTrade(alltrade)
        if alltrade.sec_code == TICER then      
                  fl = tostring(alltrade.flags);
                  if H==alltrade.datetime.hour then
                        if M==alltrade.datetime.min then
                           if fl == "1025" then VSELL = VSELL+alltrade.qty; end --Продажа
                           if fl == "1026" then VBUY  = VBUY+alltrade.qty;  end                         
                        else               
                           M=alltrade.datetime.min;
                           --Rows --срока   Coll -- Колонка
                           InsertRow(t_id, -1);
                           local Rows, Col = GetTableSize(t_id);                           
                           local Delta = VBUY-VSELL;
                           --local t = tostring(alltrade.datetime.hour)..":"..tostring(alltrade.datetime.min);
                           local t = tostring(H)..":"..tostring(M);
                           SetCell(t_id, Rows-1, 0, t);
                           SetCell(t_id, Rows-1, 1, tostring(VBUY));
                           SetCell(t_id, Rows-1, 2, tostring(VSELL));                      
                           SetCell(t_id, Rows-1, 3, tostring(Delta));
                           SetCell(t_id, Rows-1, 4, tostring(alltrade.price));
                           
                           if Delta<0 then Red(Rows-1,3); end
                           if Delta>0 then Green(Rows-1,3); end
                           if Delta==0 then Yellow(Rows-1,3); end
                           if fl == "1025" then VSELL = alltrade.qty; end --Продажа
                           if fl == "1026" then VBUY  = alltrade.qty; end                               
                        end
                  else                   
                         H = alltrade.datetime.hour;
                         M = alltrade.datetime.min;
                  end
        end
end
function Red(row,col)
        SetColor(t_id, row, col, RGB(255,0,0), RGB(0,0,0), RGB(255,0,0), RGB(0,0,0));
end
function Yellow(row,col)
        SetColor(t_id, row, col, RGB(240,240,0), RGB(0,0,0), RGB(240,240,0), RGB(0,0,0));
end
function Green(row,col)
        SetColor(t_id, row, col, RGB(0,200,0), RGB(0,0,0), RGB(0,200,0), RGB(0,0,0));
end


function EventCallBack(t_id, msg, par1, par2)
   if msg==QTABLE_CLOSE then
     OnStop();
   end;
end

function OnStop(s)
  if t_id ~= nil then
    DestroyTable (t_id);
  end;
   stopped = true;
end
35 Комментариев
  • bohemian rhapsody
    27 марта 2020, 19:21
    скинь в блокноте, плиз
      • bohemian rhapsody
        28 марта 2020, 15:13
        Виталий, пошлите на почту, плиз, адрес в личке
  • Винни Пух
    27 марта 2020, 19:22
    А теперь новое ТЗ:
    Сделать тоже самое, но для всех ликвидных и в одной таблице, причем два разных скрипта: Фондовый и Срочный.


    Просто для каждого тикера отдельно запускать смысла… мало.

    пысы, со скриптом неполадки или я летом на лыжах. У меня такие минутные дельты получились. У вас еще с общим объемом сделок не коррелирует. Инструмент юзал для фюьча RIM0, может там собака зарыта.



    • 3Qu
      27 марта 2020, 19:33
      Винни Пух, для всех? У вас из за OnAllTrade() Quik встанет.
      • Винни Пух
        27 марта 2020, 19:46
        3Qu, для ликвидов, и у меня же не встает =)
        • 3Qu
          27 марта 2020, 19:53
          Винни Пух, OnAllTrade() не встает?
          • Винни Пух
            27 марта 2020, 19:58
            3Qu, неа, тьфу тьфу тьфу.
            Фильтрую нужные инструменты на входе при заказе данных.
      • 3Qu
        27 марта 2020, 19:51
        Виталий, сделать одну функцию для всех инструментов, и вызывать ее с соответствующими параметрами. И каши не будет. Будет один большой порядок.)
          • Винни Пух
            27 марта 2020, 20:12
            Виталий, варианта два: либо горизонтально, либо вертикально. В соотв. колонках/строках наименование инструмента или тикера и потом остальные аналитические данные.
            Что-то вроде этого:



              • Винни Пух
                27 марта 2020, 20:44
                Виталий, а зачем исторические данные в таблице? Нужны только свежие, их и добавлять, с удалением старых в логи или куда то еще по мере надобности. Так что и трех колонок хватит. В зависимости от ТФ, день, 4H, 1H, 15M, 1M и т.п. 
  • Vitaliy
    27 марта 2020, 19:32
    полезная штука. Я подобное писал, правда в виде индикатора, который по любому инструменту работает. По сути своей индикатор Дельта для квика написал, ибо не хватало прям для счастья. Для практики программирования рекомендую прописать в скрипт функцию восстановления данных по всем имеющимся обезличенным сделкам :) Без нее мне было грустно с индикатором 
      • Vitaliy
        27 марта 2020, 20:28
        Виталий, Ох поверьте, пользу можно извлечь просто потрясающую и даже, отчасти, провидческую :) Ибо только активные объемы правят миром. Я изначально собирал и обрабатывал эту информацию скриптом типа Вашего и перегонял в эксель и там обрабатывал. Потом под квик все создал и сбор информации, и восстановление и обработку и анализ. У меня есть пару старых постов на тему того, как с помощью плюс-минус такой методики можно делать красивейшие входы в сделки.

        В общем там такой себе граальчик своего рода, если правильно обработать и посмотреть на данные ) Под верным углом, так сказать :)
          • Vitaliy
            27 марта 2020, 20:43
            Виталий, там ничего ценного особо, кроме показанных для примера точек входа. Когда изобрел сие чудо с доработками своими не мог поверить своему счастью и боялся торговать сигналы эти, потом чинил это все в голове и потихоньку уверовал в систему. Системность наше все :)
        • bohemian rhapsody
          10 апреля 2020, 00:04
          Vitaliy, какая доходность у граальчика?
  • 3Qu
    27 марта 2020, 20:11
    Не помню, есть ли у самодельных таблиц экспорт по DDE. Такие данные, по идее, нужно в Excel VBA обрабатывать, и уже выводить там в таблицы в обработанной форме.
    Делаю так, но не с Quik.
      • 3Qu
        27 марта 2020, 20:18
        Виталий, да, вариант, только это надо делать в потоке main(). В Lua для этого есть средства. См. потоки (нити) Lua.
      • 3Qu
        27 марта 2020, 20:38
        Виталий, Кстати, все ваши данные лучше извлекать не из OnAllTrade, а из текущей свечи. Примерно так:

        function main()
        — подписка на получение данных свечи
        ds_s, Err1 =CreateDataSource (EX_CODE, FUT_S, INTERVAL_M1)
        if Err1 == "" or Err1 == nil then
        message(«Пока ОК 1»)
        while not (ds_s:Size() >0) do
        sleep(10)
        end
        — определение функции обратного вызова
        Err1 = ds_s:SetUpdateCallback (cbCandleS)
        if Err1 == true then
        message(«cb1 OK»)
        else
        message(«Err1»… tostring(Err1))
        end
        else
        message(«Ошибка 1»… Err1)
        end

        Это уже не в main()

        — изменение свечи S и запись в БД (получение реал-тайм данных)
        function cbCandleS(i) --
        local dt ={}
        local evt =0
        dt = GetCandle(ds_s, FUT_S, i)
        --message(«Изменение свечи S»)
        a, b = CCS.cvCandleS(dt)
        --message( «CCS.cvCandleS(dt) »… a)
        end


        • Vitaliy
          27 марта 2020, 20:44
          3Qu, а разве из свечи Вы сможете вытащить данные для дельты? Я имею ввиду не общий объем, а именно направление рыночных сделок
          • 3Qu
            27 марта 2020, 20:47
            Vitaliy, да, эт вряд ли смогу, не учел. 
            Я все получаю и свечи и сделки

            function OnAllTrade(alltrade)
            if alltrade.sec_code == FUT_S or alltrade.sec_code == FUT_L then
            --message(«Обезлич сделка beg »… alltrade.sec_code)
            at ={alltrade.datetime, alltrade.sec_code, alltrade.trade_num, alltrade.flags, alltrade.price,
            alltrade.qty, alltrade.value, alltrade.period}
            CCS.AllTrade2DB(at)
            --message(«Обезлич сделка end »… alltrade.sec_code)
            end
            end



  • 3Qu
    27 марта 2020, 20:56
    CCS. func_name() — это вызовы функций DLL, которая все пишет в базу данных и обрабатывает данные.
      • 3Qu
        27 марта 2020, 21:43
        Виталий, имхо, и напрасно.
        Если почитать Р.Иерузалимски, то Lua не самостоятельный язык, а язык расширяемый и расширяющий. Т.е., он изначально разрабатывался не для самостоятельного применения, а для взаимодействия с другими программами.
        В общем, я этой концепции и придерживаюсь, Луа обеспечивает только передачу данных в ПО и взаимодействие ПО с терминалом. Вся обработка на стороне, в нормальных средах программирования с большими возможностями.

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн