Пример #1
0
		// funkcja pomocnicza zamieniająca typ zlecenia FIXML na nasz DTO.PriceType
		private static PriceType ExecReport_GetPriceType(ExecutionReportMsg msg)
		{
			switch (msg.Type)
			{
				case OrderType.Limit:
				case OrderType.StopLimit: return PriceType.Limit;
				case OrderType.PKC:
				case OrderType.StopLoss: return PriceType.PKC;
				case OrderType.PCR_PCRO:
					var time = msg.TimeInForce;
					var pcro = ((time == OrdTimeInForce.Opening) || (time == OrdTimeInForce.Closing));
					return pcro ? PriceType.PCRO : PriceType.PCR;
				default: throw new ArgumentException("Unknown ExecReport-OrderType");
			}
		}
		/// <summary>
		/// Przykład wysyłki zleceń, korzystając bezpośrednio z klas NewOrderSingleMsg i spółki...
		/// Test ten wrzuca na giełdę zlecenie kupna 1 x FW20 po 1000zł (*raczej* nie ma szans się zrealizować :)),
		/// następnie je modyfikuje ustawiając limit ceny oczko wyżej... aż ostatecznie całe zlecenie anuluje. 
		/// </summary>
		public void Execute()
		{
			var accountNumber = "00-22-...";  // <- wpisz tu swój numer, żeby program nie musiał o niego pytać
			if (accountNumber.EndsWith("..."))
			{
				Console.Write("Podaj numer rachunku (końcówkę z " + accountNumber + "): ");
				var str = Console.ReadLine();
				accountNumber = accountNumber.Replace("...", str);
				Trace.WriteLine("Wybrany rachunek: " + accountNumber);
			}

			// nawiązanie połączenia z NOL3 i zalogowanie użytkownika
			using (var nol = new NolClient())
			{
				Thread.Sleep(2000);
				var tmp = FixmlMsg.DebugFormattedXml.Enabled;
				try
				{
					ExecutionReportMsg execReport;

					// --- wysyłka nowego zlecenia --- 
					Console.WriteLine("\nPress any key... to send NEW order request    [Esc - exit]\n");
					if (Console.ReadKey(true).Key == ConsoleKey.Escape) return;

					var newRequest = new NewOrderSingleMsg();
					newRequest.Account = accountNumber;
					newRequest.Side = OrderSide.Buy;
					newRequest.Instrument = FixmlInstrument.FindBySym("FW20H12");
					newRequest.Quantity = 1;
					newRequest.Price = 1000;
					using (var socket = NolClient.GetSyncSocket())
					{
						FixmlMsg.DebugFormattedXml.Enabled = true;  // <- wyświetli nam dokładną treść komunikatów
						newRequest.Send(socket);
						execReport = new ExecutionReportMsg(socket);
						FixmlMsg.DebugFormattedXml.Enabled = tmp;
					}
					Thread.Sleep(3000);

					// --- modyfikacja tego zlecenia ---
					Console.WriteLine("\nPress any key... to MODIFY this order request    [Esc - exit]\n");
					if (Console.ReadKey(true).Key == ConsoleKey.Escape) return;

					var replaceRequest = new OrderReplaceRequestMsg();
					replaceRequest.BrokerOrderId2 = execReport.BrokerOrderId2;
					replaceRequest.Account = accountNumber;
					replaceRequest.Side = OrderSide.Buy;
					replaceRequest.Instrument = newRequest.Instrument;
					replaceRequest.Quantity = 1;
					replaceRequest.Price = 1001;
					using (var socket = NolClient.GetSyncSocket())
					{
						FixmlMsg.DebugFormattedXml.Enabled = true;
						replaceRequest.Send(socket);
						execReport = new ExecutionReportMsg(socket);
						FixmlMsg.DebugFormattedXml.Enabled = tmp;
					}
					Thread.Sleep(3000);

					// --- anulowanie tego zlecenia ---
					Console.WriteLine("\nPress any key... to CANCEL this order request    [Esc - exit]\n");
					if (Console.ReadKey(true).Key == ConsoleKey.Escape) return;

					var cancelRequest = new OrderCancelRequestMsg();
					cancelRequest.BrokerOrderId2 = replaceRequest.BrokerOrderId2;
					cancelRequest.Account = accountNumber;
					cancelRequest.Side = newRequest.Side;
					cancelRequest.Instrument = newRequest.Instrument;
					cancelRequest.Quantity = newRequest.Quantity;
					using (var socket = NolClient.GetSyncSocket())
					{
						FixmlMsg.DebugFormattedXml.Enabled = true;
						cancelRequest.Send(socket);
						execReport = new ExecutionReportMsg(socket);
						FixmlMsg.DebugFormattedXml.Enabled = false;
					}
					Thread.Sleep(3000);

					Console.WriteLine("\nPress any key... to exit\n");
					Console.ReadKey(true);
					Console.WriteLine("\n\nThank you :)\n");
				}
				catch (Exception e)
				{
					MyUtil.PrintError(e);
				}
				FixmlMsg.DebugFormattedXml.Enabled = tmp;
			}  // tu następuje wylogowanie
		}
Пример #3
0
		// funkcja pomocnicza zamieniająca status zlecenia FIXML na nasz BosOrderStatus
		private static BosOrderStatus ExecReport_GetStatus(ExecutionReportMsg msg)
		{
			switch (msg.Status)
			{
				case ExecReportStatus.New: return BosOrderStatus.Active;
				case ExecReportStatus.PartiallyFilled: return BosOrderStatus.ActiveFilled;
				case ExecReportStatus.Canceled: return ((msg.CumulatedQuantity ?? 0) > 0) ? BosOrderStatus.CancelledFilled : BosOrderStatus.Cancelled;
				case ExecReportStatus.Filled: return BosOrderStatus.Filled;
				case ExecReportStatus.Expired: return BosOrderStatus.Expired;
				case ExecReportStatus.Rejected: return BosOrderStatus.Rejected;
				case ExecReportStatus.PendingReplace: return BosOrderStatus.PendingReplace;
				case ExecReportStatus.PendingCancel: return BosOrderStatus.PendingCancel;
				default: throw new ArgumentException("Unknown ExecReport-Status");
			}
		}
Пример #4
0
		// wewnętrzna obsługa komunikatu "ExecRpt"
		// - wywołuje zdarzenie "OrderUpdateEvent"
		private void ExecReportMsgHandler(ExecutionReportMsg msg)
		{
			if (OrderUpdateEvent != null)
			{
				var order = new OrderData();
				order.AccountNumber = msg.Account;
				order.BrokerId = msg.BrokerOrderId2;
				order.ClientId = msg.ClientOrderId;

				// UWAGA: odczyt danych z komunikatu ExecRpt odbywa się "na czuja"... bo dostarczoną 
				// z Bossy/Comarchu dokumentacją na ten temat to można sobie najwyżej w kominku podpalić.
				// Generalnie wszystko jest rozjechane, ale te statusy zleceń to już chyba po pijaku pisali.
				//   Tyle - musiałem to tu napisać !!!  ;-P
				// Bo mnie już krew zalewa, jak widzę co ten NOL3 wysyła i gdzie (w których polach)... 
				// I że w ogóle musiałem te wszystkie możliwe przypadki samodzielnie analizować...
				// A jak za miesiąc przestanie działać, bo coś tam "naprawią", to chyba kogoś postrzelę ;-(


				// raport o wykonaniu - być może cząstkowym - danego zlecenia
				// (z praktyki wynika, że zawsze wcześniej dostaniemy "pełen" ExecRpt z pozostałymi
				// informacjami o tym zleceniu... dlatego teraz odbieramy sobie tylko raport z tej transakcji)
				if (msg.ExecType == ExecReportType.Trade)
				{
					order.TradeReport = new OrderTradeData();
					order.TradeReport.Time = (DateTime)msg.TransactionTime;
					order.TradeReport.Price = (decimal)msg.Price;  // LastPrice !?
					order.TradeReport.Quantity = (uint)msg.Quantity;  // LastQuantity !?
					order.TradeReport.NetValue = (decimal)msg.NetMoney;
					order.TradeReport.Commission = (decimal)msg.CommissionValue;
				}
				else
				{
					// w pozostałych przypadkach wygląda na to, że lepiej się oprzeć na polu "Status"
					// (bo ExecType czasem jest, czasem nie ma - różnie to z nim bywa... a Status jest chyba zawsze)
					order.StatusReport = new OrderStatusData();
					order.StatusReport.Status = ExecReport_GetStatus(msg);
					order.StatusReport.Quantity = (uint)msg.CumulatedQuantity;
					order.StatusReport.NetValue = (decimal)msg.NetMoney;
					order.StatusReport.Commission = (decimal)msg.CommissionValue;  // czasem == 0, ale dlaczego!? kto to wie... 

					// pozostałe dane - żeby się nie rozdrabniać - też aktualizujemy za każdym razem
					// (teoretycznie wystarczyłoby przy "new" i "replace"... ale czasem jako pierwsze
					// przychodzi np. "filled" i kto wie co jeszcze innego, więc tak będzie bezpieczniej)
					order.MainData = new OrderMainData();
					order.MainData.CreateTime = (DateTime)msg.TransactionTime;
					order.MainData.Instrument = msg.Instrument.Convert();
					order.MainData.Side = (msg.Side == Fixml.OrderSide.Buy) ? BosOrderSide.Buy : BosOrderSide.Sell;
					order.MainData.PriceType = ExecReport_GetPriceType(msg);
					if (order.MainData.PriceType == PriceType.Limit)
						order.MainData.PriceLimit = msg.Price;
					if ((msg.Type == OrderType.StopLimit) || (msg.Type == OrderType.StopLoss))
						order.MainData.ActivationPrice = msg.StopPrice;
					order.MainData.Quantity = (uint)msg.Quantity;
					order.MainData.MinimumQuantity = (msg.TimeInForce == OrdTimeInForce.WuA) ? msg.Quantity : msg.MinimumQuantity;
					order.MainData.VisibleQuantity = msg.DisplayQuantity;
					order.MainData.ImmediateOrCancel = (msg.TimeInForce == OrdTimeInForce.WiA);
					order.MainData.ExpirationDate = (msg.TimeInForce == OrdTimeInForce.Date) ? msg.ExpireDate : null;
				}

				// wywołanie zdarzenia z przygotowanymi danymi
				OrderUpdateEvent(order);
			}
		}
Пример #5
0
		// Metoda IBosClient do anulowania istniejącego zlecenia.
		public void OrderCancel(OrderData data)
		{
			Debug.WriteLine("\nOrderCancel...");
			using (Socket socket = NolClient.GetSyncSocket())
			{
				OrderCancelRequestMsg request = new OrderCancelRequestMsg();
				request.Account = data.AccountNumber;
				request.BrokerOrderId2 = data.BrokerId;
				request.Instrument = FixmlInstrument.Find(data.MainData.Instrument);
				request.Side = (data.MainData.Side == BosOrderSide.Buy) ? OrderSide.Buy : OrderSide.Sell;
				request.Quantity = data.MainData.Quantity;
				request.Send(socket);
				ExecutionReportMsg response = new ExecutionReportMsg(socket);
			}
			Debug.WriteLine("OrderCancel OK\n");
		}
Пример #6
0
		// Metoda IBosClient do modyfikacji istniejącego zlecenia.
		public void OrderReplace(OrderData data)
		{
			Debug.WriteLine("\nOrderReplace...");
			using (Socket socket = NolClient.GetSyncSocket())
			{
				OrderReplaceRequestMsg request = new OrderReplaceRequestMsg();
				request.Account = data.AccountNumber;
				request.BrokerOrderId2 = data.BrokerId;
				request.Instrument = FixmlInstrument.Find(data.MainData.Instrument);
				request.Side = (data.MainData.Side == BosOrderSide.Buy) ? OrderSide.Buy : OrderSide.Sell;
				request.Type = Order_GetType(data.MainData);
				request.Price = data.MainData.PriceLimit;
				request.StopPrice = data.MainData.ActivationPrice;
				request.Quantity = data.MainData.Quantity;
				request.MinimumQuantity = data.MainData.MinimumQuantity;
				request.DisplayQuantity = data.MainData.VisibleQuantity;
				request.TimeInForce = Order_GetTimeInForce(data.MainData);
				request.ExpireDate = data.MainData.ExpirationDate;
				request.Send(socket);
				ExecutionReportMsg response = new ExecutionReportMsg(socket);
			}
			Debug.WriteLine("OrderReplace OK\n");
		}
Пример #7
0
		// Metoda IBosClient do składania nowego zlecenia.
		public string OrderCreate(OrderData data)
		{
			string clientId;
			Debug.WriteLine("\nOrderCreate...");
			using (Socket socket = NolClient.GetSyncSocket())
			{
				NewOrderSingleMsg request = new NewOrderSingleMsg();
				clientId = request.ClientOrderId;  // automatycznie przydzielone kolejne Id
				request.Account = data.AccountNumber;
				request.CreateTime = data.MainData.CreateTime;
				request.Instrument = FixmlInstrument.Find(data.MainData.Instrument);
				request.Side = (data.MainData.Side == BosOrderSide.Buy) ? OrderSide.Buy : OrderSide.Sell;
				request.Type = Order_GetType(data.MainData);
				request.Price = data.MainData.PriceLimit;
				request.StopPrice = data.MainData.ActivationPrice;
				request.Quantity = data.MainData.Quantity;
				request.MinimumQuantity = data.MainData.MinimumQuantity;
				request.DisplayQuantity = data.MainData.VisibleQuantity;
				request.TimeInForce = Order_GetTimeInForce(data.MainData);
				request.ExpireDate = data.MainData.ExpirationDate;
				request.Send(socket);
				ExecutionReportMsg response = new ExecutionReportMsg(socket);
			}
			Debug.WriteLine("OrderCreate OK\n");
			return clientId;
		}