예제 #1
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);
        }
예제 #2
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");
 }
예제 #3
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");
            }
        }
예제 #4
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");
 }
예제 #5
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");
            }
        }
예제 #6
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);
            }
        }
예제 #7
0
        /// <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
        }