Beispiel #1
0
        protected override async Task <IEnumerable <ExchangeOrderResult> > OnGetOpenOrderDetailsAsync(string symbol = null)
        {
            List <ExchangeOrderResult> orders = new List <ExchangeOrderResult>();
            // { "SELL": [{ "oid": "59e59b279bd8d31d093d956e", "type": "SELL", "userOid": null, "coinType": "KCS", "coinTypePair": "BTC", "direction": "SELL","price": 0.1,"dealAmount": 0,"pendingAmount": 100, "createdAt": 1508219688000, "updatedAt": 1508219688000 } ... ],
            //   "BUY":  [{ "oid": "59e42bf09bd8d374c9956caa", "type": "BUY",  "userOid": null, "coinType": "KCS", "coinTypePair": "BTC", "direction": "BUY", "price": 0.00009727,"dealAmount": 31.14503, "pendingAmount": 16.94827, "createdAt": 1508125681000, "updatedAt": 1508125681000 } ... ]
            var payload = await OnGetNoncePayloadAsync();

            if (symbol != null)
            {
                payload["symbol"] = symbol;
            }

            JToken token = await MakeJsonRequestAsync <JToken>("/order/active-map?" + CryptoUtility.GetFormForPayload(payload, false), null, payload);

            if (token != null && token.HasValues)
            {
                foreach (JToken order in token["BUY"])
                {
                    orders.Add(ParseOpenOrder(order));
                }
                foreach (JToken order in token["SELL"])
                {
                    orders.Add(ParseOpenOrder(order));
                }
            }
            return(orders);
        }
Beispiel #2
0
        protected override async Task ProcessRequestAsync(HttpWebRequest request, Dictionary <string, object> payload)
        {
            if (CanMakeAuthenticatedRequest(payload))
            {
                request.Headers.Add("KC-API-KEY", PublicApiKey.ToUnsecureString());
                request.Headers.Add("KC-API-NONCE", payload["nonce"].ToStringInvariant());

                var endpoint = request.RequestUri.AbsolutePath;
                var message  = string.Format("{0}/{1}/{2}", endpoint, payload["nonce"], CryptoUtility.GetFormForPayload(payload, false));
                var sig      = CryptoUtility.SHA256Sign(Convert.ToBase64String(Encoding.UTF8.GetBytes(message)), PrivateApiKey.ToUnsecureString());

                request.Headers.Add("KC-API-SIGNATURE", sig);

                if (request.Method == "POST")
                {
                    string msg = CryptoUtility.GetFormForPayload(payload, false);
                    using (Stream stream = await request.GetRequestStreamAsync())
                    {
                        byte[] content = Encoding.UTF8.GetBytes(msg);
                        stream.Write(content, 0, content.Length);
                    }
                }
            }
        }
        protected override async Task <IEnumerable <ExchangeTransaction> > OnGetDepositHistoryAsync(string symbol)
        {
            symbol = NormalizeSymbol(symbol);
            List <ExchangeTransaction> deposits = new List <ExchangeTransaction>();

            var payload = await OnGetNoncePayloadAsync();

            payload.Add("start", DateTime.UtcNow.AddYears(-1).UnixTimestampFromDateTimeMilliseconds()); // required. Arbitrarily going with 1 year
            payload.Add("end", DateTime.UtcNow.UnixTimestampFromDateTimeMilliseconds());                // also required
            payload.Add("types", "DEPOSIT,WITHDRAWAL");                                                 // opting to return both deposits and withdraws.

            // We can also include trades and orders with this call (which makes 3 ways to return the same data)
            JToken token = await MakeJsonRequestAsync <JToken>("/exchange/payment/history/transactions?" + CryptoUtility.GetFormForPayload(payload, false), null, await OnGetNoncePayloadAsync());

            foreach (JToken tx in token)
            {
                deposits.Add(ParseTransaction(tx));
            }

            return(deposits);
        }
Beispiel #4
0
        /// <summary>
        /// This is a private call on Kucoin and therefore requires an API Key + API Secret. Calling this without authorization will cause an exception
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="periodSeconds"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        protected override async Task <IEnumerable <MarketCandle> > OnGetCandlesAsync(string symbol, int periodSeconds, DateTime?startDate = null, DateTime?endDate = null, int?limit = null)
        {
            List <MarketCandle> candles = new List <MarketCandle>();

            string periodString;

            if (periodSeconds <= 60)
            {
                periodString = "1"; periodSeconds = 60;
            }
            else if (periodSeconds <= 300)
            {
                periodString = "5"; periodSeconds = 300;
            }
            else if (periodSeconds <= 900)
            {
                periodString = "15"; periodSeconds = 900;
            }
            else if (periodSeconds <= 1800)
            {
                periodString = "30"; periodSeconds = 1800;
            }
            else if (periodSeconds <= 3600)
            {
                periodString = "60"; periodSeconds = 3600;
            }
            else if (periodSeconds <= 86400)
            {
                periodString = "D"; periodSeconds = 86400;
            }
            else
            {
                periodString = "W"; periodSeconds = 604800;
            }

            endDate   = endDate ?? DateTime.UtcNow;
            startDate = startDate ?? DateTime.UtcNow.AddDays(-1);

            // this is a little tricky. The call is private, but not a POST. We need the payload for the sig, but also for the uri
            // so, we'll do both... This is the only ExchangeAPI public call (private on Kucoin) like this.
            var payload = await OnGetNoncePayloadAsync();

            payload.Add("symbol", symbol);
            payload.Add("resolution", periodString);
            payload.Add("from", (long)startDate.Value.UnixTimestampFromDateTimeSeconds());        // the nonce is milliseconds, this is seconds without decimal
            payload.Add("to", (long)endDate.Value.UnixTimestampFromDateTimeSeconds());            // the nonce is milliseconds, this is seconds without decimal
            var addPayload = CryptoUtility.GetFormForPayload(payload, false);

            // The results of this Kucoin API call are also a mess. 6 different arrays (c,t,v,h,l,o) with the index of each shared for the candle values
            // It doesn't use their standard error format...
            JToken token = await MakeJsonRequestAsync <JToken>("/open/chart/history?" + addPayload, null, payload);

            if (token != null && token.HasValues && token["s"].ToStringInvariant() == "ok")
            {
                int childCount = token["c"].Count();
                for (int i = 0; i < childCount; i++)
                {
                    candles.Add(new MarketCandle
                    {
                        ExchangeName    = this.Name,
                        Name            = symbol,
                        PeriodSeconds   = periodSeconds,
                        Timestamp       = DateTimeOffset.FromUnixTimeSeconds(token["t"][i].ConvertInvariant <long>()).DateTime,
                        ClosePrice      = token["c"][i].ConvertInvariant <decimal>(),
                        HighPrice       = token["h"][i].ConvertInvariant <decimal>(),
                        LowPrice        = token["l"][i].ConvertInvariant <decimal>(),
                        OpenPrice       = token["o"][i].ConvertInvariant <decimal>(),
                        ConvertedVolume = token["v"][i].ConvertInvariant <decimal>(),
                        BaseVolume      = token["v"][i].ConvertInvariant <decimal>() * token["c"][i].ConvertInvariant <decimal>()
                    });
                }
            }
            return(candles);
        }
        /// <summary>
        /// Limited to the last 100 open orders
        /// </summary>
        /// <param name="symbol"></param>
        /// <returns></returns>
        protected override async Task <IEnumerable <ExchangeOrderResult> > OnGetOpenOrderDetailsAsync(string symbol = null)
        {
            symbol = NormalizeSymbol(symbol);
            List <ExchangeOrderResult> orders = new List <ExchangeOrderResult>();
            var payload = await OnGetNoncePayloadAsync();

            payload.Add("openClosed", "OPEM");
            if (symbol != null)
            {
                payload.Add("currencyPair", symbol);
            }

            JToken token = await MakeJsonRequestAsync <JToken>("/exchange/client_orders?" + CryptoUtility.GetFormForPayload(payload, false), null, await OnGetNoncePayloadAsync());

            foreach (JToken order in token)
            {
                orders.Add(ParseClientOrder(order));
            }
            return(orders);
        }
        protected override async Task <IEnumerable <ExchangeOrderResult> > OnGetCompletedOrderDetailsAsync(string symbol = null, DateTime?afterDate = null)
        {
            symbol = NormalizeSymbol(symbol);
            // We can increase the number of orders returned by including a limit parameter if desired
            List <ExchangeOrderResult> orders = new List <ExchangeOrderResult>();
            var payload = await OnGetNoncePayloadAsync();

            payload.Add("openClosed", "CLOSED");   // returns both closed and cancelled
            if (symbol != null)
            {
                payload.Add("currencyPair", symbol);
            }
            if (afterDate != null)
            {
                payload.Add("issuedFrom", ((DateTime)afterDate).UnixTimestampFromDateTimeMilliseconds());
            }

            JToken token = await MakeJsonRequestAsync <JToken>("/exchange/client_orders?" + CryptoUtility.GetFormForPayload(payload, false), null, await OnGetNoncePayloadAsync());

            foreach (JToken order in token)
            {
                orders.Add(ParseClientOrder(order));
            }
            return(orders);
        }
 /// <summary>
 /// Update the trade info via API
 /// </summary>
 public void Update()
 {
     Ticker       = ExchangeInfo.API.GetTicker(Symbol);
     RecentTrades = ExchangeInfo.API.GetRecentTrades(Symbol).ToArray();
     if (RecentTrades.Length == 0)
     {
         Trade = new Trade();
     }
     else
     {
         Trade = new Trade {
             Amount = (float)RecentTrades[RecentTrades.Length - 1].Amount, Price = (float)RecentTrades[RecentTrades.Length - 1].Price, Ticks = (long)CryptoUtility.UnixTimestampFromDateTimeMilliseconds(RecentTrades[RecentTrades.Length - 1].Timestamp)
         };
     }
     Orders = ExchangeInfo.API.GetOrderBook(Symbol);
 }
 /// <summary>
 /// Return a rounded amount if needed
 /// </summary>
 /// <returns>Rounded amount or amount if no rounding is needed</returns>
 public decimal RoundAmount()
 {
     return(ShouldRoundAmount ? CryptoUtility.RoundAmount(Amount) : Amount);
 }
Beispiel #9
0
        protected override IWebSocket OnGetTickersWebSocket(Action <IReadOnlyCollection <KeyValuePair <string, ExchangeTicker> > > callback)
        {
            if (callback == null)
            {
                return(null);
            }

            void innerCallback(string json)
            {
                #region sample json

                /*
                 * {
                 *  Nonce : int,
                 *  Deltas :
                 *  [
                 *      {
                 *          MarketName     : string,
                 *          High           : decimal,
                 *          Low            : decimal,
                 *          Volume         : decimal,
                 *          Last           : decimal,
                 *          BaseVolume     : decimal,
                 *          TimeStamp      : date,
                 *          Bid            : decimal,
                 *          Ask            : decimal,
                 *          OpenBuyOrders  : int,
                 *          OpenSellOrders : int,
                 *          PrevDay        : decimal,
                 *          Created        : date
                 *      }
                 *  ]
                 * }
                 */
                #endregion

                var    freshTickers = new Dictionary <string, ExchangeTicker>(StringComparer.OrdinalIgnoreCase);
                JToken token        = JToken.Parse(json);
                token = token["D"];
                foreach (JToken ticker in token)
                {
                    string   marketName = ticker["M"].ToStringInvariant();
                    decimal  last       = ticker["l"].ConvertInvariant <decimal>();
                    decimal  ask        = ticker["A"].ConvertInvariant <decimal>();
                    decimal  bid        = ticker["B"].ConvertInvariant <decimal>();
                    decimal  volume     = ticker["V"].ConvertInvariant <decimal>();
                    decimal  baseVolume = ticker["m"].ConvertInvariant <decimal>();
                    DateTime timestamp  = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(ticker["T"].ConvertInvariant <long>());
                    var      t          = new ExchangeTicker
                    {
                        Ask    = ask,
                        Bid    = bid,
                        Last   = last,
                        Volume = new ExchangeVolume
                        {
                            ConvertedVolume = volume,
                            ConvertedSymbol = marketName.Split('-')[0],
                            BaseVolume      = baseVolume,
                            BaseSymbol      = marketName.Split('-')[1],
                            Timestamp       = timestamp
                        }
                    };
                    freshTickers[marketName] = t;
                }
                callback(freshTickers);
            }

            var client = SocketManager;
            return(client.SubscribeToSummaryDeltas(innerCallback));
        }