Three-minute Introduction to Quantification (10): Small Market Value Strategy (Jukuan)

hello, i'm edamame. This series uses the most streamlined codes and cases to take you quickly to get started with quantification, and only talks about the most dry goods. Friends who want to learn quantification but don’t know how to get started, hurry up and read it!

Previous review:

Three-minute introduction to quantification (1): Acquisition of market data & drawing candlestick charts

Three-minute introduction to quantification (2): Introduction to Tushare Pro data interface

Three-minute introduction to quantification (3): Calculate the rate of return

Three-minute introduction to quantification (4): Statistical analysis of market data

Three-minute introduction to quantification (5): Inferential statistics of yield

Three-minute introduction to quantification (6): correlation analysis

Three-minute introduction to quantification (7): regression analysis

Three-minute introduction to quantification (8): Capital Asset Pricing Model

Three-minute Introduction to Quantification (9): Small Market Value Strategy (Local)

In the last issue, we used python to implement the small market value strategy locally, but did not take into account the uneven distribution of actual positions, transaction fees, slippage and other issues, so the calculation results were not very accurate. Today, I will continue to share how to use a third-party quantitative platform for strategy backtesting.

Poly Wide Backtesting Framework

Let's take Jukuan as an example and first look at the backtesting framework.

First log in to Jukuan official website, select Strategy Research-Strategy List, click New Strategy, and select Stock Strategy.

picture

After clicking, you will enter the Jukuan backtesting environment, and the interface will be displayed as follows:

picture

Since we chose the stock strategy, the official here has built a basic backtesting framework for the stock strategy for us, which is divided into 4 code blocks, which are as follows:

1. Initialization function initialize()

picture

Used to set some environment parameters, such as:

set_benchmark(): Set the reference benchmark, generally choose CSI 300 as a reference;

log.set_level(): Set the output log level;

set_order_cost(): Set stamp duty and transaction commission, the default handling fee is 3/10,000, and the stamp duty is 1/1000;

run_daily(): Timing task, used to set when and how often the strategy will run.

In addition to run_daily(), handle_data() can also be used to specify the running frequency of the strategy. handle_data() will be called once per unit time, if it is backtested by day, it will be called once a day, if it is measured by minute, it will be called once every minute. It should be noted that run_daily and handle_data should not be used at the same time in the same policy.

2. Run the function before the opening

picture

Before the opening of the market, we often need to pre-set the stock selection pool, so here we mainly realize the stock selection logic. The easiest way is to directly specify the stock code. In the example, the candidate stock is designated as Ping An Bank. Specify time='before open' in run_daily(), which means the running time is before the opening (9:00).

3. Run the function during the opening

picture

During the opening of the market, we need to monitor the candidate stocks and positions. Once the candidate stocks meet the buying conditions, the positions will be opened, and the position stocks will be cleared if they meet the selling conditions. Among them, order_value() and order_target() are order placing functions, which are used to realize the order placing function. Specify time='open' in run_daily(), the running time of backtesting by day is 09:30:00, and the running time of backtesting by minute is the first second of every minute.

4. Run the function after the market closes

picture

After the market closes, we can print out the transaction records of the day, or synchronize some specific information of the day. Specifying time='after close' in run_daily() means that the running time is within half an hour after the close (15:00).

The above functions all have default parameters context and g. These two objects are officially built for us in the backtest environment. The context is used to store the user's account information, time information, etc., for example:

context.portfolio: store account information, including account total funds, available funds, holdings, positions, etc.;

context.current_dt: store the current time;

g is used to store various user-defined global variables.

Generally speaking, the backtesting framework is clear and concise. Users only need to add their own functional modules on this basis, and any functions we need to implement can be achieved through various data interfaces. Jukuan provides a wealth of data interfaces, and each data interface has a detailed description in the official API document, which is very convenient to check immediately.

For example, the market value data needed to write a small market value strategy can be viewed in the stock data-financial data interface as get_fundamentals():

picture

Screen out stocks with a market capitalization of 2 billion to 3 billion. The implementation method is as follows:

q = query(
            valuation.code,
            valuation.market_cap
        ).filter(
            valuation.market_cap.between(20,30)
        )

# 选出低市值的股票,构成buylist
df = get_fundamentals(q)

Below we implement the complete small cap strategy in a backtesting environment.

Realization of small market capitalization strategy

First define the initialization function, where you can pre-define the query statement for market value screening. Its function is to filter out and sort stocks with a market value between 2 billion and 3 billion; set the holdings to 10, and set the frequency of position adjustment to every 1 time per month.

# 导入函数库
from jqdata import *

# 初始化函数,设定基准等等
def initialize(context):
    set_benchmark('000300.XSHG')
    set_option('use_real_price', True)
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    #定义用于市值筛选的query对象
    g.q = query(valuation.code,valuation.market_cap).filter(valuation.market_cap.between(20,30)).order_by(valuation.market_cap.asc())
    # 定义持仓数量
    g.N = 10 
    # 每月运行一次
    run_monthly(trade, 1)

Next, implement the transaction function, which is to sell the position stocks and buy the alternative stocks.

def trade(context):
    #筛选初市值在20-30亿之间的股票并按市值升序排序
    df = get_fundamentals(g.q)
    buylist =list(df['code'])
    #过滤停牌股票
    buylist = filter_paused_stock(buylist)
    #选择其中市值最小的10只
    buylist = buylist[:g.N]
    #持仓股卖出,如果持仓股在备选股中则不用卖
    for security in context.portfolio.positions:
        if security not in buylist:
            order_target_value(security, 0)
    #备选股买入,如果备选股在持仓股中则不用买
    buylist=[i for i in buylist if i not in context.portfolio.positions]
    if len(buylist)>0:
        #每只股资金
        cash = context.portfolio.available_cash/len(buylist)
        ## 买入股票
        for security in buylist:
            order_value(security, cash)

Write a separate function to filter suspended stocks:

# 过滤停牌股票
def filter_paused_stock(stock_list):
    current_data = get_current_data()
    return [stock for stock in stock_list if not current_data[stock].paused]

After writing, we set the backtest time to 2023-01-01 to 2023-07-01, the backtest amount to 100,000, and the backtest frequency to every day. Click to run the backtest:

picture

View an overview of benefits:

picture

The annualized return is 38.74%, the maximum drawdown is 8.06%, and the cumulative return, Sharpe ratio, winning rate and other indicators have also been calculated. The blue line in the curve is the strategy return, and the red line is the benchmark return.

Click View Transaction Details to see which stocks have been traded and what the profit and loss are:

picture

Of course, the backtest time is too short to evaluate whether the strategy is effective in the long run. We can modify the backtest time to 2013.01.01-2023.07.01, and retest:

picture

16 times in 10 years! The long-term return is good, but the maximum drawdown has also risen to 33.99%. Compared with the 32.29% annualized return, this retracement is a bit large, and the retracement time is longer. If you cannot accept the long-term retracement, you should use it with caution.

The ultra-short-term high-frequency quantitative strategy "Whirlwind Charge" used in Maodou's firm offer has gone through dozens of versions of backtesting and tuning. It not only has a super high annualized return, but also strictly controls the retracement, and the effect of the firm offer is also very good.

Backtest data: whirlwind charge strategy description icon-default.png?t=N6B9https://mp.weixin.qq.com/s?__biz=Mzk0MzQzMjc0NQ==&mid=2247483912&idx=1&sn=22ebf8962b663be518dbf648a043eec3&chksm=c332b74ef4453e583295f1 c30fff9d4824d34353d1e2485ea62d4be7bbaa31307121e6060816&token=658742839&lang=zh_CN&scene=21#wechat_redirect

Firm offer data: The six-month firm offer data of the "Whirlwind Charge" strategy is open! icon-default.png?t=N6B9http://mp.weixin.qq.com/s?__biz=Mzk0MzQzMjc0NQ==&mid=2247497573&idx=1&sn=87dc047f462302886df970e13c77524b&chksm=c3314223f446cb3590e80d4f416f 7cefc91769cf7b4fbe51916dfe12b52d92d66fb44452bd20&scene=21#wechat_redirect

picture

The above is all the content of today’s dry goods. The main purpose of this article is to explain how to do strategy backtesting through the Jukuan platform. The small market value strategy itself is not too much to evaluate here. Everyone’s risk preference and investment style are different, and the strategy that suits them is the best. good strategy.

This article is the last article of the "Three-minute Introduction to Quantification" series. Follow-up Maodou will share more quantification-related articles, and will continue to share with you the real situation of the whirlwind charge strategy every trading day. Welcome to like and follow .

Supongo que te gusta

Origin blog.csdn.net/weixin_37475278/article/details/131742660
Recomendado
Clasificación