Minor update

This commit is contained in:
Miha Kralj
2023-10-14 17:54:45 -07:00
parent 97f0c78a70
commit 1faf47e85f
5 changed files with 146 additions and 221 deletions
+4 -4
View File
@@ -2,9 +2,9 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Title>QuanTAlib</Title> <Title>QuanTAlib</Title>
<Version>0.2.5</Version> <Version>0.2.27</Version>
<AssemblyVersion>0.2.5</AssemblyVersion> <AssemblyVersion>0.2.27</AssemblyVersion>
<FileVersion>0.2.5</FileVersion> <FileVersion>0.2.27</FileVersion>
<Product>Library of TA Calculations, Charts and Strategies for Quantower</Product> <Product>Library of TA Calculations, Charts and Strategies for Quantower</Product>
<Description>Quantitative Technical Analysis Library in C# for Quantower</Description> <Description>Quantitative Technical Analysis Library in C# for Quantower</Description>
<RepositoryType>git</RepositoryType> <RepositoryType>git</RepositoryType>
@@ -24,7 +24,7 @@
<IsPublishable>True</IsPublishable> <IsPublishable>True</IsPublishable>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks> <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<DebugType>embedded</DebugType> <DebugType>full</DebugType>
<ProduceReferenceAssembly>True</ProduceReferenceAssembly> <ProduceReferenceAssembly>True</ProduceReferenceAssembly>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild> <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageTags> <PackageTags>
+27 -15
View File
@@ -21,7 +21,8 @@ Issues:
</summary> */ </summary> */
public class JMA_Series : TSeries { public class JMA_Series : TSeries
{
protected readonly int _period; protected readonly int _period;
protected readonly bool _NaN; protected readonly bool _NaN;
protected readonly TSeries _data; protected readonly TSeries _data;
@@ -34,7 +35,8 @@ public class JMA_Series : TSeries {
private readonly int _voltyS, _voltyL; private readonly int _voltyS, _voltyL;
//core constructors //core constructors
public JMA_Series(int period, double phase, int vshort, int vlong, bool useNaN) { public JMA_Series(int period, double phase, int vshort, int vlong, bool useNaN)
{
_period = period; _period = period;
_NaN = useNaN; _NaN = useNaN;
Name = $"JMA({period})"; Name = $"JMA({period})";
@@ -46,7 +48,8 @@ public class JMA_Series : TSeries {
_voltyL = vlong; _voltyL = vlong;
} }
public JMA_Series(TSeries source, int period, double phase, int vshort, int vlong, bool useNaN) : this(period, phase, vshort, vlong, useNaN) { public JMA_Series(TSeries source, int period, double phase, int vshort, int vlong, bool useNaN) : this(period, phase, vshort, vlong, useNaN)
{
_data = source; _data = source;
Name = Name.Substring(0, Name.IndexOf(")")) + $", {(string.IsNullOrEmpty(_data.Name) ? "data" : _data.Name)})"; Name = Name.Substring(0, Name.IndexOf(")")) + $", {(string.IsNullOrEmpty(_data.Name) ? "data" : _data.Name)})";
_data.Pub += Sub; _data.Pub += Sub;
@@ -63,9 +66,11 @@ public class JMA_Series : TSeries {
////////////////// //////////////////
// core Add() algo // core Add() algo
public override (DateTime t, double v) Add((DateTime t, double v) TValue, bool update = false) { public override (DateTime t, double v) Add((DateTime t, double v) TValue, bool update = false)
{
if (this.Count == 0) { prev_ma1 = prev_jma = TValue.v; } if (this.Count == 0) { prev_ma1 = prev_jma = TValue.v; }
if (update) { if (update)
{
upperBand = p_upperBand; upperBand = p_upperBand;
lowerBand = p_lowerBand; lowerBand = p_lowerBand;
Kv = p_Kv; Kv = p_Kv;
@@ -75,7 +80,8 @@ public class JMA_Series : TSeries {
prev_det1 = p_prev_det1; prev_det1 = p_prev_det1;
prev_jma = p_prev_jma; prev_jma = p_prev_jma;
} }
else { else
{
p_upperBand = upperBand; p_upperBand = upperBand;
p_lowerBand = lowerBand; p_lowerBand = lowerBand;
p_Kv = Kv; p_Kv = Kv;
@@ -86,7 +92,8 @@ public class JMA_Series : TSeries {
p_prev_jma = prev_jma; p_prev_jma = prev_jma;
} }
if (double.IsNaN(TValue.v)) { if (double.IsNaN(TValue.v))
{
return base.Add((TValue.t, double.NaN), update); return base.Add((TValue.t, double.NaN), update);
} }
@@ -95,9 +102,9 @@ public class JMA_Series : TSeries {
double del2 = TValue.v - lowerBand; double del2 = TValue.v - lowerBand;
upperBand = (del1 > 0) ? TValue.v : TValue.v - (Kv * del1); upperBand = (del1 > 0) ? TValue.v : TValue.v - (Kv * del1);
lowerBand = (del2 < 0) ? TValue.v : TValue.v - (Kv * del2); lowerBand = (del2 < 0) ? TValue.v : TValue.v - (Kv * del2);
double volty = 0; double volty = Math.Abs(del1) > Math.Abs(del2) ? Math.Abs(del1) :
if (Math.Abs(del1) > Math.Abs(del2)) { volty = Math.Abs(del1); } (Math.Abs(del1) < Math.Abs(del2) ? Math.Abs(del2) :
if (Math.Abs(del1) < Math.Abs(del2)) { volty = Math.Abs(del2); } Math.Abs(0.5 * (del1 + del2)));
//// from volty to avolty //// from volty to avolty
if (update) { volty_short[volty_short.Count - 1] = volty; } if (update) { volty_short[volty_short.Count - 1] = volty; }
@@ -142,23 +149,28 @@ public class JMA_Series : TSeries {
return base.Add(res, update); return base.Add(res, update);
} }
public override (DateTime t, double v) Add(TSeries data) { public override (DateTime t, double v) Add(TSeries data)
{
if (data == null) { return (DateTime.Today, Double.NaN); } if (data == null) { return (DateTime.Today, Double.NaN); }
foreach (var item in data) { Add(item, false); } foreach (var item in data) { Add(item, false); }
return _data.Last; return _data.Last;
} }
public (DateTime t, double v) Add(bool update) { public (DateTime t, double v) Add(bool update)
{
return this.Add(TValue: _data.Last, update: update); return this.Add(TValue: _data.Last, update: update);
} }
public (DateTime t, double v) Add() { public (DateTime t, double v) Add()
{
return Add(TValue: _data.Last, update: false); return Add(TValue: _data.Last, update: false);
} }
private new void Sub(object source, TSeriesEventArgs e) { private new void Sub(object source, TSeriesEventArgs e)
{
Add(TValue: _data.Last, update: e.update); Add(TValue: _data.Last, update: e.update);
} }
//reset calculation //reset calculation
public override void Reset() { public override void Reset()
{
upperBand = lowerBand = prev_ma1 = prev_det0 = prev_det1 = prev_vsum = prev_jma = Kv = 0.0; upperBand = lowerBand = prev_ma1 = prev_det0 = prev_det1 = prev_vsum = prev_jma = Kv = 0.0;
} }
} }
+1 -1
View File
@@ -22,7 +22,7 @@ public class TSeriesEventArgs : EventArgs {
public class TSeries : List<(DateTime t, double v)> { public class TSeries : List<(DateTime t, double v)> {
public List<DateTime> t => this.Select(item => item.t).ToList(); public List<DateTime> t => this.Select(item => item.t).ToList();
public List<double> v => this.Select(item => item.v).ToList(); public List<double> v => this.Select(item => item.v).ToList();
public (DateTime t, double v) Last => this[this.Count - 1]; public (DateTime t, double v) Last => this[^1];
public int Length => Count; public int Length => Count;
public string Name { get; set; } public string Name { get; set; }
-89
View File
@@ -1,89 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using TradingPlatform.BusinessLayer;
using QuanTAlib;
using System.Drawing;
namespace SimpleMACross {
public class SimpleMACross1 : Strategy, ICurrentAccount, ICurrentSymbol {
[InputParameter("Symbol", 0)]
public Symbol CurrentSymbol { get; set; }
[InputParameter("Account", 1)]
public Account CurrentAccount { get; set; }
[InputParameter("Fast MA", 2, minimum: 1, maximum: 100, increment: 1, decimalPlaces: 0)]
private int FastMA = 5;
[InputParameter("Slow MA", 3, minimum: 1, maximum: 100, increment: 1, decimalPlaces: 0)]
private int SlowMA = 10;
[InputParameter("Quantity", 4, 0.1, 99999, 0.1, 2)]
private double Quantity = 1.0;
[InputParameter("Period", 5)]
private Period period = Period.MIN1;
public override string[] MonitoringConnectionsIds => new string[] { this.CurrentSymbol?.ConnectionId, this.CurrentAccount?.ConnectionId };
private HistoricalData hdm;
private DateTime prev_time;
private readonly TBars bars = new();
public SimpleMACross1() {
this.Name = "MA Cross strategy 3";
this.Description = "Raw strategy without any additional functional";
}
protected override void OnRun() {
if (this.CurrentAccount != null && this.CurrentAccount.State == BusinessObjectState.Fake) {this.CurrentAccount = Core.Instance.GetAccount(this.CurrentAccount.CreateInfo());}
if (this.CurrentSymbol != null && this.CurrentSymbol.State == BusinessObjectState.Fake) {this.CurrentSymbol = Core.Instance.GetSymbol(this.CurrentSymbol.CreateInfo());}
if (this.CurrentSymbol == null || this.CurrentAccount == null || this.CurrentSymbol.ConnectionId != this.CurrentAccount.ConnectionId) {
this.Log("Incorrect input parameters... Symbol or Account are not specified or they have different connectionID.", StrategyLoggingLevel.Error);
return; }
/////////////////////////////////////////////////////
this.hdm = this.CurrentSymbol.GetHistory(Period.MIN1, this.CurrentSymbol.HistoryType, Core.TimeUtils.DateTimeUtcNow.AddDays(-1));
////////////////////////////////////////////////////
this.LogInfo($"Symbol: {CurrentSymbol.Name} period: {this.period} :-: {this.CurrentSymbol.HistoryType.ToString()} :-: {this.hdm.Count} bars loaded");
this.hdm.HistoryItemUpdated += this.Hdm_HistoryItemUpdated;
}
private void Hdm_HistoryItemUpdated(object sender, HistoryEventArgs e) {
this.OnUpdate();
}
private void OnUpdate() {
bool update = hdm.Last().TimeLeft - prev_time < this.period.Duration ? true : false;
if (!update) {prev_time = hdm.Last().TimeLeft;}
bars.Add(hdm.Last().TimeLeft, hdm.Last()[PriceType.Open], hdm.Last()[PriceType.High],
hdm.Last()[PriceType.Low], hdm.Last()[PriceType.Close], hdm.Last()[PriceType.Volume], update);
if (!update) {this.LogInfo($"{bars.Close.Last().t} OHLC4:{(double)bars.OHLC4.Last.v}");}
}
protected override List<StrategyMetric> OnGetMetrics() {
var result = base.OnGetMetrics();
// An example of adding custom strategy metrics:
result.Add("Bars processed", this.bars.Count.ToString());
return result;
}
protected override void OnStop() {
if (this.hdm != null) {
this.hdm.HistoryItemUpdated -= this.Hdm_HistoryItemUpdated;
this.hdm.Dispose();
}
base.OnStop();
}
}
}
@@ -0,0 +1,2 @@
"To use unique insights from EPAM's history, expertise, and innovative spirit we want to recalibrate technology strategies to deliver solutions that are not just innovative, but driven by value creation. We envision a future where every client engagement is delivers integrated value from strategy to optimization, and where our technical thought leadership is a benchmark for the industry, ensuring that EPAM is synonymous with transformative digital engineering."