Pages

Showing posts with label quickfixj. Show all posts
Showing posts with label quickfixj. Show all posts

Friday, May 1, 2009

FIX is digging the ESB world

After Apache Synapse got its FIX integration and Apache Camel followed with the FIX endpoint, we can see now same integration done for Mule ESB. It is interesting, that all the products use QuickFIX/J to implement the integration.

What is it? Is it a hype for the ESB world, to include FIX - there must be a trigger for this kind of features. Do the OMS really demand FIX more and more?

Wednesday, March 11, 2009

camel-quickfix update: Simple Acceptor Usage Scenario

The simplest usage scenario of a Quickfix/J Acceptor in Apache Camel would be as follows:

from("quickfix-server:server.cfg").
to("bean:someBean");


The bean will receive a class instance derived from quickfix.Message and the user can do what ever he wants with this model. However, very often you may want to map the FIX representation onto your own object model. For this purpose camel-bindy is a nice tool, where you can describe how the FIX string should be mapped onto the object model.

So now we have a bit improved version of the scenario:

DataFormat bindy = ...
from("quickfix-server:server.cfg")
.unmarshall(bindy)
.to("bean:someBean");


So, now the target bean will receive the message which is defined in your own object model.

This is the simplest scenario, but there's more to come.

Tuesday, February 24, 2009

camel-quickfix: Working with FIX messages using Apache Camel

Apache Camel

Apache Camel is a powerful open source integration framework based on known Enterprise Integration Patterns. The very nice feature in Camel is that it provides many out-of-the-box components to be reused for any kind of data sources or services.


FIX (Financial Information eXchange)

FIX is an open specification intended to streamline electronic communications in the financial industry. FIX is governed by fixprotocol.org. FIX messages are constructed with name value pairs that contains a standard header (which contains a message type property), a body and a trailer.

Here's a sample FIX message: Buy 1000 DELL @ MKT
8=FIX.4.0#9=105#35=D#34=2#49=BANZAI#52=20080711-06:42:26#56=SYNAPSE#11=1215758546278#21=1#38=1000#40=1#54=1#55=DELL#59=0#10=253


Thousands of small investment firms use FIX protocol and benefit from it as its specification is open and free. FIX supports derivatives like equity, options, FOREX (Foreign Exchange) and fixed incomes, like bonds.


Apache Camel and FIX

For the enterprise version of Apache Camel, the FUSE mediation router, there exists a component that should enable integration via FIX protocol using Camel. The current implementation depends on the Artix Data Services, which is not open-sourced, and also there are some requests for enhancements. There is also a JIRA issue: #CAMEL-1350.

Currently, we also have a project which requires integration with NASDAQ INET platform using FIX protocol, and Apache Camel would be a great tool for that, if it only had a FIX component without Artix DS dependency. For this purpose I have a small project at Google Project site: camel-quickfix.

There's a TODO list at the moment, which includes message normalization and component orchestration issues. But also there's a number of scenarios that are required to be supported in that component (or with its aid). For instance, if our application is an initiator, then in Camel DSL we write:
...to("camel-initiator:config.cfg[?params]

But, in FIX communication, the acceptor side is responding with ExecutionReport message. So, we have an issue here, how should it be supported? Either to request some sort a callback mechanism into Camel DSL, or force the QuickfixApplication to reuse the Camel context to route the response message back. This issue will go to another post.

Friday, January 16, 2009

JBoss Drools: Reasoning on QuickFIX-J data model

I just tried to make a simple JBoss Drools example which could probably handle QuickFIX-J messages. So I created the simplest rule flow, including one RuleSet node, mapped onto a ruleflow-group in a DRL file.

Simple Drools Flow Example
same in textual form:

<?xml version="1.0" encoding="UTF-8"?>
<process xmlns="http://drools.org/drools-5.0/process"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://drools.org/drools-5.0/process drools-processes-5.0.xsd"
type="RuleFlow" name="oms" id="my.oms" package-name="my.oms" >

<header>
</header>

<nodes>
<start id="1" name="Start" x="16" y="16" width="80" height="40" />
<actionNode id="2" name="Action" x="128" y="16" width="80" height="40" >
<action type="expression" dialect="java" >System.out.println("Action Start");</action>
</actionNode>
<ruleSet id="3" name="RuleSet" x="240" y="16" width="80" height="40" ruleFlowGroup="my-oms" />
<actionNode id="4" name="Action" x="352" y="16" width="80" height="40" >
<action type="expression" dialect="java" >System.out.println("Action End");</action>
</actionNode>
<end id="5" name="End" x="464" y="16" width="80" height="40" />
</nodes>

<connections>
<connection from="1" to="2" />
<connection from="2" to="3" />
<connection from="3" to="4" />
<connection from="4" to="5" />
</connections>

</process>


Next describe to rule in a DRL file:


package my.oms

import quickfix.fix44.NewOrderSingle
import quickfix.field.MinQty

rule "reset minqty"
dialect "mvel"
ruleflow-group "my-oms"
when
$order : NewOrderSingle($qty : minQty)
MinQty(value == 1.0 || value > 100.0) from $qty
then
System.out.println("reset order: " + $order);
modify($order){
$order.set(new MinQty(20));
}
end

What looks a little strange to me is the when part:

$order : NewOrderSingle($qty : minQty)
MinQty(value == 1.0 || value > 100.0) from $qty

I spent just quite a few minutes to figure out why my first version of the rule didn't work as I expected. It seemed to me that it would be more natural to make it just in one line, something like this:

NewOrderSingle(MinQty(value == 1.0 || value > 100.0))


With a Java code from the Drools examples (which may also are generated when you create a Drools Project with the Drools eclipse plug-in), I run the example and it works fine.

package my.oms;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.*;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;

import quickfix.field.MinQty;
import quickfix.fix44.NewOrderSingle;


public class MyOms {

public static final void main(String[] args) {
try {
// load up the knowledge base
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
// go !

NewOrderSingle order = new NewOrderSingle();
order.set(new MinQty(1.0));

NewOrderSingle order1 = new NewOrderSingle();
order1.set(new MinQty(111.0));

NewOrderSingle order2 = new NewOrderSingle();
order2.set(new MinQty(222.0));

ksession.insert(order);
ksession.insert(order1);
ksession.insert(order2);
ksession.startProcess("my.oms");
ksession.fireAllRules();

logger.close();
} catch (Throwable t) {
t.printStackTrace();
}
}

private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("oms.drl"), ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("oms.rf"), ResourceType.DRF);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
return kbase;
}

}


This example just shows that with Drools one may handle even quite complex data model, such as QuickFIX-J's one. Next, it would have real value if I'm able to make do the same via Guvnor.

Disqus for Code Impossible