NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name PeterLynchFormula
// @namespace http://tampermonkey.net/
// @version v1
// @description Checks to see if the stock if undervalued/overvalued/fairlyvalued using peter lynch formula on yahoo finances site.
// @author Johnson
// @match https://finance.yahoo.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=yahoo.com
// @grant none
// @license GPL-3.0-or-later; https://www.gnu.org/licenses/gpl-3.0.txt
// ==/UserScript==
(function() {
'use strict';
function getInfoBySpanText(text_to_find){
// Get all span elements
const spans = document.querySelectorAll('span');
// Loop through each span element
for (const span of spans) {
// Check if the span's text content includes the specified text
if (span.textContent.includes(text_to_find)) {
// If found, get the next element
const nextElement = span.nextElementSibling;
if (nextElement) {
// Return the text content of the next element
return nextElement.textContent.trim();
}
}
}
}
function getInfoByTdText(text_to_find){
// Get all td elements
const tds = document.querySelectorAll('td');
// Loop through each td element
for (const td of tds) {
// Check if the td's text content includes the specified text
if (td.textContent.includes(text_to_find)) {
// If found, get the next element
const nextElement = td.nextElementSibling;
if (nextElement) {
// Return the text content of the next element
return nextElement.textContent.trim();
}
}
}
}
function getTickerName(){
const h1Element = document.querySelector('h1.svelte-ufs8hf');
if (h1Element) {
const textContent = h1Element.textContent.trim();
const match = textContent.match(/\((.*?)\)/);
const textInParentheses = match ? match[1] : null;
if (textInParentheses) {
return textInParentheses;
} else {
console.error('h1 element not found');
}
}
}
function updateStockData(tickerData) {
// Retrieve existing data from localStorage
let existingData = localStorage.getItem('stock_data');
// Parse existing data or initialize an empty object if it doesn't exist
existingData = existingData ? JSON.parse(existingData) : {};
// Loop through the tickerData object
for (const ticker in tickerData) {
if (tickerData.hasOwnProperty(ticker)) {
const newData = tickerData[ticker];
// Check if the ticker already exists in the existing data
if (existingData.hasOwnProperty(ticker)) {
// If it exists, update the data
for (const key in newData) {
if (newData.hasOwnProperty(key) && newData[key] !== undefined) {
existingData[ticker][key] = newData[key];
}
}
} else {
// If it doesn't exist, add it to the existing data
existingData[ticker] = newData;
}
}
}
// Store updated data in localStorage
localStorage.setItem('stock_data', JSON.stringify(existingData));
}
function evaluateStock(ticker_name) {
// Retrieve data from localStorage
const stockData = localStorage.getItem('stock_data');
if (!stockData) {
//alert('Stock data not found in localStorage.');
return;
}
const parsedData = JSON.parse(stockData);
if (!parsedData.hasOwnProperty(ticker_name)) {
//alert(`Stock data for ${ticker_name} not found.`);
return;
}
const stockInfo = parsedData[ticker_name];
const forwardGrowth = parseFloat(stockInfo['ForwardGrowth']);
const dividendYield = parseFloat(stockInfo['DividendYield']);
const peRatio = parseFloat(stockInfo['PE_RATIO']);
if (isNaN(forwardGrowth) || isNaN(dividendYield) || isNaN(peRatio)) {
//alert('Some of the required data is missing. Cannot perform calculation.');
return;
}
// Calculate the value
const value = (forwardGrowth + dividendYield) / peRatio;
// Classify the stock based on the value
let classification;
if (value < 1) {
classification = 'Overvalued';
} else if (value >= 1 && value <= 1.5) {
classification = 'Fairly Valued';
} else if (value > 1.5 && value <= 2) {
classification = 'Undervalued';
} else {
classification = 'Very Undervalued';
}
alert(`Stock: ${ticker_name}\nClassification: ${classification}`);
}
function cleanData(data) {
if(data){
const match = data.match(/\((.*?)\)/);
const cleanedData = match ? match[1] : data;
return cleanedData.replace('%', '');
}else{
return data;
}
}
let ticker_name = getTickerName();
console.log(ticker_name);
let fdy = getInfoBySpanText('Forward Dividend & Yield');
let fgrwth = getInfoByTdText('Next 5 Years (per annum)');
let pe_ratio = getInfoBySpanText('PE Ratio (TTM)');
// Store data in localStorage as JSON
if(ticker_name){
const dataToStore = {
[ticker_name]:{
'ForwardGrowth': cleanData(fgrwth),
'DividendYield': cleanData(fdy),
'PE_RATIO': cleanData(pe_ratio),
}
};
updateStockData(dataToStore);
evaluateStock(ticker_name);
}
})();