Artificial Intelligence Perceptron Strategy
The Artificial Intelligence strategy uses a simple perceptron to combine multiple Accelerator Oscillator (AC) readings at different time shifts. The weighted sum of the current AC value and three lagged values (7, 14, 21 bars back) determines the direction of the trade. When the perceptron output is positive the strategy opens or maintains a long position; when negative it opens or maintains a short position.
After an entry the strategy protects the trade with a stop-loss expressed in points. As price moves in the profitable direction the stop level trails behind the price. If the perceptron output flips sign while the position is profitable the strategy reverses, closing the current position and entering the opposite one.
Testing shows this approach can react quickly to momentum changes while keeping risk under control. It works on any instrument that provides candle data and does not rely on specific market regimes.
Details
- Entry Criteria
- Long: Perceptron output > 0 and no existing long position.
- Short: Perceptron output < 0 and no existing short position.
- Exit / Reverse
- Trailing stop triggered.
- Perceptron output changes sign; strategy reverses position.
- Stops: Yes, trailing stop based on
StopLossparameter. - Default Values
X1 = 135X2 = 127X3 = 16X4 = 93StopLoss = 85
- Filters
- Category: Momentum
- Direction: Both
- Indicators: Accelerator Oscillator
- Stops: Yes
- Complexity: Medium
- Timeframe: Short-term
- Neural networks: Perceptron
- Divergence: No
- Risk level: Medium
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Artificial Intelligence strategy based on a simple perceptron over Accelerator Oscillator values.
/// </summary>
public class ArtificialIntelligenceStrategy : Strategy
{
private readonly StrategyParam<int> _x1;
private readonly StrategyParam<int> _x2;
private readonly StrategyParam<int> _x3;
private readonly StrategyParam<int> _x4;
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<DataType> _candleType;
private readonly decimal[] _aoBuffer = new decimal[22];
private int _aoCount;
private decimal _entryPrice;
private decimal _stopPrice;
private decimal _prevAo;
public int X1 { get => _x1.Value; set => _x1.Value = value; }
public int X2 { get => _x2.Value; set => _x2.Value = value; }
public int X3 { get => _x3.Value; set => _x3.Value = value; }
public int X4 { get => _x4.Value; set => _x4.Value = value; }
public decimal StopLoss { get => _stopLoss.Value; set => _stopLoss.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ArtificialIntelligenceStrategy()
{
_x1 = Param(nameof(X1), 135)
.SetDisplay("X1", "Perceptron weight 1", "Perceptron")
.SetOptimize(0, 200, 5);
_x2 = Param(nameof(X2), 127)
.SetDisplay("X2", "Perceptron weight 2", "Perceptron")
.SetOptimize(0, 200, 5);
_x3 = Param(nameof(X3), 16)
.SetDisplay("X3", "Perceptron weight 3", "Perceptron")
.SetOptimize(0, 200, 5);
_x4 = Param(nameof(X4), 93)
.SetDisplay("X4", "Perceptron weight 4", "Perceptron")
.SetOptimize(0, 200, 5);
_stopLoss = Param(nameof(StopLoss), 85m)
.SetDisplay("Stop Loss", "Stop loss distance in points", "Risk")
.SetOptimize(10m, 200m, 5m);
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
Array.Clear(_aoBuffer);
_aoCount = 0;
_entryPrice = 0m;
_stopPrice = 0m;
_prevAo = 0m;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ao = new AwesomeOscillator();
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ao, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ao);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal aoValue)
{
if (candle.State != CandleStates.Finished)
return;
// Use AO values directly as the perceptron inputs
for (var i = _aoBuffer.Length - 1; i > 0; i--)
_aoBuffer[i] = _aoBuffer[i - 1];
_aoBuffer[0] = aoValue;
if (_aoCount < _aoBuffer.Length)
_aoCount++;
if (_aoCount < _aoBuffer.Length)
return;
var step = Security?.PriceStep ?? 0.01m;
var w1 = X1 - 100m;
var w2 = X2 - 100m;
var w3 = X3 - 100m;
var w4 = X4 - 100m;
var perceptron = w1 * _aoBuffer[0] + w2 * _aoBuffer[7] + w3 * _aoBuffer[14] + w4 * _aoBuffer[21];
if (Position == 0)
{
if (perceptron > 0)
{
_entryPrice = candle.ClosePrice;
_stopPrice = _entryPrice - StopLoss * step;
BuyMarket();
}
else
{
_entryPrice = candle.ClosePrice;
_stopPrice = _entryPrice + StopLoss * step;
SellMarket();
}
return;
}
if (Position > 0)
{
_stopPrice = Math.Max(_stopPrice, candle.ClosePrice - StopLoss * step);
if (candle.ClosePrice <= _stopPrice || perceptron < 0)
{
SellMarket();
if (perceptron < 0)
{
_entryPrice = candle.ClosePrice;
_stopPrice = _entryPrice + StopLoss * step;
}
}
}
else if (Position < 0)
{
_stopPrice = Math.Min(_stopPrice, candle.ClosePrice + StopLoss * step);
if (candle.ClosePrice >= _stopPrice || perceptron > 0)
{
BuyMarket();
if (perceptron > 0)
{
_entryPrice = candle.ClosePrice;
_stopPrice = _entryPrice - StopLoss * step;
}
}
}
_prevAo = aoValue;
}
}
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
from StockSharp.Messages import CandleStates, DataType
from StockSharp.Algo.Indicators import AwesomeOscillator
from StockSharp.Algo.Strategies import Strategy
class artificial_intelligence_strategy(Strategy):
"""
Artificial Intelligence strategy based on a simple perceptron over Accelerator Oscillator values.
"""
def __init__(self):
super(artificial_intelligence_strategy, self).__init__()
self._x1 = self.Param("X1", 135) \
.SetDisplay("X1", "Perceptron weight 1", "Perceptron") \
.SetOptimize(0, 200, 5)
self._x2 = self.Param("X2", 127) \
.SetDisplay("X2", "Perceptron weight 2", "Perceptron") \
.SetOptimize(0, 200, 5)
self._x3 = self.Param("X3", 16) \
.SetDisplay("X3", "Perceptron weight 3", "Perceptron") \
.SetOptimize(0, 200, 5)
self._x4 = self.Param("X4", 93) \
.SetDisplay("X4", "Perceptron weight 4", "Perceptron") \
.SetOptimize(0, 200, 5)
self._stop_loss = self.Param("StopLoss", 85.0) \
.SetDisplay("Stop Loss", "Stop loss distance in points", "Risk") \
.SetOptimize(10.0, 200.0, 5.0)
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(240))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._ao_buffer = [0.0] * 22
self._ao_count = 0
self._entry_price = 0.0
self._stop_price = 0.0
@property
def X1(self): return self._x1.Value
@X1.setter
def X1(self, v): self._x1.Value = v
@property
def X2(self): return self._x2.Value
@X2.setter
def X2(self, v): self._x2.Value = v
@property
def X3(self): return self._x3.Value
@X3.setter
def X3(self, v): self._x3.Value = v
@property
def X4(self): return self._x4.Value
@X4.setter
def X4(self, v): self._x4.Value = v
@property
def StopLoss(self): return self._stop_loss.Value
@StopLoss.setter
def StopLoss(self, v): self._stop_loss.Value = v
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, v): self._candle_type.Value = v
def OnReseted(self):
super(artificial_intelligence_strategy, self).OnReseted()
self._ao_buffer = [0.0] * 22
self._ao_count = 0
self._entry_price = 0.0
self._stop_price = 0.0
def OnStarted2(self, time):
super(artificial_intelligence_strategy, self).OnStarted2(time)
ao = AwesomeOscillator()
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ao, self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ao)
self.DrawOwnTrades(area)
def ProcessCandle(self, candle, ao_value):
if candle.State != CandleStates.Finished:
return
# Shift buffer
for i in range(len(self._ao_buffer) - 1, 0, -1):
self._ao_buffer[i] = self._ao_buffer[i - 1]
self._ao_buffer[0] = float(ao_value)
if self._ao_count < len(self._ao_buffer):
self._ao_count += 1
if self._ao_count < len(self._ao_buffer):
return
step = float(self.Security.PriceStep or 0.01)
close = float(candle.ClosePrice)
w1 = self.X1 - 100.0
w2 = self.X2 - 100.0
w3 = self.X3 - 100.0
w4 = self.X4 - 100.0
perceptron = w1 * self._ao_buffer[0] + w2 * self._ao_buffer[7] + w3 * self._ao_buffer[14] + w4 * self._ao_buffer[21]
if self.Position == 0:
if perceptron > 0:
self._entry_price = close
self._stop_price = self._entry_price - self.StopLoss * step
self.BuyMarket()
else:
self._entry_price = close
self._stop_price = self._entry_price + self.StopLoss * step
self.SellMarket()
return
if self.Position > 0:
self._stop_price = max(self._stop_price, close - self.StopLoss * step)
if close <= self._stop_price or perceptron < 0:
self.SellMarket()
if perceptron < 0:
self._entry_price = close
self._stop_price = self._entry_price + self.StopLoss * step
elif self.Position < 0:
self._stop_price = min(self._stop_price, close + self.StopLoss * step)
if close >= self._stop_price or perceptron > 0:
self.BuyMarket()
if perceptron > 0:
self._entry_price = close
self._stop_price = self._entry_price - self.StopLoss * step
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return artificial_intelligence_strategy()