private static List <OrderDescription> GenerateOrdersDescription(InstructionExecutionContext instructionExecutionContext, int remainingQuantityToBeExecuted, IEnumerable <MarketInfo> validMarkets, decimal requestedPrice, int availableQuantityOnMarkets)
        {
            var ordersDescription = new List <OrderDescription>();

            if (remainingQuantityToBeExecuted == 1)
            {
                ordersDescription.Add(new OrderDescription(validMarkets.First(m => m.SellQuantity >= 1).MarketName, instructionExecutionContext.Way, remainingQuantityToBeExecuted, requestedPrice, instructionExecutionContext.AllowPartialExecution));
            }
            else
            {
                var ratio = remainingQuantityToBeExecuted / (decimal)availableQuantityOnMarkets;

                // ReSharper disable once LoopCanBeConvertedToQuery
                foreach (var marketInfo in validMarkets)
                {
                    var convertedMarketQuantity = Math.Round(marketInfo.SellQuantity * ratio, 2, MidpointRounding.AwayFromZero);
                    var quantityToExecute       = Convert.ToInt32(convertedMarketQuantity);

                    if (quantityToExecute > 0)
                    {
                        ordersDescription.Add(new OrderDescription(marketInfo.MarketName, instructionExecutionContext.Way, quantityToExecute, requestedPrice, instructionExecutionContext.AllowPartialExecution));
                    }
                }
            }

            if (ordersDescription.Count <= 0)
            {
                throw new InvalidOperationException(string.Format("No order description has been created while there is still {0} quantity to be executed (available quantity on the market is {1}).", remainingQuantityToBeExecuted, availableQuantityOnMarkets));
            }

            return(ordersDescription);
        }
Ejemplo n.º 2
0
        protected override InstructionExecutionResult ExecuteCore(InstructionExecutionContext context)
        {
            if (context.Instruction.Data < context.Memory.Length)
            {
                context.Memory[context.Instruction.Data] = false;
            }

            return(new InstructionExecutionResult(context.ProgramCounter + 1));
        }
Ejemplo n.º 3
0
        private void RouteImpl(InstructionExecutionContext instructionExecutionContext)
        {
            // 1. Prepare the corresponding OrderBasket (via solver)
            var solver      = new MarketSweepSolver(this.marketSnapshotProvider);
            var orderBasket = solver.Solve(instructionExecutionContext, this.routeOrders);

            // 2. Route the OrderBasket
            this.routeOrders.Route(orderBasket);
        }
Ejemplo n.º 4
0
        public InstructionExecutionResult Execute(InstructionExecutionContext context)
        {
            if (context.Instruction.Type != Type)
            {
                throw new InvalidOperationException($"This instruction is of type {Type}, while the presented instruction is of type {context.Instruction.Type}.");
            }

            return(ExecuteCore(context));
        }
Ejemplo n.º 5
0
 private void OnOrderFailed(OrderFailedEventArgs reason, InstructionExecutionContext instructionExecutionContext)
 {
     if (instructionExecutionContext.ShouldTheInstructionBeContinued())
     {
         this.RetryInvestorInstruction(instructionExecutionContext);
     }
     else
     {
         instructionExecutionContext.DeclareFailure(reason);
     }
 }
        protected override InstructionExecutionResult ExecuteCore(InstructionExecutionContext context)
        {
            int programCounter = context.ProgramCounter + 1;

            if (context.Instruction.Data < context.Memory.Length)
            {
                if (context.Memory[context.Instruction.Data])
                    programCounter++;
            }

            return new InstructionExecutionResult(programCounter);
        }
Ejemplo n.º 7
0
        public void Route(InvestorInstruction investorInstruction, Action <InvestorInstructionExecutedEventArgs> instructionExecutedCallback, Action <string> failureCallback)
        {
            // Prepares to feedback the investor
            var instructionExecutionContext = new InstructionExecutionContext(investorInstruction, instructionExecutedCallback, failureCallback);

            this.routeOrders.OrderExecuted += this.WhenOneOrderIsExecuted(instructionExecutionContext);
            this.routeOrders.OrderFailed   += this.WhenOneOrderFailed(instructionExecutionContext);

            this.RouteImpl(instructionExecutionContext);

            this.routeOrders.OrderExecuted -= this.WhenOneOrderIsExecuted(instructionExecutionContext);
            this.routeOrders.OrderFailed   -= this.WhenOneOrderFailed(instructionExecutionContext);
        }
        protected override InstructionExecutionResult ExecuteCore(InstructionExecutionContext context)
        {
            if (context.Instruction.Data < context.Memory.Length)
            {
                context.Memory[context.Instruction.Data] = true;
            }
            else
            {
                throw new Exception($"Invalid memory location {context.Instruction.Data}.");
            }

            return(new InstructionExecutionResult(context.ProgramCounter + 1));
        }
        public void Should_Solve_with_2_markets_when_asked_quantity_is_1()
        {
            var marketA              = new ApiMarketGateway("NYSE (New York)", sellQuantity: 50, sellPrice: 100M);
            var rejectingMarket      = new ApiMarketGateway("CME (Chicago)", sellQuantity: 50, sellPrice: 100M, orderPredicate: _ => false);
            var marketsInvolved      = new[] { marketA, rejectingMarket };
            var marketGatewayAdapter = new MarketsAdapter(marketsInvolved);

            var investorInstruction         = new InvestorInstruction(new InvestorInstructionIdentifierDto().Value, Way.Buy, quantity: 1, price: 100M, goodTill: DateTime.Now.AddMinutes(5));
            var instructionExecutionContext = new InstructionExecutionContext(investorInstruction, args => { }, failure => { });

            var marketSweepSolver = new MarketSweepSolver(new MarketSnapshotProvider(marketGatewayAdapter.GetAvailableMarketNames(), marketGatewayAdapter));
            var orderBasket       = marketSweepSolver.Solve(instructionExecutionContext, marketGatewayAdapter);

            Check.That(orderBasket.OrdersDescriptions.Extracting("Quantity")).ContainsExactly(1);
        }
Ejemplo n.º 10
0
        public void JumpTest(int programCounterInitial, int address)
        {
            var instruction = new JumpInstruction();

            var instructionModel = new InstructionModel()
            {
                Type = instruction.Type,
                Data = address,
            };

            var context = new InstructionExecutionContext(new bool[0], programCounterInitial, instructionModel);

            var result = instruction.Execute(context);

            Assert.Equal(address, result.ProgramCounter);
        }
Ejemplo n.º 11
0
        public void ConditionalSkipTest(int programCounterInitial, bool inputValue, int expectedProgramCounter)
        {
            var instruction = new ConditionalSkipInstruction();

            var instructionModel = new InstructionModel()
            {
                Type = instruction.Type,
                Data = 0,
            };

            var context = new InstructionExecutionContext(new bool[] { inputValue }, programCounterInitial, instructionModel);

            var result = instruction.Execute(context);

            Assert.Equal(expectedProgramCounter, result.ProgramCounter);
        }
Ejemplo n.º 12
0
        public void ClearOutputTest(int programCounter)
        {
            var instruction = new ClearMemoryInstruction();

            var instructionModel = new InstructionModel
            {
                Type = instruction.Type,
                Data = 0
            };

            var context = new InstructionExecutionContext(new bool[] { true }, programCounter, instructionModel);

            var result = instruction.Execute(context);

            Assert.False(context.Memory[0]);

            Assert.Equal(programCounter + 1, result.ProgramCounter);
        }
        /// <summary>
        /// Build the description of the orders needed to fulfill an <see cref="SimpleOrderRouting.Infra.InvestorInstruction" /> which
        /// is aggregated within an <see cref="InstructionExecutionContext" /> instance.
        /// </summary>
        /// <param name="instructionExecutionContext">The <see cref="InstructionExecutionContext" /> instance that aggregates the <see cref="SimpleOrderRouting.Infra.InvestorInstruction" />.</param>
        /// <param name="canRouteOrders"></param>
        /// <returns>
        /// An <see cref="OrderBasket" /> containing all the orders to be routed in order to fulfill the initial <see cref="SimpleOrderRouting.Infra.InvestorInstruction" />.
        /// </returns>
        public OrderBasket Solve(InstructionExecutionContext instructionExecutionContext, ICanRouteOrders canRouteOrders)
        {
            // Checks liquidities available to weighted average for execution
            int     remainingQuantityToBeExecuted = instructionExecutionContext.RemainingQuantityToBeExecuted;
            decimal requestedPrice = instructionExecutionContext.Price;

            var validMarkets = this.GetValidMarkets(requestedPrice);
            int availableQuantityOnMarkets = this.ComputeAvailableQuantityForThisPrice(validMarkets);

            if (availableQuantityOnMarkets == 0)
            {
                return(new OrderBasket(new List <OrderDescription>(), canRouteOrders));
            }

            var ordersDescription = GenerateOrdersDescription(instructionExecutionContext, remainingQuantityToBeExecuted, validMarkets, requestedPrice, availableQuantityOnMarkets);

            return(new OrderBasket(ordersDescription, canRouteOrders));
        }
Ejemplo n.º 14
0
 private EventHandler <OrderFailedEventArgs> WhenOneOrderFailed(InstructionExecutionContext instructionExecutionContext)
 {
     // TODO: must process the message only if it's related to the proper instruction
     return((sender, orderFailed) => this.OnOrderFailed(orderFailed, instructionExecutionContext));
 }
Ejemplo n.º 15
0
 private EventHandler <DealExecutedEventArgs> WhenOneOrderIsExecuted(InstructionExecutionContext instructionExecutionContext)
 {
     // TODO: must process the message only if it's related to the proper instruction
     return((sender, dealExecuted) => instructionExecutionContext.RecordOrderExecution(dealExecuted.Quantity));
 }
Ejemplo n.º 16
0
 private void RetryInvestorInstruction(InstructionExecutionContext instructionExecutionContext)
 {
     this.RouteImpl(instructionExecutionContext);
 }
Ejemplo n.º 17
0
 protected abstract InstructionExecutionResult ExecuteCore(InstructionExecutionContext context);
Ejemplo n.º 18
0
 public void SetInstructionExecutionContextToNonNull()
 {
     executionContext = new InstructionExecutionContext();
 }
Ejemplo n.º 19
0
 protected override InstructionExecutionResult ExecuteCore(InstructionExecutionContext context)
 {
     //return new InstructionExecutionResult(context.Instruction.Data);
     return(new InstructionExecutionResult(context.ProgramCounter + 1));
 }