量化学习平台
文章
市场宽度
背离图
登录
注册
学习贴《一个完整的-深度学习-神经网络pipeline》
策略
作者: 水滴
```python # 风险及免责提示:该策略由聚宽用户在聚宽社区分享,仅供学习交流使用。 # 原文一般包含策略说明,如有疑问请到原文和作者交流讨论。 # 原文网址:https://www.joinquant.com/post/48096 # 标题:学习贴《一个完整的-深度学习-神经网络pipeline》 # 作者:MarioC # 原回测条件:2010-01-01 到 2024-05-30, ¥100000, 每天 from jqdata import * from jqfactor import * import numpy as np import pandas as pd import pickle import pandas as pd import torch import torch.nn as nn from tqdm import tqdm from sklearn.preprocessing import MinMaxScaler # 初始化函数 def initialize(context): # 设定基准 set_benchmark('000985.XSHG') # 用真实价格交易 set_option('use_real_price', True) # 打开防未来函数 set_option("avoid_future_data", True) # 将滑点设置为0 set_slippage(FixedSlippage(0)) # 设置交易成本万分之三,不同滑点影响可在归因分析中查看 set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock') # 过滤order中低于error级别的日志 log.set_level('order', 'error') # 初始化全局变量 g.no_trading_today_signal = False g.stock_num = 3 g.hold_list = [] # 当前持仓的全部股票 g.yesterday_HL_list = [] # 记录持仓中昨日涨停的股票 run_daily(prepare_stock_list, '9:05') # run_weekly(weekly_adjustment, 1, '9:30') run_monthly(weekly_adjustment, 1, '9:30') # 1-1 准备股票池 def prepare_stock_list(context): # 获取已持有列表 g.hold_list = [] for position in list(context.portfolio.positions.values()): stock = position.security g.hold_list.append(stock) # 获取昨日涨停列表 if g.hold_list != []: df = get_price(g.hold_list, end_date=context.previous_date, frequency='daily', fields=['close', 'high_limit'], count=1, panel=False, fill_paused=False) df = df[df['close'] == df['high_limit']] g.yesterday_HL_list = list(df.code) else: g.yesterday_HL_list = [] model_path = r'model_baseline.pt' import io buffer = io.BytesIO(read_file(model_path)) class model(nn.Module): def __init__(self, fc1_size=2000, fc2_size=1000, fc3_size=100, fc1_dropout=0.2, fc2_dropout=0.2, fc3_dropout=0.2, num_of_classes=50): super(model, self).__init__() self.f_model = nn.Sequential( nn.Linear(3296, fc1_size), # 887 nn.BatchNorm1d(fc1_size), nn.ReLU(), nn.Dropout(fc1_dropout), nn.Linear(fc1_size, fc2_size), nn.BatchNorm1d(fc2_size), nn.ReLU(), nn.Dropout(fc2_dropout), nn.Linear(fc2_size, fc3_size), nn.BatchNorm1d(fc3_size), nn.ReLU(), nn.Dropout(fc3_dropout), nn.Linear(fc3_size, 1), ) self.conv_layers1 = nn.Sequential( nn.Conv1d(6, 16, kernel_size=1), nn.BatchNorm1d(16), nn.Dropout(fc3_dropout), nn.ReLU(), nn.MaxPool1d(kernel_size=2), nn.Conv1d(16, 32, kernel_size=1), nn.BatchNorm1d(32), nn.Dropout(fc3_dropout), nn.ReLU(), ) self.conv_2D = nn.Sequential( nn.Conv2d(1, 16, kernel_size=2), nn.BatchNorm2d(16), nn.Dropout(fc3_dropout), nn.ReLU(), nn.MaxPool2d(kernel_size=2), nn.Conv2d(16, 32, kernel_size=2), nn.BatchNorm2d(32), nn.Dropout(fc3_dropout), nn.ReLU(), ) hidden_dim = 32 self.lstm = nn.LSTM(input_size=hidden_dim, hidden_size=hidden_dim, num_layers=4, batch_first=True, # dropout=fc3_dropout, bidirectional=True) hidden_dim = 1 self.l = nn.LSTM(input_size=hidden_dim, hidden_size=hidden_dim, num_layers=4, batch_first=True, # dropout=fc3_dropout, bidirectional=True) for name, module in self.named_modules(): if isinstance(module, nn.Linear): nn.init.kaiming_normal_(module.weight, mode='fan_in', nonlinearity='relu') if isinstance(module, nn.Conv2d): nn.init.kaiming_normal_(module.weight, mode='fan_in', nonlinearity='relu') if isinstance(module, nn.Conv1d): nn.init.kaiming_normal_(module.weight, mode='fan_in', nonlinearity='relu') def forward(self, x): apply = torch.narrow(x, dim=-1, start=0, length=1).squeeze(1) redeem = torch.narrow(x, dim=-1, start=1, length=1).squeeze(1) apply, _ = self.l(apply) redeem, _ = self.l(redeem) apply = torch.reshape(apply, (apply.shape[0], apply.shape[1] * apply.shape[2])) redeem = torch.reshape(redeem, (redeem.shape[0], redeem.shape[1] * redeem.shape[2])) ZFF = torch.narrow(x, dim=-1, start=2, length=1).squeeze(1) HS = torch.narrow(x, dim=-1, start=3, length=1).squeeze(1) ZFF, _ = self.l(ZFF) HS, _ = self.l(HS) ZFF = torch.reshape(ZFF, (ZFF.shape[0], ZFF.shape[1] * ZFF.shape[2])) HS = torch.reshape(HS, (HS.shape[0], HS.shape[1] * HS.shape[2])) xx = x.unsqueeze(1) xx = self.conv_2D(xx) xx = torch.reshape(xx, (xx.shape[0], xx.shape[1] * xx.shape[2] * xx.shape[3])) x = x.transpose(1, 2) x = self.conv_layers1(x) out = x.transpose(1, 2) out2, _ = self.lstm(out) out2 = torch.reshape(out2, (out2.shape[0], out2.shape[1] * out2.shape[2])) IN = torch.cat((xx, out2, apply, redeem, ZFF, HS), dim=1) out = self.f_model(IN) return out model_t1 = model() model_t1.load_state_dict(torch.load(buffer)) model_t1.eval() # 0.54 print('模型加载成功') # 1-2 选股模块 def get_stock_list(context): # 指定日期防止未来数据 yesterday = context.previous_date today = context.current_dt initial_list = get_all_securities('etf', yesterday).index.tolist() tensor_list =[] ID=[] for i in initial_list: df = attribute_history(i, 60, '1d') df = df.dropna() if len(df) == 60: with torch.no_grad(): scaler = MinMaxScaler() normalized_data = scaler.fit_transform(df) normalized_df = pd.DataFrame(normalized_data, columns=df.columns) df_tensor = torch.Tensor(normalized_df.values) reshaped_tensor = df_tensor.unsqueeze(0) output = model_t1(reshaped_tensor) tensor_list.extend(output.cpu().numpy().astype(float)[0]) ID.append(i) data = {'ID': ID, 'score': tensor_list} df = pd.DataFrame(data) print(df) top_N_rows = df.nlargest(g.stock_num , 'score') top_N_IDs = top_N_rows['ID'].tolist() return top_N_IDs # 1-3 整体调整持仓 def weekly_adjustment(context): target_list = get_stock_list(context) # 调仓卖出 for stock in g.hold_list: if (stock not in target_list) and (stock not in g.yesterday_HL_list): log.info("卖出[%s]" % (stock)) position = context.portfolio.positions[stock] close_position(position) else: log.info("已持有[%s]" % (stock)) # 调仓买入 position_count = len(context.portfolio.positions) target_num = len(target_list) if target_num > position_count: print(context.portfolio.cash) value = context.portfolio.cash / (target_num - position_count) for stock in target_list: if context.portfolio.positions[stock].total_amount == 0: if open_position(stock, value): if len(context.portfolio.positions) == target_num: break def order_target_value_(security, value): if value == 0: log.debug("Selling out %s" % (security)) else: log.debug("Order %s to value %f" % (security, value)) return order_target_value(security, value) # 3-2 交易模块-开仓 def open_position(security, value): order = order_target_value_(security, value) if order != None and order.filled > 0: return True return False # 3-3 交易模块-平仓 def close_position(position): security = position.security order = order_target_value_(security, 0) # 可能会因停牌失败 if order != None: if order.status == OrderStatus.held and order.filled == order.amount: return True return False ```
文章分类
关于作者
水滴
注册时间: