Documentation

Key Concepts

Getting Started

Welcome

Welcome to QuantConnect. We are an open source, community driven algorithmic trading platform. Our trading engine is powered by LEAN, a cross platform, multi-asset technology which brings cutting edge finance to the open source community. We support C#, Python and F# programming languages making us a truly open platform.

Our Mission

We believe the future of finance is automated and we plan to be the quantitative trading infrastructure of the future. We believe algorithmic trading is a powerful tool and we want to open it up to all investors.

Select Language (C#PythonJavaF#VB): C# | Python | F#  | Toggle Edit
//Over here you'll see code snippets and examples demonstrating the API!
//Over here you'll see code snippets and examples demonstrating the API!
//Over here you'll see code snippets and examples demonstrating the API!

Security & Privacy

You own all your intellectual property and your code. Your code is private by default unless you explicitly share it with the community in the forums or with another team member via collaboration. You are creating valuable intellectual property and we respect this, and wish to make it easier.Only two QuantConnect staff members have access to the database. If we ever need access to your algorithm for the purpose of debugging, we only explicitly request permission first. Please see our terms and conditions.

Data Library

We provide an enormous library of data for your backtesting roughly 14TB in size. This library includes:

Type Source Start Date Symbols Resolutions
US Equity QuantQuote Jan 1998 16,400 Tick, Sec, Min, Hour, Daily
Forex FXCM Apr 2007 13 Tick, Sec, Min, Hour, Daily
Forex Oanda Apr 2004 71 Tick, Sec, Min, Hour, Daily
CFD Oanda Apr 2004 50 Tick, Sec, Min, Hour, Daily
Options AlgoSeek Jan 2010 4000 Minute Bars Only
Futures AlgoSeek Jan 2009 4000 Tick, Second, Minute (Trades, Quotes)

More information on the data library and its symbols can be found at the Data Library.

Business Model

QuantConnect makes backtesting available for free and charges a small monthly fee to cover live algorithm trading. This offsets our costs and aligns our interests with yours - our client. We also work with brokerages to make your live trading free.

Developing in the IDE

Coding Your Algorithm

Write code in project files and then press the Build button to compile your algorithm. Build errors will be displayed in the console and highlighted with red-lines.

You can add, rename and delete files in your project in the Projects tab. You can create a virtual folder for your project by placing a slash ("/") into the name of your file.

Algorithms require only initialization and data event handlers.

public class BasicTemplateAlgorithm : QCAlgorithm
{
	public override void Initialize() {
		// Setup algorithm requirements: cash, dates and securities.
                // Initialize is called once at the start of the algorithm.
	}

	public override void OnData(Slice data) {
               // Data requested is then piped into event handlers like this one.
	}
}

QuantConnect Backtesting and Coding Environment.

Backtesting Your Algorithm

Once you've got an algorithm compiling you can click the Play button to launch a backtest. You can launch as many backtests as want in parallel and results are shown in the result drop-down.

University Algorithms

The QuantConnect University "QCU" is a collection of videos and algorithms to demonstrate the API. There are 50+ algorithms covering all aspects of the API and common questions users have raised over time.

Data Manager

The Data Manager is a searchable database of the QuantConnect Data Library. Each asset details are accessible including the start date, delist date, source of the data, resolutions available and the exchange the asset is traded.

API Help Documentation

The Help Tab details the classes and API of the underlying LEAN engine so you can see the methods and class infrastructure. It includes an indicator reference table to see all the indicators available.

Shortcut Keys

Here are some keyboard short-cuts built into the IDE to make coding easier.

Short Cut Description
Ctrl + Space Initiate full auto-complete
Ctrl + / Toggle comments on selected code
Ctrl + Up/Down Increase/decrease font size
Ctrl + S Save document and compile project
Ctrl + D Remove line
Alt + Up/Down Move line up/down
Alt + Shift + Up/Down Copy lines up/down
Alt + 0 (zero) Collapse all code blocks
Alt + Shift + 0 (zero) Expand all code blocks

The full list of short cuts can be found on at the ACE Editor open source project.

Algorithm Reference

Overview

QuantConnect's LEAN engine manages your portfolio and data feeds letting you focus on your algorithm strategy and execution. Data is piped into your strategy via event handlers, upon which you can place trades. We provide basic portfolio management and fill modelling underneath the hood automatically. This is provided by the QCAlgorithm base class.

All algorithms extend QCAlgorithm, which provides some key helper properties for you to use: Security Manager, Portfolio Manager, Transactions Manager, Notification Manager and Scheduling Manager. Along with hundreds of helper methods to make the API easy to use. We'll go into more detail on those below, but its important for you to know the basic infrastructure around your algorithm.

The Securities property get_Securities() method is a dictionary of Security objects. Each asset (equity, forex pair etc) in your algorithm has a security object. All the models for a security live on these objects: e.g. Securities["IBM"].FeeModel or Securities["IBM"].Price. get_Securities().get_Item("SPY").get_Price()

Portfolio is a dictionary of SecurityHolding classes. These classes track the individual portfolio items profit and losses, fees and quantity held. e.g. Portfolio["IBM"].LastTradeProfitDecimal profit = get_Portfolio().get_Item("IBM").get_LastTradeProfit();.

Other helpers like Transactions, Schedule, Notify, and Universe have their own helper methods which we'll explain below.

All algorithms must have an Initialize() method to setup your strategy. Once setup most algorithms have OnData event handlers to process market data and make trading decisions.

public class QCAlgorithm
{
        SecurityManager Securities;   //Array of Security objects.
        SecurityPortfolioManager Portfolio;  // Array of SecurityHolding objects
        SecurityTransactionManager Transactions;  // Transactions helper
        ScheduleManager Schedule;  // Scheduling helper
        NotificationManager Notify; //Email, SMS helper
        UniverseManager Universe; // Universe helper
 
        //Set up Requested Data, Cash, Time Period.
        public virtual void Initialize() { ... };
 
        //Event Handlers:
        public virtual OnData() { Slice data };
        public virtual OnDividend() { ... };
        public virtual OnEndOfDay() { ... };
        public virtual OnEndOfAlgorithm() { ... };
        
        //Helpers... 
        public SimpleMovingAverage SMA();
}

Initializing Algorithms

The Initialize method is called to setup your strategy. Here you can request data, set starting cash or warm up periods.

Setting Cash

In backtests you can set your starting capital using the SetCash(decimal cash)self.SetCash(decimal cash)this.SetCash(decimal cash) method. In live trading this is ignored and your brokerage cash is used instead. In paper trading we set the cash to a fictional $100,000 USD (you can override the paper trading equity by clicking the "Live Algorithm Equity" button in your project tab).

SetCash(25000);
this.SetCash(100000)
self.SetCash(100000)

Setting Dates

Backtesting uses the SetStartDate(int year, int month, int day) self.SetStartDate(int year, int month, int day) this.SetStartDate(int year, int month, int day) and SetEndDate(int year, int month, int day) self.SetEndDate(int year, int month, int day) this.SetEndDate(int year, int month, int day) methods to configure the backtest time range. If unspecified the end date defaults to yesterday. In .NET languages you can also use a DateTime object to set the dates.

SetStartDate(2013, 1, 1);         // Set start date to specific date.
SetEndDate(2015, 1, 1);         // Set end date to specific date.
SetEndDate(DateTime.Now.Date.AddDays(-1)); // Or use a relative date.
self.SetStartDate(2013,1,1)
self.SetEndDate(2015,1,1)
this.SetStartDate(2013, 10, 7)
this.SetEndDate(2013, 10, 11)

Selecting Asset Data

Algorithms can manually subscribe to data for specific assets they need, or use universes to choose groups of assets based on filtering criteria (e.g. all stocks with volumes greater than $10M/day). See more about Universes here.

To manually subscribe to a specific asset you can call the AddEquity(), AddForex(), AddCfd() and AddOption() methods in your Initialize() method. You can subscribe to 500 minute resolution datafeeds, 100 second resolutions feeds and 10 tick resolution datafeeds.

QuantConnect supports international trading across multiple timezones and markets. Markets are used to distinguish between the same tickers on different exchanges (e.g. FXCM and Oanda both offer EURUSD, but have different rates).

QuantConnect provides 40TB of US Equities, US Options, FXCM FX and Oanda FX data. Check out more information about our data in our data library.

We provide data in tick, second, minute, hour or daily resolutions. These are specified by the Resolution enum.

If there is a gap in the data (e.g. because there are no trades), by default the data is still pumped into your strategy on each time step. This behavior is called "fillForward" and defaults to true. You can disable this by setting fillForward to false.

By default data in QuantConnect is Split and Dividend adjusted backwards in time to give smooth continuous prices. This allows easy use for indicators. Some algorithms need raw or partially adjusted price data. You can control this with the SetDataNormalizationMode() method. The DataNormalizationMode enum has the values Adjusted (default), Raw, SplitAdjusted, and TotalReturn.

If you have your own custom data you'd like to backtest against, check out the custom data section.

// Complete Add Equity API - Including Default Parameters:
AddEquity(string ticker, Resolution resolution = Resolution.Minute, string market = Market.USA, bool fillDataForward = true, decimal leverage = 0m, bool extendedMarketHours = false)

//Complete Add Forex API - Including Default Parameters:
AddForex(string ticker, Resolution resolution = Resolution.Minute, string market = Market.FXCM, bool fillDataForward = true, decimal leverage = 0m)
AddEquity("AAPL"); //Add Apple 1 minute bars (minute by default).
AddForex("EURUSD", Resolution.Second); //Add EURUSD 1 second bars.
this.AddEquity("SPY", Resolution.Minute) |> ignore
this.AddForex("EURUSD", Resolution.Second) |> ignore
self.AddEquity("SPY")  # Default to minute bars
self.AddForex("EURUSD", Resolution.Second) # Set second bars.
//Setting the data normalization mode for the MSFT security to raw (pay dividends as cash)
Securities["MSFT"].SetDataNormalizationMode(DataNormalizationMode.Raw);
# Setting the data normalization mode for the MSFT security to raw (pay dividends as cash)
self.Securities["SPY"].SetDataNormalizationMode(DataNormalizationMode.Raw);
(* Setting MSFT security to use raw prices *)
this.Securities.Item("MSFT").SetDataNormalizationMode(DataNormalizationMode.Raw);

Setting Warm Up Period

Often algorithms need some historical data to prime technical indicators, or populate historical data arrays. Using the SetWarmUp(TimeSpan period) or SetWarmUp(int barCount) methods you can specify a warm up period for your algorithm which pumps data in from before the start date. During the warm up period you cannot place a trade.

Algorithms can use the bool IsWarmingUp property to determine if the warm up period has completed.

See more about using historical data in the History section.

SetWarmUp(200); //Warm up 200 bars for all subscribed data.
SetWarmUp(TimeSpan.FromDays(7)); //Warm up 7 days of data.
self.SetWarmUp(200)
self.SetWarmUp(TimeSpan.FromDays(7))
this.SetWarmUp(200)

Cash and Brokerage Models

US Equity brokerage accounts are either Cash or Margin based accounts. Cash accounts do not allow leveraged trading, whereas Margin accounts support 2-4x leverage on your account value. You can set your brokerage account type in your initialization with SetBrokerageModel(BrokerageName broker, AccountType account);.

The BrokerageName enum supports values of Default, TradierBrokerage, InteractiveBrokersBrokerage, FxcmBrokerage and OandaBrokerage. When setting the brokerage name we also set the trading fee structures for that brokerage.

The AccountType enum supports values of Cash and Margin. When using cash leverage is disabled by default, and the cash settlement period is set to 3 days. Margin accounts are settled immediately and have a leverage of 2.

Margin accounts with more than $25,000 in equity are eligible for pattern day trading margin limits. This increases your available leverage to 4x while the market is open and 2x overnight. To model this behavior in your algorithm you must set your security MarginModel a PatternDayTradingMarginModel class.

See more about brokerage models in the Reality Modelling section.

//Brokerage model and account type:
SetBrokerageModel(BrokerageName.TradierBrokerage, AccountType.Margin);

//Add securities and if required set custom margin models 
var spy = AddEquity("SPY"); //Defaults to minute bars.
spy.MarginModel = new PatternDayTradingMarginModel();
//In Initialize:
self.AddEquity("SPY") # Default to minute bars
self.SetBrokerageModel(BrokerageName.InterativeBrokersBrokerage, AccountType.Cash)
self.Securities["SPY"].MarginModel = PatternDayTradingMarginModel
(* In Initialize method, set the brokerage models *)
this.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Cash);
this.AddEquity("SPY", Resolution.Second) |> ignore
(* Then if required, you can set specific margin models for your secutities *)
this.Securities.Item("SPY").MarginModel <- new PatternDayTradingMarginModel()
// You can also create your own brokerage model: IBrokerageModel
class MyBrokerage: DefaultBrokerage {
   // Custom implementation of brokerage here.
} 

SetBrokerageModel(new MyBrokerage());

Handling Data

Requested data is passed into event handlers for you to use to make trading decisions. The primary event handler, Slice, groups all data types together at a single moment in time in the OnData(Slice data) handler. Slice is short for "time slice" - representing a slice of time and values of the data at that time. C# and F# also allow you to receive data with dedicated event handlers for each data type e.g OnData(TradeBars data).Python only supports the Slice event handlers.

All data uses DataDictionary objects to group data by symbol and provide easy access to information. The plural of the type denotes the collection of objects e.g. the TradeBars DataDictionary is made up of TradeBar objects. You can access individual data points in the dictionary through its string or symbol dictionary index. For example var ibmTradeBar = tradebars["IBM"].

Time Slices

The Slice event handler combine all of the data together into a single method. It represents the data at a point in time. The Slice object contains many helpers for accessing your data. The Slice objects arrive to the OnData(Slice data) event handler.

The Slice object allows direct access via strongly typed properties, a dynamic string/symbol indexer and the strongly typed DataDictionary<T> Get<T> method. Strongly typed access gives you compile time safety but dynamic types can sometimes simplify coding.

Python is dynamically typed so does not have the Get method. Primary Slice data access is through the string/symbol indexer.

Slice is the recommended method for data access in your algorithm.

// Event handler for Slice method
public void OnData(Slice data) {
}
// Event handler for Slice method
member this.OnData(slice:Slice) =  
      ()
# Event handler for the slice method
def OnData(self, slice):
//Access data in a Slice object: 
// 1. Strong Typed Properties: Ticks, TradeBars, Delistings, SymbolChangedEvents, Splits and Dividends
var bars = slice.Bars; // e.g. bars["IBM"].Open

// 2. Strong Typed Get Accessor:
var bars = slice.Get<TradeBars>(); //e.g. bars["IBM"].Open
var bar   = slice.Get<TradeBar>("IBM"); //e.g. bar.Open

// 3. Dynamic String / Symbol Indexer:
var bar = slice["IBM"]; // e.g. bar.Open
#Access data in a Slice object: 
# 1. Grouped Properties: Ticks, Bars, Delistings, SymbolChangedEvents, Splits and Dividends
bars = slice.Bars; # e.g. bars["IBM"].Open

# 2. Dynamic String / Symbol Indexer:
bar = slice["IBM"] # e.g. bar.Open - TradeBar properties OHLCV
spyTickList = data["SPY"] # Tick assets return a list of Tick objects.

Event Handlers

In C#/F# data is also piped into dedicated event handlers for each data type. To use data this way you need to put an event handler in your algorithm which follows the pattern: public void OnData(TradeBars data) {}. LEAN automatically detects the method exists and sends data to it. Python does not support dedicated event data handlers. Slice is the preferred way to access data for your strategy.

public void OnData(TradeBars data) {
    // TradeBars objects are piped into this method.
}
public void OnData(Ticks data) {
    // Ticks objects are piped into this method.
}

Data Formats

There are six financial data types: TradeBars, Ticks, Delistings, SymbolChangedEvents, Splits and Dividends.

All data extends from BaseData - the core data class which provides Symbol, Time and Value properties.

TradeBar events contains Open, High, Low, Close and Volume properties for a given period of time.

Dividend events are triggered on payment of a dividend. It provides the Distribution per share.

Split events are triggered on a share split or reverse split event. It provides a SplitFactor and ReferencePrice.

SymbolChangedEvent provide notice of new ticker names for stocks, or mergers of two tickers into one. It provides the OldSymbol and NewSymbol tickers.

Delisting events provide notice an asset is no longer trading on the exchange.

//TradeBars collection of TradeBar objects
TradeBars data; TradeBar ibm = data["IBM"];

//Dividends collection of Dividend objects
Dividends data; Dividend ibm = data["IBM"];

Importing Custom Data

LEAN supports backtesting almost any external custom data source. To use this feature you need to add the data during initialize using AddData<T>() and instruct your algorithm how to read your data. We provide helpers for popular data sources like Quandl, but if you are using your own format / server you'll need to create a custom type.

Initializing Custom Data

During initialize your algorithm must use AddData<T>(string ticker, Resolution resolution = Resolution.Daily). This gives LEAN the T-type factory to create the objects, the name of the data and the resolution at which to poll the data to check for updates.

The framework checks for new data every as instructed by the Resolution period, i.e. Resolution.Tick polls constantly, Resolution.Second polls every second, and Resolution.Minute every minute. Hourly and Daily Resolutions are polled every 30 minutes to prevent skipping a day if the data was emitted late.

// In Initialize method:
AddData<Yahoo>("SPY", Resolution.Daily);

Creating and Reading Custom Data

You must create a custom type to instruct LEAN where to get your data, and how to read it. We support many different data types and formats. You can even change source locations for backtesting and live modes. All data must extend from BaseData and override the Reader and GetSource methods.

GetSource instructs LEAN where to find your data. It must return a SubscriptionDataSource object containing the string Url to find your data, and the format of the data (SubscriptionTransportMedium RemoteFile or Rest). When the source returned changes URL the data is downloaded again. This allows LEAN to cache large files and only download new data when requested. This also allows you to break up large intraday data into smaller daily files, speeding up the backtest.

When using SubscriptionTransportMedium.Rest the url provided is polled at each Resolution time step and is assumed to be sufficient for 1-data point. This is generally intended for live data sources.

Reader takes one line of data provided by the source, and parses it into one of your custom objects (e.g. Yahoo in the code snippet). In addition to setting your custom type properties, you should also take care to set three required properties:

  1. Symbol - Should always be set to config.Symbol
  2. Time - Required synchronization of custom data
  3. Value - Required for purchasing and portfolio calculations

When there is no usable data in a line, your type should return null.

public class Yahoo : BaseData {
        public decimal Open, High, Low, Close, AdjustedClose, Volume;
        
        // Return the URL external source for the data:
        public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLive) {
            // Using Quandl Wrapper on Yahoo Finance API to Sort Data:
            var url = "https://www.quandl.com/api/v1/datasets/YAHOO/" 
                           + config.Symbol + ".csv?sort_order=asc&exclude_headers=true";
            return new SubscriptionDataSource(url, SubscriptionTransportMedium.RemoteFile);
        }
        
        // Convert each line of the file above into an object.
        public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLive) {
            Yahoo yBar = new Yahoo();
            try {
                string[] data = line.Split(',');
                yBar.Symbol = config.Symbol; // Required.
                yBar.Time = DateTime.ParseExact(data[0], "yyyy-MM-dd", CultureInfo.InvariantCulture);
                yBar.Open = Convert.ToDecimal(data[1]);
                yBar.High = Convert.ToDecimal(data[2]);
                yBar.Low = Convert.ToDecimal(data[3]);
                yBar.Close = Convert.ToDecimal(data[4]);
                yBar.Volume = Convert.ToDecimal(data[5]);
                yBar.AdjustedClose = Convert.ToDecimal(data[6]);
                yBar.Value = yBar.AdjustedClose;  // Required for portfolio calculations
            } catch {    }
            return yBar;
        }
    }

Securities and Portfolio

Algorithms have a Securities property which stores a Security object for each asset in your algorithm. Security objects hold the models (backtesting behaviors) and properties of an asset. Each security can be completely customized to behave as you'd like. Securities is a Dictionary<Symbol, Security> so you can access your Security objects with their ticker Securities["IBM"].Price.

// Popular Securities Property Values:
Securities["IBM"].HasData           // Security has data 
                 .Invested          // Have holdings
                 .LocalTime         // Time on the asset exchange
                 .Holdings          // Portfolio object
                 .Exchange          // Exchange information
                 .FeeModel;         // Fee model setter

Security objects also carry all the models for creating realistic backtests. These models are set via the public security properties and then used in LEAN to improve your backtest realism.

The Portfolio property is a collection of SecurityHolding objects to provide easy access to the holding properties. The Portfolio class is a Dictionary<Symbol, SecurityHolding> so can be accessed via ticker index: Portfolio["IBM"].IsLong

// Popular Portfolio Property Values:
Portfolio["IBM"].Invested 
                .IsLong            // IsLong, IsShort Holdings.
                .Quantity          // Shares held.
                .UnrealizedProfit; // Holdings profit/loss
                .TotalFees         // Fees incurred since backtest start
                .Price;            // Asset price

Detailed information on these classes can be found in LEAN documentation. Check out the Security class (Securities objects), and SecurityHolding (Portfolio objects) classes.

//Securities array access to Security Objects:
Securities["IBM"].Price
//Security object properties:
class Security {
    Resolution Resolution;
    bool HasData;
    bool Invested;
    DateTime LocalTime;
    SecurityHolding Holdings;
    SecurityExchange Exchange;
    IFeeModel FeeModel;
    IFillModel FillModel;
    ISlippageModel SlippageModel;
    ISecurityPortfolioModel PortfolioModel;
    ISecurityMarginModel MarginModel;
    ISettlementModel SettlementModel;
    IVolatilityModel VolatilityModel;
    ISecurityDataFilter DataFilter;
}

Trading and Orders

Key Concepts

Algorithms can place an order through calling the appropriate method in the API. Going long is denoted with a ordering positive number, and short a negative one. LEAN does not support hedging (long and short at the same time).

Placing an order generates an OrderTicket which you can use to update, cancel or check the status of your order.

To update an order can call the Update method on the OrderTicket. The Update method takes an UpdateOrderFields object which defines what properties of the order should be updated. In the same way you can cancel your order with the OrderTicket Cancel method.

The OrderTicket Status property can be used to determine if the order is filled. The OrderStatus enum has the values Submitted, PartiallyFilled, Filled, Cancelled or Invalid.

// Creating an Order:
OrderTicket limitOrderTicket = LimitOrder("SPY", 100, 205);

// Updating an Order:
limitOrderTicket.Update(new UpdateOrderFields{LimitPrice = 207.50};

// Cancel an Order:
limitOrderTicket.Cancel();

Set Holdings Helper

Often portfolio based algorithms want to set the portfolio based on percentage weighting. We provide a helper method to perform this weighting for you called SetHoldings .

SetHoldings(Symbol symbol, double percentage, bool liquidateExistingHoldings = false)

When liquidate existing holdings is set to true any existing holdings will first be sold. This may be useful when you're rebalancing to a new set of stocks. The Liquidate method can achieve the same affect.

Liquidate(Symbol symbolToLiquidate = null)
Liquidate sells all holdings in your portfolio, or just the ticker symbol if the parameter is specified.

SetHoldings sets a fraction of unlevered equity. e.g. If you have 2x available leverage, and SetHoldings to 1.0 the algorithm will use 1.0 of your available buying power. To maximize buying power in this case you would make the SetHoldings fractions total 2.0.

// Set fixed percentages of known tickers:
SetHoldings("IBM", 0.25);
SetHoldings("GOOG", 0.25);
SetHoldings("AAPL", 0.25);
SetHoldings("MSFT", 0.25);

// Or set portfolio to equal weighting of all securities:
var weighting = 1m / Securities.Count;
foreach(var security in Securities.Values) {
    SetHoldings(security.Symbol, weighting);
}

Order Types

We support many different order types. In live trading some of these order types may be simulated depending on your brokerage (for more information on this see Live Trading).

Order Type Method Signature
Market Order
MarketOrder(Symbol symbol, int quantity, bool asynchronous = false, string tag = "")
Asynchronous flag can be used to send the many orders and not wait for the fill response.
Market On Open
MarketOnCloseOrder(Symbol symbol, int quantity, string tag = "")
Fill an order at the market opening. Equity markets only.
Market On Close
MarketOnOpenOrder(Symbol symbol, int quantity, string tag = "")
Fill an order on market closing. Equity markets only. Orders must be submitted 15min before closing.
Stop Market
StopMarketOrder(Symbol symbol, int quantity, decimal stopPrice, string tag = "")
Submit a market order when the stop price is reached.
Limit Order
LimitOrder(Symbol symbol, int quantity, decimal limitPrice, string tag = "")
Fill order for the limit price or better.
Stop Limit Order
StopLimitOrder(Symbol symbol, int quantity, decimal stopPrice, decimal limitPrice, string tag = "")
Submit limit order when stop price is reached.
All order methods return an OrderTicket. The tag parameter can be used to send additional debugging information along with each order object.

// Various order types:
// Fill a market order immediately (before moving to next line of code)
var newTicket = MarketOrder("IBM", 100);

// Place a long limit order with limit price less than current price
var newTicket = LimitOrder("IBM", 100, lastClose * .999m);

// Closing out a short position; long stop above the last close price
var stopPrice = close * 1.0025m;
var newTicket = StopMarketOrder("IBM", 100, stopPrice);

// Closing out a long position on market drop
var stopPrice = close * .9975m;
var newTicket = StopMarketOrder("IBM", -100, stopPrice);

// Limit order trigger on reaching the stop price
var newTicket = StopLimitOrder("IBM", 100, stopPrice, limitPrice);

// Market on Open/Close:
var newTicket = MarketOnCloseOrder("IBM", 100);
var newTicket = MarketOnOpenOrder("IBM", 100);

Order Events

Orders create lots of events you can use to track their status. These events are passed into the OnOrderEvent event handler with the relevant order.

// Override the base class event handler for order events
public override void OnOrderEvent(OrderEvent orderEvent)
{
    var order = Transactions.GetOrderById(orderEvent.OrderId);
    Console.WriteLine("{0}: {1}: {2}", Time, order.Type, orderEvent);
}

Scheduled Events

Scheduled events allow you to trigger code to run at specific times of day. This happens regardless of your data events. The schedule API requires a date and time rule to specify when the event is fired.

Scheduled events need a DateRules and TimeRules pair to set a specific time. When the event is triggered the action block is executed.

Date/Time Rules

DateRules Class Example Usage
On(year,month,day)
DateRules.On(2013, 10, 7)
Trigger an event on a specific date.
EveryDay(symbol)
DateRules.EveryDay("SPY")
Trigger an event every day a specific symbol is trading.
EveryDay()
DateRules.EveryDay()
Trigger an event every day.
Every(days)
DateRules.Every(DayOfWeek.Monday, DayOfWeek.Friday)
Trigger an event on specific days during week.

TimeRules Class Example Usage
At(hour, min)
TimeRules.At(13, 10)
Trigger an event at a specific time of day (e.g. 13:10).
AfterMarketOpen(symbol, min)
TimeRules.AfterMarketOpen("SPY", 10)
Trigger an event a few minutes after market open for a specific symbol.
BeforeMarketClose(symbol, min)
TimeRules.BeforeMarketClose("SPY", 10)
Trigger an event a few minutes before close for a specific symbol.
Every(period)
TimeRules.Every(TimeSpan.FromMinutes(10))
Trigger an event every period interval.

// Schedule an event to fire at a specific date/time
Schedule.On(DateRules.On(2013, 10, 7), TimeRules.At(13, 0), () =>
{
	Log("SpecificTime: Fired at : " + Time);
});

// Schedule an event to fire every trading day for a security
// The time rule here tells it to fire 10 minutes after SPY's market open
Schedule.On(DateRules.EveryDay("SPY"), TimeRules.AfterMarketOpen("SPY", 10), () =>
{
	Log("EveryDay.SPY 10 min after open: Fired at: " + Time);
});

// Schedule an event to fire every trading day for a security
// The time rule here tells it to fire 10 minutes before SPY's market close
Schedule.On(DateRules.EveryDay("SPY"), TimeRules.BeforeMarketClose("SPY", 10), () =>
{
	Log("EveryDay.SPY 10 min before close: Fired at: " + Time);
});

// Schedule an event to fire on certain days of the week
Schedule.On(DateRules.Every(DayOfWeek.Monday, DayOfWeek.Friday), TimeRules.At(12, 0), () =>
{
	Log("Mon/Fri at 12pm: Fired at: " + Time);
});

Indicators

We provide more than 100 technical indicators for you to use in your algorithm. These are provided in two ways; through helper short cut methods, and as class objects. Indicators created through the short cut methods have already been wired up to receive data and are "ready to use". A full list of the indicators and their properties can be found in the reference table below.

One key indicator to learn is the Identity indicator which simply returns the value of the asset. This can be useful for combining indicators together. For example:

var pep = Identity("PEP");    // Pepsi ticker
var coke = Identity("KO");    // Coke ticker
var delta = pep.Minus(coke);  // Difference between them

Reference Table

Indicators Usage
AccumulationDistribution var ad = AD(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.TradeBar] selector = null)
AccumulationDistributionOscillator var adosc = ADOSC(Symbol symbol, int fastPeriod, int slowPeriod, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.TradeBar] selector = null)
AverageDirectionalIndex var adx = ADX(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
AverageDirectionalMovementIndexRating var adxr = ADXR(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
AbsolutePriceOscillator var apo = APO(Symbol symbol, int fastPeriod, int slowPeriod, MovingAverageType movingAverageType, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
AroonOscillator var aroon = AROON(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
AroonOscillator var aroon = AROON(Symbol symbol, int upPeriod, int downPeriod, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
AverageTrueRange var atr = ATR(Symbol symbol, int period, MovingAverageType type = null, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
BollingerBands var bb = BB(Symbol symbol, int period, decimal k, MovingAverageType movingAverageType = null, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
BalanceOfPower var bop = BOP(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
CommodityChannelIndex var cci = CCI(Symbol symbol, int period, MovingAverageType movingAverageType = null, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
ChandeMomentumOscillator var cmo = CMO(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
DonchianChannel var dch = DCH(Symbol symbol, int upperPeriod, int lowerPeriod, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
DonchianChannel var dch = DCH(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
DoubleExponentialMovingAverage var dema = DEMA(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
ExponentialMovingAverage var ema = EMA(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
FractalAdaptiveMovingAverage var frama = FRAMA(Symbol symbol, int period, int longPeriod = 198, Resolution resolution = null)
IchimokuKinkoHyo var ichimoku = ICHIMOKU(Symbol symbol, int tenkanPeriod, int kijunPeriod, int senkouAPeriod, int senkouBPeriod, int senkouADelayPeriod, int senkouBDelayPeriod, Resolution resolution = null)
KaufmanAdaptiveMovingAverage var kama = KAMA(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
KeltnerChannels var kch = KCH(Symbol symbol, int period, decimal k, MovingAverageType movingAverageType = null, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
LogReturn var logr = LOGR(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
LeastSquaresMovingAverage var lsma = LSMA(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
LinearWeightedMovingAverage var lwma = LWMA(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
MovingAverageConvergenceDivergence var macd = MACD(Symbol symbol, int fastPeriod, int slowPeriod, int signalPeriod, MovingAverageType type = null, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
MeanAbsoluteDeviation var mad = MAD(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
Maximum var max = MAX(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
MoneyFlowIndex var mfi = MFI(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.TradeBar] selector = null)
MidPoint var midpoint = MIDPOINT(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
MidPrice var midprice = MIDPRICE(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Minimum var min = MIN(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
Momentum var mom = MOM(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
MomersionIndicator var momersion = MOMERSION(Symbol symbol, int minPeriod, int fullPeriod, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
MomentumPercent var momp = MOMP(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
NormalizedAverageTrueRange var natr = NATR(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
OnBalanceVolume var obv = OBV(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.TradeBar] selector = null)
PercentagePriceOscillator var ppo = PPO(Symbol symbol, int fastPeriod, int slowPeriod, MovingAverageType movingAverageType, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
ParabolicStopAndReverse var psar = PSAR(Symbol symbol, decimal afStart = 0.02, decimal afIncrement = 0.02, decimal afMax = 0.2, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
RegressionChannel var rc = RC(Symbol symbol, int period, decimal k, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
RateOfChange var roc = ROC(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
RateOfChangePercent var rocp = ROCP(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
RateOfChangeRatio var rocr = ROCR(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
RelativeStrengthIndex var rsi = RSI(Symbol symbol, int period, MovingAverageType movingAverageType = null, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
SimpleMovingAverage var sma = SMA(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
StandardDeviation var std = STD(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
Stochastic var sto = STO(Symbol symbol, int period, int kPeriod, int dPeriod, Resolution resolution = null)
Stochastic var sto = STO(Symbol symbol, int period, Resolution resolution = null)
Sum var sum = SUM(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
SwissArmyKnife var swiss = SWISS(Symbol symbol, int period, Double delta, SwissArmyKnifeTool tool, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
T3MovingAverage var t3 = T3(Symbol symbol, int period, decimal volumeFactor = 0.7, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
TripleExponentialMovingAverage var tema = TEMA(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
TrueRange var tr = TR(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
TriangularMovingAverage var trima = TRIMA(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
Trix var trix = TRIX(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
UltimateOscillator var ultosc = ULTOSC(Symbol symbol, int period1, int period2, int period3, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Variance var var = VAR(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Decimal] selector = null)
VolumeWeightedAveragePriceIndicator var vwap = VWAP(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.TradeBar] selector = null)
WilliamsPercentR var wilr = WILR(Symbol symbol, int period, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Candlesticks Patterns Usage
TwoCrows var twocrows = CandlestickPatterns.TwoCrows(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
ThreeBlackCrows var threeblackcrows = CandlestickPatterns.ThreeBlackCrows(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
ThreeInside var threeinside = CandlestickPatterns.ThreeInside(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
ThreeLineStrike var threelinestrike = CandlestickPatterns.ThreeLineStrike(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
ThreeOutside var threeoutside = CandlestickPatterns.ThreeOutside(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
ThreeStarsInSouth var threestarsinsouth = CandlestickPatterns.ThreeStarsInSouth(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
ThreeWhiteSoldiers var threewhitesoldiers = CandlestickPatterns.ThreeWhiteSoldiers(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
AbandonedBaby var abandonedbaby = CandlestickPatterns.AbandonedBaby(Symbol symbol, decimal penetration = 0.3, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
AdvanceBlock var advanceblock = CandlestickPatterns.AdvanceBlock(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
BeltHold var belthold = CandlestickPatterns.BeltHold(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Breakaway var breakaway = CandlestickPatterns.Breakaway(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
ClosingMarubozu var closingmarubozu = CandlestickPatterns.ClosingMarubozu(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
ConcealedBabySwallow var concealedbabyswallow = CandlestickPatterns.ConcealedBabySwallow(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Counterattack var counterattack = CandlestickPatterns.Counterattack(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
DarkCloudCover var darkcloudcover = CandlestickPatterns.DarkCloudCover(Symbol symbol, decimal penetration = 0.5, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Doji var doji = CandlestickPatterns.Doji(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
DojiStar var dojistar = CandlestickPatterns.DojiStar(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
DragonflyDoji var dragonflydoji = CandlestickPatterns.DragonflyDoji(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Engulfing var engulfing = CandlestickPatterns.Engulfing(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
EveningDojiStar var eveningdojistar = CandlestickPatterns.EveningDojiStar(Symbol symbol, decimal penetration = 0.3, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
EveningStar var eveningstar = CandlestickPatterns.EveningStar(Symbol symbol, decimal penetration = 0.3, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
GapSideBySideWhite var gapsidebysidewhite = CandlestickPatterns.GapSideBySideWhite(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
GravestoneDoji var gravestonedoji = CandlestickPatterns.GravestoneDoji(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Hammer var hammer = CandlestickPatterns.Hammer(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
HangingMan var hangingman = CandlestickPatterns.HangingMan(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Harami var harami = CandlestickPatterns.Harami(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
HaramiCross var haramicross = CandlestickPatterns.HaramiCross(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
HighWaveCandle var highwavecandle = CandlestickPatterns.HighWaveCandle(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Hikkake var hikkake = CandlestickPatterns.Hikkake(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
HikkakeModified var hikkakemodified = CandlestickPatterns.HikkakeModified(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
HomingPigeon var homingpigeon = CandlestickPatterns.HomingPigeon(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
IdenticalThreeCrows var identicalthreecrows = CandlestickPatterns.IdenticalThreeCrows(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
InNeck var inneck = CandlestickPatterns.InNeck(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
InvertedHammer var invertedhammer = CandlestickPatterns.InvertedHammer(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Kicking var kicking = CandlestickPatterns.Kicking(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
KickingByLength var kickingbylength = CandlestickPatterns.KickingByLength(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
LadderBottom var ladderbottom = CandlestickPatterns.LadderBottom(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
LongLeggedDoji var longleggeddoji = CandlestickPatterns.LongLeggedDoji(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
LongLineCandle var longlinecandle = CandlestickPatterns.LongLineCandle(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Marubozu var marubozu = CandlestickPatterns.Marubozu(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
MatchingLow var matchinglow = CandlestickPatterns.MatchingLow(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
MatHold var mathold = CandlestickPatterns.MatHold(Symbol symbol, decimal penetration = 0.5, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
MorningDojiStar var morningdojistar = CandlestickPatterns.MorningDojiStar(Symbol symbol, decimal penetration = 0.3, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
MorningStar var morningstar = CandlestickPatterns.MorningStar(Symbol symbol, decimal penetration = 0.3, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
OnNeck var onneck = CandlestickPatterns.OnNeck(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Piercing var piercing = CandlestickPatterns.Piercing(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
RickshawMan var rickshawman = CandlestickPatterns.RickshawMan(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
RiseFallThreeMethods var risefallthreemethods = CandlestickPatterns.RiseFallThreeMethods(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
SeparatingLines var separatinglines = CandlestickPatterns.SeparatingLines(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
ShootingStar var shootingstar = CandlestickPatterns.ShootingStar(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
ShortLineCandle var shortlinecandle = CandlestickPatterns.ShortLineCandle(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
SpinningTop var spinningtop = CandlestickPatterns.SpinningTop(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
StalledPattern var stalledpattern = CandlestickPatterns.StalledPattern(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
StickSandwich var sticksandwich = CandlestickPatterns.StickSandwich(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Takuri var takuri = CandlestickPatterns.Takuri(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
TasukiGap var tasukigap = CandlestickPatterns.TasukiGap(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Thrusting var thrusting = CandlestickPatterns.Thrusting(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
Tristar var tristar = CandlestickPatterns.Tristar(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
UniqueThreeRiver var uniquethreeriver = CandlestickPatterns.UniqueThreeRiver(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
UpsideGapTwoCrows var upsidegaptwocrows = CandlestickPatterns.UpsideGapTwoCrows(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
UpDownGapThreeMethods var updowngapthreemethods = CandlestickPatterns.UpDownGapThreeMethods(Symbol symbol, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)

// 1. Using basic indicator at the same resolution as source security:
// TIP -> You can use string "IBM" or the security.Symbol object
var ema = EMA("IBM", 14);

//2. Using indicator at different (higher) resolution to the source security:
var emaDaily = EMA("IBM", 14, Resolution.Daily);

//3. Indicator of a different property (default is close of bar/data):
// TIP -> You can use helper methods Field.Open, Field.High etc on the indicator selector:
var emaDailyHigh = EMA("IBM", 14, Resolution.Daily, point => ((TradeBar) point).High);

//NOTE. Some indicators require tradebars (ATR, AROON) so your selector must return a TradeBar object for those indicators.

Indicator Extensions

Indicators are composable - meaning they can be chained together to create unique combinations much like lego blocks. We support several indicator extensions as outlined below:

Extension Example Usage
.Plus()
var emaSum = ema5.Plus(ema20);
Add a fixed value or indicator value to another indicator
.Minus()
var emaDelta = ema20.Minus(ema5);
Find the difference between two indicators
.Times()
var rsiSafe = rsi.Times(0.95);
Multiply one indicator or constant value by another.
.Over()
var emaAverage = ema5.Plus(ema10).Over(2);
Divide indicator chain by constant or indicator.
.Of()
var sma = new SimpleMovingAverage("SPY", 14);
var rsiAverage= sma.Of( rsi );
Feed an indicator output into input of another.
.SMA(int period)
var rsiAvg = rsi.SMA(10);
Of extension helper for SMA method.
.EMA(int period)
var rsiAvg = rsi.EMA(10);
Of extension helper for EMA method.
.MAX(int period)
var rsiMax = rsi.MAX(10);
Of extension helper for MAX method, get max in i-samples.
.MIN(int period)
var rsiMin = rsi.MIN(10);
Of extension helper for MIN method, get min in i-samples.

public class IndicatorTests : QCAlgorithm
{
    //Save off reference to indicator objects
    RelativeStrengthIndex _rsi;
    SimpleMovingAverage _rsiSMA;

    public override void Initialize()
    {
       //In addition to other initialize logic:
       _rsi = RSI("SPY", 14); // Creating a RSI
       _rsiSMA = _rsi.SMA(3); // Creating the SMA on the RSI
    }
    
    public override void OnData(Slice data)
    {
       Plot("RSI", _rsi, _rsiSMA);
    }
}

Plotting Indicators

A helper method makes plotting indicators simple. Further information about the charting API can be found in the documentation below.

Plot<T>(string chart, params IndicatorBase<T>[] indicators) where T : BaseData
Note that not all indicators share the same base type(T) so may not work together.

//Plot array of indicator objects; extending "Indicator" type.
Plot("Indicators", sma, rsi); 

//Plot array of indicator objects; extending "TradeBarIndicator" type.
Plot("Indicators", atr, aroon); 

//For complex plotting it might be easiest to simply plot your indicators individually.

Universes

Often you may want to rotate securities in your algorithm based on filter criteria. You may only want equities above their 200 day EMA, or to only follow stocks on your custom list of symbols. This is possible using our universe selection API.

Universes are how LEAN organizes collections of data subscriptions under the hood. Each security and its data is controlled by a universe. When no universes are asking for data, the asset is removed from your algorithm. If your algorithm has open orders or holdings in a security we will not remove it from your subscriptions.

Every algorithm has a hidden "user-defined-universe". The assets in this universe are set by the AddEquity / AddForex methods. These assets are fixed and never removed from your algorithm.

Universes are refreshed every day by default, but can be refreshed as often as required. This is controlled in the algorithm.UniverseSettings variable which we'll describe in more detail below.

Basic Universe API

Adding Universes
Universes are added using the AddUniverse() method API. They are a type of data subscription which control what subscriptions are requested; and as such you can create custom universe data types. Depending on what type of universe you are adding there are many helper methods to make it easier. AddUniverse() methods take function filters as parameters, these filters must return an enumerable of Symbol objects.

Universe Settings
If you do not pass in a full universe object the UniverseSettings property is used to fill in the blanks. Changing the UniverseSettings algorithm property can be helpful to simplify adding universes. Universes have 4 key properties:

    //Popular universe settings:
    UniverseSettings.Resolution      // What resolution should added assets use
                    .Leverage        // What leverage should assets use in the universe?
                    .Fillforward     // Should asset data fill forward?
                    .MinimumTimeInUniverse // Minimum time assets should be in universe
                    .ExtendedMarketHours  // Should assets also feed extended market hours?

Once added universes are stored in the IDictionary<string, Universe> UniverseManager.

Universe Events
When universe contents are changed (securities are added or removed from the algorithm) we generate an OnSecuritiesChanged event. This allows your algorithm to know the changes in the universe state. The event passes in the SecurityChanges object containing references to the Added and Removed securities.

// Inside your initialize function:

// Subscriptions added via universe selection will have this resolution
UniverseSettings.Resolution = Resolution.Hour;

// Force securities to remain in the universe for a minimum of 30 days
UniverseSettings.MinimumTimeInUniverse = TimeSpan.FromDays(30);

// Helper: Add US-equity universe for the top 50 stocks by dollar volume
AddUniverse(Universe.DollarVolume.Top(50));

// Helper: Add US-equity universe for the bottom 50 stocks by dollar volume
AddUniverse(Universe.DollarVolume.Bottom(50));

// Helper: Add US-equity universe for the 90th dollar volume percentile
AddUniverse(Universe.DollarVolume.Percentile(90));

// Helper: Add US-equity universe for stocks between the 70th and 80th dollar volume percentile
AddUniverse(Universe.DollarVolume.Percentile(70, 80));
// Overriding the on changes event handler.
public override void OnSecuritiesChanged(SecurityChanges changes)
{
     _changes = changes;
}

Coarse Universe Selection

Coarse Universe selection is the built in universe data provided by QuantConnect. Using financial data we generate a few key properties for each symbol and allow you to filter the universe of 16,400+ symbols to receive the symbols matching your filter criteria. It uses the CoarseFundamental type.

Coarse fundamental has the following properties you can use to perform rough filtering.

class CoarseFundamental {
    public long Volume;          // Traded shares
    public decimal DollarVolume; // Traded shares x Price
    public decimal Price;        // Yesterday close price
    public Symbol Symbol;        // Asset symbol
}

Coarse filtering allows you to select an unlimited universe of symbols to analyse. You are only limited by practical memory and speed limits and may quickly run out of memory if you backtest too many symbols in parallel. These limits can be increased with a subscription.

// Take the top 50 by dollar volume using coarse 
AddUniverse(coarse => {
    return (from c in coarse
	    where c.Price > 10
	    orderby c.DollarVolume descending 
            select c.Symbol).Take(50);
});

Custom Universe Selection

Custom universes allow using an external data source as the security filtering source. Like normal custom data sources, custom universes are provided by extending BaseData. With this system you can define data formats to filter and select the data.

Each BaseData of the custom universe is 1 line of the source file. The Reader method will be called repeatedly until the date/time advances or the end of file is reached. This way you the engine can group universe data together, and pass it as a single collection into the filter function.

AddUniverse<NyseTopGainers>("myCustomUniverse", Resolution.Daily, nyseTopGainersList => {
      return from singleStockData in nyseTopGainersList 
             where singleStockData.Rank > 5
             select singleStockData.Symbol;
});
//Example custom universe data; it is virtually identical to other custom data types.
public class NyseTopGainers : BaseData {
    public int TopGainersRank;
    public override DateTime EndTime {
        // define end time as exactly 1 day after Time
	get { return Time + QuantConnect.Time.OneDay; }
	set { Time = value - QuantConnect.Time.OneDay; }
    }

    public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLiveMode) {
        return new SubscriptionDataSource(@"your-remote-universe-data", SubscriptionTransportMedium.RemoteFile);
     }

     public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode) {
         // Generate required data, then return an instance of your class.
        return new NyseTopGainers {
            Symbol = Symbol.Create(symbolString, SecurityType.Equity, Market.USA),
            Time = date,
            TopGainersRank = rank
        };
    }
}

Historical Data

Historical data can be provided in a batch request, or by "warming up" your algorithm. Batch requests feed requested data back as an enumerable you can use to manually prime your algorithm. The warm up feature feeds data to your event handlers from before your start date for a fixed period.

In live mode the history API can return data up to 5 seconds before the present moment.

Historical Data Requests

Batch history API is often easier to understand as you can manually feed data into your components which need it. If Resolution of the data request is not specified the history API uses the resolution of data you've specified with AddSecurity() or your Universe, similarly if the Symbol is not specified then history for all symbols is returned for the period.

Batch data returned as IEnumerable<Slice> slices or IEnumerable<TradeBar> slices has all the normal slice helpers - to assist using the data in your strategy, for example:

//From slice -> tradebars, or slice -> decimals.  
IEnumerable<Slice> slices = History(TimeSpan.FromDays(7), Resolution.Minute);
IEnumerable<TradeBar> bars = slices.Get("SPY"); // Bars 
IEnumerable<decimal> decimals = slices.Get("SPY", Field.Close); // Close from slice

// Many math libraries need double arrays, decimals -> double[]
double[] doubleArray = decimals.ToDoubleArray();

// Request history for specific symbol, default to AddSecurity resolution.
IEnumerable<TradeBar> bars = History("SPY", TimeSpan.FromDays(7));
// Request history for specific symbol, at specific resolution.
IEnumerable<TradeBar> bars = History("SPY", TimeSpan.FromDays(7), Resolution.Minute);

//Get last 14 bars of SPY, default to AddSecurity resolution.
//Note you can't get "14 ticks" -- getting a specific number of bars only applies to TradeBar data.
IEnumerable<TradeBar> bars = History("SPY", 14);
//Get last 14 bars of SPY, at specific resolution.
IEnumerable<TradeBar> bars = History("SPY", 14, Resolution.Minute);

// Get history for all tickers we're subscribed to, at their native resolution
IEnumerable<Slice> slices = History(TimeSpan.FromDays(7));
// Get history for all tickers we're subscribed to, at a specific resolution
IEnumerable<Slice> slices = History(TimeSpan.FromDays(7), Resolution.Minute);

Warming Your Algorithm

Warming up your algorithm causes data from before the algorithm starts to be fed into the conventional data event handlers. This system of warm up lends itself to stream style algorithms.

The data flowing to your algorithm will seamlessly pass from historical to live data. The flag bool IsWarmingUp can be used to monitor this transition.

During the warm up period you cannot submit orders. Warm up also does not support universe selection while the algorithm is warming up.

SetWarmUp(200); //Warm up 200 bars for all subscribed data.
SetWarmUp(TimeSpan.FromDays(7)); //Warm up 7 days of data.

Reality Modelling

Models can be used to improve the accuracy of your backtesting. We provide basic default models which assume you are trading on highly liquid assets, but if you are trading high volumes, or on low volume assets you should update these models to be more realistic.

All models are set on a per security basis. To set a model first fetch the security object and apply your model.

//Set IBM to have a constant $1 transaction fee. 
Securities["IBM"].FeeModel = new ConstantFeeTransactionModel(1); 

All models should be setup in your Initialize() method.

Brokerage Models

We provide a shortcut to set common models and properties relating to each of the brokerages we support. These brokerage models set fees, fill models, slippage models and trading markets for a brokerage. In addition they validate it is possible to submit trades to the brokerage (e.g. submitting equity trades to a forex only brokerage).

  • Transaction fees models
  • Supported markets
  • Slippage model
  • Validate orders and updates before they are submitted
  • Default account type (margin or cash account)
  • Support for extended market hours
  • How splits and dividends are applied to open order tickets
  • Default leverage for assets
  • Default settlement models
This gives you enormous control over your algorithm behavior and allow you to model virtually any brokerage in the world.

In addition to our default brokerage model ( DefaultBrokerageModel ), we provide brokerage models for Interactive Brokers ( InteractiveBrokersBrokerageModel ) , FXCM ( FxcmBrokerageModel ), Oanda ( OandaBrokerageModel ) and Tradier ( TradierBrokerageModel ).

Brokerage models override any other models you may set for a security.

// Set brokerage model using helper methods:
SetBrokerageModel(BrokerageName.FxcmBrokerage); // Defaults to margin account
SetBrokerageModel(BrokerageName.TradierBrokerage, AccountType.Cash); //Or override account type

// Supported brokerage names:
BrokerageName.FxcmBrokerage
             .OandaBrokerage
             .TradierBrokerage
             .InteractiveBrokersBrokerage
// You can also create your own brokerage model: IBrokerageModel
class MyBrokerage: DefaultBrokerage {
   // Custom implementation of brokerage here.
} 

SetBrokerageModel(new MyBrokerage());

Transaction Fee Models

Transaction fee models set the fees for each order. We provide customized transaction models for all brokerages, but you can also set your own. Like all models they must be set on a security by security basis.

Transaction models implement the ISecurityTransactionModel interface. If you wish to implement your own transaction model you can start with the SecurityTransactionModel and override methods you wish to change.

// Set IBM to use a fixed $1.5 per trade fee model.
Securities["IBM"].FeeModel = new ConstantFeeTransactionModel(1.5);

// Set EURUSD to use FXCM's transaction fees:
Securities["EURUSD"].FeeModel = new FxcmTransactionModel();

Slippage Models

Slippage is the difference in price between your last reported quote and the real price the trade filled at. This difference and be positive or negative, as sometimes the price can slip in your favor. In volatile markets you are likely to experience more slippage.

Slippage models implement the ISlippageModel interface. We provide the SpreadSlippageModel for forex based securities, and the ConstantSlippageModel for Equities.

Advanced users may wish to implement their own volatility based slippage model - increasing the accuracy of your backtests in volatile markets.

// Assigning securities custom slippage models:
Securities["SPY"].SlippageModel = new CustomSlippageModel()

// Custom slippage implementation
public class CustomSlippageModel : ISlippageModel {
    public decimal GetSlippageApproximation(Security asset, Order order) {
        return 0.1m;
    }
}

Fill Models

Fill models give you control over order fills. Each supported order type is passed through a dedicated method and returns an OrderEvent object. OrderEvents are used to carry information about order partial fills or errors.

The Fill Models implement the IFillModel interface. They have the following key methods:

public interface IFillModel {
    OrderEvent MarketFill(Security asset, MarketOrder order);
    OrderEvent StopMarketFill(Security asset, StopMarketOrder order);
    OrderEvent StopLimitFill(Security asset, StopLimitOrder order);
    OrderEvent LimitFill(Security asset, LimitOrder order);
    OrderEvent MarketOnOpenFill(Security asset, MarketOnOpenOrder order);
    OrderEvent MarketOnCloseFill(Security asset, MarketOnCloseOrder order);
}
We provide the ImmediateFillModel which assumes orders and immediately and completely filled.

// Set the fill models in initialize:
Securities["IBM"].FillModel = new PartialFillModel();

// Custom fill model implementation stub
public class PartialFillModel : ImmediateFillModel {
    public override OrderEvent MarketFill(Security asset, MarketOrder order) {
        //Override order event handler and return partial order fills, 
    }
}

Margin Models

Margin models control how much buying power your algorithm has to make trades. Margin calculations can be very complex and depends on many factors including the brokerage or even time of day.

Margin model implement the ISecurityMarginModel interface and default to the SecurityMarginModel class. We also provide the PatternDayTradingMarginModel to model intraday pattern day trading for US equities.

// Example of setting a security to use PDT margin models:
// Generally you do not need to adjust margin models
Securities["AAPL"].MarginModel = new PatternDayTradingMarginModel();

Settlement Models

After a trade is made brokerages settle the cash depending on the markets and account type. This is managed by our Settlement Models. The most common settlement type is immediate - where the funds are available for trading immediately. This is handled by the ImmediateSettlementModel . US Equities trading with cash accounts is typically settled 3 days after the transaction occurred. This is managed by the DelayedSettlementModel .

Settlement models implement the ISettlementModel interface. You can create your own settlement model by implementing this method. Most users will not need to create their own settlement model and can use one of the ones provided above.

// Set a security to a delayed settlement model: settle 7 days later, at 8am.
Securities["IBM"].SettlementModel = new DelayedSettlementModel(7, new TimeSpan(8, 0, 0));

Portfolio Models

Portfolio models control how order fills are applied to your portfolio. They take an OrderEvent , Security and SecurityPortfolioManager object and update the holdings to reflect the new final position. You should only need to update your portfolio model when you are create a new asset type.

Portfolio models implement the ISecurityPortfolioModel interface.

Volatility Model

The volatility model is a property of a security. Exactly how volatility is calculated varies a lot between strategies so we've provided an override point here. Volatility models get updated with data each time step and are expected to be updated immediately. This is primarily require for options backtesting.

Volatility models implement the IVolatilityModel interface. We default to the NullVolatilityModel which returns 0 volatility at all times. As a helper we also provide the RelativeStandardDeviationVolatilityModel which calculates the volatility based on standard deviation.

Charting

We provide a powerful charting API which can be build many chart types. At its simplest it can be used with a single line of code:

Plot("Series Name", value);
Plot("Series Name", value)

With this code a line-graph is added underneath your Strategy Equity chart and your requested values are displayed over time. To create a new chart (new tab) you should also specify the chart name in your request:

Plot("My Indicators", "EMA", ema);

Behind the scenes these methods create a new Chart object and add it to your algorithm, and then add a new Series object to that chart. A chart is made from many series. You can also initialize your charts manually to get more control over their look and feel.

Manually Creating Charts

In your initialize method you can use the AddChart(Chart obj) method to insert a new chart. Each chart object has an internal collection of Series objects.

In creating Series objects you must specify the name of the series, the SeriesType and the index the series operates on. The series index refers to its position in the chart - for example; if all the series are index 0, they will lay on top of each other. If each series has its own index, it will be have several mini-charts stack next to each other.

The picture below shows an EMA cross chart with both EMA series set to the same index: Using different indexes the chart looks as follows:

// In your initialize method:

// Chart - Master Container for the Chart:
var stockPlot = new Chart("Trade Plot");
// On the Trade Plotter Chart we want 3 series: trades and price:
var buyOrders = new Series("Buy", SeriesType.Scatter, 0);
var sellOrders = new Series("Sell", SeriesType.Scatter, 0);
var assetPrice = new Series("Price", SeriesType.Line, 0);
stockPlot.AddSeries(buyOrders);
stockPlot.AddSeries(sellOrders);
stockPlot.AddSeries(assetPrice);
AddChart(stockPlot);

// Later in your OnData(Slice data):
Plot("Trade Plot", "Price", data.Bars["SPY"].Close);

Supported Series Types

The charting API supports the follow series types. Nothing special is required to use these series, simply specify them for your series when creating your chart.

   SeriesType.Line
             .Scatter
             .Candle
             .Bar
             .Flag

Charting Limitations

Intensive charting generates hundreds of megabytes (200MB) of data which is far too much to stream online or display in a web browser. Because of this we limit the number of points a chart can have to 4000. If you see an error Exceeded maximum points per chart, data skipped you have hit this limit and should reduce your sampling frequency.

Logging and Debug

Debug Messages

Algorithms can send debug messages to the console using the Debug(string message) method. Debug messages are capped at 200 characters long. If multiple identical messages are sent within 1 second we rate limit the messages to avoid crashing your browser.

Debug(Time.ToString("o") + " Purchasing AAPL: " + data["AAPL"].Price);
self.Debug(Time + " Purchasing AAPL: " + slice["SPY"].Price)
this.Debug("Hello from FSharp")

Errors Messages

Algorithms can send error messages to the console using the Error(string message) method. Error messages appear red in the console so you can see them easily. Like debug messages, error messages are rate limited to avoid flooding your browser.

Error("Volatility too high, terminating algorithm.");
Quit(); //Option: Instruct algorithm to stop.
self.Error("Volatility too high, terminating algorithm.");
self.Quit(); # Optional: Instruct algorithm to stop.
this.Error("Volatility too high, triggering exit")
this.Quit()

Logging

Algorithms can save more detailed messaging to log files for later analysis using Log(string message). At the end of the backtest a link will be presented to view your results. In live trading a log viewer lets you view log results while the algorithm is running. Because of data vendor limitations price information cannot be recorded in logs.

Because of vendor limitations free users are capped to 10kb of logs per backtest, with a maximum of 3Mb per day. Users with a subscription can generate up to 100kb of logs per backtest.

Log("Additional detailed logging messages");
self.Log("Additional detailed logging messages")
this.Log("Additional detailed logging messages")

Live Trading

Supported Brokerages

Supported Brokerages

Algorithms designed in QuantConnect can be seamlessly live traded on your brokerage accounts. We send the algorithm signals to your brokerage and track the algorithm state. Algorithms can be deployed immediately at any time of the day or night. A subscription is required for live trading however many brokerages sponsor live trading for their clients.

Brokerage Description
FXCM FOREX, CFD FXCM is a direct market access (DMA) broker offering low spreads and brokerage fees as low as $0.04 per side for popular currencies. FXCM trading is available to users world-wide and accounts can be opened with as $50 USD. Live trading is free for FXCM clients.
Interactive Brokers US Equity, FOREX Interactive Brokers (IB) is a low cost provider of trade execution and clearing services for individuals, advisors, prop trading groups, brokers and hedge funds. IB's premier technology provides direct access to stocks, options, futures, forex, bonds and funds on over 100 markets worldwide from a single IB Universal account. Member NYSE, FINRA, SIPC. Subscription required for live trading.
Oanda FOREX, CFD Through our integratation with Oanda Brokerage we can offer FOREX or CFD trading to users world-wide. Accounts can be opened with as little as $1 USD. Subscription required for live trading.
Paper Trading US Equity, Forex See how your algorithm would have performed with our paper trading feature. We use real live-data feeds but a virtual brokerage to execute your trades. Each project is allocated $100,000 virtual currency to track how you've performed.

Live Trading Highlights.

Notifications

Notifications

In live trading mode we allow sending Email, SMS and Web-Hook notifications to notify you of significant events. You can send up to 20 notifications per hour. These are only sent during live trading.

Method Code Snippet
SMS Notify.Sms(string phoneNumber, string message);
Email Notify.Email(string address, string subject, string message, string data = "");
Web Hook Notify.Web(string address, object data = null);

//Send yourself an email on live trade executions
Notify.Email("myEmailAddress@gmail.com", "Live Trade Executed", "Bought 100 Shares of AAPL");

Runtime Statistics

Runtime Statistics

Runtime statistics are custom defined banner statistics displayed across the top of your live algorithm.

You can add your own runtime-statistics using the SetRuntimeStatistic(string name, string value); method. In the image above the user displays the current value of BTC: SetRuntimeStatistic("BTC", data["BTC"].Close);

Other

Frequently Asked Questions

What programming languages do you support?

We fully support C# with documentation and tutorials. We also offer beta support for Python, F#, Visual Basic and Java.

What brokerages do you support?

We currently support live trading through four brokerages. Interactive Brokers , FXCM and Oanda. We also support paper trading (forward testing your algorithm on "virtual currency").

What libraries are white listed for use on QuantConnect?

The following libraries are available in C#. If you have a library you want added please let us know(support@quantconnect.com).
Accord - Machine Learning, Math, Neuro, Statistics.
AForge - Genetic, Math, Neuro.
AlgoLib - Full technical indicator and statistics library.
Math.Net Filtering - Signal Processing Classes.
Math.Net Numerics - Statistics and Linear Algebra.
Newtonsoft Json.NET - JSON Serializer.
RestSharp - REST Wrapper.

What datasets do you have?

We have all US equities tick data since 1998, including dividends and stock splits factored into the price. This data is provided by QuantQuote. We also have 13 major currencies provided by FXCM. Please see more information in the data library.

I can't code, do you have a visual editor to design algorithms?

We do not have any plans to build a visual algorithm designer. We believe the only way to make money in the markets is with the most powerful, flexible tools available. Its this belief which has powered many of the design decisions behind QuantConnect. We were algorithmic traders ourselves for several years and built hundreds of algorithms. They ranged from the simple, to incredibly complex. The common theme among them was the need for flexibility which can only be achieved through raw code.

How do I get started learning algorithmic trading or quant finance?

Learning quantitative trading is especially difficult as there is so little public information available. We have sought to address this by building the QuantConnect University (QCU). The university is a video series which steps you through how to code a new algorithm each week. You can access the QuantConnect University inside the Algorithm Terminal, by clicking on the shield icon on the left side.

Common Errors

Runtime Error: 'AAPL' wasn't found in the TradeBars object

You're attempting to access data which is not in the TradeBars dictionary. There are two key reasons for this:
1. You have not requested data for this security in the Initialize method.
2. The data has gaps because it is not filling forward, or you're accessing the data after-hours when there won't be any price information.

Backtest Error: Error initializing algorithm: Date Invalid

You may have accidentally put invalid start and end dates into your algorithm. Or potentially you pressed backtest before the algorithm was fully saved. Please Ctrl+S to save the document, wait for its confirmation, and then click Backtest again.

Coding Environment

Local Development

We recommend using Visual Studio Community Edition as your programming environment. The community edition has the full power of Visual Studio and enables programming in C#, F#, VB and Python. If you're running on Mac or Linux you can also use MonoDevelop or Xamarin Studio.

If you prefer coding locally, you can run LEAN inside Visual Studio. The LEAN installation takes about 5 minutes and allows you to backtest locally and copy-paste your algorithms into QuantConnect.com. Check out the LEAN-Getting Started Tutorial for more information.

Learning Programming

We aim to make it as easy as possible to use QuantConnect but you still need to be able to program. We've provided some links below to get you started:

Language Type Name Producer
C# Video C# Fundamentals for Absolute Beginners Microsoft
C# Video C# Jump Start - Advanced Concepts Microsoft
C# Video Top 20 C# Questions Microsoft
F# Interactive Getting Started with F# Microsoft
F# Interactive Advanced Programming with F# Microsoft
F# Video F# Talks, Videos and Podcasts F# Foundation
Python Text/Video Introduction to Python Google
Python Interactive Code Academy - Python Code Academy
Java Video Java Tutorials Derek Banas
Java Video Java for Beginners New Boston
Visual Basic Video Visual Basic First Concepts New Boston
Visual Basic Video How To: Visual Basic Microsoft

Example Algorithms

Video Tutorials

Introduction to the IDE

The best source for example algorithms are shared community discussions. However we provide the example video tutorials below to help get you started with QuantConnect.

Name Description
Moving Average Cross The iconic moving average cross strategy from first principles. Watch on YouTube
Sell In May Fact or Fiction? Test the Sell in May Theory with hard data to see if it really is better to make your portfolio flat for May-October each year. Watch on YouTube
RSI with Martingale In this tutorial we use Martingale; a bet sizing technique for increasing odds of winning at the expense of increased risk. Watch on YouTube

There are hundreds of code snippets and example algorithms in the QuantConnect University accessible through the Terminal.

QuantConnect University

Language Name  
C# Basic Template Clone
C# Moving Average Cross Clone
C# Sell In May Clone
C# RSI with Martingale Position Sizing Clone
C# How Do I Use Scheduled Events? Clone
C# How Do I Warm Up an Algorithm? Clone
C# How Do I Use Order Tickets? Clone
C# How Do I Use Stop-Limit Orders? Clone
C# How do I Retrieve Historical Data? Clone
C# Strategy Example: Hello World - Basic Template Clone
C# How Do I Import Custom Data? Clone
C# How Do I Import Yahoo Data? Clone
C# How Do I Import Yahoo Data? Clone
C# How Do I Import Quandl Data? Clone
C# Strategy Example: RSI with Martingale Position Sizing Clone
C# How Do I Use Indicators? (ATR, BB, MACD, EMA, SMA, RSI) Clone
C# How do I Use the Stochastic Indicator? Clone
C# Oanda Basic Template (C#) Clone
C# How do I Use Consolidators? Clone
C# How Do I Create a Rolling Window of Data? Clone
C# Strategy Example: Moving Average Cross Strategy Clone
C# How Do I Import My Training Data Sets? Clone
Py Strategy Example: Hello World - Basic Template (Py) Clone
C# How Do I Set Zero Transaction Fees? Clone
Py Oanda/Oanda Basic Template (Py) Clone
C# How Do I Backtest Binary Options? Clone
C# How Do I Use EMA-SMA Indicator? Clone
C# Strategy Example: Sell In May Clone
C# How Do I Use Limit Orders? Clone
C# How Do I Warm Up an Algorithm? Clone
C# How Do I Use Live Custom Data? Clone
C# Strategy Example: Complete Algorithm Framework Clone
C# Strategy Example: Rotating Portfolio of Global ETFs Clone
C# How Do I Create a Parameterized Algorithm? Clone
C# How Do I Filter Bad Data-Ticks? Clone
F# Strategy Example: Hello World - Basic Template (F#) Clone
C# How Do I Create Custom Charts? Clone
C# How Do I Create Custom Charts? Clone
C# Strategy Example: SPY Dollar Cost Average Clone
C# How Do I Use FOREX-Currency Data? Clone
C# Strategy Example: Chilean Portfolio Rotation Clone
C# Weather Based Rebalancing Clone
C# How Do I Use Raw (Unadjusted) Data? Clone
C# How do I Retrieve Historical Data? Clone
C# How Do I Import Yahoo Data? Clone
C# How Do I Use End of Day Events? Clone
C# How Do I Ensure There Is Always Data? Clone
C# How Do I Use Tick Data? Clone
F# How Do I Create a Rolling Window of Data? (F#) Clone
C# How do I Use the Stochastic Indicator? Clone
C# Strategy Example: Sell In May Clone
F# How do I Use Renko Consolidators? (F#) Clone
C# How Do I Use Stop-Limit Orders? Clone
C# How Do I Use Bitcoin Data? Clone
C# How Do I Use Total Returns Price Normalization? Clone
C# How Do I Create Custom Transaction Models? Clone
C# How Do I Use Live Custom Data? Clone
C# What Features Are Available In Live Trading? Clone
F# How Do I Import Yahoo Data? (F#) Clone
C# How Do I Import Futures Data? Clone
C# How Do I Use Limit Orders? Clone
F# Oanda/Oanda Basic Template (F#) Clone
C# How Do I Import Multiple Quandl Data Sets? Clone
C# How Do I Handle Brokerage Error Messages? Clone
C# How Do I Make Any TimeSpan TradeBars? Clone
F# How Do I Filter Bad Data-Ticks? (F#) Clone