Example #1
0
		/// <summary>
		/// Called for every bar update. Find instrument (ticker) with the highest
		/// win percent and buy that stock if we have enough money.
		/// </summary>
		/// <param name="currentDate">The date that the sim is on.</param>
		/// <param name="barNumber">The bar number of the sim loop. Not to be used for indexing since each ticker has a different number of bars</param>
		private void OnBarUpdate(DateTime currentDate, int barNumber)
		{
			bool isTradingBar = false;
			ConcurrentBag<BestOfRootStrategies> buyBag = new ConcurrentBag<BestOfRootStrategies>();

			// Add all the tickers that are above our set percent to buy.
#if DEBUG
			foreach (KeyValuePair<string, BestOfRootStrategies> instrument in Instruments)
#else
						Parallel.ForEach(Instruments, instrument =>
#endif
			{
				BestOfRootStrategies strat = instrument.Value;
				int currentBar = strat.Data.GetBar(currentDate);
				if (currentBar != -1)
				{
					isTradingBar = true;

					// Run the strategy for this bar.
					strat.OnBarUpdate(currentBar);

					// All bars have a zero value by default. So something is found when the 
					// percent is higher than that.
					if (strat.Bars[currentBar].HighestPercent > 0.0)
					{
						// All orders set a min price to place an order.
						if (strat.Data.Open[currentBar] >= Config.MinPriceForOrder)
						{
							// If this is a short order, some brokers have min prices they allow for shorts.
							if (strat.Bars[currentBar].StrategyOrderType == Order.OrderType.Long ||
								(strat.Bars[currentBar].StrategyOrderType == Order.OrderType.Short && strat.Data.Open[currentBar] >= Config.MinPriceForShort))
							{
								buyBag.Add(strat);
							}
						}
					}
				}
#if DEBUG
			}
#else
			});
#endif

			if (isTradingBar == true)
			{
				List<BestOfRootStrategies> buyList = buyBag.ToList();

				// Sort the list so the instruments that have the highest buy value are first in the list.
				buyList.Sort(delegate(BestOfRootStrategies x, BestOfRootStrategies y) 
				{
					int xBar = x.Data.GetBar(currentDate);
					int yBar = y.Data.GetBar(currentDate);
					if (x.Bars[xBar].ExtraOrderInfo.ContainsKey("expectedGain"))
					{
						double xGain = (double)x.Bars[xBar].ExtraOrderInfo["expectedGain"];
						double yGain = (double)y.Bars[yBar].ExtraOrderInfo["expectedGain"];
						return yGain.CompareTo(xGain);
					}
					else
					{
						return y.Bars[yBar].HighestGain.CompareTo(x.Bars[xBar].HighestGain);
					}
				});

				// Output the buy list for each day.
				DataOutput.SaveBuyList(buyList, currentDate);

				// Update all the active orders before placing new ones.
				UpdateOrders(currentDate);

				// Keep tabs on the account cash at the start of the month. We want to 
				// limit our losses for the month.
				UpdateMonthlyAccountValue(currentDate);

				// Buy stocks if it's a good time.
				if (barNumber >= Config.NumBarsToDelayStart)
				{
					int currentCount = 0;
					for (int i = 0; i < buyList.Count; i++)
					{
						// Only allowed to have a maximum number of orders open at 1 time. This will limit us
						// to working within a budget later in the sim when we make money. Ex. If we start with
						// $100,000 and we double it in 2 years. We don't want to be investing our $200,000 worth
						// of cash. We still want to work with our original amount. This way we can see how much 
						// of a bankroll we'll need to make a living off investing.
						if (_activeOrders.Count >= Config.MaxOpenOrders || currentCount >= Config.MaxOrdersPerBar)
						{
							break;
						}

						// Also limit our losses and make sure we have not lost too much money this month.
						if (_isMonthlyLossExceeded)
						{
							break;
						}

						// If the highest percent is enough for a buy, then do it.
						// If not then since the list is sorted, no other ones will
						// be high enough and we can early out of the loop.
						int strategyBarIndex = buyList[i].Data.GetBar(currentDate);
						OrderSuggestion barStats = buyList[i].Bars[strategyBarIndex];
						if (barStats.HighestPercent > 0) // TODO: move to combo strategy && barStats.ComboSizeOfHighestStrategy >= Simulator.Config.MinComboSizeToBuy)
						{
							// Make sure we have enough money and also that we have enough time
							// before the end of the sim to complete the order we place.
							if (barNumber < NumberOfBars && Broker.AccountCash > barStats.SizeOfOrder * 1.1)
							{
								double sizeOfOrder = GetOrderSize(strategyBarIndex, barStats.SizeOfOrder, barStats.StrategyOrderType, buyList[i].Data);

								currentCount += EnterOrder(barStats.Statistics,
									barStats.StrategyOrderType, 
									buyList[i].Data, 
									strategyBarIndex,
									sizeOfOrder,
									barStats.DependentIndicators,
									barStats.BuyConditions,
									barStats.SellConditions,
									barStats.ExtraOrderInfo);
							}
						}
						else
						{
							break;
						}
					}
				}
			}
		}