Блог им. Replikant_mih

Архитектура, при которой стратегия упаковывается в файл. Algo-only.

Придумал интересный подход. Мож кого натолкнет на интересные идеи какие-то.

 

Сейчас начал торговать ML модели. С практической стороны с моделями какая сложность – там есть процесс предобработки данных – генерация признаков в основном (если с точки зрения трейдинговых данных заходить), поэтому нельзя просто сохранить модель, в другом месте загрузить и она будет работать, надо сохранить, загрузить, предобработать исходные данные к тому виду, к которому приучена модель и только тогда она будет работать. К счастью тонна сопутствующих трудозатрат убирается такой классной штукой как пайплайн – сейчас моя модель это 2 пайплайна – один для предобработки данных, другой для предикта (сама модель). Т.е. я где-то что-то рисечу, дальше автоматика упаковывает в пайплайны (2 на модель, как сказал). Все, могу кинуть эти 2 файла в папку с моделями, откуда их забирает торгующий блок и, собственно, отторговывает. Красота. Всякие мета-данные – тикер там, время удержания позиции и прочие мета-логики упаковываю или в сам пайплайн или в название файла. Красота.

 

 

Но по сути, классические алгоритмы (обычные алго-стратегии) по факту можно так же упаковывать. Можно это делать по идее (хотя на практике ещё не пробовал – идея с пылу с жару только) даже с помощью той же библиотеки. Пайплайны как работают: на вход дата-фрейм (ну или дата-сет, если кто не знаком с пандасом), на выход дата-фрейм или вероятности или че хочешь. В этот контекст вполне можно вписать обычные логики стратегии, даешь на вход свечные (или какие используешь данные), в пайплайне зашиваешь логики стратегии, на выход сигнал, например, бинарно 0/1. Т.е. по факту пайплайн это код, это алгоритм, что для стратегии и нужно, собственно.

 

По идее, если унифицировать интерфейсы, то торгующий блок может не знать что в пайплайн упаковано – модель/алгоритм простой или что-то ещё, на вход идут данные, на выход предикт (например, бинарный). Все, состряпал стратегию, упаковываешь в пайплайн, кидаешь в папку, торгующий модуль на лету подхватывает, считывает мета-данные и торгует. Мета-данные инкапсулировать тоже очень удобно по-моему. Можно там настройки про риски зашивать в том числе, например, или что-то ещё. Торгующий блок может подгружая пайплайн считывать мета-данные и использовать их как ориентир, но при необходимости может их и не использовать. Например, получая модель первый раз давать ей «испытательный срок» месяц, гоняя с пониженными рисками, собирая стату, потом уже смотреть что там про риски говорит сам пайплайн и использовать эти данные уже, как вариант.

 

Обожаю автоматизацию.

★5
43 комментария
По идее все так и должно быть, ваш торгующий модуль который обращается к какой либо стратегии, должен всегда обращаться к некоторому стандартному/общему интерфесу от блока стратегий. Как вы интерфейс опишите, это уже ваше дело, можете в джесон формате все там передавать. 
И ему, торгующему модулю, должно быть совершенно по барабану, что там у вас происходит в модуле стратегий :). Пайплайны ли вы используете или функции одну за дргой вызываете.
Касательно МЛ, то тенсорфлов сделал tensorflow serving как раз именно для того что бы использовать модели в продакшене быстро и удобно. Однако там конечно не все так здорово и удобно )) без пол литра не разберешься.
avatar

CloseToAlgoTrading, Ну, путь к лучшим практикам может быть тернист)), до этого надо ещё дорасти, прийти к этому.

 

tensorflow serving — спасибо, глянул мельком, у меня нейросетевых моделей пока нету, но видимо что-то такое (tensorflow serving) буду использовать когда дело дойдет до практики.

avatar
Replikant_mih, кажется тут уже когда то обсуждалось, но если у вас все на питоне то вы можете использовать flask и пакуйте все что угодно внутрь, получите доступ через рест к вашим алгоритмам с любых платформ ).
Но если у вас крутится на одном языке и в одной коробочке, то это все не обязательно.
avatar
CloseToAlgoTrading, Нуу да, но только во фласк оболочку стратегию все равно надо как-то засунуть, это надо заново приложение запускать, как я понимаю, какие-то доработки в коде делать, а в случае пайплайнов, ты просто «кладешь пайплайн в папку», у меня есть некая рисеч тетрадь где я играюсь с моделями, пара движений руками и тетрадь сохраняет отобранные модели в пайплайны (это пока с ML моделями, как будет с обычными стратегиями пока не знаю), ну реально пару переменных переключить, условно, упаковывать в API насколько я понимаю, будет сложнее.
avatar
Replikant_mih, вы в endpoint Flask передаете название модели. Flask забирает данные из папочки с соответствующим именем и отдает ответ. Ничего перезапускать вам не прийдется. 
avatar
Михаил, да, ну только зачем это?) если у меня само приложение так же делает) — забирает из папочки). Если я научил приложение «забирать из папочки» — зачем фласк в данной конструкции?
avatar
Replikant_mih, это нужно, если вы хотите куда-то передавать модельки через REST, как CloseToAlgoTrading изначально предлагал. Если вы все делаете на одном компе большого смысла в этом нет. 
avatar
Михаил, А, понял.
avatar
Replikant_mih, :) если все работает, то и хорошо.
Так то «пайплайн» это просто обозначение конвеера выполнения задач, вы же его как то вызываете и данные на вход передаете. Вот этот момент можете обернуть в какой нить апи, и отделить полностью работу ваших стратегий, рекомендательных алгоритмов и тд, от остального приложения. Но только если вам это нужно. 

зы. хотя возможно вы уже используете нечто подобное, :) говоря «сохраняю модель в пайплайн».
avatar
CloseToAlgoTrading, Ага, ясн. Ну это одна из задач приложения подгружать пайпалайны, пару-тройку методов в приложении замутить под это дело вполне уместно) — они это и делают, да).
avatar
Я в MongoDB кладу вместо папочек:
— обученную модель
— метаданные описывающие процесс генерации признаков и модели
— перечень инструментов и диапазон дат на которых было произведено обучение
— метрику качества
— полное время на генерацию при знаков и обучение модели
avatar
Михаил, Ну вот у меня есть юпитер-тетрадь для рисеча, там куча методов для предпроцессинга данных, значения параметров, чтобы это воспроизвести (во времена до пайплайнов) мне нужно было в приложении, которое это будет торговать создавать логики для чтения параметров, методы для предобработки. А если в новой модели новые методы, то и новые пилить и т.д. это очень неудобно, в вашем примере с базой, мета-данные — они же имеют смысл в рамках алгоритма, а если алгоритм поменялся то и данные не помогут, короче, этот вариант (с базой и прочим) — он более трудоемкий.
avatar
Replikant_mih, я как-то не очень понимаю, в чем разница. Как вы свои пайплайны сохраняете? Что вы будете делать, если у вас появятся новые типы шагов в пайплайне?
avatar
Михаил, Нуу, у меня есть рисёч часть, где я анализирую, играюсь признаками, алгоритмами обработки данных и моделями и есть торгующая часть. Когда я наигрался в рисёч частью и чисто в рамках рисеча, мне чтобы пустить в бой не нужно дорабатывать ничего(!), я просто говорю: сохрани вот эту модель и вот эту, да я даже при рисече могу все их сохранять прямо. Дальше я беру пайплайн и «кидаю в папку», на той сторой стороне доделывать нужно… ничего. А в вашей парадигме — нужно что-то править и на других сторонах тоже. Т.е. где-то вы анализируете, а потом где-то в другом месте тоже что-то нужно править.
avatar
Replikant_mih, я так и не понял, что значит «я просто говорю: сохрани вот эту модель» — в каком формате?
Я тоже просто делаю вызов сохрани модель — в результате получается грубо json с последовательностью шагов (имен функций) и параметров вызовов. Есть простая функция которая умеет загружать — берет json и делает вызовы соответствующих функций с соответствующими параметрами.
Если функции лежат в нужных модулях, то ничего больше делать не надо.

avatar
Михаил, json стоит из нескольких блоков:
— что нужно сделать, чтобы сгенерировать признаки
— как и с какими параметрами строится обучающий алгоритм
— как и с какими параметрами осуществляется обучение.
avatar
Михаил, соответсвенно я могу простым вызовом:
— сохранить соответсвующий json
— загрузить json, обучить модель, сохранить обученную модель с указанием метаданных обучения — на каких инструментах и временных интервалах
— загрузить модель и часть json с описанием признаков и сделать предсказание для конкретной даты

avatar

Михаил, я в формате sklearn_pipeline это делаю.

 

Ну я понял, короч, у вас единое пространство, единый проект. У меня пространство для рисеча отдельное, более того, разный стек — рисеч это юпитер ноутбук, а торгует проект на питоне обычный.

 

По сути да, это одно и то же, только я как бы сами функции тоже упаковываю в пайплайн, а не ссылаюсь на них и параметры передаю.

avatar
Replikant_mih, я юпитер не люблю — в нем код имеет тенденцию в хлам превращаться. Сразу py файлы пишу. 

Упаковываю это просто красивое слово — sklearn_pipeline за вас хранит ссылки на функции и параметры, и ничего он не упаковывает.

Внутри sklearn_pipeline хранит всего один атрибут — список кортежей (название шага, функция/класс шага, передаваемые параметры).

А основной метод по существу сводится к циклу — пройдись по списку вызови класс с соответсвующими аргументами, печатай в лог название шага. 

Я этот цикл сам написал. Так как вы не лезете внутрь sklearn_pipeline, то видимо делаете pickle класса. Так как я имею доступ внутрь своего класса, мне легче список кортежей сохранить в виде json, но при желании могу сделать и pickle.

Просто pickle не удобен тем, что он бинарный и не понятный. Вот лежит он на диске, а чего там внутри. А json в человеко читаемом виде — собственно тот самый перечень шагов и параметров. 

Плюс я не заперт в классах sklearn, а они не очень ложатся на сети. 
avatar

Михаил, нуу да, возможно юпитер более склонен к хаосу), но усилием воли всегда можно разруливать, у меня в юпитере всякие надстройки стоят — как то сворачивание разделов и т.д. + я организацией кода играюсь — у меня все аккуратно щас получается довольно-таки), но да, иногда задумываюсь рисечить в IDE.

 

>> «Упаковываю это просто красивое слово — sklearn_pipeline за вас хранит ссылки на функции и параметры, и ничего он не упаковывает»

Ну окей, а гиде тогда сами функции?)) Я на другую машину переношу только пайплайны. Она знать не знает что я там нарисечил), единственное только надо обеспечить совместимость по версиям либ.

 

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

 

>>«Просто pickle не удобен тем, что он бинарный и не понятный. Вот лежит он на диске, а чего там внутри. А json в человеко читаемом виде — собственно тот самы перечень шагов и параметров. „

Да, есть такое, ну я то что нужно в название упаковываю, а остальное после чтения файла уже можно вытащить.

 

Короче, не агитирую, но мне нравится).

avatar
Replikant_mih, тут каждому свою.

Хотел для себя прояснить, потому, что звучит несколько странно

Ну окей, а гиде тогда сами функции?)) Я на другую машину переношу только пайплайны. Она знать не знает что я там нарисечил), единственное только надо обеспечить совместимость по версиям либ.

А как вы все-таки сохраняете пайплайн, потому что pickle надо иметь доступ к определениям всех типов для восстановления. В интернете народ тоже вроде жалуется, что не удается перетащить с кастомными функциями? Выскакивают ошибки из серии

AttributeError: module '__main__' has no attribute 'CustomTransformer'

На что рекомендуют:
You'll have to make your CustomTransformer class available in the new session, either by re-defining or importing it.

Каким образом вы эту проблему обходите?
avatar

Михаил, Сохраняю через либу dill — это какая-то обертка над pickle. 


Проблем при переносе при реализации было много, но все победил, из-за того что много — не помню, что конкретного делал, по ощущениям большая часть проблем была связана разницей версий библиотек и самого питона — все-таки виртуальная среда с одной стороны и анаконда с другой).

>>«AttributeError: module '__main__' has no attribute 'CustomTransformer'»

Что-то такое, вроде было, тоже победилось версиями либ вроде или чем-то аналогичным.

 

Хотя кастомные функции, не уверен, что я это использую, я вроде использую только переопределение стандартных методов fit и transform, но этого и хватает, функции нужны разве что для удобства. Да, чекнул — только эти использую.

avatar
Михаил, А у вас как с результатами применения ML в трейдинге? — А то мы все о процессе о процессе).
avatar
Replikant_mih, как сейчас стало модно говорить, ушёл на пенсию в 38:)
avatar
Михаил, Тоже надо бустануть, а-то скоро 38)). И как, ML сыграл значительную роль в этом? Или больше в качестве баловства?
avatar
Replikant_mih, я исключитель на DL сейчас. 
avatar
Михаил, Это же тот DL, о котором я думаю?) И в какие архитектуры посоветуете копать? Я пока из ML леса, бустинги юзаю — какой-то эдж вытаскивают. С DL только знакомлюсь, пока размышляю в сторону паттерны на графиках распознавать, ну и рекуррентные сама вселенная велит попробовать, в общем надо пробовать. 
avatar
Replikant_mih, я что-то похожее на WaveNet использую. Но чужой опыт, как мне кажется, редко помогает, лучше самому поэкспериментировать с учетом уже имеющихся наработок.
avatar

Михаил, А где же: «дружище, копай в сторону этой архитектуры… и вот этой, ну ладно, я сегодня выпивши: и вот в сторону вот этой  перспективной ещё копай»?)))

 

Похоже, действительно, заниматься дип-ленингом это сидеть вникать в такие вот научные работы на английском).

avatar
Replikant_mih, с DL действительно возни больше. ML выбрал модель дернул fit /predict и все готово. Думаешь, только над тем, как фичи придумать. А тут придётся руками сетку собирать (у меня где-то 300 строк), для чего полезно статьи почитать. Потом руками training loop пишешь еще несколько десятков строк. Ну и данные готовишь, как в обычном ML. В общем не факт, что в это стоит погружаться, если более простые методы устраивают. 
avatar

Михаил, Да, примерно такое впечатление о процессе и складывается. Пробовал вместо своих моделей на то же признаковое пространство применить нейросеть полносвязную — ничего конечно она интересней чем бустинг не нашла. Но конечно если там твиты анализировать, или паттерны графические распознавать или что-то такое — тут конечно только нейросети. 

 

Пока нейросети побудут на правах фундаментальных исследований, а статистические классические модели — на правах прикладных), дальше как пойдет).

avatar
Replikant_mih, Возможно повторяюсь, если признаки придумывать любите сами, то большого смысла в сетях нет. Нет смысла и в полносвязный сетях. Тут лучше бустинг использовать. 
В сети лучше котировки напрямую пихать, что-то странное типа твитов. 
avatar

Михаил, ага-ага. Как-то так. 

А признаки да, люблю придумывать), творческий процесс).

avatar
Чет как-то сумбурно. 1) Обычно пайплайн это не алгоритм, а последовательность обработки. Алгоритм — это частный случай узла графа пайплайна.
2) сделать абстрагирующий интерфейс которому на вход данные, а на выход сигнал — это лежит на поверхности. Вопрос только в какой форме подавать данные вместе с историей.

У меня так: алгоритм может сериализоваться/десериализоваться вместе со своим внутреннем состоянием. Ну то есть если ему положим надо 20 последних баров, то он сам должен внутри держать буфер. При таком подходе алгоритму надо на вход только очередной бар чтобы он его «усвоил» и выдал результат. Время от времени сериализованное состояние скидывается в БД. Если приложение рестартует, то восстанавливает состояние из БД и докидывает бары до последнего известного.
Не универсально, но под специфику моих алгоритмов подходит идеально.
avatar

ivanovr, Не знаю насчет сумбурно, по-моему четко стройно и ново)). Но это с моей колокольни так, может потому что не разраб.

1) В смысле не алгоритм?) Из кубиков, которые каждый алгоритм складываем тоже алгоритм)), если не алгортим то что? — Данные + алгоритм?) — ну может, хотя самого дата-фрейма пайплайн не содержит пока не зафичен.


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

avatar
Replikant_mih, я подход выбирал с учетом скорости моделирования на истории. Если на каждом шаге окно просматривать, то будет дольше, хотя и гибче. Потому инкрементальные алгоритмы в основном.
Про алгоритм: ясень что где там грань несколько размытая. Но сам пайплайн обычно это разновидность «орекстратора» задача которого в определенной последовательности вызвать собственно алгоритмы.
avatar
ivanovr, к вопросу о скорости моделирования, подумываю GPU привлечь для увеличения этой самой скорости).
avatar
ivanovr, И че, как моделям удается эдж находить в рыночных данных?) Насколько устойчивы результаты на OOS?
avatar
Replikant_mih, раньше было весело, сейчас вяло. Но уже 10 лет в игре и планирую продолжать (не лудоман ;).
avatar
ivanovr, ага, ясн, и с ML давно? — Или про ML никто и не говорил и это я между строк прочитал).
avatar
Replikant_mih, смотря что называть ML, так то ничего нового. Тупой оптимизатор.
avatar
ivanovr, ну там бустинги, леса, дип-ленинг.
avatar
Replikant_mih, не, не использую.
avatar

теги блога Replikant_mih

....все тэги



UPDONW
Новый дизайн