http://www.tuicool.com/articles/v2me6r
Q. What is
FIX
Protocol?
A. FIX stands for Financial Information eXchange, which is an open protocol intended to streamline electronic communications in the financial securities industry. Most of the exchanges use this standard for communication like sending Order, Executions, MarketData, etc. There are many versions of the specifications like 4.2, 4.4, etc. Have a look at https://fixspec.com/FIX44.
Let's have a look at
QuickFIX/J
and Java example for sending and recieving FIX messages.
Step 1 : Required dependency JAR files
Step 2 : The quickfixj-msg-fix44-1.5.3.jar contains the data dictionary for FIX4.4 with domain objects like and XML "NewSingleOrder". Extract FIX44.xml and copy it to c:\\temp.
Step 3 : Define the configuration for the receiver or message acceptor. receiver.cfg file in /conf. Needs to be in the classpath.
[DEFAULT] ConnectionType=acceptor SocketAcceptPort=5001 SocketReuseAddress=Y StartTime=00:00:00 EndTime=00:00:00 FileLogPath=log FileStorePath=c:\\temp [SESSION] BeginString=FIX.4.4 SenderCompID=FixServer TargetCompID=CLIENT1 DataDictionary=c:\\temp\\FIX44.xml
Step 4 : Define the FIXReceiver class. It extends MessageCracker implements Application . Relevant method gets invoked in this event driven architecture used in MINA.
package com.example; import quickfix.Application; import quickfix.DoNotSend; import quickfix.FieldNotFound; import quickfix.IncorrectDataFormat; import quickfix.IncorrectTagValue; import quickfix.Message; import quickfix.RejectLogon; import quickfix.SessionID; import quickfix.UnsupportedMessageType; import quickfix.fix44.MessageCracker; import quickfix.fix44.NewOrderSingle; public class FIXReceiver extends MessageCracker implements Application { @Override public void onMessage(NewOrderSingle order, SessionID sessionID) { System.out.println("Receiver onMessage.. " + order); } @Override public void fromAdmin(Message arg0, SessionID arg1) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon { } @Override public void fromApp(Message arg0, SessionID arg1) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType { System.out.println("Receiver fromApp.. " + arg0); crack(arg0, arg1); // calls onMessage(..,..) } @Override public void onCreate(SessionID arg0) { System.out.println("Receiver onCreate.. " + arg0); } @Override public void onLogon(SessionID arg0) { System.out.println("Receiver onLogon.." + arg0); } @Override public void onLogout(SessionID arg0) {} @Override public void toAdmin(Message arg0, SessionID arg1) {} @Override public void toApp(Message arg0, SessionID arg1) throws DoNotSend {} }
Step 5 : The server socket code to receive messages. ReceiverApp.Java
package com.example; import java.util.Scanner; import quickfix.Application; import quickfix.ConfigError; import quickfix.DefaultMessageFactory; import quickfix.FileStoreFactory; import quickfix.ScreenLogFactory; import quickfix.SessionSettings; import quickfix.SocketAcceptor; public class RecieverApp { public static void main(String[] args) throws ConfigError { SessionSettings settings = new SessionSettings("receiver.cfg"); Application myApp = new FIXReceiver(); FileStoreFactory fileStoreFactory = new FileStoreFactory(settings); ScreenLogFactory screenLogFactory = new ScreenLogFactory(settings); DefaultMessageFactory msgFactory = new DefaultMessageFactory(); SocketAcceptor acceptor = new SocketAcceptor(myApp, fileStoreFactory, settings, screenLogFactory, msgFactory); acceptor.start(); Scanner reader = new Scanner(System.in); System.out.println("press <enter> to quit"); //get user input for a reader.nextLine(); acceptor.stop(); } }
Step 5 : The sender or initiator configuration file sender.cfg .
[DEFAULT] ConnectionType=initiator HeartBtInt=30 ReconnectInterval=0 FileStorePath=c:\\temp FileLogPath=log StartTime=00:00:00 EndTime=00:00:00 UseDataDictionary=N SocketConnectHost=localhost ContinueInitializationOnError=Y [SESSION] BeginString=FIX.4.4 SenderCompID=CLIENT1 TargetCompID=FixServer SocketConnectPort=5001
Step 6 : Define the FixSender class that implements Application . Relevant method gets invoked in this event driven architecture used in MINA.
package com.example; import quickfix.Application; import quickfix.DoNotSend; import quickfix.FieldNotFound; import quickfix.IncorrectDataFormat; import quickfix.IncorrectTagValue; import quickfix.Message; import quickfix.RejectLogon; import quickfix.SessionID; import quickfix.UnsupportedMessageType; public class FIXSender implements Application { @Override public void fromAdmin(Message arg0, SessionID arg1) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon { } @Override public void fromApp(Message arg0, SessionID arg1) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType { } @Override public void onCreate(SessionID arg0) {} @Override public void onLogon(SessionID arg0) {} @Override public void onLogout(SessionID arg0) {} @Override public void toAdmin(Message arg0, SessionID arg1) {} @Override public void toApp(Message msg, SessionID sessionId) throws DoNotSend { System.out.println("Sender toApp: " + msg.toString()); } }
Step 7 : The client socket initiator to send FIX messages. SenderApp.java .
package com.example; import java.util.Date; import quickfix.Application; import quickfix.ConfigError; import quickfix.DefaultMessageFactory; import quickfix.FileStoreFactory; import quickfix.ScreenLogFactory; import quickfix.Session; import quickfix.SessionID; import quickfix.SessionNotFound; import quickfix.SessionSettings; import quickfix.SocketInitiator; import quickfix.field.ClOrdID; import quickfix.field.OrdType; import quickfix.field.OrderQty; import quickfix.field.Price; import quickfix.field.Side; import quickfix.field.Symbol; import quickfix.field.TransactTime; import quickfix.fix44.NewOrderSingle; public class SenderApp { public static void main(String[] args) throws ConfigError, InterruptedException, SessionNotFound { SessionSettings settings = new SessionSettings("sender.cfg"); Application myApp = new FIXSender(); FileStoreFactory fileStoreFactory = new FileStoreFactory(settings); ScreenLogFactory screenLogFactory = new ScreenLogFactory(settings); DefaultMessageFactory msgFactory = new DefaultMessageFactory(); SocketInitiator initiator = new SocketInitiator(myApp, fileStoreFactory, settings, screenLogFactory, msgFactory); initiator.start(); Thread.sleep(3000); // matching values from sender.cfg SessionID sessionID = new SessionID("FIX.4.4", "CLIENT1", "FixServer"); NewOrderSingle order = new NewOrderSingle(new ClOrdID("DLF"), new Side(Side.BUY), new TransactTime(new Date()), new OrdType(OrdType.LIMIT)); order.set(new OrderQty(45.00)); order.set(new Price(25.40)); order.set(new Symbol("BHP")); Session.sendToTarget(order, sessionID); Thread.sleep(60000); initiator.stop(); } }
Step 8 : Run the ReceiverApp .
log4j:WARN No appenders could be found for logger (quickfix.SessionSchedule). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. <20140731-01:59:36, FIX.4.4:FixServer->CLIENT1, event> (Session FIX.4.4:FixServer->CLIENT1 schedule is daily, 00:00:00-UTC - 00:00:00-UTC) <20140731-01:59:36, FIX.4.4:FixServer->CLIENT1, event> (Created session: FIX.4.4:FixServer->CLIENT1) Receiver onCreate.. FIX.4.4:FixServer->CLIENT1 press <enter> to quit
Step 9 : Run the SenderApp .
log4j:WARN No appenders could be found for logger (quickfix.SessionSchedule). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. <20140731-01:59:44, FIX.4.4:CLIENT1->FixServer, event> (Session FIX.4.4:CLIENT1->FixServer schedule is daily, 00:00:00-UTC - 00:00:00-UTC) <20140731-01:59:44, FIX.4.4:CLIENT1->FixServer, event> (Created session: FIX.4.4:CLIENT1->FixServer) <20140731-01:59:45, FIX.4.4:CLIENT1->FixServer, outgoing> (8=FIX.4.4 9=72 35=A 34=52 49=CLIENT1 52=20140731-01:59:45.635 56=FixServer 98=0 108=30 10=203 ) <20140731-01:59:45, FIX.4.4:CLIENT1->FixServer, event> (Initiated logon request) <20140731-01:59:45, FIX.4.4:CLIENT1->FixServer, incoming> (8=FIX.4.4 9=72 35=A 34=41 49=FixServer 52=20140731-01:59:45.672 56=CLIENT1 98=0 108=30 10=202 ) <20140731-01:59:45, FIX.4.4:CLIENT1->FixServer, event> (Received logon) Sender toApp: 8=FIX.4.4 9=123 35=D 34=53 49=CLIENT1 52=20140731-01:59:47.671 56=FixServer 11=DLF 38=45 40=2 44=25.4 54=1 55=BHP 60=20140731-01:59:47.669 10=238 <20140731-01:59:47, FIX.4.4:CLIENT1->FixServer, outgoing> (8=FIX.4.4 9=123 35=D 34=53 49=CLIENT1 52=20140731-01:59:47.671 56=FixServer 11=DLF 38=45 40=2 44=25.4 54=1 55=BHP 60=20140731-01:59:47.669 10=238 ) <20140731-02:00:15, FIX.4.4:CLIENT1->FixServer, incoming> (8=FIX.4.4 9=60 35=0 34=42 49=FixServer 52=20140731-02:00:15.918 56=CLIENT1 10=145 ) <20140731-02:00:18, FIX.4.4:CLIENT1->FixServer, outgoing> (8=FIX.4.4 9=60 35=0 34=54 49=CLIENT1 52=20140731-02:00:18.604 56=FixServer 10=143 ) <20140731-02:00:46, FIX.4.4:CLIENT1->FixServer, incoming> (8=FIX.4.4 9=60 35=0 34=43 49=FixServer 52=20140731-02:00:46.916 56=CLIENT1 10=148 ) <20140731-02:00:48, FIX.4.4:CLIENT1->FixServer, event> (Initiated logout request) <20140731-02:00:48, FIX.4.4:CLIENT1->FixServer, outgoing> (8=FIX.4.4 9=60 35=5 34=55 49=CLIENT1 52=20140731-02:00:48.603 56=FixServer 10=151 ) <20140731-02:00:48, FIX.4.4:CLIENT1->FixServer, incoming> (8=FIX.4.4 9=60 35=5 34=44 49=FixServer 52=20140731-02:00:48.607 56=CLIENT1 10=153 ) <20140731-02:00:48, FIX.4.4:CLIENT1->FixServer, error> (quickfix.SessionException Logon state is not valid for message (MsgType=5)) <20140731-02:00:48, FIX.4.4:CLIENT1->FixServer, event> (Already disconnected: Verifying message failed: quickfix.SessionException: Logon state is not valid for message (MsgType=5))
Step 10: The receiver or acceptor logs grow further to
<20140731-01:59:45, FIX.4.4:FixServer->CLIENT1, incoming> (8=FIX.4.4 9=72 35=A 34=52 49=CLIENT1 52=20140731-01:59:45.635 56=FixServer 98=0 108=30 10=203 ) <20140731-01:59:45, FIX.4.4:FixServer->CLIENT1, event> (Accepting session FIX.4.4:FixServer->CLIENT1 from /127.0.0.1:60832) <20140731-01:59:45, FIX.4.4:FixServer->CLIENT1, event> (Acceptor heartbeat set to 30 seconds) <20140731-01:59:45, FIX.4.4:FixServer->CLIENT1, event> (Received logon) <20140731-01:59:45, FIX.4.4:FixServer->CLIENT1, event> (Responding to Logon request) <20140731-01:59:45, FIX.4.4:FixServer->CLIENT1, outgoing> (8=FIX.4.4 9=72 35=A 34=41 49=FixServer 52=20140731-01:59:45.672 56=CLIENT1 98=0 108=30 10=202 ) Receiver onLogon..FIX.4.4:FixServer->CLIENT1 <20140731-01:59:47, FIX.4.4:FixServer->CLIENT1, incoming> (8=FIX.4.4 9=123 35=D 34=53 49=CLIENT1 52=20140731-01:59:47.671 56=FixServer 11=DLF 38=45 40=2 44=25.4 54=1 55=BHP 60=20140731-01:59:47.669 10=238 ) Receiver fromApp.. 8=FIX.4.4 9=123 35=D 34=53 49=CLIENT1 52=20140731-01:59:47.671 56=FixServer 11=DLF 38=45 40=2 44=25.4 54=1 55=BHP 60=20140731-01:59:47.669 10=238 Receiver onMessage.. 8=FIX.4.4 9=123 35=D 34=53 49=CLIENT1 52=20140731-01:59:47.671 56=FixServer 11=DLF 38=45 40=2 44=25.4 54=1 55=BHP 60=20140731-01:59:47.669 10=238 <20140731-02:00:15, FIX.4.4:FixServer->CLIENT1, outgoing> (8=FIX.4.4 9=60 35=0 34=42 49=FixServer 52=20140731-02:00:15.918 56=CLIENT1 10=145 ) <20140731-02:00:18, FIX.4.4:FixServer->CLIENT1, incoming> (8=FIX.4.4 9=60 35=0 34=54 49=CLIENT1 52=20140731-02:00:18.604 56=FixServer 10=143 ) <20140731-02:00:46, FIX.4.4:FixServer->CLIENT1, outgoing> (8=FIX.4.4 9=60 35=0 34=43 49=FixServer 52=20140731-02:00:46.916 56=CLIENT1 10=148 ) <20140731-02:00:48, FIX.4.4:FixServer->CLIENT1, incoming> (8=FIX.4.4 9=60 35=5 34=55 49=CLIENT1 52=20140731-02:00:48.603 56=FixServer 10=151 ) <20140731-02:00:48, FIX.4.4:FixServer->CLIENT1, event> (Received logout request) <20140731-02:00:48, FIX.4.4:FixServer->CLIENT1, outgoing> (8=FIX.4.4 9=60 35=5 34=44 49=FixServer 52=20140731-02:00:48.607 56=CLIENT1 10=153 ) <20140731-02:00:48, FIX.4.4:FixServer->CLIENT1, event> (Sent logout response)
相关推荐
MySQL provides connectivity for client applications developed in the Java programming language via a JDBC driver, which is called MySQL Connector/J. MySQL Connector/J is a JDBC-3.0 Type 4 driver, ...
Java EE 6 tutorial 配套example代码,找了很久才找到的,跟Java EE 6 tutorial配套使用,是官方的学习资料。
Designed as a guidebook for those who want to become a Java developer, Java 7: A Comprehensive Tutorial discusses the essential Java programming topics that you need to master in order teach other ...
Java 8 简明教程 Java 8 Tutorial中文版 “Java并没有没落,人们很快就会发现这一点” 欢迎阅读我编写的Java 8介绍。本教程将带领你一步一步地认识这门语言的新特 性。通过简单明了的代码示例,你将会学习到如何使用...
java tutorialjava tutorial.chm
目前为止能找到的最新版本。资料很难得。 Java 3D Tutorial v1.6.2 (Java 3D API v1.2) Getting Started with the Java 3D API A Tutorial for Beginners
This book is a definite tutorial in RxJava filled with a lot of well-described examples. It explains reactive programming concepts in plain and readable language, without scientific formulas and terms...
java开发 jdk文件所需的重要文件:docs文件 和tutorial文件,有需要的亲下载!
Java Tutorial 里面有实例,很全面
Java2 Tutorial-5.0
NetBeans IDE 6.0 Java Quick Start Tutorial
The Java Tutorial 是一个非常不错的java教程
Java EE 6 APIs in the Java Platform, Standard Edition 6.0 31 GlassFish Server Tools 34 Chapter 2: Using the Tutorial Examples 37 Required Software 37 Starting and Stopping the GlassFish Server ...
Java 教程, 从简单到复杂,初学者入门教程
Beginning Cryptography with Java While cryptography can still be a controversial topic in the programming community, Java has weathered that storm and provides a rich set of APIs that allow you, the ...
SUN网站上找的英文版JAVA教程,Java Tutorial,只要你英文过四级,这绝对是JAVA SE最棒的学习资料.内容基本含概了JAVA SE的所有方面,从基本语法,继承,Generic,IO,序列化,到JavaBean,Swing组件,XML,正则表达式,JDBC,JAVA...
A tutorial on logging in java using log4j
Java JDK 1.4 Tutorial