/// <summary> /// Process fill to adjust position /// Returns null if this fill does not close anything, thus not creating a trade /// TODO: protect from misuse (internal)? /// TODO: set creation of trades in the tradecomposite logic for extensibility /// </summary> /// <param name="fill"></param> /// <returns></returns> public Trade Adjust(Fill fill) { //Set last modified LastModifiedUtc = fill.UtcTime; //Some cleaning up ClearOldPrices(); //Some information holders Fill[] opened = new Fill[0]; Fill[] closed = { fill }; //Check if we have no position at all if (IsFlat) { _fills.Clear(); _fills.Add(fill); } //Check current position if we might have flipped it else if (fill.Direction != Direction && fill.FillQuantity >= UnsignedQuantity) { //Get open fill opened = _fills.ToArray(); //Get closed fill closed = new [] { Fill.AdjustedFill(fill, fill.FillPrice, UnsignedQuantity) }; //Set new fill _fills.Clear(); fill = Fill.AdjustedFill(fill, fill.FillPrice, fill.FillQuantity - UnsignedQuantity); _fills.Add(fill); //Return trade return(new Trade(_fundId, _displayCurrency, opened, closed, GetPrice(true, opened.Union(closed)), GetPrice(false, opened.Union(closed)))); } //Check if we are adding to an existing position (FIFO) else if (fill.Direction == Direction) { _fills.Add(fill); return(null); } //Else we need to adjust according to fill and remove current fills from this position (FIFO) decimal sizeneeded = fill.FillQuantity; List <Fill> opening = new List <Fill>(); for (int i = _fills.Count - 1; i >= 0; i--) { //Get items var currentfill = _fills[i]; if (currentfill.FillQuantity > sizeneeded) { //We need to split it decimal leftover = currentfill.FillQuantity - sizeneeded; _fills[i] = Fill.AdjustedFill(currentfill, currentfill.FillPrice, leftover); currentfill = Fill.AdjustedFill(currentfill, currentfill.FillPrice, sizeneeded); } else { //Remove this fill _fills.RemoveAt(i); } //Add to currently closing fill opening.Add(currentfill); sizeneeded -= currentfill.FillQuantity; //Check if we are ok if (sizeneeded == 0) { break; } } //Return this filled trade opened = opening.ToArray(); return(new Trade(_fundId, _displayCurrency, opened, closed, GetPrice(true, opened.Union(closed)), GetPrice(false, opened.Union(closed)))); }