http://www.cnblogs.com/jinglelin/archive/2012/04/26/2470978.html

QuickFix/N简介 
FIX是Financial Information eXchange的简称。FIX是一种专门为实时电子证券交易设计的标准消息协议。该协议由FIX protocol, Ltd(FPL)所有并维护。FIX协议的官方网址为http://www.fixprotocol.org/ 
QuickFix引擎( http://www.quickfixengine.org/ )一个开源的FIX引擎,其中它有JAVA、C++、C#三个版本的实现。

QuickFix/N是实现了FIX协议4.0-5.0版本及其功能的开源软件,100%使用.NET(C#)实现。
QuickFix/N官网下载 http://www.quickfixn.org/
QuickFix/N源码下载 https://github.com/connamara/quickfixn

使用QuickFIX/N创建一个Fix应用程序

使用QuickFIX/N创建一个FIX应用程序很容易,实现它的接口Application即可,例如创建一个简单应用程序如下

public class MyQuickFixApp : Application
{
    public void FromApp(Message msg, SessionID sessionID) { }
    public void OnCreate(SessionID sessionID) { }
    public void OnLogout(SessionID sessionID) { }
    public void OnLogon(SessionID sessionID) { }
    public void FromAdmin(Message msg, SessionID sessionID) { }
    public void ToAdmin(Message msg, SessionID sessionID) { }
    public void ToApp(Message msg, SessionID sessionID) { }
}

这些实现方法将被QuickFIX/N的事件调用。

下面我们来看看每个回调事件的说明。

应用回调

客户端(对手方)发送登录请求或其它请求消息,当QuickFIX/N应用程序收到消息。QuickFIX/N应用程序会发送一个回调事件的通知。

FromApp -每个应用级别的消息将通过该方法处理,如委托指令,执行报告,证券信息以及市场数据。

FromAdmin -每个管理级别的消息将通过该方法处理,如心跳,登录以及注销。

OnCreate中 - 每当一个新的会话被创建,该方法被调用。

OnLogon - 当登录操作成功完成时,该方法被调用。

OnLogout - 当会话断开时触发,包括对方主动请求logout或者网络连接断开都会引发该事件。

ToApp -所有应用级别的消息在发送出去之前,都会调用该方法。如果需要在每个发出的消息当中添加一个标签(Tag),在该方法是实现该需求最好的位置。

ToAdmin -所有发出的管理级别消息在发送出去之前,都会调用该方法。

Acceptor 和 Initiator

QuickFIX/N 实现了的acceptor 和 initiator两种模式。

Initiator:作为客户端,当我们要连接到对方的应用时,使用Initiator。

Acceptor :作为服务端,当我们要提供应用服务供对方连接时,使用Acceptor。

创建我们的应用程序

以下示例代码,我们实现Application 接口,然后实例化一个Acceptor

using QuickFix;
public class MyQuickFixApp : Application
{
    public void FromApp(Message msg, SessionID sessionID) { }
    public void OnCreate(SessionID sessionID) { }
    public void OnLogout(SessionID sessionID) { }
    public void OnLogon(SessionID sessionID) { }
    public void FromAdmin(Message msg, SessionID sessionID) { }
    public void ToAdmin(Message msg, SessionID sessionID) { }
    public void ToApp(Message msg, SessionID sessionID) { }
}

public class MyApp
{
    static void Main(string[] args)
    {
        SessionSettings settings = new SessionSettings(args[0]);
        Application myApp = new MyQuickFixApp();
        MessageStoreFactory storeFactory = new FileStoreFactory(settings);
        LogFactory logFactory = new FileLogFactory(settings);
        ThreadedSocketAcceptor acceptor = new ThreadedSocketAcceptor(
            myApp,
            storeFactory,
            settings,
            logFactory);

acceptor.Start();
        while (true)
        {
            System.Console.WriteLine("Waiting!");
            System.Threading.Thread.Sleep(1000);
        }
        acceptor.Stop();
    }
}

如果要更改应用角色,改为Initiator,只要简单地用SocketInitiator替换ThreadedSocketAcceptor即可

其它扩展

1)消息存储扩展

MessageStore会存储FIX会话级别消息的消息传出记录。我们可以通过实现MessageStoreFactory接口,来自定义或扩展我们的消息存储。

2)日志存储扩展

日志记录已经有了两个的实现:FileLog、ScreenLog,其中文件存储的日志记录器已经可以满足一般的要求。当然,我们也可以通过实现LogFactory接口,来自定义实现或扩展我们的日志存储。

一、     发送消息

QuickFIX/N的发送FIX消息的简单示例:

FIX44.NewOrderSingle order = new FIX44.NewOrderSingle(

new ClOrdID("1234"),

new Symbol("000001"),

new Side(Side.BUY),

new TransactTime(DateTime.Now),

new OrdType(OrdType.MARKET));

Session.SendToTaget(order, sessionID);

首先,我们需要学习如何使用会话发送指令消息。

1)      QuickFIX会话

发送消息时,我们必须指定QuickFIX会话,QuickFIX根据会话信息判定消息发送目的地。

所有QuickFIX会话的标识是在消息头定义的,通常包括SenderCompIDTargetCompIDBeginString等字段,这些都是在配置文件中指定。

SenderCompID=CONNAMARA
TargetCompID=CBOE
BeginString=FIX4.4

有几个获得会话的方式。一是当会话被创建并缓存它时,我们可以获得SessionID:

private SessionID MySessionID { get; set; }
public void OnCreate(SessionID sessionID)
{
    MySessionID = sessionID;
}

另外,我们可以在响应传入消息时,得到SessionID:

public void OnMessage(FIX42.ExecutionReport execution, SessionID sessionID) 
{
    ProcessExecution(execution, sessionID);
}

或者,先在配置文件当中配置好所有的会话,我们可以从配置文件找到匹配的SessionID:

var mySessionID = new SessionID("FIX4.2", "senderCompID", "targetCompID");

2)      创建和发送消息

创建消息时,我们首选使用指定Fix版本和消息类型的构造函数,填写必选字段:

using QuickFix;
using QuickFix.Fields;
 
var order = new QuickFix.FIX44.NewOrderSingle(
    new ClOrdID("1234"),
    new Symbol("000001"),
    new Side(Side.BUY),
    new TransactTime(DateTime.Now),
    new OrdType(OrdType.LIMIT));

使用信息的字段属性设置字段值:

order.Price = new Price(new decimal(22.4));
order.Account = new Account("18861112");

把上面的内容合并在一起:创建消息,设置其必需的字段,并设置两个附加字段,使用获得的SessionID,我们发送消息示意如下:

var order = new QuickFix.FIX44.NewOrderSingle(
    new ClOrdID("1234"),
    new Symbol("000001"),
    new Side(Side.BUY),
    new TransactTime(DateTime.Now),
    new OrdType(OrdType.LIMIT));
 
order.Price = new Price(new decimal(22.4));
order.Account = new Account("18861112");
 
Session.SendToTarget(order, sessionID);

3)      创建消息及字段的其他实现方式

类型安全的方式 ,已经被证明它是最好的方式了,但我们也可以用其他创建消息及字段的方法。

1)     每个消息类型都有一个默认的构造函数:

var order = new QuickFix.FIX44.NewOrderSingle();
order.ClOrdID = new ClOrdID("1234");
order.Symbol = new Symbol("000001");
order.Side = new Side(Side.BUY);

2)     我们也可以用QuickFIX C ++及QuickFIX/J风格的get / set方法,也是类型安全的:

order.Set(new TransactTime(DateTime.Now));
order.Set(new OrdType(OrdType.LIMIT));

如果不是一个消息属性,可以用SetField设置一个字段的值:

order.SetField(new Account("18861112"));

3)     另外,也可以这么做,先创建一个Message基类的实例,它没有属性,因此都必须使用SetField 方法,但不建议使用这种风格

var order = new QuickFix.Message();
order.Header.SetField(new MsgType("D"));
order.SetField(new ClOrdID("1234"));
order.SetField(new Symbol("AAPL"));
order.SetField(new Side(Side.BUY));
order.SetField(new TransactTime(DateTime.Now));
order.SetField(new OrdType(OrdType.LIMIT));

二、        接收消息

在QuickFIX/N接收类型安全和简单类型的消息:

public void OnMessage( QuickFix.FIX44.NewOrderSingle order,SessionID sessionID)
{
    ProcessOrder(order.Price, order.OrderQty, order.Account);
}

1)      接收类型安全的消息

MessageCracker是一个抽象类,一个助手类,一般在类型安全的各个OnMessage方法中调用,用于解析各个FIX版本的委托消息类型。处理FIX消息时, Crack方法会根据消息类型,判断其类型类型是否已定义消息类型,如果已定义的消息,将调用其已注册的处理方法来处理消息。

QuickFIX/N应用时,应用类将继承MessageCracker,对于消息的处理,我们使用的都是指定​​的、强类型的Message和Field类,对于不同的消息类型,我们分别不同的处理方法实现处理逻辑。当消息到达时, FromApp方法里面调用Crack,根据不同的消息类型,调用相应类型的消息处理方法 :

using QuickFix;
 
public class MyApplication : MessageCracker, Application
{
    public void FromApp(Message msg, SessionID sessionID)
    {
        Crack(msg, sessionID);
    }
    //...
}

在重载的onMessage回调方法当中调用Crack 。以下例子演示接收委托及证券信息:

public void OnMessage( QuickFix.FIX44.NewOrderSingle ord, SessionID sessionID)
{
    ProcessOrder(ord.Price, ord.OrderQty, ord.Account);
}
 
public void OnMessage( QuickFix.FIX44.SecurityDefinition secDef, SessionID sessionID)
{
    GotSecDef(secDef);
}

2)      消息解析器示例

整合一下,一个类型安全的订单处理的应用是这样的:

public class MyApplication : MessageCracker, Application
{
    public void OnMessage(
        QuickFix.FIX42.NewOrderSingle ord,
        SessionID sessionID)
    {
        ProcessOrder(ord.Price, ord.OrderQty, ord.Account);
    }
 
    protected void ProcessOrder(
        Price price,
        OrderQty quantity,
        Account account)
    {
        //...
    }
    #region Application Methods
 
    public void FromApp(Message msg, SessionID sessionID)
    {
        Crack(msg, sessionID);
    }
    public void OnCreate(SessionID sessionID) { }
    public void OnLogout(SessionID sessionID) { }
    public void OnLogon(SessionID sessionID) { }
    public void FromAdmin(Message msg, SessionID sessionID)
    { }
    public void ToAdmin(Message msg, SessionID sessionID)
    { }
    public void ToApp(Message msg, SessionID sessionID)
    { }
    #endregion
}

3)      非类型安全的应用实现

直接对接收到的Message基类消息进行处理,没有了类型安全的类及字段,需要很多额外的逻辑。一般不建议这样做。

//不推荐
public class MyApplication : Application
{
    public void FromApp(Message msg, SessionID sessionID)
    {
        string msgType = msg.Header.GetString(Tags.MsgType);
        if (msgType.Equals(MsgType.EXECUTION_REPORT))
        {
          string account = msg.GetString(Tags.Account);
          decimal price = msg.GetDecimal(Tags.Price);
        }
    }
    // ...same Application callbacks as above
}

作者:jingle lin
出处:http://jinglelin.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

QuickFIX/N入门:三、 如何配置QuickFIX/N

QuickFIX/N入门相关推荐

  1. FIX协议介绍与QuickFIX使用入门(上)

    定义 FIX协议是由国际FIX协会组织提供的一个开放式协议,目的是推动国际贸易电子化的进程,在各类参与者之间,包括投资经理.经纪人,买方.卖方建立起实时的电子化通讯协议. FIX协议的目标是把各类证券 ...

  2. a或b search vim_vim入门,进阶与折腾

    做为编辑器之神,vim一直是我编辑文本的不二选择,哪怕其坎坷的学习曲线让人头疼不已.末学总结一下经验教训,以作备忘. 入门 个人习惯编译选项 ./configure -with-features=hu ...

  3. 【转载】uvm前置 · Vim 从入门到精通

    声明:该文章转载自github - wsdjeg的项目(见如下链接),此处仅供查阅方便,如侵删,感谢作者和翻译者的突出贡献. https://github.com/wsdjeg/vim-galore- ...

  4. 用Construct 2制作入门小游戏~

    今天在软导课上了解到了Construct 2这个神器,本零基础菜鸟决定尝试做一个简单的小游戏(实际上是入门的教程啊= = 首先呢,肯定是到官网下载软件啊,点击我下载~ 等安装完毕后我便按照新手教程开始 ...

  5. Docker入门六部曲——Swarm

    原文链接:http://www.dubby.cn/detail.html?id=8738 准备工作 安装Docker(版本最低1.13). 安装好Docker Compose,上一篇文章介绍过的. 安 ...

  6. Docker入门六部曲——Stack

    原文链接:http://www.dubby.cn/detail.html?id=8739 准备知识 安装Docker(版本最低1.13). 阅读完Docker入门六部曲--Swarm,并且完成其中介绍 ...

  7. Docker入门六部曲——服务

    原文链接:http://www.dubby.cn/detail.html?id=8735 准备 已经安装好Docker 1.13或者以上的版本. 安装好Docker Compose.如果你是用的是Do ...

  8. 【springboot】入门

    简介: springBoot是spring团队为了整合spring全家桶中的系列框架做研究出来的一个轻量级框架.随着spring4.0推出而推出,springBoot可以説是J2SEE的一站式解决方案 ...

  9. SpringBoot (一) :入门篇 Hello World

    什么是SpringBoot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不 ...

最新文章

  1. C++中类的静态成员
  2. 如何加快Gensim Word2vec模型加载时间?
  3. 查看进程运行状态的环境变量
  4. 一级二级标题_考二级造价师有啥要求?
  5. [转]中国CIO的空前机会和空前责任
  6. linux内核学习之三:linux中的32位与64位
  7. mysql暂停触发器_mysql如何临时禁用触发器
  8. MonoRail MVC应用(2)-构建多层结构的应用程序
  9. oracle nowday,Java MonthDay now()用法及代码示例
  10. Android之startService与bindService的区别
  11. uart串口通信_听说UART与STM32的HAL库更配哦
  12. vue表单中批量导入功能_Vue 编辑 新建表单复用的一些思考
  13. 云顶之弈服务器维护多长时间,英雄联盟3.17更新维护时间介绍 云顶之弈什么时候可以玩_18183云顶之弈专区...
  14. 离散数学-7 二元关系
  15. 双向链表的插入及删除图解
  16. 网络笔记:路由选路原则
  17. Virtualbox虚拟机安装win10系统卡顿
  18. 蓝蓝算法06--输出链表中倒数第k个结点
  19. SQL Service数据库上机
  20. 在数控机床上加工零件,主要取决于加工程序

热门文章

  1. [LeetCode] Length of Last Word - 最后一个单词的长度
  2. iOS之深入解析自动释放池autoreleasepool的底层原理
  3. Git之深入解析Git的安装流程与初次运行Git前的环境配置
  4. LeetCode Algorithm 118. 杨辉三角
  5. Windows 下更换pip源为阿里源
  6. 【机器视觉】 HDevelop语言基础(六)-错误处理
  7. 【Qt】QLayoutItem类
  8. 【Linux】一步一步学Linux——domainname命令(172)
  9. [Qt教程] 第34篇 网络(四)FTP(二)
  10. 如何把睡袋转给别人_微信收到的语音如何转给别人?试试这2个方法,没准能帮到你...