一.股票交易快速入门
股票交易规则
- 开户->炒股平台,券商(交易费)
- 交易版面->K线,盘口,交易价格,数量(100股)
- 交易费->佣金<3%,过户费1元每千股,印花税1%
- A股特点—>±10%(主/中小板) ±20%(创业/科创板)
二.用shift函数计算涨跌幅
def calculate_change_pct(data):
"""
涨跌幅=(当期收盘价-前期收盘价)/前期收盘价
:param data:dataframe,带有收盘价
:return:datafram,带有涨跌幅
"""
data['close_pct']=(data['close']-data['close'].shift(1))/data['close'].shift(1)
return data
import data.stock as st
#获取平安银行的行情数据(日K)
data=st.get_single_stock_Price('000001.XSHE','daily','2020-01-01','2020-02-01')
# print(data)
#计算涨跌幅,验证准确性
#data=st.calculate_change_pct(data)
# print(data)#多了一列close_pct
#获取周K
data=st.transfer_price_freq(data,'W')
print(data)
#计算涨跌幅,验证准确性
data=st.calculate_change_pct(data)
print(data)
三.模拟股票交易:买入,卖出
新建Strategy模块->创建周期选股策略->生成交易信号
import data.stock as st
import numpy as np
def week_period_strategy(code,time_freq,start_date,end_date):
data=st.get_single_stock_Price(code,time_freq,start_date,end_date)
#新建周期字段
data['weekday']=data.index.weekday
#周四买入
data['buy_signal']=np.where((data['weekday']==3),1,0)
#周一卖出
data['sell_signal']=np.where((data['weekday']==0),-1,0)
#整合信号
data['buy_signal']=np.where((data['buy_signal']==1)&(data['buy_signal'].shift(1)==0),0,data['buy_signal'])
data['sell_signal']=np.where((data['sell_signal']==-1)&(data['sell_signal'].shift(1)==-1),0,data['sell_signal'])
data['signal']=data['buy_signal']+data['sell_signal']
return data
if __name__=='__main__':
data=week_period_strategy('000001.XSHE','daily','2020-01-01','2020-03-01')
print(data[['close','weekday','buy_signal','sell_signal','signal']])
四.模拟股票交易:计算持仓收益
总盈亏=(市价-成本价)× 股数 浮动盈亏比=(市价-成本价)/成本价 成本价=买入金额/持有股数 股数=累计买入股数
import datetime
import matplotlib.pyplot as plt
import data.stock as st
import numpy as np
def compose_signal(data):
"""
整合信号
:param data:
:return:
"""
data['buy_signal'] = np.where((data['buy_signal'] == 1) & (data['buy_signal'].shift(1) == 0), 0, data['buy_signal'])
data['sell_signal'] = np.where((data['sell_signal'] == -1) & (data['sell_signal'].shift(1) == -1), 0,
data['sell_signal'])
data['signal'] = data['buy_signal'] + data['sell_signal']
return data
def calculate_prof_pct(data):
"""
计算单次收益率:开仓,平仓(开仓的全部股数)
"""
data = data[data['signal'] != 0] # 筛选
data['profit_pct'] = ((data['close'] - data['close'].shift(1)) / data['close'].shift(1))
data = data[data['signal'] == -1]
return data
def week_period_strategy(code,time_freq,start_date,end_date):
data=st.get_single_stock_Price(code,time_freq,start_date,end_date)
#新建周期字段
data['weekday']=data.index.weekday
#周四买入
data['buy_signal']=np.where((data['weekday']==3),1,0)
#周一卖出
data['sell_signal']=np.where((data['weekday']==0),-1,0)
#整合信号
data=compose_signal(data)
data=calculate_prof_pct(data)
return data
if __name__=='__main__':
df=week_period_strategy('000001.XSHE','daily',None,datetime.date.today())
print(df[['close','signal','profit_pct']])
print(df.describe())
#可视化
df['profit_pct'].plot()
plt.show()
持仓数据的计算->总盈亏,盈亏比,成本价,股数 计算单次收益率->最直接的策略收益评估指标 Matplotlib可视化->观察周期选股的收益表现
五.模拟股票交易:计算累计收益率
计算累计收益率->(1+当天收益率)的累计乘积-1
import datetime
import matplotlib.pyplot as plt
import pandas as pd
import data.stock as st
import numpy as np
def compose_signal(data):
"""
整合信号
:param data:
:return:
"""
data['buy_signal'] = np.where((data['buy_signal'] == 1) & (data['buy_signal'].shift(1) == 0), 0, data['buy_signal'])
data['sell_signal'] = np.where((data['sell_signal'] == -1) & (data['sell_signal'].shift(1) == -1), 0,
data['sell_signal'])
data['signal'] = data['buy_signal'] + data['sell_signal']
return data
def calculate_prof_pct(data):
"""
计算单次收益率:开仓,平仓(开仓的全部股数)
"""
data = data[data['signal'] != 0] # 筛选
data['profit_pct'] = ((data['close'] - data['close'].shift(1)) / data['close'].shift(1))
data = data[data['signal'] == -1]
return data
def calculate_cum_prof(data):
"""
计算累计收益率
:param data:dateframe
:return:
"""
data['cum_profit']=pd.DataFrame(1+data['profit_pct']).cumprod()-1
return data
def week_period_strategy(code,time_freq,start_date,end_date):
data=st.get_single_stock_Price(code,time_freq,start_date,end_date)
#新建周期字段
data['weekday']=data.index.weekday
#周四买入
data['buy_signal']=np.where((data['weekday']==3),1,0)
#周一卖出
data['sell_signal']=np.where((data['weekday']==0),-1,0)
#整合信号
data=compose_signal(data)#整合信号
data=calculate_prof_pct(data)#计算收益
data=calculate_cum_prof(data)#计算累计收益率
return data
if __name__=='__main__':
df=week_period_strategy('000001.XSHE','daily',None,datetime.date.today())
print(df[['close','signal','profit_pct','cum_profit']])
print(df.describe())
#可视化
df['cum_profit'].plot()
plt.show()
六.计算风险指标:最大回撤
最大回撤->在选定周期内任一历史时点往后推,产品净值走到最低点时的收益率回撤幅度,是一个非常重要的风险指标
import datetime
import matplotlib.pyplot as plt
import pandas as pd
import data.stock as st
import numpy as np
def compose_signal(data):
"""
整合信号
:param data:
:return:
"""
data['buy_signal'] = np.where((data['buy_signal'] == 1) & (data['buy_signal'].shift(1) == 0), 0, data['buy_signal'])
data['sell_signal'] = np.where((data['sell_signal'] == -1) & (data['sell_signal'].shift(1) == -1), 0,
data['sell_signal'])
data['signal'] = data['buy_signal'] + data['sell_signal']
return data
def calculate_prof_pct(data):
"""
计算单次收益率:开仓,平仓(开仓的全部股数)
"""
data = data[data['signal'] != 0]
data['profit_pct'] = ((data['close'] - data['close'].shift(1)) / data['close'].shift(1))
data = data[data['signal'] == -1]
return data
def calculate_cum_prof(data):
"""
计算累计收益率
:param data:dateframe
:return:
"""
data['cum_profit']=pd.DataFrame(1+data['profit_pct']).cumprod()-1
return data
def caculate_max_drawdown(data):
"""
计算最大回撤比
:param data:
:return:
"""
window=252
data['roll_max']=data['close'].rolling(window=252,min_periods=1).max()
data['daily_dd']=data['close']/data['roll_max']-1
data['max_dd']=data['daily_dd'].rolling(window,min_periods=1).min()
return data
def week_period_strategy(code,time_freq,start_date,end_date):
data=st.get_single_stock_Price(code,time_freq,start_date,end_date)
data['weekday']=data.index.weekday
data['buy_signal']=np.where((data['weekday']==3),1,0)
data['sell_signal']=np.where((data['weekday']==0),-1,0)
data=compose_signal(data)
data=calculate_prof_pct(data)
data=calculate_cum_prof(data)
data=caculate_max_drawdown(data)
return data
if __name__=='__main__':
df=week_period_strategy('000001.XSHE','daily','2006-01-01','2021-01-01')
df=caculate_max_drawdown(df)
print(df[['close','roll_max','daily_dd','max_dd']])
df[['daily_dd','max_dd']].plot()
plt.show()
七.计算风险收益指标:夏普比率
7.1什么是夏普率 Sharpe Ratio:夏普指数,衡量的是一项投资在对其调整风险后,相对于无风险资产的收益表现。 在1966年,由威廉·F·夏普提出,美国金融经济学者,曾在1990年获得诺贝尔经济学奖. 夏普比率是投资者额外承受的每一单位的风险所获得的额外收益,夏普率越高越好
import datetime
import matplotlib.pyplot as plt
import pandas as pd
import data.stock as st
import numpy as np
def compose_signal(data):
"""
整合信号
:param data:
:return:
"""
data['buy_signal'] = np.where((data['buy_signal'] == 1) & (data['buy_signal'].shift(1) == 0), 0, data['buy_signal'])
data['sell_signal'] = np.where((data['sell_signal'] == -1) & (data['sell_signal'].shift(1) == -1), 0,
data['sell_signal'])
data['signal'] = data['buy_signal'] + data['sell_signal']
return data
def calculate_prof_pct(data):
"""
计算单次收益率:开仓,平仓(开仓的全部股数)
"""
data = data[data['signal'] != 0]
data['profit_pct'] = ((data['close'] - data['close'].shift(1)) / data['close'].shift(1))
data = data[data['signal'] == -1]
return data
def calculate_cum_prof(data):
"""
计算累计收益率
:param data:dateframe
:return:
"""
data['cum_profit']=pd.DataFrame(1+data['profit_pct']).cumprod()-1
return data
def caculate_max_drawdown(data):
"""
计算最大回撤比
:param data:
:return:
"""
window=252
data['roll_max']=data['close'].rolling(window=252,min_periods=1).max()
data['daily_dd']=data['close']/data['roll_max']-1
data['max_dd']=data['daily_dd'].rolling(window,min_periods=1).min()
return data
def calculate_sharpe(data):
"""
计算夏普比率,返回的是年化的夏普
:param data:dateframe,stock
:return:float
"""
daily_return=data['close'].pct_change()
avg_return=daily_return.mean()
sd_return=daily_return.std()
sharpe=avg_return/sd_return
sharpe_year=sharpe*np.sqrt(252)
return sharpe,sharpe_year
def week_period_strategy(code,time_freq,start_date,end_date):
data=st.get_single_stock_Price(code,time_freq,start_date,end_date)
data['weekday']=data.index.weekday
data['buy_signal']=np.where((data['weekday']==3),1,0)
data['sell_signal']=np.where((data['weekday']==0),-1,0)
data=compose_signal(data)
data=calculate_prof_pct(data)
data=calculate_cum_prof(data)
data=caculate_max_drawdown(data)
return data
if __name__=='__main__':
df = st.get_single_stock_Price('000001.XSHE', 'daily', '2006-01-01', '2021-01-01')
sharpe=calculate_sharpe(df)
print(sharpe)
八.比较3只股票的夏普指数
import pandas as pd
import data.stock as st
import strategy.base as stb
import matplotlib.pyplot as plt
codes=['002594.XSHE','300750.XSHE','601012.XSHG']
sharpes=[]
for code in codes:
data=st.get_single_stock_Price(code,'daily','2018-10-01','2021-01-01')
print(data.head())
daily_sharpe,annual_sharpe=stb.calculate_sharpe(data)
sharpes.append([code,annual_sharpe])
print(sharpes)
sharpes=pd.DataFrame(sharpes,columns=['code','sharpe']).set_index('code')
print(sharpes)
sharpes.plot.bar(title='compare Annual Sharpe Ratio')
plt.xticks(rotation=30)
plt.show()
|