neuroalpha 0.6.12 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +14 -10
  2. package/bin/cli.js +79 -69
  3. package/docs//320/230/320/235/320/241/320/242/320/240/320/243/320/232/320/246/320/230/320/257.md +2 -2
  4. package/package.json +4 -5
  5. package/public/activate.html +41 -19
  6. package/public/activate.js +81 -10
  7. package/public/app.js +300 -152
  8. package/public/index.html +4 -37
  9. package/server/api/routes.js +570 -906
  10. package/server/auth/index.js +576 -761
  11. package/server/brokers/index.js +1 -4
  12. package/server/config.js +73 -53
  13. package/server/index.js +186 -187
  14. package/server/llm/local-engine.js +843 -0
  15. package/server/llm/providers.js +45 -34
  16. package/server/model/dataset.js +2 -4
  17. package/server/model/forecast.js +1 -3
  18. package/server/news/index.js +2 -3
  19. package/server/notify/index.js +304 -466
  20. package/deploy/docs/01-central.md +0 -96
  21. package/deploy/docs/02-cloud-instances.md +0 -130
  22. package/deploy/docs/03-desktop-build.md +0 -92
  23. package/deploy/docs/04-client-guide.md +0 -101
  24. package/deploy/docs/05-operations.md +0 -109
  25. package/deploy/docs/06-env-reference.md +0 -91
  26. package/deploy/docs/07-stress-test.md +0 -253
  27. package/deploy/docs/pdf/01-central.pdf +0 -0
  28. package/deploy/docs/pdf/02-cloud-instances.pdf +0 -0
  29. package/deploy/docs/pdf/03-desktop-build.pdf +0 -0
  30. package/deploy/docs/pdf/04-client-guide.pdf +0 -0
  31. package/deploy/docs/pdf/05-operations.pdf +0 -0
  32. package/deploy/docs/pdf/06-env-reference.pdf +0 -0
  33. package/deploy/docs/pdf/07-stress-test.pdf +0 -0
  34. package/deploy/install.sh +0 -128
  35. package/deploy/k8s/instance.yaml +0 -147
  36. package/public/admin.html +0 -604
  37. package/public/landing.html +0 -1207
  38. package/public/legal.html +0 -134
  39. package/scripts/set-admin-password.mjs +0 -30
  40. package/server/billing/yookassa.js +0 -142
  41. package/server/instance/agent.js +0 -259
  42. package/server/instance/central.js +0 -514
  43. package/server/instance/identity.js +0 -79
  44. package/server/instance/provision.js +0 -166
  45. package/server/instance/signing.js +0 -71
  46. package/server/role.js +0 -44
@@ -1,96 +0,0 @@
1
- # Развёртывание центрального сервера
2
-
3
- Центральный сервер (`NEUROALPHA_ROLE=central`) — единственная точка, которую видит клиент до подключения. На нём работают:
4
-
5
- - лендинг, регистрация и вход (email, OAuth, Telegram/MAX), оплата ЮKassa, оферта;
6
- - личный кабинет клиента с блоком «Где работать»;
7
- - консоль администратора `/admin`;
8
- - ИИ-прокси для машин клиентов (`/api/llm/proxy/v1`);
9
- - реестр машин клиентов, выпуск подписанных лицензий и автоматическое развёртывание облачных машин;
10
- - боты Telegram и MAX: уведомления с машин клиентов уходят через центр.
11
-
12
- Торговый терминал на центре тоже открывается (для владельца), но клиенты торгуют на своих машинах.
13
-
14
- ## 1. Требования
15
-
16
- | Ресурс | Значение |
17
- |---|---|
18
- | Образ | собирается из `Dockerfile` в корне репозитория (`node:22-bookworm-slim`, запуск не от root) |
19
- | Реплики | **строго 1**, стратегия `Recreate` — база SQLite не допускает двух процессов |
20
- | Том | PVC от 10 ГБ, монтируется в `/data` (база, ключи, лицензии) |
21
- | CPU / память | от 1 vCPU / 2 ГБ (обучение модели для собственного терминала владельца — до 4 ГБ) |
22
- | Сеть | входящий HTTPS через ingress на `neuroalpha.odant.org`; исходящий доступ к Мосбирже, брокерам, моделям ИИ, Telegram/MAX, ЮKassa |
23
- | WebSocket | путь `/ws`, тайм-ауты прокси не меньше 3600 с |
24
- | Проверка живости | `GET /healthz` → `{"ok":true,"role":"central"}` |
25
-
26
- ## 2. Обязательные переменные
27
-
28
- | Переменная | Значение |
29
- |---|---|
30
- | `NEUROALPHA_ROLE` | `central` |
31
- | `NEUROALPHA_DATA_DIR` | `/data` (в образе уже задано) |
32
- | `CENTRAL_PUBLIC_URL` | `https://neuroalpha.odant.org` — публичный адрес центра, его получают машины клиентов |
33
- | `MASTER_KEY` | случайная строка 32+ символов: шифрует токены ботов, ключи ЮKassa, OAuth и LLM в базе |
34
- | `LICENSE_SIGNING_KEY` | закрытый ключ подписи лицензий Ed25519 (PEM), см. раздел 3 |
35
-
36
- Полный список — в документе «Справочник переменных окружения».
37
-
38
- > **Если `MASTER_KEY` не задан**, ключ создаётся в `/data/.master.key`. Потеря этого файла означает потерю всех сохранённых в базе секретов (их придётся ввести заново в админке).
39
-
40
- ## 3. Ключ подписи лицензий — самое ценное на центре
41
-
42
- Им центр подписывает лицензии и одноразовые ссылки входа. Машины клиентов проверяют подпись открытым ключом.
43
-
44
- **Первый запуск.** Если `LICENSE_SIGNING_KEY` не задан, центр создаёт ключ в `/data/.license-ed25519.pem` и пишет об этом в журнал. Сразу после первого запуска:
45
-
46
- ```
47
- kubectl cp <namespace>/<pod>:/data/.license-ed25519.pem ./license-ed25519.pem
48
- kubectl create secret generic neuroalpha-central-keys --from-file=LICENSE_SIGNING_KEY=./license-ed25519.pem
49
- ```
50
-
51
- Подключите Secret к переменной `LICENSE_SIGNING_KEY`, удалите локальную копию и сохраните резервную копию ключа в хранилище секретов (не в git).
52
-
53
- **Открытый ключ** отдаётся всем: `GET https://neuroalpha.odant.org/api/public/license-key`. Он нужен при сборке версии для компьютера и вписывается в Secret каждой облачной машины.
54
-
55
- | Что случилось | Последствия | Действия |
56
- |---|---|---|
57
- | Ключ потерян | новые лицензии не проверяются ни одной машиной; через 72 ч все машины приостановят новые заявки | создать новый ключ, обновить `LICENSE_PUBLIC_KEY` во всех облачных машинах («Новый ключ» в админке при включённом развёртывании), пересобрать и разослать версию для компьютера |
58
- | Ключ утёк | злоумышленник может подписать себе лицензию на любой тариф | те же действия, что при потере, — немедленно |
59
-
60
- ## 4. Вход администратора
61
-
62
- Администратор платформы — пользователь №1. На центре вход без пароля отключён, поэтому после первого запуска задайте email и пароль:
63
-
64
- ```
65
- kubectl exec -it deploy/neuroalpha-central -- env ADMIN_PASS='длинный-пароль' node scripts/set-admin-password.mjs --email admin@neuroalpha.odant.org
66
- ```
67
-
68
- Скрипт завершает все прежние сессии администратора. Пароль — не короче 10 символов; после 8 неудачных попыток вход по этому email и IP блокируется на 15 минут.
69
-
70
- ## 5. Ingress и адрес клиента
71
-
72
- - Центр считает адресом клиента **последний** IP в `X-Forwarded-For` (его добавляет ваш ingress). Ingress должен добавлять этот заголовок; иначе ограничение попыток входа будет общим для всех.
73
- - Заголовок `Host` должен передаваться без изменений: по нему проверяется `Origin` запросов (защита от CSRF).
74
- - Cookie сессии ставится с флагом `Secure`, если ingress передаёт `X-Forwarded-Proto: https`.
75
-
76
- ## 6. Боты, оплата и вход через OAuth
77
-
78
- Настраиваются в `/admin` (значения шифруются `MASTER_KEY`) или переменными `TELEGRAM_BOT_TOKEN`, `MAX_BOT_TOKEN`, `YOOKASSA_SHOP_ID`, `YOOKASSA_SECRET_KEY`. Webhook ЮKassa: `https://neuroalpha.odant.org/api/billing/yookassa/webhook`.
79
-
80
- Вебхук MAX по умолчанию **выключен** (обновления забираются опросом). Чтобы включить, задайте `MAX_WEBHOOK_SECRET` и передайте этот же секрет при подписке бота — центр проверяет заголовок `X-Max-Bot-Api-Secret`.
81
-
82
- ## 7. Модель ИИ для клиентов
83
-
84
- Машины клиентов обращаются к ИИ только через прокси центра по API-ключу клиента из лицензии. Апстрим-модель центра задаётся переменными `LLM_PROVIDER`, `LLM_BASE_URL`, `LLM_MODEL`, `LLM_API_KEY` или в разделе «Модели ИИ» терминала администратора. Дневные лимиты запросов — по тарифу (`maxChatPerDay`).
85
-
86
- ## 8. Резервное копирование
87
-
88
- Ежедневно копируйте том `/data` целиком: `trading.db`, `trading.db-wal`, `.master.key`, `.license-ed25519.pem` (если ключ ещё не вынесен в Secret). Для согласованной копии SQLite делайте снимок тома или `sqlite3 trading.db ".backup /backup/trading.db"`.
89
-
90
- ## 9. Проверка после развёртывания
91
-
92
- 1. `GET /healthz` отвечает `role: central`.
93
- 2. `GET /api/public/license-key` отдаёт `-----BEGIN PUBLIC KEY-----`.
94
- 3. Вход в `/admin` по паролю из шага 4.
95
- 4. Вкладка «Машины клиентов» открывается; в журнале центра строка «Развёртывание машин клиентов: автоматически (PAAS_DRIVER=…)» или «вручную».
96
- 5. Тестовый клиент с тарифом «Профи» в течение 2–3 минут получает облачную машину (см. документ «Облачные машины клиентов»).
@@ -1,130 +0,0 @@
1
- # Облачные машины клиентов
2
-
3
- Облачная машина — отдельный namespace в Kubernetes с одним подом НейроАльфа в режиме `NEUROALPHA_ROLE=instance`, `INSTANCE_KIND=cloud`. Адрес — `naXXXXXX.odant.org`. На машине хранятся база клиента, его зашифрованные токены брокера, считается прогноз и исполняются заявки. С центром машина связывается только исходящими запросами.
4
-
5
- ## 1. Жизненный цикл
6
-
7
- 1. Клиент оплачивает тариф «Инвестор» или «Профи» (или получает его промокодом либо в админке).
8
- 2. Не позже чем через 2 минуты центр создаёт запись машины `naXXXXXX` и вызывает драйвер развёртывания.
9
- 3. Под стартует, раз в минуту отправляет в центр техническое состояние и получает подписанную лицензию на 72 часа.
10
- 4. Клиент в кабинете нажимает «Перейти в терминал»: центр выдаёт одноразовую ссылку входа (60 с), машина ставит сессию на 7 дней.
11
-
12
- Автоматически машина **не создаётся**:
13
-
14
- - администраторам;
15
- - тарифу VIP: облако или компьютер назначаются по договору вручную в админке;
16
- - клиенту, у которого уже есть любая машина, в том числе с завершённой арендой.
17
-
18
- Состояния развёртывания в админке:
19
-
20
- | Состояние | Значение |
21
- |---|---|
22
- | ожидает развёртывания | запись создана, драйвер ещё не вызван |
23
- | разворачивается… | идёт вызов драйвера |
24
- | развёрнута, ждём связь | драйвер ответил успешно, под ещё не вышел на связь |
25
- | (пусто) | машина на связи |
26
- | ошибка развёртывания | текст ошибки — во всплывающей подсказке; центр повторит через 2 минуты с новым ключом |
27
-
28
- ## 2. Драйвер развёртывания: `PAAS_DRIVER`
29
-
30
- ### `none` (по умолчанию) — вручную
31
-
32
- 1. В `/admin` → «Машины клиентов» выберите клиента и тип «☁ Облако», нажмите «Создать машину».
33
- 2. Скопируйте переменные (показываются **один раз**) в Secret и примените шаблон `deploy/k8s/instance.yaml`, заменив `na235412` на ID машины:
34
-
35
- ```
36
- sed 's/na235412/naXXXXXX/g' deploy/k8s/instance.yaml | kubectl apply -f -
37
- ```
38
-
39
- ### `k8s` — напрямую через API Kubernetes
40
-
41
- Центр применяет объекты методом server-side apply (`fieldManager=neuroalpha-central`). Внутри кластера используется токен сервисного аккаунта пода центра; снаружи — `K8S_API_URL`, `K8S_TOKEN`, `K8S_CA_FILE`.
42
-
43
- Права сервисного аккаунта центра (ClusterRole):
44
-
45
- ```yaml
46
- apiVersion: rbac.authorization.k8s.io/v1
47
- kind: ClusterRole
48
- metadata: { name: neuroalpha-provisioner }
49
- rules:
50
- - apiGroups: [""]
51
- resources: [namespaces]
52
- verbs: [get, create, patch, delete]
53
- - apiGroups: [""]
54
- resources: [secrets, persistentvolumeclaims, services]
55
- verbs: [get, create, patch, delete]
56
- - apiGroups: [apps]
57
- resources: [deployments]
58
- verbs: [get, create, patch, delete]
59
- - apiGroups: [networking.k8s.io]
60
- resources: [ingresses, networkpolicies]
61
- verbs: [get, create, patch, delete]
62
- ```
63
-
64
- ### `webhook` — ваш PaaS
65
-
66
- Центр отправляет `POST` на `PAAS_WEBHOOK_URL`:
67
-
68
- ```json
69
- {
70
- "action": "apply", // или "delete"
71
- "instanceId": "na235412",
72
- "host": "na235412.odant.org",
73
- "image": "registry.odant.org/neuroalpha:0.4.0",
74
- "env": { "NEUROALPHA_ROLE": "instance", "INSTANCE_KIND": "cloud", "INSTANCE_ID": "…",
75
- "INSTANCE_KEY": "na_inst_…", "CENTRAL_URL": "…", "CLOUD_URL": "…", "LICENSE_PUBLIC_KEY": "-----BEGIN…" },
76
- "manifests": [ /* 7 объектов Kubernetes, как в deploy/k8s/instance.yaml */ ],
77
- "ts": 1792679474163
78
- }
79
- ```
80
-
81
- Заголовок `X-NA-Signature: sha256=<hex>` — HMAC-SHA256 от **сырого тела** запроса с ключом `PAAS_WEBHOOK_SECRET`. Проверка на стороне PaaS (Node.js):
82
-
83
- ```js
84
- const expected = 'sha256=' + crypto.createHmac('sha256', SECRET).update(rawBody).digest('hex');
85
- const ok = expected.length === sig.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
86
- // дополнительно: отклонять запросы, у которых |now - ts| > 5 минут
87
- ```
88
-
89
- Требования к обработчику:
90
-
91
- - ответ 2xx — успех, любой другой код — ошибка (будет повтор);
92
- - `apply` идемпотентен: создать или обновить все объекты. При смене `INSTANCE_KEY` под должен перезапуститься: в шаблоне пода для этого есть аннотация `neuroalpha/key-rev`;
93
- - `delete` удаляет namespace целиком **вместе с томом данных клиента**.
94
-
95
- ## 3. Состав машины
96
-
97
- | Объект | Назначение |
98
- |---|---|
99
- | Namespace `naXXXXXX` | изоляция клиента |
100
- | Secret `neuroalpha-instance` | переменные машины, в том числе ключ машины и открытый ключ центра |
101
- | PVC `neuroalpha-data` | `/data`: база, ключ шифрования токенов брокера, лицензия (`INSTANCE_STORAGE`, по умолчанию 5Gi) |
102
- | Deployment `neuroalpha` | 1 реплика, `Recreate`, запуск от UID 1000, `/healthz` для проверок живости и готовности |
103
- | Service + Ingress | `naXXXXXX.odant.org`, TLS из `INSTANCE_TLS_SECRET` (wildcard `*.odant.org`), тайм-ауты WebSocket 3600 с |
104
- | NetworkPolicy | входящие соединения — только из namespace ingress-контроллера |
105
-
106
- Исходящий доступ машине нужен к центру, `iss.moex.com`, API брокеров (`invest-public-api.tinkoff.ru` и др.) и источникам новостей.
107
-
108
- Ресурсы пода: запрос 0,5 CPU / 1 ГБ, предел 2 CPU / 3 ГБ. За первые сутки база вырастает примерно до 1 ГБ: загружается история котировок.
109
-
110
- ## 4. Управление из админки
111
-
112
- | Кнопка | Что происходит |
113
- |---|---|
114
- | ⏸ Пауза | новые заявки не отправляются, защитные стопы работают; применяется при следующей связи (до 1 мин) |
115
- | ⛔ Стоп | запрещены любые заявки, включая защитные стопы (аварийная остановка) |
116
- | ▶ Возобновить | обычная работа |
117
- | 🔑 Новый ключ | новый ключ машины; при включённом развёртывании сразу передаётся в Secret, и под перезапускается |
118
- | Завершить аренду | лицензия выдаётся без тарифа: новые заявки остановлены, защитные стопы работают, данные сохраняются |
119
-
120
- Удаление машины (`DELETE /api/admin/instances/<id>`) при включённом развёртывании удаляет namespace и **все данные клиента**. В интерфейсе отдельной кнопки нет, это сделано намеренно.
121
-
122
- ## 5. Обновление версии
123
-
124
- Новый образ задаётся переменной центра `INSTANCE_IMAGE` и применяется к новым машинам и при «Новом ключе». Массовое обновление существующих машин пока выполняется средствами кластера или PaaS, например:
125
-
126
- ```
127
- kubectl -n naXXXXXX set image deploy/neuroalpha neuroalpha=registry.odant.org/neuroalpha:0.4.1
128
- ```
129
-
130
- Обновление всех машин из админки запланировано отдельно.
@@ -1,92 +0,0 @@
1
- # Сборка и выпуск версии для компьютера клиента
2
-
3
- Версия для компьютера выдаётся клиентам тарифа VIP по индивидуальному договору. Это один исполняемый файл (Node.js Single Executable Application):
4
-
5
- - код сервера внутри собран в один файл и обфусцирован;
6
- - адрес центра и открытый ключ центра вшиты при сборке;
7
- - файлы интерфейса вшиты в исполняемый файл и распаковываются в профиль пользователя.
8
-
9
- ## 1. Что защищено и что нет
10
-
11
- | Попытка | Результат |
12
- |---|---|
13
- | Запустить в режиме разработчика через `.env` или `NEUROALPHA_ROLE=dev` | игнорируется: режим вшит (`instance`, `desktop`) |
14
- | Подложить свой открытый ключ (`LICENSE_PUBLIC_KEY`) и подписать себе лицензию | игнорируется: проверяется только вшитый ключ |
15
- | Направить программу на поддельный центр (`CENTRAL_URL`) | игнорируется: адрес центра вшит |
16
- | Перенести ключ активации на другой компьютер | центр отклоняет: ключ привязан к идентификатору установки |
17
- | Прочитать исходный код в файле | код обфусцирован: имена функций заменены, большинство строк закодировано |
18
- | Пропатчить исполняемый файл и вырезать проверки | **возможно** для опытного специалиста. Защита — договор и юридическая ответственность |
19
-
20
- ## 2. Подготовка
21
-
22
- - Node.js **той же версии**, что указана в `engines` (сборка берёт исполняемый файл Node текущей версии; для Linux скачивает официальный с nodejs.org).
23
- - `npm ci` — нужны dev-зависимости `esbuild`, `javascript-obfuscator`, `postject`.
24
- - Доступ в интернет при первой сборке для Linux: около 30 МБ, кэшируется в `dist/.node-cache`.
25
-
26
- ## 3. Сборка
27
-
28
- ```
29
- npm run build:desktop -- --pubkey-url https://neuroalpha.odant.org/api/public/license-key
30
- ```
31
-
32
- Параметры:
33
-
34
- | Параметр | По умолчанию | Назначение |
35
- |---|---|---|
36
- | `--pubkey-url <url>` или `--pubkey <файл.pem>` | — (обязательно) | открытый ключ центра |
37
- | `--central <url>` | `https://neuroalpha.odant.org` | адрес центра, вшиваемый в программу |
38
- | `--platform win,linux` | `win,linux` | какие файлы собрать |
39
- | `--no-obfuscate` | выкл. | только для отладки, **не выдавать клиентам** |
40
-
41
- Результат (около 85 МБ для Windows и 120 МБ для Linux) с контрольными суммами `.sha256`:
42
-
43
- ```
44
- dist/desktop/neuroalpha-0.4.0-win-x64.exe
45
- dist/desktop/neuroalpha-0.4.0-linux-x64
46
- ```
47
-
48
- > Сборка с открытым ключом тестового центра работает только с ним. Для клиентов собирайте строго с ключом боевого центра.
49
-
50
- ## 4. Подпись для Windows
51
-
52
- Без подписи Windows SmartScreen предупреждает при запуске. Подпишите файл сертификатом разработчика (лучше EV):
53
-
54
- ```
55
- signtool sign /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 /f codesign.pfx /p <пароль> dist\desktop\neuroalpha-0.4.0-win-x64.exe
56
- ```
57
-
58
- После подписи пересчитайте `.sha256`. Предупреждение сборщика `signature seems corrupted` — ожидаемо: исходная подпись `node.exe` снимается при внедрении кода.
59
-
60
- ## 5. Образ Docker для компьютера клиента
61
-
62
- Сначала соберите Linux-версию, затем образ:
63
-
64
- ```
65
- docker build -f Dockerfile.desktop --build-arg VERSION=0.4.0 -t registry.odant.org/neuroalpha-desktop:0.4.0 .
66
- docker push registry.odant.org/neuroalpha-desktop:0.4.0
67
- ```
68
-
69
- Внутри образа — тот же защищённый файл. Обычный `Dockerfile` (исходный код, режим из переменных) предназначен **только** для вашей инфраструктуры: центр и облачные машины. Клиентам его не выдавать.
70
-
71
- ## 6. Публикация
72
-
73
- 1. Загрузите файлы на сервер раздачи (доступ только по ссылке или после входа).
74
- 2. Задайте на центре переменные, чтобы ссылки появились в кабинете VIP-клиентов:
75
-
76
- | Переменная | Пример |
77
- |---|---|
78
- | `DESKTOP_DOWNLOAD_WINDOWS` | `https://download.odant.org/neuroalpha/0.4.0/neuroalpha-0.4.0-win-x64.exe` |
79
- | `DESKTOP_DOWNLOAD_LINUX` | `https://download.odant.org/neuroalpha/0.4.0/neuroalpha-0.4.0-linux-x64` |
80
- | `DESKTOP_DOCKER_IMAGE` | `registry.odant.org/neuroalpha-desktop:0.4.0` |
81
- | `DESKTOP_LATEST_VERSION` | `0.4.0` — установки со старой версией получат отметку о новой версии |
82
- | `DESKTOP_DOWNLOAD_URL` | ссылка для обновления, передаётся вместе с отметкой |
83
-
84
- Отметка о новой версии сейчас доступна программе через `/api/local/status` (поле `update`). Баннер в интерфейсе терминала и автообновление запланированы.
85
-
86
- ## 7. Проверка перед выдачей клиентам
87
-
88
- 1. Запустить `.exe` на чистой машине: открывается экран «Активация».
89
- 2. В кабинете тестового VIP-клиента получить код и активировать: открывается терминал, тариф VIP.
90
- 3. «Отвязать» в кабинете: в течение минуты баннер «Новые заявки приостановлены».
91
- 4. `neuroalpha --version` показывает версию и дату сборки.
92
- 5. Linux: проверить в контейнере `debian:bookworm-slim` (`--version` и запуск с `HOST=0.0.0.0`).
@@ -1,101 +0,0 @@
1
- <!-- audience: client -->
2
- # Руководство клиента: где работает НейроАльфа
3
-
4
- НейроАльфа работает на **вашей персональной машине**. Выберите вариант, который вам подходит:
5
-
6
- | | ☁ В облаке | 💻 На своём компьютере |
7
- |---|---|---|
8
- | Для кого | все тарифы | тариф VIP по договору |
9
- | Что нужно от вас | только браузер | компьютер с Windows или Linux, включённый во время торгов |
10
- | Как войти | из личного кабинета | открывается на этом компьютере |
11
- | Токен брокера хранится | на вашей облачной машине, в зашифрованном виде | только на вашем компьютере, в зашифрованном виде |
12
-
13
- Перейти к нужному варианту можно в личном кабинете, в блоке **«Где работать»**.
14
-
15
- ## 1. В облаке
16
-
17
- 1. Оплатите тариф. Персональная машина создаётся автоматически, обычно за 2–5 минут.
18
- 2. В личном кабинете, в блоке «Где работать», нажмите **«Перейти в терминал»**.
19
- 3. Адрес машины вида `naXXXXXX.odant.org` можно сохранить в закладки: если вы вошли в кабинет, вход выполняется автоматически.
20
-
21
- Машина работает круглосуточно, компьютер держать включённым не нужно.
22
-
23
- ## 2. На своём компьютере (VIP)
24
-
25
- ### Требования
26
-
27
- - Windows 10/11 (64-бит) или Linux x64; 4 ГБ памяти, 3 ГБ свободного места;
28
- - стабильный интернет во время торговой сессии Мосбиржи;
29
- - компьютер включён и не уходит в сон с 9:50 до 23:50 МСК, если включена автоматическая торговля.
30
-
31
- ### Установка на Windows
32
-
33
- 1. Скачайте программу по ссылке из личного кабинета («⬇ Windows»).
34
- 2. Запустите файл. Если Windows покажет предупреждение SmartScreen, нажмите «Подробнее» → «Выполнить в любом случае».
35
- 3. Откроется браузер с экраном **«Активация»**.
36
- 4. В личном кабинете нажмите **«Получить код активации»** и введите код (вида `NA-XXXX-XXXX`) в программе. Код действует 10 минут и срабатывает один раз.
37
- 5. Чтобы терминал запускался сам при входе в Windows, выполните один раз в командной строке:
38
-
39
- ```
40
- neuroalpha-0.4.0-win-x64.exe --install
41
- ```
42
-
43
- Повторный запуск программы, когда она уже работает, просто открывает терминал в браузере. Адрес терминала: `http://localhost:3000`.
44
-
45
- ### Установка на Linux
46
-
47
- ```
48
- chmod +x neuroalpha-0.4.0-linux-x64
49
- ./neuroalpha-0.4.0-linux-x64 --install
50
- sudo loginctl enable-linger $USER # чтобы работала без входа в систему
51
- ```
52
-
53
- Откройте `http://localhost:3000` и активируйте программу кодом из кабинета.
54
-
55
- ### Через Docker
56
-
57
- ```
58
- docker run -d --name neuroalpha --restart unless-stopped -p 127.0.0.1:3000:3000 -v neuroalpha:/data registry.odant.org/neuroalpha-desktop:0.4.0
59
- ```
60
-
61
- Откройте `http://localhost:3000` и активируйте программу. Чтобы войти в терминал после активации, откройте его из личного кабинета кнопкой **«Открыть»**.
62
-
63
- ### Где хранятся данные
64
-
65
- | Система | Папка |
66
- |---|---|
67
- | Windows | `%LOCALAPPDATA%\NeuroAlpha\data` |
68
- | Linux | `~/.local/share/neuroalpha/data` |
69
- | Docker | том `neuroalpha` |
70
-
71
- Удалить программу из автозапуска: `--uninstall`. Данные и активация при этом сохраняются.
72
-
73
- ### Перенос на другой компьютер
74
-
75
- 1. В личном кабинете у текущего компьютера нажмите **«Отвязать»**. Программа на нём в течение минуты перестанет отправлять новые заявки.
76
- 2. Если хотите сохранить историю, скопируйте папку данных на новый компьютер.
77
- 3. Установите программу на новом компьютере и активируйте её новым кодом из кабинета.
78
-
79
- ## 3. Подтверждение заявок из Telegram и MAX
80
-
81
- Привяжите Telegram или MAX в личном кабинете. В режиме «Подтверждение заявок» каждый пакет заявок приходит сообщением с кнопками **«✓ Исполнить»** и **«✕ Отклонить»**. Кнопки работают и для облачной машины, и для программы на компьютере. Нажатие выполняется в течение нескольких секунд. Если пакет за это время уже заменён новым, программа ничего не исполнит и сообщит об этом. Кнопки действуют 2 часа и срабатывают один раз.
82
-
83
- ## 4. Если пропал интернет или центр недоступен
84
-
85
- Лицензия действует 72 часа без связи с центром. Всё это время программа работает как обычно. Если связи нет дольше:
86
-
87
- - новые заявки приостанавливаются;
88
- - **защитные стоп-заявки по открытым позициям продолжают работать**;
89
- - открытые позиции программа не закрывает.
90
-
91
- Причина остановки показывается баннером над списком счетов. Связь восстановится — работа продолжится автоматически.
92
-
93
- ## 5. Безопасность
94
-
95
- - Терминал на компьютере доступен только с этого компьютера. Не открывайте порт 3000 в интернет и не пробрасывайте его на роутере.
96
- - Токен брокера никогда не передаётся в центр, в чат ИИ и в браузер: в настройках видна только маска `t.…abcd`.
97
- - Если вы подозреваете, что токен брокера стал известен посторонним, перевыпустите его в личном кабинете брокера и вставьте новый в настройках счёта.
98
-
99
- ## 6. Поддержка
100
-
101
- Пишите на `support@neuroalpha.ru` или в бот НейроАльфа в Telegram / MAX. Укажите адрес машины (`naXXXXXX`) или имя компьютера из личного кабинета.
@@ -1,109 +0,0 @@
1
- # Эксплуатация и безопасность
2
-
3
- ## 1. Как машина клиента получает право торговать
4
-
5
- Раз в минуту машина отправляет в центр техническое состояние и получает лицензию, подписанную ключом Ed25519 центра, сроком на 72 часа (`LICENSE_TTL_HOURS`). В лицензии указаны тариф клиента, срок подписки и состояние торговли из админки.
6
-
7
- | Ситуация | Новые заявки | Защитные стопы |
8
- |---|---|---|
9
- | Всё в порядке | ✓ | ✓ |
10
- | Нет связи с центром, лицензия ещё действует | ✓ | ✓ |
11
- | Лицензия истекла; подписка не активна; «Пауза»; аренда завершена; программа на компьютере не активирована | ✕ | ✓ |
12
- | Центр отверг ключ машины (ключ заменён, компьютер отвязан, машина удалена) — лицензия отзывается сразу | ✕ | ✓ |
13
- | «⛔ Стоп» в админке | ✕ | ✕ |
14
-
15
- Открытые позиции машина никогда не закрывает принудительно. Клиент видит причину остановки баннером над счетами.
16
-
17
- ## 2. Что машины отправляют в центр
18
-
19
- **Только техническое состояние:**
20
-
21
- - версия программы и Node.js, время работы, память, размер базы, имя хоста;
22
- - число счетов (всего, в автоматическом режиме, на паузе, с дневным стопом) и брокеры;
23
- - сколько секунд назад была синхронизация и прогноз;
24
- - разрешена ли торговля и почему; остаток срока лицензии;
25
- - до пяти последних ошибок связи.
26
-
27
- **Никогда не отправляются:** суммы, позиции, сделки, токены брокеров, email и персональные данные клиента. Центр дополнительно отбрасывает все поля, не входящие в этот список.
28
-
29
- ## 3. Консоль администратора → «Машины клиентов»
30
-
31
- | Колонка | Значение |
32
- |---|---|
33
- | Машина | ID, адрес (облако) или имя компьютера, состояние развёртывания |
34
- | Связь | онлайн, если машина выходила на связь за последние 3 минуты |
35
- | Состояние | счета, наличие дневных стопов, разрешена ли торговля, память и размер базы, ошибки (подробно — во всплывающей подсказке) |
36
- | Торговля | торгует / пауза / аварийная остановка |
37
-
38
- Действия: «Возобновить», «Пауза», «Стоп», «Новый ключ» (облако), «Отвязать компьютер», «Завершить аренду» / «Восстановить». Все команды доходят до машины при следующей связи — до 1 минуты.
39
-
40
- ## 4. Типовые ситуации
41
-
42
- | Ситуация | Что делать |
43
- |---|---|
44
- | Машина «нет связи» | проверить под в кластере (`kubectl -n naXXXXXX get pods`, `logs`). Торговля продолжается до 72 ч, потом приостанавливаются только новые заявки |
45
- | «Ошибка развёртывания» | текст ошибки — в подсказке. Центр повторяет каждые 2 минуты с новым ключом. Частые причины: права сервисного аккаунта, нет Secret с wildcard-сертификатом в namespace, недоступен webhook PaaS |
46
- | Ключ машины мог утечь | «🔑 Новый ключ»: старый перестаёт работать сразу |
47
- | Клиент сменил компьютер | клиент сам нажимает «Отвязать» в кабинете, либо администратор — «Отвязать компьютер» |
48
- | Клиент сообщил об утечке токена брокера | клиент перевыпускает токен у брокера и вставляет новый в настройках счёта. Старый токен отозвать может только брокер |
49
- | Нужно немедленно остановить торговлю клиента | «⛔ Стоп» (не дольше 1 мин). Закрыть позиции клиент может сам в приложении брокера |
50
- | Подозрение на компрометацию ключа подписи центра | см. документ «Развёртывание центрального сервера», раздел 3 |
51
- | Клиент не может войти: «слишком много попыток» | блокировка по email и IP снимается сама через 15 минут |
52
-
53
- ## 5. Защита, включённая в версии 0.4.0
54
-
55
- - Вход обязателен для всего `/api` и WebSocket. События рассылаются только владельцу данных.
56
- - Токен брокера хранится в зашифрованном виде (AES-256-GCM) и никогда не уходит в браузер, события или чат ИИ.
57
- - Проверка `Origin` для изменяющих запросов (CSRF); CSP, SRI и DOMPurify в терминале.
58
- - Проверка TLS ко всем брокерам с корневым сертификатом НУЦ Минцифры (`config/certs`).
59
- - Ограничение попыток входа; случайные коды привязки ботов; кнопки «Исполнить» в ботах работают только из привязанного чата.
60
- - Вебхук MAX только с секретом; настройки моделей ИИ меняет только администратор.
61
- - На компьютере клиента программа без пароля доступна только с этого же компьютера; адрес, ключ центра и режим вшиты в сборку.
62
-
63
- ## 6. Исполнение заявок и журнал
64
-
65
- - У каждой заявки постоянный идентификатор (`clientOrderId`, для Т-Банка — `orderId`). Он закрепляется **до** отправки, поэтому повтор пакета не создаёт дублей. Уже принятые брокером заявки при повторе пакета «partial» не отправляются; при таймауте повтор идёт с тем же идентификатором.
66
- - Если счёт занят пересчётом заявок, «Исполнить» ждёт до 15 секунд и затем сообщает об этом, а не пропускает нажатие молча.
67
- - **Журнал исполнения** (кнопка 📋 в карточке счёта): отправленные заявки, ошибки брокера, защитные стопы, срабатывание и снятие дневного стопа, аварийная остановка. Хранятся последние 5000 событий на счёт.
68
- - **Дневной стоп** не снимается при сохранении настроек. Снять его можно только кнопкой «Снять стоп до конца дня» с подтверждением; до конца дня (МСК) он на этом счёте больше не срабатывает. Блокировку за автоследование снять нельзя.
69
- - **«⛔ Остановить всё»** в разделе «Брокерские счета»: авто-торговля на всех счетах встаёт на паузу, все активные заявки у брокера снимаются. Позиции не закрываются, защитные стопы работают.
70
-
71
- ## 7. Известные ограничения
72
-
73
- - Стоп-заявки на стороне брокера — бета, только Т-Банк, по умолчанию выключены (см. раздел 11). Без них защитные стопы работают, только пока работает машина.
74
- - Полная поддержка — только Т-Банк. Финам, БКС, Алор, Цифра и ITI — бета: только «Подтверждение заявок» (нет средней цены для защитных стопов, отмены заявок и истории). СберИнвестиции, ВТБ и Альфа не подключаются: у них нет открытого API для заявок.
75
-
76
- ## 8. Хранение счетов
77
-
78
- С версии 0.4.1 каждый брокерский счёт — отдельная запись в таблице `broker_accounts`. При сохранении записываются только поля, изменённые этим участком кода, поверх актуальной записи в транзакции. Поэтому синхронизация, пересчёт заявок и сохранение настроек не затирают друг друга, в том числе сработавший дневной стоп и режим «Только чтение». При первом запуске счета переносятся из прежнего хранения автоматически. Прежняя запись остаётся на случай отката версии.
79
-
80
- Стратег (ИИ) не принимает токены брокера через чат: токен вставляется только в форму счёта.
81
-
82
- ## 9. Кнопки «Исполнить / Отклонить» в Telegram и MAX для машин клиентов
83
-
84
- 1. Машина формирует пакет заявок и отправляет уведомление с кнопками в центр.
85
- 2. Центр пишет клиенту в его привязанный чат. В данных кнопки — только одноразовый короткий ID, действует 2 часа.
86
- 3. При нажатии центр проверяет, что кнопку нажали в чате, привязанном к владельцу машины, и ставит команду в очередь машины. Обе кнопки этого уведомления после нажатия гаснут.
87
- 4. Команда доходит до машины **внутри подписанной лицензии**, поэтому подделать её на пути нельзя. 15 минут после уведомления машина связывается с центром каждые 5 секунд, поэтому нажатие срабатывает почти сразу.
88
- 5. Машина выполняет команду, только если тот же пакет всё ещё ждёт подтверждения. Если пакет уже исполнен, отклонён или заменён новым, команда отклоняется, и клиент получает об этом сообщение.
89
- 6. Машина подтверждает выполнение (`ack`). Центр больше не отдаёт эту команду, а машина помнит выполненные ID и не исполнит пакет дважды.
90
-
91
- ## 10. Контроль связи машин
92
-
93
- Раз в 2 минуты центр проверяет облачные машины. Если машина не выходила на связь дольше `INSTANCE_OFFLINE_ALERT_MIN` (по умолчанию 10 минут), всем администраторам в Telegram/MAX приходит одно сообщение. В нём указаны машина, клиент, число счетов в «Автомате» и сколько ещё будет действовать лицензия без связи. Когда машина возвращается, приходит сообщение «снова на связи». Компьютеры клиентов по умолчанию не отслеживаются, так как их выключают на ночь; включить отслеживание можно переменной `INSTANCE_ALERT_DESKTOP=1`.
94
-
95
- ## 11. Защитные стоп-заявки у брокера (бета, Т-Банк)
96
-
97
- Включаются на счёте: «⚙» → «Защитные стоп-заявки у брокера». Как работает:
98
-
99
- - на каждую бумагу с позицией стратегии у Т-Банка выставляется стоп-лосс с исполнением по рынку и сроком «до отмены»: −2,6% от средней цены для покупок, +2,2% для шортов, ровно на число лотов позиции. Стоп сработает, даже если машина выключена;
100
- - раз в 25 секунд стоп-заявки сверяются с позициями: при изменении объёма заявка переставляется, без позиции — снимается;
101
- - **перед любой закрывающей заявкой стратегии стоп-заявка по этой бумаге снимается.** Если снять не удалось, закрывающая заявка не отправляется, чтобы не продать дважды и не открыть шорт на маржинальном счёте;
102
- - внутренний защитный стоп по бумаге со стоп-заявкой у брокера не дублируется;
103
- - после срабатывания стоп-заявки новая выставляется не раньше чем через 2 минуты и после обновления портфеля;
104
- - при выключении переключателя, режиме «Только чтение» или «⛔ Стоп» из центра программа снимает свои стоп-заявки. Чужие стоп-заявки (выставленные вручную в приложении брокера) не трогаются никогда;
105
- - все действия видны в журнале исполнения (📋).
106
-
107
- **Первое включение:** проверьте на одной небольшой позиции. В приложении Т-Банка → «Заявки» должна появиться стоп-заявка, а после закрытия позиции стратегией она должна исчезнуть. При ручных сделках по той же бумаге в приложении брокера сверка поправит объём в течение 25 секунд, но в эти секунды стоп-заявка может не соответствовать позиции.
108
- - Обновление образа всех облачных машин из админки и автообновление программы на компьютере запланированы.
109
- - Тома облачных машин нужно резервировать средствами кластера: в них база клиента и ключ шифрования его токенов.