コード例 #1
0
        public static async Task <List <string> > GetTopMarketsByBVwithETHdelta(int n)
        {
            MarketSummary markets = await BtrexREST.GetMarketSummary();

            Dictionary <string, decimal> topMarketsBTC = new Dictionary <string, decimal>();
            List <string> topMarketsETH = new List <string>();

            foreach (SummaryResult market in markets.result)
            {
                string mkbase = market.MarketName.Split('-')[0];
                if (mkbase == "BTC")
                {
                    topMarketsBTC.Add(market.MarketName, market.BaseVolume);
                }
                else if (mkbase == "ETH")
                {
                    topMarketsETH.Add(market.MarketName.Split('-')[1]);
                }
            }

            List <string> mks = new List <string>();

            foreach (KeyValuePair <string, decimal> mk in topMarketsBTC.OrderByDescending(x => x.Value).Take(n))
            {
                string coin = mk.Key.Split('-')[1];
                if (topMarketsETH.Contains(coin))
                {
                    mks.Add(coin);
                }
            }

            Trace.WriteLine(string.Format("Markets: {0}", mks.Count));
            return(mks);
        }
コード例 #2
0
        private async Task <GetOrderResult> CancelOrderGetData(string UniqueID, string OrderID)
        {
            //CANCEL ORDER:
            var cancelRequest = await BtrexREST.CancelLimitOrder(OrderID);

            if (!cancelRequest.success)
            {
                Trace.WriteLine("    !!!!ERR CANCEL-ORDER>>> " + UniqueID + ": " + cancelRequest.message);
                return(null);
            }

            //Get data from cancelled order:
            var canceledOrderData = new GetOrderResponse();

            do
            {
                canceledOrderData = await BtrexREST.GetOrder(OrderID);

                if (!canceledOrderData.success)
                {
                    Trace.WriteLine("    !!!!ERR GET-CANCELED-ORDDATA>>> " + UniqueID + ": " + canceledOrderData.message);
                }
            }while (canceledOrderData.result == null || canceledOrderData.result.IsOpen == false);

            return(canceledOrderData.result);
        }
コード例 #3
0
        public async Task ExecuteStopLoss(StopLoss stopLoss)
        {
            if (!stopLoss.virtualSL)
            {
                var lowestRate = minimumTradeSatoshis / stopLoss.Quantity;
                LimitOrderResponse orderResp = await BtrexREST.PlaceLimitOrder(stopLoss.MarketDelta, "sell", stopLoss.Quantity, lowestRate);

                if (!orderResp.success)
                {
                    Trace.WriteLine(string.Format("    !!!!ERR ExecuteStopLoss-PLACE-ORDER1>> " + orderResp.message));
                    Trace.WriteLine(string.Format("        QTY: {1} ... STOP-LOSS RATE: {2}", stopLoss.Quantity, stopLoss.StopRate));

                    //REDUNTANT (FAILSAFE) CALL ON INITIAL CALL FAILURE
                    orderResp = await BtrexREST.PlaceLimitOrder(stopLoss.MarketDelta, "sell", stopLoss.Quantity, lowestRate);

                    if (!orderResp.success)
                    {
                        Trace.WriteLine("    !!!!ERR ExecuteStopLoss-PLACE-ORDER1.2ndTry>> " + orderResp.message);
                        Trace.WriteLine(string.Format("        QTY: {1} ... STOP-LOSS RATE: {2}", stopLoss.Quantity, stopLoss.StopRate));
                        return;
                    }
                }

                Thread.Sleep(1500);

                var order = await BtrexREST.GetOrder(orderResp.result.uuid);

                if (!order.success)
                {
                    Trace.WriteLine("    !!!!ERR ExecuteStopLoss-GET-ORDER: " + order.message);
                }

                stopLoss.ExecutionCallback(order.result, stopLoss.CandlePeriod);
            }
            else
            {
                var vSell = new GetOrderResult()
                {
                    Exchange     = stopLoss.MarketDelta,
                    Quantity     = stopLoss.Quantity,
                    PricePerUnit = BtrexData.Markets[stopLoss.MarketDelta].TradeHistory.RecentFills.Last().Rate * 0.9975M,
                    Closed       = DateTime.UtcNow
                };

                stopLoss.ExecutionCallback(vSell, stopLoss.CandlePeriod);
            }
        }
コード例 #4
0
        public async Task ExecuteNewOrder(NewOrder ord)
        {
            Trace.WriteLine(string.Format("%%%%PLACING ORDER1: {0} {1} ... QTY: {2} ... RATE: {3} ", ord.BUYorSELL, ord.MarketDelta, ord.Qty, ord.Rate));

            //PLACE INITIAL ORDER:
            var orderResp = await BtrexREST.PlaceLimitOrder(ord.MarketDelta, ord.BUYorSELL, ord.Qty, ord.Rate);

            if (!orderResp.success)
            {
                orderResp = await BtrexREST.PlaceLimitOrder2(ord.MarketDelta, ord.BUYorSELL, ord.Qty, ord.Rate);

                if (!orderResp.success)
                {
                    Trace.WriteLine("    !!!!ERR ExecuteNewOrder-PLACE-ORDER1>> " + orderResp.message);
                    Trace.WriteLine(string.Format("{0} {3} QTY: {1} ...  RATE: {2}", ord.MarketDelta, ord.Qty, ord.Rate, ord.BUYorSELL));
                    return;
                }
            }

            //Wait for server processing time and then call order data:
            Thread.Sleep(1000);
            var getOrder1 = await BtrexREST.GetOrder(orderResp.result.uuid);

            if (!getOrder1.success)
            {
                Trace.WriteLine("    !!!!ERR ExecuteNewOrder-GET-ORDER1: " + getOrder1.message);
            }

            var totalQty      = 0M;
            var totalReserved = 0M;

            if (getOrder1.result.Type.ToUpper() == "LIMIT_SELL")
            {
                totalQty      = getOrder1.result.Quantity;
                totalReserved = getOrder1.result.Price;
            }
            else if (getOrder1.result.Type.ToUpper() == "LIMIT_BUY")
            {
                totalReserved = getOrder1.result.Reserved;
                totalQty      = getOrder1.result.Quantity - getOrder1.result.QuantityRemaining;
            }

            //Enter Order Data into Dictionary
            var order = new OpenOrder(getOrder1.result, totalQty, totalReserved, ord.DataUpdateCallback, ord.ExecutionCompleteCallback, ord.CandlePeriod);

            RegisterOpenOrder(order, ord.UniqueID);
        }
コード例 #5
0
        public static async Task <List <string> > GetTopMarketsByBVbtcOnly(int n)
        {
            MarketSummary markets = await BtrexREST.GetMarketSummary();

            Dictionary <string, decimal> topMarketsBTC = new Dictionary <string, decimal>();

            foreach (SummaryResult market in markets.result)
            {
                string mkbase = market.MarketName.Split('-')[0];
                if (mkbase == "BTC")
                {
                    topMarketsBTC.Add(market.MarketName, market.BaseVolume);
                }
            }

            List <string> mks = new List <string>();

            foreach (KeyValuePair <string, decimal> mk in topMarketsBTC.OrderByDescending(x => x.Value).Take(n))
            {
                mks.Add(mk.Key.Split('-')[1]);
            }

            return(mks);
        }
コード例 #6
0
        private async Task ProcessOrders()
        {
            while (true)
            {
                if (OpenOrders.Count == 0)
                {
                    Thread.Sleep(LoopFrequency);
                    continue;
                }

                foreach (var order in OpenOrders.ToList())
                {
                    //Call Order Data:
                    var getOrder2 = await BtrexREST.GetOrder(order.Value.OrderUuid);

                    if (!getOrder2.success)
                    {
                        Trace.WriteLine("    !!!!ERR ExecuteNewOrder-GET-ORDER2: " + getOrder2.message);
                    }


                    //CHECK IF COMPLETED OR UPDATED, CALL CALLBACKS:
                    if (!getOrder2.result.IsOpen)
                    {
                        //Remove from Dictionary and call ExeCallback:
                        RemoveNewOrder(order.Key);
                        order.Value.CompleteOrder(getOrder2.result);

                        continue;
                    }
                    else if (getOrder2.result.QuantityRemaining != order.Value.QuantityRemaining)
                    {
                        //Update OpenOrder in Dict and Call DataCallback
                        OpenOrders[order.Key].UpdateOrder(getOrder2.result);
                    }


                    //BUY AND SELL LOGIC FOR STILL-OPEN ORDERS:
                    if (DateTime.UtcNow - order.Value.Opened > NewOrderWaitTime)
                    {
                        if (order.Value.Type == "LIMIT_BUY" && BtrexData.Markets[order.Value.Exchange].OrderBook.Bids.OrderByDescending(a => a.Key).First().Key > order.Value.Limit)
                        {
                            //CANCEL ORDER, GET DATA:
                            var canceledOrderData = await CancelOrderGetData(order.Key, order.Value.OrderUuid);

                            if (canceledOrderData == null)
                            {
                                continue;
                            }

                            //QTY MUST BE ADJUSTED SO THAT 'TotalReserved' BTC AMT REAMINS EQUAL
                            var satoshisRemaining = order.Value.Reserved - order.Value.Price;
                            var newRate           = BtrexData.Markets[canceledOrderData.Exchange].OrderBook.Bids.OrderByDescending(a => a.Key).First().Key;
                            var newQty            = satoshisRemaining / (newRate * 1.0025M);

                            //MAKE SURE REMAINING AMOUNT IS STILL ABOVE MIN SATOSHIS
                            if (newQty * newRate < minimumTradeSatoshis)
                            {
                                //ORDER IS COMPLETE, CALL EXE CALLBACK
                                RemoveNewOrder(order.Key);
                                order.Value.CompleteOrder(canceledOrderData);
                                continue;
                            }

                            //REPLACE ORDER
                            var order2 = await BtrexREST.PlaceLimitOrder2(canceledOrderData.Exchange, "BUY", newQty, newRate);

                            if (!order2.success)
                            {
                                Trace.WriteLine("    !!!!ERR PLACE-ORDER2>>> " + order.Key + ": " + order2.message);
                                continue;
                            }

                            //GET REPLACED ORDER DATA
                            var order2data = new GetOrderResponse();
                            do
                            {
                                order2data = await BtrexREST.GetOrder(order2.result.uuid);

                                if (!order2data.success)
                                {
                                    Trace.WriteLine("    !!!!ERR GET-ORD2DATA>>> " + order.Key + ": " + order2data.message);
                                }
                            }while (order2data.result == null || order2data.result.IsOpen == false);

                            //CHECK IsOpen, IF false THEN EXE CALLBACK
                            if (!order2data.result.IsOpen)
                            {
                                //ORDER IS COMPLETE, CALL EXE CALLBACK
                                RemoveNewOrder(order.Key);
                                order.Value.CompleteOrder(canceledOrderData);
                                continue;
                            }

                            //UPDATE DATA BY COMBINING CANCELED-ORDDATA AND ORDER2DATA
                            OpenOrders[order.Key].ReplaceOrder(canceledOrderData, order2data.result);
                        }
                        else if (order.Value.Type == "LIMIT_SELL" && BtrexData.Markets[order.Value.Exchange].OrderBook.Asks.OrderBy(a => a.Key).First().Key < order.Value.Limit)
                        {
                            //CANCEL ORDER, GET DATA:
                            var canceledOrderData = await CancelOrderGetData(order.Key, order.Value.OrderUuid);

                            if (canceledOrderData == null)
                            {
                                continue;
                            }

                            //MAKE SURE REMAINING AMOUNT IS STILL ABOVE MIN SATOSHIS
                            var highestAsk = BtrexData.Markets[canceledOrderData.Exchange].OrderBook.Asks.OrderBy(a => a.Key).First().Key;
                            var satoshis   = canceledOrderData.QuantityRemaining * (highestAsk * 0.9975M);
                            if (satoshis < minimumTradeSatoshis)
                            {
                                //ORDER IS COMPLETE, CALL EXE CALLBACK
                                RemoveNewOrder(order.Key);
                                order.Value.CompleteOrder(canceledOrderData);
                                continue;
                            }

                            //REPLACE ORDER
                            var order2 = await BtrexREST.PlaceLimitOrder2(canceledOrderData.Exchange, "SELL", canceledOrderData.QuantityRemaining, BtrexData.Markets[canceledOrderData.Exchange].OrderBook.Asks.OrderBy(a => a.Key).First().Key);

                            if (!order2.success)
                            {
                                Trace.WriteLine("    !!!!ERR PLACE-ORDER2>>> " + order.Key + ": " + order2.message);
                                continue;
                            }

                            //GET REPLACED ORDER DATA
                            var order2data = new GetOrderResponse();
                            do
                            {
                                order2data = await BtrexREST.GetOrder(order2.result.uuid);

                                if (!order2data.success)
                                {
                                    Trace.WriteLine("    !!!!ERR GET-ORD2DATA>>> " + order.Key + ": " + order2data.message);
                                }
                            }while (order2data.result == null || order2data.result.IsOpen == false);

                            //CHECK IsOpen, IF false THEN EXE CALLBACK
                            if (!order2data.result.IsOpen)
                            {
                                //ORDER IS COMPLETE, CALL EXE CALLBACK
                                RemoveNewOrder(order.Key);
                                order.Value.CompleteOrder(canceledOrderData);
                                continue;
                            }

                            //UPDATE DATA BY COMBINING CANCELED-ORDDATA AND ORDER2DATA
                            OpenOrders[order.Key].ReplaceOrder(canceledOrderData, order2data.result);
                        }
                    }
                }

                Thread.Sleep(LoopFrequency);
            }

            Trace.WriteLine("\r\n\r\n    @@@ TradeControl-Thread STOPPED @@@\r\n\r\n");
        }