Sandbox or paper trading for APIs?

Suppose I’m developing software that will do something related to the orders, positions, fund etc. Now while doing development like you we need some Sandbox version of your APIs so that we can simulate real market scenarios of how things working. This is kind of paper trading for API users.

Do we have something like this?

1 Like

Yess Very Much ,It will very helpful for new learner and for applying any new strategies in live market. pls develop the same.

Hello @Dharmender @Sachin_Chaurasia

Yes, noted this. We have an API playground which is for the same purpose, but will try to add a Sandbox version.

It won’t be possible to have real market scenario, as the same is not allowed as per regulations, but can have something to test for integration testing.

1 Like

@Hardik Any update on this? Is it in your pipeline? It has been many month since you thought of it.

1 Like

Hey @Dharmender

Yes, it is already live: Introducing - DhanHQ Sandbox and DevPortal for API based Traders & Builders!

I’m active in that group.

I tried the sandbox version of API. There is critical bug in it which is rejecting order.

For example: The actual order placed for NIFTY was:

{
	"price": 61.8,
	"boProfitValue": 0.0,
	"boStopLossValue": 0.0,
	"dhanClientId": "xxxxxxx",
	"correlationId": "",
	"transactionType": "BUY",
	"exchangeSegment": "NSE_FNO",
	"productType": "MARGIN",
	"orderType": "LIMIT",
	"validity": "DAY",
	"securityId": "49209",
	"quantity": 75,
	"afterMarketOrder": false
}

But it considered an order for random scrip (if see: tradingSymbol) and rejected it. Example: VOLTAS, RELIANCE etc

 {
    "dhanClientId": "XXXXXXX",
    "orderId": "72250522153231",
    "exchangeOrderId": "0",
    "correlationId": "",
    "orderStatus": "REJECTED",
    "transactionType": "BUY",
    "exchangeSegment": "NSE_FNO",
    "productType": "MARGIN",
    "orderType": "LIMIT",
    "validity": "DAY",
    "tradingSymbol": "VOLTAS-Mar2025-2320-PE",
    "securityId": "49209",
    "quantity": 75,
    "disclosedQuantity": 0,
    "price": 61.15,
    "triggerPrice": 0,
    "afterMarketOrder": false,
    "boProfitValue": 0,
    "boStopLossValue": 0,
    "legName": "NA",
    "createTime": "2025-05-22 14:17:39",
    "updateTime": "2025-05-22 14:17:39",
    "exchangeTime": "0001-01-01 00:00:00",
    "drvExpiryDate": "2025-03-27",
    "drvOptionType": "PUT",
    "drvStrikePrice": 2320,
    "omsErrorCode": "0",
    "omsErrorDescription": "RMS:72250522153231:Order Quantity should be in Multiple of Lot Size",
    "algoId": "0",
    "remainingQuantity": 75,
    "averageTradedPrice": 0,
    "filledQty": 0
  }
{
    "dhanClientId": "XXXXXXX",
    "orderId": "72250522111231",
    "exchangeOrderId": "0",
    "correlationId": "BapOrder",
    "orderStatus": "REJECTED",
    "transactionType": "BUY",
    "exchangeSegment": "NSE_FNO",
    "productType": "MARGIN",
    "orderType": "LIMIT",
    "validity": "DAY",
    "tradingSymbol": "RELIANCE-Mar2025-1620-PE",
    "securityId": "49211",
    "quantity": 75,
    "disclosedQuantity": 0,
    "price": 64.85,
    "triggerPrice": 0,
    "afterMarketOrder": false,
    "boProfitValue": 0,
    "boStopLossValue": 0,
    "legName": "NA",
    "createTime": "2025-05-22 12:17:07",
    "updateTime": "2025-05-22 12:17:07",
    "exchangeTime": "0001-01-01 00:00:00",
    "drvExpiryDate": "2025-03-27",
    "drvOptionType": "PUT",
    "drvStrikePrice": 1620,
    "omsErrorCode": "0",
    "omsErrorDescription": "RMS:72250522111231:Order Quantity should be in Multiple of Lot Size",
    "algoId": "0",
    "remainingQuantity": 75,
    "averageTradedPrice": 0,
    "filledQty": 0
  }
{
    "dhanClientId": "XXXXXX",
    "orderId": "72250521187231",
    "exchangeOrderId": "0",
    "correlationId": "BapOrder",
    "orderStatus": "REJECTED",
    "transactionType": "BUY",
    "exchangeSegment": "NSE_FNO",
    "productType": "MARGIN",
    "orderType": "LIMIT",
    "validity": "DAY",
    "tradingSymbol": "FINNIFTY-Mar2025-27750-PE",
    "securityId": "49225",
    "quantity": 75,
    "disclosedQuantity": 0,
    "price": 132.7,
    "triggerPrice": 0,
    "afterMarketOrder": false,
    "boProfitValue": 0,
    "boStopLossValue": 0,
    "legName": "NA",
    "createTime": "2025-05-21 14:42:37",
    "updateTime": "2025-05-21 14:42:37",
    "exchangeTime": "0001-01-01 00:00:00",
    "drvExpiryDate": "2025-03-27",
    "drvOptionType": "PUT",
    "drvStrikePrice": 27750,
    "omsErrorCode": "0",
    "omsErrorDescription": "RMS:72250521187231:Order Quantity should be in Multiple of Lot Size",
    "algoId": "0",
    "remainingQuantity": 75,
    "averageTradedPrice": 0,
    "filledQty": 0
  }

As you see in above order placed was for NIFTY only But it considered it for random scrip other than NIFTY. Also reason of order rejection was “RMS:72250521187231:Order Quantity should be in Multiple of Lot Size” becuase we don’t for which scrip it is considering the order. Think like we have placed order for particular index but it is taking that for random stock or index for which we haven’t placed. So in result this would reject order because lots size would be different. This is also wrong from integration perspective that if not taking for which index/stock we are placing.

Please fix below BUG in sandbox:

  1. Order must be process/take for which it was actual placed. If order placed for NIFTY then it should be consider NIFTY not other.