【python量化交易】—— 指数增强选股 - Qteasy自定义交易策略【附源码】

45 篇文章 6 订阅
19 篇文章 1 订阅

使用qteasy自定义并回测一个指数增强选股策略

我们今天使用qteasy来回测一个双均线择时交易策略,qteasy是一个功能全面且易用的量化交易策略框架,Github地址在这里。使用它,能轻松地获取历史数据,创建交易策略并完成回测和优化,还能实盘运行。项目文档在这里。

为了继续本章的内容,您需要安装qteasy【教程1】,并下载历史数据到本地【教程2、),详情可以参考更多教程【教程3】

建议您先按照前面教程的内容了解qteasy的使用方法,然后再参考这里的例子创建自己的交易策略。

策略思想

本策略以0.8为初始权重跟踪指数标的沪深300中权重大于0.35%的成份股.
个股所占的百分比为(0.8*成份股权重)*100%.然后根据个股是否:
1.连续上涨5天 2.连续下跌5天
来判定个股是否为强势股/弱势股,并对其把权重由0.8调至1.0或0.6

策略运行频率:每日运行
策略运行时间:每日收盘前

回测时间为:2021-01-01到2022-12-31

1. 策略代码

创建自定义交易策略:

import qteasy as qt
import numpy as np

class IndexEnhancement(qt.GeneralStg):
    
    def __init__(self, pars: tuple = (0.35, 0.8, 5)):
        super().__init__(
                pars=pars,
                par_count=2,
                par_types=['float', 'float', 'int'],  # 参数1:沪深300指数权重阈值,低于它的股票不被选中,参数2: 初始权重,参数3: 连续涨跌天数,作为强弱势判断阈值
                par_range=[(0.01, 0.99), (0.51, 0.99), (2, 20)],
                name='IndexEnhancement',
                description='跟踪HS300指数选股,并根据连续上涨/下跌趋势判断强弱势以增强权重',
                strategy_run_timing='close',  # 在周期结束(收盘)时运行
                strategy_run_freq='d',  # 每天执行一次选股
                strategy_data_types='wt-000300.SH, close',  # 利用HS300权重设定选股权重, 根据收盘价判断强弱势
                data_freq='d',  # 数据频率(包括股票数据和参考数据)
                window_length=20,
                use_latest_data_cycle=True,
                reference_data_types='',  # 不需要使用参考数据
        )
    
    def realize(self, h, r=None, t=None, pars=None):

        weight_threshold, init_weight, price_days = self.pars
        # 读取投资组合的权重wt和最近price_days天的收盘价
        wt = h[:, -1, 0]  # 当前所有股票的权重值
        pre_close = h[:, -price_days - 1:-1, 1]
        close = h[:, -price_days:, 1]  # 当前所有股票的最新连续收盘价

        # 计算连续price_days天的收益
        stock_returns = pre_close - close  # 连续p天的收益
        
        # 设置初始选股权重为0.8
        weights = init_weight * np.ones_like(wt)
        
        # 剔除掉权重小于weight_threshold的股票
        weights[wt < weight_threshold] = 0
        
        # 找出强势股,将其权重设为1, 找出弱势股,将其权重设置为 init_weight - (1 - init_weight)
        up_trends = np.all(stock_returns > 0, axis=1)
        weights[up_trends] = 1.0
        down_trend_weight = init_weight - (1 - init_weight)
        down_trends = np.all(stock_returns < 0, axis=1)
        weights[down_trends] = down_trend_weight
        
        # 实际选股权重为weights * HS300权重
        weights *= wt

        return weights

2. 策略回测

回测参数:

  • 回测时间:2021-01-01到2022-12-31
  • 资产类型:股票
  • 资产池:沪深300成份股
  • 初始资金:100万
  • 买入批量:100股
  • 卖出批量:1股
shares = qt.filter_stock_codes(index='000300.SH', date='20210101')
print(len(shares), shares[:10])
alpha = IndexEnhancement()
op = qt.Operator(alpha, signal_type='PT')
op.op_type = 'stepwise'
op.set_blender('1.0*s0', "close")
op.run(mode=1,
       invest_start='20210101',
       invest_end='20221231',
       invest_cash_amounts=[1000000],
       asset_type='E',
       asset_pool=shares,
       trade_batch_size=100,
       sell_batch_size=1,
       trade_log=True,
      )

print()

回测结果

419 ['000001.SZ', '000002.SZ', '000063.SZ', '000066.SZ', '000069.SZ', '000100.SZ', '000157.SZ', '000166.SZ', '000333.SZ', '000338.SZ']
No match found! To get better result, you can
- pass "match_full_name=True" to match full names of stocks and funds

     ====================================
     |                                  |
     |       BACK TESTING RESULT        |
     |                                  |
     ====================================

qteasy running mode: 1 - History back testing
time consumption for operate signal creation: 0.0 ms
time consumption for operation back looping:  13 sec 461.8 ms

investment starts on      2021-01-04 00:00:00
ends on                   2022-12-30 00:00:00
Total looped periods:     2.0 years.

-------------operation summary:------------
Only non-empty shares are displayed, call 
"loop_result["oper_count"]" for complete operation summary

          Sell Cnt Buy Cnt Total Long pct Short pct Empty pct
000001.SZ    0         3      3   100.0%     0.0%      0.0%  
000002.SZ    0         2      2   100.0%     0.0%      0.0%  
000063.SZ    0         0      0   100.0%     0.0%      0.0%  
000100.SZ    1         5      6    66.9%     0.0%     33.1%  
000333.SZ    0         1      1   100.0%     0.0%      0.0%  
000338.SZ    1         1      2    62.3%     0.0%     37.7%  
000651.SZ    0         1      1   100.0%     0.0%      0.0%  
000725.SZ    0        95     95   100.0%     0.0%      0.0%  
000858.SZ    0         0      0   100.0%     0.0%      0.0%  
002027.SZ    1         3      4    62.3%     0.0%     37.7%  
...            ...     ...   ...      ...       ...       ...
601229.SH    1         3      4    50.2%     0.0%     49.8%  
601288.SH    0        76     76   100.0%     0.0%      0.0%  
601318.SH    0         3      3   100.0%     0.0%      0.0%  
601328.SH    0        30     30   100.0%     0.0%      0.0%  
601398.SH    0       106    106   100.0%     0.0%      0.0%  
601601.SH    1         0      1    78.8%     0.0%     21.2%  
601668.SH    0        15     15   100.0%     0.0%      0.0%  
601688.SH    0         1      1   100.0%     0.0%      0.0%  
601899.SH    0         4      4   100.0%     0.0%      0.0%  
603259.SH    0         0      0   100.0%     0.0%      0.0%   

Total operation fee:     ¥    2,388.29
total investment amount: ¥1,000,000.00
final value:              ¥  703,480.41
Total return:                   -29.65% 
Avg Yearly return:              -16.23%
Skewness:                         -0.02
Kurtosis:                          1.63
Benchmark return:               -26.50% 
Benchmark Yearly return:        -14.36%

------strategy loop_results indicators------ 
alpha:                           -0.026
Beta:                             0.941
Sharp ratio:                     -1.237
Info ratio:                      -0.139
250 day volatility:               0.168
Max drawdown:                    43.41% 
    peak / valley:        2021-02-19 / 2022-10-31
    recovered on:         Not recovered!

===========END OF REPORT=============

在这里插入图片描述

  • 19
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
股票回测是量化交易中非常重要的一环,它可以通过历史数据对交易策略进行模拟和评估,从而评估策略的可行性和优劣性。在Python中,有很多开源的量化交易框架可以用来进行股票回测,如zipline、backtrader等。 下面是一个使用zipline框架进行简单交易策略回测的例子: 1. 安装zipline ```python pip install zipline ``` 2. 编写交易策略代码 ```python from zipline.api import order_target_percent, record, symbol def initialize(context): context.asset = symbol('AAPL') def handle_data(context, data): # 获取过去10天的收盘价 prices = data.history(context.asset, 'price', 10, '1d') # 计算平均价 mean_price = prices.mean() # 如果当前价格低于平均价,则买入 if data.current(context.asset, 'price') < mean_price: # 调整持仓比例至100% order_target_percent(context.asset, 1.0) # 否则卖出 else: # 调整持仓比例至0% order_target_percent(context.asset, 0.0) # 记录当前持仓比例 record(position=context.portfolio.positions[context.asset].amount) ``` 3. 运行回测 ```python from zipline import run_algorithm from zipline.api import symbol from datetime import datetime start = datetime(2016, 1, 1) end = datetime(2017, 1, 1) result = run_algorithm( start=start, end=end, initialize=initialize, capital_base=10000, handle_data=handle_data, bundle='quandl' ) ``` 在上述代码中,我们定义了一个简单的交易策略,即如果当前价格低于过去10天的平均价,则买入,否则卖出。然后我们使用zipline框架进行回测,设定回测开始和结束时间、初始资本、数据来源等参数,最终得到回测结果。 需要注意的是,这只是一个简单的例子,实际的交易策略可能会更加复杂,需要考虑更多的因素。另外,在进行股票回测时,也需要注意避免过度拟合或过度优化,以免出现回测虚高的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值