mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-20 11:38:05 +00:00
refactor structs to records, add new classes for financial calculations, implement EMA and SMA with circular buffer. Generate random financial data using GBM model. Also, test the SMA calculation with sample data.
This commit is contained in:
+259
-245
@@ -4,270 +4,284 @@ using System.Linq;
|
||||
using TradingPlatform.BusinessLayer;
|
||||
namespace QuanTAlib;
|
||||
|
||||
public class MovingAverage_chart : Indicator {
|
||||
#region Parameters
|
||||
[InputParameter("MA1: Type:", 0, variants: new object[]
|
||||
{ "SMA", 0, "EMA", 1, "WMA", 2, "T3", 3, "SMMA", 4, "TRIMA", 5, "DWMA", 6, "FWMA", 7, "DEMA", 8, "TEMA", 9,
|
||||
"ALMA", 10, "HMA", 11, "HEMA", 12, "MAMA", 13, "KAMA", 14, "ZLEMA", 15, "JMA", 16})]
|
||||
private int MA1type = 15;
|
||||
public class MovingAverage_chart : Indicator
|
||||
{
|
||||
#region Parameters
|
||||
[InputParameter("MA1: Type:", 0, variants: new object[]
|
||||
{ "SMA", 0, "EMA", 1, "WMA", 2, "T3", 3, "SMMA", 4, "TRIMA", 5, "DWMA", 6, "FWMA", 7, "DEMA", 8, "TEMA", 9,
|
||||
"ALMA", 10, "HMA", 11, "HEMA", 12, "MAMA", 13, "KAMA", 14, "ZLEMA", 15, "JMA", 16})]
|
||||
private int MA1type = 15;
|
||||
|
||||
[InputParameter("MA1: Smoothing period:", 1, 1, 999, 1, 1)]
|
||||
private int MA1Period = 10;
|
||||
[InputParameter("MA1: Smoothing period:", 1, 1, 999, 1, 1)]
|
||||
private int MA1Period = 10;
|
||||
|
||||
[InputParameter("MA1: Data source:", 2, variants: new object[]
|
||||
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
|
||||
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
|
||||
private int MA1DataSource = 3;
|
||||
[InputParameter("MA1: Data source:", 2, variants: new object[]
|
||||
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
|
||||
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
|
||||
private int MA1DataSource = 3;
|
||||
|
||||
[InputParameter("MA2: Type:", 3, variants: new object[]
|
||||
{ "SMA", 0, "EMA", 1, "WMA", 2, "T3", 3, "SMMA", 4, "TRIMA", 5, "DWMA", 6, "FWMA", 7, "DEMA", 8, "TEMA", 9,
|
||||
"ALMA", 10, "HMA", 11, "HEMA", 12, "MAMA", 13, "KAMA", 14, "ZLEMA", 15, "JMA", 16})]
|
||||
private int MA2type = 16;
|
||||
[InputParameter("MA2: Type:", 3, variants: new object[]
|
||||
{ "SMA", 0, "EMA", 1, "WMA", 2, "T3", 3, "SMMA", 4, "TRIMA", 5, "DWMA", 6, "FWMA", 7, "DEMA", 8, "TEMA", 9,
|
||||
"ALMA", 10, "HMA", 11, "HEMA", 12, "MAMA", 13, "KAMA", 14, "ZLEMA", 15, "JMA", 16})]
|
||||
private int MA2type = 16;
|
||||
|
||||
[InputParameter("MA2: Smoothing period:", 4, 1, 999, 1, 1)]
|
||||
private int MA2Period = 50;
|
||||
[InputParameter("MA2: Smoothing period:", 4, 1, 999, 1, 1)]
|
||||
private int MA2Period = 50;
|
||||
|
||||
[InputParameter("MA2: Data source:", 5, variants: new object[]
|
||||
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
|
||||
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
|
||||
private int MA2DataSource = 8;
|
||||
[InputParameter("MA2: Data source:", 5, variants: new object[]
|
||||
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
|
||||
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
|
||||
private int MA2DataSource = 8;
|
||||
|
||||
[InputParameter("Long trades", 6)]
|
||||
private bool LongTrades = true;
|
||||
[InputParameter("Long trades", 6)]
|
||||
private bool LongTrades = true;
|
||||
|
||||
[InputParameter("Short trades", 6)]
|
||||
private bool ShortTrades = true;
|
||||
[InputParameter("Short trades", 6)]
|
||||
private bool ShortTrades = true;
|
||||
|
||||
#endregion Parameters
|
||||
#endregion Parameters
|
||||
|
||||
protected HistoricalData History;
|
||||
private TBars bars;
|
||||
protected HistoricalData History;
|
||||
private TBars bars;
|
||||
|
||||
///////
|
||||
private TSeries MA1, MA2;
|
||||
private CROSS_Series trades;
|
||||
private COMPARE_Series overunder;
|
||||
///////
|
||||
private TSeries MA1, MA2;
|
||||
private CROSS_Series trades;
|
||||
private COMPARE_Series overunder;
|
||||
|
||||
///////
|
||||
///////
|
||||
|
||||
public MovingAverage_chart() {
|
||||
this.SeparateWindow = false;
|
||||
this.Name = "MAs Crossover";
|
||||
this.AddLineSeries("MA1", Color.LimeGreen, 2, LineStyle.Solid);
|
||||
this.AddLineSeries("MA2", Color.OrangeRed, 2, LineStyle.Solid);
|
||||
}
|
||||
public MovingAverage_chart()
|
||||
{
|
||||
this.SeparateWindow = false;
|
||||
this.Name = "MAs Crossover";
|
||||
this.AddLineSeries("MA1", Color.LimeGreen, 2, LineStyle.Solid);
|
||||
this.AddLineSeries("MA2", Color.OrangeRed, 2, LineStyle.Solid);
|
||||
}
|
||||
|
||||
protected override void OnInit() {
|
||||
this.bars = new();
|
||||
this.History = this.Symbol.GetHistory(period: this.HistoricalData.Period, fromTime: HistoricalData.FromTime);
|
||||
for (int i = this.History.Count - 1; i >= 0; i--) {
|
||||
var rec = this.History[i, SeekOriginHistory.Begin];
|
||||
bars.Add(rec.TimeLeft, rec[PriceType.Open],
|
||||
rec[PriceType.High], rec[PriceType.Low],
|
||||
rec[PriceType.Close], rec[PriceType.Volume]);
|
||||
}
|
||||
this.Name = "MAs Cross: [ ";
|
||||
switch (MA1type) {
|
||||
case 0:
|
||||
MA1 = new SMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"SMA";
|
||||
break;
|
||||
case 1:
|
||||
MA1 = new EMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"EMA";
|
||||
break;
|
||||
case 2:
|
||||
MA1 = new WMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"WMA";
|
||||
break;
|
||||
case 3:
|
||||
MA1 = new T3_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"T3";
|
||||
break;
|
||||
case 4:
|
||||
MA1 = new SMMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"SMMA";
|
||||
break;
|
||||
case 5:
|
||||
MA1 = new TRIMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"TRIMA";
|
||||
break;
|
||||
case 6:
|
||||
MA1 = new DWMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"DWMA";
|
||||
break;
|
||||
case 7:
|
||||
MA1 = new FWMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period);
|
||||
this.Name += $"FWMA";
|
||||
break;
|
||||
case 8:
|
||||
MA1 = new DEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"DEMA";
|
||||
break;
|
||||
case 9:
|
||||
MA1 = new TEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"TEMA";
|
||||
break;
|
||||
case 10:
|
||||
MA1 = new ALMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"ALMA";
|
||||
break;
|
||||
case 11:
|
||||
MA1 = new HMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"HMA";
|
||||
break;
|
||||
case 12:
|
||||
MA1 = new HEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"HEMA";
|
||||
break;
|
||||
case 13:
|
||||
double factor = 1.015 * Math.Exp(-0.043 * (double)this.MA1Period);
|
||||
MA1 = new MAMA_Series(source: bars.Select(this.MA1DataSource), fastlimit: factor, slowlimit: factor * 0.1, useNaN: false);
|
||||
this.Name += $"MAMA";
|
||||
break;
|
||||
case 14:
|
||||
MA1 = new KAMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"KAMA";
|
||||
break;
|
||||
case 15:
|
||||
MA1 = new ZLEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"ZLEMA";
|
||||
break;
|
||||
default:
|
||||
MA1 = new JMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"JMA";
|
||||
break;
|
||||
}
|
||||
protected override void OnInit()
|
||||
{
|
||||
this.bars = new();
|
||||
this.History = this.Symbol.GetHistory(period: this.HistoricalData.Period, fromTime: HistoricalData.FromTime);
|
||||
for (int i = this.History.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var rec = this.History[i, SeekOriginHistory.Begin];
|
||||
bars.Add(rec.TimeLeft, rec[PriceType.Open],
|
||||
rec[PriceType.High], rec[PriceType.Low],
|
||||
rec[PriceType.Close], rec[PriceType.Volume]);
|
||||
}
|
||||
this.Name = "MAs Cross: [ ";
|
||||
switch (MA1type)
|
||||
{
|
||||
case 0:
|
||||
MA1 = new SMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"SMA";
|
||||
break;
|
||||
case 1:
|
||||
MA1 = new EMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"EMA";
|
||||
break;
|
||||
case 2:
|
||||
MA1 = new WMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"WMA";
|
||||
break;
|
||||
case 3:
|
||||
MA1 = new T3_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"T3";
|
||||
break;
|
||||
case 4:
|
||||
MA1 = new SMMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"SMMA";
|
||||
break;
|
||||
case 5:
|
||||
MA1 = new TRIMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"TRIMA";
|
||||
break;
|
||||
case 6:
|
||||
MA1 = new DWMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"DWMA";
|
||||
break;
|
||||
case 7:
|
||||
MA1 = new FWMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period);
|
||||
this.Name += $"FWMA";
|
||||
break;
|
||||
case 8:
|
||||
MA1 = new DEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"DEMA";
|
||||
break;
|
||||
case 9:
|
||||
MA1 = new TEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"TEMA";
|
||||
break;
|
||||
case 10:
|
||||
MA1 = new ALMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"ALMA";
|
||||
break;
|
||||
case 11:
|
||||
MA1 = new HMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"HMA";
|
||||
break;
|
||||
case 12:
|
||||
MA1 = new HEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"HEMA";
|
||||
break;
|
||||
case 13:
|
||||
double factor = 1.015 * Math.Exp(-0.043 * (double)this.MA1Period);
|
||||
MA1 = new MAMA_Series(source: bars.Select(this.MA1DataSource), fastlimit: factor, slowlimit: factor * 0.1, useNaN: false);
|
||||
this.Name += $"MAMA";
|
||||
break;
|
||||
case 14:
|
||||
MA1 = new KAMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"KAMA";
|
||||
break;
|
||||
case 15:
|
||||
MA1 = new ZLEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"ZLEMA";
|
||||
break;
|
||||
default:
|
||||
MA1 = new JMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"JMA";
|
||||
break;
|
||||
}
|
||||
|
||||
this.Name = this.Name + $" ({MA1Period}:{TBars.SelectStr(this.MA1DataSource)}) : ";
|
||||
this.Name = this.Name + $" ({MA1Period}:{TBars.SelectStr(this.MA1DataSource)}) : ";
|
||||
|
||||
switch (MA2type) {
|
||||
case 0:
|
||||
MA2 = new SMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"SMA";
|
||||
break;
|
||||
case 1:
|
||||
MA2 = new EMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"EMA";
|
||||
break;
|
||||
case 2:
|
||||
MA2 = new WMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"WMA";
|
||||
break;
|
||||
case 3:
|
||||
MA2 = new T3_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"T3";
|
||||
break;
|
||||
case 4:
|
||||
MA2 = new SMMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"SMMA";
|
||||
break;
|
||||
case 5:
|
||||
MA2 = new TRIMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"TRIMA";
|
||||
break;
|
||||
case 6:
|
||||
MA2 = new DWMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"DWMA";
|
||||
break;
|
||||
case 7:
|
||||
MA2 = new FWMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period);
|
||||
this.Name += $"FWMA";
|
||||
break;
|
||||
case 8:
|
||||
MA2 = new DEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"DEMA";
|
||||
break;
|
||||
case 9:
|
||||
MA2 = new TEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"TEMA";
|
||||
break;
|
||||
case 10:
|
||||
MA2 = new ALMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"ALMA";
|
||||
break;
|
||||
case 11:
|
||||
MA2 = new HMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"HMA";
|
||||
break;
|
||||
case 12:
|
||||
MA2 = new HEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"HEMA";
|
||||
break;
|
||||
case 13:
|
||||
double factor = 1.015 * Math.Exp(-0.043 * (double)this.MA2Period);
|
||||
MA2 = new MAMA_Series(source: bars.Select(this.MA2DataSource), fastlimit: factor, slowlimit: factor * 0.1, useNaN: false);
|
||||
this.Name += $"MAMA";
|
||||
break;
|
||||
case 14:
|
||||
MA2 = new KAMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"KAMA";
|
||||
break;
|
||||
case 15:
|
||||
MA2 = new ZLEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"ZLEMA";
|
||||
break;
|
||||
default:
|
||||
MA2 = new JMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"JMA";
|
||||
break;
|
||||
}
|
||||
this.Name += $"({MA2Period}:{TBars.SelectStr(this.MA2DataSource)}) ]";
|
||||
switch (MA2type)
|
||||
{
|
||||
case 0:
|
||||
MA2 = new SMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"SMA";
|
||||
break;
|
||||
case 1:
|
||||
MA2 = new EMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"EMA";
|
||||
break;
|
||||
case 2:
|
||||
MA2 = new WMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"WMA";
|
||||
break;
|
||||
case 3:
|
||||
MA2 = new T3_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"T3";
|
||||
break;
|
||||
case 4:
|
||||
MA2 = new SMMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"SMMA";
|
||||
break;
|
||||
case 5:
|
||||
MA2 = new TRIMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"TRIMA";
|
||||
break;
|
||||
case 6:
|
||||
MA2 = new DWMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"DWMA";
|
||||
break;
|
||||
case 7:
|
||||
MA2 = new FWMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period);
|
||||
this.Name += $"FWMA";
|
||||
break;
|
||||
case 8:
|
||||
MA2 = new DEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"DEMA";
|
||||
break;
|
||||
case 9:
|
||||
MA2 = new TEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"TEMA";
|
||||
break;
|
||||
case 10:
|
||||
MA2 = new ALMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"ALMA";
|
||||
break;
|
||||
case 11:
|
||||
MA2 = new HMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"HMA";
|
||||
break;
|
||||
case 12:
|
||||
MA2 = new HEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"HEMA";
|
||||
break;
|
||||
case 13:
|
||||
double factor = 1.015 * Math.Exp(-0.043 * (double)this.MA2Period);
|
||||
MA2 = new MAMA_Series(source: bars.Select(this.MA2DataSource), fastlimit: factor, slowlimit: factor * 0.1, useNaN: false);
|
||||
this.Name += $"MAMA";
|
||||
break;
|
||||
case 14:
|
||||
MA2 = new KAMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"KAMA";
|
||||
break;
|
||||
case 15:
|
||||
MA2 = new ZLEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"ZLEMA";
|
||||
break;
|
||||
default:
|
||||
MA2 = new JMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"JMA";
|
||||
break;
|
||||
}
|
||||
this.Name += $"({MA2Period}:{TBars.SelectStr(this.MA2DataSource)}) ]";
|
||||
|
||||
int maxKeep = Math.Max(Math.Max(this.MA1Period, this.MA2Period), 100);
|
||||
MA1.Keep = maxKeep;
|
||||
MA2.Keep = maxKeep;
|
||||
trades.Keep = maxKeep;
|
||||
overunder.Keep = maxKeep;
|
||||
int maxKeep = Math.Max(Math.Max(this.MA1Period, this.MA2Period), 100);
|
||||
MA1.Keep = maxKeep;
|
||||
MA2.Keep = maxKeep;
|
||||
trades.Keep = maxKeep;
|
||||
overunder.Keep = maxKeep;
|
||||
|
||||
overunder = new(MA1, MA2);
|
||||
trades = new(MA1, MA2);
|
||||
}
|
||||
overunder = new(MA1, MA2);
|
||||
trades = new(MA1, MA2);
|
||||
}
|
||||
|
||||
protected override void OnUpdate(UpdateArgs args) {
|
||||
bool update = !(args.Reason == UpdateReason.NewBar ||
|
||||
args.Reason == UpdateReason.HistoricalBar);
|
||||
this.bars.Add(this.Time(), this.GetPrice(PriceType.Open),
|
||||
this.GetPrice(PriceType.High),
|
||||
this.GetPrice(PriceType.Low),
|
||||
this.GetPrice(PriceType.Close),
|
||||
this.GetPrice(PriceType.Volume), update);
|
||||
this.SetValue(this.MA1[^1].v, lineIndex: 0);
|
||||
this.SetValue(this.MA2[^1].v, lineIndex: 1);
|
||||
protected override void OnUpdate(UpdateArgs args)
|
||||
{
|
||||
bool update = !(args.Reason == UpdateReason.NewBar ||
|
||||
args.Reason == UpdateReason.HistoricalBar);
|
||||
this.bars.Add(this.Time(), this.GetPrice(PriceType.Open),
|
||||
this.GetPrice(PriceType.High),
|
||||
this.GetPrice(PriceType.Low),
|
||||
this.GetPrice(PriceType.Close),
|
||||
this.GetPrice(PriceType.Volume), update);
|
||||
this.SetValue(this.MA1[^1].v, lineIndex: 0);
|
||||
this.SetValue(this.MA2[^1].v, lineIndex: 1);
|
||||
|
||||
if (trades[^1].v == 1) {
|
||||
this.EndCloud(0, 1, Color.Empty);
|
||||
if (LongTrades) {
|
||||
this.LinesSeries[0].SetMarker(0, new IndicatorLineMarker(Color.LimeGreen, bottomIcon: IndicatorLineMarkerIconType.UpArrow));
|
||||
this.BeginCloud(0, 1, Color.FromArgb(127, Color.Green));
|
||||
}
|
||||
if (ShortTrades) {
|
||||
this.LinesSeries[1].SetMarker(0, new IndicatorLineMarker(Color.OrangeRed, upperIcon: IndicatorLineMarkerIconType.DownArrow));
|
||||
}
|
||||
}
|
||||
if (trades[^1].v == -1) {
|
||||
this.EndCloud(0, 1, Color.Empty);
|
||||
if (ShortTrades) {
|
||||
this.LinesSeries[1].SetMarker(0, new IndicatorLineMarker(Color.OrangeRed, upperIcon: IndicatorLineMarkerIconType.UpArrow));
|
||||
this.BeginCloud(0, 1, Color.FromArgb(127, Color.Red));
|
||||
}
|
||||
if (LongTrades) {
|
||||
this.LinesSeries[0].SetMarker(0, new IndicatorLineMarker(Color.LimeGreen, bottomIcon: IndicatorLineMarkerIconType.DownArrow));
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void OnPaintChart(PaintChartEventArgs args) {
|
||||
base.OnPaintChart(args);
|
||||
if (this.CurrentChart == null) {return;}
|
||||
Graphics graphics = args.Graphics;
|
||||
var mainWindow = this.CurrentChart.MainWindow;
|
||||
int leftIndex = (int)mainWindow.CoordinatesConverter.GetBarIndex(mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Left));
|
||||
int rightIndex = (int)Math.Ceiling(mainWindow.CoordinatesConverter.GetBarIndex(mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Right)));
|
||||
int historycount = HistoricalData.Count;
|
||||
int ymax = mainWindow.ClientRectangle.Height;
|
||||
int xmax = mainWindow.ClientRectangle.Width;
|
||||
if (trades[^1].v == 1)
|
||||
{
|
||||
this.EndCloud(0, 1, Color.Empty);
|
||||
if (LongTrades)
|
||||
{
|
||||
this.LinesSeries[0].SetMarker(0, new IndicatorLineMarker(Color.LimeGreen, bottomIcon: IndicatorLineMarkerIconType.UpArrow));
|
||||
this.BeginCloud(0, 1, Color.FromArgb(127, Color.Green));
|
||||
}
|
||||
if (ShortTrades)
|
||||
{
|
||||
this.LinesSeries[1].SetMarker(0, new IndicatorLineMarker(Color.OrangeRed, upperIcon: IndicatorLineMarkerIconType.DownArrow));
|
||||
}
|
||||
}
|
||||
if (trades[^1].v == -1)
|
||||
{
|
||||
this.EndCloud(0, 1, Color.Empty);
|
||||
if (ShortTrades)
|
||||
{
|
||||
this.LinesSeries[1].SetMarker(0, new IndicatorLineMarker(Color.OrangeRed, upperIcon: IndicatorLineMarkerIconType.UpArrow));
|
||||
this.BeginCloud(0, 1, Color.FromArgb(127, Color.Red));
|
||||
}
|
||||
if (LongTrades)
|
||||
{
|
||||
this.LinesSeries[0].SetMarker(0, new IndicatorLineMarker(Color.LimeGreen, bottomIcon: IndicatorLineMarkerIconType.DownArrow));
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void OnPaintChart(PaintChartEventArgs args)
|
||||
{
|
||||
base.OnPaintChart(args);
|
||||
if (this.CurrentChart == null) { return; }
|
||||
Graphics graphics = args.Graphics;
|
||||
var mainWindow = this.CurrentChart.MainWindow;
|
||||
int leftIndex = (int)mainWindow.CoordinatesConverter.GetBarIndex(mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Left));
|
||||
int rightIndex = (int)Math.Ceiling(mainWindow.CoordinatesConverter.GetBarIndex(mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Right)));
|
||||
int historycount = HistoricalData.Count;
|
||||
int ymax = mainWindow.ClientRectangle.Height;
|
||||
int xmax = mainWindow.ClientRectangle.Width;
|
||||
|
||||
/*
|
||||
/*
|
||||
for (int i = leftIndex; i <= rightIndex; i++) {
|
||||
int xi = (int)Math.Round(mainWindow.CoordinatesConverter.GetChartX(Time(Count - 1 - i)));
|
||||
int width = this.CurrentChart.BarsWidth;
|
||||
@@ -280,5 +294,5 @@ public class MovingAverage_chart : Indicator {
|
||||
graphics.FillRectangle(bb, xi, ymax - height, width, height);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+285
-272
@@ -4,304 +4,317 @@ using System.Linq;
|
||||
using TradingPlatform.BusinessLayer;
|
||||
namespace QuanTAlib;
|
||||
|
||||
public class MovingAverageSlope_chart : Indicator {
|
||||
#region Parameters
|
||||
[InputParameter("MA1: Type:", 0, variants: new object[]
|
||||
{ "SMA", 0, "EMA", 1, "WMA", 2, "T3", 3, "SMMA", 4, "TRIMA", 5, "DWMA", 6, "FWMA", 7, "DEMA", 8, "TEMA", 9,
|
||||
"ALMA", 10, "HMA", 11, "HEMA", 12, "MAMA", 13, "KAMA", 14, "ZLEMA", 15, "JMA", 16})]
|
||||
private int MA1type = 16;
|
||||
public class MovingAverageSlope_chart : Indicator
|
||||
{
|
||||
#region Parameters
|
||||
[InputParameter("MA1: Type:", 0, variants: new object[]
|
||||
{ "SMA", 0, "EMA", 1, "WMA", 2, "T3", 3, "SMMA", 4, "TRIMA", 5, "DWMA", 6, "FWMA", 7, "DEMA", 8, "TEMA", 9,
|
||||
"ALMA", 10, "HMA", 11, "HEMA", 12, "MAMA", 13, "KAMA", 14, "ZLEMA", 15, "JMA", 16})]
|
||||
private int MA1type = 16;
|
||||
|
||||
[InputParameter("MA1: Smoothing period:", 1, 1, 999, 1, 1)]
|
||||
private int MA1Period = 10;
|
||||
[InputParameter("MA1: Smoothing period:", 1, 1, 999, 1, 1)]
|
||||
private int MA1Period = 10;
|
||||
|
||||
[InputParameter("MA1: Data source:", 2, variants: new object[]
|
||||
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
|
||||
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
|
||||
private int MA1DataSource = 3;
|
||||
[InputParameter("MA1: Data source:", 2, variants: new object[]
|
||||
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
|
||||
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
|
||||
private int MA1DataSource = 3;
|
||||
|
||||
[InputParameter("MA2: Type:", 3, variants: new object[]
|
||||
{ "SMA", 0, "EMA", 1, "WMA", 2, "T3", 3, "SMMA", 4, "TRIMA", 5, "DWMA", 6, "FWMA", 7, "DEMA", 8, "TEMA", 9,
|
||||
"ALMA", 10, "HMA", 11, "HEMA", 12, "MAMA", 13, "KAMA", 14, "ZLEMA", 15, "JMA", 16})]
|
||||
private int MA2type = 6;
|
||||
[InputParameter("MA2: Type:", 3, variants: new object[]
|
||||
{ "SMA", 0, "EMA", 1, "WMA", 2, "T3", 3, "SMMA", 4, "TRIMA", 5, "DWMA", 6, "FWMA", 7, "DEMA", 8, "TEMA", 9,
|
||||
"ALMA", 10, "HMA", 11, "HEMA", 12, "MAMA", 13, "KAMA", 14, "ZLEMA", 15, "JMA", 16})]
|
||||
private int MA2type = 6;
|
||||
|
||||
[InputParameter("MA2: Smoothing period:", 4, 1, 999, 1, 1)]
|
||||
private int MA2Period = 50;
|
||||
[InputParameter("MA2: Smoothing period:", 4, 1, 999, 1, 1)]
|
||||
private int MA2Period = 50;
|
||||
|
||||
[InputParameter("MA2: Data source:", 5, variants: new object[]
|
||||
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
|
||||
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
|
||||
private int MA2DataSource = 8;
|
||||
[InputParameter("MA2: Data source:", 5, variants: new object[]
|
||||
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
|
||||
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
|
||||
private int MA2DataSource = 8;
|
||||
|
||||
[InputParameter("Data required for slope calc:", 6, 2, 10, 1, 1)]
|
||||
private int SlopePeriod = 3;
|
||||
[InputParameter("Data required for slope calc:", 6, 2, 10, 1, 1)]
|
||||
private int SlopePeriod = 3;
|
||||
|
||||
[InputParameter("Long trades", 7)]
|
||||
private bool LongTrades = true;
|
||||
[InputParameter("Long trades", 7)]
|
||||
private bool LongTrades = true;
|
||||
|
||||
[InputParameter("Short trades", 8)]
|
||||
private bool ShortTrades;
|
||||
[InputParameter("Short trades", 8)]
|
||||
private bool ShortTrades;
|
||||
|
||||
#endregion Parameters
|
||||
#endregion Parameters
|
||||
|
||||
protected HistoricalData History;
|
||||
private TBars bars;
|
||||
protected HistoricalData History;
|
||||
private TBars bars;
|
||||
|
||||
///////
|
||||
private TSeries MA1, MA2;
|
||||
private SLOPE_Series sMA1, sMA2;
|
||||
private CROSS_Series sig1, sig2;
|
||||
///////
|
||||
private TSeries MA1, MA2;
|
||||
private SLOPE_Series sMA1, sMA2;
|
||||
private CROSS_Series sig1, sig2;
|
||||
|
||||
private bool inLong, inShort;
|
||||
///////
|
||||
private bool inLong, inShort;
|
||||
///////
|
||||
|
||||
public MovingAverageSlope_chart() {
|
||||
this.SeparateWindow = false;
|
||||
this.Name = "Slopes convergence";
|
||||
this.AddLineSeries("MA1", Color.DarkSlateGray, 2, LineStyle.Solid);
|
||||
this.AddLineSeries("MA2", Color.DarkSlateGray, 2, LineStyle.Solid);
|
||||
}
|
||||
public MovingAverageSlope_chart()
|
||||
{
|
||||
this.SeparateWindow = false;
|
||||
this.Name = "Slopes convergence";
|
||||
this.AddLineSeries("MA1", Color.DarkSlateGray, 2, LineStyle.Solid);
|
||||
this.AddLineSeries("MA2", Color.DarkSlateGray, 2, LineStyle.Solid);
|
||||
}
|
||||
|
||||
protected override void OnInit() {
|
||||
this.bars = new();
|
||||
this.History = this.Symbol.GetHistory(period: this.HistoricalData.Period, fromTime: HistoricalData.FromTime);
|
||||
for (int i = this.History.Count - 1; i >= 0; i--) {
|
||||
var rec = this.History[i, SeekOriginHistory.Begin];
|
||||
bars.Add(rec.TimeLeft, rec[PriceType.Open],
|
||||
rec[PriceType.High], rec[PriceType.Low],
|
||||
rec[PriceType.Close], rec[PriceType.Volume]);
|
||||
}
|
||||
this.Name = "Slopes convergence: [ ";
|
||||
switch (MA1type) {
|
||||
case 0:
|
||||
MA1 = new SMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"SMA";
|
||||
break;
|
||||
case 1:
|
||||
MA1 = new EMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"EMA";
|
||||
break;
|
||||
case 2:
|
||||
MA1 = new WMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"WMA";
|
||||
break;
|
||||
case 3:
|
||||
MA1 = new T3_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"T3";
|
||||
break;
|
||||
case 4:
|
||||
MA1 = new SMMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"SMMA";
|
||||
break;
|
||||
case 5:
|
||||
MA1 = new TRIMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"TRIMA";
|
||||
break;
|
||||
case 6:
|
||||
MA1 = new DWMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"DWMA";
|
||||
break;
|
||||
case 7:
|
||||
MA1 = new FWMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period);
|
||||
this.Name += $"FWMA";
|
||||
break;
|
||||
case 8:
|
||||
MA1 = new DEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"DEMA";
|
||||
break;
|
||||
case 9:
|
||||
MA1 = new TEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"TEMA";
|
||||
break;
|
||||
case 10:
|
||||
MA1 = new ALMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"ALMA";
|
||||
break;
|
||||
case 11:
|
||||
MA1 = new HMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"HMA";
|
||||
break;
|
||||
case 12:
|
||||
MA1 = new HEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"HEMA";
|
||||
break;
|
||||
case 13:
|
||||
double factor = 1.015 * Math.Exp(-0.043 * (double)this.MA1Period);
|
||||
MA1 = new MAMA_Series(source: bars.Select(this.MA1DataSource), fastlimit: factor, slowlimit: factor * 0.1, useNaN: false);
|
||||
this.Name += $"MAMA";
|
||||
break;
|
||||
case 14:
|
||||
MA1 = new KAMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"KAMA";
|
||||
break;
|
||||
case 15:
|
||||
MA1 = new ZLEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"ZLEMA";
|
||||
break;
|
||||
default:
|
||||
MA1 = new JMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"JMA";
|
||||
break;
|
||||
}
|
||||
protected override void OnInit()
|
||||
{
|
||||
this.bars = new();
|
||||
this.History = this.Symbol.GetHistory(period: this.HistoricalData.Period, fromTime: HistoricalData.FromTime);
|
||||
for (int i = this.History.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var rec = this.History[i, SeekOriginHistory.Begin];
|
||||
bars.Add(rec.TimeLeft, rec[PriceType.Open],
|
||||
rec[PriceType.High], rec[PriceType.Low],
|
||||
rec[PriceType.Close], rec[PriceType.Volume]);
|
||||
}
|
||||
this.Name = "Slopes convergence: [ ";
|
||||
switch (MA1type)
|
||||
{
|
||||
case 0:
|
||||
MA1 = new SMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"SMA";
|
||||
break;
|
||||
case 1:
|
||||
MA1 = new EMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"EMA";
|
||||
break;
|
||||
case 2:
|
||||
MA1 = new WMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"WMA";
|
||||
break;
|
||||
case 3:
|
||||
MA1 = new T3_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"T3";
|
||||
break;
|
||||
case 4:
|
||||
MA1 = new SMMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"SMMA";
|
||||
break;
|
||||
case 5:
|
||||
MA1 = new TRIMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"TRIMA";
|
||||
break;
|
||||
case 6:
|
||||
MA1 = new DWMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"DWMA";
|
||||
break;
|
||||
case 7:
|
||||
MA1 = new FWMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period);
|
||||
this.Name += $"FWMA";
|
||||
break;
|
||||
case 8:
|
||||
MA1 = new DEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"DEMA";
|
||||
break;
|
||||
case 9:
|
||||
MA1 = new TEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"TEMA";
|
||||
break;
|
||||
case 10:
|
||||
MA1 = new ALMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"ALMA";
|
||||
break;
|
||||
case 11:
|
||||
MA1 = new HMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"HMA";
|
||||
break;
|
||||
case 12:
|
||||
MA1 = new HEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"HEMA";
|
||||
break;
|
||||
case 13:
|
||||
double factor = 1.015 * Math.Exp(-0.043 * (double)this.MA1Period);
|
||||
MA1 = new MAMA_Series(source: bars.Select(this.MA1DataSource), fastlimit: factor, slowlimit: factor * 0.1, useNaN: false);
|
||||
this.Name += $"MAMA";
|
||||
break;
|
||||
case 14:
|
||||
MA1 = new KAMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"KAMA";
|
||||
break;
|
||||
case 15:
|
||||
MA1 = new ZLEMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"ZLEMA";
|
||||
break;
|
||||
default:
|
||||
MA1 = new JMA_Series(source: bars.Select(this.MA1DataSource), period: this.MA1Period, useNaN: false);
|
||||
this.Name += $"JMA";
|
||||
break;
|
||||
}
|
||||
|
||||
this.Name = this.Name + $" ({MA1Period}:{TBars.SelectStr(this.MA1DataSource)}) : ";
|
||||
this.Name = this.Name + $" ({MA1Period}:{TBars.SelectStr(this.MA1DataSource)}) : ";
|
||||
|
||||
switch (MA2type) {
|
||||
case 0:
|
||||
MA2 = new SMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"SMA";
|
||||
break;
|
||||
case 1:
|
||||
MA2 = new EMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"EMA";
|
||||
break;
|
||||
case 2:
|
||||
MA2 = new WMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"WMA";
|
||||
break;
|
||||
case 3:
|
||||
MA2 = new T3_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"T3";
|
||||
break;
|
||||
case 4:
|
||||
MA2 = new SMMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"SMMA";
|
||||
break;
|
||||
case 5:
|
||||
MA2 = new TRIMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"TRIMA";
|
||||
break;
|
||||
case 6:
|
||||
MA2 = new DWMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"DWMA";
|
||||
break;
|
||||
case 7:
|
||||
MA2 = new FWMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period);
|
||||
this.Name += $"FWMA";
|
||||
break;
|
||||
case 8:
|
||||
MA2 = new DEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"DEMA";
|
||||
break;
|
||||
case 9:
|
||||
MA2 = new TEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"TEMA";
|
||||
break;
|
||||
case 10:
|
||||
MA2 = new ALMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"ALMA";
|
||||
break;
|
||||
case 11:
|
||||
MA2 = new HMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"HMA";
|
||||
break;
|
||||
case 12:
|
||||
MA2 = new HEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"HEMA";
|
||||
break;
|
||||
case 13:
|
||||
double factor = 1.015 * Math.Exp(-0.043 * (double)this.MA2Period);
|
||||
MA2 = new MAMA_Series(source: bars.Select(this.MA2DataSource), fastlimit: factor, slowlimit: factor * 0.1, useNaN: false);
|
||||
this.Name += $"MAMA";
|
||||
break;
|
||||
case 14:
|
||||
MA2 = new KAMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"KAMA";
|
||||
break;
|
||||
case 15:
|
||||
MA2 = new ZLEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"ZLEMA";
|
||||
break;
|
||||
default:
|
||||
MA2 = new JMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"JMA";
|
||||
break;
|
||||
}
|
||||
this.Name += $"({MA2Period}:{TBars.SelectStr(this.MA2DataSource)}) ]";
|
||||
switch (MA2type)
|
||||
{
|
||||
case 0:
|
||||
MA2 = new SMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"SMA";
|
||||
break;
|
||||
case 1:
|
||||
MA2 = new EMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"EMA";
|
||||
break;
|
||||
case 2:
|
||||
MA2 = new WMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"WMA";
|
||||
break;
|
||||
case 3:
|
||||
MA2 = new T3_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"T3";
|
||||
break;
|
||||
case 4:
|
||||
MA2 = new SMMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"SMMA";
|
||||
break;
|
||||
case 5:
|
||||
MA2 = new TRIMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"TRIMA";
|
||||
break;
|
||||
case 6:
|
||||
MA2 = new DWMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"DWMA";
|
||||
break;
|
||||
case 7:
|
||||
MA2 = new FWMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period);
|
||||
this.Name += $"FWMA";
|
||||
break;
|
||||
case 8:
|
||||
MA2 = new DEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"DEMA";
|
||||
break;
|
||||
case 9:
|
||||
MA2 = new TEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"TEMA";
|
||||
break;
|
||||
case 10:
|
||||
MA2 = new ALMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"ALMA";
|
||||
break;
|
||||
case 11:
|
||||
MA2 = new HMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"HMA";
|
||||
break;
|
||||
case 12:
|
||||
MA2 = new HEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"HEMA";
|
||||
break;
|
||||
case 13:
|
||||
double factor = 1.015 * Math.Exp(-0.043 * (double)this.MA2Period);
|
||||
MA2 = new MAMA_Series(source: bars.Select(this.MA2DataSource), fastlimit: factor, slowlimit: factor * 0.1, useNaN: false);
|
||||
this.Name += $"MAMA";
|
||||
break;
|
||||
case 14:
|
||||
MA2 = new KAMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"KAMA";
|
||||
break;
|
||||
case 15:
|
||||
MA2 = new ZLEMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"ZLEMA";
|
||||
break;
|
||||
default:
|
||||
MA2 = new JMA_Series(source: bars.Select(this.MA2DataSource), period: this.MA2Period, useNaN: false);
|
||||
this.Name += $"JMA";
|
||||
break;
|
||||
}
|
||||
this.Name += $"({MA2Period}:{TBars.SelectStr(this.MA2DataSource)}) ]";
|
||||
|
||||
sMA1 = new(MA1, SlopePeriod);
|
||||
sMA2 = new(MA2, SlopePeriod);
|
||||
sig1 = new(sMA1, 0);
|
||||
sig2 = new(sMA2, 0);
|
||||
sMA1 = new(MA1, SlopePeriod);
|
||||
sMA2 = new(MA2, SlopePeriod);
|
||||
sig1 = new(sMA1, 0);
|
||||
sig2 = new(sMA2, 0);
|
||||
|
||||
int maxKeep = Math.Max(Math.Max(this.MA1Period, this.MA2Period), 100);
|
||||
int maxKeep = Math.Max(Math.Max(this.MA1Period, this.MA2Period), 100);
|
||||
|
||||
MA1.Keep = maxKeep;
|
||||
MA2.Keep = maxKeep;
|
||||
sMA1.Keep = maxKeep;
|
||||
sMA2.Keep = maxKeep;
|
||||
sig1.Keep = maxKeep;
|
||||
sig2.Keep = maxKeep;
|
||||
}
|
||||
MA1.Keep = maxKeep;
|
||||
MA2.Keep = maxKeep;
|
||||
sMA1.Keep = maxKeep;
|
||||
sMA2.Keep = maxKeep;
|
||||
sig1.Keep = maxKeep;
|
||||
sig2.Keep = maxKeep;
|
||||
}
|
||||
|
||||
protected override void OnUpdate(UpdateArgs args) {
|
||||
bool update = !(args.Reason == UpdateReason.NewBar ||
|
||||
args.Reason == UpdateReason.HistoricalBar);
|
||||
this.bars.Add(this.Time(),this.Open(), this.High(), this.Low(), this.Close(), this.Volume(), update);
|
||||
this.SetValue(this.MA1[^1].v, lineIndex: 0);
|
||||
this.SetValue(this.MA2[^1].v, lineIndex: 1);
|
||||
protected override void OnUpdate(UpdateArgs args)
|
||||
{
|
||||
bool update = !(args.Reason == UpdateReason.NewBar ||
|
||||
args.Reason == UpdateReason.HistoricalBar);
|
||||
this.bars.Add(this.Time(), this.Open(), this.High(), this.Low(), this.Close(), this.Volume(), update);
|
||||
this.SetValue(this.MA1[^1].v, lineIndex: 0);
|
||||
this.SetValue(this.MA2[^1].v, lineIndex: 1);
|
||||
|
||||
Color s1Color= (this.sMA1[^1].v > 0)?Color.LimeGreen:Color.OrangeRed;
|
||||
Color s2Color = (this.sMA2[^1].v > 0) ? Color.LimeGreen : Color.OrangeRed;
|
||||
Color s1Color = (this.sMA1[^1].v > 0) ? Color.LimeGreen : Color.OrangeRed;
|
||||
Color s2Color = (this.sMA2[^1].v > 0) ? Color.LimeGreen : Color.OrangeRed;
|
||||
|
||||
this.LinesSeries[0].SetMarker(0,s1Color);
|
||||
this.LinesSeries[1].SetMarker(0,s2Color);
|
||||
this.LinesSeries[0].SetMarker(0, s1Color);
|
||||
this.LinesSeries[1].SetMarker(0, s2Color);
|
||||
|
||||
if (sig1[^1].v > 0 || sig2[^1].v > 0) {
|
||||
if (sMA1[^1].v >= 0 && sMA2[^1].v >= 0 && LongTrades)
|
||||
{
|
||||
inLong = true;
|
||||
this.BeginCloud(0, 1, Color.FromArgb(127, Color.DarkGreen));
|
||||
this.LinesSeries[(this.MA1[^1].v < this.MA2[^1].v)? 0 : 1 ].SetMarker(0, new IndicatorLineMarker(Color.LimeGreen, bottomIcon: IndicatorLineMarkerIconType.UpArrow));
|
||||
}
|
||||
else {
|
||||
this.EndCloud(0, 1, Color.Empty);
|
||||
if (inShort && this.Count > 1)
|
||||
{
|
||||
this.LinesSeries[(this.MA1[^1].v < this.MA2[^1].v) ? 1 : 0].SetMarker(1, new IndicatorLineMarker(Color.OrangeRed, upperIcon: IndicatorLineMarkerIconType.DownArrow));
|
||||
inShort = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sig1[^1].v > 0 || sig2[^1].v > 0)
|
||||
{
|
||||
if (sMA1[^1].v >= 0 && sMA2[^1].v >= 0 && LongTrades)
|
||||
{
|
||||
inLong = true;
|
||||
this.BeginCloud(0, 1, Color.FromArgb(127, Color.DarkGreen));
|
||||
this.LinesSeries[(this.MA1[^1].v < this.MA2[^1].v) ? 0 : 1].SetMarker(0, new IndicatorLineMarker(Color.LimeGreen, bottomIcon: IndicatorLineMarkerIconType.UpArrow));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.EndCloud(0, 1, Color.Empty);
|
||||
if (inShort && this.Count > 1)
|
||||
{
|
||||
this.LinesSeries[(this.MA1[^1].v < this.MA2[^1].v) ? 1 : 0].SetMarker(1, new IndicatorLineMarker(Color.OrangeRed, upperIcon: IndicatorLineMarkerIconType.DownArrow));
|
||||
inShort = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sig1[^1].v < 0 || sig2[^1].v < 0) {
|
||||
if (sMA1[^1].v <= 0 && sMA2[^1].v <= 0 && ShortTrades)
|
||||
{
|
||||
inShort = true;
|
||||
this.BeginCloud(0, 1, Color.FromArgb(100, Color.Red));
|
||||
this.LinesSeries[(this.MA1[^1].v > this.MA2[^1].v) ? 0 : 1].SetMarker(0, new IndicatorLineMarker(Color.OrangeRed, upperIcon: IndicatorLineMarkerIconType.UpArrow));
|
||||
}
|
||||
else {
|
||||
this.EndCloud(0, 1, Color.Empty);
|
||||
if (inLong && this.Count > 1) {
|
||||
LinesSeries[(this.MA1[^1].v > this.MA2[^1].v)?1:0].SetMarker(1, new IndicatorLineMarker(Color.LimeGreen, bottomIcon: IndicatorLineMarkerIconType.DownArrow));
|
||||
inLong = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void OnPaintChart(PaintChartEventArgs args) {
|
||||
base.OnPaintChart(args);
|
||||
if (this.CurrentChart == null) {return;}
|
||||
Graphics graphics = args.Graphics;
|
||||
var mainWindow = this.CurrentChart.MainWindow;
|
||||
int leftIndex = (int)mainWindow.CoordinatesConverter.GetBarIndex(mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Left));
|
||||
int rightIndex = (int)Math.Ceiling(mainWindow.CoordinatesConverter.GetBarIndex(mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Right)));
|
||||
/*
|
||||
int historycount = HistoricalData.Count;
|
||||
int ymax = mainWindow.ClientRectangle.Height;
|
||||
if (sig1[^1].v < 0 || sig2[^1].v < 0)
|
||||
{
|
||||
if (sMA1[^1].v <= 0 && sMA2[^1].v <= 0 && ShortTrades)
|
||||
{
|
||||
inShort = true;
|
||||
this.BeginCloud(0, 1, Color.FromArgb(100, Color.Red));
|
||||
this.LinesSeries[(this.MA1[^1].v > this.MA2[^1].v) ? 0 : 1].SetMarker(0, new IndicatorLineMarker(Color.OrangeRed, upperIcon: IndicatorLineMarkerIconType.UpArrow));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.EndCloud(0, 1, Color.Empty);
|
||||
if (inLong && this.Count > 1)
|
||||
{
|
||||
LinesSeries[(this.MA1[^1].v > this.MA2[^1].v) ? 1 : 0].SetMarker(1, new IndicatorLineMarker(Color.LimeGreen, bottomIcon: IndicatorLineMarkerIconType.DownArrow));
|
||||
inLong = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void OnPaintChart(PaintChartEventArgs args)
|
||||
{
|
||||
base.OnPaintChart(args);
|
||||
if (this.CurrentChart == null) { return; }
|
||||
Graphics graphics = args.Graphics;
|
||||
var mainWindow = this.CurrentChart.MainWindow;
|
||||
int leftIndex = (int)mainWindow.CoordinatesConverter.GetBarIndex(mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Left));
|
||||
int rightIndex = (int)Math.Ceiling(mainWindow.CoordinatesConverter.GetBarIndex(mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Right)));
|
||||
/*
|
||||
int historycount = HistoricalData.Count;
|
||||
int ymax = mainWindow.ClientRectangle.Height;
|
||||
|
||||
|
||||
for (int i = leftIndex; i <= rightIndex; i++) {
|
||||
int xi = (int)Math.Round(mainWindow.CoordinatesConverter.GetChartX(Time(Count - 1 - i)));
|
||||
int width = this.CurrentChart.BarsWidth;
|
||||
int height = (int)((equity[i+historycount].v) *proportion);
|
||||
for (int i = leftIndex; i <= rightIndex; i++) {
|
||||
int xi = (int)Math.Round(mainWindow.CoordinatesConverter.GetChartX(Time(Count - 1 - i)));
|
||||
int width = this.CurrentChart.BarsWidth;
|
||||
int height = (int)((equity[i+historycount].v) *proportion);
|
||||
|
||||
Brush bb = Brushes.DarkSlateGray;
|
||||
bb = (overunder[i+historycount].v>0 && LongTrades)? Brushes.Green : bb;
|
||||
bb = (overunder[i + historycount].v < 0 && ShortTrades) ? Brushes.Red : bb;
|
||||
Brush bb = Brushes.DarkSlateGray;
|
||||
bb = (overunder[i+historycount].v>0 && LongTrades)? Brushes.Green : bb;
|
||||
bb = (overunder[i + historycount].v < 0 && ShortTrades) ? Brushes.Red : bb;
|
||||
|
||||
graphics.FillRectangle(bb, xi, ymax - height, width, height);
|
||||
}
|
||||
*/
|
||||
}
|
||||
graphics.FillRectangle(bb, xi, ymax - height, width, height);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,92 +6,99 @@ using TradingPlatform.BusinessLayer;
|
||||
using TradingPlatform.BusinessLayer.Chart;
|
||||
namespace QuanTAlib;
|
||||
|
||||
public class JMA_chart : Indicator {
|
||||
#region Parameters
|
||||
public class JMA_chart : Indicator
|
||||
{
|
||||
#region Parameters
|
||||
|
||||
[InputParameter("Data source", 0, variants: new object[]
|
||||
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
|
||||
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
|
||||
private int DataSource = 3;
|
||||
[InputParameter("Data source", 0, variants: new object[]
|
||||
{ "Open", 0, "High", 1, "Low", 2, "Close", 3, "HL2", 4, "OC2", 5,
|
||||
"OHL3", 6, "HLC3", 7, "OHLC4", 8, "Weighted (HLCC4)", 9 })]
|
||||
private int DataSource = 3;
|
||||
|
||||
[InputParameter("Smoothing period", 1, 1, 999, 1, 1)]
|
||||
private int Period = 9;
|
||||
[InputParameter("Smoothing period", 1, 1, 999, 1, 1)]
|
||||
private int Period = 9;
|
||||
|
||||
[InputParameter("Volatility short", 2, 3, 50, 1, 1)]
|
||||
private int Vshort = 10;
|
||||
[InputParameter("Volatility short", 2, 3, 50, 1, 1)]
|
||||
private int Vshort = 10;
|
||||
|
||||
[InputParameter("Volatility long", 3, 20, 500, 1, 1)]
|
||||
private int Vlong = 65;
|
||||
[InputParameter("Volatility long", 3, 20, 500, 1, 1)]
|
||||
private int Vlong = 65;
|
||||
|
||||
[InputParameter("Phase", 4, -100, 100, 1, 2)]
|
||||
private double Jphase;
|
||||
[InputParameter("Phase", 4, -100, 100, 1, 2)]
|
||||
private double Jphase;
|
||||
|
||||
#endregion Parameters
|
||||
#endregion Parameters
|
||||
|
||||
///////
|
||||
private JMA_Series indicator;
|
||||
///////
|
||||
///////
|
||||
private JMA_Series indicator;
|
||||
///////
|
||||
|
||||
protected TBars bars;
|
||||
protected IChartWindow mainWindow;
|
||||
protected Graphics graphics;
|
||||
protected int firstOnScreenBarIndex, lastOnScreenBarIndex;
|
||||
protected HistoricalData History;
|
||||
protected int HistPeriod;
|
||||
public JMA_chart() {
|
||||
Name = "JMA - Jurik Moving Avg";
|
||||
Description = "Jurik Moving Average description";
|
||||
AddLineSeries(lineName: "JMA", lineColor: Color.Yellow, lineWidth: 3,lineStyle: LineStyle.Solid);
|
||||
SeparateWindow = false;
|
||||
HistPeriod = Period;
|
||||
}
|
||||
protected TBars bars;
|
||||
protected IChartWindow mainWindow;
|
||||
protected Graphics graphics;
|
||||
protected int firstOnScreenBarIndex, lastOnScreenBarIndex;
|
||||
protected HistoricalData History;
|
||||
protected int HistPeriod;
|
||||
public JMA_chart()
|
||||
{
|
||||
Name = "JMA - Jurik Moving Avg";
|
||||
Description = "Jurik Moving Average description";
|
||||
AddLineSeries(lineName: "JMA", lineColor: Color.Yellow, lineWidth: 3, lineStyle: LineStyle.Solid);
|
||||
SeparateWindow = false;
|
||||
HistPeriod = Period;
|
||||
}
|
||||
|
||||
|
||||
protected override void OnInit() {
|
||||
base.OnInit();
|
||||
bars = new();
|
||||
var dur1 = this.HistoricalData.FromTime;
|
||||
var dur = this.HistoricalData.Period.Duration.TotalSeconds * (HistPeriod * 4); //seconds of two periods
|
||||
protected override void OnInit()
|
||||
{
|
||||
base.OnInit();
|
||||
bars = new();
|
||||
var dur1 = this.HistoricalData.FromTime;
|
||||
var dur = this.HistoricalData.Period.Duration.TotalSeconds * (HistPeriod * 4); //seconds of two periods
|
||||
|
||||
this.History = this.Symbol.GetHistory(period: this.HistoricalData.Period, fromTime: HistoricalData.FromTime);
|
||||
this.History = this.Symbol.GetHistory(period: this.HistoricalData.Period, fromTime: HistoricalData.FromTime);
|
||||
|
||||
for (int i = this.History.Count - 1; i >= 0; i--) {
|
||||
for (int i = this.History.Count - 1; i >= 0; i--)
|
||||
{
|
||||
|
||||
var rec = this.History[i, SeekOriginHistory.Begin];
|
||||
var rec = this.History[i, SeekOriginHistory.Begin];
|
||||
|
||||
bars.Add(rec.TimeLeft, rec[PriceType.Open],
|
||||
rec[PriceType.High], rec[PriceType.Low],
|
||||
rec[PriceType.Close], rec[PriceType.Volume]);
|
||||
}
|
||||
bars.Add(rec.TimeLeft, rec[PriceType.Open],
|
||||
rec[PriceType.High], rec[PriceType.Low],
|
||||
rec[PriceType.Close], rec[PriceType.Volume]);
|
||||
}
|
||||
|
||||
indicator = new(source: bars.Select(DataSource), period: Period, phase: Jphase, vshort: Vshort, vlong: Vlong, useNaN: true);
|
||||
indicator.Keep = Math.Max(Period, 100);
|
||||
}
|
||||
indicator = new(source: bars.Select(DataSource), period: Period, phase: Jphase, vshort: Vshort, vlong: Vlong, useNaN: true);
|
||||
indicator.Keep = Math.Max(Period, 100);
|
||||
}
|
||||
|
||||
protected override void OnUpdate(UpdateArgs args) {
|
||||
base.OnUpdate(args);
|
||||
bars.Add(Time(), GetPrice(PriceType.Open),
|
||||
GetPrice(PriceType.High),
|
||||
GetPrice(PriceType.Low),
|
||||
GetPrice(PriceType.Close),
|
||||
GetPrice(PriceType.Volume),
|
||||
update: !(args.Reason == UpdateReason.NewBar || args.Reason == UpdateReason.HistoricalBar));
|
||||
|
||||
this.SetValue(indicator[^1].v, lineIndex: 0);
|
||||
}
|
||||
public override void OnPaintChart(PaintChartEventArgs args) {
|
||||
base.OnPaintChart(args);
|
||||
if (this.CurrentChart == null) {
|
||||
return;
|
||||
}
|
||||
protected override void OnUpdate(UpdateArgs args)
|
||||
{
|
||||
base.OnUpdate(args);
|
||||
bars.Add(Time(), GetPrice(PriceType.Open),
|
||||
GetPrice(PriceType.High),
|
||||
GetPrice(PriceType.Low),
|
||||
GetPrice(PriceType.Close),
|
||||
GetPrice(PriceType.Volume),
|
||||
update: !(args.Reason == UpdateReason.NewBar || args.Reason == UpdateReason.HistoricalBar));
|
||||
|
||||
graphics = args.Graphics;
|
||||
mainWindow = this.CurrentChart.MainWindow;
|
||||
this.SetValue(indicator[^1].v, lineIndex: 0);
|
||||
}
|
||||
public override void OnPaintChart(PaintChartEventArgs args)
|
||||
{
|
||||
base.OnPaintChart(args);
|
||||
if (this.CurrentChart == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DateTime leftTime = mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Left);
|
||||
DateTime rightTime = mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Right);
|
||||
firstOnScreenBarIndex = (int)mainWindow.CoordinatesConverter.GetBarIndex(leftTime);
|
||||
lastOnScreenBarIndex = (int)Math.Ceiling(mainWindow.CoordinatesConverter.GetBarIndex(rightTime));
|
||||
}
|
||||
graphics = args.Graphics;
|
||||
mainWindow = this.CurrentChart.MainWindow;
|
||||
|
||||
DateTime leftTime = mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Left);
|
||||
DateTime rightTime = mainWindow.CoordinatesConverter.GetTime(mainWindow.ClientRectangle.Right);
|
||||
firstOnScreenBarIndex = (int)mainWindow.CoordinatesConverter.GetBarIndex(leftTime);
|
||||
lastOnScreenBarIndex = (int)Math.Ceiling(mainWindow.CoordinatesConverter.GetBarIndex(rightTime));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,91 +5,98 @@ using System.Linq;
|
||||
using TradingPlatform.BusinessLayer;
|
||||
namespace QuanTAlib;
|
||||
|
||||
public class TrailingStop_chart : Indicator {
|
||||
#region Parameters
|
||||
public class TrailingStop_chart : Indicator
|
||||
{
|
||||
#region Parameters
|
||||
|
||||
[InputParameter("Period", 0, 1, 100, 1, 1)]
|
||||
protected int _period = 30;
|
||||
|
||||
[InputParameter("Factor", 1, 1, 100, 0.1, 1)]
|
||||
protected double _factor = 10;
|
||||
[InputParameter("Period", 0, 1, 100, 1, 1)]
|
||||
protected int _period = 30;
|
||||
|
||||
[InputParameter("Long TS", 2)]
|
||||
private bool _LongTS = true;
|
||||
[InputParameter("Factor", 1, 1, 100, 0.1, 1)]
|
||||
protected double _factor = 10;
|
||||
|
||||
[InputParameter("Short TS", 3)]
|
||||
private bool _ShortTS = true;
|
||||
[InputParameter("Long TS", 2)]
|
||||
private bool _LongTS = true;
|
||||
|
||||
#endregion Parameters
|
||||
[InputParameter("Short TS", 3)]
|
||||
private bool _ShortTS = true;
|
||||
|
||||
///////
|
||||
private HistoricalData History;
|
||||
private TBars bars;
|
||||
private ATR_Series _atr;
|
||||
private double _tslineL, _ratchetL, _tslineS, _ratchetS;
|
||||
#endregion Parameters
|
||||
|
||||
///////
|
||||
///////
|
||||
private HistoricalData History;
|
||||
private TBars bars;
|
||||
private ATR_Series _atr;
|
||||
private double _tslineL, _ratchetL, _tslineS, _ratchetS;
|
||||
|
||||
public TrailingStop_chart() {
|
||||
Name = $"ATR Trailing Stop";
|
||||
AddLineSeries(lineName: "TrailingATR Long", lineColor: Color.Yellow, lineWidth: 1,lineStyle: LineStyle.Dot);
|
||||
AddLineSeries(lineName: "Ratchet Long", lineColor: Color.Yellow, lineWidth: 3, lineStyle: LineStyle.Solid);
|
||||
///////
|
||||
|
||||
AddLineSeries(lineName: "TrailingATR Short", lineColor: Color.Yellow, lineWidth: 1, lineStyle: LineStyle.Dot);
|
||||
AddLineSeries(lineName: "Ratchet Short", lineColor: Color.Yellow, lineWidth: 3, lineStyle: LineStyle.Solid);
|
||||
|
||||
SeparateWindow = false;
|
||||
}
|
||||
public TrailingStop_chart()
|
||||
{
|
||||
Name = $"ATR Trailing Stop";
|
||||
AddLineSeries(lineName: "TrailingATR Long", lineColor: Color.Yellow, lineWidth: 1, lineStyle: LineStyle.Dot);
|
||||
AddLineSeries(lineName: "Ratchet Long", lineColor: Color.Yellow, lineWidth: 3, lineStyle: LineStyle.Solid);
|
||||
|
||||
AddLineSeries(lineName: "TrailingATR Short", lineColor: Color.Yellow, lineWidth: 1, lineStyle: LineStyle.Dot);
|
||||
AddLineSeries(lineName: "Ratchet Short", lineColor: Color.Yellow, lineWidth: 3, lineStyle: LineStyle.Solid);
|
||||
|
||||
SeparateWindow = false;
|
||||
}
|
||||
|
||||
|
||||
protected override void OnInit() {
|
||||
this.Name = $"Trailing Stop (ATR:{_period}, Mult:{_factor:f2})";
|
||||
this.bars = new();
|
||||
protected override void OnInit()
|
||||
{
|
||||
this.Name = $"Trailing Stop (ATR:{_period}, Mult:{_factor:f2})";
|
||||
this.bars = new();
|
||||
|
||||
this.History = this.Symbol.GetHistory(period: this.HistoricalData.Period, fromTime: HistoricalData.FromTime);
|
||||
for (int i = this.History.Count - 1; i >= 0; i--) {
|
||||
var rec = this.History[i, SeekOriginHistory.Begin];
|
||||
bars.Add(rec.TimeLeft, rec[PriceType.Open],
|
||||
rec[PriceType.High], rec[PriceType.Low],
|
||||
rec[PriceType.Close], rec[PriceType.Volume]);
|
||||
}
|
||||
_atr = new(source: bars, _period, useNaN: true);
|
||||
_ratchetL = Double.NegativeInfinity;
|
||||
_ratchetS = Double.PositiveInfinity;
|
||||
this.History = this.Symbol.GetHistory(period: this.HistoricalData.Period, fromTime: HistoricalData.FromTime);
|
||||
for (int i = this.History.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var rec = this.History[i, SeekOriginHistory.Begin];
|
||||
bars.Add(rec.TimeLeft, rec[PriceType.Open],
|
||||
rec[PriceType.High], rec[PriceType.Low],
|
||||
rec[PriceType.Close], rec[PriceType.Volume]);
|
||||
}
|
||||
_atr = new(source: bars, _period, useNaN: true);
|
||||
_ratchetL = Double.NegativeInfinity;
|
||||
_ratchetS = Double.PositiveInfinity;
|
||||
|
||||
this.LinesSeries[0].Visible = _LongTS;
|
||||
this.LinesSeries[1].Visible = _LongTS;
|
||||
this.LinesSeries[2].Visible = _ShortTS;
|
||||
this.LinesSeries[3].Visible = _ShortTS;
|
||||
}
|
||||
this.LinesSeries[0].Visible = _LongTS;
|
||||
this.LinesSeries[1].Visible = _LongTS;
|
||||
this.LinesSeries[2].Visible = _ShortTS;
|
||||
this.LinesSeries[3].Visible = _ShortTS;
|
||||
}
|
||||
|
||||
protected override void OnUpdate(UpdateArgs args) {
|
||||
bool update = !(args.Reason == UpdateReason.NewBar ||
|
||||
args.Reason == UpdateReason.HistoricalBar);
|
||||
this.bars.Add(this.Time(), this.GetPrice(PriceType.Open),
|
||||
this.GetPrice(PriceType.High),
|
||||
this.GetPrice(PriceType.Low),
|
||||
this.GetPrice(PriceType.Close),
|
||||
this.GetPrice(PriceType.Volume), update);
|
||||
|
||||
_tslineL = bars.High[^1].v - (_factor * _atr[^1].v);
|
||||
_ratchetL = Math.Max(_tslineL,_ratchetL);
|
||||
if (_ratchetL > bars.Low[^1].v) {
|
||||
this.LinesSeries[1].SetMarker(0, new IndicatorLineMarker(Color.Yellow, bottomIcon: IndicatorLineMarkerIconType.DownArrow));
|
||||
_ratchetL = _tslineL;
|
||||
}
|
||||
protected override void OnUpdate(UpdateArgs args)
|
||||
{
|
||||
bool update = !(args.Reason == UpdateReason.NewBar ||
|
||||
args.Reason == UpdateReason.HistoricalBar);
|
||||
this.bars.Add(this.Time(), this.GetPrice(PriceType.Open),
|
||||
this.GetPrice(PriceType.High),
|
||||
this.GetPrice(PriceType.Low),
|
||||
this.GetPrice(PriceType.Close),
|
||||
this.GetPrice(PriceType.Volume), update);
|
||||
|
||||
_tslineS = bars.High[^1].v + (_factor * _atr[^1].v);
|
||||
_ratchetS = Math.Min(_tslineS, _ratchetS);
|
||||
if (_ratchetS < bars.High[^1].v) {
|
||||
this.LinesSeries[3].SetMarker(0, new IndicatorLineMarker(Color.Yellow, upperIcon: IndicatorLineMarkerIconType.UpArrow));
|
||||
_ratchetS = _tslineS;
|
||||
}
|
||||
_tslineL = bars.High[^1].v - (_factor * _atr[^1].v);
|
||||
_ratchetL = Math.Max(_tslineL, _ratchetL);
|
||||
if (_ratchetL > bars.Low[^1].v)
|
||||
{
|
||||
this.LinesSeries[1].SetMarker(0, new IndicatorLineMarker(Color.Yellow, bottomIcon: IndicatorLineMarkerIconType.DownArrow));
|
||||
_ratchetL = _tslineL;
|
||||
}
|
||||
|
||||
this.SetValue(_tslineL, lineIndex: 0);
|
||||
this.SetValue(_ratchetL, lineIndex: 1);
|
||||
this.SetValue(_tslineS, lineIndex: 2);
|
||||
this.SetValue(_ratchetS, lineIndex: 3);
|
||||
}
|
||||
_tslineS = bars.High[^1].v + (_factor * _atr[^1].v);
|
||||
_ratchetS = Math.Min(_tslineS, _ratchetS);
|
||||
if (_ratchetS < bars.High[^1].v)
|
||||
{
|
||||
this.LinesSeries[3].SetMarker(0, new IndicatorLineMarker(Color.Yellow, upperIcon: IndicatorLineMarkerIconType.UpArrow));
|
||||
_ratchetS = _tslineS;
|
||||
}
|
||||
|
||||
this.SetValue(_tslineL, lineIndex: 0);
|
||||
this.SetValue(_ratchetL, lineIndex: 1);
|
||||
this.SetValue(_tslineS, lineIndex: 2);
|
||||
this.SetValue(_ratchetS, lineIndex: 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user