请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

照搬测试结果大相径庭

# base.py
def compose_signal(data):
    # 整合交易信号,连续出现两次买入信号只保留第一次
    data['buy_signal'] = np.where((data['buy_signal'] == 1) & (data['buy_signal'].shift(1) == 1), 0, data['buy_signal'])
    data['sell_signal'] = np.where((data['sell_signal'] == -1) & (data['sell_signal'].shift(1) == -1), 0,
                                   data['sell_signal'])

    # 合并信号,1买入,-1卖出,后面按照这个来计算收益
    data['signal'] = data['buy_signal'] + data['sell_signal']
    return data

def calculate_prof_pct(data):
    # 计算单次收益率:开仓、平仓(开仓的全部股数)
    data.loc[data['signal'] != 0, 'profit_pct'] = data['close'].pct_change()
    data = data[data['signal'] == -1]   # 筛选平仓后的数据:单次收益
    return data

def calculate_cum_prof(data):
    df = data.copy()
    df['cum_profit'] = pd.DataFrame(1+ df['profit_pct']).cumprod()-1
    return df
# ma.py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import data.stock as st
import strategy.base as stra

def ma_strategy(data, short_windows=5, long_window=20):
    # 计算技术指标,ma短期,ma长期
    data['short_ma'] = data['close'].rolling(window=short_windows).mean()
    data['long_ma'] = data['close'].rolling(window=long_window).mean()

    # 生成信号:金叉买入,死叉卖出
    data['buy_signal'] = np.where(data['short_ma'] > data['long_ma'], 1, 0)
    data['sell_signal'] = np.where(data['short_ma'] < data['long_ma'], -1, 0)

    # 过滤信号
    data = stra.compose_signal(data)
    
    # 计算单次收益
    data = stra.calculate_prof_pct(data)

    # 计算累计收益
    data = stra.calculate_cum_prof(data)

    return data

if __name__ == '__main__':

    # # 计算多个股的累计收益率
    stocks = ['000001.XSHE', '000858.XSHE', '002594.XSHE']
    cum_profits = pd.DataFrame()
    
    for code in stocks:
        df = st.get_single_price(code=code, time_freq='daily', start_date='2016-01-01', end_date='2021-01-01')
        df = ma_strategy(df)
        cum_profits[code] = df['cum_profit'].reset_index(drop=True)
        df['cum_profit'].plot(label=code)
        
    print(cum_profits)
    plt.legend()
    plt.show()

图片描述

说明:为了避免 SettingwithCopyWarning 的问题,我改写了 calculate_cum_prof 函数,即便是按照视频 calculate_cum_prof 函数写法,我测试结果依旧一样,和视频结果大相径庭。不知道哪里有问题,我核对了所有函数,没发现哪里有写错。

另:4-11 寻找最优参数章节计算的数字和视频吻合,说明 ma_strategy 函数无误,我裂了…

正在回答 回答被采纳积分+3

4回答

weixin_慕勒9344830 2021-04-25 16:05:31

确实,我也是遇到了这个问题

2 回复 有任何疑惑可以回复我~
慕粉17780521093 2021-08-03 22:50:23
def calculate_prof_pct(data):
    # 计算单次收益率:开仓、平仓(开仓的全部股数)
    data.loc[data['signal'] != 0, 'profit_pct'] = data[data['signal']!=0]['close'].pct_change()
    data = data[data['signal'] == -1]   # 筛选平仓后的数据:单次收益
    return data

这么改一下就好了,你可以试一下,原因在于你之前的写法

data.loc[data['signal'] != 0, 'profit_pct'] = data['close'].pct_change()

等号右边会先计算pct_change(),但是这个计算不是筛选了signal不等于0之后再计算,而是获取的全量数据计算pct_change()

修改之后,你的代码运行结果是这样的

https://img1.sycdn.imooc.com//szimg/610958bc09338f2e12800520.jpg

1 回复 有任何疑惑可以回复我~
慕码人1336249 2021-07-28 15:51:27

我也遇到这个问题了 老哥你现在找到问题了么

0 回复 有任何疑惑可以回复我~
DeltaF 2021-04-20 20:24:57

我来看下,晚点回~

0 回复 有任何疑惑可以回复我~
  • 累计收益率函数有问题
    回复 有任何疑惑可以回复我~ 2022-02-03 11:17:53
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信