protected virtual OrderBookEntry GetAvailableToBuy(double maxBuy)
        {
            OrderBookEntry res        = new OrderBookEntry();
            double         maxDeposit = ApplyFee(MaxActualBuyDeposit);

            lock (Ticker.OrderBook.Asks) {
                for (int i = 0; i < Ticker.OrderBook.Asks.Count; i++)
                {
                    OrderBookEntry entry = Ticker.OrderBook.Asks[i];
                    if (maxBuy != 0 && entry.Value > maxBuy)
                    {
                        break;
                    }
                    res.Value = entry.Value;
                    double amount = maxDeposit / entry.Value;
                    if (amount > entry.Amount)
                    {
                        amount = entry.Amount;
                    }
                    res.Amount += amount;
                    maxDeposit -= amount * entry.Value;
                    if (maxDeposit == 0)
                    {
                        break;
                    }
                }
            }
            return(res);
        }
Пример #2
0
        private static void OnOrderBookChanged(object sender, OrderBookEventArgs e)
        {
            Ticker t = ((OrderBook)sender).Owner;

            OrderBookEntry ask = t.OrderBook.Asks[0];
            OrderBookEntry bid = t.OrderBook.Bids[0];
        }
 private void InsertOrderHistoryEntry(
     decimal filledQty, OrderBookEntry orderToClose, OrderStatus status, DateTime closeTime)
 {
     OrderHistory.InsertOne(
         new OrderHistoryEntry
     {
         CreateTime = orderToClose.EntryTime,
         CloseTime  = closeTime,
         User       = orderToClose.User,
         AccountId  = orderToClose.AccountId,
         Instrument = orderToClose.Instrument,
         Qty        = orderToClose.Qty,
         Side       = orderToClose.Side,
         // Closed limit order
         Type = OrderType.Limit,
         // The entire order quantity was filled
         FilledQty  = filledQty,
         LimitPrice = orderToClose.LimitPrice,
         StopPrice  = null,
         // TODO from stop loss and take profit
         //ChildrenIds
         DurationType = orderToClose.DurationType,
         Duration     = orderToClose.Duration,
         Status       = status,
     }
         );
 }
Пример #4
0
        public override bool UpdateOrderBook(TickerBase ticker)
        {
            string address = string.Format("https://yobit.net/api/3/depth/{0}?depth={1}",
                                           Uri.EscapeDataString(ticker.CurrencyPair), OrderBook.Depth);
            string text = ((TickerBase)ticker).DownloadString(address);

            if (string.IsNullOrEmpty(text))
            {
                return(false);
            }

            Dictionary <string, object> res2 = null;

            lock (JsonParser) {
                res2 = JsonParser.Parse(text) as Dictionary <string, object>;
                if (res2 == null)
                {
                    return(false);
                }
            }
            res2 = (Dictionary <string, object>)res2[ticker.CurrencyPair];
            List <object> bids = (List <object>)res2["bids"];
            List <object> asks = (List <object>)res2["asks"];

            ticker.OrderBook.GetNewBidAsks();
            int index = 0;

            OrderBookEntry[] list = ticker.OrderBook.Bids;
            foreach (List <object> item in bids)
            {
                OrderBookEntry entry = list[index];
                entry.ValueString  = (string)item.First();
                entry.AmountString = (string)item.Last();
                index++;
                if (index >= list.Length)
                {
                    break;
                }
            }
            index = 0;
            list  = ticker.OrderBook.Asks;
            foreach (List <object> item in asks)
            {
                OrderBookEntry entry = list[index];
                entry.ValueString  = (string)item.First();
                entry.AmountString = (string)item.Last();
                index++;
                if (index >= list.Length)
                {
                    break;
                }
            }

            ticker.OrderBook.UpdateEntries();
            ticker.OrderBook.RaiseOnChanged(new OrderBookUpdateInfo()
            {
                Action = OrderBookUpdateType.RefreshAll
            });
            return(true);
        }
Пример #5
0
        public void RunPriceLevelDelete(string pair, OrderBookEntry[] bids, OrderBookEntry[] asks)
        {
            if (OrderBooks.ContainsKey(pair))
            {
                OrderBookDictionary dic = OrderBooks[pair];

                foreach (OrderBookEntry bid in bids)
                {
                    if (dic.Entries.ContainsKey(bid.id))
                    {
                        OrderBookEntry entry = dic.Entries[bid.id];
                        dic.Entries.Remove(bid.id);
                    }
                    //else
                    //    throw new Exception(string.Format("Could not find price level for pair {0} with id {1}", pair, bid.id));
                }

                foreach (OrderBookEntry ask in asks)
                {
                    if (dic.Entries.ContainsKey(ask.id))
                    {
                        OrderBookEntry entry = dic.Entries[ask.id];
                        dic.Entries.Remove(ask.id);
                    }
                    //else
                    //    throw new Exception(string.Format("Could not find price level for pair {0} with id {1}", pair, ask.id));
                }
            }
            else
            {
                throw new Exception(string.Format("Unknown Error: Order Book not found in memory for pair {0}", pair));
            }
        }
Пример #6
0
        public void RunPriceLevelUpdate(string pair, OrderBookEntry[] bids, OrderBookEntry[] asks)
        {
            if (OrderBooks.ContainsKey(pair))
            {
                OrderBookDictionary dic = OrderBooks[pair];

                foreach (OrderBookEntry bid in bids)
                {
                    if (dic.Entries.ContainsKey(bid.id))
                    {
                        OrderBookEntry entry = dic.Entries[bid.id];
                        entry.size = bid.size;
                    }
                    //else
                    //   throw new Exception(string.Format("Could not find price level for pair {0} with id {1}", pair, bid.id));
                }

                foreach (OrderBookEntry ask in asks)
                {
                    if (dic.Entries.ContainsKey(ask.id))
                    {
                        OrderBookEntry entry = dic.Entries[ask.id];
                        Console.WriteLine(string.Format("ASK UPDATE SIZE={0} PRICE={1}", ask.size.ToString("##.##"), entry.price.ToString("##.########")));
                        entry.size = ask.size;
                    }
                    //else
                    //    throw new Exception(string.Format("Could not find price level for pair {0} with id {1}", pair, ask.id));
                }
            }
            else
            {
                throw new Exception(string.Format("Unknown Error: Order Book not found in memory for pair {0}", pair));
            }
        }
        protected virtual OrderBookEntry GetAvailableToSell(double minSell)
        {
            OrderBookEntry res        = new OrderBookEntry();
            double         maxDeposit = ApplyFee(MaxActualSellDeposit);

            res.Amount = maxDeposit;
            lock (Ticker.OrderBook.Bids) {
                for (int i = 0; i < Ticker.OrderBook.Bids.Count; i++)
                {
                    OrderBookEntry entry = Ticker.OrderBook.Bids[i];
                    if (minSell != 0 && entry.Value < minSell)
                    {
                        break;
                    }
                    res.Value   = entry.Value;
                    res.Amount += entry.Amount;
                    maxDeposit -= entry.Amount;
                    if (maxDeposit <= 0)
                    {
                        break;
                    }
                }
            }
            res.Amount = Math.Min(res.Amount, ApplyFee(MaxActualSellDeposit));
            return(res);
        }
        public BitmexMarketDataOrderBookEntryWrapper(string pAction, OrderBookEntry pOrderBookEntry, bool isBid)
        {
            action = pAction;

            OrderBookEntry = pOrderBookEntry;

            IsBid = isBid;
        }
Пример #9
0
        public void ShortSellTest()
        {
            //OrderList = new Dictionary<string, int>();
            //OrderList.Add("000768", 1000);
            //OrderList.Add("600893", 600);
            //OrderList.Add("300070", 1200);
            //OrderList.Add("300024", 1000);
            //OrderList.Add("300124", 700);
            //OrderList.Add("300058", 800);
            //OrderList.Add("300002", 1000);
            //OrderList.Add("300003", 800);

            if (OrderList == null)
            {
                return;
            }

            foreach (KeyValuePair <string, int> kvp in OrderList)
            {
                try
                {
                    SingleStockData sd = dataDict[kvp.Key];

                    FIXApi.OrderBookEntry entry = new OrderBookEntry();
                    entry.strategies     = TradingStrategies.StockTrending;
                    entry.action         = OrderAction.ShortSell;
                    entry.type           = FIXApi.OrderType.CreditMarginSell;
                    entry.ticker         = kvp.Key;
                    entry.quantityListed = kvp.Value;

                    int tCount = 0;
                    while (sd.AskPrices[0] == 0)
                    {
                        tCount++;
                        Thread.Sleep(100);
                        if (tCount > 100)
                        {
                            break;
                        }
                    }

                    if (sd.AskPrices[0] == 0)
                    {
                        continue;
                    }

                    entry.priceListed = sd.AskPrices[0];

                    Thread orderThread = new Thread(new ParameterizedThreadStart(tc.OrderSender_StockTrending));
                    orderThread.IsBackground = true;
                    orderThread.Start(entry);
                }
                catch (Exception ex)
                {
                    strListLog.Add(ex.Message);
                }
            }
        }
Пример #10
0
        public void GetOrderBook(BittrexMarketInfo info, int depth)
        {
            Timer.Reset();
            Timer.Start();
            string address = string.Format("https://bittrex.com/api/v1.1/public/getorderbook?market={0}&type=both&depth={1}", Uri.EscapeDataString(info.MarketName), depth);
            string text    = GetDownloadString(info, address);

            if (string.IsNullOrEmpty(text))
            {
                return;
            }
            JObject res = (JObject)JsonConvert.DeserializeObject(text);

            foreach (JProperty prop in res.Children())
            {
                if (prop.Name == "success")
                {
                    if (prop.Value.Value <bool>() == false)
                    {
                        break;
                    }
                }
                if (prop.Name == "message")
                {
                    continue;
                }
                if (prop.Name == "result")
                {
                    lock (info) {
                        info.OrderBook.Clear();
                        JArray bids = ((JObject)prop.Value).Value <JArray>("buy");
                        JArray asks = ((JObject)prop.Value).Value <JArray>("sell");
                        foreach (JObject obj in bids)
                        {
                            OrderBookEntry e = new OrderBookEntry();
                            e.Value  = obj.Value <double>("Rate");
                            e.Amount = obj.Value <double>("Quantity");
                            info.OrderBook.Bids.Add(e);
                        }
                        foreach (JObject obj in asks)
                        {
                            OrderBookEntry e = new OrderBookEntry();
                            e.Value  = obj.Value <double>("Rate");
                            e.Amount = obj.Value <double>("Quantity");
                            info.OrderBook.Asks.Add(e);
                        }
                    }
                    Timer.Stop();
                    Console.WriteLine(DateTime.Now.ToString("hh:mm:ss.fff") + " order book update. process time = " + Timer.ElapsedMilliseconds);
                }
            }
            info.OrderBook.RaiseOnChanged(new OrderBookUpdateInfo()
            {
                Action = OrderBookUpdateType.RefreshAll
            });
        }
Пример #11
0
        public void OrderBookEntry_constructor_test()
        {
            double price  = 100;
            double volume = 10;

            OrderBookEntry entry = new OrderBookEntry(price, volume);

            Assert.AreEqual(price, entry.Price);
            Assert.AreEqual(volume, entry.Volume);
        }
Пример #12
0
        private void UpdateOrderBook()
        {
            List <OrderBookRowData> list = new List <OrderBookRowData>();

            lock (this.instrument.OrderBook.Ask.SyncRoot)
            {
                IEnumerator local_7 = this.instrument.OrderBook.Ask.GetEnumerator();
                try
                {
                    while (local_7.MoveNext())
                    {
                        OrderBookEntry local_1 = (OrderBookEntry)local_7.Current;
                        list.Insert(0, new OrderBookRowData(local_1.Price, new int?(), new int?(local_1.Size)));
                    }
                }
                finally
                {
                    IDisposable local_9 = local_7 as IDisposable;
                    if (local_9 != null)
                    {
                        local_9.Dispose();
                    }
                }
            }
            lock (this.instrument.OrderBook.Bid.SyncRoot)
            {
                IEnumerator local_11 = this.instrument.OrderBook.Bid.GetEnumerator();
                try
                {
                    while (local_11.MoveNext())
                    {
                        OrderBookEntry local_2 = (OrderBookEntry)local_11.Current;
                        list.Add(new OrderBookRowData(local_2.Price, new int?(local_2.Size), new int?()));
                    }
                }
                finally
                {
                    IDisposable local_13 = local_11 as IDisposable;
                    if (local_13 != null)
                    {
                        local_13.Dispose();
                    }
                }
            }
            this.dgvBook.Columns["colPrice"].DefaultCellStyle.Format = this.instrument.PriceDisplay;
            int scrollingRowIndex = this.dgvBook.FirstDisplayedScrollingRowIndex;

            this.dgvBook.DataSource = (object)list;
            if (scrollingRowIndex < 0 || scrollingRowIndex >= this.dgvBook.Rows.Count)
            {
                return;
            }
            this.dgvBook.FirstDisplayedScrollingRowIndex = scrollingRowIndex;
        }
Пример #13
0
        /**
         * getOrderBookExample
         * Get the market depth for specific market.
         */
        public static void GetOrderBookExample()
        {
            /***Initialize the calling object*/
            IdaxApiRestClient idaxApiRestClient = IdaxConfig.init();

            /**Request parameter encapsulation**/
            string symbol = IdaxApiConstants.ETH_BTC;

            /**Call remote interface**/
            OrderBookEntry orderBook = idaxApiRestClient.getOrderBook(symbol);
        }
Пример #14
0
        public OrderBookEntry GetOrderBookEntry(Wrapper wrapper)
        {
            OrderBookEntry entry = new OrderBookEntry();

            entry.MDEntryType    = (MDEntryType)wrapper.GetField(MarketDataOrderBookEntryFields.MDEntryType);
            entry.MDUpdateAction = (MDUpdateAction)wrapper.GetField(MarketDataOrderBookEntryFields.MDUpdateAction);
            entry.Symbol         = (ValidateField(wrapper, MarketDataOrderBookEntryFields.Symbol) ? Convert.ToString(wrapper.GetField(MarketDataOrderBookEntryFields.Symbol)) : null);
            entry.MDEntrySize    = (ValidateField(wrapper, MarketDataOrderBookEntryFields.MDEntrySize) ? Convert.ToDecimal(wrapper.GetField(MarketDataOrderBookEntryFields.MDEntrySize)) : 0);
            entry.MDEntryPx      = (ValidateField(wrapper, MarketDataOrderBookEntryFields.MDEntryPx) ? Convert.ToDecimal(wrapper.GetField(MarketDataOrderBookEntryFields.MDEntryPx)) : 0);

            return(entry);
        }
Пример #15
0
        private void button1_Click(object sender, EventArgs e)
        {
            //限价
            //string tickerListStr = dc.LoadDataDict();
            //dc.SetSubscription(tickerListStr, SubscriptionType.SUBSCRIPTION_SET);
            //while (dataDict.Count < 1000)
            //    Thread.Sleep(1000);

            if (OrderClassList.Count == 0)
            {
                MessageBox.Show("无下单股票");
            }

            foreach (OrderClass oclass in OrderClassList)
            {
                OrderBookEntry entry = new OrderBookEntry();
                entry.Account = oclass.Account;
                //买卖方向
                entry.action         = (OrderAction)Enum.Parse(typeof(OrderAction), oclass.Direction);
                entry.orderTime      = Convert.ToInt32(DateTime.Now.ToString("Hmmss"));
                entry.orderDate      = Convert.ToInt32(DateTime.Now.ToString("yyyyMMdd"));
                entry.ticker         = oclass.Ticker;
                entry.strategies     = (TradingStrategies)Enum.Parse(typeof(TradingStrategies), oclass.Strategy);
                entry.quantityListed = oclass.Num;

                //限价
                //entry.bMarket = false;
                //entry.priceListed = 10;
                //市价
                entry.bMarket     = true;
                entry.priceListed = 0;

                //模拟交易时使用资金账户买
                if (Convert.ToString(entry.action).Contains("Buy"))
                {
                    entry.type = OrderType.CashBuy;
                }

                else
                {
                    entry.type = OrderType.CashSell;
                }

                Thread orderThread = new Thread(new ParameterizedThreadStart(ec.OrderRouter));
                orderThread.IsBackground = true;
                orderThread.Start(entry);
                Thread.Sleep(100);
            }
        }
        protected void Buy()
        {
            OrderBookEntry e   = GetAvailableToBuy(BuyLevel);
            TradingResult  res = MarketBuy(e.Value, e.Amount);

            if (res == null)
            {
                return;
            }

            BoughtTotal          += res.Total;
            Earned               -= res.Total + CalcFee(res.Total);
            MaxActualBuyDeposit  -= res.Total + CalcFee(res.Total);
            MaxActualSellDeposit += res.Amount;
        }
        protected void Sell()
        {
            OrderBookEntry e   = GetAvailableToSell(SellLevel);
            TradingResult  res = MarketSell(e.Value, e.Amount);

            if (res == null)
            {
                return;
            }

            SoldTotal            += res.Amount;
            Earned               += res.Total - CalcFee(res.Total);
            MaxActualBuyDeposit  += res.Total;
            MaxActualSellDeposit -= res.Amount + CalcFee(res.Total);
        }
        private void AssertMatchOrderQty(
            MatchOrderEventEntry matchOrder, OrderBookEntry actionOrder, OrderBookEntry targetOrder)
        {
            if (actionOrder != null && matchOrder.ActionOrderQtyRemaining !=
                actionOrder.Qty - (actionOrder.FilledQty + matchOrder.Qty))
            {
                throw new Exception(
                          $"Integrity assertion failed! {nameof(MatchOrderEventEntry)} ID {matchOrder.Id} attempted to increase {nameof(targetOrder.FilledQty)} of action order ID {actionOrder.Id} from {actionOrder.FilledQty.ToString(CultureInfo.CurrentCulture)} by {matchOrder.Qty}, but that didn't add up to event entry-asserted value of {matchOrder.ActionOrderQtyRemaining.ToString(CultureInfo.CurrentCulture)}!");
            }

            if (matchOrder.TargetOrderQtyRemaining != targetOrder.Qty - (targetOrder.FilledQty + matchOrder.Qty))
            {
                throw new Exception(
                          $"Integrity assertion failed! {nameof(MatchOrderEventEntry)} ID {matchOrder.Id} attempted to increase {nameof(targetOrder.FilledQty)} of target order ID {targetOrder.Id} from {targetOrder.FilledQty.ToString(CultureInfo.CurrentCulture)} by {matchOrder.Qty}, but that didn't add up to event entry-asserted value of {matchOrder.TargetOrderQtyRemaining.ToString(CultureInfo.CurrentCulture)}!");
            }
        }
Пример #19
0
 public NewOrder(SymbolInformation si, OrderBookEntry entry = null) : base(si)
 {
     if (entry != null)
     {
         Price    = entry.Price;
         Quantity = entry.Quantity;
         Side     = (entry.Side == TradeSide.Buy) ? TradeSide.Sell : TradeSide.Buy;
     }
     else
     {
         Price = si.PriceTicker.LastPrice.GetValueOrDefault();
     }
     this.WhenAnyValue(x => x.Side).Subscribe(OrderSideDependantActions);
     this.WhenAnyValue(x => x.BalancePercent).Subscribe(y => CalcQuantity());
     BalancePercent = 0.05;
 }
Пример #20
0
        void OnUpdateOrderBook(Ticker ticker, byte[] bytes)
        {
            int startIndex = 0;

            string[] updateId = JSonHelper.Default.StartDeserializeObject(bytes, ref startIndex, OrderBookStartItems);

            const string bidString = "\"bids\":";
            const string askString = "\"asks\":";

            startIndex += bidString.Length + 1;
            List <string[]> jbids = JSonHelper.Default.DeserializeArrayOfArrays(bytes, ref startIndex, 3);

            startIndex += askString.Length + 1;
            List <string[]> jasks = JSonHelper.Default.DeserializeArrayOfArrays(bytes, ref startIndex, 3);

            List <OrderBookEntry> bids  = ticker.OrderBook.Bids;
            List <OrderBookEntry> asks  = ticker.OrderBook.Asks;
            List <OrderBookEntry> iasks = ticker.OrderBook.AsksInverted;

            bids.Clear();
            asks.Clear();
            iasks.Clear();

            foreach (string[] item in jbids)
            {
                bids.Add(new OrderBookEntry()
                {
                    ValueString = item[0], AmountString = item[1]
                });
            }

            foreach (string[] item in jasks)
            {
                OrderBookEntry e = new OrderBookEntry()
                {
                    ValueString = item[0], AmountString = item[1]
                };
                asks.Add(e);
                iasks.Insert(0, e);
            }

            ticker.OrderBook.Updates.Clear(FastValueConverter.ConvertPositiveLong(updateId[0]) + 1);
            ticker.OrderBook.UpdateEntries();
            ticker.OrderBook.RaiseOnChanged(new IncrementalUpdateInfo());
            ticker.RaiseChanged();
        }
Пример #21
0
        public void Update(IEnumerable <UpdateDataItem> items, OrderBookSides side)
        {
            foreach (var entry in items)
            {
                if (side == OrderBookSides.Buy)
                {
                    var updatedEntry = new OrderBookEntry(entry.Id, entry.Size, _bids[entry.Id].Price);

                    _bids.TryUpdate(entry.Id, updatedEntry, _bids[entry.Id]);
                }
                else if (side == OrderBookSides.Sell)
                {
                    var updatedEntry = new OrderBookEntry(entry.Id, entry.Size, _asks[entry.Id].Price);

                    _asks.TryUpdate(entry.Id, updatedEntry, _asks[entry.Id]);
                }
            }
        }
        bool OnUpdateOrderBook(Ticker ticker, byte[] bytes)
        {
            if (bytes == null)
            {
                return(false);
            }

            int startIndex = 0; // skip {

            List <string[]> items = JSonHelper.Default.DeserializeArrayOfObjects(bytes, ref startIndex, OrderBookItems);

            ticker.OrderBook.BeginUpdate();
            try {
                List <OrderBookEntry> bids  = ticker.OrderBook.Bids;
                List <OrderBookEntry> asks  = ticker.OrderBook.Asks;
                List <OrderBookEntry> iasks = ticker.OrderBook.AsksInverted;
                for (int i = 0; i < items.Count; i++)
                {
                    string[]       item  = items[i];
                    OrderBookEntry entry = new OrderBookEntry();
                    entry.Id           = FastValueConverter.ConvertPositiveLong(item[1]);
                    entry.ValueString  = item[4];
                    entry.AmountString = item[3];
                    if (item[2][0] == 'S')
                    {
                        if (iasks != null)
                        {
                            iasks.Add(entry);
                        }
                        asks.Insert(0, entry);
                    }
                    else
                    {
                        bids.Add(entry);
                    }
                }
            }
            finally {
                ticker.OrderBook.IsDirty = false;
                ticker.OrderBook.EndUpdate();
            }
            return(true);
        }
Пример #23
0
        public bool UpdateOrderBook(Ticker ticker, byte[] bytes, bool raiseChanged, int depth)
        {
            if (bytes == null)
            {
                return(false);
            }

            int startIndex = 0;

            List <string[]> items = JSonHelper.Default.DeserializeArrayOfArrays(bytes, ref startIndex, 3);

            ticker.OrderBook.GetNewBidAsks();
            int bidIndex = 0, askIndex = 0;
            List <OrderBookEntry> bids = ticker.OrderBook.Bids;
            List <OrderBookEntry> asks = ticker.OrderBook.Asks;

            foreach (string[] item in items)
            {
                OrderBookEntry entry = null;
                if (item[2][0] == '-')
                {
                    entry        = asks[askIndex];
                    entry.Amount = -FastValueConverter.Convert(item[2]);
                    askIndex++;
                }
                else
                {
                    entry = bids[bidIndex];
                    entry.AmountString = item[2];
                    bidIndex++;
                }
                entry.ValueString = item[0];

                if (bidIndex >= bids.Count || askIndex >= asks.Count)
                {
                    break;
                }
            }
            ticker.OrderBook.UpdateEntries();
            return(true);
        }
Пример #24
0
        public bool OnUpdateOrderBook(Ticker ticker, byte[] bytes, bool raiseChanged, int depth) {
            if(bytes == null)
                return false;

            int startIndex = 0;

            List<string[]> items = JSonHelper.Default.DeserializeArrayOfArrays(bytes, ref startIndex, 3);

            ticker.OrderBook.BeginUpdate();
            try {
                ticker.OrderBook.GetNewBidAsks();
                int bidIndex = 0, askIndex = 0;
                List<OrderBookEntry> bids = ticker.OrderBook.Bids;
                List<OrderBookEntry> asks = ticker.OrderBook.Asks;
                for(int i = 0; i < items.Count; i++) {
                    string[] item = items[i];
                    OrderBookEntry entry = null;
                    if(item[2][0] == '-') {
                        entry = asks[askIndex];
                        entry.Amount = -FastValueConverter.Convert(item[2]);
                        askIndex++;
                    }
                    else {
                        entry = bids[bidIndex];
                        entry.AmountString = item[2];
                        bidIndex++;
                    }
                    entry.ValueString = item[0];
                    if(bidIndex >= bids.Count || askIndex >= asks.Count)
                        break;
                }
            }
            finally {
                ticker.OrderBook.IsDirty = false;
                ticker.OrderBook.EndUpdate();
            }
            return true;
        }
Пример #25
0
        public void PrevLockAll()
        {
            foreach (string ticker in dc.TickerList)
            {
                SingleStockData sd = dataDict[ticker];

                FIXApi.OrderBookEntry entry = new OrderBookEntry();
                entry.strategies     = TradingStrategies.StockTrending;
                entry.action         = OrderAction.PrevLock;
                entry.type           = FIXApi.OrderType.CreditMarginSell;
                entry.ticker         = ticker;
                entry.quantityListed = sd.Quantity;

                entry.priceListed = Math.Round(sd.PrevClose * 1.098, 2);

                //entry.orderTime = sd.BuyTime;
                //entry.orderDate = sd.DateStamp;
                Thread orderThread = new Thread(new ParameterizedThreadStart(tc.OrderSender_StockTrending));
                orderThread.IsBackground = true;
                orderThread.Start(entry);
                Thread.Sleep(1000); //避免堵塞
            }
        }
Пример #26
0
        private static (decimal price, decimal above) GetBestCurrentPrice(OrderBook orderBook, OrderKind kind, decimal myCurPrice, decimal myVolume)
        {
            // Allowed cumulative volume percentage above our order
            const decimal allowAbove = 0.15m;

            decimal volumeAllowedAbove = myVolume * allowAbove;

            IReadOnlyList <OrderBookEntry> entries = kind == OrderKind.Buy ? orderBook.Bids : orderBook.Asks;

            int placeAbove = 0;

            while (true)
            {
                OrderBookEntry entry  = entries[placeAbove];
                decimal        volume = entry.Volume - (entry.Price == myCurPrice ? myVolume : 0);
                if (volume > volumeAllowedAbove)
                {
                    break;
                }

                placeAbove++;
                volumeAllowedAbove -= volume;
            }

            decimal price = entries[placeAbove].Price;

            if (kind == OrderKind.Buy)
            {
                price += 0.00001m;
            }
            else
            {
                price -= 0.00001m;
            }

            return(price, myVolume *allowAbove - volumeAllowedAbove);
        }
        bool UpdateOrderBook(Ticker ticker, byte[] bytes)
        {
            if (bytes == null)
            {
                return(false);
            }

            int startIndex = 0; // skip {

            List <string[]> items = JSonHelper.Default.DeserializeArrayOfObjects(bytes, ref startIndex, OrderBookItems);

            List <OrderBookEntry> bids  = ticker.OrderBook.Bids;
            List <OrderBookEntry> asks  = ticker.OrderBook.Asks;
            List <OrderBookEntry> iasks = ticker.OrderBook.AsksInverted;

            foreach (string[] item in items)
            {
                OrderBookEntry entry = new OrderBookEntry();

                entry.Id           = FastValueConverter.ConvertPositiveLong(item[1]);
                entry.ValueString  = item[4];
                entry.AmountString = item[3];

                if (item[2][0] == 'S')
                {
                    iasks.Add(entry);
                    asks.Insert(0, entry);
                }
                else
                {
                    bids.Add(entry);
                }
            }
            ticker.OrderBook.UpdateEntries();
            return(true);
        }
Пример #28
0
        internal void OnUpdateOrderBook(Ticker ticker, byte[] bytes)
        {
            int startIndex = 0;

            string[] updateId = JSonHelper.Default.StartDeserializeObject(bytes, ref startIndex, OrderBookStartItems);

            if (ticker.CaptureData)
            {
                ticker.CaptureDataCore(CaptureStreamType.OrderBook, CaptureMessageType.Snapshot, System.Text.ASCIIEncoding.Default.GetString(bytes));
            }

            const string bidString = "\"bids\":";
            const string askString = "\"asks\":";

            startIndex += bidString.Length + 1;
            List <string[]> jbids = JSonHelper.Default.DeserializeArrayOfArrays(bytes, ref startIndex, 2);

            startIndex += askString.Length + 1;
            List <string[]> jasks = JSonHelper.Default.DeserializeArrayOfArrays(bytes, ref startIndex, 2);

            ticker.OrderBook.BeginUpdate();
            try {
                List <OrderBookEntry> bids  = ticker.OrderBook.Bids;
                List <OrderBookEntry> asks  = ticker.OrderBook.Asks;
                List <OrderBookEntry> iasks = ticker.OrderBook.AsksInverted;

                bids.Clear();
                asks.Clear();
                if (iasks != null)
                {
                    iasks.Clear();
                }
                if (jbids != null)
                {
                    for (int i = 0; i < jbids.Count; i++)
                    {
                        string[] item = jbids[i];
                        bids.Add(new OrderBookEntry()
                        {
                            ValueString = item[0], AmountString = item[1]
                        });
                    }
                }
                if (jasks != null)
                {
                    for (int i = 0; i < jasks.Count; i++)
                    {
                        string[]       item = jasks[i];
                        OrderBookEntry e    = new OrderBookEntry()
                        {
                            ValueString = item[0], AmountString = item[1]
                        };
                        asks.Add(e);
                        if (iasks != null)
                        {
                            iasks.Insert(0, e);
                        }
                    }
                }
                ticker.OrderBook.Updates.Clear(FastValueConverter.ConvertPositiveLong(updateId[0]) + 1);
            }
            finally {
                ticker.OrderBook.IsDirty = false;
                ticker.OrderBook.EndUpdate();
            }
            ticker.RaiseChanged();
        }
Пример #29
0
        public bool UpdateArbitrageOrderBook(ExmoTicker ticker, int depth)
        {
            string text    = string.Empty;
            string address = string.Format("https://api.exmo.me/v1/order_book/?pair={0}", ticker.MarketName);

            try {
                text = GetDownloadString(address);
                if (text == null)
                {
                    return(false);
                }
            }
            catch (Exception) {
                return(false);
            }

            Dictionary <string, object> res = null;

            lock (JsonParser) {
                res = (Dictionary <string, object>)JsonParser.Parse(text);
            }

            res = (Dictionary <string, object>)res[ticker.MarketName];

            List <object> bids = (List <object>)res["bid"];
            List <object> asks = (List <object>)res["ask"];

            ticker.OrderBook.GetNewBidAsks();
            int index = 0;

            OrderBookEntry[] list = ticker.OrderBook.Bids;
            foreach (List <object> item in bids)
            {
                OrderBookEntry entry = list[index];
                entry.Value  = (decimal)(double.Parse((string)item.First()));
                entry.Amount = (decimal)(double.Parse((string)item.Last()));
                index++;
                if (index >= list.Length)
                {
                    break;
                }
            }
            index = 0;
            list  = ticker.OrderBook.Asks;
            foreach (List <object> item in asks)
            {
                OrderBookEntry entry = list[index];
                entry.Value  = (decimal)(double.Parse((string)item.First()));
                entry.Amount = (decimal)(double.Parse((string)item.Last()));
                index++;
                if (index >= list.Length)
                {
                    break;
                }
            }

            ticker.OrderBook.UpdateEntries();
            ticker.OrderBook.RaiseOnChanged(new OrderBookUpdateInfo()
            {
                Action = OrderBookUpdateType.RefreshAll
            });
            return(true);
        }
Пример #30
0
        //重载OnRecvDataMsg方法,接收行情数据
        // 请注意:
        //  1. 不要在这个函数里做耗时操作
        //  2. 只在这个函数里做数据获取工作 -- 将数据复制到其它数据缓存区,由其它线程做业务逻辑处理
        public override void OnRecvDataMsg(TDFMSG msg)
        {
            try
            {
                if (msg.MsgID == TDFMSGID.MSG_DATA_MARKET)
                {
                    //行情消息
                    TDFMarketData[] marketDataArr = msg.Data as TDFMarketData[];

                    foreach (TDFMarketData data in marketDataArr)
                    {
                        //if (data.Code.Contains("10000015"))
                        //    continue;
                        lock (this.dataDict)
                        {
                            if (dataDict.Keys.Contains(data.Code))
                            {
                                SingleStockData sd = dataDict[data.Code];

                                //数据获取部分
                                if (data.Match != 0)
                                {
                                    sd.LastPrice = (double)data.Match / 10000;     //最新成交价
                                }
                                sd.PrevClose    = (double)data.PreClose / 10000;
                                sd.AskPrices[0] = (double)data.AskPrice[0] / 10000;
                                sd.BidPrices[0] = (double)data.BidPrice[0] / 10000;

                                for (int i = 0; i < 10; i++)
                                {
                                    sd.BidPrices[i] = (double)data.BidPrice[i] / 10000;
                                    sd.AskPrices[i] = (double)data.AskPrice[i] / 10000;
                                    sd.BidVol[i]    = data.BidVol[i];
                                    sd.AskVol[i]    = data.AskVol[i];
                                }

                                if ((sd.ShortPriceListed != sd.AskPrices[0]) && (sd.StatusTrending == StrategyStatus.ShortListedOnly)) //最新卖一已变动,需改价重挂
                                {
                                    sd.bAskPriceChanged = true;                                                                        //测试,按卖五挂单
                                }
                                # region Fishing Strategies
                                //业务逻辑部分,只有对FishingStrategy这样时效要求极高的放在此处,其余均放入EngineClass
                                if (sd.StatusCBFishing != StrategyStatus.None)     //此ticker需要跑CBFishing Strategy
                                {
                                    if (sd.StatusCBFishing == StrategyStatus.New)  //首次挂买单,或上一轮结束后重新挂单
                                    {
                                        //sd.LongPriceListed = sd.BidPrices[0] - sd.CBBuyPriceOffset; //挂在卖五,后续可以参数化
                                        sd.LongPriceListed = sd.BidPrices[4];     //挂在卖五,后续可以参数化
                                        sd.StatusCBFishing = StrategyStatus.LongListedOnly;

                                        //下一步考虑在EngineClass或TradeClass中生成Order,只需有strategy和ticker,即可在dataDict中取到生成order所需数据
                                        FIXApi.OrderBookEntry entry = new OrderBookEntry();
                                        entry.strategies     = TradingStrategies.CBFishing;
                                        entry.action         = OrderAction.Buy;
                                        entry.type           = FIXApi.OrderType.CreditBuy;
                                        entry.ticker         = data.Code;
                                        entry.quantityListed = sd.Quantity;
                                        entry.priceListed    = sd.LongPriceListed;

                                        sd.StatusCBFishing = StrategyStatus.Pending;     //获得成交回报后再改变状态,避免重复执行
                                        Thread orderThread = new Thread(new ParameterizedThreadStart(tc.OrderSender_CBFishing));
                                        orderThread.IsBackground = true;
                                        orderThread.Start(entry);
                                    }
                                    else if (sd.StatusCBFishing == StrategyStatus.LongListedOnly)                               //买单已挂,根据最新价格检查是否需要撤单重挂
                                    {
                                        if ((sd.LongPriceListed >= sd.BidPrices[3]) || (sd.LongPriceListed <= sd.BidPrices[5])) //大于卖三或小于卖七时重挂
                                        {
                                            sd.LongPriceListed = sd.BidPrices[0] - sd.CBBuyPriceOffset;
                                            FIXApi.OrderBookEntry entry = new OrderBookEntry();
                                            entry.strategies     = TradingStrategies.CBFishing;
                                            entry.action         = OrderAction.CancelAndBuy;
                                            entry.type           = FIXApi.OrderType.CreditBuy;
                                            entry.ticker         = data.Code;
                                            entry.quantityListed = sd.Quantity;
                                            entry.priceListed    = sd.LongPriceListed;

                                            sd.StatusCBFishing = StrategyStatus.Pending;     //获得成交回报后再改变状态,避免重复执行
                                            Thread orderThread = new Thread(new ParameterizedThreadStart(tc.OrderSender_CBFishing));
                                            orderThread.IsBackground = true;
                                            orderThread.Start(entry);
                                        }
                                        //if ((sd.ShortPriceListed<data.AskPrice[4]) || (sd.ShortPriceListed>data.AskPrice[6]) ) //低于卖五或者高于卖七时撤单重挂,避免撤单过于频繁
                                        //    sd.ShortPriceListed = sd.AskPrices[4];
                                        ////cancel and resend
                                    }
                                    else if (sd.StatusCBFishing == StrategyStatus.ShortListedOnly)       //卖单已挂,根据最新价格检查是否需要撤单重挂
                                    {
                                        if (sd.ShortPriceListed > sd.AskPrices[0])
                                        {
                                            sd.ShortPriceListed = sd.AskPrices[0] - sd.CBSellPriceOffset;      //一直挂在比卖一低0.01的位置
                                            FIXApi.OrderBookEntry entry = new OrderBookEntry();
                                            entry.strategies     = TradingStrategies.CBFishing;
                                            entry.action         = OrderAction.CancelAndSell_CF;
                                            entry.type           = FIXApi.OrderType.CreditSell;
                                            entry.ticker         = data.Code;
                                            entry.quantityListed = sd.Quantity;
                                            entry.priceListed    = sd.ShortPriceListed;
                                            entry.strategies     = TradingStrategies.CBFishing;
                                            sd.StatusCBFishing   = StrategyStatus.Pending;   //获得成交回报后再改变状态,避免重复执行
                                            Thread orderThread = new Thread(new ParameterizedThreadStart(tc.OrderSender_CBFishing));
                                            orderThread.IsBackground = true;
                                            orderThread.Start(entry);
                                        }
                                        //if ((sd.ShortPriceListed<data.AskPrice[4]) || (sd.ShortPriceListed>data.AskPrice[6]) ) //低于卖五或者高于卖七时撤单重挂,避免撤单过于频繁
                                        //    sd.ShortPriceListed = sd.AskPrices[4];
                                        ////cancel and resend
                                    }
                                    else if (sd.StatusStockFishing != StrategyStatus.None)     //此ticker需要跑StockFishing Strategy
                                    {
                                    }
                                }
                                # endregion
                            }
                        }
                    }
                    //极其耗时,轻易不要打开
                    //RecvDataReport(this, null);
                }
                else if (msg.MsgID == TDFMSGID.MSG_DATA_FUTURE)
                {
                    //期货行情消息
                    TDFFutureData[] futureDataArr = msg.Data as TDFFutureData[];
                    foreach (TDFFutureData data in futureDataArr)
                    {
                        ;
                    }
                    return;
                }
                else if (msg.MsgID == TDFMSGID.MSG_DATA_INDEX)
                {
                    //指数消息
                    TDFIndexData[] indexDataArr = msg.Data as TDFIndexData[];
                    foreach (TDFIndexData data in indexDataArr)
                    {
                        return;
                    }
                }
                else if (msg.MsgID == TDFMSGID.MSG_DATA_TRANSACTION)
                {
                    //逐笔成交
                    TDFTransaction[] transactionDataArr = msg.Data as TDFTransaction[];
                    foreach (TDFTransaction data in transactionDataArr)
                    {
                        //每一data变量包含最底层的一笔逐笔成交数据
                        lock (this.dataDict)
                        {
                            if (dataDict.Keys.Contains(data.Code))
                            {
                                //数据获取部分
                                int timeStamp = Convert.ToInt32((double)data.Time / 1000 - 0.5); //去掉毫秒部分;

                                if (timeStamp == 93524)
                                {
                                    timeStamp = 93524;
                                }

                                int direction = 0;
                                if (data.BSFlag == 66)
                                {
                                    direction = 1;
                                }
                                else if (data.BSFlag == 83)
                                {
                                    direction = -1;
                                }
                                int    volume = data.Volume;
                                double price  = (double)data.Price / 10000;

                                if (dataDict[data.Code].zbDataList.Count == 0) //第一次添加
                                {
                                    ZBTickData zbdata = new ZBTickData();
                                    zbdata.timeStamp = timeStamp;

                                    if (direction == 1)
                                    {
                                        zbdata.volumeB     = volume;
                                        zbdata.priceTotalB = price;
                                        zbdata.countB      = 1;
                                        zbdata.priceB      = zbdata.priceTotalB / (double)zbdata.countB;//计算该秒、买方向的平均价格
                                    }
                                    else if (direction == -1)
                                    {
                                        zbdata.volumeS     = volume;
                                        zbdata.priceTotalS = price;
                                        zbdata.countS      = 1;
                                        zbdata.priceS      = zbdata.priceTotalS / (double)zbdata.countS;//计算该秒、买方向的平均价格
                                    }

                                    if ((zbdata.priceB > 0) && (zbdata.priceS > 0))
                                    {
                                        zbdata.price = (zbdata.priceB + zbdata.priceS) / 2;
                                    }
                                    else
                                    {
                                        zbdata.price = (zbdata.priceB + zbdata.priceS);
                                    }
                                    zbdata.volume = zbdata.volumeB + zbdata.volumeS;

                                    if ((zbdata.volume == 0) || (zbdata.price == 0))
                                    {
                                        continue;                                             //空记录
                                    }
                                    dataDict[data.Code].zbDataList.Add(zbdata);

                                    dataDict[data.Code].ZBFirstIndex = 0;
                                    dataDict[data.Code].ZBLastIndex  = 0;
                                }
                                else
                                {
                                    int currLastIndex = dataDict[data.Code].ZBLastIndex;

                                    if (dataDict[data.Code].zbDataList[currLastIndex].timeStamp == timeStamp) //同一时间戳存在,只需更新价格与成交量,不需插入新纪录
                                    {
                                        ZBTickData zbdata = dataDict[data.Code].zbDataList[currLastIndex];    //取出字典中的元素并进行修改,由于是引用,对zbdata的修改会自动在字典中更新

                                        if (direction == 1)
                                        {
                                            zbdata.priceTotalB = zbdata.priceTotalB + price;
                                            zbdata.countB      = zbdata.countB + 1;
                                            zbdata.priceB      = zbdata.priceTotalB / (double)zbdata.countB;//计算该秒、该方向的平均价格
                                            zbdata.volumeB     = zbdata.volumeB + volume;
                                        }
                                        else if (direction == -1)
                                        {
                                            zbdata.priceTotalS = zbdata.priceTotalS + price;
                                            zbdata.countS      = zbdata.countS + 1;
                                            zbdata.priceS      = zbdata.priceTotalS / (double)zbdata.countS;//计算该秒、该方向的平均价格
                                            zbdata.volumeS     = zbdata.volumeS + volume;
                                        }

                                        if ((zbdata.priceB > 0) && (zbdata.priceS > 0))
                                        {
                                            zbdata.price = (zbdata.priceB + zbdata.priceS) / 2;
                                        }
                                        else
                                        {
                                            zbdata.price = (zbdata.priceB + zbdata.priceS);
                                        }
                                        zbdata.volume = zbdata.volumeB + zbdata.volumeS;

                                        dataDict[data.Code].zbDataList.RemoveAt(currLastIndex);
                                        dataDict[data.Code].zbDataList.Add(zbdata);
                                    }
                                    else //不存在此时间戳,需添加新纪录
                                    {
                                        ZBTickData zbdata = new ZBTickData();
                                        zbdata.timeStamp = timeStamp;

                                        if (direction == 1)
                                        {
                                            zbdata.volumeB     = volume;
                                            zbdata.priceTotalB = price;
                                            zbdata.countB      = 1;
                                            zbdata.priceB      = zbdata.priceTotalB / (double)zbdata.countB;//计算该秒、买方向的平均价格
                                        }
                                        else if (direction == -1)
                                        {
                                            zbdata.volumeS     = volume;
                                            zbdata.priceTotalS = price;
                                            zbdata.countS      = 1;
                                            zbdata.priceS      = zbdata.priceTotalS / (double)zbdata.countS;//计算该秒、买方向的平均价格
                                        }

                                        if ((zbdata.priceB > 0) && (zbdata.priceS > 0))
                                        {
                                            zbdata.price = (zbdata.priceB + zbdata.priceS) / 2;
                                        }
                                        else
                                        {
                                            zbdata.price = (zbdata.priceB + zbdata.priceS);
                                        }
                                        zbdata.volume = zbdata.volumeB + zbdata.volumeS;

                                        //dataDict[data.Code].totalVolTillNow += zbdata.volume;
                                        if ((zbdata.volume == 0) || (zbdata.price == 0))
                                        {
                                            continue;                                             //空记录
                                        }
                                        dataDict[data.Code].zbDataList.Add(zbdata);

                                        dataDict[data.Code].ZBLastIndex = dataDict[data.Code].ZBLastIndex + 1;
                                    }
                                }

                                /*
                                 * //数据获取部分
                                 * ZBTickData zbdata = new ZBTickData();
                                 * zbdata.timeStamp = Convert.ToInt32((double)data.Time / 1000); //去掉毫秒部分
                                 *
                                 * //if (zbdata.timeStamp > 93850) { int i = 0; i++; }
                                 *
                                 * zbdata.price = (double)data.Price / 10000;
                                 * if (data.BSFlag == 66)
                                 *  zbdata.direction = 1;
                                 * else if (data.BSFlag == 83)
                                 *  zbdata.direction = -1;
                                 * else
                                 *  zbdata.direction = 0;
                                 * zbdata.volume = data.Volume;
                                 * dataDict[data.Code].totalVolTillNow += zbdata.volume;
                                 *
                                 * dataDict[data.Code].zbDataList.Add(zbdata);
                                 *
                                 * if (dataDict[data.Code].zbDataList.Count == 1) //第一次添加
                                 * {
                                 *  dataDict[data.Code].ZBFirstIndex = 0;
                                 *  dataDict[data.Code].ZBLastIndex = 0;
                                 * }
                                 * else
                                 * {
                                 *  dataDict[data.Code].ZBLastIndex = dataDict[data.Code].ZBLastIndex + 1;
                                 * }
                                 */
                            }
                        }
                        //极其耗时,轻易不要打开
                        //RecvDataReport(this, null);
                    }
                }
                else if (msg.MsgID == TDFMSGID.MSG_DATA_ORDER)
                {
                    //逐笔委托
                    TDFOrder[] orderDataArr = msg.Data as TDFOrder[];
                    foreach (TDFOrder data in orderDataArr)
                    {
                        return;
                    }
                }
                else if (msg.MsgID == TDFMSGID.MSG_DATA_ORDERQUEUE)
                {
                    //委托队列
                    TDFOrderQueue[] orderQueueArr = msg.Data as TDFOrderQueue[];
                    foreach (TDFOrderQueue data in orderQueueArr)
                    {
                        return;
                    }
                }
            }