Блог им. vitales

Скрипт 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
  • обсудить на форуме:
  • QUIK
7.3К | ★51
35 комментариев
скинь в блокноте, плиз
avatar
bohemian rhapsody, Не знаю как тут файл прикрепить. Зарегистрировался недавно, пока еще не разобрался до конца как ту что работает.
avatar
Виталий, пошлите на почту, плиз, адрес в личке
avatar
А теперь новое ТЗ:
Сделать тоже самое, но для всех ликвидных и в одной таблице, причем два разных скрипта: Фондовый и Срочный.


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

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



avatar
Винни Пух, для всех? У вас из за OnAllTrade() Quik встанет.
avatar
3Qu, для ликвидов, и у меня же не встает =)
avatar
Винни Пух, OnAllTrade() не встает?
avatar
3Qu, неа, тьфу тьфу тьфу.
Фильтрую нужные инструменты на входе при заказе данных.
avatar
Винни Пух, Я думая над этим, но пришел к выводу, что тогда в таблице будет неупорядоченная «каша» если туда все инструменты писать. 
avatar
Виталий, сделать одну функцию для всех инструментов, и вызывать ее с соответствующими параметрами. И каши не будет. Будет один большой порядок.)
avatar
3Qu, Это понятно, что алгоритм должен быть универсальный. Просто как данные из разных инструментов запихнуть в одну таблицу. Тогда надо для каждого инструмента создавать отдельную таблицу.
avatar
Виталий, варианта два: либо горизонтально, либо вертикально. В соотв. колонках/строках наименование инструмента или тикера и потом остальные аналитические данные.
Что-то вроде этого:



avatar
Винни Пух, Можно наверно и так, но тогда, допустим если в колонках писать дельту то для каждого инструмента будет грубо говоря 1440 колонок. Если брать 24 торговых часа по 60 минут в каждом. Надо тогда увеличивать интервал и считать часовую дельту тогда колонок будет 24 для одного инструмента. 
avatar
Виталий, а зачем исторические данные в таблице? Нужны только свежие, их и добавлять, с удалением старых в логи или куда то еще по мере надобности. Так что и трех колонок хватит. В зависимости от ТФ, день, 4H, 1H, 15M, 1M и т.п. 
avatar
Винни Пух, Если так, то это думаю будет работоспособный вариант. Можно брать тикер инструмента из таблицы текущих торгов и уже после получения данных в OnAllTrade() обновлять таблицу.
avatar
Винни Пух, Возможно в скрипте ошибка, и минуты пишет не верно со смещением. Например данные были за 30-тую минуту, а в таблице пишется 31-вая минута. И еще он считает не объем в деньгах, а кол-во лотов в ленте сделок.
avatar
полезная штука. Я подобное писал, правда в виде индикатора, который по любому инструменту работает. По сути своей индикатор Дельта для квика написал, ибо не хватало прям для счастья. Для практики программирования рекомендую прописать в скрипт функцию восстановления данных по всем имеющимся обезличенным сделкам :) Без нее мне было грустно с индикатором 
avatar
Vitaliy, Я пока не знаю какую из этого скрипта можно извлечь практическую пользу. Предполагаю, что информацию из него можно использовать скальперам. В свободное время подумаю, что еще полезного можно будет туда добавить. Может быть накопленную дельту раз в час в дополнении к минутной дельты. 
avatar
Виталий, Ох поверьте, пользу можно извлечь просто потрясающую и даже, отчасти, провидческую :) Ибо только активные объемы правят миром. Я изначально собирал и обрабатывал эту информацию скриптом типа Вашего и перегонял в эксель и там обрабатывал. Потом под квик все создал и сбор информации, и восстановление и обработку и анализ. У меня есть пару старых постов на тему того, как с помощью плюс-минус такой методики можно делать красивейшие входы в сделки.

В общем там такой себе граальчик своего рода, если правильно обработать и посмотреть на данные ) Под верным углом, так сказать :)
avatar
Vitaliy, :) Я только начинаю с этим разбираться, так что у меня все еще впереди. Надо будет почитать ваши посты.
avatar
Виталий, там ничего ценного особо, кроме показанных для примера точек входа. Когда изобрел сие чудо с доработками своими не мог поверить своему счастью и боялся торговать сигналы эти, потом чинил это все в голове и потихоньку уверовал в систему. Системность наше все :)
avatar
Vitaliy, какая доходность у граальчика?
avatar
Не помню, есть ли у самодельных таблиц экспорт по DDE. Такие данные, по идее, нужно в Excel VBA обрабатывать, и уже выводить там в таблицы в обработанной форме.
Делаю так, но не с Quik.
avatar
3Qu, Можно паралельно с выводом в таблицу еще писать в текстовый файл, а потом этот файл обрабатывать в другой программе.
avatar
Виталий, да, вариант, только это надо делать в потоке main(). В Lua для этого есть средства. См. потоки (нити) Lua.
avatar
3Qu, Понял, спасибо почитаю об этом.
avatar
Виталий, Кстати, все ваши данные лучше извлекать не из 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


avatar
3Qu, а разве из свечи Вы сможете вытащить данные для дельты? Я имею ввиду не общий объем, а именно направление рыночных сделок
avatar
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



avatar
3Qu, Я понял, что мы подписываемся на получение данных заданного инструмента и когда происходит изменение свечи выполняем какие то действие. Только не понял, что за объект или структура CCS. Она пишет данные в БД? Пока не знаю как с помощью GetCandle() получить данные о том какое действие вызвало изменение свечи. Покупка или продажа и какой был объем.
avatar
CCS. func_name() — это вызовы функций DLL, которая все пишет в базу данных и обрабатывает данные.
avatar
3Qu, Получается это какая то ваша собственная разработка реализованная в виде DLL. Я пока в это не лезу, мне бы со встроенными функциями разобраться для начала.
avatar
Виталий, имхо, и напрасно.
Если почитать Р.Иерузалимски, то Lua не самостоятельный язык, а язык расширяемый и расширяющий. Т.е., он изначально разрабатывался не для самостоятельного применения, а для взаимодействия с другими программами.
В общем, я этой концепции и придерживаюсь, Луа обеспечивает только передачу данных в ПО и взаимодействие ПО с терминалом. Вся обработка на стороне, в нормальных средах программирования с большими возможностями.
avatar
3Qu, Саму книгу не читал, но видел инфу в интернет, о том что lua лучше использовать совместно со сторонними DLL, это вроде как снижает нагрузку на терминал и дает больше простора для творчества. У меня тут вопрос возник, если не сложно подскажите как мне средствами lua получить вот такую информацию о инструменте.



avatar
Все, спасибо вроде уже сам разобрался.
avatar

Читайте на SMART-LAB:
Фото
Актуальный состав портфеля и взгляд на рынок 2026: по-прежнему 0% позитива.
Добрый вечер! С момента предыдущего поста, касающегося моего портфеля, прошел квартал.  Пришло время актуализировать его состав. Также поделюсь...
Фото
Биткоин попробует разыграть «треугольную карту»?
«Цифровое золото» прорвало верхнюю границу восходящего треугольника на уровне 94 500 и сейчас тестирует пробитую горизонталь, формируя серию...
Фото
Индикатор Fractal: торговые сигналы и робот для OsEngine. Видео
В этом видео разбираем индикатор Fractal Билла Вильямса — один из самых известных инструментов в трейдинге. Покажем, как формируются фракталы,...
Фото
Стратегия 2026 по рынку акций от Mozgovik Research: трудный год, но, возможно, последний год низких цен
Сегодня у меня первый день официального отпуска. За окном темная звездная ночь, яркая белая луна, +24С и шум волн Андаманского моря. Неудачный...

теги блога Виталий А

....все тэги



UPDONW
Новый дизайн