contract – ShinyBroker

# Contract

`Contract(self, contract_params=None)`

All tradable assets – even stocks and currencies – are ‘contracts’. Whether you’re placing a trade order, requesting market data, or searching for details about a particular financial instrument, the `Contract` object is how you specify to Interactive Brokers exactly which asset you’re referring to.

## Parameters

Name | Type | Description | Default
--- | --- | --- | ---
`contract_params` | dict | Dictionary for which each named element defines a contract property. See IBKR’s Contract Management documentation for more examples. | `None`
`contract_params` | str or int | If you pass a single string or an integer, it will be interpreted as `conId` in the resultant `Contract` object. | `None`
`contract_params` | None | Passing `None` (the default) to `Contract()` will return an empty instance of the `Contract` object class that you can manipulate by setting attributes directly. | `None`

## Returns

Type | Description
--- | ---
Contract | A Contract object that IBKR will understand to mean the tradable asset you are referring to.

## “Why Not Just Use Ticker”?

To see why we use a `Contract` object system instead of just referring to an asset by its symbol, pick a common ticker like “AAPL” and search for it using the “Matching Symbols” tool in ShinyBroker. You will quickly note that there are many contracts matching that description available for trading. The `Contract` object system lets you specify which asset you’re interested in by allowing you to pass in additional parameters like secType, currency, exchange.

## Writing & Checking Contract Definitions

As a general rule of thumb, a well-defined `Contract` object uses the minimum number of specified parameters needed to uniquely define one single tradable asset. If you’re unsure whether a `Contract` object you’ve created works, or whether it defines only one unique asset, you can copy-paste your code into the “Contract Details” tool in ShinyBroker. If it returns only one asset, and it’s the asset that you had in mind, then you can be sure your definition is good.

## Contract Id Is Sufficient On Its Own

Every tradable asset at IBKR is given its own unique `conId`, which is the minimum information you need in order to specify that instrument. If you pass a single `int` or `str` object to the `Contract` constructor, then it will be treated as the `conId`.

## Three Ways Of Creating / Updating Contracts

Way 1: Instantiate a contract object and then assign parameters to the attributes as you require:

    from shinybroker import Contract
    aapl_contract = Contract()
    aapl_contract.symbol = "AAPL"
    aapl_contract.secType = "STK"
    aapl_contract.exchange = "SMART"
    aapl_contract.currency = "USD"

Way 2: Pass everything in as a dictionary all at once:

    from shinybroker import Contract
    aapl_contract = Contract({
        'symbol': "AAPL",
        'secType': "STK",
        'exchange': "SMART",
        'currency': "USD"
    })

Way 3: Pass in just the `conId` as a string or integer:

    from shinybroker import Contract
    aapl_contract = Contract(265598)
    aapl_contract = Contract("265598")

## Compact Printing

By default, all instances of the `Contract()` class possess all attributes, but not all attributes are set to something meaningful. To understand this point, run:

    import shinybroker as sb
    aapl_us_stock = sb.Contract()
    aapl_us_stock.symbol = "AAPL"
    aapl_us_stock.secType = "STK"
    aapl_us_stock.exchange = "SMART"
    aapl_us_stock.currency = "USD"
    print(aapl_us_stock)

…and you will see that all parameters are represented in `aapl_us_stock`, but not all the parameters have meaningful, non-empty values (e.g, `strike`, because stocks don’t have a strike price).

To get a clean dictionary containing only the non-empty values, run:

    print(aapl_us_stock.compact())

## Use Compact To Copy Contract Objects

Say you want to create contracts for the put and the call options for a particular strike, expiry, and underlying, so you write a code like this:

    import shinybroker as sb
    goog_call = sb.Contract({
        'symbol': 'GOOG',
        'secType': 'OPT',
        'exchange': 'SMART',
        'currency': 'USD',
        'lastTradeDateOrContractMonth': '20261218',
        'strike': 160,
        'right': 'C',
        'multiplier': '100'
    })
    goog_put = goog_call
    goog_put.right = "P"
    print(goog_call)
    print(goog_put)

If you’re used to Python, you know what’s coming because… mutability. `goog_put` isn’t a true copy of `goog_call`, it’s just a pointer that points to the same value as `goog_call`. Therefore, when you ran `goog_put.right = "P"` you actually set the original value to “P” for “put” for both `goog_put` and `goog_call`.

This inelegant solecism is a feature of Python that one must simply endure. You may, however, accomplish what you’re after by using the `compact()` method on `goog_call` to instantiate a new object as in the modified code below, which correctly declares a put and a call contract as expected:

    import shinybroker as sb
    goog_call = sb.Contract({
        'symbol': 'GOOG',
        'secType': 'OPT',
        'exchange': 'SMART',
        'currency': 'USD',
        'lastTradeDateOrContractMonth': "20261218",
        'strike': 160,
        'right': 'C',
        'multiplier': '100'
    })
    goog_put = sb.Contract(goog_call.compact())
    goog_put.right = "P"
    print(goog_call)
    print(goog_put)

## “So Why Not Always Specify Contracts Using Contract Id Only”?

You can. Go right ahead – you can probably adopt that practice and build apps for quite a while without a problem. However, in some use cases it might be handy for you to NOT have to look up all the `conId`s and, instead, just loop through contract parameters like this:

    for strike in list_of_strikes:
        for expiry in list_of_expiries:
            goog_call = sb.Contract({
                'symbol': 'GOOG',
                'secType': 'OPT',
                'exchange': 'SMART',
                'currency': 'USD',
                'lastTradeDateOrContractMonth': expiry,
                'strike': strike,
                'right': 'C',
                'multiplier': '100'
            })
            goog_put = sb.Contract(goog_call.compact())
            goog_put.right = "P"
            your_super_clever_trading_logic(goog_call, goog_put)