14章終える
インディケーターをつくっているところで問題が発生。
Indicatorクラスで__getitem__(self,key)で
エラーをチェックしてるために、
そのIndicatorの親クラスのArrayクラスで
def _each_cons(self, span): return zip(*(self[i:] for i in range(span)))
が呼び出されたときに[i:]のところでエラーになってしまう。
しかたないのでまずArrayクラスで計算して、
その後にIndicatorクラスに変更するようにした。
base.rbについては調べたが、
Pythonの場合は自動で読み込まず、
使う時にimportした方がいいと書かれていたので作っていない。
あと最近やっと気付いたが、Pythonの場合はキーワード引数が使えるので、
rubyのように辞書を使って擬似的にキーワード引数をつくる必要はなかった。
だがここまで作ってしまったのでとりあえずはこのまま続ける。
以下順番に
moving_average.py
estrangement.py
moving_average_direction.py
average_true_range.py
#!/usr/bin/env python # -*- coding: utf-8 -*- from indicator import Indicator from myarray import Array # 移動平均クラス # 始値、高値、安値、終値 #(open, high, low, close)のうちどれでも #price_atパラメーターを指定しなければ、終値で計算する class MovingAverage(Indicator): def __init__(self, stock, params): self.stock = stock self.span = params['span'] self.price_at = params['price_at'] or 'close' def calculate_indicator(self): prices = Array(getattr(self.stock, self.price_at + '_prices')()) return prices.moving_average(self.span)
#!/usr/bin/env python # -*- coding: utf-8 -*- from indicator import Indicator from myarray import Array # 移動平均乖離率クラス class Estrangement(Indicator): def __init__(self, stock, params): self.stock = stock self.span = params['span'] def calculate_indicator(self): close_prices = Array(self.stock.close_prices()) return [(prices[-1] - sum(prices)/self.span)/ (sum(prices)/self.span) * 100 if prices is not None else None for prices in close_prices.map_indicator(self.span)]
#!/usr/bin/env python # -*- coding: utf-8 -*- from indicator import Indicator from myarray import Array # 移動平均の方向クラス # 前日の移動平均と本日の移動平均を比べ # 本日のほうが高ければ:up # 前日のほうが高ければ:down # 同じならば:flat class MovingAverageDirection(Indicator): def __init__(self, stock, params): self.stock = stock self.span = params['span'] # 最新の終値と@span日前の終値を比べ、 # 最新のほうが高ければ上昇 # 最新のほうが低ければ下降 def calculate_indicator(self): def direction_check(firstprice, lastprice): if firstprice < lastprice: return 'up' elif firstprice > lastprice: return 'down' else: return 'flat' close_prices = Array(self.stock.close_prices()) return [direction_check(prices[0], prices[-1]) if prices is not None else None for prices in close_prices.map_indicator(self.span + 1)]
#!/usr/bin/env python # -*- coding: utf-8 -*- from indicator import Indicator from myarray import Array # 真の値幅の平均クラス # 真の値幅(前日の終値と本日の高値の高いほう # - 前日の終値と本日の安値の安い方)の移動平均 class AverageTrueRange(Indicator): def __init__(self, stock, params): self.stock = stock self.span = params['span'] def calculate_indicator(self): def calc_atr(prices): previous_close = prices[0]['close'] current_high = prices[-1]['high'] current_low = prices[-1]['low'] true_high = max(current_high, previous_close) true_low = min(current_low, previous_close) return true_high - true_low true_ranges = Array([calc_atr(prices) if prices is not None else None for prices in Array(self.stock.prices).map_indicator(2)]) return true_ranges.moving_average(self.span)