diff --git a/KiteConnect/Constants.cs b/KiteConnect/Constants.cs index 03a7d6f..79c4639 100644 --- a/KiteConnect/Constants.cs +++ b/KiteConnect/Constants.cs @@ -30,6 +30,7 @@ public class Constants public const string VARIETY_BO = "bo"; public const string VARIETY_CO = "co"; public const string VARIETY_AMO = "amo"; + public const string VARIETY_ICEBERG = "iceberg"; // Transaction type public const string TRANSACTION_TYPE_BUY = "BUY"; @@ -38,6 +39,7 @@ public class Constants // Validity public const string VALIDITY_DAY = "DAY"; public const string VALIDITY_IOC = "IOC"; + public const string VALIDITY_TTL = "TTL"; // Exchanges public const string EXCHANGE_NSE = "NSE"; diff --git a/KiteConnect/Kite.cs b/KiteConnect/Kite.cs index 2c8aa14..7ce818f 100644 --- a/KiteConnect/Kite.cs +++ b/KiteConnect/Kite.cs @@ -349,14 +349,17 @@ public UserMargin GetMargins(string Segment) /// For LIMIT orders /// Margin product applied to the order (margin is blocked based on this) /// Order type (MARKET, LIMIT etc.) - /// Order validity + /// Order validity (DAY, IOC and TTL) /// Quantity to disclose publicly (for equity trades) /// For SL, SL-M etc. /// Price difference at which the order should be squared off and profit booked (eg: Order price is 100. Profit target is 102. So squareoff = 2) /// Stoploss difference at which the order should be squared off (eg: Order price is 100. Stoploss target is 98. So stoploss = 2) /// Incremental value by which stoploss price changes when market moves in your favor by the same incremental value from the entry price (optional) - /// You can place orders of varieties; regular orders, after market orders, cover orders etc. - /// An optional tag to apply to an order to identify it (alphanumeric, max 8 chars) + /// You can place orders of varieties; regular orders, after market orders, cover orders, iceberg orders etc. + /// An optional tag to apply to an order to identify it (alphanumeric, max 20 chars) + /// Order life span in minutes for TTL validity orders + /// Total number of legs for iceberg order type (number of legs per Iceberg should be between 2 and 10) + /// Split quantity for each iceberg leg order (Quantity/IcebergLegs) /// Json response in the form of nested string dictionary. public Dictionary PlaceOrder( string Exchange, @@ -373,7 +376,11 @@ public Dictionary PlaceOrder( decimal? StoplossValue = null, decimal? TrailingStoploss = null, string Variety = Constants.VARIETY_REGULAR, - string Tag = "") + string Tag = "", + int? ValidityTTL = null, + int? IcebergLegs = null, + int? IcebergQuantity = null + ) { var param = new Dictionary(); @@ -392,6 +399,9 @@ public Dictionary PlaceOrder( Utils.AddIfNotNull(param, "trailing_stoploss", TrailingStoploss.ToString()); Utils.AddIfNotNull(param, "variety", Variety); Utils.AddIfNotNull(param, "tag", Tag); + Utils.AddIfNotNull(param, "validity_ttl", ValidityTTL.ToString()); + Utils.AddIfNotNull(param, "iceberg_legs", IcebergLegs.ToString()); + Utils.AddIfNotNull(param, "iceberg_quantity", IcebergQuantity.ToString()); return Post("orders.place", param); } diff --git a/KiteConnect/Structures.cs b/KiteConnect/Structures.cs index f84d4e7..b1f371e 100644 --- a/KiteConnect/Structures.cs +++ b/KiteConnect/Structures.cs @@ -474,11 +474,23 @@ public Order(Dictionary data) Status = data["status"]; StatusMessage = data["status_message"]; Tag = data["tag"]; + Tags = new List(); + if(data.ContainsKey("tags")) { + Tags = ((data["tags"] ?? Tags) as ArrayList).Cast().ToList(); + } Tradingsymbol = data["tradingsymbol"]; TransactionType = data["transaction_type"]; TriggerPrice = data["trigger_price"]; Validity = data["validity"]; + ValidityTTL = 0; + if(data.ContainsKey("validity_ttl")) { + ValidityTTL = Convert.ToInt32(data["validity_ttl"]); + } Variety = data["variety"]; + Meta = new Dictionary(); + if(data.ContainsKey("meta")) { + Meta = data["meta"]; + } } catch (Exception e) { @@ -507,11 +519,14 @@ public Order(Dictionary data) public string Status { get; set; } public string StatusMessage { get; set; } public string Tag { get; set; } + public List Tags { get; set; } public string Tradingsymbol { get; set; } public string TransactionType { get; set; } public decimal TriggerPrice { get; set; } public string Validity { get; set; } + public int ValidityTTL { get; set; } public string Variety { get; set; } + public Dictionary Meta { get; set; } } /// diff --git a/KiteConnectSample/Program.cs b/KiteConnectSample/Program.cs index 9678b16..82d012a 100644 --- a/KiteConnectSample/Program.cs +++ b/KiteConnectSample/Program.cs @@ -288,6 +288,33 @@ static void Main(string[] args) ParentOrderId: "5678" ); + // Place order with TTL validity + kite.PlaceOrder( + Exchange: Constants.EXCHANGE_NSE, + TradingSymbol: "INFY", + TransactionType: Constants.TRANSACTION_TYPE_BUY, + Quantity: 1, + Price: 1500.0m, + OrderType: Constants.ORDER_TYPE_LIMIT, + Product: Constants.PRODUCT_MIS, + Validity: Constants.VALIDITY_TTL, + ValidityTTL: 5 + ); + + // Place an Iceberg order + kite.PlaceOrder( + Exchange: Constants.EXCHANGE_NSE, + TradingSymbol: "INFY", + TransactionType: Constants.TRANSACTION_TYPE_BUY, + Quantity: 10, + Price: 1500.0m, + OrderType: Constants.ORDER_TYPE_LIMIT, + Product: Constants.PRODUCT_MIS, + Variety: Constants.VARIETY_ICEBERG, + IcebergLegs: 2, + IcebergQuantity: 5 + ); + // Trades List trades = kite.GetOrderTrades("1234"); diff --git a/KiteConnectTest/KiteTest.cs b/KiteConnectTest/KiteTest.cs index e6b99b3..76e28b2 100644 --- a/KiteConnectTest/KiteTest.cs +++ b/KiteConnectTest/KiteTest.cs @@ -257,7 +257,14 @@ public void TestOrders() Kite kite = new Kite("apikey", Root: "http://localhost:8080"); List orders = kite.GetOrders(); - Assert.AreEqual(orders[0].Price, 90); + Assert.AreEqual(orders[0].Price, 72); + + Assert.AreEqual(orders[2].Tag, "connect test order2"); + Assert.AreEqual(orders[2].Tags[1], "XXXXX"); + + Assert.AreEqual(orders[3].ValidityTTL, 2); + + Assert.AreEqual(orders[3].Meta["iceberg"]["legs"], 5); } [TestMethod] diff --git a/KiteConnectTest/responses/orders.json b/KiteConnectTest/responses/orders.json index 7d1a09d..35954dd 100644 --- a/KiteConnectTest/responses/orders.json +++ b/KiteConnectTest/responses/orders.json @@ -2,60 +2,152 @@ "status": "success", "data": [ { - "average_price": 0, - "cancelled_quantity": 0, + "placed_by": "XXXXXX", + "order_id": "100000000000000", + "exchange_order_id": "200000000000000", + "parent_order_id": null, + "status": "CANCELLED", + "status_message": null, + "status_message_raw": null, + "order_timestamp": "2021-05-31 09:18:57", + "exchange_update_timestamp": "2021-05-31 09:18:58", + "exchange_timestamp": "2021-05-31 09:15:38", + "variety": "regular", + "exchange": "CDS", + "tradingsymbol": "USDINR21JUNFUT", + "instrument_token": 412675, + "order_type": "LIMIT", + "transaction_type": "BUY", + "validity": "DAY", + "product": "NRML", + "quantity": 1, "disclosed_quantity": 0, - "exchange": "NFO", - "exchange_order_id": null, - "exchange_timestamp": null, + "price": 72, + "trigger_price": 0, + "average_price": 0, "filled_quantity": 0, - "instrument_token": 13941506, + "pending_quantity": 1, + "cancelled_quantity": 1, "market_protection": 0, - "order_id": "171128000482270", - "order_timestamp": "2017-11-28 10:30:24", - "order_type": "LIMIT", + "meta": {}, + "tag": null, + "guid": "XXXXX" + }, + { + "placed_by": "XXXXXX", + "order_id": "700000000000000", + "exchange_order_id": "800000000000000", "parent_order_id": null, - "pending_quantity": 0, - "placed_by": "ZR0000", - "price": 90, - "product": "BO", - "quantity": 75, - "status": "REJECTED", - "status_message": "RMS:Margin Exceeds,Required:4725.00, Available:1697.70 for entity account-DH0490 across exchange across segment across product ", - "tag": "sample", - "tradingsymbol": "NIFTY17NOV10350CE", + "status": "COMPLETE", + "status_message": null, + "status_message_raw": null, + "order_timestamp": "2021-05-31 16:00:36", + "exchange_update_timestamp": "2021-05-31 16:00:36", + "exchange_timestamp": "2021-05-31 16:00:36", + "variety": "regular", + "exchange": "MCX", + "tradingsymbol": "GOLDPETAL21JUNFUT", + "instrument_token": 58424839, + "order_type": "LIMIT", "transaction_type": "BUY", - "trigger_price": 0, "validity": "DAY", - "variety": "bo" + "product": "NRML", + "quantity": 1, + "disclosed_quantity": 0, + "price": 4854, + "trigger_price": 0, + "average_price": 4852, + "filled_quantity": 1, + "pending_quantity": 0, + "cancelled_quantity": 0, + "market_protection": 0, + "meta": {}, + "tag": "connect test order1", + "tags": [ + "connect test order1" + ], + "guid": "XXXXXXX" }, { - "average_price": 0, - "cancelled_quantity": 0, + "placed_by": "XXXXXX", + "order_id": "9000000000000000", + "exchange_order_id": "1000000000000000", + "parent_order_id": null, + "status": "COMPLETE", + "status_message": null, + "status_message_raw": null, + "order_timestamp": "2021-05-31 16:08:40", + "exchange_update_timestamp": "2021-05-31 16:08:41", + "exchange_timestamp": "2021-05-31 16:08:41", + "variety": "regular", + "exchange": "MCX", + "tradingsymbol": "GOLDPETAL21JUNFUT", + "instrument_token": 58424839, + "order_type": "LIMIT", + "transaction_type": "BUY", + "validity": "DAY", + "product": "NRML", + "quantity": 1, "disclosed_quantity": 0, - "exchange": "NFO", - "exchange_order_id": null, - "exchange_timestamp": null, - "filled_quantity": 0, - "instrument_token": 13941506, + "price": 4854, + "trigger_price": 0, + "average_price": 4852, + "filled_quantity": 1, + "pending_quantity": 0, + "cancelled_quantity": 0, "market_protection": 0, - "order_id": "171128000485269", - "order_timestamp": "2017-11-28 10:31:16", - "order_type": "LIMIT", + "meta": {}, + "tag": "connect test order2", + "tags": [ + "connect test order2", + "XXXXX" + ], + "guid": "XXXXXX" + }, + { + "placed_by": "XXXXXX", + "order_id": "220524001859672", + "exchange_order_id": null, "parent_order_id": null, - "pending_quantity": 0, - "placed_by": "ZR0000", - "price": 90, - "product": "BO", - "quantity": 75, "status": "REJECTED", - "status_message": "RMS:Margin Exceeds,Required:4725.00, Available:1697.70 for entity account-DH0490 across exchange across segment across product ", - "tag": "sample", - "tradingsymbol": "NIFTY17NOV10350CE", + "status_message": "Insufficient funds. Required margin is 95417.84 but available margin is 74251.80. Check the orderbook for open orders.", + "status_message_raw": "RMS:Margin Exceeds,Required:95417.84, Available:74251.80 for entity account-XXXXX across exchange across segment across product ", + "order_timestamp": "2022-05-24 12:26:52", + "exchange_update_timestamp": null, + "exchange_timestamp": null, + "variety": "iceberg", + "modified": false, + "exchange": "NSE", + "tradingsymbol": "SBIN", + "instrument_token": 779521, + "order_type": "LIMIT", "transaction_type": "BUY", + "validity": "TTL", + "validity_ttl": 2, + "product": "CNC", + "quantity": 200, + "disclosed_quantity": 0, + "price": 463, "trigger_price": 0, - "validity": "DAY", - "variety": "bo" + "average_price": 0, + "filled_quantity": 0, + "pending_quantity": 0, + "cancelled_quantity": 0, + "market_protection": 0, + "meta": { + "iceberg": { + "leg": 1, + "legs": 5, + "leg_quantity": 200, + "total_quantity": 1000, + "remaining_quantity": 800 + } + }, + "tag": "icebergord", + "tags": [ + "icebergord" + ], + "guid": "XXXXXX" } ] } \ No newline at end of file