(18-2)基于深度强化学习的股票交易模型:EDA

1.3  EDA

EDA(探索性数据分析,Exploratory Data Analysis)是数据处理的一部分,通过统计方法和可视化技术来探索数据集,发现数据中的模式、关系、异常值和分布情况。

(1)加载Salesforce股票历史数据,将日期列转换为时间格式并设置为索引,然后显示数据的日期范围和前几行数据。

import warnings
warnings.filterwarnings('ignore')  # 忽略警告信息

data = pd.read_csv('input/salesforce-stock-date-latest-and-updated/Salesforce_stock_history.csv')  # 读取Salesforce股票历史数据
data['Date'] = pd.to_datetime(data['Date'])  # 将日期列转换为日期时间格式
data = data.set_index('Date')  # 将日期列设置为索引
print(data.index.min(), data.index.max())  # 打印数据的最小日期和最大日期
data.head()  # 显示数据的前几行

执行后会输出:

2004-06-23 00:00:00 2021-11-18 00:00:00
Open	High	Low	Close	Volume	Dividends	Stock Splits
Date							
2004-06-23	3.7500	4.3250	3.6875	4.30	43574400	0	0.0
2004-06-24	4.3875	4.4225	4.1250	4.19	8887200	0	0.0
2004-06-25	4.1275	4.1875	3.9475	3.95	6710000	0	0.0
2004-06-28	4.0000	4.0525	3.8600	4.00	2270800	0	0.0
2004-06-29	4.0000	4.1750	3.9575	4.10	2112000	0	0.0

(2)根据指定的日期date_split将股票数据集分为训练集和测试集,并计算训练集和测试集的样本数量。

date_split = '2013-01-01'
train = data[:date_split]  # 将数据集在指定日期之前的数据分为训练集
test = data[date_split:]  # 将数据集在指定日期及之后的数据分为测试集
len(train), len(test)  # 计算训练集和测试集的样本数量

执行后会输出:

(2147, 2238)

(3)定义函数 plot_train_test,用于可视化训练集和测试集的数据。函数使用Candlestick图(蜡烛图)来展示股票价格数据,并在图中标记出训练集和测试集的分界线。

def plot_train_test(train, test, date_split):
    
    data = [
        Candlestick(x=train.index, open=train['Open'], high=train['High'], low=train['Low'], close=train['Close'], name='train'),
        Candlestick(x=test.index, open=test['Open'], high=test['High'], low=test['Low'], close=test['Close'], name='test')
    ]
    layout = {
         'shapes': [
             {'x0': date_split, 'x1': date_split, 'y0': 0, 'y1': 1, 'xref': 'x', 'yref': 'paper', 'line': {'color': 'rgb(0,0,0)', 'width': 1}}
         ],
        'annotations': [
            {'x': date_split, 'y': 1.0, 'xref': 'x', 'yref': 'paper', 'showarrow': False, 'xanchor': 'left', 'text': '测试数据'},
            {'x': date_split, 'y': 1.0, 'xref': 'x', 'yref': 'paper', 'showarrow': False, 'xanchor': 'right', 'text': '训练数据 '}
        ]
    }
    figure = Figure(data=data, layout=layout)
    iplot(figure)  # 绘制图形

(4)调用 plot_train_test(train, test, date_split) 函数绘制蜡烛图,帮助我们直观地比较训练集和测试集的数据,了解模型的训练和测试时间段。

plot_train_test(train, test, date_split)

对上述代码的具体说明如下所示:

  1. 训练集数据 (train):使用蜡烛图显示训练集中的股票开盘价、最高价、最低价和收盘价。
  2. 测试集数据 (test):使用蜡烛图显示测试集中的股票开盘价、最高价、最低价和收盘价。
  3. 添加分界线和注释:在图中添加一条垂直的分界线,标记出训练集和测试集的分界日期(date_split)。在分界线左右添加注释,分别标记“训练数据”和“测试数据”。
  4. 绘制图形:使用Plotly库中的iplot函数在Notebook中显示生成的图形,如图1-8所示。绿色表示收盘价相比前一天上涨,红色表示收盘价相比前一天下跌。

图1-8  绘制的蜡烛图

(5)定义一个名为 Environment1 的类,模拟一个简单的股票交易环境。类Environment1允许在给定的历史数据上执行买入、卖出或持有操作,并计算相应的奖励。环境会根据操作更新状态,并返回当前状态、奖励和是否结束的标志。

class Environment1:
    
    def __init__(self, data, history_t=90):
        self.data = data
        self.history_t = history_t
        self.reset()
        
    def reset(self):
        self.t = 0
        self.done = False
        self.profits = 0
        self.positions = []
        self.position_value = 0
        self.history = [0 for _ in range(self.history_t)]
        return [self.position_value] + self.history # 观测值
    
    def step(self, act):
        reward = 0
        
        # act = 0: 持有, 1: 买入, 2: 卖出
        if act == 1:  # 买入
            self.positions.append(self.data.iloc[self.t, :]['Close'])
        elif act == 2:  # 卖出
            if len(self.positions) == 0:
                reward = -1
            else:
                profits = 0
                for p in self.positions:
                    profits += (self.data.iloc[self.t, :]['Close'] - p)
                reward += profits
                self.profits += profits
                self.positions = []
        
        # 设置下一个时间
        self.t += 1
        self.position_value = 0
        for p in self.positions:
            self.position_value += (self.data.iloc[self.t, :]['Close'] - p)
        self.history.pop(0)
        self.history.append(self.data.iloc[self.t, :]['Close'] - self.data.iloc[(self.t-1), :]['Close'])
        
        # 奖励裁剪
        if reward > 0:
            reward = 1
        elif reward < 0:
            reward = -1
        
        return [self.position_value] + self.history, reward, self.done # 观测值, 奖励, 是否结束

(6)如下代码通过创建 Environment1 类的实例并对其进行初始化和测试,模拟股票交易环境的初始状态。随后,代码随机选择了三个操作(持有、买入、卖出),并输出了每个操作后的环境状态、奖励以及是否交易结束的标志。

env = Environment1(train)  # 创建环境实例
print(env.reset())  # 重置环境并打印初始状态

for _ in range(3):
    pact = np.random.randint(3)  # 生成一个随机操作(0: 持有, 1: 买入, 2: 卖出)
    print(env.step(pact))  # 执行操作并打印结果

执行后会输出:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
([-0.1100001335144043, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.1100001335144043], 0, False)
([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.1100001335144043, -0.24000000953674316], -1, False)
([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.1100001335144043, -0.24000000953674316, 0.04999995231628418], -1, False)

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

感谢鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值