加重移動平均を算出する
移動平均もいろいろあるなー。
普通の移動平均は作成済みなので、その次の加重移動平均を実装。
# 一定期間の加重移動平均を得る 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
例によって、デモサイトにも置いています。