Price History using Yahoo Finance
Pricing
from $0.03 / 1,000 results
Price History using Yahoo Finance
This Actor fetches historical stock price data from Yahoo Finance. It retrieves OHLCV (Open, High, Low, Close, Volume) data with adjusted closing prices and auto-calculated daily returns for financial analysis and backtesting.
Pricing
from $0.03 / 1,000 results
Rating
0.0
(0)
Developer

JC
Actor stats
0
Bookmarked
1
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Yahoo Finance Historical Stock Data Actor
Fetch historical OHLCV stock price data from Yahoo Finance with adjusted closing prices and automated daily returns calculation. Perfect for backtesting trading strategies, financial analysis, portfolio research, and quantitative analysis with support for multiple ticker symbols and flexible time ranges.
Quick Start
Once you've installed the dependencies, start the Actor:
$apify run
Once your Actor is ready, you can push it to the Apify Console:
apify login # first, you need to log in if you haven't already done soapify push
Project Structure
.actor/├── actor.json # Actor configuration and metadata├── input_schema.json # Input validation & Console form definition└── output_schema.json # Output data structure specificationsrc/└── main.js # Actor entry point - fetches Yahoo Finance dataanalysis/└── analysis.py # Python analysis script with Analyzer classDockerfile # Container image definitionpackage.json # Node.js dependencies and scripts
For more information, see the Actor definition documentation.
How it works
This Actor automates the process of fetching historical stock price data from the Yahoo Finance API and stores structured financial data in a dataset for analysis and backtesting.
- The Actor accepts ticker symbols (AAPL, MSFT, GOOGL, etc.) and a time range from the input
- It queries Yahoo Finance's API for complete OHLCV (Open, High, Low, Close, Volume) data
- Daily returns are automatically calculated for each trading day using percentage change formula
- Adjusted closing prices account for stock splits and dividends
- Data is validated and pushed to the dataset for output
- Built-in rate limiting prevents API throttling when processing multiple tickers
What's included
- Apify SDK - toolkit for building Actors
- OHLCV data extraction - Complete historical price and volume data from Yahoo Finance
- Input validation - configurable ticker symbols, time ranges (1d to max), and rate limiting
- Dataset - store structured financial data with daily returns
- Automated returns calculation - daily percentage change calculated for each trading day
- Error handling - robust error recovery and logging for reliability
- Rate limiting - configurable delays to respect API limits and prevent throttling
- Python analysis tools - included Analyzer class for support/resistance, smart money detection, and momentum signals
Resources
- Quick Start guide for building your first Actor
- Apify SDK documentation
- Crawlee documentation for advanced scraping
- Join our developer community on Discord
Use Cases
- Backtesting trading strategies - Test algorithmic trading strategies with historical OHLCV data
- Financial analysis - Analyze price trends, volatility, and volume patterns
- Portfolio research - Track historical performance of multiple stocks
- Quantitative analysis - Gather data for machine learning and statistical models
- Technical analysis - Support and resistance level identification, momentum analysis
- Investment research - Compare historical performance across different tickers
Getting started
For complete information see this article. In short, you will:
- Build the Actor
- Run the Actor
Features
- Historical OHLCV data (Open, High, Low, Close, Volume)
- Adjusted closing prices for accurate returns
- Auto-calculated daily returns (percentage change)
- Configurable rate limiting to avoid API blocks
- Support for multiple tickers in a single run
- Flexible time ranges (1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, 10y, ytd, max)
Input Configuration
{"tickers": ["AAPL", "MSFT", "GOOGL"],"range": "3mo","interval": "1d","maxRequestsPerCrawl": 100,"maxConcurrency": 10,"timeoutSecs": 7200,"memoryMbytes": 2048,"rateLimitDelay": 1000,"restartOnError": false,"proxyConfiguration": {"useApifyProxy": true}}
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
tickers | array | ["AAPL"] | Stock ticker symbols to fetch (max 10) |
range | string | "3mo" | Time range for historical data (1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, 10y, ytd, max) |
interval | string | "1d" | Time interval for data points (1min, 1h, 1d, 1mo, 1y) |
maxRequestsPerCrawl | integer | 100 | Maximum number of requests/tickers to process (1-2000) |
maxConcurrency | integer | 10 | Number of concurrent requests (1-50) |
timeoutSecs | integer | 7200 | Maximum runtime in seconds (60-10800) |
memoryMbytes | integer | 2048 | Memory allocation in MB (528-4096) |
restartOnError | boolean | false | Automatically restart if the actor fails |
rateLimitDelay | integer | 1000 | Milliseconds to wait between ticker requests (100-10000) |
proxyConfiguration | object | {"useApifyProxy": true} | Proxy settings for requests |
Output Format
Each row represents one trading day:
{"ticker": "AAPL","date": "2024-12-10","open": 195.50,"high": 197.30,"low": 194.80,"close": 196.45,"volume": 52431900,"adjClose": 196.45,"dailyReturn": 0.48,"fetchedAt": "2024-12-11T08:30:00.000Z"}
Financial Analysis with Python
The included Python analysis script provides advanced financial analysis capabilities.
Analyzer Class Features
The analysis/analysis.py file contains an Analyzer class with three main analysis methods:
- Professional Support & Resistance - Identifies swing highs/lows from the last 3 months of daily data
- Smart Money Detection - Spots institutional buying/selling through volume spike analysis
- Momentum Signals - Determines if stock is overbought/oversold in short term
Example Usage
import pandas as pdfrom analysis import Analyzer# Load data from dataset CSVanalyzer = Analyzer('./data/dataset.csv', ["NVDA", "AMD", "INTC"])# Get first tickerticker1 = analyzer.df['ticker'].iloc[0]# Find support and resistance levelssupport_resistance = analyzer.professional_support_resistance(ticker1)# Output: {'support': 169.55, 'resistance': 188.0, 'method': 'swing_points', ...}# Detect institutional trading patternssmart_money = analyzer.detect_smart_money(ticker1)# Output: {'accumulation_days': 1, 'distribution_days': 0, 'biggest_buy_day': '2025-11-25', ...}# Get momentum signalmomentum = analyzer.momentum_signal(ticker1)# Output: {'5_day_return': '-5.7%', '20_day_return': '-8.0%', 'signal': 'No extreme signal', ...}
Analysis Methods Details
Professional Support & Resistance
Finds actionable support (buy) and resistance (sell) levels using swing point analysis on the last 3 months of daily data.
def professional_support_resistance(self, ticker):"""Professional method finding actionable support (buy)/resistance (sell) in last 3 months of daily dataIdeal range/interval: 3 months of daily data (63 trading days)"""# Find recent swing highs (local maxima)three_months_ago = datetime.datetime.now() - pd.DateOffset(months=3)df = self.df.loc[(self.df['ticker'] == ticker) & (self.df['date'] >= three_months_ago)]swing_highs = []for i in range(1, len(df)-1):if df['high'].iloc[i] > df['high'].iloc[i-1] and df['high'].iloc[i] > df['high'].iloc[i+1]:swing_highs.append(df['high'].iloc[i])# Find recent swing lows (local minima)swing_lows = []for i in range(1, len(df)-1):if df['low'].iloc[i] < df['low'].iloc[i-1] and df['low'].iloc[i] < df['low'].iloc[i+1]:swing_lows.append(df['low'].iloc[i])# Use most recent swingsresistance = max(swing_highs[-3:]) if swing_highs else df['high'].max()support = min(swing_lows[-3:]) if swing_lows else df['low'].min()return {'support': support,'resistance': resistance,'method': 'swing_points','most_recent_price': df.sort_values(['date'],ascending=False).iloc[0]['close']}
Smart Money Detection
Identifies volume spikes (>150% of 20-day average) with meaningful price moves.
def detect_smart_money(self, ticker):"""Spot institutional buying/selling, i.e. volume spikes with meaningful price movesIdeal range/interval: 1 month of daily data (21 trading days)"""# Calculate 20-day average volumetwenty_days_ago = datetime.datetime.now() - pd.DateOffset(days=20)df = self.df.loc[(self.df['ticker'] == ticker) & (self.df['date'] >= twenty_days_ago)]avg_volume = df['volume'].mean()high_vol_days = df[df['volume'] > avg_volume * 1.5]# Analyze price action on those daysinsights = {'accumulation_days': high_vol_days[high_vol_days['close'] > high_vol_days['open']].shape[0],'distribution_days': high_vol_days[high_vol_days['close'] < high_vol_days['open']].shape[0],'biggest_buy_day': high_vol_days.loc[high_vol_days['volume'].idxmax(), 'date'].strftime('%Y-%m-%d') if not high_vol_days.empty else None,'volume_trend': 'Increasing' if df['volume'].iloc[0] > avg_volume else 'Decreasing'}return insights
Momentum Signal
Calculates 5-day vs 20-day momentum for mean reversion analysis.
def momentum_signal(self, ticker):"""5-day momentum vs 20-day average for mean reversion to determine whether stock is overbought or oversold short-term"""df = self.df.loc[self.df['ticker'] == ticker]current_price = df.sort_values(['date'],ascending=False)['close'].iloc[0]price_5d_ago = df.sort_values(['date'],ascending=False)['close'].iloc[4]price_20d_ago = df.sort_values(['date'],ascending=False)['close'].iloc[19]# Calculate returnsreturn_5d = ((current_price - price_5d_ago) / price_5d_ago) * 100return_20d = ((current_price - price_20d_ago) / price_20d_ago) * 100# Simple mean reversion signalif return_5d > 8:signal = "Consider taking profits"elif return_5d < -8:signal = "Potential bounce opportunity"elif return_20d > return_5d > 0:signal = "Momentum weakening"else:signal = "No extreme signal"return {'5_day_return': f"{return_5d:.1f}%",'20_day_return': f"{return_20d:.1f}%",'signal': signal,'extreme_move': abs(return_5d) > 8}
Rate Limiting
The Actor includes built-in rate limiting to respect API limits and avoid throttling. The code implements a configurable delay between ticker requests (default: 1000ms):
const { tickers = ['AAPL'], range = "1y", rateLimitDelay = 1000 } = input || {};
Recommended settings:
- 1000ms (default): Safe for most use cases
- 500ms: Faster requests, but may trigger rate limits with many tickers
- 2000ms+: Extra conservative for large batches (50+ tickers)
Supported Time Ranges and Intervals
Time Ranges: 1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, 10y, ytd, max
Intervals: 1min, 1h, 1d, 1mo, 1y
Choose based on your analysis needs - daily (1d) data is most common for backtesting and technical analysis.
Understanding the Data
- OHLCV: Open, High, Low, Close, and Volume prices for each time period
- Adjusted Close (
adjClose): The closing price adjusted for stock splits and dividend distributions - Daily Return (
dailyReturn): Percentage change from previous close, calculated as:((close - previousClose) / previousClose) * 100 - Volume: Number of shares traded during the period
Tips
- Use 3+ months of daily data for reliable support/resistance analysis
- Volume spikes above 150% of 20-day average often indicate institutional activity
- Daily returns help identify momentum and mean reversion opportunities
- The
adjClosefield accounts for stock splits and dividends