無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

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

ボリンジャーバンドを算出する

クリック証券のスクレイピング版プラグインもだいぶできつつある(現在稼動テスト&デバッグ中)ので、ぼちぼち組み込みのライブラリを充実させて簡単にエージェントを作れるようにしていきたい。ということで、とりあえずボリンジャーバンドを算出するライブラリを書いてみました。jiji添付の「MovingAverage」と同じような形で使えます。

# ボリンジャーバンドを得る
class BollingerBands
  
  #コンストラクタ
  #range:: 集計期間
  def initialize( range=25, pivot=[0,1,2] )
    @rates = [] # レートを記録するバッファ
    @range = range
    @pivot = pivot
  end

  def next_rate( rate )
    # バッファのデータを更新
    @rates.push rate
    @rates.shift if @rates.length > @range
    
    # バッファサイズが十分でなければ、nilを返す。
    return nil if @rates.length != @range
    
    # ボリンジャーバンドを算出
    return BollingerBands.get_bollinger_bands(@rates, @pivot)
  end

private

  # 移動平均値を計算する。 
  def self.get_moving_average( rates )
    total = 0
    rates.each {|s|
      total += s.end
      total += s.max
      total += s.min
    }
    return total / ( rates.length * 3 )
  end  

  #===ボリンジャーバンド値を得る。
  #
  # TP(ティピカルプライス)=(高値+安値+終値)÷3
  # +2σ=TPの移動平均+標準偏差×2
  # +σ=TPの移動平均+標準偏差
  # -σ=TPの移動平均-標準偏差
  # -2σ=TPの移動平均-標準偏差×2
  # 標準偏差=√{(各TP−TPの期間中平均値)の2乗を期間分全部加えたもの}÷期間
  # (√は式全体にかかる)
  #
  #rates:: 値を取得する範囲の株価の配列 25が一般的。
  #range:: 標準偏差の倍数。初期値[0,1,2]
  #戻り値:: ボリンジャーバンドの各値の配列。例)  [+2σ, +1σ, TP, -1σ, -2σ]
  #
  def self.get_bollinger_bands( rates, range=[0,1,2] )
    ma = get_moving_average( rates )
    total = rates.inject(0.0) {|t,s|
      t+= (( (s.end + s.max + s.min ) / 3 ) - ma ) ** 2
      t
    }
    sd = Math.sqrt((total / rates.length))
    res = []
    range.each { |r|
      res.unshift( ma + sd * r )
      res.push( ma + sd * r * -1 ) if r != 0
    }
    return res
  end
end

利用側のエージェントは以下。取引はせず、グラフデータの出力のみ行っています。

#ボリンジャーバンドを使うエージェントのサンプル
class BollingerBandSampleAgent < JIJI::PeriodicallyAgent

  def description
      <<-STR
ボリンジャーバンドを使うエージェントのサンプルです。
      STR
  end
  
  # エージェントを初期化する。
  def init
    @bollinger_band = JIJI::Agent::Shared::BollingerBands.new(@range)
    
    # 移動平均をグラフで表示するためのOutput
    @out = output.get( "ボリンジャーバンド", :graph, {
      :column_count=>5,
      :graph_type=>:rate, 
      :colors=>["#779999","#557777","#335555","#557777", "#779999"]
    } )
  end
  
  # 次のレートを受け取る
  def next_period_rates( rates )
    res =@bollinger_band.next_rate( rates[:EURJPY].bid )
    return unless res
    
    @out.put( *res )
  end  
  
  # UIから設定可能なプロパティの一覧を返す。
  def property_infos
    super().concat [
      Property.new( "range", "集計期間", 25, :number )
    ]
  end

end

デモサイトにも置いたので遊びたい方はどうぞ。