【问题标题】:WebIce Integration using Quick fix使用快速修复的 WebIce 集成
【发布时间】:2016-11-14 18:44:07
【问题描述】:

我是修复协议和快速修复编程的新手。我正在寻求有关从 ICE 获取贸易捕获报告的帮助。我已经搜索了示例/教程以使用快速修复/n 来获取交易报告,但我无法获得足够的输出。 我的问题是为此我尝试使用 TradeCaptureReportRequest、TradeCaptureReportRequestAck、TradeCaptureReport 类获取贸易捕获报告或交易信息,但不知何故它现在正在工作。 一个简单的如何提取信息将是一个很大的帮助。 提前感谢大家。

【问题讨论】:

  • 所以您收到了回复,但无法解析数据?只是确保我理解清楚。
  • 如果您需要简单地获取一个字段,请使用 msg.GetField(int),其中 int 是定义文件中的枚举值(例如,FIX50SP2.xml)。如果是头域,msg.Header.GetField(int)。这是你需要的吗?
  • @aaron 我没有得到任何回应。实际上它根本没有做任何事情。能否请您详细介绍一下此次整合的整体流程?
  • 我会在我的办公桌前。我看看能不能帮上忙。你已经建好了骨架吗? (您的项目中是否有 FIX[ver].XML、initiator.cfg 和创建消息的主表单?
  • @aaron,我确实很少,但我认为它不正确。如果你能提供一个样本和步骤将是一个很大的帮助。

标签: c# ice quickfixn


【解决方案1】:

好的,我将发布作为答案,因为评论的时间太长了。请记住,我已经编写了自定义常量、消息类型等(我也编写了我的接受器服务器,所以我不受 ICE 常量/枚举的限制)。您需要确定 ICE 需要哪些字段并进行更改 - 这不容易复制/粘贴...

首先,您需要确保您拥有所有必需的文件并被引用。我在我的项目中创建了一个名为“fix”的文件夹,并将所有修复文件复制到其中。这些需要(至少 1 个)FixXXX.xml 文件,如果您使用的是 FIX50SP1 或 2,则还需要有 FIXT11.xml。除了 .xml 文件,您还需要有一个initiator.cfg 文件(假设您正在制作一个启动器,而不是服务器,否则这将需要是“acceptor.cfg”,但同样,听起来您正在尝试连接到ICE,所以initiator是正确的用法。最后,你需要一个QuickFix.dll。我的树如下所示:

我不打算浏览 XML 文件 - 您只需了解这一点 - 它非常令人困惑且需要时间。尤其是在将 FIXT11.XML 与 SP1 或 2 一起使用时。

您的initiator.cfg 应该类似于以下内容:

# default settings for sessions
[DEFAULT]
FileStorePath=store
FileLogPath=log
ConnectionType=initiator
ReconnectInterval=60
SenderCompID=[Enter yours]

ResetOnLogon=Y 
ResetOnLogout=Y 
ResetOnDisconnect=Y 


[SESSION]
BeginString=FIXT.1.1
TargetCompID=[Enter ICE Acceptor]
DefaultApplVerID=FIX.5.0
StartTime=12:30:00
EndTime=21:30:00
# overide default setting for RecconnectInterval
ReconnectInterval=30
HeartBtInt=30
SocketConnectPort=[From ICE]
# (optional) only listen for incoming connections on a specific host
#SocketConnectHost=127.0.0.1
SocketConnectHost=[ICE Ip Address- from your documentation/registration]
DataDictionary=..\..\fix\FIX50.xml
TransportDataDictionary=..\..\fix\FIXT11.xml

好的,假设您已经导入并引用了 QuickFix.dll,并且您的initiator.cfg 已正确连接,这实际上相当简单:

创建一个处理所有事情的类。忽略 AddToLB,这是一个测试函数。

public class TCT_Fix : Control, IApplication
{
    private readonly string username = [removed]
    private readonly string password = [removed]
    public string InitiatorID;                           
    SessionID sessionID;                                 
    public bool running;                                 
    SessionSettings settings;
    IMessageStoreFactory storeFactory;
    ILogFactory logFactory;
    SocketInitiator initiator;
    public event EventHandler AddToLB;
    public event EventHandler AddToAdmin;
    public void StopIt()
    {
        if (sessionID == null) return;
        try
        {
            Session.LookupSession(sessionID).Disconnect("Stopping");
            settings.Remove(sessionID);
            settings = null;
            initiator.Dispose();
            settings = new SessionSettings(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fix", "initiator.cfg"));
            storeFactory = new FileStoreFactory(settings);
            logFactory = new FileLogFactory(settings);
            initiator = new SocketInitiator(
                this,
                storeFactory,
                settings,
                logFactory);
        }
        catch { }   
    }
    public void FromApp(QuickFix.Message msg, SessionID sessionID)
    {
        var sMsg = "FROM APP: " + msg.ToString();
        AddToLB(sMsg, null);
        if (msg.Header.GetField(35) == "TC") //Cash
        {
            DateTime dtTdate;
            float fPrice;
            int Qty;
            int OrdType;
            bool BPisBuyer;

            DateTime.TryParse(msg.GetField(CustomConstants.TDATE),out dtTdate);
            string BPSide = msg.GetField(CustomConstants.BP_SIDE);                
            float.TryParse(msg.GetField(CustomConstants.F_PRICE), out fPrice);
            int.TryParse(msg.GetField(CustomConstants.QTY), out Qty);
            string TCTReference = msg.GetField(CustomConstants.TCT_REF);
            string BPAcct = msg.GetField(CustomConstants.BP_COMPANY);
            int.TryParse(msg.GetField(CustomConstants.ORDER_TYPE), out OrdType);
            string ExecBkr = msg.GetField(CustomConstants.EXEC_BKR);
            string CounterParty = msg.GetField(CustomConstants.COUNTER_PARTY);
            BPisBuyer = msg.GetField(CustomConstants.IS_BUYER) == "Y";
            string BPTrader = msg.GetField(CustomConstants.BP_TRADER);
            string CounterTrader = msg.GetField(CustomConstants.COUNTER_TRADER);
            string Grade = msg.GetField(CustomConstants.GRADE);
            string Location = msg.GetField(CustomConstants.LOCATION);
            string CycDt = msg.GetField(CustomConstants.CYCLE_DATE);
            string DelMo = msg.GetField(CustomConstants.DELIVER_MONTH);
            string Terms = msg.GetField(CustomConstants.TERMS);
            string Payment = msg.GetField(CustomConstants.PAYMENT);
            string Origin = msg.GetField(CustomConstants.ORIGIN);
            string NumOfCyc = msg.GetField(CustomConstants.NUM_OF_CYCLES);
            string Via = msg.GetField(CustomConstants.VIA);
            string MoveMo = msg.GetField(CustomConstants.MOVE_MONTH);
            string Comment = msg.GetField(CustomConstants.COMMENT);
        }
        else if (msg.Header.GetField(35) == "TE") //EFP
        {
            DateTime dtTdate;
            float fPrice;
            int Qty;
            int OrdType;
            bool BPisBuyer;
            bool IsWater;

            DateTime.TryParse(msg.GetField(CustomConstants.TDATE), out dtTdate);
            string BPSide = msg.GetField(CustomConstants.BP_SIDE);
            float.TryParse(msg.GetField(CustomConstants.F_PRICE), out fPrice);
            int.TryParse(msg.GetField(CustomConstants.QTY), out Qty);
            string TCTReference = msg.GetField(CustomConstants.TCT_REF);
            string BPAcct = msg.GetField(CustomConstants.BP_COMPANY);
            int.TryParse(msg.GetField(CustomConstants.ORDER_TYPE), out OrdType);
            string ExecBkr = msg.GetField(CustomConstants.EXEC_BKR);
            string CounterParty = msg.GetField(CustomConstants.COUNTER_PARTY);
            BPisBuyer = msg.GetField(CustomConstants.IS_BUYER) == "Y";
            string BPTrader = msg.GetField(CustomConstants.BP_TRADER);
            string CounterTrader = msg.GetField(CustomConstants.COUNTER_TRADER);
            string Grade = msg.GetField(CustomConstants.GRADE);
            string Location = msg.GetField(CustomConstants.LOCATION);
            string CycDt = msg.GetField(CustomConstants.CYCLE_DATE);
            string DelMo = msg.GetField(CustomConstants.DELIVER_MONTH);
            string Terms = msg.GetField(CustomConstants.TERMS);
            string Payment = msg.GetField(CustomConstants.PAYMENT);
            string Origin = msg.GetField(CustomConstants.ORIGIN);
            string NumOfCyc = msg.GetField(CustomConstants.NUM_OF_CYCLES);
            string Via = msg.GetField(CustomConstants.VIA);
            string MoveMo = msg.GetField(CustomConstants.MOVE_MONTH);
            string Comment = msg.GetField(CustomConstants.COMMENT);
            IsWater = msg.GetField(CustomConstants.ISWATER) == "Y";
            string BPFloorBkr = msg.GetField(CustomConstants.BP_FLOOR_BKR);
            string CounterFloorBkr = msg.GetField(CustomConstants.COUNTER_FLOOR_BKR);
            string Diff = msg.GetField(CustomConstants.DIFFERENCE);
            string MercMo = msg.GetField(CustomConstants.MERC_MO);
            string MercPr = msg.GetField(CustomConstants.MERC_PRICE);
        }
        else if (msg.Header.GetField(35) == "TI") //Index
        {
            DateTime dtTdate;
            float fPrice;
            int Qty;
            int OrdType;
            bool BPisBuyer;
            bool IsWater;

            DateTime.TryParse(msg.GetField(CustomConstants.TDATE), out dtTdate);
            string BPSide = msg.GetField(CustomConstants.BP_SIDE);
            float.TryParse(msg.GetField(CustomConstants.F_PRICE), out fPrice);
            int.TryParse(msg.GetField(CustomConstants.QTY), out Qty);
            string TCTReference = msg.GetField(CustomConstants.TCT_REF);
            string BPAcct = msg.GetField(CustomConstants.BP_COMPANY);
            int.TryParse(msg.GetField(CustomConstants.ORDER_TYPE), out OrdType);
            string ExecBkr = msg.GetField(CustomConstants.EXEC_BKR);
            string CounterParty = msg.GetField(CustomConstants.COUNTER_PARTY);
            BPisBuyer = msg.GetField(CustomConstants.IS_BUYER) == "Y";
            string BPTrader = msg.GetField(CustomConstants.BP_TRADER);
            string CounterTrader = msg.GetField(CustomConstants.COUNTER_TRADER);
            string Grade = msg.GetField(CustomConstants.GRADE);
            string Location = msg.GetField(CustomConstants.LOCATION);
            string CycDt = msg.GetField(CustomConstants.CYCLE_DATE);
            string DelMo = msg.GetField(CustomConstants.DELIVER_MONTH);
            string Terms = msg.GetField(CustomConstants.TERMS);
            string Payment = msg.GetField(CustomConstants.PAYMENT);
            string Origin = msg.GetField(CustomConstants.ORIGIN);
            string NumOfCyc = msg.GetField(CustomConstants.NUM_OF_CYCLES);
            string Via = msg.GetField(CustomConstants.VIA);
            string MoveMo = msg.GetField(CustomConstants.MOVE_MONTH);
            string Comment = msg.GetField(CustomConstants.COMMENT);
            IsWater = msg.GetField(CustomConstants.ISWATER) == "Y";
            string BPFloorBkr = msg.GetField(CustomConstants.BP_FLOOR_BKR);
            string CounterFloorBkr = msg.GetField(CustomConstants.COUNTER_FLOOR_BKR);
            string Diff = msg.GetField(CustomConstants.DIFFERENCE);
            string MercMo = msg.GetField(CustomConstants.MERC_MO);
            string MercPr = msg.GetField(CustomConstants.MERC_PRICE);


        }
    }
    public void OnCreate(SessionID sessionID)
    {
        AddToAdmin("SESSION CREATED: " + sessionID.ToString(), null);
    }
    public void OnLogout(SessionID sessionID)
    {
        AddToAdmin("LOGOUT: " + this.sessionID.ToString(), null);       
    }
    public void OnLogon(SessionID sessionID)
    {
        this.sessionID = sessionID;
        AddToAdmin("LOG ON: " + this.sessionID.ToString(),null);
    }
    public void FromAdmin(QuickFix.Message msg, SessionID sessionID)
    {
        AddToAdmin("FROM ADMIN: " + msg.ToString(), null);
    }
    public void ToAdmin(QuickFix.Message msg, SessionID sessionID)
    {
        if (msg.Header.GetField(35).ToString() == "A")
        {
            msg.SetField(new QuickFix.Fields.Username(username));
            msg.SetField(new QuickFix.Fields.Password(password));
        }

        AddToAdmin("TO ADMIN: " + msg.ToString(), null);
    }
    public void ToApp(QuickFix.Message msg, SessionID sessionID)
    {
        AddToLB("TO APP: " + msg.ToString(), null);       
    }        
    public void GetTestMessage(string msgType)
    {
        if (sessionID == null) return;
        QuickFix.FIX50.TestMessage msg = new QuickFix.FIX50.TestMessage();
        msg.TestType = msgType;
        msg.Header.SetField(new QuickFix.Fields.MsgType("TEST"));
        msg.SetField(new QuickFix.Fields.StringField(CustomConstants.TEST_TYPE, msgType));
        Session.SendToTarget(msg, sessionID);
    }
    public TCT_Fix()
    {
        settings = new SessionSettings(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fix", "initiator.cfg"));
        storeFactory = new FileStoreFactory(settings);
        logFactory = new FileLogFactory(settings);
        initiator = new SocketInitiator(
            this,
            storeFactory,
            settings,
            logFactory);
    }
    public TCT_Fix(ref string initID)
    {
        InitiatorID = initID;
        settings = new SessionSettings(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fix", "initiator.cfg"));
        storeFactory = new FileStoreFactory(settings);
        logFactory = new FileLogFactory(settings);
        initiator = new SocketInitiator(
            this,
            storeFactory,
            settings,
            logFactory);
    }
    public void RunIt()
    {
        if (running) return;
        if(initiator.IsStopped)
        {
            try
            {   
                initiator.Start(); //This can throw an error due to current set up.  I would recommend making the connection,
                                   //pulling data, and then closing the connection (polling) to ensure the initiator clears the
                                   //log files
                                   //reference http://lists.quickfixn.com/pipermail/quickfixn-quickfixn.com/2013q1/000747.html
                                   //2013 issue, still unresolved...  Restart app
            }
            catch(Exception ex)
            {
                if (MessageBox.Show("Error restarting initiator.  Program will close due to file access.  This is a Quickfix bug, not an issue with this program.  Please restart." + Environment.NewLine + Environment.NewLine +
                    "Reference: http://lists.quickfixn.com/pipermail/quickfixn-quickfixn.com/2013q1/000747.html for more information.  Click ok to copy link to clipboard.  Click \"X\" to ignore.") == DialogResult.OK)
                {
                    Clipboard.SetText("http://lists.quickfixn.com/pipermail/quickfixn-quickfixn.com/2013q1/000747.html");
                }
                throw new Exception(ex.ToString());
            }
        }          
        running = true;           
    }
}

最后,为了让它脱颖而出(这实际上也在上面的块中),您构建一个类似于下面的消息,请记住,您的 ICE 消息将具有某些必填字段,而我的“TestMessage”没有。不过,我无法提供生产代码 - 抱歉。

public void GetTestMessage(string msgType)
    {
        if (sessionID == null) return;
        QuickFix.FIX50.TestMessage msg = new QuickFix.FIX50.TestMessage();
        msg.TestType = msgType;
        msg.Header.SetField(new QuickFix.Fields.MsgType("TEST"));
        msg.SetField(new QuickFix.Fields.StringField(CustomConstants.TEST_TYPE, msgType));
        Session.SendToTarget(msg, sessionID);
    }

学习曲线很长。你只需要继续玩,直到你得到它。不过,一旦你把它弄下来,它就有意义了。坚持下去。如果您还需要什么,请告诉我。

【讨论】:

  • 感谢@Aaron。我尝试实施您的建议,并得到了类似目前我得到的地方:MsgType = AQ 和 TraderRequestID = 请求的值,但是当我尝试获取其他字段(如符号或价格)时,我收到错误 bold “饼干异常消息:未找到标签 55 的字段。”你能建议我在这里缺少什么吗?还有我们如何使用 GetField 从交易中获取不同的字段。目前我正在使用 Fix44 和 QuickFix/N-v1.7.0。再次感谢您,希望您能理解新手。
  • 字段真的进来了吗?如果未发送该字段,您将收到该错误。您请求的消息类型可能不包含这些字段。将此放在您的每个“To/From”方法(FromApp、ToAdmin 等)中的任何其他内容之前:Console.WriteLine(msg.ToString());你应该得到类似(单独的评论)(续):::
  • 8 = fixt.1.19 = 46035 = te34 = 849 = tctaCceptor5052 = 20161122-17:52:53.37756 = bpconfinitiator501140 = companyb1141 = n1142 = bptraderguy1143 = arturetraderguy1143 = usgc1145 = cod161146 = Jan1147 = FOB1148 = 2个业务Days1149 = Test Option1150 = 11151 =测试Barge1152 = Nov161154 = Buy1155 = 1.331156 = 1609000021157 = 11/22 / 2016 5:52:53 PM1158 = 11159 = 751160 = BPaccountNum21161 = TestLoc21162 = JJA1163 =测试注释1164 = Y1165 = BP地板经纪人1166 =计数器场内经纪人1167=251168=JAN1169=1.5810=204
  • 每个数字(寻找等号)代表一个“获取”字段。例如,8 表示“什么类型的 FIX”,35 是消息类型(在我的例子中是 TE)等等。如果你查看你的修复字典,你应该能够搜索“35”并循环直到你得到到正确的消息类型,它会告诉你它是什么...首先,在 44 字典中找到标签 55,看看它是什么,然后看看你收到的消息中是否有标签 55 ...它可能不存在。
  • 55 是符号,因此您的错误消息似乎是合法的。确保您实际上收到的是 55 标签...
猜你喜欢
  • 1970-01-01
  • 2012-09-20
  • 2018-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-04
  • 1970-01-01
相关资源
最近更新 更多