Brokerages

Public

Introduction

QuantConnect enables you to run your algorithms in live mode with real-time market data.

Public is a commission-free investing platform founded in 2019 and operated in the United States by Public Holdings, Inc. Its brokerage services are provided by Open to the Public Investing, Inc., a registered broker-dealer and member of FINRA and SIPC. Public provides access to trading Equities, Equity Options, Index Options, and Crypto through its Trading API, with no commissions on US-listed stocks and options during regular market hours.

Account Types

Public supports cash and margin accounts. To set the account type in an algorithm, see the Public brokerage model documentation.

Create an Account

Follow the account creation wizard on the Public website to create a Public account.

Create API Credentials

To trade with the Public API, you need a secret key and the account number of the Public account you want to trade. The following steps summarize how to get them. For a video walkthrough, see The Public API: How to Program Your Trading of Stocks, Options, and More on the Public YouTube channel.

  1. Apply for API access on the Public API page. Fill out and submit the form, and then wait for the Public concierge team to approve your application.
  2. After approval, log in to Public.com, open the Settings menu, click Security on the far right side of the menu, and then click API in the left panel.
  3. Generate your secret key. You can keep up to two keys at once and remove a key at any time. Keys inherit your account's permissions and allow read and write access, and LEAN exchanges the secret key for short-lived access tokens automatically.
  4. Note the account number of the Public account you want to trade. Public lets you have more than one account, so the account number picks which one to trade.

Paper Trading

The Public API doesn't support paper trading, but you can follow these steps to simulate it with QuantConnect:

  1. In the Initializeinitialize method of your algorithm, set the Public brokerage model and your account type.
  2. Deploy your algorithm with the QuantConnect Paper Trading brokerage.

Asset Classes

Our Public integration supports the following asset classes:

You may not be able to trade all assets with Public. For example, if you live in the EU, you can't trade US ETFs. Check with your local regulators to know which assets you are allowed to trade. You may need to adjust settings in your brokerage account to live trade some assets.

Data Providers

Public doesn't provide a live data feed. The QuantConnect data provider supplies US Equity and Crypto data during live trading. For Equity Options, Index, and Index Options data, use the Polygon data provider or a data feed from another brokerage, such as Tastytrade or Charles Schwab. For more information about live data providers, see Datasets.

Orders

We model the Public API by supporting several order types, the TimeInForce order property, and order updates. When you deploy live algorithms, you can place manual orders through the IDE.

Order Types

The following table describes the available order types for each asset class that our Public integration supports:

Order TypeEquityEquity OptionsIndex OptionsCrypto
Marketgreen checkgreen checkgreen checkgreen check
Limitgreen checkgreen checkgreen checkgreen check
Stop marketgreen checkgreen checkgreen checkgreen check
Stop limitgreen checkgreen checkgreen checkgreen check
Combo limitgreen checkgreen check

Order Properties

We model custom order properties from the Public API. The following table describes the members of the PublicOrderProperties object that you can set to customize order execution.

PropertyData TypeDescriptionDefault Value
TimeInForcetime_in_forceTimeInForceA TimeInForce instruction to apply to the order. The following instructions are supported:
  • DayDAY
  • GoodTilCanceledGOOD_TIL_CANCELED
  • GoodTilDategood_til_date
Public natively supports only day and good-til-date orders, so LEAN sends good-til-canceled orders as good-til-date orders that expire 90 days out.
TimeInForce.GoodTilCanceledTimeInForce.GOOD_TIL_CANCELED
OutsideRegularTradingHoursoutside_regular_trading_hoursboolIf set to true, allows the order to trigger or fill outside of regular trading hours. This property applies to Equity limit orders with a day time-in-force only, since Public only accepts limit orders in the extended session.falseFalse
UseMarginuse_marginbool?Controls the buying power the order uses. If set to true, the order uses margin buying power when the account allows it. If set to false, the order uses cash-only (settled cash) buying power. If you don't set it, orders on margin accounts use margin buying power and orders on cash accounts always use cash-only buying power.nullNone

Updates

We model the Public API by supporting order updates for single-leg orders. Public doesn't support updating combo (multi-leg) orders.

Handling Splits

If you're using raw data normalization and you have active orders with a limit, stop, or trigger price in the market for a US Equity when a stock split occurs, the following properties of your orders automatically adjust to reflect the stock split:

  • Quantity
  • Limit price
  • Stop price
  • Trigger price

Rate Limit

The Public API limits the rate of requests, so our Public integration throttles its requests to 10 requests per second. Public also allows up to 10 pending orders that open new positions on the same underlying.

To avoid hitting these limits, design your algorithm to issue orders sparingly.

Fees

Public trading for Equity, Equity Options, and Options on ETFs is commission-free during regular market hours. Equity trades during extended hours cost $2.99 per trade, Index Options cost $0.50 per contract, and Crypto trades carry a fee that depends on the order amount. To view the Public trading fees, see the Fee Schedule page on the Public website. To view how we model their fees, see Fees.

Margin

We model buying power and margin calls to ensure your algorithm stays within the margin requirements.

Trading on margin with Public, which includes short selling and buying for more than your settled cash, requires your account to hold at least $2,000 of cash, equities, and bonds. The UseMarginuse_margin order property selects the buying power each order uses.

Slippage

Orders through Public do not experience slippage in backtests and QuantConnect Paper Trading. In live trading, your orders may experience slippage.

To view how we model Public slippage, see Slippage.

Fills

QuantConnect fills market orders immediately and completely in backtests and QuantConnect Paper Trading. In live trading, if the quantity of your market orders exceeds the quantity available at the top of the order book, your orders are filled according to what is available in the order book.

To view how we model Public order fills, see Fills.

Settlements

If you trade with a margin account, trades settle immediately

To view how we model settlement for Public trades, see Settlement.

Security and Stability

When you deploy live algorithms with Public, we don't save your credentials.

Deposits and Withdrawals

You can deposit and withdraw cash from your brokerage account while you run an algorithm that's connected to the account. We sync the algorithm's cash holdings with the cash holdings in your brokerage account every day at 7:45 AM Eastern Time (ET).

Demo Algorithm

The following algorithm demonstrates the functionality of the Public brokerage:

// Demonstrate Public brokerage functionality with an EMA crossover strategy on SPY.
public class PublicDemoAlgorithm : QCAlgorithm
{
    private ExponentialMovingAverage _fast;
    private ExponentialMovingAverage _slow;

    public override void Initialize()
    {
        SetStartDate(2024, 9, 1);
        SetEndDate(2024, 12, 31);
        SetCash(100000);
        SetBrokerageModel(BrokerageName.Public, AccountType.Margin);
        var symbol = AddEquity("SPY", Resolution.Daily).Symbol;
        _fast = EMA(symbol, 10, Resolution.Daily);
        _slow = EMA(symbol, 50, Resolution.Daily);
    }

    public override void OnData(Slice slice)
    {
        if (!_slow.IsReady) return;
        if (_fast > _slow && !Portfolio.Invested)
            SetHoldings("SPY", 1);
        else if (_fast < _slow && Portfolio.Invested)
            Liquidate();
    }
}
# Demonstrate Public brokerage functionality with an EMA crossover strategy on SPY.
class PublicDemoAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self.set_cash(100000)
        self.set_brokerage_model(BrokerageName.PUBLIC, AccountType.MARGIN)
        symbol = self.add_equity("SPY", Resolution.DAILY).symbol
        self._fast = self.ema(symbol, 10, Resolution.DAILY)
        self._slow = self.ema(symbol, 50, Resolution.DAILY)

    def on_data(self, slice: Slice) -> None:
        if not self._slow.is_ready:
            return
        if self._fast.current.value > self._slow.current.value and not self.portfolio.invested:
            self.set_holdings("SPY", 1)
        elif self._fast.current.value < self._slow.current.value and self.portfolio.invested:
            self.liquidate()

Deploy Live Algorithms

You must have an available live trading node for each live trading algorithm you deploy.

Follow these steps to deploy a live algorithm:

  1. Open the project you want to deploy.
  2. Click the Lightning icon Deploy Live icon.
  3. On the Deploy Live page, click the Brokerage field and then click Public from the drop-down menu.
  4. Enter your Public secret key and account number.
  5. To generate your API credentials, see Account Types. Your account details are not saved on QuantConnect.

  6. Click the Node field and then click the live trading node that you want to use from the drop-down menu.
  7. (Optional) In the Data Provider section, click Show and change the data provider or add additional providers.
  8. Public doesn't provide a live data feed, so use a data provider for the securities you trade. The QuantConnect data provider supplies US Equity and Crypto data. For Equity Options, Index, and Index Options data, use the Polygon data provider or a data feed from another brokerage.

  9. (Optional) Set up notifications.
  10. Configure the Automatically restart algorithm setting.
  11. By enabling automatic restarts, the algorithm will use best efforts to restart the algorithm if it fails due to a runtime error. This can help improve the algorithm's resilience to temporary outages such as a brokerage API disconnection.

  12. Click Deploy.

The deployment process can take up to 5 minutes. When the algorithm deploys, the live results page displays. If you know your brokerage positions before you deployed, you can verify they have been loaded properly by checking your equity value in the runtime statistics, your cashbook holdings, and your position holdings.

Troubleshooting

The following table describes errors you may see when deploying to Public:

Error Message(s)Possible Cause and Fix
A deposit of $<amount> is required to place this order
The order costs more than the buying power available for it, so Public rejects it at submission and LEAN reports an invalid order event. The deposit amount in the message is the shortfall. Size the order within your available buying power, or set the UseMarginuse_margin order property to trueTrue on a margin account to use margin buying power.
You can have up to 10 pending orders opening new positions on the same underlying
Public allows up to 10 pending orders that open new positions per underlying. Cancel one or more pending orders on the underlying before placing a new trade.
Short selling require margin
Trading on margin, which includes short selling and buying for more than your settled cash, requires at least $2,000 of cash, equities, and bonds in your account. Deposit funds to meet the minimum or avoid orders that need margin.

If you need further support, open a new support ticket and add the live deployment with the error.

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: