ITO/DOI库存周转率优化闭环 — 库存效率KPI驱动的补货与清仓决策
Skill-ITO-DOI-Inventory-Turnover-Optimizer · 04-供应链
1. 解决的问题
高DOI导致$17万资金压在仓库利息白付——ITO约束补货优化将库存周转从65天压缩至44天,释放资金$17.5万,ROI超1000%
2. 核心算法逻辑
业务背景(陈凤霞实战经验):ITO(Inventory Turnover,库存周转次数)和DOI(Days of Inventory,库存天数)是电商供应链最核心的效率指标。书中指出:库存是过程,效率是结果——过高的DOI意味着资金被压在仓库里,过低的DOI意味着频繁缺货。跨境母婴卖家的行业基准是ITO≥8次/年(DOI≤45天),优秀卖家可达ITO 12次(DOI 30天)。
3. 业务应用场景
- 业务问题:某卖家年销$300万,平均DOI 65天(行业基准45天),每多占用20天约$15万资金,年额外持有成本约$3万,且旺季爆款缺货(DOI仅8天)与滞销款积压同时存在 - 数据要求:所有SKU的日销量、当前库存、在途库存、采购成本 - 算法应用: 1. 计算全SKU ITO矩阵,发现A类SKU(吸奶器)DOI仅10天(偏低),C类SKU(旧款配件)DOI 150天(严重积压) 2. 资金重分配:从DOI>90天的SKU减少采购,释放$8万资金用于A类SKU加急补货 3. C类积压SKU启动阶梯促销清仓(每2周降价5%) 4. 3个月后:全品类平均DOI从65天降至44天,达行业基准
场景B:多仓库存周转一致化(FBA+海外仓)
- **业务问题**:FBA仓DOI 30天(正常),自营海外仓DOI 90天(严重积压),两仓割裂导致整体效率低下 - **算法应用**:统一计算跨仓DOI,发现海外仓积压的UV消毒仓可以调拨到FBA(FBA偏低SKU),减少重新采购;同时对海外仓独有滞销款启动清仓 - **预期产出**:跨仓整体DOI从60天降至40天,释放$20万沉淀资金
4. 输入数据要求
请查看原始代码模板获取输入规格。
5. 输出结果
请查看原始代码模板获取输出规格。
6. 业务价值 / ROI
- ROI 预估:年销$300万卖家,DOI从65天降至44天,释放约$17.5万资金;按20%资金成本,年省$3.5万持有成本;同时爆款缺货率降低带来GMV提升12%≈$36万;年总收益约$40万,系统成本$3万,ROI≈1300%
- 实施难度:⭐⭐☆☆☆(公式简单,关键是数据质量——日销量、库存数据需要准确实时)
- 优先级:⭐⭐⭐⭐⭐(所有供应链KPI中最直接与资金效率挂钩的指标,强烈推荐作为基础能力建设)
- 适用规模:所有卖家,SKU数>20个就值得系统化追踪
- 数据依赖:每日SKU销量、实时库存(含FBA+自营仓)、采购成本数据
7. 代码模板
代码块数量:1 · 路径:未检测到
"""
ITO/DOI库存周转率优化闭环系统
功能:周转率计算 + 五色灯状态分类 + ITO约束补货优化 + 清仓建议
"""
import numpy as np
import pandas as pd
from dataclasses import dataclass, field
from typing import List, Dict, Optional, Tuple
from scipy.optimize import linprog
import warnings
warnings.filterwarnings('ignore')
@dataclass
class InventorySKU:
"""SKU库存状态"""
sku_id: str
abc_class: str # A/B/C
current_stock: int # 当前库存(含FBA+自营)
in_transit: int # 在途
daily_sales: float # 近30天日均销量
unit_cost: float # 采购成本($)
lead_time_days: int # 采购提前期
safety_stock_days: int # 安全库存天数
season_factor: float = 1.0 # 季节调整系数(旺季>1,淡季<1)
@property
def target_doi(self) -> float:
"""目标DOI = 提前期 + 安全库存"""
return (self.lead_time_days + self.safety_stock_days) * self.season_factor
@property
def current_doi(self) -> float:
"""当前DOI(含在途)"""
total_stock = self.current_stock + self.in_transit
if self.daily_sales <= 0:
return 999.0
return total_stock / self.daily_sales
@property
def inventory_value(self) -> float:
"""当前库存价值($)"""
return (self.current_stock + self.in_transit) * self.unit_cost
@property
def ito_annual(self) -> float:
"""年化ITO(次/年)"""
if self.current_doi >= 999:
return 0.0
return 365 / self.current_doi
def classify_doi_status(sku: InventorySKU) -> Tuple[str, str]:
"""五色灯DOI状态分类"""
doi = sku.current_doi
target = sku.target_doi
if doi <= 0 or sku.current_stock == 0:
return 'BLACK', '⚫缺货'
elif doi < target * 0.8:8. 论文来源
- 2402.07334