示例#1
0
        /// <summary>
        /// Funkcja zamieniająca komunikat odebrany z socketa (klasy bazowej FixmlMsg)
        /// na konkretną klasę pochodną FixmlMsg - odpowiednią dla typu danego komunikatu.
        /// Obecnie przystosowane tylko dla komunikatów nadsyłanych w kanale asynchronicznym
        /// (raczej tylko tam ma to sens, normalnie wiemy jakiego komunikatu się spodziewać).
        /// </summary>
        /// <param name="msg">Obiekt klasy bazowej FixmlMsg</param>
        /// <returns>Obiekt konkretnej klasy pochodnej FixmlMsg, zależnej od typu komunikatu.
        /// Jeśli trafi na nieznany komunikat, zwraca ten sam obiekt bazowy FixmlMsg.
        /// </returns>
        public static FixmlMsg GetParsedMsg(FixmlMsg msg)
        {
            if (msg.GetType() != typeof(FixmlMsg))
            {
                throw new ArgumentException("Base 'FixmlMsg' class object required", "msg");
            }
            switch (msg.Xml.Name)
            {
            case AppMessageReportMsg.MsgName: return(new AppMessageReportMsg(msg));

            case ExecutionReportMsg.MsgName: return(new ExecutionReportMsg(msg));

            case MarketDataIncRefreshMsg.MsgName: return(new MarketDataIncRefreshMsg(msg));

            case TradingSessionStatusMsg.MsgName: return(new TradingSessionStatusMsg(msg));

            case NewsMsg.MsgName: return(new NewsMsg(msg));

            case StatementMsg.MsgName: return(new StatementMsg(msg));

            case UserResponseMsg.MsgName: return(new UserResponseMsg(msg));

            case "Heartbeat": return(msg);                     // <- dla tego szkoda oddzielnej klasy ;-)

            default:
                string txt = string.Format("Unexpected async message '{0}'", msg.Xml.Name);
                MyUtil.PrintWarning(txt);
                if (!FixmlMsg.DebugOriginalXml.Enabled && !FixmlMsg.DebugFormattedXml.Enabled)
                {
                    Trace.WriteLine(string.Format("'{0}'", MyUtil.FormattedXml(msg.Xml.OwnerDocument)));
                }
                return(msg);
            }
        }
示例#2
0
 // Konstruktor używany wewnętrznie dla komunikatów przychodzących -
 // "opakowywuje" odebrany komunikat w inną, bardziej precyzyjną klasę pochodną.
 protected FixmlMsg(FixmlMsg msg)
 {
     Debug.WriteLineIf(DebugInternals.Enabled, string.Format("new {0} from FixmlMsg", GetType().Name), DebugCategory);
     xmlDoc = msg.xmlDoc;
     ParseXmlMessage(null);
     Debug.WriteLineIf(DebugParsedMessage.Enabled, this.ToString(), DebugRecvCategory);
     Debug.WriteLineIf(DebugInternals.Enabled, string.Format("new {0} ok", GetType().Name), DebugCategory);
 }
 public ExecutionReportMsg(FixmlMsg m) : base(m)
 {
 }
		public TradingSessionStatusMsg(FixmlMsg msg) : base(msg) { }
		public StatementMsg(FixmlMsg m) : base(m) { }
示例#6
0
 public NewsMsg(FixmlMsg m) : base(m)
 {
 }
示例#7
0
		/// <summary>
		/// Funkcja zamieniająca komunikat odebrany z socketa (klasy bazowej FixmlMsg)
		/// na konkretną klasę pochodną FixmlMsg - odpowiednią dla typu danego komunikatu.
		/// Obecnie przystosowane tylko dla komunikatów nadsyłanych w kanale asynchronicznym
		/// (raczej tylko tam ma to sens, normalnie wiemy jakiego komunikatu się spodziewać).
		/// </summary>
		/// <param name="msg">Obiekt klasy bazowej FixmlMsg</param>
		/// <returns>Obiekt konkretnej klasy pochodnej FixmlMsg, zależnej od typu komunikatu.
		/// Jeśli trafi na nieznany komunikat, zwraca ten sam obiekt bazowy FixmlMsg.
		/// </returns>
		public static FixmlMsg GetParsedMsg(FixmlMsg msg)
		{
			if (msg.GetType() != typeof(FixmlMsg))
				throw new ArgumentException("Base 'FixmlMsg' class object required", "msg");
			switch (msg.Xml.Name)
			{
				case AppMessageReportMsg.MsgName: return new AppMessageReportMsg(msg);
				case ExecutionReportMsg.MsgName: return new ExecutionReportMsg(msg);
				case MarketDataIncRefreshMsg.MsgName: return new MarketDataIncRefreshMsg(msg);
				case TradingSessionStatusMsg.MsgName: return new TradingSessionStatusMsg(msg);
				case NewsMsg.MsgName: return new NewsMsg(msg);
				case StatementMsg.MsgName: return new StatementMsg(msg);
				case UserResponseMsg.MsgName: return new UserResponseMsg(msg);
				case "Heartbeat": return msg;  // <- dla tego szkoda oddzielnej klasy ;-)
				default:
					string txt = string.Format("Unexpected async message '{0}'", msg.Xml.Name);
					MyUtil.PrintWarning(txt);
					if (!FixmlMsg.DebugOriginalXml.Enabled && !FixmlMsg.DebugFormattedXml.Enabled)
						Trace.WriteLine(string.Format("'{0}'", MyUtil.FormattedXml(msg.Xml.OwnerDocument)));
					return msg;
			}
		}
 public FixmlErrorMsgException(string str, FixmlMsg msg) : base(str)
 {
     this.msg = msg;
 }
		public FixmlErrorMsgException(string str, FixmlMsg msg) : base(str) { this.msg = msg; }
		/// <summary>
		/// Bardziej zaawansowany przykład użycia "NolClient": zalogowanie dopiero na żądanie, 
		/// bez uruchamiania wątku odbierającego komunikaty asynchroniczne (można go obsłużyć samemu).
		/// Samodzielne przygotowanie, wysyłka i odbiór przykładowego message'a.
		/// </summary>
		public void Execute()
		{
			using (var nol = new NolClient(false, false))
			{
				// zalogowanie użytkownika
				Console.WriteLine("\nPress any key... to log in   [Esc - cancel]\n");
				if (Console.ReadKey(true).Key == ConsoleKey.Escape) return;
				nol.Login();

				// otwarcie kanału asynchronicznego
				// (na razie nic tu z niego nie odbieramy, bo do tego przydałby się oddzielny wątek)
				Console.WriteLine("\nPress any key... to open async socket   [Esc - skip]\n");
				Socket asyncSocket = null;
				if (Console.ReadKey(true).Key != ConsoleKey.Escape)
					asyncSocket = NolClient.GetAsyncSocket();

				// wysyłka przykładowego komunikatu
				// (można skorzystać z gotowych klas zdefiniowanych w pjank.BossaAPI.Fixml, 
				// ale można też spreparować coś zupełnie własnego w oparciu o klasę CustomMsg)
				Console.WriteLine("\nPress any key... to send a custom message   [Esc - cancel]\n");
				if (Console.ReadKey(true).Key == ConsoleKey.Escape) return;
				var tmp = FixmlMsg.DebugOriginalXml.Enabled;
				try
				{
					FixmlMsg.DebugOriginalXml.Enabled = true;

					// otwarcie nowego połączenia (kanał synchroniczny za każdym razem nowy!)
					using (var syncSocket = NolClient.GetSyncSocket())
					{
						// przygotowanie komunikatu
						var request = new UserRequestMsg()
						{
							Username = "******",
							Type = UserRequestType.GetStatus,
						};
						// wysyłka komunikatu
						request.Send(syncSocket);

						// odbiór odpowiedzi
						Console.WriteLine("\nPress any key... to read the response\n");
						Console.ReadKey(true);
						var response = new FixmlMsg(syncSocket);
						Trace.WriteLine("\nResponse XML:\n" + response.Xml.FormattedXml() + "\n");

						// dokładniejsza analiza odpowiedzi (w klasie konkretnego rodzaju komunikatu)
						Console.WriteLine("Press any key... to parse the response message\n");
						Console.ReadKey(true);
						UserResponseMsg parsedResponse = new UserResponseMsg(response);
						Trace.WriteLine(String.Format("\nResponse parsed:\n Status = {0}, StatusText = '{1}'\n",
							parsedResponse.Status, parsedResponse.StatusText));
					}

					Console.WriteLine("\nPress any key... to send another custom message   [Esc - cancel]\n");
					if (Console.ReadKey(true).Key == ConsoleKey.Escape) return;

					// otwarcie nowego połączenia (kanał synchroniczny za każdym razem nowy!)
					using (var syncSocket = NolClient.GetSyncSocket())
					{
						// tak można spreparować dowolny komunikat, również taki jeszcze nieistniejący ;->
						var request = new CustomMsg("MyCustomRequest");
						var xmlElement = request.AddElement("Test");
						xmlElement.SetAttribute("attr1", "1");
						xmlElement.SetAttribute("attr2", "2");
						// wysyłka tak samodzielnie spreparowanego komunikatu
						request.Send(syncSocket);
						// odbiór odpowiedzi - tutaj powinniśmy otrzymać błąd... "BizMessageRejectException"
						// niestety aktualna wersja NOL3 zwraca nieprawidłowy XML, którego nie da się parsować
						Console.WriteLine("\nPress any key... to read the response\n");
						Console.ReadKey(true);
						var response = new FixmlMsg(syncSocket);
					}
				}
				catch (Exception e)
				{
					MyUtil.PrintError(e);
				}
				FixmlMsg.DebugOriginalXml.Enabled = tmp;
				Console.ReadKey(true);
				if (asyncSocket != null) asyncSocket.Close();

			}  // tu następuje automatyczne wylogowanie
		}
		public MarketDataIncRefreshMsg(FixmlMsg m) : base(m) { }
示例#12
0
 public StatementMsg(FixmlMsg m) : base(m)
 {
 }
示例#13
0
		// procedura wątku z obsługą kanału asynchronicznego
		private void ThreadProc()
		{
			try
			{
				using (Socket socket = GetAsyncSocket())
				{
					while (socket.Connected)
					{
						Debug.WriteLineIf(FixmlMsg.DebugInternals.Enabled, "");
						FixmlMsg msg;
						// odbiór komunikatu, na razie w "bezimiennej" klasie bazowej FixmlMsg
						try { msg = new FixmlMsg(socket); }
						catch (ThreadAbortException) { throw; }
						catch (FixmlSocketException) { throw; }
						catch (Exception e) { e.PrintError(); continue; }
						// rozpoznanie typu komunikatu i przetworzenie na konkretną klasę pochodną z FixmlMsg
						try { msg = FixmlMsg.GetParsedMsg(msg); }
						catch (ThreadAbortException) { throw; }
						catch (Exception e) { e.PrintError(); }
						// wywołanie podpiętych metod obsługi danego komunikatu
						try
						{
							if (AsyncMessageEvent != null) AsyncMessageEvent(msg);
							if (msg is AppMessageReportMsg)
								if (AppReportMsgEvent != null) AppReportMsgEvent((AppMessageReportMsg)msg);
							if (msg is ExecutionReportMsg)
								if (ExecReportMsgEvent != null) ExecReportMsgEvent((ExecutionReportMsg)msg);
							if (msg is MarketDataIncRefreshMsg)
								if (MarketDataMsgEvent != null) MarketDataMsgEvent((MarketDataIncRefreshMsg)msg);
							if (msg is TradingSessionStatusMsg)
								if (SessionStatusMsgEvent != null) SessionStatusMsgEvent((TradingSessionStatusMsg)msg);
							if (msg is NewsMsg)
								if (NewsMsgEvent != null) NewsMsgEvent((NewsMsg)msg);
							if (msg is StatementMsg)
								if (StatementMsgEvent != null) StatementMsgEvent((StatementMsg)msg);
							if (msg is UserResponseMsg)
								if (UserResponseMsgEvent != null) UserResponseMsgEvent((UserResponseMsg)msg);
						}
						catch (ThreadAbortException) { throw; }
						catch (Exception e) { e.PrintError(); }
					}
				}
			}
			catch (ThreadAbortException) { Thread.ResetAbort(); }
			catch (Exception e) { e.PrintError(); }
			Debug.WriteLineIf(FixmlMsg.DebugInternals.Enabled, "NolClient.ThreadProc stop", FixmlMsg.DebugCategory);
		}
 public UserResponseMsg(FixmlMsg m) : base(m)
 {
 }
示例#15
0
 public MarketDataIncRefreshMsg(FixmlMsg m) : base(m)
 {
 }
		public ExecutionReportMsg(FixmlMsg m) : base(m) { }
		public UserResponseMsg(FixmlMsg m) : base(m) { }
示例#18
0
 public TradingSessionStatusMsg(FixmlMsg msg) : base(msg)
 {
 }
		public FixmlErrorMsgException(FixmlMsg msg) : this(msg.ToString(), msg) { }
示例#20
0
		public NewsMsg(FixmlMsg m) : base(m) { }
 public FixmlErrorMsgException(FixmlMsg msg) : this(msg.ToString(), msg)
 {
 }
示例#22
0
		// Konstruktor używany wewnętrznie dla komunikatów przychodzących - 
		// "opakowywuje" odebrany komunikat w inną, bardziej precyzyjną klasę pochodną. 
		protected FixmlMsg(FixmlMsg msg)
		{
			Debug.WriteLineIf(DebugInternals.Enabled, string.Format("new {0} from FixmlMsg", GetType().Name), DebugCategory);
			xmlDoc = msg.xmlDoc;
			ParseXmlMessage(null);
			Debug.WriteLineIf(DebugParsedMessage.Enabled, this.ToString(), DebugRecvCategory);
			Debug.WriteLineIf(DebugInternals.Enabled, string.Format("new {0} ok", GetType().Name), DebugCategory);
		}