public decimal CheckCost(Order order) { decimal net; decimal gross; CalcPrices(order, out net, out gross); return gross; }
public Fill[] Execute(Order order) { double amount = order.Amount; double maxlot = MaxLot; //how many fills we expect at the end? int fillsCount = (int)Math.Ceiling(amount / maxlot); List<Fill> totalFills = new List<Fill>(fillsCount); for (int i = 0; i < fillsCount; i++) { //create an order for a partial fill double currentAmount = Math.Min(amount, maxlot); Order currentOrder = new Order(order); currentOrder.Amount = currentAmount; //find the best route by smart algorithm var bestRoute = SmartSelector.SelectBestRoute(currentOrder, Routes); //execute order var fills = bestRoute.Execute(currentOrder); //setting the initiator foreach (var fill in fills) fill.Initiator = order; //saving results totalFills.AddRange(fills); amount -= currentAmount; } return totalFills.ToArray(); }
public Order(Order order) : this() { Instrument = order.Instrument; Account = order.Account; Amount = order.Amount; Side = order.Side; }
public Fill[] Execute(Order order) { decimal net; decimal gross; CalcPrices(order, out net, out gross); //creating a fill Fill fill = GetFill(order, net, gross); System.Diagnostics.Debug.WriteLine("{0} {1} lots {2} for {3}", order.Side, order.Amount, order.Instrument.Name, order.Account.Name); return new Fill[] { fill }; }
public bool Validate(Order order) { if (order == null) throw new ArgumentNullException("order"); var instrument = order.Instrument; if (instrument == null) return false; if (order.Amount < instrument.MinLot) return false; return true; }
private void CalcPrices(Order order, out decimal net, out decimal gross) { if (order == null) throw new ArgumentNullException("order"); var quote = LastQuote; if (quote == null) throw new Exception("no price available"); var amount = order.Amount; if (amount > MaxLot) throw new ArgumentOutOfRangeException("amount is too big"); var instrument = order.Instrument; var lotsize = instrument.LotSize; //calculating the prices net = (decimal)quote.Price * lotsize * (decimal)amount; gross = net * CommissionCalculator.CalcCommissionMultiplier(amount); }
public IRoute SelectBestRoute(Order order, IRoute[] routes) { return routes.OrderBy(x => x.CheckCost(order)).FirstOrDefault(); }
private Fill GetFill(Order order, decimal net, decimal gross) { Fill fill = new Fill(order); fill.Initiator = order; fill.Route = this; fill.Net = net; fill.Gross = gross; return fill; }
public Fill(Order order) : base(order) { }
public decimal CheckCost(Order order) { //benefits of the smart routing return Routes.Min(r => r.CheckCost(order)); }
/// <summary> /// Main trade opearation /// </summary> public DealTicket PlaceOrder(Order order) { if (order == null) throw new ArgumentNullException("order"); if (!OrderValidator.Validate(order)) throw new Exception("Market order cannot be executed"); var route = Route; if (route == null) throw new Exception("Route was not specified"); var fills = route.Execute(order); lock (Fills) { FilledOrders.Add(order); Fills.AddRange(fills); } var result = new DealTicket(fills.Sum(x => x.Gross), fills.Sum(x => x.Net)); return result; }