山东建站管理系统淘宝支持做微交易网站吗
原创内容第922篇,专注智能量化投资、个人成长与财富自由。
咱们星球叫“智能量化实验室“,有一部分智能的工作,落在了AGI星球来实现。
但智能量化框架,还有深挖的空间。
区别于传统量化(backtrader,bt等)都是传统量化。也就是技术分析的”自动化“版本。
比如咱们的动量轮动,排序因子,还是止盈、止损规则。
当然这是有效的,也是可解释的——大家看策略榜的更新就知道了:

然而,这里还没有太多机器学习、深度学习等智能化相关的东西。
策略也不会自主学习和进化。
qlib框架是最接近AI驱动的开源量化框架,设计理念就是机器学习导向。
不过咱们之前也分析过,它不太兼容传统规则量化,而且表达式与自定义的数据存储格式绑定,不容易切换到自己的数据存储。vnpy.alpha在这方面处理得挺好。
import jsonimport shelveimport picklefrom pathlib import Pathfrom datetime import datetime, timedeltafrom collections import defaultdictfrom functools import lru_cache, partialimport numpy as npfrom loguru import loggerimport polars as plfrom constant import Intervalfrom dataset import to_datetime, AlphaDataset, process_drop_na, process_cs_norm, Segmentfrom dataset.datasets.alpha_158 import Alpha158from model import AlphaModelfrom model.models.lgb_model import LgbModelfrom strategy.strategies.equity_demo_strategy import EquityDemoStrategyclass AlphaLab:def __init__(self, lab_path: str, data_path:str) -> None:self.lab_path: Path = Path(lab_path)self.data_path = Path(data_path)self.dataset_path: Path = self.lab_path.joinpath("dataset")self.model_path: Path = self.lab_path.joinpath("model")self.signal_path: Path = self.lab_path.joinpath("signal")# 创建文件夹for path in [self.lab_path,self.dataset_path,self.model_path,self.signal_path]:if not path.exists():path.mkdir(parents=True)def save_dataset(self, name: str, dataset: AlphaDataset) -> None:"""Save dataset"""file_path: Path = self.dataset_path.joinpath(f"{name}.pkl")with open(file_path, mode="wb") as f:pickle.dump(dataset, f)def load_dataset(self, name: str) -> AlphaDataset | None:"""Load dataset"""file_path: Path = self.dataset_path.joinpath(f"{name}.pkl")if not file_path.exists():logger.error(f"Dataset file {name} does not exist")return Nonewith open(file_path, mode="rb") as f:dataset: AlphaDataset = pickle.load(f)return datasetdef save_model(self, name: str, model: AlphaModel) -> None:"""Save model"""file_path: Path = self.model_path.joinpath(f"{name}.pkl")with open(file_path, mode="wb") as f:pickle.dump(model, f)def load_model(self, name: str) -> AlphaModel | None:"""Load model"""file_path: Path = self.model_path.joinpath(f"{name}.pkl")if not file_path.exists():logger.error(f"Model file {name} does not exist")return Nonewith open(file_path, mode="rb") as f:model: AlphaModel = pickle.load(f)return modeldef remove_model(self, name: str) -> bool:"""Remove model"""file_path: Path = self.model_path.joinpath(f"{name}.pkl")if not file_path.exists():logger.error(f"Model file {name} does not exist")return Falsefile_path.unlink()return Truedef list_all_models(self) -> list[str]:"""List all models"""return [file.stem for file in self.model_path.glob("*.pkl")]def save_signal(self, name: str, signal: pl.DataFrame) -> None:"""Save signal"""file_path: Path = self.signal_path.joinpath(f"{name}.parquet")signal.write_parquet(file_path)def load_signal(self, name: str) -> pl.DataFrame | None:"""Load signal"""file_path: Path = self.signal_path.joinpath(f"{name}.parquet")if not file_path.exists():logger.error(f"Signal file {name} does not exist")return Nonereturn pl.read_parquet(file_path)def remove_signal(self, name: str) -> bool:"""Remove signal"""file_path: Path = self.signal_path.joinpath(f"{name}.parquet")if not file_path.exists():logger.error(f"Signal file {name} does not exist")return Falsefile_path.unlink()return Truedef list_all_signals(self) -> list[str]:"""List all signals"""return [file.stem for file in self.model_path.glob("*.parquet")]def load_bar_df(self,symbols: list[str],start: datetime | str='20100101',end: datetime | str=datetime.now().strftime('%Y%m%d'),extended_days: int=20):start = to_datetime(start) - timedelta(days=extended_days)end = to_datetime(end) + timedelta(days=extended_days // 10)dfs: list = []for s in symbols:# Check if file existsfile_path: Path = self.data_path.joinpath(f"{s}.csv")if not file_path.exists():logger.error(f"File {file_path} does not exist")continue# Open filedf: pl.DataFrame = pl.read_csv(file_path, schema_overrides={'date': pl.Utf8})# Convert the date column to Date typedf = df.with_columns(pl.col("date").str.strptime(pl.Date, "%Y%m%d").alias("date"))# Filter by date rangedf = df.filter((pl.col("date") >= start) & (pl.col("date") <= end))# Specify data typesdf = df.with_columns(pl.col("open"), # .round(3).cast(pl.Float32),pl.col("high"), # .cast(pl.Float32),pl.col("low"), # .cast(pl.Float32),pl.col("close"), # .cast(pl.Float32),pl.col("volume"), # .cast(pl.Float32),)# Check for empty dataif df.is_empty():continuedfs.append(df)#start_dates = [df.get_column("date").min() for df in dfs]# 找到最近的起始日期#latest_start_date = max(start_dates)#print("统一截取的起始日期:", latest_start_date)# dfs_cut = [# df.filter(pl.col("date") >= latest_start_date)# for df in dfs# ]# Concatenate resultsresult_df: pl.DataFrame = pl.concat(dfs)# compare_symbol_dates(result_df,'513500.SH','512890.SH')return result_dfdef calc_exprs(self, df, names, fields):from dataset.utility import calculate_by_expressionif len(fields) == len(names) and len(names) > 0:results = []for name,field in zip(names, fields):if field == '':continue#try:expr = calculate_by_expression(df, field)#except:# print(f'因子表达式有问题,忽略:{field}')# import traceback# traceback.print_stack()# continueresults.append(expr['data'].alias(name))df = df.with_columns(results)return df# self.df = self.df.drop_nans()if __name__ == '__main__':from strategy import BacktestingEnginesymbols = ['510300.SH','159915.SZ']lab = AlphaLab(lab_path='./run', data_path='D:\work\.aitrader_data\quotes_etf')df = lab.load_bar_df(symbols=symbols, start='20100101', end='20250506',extended_days=10)print(df)dataset: AlphaDataset = Alpha158(df,train_period=("2010-01-01", "2014-12-31"),valid_period=("2015-01-01", "2016-12-31"),test_period=("2017-01-01", "2020-8-31"),)# 添加数据预处理器dataset.add_processor("learn", partial(process_drop_na, names=["label"]))dataset.add_processor("learn", partial(process_cs_norm, names=["label"], method="zscore"))# 准备特征和标签数据name = 'etf轮动'dataset.prepare_data(filters=None, max_workers=3)lab.save_dataset(name=name,dataset=dataset)dataset: AlphaDataset = lab.load_dataset(name)model: AlphaModel = LgbModel(seed=42)# # 使用数据集训练模型model.fit(dataset)# # 查看模型细节# model.detail()lab.save_model(name,model)model = lab.load_model(name)#用模型在测试集上预测pre: np.ndarray = model.predict(dataset, Segment.TEST)# 加载测试集数据df_t: pl.DataFrame = dataset.fetch_infer(Segment.TEST)# 合并预测信号列df_t = df_t.with_columns(pl.Series(pre).alias("signal"))# 提取信号数据signal: pl.DataFrame = df_t["date", "symbol", "signal"]dataset.show_signal_performance(signal)lab.save_signal(name,signal)# 从文件加载信号数据signal = lab.load_signal(name)import btfrom bt.algos import *from bt_algos_extend import SelectTopK# create the strategys = bt.Strategy('s1', [bt.algos.RunDaily(),SelectTopK(signal=signal),bt.algos.WeighEqually(),bt.algos.Rebalance()])# 创建回测引擎对象engine = BacktestingEngine(lab)# 设置回测参数engine.set_parameters(vt_symbols=symbols,interval=Interval.DAILY,start=datetime(2017, 1, 1),end=datetime(2020, 8, 1),capital=100000000)# # 添加策略实例# setting = {"top_k": 30, "n_drop": 3, "hold_thresh": 3}# engine.add_strategy(EquityDemoStrategy, setting, signal)# 执行回测任务# engine.load_data()# engine.run_backtesting()# engine.calculate_result()# engine.calculate_statistics()# engine.show_chart()#dataset.show_feature_performance("rsv_5")
典型的机器学习流程,数据及因子计算,划分数据集,然后有监督学习建模,预测信号,回测,可视化。
通过滚动式的学习,模型是可以持续进化的,这就是核心逻辑:
代码与数据下载:AI量化实验室——2025量化投资的星辰大海

吾日三省吾身
01
《拿铁因素》里三句话:先投资自己,让账户自动运转,从现在起,富有地生活。
其实“拿铁因素”本身,只是有效“省钱”的方式。
让账户自动运转才是根本。
很幸运这几年构建了自己的投资理财体系,账户可以自动运转。
无论你是通过“节约拿铁因素”去节流,还是通过“一人企业”去开源,这个“杠杆”的金钱系统都有有效地发挥作用。
“从现在起,富有地生活”。——不留遗憾。
如果仅仅指望退休生活,那就是《百万富翁快车道》里看不上的“慢车道”。
“有花堪折直须折,莫待无花空折枝”。
当你三十岁的时候,去买十八岁时想买的东西,去二十岁想去的地方,已经毫无意义。世界上没有那么多的来日方长,只有世事无常,欲买桂花同载酒,终不似少年游。”
如何平衡现在和未来呢?既要活在当下,又要长期主义。
其实也特别简单,存下每天收入的1/8以上(先投资自己),然后让复利滚动起来(让账户自动运转)。然后就可以在“当下”,“富有地生活”了。
不必想象自己达到A7.7或者A8,或者等到这一天。
因为你等到这一天,你会发现,其实没有特别根本的变化。
前两句话是如何实现财富自由,而第三句话则是关于为什么这么做?
财务自由并不是目的,财富自由是为了精神自由,能自由,深度去体验这个世界。首先确定对你来说什么是重要的,然后照着去做。比如你想上很久的摄影课、想看很久的演唱会、想去很久的一场旅行……你比你想象的更富有,所以从现在起富有地生活吧,不是在遥远的未来,就从今天开始。
——像你已经财富自由了那样,去生活。
02
大家都各大有各的事情,但多数人终归是普通人。
有人说,潜在的机会在弱联系里,这是有一定的道理。
弱联系的主动维护和激活: 弱连接不会自动产生价值。你需要:
-
-
建立连接: 积极参与社交活动、线上社区、行业会议等。
-
保持可见度: 偶尔互动(如社交媒体点赞评论、节日问候、分享有用信息)。
-
清晰表达价值: 在适当的时候,让对方知道你的专长和需求(但不要过于功利)。
-
乐于助人: 在力所能及的范围内帮助弱连接对象,建立好感与互惠基础。
-
善于倾听和提问: 了解对方的世界,发现潜在的交集。
“潜在”二字很关键: 并非所有弱连接都会带来直接机会,但弱连接网络大大增加了你接触到潜在机会的可能性。它是一个概率游戏,网络越大越多元,可能性越高。
-
代码和数据下载:AI量化实验室——2025量化投资的星辰大海
扩展 • 历史文章
EarnMore(赚得更多)基于RL的投资组合管理框架:一致的股票表示,可定制股票池管理。(附论文+代码)
年化收益200%+的策略集 | 实时板块资金热力图 「aitrader 5.0系统代码发布」
机器学习驱动的策略开发通过流程 | 普通人阶层跃迁的可能路径?
年化30.24%,最大回撤19%,综合动量多因子评分策略再升级(python代码+数据)
三秒钟创建一个年化28%,夏普比1.25的策略(python系统已开放源代码下载)
会员专属策略可以直接下载了,多个十年年化30+%策略集|polars重构因子引擎(代码+数据下载)
6年年化收益46%,最大回撤率为16%的策略(附python代码)
