PSYahooFinance-AI.psm1
|
<#
.SYNOPSIS YFinanceTools PowerShell Module - A port of Python's YFinanceTools .DESCRIPTION This module provides functions for getting financial data from Yahoo Finance. It is a PowerShell port of the Python agno YFinanceTools toolkit. .NOTES Author: Ported from Python agno YFinanceTools Date: 2025-11-27 Version: 1.0.0 #> #region Private Helper Functions function Get-ValueOrDefault { <# .SYNOPSIS Returns the value if not null, otherwise returns the default value. PowerShell 5.1 compatible alternative to ?? operator. #> param( [Parameter(Position = 0)] $Value, [Parameter(Position = 1)] $Default = 'N/A' ) if ($null -ne $Value) { return $Value } return $Default } function Invoke-YahooFinanceV8Request { <# .SYNOPSIS Makes HTTP requests to Yahoo Finance V8 API for chart/historical data #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Symbol, [Parameter()] [string]$Range = '1mo', [Parameter()] [string]$Interval = '1d' ) try { $url = "https://query1.finance.yahoo.com/v8/finance/chart/$Symbol`?range=$Range&interval=$Interval" $headers = @{ 'User-Agent' = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' } $response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get return $response } catch { throw "Error fetching chart data from Yahoo Finance: $_" } } function Get-YahooFinanceQuote { <# .SYNOPSIS Gets basic quote data for a symbol using the v8 chart API #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Symbol ) try { $response = Invoke-YahooFinanceV8Request -Symbol $Symbol -Range '1d' -Interval '1d' $result = $response.chart.result[0] $meta = $result.meta # Build a quote object from chart metadata return @{ regularMarketPrice = $meta.regularMarketPrice currentPrice = $meta.regularMarketPrice previousClose = $meta.chartPreviousClose currency = $meta.currency symbol = $meta.symbol exchangeName = $meta.exchangeName fullExchangeName = $meta.fullExchangeName longName = $meta.longName shortName = $meta.shortName fiftyTwoWeekHigh = $meta.fiftyTwoWeekHigh fiftyTwoWeekLow = $meta.fiftyTwoWeekLow regularMarketDayHigh = $meta.regularMarketDayHigh regularMarketDayLow = $meta.regularMarketDayLow regularMarketVolume = $meta.regularMarketVolume instrumentType = $meta.instrumentType } } catch { throw "Error fetching quote for $Symbol`: $_" } } function Get-YahooFinanceSearch { <# .SYNOPSIS Searches Yahoo Finance for a symbol and returns news #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Query, [Parameter()] [int]$NewsCount = 5 ) try { $url = "https://query1.finance.yahoo.com/v1/finance/search?q=$Query&newsCount=$NewsCount"esCount=1" $headers = @{ 'User-Agent' = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' } $response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get return $response } catch { throw "Error searching Yahoo Finance: $_" } } #endregion #region Public Functions function Get-CurrentStockPrice { <# .SYNOPSIS Gets the current stock price for a given symbol .DESCRIPTION Use this function to get the current stock price for a given symbol. Returns the regular market price or current price. .PARAMETER Symbol The stock symbol (e.g., 'AAPL', 'MSFT', 'NVDA') .EXAMPLE Get-CurrentStockPrice -Symbol 'AAPL' Returns the current stock price for Apple Inc. .EXAMPLE 'NVDA', 'TSLA' | Get-CurrentStockPrice Returns current stock prices for multiple symbols via pipeline #> [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string]$Symbol ) process { try { Write-Verbose "Fetching current price for $Symbol" $quote = Get-YahooFinanceQuote -Symbol $Symbol $currentPrice = $quote.regularMarketPrice if (-not $currentPrice) { $currentPrice = $quote.currentPrice } if ($currentPrice) { return "{0:N4}" -f $currentPrice } else { return "Could not fetch current price for $Symbol" } } catch { return "Error fetching current price for $Symbol`: $_" } } } function Get-CompanyInfo { <# .SYNOPSIS Gets company information and overview for a given stock symbol .DESCRIPTION Use this function to get company information and overview for a given stock symbol. Returns a JSON string containing company profile and overview from available data. .PARAMETER Symbol The stock symbol (e.g., 'AAPL', 'MSFT', 'NVDA') .PARAMETER AsObject If specified, returns the data as a PowerShell object instead of JSON .EXAMPLE Get-CompanyInfo -Symbol 'AAPL' Returns company information for Apple Inc. as JSON .EXAMPLE Get-CompanyInfo -Symbol 'MSFT' -AsObject Returns company information for Microsoft as a PowerShell object #> [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string]$Symbol, [Parameter()] [switch]$AsObject ) process { try { Write-Verbose "Fetching company info for $Symbol" # Get data from v8 chart API $quote = Get-YahooFinanceQuote -Symbol $Symbol if (-not $quote) { return "Could not fetch company info for $Symbol" } $currency = Get-ValueOrDefault $quote.currency 'USD' $companyInfo = [ordered]@{ Name = $quote.longName ShortName = $quote.shortName Symbol = $quote.symbol 'Current Stock Price' = "$($quote.regularMarketPrice) $currency" Currency = $currency Exchange = $quote.fullExchangeName 'Instrument Type' = $quote.instrumentType '52 Week Low' = $quote.fiftyTwoWeekLow '52 Week High' = $quote.fiftyTwoWeekHigh 'Day Low' = $quote.regularMarketDayLow 'Day High' = $quote.regularMarketDayHigh 'Previous Close' = $quote.previousClose Volume = $quote.regularMarketVolume } if ($AsObject) { return [PSCustomObject]$companyInfo } return $companyInfo | ConvertTo-Json -Depth 10 } catch { return "Error fetching company profile for $Symbol`: $_" } } } function Get-HistoricalStockPrices { <# .SYNOPSIS Gets historical stock prices for a given symbol .DESCRIPTION Use this function to get the historical stock price for a given symbol. Valid periods: 1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, 10y, ytd, max Valid intervals: 1d, 5d, 1wk, 1mo, 3mo .PARAMETER Symbol The stock symbol (e.g., 'AAPL', 'MSFT', 'NVDA') .PARAMETER Period The period for which to retrieve historical prices. Defaults to "1mo". Valid periods: 1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, 10y, ytd, max .PARAMETER Interval The interval between data points. Defaults to "1d". Valid intervals: 1d, 5d, 1wk, 1mo, 3mo .PARAMETER AsObject If specified, returns the data as PowerShell objects instead of JSON .EXAMPLE Get-HistoricalStockPrices -Symbol 'AAPL' Returns 1 month of daily historical prices for Apple Inc. .EXAMPLE Get-HistoricalStockPrices -Symbol 'NVDA' -Period '3mo' -Interval '1wk' Returns 3 months of weekly historical prices for NVIDIA #> [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string]$Symbol, [Parameter()] [ValidateSet('1d', '5d', '1mo', '3mo', '6mo', '1y', '2y', '5y', '10y', 'ytd', 'max')] [string]$Period = '1mo', [Parameter()] [ValidateSet('1d', '5d', '1wk', '1mo', '3mo')] [string]$Interval = '1d', [Parameter()] [switch]$AsObject ) process { try { Write-Verbose "Fetching historical prices for $Symbol" $response = Invoke-YahooFinanceV8Request -Symbol $Symbol -Range $Period -Interval $Interval $chart = $response.chart.result[0] $timestamps = $chart.timestamp $quote = $chart.indicators.quote[0] $historicalData = @{} for ($i = 0; $i -lt $timestamps.Count; $i++) { $timestamp = $timestamps[$i] $date = [DateTimeOffset]::FromUnixTimeSeconds($timestamp).DateTime.ToString('yyyy-MM-dd HH:mm:ss') $historicalData[$date] = [ordered]@{ Open = $quote.open[$i] High = $quote.high[$i] Low = $quote.low[$i] Close = $quote.close[$i] Volume = $quote.volume[$i] } } if ($AsObject) { $result = @() foreach ($key in $historicalData.Keys | Sort-Object) { $result += [PSCustomObject]@{ Date = $key Open = $historicalData[$key].Open High = $historicalData[$key].High Low = $historicalData[$key].Low Close = $historicalData[$key].Close Volume = $historicalData[$key].Volume } } return $result } return $historicalData | ConvertTo-Json -Depth 10 } catch { return "Error fetching historical prices for $Symbol`: $_" } } } function Get-StockFundamentals { <# .SYNOPSIS Gets fundamental data for a given stock symbol .DESCRIPTION Use this function to get fundamental data for a given stock symbol. Returns key metrics available from the chart API including 52-week range. .PARAMETER Symbol The stock symbol (e.g., 'AAPL', 'MSFT', 'NVDA') .PARAMETER AsObject If specified, returns the data as a PowerShell object instead of JSON .EXAMPLE Get-StockFundamentals -Symbol 'AAPL' Returns fundamental data for Apple Inc. as JSON .EXAMPLE Get-StockFundamentals -Symbol 'MSFT' -AsObject Returns fundamental data for Microsoft as a PowerShell object #> [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string]$Symbol, [Parameter()] [switch]$AsObject ) process { try { Write-Verbose "Fetching fundamentals for $Symbol" $quote = Get-YahooFinanceQuote -Symbol $Symbol # Calculate simple metrics from available data $currentPrice = $quote.regularMarketPrice $fiftyTwoWeekHigh = $quote.fiftyTwoWeekHigh $fiftyTwoWeekLow = $quote.fiftyTwoWeekLow # Calculate percentage from 52-week high/low $pctFrom52WeekHigh = if ($fiftyTwoWeekHigh -and $currentPrice) { [math]::Round((($currentPrice - $fiftyTwoWeekHigh) / $fiftyTwoWeekHigh) * 100, 2) } else { 'N/A' } $pctFrom52WeekLow = if ($fiftyTwoWeekLow -and $currentPrice) { [math]::Round((($currentPrice - $fiftyTwoWeekLow) / $fiftyTwoWeekLow) * 100, 2) } else { 'N/A' } $fundamentals = [ordered]@{ symbol = $Symbol company_name = $quote.longName short_name = $quote.shortName current_price = $currentPrice currency = $quote.currency exchange = $quote.fullExchangeName instrument_type = $quote.instrumentType previous_close = $quote.previousClose day_high = $quote.regularMarketDayHigh day_low = $quote.regularMarketDayLow volume = $quote.regularMarketVolume '52_week_high' = $fiftyTwoWeekHigh '52_week_low' = $fiftyTwoWeekLow pct_from_52wk_high = $pctFrom52WeekHigh pct_from_52wk_low = $pctFrom52WeekLow } if ($AsObject) { return [PSCustomObject]$fundamentals } return $fundamentals | ConvertTo-Json -Depth 10 } catch { return "Error getting fundamentals for $Symbol`: $_" } } } function Get-IncomeStatements { <# .SYNOPSIS Gets historical price data that can be used for income analysis .DESCRIPTION Use this function to get historical price data for a given stock symbol. Due to API restrictions, this returns historical price data for the past year which can be used for performance analysis. .PARAMETER Symbol The stock symbol (e.g., 'AAPL', 'MSFT', 'NVDA') .PARAMETER AsObject If specified, returns the data as a PowerShell object instead of JSON .EXAMPLE Get-IncomeStatements -Symbol 'AAPL' Returns yearly historical data for Apple Inc. #> [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string]$Symbol, [Parameter()] [switch]$AsObject ) process { try { Write-Verbose "Fetching historical financial data for $Symbol" # Get 5 years of monthly data for trend analysis $response = Invoke-YahooFinanceV8Request -Symbol $Symbol -Range '5y' -Interval '1mo' $chart = $response.chart.result[0] $timestamps = $chart.timestamp $quote = $chart.indicators.quote[0] $meta = $chart.meta # Group by year $yearlyData = @{} for ($i = 0; $i -lt $timestamps.Count; $i++) { $timestamp = $timestamps[$i] $date = [DateTimeOffset]::FromUnixTimeSeconds($timestamp).DateTime $year = $date.Year.ToString() if (-not $yearlyData.ContainsKey($year)) { $yearlyData[$year] = @{ Opens = @() Closes = @() Highs = @() Lows = @() Volumes = @() } } if ($quote.open[$i]) { $yearlyData[$year].Opens += $quote.open[$i] } if ($quote.close[$i]) { $yearlyData[$year].Closes += $quote.close[$i] } if ($quote.high[$i]) { $yearlyData[$year].Highs += $quote.high[$i] } if ($quote.low[$i]) { $yearlyData[$year].Lows += $quote.low[$i] } if ($quote.volume[$i]) { $yearlyData[$year].Volumes += $quote.volume[$i] } } $financials = @{} foreach ($year in $yearlyData.Keys | Sort-Object -Descending) { $data = $yearlyData[$year] $avgClose = if ($data.Closes.Count -gt 0) { [math]::Round(($data.Closes | Measure-Object -Average).Average, 2) } else { 'N/A' } $yearHigh = if ($data.Highs.Count -gt 0) { ($data.Highs | Measure-Object -Maximum).Maximum } else { 'N/A' } $yearLow = if ($data.Lows.Count -gt 0) { ($data.Lows | Measure-Object -Minimum).Minimum } else { 'N/A' } $totalVolume = if ($data.Volumes.Count -gt 0) { ($data.Volumes | Measure-Object -Sum).Sum } else { 'N/A' } $yearOpen = if ($data.Opens.Count -gt 0) { $data.Opens[0] } else { 'N/A' } $yearClose = if ($data.Closes.Count -gt 0) { $data.Closes[-1] } else { 'N/A' } $yearReturn = if ($yearOpen -ne 'N/A' -and $yearClose -ne 'N/A' -and $yearOpen -gt 0) { [math]::Round((($yearClose - $yearOpen) / $yearOpen) * 100, 2) } else { 'N/A' } $financials[$year] = [ordered]@{ 'Year Open' = $yearOpen 'Year Close' = $yearClose 'Year High' = $yearHigh 'Year Low' = $yearLow 'Average Close' = $avgClose 'Total Volume' = $totalVolume 'Year Return %' = $yearReturn } } if ($AsObject) { $results = @() foreach ($key in $financials.Keys | Sort-Object -Descending) { $obj = [PSCustomObject]@{ Year = $key } foreach ($prop in $financials[$key].Keys) { $obj | Add-Member -NotePropertyName $prop -NotePropertyValue $financials[$key][$prop] } $results += $obj } return $results } return $financials | ConvertTo-Json -Depth 10 } catch { return "Error fetching financial data for $Symbol`: $_" } } } function Get-KeyFinancialRatios { <# .SYNOPSIS Gets key financial metrics for a given stock symbol .DESCRIPTION Use this function to get key financial metrics for a given stock symbol. Returns metrics calculated from available price data. .PARAMETER Symbol The stock symbol (e.g., 'AAPL', 'MSFT', 'NVDA') .PARAMETER AsObject If specified, returns the data as a PowerShell object instead of JSON .EXAMPLE Get-KeyFinancialRatios -Symbol 'AAPL' Returns key financial ratios for Apple Inc. #> [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string]$Symbol, [Parameter()] [switch]$AsObject ) process { try { Write-Verbose "Fetching key financial ratios for $Symbol" $quote = Get-YahooFinanceQuote -Symbol $Symbol # Get historical data for volatility calculation $histResponse = Invoke-YahooFinanceV8Request -Symbol $Symbol -Range '1y' -Interval '1d' $chart = $histResponse.chart.result[0] $histQuote = $chart.indicators.quote[0] # Calculate daily returns and volatility $closes = $histQuote.close | Where-Object { $_ -ne $null } $dailyReturns = @() for ($i = 1; $i -lt $closes.Count; $i++) { if ($closes[$i-1] -gt 0) { $dailyReturns += ($closes[$i] - $closes[$i-1]) / $closes[$i-1] } } $avgDailyReturn = if ($dailyReturns.Count -gt 0) { [math]::Round(($dailyReturns | Measure-Object -Average).Average * 100, 4) } else { 'N/A' } # Calculate standard deviation (volatility) $volatility = 'N/A' if ($dailyReturns.Count -gt 1) { $avg = ($dailyReturns | Measure-Object -Average).Average $sumSquares = 0 foreach ($r in $dailyReturns) { $sumSquares += [math]::Pow($r - $avg, 2) } $stdDev = [math]::Sqrt($sumSquares / ($dailyReturns.Count - 1)) $volatility = [math]::Round($stdDev * [math]::Sqrt(252) * 100, 2) # Annualized } # Calculate YTD return $currentYear = (Get-Date).Year $ytdResponse = Invoke-YahooFinanceV8Request -Symbol $Symbol -Range 'ytd' -Interval '1mo' $ytdChart = $ytdResponse.chart.result[0] $ytdQuote = $ytdChart.indicators.quote[0] $ytdOpens = $ytdQuote.open | Where-Object { $_ -ne $null } $ytdCloses = $ytdQuote.close | Where-Object { $_ -ne $null } $ytdReturn = 'N/A' if ($ytdOpens.Count -gt 0 -and $ytdCloses.Count -gt 0 -and $ytdOpens[0] -gt 0) { $ytdReturn = [math]::Round((($ytdCloses[-1] - $ytdOpens[0]) / $ytdOpens[0]) * 100, 2) } $ratios = [ordered]@{ # Price metrics symbol = $Symbol shortName = $quote.shortName longName = $quote.longName regularMarketPrice = $quote.regularMarketPrice previousClose = $quote.previousClose currency = $quote.currency # Day metrics dayHigh = $quote.regularMarketDayHigh dayLow = $quote.regularMarketDayLow dayVolume = $quote.regularMarketVolume # 52-week metrics fiftyTwoWeekHigh = $quote.fiftyTwoWeekHigh fiftyTwoWeekLow = $quote.fiftyTwoWeekLow # Calculated metrics avgDailyReturnPct = $avgDailyReturn annualizedVolatilityPct = $volatility ytdReturnPct = $ytdReturn # Price change from previous close dayChangePct = if ($quote.previousClose -gt 0) { [math]::Round((($quote.regularMarketPrice - $quote.previousClose) / $quote.previousClose) * 100, 2) } else { 'N/A' } } if ($AsObject) { return [PSCustomObject]$ratios } return $ratios | ConvertTo-Json -Depth 10 } catch { return "Error fetching key financial ratios for $Symbol`: $_" } } } function Get-AnalystRecommendations { <# .SYNOPSIS Gets price momentum analysis for a given stock symbol .DESCRIPTION Use this function to get price momentum analysis for a given stock symbol. Returns trend analysis based on moving averages and price momentum. .PARAMETER Symbol The stock symbol (e.g., 'AAPL', 'MSFT', 'NVDA') .PARAMETER AsObject If specified, returns the data as a PowerShell object instead of JSON .EXAMPLE Get-AnalystRecommendations -Symbol 'AAPL' Returns price analysis for Apple Inc. #> [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string]$Symbol, [Parameter()] [switch]$AsObject ) process { try { Write-Verbose "Fetching price analysis for $Symbol" # Get 6 months of daily data for analysis $response = Invoke-YahooFinanceV8Request -Symbol $Symbol -Range '6mo' -Interval '1d' $chart = $response.chart.result[0] $meta = $chart.meta $quote = $chart.indicators.quote[0] $closes = @($quote.close | Where-Object { $_ -ne $null }) $currentPrice = $meta.regularMarketPrice # Calculate moving averages $sma20 = 'N/A' $sma50 = 'N/A' $sma100 = 'N/A' if ($closes.Count -ge 20) { $sma20 = [math]::Round(($closes[-20..-1] | Measure-Object -Average).Average, 2) } if ($closes.Count -ge 50) { $sma50 = [math]::Round(($closes[-50..-1] | Measure-Object -Average).Average, 2) } if ($closes.Count -ge 100) { $sma100 = [math]::Round(($closes[-100..-1] | Measure-Object -Average).Average, 2) } # Generate simple recommendation based on moving averages $trend = 'neutral' $recommendation = 'hold' if ($sma20 -ne 'N/A' -and $sma50 -ne 'N/A') { if ($currentPrice -gt $sma20 -and $sma20 -gt $sma50) { $trend = 'bullish' $recommendation = 'buy' } elseif ($currentPrice -lt $sma20 -and $sma20 -lt $sma50) { $trend = 'bearish' $recommendation = 'sell' } } # Calculate momentum (rate of change) $momentum5d = 'N/A' $momentum20d = 'N/A' if ($closes.Count -ge 5 -and $closes[-5] -gt 0) { $momentum5d = [math]::Round((($closes[-1] - $closes[-5]) / $closes[-5]) * 100, 2) } if ($closes.Count -ge 20 -and $closes[-20] -gt 0) { $momentum20d = [math]::Round((($closes[-1] - $closes[-20]) / $closes[-20]) * 100, 2) } $recommendations = [ordered]@{ symbol = $Symbol companyName = $meta.longName currentPrice = $currentPrice currency = $meta.currency # Moving averages sma20 = $sma20 sma50 = $sma50 sma100 = $sma100 # Position relative to MAs aboveSMA20 = if ($sma20 -ne 'N/A') { $currentPrice -gt $sma20 } else { 'N/A' } aboveSMA50 = if ($sma50 -ne 'N/A') { $currentPrice -gt $sma50 } else { 'N/A' } aboveSMA100 = if ($sma100 -ne 'N/A') { $currentPrice -gt $sma100 } else { 'N/A' } # Momentum momentum5Day = $momentum5d momentum20Day = $momentum20d # Overall analysis trend = $trend technicalSignal = $recommendation # 52-week context fiftyTwoWeekHigh = $meta.fiftyTwoWeekHigh fiftyTwoWeekLow = $meta.fiftyTwoWeekLow pctFrom52WeekHigh = if ($meta.fiftyTwoWeekHigh -gt 0) { [math]::Round((($currentPrice - $meta.fiftyTwoWeekHigh) / $meta.fiftyTwoWeekHigh) * 100, 2) } else { 'N/A' } } if ($AsObject) { return [PSCustomObject]$recommendations } return $recommendations | ConvertTo-Json -Depth 10 } catch { return "Error fetching price analysis for $Symbol`: $_" } } } function Get-CompanyNews { <# .SYNOPSIS Gets company news and press releases for a given stock symbol .DESCRIPTION Use this function to get company news and press releases for a given stock symbol. .PARAMETER Symbol The stock symbol (e.g., 'AAPL', 'MSFT', 'NVDA') .PARAMETER NumStories The number of news stories to return. Defaults to 3. .PARAMETER AsObject If specified, returns the data as PowerShell objects instead of JSON .EXAMPLE Get-CompanyNews -Symbol 'AAPL' Returns the 3 most recent news stories for Apple Inc. .EXAMPLE Get-CompanyNews -Symbol 'NVDA' -NumStories 10 Returns the 10 most recent news stories for NVIDIA #> [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string]$Symbol, [Parameter()] [int]$NumStories = 3, [Parameter()] [switch]$AsObject ) process { try { Write-Verbose "Fetching company news for $Symbol" $searchResult = Get-YahooFinanceSearch -Query $Symbol -NewsCount $NumStories $news = @() foreach ($item in $searchResult.news | Select-Object -First $NumStories) { $publishTime = $null if ($item.providerPublishTime) { $publishTime = [DateTimeOffset]::FromUnixTimeSeconds($item.providerPublishTime).DateTime.ToString('yyyy-MM-dd HH:mm:ss') } $newsItem = [ordered]@{ title = $item.title publisher = $item.publisher link = $item.link providerPublishTime = $publishTime type = $item.type relatedTickers = $item.relatedTickers } $news += $newsItem } if ($AsObject) { return $news | ForEach-Object { [PSCustomObject]$_ } } return $news | ConvertTo-Json -Depth 10 } catch { return "Error fetching company news for $Symbol`: $_" } } } function Get-TechnicalIndicators { <# .SYNOPSIS Gets technical indicators for a given stock symbol .DESCRIPTION Use this function to get technical indicators for a given stock symbol. Returns historical OHLCV data that can be used for technical analysis. .PARAMETER Symbol The stock symbol (e.g., 'AAPL', 'MSFT', 'NVDA') .PARAMETER Period The time period for which to retrieve technical indicators. Valid periods: 1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, 10y, ytd, max. Defaults to 3mo. .PARAMETER AsObject If specified, returns the data as PowerShell objects instead of JSON .EXAMPLE Get-TechnicalIndicators -Symbol 'AAPL' Returns 3 months of technical indicator data for Apple Inc. .EXAMPLE Get-TechnicalIndicators -Symbol 'NVDA' -Period '1y' -AsObject Returns 1 year of data for NVIDIA as PowerShell objects #> [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [string]$Symbol, [Parameter()] [ValidateSet('1d', '5d', '1mo', '3mo', '6mo', '1y', '2y', '5y', '10y', 'ytd', 'max')] [string]$Period = '3mo', [Parameter()] [switch]$AsObject ) process { try { Write-Verbose "Fetching technical indicators for $Symbol" $response = Invoke-YahooFinanceV8Request -Symbol $Symbol -Range $Period -Interval '1d' $chart = $response.chart.result[0] $timestamps = $chart.timestamp $quote = $chart.indicators.quote[0] $adjCloseData = $chart.indicators.adjclose $adjClose = $null if ($adjCloseData -and $adjCloseData[0]) { $adjClose = $adjCloseData[0].adjclose } $indicators = @{} for ($i = 0; $i -lt $timestamps.Count; $i++) { $timestamp = $timestamps[$i] $date = [DateTimeOffset]::FromUnixTimeSeconds($timestamp).DateTime.ToString('yyyy-MM-dd HH:mm:ss') $adjCloseValue = $null if ($adjClose) { $adjCloseValue = $adjClose[$i] } $indicators[$date] = [ordered]@{ Open = $quote.open[$i] High = $quote.high[$i] Low = $quote.low[$i] Close = $quote.close[$i] Volume = $quote.volume[$i] 'Adj Close' = $adjCloseValue } } if ($AsObject) { $result = @() foreach ($key in $indicators.Keys | Sort-Object) { $result += [PSCustomObject]@{ Date = $key Open = $indicators[$key].Open High = $indicators[$key].High Low = $indicators[$key].Low Close = $indicators[$key].Close Volume = $indicators[$key].Volume 'Adj Close' = $indicators[$key]['Adj Close'] } } return $result } return $indicators | ConvertTo-Json -Depth 10 } catch { return "Error fetching technical indicators for $Symbol`: $_" } } } #endregion #region Aliases Set-Alias -Name Get-StockPrice -Value Get-CurrentStockPrice Set-Alias -Name Get-Quote -Value Get-CurrentStockPrice Set-Alias -Name Get-Fundamentals -Value Get-StockFundamentals Set-Alias -Name Get-Financials -Value Get-IncomeStatements Set-Alias -Name Get-News -Value Get-CompanyNews Set-Alias -Name Get-Recommendations -Value Get-AnalystRecommendations #endregion # # Export module members # Export-ModuleMember -Function @( # 'Get-CurrentStockPrice', # 'Get-CompanyInfo', # 'Get-HistoricalStockPrices', # 'Get-StockFundamentals', # 'Get-IncomeStatements', # 'Get-KeyFinancialRatios', # 'Get-AnalystRecommendations', # 'Get-CompanyNews', # 'Get-TechnicalIndicators' # ) -Alias @( # 'Get-StockPrice', # 'Get-Quote', # 'Get-Fundamentals', # 'Get-Financials', # 'Get-News', # 'Get-Recommendations' # ) |