/// <inheritdoc /> public virtual IMessageAdapter TryGetAdapter(string portfolioName) { if (portfolioName.IsEmpty()) { throw new ArgumentNullException(nameof(portfolioName)); } return(_adapters.TryGetValue(portfolioName)); }
/// <summary> /// To get a board by the code. /// </summary> /// <param name="code">The board code <see cref="ExchangeBoard.Code"/>.</param> /// <returns>Trading board. If the board with the specified code does not exist, then <see langword="null" /> will be returned.</returns> public ExchangeBoard GetExchangeBoard(string code) { if (code.IsEmpty()) { throw new ArgumentNullException(nameof(code)); } return(_boards.TryGetValue(code)); }
/// <summary> /// To get an exchange by the code. /// </summary> /// <param name="code">The exchange code <see cref="Exchange.Name"/>.</param> /// <returns>Exchange. If the exchange with the specified code does not exist, then <see langword="null" /> will be returned.</returns> public Exchange GetExchange(string code) { if (code.IsEmpty()) { throw new ArgumentNullException(nameof(code)); } if (code.CompareIgnoreCase("RTS")) { code = "FORTS"; } return(_exchanges.TryGetValue(code)); }
private void Refresh() { var ids = Invoke(f => f.GetStrategies(_lastCheckTime)).ToArray(); foreach (var tuple in ids.Where(t => t.Item2 < 0)) { var strategy = _strategies.TryGetValue(tuple.Item1); if (strategy != null) { StrategyDeleted?.Invoke(strategy); } } var newIds = new List <long>(); var updatedIds = new List <long>(); foreach (var tuple in ids.Where(t => t.Item2 >= 0)) { var strategy = _strategies.TryGetValue(tuple.Item1); if (strategy != null) { updatedIds.Add(tuple.Item1); } else { newIds.Add(tuple.Item1); } } var newStrategies = Invoke(f => f.GetDescription(newIds.ToArray())); foreach (var newStrategy in newStrategies) { _strategies.Add(newStrategy.Id, newStrategy); StrategyCreated?.Invoke(newStrategy); } var updatedStrategies = Invoke(f => f.GetDescription(updatedIds.ToArray())); foreach (var updatedStrategy in updatedStrategies) { var strategy = _strategies[updatedStrategy.Id]; CopyTo(updatedStrategy, strategy); StrategyUpdated?.Invoke(strategy); } _lastCheckTime = DateTime.Now; }
/// <summary> /// To process the message, containing market data. /// </summary> /// <param name="message">The message, containing market data.</param> public void ProcessMessage(Message message) { switch (message.Type) { case MessageTypes.Execution: { var execMsg = (ExecutionMessage)message; if (execMsg.ExecutionType != ExecutionTypes.Tick) { break; } var queue = _securityPnLs.TryGetValue(execMsg.SecurityId); if (queue != null) { queue.ProcessExecution(execMsg); } break; } case MessageTypes.Level1Change: { var levelMsg = (Level1ChangeMessage)message; var queue = _securityPnLs.TryGetValue(levelMsg.SecurityId); if (queue != null) { queue.ProcessLevel1(levelMsg); } break; } case MessageTypes.QuoteChange: { var quoteMsg = (QuoteChangeMessage)message; var queue = _securityPnLs.TryGetValue(quoteMsg.SecurityId); if (queue != null) { queue.ProcessQuotes(quoteMsg); } break; } } }
///// <summary> ///// To get the source or executable codes. ///// </summary> ///// <param name="strategy">The strategy data.</param> //public void Download(StrategyData strategy) //{ // if (strategy == null) // throw new ArgumentNullException(nameof(strategy)); // var content = Invoke(f => f.GetContent(SessionId, strategy.Id)); // strategy.Revision = content.Revision; // strategy.Content = content.Content; // strategy.ContentName = content.ContentName; //} /// <summary> /// To subscribe for the strategy. /// </summary> /// <param name="isAutoRenew">Is auto renewable subscription.</param> /// <param name="strategy">The strategy data.</param> /// <returns>The strategy subscription.</returns> public StrategySubscription Subscribe(StrategyData strategy, bool isAutoRenew) { if (strategy == null) { throw new ArgumentNullException(nameof(strategy)); } var subscription = Invoke(f => f.Subscribe(SessionId, strategy.Id, isAutoRenew)); if (subscription.Id < 0) { ValidateError((byte)-subscription.Id, strategy.Id); } else { lock (_subscriptions.SyncRoot) { var prevSubscr = _subscriptions.TryGetValue(subscription.Id); if (prevSubscr == null) { _subscriptions.Add(subscription.Id, subscription); } else { subscription = prevSubscr; } } StrategySubscribed?.Invoke(subscription); } return(subscription); }
/// <summary> /// Зарегистрировать индикатор. После регистрации данный индикатор начнет обновляться с использованием переданного источника. /// Если по данному источнику уже есть сохраненные данные, то они будут использованы для инициализации индикатора. /// Если пара индикатор-источник уже была ранее зарегистрирована, то вернется существующий токен. /// </summary> /// <param name="indicator">Индикатор.</param> /// <param name="source">Источник данных для индикатора.</param> /// <returns>Токен, который был зарегистрирован.</returns> public virtual IndicatorToken RegisterIndicator(IIndicator indicator, IIndicatorSource source) { lock (_indicatorUsages.SyncRoot) { var token = new IndicatorToken(indicator, source); var inDict = _indicatorUsages.TryGetValue(token); if (inDict != null) { //найден индикатор, увеличим количество ссылок inDict.Second++; return(inDict.First); } //индикатора нет, добавим lock (_sources.SyncRoot) { var indicators = _sources.SafeAdd(source, key => new IndicatorList(this, key)); token = new IndicatorToken(indicator, indicators.Source) { Container = Container }; _indicatorUsages.Add(token, new RefPair <IndicatorToken, int>(token, 1)); indicators.Add(token); // тут пройдет подписка на события источника и обработка тех значений, которые уже есть в источнике } return(token); } }
public Position TryAddPosition(Portfolio portfolio, Security security, string clientCode, string depoName, TPlusLimits?limitType, string description, out bool isNew) { isNew = false; Position position; lock (_positions.SyncRoot) { if (depoName == null) { depoName = string.Empty; } if (clientCode == null) { clientCode = string.Empty; } var key = Tuple.Create(portfolio, security, clientCode, depoName, limitType); if (!_positions.TryGetValue(key, out position)) { isNew = true; position = EntityFactory.CreatePosition(portfolio, security); position.DepoName = depoName; position.LimitType = limitType; position.Description = description; position.ClientCode = clientCode; _positions.Add(key, position); } } return(position); }
/// <summary> /// Сообщить, что данный токен больше не требуется. /// Если количество вызовов будет равно количеству вызовов <see cref="RegisterIndicator"/>, то все данные по индикатору будут удалены. /// </summary> /// <param name="indicatorToken">Токен индикатора.</param> public virtual void UnRegisterIndicator(IndicatorToken indicatorToken) { lock (_indicatorUsages.SyncRoot) { var inDict = _indicatorUsages[indicatorToken]; if (inDict.Second <= 0) { throw new InvalidOperationException(); } if (--inDict.Second == 0) { _indicatorUsages.Remove(indicatorToken); //чистим значения в контейнере Container.RemoveIndicator(indicatorToken); //удаляем из списка источника lock (_sources.SyncRoot) { var indicators = _sources.TryGetValue(indicatorToken.Source); if (indicators != null) { indicators.Remove(indicatorToken); } } } } }
/// <summary> /// Load settings. /// </summary> /// <param name="storage">Settings storage.</param> public void Load(SettingsStorage storage) { var drives = storage .GetValue <IEnumerable <SettingsStorage> >(nameof(Drives)) .Select(s => s.LoadEntire <IMarketDataDrive>()) .ToArray(); lock (_drives.SyncRoot) { foreach (var drive in drives) { _drives.TryAdd(CreatePair(drive.Path), drive); } } if (storage.ContainsKey(nameof(DefaultDrive))) { var pair = CreatePair(storage.GetValue <string>(nameof(DefaultDrive))); if (_drives.TryGetValue(pair, out var drive)) { DefaultDrive = drive; } } }
/// <inheritdoc /> public Portfolio LookupByPortfolioName(string name) { if (name.IsEmpty()) { throw new ArgumentNullException(nameof(name)); } return(_inner.TryGetValue(name)); }
/// <summary> /// To get an exchange by the code. /// </summary> /// <param name="code">The exchange code <see cref="Exchange.Name"/>.</param> /// <returns>Exchange. If the exchange with the specified code does not exist, then <see langword="null" /> will be returned.</returns> public Exchange GetExchange(string code) { if (code.IsEmpty()) { throw new ArgumentNullException("code"); } return(_exchanges.TryGetValue(code)); }
IExtendedInfoStorageItem IExtendedInfoStorage.Get(string storageName) { if (storageName.IsEmpty()) { throw new ArgumentNullException(nameof(storageName)); } return(_items.TryGetValue(storageName)); }
private void DecRefProcessor(IMessageProcessor processor) { var ptr = _processorPointers.TryGetValue(processor); if (ptr != null) { ptr.DecRef(); } }
/// <summary> /// Прекратить получение данных, запущенное через <see cref="Start"/>. /// </summary> /// <param name="series">Серия свечек.</param> public override void Stop(CandleSeries series) { lock (_series.SyncRoot) { var info = _series.TryGetValue(series); if (info != null) { info.IsStopping = true; } } }
public void UpdateTimeOut(long transactionId) { if (transactionId == 0) { return; } lock (_registeredIds.SyncRoot) { if (!_registeredIds.TryGetValue(transactionId, out var timeOut)) { return; } _registeredIds[transactionId] = timeOut; } }
private MarketDataGenerator TryGetGenerator(MarketDataMessage message) { switch (message.DataType) { case MarketDataTypes.Trades: return(_tradeGenerators.TryGetValue(message.SecurityId)); case MarketDataTypes.MarketDepth: return(_depthGenerators.TryGetValue(message.SecurityId)); case MarketDataTypes.OrderLog: return(_orderLogGenerators.TryGetValue(message.SecurityId)); default: return(null); } }
public void UpdateTimeOut <TMessage>(TMessage message) where TMessage : IOriginalTransactionIdMessage { var transactionId = message.OriginalTransactionId; if (transactionId == 0) { return; } lock (_registeredIds.SyncRoot) { if (!_registeredIds.TryGetValue(transactionId, out var timeOut)) { return; } _registeredIds[transactionId] = timeOut; } }
T IStorageEntityList <T> .ReadById(object id) { return(_items.TryGetValue(id)); }
/// <summary> /// To calculate position. /// </summary> /// <param name="message">Message.</param> /// <returns>The position by order or trade.</returns> public decimal?ProcessMessage(Message message) { switch (message.Type) { case MessageTypes.Reset: { Reset(); break; } case MessageTypes.Execution: { var execMsg = (ExecutionMessage)message; var key = Tuple.Create(execMsg.SecurityId, execMsg.PortfolioName); if (ByOrders && execMsg.HasOrderInfo()) { var orderId = execMsg.OriginalTransactionId; var newPosition = execMsg.GetPosition(); bool isNew; decimal position; lock (_positions.SyncRoot) { decimal prev; isNew = _positions.TryGetValue(key, out prev); Tuple <Sides, decimal> oldPosition; if (_byOrderPositions.TryGetValue(orderId, out oldPosition)) { if (newPosition != oldPosition.Item2) { _byOrderPositions[orderId] = Tuple.Create(execMsg.Side, newPosition); } position = newPosition - oldPosition.Item2; } else { _byOrderPositions.Add(orderId, Tuple.Create(execMsg.Side, newPosition)); position = newPosition; } _positions[key] = prev + position; Position += position; } if (isNew) { NewPosition?.Invoke(new KeyValuePair <Tuple <SecurityId, string>, decimal>(key, Position)); } else { PositionChanged?.Invoke(new KeyValuePair <Tuple <SecurityId, string>, decimal>(key, Position)); } return(position); } if (!ByOrders && execMsg.HasTradeInfo()) { var position = execMsg.GetPosition(); if (position == 0) { break; } bool isNew; lock (_positions.SyncRoot) { decimal prev; isNew = _positions.TryGetValue(key, out prev); _positions[key] = prev + position; Position += position; } if (isNew) { NewPosition?.Invoke(new KeyValuePair <Tuple <SecurityId, string>, decimal>(key, Position)); } else { PositionChanged?.Invoke(new KeyValuePair <Tuple <SecurityId, string>, decimal>(key, Position)); } return(position); } break; } } return(null); }
private void Refresh() { var ids = Invoke(f => f.GetStrategies(_lastCheckTime)).ToArray(); foreach (var tuple in ids.Where(t => t.Item2 < 0)) { var strategy = _strategies.TryGetValue(tuple.Item1); if (strategy != null) { StrategyDeleted?.Invoke(strategy); } } var newIds = new List <long>(); var updatedIds = new List <long>(); foreach (var tuple in ids.Where(t => t.Item2 >= 0)) { var strategy = _strategies.TryGetValue(tuple.Item1); if (strategy != null) { updatedIds.Add(tuple.Item1); } else { newIds.Add(tuple.Item1); } } var newStrategies = Invoke(f => f.GetDescription(newIds.ToArray())); foreach (var newStrategy in newStrategies) { _strategies.Add(newStrategy.Id, newStrategy); StrategyCreated?.Invoke(newStrategy); } var updatedStrategies = Invoke(f => f.GetDescription(updatedIds.ToArray())); foreach (var updatedStrategy in updatedStrategies) { var strategy = _strategies[updatedStrategy.Id]; CopyTo(updatedStrategy, strategy); StrategyUpdated?.Invoke(strategy); } _lastCheckTime = DateTime.Now; foreach (var backtest in _backtests.CachedValues) { if (_backtestResults.ContainsKey(backtest)) { continue; } var resultId = Invoke(f => f.GetBacktestResult(SessionId, backtest.Id)); if (resultId == null) { continue; } _backtestResults.Add(backtest, resultId.Value); BacktestStopped?.Invoke(backtest); _startedBacktests.Remove(backtest); } foreach (var backtest in _startedBacktests.CachedKeys) { var count = Invoke(f => f.GetCompletedIterationCount(SessionId, backtest.Id)); var prevCount = _startedBacktests[backtest]; if (count == prevCount) { continue; } BacktestProgressChanged?.Invoke(backtest, count); if (count == backtest.Iterations.Length) { _startedBacktests.Remove(backtest); } else { _startedBacktests[backtest] = count; } } }
ExchangeBoard IExchangeInfoProvider.GetExchangeBoard(string code) { return(_boards.TryGetValue(code)); }
Exchange IExchangeInfoProvider.GetExchange(string code) { return(_exchanges.TryGetValue(code)); }
public T ReadById(object id) { return(_items.TryGetValue(id)); }
/// <summary> /// To process the message, containing market data. /// </summary> /// <param name="message">The message, containing market data.</param> /// <returns><see cref="PnL"/> was changed.</returns> public bool ProcessMessage(Message message) { switch (message.Type) { case MessageTypes.Execution: { var execMsg = (ExecutionMessage)message; if (execMsg.ExecutionType != ExecutionTypes.Tick) { break; } var queue = _securityPnLs.TryGetValue(execMsg.SecurityId); if (queue == null) { break; } queue.ProcessExecution(execMsg); return(true); } case MessageTypes.Level1Change: { var levelMsg = (Level1ChangeMessage)message; var queue = _securityPnLs.TryGetValue(levelMsg.SecurityId); if (queue == null) { break; } queue.ProcessLevel1(levelMsg); return(true); } case MessageTypes.QuoteChange: { var quoteMsg = (QuoteChangeMessage)message; var queue = _securityPnLs.TryGetValue(quoteMsg.SecurityId); if (queue == null) { break; } queue.ProcessQuotes(quoteMsg); return(true); } case MessageTypes.PositionChange: { var posMsg = (PositionChangeMessage)message; var leverage = posMsg.Changes.TryGetValue(PositionChangeTypes.Leverage).To <decimal?>(); if (leverage != null) { if (posMsg.IsMoney()) { _securityPnLs.CachedValues.ForEach(q => q.Leverage = leverage.Value); } else { _securityPnLs.SafeAdd(posMsg.SecurityId, security => new PnLQueue(security)).Leverage = leverage.Value; } } break; } } return(false); }
/// <summary> /// To process the message, containing market data. /// </summary> /// <param name="message">The message, containing market data.</param> public void ProcessMessage(Message message) { switch (message.Type) { case MessageTypes.Execution: { var execMsg = (ExecutionMessage)message; if (execMsg.ExecutionType != ExecutionTypes.Tick) { break; } var queue = _securityPnLs.TryGetValue(execMsg.SecurityId); queue?.ProcessExecution(execMsg); break; } case MessageTypes.Level1Change: { var levelMsg = (Level1ChangeMessage)message; var queue = _securityPnLs.TryGetValue(levelMsg.SecurityId); queue?.ProcessLevel1(levelMsg); break; } case MessageTypes.QuoteChange: { var quoteMsg = (QuoteChangeMessage)message; var queue = _securityPnLs.TryGetValue(quoteMsg.SecurityId); queue?.ProcessQuotes(quoteMsg); break; } case MessageTypes.PortfolioChange: { var pfMsg = (PortfolioChangeMessage)message; var leverage = pfMsg.Changes.TryGetValue(PositionChangeTypes.Leverage).To <decimal?>(); if (leverage != null) { _securityPnLs.CachedValues.ForEach(q => q.Leverage = leverage.Value); } break; } case MessageTypes.PositionChange: { var posMsg = (PositionChangeMessage)message; var leverage = posMsg.Changes.TryGetValue(PositionChangeTypes.Leverage).To <decimal?>(); if (leverage != null) { _securityPnLs.SafeAdd(posMsg.SecurityId, security => new PnLQueue(security)).Leverage = leverage.Value; } break; } } }
/// <summary> /// Get series by request identifier. /// </summary> /// <param name="transactionId">Request identifier.</param> /// <returns>Candles series or <see langword="null"/> if identifier is non exist.</returns> public CandleSeries TryGetCandleSeries(long transactionId) => _holders.TryGetValue(transactionId)?.Series;
public OrderInfo TryGetOrder(OrderTypes?type, long transactionId, bool isCancel) { return(Orders.TryGetValue(CreateOrderKey(type, transactionId, isCancel)) ?? (type == null ? Orders.TryGetValue(CreateOrderKey(OrderTypes.Conditional, transactionId, isCancel)) : null)); }
/// <summary> /// Send message. /// </summary> /// <param name="message">Message.</param> protected override void OnSendInMessage(Message message) { switch (message.Type) { case MessageTypes.Reset: ProcessReset(message); break; case MessageTypes.Connect: if (_isFirstConnect) { _isFirstConnect = false; } else { ProcessReset(new ResetMessage()); } _hearbeatAdapters.AddRange(GetSortedAdapters().ToDictionary(a => a, a => { var hearbeatAdapter = (IMessageAdapter) new HeartbeatAdapter(a); hearbeatAdapter.Parent = this; hearbeatAdapter.NewOutMessage += m => OnInnerAdapterNewMessage(a, m); return(hearbeatAdapter); })); if (_hearbeatAdapters.Count == 0) { throw new InvalidOperationException(LocalizedStrings.Str3650); } _hearbeatAdapters.Values.ForEach(a => a.SendInMessage(message)); break; case MessageTypes.Disconnect: _connectedAdapters .CachedValues .SelectMany(c => c.Cache) .Distinct() .ForEach(a => a.SendInMessage(message)); break; case MessageTypes.Portfolio: { var pfMsg = (PortfolioMessage)message; ProcessPortfolioMessage(pfMsg.PortfolioName, pfMsg); break; } case MessageTypes.OrderRegister: case MessageTypes.OrderReplace: case MessageTypes.OrderCancel: case MessageTypes.OrderGroupCancel: { var ordMsg = (OrderMessage)message; ProcessPortfolioMessage(ordMsg.PortfolioName, ordMsg); break; } case MessageTypes.OrderPairReplace: { var ordMsg = (OrderPairReplaceMessage)message; ProcessPortfolioMessage(ordMsg.Message1.PortfolioName, ordMsg); break; } case MessageTypes.MarketData: { var adapters = _connectedAdapters.TryGetValue(message.Type); if (adapters == null) { throw new InvalidOperationException(LocalizedStrings.Str629Params.Put(message.Type)); } var mdMsg = (MarketDataMessage)message; switch (mdMsg.DataType) { case MarketDataTypes.News: adapters.Cache.ForEach(a => a.SendInMessage(mdMsg)); break; default: { var key = CreateKey(mdMsg); var state = _subscriptionStates.TryGetValue2(key); if (mdMsg.IsSubscribe) { if (state != null) { RaiseMarketDataMessage(null, mdMsg.OriginalTransactionId, new InvalidOperationException(state.Value.ToString()), true); break; } else { _subscriptionStates.Add(key, SubscriptionStates.Subscribing); } } else { var canProcess = false; switch (state) { case SubscriptionStates.Subscribed: canProcess = true; _subscriptionStates[key] = SubscriptionStates.Unsubscribing; break; case SubscriptionStates.Subscribing: case SubscriptionStates.Unsubscribing: RaiseMarketDataMessage(null, mdMsg.OriginalTransactionId, new InvalidOperationException(state.Value.ToString()), false); break; case null: RaiseMarketDataMessage(null, mdMsg.OriginalTransactionId, null, false); break; default: throw new ArgumentOutOfRangeException(); } if (!canProcess) { break; } } if (mdMsg.TransactionId != 0) { _subscriptionKeys.Add(mdMsg.TransactionId, key); } if (mdMsg.IsSubscribe) { //if (_subscriptionQueue.ContainsKey(key)) // return; var enumerator = adapters.Cache.Cast <IMessageAdapter>().GetEnumerator(); _subscriptionQueue.Add(key, enumerator); ProcessSubscriptionAction(enumerator, mdMsg, mdMsg.TransactionId); } else { var adapter = _subscriptions.TryGetValue(key); if (adapter != null) { _subscriptions.Remove(key); adapter.SendInMessage(message); } } break; } } break; } default: { var adapters = _connectedAdapters.TryGetValue(message.Type); if (adapters == null) { throw new InvalidOperationException(LocalizedStrings.Str629Params.Put(message.Type)); } adapters.Cache.ForEach(a => a.SendInMessage(message)); break; } } }
/// <inheritdoc /> public virtual IMessageAdapter GetAdapter(string portfolioName) { return(_adapters.TryGetValue(portfolioName)); }