回测框架之计算收益模块
生活随笔
收集整理的這篇文章主要介紹了
回测框架之计算收益模块
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
# =====計算實際資金曲線(實際方法)
df = df[['交易日期', '股票代碼', '開盤價', '最高價', '最低價', '收盤價', '漲跌幅', 'pos']]
df.reset_index(inplace=True, drop=True)# ===設定參數
initial_money = 1000000 # 初始資金,默認為1000000元
slippage = 0.01 # 滑點,默認為0.01元
c_rate = 5.0 / 10000 # 手續費,commission fees,默認為萬分之5
t_rate = 1.0 / 1000 # 印花稅,tax,默認為千分之1# ===第一天的情況
df.at[0, 'hold_num'] = 0 # 持有股票數量,此處也可用loc,但是定位單個元素at效率更高。
df.at[0, 'stock_value'] = 0 # 持倉股票市值
df.at[0, 'actual_pos'] = 0 # 每日的實際倉位
df.at[0, 'cash'] = initial_money # 持有現金現金
df.at[0, 'equity'] = initial_money # 總資產 = 持倉股票市值 + 現金
# print df[['交易日期', '開盤價', 'pos', 'hold_num', 'stock_value', 'actual_pos', 'cash', 'equity']]# ===第一天之后每天的情況
# 從第二行開始,逐行遍歷,逐行計算
for i in range(1, df.shape[0]):# 前一天持有的股票的數量hold_num = df.at[i - 1, 'hold_num']# 判斷當天是否除權,若發生除權,需要調整hold_num# 若當天通過收盤價計算出的漲跌幅,和當天實際漲跌幅不同,說明當天發生了除權if abs((df.at[i, '收盤價'] / df.at[i-1, '收盤價'] - 1) - df.at[i, '漲跌幅']) > 0.001:stock_value = df.at[i - 1, 'stock_value']# 交易所會公布除權之后的價格last_price = df.at[i, '收盤價'] / (df.at[i, '漲跌幅'] + 1)hold_num = stock_value / last_pricehold_num = int(hold_num)# if i > 1030:# print stock_value, last_price, hold_num# print df.iloc[1034:][['交易日期', '收盤價', '漲跌幅', 'pos', 'hold_num', 'cash', 'stock_value']]# 判斷是否需要調整倉位:拿今天的倉位pos,和昨天的倉位pos進行比較,看是否相同# 需要調整倉位if df.at[i, 'pos'] != df.at[i - 1, 'pos']:# 對于需要調整到的倉位,需要買入多少股票# 昨天的總資產 * 今天的倉位 / 今天的收盤價,得到需要持有的股票數theory_num = df.at[i - 1, 'equity'] * df.at[i, 'pos'] / df.at[i, '開盤價']# 對需要持有的股票數取整theory_num = int(theory_num) # 向下取整數,向上取整會出現錢不夠的情況# 將theory_num和昨天持有股票相比較,判斷加倉還是減倉# 加倉if theory_num >= hold_num:# 計算實際需要買入的股票數量buy_num = theory_num - hold_num# 買入股票只能整百,對buy_num進行向下取整百buy_num = int(buy_num / 100) * 100# 計算買入股票花去的現金buy_cash = buy_num * (df.at[i, '開盤價'] + slippage)# 計算買入股票花去的手續費,并保留2位小數commission = round(buy_cash * c_rate, 2)# 不足5元按5元收if commission < 5 and commission != 0:commission = 5df.at[i, '手續費'] = commission# 計算當天收盤時持有股票的數量和現金df.at[i, 'hold_num'] = hold_num + buy_num # 持有股票,昨天持有的股票,加上今天買入的股票df.at[i, 'cash'] = df.at[i - 1, 'cash'] - buy_cash - commission # 剩余現金# print df[['交易日期', '開盤價', 'pos', 'hold_num', 'cash', '手續費']]# exit()# 減倉else:# 計算賣出股票數量,賣出股票可以不是整數,不需要取整百。sell_num = hold_num - theory_num# 計算賣出股票得到的現金sell_cash = sell_num * (df.at[i, '開盤價'] - slippage)# 計算手續費,不足5元按5元收,并保留2位小數commission = round(max(sell_cash * c_rate, 5), 2)df.at[i, '手續費'] = commission# 計算印花稅,保留2位小數。歷史上有段時間,買入也會收取印花稅tax = round(sell_cash * t_rate, 2)df.at[i, '印花稅'] = tax# 計算當天收盤時持有股票的數量和現金df.at[i, 'hold_num'] = hold_num - sell_num # 持有股票df.at[i, 'cash'] = df.at[i - 1, 'cash'] + sell_cash - commission - tax # 剩余現金# print df.iloc[50:100][['交易日期', '開盤價', 'pos', 'hold_num', 'cash', '手續費', '印花稅']]# 不需要調倉else:# 計算當天收盤時持有股票的數量和現金df.at[i, 'hold_num'] = hold_num # 持有股票df.at[i, 'cash'] = df.at[i - 1, 'cash'] # 剩余現金。此處的cash可以乘以余額寶的收益率。# print df[['交易日期', 'pos', 'hold_num', 'cash']]# 以上的計算得到每天的hold_num和cash# 計算當天收盤時的各種資產數據df.at[i, 'stock_value'] = df.at[i, 'hold_num'] * df.at[i, '收盤價'] # 股票市值df.at[i, 'equity'] = df.at[i, 'cash'] + df.at[i, 'stock_value'] # 總資產df.at[i, 'actual_pos'] = df.at[i, 'stock_value'] / df.at[i, 'equity'] # 實際倉位
總結
以上是生活随笔為你收集整理的回测框架之计算收益模块的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个算法工程师在技术方面的反思!
- 下一篇: 出租车计价器的测试用例