なりさんBLOG

金融・FIXプロトコルの相談。いつでも承ります。機械学習のコンテンツを充実させてきます。

FIXアプリを作ってみる

OverView

 

FIXのアプリケーションをモデル化すると、主に3つに分かれます。

  • FIX Message

やりとりされるメッセージオブジェクト。

  • FIX Session

ハートビートや送受信などを管理する。FIX Messageを取り扱う。送受信の結果をFIX Clientに伝える。

  • FIX Client

新規注文・約定などのビジネスレベルのロジックを組み込む。FIX SessionおよびMessageを取り扱う。

FIX Message

まずは、きわめてLowLevelなところからモデル化。

Tag=Value のモデルをFieldクラスという形にすると以下。

public class Field {
 private int tag;
 private String value;
 
 
 public Field(int i, String format) {
 // TODO Auto-generated constructor stub
 tag=i;
 value=format;
 
 }
 public int getTag() {
 return tag;
 }
 public void setTag(int tag) {
 this.tag = tag;
 }
 public String getValue() {
 return value;
 }
 public void setValue(String value) {
 this.value = value;
 }
 public String toString(){
 return String.valueOf(tag)+"="+value;
 }
}

 

本来ならばTagという形のEnumで作るべきだが、今回はカスタムタグなどを簡単に指定できるように、intで定義した。
ちなみに、TagのENUMクラスを作るとこんな感じ。

public enum Tag {
 VERSION(8),MSGTYPE(35);
 private int tagNo;
 
 private Tag(int _tagNo){
 tagNo=_tagNo;
 }
 public int getTagNo() {
 return tagNo;
 }
 
 public String toString(){
 return String.valueOf(tagNo);
 }
}

 

Filedが繰り返し集まったものがFIX Message。また別の見方では、FIX Messageはヘッダー、ボディ、トレーラーの3つの部分に分けられる。

そのため、Messageクラスは以下のようになる。

import java.util.ArrayList;
public class FieldList extends ArrayList<Field>{
 private static final long serialVersionUID = 1L;
}
public class FixMessage {
 private String msgType;
 private FieldList header;
 private FieldList body;
 private FieldList trailer;
 public byte SOH = 0x01;
 public FixMessage(String msgType, FieldList header, FieldList body, FieldList trailer) {
 super();
 this.msgType = msgType;
 this.header = header;
 this.body = body;
 this.trailer = trailer;
 }
 public String toString(){
 return null;
 }
 public FixMessage() {
 // TODO Auto-generated constructor stub
 }
}

 

メッセージタイプを含めるか悩んだが、メッセージタイプはメッセージの扱い方を大きく左右するため明示的に指定させることにしてみた。

FIX Session

ハートビートや送受信などを管理する。FIX Messageを取り扱う。送受信の結果をFIX Clientに伝えること。

ここで、どんなClientが来るかわからないので、Obserberデザインパターンを使う。

また仕組みが複雑になってくるのと今後の拡張を踏まえて、Interfaceを作成して、それに実装していく。

 

 

 

public class FixSession {
 public enum Status {
 STOP, READY, START, LOGGED, CLOSING,WAITING_LOGON;
 }
 public enum Direction {
 OUT, IN
 }
 private Socket socket;
 private String version;
 private String senderCompID;
 private String targetConmID;
 private int seqNum = 1;
 private String host;
 private int port;
 private int HB = 30;
 private int sleepIntvl = 10000;
 InputStream is;
 BufferedReader bufreader;
 BufferedWriter bufwriter;
 private FixClient fixClient;
 BufferedInputStream bufIS;
 public Status status;
 public Boolean logged = false;
 public FixSession(String host, int port, String version,
 String senderCompID, String targetConmID, int HB,
 FixClient fixClient) throws UnknownHostException, IOException {
 super();
 this.host = host;
 this.port = port;
 this.version = version;
 this.senderCompID = senderCompID;
 this.targetConmID = targetConmID;
 this.fixClient = fixClient;
 this.HB = HB;
 socket = new Socket(host, port);
 is = socket.getInputStream();
 bufIS = new BufferedInputStream(is);
 bufreader = new BufferedReader(new InputStreamReader(is));
 bufwriter = new BufferedWriter(new OutputStreamWriter(socket
 .getOutputStream()));
 status = FixSession.Status.READY;
 System.out.println("Socket Ready.");
 this.status=Status.START;
 }
 public synchronized void sendMsg(String msg) throws IOException {
 bufwriter.write(msg);
 System.out.println("out:" + msg);
 bufwriter.flush();
 fixClient.notify(msg, Direction.OUT);
 seqNum++;
 }
 public void close() throws IOException {
 bufreader.close();
 socket.close();
 }
 private void sendHB() throws IOException {
 sendMsg(FixMsgFactory.generateAdminFixMsg(FixConstraints.MsgType.HB, this));
 }
 public void checkLogOnMsg() {
 }
 private void sendLogOn() throws IOException{
 String msg = FixMsgFactory.generateAdminFixMsg(FixConstraints.MsgType.LOGON,
 this);
 sendMsg(msg);
 status=Status.WAITING_LOGON;
 }
 
 
 public void connect() throws IOException, InterruptedException {
 if(status==Status.START)sendLogOn();
 
 while (is.available() == 0)
 Thread.sleep(100);
 
 while (status == Status.WAITING_LOGON && !socket.isClosed()) {
 byte[] data = new byte[is.available()];
 is.read(data, 0, is.available());
 if (data.length == 0) {
 // System.out.println("sleeping");
 Thread.sleep(sleepIntvl);
 continue;
 }
 System.out.println("in:" + new String(data, "EUC_JP"));
 HashMap<Integer, String> rcv_msg = FixMsgFactory.getTagSet(
 new String(data), String.valueOf(FixConstraints.SOH));
 MsgType msgType = MsgType.getMsgType(rcv_msg.get(35));
 
 if (msgType != null) {
 switch (msgType) {
 case LOGON:
 status=Status.LOGGED;
 break;
 case LOGOUT:
 sendLogOn();
 break;
 }
 }
 }
 int HBcount = 0;
 while (status != Status.CLOSING && !socket.isClosed()) {
 byte[] data = new byte[is.available()];
 is.read(data, 0, is.available());
 if (data.length == 0) {
 // System.out.println("sleeping");
 Thread.sleep(sleepIntvl);
 if (HBcount++ * sleepIntvl > HB * 900) {
 sendHB();
 HBcount = 0;
 }
 continue;
 }
 System.out.println("in:" + new String(data, "EUC_JP"));
 
 fixClient.notify(new String(data), Direction.IN);
 }
 }
 public String getHost() {
 return host;
 }
 public int getPort() {
 return port;
 }
 public int getHB() {
 return HB;
 }
 public int getSeqNum() {
 return seqNum;
 }
 public void setSeqNum(int seqNum) {
 this.seqNum = seqNum;
 }
 public String getVersion() {
 return version;
 }
 public String getSenderCompID() {
 return senderCompID;
 }
 public String getTargetConmID() {
 return targetConmID;
 }
}

 

  1. ropa de bebe online 2014.04.12 12:15pm

    I truly love your website.. Pleasant colors & theme.

    Did you make this website yourself? Please reply back as I’m
    planning to create my very own website and would like to learn where you got this from or what
    the theme is called. Thanks!

    • 0
    • 0
  2. Dorothea 2014.04.23 10:54pm

    Everything is very open with a precise description of the issues.
    It was truly informative. Your site is extremely helpful. Thank you for sharing!

    • 0
    • 0
  3. google 2014.05.08 4:56pm

    This design is steller! You most certainly know how to keep a reader entertained.
    Between your wit and your videos, I was almost moved to start my own blog (well, almost…HaHa!)
    Excellent job. I really enjoyed what you had to say, and more than that, how you
    presented it. Too cool!

    • 0
    • 0

This blog is kept spam free by WP-SpamFree.

柳原尚史(なりさん)


AIソリューション開発、Ridge-iの代表をやっています。
旧姓が成行であだ名がずっとなりさんだったので、なりさんです。

証券アナリスト持っています。債券取引と株DMA・アルゴが得意分野。

もっぱらの趣味は、トレイルランニングとプログラミング。
UTMB2014/2015完走(フランスのモンブラン一周166KMを2日で走破するレース)

詳しいプロフィール
質問・お問い合わせ

おすすめ