RSIを算出する
RSIを算出するクラスです。
module Signal #===一定期間のレートデータを元に値を算出するシグナルの基底クラス class RangeSignal include Signal def initialize( range=25 ) @datas = [] # レートを記録するバッファ @range = range end def next_data( data ) # バッファのデータを更新 @datas.push data @datas.shift if @datas.length > @range # バッファサイズが十分でなければ、nilを返す。 return nil if @datas.length != @range # 算出 return calculate(@datas) end def calculate(datas); end attr_reader :range end #===RSI class RSI < RangeSignal def initialize( range=14 ) super(range) end def calculate(datas) rsi( datas ) end end module_function #===RSIを得る。 # #RSI = n日間の値上がり幅合計 / (n日間の値上がり幅合計 + n日間の値下がり幅合計) * 100 #nとして、14や9を使うのが、一般的。30以下では売られすぎ70以上では買われすぎの水準。 # #datas:: 値の配列 #戻り値:: RSI値 def rsi( datas ) prev = nil tmp = datas.inject( [0.0,0.0] ) {|r,i| r[ i > prev ? 0 : 1 ] += (i - prev).abs if prev prev = i r } (tmp[0] + tmp[1] ) == 0 ? 0.0 : tmp[0] / (tmp[0] + tmp[1]) * 100 end end
RSIを表示するエージェントは以下。
#RSIを表示するエージェントのサンプル class RSISampleAgent < JIJI::PeriodicallyAgent def description "RSIを表示するエージェントのサンプルです" end def init @rsi = JIJI::Agent::Shared::Signal::RSI.new(@range) @out = output.get( "RSI", :graph, { :column_count=>1, :lines=>[30,70], :colors=>["#557777"] } ) end # 次のレートを受け取る def next_period_rates( rates ) res =@rsi.next_data( rates[:EURJPY].bid.end ) return unless res @out.put( res ) end # UIから設定可能なプロパティの一覧を返す。 def property_infos super().concat [ Property.new( "range", "集計期間", 25, :number ) ] end end
例によって、デモサイトにおいています。