Прогноз продаж

Как считается число

По истории продаж в вашей 1С, без нейросети. Ниже — правила, проверка на тестовой базе и формулы.

VOLY AI ставится в 1С отдельным расширением и считает прогноз продаж по каждой позиции на ближайшие месяцы — с диапазоном «от–до», отметкой надёжности и объяснением, откуда взялось число. Ниже — как это устроено на самом деле, какие решения мы приняли и чего прогноз пока не умеет.

Прогноз сейчас работает в 1С:Управление нашей фирмой и 1С:Бухгалтерии предприятия. Для остальных конфигураций совместимость проверяем до установки.

Почему не нейросеть

Первое, что хочется сделать с прогнозом продаж в 2026 году, — отдать его большой модели или градиентному бустингу. Мы этого не сделали, и дело не в моде.

  • Данные 1С помесячные и короткие. Прогноз строится по ряду «товар × месяц» за последние три года. Это не миллионы чеков, а десятки точек на позицию — на таком объёме классические модели не хуже сложных, а объяснить их результат проще.

  • Большая часть каталога продаётся редко. На тестовой базе УНФ у 3 845 позиций из 4 221 спрос редкий: продажи бывают не каждый месяц. Для такого спроса есть специальный метод, и он важнее выбора «умной» модели.

  • Число должно быть проверяемым. Пользователь видит, какой моделью посчитан прогноз и какая у неё ошибка на уже прошедших месяцах. Языковая модель в расчёте не участвует: числа считает программа на сервере по заданным правилам.

Откуда данные

1С сама выгружает продажи в сервис VOLY AI: чистые продажи (с учётом возвратов) по товару и месяцу за 36 месяцев. Источник зависит от конфигурации: в УНФ — регистр «Продажи», в Бухгалтерии — проведённые реализации, отчёты о розничных продажах и возвраты. Услуги в прогноз не попадают. Организация и склад в ряд не входят: ряд один на товар по всей базе.

Для прогноза в сервис уходят только количества, суммы и себестоимость продаж по кодам товаров и коды складов — без наименований товаров и контрагентов. Названия подставляет сама 1С, когда показывает прогноз.

Граница истории — по данным, а не по календарю. Если база — копия на конец июля, а прогноз считают в сентябре, календарный подход решит, что в августе продаж не было, и занизит прогноз. Поэтому 1С сообщает дату последнего движения в учёте, и месяц, обрезанный посередине, в историю не берётся.

Как строится прогноз по каждой позиции

Ветки проверяются по порядку.

  • Товар больше не продаётся. Если продаж нет 12 месяцев и дольше и это дольше обычного интервала между продажами этой позиции, прогноз обнуляется. Без этого правила метод редкого спроса продолжал бы «помнить» давние отгрузки и прогнозировать продажи товару, который давно выведен. Сравнение с собственным интервалом бережёт сезонные позиции, которые продаются раз в год.

  • Мало истории (меньше 6 месяцев). Прогноз — среднее по имеющимся месяцам, диапазон широкий, точность не оценивается.

  • Редкий спрос. Если продажи случаются в среднем реже, чем раз в 1,32 месяца (порог Синтетоса–Бойлана), используется метод Кростона с поправкой SBA. Его прогноз — средний спрос в месяц, а не обещание продажи в каждом месяце.

  • Обычный ряд. Соревнуются четыре модели: скользящее среднее, «как тот же месяц год назад», сглаживание с трендом (Хольт) и с трендом и сезонностью (Хольт–Уинтерс). Модель выбирается по ошибке на нескольких прошлых срезах истории, при равной ошибке — более простая. Последние три месяца в выборе не участвуют: на них выбранную модель только проверяют, и эта ошибка показывается пользователю. Затем модель переобучается на всей истории и считает будущие месяцы.

Разовые оптовые отгрузки. Одна крупная отгрузка на фоне обычных продаж способна раздуть прогноз на каждый будущий месяц. Поэтому месяц, в котором продано не меньше чем в 5 раз больше обычного и не меньше 10 единиц, для обучения моделей берётся как обычный. В фактических продажах он остаётся, а в обосновании позиции указано, какая отгрузка учтена так и почему. Последние два месяца правило не трогает: по ним рост не отличить от разовой отгрузки. На тестовой базе правило сработало на 29 позициях из 95 проверенных, прогноз по ним снизился в 2–3 раза.

Диапазон и надёжность

Диапазон «от–до» считается по разбросу ошибок модели на прошедших месяцах и расширяется с горизонтом. Это эвристика: мы не обещаем, что факт попадёт в диапазон с заданной вероятностью, — калибровки на полевых данных ещё не было.

Надёжность показывается по каждой позиции в жёстком порядке:

ОтметкаКогда
проблемы учётапо товару открыты находки проверки склада: минусовые остатки, дубли, расхождения штрихкодов
нет движенияпрогноз обнулён по правилу выше
мало историименьше 6 месяцев продаж
редкие продажипрогноз по методу Кростона
высокая / средняя / низкаяошибка на отложенных месяцах до 20%, до 50%, больше 50%
не оцененаошибку в процентах посчитать не из чего

Первая строка — связь с проверкой склада: прогноз наследует ошибки учёта. Исправили учёт и снова проверили склад — отметка снимается, даже если прогноз считали раньше.

Что видит пользователь

Вкладка «Прогноз продаж» в самой 1С: прогноз и диапазон за выбранный период, цена по факту продаж за год и сумма, колонки «Было» (факт за такой же период перед прогнозом) и «Отклонение», надёжность, дата последней продажи и обоснование. Прогноз стоит рядом с текущим остатком — видно, где товара может не хватить.

После каждого расчёта итоги — позиции с минусовыми остатками, редкий спрос, короткая история — приходят репликой в чат ассистента и уведомлением в колокольчик 1С. Тексты этих итогов собираются по правилам, модель их не пишет.

Прогноз пересчитывается по кнопке «Обновить прогноз» и, если администратор включил, каждую ночь в 02:00.

Проверка на живой базе

21.09.2026 мы сверили выгрузку прогноза с тестовой копией базы УНФ. Арифметика совпала во всех ветках. Ошибки нашлись не в вычислениях, а в предпосылках: календарная граница истории и отсутствие правила для давно не продававшихся товаров. После исправления из 4 234 позиций с продажами за три года прогноз обнуляется у 2 397 — у 1 914 единственная отгрузка была больше года назад, 237 не продавались два года и дольше. С прогнозом остаются 1 835 позиций.

Чего прогноз пока не делает

Честный список — он же план работ:

  • не восстанавливает спрос в месяцы, когда товара не было на складе: для этого нужны дни с нулевым остатком;

  • не прогнозирует по категориям — для редких позиций это было бы точнее поштучного;

  • не различает размеры и цвета (характеристики номенклатуры);

  • не учитывает заказы покупателей, акции и поступления;

  • не считает страховой запас и рекомендованный заказ со сроками поставки;

  • не создаёт документов. «План продаж» и «Заказ поставщику» по прогнозу — следующий этап, и будут они создаваться только явной командой пользователя;

  • не обещает точность в процентах: проверки на реальных данных клиентов ещё впереди.

Если у вас УНФ или Бухгалтерия и хочется посмотреть прогноз на своей базе — оставьте заявку на пилот или напишите на 1c@voly.codes. Цены, состав продуктов и условия.

Приложение: формулы

Для тех, кто хочет проверить расчёт руками. Обозначения: y_t — чистые продажи позиции в месяце t (продажи минус возвраты), T — последний полный месяц истории, h = 1, 2, \dots — шаг прогноза в месяцах, \hat y_{T+h} — прогноз. Прогноз количества не бывает ниже нуля: \hat y \leftarrow \max(0, \hat y) .

Какая ветка

Средний интервал спроса (ADI) — длина ряда n (от первой продажи до T ) на число месяцев с движением:

\mathrm{ADI} = \frac{n}{\#\{t : y_t \ne 0\}}

Считается без последних трёх месяцев — они отложены для проверки. Если \mathrm{ADI} > 1{,}32 , спрос редкий.

Нет движения. Пусть d — число месяцев без продаж на конец ряда, k — число месяцев с продажами, t_1 и t_k — первый и последний из них. Обычный интервал между продажами \bar q = (t_k - t_1)/(k - 1) . Прогноз обнуляется, если

d \ge 12 \quad \text{и} \quad \bigl(k = 1 \ \text{или}\ d > \bar q\bigr).

Мало истории (меньше 6 месяцев, n < 6): \hat y_{T+h} = \frac{1}{n}\sum_t y_t , диапазон

[0;\ 2\hat y] .

Разовая отгрузка

m — медиана месяцев с продажами. Месяц t — разовая отгрузка, если

y_t \ge \max(5m,\ 10)

и он не входит в два последних месяца. Правило работает, только если месяцев с продажами больше трёх, а таких отгрузок не больше \max(1, \lfloor k/6 \rfloor) . Для обучения моделей y_t заменяется медианой остальных месяцев с продажами; ошибки и «Было» считаются по настоящим продажам.

Модели обычного ряда

Скользящее среднее: \hat y_{T+h} = \frac{1}{3}(y_T + y_{T-1} + y_{T-2}) .

Тот же месяц год назад: \hat y_{T+h} = y_{T+h-12} .

Хольт (уровень \ell и тренд b ):

\ell_t = \alpha y_t + (1-\alpha)(\ell_{t-1} + b_{t-1}), \qquad b_t = \beta(\ell_t - \ell_{t-1}) + (1-\beta)\, b_{t-1}
\hat y_{T+h} = \ell_T + h\, b_T

Старт: \ell_1 = y_1 , b_1 = y_2 - y_1 . Параметры \alpha, \beta \in {0{,}1;\ 0{,}3;\ 0{,}5;\ 0{,}7;\ 0{,}9} — по минимуму суммы квадратов ошибок на шаг вперёд.

Хольт–Уинтерс, аддитивная сезонность ( s — сезонная поправка, период 12):

\ell_t = \alpha (y_t - s_{t-12}) + (1-\alpha)(\ell_{t-1} + b_{t-1})
b_t = \beta(\ell_t - \ell_{t-1}) + (1-\beta)\, b_{t-1}, \qquad s_t = \gamma (y_t - \ell_t) + (1-\gamma)\, s_{t-12}
\hat y_{T+h} = \ell_T + h\, b_T + s_{T+h-12}

Начальные уровень, тренд и сезонные поправки берутся из первых двух лет; поэтому модели нужно не меньше 24 месяцев. \alpha, \beta, \gamma \in {0{,}1;\ 0{,}3;\ 0{,}5} .

Редкий спрос: Кростон с поправкой SBA

Сглаживаются отдельно размер продажи z и интервал между продажами p . Обновление — только в месяцы с продажей; q — сколько месяцев прошло с предыдущей продажи:

z \leftarrow \alpha y_t + (1-\alpha)\, z, \qquad p \leftarrow \alpha q + (1-\alpha)\, p
\hat y_{T+h} = \Bigl(1 - \frac{\alpha}{2}\Bigr)\frac{z}{p}

Старт: z — первая продажа, p = \mathrm{ADI} . \alpha \in {0{,}1;\ 0{,}2;\ 0{,}3} . Множитель 1 - \alpha/2 — поправка Синтетоса–Бойлана: без неё метод Кростона систематически завышает прогноз; поправка это смещение в основном снимает, но не до нуля. Прогноз одинаков на все месяцы горизонта — это средний спрос в месяц.

Выбор модели и ошибки

Ошибка e_t = \hat y_t - y_t . Модель выбирается по WAPE на нескольких (до трёх) прошлых срезах истории до отложенных месяцев:

\mathrm{WAPE} = \frac{\sum |e_t|}{\sum |y_t|}\cdot 100\%

(если все y_t = 0 — по средней абсолютной ошибке). На трёх отложенных месяцах выбранную модель проверяют и показывают пользователю:

\mathrm{MAPE} = \frac{1}{|P|}\sum_{t \in P} \frac{|e_t|}{y_t}\cdot 100\%, \qquad P = \{t : y_t > 0\}

Отметка надёжности: MAPE до 20% — высокая, до 50% — средняя, выше — низкая.

Диапазон

\hat y_{T+h} \pm 1{,}28 \cdot \sigma^{*} \cdot \sqrt{h}, \qquad \sigma^{*} = \max\bigl(\mathrm{sd}(e),\ \mathrm{RMSE}(e)\bigr)

по ошибкам на отложенных месяцах (если их меньше двух — по ошибкам на обучении; если и там меньше двух — \sigma^{*} = 0{,}25 \hat y ). Нижняя граница не ниже нуля, для редкого спроса — всегда ноль. Множитель 1,28 взят от нормального 80%-интервала, но покрытие 80% не проверено и не обещается.

Обсудить пилот