Exploring the concept of value fluctuation using RXJS

My current dilemma involves an Observable that continuously generates a rapid sequence of positive-integer values.

I am seeking a way to transform this sequence into value-change percentages, particularly when those values exceed a certain threshold within a specified time interval (in milliseconds).

Snippet:

function getPressurePercents(input: Observable, minChange: number, iw: number) {
   // Create an observable that emits value-change percentages outside
   // the designated minimum change percentage during each interval window
}

const obs = getPressurePercents(input, 0.5, 3000).subscribe(val => {
    // Notify when input values have changed by at least 0.5% in the last 3 seconds
    // The emitted value represents the percent change, where Math.abs(value) >= 0.5
    // Positive values indicate percent increases, while negative values signify decreases
});

In the scenario outlined above, I aim to receive an observable that notifies me of any value-change percentages exceeding 0.5% within a 3-second timeframe.

The objective is to identify sudden spikes in value changes and react to all percentages outside the defined threshold, such as abrupt fluctuations in equity prices (price spikes).

CRUCIAL NOTE: The solution should account for both upward and downward changes, meaning a decrease in percentage within the window should emit a corresponding negative percent value.

RESOLUTION

After exploring various options, I devised my own solution that operates independently from the RXJS pipeline but can be seamlessly integrated into it. This approach is more straightforward and compact compared to previously suggested pure RXJS methods. Check out my answer below for details.

Answer №1

In my opinion, a potential solution could resemble the following approach:

  • The system promptly sends spike notifications as soon as a spike is detected, without any waiting interval, while taking into account values from the previous spikeIntervalMs. This enables an instant response to spikes.
  • If there is a spike wave, where the percent change gradually increases or decreases, it only sends spike notifications for values higher than the maximum in that particular spike wave. This continues until the spike wave subsides (no spikes detected during a certain period).
export function getSpikedPercentChangeAbs$(
  value$: Observable<number>,
  spikePercentage: number,
  spikeIntervalMs: number,
): Observable<number> {
  // Implementation logic here
}

function getPercentChangeAbs(
  previousValue: number,
  currentValue: number,
): number {
  // Definition of percent change calculation
}

function removeOldValues(
  oldTime: Date,
  valueAndTimeList: IValueAndTime[],
): void {
  // Logic to remove outdated values from the list
}

export interface IValueAndTime {
  time: Date;
  value: number;
}

Answer №2

While I initially searched for a RXJS solution that was fully functional, I couldn't find one that suited my needs. So here's my take on it - a solution that doesn't involve RXJS but can easily be integrated with it:

class SpikeDetector {

    private buffer: Array<{ ts: number, value: number }> = [];

    constructor(private change: number, private interval: number) {
    }

    next(value: number, spike: (change: number) => void): void {
        const ts = Date.now(); // timestamp
        const b = this.buffer; // abbreviation        
        while (b.length && ts - b[0].ts > this.interval) {
            b.shift();
        }
        b.push({ts, value});
        if (b.length >= 2) {
            const change = 100 * value / b[0].value - 100;
            if (Math.abs(change) >= this.change) {
                b.length = 0;
                spike(change);
            }
        }
    }
}

Using with RXJS:

const sd = new SpikeDetector(0.5, 3000);

input.subscribe(value => {
    sd.next(value, change => {
        // value spike by >=0.5% within 3 seconds
    });
});

Alternatively, you can utilize an RXJS helper as shown below:

function changeSpike(input: Observable<number>, change: number, i: number) {
    const sd = new SpikeDetector(change, i);
    return input.pipe(switchMap(value =>
        new Observable<number>(obs => {
            sd.next(value, change => obs.next(change));
        })
    ));
}

UPDATE:

Here's an enhanced and comprehensive solution that I've implemented in my financial project for detecting equity price spikes.

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

My troubleshooting journey: Why isn't Angular's HostListener preventDefault function

Struggling with creating a file drag and drop upload feature. I've set up the div container with dragenter, dragleave, and drop events using HostListener in an Angular Directive. The dragenter and dragleave events are functioning correctly, but I&apos ...

Dealing with delays in rendering certain values with Angular interpolation & ways to eliminate an element from an array of TypeScript objects

I am currently developing a web application using ASP.NET Core - Angular. The app allows users to select a customer as the starting point and then calculates the distance & duration to other customers using Google Maps Distance Matrix Service. Although I a ...

Enhance Axios to support receiving a URL in the form of a URL address

I am currently developing a TypeScript project where I am utilizing Axios to send GET requests to different URLs. In order to streamline the process, I am using the NodeJS URL interface to handle my URLs. However, it seems that Axios only accepts URLs in s ...

React typescript wormhole is struggling to display content due to createPortal and useContext combination

Explore the interactive demo here. Purpose: The main objective is to have all children elements of PortalEntrance rendered beneath PortalExit. Main concept: PortalProvider provides a ref PortalExit assigns the ref to one of its child elements PortalEntr ...

Exploring the differences between two Observables by utilizing a combination of .forEach and .some on an array

I am currently working with an Observable that is asynchronously bound to the view, and I need to compare its emitted values with another Observable to check for any overlap in their values. Previously, I was managing this by using two Arrays of Objects - ...

Assign a variable to set the property of a class

Could something similar to this scenario be achievable? const dynamicPropName = "x"; class A { static propName = 1 // equivalent to static x = 1 } A[dynamicPropName] // will result in 1 or would it need to be accessed as (typeof A)[dynamicPropN ...

Display a complete inventory of installed typings using the tsd command

How can I display a list of all installed tsd typings in the terminal? Perhaps using the following command: $ tsd list ...

What could be causing my AJAX request to send a null object to the server?

I'm currently working on an ajax request using XMLHttpRequest, but when the processRequest method is triggered, my MVC action gets hit and all object property values come up as null. Ajax Class import {Message} from "./Message"; export class AjaxHe ...

Receiving "this" as an undefined value within the TypeScript class

Currently developing a rest api using express.js, typescript, and typeorm. Initially thought the issue was with AppDataSource, but it seems to be functioning properly. Below is my controller class: import { RequestWithBody } from '@utils/types/reque ...

Error encountered while executing vitest within DevContainer

Recently, my company transitioned to DevContainer. I had a few PACT tests that were running successfully with vitest in my local environment. However, upon moving to DevContainer, I encountered the following error when attempting to run the same command: ...

Angular: Incorporating a custom validation function into the controller - Techniques for accessing the 'this' keyword

I'm currently working on implementing a custom validator for a form in Angular. I've encountered an issue where I am unable to access the controller's this within the validator function. This is the validator function that's causing tr ...

One of the modules ionic declaration consists of

Upon executing the ionic cordova build android --release --prod command, an error message is displayed in the console. Can anyone provide guidance on how to proceed? I am eagerly awaiting this to publish my app. `Type LoginPage in c:/Users/Mike/Desktop/G ...

I am interested in creating an input range slider using React and TypeScript

This code was used to create a slider functionality import { mainModule } from 'process'; import React, { useState } from 'react'; import styled from 'styled-components'; const DragScaleBar = () => { const [value, setV ...

Utilizing Node.JS Tools for Visual Studio to share classes across numerous TypeScript files

Currently, I am working on a Node.JS project that is written in TypeScript and utilizing Node.JS Tools for Visual Studio (NTVS). Within my project, I have several classes and enums distributed across 3 or 4 files. My goal now is to access and use these cla ...

the data chart is malfunctioning

Is it possible to use a chart with Angular that dynamically retrieves data from an API? I am able to get the data from the API in ngOnInit, but encounter difficulties assigning it to the chart. Below is the component TS code : import { Component, OnInit, ...

Exploring the World of TypeScript Decorators

I'm having trouble getting my custom @enumerable decorator to work properly. I followed the example in the documentation, but it's not functioning as expected. Am I overlooking something? Decorator export function enumerable(value: boolean) { ...

The continuous invocation of the ngStyle background-image in Angular 4 is causing a decrease in the loading speed of the page

I'm currently working on an Angular CLI Project "@angular/cli": "^1.1.1", "@angular/compiler-cli": "^4.0.0", In order to dynamically load images from the assets folder within an ng-for loop, I am using the following line of code: [ngStyle]="{&a ...

Is there a way to automatically populate the result input field with the dynamic calculation results from a dynamic calculator in Angular6?

My current challenge involves creating dynamic calculators with customizable fields. For example, I can generate a "Percentage Calculator" with specific input fields or a "Compound Interest" Calculator with different input requirements and formulas. Succes ...

Tips on how to access the previous and current state within a selector in ngrx selectors

I am interested in whether it is possible to access both the previous and current state within ngrx selectors. I have not been able to find relevant information on this topic. Could it be because I am using createSelector? Is there a factory method that ca ...

Add a unique class to an element within a main component

Within our application root, there exists a sidebar consisting of a list. We utilize uiSrefActive to apply an active class to the selected list item upon clicking it. However, once you navigate away from that component, the original list item loses its a ...