nebsl-b2c-api 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nebsl_b2c_api-1.0.0.dist-info/METADATA +384 -0
- nebsl_b2c_api-1.0.0.dist-info/RECORD +13 -0
- nebsl_b2c_api-1.0.0.dist-info/WHEEL +5 -0
- nebsl_b2c_api-1.0.0.dist-info/top_level.txt +1 -0
- pycloudrestapi/__init__.py +6 -0
- pycloudrestapi/__main__.py +0 -0
- pycloudrestapi/__version__.py +8 -0
- pycloudrestapi/common_methods.py +245 -0
- pycloudrestapi/connect.py +620 -0
- pycloudrestapi/constants.py +270 -0
- pycloudrestapi/logger_config.py +29 -0
- pycloudrestapi/parser.py +498 -0
- pycloudrestapi/utils.py +198 -0
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nebsl-b2c-api
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: The official Python client for the NEBSL B2C REST API
|
|
5
|
+
Author-email: code161263 <code@northeastltd.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/giridhargk/nebslB2C
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.7
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: python-engineio==4.9.0
|
|
14
|
+
Requires-Dist: python-socketio==5.0.1
|
|
15
|
+
Requires-Dist: requests==2.31.0
|
|
16
|
+
Requires-Dist: websockets==12.0
|
|
17
|
+
|
|
18
|
+
# NEBSL REST API Integration Guide
|
|
19
|
+
|
|
20
|
+
> Source documentation: NEBSL Cloud REST API docs
|
|
21
|
+
|
|
22
|
+
## Overview
|
|
23
|
+
|
|
24
|
+
This repository contains a Git-friendly Markdown version of the NEBSL REST API documentation, organized for developers who want a quick implementation reference.
|
|
25
|
+
|
|
26
|
+
Based on the accessible documentation summary, the API supports:
|
|
27
|
+
|
|
28
|
+
- JSON-based requests and responses
|
|
29
|
+
- Data compression
|
|
30
|
+
- Authentication and session-based access
|
|
31
|
+
- Order operations such as:
|
|
32
|
+
- Place Order
|
|
33
|
+
- Modify Order
|
|
34
|
+
- Cancel Order
|
|
35
|
+
- Reports such as:
|
|
36
|
+
- Order Book
|
|
37
|
+
- Trade Book
|
|
38
|
+
- Position
|
|
39
|
+
- Holding
|
|
40
|
+
- Limit
|
|
41
|
+
- Portfolio information management
|
|
42
|
+
- Scrip Master details
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Basic Integration Flow
|
|
47
|
+
|
|
48
|
+
The documentation indicates the following high-level onboarding flow for implementation:
|
|
49
|
+
|
|
50
|
+
1. **Login**
|
|
51
|
+
- Make the login API call using your authorized credentials.
|
|
52
|
+
- Store the returned session/authentication details securely.
|
|
53
|
+
|
|
54
|
+
2. **Maintain Session**
|
|
55
|
+
- Reuse the session or token returned by the login API for subsequent requests.
|
|
56
|
+
- Ensure session validity before making trade or report requests.
|
|
57
|
+
|
|
58
|
+
3. **Call Functional APIs**
|
|
59
|
+
- After successful login, call the required APIs depending on your use case:
|
|
60
|
+
- Order placement
|
|
61
|
+
- Order modification
|
|
62
|
+
- Order cancellation
|
|
63
|
+
- Order book and trade book retrieval
|
|
64
|
+
- Portfolio and holdings retrieval
|
|
65
|
+
- Limits and positions
|
|
66
|
+
- Scrip master and related reference data
|
|
67
|
+
|
|
68
|
+
4. **Handle Standard Response Structure**
|
|
69
|
+
- Parse the API response uniformly.
|
|
70
|
+
- Centralize success/error handling in one place in your application.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Request Conventions
|
|
75
|
+
|
|
76
|
+
From the available documentation summary:
|
|
77
|
+
|
|
78
|
+
- **GET** and **DELETE** request parameters are passed as **query parameters**
|
|
79
|
+
- **POST** and **PUT** request parameters are passed as **JSON body**
|
|
80
|
+
- Content type is expected to be **`application/json`**
|
|
81
|
+
|
|
82
|
+
### Example patterns
|
|
83
|
+
|
|
84
|
+
#### GET
|
|
85
|
+
```http
|
|
86
|
+
GET /api/example?clientCode=ABC123&exchange=NSE
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### POST
|
|
90
|
+
```http
|
|
91
|
+
POST /api/example
|
|
92
|
+
Content-Type: application/json
|
|
93
|
+
|
|
94
|
+
{
|
|
95
|
+
"clientCode": "ABC123",
|
|
96
|
+
"exchange": "NSE"
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Response Structure
|
|
103
|
+
|
|
104
|
+
The published documentation includes a dedicated **Response Structure** section.
|
|
105
|
+
A practical reusable structure for implementation is shown below:
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"status": true,
|
|
110
|
+
"message": "Request processed successfully",
|
|
111
|
+
"data": {}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Recommended handling
|
|
116
|
+
|
|
117
|
+
- `status` → whether the request succeeded
|
|
118
|
+
- `message` → human-readable success or error message
|
|
119
|
+
- `data` → actual payload returned by the API
|
|
120
|
+
|
|
121
|
+
> Exact field names and nested objects may vary by endpoint. Validate each endpoint response during implementation.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Functional Areas
|
|
126
|
+
|
|
127
|
+
## 1. Authentication
|
|
128
|
+
|
|
129
|
+
Used to establish a valid session before accessing trading or reporting APIs.
|
|
130
|
+
|
|
131
|
+
Typical responsibilities:
|
|
132
|
+
|
|
133
|
+
- User login
|
|
134
|
+
- Session generation
|
|
135
|
+
- Session validation
|
|
136
|
+
- Logout or session termination
|
|
137
|
+
|
|
138
|
+
### Implementation notes
|
|
139
|
+
|
|
140
|
+
- Keep secrets out of source control
|
|
141
|
+
- Store session tokens securely
|
|
142
|
+
- Add automatic re-login or refresh handling where needed
|
|
143
|
+
- Centralize auth logic in a dedicated client/service layer
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 2. Order Management
|
|
148
|
+
|
|
149
|
+
The documentation summary explicitly mentions:
|
|
150
|
+
|
|
151
|
+
- **Place Order**
|
|
152
|
+
- **Modify Order**
|
|
153
|
+
- **Cancel Order**
|
|
154
|
+
|
|
155
|
+
### Typical order lifecycle
|
|
156
|
+
|
|
157
|
+
1. Validate session
|
|
158
|
+
2. Build order payload
|
|
159
|
+
3. Submit order
|
|
160
|
+
4. Parse acknowledgement / order reference
|
|
161
|
+
5. Track order status using Order Book or Trade Book APIs
|
|
162
|
+
6. Handle rejects, partial fills, or exchange-side failures
|
|
163
|
+
|
|
164
|
+
### Suggested internal module structure
|
|
165
|
+
|
|
166
|
+
```text
|
|
167
|
+
src/
|
|
168
|
+
api/
|
|
169
|
+
auth_client.*
|
|
170
|
+
order_client.*
|
|
171
|
+
report_client.*
|
|
172
|
+
models/
|
|
173
|
+
auth.*
|
|
174
|
+
order.*
|
|
175
|
+
report.*
|
|
176
|
+
services/
|
|
177
|
+
session_service.*
|
|
178
|
+
order_service.*
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 3. Reports
|
|
184
|
+
|
|
185
|
+
The documentation summary lists the following report categories:
|
|
186
|
+
|
|
187
|
+
- **Order Book**
|
|
188
|
+
- **Trade Book**
|
|
189
|
+
- **Position**
|
|
190
|
+
- **Holding**
|
|
191
|
+
- **Limit**
|
|
192
|
+
|
|
193
|
+
### Common usage
|
|
194
|
+
|
|
195
|
+
- Fetch order history
|
|
196
|
+
- Track completed trades
|
|
197
|
+
- Retrieve live positions
|
|
198
|
+
- Show demat/portfolio holdings
|
|
199
|
+
- Check client trading limits and margins
|
|
200
|
+
|
|
201
|
+
### Recommended implementation pattern
|
|
202
|
+
|
|
203
|
+
- Wrap each report in a dedicated function/service
|
|
204
|
+
- Normalize response mapping into internal DTOs/models
|
|
205
|
+
- Add retry logic for transient failures
|
|
206
|
+
- Log raw responses safely for debugging
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 4. Portfolio Information Management
|
|
211
|
+
|
|
212
|
+
The documentation summary mentions **Portfolio information management**.
|
|
213
|
+
|
|
214
|
+
This usually includes:
|
|
215
|
+
|
|
216
|
+
- Portfolio-level summary retrieval
|
|
217
|
+
- Client asset visibility
|
|
218
|
+
- Security-wise holdings
|
|
219
|
+
- Position and valuation access
|
|
220
|
+
- Investment overview components
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 5. Scrip Master Details
|
|
225
|
+
|
|
226
|
+
The documentation summary mentions **Scrip Master Details**.
|
|
227
|
+
|
|
228
|
+
This is usually used to:
|
|
229
|
+
|
|
230
|
+
- Fetch instrument metadata
|
|
231
|
+
- Resolve symbol/token/security identifiers
|
|
232
|
+
- Validate tradable contracts or scrips
|
|
233
|
+
- Map internal instrument references
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Suggested README Sections for Production Repositories
|
|
238
|
+
|
|
239
|
+
If you are adding this into a Git repository, this structure works well:
|
|
240
|
+
|
|
241
|
+
```md
|
|
242
|
+
# Project Name
|
|
243
|
+
|
|
244
|
+
## Environment Variables
|
|
245
|
+
## Authentication
|
|
246
|
+
## API Endpoints
|
|
247
|
+
## Request/Response Examples
|
|
248
|
+
## Error Handling
|
|
249
|
+
## Retry Strategy
|
|
250
|
+
## Logging
|
|
251
|
+
## Security Notes
|
|
252
|
+
## Testing
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Example API Client Wrapper
|
|
258
|
+
|
|
259
|
+
Below is a generic example in JavaScript/TypeScript style:
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
type ApiResponse<T> = {
|
|
263
|
+
status: boolean;
|
|
264
|
+
message: string;
|
|
265
|
+
data: T;
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
async function apiRequest<T>(
|
|
269
|
+
url: string,
|
|
270
|
+
method: "GET" | "POST" | "PUT" | "DELETE",
|
|
271
|
+
body?: unknown
|
|
272
|
+
): Promise<ApiResponse<T>> {
|
|
273
|
+
const options: RequestInit = {
|
|
274
|
+
method,
|
|
275
|
+
headers: {
|
|
276
|
+
"Content-Type": "application/json"
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
if (body && (method === "POST" || method === "PUT")) {
|
|
281
|
+
options.body = JSON.stringify(body);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const response = await fetch(url, options);
|
|
285
|
+
if (!response.ok) {
|
|
286
|
+
throw new Error(`HTTP ${response.status}`);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return response.json() as Promise<ApiResponse<T>>;
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## Error Handling Recommendations
|
|
296
|
+
|
|
297
|
+
Implement these checks consistently:
|
|
298
|
+
|
|
299
|
+
- HTTP status validation
|
|
300
|
+
- API-level `status` validation
|
|
301
|
+
- Empty `data` handling
|
|
302
|
+
- Unauthorized session handling
|
|
303
|
+
- Timeout and retry handling
|
|
304
|
+
- Structured logs for trading/reporting calls
|
|
305
|
+
|
|
306
|
+
### Suggested categories
|
|
307
|
+
|
|
308
|
+
- Authentication errors
|
|
309
|
+
- Validation errors
|
|
310
|
+
- Business rule failures
|
|
311
|
+
- Exchange/order rejections
|
|
312
|
+
- Network timeouts
|
|
313
|
+
- Server-side internal errors
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Security Recommendations
|
|
318
|
+
|
|
319
|
+
- Never commit credentials to Git
|
|
320
|
+
- Use environment variables or a secret manager
|
|
321
|
+
- Mask client identifiers in logs
|
|
322
|
+
- Encrypt stored session artifacts where required
|
|
323
|
+
- Add rate limiting and retry backoff
|
|
324
|
+
- Keep audit logs for critical trade actions
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Testing Checklist
|
|
329
|
+
|
|
330
|
+
- [ ] Login success flow
|
|
331
|
+
- [ ] Login failure flow
|
|
332
|
+
- [ ] Session expiry flow
|
|
333
|
+
- [ ] Place order success
|
|
334
|
+
- [ ] Place order rejection
|
|
335
|
+
- [ ] Modify order success/failure
|
|
336
|
+
- [ ] Cancel order success/failure
|
|
337
|
+
- [ ] Order Book fetch
|
|
338
|
+
- [ ] Trade Book fetch
|
|
339
|
+
- [ ] Position fetch
|
|
340
|
+
- [ ] Holding fetch
|
|
341
|
+
- [ ] Limit fetch
|
|
342
|
+
- [ ] Invalid request body handling
|
|
343
|
+
- [ ] Network timeout handling
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Repository Usage Example
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
git clone <your-repo-url>
|
|
351
|
+
cd <your-repo>
|
|
352
|
+
cp .env.example .env
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## Important Note
|
|
358
|
+
|
|
359
|
+
This README is a **developer-friendly Markdown conversion based on the publicly visible documentation summary available from the NEBSL REST API page**.
|
|
360
|
+
|
|
361
|
+
During this conversion, the original documentation site was not fully machine-readable from my side, so this file is a **clean implementation README draft**, not a verbatim endpoint-by-endpoint export.
|
|
362
|
+
|
|
363
|
+
For a complete production reference, you should still verify:
|
|
364
|
+
|
|
365
|
+
- Exact endpoint paths
|
|
366
|
+
- Required headers
|
|
367
|
+
- Authentication field names
|
|
368
|
+
- Mandatory request fields
|
|
369
|
+
- Exact response schema for each endpoint
|
|
370
|
+
- Error codes and exchange-specific behaviors
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## Recommended Next Step
|
|
375
|
+
|
|
376
|
+
Use this file as the root `README.md`, then extend it with:
|
|
377
|
+
|
|
378
|
+
- Exact endpoint list
|
|
379
|
+
- Full request/response payload samples
|
|
380
|
+
- Sandbox/production base URLs
|
|
381
|
+
- Authentication headers
|
|
382
|
+
- Error code reference
|
|
383
|
+
- SDK examples for your preferred language
|
|
384
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
pycloudrestapi/__init__.py,sha256=03u6JAKmKsbZZ94IGFid0IMZivJxgXXiNchd6kc2MqI,137
|
|
2
|
+
pycloudrestapi/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
pycloudrestapi/__version__.py,sha256=V2WjhiyycHnU_-9HpTMHTTuwLCVq4M9k0B66duUE0KQ,292
|
|
4
|
+
pycloudrestapi/common_methods.py,sha256=NnkflRNJ1rkiBTyb1CkLAUN_G1gKJSr-aPHqzZmmX90,12126
|
|
5
|
+
pycloudrestapi/connect.py,sha256=MTt4fY-gVUMJNw2xHed77G_BHM4wktXKokrXR5-6d7c,24479
|
|
6
|
+
pycloudrestapi/constants.py,sha256=FriAtrb0rfnf5HWozwDun5mU3nbsbiR_w2ithe0RCBg,7732
|
|
7
|
+
pycloudrestapi/logger_config.py,sha256=9Lumzb8X_pBMcsFYqhexYzzve8_2r9PJkzOrd3sxNqY,913
|
|
8
|
+
pycloudrestapi/parser.py,sha256=sQ63VJLRaeBRmyPw6GfKC76BvL0U3-uaLxH3vs4dyy8,28485
|
|
9
|
+
pycloudrestapi/utils.py,sha256=U-ADIAHOdNhDSeeccRoWq99Yap7hPzYAIgc0D2FfEfo,6282
|
|
10
|
+
nebsl_b2c_api-1.0.0.dist-info/METADATA,sha256=KClLhb3lDvN6kL6qUnW7Br467oyX9t-gQrTVHyGjAnM,8609
|
|
11
|
+
nebsl_b2c_api-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
12
|
+
nebsl_b2c_api-1.0.0.dist-info/top_level.txt,sha256=-c2C4q8uc9ma8xgJEBK7242qZ_-Bsh3q-SfAzVwIunY,15
|
|
13
|
+
nebsl_b2c_api-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pycloudrestapi
|
|
File without changes
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
__title__ = "nebsl-b2c-api"
|
|
2
|
+
__description__ = "The official Python client for the NEBSL B2C REST API"
|
|
3
|
+
__url__ = "https://github.com/giridhargk/nebslB2C"
|
|
4
|
+
__download_url__ = ""
|
|
5
|
+
__version__ = "1.0.0"
|
|
6
|
+
__author__ = "code161263"
|
|
7
|
+
__author_email__ = "code@northeastltd.com"
|
|
8
|
+
__license__ = "MIT"
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
|
|
2
|
+
import time
|
|
3
|
+
import re
|
|
4
|
+
from pycloudrestapi import constants
|
|
5
|
+
from pycloudrestapi.logger_config import logger
|
|
6
|
+
|
|
7
|
+
class CommonMethods:
|
|
8
|
+
def __init__(self, debug):
|
|
9
|
+
self.debug = debug
|
|
10
|
+
|
|
11
|
+
def get_current_time(self):
|
|
12
|
+
return f"{time.strftime('%H:%M:%S')} :"
|
|
13
|
+
|
|
14
|
+
def string_is_null_or_empty(self, data):
|
|
15
|
+
if data is None or data == "":
|
|
16
|
+
return True
|
|
17
|
+
return False
|
|
18
|
+
|
|
19
|
+
def get_date_time(self):
|
|
20
|
+
current_date = time.localtime()
|
|
21
|
+
hr = str(current_date.tm_hour).zfill(2)
|
|
22
|
+
minu = str(current_date.tm_min).zfill(2)
|
|
23
|
+
sec = str(current_date.tm_sec).zfill(2)
|
|
24
|
+
str_time = f"{hr}:{minu}:{sec}"
|
|
25
|
+
return str_time
|
|
26
|
+
|
|
27
|
+
def convert_to_decimal(self, stype, value, decimal_loc):
|
|
28
|
+
return_val = 0
|
|
29
|
+
nfixed = 4 if decimal_loc == 1000 else 2
|
|
30
|
+
try:
|
|
31
|
+
if value > 0:
|
|
32
|
+
if stype == "Price":
|
|
33
|
+
return_val = round(value / decimal_loc, nfixed)
|
|
34
|
+
elif stype == "Percentage":
|
|
35
|
+
return_val = value / decimal_loc
|
|
36
|
+
else:
|
|
37
|
+
return_val = value
|
|
38
|
+
except Exception as error:
|
|
39
|
+
if self.debug:
|
|
40
|
+
logger.error(f"${error}")
|
|
41
|
+
return_val = "0"
|
|
42
|
+
return return_val
|
|
43
|
+
|
|
44
|
+
def get_time_in_seconds(self):
|
|
45
|
+
seconds_since_epoch = round(time.time())
|
|
46
|
+
return seconds_since_epoch
|
|
47
|
+
|
|
48
|
+
def write_console_log(self, data):
|
|
49
|
+
if self.debug:
|
|
50
|
+
logger.error(f"{self.get_current_time()} {data}")
|
|
51
|
+
|
|
52
|
+
def find_value(self, arr_input, str_check_for):
|
|
53
|
+
sval = ""
|
|
54
|
+
try:
|
|
55
|
+
arr_input = "|" + arr_input
|
|
56
|
+
my_reg_exp = re.compile(
|
|
57
|
+
"[^0-9]" + str_check_for.strip() + "[ ]*=[ ]*([^|]*)")
|
|
58
|
+
areg_result = my_reg_exp.search(arr_input)
|
|
59
|
+
if areg_result is not None and areg_result.group(1) != "undefined" and areg_result.group(1) != "":
|
|
60
|
+
sval = areg_result.group(1)
|
|
61
|
+
except Exception as error:
|
|
62
|
+
if self.debug:
|
|
63
|
+
logger.error(f"${error}")
|
|
64
|
+
raise error
|
|
65
|
+
return sval
|
|
66
|
+
|
|
67
|
+
def remove_field_delimiter(self, str_source):
|
|
68
|
+
if str_source.endswith(constants.C_S_FIELD_DELIMITER):
|
|
69
|
+
str_source = str_source[:-1]
|
|
70
|
+
return str_source
|
|
71
|
+
|
|
72
|
+
def look_up(self, str_response):
|
|
73
|
+
lk_up = {}
|
|
74
|
+
try:
|
|
75
|
+
sfield_data = ""
|
|
76
|
+
afield_data = None
|
|
77
|
+
if str_response is not None:
|
|
78
|
+
resp_data = str_response.split(constants.C_S_FIELD_DELIMITER)
|
|
79
|
+
for _, sfield_data in enumerate(resp_data):
|
|
80
|
+
if sfield_data != "undefined":
|
|
81
|
+
afield_data = sfield_data.split(
|
|
82
|
+
constants.C_S_NAMEVALUE_DELIMITER)
|
|
83
|
+
lk_up[afield_data[0]] = afield_data[1]
|
|
84
|
+
except Exception:
|
|
85
|
+
pass
|
|
86
|
+
return lk_up
|
|
87
|
+
|
|
88
|
+
def get_price_formatter(self, str_decimal_locator, int_mkt_seg_id):
|
|
89
|
+
try:
|
|
90
|
+
if int_mkt_seg_id in [constants.C_V_MAPPED_MSX_DERIVATIVES, constants.C_V_MAPPED_MSX_SPOT, constants.C_V_MSX_DERIVATIVES, constants.C_V_MSX_SPOT, constants.C_V_NSX_DERIVATIVES, constants.C_V_NSX_SPOT, constants.C_V_MAPPED_NSX_DERIVATIVES, constants.C_V_MAPPED_NSX_SPOT, constants.C_V_BSECDX_DERIVATIVES, constants.C_V_BSECDX_SPOT, constants.C_V_MAPPED_BSECDX_DERIVATIVES, constants.C_V_MAPPED_BSECDX_SPOT, constants.C_V_MAPPED_MCX_DERIVATIVES]:
|
|
91
|
+
if int_mkt_seg_id == constants.C_V_MAPPED_MCX_DERIVATIVES and str_decimal_locator.strip() == "0":
|
|
92
|
+
str_decimal_locator = "100"
|
|
93
|
+
if str_decimal_locator.strip() == "0":
|
|
94
|
+
str_decimal_locator = "10000"
|
|
95
|
+
if str_decimal_locator == "100":
|
|
96
|
+
return 2
|
|
97
|
+
if str_decimal_locator in ["10000", constants.C_V_NSECDS_DECLOC]:
|
|
98
|
+
return 4
|
|
99
|
+
return 2
|
|
100
|
+
if int_mkt_seg_id in [constants.C_V_MAPPED_BFX_DERIVATIVES, constants.C_V_MAPPED_BFX_SPOT]:
|
|
101
|
+
if str_decimal_locator == "1000":
|
|
102
|
+
return 3
|
|
103
|
+
if str_decimal_locator == "10000":
|
|
104
|
+
return 4
|
|
105
|
+
return 2
|
|
106
|
+
if int_mkt_seg_id in [constants.C_V_MAPPED_MSX_CASH, constants.C_V_MAPPED_MSX_FAO]:
|
|
107
|
+
return self.get_price_forma_from_dec_loc(int(str_decimal_locator))
|
|
108
|
+
if str_decimal_locator is not None and str_decimal_locator != "" and str_decimal_locator != "0":
|
|
109
|
+
return self.get_no_of_zeros(str_decimal_locator)
|
|
110
|
+
return 2
|
|
111
|
+
except Exception as error:
|
|
112
|
+
if self.debug:
|
|
113
|
+
logger.error(f"${error}")
|
|
114
|
+
|
|
115
|
+
def get_mapped_market_segment_id(self, imarket_segment_id):
|
|
116
|
+
imapped_market_segment_id = -1
|
|
117
|
+
try:
|
|
118
|
+
if imarket_segment_id == constants.C_V_NSE_CASH:
|
|
119
|
+
imapped_market_segment_id = constants.C_V_MAPPED_NSE_CASH
|
|
120
|
+
elif imarket_segment_id == constants.C_V_NSE_DERIVATIVES:
|
|
121
|
+
imapped_market_segment_id = constants.C_V_MAPPED_NSE_DERIVATIVES
|
|
122
|
+
elif imarket_segment_id == constants.C_V_BSE_CASH:
|
|
123
|
+
imapped_market_segment_id = constants.C_V_MAPPED_BSE_CASH
|
|
124
|
+
elif imarket_segment_id == constants.C_V_BSE_DERIVATIVES:
|
|
125
|
+
imapped_market_segment_id = constants.C_V_MAPPED_BSE_DERIVATIVES
|
|
126
|
+
elif imarket_segment_id == constants.C_V_MCX_DERIVATIVES:
|
|
127
|
+
imapped_market_segment_id = constants.C_V_MAPPED_MCX_DERIVATIVES
|
|
128
|
+
elif imarket_segment_id == constants.C_V_MCX_SPOT:
|
|
129
|
+
imapped_market_segment_id = constants.C_V_MAPPED_MCX_SPOT
|
|
130
|
+
elif imarket_segment_id == constants.C_V_NCDEX_DERIVATIVES:
|
|
131
|
+
imapped_market_segment_id = constants.C_V_MAPPED_NCDEX_DERIVATIVES
|
|
132
|
+
elif imarket_segment_id == constants.C_V_NCDEX_SPOT:
|
|
133
|
+
imapped_market_segment_id = constants.C_V_MAPPED_NCDEX_SPOT
|
|
134
|
+
elif imarket_segment_id == constants.C_V_NSEL_DERIVATIVES:
|
|
135
|
+
imapped_market_segment_id = constants.C_V_MAPPED_NSEL_DERIVATIVES
|
|
136
|
+
elif imarket_segment_id == constants.C_V_NSEL_SPOT:
|
|
137
|
+
imapped_market_segment_id = constants.C_V_MAPPED_NSEL_SPOT
|
|
138
|
+
elif imarket_segment_id == constants.C_V_MSX_DERIVATIVES:
|
|
139
|
+
imapped_market_segment_id = constants.C_V_MAPPED_MSX_DERIVATIVES
|
|
140
|
+
elif imarket_segment_id == constants.C_V_MSX_SPOT:
|
|
141
|
+
imapped_market_segment_id = constants.C_V_MAPPED_MSX_SPOT
|
|
142
|
+
elif imarket_segment_id == constants.C_V_NSX_DERIVATIVES:
|
|
143
|
+
imapped_market_segment_id = constants.C_V_MAPPED_NSX_DERIVATIVES
|
|
144
|
+
elif imarket_segment_id == constants.C_V_NSX_SPOT:
|
|
145
|
+
imapped_market_segment_id = constants.C_V_MAPPED_NSX_SPOT
|
|
146
|
+
elif imarket_segment_id == constants.C_V_BSECDX_DERIVATIVES:
|
|
147
|
+
imapped_market_segment_id = constants.C_V_MAPPED_BSECDX_DERIVATIVES
|
|
148
|
+
elif imarket_segment_id == constants.C_V_BSECDX_SPOT:
|
|
149
|
+
imapped_market_segment_id = constants.C_V_MAPPED_BSECDX_SPOT
|
|
150
|
+
elif imarket_segment_id == constants.C_V_MSX_CASH:
|
|
151
|
+
imapped_market_segment_id = constants.C_V_MAPPED_MSX_CASH
|
|
152
|
+
elif imarket_segment_id == constants.C_V_MSX_FAO:
|
|
153
|
+
imapped_market_segment_id = constants.C_V_MAPPED_MSX_FAO
|
|
154
|
+
elif imarket_segment_id == constants.C_V_NMCE_DERIVATIVES:
|
|
155
|
+
imapped_market_segment_id = constants.C_V_MAPPED_NMCE_DERIVATIVES
|
|
156
|
+
elif imarket_segment_id == constants.C_V_DSE_CASH:
|
|
157
|
+
imapped_market_segment_id = constants.C_V_MAPPED_DSE_CASH
|
|
158
|
+
elif imarket_segment_id == constants.C_V_UCX_DERIVATIVES:
|
|
159
|
+
imapped_market_segment_id = constants.C_V_MAPPED_UCX_DERIVATIVES
|
|
160
|
+
elif imarket_segment_id == constants.C_V_UCX_SPOT:
|
|
161
|
+
imapped_market_segment_id = constants.C_V_MAPPED_UCX_SPOT
|
|
162
|
+
elif imarket_segment_id == constants.C_V_DGCX_DERIVATIVES:
|
|
163
|
+
imapped_market_segment_id = constants.C_V_MAPPED_DGCX_DERIVATIVES
|
|
164
|
+
elif imarket_segment_id == constants.C_V_DGCX_SPOT:
|
|
165
|
+
imapped_market_segment_id = constants.C_V_MAPPED_DGCX_SPOT
|
|
166
|
+
elif imarket_segment_id == constants.C_V_BFX_DERIVATIVES:
|
|
167
|
+
imapped_market_segment_id = constants.C_V_MAPPED_BFX_DERIVATIVES
|
|
168
|
+
elif imarket_segment_id == constants.C_V_BFX_SPOT:
|
|
169
|
+
imapped_market_segment_id = constants.C_V_MAPPED_BFX_SPOT
|
|
170
|
+
elif imarket_segment_id == constants.C_V_OFS_IPO_BONDS:
|
|
171
|
+
imapped_market_segment_id = constants.C_V_MAPPED_OFS_IPO_BONDS
|
|
172
|
+
else:
|
|
173
|
+
imapped_market_segment_id = -1
|
|
174
|
+
except Exception as error:
|
|
175
|
+
if self.debug:
|
|
176
|
+
logger.error(f"${error}")
|
|
177
|
+
return imapped_market_segment_id
|
|
178
|
+
|
|
179
|
+
def get_no_of_zeros(self, num):
|
|
180
|
+
num = float(num)
|
|
181
|
+
count = 0
|
|
182
|
+
last = 0
|
|
183
|
+
while last == 0:
|
|
184
|
+
last = float(str(num % 10))
|
|
185
|
+
num = num / 10
|
|
186
|
+
count += 1
|
|
187
|
+
return count - 1
|
|
188
|
+
|
|
189
|
+
def parse_ter(self, int_mkt_seg_id, str_ter):
|
|
190
|
+
if int_mkt_seg_id not in [constants.C_V_NSE_DERIVATIVES, constants.C_V_NSX_DERIVATIVES, constants.C_V_MAPPED_NSX_DERIVATIVES]:
|
|
191
|
+
str_ter = ""
|
|
192
|
+
return str_ter
|
|
193
|
+
|
|
194
|
+
def get_price_forma_from_dec_loc(self, idecimal_lc):
|
|
195
|
+
str_format = "2"
|
|
196
|
+
try:
|
|
197
|
+
str_format = str(len(str(idecimal_lc)) - 1)
|
|
198
|
+
except Exception:
|
|
199
|
+
pass
|
|
200
|
+
return int(str_format)
|
|
201
|
+
|
|
202
|
+
# def getPreciseValue(self, strOrgValue, MktSegId, DecimalLocator):
|
|
203
|
+
# strPrecValue = strOrgValue
|
|
204
|
+
# strPrecison = "2" # Default Value as 2 precisions
|
|
205
|
+
# if strOrgValue != "" and float(strOrgValue) > 0:
|
|
206
|
+
# if MktSegId in [constants.C_V_MSX_DERIVATIVES, constants.C_V_MSX_SPOT, constants.C_V_NSX_SPOT, constants.C_V_NSX_DERIVATIVES, constants.C_V_BSECDX_SPOT, constants.C_V_BSECDX_DERIVATIVES]:
|
|
207
|
+
# if MktSegId in [constants.C_V_NSX_SPOT, constants.C_V_BSECDX_SPOT]:
|
|
208
|
+
# if DecimalLocator == 100:
|
|
209
|
+
# strPrecison = "2"
|
|
210
|
+
# else:
|
|
211
|
+
# strPrecison = "4"
|
|
212
|
+
# else:
|
|
213
|
+
# strPrecison = "4"
|
|
214
|
+
# elif MktSegId in [constants.C_V_MCX_SPOT, constants.C_V_NSEL_SPOT, constants.C_V_MCX_DERIVATIVES]:
|
|
215
|
+
# if DecimalLocator == 10000:
|
|
216
|
+
# strPrecison = "4"
|
|
217
|
+
# elif MktSegId in [constants.C_V_MAPPED_BFX_DERIVATIVES, constants.C_V_MAPPED_BFX_SPOT, constants.C_V_BFX_DERIVATIVES, constants.C_V_BFX_SPOT]:
|
|
218
|
+
# if DecimalLocator == 1000:
|
|
219
|
+
# strPrecison = "3"
|
|
220
|
+
# if DecimalLocator == 10000:
|
|
221
|
+
# strPrecison = "4"
|
|
222
|
+
# elif MktSegId in [constants.C_V_MSX_CASH, constants.C_V_MSX_FAO, constants.C_V_MAPPED_MSX_CASH, constants.C_V_MAPPED_MSX_FAO]:
|
|
223
|
+
# strFormat = "2"
|
|
224
|
+
# strFormat = str(len(str(DecimalLocator)) - 1)
|
|
225
|
+
# strPrecison = strFormat
|
|
226
|
+
# strPrecValue = round(float(strOrgValue), int(strPrecison))
|
|
227
|
+
# return strPrecValue
|
|
228
|
+
|
|
229
|
+
def get_date_time_part(self, str_dt):
|
|
230
|
+
if self.trim(str_dt) != "":
|
|
231
|
+
if " " not in str_dt:
|
|
232
|
+
return str_dt
|
|
233
|
+
str_dt = str_dt.split(" ")
|
|
234
|
+
if len(str_dt) == 2:
|
|
235
|
+
if float(str_dt[1]) == 0:
|
|
236
|
+
return ""
|
|
237
|
+
str1 = self.trim(str_dt[1])[:2]
|
|
238
|
+
str2 = self.trim(str_dt[1])[2:4]
|
|
239
|
+
str3 = self.trim(str_dt[1])[4:6]
|
|
240
|
+
return f"{str1}:{str2}:{str3} {str_dt[0]}"
|
|
241
|
+
return ""
|
|
242
|
+
return ""
|
|
243
|
+
|
|
244
|
+
def trim(self, obj_txt_value):
|
|
245
|
+
return str(obj_txt_value).replace(" ", "")
|