[Python] Why do trading API wrappers often use dictionaries to map user-friendly inputs (.....

Discussão em 'Python' iniciado por Stack, Agosto 18, 2025.

  1. Stack

    Stack Membro Participativo

    I use the following code to place an order:

    from Dhan_Tradehull import Tradehull

    client_code = "110"
    token_id = "eCbXElV9AIPuQ"

    # Initialize Tradehull object (tradehull support library)
    tsl = Tradehull(client_code, token_id)

    # Place an order using the wrapper function, without needing security ID manually
    orderid3 = tsl.order_placement(
    'MONOT', # Trading symbol
    'BSE', # Exchange
    10, # Quantity
    0, # Price
    0, # Trigger price
    'MARKET', # Order type
    'BUY', # Transaction type
    'CNC' # Trade type / product
    )


    In the above code, I am using the Tradehull class defined in Dhan_Tradehull.py. The constructor of Tradehull has a Dhan object of the dhanhq class defined in dhanhq.py.

    Inside Tradehull, the order_placement function is defined like this:

    def order_placement(
    self,
    tradingsymbol: str,
    exchange: str,
    quantity: int,
    price: int,
    trigger_price: int,
    order_type: str,
    transaction_type: str,
    trade_type: str
    ) -> str:

    try:
    script_exchange = {
    "NSE": self.Dhan.NSE,
    "NFO": self.Dhan.NSE_FNO,
    "BFO": self.Dhan.BSE_FNO,
    "CUR": self.Dhan.CUR,
    "BSE": self.Dhan.BSE,
    "MCX": self.Dhan.MCX
    }

    self.order_Type = {
    'LIMIT': self.Dhan.LIMIT,
    'MARKET': self.Dhan.MARKET,
    'STOPLIMIT': self.Dhan.SL,
    'STOPMARKET': self.Dhan.SLM
    }

    product = {
    'MIS': self.Dhan.INTRA,
    'MARGIN': self.Dhan.MARGIN,
    'MTF': self.Dhan.MTF,
    'CO': self.Dhan.CO,
    'BO': self.Dhan.BO,
    'CNC': self.Dhan.CNC
    }

    Validity = {'DAY': "DAY", 'IOC': 'IOC'}
    transactiontype = {'BUY': self.Dhan.BUY, 'SELL': self.Dhan.SELL}
    instrument_exchange = {
    'NSE': "NSE",
    'BSE': "BSE",
    'NFO': 'NSE',
    'BFO': 'BSE',
    'MCX': 'MCX',
    'CUR': 'NSE'
    }

    exchangeSegment = script_exchange[exchange]
    product_Type = product[trade_type.upper()]
    order_type = self.order_Type[order_type.upper()]
    order_side = transactiontype[transaction_type.upper()]
    time_in_force = Validity['DAY']

    # Get security ID from instrument dataframe
    security_id = self.instrument_df[
    ((self.instrument_df['SEM_TRADING_SYMBOL'] == tradingsymbol) |
    (self.instrument_df['SEM_CUSTOM_SYMBOL'] == tradingsymbol)) &
    (self.instrument_df['SEM_EXM_EXCH_ID'] == instrument_exchange[exchange])
    ].iloc[-1]['SEM_SMST_SECURITY_ID']

    # Call Dhan's API wrapper
    order = self.Dhan.place_order(
    security_id=str(security_id),
    exchange_segment=exchangeSegment,
    transaction_type=order_side,
    quantity=quantity,
    order_type=order_type,
    product_type=product_Type,
    price=price,
    trigger_price=trigger_price
    )

    orderid = order["data"]["orderId"]
    return str(orderid)

    except Exception as e:
    self.logger.exception(f'Got exception in place_order: {e}')
    traceback.print_exc()
    return None


    And inside dhanhq.py, the dhanhq class has a place_order function which is called internally.

    def place_order(
    self,
    security_id,
    exchange_segment,
    transaction_type,
    quantity,
    order_type,
    product_type,
    price,
    trigger_price=0,
    disclosed_quantity=0,
    after_market_order=True,
    validity='DAY',
    amo_time='OPEN',
    bo_profit_value=None,
    bo_stop_loss_Value=None,
    tag=None
    ):
    try:
    url = self.base_url + '/orders'
    payload = {
    "dhanClientId": self.client_id,
    "transactionType": transaction_type.upper(),
    "exchangeSegment": exchange_segment.upper(),
    "productType": product_type.upper(),
    "orderType": order_type.upper(),
    "validity": validity.upper(),
    "securityId": security_id,
    "quantity": int(quantity),
    "disclosedQuantity": int(disclosed_quantity),
    "price": float(price),
    "afterMarketOrder": after_market_order,
    "boProfitValue": bo_profit_value,
    "boStopLossValue": bo_stop_loss_Value
    }

    if tag is not None and tag != '':
    payload["correlationId"] = tag

    if after_market_order:
    if amo_time in ['PRE_OPEN', 'OPEN', 'OPEN_30', 'OPEN_60']:
    payload['amoTime'] = amo_time
    else:
    raise Exception("amo_time must be one of ['PRE_OPEN','OPEN','OPEN_30','OPEN_60']")

    if trigger_price > 0:
    payload["triggerPrice"] = float(trigger_price)
    else:
    payload["triggerPrice"] = 0.0

    payload = json_dumps(payload)
    response = self.session.post(url, data=payload, headers=self.header, timeout=self.timeout)
    return self._parse_response(response)

    except Exception as e:
    logging.error('Exception in dhanhq>>place_order: %s', e)
    return {
    'status': 'failure',
    'remarks': str(e),
    'data': '',
    }


    My question:

    I want to ask about these dictionaries inside order_placement, for example:

    product = {
    'MIS': self.Dhan.INTRA,
    'MARGIN': self.Dhan.MARGIN,
    'MTF': self.Dhan.MTF,
    'CO': self.Dhan.CO,
    'BO': self.Dhan.BO,
    'CNC': self.Dhan.CNC
    }


    I want to know the reason why these dictionaries are defined. From what I see, using these dictionaries, they are just converting user inputs into some internal names.


    Is this indeed the case?

    If yes, why is this mapping necessary?

    If not, what is the actual reason for this design?
    ​

    I want to understand the rationale behind defining these dictionaries. Because in my opinion, they seem to be just meant for converting user inputs to internal representations.

    Continue reading...

Compartilhe esta Página