В продолжение двух предыдущих статей о вопросах, требующих внимания в программной торговле:
Жесткие галантерейные товары - подробности и мысли об автоматизированной торговле количественными торговыми системами в реальном времени (1. Проблемы и трудности)
Количественная торговая система - автоматизированная информация и мысли о твердом предложении (2. Цель твердого предложения)
Здесь мы продолжим говорить о некоторых подробных навыках работы с кодом.
база данных
Как упоминалось в двух предыдущих статьях, запись статуса более сложной комбинации стратегий очень важна и требует использования базы данных.
Фактически, большинство компаний, занимающихся программированием, можно отнести к категории CRUD, то есть основной процесс — это просто добавление, удаление, изменение и проверка базы данных. Торговые коды не являются исключением. Средне- и низкочастотное торговое поведение на вторичном рынке на самом деле мало чем отличается от того, когда люди ходят за покупками определенного сокровища. Они одновременно покупают и продают. Цель автоматической торговли заключается в управлении стратегическим статусом.
Если вы еще не знакомы с реляционными базами данных, такими как SQL, рекомендуется напрямую научиться использовать базы данных NoSQL в памяти, такие как Redis. Его преимущества заключаются в том, что его легко начать, он имеет отличную производительность и по своей сути является однопоточным. Нет необходимости рассматривать низкоуровневые операции, такие как блокировка данных при чтении и записи. Однако недостатком является отсутствие первичного ключа и невозможность реализации таких функций, как автоматическое увеличение номера. При необходимости вам придется написать код для его реализации самостоятельно. Однако я никогда так долго не использовал эту функцию в автоматической торговле.
Еще одна неважная проблема заключается в том, что для баз данных в памяти, если объем данных, которые необходимо хранить, относительно велик, то память сервера должна быть больше. Однако для общей количественной торговли достаточно и 4G или даже 2G памяти. Сохранять так много данных не нужно.
Redis действительно эффективен в реальном мире. Если ваша стратегия требует высокой частоты, она также может реализовать модель подписки на сообщения «публикация/подписка», устраняя необходимость добавления различных дополнительных модулей MQ. Если вы используете реляционную базу данных, такую как MySQL, как упоминалось ранее, до тех пор, пока вы раньше не использовали ее на практике, вам придется потратить время и силы на изучение SQL, относительно отвратительного и сложного языка программирования. Обратите внимание, что все здесь для того, чтобы заниматься количественной торговлей, а не для того, чтобы научиться писать код. Попробуйте использовать более простое решение.
Кроме того, если вы хотите построить рыночный центр, учитывая производительность, вы также будете использовать базу данных Redis и для удобства взаимодействовать с очередью сообщений. Решение простое и подходит для большинства сценариев. Можно использовать один сервер (или несколько серверов).
дизайн кода
По сути, при написании кода основная структура данных является наиболее важной. Конструкция структуры данных недостаточно разумна, и код будет написан неуклюже, поскольку это неизбежно приведет к объединению различных модулей, что сделает внесение изменений очень затруднительным. Но чтобы его правильно спроектировать, нужен некоторый опыт торговли, то есть опыта ведения бизнеса. Это все о том, как писать код, здесь особо нечего сказать. Стратегии у всех разные, и к ним нельзя относиться одинаково. Однако некоторые принципы, вероятно, одинаковы.
Например, после подачи заявки нет гарантии успеха, даже если это рыночная заявка, поскольку она может быть отклонена биржей. Например, обмен слишком занят или произошла временная потеря пакетов сетевых данных. Затем лучше всего спроектировать несколько промежуточных состояний, подобных 2-фазной фиксации. Если это не удается, продолжайте попытки (конечно, не слишком часто, иначе они будут запрещены, если превысят лимит. Для этого существует специальный декоратор повторных попыток). или добавьте дополнительный метод для исправления состояния ошибки.
В обычных обстоятельствах, даже если биржа выйдет из строя, она быстро восстановится. Если не восстановиться, то одна сторона полностью выйдет из строя, либо биржа, либо ваш собственный сервер кода. За этим нужно следить и предупреждать. Автоматический код не может охватить все. Если он не может быть обработан автоматически, потребуется ручное вмешательство. Если ручная обработка не будет выполнена вовремя, пока мы не продолжим открывать позиции для увеличения риска, проблема не будет слишком большой, поскольку существуют алгоритмические стоп-лоссы для покрытия дна.
Ниже представлена логика открытия стратегии, с которой я разобрался сам:

По сути, нарисовав подобную блок-схему, код станет гораздо более организованным, а количество потенциальных ошибок уменьшится. Поэтому перед написанием кода лучше всего нарисовать блок-схему или разобраться в ней во время написания, чтобы логика была понятна и у вас была идея.
Логика закрытия позиции гораздо сложнее, поскольку существует больше условий закрытия позиции, таких как стоп-профит, стоп-лосс и сигналы выхода различных стратегий, которые инициируют закрытие позиции. Короче говоря, важность выхода выше, чем входа, и реальное предложение также немного более проблематично.
Поскольку логика стратегии у всех разная, я не буду здесь вдаваться в подробности. Главное — выправить свою стратегическую логику и не допустить различных возможных ошибок.
Однако они кажутся сложными и представляют собой всего лишь набор if elses (в Python нет даже оператора переключения). Если условия соблюдены, перейдите к следующему шагу. Если нет, выйдите. Никаких больших проблем.
Контроль времени
При совершении транзакций время, несомненно, очень важно. Здесь я поделюсь еще некоторыми своими навыками контроля времени.
В общем программировании, если есть задачи, которые необходимо выполнять регулярно, обычно используются пакеты заданий cron, такие как apscheduler. Например, запланируйте запланированную задачу, чтобы определить, должна ли цена K-линии открыть или закрыть позицию, как только наступит час.
Пакет такого типа фактически сразу открывает новый поток в заданное время (может быть с точностью до второго уровня), а затем выполняет указанную задачу. Проблема в том, что если время выполнения этой задачи слишком велико, то выполняется следующая задача. начнутся снова. Будут проблемы, хотя их можно решить, но они более хлопотные.
Обычно я использую такие запланированные задачи, когда мне нужно регулярно выводить информацию журнала и выполнять самокоррекцию и самотестирование программы, которые представляют собой низкочастотные функции, которые можно выполнить быстро. Эти функции только читают данные в базе данных, без операций записи или обновления, поэтому не помешает позволить аппланировщику открыть другой поток для обработки.
Однако логика, которая требует постоянного и частого запроса рыночных цен или статуса местной политики, не подходит для такого пакета синхронизации и должна управляться циклом while.
Например, если в стратегии используются сигналы внутри бара К-линии, это означает, что сигнал может появиться в любой момент, и вам необходимо постоянно проверять цену базового актива или объем торгов, чтобы определить, нужно ли совершать соответствующие операции. Например, если в это время вам нужен более точный контроль времени, выполняйте только последовательную логику открытия позиции за 10 секунд до окончания часа k-линии. Так как же можно просто судить, действительно ли это последние 10 секунд?
Оставшуюся часть 3600 я взял, используя метку времени.
(Если вы не знакомы с меткой времени на компьютере, то есть меткой времени, она начинается со среднего времени по Гринвичу 1970.1.1. Например, это примерно 1691240298-я секунда. Нет проблем с тем, чтобы компьютер был точен до микросекундный уровень.)
После взятия остатка от 3600, если остаток превышает 3590 секунд, это последние десять секунд. Ошибка может достигать миллисекунд. Как упоминалось ранее, лучше всего, чтобы основные операции транзакции выполнялись последовательно в одном потоке. Таким образом можно грубо контролировать время выполнения или размыть временной период, что не составит проблемы.
Этот вид контроля требует, чтобы настройка времени вашего собственного сервера не сильно отклонялась от стандартного времени. Однако такой контроль не будет очень точным, он может достигать только второго уровня. Однако Python не может очень точно контролировать время, и эти функции сна будут вызывать ошибки примерно в микросекундах.
Уменьшите частоту доступа к API
Если вы внедрили независимый рыночный центр на основе веб-сокета для обмена общедоступной рыночной информацией, такой как K-линии, между различными стратегиями или даже разными торговыми кодами, то в этом отношении ограничения частоты API не беспокоят.
Но нам также необходимо своевременно получать информацию о счете, то есть три типа информации: средства, позиции и ордера. Хотя информация об учетной записи также может использовать веб-сокет и ждать, пока сервер обмена активно ее отправит, проще напрямую использовать остальные API по трем причинам.
Во-первых, чтобы снизить нагрузку на информацию об учетной записи, передаваемую через веб-сокет, биржа требует, чтобы биржа время от времени переподключалась или обновляла ListenKey (Binance — 60 минут). Эту ситуацию, очевидно, труднее поддерживать. Хотя это не так уж и сложно, если вы используете API-хостинг и одновременно торгуете несколькими учетными записями, вам необходимо активировать отдельную программу, чтобы обеспечить точность информации в реальном времени, и логика становится намного сложнее.
Во-вторых, на некоторых биржах нет поддержки веб-сокетов для обновления информации об аккаунте. В этом случае торговая логика не универсальна, и переключать реальные торговые коды между разными биржами сложнее. Конечно, большинство людей не будут торговать на нескольких биржах и не столкнутся с такой ситуацией.
В-третьих, если ссылка на веб-сокет не работает или возникают проблемы, такие как обновление или истечение срока действия ListenKey, упомянутое ранее, если программа не обнаруживает его вовремя, и в это время происходит транзакция, то если вы полагаетесь только на веб-сокет, это вызовет большую проблему при сравнении, поскольку информация о пропущенном обновлении учетной записи не будет отправлена повторно. Чтобы избежать возможности таких потенциальных проблем, вы также должны полагаться на остальные API для получения определенной информации об учетной записи. Так что, в конце концов, вам придется полагаться на остальные API, разве это не излишне?
Таким образом, для средне- и низкочастотных транзакций лучше напрямую использовать rest API для получения информации об аккаунте. Для важных источников данных лучше всего использовать SSOT (единый источник истины), иначе это может привести к путанице. Эту концепцию можно найти в Google самостоятельно, и она очень полезна в программировании, основанном на обработке данных.
Затем, если вы используете REST API только для получения информации об учетной записи, вы можете поддерживать временную таблицу информации об учетной записи в локальной памяти кода, особенно о доступных средствах. Это может сократить частые посещения биржи. Главное, чтобы это было быстро и эффективно. вы можете отправить все заказы одновременно. Аналогично размещению заказов партиями с последующей медленной обработкой логики обновления: чем быстрее будет размещен заказ, тем меньше будет проскальзывание.
Кроме того, чтобы определить, исполнен ли алгоритмический стоп-лосс, вы можете использовать недавние максимальную и минимальную цены вместо непосредственного получения статуса отложенного ордера, поскольку для определения того, исполнен ли ордер, необходимо опросить постоянно, что происходит относительно часто и приводит к большому количеству недействительных доступов к API. Обновление цен на веб-сокеты K-line является очень своевременным и не требует ограничения частоты API.
Таким же образом могут быть и некоторые приказы на выход. Если ваш сигнал выхода зависит от цены внутри бара, возможно, лучше использовать недавние максимум и минимум цены. Поскольку иногда цена срабатывает и возвращается немедленно, если ваша частота проверок не слишком высока, вы можете ее пропустить. Чтобы обеспечить последовательность в вашей торговой стратегии, проверяйте максимум и минимум, чтобы не пропустить цены. Дополнительным преимуществом этого подхода является то, что фактическая цена сделки может быть более выгодной, чем реальная триггерная цена.
Я не знаю, легко ли понять два вышеуказанных пункта. Это может потребовать некоторого реального опыта.
Я хотел бы поделиться своим опытом разработки реального кода, надеюсь, он будет полезен всем.