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

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

クリック証券で提供されている為替レートのヒストリカルデータを一括取得するスクリプト

クリック証券で提供されている、為替レートのヒストリカルデータを一括取得するスクリプトを書いてみました。クリック証券にアクセスしてデータのzipアーカイブを取得し、指定ディレクトリに展開します。

注意事項

    • ダウンロードするにはクリック証券のアカウントが必要です。
    • データの利用にあたっては、ヒストリカルデータの利用規約もご確認願います。

依存モジュール

実行には「mechanize」と「rubyzip」が必要です。

$ gem install mechanize
$ gem install rubyzip

スクリプト

「Download」モジュールがメイン。モジュールのAPIを利用して、2009年の1月から6月までのUSDJPYデータを取得します。

require 'rubygems'
require 'mechanize'
require 'zip/zip'

#
#==クリック証券のヒストリカルデータダウンロードサービスから為替レートデータを取得するユーティリティ。
#
module Download

  #===ダウンロードを行うためのセッションを開始する
  #userId:: クリック証券のユーザーID
  #password:: ログインパスワード
  #proxy:: プロキシ 
  def self.session( userid, password, proxy=nil )
    client = WWW::Mechanize.new {|c|
      # プロキシ
      if proxy 
        uri = URI.parse( proxy )
        c.set_proxy( uri.host, uri.port )
      end
    }
    client.keep_alive = false
    client.max_history=0
    client.user_agent_alias = 'Windows IE 7'
    
    # ログイン
    page = client.get("https://sec-sso.click-sec.com/loginweb/")
    raise "Unexpected Error" if page.forms.length <= 0
    form = page.forms.first
    form.j_username = userid
    form.j_password = password
    client.submit(form, form.buttons.first) 
    session = Session.new( client )
    if block_given?
      begin 
        return yield( session )
      ensure
        session.logout
      end
    else
      return session
    end
  end
  class Session
    def initialize( client )
      @client = client
    end
    #===CSVデータをダウンロードする
    #yesr:: 年
    #month:: 月
    #pair:: 通貨ペア
    #to:: ダウンロード先ディレクトリ
    def download( year, month, pair, to="./" )
      FileUtils.makedirs(to)
      file = "#{to}/#{pair}_#{year}_#{month}.zip"
      result = @client.get("https://tb.click-sec.com/fx/historical/historicalDataDownload.do?" + 
        "y=#{year}&m=#{month<=9 ? "0" + month.to_s : month}&c=#{C_MAP[pair]}&n=#{pair}" )
      open( file, "w" ) {|w| w << result.body }
      extract( file, to )
      FileUtils.rm(file)
    end
    #===ログアウトする
    def logout
      @client.get("https://sec-sso.click-sec.com/loginweb/sso-logout")
    end
    #===zipファイルを展開する。
    #zip:: zipファイル
    #dest:: 展開先ディレクトリ
    def extract( zip, dest )
      FileUtils.makedirs(dest)
      Zip::ZipFile.foreach(zip) {|entry|
        if entry.file?
          FileUtils.makedirs("#{dest}/#{File.dirname(entry.name)}")
          entry.get_input_stream {|io|
            open( "#{dest}/#{entry.name}", "w" ) {|w|
              while ( bytes = io.read(1024)) 
                w.write bytes
              end
            }
          }
        else
          FileUtils.makedirs("#{dest}/#{entry.name}")
        end
      }
    end
    C_MAP = {
      :USDJPY=>"01", :EURJPY=>"02", :GBPJPY=>"03",
      :AUDJPY=>"04", :NZDJPY=>"05", :CADJPY=>"06", 
      :CHFJPY=>"07", :ZARJPY=>"08", :EURUSD=>"09",
      :GBPUSD=>"10", :EURCHF=>"11", :GBPCHF=>"12",
      :USDCHF=>"13"
    }
  end
end

# ヒストリカルデータをダウンロードする
Download.session( "<ユーザーID>", "<パスワード>" ) {|s|
  # 2009年の1月から6月までのUSDJPYデータを取得する。
  1.upto(6) {|m|
    s.download( 2009, m,  :USDJPY,  "./2009-1_6" )
  }
}

さて、あとはjijiで使えるCSV形式に変換する処理を書けば、インポートツールとして提供できそうですな。