Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "upstox-js-sdk",
"version": "2.21.0",
"version": "2.22.0",
"description": "The official Node Js client for communicating with the Upstox API",
"license": "MIT",
"main": "dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion src/ApiClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export class ApiClient {
*/
this.defaultHeaders = {
'X-Upstox-SDK-Language': 'nodejs',
'X-Upstox-SDK-Version': '2.21.0'
'X-Upstox-SDK-Version': '2.22.0'
};

/**
Expand Down
5 changes: 3 additions & 2 deletions src/api/LoginApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ export class LoginApi {
* @param {String} opts.clientId
* @param {String} opts.clientSecret
* @param {String} opts.redirectUri
* @param {String} opts.grantType
* @param {String} opts.grantType
* @param {Boolean} opts.refreshExtendedToken
* @param {module:api/LoginApi~tokenCallback} callback The callback function, accepting three arguments: error, data, response
* data is of type: {@link <&vendorExtensions.x-jsdoc-type>}
*/
Expand All @@ -245,7 +246,7 @@ export class LoginApi {
'Api-Version': apiVersion
};
let formParams = {
'code': opts['code'],'client_id': opts['clientId'],'client_secret': opts['clientSecret'],'redirect_uri': opts['redirectUri'],'grant_type': opts['grantType']
'code': opts['code'],'client_id': opts['clientId'],'client_secret': opts['clientSecret'],'redirect_uri': opts['redirectUri'],'grant_type': opts['grantType'],'refresh_extended_token': opts['refreshExtendedToken']
};

let authNames = [];
Expand Down
2 changes: 2 additions & 0 deletions src/api/OrderApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,8 @@ export class OrderApi {
obj.disclosed_quantity = ApiClient.convertToType(data['disclosedQuantity'], 'Number');
if (data.hasOwnProperty('triggerPrice'))
obj.trigger_price = ApiClient.convertToType(data['triggerPrice'], 'Number');
if (data.hasOwnProperty('marketProtection'))
obj.market_protection = ApiClient.convertToType(data['marketProtection'], 'Number');
}
return obj;
}
Expand Down
8 changes: 7 additions & 1 deletion src/api/OrderControllerV3Api.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ export class OrderApiV3 {
rule.trigger_price = ApiClient.convertToType(userRule['triggerPrice'], 'Number');
if(userRule.hasOwnProperty('trailingGap'))
rule.trailing_gap = ApiClient.convertToType(userRule['trailingGap'], 'Number');
if(userRule.hasOwnProperty('marketProtection'))
rule.market_protection = ApiClient.convertToType(userRule['marketProtection'], 'Number');
obj.rules.push(rule);
});
}
Expand Down Expand Up @@ -301,6 +303,8 @@ export class OrderApiV3 {
obj.disclosed_quantity = ApiClient.convertToType(data['disclosedQuantity'], 'Number');
if (data.hasOwnProperty('triggerPrice'))
obj.trigger_price = ApiClient.convertToType(data['triggerPrice'], 'Number');
if (data.hasOwnProperty('marketProtection'))
obj.market_protection = ApiClient.convertToType(data['marketProtection'], 'Number');
}
return obj;
}
Expand Down Expand Up @@ -382,7 +386,9 @@ export class OrderApiV3 {
if (data.hasOwnProperty('isAmo'))
obj.is_amo = ApiClient.convertToType(data['isAmo'], 'Boolean');
if (data.hasOwnProperty('slice'))
obj.is_amo = ApiClient.convertToType(data['slice'], 'Boolean');
obj.slice = ApiClient.convertToType(data['slice'], 'Boolean');
if (data.hasOwnProperty('marketProtection'))
obj.market_protection = ApiClient.convertToType(data['marketProtection'], 'Number');
}
return obj;
}
Expand Down
8 changes: 8 additions & 0 deletions src/model/GttRule.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export class GttRule {
obj.triggerPrice = ApiClient.convertToType(data['trigger_price'], 'Number');
if (data.hasOwnProperty('trailing_gap'))
obj.trailingGap = ApiClient.convertToType(data['trailing_gap'], 'Number');
if (data.hasOwnProperty('market_protection'))
obj.marketProtection = ApiClient.convertToType(data['market_protection'], 'Number');
}
return obj;
}
Expand Down Expand Up @@ -130,3 +132,9 @@ GttRule.prototype.triggerPrice = undefined;
*/
GttRule.prototype.trailingGap = undefined;

/**
* Optional market price protection for the GTT order rule
* @member {Number} marketProtection
*/
GttRule.prototype.marketProtection = undefined;

8 changes: 8 additions & 0 deletions src/model/MultiOrderRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ export class MultiOrderRequest {
obj.is_amo = ApiClient.convertToType(data['is_amo'], 'Boolean');
if (data.hasOwnProperty('correlation_id'))
obj.correlation_id = ApiClient.convertToType(data['correlation_id'], 'String');
if (data.hasOwnProperty('market_protection'))
obj.market_protection = ApiClient.convertToType(data['market_protection'], 'Number');
}
return obj;
}
Expand Down Expand Up @@ -254,3 +256,9 @@ MultiOrderRequest.prototype.is_amo = undefined;
*/
MultiOrderRequest.prototype.correlation_id = undefined;

/**
* Market price protection (optional). Numeric value.
* @member {Number} market_protection
*/
MultiOrderRequest.prototype.market_protection = undefined;

7 changes: 7 additions & 0 deletions src/model/TokenRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ export class TokenRequest {
obj.redirectUri = ApiClient.convertToType(data['redirect_uri'], 'String');
if (data.hasOwnProperty('grant_type'))
obj.grantType = ApiClient.convertToType(data['grant_type'], 'String');
if (data.hasOwnProperty('refresh_extended_token'))
obj.refreshExtendedToken = ApiClient.convertToType(data['refresh_extended_token'], 'Boolean');
}
return obj;
}
Expand Down Expand Up @@ -92,3 +94,8 @@ TokenRequest.prototype.redirectUri = undefined;
*/
TokenRequest.prototype.grantType = undefined;

/**
* @member {Boolean} refreshExtendedToken
*/
TokenRequest.prototype.refreshExtendedToken = undefined;

170 changes: 170 additions & 0 deletions test/sdk/MarketProtection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/**
* Script-style tests for market_protection support on order APIs.
* Run with: node test/sdk/MarketProtection.js
* Requires a valid access token in test/sdk/DataToken.js.
*/
let UpstoxClient = require('upstox-js-sdk');
const { accessToken } = require('./DataToken');
let defaultClient = UpstoxClient.ApiClient.instance;
let OAUTH2 = defaultClient.authentications['OAUTH2'];
OAUTH2.accessToken = accessToken;

let X_Algo_Name = 'MarketProtectionTest';

// ---------------------------------------------------------------------------
// 1. V3 placeOrder with marketProtection
// ---------------------------------------------------------------------------
function testV3PlaceOrderWithMarketProtection() {
let apiInstance = new UpstoxClient.OrderApiV3();
let body = new UpstoxClient.PlaceOrderV3Request(
1,
UpstoxClient.PlaceOrderV3Request.ProductEnum.D,
UpstoxClient.PlaceOrderV3Request.ValidityEnum.DAY,
0,
'NSE_EQ|INE669E01016',
UpstoxClient.PlaceOrderV3Request.OrderTypeEnum.MARKET,
UpstoxClient.PlaceOrderV3Request.TransactionTypeEnum.BUY,
0,
0,
false
);
body.slice = false;
body.marketProtection = 0;

apiInstance.placeOrder(body, {}, (error, data, response) => {
if (error) {
console.log('V3 placeOrder with marketProtection: error (may be expected if market closed) –', error.response?.text || error.message);
} else {
console.log('V3 placeOrder with marketProtection: success –', JSON.stringify(data));
}
}, X_Algo_Name);
}

// ---------------------------------------------------------------------------
// 2. V3 modifyOrder with marketProtection
// ---------------------------------------------------------------------------
function testV3ModifyOrderWithMarketProtection() {
let apiInstance = new UpstoxClient.OrderApiV3();
let body = new UpstoxClient.ModifyOrderRequest(
UpstoxClient.ModifyOrderRequest.ValidityEnum.DAY,
0,
'REPLACE_WITH_VALID_ORDER_ID',
UpstoxClient.ModifyOrderRequest.OrderTypeEnum.MARKET,
0
);
body.quantity = 1;
body.marketProtection = 0;

apiInstance.modifyOrder(body, (error, data, response) => {
if (error) {
console.log('V3 modifyOrder with marketProtection: error (expected if order_id invalid) –', error.response?.text || error.message);
} else {
console.log('V3 modifyOrder with marketProtection: success –', JSON.stringify(data));
}
}, X_Algo_Name);
}

// ---------------------------------------------------------------------------
// 3. V2 placeMultiOrder with market_protection on orders
// ---------------------------------------------------------------------------
function testV2PlaceMultiOrderWithMarketProtection() {
let apiInstance = new UpstoxClient.OrderApi();
let order1 = new UpstoxClient.MultiOrderRequest(1, 'D', 'DAY', 8.9, true, 'NSE_EQ|INE669E01016', 'LIMIT', 'BUY', 0, 9, true, 'mp_cid1');
order1.tag = 'mp_tg1';
order1.market_protection = 0;

let order2 = new UpstoxClient.MultiOrderRequest(1, 'D', 'DAY', 8.9, true, 'NSE_EQ|INE669E01016', 'LIMIT', 'BUY', 0, 9.0, true, 'mp_cid2');
order2.market_protection = 2;

let body = [order1, order2];

apiInstance.placeMultiOrder(body, (error, data, response) => {
if (error) {
console.log('V2 placeMultiOrder with market_protection: error (may be expected if market closed) –', error.response?.text || error.message);
} else {
console.log('V2 placeMultiOrder with market_protection: success –', JSON.stringify(data));
}
}, X_Algo_Name);
}

// ---------------------------------------------------------------------------
// 4. V3 placeGTTOrder with marketProtection on rule
// ---------------------------------------------------------------------------
function testV3PlaceGTTOrderWithMarketProtection() {
let apiInstance = new UpstoxClient.OrderApiV3();
let entryRule = new UpstoxClient.GttRule(
UpstoxClient.GttRule.StrategyEnum.ENTRY,
UpstoxClient.GttRule.TriggerTypeEnum.ABOVE,
100
);
entryRule.marketProtection = 0;

let body = new UpstoxClient.GttPlaceOrderRequest(
UpstoxClient.GttPlaceOrderRequest.TypeEnum.SINGLE,
1,
UpstoxClient.GttPlaceOrderRequest.ProductEnum.D,
[entryRule],
'NSE_EQ|INE669E01016',
UpstoxClient.GttPlaceOrderRequest.TransactionTypeEnum.BUY
);

apiInstance.placeGTTOrder(body, (error, data, response) => {
if (error) {
console.log('V3 placeGTTOrder with marketProtection: error (may be expected) –', error.response?.text || error.message);
} else {
console.log('V3 placeGTTOrder with marketProtection: success –', JSON.stringify(data));
}
}, X_Algo_Name);
}

// ---------------------------------------------------------------------------
// 5. V3 modifyGTTOrder with marketProtection on rule
// ---------------------------------------------------------------------------
function testV3ModifyGTTOrderWithMarketProtection() {
let apiInstance = new UpstoxClient.OrderApiV3();
let entryRule = new UpstoxClient.GttRule(
UpstoxClient.GttRule.StrategyEnum.ENTRY,
UpstoxClient.GttRule.TriggerTypeEnum.ABOVE,
100
);
entryRule.marketProtection = 0;

let body = new UpstoxClient.GttModifyOrderRequest(
UpstoxClient.GttModifyOrderRequest.TypeEnum.SINGLE,
1,
[entryRule],
'REPLACE_WITH_VALID_GTT_ORDER_ID'
);
body.quantity = 1;

apiInstance.modifyGTTOrder(body, (error, data, response) => {
if (error) {
console.log('V3 modifyGTTOrder with marketProtection: error (expected if gtt_order_id invalid) –', error.response?.text || error.message);
} else {
console.log('V3 modifyGTTOrder with marketProtection: success –', JSON.stringify(data));
}
}, X_Algo_Name);
}

// ---------------------------------------------------------------------------
// Run tests (staggered to avoid rate limits; some calls may fail without live orders)
// ---------------------------------------------------------------------------
console.log('Market protection SDK tests (script-style). Some calls may fail without valid orders/tokens.\n');

testV3PlaceOrderWithMarketProtection();

setTimeout(() => {
testV3ModifyOrderWithMarketProtection();
}, 500);

setTimeout(() => {
testV2PlaceMultiOrderWithMarketProtection();
}, 1000);

setTimeout(() => {
testV3PlaceGTTOrderWithMarketProtection();
}, 1500);

setTimeout(() => {
testV3ModifyGTTOrderWithMarketProtection();
}, 2000);
Loading