Day 015

JavaScript

1、创建新节点
创建一个具体的元素: createElement()
创建一个文本节点:createTextNode()
2、添加、移除、替换、插入
添加:appendChild()
移除:removeChild()
替换:replaceChild()
插入:insertBefore() 在已有的子节点前插入一个新的子节点
3、查找
通过标签名称:getElementsByTagName()
通过元素的Name属性的值:getElementsByName()
通过元素Id:getElementById()

MySQL

CREATE TABLE food(
    id INT PRIMARY KEY NOT NULL UNIQUE AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    company VARCHAR(30) NOT NULL,
    price FLOAT,
    produce_time YEAR,
    validity_time INT,
    address VARCHAR(50)
);

INSERT  INTO  food  
VALUES(NULL,'AA饼干','AA饼干厂', 2.5 ,'2013', 3 ,'北京');

UPDATE food SET address='内蒙古',price=3.2 WHERE name='CC牛奶';

UPDATE food SET validity_time=5 WHERE address='北京';

DELETE FROM food WHERE validity_time < (2017-produce_time);

DELETE FROM food WHERE address='北京';

Java

package test;

public class Day014 {
    public static void main(String[] args) {
        System.out.println("兑换方式如下:");
        int a, b, c, count = 0;
        for (a = 0; a <= 10; a++)
            for (b = 0; b <= 20; b++)
                for (c = 0; c <= 100; c++)
                    if (((a + b + c) == 20) && (10 * a + 5 * b + c == 100)) {
                        System.out.println("10元张数:" + a + ", 5元张数" + b + ", 1元张数:" + c);
                        count++;
                    }
        System.out.println("一共有" + count + "种兑换方法。");
    }
}
import pandas as pd import akshare as ak import warnings warnings.filterwarnings(‘ignore’) ======参数设置====== start_date = ‘20100101’ #开始日期 end_date = ‘20250320’ #结束日期 ma_length = 26 #均线长度 cost = 0.0003 #交易费率,万三 获取美债收益率数据 bond_df = ak.bond_zh_us_rate(start_date=start_date) bond_df[‘日期’] = bond_df[‘日期’].apply(lambda x: x.strftime(‘%Y-%m-%d’)) 获取沪深300指数数据 hs300_df = ak.index_zh_a_hist(symbol=‘000300’, period=‘daily’, start_date=start_date, end_date=end_date) hs300_df[‘涨跌幅’] = hs300_df[‘涨跌幅’] / 100.0 #将百分比转化成小数形式 合并数据,以沪深300日期为准 df = pd.merge(hs300_df[[‘日期’, ‘收盘’, ‘涨跌幅’]].rename(columns={‘收盘’:‘沪深300’}), bond_df[[‘日期’,‘美国国债收益率10年’]].rename(columns={‘美国国债收益率10年’:‘美债收益率’}), on=‘日期’, how=‘left’).fillna(method=‘ffill’).reset_index(drop=True) df[‘日期’] = pd.to_datetime(df[‘日期’]) # ======获取每周最后一个交易日====== rule:重采样频率,W-周频,M-月频 week_df = df.resample(rule=‘W’, on=‘日期’).agg({‘日期’:‘last’,‘美债收益率’:‘last’}).dropna() week_df[‘美债收益率MA’] = week_df[‘美债收益率’].rolling(ma_length).mean() week_df[‘周最后交易日’] = 1 week_df.index.name = ‘date’ # 拼接数据 day_df = pd.merge(df.drop(columns=[‘美债收益率’]), week_df, on=‘日期’, how=‘left’) day_df[‘周最后交易日’] = day_df[‘周最后交易日’].fillna(value=0) # 生成交易信号 如果 r-r_ma(26)<0,认为情绪偏多,今日只能看到昨日的数据 day_df.loc[((day_df[‘美债收益率’]-day_df[‘美债收益率MA’]).shift(1)<0) & (day_df[‘周最后交易日’].shift(1)>0), ‘signal’] = 1 如果 r-r_ma(26)>0,认为情绪偏空,今日只能看到昨日的数据 day_df.loc[((day_df[‘美债收益率’]-day_df[‘美债收益率MA’]).shift(1)>0) & (day_df[‘周最后交易日’].shift(1)>0), ‘signal’] = -1 day_df = day_df.set_index(‘日期’, drop=True) # 将交易信号转化为持仓 day_df[‘signal’] = day_df[‘signal’].fillna(method=‘ffill’).fillna(value=0) day_df[‘position’] = day_df[‘signal’].shift(1).fillna(value=0) #收盘交易,下一日才会有持仓 考虑交易成本 day_df[‘after_cost’] = 1.0 day_df.loc[day_df[‘signal’] != day_df[‘signal’].shift(1), ‘after_cost’] = (1.0 + cost) * (1.0 + cost) #开平仓各收一次手续费 day_df.loc[(day_df[‘signal’].shift(1) == 0) & (day_df[‘signal’] != 0), ‘after_cost’] = 1.0 + cost #第一次开仓只收一次手续费 day_df.loc[day_df.index[0], ‘after_cost’] = 1.0 # 画出净值曲线图 import matplotlib.pyplot as plt plt.rcParams[‘font.sans-serif’] = [‘SimHei’] plt.rcParams[‘axes.unicode_minus’] = False 择时策略的日收益率 day_df[‘strategy_pct’] = day_df[‘涨跌幅’] * day_df[‘position’] #策略和沪深300的净值 day_df[‘strategy’] = (1.0 + day_df[‘strategy_pct’]).cumprod() / day_df[‘after_cost’].cumprod() day_df[‘benchmark’] = (1.0 + day_df[‘涨跌幅’]).cumprod() 粗略计算年化收益率 annual_return = 100 * (pow(day_df[‘strategy’].iloc[-1], 250/day_df.shape[0]) - 1.0) print(‘美债收益率大盘择时策略的年化收益率:%.2f%%’ %annual_return) #将索引从字符串转换为日期格式,方便展示 ax = day_df[[‘strategy’,‘benchmark’]].plot(figsize=(16,8), color=[‘SteelBlue’,‘Red’], grid=True, title=‘美债收益率大盘择时策略净值’) plt.show() 给上述代码再加上最大回撤及夏普比率 卡玛比率代码 比较基准也一块加上
03-22
<think>好的,我需要帮用户给现有的Python代码添加最大回撤、夏普比率和卡玛比率,同时将这些指标与基准(沪深300)进行比较。现在我先仔细理解用户提供的代码结构,然后确定需要添加的部分。 首先,用户现有的代码通过美债收益率的移动平均生成交易信号,计算策略的净值曲线和年化收益率。现在需要补充三个指标:最大回撤、夏普比率、卡玛比率,并且对基准也做同样的计算。 最大回撤的计算需要找出净值曲线从峰值到谷底的最大跌幅。可以通过累计最大值和当前值来计算每日的回撤,然后取最大值。 夏普比率需要策略的年化收益率减去无风险利率(这里可能需要假设,比如用美债收益率作为无风险利率?但用户代码中未明确,可能需要用0或者另外获取数据),然后除以年化波动率。这里需要注意计算的是日度夏普,然后年化处理。 卡玛比率则是年化收益率除以最大回撤,所以需要先算年化收益和最大回撤。 另外,用户希望将基准(沪深300的净值)也计算同样的指标,所以需要分别对策略和基准进行处理。 现在分步骤考虑: 1. **计算最大回撤**:对于策略和基准的净值序列,计算每个时间点的历史最高值,然后计算当前净值相对于历史最高值的回撤比例,找出最大值。 2. **计算夏普比率**:需要日收益率数据。年化收益率已经计算,但需要年化波动率。假设一年约250个交易日。另外,无风险利率可能需要处理,例如用户可能用美债收益率的平均值作为无风险利率,或者忽略(即设为0)。这里可能需要进一步确认,但用户代码中没有明确,暂时假设无风险利率为0,或者从数据中提取。例如,美债收益率可能作为无风险利率的代理,但需要日度数据。当前代码中的美债收益率是周数据,填充到日数据,可能用ffill。所以,可以考虑每日的无风险利率是该天的美债收益率,或者周最后一个交易日的值。但这里可能比较复杂,用户可能希望简化处理,比如假设无风险利率为0。或者,用美债收益率的日数据计算日度的无风险收益。例如,将美债收益率除以252得到日利率。这部分需要明确,但用户代码中可能没有处理,所以可能需要假设或者询问用户,但根据用户的问题,可能暂时按默认方式处理,即使用年化无风险利率,例如0或者使用美债收益率的平均值。但需要看用户的数据是否有相关字段。 查看代码中的df结构,合并了美债收益率的数据,可能day_df中有美债收益率的日数据。所以,可以考虑将每日的美债收益率作为无风险利率。例如,将日度的美债收益率除以252(假设年化),得到日无风险利率。例如,如果美债收益率是年化的,那么日利率是r/252。但需要确认用户的数据中美债收益率的单位是否为年化百分比。例如,用户数据中的美债收益率如果是3表示3%,那么需要转换成小数形式。在现有代码中,用户处理涨跌幅时除以了100,所以可能美债收益率也是以百分比形式存在,需要转换。例如,原数据中的‘美国国债收益率10年’是百分比数值,比如3.0代表3%,所以用户可能在合并后没有处理,所以在day_df中的‘美债收益率’是百分比数值。例如,如果美债收益率是3%,那么日无风险利率为0.03/252。这可能需要调整。 但用户的代码中,可能未对美债收益率进行单位转换,例如原数据中的美债收益率是否为百分比形式(比如3.0代表3%)?比如在bond_df中,是否已经是小数形式?查看用户代码: 在获取美债收益率数据时,用户用的是akshare的bond_zh_us_rate函数。查阅akshare文档,美国国债收益率的数据返回的是数值型,例如10年期国债收益率可能是以百分比为单位,比如1.5表示1.5%。因此,用户可能需要将其转换为小数。例如,原数据中的美债收益率是1.5,那么实际是0.015。但用户当前代码中在合并后,并未进行这样的转换。例如,在合并后的df中的‘美债收益率’列是直接取自bond_df的‘美国国债收益率10年’,所以可能是百分比数值,如2.5代表2.5%。这时候需要除以100转化为小数形式。但用户的代码中,在获取沪深300的涨跌幅时,将其除以100转化为小数,但美债收益率可能没有处理,所以在计算无风险利率时需要转换。这可能是一个问题,需要确认。 例如,用户当前的代码中: hs300_df[‘涨跌幅’] = hs300_df[‘涨跌幅’] / 100.0 #将百分比转化成小数形式 但bond_df中的‘美国国债收益率10年’没有进行这样的转换,所以可能该列的数据是如3.0表示3%,即0.03的小数形式?或者原数据是3.0代表3%?需要确认akshare返回的数据格式。假设akshare返回的美债收益率是百分比形式,例如3.0代表3%,则用户需要将其除以100转换为小数。例如,在合并后的df中美债收益率是3.0,此时用户需要将其转换为0.03。否则,如果已经是小数形式(如0.03),则无需转换。如果用户代码中未处理,那么在计算无风险利率时可能出现错误。 例如,用户代码中的美债收益率可能未转换,导致数值错误。这可能是一个潜在的问题。但根据用户的现有代码,暂时无法确定,所以可能需要假设。例如,假设美债收益率是以百分比形式存在,例如3.0代表3%,所以在计算时需要除以100转换为小数。因此,在计算无风险利率时,需要将美债收益率转换为小数,再计算日利率。 例如,假设用户的美债收益率是年化百分比,则日无风险利率为 (美债收益率 / 100) / 252。 但用户的代码中,美债收益率可能已经被处理了?或者原数据中已经是小数形式?比如,bond_zh_us_rate返回的数据是否已经是小数?比如,3%表示为0.03。需要确认。假设原数据中的美债收益率是小数形式,例如0.03代表3%,那么无需转换。否则,如果是3.0,则需要除以100。 这个问题可能会影响夏普比率的计算,所以需要处理。如果用户当前代码中没有对美债收益率进行转换,那么需要加上这一步。例如,在合并后的df中美债收益率是百分比数值,需要除以100。 例如,在合并后的df中,加入: df['美债收益率'] = df['美债收益率'] / 100.0 但用户当前的代码中没有这一步,所以在后续计算中可能存在错误。但用户的问题不是调试代码,而是添加最大回撤等指标。因此,这里可能需要先修正美债收益率的转换问题,或者在计算无风险利率时进行处理。 这可能是一个需要注意的地方,但根据用户提供的现有代码,可能没有处理,所以这可能导致夏普比率计算时的错误。因此,在回答时需要指出这一点,或者直接在代码中添加转换。 综上,考虑到用户可能忽略将美债收益率转换为小数形式,所以在夏普比率计算时,需要处理。例如,在合并后的数据中,将美债收益率除以100: df['美债收益率'] = df['美债收益率'] / 100.0 或者在计算无风险利率时处理。 现在回到用户的代码,在合并后的df中,美债收益率是来自bond_df的‘美国国债收益率10年’,而bond_df的数据可能未转换,所以需要检查是否应该进行转换。例如,假设原数据中的美债收益率是百分比数值,例如3.0代表3%,所以需要除以100转换为小数形式。这可能是一个必要的步骤,但用户的现有代码中没有,所以在添加指标时可能需要先处理。 因此,在合并后的df中,应该添加: df['美债收益率'] = df['美债收益率'] / 100.0 这样才能正确使用美债收益率作为无风险利率。否则,如果美债收益率是小数形式,例如0.03代表3%,则无需处理。这需要用户确认akshare返回的数据格式。但根据用户处理涨跌幅的方式(除以100),推测美债收益率也需要同样的处理,所以应该在代码中添加这一步。 现在,假设用户的代码需要修正,将美债收益率转换为小数形式,在合并后的数据中添加: df['美债收益率'] = df['美债收益率'] / 100.0 接下来,计算夏普比率时,需要策略的日收益率减去无风险利率的日收益率。假设美债收益率是年化的,那么日无风险利率为 (美债收益率) / 252。例如,年化3%的美债收益率对应的日利率约为0.03/252 ≈ 0.00011905。 因此,在计算每日的超额收益率时,策略的日收益率减去当日的无风险日利率。 但需要注意,美债收益率的数据可能存在缺失或者填充的情况。在用户代码中,合并数据时使用了ffill填充,所以每个交易日都有美债收益率的数据。 现在,添加最大回撤、夏普比率、卡玛比率的具体步骤: **对于策略和基准:** 1. 最大回撤: 计算累计最大净值,然后计算每日回撤((累计最大值 - 当前净值)/ 累计最大值),取最大值。 2. 夏普比率: 计算日度超额收益率(策略日收益率 - 无风险日利率),计算平均超额收益率的年化值(乘以252),标准差年化(乘以sqrt(252)),夏普比率 = 年化平均超额收益率 / 年化标准差。 或者,如果假设无风险利率为0,则直接使用策略的日收益率计算。 但更准确的做法是使用无风险利率,这里用美债收益率作为无风险利率的代理。 3. 卡玛比率: 年化收益率 / 最大回撤。 **具体代码实现:** 首先,计算策略和基准的净值曲线已经存在('strategy'和'benchmark'列)。 然后,计算最大回撤: 对于策略: max_drawdown = (1 - (day_df['strategy'] / day_df['strategy'].cummax())).max() 同样,基准的最大回撤: benchmark_max_drawdown = (1 - (day_df['benchmark'] / day_df['benchmark'].cummax())).max() 然后,夏普比率: 需要策略的日收益率,这里策略的日收益率存储在'strategy_pct'列,但已经考虑了持仓和交易成本。或者,策略的日收益率是根据'strategy'列计算的每日收益率。例如: day_df['strategy_daily_return'] = day_df['strategy'].pct_change().fillna(0) 但可能更准确的方式是使用已经计算好的'strategy_pct'列,因为策略的日收益率是涨跌幅乘以持仓,并且考虑交易成本后的净值。但原代码中的'strategy_pct'是涨跌幅乘以position,然后累计乘积再除以after_cost的累计乘积,这可能比较复杂。或者,可能应该根据净值的每日变化来计算日收益率。例如,策略的日收益率是 (strategy_t / strategy_{t-1}) - 1。 所以更准确的计算方式是: day_df['strategy_daily_return'] = day_df['strategy'].pct_change().fillna(0) 同样,基准的日收益率是涨跌幅,即'涨跌幅'列。 对于无风险日利率,假设美债收益率是年化收益率,将其转换为日利率: day_df['risk_free_daily'] = day_df['美债收益率'] / 252 然后,计算超额收益率: day_df['excess_return_strategy'] = day_df['strategy_daily_return'] - day_df['risk_free_daily'] 夏普比率 = (平均超额收益率 * 252) / (超额收益率的标准差 * sqrt(252)) 即: sharpe_ratio = (excess_return_strategy.mean() * 252) / (excess_return_strategy.std() * np.sqrt(252)) 同样,对于基准: day_df['benchmark_daily_return'] = day_df['benchmark'].pct_change().fillna(0) excess_return_benchmark = day_df['benchmark_daily_return'] - day_df['risk_free_daily'] sharpe_ratio_benchmark = (excess_return_benchmark.mean() * 252) / (excess_return_benchmark.std() * np.sqrt(252)) 卡玛比率: 策略年化收益率 / 策略最大回撤 假设已有策略的年化收益率变量annual_return(以小数形式,比如0.1代表10%),则卡玛比率 = annual_return / max_drawdown 同样计算基准的年化收益率,然后卡玛比率。 但原代码中的annual_return是用户计算的策略年化收益率,但以百分比形式输出。例如,用户代码中的: annual_return = 100 * (pow(day_df['strategy'].iloc[-1], 250/day_df.shape[0]) - 1.0) 这里,可能计算有误,因为通常年化收益率的计算应该是 (净值^(365/天数) - 1),但用户这里用250/day_df.shape[0]。假设一年250个交易日,所以是正确的。 但需要将结果转换为小数形式,比如如果annual_return是10.5(代表10.5%),则需要除以100得到0.105。 因此,在计算卡玛比率时,应该用年化收益率的小数形式除以最大回撤的小数形式。 现在,具体代码步骤: 首先,计算最大回撤: # 策略最大回撤 strategy_max_drawdown = (1 - day_df['strategy'] / day_df['strategy'].cummax()).max() # 基准最大回撤 benchmark_max_drawdown = (1 - day_df['benchmark'] / day_df['benchmark'].cummax()).max() 然后,计算夏普比率: 假设无风险利率是美债收益率,年化转换为日: import numpy as np # 转换美债收益率为小数(如果尚未转换) day_df['美债收益率'] = day_df['美债收益率'] / 100.0 # 如果原数据是百分比形式,例如3.0代表3% day_df['risk_free_daily'] = day_df['美债收益率'] / 252 # 计算策略的日收益率 day_df['strategy_daily_return'] = day_df['strategy'].pct_change().fillna(0) # 计算基准的日收益率 day_df['benchmark_daily_return'] = day_df['benchmark'].pct_change().fillna(0) # 策略超额收益 day_df['excess_return_strategy'] = day_df['strategy_daily_return'] - day_df['risk_free_daily'] # 基准超额收益 day_df['excess_return_benchmark'] = day_df['benchmark_daily_return'] - day_df['risk_free_daily'] # 计算夏普比率 sharpe_strategy = (day_df['excess_return_strategy'].mean() * 252) / (day_df['excess_return_strategy'].std() * np.sqrt(252)) sharpe_benchmark = (day_df['excess_return_benchmark'].mean() * 252) / (day_df['excess_return_benchmark'].std() * np.sqrt(252)) 卡玛比率: # 计算策略年化收益率(小数形式) annual_return_strategy = pow(day_df['strategy'].iloc[-1], 250/day_df.shape[0]) - 1.0 # 卡玛比率策略 calmar_strategy = annual_return_strategy / strategy_max_drawdown # 计算基准年化收益率 annual_return_benchmark = pow(day_df['benchmark'].iloc[-1], 250/day_df.shape[0]) - 1.0 # 卡玛比率基准 calmar_benchmark = annual_return_benchmark / benchmark_max_drawdown 然后,将这些指标格式化输出,与之前的annual_return一起显示。 用户当前的代码中,annual_return是以百分比形式打印的,所以可能需要将这里的annual_return_strategy乘以100得到百分比形式。 同时,注意原代码中的annual_return计算可能存在误差,因为用户用了250/day_df.shape[0],而实际交易日数量可能不等于该数值。但用户可能假设如此,所以保持原计算方式。 现在,将这些代码添加到用户的代码中: 在计算完annual_return后,添加: import numpy as np # 计算最大回撤 day_df['strategy_cummax'] = day_df['strategy'].cummax() strategy_max_drawdown = (1 - day_df['strategy'] / day_df['strategy_cummax']).max() day_df['benchmark_cummax'] = day_df['benchmark'].cummax() benchmark_max_drawdown = (1 - day_df['benchmark'] / day_df['benchmark_cummax']).max() # 转换美债收益率为小数形式(假设原数据为百分比) day_df['美债收益率'] = day_df['美债收益率'] / 100.0 # 计算无风险日利率 day_df['risk_free_daily'] = day_df['美债收益率'] / 252 # 计算策略和基准的日收益率 day_df['strategy_daily_return'] = day_df['strategy'].pct_change().fillna(0) day_df['benchmark_daily_return'] = day_df['benchmark'].pct_change().fillna(0) # 计算超额收益 day_df['excess_return_strategy'] = day_df['strategy_daily_return'] - day_df['risk_free_daily'] day_df['excess_return_benchmark'] = day_df['benchmark_daily_return'] - day_df['risk_free_daily'] # 计算夏普比率 sharpe_strategy = (day_df['excess_return_strategy'].mean() * 252) / (day_df['excess_return_strategy'].std() * np.sqrt(252)) sharpe_benchmark = (day_df['excess_return_benchmark'].mean() * 252) / (day_df['excess_return_benchmark'].std() * np.sqrt(252)) # 计算卡玛比率 annual_return_strategy = pow(day_df['strategy'].iloc[-1], 250/day_df.shape[0]) - 1.0 calmar_strategy = annual_return_strategy / strategy_max_drawdown annual_return_benchmark = pow(day_df['benchmark'].iloc[-1], 250/day_df.shape[0]) - 1.0 calmar_benchmark = annual_return_benchmark / benchmark_max_drawdown # 输出结果 print('策略年化收益率:{:.2f}%'.format(annual_return * 100)) # 这里原代码中的annual_return可能已经计算正确? print('策略最大回撤:{:.2%}'.format(strategy_max_drawdown)) print('策略夏普比率:{:.2f}'.format(sharpe_strategy)) print('策略卡玛比率:{:.2f}'.format(calmar_strategy)) print('------------------------') print('基准年化收益率:{:.2f}%'.format(annual_return_benchmark * 100)) print('基准最大回撤:{:.2%}'.format(benchmark_max_drawdown)) print('基准夏普比率:{:.2f}'.format(sharpe_benchmark)) print('基准卡玛比率:{:.2f}'.format(calmar_benchmark)) 但需要注意原代码中的annual_return变量是否正确。用户原来的代码: annual_return = 100 * (pow(day_df['strategy'].iloc[-1], 250/day_df.shape[0]) - 1.0) 这可能有问题,因为策略的净值在计算时除以了after_cost的累计乘积。例如,策略的净值计算是: day_df['strategy'] = (1.0 + day_df['strategy_pct']).cumprod() / day_df['after_cost'].cumprod() 但after_cost的累计乘积可能不是简单的时间加权,需要确认是否正确。或者,是否应该直接根据strategy的净值曲线计算年化收益率。例如,年化收益率的正确计算应该是: (day_df['strategy'].iloc[-1] ** (252 / len(day_df))) - 1 假设每年252个交易日,len(day_df)是总交易日数。所以用户原来的代码中使用了250/day_df.shape[0],可能存在偏差。应该根据实际交易天数调整。 例如,正确的年化收益率计算应为: annual_return_strategy = (day_df['strategy'].iloc[-1] ** (252 / len(day_df))) - 1 同样适用于基准的年化收益率。 因此,用户原来的annual_return计算可能需要修正。例如,将250改为252,并计算正确的年化收益率。但用户可能根据自身需求设置,这里暂时保持原计算方式,但需要注意。 综上,将这些代码添加到用户现有代码的打印年化收益率之后即可。 同时,可能需要在计算前导入numpy: import numpy as np 现在,整合到用户代码中: 在plt.show()之前添加: # 计算最大回撤 day_df['strategy_cummax'] = day_df['strategy'].cummax() strategy_max_drawdown = (1 - day_df['strategy'] / day_df['strategy_cummax']).max() day_df['benchmark_cummax'] = day_df['benchmark'].cummax() benchmark_max_drawdown = (1 - day_df['benchmark'] / day_df['benchmark_cummax']).max() # 转换美债收益率为小数形式(假设原数据为百分比) day_df['美债收益率'] = day_df['美债收益率'] / 100.0 # 计算无风险日利率 day_df['risk_free_daily'] = day_df['美债收益率'] / 252 # 计算策略和基准的日收益率 day_df['strategy_daily_return'] = day_df['strategy'].pct_change().fillna(0) day_df['benchmark_daily_return'] = day_df['benchmark'].pct_change().fillna(0) # 计算超额收益 day_df['excess_return_strategy'] = day_df['strategy_daily_return'] - day_df['risk_free_daily'] day_df['excess_return_benchmark'] = day_df['benchmark_daily_return'] - day_df['risk_free_daily'] # 计算夏普比率 sharpe_strategy = (day_df['excess_return_strategy'].mean() * 252) / (day_df['excess_return_strategy'].std() * np.sqrt(252)) sharpe_benchmark = (day_df['excess_return_benchmark'].mean() * 252) / (day_df['excess_return_benchmark'].std() * np.sqrt(252)) # 计算卡玛比率 annual_return_strategy = pow(day_df['strategy'].iloc[-1], 250/day_df.shape[0]) - 1.0 calmar_strategy = annual_return_strategy / strategy_max_drawdown annual_return_benchmark = pow(day_df['benchmark'].iloc[-1], 250/day_df.shape[0]) - 1.0 calmar_benchmark = annual_return_benchmark / benchmark_max_drawdown print('策略年化收益率:{:.2f}%'.format(annual_return)) print('策略最大回撤:{:.2%}'.format(strategy_max_drawdown)) print('策略夏普比率:{:.2f}'.format(sharpe_strategy)) print('策略卡玛比率:{:.2f}'.format(calmar_strategy)) print('------------------------') print('基准年化收益率:{:.2f}%'.format(annual_return_benchmark * 100)) print('基准最大回撤:{:.2%}'.format(benchmark_max_drawdown)) print('基准夏普比率:{:.2f}'.format(sharpe_benchmark)) print('基准卡玛比率:{:.2f}'.format(calmar_benchmark)) 但需要注意,原来的annual_return是用户计算的策略年化收益率,而annual_return_strategy是重新计算的,可能存在差异。例如,用户原来的代码: annual_return = 100 * (pow(day_df['strategy'].iloc[-1], 250/day_df.shape[0]) - 1.0) 而在这里,annual_return_strategy = pow(...) - 1.0,没有乘以100。所以,在打印基准年化时,应该使用annual_return_benchmark * 100。 或者,统一使用新的计算方式,避免混淆。例如,重新计算策略和基准的年化收益率: # 重新计算年化收益率(假设250个交易日) annual_return_strategy = (day_df['strategy'].iloc[-1] ** (250 / len(day_df))) - 1 annual_return_benchmark = (day_df['benchmark'].iloc[-1] ** (250 / len(day_df))) - 1 print('策略年化收益率:{:.2%}'.format(annual_return_strategy)) print('策略最大回撤:{:.2%}'.format(strategy_max_drawdown)) print('策略夏普比率:{:.2f}'.format(sharpe_strategy)) print('策略卡玛比率:{:.2f}'.format(annual_return_strategy / strategy_max_drawdown)) print('------------------------') print('基准年化收益率:{:.2%}'.format(annual_return_benchmark)) print('基准最大回撤:{:.2%}'.format(benchmark_max_drawdown)) print('基准夏普比率:{:.2f}'.format(sharpe_benchmark)) print('基准卡玛比率:{:.2f}'.format(annual_return_benchmark / benchmark_max_drawdown)) 这样更统一,可能更准确。 但用户原来的代码中annual_return是乘以100并以百分比打印,所以需要保持一致性。或者,建议用户统一使用更准确的年化计算方法,并确保美债收益率的转换正确。 综上,最终的代码补充部分应该包括: 1. 转换美债收益率为小数形式(如果原数据是百分比)。 2. 计算最大回撤。 3. 计算夏普比率,使用美债收益率作为无风险利率。 4. 计算卡玛比率。 同时,将基准的相同指标一并计算并输出。 最后,确保导入numpy库,并在代码中添加必要的部分。</think>以下是添加最大回撤、夏普比率和卡玛比率的完整代码实现(新增部分已用注释标注): ```python # ... 原有代码保持不变 ... # ======新增性能指标计算====== import numpy as np # 计算最大回撤(策略) day_df['strategy_cummax'] = day_df['strategy'].cummax() strategy_drawdown = (day_df['strategy'] - day_df['strategy_cummax']) / day_df['strategy_cummax'] strategy_max_drawdown = strategy_drawround.min() # 计算最大回撤(基准) day_df['benchmark_cummax'] = day_df['benchmark'].cummax() benchmark_drawdown = (day_df['benchmark'] - day_df['benchmark_cummax']) / day_df['benchmark_cummax'] benchmark_max_drawdown = benchmark_drawdown.min() # 转换美债收益率为小数格式(假设原始数据为百分比) day_df['美债收益率'] = day_df['美债收益率'] / 100.0 # 计算年化无风险利率(使用美债收益率均值) risk_free_rate = day_df['美债收益率'].mean() # 计算夏普比率(策略) strategy_return = day_df['strategy'].pct_change().dropna() excess_return_strategy = strategy_return - risk_free_rate/252 sharpe_strategy = np.sqrt(252) * excess_return_strategy.mean() / excess_return_strategy.std() # 计算夏普比率(基准) benchmark_return = day_df['涨跌幅'].copy() excess_return_benchmark = benchmark_return - risk_free_rate/252 sharpe_benchmark = np.sqrt(252) * excess_return_benchmark.mean() / excess_return_benchmark.std() # 计算卡玛比率(策略) annual_return_strategy = (day_df['strategy'].iloc[-1] ** (250/len(day_df)) - 1) calmar_strategy = annual_return_strategy / abs(strategy_max_drawdown) # 计算卡玛比率(基准) annual_return_benchmark = (day_df['benchmark'].iloc[-1] ** (250/len(day_df)) - 1) calmar_benchmark = annual_return_benchmark / abs(benchmark_max_drawdown) # ======结果输出====== print('\n======策略表现======') print(f'策略年化收益率:{annual_return:.2f}%') print(f'策略最大回撤:{abs(strategy_max_drawdown):.2%}') print(f'策略夏普比率:{sharpe_strategy:.2f}') print(f'策略卡玛比率:{calmar_strategy:.2f}') print('\n======基准表现======') print(f'基准年化收益率:{annual_return_benchmark*100:.2f}%') print(f'基准最大回撤:{abs(benchmark_max_drawdown):.2%}') print(f'基准夏普比率:{sharpe_benchmark:.2f}') print(f'基准卡玛比率:{calmar_benchmark:.2f}') # ... 后续绘图代码保持不变 ... ``` **代码说明:** 1. **最大回撤计算**:通过累计最大值计算每个交易日的回撤率,取最小值作为最大回撤(结果为负值,取绝对值显示) 2. **夏普比率计算**: - 使用$$Sharpe = \frac{E(R_p - R_f)}{\sigma_p} \times \sqrt{252}$$公式 - 将年化美债收益率转换为日无风险利率$$R_f^{daily} = R_f^{annual}/252$$ 3. **卡玛比率计算**: - 使用$$Calmar = \frac{年化收益率}{最大回撤}$$公式 - 年化收益率计算保持与原有代码一致(250个交易日假设) 4. **基准指标计算**: - 使用沪深300原始涨跌幅计算基准的夏普比率 - 基准最大回撤计算方式与策略一致 **注意事项:** 1. 美债收益率数据需要确认是否为百分比格式,若原始数据已为小数格式需删除转换代码 2. 年化交易日假设可根据实际数据调整(建议使用252天) 3. 最大回撤计算结果为负值,输出时取绝对值显示
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值