Избранное трейдера Ray Intraday

по

QLua: таблица крупных "склеенных" обезличенных сделок

    • 03 апреля 2020, 15:06
    • |
    • _sk_
  • Еще
Иногда хочется наблюдать за ситуациями, когда участники торгов исполняют по рынку крупные заявки. Конечно, можно смотреть на обычную ленту обезличенных сделок с настроенными фильтрами на размер сделки, но ведь можно написать специальный QLua-скрипт, который будет отбирать сделки, являющиеся результатом исполнения.

В терминале QUIK ордерлог недоступен, поэтому надо как-то эвристическим образом определить, что набор обезличенных сделок относится к одной и той же рыночной заявке. Например, можно проверять, что инструмент в текущей сделке совпадает с инструментом в предыдущей сделке, направление сделки то же самое, время сделки совпадает с точностью до миллисекунд, и цена при покупке растёт, а при продаже — падает.

Если суммарный объём не менее какой-то границы, которую можно задать для каждого инструмента индивидуально, такие «склеенные» сделки выводятся в таблице. В ней указаны:
— суммарный объём;
— количество обезличенных сделок, которые были склеены;
— начальная цена и конечная цена;

( Читать дальше )
  • обсудить на форуме:
  • Quik Lua

Скрипт lua Баланс покупок/продаж

Всем привет. Переделал первоначальную версию скрипта. Исправил некоторые ошибки и немного расширил функционал. Теперь скрипт может сохранять данные в текстовый файл, который потом можно анализировать в другой программе (например exсel). Также, в отличии от первого варианта, скрипт показывает в таблице усредненную цену, по которой прошли сделки. В первом варианте отображалась цена последней сделки. И в скрипте добавлен показ накопленной дельты за все время пока скрипт работает.

TICER = "SBER";
CLASS_CODE = "TQBR";
FilePath = getScriptPath() .. "\\export.txt";--путь к файлу
save = false;--сохранять данные в файл если false нет, true да

f = nil;
stopped = false;
t_id = nil
H = -1;
M = -1;
VSELL = 0;
VBUY  = 0;
CDelta = 0;
CountTrans = 0;
PriceTrans = 0.0; 
t = "";
function OnInit()
    CountTrans = 0;
        if save then f = io.open(FilePath,"w"); end
        CreateTable();
end 

function main() 
        while not stopped do 
          if IsWindowClosed(t_id) then
         stopped = true;
      end       
          sleep(10);
        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, 10);
   AddColumn(t_id, 2, "SELL", true, QTABLE_INT_TYPE, 10);
   AddColumn(t_id, 3, "Дельта V", true, QTABLE_INT_TYPE, 10);   
   AddColumn(t_id, 4, "AVG Цена", true, QTABLE_DOUBLE_TYPE, 15);
   AddColumn(t_id, 5, "Накопленная Дельта", true, QTABLE_INT_TYPE, 15);
   AddColumn(t_id, 6, "Кол-во сделок", true, QTABLE_DOUBLE_TYPE, 12);   
   tab = CreateWindow(t_id);
   local NAME = tostring(getParamEx(CLASS_CODE,TICER,"LONGNAME").param_image);
   SetWindowCaption(t_id, TICER.." ("..NAME..") Баланс покупок/продаж");
   SetTableNotificationCallback(t_id, EventCallBack);
end

function Calc(alltrade)
        if bit.test(alltrade.flags, 0) then VSELL = VSELL+alltrade.qty;  --Продажа
        else VBUY  = VBUY+alltrade.qty;  end                            
        CountTrans = CountTrans+1;
        PriceTrans = PriceTrans+alltrade.price;                 
end

function OnAllTrade(alltrade)    
        if alltrade.sec_code == TICER then      
                local Rows, Col = GetTableSize(t_id);
                
                if H==-1 or H~= alltrade.datetime.hour then 
                        H = alltrade.datetime.hour;
                        M = alltrade.datetime.min;
                        t = tostring(alltrade.datetime.hour)..":"..tostring(alltrade.datetime.min);
                end
                if M==alltrade.datetime.min then
                        Calc(alltrade);
                else                                    
                M=alltrade.datetime.min;        
                        InsertRow(t_id, -1);                                               
                        local Delta = VBUY-VSELL;
                        Price = PriceTrans/CountTrans;
                        SetCell(t_id, Rows, 6, tostring(CountTrans));                   
                        SetCell(t_id, Rows, 0, t);
                        SetCell(t_id, Rows, 1, tostring(VBUY));
                        SetCell(t_id, Rows, 2, tostring(VSELL));                           
                        SetCell(t_id, Rows, 3, tostring(Delta));
                        local SEC_SCALE = tostring(getParamEx(CLASS_CODE,TICER,"SEC_SCALE").param_value);
                        SEC_SCALE = string.format("%.0f",SEC_SCALE);                    
                        SetCell(t_id, Rows, 4, string.format("%."..SEC_SCALE.."f", tostring(Price)));
                   if Rows>=2 then
                           local OldPrice = tonumber(GetCell(t_id,Rows-1,4).image);
                           if OldPrice>Price then 
                                        Red(Rows,4); 
                           else 
                                        Green(Rows,4);
                           end
                           CDelta = tonumber(GetCell(t_id,Rows-1,5).image);
                           CDelta = CDelta + Delta;                        
                        else 
                          CDelta = Delta;
                        end
                        SetCell(t_id, Rows, 5, tostring(CDelta));
                    if Delta<0 then Red(Rows,3); end
                    if Delta>0 then Green(Rows,3); end
                    if CDelta<0 then Red(Rows,5); end
                    if CDelta>0 then Green(Rows,5); end                                                   
                   if save then
                                local Str = tostring(H)..";"..tostring(M)..";"..tostring(VBUY)..";"..tostring(VSELL)..";"
                                                ..tostring(Delta)..";"..tostring(Price)..";"..tostring(CDelta);
                           Str=Str.."\n";
                           SaveFile(Str);
                        end
                t = tostring(alltrade.datetime.hour)..":"..tostring(alltrade.datetime.min);                        
                    VBUY = 0;VSELL = 0;
                        PriceTrans = 0;
                        CountTrans = 0;
                        Calc(alltrade);
                end
        end --if alltrade.sec_code == TICER then        
end

function SaveFile(Str)
        if f ~= nil then 
                f:write(Str);           
                f:flush();                               
        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 f ~= nil then f:close(); end
  if t_id ~= nil then
    DestroyTable (t_id);
  end;
  stopped = true;
end




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

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

( Читать дальше )
  • обсудить на форуме:
  • QUIK

Сливают 95% или 99,5%?

Частенько нам пытаются внушить, что только 95% трейдеров сливают (т.е. 5% — постоянно в прибыле). Точных данных о сливших на Московской бирже или брокерах днем с огнем не найдешь. Но известны исследования по дэй-трейдингу по Тайваню: постоянную прибыль имеют 0.3%, и по Бразилии — 0.7% (MadQuant: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3423101).

Если бы действительно 5% были постоянно в прибыле, то на СЛ от их топиков было бы не продохнуть: такова натура человека – желание похвастать. Однако на самом деле это максимум человек 100 (с большим-большим запасом).

Попробуем посчитать, исходя из 5%. Пусть на биржу приходит новых ежегодно 10000 трейдеров. 5% — это 500 человек. За десять лет — это 5000 успешных. (За 2019 год пришло активных не менее 150000, что должно дать 7500). Что-то такого количества счастливчиков на СЛ не наблюдается.


Разбор по винтикам: какую криптобиржу выбрать для торговли?

Выбор биржи


По данным Coinmarketcap, к концу 2019 года на криптовалютном рынке существует более 300 бирж и торговых площадок. Часть из них не функционируют или обанкротились во время криптозимы 2018 года. Условия торговли на биржах значительно отличаются. Чтобы разобраться в условиях работы на торговых площадках, мы сравним четыре популярных биржи: Binance, BitMEX, Currency.com, PrimeXBT. Данные площадки чаще всего выбирают профессиональные трейдеры и инвесторы за широкий выбор активов и мягкие торговые условия.

Binance

Binance – одна из крупнейших по объему торгов и популярности криптовалютная биржа, запущенная в 2017 году. Преимущество биржи – это более 500 торговых пар, которые состоят в основном из криптовалют и токенов. К сожалению, многие из криптоактивов неликвидны и периодически попадают под процедуру делистинга.

Разнообразие цифровых активов дает возможность развиваться блокчейн-проектам, которые используют для внутренних расчетов токены. В то же время, все альткоины и токены зависимы от курса биткоина. Если падает или растет главная криптовалюта, за ней следует весь рынок, это не оставляет возможностей для маневра трейдерам и инвесторам. Они не могут ни хеджировать риски, ни диверсифицировать портфель.



( Читать дальше )

Импорт значений дневных свечей из QUIK

qpile скрипт, создающий таблицу значений дневных свечей, для создания таблицы должен быть открыт соответствующий график, код скрипта в конце.
Порядок действий:
1) Создаём текстовый документ, меняем его расширение с txt на qpl
2) Открываем документ при помощи блокнота и копируем в него код скрипта
3) На 9 строке ставим в кавычках код класса, на 10й вставляем код инструмента, на 11 строке устанавливаем количество импортируемых свечей (в теории можно импортировать 3000, однако обычно выходит меньше)
4) сохраняем файл
5) В добавляем скрипт в QUIK: В верхнем меню, вкладка сервисы -> QPILE скрипты -> Добавить (находим и выбираем файл со скриптом) -> Загрузить локально (и закрываем верхнее окно) -> В окне «работа со скриптами» жмём создать таблицу -> Добавляем все параметры и жмём «Да»
6) Кликаем на открывшуюся таблицу правой кнопкой мыши, и жмём на вывод через DDE сервер, в открывшемся окне выбираем книгу эксель, лист и жмём «Начать вывод»
В качестве примера введены код класса и инструмента для валютной пары USD/RUB с поставкой на завтра. 

( Читать дальше )
  • обсудить на форуме:
  • QUIK

Метод торговли Market Profle (Профиль рынка)


Кто торгует/пробовал?

Как успехи?

Просто знакомый очень хвалит одного гуру, он с 3 плечом вроде как инрадеит каждый день. Что-то типа индикатора POC VAH VAL, особые настройки (период, по вчерашнему дню, по позавчерашнему) вроде как грааль.

Но дело в том, что индрадей не мое… Я не могу торговать каждый день...

Есть смысл тратить время на изучение нового метода?
Или как обычно — обычный индикатор с вероятностью 50/50, непонятным стопом и плечом?

Типа таких картинок я вижу периодически от знакомого:
Метод торговли Market Profle (Профиль рынка)


Плюсаните до +15, давайте пообсуждаем...







БАБЛО ИЗ ВОЗДУХА или теория портфельной ребалансировки.

 

Вам говорили о том, что на рынке есть доходность «из воздуха»? Скорее всего нет, а она есть. Сейчас, как всегда, четко и без воды, откроем все «тайны», которые никакие не тайны. Просто люди в индустрии хотят, чтобы вам казалось, что все это сложно и без них вам ну никак не обойтись. В реальности портфельных инвестиций, как правило, все сильно проще.

БАБЛО ИЗ ВОЗДУХА или теория портфельной ребалансировки.

( Читать дальше )

последняя версия индикатора vcur

последняя версия индикатора vcur

Settings={
Name="VCUR",
period=50,
periodma=15,
weighted=1,
weightedma=1,
proportional=1,
    line=                                     
                {                               
                    {  
                        Name = "cur1",
                        Type =TYPE_LINE,
                        Width = 1,
                        Color = RGB(155,0, 0)
                    },	
                    {  
                        Name = "cur2",
                        Type =TYPE_LINE,
                        Width = 1,
                        Color = RGB(0,0,155)
                    },						
                    {  
                        Name = "cur3",
                        Type =TYPE_LINE,
                        Width = 1,
                        Color = RGB(0,0, 0)
                    }					
                }
}
--[[

-- кривая объемов
описание свойств:

period: сколько баров берутся в подсчет
weighted: =0 - обычная, =1 - взвешанная
proportional: =1- считается: volume*(close-open)/(hight-low), =0 - считается: volume*sign(close-open)

--]]

function Init()
    
  mas={}	
  return 2
  
end

function OnCalculate(index)
  	
	sumv = 0
	
	wsum = 0
	if index >= Settings.period then 
	  for i=index-Settings.period+1, index do    
        if sumv == nil then
	      sumv = 0
        end	  
	    if C(i-1) ~= nil then
		  wsum = wsum + i-(index-Settings.period)
	      if C(i-1) > O(i-1) then
		    if Settings.proportional == 0 then
		      prop = 1
			else
			  if (H(i-1)-L(i-1)) == 0 then
			    prop = 0
			  else
			    prop = (C(i-1)-O(i-1))/(H(i-1)-L(i-1))
			  end
			end
		    if Settings.weighted == 0 then
              sumv = sumv + prop*V(i-1)
			else
			  sumv = sumv + prop*V(i-1)*(i-(index-Settings.period))--/Settings.period
			end
	      else
            if Settings.proportional == 0 then
		      prop = 1
			else
              if (H(i-1)-L(i-1)) == 0 then
			    prop = 0
			  else			
			    prop = (O(i-1)-C(i-1))/(H(i-1)-L(i-1))
			  end
			end	  
		    if Settings.weighted == 0 then
              sumv = sumv - prop*V(i-1)
			else
			  sumv = sumv - prop*V(i-1)*(i-(index-Settings.period))--/Settings.period
			end
	      end
        end 
	  end 
	else
	  sumv = nil
	end	
	if Settings.weighted ~= 0 then
      if sumv ~= nil then
	    sum =sumv/wsum
	  end
	end	
    mas[index]=sumv
	
	ma = 0
	wsum = 0
	if index >= Settings.periodma then 
	  for i=index-Settings.periodma+1, index do    
	    if mas[i] ~= nil then		  
		    wsum = wsum + i-(index-Settings.periodma)
		    if Settings.weightedma == 0 then
              ma = ma + mas[i]
			else
			  ma = ma + mas[i]*(i-(index-Settings.periodma))--/Settings.periodma
			end
			
		end 
	  end
	end  
	if Settings.weightedma == 0 then
	  if ma ~= nil then
	    ma = ma/Settings.periodma	
	  end
	else	
	  ma = ma/wsum	
	end
     
  return sumv, ma--, 0


end



Робот "Два Боллинджера" с исходниками

Хорош философствовать. Давайте писать более полезные посты.
Итак, робот на двух графиках Боллинджера.
Общий принцип:
1) На цену накладываются два графика Боллинджера: с периодами 20 и 120 (назовем их local и global).
2) В зависимости от параметра внутри робота, входим либо когда цена входит внутрь local-Боллинджера (ContrTrendFlag=1), либо выходит из него (ContrTrendFlag=0).
3) Дополнительный фильтр: Лонг только когда когда мы в верхней половине global-Боллинджера, шорт — если в нижней.
Данные робот берет из графиков, так что график должен быть открыт, и прописаны идентификаторы.

График с двумя Боллинджерами выглядит примерно так:

Робот "Два Боллинджера" с исходниками

Настройки на цене и индикаторах не забудьте:

Робот "Два Боллинджера" с исходниками

( Читать дальше )

....все тэги
UPDONW
Новый дизайн