---
title: "Key Concepts"
description: "The Portfolio object provides information about the whole portfolio state."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/portfolio/key-concepts
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/portfolio/key-concepts.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/08%20Portfolio/01%20Key%20Concepts
modified: 2026-10-29
index: https://www.quantconnect.com/llms.txt
---

# Key Concepts

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

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

## Introduction

The `portfolio` object provides information about the investment state and history of all of the securities that have been in the algorithm during its lifetime.

The `portfolio` property of the `QCAlgorithm` class is a dictionary where the keys are `Symbol` objects and the values are `SecurityHolding` objects. The `SecurityHolding` object provides information about the investment state and history of a security.

To get the keys or values of a LEAN dictionary, call the `keys()` and `values()` methods with parentheses. For more information, see [Dictionary Types](https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/python-and-lean.md#05-Dictionary-Types).

## Investment Status

To get the investment status of your strategy, access the `invested` property of a `portfolio` object.

```python
# Get the investment status and return True if the portfolio is invested.
invested = self.portfolio.invested
```

## Holdings Status

You can identify a position as long- or short-biased based on the sign of the holding quantity. Long positions have a positive quantity and short positions have a negative quantity. The `SecurityHolding` object has the following properties to describe the holding status.

```python
# Create a SecurityHolding object.
holdings = self.portfolio[self._symbol]
# Check the holding quantity of the security.
quantity = holdings.quantity
# Check the investing status of the security.
invested = holdings.invested
# Check if the strategy is long or short the security.
is_long = holdings.is_long
is_short = holdings.is_short
```

The quantity can be lower than the minimum order size. If the quantity is less than the lot size of the asset, the `invested` property is `False`.

## Buying Power

To get the maximum buying power in your [account currency](https://www.quantconnect.com/docs/v2/writing-algorithms/initialization.md#03-Set-Account-Currency) you can use for a given `Symbol` and order direction, call the `get_buying_power` method.

```python
# Check the total amount of buying power available. Margin available varies by order direction and current holdings.
available_buying_power = self.portfolio.get_buying_power(self._symbol, OrderDirection.BUY)
```

For more information about buying power, see [Buying Power](https://www.quantconnect.com/docs/v2/writing-algorithms/reality-modeling/buying-power.md).

## Cost Averaging Accounting

LEAN uses the cost averaging accounting method, which determines the cost of your holdings by taking a weighted average of all your purchase prices. For example, say you place the following buy orders:

1. Buy 10 ABC @ $10
2. Buy 5 ABC @ $11
3. Buy 20 ABC @ $14
4. Buy 3 ABC @ $9

In the preceding example, the average cost of your ABC position is (10*10 + 5*11 + 20*14 + 3*9) / (10 + 5 + 20 + 3) = 12.1579/share. In contrast, if you use the first-in, first-out (FIFO) accounting method, the cost of the first 10 shares is 10/share, not 12.1579/share.

To get the cost of your security holdings, use the `holdings_cost` property of the [SecurityHolding object](https://www.quantconnect.com/docs/v2/writing-algorithms/portfolio/holdings.md). If you fill buy and sell orders, the holdings cost is the product of the holding quantity and the average price. For example, the following table shows how the average price and holdings cost changes with each buy and sell order order in a long position:

| Order Quantity | Fill Price ($) | Holding Quantity | Average Price ($) | Holdings Cost ($) |
| --- | --- | --- | --- | --- |
| 2 | 10 | 2 | (2 * 10) / 2 = 10 | 2 * 10 = 20 |
| -1 | 11 | 1 | (1 * 10) / 1 = 10 | 1 * 10 = 10 |
| 1 | 12 | 2 | (1 * 10 + 1 * 12) / 2 = 11 | 2 * 11 = 22 |
| -2 | 13 | 0 | 0 | 0 * 0 = 0 |

The following table shows how the average price and holdings cost changes with each buy and sell order order in a short position:

| Order Quantity | Fill Price ($) | Holding Quantity | Average Price ($) | Holdings Cost ($) |
| --- | --- | --- | --- | --- |
| -2 | 10 | -2 | (-2 * 10) / -2 = 10 | -2 * 10 = -20 |
| 1 | 11 | -1 | (-1 * 10) / -1 = 10 | -1 * 10 = -10 |
| -1 | 12 | -2 | (-1 * 10 + (-1) * 12) / -2 = 11 | -2 * 11 = -22 |
| 2 | 13 | 0 | 0 | 0 * 0 = 0 |

Note that when you decrease the position size without closing the trade, the average price doesn't change because the denominator and the coefficients in the numerator of its formula are scaled by the quotient of the current holding quantity and the previous holding quantity. For instance, if the last row in the preceding table had an order quantity 1, the holding quantity would be -1 and the average price would be

$$ \frac{(-1 * q) * 10 + (-1 * q) * 12}{-2 * q} $$ $$ =\frac{(-1 * \frac{-1}{-2}) * 10 + (-1 * \frac{-1}{-2}) * 12}{-2 * \frac{-1}{-2}} $$ $$ =\frac{\frac{-1}{2} * 10 + \frac{-1}{2} * 12}{-1 } $$ $$ =\frac{-5 - 6}{-1} = 11 $$

## Performance Statistics

The `portfolio` object has a collection of properties that provide the combined state of [holdings](https://www.quantconnect.com/docs/v2/writing-algorithms/portfolio/holdings.md) and the [cashbook](https://www.quantconnect.com/docs/v2/writing-algorithms/portfolio/cashbook.md).

```python
# Access key statistics of the portfolio using the properties of the portfolio object.
value = self.portfolio.total_portfolio_value
total_margin_used = self.portfolio.total_margin_used
margin_remaining = self.portfolio.margin_remaining
total_net_profit = self.portfolio.total_net_profit
total_unrealised_profit = self.portfolio.total_unrealised_profit
total_fees = self.portfolio.total_fees
cash = self.portfolio.cash
```

## Properties

The `portfolio` object has the following properties:

*Members of `QuantConnect.Securities.SecurityPortfolioManager` (JSON): https://www.quantconnect.com/services/inspector?type=T:QuantConnect.Securities.SecurityPortfolioManager&language=python*

## Examples

The following examples demonstrate common practices for handling the portfolio.

### Example 1: Martingale

The following algorithm trades a Martingale strategy on AAPL. The trend indicated by an EMA indicator follows the trend with a $1 per share stop-loss and a $2 take-profit level. Yet, if the last trade is lost, it will double the next trading size to recover the last loss.

```python
class PortfolioExampleAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)

        # Request AAPL's data to trade.
        self.aapl = self.add_equity("AAPL").symbol

        # Create an EMA indicator to generate trading data.
        self._ema = self.ema(self.aapl, 20, Resolution.DAILY)
        # Warm up the indicator to provide an immediate trade signal.
        self.warm_up_indicator(self.aapl, self._ema, Resolution.DAILY)

        self.next_quantity = 1

    def on_data(self, slice: Slice) -> None:
        # Ride on the AAPL trend indicated by the EMA indicator.
        if not self.portfolio.invested:
            if self.securities[self.aapl].price >= self._ema.current.value:
                self.market_order(self.aapl, self.next_quantity)
            else:
                self.market_order(self.aapl, -self.next_quantity)
        else:
            holding = self.portfolio[self.aapl]
            # Stop loss at $1 per share.
            if holding.unrealized_profit <= -1 * self.next_quantity:
                self.liquidate(self.aapl)
                # Double the next quantity to recover this loss.
                self.next_quantity *= 2
            # Take profit at $2 per share.
            elif holding.unrealized_profit >= 2:
                self.liquidate(self.aapl)
                self.next_quantity = 1
```
