量化交易系统-如何评价交易策略(含源码)

量化交易系统-如何评价交易策略(含源码)


在量化交易系统的回测模块中,按照我们的交易策略,产生了一条条的交易记录,如何通过这些交易数据,来判断我们策略的好坏,是否可以拿到实盘上跑呢?

评价一个交易策略,主要从以下三个方面:收益、风险、稳定性。常用的评价指标有:年化收益率、最大回撤、夏普比率、胜率、信息率等。今天主要分享这些指标的代码实现。

python 版本免费、c++版本需付费,已付费用户在后台提供邮箱地址,可以将两个版本的源码文件打包发给你。

最大回撤

计算净值的最大回撤可以帮助投资者了解其投资组合经历的最大损失幅度,也就是能够承受的最大亏损,属于风险性指标。最大回撤的计算涉及找到净值序列中某个峰值到谷值之间的最大跌幅。

def calculate_max_drawdown(net_values):
    """
    计算净值数组的最大回撤以及回撤区间的开始和结束下标。

    参数:
    net_values (list of float): 净值数组。

    返回:
    tuple: (最大回撤值, 回撤开始下标, 回撤结束下标)
    """
    if not net_values:
        return (0, -1, -1)

    max_drawdown = 0
    start_index = 0
    end_index = 0
    peak_index = 0

    for i in range(1, len(net_values)):
        if net_values[i] > net_values[peak_index]:
            peak_index = i
        
        drawdown = (net_values[peak_index] - net_values[i]) / net_values[peak_index]

        if drawdown > max_drawdown:
            max_drawdown = drawdown
            start_index = peak_index
            end_index = i

    return max_drawdown, start_index, end_index

在之前的文章 七天打造一套量化交易系统:Day3-回测系统的选择、搭建及改造,回测结果资金曲线中,可以加上最大回撤的区间,画图模块的代码后续分享。

年化收益率

计算净值的年化收益率可以帮助投资者理解其投资的长期回报率。下面代码中假设一年有 245 个交易日(针对国内股票、期货市场)。如果是数字货币交易,全年无休,就需要填成 365。

def calculate_annualized_return(net_values, num_trading_days=None):
    """
    计算净值数组的年化收益率。

    参数:
    net_values (list of float): 净值列表。
    num_trading_days (int, optional): 净值列表所代表的交易天数。如果为 None,将假设净值列表长度为交易天数。

    返回:
    float: 年化收益率,以小数形式表示。
    """
    if not net_values or len(net_values) < 2:
        raise ValueError("净值列表至少需要两个数据点")

    initial_value = net_values[0]
    final_value = net_values[-1]
    
    # 默认以净值长度为交易天数
    num_days = len(net_values) if num_trading_days is None else num_trading_days

    # 计算总收益率
    total_return = (final_value - initial_value) / initial_value

    # 计算年化收益率,假设一年有 245 个交易日
    annualized_return = (1 + total_return) ** (245.0 / num_days) - 1

    return annualized_return

夏普比率

夏普比率(Sharpe Ratio)是一个可以同时对收益与风险加以综合考虑的指标。

  • 在给定的风险水平下使期望回报最大化
  • 在给定期望回报率的水平上使风险最小化
def calculate_daily_returns(net_values):
    """
    计算每日回报率。

    参数:
    net_values (list of float): 每日净值列表。

    返回:
    list of float: 每日回报率,以小数表示。
    """
    if not net_values or len(net_values) < 2:
        raise ValueError("净值列表必须包含至少两个元素。")

    daily_returns = []
    for i in range(1, len(net_values)):
        daily_return = (net_values[i] - net_values[i - 1]) / net_values[i - 1]
        daily_returns.append(daily_return)

    return daily_returns

def calculate_sharpe_ratio(returns, risk_free_rate=0):
    """
    计算投资组合的夏普比率。

    参数:
    returns (list or np.ndarray): 投资组合的回报率序列。
    risk_free_rate (float): 无风险利率(默认值为 0)。

    返回:
    float: 夏普比率。
    """
    returns = np.array(returns)
    
    # 计算超额收益
    excess_returns = returns - risk_free_rate
    
    # 计算平均超额收益
    mean_excess_return = np.mean(excess_returns)
    
    # 计算超额收益的标准差
    std_excess_return = np.std(excess_returns)
    
    # 计算夏普比率
    sharpe_ratio = mean_excess_return / std_excess_return
    
    return sharpe_ratio

信息率

信息率用来衡量承担主动风险所带来的超额收益,表示单位主动风险所带来的超额收益,在承担适度风险的情况下,尽量追求高信息率。

def calculate_information_ratio(portfolio_returns, benchmark_returns):
    """
    计算投资组合的信息率。

    参数:
    portfolio_returns (list or np.ndarray): 投资组合的回报率序列。
    benchmark_returns (list or np.ndarray): 基准的回报率序列。

    返回:
    float: 信息率。
    """
    portfolio_returns = np.array(portfolio_returns)
    benchmark_returns = np.array(benchmark_returns)
    
    # 计算主动回报(超额收益)
    active_returns = portfolio_returns - benchmark_returns
    
    # 计算平均主动回报
    mean_active_return = np.mean(active_returns)
    
    # 计算跟踪误差(主动回报的标准差)
    tracking_error = np.std(active_returns)
    
    # 计算信息率
    information_ratio = mean_active_return / tracking_error
    
    return information_ratio

测试方法

if __name__ == "__main__":
    
    # 每日净值列表(假设9个交易日)
    net_values = [1.0, 1.2, 1.1, 1.4, 1.3, 1.0, 1.5, 1.4, 1.2]
    print(net_values)
    
    # 计算最大回撤
    max_drawdown, start, end = calculate_max_drawdown(net_values)
    print(f"max_drawdown: {max_drawdown:.4f}")
    print(f"start index: {start} value: {net_values[start]:.2f}")
    print(f"end   index: {end} value: {net_values[end]:.2f}")
    
    # 计算年化收益率
    print(f"calculate_annualized_return: {calculate_annualized_return(net_values):.4f}")
    print(f"calculate_annualized_return (245 days): {calculate_annualized_return(net_values, 245):.4f}")
    print(f"calculate_annualized_return (490 days): {calculate_annualized_return(net_values, 490):.4f}")
    
    # 计算每日回报率
    daily_returns = calculate_daily_returns(net_values)
    # 使用列表推导式格式化数组中的每个数字保留4位小数
    formatted_daily_returns = ["{:.4f}".format(num) for num in daily_returns]
    print(f"daily_returns: {formatted_daily_returns}")
    
    # 计算夏普比率
    risk_free_rate = 0.03/245  # 假设每日无风险利率
    sharpe_ratio = calculate_sharpe_ratio(daily_returns, risk_free_rate)
    print(f"sharpe_ratio: {sharpe_ratio:.4f}")
    
    # 计算信息率
    # 假设基准的每日回报率
    benchmark_returns = [0.005, 0.015, 0.01, 0, 0.02, 0.01, 0, -0.02]
    information_ratio = calculate_information_ratio(daily_returns, benchmark_returns)
    print(f"information_ratio: {information_ratio:.4f}")

执行结果:

[1.0, 1.2, 1.1, 1.4, 1.3, 1.0, 1.5, 1.4, 1.2]
max_drawdown: 0.2857
start index: 3 value: 1.40
end   index: 5 value: 1.00
calculate_annualized_return2: 0.0231
calculate_annualized_return: 142.0505
calculate_annualized_return (245 days): 0.2000
calculate_annualized_return (490 days): 0.0954
daily_returns: ['0.2000', '-0.0833', '0.2727', '-0.0714', '-0.2308', '0.5000', '-0.0667', '-0.1429']
sharpe_ratio: 0.2015
information_ratio: 0.1820

c++版本

对于大部分朋友,python版本的代码已经足够使用。c++改写的版本,运行速度会更快,编码难度也更大,所以就不免费提供了,如果需要可自取,不需要的可以跳过了。

python 版本免费、c++版本需付费,已付费用户在后台提供邮箱地址,可以将两个版本的源码文件打包发给你。

c++版本跳转链接

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值