public void SimulateMarket() { try { AxChartSpace chartSpace = this.axChartSpace; // It is possible for this foreground thread to be called after the thread has been terminated. This will prevent // the COM control from being accessed during a shutdown sequence. Also, if there is nothing to display there's no // need to continue trying to paint the chart. if (!this.isTickerRunning || chartSpace.Charts.Count == 0) { return; } ChChart chartMain = chartSpace.Charts[0]; int side = random.Next(0, 3); if (side == 0) { int range = this.market.Bid.Rows.Count; if (range == 0) { return; } int bidIndex = random.Next(0, range - 1); Market.BidRow bidRow = this.market.Bid[bidIndex]; int down = random.Next(0, 2); if (down == 0) { int largeBlock = random.Next(0, 3); double quantity = Convert.ToDouble(random.Next(1, largeBlock == 0 ? 20 : 5) * 100); bidRow.Quantity -= quantity; if (bidRow.Quantity <= 0.0) { bidRow.Quantity = 0.0; } } else { int largeBlock = random.Next(0, 3); double quantity = Convert.ToDouble(random.Next(1, largeBlock == 0 ? 20 : 5) * 100); bidRow.Quantity += quantity; } bidRow.AcceptChanges(); } else { if (side == 1) { int range = this.market.Ask.Rows.Count; if (range == 0) { return; } int askIndex = random.Next(0, range - 1); Market.AskRow askRow = this.market.Ask[askIndex]; int down = random.Next(0, 2); if (down == 0) { int largeBlock = random.Next(0, 3); double quantity = Convert.ToDouble(random.Next(1, largeBlock == 0 ? 20 : 5) * 100); askRow.Quantity -= quantity; if (askRow.Quantity <= 0.0) { askRow.Quantity = 0.0; } } else { int largeBlock = random.Next(0, 3); double quantity = Convert.ToDouble(random.Next(1, largeBlock == 0 ? 20 : 5) * 100); askRow.Quantity += quantity; } askRow.AcceptChanges(); } else { int largeBlock = random.Next(0, 3); int direction = random.Next(0, 3); double newPrice = this.lastPrice + (direction == 0 ? -0.01 : direction == 1 ? 0.0 : 0.01); Market.BidRow highestBid = null; foreach (Market.BidRow bidLoop in market.Bid) { if (highestBid == null || bidLoop.Price > highestBid.Price) { highestBid = bidLoop; } } Market.AskRow lowestAsk = null; foreach (Market.AskRow askLoop in market.Ask) { if (lowestAsk == null || askLoop.Price < lowestAsk.Price) { lowestAsk = askLoop; } } if (newPrice < highestBid.Price || lowestAsk.Price < newPrice) { return; } this.lastPrice = newPrice; this.lastQuantity = Convert.ToDouble(random.Next(1, largeBlock == 0 ? 20 : 5) * 100); } } Series series = GenerateSeries(); ChSeries chSeries = chartMain.SeriesCollection[0]; chSeries.SetData(ChartDimensionsEnum.chDimValues, (int)ChartSpecialDataSourcesEnum.chDataLiteral, series.values); chSeries.SetData(ChartDimensionsEnum.chDimFormatValues, (int)ChartSpecialDataSourcesEnum.chDataLiteral, series.format); } catch (Exception exception) { Console.WriteLine(exception.Message); } }
public void DisplayForeground(string securityName, decimal startingPrice) { lock (this) { try { lastPrice = 0.0; lastQuantity = 0.0; steps = 17; lowRange = Convert.ToDouble(startingPrice - startingPrice * 0.01M); highRange = Convert.ToDouble(startingPrice + startingPrice * 0.01M); stepSize = (highRange - lowRange) / steps; // Initialize the market InitializeMarket(Convert.ToDouble(startingPrice) + stepSize * 2.0); // Calculate a random price movement and go back in time building the history for this security. The // price movement will be anywhere between nothing and 10 cents. int direction = random.Next(0, 1); double priceChange = Math.Round(random.NextDouble() * direction == 0 ? -0.05 : 0.05, 2); double[] priceHistory = new Double[4]; priceHistory[0] = Convert.ToDouble(startingPrice) + (-priceChange * 2); priceHistory[1] = priceHistory[0] + priceChange; priceHistory[2] = priceHistory[1] + priceChange; priceHistory[3] = priceHistory[2] + priceChange; series = new Series[4]; series[0] = GenerateSeries(); this.MoveMarket(priceHistory[1]); series[1] = GenerateSeries(); this.MoveMarket(priceHistory[2]); series[2] = GenerateSeries(); this.MoveMarket(priceHistory[3]); series[3] = GenerateSeries(); object[] categories = new object[steps]; for (int step = 0; step < steps; step++) { categories[step] = Convert.ToDouble(Math.Round(lowRange + step * stepSize, 2)); } double maxQuantity = 0.0; for (int seriesIndex = 0; seriesIndex < 4; seriesIndex++) { for (int step = 0; step < steps; step++) { if (Convert.ToDouble(series[seriesIndex].values[step]) > maxQuantity) { maxQuantity = Convert.ToDouble(series[seriesIndex].values[step]); } } } // Clear the contents of the chart workspace. This removes // any old charts that may already exist and leaves the chart workspace // completely empty. One chart object is then added. AxChartSpace chartSpace = this.axChartSpace; chartSpace.Clear(); ChChart chartMain = chartSpace.Charts.Add(0); chartMain.Type = ChartChartTypeEnum.chChartTypeColumn3D; chartMain.PlotArea.BackWall.Interior.SetTextured(ChartPresetTextureEnum.chTextureWhiteMarble, ChartTextureFormatEnum.chTile, 0.0, ChartTexturePlacementEnum.chAllFaces); chartMain.PlotArea.SideWall.Interior.SetTextured(ChartPresetTextureEnum.chTextureWhiteMarble, ChartTextureFormatEnum.chTile, 0.0, ChartTexturePlacementEnum.chAllFaces); chartMain.PlotArea.Floor.Interior.SetTextured(ChartPresetTextureEnum.chTextureWhiteMarble, ChartTextureFormatEnum.chTile, 0.0, ChartTexturePlacementEnum.chAllFaces); chartMain.Overlap = 100; chartMain.ChartDepth = 50; chartMain.GapWidth = 50; chartMain.Perspective = 0; chartMain.ProjectionMode = ChartProjectionModeEnum.chProjectionModePerspective; chartMain.Inclination = 30.0; chartMain.DirectionalLightInclination = 10.0; chartMain.DirectionalLightRotation = 60.0; chartMain.DirectionalLightIntensity = 0.5; chartMain.Rotation = 330.0; chartMain.HasTitle = true; chartMain.Title.Caption = securityName; chartMain.Title.Font.Bold = true; chartMain.Title.Font.Name = "Ariel"; chartMain.Title.Font.Size = 12; chartMain.Axes[0].Scaling.Minimum = 1.0; chartMain.Axes[0].Scaling.Maximum = 17.0; chartMain.Axes[1].Scaling.Minimum = 0.0; chartMain.Axes[1].Scaling.Maximum = maxQuantity; chartMain.Axes[1].NumberFormat = "#0.00"; DateTime currentTime = DateTime.Now; // Bid Series ChSeries chSeries0 = chartMain.SeriesCollection.Add(0); chSeries0.Caption = (currentTime - new TimeSpan(0, 15, 0)).ToString("hh:mm"); chSeries0.Interior.SetSolid(ChRGB.Get(Color.Transparent)); chSeries0.Border.Color = ChRGB.Get(Color.Transparent); chSeries0.SetData(ChartDimensionsEnum.chDimCategories, (int)ChartSpecialDataSourcesEnum.chDataLiteral, categories); chSeries0.SetData(ChartDimensionsEnum.chDimValues, (int)ChartSpecialDataSourcesEnum.chDataLiteral, series[0].values); chSeries0.SetData(ChartDimensionsEnum.chDimFormatValues, (int)ChartSpecialDataSourcesEnum.chDataLiteral, series[0].format); AddBidAskSegment(chSeries0, 3); ChSeries chSeries1 = chartMain.SeriesCollection.Add(0); chSeries1.Caption = (currentTime - new TimeSpan(0, 10, 0)).ToString("hh:mm"); chSeries1.Interior.SetSolid(ChRGB.Get(Color.Transparent)); chSeries1.Border.Color = ChRGB.Get(Color.Transparent); chSeries1.SetData(ChartDimensionsEnum.chDimCategories, (int)ChartSpecialDataSourcesEnum.chDataLiteral, categories); chSeries1.SetData(ChartDimensionsEnum.chDimValues, (int)ChartSpecialDataSourcesEnum.chDataLiteral, series[1].values); chSeries1.SetData(ChartDimensionsEnum.chDimFormatValues, (int)ChartSpecialDataSourcesEnum.chDataLiteral, series[1].format); AddBidAskSegment(chSeries1, 2); ChSeries chSeries2 = chartMain.SeriesCollection.Add(0); chSeries2.Caption = (currentTime - new TimeSpan(0, 5, 0)).ToString("hh:mm"); chSeries2.Interior.SetSolid(ChRGB.Get(Color.Transparent)); chSeries2.Border.Color = ChRGB.Get(Color.Transparent); chSeries2.SetData(ChartDimensionsEnum.chDimCategories, (int)ChartSpecialDataSourcesEnum.chDataLiteral, categories); chSeries2.SetData(ChartDimensionsEnum.chDimValues, (int)ChartSpecialDataSourcesEnum.chDataLiteral, series[2].values); chSeries2.SetData(ChartDimensionsEnum.chDimFormatValues, (int)ChartSpecialDataSourcesEnum.chDataLiteral, series[2].format); AddBidAskSegment(chSeries2, 1); ChSeries chSeries3 = chartMain.SeriesCollection.Add(0); chSeries3.Caption = "Now"; chSeries3.Interior.SetSolid(ChRGB.Get(Color.Transparent)); chSeries3.Border.Color = ChRGB.Get(Color.Transparent); chSeries3.SetData(ChartDimensionsEnum.chDimCategories, (int)ChartSpecialDataSourcesEnum.chDataLiteral, categories); chSeries3.SetData(ChartDimensionsEnum.chDimValues, (int)ChartSpecialDataSourcesEnum.chDataLiteral, series[3].values); chSeries3.SetData(ChartDimensionsEnum.chDimFormatValues, (int)ChartSpecialDataSourcesEnum.chDataLiteral, series[3].format); AddBidAskSegment(chSeries3, 0); this.lastPrice = Convert.ToDouble(startingPrice); } catch (Exception exception) { Console.WriteLine(exception.Message); } } }