From 6bdf3ba130e958dd57314d9a3017a3bdceec97c4 Mon Sep 17 00:00:00 2001 From: kyh <1329522@naver.com> Date: Thu, 29 Aug 2024 13:10:26 +0900 Subject: [PATCH] =?UTF-8?q?buy=20sell=20=EA=B4=80=EB=A0=A8=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=A0=95=EB=A6=AC=20=EB=B0=8F=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=20->=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=8A=94=20=ED=95=84?= =?UTF-8?q?=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BitgetApi/CommonProperty.cs | 24 ++++- .../IndicatorProcess.cs | 100 ++++++++++++++++-- 2 files changed, 115 insertions(+), 9 deletions(-) diff --git a/BitgetApi/CommonProperty.cs b/BitgetApi/CommonProperty.cs index b8b14d5..390c7a2 100644 --- a/BitgetApi/CommonProperty.cs +++ b/BitgetApi/CommonProperty.cs @@ -98,7 +98,16 @@ namespace BitgetAPI [Description("BitgetOrderCancel_FUTURE")] BitgetCancelOrder_Future = 32, [Description("BitgetPendingOrder_FUTURE")] - BitgetPendingOrder_Future = 33 + BitgetPendingOrder_Future = 33, + [Description("BitgetChangeLeverage_FUTURE")] + BitgetChangeLeverage_Future = 34, + [Description("BitgetChangeMarginMode_FUTURE")] + BitgetChangeMarginMode_Future = 35, + [Description("BitgetChangePositionMode_FUTURE")] + BitgetChangePositionMode_Future = 36, + [Description("BitgetOrderDetail_FUTURE")] + BitgetOrderDetail_Future = 37, + #endregion } @@ -119,6 +128,14 @@ namespace BitgetAPI sell =1 } + public enum FuturePositionMode + { + [Description("one_way_mode")] + one_way_mode = 0, + [Description("hedge_mode")] + hedge_mode = 1 + } + public enum OrderType { [Description("limit")] @@ -227,6 +244,11 @@ namespace BitgetAPI public static string BitgetURL_BuySellOrder_Future = @"https://api.bitget.com/api/v2/mix/order/place-order"; public static string BitgetURL_CancelOrder_Future = @"https://api.bitget.com/api/v2/mix/order/cancel-order"; public static string BitgetURL_PendingOrders_Future = @"https://api.bitget.com/api/v2/mix/order/orders-pending?productType=usdt-futures"; + public static string BitgetURL_ChangeLeverage_Future = @"https://api.bitget.com/api/v2/mix/account/set-leverage"; + public static string BitgetURL_ChangeMarginMode_Future = @"https://api.bitget.com/api/v2/mix/account/set-margin-mode"; + public static string BitgetURL_ChangePositionMode_Future = @"https://api.bitget.com/api/v2/mix/account/set-position-mode"; + public static string BitgetURL_OrderDetail_Future = @"https://api.bitget.com/api/v2/mix/order/detail"; + #endregion } } diff --git a/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs b/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs index a1fb152..959534f 100644 --- a/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs +++ b/BitgetApi/IndicatorConditionSetup/IndicatorProcess.cs @@ -23,6 +23,7 @@ using static System.Windows.Forms.VisualStyles.VisualStyleElement.Tab; using static DevExpress.XtraPrinting.Native.ExportOptionsPropertiesNames; using System.Security.Cryptography; using System.Globalization; +using Newtonsoft.Json; namespace BitgetAPI.IndicatorConditionSetup @@ -88,6 +89,18 @@ namespace BitgetAPI.IndicatorConditionSetup GetFutureAccountList(); + /** + * 사는 방법 + * 1. ChangeFuturePositionMode 호출(한방향, 양방향 -> Long, Short) + * 2. FutureOrder 호출 + * 1). Bitget_ChangeMarginMode_Future 를 통해Coin, ProductType 별 Margin Mode 변경 + * 2). 변경된 Margin Coin 별 MarginMode에 Leverage를 Set 함 + * 3). Buy 진행 + * 3. GetPendingOrders를 통해 확인 가능 + * 4. Sell 시 FutureOrder 호출 + * 5. Order Detail를 통해 Client OID를 획득 후 처리 + */ + // 추후 공통화 및 소스정리 필요 while (true) { @@ -890,7 +903,7 @@ namespace BitgetAPI.IndicatorConditionSetup var reqStr = "/api/v2/mix/order/cancel-order"; var nvc = new NameValueCollection { - {"ACCESS-KEY", new Guid().ToString()}, + {"ACCESS-KEY", YHKIM_AccessKey}, {"ACCESS-SIGN", GenerateSignString(timestamp, "POST", reqStr, "", null, YHKIM_SecreteKey)}, {"ACCESS-PASSPHRASE", YHKIM_PassphraseKey }, {"ACCESS-TIMESTAMP", timestamp} @@ -901,18 +914,40 @@ namespace BitgetAPI.IndicatorConditionSetup return (Dictionary)WebConnection.SendWebServer(ExchangeWebReqType.BitgetCancelOrder_Future, BitgetURL_CancelOrder_Future, null, MCandleTimeType.M1, postStr, "", nvc); } - public Dictionary FutureOrder(string symbol, FutureMarginMode marginMode, double size, double price, FutureSide futureSide, OrderType orderType) + public Dictionary ChangeFuturePositionMode(FuturePositionMode mode) + { + var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0)); + + var timestamp = (timeSpan.TotalSeconds * 1000).ToString(); + + var reqStr = "/api/v2/mix/account/set-position-mode"; + var nvc = new NameValueCollection { + {"ACCESS-KEY", YHKIM_AccessKey}, + {"ACCESS-SIGN", GenerateSignString(timestamp, "POST", reqStr, "", null, YHKIM_SecreteKey)}, + {"ACCESS-PASSPHRASE", YHKIM_PassphraseKey }, + {"ACCESS-TIMESTAMP", timestamp} + }; + + var postStr = string.Format("{\"productType\" : \"USDT-FUTURES\", \"posMode\" : \"{0}\"}", Utils.Convertor.GetEnumDescription((Enum)mode)); + + return (Dictionary)WebConnection.SendWebServer(ExchangeWebReqType.BitgetChangePositionMode_Future, BitgetURL_ChangePositionMode_Future, null, MCandleTimeType.M1, postStr, "", nvc); + } + + + public Dictionary FutureOrder(string symbol, FutureMarginMode marginMode, double size, double price, FutureSide futureSide, OrderType orderType, string leverage, string id = "") { var side = ""; var tradeSide = ""; - - if(futureSide == FutureSide.BuyShort) + + if (futureSide == FutureSide.BuyShort) { + id = new Guid().ToString(); side = "sell"; tradeSide = "open"; } else if (futureSide == FutureSide.BuyLong) { + id = new Guid().ToString(); side = "buy"; tradeSide = "Open"; } @@ -937,16 +972,65 @@ namespace BitgetAPI.IndicatorConditionSetup var reqStr = "/api/v2/mix/order/place-order"; var nvc = new NameValueCollection { - {"ACCESS-KEY", new Guid().ToString()}, + {"ACCESS-KEY", YHKIM_AccessKey}, {"ACCESS-SIGN", GenerateSignString(timestamp, "POST", reqStr, "", null, YHKIM_SecreteKey)}, {"ACCESS-PASSPHRASE", YHKIM_PassphraseKey }, {"ACCESS-TIMESTAMP", timestamp} }; - var postStr = string.Format("{\"symbol\": \"{0}\", \"productType\": \"usdt - futures\", \"marginMode\": \"{1}\", \"marginCoin\": \"USDT\", \"size\": \"{2}\", \"price\": \"{3}\", \"side\": \"{4}\", " + + if(futureSide == FutureSide.BuyShort|| futureSide == FutureSide.BuyLong) + { + //change margin mode 이후 leverage 처리 해야 함 + var changeMarginModeStr = string.Format("{\"symbol\": \"{0}\", \"productType\": \"usdt-futures\", \"marginCoin\": \"USDT\", \"marginMode\": \"{1}\"}", + symbol, Utils.Convertor.GetEnumDescription((Enum)marginMode)); + var nvcMargin = new NameValueCollection { + {"ACCESS-KEY", YHKIM_AccessKey}, + {"ACCESS-SIGN", GenerateSignString(timestamp, "POST", "/api/v2/mix/account/set-margin-mode", "", null, YHKIM_SecreteKey)}, + {"ACCESS-PASSPHRASE", YHKIM_PassphraseKey }, + {"ACCESS-TIMESTAMP", timestamp} + }; + var result = (Dictionary)WebConnection.SendWebServer(ExchangeWebReqType.BitgetChangeMarginMode_Future, BitgetURL_ChangeMarginMode_Future, null, MCandleTimeType.M1, changeMarginModeStr, "", nvcMargin); + if (result["msg"]?.ToString() != "success") + { + return null; + } + + var leverageStr = string.Format("{\"symbol\": \"{0}\", \"productType\": \"usdt-futures\", \"marginCoin\": \"USDT\", \"leverage\": \"{1}\", \"holdSide\": \"{3}\"}", + symbol, leverage, futureSide == FutureSide.BuyShort ? "short" : "long"); + var nvcLeverage = new NameValueCollection { + {"ACCESS-KEY", YHKIM_AccessKey}, + {"ACCESS-SIGN", GenerateSignString(timestamp, "POST", "/api/v2/mix/account/set-leverage", "", null, YHKIM_SecreteKey)}, + {"ACCESS-PASSPHRASE", YHKIM_PassphraseKey }, + {"ACCESS-TIMESTAMP", timestamp} + }; + result = (Dictionary)WebConnection.SendWebServer(ExchangeWebReqType.BitgetChangeLeverage_Future, BitgetURL_ChangeLeverage_Future, null, MCandleTimeType.M1, leverageStr, "", nvcLeverage); + if (result["msg"]?.ToString() != "success") + { + return null; + } + } + else + { + // sell은 ClientOID 가 필요 + var orderDetailStr = "/api/v2/mix/order/detail"; + + var orderDetailnvc = new NameValueCollection { + {"ACCESS-KEY", YHKIM_AccessKey}, + {"ACCESS-SIGN", GenerateSignString(timestamp, "GET", orderDetailStr, "symbol="+symbol.ToString()+"&orderId="+id.ToString()+"&productType=usdt-future", null, YHKIM_SecreteKey) }, + {"ACCESS-PASSPHRASE", YHKIM_PassphraseKey }, + {"ACCESS-TIMESTAMP",timestamp} + }; + + var orderDetail = (Dictionary)WebConnection.SendWebServer(ExchangeWebReqType.BitgetOrderDetail_Future, BitgetURL_OrderDetail_Future, null, MCandleTimeType.M1, "", "", orderDetailnvc); + if (orderDetail["msg"]?.ToString() != "success") return null; + var data = JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(orderDetail["data"])); + id = data["clientOid"].ToString(); + } + + var postStr = string.Format("{\"symbol\": \"{0}\", \"productType\": \"usdt-futures\", \"marginMode\": \"{1}\", \"marginCoin\": \"USDT\", \"size\": \"{2}\", \"price\": \"{3}\", \"side\": \"{4}\", " + "\"tradeSide\": \"{5}\", \"orderType\": \"{6}\", \"force\": \"gtc\", \"clientOid\": \"{8}\" }", - symbol, Utils.Convertor.GetEnumDescription((Enum)marginMode), size.ToString(), - price.ToString(), side, tradeSide, Utils.Convertor.GetEnumDescription((Enum)orderType), new Guid().ToString()); + symbol, Utils.Convertor.GetEnumDescription((Enum)marginMode), size.ToString(), + price.ToString(), side, tradeSide, Utils.Convertor.GetEnumDescription((Enum)orderType), id); return (Dictionary)WebConnection.SendWebServer(ExchangeWebReqType.BitgetOrder_Future, BitgetURL_BuySellOrder_Future, null, MCandleTimeType.M1, postStr, "", nvc); }