@@ -11,17 +11,186 @@ The above copyright notice and this permission notice shall be included in all c
1111*/
1212
1313using ExchangeSharp . OKGroup ;
14+ using Newtonsoft . Json . Linq ;
15+ using System ;
16+ using System . Collections . Generic ;
17+ using System . Threading . Tasks ;
1418
1519namespace ExchangeSharp
1620{
17- public sealed partial class ExchangeOKExAPI : OKGroupCommon
21+ public sealed partial class ExchangeOKExAPI : OKGroupCommon
1822 {
19- public override string BaseUrl { get ; set ; } = "https://www.okex.com/api/v1" ;
23+ public override string BaseUrl { get ; set ; } = "https://www.okex.com/api/v1" ;
2024 public override string BaseUrlV2 { get ; set ; } = "https://www.okex.com/v2/spot" ;
2125 public override string BaseUrlV3 { get ; set ; } = "https://www.okex.com/api" ;
22- public override string BaseUrlWebSocket { get ; set ; } = "wss://real.okex.com:8443/ws/v3" ;
26+ public override string BaseUrlWebSocket { get ; set ; } = "wss://real.okex.com:8443/ws/v3" ;
27+ public string BaseUrlV5 { get ; set ; } = "https://okex.com/api/v5" ;
2328 protected override bool IsFuturesAndSwapEnabled { get ; } = true ;
29+
30+ protected internal override async Task < IEnumerable < ExchangeMarket > > OnGetMarketSymbolsMetadataAsync ( )
31+ {
32+ /*
33+ {
34+ "code":"0",
35+ "msg":"",
36+ "data":[
37+ {
38+ "instType":"SWAP",
39+ "instId":"LTC-USD-SWAP",
40+ "uly":"LTC-USD",
41+ "category":"1",
42+ "baseCcy":"",
43+ "quoteCcy":"",
44+ "settleCcy":"LTC",
45+ "ctVal":"10",
46+ "ctMult":"1",
47+ "ctValCcy":"USD",
48+ "optType":"C",
49+ "stk":"",
50+ "listTime":"1597026383085",
51+ "expTime":"1597026383085",
52+ "lever":"10",
53+ "tickSz":"0.01",
54+ "lotSz":"1",
55+ "minSz":"1",
56+ "ctType":"linear",
57+ "alias":"this_week",
58+ "state":"live"
59+ },
60+ ...
61+ ]
62+ }
63+ */
64+ List < ExchangeMarket > markets = new List < ExchangeMarket > ( ) ;
65+ parseMarketSymbolTokens ( await MakeJsonRequestAsync < JToken > (
66+ "/public/instruments?instType=SPOT" , BaseUrlV5 ) ) ;
67+ if ( IsFuturesAndSwapEnabled )
68+ {
69+ parseMarketSymbolTokens ( await MakeJsonRequestAsync < JToken > (
70+ "/public/instruments?instType=FUTURES" , BaseUrlV5 ) ) ;
71+ parseMarketSymbolTokens ( await MakeJsonRequestAsync < JToken > (
72+ "/public/instruments?instType=SWAP" , BaseUrlV5 ) ) ;
73+ }
74+ void parseMarketSymbolTokens ( JToken allMarketSymbolTokens )
75+ {
76+ foreach ( JToken marketSymbolToken in allMarketSymbolTokens )
77+ {
78+ var isSpot = marketSymbolToken [ "instType" ] . Value < string > ( ) == "SPOT" ;
79+ var baseCurrency = isSpot
80+ ? marketSymbolToken [ "baseCcy" ] . Value < string > ( )
81+ : marketSymbolToken [ "settleCcy" ] . Value < string > ( ) ;
82+ var quoteCurrency = isSpot
83+ ? marketSymbolToken [ "quoteCcy" ] . Value < string > ( )
84+ : marketSymbolToken [ "ctValCcy" ] . Value < string > ( ) ;
85+ var market = new ExchangeMarket
86+ {
87+ MarketSymbol = marketSymbolToken [ "instId" ] . Value < string > ( ) ,
88+ IsActive = marketSymbolToken [ "state" ] . Value < string > ( ) == "live" ,
89+ QuoteCurrency = quoteCurrency ,
90+ BaseCurrency = baseCurrency ,
91+ PriceStepSize = marketSymbolToken [ "tickSz" ] . ConvertInvariant < decimal > ( ) ,
92+ MinPrice = marketSymbolToken [ "tickSz" ] . ConvertInvariant < decimal > ( ) , // assuming that this is also the min price since it isn't provided explicitly by the exchange
93+ MinTradeSize = marketSymbolToken [ "minSz" ] . ConvertInvariant < decimal > ( ) ,
94+ QuantityStepSize = marketSymbolToken [ "lotSz" ] . ConvertInvariant < decimal > ( ) ,
95+ } ;
96+ markets . Add ( market ) ;
97+ }
98+ }
99+
100+ return markets ;
101+ }
102+
103+ protected override async Task < ExchangeTicker > OnGetTickerAsync ( string marketSymbol )
104+ {
105+ var tickerResponse = await MakeJsonRequestAsync < JToken > ( $ "/market/ticker?instId={ marketSymbol } ", BaseUrlV5 ) ;
106+ var symbol = tickerResponse [ "instId" ] . Value < string > ( ) ;
107+ return await ParseTickerV5Async ( tickerResponse , symbol ) ;
108+ }
109+
110+ protected override async Task < IEnumerable < KeyValuePair < string , ExchangeTicker > > > OnGetTickersAsync ( )
111+ {
112+ List < KeyValuePair < string , ExchangeTicker > > tickers = new List < KeyValuePair < string , ExchangeTicker > > ( ) ;
113+ await parseData ( await MakeJsonRequestAsync < JToken > ( "/market/tickers?instType=SPOT" , BaseUrlV5 ) ) ;
114+ if ( IsFuturesAndSwapEnabled )
115+ {
116+ await parseData ( await MakeJsonRequestAsync < JToken > ( "/market/tickers?instType=FUTURES" , BaseUrlV5 ) ) ;
117+ await parseData ( await MakeJsonRequestAsync < JToken > ( "/market/tickers?instType=SWAP" , BaseUrlV5 ) ) ;
118+ }
119+ async Task parseData ( JToken tickerResponse )
120+ {
121+ /*{
122+ "code":"0",
123+ "msg":"",
124+ "data":[
125+ {
126+ "instType":"SWAP",
127+ "instId":"LTC-USD-SWAP",
128+ "last":"9999.99",
129+ "lastSz":"0.1",
130+ "askPx":"9999.99",
131+ "askSz":"11",
132+ "bidPx":"8888.88",
133+ "bidSz":"5",
134+ "open24h":"9000",
135+ "high24h":"10000",
136+ "low24h":"8888.88",
137+ "volCcy24h":"2222",
138+ "vol24h":"2222",
139+ "sodUtc0":"0.1",
140+ "sodUtc8":"0.1",
141+ "ts":"1597026383085"
142+ },
143+ ...
144+ ]
145+ }
146+ */
147+
148+ foreach ( JToken t in tickerResponse )
149+ {
150+ var symbol = t [ "instId" ] . Value < string > ( ) ;
151+ ExchangeTicker ticker = await ParseTickerV5Async ( t , symbol ) ;
152+ tickers . Add ( new KeyValuePair < string , ExchangeTicker > ( symbol , ticker ) ) ;
153+ }
154+ }
155+
156+ return tickers ;
157+ }
158+
159+ protected override async Task < IEnumerable < ExchangeTrade > > OnGetRecentTradesAsync ( string marketSymbol , int ? limit )
160+ {
161+ limit = limit ?? 500 ;
162+ marketSymbol = NormalizeMarketSymbol ( marketSymbol ) ;
163+ List < ExchangeTrade > trades = new List < ExchangeTrade > ( ) ;
164+ var recentTradesResponse = await MakeJsonRequestAsync < JToken > ( $ "/market/trades?instId={ marketSymbol } &limit={ limit } ", BaseUrlV5 ) ;
165+ foreach ( var t in recentTradesResponse )
166+ {
167+ trades . Add (
168+ t . ParseTrade (
169+ amountKey : "sz" ,
170+ priceKey : "px" ,
171+ typeKey : "side" ,
172+ timestampKey : "ts" ,
173+ timestampType : TimestampType . UnixMilliseconds ,
174+ idKey : "tradeId" ) ) ;
175+ }
176+
177+ return trades ;
178+ }
179+
180+ private async Task < ExchangeTicker > ParseTickerV5Async ( JToken t , string symbol )
181+ {
182+ return await this . ParseTickerAsync (
183+ t ,
184+ symbol ,
185+ askKey : "askPx" ,
186+ bidKey : "bidPx" ,
187+ lastKey : "last" ,
188+ baseVolumeKey : "vol24h" ,
189+ quoteVolumeKey : "volCcy24h" ,
190+ timestampKey : "ts" ,
191+ timestampType : TimestampType . UnixMilliseconds ) ;
192+ }
24193 }
25194
26195 public partial class ExchangeName { public const string OKEx = "OKEx" ; }
27- }
196+ }
0 commit comments