QuickFIX/N入门:二、发送消息及接收消息

一、     发送消息

 

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
}

 

 

posted @ 2012-04-27 09:01  可乐加冰  阅读(7163)  评论(0编辑  收藏  举报