TimeSeriesQueryLanguage 2.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package TimeSeriesQueryLanguage --version 2.0.1
NuGet\Install-Package TimeSeriesQueryLanguage -Version 2.0.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TimeSeriesQueryLanguage" Version="2.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add TimeSeriesQueryLanguage --version 2.0.1
#r "nuget: TimeSeriesQueryLanguage, 2.0.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install TimeSeriesQueryLanguage as a Cake Addin
#addin nuget:?package=TimeSeriesQueryLanguage&version=2.0.1

// Install TimeSeriesQueryLanguage as a Cake Tool
#tool nuget:?package=TimeSeriesQueryLanguage&version=2.0.1

TimeSeries Query Language

This is a library to aggregate values on user defined time series datasets.

The syntax is simple yet powerfull because it can compare series of data.

Example: "ag(Avg, Price, Fr.H1, To.Zero)"  means ''Get average price for the last hour''
Example: ">(ag(Avg, Price, Fr.H1, To.Zero),ag(Avg, Price, Fr.D1, To.Zero))" means ''Is price average for the last hour bigger than the price average for he last 24h''

For flexibility "Avg" is a function defined by your own implementation. On some applications, its common to have Avg, Count, StandardDeviation, Min, Max, etc

And "Price" is again, defined by your own dataset implementation. Tipically columns in tables where you want to aggregate values. On financial applications, its common to have Price, QuantityBought, QuantitySold, etc

The Eval method will always return a decimal.

Quick Start

Sample minimal pseudo code implementation:

public class YOUREvalImplementation : ITimeSeriesQueryLanguageContext
{
    readonly YOURDbContext Db;
    public YOUREvalImplementation(YOURDbContext db)
    {
        Db = db;
    }
    public async Task<decimal> Eval(string fn)
    {
        var tsqlp = new TimeSeriesQueryLanguageParser().Set(fn)?.Parse();
        return tsqlp == null ? 0.0m : await tsqlp.Eval(this);
    }

    public async Task<decimal> Eval<TAggFn, TAggCl>(
        OperationEnum operationEnum = OperationEnum.Agg,
        TAggFn? aggFn = default,
        TAggCl? aggCl = default,
        AggTimeIntervalEnum aggTsFr = AggTimeIntervalEnum.Zero,
        AggTimeIntervalEnum aggTsTo = AggTimeIntervalEnum.Zero,
        int i = 0
    ) where TAggFn : Enum where TAggCl : Enum
    {
        var to = DateTime.UtcNow - AggTimeIntervalEnumToTimeSpan.Map(aggTsTo);
        var fr = to - AggTimeIntervalEnumToTimeSpan.Map(aggTsFr);
        var tickers = Db.Tickers.Where(_ => _.ts >= fr && _.ts <= to);

        switch (aggFn)
        {
            case AggFn.Avg: return await tickers.AvgAsync(_ => _.Price);
        }
        return 0.0m;
    }
}

// Average column price for the last day (D1), starting now (Zero)
var c1 = await YOUREvalImplementation.Eval("ag(Avg,Price,Fr.D1,To.Zero)");										

Open the Samples project to see it in action with many more examples.

The Eval function: This function lives within your class implementation, that also holds a context to your data. You can query your data with aggregates, algebraic and logical operators.

Usage

The engine will interpret the function syntax, validate it and recall the Eval function on you implementation class, recursing all calls.

Aggregate Operators: ag - main aggregation operator fid - formula id, usefull to implement as a persisted formula

Algebraic Operators: + - Add * - Mult / - Div

Transform Operators: sc - value on scale1 to scale2

Logical Operators: & - and | - or < - less then > - bigger then in - in between 2 values

Support

It is currently working with millions of crypto currency tickers and indicators at https://sidegence.com/

Optimizations

All Eval args have default values, so can be queried as "ag(Sum, Quantity, Fr.H1)" means ''Get sum of quantity for the last hour''

2) When quering millions of records to aggregate, make sure to use a fast data series access - EF may not do the job - Stored Procs may be more effective. It is up to your implementation which data series access to use. This lib will only manipulate results, based on the syntax.

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.0.4 97 12/31/2023
2.0.3 125 9/2/2023
2.0.2 261 1/4/2023
2.0.1 257 12/19/2022
2.0.0 264 12/17/2022
1.0.5 385 10/2/2022
1.0.4 361 8/29/2022
1.0.3 355 8/21/2022
1.0.1 361 8/21/2022
1.0.0 380 8/21/2022