無料で使えるシステムトレードフレームワーク「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

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