XGBoost for Return Direction: Class Imbalance and Decision Thresholds
Келесі сағаттың қайтарымы +0,5%-дан асатынын болжау үшін классификаторды жаттықтырыңыз және сіз теңдестірілген екілік мәселені құрастырған жоқсыз. Тыныш криптографиялық режимдер кезінде жолақтардың 70--80% шекті мәннен төмен түседі, сондықтан модель ешқашан бір позитивті болжау арқылы 75% дәлдікке қол жеткізе алады. Мұнда дәлдік пайдасыз. Ешкім әдейі таңдамаған әдепкі 0,5 шешім шекарасы - бұл мән predict() пайдалану орын алады.
Үш стандартты жауап бар: жоғалтуды қайта өлшеңіз scale_pos_weight, жоғалтуды фокалды жоғалтумен ауыстырыңыз немесе жоғалтуды жалғыз қалдырыңыз және фактіден кейін шешім табалдырығын жылжытыңыз. Олар әдетте бір-бірін алмастыратын ретінде ұсынылады. Олар емес. Олар әртүрлі дәлдік/шақыру айырбастауларын және одан да маңыздысы әр түрлі пост-құнды PnL шығарады, өйткені сауда қайта шақырудан гөрі дәлдікке көбірек көңіл бөледі — өткізіп алған сауда ешнәрсеге тұрмайды, ал нашар сауда таратуға және алымдарға кетеді.
Бұл мақала үшеуін де сағат сайынғы BTC және ETH деректерінің бірдей тазартылған алға қарай бүктемелерінде өлшейді, содан кейін одан туындайтын екі нәрсені қамтиды: неге min_child_weight бұл жолдар санына қарағанда гесс шегі болып табылады (сол себепті жоғалтуды қайта өлшеген кезде «дұрыс» мән ауысады) және XGBoost, LightGBM және CatBoost нақты айырмашылығы бар жерде.
| Тәсіл | Дәлдік | Еске түсіру | Сауда | Шығыннан кейінгі PnL | Дефляцияланған Sharpe |
|---|---|---|---|---|---|
| Базалық (түзету жоқ, thr=0,5) | — | — | — | — | — |
scale_pos_weight = n_neg/n_pos |
— | — | — | — | — |
| Фокальды жоғалту (γ=2, α=0,25) | — | — | — | — | — |
| Шекті оңтайландыру (мин дәлдік 0,55) | — | — | — | — | — |
Бірдей қатпарлар, бірдей мүмкіндіктер, әр жол үшін бірдей шығын үлгісі. Шарп сыналған конфигурациялар саны үшін дефляцияланған Sharpe және бірнеше сынақ; шығындар тайғақ және шығын үлгілері.
Қайтаруды болжаудағы класс теңгерімсіздігін өңдеу

1-тәсіл: таразы_пос_салмақ
Ең қарапайым әдіс. Орнату scale_pos_weight = n_negative / n_positive:
n_pos = y_train.sum()
n_neg = len(y_train) - n_pos
scale_pos_weight = n_neg / n_pos # e.g., 3.0 if 75% negative
model = xgb.XGBClassifier(
scale_pos_weight=scale_pos_weight,
...
)
Бұл оң класты үлгілер үшін градиентті масштабтайды, бұл модельге оң мысалды қате жіктеу болып табылатынын айтады. теріс жіктеуден де жаман.
Жанама әсерді жіберіп алу оңай: ол сонымен қатар гессийлерді таразылайды. бері min_child_weight жапырақтағы гессиандардың *қосындысының табалдырығы болып табылады (төменде қараңыз), жоғалтуды қайта өлшеу ағаштың агрессивті түрде бөлінуін үнсіз өзгертеді. А min_child_weight реттелген scale_pos_weight=1 енді бір нәрсені білдірмейді scale_pos_weight=3. Екеуін ретімен емес, бірге қайта реттеңіз.
Екінші жанама әсер: шығу ықтималдықтары бұдан былай калибрленбейді. predict_proba шынайы ықтималдықта монотонды, бірақ оған тең емес нәрсені қайтарады, бұл сол сандарға негізделген кез келген төменгі позиция өлшемін қате етеді.
2-тәсіл: Фокальды жоғалту
Фокус жоғалту сыныпқа қарамастан жеңіл мысалдарды азайтады және жаттығуларды қатты, анық емес үлгілерге шоғырландырады. Бұл қайтаруды болжау үшін тартымды фрейм, мұнда +0,5% жолақ пен +0,4% жолақ арасындағы шекара негізінен шу болады, дегенмен «анық емес жағдайларға назар аудару» және «үйренуге болмайтын жағдайларға назар аудару» белгілер шулы болған кезде бірдей нұсқау болып табылады, бұл болжау орнына өлшеуге негіз болады.
қайда шынайы класс үшін болжанған ықтималдық, сынып салмағын теңестіреді және (әдетте 1--3) жеңіл мысалдардың қаншалықты төмен салмақталғанын басқарады.
def focal_loss_objective(y_true, y_pred, gamma=2.0, alpha=0.25):
"""
Custom focal loss for XGBoost. Returns gradient and hessian.
"""
p = 1.0 / (1.0 + np.exp(-y_pred)) # sigmoid
g1 = alpha * y_true * (1 - p)**gamma * (gamma * p * np.log(p + 1e-9) + p - 1)
g2 = (1 - alpha) * (1 - y_true) * p**gamma * (
-gamma * (1 - p) * np.log(1 - p + 1e-9) - p
)
grad = -(g1 + g2)
hess = np.maximum(grad * (1 - grad), 1e-6)
return grad, hess
model = xgb.XGBClassifier(objective=focal_loss_objective, ...)
Жапырақ салмағы формуласы төмендеу қадамы болуы үшін теңшелетін мақсаттарға градиент және оң гессиан қажет. Фокустық жоғалтудың нақты екінші туындысы барлық жерде оң емес, сондықтан іске асыру суррогатқа жетеді - бірақ масштаб факторы бойынша суррогат қадам өлшемдерін өзгертеді, ал Гессиан қосындысы арқылы ол нені өзгертеді min_child_weight қара өрік. Тек салыстыру кестесі бұл іс жүзінде ешқандай шығын әкелмейтінін көрсетеді.
3-тәсіл: шекті оңтайландыру
Шығынды жалғыз қалдырыңыз, калибрленген үлгіні оқытыңыз және валидация жинағындағы шешім шегін жылжытыңыз:
from sklearn.metrics import precision_recall_curve
def optimize_threshold(y_true, y_proba, min_precision=0.55):
"""
Find the threshold maximizing F1 subject to a minimum precision.
"""
precisions, recalls, thresholds = precision_recall_curve(y_true, y_proba)
f1_scores = 2 * (precisions * recalls) / (precisions + recalls + 1e-9)
valid = precisions[:-1] >= min_precision
if not valid.any():
return 0.5 # fallback
best_idx = np.argmax(f1_scores[:-1] * valid)
return thresholds[best_idx]
Сауда үшін дәлдік деңгейі маңызды. Жалғыз F1-ді барынша арттыру сауда-саттықты қайтарып алудың дәлдігін қамтамасыз етеді, бұл PnL терминдерінде әрбір спрэдті төлейтін маржиналды сауда-саттықты білдіреді. Дәлдікті шектеу және оның астындағы қайта шақыруды барынша арттыру «аз сауда жасаңыз, бірақ жасаған кезде дұрыс болыңыз» дегенді білдіреді.
Екі ереже бұл адалдықты сақтайды: жаттығу терезесінен кейін хронологиялық түрде орналасатын валидация деректерінде шекті сәйкестендіріңіз және оны әр fold-та қайта орнатыңыз. Бүкіл sample бойынша бір рет таңдалған шек look-ahead bias таксономиясында сипатталған болашаққа көз жүгірту leakage-і болады. Әр fold-та қайта fitting жасау тегін диагностиканы да береді: егер оңтайлы шек fold-тар арасында секірсе, calibration тұрақсыз, ал шек noise-қа fit болып жатыр.
Неліктен баланың ең төменгі_салмағы қатар саны емес, гессиан сомасы болып табылады

Градиентті күшейту қосымша ансамбльді құрады. Қадамда ағаш қосады XGBoost екінші ретті Тейлор кеңеюімен жуықтайтын реттелген мақсатты азайту:
бірге , , және
қайда жапырақ саны, жапырақ салмағы, әр жапырақ айыппұлы және L2 термині. Жапырақтың оңтайлы салмағын шешуге мүмкіндік береді .
Гессиан сомасы бөлгіште отырады және бұл мәселе. min_child_weight табалдырықтар сол қосынды, жапырақтағы жолдар саны емес. Журналды жоғалту үшін, , ол ең үлкен және болжау сенімділікке жақындаған сайын нөлге қарай құлайды. Осылайша, сенімді түрде жіктелген жолақтарға толы жапырақтың кішкентай гессиан сомасы бар және кесіледі, ал шын мәнінде анық емес жолақтарды ұстайтын жапырақ аман қалады.
Шулы қаржылық белгілер үшін бұл сіз қалаған мінез-құлық және ол практикалық салдарын түсіндіреді:
- көтеру
min_child_weightқара өрік жапырақтары бірнеше белгісіз бақылауларға сүйенеді — дәл сол, ең алдымен, сәйкес келетін шу. Бұл қарағанда өткір құралmin_child_samples-стильді қатарларды санау. - Жоғалтуды өзгертетін кез келген нәрсе гессиандықтардың масштабын өзгертеді.
scale_pos_weight, реттелетін мақсаттар және үлгі салмақтары барлығы тиімділікті өзгертедіmin_child_weightтерген нөміріңіз өзгермесе де. - Артық табыс пен болжамдар күшейген сайын, гессендер жаһандық деңгейде азаяды, сондықтан тұрақты
min_child_weightкейінгі раундтарда агрессивті түрде кесіледі. Бұл кіріктірілген жасыту әсері, сондықтан ағаштар көп болған кезде оқу жылдамдығының төмендеуі аз, үлкен қадамдардан басқаша әрекет етеді.
LightGBM min_child_samples жолдар саны, яғни ұқсас атауы бар шын басқа параметр. Оның Гессиан аналогы min_sum_hessian_in_leaf. Атауларды сәйкестендіру арқылы екі кітапхана арасында конфигурацияны тасымалдау үлгіні кездейсоқ өзгертудің кең таралған жолы болып табылады.
XGBoost және LightGBM және CatBoost: инженерлік айырмашылықтар

Үшеуі де градиентті күшейтілген шешім ағаштарын жүзеге асырады. Айырмашылықтар ағаш құрылысында және олар шын мәнінде жаттығу уақытында және үлгіден тыс ұпайда көрінеді.
XGBoost деңгей бойынша өседі (ені бойынша бірінші): берілген тереңдіктегі барлық жапырақтар тереңірек өту алдында бөлінеді. Бұл теңдестірілген ағаштарды шығарады, жасайды max_depth мәнді күрделілікті басқару және реттеу үшін болжамдырақ. Ол сондай-ақ азайту үшін аз шығын қалдыратын жапырақтарды бөлу жұмысын ысырап етеді.
LightGBM жапырақ тәрізді өседі: ол жапырақтың қай жерде орналасса да жоғалтуды барынша азайтатын жапырақты бөледі. Бірдей жаттығу шығынына аз бөлінулер жетеді, бірақ ағаштар терең және теңгерімсіз болады, сондықтан max_depth дұрыс басқару тұтқасы болуды тоқтатады — num_leaves болып табылады. Тағы екі трюк оның жылдамдығын арттырады:
- GOSS (Градиент негізіндегі бір жақты іріктеу) барлық үлкен градиентті даналарды сақтайды және градиентті бағалауды бейтарап ұстау үшін тірі қалғандардың салмағын арттыра отырып, шағын градиентті үлгілерді кездейсоқ түрде қосалқы үлгілермен алады. Қаржылық деректерде үлкен градиентті даналар модель қазіргі уақытта қателесетін жолақтар болып табылады - бұл жапсырма шуы да өмір сүретін жерде, сондықтан GOSS іріктеуді шу ең нашар жерде шоғырландырады. Болжамдан гөрі қарапайым ішкі іріктеуге қарсы тексерген жөн.
- EFB (Exclusive Feature Bundling) бір-бірінен ерекшеленетін сирек мүмкіндіктерді бір жәшік бос орын мүмкіндігіне жинақтайды. Бір ыстық кодтауда тиімді; техникалық мүмкіндік матрицасының көпшілігі болып табылатын тығыз үздіксіз мүмкіндіктер бойынша дерлік пайдасыз.
CatBoost симметриялық (ескермейтін) ағаштарды өсіреді: берілген тереңдіктегі әрбір түйін бірдей бөлу жағдайын пайдаланады. Бұл күшті регуляризатор және қорытындыны өте жылдам жасайды - ағаш индекстік іздеуге айналады - әр ағаштың мәнерлілігі құнына. Оның екі ажырататын механизмі:
- Тапсырысты күшейту. Стандартты күшейту сол үлгіде оқытылған үлгіні пайдаланып үлгі үшін қалдықтарды есептейді, бұл қалдықты «болжаудың ауысуы». CatBoost әрбір үлгі үшін қалдықтарды тек оның алдындағы үлгілерде кездейсоқ ауыстыруда орнатылған үлгіні пайдалана отырып бағалайды. Құрылым уақыт қатарындағы ойлауға табиғи сәйкес келеді және деректер шектеулі болған кезде маңыздырақ.
- Категориялық кодтауға арналған реттелген мақсатты статистика, ол тек алдыңғы үлгілерден мақсатты статистиканы есептейді, бұл қарапайым орташа кодтау енгізетін мақсатты ағып кетуді болдырмайды. Бұл мүмкіндіктер жинағы алмасу, актив деңгейі немесе режим белгілері бар кезде CatBoost пайдаланудың шынайы себебі.
| Меншік | XGBoost | LightGBM | CatBoost |
|---|---|---|---|
| Ағаштың өсуі | Деңгейі бойынша | Жапырақ-дана | Симметриялық (ескертусіз) |
| Күрделілік тұтқасы | max_depth |
num_leaves |
depth |
| Жапырақ өлшеміндегі қорғаныс | min_child_weight (Гессиан) |
min_child_samples (жолдар) |
min_data_in_leaf (жолдар) |
| Категориялық белгілері | Қолмен кодтау | Негізгі қолдау | Туған, реттелген TS |
| Регуляризация | L1/L2 + гамма | L1/L2 + жапырақтар_саны | L2 + кездейсоқ күш |
| Пайдаланушы жоғалту | Икемді | Икемді | Біршама шектелген |
| Пойыз уақыты, бұл деректер жинағы | — | — | |
| OOS журналының жоғалуы, бірдей қатпарлар | — | — |
Сапалық қатарлар кітапхана фактілері болып табылады. Соңғы екі жол «қайсысын пайдалануым керек» деген сұраққа жауап беретін жалғыз жол және олар сіздің жеке деректеріңіз бойынша іске қосылуы керек — жақсы реттелген енгізулер арасындағы айырмашылықтар әдетте деректер жиынының пішіні шешетіндей аз болады.
Кітапханаларды ауыстыру негізінен атауды өзгерту болып табылады. Параметрлері үш еселенген емес тізімделген бір жаттығу функциясы:
import xgboost as xgb
def train_xgb_model(X_train, y_train, X_val, y_val, class_weight_ratio=1.0):
"""Train XGBoost classifier for return direction prediction."""
model = xgb.XGBClassifier(
n_estimators=2000,
max_depth=5,
learning_rate=0.01,
subsample=0.7,
colsample_bytree=0.7,
min_child_weight=10, # Hessian sum, not row count
gamma=1.0,
reg_alpha=0.1,
reg_lambda=1.0,
scale_pos_weight=class_weight_ratio,
objective='binary:logistic',
eval_metric='logloss',
tree_method='hist',
random_state=42,
early_stopping_rounds=50,
)
model.fit(X_train, y_train, eval_set=[(X_val, y_val)], verbose=False)
return model
| Тұжырымдама | XGBoost | LightGBM | CatBoost |
|---|---|---|---|
| Ағаштар саны | n_estimators |
n_estimators |
iterations |
| L2 пенальти | reg_lambda |
reg_lambda |
l2_leaf_reg |
| Бағанды таңдау | colsample_bytree |
colsample_bytree |
rsm |
| Сыныптық теңгерімсіздік | scale_pos_weight |
scale_pos_weight |
auto_class_weights='Balanced' |
| Ерте тоқтату | early_stopping_rounds |
lgb.early_stopping() кері қоңырау |
early_stopping_rounds |
Альфа-ыдырау детекторы ретінде қатпарлардағы SHAP маңыздылығы

Блогта градиентті күшейтетін үлгідегі SHAP — TreeExplainer, жиынтық сюжеттер және оларды қалай оқу керек. Қамтылмаған нәрсе SHAP бойлық пайдалану болып табылады: әр алға жылжыту үшін бір түсіндіргіш, уақыт бойынша әрбір мүмкіндіктің орташа абсолютті атрибуциясын бақылайды.
def shap_over_time(models, test_sets, feature_names) -> pd.DataFrame:
"""
Track SHAP-based feature importance across walk-forward folds.
Rows are folds, columns are features.
"""
importance_over_time = []
for fold_idx, (model, X_test) in enumerate(zip(models, test_sets)):
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X_test)
mean_abs_shap = np.abs(shap_values).mean(axis=0)
importance_over_time.append(
pd.Series(mean_abs_shap, index=feature_names, name=fold_idx)
)
return pd.DataFrame(importance_over_time)
Шығару - бүктеме × мүмкіндік матрицасы және онда үш ерекшеленетін пішін бар:
- Монотонды құлдырау — мүмкіндіктің жиегі ыдырап жатыр. Жоюға немесе нарық құрылымында не өзгергенін зерттеуге үміткер.
- Жоғары дисперсия, тренд жоқ — бұл мүмкіндік кейбір режимдерде модель ілінетін шу. Бұл плато талдауы мүмкіндіктерге қолданылатын параметрлердің санын анықтайды.
- Режимді ауыстыратын қадамды өзгерту — маңыздылық белгілі бір бүктемеде төмендейді және төменде қалады. Әдетте альфа ыдырауына емес, биржаға, листингке немесе комиссиялық құрылым оқиғасына бақыланады.
Тұзақ мынада: модельдің жалпы сенімділігі өзгерген кезде абсолютті SHAP қатпарлар бойынша салыстыруға келмейді: барлық жерде 0,5-ке жақын болжайтын модель бір уақытта әрбір мүмкіндік үшін кішірек атрибуттарды жасайды. Салыстыру алдында әрбір бүктеудің маңыздылығын 1-ге қосу үшін қалыпқа келтіріңіз, осылайша сіз сенімділік ауысымынан гөрі салыстырмалы маңыздылық ауысымдарын оқисыз.
Неліктен ағаштар, қысқаша

Grinsztajn, Oyallon және Varoquaux (NeurIPS 2022) ағаш ансамбльдерін 45 кестелік деректер жиынында терең үйренуге қарсы сынады және ағаштарды жақсы көретін оқшауланған үш құрылымдық сипаттарды — үшеуі де қаржылық деректерді сипаттайды:
- Тұрыс емес мақсатты функциялар. Қайтарулар біркелкі емес; оларда үзілістер, режим өзгерістері және шекті әсерлер бар. Оське тураланған сплиттер оларды тегіс бетке жақындатпай түсіреді.
- Ақпараттық емес мүмкіндіктер. Альфа құбыры жүздеген үміткерлерді тудырады және көпшілігі шу. Ағаштар әр бөлінгенде таңдалады; нейрондық желілер барлық кірістер бойынша сыйымдылықты таратады, параметрлерді шуға жұмсайды.
- Айналмайтын инварианттылық. Көлемді құбылмалылықпен алмастыруға болмайды. Нейрондық желілер әдепкі бойынша айналмалы инвариантты, мүмкіндіктердің сызықтық комбинацияларын түпнұсқаларға балама ретінде қарастырады - бұл нақты семантикалық мағынасы бар мүмкіндіктер үшін дұрыс емес.
Бұл мәміленің практикалық жағы үшін — деректер өлшемі, кідіріс, feature engineering күші, интерпретация және режимге бейімделу — блогта машиналық оқытумен spread modeling бойынша толық шешімдер кестесі бар.
Инженерлік мүмкіндіктер

import pandas as pd
import numpy as np
def build_features(df: pd.DataFrame) -> pd.DataFrame:
"""
Build trading features from OHLCV data.
Expects columns: open, high, low, close, volume, timestamp
"""
feat = pd.DataFrame(index=df.index)
feat['return_1'] = df['close'].pct_change(1)
feat['return_5'] = df['close'].pct_change(5)
feat['return_15'] = df['close'].pct_change(15)
feat['return_60'] = df['close'].pct_change(60)
log_ret = np.log(df['close'] / df['close'].shift(1))
feat['volatility_20'] = log_ret.rolling(20).std()
feat['volatility_60'] = log_ret.rolling(60).std()
feat['vol_ratio'] = feat['volatility_20'] / feat['volatility_60']
feat['parkinson_vol'] = np.sqrt(
(1 / (4 * np.log(2)))
* (np.log(df['high'] / df['low']) ** 2).rolling(20).mean()
)
feat['volume_sma_ratio'] = df['volume'] / df['volume'].rolling(20).mean()
feat['volume_std_20'] = df['volume'].rolling(20).std()
feat['obv'] = (np.sign(df['close'].diff()) * df['volume']).cumsum()
feat['obv_slope'] = feat['obv'].diff(5) / feat['obv'].shift(5)
feat['high_low_range'] = (df['high'] - df['low']) / df['close']
feat['close_position'] = (df['close'] - df['low']) / (df['high'] - df['low'])
feat['gap'] = df['open'] / df['close'].shift(1) - 1
delta = df['close'].diff()
gain = delta.clip(lower=0).rolling(14).mean()
loss = (-delta.clip(upper=0)).rolling(14).mean()
feat['rsi_14'] = 100 - 100 / (1 + gain / loss)
ema_12 = df['close'].ewm(span=12).mean()
ema_26 = df['close'].ewm(span=26).mean()
feat['macd'] = (ema_12 - ema_26) / df['close']
feat['macd_signal'] = feat['macd'].ewm(span=9).mean()
feat['macd_hist'] = feat['macd'] - feat['macd_signal']
for window in [10, 20, 50]:
sma = df['close'].rolling(window).mean()
feat[f'distance_sma_{window}'] = (df['close'] - sma) / sma
std = df['close'].rolling(window).std()
feat[f'bb_position_{window}'] = (df['close'] - sma) / (2 * std)
return feat
Жоғарыдағы әрбір feature құрылымы бойынша causal: тек rolling және expanding операциялары, full-sample статистикасы жоқ. Бұл әдейі жасалған: whole-series z-scoring — мұндай pipeline-дағы ең көп таралған leakage, оның reported Sharpe-ке әсері look-ahead bias таксономиясында өлшенген.
Қаржы деректеріндегі XGBoost үшін гиперпараметр ауқымдары

Мақсат үлгідегі максималды өнімділік емес, үлгіден тыс максималды тұрақтылық. Бірінші реттілік, екінші күрделілік:
| Параметр | Типтік диапазон | Мақсаты |
|---|---|---|
max_depth |
3--7 | Өзара әрекеттесу тәртібін шектейді. Тереңірек ағаштар жоғары дәрежелі өзара әрекеттесуді модельдейді, бірақ тезірек шамадан тыс орналасады. 4-тен бастаңыз. |
min_child_weight |
5--100 | Жапырақтағы ең аз гессиан сомасы. Өзгерген сайын қайта реттеңіз scale_pos_weight немесе мақсат. |
learning_rate |
0,005--0,05 | Шөгу. Төменгі мәндер көбірек ағаштарды қажет етеді, бірақ жақсырақ жалпыланады. |
subsample |
0,5--0,8 | Бір ағашқа жол сынамасы. Кездейсоқтықты қосады, артық сәйкестікті азайтады. |
colsample_bytree |
0,5--0,8 | Бір ағашқа баған сынамасы. Көптеген өзара байланысты мүмкіндіктері бар сыни. |
gamma |
0,5--5,0 | Бөлу үшін ең аз шығынды азайту. Кесу табалдырығы ретінде әрекет етеді. |
reg_alpha (L1) |
0,01--1,0 | Жапырақ салмағы бойынша L1. Сиректікті ынталандырады. |
reg_lambda (L2) |
0,1--10,0 | Жапырақ салмағы бойынша L2. Үлкен жапырақ мәндерін болдырмайды. |
Іздеу процедурасының өзі — TPE, study persistence және Bayesian search неге coordinate descent-тен жақсы екені — туралы Optuna және coordinate descent мақаласын қараңыз. Қолданған кез келген trial саны кейін Sharpe дефляциясына енгізілуі керек.
Бұл мақала басқа жазбаларға әдейі не қалдырады

Градиентті күшейту үлгісінің айналасындағы тірек мұнда өлшемдермен бірге жабылған:
- Тексеруді бөлу. Алға қарай оңтайландыру зәкірлі терезелер мен жылжымалы терезелер және деградация жылдамдығы үшін;
purged_walk_forwardмашиналық оқытумен модельдеуді тарату нақты тазалау/эмбарго аралығы бар сплиттерге арналған. Біреуін тазартусыз жібермеңіз — қабаттасқан алдыңғы терезе нысандары бүктеме шекаралары арқылы ағып кетеді. - Басқару элементтерін шамадан тыс орнату. Пойыз/сынақ аралығы және көлденең бүктеу мүмкіндігінің тұрақтылығы, плато талдауында және артқы сынақтың шамадан тыс орнату ықтималдығы.
- PnL болжамы. Flat bps costs бар векторланған
signal * shifted-returnbacktest бірнеше сәтті trade арқылы Sharpe жасап шығарады — objective function design және active time үшін PnL мақалаларын қараңыз. Search trial саны үшін post-search Sharpe-ті дефляциялаңыз: deflated Sharpe және edge шынайы болмағандағы көрініс үшін адал теріс нәтиже. - Транзакция шығындары. Слиппинг құны үлгілері және мейкер-такер алымдары. 53% дәлдік бағыты үлгісі сіз таңдаған шығын үлгісінде өмір сүреді немесе өледі.
Бұл жерде нәтижелер емес, гипотеза ретінде тағы үш қате айтылады: тек тізімде көрсетілген активтер бойынша оқудан аман қалуға бейімділік; шикі қайтарым көрсеткіштерінің стационарлық еместігі, мұнда бета-қалдық қайтарым жақсырақ болуы мүмкін; және қайта даярлау каденциясы, мұнда SHAP-over-folds диагностикасы табиғи дрейф мониторы болып табылады.
Қорытынды

Қайтару бағытының жіктелуі ешкім таңдамаған шешім табалдырығымен теңдестірілмеген мәселе және үш стандартты түзету бір-бірін алмастырмайды. scale_pos_weight бір сызық болып табылады, бірақ ықтималдықтарды калибрлеп, үнсіз қозғалады min_child_weight. Фокус жоғалтуға гессий қажет, ол көптеген іске асырулар шамамен. Шекті оңтайландыру үлгіні жалғыз қалдырады және саудаға қатысты шектеуді — дәлдікті — ол тиесілі жеріне қояды, бірақ егер шек оқудан кейін келетін деректерде әр бүкте қайта орнатылса ғана.
Қайсысы жеңеді - бұл сіздің деректеріңіз, шегіңіз және шығындар үлгісі туралы эмпирикалық сұрақ. Жоғарғы жағындағы кесте бір деректер жиынының жауабы болып табылады; оны өзіңіздікінде іске қосу болжауға кеткен баптау уақытынан аз тұрады.
- Қосымша оқу:*
- Grinsztajn және т.б., «Неліктен ағашқа негізделген модельдер әлі де әдеттегі кестелік деректерде терең оқытудан асып түседі?» (NeurIPS 2022)
- Ванг және т.б., «Бассыздық-XGBoost: екілік белгі-теңгерімсіз жіктеу үшін өлшенген және фокалды жоғалтуларды пайдалану»
- Чен және Гострин, "XGBoost: Ағашты кеңейту жүйесі" (KDD 2016)
- Ke және т.б., «LightGBM: жоғары тиімді градиентті күшейтетін шешім ағашы» (NeurIPS 2017)
- Прохоренкова және т.б., «CatBoost: категориялық ерекшеліктері бар бейтарап күшейту» (NeurIPS 2018)
- XGBoost құжаттамасы: Параметрлерді баптау бойынша ескертпелер
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.