private ExchangeOrderResult ParseOrder(string orderId, JToken order) { ExchangeOrderResult orderResult = new ExchangeOrderResult { OrderId = orderId }; switch (order["status"].ToStringInvariant()) { case "pending": orderResult.Result = ExchangeAPIOrderResult.Pending; break; case "open": orderResult.Result = ExchangeAPIOrderResult.FilledPartially; break; case "closed": orderResult.Result = ExchangeAPIOrderResult.Filled; break; case "canceled": case "expired": orderResult.Result = ExchangeAPIOrderResult.Canceled; break; default: orderResult.Result = ExchangeAPIOrderResult.Error; break; } orderResult.Message = (orderResult.Message ?? order["reason"].ToStringInvariant()); orderResult.OrderDate = CryptoUtility.UnixTimeStampToDateTimeSeconds(order["opentm"].ConvertInvariant <double>()); orderResult.Symbol = order["descr"]["pair"].ToStringInvariant(); orderResult.IsBuy = (order["descr"]["type"].ToStringInvariant() == "buy"); orderResult.Amount = order["vol"].ConvertInvariant <decimal>(); orderResult.AmountFilled = order["vol_exec"].ConvertInvariant <decimal>(); orderResult.Price = order["descr"]["price"].ConvertInvariant <decimal>(); orderResult.AveragePrice = order["price"].ConvertInvariant <decimal>(); return(orderResult); }
/// <summary> /// Get market candles /// </summary> /// <param name="exchange">Exchange name</param> /// <param name="marketName">Market name</param> /// <param name="before">Optional date to restrict data to before this date</param> /// <param name="after">Optional date to restrict data to after this date</param> /// <param name="periods">Periods</param> /// <returns>Market candles</returns> public async Task <IEnumerable <MarketCandle> > GetMarketCandlesAsync(string exchange, string marketName, DateTime?before, DateTime?after, params int[] periods) { await new SynchronizationContextRemover(); List <MarketCandle> candles = new List <MarketCandle>(); string periodString = string.Join(",", periods); string beforeDateString = (before == null ? string.Empty : "&before=" + (long)before.Value.UnixTimestampFromDateTimeSeconds()); string afterDateString = (after == null ? string.Empty : "&after=" + (long)after.Value.UnixTimestampFromDateTimeSeconds()); string url = "/markets/" + exchange + "/" + marketName + "/ohlc?periods=" + periodString + beforeDateString + afterDateString; JToken token = await MakeCryptowatchRequestAsync(url); foreach (JProperty prop in token) { foreach (JArray array in prop.Value) { candles.Add(new MarketCandle { ExchangeName = exchange, Name = marketName, ClosePrice = array[4].ConvertInvariant <decimal>(), Timestamp = CryptoUtility.UnixTimeStampToDateTimeSeconds(array[0].ConvertInvariant <long>()), HighPrice = array[2].ConvertInvariant <decimal>(), LowPrice = array[3].ConvertInvariant <decimal>(), OpenPrice = array[1].ConvertInvariant <decimal>(), PeriodSeconds = prop.Name.ConvertInvariant <int>(), BaseVolume = array[5].ConvertInvariant <decimal>(), ConvertedVolume = array[5].ConvertInvariant <decimal>() * array[4].ConvertInvariant <decimal>() }); } } return(candles); }
protected override async Task <IEnumerable <MarketCandle> > OnGetCandlesAsync(string symbol, int periodSeconds, DateTime?startDate = null, DateTime?endDate = null, int?limit = null) { //if (limit != null) throw new APIException("Limit parameter not supported"); Really? You want to throw an exception instead of ignoring the parm? List <MarketCandle> candles = new List <MarketCandle>(); endDate = endDate ?? DateTime.UtcNow; startDate = startDate ?? endDate.Value.Subtract(TimeSpan.FromDays(1.0)); //[time, low, high, open, close, volume], ["1505984400","14209.92500000","14209.92500000","14209.92500000","14209.92500000","0.001"] JToken obj = await MakeJsonRequestAsync <JToken>("/products/" + symbol + "/candles?granularity=" + periodSeconds + "&start=" + ((DateTime)startDate).ToString("o") + "&end=" + ((DateTime)endDate).ToString("o")); if (obj.HasValues) { foreach (JArray array in obj) { candles.Add(new MarketCandle() { ExchangeName = this.Name, Name = symbol, Timestamp = CryptoUtility.UnixTimeStampToDateTimeSeconds(array[0].ConvertInvariant <long>()), PeriodSeconds = periodSeconds, LowPrice = array[1].ConvertInvariant <decimal>(), HighPrice = array[2].ConvertInvariant <decimal>(), OpenPrice = array[3].ConvertInvariant <decimal>(), ClosePrice = array[4].ConvertInvariant <decimal>(), ConvertedVolume = array[5].ConvertInvariant <decimal>(), BaseVolume = array[4].ConvertInvariant <decimal>() }); } } return(candles); }
protected override async Task <IEnumerable <MarketCandle> > OnGetCandlesAsync(string symbol, int periodSeconds, DateTime?startDate = null, DateTime?endDate = null, int?limit = null) { /* * { * "status": "ok", * "ch": "market.btcusdt.kline.1day", * "ts": 1499223904680, * “data”: [ * { * "id": 1499184000, * "amount": 37593.0266, * "count": 0, * "open": 1935.2000, * "close": 1879.0000, * "low": 1856.0000, * "high": 1940.0000, * "vol": 71031537.97866500 * }, */ List <MarketCandle> candles = new List <MarketCandle>(); symbol = NormalizeSymbol(symbol); string url = "/market/history/kline?symbol=" + symbol; if (limit != null) { // default is 150, max: 2000 url += "&size=" + (limit.Value.ToStringInvariant()); } string periodString = CryptoUtility.SecondsToPeriodStringLong(periodSeconds); url += "&period=" + periodString; JToken allCandles = await MakeJsonRequestAsync <JToken>(url, BaseUrl, null); var ts = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(allCandles.Parent.Parent["ts"].ConvertInvariant <long>()); foreach (var array in allCandles) { candles.Add(new MarketCandle { ClosePrice = array["close"].ConvertInvariant <decimal>(), ExchangeName = Name, HighPrice = array["high"].ConvertInvariant <decimal>(), LowPrice = array["low"].ConvertInvariant <decimal>(), Name = symbol, OpenPrice = array["open"].ConvertInvariant <decimal>(), PeriodSeconds = periodSeconds, Timestamp = CryptoUtility.UnixTimeStampToDateTimeSeconds(array["id"].ConvertInvariant <long>()), BaseVolume = array["vol"].ConvertInvariant <decimal>() / array["close"].ConvertInvariant <decimal>(), ConvertedVolume = array["vol"].ConvertInvariant <decimal>(), WeightedAverage = 0m }); } candles.Reverse(); return(candles); }
protected override async Task OnGetHistoricalTradesAsync(Func <IEnumerable <ExchangeTrade>, bool> callback, string symbol, DateTime?startDate = null, DateTime?endDate = null) { symbol = NormalizeSymbol(symbol); string baseUrl = "/0/public/Trades?pair=" + symbol; string url; DateTime timestamp; List <ExchangeTrade> trades = new List <ExchangeTrade>(); while (true) { url = baseUrl; if (startDate != null) { url += "&since=" + (long)(CryptoUtility.UnixTimestampFromDateTimeMilliseconds(startDate.Value) * 1000000.0); } JToken result = await MakeJsonRequestAsync <JToken>(url); if (result == null) { break; } JArray outerArray = result[symbol] as JArray; if (outerArray == null || outerArray.Count == 0) { break; } if (startDate != null) { startDate = CryptoUtility.UnixTimeStampToDateTimeMilliseconds(result["last"].ConvertInvariant <double>() / 1000000.0d); } foreach (JArray array in outerArray.Children <JArray>()) { timestamp = CryptoUtility.UnixTimeStampToDateTimeSeconds(array[2].ConvertInvariant <double>()); trades.Add(new ExchangeTrade { Amount = array[1].ConvertInvariant <decimal>(), Price = array[0].ConvertInvariant <decimal>(), Timestamp = timestamp, Id = timestamp.Ticks, IsBuy = array[3].ConvertInvariant <char>() == 'b' }); } trades.Sort((t1, t2) => t1.Timestamp.CompareTo(t2.Timestamp)); if (!callback(trades)) { break; } trades.Clear(); if (startDate == null) { break; } Task.Delay(1000).Wait(); } }
private ExchangeTrade ParseTrade(JToken token) { // [ {"time": 1409935047,"id": 99451,"price": 350,"quantity": 2.85714285, "type": "BUY" }, ... ] return(new ExchangeTrade() { Timestamp = CryptoUtility.UnixTimeStampToDateTimeSeconds(token["time"].ConvertInvariant <long>()), Id = token["id"].ConvertInvariant <long>(), Price = token["price"].ConvertInvariant <decimal>(), Amount = token["quantity"].ConvertInvariant <decimal>(), IsBuy = token["type"].ToStringInvariant().Equals("BUY") }); }
protected override async Task <IEnumerable <MarketCandle> > OnGetCandlesAsync(string symbol, int periodSeconds, DateTime?startDate = null, DateTime?endDate = null, int?limit = null) { if (limit != null) { throw new APIException("Limit parameter not supported"); } // /products/<product-id>/candles // https://api.gdax.com/products/LTC-BTC/candles?granularity=86400&start=2017-12-04T18:15:33&end=2017-12-11T18:15:33 List <MarketCandle> candles = new List <MarketCandle>(); symbol = NormalizeSymbol(symbol); string url = "/products/" + symbol + "/candles?granularity=" + periodSeconds; if (startDate == null) { startDate = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1.0)); } url += "&start=" + startDate.Value.ToString("s", System.Globalization.CultureInfo.InvariantCulture); if (endDate == null) { endDate = DateTime.UtcNow; } url += "&end=" + endDate.Value.ToString("s", System.Globalization.CultureInfo.InvariantCulture); // time, low, high, open, close, volume JToken token = await MakeJsonRequestAsync <JToken>(url); foreach (JArray candle in token) { decimal volume = candle[5].ConvertInvariant <decimal>(); decimal close = candle[4].ConvertInvariant <decimal>(); candles.Add(new MarketCandle { ClosePrice = close, ExchangeName = Name, HighPrice = candle[2].ConvertInvariant <decimal>(), LowPrice = candle[1].ConvertInvariant <decimal>(), Name = symbol, OpenPrice = candle[3].ConvertInvariant <decimal>(), PeriodSeconds = periodSeconds, Timestamp = CryptoUtility.UnixTimeStampToDateTimeSeconds(candle[0].ConvertInvariant <long>()), BaseVolume = volume, ConvertedVolume = ((decimal)volume * close) }); } // re-sort in ascending order candles.Sort((c1, c2) => c1.Timestamp.CompareTo(c2.Timestamp)); return(candles); }
protected override async Task <IEnumerable <MarketCandle> > OnGetCandlesAsync(string symbol, int periodSeconds, DateTime?startDate = null, DateTime?endDate = null, int?limit = null) { if (limit != null) { throw new APIException("Limit parameter not supported"); } // https://api.kraken.com/0/public/OHLC // pair = asset pair to get OHLC data for, interval = time frame interval in minutes(optional):, 1(default), 5, 15, 30, 60, 240, 1440, 10080, 21600, since = return committed OHLC data since given id(optional.exclusive) // array of array entries(<time>, <open>, <high>, <low>, <close>, <vwap>, <volume>, <count>) symbol = NormalizeSymbol(symbol); startDate = startDate ?? DateTime.UtcNow.Subtract(TimeSpan.FromDays(1.0)); endDate = endDate ?? DateTime.UtcNow; JToken json = await MakeJsonRequestAsync <JToken>("/0/public/OHLC?pair=" + symbol + "&interval=" + periodSeconds / 60 + "&since=" + startDate); List <MarketCandle> candles = new List <MarketCandle>(); if (json.Children().Count() != 0) { JProperty prop = json.Children().First() as JProperty; foreach (JArray jsonCandle in prop.Value) { MarketCandle candle = new MarketCandle { ClosePrice = jsonCandle[4].ConvertInvariant <decimal>(), ExchangeName = Name, HighPrice = jsonCandle[2].ConvertInvariant <decimal>(), LowPrice = jsonCandle[3].ConvertInvariant <decimal>(), Name = symbol, OpenPrice = jsonCandle[1].ConvertInvariant <decimal>(), PeriodSeconds = periodSeconds, Timestamp = CryptoUtility.UnixTimeStampToDateTimeSeconds(jsonCandle[0].ConvertInvariant <long>()), BaseVolume = jsonCandle[6].ConvertInvariant <decimal>(), ConvertedVolume = jsonCandle[6].ConvertInvariant <decimal>() * jsonCandle[4].ConvertInvariant <decimal>(), WeightedAverage = jsonCandle[5].ConvertInvariant <decimal>() }; if (candle.Timestamp >= startDate.Value && candle.Timestamp <= endDate.Value) { candles.Add(candle); } } } return(candles); }
protected override async Task OnGetHistoricalTradesAsync(Func <IEnumerable <ExchangeTrade>, bool> callback, string symbol, DateTime?startDate = null, DateTime?endDate = null) { // [{"date": "1513387997", "tid": "33734815", "price": "0.01724547", "type": "1", "amount": "5.56481714"}] symbol = NormalizeSymbol(symbol); JToken token = await MakeBitstampRequestAsync("/transactions/" + symbol); List <ExchangeTrade> trades = new List <ExchangeTrade>(); foreach (JToken trade in token) { trades.Add(new ExchangeTrade { Amount = trade["amount"].ConvertInvariant <decimal>(), Id = trade["tid"].ConvertInvariant <long>(), IsBuy = trade["type"].ToStringInvariant() == "0", Price = trade["price"].ConvertInvariant <decimal>(), Timestamp = CryptoUtility.UnixTimeStampToDateTimeSeconds(trade["date"].ConvertInvariant <long>()) }); } callback(trades); }
protected override async Task <ExchangeTicker> OnGetTickerAsync(string symbol) { // {"high": "0.10948945", "last": "0.10121817", "timestamp": "1513387486", "bid": "0.10112165", "vwap": "0.09958913", "volume": "9954.37332614", "low": "0.09100000", "ask": "0.10198408", "open": "0.10250028"} symbol = NormalizeSymbol(symbol); JToken token = await MakeBitstampRequestAsync("/ticker/" + symbol); return(new ExchangeTicker { Ask = token["ask"].ConvertInvariant <decimal>(), Bid = token["bid"].ConvertInvariant <decimal>(), Last = token["last"].ConvertInvariant <decimal>(), Volume = new ExchangeVolume { BaseVolume = token["volume"].ConvertInvariant <decimal>(), BaseSymbol = symbol, ConvertedVolume = token["volume"].ConvertInvariant <decimal>() * token["last"].ConvertInvariant <decimal>(), ConvertedSymbol = symbol, Timestamp = CryptoUtility.UnixTimeStampToDateTimeSeconds(token["timestamp"].ConvertInvariant <long>()) } }); }
private ExchangeTicker ParseTicker(string symbol, JToken data) { //{"date":"1518043621","ticker":{"high":"0.01878000","vol":"1911074.97335534","last":"0.01817627","low":"0.01813515","buy":"0.01817626","sell":"0.01823447"}} JToken ticker = data["ticker"]; decimal last = ticker["last"].ConvertInvariant <decimal>(); decimal vol = ticker["vol"].ConvertInvariant <decimal>(); return(new ExchangeTicker { Ask = ticker["sell"].ConvertInvariant <decimal>(), Bid = ticker["buy"].ConvertInvariant <decimal>(), Last = last, Volume = new ExchangeVolume { BaseVolume = vol, BaseSymbol = symbol, ConvertedVolume = vol * last, ConvertedSymbol = symbol, Timestamp = CryptoUtility.UnixTimeStampToDateTimeSeconds(data["date"].ConvertInvariant <long>()) } }); }
public static void CreateBinFileFromCSVFiles(string outputFile, params string[] inputFiles) { unsafe { Trade trade = new Trade(); byte[] bytes = new byte[16]; fixed(byte *ptr = bytes) { foreach (string file in inputFiles) { using (StreamReader reader = new StreamReader(file, CryptoUtility.UTF8EncodingNoPrefix)) using (Stream writer = File.Create(outputFile)) { string line; string[] lines; DateTime dt; while ((line = reader.ReadLine()) != null) { lines = line.Split(','); if (lines.Length == 3) { dt = CryptoUtility.UnixTimeStampToDateTimeSeconds(double.Parse(lines[0])); trade.Ticks = (long)CryptoUtility.UnixTimestampFromDateTimeMilliseconds(dt); trade.Price = float.Parse(lines[1]); trade.Amount = float.Parse(lines[2]); if (trade.Amount > 0.01f && trade.Price > 0.5f) { *(Trade *)ptr = trade; writer.Write(bytes, 0, bytes.Length); } } } } } } } }