Skip to content

add FTX.US and trade stream to FTX #721

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/ExchangeSharp/API/Exchanges/BitMEX/ExchangeBitMEXAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ protected override Task<IWebSocket> OnGetTradesWebSocketAsync(Func<KeyValuePair<
foreach (var t in data)
{
var marketSymbol = t["symbol"].ToStringInvariant();
await callback(new KeyValuePair<string, ExchangeTrade>(marketSymbol, t.ParseTrade("size", "price", "side", "timestamp", TimestampType.Iso8601, "trdMatchID")));
await callback(new KeyValuePair<string, ExchangeTrade>(marketSymbol, t.ParseTrade("size", "price", "side", "timestamp", TimestampType.Iso8601UTC, "trdMatchID")));
}
}, async (_socket) =>
{
Expand Down Expand Up @@ -426,7 +426,7 @@ protected override async Task<IEnumerable<MarketCandle>> OnGetCandlesAsync(strin
var obj = await MakeJsonRequestAsync<JToken>(url);
foreach (var t in obj)
{
candles.Add(this.ParseCandle(t, marketSymbol, periodSeconds, "open", "high", "low", "close", "timestamp", TimestampType.Iso8601, "volume", "turnover", "vwap"));
candles.Add(this.ParseCandle(t, marketSymbol, periodSeconds, "open", "high", "low", "close", "timestamp", TimestampType.Iso8601UTC, "volume", "turnover", "vwap"));
}
candles.Reverse();

Expand Down Expand Up @@ -468,7 +468,7 @@ public async Task<IEnumerable<ExchangeTrade>> GetHistoricalTradesAsync(
var obj = await MakeJsonRequestAsync<JToken>(url);
foreach (var t in obj)
{
trades.Add(t.ParseTrade("size", "price", "side", "timestamp", TimestampType.Iso8601, "trdMatchID"));
trades.Add(t.ParseTrade("size", "price", "side", "timestamp", TimestampType.Iso8601UTC, "trdMatchID"));
}

return trades;
Expand Down Expand Up @@ -709,7 +709,7 @@ private ExchangePosition ParsePosition(JToken token)
LiquidationPrice = token["liquidationPrice"].ConvertInvariant<decimal>(),
Leverage = token["leverage"].ConvertInvariant<decimal>(),
LastPrice = token["lastPrice"].ConvertInvariant<decimal>(),
TimeStamp = CryptoUtility.ParseTimestamp(token["currentTimestamp"], TimestampType.Iso8601)
TimeStamp = CryptoUtility.ParseTimestamp(token["currentTimestamp"], TimestampType.Iso8601UTC)
};
return result;
}
Expand Down
67 changes: 62 additions & 5 deletions src/ExchangeSharp/API/Exchanges/Bithumb/ExchangeBithumbAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The above copyright notice and this permission notice shall be included in all c

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Newtonsoft.Json.Linq;
Expand All @@ -21,6 +22,8 @@ namespace ExchangeSharp
public sealed partial class ExchangeBithumbAPI : ExchangeAPI
{
public override string BaseUrl { get; set; } = "https://api.bithumb.com";
public override string BaseUrlWebSocket { get; set; } = "wss://pubwss.bithumb.com/pub/ws";


private ExchangeBithumbAPI()
{
Expand Down Expand Up @@ -112,15 +115,16 @@ protected override (string baseCurrency, string quoteCurrency) OnSplitMarketSymb
protected override async Task<IEnumerable<string>> OnGetMarketSymbolsAsync()
{
List<string> marketSymbols = new List<string>();
string marketSymbol = "all";
string marketSymbol = "all_BTC";
var data = await MakeRequestBithumbAsync(marketSymbol, "/public/ticker/$SYMBOL$");
foreach (JProperty token in data.Item1)
{
if (token.Name != "date")
{
marketSymbols.Add(token.Name);
}
}
marketSymbols.Add($"{token.Name}_KRW");
if (token.Name != "BTC") marketSymbols.Add($"{token.Name}_BTC");
}
}
return marketSymbols;
}

Expand Down Expand Up @@ -169,7 +173,60 @@ protected override async Task<IEnumerable<KeyValuePair<string, ExchangeOrderBook
}
return books;
}
}

protected override async Task<IWebSocket> OnGetTradesWebSocketAsync(Func<KeyValuePair<string, ExchangeTrade>, Task> callback, params string[] marketSymbols)
{
/*
{
"type" : "transaction",
"content" : {
"list" : [
{
"symbol" : "BTC_KRW", // currency code
"buySellGb" : "1", // Execution type (1: sell execution, 2: buy execution)
"contPrice" : "10579000", // Execution price
"contQty" : "0.01", // contract quantity
"contAmt" : "105790.00", // Execution amount
"contDtm" : "2020-01-29 12:24:18.830039", // Execution time
"updn" : "dn" // Compare with the previous price: up-up, dn-down
}
]
}
}
*/
if (marketSymbols == null || marketSymbols.Length == 0)
{
marketSymbols = (await GetMarketSymbolsAsync(true)).ToArray();
}
return await ConnectPublicWebSocketAsync(null, messageCallback: async (_socket, msg) =>
{
JToken parsedMsg = JToken.Parse(msg.ToStringFromUTF8());
if (parsedMsg["status"].ToStringInvariant().Equals("0000"))
return; // either "Connected Successfully" or "Filter Registered Successfully"
else if (parsedMsg["status"].ToStringInvariant().Equals("5100"))
{
Logger.Error("Error in exchange {0} OnGetTradesWebSocketAsync(): {1}", Name, parsedMsg["resmsg"].ToStringInvariant());
return;
}
else if (parsedMsg["type"].ToStringInvariant().Equals("transaction"))
{
foreach (var data in parsedMsg["content"]["list"])
{
var exchangeTrade = data.ParseTrade("contQty", "contPrice", "buySellGb", "contDtm", TimestampType.Iso8601UTC, null, typeKeyIsBuyValue: "2");

await callback(new KeyValuePair<string, ExchangeTrade>(parsedMsg["market"].ToStringInvariant(), exchangeTrade));
}
}
}, connectCallback: async (_socket) =>
{
await _socket.SendMessageAsync(new
{
type = "transaction",
symbols = marketSymbols,
});
});
}
}

public partial class ExchangeName { public const string Bithumb = "Bithumb"; }
}
8 changes: 4 additions & 4 deletions src/ExchangeSharp/API/Exchanges/Bittrex/ExchangeBittrexAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ protected override async Task<ExchangeTicker> OnGetTickerAsync(string marketSymb
{
JToken ticker = await MakeJsonRequestAsync<JToken>("/markets/" + marketSymbol + "/ticker");
//NOTE: Bittrex uses the term "BaseVolume" when referring to the QuoteCurrencyVolume
return await this.ParseTickerAsync(ticker, marketSymbol, "askRate", "bidRate", "lastTradeRate", "volume", "quoteVolume", "updatedAt", TimestampType.Iso8601);
return await this.ParseTickerAsync(ticker, marketSymbol, "askRate", "bidRate", "lastTradeRate", "volume", "quoteVolume", "updatedAt", TimestampType.Iso8601UTC);
}

protected override async Task<IEnumerable<KeyValuePair<string, ExchangeTicker>>> OnGetTickersAsync()
Expand All @@ -241,7 +241,7 @@ protected override async Task<IEnumerable<KeyValuePair<string, ExchangeTicker>>>
foreach (JToken ticker in tickers)
{
marketSymbol = ticker["symbol"].ToStringInvariant();
ExchangeTicker tickerObj = await this.ParseTickerAsync(ticker, marketSymbol, "askRate", "bidRate", "lastTradeRate", "volume", "quoteVolume", "updatedAt", TimestampType.Iso8601);
ExchangeTicker tickerObj = await this.ParseTickerAsync(ticker, marketSymbol, "askRate", "bidRate", "lastTradeRate", "volume", "quoteVolume", "updatedAt", TimestampType.Iso8601UTC);
tickerList.Add(new KeyValuePair<string, ExchangeTicker>(marketSymbol, tickerObj));
}
return tickerList;
Expand Down Expand Up @@ -319,7 +319,7 @@ protected override async Task<IEnumerable<ExchangeTrade>> OnGetRecentTradesAsync
JToken array = await MakeJsonRequestAsync<JToken>(baseUrl);
foreach (JToken token in array)
{
trades.Add(token.ParseTrade("quantity", "rate", "takerSide", "executedAt", TimestampType.Iso8601, "id"));
trades.Add(token.ParseTrade("quantity", "rate", "takerSide", "executedAt", TimestampType.Iso8601UTC, "id"));
}
return trades;
}
Expand Down Expand Up @@ -488,7 +488,7 @@ protected override async Task<IEnumerable<MarketCandle>> OnGetCandlesAsync(strin
{
//NOTE: Bittrex uses the term "BaseVolume" when referring to the QuoteCurrencyVolume
MarketCandle candle = this.ParseCandle(token: jsonCandle, marketSymbol: marketSymbol, periodSeconds: periodSeconds,
openKey: "open", highKey: "high", lowKey: "low", closeKey: "close", timestampKey: "startsAt", timestampType: TimestampType.Iso8601,
openKey: "open", highKey: "high", lowKey: "low", closeKey: "close", timestampKey: "startsAt", timestampType: TimestampType.Iso8601UTC,
baseVolumeKey: "volume", quoteVolumeKey: "quoteVolume");
if (startDate != null && endDate != null)
{
Expand Down
4 changes: 2 additions & 2 deletions src/ExchangeSharp/API/Exchanges/Bybit/ExchangeBybitAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ protected override async Task<IWebSocket> OnGetTradesWebSocketAsync(Func<KeyValu
priceKey: "price",
typeKey: "side",
timestampKey: "timestamp",
timestampType: TimestampType.Iso8601,
timestampType: TimestampType.Iso8601UTC,
idKey: "trade_id");
await callback(new KeyValuePair<string, ExchangeTrade>(dataRow["symbol"].ToStringInvariant(), trade));
}
Expand Down Expand Up @@ -927,7 +927,7 @@ private ExchangePosition ParsePosition(JToken token)
AveragePrice = token["entry_price"].ConvertInvariant<decimal>(),
LiquidationPrice = token["liq_price"].ConvertInvariant<decimal>(),
Leverage = token["effective_leverage"].ConvertInvariant<decimal>(),
TimeStamp = CryptoUtility.ParseTimestamp(token["updated_at"], TimestampType.Iso8601)
TimeStamp = CryptoUtility.ParseTimestamp(token["updated_at"], TimestampType.Iso8601UTC)
};
if (token["side"].ToStringInvariant() == "Sell")
result.Amount *= -1;
Expand Down
10 changes: 5 additions & 5 deletions src/ExchangeSharp/API/Exchanges/Coinbase/ExchangeCoinbaseAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ protected override async Task<IReadOnlyDictionary<string, ExchangeCurrency>> OnG
protected override async Task<ExchangeTicker> OnGetTickerAsync(string marketSymbol)
{
JToken ticker = await MakeJsonRequestAsync<JToken>("/products/" + marketSymbol + "/ticker");
return await this.ParseTickerAsync(ticker, marketSymbol, "ask", "bid", "price", "volume", null, "time", TimestampType.Iso8601);
return await this.ParseTickerAsync(ticker, marketSymbol, "ask", "bid", "price", "volume", null, "time", TimestampType.Iso8601UTC);
}

protected override async Task<ExchangeDepositDetails> OnGetDepositAddressAsync(string symbol, bool forceRegenerate = false)
Expand Down Expand Up @@ -375,7 +375,7 @@ protected override async Task<IWebSocket> OnGetTickersWebSocketAsync(Action<IRea
JToken token = JToken.Parse(msg.ToStringFromUTF8());
if (token["type"].ToStringInvariant() == "ticker")
{
ExchangeTicker ticker = await this.ParseTickerAsync(token, token["product_id"].ToStringInvariant(), "best_ask", "best_bid", "price", "volume_24h", null, "time", TimestampType.Iso8601);
ExchangeTicker ticker = await this.ParseTickerAsync(token, token["product_id"].ToStringInvariant(), "best_ask", "best_bid", "price", "volume_24h", null, "time", TimestampType.Iso8601UTC);
callback(new List<KeyValuePair<string, ExchangeTicker>>() { new KeyValuePair<string, ExchangeTicker>(token["product_id"].ToStringInvariant(), ticker) });
}
}, async (_socket) =>
Expand Down Expand Up @@ -438,7 +438,7 @@ protected override async Task<IWebSocket> OnGetTradesWebSocketAsync(Func<KeyValu

private ExchangeTrade ParseTradeWebSocket(JToken token)
{
return token.ParseTradeCoinbase("size", "price", "side", "time", TimestampType.Iso8601, "trade_id");
return token.ParseTradeCoinbase("size", "price", "side", "time", TimestampType.Iso8601UTC, "trade_id");
}

protected override async Task<IWebSocket> OnUserDataWebSocketAsync(Action<object> callback)
Expand Down Expand Up @@ -556,7 +556,7 @@ protected override async Task OnGetHistoricalTradesAsync(Func<IEnumerable<Exchan
{
Callback = callback,
EndDate = endDate,
ParseFunction = (JToken token) => token.ParseTrade("size", "price", "side", "time", TimestampType.Iso8601, "trade_id"),
ParseFunction = (JToken token) => token.ParseTrade("size", "price", "side", "time", TimestampType.Iso8601UTC, "trade_id"),
StartDate = startDate,
MarketSymbol = marketSymbol,
Url = "/products/[marketSymbol]/trades",
Expand All @@ -578,7 +578,7 @@ protected override async Task<IEnumerable<ExchangeTrade>> OnGetRecentTradesAsync
List<ExchangeTrade> tradeList = new List<ExchangeTrade>();
foreach (JToken trade in trades)
{
tradeList.Add(trade.ParseTrade("size", "price", "side", "time", TimestampType.Iso8601, "trade_id"));
tradeList.Add(trade.ParseTrade("size", "price", "side", "time", TimestampType.Iso8601UTC, "trade_id"));
}
return tradeList;
}
Expand Down
Loading