策略:
这个模型的逻辑是基于短期和长期移动平均线之间的交叉来产生买卖信号。当短期移动平均线上穿长期移动平均线时,买入信号被产生;当短期移动平均线下穿长期移动平均线时,卖出信号被产生。
这个模型使用的数据是从CSV文件中读取的股票价格数据。然后,计算短期和长期移动平均线,并基于这些移动平均线产生买卖信号。接下来,计算持仓和账户余额,并绘制图表展示。
import pandas as pd
import numpy as np
# 读取历史股票数据
stock_data = pd.read_csv('stock_data.csv')
stock_data['Date'] = pd.to_datetime(stock_data['Date'])
stock_data = stock_data.set_index('Date')
# 计算移动平均线
short_ma = stock_data['Close'].rolling(window=20).mean()
long_ma = stock_data['Close'].rolling(window=50).mean()
# 创建一个新的dataframe来存储信号和持仓
signals = pd.DataFrame(index=stock_data.index)
signals['signal'] = 0.0
signals['short_ma'] = short_ma
signals['long_ma'] = long_ma
# 生成买入信号
signals['signal'][20:] = np.where(signals['short_ma'][20:] > signals['long_ma'][20:], 1.0, 0.0)
# 生成卖出信号
signals['signal'][20:] = np.where(signals['short_ma'][20:] < signals['long_ma'][20:], -1.0, signals['signal'][20:])
# 计算持仓
signals['positions'] = signals['signal'].diff()
# 初始化账户余额和持有股票数
initial_capital = 100000.0
positions = pd.DataFrame(index=signals.index).fillna(0.0)
positions['stock'] = 100 * signals['signal']
# 计算账户余额
portfolio = positions.multiply(stock_data['Close'], axis=0)
pos_diff = positions.diff()
portfolio['holdings'] = (positions.multiply(stock_data['Close'], axis=0)).sum(axis=1)
portfolio['cash'] = initial_capital - (pos_diff.multiply(stock_data['Close'], axis=0)).sum(axis=1).cumsum()
portfolio['total'] = portfolio['cash'] + portfolio['holdings']
# 绘制图表
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111, ylabel='Portfolio value in $')
portfolio['total'].plot(ax=ax1, lw=2.)
ax1.plot(portfolio.loc[signals.positions == 1.0].index,
portfolio.total[signals.positions == 1.0],
'^', markersize=10, color='m')
ax1.plot(portfolio.loc[signals.positions == -1.0].index,
portfolio.total[signals.positions == -1.0],
'v', markersize=10, color='k')
plt.show()