Блог им. 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
★49
скинь в блокноте, плиз
avatar

bohemian rhapsody

bohemian rhapsody, Не знаю как тут файл прикрепить. Зарегистрировался недавно, пока еще не разобрался до конца как ту что работает.
avatar

Виталий

Виталий, пошлите на почту, плиз, адрес в личке
avatar

bohemian rhapsody

А теперь новое ТЗ:
Сделать тоже самое, но для всех ликвидных и в одной таблице, причем два разных скрипта: Фондовый и Срочный.


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

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



avatar

Винни Пух

Винни Пух, для всех? У вас из за OnAllTrade() Quik встанет.
avatar

3Qu

3Qu, для ликвидов, и у меня же не встает =)
avatar

Винни Пух

Винни Пух, OnAllTrade() не встает?
avatar

3Qu

3Qu, неа, тьфу тьфу тьфу.
Фильтрую нужные инструменты на входе при заказе данных.
avatar

Винни Пух

Винни Пух, Я думая над этим, но пришел к выводу, что тогда в таблице будет неупорядоченная «каша» если туда все инструменты писать. 
avatar

Виталий

Виталий, сделать одну функцию для всех инструментов, и вызывать ее с соответствующими параметрами. И каши не будет. Будет один большой порядок.)
avatar

3Qu

3Qu, Это понятно, что алгоритм должен быть универсальный. Просто как данные из разных инструментов запихнуть в одну таблицу. Тогда надо для каждого инструмента создавать отдельную таблицу.
avatar

Виталий

Виталий, варианта два: либо горизонтально, либо вертикально. В соотв. колонках/строках наименование инструмента или тикера и потом остальные аналитические данные.
Что-то вроде этого:



avatar

Винни Пух

Винни Пух, Можно наверно и так, но тогда, допустим если в колонках писать дельту то для каждого инструмента будет грубо говоря 1440 колонок. Если брать 24 торговых часа по 60 минут в каждом. Надо тогда увеличивать интервал и считать часовую дельту тогда колонок будет 24 для одного инструмента. 
avatar

Виталий

Виталий, а зачем исторические данные в таблице? Нужны только свежие, их и добавлять, с удалением старых в логи или куда то еще по мере надобности. Так что и трех колонок хватит. В зависимости от ТФ, день, 4H, 1H, 15M, 1M и т.п. 
avatar

Винни Пух

Винни Пух, Если так, то это думаю будет работоспособный вариант. Можно брать тикер инструмента из таблицы текущих торгов и уже после получения данных в OnAllTrade() обновлять таблицу.
avatar

Виталий

Винни Пух, Возможно в скрипте ошибка, и минуты пишет не верно со смещением. Например данные были за 30-тую минуту, а в таблице пишется 31-вая минута. И еще он считает не объем в деньгах, а кол-во лотов в ленте сделок.
avatar

Виталий

полезная штука. Я подобное писал, правда в виде индикатора, который по любому инструменту работает. По сути своей индикатор Дельта для квика написал, ибо не хватало прям для счастья. Для практики программирования рекомендую прописать в скрипт функцию восстановления данных по всем имеющимся обезличенным сделкам :) Без нее мне было грустно с индикатором 
avatar

Vitaliy

Vitaliy, Я пока не знаю какую из этого скрипта можно извлечь практическую пользу. Предполагаю, что информацию из него можно использовать скальперам. В свободное время подумаю, что еще полезного можно будет туда добавить. Может быть накопленную дельту раз в час в дополнении к минутной дельты. 
avatar

Виталий

Виталий, Ох поверьте, пользу можно извлечь просто потрясающую и даже, отчасти, провидческую :) Ибо только активные объемы правят миром. Я изначально собирал и обрабатывал эту информацию скриптом типа Вашего и перегонял в эксель и там обрабатывал. Потом под квик все создал и сбор информации, и восстановление и обработку и анализ. У меня есть пару старых постов на тему того, как с помощью плюс-минус такой методики можно делать красивейшие входы в сделки.

В общем там такой себе граальчик своего рода, если правильно обработать и посмотреть на данные ) Под верным углом, так сказать :)
avatar

Vitaliy

Vitaliy, :) Я только начинаю с этим разбираться, так что у меня все еще впереди. Надо будет почитать ваши посты.
avatar

Виталий

Виталий, там ничего ценного особо, кроме показанных для примера точек входа. Когда изобрел сие чудо с доработками своими не мог поверить своему счастью и боялся торговать сигналы эти, потом чинил это все в голове и потихоньку уверовал в систему. Системность наше все :)
avatar

Vitaliy

Vitaliy, какая доходность у граальчика?
avatar

bohemian rhapsody

Не помню, есть ли у самодельных таблиц экспорт по DDE. Такие данные, по идее, нужно в Excel VBA обрабатывать, и уже выводить там в таблицы в обработанной форме.
Делаю так, но не с Quik.
avatar

3Qu

3Qu, Можно паралельно с выводом в таблицу еще писать в текстовый файл, а потом этот файл обрабатывать в другой программе.
avatar

Виталий

Виталий, да, вариант, только это надо делать в потоке main(). В Lua для этого есть средства. См. потоки (нити) Lua.
avatar

3Qu

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

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

Vitaliy

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

3Qu, Я понял, что мы подписываемся на получение данных заданного инструмента и когда происходит изменение свечи выполняем какие то действие. Только не понял, что за объект или структура CCS. Она пишет данные в БД? Пока не знаю как с помощью GetCandle() получить данные о том какое действие вызвало изменение свечи. Покупка или продажа и какой был объем.
avatar

Виталий

CCS. func_name() — это вызовы функций DLL, которая все пишет в базу данных и обрабатывает данные.
avatar

3Qu

3Qu, Получается это какая то ваша собственная разработка реализованная в виде DLL. Я пока в это не лезу, мне бы со встроенными функциями разобраться для начала.
avatar

Виталий

Виталий, имхо, и напрасно.
Если почитать Р.Иерузалимски, то Lua не самостоятельный язык, а язык расширяемый и расширяющий. Т.е., он изначально разрабатывался не для самостоятельного применения, а для взаимодействия с другими программами.
В общем, я этой концепции и придерживаюсь, Луа обеспечивает только передачу данных в ПО и взаимодействие ПО с терминалом. Вся обработка на стороне, в нормальных средах программирования с большими возможностями.
avatar

3Qu

3Qu, Саму книгу не читал, но видел инфу в интернет, о том что lua лучше использовать совместно со сторонними DLL, это вроде как снижает нагрузку на терминал и дает больше простора для творчества. У меня тут вопрос возник, если не сложно подскажите как мне средствами lua получить вот такую информацию о инструменте.



avatar

Виталий

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

Виталий


....все тэги
2010-2020
UPDONW