Streamlined [JavaScript?] solution for displaying and modifying several location-specific purchasing and selling rates

No, this is not related to interviews or cryptocurrencies! :)
It is for a non-profit personal web application designed to enhance a game.

This question involves both finance and coding.
I am developing this web app using Vue.js, so I prefer a JavaScript solution. However, an abstract approach or pseudo-code would also be helpful as I can translate it into JavaScript.

Here is the scenario:
Multiple locations (referred to as "stores") buy and sell various items at different prices.
Prices fluctuate randomly, possibly due to supply and demand, but that is not crucial to the problem.
There will be around 100-1000 locations and 10-100 different items.
The majority of locations (estimated 80-90%) will only deal with a few items.
Some locations (about 1-10%) will handle many items, if not all.
Around 50% of locations may only buy or sell, not both.

The objective is to display an extensive list of all locations that have a buying price for an item compared to locations that have a selling price for that same item (similar to permutations/combinations, but with expected gaps).
The final output should be a simple list/array of objects (keyed/value pairs).

A worst-case scenario could involve a paginated list of 99 million objects (1000 stores * (1000 - 1) stores * 100 items); however, there are anticipated gaps in the data, so ideally there would be significantly fewer than 1 million objects (ideally under 100,000; they do not all need to be live in memory and could be loaded from storage).

For example (sorted by Item and Buy Location for clarity):


Item     Buy Location   Buy Price Ratio Sell Price   Sell Location
Item A   Location A     4         0.5   2            Location B
Item A   Location A     4         2.0   8            Location C
Item A   Location B     6         0.66  4            Location A
Item A   Location B     6         1.33  8            Location C
Item A   Location C     10        0.4   4            Location A
Item A   Location C     10        0.2   2            Location B
Item B   Location A     3         0.33  1            Location B
Item B   Location A     3         1.33  4            Location C
Item B   Location B     3         0.66  2            Location A
Item B   Location B     3         1.33  4            Location C
Item B   Location C     5         0.4   2            Location A
Item B   Location C     5         0.2   1            Location B

Each column in the list is sortable, with the default being "Ratio" to display the optimal combinations of buying and selling locations. When prices are updated, Vue.js automatically updates and resorts the list.

Currently, I have inefficient ideas on how to tackle this issue, which involve regenerating the entire list whenever a single price changes.
Since the final output must support arbitrary sorting, direct indexing or access to items is not plausible.
If the price for a specific location's item changes, there isn't a method to pinpoint and update that specific row or cell.

I suspect that my approach is lacking efficiency, and I believe this task has been addressed before in scalable ways.
For instance, creating a straightforward buy/sell price chart across multiple exchanges.
While considering exploring open-source cryptocurrency bot code, this seems more like a finance-related challenge that I wish to comprehend rather than a programming one that I intend to replicate.

How would you go about implementing this?
What kind of dataset(s) would you utilize?

Thank you!

Answer №1

In my perspective

  • The 1 million lines of data may overwhelm users if presented all at once.
  • While a 1 million array size may not be too large for Javascript (~10MB, as demonstrated in your application here), rendering it all to the DOM element could pose significant challenges.

How would you tackle this issue?

In such a scenario, I would opt for pagination or aggregation (e.g., displaying the first 10 highest ratios for each item).

For instance:

computed: {
  displayItems () {
    // This will get updated when rawItems, currentPage, or pageSize change
    return doFilterOrSort(rawItems).slice(currentPage * pageSize, pageSize)
  }
}

This approach addresses the problem of an excessive number of DOM elements (assuming that updating a 1 million array size is fast enough not to become a bottleneck).

If your data changes frequently, like 10 times in a second, consider throttling or debouncing to reduce rendering frequency.

Example of throttling:

watch: {
  rawItems () {
    if (!ticking) {
      requestAnimationFrame(() => {
        displayItems = doFilterOrSort(rawItems).slice(currentPage * pageSize, pageSize)
        ticking = false
      })
      ticking = true
    }
  }
}

If you wish to implement infinite scrolling, recycle out-of-screen DOM elements. Refer to examples in react-virtualized.

What type of dataset(s) should you use?

Without details on the data format retrieved (initially and with updates), it's challenging to provide a precise answer.

Assuming a fixed number of stores and items with updates per item, I suggest using three arrays:

1. The first array stores buy/sell values for each item in every store. Updates here are easily done in O(1) time complexity.

2. The second array holds ratio objects for combinations of store-item pairs. Updating this incurs O(n⋅n) operations, e.g., updating 'ab' and 'ba' for a set of 3 stores and 1 item.

3. The third array extends the previous one by incorporating sorting or grouping, costing O((n⋅n⋅m) log (n⋅n⋋m)) (a potential bottleneck requiring careful attention based on array structure).

In case these solutions are insufficient, consider aggregating data on the server before transmitting it via web sockets instead of sending everything to the client side.

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

Exploring the world of Vue and Pinia: managing and accessing data like

While delving into Vue and Pinia, I encountered a data management issue on the user side. On my main page, I showcase categories and auction items. However, upon navigating to a specific category in the catalog, the data for auction items remains in the st ...

The synergy between Tailwind's divide-y utility and Vue3's v-for directive

How can I use Tailwind's divide to create dividers between elements generated with a v-for loop in Vue3? <div v-for="(i) in [1, 2, 3]" class="divide-y divide-red-400"> <div>{{ i }}</div> </div> Currently, ...

Can the caller function's arguments be altered using Function.prototype.apply()?

function modifyValues(a,b){ console.log(arguments); //["oldValue","oldValue"] var newArguments = updateValues.apply(this,arguments); for (var i=0;i<arguments.length;i++){ arguments[i] = newArguments[i]; } console.log(arguments); // ...

Configure Laravel application to use a specific language locale in the app.php file

Whenever the user selects a different language, I attempt to set it as the local language. However, whenever the page is refreshed, it reverts back to my default language... 'locale' => 'en', 'locales' => ['fr&apos ...

Trouble arises when attempting to establish an isolated scope within Angular alongside UI Bootstrap

My table of data is set up with AngularJS, and one of the columns is calculated using a function in the controller. On my webpage, I have a button that opens a modal. When I use UI Bootstrap to open the modal, it creates a new isolated scope (child of the ...

Tips on locating information within a pre-existing GET array with parameters provided

Apologies for the unclear title. I am currently utilizing a category chooser that pulls categories from an API. The process involves fetching a list of categories, filtering out their names, and presenting them in the category chooser. Upon clicking submit ...

The perfect way to override jest mocks that are specified in the "__mocks__" directory

Within the module fetchStuff, I have a mock function named registerAccount that is responsible for fetching data from an API. To test this mock function, I've created a mock file called __mocks__/fetchStuff.ts. Everything seems to be functioning corre ...

What is the optimal method for transmitting both an image and JSON data to my express server?

Hey there! So I've set up a MongoDB database and I'm using Mongoose to work with it. Here's the model I have for my product: const productSchema = new Schema({ name: { type: String, required: true}, description: { type: String, required ...

What is the process for obtaining the hash of every hyperlink?

I'm currently working on implementing an active link state based on scroll position for each section. My goal is to extract the hash value from the link. The issue I'm facing is that when I run the line 'console.log($(this).eq(i).hash);&ap ...

Upon receiving the ajax request, the entire code page is called back

I'm having trouble saving data using a button in Laravel. When I use console.log, the entire code appears in the console and I don't understand why this is happening. Here is my input field and button: <form action="{{ url('sendcom& ...

Compatible with pure vanilla JavaScript, but not jQuery

I am currently facing an issue with attaching VKI (Virtual Keyboard Interface) to an element that is dynamically added to the DOM using JavaScript. The scenario involves a table with initially only one row, along with "Add Row" and "Delete Row" functionali ...

Updating a boolean prop does not cause the child component to be refreshed

I am working with the following components: Parent: <template> <Child path="instance.json" v-bind:authenticated="authenticated" v-bind:authenticator="authenticator" /> </tem ...

What is the proper way to display the date and time 2021-11-14T18:30:00.000+00:00?

Here is my ts file code: mydate: Date = new Date('2021-11-14T18:30:00.000+00:00'); However, I want the date to be in this format:- 07-July-2022 If anyone can assist with achieving this format, it would be greatly appreciated. Thank you! ...

Maximizing the power of datatables with ajax integration

Exploring pagination with AJAX on datatables.net is something I want to try. I have two input fields where users can enter start and end dates, followed by the table structure below: <table class="table table-hover" id="example"> < ...

Steps for correctly retrieving a specific product from my API using Vue3

I've integrated Pinia to manage my product catalog fetched from my Django API. The products are displayed in a table, and I want users to be able to click on a product and view its detailed information. Should I make a new API call for the product de ...

The strict-origin-when-cross-origin policy is enforced when submitting a POST request through a form to a specific route

Currently, I am diving into the world of Node.js, express, and MongoDB by reading Greg Lims's book. However, I've hit a roadblock when trying to utilize a form to submit data to a route that should then output the body.title of the form in the co ...

Duplicate the identical data retrieval query, this time utilizing a JavaScript Ajax post method

To enhance the data request query, implement a JavaScript Ajax post method to avoid page refresh when the button is pressed. This will allow for requesting another page and displaying it in a designated section on the webpage. Here's the code snippet ...

React component stuck in endless loop due to Intersection Observer

My goal is to track the visibility of 3 elements and update state each time one of them becomes visible. Despite trying various methods like other libraries, useMemo, useCallback, refs, etc., I still face challenges with my latest code: Endless loop scenar ...

How to implement a cyclic item generation feature in React.js

My function is meant to draw multiple items in a cycle, but it is only drawing the first item when I attempt to draw 5. This is my function: export default function CinemaHole() { const items = []; for(let i = 0; i < 5; i++) { item ...

Accessing a Child Component Function in Material UI

Utilizing the Material UI framework, I am constructing an application with React. Included in this application is a Dialog feature that permits users to modify various information about an object (referencing the code below). The dialog consists of two but ...