Bollinger Bands ロング戦略
この戦略は、価格がBollinger Bands下限を下回って終値が付き、RSIが売られすぎの状態にある時に買いを入れます。価格が中央バンドに戻ったらロングポジションを決済します。
詳細
- エントリー条件:
- 価格がBollinger Bands下限を下回って終値が付く。
- RSIが売られすぎのレベルを下回る。
- ロング/ショート: ロングのみ。
- エグジット条件:
- 価格がBollinger Bands中央バンドで、またはそれを上回って終値が付く。
- ストップ: いいえ。
- デフォルト値:
BbLength= 10BbDeviation= 2RsiLength= 14RsiOversold= 30
- フィルター:
- カテゴリ: 平均回帰
- 方向: ロング
- インジケーター: Bollinger Bands, RSI
- ストップ: いいえ
- 複雑さ: 低
- 時間軸: 任意
- 季節性: いいえ
- ニューラルネットワーク: いいえ
- ダイバージェンス: いいえ
- リスクレベル: 中
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>
/// Bollinger Bands Long strategy.
/// Long only: buys when the close is below the lower Bollinger band and RSI is below RsiOversold, and closes the long once the close
/// is at or above the middle band.
/// </summary>
public class BollingerBandsLongStrategy : Strategy
{
private readonly StrategyParam<int> _bbLength;
private readonly StrategyParam<decimal> _bbDeviation;
private readonly StrategyParam<int> _rsiLength;
private readonly StrategyParam<decimal> _rsiOversold;
private readonly StrategyParam<DataType> _candleType;
/// <summary>
/// Bollinger period.
/// </summary>
public int BbLength
{
get => _bbLength.Value;
set => _bbLength.Value = value;
}
/// <summary>
/// Bollinger standard deviation multiplier.
/// </summary>
public decimal BbDeviation
{
get => _bbDeviation.Value;
set => _bbDeviation.Value = value;
}
/// <summary>
/// RSI period.
/// </summary>
public int RsiLength
{
get => _rsiLength.Value;
set => _rsiLength.Value = value;
}
/// <summary>
/// RSI oversold level.
/// </summary>
public decimal RsiOversold
{
get => _rsiOversold.Value;
set => _rsiOversold.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public BollingerBandsLongStrategy()
{
_bbLength = Param(nameof(BbLength), 10)
.SetGreaterThanZero()
.SetDisplay("BB Length", "Bollinger period", "Bollinger");
_bbDeviation = Param(nameof(BbDeviation), 2m)
.SetGreaterThanZero()
.SetDisplay("BB Deviation", "Bollinger standard deviation multiplier", "Bollinger");
_rsiLength = Param(nameof(RsiLength), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Length", "RSI period", "RSI");
_rsiOversold = Param(nameof(RsiOversold), 30m)
.SetDisplay("RSI Oversold", "RSI oversold level", "RSI");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var bollinger = new BollingerBands { Length = BbLength, Width = BbDeviation };
var rsi = new RelativeStrengthIndex { Length = RsiLength };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(bollinger, rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, bollinger);
DrawOwnTrades(area);
var oscillators = CreateChartArea();
if (oscillators != null)
{
DrawIndicator(oscillators, rsi);
}
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue bollingerValue, IIndicatorValue rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!bollingerValue.IsFormed || !rsiValue.IsFormed)
return;
var bands = (BollingerBandsValue)bollingerValue;
if (bands.LowBand is not decimal lower || bands.MovingAverage is not decimal middle)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
var rsi = rsiValue.GetValue<decimal>();
if (Position == 0 && close < lower && rsi < RsiOversold)
BuyMarket(Volume);
else if (Position > 0 && close >= middle)
SellMarket(Position);
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import BollingerBands, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class bollinger_bands_long_strategy(Strategy):
"""
Bollinger Bands Long strategy.
Long only: buys when the close is below the lower Bollinger band and RSI is below RsiOversold, and closes the long once the close
is at or above the middle band.
"""
def __init__(self):
super(bollinger_bands_long_strategy, self).__init__()
self._bb_length = self.Param("BbLength", 10).SetGreaterThanZero().SetDisplay("BB Length", "Bollinger period", "Bollinger")
self._bb_deviation = self.Param("BbDeviation", 2.0).SetGreaterThanZero().SetDisplay("BB Deviation", "Bollinger standard deviation multiplier", "Bollinger")
self._rsi_length = self.Param("RsiLength", 14).SetGreaterThanZero().SetDisplay("RSI Length", "RSI period", "RSI")
self._rsi_oversold = self.Param("RsiOversold", 30.0).SetDisplay("RSI Oversold", "RSI oversold level", "RSI")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))).SetDisplay("Candle Type", "Type of candles to use", "General")
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(bollinger_bands_long_strategy, self).OnStarted2(time)
bollinger = BollingerBands()
bollinger.Length = self._bb_length.Value
bollinger.Width = Decimal(self._bb_deviation.Value)
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_length.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(bollinger, rsi, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, bollinger)
self.DrawOwnTrades(area)
oscillators = self.CreateChartArea()
if oscillators is not None:
self.DrawIndicator(oscillators, rsi)
def _process_candle(self, candle, bollinger_value, rsi_value):
if candle.State != CandleStates.Finished:
return
if not bollinger_value.IsFormed or not rsi_value.IsFormed:
return
lower = bollinger_value.LowBand
middle = bollinger_value.MovingAverage
if lower is None or middle is None:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
close = candle.ClosePrice
rsi = rsi_value.GetValue[Decimal](None)
if self.Position == 0 and close < lower and rsi < Decimal(self._rsi_oversold.Value):
self.BuyMarket(self.Volume)
elif self.Position > 0 and close >= middle:
self.SellMarket(self.Position)
def CreateClone(self):
return bollinger_bands_long_strategy()