当前位置:首页 >> 中医新闻 >> A股实践 :图神经网络与新闻共现矩阵手段(附代码)

A股实践 :图神经网络与新闻共现矩阵手段(附代码)

发布时间:2023-02-24

要,隐式地专业训练求讲授房东路由对之前心路由通告传递的益处,然后根据益处对房东路由的并不相同之处展开基准求和,给予新的路由比如说。

基于Qlib的方法论系统性

Qlib是开发者技术开发的开源AI取样基本概念。该平台以机器求讲授在取样数据系统性的运用为当前,整合了类似数据下载、类似数据预处理、机器求讲授外推及回测和方针高度评价的均方式则上。Qlib基本概念之前有很多仍然充分利用的机器求讲授静态,其之前就包含GATs静态。该静态的基本基本概念如下:

可用类似数据:为某股份池(后续方法论运用于沪深300成分股)每个股份现在158个技术量化的历史文化星期脱氧核糖核酸作为并不相同之处类似数据。这158个技术量化是Qlib外设的常用的技术量化。每个专业训练的比对为一只股份158个并不相同之处现在N天的历史文化类似数据上有的等价。

一个batch的上述星期脱氧核糖核酸类似数据首先可用到LSTM静态给予 ,即LSTM在最后一个时刻T的隐藏状态并不相同之处。这一层主要运用于LSTM捕捉脱氧核糖核酸曾一度不确定性,求讲授股份的星期脱氧核糖核酸并不相同之处。

GAT层:GAT层的当前是建起可以说明了股份在在关联人关系的静态,Qlib之前充分利用的GAT引入有序自视线必要,这种方式则不必需借助于详述了的股份人关系由此可知,而是对每个路由推算是其与其他所有路由的益处,日后基准生成其他路由的并不相同之处。在上一层LSTM求讲授到每个股份的星期脱氧核糖核酸并不相同之处后,这些并不相同之处作为这个由此可知之前每个路由的类型,并通过视线必要生成其他路由的类型,并可用到非新线性介导层,从而达到求讲授整个由此可知结构设计的便是比如说。

得出最大限度:在Qlib充分利用的GATs静态之前,得出最大限度为t+2日与t+1日定价推算是的利息率,而巨大损失变量则搭配的最非常简单的MSE变量。

以上为Qlib之前充分利用的基于由此可知视线网络服务GAT充分利用的股份利息外推,其在借助于由此可知网络服务的处理过程之前,并没有考量股份在在的显性人关系。在最早提议GAT的科讲授论文之前,作者只考量了有详述了由此可知人关系的路由在在通告的传递,这样的方式则称为Masked Self-Attention,即只推算是南边路由在在的视线下式。基于这个语义,我们在Qlib已充分利用的GATs静态之前过渡到基于新闻网共现的详述了由此可知人关系,并测试在之后方针运用技术性详述了由此可知人关系过渡到后静态真实感是否有提升。

借助于新闻网共现等价

我们基于数库科技提供的SmarTag新闻网系统性类似数据借助于新闻网共现等价,这个等价作为南边阶等价传布GAT静态之前。我们运用于SmarTag类似数据之前的股份ID同上(news_compnay_label同上),新闻网类似数据的跨度为2017年1翌年1日至2022年3翌年1日,其类似数据结构设计如下由此可知ID类似除此以外简述:

我们首先以每个停牌下午早先为整块星期,把收盘后的新闻网算是好好下一停牌的新闻网,这样就可以把年历日映射到停牌,然后在基于一般而言字符串推算是每个停牌的股份共现等价:

importpandas aspd

fromjoblib importParallel

defget_coc_dt(news_data, dt):

temp = news_data.query( "trade_date==@dt").reset_index(drop= True)

temp[ 'cnt'] = 1

coc_df = temp.pivot_table(index= 'news_id', columns= 'sec_code', values= 'cnt').fillna( 0)

coc_mat, coc_codes = coc_df.values, coc_df.columns.tolist

adj_mat = coc_mat.T.dot(coc_mat)

adj_df = pd.DataFrame(data=adj_mat, index=coc_codes , columns=coc_codes ).replace( 0, np.nan).unstack.dropna

return(dt, adj_df)

defget_coc_all(news_data):

all_dts_str = [str(dt) fordt innews_data[ 'trade_date'].dt.date.unique]

coc_all_lst = Parallel(n_jobs= 5)(delayed(get_coc_dt)(com_senti_fil, dt) fordt intqdm(all_dts_str))

returncoc_all_lst

由于共现等价非常均匀分布,如果直接留有等价将浪费大量空在在与效率,所以我们运用于多重书目的Series留有每日的股份共现类似数据,并删除空值记录。

每日的股份共现情况下转变现在频繁,我们对每日的共现等价推算是20日的净资产基准回转概率分布,这样既能一个系统凸显共现人关系的推移,也能使类似数据转变平稳。由于我们仅必需沪深300的共现等价,所以必需从原先均A的记录之前软性出沪深300的每日共现等价,然后推算是回转概率分布:

fromcollections importOrderDict

# 一般而言字符串之前csi300_sec_code为沪深300所有历史文化成分股的字符串列同上

coc_all_lst = get_coc_all(news_data)

fordt, coc_mat incoc_all_lst:

temp = coc_mat.unstack.reindex(csi300_sec_code).T.reindex(csi300_sec_code)

csi300_coc_dct[dt] = temp.unstack.dropna

# 推算是共现等价回转概率分布(净资产基准,半衰为10),以{dt: Series}的PDF留有,

# 一般而言字符串只是作为示例,我们之后是在GATs当前充分利用的

df_csi300 = pd.concat(csi300_coc_dct.values, keys=csi300_coc_dct.keys, axis= 1).fillna( 0)

coc_ewa_csi300 = df_csi300.ewm(halflife= 10, min_periods= 1, axis= 1).mean

coc_ewa_csi300 = coc_ewa_csi300.where(coc_ewa_csi300>= 0.25, np.nan) # 软性共现短时间概率分布极小0.25的记录

coc_ewa_csi300_dct = OrderedDict

forcol incoc_ewa_csi300:

coc_ewa_csi300_dct[col] = coc_ewa_csi300[col].dropna

一般而言就是共现等价的示例类似数据,总结借助于处理过程就是基于日度新闻网之前股份共现的类似数据,按10日半衰推算是净资产漂移概率分布,并软性上来数值极小0.25的记录:

简化Qlib外设GATs字符串,过渡到新闻网共现等价

Qlib外设的GATs静态在一般而言梯度:qlib.contrib.model.pytorch_gats_ts之前的GATModel,这个静态之前没有运用于显性的由此可知结构设计类似数据,我们必需好好以简化,主要分一般而言两个流程:

1、在GATModel之前过渡到南边接等价,简化后的字符串如下,主要推移在cal_attention变量里,在47行attenion_out经非新线性介导变量leaky_relu介导后,并没有直接可用到softmax展开均值归一,而是运用于南边接等价adj将adj之前记录总和0的路由的视线均值软性上来(新设零),然后在经softmax展开均值归一。

2、我们还过渡到了由此可知结构设计之前的dropout层,给定为gat_dropout,用于对由此可知视线之前的均值随机dropout,提升静态稳健性。

classGATModel(nn.Module):

def短时init短时(self, d_feat= 6, hidden_size= 64, num_layers= 2, lstm_dropout= 0.0, gat_dropout= 0.0, base_model= "GRU") :

super.短时init短时

ifbase_model == "GRU":

self.rnn = nn.GRU(

input_size=d_feat,

hidden_size=hidden_size,

num_layers=num_layers,

batch_first= True,

dropout=lstm_dropout,

)

elifbase_model == "LSTM":

self.rnn = nn.LSTM(

input_size=d_feat,

hidden_size=hidden_size,

num_layers=num_layers,

batch_first= True,

dropout=lstm_dropout,

)

else:

raiseValueError( "unknown base model name MLT-%sMLT-"% base_model)

self.hidden_size = hidden_size

self.d_feat = d_feat

self.transformation = nn.Linear(self.hidden_size, self.hidden_size)

self.a = nn.Parameter(torch.randn(self.hidden_size * 2, 1))

self.a.requires_grad = True

self.fc = nn.Linear(self.hidden_size, self.hidden_size)

self.fc_out = nn.Linear(hidden_size, 1)

self.leaky_relu = nn.LeakyReLU

self.softmax = nn.Softmax(dim= 1)

self.dropout = nn.Dropout(gat_dropout)

defcal_attention(self, x, y, adj):

x = self.transformation(x)

y = self.transformation(y)

sample_num = x.shape[ 0]

dim = x.shape[ 1]

e_x = x.expand(sample_num, sample_num, dim)

e_y = torch.transpose(e_x, 0, 1)

attention_in = torch.cat((e_x, e_y), 2).view( -1, dim * 2)

self.a_t = torch.t(self.a)

attention_out = self.a_t.mm(torch.t(attention_in)).view(sample_num, sample_num)

attention_out = self.leaky_relu(attention_out)

zero_vec = -9e15*torch.ones_like(attention_out)

attention_out = torch.where(adj> 0, attention_out, zero_vec)

att_weight = self.softmax(attention_out)

att_weight = self.dropout(att_weight)

returnatt_weight

defforward(self, x, adj):

out, _ = self.rnn(x)

hidden = out[:, -1, :]

att_weight = self.cal_attention(hidden, hidden, adj)

hidden = att_weight.mm(hidden) + hidden

hidden = self.fc(hidden)

hidden = self.leaky_relu(hidden)

returnself.fc_out(hidden).squeeze

那么我们运用于数库Smartag推算是的详述了由此可知人关系(新闻网共现等价)怎么以给定adj传布GATModel的forward变量之前呢?GATModel是在GATs类的fit系统性方法之前被调用,所以我们只要在GATs初始化的处理过程之前唯取均部历史文化的新闻网共现类似数据,然后在专业训练处理过程之前按照应于和当期的成分股字符串展开唯取即可,简略字符串如下,主要改动的偏远地区有:

1、初始化时唯取均部新闻网共现的历史文化类似数据,load_adj_data变量根据可用的半衰adj_hf和阈值adj_th,推算是净资产漂移基准的新闻网共现等价

2、get_adj_matrix根据给定dt和codes,来到指定应于某两组股份的共现等价,这里有个显然必需注意是,我们把对角等价都用1可用,因为GAT在通告生成时必需再加自身路由的并不相同之处。

3、如何在train的处理过程之前知道当前专业训练类似数据的应于和金融集团?我们可以看到在train_epoch和test_epoch之前我们通过dataloader.dataset.get_index获得了所有专业训练应于及金融集团,这样每次for循序内,我们就可以知道当前专业训练类似数据的应于和金融集团。

classGATs(Model):

adj_path = './csi300_coc_dct.pkl'

"""GATs Model

Parameters

---------------

lr : float

learning rate

d_feat : int

input dimensions for each time step

metric : str

the evaluate metric used in early stop

optimizer : str

optimizer name

GPU : int

the GPU ID used for training

"""

def短时init短时(

self,

adj_hf= 10,

adj_th= 0.2,

d_feat= 20,

hidden_size= 64,

num_layers= 2,

lstm_dropout= 0.0,

gat_dropout= 0.0,

n_epochs= 200,

lr= 0.001,

metric= "",

early_stop= 20,

loss= "mse",

base_model= "GRU",

model_path=None,

optimizer= "adam",

GPU= 0,

n_jobs= 10,

seed=None,

**kwargs

) :

# Set logger.

self.logger = get_module_logger( "GATs")

self.logger.info( "GATs pytorch version...")

# Adj Matirx

self.adj = self.load_adj_data(self.adj_path, adj_hf, adj_th)

# set hyper-parameters.

self.d_feat = d_feat

self.hidden_size = hidden_size

self.num_layers = num_layers

self.lstm_dropout = lstm_dropout

self.gat_dropout = gat_dropout

self.n_epochs = n_epochs

self.lr = lr

self.metric = metric

self.early_stop = early_stop

self.optimizer = optimizer.lower

self.loss = loss

self.base_model = base_model

self.model_path = model_path

self.device = torch.device( "cuda:%d"% (GPU) iftorch.cuda.is_available andGPU>= 0else"cpu")

self.n_jobs = n_jobs

self.seed = seed

self.logger.info(

"GATs parameters setting:"

"d_feat : {}"

"hidden_size : {}"

"num_layers : {}"

"lstm_dropout : {}"

"gat_dropout : {}"

"n_epochs : {}"

"lr : {}"

"metric : {}"

"early_stop : {}"

"optimizer : {}"

"loss_type : {}"

"base_model : {}"

"model_path : {}"

"visible_GPU : {}"

"use_GPU : {}"

"seed : {}".format(

d_feat,

hidden_size,

num_layers,

lstm_dropout,

gat_dropout,

n_epochs,

lr,

metric,

early_stop,

optimizer.lower,

loss,

base_model,

model_path,

GPU,

self.use_gpu,

seed,

)

)

ifself.seed isnotNone:

np.random.seed(self.seed)

torch.manual_seed(self.seed)

self.GAT_model = GATModel(

d_feat=self.d_feat,

hidden_size=self.hidden_size,

num_layers=self.num_layers,

lstm_dropout=self.lstm_dropout,

gat_dropout=self.gat_dropout,

base_model=self.base_model,

)

self.logger.info( "model:{:}".format(self.GAT_model))

self.logger.info( "model size: {:.4f} MB".format(count_parameters(self.GAT_model)))

ifoptimizer.lower == "adam":

self.train_optimizer = optim.Adam(self.GAT_model.parameters, lr=self.lr)

elifoptimizer.lower == "gd":

self.train_optimizer = optim.SGD(self.GAT_model.parameters, lr=self.lr)

else:

raiseNotImplementedError( "optimizer {} is not supported!".format(optimizer))

self.fitted = False

self.GAT_model.to(self.device)

defload_adj_data(self, adj_path, adj_hf, adj_th):

withopen( './csi_coc_mat.pkl', 'rb') asf:

csi300_coc_dct = pickle.load(f)

df_csi300 = pd.concat(csi300_coc_dct.values, keys=csi300_coc_dct.keys, axis= 1).fillna( 0)

coc_ewa_csi300 = df_csi300.ewm(halflife=adj_hf, min_periods= 1, axis= 1).mean

coc_ewa_csi300 = coc_ewa_csi300.where(coc_ewa_csi300>=adj_th, np.nan)

coc_ewa_csi300_dct = OrderedDict

forcol incoc_ewa_csi300:

coc_ewa_csi300_dct[col] = coc_ewa_csi300[col].dropna

returncoc_ewa_csi300_dct

@property

defuse_gpu(self):

returnself.device != torch.device( "cpu")

defmse(self, pred, label):

loss = (pred - label) ** 2

returntorch.mean(loss)

defloss_fn(self, pred, label):

mask = ~torch.isnan(label)

ifself.loss == "mse":

returnself.mse(pred[mask], label[mask])

raiseValueError( "unknown loss MLT-%sMLT-"% self.loss)

defmetric_fn(self, pred, label):

mask = torch.isfinite(label)

ifself.metric in( "", "loss"):

return-self.loss_fn(pred[mask], label[mask])

raiseValueError( "unknown metric MLT-%sMLT-"% self.metric)

defget_daily_inter(self, df, shuffle=False):

# organize the train data into daily batches

daily_count = df.groupby(level= 0).size.values

daily_index = np.roll(np.cumsum(daily_count), 1)

daily_index[ 0] = 0

ifshuffle:

# shuffle data

daily_shuffle = list(zip(daily_index, daily_count))

np.random.shuffle(daily_shuffle)

daily_index, daily_count = zip(*daily_shuffle)

returndaily_index, daily_count

defget_adj_matrix(self, dt, codes):

ifnotisinstance(dt, str):

dt_str = str(dt.date)

else:

dt_str = dt

res = self.adj.get(dt_str).unstack

res = res.reindex(codes).T.reindex(codes)

fill_df = pd.DataFrame(np.diag(np.ones(len(res))[np.newaxis:]), index=res.index, columns=res.columns)

res = res.combine_first(fill_df)

adj = torch.FloatTensor(res.values)

returnadj.to(self.device)

deftrain_epoch(self, data_loader):

self.GAT_model.train

idx = data_loader.dataset.get_index

dts = idx.get_level_values( 0).unique.tolist

codes_idx = idx.get_level_values( 1)

i = 0

fordata indata_loader:

codes = codes_idx[idx.get_loc(dts[i])].tolist

adj = self.get_adj_matrix(dts[i], codes)

data = data.squeeze

feature = data[:, :, 0: -1].to(self.device)

label = data[:, -1, -1].to(self.device)

pred = self.GAT_model(feature.float, adj)

loss = self.loss_fn(pred, label)

self.train_optimizer.zero_grad

loss.backward

torch.nn.utils.clip_grad_value_(self.GAT_model.parameters, 3.0)

self.train_optimizer.step

i += 1

deftest_epoch(self, data_loader):

self.GAT_model.eval

scores = []

losses = []

idx = data_loader.dataset.get_index

dts = idx.get_level_values( 0).unique.tolist

codes_idx = idx.get_level_values( 1)

i = 0

fordata indata_loader:

codes = codes_idx[idx.get_loc(dts[i])].tolist

adj = self.get_adj_matrix(dts[i], codes)

data = data.squeeze

feature = data[:, :, 0: -1].to(self.device)

# feature[torch.isnan(feature)] = 0

label = data[:, -1, -1].to(self.device)

pred = self.GAT_model(feature.float, adj)

loss = self.loss_fn(pred, label)

losses.append(loss.item)

score = self.metric_fn(pred, label)

scores.append(score.item)

i += 1

returnnp.mean(losses), np.mean(scores)

deffit(

self,

dataset,

evals_result=dict ,

save_path=None,

) :

dl_train = dataset.prepare( "train", col_set=[ "feature", "label"], data_key=DataHandlerLP.DK_L)

dl_valid = dataset.prepare( "valid", col_set=[ "feature", "label"], data_key=DataHandlerLP.DK_L)

ifdl_train.empty ordl_valid.empty:

raiseValueError( "Empty data from dataset, please check your dataset config.")

dl_train.config(fillna_type= "ffill+bfill") # process nan brought by dataloader

dl_valid.config(fillna_type= "ffill+bfill") # process nan brought by dataloader

sampler_train = DailyBatchSampler(dl_train)

sampler_valid = DailyBatchSampler(dl_valid)

train_loader = DataLoader(dl_train, sampler=sampler_train, num_workers=self.n_jobs, drop_last= True)

valid_loader = DataLoader(dl_valid, sampler=sampler_valid, num_workers=self.n_jobs, drop_last= True)

save_path = get_or_create_path(save_path)

stop_steps = 0

train_loss = 0

best_score = -np.inf

best_epoch = 0

evals_result[ "train"] = []

evals_result[ "valid"] = []

# load pretrained base_model

ifself.base_model == "LSTM":

pretrained_model = LSTMModel(d_feat=self.d_feat, hidden_size=self.hidden_size, num_layers=self.num_layers)

elifself.base_model == "GRU":

pretrained_model = GRUModel(d_feat=self.d_feat, hidden_size=self.hidden_size, num_layers=self.num_layers)

else:

raiseValueError( "unknown base model name MLT-%sMLT-"% self.base_model)

ifself.model_path isnotNone:

self.logger.info( "Loading pretrained model...")

pretrained_model.load_state_dict(torch.load(self.model_path, map_location=self.device))

model_dict = self.GAT_model.state_dict

pretrained_dict = {

k: v fork, v inpretrained_model.state_dict.items ifk inmodel_dict # pylint: disable=E1135

}

model_dict.update(pretrained_dict)

self.GAT_model.load_state_dict(model_dict)

self.logger.info( "Loading pretrained model Done...")

# train

self.logger.info( "training...")

self.fitted = True

forstep inrange(self.n_epochs):

self.logger.info( "Epoch%d:", step)

self.logger.info( "training...")

self.train_epoch(train_loader)

self.logger.info( "evaluating...")

train_loss, train_score = self.test_epoch(train_loader)

val_loss, val_score = self.test_epoch(valid_loader)

self.logger.info( "train %.6f, valid %.6f"% (train_score, val_score))

evals_result[ "train"].append(train_score)

evals_result[ "valid"].append(val_score)

ifval_score> best_score:

best_score = val_score

stop_steps = 0

best_epoch = step

best_param = copy.deepcopy(self.GAT_model.state_dict)

else:

stop_steps += 1

ifstop_steps>= self.early_stop:

self.logger.info( "early stop")

break

self.logger.info( "best score: %.6lf @ %d"% (best_score, best_epoch))

self.GAT_model.load_state_dict(best_param)

torch.save(best_param, save_path)

ifself.use_gpu:

torch.cuda.empty_cache

defpredict(self, dataset):

ifnotself.fitted:

raiseValueError( "model is not fitted yet!")

dl_test = dataset.prepare( "test", col_set=[ "feature", "label"], data_key=DataHandlerLP.DK_I)

dl_test.config(fillna_type= "ffill+bfill")

sampler_test = DailyBatchSampler(dl_test)

test_loader = DataLoader(dl_test, sampler=sampler_test, num_workers=self.n_jobs)

self.GAT_model.eval

preds = []

idx = test_loader.dataset.get_index

dts = idx.get_level_values( 0).unique.tolist

codes_idx = idx.get_level_values( 1)

i = 0

fordata intest_loader:

codes = codes_idx[idx.get_loc(dts[i])].tolist

adj = self.get_adj_matrix(dts[i], codes)

data = data.squeeze

feature = data[:, :, 0: -1].to(self.device)

withtorch.no_grad:

pred = self.GAT_model(feature.float, adj).detach.cpu.numpy

preds.append(pred)

i += 1

returnpd.Series(np.concatenate(preds), index=dl_test.get_index)

之后我们在展开一系列装配后(字符串如下),其之前专业训练区在在为2017年1翌年1日至2019年12翌年31日,解析集为2020年1翌年1日至2020年12翌年31日,测试集为2021年1翌年1日至2022年3翌年1日。运用于3090的DirectX展开专业训练,每个epoch大概必需5分钟,共有200epoch,专业训练星期在15个小时左右。

importos

importqlib

importpandas aspd

fromqlib.constant importREG_CN

fromqlib.utils importexists_qlib_data, init_instance_by_config

fromqlib.workflow importR

fromqlib.workflow.record_temp importSignalRecord, PortAnaRecord

fromqlib.utils importflatten_dict

provider_uri = "~/qlib_data/cn_data/"# target_dir

qlib.init(provider_uri=provider_uri, region=REG_CN)

market = "sh000300"

benchmark = "SH000300"

#### 1. 匆忙Dataset

data_handler_config = {

'start_time': "2017-01-01",

'end_time': "2022-03-01",

'fit_start_time': "2017-01-01",

'fit_end_time': "2019-12-31",

'instruments': market,

'infer_processors': [

{ 'class': 'RobustZScoreNorm',

'kwargs': { 'fields_group': 'feature', 'clip_outlier': True}},

{ 'class': 'Fillna', 'kwargs': { 'fields_group': 'feature'}}],

'learn_processors': [{ 'class': 'DropnaLabel'},

{ 'class': 'CSRankNorm', 'kwargs': { 'fields_group': 'label'}}],

'label': [ 'Ref($open, -2) / Ref($open, -1) - 1']}

dataset_config = {

"class": "TSDatasetH",

"module_path": "qlib.data.dataset",

"kwargs": {

"handler": {

"class": "Alpha158",

"module_path": "qlib.contrib.data.handler",

"kwargs": data_handler_config

},

"segments": {

"train": ( "2017-01-01", "2019-12-31"),

"valid": ( "2020-01-01", "2020-12-31"),

"test": ( "2021-01-01", "2022-03-01")

},

"step_len": 40

}

}

dataset = init_instance_by_config(dataset_config)

#### 2. 装配静态

importgat_model

gat_kwargs = {

'd_feat': 158,

'hidden_size': 64,

'num_layers': 2,

'lstm_dropout': 0.7,

'gat_dropout': 0.5,

'n_epochs': 200,

'lr': 1e-4,

'early_stop': 20,

'metric': 'loss',

'loss': 'mse',

'GPU': 0

}

model = gat_model.GATs(**gat_kwargs)

# 开始专业训练静态

withR.start(experiment_name= "train_model_gat_coc_csi300", resume= True):

R.log_params(**flatten_dict(gat_kwargs))

model.fit(dataset)

R.save_objects(trained_model=model)

其他方法论处理过程之前遇见的关键问题

1、每次专业训练的类似数据结构设计

静态每个可用的Batch类似数据为每个应于截面积上所有沪深300恒生指数的并不相同之处类似数据,借来华泰证券在调查结果《由此可知人工神经网络服务选股与Qlib实践》之前的示意由此可知,我们可以清楚看到每次专业训练每个Batch的类似数据结构设计:

2、外设类似数据的质量关键问题

Qlib外设默认下载的类似数据唯在来得多的缺陷,比如成分股类似数据不非常简单,科创刷字符串就其深交所等关键问题。所以本文实践之前均运用于其他第三方商业类似数据库。把每个股份的后复权的K新线类似数据唯为一个元数据,并以金融集团重新命名这个csv元数据。把所有元数据放在一个元数据夹,运用于qlib之前dump_all的命令就可以将类似数据元数据改以qlib运用于的binPDF:

python qlib/s/dump_bin.py dump_all ---csv_path ~/.qlib/csv_data/my_data ---qlib_dir ~/.qlib/qlib_data/my_data ---include_fields open,close,high,low,volume,factor

方法论结果

基于静态的得出,我们引入qlib外设的Topkdropout方针展开回测。如下由此可知简述,即在最开始的时候根据得出排名顺序,买入得出值最高的TopK个股份,后面每个停牌,把得出最低的N个股份卖出,替换上得出最高的N个股份重新借助于复合。

我们对比了Qlib类似的GAT静态(GAT_baseline)、投身新闻网共现的GAT静态(GAT_news_coccurrence)及沪深300净资产(CSI300),结果如下:

两个静态比起沪深300其所利息统计如下:

后续

本文方法论数据系统性新闻网共现等价作为显性由此可知人关系比有序自视线必要的由此可知人工神经网络服务,在方针充分利用之前能获得更加高的其所利息率。但本文还有未经商议,下一步简化会从一般而言几方面着手:

过渡到多层GAT静态 相反巨大损失变量,过渡到股份在在的先后顺序作为处罚因素 解析集之前,以qIC作为解析量化

其他用户阅读原文,认识到更加多

SmarTag新闻网系统性类似数据

什么药能缓解关节僵硬
辽宁男科医院
咸阳白癜风正规的医院
吉林男科医院哪里好
北京哪家专科医院做人流好
标签:
友情链接: 成都治疗阳痿医院