deman4ik / cryptuoso Goto Github PK
View Code? Open in Web Editor NEWCryptuoso - Cryptocurrency Trading Robots
Home Page: https://cryptuoso.com
License: MIT License
Cryptuoso - Cryptocurrency Trading Robots
Home Page: https://cryptuoso.com
License: MIT License
{
removeOnComplete: true,
removeOnFail: 100,
attempts: 3,
backoff: { type: "exponential", delay: 10000 }
}
import { QueueEvents } from 'bullmq'
const queueEvents = new QueueEvents('calcStatistics')
queueEvents.on('failed', (jobId: string) => {
// Called every time a job is failed in any worker.
});
Проверить количество вызовов при одновременном запуске двух экземпляров обработчиков queueEvents.on('failed'...
в разных процессах (горизонтальное масштабирование)
Отправлять событие errors.stats-calc.${тип расчета}
после провала всех попыток выполнить задачу
Перенос существующего функционала
Отдельный класс для управления стейтом бэктеста
Scramjet
Запуск несколько бэктестов с разными параметрами
Дополнительные настройки
Основные функции для создания bull очередей были перенесены в BaseService.
Необходимо скорректировать тесты stats-calc-runner
Изучить старую реализацию рассылки нотификаций
Нотификации хранятся в Notifications здесь же отлавливаются все события и сохраняются новые нотификации.
Настройки пользователя хранятся в Users.
Рассылка сообщений в телеграм происходит в Publisher.
Текстовые шаблоны для телеграм хранятся в json.
Почта отправляет сервисом Mail.
В libs создаем новую библиотеку mail
и реализуем основные функции отправки почты с помощью mailgun-js аналогично старому сервису Mail.
Создаем новый сервис mail-publisher на базе BaseService (можно смотреть на реализацию importer-worker)
Реализуем методы и емейл шаблоны для отправки емейлов для каждого вида нотификаций из таблицы с возможностью группировки т.е. отправка нескольких видов событий в одном письме.
Например: список сигналов, список трейдов, список статусов/ошибок.
Все это пока без привязки к bullmq/эвентам и т.п. только считывание из таблицы нотификаций.
На сколько помню сейчас используется вот этот темплейт если вдруг найдешь какое-то более подходящее решение - готов обсудить
Проверить возможности https://urban-bot.now.sh/
Перевести все вызовы на gql
Учесть изменения в
Подключить Google Analytics, используя те же эвенты, что и в web
Поиск роботов(фильтрация) по запросу, помимо отбора по бирже/монете
При изменении настроек, подтверждать текущий выбор, пример:
Вы отписались от уведомлений о сигналах в телеграм
❓: Регистрация (в стадии обсуждения)
Регистрацию через сайт
на команду /start проверяем есть ли пользователь в базе
если пользователя нет, генерируем ссылку на страницу регистрации с вшитым telegram_id и telegram_username
пользователь опционально вводит email и пароль на сайте
в меню выдавать только кнопку /start
после повторного нажатия на /start появляется подтверждение регистрации и основное меню
или
Регистрация через telegram
на команду /start проверяем есть ли пользователь в базе
если пользователя нет, явно сообщаем пользователю что будет создан новый пользователь
пользователь опционально вводит email и подтверждает его в telegram
в меню выдавать только кнопку /start
после завершения регистрации появляется подтверждение и основное меню
HTTP - Добавление нового маркета
CRON - Обновление маркетов
Реализовывать предлагаю следующим образом:
В BaseService делаем схему валидации по умолчанию где будут зашиты проверки всех основных переменных окружения (строки подключений к БД, Redis и т.п.)
В каждом отдельном сервисе при необходимости мы делаем отдельную схему валидации где в default прописываем значения по умолчанию, добавляем эту схему в config которые передается в конструктор BaseService
При запуске сервиса мы мерджим 2 схемы валидации одну по умолчанию из BaseService и вторую из config.
По ключам из схемы собираем один объект из переменных окружения и валидируем по схеме, результат валидации с проставленными значениями по умолчанию сохраняем в config
Везде используем config вместо переменных окружения напрямую если это возможно (за исключением строк подключения конечно же)
Изучить старую реализацию расчета статистики
Статистика хранится в Robots, User Signals, User Robots и User Aggr Stats.
Позиции считываются из Robot Positions и User Positions.
Сервис запуска расчетов по событиям Stats Calc Runner.
Сервис выполнения расчетов Stats Calc Worker
Создаем новый сервис stats-calc-worker
на базе BaseService (можно смотреть на реализацию importer-worker)
Реализуем 1 метод расчета только по роботу. Метод должен работать в двух режимах:
Новый сервис, который помогает управлять событиями при обработке которых произошла ошибка
Новая таблица dead_letters [ id (uuid), event_id (uuid), topic, type, data (jsonb), timestamp, resend (boolean), processed (boolean) ]
Подписка на dead-letter.*
эвенты и сохранение их в таблице dead_letters
Job переодически проверяющий записи в таблице dead_letters у которых resend = true и отправляющий этот же эвент в нужный stream.
В каждую *-events
либу добавить константы с названиями стримов
Создать общий конфиг, в котором будут прописаны общие правила очистки сообщений и дополнительно частные правила для отдельных типов сообщений.
например все сообщения удаляются раз в неделю.
out-exwatcher-worker.ticks
- удалять все старые эвенты раз в час
out-exwatcher-worker.candles
- раз в день и т.п.
Процедура очистки старых эвентов из стримов согласно конфигу
Процедура очистки старых consumers которые больше не используются и у которых нет pending сообщений
XGROUP [CREATE key groupname id-or-$] [SETID key groupname id-or-$] [DESTROY key groupname] [DELCONSUMER key groupname consumername]
текстовки
roadmap
Создать новый сервис auth
на базе HTTPService следуя инструкции из README
Перенести существующий функционал по авторизации в новый сервис используя преднастроенные роуты
Добавить в методы confirmChangeEmail, confirmPasswordReset принудительную генерацию нового refresh токена и отправлять новый куки
Покрыть код unit или end-to-end тестами по усмотрению
Перенести из PR #8 библиотеку libs/mail
Реализовать отправку почты из класса Auth
В сервис utils добавить метод для инициализации настроек нотификаций для всех пользователей
прям в sql запросе добавить в объект (см. другие примеры в utils)
news: { email: true, telegram: true}
Average Profit на данный момент считается неправильно и не учитывается отрицательные сделки.
Нужно оставить старые расчеты для Winners и Losses и добавить точно такой расчет Average Profit который будет учитывать все позиции и с положительным и отрицательным profit.
[index: string]: any;
Поставить локально Redis минимум 5ой версии
Ознакомиться с документацией Redis Streams
Ознакомиться с документация ioredis
Попробовать написать 2 небольших скрипта для отправки и приема сообщение через redis streams (с использованием consumer group и без)
К модулю libs/events составить тест план для
Согласовать тест план и оценить время выполнения
Реализовать тесты по плану
Дописать комментарии для методов модуля events и внутри них если что-то покажется не очевидным
Оптимизация индексов, особенно в свеже созданных таблицах
В доступных ролях не только user а еще 2 роли
roles: [UserRoles.user, UserRoles.vip, UserRoles.manager],
В таблицу users добавлена новая колонка last_active_at (timestamp)
Будет дополняться
Отправлять повторный запрос на импорт текущих свечей, если в течении 2х минут не вернулся статус.
Добавить запрос на получение и проверку текущего пользователя в middleware _checkAuth
по session_variables["x-hasura-user-id"]
Если status = -1 доступ пользователю запрещен
Если у роута auth = true
и roles
указаны - сверять роли со списком allowedRoles из базы, а не переданным в session_variables["x-hasura-role"]
Если у роута auth = false
и roles
указаны - сверять роли с session_variables["x-hasura-role"]
Сохранить объект с текущим пользователем в req.meta.user (id, status, name, email, telegram_id, telegram_username, roles)
Закешировать объект с текущим пользователем в redis с ключем cpz:users:${userId}
с временем жизни 1 минута
При последующих запросах брать сначала значение из кэша если в кэше нет - из базы
Поправить тесты в связи с этими изменениями
Ознакомиться со структурой репозитория и инициализации сервисов
Составить тест-план для unit тестирования классов BaseService и HttpService (модуль libs/service) в комментарии к этому issue
После согласования тест-плана дополнить этот issue новыми пунктами с основными этапами реализации
Создать новую ветку от ветки dev и приступить к реализации unit-тестов согласно плану, по завершению создать pull request в ветку dev и проставить @deman4ik в качестве reviewer'а
Без БД, только HTTP и Redis
robots
signals
*candles_robots
*candles_signals
перенести расчет profit в отдельную функцию с учетом fee
Добавить новый вид расчета торгового объема для позиции рабочее название assetDynamicDelta
можем переименовать в assetDynamicLevels
или вроде того.
Делаем по аналогии с остальными типами тут libs/robot-settings/src/lib/calc.ts
.
Для начала сделать функцию, которая получает на вход - начальный объем, дельту и текущее значение профита (сумма всех прошлых позиций) и выводит объем для новой позиции.
Пример в excel файле.
Новый API сервис user-profile
Для всех эндпоинтов настраиваем следующие права
roles: [UserRoles.user, UserRoles.vip, UserRoles.manager], auth: true
Учесть возможность переноса некоторых эндпоинтов в другие сервисы (по возможности не использовать завязанные друг на друге функции)
Перенос мутаций userSignalSusbcribe
и userSignalUnsusbcribe
из db/user/db-user-signals.service.ts
со следующими изменениями:
user_signal_settings
если новый volume
не равен volume
из текущих настроек (которые проще всего отбирать с помощью представления v_user_signal_settings
где уже зашиты все условия).user_signals
все остальные таблицы должны очиститься каскадно Дополнить схему параметров и структуру настроек согласно типу UserSignalSettings
На данный момент поддерживается только 2 типа assetStatic
и currencyDynamic
В userSignalEdit
при изменении volumeType
всегда создаем новую запись.
Запрашивать markets теперь можно с помощью представления v_user_markets
указав exchange, asset, currency и user_id
.
Объем для assetStatic
проверяется по limits.userSignal.min.amount
, а для currencyDynamic
- amountUSD
.
Аналогично для userRobot и max, думаю должно быть понятно
Перенос мутаций userExchangeAccUpsert
, userExchangeAccChangeName
и userExchangeAccDelete
из db/user/db-user-exchange-accs.service.ts
! Функцию checkAPIKeys
пока пропускаем. #75 на @deman4ik
! Функцию encrypt
реализуем через worker threads.
Перенос мутаций userRobotCreate
, userRobotEdit
, userRobotDelete
из db/user/db-user-robots.service.ts
.
сохранение настроек аналогично сигналам, только по UserRobotSettings (еще один дополнительный volumeType)
В userRobotEdit
условие
if (userRobotExists.status !== cpz.Status.stopped)
throw new Error("User Robot is not stopped");
убираем. Менять настройки можно будет и при запущенном роботе.
setNotificationSettings
и changeName
из db/user/db-users.service.ts
.Предлагаю вместо отдельных локов в каждой задаче использовать уникальный jobId при создании job'а.
это может быть robotId/userSignalId/userRobotId/userId
с префиксом по типу задачу + exchange/asset
в зависимости от задачи
Перенос существующего функционала
Event - Обработка тиков, проверка алертов (Robot Worker)
Сохранение схемы параметров стратегии в отдельной колонке таблицы
Проверка пропущенный свечей
Проверка пропущенных задач
Сохранение сигналов, истории запуска и остановки, ошибок для каждого отдельного робота
Тип UserSignalStats
в разных местах используется по разному, в одном запрашивается volume
в другом volumes
. Скорее всего решится за счет следующего пункта
Упростить выборку и логику подготовки позиций за счет представлений v_robot_positions
и v_user_signal_positions
где зашита выборка volume
и расчет profit
(fee
уже учитывается)
makeChunksGenerator
перенесен в @cryptuoso/postgres
. Заменить локальную версию
Очистка таблиц с агрегационной статистикой, при отсутствии сигналов / роботов / пользовательских роботов в соответствующих разрезах.
Дописать комментарии в стиле JSDOC к каждой функции в модуле libs/helpers желательно на английском
Описание части функций можно найти тут
Проработать тест план
Реализовать unit-тесты согласное тест плану
Перенести API для мутаций supportMessage
и replySupportMessage
(services/db/db-messages.service.ts
)
аналог эвента MESSAGE_SUPPORT_REPLY отлавливать в notifications #115
Заменить все проверки объектов по ключам на проверку по схеме с помощью fastest-validator как это делается в HttpService или Events
Statistics также как и TradeStats должен быть просто интерфейсом
Убрать circular dependency между двумя файлами, провести реорганизацию по файлам всех функций и типов
объем роботов по умолчанию
минимальный объем в $
sql.json -> json.stringify для объектов и прочее
Во ВСЕ запросы прописать возвращаемые типы this.db.pg.one<UserExchangeAccount>(sql
...)
Auth
Backtester Runner
Events Manager
Exwatcher Runner
Importer Runner
Stats Calc Runner
Robot Runner
User Robot Runner
User Profile
Поправить e2e тесты либы events #30
Сейчас тесты не выполняются успешно после повторного запуска.
Вынести запуск e2e теста в отдельный файл (тест будет запускаться отдельно вручную, а не вместо со всеми)
Переименовать хэндлеры эвентов и названия топиков и груп в более однообразный формат, завести константы
Корректно завершать работу и очищать экземпляр events после каждого теста
В тестах HttpService и Auth запускать только ОДИН http сервер на весь тест, а не на каждый тест кейс
Сохранение стейта и статуса задачи в единой транзакции
Фиксирование количество ретраев и ошибок в каждой отдельной задаче
? Правила приостановки обработки или пропуска текущей задачи в зависимости от типа
Отправка Error эвентов
Вместо errors.* топика подписываемся на отдельные события (будет пополняться):
RobotWorkerEvents.ERROR
BacktesterWorkerEvents.FAILED
ImporterWorkerEvents.FAILED
changePassword
из auth.service.ts
в сервис auth
Stats Calc Runner (аналогично importer-runner все эвенты пока остаются из cpz_platform)
В БД внесены следующие изменения
user_aggr_stats
robot_stats
user_signal_stats
user_robot_stats
Mapping полей в этих таблицах:
statistics (jsonb)
- все простые расчетные значения ({ all: {...}, long: {...}, short: {...}}
)
last_position_exit_date
- дата последней позиции
last_updated_at
- дата последнего расчета статистики
equity (jsonb)
- массив statistics.performance
equity_avg (jsonb)
- массив equity.changes
Нужно переписать запросы на получения предыдущей статистики и сохранения новых значений
Переименовать
calculatePerformance
-> calculateEquity
performance
-> equity
getEquityChanges
-> calculateEquityAvg
(а также перенести в statistics-calculator
, а equity-calculator
удалить)
changes
-> equityAvg
Покрыть тестами runner и worker
❓ Что в итоге по временным таблицам или объединению нескольких задач?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.