neuroalpha 0.3.12 → 0.3.13
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/LICENSE +13 -17
- package/README.md +4 -2
- package/bin/cli.js +1 -1
- package/deploy/install.sh +1 -1
- package/docs//320/230/320/235/320/241/320/242/320/240/320/243/320/232/320/246/320/230/320/257.md +1 -1
- package/docs//320/234/320/225/320/245/320/220/320/235/320/230/320/232/320/220_/320/230_/320/237/320/220/320/240/320/220/320/234/320/225/320/242/320/240/320/253.md +1 -1
- package/package.json +2 -2
- package/public/admin.html +43 -20
- package/public/app.js +524 -211
- package/public/index.html +43 -3
- package/public/landing.html +328 -115
- package/public/legal.html +37 -16
- package/public/styles.css +24 -3
- package/server/api/routes.js +61 -29
- package/server/auth/index.js +109 -20
- package/server/billing/yookassa.js +1 -1
- package/server/brokers/index.js +179 -34
- package/server/config.js +1 -1
- package/server/data/moex.js +1 -1
- package/server/db.js +17 -3
- package/server/hub.js +1 -1
- package/server/index.js +4 -4
- package/server/llm/client.js +1 -1
- package/server/llm/providers.js +1 -1
- package/server/model/dataset.js +1 -1
- package/server/model/forecast.js +188 -17
- package/server/model/linalg.js +1 -1
- package/server/model/live.js +6 -19
- package/server/model/metrics.js +1 -1
- package/server/model/models.js +1 -1
- package/server/model/profiles.js +1 -1
- package/server/model/research.js +12 -36
- package/server/model/vocab.js +1 -1
- package/server/news/index.js +1 -1
- package/server/notify/index.js +1 -1
- package/server/params-meta.js +4 -3
- package/server/settings.js +1 -1
- package/server/strategist/analytics.js +2 -2
- package/server/strategist/index.js +2 -2
- package/server/strategist/tools.js +1 -1
- package/server/util.js +1 -1
package/LICENSE
CHANGED
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
PROPRIETARY SOFTWARE LICENSE
|
|
2
|
+
Все права защищены · All Rights Reserved
|
|
2
3
|
|
|
3
|
-
Copyright (c) 2026 Roman A. Perepelkin
|
|
4
|
+
Copyright (c) 2026 Roman A. Perepelkin (Перепелкин Роман Александрович).
|
|
5
|
+
Оператор платформы: ООО «БИС» («Бизнес Интер Софт», г. Рязань).
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
7
|
+
Настоящее программное обеспечение «НейроАльфа» (включая исходный код, математические модели, алгоритмы обучения, архитектуру, документацию и элементы пользовательского интерфейса) является объектом исключительного авторского права и коммерческой тайной Правообладателя.
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
Без предварительного письменного разрешения Правообладателя строго запрещается:
|
|
10
|
+
1. Копировать, воспроизводить, распространять, публиковать или передавать третьим лицам исходный или объектный код Программы (полностью или частично);
|
|
11
|
+
2. Модифицировать, адаптировать, декомпилировать, дизассемблировать или осуществлять обратную разработку (reverse engineering) Программы и её алгоритмов;
|
|
12
|
+
3. Сдавать в аренду, сублицензировать или использовать Программу для оказания услуг третьим лицам (включая ретрансляцию торговых сигналов и подключение счетов автоследования);
|
|
13
|
+
4. Удалять или изменять знаки охраны авторского права и сведения о Правообладателе и Операторе платформы.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
15
|
+
Доступ к функциональным возможностям платформы предоставляется конечным пользователям исключительно на условиях Договора публичной оферты (модель PaaS/SaaS).
|
|
16
|
+
|
|
17
|
+
ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ ПО ПРИНЦИПУ «КАК ЕСТЬ» (AS IS), БЕЗ КАКИХ-ЛИБО ПРЯМЫХ ИЛИ КОСВЕННЫХ ГАРАНТИЙ, ВКЛЮЧАЯ ГАРАНТИИ ОКУПАЕМОСТИ ИЛИ ДОСТИЖЕНИЯ ФИНАНСОВОГО РЕЗУЛЬТАТА. АВТОР И ОПЕРАТОР ПЛАТФОРМЫ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЯМЫЕ ИЛИ КОСВЕННЫЕ УБЫТКИ, ВОЗНИКШИЕ В РЕЗУЛЬТАТЕ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ.
|
package/README.md
CHANGED
|
@@ -163,6 +163,8 @@ MOEX ISS: ~100 акций MOEXBMI + IMOEX, свечи по 10 минут (буд
|
|
|
163
163
|
- Описания компаний и разметку новостей делает ИИ — они могут ошибаться. В описания сознательно попадают только
|
|
164
164
|
устойчивые факты (без событий и прогнозов), а новости не используются в проверках на истории — иначе ИИ «подсмотрит будущее».
|
|
165
165
|
|
|
166
|
-
##
|
|
166
|
+
## Правовая информация и лицензия
|
|
167
167
|
|
|
168
|
-
Copyright (c) 2026 Roman A. Perepelkin.
|
|
168
|
+
Copyright (c) 2026 Roman A. Perepelkin (Перепелкин Р.А.). Все права защищены.
|
|
169
|
+
Оператор платформы: ООО «БИС» («Бизнес Интер Софт», г. Рязань).
|
|
170
|
+
Проприетарное программное обеспечение ([LICENSE](LICENSE)) — копирование, модификация и распространение без письменного разрешения правообладателя запрещены.
|
package/bin/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Copyright (c) 2026 Roman A. Perepelkin.
|
|
2
|
+
// Copyright (c) 2026 Roman A. Perepelkin. All rights reserved. Proprietary software.
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import fs from 'node:fs';
|
package/deploy/install.sh
CHANGED
package/docs//320/230/320/235/320/241/320/242/320/240/320/243/320/232/320/246/320/230/320/257.md
CHANGED
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
| Минимальное удержание, часов | Не закрывать позицию раньше этого времени при обычном ослаблении прогноза. Снижает число сделок и комиссий |
|
|
127
127
|
| Сколько акций держать | Сколько лучших по прогнозу акций держать одновременно (при продажах — и столько же на продажу) |
|
|
128
128
|
| Распределение суммы между акциями | «Поровну» — одинаково; «Обратно размаху акции» — спокойным бумагам больше, волатильным — меньше (снижает просадку) |
|
|
129
|
-
| Направление торговли | «Только в рост (без шорта)» — классическая покупка акций и продажа купленного с прибылью (работает на любом счёте и ИИС); «В рост и в падение (с шортом)» — дополнительно зарабатывает на падающих акциях за счёт коротких продаж (требуется маржинальная торговля; если на брокерском счёте она выключена, система автоматически переключает счёт в режим «Только в рост»)
|
|
129
|
+
| Направление торговли | «Только в рост (без шорта)» — классическая покупка акций и продажа купленного с прибылью (работает на любом счёте и ИИС); «В рост и в падение (с шортом)» — дополнительно зарабатывает на падающих акциях за счёт коротких продаж (требуется маржинальная торговля; если на брокерском счёте она выключена, система автоматически переключает счёт в режим «Только в рост») |
|
|
130
130
|
| Фильтр падающего рынка | Не открывать новые покупки, когда индекс Мосбиржи одновременно ниже уровня 2 часов назад и уровня торгового дня назад |
|
|
131
131
|
| Плата за заём акций, % годовых | Сколько брокер берёт за заём акций для продажи без покупки. Начисляется за всё время, пока продажа открыта (20% годовых — около 0,05% за сутки) |
|
|
132
132
|
| Окно обучения | На скольких последних днях стратегия учится |
|
|
@@ -123,7 +123,7 @@ $$\text{Edge}_i = \hat{y}_i \cdot \sigma_i \cdot \sqrt{H}$$
|
|
|
123
123
|
|---|---|---|
|
|
124
124
|
| **Самообучение правил торговли (`modelAutoAdapt`)** | `Вкл` | Полный Автомат: включает мульти-горизонтное обучение (`1.5–3.5 ч`), полушаговое сопровождение `H/2`, двухступенчатый порог выхода (`0.35 / 0.95`), временный карантин убыточных бумаг, адаптацию порогов `Long/Short` к тренду индекса и взвешивание слота по силе сигнала (`Conviction Sizing`). При включённом Авто-режиме поля горизонта и порогов управляются автоматически. |
|
|
125
125
|
| **Сколько акций держать (`modelTopK`)** | `2` | Максимальное число одновременных позиций в лонг (и столько же в шорт при режиме `longshort`). `2–3` акции дают максимальную концентрацию в самых сильных сигналах при просадке в пределах 9–11.5%. |
|
|
126
|
-
| **Направление торговли (`modelDirection`)** | `В рост и в падение (с шортом)` (`longshort`) | • `Только в рост (без шорта)` (`long`) — классическая покупка акций и их продажа при фиксации прибыли (подходит для любого счёта и ИИС).<br>• `В рост и в падение (с шортом)` (`longshort`) — покупает лидеров и шортит аутсайдеров с авто-балансировкой по тренду индекса (**максимальная доходность +1 061% за 2,4 года / +134.6% OOS, Шарп 4.04**; на реальном брокерском счёте без подключённой маржинальной торговли шорты отключаются автоматически)
|
|
126
|
+
| **Направление торговли (`modelDirection`)** | `В рост и в падение (с шортом)` (`longshort`) | • `Только в рост (без шорта)` (`long`) — классическая покупка акций и их продажа при фиксации прибыли (подходит для любого счёта и ИИС).<br>• `В рост и в падение (с шортом)` (`longshort`) — покупает лидеров и шортит аутсайдеров с авто-балансировкой по тренду индекса (**максимальная доходность +1 061% за 2,4 года / +134.6% OOS, Шарп 4.04**; на реальном брокерском счёте без подключённой маржинальной торговли шорты отключаются автоматически). |
|
|
127
127
|
| **Горизонт прогноза, часов (`modelHorizon`)** | `2.5` ч *(авто: 1.5–3.5ч)* | В режиме Авто управляется автоматически (мульти-горизонтная траектория `0.6H / 1.0H / 1.4H`). В ручном режиме — на сколько часов вперёд модель предсказывает движение. |
|
|
128
128
|
| **Порог выгоды на вход (`modelMinEdge`)** | `2.5` *(авто)* | В режиме Авто управляется автоматически (`2.5×` издержек). В ручном режиме — во сколько раз ожидаемое движение должно превышать удвоенные издержки. |
|
|
129
129
|
| **Порог на выход (`modelExitRatio`)** | `0.95` *(авто)* | В режиме Авто управляется автоматически (`0.35` на первых двух полушагах, `0.95` по зрелости). В ручном режиме — доля от порога входа для удержания позиции. |
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neuroalpha",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.13",
|
|
4
4
|
"description": "НейроАльфа — ИИ-автопилот для рынка акций Мосбиржи: эмбеддинги акций, самообучение правил, коннекторы Т-Банк / БКС / Финам / Алор и боты Telegram / MAX",
|
|
5
5
|
"author": "Roman A. Perepelkin",
|
|
6
|
-
"license": "
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/proman1968/trading.git"
|
package/public/admin.html
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- Copyright (c) 2026 Roman A. Perepelkin.
|
|
1
|
+
<!-- Copyright (c) 2026 Roman A. Perepelkin. All rights reserved. Proprietary software. -->
|
|
2
2
|
<!doctype html>
|
|
3
3
|
<html lang="ru">
|
|
4
4
|
<head>
|
|
@@ -131,21 +131,27 @@
|
|
|
131
131
|
</div>
|
|
132
132
|
|
|
133
133
|
<div class="card">
|
|
134
|
-
<h2
|
|
135
|
-
<p class="sub"
|
|
134
|
+
<h2>Персональные VIP-токены и Промокоды</h2>
|
|
135
|
+
<p class="sub">Сгенерируйте персональный <code>VIP-…</code> токен (снимает все ограничения на количество счетов, капитал и потолок годовой доходности) или промокод для тарифов «Инвестор» / «Профи».</p>
|
|
136
136
|
<form id="form-promo" class="row-gap" style="flex-wrap:wrap;margin-bottom:14px">
|
|
137
|
-
<input name="code" placeholder="Код (
|
|
138
|
-
<select name="plan" style="width:
|
|
139
|
-
<option value="
|
|
140
|
-
<option value="pro">Тариф
|
|
137
|
+
<input name="code" placeholder="Код (или пусто для авто VIP-…)" style="width:220px">
|
|
138
|
+
<select name="plan" style="width:210px">
|
|
139
|
+
<option value="vip">👑 Тариф «VIP» (Без ограничений)</option>
|
|
140
|
+
<option value="pro">Тариф «Профи» (до 100%/год)</option>
|
|
141
|
+
<option value="investor">Тариф «Инвестор» (до 50%/год)</option>
|
|
141
142
|
</select>
|
|
142
|
-
<input name="days" type="number" value="
|
|
143
|
-
<input name="maxUses" type="number" value="
|
|
144
|
-
<button type="submit" class="primary"
|
|
143
|
+
<input name="days" type="number" value="365" min="1" max="3650" style="width:110px" title="Длительность, дней" placeholder="Дней">
|
|
144
|
+
<input name="maxUses" type="number" value="1" min="1" max="10000" style="width:120px" title="Лимит активаций" placeholder="Лимит">
|
|
145
|
+
<button type="submit" class="primary">Выпустить токен / промокод</button>
|
|
145
146
|
</form>
|
|
146
147
|
<div id="promos-list"></div>
|
|
147
148
|
</div>
|
|
148
149
|
|
|
150
|
+
<div class="card">
|
|
151
|
+
<h2>Заявки на согласование тарифа VIP</h2>
|
|
152
|
+
<div id="vip-reqs-wrap"></div>
|
|
153
|
+
</div>
|
|
154
|
+
|
|
149
155
|
<div class="card">
|
|
150
156
|
<h2>История платежей ЮKassa</h2>
|
|
151
157
|
<div id="payments-wrap"></div>
|
|
@@ -252,19 +258,21 @@
|
|
|
252
258
|
return;
|
|
253
259
|
}
|
|
254
260
|
$('#users-table-wrap').innerHTML = `<table>
|
|
255
|
-
<thead><tr><th>ID</th><th>Имя и Email</th><th>Роль</th><th>Тариф</th><th>Оплачен до</th><th>Мессенджеры</th><th>Сменить
|
|
261
|
+
<thead><tr><th>ID</th><th>Имя и Email</th><th>Роль</th><th>Тариф</th><th>Оферта</th><th>Оплачен до</th><th>Мессенджеры</th><th>Сменить тариф</th></tr></thead>
|
|
256
262
|
<tbody>${list.map((u) => `<tr>
|
|
257
263
|
<td>${u.id}</td>
|
|
258
264
|
<td><b>${esc(u.name)}</b><div class="muted small">${esc(u.email)}</div></td>
|
|
259
265
|
<td><span class="tag ${u.role === 'admin' ? 'mid' : ''}">${esc(u.role)}</span></td>
|
|
260
|
-
<td><span class="tag ${u.plan !== 'free' ? 'ok' : ''}">${esc(u.planName)}</span></td>
|
|
266
|
+
<td><span class="tag ${u.plan === 'vip' ? 'mid' : u.plan !== 'free' ? 'ok' : ''}">${esc(u.planName)}</span></td>
|
|
267
|
+
<td class="muted small">${u.offerAcceptedAt ? `<span class="pos" title="${fmtTs(u.offerAcceptedAt)}">подписана ✓</span>` : '—'}</td>
|
|
261
268
|
<td class="muted small">${u.planUntil > Date.now() ? fmtTs(u.planUntil) : 'бессрочно'}</td>
|
|
262
269
|
<td class="small">${u.tgConnected ? '<span class="pos">TG ✓</span> ' : ''}${u.maxConnected ? '<span class="pos">MAX ✓</span>' : (!u.tgConnected ? '<span class="muted">—</span>' : '')}</td>
|
|
263
270
|
<td>
|
|
264
271
|
<select data-user-plan="${u.id}">
|
|
265
272
|
<option value="free"${u.plan === 'free' ? ' selected' : ''}>Старт (Free)</option>
|
|
266
|
-
<option value="investor"${u.plan === 'investor' ? ' selected' : ''}>Инвестор (
|
|
267
|
-
<option value="pro"${u.plan === 'pro' ? ' selected' : ''}>Профи (
|
|
273
|
+
<option value="investor"${u.plan === 'investor' ? ' selected' : ''}>Инвестор (до 50%/год)</option>
|
|
274
|
+
<option value="pro"${u.plan === 'pro' ? ' selected' : ''}>Профи (до 100%/год)</option>
|
|
275
|
+
<option value="vip"${u.plan === 'vip' ? ' selected' : ''}>👑 VIP (Без ограничений)</option>
|
|
268
276
|
</select>
|
|
269
277
|
</td>
|
|
270
278
|
</tr>`).join('')}</tbody>
|
|
@@ -288,7 +296,7 @@
|
|
|
288
296
|
const users = admState?.users || [];
|
|
289
297
|
const payments = admState?.payments || [];
|
|
290
298
|
$('#kpi-users').textContent = fmtNum(users.length);
|
|
291
|
-
$('#kpi-paid').textContent = fmtNum(users.filter((u) => u.plan === 'investor' || u.plan === 'pro').length);
|
|
299
|
+
$('#kpi-paid').textContent = fmtNum(users.filter((u) => u.plan === 'investor' || u.plan === 'pro' || u.plan === 'vip').length);
|
|
292
300
|
const rev = payments.filter((p) => p.status === 'succeeded').reduce((s, p) => s + (Number(p.amount_rub) || 0), 0);
|
|
293
301
|
$('#kpi-revenue').textContent = `${fmtNum(rev)} ₽`;
|
|
294
302
|
$('#kpi-bots').textContent = fmtNum(users.filter((u) => u.tgConnected || u.maxConnected).length);
|
|
@@ -307,11 +315,17 @@
|
|
|
307
315
|
bf.secretKey.placeholder = admState.billing?.hasSecret ? 'Секретный ключ задан (оставьте пустым, чтобы не менять)' : 'Секретный ключ ЮKassa';
|
|
308
316
|
bf.sendReceipt.checked = Boolean(admState.billing?.sendReceipt);
|
|
309
317
|
|
|
310
|
-
// Promos
|
|
318
|
+
// Promos & VIP tokens
|
|
311
319
|
const promos = admState.promos || [];
|
|
312
320
|
$('#promos-list').innerHTML = promos.length
|
|
313
|
-
? `<table><thead><tr><th
|
|
314
|
-
: '<p class="muted small">Активных промокодов пока нет.</p>';
|
|
321
|
+
? `<table><thead><tr><th>Токен / Код</th><th>Тариф</th><th>Дней</th><th>Использовано</th><th>Создан</th></tr></thead><tbody>${promos.map((p) => `<tr><td><code>${esc(p.code)}</code></td><td><span class="tag ${p.plan === 'vip' ? 'mid' : 'ok'}">${esc(p.plan.toUpperCase())}</span></td><td>${p.days} дн.</td><td>${p.used_count} / ${p.max_uses}</td><td class="muted small">${fmtTs(p.created_at)}</td></tr>`).join('')}</tbody></table>`
|
|
322
|
+
: '<p class="muted small">Активных VIP-токенов и промокодов пока нет.</p>';
|
|
323
|
+
|
|
324
|
+
// VIP requests
|
|
325
|
+
const vreqs = admState.vipRequests || [];
|
|
326
|
+
$('#vip-reqs-wrap').innerHTML = vreqs.length
|
|
327
|
+
? `<table><thead><tr><th>Дата</th><th>Имя</th><th>Контакт / Email</th><th>Планируемый капитал</th><th>Пользователь</th></tr></thead><tbody>${vreqs.map((v) => `<tr><td class="muted small">${fmtTs(v.createdAt)}</td><td><b>${esc(v.name)}</b></td><td><code>${esc(v.contact || v.email)}</code></td><td>${esc(v.capitalRub || '—')}</td><td>${v.userId ? `#${v.userId}` : 'гость'}</td></tr>`).join('')}</tbody></table>`
|
|
328
|
+
: '<p class="muted small">Новых заявок на согласование тарифа VIP пока нет.</p>';
|
|
315
329
|
|
|
316
330
|
// Payments
|
|
317
331
|
const pays = admState.payments || [];
|
|
@@ -369,9 +383,18 @@
|
|
|
369
383
|
e.preventDefault();
|
|
370
384
|
const f = e.target.elements;
|
|
371
385
|
try {
|
|
372
|
-
await api('/api/admin/promo', {
|
|
386
|
+
await api('/api/admin/promo', {
|
|
387
|
+
method: 'POST',
|
|
388
|
+
body: {
|
|
389
|
+
code: f.code.value,
|
|
390
|
+
plan: f.plan.value,
|
|
391
|
+
days: f.days.value,
|
|
392
|
+
maxUses: f.maxUses.value,
|
|
393
|
+
generateVip: f.plan.value === 'vip' && !f.code.value.trim(),
|
|
394
|
+
},
|
|
395
|
+
});
|
|
373
396
|
f.code.value = '';
|
|
374
|
-
toast('
|
|
397
|
+
toast('Токен / промокод выпущен');
|
|
375
398
|
loadAdminState();
|
|
376
399
|
} catch (err) { toast(err.message); }
|
|
377
400
|
});
|