相場商売

トレーディングビジネスあれこれ

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)