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.
Files changed (41) hide show
  1. package/LICENSE +13 -17
  2. package/README.md +4 -2
  3. package/bin/cli.js +1 -1
  4. package/deploy/install.sh +1 -1
  5. 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
  6. 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
  7. package/package.json +2 -2
  8. package/public/admin.html +43 -20
  9. package/public/app.js +524 -211
  10. package/public/index.html +43 -3
  11. package/public/landing.html +328 -115
  12. package/public/legal.html +37 -16
  13. package/public/styles.css +24 -3
  14. package/server/api/routes.js +61 -29
  15. package/server/auth/index.js +109 -20
  16. package/server/billing/yookassa.js +1 -1
  17. package/server/brokers/index.js +179 -34
  18. package/server/config.js +1 -1
  19. package/server/data/moex.js +1 -1
  20. package/server/db.js +17 -3
  21. package/server/hub.js +1 -1
  22. package/server/index.js +4 -4
  23. package/server/llm/client.js +1 -1
  24. package/server/llm/providers.js +1 -1
  25. package/server/model/dataset.js +1 -1
  26. package/server/model/forecast.js +188 -17
  27. package/server/model/linalg.js +1 -1
  28. package/server/model/live.js +6 -19
  29. package/server/model/metrics.js +1 -1
  30. package/server/model/models.js +1 -1
  31. package/server/model/profiles.js +1 -1
  32. package/server/model/research.js +12 -36
  33. package/server/model/vocab.js +1 -1
  34. package/server/news/index.js +1 -1
  35. package/server/notify/index.js +1 -1
  36. package/server/params-meta.js +4 -3
  37. package/server/settings.js +1 -1
  38. package/server/strategist/analytics.js +2 -2
  39. package/server/strategist/index.js +2 -2
  40. package/server/strategist/tools.js +1 -1
  41. package/server/util.js +1 -1
package/LICENSE CHANGED
@@ -1,21 +1,17 @@
1
- MIT License
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
- Permission is hereby granted, free of charge, to any person obtaining a copy
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
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
9
+ Без предварительного письменного разрешения Правообладателя строго запрещается:
10
+ 1. Копировать, воспроизводить, распространять, публиковать или передавать третьим лицам исходный или объектный код Программы (полностью или частично);
11
+ 2. Модифицировать, адаптировать, декомпилировать, дизассемблировать или осуществлять обратную разработку (reverse engineering) Программы и её алгоритмов;
12
+ 3. Сдавать в аренду, сублицензировать или использовать Программу для оказания услуг третьим лицам (включая ретрансляцию торговых сигналов и подключение счетов автоследования);
13
+ 4. Удалять или изменять знаки охраны авторского права и сведения о Правообладателе и Операторе платформы.
14
14
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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. Распространяется по лицензии [MIT](LICENSE).
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. Licensed under the MIT License.
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
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # Copyright (c) 2026 Roman A. Perepelkin. Licensed under the MIT License.
2
+ # Copyright (c) 2026 Roman A. Perepelkin. All rights reserved. Proprietary software.
3
3
  set -e
4
4
 
5
5
  echo "======================================================"
@@ -126,7 +126,7 @@
126
126
  | Минимальное удержание, часов | Не закрывать позицию раньше этого времени при обычном ослаблении прогноза. Снижает число сделок и комиссий |
127
127
  | Сколько акций держать | Сколько лучших по прогнозу акций держать одновременно (при продажах — и столько же на продажу) |
128
128
  | Распределение суммы между акциями | «Поровну» — одинаково; «Обратно размаху акции» — спокойным бумагам больше, волатильным — меньше (снижает просадку) |
129
- | Направление торговли | «Только в рост (без шорта)» — классическая покупка акций и продажа купленного с прибылью (работает на любом счёте и ИИС); «В рост и в падение (с шортом)» — дополнительно зарабатывает на падающих акциях за счёт коротких продаж (требуется маржинальная торговля; если на брокерском счёте она выключена, система автоматически переключает счёт в режим «Только в рост»); «Хедж 50/50 (рост + падение)» — держит позиции в рост и в падение на равные суммы, чтобы не зависеть от падения индекса |
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**; на реальном брокерском счёте без подключённой маржинальной торговли шорты отключаются автоматически).<br>• `Хедж 50/50 (рост + падение)` (`neutral`) — открывает позиции в рост и в падение строго парами на равные суммы. |
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.12",
3
+ "version": "0.3.13",
4
4
  "description": "НейроАльфа — ИИ-автопилот для рынка акций Мосбиржи: эмбеддинги акций, самообучение правил, коннекторы Т-Банк / БКС / Финам / Алор и боты Telegram / MAX",
5
5
  "author": "Roman A. Perepelkin",
6
- "license": "MIT",
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. Licensed under the MIT License. -->
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>Промокоды (выдача партнёрского и пробного доступа)</h2>
135
- <p class="sub">Промокод активируется пользователем в личном кабинете или в настройках терминала.</p>
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="Код (напр. ALPHA14)" required style="width:170px">
138
- <select name="plan" style="width:180px">
139
- <option value="investor">Тариф «Инвестор»</option>
140
- <option value="pro">Тариф «Профи»</option>
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="14" min="1" max="365" style="width:110px" title="Длительность, дней" placeholder="Дней">
143
- <input name="maxUses" type="number" value="50" min="1" max="10000" style="width:120px" title="Лимит активаций" placeholder="Лимит">
144
- <button type="submit" class="primary">Создать промокод</button>
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>Сменить тариф (на 30 дн.)</th></tr></thead>
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' : ''}>Инвестор (3 900 ₽)</option>
267
- <option value="pro"${u.plan === 'pro' ? ' selected' : ''}>Профи (9 900 ₽)</option>
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>Код</th><th>Тариф</th><th>Дней</th><th>Использовано</th><th>Создан</th></tr></thead><tbody>${promos.map((p) => `<tr><td><code>${esc(p.code)}</code></td><td>${esc(p.plan)}</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>`
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', { method: 'POST', body: { code: f.code.value, plan: f.plan.value, days: f.days.value, maxUses: f.maxUses.value } });
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
  });