利用python比较股票定投和一次性投资收益效果_20200718_

利用python比较股票定投和一次性投资收益效果。最终发现,当股市上涨时,定投收益低于一次性投资;当股市下跌时,定投优于一次性投资,定投收益可以在股市下跌后的第一次反弹时迅速有力的回升。并且,一次性投资收益基本处于随机状态,定投则可以跟随股市趋势变动

import tushare as ts
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import copy
plt.rcParams['font.sans-serif']=['simhei']#用于正常显示中文标签
plt.rcParams['axes.unicode_minus']=False#用于正常显示负号

pro=ts.pro_api()

class InvestmentStrategy():

    def __init__(self,ts_code):
        self.__basic_parameters()
        self.ts_code=ts_code
        self.__get_data()


    def __basic_parameters(self):
        """基础参数"""
        self.cycle=100#投资周期(天)
        self.per_cycle=5#定投间隔时间(天)
        self.init_fund=1000#定投初始建仓资金(元)
        self.per_fund=100#每期定投金额(元)

        #定投智能参数
        self.auto=True#是否使用智能定投
        self.critical_point=0.03#涨跌幅度调整临界值

    def __get_data(self):
        """获得股票数据"""
        self.stock = pro.daily(ts_code=self.ts_code)[['ts_code','trade_date','close','pct_chg']]
        self.stock=pd.DataFrame(self.stock)
        self.stock.sort_index(ascending=False,inplace=True)
        self.stock.index=range(len(self.stock))

    def fixed_investment(self):
        """定额投资"""

        #self_stock=copy.deepcopy(stock_0)

        self.stock['fixed_rate']=0.000#定额投资
        self.stock['general_rate'] = 0.000#普通投资
        for i in self.stock.index[:(-1*self.cycle)]:
            #i=5
            stock=self.stock[i:(i+self.cycle)]
            number =self.init_fund/stock.ix[i,'close']
            self.cost=self.init_fund#总投资成本
            for j in stock.index[::self.per_cycle]:
                #j=7
                per_fund = self.per_fund
                if self.auto==True:
                    per_fund=self.__change_per_fund(day_rate=stock.ix[j,'pct_chg'])
                elif self.auto==False:
                    per_fund=self.per_fund

                number_=per_fund/stock.ix[j,'close']
                number+=number_
                self.cost+=per_fund

            for j in (set(stock.index)-set(stock.index[::self.per_cycle])):
                day_rate=stock.ix[j,'pct_chg']

                if day_rate < -1 * self.critical_point:
                    per_fund += self.per_fund * ((-1 * self.critical_point - day_rate) * 100)
                    number_ = per_fund / stock.ix[j, 'close']
                    number += number_
                    self.cost += per_fund

            rate=(stock.ix[i+self.per_cycle,'close']*number-self.cost)/self.cost/self.cycle*360
            self.stock.ix[(i+self.cycle),'fixed_rate']=rate

            #用相同的资金进行普通的一次性投资,计算收益
            number = self.cost / stock.ix[i, 'close']
            rate=(stock.ix[i+self.per_cycle,'close']*number-self.cost)/self.cost/self.cycle*360
            self.stock.ix[(i + self.cycle), 'general_rate'] = rate

            print('已经完成{}%'.format(round(i/len(self.stock),4)*100))

    def __change_per_fund(self,day_rate):
        """根据涨跌幅度及时调整每期定投金额
        day_rate为当天涨跌幅度
        """
        per_fund = self.per_fund
        #如果当天跌幅超过一定点,则多加仓;如果涨幅高于一定点,则少加仓
        if day_rate>self.critical_point:
            per_fund=self.per_fund/((day_rate-self.critical_point)*100)
        elif day_rate<-1*self.critical_point:
            per_fund += self.per_fund *(( -1* self.critical_point-day_rate) * 100)

        return per_fund


    def compare(self,start_date,end_date):
        """将两种投资方式的收益率进行比较"""
        stock = copy.deepcopy(self.stock)
        stock.index=stock['trade_date']
        stock=stock.ix[start_date:end_date,:]

        print(stock[['fixed_rate','general_rate']].describe())#m描述性统计分析比较

        plt.figure(figsize=(12,8))
        plt.grid(True,alpha=0.3)
        plt.plot(stock['trade_date'],stock['fixed_rate'],label='定额投资')
        plt.plot(stock['trade_date'], stock['general_rate'],label='一次性投资')

        plt.legend(fontsize=14)
        plt.xlabel('日期',fontsize=15)
        plt.ylabel('收益率',fontsize=15)
        plt.title(str(self.ts_code)+'收益率比较图',fontsize=18)

        close = plt.twinx()
        close.plot(stock['trade_date'], stock['close'], label='收盘价', color='black')
        close.set_ylabel('收盘价', fontsize=15)
        plt.xticks(stock['trade_date'].values[::200],rotation=270)


    def single_invstment(self,start_date,end_date):
        """在一只股票上各个期限的定投"""
        stock = copy.deepcopy(self.stock)
        stock.index = stock['trade_date']
        stock = stock.ix[start_date:end_date, :]
        stock.index=range(len(stock))

        stock['fixed_rate'] = 0.000  # 定额投资收益
        stock['fixed_year_rate']=0.000#年化收益率
        stock['fixed_number']=0.000#定额投资股票份数
        stock['fixed_value']=0.000#定额投资股票价值
        stock['cost']=0.000#投资股票所需要的成本
        stock['general_rate'] = 0.000  # 普通投资收益

        #投入初始建仓资金
        stock.ix[0,'cost'] =self.init_fund
        stock['fixed_value'] =self.init_fund
        stock.ix[0,'fixed_number']=self.init_fund/stock.ix[0,'close']

        for i in stock.index[1:]:
            if i%self.per_cycle==0:
                stock.ix[i,'fixed_number'] =stock.ix[i-1,'fixed_number']+self.per_fund/stock.ix[i,'close']
                stock.ix[i,'cost'] =stock.ix[i-1,'cost']+self.per_fund
                stock.ix[i,'fixed_value']=stock.ix[i,'fixed_number']*stock.ix[i,'close']
                stock.ix[i,'fixed_rate']=(stock.ix[i,'fixed_value']-stock.ix[i,'cost'])/stock.ix[i,'cost']
                stock.ix[i,'fixed_year_rate']=stock.ix[i,'fixed_rate']/(i+1)*360
                stock.ix[i,'general_rate']=(stock.ix[i,'close']-stock.ix[0,'close'])/stock.ix[0,'close']
            else:
                stock.ix[i, 'fixed_number']=stock.ix[i-1, 'fixed_number']
                stock.ix[i, 'cost']=stock.ix[i-1,'cost']
                stock.ix[i, 'fixed_value'] = stock.ix[i, 'fixed_number'] * stock.ix[i, 'close']
                stock.ix[i, 'fixed_rate'] = (stock.ix[i, 'fixed_value'] - stock.ix[i, 'cost']) / stock.ix[i, 'cost']
                stock.ix[i, 'fixed_year_rate'] = stock.ix[i, 'fixed_rate'] / (i + 1) * 360
                stock.ix[i,'general_rate']=(stock.ix[i,'close']-stock.ix[0,'close'])/stock.ix[0,'close']

        self.stock=stock


if __name__=='__main__':
    ts_code = '000002.SZ'
    invest_strategy=InvestmentStrategy(ts_code)
    invest_strategy.cycle=100
    invest_strategy.fixed_investment()
    invest_strategy.compare(start_date='20091202',end_date='20161116')

    invest_strategy.single_invstment(start_date='20131202',end_date='20200616')
    invest_strategy.compare(start_date='20151202',end_date='20190616')

    stock=invest_strategy.stock

猜你喜欢

转载自blog.csdn.net/weixin_45590329/article/details/107431175