本程序是關於回測,策略使用上章擇時選股策略,
例程代碼
# N日突破擇時策略
import pandas_datareader.data as web
import pandas as pd
import numpy as np
import datetime
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號
cash_hold = 100000 #初始資金
posit_num = 0 #持股數目
market_total = 0 #持股市值
skip_days = 0 #持股/持幣狀態
#股票數據獲取及處理接口
def GetStockDatApi(stockName=None,stockTimeS=None,stockTimeE=None, N1=15,N2=5):
stockdata = web.DataReader(stockName, "yahoo", stockTimeS, stockTimeE)
stockdata['N1_High'] = stockdata.High.rolling(window=N1).max()#計算最近N1個交易日最高價
# expanding 從最開始到當前的最大值
expan_max = stockdata.Close.expanding().max()
stockdata['N1_High'].fillna(value=expan_max,inplace=True)#目前出現過的最大值填充前N1個nan
stockdata['N2_Low'] = stockdata.Low.rolling(window=N2).min()#計算最近N2個交易日最低價
expan_min = stockdata.Close.expanding().min()
stockdata['N2_Low'].fillna(value=expan_min,inplace=True)#目前出現過的最小值填充前N2個nan
#收盤價超過N1最高價 買入股票持有
buy_index = stockdata[stockdata.Close > stockdata.N1_High.shift(1)].index
stockdata.loc[buy_index,'signal'] = 1
#收盤價超過N2最低價 賣出股票持有
sell_index = stockdata[stockdata.Close < stockdata.N2_Low.shift(1)].index
stockdata.loc[sell_index,'signal'] = 0
stockdata['signal'].fillna(method = 'ffill',inplace = True)
stockdata['signal'] = stockdata.signal.shift(1)
stockdata['signal'].fillna(method = 'bfill',inplace = True)
return stockdata
# N日突破買賣信號區間顯示
skip_days = 0
df_stockload = GetStockDatApi("600410.SS",datetime.datetime(2018, 10, 1), datetime.datetime(2019, 4, 1))
print(df_stockload)
df_stockload.Close.plot()
for kl_index, today in df_stockload.iterrows():
for kl_index, today in df_stockload.iterrows():
# 遍歷signal 買入/賣出執行代碼
# 買入/賣出執行代碼
if today.signal == 1 and skip_days == 0: # 買入
start = df_stockload.index.get_loc(kl_index)
skip_days = -1
posit_num = int(cash_hold / today.Close) # 資金轉化爲股票
cash_hold = 0
elif today.signal == 0 and skip_days == -1: # 賣出 避免未買先賣
end = df_stockload.index.get_loc(kl_index)
skip_days = 0
cash_hold = int(posit_num * today.Close) # 股票轉化爲資金
market_total = 0
if skip_days == -1: # 持股
market_total = int(posit_num * today.Close)
df_stockload.loc[kl_index, 'total'] = market_total
else: # 空倉
df_stockload.loc[kl_index, 'total'] = cash_hold
print(df_stockload.total)
df_stockload.total.plot(grid=True)
plt.show()
"""
#買/賣時間
buy: 2018-11-07 00:00:00
sell: 2018-11-26 00:00:00
buy: 2019-01-17 00:00:00
sell: 2019-01-22 00:00:00
buy: 2019-02-19 00:00:00
"""