交易的遗传编程:如何表示染色体
我正在用Python做一个遗传算法,这个算法可以用来进行交易。这个原理很简单,如果你对进化算法有点了解的话:
基因代表交易策略:更具体一点,每个基因都是一个这样的树:
这可以被理解为一个布尔值,意思是:
如果:
最近50个股票价格的平均值 小于 当前价格
并且 最近6个股票价格的最小值 小于 当前价格,那么结果就是真(True),否则就是假(False)
如果结果是True,就发出买入信号;如果是False,就发出卖出信号。
这是我在Python中表示这样一棵树的一个例子:
class BinaryRule:
def __init__(self, child1, child2):
self.child1 = child1
self.child2 = child2
class LessThan(BinaryRule):
name = '<'
def eval(self):
return self.child1.eval() < self.child2.eval()
# Here there is the definition of the other classes
# and then I create the tree
tree = rules.LessThan(
rules.Max( rules.Float(1) ),
rules.SMA( rules.Float(15) ),
)
print tree.eval() # True or false
现在的问题是,我想不出好的方法来进行交叉和变异操作。有什么想法吗?
2 个回答
这通常不是遗传算法的标准表示方式,我个人觉得用遗传算法来解决这个问题可能不太合适,但这确实是可以做到的。
假设你只是想处理这组特定的变量,你有一小部分可能的值:
boolean = "and"
comparator = "<"
等等……
这意味着你可以很容易地把这些值表示成一个简单的列表:
chromosome = ["and", "<", ...]
交叉操作就是在某个特定的分割点把两个染色体混合在一起:
def crossover(cr1, cr2):
split_point = random.randint(1, len(cr1))
return [cr1[:split_point] + cr2[split_point:]], [cr2[:split_point] + cr1[split_point:]]
变异操作也相对简单,只需随机改变一个数字,切换布尔运算符等等……不过这个我就留给读者自己去练习了。
你的操作符应该能够安全地互换,也就是说,它们应该都能接受相同类型的输入,并返回相同类型的输出(通常是浮点数)。
虽然不是必须的,但使用可微分的操作函数是个好主意(通过神经网络的方式):也就是说,不要只返回“是”或“否”,而是返回一个“肯定程度”。这样可以提供更细致的反馈,帮助你改进表达方式。同时,给每个操作符设置一个控制值也很有用,这样可以调整它的行为。
变异操作符可以改变操作符的类型或控制值;而交叉操作通常是交换子树。
一种比较标准的二叉树表示方法是用一个列表,比如 [头, 左, 右, 左左, 左右, 右左, 右右, 左左左, ...]。这样做的好处是,给定任何节点的索引,你可以立即计算出它的父节点、左子节点和右子节点的索引;但缺点是,如果你的树结构比较稀疏,这样会浪费很多空间。此外,正确复制子树应该通过递归函数来完成,而不是像 @Slater 上面展示的那样简单地切片和拼接。