Getting Started Sample
This sample shows how to connect to the CME iLink 3 Gateway or the local Gateway emulator.
The NewSingleOrder
message is sent to the counterparty when the session is established.
Source code
using OnixS.Cme.ILink3;
using OnixS.Cme.ILink3.Testing;
using OnixS.SimpleBinaryEncoding;
using System;
using System.Configuration;
using System.Globalization;
using System.Threading.Tasks;
namespace GettingStarted
{
internal static class GettingStarted
{
static readonly NLog.Logger logger = NLog.LogManager.GetLogger("Sample");
const int NewOrderSingleTemplateId = 514;
const int DefaultSecurityId = 5424; // Channel 54 - "CME Equity Options"
const decimal DefaultPrice = -46190;
const ulong PartyDetailsListReqID = 1;
static Session CreateSession(SessionSettings settings, string segmentId)
{
if (segmentId.Equals("CGW", StringComparison.OrdinalIgnoreCase))
return new CgwSession(settings);
return new Session(settings, int.Parse(segmentId, CultureInfo.InvariantCulture));
}
static void FillSettings(SessionSettings settings, bool useEmulator)
{
settings.LicenseStore = "../../../../../license|../../../../license|.";
settings.TradingSystemVersion = "1.1.0";
settings.TradingSystemName = "Trading System";
settings.TradingSystemVendor = "OnixS";
if (useEmulator)
{
settings.SessionId = "XXX";
settings.FirmId = "001";
settings.AccessKey = "dGVzdHRlc3R0ZXN0dA==";
settings.SecretKey = "dGVzdHRlc3R0ZXN0dGVzdHRlc3R0";
settings.KeepAliveInterval = 5000;
settings.ReconnectAttempts = 0;
}
else
{
settings.SessionId = ConfigurationManager.AppSettings["SessionId"];
settings.FirmId = ConfigurationManager.AppSettings["FirmId"];
settings.AccessKey = ConfigurationManager.AppSettings["AccessKey"];
settings.SecretKey = ConfigurationManager.AppSettings["SecretKey"];
}
}
static int Main(string[] args)
{
logger.Info("CME iLink 3 Getting Started Sample.");
string marketSegmentId = "99";
string host = "127.0.0.1";
int port = 49152;
bool useEmulator = false;
if (args.Length < 3)
{
useEmulator = true;
logger.Info("Emulator is used, remote usage: [MarketSegmentId|'CGW'] [Host] [Port] (SecurityId) (Price)");
}
else
{
marketSegmentId = args[0];
host = args[1];
port = int.Parse(args[2], CultureInfo.InvariantCulture);
}
int securityId = args.Length >= 5 ? int.Parse(args[4], CultureInfo.InvariantCulture) : DefaultSecurityId;
decimal price = args.Length >= 6 ? decimal.Parse(args[5], CultureInfo.InvariantCulture) : DefaultPrice;
try
{
var settings = new SessionSettings();
FillSettings(settings, useEmulator);
Task emulatorTask = null;
Gateway emulator = null;
if (useEmulator)
{
emulator = new Gateway(port, settings);
emulatorTask = Task.Run(() =>
{
emulator.AcceptSession();
emulator.WaitUntilTerminate(
TimeSpan.FromMinutes(30),
(IMessage message) =>
{
if (message.TemplateID == TemplateId.NewOrderSingle)
{
var report = emulator.Encoder().Wrap(TemplateId.ExecutionReportTradeOutright);
report.SetUnsignedLong(Tag.UUID, emulator.Uuid);
emulator.Send(report, 1);
}
});
});
}
using (Session session = CreateSession(settings, marketSegmentId))
{
session.InboundApplicationMessage += (object sender, InboundMessageEventArgs e) => logger.Info($"Incoming application message: {e.Message}");
session.InboundSessionMessage += (object sender, InboundMessageEventArgs e) => logger.Info($"Incoming session message: {e.Message}");
session.Warning += (object sender, SessionWarningEventArgs e) => logger.Warn(e.Description);
session.Error += (object sender, SessionErrorEventArgs e) => logger.Error(e.Description);
session.Reset();
session.Connect(host, port);
IEncoder encoder = session.CreateEncoder();
IMessage order = CreateOrder(encoder, PartyDetailsListReqID, securityId, price);
session.Send(order);
logger.Info("The order was sent. Will disconnect the session and terminate the application.");
session.Disconnect();
}
if (useEmulator && emulatorTask != null)
{
if(emulatorTask.Wait(TimeSpan.FromMinutes(1)) && emulator != null)
emulator.Dispose();
}
}
catch (Exception ex)
{
logger.Error("Exception: " + ex.ToString());
return 1;
}
NLog.LogManager.Shutdown();
return 0;
}
private static IMessage CreateOrder(IEncoder encoder, ulong partyDetailsListReqID, int securityId, decimal price)
{
IMessage message = encoder.Wrap(NewOrderSingleTemplateId);
message
.SetUnsignedLong(Tag.PartyDetailsListReqID, partyDetailsListReqID)
.SetByte(Tag.Side, (byte)Side.Buy)
.SetString(Tag.SenderID, "GFP")
.SetString(Tag.ClOrdID, "OrderId")
.SetUnsignedLong(Tag.OrderRequestID, 1u)
.SetString(Tag.Location, "UK")
.SetChar(Tag.OrdType, (char)OrderType.Limit)
.SetByte(Tag.TimeInForce, (byte)TimeInForce.Day)
.SetInteger(Tag.SecurityID, securityId)
.SetUnsignedInteger(Tag.OrderQty, 1)
.SetDecimal(Tag.Price, price)
.SetByte(Tag.ManualOrderIndicator, (byte)ManualOrdInd.Automated)
.SetChar(Tag.ExecutionMode, (char)ExecMode.Aggressive)
.SetByte(Tag.ExecInst, (byte)ExecInst.AON);
return message;
}
}
}
CME Tags
using System;
namespace GettingStarted
{
static class TemplateId
{
internal const int ExecutionReportTradeOutright = 525;
internal const int NewOrderSingle = 514;
}
static class Tag
{
internal const int Price = 44;
internal const int OrderQty = 38;
internal const int SecurityID = 48;
internal const int Side = 54;
internal const int SenderID = 5392;
internal const int ClOrdID = 11;
internal const int PartyDetailsListReqID = 1505;
internal const int Location = 9537;
internal const int OrderRequestID = 2422;
internal const int OrdType = 40;
internal const int TimeInForce = 59;
internal const int ManualOrderIndicator = 1028;
internal const int ExecutionMode = 5906;
internal const int ExecInst = 18;
internal const int UUID = 39001;
}
enum Side
{
Buy = 1,
Sell = 2
}
enum OrderType
{
MarketwithProtection = '1',
Limit = '2',
StopwithProtection = '3',
StopLimit = '4',
MarketWithLeftoverAsLimit = 'K'
}
enum TimeInForce
{
Day = 0,
GoodTillCancel = 1,
FillAndKill = 3,
FillOrKill = 4,
GoodTillDate = 6
}
enum ManualOrdInd
{
Automated = 0,
ExecMode = 1
}
enum ExecMode
{
Aggressive = 'A',
Passive = 'P'
}
[Flags]
enum ExecInst
{
AON = 0,
OB = 1,
NH = 2
}
}