12章改
指数移動平均ができないので作り直したarray.pyあらためmyarray.py
#!/usr/bin/env python # -*- coding: utf-8 -*- from functools import reduce # Array クラスの拡張 # 合計、平均、移動平均、区間高値・安値を求めるメソッドを追加 # 配列から指標計算するメソッドを定義 class Array(list): # 合計 def sum(self): return reduce(lambda a , b: a+b, self) # 平均 def average(self): return float(self.sum()) / len(self) # 元の配列と同じ要素数の配列を返す # 配列の各要素を span 個ずつ取り出した配列に対して、順番に # ブロックで実装された処理を実行する # 呼び出し方:array.map_indicator(span) {|span_array| ...} def map_indicator(self, span): indicator_array = Array([None for x in range(0, len(self))]) for i, x in enumerate(self._each_cons(span)): if None not in x: indicator_array[i + span - 1] = x return indicator_array # 移動平均 def moving_average(self, span): return Array([sum(x) / span if x != None else None for x in self.map_indicator(span)]) # 区間高値 def highs(self, span): return Array([max(x) if x != None else None for x in self.map_indicator(span)]) # 区間安値 def lows(self, span): return Array([min(x) if x != None else None for x in self.map_indicator(span)]) def _each_cons(self, span): return zip(*(self[i:] for i in range(span))) if __name__ == '__main__': array = Array([100, 97, 111, 115, 116, 123, 121, 119, 115, 110]) print(array.sum()) print(array.average()) print(array.moving_average(4)) print(array.highs(3)) print(array.lows(3)) # 3区間高値と安値の中間 middle = Array([(max(x)+min(x))/2 if x != None else None for x in array.map_indicator(3)]) print(middle) # 前日との増減 changes = Array([x[1] - x[0] if x != None else None for x in array.map_indicator(2)]) print(changes) # 3区間の増減の平均 average_changes = changes.moving_average(3) print(average_changes) # 指数移動平均(Exponential Moving Average) span = 4 alpha = 2.0 / (span + 1) ema = None ema_array = Array([None for x in range(0, len(array))]) for i, x in enumerate(array.map_indicator(span)): if x != None: if ema == None: ema = sum(x) / span else: ema += alpha * (x[span - 1] - ema) ema_array[i] = ema print(ema_array)
map_incidatorを配列を返すだけに変えた。
map_incidatorの役割を変えてしまって大丈夫か心配だが、
目的はRubuのコードをPythonに変えるのではなく、
Pythonでシステムトレードをすることなのでとりあえずこれでよしとする。