HashSet <long> SpotOrders(Spot spot) { try { var res = new HashSet <long>(); var param = new KV[] { new KV("symbol", Serialization.AsString(spot.CoinType, spot.Currency)), new KV("order_id", "-1") // all open orders }; string content = SendRequest(HttpMethod.Post, "order_info.do", Authenticated(param)); var root = JObject.Parse(content); CheckErrorCode(root); foreach (JObject data in (JArray)root["orders"]) { int status = (int)data["status"]; // 0 is unfilled, 1 is partially filled. if (status == 0 || status == 1) { res.Add((long)data["order_id"]); } } return(res); } catch (Exception e) { _log.Warn(e, "RestClient.SpotOrders() failed"); throw; } }
public static string MyOrders(ProductType p, Currency c) { switch (p) { case ProductType.Future: return(String.Format("ok_{0}_future_realtrades", Serialization.AsString(c))); case ProductType.Spot: return(String.Format("ok_{0}_realtrades", Serialization.AsString(c))); } throw new ArgumentException("Unknown ProductType: " + p); }
public static string SpotPositions(Currency c, RequestType req) { switch (req) { case RequestType.Poll: return(String.Format("ok_spot{0}_userinfo", Serialization.AsString(c))); case RequestType.Subscribe: return(String.Format("ok_sub_spot{0}_userinfo", Serialization.AsString(c))); } throw new Exception("Invalid RequestType: " + req); }
HashSet <long> FutureOrders(Future future) { try { var res = new HashSet <long>(); for (int page = 0; true; ++page) { var param = new KV[] { new KV("symbol", Serialization.AsString(future.CoinType, future.Currency)), new KV("contract_type", Serialization.AsString(future.FutureType)), new KV("status", "1"), // unfilled orders new KV("order_id", "-1"), // all matching orders new KV("page_length", "50"), // this is the maximum supported value new KV("current_page", page.ToString()), }; string content = SendRequest(HttpMethod.Post, "future_order_info.do", Authenticated(param)); var root = JObject.Parse(content); CheckErrorCode(root); int total_orders = 0; int new_orders = 0; foreach (JObject data in (JArray)root["orders"]) { int status = (int)data["status"]; // 0 is unfilled, 1 is partially filled. if (status == 0 || status == 1) { if (res.Add((long)data["order_id"])) { ++new_orders; } } ++total_orders; } // Pagination on OKCoin is weird. They don't tell us if there are more results, so we have to guess. // We can't just go over the pages until we get an empty one -- they always return the last page if // current_page is too large. if (total_orders < 50 || new_orders == 0) { break; } } return(res); } catch (Exception e) { _log.Warn(e, "RestClient.FutureOrders() failed"); throw; } }
// Throws on HTTP timeouts, HTTP errors, parse errors and // application errors (when OkCoin gives us error_code). public Dictionary <FutureType, List <FuturePosition> > FuturePositions(Currency currency, CoinType coin) { try { var param = new KV[] { new KV("symbol", Serialization.AsString(coin, currency)), new KV("type", "1"), }; string content = SendRequest(HttpMethod.Post, "future_position_4fix.do", Authenticated(param)); var root = JObject.Parse(content); CheckErrorCode(root); var res = new Dictionary <FutureType, List <FuturePosition> >(); foreach (var e in Util.Enum.Values <FutureType>()) { res.Add(e, new List <FuturePosition>()); } foreach (JObject data in (JArray)root["holding"]) { Action <PositionType, string> AddPosition = (PositionType type, string prefix) => { var quantity = data[prefix + "_amount"].AsDecimal(); if (quantity == 0) { return; } FutureType ft = Serialization.ParseFutureType((string)data["contract_type"]); string contractId = (string)data["contract_id"]; VerifyFutureType(ft, contractId); res[ft].Add(new FuturePosition() { Quantity = quantity, PositionType = type, AvgPrice = data[prefix + "_price_avg"].AsDecimal(), ContractId = contractId, Leverage = Serialization.ParseLeverage((string)data["lever_rate"]), }); }; AddPosition(PositionType.Long, "buy"); AddPosition(PositionType.Short, "sell"); } return(res); } catch (Exception e) { _log.Warn(e, "RestClient.FuturePosition() failed"); throw; } }
public string Visit(CancelOrderRequest msg) { IEnumerable <KV> param = new KV[] { new KV("order_id", msg.OrderId.ToString()), new KV("symbol", Serialization.AsString(msg.Product.CoinType, msg.Product.Currency)), }; var future = msg.Product as Future; if (future != null) { param = param.Append(new KV("contract_type", Serialization.AsString(future.FutureType))); } return(AuthenticatedRequest(msg, param)); }
public string Visit(NewSpotRequest msg) { IEnumerable <KV> param = new KV[] { new KV("amount", Serialization.AsString(msg.Amount.Quantity)), new KV("symbol", Serialization.AsString(msg.Product.CoinType, msg.Product.Currency)), }; if (msg.OrderType == OrderType.Limit) { param = param.Append(new KV("price", Serialization.AsString(msg.Amount.Price))) .Append(new KV("type", msg.Amount.Side == Side.Buy ? "buy" : "sell")); } else { param = param.Append(new KV("type", msg.Amount.Side == Side.Buy ? "market_buy" : "market_sell")); } return(AuthenticatedRequest(msg, param)); }
public static string MarketData(Product p, MarketData ch) { // Representative examples of channel names: // ok_btcusd_trades_v1 // ok_btcusd_depth60 // ok_btcusd_future_trade_v1_this_week // ok_btcusd_future_depth_this_week_60 var res = new StringBuilder(64); res.Append("ok_"); res.Append(Serialization.AsString(p.CoinType)); res.Append(Serialization.AsString(p.Currency)); res.Append("_"); switch (p.ProductType) { case ProductType.Spot: switch (ch) { case OkCoin.MarketData.Depth60: res.Append("depth60"); break; case OkCoin.MarketData.Trades: res.Append("trades_v1"); break; } break; case ProductType.Future: res.Append("future_"); switch (ch) { case OkCoin.MarketData.Depth60: res.Append("depth_"); res.Append(Serialization.AsString(((Future)p).FutureType)); res.Append("_60"); break; case OkCoin.MarketData.Trades: res.Append("trade_v1_"); res.Append(Serialization.AsString(((Future)p).FutureType)); break; } break; } return(res.ToString()); }
public string Visit(NewFutureRequest msg) { IEnumerable <KV> param = new KV[] { new KV("contract_type", Serialization.AsString(msg.Product.FutureType)), new KV("amount", Serialization.AsString(msg.Amount.Quantity)), new KV("type", Serialization.AsString(msg.Amount.Side, msg.PositionType)), new KV("lever_rate", Serialization.AsString(msg.Leverage)), new KV("symbol", Serialization.AsString(msg.Product.CoinType, msg.Product.Currency)), }; if (msg.OrderType == OrderType.Limit) { param = param.Append(new KV("price", Serialization.AsString(msg.Amount.Price))) .Append(new KV("match_price", "0")); } else { param = param.Append(new KV("match_price", "1")); } return(AuthenticatedRequest(msg, param)); }
public IMessageIn Visit(SpotPositionsUpdate msg) { // RequestType == Poll. // // "info": { // "funds": { // "asset": { // "net": "7.58", // "total": "7.58" // }, // "free": { // "btc": "0.00498", // "ltc": "0", // "usd": "5.5314" // }, // "freezed": { // "btc": "0", // "ltc": "0", // "usd": "0" // } // } // }, // "result": true // // RequestType == Subscribe. // // "info": { // "free": { // "btc": 0.01498, // "usd": 1.4137, // "ltc": 0 // }, // "freezed": { // "btc": 0, // "usd": 0, // "ltc": 0 // } // } if (_data == null) { // OkCoin sends an empty message without data in response to // our subscription request. return(msg); } JToken funds = _data["info"]; if (msg.RequestType == RequestType.Poll) { funds = funds["funds"]; } JToken free = funds["free"]; JToken frozen = funds["freezed"]; Func <string, Asset> MakeAsset = (string name) => new Asset() { Free = free[name].AsDecimal(), Frozen = frozen[name].AsDecimal() }; msg.Balance = MakeAsset(Serialization.AsString(msg.Currency)); msg.Positions = new Dictionary <CoinType, Asset>(); foreach (CoinType c in Util.Enum.Values <CoinType>()) { msg.Positions.Add(c, MakeAsset(Serialization.AsString(c))); } return(msg); }
public static string CancelOrder(ProductType p, Currency c) { return(String.Format("ok_{0}{1}_cancel_order", Serialization.AsString(p), Serialization.AsString(c))); }
public static string NewOrder(ProductType p, Currency c) { return(String.Format("ok_{0}{1}_trade", Serialization.AsString(p), Serialization.AsString(c))); }