local FreeMoney = cur_cost() -- Возвращает доступные средства local E = FreeMoney*fraction; -- fraction - разрешение на использование средств (доля) local RiskDay = round(E*RiskDay*0.01,2); -- Задаем риск на торговый день
E = round(E-RiskDay,2); -- я его сразу вычитаю так как торговать будет на всю "котлету"
--local WorkCapital = E/#sec; -- "каждому по заслугам"
Уперся в другую проблему. Сколько открывать SmartOrder? Которая на прямую упираемся "что делать с открытыми позициями во время пере запусков" и как их согласовывать с SmartOrder? Не понятно? Дело в том что замучили детские ошибки (невнимательность + тестовый режим), а может дело в местных флюидах Ну в любом случае позицию жалко ликвидировать все встает по тренду, а когда все на глазах увеличивается тут "жаба душит".
Проскочить не получилось. Эксперимент затягивается "жаба" + нерешённая проблема это надолго.
А тем временем, получив сигналы от нашей стратегии, подошли в плотную к вопросам Мани Менеджмента. Распределению весов в портфеле и количеству контрактов на сделку.
Владимир написал: Нет за мной никакого "конечного решения". Я обычно вообще не знаю, как он торгует, а иногда даже чем он торгует. И торгует он куда более "рентабельно", чем я сам.
Включить выключить когда вкл. это конечные решения. Суть не в этом, то как на писали так и торгует все решения были за Вами, исполнение за скриптом.
Владимир написал: Какая, в задницу, "чёткая логика"? Побитовые операции, хоть и называются "логическими", никакого отношения к логике не имеют.
bit -0; 1; да или нет;
Цитата
Владимир написал: А сленгом обычно пользуются дилетанты, которые пытаются изображать из себя профессионалов
Любая дисциплина профессия в сленге, не смотря на то что называют профессиональным языком (химия, физика,......)
Цитата
Владимир написал: В профессиональной среде сленг неустойчив и частенько привязан к конкретной задаче.
Только сленг, послушайте академика обязательно будет сленг даже при обсуждении фундаментальных Вопросов.
Профессиональная среда это шахтеры, металлурги, транспорт и т.д. Торгаши как без них, а то о чем Вы, прикладное к данным профессиям: облегчить, упростить, автоматизировать и т.д.
Владимир написал: Лично я учиться быть трейдером не хочу и, соответственно, торгую не я.
А это просто иллюзия! Торгуете Вы и конечное решение за Вами. А для того чтоб торговал Ваш скрипт рентабельно, не достаточно знаний побитовых операций, нужно еще кое что знать и применять
Владимир написал: Если Вы не "писатель", то и велосипед не Вам конструировать - нужно брать готовый.
По Вашей логике, если Вы не инвестор (трейдер) то и торговать не Вам.
Главная задача ради которой здесь - это автоматизации торговли. Торговать!
Если Вы, собираете велосипед, то вам не нужны отдельно спицы, достаточно целого колеса, а уж куда его прикрутить, какое колесо, это решения конструктора!
Тяжело с Вами программистами, все "с ног на голову" поставите
Владимир написал: Если Вы не знаете побитовые операции, то Вам просто нечего делать в программировании
Так и я же об этом, я не "писатель" я "конструктор", конструирую свой маленький велосипед для автоматизации торговли средствами QUIK!
Цитата
Владимир написал: а тут несколько страниц обсуждается несчастный AND
Обсуждаем как его прикрутить к buy = line1 > line2 sell = line1 < line2 Вот ребята и объясняют одному неучу!
Цитата
Владимир написал: А мы с Борькой когда-то хотели обсудить и реализовать идеальный интерфейс для программиста, отлаженный в боевых условиях и нечувствительный ко всем существующим глюкам. Это вряд ли больше десятка функций, на отлладку которых и гробится 99% времени программистов и которым посвящены чуть ли не все здешние ветки
Хотеть и делать чуть разные вещи. А так одни лозунги. "Экономика должна быть экономной"
БорисД написал: Я дважды предлагал совместно обсудить "технические" утилиты, вплоть до открытых кодов - один раз сам, другой вместе с Борисом.
Вопрос на мой взгляд не в технических утилитах, их достаточно опубликовано (большая библиотека Универа, здесь публикуются, даются ссылки, да и свои накапливаются).
Ну к примеру если Вы не писатель, а конструктор и собираете свой еще трехколесный велосипед, то зачем знать побитовые операции? Хорошо здешние пользователи "разжёвывают" что за чем, за что им отдельное спасибо.
Все что нужно начинающему конструктору уметь делать "без ковыряния в носу":
Ziveleos написал: По моему, определять лучше сразу оба бита.Если bit.band(order.flags,3) или order.flags & 3 равно 3, то заявка снята, равно 2 - исполнена, 1 - активна.
Кое что нашел:
true - флаг установлен
false - флаг не установлен
-- Функция проверяет установлен бит, или нет (возвращает true, или false)
CheckBit = function(flags, _bit)
-- Проверяет, что переданные аргументы являются числами
if type(flags) ~= "number" then error("Ошибка!!! Checkbit: 1-й аргумент не число!") end
if type(_bit) ~= "number" then error("Ошибка!!! Checkbit: 2-й аргумент не число!") end
if _bit == 0 then _bit = 0x1
elseif _bit == 1 then _bit = 0x2
elseif _bit == 2 then _bit = 0x4
elseif _bit == 3 then _bit = 0x8
elseif _bit == 4 then _bit = 0x10
elseif _bit == 5 then _bit = 0x20
elseif _bit == 6 then _bit = 0x40
elseif _bit == 7 then _bit = 0x80
elseif _bit == 8 then _bit = 0x100
elseif _bit == 9 then _bit = 0x200
elseif _bit == 10 then _bit = 0x400
elseif _bit == 11 then _bit = 0x800
elseif _bit == 12 then _bit = 0x1000
elseif _bit == 13 then _bit = 0x2000
elseif _bit == 14 then _bit = 0x4000
elseif _bit == 15 then _bit = 0x8000
elseif _bit == 16 then _bit = 0x10000
elseif _bit == 17 then _bit = 0x20000
elseif _bit == 18 then _bit = 0x40000
elseif _bit == 19 then _bit = 0x80000
elseif _bit == 20 then _bit = 0x100000
end
if bit.band(flags,_bit ) == _bit then return true
else return false end
end
function OnOrder(order)
--бит 0 (0x1) Заявка активна, иначе – не активна
--бит 1 (0x2) Заявка снята. Если флаг не установлен и значение бита «0» равно «0», то заявка исполнена
--бит 2 (0x4) Заявка на продажу, иначе – на покупку. Данный флаг для сделок и сделок для исполнения определяет направление сделки (BUY/SELL)
--бит 3 (0x8) Заявка лимитированная, иначе – рыночная
--бит 4 (0x10) Разрешить / запретить сделки по разным ценам
--бит 5 (0x20) Исполнить заявку немедленно или снять (FILL OR KILL)
--бит 6 (0x40) Заявка маркет-мейкера. Для адресных заявок – заявка отправлена контрагенту
--бит 7 (0x80) Для адресных заявок – заявка получена от контрагента
--бит 8 (0x100) Снять остаток
--бит 9 (0x200) Айсберг-заявка
-- Проверка бита 2
if CheckBit(order.flags, 2) then
message("Заявка на продажу");
else
message("Заявка на покупку");
end;
end;
https://quikluacsharp.ru/qlua-osnovy/funktsiya-dlya-raboty-s-bitovymi-flagami-v-qlua-lua/
Сейчас в QLua появилась встроенная функция bit.test, которая решает ту же задачу,
т.е. смысла в использовании функции CheckBit больше нет!
Открываю справку
bit.test
Функция проверяет состояние указанного бита в значении.
Возвращает
true, если бит равен «1», и
false, если бит равен «0».
BOOLEAN bit.test(NUMBER х, NUMBER n)
где:
х – значение;
n – номер бита. Нумерация битов начинается с «0».
Владимир, Вы не поняли. В основном пользуются двумя видами Стоп лосов;
1) На торговый день защита депозита от чрезмерной просадки, К примеру если депозит теряет 2-5%, то сделки по счету закрывают, активные заявки сбрасываются, торговля останавливается, выясняется причина такой просадки. Смысл сводится, Сколько просадок депозит выдержит что можно было восстановить счет.
2) На сделку. Здесь защищают конкретную сделку обычно привязываются к рынку (волатильности прикидывают risk/rewar или другим способом).
То что Вы описали это стоп на сделку, если бы у Вас стоял и сработал, Вы получаете ожидаемый убыток в моменте, но продолжаете крутить высвобожденную сумму, Нет упущенной выгоды! Пересиживать можно в акциях и то на свои.
Цитата
Владимир написал: а уж вероятность того, что именно в этот момент случится что-то страшное
То что сейчас все спокойно, еще не повод, да и новости никто не отменял.
Цитата
Владимир написал: Сейчас вероятность проблем со связью близка к нулю
От этого защищаются установкой на сторонней сервер.
При переходе от одного инструмента к портфелю, встал вопрос как поступить с расчетом индикаторов:
Вариант 1) Оставить как есть, то есть расчеты вести в QUIK и получать результат. Вариант 2) Сбросить все алгоритмы в main и там их считать.
Стратегия реверсная по тренду, на стадии наладки Вариант1: за) визуализация, main просто отдыхает замедление минимальное ставим, нет проблем с синхронизацией данных. против) нужны графики на каждый инструмент, нагрузка на Терминал.
Пока так быстрее, да и хочется посмотреть как оно будет, такой подход практиковала команда Универ.
Nikolay написал: Только я писал о проблеме, если колбек пропущен по любой причине.
Да но заявка формируется еще до запуска основного потока main, то есть изначально существует у нее trans_id. если увидит свой trans_id то поступит с ней согласно SmartOrder:update(price, planned), Ну вообще нужно посмотреть этот момент? Спасибо.
Nikolay написал: Элементарно - выключил скрипт, все данные потерял. Надо дописывать хранение данных между запусками.
Да это нужно доделать!
Цитата
Nikolay написал: Также пропустил колбек - ордер не будет в актуальном состоянии.
Там получение через два колбека.
1) OnTransReply активирует получение ordernum:
if trans_reply.status == 3 then executor.order.number = trans_reply.ordernum else executor.order = nil end
и 2) OnOrder уже контролирует исполнение заявки:
Нет заказа, если он был выполнен немедленно! if executor ~= nil and executor.order ~= nil then executor.order.filled = order.qty - order.balance if (order.flags % 2) == 0 then --Заявка снята. Если флаг не установлен и значение бита «0» равно «0», то заявка исполнена executor.order.active = false end end Намой взгляд на оборот более надежно.
Цитата
Nikolay написал: Ну и другие вещи - обрывы связи, ожидание получения данных, смена торговой сессии, суток, ошибки чтения данных с графиков и т.д.
Это со старых беру.
Цитата
Nikolay написал: Но оставлять его без присмотра - это надо быть смелым.
До самостоятельности пока далековато. Я его тоже раньше видел, но тогда показался сложным в написании, а сейчас зашел на раз, да еще закрыл затычки при установлении момент наступления события.
Игорь М написал: В фрейморке HackTrade так было написано не из-за надежности, а из-за отсутствия побитовых операций в Lua52 на тот момент, они только в 2015 году появились в Lua53.
У Вас есть опыт работы с фрейморк HackTrade, если есть может поделитесь на что обратить внимание? Переписываю свой рабочий вариант встраиваю HackTrade, подкупает модульность, ну и конечно умная заявка.
TGB написал: Влючительно до версии 5.4.1, в кодах стандартных библиотек Lua не был учтен существующий режим конфигурирования (предусмотренный в исходниках Lua) использования стеков сопрограмм (thread) в отдельных потоках. Функции стандартных библиотек определены в Lua как сишные (потокобезопасные, допускающие параллельное выолнение), но в их коде нередко используется внутренняя среда интерпретатора Lua (не являющаяся потокобезопасной), и нет гарантии на уровне архитектуры реализации языка, того, что стандартные функции Lua по-токобезопасны для упомянутого режима.
Вот это совсем не понял? можно своими словами попроще.
Владимир написал: В если дяди нет, то решения принимает АЛГОРИТМ.
Ну алгоритм это часть чего то большего, а если несколько и на основании этих решений нужно принять решение без участия человека. А кто Каспарова обыграл? Не думаю что там один алгоритм матрица 8х8, разные фигуры ходят по разному?
Владимир написал: Все необходимые стратегии реализованы, отлажены, работают, а всё "спредовое, трендовое, свинговое, сеточное и прочее дерьмо отправлено на помойку. А вот цена в заявке есть постоянная величина.
Это то что я опробовал, детские ошибки сам пишу, сам делаю, сам исправляю, видимо пора чемоданы собирать и .... А у нас если поставим last то заявка обязательно исполнится! А у нас если поставим лучший bid или ask то встанет в стакан!
Конец придумыванию "велосипедов", мчимся на "болид формулы 1" - фреймворк HackTrade!
За все время тестирования, выявлена одна оплошность в HackTrade, не могу назвать ошибкой. И так, можно подвести некоторые промежуточные итоги эксплуатации фреймворка:
1) Написан на чистом lua (достаточно навыка знаний lua); 2) Взаимодействие с QUIK через стандартную библиотеку qlua (без дополнительных внешних библиотек); 3) Пожалуй самое главное, заявки не теряются, забыть про всякие "затычки"! каждая заявка сформированная HackTrade присматривает сама за собой, "Каждая заявка помнит, сколько она набрала, и сколько надо скидывать"; 4) Легко реализуется стратегии Мани Менеджмента, количество в заявке есть переменная величина; 5) Легко реализуются стратегии спредовые, трендовые, свинг, сетка и т.д., цена в заявке есть переменная величина; 6) Легко реализуются стратегии Риск Менеджмента.
Модульность! дописываем и цепляем, не трогая основное тело скрипта!
HackTrade - уверенно приобретает Искусственный Интеллект: решения формирует на основании множества индикаторов, адаптируется под цену, адаптируется под количество, выставляет заявки, а при необходимости легко дописывается "айсберг" заявка, (разбивка на небольшие лоты), отслеживает стоп-цену, отслеживает таке-профит, выводит своё состояние в окно.
Функциональность скрипта его модульность превращается в заслуженный торговый робот с ИИ.
Добрый день, Mariana, попробуйте так, ввел проверки на получение данных, ну и локализацию, а в целом понравилось, курс не прошел даром:
Код
local tostring=tostring;
local is_run = true;
local instrument_list = {"BRQ3", "BRU3", "BRV3", "BRX3", "GDU3", "GDZ3", "HSU3", "HSZ3", "NAU3", "NAZ3", "NGQ3", "NGU3", "NGV3", "NGX3", "PDU3", "PDZ3", "PTU3", "PTZ3", "SFU3", "SFZ3", "SVU3", "SVZ3"}
local nsecrefresh = 3;
local class;
function OnStop()
is_run = false
end
function round(num, idp)
if num == nil then return nil end
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
function CreateTable()
local t_id = AllocTable();
AddColumn(t_id, 0, "FUT", true, QTABLE_INT_TYPE, 10);
AddColumn(t_id, 1, "OI", true, QTABLE_INT_TYPE, 10);
AddColumn(t_id, 2, "OIINIT", true, QTABLE_INT_TYPE, 10);
AddColumn(t_id, 3, "OICHG", true, QTABLE_INT_TYPE, 10);
AddColumn(t_id, 4, "OICHG%", true, QTABLE_DOUBLE_TYPE, 10);
local t = CreateWindow(t_id);
SetWindowCaption(t_id, "Open Interest Change");
SetWindowPos(t_id, 100, 100, 252, 532);
class = "SPBFUT"
for k,v in pairs(instrument_list) do
InsertRow (t_id, k)
local sec = tostring(v)
local mdparam = getParamEx(class, sec, "NUMCONTRACTS")
local trueoi = mdparam.param_value
local trueoi_str = string.format("%d", trueoi)
SetCell (t_id, k, 0, sec)
SetCell (t_id, k, 1, trueoi_str)
SetCell (t_id, k, 2, trueoi_str)
local chg = 0;
SetCell (t_id, k, 3, tostring(chg))
local chg_pc = 0
SetCell (t_id, k, 4, tostring(chg_pc))
end
return t_id
end;
function RefreshTable(t_id)
for k,v in pairs(instrument_list) do
local sec = tostring(v)
local mdparam = getParamEx(class, sec, "NUMCONTRACTS")
local trueoi = mdparam and mdparam.param_value or 0;
local trueoi_str = string.format("%d", trueoi);
SetCell (t_id, k, 1, trueoi_str)
local initoi = GetCell(t_id, k, 2).image;
local chg = trueoi - initoi;
local chg_str = string.format("%d", chg);
SetCell (t_id, k, 3, chg_str)
local initoi_val = tonumber(initoi);
local chg_pc = initoi_val~=0 and round(chg / initoi_val * 100,2) or 0;
SetCell (t_id, k, 4, tostring(chg_pc))
end
end;
function main()
local table_id = CreateTable()
while is_run do
sleep(nsecrefresh*1000)
RefreshTable(table_id)
end
end