private void RunCurrentPeriodInstructions( Bar[] lastPeriodTradingData, Bar[] currentPeriodTradingData, DateTime time) { var readyInstructions = new List <Tuple <Instruction, double> >(_currentPeriodInstructions.Count); foreach (var instruction in _currentPeriodInstructions) { var tradingObjectIndex = instruction.TradingObject.Index; var currentBarOfObject = currentPeriodTradingData[tradingObjectIndex]; if (currentBarOfObject.Time == Bar.InvalidTime) { _context.Log(string.Format("the data for trading object {0} is invalid, can't execute instruction", instruction.TradingObject.Code)); continue; } // exclude 开盘涨停/跌停 var lastBarOfObject = lastPeriodTradingData[tradingObjectIndex]; const double MaxChangesCoefficient = 0.99; if (lastBarOfObject.Time != Bar.InvalidTime) { if (instruction.Price.Option == TradingPriceOption.OpenPrice || instruction.Price.Option == TradingPriceOption.CustomPrice) { double priceChangeRatio = Math.Abs(currentBarOfObject.OpenPrice - lastBarOfObject.ClosePrice) / lastBarOfObject.ClosePrice; if (instruction.Action == TradingAction.OpenLong && priceChangeRatio >= instruction.TradingObject.LimitUpRatio * MaxChangesCoefficient) { _context.Log( string.Format( "{0} price {1:0.0000} hit limit up in {2:yyyy-MM-dd}, failed to execute transaction", instruction.TradingObject.Code, currentBarOfObject.OpenPrice, time)); continue; } if (instruction.Action == TradingAction.CloseLong && priceChangeRatio >= instruction.TradingObject.LimitDownRatio * MaxChangesCoefficient) { _context.Log( string.Format( "{0} price {1:0.0000} hit limit down in {2:yyyy-MM-dd}, failed to execute transaction", instruction.TradingObject.Code, currentBarOfObject.OpenPrice, time)); continue; } } } // exclude 一字板 if (currentBarOfObject.HighestPrice == currentBarOfObject.LowestPrice) { if ((currentBarOfObject.LowestPrice < lastBarOfObject.ClosePrice && instruction.Action == TradingAction.CloseLong) || (currentBarOfObject.LowestPrice > lastBarOfObject.ClosePrice && instruction.Action == TradingAction.OpenLong)) { _context.Log( string.Format( "{0} price is locked down in {1:yyyy-MM-dd}, failed to execute transaction", instruction.TradingObject.Code, time)); } continue; } double price = CalculateTransactionPrice( currentBarOfObject, lastBarOfObject, instruction); // Exclude unrealistic price. if ((_settings.IsLowestPriceAchievable && price < currentBarOfObject.LowestPrice) || (!_settings.IsLowestPriceAchievable && price <= currentBarOfObject.LowestPrice) || price > currentBarOfObject.HighestPrice) { _context.Log( string.Format( "{0} price {1:0.000} in {2:yyyy-MM-dd} is not achievable", instruction.TradingObject.Code, price, time)); continue; } readyInstructions.Add(Tuple.Create(instruction, price)); } int totalNumberOfObjectsToBeEstimated = readyInstructions.Count(t => t.Item1.Action == TradingAction.OpenLong); int maxNewPositionCount = _strategy.GetMaxNewPositionCount(totalNumberOfObjectsToBeEstimated); var pendingTransactions = new List <Transaction>(readyInstructions.Count); foreach (var readyInstruction in readyInstructions) { var instruction = readyInstruction.Item1; double price = readyInstruction.Item2; if (instruction.Action == TradingAction.OpenLong) { if (maxNewPositionCount <= 0) { _context.Log(string.Format( "Max new position count reached, ignore this instruction: {0}/{1}. //{2}", instruction.TradingObject.Code, instruction.TradingObject.Name, instruction.Comments)); continue; } _strategy.EstimateStoplossAndSizeForNewPosition(instruction, price, totalNumberOfObjectsToBeEstimated); if (instruction.Volume == 0) { _context.Log(string.Format( "The volume of instruction for {0}/{1} is 0. //{2}", instruction.TradingObject.Code, instruction.TradingObject.Name, instruction.Comments)); continue; } --maxNewPositionCount; } var transaction = BuildTransactionFromInstruction( instruction, time, price); pendingTransactions.Add(transaction); } // always execute transaction according to the original order, so the strategy itself // can decide the order. foreach (var transaction in pendingTransactions) { ExecuteTransaction(transaction, true); } // compact pending instruction list _currentPeriodInstructions.Clear(); }