← Макалаларга кайтуу
June 12, 2026
5 мүн окуу

Тобокелдикти Эске Алган Позиция Көлөмүн Аныктоо үчүн Конформдук Божомол

Тобокелдикти Эске Алган Позиция Көлөмүн Аныктоо үчүн Конформдук Божомол
#uncertainty
#conformal-prediction
#risk
#position-sizing
#statistics
#algorithmic-trading
🧠
Part 4 of 4 · Collection
Deep Learning for Markets

Позиция көлөмүн аныктоонун ар кандай формуласы белгисиздиктин баасын талап кылат. Kelly критерийине жеңүү ыктымалдыгы жана төлөм катышы керек (караңыз: Стратегиялар үчүн Kelly критерийи). Орточо-дисперсия оптималдаштыруу ковариация матрицасын талап кылат. VaR кирешелердин бөлүштүрүлүшүн талап кылат. Булардын баары маалыматтарды жаратуучу процесс жөнүндө болжолдоолорду талап кылат — каржы рыногу адатта бузган болжолдоолорду.

Конформдук божомол таптакыр башка нерсени сунуштайт: эч кандай параметрдик бөлүштүрүү болжолдоосуз, чектелген тандоо үчүн камтуу кепилдиги бар божомол интервалдары. Эгер сиз 90% камтууну сурасаңыз, жок дегенде 90% камтууга ээ болосуз — кирешелер гаусстык, калың куйруктуу, ийри же гетероскедастикалык болобу, айырмасы жок. Жалгыз талап — алмашуучулук (exchangeability), же кийинчерээк көрөрүбүздөй, андан да алсызыраак шарттар.

Бул макалада теория, негизги варианттар жана Python'до позиция көлөмүн аныктоо үчүн практикалык ишке ашыруу камтылган.

Негизги Идея: Nonconformity Упайлары

Квантиль чеги белгиленген nonconformity (калдык) упайларынын бөлүштүрүлүшү — конформдук калибрлөөнүн өзөгү

Конформдук божомол жаңы байкоонун мурунку маалыматтарга карата канчалык "жат" экенин өлчөө аркылуу иштейт. Бул жаттык nonconformity упайы менен сандык жактан өлчөнөт — маалыматтын калган бөлүгүндө көрүлгөн үлгүгө бир чекиттин канчалык начар дал келерин өлчөгөн ар кандай функция.

Регрессия үчүн (киреше сыяктуу үзгүлтүксүз маанини божомолдоо), эң жөнөкөй nonconformity упайы — абсолюттук калдык:

Ri=Yiμ^(Xi)R_i = |Y_i - \hat{\mu}(X_i)|

бул жерде μ^\hat{\mu} — ар кандай чекиттик божомолдоочу (сызыктуу регрессия, random forest, нейрондук тармак — маанилүү эмес), ал (Xi,Yi)(X_i, Y_i) — маалымат чекити.

Негизги түшүнүк: эгер (X1,Y1),,(Xn,Yn),(Xn+1,Yn+1)(X_1, Y_1), \ldots, (X_n, Y_n), (X_{n+1}, Y_{n+1}) маалымат чекиттери алмашуучу болсо, анда Rn+1R_{n+1} дин R1,,Rn,Rn+1R_1, \ldots, R_n, R_{n+1} арасындагы даражасы {1,,n+1}\{1, \ldots, n+1\} боюнча бир калыпта бөлүштүрүлөт. Бул — таза комбинаторикалык факт, ал XX же YY дин бөлүштүрүлүшү жөнүндө эч кандай болжолдоону талап кылбайт.

Ушул даража бир калыптуулугунан биз чектелген тандоо камтуусу бар божомол интервалдарын түзө алабыз.

Split Конформдук Божомол

Split конформдук божомол: маалыматтар окутуу жана калибрлөө бөлүктөрүнө бөлүнгөн, калибрлөө калдыктары божомол интервалдарын пайда кылат

Split конформдук божомол (Papadopoulos жана башк., 2002; Lei жана башк., 2018) — эң практикалык вариант. Алгоритм жөнөкөй:

1-кадам. Маалыматтарды окутуу топтому Dtrain\mathcal{D}_{\text{train}} жана калибрлөө топтомуна Dcal={(X1,Y1),,(Xn,Yn)}\mathcal{D}_{\text{cal}} = \{(X_1, Y_1), \ldots, (X_n, Y_n)\} бөлүңүз.

2-кадам. Dtrain\mathcal{D}_{\text{train}} де каалаган μ^\hat{\mu} моделин ыңгайлаштырыңыз.

3-кадам. Калибрлөө топтомунда nonconformity упайларын эсептеңиз:

Ri=Yiμ^(Xi),i=1,,nR_i = |Y_i - \hat{\mu}(X_i)|, \quad i = 1, \ldots, n

4-кадам. Каалаган камтылбоочулук деңгээли α(0,1)\alpha \in (0, 1) үчүн, q^\hat{q} ны R1,,RnR_1, \ldots, R_n дин (1α)(n+1)n\frac{\lceil (1 - \alpha)(n + 1) \rceil}{n} эмпирикалык квантили катары алыңыз. Тактап айтканда, бул — (1α)(n+1)\lceil (1 - \alpha)(n + 1) \rceil-чи эң кичине калдык (жана (1α)(n+1)>n\lceil (1 - \alpha)(n + 1) \rceil > n болгондо, б.а. өтө кичине nn үчүн, q^=+\hat{q} = +\infty).

5-кадам. Жаңы Xn+1X_{n+1} чекити үчүн божомол интервалы:

C(Xn+1)=[μ^(Xn+1)q^,  μ^(Xn+1)+q^]C(X_{n+1}) = \left[\hat{\mu}(X_{n+1}) - \hat{q}, \; \hat{\mu}(X_{n+1}) + \hat{q}\right]

Камтуу Кепилдиги

Калибрлөө маалыматтарынын жана жаңы тест чекитинин алмашуучулугу алдында:

P(Yn+1C(Xn+1))1α\mathbb{P}\left(Y_{n+1} \in C(X_{n+1})\right) \geq 1 - \alpha

Бул — чектелген тандоо кепилдиги, асимптотикалык болжолдоо эмес. Ал ар кандай μ^\hat{\mu} модели, маалыматтардын ар кандай бөлүштүрүлүшү жана ар кандай nn тандоо көлөмү үчүн аткарылат. Эгер μ^\hat{\mu} начар божомолдоочу болсо, интервалдар жөн гана кеңири болот. Камтуу кепилдиги баары бир аткарылат.

Упайларда тең маанилер болбогондо жогорку чек да бар: P(Yn+1C(Xn+1))1α+1n+1\mathbb{P}(Y_{n+1} \in C(X_{n+1})) \leq 1 - \alpha + \frac{1}{n+1}, ошондуктан камтуу бекеринен консервативдүү эмес.

Бул Соода үчүн Эмне Үчүн Маанилүү

Мисалы, сызыктуу регрессиядан алынган салттуу божомол интервалдары гаусстык каталарды божомолдойт. Маалыматтардын негизги бөлүгүнө калибрленген гаусстык интервал чыныгы калдыктар калың куйруктуу болгондо (мисалы, аз эркиндик даражасы бар Student-tt) куйруктарды катуу туура эмес баалашы мүмкүн: борбордук масса гаусстыктан ичкерээк, ошондуктан дисперсияга дал келген гаусстык интервал борборго жакын жерде ашыкча камтыйт, бирок куйруктарда жетишсиз камтыйт, ал эми куйрукка ылайыкташтырылган интервал тескерисинче иш алып барат. Маселе жалгыз сыйкырдуу санда эмес — маселе параметрдик интервалдын чыныгы камтуусу сиз текшербеген бөлүштүрүү болжолдоосуна көз каранды болушунда.

Конформдук божомол интервалдары муну айланып өтөт. Алар модель белгисиз болгондо автоматтык түрдө кеңейет жана чыныгы ката бөлүштүрүлүшүнө карабастан четки камтууну сактайт. Трейдер үчүн бул төмөнкүнү билдирет:

  • Эгер сиз позицияларды интервал энинин тескери пропорциясы менен өлчөсөңүз, модель белгисиз болгондо сиз таасирди автоматтык түрдө азайтасыз.
  • Камтуу кепилдиги сиздин тобокелдик баалооңуздун чынчыл экенин билдирет — эгер сиз "ишке ашкан кирешелердин 90%-ы ушул интервалга түшөт" десеңиз, бул билдирүү статистикалык жактан жарактуу (четки мааниде, алмашуучулук алдында).

Толук Конформдук жана Jackknife+

Split conformal жөнөкөй, бирок маалыматтарды текке кетирет: калибрлөө топтомун окутуу үчүн колдонсо болбойт. Эки альтернатива муну чечет.

Толук Конформдук Божомол

Толук конформдук божомол (Vovk жана башк., 2005) бардык маалыматтарды окутуу үчүн да, калибрлөө үчүн да колдонот. Yn+1Y_{n+1} дин ар бир yy талапкер мааниси үчүн:

  1. Маалыматтар топтомун (Xn+1,y)(X_{n+1}, y) менен толуктаңыз.
  2. Модель толукталган топтомдо кайра ыңгайлаштырыңыз.
  3. Бардык nonconformity упайларын эсептеңиз.
  4. Эгер (Xn+1,y)(X_{n+1}, y) үчүн упай өтө экстремалдуу болбосо, yy ны божомол топтомуна кошуңуз.

Божомол топтому:

C(Xn+1)={y:{i:RiyRn+1y}n+1>α}C(X_{n+1}) = \left\{y : \frac{|\{i : R_i^y \geq R_{n+1}^y\}|}{n+1} > \alpha \right\}

бул жерде RiyR_i^y — толукталган топтом менен эсептелген nonconformity упайлары.

Толук conformal эң тар интервалдарды берет, бирок көпчүлүк моделдер үчүн эсептөө жагынан мүмкүн эмес деңгээлде кымбат — торчодо ар бир талапкер yy үчүн моделди кайра ыңгайлаштыруу керек. Киреше божомолу үчүн бул бир божомолго миңдеген жолу кайра ыңгайлаштырууну билдириши мүмкүн.

Jackknife+ (Barber жана башк., 2021)

Jackknife+ тең салмактуулукту табат. Ал leave-one-out (LOO) калдыктарын колдонот, бирок LOO бөлүктөрү боюнча ыңгайлаштырылган моделдеги өзгөрүлмөлүүлүктү эске алат.

μ^i\hat{\mu}_{-i} дегенибиз ii чекитинен башка бардык маалыматтарда окутулган модель дейли. LOO nonconformity упайын жалгыз абсолюттук калдык менен аныктайбыз:

Ri=Yiμ^i(Xi)R_i = |Y_i - \hat{\mu}_{-i}(X_i)|

Jackknife+ божомол интервалы андан кийин тест чекитиндеги LOO божомолдорунан, ушул калдыктар менен кеңейтилип түзүлөт:

C(Xn+1)=[qα ⁣{μ^i(Xn+1)Ri},    q1α+ ⁣{μ^i(Xn+1)+Ri}]C(X_{n+1}) = \left[\, q_{\alpha}^{-}\!\left\{\hat{\mu}_{-i}(X_{n+1}) - R_i\right\}, \;\; q_{1-\alpha}^{+}\!\left\{\hat{\mu}_{-i}(X_{n+1}) + R_i\right\} \right]

Бул жерде q1α+{vi}q_{1-\alpha}^{+}\{v_i\}{vi}i=1n\{v_i\}_{i=1}^n топтомунун (1α)(n+1)\lceil (1-\alpha)(n+1)\rceil-чи эң кичине мааниси, ал эми qα{vi}q_{\alpha}^{-}\{v_i\}α(n+1)\lfloor \alpha(n+1)\rfloor-чи эң кичине мааниси. Төмөнкү чек ар бир LOO божомолунан калдыкты алып салат; жогорку чек аны кошот. Ушул асимметрия — бүт маани: эки чекти тең μ^i+Ri\hat{\mu}_{-i} + R_i ге чейин кыскартуу төмөнкү чекти божомолдон жогору коет, бул туура эмес болмок.

Jackknife+ жок дегенде 12α1 - 2\alpha камтуу кепилдигин берет (split conformal дын 1α1-\alpha дан бир аз алсызыраак), бирок бардык маалыматтарды окутуу үчүн да, калибрлөө үчүн да колдонот. Иш жүзүндө камтуу адатта 1α1-\alpha га жакын болот.

Чектелген маалыматтар менен окутулган соода моделдери үчүн (мисалы, бир нече жүздөгөн байкоосу гана бар режимге мүнөздүү моделдер), jackknife+ көбүнчө эң жакшы тандоо болуп саналат — ал калибрлөө үчүн жетишсиз маалыматтарды курмандыкка чалбайт. Баасы — nn моделди кайра ыңгайлаштыруу.

Каржы Убакыт Катарларынын Көйгөйү: Алмашылбоочулук

Каржы убакыт катарларындагы алмашылбоочулук: режим өзгөрүшү менен стационардык эмес катар, бөлүштүрүлүш жылышкан сайын камтуунун бузулушу

Стандарттуу конформдук кепилдик алмашуучулукту талап кылат: (Z1,,Zn+1)(Z_1, \ldots, Z_{n+1}) дин биргелешкен бөлүштүрүлүшү алмаштыруулар алдында инварианттуу. i.i.d. маалыматтар үчүн бул тривиалдуу түрдө аткарылат.

Каржы убакыт катарлары алмашуучу эмес. Кирешелер төмөнкүлөрдү көрсөтөт:

  • Волатилдиктин кластерленүүсү: Жогорку волатилдик мезгилдеринен кийин дагы жогорку волатилдик мезгилдери келет (GARCH таасирлери).
  • Импульс жана орточого кайтуу: Кирешелердеги же квадраттык кирешелердеги автокорреляция.
  • Режим өзгөрүүлөрү: Бөлүштүрүлүш убакыттын өтүшү менен жылышат (бука жана аюу рыноктору).

Эгер сиз split conformal ды убакыт катарына жөнөкөй түрдө, кокустук калибрлөө бөлүнүшү менен колдонсоңуз, убактылуу түзүлүштү бузасыз. Тынч 2017-жылдын калибрлөө упайлары туруксуз 2020-жылдын белгисиздигин чагылдырбайт. Сиздин камтуу кепилдигиңиз бузулат.

Адаптивдүү Конформдук Тыянак (ACI)

Адаптивдүү конформдук тыянак: ишке ашкан камтууну максатка карай көзөмөлдөгөн кайтарым байланыш циклу аркылуу кеңейген жана кыскарган божомол интервалы

Gibbs жана Candes (2021, NeurIPS) бөлүштүрүлүш жылышуусу жана алмашылбоочу маалыматтар менен иштөө үчүн Адаптивдүү Конформдук Тыянакты (ACI) киргизишти. Идея сонун: туруктуу камтуу деңгээлин колдонуунун ордуна, акыркы интервалдар чыныгы натыйжаны камтыдыбы же жокпу ошого негизделип максаттуу камтылбоочулук деңгээлин онлайн ыңгайлаштыруу жана ар бир кадамда упай бөлүштүрүлүшүнөн квантилди кайра чыгаруу.

ACI Алгоритми

ACI интервал энин түз өзгөртпөйт. Ал адаптивдүү камтылбоочулук параметри αt\alpha_t ны сактайт жана андан конформдук квантилди кайра эсептейт. Ар бир tt убакыт кадамында:

  1. Конформдук чекти учурдагы калдыктар топтомунун (калибрлөө упайлары, ошону менен катар ушул убакытка чейин ишке ашкан ар кандай упайлар) эмпирикалык (1αt)(1 - \alpha_t)-квантили катары эсептеңиз: q^t=Quantile^1αt({Rj})\hat{q}_t = \widehat{\text{Quantile}}_{1-\alpha_t}(\{R_j\}).
  2. XtX_t белгилерин байкаңыз, Ct(Xt)=[μ^(Xt)q^t,  μ^(Xt)+q^t]C_t(X_t) = [\hat{\mu}(X_t) - \hat{q}_t, \; \hat{\mu}(X_t) + \hat{q}_t] интервалын чыгарыңыз.
  3. Чыныгы YtY_t маанисин байкаңыз жана ката көрсөткүчүн эсептеңиз: errt=1{YtCt(Xt)}\text{err}_t = \mathbf{1}\{Y_t \notin C_t(X_t)\}.
  4. Деңгээлди жаңылаңыз (энди эмес):

αt+1=clip ⁣(αt+γ(αerrt),  0,  1)\alpha_{t+1} = \text{clip}\!\left(\alpha_t + \gamma\,(\alpha - \text{err}_t),\; 0,\; 1\right)

бул жерде γ>0\gamma > 0 — кадам өлчөмү, ал эми α\alpha — максаттуу камтылбоочулук. Эгер интервал жаңылса (errt=1\text{err}_t = 1), αt\alpha_t кичирейет, бул кийинки квантилди жогору түртөт жана интервалды кеңейтет; эгер камтыса, αt\alpha_t өсөт жана интервалдар кыскарат. Маанилүүсү, бул жердеги γ\gamma ыктымалдык бирдиктеринде — ал деңгээлди [0,1][0,1] ичинде түртөт, чийки киреше бирдиктериндеги чекти эмес — ошондуктан бирдей γ\gamma калдыктар 10310^{-3} тартибинде болобу же жокпу, акылга сыярлык иштейт.

ACI Үчүн Камтуу Кепилдиги

ACI бөлүштүрүлүш моделине көз каранды эмес узак мөөнөттүү камтуу кепилдигин берет:

1Tt=1TerrtααT+1α1γT\left|\frac{1}{T}\sum_{t=1}^{T} \text{err}_t - \alpha\right| \leq \frac{|\alpha_{T+1} - \alpha_1|}{\gamma T}

αt\alpha_t [0,1][0,1] ге чектелгендиктен, алымы 1/γ1/\gamma ны туруктуу санга көбөйткөнгө чектелген, ошондуктан оң жагы O(1/T)O(1/T) болот жана эмпирикалык камтылбоочулук жыштыгы α\alpha га жакындайт. Так тыянак: ACI, ыңгайлаштырылган деңгээлдер чектелген бойдон калат экен (муну clip камсыздайт), каалаган (анын ичинде атаандаш) удаалаштыктар үчүн узак мөөнөттүү эмпирикалык камтылбоочулук жыштыгынын α\alpha га жакындашына кепилдик берет. Бул камтуу жыштыгы жөнүндөгү кепилдик, интервалдын маалыматтуулугу жөнүндө эмес: чыныгы атаандаш удаалаштык алдында интервалдар камтуу максатына жетишкен бойдон эле маалыматсыз кеңейип кетиши мүмкүн.

Динамикалык Жөндөлүүчү ACI (DtACI)

Gibbs жана Candes (2024, JMLR) ACI ны γ\gamma кадам өлчөмүн динамикалык жөндөө менен өркүндөтүштү. γ\gamma ны бекитүүнүн ордуна, алар Γ={γ1,,γK}\Gamma = \{\gamma_1, \ldots, \gamma_K\} талапкерлер топтомун сактайт жана аларды эксперт-агрегация эрежеси аркылуу бириктирет, акыркы камтуусу максатка эң жакын γ\gamma ны артыкчылыктуу көрөт.

Бул практикалык маселени чечет: чоң γ\gamma режим өзгөрүүлөрүнө тез ыңгайлашат, бирок туруксуз интервал эндерин пайда кылат; кичине γ\gamma туруктуу, бирок ыңгайлашууда жай. DtACI муну автоматтык түрдө теңдештирет.

Бул Соода үчүн Эмне Үчүн Маанилүү

Киреше божомолдоо моделин колдонгон market-making стратегиясын карап көрөлү. Тынч рыноктордо конформдук интервалдар тар болот — модель ишенимдүү, ошондуктан сиз чоңураак позицияларды ала аласыз. Волатилдик көтөрүлгөндө (пайда мезгили, FOMC билдирүүлөрү, геосаясий соккулар), ACI деңгээли ыңгайлашат жана интервалдар бир нече убакыт кадамында кеңейет. Сиздин позиция көлөмүңүз ага жооп катары кичирейет, эч кандай ачык волатилдик модели же режимди аныктоо логикасысыз.

Бул — белгисиздикти сандык баалоо кийинчерээк ойлоп табылган нерсе эмес, биринчи даражалуу сигнал катары.

Конформдук Интервалдар менен Позиция Көлөмүн Аныктоо

Калибрленген белгисиздик интервалын позиция көлөмүнө дал келтирүү: тар интервал чоң позицияны, кең интервал кичине позицияны башкарат

Эми конформдук божомолду конкреттүү позиция көлөмүн аныктоо менен байланыштыралы. Негизги өзгөрмө — симметриялуу абсолюттук калдык учуруна карата божомол интервалынын жарым эни. Симметриялуу [μ^(Xt)q^t,  μ^(Xt)+q^t][\hat{\mu}(X_t) - \hat{q}_t, \; \hat{\mu}(X_t) + \hat{q}_t] интервалы менен, толук эни wt=2q^tw_t = 2\hat{q}_t. Формулаларды жана кодду шайкеш сактоо үчүн, биз баарын толук эн wtw_t га карата өлчөйбүз.

Тескери-Эн Боюнча Өлчөө

Эң жөнөкөй ыкма: көлөмдү интервал энине тескери пропорционалдуу түрдө аныктоо.

position_sizet=kwt\text{position\_size}_t = \frac{k}{w_t}

бул жерде kk — сиздин тобокелдик бюджетиңизге калибрленген масштабдоо туруктуусу. Модель ишенимдүү болгондо (тар интервал), сиз чоңураак позиция аласыз. Белгисиз болгондо (кең интервал), кичинекейин аласыз.

Бул волатилдикке багыттоого (size1/σ\text{size} \propto 1/\sigma) окшош, бирок маанилүү айырмачылык менен: конформдук интервал эни — бөлүштүрүлүштөн көз каранды эмес белгисиздик өлчөмү, параметрдик волатилдик баасы эмес. Ал жалгыз гана киреше дисперсиясын эмес, камтуу кепилдиги алдындагы божомолдук белгисиздикти камтыйт.

Edge-Катыш Боюнча Өлчөө жана Соода Кылбоо Чыпкасы

Таза тескери-эн өлчөө сигналдын өзүнүн күчүн этибарга албайт. Табигый өркүндөтүү edge катышы боюнча масштабдайт — интервал энине карата чекиттик божомол:

et=μ^(Xt)wte_t = \frac{|\hat{\mu}(X_t)|}{w_t}

Бул — сигнал-ызы-чуу катышынын конформдук аналогу: күтүлгөн киреше бөлүштүрүлүштөн көз каранды эмес белгисиздик өлчөмүнө бөлүнгөн. Биз аны өлчөө үчүн да, соода кылбоо чыпкасы үчүн да колдонобуз.

Чыпка негизделген. Эгер интервал нөлдү камтыса,

lowert<0<uppert,\text{lower}_t < 0 < \text{upper}_t,

анда (1α)(1-\alpha) божомол интервалы оң да, терс да кирешелерди камтыйт — ишке ашкан киреше сиздин божомолуңузга каршы белгиге ээ болушу ыктымал. Эң төмөнкү edge чеги θ\theta ны аныктаңыз жана et>θe_t > \theta болгондо гана соода кылыңыз. Байкаңыз, "ete_t интервал нөлдү камтыбагандай чоң" деген геометриялык маани так et>1/2e_t > 1/2 ге барабар (себеби интервал μ^>q^t=wt/2|\hat{\mu}| > \hat{q}_t = w_t/2 болгондо нөлдөн тазаланат). θ\theta ны et=μ^/wte_t = |\hat{\mu}|/w_t нин чыныгы шкаласында backtesting аркылуу тандаңыз; күндөлүк киреше калдыктары үчүн ete_t адатта 1/21/2 ден алда канча төмөн болот, ошондуктан абдан кичине θ\theta дээрлик бардык соодаларды кабыл алышы, ал эми чоңу эч бирин кабыл албашы мүмкүн. Аны өз маалыматтарыңызга калибрлеңиз.

"Конформдук Kelly" Жөнүндө

Конформдук интервалдарды Kelly үлүшүнө f=pb(1p)bf^* = \frac{pb - (1-p)}{b} байлоо кызыктырат. Бирок ff^* жеңүү ыктымалдыгы pp жана төлөм катышы bb дан алынган толук, чектелген үлүш болуп саналат; аны μ^/q^\hat{\mu}/\hat{q} сыяктуу чектелбеген катышка көбөйтүүнүн чечим теориясы жагынан эч кандай негизи жок — ал 1 ден ашып кетиши же ff^* дан көз каранды эмес белгисин өзгөртүшү мүмкүн, жана ff^* мурунтан эле коддогон edge ти эки эсе эсептейт. Ошондуктан биз "конформдук Kelly" көбөйткүчүн сунуш кылбайбыз.

Эгер Kelly ди интервал аркылуу башкаргыңыз келсе, андан чыныгыда эле pp жана bb ны чыгарышыңыз керек, бул интервал ичиндеги бөлүштүрүлүш жөнүндө ачык болжолдоону талап кылат (конформдук интервалдар бул жөнүндө атайылап эч нерсе айтпайт — Чектөөлөрдү караңыз). Мисалы, интервал ичинде болжолдонгон форма алдында сиз pP(киреше>0)p \approx \mathbb{P}(\text{киреше} > 0) ды жана интервал геометриясынан төлөм катышын болжолдуу эсептей аласыз — бирок бул болжолдоону үнү менен белгилеңиз, себеби ал так конформдук божомол алдын алууга аракет кылган параметрдик милдеттенмени кайра киргизет.

Чынчыл, болжолдоолору аз альтернатива — edge катышы et=μ^/wte_t = |\hat{\mu}|/w_t ды бөлчөк-Kelly кичирейтүү катары колдонуу: күтүлгөн киреше интервалга карата чоң болгондо көлөмдү чоңойтуу, кичине болгондо кичирейтүү, жана муну катуу жогорку чектин үстүнө колдонуу — так эвристика катары, "Kelly үлүшү" катары эмес.

Python Ишке Ашыруу

Бул жерде практикалык ишке ашыруу. Биз split/prefit жолун да, убактылуу (EnbPI) жолду да көрсөтөбүз, себеби бул макаланын бүт мааниси каржы маалыматтарынын алмашылбоочу экенинде.

Жөндөө жана Маалыматтарды Даярдоо

import numpy as np
import pandas as pd
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import KFold

from mapie.regression import MapieRegressor, MapieTimeSeriesRegressor
from mapie.subsample import BlockBootstrap


def prepare_features(prices: pd.Series, lookback: int = 20) -> pd.DataFrame:
    """Create features from a price series."""
    df = pd.DataFrame()
    returns = prices.pct_change()

    for lag in range(1, lookback + 1):
        df[f"ret_lag_{lag}"] = returns.shift(lag)

    for window in [5, 10, 20]:
        df[f"ret_mean_{window}"] = returns.rolling(window).mean().shift(1)
        df[f"ret_std_{window}"] = returns.rolling(window).std().shift(1)
        df[f"ret_skew_{window}"] = returns.rolling(window).skew().shift(1)

    df["target"] = returns.shift(-1)

    return df.dropna()

MAPIE менен Split Conformal (Prefit)

Split/prefit conformal үчүн cv="prefit" method="base" ты талап кылат (жөнөкөй split-conformal баалоочу). method="plus" варианты — CV+/jackknife+ баалоочу жана cv="prefit" менен шайкеш эмес — анын ордуна кросс-валидация объектиси керек. Биз бул жерде туура айкалышты колдонобуз жана өлчөөнү толук энге стандарттайбыз.

def split_conformal_sizing(
    prices: pd.Series,
    alpha: float = 0.1,
    k: float = 1e-3,          # scaling constant, in width units
    max_position: float = 1.0,
    min_edge: float = 0.05,   # threshold on |pred| / width
) -> pd.DataFrame:
    """
    Position sizing using split (prefit) conformal prediction intervals.

    Sizing rule (consistent with the prose):
        edge_t = |pred_t| / width_t
        size_t = clip(k / width_t, 0, max_position)   # inverse-width
        size_t = 0 if edge_t < min_edge               # no-trade filter
    """
    df = prepare_features(prices)
    X = df.drop(columns=["target"])
    y = df["target"]

    n_train = int(len(X) * 0.6)
    n_cal = int(len(X) * 0.2)

    X_train, y_train = X.iloc[:n_train], y.iloc[:n_train]
    X_cal, y_cal = X.iloc[n_train:n_train + n_cal], y.iloc[n_train:n_train + n_cal]
    X_test, y_test = X.iloc[n_train + n_cal:], y.iloc[n_train + n_cal:]

    base_model = GradientBoostingRegressor(
        n_estimators=200, max_depth=3, learning_rate=0.05, random_state=42,
    )
    base_model.fit(X_train, y_train)

    mapie = MapieRegressor(estimator=base_model, cv="prefit", method="base")
    mapie.fit(X_cal, y_cal)

    y_pred, y_intervals = mapie.predict(X_test, alpha=alpha)
    lower = y_intervals[:, 0, 0]
    upper = y_intervals[:, 1, 0]
    width = upper - lower

    raw_size = k / np.where(width > 0, width, np.inf)
    position_size = np.clip(raw_size, 0.0, max_position)

    edge_ratio = np.abs(y_pred) / np.where(width > 0, width, np.inf)
    position_size = np.where(edge_ratio < min_edge, 0.0, position_size)

    position_size = position_size * np.sign(y_pred)

    return pd.DataFrame({
        "prediction": y_pred,
        "lower": lower,
        "upper": upper,
        "width": width,
        "edge_ratio": edge_ratio,
        "position_size": position_size,
        "actual": y_test.values,
    }, index=X_test.index)

EnbPI менен Убакыт Катары Conformal

Кирешелер алмашуучу болбогондуктан, жогорудагы кокустук/prefit бөлүнүш жалгыз гана негиз болуп саналат. MAPIE нин method="enbpi" (Xu & Xie, 2021) аркылуу MapieTimeSeriesRegressor и убактылуу көз карандылык үчүн иштелип чыккан блоктук bootstrap жана калдыктарды жаңылоону колдонот. Бул макаланын өзүнүн аргументине дал келген курал.

def enbpi_sizing(
    prices: pd.Series,
    alpha: float = 0.1,
    k: float = 1e-3,
    max_position: float = 1.0,
    min_edge: float = 0.05,
) -> pd.DataFrame:
    """Position sizing with EnbPI (block-bootstrap, time-series conformal)."""
    df = prepare_features(prices)
    X = df.drop(columns=["target"])
    y = df["target"]

    n_train = int(len(X) * 0.7)
    X_train, y_train = X.iloc[:n_train], y.iloc[:n_train]
    X_test, y_test = X.iloc[n_train:], y.iloc[n_train:]

    base_model = GradientBoostingRegressor(
        n_estimators=200, max_depth=3, learning_rate=0.05, random_state=42,
    )

    cv = BlockBootstrap(n_resamplings=30, length=20, overlapping=False, random_state=42)
    mapie_ts = MapieTimeSeriesRegressor(base_model, method="enbpi", cv=cv, agg_function="mean")
    mapie_ts.fit(X_train, y_train)

    y_pred, y_intervals = mapie_ts.predict(X_test, alpha=alpha, ensemble=True)
    lower = y_intervals[:, 0, 0]
    upper = y_intervals[:, 1, 0]
    width = upper - lower

    raw_size = k / np.where(width > 0, width, np.inf)
    position_size = np.clip(raw_size, 0.0, max_position)
    edge_ratio = np.abs(y_pred) / np.where(width > 0, width, np.inf)
    position_size = np.where(edge_ratio < min_edge, 0.0, position_size)
    position_size = position_size * np.sign(y_pred)

    return pd.DataFrame({
        "prediction": y_pred, "lower": lower, "upper": upper,
        "width": width, "edge_ratio": edge_ratio,
        "position_size": position_size, "actual": y_test.values,
    }, index=X_test.index)

Адаптивдүү Конформдук Тыянак (Онлайн)

Тирүү соода үчүн биз чыныгы ACI ны нөлдөн ишке ашырабыз: камтылбоочулук деңгээли αt\alpha_t ны сактайбыз, аны кошуу жолу менен жаңылайбыз жана ар бир кадамда калдыктар топтомунан квантилди кайра чыгарабыз. Эки чектелген тандоо деталы маанилүү:

  • Интерполяцияланган квантиль эмес, тартип статистикасын колдонуңуз. np.quantile демейки боюнча интерполяция кылат, бул талап кылынган деңгээлден бир аз төмөн түшүп, жетишсиз камтууга алып келиши мүмкүн; method="higher" ("inverted_cdf" ге барабар) бериңиз.
  • Талап кылынган даража nn дан ашканда (кичине nn, жогорку максаттуу камтуу), туура чек ++\infty (интервал = бүт түз сызык), эң чоң калдыкка кысуу эмес. Кысуу 1αt\ge 1-\alpha_t кепилдигин байкалбай бузат.
class AdaptiveConformalSizer:
    """
    Online position sizing with Adaptive Conformal Inference (Gibbs & Candes,
    2021). Updates the miscoverage LEVEL alpha_t and re-derives the quantile
    from the residual set each step -- gamma is in probability units.
    """

    def __init__(self, base_model, alpha=0.1, gamma=0.02,
                 max_position=1.0, min_edge=0.05, k=1e-3):
        self.base_model = base_model
        self.alpha_target = alpha     # target miscoverage
        self.alpha_t = alpha          # adaptive miscoverage level
        self.gamma = gamma            # step size, in [0, 1] units
        self.max_position = max_position
        self.min_edge = min_edge
        self.k = k
        self.residuals = []
        self.q_hat = np.inf
        self.coverage_history = []

    @staticmethod
    def _conformal_quantile(residuals, alpha_t):
        """(1 - alpha_t) conformal quantile via the order statistic."""
        n = len(residuals)
        if n == 0:
            return np.inf
        rank = int(np.ceil((1.0 - alpha_t) * (n + 1)))
        if rank > n:                  # required order statistic does not exist
            return np.inf             # -> interval is the whole line
        level = rank / n
        return float(np.quantile(residuals, min(level, 1.0), method="higher"))

    def calibrate(self, X_cal, y_cal):
        preds = self.base_model.predict(X_cal)
        self.residuals = list(np.abs(np.asarray(y_cal) - preds))
        self.q_hat = self._conformal_quantile(self.residuals, self.alpha_t)

    def predict_and_size(self, X_t) -> dict:
        mu_hat = self.base_model.predict(np.asarray(X_t).reshape(1, -1))[0]
        lower, upper = mu_hat - self.q_hat, mu_hat + self.q_hat
        width = upper - lower                      # = 2 * q_hat

        edge_ratio = abs(mu_hat) / width if np.isfinite(width) and width > 0 else 0.0

        if edge_ratio < self.min_edge:
            size = 0.0
        else:
            size = min(self.k / width, self.max_position) if width > 0 else 0.0

        return {
            "prediction": mu_hat, "lower": lower, "upper": upper,
            "width": width, "edge_ratio": edge_ratio,
            "position_size": size * np.sign(mu_hat),
            "alpha_t": self.alpha_t, "q_hat": self.q_hat,
        }

    def update(self, X_t, y_t: float):
        """ACI update: adapt the LEVEL, then re-derive the quantile."""
        mu_hat = self.base_model.predict(np.asarray(X_t).reshape(1, -1))[0]
        residual = abs(y_t - mu_hat)

        covered = int(residual <= self.q_hat)
        err_t = 1 - covered

        self.alpha_t = float(np.clip(
            self.alpha_t + self.gamma * (self.alpha_target - err_t), 0.0, 1.0
        ))

        self.residuals.append(residual)
        self.q_hat = self._conformal_quantile(self.residuals, self.alpha_t)

        self.coverage_history.append(covered)

    @property
    def running_coverage(self) -> float:
        if not self.coverage_history:
            return float("nan")
        return float(np.mean(self.coverage_history))

Баарын Бириктирүү: Backtest Циклу

def backtest_aci_sizing(prices: pd.Series, alpha=0.1, gamma=0.02) -> pd.DataFrame:
    """Backtest position sizing with Adaptive Conformal Inference."""
    df = prepare_features(prices)
    X = df.drop(columns=["target"]).values
    y = df["target"].values
    index = df.index

    n_train = int(len(X) * 0.5)
    n_cal = int(len(X) * 0.2)

    X_train, y_train = X[:n_train], y[:n_train]
    X_cal, y_cal = X[n_train:n_train + n_cal], y[n_train:n_train + n_cal]
    X_test, y_test = X[n_train + n_cal:], y[n_train + n_cal:]
    test_index = index[n_train + n_cal:]

    model = GradientBoostingRegressor(
        n_estimators=200, max_depth=3, learning_rate=0.05, random_state=42,
    )
    model.fit(X_train, y_train)

    sizer = AdaptiveConformalSizer(base_model=model, alpha=alpha, gamma=gamma)
    sizer.calibrate(X_cal, y_cal)

    records = []
    for i in range(len(X_test)):
        result = sizer.predict_and_size(X_test[i])
        result["actual"] = y_test[i]
        result["pnl"] = result["position_size"] * y_test[i]
        records.append(result)
        sizer.update(X_test[i], y_test[i])   # online residual + level update

    results = pd.DataFrame(records, index=test_index)
    results["cumulative_pnl"] = results["pnl"].cumsum()
    results["running_coverage"] = (
        ((results["lower"] <= results["actual"]) &
         (results["actual"] <= results["upper"])).expanding().mean()
    )
    return results

Натыйжаларды Баалоо

def evaluate(results: pd.DataFrame, alpha: float = 0.1):
    """Print evaluation metrics for conformal position sizing."""
    covered = ((results["actual"] >= results["lower"]) &
               (results["actual"] <= results["upper"]))

    print(f"Target coverage:      {1 - alpha:.1%}")
    print(f"Empirical coverage:   {covered.mean():.1%}")
    print(f"Mean interval width:  {results['width'].mean():.6f}")
    print(f"Median position size: {results['position_size'].abs().median():.4f}")
    print(f"Fraction no-trade:    {(results['position_size'] == 0).mean():.1%}")
    print(f"Total PnL (bps):      {results['pnl'].sum() * 10000:.1f}")
    sd = results['pnl'].std()
    sharpe = results['pnl'].mean() / sd * np.sqrt(252) if sd > 0 else float('nan')
    print(f"Sharpe (annualized):  {sharpe:.2f}")

Практикалык Ой Жүгүртүүлөр

Nonconformity Упайын Тандоо

Абсолюттук калдык Yμ^(X)|Y - \hat{\mu}(X)| — стандарт, бирок ал божомол интервалы чекиттик божомолдун тегерегинде симметриялуу болушу керек деп болжолдойт. Каржы кирешелери үчүн асимметриялуу интервалдар көбүнчө маанилүүрөөк болот:

  • Конформдоштурулган Квантилдик Регрессия (CQR): α/2\alpha/2 жана 1α/21 - \alpha/2 деңгээлдеринде квантилдик регрессорлорду ыңгайлаштырып, андан кийин конформдоштуруңуз (Romano жана башк., 2019). Интервалдар өз формасын жергиликтүү бөлүштүрүлүшкө ыңгайлаштырат — түшүү учурунда төмөн жагында кеңири, көтөрүлүү учурунда жогорку жагында кеңири. (CQR менен интервал энди симметриялуу эмес, ошондуктан wtw_t чыныгы жогорку-минус-төмөнкү эн болуп саналат — бардык жерде wtw_t ны бөлүүчү катары колдонууну улантыңыз.)
  • Нормалдаштырылган упайлар: Ri=Yiμ^(Xi)/σ^(Xi)R_i = |Y_i - \hat{\mu}(X_i)| / \hat{\sigma}(X_i), бул жерде σ^\hat{\sigma} — жергиликтүү волатилдик баасы. Бул шарттуу түрдө адаптивдүү интервалдарды пайда кылат — төмөн волатилдик режимдеринде тар, жогорку волатилдик режимдеринде кең — четки камтууну сактап туруп.

Калибрлөө Топтомунун Көлөмү

Split conformal дын камтуу кепилдиги каалаган nn калибрлөө топтом көлөмү үчүн аткарылат, бирок nn өскөн сайын интервал эни азаят. Өтө кичине nn үчүн талап кылынган тартип статистикасы жок болушу мүмкүн, бул учурда чынчыл чек ++\infty (маалыматсыз, бирок жарактуу интервал) — эң чоң калдыкка кысуу кепилдикти байкалбай жокко чыгарат. Практикалык соода үчүн:

  • n100n \geq 100 калибрлөө чекити жетиштүү тар интервалдарды берет.
  • Туруктуу квантиль баалоо үчүн n500n \geq 500 артыкчылыктуу.
  • ACI менен, калибрлөө топтому болгону инициализация үчүн; онлайн деңгээл жаңылоолору калганын аткарат.

Кайра Окутуу Жыштыгы

Негизги μ^\hat{\mu} модели эскирип калышы мүмкүн. Эки ыкма:

  1. Мезгилдүү түрдө кайра окутуу (мисалы, ай сайын) жана конформдук квантилди кайра калибрлөө.
  2. ACI ны колдонуу жана адаптивдүү деңгээлге моделдин эскирүүсүн компенсациялоого мүмкүндүк берүү — моделдин калдыктары өскөн сайын интервалдар автоматтык түрдө кеңейет.

2-вариант жөнөкөйрөөк жана күтүлбөгөн жерден натыйжалуу. Конформдук катмар коопсуздук тору катары иштейт: моделдин сапаты начарласа да, узак мөөнөттүү ACI камтуу жыштыгы дагы деле максатка жакындай берет.

Бүтүм Чыгымдары

Конформдук интервалдар бүтүм чыгымдары менен пайдалуу түрдө өз ара аракеттенет. Интервалдар кең болгондо (жогорку белгисиздик), позициялар кичине, ошондуктан жүгүртүү төмөн. Интервалдар кыскарганда (модель ишенимдүү), позициялар өсөт — бирок моделдин туура болуу мүмкүнчүлүгү жогорураак, ошондуктан жүгүртүүнү төлөө татыктуу.

Сиз бүтүм чыгымдарын соода кылбоо чыпкасына түз да кошо аласыз:

trade only if μ^(Xt)cost>θwt\text{trade only if } |\hat{\mu}(X_t)| - \text{cost} > \theta \cdot w_t

Бул сизге күтүлгөн таза edge конформдук эн менен масштабдалган чектен ашканда гана соода кылганыңызды камсыздайт — бардык жерде болгондой эле бирдей wtw_t бөлүүчүсүн колдонуп.

Салттуу Ыкмалар менен Салыштыруу

Касиет Гаусс ИИ Bootstrap ИИ Конформдук БИ
Бөлүштүрүү болжолдоосу Калыпта каталар i.i.d. + асимптотикалык Жок (алмашуучулук)
Чектелген тандоо кепилдиги Жок Жок Ооба
Каалаган модель менен иштейт Жок Ооба Ооба
Гетероскедастиктикке ыңгайлашат Жок Жарым-жартылай CQR / нормалдаштырылган упайлар менен
Бөлүштүрүлүш жылышуусун иштетет Жок Жок ACI / EnbPI варианты
Эсептөө чыгымы Төмөн Орточо Split: төмөн; jackknife+: O(n)O(n) кайра ыңгайлаштыруу; толук: мүмкүн эмес

Bootstrap болгону өзүнүн кепилдигинде "асимптотикалык"; ал баары бир i.i.d./алмашуучу маалыматтарды жана тегиздикти болжолдойт, ошондуктан анын бөлүштүрүү-болжолдоо клеткасы "болжолдоосуз" эмес. Ал эми жалгыз "конформдук" мамы варианттардын ортосундагы абдан ар түрдүү чыгымдарды жашырат, муну эми чыгым саптары ачык көрсөтөт.

Чектөөлөр

Конформдук божомол сыйкыр эмес. Соода үчүн негизги чектөөлөр:

  1. Четки, шарттуу эмес, камтуу. Кепилдик P(Yn+1C(Xn+1))1α\mathbb{P}(Y_{n+1} \in C(X_{n+1})) \geq 1 - \alpha четки мааниде — XX жана YY дегидей кокустукка боюнча орточолонгон. Так шарттоо мааниси X=xX = x үчүн жергиликтүү камтуу 1α1 - \alpha дан жогору же төмөн болушу мүмкүн. Конформдоштурулган квантилдик регрессия муну жарым-жартылай чечет.

  2. Алмашуучулук — чыныгы талап. Split conformal үчүн калибрлөө маалыматтары жана тест чекити алмашуучу болушу керек. Каржы маалыматтары андай эмес. ACI жана EnbPI муну узак мөөнөттүү кепилдикке чейин жеңилдетет, бирок кыска мөөнөттүү камтуу четтеши мүмкүн.

  3. Интервал эни ыктымалдык тыгыздыгы эмес. Конформдук интервал сизге YY нин 1α1-\alpha ыктымалдык менен кайда түшөрүн айтат, бирок интервал ичиндеги бөлүштүрүлүш жөнүндө эч нерсе айтпайт. Ал толук божомолдук бөлүштүрүлүштүн ордун баспайт — так ошол себептен андан Kelly pp жана bb ны чыгаруу кошумча, ачык болжолдоону талап кылат.

  4. Таштанды кирсе, кеңирээк чыгат. Начар негизги модель кең интервалдарды пайда кылат. Конформдук божомол камтууну кепилдейт, бирок пайдалуулукту эмес. Эгер сиздин моделиңиздин божомолдук күчү жок болсо, интервалдар ушунчалык кең болот, позиция көлөмүн аныктоочу эч качан соода кылбайт.

Корутунду

Конформдук божомол позиция көлөмүн аныктоого табигый түрдө дал келген, белгисиздикти сандык баалоо үчүн катуу, бөлүштүрүлүштөн көз каранды эмес негизди берет:

  • Split conformal — чектелген тандоо камтуусу бар статикалык, оффлайн калибрлөө үчүн.
  • Jackknife+ — калибрлөө маалыматтары жетишсиз болгондо жана бардык байкоолорду колдонгуңуз келгенде (nn жолу кайра ыңгайлаштыруу баасы менен).
  • Адаптивдүү конформдук тыянак / EnbPI — стационардык эмес рыноктор менен онлайн соода үчүн.
  • Позиция көлөмүн аныктоо — интервалдын тескери эни жана edge-катыш соода кылбоо чыпкасы аркылуу — жана Kelly ге өтсөңүз, болгону pp жана bb ны чынчыл чыгаргандан кийин, негизсиз көбөйткүч аркылуу эмес.

Параметрдик альтернативаларга караганда негизги артыкчылыгы: сизге параметрдик бөлүштүрүү болжолдоосун эч качан аныктоо же текшерүү керек эмес. Интервалдар түзүлүшү боюнча чынчыл (четки мааниде, алмашуучулук алдында). Системалык трейдер үчүн бул модель тобокелдигинин бир булагынын азаюусун билдирет — ал эми модель тобокелдиги өмүрлүк маанилүү болгон бизнесте, бул маанилүү.


Булактар:

  • Papadopoulos, H., Proedrou, K., Vovk, V., Gammerman, A. (2002). Inductive confidence machines for regression. ECML.
  • Vovk, V., Gammerman, A., Shafer, G. (2005). Algorithmic Learning in a Random World. Springer.
  • Lei, J., G'Sell, M., Rinaldo, A., Tibshirani, R.J., Wasserman, L. (2018). Distribution-free predictive inference for regression. JASA.
  • Xu, C., Xie, Y. (2021). Conformal prediction interval for dynamic time-series (EnbPI). ICML.
  • Barber, R.F., Candes, E.J., Ramdas, A., Tibshirani, R.J. (2021). Predictive inference with the jackknife+. Annals of Statistics.
  • Gibbs, I., Candes, E.J. (2021). Adaptive conformal inference under distribution shift. NeurIPS.
  • Gibbs, I., Candes, E.J. (2024). Conformal inference for online prediction with arbitrary distribution shifts. JMLR.
  • Romano, Y., Patterson, E., Candes, E.J. (2019). Conformalized quantile regression. NeurIPS.
  • Cordier, T. et al. (2022). MAPIE: an open-source library for distribution-free uncertainty quantification. arXiv:2207.12274.
blog.disclaimer

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

Рынктан бир кадам алдыда болуңуз

AI соода аналитикасы, рынок талдоолору жана платформа жаңылыктары үчүн биздин жаңылыктар бюллетенине жазылыңыз.

Биз сиздин купуялыгыңызды урматтайбыз. Каалаган убакта жазылымдан чыга аласыз.