MACD-Strategie mit Neuronalem Netz
Diese Strategie kombiniert einen einfachen Vier-Gewicht-Perzeptron-Filter mit einem klassischen MACD-Crossover. Eine Position wird nur eröffnet, wenn sowohl der MACD als auch das neuronale Netz in der gleichen Richtung übereinstimmen.
Funktionsweise
- Perzeptron-Filter
Drei Perzeptronen bewerten den Preismomentum anhand der Differenzen zwischen dem aktuellen Schlusskurs und einer Reihe vergangener Eröffnungskurse. Jeder Perzeptron hat vier ganzzahlige Gewichte (X11…X34), wobei0keinen Einfluss bedeutet. Die Ausgabe des Perzeptrons ist eine gewichtete Summe der Preisdifferenzen.
Abhängig vom ParameterPassnehmen ein, zwei oder alle drei Perzeptronen an der Entscheidungsfindung teil. Der Filter definiert auch Stop-Loss- und Take-Profit-Abstände (Sl1,Tp1,Sl2,Tp2). - MACD-Bestätigung
Ein Standard-MACD (12, 26, 9) wird berechnet. Ein Kaufsignal erscheint, wenn die MACD-Linie unter null liegt und die Signallinie von unten kreuzt. Ein Verkaufssignal entsteht, wenn die Linie über null liegt und die Signallinie von oben kreuzt. - Handelsausführung
- Eine Long-Position wird eröffnet, wenn sowohl der MACD als auch der Perzeptron-Filter positiv sind.
- Eine Short-Position wird eröffnet, wenn beide negativ sind.
Die Position wird geschlossen, wenn ein Stop-Loss- oder Take-Profit-Level erreicht wird.
Parameter
| Name | Beschreibung |
|---|---|
X11…X34 |
Gewichte für Perzeptron-Eingaben. |
Tp1, Sl1 |
Take-Profit und Stop-Loss für den ersten Perzeptron. |
Tp2, Sl2 |
Take-Profit und Stop-Loss für den zweiten Perzeptron. |
P1, P2, P3 |
Verschiebungen in Balken zur Berechnung der Perzeptron-Eingaben. |
Pass |
Anzahl der zu verwendenden Perzeptronen (1-3). |
CandleType |
Kerzenserie für Berechnungen. |
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// MACD combined with simple neural network.
/// Perceptron-based filter validates MACD signals.
/// </summary>
public class NeuralNetworkMacdStrategy : Strategy
{
private readonly StrategyParam<int> _x11;
private readonly StrategyParam<int> _x12;
private readonly StrategyParam<int> _x13;
private readonly StrategyParam<int> _x14;
private readonly StrategyParam<decimal> _tp1;
private readonly StrategyParam<decimal> _sl1;
private readonly StrategyParam<int> _p1;
private readonly StrategyParam<int> _x21;
private readonly StrategyParam<int> _x22;
private readonly StrategyParam<int> _x23;
private readonly StrategyParam<int> _x24;
private readonly StrategyParam<decimal> _tp2;
private readonly StrategyParam<decimal> _sl2;
private readonly StrategyParam<int> _p2;
private readonly StrategyParam<int> _x31;
private readonly StrategyParam<int> _x32;
private readonly StrategyParam<int> _x33;
private readonly StrategyParam<int> _x34;
private readonly StrategyParam<int> _p3;
private readonly StrategyParam<int> _pass;
private readonly StrategyParam<DataType> _candleType;
private bool _macdInitialized;
private decimal _prevMacd;
private decimal _prevSignal;
private decimal[] _openHistory = Array.Empty<decimal>();
private int _historyIndex;
private bool _historyFilled;
private decimal _currentClose;
private decimal _currentStopLoss;
private decimal _currentTakeProfit;
private decimal _entryPrice;
private bool _isLong;
/// <summary>
/// Weight 1 for perceptron 1.
/// </summary>
public int X11 { get => _x11.Value; set => _x11.Value = value; }
/// <summary>
/// Weight 2 for perceptron 1.
/// </summary>
public int X12 { get => _x12.Value; set => _x12.Value = value; }
/// <summary>
/// Weight 3 for perceptron 1.
/// </summary>
public int X13 { get => _x13.Value; set => _x13.Value = value; }
/// <summary>
/// Weight 4 for perceptron 1.
/// </summary>
public int X14 { get => _x14.Value; set => _x14.Value = value; }
/// <summary>
/// Take profit for perceptron 1.
/// </summary>
public decimal Tp1 { get => _tp1.Value; set => _tp1.Value = value; }
/// <summary>
/// Stop loss for perceptron 1.
/// </summary>
public decimal Sl1 { get => _sl1.Value; set => _sl1.Value = value; }
/// <summary>
/// Shift parameter for perceptron 1.
/// </summary>
public int P1 { get => _p1.Value; set => _p1.Value = value; }
/// <summary>
/// Weight 1 for perceptron 2.
/// </summary>
public int X21 { get => _x21.Value; set => _x21.Value = value; }
/// <summary>
/// Weight 2 for perceptron 2.
/// </summary>
public int X22 { get => _x22.Value; set => _x22.Value = value; }
/// <summary>
/// Weight 3 for perceptron 2.
/// </summary>
public int X23 { get => _x23.Value; set => _x23.Value = value; }
/// <summary>
/// Weight 4 for perceptron 2.
/// </summary>
public int X24 { get => _x24.Value; set => _x24.Value = value; }
/// <summary>
/// Take profit for perceptron 2.
/// </summary>
public decimal Tp2 { get => _tp2.Value; set => _tp2.Value = value; }
/// <summary>
/// Stop loss for perceptron 2.
/// </summary>
public decimal Sl2 { get => _sl2.Value; set => _sl2.Value = value; }
/// <summary>
/// Shift parameter for perceptron 2.
/// </summary>
public int P2 { get => _p2.Value; set => _p2.Value = value; }
/// <summary>
/// Weight 1 for perceptron 3.
/// </summary>
public int X31 { get => _x31.Value; set => _x31.Value = value; }
/// <summary>
/// Weight 2 for perceptron 3.
/// </summary>
public int X32 { get => _x32.Value; set => _x32.Value = value; }
/// <summary>
/// Weight 3 for perceptron 3.
/// </summary>
public int X33 { get => _x33.Value; set => _x33.Value = value; }
/// <summary>
/// Weight 4 for perceptron 3.
/// </summary>
public int X34 { get => _x34.Value; set => _x34.Value = value; }
/// <summary>
/// Shift parameter for perceptron 3.
/// </summary>
public int P3 { get => _p3.Value; set => _p3.Value = value; }
/// <summary>
/// Number of perceptrons to use.
/// </summary>
public int Pass { get => _pass.Value; set => _pass.Value = value; }
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
/// <summary>
/// Initialize <see cref="NeuralNetworkMacdStrategy"/>.
/// </summary>
public NeuralNetworkMacdStrategy()
{
_x11 = Param(nameof(X11), 120).SetDisplay("X11", "Weight 1 for perceptron 1", "Perceptron1");
_x12 = Param(nameof(X12), 80).SetDisplay("X12", "Weight 2 for perceptron 1", "Perceptron1");
_x13 = Param(nameof(X13), 110).SetDisplay("X13", "Weight 3 for perceptron 1", "Perceptron1");
_x14 = Param(nameof(X14), 90).SetDisplay("X14", "Weight 4 for perceptron 1", "Perceptron1");
_tp1 = Param(nameof(Tp1), 100m).SetDisplay("Take Profit 1", "Take profit for perceptron 1", "Perceptron1");
_sl1 = Param(nameof(Sl1), 50m).SetDisplay("Stop Loss 1", "Stop loss for perceptron 1", "Perceptron1");
_p1 = Param(nameof(P1), 10).SetDisplay("P1", "Shift parameter for perceptron 1", "Perceptron1");
_x21 = Param(nameof(X21), 130).SetDisplay("X21", "Weight 1 for perceptron 2", "Perceptron2");
_x22 = Param(nameof(X22), 70).SetDisplay("X22", "Weight 2 for perceptron 2", "Perceptron2");
_x23 = Param(nameof(X23), 115).SetDisplay("X23", "Weight 3 for perceptron 2", "Perceptron2");
_x24 = Param(nameof(X24), 85).SetDisplay("X24", "Weight 4 for perceptron 2", "Perceptron2");
_tp2 = Param(nameof(Tp2), 100m).SetDisplay("Take Profit 2", "Take profit for perceptron 2", "Perceptron2");
_sl2 = Param(nameof(Sl2), 50m).SetDisplay("Stop Loss 2", "Stop loss for perceptron 2", "Perceptron2");
_p2 = Param(nameof(P2), 10).SetDisplay("P2", "Shift parameter for perceptron 2", "Perceptron2");
_x31 = Param(nameof(X31), 125).SetDisplay("X31", "Weight 1 for perceptron 3", "Perceptron3");
_x32 = Param(nameof(X32), 75).SetDisplay("X32", "Weight 2 for perceptron 3", "Perceptron3");
_x33 = Param(nameof(X33), 105).SetDisplay("X33", "Weight 3 for perceptron 3", "Perceptron3");
_x34 = Param(nameof(X34), 95).SetDisplay("X34", "Weight 4 for perceptron 3", "Perceptron3");
_p3 = Param(nameof(P3), 10).SetDisplay("P3", "Shift parameter for perceptron 3", "Perceptron3");
_pass = Param(nameof(Pass), 3).SetDisplay("Pass", "Number of perceptrons to use", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_macdInitialized = false;
_prevMacd = 0m;
_prevSignal = 0m;
_openHistory = Array.Empty<decimal>();
_historyIndex = 0;
_historyFilled = false;
_currentClose = 0m;
_currentStopLoss = 0m;
_currentTakeProfit = 0m;
_entryPrice = 0m;
_isLong = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var macd = new MovingAverageConvergenceDivergenceSignal(
new MovingAverageConvergenceDivergence
{
ShortMa = { Length = 12 },
LongMa = { Length = 26 },
},
new ExponentialMovingAverage { Length = 9 }
);
var maxLag = Math.Max(Math.Max(P1, P2), P3) * 4 + 1;
_openHistory = new decimal[maxLag];
_historyIndex = 0;
_historyFilled = false;
_currentClose = 0m;
_currentStopLoss = 0m;
_currentTakeProfit = 0m;
var subscription = SubscribeCandles(CandleType);
subscription.BindEx(macd, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, macd);
DrawOwnTrades(area);
}
// Protection handled manually in ProcessCandle
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue macdInd)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var macdSig = (IMovingAverageConvergenceDivergenceSignalValue)macdInd;
var macdValue = macdSig.Macd ?? 0m;
var signalValue = macdSig.Signal ?? 0m;
_currentClose = candle.ClosePrice;
var macdDir = EvaluateMacd(macdValue, signalValue);
var percDir = Supervisor();
if (macdDir > 0 && percDir > 0 && Position <= 0)
{
BuyMarket(Volume + Math.Abs(Position));
_entryPrice = candle.ClosePrice;
_isLong = true;
}
else if (macdDir < 0 && percDir < 0 && Position >= 0)
{
SellMarket(Volume + Math.Abs(Position));
_entryPrice = candle.ClosePrice;
_isLong = false;
}
if (Position > 0 && _isLong)
{
if (_currentTakeProfit > 0 && candle.ClosePrice >= _entryPrice + _currentTakeProfit)
SellMarket(Math.Abs(Position));
else if (_currentStopLoss > 0 && candle.ClosePrice <= _entryPrice - _currentStopLoss)
SellMarket(Math.Abs(Position));
}
else if (Position < 0 && !_isLong)
{
if (_currentTakeProfit > 0 && candle.ClosePrice <= _entryPrice - _currentTakeProfit)
BuyMarket(Math.Abs(Position));
else if (_currentStopLoss > 0 && candle.ClosePrice >= _entryPrice + _currentStopLoss)
BuyMarket(Math.Abs(Position));
}
AddOpen(candle.OpenPrice);
}
private int EvaluateMacd(decimal macd, decimal signal)
{
if (!_macdInitialized)
{
_prevMacd = macd;
_prevSignal = signal;
_macdInitialized = true;
return 0;
}
var result = 0;
if (macd < 0 && macd >= signal && _prevMacd <= _prevSignal)
result = 1;
else if (macd > 0 && macd <= signal && _prevMacd >= _prevSignal)
result = -1;
_prevMacd = macd;
_prevSignal = signal;
return result;
}
private void AddOpen(decimal open)
{
if (_openHistory.Length == 0)
return;
_openHistory[_historyIndex] = open;
_historyIndex++;
if (_historyIndex >= _openHistory.Length)
{
_historyIndex = 0;
_historyFilled = true;
}
}
private bool TryGetOpen(int shift, out decimal price)
{
if (_openHistory.Length == 0)
{
price = 0m;
return false;
}
if (!_historyFilled && shift >= _historyIndex)
{
price = 0m;
return false;
}
var index = _historyIndex - 1 - shift;
if (index < 0)
index += _openHistory.Length;
price = _openHistory[index];
return true;
}
private decimal Perceptron1()
{
if (!TryGetOpen(P1, out var o1) ||
!TryGetOpen(P1 * 2, out var o2) ||
!TryGetOpen(P1 * 3, out var o3) ||
!TryGetOpen(P1 * 4, out var o4))
return 0m;
var w1 = X11 - 100;
var w2 = X12 - 100;
var w3 = X13 - 100;
var w4 = X14 - 100;
var a1 = _currentClose - o1;
var a2 = o1 - o2;
var a3 = o2 - o3;
var a4 = o3 - o4;
return w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4;
}
private decimal Perceptron2()
{
if (!TryGetOpen(P2, out var o1) ||
!TryGetOpen(P2 * 2, out var o2) ||
!TryGetOpen(P2 * 3, out var o3) ||
!TryGetOpen(P2 * 4, out var o4))
return 0m;
var w1 = X21 - 100;
var w2 = X22 - 100;
var w3 = X23 - 100;
var w4 = X24 - 100;
var a1 = _currentClose - o1;
var a2 = o1 - o2;
var a3 = o2 - o3;
var a4 = o3 - o4;
return w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4;
}
private decimal Perceptron3()
{
if (!TryGetOpen(P3, out var o1) ||
!TryGetOpen(P3 * 2, out var o2) ||
!TryGetOpen(P3 * 3, out var o3) ||
!TryGetOpen(P3 * 4, out var o4))
return 0m;
var w1 = X31 - 100;
var w2 = X32 - 100;
var w3 = X33 - 100;
var w4 = X34 - 100;
var a1 = _currentClose - o1;
var a2 = o1 - o2;
var a3 = o2 - o3;
var a4 = o3 - o4;
return w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4;
}
private int Supervisor()
{
if (Pass >= 3)
{
if (Perceptron3() > 0m)
{
if (Perceptron2() > 0m)
{
_currentStopLoss = Sl2;
_currentTakeProfit = Tp2;
return 1;
}
}
else
{
if (Perceptron1() < 0m)
{
_currentStopLoss = Sl1;
_currentTakeProfit = Tp1;
return -1;
}
}
return 0;
}
if (Pass == 2)
{
if (Perceptron2() > 0m)
{
_currentStopLoss = Sl2;
_currentTakeProfit = Tp2;
return 1;
}
return 0;
}
if (Pass == 1)
{
if (Perceptron1() < 0m)
{
_currentStopLoss = Sl1;
_currentTakeProfit = Tp1;
return -1;
}
return 0;
}
return 0;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math, Array
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import MovingAverageConvergenceDivergenceSignal, MovingAverageConvergenceDivergence, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
from indicator_extensions import *
class neural_network_macd_strategy(Strategy):
def __init__(self):
super(neural_network_macd_strategy, self).__init__()
self._x11 = self.Param("X11", 120).SetDisplay("X11", "Weight 1 for perceptron 1", "Perceptron1")
self._x12 = self.Param("X12", 80).SetDisplay("X12", "Weight 2 for perceptron 1", "Perceptron1")
self._x13 = self.Param("X13", 110).SetDisplay("X13", "Weight 3 for perceptron 1", "Perceptron1")
self._x14 = self.Param("X14", 90).SetDisplay("X14", "Weight 4 for perceptron 1", "Perceptron1")
self._tp1 = self.Param("Tp1", 100.0).SetDisplay("Take Profit 1", "Take profit for perceptron 1", "Perceptron1")
self._sl1 = self.Param("Sl1", 50.0).SetDisplay("Stop Loss 1", "Stop loss for perceptron 1", "Perceptron1")
self._p1 = self.Param("P1", 10).SetDisplay("P1", "Shift for perceptron 1", "Perceptron1")
self._x21 = self.Param("X21", 130).SetDisplay("X21", "Weight 1 for perceptron 2", "Perceptron2")
self._x22 = self.Param("X22", 70).SetDisplay("X22", "Weight 2 for perceptron 2", "Perceptron2")
self._x23 = self.Param("X23", 115).SetDisplay("X23", "Weight 3 for perceptron 2", "Perceptron2")
self._x24 = self.Param("X24", 85).SetDisplay("X24", "Weight 4 for perceptron 2", "Perceptron2")
self._tp2 = self.Param("Tp2", 100.0).SetDisplay("Take Profit 2", "Take profit for perceptron 2", "Perceptron2")
self._sl2 = self.Param("Sl2", 50.0).SetDisplay("Stop Loss 2", "Stop loss for perceptron 2", "Perceptron2")
self._p2 = self.Param("P2", 10).SetDisplay("P2", "Shift for perceptron 2", "Perceptron2")
self._x31 = self.Param("X31", 125).SetDisplay("X31", "Weight 1 for perceptron 3", "Perceptron3")
self._x32 = self.Param("X32", 75).SetDisplay("X32", "Weight 2 for perceptron 3", "Perceptron3")
self._x33 = self.Param("X33", 105).SetDisplay("X33", "Weight 3 for perceptron 3", "Perceptron3")
self._x34 = self.Param("X34", 95).SetDisplay("X34", "Weight 4 for perceptron 3", "Perceptron3")
self._p3 = self.Param("P3", 10).SetDisplay("P3", "Shift for perceptron 3", "Perceptron3")
self._pass_count = self.Param("Pass", 3).SetDisplay("Pass", "Number of perceptrons to use", "General")
self._candle_type = self.Param("CandleType", tf(15)).SetDisplay("Candle Type", "Type of candles", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(neural_network_macd_strategy, self).OnReseted()
self._macd_initialized = False
self._prev_macd = 0
self._prev_signal = 0
self._open_history = []
self._current_close = 0
self._current_sl = 0
self._current_tp = 0
self._entry_price = 0
self._is_long = False
def OnStarted2(self, time):
super(neural_network_macd_strategy, self).OnStarted2(time)
self._macd_initialized = False
self._prev_macd = 0
self._prev_signal = 0
max_lag = max(self._p1.Value, self._p2.Value, self._p3.Value) * 4 + 1
self._open_history = [0] * max_lag
self._hist_index = 0
self._hist_filled = False
self._current_close = 0
self._current_sl = 0
self._current_tp = 0
self._entry_price = 0
self._is_long = False
macd = MovingAverageConvergenceDivergenceSignal()
macd.Macd.ShortMa.Length = 12
macd.Macd.LongMa.Length = 26
macd.SignalMa.Length = 9
sub = self.SubscribeCandles(self.CandleType)
sub.BindEx(macd, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, macd)
self.DrawOwnTrades(area)
def _add_open(self, open_price):
if len(self._open_history) == 0:
return
self._open_history[self._hist_index] = open_price
self._hist_index += 1
if self._hist_index >= len(self._open_history):
self._hist_index = 0
self._hist_filled = True
def _try_get_open(self, shift):
if len(self._open_history) == 0:
return None
if not self._hist_filled and shift >= self._hist_index:
return None
index = self._hist_index - 1 - shift
if index < 0:
index += len(self._open_history)
return self._open_history[index]
def _perceptron(self, p, x1, x2, x3, x4):
o1 = self._try_get_open(p)
o2 = self._try_get_open(p * 2)
o3 = self._try_get_open(p * 3)
o4 = self._try_get_open(p * 4)
if o1 is None or o2 is None or o3 is None or o4 is None:
return 0
w1 = x1 - 100
w2 = x2 - 100
w3 = x3 - 100
w4 = x4 - 100
return w1 * (self._current_close - o1) + w2 * (o1 - o2) + w3 * (o2 - o3) + w4 * (o3 - o4)
def _supervisor(self):
pass_val = self._pass_count.Value
if pass_val >= 3:
if self._perceptron(self._p3.Value, self._x31.Value, self._x32.Value, self._x33.Value, self._x34.Value) > 0:
if self._perceptron(self._p2.Value, self._x21.Value, self._x22.Value, self._x23.Value, self._x24.Value) > 0:
self._current_sl = self._sl2.Value
self._current_tp = self._tp2.Value
return 1
else:
if self._perceptron(self._p1.Value, self._x11.Value, self._x12.Value, self._x13.Value, self._x14.Value) < 0:
self._current_sl = self._sl1.Value
self._current_tp = self._tp1.Value
return -1
return 0
if pass_val == 2:
if self._perceptron(self._p2.Value, self._x21.Value, self._x22.Value, self._x23.Value, self._x24.Value) > 0:
self._current_sl = self._sl2.Value
self._current_tp = self._tp2.Value
return 1
return 0
if pass_val == 1:
if self._perceptron(self._p1.Value, self._x11.Value, self._x12.Value, self._x13.Value, self._x14.Value) < 0:
self._current_sl = self._sl1.Value
self._current_tp = self._tp1.Value
return -1
return 0
return 0
def _evaluate_macd(self, macd_val, signal_val):
if not self._macd_initialized:
self._prev_macd = macd_val
self._prev_signal = signal_val
self._macd_initialized = True
return 0
result = 0
if macd_val < 0 and macd_val >= signal_val and self._prev_macd <= self._prev_signal:
result = 1
elif macd_val > 0 and macd_val <= signal_val and self._prev_macd >= self._prev_signal:
result = -1
self._prev_macd = macd_val
self._prev_signal = signal_val
return result
def OnProcess(self, candle, macd_ind):
if candle.State != CandleStates.Finished:
return
macd_val = macd_ind.Macd if macd_ind.Macd is not None else 0
signal_val = macd_ind.Signal if macd_ind.Signal is not None else 0
self._current_close = candle.ClosePrice
macd_dir = self._evaluate_macd(float(macd_val), float(signal_val))
perc_dir = self._supervisor()
if macd_dir > 0 and perc_dir > 0 and self.Position <= 0:
self.BuyMarket(self.Volume + Math.Abs(self.Position))
self._entry_price = candle.ClosePrice
self._is_long = True
elif macd_dir < 0 and perc_dir < 0 and self.Position >= 0:
self.SellMarket(self.Volume + Math.Abs(self.Position))
self._entry_price = candle.ClosePrice
self._is_long = False
if self.Position > 0 and self._is_long:
if self._current_tp > 0 and candle.ClosePrice >= self._entry_price + self._current_tp:
self.SellMarket(Math.Abs(self.Position))
elif self._current_sl > 0 and candle.ClosePrice <= self._entry_price - self._current_sl:
self.SellMarket(Math.Abs(self.Position))
elif self.Position < 0 and not self._is_long:
if self._current_tp > 0 and candle.ClosePrice <= self._entry_price - self._current_tp:
self.BuyMarket(Math.Abs(self.Position))
elif self._current_sl > 0 and candle.ClosePrice >= self._entry_price + self._current_sl:
self.BuyMarket(Math.Abs(self.Position))
self._add_open(candle.OpenPrice)
def CreateClone(self):
return neural_network_macd_strategy()