public void Register(ContractSide side) { lock (LockObject) { sides[side.SideKey].Add(side); } }
public ContractSide GetAnother(ContractSide side) { if (side == Minus) return Plus; else if (side == Plus) return Minus; else throw new InvalidArgumentExcetipn("Provided <Side> does not relate to the <Connection>"); }
public void UnRegister(ContractSide side) { lock (LockObject) { sides[side.SideKey].Remove(side); } }
protected override void DoDispose() { Plus = null; Minus = null; }
internal SideConnection(ContractSide minus,ContractSide plus, bool isInternalConnection) { DNUInsideContractConnection = isInternalConnection; Minus = minus; Plus = plus; }
/// <summary> /// function searches the best path between current and to, /// in case of path found it adds its cost to currentCost /// </summary> /// <param name="currentCost">Reference param, function adds cost of found path to the param</param> /// <param name="current">a side to start path from</param> /// <param name="to">a destination side</param> /// <returns>null if no path exists, empty list if 'current' == 'to'</returns> LinkedList<ContractSide> F11BestPathRecursive(ref double currentCost, ContractSide current, ContractSide to) { if (current == to) return new LinkedList<ContractSide>(); //check if we already know the best path between 'current' and 'to' PreTrade preTrade = pretrades[current.SideKey][to.SideKey]; if (!preTrade.Exists)//we already know that there is no any path between 'current' and 'to' return null; if (!preTrade.Empty) { //yes the path exists and we already know the best, we will just use cached values currentCost += preTrade.Cost; return preTrade.Path; } //Below we perform search of the next steps of path LinkedList<ContractSide> bestPath = null; double bestCost = double.MinValue; //iterating ALL possible connections foreach (SideConnection connection in current.ExternalConnections) { //this is a next side ContractSide next = connection.GetAnother(current); //we go into the next side if it was not used in THIS path before //AND (either it is spread or our destination side) if (next.SideKey.Used==0 && (next == to || next.Parent.SideCount>1)) { //we add cost of contract only in case we did not go through it for the current path //we could already go through one of side of the contract double nextCost = next.Parent.Used == 0 ? 0 : next.Parent.Price; //we put that the side is used, to prevent usage of them for the next path steps next.Used = true; ContractSide nextStored = next; //in case if it is spread, and not next side is not the destination, //then we perform step through the spread automatically and update 'next' value if (next.Parent.SideCount>1 && next!=to) { nextStored = next; SideConnection con = next.InternalConnections.First(); next = con.GetAnother(next); next.Used = true; } //now we performed single step and can call the same function recursively //in order to searach the rest of the path LinkedList<ContractSide> curPath = F11BestPathRecursive(ref nextCost, next, to); //ONLY now when we have FULL path constructed between 'next' and 'to'... //we can compare full paths and full costs if (curPath!=null && nextCost > bestCost) { bestCost = nextCost; bestPath = curPath; bestPath.AddFirst(next); if (next!=nextStored) bestPath.AddFirst(nextStored); } //now we can release the side, so it could be used in other trades next.Used = false; nextStored.Used = false; } } if (bestCost == double.MinValue) { preTrade.Exists = false; return null; } preTrade.Cost = bestCost; preTrade.Path = bestPath; currentCost += bestCost; return bestPath; //current. // .SideKey.Opposite }
IEnumerable<ContractSide> F1BestPath(ContractSide from, ContractSide to) { from.Used = true; double price = from.Parent.Price; LinkedList<ContractSide> curPath = F11BestPathRecursive(ref price, from, to); from.Used = false; if (curPath!=null) { curPath.AddFirst(from); } return curPath; }