Стратегия MBKAsctrend3
Стратегия MBKAsctrend3 использует три осциллятора Williams %R с различными периодами. Их взвешенное сочетание определяет рыночный тренд. Длинная позиция открывается, когда комбинированное значение выше уровня 67+Swing и долгосрочный осциллятор выше 50-AverageSwing. Короткая позиция открывается при обратном условии. Позиции защищены настраиваемыми стоп-лоссом и тейк-профитом в пунктах.
Подробности
- Условия входа:
- Покупка: взвешенный WPR > 67+Swing и долгосрочный WPR > 50-AverageSwing.
- Продажа: взвешенный WPR < 33-Swing и долгосрочный WPR < 50+AverageSwing.
- Длинные/короткие: обе стороны.
- Условия выхода: обратный сигнал или защитные уровни.
- Стопы: абсолютные стоп-лосс и тейк-профит.
- Фильтры: отсутствуют.
Параметры
WprLength1,WprLength2,WprLength3– периоды индикаторов Williams %R.Swing– смещение верхней и нижней границ.AverageSwing– дополнительное смещение для долгосрочного осциллятора.Weight1,Weight2,Weight3– веса индикаторов.StopLoss,TakeProfit– уровни защиты в пунктах.CandleType– таймфрейм свечей, по умолчанию 4 часа.
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>
/// MBKAsctrend3 based strategy.
/// </summary>
public class Mbkasctrend3Strategy : Strategy
{
private readonly StrategyParam<int> _wpr1;
private readonly StrategyParam<int> _wpr2;
private readonly StrategyParam<int> _wpr3;
private readonly StrategyParam<int> _swing;
private readonly StrategyParam<int> _avgSwing;
private readonly StrategyParam<decimal> _w1;
private readonly StrategyParam<decimal> _w2;
private readonly StrategyParam<decimal> _w3;
private readonly StrategyParam<decimal> _sl;
private readonly StrategyParam<decimal> _tp;
private readonly StrategyParam<DataType> _candle;
private int _prevTrend;
public int WprLength1 { get => _wpr1.Value; set => _wpr1.Value = value; }
public int WprLength2 { get => _wpr2.Value; set => _wpr2.Value = value; }
public int WprLength3 { get => _wpr3.Value; set => _wpr3.Value = value; }
public int Swing { get => _swing.Value; set => _swing.Value = value; }
public int AverageSwing { get => _avgSwing.Value; set => _avgSwing.Value = value; }
public decimal Weight1 { get => _w1.Value; set => _w1.Value = value; }
public decimal Weight2 { get => _w2.Value; set => _w2.Value = value; }
public decimal Weight3 { get => _w3.Value; set => _w3.Value = value; }
public decimal StopLoss { get => _sl.Value; set => _sl.Value = value; }
public decimal TakeProfit { get => _tp.Value; set => _tp.Value = value; }
public DataType CandleType { get => _candle.Value; set => _candle.Value = value; }
public Mbkasctrend3Strategy()
{
_wpr1 = Param(nameof(WprLength1),9).SetGreaterThanZero().SetDisplay("WPR Length 1","Period for the first WPR","Indicator");
_wpr2 = Param(nameof(WprLength2),33).SetGreaterThanZero().SetDisplay("WPR Length 2","Period for the second WPR","Indicator");
_wpr3 = Param(nameof(WprLength3),77).SetGreaterThanZero().SetDisplay("WPR Length 3","Period for the third WPR","Indicator");
_swing = Param(nameof(Swing),3).SetDisplay("Swing","Swing adjustment","Indicator");
_avgSwing = Param(nameof(AverageSwing),-5).SetDisplay("Average Swing","Average swing adjustment","Indicator");
_w1 = Param(nameof(Weight1),1m).SetDisplay("Weight 1","Weight for WPR1","Indicator");
_w2 = Param(nameof(Weight2),3m).SetDisplay("Weight 2","Weight for WPR2","Indicator");
_w3 = Param(nameof(Weight3),1m).SetDisplay("Weight 3","Weight for WPR3","Indicator");
_sl = Param(nameof(StopLoss),1000m).SetGreaterThanZero().SetDisplay("Stop Loss","Stop loss in points","Protection");
_tp = Param(nameof(TakeProfit),2000m).SetGreaterThanZero().SetDisplay("Take Profit","Take profit in points","Protection");
_candle = Param(nameof(CandleType),TimeSpan.FromHours(4).TimeFrame()).SetDisplay("Candle Type","Time frame for calculations","General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
protected override void OnReseted()
{
base.OnReseted();
_prevTrend = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var w1 = new WilliamsR { Length = WprLength1 };
var w2 = new WilliamsR { Length = WprLength2 };
var w3 = new WilliamsR { Length = WprLength3 };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(w1, w2, w3, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal v1, decimal v2, decimal v3)
{
if (candle.State != CandleStates.Finished || !IsFormedAndOnlineAndAllowTrading())
return;
var r1 = 100m + v1;
var r2 = 100m + v2;
var r3 = 100m + v3;
var sum = Weight1 + Weight2 + Weight3;
var avg = (Weight1 * r1 + Weight2 * r2 + Weight3 * r3) / sum;
var upLevel = 67m + Swing;
var dnLevel = 33m - Swing;
var up1 = 50m - AverageSwing;
var dn1 = 50m + AverageSwing;
var trend = 0;
if (avg > upLevel && r3 >= up1) trend = 1;
else if (avg < dnLevel && r3 <= dn1) trend = -1;
if (_prevTrend <= 0 && trend > 0 && Position <= 0)
BuyMarket();
else if (_prevTrend >= 0 && trend < 0 && Position >= 0)
SellMarket();
if (trend != 0)
_prevTrend = trend;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import WilliamsR
from StockSharp.Algo.Strategies import Strategy
class mbkasctrend3_strategy(Strategy):
def __init__(self):
super(mbkasctrend3_strategy, self).__init__()
self._wpr1 = self.Param("WprLength1", 9) \
.SetDisplay("WPR Length 1", "Period for the first WPR", "Indicator")
self._wpr2 = self.Param("WprLength2", 33) \
.SetDisplay("WPR Length 2", "Period for the second WPR", "Indicator")
self._wpr3 = self.Param("WprLength3", 77) \
.SetDisplay("WPR Length 3", "Period for the third WPR", "Indicator")
self._swing = self.Param("Swing", 3) \
.SetDisplay("Swing", "Swing adjustment", "Indicator")
self._avg_swing = self.Param("AverageSwing", -5) \
.SetDisplay("Average Swing", "Average swing adjustment", "Indicator")
self._w1 = self.Param("Weight1", 1.0) \
.SetDisplay("Weight 1", "Weight for WPR1", "Indicator")
self._w2 = self.Param("Weight2", 3.0) \
.SetDisplay("Weight 2", "Weight for WPR2", "Indicator")
self._w3 = self.Param("Weight3", 1.0) \
.SetDisplay("Weight 3", "Weight for WPR3", "Indicator")
self._sl = self.Param("StopLoss", 1000.0) \
.SetDisplay("Stop Loss", "Stop loss in points", "Protection")
self._tp = self.Param("TakeProfit", 2000.0) \
.SetDisplay("Take Profit", "Take profit in points", "Protection")
self._candle = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Time frame for calculations", "General")
self._prev_trend = 0
@property
def wpr_length1(self):
return self._wpr1.Value
@property
def wpr_length2(self):
return self._wpr2.Value
@property
def wpr_length3(self):
return self._wpr3.Value
@property
def swing(self):
return self._swing.Value
@property
def average_swing(self):
return self._avg_swing.Value
@property
def weight1(self):
return self._w1.Value
@property
def weight2(self):
return self._w2.Value
@property
def weight3(self):
return self._w3.Value
@property
def candle_type(self):
return self._candle.Value
def OnReseted(self):
super(mbkasctrend3_strategy, self).OnReseted()
self._prev_trend = 0
def OnStarted2(self, time):
super(mbkasctrend3_strategy, self).OnStarted2(time)
w1 = WilliamsR()
w1.Length = self.wpr_length1
w2 = WilliamsR()
w2.Length = self.wpr_length2
w3 = WilliamsR()
w3.Length = self.wpr_length3
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(w1, w2, w3, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def process_candle(self, candle, v1, v2, v3):
if candle.State != CandleStates.Finished or not self.IsFormedAndOnlineAndAllowTrading():
return
r1 = 100.0 + float(v1)
r2 = 100.0 + float(v2)
r3 = 100.0 + float(v3)
wt1 = float(self.weight1)
wt2 = float(self.weight2)
wt3 = float(self.weight3)
total = wt1 + wt2 + wt3
avg = (wt1 * r1 + wt2 * r2 + wt3 * r3) / total
up_level = 67.0 + float(self.swing)
dn_level = 33.0 - float(self.swing)
up1 = 50.0 - float(self.average_swing)
dn1 = 50.0 + float(self.average_swing)
trend = 0
if avg > up_level and r3 >= up1:
trend = 1
elif avg < dn_level and r3 <= dn1:
trend = -1
if self._prev_trend <= 0 and trend > 0 and self.Position <= 0:
self.BuyMarket()
elif self._prev_trend >= 0 and trend < 0 and self.Position >= 0:
self.SellMarket()
if trend != 0:
self._prev_trend = trend
def CreateClone(self):
return mbkasctrend3_strategy()