From 2f78955d3b0c2e82b6be01d9be67678c2f74d0e8 Mon Sep 17 00:00:00 2001 From: Miha Kralj Date: Fri, 7 Apr 2023 16:49:59 -0700 Subject: [PATCH] Update package version argument in main and dev automation builds --- .github/workflows/main_automation.yml | 17 +- Calculations/Calculations.csproj | 13 +- Calculations/Logic/EQUITY_Series.cs | 58 ++++ Calculations/Trends/HWMA_Series.cs | 2 +- Calculations/Trends/MAMA_Series.cs | 3 +- GitVersion.yml | 10 +- Indicators/Indicators.csproj | 7 +- Strategies/Strategies.csproj | 7 +- Tests/Tests.csproj | 14 +- docs/Trading_example.ipynb | 389 ++++++++++++++++++++++++++ docs/getting_started.ipynb | 347 +++++++++++++++++------ 11 files changed, 752 insertions(+), 115 deletions(-) create mode 100644 Calculations/Logic/EQUITY_Series.cs create mode 100644 docs/Trading_example.ipynb diff --git a/.github/workflows/main_automation.yml b/.github/workflows/main_automation.yml index 091e827b..7781217d 100644 --- a/.github/workflows/main_automation.yml +++ b/.github/workflows/main_automation.yml @@ -26,7 +26,8 @@ jobs: - name: Install GitVersion uses: gittools/actions/gitversion/setup@v0 with: - versionSpec: '5.5.0' + versionSpec: '6.x' + includePrerelease: true - name: Determine Version id: gitversion @@ -34,6 +35,7 @@ jobs: with: useConfigFile: true configFilePath: /a/QuanTAlib/QuanTAlib/GitVersion.yml + additionalArguments: '/updateassemblyinfo /ensureassemblyinfo' - name: Display GitVersion variables (without prefix) run: | @@ -76,10 +78,17 @@ jobs: /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.dotcover.reportsPaths=./coveragereport.html - - name: Build Core QuanTAlib DLL - run: dotnet build ./Calculations/Calculations.csproj --verbosity detailed --configuration Release --nologo + - name: Build Main branch of QuanTAlib DLL + if: ${{ github.ref == 'refs/heads/main' }} + run: dotnet build ./Calculations/Calculations.csproj --verbosity detailed --configuration Release --nologo -p:PackageVersion=${{ steps.gitversion.outputs.MajorMinorPatch }} + + - name: Build dev branch of QuanTAlib DLL + if: ${{ github.ref == 'refs/heads/dev' }} + run: dotnet build ./Calculations/Calculations.csproj --verbosity detailed --configuration Release --nologo -p:PackageVersion=${{ steps.gitversion.outputs.FullSemVer }} + - name: Build Indicators DLL run: dotnet build ./Indicators/Indicators.csproj --verbosity detailed --configuration Release --nologo + - name: Build Strategies DLL run: dotnet build ./Strategies/Strategies.csproj --verbosity detailed --configuration Release --nologo @@ -104,8 +113,6 @@ jobs: project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} coverage-reports: ./coveragereport.xml - - - name: Publish dev release assets if: ${{ github.ref == 'refs/heads/dev' }} uses: SourceSprint/upload-multiple-releases@1.0.7 diff --git a/Calculations/Calculations.csproj b/Calculations/Calculations.csproj index e9e703fd..02fbbdf4 100644 --- a/Calculations/Calculations.csproj +++ b/Calculations/Calculations.csproj @@ -1,7 +1,7 @@ - - + QuanTAlib + 0.2.0 Library of TA Calculations, Charts and Strategies for Quantower Quantitative Technical Analysis Library in C# for Quantower git @@ -31,6 +31,9 @@ Apache-2.0 + 0.2.1.0 + 0.2.1.0 + 0.2.1-dev.2+Branch.dev.Sha.cb5fe2dc86a78fe9358da810d17952c82299ed3d full @@ -51,7 +54,7 @@ https://raw.githubusercontent.com/mihakralj/QuanTAlib/main/.github/QuanTAlib2.png True ..\.sonarlint\mihakralj_quantalibcsharp.ruleset - + 0.2.1-dev.2 @@ -66,9 +69,5 @@ False - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - \ No newline at end of file diff --git a/Calculations/Logic/EQUITY_Series.cs b/Calculations/Logic/EQUITY_Series.cs new file mode 100644 index 00000000..63e8eea5 --- /dev/null +++ b/Calculations/Logic/EQUITY_Series.cs @@ -0,0 +1,58 @@ +namespace QuanTAlib; +using System; + +/* +EQUITY - Generates P&L portfolio based on trades signals and equity prices + + */ + + +//base prices: bars.close +//trade signals: trades +//optional: long, short, long&short +//optional: warmup period: warmup + +public class EQUITY_Series : Single_TSeries_Indicator { + int trade_state = 0; + readonly int _warmup = 0; + double eq_value = 0; + readonly TSeries _prices; + readonly bool _long, _short; + public EQUITY_Series(TSeries trades, TSeries prices, bool Long = true, bool Short = false, int Warmup = 0) : base(trades, period: 0, useNaN: false) { + _prices = prices; + _long = Long; + _short = Short; + _warmup = Warmup; + if (base._data.Count > 0) { base.Add(base._data); } + } + + public override void Add((System.DateTime t, double v) TValue, bool update) { + if (this.Count != 0) + eq_value = this[this.Count - 1].v; + + //buy signal + if (TValue.v == 1 && this.Count > _warmup) { + //we are not in-market and we can do long trades + if (_short) { trade_state = 0; } + if (_long) { trade_state = 1; } + } + + //sell signal + if (TValue.v == -1 && this.Count > _warmup) { + //we are in-market and we can do long trades + if (_long) { trade_state = 0; } + if (_short) { trade_state = -1; } + } + + if (trade_state == 1) { + eq_value = this[this.Count - 1].v + (_prices[this.Count].v - _prices[this.Count - 1].v); + + } + + if (trade_state == -1) { + eq_value = this[this.Count - 1].v + (_prices[this.Count - 1].v - _prices[this.Count].v); + + } + base.Add((TValue.t, eq_value), update, _NaN); + } +} \ No newline at end of file diff --git a/Calculations/Trends/HWMA_Series.cs b/Calculations/Trends/HWMA_Series.cs index 50754285..f2ba9ae3 100644 --- a/Calculations/Trends/HWMA_Series.cs +++ b/Calculations/Trends/HWMA_Series.cs @@ -25,7 +25,7 @@ HWMA[i] = F[i] + V[i] + 0.5 * A[i] */ public class HWMA_Series : Single_TSeries_Indicator { - double _nA, _nB, _nC; + readonly double _nA, _nB, _nC; double _pF, _pV, _pA; double _ppF, _ppV, _ppA; diff --git a/Calculations/Trends/MAMA_Series.cs b/Calculations/Trends/MAMA_Series.cs index ff85d784..7c491913 100644 --- a/Calculations/Trends/MAMA_Series.cs +++ b/Calculations/Trends/MAMA_Series.cs @@ -25,7 +25,8 @@ public class MAMA_Series : Single_TSeries_Indicator if (base._data.Count > 0) { base.Add(base._data); } } - private double sumPr, jI, jQ, fastl, slowl; + private double sumPr, jI, jQ; + readonly double fastl, slowl; private (double i, double i1, double i2, double i3, double i4, double i5, double i6, double io) pr, i1, q1, sm, dt; private (double i, double i1, double io) i2, q2, re, im, pd, ph, mama, fama; public TSeries Fama { get; } diff --git a/GitVersion.yml b/GitVersion.yml index 8ba6110c..405fca4d 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -6,13 +6,15 @@ branches: is-mainline: true prevent-increment-of-merged-branch-version: true track-merge-target: false - increment: inherit + increment: Patch source-branches: [ 'develop' ] is-release-branch: true is-mainline: true - continuous-delivery-fallback-tag: '' + label: '' + #continuous-delivery-fallback-tag: '' develop: regex: ^dev$ + increment: Patch is-release-branch: false prevent-increment-of-merged-branch-version: false track-merge-target: true @@ -20,10 +22,10 @@ branches: is-release-branch: false tracks-release-branches: true is-mainline: false - tag: dev + label: dev ignore: sha: [] major-version-bump-message: '\+semver:\s?(feature|major)' -minor-version-bump-message: '\+semver:\s?(new|update|minor)' +minor-version-bump-message: '\+semver:\s?(new|update|minor|add)' no-bump-message: '\+semver:\s?(skip|none|fix)' diff --git a/Indicators/Indicators.csproj b/Indicators/Indicators.csproj index db3613a6..3ba70424 100644 --- a/Indicators/Indicators.csproj +++ b/Indicators/Indicators.csproj @@ -1,5 +1,4 @@ - - + net6.0 preview @@ -13,6 +12,10 @@ disable False ..\.sonarlint\mihakralj_quantalibcsharp.ruleset + 0.2.1.0 + 0.2.1.0 + 0.2.1-dev.2+Branch.dev.Sha.cb5fe2dc86a78fe9358da810d17952c82299ed3d + 0.2.1-dev.2 True diff --git a/Strategies/Strategies.csproj b/Strategies/Strategies.csproj index 280576ad..88daf6b3 100644 --- a/Strategies/Strategies.csproj +++ b/Strategies/Strategies.csproj @@ -1,5 +1,4 @@ - - + net6.0 preview @@ -13,6 +12,10 @@ disable False ..\.sonarlint\mihakralj_quantalibcsharp.ruleset + 0.2.1.0 + 0.2.1.0 + 0.2.1-dev.2+Branch.dev.Sha.cb5fe2dc86a78fe9358da810d17952c82299ed3d + 0.2.1-dev.2 True diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 214ef839..7751eda6 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -6,11 +6,15 @@ enable false AnyCPU;x64 + 0.2.1.0 + 0.2.1.0 + 0.2.1-dev.2+Branch.dev.Sha.cb5fe2dc86a78fe9358da810d17952c82299ed3d + 0.2.1-dev.2 - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all @@ -21,15 +25,13 @@ - - - + \ No newline at end of file diff --git a/docs/Trading_example.ipynb b/docs/Trading_example.ipynb new file mode 100644 index 00000000..0178351b --- /dev/null +++ b/docs/Trading_example.ipynb @@ -0,0 +1,389 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
Installed Packages
  • QuanTAlib, 0.2.0
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "#r \"nuget: QuanTAlib\"\n", + "#r \"nuget: Plotly.NET;\"\n", + "#r \"nuget: Plotly.NET.Interactive;\"\n", + "\n", + "using QuanTAlib;\n", + "using Plotly.NET;\n", + "using Plotly.NET.LayoutObjects;" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "string symbol=\"SPY\"; // we'll focus on SPY symbol\n", + "int warmup = 50; // we'll allow 50 bars to pass by with no trading - for warm-up\n", + "Yahoo_Feed bars = new(symbol,350); //collect bars of symbol from Yahoo feed\n", + "TSeries data = bars.Close; //we need just one average value - (Open+High+Low+CLose)/4\n", + "\n", + "//make a chart\n", + "var d = Chart2D.Chart.Candlestick(bars.Open.v.Skip(warmup).ToList(), bars.High.v.Skip(warmup).ToList(), \n", + "bars.Low.v.Skip(warmup).ToList(), bars.Close.v.Skip(warmup).ToList(), bars.Open.t.Skip(warmup).ToList(), symbol)\n", + " .WithSize(1200,400).WithMargin(Margin.init(30,10,40,30,1,false)).WithXAxisRangeSlider(RangeSlider.init(Visible:false)).WithTitle(symbol);\n", + "d" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "JMA_Series fastMA = new(data,12); //typically MACD uses EMA(12), but let's try with superior JMA(12)\n", + "JMA_Series slowMA = new(data,26); //likewise, let's use JMA(26) instead of EMA(26)\n", + "\n", + "//make a chart\n", + "var cfast = Chart2D.Chart.Line(fastMA.t.Skip(warmup).ToList(), fastMA.v.Skip(warmup).ToList(), false, \"Fast MA\").WithLineStyle(Width: 2, Color: Color.fromString(\"blue\"));\n", + "var cslow = Chart2D.Chart.Line(slowMA.t.Skip(warmup).ToList(), slowMA.v.Skip(warmup).ToList(), false, \"Slow MA\").WithLineStyle(Width: 2, Color: Color.fromString(\"red\"));\n", + "var chart = Chart.Combine(new []{cfast,cslow}).WithSize(1200,400).WithMargin(Margin.init(30,10,40,30,1,false))\n", + " .WithXAxisRangeSlider(RangeSlider.init(Visible:false)).WithTitle($\"slow MA and fast MA of {symbol} OHLC4\");\n", + "chart" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "SUB_Series MACD_line = new(fastMA, slowMA); //MACD line is just a SUBtraction fastMA-slowMA\n", + "JMA_Series signal_line = new(MACD_line, 9); //signal line is an EMA(9) of MACD; we use superior JMA(9) instead\n", + "\n", + "//make a chart\n", + "var cfast = Chart2D.Chart.Line(MACD_line.t.Skip(warmup).ToList(), MACD_line.v.Skip(warmup).ToList(), false, \"MACD\").WithLineStyle(Width: 2, Color: Color.fromString(\"orange\"));\n", + "var cslow = Chart2D.Chart.Line(signal_line.t.Skip(warmup).ToList(), signal_line.v.Skip(warmup).ToList(), false, \"signal\").WithLineStyle(Width: 2, Color: Color.fromString(\"green\"));\n", + "var chart = Chart.Combine(new []{cfast,cslow}).WithSize(1200,400).WithMargin(Margin.init(30,10,40,30,1,false))\n", + " .WithXAxisRangeSlider(RangeSlider.init(Visible:false)).WithTitle($\"MACD line and signal line of fastMA-slowMA\");\n", + "chart" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "SUB_Series histogram = new(MACD_line, signal_line); //MACD histogram is an oscillator of MACD-signal\n", + "\n", + "//make a chart\n", + "var cfast = Chart2D.Chart.Column(values: histogram.v.Skip(warmup).ToList(), Keys: histogram.t.Skip(warmup).ToList())\n", + ".WithSize(1200,400).WithMargin(Margin.init(30,10,40,30,1,false)).WithXAxisRangeSlider(RangeSlider.init(Visible:false))\n", + ".WithTitle(\"MACD histogram of MACD-signal\");\n", + "cfast" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "COMPARE_Series over = new(histogram,0); //generate over/under series when histogram is above/below zero\n", + "CROSS_Series trades = new(histogram,0); //generate a signal series where histogram crosses zero (from below and from above)\n", + "\n", + "//make a chart\n", + "var cover = Chart2D.Chart.Line(over.t.Skip(warmup).ToList(),over.v.Skip(warmup).ToList(),false,\"state\").WithLineStyle(Width: 1, Color: Color.fromString(\"blue\"));\n", + "var cbars = Chart2D.Chart.Area(trades.t.Skip(warmup).ToList(), trades.v.Skip(warmup).ToList(),false );\n", + "var chart = Chart.Combine(new []{cover,cbars}).WithSize(1200,400).WithMargin(Margin.init(30,10,40,30,1,false))\n", + " .WithXAxisRangeSlider(RangeSlider.init(Visible:false)).WithTitle(\"in-market signal and trading orders based on MACD histogram\");\n", + "chart" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "EQUITY_Series folio = new(trades, data, Long:true, Short:false, Warmup:warmup); //generate equity curve from trades and \n", + "\n", + "//make a chart\n", + "var cbars = Chart2D.Chart.Area(folio.t.Skip(warmup).ToList(), folio.v.Skip(warmup).ToList(),false ).WithSize(1200,400).WithMargin(Margin.init(30,10,40,30,1,false))\n", + " .WithXAxisRangeSlider(RangeSlider.init(Visible:false)).WithTitle($\"Trading P&L (long only) for MACD-generated trades on {symbol}\");\n", + "cbars" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".NET (C#)", + "language": "C#", + "name": ".net-csharp" + }, + "language_info": { + "name": "polyglot-notebook" + }, + "polyglot_notebook": { + "kernelInfo": { + "defaultKernelName": "csharp", + "items": [ + { + "aliases": [ + "C#", + "c#" + ], + "languageName": "C#", + "name": "csharp" + }, + { + "aliases": [ + "frontend" + ], + "name": "vscode" + } + ] + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/getting_started.ipynb b/docs/getting_started.ipynb index bf8c469c..681f37e2 100644 --- a/docs/getting_started.ipynb +++ b/docs/getting_started.ipynb @@ -2,14 +2,7 @@ "cells": [ { "cell_type": "markdown", - "metadata": { - "dotnet_interactive": { - "language": "csharp" - }, - "polyglot_notebook": { - "kernelName": "csharp" - } - }, + "metadata": {}, "source": [ "# Quick Start\n", "\n", @@ -24,16 +17,39 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "dotnet_interactive": { "language": "csharp" - }, - "vscode": { - "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "index\t data\t\t sma(data)\t ema(sma(data))\t wma(ema(sma(data)))\n", + "0\t 2023-03-27\t 158.28\t\t 158.28\t\t NaN\n", + "1\t 2023-03-28\t 157.97\t\t 158.12\t\t NaN\n", + "2\t 2023-03-29\t 158.90\t\t 158.38\t\t NaN\n", + "3\t 2023-03-30\t 159.77\t\t 158.73\t\t NaN\n", + "4\t 2023-03-31\t 160.79\t\t 159.14\t\t 158.69\n", + "5\t 2023-04-03\t 162.37\t\t 160.22\t\t 159.25\n", + "6\t 2023-04-04\t 163.97\t\t 161.47\t\t 160.10\n", + "7\t 2023-04-05\t 164.56\t\t 162.50\t\t 161.07\n", + "8\t 2023-04-06\t 165.02\t\t 163.34\t\t 162.04\n" + ] + } + ], "source": [ "#r \"nuget:QuanTAlib;\"\n", "using QuanTAlib;\n", @@ -51,14 +67,7 @@ }, { "cell_type": "markdown", - "metadata": { - "dotnet_interactive": { - "language": "csharp" - }, - "polyglot_notebook": { - "kernelName": "csharp" - } - }, + "metadata": {}, "source": [ "## Understanding QuanTAlib data model\n", "\n", @@ -67,16 +76,54 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "dotnet_interactive": { "language": "csharp" - }, - "vscode": { - "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
indexvalue
0
(4/7/2023 12:00:00 AM, 105.3)
Item12023-04-07 00:00:00Z
Item2
105.3
1
(4/7/2023 2:34:48 PM, 293.1)
Item12023-04-07 14:34:48Z
Item2
293.1
2
(4/7/2023 2:34:48 PM, 0)
Item12023-04-07 14:34:48Z
Item2
0
3
(4/4/2023 2:34:48 PM, 10)
Item12023-04-04 14:34:48Z
Item2
10
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "var item1 = (DateTime.Today, 105.3); // (DateTime, Value) tuple\n", "double item2 = 293.1; // a simple double\n", @@ -92,60 +139,122 @@ }, { "cell_type": "markdown", - "metadata": { - "dotnet_interactive": { - "language": "csharp" - }, - "polyglot_notebook": { - "kernelName": "csharp" - } - }, + "metadata": {}, "source": [ "TSeries list can display only values (without timestamps) or only timestamps (without values) by using `.v` or `.t` properties" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "dotnet_interactive": { "language": "csharp" - }, - "vscode": { - "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
[ 105.3, 293.1, 0, 10 ]
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "data.v" ] }, { "cell_type": "markdown", - "metadata": { - "dotnet_interactive": { - "language": "csharp" - }, - "polyglot_notebook": { - "kernelName": "csharp" - } - }, + "metadata": {}, "source": [ "The last element on the list can be accessed by .Last() or by [^1] - and using `.t` (time) and `.v` (value) properties. Also, casting a TSeries into (double) will return the value of the last element" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": { "dotnet_interactive": { "language": "csharp" - }, - "vscode": { - "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
10
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "bool IsTheSame = data.Last().v == data[^1].v;\n", "double lastvalue = data;\n", @@ -155,30 +264,61 @@ }, { "cell_type": "markdown", - "metadata": { - "dotnet_interactive": { - "language": "csharp" - }, - "polyglot_notebook": { - "kernelName": "csharp" - } - }, + "metadata": {}, "source": [ "All indicators are just modified TSeries classes; they get all required input during class construction (source of the datafeed, period...) and they automatically subscribe to events of the datafeed. Whenever datafeed gets a new value, indicator will calculate its own value. Indicators are also event publishers, so other indicators can subscribe to their results, chaining indicators together:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "dotnet_interactive": { "language": "csharp" - }, - "vscode": { - "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
[ Infinity, 0.6666666666666666, 0.3333333333333333, 0.2, 0.14285714285714285, 0.1111111111111111, 0.09090909090909091, 0.07692307692307693, 0.06666666666666667, 0.058823529411764705, 0.25 ]
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "TSeries t1 = new() {0,1,2,3,4,5,6,7,8,9}; // t1 is loaded with data and activated as a publisher\n", "EMA_Series t2 = new(t1, 3); // t2 will auto-load all history of t1 and wait for events from t1\n", @@ -194,14 +334,7 @@ }, { "cell_type": "markdown", - "metadata": { - "dotnet_interactive": { - "language": "csharp" - }, - "polyglot_notebook": { - "kernelName": "csharp" - } - }, + "metadata": {}, "source": [ "# MACD compounded indicator\n", "\n", @@ -210,16 +343,54 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "dotnet_interactive": { "language": "csharp" - }, - "vscode": { - "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.000974358974349343, -0.03456027049873228, -0.13792617985566447, -0.4729486712049916, -0.825402881197467, -0.8902360596814031, -0.9360607784903126, -0.7333381872239422 ... (79 more) ]
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "Yahoo_Feed aapl = new(\"AAPL\", 100);\n", "TSeries close = aapl.Close; // close will get data from history\n", @@ -239,29 +410,31 @@ "language": "C#", "name": ".net-csharp" }, + "language_info": { + "name": "polyglot-notebook" + }, "polyglot_notebook": { "kernelInfo": { "defaultKernelName": "csharp", "items": [ { "aliases": [ - "c#", - "C#" + "C#", + "c#" ], "languageName": "C#", "name": "csharp" }, - { - "aliases": [ - "frontend" - ], - "languageName": null, - "name": "vscode" - }, { "aliases": [], "languageName": "KQL", "name": "kql" + }, + { + "aliases": [ + "frontend" + ], + "name": "vscode" } ] }