Skip to content

Commit

Permalink
feat: ttl validity, iceberg order
Browse files Browse the repository at this point in the history
  • Loading branch information
ajinasokan committed Jun 1, 2022
1 parent bb71581 commit d071a86
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 45 deletions.
2 changes: 2 additions & 0 deletions KiteConnect/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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";
Expand Down
18 changes: 14 additions & 4 deletions KiteConnect/Kite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -349,14 +349,17 @@ public UserMargin GetMargins(string Segment)
/// <param name="Price">For LIMIT orders</param>
/// <param name="Product">Margin product applied to the order (margin is blocked based on this)</param>
/// <param name="OrderType">Order type (MARKET, LIMIT etc.)</param>
/// <param name="Validity">Order validity</param>
/// <param name="Validity">Order validity (DAY, IOC and TTL)</param>
/// <param name="DisclosedQuantity">Quantity to disclose publicly (for equity trades)</param>
/// <param name="TriggerPrice">For SL, SL-M etc.</param>
/// <param name="SquareOffValue">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)</param>
/// <param name="StoplossValue">Stoploss difference at which the order should be squared off (eg: Order price is 100. Stoploss target is 98. So stoploss = 2)</param>
/// <param name="TrailingStoploss">Incremental value by which stoploss price changes when market moves in your favor by the same incremental value from the entry price (optional)</param>
/// <param name="Variety">You can place orders of varieties; regular orders, after market orders, cover orders etc. </param>
/// <param name="Tag">An optional tag to apply to an order to identify it (alphanumeric, max 8 chars)</param>
/// <param name="Variety">You can place orders of varieties; regular orders, after market orders, cover orders, iceberg orders etc. </param>
/// <param name="Tag">An optional tag to apply to an order to identify it (alphanumeric, max 20 chars)</param>
/// <param name="ValidityTTL">Order life span in minutes for TTL validity orders</param>
/// <param name="IcebergLegs">Total number of legs for iceberg order type (number of legs per Iceberg should be between 2 and 10)</param>
/// <param name="IcebergQuantity">Split quantity for each iceberg leg order (Quantity/IcebergLegs)</param>
/// <returns>Json response in the form of nested string dictionary.</returns>
public Dictionary<string, dynamic> PlaceOrder(
string Exchange,
Expand All @@ -373,7 +376,11 @@ public Dictionary<string, dynamic> 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<string, dynamic>();

Expand All @@ -392,6 +399,9 @@ public Dictionary<string, dynamic> 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);
}
Expand Down
15 changes: 15 additions & 0 deletions KiteConnect/Structures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -474,11 +474,23 @@ public Order(Dictionary<string, dynamic> data)
Status = data["status"];
StatusMessage = data["status_message"];
Tag = data["tag"];
Tags = new List<string>();
if(data.ContainsKey("tags")) {
Tags = ((data["tags"] ?? Tags) as ArrayList).Cast<string>().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<string, dynamic>();
if(data.ContainsKey("meta")) {
Meta = data["meta"];
}
}
catch (Exception e)
{
Expand Down Expand Up @@ -507,11 +519,14 @@ public Order(Dictionary<string, dynamic> data)
public string Status { get; set; }
public string StatusMessage { get; set; }
public string Tag { get; set; }
public List<string> 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<string, dynamic> Meta { get; set; }
}

/// <summary>
Expand Down
27 changes: 27 additions & 0 deletions KiteConnectSample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Trade> trades = kite.GetOrderTrades("1234");
Expand Down
9 changes: 8 additions & 1 deletion KiteConnectTest/KiteTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,14 @@ public void TestOrders()
Kite kite = new Kite("apikey", Root: "http://localhost:8080");
List<Order> 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]
Expand Down
172 changes: 132 additions & 40 deletions KiteConnectTest/responses/orders.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
]
}

0 comments on commit d071a86

Please sign in to comment.