Тәуекелді Ескеретін Позиция Көлемін Анықтауға арналған Конформды Болжам
Позиция көлемін анықтаудың кез келген формуласы белгісіздіктің бағасын қажет етеді. Kelly критерийіне жеңіс ықтималдығы мен төлем қатынасы қажет (қараңыз: Стратегияларға арналған Kelly критерийі). Орта-дисперсия оңтайландыруына ковариация матрицасы қажет. VaR-ға кірістердің үлестірімі қажет. Мұның бәрі деректерді генерациялайтын процесс туралы болжамдарды талап етеді — қаржы нарықтары әдетте бұзатын болжамдарды.
Конформды болжам мүлдем басқа нәрсе ұсынады: ешқандай параметрлік үлестірімдік болжамсыз, ақырғы таңдама үшін қамту кепілдігі бар болжам аралықтары. Егер сіз 90% қамтуды сұрасаңыз, кем дегенде 90% қамту аласыз — кірістер гаусстық, қалың құйрықты, қисық немесе гетероскедастикалық болуына қарамастан. Жалғыз талап — алмасымдылық (exchangeability), немесе кейінірек көретініміздей, одан да әлсіз шарттар.
Бұл мақалада теория, негізгі нұсқалар және Python-да позиция көлемін анықтауға арналған практикалық іске асыру қамтылған.
Негізгі Идея: Nonconformity Ұпайлары

Конформды болжам жаңа бақылаудың өткен деректерге қатысты қаншалықты "бөтен" екенін өлшеу арқылы жұмыс істейді. Бұл бөтендік nonconformity ұпайымен сандық түрде өлшенеді — деректің қалған бөлігінде байқалған үлгіге бір нүктенің қаншалықты нашар сәйкес келетінін өлшейтін кез келген функция.
Регрессия үшін (кірістер сияқты үздіксіз мәнді болжау), ең қарапайым nonconformity ұпайы — абсолютті қалдық:
мұндағы — кез келген нүктелік болжаушы (сызықтық регрессия, random forest, нейрондық желі — маңызды емес), ал — деректер нүктесі.
Негізгі түсінік: егер деректер нүктелері алмасымды болса, онда -дің арасындағы дәрежесі бойынша бірқалыпты үлестірілген. Бұл — таза комбинаторлық факт, ол немесе -тің үлестірімі туралы ешқандай болжамды талап етпейді.
Осы дәреже бірқалыптылығынан біз ақырғы таңдама қамтуы бар болжам аралықтарын құра аламыз.
Split Конформды Болжам

Split конформды болжам (Papadopoulos және т.б., 2002; Lei және т.б., 2018) — ең практикалық нұсқа. Алгоритм қарапайым:
1-қадам. Деректерді оқыту жиынтығы мен калибрлеу жиынтығына бөліңіз.
2-қадам. -де кез келген моделін бейімдеңіз.
3-қадам. Калибрлеу жиынтығында nonconformity ұпайларын есептеңіз:
4-қадам. Қажетті қамтусыздық деңгейі үшін, -ны -нің эмпирикалық квантилі ретінде алыңыз. Нақтырақ айтқанда, бұл — -ші ең кіші қалдық (және болғанда, яғни өте кіші үшін, ).
5-қадам. Жаңа нүктесі үшін болжам аралығы:
Қамту Кепілдігі
Калибрлеу деректері мен жаңа тест нүктесінің алмасымдылығы кезінде:
Бұл — ақырғы таңдама кепілдігі, асимптотикалық жуықтау емес. Ол кез келген моделі, деректердің кез келген үлестірімі және кез келген таңдама көлемі үшін орындалады. Егер нашар болжаушы болса, аралықтар жай ғана кеңірек болады. Қамту кепілдігі бәрібір орындалады.
Ұпайларда тең мәндер болмаған жағдайда жоғарғы шек те бар: , сондықтан қамту бекерге консервативті емес.
Бұл Сауда Үшін Неге Маңызды
Мысалы, сызықтық регрессиядан алынған дәстүрлі болжам аралықтары гаусстық қателерді болжайды. Деректердің негізгі бөлігіне калибрленген гаусстық аралық нақты қалдықтар қалың құйрықты болғанда (мысалы, аз еркіндік дәрежесі бар Student-) құйрықтарды қатты қате бағалауы мүмкін: орталық масса гаусстықтан жұқарақ, сондықтан дисперсияға сәйкестендірілген гаусстық аралық орталыққа жақын жерде артық қамтиды, бірақ құйрықтарда жеткіліксіз қамтиды, ал құйрыққа бейімделген аралық керісінше істейді. Мәселе жалғыз сиқырлы санда емес — мәселе параметрлік аралықтың нақты қамтуы сіз тексермеген үлестірімдік болжамға тәуелді болуында.
Конформды болжам аралықтары мұны айналып өтеді. Олар модель белгісіз болғанда автоматты түрде кеңейеді және нақты қате үлестіріміне қарамастан шеткі қамтуды сақтайды. Трейдер үшін бұл мыналарды білдіреді:
- Егер сіз позицияларды аралық енінің кері пропорциясымен өлшесеңіз, модель белгісіз болғанда сіз әсерді автоматты түрде азайтасыз.
- Қамту кепілдігі сіздің тәуекел бағалауларыңыздың шынайы екенін білдіреді — егер сіз "іске асқан кірістердің 90%-ы осы аралыққа түседі" десеңіз, бұл мәлімдеме статистикалық тұрғыдан жарамды (шеткі мағынада, алмасымдылық кезінде).
Толық Конформды және Jackknife+
Split conformal қарапайым, бірақ деректерді ысырап етеді: калибрлеу жиынтығын оқыту үшін пайдалануға болмайды. Екі балама шешім мұны жояды.
Толық Конформды Болжам
Толық конформды болжам (Vovk және т.б., 2005) барлық деректерді оқыту үшін де, калибрлеу үшін де пайдаланады. -дің әрбір кандидат мәні үшін:
- Деректер жиынтығын арқылы толықтырыңыз.
- Модельді толықтырылған жиынтықта қайта бейімдеңіз.
- Барлық nonconformity ұпайларын есептеңіз.
- Егер үшін ұпай тым экстремалды болмаса, -ты болжам жиынтығына қосыңыз.
Болжам жиынтығы:
мұндағы — толықтырылған жиынтықпен есептелген nonconformity ұпайлары.
Толық conformal ең тар аралықтарды береді, бірақ көптеген модельдер үшін есептеу тұрғысынан мүмкін емес — торда әрбір кандидат үшін модельді қайта бейімдеу қажет. Кіріс болжамы үшін бұл бір болжамға мыңдаған қайта бейімдеуді білдіруі мүмкін.
Jackknife+ (Barber және т.б., 2021)
Jackknife+ тепе-теңдік табады. Ол leave-one-out (LOO) қалдықтарын пайдаланады, бірақ LOO бөліктері бойынша бейімделген модельдегі өзгергіштікті ескереді.
дегеніміз нүктесінен басқа барлық деректерде оқытылған модель делік. LOO nonconformity ұпайын жалғыз абсолютті қалдықпен анықтаймыз:
Jackknife+ болжам аралығы содан кейін тест нүктесіндегі LOO болжамдарынан, осы қалдықтармен кеңейтіліп құрылады:
Мұндағы — жиынтығының -ші ең кіші мәні, ал — -ші ең кіші мәні. Төменгі шек әрбір LOO болжамынан қалдықты алып тастайды; жоғарғы шек оны қосады. Осы асимметрия — бүкіл мәні: екі шекті де -ге дейін қысқарту төменгі шекті болжамнан жоғары қояр еді, бұл қате болар еді.
Jackknife+ кем дегенде қамту кепілдігін береді (split conformal-дың -нан сәл әлсізірек), бірақ барлық деректерді оқыту үшін де, калибрлеу үшін де пайдаланады. Іс жүзінде қамту әдетте -ға жақын болады.
Шектеулі деректермен оқытылған сауда модельдері үшін (мысалы, тек бірнеше жүздеген бақылауы бар режимге тән модельдер), jackknife+ көбіне ең жақсы таңдау болып табылады — ол калибрлеу үшін тапшы деректерді құрбан етпейді. Бағасы — модельді қайта бейімдеу.
Қаржылық Уақыт Қатарларының Мәселесі: Алмасымсыздық

Стандартты конформды кепілдік алмасымдылықты талап етеді: -дің бірлескен үлестірімі алмастырулар кезінде инвариантты. i.i.d. деректер үшін бұл тривиалды түрде орындалады.
Қаржылық уақыт қатарлары алмасымды емес. Кірістер мыналарды көрсетеді:
- Волатильділіктің кластерленуі: Жоғары волатильділік кезеңдерінен кейін тағы да жоғары волатильділік кезеңдері келеді (GARCH әсерлері).
- Импульс және ортаға қайту: Кірістердегі немесе квадраттық кірістердегі автокорреляция.
- Режим өзгерістері: Үлестірім уақыт өте келе ауысады (бұқа мен аю нарықтары).
Егер сіз split conformal-ды уақыт қатарына қарапайым түрде, кездейсоқ калибрлеу бөлінуімен қолдансаңыз, уақыттық құрылымды бұзасыз. Тыныш 2017 жылдың калибрлеу ұпайлары құбылмалы 2020 жылдың белгісіздігін көрсетпейді. Сіздің қамту кепілдігіңіз бұзылады.
Адаптивті Конформды Қорытынды (ACI)

Gibbs пен Candes (2021, NeurIPS) үлестірім ауысуы мен алмасымды емес деректермен жұмыс істеу үшін Адаптивті Конформды Қорытындыны (ACI) енгізді. Идея талғампаз: тұрақты қамту деңгейін пайдаланудың орнына, соңғы аралықтар нақты нәтижені қамтыды ма, жоқ па соған негізделіп мақсатты қамтусыздық деңгейін онлайн бейімдеу және әрбір қадамда ұпай үлестірімінен квантильді қайта шығару.
ACI Алгоритмі
ACI аралық енін тікелей өзгертпейді. Ол адаптивті қамтусыздық параметрі -ны сақтайды және одан конформды квантильді қайта есептейді. Әрбір уақыт қадамында:
- Конформды шекті ағымдағы қалдықтар жиынтығының (калибрлеу ұпайлары, оған қоса осы уақытқа дейін іске асқан кез келген ұпайлар) эмпирикалық -квантилі ретінде есептеңіз: .
- белгілерін бақылаңыз, аралығын шығарыңыз.
- Нақты мәнін бақылаңыз және қате көрсеткішін есептеңіз: .
- Деңгейді жаңартыңыз (енді емес):
мұндағы — қадам өлшемі, ал — мақсатты қамтусыздық. Егер аралық жіберіп алса (), кішірейеді, бұл келесі квантильді жоғары итереді және аралықты кеңейтеді; егер қамтыса, өседі және аралықтар тарылады. Маңыздысы, мұндағы ықтималдық бірліктерінде — ол деңгейді ішінде итереді, шектен тыс кіріс бірліктеріндегі шекті емес — сондықтан бірдей қалдықтар ретінде болсын, болмасын ақылға қонымды әрекет етеді.
ACI Үшін Қамту Кепілдігі
ACI үлестірімдік модельге тәуелді емес ұзақ мерзімді қамту кепілдігін береді:
-ге шектелгендіктен, алымы -ны тұрақтыға көбейткенге шектелген, сондықтан оң жағы болады және эмпирикалық қамтусыздық жиілігі -ға жақындайды. Нақты тұжырым: ACI, бейімделген деңгейлер шектелген күйде қалатын болса (мұны clip қамтамасыз етеді), кез келген (соның ішінде қарсылас) тізбектер үшін ұзақ мерзімді эмпирикалық қамтусыздық жиілігінің -ға жақындайтынына кепілдік береді. Бұл қамту жиілігі туралы кепілдік, аралықтың ақпараттылығы туралы емес: шынайы қарсылас тізбек кезінде аралықтар қамту мақсатына жеткен күйде де ақпаратсыз кең болып кетуі мүмкін.
Динамикалық Реттелетін ACI (DtACI)
Gibbs пен Candes (2024, JMLR) ACI-ды қадам өлшемін динамикалық реттеу арқылы жетілдірді. -ны бекітудің орнына, олар кандидаттар жиынтығын сақтайды және оларды сарапшылар-агрегациясы ережесі арқылы біріктіреді, соңғы қамтуы мақсатқа ең жақын -ны артық көреді.
Бұл практикалық мәселені шешеді: үлкен режим өзгерістеріне тез бейімделеді, бірақ құбылмалы аралық ендерін тудырады; кіші тұрақты, бірақ бейімделуде баяу. DtACI мұны автоматты түрде теңестіреді.
Бұл Сауда Үшін Неге Маңызды
Кіріс болжау моделін пайдаланатын market-making стратегиясын қарастырайық. Тыныш нарықтарда конформды аралықтар тар болады — модель сенімді, сондықтан сіз үлкенірек позициялар ала аласыз. Волатильділік көтерілгенде (пайда маусымы, FOMC хабарламалары, геосаяси соққылар), ACI деңгейі бейімделеді және аралықтар бірнеше уақыт қадамында кеңейеді. Сіздің позиция көлеміңіз соған жауап ретінде кішірейеді, ешқандай айқын волатильділік моделі немесе режимді анықтау логикасынсыз.
Бұл — белгісіздікті сандық бағалау кейінірек ойлап табылған нәрсе емес, бірінші дәрежелі сигнал ретінде.
Конформды Аралықтармен Позиция Көлемін Анықтау

Енді конформды болжамды нақты позиция көлемін анықтаумен байланыстырайық. Негізгі айнымалы — симметриялы абсолютті қалдық жағдайына қатысты болжам аралығының жарты ені. Симметриялы аралығымен, толық ені . Формулалар мен кодты сәйкес сақтау үшін, біз бәрін толық ен -ге қатысты өлшейміз.
Кері-Ен Бойынша Өлшеу
Ең қарапайым тәсіл: көлемді аралық еніне кері пропорционалды түрде анықтау.
мұндағы — сіздің тәуекел бюджетіңізге калибрленген масштабтау константасы. Модель сенімді болғанда (тар аралық), сіз үлкенірек позиция аласыз. Белгісіз болғанда (кең аралық), кішірек аласыз.
Бұл волатильділікті мақсаттауға () ұқсас, бірақ маңызды айырмашылықпен: конформды аралық ені — үлестірімге тәуелсіз белгісіздік өлшемі, параметрлік волатильділік бағасы емес. Ол тек кіріс дисперсиясын емес, қамту кепілдігі кезіндегі болжамдық белгісіздікті қамтиды.
Edge-Қатынасы Бойынша Өлшеу және Сауда Жасамау Сүзгісі
Таза кері-ен өлшеуі сигналдың өз күшін елемейді. Табиғи жетілдіру edge қатынасы бойынша масштабтайды — аралық еніне қатысты нүктелік болжам:
Бұл — сигнал-шу қатынасының конформды аналогы: күтілетін кіріс үлестірімге тәуелсіз белгісіздік өлшеміне бөлінген. Біз оны өлшеу үшін де, сауда жасамау сүзгісі үшін де пайдаланамыз.
Сүзгі негізделген. Егер аралық нөлді қамтыса,
онда болжам аралығы оң да, теріс те кірістерді қамтиды — іске асқан кіріс сіздің болжамыңызға қарсы таңбаға ие болуы ықтимал. Ең төменгі edge шегі -ны анықтаңыз және тек болғанда сауда жасаңыз. Назар аударыңыз, " аралық нөлді қамтымайтындай үлкен" деген геометриялық мағына дәл -ге тең (себебі аралық болғанда нөлден тазарады). -ны -тің нақты шкаласында backtesting арқылы таңдаңыз; күнделікті кіріс қалдықтары үшін әдетте -ден әлдеқайда төмен болады, сондықтан өте кіші дерлік барлық саудаларды қабылдауы, ал үлкені ешбірін қабылдамауы мүмкін. Оны өз деректеріңізге калибрлеңіз.
"Конформды Kelly" Туралы
Конформды аралықтарды Kelly үлесіне жалғау азғырады. Бірақ жеңіс ықтималдығы мен төлем қатынасы -дан алынған толық, шектелген үлес болып табылады; оны сияқты шектелмеген қатынасқа көбейтудің шешім теориясы тұрғысынан ешқандай негізі жоқ — ол 1-ден асып кетуі немесе -тан тәуелсіз таңбасын өзгертуі мүмкін, әрі бұрыннан кодтаған edge-ті екі есе есептейді. Сондықтан біз "конформды Kelly" көбейткішін ұсынбаймыз.
Егер Kelly-ды аралық арқылы басқарғыңыз келсе, одан нақты мен -ны шығаруыңыз керек, бұл аралық ішіндегі үлестірім туралы айқын болжамды талап етеді (конформды аралықтар бұл туралы әдейі ештеңе айтпайды — Шектеулерді қараңыз). Мысалы, аралық ішінде болжанған пішін кезінде сіз -ды және аралық геометриясынан төлем қатынасын шамамен есептей аласыз — бірақ бұл болжамды дауыстап белгілеңіз, себебі ол дәл конформды болжам болдырмауға тырысқан параметрлік міндеттемені қайта енгізеді.
Шынайы, болжамдары аз балама — edge қатынасы -ды бөлшек-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-ды нөлден іске асырамыз: қамтусыздық деңгейі -ны сақтаймыз, оны аддитивті түрде жаңартамыз және әрбір қадамда қалдықтар жиынтығынан квантильді қайта шығарамыз. Екі ақырғы таңдама детальі маңызды:
- Интерполяцияланған квантиль емес, реттік статистиканы пайдаланыңыз.
np.quantileәдепкі бойынша интерполяция жасайды, бұл талап етілген деңгейден сәл төмен түсіп, жеткіліксіз қамтуға әкелуі мүмкін;method="higher"(эквиваленті"inverted_cdf") беріңіз. - Талап етілген дәреже -нен асқанда (кіші , жоғары мақсатты қамту), дұрыс шек (аралық = бүкіл түзу), ең үлкен қалдыққа қысу емес. Қысу кепілдігін байқаусыз бұзады.
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 Ұпайын Таңдау
Абсолютті қалдық — стандарт, бірақ ол болжам аралығы нүктелік болжамның айналасында симметриялы болуы керек деп болжайды. Қаржылық кірістер үшін асимметриялы аралықтар көбіне мағыналырақ:
- Конформдалған Квантильдік Регрессия (CQR): мен деңгейлерінде квантильдік регрессорларды бейімдеп, содан кейін конформдаңыз (Romano және т.б., 2019). Аралықтар өз пішінін жергілікті үлестірімге бейімдейді — құлдырау кезінде төмен жағында кеңірек, өрлеу кезінде жоғарғы жағында кеңірек. (CQR-мен аралық енді симметриялы емес, сондықтан шынайы жоғарғы-минус-төменгі ен болып табылады — барлық жерде -ны бөлгіш ретінде пайдалануды жалғастырыңыз.)
- Нормаланған ұпайлар: , мұндағы — жергілікті волатильділік бағасы. Бұл шартты түрде адаптивті аралықтарды тудырады — төмен волатильділік режимдерінде тар, жоғары волатильділік режимдерінде кең — шеткі қамтуды сақтай отырып.
Калибрлеу Жиынтығының Көлемі
Split conformal-дың қамту кепілдігі кез келген калибрлеу жиынтығы көлемі үшін орындалады, бірақ өскен сайын аралық ені азаяды. Өте кіші үшін талап етілген реттік статистика болмауы мүмкін, бұл жағдайда шынайы шек (ақпаратсыз, бірақ жарамды аралық) — ең үлкен қалдыққа қысу кепілдікті байқаусыз күшін жояды. Практикалық сауда үшін:
- калибрлеу нүктесі жеткілікті тар аралықтар береді.
- Тұрақты квантиль бағалауы үшін артық көрінеді.
- ACI-мен, калибрлеу жиынтығы тек инициализация үшін; онлайн деңгей жаңартулары қалғанын атқарады.
Қайта Оқыту Жиілігі
Негізгі моделі ескіруі мүмкін. Екі тәсіл:
- Кезеңдік түрде қайта оқыту (мысалы, айсайын) және конформды квантильді қайта калибрлеу.
- ACI-ны пайдалану және адаптивті деңгейге модельдің ескіруін өтеуге мүмкіндік беру — модельдің қалдықтары өскен сайын аралықтар автоматты түрде кеңейеді.
2-нұсқа қарапайымырақ әрі күтпеген жерден тиімді. Конформды қабат қауіпсіздік торы ретінде әрекет етеді: тіпті модель нашарласа да, ұзақ мерзімді ACI қамту жиілігі мақсатқа жақындай береді.
Мәміле Шығындары
Конформды аралықтар мәміле шығындарымен пайдалы түрде өзара әрекеттеседі. Аралықтар кең болғанда (жоғары белгісіздік), позициялар кіші, сондықтан айналым төмен. Аралықтар тарылғанда (модель сенімді), позициялар өседі — бірақ модель дұрыс болу мүмкіндігі жоғарырақ, сондықтан айналымды төлеу тұрарлық.
Сіз мәміле шығындарын сауда жасамау сүзгісіне тікелей де қоса аласыз:
Бұл сізге күтілетін таза edge конформды енмен масштабталған шектен асқанда ғана сауда жасауыңызды қамтамасыз етеді — барлық жердегідей бірдей бөлгішін пайдаланып.
Дәстүрлі Әдістермен Салыстыру
| Қасиет | Гаусс ЖА | Bootstrap ЖА | Конформды ЖА |
|---|---|---|---|
| Үлестірімдік болжам | Қалыпты қателер | i.i.d. + асимптотикалық | Жоқ (алмасымдылық) |
| Ақырғы таңдама кепілдігі | Жоқ | Жоқ | Иә |
| Кез келген модельмен жұмыс істейді | Жоқ | Иә | Иә |
| Гетероскедастикалыққа бейімделеді | Жоқ | Ішінара | CQR / нормаланған ұпайлармен |
| Үлестірім ауысуын өңдейді | Жоқ | Жоқ | ACI / EnbPI нұсқасы |
| Есептеу шығыны | Төмен | Орташа | Split: төмен; jackknife+: қайта бейімдеу; толық: мүмкін емес |
Bootstrap тек өз кепілдігінде "асимптотикалық"; ол бәрібір i.i.d./алмасымды деректер мен тегістікті болжайды, сондықтан оның үлестірімдік-болжам ұяшығы "болжамсыз" емес. Ал жалғыз "конформды" бағаны нұсқалар арасындағы әртүрлі шығындарды жасырады, оны шығын жолы енді анық көрсетеді.
Шектеулер
Конформды болжам — сиқыр емес. Сауда үшін негізгі шектеулер:
-
Шеткі, шартты емес, қамту. Кепілдік шеткі мағынада — пен -дегі кездейсоқтық бойынша орташаланған. Нақты шарттау мәні үшін жергілікті қамту -дан жоғары немесе төмен болуы мүмкін. Конформдалған квантильдік регрессия мұны ішінара шешеді.
-
Алмасымдылық — нақты талап. Split conformal үшін калибрлеу деректері мен тест нүктесі алмасымды болуы керек. Қаржылық деректер олай емес. ACI мен EnbPI мұны ұзақ мерзімді кепілдікке дейін жеңілдетеді, бірақ қысқа мерзімді қамту ауытқуы мүмкін.
-
Аралық ені ықтималдық тығыздығы емес. Конформды аралық сізге -дің ықтималдықпен қайда түсетінін айтады, бірақ аралық ішіндегі үлестірім туралы ештеңе айтпайды. Ол толық болжамдық үлестірімнің орнын баспайды — дәл сол себепті одан Kelly мен -ны шығару қосымша, айқын болжамды талап етеді.
-
Қоқыс кірсе, кеңірек шығады. Нашар негізгі модель кең аралықтарды тудырады. Конформды болжам қамтуды кепілдейді, бірақ пайдалылықты кепілдемейді. Егер сіздің модельіңіздің болжамдық күші болмаса, аралықтар соншалықты кең болады, позиция көлемін анықтаушы ешқашан сауда жасамайды.
Қорытынды
Конформды болжам позиция көлемін анықтауға табиғи түрде сай келетін, белгісіздікті сандық бағалаудың қатаң, үлестірімге тәуелсіз негізін береді:
- Split conformal — ақырғы таңдама қамтуы бар статикалық, оффлайн калибрлеу үшін.
- Jackknife+ — калибрлеу деректері тапшы болғанда және барлық бақылауларды пайдаланғыңыз келгенде ( рет қайта бейімдеу бағасымен).
- Адаптивті конформды қорытынды / EnbPI — стационарлы емес нарықтармен онлайн сауда үшін.
- Позиция көлемін анықтау — аралықтың кері ені мен edge-қатынасты сауда жасамау сүзгісі арқылы — және Kelly-ге бет алсаңыз, тек мен -ны шынайы шығарғаннан кейін, негізсіз көбейткіш арқылы емес.
Параметрлік баламаларға қарағанда негізгі артықшылығы: сізге параметрлік үлестірімдік болжамды ешқашан белгілеу немесе тексеру қажет емес. Аралықтар құрылымы бойынша шынайы (шеткі мағынада, алмасымдылық кезінде). Жүйелі трейдер үшін бұл модель тәуекелінің бір көзінің азаюын білдіреді — ал модель тәуекелі өмірлік маңызды бизнесте бұл маңызды.
Дереккөздер:
- 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.
Authors
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.