読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

加重移動平均を算出する

Ruby jiji

移動平均もいろいろあるなー。

Wikipedia - 移動平均

普通の移動平均は作成済みなので、その次の加重移動平均を実装。

# 一定期間の加重移動平均を得る
class WeightedMovingAverage
  def initialize( range=25 )
    @rates = [] # レートを記録するバッファ
    @range = range
  end

  def next_rate( rate )
    # バッファのデータを更新
    @rates.push rate
    @rates.shift if @rates.length > @range
    
    # バッファサイズが十分でなければ、nilを返す。
    return nil if @rates.length != @range
    
    return WeightedMovingAverage.get_weighted_moving_average(@rates)
  end

private

  # 加重移動平均値を計算する。 
  # see http://ja.wikipedia.org/wiki/%E7%A7%BB%E5%8B%95%E5%B9%B3%E5%9D%87
  def self.get_weighted_moving_average( rates )
    weight = 1
    total = rates.inject(0.0) {|t,s|
      t += s.end * weight
      weight += 1
      t
    }
    return total / ( rates.length * (rates.length+1) / 2 )
  end
end

利用側のエージェントは以下。普通の移動平均との違いがわかるように、両者を表示してみました。実行してみると加重移動平均(緑)のほうが感度が高いのがわかるかと思います。

#
# 加重移動平均を使うエージェントのサンプル
#
class MovingAverageAgent < JIJI::PeriodicallyAgent

  # エージェントの説明
  def description
      "加重移動平均を使うエージェントのサンプル。"
  end
  
  # エージェントを初期化する。
  def init
    # 移動平均の算出クラス
    @mvs = [
      JIJI::Agent::Shared::WeightedMovingAverage.new(@range),
      JIJI::Agent::Shared::MovingAverage.new(@range)
    ]
    @out = output.get( "加重移動平均と移動平均", :graph, {
      :column_count=>2,
      :graph_type=>:rate,      
      :colors=>["#99aaaa","#aa99aa"] # デフォルトのグラフの色
    } )
  end
  
  # 次のレートを受け取る
  def next_period_rates( rates )
    res = @mvs.map{|mv| mv.next_rate( rates[:EURJPY].bid ) }
    return if ( !res[0] || !res[1])
    @out.put( *res )
  end  
  
  # UIから設定可能なプロパティの一覧を返す。
  def property_infos
    super().concat [
      Property.new( "range", "集計期間", 25, :number )
    ]
  end

end

例によって、デモサイトにも置いています。