А что случилось со статистикой на форуме? Строка "Сейчас на форуме" вообще пустая , если раньше чуть-чуть приписывала то нынче вообще ничего не отражает. Таланты!
Вернулся к проекту - "суперкар", (Фреймворк HackTrade 1.4 для написания торговых роботов от https://github.com/DenisKolodin.)
Изменения, на что следует обратить внимание: Фреймворк написан на lua 5.1, модуль qlua 5.4.1; Поправим на соответствие. изменений не много.
Но выявилась и концептуальная ошибка, ну скорее недочет. Так как HackTrade продолжает летать со скоростями в один тик, то и проект смело можно назвать "ракета".
Текущая реализация концептуально выглядит так, код:
Код
dofile("hacktrade.lua") -- основной модуль
function Robot() -- основной функции
-- 1) (~) Инициализация
2) Получение констант
3) Предварительные расчеты
while working do -- основной цикл
for i=1,#sec do ---- цикла по бумагам:
-- Система нескольких окон
for j=1,#tf do ---- цикла по таймфремам
F[i][j]() --парад стратегий
end
signal[i] -- Вырабатываем сигнал на сделку
rm[i] -- определение риска на сделку
mm[i] -- расчет колличества на сделку
p[i] -- получаем цену на сделку
SmartOrder[i]( p[i], q[i] ) -- формируем ордер на сделку
end
Trade() -- Вызова функции Trade, для осуществления торговых действий
pos[i] -- получаем позицию по инструменту
sleep(950) -- тормозим чтоб в ближним космосе очутиться!
end
--Сохраняем
--Закрываем
end
Вопрос с модульностью решен, пишем свои стратегии входа, стратегии выхода, управление позицией, риском, алгоритмы - все независимо! Собираем Систему (торговую!)
Чего не хватает так это тестера, но об этом отдельно.
Ну и конечно, скажем дружно, огромное, человеческое спасибо автору! (Фреймворк HackTrade 1.4 для написания торговых роботов от https://github.com/DenisKolodin.)
Судить о луа я конечно не могу, я им просто пользуюсь, таким какой он есть, и прислушиваюсь к автору и другим советам, в том числе с форума к тем кто лучше меня разбирается.
Вот например пишет автор:
"Lua предлагает как раз то, для чего С недостаточно хорош: высокая степень независимости от аппаратного обеспечения, динамические структуры, отсутствие избыточности и легкость тестирования и отладки".
"многие алгоритмы с использованием таблиц становятся до банальности простыми. Например, мы редко пишем алгоритм поиска в Lua, поскольку таблицы предоставляют прямой доступ к любому типу.
Таблица в Lua — это объект во многих отношениях. Подобно объектам, у таблиц есть состояние. Подобно объектам, у таблиц есть идентичность (собственное «я» — self), которая не зависит от ее значений; Подобно объектам, у таблиц есть жизненный цикл У объектов есть свои собственные действия. У таблиц также могут быть действия..."
И я не понимаю почему этим не пользоваться в полной мере, да мета таблицы здесь самое сложное, но то что получаешь на выходе стоит, того чтоб сними один раз разобраться.
Проблемы с терминалом описанные здесь возникли при переводе скриптов на 5.4 (с 5.1 на 5.3 получилось с минимальными затратами по времени), здесь так не получилось, пришлось разбираться. Оказалось скрипты которые годами работали "запустил и забыл" (ну к примеру скрип сохранения сделок) нужно проверять на соответствие с 5.4.
Я уже здесь писал, что к программированию имею отношение только в части данного проекта (хобби). Мои отношения с луа: читаю автора; ищу примеры; встраиваю в свои алгоритмы; думал что можно добавить обсуждение на форуме.
Я не обсуждаю на форуме личные качества участников, я лишь высказываю собственное мнение, в силу собственного понимания, о предмете обсуждения. Уровни в программировании я тоже не обсуждаю, я в этом ни чего не понимаю, я даже не понимаю то что Вы написали, чем Вы занимаетесь на луа.
Я обсуждаю конкретный проект, "программирование на луа" для целей автоматизации процесса торговли на бирже, который не заканчивается программированием! И рад единомышленникам или объективной здоровой критике!
Уважаемый nikolz, Вы видимо имеете отношение к программированию, но не знакомы с надежностью (Есть такая теория). Не нужно валить все в одну кучу. Обо всем и по порядку.
Цитата
nikolz написал: Терминал сделали, чтобы Вы могли подавать заявки брокеру руками. И эту функцию он реализует прекрасно.
Именно об этом мое самое первое сообщение на этом форуме. Сломали что работало лет 20. и не могут исправить. Ломать не строить
Цитата
nikolz написал: Так как терминал посылает сообщения на сервер и Вы в скрипте формируете эти сообщения, то Вы можете даже организовать DDOS атаку даже из своего скрипта.
Это вообще шедевр таланты. Сообщению чтоб попасть на сервер, нужно отвечать определённым требованиям, посланное хоть руками хоть еще чем. Атаку в подобной реализации вообще не вопрос, достаточно ошибиться в количестве. Но это к вопросу надежности. Версии лепятся не понятно зачем, а где надежность?
Цитата
nikolz написал: А уж завалить терминал это Вы можете как два пальца...
Цитата
про это уже писал: VPM написал: Кто виноват? и Что делать? Вот вопрос.Терминал устанавливают для возможности торговать (в не зависимости от его версии).Пользовательские скрипты используют для автоматизации этого процесса (в не зависимости от языка и версии).И это не сколько не отменяет тот факт, что пользовательский скрип не должен убивать терминал и тем более влиять на работу сервера ,кем бы и как не был написан.
nikolz написал: Вы как и многие "профи" на этом форуме постоянно ругаете КВИК , а когда понимаете, что это вы на...ли г-но, скромно молчите.
Цитата
nikolz написал: Увы, LUA дает доступ во внутрь терминала. Поэтому защиту от дурака здесь установить невозможно.
Квик я люблю, а не ругаю (разве немного таланты), мои сообщения о недочетах замеченных, надеюсь это помогает (так называема обратная связь), это одна из задач данного форума.
"защиту от дурака" должна быть установлена! Скрипты писал и буду писать. К профи не отношусь, здесь их на пальцах одной руки. Да и луа мало кто понимает: "Таблицы в Lua — это не одна из структур данных, — это единственная структура данных."
Терминал устанавливают для возможности торговать (в не зависимости от его версии). Пользовательские скрипты используют для автоматизации этого процесса (в не зависимости от языка и версии). И это не сколько не отменяет тот факт, что пользовательский скрип не должен убивать терминал и тем более влиять на работу сервера , кем бы и как не был написан.
Дошли руки восстановил работу квик обновился до версии 10.3.и опять в боевом строю! Вероятно причиной задержки, при получении ответа терминалом от сервера, являлись скрипты луа при переходе на версию 5.4. Хотя снес почти все лишнее. Все скрипты нужно проверять на соответсвие с 5.4.
Andrey Golik написал: Уточните, пожалуйста, после какого обновления столкнулись с данной проблемой (на какую версию)?
Откатил назад с версии 10.3 на 10.1.2.2 удалил самописные индикаторы из папки, проверил получение данных(обезличенные сделки и 4 класса), задержка на рынке акций, при вводе в окно ввода заявки, пишет "ожидании ответа сервера" и так до нескольких минут. После отката чуть улучшилось по времени но все равно работает не нормально.
Цитата
Andrey Golik написал: После выставления заявки терминал "зависает", то есть становятся недоступны никакие действия с программой?
Нет во время выставления, после исполнения идет очень медленное обновление таблиц о сделке до нескольких минут. Графики тоже тормозят. (~ 20шт) Обращался к брокеру не помогли. Брокер "АТОН". Терминал стоит очень давно обновляется вместе с рекомендациями брокера.
БорисД написал: В любом бизнесе учет и аналитика первостепенны и без них даже не стоит открывать бизнес или торговлю на бирже начинать.
Целиком и полностью! Вот скрип которым я пользуюсь, по принципу "запустил и забыл", за что автору скажем спасибо. Это конечно не бухгалтерия в полном виде, но вполне достаточно чтоб в екселе сделать анализ.
local Run;-- = true; -- флаг работы цикла в main
local DataFolder = ''; -- Полный путь к папке "Данные(c)quikluacsharp.ru"
local TradesFiles = {};-- Массив дескрипторов файлов
-- Функция возвращает значение бита (число 0, или 1) под номером bit (начинаются с 0) в числе flags, если такого бита нет, возвращает nil
function CheckBit(flags, bit)
-- Проверяет, что переданные аргументы являются числами
if type(flags) ~= "number" then error("Ошибка!!! Checkbit: 1-й аргумент не число!"); end;
if type(bit) ~= "number" then error("Ошибка!!! Checkbit: 2-й аргумент не число!"); end;
local RevBitsStr = ""; -- Перевернутое (задом наперед) строковое представление двоичного представления переданного десятичного числа (flags)
local Fmod = 0; -- Остаток от деления
local Go = true; -- Флаг работы цикла
while Go do
Fmod = math.fmod(flags, 2); -- Остаток от деления
flags = math.floor(flags/2); -- Оставляет для следующей итерации цикла только целую часть от деления
RevBitsStr = RevBitsStr ..tostring(Fmod); -- Добавляет справа остаток от деления
if flags == 0 then Go = false; end; -- Если был последний бит, завершает цикл
end;
-- Возвращает значение бита
local Result = RevBitsStr:sub(bit+1,bit+1);
if Result == "0" then return 0;
elseif Result == "1" then return 1;
else return nil;
end;
end;
-- Добавляет новую сделку в файл истории
function AddTradeInFile(trade)
local DateTime = trade and trade.datetime;
local Date = tonumber(DateTime.year);
local month = tostring(DateTime.month);
if #month == 1 then Date = Date.."0"..month; else Date = Date..month; end;
local day = tostring(DateTime.day);
if #day == 1 then Date = Date.."0"..day; else Date = Date..day; end;
Date = tonumber(Date);
local Time = "";
local hour = tostring(DateTime.hour);
if #hour == 1 then Time = Time.."0"..hour; else Time = Time..hour; end;
local minute = tostring(DateTime.min);
if #minute == 1 then Time = Time.."0"..minute; else Time = Time..minute; end;
local sec = tostring(DateTime.sec);
if #sec == 1 then Time = Time.."0"..sec; else Time = Time..sec; end;
Time = tonumber(Time);
-- Если ночная сделка, смещает дату на 1 день вперед
if Time < 90000 then
local seconds = os.time(DateTime);
seconds = seconds + 24*60*60;
DateTime = os.date("*t",seconds);
Date = tonumber(DateTime.year);
month = tostring(DateTime.month);
if #month == 1 then Date = Date.."0"..month; else Date = Date..month; end;
day = tostring(DateTime.day);
if #day == 1 then Date = Date.."0"..day; else Date = Date..day; end;
Date = tonumber(Date);
end;
local Operation = "";
if CheckBit(trade.flags, 2) == 1 then Operation = "S"; else Operation = "B"; end;
-- Добавляет сделку в массив
local Trade = {};
Trade.Account = trade.account;
Trade.Sec_code = trade.sec_code;
Trade.Num = trade.trade_num;
Trade.Date = Date;
Trade.Time = Time;
Trade.Operation = Operation;
Trade.Qty = tonumber(trade.qty);
Trade.Price = tonumber(trade.price);
Trade.Hint = "Счет: "..tostring(Trade.Account).."_Номер: "..tostring(trade.trade_num).."_Дата: ";
if #day == 1 then Trade.Hint = Trade.Hint.."0"..day.."/"; else Trade.Hint = Trade.Hint..day.."/"; end;
if #month == 1 then Trade.Hint = Trade.Hint.."0"..month.."/"..DateTime.year; else Trade.Hint = Trade.Hint..month.."/"..DateTime.year; end;
if #hour == 1 then Trade.Hint = Trade.Hint.."_Время: 0"..hour..":"; else Trade.Hint = Trade.Hint.."_Время: "..hour..":"; end;
if #minute == 1 then Trade.Hint = Trade.Hint.."0"..minute..":"; else Trade.Hint = Trade.Hint..minute..":"; end;
if #sec == 1 then Trade.Hint = Trade.Hint.."0"..sec; else Trade.Hint = Trade.Hint..sec; end;
Trade.Hint = Trade.Hint.."_Количество: "..trade.qty;
Trade.Hint = Trade.Hint.."_Цена: "..trade.price;
-- Получает путь к файлу инструмента в папке торгового счета
local PathAccountSec = DataFolder..Trade.Account..'\\'..Trade.Sec_code..'.csv';
local FileIndex = Trade.Account..'_'..Trade.Sec_code;
-- Если файл еще не открыт, или не существует
if TradesFiles[FileIndex] == nil then
-- Пытается открыть файл текущего инструмента в режиме "дописывания"
TradesFiles[FileIndex] = io.open(PathAccountSec,"a+");
-- Если файл не существует, то сделка не записана
if TradesFiles[FileIndex] == nil then
-- Создает файл в режиме "записи"
TradesFiles[FileIndex] = io.open(PathAccountSec,"w");
-- Закрывает файл
TradesFiles[FileIndex]:close();
-- Открывает уже существующий файл в режиме "дописывания"
TradesFiles[FileIndex] = io.open(PathAccountSec,"a+");
end;
end;
-- Встает в начало файла
TradesFiles[FileIndex]:seek("set",0);
-- Если файл пустой
if TradesFiles[FileIndex]:read() == nil then
-- Добавляет строку заголовков
TradesFiles[FileIndex]:write("Счет;Код бумаги;Номер сделки;Дата сделки;Время сделки;Операция;Количество;Цена;Текст подсказки", "\n");
end;
-- Встает в конец файла
TradesFiles[FileIndex]:seek("end",0);
-- Записывает сделку в файл
TradesFiles[FileIndex]:write(Trade.Account..";"..Trade.Sec_code..";"..Trade.Num..";"..Trade.Date..";"..Trade.Time..";"..Trade.Operation..";"..Trade.Qty..";"..Trade.Price..";"..Trade.Hint, "\n");
TradesFiles[FileIndex]:flush();
end;
-- Создает каталоги по всем найденным счетам
function CreateAccountsFolders()
-- Перебирает все счета
for i=0, getNumberOf("trade_accounts")-1 do
-- Получает номер счета
local Account = getItem("trade_accounts", i).trdaccid;
message('Account = '..Account)
-- Получает путь
local Path = '"'..DataFolder..Account..'\\"';
-- Если каталог не существует
---- можно получить доступ к выхлопу команды, взяв result
--[[local handle = io.popen('cd '..Path)
local result = handle:read("*a")
handle:close()
message('result = '..tostring(result))
--]]
--message(' os.execute(cdPath) = '..os.execute('cd '..Path))
if os.execute('cd '..Path) == 1 then
-- Создает каталог
os.execute('mkdir '..Path);
end;
end;
end;
-- Проверяет записана ли данная сделка в файл истории
function CheckTradeInFile(trade)
-- Получает путь к файлу инструмента в папке торгового счета
local PathAccountSec = DataFolder..trade.account..'\\'..trade.sec_code..'.csv';
-- Пытается открыть файл текущего инструмента в режиме "чтения"
local TradesFile = io.open(PathAccountSec,"r");
-- Если файл не существует, то сделка не записана
if TradesFile == nil then return false;
else -- Если файл существует
-- Получает индекс файла
local FileIndex = trade.account..'_'..trade.sec_code;
-- Если файл еще не открыт для дописывания
if TradesFiles[FileIndex] == nil then
-- Открывает файл текущего инструмента в режиме "дописывания"
TradesFiles[FileIndex] = io.open(PathAccountSec,"a+");
end;
-- Перебирает строки файла
local Count = 0; -- Счетчик строк
for line in TradesFile:lines() do
Count = Count + 1;
if Count > 1 and line ~= "" then
-- Если номера сделок совпадают, то сделка записана
local i = 0;
for str in line:gmatch("[^;^\n]+") do
i = i + 1;
if i == 3 and tonumber(str) == trade.trade_num then
TradesFile:close();
return true;
end;
end;
end;
end;
end;
TradesFile:close();
return false;
end;
-- Записывает все ранее не записанные сделки из таблицы "Сделки" в файлы
function CheckAndSaveTerminalTrades()
local trade = nil;
-- Перебирает все сделки в таблице "Сделки"
for i=0,getNumberOf("trades")-1,1 do
trade = getItem ("trades", i);
-- Если данная сделка еще не записана в файл истории
if not CheckTradeInFile(trade) then
-- Добавляет сделку в файл истории
AddTradeInFile(trade);
end;
end;
end;
---------------------------------
function OnTrade(trade)
-- Если данная сделка еще не записана в файл истории
if not CheckTradeInFile(trade) and Run then
-- Добавляет сделку в файл истории
AddTradeInFile(trade);
end;
end;
function OnStop()
-- Закрывает все файлы
for key,Handle in pairs(TradesFiles) do
if Handle ~= nil then Handle:close(); end;
end;
Run = false;
end;
--function OnInit() end;
function main()
Run = true;
-- Получает полный путь к папке "Данные(c)quikluacsharp.ru"
DataFolder = getWorkingFolder()..'\\Данные(c)quikluacsharp.ru\\';
-- Создает папки по всем найденным счетам
CreateAccountsFolders();
-- Записывает все ранее не записанные сделки из таблицы "Сделки" в файлы
CheckAndSaveTerminalTrades();
while Run do
sleep(1000);
end;
end;
Что - то с последними обновлениями все переломалось. У одного из брокеров терминал зависает на несколько минут после отдачи приказа в ожидании ответа сервера?
БорисД, Я ни кого не переубеждаю, я лишь публично высказываю свое видение на то чем мы тут занимаемся, и не претендую на истину в последний инстанции.
"не опровержимые факты" кого угодно переубедят, на то они не опровержимы. С Владимир мы не спорим, скорее дискутируем о взглядах на рынок, так как придерживаемся разных подходов в торговле, а судья здесь один торговый счет. Вот и Вы про
Цитата
БорисД написал: наблюдаем это в 10 секундном тайфрейме онлайн
Но Вы то наверняка знаете, что говоря о тайм фрейме нужно говорить о фрактальности в поведении цены, а значить поймав тенденции на 10 сек. то и горизонт планирования сделки такой же.
Nikolay написал: Да. Перебираем бары и когда надо перейти на новый индекс, вызывается функция.Также это будет работать и для текущих данных. Так что код становится однотипным.
Заманчиво попробую посмотрим что из этого получится у меня.
Nikolay написал: При этом у каждого ds в списке можно написать свой колбек на приход нового индекса. Тогда код становится еще более простой, в функциональном стиле.
Посмотрел Вашу идею более внимательно. Не понял вот здесь "написать свой колбек на приход нового индекса" Вы говорите про исторические данные?
Владимир написал: Лучше спросить: А ЗАЧЕМ она нужна?
Ну речь идет о тестировании на прошлых свечах, вот я показываю
Цитата
VPM написал: Ну к примеру, на H2,Свечи сформированы у них есть High и Low, текущая цена становится ниже Low на H2 . lact < Low это только условия для поиска ситуации на открытие Short позиции на 5 минутах.на 5 минутах свои условия на подтверждении.
Время 1000 24.08.2023г. начало теста, мне нужно найти индекс для свечей на 1 Часовом графике и на 1 минутном (для простоты рассуждения) чтоб можно было получить все остальные значения со свечи. и дальше их синхронно смещать, получая для каждого графика свой индекс. Сравнить индексы можно только установив время.
VPM написал: В своих алгоритмах я использую цены максимальную на интервале и минимальную на интервале.Я это называю так, последний покупатель и последний продавец, это чтоб не забыть смысл. На мой взгляд они наиболее информативны чем просто средние. Отражают уровни поддержки и сопротивление, тенденцию.Т.е. можно реализовать пробойные стратегии, лучше характеризуют трендовое движение.
Без разниц
Цитата
Владимир написал: 6 000 000 тиков, а на 6 000 000 секундных свечей
Цитата
Владимир написал: 6 000 000 тиков, а на 6 000 000 секундных свечей
В моем подходе все это шум. Все что ниже даже 5 минут тоже шум. Так как оценку веду от старшего таймфрейма.
Ну к примеру, на H2, Свечи сформированы у них есть High и Low, текущая цена становится ниже Low на H2 .
lact < Low это только условия для поиска ситуации на открытие Short позиции на 5 минутах. на 5 минутах свои условия на подтверждении.
Все Ваши секундные свечи уже сидят внутри 5 минутной свечи и для нее это шум.
Ну на том и порешим. Писать массив на 6 000 000 тиков по сотне бумаг не вижу смысла. Данные есть и так только их нужно получить корректно. Свой подход я тоже описал достаточно подробно буду дальше реализовывать. Ну а депозит рассудит!
Владимир написал: Там двухмесячный тиковый массив (по-моему, Борька его нашёл), 44 мега с датами сделок или 28 мегов голых секундных свечей. Торги не идут все 24 часа, и выходные имеются. Мой скрипт тыщу раз тестировался на этом массиве в разных режимах, пробегает он его секунд за 20. Если кто-то знает более оптимальный подход, то это не я.
Ну смотри те сами, пишите "тиковый массив". Давайте посмотрим что такое тик Вариант 1) ликвидный рынок есть лучшей аск 1 контракт есть лучшей бид 1 контракт с рынка продали 1 контракт. Как это повлияло на рынок? Ответ ни как (шум)! Вариант 2) неликвидный рынок та же ситуация. Может изменить баланс так как спреды огромные или никак.
Владимир написал: Я хороший алгоритмист, неплохой программист, мои способности проявлялись в самых разнообразных областях, а биржевыми погремушками я начал заниматься уже на пенсии.
Еще век назад люди торговали, рисовали графики на миллиметровке карандашами, и писали алгоритмы. Я подчеркиваю, при этом создавая личное благополучие и делясь своими знаниями.
Владимир написал: Да плевать мне на Ваше мнение. Я хороший алгоритмист, неплохой программист, мои способности проявлялись в самых разнообразных областях, а биржевыми погремушками я начал заниматься уже на пенсии. Что Вы можете знать обо мне? Да ничего!
Я Вас совсем не обидеть хотел или изучить, а лишь говорю о том чем мы с Вами здесь занимаемся и обсуждаем на этом форуме. Ни чего личного. Если я чем то обидел Вас то извините. Я лишь высказываюсь сию минутном занятии.
"биржевыми погремушками" - это огромный бизнес, как да сами убедитесь я думаю Ваш подход изменится.
А Вы с Борькой не слышали что рынок меняется? Вы рассуждаете так как рассуждают для подбора тестовых массивов нейросетей.
Ну смотрите сами ваш массив учитывает событие 02.22г. Ваш подход оценил это, дальше нестабильность рынок скачет при каждом шорохе без всяких тенденций. оценил это. Наступило затишье, и что ему делать основываясь на прошлом опыте. Вывод не торговать. Это описание ситуации происходящей на наших глазах. Я там торговал.
Я лишь рассуждаю о том чтоб, оптимизировать поведение скрипта под поведение рынка в своей торговле, оставляю режим эксперт, для переоценки изменений в поведения рынком.
VPM написал: 1минута = 60 секунд или 1440 минут в на графике Д1, считаю 6 000 000 секунд / 60 / 1440 ~= 69 дней Существования фьючерса.т.е. ваш уникальный скрипт тестируется на этом промежутке. и Вы утверждаете что это оптимальный подход?Я Вас правильно понимаю?
Владимир написал: На каком "том временном отрезке и только"? НА ЛЮБОМ отрезке ЛЮБОГО инструмента ЛЮБОГО тикового (или даже не обязательно тикового) массива. Другое дело, что у меня давно уже для тестирования используется только один массив, примерно на 6 миллионов секунд, и только потому, что там есть буквально всё: и длительное топтание на месте, и "нормальные" взлёты и падения, и спокойный долгий рост, и резкое обрушение курса почти вдвое, так что мне просто НЕЧЕГО тестировать на любых других исторических данных - в этом массиве есть буквально всё, что душе угодно. Хотя до сих пор валяется 3 гига разных исторических данных, 120 миллионов строк (чуть больше) по... ща скажу... по 309 инструментам Мосбиржи и 1454 инструментам СПб. Я тогда ещё пытался определять "характер тикера" и прочую лабуду, но быстро понял, что всё это чушь собачья, и скрипт мой прекрасно справится с любым "характером". Сейчас это всё уже мусор, "преданья старины глубокой" (2020 год, когда я только начинал), остался только один тестовый массив одного из этих инструментов, который я гонял и в режиме, как будто это акции, и как будто это фьючерсы (даже не помню, что там в оригинале было - кажется, фьючерсы). Но даже эти прогоны по историческим данным нужны были только для черновой отладки скрипта.
Nikolay, Тут дело даже не 2008 годе, я в своих стратегиях так далеко не заглядываю.
Для фьючерсов я практикую три режима в одном скрипте: 1) бэктест на несколько дней назад; 2) эксперт - т.е. в торговое время, идут торги ,но без выставления приказов в торговую систему. и фиксирую сигнал , делаю расчет показателей сделки. 3) и боевой режим.
Все это луа позволяет сделать это удобно, на мой взгляд практично, я так просто привык.
Перед торгами запустил бэктест, все устраивает, авто торговлю, нет посмотрим поведение рынка. Это просто мой подход, мне так комфортно.
В своих алгоритмах я использую цены максимальную на интервале и минимальную на интервале. Я это называю так, последний покупатель и последний продавец, это чтоб не забыть смысл. На мой взгляд они наиболее информативны чем просто средние. Отражают уровни поддержки и сопротивление, тенденцию. Т.е. можно реализовать пробойные стратегии, лучше характеризуют трендовое движение.
То что предлагаете Вы, хорошо на скальперских стратегиях. Там отставание средней не так критично как на Н1 или Д1, Да и накапливать данные, когда они уже есть?
Я использую Н1 и выше для определения текущей тенденции, целевых уровней. куда буду торговать (мат. ожидание на свою сторону). На меньших, уточняю т. входа, стоплос на сделку, т.е. то что может отменить сделку или потвердеть.
Войти можно и случайным образом. вопрос а где закрыть сделку, "чтобы не так было больно за прожитые годы"
Прислушался к советам, поднял старые наработки, сам поднапрягся, ( ну не все могут быть хирургами или хорошими адвокатами, а я не программист пишу потихоньку для себя).
Спрятать удалось пока только поиск начальной точки для входа в режим теста. Оказалось не все так прозаично, Изменили время начало торгов на секции срочного рынка, в виде добавления еще одной сессии "Аукцион открытия". Полезно делать ревизию старым скриптам! Соответственно изменилась индексация на графике в квике. Несколько удивил подход разработчиков?
Вот так теперь выглядит начало торгов на разных тайм фреймах:
Заглянул на сайт ММВБ, а у них вообще значится "Аукцион открытия" 08:50.
Про свою реализацию, сделал через замыкание. запихнув все интервалы готовые. и что б потом можно добавить свои. На вход подаем дату и время желаемого начала теста, на выходе массив необходимых индексов все банально.
да так примерно и реализовывал вот пример со старого скрипта
if newREJIM then Log:trace( ' =========================' ) Log:trace( 'REJIM: '..REJIM..'; (TEST='..tostring(TEST)..'; AVTO='..tostring(AVTO)..'; EXPERT='..tostring(EXPERT)..')');--..tostring(a) Log:trace( ' =========================' )
if TEST then--REJIM==' Log:trace( 'REJIM: '..REJIM..'; Синхронизация');
---- local i,d,t,hour='0','0',0; ---- Дневной do local countD=getNumCandles(tag[4]); countD = countD - test.count_day; local bar = getCandlesByIndex(tag[4],0,countD-1,1) local td = bar[0] and bar[0].datetime or nil; if td then d=get_date(td); t=get_time(td); end; Index[4]=countD; dd=d; Log:info('Синхронизация Дня: '..d..'=='..dd..'; Index[4]='..Index[4] ); end ---- Часовой - средне срочный для установления тренда на день. local countH=getNumCandles(tag[3]); for i=countH,1,-1 do local bar = getCandlesByIndex(tag[3],0,i-1,1)[0] local td = bar and bar.datetime or nil;
и так далее ...
В начале этот код и хотел перетащить и вставить в новый скрипт. Там я проходил по 4 тайм фреймам , но какое то нагромождение, в общем ревизию не прошел.
Вот я и подумал возможно есть наработки более удобные, ну к примеру двигать через интервалы ведь известно же INTERVAL_D1 == 1440 минут INTERVAL_H1 == 60 минут или через метку там время возвращается.
из Руководство пользователя QLua Версия 10.3: Свечки графика. Описание параметров свечки графика:
Параметр Тип Описание open NUMBER Цена открытия close NUMBER Цена закрытия high NUMBER Максимальная цена сделки low NUMBER Минимальная цена сделки volume NUMBER Объем последней сделки datetime TABLE Формат даты и времени doesExist NUMBER Признак расчета индикатора при наличии свечки. Возможные значения: «0» – индикатор не рассчитан; «1» – индикатор рассчитан
Вопрос, а где тут индекс? Ну зато появляется массив - datetime TABLE Формат даты и времени.
Вот она наконец удача, знаем дату, знаем время (до миллисекунд) можно вернуть интересующею нас нас цену на конкретном баре!
Backtesting - проверка торговых стратегий на исторических (прошлых) данных.
Задача сводится к определению параметров устойчивости стратеги, на разных инструментах, при разных рыночных условиях. И предположению, что будет какое то время, оставаться такой же надежной и в будущем.
Казалось бы, простая реализация задачи сводится: загрузил данные, в цикле прокатился по ним с выполнением правил торговой стратегии. Сохранил результаты сделок, расчитал показатели данной стратегии. Сравнил. При необходимости оптимизировал.
Но каждый раз при реализации задачи на тыкаюсь на одну и туже проблему. Это синхронизация графиков разных таймфремов (система нескольких окон)!
Ну это когда младший график двигается в промежуток времени старшего таймфрема и совместно сдвигаются.
Каждый раз "леплю очередной огород". Возможно есть готовое решение, или идеи по реализации в виде модуля?