vortex_api
Vortex API client for Python -- Visit Api Center. Astha Credit & Securities Pvt. Ltd. (c) 2023
License
AsthaTrade's Vortex Python library is licensed under the MIT License
The library
Vortex APIs are meant for clients who want to execute orders based on their own strategy programatically and for partners to build their own applications. These apis provide a fast and secure way to place trades, manage positions and access real time market data.
The python client provides an abstraction over these APIs in order to seamlessly write applications and atrategies without the hassle of managing the apis.
Getting started
#!python
from vortex_api import AsthaTradeVortexAPI
client = AsthaTradeVortexAPI("your api secret","your application id")
#For client login using TOTP
client.login("client code","client password","totp")
# Place order
client.place_order(client.EXCHANGE_NSE_EQUITY,22,client.TRANSACTION_TYPE_BUY,client.PRODUCT_DELIVERY,client.VARIETY_REGULAR_LIMIT_ORDER,1,1700,0,0,"DAY",1,True)
#Get order book
client.orders(limit=20,offset=1)
1""" 2Vortex API client for Python -- [Visit Api Center](https://vortex.asthatrade.com). 3Astha Credit & Securities Pvt. Ltd. (c) 2023 4 5License 6------- 7AsthaTrade's Vortex Python library is licensed under the MIT License 8 9The library 10----------- 11Vortex APIs are meant for clients who want to execute orders based on their own strategy programatically and for partners to build their own applications. 12These apis provide a fast and secure way to place trades, manage positions and access real time market data. 13 14The python client provides an abstraction over these APIs in order to seamlessly write applications and atrategies without 15the hassle of managing the apis. 16 17Getting started 18--------------- 19 #!python 20 from vortex_api import AsthaTradeVortexAPI 21 22 client = AsthaTradeVortexAPI("your api secret","your application id") 23 24 #For client login using TOTP 25 client.login("client code","client password","totp") 26 27 # Place order 28 29 client.place_order(client.EXCHANGE_NSE_EQUITY,22,client.TRANSACTION_TYPE_BUY,client.PRODUCT_DELIVERY,client.VARIETY_REGULAR_LIMIT_ORDER,1,1700,0,0,"DAY",1,True) 30 31 #Get order book 32 client.orders(limit=20,offset=1) 33 34""" 35from __future__ import unicode_literals, absolute_import 36from vortex_api.api import AsthaTradeVortexAPI,Constants 37from vortex_api.vortex_feed import VortexFeed 38__all__ = [AsthaTradeVortexAPI,Constants,VortexFeed]
150class AsthaTradeVortexAPI: 151 152 def __init__(self, api_key: str, application_id: str, base_url: str = "https://vortex.restapi.asthatrade.com",enable_logging: bool=False) -> None: 153 """ 154 Constructor method for AsthaTradeAPI class. 155 156 Args: 157 api_key (str): API key for the Astha Trade API. 158 api_secret (str): API secret for the Astha Trade API. 159 base_url (str, optional): Base URL for the Astha Trade API. Defaults to "https://vortex.restapi.asthatrade.com". 160 """ 161 self.api_key = api_key 162 self.application_id = application_id 163 self.base_url = base_url 164 self.access_token = None 165 self.enable_logging = enable_logging 166 if self.enable_logging: 167 logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') 168 169 def _make_api_request(self, method: str, endpoint: str, data: dict = None, params=None) -> dict: 170 """ 171 Private method to make HTTP requests to the Astha Trade API. 172 173 Args: 174 method (str): HTTP method for the request (e.g. "GET", "POST", "PUT", "DELETE"). 175 endpoint (str): API endpoint for the request. 176 data (dict, optional): Payload data for the request. Defaults to None. 177 178 Returns: 179 dict: Dictionary containing the response data from the API. 180 """ 181 if(self.access_token == None): 182 op = {} 183 op["status"]= "error" 184 op["message"] = "please login first" 185 return op 186 bearer_token = f"Bearer {self.access_token}" 187 headers = {"Content-Type": "application/json", "Authorization": bearer_token} 188 url = self.base_url + endpoint 189 if self.enable_logging: 190 logging.debug(f"Making network call to {url} , params: {params}, data: {data}, headers: {headers}") 191 response = requests.request(method, url, headers=headers, json=data,params=params) 192 if self.enable_logging: 193 logging.debug(f"Response received from {url} , body: {response.json()}") 194 response.raise_for_status() 195 return response.json() 196 197 def _make_unauth_request(self, method: str, endpoint: str, data: dict = None, params: dict = None) -> dict: 198 """ 199 Private method to make HTTP requests to the Astha Trade API. 200 201 Args: 202 method (str): HTTP method for the request (e.g. "GET", "POST", "PUT", "DELETE"). 203 endpoint (str): API endpoint for the request. 204 data (dict, optional): Payload data for the request. Defaults to None. 205 206 Returns: 207 dict: Dictionary containing the response data from the API. 208 """ 209 headers = {"Content-Type": "application/json", "x-api-key": self.api_key} 210 url = self.base_url + endpoint 211 if self.enable_logging: 212 logging.debug(f"Making network call to {url} , params: {params}, data: {data}, headers: {headers}") 213 response = requests.request(method, url, headers=headers, json=data) 214 response.raise_for_status() 215 if self.enable_logging: 216 logging.debug(f"Response received from {url} , body: {response.json()}") 217 return response.json() 218 219 def login(self, client_code: str, password: str, totp: str)->dict: 220 """ 221 Login using password and totp directly 222 223 Documentation: 224 https://vortex.asthatrade.com/docs/authentication/ 225 226 Args: 227 client_code(str): Client Code of the account 228 password(str): Password of the account 229 totp(str): TOTP generated using third party apps like google authenticator etc. 230 231 Returns: 232 dict: JSON response containing the details of the user 233 """ 234 endpoint = "/user/login" 235 data = { 236 "client_code": client_code, 237 "password": password, 238 "totp": totp, 239 "application_id": self.application_id 240 } 241 res = self._make_unauth_request("POST", endpoint= endpoint, data=data) 242 self._setup_client_code(login_object=res) 243 return res 244 245 def download_master(self) -> dict: 246 """ 247 Download list of all available instruments and their details across all exchanges 248 249 Documentation: 250 https://vortex.asthatrade.com/docs/historical/#fetch-all-instruments 251 252 Returns: 253 dict: CSV Array of all instruments. The first row contains headers 254 """ 255 endpoint = "/data/instruments" 256 bearer_token = f"Bearer {self.access_token}" 257 headers = {"Content-Type": "application/json", "Authorization": bearer_token} 258 with requests.Session() as s: 259 download = s.get(url=self.base_url + endpoint,headers=headers) 260 decoded_content = download.content.decode('utf-8') 261 cr = csv.reader(decoded_content.splitlines(), delimiter=',') 262 my_list = list(cr) 263 return my_list 264 265 def place_order(self,exchange: Constants.ExchangeTypes, token: int, transaction_type: Constants.TransactionSides, product: Constants.ProductTypes, variety: Constants.VarietyTypes, 266 quantity: int, price: float, trigger_price: float, disclosed_quantity: int, validity: Constants.ValidityTypes) -> dict: 267 """ 268 Place an order for a specific security 269 270 Documentation: 271 https://vortex.asthatrade.com/docs/order/#placing-an-order 272 273 Args: 274 exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO] 275 token (int): Security token of the scrip. It can be found in the scripmaster file 276 transaction_type (Constants.TransactionSides): Possible values: [BUY, SELL] 277 product (Constants.ProductTypes): Possible values: [INTRADAY, DELIVERY, MTF]. MTF product can only be used in NSE_EQ exchange. 278 variety (Constants.VarietyTypes): Possible values: [RL, RL-MKT, SL, SL-MKT]. RL means regular orders, SL means Stop Loss order. 279 MKT means that the trade will happen at market price 280 quantity (int): For exchange NSE_FO, if you want to trade in 2 lots and lot size is 50, you should pass 100. 281 In all other exchanges, you should pass just the number of lots. For example, in MCX_FO, 282 if you want to trade 5 lots, you should pass just 5. 283 price (float): Price should be an integer multiple of Tick Size. For example, IDEA's tick size is 0.05. 284 So the price entered can be 9.5 or 9.65. It cannot be 9.67. 285 In case of market orders, you should send the Last Trade Price received from the Quote API or Websocket API 286 trigger_price (float): To be used for Stop loss orders. For BUY side SL orders, trigger_price should be 287 lesser than price. for SELL side SL orders, trigger_price should be greater than price. 288 disclosed_quantity (int): Can be any number lesser than or equal to quantity, including 0 289 validity (Constants.ValidityTypes): Can be DAY for orders which are valid throughout the day, or IOC. 290 IOC order will be cancelled if it is not traded immediately 291 Returns: 292 dict: JSON response containing the details of the placed order 293 294 Raises: 295 HTTPError: If any HTTP error occurs during the API call 296 """ 297 298 endpoint = "/orders/regular" 299 if validity == Constants.ValidityTypes.FULL_DAY: 300 validity_days = 1 301 is_amo = False 302 elif validity == Constants.ValidityTypes.IMMEDIATE_OR_CANCEL: 303 validity_days = 0 304 is_amo = False 305 else: 306 validity_days = 1 307 is_amo = True 308 309 data = { 310 "exchange": exchange, 311 "token": token, 312 "transaction_type": transaction_type, 313 "product": product, 314 "variety": variety, 315 "quantity": quantity, 316 "price": price, 317 "trigger_price": trigger_price, 318 "disclosed_quantity": disclosed_quantity, 319 "validity": validity, 320 "validity_days": validity_days, 321 "is_amo": is_amo 322 } 323 324 return self._make_api_request("POST", endpoint, data=data) 325 326 def modify_order(self,exchange: Constants.ExchangeTypes, order_id: str, variety: Constants.VarietyTypes, quantity: int, traded_quantity: int, price: float, trigger_price: float, disclosed_quantity: int, validity: Constants.ValidityTypes) -> dict: 327 """ 328 Method to modify an order using the Astha Trade API. 329 330 Documentation: 331 https://vortex.asthatrade.com/docs/order/#modifying-an-order 332 333 Args: 334 exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO] 335 order_id (str): The unique ID of the order to modify. 336 variety (Constants.VarietyTypes): Possible values: [RL, RL-MKT, SL, SL-MKT]. RL means regular orders, SL means Stop Loss order. 337 MKT means that the trade will happen at market price 338 quantity (int): The new quantity for the order. 339 traded_quantity (int): The quantity of the order that has already been traded. 340 price (float): The new price for the order. 341 trigger_price (float): The new trigger price for the order. Required for SL and SL-M orders. 342 disclosed_quantity (int): The new quantity to be disclosed publicly. 343 validity (Constants.ValidityTypes): The new validity for the order (e.g. DAY, IOC, GTD). 344 345 Returns: 346 dict: Dictionary containing the response data from the API. 347 """ 348 endpoint = f"/orders/regular/{exchange}/{order_id}" 349 if validity == Constants.ValidityTypes.FULL_DAY: 350 validity_days = 1 351 elif validity == Constants.ValidityTypes.IMMEDIATE_OR_CANCEL: 352 validity_days = 0 353 else: 354 validity_days = 1 355 356 data = { 357 "variety": variety, 358 "quantity": quantity, 359 "traded_quantity": traded_quantity, 360 "price": price, 361 "trigger_price": trigger_price, 362 "disclosed_quantity": disclosed_quantity, 363 "validity": validity, 364 "validity_days": validity_days 365 } 366 return self._make_api_request("PUT", endpoint, data=data) 367 368 def cancel_order(self,exchange: Constants.ExchangeTypes, order_id: str) -> dict: 369 """ 370 Method to cancel an order using the Astha Trade API. 371 372 Documentation: 373 https://vortex.asthatrade.com/docs/order/#cancel-an-order 374 375 Args: 376 exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO] 377 order_id (str): The unique ID of the order to cancel. 378 379 Returns: 380 dict: Dictionary containing the response data from the API. 381 """ 382 383 endpoint = f"/orders/regular/{exchange}/{order_id}" 384 return self._make_api_request("DELETE", endpoint) 385 386 def orders(self,limit: int, offset: int) -> dict: 387 """ 388 Method to get all orders. 389 390 Documentation: 391 https://vortex.asthatrade.com/docs/order/#fetching-order-book 392 393 Args: 394 limit (int): Limit is the number of orders to be fetched. 395 offset (int): Offset should atleast be 1 396 397 Returns: 398 dict: Dictionary containing the response data from the API. 399 """ 400 endpoint = f"/orders?limit={limit}&offset={offset}" 401 return self._make_api_request("GET", endpoint) 402 403 def order_history(self,order_id: str) -> dict: 404 """ 405 Method to get the order history of a particular order 406 407 Documentation: 408 https://vortex.asthatrade.com/docs/order/ 409 410 Args: 411 order_id (str): Order id for which history has to be fetched 412 413 Returns: 414 dict: Dictionary containing the response data from the API. 415 """ 416 endpoint = f"/orders/{order_id}" 417 return self._make_api_request("GET", endpoint) 418 419 def positions(self) -> dict: 420 """ 421 Method to get the position book using the Astha Trade API. 422 423 Documentation: 424 https://vortex.asthatrade.com/docs/positions/#fetch-all-positions 425 426 Returns: 427 dict: Dictionary containing the response data from the API. 428 """ 429 endpoint = f"/portfolio/positions" 430 return self._make_api_request("GET", endpoint) 431 432 def holdings(self) -> dict: 433 """ 434 Method to get the holdings of the user using the Astha Trade API. 435 436 Documentation: 437 https://vortex.asthatrade.com/docs/holdings/ 438 439 Returns: 440 dict: Dictionary containing the response data from the API. 441 """ 442 endpoint = "/portfolio/holdings" 443 return self._make_api_request("GET", endpoint) 444 445 def trades(self) -> dict: 446 """ 447 Method to get today's trades of the user using the Astha Trade API. 448 449 Documentation: 450 https://vortex.asthatrade.com/docs/positions/#get-trades 451 452 Returns: 453 dict: Dictionary containing the response data from the API. 454 """ 455 endpoint = "/trades" 456 return self._make_api_request("GET", endpoint) 457 458 def funds(self) -> dict: 459 """ 460 Method to get the funds of the user using the Astha Trade API. 461 462 Documentation: 463 https://vortex.asthatrade.com/docs/user/#available-funds 464 465 Returns: 466 dict: Dictionary containing the response data from the API. 467 """ 468 endpoint = "/user/funds" 469 return self._make_api_request("GET", endpoint) 470 471 def get_order_margin(self, exchange: Constants.ExchangeTypes, token: int, transaction_type: Constants.TransactionSides, product: Constants.ProductTypes, variety: Constants.VarietyTypes, 472 quantity: int, price: float,mode: Constants.OrderMarginModes, old_quantity: int = 0 , old_price: float = 0 ) -> dict: 473 """ 474 Get the margin required for placing an order for a specific security. 475 476 Documentation: 477 https://vortex.asthatrade.com/docs/margin/#order-margin 478 479 Args: 480 exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO] 481 token (int): Security token of the scrip. It can be found in the scripmaster file 482 transaction_type (Constants.TransactionSides): Possible values: [BUY, SELL] 483 product (Constants.ProductTypes): Possible values: [INTRADAY, DELIVERY, MTF]. MTF product can only be used in NSE_EQ exchange. 484 variety (Constants.VarietyTypes): Possible values: [RL, RL-MKT, SL, SL-MKT]. RL means regular orders, SL means Stop Loss order. 485 MKT means that the trade will happen at market price 486 quantity (int): For exchange NSE_FO, if you want to trade in 2 lots and lot size is 50, you should pass 100. 487 In all other exchanges, you should pass just the number of lots. For example, in MCX_FO, 488 if you want to trade 5 lots, you should pass just 5. 489 price (float): Price should be an integer multiple of Tick Size. For example, IDEA's tick size is 0.05. 490 So the price entered can be 9.5 or 9.65. It cannot be 9.67. 491 In case of market orders, you should send the Last Trade Price received from the Quote API or Websocket API 492 mode (Constants.OrderMarginModes): Possible values: [NEW, MODIFY] , Whether you are trying to modify an existing order or placing a new order. 493 old_quantity (int): For NSE_FO segments, old_quantity is lots * lot_size. For all others, enter just the number of lots. Required if mode is MODIFY 494 old_price (float): Old Price in INR. Required if mode is MODIFY 495 496 Returns: 497 dict: JSON response containing the details of the margin required to place the order 498 499 Raises: 500 HTTPError: If any HTTP error occurs during the API call 501 """ 502 503 endpoint = "/margins/order" 504 505 data = { 506 "exchange": exchange, 507 "token": token, 508 "transaction_type": transaction_type, 509 "product": product, 510 "variety": variety, 511 "quantity": quantity, 512 "price": price, 513 "old_quantity": old_quantity, 514 "old_price": old_price, 515 "mode": mode, 516 } 517 return self._make_api_request("POST", endpoint, data=data) 518 519 def quotes(self, instruments: list, mode: Constants.QuoteModes)-> dict: 520 """ 521 Gets quotes of up to 1000 instruments at a time. 522 523 Documentation: 524 https://vortex.asthatrade.com/docs/historical/#fetch-price-quotes 525 526 Args: 527 instrument(list): List of instruments. The items should be like ( "NSE_EQ-22", "NSE_FO-1234") 528 mode(Constants.QuoteModes): Quote mode. Can be ["ltp","ohlcv", "full"]. LTP quotes just give the last trade price, ohlc give open, high, low, close and volume, full mode also gives depth. 529 530 Returns: 531 dict: JSON response containing quotes. It is possible that not all the symbol identifiers you passed had a quote available. Those inputs will be missing from the response. 532 Also, the order of output might be different than the order of input 533 """ 534 endpoint = "/data/quote" 535 params = {"q": instruments,"mode": mode} 536 return self._make_api_request("GET", endpoint, data=None,params=params) 537 538 def historical_candles(self, exchange: Constants.ExchangeTypes, token: int, to: datetime.datetime , start: datetime.datetime, resolution: Constants.Resolutions): 539 """ 540 Gets historical candle data of a particular instrument. 541 542 Documentation: 543 https://vortex.asthatrade.com/docs/historical/#fetch-historical-candle-data 544 545 Args: 546 exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO] 547 token (int): Security token of the scrip. It can be found in the instruments master file: 548 to (datetime): datetime up till when you want to receive candles 549 start (datetime): datetime from when you want to receive candles 550 resolution (Constants.Resolutions): resoulution of the candle. can be "1", "2", "3", "4", "5", "10", "15", "30", "45", "60", "120", "180", "240", "1D", "1W", "1M" 551 552 Returns: 553 dict: JSON response containing the historical candles 554 """ 555 556 if not isinstance(token, int): 557 raise TypeError("token must be an integer") 558 if not isinstance(to,datetime.datetime): 559 raise TypeError("to must be a datetime") 560 if not isinstance(start,datetime.datetime): 561 raise TypeError("start must be a datetime") 562 563 564 endpoint = "/data/history" 565 params = {"exchange": exchange,"token": token , "to": int(to.timestamp()), "from": int(start.timestamp()), "resolution": resolution} 566 return self._make_api_request("GET", endpoint, data=None,params=params) 567 568 569 def _setup_client_code(self, login_object: dict) -> bool: 570 """ 571 Sets up access token after login 572 573 Args: 574 login_object(dict): Login object received 575 576 Returns: 577 (bool): Whether successful or not 578 """ 579 580 if (('data' in login_object ) and login_object["data"] != None and login_object["data"]["access_token"] != None): 581 self.access_token = login_object["data"]["access_token"] 582 return True 583 584 return False
152 def __init__(self, api_key: str, application_id: str, base_url: str = "https://vortex.restapi.asthatrade.com",enable_logging: bool=False) -> None: 153 """ 154 Constructor method for AsthaTradeAPI class. 155 156 Args: 157 api_key (str): API key for the Astha Trade API. 158 api_secret (str): API secret for the Astha Trade API. 159 base_url (str, optional): Base URL for the Astha Trade API. Defaults to "https://vortex.restapi.asthatrade.com". 160 """ 161 self.api_key = api_key 162 self.application_id = application_id 163 self.base_url = base_url 164 self.access_token = None 165 self.enable_logging = enable_logging 166 if self.enable_logging: 167 logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
Constructor method for AsthaTradeAPI class.
Arguments:
- api_key (str): API key for the Astha Trade API.
- api_secret (str): API secret for the Astha Trade API.
- base_url (str, optional): Base URL for the Astha Trade API. Defaults to "https://vortex.restapi.asthatrade.com".
219 def login(self, client_code: str, password: str, totp: str)->dict: 220 """ 221 Login using password and totp directly 222 223 Documentation: 224 https://vortex.asthatrade.com/docs/authentication/ 225 226 Args: 227 client_code(str): Client Code of the account 228 password(str): Password of the account 229 totp(str): TOTP generated using third party apps like google authenticator etc. 230 231 Returns: 232 dict: JSON response containing the details of the user 233 """ 234 endpoint = "/user/login" 235 data = { 236 "client_code": client_code, 237 "password": password, 238 "totp": totp, 239 "application_id": self.application_id 240 } 241 res = self._make_unauth_request("POST", endpoint= endpoint, data=data) 242 self._setup_client_code(login_object=res) 243 return res
Login using password and totp directly
Documentation:
Arguments:
- client_code(str): Client Code of the account
- password(str): Password of the account
- totp(str): TOTP generated using third party apps like google authenticator etc.
Returns:
dict: JSON response containing the details of the user
245 def download_master(self) -> dict: 246 """ 247 Download list of all available instruments and their details across all exchanges 248 249 Documentation: 250 https://vortex.asthatrade.com/docs/historical/#fetch-all-instruments 251 252 Returns: 253 dict: CSV Array of all instruments. The first row contains headers 254 """ 255 endpoint = "/data/instruments" 256 bearer_token = f"Bearer {self.access_token}" 257 headers = {"Content-Type": "application/json", "Authorization": bearer_token} 258 with requests.Session() as s: 259 download = s.get(url=self.base_url + endpoint,headers=headers) 260 decoded_content = download.content.decode('utf-8') 261 cr = csv.reader(decoded_content.splitlines(), delimiter=',') 262 my_list = list(cr) 263 return my_list
Download list of all available instruments and their details across all exchanges
Documentation:
https://vortex.asthatrade.com/docs/historical/#fetch-all-instruments
Returns:
dict: CSV Array of all instruments. The first row contains headers
265 def place_order(self,exchange: Constants.ExchangeTypes, token: int, transaction_type: Constants.TransactionSides, product: Constants.ProductTypes, variety: Constants.VarietyTypes, 266 quantity: int, price: float, trigger_price: float, disclosed_quantity: int, validity: Constants.ValidityTypes) -> dict: 267 """ 268 Place an order for a specific security 269 270 Documentation: 271 https://vortex.asthatrade.com/docs/order/#placing-an-order 272 273 Args: 274 exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO] 275 token (int): Security token of the scrip. It can be found in the scripmaster file 276 transaction_type (Constants.TransactionSides): Possible values: [BUY, SELL] 277 product (Constants.ProductTypes): Possible values: [INTRADAY, DELIVERY, MTF]. MTF product can only be used in NSE_EQ exchange. 278 variety (Constants.VarietyTypes): Possible values: [RL, RL-MKT, SL, SL-MKT]. RL means regular orders, SL means Stop Loss order. 279 MKT means that the trade will happen at market price 280 quantity (int): For exchange NSE_FO, if you want to trade in 2 lots and lot size is 50, you should pass 100. 281 In all other exchanges, you should pass just the number of lots. For example, in MCX_FO, 282 if you want to trade 5 lots, you should pass just 5. 283 price (float): Price should be an integer multiple of Tick Size. For example, IDEA's tick size is 0.05. 284 So the price entered can be 9.5 or 9.65. It cannot be 9.67. 285 In case of market orders, you should send the Last Trade Price received from the Quote API or Websocket API 286 trigger_price (float): To be used for Stop loss orders. For BUY side SL orders, trigger_price should be 287 lesser than price. for SELL side SL orders, trigger_price should be greater than price. 288 disclosed_quantity (int): Can be any number lesser than or equal to quantity, including 0 289 validity (Constants.ValidityTypes): Can be DAY for orders which are valid throughout the day, or IOC. 290 IOC order will be cancelled if it is not traded immediately 291 Returns: 292 dict: JSON response containing the details of the placed order 293 294 Raises: 295 HTTPError: If any HTTP error occurs during the API call 296 """ 297 298 endpoint = "/orders/regular" 299 if validity == Constants.ValidityTypes.FULL_DAY: 300 validity_days = 1 301 is_amo = False 302 elif validity == Constants.ValidityTypes.IMMEDIATE_OR_CANCEL: 303 validity_days = 0 304 is_amo = False 305 else: 306 validity_days = 1 307 is_amo = True 308 309 data = { 310 "exchange": exchange, 311 "token": token, 312 "transaction_type": transaction_type, 313 "product": product, 314 "variety": variety, 315 "quantity": quantity, 316 "price": price, 317 "trigger_price": trigger_price, 318 "disclosed_quantity": disclosed_quantity, 319 "validity": validity, 320 "validity_days": validity_days, 321 "is_amo": is_amo 322 } 323 324 return self._make_api_request("POST", endpoint, data=data)
Place an order for a specific security
Documentation:
Arguments:
- exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO]
- token (int): Security token of the scrip. It can be found in the scripmaster file
- transaction_type (Constants.TransactionSides): Possible values: [BUY, SELL]
- product (Constants.ProductTypes): Possible values: [INTRADAY, DELIVERY, MTF]. MTF product can only be used in NSE_EQ exchange.
- variety (Constants.VarietyTypes): Possible values: [RL, RL-MKT, SL, SL-MKT]. RL means regular orders, SL means Stop Loss order. MKT means that the trade will happen at market price
- quantity (int): For exchange NSE_FO, if you want to trade in 2 lots and lot size is 50, you should pass 100. In all other exchanges, you should pass just the number of lots. For example, in MCX_FO, if you want to trade 5 lots, you should pass just 5.
- price (float): Price should be an integer multiple of Tick Size. For example, IDEA's tick size is 0.05. So the price entered can be 9.5 or 9.65. It cannot be 9.67. In case of market orders, you should send the Last Trade Price received from the Quote API or Websocket API
- trigger_price (float): To be used for Stop loss orders. For BUY side SL orders, trigger_price should be lesser than price. for SELL side SL orders, trigger_price should be greater than price.
- disclosed_quantity (int): Can be any number lesser than or equal to quantity, including 0
- validity (Constants.ValidityTypes): Can be DAY for orders which are valid throughout the day, or IOC. IOC order will be cancelled if it is not traded immediately
Returns:
dict: JSON response containing the details of the placed order
Raises:
- HTTPError: If any HTTP error occurs during the API call
326 def modify_order(self,exchange: Constants.ExchangeTypes, order_id: str, variety: Constants.VarietyTypes, quantity: int, traded_quantity: int, price: float, trigger_price: float, disclosed_quantity: int, validity: Constants.ValidityTypes) -> dict: 327 """ 328 Method to modify an order using the Astha Trade API. 329 330 Documentation: 331 https://vortex.asthatrade.com/docs/order/#modifying-an-order 332 333 Args: 334 exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO] 335 order_id (str): The unique ID of the order to modify. 336 variety (Constants.VarietyTypes): Possible values: [RL, RL-MKT, SL, SL-MKT]. RL means regular orders, SL means Stop Loss order. 337 MKT means that the trade will happen at market price 338 quantity (int): The new quantity for the order. 339 traded_quantity (int): The quantity of the order that has already been traded. 340 price (float): The new price for the order. 341 trigger_price (float): The new trigger price for the order. Required for SL and SL-M orders. 342 disclosed_quantity (int): The new quantity to be disclosed publicly. 343 validity (Constants.ValidityTypes): The new validity for the order (e.g. DAY, IOC, GTD). 344 345 Returns: 346 dict: Dictionary containing the response data from the API. 347 """ 348 endpoint = f"/orders/regular/{exchange}/{order_id}" 349 if validity == Constants.ValidityTypes.FULL_DAY: 350 validity_days = 1 351 elif validity == Constants.ValidityTypes.IMMEDIATE_OR_CANCEL: 352 validity_days = 0 353 else: 354 validity_days = 1 355 356 data = { 357 "variety": variety, 358 "quantity": quantity, 359 "traded_quantity": traded_quantity, 360 "price": price, 361 "trigger_price": trigger_price, 362 "disclosed_quantity": disclosed_quantity, 363 "validity": validity, 364 "validity_days": validity_days 365 } 366 return self._make_api_request("PUT", endpoint, data=data)
Method to modify an order using the Astha Trade API.
Documentation:
https://vortex.asthatrade.com/docs/order/#modifying-an-order
Arguments:
- exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO]
- order_id (str): The unique ID of the order to modify.
- variety (Constants.VarietyTypes): Possible values: [RL, RL-MKT, SL, SL-MKT]. RL means regular orders, SL means Stop Loss order. MKT means that the trade will happen at market price
- quantity (int): The new quantity for the order.
- traded_quantity (int): The quantity of the order that has already been traded.
- price (float): The new price for the order.
- trigger_price (float): The new trigger price for the order. Required for SL and SL-M orders.
- disclosed_quantity (int): The new quantity to be disclosed publicly.
- validity (Constants.ValidityTypes): The new validity for the order (e.g. DAY, IOC, GTD).
Returns:
dict: Dictionary containing the response data from the API.
368 def cancel_order(self,exchange: Constants.ExchangeTypes, order_id: str) -> dict: 369 """ 370 Method to cancel an order using the Astha Trade API. 371 372 Documentation: 373 https://vortex.asthatrade.com/docs/order/#cancel-an-order 374 375 Args: 376 exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO] 377 order_id (str): The unique ID of the order to cancel. 378 379 Returns: 380 dict: Dictionary containing the response data from the API. 381 """ 382 383 endpoint = f"/orders/regular/{exchange}/{order_id}" 384 return self._make_api_request("DELETE", endpoint)
Method to cancel an order using the Astha Trade API.
Documentation:
Arguments:
- exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO]
- order_id (str): The unique ID of the order to cancel.
Returns:
dict: Dictionary containing the response data from the API.
386 def orders(self,limit: int, offset: int) -> dict: 387 """ 388 Method to get all orders. 389 390 Documentation: 391 https://vortex.asthatrade.com/docs/order/#fetching-order-book 392 393 Args: 394 limit (int): Limit is the number of orders to be fetched. 395 offset (int): Offset should atleast be 1 396 397 Returns: 398 dict: Dictionary containing the response data from the API. 399 """ 400 endpoint = f"/orders?limit={limit}&offset={offset}" 401 return self._make_api_request("GET", endpoint)
Method to get all orders.
Documentation:
https://vortex.asthatrade.com/docs/order/#fetching-order-book
Arguments:
- limit (int): Limit is the number of orders to be fetched.
- offset (int): Offset should atleast be 1
Returns:
dict: Dictionary containing the response data from the API.
403 def order_history(self,order_id: str) -> dict: 404 """ 405 Method to get the order history of a particular order 406 407 Documentation: 408 https://vortex.asthatrade.com/docs/order/ 409 410 Args: 411 order_id (str): Order id for which history has to be fetched 412 413 Returns: 414 dict: Dictionary containing the response data from the API. 415 """ 416 endpoint = f"/orders/{order_id}" 417 return self._make_api_request("GET", endpoint)
Method to get the order history of a particular order
Documentation:
Arguments:
- order_id (str): Order id for which history has to be fetched
Returns:
dict: Dictionary containing the response data from the API.
419 def positions(self) -> dict: 420 """ 421 Method to get the position book using the Astha Trade API. 422 423 Documentation: 424 https://vortex.asthatrade.com/docs/positions/#fetch-all-positions 425 426 Returns: 427 dict: Dictionary containing the response data from the API. 428 """ 429 endpoint = f"/portfolio/positions" 430 return self._make_api_request("GET", endpoint)
Method to get the position book using the Astha Trade API.
Documentation:
https://vortex.asthatrade.com/docs/positions/#fetch-all-positions
Returns:
dict: Dictionary containing the response data from the API.
432 def holdings(self) -> dict: 433 """ 434 Method to get the holdings of the user using the Astha Trade API. 435 436 Documentation: 437 https://vortex.asthatrade.com/docs/holdings/ 438 439 Returns: 440 dict: Dictionary containing the response data from the API. 441 """ 442 endpoint = "/portfolio/holdings" 443 return self._make_api_request("GET", endpoint)
Method to get the holdings of the user using the Astha Trade API.
Documentation:
https://vortex.asthatrade.com/docs/holdings/
Returns:
dict: Dictionary containing the response data from the API.
445 def trades(self) -> dict: 446 """ 447 Method to get today's trades of the user using the Astha Trade API. 448 449 Documentation: 450 https://vortex.asthatrade.com/docs/positions/#get-trades 451 452 Returns: 453 dict: Dictionary containing the response data from the API. 454 """ 455 endpoint = "/trades" 456 return self._make_api_request("GET", endpoint)
Method to get today's trades of the user using the Astha Trade API.
Documentation:
https://vortex.asthatrade.com/docs/positions/#get-trades
Returns:
dict: Dictionary containing the response data from the API.
458 def funds(self) -> dict: 459 """ 460 Method to get the funds of the user using the Astha Trade API. 461 462 Documentation: 463 https://vortex.asthatrade.com/docs/user/#available-funds 464 465 Returns: 466 dict: Dictionary containing the response data from the API. 467 """ 468 endpoint = "/user/funds" 469 return self._make_api_request("GET", endpoint)
Method to get the funds of the user using the Astha Trade API.
Documentation:
https://vortex.asthatrade.com/docs/user/#available-funds
Returns:
dict: Dictionary containing the response data from the API.
471 def get_order_margin(self, exchange: Constants.ExchangeTypes, token: int, transaction_type: Constants.TransactionSides, product: Constants.ProductTypes, variety: Constants.VarietyTypes, 472 quantity: int, price: float,mode: Constants.OrderMarginModes, old_quantity: int = 0 , old_price: float = 0 ) -> dict: 473 """ 474 Get the margin required for placing an order for a specific security. 475 476 Documentation: 477 https://vortex.asthatrade.com/docs/margin/#order-margin 478 479 Args: 480 exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO] 481 token (int): Security token of the scrip. It can be found in the scripmaster file 482 transaction_type (Constants.TransactionSides): Possible values: [BUY, SELL] 483 product (Constants.ProductTypes): Possible values: [INTRADAY, DELIVERY, MTF]. MTF product can only be used in NSE_EQ exchange. 484 variety (Constants.VarietyTypes): Possible values: [RL, RL-MKT, SL, SL-MKT]. RL means regular orders, SL means Stop Loss order. 485 MKT means that the trade will happen at market price 486 quantity (int): For exchange NSE_FO, if you want to trade in 2 lots and lot size is 50, you should pass 100. 487 In all other exchanges, you should pass just the number of lots. For example, in MCX_FO, 488 if you want to trade 5 lots, you should pass just 5. 489 price (float): Price should be an integer multiple of Tick Size. For example, IDEA's tick size is 0.05. 490 So the price entered can be 9.5 or 9.65. It cannot be 9.67. 491 In case of market orders, you should send the Last Trade Price received from the Quote API or Websocket API 492 mode (Constants.OrderMarginModes): Possible values: [NEW, MODIFY] , Whether you are trying to modify an existing order or placing a new order. 493 old_quantity (int): For NSE_FO segments, old_quantity is lots * lot_size. For all others, enter just the number of lots. Required if mode is MODIFY 494 old_price (float): Old Price in INR. Required if mode is MODIFY 495 496 Returns: 497 dict: JSON response containing the details of the margin required to place the order 498 499 Raises: 500 HTTPError: If any HTTP error occurs during the API call 501 """ 502 503 endpoint = "/margins/order" 504 505 data = { 506 "exchange": exchange, 507 "token": token, 508 "transaction_type": transaction_type, 509 "product": product, 510 "variety": variety, 511 "quantity": quantity, 512 "price": price, 513 "old_quantity": old_quantity, 514 "old_price": old_price, 515 "mode": mode, 516 } 517 return self._make_api_request("POST", endpoint, data=data)
Get the margin required for placing an order for a specific security.
Documentation:
https://vortex.asthatrade.com/docs/margin/#order-margin
Arguments:
- exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO]
- token (int): Security token of the scrip. It can be found in the scripmaster file
- transaction_type (Constants.TransactionSides): Possible values: [BUY, SELL]
- product (Constants.ProductTypes): Possible values: [INTRADAY, DELIVERY, MTF]. MTF product can only be used in NSE_EQ exchange.
- variety (Constants.VarietyTypes): Possible values: [RL, RL-MKT, SL, SL-MKT]. RL means regular orders, SL means Stop Loss order. MKT means that the trade will happen at market price
- quantity (int): For exchange NSE_FO, if you want to trade in 2 lots and lot size is 50, you should pass 100. In all other exchanges, you should pass just the number of lots. For example, in MCX_FO, if you want to trade 5 lots, you should pass just 5.
- price (float): Price should be an integer multiple of Tick Size. For example, IDEA's tick size is 0.05. So the price entered can be 9.5 or 9.65. It cannot be 9.67. In case of market orders, you should send the Last Trade Price received from the Quote API or Websocket API
- mode (Constants.OrderMarginModes): Possible values: [NEW, MODIFY] , Whether you are trying to modify an existing order or placing a new order.
- old_quantity (int): For NSE_FO segments, old_quantity is lots * lot_size. For all others, enter just the number of lots. Required if mode is MODIFY
- old_price (float): Old Price in INR. Required if mode is MODIFY
Returns:
dict: JSON response containing the details of the margin required to place the order
Raises:
- HTTPError: If any HTTP error occurs during the API call
519 def quotes(self, instruments: list, mode: Constants.QuoteModes)-> dict: 520 """ 521 Gets quotes of up to 1000 instruments at a time. 522 523 Documentation: 524 https://vortex.asthatrade.com/docs/historical/#fetch-price-quotes 525 526 Args: 527 instrument(list): List of instruments. The items should be like ( "NSE_EQ-22", "NSE_FO-1234") 528 mode(Constants.QuoteModes): Quote mode. Can be ["ltp","ohlcv", "full"]. LTP quotes just give the last trade price, ohlc give open, high, low, close and volume, full mode also gives depth. 529 530 Returns: 531 dict: JSON response containing quotes. It is possible that not all the symbol identifiers you passed had a quote available. Those inputs will be missing from the response. 532 Also, the order of output might be different than the order of input 533 """ 534 endpoint = "/data/quote" 535 params = {"q": instruments,"mode": mode} 536 return self._make_api_request("GET", endpoint, data=None,params=params)
Gets quotes of up to 1000 instruments at a time.
Documentation:
https://vortex.asthatrade.com/docs/historical/#fetch-price-quotes
Arguments:
- instrument(list): List of instruments. The items should be like ( "NSE_EQ-22", "NSE_FO-1234")
- mode(Constants.QuoteModes): Quote mode. Can be ["ltp","ohlcv", "full"]. LTP quotes just give the last trade price, ohlc give open, high, low, close and volume, full mode also gives depth.
Returns:
dict: JSON response containing quotes. It is possible that not all the symbol identifiers you passed had a quote available. Those inputs will be missing from the response. Also, the order of output might be different than the order of input
538 def historical_candles(self, exchange: Constants.ExchangeTypes, token: int, to: datetime.datetime , start: datetime.datetime, resolution: Constants.Resolutions): 539 """ 540 Gets historical candle data of a particular instrument. 541 542 Documentation: 543 https://vortex.asthatrade.com/docs/historical/#fetch-historical-candle-data 544 545 Args: 546 exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO] 547 token (int): Security token of the scrip. It can be found in the instruments master file: 548 to (datetime): datetime up till when you want to receive candles 549 start (datetime): datetime from when you want to receive candles 550 resolution (Constants.Resolutions): resoulution of the candle. can be "1", "2", "3", "4", "5", "10", "15", "30", "45", "60", "120", "180", "240", "1D", "1W", "1M" 551 552 Returns: 553 dict: JSON response containing the historical candles 554 """ 555 556 if not isinstance(token, int): 557 raise TypeError("token must be an integer") 558 if not isinstance(to,datetime.datetime): 559 raise TypeError("to must be a datetime") 560 if not isinstance(start,datetime.datetime): 561 raise TypeError("start must be a datetime") 562 563 564 endpoint = "/data/history" 565 params = {"exchange": exchange,"token": token , "to": int(to.timestamp()), "from": int(start.timestamp()), "resolution": resolution} 566 return self._make_api_request("GET", endpoint, data=None,params=params)
Gets historical candle data of a particular instrument.
Documentation:
https://vortex.asthatrade.com/docs/historical/#fetch-historical-candle-data
Arguments:
- exchange (Constants.ExchangeTypes): Possible values: [NSE_EQ, NSE_FO, NSE_CD or MCX_FO]
- token (int): Security token of the scrip. It can be found in the instruments master file:
- to (datetime): datetime up till when you want to receive candles
- start (datetime): datetime from when you want to receive candles
- resolution (Constants.Resolutions): resoulution of the candle. can be "1", "2", "3", "4", "5", "10", "15", "30", "45", "60", "120", "180", "240", "1D", "1W", "1M"
Returns:
dict: JSON response containing the historical candles
10class Constants: 11 """ 12 Constants used in the API 13 """ 14 class ExchangeTypes(str,Enum): 15 """ 16 Constants for exchanges 17 """ 18 NSE_FO = "NSE_FO" 19 NSE_EQUITY = "NSE_EQ" 20 NSE_CURRENCY = "NSE_CD" 21 MCX = "MCX_FO" 22 23 def __str__(self): 24 return str(self.value) 25 class VarietyTypes(str,Enum): 26 """ 27 Constants for varieties 28 """ 29 REGULAR_LIMIT_ORDER = "RL" 30 REGULAR_MARKET_ORDER = "RL-MKT" 31 STOP_LIMIT_ORDER = "SL" 32 STOP_MARKET_ORDER = "SL-MKT" 33 34 def __str__(self): 35 return str(self.value) 36 class ProductTypes(str,Enum): 37 """ 38 Constants for product types 39 """ 40 INTRADAY = "INTRADAY" 41 DELIVERY = "DELIVERY" 42 MTF = "MTF" 43 44 def __str__(self): 45 return str(self.value) 46 class ValidityTypes(str,Enum): 47 """ 48 Constants for validity types 49 """ 50 FULL_DAY = "DAY" 51 IMMEDIATE_OR_CANCEL = "IOC" 52 AFTER_MARKET = "AMO" 53 54 def __str__(self): 55 return str(self.value) 56 class TransactionSides(str,Enum): 57 """ 58 Constants for transaction sides 59 """ 60 BUY = "BUY" 61 SELL = "SELL" 62 def __str__(self): 63 return str(self.value) 64 class QuoteModes(str,Enum): 65 """ 66 Constants for quote modes 67 """ 68 LTP = "ltp" 69 FULL = "full" 70 OHLCV = "ohlcv" 71 def __str__(self): 72 return str(self.value) 73 class OrderMarginModes(str,Enum): 74 """ 75 Constants for order margin modes 76 """ 77 NEW_ORDER = "NEW" 78 MODIFY_ORDER = "MODIFY" 79 80 def __str__(self): 81 return str(self.value) 82 class Resolutions(str,Enum): 83 """ 84 Constants for resolutions 85 """ 86 MIN_1 = "1" 87 MIN_2 = "2" 88 MIN_3 = "3" 89 MIN_4 = "4" 90 MIN_5 = "5" 91 MIN_10 = "10" 92 MIN_15 = "15" 93 MIN_30 = "30" 94 MIN_45 = "45" 95 MIN_60 = "60" 96 MIN_120 = "120" 97 MIN_180 = "180" 98 MIN_240 = "240" 99 DAY = "1D" 100 WEEK = "1W" 101 MONTH = "1M" 102 103 def __str__(self): 104 return str(self.value)
Constants used in the API
14 class ExchangeTypes(str,Enum): 15 """ 16 Constants for exchanges 17 """ 18 NSE_FO = "NSE_FO" 19 NSE_EQUITY = "NSE_EQ" 20 NSE_CURRENCY = "NSE_CD" 21 MCX = "MCX_FO" 22 23 def __str__(self): 24 return str(self.value)
Constants for exchanges
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
25 class VarietyTypes(str,Enum): 26 """ 27 Constants for varieties 28 """ 29 REGULAR_LIMIT_ORDER = "RL" 30 REGULAR_MARKET_ORDER = "RL-MKT" 31 STOP_LIMIT_ORDER = "SL" 32 STOP_MARKET_ORDER = "SL-MKT" 33 34 def __str__(self): 35 return str(self.value)
Constants for varieties
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
36 class ProductTypes(str,Enum): 37 """ 38 Constants for product types 39 """ 40 INTRADAY = "INTRADAY" 41 DELIVERY = "DELIVERY" 42 MTF = "MTF" 43 44 def __str__(self): 45 return str(self.value)
Constants for product types
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
46 class ValidityTypes(str,Enum): 47 """ 48 Constants for validity types 49 """ 50 FULL_DAY = "DAY" 51 IMMEDIATE_OR_CANCEL = "IOC" 52 AFTER_MARKET = "AMO" 53 54 def __str__(self): 55 return str(self.value)
Constants for validity types
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
56 class TransactionSides(str,Enum): 57 """ 58 Constants for transaction sides 59 """ 60 BUY = "BUY" 61 SELL = "SELL" 62 def __str__(self): 63 return str(self.value)
Constants for transaction sides
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
64 class QuoteModes(str,Enum): 65 """ 66 Constants for quote modes 67 """ 68 LTP = "ltp" 69 FULL = "full" 70 OHLCV = "ohlcv" 71 def __str__(self): 72 return str(self.value)
Constants for quote modes
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
73 class OrderMarginModes(str,Enum): 74 """ 75 Constants for order margin modes 76 """ 77 NEW_ORDER = "NEW" 78 MODIFY_ORDER = "MODIFY" 79 80 def __str__(self): 81 return str(self.value)
Constants for order margin modes
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
82 class Resolutions(str,Enum): 83 """ 84 Constants for resolutions 85 """ 86 MIN_1 = "1" 87 MIN_2 = "2" 88 MIN_3 = "3" 89 MIN_4 = "4" 90 MIN_5 = "5" 91 MIN_10 = "10" 92 MIN_15 = "15" 93 MIN_30 = "30" 94 MIN_45 = "45" 95 MIN_60 = "60" 96 MIN_120 = "120" 97 MIN_180 = "180" 98 MIN_240 = "240" 99 DAY = "1D" 100 WEEK = "1W" 101 MONTH = "1M" 102 103 def __str__(self): 104 return str(self.value)
Constants for resolutions
Inherited Members
- enum.Enum
- name
- value
- builtins.str
- encode
- replace
- split
- rsplit
- join
- capitalize
- casefold
- title
- center
- count
- expandtabs
- find
- partition
- index
- ljust
- lower
- lstrip
- rfind
- rindex
- rjust
- rstrip
- rpartition
- splitlines
- strip
- swapcase
- translate
- upper
- startswith
- endswith
- isascii
- islower
- isupper
- istitle
- isspace
- isdecimal
- isdigit
- isnumeric
- isalpha
- isalnum
- isidentifier
- isprintable
- zfill
- format
- format_map
- maketrans
The WebSocket client for connecting to vortex's live price and order streaming service
238 def __init__(self, access_token: str, websocket_endpoint="wss://wire.asthatrade.com/ws",reconnect=True, reconnect_max_tries=RECONNECT_MAX_TRIES, reconnect_max_delay=RECONNECT_MAX_DELAY, 239 connect_timeout=CONNECT_TIMEOUT, debug = False) -> None: 240 self._maximum_reconnect_max_tries = self.RECONNECT_MAX_TRIES 241 self._minimum_reconnect_max_delay = 0 242 if reconnect == False: 243 self.reconnect_max_tries = 0 244 elif reconnect_max_tries > self._maximum_reconnect_max_tries: 245 log.warning("`reconnect_max_tries` can not be more than {val}. Setting to highest possible value - {val}.".format( 246 val=self._maximum_reconnect_max_tries)) 247 self.reconnect_max_tries = self._maximum_reconnect_max_tries 248 else: 249 self.reconnect_max_tries = reconnect_max_tries 250 251 if reconnect_max_delay < self._minimum_reconnect_max_delay: 252 log.warning("`reconnect_max_delay` can not be less than {val}. Setting to lowest possible value - {val}.".format( 253 val=self._minimum_reconnect_max_delay)) 254 self.reconnect_max_delay = self._minimum_reconnect_max_delay 255 else: 256 self.reconnect_max_delay = reconnect_max_delay 257 258 self.connect_timeout = connect_timeout 259 self.socket_url = websocket_endpoint+"?auth_token="+access_token 260 self.access_token = access_token 261 self.socket_token = self.__getSocketToken__(self.access_token) 262 263 self.debug = debug 264 # self.on_price_update = None 265 self.on_price_update = None 266 self.on_open = None 267 self.on_close = None 268 self.on_error = None 269 self.on_connect = None 270 self.on_message = None 271 self.on_reconnect = None 272 self.on_noreconnect = None 273 self.on_order_update = None 274 self.subscribed_tokens = {} 275 pass
299 def connect(self, threaded=False, disable_ssl_verification=False): 300 """ 301 Establish a websocket connection. 302 - `disable_ssl_verification` disables building ssl context 303 """ 304 # Init WebSocket client factory 305 self._create_connection(self.socket_url, 306 useragent=self._user_agent()) 307 308 # Set SSL context 309 context_factory = None 310 if self.factory.isSecure and not disable_ssl_verification: 311 context_factory = ssl.ClientContextFactory() 312 313 # Establish WebSocket connection to a server 314 connectWS(self.factory, contextFactory=context_factory, timeout=self.connect_timeout) 315 316 if self.debug: 317 twisted_log.startLogging(sys.stdout) 318 319 # Run in seperate thread of blocking 320 opts = {} 321 # Run when reactor is not running 322 if not reactor.running: 323 if threaded: 324 # Signals are not allowed in non main thread by twisted so suppress it. 325 opts["installSignalHandlers"] = False 326 self.websocket_thread = threading.Thread(target=reactor.run, kwargs=opts) 327 self.websocket_thread.daemon = True 328 self.websocket_thread.start() 329 else: 330 reactor.run(**opts) 331 else: 332 print(reactor.running)
Establish a websocket connection.
disable_ssl_verification
disables building ssl context
334 def is_connected(self): 335 """Check if WebSocket connection is established.""" 336 if self.ws and self.ws.state == self.ws.STATE_OPEN: 337 return True 338 else: 339 return False
Check if WebSocket connection is established.
346 def close(self, code=None, reason=None): 347 """Close the WebSocket connection.""" 348 self.stop_retry() 349 self._close(code, reason)
Close the WebSocket connection.
351 def stop(self): 352 """Stop the event loop. Should be used if main thread has to be closed in `on_close` method. 353 Reconnection mechanism cannot happen past this method 354 """ 355 reactor.stop()
Stop the event loop. Should be used if main thread has to be closed in on_close
method.
Reconnection mechanism cannot happen past this method
357 def stop_retry(self): 358 """Stop auto retry when it is in progress.""" 359 if self.factory: 360 self.factory.stopTrying()
Stop auto retry when it is in progress.
362 def subscribe(self, exchange: str,token: int,mode: str)->bool: 363 """ 364 Subscribe to a list of instrument_tokens. 365 - `instrument_tokens` is list of instrument instrument_tokens to subscribe 366 """ 367 try: 368 self.ws.sendMessage(six.b(json.dumps({"message_type": self._message_subscribe, "exchange": exchange,"token": token,"mode": mode}))) 369 370 try: 371 self.subscribed_tokens[exchange][token] = mode 372 except KeyError: 373 self.subscribed_tokens[exchange] = {} 374 self.subscribed_tokens[exchange][token] = mode 375 376 return True 377 except Exception as e: 378 self._close(reason="Error while subscribe: {}".format(str(e))) 379 raise
Subscribe to a list of instrument_tokens.
instrument_tokens
is list of instrument instrument_tokens to subscribe
381 def unsubscribe(self, exchange: str,token: int)->bool: 382 """ 383 Unsubscribe the given list of instrument_tokens. 384 - `instrument_tokens` is list of instrument_tokens to unsubscribe. 385 """ 386 try: 387 self.ws.sendMessage(six.b(json.dumps({"message_type": self._message_unsubscribe, "exchange": exchange,"token": token}))) 388 389 try: 390 del(self.subscribed_tokens[exchange][token]) 391 except KeyError: 392 pass 393 394 return True 395 except Exception as e: 396 self._close(reason="Error while unsubscribe: {}".format(str(e))) 397 raise
Unsubscribe the given list of instrument_tokens.
instrument_tokens
is list of instrument_tokens to unsubscribe.
399 def resubscribe(self): 400 """Resubscribe to all current subscribed tokens.""" 401 modes = {} 402 403 for exchange in self.subscribed_tokens: 404 for token in self.subscribed_tokens[exchange]: 405 self.subscribe(exchange=exchange, token=token,mode=self.subscribed_tokens[exchange][token])
Resubscribe to all current subscribed tokens.