Shoonya API Python Wrapper

repository·master·Indexed 41 days ago

https://github.com/shoonya-dev/shoonyaapi-py

A Python client interface for connecting to the Shoonya Order Management System (OMS) via REST API and WebSockets. It provides programmatic access to place, modify, and cancel orders, retrieve order and trade books, manage holdings and positions, and calculate margin requirements using the span_calculator.

Tokens
8.3K
Snippets
26
Records
39
Agent score
1%

What's inside Shoonya API

  1. Overview of Shoonya API Python Wrapper

    master

    The shoonyaapi-py library is a Python wrapper and connector designed to interface with the Shoonya Order Management System (OMS). It provides programmatic access to both the Shoonya REST API and its WebSocket services.

    For comprehensive details regarding the underlying API endpoints, parameters, and authentication requirements, refer to the official Shoonya API documentation at https://www.shoonya.com/api-documentation.

  2. Authenticate with ShoonyaApiPy

    master

    To use the API, initialize the ShoonyaApiPy class and call the login method with your credentials. You can enable debug logging to inspect the raw requests and responses sent to the server.

    from api_helper import ShoonyaApiPy
    import logging
    
    # enable debug to see request and responses
    logging.basicConfig(level=logging.DEBUG)
    
    api = ShoonyaApiPy()
    
    # credentials
    user        = '< user id>'
    u_pwd       = '< password >'
    factor2     = 'OTP/TOTP'
    vc          = 'vendor code'
    app_key     = 'API key'
    imei        = 'uniq identifier'
    
    ret = api.login(userid=user, password=u_pwd, twoFA=factor2, vendor_code=vc, api_secret=app_key, imei=imei)
    print(ret)
  3. Subscribe to Live Market Data Feeds

    master

    To receive live market updates, you must first connect to the WebSocket using api.start_websocket() and then use the api.subscribe() method.

    Note: Both market data feeds and order updates are received through the same WebSocket connection; you only need to connect once.

    feed_opened = False
    
    def event_handler_feed_update(tick_data):
        print(f"feed update {tick_data}")
    
    def open_callback():
        global feed_opened
        feed_opened = True
    
    # 1. Start the websocket with callbacks
    api.start_websocket(order_update_callback=None, 
                         subscribe_callback=event_handler_feed_update, 
                         socket_open_callback=open_callback)
    
    # 2. Wait for connection to open
    while not feed_opened:
        pass
    
    # 3. Subscribe to tokens (single or list)
    api.subscribe('NSE|13')
    api.subscribe(['NSE|22', 'BSE|522032'])
  4. Retrieve the Trade Book using get_trade_book()

    master

    Call get_trade_book() to get a list of all executed trades for the account. The response is a JSON array of objects containing trade execution details like fill price, fill quantity, and time.

    ret = api.get_trade_book()
    print(ret)
  5. Retrieve the Order Book using get_order_book()

    master

    Call get_order_book() to retrieve a list of all orders placed for the account. The response is a JSON array of objects containing order details such as status, price, quantity, and exchange information.

    ret = api.get_order_book()
    print(ret)
  6. Calculate margin requirements with span_calculator()

    master

    Use the span_calculator(actid, positionlist) method to calculate the margin requirement for a specific list of positions.

    Request Parameters

    • actid: The Account ID (preferably the actual account ID if sending from a post-login screen).
    • pos: An array of JSON objects representing the positions. Each position object must contain:
      • prd: Product (e.g., C, M, H)
      • exch: Exchange (e.g., NFO, CDS, MCX)
      • instname: Instrument name (e.g., FUTSTK, FUTIDX, OPTSTK, FUTCUR)
      • symname: Symbol name (e.g., USDINR, ACC, ABB, NIFTY)
      • exd: Expiry Date in DD-MMM-YYYY format (e.g., 29-DEC-2022)
      • optt: Option Type (CE or PE)
      • strprc: Strike price
      • buyqty: Buy Open Quantity
      • sellqty: Sell Open Quantity
      • netqty: Net traded quantity

    Response Fields

    • stat: Success or failure indication (Ok or Not_Ok).
    • span: The calculated Span value.
    • expo: The Exposure margin.
    • span_trade: Span value calculated ignoring the buyqty and sellqty input fields.
    • expo_trade: Exposure margin calculated ignoring the buyqty and sellqty input fields.
    ret = api.span_calculator(actid, positionlist)
  7. Search for Scrips and Tokens

    master

    Use api.searchscrip() to find the exchange-provided token for a specific scrip or to search for matching scrips using a partial string.

    Naming Conventions for Search Text:

    • Futures: SymbolName + ExpDate + 'F' (e.g., for instruments starting with FUT). Note: For MCX, the 'F' should be ignored.
    • Put Options: SymbolName + ExpDate + 'P' + StrikePrice (for OPT instruments with type PE).
    • Call Options: SymbolName + ExpDate + 'C' + StrikePrice (for OPT instruments with type C).
    # Search for scrips matching 'REL' on NSE
    api.searchscrip(exchange='NSE', searchtext='REL')
  8. Login to the Shoonya API

    master

    Use the login method to connect to the broker. This must be called successfully before any other operations can be performed. For TOTP automation, you can use the pyotp library to generate the required twoFA token.

    Parameters:

    • userid: User Id of the login user.
    • password: Shoonya login password.
    • twoFA: OTP or TOTP generated from the Shoonya app.
    • vendor_code: Vendor code provided by the Noren team.
    • api_secret: Prism Generated API key.
    • imei: MAC address for desktop login, or IMEI for mobile.

    Response: On success, the response contains stat: "Ok" and a susertoken. The susertoken must be sent in the jKey field of subsequent requests and used for WebSocket connections.

    # Example login
    ret = api.login(userid=uid, password=pwd, twoFA=factor2, vendor_code=vc, api_secret=app_key, imei=imei)
  9. Subscribe to market instruments with subscribe()

    master

    Sends a list of instruments to the WebSocket for real-time monitoring.

    Parameters:

    • instruments (list, required): A list of instrument strings in the format [Exchange|Token]. Example: ['NSE|22', 'CDS|1']. You can also subscribe to indices like ['NSE|26000'] (Nifty-50).

    Data Types and Behavior:

    • Touchline (t='tk'): Sent once upon subscription for each instrument containing all current fields. Subsequent updates use t='tf' (touchline field) to send only the specific fields that have changed.
    • Depth (t='dk'): Provides full market depth information.

    Key Fields in Touchline Updates (t='tf'):

    • lp: Last Traded Price (LTP)
    • pc: Percentage change
    • v: Volume
    • ap: Average trade price
    • bp1/sp1: Best Buy Price 1 / Best Sell Price 1
    • bq1/sq1: Best Buy Quantity 1 / Best Sell Quantity 1
    # Example subscription format
    api.subscribe(['NSE|22', 'NSE|26000'])
  10. Convert a position product using position_product_conversion()

    master

    Use position_product_conversion() to change the product type of an existing position (e.g., converting an intraday position to carry forward or vice versa).

    Important: For the tsym (trading symbol) field, use URL encoding to avoid errors with special characters (e.g., M&M should be encoded).

    ret = api.get_positions()
    # converts the first position from existing product to intraday
    p = ret[0]
    ret = api.position_product_conversion(p['exch'], p['tsym'], p['netqty'], 'I', p['prd'], 'B', 'DAY')