Quantitative backtesting with pandas (akshare)

In my opinion, it is a little more advanced than excel, and a little less than the frameworks of backtrader. You can do the most basic test. If you add the function of adding positions later, or functions such as take profit and stop loss, it is very inappropriate. Only the simplest technical indicator test can be done. So don't take it too seriously.

Import package, commonly used package import:

import os
import akshare as ak
import requests
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import talib as ta
%matplotlib inline
plt.style.use("ggplot")

To obtain data, this article uses the bond data in akshare as the object analysis:

bond_zh_hs_daily_df = ak.bond_zh_hs_daily(symbol="sh010107")

Add metrics:

def backtest_trend_strategy(ohlc: pd.DataFrame,
                            fast_period: int = 50,
                            slow_period: int = 200,
                            threshold: float = 1.0) -> pd.DataFrame:
    """封装向量化回测的逻辑"""
    # 计算指标
    ohlc["fast_ema"] = talib.EMA(ohlc.close, fast_period)
    ohlc["slow_ema"] = talib.EMA(ohlc.close, slow_period)
    ohlc["pct_diff"] = (ohlc["fast_ema"] / ohlc["slow_ema"] - 1) * 100

    # 生成信号,1表示做多,-1表示做空,0表示空仓
    ohlc["signal"] = np.where(ohlc["pct_diff"] > threshold, 1, 0)
    ohlc["signal"] = np.where(ohlc["pct_diff"] < -threshold, -1, ohlc["signal"])

    # 计算策略收益率
    ohlc["returns"] = np.log(ohlc["close"] / ohlc["close"].shift(1))
    ohlc["strategy"] = ohlc["signal"].shift(1) * ohlc["returns"]
    ohlc["strategy_returns"] = ohlc["strategy"].cumsum()
    
    return ohlc

Run the strategy and draw the picture:

data = strategy1(data)


fig, ax = plt.subplots(nrows=3, ncols=1, figsize=(12, 15), sharex=True)

ax[0].plot(data.index, data["close"])
ax[0].plot(data.index, data["fast_ema"])
ax[0].plot(data.index, data["slow_ema"])
ax[0].set_title("Price and Indicators")

ax[1].plot(data.index, data["signal"])
ax[1].set_title("Strategy Position")

data[["returns", "strategy"]].cumsum().plot(ax=ax[2], title="Strategy Return")

 Parameter optimization:

# 选择核心参数和扫描区间,其它参数保持不变
fast_period_rng = np.arange(5, 101, 5)

total_return = []
for fast_period in fast_period_rng:
    ohlc = data.filter(["open", "high", "low", "close"])
    res = backtest_trend_strategy(ohlc, fast_period, 200, 1.0)
    total_return.append(res["strategy_returns"].iloc[-1])
    

# 散点图:策略收益率 vs 快速均线回溯期
fig, ax = plt.subplots(figsize=(12, 7))
ax.plot(fast_period_rng, total_return, "r-o", markersize=10)
ax.set_title("Strategy Return vs Fast period")
ax.set_xlabel("fast_period")
ax.set_ylabel("return(%)")

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324319791&siteId=291194637