Skip to content

clojure-quant/quanta-blotter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

quanta-blotter GitHub Actions status |clojure-quant/quanta-blotterClojars Project

orders executions positions with account/trader routing

MESSAGE TYPES

  • trader/new-order place a new order

  • trader/cancel-order cancel existing order trader/modify-order modify existing order trader/position-status

  • broker/order-rejected a new order is rejected

  • broker/order-confirmed a new order is confirmed (so it is working) [broker/order-pending-new] order received but not working yet. avoid if possible

  • broker/order-canceled an existing order is canceled (so it is no longer working) broker/order-cancel-reject cancel of existing order rejected (see :text for reason) broker/order-modified the order was modified (as per trader request)

  • broker/order-filled a fill or a partial fill "execution-report" broker/order-expired for example good-till-day order or fill-or-kill order broker/order-status this is the order-status of the broker. avoid if possible. (will not get granular fills)

  • broker/message broker/session-message broker/position-status broker/balance-status broker/margin-status

session/connected session/disconnected

oms/order-status internally generated oms/position-status internally generated

universal-fx-message-types

public enum UpdateType : short { // Trader Requests TraderOrderSendRequest=1, TraderOrderCancelRequest=2,

// Responses to TraderNewOrder,
NewOrderAcq=3,
Reject=4,
		
// Responses to Cancel
CancelAcq=5,
OrderCancelReject = 6,
Cancel=7,
		
// Events that happen long after a new Order has been Aqnowledged
// We need to differenciate between FillPartial and FillComplete, because FIX sends FillComplete after the
//order is no longer working.
FillPartial=8,
FillComplete=9,
		
Expiry=10

}

NOTES

  • to use fill partial/complete for a broker that supports it is ok. however, if a broke does only send fill, then what does this mean? it means the broker-api needs to track if an order is open or not. this adds additional complexity to the broker-api. therefore the OMS needs to accept multiple fillpartial, and needs to gracefully interpret the last fillpartial as fillcomplete.

  • we might be able to skip cancelacq and only go for cancel.

order-status :live :not-live :fill :all

OrderUpdateFilter { All=1, FillComplete=2, FillPartial=8, Reject=3, Cancel=4, Expire=5, SendOrder=6, CancelOrder=7 }

public void onOrderUpdate(OrderUpdate orderUpdate) { //log.Info("PositionManager Order Update Received... " + orderUpdate.OrderID);

		Order order = null;
		string orderID = orderUpdate.OrderID;
		
		// Safety net, in case the OrderID is empty (this should never happen though)
		if (string.IsNullOrEmpty (orderID))
		{
			order = new Order (OrderData.NewUnknown ());
			orderID = Guid.NewGuid().ToString();
			order.OrderID = orderID;
			order.Notes = "Error: Empty OrderID";
		}
		
		//if (orderUpdate.Type == OrderUpdate.UpdateType.OrderCancelReject)
		//{
		//	orderUpdate.RejectUpdateType^
		//}
		
		
		// Normal Case: Find the already existing Order in the Order Dictionary.
		if (_OrdersDictionary.ContainsKey (orderID)) // Lookup Order based on the Order ID.
		{
			order = _OrdersDictionary[orderID];
		}
		
		// For Cancels: lookup Orders based on the Original Order ID
		/*if (order==null) // When Orders are Cancelled, they get a new cancel ID; and we need to look for the original Order ID.
		{
			if ( (orderUpdate.Type == OrderUpdate.UpdateType.Cancel) || (orderUpdate.Type == OrderUpdate.UpdateType.CancelAcq) )
			{
				if (!string.IsNullOrEmpty (orderUpdate.FIX_ClientOriginalOrderID))
				{
					if (_OrdersDictionary.ContainsKey (orderUpdate.FIX_ClientOriginalOrderID))
					{
						order = _OrdersDictionary[orderUpdate.FIX_ClientOriginalOrderID];
					}
				}
			}
		}*/
			
		// It is a new order.			
		if (order==null)
		{
			if ( ( (orderUpdate.Type == OrderUpdate.UpdateType.TraderOrderSendRequest) || (orderUpdate.Type == OrderUpdate.UpdateType.NewOrderAcq)  ) &&  (orderUpdate.OrderData != null) )
			{
				order = new Order (orderUpdate.OrderData);
				order.OrderID = orderUpdate.OrderID;
				order.SentTime = orderUpdate.Time; // The first time of the order is what is important.
			}
			else
			{
				// This should never happen; however some logfiles have a DateTime ordering bug,
				// and for those we need to have this in.
				order = new Order (OrderData.NewUnknown());
				order.OrderID = orderUpdate.OrderID;
			}
			_OrdersDictionary.Add (orderID, order);
			_Orders.Add(order);
		}
		
		// Make sure that the orderupdate links to the underlying order OR to the orderinfo from the FIX parser
		//if (orderUpdate.OrderData == null)
		//{
		//	orderUpdate.OrderData = order;
		//}

		_OrderUpdates.Add(orderUpdate);
		order.OnOrderUpdateReceived(orderUpdate);


        public enum UpdateType : short
	{
		// Trader Requests
		TraderOrderSendRequest=1,
		TraderOrderCancelRequest=2,
		
		// Responses to TraderNewOrder,
		NewOrderAcq=3,
		Reject=4,
		
		// Responses to Cancel
		CancelAcq=5,
		OrderCancelReject = 6,
		Cancel=7,
		
		// Events that happen long after a new Order has been Aqnowledged
		// We need to differenciate between FillPartial and FillComplete, because FIX sends FillComplete after the
		//order is no longer working.
		FillPartial=8,
		FillComplete=9,
		
		Expiry=10
	}

About

orders executions positions with account/trader routing

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors