強気リバーサル戦略
古典的な強気リバーサルのローソク足パターンを検索する戦略です。これらのパターンのいずれかが50期間の単純移動平均線より下に現れたとき、戦略はロングポジションを開きます。オプションのトレーリングストップが未決利益を保護します。
パターン
- Abandoned Baby – 2本の連続した弱気ローソク足に続き、2本目がギャップダウンしながら、1本目の始値を上回って終値となる強気ローソク足。
- Morning Doji Star – 弱気ローソク足、次に十字線または小さいボディのローソク足、その後1本目のローソク足のボディに戻って終値となる強気ローソク足。
- Three Inside Up – 弱気ローソク足、その範囲内に収まるより小さい強気ローソク足、次に1本目の始値を上回って終値となる強気ローソク足。
- Three Outside Up – 弱気ローソク足に続き、それを包み込むより大きな強気ローソク足、その後リバーサルを確認する3本目の強気ローソク足。
- Three White Soldiers – 終値が上昇し続ける3本の連続した強気ローソク足。
詳細
- エントリー条件: リストされたパターンのいずれかと、最後のローソク足が移動平均線より下で始値を付けること
- ロング/ショート: ロング
- エグジット条件: オプションのトレーリングストップ
- ストップ: トレーリング
- デフォルト値:
MaPeriod= 50TrailingStop= 50UseTrailingStop= true
- フィルター:
- カテゴリ: パターン
- 方向: ロングのみ
- インジケーター: SMA
- ストップ: トレーリング
- 複雑さ: 基本
- 時間軸: イントラデイ
- 季節性: いいえ
- ニューラルネットワーク: いいえ
- ダイバージェンス: いいえ
- リスクレベル: 中
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>
/// Strategy looking for bullish/bearish reversal candlestick patterns with MA filter.
/// </summary>
public class BullishReversalStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _maPeriod;
private decimal _prevOpen1, _prevClose1, _prevLow1;
private decimal _prevOpen2, _prevClose2, _prevLow2;
private decimal _prevOpen3, _prevClose3, _prevLow3;
private int _candleCount;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int MaPeriod { get => _maPeriod.Value; set => _maPeriod.Value = value; }
public BullishReversalStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
_maPeriod = Param(nameof(MaPeriod), 50)
.SetDisplay("MA Period", "EMA length", "Parameters")
.SetGreaterThanZero();
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevOpen1 = 0; _prevClose1 = 0; _prevLow1 = 0;
_prevOpen2 = 0; _prevClose2 = 0; _prevLow2 = 0;
_prevOpen3 = 0; _prevClose3 = 0; _prevLow3 = 0;
_candleCount = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = MaPeriod };
SubscribeCandles(CandleType).Bind(ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal ma)
{
if (candle.State != CandleStates.Finished) return;
_candleCount++;
if (_candleCount < 4)
{
ShiftCandles(candle);
return;
}
// Bullish patterns using stored values
var threeWhiteSoldiers = _prevOpen3 < _prevClose3 && _prevOpen2 < _prevClose2 && _prevOpen1 < _prevClose1 &&
_prevClose3 < _prevClose2 && _prevClose2 < _prevClose1;
var threeInsideUp = _prevOpen3 > _prevClose3 &&
Math.Abs(_prevClose2 - _prevOpen2) <= 0.6m * Math.Abs(_prevOpen3 - _prevClose3) &&
_prevClose2 > _prevOpen2 && _prevClose1 > _prevOpen1 && _prevClose1 > _prevOpen3;
// Bearish patterns
var threeBlackCrows = _prevOpen3 > _prevClose3 && _prevOpen2 > _prevClose2 && _prevOpen1 > _prevClose1 &&
_prevClose3 > _prevClose2 && _prevClose2 > _prevClose1;
var threeInsideDown = _prevOpen3 < _prevClose3 &&
Math.Abs(_prevClose2 - _prevOpen2) <= 0.6m * Math.Abs(_prevOpen3 - _prevClose3) &&
_prevClose2 < _prevOpen2 && _prevClose1 < _prevOpen1 && _prevClose1 < _prevOpen3;
var bullSignal = threeWhiteSoldiers || threeInsideUp;
var bearSignal = threeBlackCrows || threeInsideDown;
if (bullSignal && candle.ClosePrice > ma && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (bearSignal && candle.ClosePrice < ma && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
ShiftCandles(candle);
}
private void ShiftCandles(ICandleMessage candle)
{
_prevOpen3 = _prevOpen2; _prevClose3 = _prevClose2; _prevLow3 = _prevLow2;
_prevOpen2 = _prevOpen1; _prevClose2 = _prevClose1; _prevLow2 = _prevLow1;
_prevOpen1 = candle.OpenPrice; _prevClose1 = candle.ClosePrice; _prevLow1 = candle.LowPrice;
}
}
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 DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class bullish_reversal_strategy(Strategy):
def __init__(self):
super(bullish_reversal_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._ma_period = self.Param("MaPeriod", 50) \
.SetDisplay("MA Period", "EMA length", "Parameters")
self._prev_open1 = 0.0
self._prev_close1 = 0.0
self._prev_low1 = 0.0
self._prev_open2 = 0.0
self._prev_close2 = 0.0
self._prev_low2 = 0.0
self._prev_open3 = 0.0
self._prev_close3 = 0.0
self._prev_low3 = 0.0
self._candle_count = 0
@property
def candle_type(self):
return self._candle_type.Value
@property
def ma_period(self):
return self._ma_period.Value
def OnReseted(self):
super(bullish_reversal_strategy, self).OnReseted()
self._prev_open1 = 0.0
self._prev_close1 = 0.0
self._prev_low1 = 0.0
self._prev_open2 = 0.0
self._prev_close2 = 0.0
self._prev_low2 = 0.0
self._prev_open3 = 0.0
self._prev_close3 = 0.0
self._prev_low3 = 0.0
self._candle_count = 0
def OnStarted2(self, time):
super(bullish_reversal_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self.ma_period
self.SubscribeCandles(self.candle_type).Bind(ema, self.process_candle).Start()
def process_candle(self, candle, ma):
if candle.State != CandleStates.Finished:
return
self._candle_count += 1
if self._candle_count < 4:
self._shift_candles(candle)
return
mv = float(ma)
three_white_soldiers = (self._prev_open3 < self._prev_close3 and
self._prev_open2 < self._prev_close2 and
self._prev_open1 < self._prev_close1 and
self._prev_close3 < self._prev_close2 and
self._prev_close2 < self._prev_close1)
three_inside_up = (self._prev_open3 > self._prev_close3 and
abs(self._prev_close2 - self._prev_open2) <= 0.6 * abs(self._prev_open3 - self._prev_close3) and
self._prev_close2 > self._prev_open2 and
self._prev_close1 > self._prev_open1 and
self._prev_close1 > self._prev_open3)
three_black_crows = (self._prev_open3 > self._prev_close3 and
self._prev_open2 > self._prev_close2 and
self._prev_open1 > self._prev_close1 and
self._prev_close3 > self._prev_close2 and
self._prev_close2 > self._prev_close1)
three_inside_down = (self._prev_open3 < self._prev_close3 and
abs(self._prev_close2 - self._prev_open2) <= 0.6 * abs(self._prev_open3 - self._prev_close3) and
self._prev_close2 < self._prev_open2 and
self._prev_close1 < self._prev_open1 and
self._prev_close1 < self._prev_open3)
bull_signal = three_white_soldiers or three_inside_up
bear_signal = three_black_crows or three_inside_down
close = float(candle.ClosePrice)
if bull_signal and close > mv and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif bear_signal and close < mv and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._shift_candles(candle)
def _shift_candles(self, candle):
self._prev_open3 = self._prev_open2
self._prev_close3 = self._prev_close2
self._prev_low3 = self._prev_low2
self._prev_open2 = self._prev_open1
self._prev_close2 = self._prev_close1
self._prev_low2 = self._prev_low1
self._prev_open1 = float(candle.OpenPrice)
self._prev_close1 = float(candle.ClosePrice)
self._prev_low1 = float(candle.LowPrice)
def CreateClone(self):
return bullish_reversal_strategy()