protected virtual DataSubscriptionResponseMessage Receive(DataSubscriptionRequestMessage message) { if (message.TransportInfo.OriginalSenderId.HasValue == false) { SystemMonitor.Error("Received a message with no original sender. Dropped."); return(null); } if (message.SessionInfo.IsEmtpy) {// General (un)subscription requestMessage, not specific to a sessionInformation. if (message.Subscribe) { SystemMonitor.OperationError("Unexpected combination of empty session and subscribe request, ignored."); } else {// Unsubscribe to each that has a orderInfo for this original sender. lock (this) { foreach (CombinedDataSubscriptionInformation combined in _dataSessions.Values) { if (combined.FullUnsubscribe(message.TransportInfo.OriginalSenderId.Value) == false) { SystemMonitor.OperationError("Failed to unsubscribe [" + message.TransportInfo.OriginalSenderId.Value.Id.Name + "]."); } } } } } else { lock (this) { if (_dataSessions.ContainsKey(message.SessionInfo.Symbol) == false || _dataSessions[message.SessionInfo.Symbol].SessionInformation.Info.Equals(message.SessionInfo) == false) { SystemMonitor.Warning("Subsribe request for non existing session."); return(new DataSubscriptionResponseMessage(message.SessionInfo, false)); } CombinedDataSubscriptionInformation combined = _dataSessions[message.SessionInfo.Symbol]; if (combined != null) { TracerHelper.Trace("Subscribing... " + message.TransportInfo.OriginalSenderId.Value.Id.Name); combined.HandleRequest(message.TransportInfo, message.Subscribe, message.Information); } else { SystemMonitor.OperationError("Combined subscription info not found."); } } } // Finalizing / responding section. if (message.RequestResponse) { return(new DataSubscriptionResponseMessage(message.SessionInfo, true)); } return(null); }
public bool InitializeIntegrationSession(string symbol, decimal modePoint, decimal modeDigits, decimal modeSpread, decimal modeStopLevel, decimal modeLotSize, decimal modeTickValue, decimal modeTickSize, decimal modeSwapLong, decimal modeSwapShort, decimal modeStarting, decimal modeExpiration, decimal modeTradeAllowed, decimal modeMinLot, decimal modeLotStep, decimal modeMaxLot, decimal modeSwapType, decimal modeProfitCalcMode, decimal modeMarginCalcMode, decimal modeMarginInit, decimal modeMarginMaintenance, decimal modeMarginHedged, decimal modeMarginRequired, decimal modeFreezeLevel) { TracerHelper.Trace(symbol); CombinedDataSubscriptionInformation session = GetDataSession(symbol); if (session == null) { DataSessionInfo sessionInfo = new DataSessionInfo(Guid.NewGuid(), symbol, CreateSymbol(symbol), modeLotSize, (int)modeDigits); RuntimeDataSessionInformation runtimeSession = new RuntimeDataSessionInformation(sessionInfo); session = new CombinedDataSubscriptionInformation(runtimeSession); lock (this) { _dataSessions.Add(sessionInfo.Symbol, session); } } return(true); }
/// <summary> /// OperationId is not mandatory - but is should be there when the update was requested by a special recepient. /// </summary> public void TradingValuesUpdate(string symbol, int operationId, double time, int period, int availableBarsCount, Int64[] times, decimal[] opens, decimal[] closes, decimal[] highs, decimal[] lows, decimal[] volumes) { TracerHelper.TraceEntry(); CombinedDataSubscriptionInformation session = GetDataSession(symbol); if (session == null) { SystemMonitor.Error("Failed to find symbol session [" + symbol + "], quotes not sent."); return; } try { // History update. TimeSpan periodValue = TimeSpan.FromMinutes(period); DataHistoryUpdate update = new DataHistoryUpdate(periodValue, GenerateDataBars(periodValue, times, opens, closes, highs, lows, volumes)); update.AvailableHistorySize = availableBarsCount; DataHistoryUpdateMessage message = new DataHistoryUpdateMessage(session.SessionInformation.Info, update, true); SendToDataSubscribers(session, null, message); } catch (Exception ex) {// Make sure we handle any possible unexpected exceptions, as otherwise they bring the // entire package (MT4 included) down with a bad error. SystemMonitor.Error(ex.Message); } TracerHelper.TraceExit(); }
void manager_QuoteUpdatedEvent(FXCMConnectionManager manager, string symbolName, DataTick dataTick) { Symbol symbol = new Symbol(Symbol.SymbolGroup.Forex, symbolName); DataSourceStub dataSourceStub = _dataSourceStub; if (dataSourceStub == null) { return; } RuntimeDataSessionInformation sessionInformation = dataSourceStub.GetSymbolSessionInformation(symbol); if (sessionInformation == null) { return; } CombinedDataSubscriptionInformation info = dataSourceStub.GetUnsafeSessionSubscriptions(sessionInformation.Info); if (info != null && info.GetCombinedDataSubscription().QuoteSubscription) { dataSourceStub.UpdateQuote(sessionInformation.Info, new Quote(dataTick.Ask, dataTick.Bid, null, dataTick.DateTime), null); foreach (TimeSpan supportedPeriod in DefaultAvailablePeriods) { dataSourceStub.UpdateDataHistory(sessionInformation.Info, new DataHistoryUpdate(supportedPeriod, new DataTick[] { dataTick })); } } }
/// <summary> /// /// </summary> public void Quotes(string symbol, int operationId, double ask, double bid, double open, double close, double low, double high, double volume, double time) { TracerHelper.TraceEntry(); CombinedDataSubscriptionInformation session = GetDataSession(symbol); if (session == null) { SystemMonitor.Error("Failed to find symbol session [" + symbol + "], quotes not sent."); return; } try { QuoteUpdateMessage message = new QuoteUpdateMessage(session.SessionInformation.Info, new Quote((decimal)ask, (decimal)bid, (decimal)open, (decimal)close, (decimal)high, (decimal)low, (decimal)volume, GeneralHelper.GenerateDateTimeSecondsFrom1970((long)time)), true); SendToDataSubscribers(session, message, null); } catch (Exception ex) {// Make sure we handle any possible unexpected exceptions, as otherwise they bring the // entire package (MT4 included) down with a bad error. SystemMonitor.Error(ex.Message); } }
// << Result format : int& orderTicket, int& operationID, double& minVolume, double& price, int& slippage public string RequestCloseOrder() { try { int operationId; CloseOrderVolumeMessage message = base.GetPendingMessage <CloseOrderVolumeMessage>(true, out operationId); if (message == null) { return(string.Empty); } // Convert slippage to points. int slippage = ConvertSlippage(message.Symbol, message.Slippage); // Process price. if (message.Price.HasValue == false) { message.Price = 0; } // Process minVolume. CombinedDataSubscriptionInformation session = base.GetDataSession(message.Symbol); if (session == null) { SystemMonitor.Error("Failed to establish symbol [" + message.Symbol.Name + "] session."); if (message.PerformSynchronous) { base.CompleteOperation(operationId, new ResponseMessage(false, "Failed to establish symbol session.")); } return(string.Empty); } decimal volumeDecreasal = ConvertVolume(session.SessionInformation.Info.LotSize, (int)message.VolumeDecreasal); string result = message.OrderId.ToString() + SeparatorSymbol + operationId.ToString() + SeparatorSymbol + volumeDecreasal.ToString(GeneralHelper.UniversalNumberFormatInfo) + SeparatorSymbol + message.Price.Value.ToString(GeneralHelper.UniversalNumberFormatInfo) + SeparatorSymbol + slippage.ToString(); TracerHelper.Trace(result); return(result); } catch (Exception ex) {// Make sure we handle any possible unexpected exceptions, as otherwise they bring the // entire package (MT4 included) down with a bad error. SystemMonitor.Error(ex.Message); } return(string.Empty); }
/// <summary> /// /// </summary> public void SessionDataSubscriptionUpdate(DataSessionInfo session, bool subscribe, DataSubscriptionInfo?info) { SystemMonitor.CheckError(session.IsEmtpy == false, "Method needs valid session info assigned to operate."); DataSourceStub dataSourceStub = DataSourceStub; if (dataSourceStub == null) { return; } CombinedDataSubscriptionInformation combined = dataSourceStub.GetUnsafeSessionSubscriptions(session); if (combined == null) { SystemMonitor.OperationError("Update on not existing session."); return; } MBTradingConnectionManager manager = _manager; if (manager == null) { return; } DataSubscriptionInfo combinedInfo = combined.GetCombinedDataSubscription(); if (combinedInfo.QuoteSubscription) { if (manager.Adapter != null) { manager.Quotes.SubscribeSymbolSession(session.Symbol, Commission.GenerateSymbolCommission(manager.Adapter, session.Symbol)); } else { SystemMonitor.OperationError("Failed to perform data subscription update, since manager adapter not assigned."); } GeneralHelper.FireAndForget(delegate() {// Run an async update of quotes. string market; Quote?quote = _manager.Quotes.GetSingleSymbolQuote(session.Symbol.Name, TimeSpan.FromSeconds(10), out market); if (quote.HasValue) { DataSourceStub.UpdateQuote(session, quote, null); } }); } else { manager.Quotes.UnSubscribeSymbolSession(session.Symbol.Name); } }
/// <summary> /// /// </summary> public void SessionDataSubscriptionUpdate(DataSessionInfo session, bool subscribe, DataSubscriptionInfo?info) { SystemMonitor.CheckError(session.IsEmtpy == false, "Method needs valid session info assigned to operate."); DataSourceStub dataSourceStub = _dataSourceStub; if (dataSourceStub == null) { return; } CombinedDataSubscriptionInformation combined = dataSourceStub.GetUnsafeSessionSubscriptions(session); if (combined == null) { SystemMonitor.OperationError("Update of a non-existing session."); return; } }
void PostQuoteUpdate(string forexPair, DataTick dataTick) { RuntimeDataSessionInformation sessionInformation = _dataSourceStub.GetSymbolSessionInformation(new Symbol("Forex", forexPair)); if (sessionInformation != null && _subscribedSymbols.ContainsKey(forexPair)) { CombinedDataSubscriptionInformation info = _dataSourceStub.GetUnsafeSessionSubscriptions(sessionInformation.Info); if (info != null && info.GetCombinedDataSubscription().QuoteSubscription) { _dataSourceStub.UpdateQuote(sessionInformation.Info, new Quote(dataTick.Ask, dataTick.Bid, null, dataTick.DateTime), null); foreach (TimeSpan supportedPeriod in DefaultAvailablePeriods) { _dataSourceStub.UpdateDataHistory(sessionInformation.Info, new DataHistoryUpdate(supportedPeriod, new DataTick[] { dataTick })); } } } }
public bool AddSessionPeriod(string symbol, int period) { TracerHelper.TraceEntry(); TimeSpan span = TimeSpan.FromMinutes(period); CombinedDataSubscriptionInformation session = GetDataSession(symbol); if (session == null) { SystemMonitor.Error("Session not found [" + symbol + "], periods not set."); return(false); } lock (this) { if (session.SessionInformation.AvailableDataBarPeriods.Contains(span) == false) { session.SessionInformation.AvailableDataBarPeriods.Add(span); } } return(true); }
void SendToDataSubscribers(CombinedDataSubscriptionInformation session, QuoteUpdateMessage quoteMessage, DataHistoryUpdateMessage updateMessage) { TracerHelper.TraceEntry(); lock (this) { // TODO: make sure proper subscription based filtering is applied here too. foreach (KeyValuePair <TransportInfo, DataSubscriptionInfo> pair in session.SubscriptionsUnsafe.Values) { if (quoteMessage != null && pair.Value.AcceptsUpdate(quoteMessage.Quote)) { TracerHelper.Trace("Sending [" + quoteMessage.GetType().Name + "] to [" + pair.Key.OriginalSenderId.Value.Id.Name + "]."); SendResponding(pair.Key, quoteMessage); } if (updateMessage != null && pair.Value.AcceptsUpdate(updateMessage.Update)) { TracerHelper.Trace("Sending [" + updateMessage.GetType().Name + "] to [" + pair.Key.OriginalSenderId.Value.Id.Name + "]."); SendResponding(pair.Key, updateMessage); } } } }
/// <summary> /// /// </summary> public void SessionDataSubscriptionUpdate(DataSessionInfo session, bool subscribe, DataSubscriptionInfo?info) { SystemMonitor.CheckError(session.IsEmtpy == false, "Method needs valid session info assigned to operate."); DataSourceStub dataSourceStub = _dataSourceStub; if (dataSourceStub == null) { return; } CombinedDataSubscriptionInformation combined = dataSourceStub.GetUnsafeSessionSubscriptions(session); if (combined == null) { SystemMonitor.OperationError("Update on not existing session."); return; } DataSubscriptionInfo combinedInfo = combined.GetCombinedDataSubscription(); if (combinedInfo.QuoteSubscription) { if (!_subscribedSymbols.ContainsKey(session.Symbol.Name)) { _subscribedSymbols.Add(session.Symbol.Name, session.Symbol); } } else { if (_subscribedSymbols.ContainsKey(session.Symbol.Name)) { _subscribedSymbols.Remove(session.Symbol.Name); } } }
// >> public void OrderInformation(int orderTicket, int operationID, string orderSymbol, int orderType, decimal volume, decimal inputOpenPrice, decimal inputClosePrice, decimal inputOrderStopLoss, decimal inputOrderTakeProfit, decimal currentProfit, decimal orderSwap, int inputOrderPlatformOpenTime, int inputOrderPlatformCloseTime, int inputOrderExpiration, decimal orderCommission, string orderComment, int orderCustomID, bool operationResult, string operationResultMessage) { TracerHelper.TraceEntry(string.Format("ticketId[{0}], customId[{1}], operationId[{2}], symbol[{3}], SL[{4}, TP[{5}]", orderTicket.ToString(), orderCustomID.ToString(), operationID.ToString(), orderSymbol, inputOrderStopLoss.ToString(), inputOrderTakeProfit.ToString())); try { #region Preprocess Data decimal?openPrice = Convert(inputOpenPrice); decimal?closePrice = Convert(inputClosePrice); decimal?orderStopLoss = Convert(inputOrderStopLoss); decimal?orderTakeProfit = Convert(inputOrderTakeProfit); int? orderPlatformOpenTime = Convert(inputOrderPlatformOpenTime); int? orderPlatformCloseTime = Convert(inputOrderPlatformCloseTime); int? orderExpiration = Convert(inputOrderExpiration); // Perform dataDelivery fixes to convert to proper cases. bool isOpen = orderPlatformCloseTime.HasValue == false || orderPlatformCloseTime == 0; OrderStateEnum orderState = OrderStateEnum.Unknown; // According to documentataion this is the way to establish if order is closed, see here : http://docs.mql4.com/trading/OrderSelect if (isOpen) { if (CommonFinancial.OrderInfo.TypeIsDelayed((OrderTypeEnum)orderType) == false && orderPlatformOpenTime > 0) { orderState = OrderStateEnum.Executed; } else { orderState = OrderStateEnum.Submitted; } } else { orderState = OrderStateEnum.Closed; } if (orderState == OrderStateEnum.Executed) {// Since the integration might report close price for opened orders, at the current closing price. closePrice = null; } DateTime?openTime = GeneralHelper.GenerateDateTimeSecondsFrom1970(orderPlatformOpenTime); DateTime?closeTime = GeneralHelper.GenerateDateTimeSecondsFrom1970(orderPlatformCloseTime); DateTime?expirationTime = GeneralHelper.GenerateDateTimeSecondsFrom1970(orderExpiration); CombinedDataSubscriptionInformation sessionSubscriptionInfo = GetDataSession(orderSymbol); if (sessionSubscriptionInfo == null) { SystemMonitor.Error("Corresponding symbol [" + orderSymbol + "] session info not found."); return; } #endregion bool isNewlyAcquired = false; OrderInfo?orderInformation = null; if (orderTicket > -1) {// Store call information for later use. orderInformation = new OrderInfo( orderTicket.ToString(), sessionSubscriptionInfo.SessionInformation.Info.Symbol, ConvertOrderType(orderType), orderState, ConvertVolume(sessionSubscriptionInfo.SessionInformation.Info.LotSize, volume), openPrice, closePrice, orderStopLoss, orderTakeProfit, currentProfit, orderSwap, openTime, closeTime, openTime, expirationTime, orderCommission, orderComment, orderCustomID.ToString()); lock (this) { isNewlyAcquired = _orders.ContainsKey(orderTicket.ToString()) == false || _orders[orderTicket.ToString()].HasValue == false; _orders[orderTicket.ToString()] = orderInformation; } TracerHelper.TraceEntry(string.Format("Storing information, id[{0}], symb[{1}], customId[{2}], operationId[{3}].", orderTicket.ToString(), orderSymbol, orderCustomID.ToString(), operationID)); } else {// This used to be flush call (send all stored to user), but currently not used. SystemMonitor.NotImplementedError("Case not implemented."); } //if (isNewlyAcquired) {// Send a notification to subscribers, an order orderInfo was acquired. OrdersInformationUpdateResponseMessage message = new OrdersInformationUpdateResponseMessage(_accountInfo, new OrderInfo[] { orderInformation.Value }, true); SendToSubscribers(message); } } catch (Exception ex) {// Make sure we handle any possible unexpected exceptions, as otherwise they bring the // entire package (MT4 included) down with a bad error. SystemMonitor.Error(ex.Message); } }
// << Result format ; string& symbol, double& minVolume, double& desiredPrice (0 for none), int& slippage, double& takeProfit, double& stopLoss, int& orderType, int& operationID, string& comment public string RequestNewOrder() { int operationId; try { OrderMessage message = base.GetPendingMessage <OrderMessage>(true, out operationId); if (message == null) { return(string.Empty); } // Process comment. if (string.IsNullOrEmpty(message.Comment) == false) { message.Comment = message.Comment.Replace(SeparatorSymbol, ","); } else { message.Comment = string.Empty; } // Convert slippage to points. int slippage = ConvertSlippage(message.Symbol, message.Slippage); // Process desired price. if (message.DesiredPrice.HasValue == false) { message.DesiredPrice = 0; } // Process TP. if (message.TakeProfit.HasValue == false) { message.TakeProfit = 0; } // Process SL. if (message.StopLoss.HasValue == false) { message.StopLoss = 0; } // Process minVolume. CombinedDataSubscriptionInformation session = base.GetDataSession(message.Symbol); if (session == null) { SystemMonitor.Error("Failed to establish symbol [" + message.Symbol.Name + "] session."); if (message.PerformSynchronous == false) { base.CompleteOperation(operationId, new ResponseMessage(false, "Failed to establish symbol session.")); } return(string.Empty); } decimal volume = ConvertVolume(session.SessionInformation.Info.LotSize, message.Volume); string result = message.Symbol.Name + SeparatorSymbol + volume.ToString(GeneralHelper.UniversalNumberFormatInfo) + SeparatorSymbol + message.DesiredPrice.Value.ToString(GeneralHelper.UniversalNumberFormatInfo) + SeparatorSymbol + slippage.ToString() + SeparatorSymbol + message.TakeProfit.Value.ToString(GeneralHelper.UniversalNumberFormatInfo) + SeparatorSymbol + message.StopLoss.Value.ToString(GeneralHelper.UniversalNumberFormatInfo) + SeparatorSymbol + ((int)message.OrderType).ToString() + SeparatorSymbol + operationId + SeparatorSymbol + message.Comment; TracerHelper.Trace(result); return(result); } catch (Exception ex) {// Make sure we handle any possible unexpected exceptions, as otherwise they bring the // entire package (MT4 included) down with a bad error. SystemMonitor.Error(ex.Message); } return(string.Empty); }