neuroalpha 0.6.13 → 0.7.1
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.
- package/README.md +14 -10
- package/bin/cli.js +79 -69
- 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
- package/package.json +4 -5
- package/public/activate.html +41 -19
- package/public/activate.js +81 -10
- package/public/app.js +471 -166
- package/public/index.html +9 -39
- package/public/styles.css +42 -3
- package/server/api/routes.js +595 -906
- package/server/auth/index.js +583 -761
- package/server/brokers/index.js +14 -3
- package/server/config.js +73 -53
- package/server/index.js +186 -212
- package/server/llm/local-engine.js +843 -0
- package/server/llm/providers.js +45 -34
- package/server/model/live.js +2 -1
- package/server/notify/index.js +304 -466
- package/server/strategist/index.js +4 -1
- package/deploy/docs/01-central.md +0 -96
- package/deploy/docs/02-cloud-instances.md +0 -130
- package/deploy/docs/03-desktop-build.md +0 -92
- package/deploy/docs/04-client-guide.md +0 -101
- package/deploy/docs/05-operations.md +0 -109
- package/deploy/docs/06-env-reference.md +0 -91
- package/deploy/docs/07-stress-test.md +0 -253
- package/deploy/docs/pdf/01-central.pdf +0 -0
- package/deploy/docs/pdf/02-cloud-instances.pdf +0 -0
- package/deploy/docs/pdf/03-desktop-build.pdf +0 -0
- package/deploy/docs/pdf/04-client-guide.pdf +0 -0
- package/deploy/docs/pdf/05-operations.pdf +0 -0
- package/deploy/docs/pdf/06-env-reference.pdf +0 -0
- package/deploy/docs/pdf/07-stress-test.pdf +0 -0
- package/deploy/install.sh +0 -128
- package/deploy/k8s/instance.yaml +0 -147
- package/public/admin.html +0 -604
- package/public/landing.html +0 -1207
- package/public/legal.html +0 -134
- package/scripts/set-admin-password.mjs +0 -30
- package/server/billing/yookassa.js +0 -142
- package/server/instance/agent.js +0 -259
- package/server/instance/central.js +0 -514
- package/server/instance/identity.js +0 -79
- package/server/instance/provision.js +0 -166
- package/server/instance/signing.js +0 -71
- package/server/role.js +0 -44
package/public/index.html
CHANGED
|
@@ -11,14 +11,17 @@
|
|
|
11
11
|
<script src="https://unpkg.com/dompurify@3.2.6/dist/purify.min.js" integrity="sha384-JEyTNhjM6R1ElGoJns4U2Ln4ofPcqzSsynQkmEc/KGy6336qAZl70tDLufbkla+3" crossorigin="anonymous"></script>
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
|
+
<div id="lic-error-bar" class="lic-error-bar" hidden>
|
|
15
|
+
<span id="lic-error-text">ЛИЦЕНЗИЯ НЕ УСТАНОВЛЕНА (Торговля и сигналы отключены)</span>
|
|
16
|
+
<button id="btn-get-license" type="button" class="lic-cta-btn">Получить лицензию</button>
|
|
17
|
+
</div>
|
|
14
18
|
<header>
|
|
15
19
|
<div class="brand">
|
|
16
20
|
<button id="btn-chat-toggle" type="button" class="hdr-btn" title="Показать или скрыть панель чата с ИИ-Стратегом">💬 Стратег</button>
|
|
17
21
|
<span class="logo">◈</span><b>НейроАльфа</b><span class="muted">· Рынок как язык · Мосбиржа</span>
|
|
18
22
|
</div>
|
|
19
23
|
<div class="hright">
|
|
20
|
-
<
|
|
21
|
-
<button id="btn-user" type="button" class="hdr-btn" title="Профиль, подписка и боты Telegram / MAX">Профиль</button>
|
|
24
|
+
<button id="btn-user" type="button" class="hdr-btn" title="Лицензия, доступ и уведомления">Лицензия</button>
|
|
22
25
|
<span id="st" class="dot" title="Подключение…"></span>
|
|
23
26
|
<button id="btn-theme" class="hdr-btn icon-only" title="Светлая / тёмная тема">☀</button>
|
|
24
27
|
<button id="btn-help" class="hdr-btn icon-only" title="Справка">?</button>
|
|
@@ -89,7 +92,7 @@
|
|
|
89
92
|
<button type="button" data-sec="news" id="nnav-news">Новости рынка</button>
|
|
90
93
|
<div class="ssep"></div>
|
|
91
94
|
<button type="button" data-sec="overview" id="nnav-overview" hidden>Эксперименты</button>
|
|
92
|
-
<button type="button" data-sec="cloud" id="snav-cloud"
|
|
95
|
+
<button type="button" data-sec="cloud" id="snav-cloud">Лицензия</button>
|
|
93
96
|
<button type="button" data-sec="llm" id="snav-llm">Модели ИИ</button>
|
|
94
97
|
</aside>
|
|
95
98
|
<div class="spane">
|
|
@@ -246,7 +249,7 @@
|
|
|
246
249
|
</section>
|
|
247
250
|
|
|
248
251
|
<section class="ssec" data-sec="cloud" id="cloud-box" hidden>
|
|
249
|
-
<div class="stitle"
|
|
252
|
+
<div class="stitle">Лицензия терминала, доступ и уведомления (Telegram / MAX)</div>
|
|
250
253
|
<div class="scard spadded" id="cloud-pane"></div>
|
|
251
254
|
</section>
|
|
252
255
|
|
|
@@ -254,11 +257,12 @@
|
|
|
254
257
|
<div class="stitle bar">
|
|
255
258
|
<span id="llm-sum">Модели ИИ для Стратега</span>
|
|
256
259
|
<div class="row-gap" style="align-items:center">
|
|
257
|
-
<button type="button" id="btn-llm-open-add" class="primary">+ Подключить ИИ-сервис</button>
|
|
260
|
+
<button type="button" id="btn-llm-open-add" class="primary">+ Подключить внешний ИИ-сервис</button>
|
|
258
261
|
</div>
|
|
259
262
|
</div>
|
|
260
263
|
<div class="scard spadded">
|
|
261
264
|
<div id="llm-active-banner"></div>
|
|
265
|
+
<div id="local-llm-box" style="margin-bottom:16px"></div>
|
|
262
266
|
<div id="llm-form-slot">
|
|
263
267
|
<details id="llm-add-box" class="llm-form-card">
|
|
264
268
|
<summary id="llm-add-sum">+ Подключить новый сервис или локальную модель ИИ</summary>
|
|
@@ -372,40 +376,6 @@
|
|
|
372
376
|
</div>
|
|
373
377
|
</div>
|
|
374
378
|
|
|
375
|
-
<!-- Модальное окно подписания Договора-оферты и Декларации о рисках -->
|
|
376
|
-
<div id="offer-modal" class="modal" hidden>
|
|
377
|
-
<div class="modal-box" style="max-width:680px">
|
|
378
|
-
<div class="modal-head">
|
|
379
|
-
<b>Договор публичной оферты и Декларация о рисках</b>
|
|
380
|
-
<button id="offer-close" class="icon">✕</button>
|
|
381
|
-
</div>
|
|
382
|
-
<div class="md" style="max-height:300px;overflow-y:auto;padding:12px 16px;border-bottom:1px solid var(--line);font-size:13px;line-height:1.55">
|
|
383
|
-
<p style="margin-top:0"><b>1. Предмет договора:</b> Настоящая Публичная оферта регулирует предоставление доступа к облачной аналитической платформе «НейроАльфа» (PaaS/SaaS) согласно выбранному тарифному плану («Инвестор», «Профи», «VIP»).</p>
|
|
384
|
-
<p><b>2. Правовой статус (отсутствие ИИР и ДУ):</b> Сервис является исключительно программно-техническим средством (калькулятором статистических закономерностей). Исполнитель <b>не осуществляет инвестиционное консультирование</b>, не даёт индивидуальных инвестиционных рекомендаций (ФЗ № 39-ФЗ) и не осуществляет доверительное управление. Все сделки совершаются Пользователем самостоятельно на его личном брокерском счёте.</p>
|
|
385
|
-
<p><b>3. Параметры тарифов и предельные уровни доходности:</b>
|
|
386
|
-
<br>• <b>«Инвестор» (3 900 ₽/мес)</b> — 1 брокерский счёт, стартовый лимит до 1 000 000 ₽ (+ реинвестирование всей заработанной прибыли), торговля только от покупки («Только в рост (без шорта)»);
|
|
387
|
-
<br>• <b>«Профи» (9 900 ₽/мес)</b> — до 5 брокерских счетов, стартовый лимит до 1 000 000 ₽ на каждом счёте (+ реинвестирование всей заработанной прибыли), торговля в рост и в падение (с шортами);
|
|
388
|
-
<br>• <b>«VIP» (по индивидуальному согласованию)</b> — количество счетов и начальная сумма торговли по согласованию, торговля в рост и в падение (с шортами).
|
|
389
|
-
</p>
|
|
390
|
-
<p><b>4. Запрет автоследования и ретрансляции сигналов:</b> Пользователю строго запрещается подключать к платформе счета, участвующие в сервисах автоследования или копирования сделок (как в роли ведущего/автора стратегии, так и в роли подписчика), а также передавать или перепродавать сигналы третьим лицам. При обнаружении признаков автоследования счёт автоматически блокируется.</p>
|
|
391
|
-
<p style="margin-bottom:0"><b>5. Декларация о рисках:</b> Торговля ценными бумагами сопряжена с риском потери части или всего инвестированного капитала. Результаты на исторических данных не гарантируют доходности в будущем. Полный текст документа: <a href="/legal" target="_blank" style="color:var(--accent)">открыть /legal →</a></p>
|
|
392
|
-
</div>
|
|
393
|
-
<div style="padding:14px 18px;display:grid;gap:10px;font-size:13px">
|
|
394
|
-
<label style="display:flex;gap:10px;align-items:flex-start;cursor:pointer">
|
|
395
|
-
<input type="checkbox" id="term-offer-chk1" style="width:16px;height:16px;margin-top:2px;flex:none">
|
|
396
|
-
<span>Я прочитал(а) и безоговорочно принимаю условия <a href="/legal#offer" target="_blank" style="color:var(--accent)">Договора публичной оферты</a> и <a href="/legal#privacy" target="_blank" style="color:var(--accent)">Политики обработки персональных данных</a>.</span>
|
|
397
|
-
</label>
|
|
398
|
-
<label style="display:flex;gap:10px;align-items:flex-start;cursor:pointer">
|
|
399
|
-
<input type="checkbox" id="term-offer-chk2" style="width:16px;height:16px;margin-top:2px;flex:none">
|
|
400
|
-
<span>Я ознакомлен(а) с <a href="/legal#risks" target="_blank" style="color:var(--accent)">Декларацией о рисках</a>, понимаю, что сервис не является индивидуальной инвестиционной рекомендацией, и обязуюсь <b>не использовать автоследование</b> на подключаемых счетах.</span>
|
|
401
|
-
</label>
|
|
402
|
-
<div class="row-gap" style="justify-content:flex-end;margin-top:4px">
|
|
403
|
-
<button type="button" id="term-offer-decline">Отказ (Отмена)</button>
|
|
404
|
-
<button type="button" class="primary" id="term-offer-accept" disabled>Подписать оферту и продолжить →</button>
|
|
405
|
-
</div>
|
|
406
|
-
</div>
|
|
407
|
-
</div>
|
|
408
|
-
</div>
|
|
409
379
|
<div id="toast"></div>
|
|
410
380
|
<script src="app.js" type="module"></script>
|
|
411
381
|
</body>
|
package/public/styles.css
CHANGED
|
@@ -47,8 +47,9 @@ body.light {
|
|
|
47
47
|
--hover-bg: #f0f3f6;
|
|
48
48
|
}
|
|
49
49
|
* { box-sizing: border-box; }
|
|
50
|
+
[hidden] { display: none !important; }
|
|
50
51
|
html, body { height: 100%; }
|
|
51
|
-
body { margin: 0; background: var(--bg); color: var(--text); font: 14px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; overflow: hidden; }
|
|
52
|
+
body { margin: 0; background: var(--bg); color: var(--text); font: 14px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; overflow: hidden; display: flex; flex-direction: column; }
|
|
52
53
|
a, a:visited { color: var(--accent); text-decoration: none; }
|
|
53
54
|
a:hover { color: var(--accent); text-decoration: underline; }
|
|
54
55
|
.muted { color: var(--muted); }
|
|
@@ -58,7 +59,45 @@ a:hover { color: var(--accent); text-decoration: underline; }
|
|
|
58
59
|
.neg { color: var(--red); }
|
|
59
60
|
h4 { margin: 18px 0 6px; font-size: 13px; color: var(--muted); font-weight: 500; }
|
|
60
61
|
|
|
61
|
-
header { height: 48px; display: flex; justify-content: space-between; align-items: center; padding: 0 16px; border-bottom: 1px solid var(--line); background: var(--panel); }
|
|
62
|
+
header { height: 48px; flex: none; display: flex; justify-content: space-between; align-items: center; padding: 0 16px; border-bottom: 1px solid var(--line); background: var(--panel); }
|
|
63
|
+
.lic-error-bar {
|
|
64
|
+
background: #d32f2f;
|
|
65
|
+
color: #ffffff;
|
|
66
|
+
flex: none;
|
|
67
|
+
display: flex;
|
|
68
|
+
align-items: center;
|
|
69
|
+
justify-content: center;
|
|
70
|
+
flex-wrap: wrap;
|
|
71
|
+
gap: 12px;
|
|
72
|
+
padding: 5px 16px;
|
|
73
|
+
font-size: 13px;
|
|
74
|
+
font-weight: 600;
|
|
75
|
+
}
|
|
76
|
+
.lic-error-bar button.lic-cta-btn {
|
|
77
|
+
background: #ffffff;
|
|
78
|
+
color: #1e293b;
|
|
79
|
+
border: 0;
|
|
80
|
+
border-radius: 5px;
|
|
81
|
+
padding: 4px 12px;
|
|
82
|
+
font-size: 12.5px;
|
|
83
|
+
font-weight: 700;
|
|
84
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.28);
|
|
85
|
+
}
|
|
86
|
+
.lic-error-bar button.lic-cta-btn:hover {
|
|
87
|
+
background: #f1f5f9;
|
|
88
|
+
color: #0f172a;
|
|
89
|
+
}
|
|
90
|
+
.hdr-btn.lic-err {
|
|
91
|
+
background: rgba(211, 47, 47, 0.16);
|
|
92
|
+
border-color: #ef4444;
|
|
93
|
+
color: #f87171;
|
|
94
|
+
font-weight: 600;
|
|
95
|
+
}
|
|
96
|
+
body.light .hdr-btn.lic-err {
|
|
97
|
+
background: #fee2e2;
|
|
98
|
+
border-color: #dc2626;
|
|
99
|
+
color: #b91c1c;
|
|
100
|
+
}
|
|
62
101
|
.brand { display: flex; gap: 8px; align-items: center; }
|
|
63
102
|
.logo { color: var(--accent); font-size: 18px; }
|
|
64
103
|
.hright { display: flex; gap: 8px; align-items: center; }
|
|
@@ -99,7 +138,7 @@ button.icon-lg { width: 40px; height: 40px; padding: 0; font-size: 15px; flex: n
|
|
|
99
138
|
.hdr-btn { padding: 4px 10px; font-size: 12.5px; }
|
|
100
139
|
.hdr-btn.icon-only { width: 30px; height: 30px; padding: 0; }
|
|
101
140
|
|
|
102
|
-
main { display: grid; grid-template-columns: var(--chat-w) 5px 1fr;
|
|
141
|
+
main { display: grid; grid-template-columns: var(--chat-w) 5px 1fr; flex: 1; min-height: 0; }
|
|
103
142
|
body.chat-closed main { grid-template-columns: 1fr; }
|
|
104
143
|
body.chat-closed .chat, body.chat-closed #splitter { display: none; }
|
|
105
144
|
#btn-chat-toggle.active { border-color: var(--accent); color: var(--accent); background: var(--accent-bg); font-weight: 600; }
|