一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

backtrader量化平臺教程(四)對策略進行優(yōu)化...

 昵稱806630 2021-06-14

對策略進行優(yōu)化

多數(shù)策略實際上依賴于指標(biāo),指標(biāo)又依賴一下預(yù)設(shè)的數(shù)值。那么預(yù)設(shè)的數(shù)值是否合理?
光憑腦袋想肯定是不行的,既然我們用了量化的方法。可以教給計算機來計算,找到最優(yōu)值。

經(jīng)典的28輪動策略

300、500、國債指數(shù)輪動,300和500的20天漲幅哪個大持有哪個,兩個都為負(fù)數(shù)持有國債.

28輪動的收益到底怎么樣?我們通過回測程序看下。

我們還是回測2012-1-1到2019-12-31的歷史數(shù)據(jù)。(主要時baostock的國債指數(shù)在2011年有部分缺失)

對策略進行優(yōu)化

策略里的20天,究竟為什么?有沒有更好的選擇?

可以通過optstrategy設(shè)置策略參數(shù)的測試范圍,backtrader會對這些參數(shù)進行測試驗證。

這塊驗證了1~60天的收益率情況。

    periods = range(1, 60)
    ...
    cerebro.optstrategy(TestStrategy, period=periods)

我們可以通過優(yōu)化,進行下測試,測試結(jié)果如下(最高的5個):

21211.89%12.05%
20176.95%10.72%
8174.41%10.62%
19163.45%10.17%
22163.34%10.17%

怎么設(shè)置交易費率(不可忽視的交易成本)

短周期的輪動策略,通常會導(dǎo)致大量換手。不同交易費率,究竟在回測結(jié)果中又多大影響?

我們可以通過setcommission設(shè)置交易費率進行下測試。

可以看出來不同費率下總的收益和每年平均收益,差距還是挺大的。

cerebro.broker.setcommission(0.0005)

手續(xù)費為0.0005時的收益率情況:

21211.89%12.05%
20176.95%10.72%
8174.41%10.62%
19163.45%10.17%
22163.34%10.17%

手續(xù)費為0.0001時的收益率情況:

periodTotal ROIAnnual ROI
21275.69%14.15%
8269.06%13.95%
20233.37%12.8%
19219.36%12.31%
12219.02%12.3%

總結(jié)

28輪動的策略,總體來說回報還是不錯的,遠(yuǎn)遠(yuǎn)戰(zhàn)勝了通脹。
在28輪動策略里,我們需要重視交易費率的問題,盡量采用費率更低的輪動方式。(比如
從券商處獲得更大的優(yōu)惠,或者通過同一家基金公司的基金的方式轉(zhuǎn)換節(jié)省交易費用。)

完整回測代碼

#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
"""計算28輪動某個標(biāo)的池的盈利情況"""

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import datetime  # For datetime objects
import os.path  # To manage paths
import sys  # To find out the script name (in argv[0])

# Import the backtrader platform
import backtrader as bt
import backtrader.feeds as btfeed


# Create a Stratey
class TestStrategy(bt.Strategy):
    params = (
        ('period', 20),
    )

    def log(self, txt, dt=None):
        ''' Logging function fot this strategy'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))

    def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close
        # To keep track of pending orders
        self.order = None
        self.month = -1
        self.mom = [bt.indicators.MomentumOscillator(i, period=self.params.period) for i in self.datas]

    def next(self):
        # Simply log the closing price of the series from the reference
        buy_id = 0

        c = [i.momosc[0] for i in self.mom]
        c[0] = 0
        index, value = c.index(max(c)), max(c)
        if value > 100:
            buy_id = index

        # print("buy_id ", buy_id)

        for i in range(0, len(c)):
            if i != buy_id:
                position_size = self.broker.getposition(data=self.datas[i]).size
                if position_size != 0:
                    self.order_target_percent(data=self.datas[i], target=0)
        position_size = self.broker.getposition(data=self.datas[buy_id]).size
        if position_size == 0:
            self.order_target_percent(data=self.datas[buy_id], target=0.98)

    def stop(self):
        # print(self.broker.getvalue())
        return_all = self.broker.getvalue() / 1200000.0
        print('{0},{1}%,{2}%'.format(self.params.period,
                                     round((return_all - 1.0) * 100, 2),
                                     round((pow(return_all, 1.0 / 8) - 1.0) * 100, 2)
                                     ))


class TSCSVData(btfeed.GenericCSVData):
    params = (
        ("fromdate", datetime.datetime(2012, 1, 1)),
        ("todate", datetime.datetime(2019, 12, 31)),
        ('nullvalue', 0.0),
        ('dtformat', ('%Y-%m-%d')),
        ('openinterest', -1)
    )


def backtest(cash, files, periods):
    files = files
    # Create a cerebro entity
    cerebro = bt.Cerebro()

    # Add a strategy
    cerebro.optstrategy(TestStrategy, period=periods)

    modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
    for i in files:
        datapath = os.path.join(modpath, 'datas/{0}'.format(i))

        # Create a Data Feed
        data = TSCSVData(dataname=datapath)

        # Add the Data Feed to Cerebro
        cerebro.adddata(data)

    # Set our desired cash start
    cerebro.broker.setcash(cash)
    cerebro.broker.setcommission(0.0005)

    # Run over everything
    print("period,Total ROI,Annual ROI")
    cerebro.run()


if __name__ == '__main__':
    """第0個標(biāo)的是默認(rèn)標(biāo)的"""
    files = ['bs_sh.000012.csv', 'bs_sh.000300.csv', 'bs_sh.000905.csv']
    cash = 1200000.0
    periods = range(0, 60)
    backtest(cash, files, periods)

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    色偷偷亚洲女人天堂观看| 亚洲综合色在线视频香蕉视频| 色综合伊人天天综合网中文| 日本一区不卡在线观看| 国内自拍偷拍福利视频| 五月婷日韩中文字幕四虎| av一区二区三区天堂| 午夜国产精品福利在线观看| 激情亚洲内射一区二区三区| 欧美黑人在线精品极品| 中文字幕高清免费日韩视频| 日韩熟妇人妻一区二区三区| 天海翼精品久久中文字幕| 经典欧美熟女激情综合网| 精品女同在线一区二区| 日韩黄色一级片免费收看| 成人精品亚洲欧美日韩| 欧美日韩视频中文字幕| 尤物久久91欧美人禽亚洲| 亚洲综合一区二区三区在线| 国产户外勾引精品露出一区| 日韩精品免费一区二区三区| 精品人妻一区二区三区四在线| 亚洲精品一区三区三区| 好吊视频一区二区在线| 东京热加勒比一区二区| 日韩免费成人福利在线| 少妇高潮呻吟浪语91| 国产av乱了乱了一区二区三区| 亚洲中文字幕高清乱码毛片| 中文字幕亚洲精品乱码加勒比| 人妻内射在线二区一区| 少妇肥臀一区二区三区| 午夜久久久精品国产精品| 亚洲视频在线观看免费中文字幕 | 好吊日在线视频免费观看| 五月情婷婷综合激情综合狠狠| 色综合伊人天天综合网中文| 中文字幕日韩欧美亚洲午夜| 日本高清加勒比免费在线| 亚洲精品一二三区不卡|