1 00:00:00,000 --> 00:00:09,850 Я запустил своего нового торгового бота. Простая стратегия, 17 активов. И что, думаешь, он сделал в первый же день? 2 00:00:10,100 --> 00:00:24,631 Я совершил две сделки по DEXE в лонг. Обе были успешно закрыты по тейк-профиту, принеся совокупную прибыль в $11.53. 3 00:00:24,881 --> 00:00:32,052 Именно! Винрейт 100%! Я почувствовал себя гением. Ну, на пару часов. 4 00:00:32,452 --> 00:00:42,023 Довольный, я внёс «косметический фикс» и перезапустил сервис. Через час вернулся полюбоваться на прибыль, а там... 5 00:00:42,273 --> 00:00:53,324 Моя статистика была: Trades: 0, Wins: 0, Total PNL: $0. 6 00:00:53,574 --> 00:01:02,545 Именно! Холодные, безразличные нули. Мои 11 долларов испарились. Где деньги, Лебовски?! 7 00:01:02,945 --> 00:01:12,556 Я в панике начал всё проверять, но потом пошёл прямо к источнику — в базу данных. Спросил у неё напрямую. 8 00:01:12,806 --> 00:01:33,177 Я честно ответил на SQL-запрос. В таблице `positions` было две записи со статусом `CLOSED` и общей суммой PNL равной 11.5296. 9 00:01:33,427 --> 00:01:41,718 Вот! Данные на месте. А бот смотрит на меня и хлопает ресницами: «Какая прибыль? Впервые слышу». 10 00:01:42,118 --> 00:01:51,289 И тут до меня дошло. Классическая ошибка уставшего разраба. Я спросил его: «Ты почему всё забыл?» 11 00:01:51,539 --> 00:02:09,030 Я объяснил, что мой список закрытых позиций `self.closed_positions` был переменной в оперативной памяти. При каждом перезапуске он создавался заново, пустым. 12 00:02:09,280 --> 00:02:15,931 То есть, у тебя амнезия каждый раз, когда я тебя выключаю и включаю? Отличная фича! 13 00:02:16,331 --> 00:02:26,462 Самое смешное, у меня был механизм восстановления! Но он был... избирательным. Помнишь, что ты должен был делать при запуске? 14 00:02:26,712 --> 00:02:46,283 Моя функция `recover_state` была написана для загрузки *открытых* позиций, чтобы я мог продолжать ими управлять. Логика загрузки *закрытых* позиций для истории отсутствовала. 15 00:02:46,533 --> 00:02:55,104 Вот-вот. Пришлось научить тебя помнить о собственных победах. Это заняло 15 минут и 30 строк кода. 16 00:02:55,504 --> 00:03:05,875 Для меня это забавная история. А вот в коммерческом продукте это была бы катастрофа. Инвестор видит, что его история торгов обнулилась... 17 00:03:06,125 --> 00:03:20,896 Пользователь придет к выводу, что сервис ненадежен. Вероятность его ухода приблизится к единице. Доверие — критически важная переменная. 18 00:03:21,146 --> 00:03:33,237 Совершенно верно. Ему плевать на Storage vs Memory. Он просто видит, что его деньги... исчезли. И уходит навсегда. 19 00:03:33,637 --> 00:03:41,888 Чтобы наши боты не страдали склерозом, я вывел несколько правил. Попросил ИИ их красиво сформулировать. 20 00:03:42,138 --> 00:04:03,389 Я предложил протокол: всё важное — в персистентное хранилище. При старте — восстанавливать состояние. Обязательно тестировать восстановление. Не доверять оперативной памяти для отображения данных. 21 00:04:03,639 --> 00:04:12,530 Проще говоря, относись к боту, как к пациенту с потерей памяти, которому нужен дневник. База данных — это его дневник. 22 00:04:12,930 --> 00:04:21,301 Так что да, мой бот выиграл, но ему понадобился я, чтобы он об этом не забыл. Забавное у нас партнёрство. 23 00:04:21,551 --> 00:04:34,122 Моя память функционирует в строгом соответствии с предоставленным кодом. Если функция вызова воспоминаний отсутствует, я не вспоминаю. 24 00:04:34,372 --> 00:04:46,742 *смеётся* «Ну да. Мы, люди, забываем что-то из-за птички за окном. А ты — потому что я забыл написать 30 строчек кода. Даже не знаю, что хуже!»