VPM (Все сообщения пользователя)

Выбрать дату в календареВыбрать дату в календаре

Страницы: 1 2 3 4 5 6 7 8 9 10 11 ... 28 След.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
"Разделяй и Властвуй"

Вновь и вновь возвращаюсь к примеру автор Nikolay №558,  Назову его "ФУНДАМЕНТАЛЬНЫМ" для QUIK / QLUA. Попробую разобраться с подходом, что здесь за модель и как из неё сделать универсальный боевой модуль, не сломав фундаментальные допущения?

Что уже реализовано — это кооперативный неблокирующий планировщик задач (cooperative task scheduler) в одном Lua-потоке, с:
* отсутствием ожиданий по времени;
* отсутствием блокировок;
* отсутствием предположения о задержке (assumptions о latency);
* прогрессом по факту изменения состояния.
И это НЕ очередь задач в классическом смысле. Это конечный автомат, опрос, управляемый событиями, (event-driven polling FSM).
Главное архитектурное решение (и оно единственно верное): > Мы не знаем, сколько времени займёт операция. Следовательно,

Нельзя:
* sleep(n)
* while not ready do end
* «ждать 30 секунд»
* «ждать 2 минуты»

Можно:
* проверять факт изменения состояния;
* делать это часто;
* не блокировать выполнение.

В коде "task" — это: > Объект проверки состояния, а не операция.
task.process = function()
   if условие_выполнено then
       return done
   end
   -- иначе ничего не делаем
end

И это принципиально, по следующим причинам:
* task.process() не делает работу,
* она проверяет, завершилась ли работа,
* сама работа выполняется вне task (QUIK, брокер, сервер).

И это правильная модель для:
* DataSource;
* транзакций;
* подписок;
* внешних сервисов.

Почему модель классная, а главное масштабируется. Очень важный плюс текущего подхода:
* можно иметь 100 DS
* можно иметь 1000 задач
* ни одна не блокирует другие
* все живут в одном цикле

И это уже:
* не потоковая модель;
* не callback-ад;
* не FSM в лоб.
Это кооперативная многозадачность, и для QLUA она оптимальна! Ну хоть и "опосля", ну доходит!

Главный вывод (ключевая формулировка).

Этот пример кода — с: > Неблокирующий кооперативный планировщик проверок состояния внешних асинхронных процессов. И это ровно то, что нужно для:
* DataSource;
* транзакций;
* брокерских ответов;
* пользовательских команд;
* UI;
* логики стратегий.
и что там еще нам нужно в нашей деятельности.

Это изначально, выбор правильного фундамента. И тут можно было бы закончить, поблагодарив автора за столь мощный "ФУНДАМЕНТАЛЬНЫЙ" пример.

Но от себя добавлю, что бы идти дальше и правильно, остаться в парадигме "один список задач", идея так себе — тупик в бою, и вот почему. "Один список задач" хорошо работает, пока:
* задач мало,
* они однородны,
* нет вытеснения,
* нет зависимостей,
* нет приоритетов,

Как только появляется:
* DS, которые живут часами,
* транзакции с неопределённым задержками (latency),
* стратегии, подписанные на бары,
* команды пользователя,
* аварийные события.
список превращается в плоскую кашу, и дальше начинается:
* If-ад
* флаги поверх флагов
* неявные зависимости
* ошибки, которые невозможно воспроизвести

Кто это знает, кто уже туда смотрел, и переходит к формированию задачи "планировщик + типы задач (DS, TX, UI)".
Вариант 2 — естественное развитие кода, возможно даже единственно правильный подход для боевого модуля?
Использование getParamEx для облигаций, Получение данных по облигациям из таблицы Текущих торгов
 
Танго,  Попробуйте так:
Код
  -- ОФЗ-ПД
  -- 26238 15/05/2041
  -- SU26238RMFS4
  -- TQOB
local Class   = "TQOB"                    -- пробовал   TQСB
local Emit    = "SU26238RMFS4"            -- пробовал  RU000A108EF8

local actualPrice = getParamEx(Class,Emit,"LAST").param_value;
message( 'actualPric = '.. tostring(actualPrice) )
-- вывожу в таблицу
-- SetCell(TableNaladka,2,2,actualPrice);
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Ок, спасибо Izotova Liliya, все так!
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Izotova Liliya,  Пользуясь случаем подскажите, при этих настройках я смогу  заказывать получать эти данные с помощь функции CreateDataSource используя четвертый параметр? Или этого недостаточно? За ранее благодарю!
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Все подгрузилось на графики, но теперь не понимаю радоваться этому или нет? На сколько скорость терминала упадет, и главное тут чтоб сам устоял, "ни пал лицом в грязь".
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
"Не что не вечно под луной". Заглянул в настройки котировок, а там классов по "наплодили"  :shock: ,  какие торговые, за полгода не разобрать? Пробежался вроде все нужны, парочку только отключил.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Izotova Liliya,  Спасибо принято, действительно упусти этот момент, надеюсь, что и терминал теперь загрузится.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Не могу понять, что опять не так делаю? Открыта таблица текущих торгов. Вывожу на график заявки и суммарный спрос / предложения. На дневном масштабе прошлой сессии есть значения, текущий нет?
Кто то может знает как этим правильно пользоваться?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
nikolz написал:
Прикольно читать Вашу тему.
А да рад что порадовал Вас!!!
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
nikolz,  Кто бы не сидел в "песочнице со своим ведерком", ему нужно выбраться. Хотя если ведерко полнехонько то и ладно.
А я лишь о профессиональном подходе к написанию, а главное применению кода. Что касается "Промышленный" это перевод слова "production", значений в  слове на "ангельском" много, поэтому имею право переводить так. Некоторые стандарты к промышленному применению кода есть здесь, а так гугл в помощь.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
nikolz,  да Вы не обижайтесь. Ведь подобный стиль общения задаете именно Вы, я же предпочитаю "инженерный", если не прав или есть ошибки, так и приводите доводы. А лепет ребенка из песочницы, можно использовать когда все вокруг шутят.

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

Для своих целей собрал из них 10 бальную шкалу и проверяю на соответствие архитектуре свои скрипты. Уровень описанный выше соответствует в моей шкале началу 5 уровня, до которого зачастую не дорастают большинство любительских скриптов, заканчиваясь принятием решения при пересечениях индикаторов или что то в этом роде.
Модульность позволяет разворачивать программу до нужного уровня. Разделение ответственности по кругу задач, еще один важный момент в подобном подходе, который у меня страдает.  
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
nikolz написал:
Прикольно, что вы написали. И это не по взрослому, а по дилетанскому.
Ну наконец то "ПрофЭсор" разбушевался.
Цитата
nikolz написал:
а что такое "промышленная архитектура"? Откуда вы взяли этот термин? если сами придумали, то дайте определение.  
Это видимо то что Вы пропустили в детском саду?  
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Видите в чем дело, велосипед изобретен за долго до меня, я лишь кручу педали .

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

Вторая логично вытекающая задача сделать его универсальным, в формате "Советника", с возможностью расширения архитектуры до боевой. Вот что обернулось быстро я частично описал.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
nikolz,  "У нас" - это те кто пользуется  инфраструктурой Квика, и я рассуждаю о разворачивании на ее основе торговой платформы на луа, а не вообще. Не нужны, тут ни какие драйвера, кроме того что предоставляет квик. Разворачивая торговую систему, приводя в порядок архитектуру  и дописывая модули, мне это напомнило порядок ОС (как пример DOS). Зная это, можно изначально закладывать архитектуру как промышленную. Сложно но можно!
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
nikolz написал:
А если серьезно, то попробуйте написать на луа какой-нибудь драйвер устройства, что является обязательным элементом OC.
Не я тоже возмущен почему, у "Условного Маркет Мейкера"  скорость 10 мк.сек. а унас 200 мл.сек., а кому повезет, ну хорошо кто следит, 100 мл.сек.
И это ни сколько не отменяет тот  факт что код может отвечать принципам и требованиям ОС?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
nikolz написал:
В мире еще много удивительного и не познанного.
Соглашусь с Вами!
Цитата
nikolz написал:
А самое прикольное, Вы никогда бы не догадались, земля -круглая, а не плоская.  
А Вы спросите у ГЕОЛОГОВ - специалистов? Это просто стереотип!
Цитата
nikolz написал:
Вы еще больше удивитесь, когда узнаете, что из кирпичей можно построить стены дома и, даже сложить печку в доме том.
Не не не удивляйтесь, в степях строили "мазанки", в Сибири из бруса, кому удавалось, в основном кругляк, боюсь сказать какие материалы применяются в современном мире.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 

"Разделяй и Властвуй (лат. divide et impera)".

Сам себе удивляюсь. Разработка концепции "Разделение ответственности", пример выше, привела к осознанию, того что можно строить "Операционную Систему". Да, да и я не описался. Скриптовый язык луа, для торговой системы QUIK, можно строить торговую "ОС" ни прибегая к стороним программам. НУ Хорошо пусть будет платформа. Так я проверил отвечает принципам ОС.
Просто в шоке! А где специалисты? Хоть кто то бы на это намекнул?  
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
VPM написал:
Конечно невозможно поучить во встроенных индикаторах
Упёрся ровно в ключевое ограничение QUIK, и если решить его правильно — дальше всё встанет на свои места, очень чисто.
Продлема:
   ->  QUIK НЕ даёт напрямую получить параметры class_code и sec_code из легенды графика.
   -> Легенда — это "UI-строка", не идентификатор инструмента.
Но не обходное решение нашлось, и оно рабочее. Задача. Нужна универсальная функция (алгоритм) утверждающая "это мой инструмент", должна быть безопасна при переключении графиков.

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

Важно. Нельзя здесь конечно ни чего утверждать однозначно.
Так как строится данный алгоритм на гипотезе утверждающей: "Легенда графика всегда содержит short_name, но с хвостом вида: " [Price]" / " [Volume]" / " [ATR]" и т.п.".
Есть просто надежда, что еще какое то время, она просуществует, но ведь существовала же до сих пор.
Возможно это очередной "велосипед", и кто то решал уже подобную задачу, но я ни чего не нашел, поэтому будет "Трехколесный".

Ниже — по порядку.

Что у нас есть?
SecurityInfo.short_name = "Сургнфгз-п"
legenda = "Сургнфгз-п [Price]"

Правильная логика сравнения. Нужно убрать всё после '[' и сравнить "чистые" строки.

if short_name == legend_clean then
   -- это нужный график
end

Это единственный надёжный путь. Стратегия - обратное сопоставление: legend -> short_name -> sec_code + class_code
То есть:
1. Берём legend
2. Извлекаем short_name
3. Ищем инструмент, у которого SecurityInfo.short_name совпадает
4. Запоминаем class_code + sec_code
 
ВАЖНО: коллизии short_name. Это реальная проблема:
* GAZP (акции)
* GAZP-12.25 (фьючерс)
Как защититься (думаю), хранить список, а не один элемент.

Это значит, что мы можем построить полностью автоматическую библиотеку инструментов:

getClassesList()
   v
getClassInfo(class)
   v
getClassSecurities(class)
   v
getSecurityInfo(class, sec)

И уже по легенде графика восстанавливать: legend > short_name > sec_code + class_code.  
Извечный вопрос: повторные вызовы OnTrade, Даже при заявке на одну акцию
 
Цитата
TGB написал:
Цитата
VPM написал:
особенно в скоростных алгоритмах
    Какие скоростные алгоритмы? Когда есть ограничение архитектуры QUIK. Факторами возможных задержек в нем являются <Реализация скрипта>  ->  <Реализация QUIK>  ->  <Используемая аппаратура ПК>  -> <Канал связи с брокером> -> <Сервер брокера> ->  -> <Канал связи брокера с биржей> -> <Биржа>.
Я не очень понимаю, что Вы хотите донести, и о чем спорите? И  при этой архитектуре можно строить торговлю спредом, с выставление огромного количества ордеров, а следовательно нужна обработка как ордеров так и сделок. Например, мой алгоритм оставленный мной без присмотра, поймал какую то  ошибку (уже и не припомню причину) наделал столько заявок, что брокер заблокировал канал, а затем выставил штраф. Это я к тому что все возможно!
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
"А ларчик просто открывался!"

При описанным выше подходе "разделения ответственности", элегантно решаемся еще одна наедающая покоя задача. А именно передача параметра sec_coda из индикатора в луа скрипт. Конечно невозможно поучить во встроенных индикаторах, но всегда можно повторить его в луа, получить параметр и передать, как показано выше в моем  примере.
Извечный вопрос: повторные вызовы OnTrade, Даже при заявке на одну акцию
 
Добрый день TGB,  то что Вы описываете в определённых стратегиях конечно надежней, но задача далеко не тривиальна, особенно в скоростных алгоритмах. Да и автор вопроса применяет событийный подход. А вопрос звучит так:
Цитата
User12501 написал:
Речь о том, как проигнорировать бесполезный вызов и не посчитать дважды то, что нужно? Например если в момент OnTrade мне нужно знать общее количество оставшихся акций, стандартные get-функции не работают (спрашивал об этом вот здесь:  https://forum.quik.ru/forum10/topic9409/  ). Значит нужно вводить отдельную переменную - количество акций, и при каждом OnTrade обновлять. Но тогда при повторном OnTrade происходит повторное обновление, и пожалуйста - ошибка.  
Плюс учет различных комиссий в принятии решений, насколько помню точность в учете QUIK до шестого знака. Как же тут не сверять свою вторую бухгалтерию?
 
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Концептуально, такую архитектуру можно свести к последовательным шагам взросления системы, в стиле боевого QUIK-safe.
Важных, самостоятельных 4 - логических слоя, как в профессиональных торговых платформах:

ШАГ 1. Цель QUIK-safe. Приведение индикатора к QUIK-safe стилю, для QUIK это будет означать:
1.  никаких глобальных переменных;
2.  никаких "висящих" состояний;
3.  чёткий lifecycle: "init -> bar -> return";
4.  "индикатор не знает про торговлю, только сигналы".

1.1. Новая контрактация индикатора (правильный подход). "Индикатор = детектор структуры рынка, не стратегии". Он должен:
* принимать index, settings, datasourсe;
* хранить локальный state;
* возвращать расчетные значения (для индикатора только линии).

ШАГ 2. Встраивание в SignalEngine. Теперь "SignalEngine — мозг, индикатор — сенсор".

2.1. Контракт SignalEngine (минимальный).
Код
local SignalEngine = {
    factors = {},
    regime = "unknown",
    score = 0
}

2.2. Использование данных от индикатора (и это уже по взрослому).
Код
function SignalEngine:updateFromBreakout(buy, sell, support, resistance, volRatio)

    local factor = {}

    -- Фактор направления
    factor.breakout =
        buy and 1 or
        sell and -1 or
        0

    -- Фактор структуры
    factor.structure =
        support and 0.5 or
        resistance and -0.5 or
        0

    -- Фактор волатильности
    factor.volatility = clamp((volRatio or 0) - 1, -1, 1)

    self.factors.breakout = factor
end

ШАГ 3. Indicator / TradingCore (разделение ответственности). Правило №1. "Индикатор не принимает решений".

| Слой              | Отвечает за |
| ------------------ | ----------------- |
| Indicator         | данные        |
| SignalEngine  | оценку         |
| Trader            | ордера         |

-- Trading Core (пример концепции)
Код
local Trader =  {}
function Trader:process(signalScore, regime)
    if regime == "flat" then return end

    if signalScore > 0.7 then
        self:buy()
    elseif signalScore < -0.7 then
        self:sell()
    end
end
ШАГ 4. Auto-Regime + фильтры.

4.1. Определение режима.
Код
function SignalEngine:detectRegime(vol, adx)
    if vol < 0.7 and adx < 15 then
        return "flat"
    elseif adx > 25 then
        return "trend"
    else
        return "transition"
    end
end

-- 4.2. Режимно-зависимая (Regime-aware) фильтрация.
Код
function SignalEngine:filterFactorsByRegime(regime)
    if regime == "flat" then
        self.factors.breakout.breakout = 0
    elseif regime == "transition" then
        self.factors.breakout.breakout = 0.5
    end
end

-- 4.3. Финальный Score
Код
function SignalEngine:calcScore()
    local score = 0
    for _, f in pairs(self.factors) do
        score = score + (f.breakout or 0) + (f.structure or 0)
    end
    self.score = clamp(score, -1, 1)
    return self.score
end
И ни какой магии, типа машинного обучения или нейросетей!  А главное безопасное изменение и замена модулей. Хочется думать так, а жизнь покажет, что опять не учитываю.  :smile:  
Извечный вопрос: повторные вызовы OnTrade, Даже при заявке на одну акцию
 
Привел Вам просто базовую свою заготовку, в качестве примера не более. Если вы пишите на луа 5.4, то нужно отказаться от bit.band в пользу продвинутого метода. Что там точно за комиссии, подсказать  тоже не могу так как на каждом рынке есть особенности. Для Фондового API QUIK предлагает предварительный расчет через стандартную функцию. Для оценки можно ее воспользоваться. На срочном есть зависимость от гарантийного обеспечения и курсов ... Что касается моего подхода, то я применяю подход  Ральфа Винса, а именно, торговый капитал делю изначально на две части: пассивный и активный. Так как в процессе торговле всегда присутствует пассивная часть, нет необходимости вести четкий учет комиссий, сверяю по клирингу. Здесь более важен учет количества и цены, так как на прямую влияют на управление позицией.  
Извечный вопрос: повторные вызовы OnTrade, Даже при заявке на одну акцию
 
User12501,  И это еще не вся проблематика, ведь нужно данные периодически синхронизировать с данными QUIK.  
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Nikolay,  Вы подняли очень важную проблему "вопрос консистентности данных", все мы сталкиваемся, так как повлиять на ситуацию целиком мы не можем, но должны учитывать эти особенности, должны применять какие то инженерные подходы в обеспечении безопасности. На мой взгляд проблема слишком большая, и требует отдельного обсуждения, может даже выноса в отдельную ветку (если еще не вынесена).

Но давайте по порядку.
Цитата
Nikolay написал:
Вы забыли данные из других источников.
  • Я их умышленно обошел, и задачу свел к получению исторических данных из QUIK,  предполагая что они уже есть, и показу единообразия в подходах. Запись в файл и чтения из него, здесь сводится к единой структуре данных. По сути заданию некоего индекса.
  • Расчет  local breakout = f( index, Settings ) , если не нежны графики? выводим в скрипте f( index, Settings, ds ). По сути сменили источник с сохранением архитектуры, ровно то что Вы описали выше. Давно уже задался задачей сохранения архитектуры при изменяемых модулях.
Извечный вопрос: повторные вызовы OnTrade, Даже при заявке на одну акцию
 
Цитата
User12501 написал:
Например если в момент OnTrade мне нужно знать общее количество оставшихся акций, стандартные get-функции не работают
Вы подняли очень важный вопрос. Он касается широкого круга пользователей, и широко обсуждался на форуме и приводились различные боевые подходы. На Ваш вопрос выше, ответ нужно организовывать внутренний учет, не только количества но и других параметров зависящих от конкретной сделки сделки (допустим усреднялись). Вот пример подхода которым, часто пользуюсь на скоростных скриптах:
Код
function OnTrade(trade)

    if not WORKING_FLAG then return end

    local key = trade.trans_id
    local i = tonumber(sdelka[0]); 
    
  if working 
  and key and key>0
  and (i==0 and key~=sdelka.id) or (i>0 and sdelka[i][1]~=key)
  --and trade.sec_code==symbol --and trade.class_code==class 
  then
    
    i=i+1;  
    sdelka[0]=i;                         
    sdelka[i]={};                     
    sdelka[i][0]=sdelka[0];
    sdelka[i][1]=trade.trans_id;      
    sdelka[i][2]=get_date(trade.datetime)
    sdelka[i][3]=get_time(trade.datetime)
    
    sdelka[i][4]="B"; if bit.band(trade.flags,4)~=0 then sdelka[i][4]="S"; end;
    local dir = sdelka[i][4]=="B" and 1 or sdelka[i][4]=="S" and -1 or 0;
    sdelka[i][5]=trade.qty*dir;       
    sdelka[i][6]=trade.price;         
    ----- comission 
    sdelka[i][7]=trade.clearing_comission+trade.exchange_comission+trade.tech_center_comission;
    
    sdelka[i][8]=trade.order_num;    
    sdelka[i][9]=trade.trade_num;  
    sdelka[i][10]=trade.sec_code;     
                        
    sdelka.id=trade.trans_id;
    
    Log:info("OnTrade! sdelka "..i .."; "
                                  .."; trans_id="..sdelka[i][1] 
                                  .."; "..sdelka[i][2]
                                  .."; "..sdelka[i][3]
                                  .."; "..sdelka[i][4]
                                  .."; "..sdelka[i][5]
                                  .."; "..sdelka[i][6]
                                  .."; comission="..sdelka[i][7]
                                  .."; onum="..sdelka[i][8]
                                  .."; tnum="..sdelka[i][9]
                                  .."; "..sdelka[i][10]
                                  .."\n"
                                  );
    --local a,v; for a,v in pairs(sdelka[i) do Log:trace( 'OnTrade! sdelka['..i..']['..tostring(a)..'] = '.. tostring(v) ) end;
  end
end;
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Разделение ответственности, на примере создания индикатора. Единый принцип архитектуры торговой системы в QUIK.

Что общего в получении исторической информации в QUIK разными способами. Ответ очевиден - хранение информации в массивах данных и извлечения ее с помощью параметра "index".

1. OnCalculate. Задается на прямую QUIK.
2. getCandlesByIndex. Получаем количество свечей "==" local index = getNumCandles(CFG.tags.price), индекс текущей свечи.
3. CreateDataSource. По факту тоже самое, получаем уже размер массива Size() "== index". Зачем введены разные смыслы, остается загадкой?

Понимание этого, приводит к пониманию принципа построения единой архитектуры для разных источников данных.
Принципиальная ИТОГОВАЯ АРХИТЕКТУРА: [ QUIK Chart ] -> [ Indicator/ CandlesByIndex/DataSource] -> [ SignalEngine ] -> [ Regime Filter ] -> [ Trading Core ].

Коротко почему это наиболее правильный подход:
* безопасно для QUIK;
* расширяемо;
* легко диагностировать;
* нет переобучения внутри источника (индикатора);
* можно менять стратегию без переписывания индикаторов.
Пример, индикатор источник данных, перенос ответственности.
Код
local path = getWorkingFolder()
local f;
local save = {
    position = 0,
    d = 0,
    t = 0
    }

Settings={}
Settings.Name = "*BreakoutIndicator"
Settings.period = 5
Settings.k = 1
Settings.wid = 0

function Init()
    local Cached = dofile(path .. "\\cached.lua"); 
   f = BreakoutIndicator()
   Cached=nil
   Settings.line = {
   {Name = "BUY", Type = TYPE_TRIANGLE_UP, Width = 1, Color = RGB(0, 0, 255) },
   {Name = "SELL", Type = TYPE_TRIANGLE_DOWN, Width = 1, Color = RGB(255, 0, 128) },
   
   {Name = "save.upper", Type = TYPE_BAR , Width = 1, Color = RGB(0, 128, 255) },
   {Name = "save.lower", Type = TYPE_BAR, Width = 1, Color = RGB(255, 0, 128) },
   {Name = "SL", Type =TYPE_DASH, Width = 1, Color = RGB(255, 0, 0) }
   }
   return #Settings.line
end
function OnCalculate(index)

   -- ====== ТЕКУЩИИ ЗНАЧЕНИЯ ======
    local position1 = save.position 
    local d1 = save.d
    local t1 = save.t
    
    -- ====== Расчет ЗНАЧЕНИЙ ======
    local breakout = f( index, Settings )
    
    -- ====== Обработка ======
    local newbar = (breakout and d1 ~= breakout.d or breakout.t ~= t1)
    
    save.position = breakout and breakout.position
    save.d = breakout and breakout.d
    save.t = breakout and breakout.t
    
    --====== RETURN LINES ======
    if Settings.wid == 2 then
        return nil,nil,nil,nil, breakout and breakout.volatilityRatio > 1 and breakout.volatilityRatio or nil
    end
    return  breakout and (d1 ~= breakout.d or breakout.t ~= t1) and breakout.position == 1 and  breakout.entryLevel or nil,   -- BUY
            breakout and (d1 ~= breakout.d or breakout.t ~= t1) and breakout.position == -1 and breakout.entryLevel or nil,   -- SELL
            breakout and breakout.position == 1 and breakout.upperPivot or nil,
            breakout and breakout.position == -1 and breakout.lowerPivot or nil,
            breakout and breakout.position ~= 0 and breakout.slLevel or nil

end
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
Nikolay написал:
А для получения результата сейчас лучше пойти намного более простым путем.
А чем же он проще? Все модули нужны везде?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Согласен, картину страшную описали для авто торговли. Думал заменить подход, теперь верну.
Код
----- Получаем цену последней сделки с графика цены 
      local I = getNumCandles(tag.price)   
      while I==nil or I==0 do
         sleep (100)
         I = getNumCandles(tag.price)
      end
       if I<=4 then toLog(log,  'Недостаточно бар для продолжения работы ' .. tostring(I) ) return end
Вывод. Получение данных сводится к отдельной задаче. Корректность данных можно свести к общим подходам так как данные сводим в таблицы. Так?
В реализации подхода рассмотренного мною, без машины состояний вообще не вариант.
State Machine - система состояний (FSM), будет отслеживать состояние робота — в состоянии ли он торгов, или ждёт обновлений данных или ждёт сигналов и т.д.

Итог. правильная модель (минимальный фундамент):
-> рынок — это функция времени (ввести понятие дискретности  "квант времени"),
-> стратегия — функция состояния (снимок, срез в заданный момент).

Принципы.
1. Источник истины — время
2. Минимальный ТФ > двигатель времени
3. Остальные ТФ > состояния мира
4. Стратегия никогда не входит в источники данных
5. Индикаторы — просто ещё один Source.

Каркас - итоговый поток:

DataSource
  v
TimeEngine (tick - "квант времени")
  v
WorldState (snapshot -  снимок)
  v
Strategy (signal)
  v
SignalFilter
  v
PositionManager
  v
FSM
  v
TradeAdapter
  v
Equity

Каждый слой делает только своё.
Попробую реализовать. Не могу сказать что упростил, но "руки чешутся" по пробовать.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Код
-- Безопасное получение значения с графика
function Utils.getGraphValue(tag, line, index, field)
    local candles = getCandlesByIndex(tag, line, index, 1)
    if not candles or not candles[0] then
        return nil
    end
    return candles[0][field]
end
-- ===============================
-- ДАННЫЕ (DATA LAYER)
-- ===============================
local Data = {}

function Data:init()
    self.context = {}
    self.history = {}
    self.current_index = 0
end

function Data:update()
    -- Получаем количество свечей
    local num_candles = getNumCandles(CFG.tags.price)
    if num_candles < 20 then
        Utils.log("WARN", "Недостаточно свечей: " .. num_candles)
        return false
    end
    
    -- Текущая свеча
    local candle = Utils.getGraphValue(CFG.tags.price, 0, num_candles - 1, "close")
    if not candle then return false end
    
    self.context = {
        -- Цены
        bar_index = num_candles - 1,
        datetime = Utils.getGraphValue(CFG.tags.price, 0, num_candles - 1, "datetime"),
        open = Utils.getGraphValue(CFG.tags.price, 0, num_candles - 1, "open"),
        high = Utils.getGraphValue(CFG.tags.price, 0, num_candles - 1, "high"),
        low = Utils.getGraphValue(CFG.tags.price, 0, num_candles - 1, "low"),
        close = Utils.getGraphValue(CFG.tags.price, 0, num_candles - 1, "close"),
        volume = Utils.getGraphValue(CFG.tags.price, 0, num_candles - 1, "volume"),
        
        -- Price Channel
        resistance = Utils.getGraphValue(CFG.tags.channel, 0, num_candles - 1, "close"),
        middle = Utils.getGraphValue(CFG.tags.channel, 1, num_candles - 1, "close"),
        support = Utils.getGraphValue(CFG.tags.channel, 2, num_candles - 1, "close"),
        
        -- Decycler
        decycler_high = Utils.getGraphValue(CFG.tags.decycler, 0, num_candles - 1, "close"),
        decycler_low = Utils.getGraphValue(CFG.tags.decycler, 1, num_candles - 1, "close"),
        decycler_high_prev = Utils.getGraphValue(CFG.tags.decycler, 0, num_candles - 2, "close"),
        
        -- RSI
        rsi = Utils.getGraphValue(CFG.tags.rsi, 0, num_candles - 1, "close"),
        
        -- ADX
        adx = Utils.getGraphValue(CFG.tags.adx, 0, num_candles - 1, "close"),
        plus_di = Utils.getGraphValue(CFG.tags.adx, 1, num_candles - 1, "close"),
        minus_di = Utils.getGraphValue(CFG.tags.adx, 2, num_candles - 1, "close"),
        
        -- ATR
        atr = Utils.getGraphValue(CFG.tags.atr, 0, num_candles - 1, "close")
    }
    
    -- Проверка данных
    if not self.context.resistance or not self.context.middle or not self.context.support then
        Utils.log("ERROR", "Не удалось получить данные Price Channel")
        return false
    end
    
    -- Расчет процента ATR
    if self.context.atr and self.context.close then
        self.context.atr_pct = (self.context.atr / self.context.close) * 100
    else
        self.context.atr_pct = 0
    end
    
    -- Сохраняем в историю 
    table.insert(self.history, {
        index = self.context.bar_index,
        datetime = self.context.datetime,
        open = self.context.open,
        high = self.context.high,
        low = self.context.low,
        close = self.context.close,
        data = {
            resistance = self.context.resistance,
            middle = self.context.middle,
            support = self.context.support,
            decycler_high = self.context.decycler_high,
            decycler_low = self.context.decycler_low,
            rsi = self.context.rsi,
            adx = self.context.adx,
            plus_di = self.context.plus_di,
            minus_di = self.context.minus_di,
            atr = self.context.atr
        }
    })
    
    return true
end
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Синхронизация же нужна для режима бэк теста.  
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
Nikolay написал:
Здесь вопрос в излишней сложности.
Вопрос получения данных обособленный процесс.  Если рассматривать 2 способа.  getCandlesByIndex возвращает таблицу луа, DataSource возвращает методы получения данных. Два подхода таблица и функция. Мне  представляется во втором больше проверок, так как если график отрисован -> таблица уже есть.
Цитата
Nikolay написал:
В режиме чтения с графика необходимо реализовать все те же методы синхронизации, заказа и ожидания данных
Появление данных проверяем в первом проверяем с getNumCandles по факту индекс. Обновилась таблица пересчет все остальных индикаторов. Возможно и здесь коме события нужны состояния и переходы?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
Nikolay написал:
Легенда - это просто подпись под данными.
Так вот я и подумал, что  если со сменой Легенды (или вместо) возвращать параметры class_code,  sec_code, решается много задач автоматизации. Или как то их привязать друг к другу.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
Nikolay написал:
Ну если обмен информацией еще не кажется на данном этапе "стоп-сигналом для использования данной "технологии"
Я не вижу здесь противоречий. Заменяя способ получения данных, делаешь все тоже самое в луа, возникает необходимость дописывать алгоритмы уже в самом луа, в место получения их графика. А здесь уже компетенции играют роль. За частую наделаю ошибок и всю хорошею (ну как минимум не проверенную)  заброшу.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
Nikolay написал:
Но т.к. Вы решили пойти сложным путем, и использовать зачем-то связанные окна
Идея проста. Инвестиционный портфель (МЕСЯЧНЫЙ ТАЙМ ФРЕЙМ) , Среднесрочный портфель (НЕДЕЛЬНЫЙ ТАЙМ ФРЕЙМ) . На них удобен этот подход. Редкие запросы.
Цитата
VPM написал:
QUIK сам делает тяжёлую работу. Lua только читает результат.
Получаем всю картинку в виде метрик по инструменту в таблице луа + визуализации на графике, видно весь контекст.  
Для ручного управления подходит. А вот дальнейшия автоматизация требует дополнительных параметров.
Если рассуждать про торговый робот то и событийная модель не проходит, нужно в водить машину состояний.  Да и Вами ранее описанный асинхронный подход (Dispatch) не будет лишним, а красиво ляжет. При этом получаем робот на один инструмент, с просты переходом на любой другой. Делая различные контуры управления, можно достигать любой необходимой сложности?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Не совсем понял:
Цитата
Nikolay написал:
Но тут же возникает вопрос - а может еще сложнее сделать... И это при существующем решении полностью независящим от графиков, интерфейса, случайных действий пользователя с графиком, особенностей запуска Квика и т.д.
Мои рассуждения просты. Одним из параметров возвращаемых ф. getCandlesByIndex является легенда (подпись) графика. Что это за подпись в справке умалчивается? По ней фиксирую смену инструмента. Здесь возникает вопрос, а можно ли по ней восстанавливать параметры class_code,  sec_code? Так как они ключ к получению остальной информации по инструменту.
Вариант 2. На графике в режиме индикатор можем получить, но возникает вопрос как простым способом передать в луа?
Цитата
nikolz написал:
local t=getDataSourceInfo();
  int=t.interval; clas=t.class_code; sec=t.sec_code;
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
С Новым годом!

Цитата
nikolz написал:
Если это не то, то расскажите на примере, что Вы хотите.
Так выше все описано. Раньше здесь предлагались dll от разных авторов, но дума и на чистом луа должно быть решение.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
nikolz,  Да я умею читать справку. Речь идет о передаче из графика в луа? Есть график где исполняются в QUIK разные индикаторы и формируются свечи, но чтобы привести цену к необходимому формату нужны class_code и sec_code, а с графика получаем легенду графика, если б приходил sec_code, то все остальные торговые параметры можно было бы восстанавливать (получать)  по нему. А по факту задал tag графику получил все остальные метрики в том числе и торговые.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Определенное не удобство в этом подходе, вызывает от факт что нельзя вернуть с class_code и sec_code? То факт что возвращается легенда графика, мало чем помогает в автоматизации подхода.  
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
Nikolay написал:
Все же мне сложно понять зачем выбирать чтение с медленного графика, когда есть инструмент для получения данных без каких либо ручных манипуляций.
Все дело в компетенции.
Подход с запахом "нафталина", напомнил времена, когда информация передавалась на дискетах, а вместо монитора зачастую использовали телевизор.  А под DOS за несколько минут можно было собрать не большое приложение, да еще работающее.

Вот и это подход позволяет за не большой промежуток времени собрать целые стратегии. Да он отправляет к истокам самого QUIK, но мне представилось, что его не забросили разработчики и что то подкрутили. По крайней мере у меня такое чувство сложилось от применения. Если отбросить мой контур управления из луа кода в виде модулей, то подход с правилами описанными выше стоит 100 - 300 кБ. Но главное это время от идеи до воплощения в терминале!
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
nikolz написал:
В таком случае можно сделать просто бесконечный цикл и выход по break
Этот мой пример вообще на "помойку" нужно выбросить, что и сделаем.
Получить номер свечи-фрактала
 
Сергей,  Если Вы про скрипт выше FRACTALS, то он написан для использования в 2 подходах: main и OnCalculate.
Для использования в OnCalculate ds не нужен.
Для варианта с main его нужно определить и передать в расчеты. Этот подход реализован функцией Value, а именно строками:  Out = (O and O(I)) or (ds and ds:O(I)), так как  O(I) определенна в  OnCalculate следовательно будет возвращать значение. В случае с  main нужно определять ds и получать значения через метод. Здесь много примеров как это делается для обоих вариантов.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Оказывается, QUIK гарантирует, если время последней свечи изменилось — свеча закрыта! Тогда определяется ключевой элемент "детектор НОВОЙ СВЕЧИ".
Важно, торговые решения применяем, только после закрытия свечи, торговля внутри незакрытой свечи Запрещена!
Следящее правило, работать с 2–3 последними свечами, отсчет ведется от текущей не закрытой свечи.
Еще одно правило, так как QUIK не гарантирует синхронность и свеча может закрыться с задержкой, правильно: сравнение datetime свечи.
Правило уже озвучено зафиксируем, график = результат, Lua только читает.

Минимальная необходимая структура:
robot/
* main.lua
* Graph.lua
* NewBar.lua
* Trade.lua

Сам адаптер:
Код
local Graph = {}

function Graph.new(tag, line)
    local o = {}
    o.tag = tag
    o.line = line or 0

    function o:last()
        for i = 0, 50000 do
            local _, n = getCandlesByIndex(o.tag, o.line, i, 1)
            if n == 0 then
                local t = getCandlesByIndex(o.tag, o.line, i - 1, 1)
                return t and t[1] or nil
            end
        end
    end

    return o
end

return Graph
Ну и пример того что получилось:
Код
local Graph   = require("Graph")
local NewBar  = require("NewBar")
local Trade   = require("Trade")
local is_run = true

function main()
local price = Graph.new("graph_SBER", 0)
local ma20  = Graph.new("graph_SBER", 1)
local ma50  = Graph.new("graph_SBER", 2)

local bar = NewBar.new("graph_SBER")

while is_run do
    if bar:check() then
        local p  = price:last()
        local m20 = ma20:last()
        local m50 = ma50:last()

        if p and m20 and m50 then
            if p.close > m20.close and m20.close > m50.close then
                Trade.buy()
            elseif p.close < m20.close and m20.close < m50.close then
                Trade.sell()
            end
        end
    end
    sleep(200)
end
end

function OnStop()
    is_run = false
end
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Обоснуем подход не как “универсальный”, а как узкоспециализированный адаптер под индикаторный график.
Если сделать его правильно, getCandlesByIndex —оказывается очень удобный и надёжный источник для робота, торгующего одним инструментом на одном графике. Когда getCandlesByIndex — правильный выбор. Подходит ИДЕАЛЬНО, если:
  • индикаторы уже построены в QUIK,
  • сигналы зависят от: пользовательских индикаторов,
  • стратегия реагирует на закрытие свечи.

То есть: график = источник истины! Подход реально надёжен и это важно понимать, понимая что делает QUIK:

  1. индикаторы считаются C++-кодом QUIK,
  2. график уже агрегирован
  3. все пересчёты завершены ДО вызова Lua

Следовательно, нет рассинхронизации, нет “ещё не досчиталось”, нет гонок. Скрипт читает готовый результат, а не поток данных. QUIK сам делает тяжёлую работу. Lua только читает результат.

Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
О чудеса чудесные! Вот какой вывод могу сделать, после всех моих изысканий. Формула QUIK - нативного кода. Если свести всё к одному правилу:

"Пиши Lua так, как будто это C-обёртка над QUIK API"
  1. явные функции.

  2. минимум таблиц.

  3. минимум косвенности.

  4. предсказуемый жизненный цикл.

Поэтому версия без метатаблиц — QUIK - нативная! Да уж, до экспериментировал. Где то это уже видел?

Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
Nikolay написал:
Более важен вопрос - а надо ли это делать.
С моей точки зрения "универсальность"  - это прагматичный подход даёт нам гибкость, когда она нужна, и не мешает, когда не нужна. Один раз создав модуль, забываем про него, и пользуемся повсеместно.
То что Вы описываете, получается подход не "универсальный источник", а универсальный такой контейнер-декоратор, и это ключевое отличие. Нет таймеров, подписок, событий — всё по запросу? В QUIK это будет снижать риск зависаний и утечек?  

Главным критерием достоинством подхода, должен быть лозунг "не бороться с QUIK, а работаешь в рамках его реальности".

На сколько оправдано, пока для меня не понятно, много лишнего кода, пробую упростить без лишней магии и версия без метатаблиц вообще?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
nikolz,  Выше описанному мной подходу, ну так с десяток лет! Код просто поднял, накидал нужных мне индикаторов и все работает. Работает в режиме советника, тестирования, торговли.  Попробуйте проделать с Вашим решение все это?
Что касается меня, не применяю ни чего кроме луа и квик, даже dll отметаю. Причина здесь банально, в мире где все изменяется стремительно, а время выступает основным фактором, сторонние приложении требуют отдельной поддержки и затрат времени на их поддержание и разбирательство с ними.
Вторым фактором, является достижение надежности  в автоматических системах.  
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Идея объединить все эти источники под единый интерфейс на первый взгляд очень хороша и удобна, поскольку позволяет работать с данными с разных источников одинаково. Но, учитывая особенности Квик, а именно отсутствие синхронизации данных, не известно что и когда получишь, страшно выкладывать получившийся класс.

Посмотрим асинхронный подход ранее здесь обсуждаемый, может там что то по проще проявится?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Подход, разделяем получение данных и их обработку.
  1. Задача на получение данных создает источник и регистрирует его в менеджере.
  2. Задачи на обработку данных берут источник из менеджера и работают с ним через единый интерфейс.
За основу таблицы-прототипа для представления данных в едином виде, напрашивается подход реализованный CreateDataSource - "Функция предназначена для создания таблицы Lua и позволяет работать со  свечками". То есть по индексу свечи  возвращать соответствующее значение?
Получить номер свечи-фрактала
 
Сергей, Смотрите в справке функцию CreateDataSource - Функция предназначена для создания таблицы Lua и позволяет работать со  свечками, полученными с сервера QUIK, а также реагировать на их изменение.

Пример: ds = CreateDataSource("SPBFUT", "RIU5", INTERVAL_M1)

Страницы: 1 2 3 4 5 6 7 8 9 10 11 ... 28 След.
Наверх