Key Concepts

Security Identifiers

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:

PropertyData TypeDescription
MarketstringThe market in which the asset trades
SecurityTypeSecurityTypeThe asset class
OptionStyleOptionStyleAmerican or European Option style
OptionRightOptionRightCall or put Option type
StrikePricedecimalThe Option contract strike price
DatedatetimeDateTimeEarliest listing date for Equities; expiry for Futures and Options; December 30, 1899 for continuous Futures contracts and Indices.
HasUnderlyingboolA 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

The following table shows the results of our encoding process given the preceding SecurityIdentifier properties:

MarketSecurityTypeOptionStyleOptionRightStrikePriceDateHasUnderlyingEncoded SecurityIdentifer After the TickerFull Encoded SecurityIdentifer Example
USAEquityN/AN/AN/AfalseDepends on the listing dateSPY R735QTJ8XC9X
IndiaEquityN/AN/AN/AfalseDepends on the listing dateYESBANK TA8Y7QR36M31
USAOptionAmericanCalltrueDepends on the strike price and contract expiry dateSPY Y7T8ERCJRZHI|SPY R735QTJ8XC9X
USAOptionAmericanPuttrueDepends on the strike price and contract expiry dateSPY 325YRWXJ6A2CM|SPY R735QTJ8XC9X
BitfinexCryptoN/AN/AN/AN/AfalseE3BTCUSD E3
GDAXCryptoN/AN/AN/AN/AfalseXJBTCUSD XJ
KrakenCryptoN/AN/AN/AN/Afalse10BBTCUSD 10B
BinanceCryptoN/AN/AN/AN/Afalse18NBTCUSDT 18N
BinanceUSCryptoN/AN/AN/AN/Afalse2S7BTCUSD 2S7
BinanceCryptoFutureN/AN/AN/ADefault value for continuous contracts (December 30, 1899)false18RBTCBUSD 18R
OandaForexN/AN/AN/AN/Afalse8GEURUSD 8G
NYMEXFuturesN/AN/AN/ADefault value for continuous contracts (December 30, 1899)falseJLCL JL
NYMEXFuturesN/AN/AN/AfalseDepends on the contract expiry dateCL Y5BMQ78IXW3L
CBOTFuturesN/AN/AN/ADefault value for continuous contracts (December 30, 1899)falseMD10Y MD
CBOTFuturesN/AN/AN/AfalseDepends on the contract expiry date10Y Y6E15UI3XBFP
ICEFuturesN/AN/AN/ADefault value for continuous contracts (December 30, 1899)falseP5SB P5
ICEFuturesN/AN/AN/AfalseDepends on the contract expiry dateSB XS9YHLR0G0P5
CFEFuturesN/AN/AN/ADefault value for continuous contracts (December 30, 1899)false2JTVX 2JT
CFEFuturesN/AN/AN/AfalseDepends on the contract expiry dateVX XLCUDY7B36Y1
COMEXFuturesN/AN/AN/ADefault value for continuous contracts (December 30, 1899)false1P9AUP 1P9
COMEXFuturesN/AN/AN/AfalseDepends on the contract expiry dateAUP Y6E15UI3XCIL
CMEFuturesN/AN/AN/ADefault value for continuous contracts (December 30, 1899)false1S16A 1S1
CMEFuturesN/AN/AN/AfalseDepends on the contract expiry date6A Y54QLJOCEN7L
CBOTFutureOptionAmericanCalltrueDepends on the strike price and Option contract expiry dateOZB Y5IIV0IM2B9K|ZB Y6ZOZWJTLWYT
CBOTFutureOptionAmericanPuttrueDepends on the strike price and Option contract expiry dateOZB 324MJ0GMRY64O|ZB Y6ZOZWJTLWYT
CMEFutureOptionAmericanCalltrueDepends on the strike price and Option contract expiry dateDC Y6F0M6PN2P50|DC Y79JGU7IDHQ9
CMEFutureOptionAmericanPuttrueDepends on the strike price and Option contract expiry dateDC 325J0RLJHWU6C|DC Y79JGU7IDHQ9
COMEXFutureOptionAmericanCalltrueDepends on the strike price and Option contract expiry dateOG Y5HJES9Z6R40|GC Y6A3DH1FMBVH
COMEXFutureOptionAmericanPuttrueDepends on the strike price and Option contract expiry dateOG 324LJK7HQ75GG|GC Y6A3DH1FMBVH
NYMEXFutureOptionAmericanCalltrueDepends on the strike price and Option contract expiry dateON Y693XDUJYOX0|NG Y6A3DH1FMAPT
NYMEXFutureOptionAmericanPuttrueDepends on the strike price and Option contract expiry dateON 325D42V6VFRT0|NG Y6A3DH1FMAPT
USAIndexN/AN/AN/ADefault value for Indices (December 30, 1899)false31SPX 31
USAIndexOptionEuropeanCalltrueDepends on the strike price and contract expiry dateSPX XVDBJU811DE6|SPX 31
USAIndexOptionEuropeanPuttrueDepends on the strike price and contract expiry dateSPX 31UHBPA78B6RY|SPX 31
OANDACfdN/AN/AN/AN/Afalse8ISPX500USD 8I

LEAN assumes the ticker you pass to the AddEquity method is the current ticker of the Equity asset. To access this ticker, use the Value property of the Symbol object.

self.symbol = self.AddEquity("GOOG").Symbol
self.Debug(self.symbol.ID.Value) # Prints "GOOCV"
self.Debug(self.symbol.Value)    # Prints "GOOG"
var symbol = AddEquity("GOOG").Symbol;
Debug(symbol.ID.Value); // Prints "GOOCV"
Debug(symbol.Value);    // Prints "GOOG"

If you create the security subscription with a universe selection 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.

var symbol = Symbol("GOOCV VP83T1ZUHROL");
symbol.ID.Market;     // => "USA"
symbol.SecurityType;  // => SecurityType.Equity
symbol.Value;         // => "GOOCV"
symbol = self.Symbol("GOOCV VP83T1ZUHROL")
symbol.ID.Market     # => "USA"
symbol.SecurityType  # => SecurityType.Equity
symbol.Value         # => "GOOCV"

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.

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 GenerateEquity 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:

ticker = "ATHN"
security_id = SecurityIdentifier.GenerateEquity(ticker, Market.USA, mappingResolveDate=datetime(2021, 12, 1))
symbol = Symbol(security_id, ticker)
var ticker = "ATHN";
var securityID = SecurityIdentifier.GenerateEquity(ticker, Market.USA, mappingResolveDate:new DateTime(2021, 12, 1));
var symbol = new Symbol(securityID, ticker);

In the preceding code snippet, the mappingResolveDate 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.

# Example 1: Relying On Symbol Cache:
self.AddEquity("IBM")         # Add by IBM string ticker, save reference to Symbol Cache.
self.MarketOrder("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.AddEquity("IBM").Symbol   # Add IBM Equity string ticker, save Symbol.
self.MarketOrder(self.ibm, 100)           # Use IBM Symbol in future API calls.

self.aapl = Symbol.Create("AAPL", SecurityType.Equity, Market.USA)
self.History(self.aapl, 14)
// Example 1: Relying On Symbol Cache:
AddEquity("IBM");         // Add by IBM string ticker, save reference to Symbol Cache.
MarketOrder("IBM", 100);  // Determine refering to IBM Equity from Symbol Cache.
History("AAPL", 14);      // Guess referring to AAPL Equity.

// Example 2: Correctly Using Symbols: 
var ibm = AddEquity("IBM").Symbol;   // Add IBM Equity string ticker, save Symbol.
MarketOrder(ibm, 100);               // Use IBM Symbol in future API calls.

var aapl = Symbol.Create("AAPL", SecurityType.Equity, Market.USA);
History(aapl, 14);

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.

symbol = self.CUSIP("03783310") # AAPL Symbol
cusip = self.CUSIP(symbol) # AAPL CUSIP (03783310)
var symbol = CUSIP("03783310"); // AAPL Symbol
var cusip = 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 CompositeFIGI method.

symbol = self.CompositeFIGI("BBG000B9XRY4") # AAPL Symbol
figi = self.CompositeFIGI(symbol) # AAPL FIGI (BBG000B9XRY4)
var symbol = CompositeFIGI("BBG000B9XRY4"); // AAPL Symbol
var figi = CompositeFIGI(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.

symbol = self.ISIN("US0378331005") # AAPL Symbol
isin = self.ISIN(symbol) # AAPL ISIN (US0378331005)
var symbol = ISIN("US0378331005"); // AAPL Symbol
var isin = 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.

symbol = self.SEDOL("2046251") # AAPL Symbol
sedol = self.SEDOL(symbol) # AAPL SEDOL (2046251)
var symbol = SEDOL("2046251"); // AAPL Symbol
var sedol = SEDOL(symbol); // AAPL SEDOL (2046251)

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: