“”"
利用python进行股票技术分析–以茅台为例
通过下述策略对利用python进行股票技术分析,可以举一反三,并且能够实现复杂的技术分析策略,同时可以同python的宏观数据、公司基本面数据、舆情等分析结合起来。
策略原理:在股票下跌过程中,当出现上涨锤子线,显示行情先继续下跌后出现大幅反弹,行情可能由此反转;
利用均线识别下跌趋势,以下跌趋势中出现锤子线,同时以RSI出现超卖,三种信号出现作为开仓信号;
采用移动止损方式进行止损,止损条件:当天最低价 < max(均价-观察期内一定倍数的标准差,开仓价-开仓时标准差)
“”"
stock_code='600519' #股票代码
start_time='2018-01-01' #开始时间
end_time='2020-02-15' #截止时间
body_range=0.05 #实体线波动范围
head_length=0.5 #上影线长度
tail_length=2 #下影线长度
ma_period=9 #均线周期
rsi_period=5 #rsi周期
rsi_oversell=30 #超卖
stoplose_std=2 #止损标准差倍数
stock_data=ts.get_k_data(stock_code,start=start_time,end=end_time)
stock_data.sort_index(ascending=True,inplace=True)
stock_data.reset_index(inplace=True)
del stock_data['volume']
del stock_data['code']
stock_data=pd.DataFrame(stock_data)
#计算每天的收益变化
stock_data['perday_change']=stock_data['close'].pct_change()
#计算指标,当天交易的时候只能用上一天的数据:
stock_data['ma']=ta.SMA(np.asarray(stock_data['close']),timeperiod=ma_period)
stock_data['rsi']=ta.RSI(np.asarray(stock_data['close']),timeperiod=rsi_period)
stock_data['std']=stock_data['close'].rolling(ma_period).std()
stock_data['y_ma']=stock_data['ma'].shift(1)
stock_data['y_rsi']=stock_data['rsi'].shift(1)
stock_data['y_std']=stock_data['std'].shift(1)
#计算锤子线形态并判断是否为锤子线:实体线变化范围在一定范围内,下影线要是实体线的一定倍数,上影线要小于下影线一定倍数,当天交易的时候只能用上一天的数据:
stock_data['st_body']=abs(stock_data['open']-stock_data['close'])
stock_data['s_head']=stock_data['high']-stock_data[['open','close']].max(axis=1)
stock_data['x_tail']=stock_data[['open','close']].min(axis=1)-stock_data['low']
stock_data['r_body']=np.where(stock_data['st_body']/stock_data['open']<body_range,True,False)
stock_data['r_head']=np.where(stock_data['s_head']==0,False,stock_data['s_head']/stock_data['x_tail']<head_length)
stock_data['r_tail']=np.where(stock_data['st_body']==0,True,stock_data['x_tail']/stock_data['st_body']>tail_length)
stock_data['chuizi']=stock_data[['r_body','r_head','r_tail']].all(axis=1)
stock_data['y_chuizi']=stock_data['chuizi'].shift(1)
对ts获取到的数据转换成candlestick_ohlc()方法可读取的格式
data_list = []
data_ma=[]
for dates,row in stock_data.iterrows():
# 将时间转换为数字
date_time = datetime.datetime.strptime(row['date'],'%Y-%m-%d')
t = date2num(date_time)
open,high,low, close= row[['open','high','low','close']]
datas = (t,open,high,low,close)
data_list.append(datas)
data_ma.append(t)
fig, ax = plt.subplots(figsize=(20, 10))
fig.subplots_adjust(bottom=0.2)#子图所在区域的边界
ax.xaxis_date()# 设置X轴刻度为日期时间
plt.xticks()
plt.yticks()
plt.title("股价走势K线图")
plt.xlabel("时间")
plt.ylabel("股价(元)")
mpf.candlestick_ohlc(ax,data_list,width=0.5,colorup='r',colordown='green')
plt.plot(data_ma,stock_data['y_ma'],color='b')
plt.legend()
plt.grid()
fig, ax = plt.subplots(figsize=(20, 10))
fig.subplots_adjust(bottom=0.2)#子图所在区域的边界
ax.xaxis_date()# 设置X轴刻度为日期时间
plt.plot(data_ma,stock_data['y_rsi'],color='r')
plt.title('RSI指标')
plt.legend()
plt.grid()
flag=0 #flag表示持仓记录,0代表空仓,1代表持仓
for i in range(2*ma_period,len(stock_data)):
if flag==0:
#满足三个条件才开仓,并计算收益
if stock_data.loc[i-ma_period,'y_ma']>stock_data.loc[i,'y_ma'] and stock_data.loc[i,'y_rsi']<rsi_oversell and stock_data.loc[i,'y_chuizi']:
flag=1
long_openprice=stock_data.loc[i,'open']
long_gap=stock_data.loc[i,'y_std']
stock_data.loc[i,'return']=stock_data.loc[i,'close']/stock_data.loc[i,'open']-1
stock_data.loc[i,'mark']=100
if flag==1:
#设置止损价格,达到止损条件平仓
long_stoplose=max(stock_data.loc[i,'y_ma']-stoplose_std*stock_data.loc[i,'y_std'],long_openprice-long_gap)
if stock_data.loc[i,'low']<long_stoplose:
flag=0
stock_data.loc[i,'return']=min(stock_data.loc[i,'open'],long_stoplose)/stock_data.loc[i-1,'close']-1
stock_data.loc[i,'mark']=-100
else:
#持仓过程中计算收益
stock_data.loc[i,'return']=stock_data.loc[i,'close']/stock_data.loc[i-1,'close']-1
stock_data.loc[i,'mark']=200
stock_data['return'].fillna(0,inplace=True)
stock_data['strategy_return']=(stock_data['return']+1).cumprod()
stock_data['stock_return']=(stock_data['perday_change']+1).cumprod()
fig2 = plt.figure(figsize=(20,10))
ax2 = fig2.add_subplot(1,1,1)
ax2.plot(stock_data.stock_return,color='b')
ax2.plot(stock_data.strategy_return,color='r')
plt.title(stock_code)
plt.legend()
plt.grid()