jijiについて
スクリーンショット
デモサイト
サポートしている証券会社
免責
コンタクト
準備するもの
インストールと設定
jijiを起動する
jijiを停止する
自動取り引きの流れ
1.エージェントの作成
2.バックテスト
3.テスト結果の確認
4.運用開始!
5.取り引き状況の確認
エージェントとは
初期化と実行の流れ
取り引きを行う
ログを出力する
グラフを描く
カスタマイズできるようにする
共有ライブラリ
エージェントのサンプル
APIリファレンス
ソースコード
テクニカルノート
作った人のブログ
バージョン2をリリースしました。新バージョンをぜひご利用ください。
FXシステムトレードフレームワーク「Jiji」
jijiについて

「jiji (ジジ) 」は、オープン・フリーのFX自動取引システムです。

  • 完全自動でのFX取引を実現
  • レートデータの取得から証券会社への発注まで、プログラミングしたルールに従った完全自動でのFX取引を実現します。
  • 注:「必ず利益が出せる取り引きルール」を提供するソフトウェアではありません。取り引きルールを作成・検証し、実際に運用を行うためのフレームワークです。
  • 取引ルールはRubyで
  • 取引ルールはオブジェクト指向プログラミング言語「Ruby」で記述します。
  • オブジェクト指向言語ですので、よく使う機能の部品化・再利用が容易に行えます。
  • バックテスト機能を搭載
  • 過去のデータを使用した取引ルールの検証(バックテスト)機能を実装済み。
  • 運用前に、実際のレートデータを使用して動作を確認しておくことが可能です。(※1)
  • 外出先からも操作可能
  • jijiはスタンドアロンなサーバーとして動作するWebアプリケーションです。
  • 自宅のマシンをサーバーとして公開しておくことで、外出先からの状況の確認やメンテナンスが可能。
  • 忙しいサラリーマンの方も安心してご利用いただけます。
  • オープン、フリー
  • 個人での非商用利用に限り、無償で利用できます。
  • ソースコードも Github - unageanu/jiji にて公開中。
※1.. バックテストを行なうには、一定期間「jiji」を起動して、レート情報を収集する必要があります。
jiji
スクリーンショット
※クリックで拡大します。
ローソク足チャート
ローソク足チャート:
ローソク足チャートで値動きを確認できます。取り引きルール(エージェント)でグラフを描くこともできます。
取り引き一覧
取り引き一覧:
バックテスト/リアルトレードで行った取引の一覧を表示。勝率や平均損益などの統計情報も確認可能。エージェントごとの集計もできます。
取り引きルール(エージェント)エディタ
取り引きルール(エージェント)エディタ:
オンラインでの作成・編集が可能。作成したエージェントはプログラムの再起動なしに利用できます。
バックテスト設定
バックテスト設定:
期間とエージェントを指定してバックテストを実行。複数のエージェントを同時にテストできます。
ログ
ログ:
エージェントが出力したログを表示します。エージェントのデバッグに利用できます。
サポートしている証券会社

「jiji」がサポートする証券会社は以下のとおりです。

証券会社
アクセス方式
クリック証券 スクレイピング (※2)
クリック証券デモトレード スクレイピング (※2)
SBI証券 スクレイピング (※2)
クリック証券デモトレード(※1) Webサービス

ご利用の際には、いずれかの証券会社のアカウントをご用意ください。

※1.. Webサービスの提供終了により、利用不可となりました。ご了承ください。
※2.. スクレイピング方式は証券会社のWebサイトを解析してレート情報の取得や発注を行う方式です。 このため、サイトの仕様変更などにより突然動作しなくなるリスクがあります。ご了承ください。
免責
本プログラムの利用は自己責任でお願いします。
プログラムの不備・不具合等によるあらゆる損害について、作成者は責任を負いません。
コンタクト

不具合やご意見・ご要望はブログのコメント またはメール( masaya.yamauchi@gmail.com )にてご報告いただければ幸いです。

準備するもの

「jiji」のインストールと実行には、以下のソフトウェアやアカウント情報が必要です。インストールの前にご用意下さい。

項目
詳細
Ruby バージョン1.8.7x
※Windows環境であれば、 ActiveScriptRuby や Cygwin版Ruby が利用可能です。
※バージョン1.9での動作は未確認です。
RubyGems バージョン1.3.3以降
※ActiveScriptRubyには標準で添付されていますが、バージョンが古いようなので以下の操作を別途実行しておく必要があります。
$ gem install rubygems-update
$ update_rubygems
$ gem install rake
$ gem install rspec
$ gem install cucumber
$ gem install hoe
Webブラウザ FireFox3 または InternetExplorer7
※InternetExplorer6では利用できません。
証券会社のアカウント サポートしている証券会社 のいずれかのアカウントが必要です。
インストール

gem経由でインストールできます。コンソールから以下のコマンドを実行してください。

 $ gem sources -a http://gems.github.com
 $ gem install gemcutter
 $ gem tumble
 $ gem install jiji
※UbuntuなどDebian系ディストリビューションの場合、デフォルトではRubyGemsの実行ファイル置き場がパスに含まれていないため、以下の操作を追加で行ってください。
$ export PATH=$PATH:/var/lib/gems/1.8/bin/
ActiveScriptRubyやCentOSなどredHat系ディストリビューションでは、この手順は不要です。

ダウンロートが完了したら初期設定を行ないます。「jiji」を実行するユーザーで以下のコマンドを実行してください。

$ jiji setting
> Please select a securities.
    1 : CLICK Securities
    2 : CLICK Securities DEMO
    3 : SBI Securities
1 ←アクセス先証券会社を選択
> Please input a user name of CLICK Securities.
xxx  ←ユーザー名を入力
> Please input a password of CLICK Securities.
**********  ←パスワードを入力
> Please input a proxy. example: https://example.com:80 (default: nil )
  ←(必要なら) 証券会社へのアクセスで使用するプロキシを入力
  (何も入力しなければ、プロキシは利用されません。)
> Please input a data directory of jiji. (default: ~/.jiji )
  ←データの保存先となるディレクトリを選択。デフォルトは「~/.jiji」
> Please input a server port. (default: 7000 )
  ←jijiが動作するポートを選択。デフォルトは「7000」

create. /home/xxx/.jiji
create. /home/xxx/.jiji/base
create. /home/xxx/.jiji/conf
Setting was completed!
※入力を失敗した場合は、「jiji setting」を再実行します。

ファイアウォールが有効な場合は、↑で指定したポートでの通信を許可する設定を追加で行って下さい。

jijiを起動する

「jiji」を起動するには、以下のコマンドを実行します。

 $ jiji start

起動後、Webブラウザから次のURLにアクセスできればOKです。

 http://<インストール先ホスト(ローカルマシンの場合、「127.0.0.1」でOK)>:<ポート>
※初回の起動直後は、レートデータがないため、ローソク足チャートは表示されません。
レートデータは起動しておけば自動で収集されますので、一定期間jijiを稼働させておくことで表示されるようになります。

動作していない場合は、以下に示すフォルダにあるログの内容をご確認ください。

 <データ保存先ディレクトリ>/logs
jijiを停止する

「jiji」を停止したい場合は、「stop」コマンドを実行します。

 $ jiji stop
自動取引のながれ
「jiji」での自動取引の流れは次の通りです。
  • 1.取り引きルール(エージェント)の作成
  • [エージェント]-[作成/編集]から取り引きルール(エージェント)を作成します。
  • 2.バックテスト
  • バックテストを実行し、作成したエージェントの動作を確認します。
  • 複数のエージェントを同時にテストすることが可能です。
  • 3.テスト結果の分析
  • テストの実行完了後、[バックテスト]-[結果を見る]から取引の結果を確認。
  • 満足できる結果が得られれば運用を開始します。そうでなければ1に戻ってエージェントのロジックを見直します。
  • 4.運用開始!
  • [リアルトレード]-[設定]でエージェントを登録し、運用を開始します。
  • 5.取り引き状況の確認
  • あとはエージェントによる自動取引を見守るだけ。
  • [リアルトレード]-[状況を見る]から現在の取引情報を確認できます。
  • 不測の事態が発生した場合は、全てのエージエントによる取引を緊急停止することも可能です。
エージェントの作成
[作成/編集]メニュー
[エージェント]-[作成/編集]メニュー
「jiji」では、「取引のルール」を「エージェント」と呼びます。 エージェントは、レート情報を受け取って分析・取引を行う機能を持つRubyのクラスで、 [エージェント] - [作成/編集] から作成できます。
※エージェントプログラムの書き方については、「エージェント作成ガイド」を参照ください。
エージェント編集画面
エージェント編集画面
エージェント編集画面
エージェント編集画面の使い方は以下の通りです。
1.エージェント一覧
作成済みのエージェントおよび共有ライブラリの一覧です。 「エージェント」ディレクトリ以下のファイルがエージェント、「共有ライブラリ」以下のファイルが共有ライブラリとみなされます。 ディレクトリファイルをダブルクリックするとエージェントのコードがエディタに表示されます。
2.ファイル/ディレクトリ追加ボタン
選択されているディレクトリ配下にファイルorディレクトリを追加します。ボタンを押すとダイアログが表示されるので、そこで追加するファイル名を入力します。
3.リネームボタン
選択されているファイルまたはディレクトリをリネームします。ボタンを押すとダイアログが表示されるので、そこで新しい名前を入力します。
4.削除ボタン
選択したファイルまたはディレクトリを削除します。
5.メッセージ領域
保存したコードに問題があった場合に、エラーの詳細が表示されるスペースです。
6.保存ボタン
編集したコードを保存します。コードに問題があった場合は、[メッセージ領域]にエラーの詳細が表示されます。
7.エージェントエディタ
選択したエージェントのRubyコードを編集するエディタ領域です。
バックテスト
[バックテスト]-[新規作成]メニュー
[バックテスト]-[新規作成]メニュー
エージェントができたら、バックテストで動作を検証します。
※バックテストを行なうには、レートデータが必要です。 一定期間「jiji」を稼働させ、データを収集しておく必要があります。
バックテストは[バックテスト]-[新規作成]から開始できます。
名前とメモ
期間
エージェント
バックテスト設定画面
バックテストで設定可能な項目は次のとおりです。
1.名前 (※入力必須)
バックテストの名前を入力します。
2.メモ
必要に応じてメモを残しておくことができます。 エージェントの設定に関する補足情報などを書いておけば、テスト結果画面から参照できます。
3.期間 (※入力必須)
テストの開始日、終了日をYYYY-MM-DDの形式( 例) 2009-01-01 )で設定します。 右にあるボタンでカレンダーが表示されるので、そこから選択することもできます。 レートデータが収集できている日はカレンダーの背景が「緑」で表示されます。
4.エージェント
バックテストで動作させるエージェントを選択します。
[追加]ボタンでエージェント選択ダイアログが表示されるので、テストしたいエージェントを選択して[OK]を押します。 エージェントは複数追加することができます。
追加したエージェントを選択すると右のパネルに詳細が表示されます。エージェントの名前やプロパティの設定は詳細パネルから行ないます。
エージェント
開始ボタン
テストの設定を行なったら[開始]ボタンでテストを開始します。
テストの進捗状況は左側のサイドバーで確認可能です。また、[削除]で実行をキャンセルできます。
3.テスト結果の確認
[バックテスト]-[結果を見る]メニュー
[バックテスト]-[結果を見る]メニュー
バックテストの実行が完了したら、テスト名のリンクからテスト結果を参照できるようになります。 以下にテスト結果の各画面の説明を示します。
ローソク足チャート
ローソク足チャート
ローソク足チャート
ローソク足チャート
ローソク足チャート
ローソク足チャートを表示する画面です。 エージェントが取引を行なった時刻をレートの推移とあわせて確認できます。 また、エージェントでグラフを描いている場合、それもローソク足チャート上で表示できます。
1.スクロールバー
チャートの表示範囲を設定します。チャートをドラッグしてもスクロールは可能ですが、期間を一気に移動したい場合はスクロールバーが便利です。
2.自動更新
リアルトレードのレートを表示している場合に、チャートを定期的に最新の状態に更新する機能です。 バックテストの結果を表示している場合は、グレーアウトします。
3.通貨ペア・スケール選択
表示する通貨ペアとスケールをドロップダウンリストで選択します。
4.情報ウインドウ
マウスが示す位置のレート情報や損益の状態を表示するウインドウです。
カソール位置の始値/終値,日時,Y座標のレート、決済済み/未決済の損益情報などが確認できます。
5.グラフ
エージェントが描画したグラフがあればそれを表示します。後述の[グラフの設定]で、表示・非表示 の切り替えや、色の変更が可能です。
6.取引
エージェントが行なった取引を表示します。赤はプラス/青はマイナス、○(白抜きの丸)は売/●(塗りつぶされた丸)は買です。 カーソルをあわせると詳細が確認可能です。
※取引はプラス、マイナスそれぞれ最大6個まで表示されます。 6つ以上の取引があった場合、7つめ以降の取引は表示されません。
7.損益グラフ
損益状態を示すグラフです。取引表示領域の背景に描かれます。 未決済の取引を含む推移は紫の線グラフで、決済済みの損益は縞模様の領域で示されます。
[取引一覧],[設定を見る],[ログ]メニュー
[取引一覧],[設定を見る],[ログ]メニュー
取引一覧
取引の一覧と統計情報(損益の合計、勝率など)を表示します。 エージェントごとの統計も確認可能です。
設定を見る
テストの期間や動作させたエージェントのプロパティを確認します。 作成時に設定したメモもここから参照できます。
ログ
テスト中に出力されたログを表示します。
グラフの設定
グラフの設定
グラフの設定
ローソク足チャートで表示するグラフを設定します。 チャックボックスで表示/非表示の切り替えができます。 また、色のボックスをクリックするとカラーピッカーが表示され、 グラフの色を変更できます。
収益
収益
バックテストで満足いく結果が得られたら運用に移ります。 そうなるまでは、1に戻ってエージェントロジックの見直しとテストを繰り返します。
jijiについて
[リアルトレード]-[設定]メニュー
[リアルトレード]-[設定]メニュー
安定した収益を上げられるエージェントが完成したら、運用を開始します。 運用を開始するには、[リアルトレード]-[設定]でエージェントを登録します。
リアルトレード設定画面
リアルトレード設定画面
リアルトレード設定画面で編集可能な項目は次の2つです。
1.自動取引の設定
証券会社にアクセスして発注を行なうかどうかを設定します。 onにすると発注が行なわれ、offにすると証券会社への発注は行なわれません。
取引を強制的に禁止したい場合、offにします。これにより全てのエージェントの取引を緊急停止できます。 現在所有している建玉はそのまま残されますので、必要に応じて手動で決済してください。
※offにした場合、停止となるのは「証券会社への発注のみ」です。 「jiji」上ではエージェントは動作し、取引を行ないます。(要は、バックテスト中のような状態になります。)
2.エージェント
リアルトレードで動作させるエージェントを登録します。利用方法はバックテストでのエージェント登録画面と同じです。
適用ボタン
適用ボタン
エージェントを登録後、[適用]ボタンを押すと、設定が反映されエージェントの実行が開始されます。
取引状況の確認
[リアルトレード]-[状況を見る]メニュー
[リアルトレード]-[状況を見る]メニュー
チャートの自動更新機能
取引一覧の範囲指定
チャートの自動更新機能,取引一覧の範囲指定
エージエントの運用状況は、[リアルトレード]-[状況を見る]から確認できます。 機能はバックテスト結果画面とだいたい同じですが、以下の2点が異なります。
1.チャートの自動更新機能
チャートの自動更新機能が有効化され、自動的にチャートの更新が行なわれます。 offにすることもできます。
2.取引一覧の範囲指定
取引一覧において、期間での絞り込みができるようになります。 期間を設定後「最新の状態に更新」で一覧が更新されます。 デフォルトでは「過去一週間分のデータ」を表示します。
取引状況の確認
「エージェント」とは、レート情報を受け取って取引を行うRubyのクラスです。 プログラミングにより、以下の処理を行なうことが可能です。
  • 移動平均など各種シグナルの計算
  • シグナルに基づくFX取引(売り・買い・決済)
  • グラフの描画
  • ログの出力(デバッグ用)
「jiji」では「Agent」モジュールをインクルードしたクラスがエージェントとして認識されます。 また、「PeriodicallyAgent」を継承して作成することも可能です。
 
Agent
PeriodicallyAgent
説明
「エージェント」を示すモジュールです。 このモジュールをincludeしたクラスが「エージェント」となります。 一定期間の4本値(始値/終値/高値/安値)を処理するエージェントを簡単に作成するための基底クラスです。 「jiji」では一定期間(デフォルトは10秒)ごとにレート情報を取得しエージェントに通知します。 このため、4本値を算出するためには、エージェントで一定期間レート情報を蓄積し集計する必要があります。 「PeriodicallyAgent」を継承してエージェントを作成すると、この蓄積と集計機能を簡単に実装できます。
種別
モジュール クラス
JIJI::Agent と JIJI::PeriodicallyAgent
エージェントのライフサイクル
エージェントの初期化と実行の流れを以下に示します。バックテストを開始した場合や、エージェントをリアルトレードに登録した場合、以下の順番でエージェントのメソッドが呼び出されます。
エージェントの初期化と実行の流れ
エージェントの初期化と実行の流れ
各メソッドの詳細は次のとおりです。APIリファレンスもあわせて参照ください。
メソッド
説明
引数
initialize エージェントのコンストラクタです。
バックテストやリアルトレードでエージェントが使用されると、最初に実行されます。
※この段階では、後述するoperatorやloggerは未設定ですので利用できません。
引数なしで呼び出されます。エージェントのコンストラクタは引数なしで呼び出せるようにしておく必要があります。
properties=(props) エージェントのプロパティを設定するメソッドです。
エージェント登録時に設定したプロパティが「プロパティIDをキー、プロパティ値を値とするハッシュ」で渡されます。 デフォルトの実装では、各キーの値をエージェントのインスタンス変数に設定します。
def properties=( properties )
  @properties = properties
  properties.each_pair {|k,v|
    instance_variable_set("@#{k}", v)
  }
end 
オーバーライドして任意の処理を行うことも可能です。
props .. 設定されたプロパティ。「プロパティIDをキー、プロパティ値を値とするハッシュ」で指定されます。
operator=(operator), logger=(logger), outputs=(outs) 取り引きで使用するOperatorやログ出力用のLogger等が設定されます。 operatorやloggerの各インスタンス
init エージェントを初期化します。
コンストラクタでも初期化は可能ですが、initではoperatorやlogger,outputが利用可能です。 必要に応じてオーバーライドして、処理を記述します。
なし
next_rates(rates), next_period_rates(rates) レート情報が通知されるメソッドです。
「Agent」をincludeしたエージェントの場合「next_rates(rates)」、 「PeriodicallyAgent」を継承したエージェントの場合「next_period_rates(rates)」 が、エージェントが動作している間順次呼び出されます。 エージェントでは、このメソッドをオーバーライドして、シグナルの計算や取り引きを行うロジックを書きます。

リアルトレードでは、一定期間(デフォルトは10秒)ごとにレート情報が取得され、このメソッドが実行されます。 (PeriodicallyAgentの場合は、一定期間のレートデータが集計され、4本値に変換されたものが渡されます。) バックテストでも同様に読み込んだレートデータが順次渡されてきます。
rates .. レート情報。next_rates()ではRates、next_period_rates()ではPeriodicallyRatesが渡されてきます。それぞれ以下のようなコードで情報にアクセス可能です。
# JIJI::Ratesの場合
r = rates[:EURJPY]
r.bid #bidレート
r.ask #askレート
r.sell_swap #売スワップ
r.buy_swap #買スワップ

# JIJI::PeriodicallyRatesの場合
# ※同様にask等にもアクセス可。
r = rates[:EURJPY]
r.bid.start #始値
r.bid.end #終値
r.bid.max #高値
r.bid.min #安値 
初期化・実行で呼ばれるエージェントのメソッド一覧
補足1: 実行中にエージェントを編集した場合の動作について
エージェントをバックテストやリアルトレードで動作させている状態でコードを改変しても、 実行中のエージェントのコードには反映されません。 実行中のエージェントは現在のロジックのまま動作を継続します。
改変後のエージェントは、新規にバックテストを開始した場合、またはリアルトレードに新規に登録した場合に有効となります。
補足2: セーフレベル
安全性確保のため、エージェントのすべてのメソッドは、デフォルトではセーフレベル4で実行されます。 このため、初期値のままでは、エージェントでネットワーク通信やファイル入出力を行うことはできません。 (ただし、operatorやloggerを使用した通信やログの入出力は特別に許可されており可能です。) 上記操作をエージェント内で行えるようにするには、「~/.jiji/conf/configuration.yaml」に以下を追加します。
---
server:
 port: 8080
(..中略)

agent:
  safe_level: 0 ←セーフレベルを「0」に設定
取り引きを行う
取り引きを行うには、 operator を使用します。 operator は Agent のインスタンス変数として初期化時に設定されます。以下は operator のAPIを呼び出して取引を行なう例です。
sell_position = @operator.sell(1, :EURJPY) # 売り
buy_position  = @operator.buy(1, :EURJPY) # 買い
@operator.commit( sell_position ) # 決済
成り行きでの売/買および、決済操作が可能です。operator APIの詳細は以下の表を参照下さい。
メソッド
説明
引数
戻り値
buy(count,pair) 買い注文を行います。 count .. 取引数量。「指定した値*通貨単位」が実際の取引数になります。 たとえば、USDJPYは単位が10,000ですので、10,000単位取引したいときは「1」を指定します。
pair .. 取引する通貨ペアを示すシンボル。次のいずれかの値が指定可能です。
:USDJPY, :EURJPY, :GBPJPY, :AUDJPY,
:NZDJPY, :CADJPY, :CHFJPY, :ZARJPY,
:EURUSD, :GBPUSD, :AUDUSD, :EURCHF,
:GBPCHF, :USDCHF
省略した場合、「:EURJPY」 が使用されます。
建玉(Position)
sell(count,pair) 売り注文を行います。 count .. 取引数量。
pair .. 取引する通貨ペアを示すシンボル。指定可能な値は買い注文と同じです。
建玉(Position)
commit(position) 建玉を決済します。 position .. 決済する建玉。sellまたはbuyで返されたオブジェクトを指定します。 なし
positions 現在保持している建玉の一覧を取得します。
※同時に動作している他のエージェントの建玉は含まれません。また、決済した建玉も含まれません。
なし 現在保持している建玉の一覧。建玉IDをキー、建玉オブジェクトを値とするハッシュです。
operator のメソッド一覧
売/買操作では建玉オブジェクト(Position)が返されます。 建玉オブジェクトからは購入レートや現在の損益が取得できます。
# 建玉
p = @operator.sell( 1, :EURJPY )

p.position_id # 一意な識別子
p.sell_or_buy # 買(JIJI::Position::BUY) or 売(JIJI::Position::SELL)

# 状態。以下のいずれかになります。
#   - 注文中     .. JIJI::Position::STATE_WAITING
#   - 新規       .. JIJI::Position::STATE_START
#   - 決済注文中 .. JIJI::Position::STATE_FIX_WAITING
#   - 決済済み   .. JIJI::Position::STATE_FIXED
#   - ロスト     .. JIJI::Position::STATE_LOST
#     (決済前にシステムが再起動された場合、ロスト状態になります)
p.state

p.date # 購入日時
p.fix_date # 決済日時
p.count # 取引数量
p.price # 取得金額
p.current_price # 現在価値
p.profit_or_loss # 現在の損益
p.rate     # 購入時のレート
p.fix_rate # 決済時のレート
p.swap     # 累計スワップ
p.pair     # 通貨ペア( :EURJPYのようなシンボル )
ログを出力する
loggerを利用して、任意の文字列をログファイルに出力することが可能です。 発生したエラーやデバッグ情報の記録に利用できます。
# ログを出力。loggerはagentのインスタンス変数です。
@logger.debug "test"
@logger.info "info"
@logger.warn "warn"
loggerのAPIについては、Ruby リファレンスマニュアル - Loggerを参照下さい。
出力したログは、バックテストやリアルトレードの結果画面から確認できます。↑のサンプルであれば以下のログが出力されます。
D, [2009-03-18T07:26:31.612000 #7696] DEBUG -- : test
I, [2009-03-18T07:26:31.617000 #7696]  INFO -- : info
W, [2009-03-18T07:26:31.622000 #7696]  WARN -- : warn
グラフを描く
エージェントでグラフデータを出力しておくことで、 ローソク足チャートにグラフを描くことができます。 移動平均線やMACDなどをグラフとして表示して、エージェントの動作検証に利用できます。
グラフを描く
グラフを描くには、output を使用します。必要な手順は次の通りです。
  1. 「output.get( name,type,options)」で、名前やオプションを指定してグラフの出力先(GraphOut)を作成
  2. 「GraphOut#put(numbers)」でグラフデータを出力
# output から出力先を作成。
# 1つ目の引数は、グラフの名前
# 2つ目は「:graph」を固定で指定する
# 3つ目の引数で、グラフの設定情報を指定する。(詳細後述)
@out = output.get( "移動平均線", :graph, {
  :column_count=>2, # データ数は2
  :graph_type=>:line, # 線グラフ
  :lines=>[30,40,50], # 30,40,50のメモリを描く
  :colors=>["#779999","#557777"] # デフォルトのグラフの色
})

...(略)

# グラフのデータを出力。
# 出力先作成時にデータ数は2としているので、2つのデータを指定可能。
@out.put( 33, 39 )
@out.put( 45, 43 )
@out.put( 60, 69 )
グラフのオプション
「output.get( name,type,options)」のoption引数として指定可能なパラメータを以下に示します。
オプション
説明
:column_count グラフのカラム数を整数値で指定します。設定必須です。
:graph_type グラフの種類を指定します。以下の値のいずれかが設定可能です。
:rate .. グラフをレート情報に重ねて表示します。移動平均線やボリンジャーバンド向けです。
:zero_base .. 0を中心線とした線グラフとして表示します。RCIやMACD向けです。
:line .. 通常の線グラフとして描画します。

各値でのグラフの表示イメージは、下の画像を参照ください。値を指定しない場合、:lineが指定されたと見なされます。
:lines グラフの背景に描画するy軸のメモリを配列で指定します。グラフの種類が zero_base,lineの場合のみ有効です。
:colors グラフの色を"#FFFFFF"形式の配列で指定します。 値を指定しない場合、グラフは#557777で描かれます。
option のキー一覧
rate
:rate のグラフ
zero_base
:zero_base のグラフ
line
:line のグラフ
カスタマイズできるようにする
規定のメソッドを実装することで、カスタマイズ可能なプロパティや表示される説明を設定できます。
プロパティの入力を受け付ける

カスタマイズ可能なプロパティを追加するには、 property_infos を実装し、UIから設定可能なプロパティの一覧情報(JIJI::Agent::Propertyの配列)を返すようにします。

# UIから設定可能なプロパティ(JIJI::Agent::Property)の一覧を返す。
def property_infos
  return [
    # ID, 表示名,初期値,型の順で指定する。
    Property.new( "short", "短期移動平均線", 25, :number ),
    Property.new( "long",  "長期移動平均線", 75, :number ),
    Property.new( "pair",  "取り引きする通貨ペア", "EURJPY", :string )
  ]
end

これにより、エージェント選択時にUIからプロパティを設定できるようになります。設定されたプロパティは、 「properties=(props)」メソッドでエージェントに設定されます。

※「PeriodicallyAgent」では、property_infos が実装されており、4本値を作成する期間を指定できるようになっています。 このため、「PeriodicallyAgent」を継承して作成したエージェントで property_infos をオーバーライドする場合、 以下のように記述する必要があります。
def property_infos
  # 親クラスの property_infos を呼び出した結果に、自身のプロパティを追加して返す。
  super().concat [
    Property.new( "short", "短期移動平均線", 25, :number ),
    Property.new( "long",  "長期移動平均線", 75, :number )
  ]
end

プロパティ(JIJI::Agent::Property)のコンストラクタ引数は以下のとおりです。

番号
引数
説明
1 ID プロパティの識別子を指定します。設定必須です。 IDは「properties=(props)」メソッドの引数として渡されるハッシュのキーとなります。
2 表示名 UIで表示する設定値の表示名を設定します。設定必須です。
3 初期値 プロパティの初期値を指定します。
4 型 プロパティの型を指定します。以下の値のいずれかが設定可能です。
:string .. 文字列です。プロパティ値として任意の文字列が設定可能です。
:number .. 数値を示します。プロパティ値として数値(負数,少数を含む)のみ設定可能です。 「properties=(props)」で渡されるハッシュの値も数値型になります。

値を指定しない場合、:stringが指定されたと見なされます。
JIJI::Agent::Propertyのコンストラクタ引数一覧
説明のカスタマイズ

descriptionメソッドをオーバーライドすることでエージェントの説明を指定できます。

# エージェントの説明  
def description
  <<-STR
移動平均を使うエージェントです。 
  -ゴールデンクロスで買い&売り建て玉をコミット。 
  -デッドクロスで売り&買い建て玉をコミット。      
STR
end
共有ライブラリ
共有ライブラリとは、全てのエージェント間で共有される関数やクラスを定義するファイルです。 エージェントでよく使う機能や関数を共有ライブラリに定義しておくことで、複数のエージェントでそれを再利用できます。
共有ライブラリを作る
共有ライブラリは、[エージェント]-[作成/編集]から作成できます。ファイル一覧で「共有ライブラリ」以下に作成されたファイルが共有ライブラリとみなされます。
※共有ライブラリのコードを変更した後、次にライブラリ内のクラスや関数を利用した場合に、新しいコードが使用されます。 変更前に作成したインスタンスがあっても、その動作は変更されません。変更後に作成したインスタンスから新しいコードが使用されます。
共有ライブラリを使う
共有ライブラリの内容は「JIJI::Agent::Shared」モジュール以下に定義されます。 たとえば以下のコードが書かれた共有ライブラリがある場合、
# クラス
class Foo
  def foo
   "foo."
  end
end
# 関数。「self.」をつけること。
def self.hoge
  "hoge"
end
エージェントで「JIJI::Agent::Shared::Foo」とすることで、共有ライブラリのクラスを利用できます。
 #共有ライブラリのクラスを利用
 foo = JIJI::Agent::Shared::Foo.new
 logger.info foo.foo
 #共有ライブラリの関数を利用
 logger.info JIJI::Agent::Shared.hoge
添付の共有ライブラリ
標準添付の共有ライブラリとして以下が用意されています。
クラス(定義されているファイル)
説明
JIJI::Agent::Shared::Signal
(system/signal.rb)
移動平均やMACDなど、各種トレードシグナルを算出するライブラリです。
JIJI::Agent::Shared::PositionManager
(system/position_manager.rb)
ポジションの管理クラス。以下の機能を提供します。
  • 条件にマッチするポジションを探す。
  • すべてのor条件にマッチするポジションを決済する。
  • 指定したポジションを損切りorトレーリングストップで決済する。
JIJI::Agent::Shared::Cross
(system/cross.rb)
指標の交差状態(クロスアップ/クロスダウン)を判定するためのユーティリティです。
添付の共有ライブラリ一覧
エージェントのサンプル
以下は、移動平均を使って取り引きを行うエージェントのサンプルです。
共有ライブラリ「MovingAverage」を利用して移動平均を算出し、デッドクロスで売、ゴールデンクロスで買注文を行います。 また、算出した移動平均値をグラフに出力します。
#
# 移動平均を使うエージェント。
# -ゴールデンクロスで買い。
# -デッドクロスで売り。
#
class MovingAverageAgent < JIJI::PeriodicallyAgent

  # エージェントの説明
  def description
      <<-STR
移動平均を使うエージェントです。
 -ゴールデンクロスで買い&売り建て玉をコミット。
 -デッドクロスで売り&買い建て玉をコミット。
      STR
  end
  
  # エージェントを初期化する。
  def init
    # 移動平均の算出クラス
    # 共有ライブラリのクラスを利用。(JIJI::Agent::Sharedモジュールに定義される。)
    @mvs = [
      JIJI::Agent::Shared::MovingAverage.new(@short),
      JIJI::Agent::Shared::MovingAverage.new(@long)
    ]
    @prev_state = nil
    
    # 移動平均をグラフで表示するためのOutput
    @out = output.get( "移動平均線", :graph, {
      :column_count=>2, # データ数は2
      :graph_type=>:rate, # レートにあわせる形式で表示
      :colors=>["#779999","#557777"] # デフォルトのグラフの色
    } )
  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 )
    
    # ゴールデンクロス/デッドクロスを判定 
    state = res[0] > res[1] ? :high : :low
    if ( @prev_state && @prev_state != state ) 
      if state == :high
        # ゴールデンクロス
        # 売り建玉があれば全て決済
        operator.positions.each_pair {|k,p|
          operator.commit(p) if p.sell_or_buy == JIJI::Position::SELL
        }
        # 新規に買い
        operator.buy 1
      else
        # デッドクロス
        # 買い建玉があれば全て決済
        operator.positions.each_pair {|k,p|
          operator.commit(p) if p.sell_or_buy == JIJI::Position::BUY
        }
        # 新規に売り 
        operator.sell 1
      end
    end
    @prev_state = state
  end  
  
  # UIから設定可能なプロパティの一覧を返す。
  def property_infos
    super().concat [
      Property.new( "short", "短期移動平均線", 25, :number ),
      Property.new( "long",  "長期移動平均線", 75, :number )
    ]
  end

end
共有ライブラリ「MovingAverage」のソースは次のとおりです。
# 一定期間の移動平均を得る
class MovingAverage
  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 MovingAverage.get_moving_average(@rates)
  end

  # 前の結果(引数で指定した件数だけ記録。)
  attr :prev, true
  
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  
end
APIリファレンス
エージェントおよび添付の共有ライブラリのAPIについてはこちらを参照ください。
ソースコード
ソースコードは Github - unageanu/jijiにて公開しています。
テクニカルノート
  • 証券会社プラグイン作成ガイド
  • 収集した為替レートのCSVファイルを再利用する。
  • 収集した為替レートをJSON-RPCで取得する。
  • クリック証券で提供されている為替レートのヒストリカルデータをjijiに取り込むスクリプト
  • スクリプトからバックテストの実行と結果の取得を行う。
  • 認証と通信内容の暗号化機能を追加する(CentOS編)。
    (※jiji単体では未サポートですがApacheと連携させることで機能を実現できます。)
  • 認証と通信内容の暗号化機能を追加する(Ubuntu編)。
  • プラグインローダーの仕組み
作った人のブログ
作った人のブログはこちら。 更新情報や最新の技術情報はブログにて。
jijiについて | インストール | 使い方 | エージェント作成ガイド | APIリファレンス | 技術情報 | 免責 | コンタクト