Agent framework designed for FIX applications using quickfix-jruby.
- Connects to an address hosting a fix session (FIX Client)
- Binds on an address to host a fix session (FIX Server)
Inside your project, declare agents and connection information inside config/fix_agents.rb
like so:
PORT=5000
AgentFIX.session_defaults.merge! BeginString: "FIX.4.2", SocketAcceptPort: PORT, SocketConnectPort: PORT, SocketConnectHost: "localhost"
AgentFIX.define_acceptor :my_acceptor do |a|
a.default ={SenderCompID: "TW"}
a.session ={TargetCompID: "ARCA"}
end
AgentFIX.define_initiator :my_initiator do |i|
i.default ={SenderCompID: "ARCA"}
i.session ={TargetCompID: "TW"}
end
In order to use Agent FIX, you must:
require 'agent_fix'
To use with cucumber, you must:
# env.rb
require 'agent_fix/cucumber'
require 'agent_fix/cucumber/report'
You can define a data dictionary using FIX spec:
FIXSpec.data_dictionary= quickfix.DataDictionary.new "path/to/FIX42.xml"
Configure inspection behavior to use combined admin & app messages (default is app-only):
AgentFIX.include_session_level = true
Start the FIX agents:
AgentFIX.start
at_exit {AgentFIX.stop}
When using cucumber, to clear message caches before each scenario:
Before do
sleep(0.5)
AgentFIX.reset
end
Agent FIX comes with a few features to assist in organizing larger tests, including the ability to scope incoming messages. As an example, taken from features/scope.feature
, first define your scope size with the expectation to receive a certain number of messages:
Then I should receive 3 messages on FIX with agent "my_initiator"
Your scope is now defined to 3 messages. Whenever you attempt to inspect a message by index, the locally defined scope will be used:
And the 2nd message should have the following:
| ClOrdID | "hello" |
| OrderID | "abc" |
| Symbol | "IBM" |
| OrdStatus | "PENDING_NEW" |
This will attempt to inspect the second message in the local scope. If you then said:
Then I should receive 4 messages on FIX with agent "my_initiator"
And the 2nd message should have the following:
| ClOrdID | "hello" |
| OrderID | "abc" |
| Symbol | "IBM" |
| OrdStatus | "PENDING_CANCEL" |
The inspection step, And the 2nd message should have the following
will be looking at the 5th message the agent has received since the scenario was started, or the 2nd message in the last defined scope. The first scope was defined to have 3 messages, the second defined to have 4, which means the second scope is defined as messages #4-7.
Scope inclusion is scope inspection without regard to order. Say the agent received the following FIX messages:
8=FIX.4.2|35=8|11=hello|17=123|37=abc|39=A|150=A|151=0|20=0|6=0|14=0|21=1|55=IBM|54=1|40=2|60=20090101-17:13:06.684|
8=FIX.4.2|35=8|11=hello|17=123|37=abc|39=0|150=0|151=0|20=0|6=0|14=0|21=1|55=IBM|54=1|40=2|60=20090101-17:13:06.684|
8=FIX.4.2|35=8|11=hello|17=123|37=abc|39=4|150=A|151=0|20=0|6=0|14=0|21=1|55=IBM|54=1|40=2|60=20090101-17:13:06.684|
8=FIX.4.2|35=8|11=hello|17=123|37=abc|39=2|150=A|151=0|20=0|6=0|14=0|21=1|55=IBM|54=1|40=2|60=20090101-17:13:06.684|
Define your scope:
Then I should receive 3 messages on FIX with agent "my_initiator"
Check for inclusion:
And the FIX messages should include a message with the following:
| ClOrdID | "hello" |
| OrderID | "abc" |
| Symbol | "IBM" |
| OrdStatus | "NEW" |
Message #2 has OrdStatus=NEW
, and matches the cucumber step, so this step will pass. If the message was first or third in the scope, the step would still pass. If, however, another scope was then defined:
Then I should receive a message on FIX with agent "my_initiator"
And an inclusion check was performed:
And the FIX messages should include a message with the following:
| ClOrdID | "hello" |
| OrderID | "abc" |
| Symbol | "IBM" |
| OrdStatus | "NEW" |
The new scope, containing one message, will contain the last FIX message OrdStatus=CANCELED
, and not OrdStatus=NEW
since that was consumed by the previous scope. The second inclusion check for OrdStatus=NEW
would then fail, since the received message was defined in a previous inspection scope.
In a failed Agent FIX scenario, if a scope & agent were ever defined, the last defined scope & agent will print their sent & received messages, colored according to the last defined scope. All sent messages will be colored in green, received messages prior to the current scope will be colored in green, and the current scope when the scenario failed will have its messages colored in red.
Check out features to see all the ways you can use agent_fix.
gem install agent_fix
or add the following to Gemfile:
gem 'agent_fix'
and run bundle install
from your shell.
Please see the contribution guidelines.
Contributers:
- Chris Busbey
- Matt Lane
- Mike Gatny
agent_fix is maintained and funded by Connamara Systems, llc.
The names and logos for Connamara Systems are trademarks of Connamara Systems, llc.
agent_fix is Copyright © 2016 Connamara Systems, llc.
This software is available under the GPL and a commercial license. Please see the LICENSE file for the terms specified by the GPL license. The commercial license offers more flexible licensing terms compared to the GPL, and includes support services. Contact us for more information on the Connamara commercial license, what it enables, and how you can start commercial development with it.
This product includes software developed by quickfixengine.org (http://www.quickfixengine.org/). Please see the QuickFIX Software LICENSE for the terms specified by the QuickFIX Software License.