Generate code in 3 minutes
Enter your idea and AI generates runnable code.
To check if your portfolio currently holds a position in a specific stock within the QuantConnect Lean engine, you should access the self.portfolio object. This object is a dictionary keyed by the security's Symbol.
Here are the primary methods to check your positions using the modern PEP8 Python API.
.invested Property (Recommended)The cleanest way to check if you have any position (Long or Short) is to use the boolean property .invested.
# Check if we have any position in the symbol
if self.portfolio[self.symbol].invested:
self.log(f"We are already invested in {self.symbol}")
else:
self.buy(self.symbol, 10)
If you need to know the specific size of the position or distinguish between Long and Short manually, check .quantity.
# Check if we have a specific quantity
current_qty = self.portfolio[self.symbol].quantity
if current_qty == 0:
self.log("No position")
elif current_qty > 0:
self.log(f"Long position of {current_qty} shares")
else:
self.log(f"Short position of {current_qty} shares")
QuantConnect provides helper properties to specifically check the direction of the trade.
position = self.portfolio[self.symbol]
if position.is_long:
self.log("Currently Long")
if position.is_short:
self.log("Currently Short")
Below is a fully functional example demonstrating how to implement these checks inside the on_data method to prevent opening duplicate positions.
from AlgorithmImports import *
class PortfolioCheckAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2023, 1, 1)
self.set_end_date(2023, 6, 1)
self.set_cash(100000)
# Add Equity and save the Symbol object
self.spy = self.add_equity("SPY", Resolution.DAILY).symbol
def on_data(self, data: Slice):
# Ensure data exists for the symbol before accessing
if not data.contains_key(self.spy):
return
# 1. Check if we are NOT invested before buying
if not self.portfolio[self.spy].invested:
self.set_holdings(self.spy, 0.5)
self.debug("Purchased SPY - Position Opened")
# 2. Check if we are invested to manage exit logic
else:
# Example: Liquidate if profit is > 5%
# unrealized_profit_percent returns a decimal (e.g., 0.05 for 5%)
pnl_pct = self.portfolio[self.spy].unrealized_profit_percent
if pnl_pct > 0.05:
self.liquidate(self.spy)
self.debug("Profit target hit - Position Closed")
Q: What is the difference between self.Portfolio and self.portfolio?
A: self.Portfolio is the older C#-style PascalCase naming convention. self.portfolio is the newer PEP8 snake_case convention. Both work in Python, but self.portfolio is recommended for new algorithms to ensure consistency with standard Python practices.
Q: Does self.portfolio[symbol].invested return true for pending orders?
A: No. The .invested property only returns True if the order has been filled and the asset is currently held in your holdings. To check for pending orders, you must check self.transactions.get_open_orders(symbol).
Q: How do I check if my entire portfolio is empty (100% Cash)?
A: You can check self.portfolio.invested. If this returns False, it means you hold no positions in any security and are entirely in cash.
Q: Can I check the average entry price of my position?
A: Yes. You can access self.portfolio[symbol].average_price to get the average cost basis of your current holdings.