[Day 14] 回测分析

什麽是回测?

在金融领域,回测通过测试交易策略,并根据历史资料的表现来核查其可行性。换句话说,它使用过去的资料来检视策略的执行情况。如果回测显示出良好的结果,则交易者或投资者可以继续进行并将该策略应用於实际环境。

但是,如果通过回测得到了较满意的结果,又意味着什麽呢?使用回测工具是为了分析特定策略的风险和潜在获利能力。可以基於统计反馈来优化和增强投资策略,以最大程度地提高潜在收益。通过完备的回测还可以确保实际交易环境中实施该策略的可行性。

回测平台或工具在评估策略是否在某些时间段不可行或存在较大风险方面也能够有所帮助。如果对回测的结果不满意,则应适当放弃或修改交易思路。同样,评估回测的市场条件也十分重要。当市场条件发生变化时,相同的回测可能会带来相反的结果。
From 什麽是回测?

backtrader vs backtesting.py

目前Python主流库基本上就两种,backtrader与backtesting.py,
zipline过於老旧不考虑,
FinMind虽然有内建回测但稳定度与相容性不佳。

backtrader

  • 优点
    • 直觉、简洁。
    • 有很多内容可以学习更多关於算法交易的知识。
    • 有一个活跃的社群在修复错误。
    • 非常好的文档。
  • 缺点
    • 学习曲线高。

backtesting.py

  • 优点
    • 轻量、简洁。
    • 内建回测会用到的所有功能。
    • 可互动的分析介面
  • 缺点
    • 学习曲线高。
    • 相对小的社群。
    • 简单到不能更简单的文档。

实例

引入函式库

import datetime
import warnings

import pandas as pd 
import requests
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from backtesting.test import SMA
from pandas.core.common import SettingWithCopyWarning

warnings.simplefilter(action="ignore", category=SettingWithCopyWarning)
pd.set_option("display.max_columns", None)

取得资料

backtesting强制要求栏位名称格式,
所以需要先转换栏位名称

stock_index = 2340
url = "https://api.finmindtrade.com/api/v4/data"
parameter = {
    "dataset": "TaiwanStockPrice",
    "start_date": datetime.datetime(2012, 1, 1, 0, 0).strftime("%Y-%m-%d"),
    "end_date": datetime.datetime(2018, 1, 1, 0, 0).strftime("%Y-%m-%d"),
    "data_id": stock_index,
}

data = requests.get(url, params=parameter)
data = data.json()

df = pd.DataFrame(data["data"])

df.index = pd.to_datetime(df["date"])
df.rename(
    columns={
        "Trading_Volume": "Volume",
        "open": "Open",
        "max": "High",
        "min": "Low",
        "close": "Close",
    },
    inplace=True,
)

df.drop(
    columns=["stock_id", "date", "Trading_money", "spread", "Trading_turnover"],
    inplace=True,
)

df

回测策略

如果快线超过慢线,表示股票进入上涨的趋势,此时进行买空操作,分析图表以https://ithelp.ithome.com.tw/upload/images/20210919/20141586vhDmTPQp9Z.png表示。
如果快线跌过慢线,表示股票进入下跌的趋势,此时进行卖空操作,分析图表以https://ithelp.ithome.com.tw/upload/images/20210919/20141586Y98Ntg07AE.png表示。
颜色代表上一次操作的获利情形,绿色表示获利,绿色表示赔钱。

class SmaCross(Strategy):
    def init(self):
        self.fast_line = self.I(SMA, self.data.Close, 5)
        self.slow_line = self.I(SMA, self.data.Close, 15)

    def next(self):
        if crossover(self.fast_line, self.slow_line):
            print(
                f"{self.data.index[-1]} Buy: Price: {self.data.Close[-1]}, Slow: {self.slow_line[-5:]}, Fast: {self.fast_line[-5:]}"
            )
            self.buy()
        elif crossover(self.slow_line, self.fast_line):
            print(
                f"{self.data.index[-1]} Sell: Price: {self.data.Close[-1]}, Slow: {self.slow_line[-5:]}, Fast: {self.fast_line[-5:]}"
            )

            self.sell()

执行策略

  • cash:本金。
  • commission:交易费用。
  • hedging:进行反向操作会以FIFO形式进行抵销。
    • Sell(1100)、Buy(1000) -> 卖空100
    • Sell(1000)、Buy(1100) -> 买空100
  • exclusive_orders:每次操作前自动关闭(close)上次操作。
    • self.trades[0].close()
  • trade_on_close:於收盘时交易,否则预设於开盘交易。
test = Backtest(
    df,
    SmaCross,
    cash=1000000,
    commission=0.004,
    exclusive_orders=True,
    trade_on_close=True,
)
result = test.run()

分析结果

将分析结果储存,并利用预设浏览器开启,
result为详细的分析结果。

test.plot(filename=f"./backtest_result/{stock_index}.html")
print(result)

https://ithelp.ithome.com.tw/upload/images/20210919/20141586nTsggfN69g.png

分析结果栏位说明
From https://hackmd.io/@s02260441/SkA7IWVJv

栏位 说明
Start 起始时间
End 结束时间
Duration 经过天数
Exposure [%] 投资比率
Equity Final [$] 最终资产
Equity Peak [$] 最高资产
Return [%] 报酬率
Buy & Hold Return [%] 买入持有报酬率
Max. Drawdown [%] 最大交易回落
Avg. Drawdown [%] 平均交易回落
Max. Drawdown Duration 最长交易回落期间
Avg. Drawdown Duration 平均交易回落期间
Win Rate [%] 胜率
Best Trade [%] 最好交易报酬率
Worst Trade [%] 最差交易报酬率
Avg. Trade [%] 平均交易报酬率
Max. Trade Duration 最长交易间隔
Avg. Trade Duration 平均交易间隔
Expectancy [%] 期望值
SQN 系统品质指标
Sharpe Ratio 夏普比率
Sortino Ratio 索丁诺比率
Calmar Ratio 卡玛比率
_strategy 使用策略名称

参考


<<:  第3章:基本存取命令列与终端机介绍

>>:  [Day6] - Django 起手式

【把玩Azure DevOps】Day14 Extensions for Azure DevOps:Azure DevOps也能装外挂?

许多功能强大的系统或软件都会设计有能够安装额外的扩充套件或外挂的功能,藉此延伸软件的功能应用层面,A...

Proxmox VE 虚拟机防火墙管理 (二)

当我们已经开始使用防火墙规则管理连出入的网路传输时,随着制订规则数目越来越多,在管理上就会遇到开始...

【第八天 - Quick Sort 介绍】

Q1. Quick Sort是什麽 与前天介绍的 bubble sort 一样,是一种计算排序的方法...

[Day 13] C#改造程序码( Func<T, TResult> )教学(下)

昨天稍微看了一下范例程序码是如何包装API的input+output参数型别 今天就来继续改造原本的...

Day30 阿里云30後结语

结语: 嗨大家,这30天的铁人赛就在今天要画上结尾了。今天就来跟各位聊聊这30天挑战的一些想法跟可以...