Ejemplo n.º 1
0
		/// <summary>
		/// Send message.
		/// </summary>
		/// <param name="message">Message.</param>
		protected override void OnSendInMessage(Message message)
		{
			switch (message.Type)
			{
				case MessageTypes.Reset:
				{
					if (_client != null)
					{
						DisposeClient();
					}

					try
					{
						Connection.Close();
						Connection.ClearCache();
					}
					catch (Exception ex)
					{
						SendOutError(ex);
					}

					Connection.StatusChange -= ConnectionOnStatusChange;

					SendOutMessage(new ResetMessage());

					break;
				}

				case MessageTypes.Connect:
				{
					if (_client != null)
						throw new InvalidOperationException(LocalizedStrings.Str3378);

					var doc = XDocument.Load("http://www.ddfplus.com/getusersettings.php?username={0}&password={1}".Put(Login, Password.To<string>()));

					var loginElem = doc.Element("usersettings").Elements("login").First();

					if (loginElem.GetAttributeValue<string>("status") != "ok")
						throw new InvalidOperationException(LocalizedStrings.UnknownServerError);

					if (loginElem.GetAttributeValue<string>("credentials") != "ok")
						throw new InvalidOperationException(LocalizedStrings.Str3350);

					foreach (var elem in doc.Element("usersettings").Element("servers").Elements())
					{
						switch (elem.GetAttributeValue<string>("type"))
						{
							case "stream":
								_streamAddress = elem.GetAttributeValue<string>("primary");
								break;

							case "historicalv2":
								_historicalAddress = elem.GetAttributeValue<string>("primary");
								break;

							case "extras":
								_extrasAddress = elem.GetAttributeValue<string>("primary");
								break;

							case "news":
								_newsAddress = elem.GetAttributeValue<string>("primary");
								break;
						}
					}

					SendOutMessage(new ConnectMessage());

					Connection.StatusChange += ConnectionOnStatusChange;
					Connection.Properties["streamingversion"] = "3";

					_client = new Client();

					_client.Error += ClientOnError;
					_client.NewBookQuote += ClientOnNewBookQuote;
					_client.NewOHLCQuote += ClientOnNewOhlcQuote;
					_client.NewQuote += ClientOnNewQuote;

					Connection.Username = Login;
					Connection.Password = Password.To<string>();
					Connection.Mode = ConnectionMode.TCPClient;

					break;
				}

				case MessageTypes.Disconnect:
				{
					if (_client == null)
						throw new InvalidOperationException(LocalizedStrings.Str1856);

					DisposeClient();
					Connection.Close();

					break;
				}

				case MessageTypes.SecurityLookup:
				{
					var lookupMsg = (SecurityLookupMessage)message;

					XDocument doc = null;

					if (!lookupMsg.SecurityId.SecurityCode.IsEmpty())
					{
						doc = XDocument.Load("{0}/instruments/?lookup={1}".Put(_extrasAddress, lookupMsg.SecurityId.SecurityCode));
					}
					else if (!lookupMsg.SecurityId.BoardCode.IsEmpty())
					{
						doc = XDocument.Load("{0}/instruments/?exchange={1}".Put(_extrasAddress, lookupMsg.SecurityId.BoardCode));
					}

					if (doc != null)
					{
						foreach (var element in doc.Element("instruments").Elements())
						{
							SendOutMessage(new SecurityMessage
							{
								SecurityId = new SecurityId
								{
									SecurityCode = element.GetAttributeValue<string>("guid"),
									BoardCode = element.GetAttributeValue<string>("exchange"),
								},
								Name = element.GetAttributeValue<string>("symbol_description"),
								OriginalTransactionId = lookupMsg.TransactionId,
								SecurityType = TraderHelper.FromIso10962(element.GetAttributeValue<string>("symbol_cfi")),
								PriceStep = element.GetAttributeValue<decimal?>("tick_increment"),
								Multiplier = element.GetAttributeValue<decimal?>("point_value"),
								Currency = element.GetAttributeValue<CurrencyTypes?>("currency")
							});
						}
					}

					SendOutMessage(new SecurityLookupResultMessage
					{
						OriginalTransactionId = lookupMsg.TransactionId,
					});

					break;
				}

				case MessageTypes.MarketData:
				{
					var mdMsg = (MarketDataMessage)message;

					switch (mdMsg.DataType)
					{
						case MarketDataTypes.Level1:
							break;
						case MarketDataTypes.MarketDepth:
							break;
						case MarketDataTypes.Trades:
						{
							if (mdMsg.Count != null || mdMsg.From != null || mdMsg.To != null)
							{
								var url = new Url("{0}/queryticks.ashx".Put(_historicalAddress));

								url.QueryString
									.Append("username", Login)
									.Append("password", Password.To<string>())
									.Append("symbol", mdMsg.SecurityId.SecurityCode)
									.Append("order", "asc");

								if (mdMsg.Count != null)
									url.QueryString.Append("maxrecords", mdMsg.Count.Value);

								if (mdMsg.From != null)
									url.QueryString.Append("start", mdMsg.From.Value.FromDateTimeOffset(_defaultTimeFormatRequest));

								if (mdMsg.To != null)
									url.QueryString.Append("end", mdMsg.To.Value.FromDateTimeOffset(_defaultTimeFormatRequest));

								using (var client = new WebClient())
								{
									var lines = client.DownloadString(url)
										.Split("\n")
										.Where(l => l != "\r")
										.ToArray();

									var i = 0;
									foreach (var line in lines)
									{
										var columns = line.Split(',');

										try
										{
											var msg = new ExecutionMessage
											{
												SecurityId = mdMsg.SecurityId,
												OriginalTransactionId = mdMsg.TransactionId,
												ExecutionType = ExecutionTypes.Tick,
												ServerTime = columns[0].ToDateTime("yyyy-MM-dd HH:mm:ss.fff"),
												TradePrice = columns[3].To<decimal>(),
												Volume = columns[4].To<decimal>(),
											};

											msg.AddValue("IsFinished", ++i == lines.Length);

											SendOutMessage(msg);
										}
										catch (Exception ex)
										{
											throw new InvalidOperationException(LocalizedStrings.Str2141Params.Put(line), ex);
										}
									}
								}
							}

							break;
						}
						case MarketDataTypes.News:
							break;
						case MarketDataTypes.CandleTimeFrame:
						{
							var tf = (TimeSpan)mdMsg.Arg;

							string serviceName;
							string timeFormatRequest = _defaultTimeFormatRequest;
							string timeFormatResponse = "yyyy-MM-dd";

							if (tf == TimeSpan.FromMinutes(1))
							{
								serviceName = "queryminutes";
								timeFormatResponse = "yyyy-MM-dd HH:mm";
							}
							else if (tf == TimeSpan.FromDays(1))
							{
								serviceName = "queryeod";
								timeFormatRequest = "yyyyMMdd";
							}
							else
								throw new InvalidOperationException(LocalizedStrings.Str2102);

							var url = new Url("{0}/{1}.ashx".Put(_historicalAddress, serviceName));

							url.QueryString
								.Append("username", Login)
								.Append("password", Password.To<string>())
								.Append("symbol", mdMsg.SecurityId.SecurityCode)
								.Append("order", "asc");

							if (mdMsg.Count != null)
								url.QueryString.Append("maxrecords", mdMsg.Count.Value);

							if (mdMsg.From != null)
								url.QueryString.Append("start", mdMsg.From.Value.FromDateTimeOffset(timeFormatRequest));

							if (mdMsg.To != null)
								url.QueryString.Append("end", mdMsg.To.Value.FromDateTimeOffset(timeFormatRequest));

							using (var client = new WebClient())
							{
								var lines = client.DownloadString(url)
										.Split("\n")
										.Where(l => l != "\r")
										.ToArray();

								var i = 0;
								foreach (var line in lines)
								{
									var columns = line.Split(',');

									try
									{
										SendOutMessage(new TimeFrameCandleMessage
										{
											SecurityId = mdMsg.SecurityId,
											OriginalTransactionId = mdMsg.TransactionId,
											OpenTime = columns[tf == TimeSpan.FromMinutes(1) ? 0 : 1].ToDateTime(timeFormatResponse).ApplyTimeZone(TimeHelper.Est),
											OpenPrice = columns[2].To<decimal>(),
											HighPrice = columns[3].To<decimal>(),
											LowPrice = columns[4].To<decimal>(),
											ClosePrice = columns[5].To<decimal>(),
											TotalVolume = columns[6].To<decimal>(),
											OpenInterest = columns.Length > 7 ? columns[7].To<decimal>() : (decimal?)null,
											IsFinished = ++i == lines.Length
										});
									}
									catch (Exception ex)
									{
										throw new InvalidOperationException(LocalizedStrings.Str2141Params.Put(line), ex);
									}
								}
							}

							break;
						}
						default:
						{
							SendOutMarketDataNotSupported(mdMsg.TransactionId);
							return;
						}
					}

					SendOutMessage(new MarketDataMessage { OriginalTransactionId = mdMsg.TransactionId });
					break;
				}
			}
		}