How to place Order via FIX message?
Purpose
The purpose of thispost isto walk-throughimplementation to“Place anOrderon viaFIXmessage
channel”.
In mypreviousposts,Ihave shownbasicimplementationof FIXmessageslike connect/disconnectand
Consume MarketFeeds.
You can read previous poststoknowmore aboutFIXmessage implementation.
 Fix Message Implementation usingQuickFix
 Consume Market feeds on FIX Protocol from Fix enabled broker/exchange usingQuickFix/n
Topics to be covered
I will coverfollowingtopicswithexample code inthispost:
 Differenttypesof Orders.
 OrdersValidity
 Orderworkflow.
 Place Order
 What isExecutionReport?
 Process ExecutionReport.
Order Types:
 Market Order: This isbasictype of order;wherein, traderbuyorsell at marketprice without
specifyingdesiredbuyorsell price.
 Limit Order: It isan order to buyor sell at a specifiedprice.A limitbuyordercanexecute at
specifiedbuyprice orlower. A limitsell ordercanexecute atspecified price orhigher.Inthis
order,traderhas to specifyprice before placinganorder.
 Stop Order: It issimilartomarket orderwhich execute whenspecificprice triggers.Forexample,
if the marketprice is $150, a traderplacesa buystoporder witha price of $160, whenprice
wouldmove 160 or above,thisorderwill become marketorderandexecuteatbestavailable
price.Thistype ordercan be usedfor Take-Profitand Stop-Loss.
 Stop Limit Order: Thisis a combinationof stoporderandlimitorder,like stoporder,it isonly
processedif the marketreachesaspecificprice,butitisexecutedlimitorder,therefore itwill
only getfilledatthe chosen or a betterprice.Forexample,if the currentprice is 150, a trader
mightplace a buy stoplimitorderwitha price of 160. If the markettradesat 160 or above,this
Execution Report <8> (Pending New)
Execution Report <8> (New)
Execution Report <8> (Partially Fill / Filled)
Single Order –New <D>
orderwill execute aslimitordertogetfilledat160. However,itmighthappenthatthisorder
may notfill if there isnotdepthavailable.
Detail descriptionof eachordertypescan be read on investopedia.
Order Validity
In additiontospecifyordertypes, tradescanalsospecifyvalidityof anorderforhow longparticular
orderis valid.Orderwouldbe cancelledafterexpiry.
Traderscan specifyfollowingvalidityof anorder:
 Day: Orderis onlyvalidtill endof the marketsession.
 GTC (Goodtill Cancel):Orderisvalidtill tradermanuallycancelsit.However,brokersmight
have max timeline tocancel ordersautomaticallyif orderisbeyondcertaindays,typically30,60
or 90 days.
 GTD (Goodtill Date): Orderis validtill endof the marketsessionof specifieddate mentionin
thisorder.
 IOC (Immediate or Cancel):Ordershouldbe partially/filledimmediatelywhile placingorder;
otherwise,itwouldbe cancelled.
 FOK (Fill or Kill):Eitherorderwouldbe fullyfilledorcancelled.Thistype of orderwould not
allowanypartial fills.
FIX Order workflow(Fills)
What is ExecutionReport?
It isFIX message whichbrokerside sentforanorder.Brokerside relaysstatusof an order,and there can
be multiple ExecutionReportsforasingle ordermessage.Executionreportscanhave followingstatus
and information:
Order Status
Fix Client
FIXBroker
Side
Important Fields
Field Description
ClOrderId Unique keyof an orderrequestedbyclient.
OrderId Unique keygeneratedbybroker/exchange foranorder.
ExecID Unique keyof each executionreportmessage.
Account Accountnumberon whichorder wasplaced.
OrdType Type of Ordere.g.Market , Limit
Price OrderedPrice specifiedtobuyorsell
Side Side of an order(buyor Sell)
Symbol Symbol name of instrumentonwhichorderplaced.
SecurityId InstrumentID
LastPx Orderd executedonthisprice.
LastQty Tradedquantityineach fill
LeavesQty RemainingQtyof an order.It iszerowhenorderis fullyfilled.
CumQty Total TradedQuantity
Technology/ToolsUsed:
Order
Status
Description
Done for
Day
Orderdidnot fullyorpartiallyfilled;nofurtherexecutions are pendingforthe trading
day.
Filled Ordercompletely filled;noremainingquantity.
Suspended Orderhas beenplacedinsuspendedstate atthe requestof the client.
Canceled Canceledorderwithorwithoutexecutions.
Expired Orderhas beencanceledinbroker'ssystemdue toordervalidity(TimeInForce)
instructions.
Partially
Filled
Outstandingorderwithexecutionsandremainingquantity.
Replaced Replacedorderwithorwithoutexecutions
New Outstandingorderwithnoexecutions
Rejected Orderhas beenrejectedbybroker.NOTE:Anordercan be rejectedsubsequenttoorder
acknowledgment,i.e.anordercan passfrom New toRejectedstatus.
Pending
New
Orderhas beenreceivedbybrokerssystembutnotyetacceptedforexecution.An
executionmessage withthisstatuswill onlybe sentinresponsetoa StatusRequest
message.
Accepted Orderhas beenreceivedandisbeingevaluatedfor pricing.
Examplesare writteninC#.
Fix message parserLibrary: QuickFix/n
Online Fix Logtool: http://FixHawk.Terebrum.com
Implementation
I have downloaded FIX UIDemocode fromQuickFix/nGithublocation tosave some time. Thissample
code alreadyhas connectionandorderroutines. Iwill dofurtherchangestoshow varioususe casesof
orderwork flowwithFIX4.4 specification. Ihave alsoaddedFIXAcceptorcomponenttoprocessFIX
messageslocally.
Connectwith FIX Acceptor
Clickon connectbutton.Fix InitiatorwillsendLogonmessage,whichwill be receivedbyFIXacceptor
and acknowledge itinreversesendinglogonmessage.
Applicationisreadytoplace anorder after connectionisestablished.
Placing Order
Fix 4.4 supports“NewOrderSingle (D)”toplace anysingle orderbythe client. Youcan findstandard
specificationthismessage onanyfix dictionary available online.However,message specificationmight
differfrombrokertobroker.
You can see standardFIXmessages/tagsspecificationon FIXIMATE.
Create an objectof “NewOrderSingle”classandset valuestopropertiesof class:
Code:
// hard-coded fields
QuickFix.Fields.HandlInst fHandlInst = new
QuickFix.Fields.HandlInst(QuickFix.Fields.HandlInst.AUTOMATED_EXECUTION_ORDER_PRIVATE);
// from params
QuickFix.Fields.OrdType fOrdType = FixEnumTranslator.ToField(orderType);
QuickFix.Fields.SidefSide=FixEnumTranslator.ToField(side);
QuickFix.Fields.Symbol fSymbol =new QuickFix.Fields.Symbol(symbol);
QuickFix.Fields.TransactTime fTransactTime = new
QuickFix.Fields.TransactTime(DateTime.Now);
QuickFix.Fields.ClOrdID fClOrdID = GenerateClOrdID();
QuickFix.FIX44.NewOrderSingle nos = new QuickFix.FIX44.NewOrderSingle(
fClOrdID, fSymbol, fSide, fTransactTime, fOrdType);
nos.HandlInst = fHandlInst;
nos.OrderQty = new QuickFix.Fields.OrderQty(orderQty);
nos.TimeInForce = FixEnumTranslator.ToField(tif);
if (orderType == OrderType.Limit)
nos.Price = new QuickFix.Fields.Price(price);
ProcessExecution Report
public void HandleExecutionReport(QuickFix.FIX44.ExecutionReport msg)
{
string execId = msg.ExecID.Obj;
string execType = FixEnumTranslator.Translate(msg.ExecType);
Trace.WriteLine("EVM: Handling ExecutionReport: " + execId + " / " +
execType);
ExecutionRecord exRec = new ExecutionRecord(
msg.ExecID.Obj,
msg.OrderID.Obj,
string.Empty,
execType,
msg.Symbol.Obj,
FixEnumTranslator.Translate(msg.Side));
exRec.LeavesQty = msg.LeavesQty.getValue();
exRec.TotalFilledQty = msg.CumQty.getValue();
exRec.LastQty = msg.LastQty.getValue();
}
FIX Acceptor
Thisis serverside componentwhichprocessmessagesfromFIXclientsandsendresponse backto them.
Executor Class
Thisclass is gettingvariousmethods callbacksonce receivedFIXmessage fromFIXClient.
public void OnMessage(QuickFix.FIX44.NewOrderSingle n, SessionID s)
Thismethodwill be calledeverytime when“NewOrderSingle”message received.
I am simulatingdifferentstatusof anexecutionreport.Ihave added1sec sleeptime betweeneach
statuschange andcan be clearlyseeninUI.
public void OnMessage(QuickFix.FIX44.NewOrderSingle n, SessionID s)
{
Symbol symbol = n.Symbol;
Side side = n.Side;
OrdType ordType = n.OrdType;
OrderQty orderQty = n.OrderQty;
Price price = new Price(DEFAULT_MARKET_PRICE);
ClOrdID clOrdID = n.ClOrdID;
switch (ordType.getValue())
{
case OrdType.LIMIT:
price = n.Price;
if (price.Obj == 0)
throw new IncorrectTagValue(price.Tag);
break;
case OrdType.MARKET: break;
default: throw new IncorrectTagValue(ordType.Tag);
}
// Send Status New
SendExecution(s, OrdStatus.NEW, ExecType.NEW, n, n.OrderQty.getValue(), 0, 0,
0, 0);
Thread.Sleep(1000);
// Send Status Partially Filled
decimal filledQty = Math.Abs(Math.Round(n.OrderQty.getValue() / 4, 2));
decimal cumQty = filledQty;
SendExecution(s, OrdStatus.PARTIALLY_FILLED, ExecType.PARTIAL_FILL, n,
filledQty, filledQty, price.getValue(), filledQty, price.getValue());
Thread.Sleep(1000);
// Send Status Partially Filled
filledQty = Math.Abs(Math.Round(n.OrderQty.getValue() / 4, 2));
cumQty += filledQty;
SendExecution(s, OrdStatus.PARTIALLY_FILLED, ExecType.PARTIAL_FILL, n,
n.OrderQty.getValue() - cumQty, cumQty, price.getValue(), filledQty, price.getValue());
Thread.Sleep(1000);
// Send Status Fully Filled
filledQty = n.OrderQty.getValue() - cumQty;
cumQty += filledQty;
SendExecution(s, OrdStatus.FILLED, ExecType.FILL, n, 0, cumQty,
price.getValue(), filledQty, price.getValue());
}
private void SendExecution(SessionID s, char ordStatus, char execType,
QuickFix.FIX44.NewOrderSingle n, decimal leavesQty, decimal cumQty, decimal avgPx,
decimal lastQty, decimal lastPrice)
{
QuickFix.FIX44.ExecutionReport exReport = new QuickFix.FIX44.ExecutionReport(
new OrderID(GenOrderID()),
new ExecID(GenExecID()),
new ExecType(execType),
new OrdStatus(ordStatus),
n.Symbol, //shouldn't be here?
n.Side,
new LeavesQty(leavesQty),
new CumQty(cumQty),
new AvgPx(avgPx));
exReport.ClOrdID = new ClOrdID(n.ClOrdID.getValue());
exReport.Set(new LastQty(lastQty));
exReport.Set(new LastPx(lastPrice));
if (n.IsSetAccount())
exReport.SetField(n.Account);
try
{
Session.SendToTarget(exReport, s);
}
catch (SessionNotFound ex)
{
Console.WriteLine("==session not found exception!==");
Console.WriteLine(ex.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Thispost exhibitsstandardwayof handlingFIXmessages;however,implementationcanvaryfrom
brokerto broker.
I hope,thispostwill give yougoodunderstandingof how ordercanbe placedviaFIXchannel.Iwill
coverorder cancel and replace scenarioinnextpost.
Source Code
 Github
 Downloadable Zip file

How to place orders through FIX Message

  • 1.
    How to placeOrder via FIX message? Purpose The purpose of thispost isto walk-throughimplementation to“Place anOrderon viaFIXmessage channel”. In mypreviousposts,Ihave shownbasicimplementationof FIXmessageslike connect/disconnectand Consume MarketFeeds. You can read previous poststoknowmore aboutFIXmessage implementation.  Fix Message Implementation usingQuickFix  Consume Market feeds on FIX Protocol from Fix enabled broker/exchange usingQuickFix/n Topics to be covered I will coverfollowingtopicswithexample code inthispost:  Differenttypesof Orders.  OrdersValidity  Orderworkflow.  Place Order  What isExecutionReport?  Process ExecutionReport. Order Types:  Market Order: This isbasictype of order;wherein, traderbuyorsell at marketprice without specifyingdesiredbuyorsell price.  Limit Order: It isan order to buyor sell at a specifiedprice.A limitbuyordercanexecute at specifiedbuyprice orlower. A limitsell ordercanexecute atspecified price orhigher.Inthis order,traderhas to specifyprice before placinganorder.  Stop Order: It issimilartomarket orderwhich execute whenspecificprice triggers.Forexample, if the marketprice is $150, a traderplacesa buystoporder witha price of $160, whenprice wouldmove 160 or above,thisorderwill become marketorderandexecuteatbestavailable price.Thistype ordercan be usedfor Take-Profitand Stop-Loss.  Stop Limit Order: Thisis a combinationof stoporderandlimitorder,like stoporder,it isonly processedif the marketreachesaspecificprice,butitisexecutedlimitorder,therefore itwill only getfilledatthe chosen or a betterprice.Forexample,if the currentprice is 150, a trader mightplace a buy stoplimitorderwitha price of 160. If the markettradesat 160 or above,this
  • 2.
    Execution Report <8>(Pending New) Execution Report <8> (New) Execution Report <8> (Partially Fill / Filled) Single Order –New <D> orderwill execute aslimitordertogetfilledat160. However,itmighthappenthatthisorder may notfill if there isnotdepthavailable. Detail descriptionof eachordertypescan be read on investopedia. Order Validity In additiontospecifyordertypes, tradescanalsospecifyvalidityof anorderforhow longparticular orderis valid.Orderwouldbe cancelledafterexpiry. Traderscan specifyfollowingvalidityof anorder:  Day: Orderis onlyvalidtill endof the marketsession.  GTC (Goodtill Cancel):Orderisvalidtill tradermanuallycancelsit.However,brokersmight have max timeline tocancel ordersautomaticallyif orderisbeyondcertaindays,typically30,60 or 90 days.  GTD (Goodtill Date): Orderis validtill endof the marketsessionof specifieddate mentionin thisorder.  IOC (Immediate or Cancel):Ordershouldbe partially/filledimmediatelywhile placingorder; otherwise,itwouldbe cancelled.  FOK (Fill or Kill):Eitherorderwouldbe fullyfilledorcancelled.Thistype of orderwould not allowanypartial fills. FIX Order workflow(Fills) What is ExecutionReport? It isFIX message whichbrokerside sentforanorder.Brokerside relaysstatusof an order,and there can be multiple ExecutionReportsforasingle ordermessage.Executionreportscanhave followingstatus and information: Order Status Fix Client FIXBroker Side
  • 3.
    Important Fields Field Description ClOrderIdUnique keyof an orderrequestedbyclient. OrderId Unique keygeneratedbybroker/exchange foranorder. ExecID Unique keyof each executionreportmessage. Account Accountnumberon whichorder wasplaced. OrdType Type of Ordere.g.Market , Limit Price OrderedPrice specifiedtobuyorsell Side Side of an order(buyor Sell) Symbol Symbol name of instrumentonwhichorderplaced. SecurityId InstrumentID LastPx Orderd executedonthisprice. LastQty Tradedquantityineach fill LeavesQty RemainingQtyof an order.It iszerowhenorderis fullyfilled. CumQty Total TradedQuantity Technology/ToolsUsed: Order Status Description Done for Day Orderdidnot fullyorpartiallyfilled;nofurtherexecutions are pendingforthe trading day. Filled Ordercompletely filled;noremainingquantity. Suspended Orderhas beenplacedinsuspendedstate atthe requestof the client. Canceled Canceledorderwithorwithoutexecutions. Expired Orderhas beencanceledinbroker'ssystemdue toordervalidity(TimeInForce) instructions. Partially Filled Outstandingorderwithexecutionsandremainingquantity. Replaced Replacedorderwithorwithoutexecutions New Outstandingorderwithnoexecutions Rejected Orderhas beenrejectedbybroker.NOTE:Anordercan be rejectedsubsequenttoorder acknowledgment,i.e.anordercan passfrom New toRejectedstatus. Pending New Orderhas beenreceivedbybrokerssystembutnotyetacceptedforexecution.An executionmessage withthisstatuswill onlybe sentinresponsetoa StatusRequest message. Accepted Orderhas beenreceivedandisbeingevaluatedfor pricing.
  • 4.
    Examplesare writteninC#. Fix messageparserLibrary: QuickFix/n Online Fix Logtool: http://FixHawk.Terebrum.com Implementation I have downloaded FIX UIDemocode fromQuickFix/nGithublocation tosave some time. Thissample code alreadyhas connectionandorderroutines. Iwill dofurtherchangestoshow varioususe casesof orderwork flowwithFIX4.4 specification. Ihave alsoaddedFIXAcceptorcomponenttoprocessFIX messageslocally. Connectwith FIX Acceptor Clickon connectbutton.Fix InitiatorwillsendLogonmessage,whichwill be receivedbyFIXacceptor and acknowledge itinreversesendinglogonmessage. Applicationisreadytoplace anorder after connectionisestablished. Placing Order Fix 4.4 supports“NewOrderSingle (D)”toplace anysingle orderbythe client. Youcan findstandard specificationthismessage onanyfix dictionary available online.However,message specificationmight differfrombrokertobroker. You can see standardFIXmessages/tagsspecificationon FIXIMATE.
  • 5.
    Create an objectof“NewOrderSingle”classandset valuestopropertiesof class: Code: // hard-coded fields QuickFix.Fields.HandlInst fHandlInst = new QuickFix.Fields.HandlInst(QuickFix.Fields.HandlInst.AUTOMATED_EXECUTION_ORDER_PRIVATE); // from params QuickFix.Fields.OrdType fOrdType = FixEnumTranslator.ToField(orderType); QuickFix.Fields.SidefSide=FixEnumTranslator.ToField(side); QuickFix.Fields.Symbol fSymbol =new QuickFix.Fields.Symbol(symbol); QuickFix.Fields.TransactTime fTransactTime = new QuickFix.Fields.TransactTime(DateTime.Now); QuickFix.Fields.ClOrdID fClOrdID = GenerateClOrdID(); QuickFix.FIX44.NewOrderSingle nos = new QuickFix.FIX44.NewOrderSingle( fClOrdID, fSymbol, fSide, fTransactTime, fOrdType); nos.HandlInst = fHandlInst; nos.OrderQty = new QuickFix.Fields.OrderQty(orderQty); nos.TimeInForce = FixEnumTranslator.ToField(tif); if (orderType == OrderType.Limit)
  • 6.
    nos.Price = newQuickFix.Fields.Price(price); ProcessExecution Report public void HandleExecutionReport(QuickFix.FIX44.ExecutionReport msg) { string execId = msg.ExecID.Obj; string execType = FixEnumTranslator.Translate(msg.ExecType); Trace.WriteLine("EVM: Handling ExecutionReport: " + execId + " / " + execType); ExecutionRecord exRec = new ExecutionRecord( msg.ExecID.Obj, msg.OrderID.Obj, string.Empty, execType, msg.Symbol.Obj, FixEnumTranslator.Translate(msg.Side)); exRec.LeavesQty = msg.LeavesQty.getValue(); exRec.TotalFilledQty = msg.CumQty.getValue(); exRec.LastQty = msg.LastQty.getValue(); } FIX Acceptor Thisis serverside componentwhichprocessmessagesfromFIXclientsandsendresponse backto them. Executor Class Thisclass is gettingvariousmethods callbacksonce receivedFIXmessage fromFIXClient.
  • 7.
    public void OnMessage(QuickFix.FIX44.NewOrderSinglen, SessionID s) Thismethodwill be calledeverytime when“NewOrderSingle”message received. I am simulatingdifferentstatusof anexecutionreport.Ihave added1sec sleeptime betweeneach statuschange andcan be clearlyseeninUI. public void OnMessage(QuickFix.FIX44.NewOrderSingle n, SessionID s) { Symbol symbol = n.Symbol; Side side = n.Side; OrdType ordType = n.OrdType; OrderQty orderQty = n.OrderQty; Price price = new Price(DEFAULT_MARKET_PRICE); ClOrdID clOrdID = n.ClOrdID; switch (ordType.getValue()) { case OrdType.LIMIT: price = n.Price; if (price.Obj == 0) throw new IncorrectTagValue(price.Tag); break; case OrdType.MARKET: break; default: throw new IncorrectTagValue(ordType.Tag); } // Send Status New SendExecution(s, OrdStatus.NEW, ExecType.NEW, n, n.OrderQty.getValue(), 0, 0, 0, 0); Thread.Sleep(1000); // Send Status Partially Filled decimal filledQty = Math.Abs(Math.Round(n.OrderQty.getValue() / 4, 2)); decimal cumQty = filledQty; SendExecution(s, OrdStatus.PARTIALLY_FILLED, ExecType.PARTIAL_FILL, n, filledQty, filledQty, price.getValue(), filledQty, price.getValue()); Thread.Sleep(1000); // Send Status Partially Filled filledQty = Math.Abs(Math.Round(n.OrderQty.getValue() / 4, 2)); cumQty += filledQty; SendExecution(s, OrdStatus.PARTIALLY_FILLED, ExecType.PARTIAL_FILL, n, n.OrderQty.getValue() - cumQty, cumQty, price.getValue(), filledQty, price.getValue()); Thread.Sleep(1000); // Send Status Fully Filled filledQty = n.OrderQty.getValue() - cumQty; cumQty += filledQty; SendExecution(s, OrdStatus.FILLED, ExecType.FILL, n, 0, cumQty, price.getValue(), filledQty, price.getValue()); }
  • 8.
    private void SendExecution(SessionIDs, char ordStatus, char execType, QuickFix.FIX44.NewOrderSingle n, decimal leavesQty, decimal cumQty, decimal avgPx, decimal lastQty, decimal lastPrice) { QuickFix.FIX44.ExecutionReport exReport = new QuickFix.FIX44.ExecutionReport( new OrderID(GenOrderID()), new ExecID(GenExecID()), new ExecType(execType), new OrdStatus(ordStatus), n.Symbol, //shouldn't be here? n.Side, new LeavesQty(leavesQty), new CumQty(cumQty), new AvgPx(avgPx)); exReport.ClOrdID = new ClOrdID(n.ClOrdID.getValue()); exReport.Set(new LastQty(lastQty)); exReport.Set(new LastPx(lastPrice)); if (n.IsSetAccount()) exReport.SetField(n.Account); try { Session.SendToTarget(exReport, s); } catch (SessionNotFound ex) { Console.WriteLine("==session not found exception!=="); Console.WriteLine(ex.ToString()); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } Thispost exhibitsstandardwayof handlingFIXmessages;however,implementationcanvaryfrom brokerto broker. I hope,thispostwill give yougoodunderstandingof how ordercanbe placedviaFIXchannel.Iwill coverorder cancel and replace scenarioinnextpost. Source Code  Github  Downloadable Zip file