Locate the closest array index to ensure precise calculations

While working on a Javascript project, I encountered an issue where I needed to calculate the "Price/Earnings Ratio" from a finance API. However, the API did not have a direct method to retrieve the required value.

The formula for computing the Price/Earnings Ratio for a specific year is as follows:

Last Stock Price of Mentioned Date / Date Earnings Per Share

The problem arose when I had the following data:

let as-of-date = "2019-12-31";
    let as-of-date-eps = 2.00;
    let ratio-as-of-date = as-of-date-eps/?
    

Unfortunately, the array containing the nearest stock prices for the mentioned date did not include the specific date "2019-12-31". To accurately compute the Price/Earnings Ratio, I needed to find the index of the nearest stock price entry before that date. In this case, it was the second index or stock-price-history[1].last, resulting in an expected Price/Earnings Ratio of 4.095.

My question now is how can I write the code to ensure that I obtain the correct result?

Answer №1

Simplifying things:

  • Find the difference between each item's date and the chosen date
  • Store these indexes and differences in an array
  • Sort this array by the differences
  • Select the first index from the sorted array as the minIndex
  • Use this minIndex to retrieve the relevant item from your stockPriceHistory array

Please note: the minimum offset can be calculated as "2020-01-02" - "2019-12-31" = 2 days, whereas "2020-12-27" - "2019-12-31" = -4 days. Is the logic to exclude any dates that are ahead of the chosen date?

const chosenDate = new Date("2019-12-31");
const stockPriceHistory = [
        {
            "date": "2019-12-26",
            "open": 8.3,
            "high": 8.48,
            "low": 8.2,
            "last": 8.21,
            "volume": 162800
        },
        {
            "date": "2019-12-27",
            "open": 8.48,
            "high": 8.48,
            "low": 8,
            "last": 8.19,
            "volume": 113000
        },
        {
            "date": "2020-01-02",
            "open": 8.45,
            "high": 8.48,
            "low": 8.2,
            "last": 8.4,
            "volume": 100000
        },
];

const dateOffsetsByIndex = stockPriceHistory.map((item, index) => {
  const currDate = new Date(item.date);
  const offset = (currDate - chosenDate) / (1000 * 60 * 60 * 24); //days
  return [index, offset];
})
  .sort((a,b) => {
    if (a[1] > 0 && b[1] < 0){
      return 1;
    }
    if (a[1] < 0 && b[1] > 0){
      return -1;
    }
    return Math.abs(a[1]) - Math.abs(b[1])
  });

const minIndex = dateOffsetsByIndex[0][0];

console.log(stockPriceHistory[minIndex]);

A cleaner version using reduce could be:

const chosenDate = new Date("2019-12-31");
const stockPriceHistory = [
        {
            "date": "2019-12-26",
            "open": 8.3,
            "high": 8.48,
            "low": 8.2,
            "last": 8.21,
            "volume": 162800
        },
        {
            "date": "2019-12-27",
            "open": 8.48,
            "high": 8.48,
            "low": 8,
            "last": 8.19,
            "volume": 113000
        },
        {
            "date": "2020-01-02",
            "open": 8.45,
            "high": 8.48,
            "low": 8.2,
            "last": 8.4,
            "volume": 100000
        },
];

const minOffset = stockPriceHistory.reduce((agg, item) => {
  const currDate = new Date(item.date);
  const offset = (currDate - chosenDate) / (1000 * 60 * 60 * 24); //days
  if (!agg.offset) return  {...item, offset};
  if (agg.offset > 0 && offset < agg.offset) return {...item, offset}; 
  if (agg.offset < 0 && (offset > agg.offset && offset <=0)) return {...item, offset};
  return agg;
}, {});

console.log(minOffset);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

beforeprinting() and afterprinting() function counterparts for non-IE browsers

Is there a way to send information back to my database when a user prints a specific webpage, without relying on browser-specific functions like onbeforeprint() and onafterprint()? I'm open to using any combination of technologies (PHP, MySQL, JavaScr ...

Processing a list of Strings

import java.util.Random; import java.util.Scanner; public class ArrayHelpers{ public static void main(String[] args){ String arr[] = {"X1", "X3", "X5", "X7", "2 Series", "3 Series"}; String stockElements[] = {"BMW X1","BMW X3", "BMW X5", ...

The type '{ children: Element[]; }' does not include the properties 'location' and 'navigator' that are present in the 'RouterProps' type

Struggling to implement React Router V6 with TypeScript, encountering a type error when including Routes within the `<Router />` component. The error message indicates that the children property passed to the Router is of an incorrect type, despite u ...

What is the best method for combining this function?

Currently, I am working on a code snippet that generates a sitemap.xml file when the /sitemap.xml endpoint is accessed. database = firebase.database(); var ref = database.ref('urls'); ref.on('value', gotData, errData); fu ...

Using AJAX to send both data input values and file attachments simultaneously to a PHP server

I am currently having an issue with sending form values to my PHP page using AJAX. My form includes text inputs and a file input for image uploads. Below are the AJAX codes I have been working on: function sendval() { var form = $('#user_update_for ...

Extracting data from a JSON object using Angular

Recently, I've been delving into the world of AngularJS and encountered a hurdle with LocalStorage. After spending numerous hours trying to figure out how to save data locally, I believe I have finally got it working as intended. Now, my next challeng ...

Sending data from an Angular form to a Node.js server using Sendgrid or Nodemailer

I recently implemented a solution from this example to send data from my Angular app to Node.js and then post a web form to Sendgrid. After making some adjustments, it is now working smoothly, and I am grateful for the quick start guide provided. The funct ...

"Implementing bubble sort on an array of strings using strcmp function in C is not yielding the

I've been attempting to organize a string array in C (char**), where the string array represents all the file names within a directory. Below is the code snippet that should sort the array alphabetically, however, it's not functioning as expected ...

Creating a dynamic search feature that displays results from an SQL database with a dropdown box

Is there a way to create a search bar similar to those seen on popular websites like YouTube, where the search results overlay the rest of the page without displacing any content? I've searched extensively on Google and YouTube for tutorials on databa ...

Adjust the position of a textarea on an image using a slider

Currently, I am exploring how to creatively position a textarea on an image. The idea is to overlay the text on the image within the textarea and then use a slider to adjust the vertical position of the text as a percentage of the image height. For instanc ...

Tips for representing entire months as object keys using numerical values

Currently, I find myself a bit puzzled as to why my code is not functioning as expected, and I am hopeful that you all could assist me in solving this issue. The data structure I am working with consists of years and corresponding months. chosenMonths = { ...

The dropdown feature fails to function properly when contained within a Bootstrap Popover

Utilizing jQuery v1.12.4, Bootstrap v3.3.7 and Bootstrap-Select v1.10.0. In a popover, I have 2 components. When the popover is opened, I am able to interact with the dropdowns but the selection does not change when clicking an option. You can view the e ...

I'm trying to figure out how to retrieve data from a JQuery autocomplete response that contains an array. Specifically, I want

https://i.stack.imgur.com/YpuJl.pngThis form field is for entering text input. <span> <img src="images/author2.jpg" width="50" /> //The profile picture displayed here is static but in the database I have a dynamic image. <input class="sea ...

Convert XML to JSON using an Express.js proxy pipeline

In order to access an external API that does not support CORS for my front-end (angular) application, I have implemented a simple proxy using Node.JS / Express.JS to handle the requests. This setup allows me to securely store my api credentials at the prox ...

Should tokens be sent via POST request or stored in a cookie?

I have a single-page Node.js Facebook Canvas App. Whenever a user interacts with the app, it triggers an AJAX POST request to my Node.js HTTPS server, which then returns the result. Now, I am looking for a way to send a user token that I generate from the ...

Transform a legitimate web address into an acceptable file path

I find myself in a situation that has me scratching my head. Imagine I want to convert any valid URL into a valid pathname for use on an image proxy with a URL structure like this: http://image-proxy/hash_of_url/encoded_url Is there an efficient way to a ...

What is the process for importing a file that contains special characters in its name?

Is there a way to correctly import a file with special characters in its name using ES6? I am able to: import { tomorrow} from 'react-syntax-highlighter/dist/esm/styles/hljs'; However, I encounter difficulties when attempting to: import { tom ...

Retrieving JSON data every few seconds using JavaScript

I am attempting to continuously read a local JSON file in order to generate a plot. This JSON file is updated every n seconds. To accommodate for the changing file, I am using a combination of $.getJSON() and setInterval() to read the file at regular inter ...

difficulty with displaying the following image using jquery

I have referenced this site http://jsfiddle.net/8FMsH/1/ //html $(".rightArrow").on('click',function(){ imageClicked.closest('.images .os').next().find('img').trigger('click'); }); However, the code is not working ...

Arranging an array in alphabetical order, with some special cases taken into consideration

Below is a breakdown of the array structure: [{ name: "Mobile Uploads" }, { name: "Profile Pictures" }, { name: "Reports" }, { name: "Instagram Photos" }, { name: "Facebook" }, { name: "My Account" }, { name: "Twi ...