private void DelayedAction(Action action, string actionName) { var delay = RandomGen.GetInt(1, 2); Log($"Action '{actionName}' is delayed for {delay:0.##}sec"); Task.Delay(delay * 1000).ContinueWith(t => Dispatcher.GuiAsync(action)); }
public void UpdateData(Security sec, decimal price) { var ps = sec.PriceStep ?? 1; var msg = new Level1ChangeMessage { SecurityId = sec.ToSecurityId(), ServerTime = DateTimeOffset.Now, }; if (RandomGen.GetBool()) { msg.Changes.TryAdd(Level1Fields.BestBidPrice, price - RandomGen.GetInt(1, 10) * ps); } if (RandomGen.GetBool()) { msg.Changes.TryAdd(Level1Fields.BestAskPrice, price + RandomGen.GetInt(1, 10) * ps); } foreach (var l1Subscriptions in _l1Subscriptions) { _level1Received?.Invoke(l1Subscriptions, msg); } }
private void UpdateRealtimeCandles() { if (!_historyLoaded || !_isRealTime) { return; } var nextTick = (ExecutionMessage)_tradeGenerator.Process(new TimeMessage { ServerTime = _lastTime }); if (nextTick != null) { if (_candleTransform.Process(nextTick)) { var candles = _candleBuilder.Process(_mdMsg, _currCandle, _candleTransform); foreach (var candle in candles) { _currCandle = candle; _updatedCandles.Add((CandleMessage)candle.Clone()); } } } _lastTime += TimeSpan.FromMilliseconds(RandomGen.GetInt(100, 2000)); }
private void UpdateRealtimeCandles() { if (!_historyLoaded || !_isRealTime) { return; } var nextTick = (ExecutionMessage)_tradeGenerator.Process(new TimeMessage { ServerTime = _lastTime }); if (nextTick != null) { if (nextTick.TradePrice != null) { _testProvider.UpdateData(_security, nextTick.TradePrice.Value); } if (_candleTransform.Process(nextTick)) { var candles = _candleBuilder.Process(this, _candleTransform); foreach (var candle in candles) { _updatedCandles.Add(candle.TypedClone()); } } } _lastTime += TimeSpan.FromMilliseconds(RandomGen.GetInt(100, 20000)); }
private void ChartUpdateTimerOnTick(object sender, EventArgs eventArgs) { if (IsRealtime.IsChecked == true && _lastPrice != 0m) { var step = PriceStep.Value ?? 10; var price = Round(_lastPrice + (decimal)((RandomGen.GetDouble() - 0.5) * 5 * step), (decimal)step); AppendTick(_security, new ExecutionMessage { ServerTime = _lastTime, TradePrice = price, Volume = RandomGen.GetInt(50) + 1 }); _lastTime += TimeSpan.FromSeconds(10); } TimeFrameCandle[] candlesToUpdate; lock (_updatedCandles.SyncRoot) { candlesToUpdate = _updatedCandles.OrderBy(p => p.Key).Select(p => p.Value).ToArray(); _updatedCandles.Clear(); } _allCandles.AddRange(candlesToUpdate); candlesToUpdate.ForEach(c => { Chart.Draw(c.OpenTime, new Dictionary <IChartElement, object> { { _candleElement1, c }, }); }); }
private static Security CreateStrike(decimal strike, decimal oi, decimal iv, OptionTypes type, DateTime expiryDate, Security asset, decimal?lastTrade) { var s = new Security { Code = "RI {0} {1}".Put(type == OptionTypes.Call ? 'C' : 'P', strike), Strike = strike, OpenInterest = oi, ImpliedVolatility = iv, HistoricalVolatility = iv, OptionType = type, ExpiryDate = expiryDate, Board = ExchangeBoard.Forts, UnderlyingSecurityId = asset.Id, LastTrade = lastTrade == null ? null : new Trade { Price = lastTrade.Value }, Volume = RandomGen.GetInt(10000), Type = SecurityTypes.Option }; s.BestBid = new Quote(s, s.StepPrice ?? 1m * RandomGen.GetInt(100), s.VolumeStep ?? 1m * RandomGen.GetInt(100), Sides.Buy); s.BestAsk = new Quote(s, s.BestBid.Price.Max(s.StepPrice ?? 1m * RandomGen.GetInt(100)), s.VolumeStep ?? 1m * RandomGen.GetInt(100), Sides.Sell); return(s); }
static void Main() { // creating AAPL security var security = new Security { Id = "AAPL@NASDAQ", PriceStep = 0.1m, Decimals = 1, }; var trades = new List <Trade>(); // generation 1000 random ticks // for (var i = 0; i < 1000; i++) { var t = new Trade { Time = DateTime.Today + TimeSpan.FromMinutes(i), Id = i + 1, Security = security, Volume = RandomGen.GetInt(1, 10), Price = RandomGen.GetInt(1, 100) * security.PriceStep ?? 1m + 99 }; trades.Add(t); } using (var drive = new LocalMarketDataDrive()) { // get AAPL storage var aaplStorage = drive.GetSecurityDrive(security); // get tick storage var tradeStorage = (IMarketDataStorage <Trade>)aaplStorage.GetTickStorage(new CsvMarketDataSerializer <ExecutionMessage>()); // saving ticks tradeStorage.Save(trades); // loading ticks var loadedTrades = tradeStorage.Load(DateTime.Today, DateTime.Today + TimeSpan.FromMinutes(1000)); foreach (var trade in loadedTrades) { Console.WriteLine(LocalizedStrings.Str2968Params, trade.Id, trade); } Console.ReadLine(); // deleting ticks (and removing file) tradeStorage.Delete(DateTime.Today, DateTime.Today + TimeSpan.FromMinutes(1000)); } }
static void Main() { // создаем тестовый инструмент var security = new Security { Id = "TestId", PriceStep = 0.1m, Decimals = 1, }; var trades = new List <Trade>(); // генерируем 1000 произвольных сделок // for (var i = 0; i < 1000; i++) { var t = new Trade { Time = DateTime.Today + TimeSpan.FromMinutes(i), Id = i + 1, Security = security, Volume = RandomGen.GetInt(1, 10), Price = RandomGen.GetInt(1, 100) * security.PriceStep + 99 }; trades.Add(t); } var storage = new StorageRegistry(); // получаем хранилище для тиковых сделок var tradeStorage = storage.GetTradeStorage(security); // сохраняем сделки tradeStorage.Save(trades); // загружаем сделки var loadedTrades = tradeStorage.Load(DateTime.Today, DateTime.Today + TimeSpan.FromMinutes(1000)); foreach (var trade in loadedTrades) { Console.WriteLine(LocalizedStrings.Str2968Params, trade.Id, trade); } Console.ReadLine(); // удаляем сделки (очищаем файл) tradeStorage.Delete(DateTime.Today, DateTime.Today + TimeSpan.FromMinutes(1000)); }
private void NewAnnotation_Click(object sender, RoutedEventArgs e) { if (_currCandle == null) { return; } var values = Enumerator.GetValues <ChartAnnotationTypes>().ToArray(); _annotation = new ChartAnnotation { Type = values[RandomGen.GetInt(1, values.Length - 1)] }; _annotationData = null; Chart.AddElement(_areaComb, _annotation); ModifyAnnotation(true); }
private void ChartUpdateTimerOnTick(object sender, EventArgs eventArgs) { if (IsRealtime.IsChecked == true && _lastPrice != 0m) { var step = _priceStep; var price = Round(_lastPrice + (decimal)((RandomGen.GetDouble() - 0.5) * 5 * (double)step), step); AppendTick(_security, new ExecutionMessage { ServerTime = _lastTime, TradePrice = price, TradeVolume = RandomGen.GetInt(50) + 1, OriginSide = Sides.Buy, }); _lastTime += TimeSpan.FromSeconds(10); } TimeFrameCandle[] candlesToUpdate; lock (_updatedCandles.SyncRoot) { candlesToUpdate = _updatedCandles.OrderBy(p => p.Key).Select(p => p.Value).ToArray(); _updatedCandles.Clear(); } var lastCandle = _allCandles.LastOrDefault(); _allCandles.AddRange(candlesToUpdate.Where(c => lastCandle == null || c.OpenTime != lastCandle.OpenTime)); var hasValue = false; var chartData = new ChartDrawData(); foreach (var candle in candlesToUpdate) { chartData.Group(candle.OpenTime).Add(_candleElement1, candle); hasValue = true; } if (hasValue) { Chart.Draw(chartData); } }
private void Fill_Click(object sender, RoutedEventArgs e) { var order = SelectedOrder; if (IsInFinalState(order)) { Log($"Unable to fill order in state {order.State}"); return; } Log($"Fill order: {order}"); order.Balance -= RandomGen.GetInt(1, (int)order.Balance); if (order.Balance == 0) { order.State = OrderStates.Done; _orders.Remove(order); } Chart.Draw(new ChartDrawData().Add(_activeOrdersElement, order)); }
private void ChartUpdateTimerOnTick(object sender, EventArgs eventArgs) { if (!_dataIsLoaded || IsRealtime.IsChecked != true || _lastPrice == 0m) { return; } _lastTime += TimeSpan.FromSeconds(10); var numCandles = _candles.Count; AppendTick(new ExecutionMessage { ServerTime = _lastTime, TradePrice = Round(_lastPrice + (decimal)((RandomGen.GetDouble() - 0.5) * 5 * _priceStep), _priceStep), TradeVolume = RandomGen.GetInt(50) + 1 }); TimeFrameCandle candle; var lastLightCandle = _candles[_candles.Count - 1]; if (_candles.Count != numCandles && _lastCandle != null) { _lastCandle.State = CandleStates.Finished; DrawCandle(_lastCandle); } if (_candles.Count != numCandles || _lastCandle == null) { _lastCandle = candle = lastLightCandle.ToCandle(_tfSpan, _security); } else { candle = _lastCandle; lastLightCandle.UpdateCandle(candle); } DrawCandle(candle); }
private void ChartUpdateTimerOnTick(object sender, EventArgs eventArgs) { if (_checkRealtime.IsChecked == true && _lastPrice != 0m) { var step = _updownPriceStep.Value ?? 10; var price = Round(_lastPrice + (decimal)((RandomGen.GetDouble() - 0.5) * 5 * step), (decimal)step); AppendTick(new ExecutionMessage { ServerTime = _lastTime, TradePrice = price, Volume = RandomGen.GetInt(50) + 1 }); _lastTime += TimeSpan.FromSeconds(10); } var candlesToUpdate = _updatedCandles.OrderBy(c => c.OpenTime).ToArray(); _updatedCandles.Clear(); candlesToUpdate.ForEach(c => { _chartCombined.Draw(c.OpenTime, new Dictionary <IChartElement, object> { { _candleElement1, c } }); _chartCombined.Draw(c.OpenTime, new Dictionary <IChartElement, object> { { _bvElement, c } }); _chartBindVisibleRange.Draw(c.OpenTime, new Dictionary <IChartElement, object> { { _candleElement2, c } }); _chartBindVisibleRange.Draw(c.OpenTime, new Dictionary <IChartElement, object> { { _cpElement, c } }); }); }
private void StartBtnClick(object sender, RoutedEventArgs e) { if (_batchEmulation != null) { _batchEmulation.Resume(); return; } if (HistoryPath.Folder.IsEmpty() || !Directory.Exists(HistoryPath.Folder)) { MessageBox.Show(this, LocalizedStrings.Str3014); return; } TestingProcess.Value = 0; Curve.Clear(); Stat.Clear(); var logManager = new LogManager(); var fileLogListener = new FileLogListener("sample.log"); logManager.Listeners.Add(fileLogListener); // SMA periods var periods = new List <(int longMa, int shortMa, Color color)>(); for (var l = 100; l >= 50; l -= 10) { for (var s = 10; s >= 5; s -= 1) { periods.Add((l, s, Color.FromRgb((byte)RandomGen.GetInt(255), (byte)RandomGen.GetInt(255), (byte)RandomGen.GetInt(255)))); } } // storage to historical data var storageRegistry = new StorageRegistry { // set historical path DefaultDrive = new LocalMarketDataDrive(HistoryPath.Folder) }; var timeFrame = TimeSpan.FromMinutes(1); // create test security var security = new Security { Id = "SBER@TQBR", // sec id has the same name as folder with historical data Code = "SBER", Name = "SBER", Board = ExchangeBoard.Micex, }; var startTime = new DateTime(2020, 4, 1); var stopTime = new DateTime(2020, 4, 20); var level1Info = new Level1ChangeMessage { SecurityId = security.ToSecurityId(), ServerTime = startTime, } .TryAdd(Level1Fields.PriceStep, 0.01m) .TryAdd(Level1Fields.StepPrice, 0.01m) .TryAdd(Level1Fields.MinPrice, 0.01m) .TryAdd(Level1Fields.MaxPrice, 1000000m) .TryAdd(Level1Fields.MarginBuy, 10000m) .TryAdd(Level1Fields.MarginSell, 10000m); // test portfolio var portfolio = Portfolio.CreateSimulator(); // create backtesting connector _batchEmulation = new BatchEmulation(new[] { security }, new[] { portfolio }, storageRegistry) { EmulationSettings = { MarketTimeChangedInterval = timeFrame, StartTime = startTime, StopTime = stopTime, // count of parallel testing strategies // if not set, then CPU count * 2 //BatchSize = 3, } }; // handle historical time for update ProgressBar _batchEmulation.TotalProgressChanged += (currBatch, total) => this.GuiAsync(() => TestingProcess.Value = total); _batchEmulation.StateChanged += (oldState, newState) => { var isFinished = _batchEmulation.IsFinished; if (_batchEmulation.State == ChannelStates.Stopped) { _batchEmulation = null; } this.GuiAsync(() => { switch (newState) { case ChannelStates.Stopping: case ChannelStates.Starting: case ChannelStates.Suspending: SetIsEnabled(false, false, false); break; case ChannelStates.Stopped: SetIsEnabled(true, false, false); if (isFinished) { TestingProcess.Value = TestingProcess.Maximum; MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime)); } else { MessageBox.Show(this, LocalizedStrings.cancelled); } break; case ChannelStates.Started: SetIsEnabled(false, true, true); break; case ChannelStates.Suspended: SetIsEnabled(true, false, true); break; default: throw new ArgumentOutOfRangeException(newState.ToString()); } }); }; _startEmulationTime = DateTime.Now; var strategies = periods .Select(period => { var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame); // create strategy based SMA var strategy = new SampleHistoryTesting.SmaStrategy(series) { ShortSma = { Length = period.shortMa }, LongSma = { Length = period.longMa }, Volume = 1, Security = security, Portfolio = portfolio, //Connector = connector, // by default interval is 1 min, // it is excessively for time range with several months UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>() }; this.GuiSync(() => { var curveElem = Curve.CreateCurve(LocalizedStrings.Str3026Params.Put(period.Item1, period.Item2), period.Item3, ChartIndicatorDrawStyles.Line); strategy.PnLChanged += () => { var data = new ChartDrawData(); data .Group(strategy.CurrentTime) .Add(curveElem, strategy.PnL); Curve.Draw(data); }; Stat.AddStrategies(new[] { strategy }); }); return(strategy); }); // start emulation _batchEmulation.Start(strategies, periods.Count); }
private void ModifyAnnotation(bool isNew) { Brush RandomBrush() { var b = new SolidColorBrush(Color.FromRgb((byte)RandomGen.GetInt(0, 255), (byte)RandomGen.GetInt(0, 255), (byte)RandomGen.GetInt(0, 255))); b.Freeze(); return(b); } if (_annotation == null) { return; } IComparable x1, x2, y1, y2; var mode = RandomGen.GetDouble() > 0.5 ? AnnotationCoordinateMode.Absolute : AnnotationCoordinateMode.Relative; if (_annotationData == null) { if (mode == AnnotationCoordinateMode.Absolute) { GetMiddle(out var x0, out var y0); x1 = x0 - TimeSpan.FromMinutes(RandomGen.GetInt(10, 60)); x2 = x0 + TimeSpan.FromMinutes(RandomGen.GetInt(10, 60)); y1 = y0 - RandomGen.GetInt(5, 10) * _security.PriceStep ?? 0.01m; y2 = y0 + RandomGen.GetInt(5, 10) * _security.PriceStep ?? 0.01m; } else { x1 = 0.5 - RandomGen.GetDouble() / 10; x2 = 0.5 + RandomGen.GetDouble() / 10; y1 = 0.5 - RandomGen.GetDouble() / 10; y2 = 0.5 - RandomGen.GetDouble() / 10; } } else { mode = _annotationData.CoordinateMode.Value; if (mode == AnnotationCoordinateMode.Absolute) { x1 = (DateTimeOffset)_annotationData.X1 - TimeSpan.FromMinutes(1); x2 = (DateTimeOffset)_annotationData.X2 + TimeSpan.FromMinutes(1); y1 = (decimal)_annotationData.Y1 + _security.PriceStep ?? 0.01m; y2 = (decimal)_annotationData.Y2 - _security.PriceStep ?? 0.01m; } else { x1 = ((double)_annotationData.X1) - 0.05; x2 = ((double)_annotationData.X2) + 0.05; y1 = ((double)_annotationData.Y1) - 0.05; y2 = ((double)_annotationData.Y2) + 0.05; } } _dataThreadActions.Add(() => { var data = new ChartDrawData.AnnotationData { X1 = x1, X2 = x2, Y1 = y1, Y2 = y2, IsVisible = true, Fill = RandomBrush(), Stroke = RandomBrush(), Foreground = RandomBrush(), Thickness = new Thickness(RandomGen.GetInt(1, 5)), }; if (isNew) { data.Text = "random annotation #" + (++_annotationId); data.HorizontalAlignment = HorizontalAlignment.Stretch; data.VerticalAlignment = VerticalAlignment.Stretch; data.LabelPlacement = LabelPlacement.Axis; data.ShowLabel = true; data.CoordinateMode = mode; } var dd = new ChartDrawData(); dd.Add(_annotation, data); Chart.Draw(dd); }); }
/// <inheritdoc /> protected override Message OnProcess(Message message) { DateTimeOffset time; switch (message.Type) { case MessageTypes.Board: return(null); case MessageTypes.Level1Change: { var l1Msg = (Level1ChangeMessage)message; var value = l1Msg.TryGetDecimal(Level1Fields.LastTradePrice); if (value != null) { _lastTradePrice = value.Value; } time = l1Msg.ServerTime; break; } case MessageTypes.Execution: { var execMsg = (ExecutionMessage)message; var price = execMsg.TradePrice; if (price != null) { _lastTradePrice = price.Value; } else if (execMsg.ExecutionType != ExecutionTypes.OrderLog) { return(null); } time = execMsg.ServerTime; break; } case MessageTypes.Time: { var timeMsg = (TimeMessage)message; time = timeMsg.ServerTime; break; } default: return(null); } if (!IsTimeToGenerate(time)) { return(null); } var trade = new ExecutionMessage { SecurityId = SecurityId, TradeId = IdGenerator.GetNextId(), ServerTime = time, LocalTime = time, OriginSide = GenerateOriginSide ? RandomGen.GetEnum <Sides>() : null, TradeVolume = Volumes.Next(), ExecutionType = ExecutionTypes.Tick }; var priceStep = SecurityDefinition.PriceStep ?? 0.01m; _lastTradePrice += RandomGen.GetInt(-MaxPriceStepCount, MaxPriceStepCount) * priceStep; if (_lastTradePrice <= 0) { _lastTradePrice = priceStep; } trade.TradePrice = _lastTradePrice; LastGenerationTime = time; return(trade); }
public void UpdateData(Security sec, decimal price) { var ps = sec.PriceStep ?? 1; var list = new List <KeyValuePair <Level1Fields, object> >(); if (RandomGen.GetBool()) { list.Add(new KeyValuePair <Level1Fields, object>(Level1Fields.BestBidPrice, price - RandomGen.GetInt(1, 10) * ps)); } if (RandomGen.GetBool()) { list.Add(new KeyValuePair <Level1Fields, object>(Level1Fields.BestAskPrice, price + RandomGen.GetInt(1, 10) * ps)); } var now = DateTimeOffset.Now; ValuesChanged?.Invoke(sec, list, now, now); }
private static Color GetRandomColor() => Color.FromRgb((byte)RandomGen.GetInt(0, 255), (byte)RandomGen.GetInt(0, 255), (byte)RandomGen.GetInt(0, 255));
protected override void OnSendInMessage(Message message) { switch (message.Type) { case MessageTypes.Reset: SendOutMessage(new ResetMessage()); break; case MessageTypes.Connect: SendOutMessage(new ConnectMessage()); break; case MessageTypes.Disconnect: SendOutMessage(new DisconnectMessage()); break; case MessageTypes.SecurityLookup: { var lookupMsg = (SecurityLookupMessage)message; foreach (var id in new[] { "RIZ2@FORTS", "@ES#@CMEMINI" }) { SendOutMessage(new SecurityMessage { SecurityId = id.ToSecurityId(), OriginalTransactionId = lookupMsg.TransactionId, }); } SendOutMessage(new SecurityLookupResultMessage { OriginalTransactionId = lookupMsg.TransactionId }); break; } case MessageTypes.MarketData: { var mdMsg = (MarketDataMessage)message; switch (mdMsg.DataType) { case MarketDataTypes.CandleTimeFrame: { if (mdMsg.IsSubscribe) { var start = mdMsg.From.Value; var stop = mdMsg.To.Value; var tf = mdMsg.GetTimeFrame(); // sends subscribed successfully SendOutMarketDataReply(mdMsg.TransactionId); const decimal step = 0.01m; for (var curr = start; curr < stop; curr += tf) { var price = RandomGen.GetInt(100, 110); var open = price + RandomGen.GetInt(10) * step; var high = open + RandomGen.GetInt(10) * step; var low = high - RandomGen.GetInt(10) * step; var close = low + RandomGen.GetInt(10) * step; if (high < low) { var d = high; high = low; low = d; } SendOutMessage(new TimeFrameCandleMessage { OriginalTransactionId = mdMsg.TransactionId, OpenPrice = open, HighPrice = high, LowPrice = low, ClosePrice = close, OpenTime = curr, State = CandleStates.Finished, }); } SendOutMessage(new MarketDataFinishedMessage { OriginalTransactionId = mdMsg.TransactionId }); } else { // sends unsubscribed successfully SendOutMarketDataReply(mdMsg.TransactionId); } break; } default: // not supported other data types SendOutMarketDataNotSupported(mdMsg.TransactionId); break; } break; } } }
/// <summary> /// Обработать сообщение. /// </summary> /// <param name="message">Сообщение.</param> /// <returns>Результат обработки. Если будет возрвщено <see langword="null"/>, /// то генератору пока недостаточно данных для генерации нового сообщения.</returns> protected override Message OnProcess(Message message) { DateTimeOffset time; switch (message.Type) { case MessageTypes.Level1Change: { var l1Msg = (Level1ChangeMessage)message; var value = l1Msg.Changes.TryGetValue(Level1Fields.LastTradePrice); if (value != null) { _lastOrderPrice = (decimal)value; } TradeGenerator.Process(message); time = l1Msg.ServerTime; break; } case MessageTypes.Execution: { var execMsg = (ExecutionMessage)message; switch (execMsg.ExecutionType) { case ExecutionTypes.Tick: _lastOrderPrice = execMsg.GetTradePrice(); break; default: return(null); } time = execMsg.ServerTime; break; } case MessageTypes.Time: { var timeMsg = (TimeMessage)message; time = timeMsg.ServerTime; break; } default: return(null); } if (!IsTimeToGenerate(time)) { return(null); } // TODO более реалистичную генерацию, так как сейчас объемы, цены и сделки c потолка var action = RandomGen.GetInt(0, 5); var isNew = action < 3 || _activeOrders.IsEmpty(); ExecutionMessage item; if (isNew) { var priceStep = SecurityDefinition.PriceStep ?? 0.01m; _lastOrderPrice += RandomGen.GetInt(-MaxPriceStepCount, MaxPriceStepCount) * priceStep; if (_lastOrderPrice <= 0) { _lastOrderPrice = priceStep; } item = new ExecutionMessage { OrderId = IdGenerator.GetNextId(), SecurityId = SecurityId, ServerTime = time, OrderState = OrderStates.Active, Volume = Volumes.Next(), Side = RandomGen.GetEnum <Sides>(), Price = _lastOrderPrice, ExecutionType = ExecutionTypes.OrderLog, }; _activeOrders.Enqueue((ExecutionMessage)item.Clone()); } else { var activeOrder = _activeOrders.Peek(); item = (ExecutionMessage)activeOrder.Clone(); item.ServerTime = time; var isMatched = action == 5; ExecutionMessage trade = null; if (isMatched) { trade = (ExecutionMessage)TradeGenerator.Process(message); } if (isMatched && trade != null) { item.Volume = RandomGen.GetInt(1, (int)activeOrder.GetVolume()); item.TradeId = trade.TradeId; item.TradePrice = trade.TradePrice; item.TradeStatus = trade.TradeStatus; // TODO //quote.Trade = TradeGenerator.Generate(time); //item.Volume = activeOrder.Volume; //if (item.Side == Sides.Buy && quote.Trade.Price > quote.Order.Price) // item.TradePrice = item.Price; //else if (item.Side == Sides.Sell && quote.Trade.Price < quote.Order.Price) // item.TradePrice = item.Price; activeOrder.Volume -= item.Volume; if (activeOrder.Volume == 0) { item.OrderState = OrderStates.Done; _activeOrders.Dequeue(); } else { item.OrderState = OrderStates.Active; } } else { item.OrderState = OrderStates.Done; item.IsCancelled = true; _activeOrders.Dequeue(); } } LastGenerationTime = time; return(item); }
private void Move_Click(object sender, RoutedEventArgs e) { Chart_OnMoveOrder(SelectedOrder, SelectedOrder.Price + RandomGen.GetInt(-3, 3) * _priceStep); }
private void ChartUpdateTimerOnTick(object sender, EventArgs eventArgs) { if (_historyLoaded && IsRealtime.IsChecked == true) { var nextTick = (ExecutionMessage)_tradeGenerator.Process(new TimeMessage { ServerTime = _lastTime }); if (nextTick != null) { if (_candleTransform.Process(nextTick)) { var candles = _candleBuilder.Process(_mdMsg, _currCandle, _candleTransform); lock (_lock) { foreach (var candle in candles) { _currCandle = candle; _updatedCandles[candle.OpenTime] = Tuple.Create(candle, candle.State == CandleStates.Finished); } } } } _lastTime += TimeSpan.FromSeconds(RandomGen.GetInt(1, 10)); } Tuple <Candle, bool>[] candlesToUpdate; lock (_updatedCandles.SyncRoot) { candlesToUpdate = _updatedCandles.OrderBy(p => p.Key).Select(p => Tuple.Create(p.Value.Item1.ToCandle(_security), p.Value.Item2)).ToArray(); _updatedCandles.Clear(); } var lastCandle = _allCandles.LastOrDefault(); _allCandles.AddRange(candlesToUpdate.Where(c => lastCandle == null || c.Item1.OpenTime != lastCandle.OpenTime).Select(t => t.Item1)); ChartDrawData chartData = null; foreach (var tuple in candlesToUpdate) { var candle = tuple.Item1; var needToFinish = tuple.Item2; if (chartData == null) { chartData = new ChartDrawData(); } if (needToFinish && candle.State != CandleStates.Finished) { candle.State = CandleStates.Finished; } var chartGroup = chartData.Group(candle.OpenTime); lock (_lock) { chartGroup.Add(_candleElement, candle); } foreach (var pair in _indicators.CachedPairs) { chartGroup.Add(pair.Key, pair.Value.Process(candle)); } } if (chartData != null) { Chart.Draw(chartData); } }