---
title: "Security Identifiers"
description: "We implemented Symbol objects in the LEAN open-source project as a way to identify or \"finger-print\" tradable assets so that no further database look-up is required."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/security-identifiers
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/security-identifiers.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/01%20Key%20Concepts/06%20Security%20Identifiers
modified: 2026-10-29
index: https://www.quantconnect.com/llms.txt
---

# Security Identifiers

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Writing Algorithms](https://www.quantconnect.com/docs/v2/writing-algorithms.md) > Key Concepts > Security Identifiers

> Code examples are shown in Python. Append `?lang=csharp` to this URL for the C# version of this page.

## Introduction

We implemented `Symbol` objects in the LEAN open-source project as a way to identify or "finger-print" tradable assets so that no further database look-up is required. All QuantConnect and LEAN Algorithm API methods use `Symbol` objects to identify assets.

## Encoding Symbols

`SecurityIdentifier` objects have several public properties to uniquely identify each asset. The following table describes these properties:

| Property | Data Type | Description |
| --- | --- | --- |
| `market` | `str` | The market in which the asset trades |
| `security_type` | `SecurityType` | The asset class |
| `option_style` | `OptionStyle` | American or European Option style |
| `option_right` | `OptionRight` | Call or put Option type |
| `strike_price` | `float` | The Option contract strike price |
| `date` | `datetime` | Earliest listing date for Equities; expiry for Futures and Options; December 30, 1899 for continuous Futures contracts and Indices. |
| `has_underlying` | `bool` | A flag to represent if its a derivative asset with another underlying asset |

We encode the preceding properties to create `Symbol` objects. We do our best to hide the details of this process from your algorithm, but you'll occasionally see it come through as an encoded hash like `AAPL R735QTJ8XC9X`. The first half of the encoded string represents the first ticker AAPL was listed under. The other letters at the end of the string represent the serialized form of the preceding `SecurityIdentifier` properties. You may also see an encoded has like `AAPL XL7X5I241SO6|AAPL R735QTJ8XC9X` for a derivative contract. In this case, the part before the `|` is contract hash and the part after the `|` is the underlying hash. This serialization approach lets LEAN assign a short, unique string to octillions of different security objects.

![Security identifier decomposition](https://cdn.quantconnect.com/docs/i/symbol-encoding-examples_rev0.png)

LEAN assumes the ticker you pass to the [add_equity](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/us-equity/requesting-data.md#02-Create-Subscriptions) method is the current ticker of the Equity asset. To access this ticker, use the `value` property of the `Symbol` object.

```python
# Add equity for "GOOG" and print symbol id value, symbol value and encoded symbol id.
self._symbol = self.add_equity("GOOG").symbol
self.debug(self._symbol.id.value) # Prints "GOOCV"
self.debug(self._symbol.value)    # Prints "GOOG"
self.debug(str(self._symbol.id))  # Prints "GOOCV VP83T1ZUHROL"
```

If you create the security subscription with a [universe selection](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/equity.md) function, the `value` property of the `Symbol` object is the point-in-time ticker.

## Decoding Symbols

When a `SecurityIdentifier` is serialized to a string, it looks something like `SPY R735QTJ8XC9X`. This two-part string is a base64 encoded set of data. Encoding all of the properties into a short format allows dense communication without requiring a third-party list or look-up. Most of the time, you will not need to work with these encoded strings. However, to deserialize the string into a `Symbol` object, call the `symbol` method.

```python
# Extract the market, security type, and value from the symbol with ID "GOOCV VP83T1ZUHROL".
symbol = self.symbol("GOOCV VP83T1ZUHROL")
symbol.id.market      # => "USA"
symbol.security_type  # => SecurityType.EQUITY
symbol.value          # => "GOOCV"
```

## Tickers

**Tickers** are a string shortcode representation for an asset. Some examples of popular tickers include "AAPL" for Apple Corporation and "IBM" for International Business Machines Corporation. These tickers often change when the company rebrands or they undergo a merger or reverse merger.

The ticker of an asset is not the same as the `Symbol`. `Symbol` objects are permanent and track the underlying entity. When a company rebrands or changes its name, the `Symbol` object remains constant, giving algorithms a way to reliably track assets over time.

Tickers are also often reused by different brokerages. For example Coinbase, a leading US Crypto Brokerage lists the "BTCUSD" ticker for trading. Its competitor, Bitfinex, also lists "BTCUSD". You can trade both tickers with LEAN. `Symbol` objects allow LEAN to identify which market you reference in your algorithms.

To create a `Symbol` object for a point-in-time ticker, call the `generate_equity` method to create the security identifier and then call the `Symbol` constructor. For example, Heliogen, Inc. changed their ticker from ATHN to HLGN on December 31, 2021. To convert the ATHN ticker to the Equity`Symbol`, type:

```python
# Generate an Equity security identifier for a ticker and then create a symbol with it.
ticker = "ATHN"
security_id = SecurityIdentifier.generate_equity(ticker, Market.USA, mapping_resolve_date=datetime(2021, 12, 1))
symbol = Symbol(security_id, ticker)
```

In the preceding code snippet, the `mapping_resolve_date` must be a date when the point-in-time ticker was trading.

## Symbol Cache

To make using the API easier, we have built the **Symbol Cache** technology, which accepts strings and tries to guess which `Symbol` object you might mean. With the Symbol Cache, many methods can accept a string such as "IBM" instead of a complete `Symbol` object. We highly recommend you don't rely on this technology and instead save explicit references to your securities when you need them.

```python
# Example 1: Relying On Symbol Cache:
self.add_equity("IBM")          # Add by IBM string ticker, save reference to Symbol Cache.
self.market_order("IBM", 100)   # Determine refering to IBM Equity from Symbol Cache.
self.history("AAPL", 14)        # Makes a guess referring to AAPL Equity.

# Example 2: Correctly Using Symbols:
self.ibm = self.add_equity("IBM").symbol   # Add IBM Equity string ticker, save Symbol.
self.market_order(self.ibm, 100)           # Use IBM Symbol in future API calls.

self.aapl = Symbol.create("AAPL", SecurityType.EQUITY, Market.USA)
self.history(self.aapl, 14)
```

## Markets

The `market` property distinguishes between tickers that have the same string value but represent different underlying assets. A prime example of this is the various market makers who have different prices for EURUSD. We store this data separately and as they have different fill prices, we treat the execution venues as different markets.

The following table shows the available markets for each security type:

| Security Type | Market(s) |
| --- | --- |
| `SecurityType.EQUITY` | `Market.USA` |
| `SecurityType.OPTION` | `Market.USA` |
| `SecurityType.CRYPTO` | `Market.BINANCE Market.BINANCE_US Market.BITFINEX Market.BYBIT Market.COINBASE Market.KRAKEN` |
| `SecurityType.CRYPTO_FUTURE` | `Market.BINANCE Market.BYBIT Market.DYDX` |
| `SecurityType.FOREX` | `Market.OANDA` |
| `SecurityType.FUTURE` | `Market.CBOT Market.CFE Market.CME Market.COMEX Market.EUREX Market.HKFE Market.ICE Market.INDIA Market.KRX Market.NYMEX Market.NYSELIFFE Market.SGX` |
| `SecurityType.FUTURE_OPTION` | `Market.CBOT Market.COMEX Market.NYSELIFFE` |
| `SecurityType.INDEX` | `Market.CBOE Market.EUREX Market.HKFE Market.KRX Market.OSE Market.USA` |
| `SecurityType.INDEX_OPTION` | `Market.USA` |
| `SecurityType.CFD` | `Market.INTERACTIVE_BROKERS Market.OANDA` |

## Industry Standard Identifiers

You can convert industry-standard security identifiers like CUSIP, FIGI, ISIN, and SEDOL to `Symbol` objects and you can convert `Symbol` objects to industry-standard security identifiers.

### CUSIP

To convert a Committee on Uniform Securities Identification Procedures (CUSIP) number to a `Symbol` or a `Symbol` to a CUSIP number, call the `cusip` method.

```python
# Get the CUSIP for the symbol and vice versa.
symbol = self.cusip("03783310") # AAPL Symbol
cusip = self.cusip(symbol) # AAPL CUSIP (03783310)
```

### FIGI

To convert a Financial Instrument Global Identifier (FIGI) to a `Symbol` or a `Symbol` to a FIGI, call the `composite_figi` method.

```python
# Get the FIGI for the symbol and vice versa.
symbol = self.composite_figi("BBG000B9XRY4") # AAPL Symbol
figi = self.composite_figi(symbol) # AAPL FIGI (BBG000B9XRY4)
```

### ISIN

To convert an International Securities Identification Number (ISIN) to a `Symbol` or a `Symbol` to an ISIN, call the `isin` method.

```python
# Get the ISIN for the symbol and vice versa.
symbol = self.isin("US0378331005") # AAPL Symbol
isin = self.isin(symbol) # AAPL ISIN (US0378331005)
```

### SEDOL

To convert a Stock Exchange Daily Official List (SEDOL) number to a `Symbol` or a `Symbol` to a SEDOL number, call the `sedol` method.

```python
# Get the SEDOL for the symbol and vice versa
symbol = self.sedol("2046251") # AAPL Symbol
sedol = self.sedol(symbol) # AAPL SEDOL (2046251)
```

## Examples

The following examples demonstrate some common practices for using the security identifier.

### Example 1: Future Contract Expiry

The following example demonstrates the use of the security identifier of a Future contract to access its expiry date for contract selection and schedule a singular non-repeating event to rollover using `future.symbol.id.date` .

```python
class SecurityIdentifierExampleAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        # Seed the price data in order to allow the mapped contract to fill despite sparse data.
        self.settings.seed_initial_prices = True
        self._last_scheduled_event = None

    def on_warmup_finished(self) -> None:
        # Since we do not subscribe to any data source, we can use the on_warmup_finished event handler instead of OnData for the initial position.
        es = Symbol.create(Futures.Indices.SP_500_E_MINI, SecurityType.FUTURE, Market.CME)
        self.open_future_position(es, self.time + timedelta(30), 1)

    def open_future_position(self, symbol: Symbol, min_expiry: DateTime, quantity: float) -> None:
        # Select the next mapped future contract with the nearest expiry,
        # which should be further than the current contract.
        selected = selected = [c.symbol for c in self.futures_chain(symbol) if c.expiry > min_expiry][0]
        # Subscribe to its data to trade it.
        self._future = self.add_future_contract(selected, extended_market_hours=True)

        # Buy back the corresponding number of contracts as the previous mapped contract.
        self.market_order(self._future.symbol, quantity)

        # Schedule the next rollover to be 1 week before the expiry to avoid excessive volatility.
        # It will only be triggered once 7 days before the expiry and discarded afterward.
        if self._last_scheduled_event:
            self.schedule.remove(self._last_scheduled_event)
        self.schedule.on(
            self.date_rules.on([self._future.symbol.id.date - timedelta(7)]),
            self.time_rules.at(9, 30),
            self.roll_over
        )

    def roll_over(self) -> None:
        # Save the current number of contracts to roll over to the next mapped contract.
        quantity = self._future.holdings.quantity
        # Liquidate the to-be-expired contract to roll over the position.
        self.liquidate(self._future.symbol)

        self.open_future_position(self._future.symbol.canonical, self._future.symbol.id.date, quantity)
```
