社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

含年化100%+的复合轮动因子,aitraderv4.7源码发布,支持duckdb列存访问数据(python源码+数据)

七年实现财富自由 • 1 月前 • 73 次点击  
原创内容第825篇,专注量化投资、个人成长与财富自由。
今天是周五,春天来了,桃花都开了。
周五是星球更新代码的日子,今天主要更新点如下:
1、duckdb loader按列加载多文件夹里的csv数据,性能更好。
2、解决了当天信号不显示的问题。
3、年化100%+的策略因子。
请前往星球下载:AI量化实验室——2025量化投资的星辰大海
代码随系统源码打包在策略集中:
核心代码片段如下:
from bt_algos_extend import TaskEngine


def ranking_ETFs():
    t = Task()
    t.name = '基于ETF历史评分的轮动策略'
    排序
    t.period = 'RunDaily'
    t.weight = 'WeighEqually'
    t.order_by_signal = 'trend_score(close,25)*0.4+(roc(close,5)+roc(close,10))*0.2+ma(volume,5)/ma(volume,20)'
    # t.start_date = '20180101'
    # t.end_date = '20240501'

    t.symbols = [
        '159915.SZ',  # '创业板ETF',
        '510180.SH',  # '上证180ETF',
        '518880.SH',  # '黄金ETF',
        '513100.SH',  # '纳指ETF',
        '159509.SZ',  # '纳指科技ETF',
        '512100.SH',  # '中证1000ETF',
        '513500.SH',  # '标普500ETF',
        '512480.SH',  # '科创100ETF'
    ]
    t.benchmark = '510300.SH'
    return t


res = Engine().run(ranking_ETFs())
import matplotlib.pyplot as plt

print(res.stats)
from matplotlib import rcParams

rcParams['font.family'] =  'SimHei'
# res.plot_weights()
res.prices.plot()
print(res.get_transactions())
df = (res.prices.pct_change() + 1).cumprod()
print(df.iloc[-1])
plt.show()
duckdb通过列的方式加载多个csv数据:
from datetime import datetime

import duckdb
import pandas as pd
from tqdm import tqdm


class DuckdbLoader:
    def __init__(selfpathsymbolscols=['close']start_date='20100101',
                 end_date=datetime.now().strftime('%Y%m%d')folder='/*'):
        self.path = path
        self.folder = folder
        self.start_date = start_date
        self.end_date = end_date
        self.cols = cols
        self.symbols = symbols
        self.df = None
        self._load_data(self.symbolsself.cols)

    def get_col_df(selfcol='close'):
        if col not in self.df.columns:
            print('列数据没有加载!')
            return None

        df_col = self.df[[col'symbol']].pivot_table(values=colindex=self.df.indexcolumns='symbol')
        return df_col

    def _load_data(selfsymbolscolumns):
        columns.extend(['symbol''date'])
        cols_str = ','.join(columns)

        symbols_str = None
        if symbols and len(symbols):
            symbols = ["'{}'".format(s) for in symbols]
            symbols_str = ",".join(symbols)

        query_str = """
    select {} from '{}{}/*.csv'
    where date >= '{}' and date <= '{}'
    """.format(cols_strself.pathself.folderself.start_dateself.end_date)
        if symbols_str:
            query_str += ' and symbol IN ({})'.format(symbols_str)

        df = duckdb.query(
            query_str
        ).df()
        df['date'] = df['date'].apply(lambda x: str(x))
        df.set_index('date'inplace=True)
        df.index = pd.to_datetime(df.index)
        df.sort_index(inplace=True, ascending=True)
        self.df = df

    def calc_all_expressions(selffieldsnames):
        df = self.df
        cols = []
        count = 0
        df.set_index([df.index'symbol']inplace=True)
        for fieldname in tqdm(zip(fieldsnames)):
            try:
                if len(field) <= 0:
                    continue
                se = calc_expr(dffield)

                count += 1
                if count 10:
                    df[name] = se
                else:
                    se.name = name
                    cols.append(se)
            except:
                print('{}错误'.format(field))
                import traceback
                print(traceback.print_exc())
                continue
        if len(cols):
            df_cols = pd.concat(colsaxis=1)
            df = pd.concat([dfdf_cols]axis=1)

        # df_all = df.loc[self.start_date: self.end_date].copy()
        # print(df_all.index.levels[0])
        df['symbol'] = df.index.droplevel(0)
        # df_all['symbol'] = df_all.index.levels[0]
        df.index = df.index.droplevel(1)
        self.df = df


if __name__ == '__main__':
    from config import DATA_ETF_QUOTES

    loader = DuckdbLoader(path=DATA_ETF_QUOTES.resolve()symbols=['510300.SH''159915.SZ'],
                          cols=['close''adj_factor'])
    df_col = loader.get_col_df('adj_factor')
    print(df_col)

     from datafeed.expr import calc_expr

    loader.calc_all_expressions(fields=['roc(close,20)']names=['roc_20'])
    df = loader.get_col_df('roc_20')
    print(df)

吾日三省吾身
宏观是我们必须承受的,而微观才是我们有所作为的。
回顾这二十年来,做对的事情有一些,有一点值得一提就是一直持续的做技术,当然不止于做技术。而且不是局限于工作中所需要的,而是觉得有意义,有外延和扩展性的。
用当下的话说,这叫“一人企业技术栈”。
当然花了很多心思,只不过是乐在其中,也并不觉得苦,也没有人要求去学习或做什么,而是就当成一个兴趣爱好。
从采集,到搜索再到推荐,再到后来的人工智能和量化投资。
做喜欢且擅长的事情,你并不会觉得是在工作或者加班。
我们讲"ABCZ"的计划,如果A(工作是你喜欢且擅长的),Z(投资计划,积累本金让自己财务小自由), 然后是造一个小商业系统(能够带来工资外,投资外的被动收入),当下以deepseek为代表的大模型及智能体,又进一步赋能“一个企业”技术栈。
日子是一天天过的,人生重要的转折点就那么几个。
在等待风来的日子里,做喜欢和擅长的事情,做到最好,开心点,就是这样!
代码和数据下载:AI量化实验室——2025量化投资的星辰大海

AI量化实验室 星球,已经运行三年多,1500+会员。

aitrader代码,因子表达式引擎、遗传算法(Deap)因子挖掘引等,支持vnpy,qlib,backtrader和bt引擎,内置多个年化30%+的策略,每周五迭代一次,代码和数据在星球全部开源。

扩展  •  历史文章   

EarnMore(赚得更多)基于RL的投资组合管理框架:一致的股票表示,可定制股票池管理。(附论文+代码)
deap系统重构,再新增一个新的因子,年化39.1%,卡玛提升至2.76(附python代码)

aitrader_v4.6代码发布,支持duckdb|股票全量数据(python代码+数据)

年化19.66%,回撤12%的稳健策略|manus的启发:基于大模型多智能体的智能投研系统(python代码+数据)

年化30.24%,最大回撤19%,综合动量多因子评分策略再升级(python代码+数据)

年化18%-39.3%的策略集 | backtrader通过xtquant连接qmt实战

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/180056
 
73 次点击