Use python to compare the effect of stock fixed investment and one-time investment income_20200718_

Use python to compare the effect of stock fixed investment and one-time investment income. In the end, it was found that when the stock market rose, the return on fixed investment was lower than that of one-time investment; when the stock market fell, fixed investment was better than one-time investment, and the return on fixed investment could rebound rapidly and strongly after the stock market fell for the first time. Moreover, one-time investment income is basically in a random state, while fixed investment can follow the trend of the stock market.

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

Guess you like

Origin blog.csdn.net/weixin_45590329/article/details/107431175