4 года и 4 месяца прошло с выхода поста «Торговый робот на LUA для QUIK» (https://smart-lab.ru/blog/200767.php) про конструктор Lbot. За это время он повзрослел, лишился графического интерфейса и… превратился в младшего брата для Lbot3D. И если раньше для Lbot была пробная версия (с одним инструментом и одним лотом), то теперь, фактически, сам превратился в пробную версию для Lbot3D и, с этого дня, предоставляется в свободное пользование с полным функционалом:
Скачать Lbot180.zip можно тут: drive.google.com/open?id=1DL9jGEBm2Uhk89PcQdlK-ObaOe2zihnx
INI-файл написан для демо-QUIK на 3 инструмента — Сбербанк, Газпром и Лукойл. Стратегия на Газпроме — безиндикаторная, на Сбербанке — на скользящих средних, на Лукойле — на пересечениях MACD.
encoding = "UTF-8" FREQUENCY = 1000 account = NL0011100043, 10110 PositionSize = 300000 xy = 421, 0, 859, 118 ;------------------------------------------------------------------------------- [GAZP] Security = GAZP, QJSIM, Gazp_moex WorkSize = 3 // рабочий объем, в штуках; LossLimit = 100 // ограничение на убыток по стратегии OpenSlippage = 10 // допустимое проскальзывание на сделке, в количестве минимальных шагов цены; OpenLong = {Close, 1} < {High, 2} // цена 'close' предыдущей 'полной' свечи превысила 'high' предшествующего ей бара; OpenShort = {Close, 1} > {Low, 5-2} // цена 'close' предыдущей 'полной' свечи принизила 'low' 5-2 баров; StopLoss = 2 TakeProfit = 3, 1, 1 EOD = 18:29:00 //закрытия позиции в указанное время. autoBot = Y [SBER] Security = SBER, QJSIM, Sber_moex WorkSize = 10 LossLimit = 100 OpenSlippage = 10 OpenLong = {Ema1} > {Ema2} CloseLong = {Ema1} < {Ema2} OpenShort = {Ema1} < {Ema2} CloseShort = {Ema1} > {Ema2} autoBot = Y [LKOH] WorkSize = 2 Security = LKOH, QJSIM, Lkoh_moex LossLimit = 225 OpenSlippage = 10 OpenLong = cross(macd_Lkoh.0, macd_Lkoh.1) OpenShort = cross(macd_Lkoh.1, macd_Lkoh.0) ;OpenLong = {Close, 1} < {Low, 5-2} ;OpenShort = {Close, 1} > {High, 2} StopLoss = 30 TakeProfit = 50, 10, 10 autoBot = Y
Программирование на языке Lua
Автор:Роберту Иерузалимски
Чистый код: создание, анализ и рефакторинг
Автор:Роберт Мартин
В своей торговле применяю комбинации рыночных и лимитированных заявок, (методику описывал ранее, "Настоящая торговая стратегия." и "US500: Объемы больше, спреды уже!" ). Временами количество одновременно работающих стратегий зашкаливало за сотню и на некоторые из них не хватало денег под выставление заявок, они отключались, иногда ломая логику работы связанных с ней стратегий. В QUIK в таблице «Состояние счета» считается цифра — «Свободно» — свободные средства под заявки, но сходу вытащить ее из Lua у меня не получилось. И пришлось вписать расчет этой величины в робота.
Сегодня предлагаю вашему вниманию доработанный скрипт Fn044.lua (https://yadi.sk/d/O-6JzZdXkOxyow)
в котором реализован расчет свободных средств для заявок на ФОРТС с учетом имеющихся контрактов и заявок.
Один в один вывести не получилось, как смог.
As is, и все такое!
-- fn044set.lua расчет стоимости фьючерсных контрактов в портфеле относительно депозита -- © smart-lab.ru/profile/xxm 08.10.2018 -- торговый счет (из таблицы «Позиции по клиентским счетам (фьючерсы)») account = 'SPBFUT0003f' --положение окна с таблицей. Левый верхний угол в координаты left,top и размеры в width и height. xy = {} xy.left, xy.top, xy.width,xy.height = 0, 232, 722, nil --ширина столбцов таблицы t_width = {12, 6, 10, 8, 10, 10, 9, 7, 6, 11, 10, 11} -- месяц и год исполнения, 2 символа, https://www.moex.com/s205 MonthYear = "Z8" -- код базового актива, 2 символа -- если 4 символа, то переменная "MonthYear" не учитывается SecCodes={ {"MM"}, --контракт на индекс МосБиржи {"Si"}, --руб/доллар FORTS {"SR"}, --Sber FORTS {"LK"}, --контракт на Лукойл {"GZ"}, --контракт на Газпром {"BRX8"}, --контракт на нефть Брент, месяц и год - "X8" {"ED"}, --контракт на ED {"RN"}, --контракт на Роснефть {"GD"}, -- Gold } --Если xy.height == nil, то вычислить ее. --Для разных мониторов коэффициенты (17, 45 и 868 - подобраны эмпирически) будут разными. local height = xy.height or ((#SecCodes + 1)*17 + 45) if height > 868 then height = 868 end xy.height = height
local w32 = require("w32") function FindLoginWindow() hLoginWnd = w32.FindWindow("", "Установка сетевого соединения") if hLoginWnd == 0 then hLoginWnd = w32.FindWindow("", "Network connection setting") end return hLoginWnd end timeout = 1000 -- таймаут между попытками поиска окна логина is_run = true function OnStop() timeout = 1 is_run = false end function main() while is_run do sleep(timeout) if isConnected() == 0 then local hLoginWnd = FindLoginWindow() if hLoginWnd ~= 0 then local nBtnOk = w32.FindWindowEx(hLoginWnd, 0, "Button", "&Ввод") if nBtnOk == 0 then nBtnOk = w32.FindWindowEx(hLoginWnd, 0, "Button", "&Enter") end w32.SetFocus(nBtnOk) w32.PostMessage(nBtnOk, w32.BM_CLICK, 0, 0) while not isConnected() do sleep(1000); end; end end end end
Settings =
{Name = «Fracta_l»,
period=31,
line =
{{
Name = «Level_High»,
Color = RGB(0,255,0),
Type = TYPE_POINT,
Width = 1
},{
Name = «Level_Low»,
Color = RGB(255,0,0),
Type = TYPE_POINT,
Width = 1
}}}
idx_prosl=0
function Init()
return #Settings.line
end
function OnCalculate(idx)
if idx==1 then
P = math.floor(Settings.period/2)*2+1
t_H,t_L={},{}
end
if idx~=nil and idx>P then
if idx_prosl~=idx then
local l=idx-P
for l=l,idx-1 do
t_H[l]=H(l)
t_L[l]=L(l)
end
if t_H[#t_H-(P-1)/2]==math.max(unpack(t_H,#t_H-P+1,#t_H)) then
H_ind_value=t_H[#t_H-(P-1)/2]
end
if t_L[#t_L-(P-1)/2]==math.min(unpack(t_L,#t_L-P+1,#t_L)) then
L_ind_value=t_L[#t_L-(P-1)/2]
end
end
else
H_ind_value=nil
L_ind_value=nil
end
idx_prosl=idx
return H_ind_value, L_ind_value
end