Quantlab v3.9.2:策略集合

咱们星球围绕一个核心:开发有效的可实盘的策略。

代码更新(更新策略集合)

图片

task的定义在:

engine/task.py中: 需要的配置项很少:

name = "创业板动量择时"
desc = "创业板动量择时:在动量大的时候买入,动量小的时候卖出"
symbols = ['159915.SZ']
algo_period = "RunDaily"
algo_period_days = 20 #RunPeriod时有效
rules_buy = ['roc_20>N1'] at_least_buy = 1 rules_sell = ['roc_20<N2'] at_least_sell = 1 order_by = "" topK = 1 dropN = 0 b_ascending = 0 algo_weight = "WeightEqually" algo_weight_fix = [] feature_names = ['roc_20'] features = ['roc(close,20)'] start_date = "20100101" end_date = "" commission = 0.0001 slippage = 0.0001 init_cash = 1000000 benchmark = "510300.SH"

回测结果如下:

创成长与红利低波动的智能beta策略(年化29.3%,最大回撤24%):

图片

全球大类资产轮动,年化26.1%:

图片

再来创业板择时

图片

import importlib
from dataclasses import dataclass, field, asdict

from datafeed.dataloader import CSVDataloader
from engine.algos import *
import json

@dataclass
class Task:
    name: str = '策略名称'
    desc: str = '策略描述'

    # 标的池
    symbols: list[str] = field(default_factory=list)

    algo_period: str = 'RunDaily'
    algo_period_days: int = 20  # 仅当RunDays时需要

    # 规则选标的:当rules_buyrules_sell至少有一条规则时,添加SelectBySignal算子, 在SelectAll之后
    rules_buy: list[str] = field(default_factory=list)  # roc(close,20)>0.08
    at_least_buy: int = 1
    rules_sell: list[str] = field(default_factory=list)  # roc(close,20)<0
    at_least_sell: int = 1

    # 排序算子:当order_by不为空时,在选股之后,添加SelectTopK算子
    order_by: str = ''  # 比如roc(close,20),或者 roc(close,20)+ slope(close,20)
    topK: int = 1
    dropN: int = 0
    b_ascending: bool = 0  # 默认降序, 0=False

    # 仓位分配,默认等权
    algo_weight: str = 'WeightEqually'
    algo_weight_fix: list = field(default_factory=list)  # WeightFix时需要

    feature_names: list = field(default_factory=list)  # roc(close,20)
    features: list = field(default_factory=list)  # roc_20

    # 回测时用户可以改变的,不变就使用默认值,字符串为空表示不设置
    start_date: str = '20100101'
    end_date: str = ''
    commission: float = 0.0001
    slippage: float = 0.0001
    init_cash: int = 100 * 10000
    benchmark: str = '510300.SH'

    def __str__(self):
        return self.name

    def load_datas(self):
        logger.info('开始加载数据...')  #
        loader = CSVDataloader(DATA_DIR.joinpath('universe'), self.symbols, start_date=self.start_date,
                               end_date=self.end_date)
        df = loader.load(fields=self.features, names=self.feature_names)
        df['date'] = df.index
        df.dropna(inplace=True)
        return df

    def _parse_period(self):
        module = importlib.import_module('engine.algos')
        if self.algo_period == 'RunDays':
            algo_period = getattr(module, self.algo_period)(self.algo_period_days)
        else:
            if self.algo_period in ['RunWeekly', 'RunOnce', 'RunMonthly', 'RunQuarterly', 'RunYearly']:
                algo_period = getattr(module, self.algo_period)()
            else:
                algo_period = RunAlways()
        return algo_period

    def _parse_weights(self):
        module = importlib.import_module('engine.algos')
        if self.algo_weight == 'WeightEqually':
            return WeightEqually()
        if self.algo_weight == 'WeightFix':
            if len(self.symbols) != len(self.algo_weight_fix):
                logger.error('固定权重 != symbols ')
                return
            return WeightFix(self.algo_weight_fix)
        if self.algo_weight == 'WeightERC':
            return WeightERC()
        return None

    def get_algos(self):
        algos = []
        algos.append(self._parse_period())
        algos.append(SelectAll())
        if len(self.rules_buy) or len(self.rules_sell):
            algos.append(SelectBySignal(rules_buy=self.rules_buy,
                                        buy_at_least_count=self.at_least_buy,
                                        rules_sell=self.rules_sell,
                                        sell_at_least_count=self.at_least_sell
                                        ))

        if len(self.order_by):
            algos.append(SelectTopK(factor_name=self.order_by, K=self.topK, drop_top_n=self.dropN,
                                    b_ascending=self.b_ascending))

        algos.append(self._parse_weights())
        algos.append(Rebalance())
        return algos

    def to_toml(self, name):
        import toml
        from config import DATA_DIR
        with open(DATA_DIR.joinpath('tasks').joinpath(name + '.json'), "w", encoding='UTF-8') as f:
            toml.dump(asdict(self),f)

    def to_json(self, name):
        import json
        from config import DATA_DIR
        with open(DATA_DIR.joinpath('tasks').joinpath(name + '.json'), "w", encoding='UTF-8') as f:
            json.dump(asdict(self), f, ensure_ascii=False)


def task_from_json(name):
    with open(DATA_DIR.joinpath('tasks').joinpath(name), "r", encoding='UTF-8') as f:
        json_data = json.load(f)
        return Task(**json_data)


@dataclass
class TaskAssetsAllocation(Task):

    def get_algos(self):
        return [
            self._parse_period(),
            SelectAll(),
            self._parse_weights(),
            Rebalance()
        ]


@dataclass
class TaskRolling(Task):  # 轮动策略模板
    def get_algos(self):
        return [
            RunAlways(),
            SelectBySignal(rules_buy=self.rules_buy,
                           buy_at_least_count=self.at_least_buy,
                           rules_sell=self.rules_sell,
                           sell_at_least_count=self.at_least_sell
                           ),
            SelectTopK(factor_name=self.order_by, K=self.topK, drop_top_n=self.dropN,
                       b_ascending=self.b_ascending),
            self._parse_weights(),
            Rebalance()
        ]


@dataclass
class TaskRolling_Model(Task):  # 轮动策略模板
    def get_algos(self):
        return [
            RunAlways(),
            SelectBySignal(rules_buy=self.rules_buy,
                           buy_at_least_count=self.at_least_buy,
                           rules_sell=self.rules_sell,
                           sell_at_least_count=self.at_least_sell
                           ),
            SelectByModel(model_name=self.model_name, feature_names=self.feature_names),
            SelectTopK(factor_name=self.order_by, K=self.topK, drop_top_n=self.dropN,
                       b_ascending=self.b_ascending),
            self._parse_weights(),
            Rebalance()
        ]


@dataclass
class TaskPickTime(Task):  # 择时策略模板
    def get_algos(self):
        return [
            RunAlways(),
            SelectBySignal(rules_buy=self.rules_buy,
                           buy_at_least_count=self.at_least_buy,
                           rules_sell=self.rules_sell,
                           sell_at_least_count=self.at_least_sell
                           ),
            WeightEqually(),
            Rebalance()
        ]

吾日三省吾身

专注,一针顶破天。

有所为有所不为,有所必为。

能力圈与行动圈。

量化投资的本质还是投资。

投资没有圣杯,它是一个无限游戏。

投机就像赌场,为什么让很多人着迷,因为真的有人会赢,而且赢得很多。

塔勒布在《随机漫步的傻瓜》里讲的,地球70亿人,真就有那么几个幸运儿,他纯粹就是运气好。

但最怕这样的人出书立说,把他的经历当成经验让我们信以为真。

股神并不炒股,股神的公司80%的资产全资控股的子公司,合纵连横。可以为股神是经营了一个大集团公司,可以打通多个领域,多条产业链,相互扶持。——这个神话不可以复制。

普通人也确有人可以以交易为生,但冷暖自知。

个人曾经有一段不短的产品经理的职业经历,我把平台当产品来经营的——并不刻意所谓知识付费。

产品最重要的事:为谁解决什么问题?

几类用户:

1、使用者:不会代码,查学理财,甚至会一点量化投资,可以订阅别人的策略。————获得策略,理解策略,创建策略,分享策略。

2、策略或组合主理人。通过分享策略参数赚钱。

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/103432
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 2024 年 7 月 29 日
下一篇 2024 年 7 月 29 日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注