Managing stocks and ETFs across accounts gets messy fast, and guessing your gains or sector exposure is no way to invest. Centralize everything, track real performance, and get notified when something needs your attention instead of reacting late. This guide walks you through pulling live stock prices, calculating gains and losses, monitoring sector exposure, and setting alerts for meaningful price changes. And hereās the thing: this comprehensive guide will show you how to build an investment portfolio tracker in Excel to monitor all your holdings in one place and send automated email alerts for significant market moves.
1. Design The Column StructureĀ
Open MS Excel and decide on the column structure based on the investment details you want to track. Fill in the header rows. I have used the structure below:Ā
A1: Symbol – Stock ticker (AAPL, MSFT, SPY)Ā
B1: Company Name – Full company/fund nameĀ
C1: Asset Type – Stock, ETF, Bond, CryptoĀ
D1: Shares – Number of shares ownedĀ
E1: Avg Cost – Average purchase price per shareĀ
F1: Total Cost – Total investment amountĀ
G1: Current Price – Live market price (auto-updated)Ā
H1: Market Value – Current total valueĀ
I1: Gain/Loss $ – Profit or loss in dollarsĀ
J1: Gain/Loss % – Return percentageĀ
K1: Sector – Industry sector (Technology, Healthcare, etc.)Ā
L1: Notes – Purchase date, strategy notes
2. Fill in Sample DataĀ
Insert a sample of 20 diverse stock and ETF holdings across multiple sectors. Include technology stocks, financial services, healthcare, consumer goods, energy, and index ETFs to create a diversified portfolio. Leave Columns F through J empty initially, as they will be filled automatically with formulas in the upcoming steps.Ā
Sample Holdings:Ā
3. Getting Live Stock PricesĀ
Now weāll set up automatic price feeds. Excel Desktop has multiple methods, but weāll use the most reliable approach for consistent results.Ā
Method 1: Using Stock Data Types Ā
Follow the following steps below:Ā
- Select ticker symbols in column A (A2:A21)Ā
- Go to Data tabĀ Ā
- Click Stocks buttonĀ
- Wait for conversion (10-15 seconds for all 20 stocks)Ā
- Verifyy success by seeing a small icon next to each tickerĀ
Extract Current Price in Column G:Ā
Click cell G2 and enter this formula: =A2.PriceĀ
This extracts the live current price from the Stock data type. Copy this formula down to G3:G21.
Method 2: Alternative Solution for Compatibility IssuesĀ
Sometimes the āSTOCKā Function in excel depends upon the latest version and geography. If Stock data types donāt work on your system, use this STOCKHISTORY function:Ā
Click cell G2 and enter: =INDEX(STOCKHISTORY(A2,TODAY()-1,TODAY()),1,5)Ā
This pulls the most recent closing price. Copy down to G3:G21.Ā
4. Building Smart Calculation FormulasĀ
Now weāll add formulas to automatically calculate your investment performance. These formulas update instantly whenever prices change.Ā
A. Total Cost Formula (Column F)Ā
Click cell F2 and enter this formula: =D2*E2Ā
This calculates: Shares Ć Average Cost = Total InvestmentĀ
Copy this formula down to F3:F21.Ā
B. Market Value Formula (Column H)Ā
Click cell H2 and enter this formula: =D2*G2Ā
This calculates: Shares Ć Current Price = Current Market ValueĀ
Copy down to H3:H21.Ā
C. Gain/Loss in Dollars (Column I)Ā
Click cell I2 and enter this formula: =H2-F2Ā
This calculates: Market Value ā Total Cost = Profit/LossĀ
Copy down to I3:I21.Ā
D. Gain/Loss Percentage (Column J)Ā
Click cell J2 and enter this formula: =IF(F2=0,0,(I2/F2)*100)Ā
Then format column J as PercentageĀ Ā
This calculates: (Gain/Loss Ć· Total Cost) = Return PercentageĀ
Copy down to J3:J21.Ā
5. Build A Summary DashboardĀ
Add a portfolio summary section starting at row 24 to track key metrics:Ā
A. Total Portfolio Value (In USD)Ā
Add this formula to calculate total current value: =SUM(H2:H21)Ā
B. Total Cost Basis (In USD)Ā
Add this formula to calculate total investment: =SUM(F2:F21)Ā
C. Total Gain/Loss ($)Ā
Add this formula to calculate total profit/loss: =B27-B28Ā
(Assuming B27 has portfolio value and B28 has cost basis)Ā
D. Total Return (%)Ā
Add this formula to calculate overall return percentage: =(B29/B28)Ā
E. Number of HoldingsĀ
Add this formula to count active positions: =COUNTA(A2:A21)Ā
F. Best PerformerĀ
Add this formula to identify top gainer: =INDEX(A2:A21,MATCH(MAX(J2:J21),J2:J21,0))Ā
G. Worst PerformerĀ
Add this formula to identify biggest loser: =INDEX(A2:A21,MATCH(MIN(J2:J21),J2:J21,0))Ā
6. Creating Visual Alerts with Conditional FormattingĀ
Now set up conditional formatting to highlight significant movements and performance:Ā
Format Gain/Loss $ Column (I):Ā
- Select column I (I2:I21)Ā
- Go to Home : Conditional Formatting : New RuleĀ
- Format cells > 0: Light green fill with dark green textĀ
- Add another rule for
Format Gain/Loss % Column (J):Ā
Repeat the same green/red formatting process for column J.Ā
Add Data Bars to Market Value (Column H):Ā
- Select H2:H21Ā
- Conditional Formatting : Data Bars : Blue Gradient FillĀ
This creates visual bars showing the relative size of each position.Ā
Now your tracker will automatically highlight gains in green and losses in red, making it easy to spot performance at a glance.Ā
7. Set up Automated Email AlertsĀ
Since Excel Desktop doesnāt have built-in email automation, weāll use Google App Script for automated email alerts.Ā
Steps for Setting Up Google Apps Script:Ā
- Export to CSV: From Excel, save as CSVĀ
- Upload to Google Sheets: Import the CSV fileĀ
- Add GOOGLEFINANCE: Replace column G with =GOOGLEFINANCE(A2,”price”)Ā
- Access Apps Script: In Google Sheets, go to Extensions : Apps ScriptĀ
- Delete Default Code: Remove existing codeĀ
- Rename Project: Click āUntitled projectā and rename to āPortfolio AlertsāĀ
Paste this complete script into the Code.gs file:Ā
function checkStockAlerts() {Ā
Ā const sheet = SpreadsheetApp.getActiveSheet();Ā
Ā const data = sheet.getDataRange().getValues();Ā
Ā const headers = data[0];Ā
Ā Ā // Find column indicesĀ
Ā const symbolCol = headers.indexOf(‘Symbol’);Ā
Ā const companyCol = headers.indexOf(‘Company Name’);Ā
Ā const priceCol = headers.indexOf(‘Current Price’);Ā
Ā const dayChangeCol = headers.indexOf(‘Day Change %’);Ā
Ā const gainLossCol = headers.indexOf(‘Gain/Loss %’);Ā
Ā const sharesCol = headers.indexOf(‘Shares’);Ā
Ā const marketValueCol = headers.indexOf(‘Market Value’);Ā
Ā Ā let alerts = [];Ā
Ā Ā // Loop through each row (skip header)Ā
Ā for (let i = 1; i 5% or = 5) {Ā
Ā alerts.push({Ā
Ā Ā Ā symbol: symbol,Ā
Ā Ā Ā company: company,Ā
Ā Ā Ā type: ‘Daily Movement’,Ā
Ā Ā Ā message: `$Ā
Ā symbol: ‘TEST’,Ā
Ā company: ‘Test Company’,Ā
Ā type: ‘Daily Movement’,Ā
Ā message: ‘TEST: 5.5% day change (This is a test)’,Ā
Ā details: ‘Current Price: $100.00 ($Ā
Ā symbol: ‘TEST’,Ā
Ā company: ‘Test Company’,Ā
Ā type: ‘Daily Movement’,Ā
Ā message: ‘TEST: 5.5% day change (This is a test)’,Ā
Ā details: ‘Current Price: $100.00 ): $ Shares: 10 % day change`,Ā
Ā Ā Ā details: `Current Price: $ Shares: 10 | Shares: ${shares} | Value: ${marketValue.toFixed(2)}`Ā
Ā });Ā
Ā Ā Ā }Ā
Ā Ā Ā // Alert if gain/loss milestone reachedĀ
Ā Ā Ā if (gainLoss >= 50) {Ā
Ā alerts.push({Ā
Ā Ā Ā symbol: symbol,Ā
Ā Ā Ā company: company,Ā
Ā Ā Ā type: ‘Profit Milestone’,Ā
Ā Ā Ā message: `${symbol}: +${gainLoss.toFixed(2)}% gain reached!`,Ā
Ā Ā Ā details: `Current Price: ${currentPrice.toFixed(2)} | Position Value: ${marketValue.toFixed(2)}`Ā
Ā });Ā
Ā Ā Ā } else if (gainLoss 0) {Ā
Ā Ā Ā sendAlertEmail(alerts);Ā
Ā Ā Ā Logger.log(‘Alert email sent with ‘ + alerts.length + ‘ alert(s)’);Ā
Ā } else {Ā
Ā Ā Ā Logger.log(‘No alerts to send at this time’);Ā
Ā }Ā
}Ā
function sendAlertEmail(alerts) {Ā
Ā // CHANGE THIS TO YOUR EMAIL ADDRESSĀ
Ā const emailAddress=”[emailĀ protected]”;Ā
Ā Ā // Build email subjectĀ
Ā const subject=”šØ Stock Alert: ” + alerts.length + ‘ Position(s) Require Attention’;Ā
Ā Ā // Build email bodyĀ
Ā let body = ‘Portfolio Alert Summary\n’;Ā
Ā body += ‘āāāāāāāāāāāāāāāāāāāāāāāāāāā\n\n’;Ā
Ā Ā // Group alerts by typeĀ
Ā const dailyMovement = alerts.filter(a => a.type === ‘Daily Movement’);Ā
Ā const profitMilestones = alerts.filter(a => a.type === ‘Profit Milestone’);Ā
Ā const lossWarnings = alerts.filter(a => a.type === ‘Loss Warning’);Ā
Ā Ā // Daily movement alertsĀ
Ā if (dailyMovement.length > 0) {Ā
Ā Ā Ā body += ‘š SIGNIFICANT DAILY MOVEMENTS:\n\n’;Ā
Ā Ā Ā dailyMovement.forEach(alert => {Ā
Ā body += alert.message + ‘\n’;Ā
Ā body += alert.details + ‘\n\n’;Ā
Ā Ā Ā });Ā
Ā }Ā
Ā Ā // Profit milestone alertsĀ
Ā if (profitMilestones.length > 0) {Ā
Ā Ā Ā body += ‘š° PROFIT MILESTONES:\n\n’;Ā
Ā Ā Ā profitMilestones.forEach(alert => {Ā
Ā body += alert.message + ‘\n’;Ā
Ā body += alert.details + ‘\n\n’;Ā
Ā Ā Ā });Ā
Ā }Ā
Ā Ā // Loss warning alertsĀ
Ā if (lossWarnings.length > 0) {Ā
Ā Ā Ā body += ‘ā ļø LOSS WARNINGS:\n\n’;Ā
Ā Ā Ā lossWarnings.forEach(alert => {Ā
Ā body += alert.message + ‘\n’;Ā
Ā body += alert.details + ‘\n\n’;Ā
Ā Ā Ā });Ā
Ā }Ā
Ā Ā // Add footerĀ
Ā body += ‘āāāāāāāāāāāāāāāāāāāāāāāāāāā\n’;Ā
Ā body += ‘Alert generated: ‘ + new Date().toLocaleString() + ‘\n’;Ā
Ā body += ‘Check your portfolio tracker for full details.\n’;Ā
Ā Ā // Send the emailĀ
Ā try {Ā
Ā Ā Ā GmailApp.sendEmail(emailAddress, subject, body);Ā
Ā } catch (error) {Ā
Ā Ā Ā Logger.log(‘Error sending email: ‘ + error);Ā
Ā }Ā
}Ā
function testEmailAlert() {Ā
Ā // Test function to verify email worksĀ
Ā const testAlerts = [Ā
Ā Ā Ā {Ā
Ā symbol: ‘TEST’,Ā
Ā company: ‘Test Company’,Ā
Ā type: ‘Daily Movement’,Ā
Ā message: ‘TEST: 5.5% day change (This is a test)’,Ā
Ā details: ‘Current Price: $100.00 | Shares: 10 | Value: $1,000.00’Ā
Ā Ā Ā }Ā
Ā ];Ā
Ā Ā sendAlertEmail(testAlerts);Ā
Ā Logger.log(‘Test email sent’);Ā
}
Important: Next to const emailAddress = Replace [emailĀ protected] with your Gmail address.Ā
Authorize and Test the Script:Ā
- Save the script (press Ctrl+S or Cmd+S)Ā
- Select function: Choose testEmailAlert from dropdownĀ
- Click Run buttonĀ
- Grant permissions when prompted:Ā
- Click āReview permissionsāĀ
- Choose your Google accountĀ
- Click āAdvancedā : āGo to [Project Name] (unsafe)āĀ
- Click āAllowāĀ
- Check your email for the test messageĀ
Set Up Automatic Trigger:Ā
- Click the Clock icon in the left sidebar (Triggers)Ā
- Click ā+ Add TriggerāĀ
- Configure trigger:Ā
- Function: checkStockAlertsĀ
- Event source: Time-drivenĀ
- Type: Hour timerĀ
- Interval: Every hour (or your preference)
- Click SaveĀ
Best Practices for MaintenanceĀ
Here are some pointers you can follow to keep your investment tracker running smoothly:Ā
- Weekly Review: Open tracker and review performance, check email alerts from the past week & note any significant changesĀ
- Quarterly Analysis: Review sector allocation, assess individual holdings performance and consider rebalancing opportunitiesĀ
- Annual Audit: Generate annual performance report, export transactions for tax preparation & review and update investment strategyĀ
ConclusionĀ
With multiple investment accounts and dozens of stocks it can be difficult to keep track of your complete portfolio performance. However, now with the help of this Excel tracker with live data feeds, you can be on top of your investments and make informed decisions. With the help of this knowledge, you can now:Ā
- Build a comprehensive investment tracker in Excel Desktop with live stock pricesĀ
- Automate calculations for gains, losses, and returns across all positionsĀ
- Set up automated email alerts using Google Apps Script for significant price movementsĀ
- Track transactions and maintain accurate cost basis for tax purposesĀ
- Monitor portfolio performance across multiple sectors and asset classesĀ
With this system, youāll never lose track of your investment performance again and can make informed decisions based on real-time data and comprehensive analytics.
Read more:
Frequently Asked Questions
Q1. Should I use Excel Desktop or Excel Online for this tracker?
A. Excel Desktop is strongly recommended for the best experience. It has full Stock data type support for automatic live price feeds. Excel Online has limitations with live data. If you donāt have Excel Desktop, Google Sheets is a better free alternative than Excel Online, as GOOGLEFINANCE works reliably worldwide.Ā
Q2. How many stocks can this tracker handle?Ā
A. The tracker can easily handle 100+ stocks. Excel Desktop performs well with 200+ holdings. Google Sheets handles 1,000+ stocks smoothly. For optimal performance, keep under 200 holdings in Excel, or consider splitting into multiple sheets by account type.Ā
Q3. Iām seeing unrealistic percentages like 6510% in Gain/Loss %. How do I fix this?Ā
A. This error occurs when:Ā
1. The Total Cost formula (Column F) isnāt working: Ensure F2 = =D2*E2Ā
2. Wrong formula in Gain/Loss %: Should be =IF(F2=0,0,I2/F2) not I2/E2Ā
3. Double percentage multiplication: If using Percentage format, remove *100 from formulaĀ
Sohan Sethi is a Data Analytics Manager and Content creator passionate about using data, technology, and storytelling to create meaningful impact. With experience in healthcare, analytics, and workflow automation, he has built tools and platforms that streamline processes for thousands of users, combining technical expertise in SQL, Python, Excel, SharePoint, and Power Platform with a people-first approach to problem-solving.
Beyond his professional career, Sohan is dedicated to empowering job seekers and international students through free resources, mentorship, and thought leadership. He has given a TEDx talk and featured in multiple media platforms including Business Insider, CNBC, Fox News, etc. He regularly shares strategies on job search, career growth, and adapting to challenges. His work has inspired professionals worldwide to unlock opportunities and reach their goals.
Login to continue reading and enjoy expert-curated content.
Keep Reading for Free
