历史长期年化32.1%, 最大回撤26.7%,夏普比1.372(代码+数据下载)

策略的代码我又改了一下。

网站上可以直接看效果:http://www.ailabx.com/task/a568a2e8-f145-4229-b20b-9a2435be26ed

历史长期年化32.1%, 最大回撤26.7%,夏普比1.372

图片

图片

登录网站后,可以看到交易记录:

图片

之前还是走了一些“弯路”。gui交互式固然是好事,但本质上,多数用户仍然用不起来,能用起来的用户想要代码,可以看代码会自己折腾;不会用或者不想用的用户,直接给策略就好了。

任务我进一步改进了一下。

@dataclass
class Task:
    _id: str = str(uuid.uuid1())
    name: str = '策略1'
    desc: str = ''
    author: str = 'AI量化实验室'
    start_date: str = '20100101'
    end_date: str = None
    commission: int = 0.0001
    slippage: int = 0.0001
    benchmark: str = '510300.SH'
    symbols: list[str] = field(default_factory=list)
    algo_select: str = 'SelectAll'  # 选股
    algo_rank: str = 'SelectTopK'  # 排序
    algo_weight = 'WeightEqually'  # 择时
    algo_period = 'RunDaily'  # 调仓周期

    # template: str = '大类资产配置'  # 轮动,多策略组合

    # 信号
    rules_buy: list[str] = field(default_factory=list)
    at_least_buy: int = 1
    rules_sell: list[str] = field(default_factory=list)
    at_least_sell: int = 1

    # 排序
    factor_name: str = None
    # 择时
    pick_time: str = None

    topK: int = 1
    dropN: int = 0
    b_ascending = False

    # 权重
    # weights: str = 'equally'  # or fixed
    # weights_fixed: list[float] = field(default_factory=list)  # weights == fixed时有效
    target_vol: float = None
    exclude: list[str] = field(default_factory=list)  # target_vol不为None时,排除债券基金

    # 调仓周期
    # period: str = 'RunDaily'  # RunOnce, RunQuarterly, RunMonthly, RunYearly, RunDays
    days: int = 5  # 如果period == days有效

    fields: list[str] = field(default_factory=list)
    names: list[str] = field(default_factory=list)

    # algos = [RunPeriod, SelectAll(), WeightEqually/Fixed, Rebalance]
    # 择时/轮动: [RunPeriod, SelectBySignal(),SelectTopK, WeightEqually/WeightVol, Rebalance]
    # todo 多策略:  load_df加载策略结果,[RunPeriod, SelectAll(), WeightEqually/Fixed, Rebalance]
    def get_names_fields(self):
        names = [self.factor_name.replace('(','_').replace(',','_').replace(')','')]
        fields = [self.factor_name]

        factor = None
        # roc(close,20)>0.02
        for rule in self.rules_buy:
            for s in ['>=', '>', "<=", "<"]:
                if s in rule:
                    factor = rule.split(s)[0]
                    names.append(factor.replace('(','_').replace(',','_').replace(')',''))
                    fields.append(factor)
                    break

        for rule in self.rules_sell:
            for s in ['>=', '>', "<=", "<"]:
                if s in rule:
                    factor = rule.split(s)[0]
                    names.append(factor.replace('(', '_').replace(',', '_').replace(')', ''))
                    fields.append(factor)
                    break
        return names, fields

    def load_df(self):
        logger.info('开始加载数据...')
        from quantlab.datafeed.dataloader import Mongoloader
        # df = load_data(DATA_DIR_CSVS.joinpath('etfs').resolve(), self.fields, self.names, self.symbols, columns=None,
        #               start_date=self.start_date, end_date=self.end_date,
        #               )
        #self.names, self.fields = self.get_names_fields()
        loader = Mongoloader(self.symbols, start_date=self.start_date, end_date=self.end_date)
        df = loader.load(names=self.names, fields=self.fields)
        df['date'] = df.index
        return df

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

    def _parse_weights(self):
        module = importlib.import_module('quantlab.engine.algos')
        if self.algo_weight == 'WeightEqually':
            return WeightEqually()
        if self.algo_weight == 'WeightFix':
            return WeightFix(self.weights_fixed)
        if self.algo_weight == 'WeightERC':
            return WeightERC()
        return None

    def gen_algos(self):
        algos = []
        algo_period = self._parse_period()
        if algo_period:
            algos.append(algo_period)

        # 选股
        if self.algo_select == 'SelectAll':
            algos.append(SelectAll())
        else:
            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 self.factor_name:
            algos.append(SelectTopK(factor_name=self.factor_name, K=self.topK, drop_top_n=self.dropN,
                                b_ascending=self.b_ascending))
        if self.pick_time:
            algos.append(PickTime(rule_picktime=self.pick_time))

        algo_weight = self._parse_weights()
        if algo_weight:
            algos.append(algo_weight)

        if self.target_vol:
            algos.append(TargetVol(target_volatility=self.target_vol, exclude=self.exclude))

        algos.append(Rebalance())
        return algos

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

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

相关推荐

发表回复

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