using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using System.Drawing;
using Matriks.Data.Identifiers;
using Matriks.Data.Symbol;
using Matriks.Engines;
using Matriks.Indicators;
using Matriks.Symbols;
using Matriks.AlgoTrader;
using Matriks.Trader.Core;
using Matriks.Trader.Core.Fields;
using Matriks.Trader.Core.TraderModels;
using Matriks.Lean.Algotrader.AlgoBase;
using Matriks.Lean.Algotrader.Models;
using Matriks.Lean.Algotrader.Trading;
namespace Matriks.Lean.Algotrader
{
[IndicatorInformationAttribute("WaveTrend", IndicatorDrawingArea.NewWindow)]
[IndicatorLineInformationAttribute(new[]
{
"WT1",
"WT2",
"Zero Line",
"OB Level 1",
"OS Level 1",
"OB Level 2",
"OS Level 2"
})]
public class WaveTrend : MatriksIndicator
{
[DefaultValue(10)]
public int ChannelLength { get; set; }
[DefaultValue(21)]
public int AverageLength { get; set; }
[DefaultValue(60)]
public decimal OverBoughtLevel1 { get; set; }
[DefaultValue(53)]
public decimal OverBoughtLevel2 { get; set; }
[DefaultValue(-60)]
public decimal OverSoldLevel1 { get; set; }
[DefaultValue(-53)]
public decimal OverSoldLevel2 { get; set; }
public sealed override void OnInit()
{
for (int i = 0; i < 7; i++)
{
SetLine(i, 0);
}
}
public override void OnDataUpdate(int currentBar, decimal inputValue, DateTime barDateTime)
{
if (currentBar < Math.Max(ChannelLength, AverageLength))
{
for (int i = 0; i < 7; i++)
{
SetLine(i, currentBar, 0);
}
return;
}
decimal ap = GetHL3(currentBar);
decimal esa = GetEMA(ap, ChannelLength, currentBar);
decimal d = GetEMA(Math.Abs(ap - esa), ChannelLength, currentBar);
decimal ci = (ap - esa) / (0.015m * d);
decimal tci = GetEMA(ci, AverageLength, currentBar);
decimal wt1 = tci;
decimal wt2 = GetSMA(wt1, 4, currentBar);
SetLine(0, currentBar, wt1, Color.Green); // WT1
SetLine(1, currentBar, wt2, Color.Red); // WT2
SetLine(2, currentBar, 0, Color.Gray); // Zero Line
SetLine(3, currentBar, OverBoughtLevel1, Color.Red); // OB Level 1
SetLine(4, currentBar, OverSoldLevel1, Color.Green); // OS Level 1
SetLine(5, currentBar, OverBoughtLevel2, Color.Red); // OB Level 2
SetLine(6, currentBar, OverSoldLevel2, Color.Green); // OS Level 2
// Plot crosses
if (Cross(wt1, wt2, currentBar))
{
SetLine(1, currentBar, wt2, Color.Black, LineStyle.Circles, 3);
SetLine(1, currentBar, wt2, (wt2 - wt1 > 0 ? Color.Red : Color.Lime), LineStyle.Circles, 2);
}
// Bar coloring
if (Cross(wt1, wt2, currentBar))
{
BarColor(currentBar, wt2 - wt1 > 0 ? Color.Aqua : Color.Yellow);
}
}
private decimal GetHL3(int currentBar)
{
return (Instrument.SymbolBarData.High[currentBar] + Instrument.SymbolBarData.Low[currentBar] + Instrument.SymbolBarData.Close[currentBar]) / 3;
}
private decimal GetEMA(decimal value, int period, int currentBar)
{
decimal k = 2m / (period + 1);
decimal ema = value;
for (int i = 1; i <= period && currentBar - i >= 0; i++)
{
ema = (value * k) + (ema * (1 - k));
}
return ema;
}
private decimal GetSMA(decimal value, int period, int currentBar)
{
decimal sum = 0;
for (int i = 0; i < period && currentBar - i >= 0; i++)
{
sum += value;
}
return sum / period;
}
private bool Cross(decimal series1, decimal series2, int currentBar)
{
return (series1 > series2 && GetPreviousValue(series1, currentBar) <= GetPreviousValue(series2, currentBar)) ||
(series1 < series2 && GetPreviousValue(series1, currentBar) >= GetPreviousValue(series2, currentBar));
}
private decimal GetPreviousValue(decimal value, int currentBar)
{
return currentBar > 0 ? value : 0;
}
private void BarColor(int currentBar, Color color)
{
// Implement bar coloring logic here
}
private void SetLine(int index, int currentBar, decimal value, Color color = default, LineStyle style = default, int lineWidth = 1)
{
// Implement line setting logic here
// This is a placeholder implementation. You need to replace it with actual logic to set the line properties.
Console.WriteLine($"Setting line {index} at bar {currentBar} with value {value}, color {color}, style {style}, lineWidth {lineWidth}");
}
}
public enum LineStyle
{
Solid,
Dotted,
Dashed,
Circles
}
}