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]
class AsthaTradeVortexAPI:
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
AsthaTradeVortexAPI( api_key: str, application_id: str, base_url: str = 'https://vortex.restapi.asthatrade.com', enable_logging: bool = 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".
def login(self, client_code: str, password: str, totp: str) -> dict:
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:

https://vortex.asthatrade.com/docs/authentication/

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

def download_master(self) -> dict:
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

def place_order( self, exchange: vortex_api.Constants.ExchangeTypes, token: int, transaction_type: vortex_api.Constants.TransactionSides, product: vortex_api.Constants.ProductTypes, variety: vortex_api.Constants.VarietyTypes, quantity: int, price: float, trigger_price: float, disclosed_quantity: int, validity: vortex_api.Constants.ValidityTypes) -> dict:
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:

https://vortex.asthatrade.com/docs/order/#placing-an-order

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
def modify_order( self, exchange: vortex_api.Constants.ExchangeTypes, order_id: str, variety: vortex_api.Constants.VarietyTypes, quantity: int, traded_quantity: int, price: float, trigger_price: float, disclosed_quantity: int, validity: vortex_api.Constants.ValidityTypes) -> dict:
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.

def cancel_order( self, exchange: vortex_api.Constants.ExchangeTypes, order_id: str) -> dict:
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:

https://vortex.asthatrade.com/docs/order/#cancel-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 cancel.
Returns:

dict: Dictionary containing the response data from the API.

def orders(self, limit: int, offset: int) -> dict:
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.

def order_history(self, order_id: str) -> dict:
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:

https://vortex.asthatrade.com/docs/order/

Arguments:
  • order_id (str): Order id for which history has to be fetched
Returns:

dict: Dictionary containing the response data from the API.

def positions(self) -> dict:
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.

def holdings(self) -> dict:
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.

def trades(self) -> dict:
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.

def funds(self) -> dict:
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.

def get_order_margin( self, exchange: vortex_api.Constants.ExchangeTypes, token: int, transaction_type: vortex_api.Constants.TransactionSides, product: vortex_api.Constants.ProductTypes, variety: vortex_api.Constants.VarietyTypes, quantity: int, price: float, mode: vortex_api.Constants.OrderMarginModes, old_quantity: int = 0, old_price: float = 0) -> dict:
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
def quotes( self, instruments: list, mode: vortex_api.Constants.QuoteModes) -> dict:
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

def historical_candles( self, exchange: vortex_api.Constants.ExchangeTypes, token: int, to: datetime.datetime, start: datetime.datetime, resolution: vortex_api.Constants.Resolutions):
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

class Constants:
 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

class Constants.ExchangeTypes(builtins.str, enum.Enum):
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

NSE_FO = <ExchangeTypes.NSE_FO: 'NSE_FO'>
NSE_EQUITY = <ExchangeTypes.NSE_EQUITY: 'NSE_EQ'>
NSE_CURRENCY = <ExchangeTypes.NSE_CURRENCY: 'NSE_CD'>
MCX = <ExchangeTypes.MCX: 'MCX_FO'>
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
class Constants.VarietyTypes(builtins.str, enum.Enum):
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

REGULAR_LIMIT_ORDER = <VarietyTypes.REGULAR_LIMIT_ORDER: 'RL'>
REGULAR_MARKET_ORDER = <VarietyTypes.REGULAR_MARKET_ORDER: 'RL-MKT'>
STOP_LIMIT_ORDER = <VarietyTypes.STOP_LIMIT_ORDER: 'SL'>
STOP_MARKET_ORDER = <VarietyTypes.STOP_MARKET_ORDER: 'SL-MKT'>
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
class Constants.ProductTypes(builtins.str, enum.Enum):
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

INTRADAY = <ProductTypes.INTRADAY: 'INTRADAY'>
DELIVERY = <ProductTypes.DELIVERY: 'DELIVERY'>
MTF = <ProductTypes.MTF: 'MTF'>
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
class Constants.ValidityTypes(builtins.str, enum.Enum):
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

FULL_DAY = <ValidityTypes.FULL_DAY: 'DAY'>
IMMEDIATE_OR_CANCEL = <ValidityTypes.IMMEDIATE_OR_CANCEL: 'IOC'>
AFTER_MARKET = <ValidityTypes.AFTER_MARKET: 'AMO'>
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
class Constants.TransactionSides(builtins.str, enum.Enum):
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

BUY = <TransactionSides.BUY: 'BUY'>
SELL = <TransactionSides.SELL: 'SELL'>
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
class Constants.QuoteModes(builtins.str, enum.Enum):
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

LTP = <QuoteModes.LTP: 'ltp'>
FULL = <QuoteModes.FULL: 'full'>
OHLCV = <QuoteModes.OHLCV: 'ohlcv'>
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
class Constants.OrderMarginModes(builtins.str, enum.Enum):
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

NEW_ORDER = <OrderMarginModes.NEW_ORDER: 'NEW'>
MODIFY_ORDER = <OrderMarginModes.MODIFY_ORDER: 'MODIFY'>
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
class Constants.Resolutions(builtins.str, enum.Enum):
 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

MIN_1 = <Resolutions.MIN_1: '1'>
MIN_2 = <Resolutions.MIN_2: '2'>
MIN_3 = <Resolutions.MIN_3: '3'>
MIN_4 = <Resolutions.MIN_4: '4'>
MIN_5 = <Resolutions.MIN_5: '5'>
MIN_10 = <Resolutions.MIN_10: '10'>
MIN_15 = <Resolutions.MIN_15: '15'>
MIN_30 = <Resolutions.MIN_30: '30'>
MIN_45 = <Resolutions.MIN_45: '45'>
MIN_60 = <Resolutions.MIN_60: '60'>
MIN_120 = <Resolutions.MIN_120: '120'>
MIN_180 = <Resolutions.MIN_180: '180'>
MIN_240 = <Resolutions.MIN_240: '240'>
DAY = <Resolutions.DAY: '1D'>
WEEK = <Resolutions.WEEK: '1W'>
MONTH = <Resolutions.MONTH: '1M'>
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
class VortexFeed:

The WebSocket client for connecting to vortex's live price and order streaming service

VortexFeed( access_token: str, websocket_endpoint='wss://wire.asthatrade.com/ws', reconnect=True, reconnect_max_tries=50, reconnect_max_delay=60, connect_timeout=30, debug=False)
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
def connect(self, threaded=False, disable_ssl_verification=False):
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
def is_connected(self):
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.

def close(self, code=None, reason=None):
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.

def stop(self):
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

def stop_retry(self):
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.

def subscribe(self, exchange: str, token: int, mode: str) -> bool:
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
def unsubscribe(self, exchange: str, token: int) -> bool:
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.
def resubscribe(self):
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.