纳斯达克股票交易所的每个交易日都以纳斯达克收盘交叉竞拍结束。这个过程确定了交易所上市证券的官方收盘价格。这些收盘价格对于投资者、分析师和其他市场参与者来说,是评估个别证券和整个市场表现的关键指标。
是数据点的总数。
是数据点
的预测值。
是数据点
的观察值。
https://www.kaggle.com/code/lblhandsome/optiver-robust-best-single-model
特征组合1
首先生成一些不平衡特征,这些特征可以用于训练机器学习模型,以预测股票价格走势或其他市场行为。
volume
:股票的交易量,表示为买入和卖出的总量。
mid_price
:股票的中间价格,即卖出价格和买入价格的平均值。
liquidity_imbalance
:市场的流动性不平衡,通过买卖订单的大小差异来计算。
matched_imbalance
:通过买卖订单未匹配部分和已匹配部分的差异来计算市场的匹配不平衡。
size_imbalance
:买入订单大小与卖出订单大小的比率。
价格差异特征
:基于不同价格之间的差异,例如
far_price
和
near_price
之间的差异。
imbalance_momentum
:不平衡大小的动量,表示为不平衡大小的变化与已匹配大小之比。
price_spread
:卖出价格与买入价格之间的差距。
spread_intensity
:价格差距的变化。
price_pressure
:价格差距与不平衡大小的乘积。
market_urgency
:价格差距与流动性不平衡的乘积。
depth_pressure
:卖出和买入订单簿深度与价格差异的乘积。
对于指定的列(如
matched_size
、
imbalance_size
、
reference_price
和
imbalance_buy_sell_flag
),计算它们的滞后值和百分比变化。这些特征在不同时间窗口内计算,包括1、2、3和10个时间单位。
对于指定的列(如
ask_price
、
bid_price
、
ask_size
和
bid_size
),计算它们的差异,也在不同时间窗口内计算。
# generate imbalance features
def imbalance_features(df):
prices = ["reference_price", "far_price", "near_price", "ask_price", "bid_price", "wap"]
sizes = ["matched_size", "bid_size", "ask_size", "imbalance_size"]
# V1
df["volume"] = df.eval("ask_size + bid_size")
df["mid_price"] = df.eval("(ask_price + bid_price) / 2")
df["liquidity_imbalance"] = df.eval("(bid_size-ask_size)/(bid_size+ask_size)")
df["matched_imbalance"] = df.eval("(imbalance_size-matched_size)/(matched_size+imbalance_size)")
df["size_imbalance"] = df.eval("bid_size / ask_size")
for c in combinations(prices, 2):
df[f"{c[0]}_{c[1]}_imb"] = df.eval(f"({c[0]} - {c[1]})/({c[0]} + {c[1]})")
for c in [['ask_price', 'bid_price', 'wap', 'reference_price'], sizes]:
triplet_feature = calculate_triplet_imbalance_numba(c, df)
df[triplet_feature.columns] = triplet_feature.values
# V2
df["imbalance_momentum"] = df.groupby(['stock_id'])['imbalance_size'].diff(periods=1) / df['matched_size']
df["price_spread"] = df["ask_price"] - df["bid_price"]
df["spread_intensity"] = df.groupby(['stock_id'])['price_spread'].diff()
df['price_pressure'] = df['imbalance_size'] * (df['ask_price'] - df['bid_price'])
df['market_urgency'] = df['price_spread'] * df['liquidity_imbalance']
df['depth_pressure'] = (df['ask_size'] - df['bid_size']) * (df['far_price'] - df['near_price'])
for func in ["mean", "std", "skew", "kurt"]:
df[f"all_prices_{func}"] = df[prices].agg(func, axis=1)
df[f"all_sizes_{func}"] = df[sizes].agg(func, axis=1)
# V3
for col in ['matched_size', 'imbalance_size', 'reference_price', 'imbalance_buy_sell_flag']:
for window in [1, 2, 3, 10]:
df[f"{col}_shift_{window}"] = df.groupby('stock_id')[col].shift(window)
df[f"{col}_ret_{window}"] = df.groupby('stock_id')[col].pct_change(window)
for col in ['ask_price', 'bid_price', 'ask_size', 'bid_size']:
for window in [1, 2, 3, 10]:
df[f"{col}_diff_{window}"] = df.groupby("stock_id")[col].diff(window)
return df.replace([np.inf, -np.inf], 0)
特征组合2
提出时间和股票特征,用于提供更多关于交易数据的上下文信息。
dow
(Day of the Week):表示日期的星期几,范围从0到4。这个特征可用于捕捉一周内的周期性交易模式。
seconds
:表示每个交易日从交易日开始到当前时间的秒数。这有助于了解一天中的不同时间段对市场的影响。
minute
:表示每个交易日从交易日开始到当前时间的分钟数。这有助于将交易数据划分为不同的时间段,以分析分钟级别的变化。
# generate time & stock features
def other_features(df):
df["dow"] = df["date_id"] % 5
df["seconds"] = df["seconds_in_bucket"] % 60
df["minute"] = df["seconds_in_bucket"] // 60
for key, value in global_stock_id_feats.items():
df[f"global_{key}"] = df["stock_id"].map(value.to_dict())
return df
时序验证集
接下来使用LightGBM来建立一个回归模型,以在股票市场上预测股票收盘价格的变动。模型的参数和数据集的划分都是关键因素,影响着模型的性能和泛化能力。
lgb_params = {
"objective" : "mae",
"n_estimators" : 3000,
"num_leaves" : 128,
"subsample" : 0.6,
"colsample_bytree" : 0.6,
"learning_rate" : 0.05,
"n_jobs" : 4,
"device" : "gpu",
"verbosity": -1,
"importance_type" : "gain",
}
print(f"Feature length = {len(feature_name)}")
offline_split = df_train['date_id']>(split_day - 45)
df_offline_train = df_train_feats[~offline_split]
df_offline_valid = df_train_feats[offline_split]
df_offline_train_target = df_train['target'][~offline_split]
df_offline_valid_target = df_train['target'][offline_split]
print("Valid Model Trainning.")
lgb_model = lgb.LGBMRegressor(**lgb_params)
lgb_model.fit(
df_offline_train[feature_name],
df_offline_train_target,
eval_set=[(df_offline_valid[feature_name], df_offline_valid_target)],
callbacks=[
lgb.callback.early_stopping(stopping_rounds=100),
lgb.callback.log_evaluation(period=100),
],
)
预测结果后处理
在预测代码中加入数据缓存,用于存储历史测试数据,以便在进行预测时使用。然后根据缓存数据生成特征,这些特征将用于进行预测。
最终使用np.clip函数来确保预测结果在一个指定的范围内,通常是评估标准所要求的范围。
for (test, revealed_targets, sample_prediction) in iter_test:
now_time = time.time()
cache = pd.concat([cache, test], ignore_index=True, axis=0)
if counter > 0:
cache = cache.groupby(['stock_id']).tail(21).sort_values(by=['date_id', 'seconds_in_bucket', 'stock_id']).reset_index(drop=True)
feat = generate_all_features(cache)[-len(test):]
lgb_prediction = infer_lgb_model.predict(feat)
lgb_prediction = zero_sum(lgb_prediction, test['bid_size'] + test['ask_size'])
clipped_predictions = np.clip(lgb_prediction, y_min, y_max)
sample_prediction['target'] = clipped_predictions
env.predict(sample_prediction)
大模型来做推荐系统有意义吗?会给现有的增加价值吗?
刘慈欣:人类的无能反而是人类最后的屏障
1101.AI日报:GPT-4+DALL·E3+midjourney 做出了AI版愤怒的南瓜
Next.js 的路由为什么这么奇怪?
Nature | 30多年前的断言被打破了?大模型具备了人类水平的系统泛化能力
陶哲轩论文漏洞竟被AI发现,26年预言要成真!看定理名猜出研究方向,大神直呼AI能力惊人
知识图谱实践:基于在线百科多义实体的消歧与链接项目实践
大模型训练与微调关键技术-医学问答机器人
目录整理 | 机器学习初学者的完全入门指南
Kafka基本原理、生产问题总结及性能优化实践
NestJS装饰器
苹果M3是英特尔、高通和AMD的威胁吗?
云,哪里贵了?
刷抖音搞出一个小项目,活该他赚钱
史上最全后台开发成长指南
面试官:一台服务器最大能支持多少条 TCP 连接?问倒一大片。。。