股票連續投資歷史收益計算
阿新 • • 發佈:2018-12-04
假設每月有幾千塊錢投資某股票,在每月第一個星期五按收盤價買入,購買一定時間後全部賣出,計算收益率
由於有除權這種事件存在,所以不能簡單的按照歷史價格進行計算。
後復權:以時間起點往後復權,分紅送股向上平移,用於計算曆史收益,時間起點是股票發行日
前復權:以時間終點往前復權,分紅送股向下平移,用於觀察漲跌行情?
計算曆史上某一段時間的收益,演算法如下。
股票買入價:獲取不復權的股價資料,尋找當日的股價A。
股票賣出價:獲取後復權的股價資料,尋找買入日和賣出日的股價X和Y,做比例縮放即可。A/X*Y,這樣就可以將中間的除權事件包含在內了。
python環境anaconda 5.1.0
股票介面使用tushare
完整計算器程式碼如下:
# 測試環境 anaconda 5.1.0
# tushare 安裝 pip install tushare
import sys
import datetime
import tushare as ts
def get_stock_price(pricedata, buydate):
# pricedate 股價資料
# buydate 買入日期,字串 例 2012-01-01
# 返回收盤價 如果停牌返回0
for index, row in pricedata.iterrows():
if row.date == buydate:
return row.close
return 0
def get_max_buy_count(price, fund):
count = 100
while count * price < fund:
count += 100
return count - 100
def get_last_trade_date(pricedata, selldate_exp):
# pricedate 股價資料
# selldate_exp 期望的賣出日期,字串 例 2012-01-01
# 返回距離期望最近的交易日期
dsell = datetime.datetime.strptime(selldate_exp,'%Y-%m-%d')
dret = 0
for index, row in pricedata.iterrows():
drow = datetime.datetime.strptime(row.date,'%Y-%m-%d')
if drow <= dsell:
dret = drow
else:
break
if dret == 0:
return 0
return dret.strftime("%Y-%m-%d")
def calc_stock(price, price_hfq, buydate, selldate, fund):
# price 股價資料 不復權
# price_hfq 股價資料 後復權
# buydate 買入日期
# selldate 賣出日期
# fund 購買資金
# 返回 買入單價,買入單價後復權,賣出單價,購買數量
buyprice = get_stock_price(price, buydate)
buyprice_hfq = get_stock_price(price_hfq, buydate)
sellprice_hfq = get_stock_price(price_hfq, selldate)
if buyprice == 0 or buyprice_hfq == 0 or sellprice_hfq == 0:
return 0,0,0,0
buycount = get_max_buy_count(buyprice, fund)
sellprice = buyprice / buyprice_hfq * sellprice_hfq
return buyprice, buyprice_hfq, sellprice, buycount
def main(stock, start, end, fundpermonth):
print('股票程式碼: ', stock)
print('開始日期: ', start)
print('賣出日期: ', end)
print('每月資金: ', fundpermonth)
# 獲取不復權股價資料
print('正在獲取不復權股價資料')
data_bfq = ts.get_k_data(stock,start,end,autype='none')
print('正在獲取後復權股價資料')
data_hfq = ts.get_k_data(stock,start,end,autype='hfq')
# 獲取最後賣出日
selldate = get_last_trade_date(data_bfq, end)
if selldate == 0:
print('賣出日期不存在')
sys.exit(1)
print('正在計算連續投資收益')
# 遍歷交易日 (每個月第一個星期五)
dstart = datetime.datetime.strptime(start,'%Y-%m-%d')
dend = datetime.datetime.strptime(end,'%Y-%m-%d')
dtmp = dstart
oneday = datetime.timedelta(days=1)
month_buy = 0
month_fund = 0
total_buy = 0
total_sell = 0
total_stock = 0
fund_pool = 0
last_price_hfq = 0
while dtmp <= dend:
if dtmp.month != month_fund:
# 新的月份,資金池累加
fund_pool += int(fundpermonth)
month_fund = dtmp.month
if dtmp.month != month_buy:
if dtmp.weekday() == 4: #是個星期五
# 檢查是否可以購買
print('=================================')
buydate = dtmp.strftime("%Y-%m-%d")
price = get_stock_price(data_bfq, buydate)
if price > 0:
# 可以購買 買入
buyprice,buyprice_hfq,sellprice,buycount = calc_stock(data_bfq, data_hfq, buydate, selldate, fund_pool)
if last_price_hfq > 0:
gain = (buyprice_hfq - last_price_hfq) / last_price_hfq * 100
print('同比增長: ', round(gain, 2), '%')
print('買入日期: ', buydate)
print('買入單價: ', round(buyprice, 2))
print('賣出單價: ', round(sellprice, 2))
print('買入數量: ', buycount)
print('當月投資: ', round(buyprice * buycount, 2))
total_buy += buyprice * buycount
total_stock += buycount
total_sell += sellprice * buycount
fund_pool -= buyprice * buycount
print('剩餘資金: ', round(fund_pool, 2))
print('當期總投資: ', round(total_buy, 2))
print('當期總持股: ', total_stock)
print('當期總收入: ', round(total_sell, 2))
print('當期總收益: ', round((total_sell - total_buy) / total_buy * 100, 2), '%')
last_price_hfq = buyprice_hfq
month_buy = dtmp.month
else:
# 停牌 無法交易
print('買入日期: ', buydate)
print('停牌中,無法交易')
dtmp += oneday
rate = round((total_sell - total_buy) * 100 / total_buy, 2)
print('=================================')
print('總投資額: ', round(total_buy, 2))
print('總持有量: ', total_stock)
print('賣出金額: ', round(total_sell, 2))
print('總收益率: ', rate, '%')
# 命令列引數
# 股票程式碼 買入起始日期 賣出日期 每月資金
if __name__ == "__main__":
if len(sys.argv) < 5:
print('Usage: calc [stockcode] [startdate] [selldate] [fundpermonth]')
print('Exam: calc 000002 2012-01-01 2016-01-01 8000')
sys.exit()
main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
測試輸出結果
(base) D:\stock>python main.py 000002 2012-01-01 2012-12-31 8000
股票程式碼: 000002
開始日期: 2012-01-01
賣出日期: 2012-12-31
每月資金: 8000
正在獲取不復權股價資料
正在獲取後復權股價資料
正在計算連續投資收益
=================================
買入日期: 2012-01-06
買入單價: 7.16
賣出單價: 10.27
買入數量: 1100
當月投資: 7876.0
剩餘資金: 124.0
當期總投資: 7876.0
當期總持股: 1100
當期總收入: 11292.3
當期總收益: 43.38 %
=================================
同比增長: 8.8 %
買入日期: 2012-02-03
買入單價: 7.79
賣出單價: 10.27
買入數量: 1000
當月投資: 7790.0
剩餘資金: 334.0
當期總投資: 15666.0
當期總持股: 2100
當期總收入: 21558.04
當期總收益: 37.61 %
=================================
同比增長: 10.78 %
買入日期: 2012-03-02
買入單價: 8.63
賣出單價: 10.27
買入數量: 900
當月投資: 7767.0
剩餘資金: 567.0
當期總投資: 23433.0
當期總持股: 3000
當期總收入: 30797.2
當期總收益: 31.43 %
=================================
同比增長: -2.9 %
買入日期: 2012-04-06
買入單價: 8.38
賣出單價: 10.27
買入數量: 1000
當月投資: 8380.0
剩餘資金: 187.0
當期總投資: 31813.0
當期總持股: 4000
當期總收入: 41062.93
當期總收益: 29.08 %
=================================
同比增長: 10.02 %
買入日期: 2012-05-04
買入單價: 9.22
賣出單價: 10.27
買入數量: 800
當月投資: 7376.0
剩餘資金: 811.0
當期總投資: 39189.0
當期總持股: 4800
當期總收入: 49275.52
當期總收益: 25.74 %
=================================
同比增長: -0.76 %
買入日期: 2012-06-01
買入單價: 9.15
賣出單價: 10.27
買入數量: 900
當月投資: 8235.0
剩餘資金: 576.0
當期總投資: 47424.0
當期總持股: 5700
當期總收入: 58514.68
當期總收益: 23.39 %
=================================
同比增長: 6.98 %
買入日期: 2012-07-06
買入單價: 9.65
賣出單價: 10.12
買入數量: 800
當月投資: 7720.0
剩餘資金: 856.0
當期總投資: 55144.0
當期總持股: 6500
當期總收入: 66610.68
當期總收益: 20.79 %
=================================
同比增長: -9.84 %
買入日期: 2012-08-03
買入單價: 8.7
賣出單價: 10.12
買入數量: 1000
當月投資: 8700.0
剩餘資金: 156.0
當期總投資: 63844.0
當期總持股: 7500
當期總收入: 76730.68
當期總收益: 20.18 %
=================================
同比增長: -1.15 %
買入日期: 2012-09-07
買入單價: 8.6
賣出單價: 10.12
買入數量: 900
當月投資: 7740.0
剩餘資金: 416.0
當期總投資: 71584.0
當期總持股: 8400
當期總收入: 85838.68
當期總收益: 19.91 %
=================================
買入日期: 2012-10-05
停牌中,無法交易
=================================
同比增長: -4.19 %
買入日期: 2012-10-12
買入單價: 8.24
賣出單價: 10.12
買入數量: 1000
當月投資: 8240.0
剩餘資金: 176.0
當期總投資: 79824.0
當期總持股: 9400
當期總收入: 95958.68
當期總收益: 20.21 %
=================================
同比增長: 4.98 %
買入日期: 2012-11-02
買入單價: 8.65
賣出單價: 10.12
買入數量: 900
當月投資: 7785.0
剩餘資金: 391.0
當期總投資: 87609.0
當期總持股: 10300
當期總收入: 105066.68
當期總收益: 19.93 %
=================================
同比增長: 6.36 %
買入日期: 2012-12-07
買入單價: 9.2
賣出單價: 10.12
買入數量: 900
當月投資: 8280.0
剩餘資金: 111.0
當期總投資: 95889.0
當期總持股: 11200
當期總收入: 114174.69
當期總收益: 19.07 %
=================================
總投資額: 95889.0
總持有量: 11200
賣出金額: 114174.69
總收益率: 19.07 %
參考:http://tushare.org/
參考:https://xueqiu.com/3488649239/62074848
由於有除權這種事件存在,所以不能簡單的按照歷史價格進行計算。
後復權:以時間起點往後復權,分紅送股向上平移,用於計算曆史收益,時間起點是股票發行日
前復權:以時間終點往前復權,分紅送股向下平移,用於觀察漲跌行情?
計算曆史上某一段時間的收益,演算法如下。
股票買入價:獲取不復權的股價資料,尋找當日的股價A。
股票賣出價:獲取後復權的股價資料,尋找買入日和賣出日的股價X和Y,做比例縮放即可。A/X*Y,這樣就可以將中間的除權事件包含在內了。
python環境anaconda 5.1.0
股票介面使用tushare
完整計算器程式碼如下:
# 測試環境 anaconda 5.1.0
# tushare 安裝 pip install tushare
import sys
import datetime
import tushare as ts
def get_stock_price(pricedata, buydate):
# pricedate 股價資料
# buydate 買入日期,字串 例 2012-01-01
# 返回收盤價 如果停牌返回0
for index, row in pricedata.iterrows():
if row.date == buydate:
return row.close
return 0
def get_max_buy_count(price, fund):
count = 100
while count * price < fund:
count += 100
return count - 100
def get_last_trade_date(pricedata, selldate_exp):
# pricedate 股價資料
# selldate_exp 期望的賣出日期,字串 例 2012-01-01
# 返回距離期望最近的交易日期
dsell = datetime.datetime.strptime(selldate_exp,'%Y-%m-%d')
dret = 0
for index, row in pricedata.iterrows():
drow = datetime.datetime.strptime(row.date,'%Y-%m-%d')
if drow <= dsell:
dret = drow
else:
break
if dret == 0:
return 0
return dret.strftime("%Y-%m-%d")
def calc_stock(price, price_hfq, buydate, selldate, fund):
# price 股價資料 不復權
# price_hfq 股價資料 後復權
# buydate 買入日期
# selldate 賣出日期
# fund 購買資金
# 返回 買入單價,買入單價後復權,賣出單價,購買數量
buyprice = get_stock_price(price, buydate)
buyprice_hfq = get_stock_price(price_hfq, buydate)
sellprice_hfq = get_stock_price(price_hfq, selldate)
if buyprice == 0 or buyprice_hfq == 0 or sellprice_hfq == 0:
return 0,0,0,0
buycount = get_max_buy_count(buyprice, fund)
sellprice = buyprice / buyprice_hfq * sellprice_hfq
return buyprice, buyprice_hfq, sellprice, buycount
def main(stock, start, end, fundpermonth):
print('股票程式碼: ', stock)
print('開始日期: ', start)
print('賣出日期: ', end)
print('每月資金: ', fundpermonth)
# 獲取不復權股價資料
print('正在獲取不復權股價資料')
data_bfq = ts.get_k_data(stock,start,end,autype='none')
print('正在獲取後復權股價資料')
data_hfq = ts.get_k_data(stock,start,end,autype='hfq')
# 獲取最後賣出日
selldate = get_last_trade_date(data_bfq, end)
if selldate == 0:
print('賣出日期不存在')
sys.exit(1)
print('正在計算連續投資收益')
# 遍歷交易日 (每個月第一個星期五)
dstart = datetime.datetime.strptime(start,'%Y-%m-%d')
dend = datetime.datetime.strptime(end,'%Y-%m-%d')
dtmp = dstart
oneday = datetime.timedelta(days=1)
month_buy = 0
month_fund = 0
total_buy = 0
total_sell = 0
total_stock = 0
fund_pool = 0
last_price_hfq = 0
while dtmp <= dend:
if dtmp.month != month_fund:
# 新的月份,資金池累加
fund_pool += int(fundpermonth)
month_fund = dtmp.month
if dtmp.month != month_buy:
if dtmp.weekday() == 4: #是個星期五
# 檢查是否可以購買
print('=================================')
buydate = dtmp.strftime("%Y-%m-%d")
price = get_stock_price(data_bfq, buydate)
if price > 0:
# 可以購買 買入
buyprice,buyprice_hfq,sellprice,buycount = calc_stock(data_bfq, data_hfq, buydate, selldate, fund_pool)
if last_price_hfq > 0:
gain = (buyprice_hfq - last_price_hfq) / last_price_hfq * 100
print('同比增長: ', round(gain, 2), '%')
print('買入日期: ', buydate)
print('買入單價: ', round(buyprice, 2))
print('賣出單價: ', round(sellprice, 2))
print('買入數量: ', buycount)
print('當月投資: ', round(buyprice * buycount, 2))
total_buy += buyprice * buycount
total_stock += buycount
total_sell += sellprice * buycount
fund_pool -= buyprice * buycount
print('剩餘資金: ', round(fund_pool, 2))
print('當期總投資: ', round(total_buy, 2))
print('當期總持股: ', total_stock)
print('當期總收入: ', round(total_sell, 2))
print('當期總收益: ', round((total_sell - total_buy) / total_buy * 100, 2), '%')
last_price_hfq = buyprice_hfq
month_buy = dtmp.month
else:
# 停牌 無法交易
print('買入日期: ', buydate)
print('停牌中,無法交易')
dtmp += oneday
rate = round((total_sell - total_buy) * 100 / total_buy, 2)
print('=================================')
print('總投資額: ', round(total_buy, 2))
print('總持有量: ', total_stock)
print('賣出金額: ', round(total_sell, 2))
print('總收益率: ', rate, '%')
# 命令列引數
# 股票程式碼 買入起始日期 賣出日期 每月資金
if __name__ == "__main__":
if len(sys.argv) < 5:
print('Usage: calc [stockcode] [startdate] [selldate] [fundpermonth]')
print('Exam: calc 000002 2012-01-01 2016-01-01 8000')
sys.exit()
main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
測試輸出結果
(base) D:\stock>python main.py 000002 2012-01-01 2012-12-31 8000
股票程式碼: 000002
開始日期: 2012-01-01
賣出日期: 2012-12-31
每月資金: 8000
正在獲取不復權股價資料
正在獲取後復權股價資料
正在計算連續投資收益
=================================
買入日期: 2012-01-06
買入單價: 7.16
賣出單價: 10.27
買入數量: 1100
當月投資: 7876.0
剩餘資金: 124.0
當期總投資: 7876.0
當期總持股: 1100
當期總收入: 11292.3
當期總收益: 43.38 %
=================================
同比增長: 8.8 %
買入日期: 2012-02-03
買入單價: 7.79
賣出單價: 10.27
買入數量: 1000
當月投資: 7790.0
剩餘資金: 334.0
當期總投資: 15666.0
當期總持股: 2100
當期總收入: 21558.04
當期總收益: 37.61 %
=================================
同比增長: 10.78 %
買入日期: 2012-03-02
買入單價: 8.63
賣出單價: 10.27
買入數量: 900
當月投資: 7767.0
剩餘資金: 567.0
當期總投資: 23433.0
當期總持股: 3000
當期總收入: 30797.2
當期總收益: 31.43 %
=================================
同比增長: -2.9 %
買入日期: 2012-04-06
買入單價: 8.38
賣出單價: 10.27
買入數量: 1000
當月投資: 8380.0
剩餘資金: 187.0
當期總投資: 31813.0
當期總持股: 4000
當期總收入: 41062.93
當期總收益: 29.08 %
=================================
同比增長: 10.02 %
買入日期: 2012-05-04
買入單價: 9.22
賣出單價: 10.27
買入數量: 800
當月投資: 7376.0
剩餘資金: 811.0
當期總投資: 39189.0
當期總持股: 4800
當期總收入: 49275.52
當期總收益: 25.74 %
=================================
同比增長: -0.76 %
買入日期: 2012-06-01
買入單價: 9.15
賣出單價: 10.27
買入數量: 900
當月投資: 8235.0
剩餘資金: 576.0
當期總投資: 47424.0
當期總持股: 5700
當期總收入: 58514.68
當期總收益: 23.39 %
=================================
同比增長: 6.98 %
買入日期: 2012-07-06
買入單價: 9.65
賣出單價: 10.12
買入數量: 800
當月投資: 7720.0
剩餘資金: 856.0
當期總投資: 55144.0
當期總持股: 6500
當期總收入: 66610.68
當期總收益: 20.79 %
=================================
同比增長: -9.84 %
買入日期: 2012-08-03
買入單價: 8.7
賣出單價: 10.12
買入數量: 1000
當月投資: 8700.0
剩餘資金: 156.0
當期總投資: 63844.0
當期總持股: 7500
當期總收入: 76730.68
當期總收益: 20.18 %
=================================
同比增長: -1.15 %
買入日期: 2012-09-07
買入單價: 8.6
賣出單價: 10.12
買入數量: 900
當月投資: 7740.0
剩餘資金: 416.0
當期總投資: 71584.0
當期總持股: 8400
當期總收入: 85838.68
當期總收益: 19.91 %
=================================
買入日期: 2012-10-05
停牌中,無法交易
=================================
同比增長: -4.19 %
買入日期: 2012-10-12
買入單價: 8.24
賣出單價: 10.12
買入數量: 1000
當月投資: 8240.0
剩餘資金: 176.0
當期總投資: 79824.0
當期總持股: 9400
當期總收入: 95958.68
當期總收益: 20.21 %
=================================
同比增長: 4.98 %
買入日期: 2012-11-02
買入單價: 8.65
賣出單價: 10.12
買入數量: 900
當月投資: 7785.0
剩餘資金: 391.0
當期總投資: 87609.0
當期總持股: 10300
當期總收入: 105066.68
當期總收益: 19.93 %
=================================
同比增長: 6.36 %
買入日期: 2012-12-07
買入單價: 9.2
賣出單價: 10.12
買入數量: 900
當月投資: 8280.0
剩餘資金: 111.0
當期總投資: 95889.0
當期總持股: 11200
當期總收入: 114174.69
當期總收益: 19.07 %
=================================
總投資額: 95889.0
總持有量: 11200
賣出金額: 114174.69
總收益率: 19.07 %
參考:http://tushare.org/
參考:https://xueqiu.com/3488649239/62074848