原创文章第521篇,专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 逆波兰表达式如何构建,是强化学习因子挖掘的关系:网上有开源的代码,使用qlib的底层,实现了很多类,用递归的方式,很不好理解,而且与qlib的因子表达式绑定的很厉害: 我重写了这个问题,只需要token。——这里的逻辑与 gplearn 里构建的表达式树的逻辑一样,重点是如何校验生成的表达式是有效的,而不是一堆token的混合体。 # from alphagen.data.expression import * from typing import List
from datafeed.mining.tokens import * from datafeed.expr_functions import *
class ExpressionBuilder: stack: List[Token]
def __init__(self): self.stack = []
def get_tree(self) -> Token: if len(self.stack) == 1: return self.stack[0] else: raise InvalidExpressionException(f"Expected only one tree, got {len(self.stack)}")
def add_token(self, token: Token): if not self.validate(token): raise InvalidExpressionException(f"Token {token} not allowed here, stack: {self.stack}.") if isinstance(token, OperatorToken): n_args: int = token.n_args() children = [] for _ in range(n_args): children.append(self.stack.pop()) token.add_children(list(reversed(children))) self.stack.append(token) elif isinstance(token, ConstantToken): self.stack.append(token) elif isinstance(token, DeltaTimeToken): self.stack.append(token) elif isinstance(token, FeatureToken): self.stack.append(token) else: assert False
def is_valid(self) -> bool: return len(self.stack) == 1 and self.stack[0].is_featured
def validate(self, token: Token) -> bool: if isinstance(token, OperatorToken): return self.validate_op(token) elif isinstance(token, DeltaTimeToken): return self.validate_dt() elif isinstance(token, ConstantToken): return self.validate_const() elif isinstance(token, FeatureToken): return self.validate_feature() else: assert False
def validate_op(self, op: Type[OperatorToken]) -> bool: if len(self.stack) < op.n_args(): return False
if isinstance(op, UnaryOpsToken): if not self.stack[-1].is_featured: return False elif isinstance(op, BinaryOpsToken): if not self.stack[-1].is_featured and not self.stack[-2].is_featured: return False if (isinstance(self.stack[-1], DeltaTimeToken) or isinstance(self.stack[-2], DeltaTimeToken)): return False elif isinstance(op, UnaryRollingOpsToken): if not isinstance(self.stack[-1], DeltaTimeToken): return False if not self.stack[-2].is_featured: return False elif isinstance(op, BinaryRollingOpsToken): if not isinstance(self.stack[-1], DeltaTimeToken): return False if not self.stack[-2].is_featured or not self.stack[-3].is_featured: return False else: assert False return True
def validate_dt(self) -> bool: return len(self.stack) > 0 and self.stack[-1].is_featured
def validate_const(self) -> bool: return len(self.stack) == 0 or self.stack[-1].is_featured
def validate_feature(self) -> bool: return not (len(self.stack) >= 1 and isinstance(self.stack[-1], DeltaTimeToken))
class InvalidExpressionException(ValueError): pass
if __name__ == '__main__': tokens = [ FeatureToken(FeatureType.LOW), UnaryOpsToken(abs), DeltaTimeToken(10), UnaryRollingOpsToken(rank), FeatureToken(FeatureType.HIGH), FeatureToken(FeatureType.CLOSE), BinaryOpsToken(Div), BinaryOpsToken(Add), ]
builder = ExpressionBuilder() for token in tokens: #print(token) builder.add_token(token) #print(builder.stack) print(f'res: {str(builder.get_tree())}') print(f'ref: Add(rank(abs(low),10),Div(high,close))')
我们已经正确生成了表达式,当然可以把Add,Div简化成 + 和 /,这是小事了。 后续加上强化学习的环境,结合咱们的因子计算引擎,就可以进行因子挖掘了。 代码在如下位置: 重构强化学习DeepAlpha之“逆波兰表达式”构建(代码+数据)
AI量化实验室——2024量化投资的星辰大海
吾日三省吾身
高速增长的团队或组织,也并不是没有问题和矛盾,只是矛盾和消化在增长中。
大家也不是着急抢地盘,机会多的是;
出现一些问题也能消化,也因为机会多的是,所以大家相对和谐。
当周期下行,矛盾凸显。 蛋糕就这么大,开始分存量蛋糕的时候,情况就不同了。
当然,古代的仕途华山一条道,因此都是你死我活。 职场再怎么着,总有别的路可以走。 历史文章:
重构强化学习DeepAlpha之“逆波兰表达式”构建(代码+数据)
AI量化实验室——2024量化投资的星辰大海
|