ホーム
/
戦略のサンプル
GitHub で見る
Fibonacci 戦略によるプロフィット ハンター HSI
概要
この戦略は、MetaTrader 4 Expert Advisor Profit_Hunter_HSI_with_fibonacci.mq4 の C# ポートです。オリジナルのスクリプトを組み合わせると、
日次チャートから派生した Fibonacci リトレースメント ゾーンを含む日中指数移動平均 (EMA) フィルター。 StockSharp
実装は、高レベルの API を使用した同じアイデアに従います。2 つのローソク足ストリーム (日中と日次) をサブスクライブし、計算します。
Fibonacci グリッドは動的に、価格がこれらのバンドと相互作用するときに取引シグナルを生成し、結果として生じるポジションを管理します
適応的なストップ配置と段階的なトレーリングストップロジックを備えています。
マーケットデータの流れ
Intraday candles – the TimeFrame parameter defines the working resolution (default: 1 minute).完成したキャンドルはそれぞれ供給されます
EMA トレンド フィルターは、NumBars バー前に取得された最新のサポート/レジスタンス参照を更新し、取引をトリガーします
ロジック。
毎日のローソク足 – 専用のサブスクリプションにより、より高い時間枠のデータが収集されます。ユーザーが構成可能な 2 つのインデックスがスイングの高さを選択します
スイングローは、Fibonacci グリッドのアンカーとして使用されます。新しい毎日のキャンドルが到着するたびに、リトレースメントのはしご全体が
拡張子を含めて再計算されます (161.8%、261.8%、423.6%)。
信号の生成
MQL アドバイザーは、最後に検出された高値/安値のスイングを保存し、どちらが最初に発生したかを判断しました (highFirst)。ポートは
same concept by comparing the day indices:
選択した高値が選択した安値 (highFirst = true) よりも新しい場合、市場は降順として扱われ、
Fibonacci レベルは最低値から上方に測定されます。
それ以外の場合、動きは上昇しているとみなされ、グリッドは高値から下に投影されます。
完了した日中ローソク足ごとに、次のルールは元の EA を反映します。
トレンド フィルター – 期間 MaPeriod の EMA は、短期的なバイアスを分類します。終値の場合(買値と買値の両方として扱われます)
is above the EMA the trend is "Naik" (up);それを下回っている場合、トレンドは「トゥルン」(下落)です。価格がちょうどその付近で推移しているとき
EMA 取引は開始されません。
Fibonacci シグナル – highFirst に応じて、23.6%、76.4%、91%、14.6% レベルとの価格相互作用により、次のいずれかが生成されます。
MT4 コードからの 4 つの文字列シグナル: Reverse-Buy、Reverse-Sell、Trading-Area、または Continuation。 Only the first three are
used for actual entries, the last one simply reports a trend continuation.
エントリ ルール – 元のスクリプトには 6 つのエントリ ブランチが含まれていました。それらはそのまま再現されます。
上昇トレンド + トレーディングエリア + 基準レジスタンスを上回るブレイクアウト → 基準サポートでの保護ストップで購入。
上昇トレンド + 逆売り + highFirst == false + 価格は依然として抵抗線を下回っている → 14.6% レベルのストップでショートをオープンします。
上昇トレンド + 逆買い + highFirst == false + レジスタンス以下の価格 → 91% レベルのストップで買い。
下降トレンド + 取引エリア + サポートの下でブレイク → レジスタンスラインでストップして売る。
下降トレンド + 逆売り + highFirst == true + レジスタンス以下の価格 → 91% レベルのストップで売り。
下降トレンド + 逆買い + highFirst == true + レジスタンス以下の価格 → 14.6% レベルのストップで買い。
一度に存在できるポジションは 1 つだけです。アクティブな注文はスタックされません。
ポジション管理
サポート/レジスタンスの終了 – EA のように、価格がサポート基準まで下がった場合、ロングポジションは清算されます。
現在の利益に関係なく、価格がレジスタンス基準まで回復すると、ショートはクローズされます。
初期保護停止 – エントリの決定中に計算された停止レベルは内部に保存され、終了トリガーとして使用されます。
StockSharp バージョンは、ブローカー注文を直接変更するのではなく、すべてのキャンドルに対して同じチェックを実行します。
段階的なトレーリング ストップ – MQL スクリプトは、最初の 60 ポイントの移動後、20 ポイントごとにストップ レベルを上げました (例: +60 → ストップ)
+55、+80 → +75 まで停止、…最大 +260)。 The port keeps the exact ladder using the instrument PriceStep to convert points into
価格のオフセット。短期トレードの場合、ストップが下にスライドして利益を確定し、元の取引と同じ距離を保証します。
パラメーター
名前
説明
デフォルト
注意事項
NumBars
高値/安値が一時的な抵抗線/サポートとなるローソク足の推移。
3
numBars の外部入力と一致します。ゼロより大きくなければなりません。
MaPeriod
Period of the EMA used for trend classification.
5
EA の maPeriod に相当します。
TimeFrame
日中のローソク足の時間枠。
1 minute
timeFrame 外部をミラーリングします。任意の TimeSpan を受け入れます。
DaysBackForHigh
スイング高を提供する毎日のローソク足のインデックス。
1
daysBackForHighに対応します。
DaysBackForLow
安値スイングを提供する毎日のローソク足のインデックス。
1
daysBackForLowに対応します。
Volume
Market order size.
1
ロット/シェアを表します。陽性を維持することが検証されました。
実装メモ
オリジナルの EA は多数のグラフィック オブジェクトを作成しました。 StockSharp がグラフ作成を処理するため、これらの呼び出しは意図的に省略されています
形状は純粋に表面的なものでした。
iLow や iHigh などの履歴バッファーをクエリする代わりに、ポートは完了したローソク足の 2 つのメモリ内リストを維持します。
reads the required shift directly from there.
停止管理は、OrderModify 経由ではなく戦略コード (ManagePosition) で実装され、動作ブローカーを維持します。
同じ決定木を維持しながら不可知論的です。
注文拒否によりエントリー保留状態がクリアされるため、手動調整により古い内部フラグが残らないようになり、防御的条件と一致します。
多くの既存の API 戦略に存在するコーディング。
MetaTrader は、ティックレベルの Ask および Bid へのアクセスを想定しました。 StockSharp はデフォルトでローソク足の終値で動作します。 the close price is used
入札および問い合わせプロキシの両方として使用できます。これは、意思決定ロジックを複製するのに十分です。
「どの極値が最初に出現したか」という概念は、MT4 の High[]/Low[] シリーズに依存することはできません。ポートは比較することによってそれを近似します。
the selected day indices, delivering identical results for the default configuration and preserving the intended behaviour for
other settings.
ブローカー側のストップ注文とテイクプロフィット注文は、ローソクごとに評価される仮想出口に置き換えられます。これにより、コネクタ固有の順序が回避されます
同じ終了条件が満たされていることを確認しながら、タイプを変更します。
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Profit Hunter strategy with Fibonacci retracement levels.
/// Uses EMA trend filter and enters on pullbacks to Fibonacci levels.
/// </summary>
public class ProfitHunterHsiWithFibonacciStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _lookbackPeriod;
private readonly StrategyParam<DataType> _candleType;
private int _barCount;
public ProfitHunterHsiWithFibonacciStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetDisplay("EMA Period", "Period for trend filter EMA.", "Indicators");
_lookbackPeriod = Param(nameof(LookbackPeriod), 50)
.SetDisplay("Lookback Period", "Bars to look back for range high/low.", "Fibonacci");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(2).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for analysis.", "General");
}
public int EmaPeriod
{
get => _emaPeriod.Value;
set => _emaPeriod.Value = value;
}
public int LookbackPeriod
{
get => _lookbackPeriod.Value;
set => _lookbackPeriod.Value = value;
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <inheritdoc />
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_barCount = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_barCount = 0;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var highest = new Highest { Length = LookbackPeriod };
var lowest = new Lowest { Length = LookbackPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, highest, lowest, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue, decimal highestValue, decimal lowestValue)
{
if (candle.State != CandleStates.Finished)
return;
_barCount++;
if (_barCount < LookbackPeriod)
return;
var range = highestValue - lowestValue;
if (range <= 0)
return;
// Fibonacci levels
var fib382 = highestValue - range * 0.382m;
var fib618 = highestValue - range * 0.618m;
var close = candle.ClosePrice;
// Manage position
if (Position > 0)
{
// Exit long at 0 fib (range high) or if price drops below 61.8%
if (close >= highestValue || close < fib618)
{
SellMarket();
}
}
else if (Position < 0)
{
// Exit short at 100% fib (range low) or if price rises above 38.2%
if (close <= lowestValue || close > fib382)
{
BuyMarket();
}
}
// Entry logic
if (Position == 0)
{
if (close > emaValue && close <= fib382 && close > fib618)
{
// Uptrend + pullback to Fib zone -> buy
BuyMarket();
}
else if (close < emaValue && close >= fib618 && close < fib382)
{
// Downtrend + pullback to Fib zone -> sell
SellMarket();
}
}
}
}
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.Strategies import Strategy
from StockSharp.Algo.Indicators import ExponentialMovingAverage, Highest, Lowest
class profit_hunter_hsi_with_fibonacci_strategy(Strategy):
def __init__(self):
super(profit_hunter_hsi_with_fibonacci_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 20) \
.SetDisplay("EMA Period", "Period for trend filter EMA", "Indicators")
self._lookback_period = self.Param("LookbackPeriod", 50) \
.SetDisplay("Lookback Period", "Bars to look back for range high/low", "Fibonacci")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(2))) \
.SetDisplay("Candle Type", "Timeframe for analysis", "General")
self._bar_count = 0
@property
def EmaPeriod(self):
return self._ema_period.Value
@property
def LookbackPeriod(self):
return self._lookback_period.Value
@property
def CandleType(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(profit_hunter_hsi_with_fibonacci_strategy, self).OnStarted2(time)
self._bar_count = 0
self._ema = ExponentialMovingAverage()
self._ema.Length = self.EmaPeriod
self._highest = Highest()
self._highest.Length = self.LookbackPeriod
self._lowest = Lowest()
self._lowest.Length = self.LookbackPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self._ema, self._highest, self._lowest, self.ProcessCandle).Start()
def ProcessCandle(self, candle, ema_value, highest_value, lowest_value):
if candle.State != CandleStates.Finished:
return
self._bar_count += 1
if self._bar_count < self.LookbackPeriod:
return
ema_val = float(ema_value)
high_val = float(highest_value)
low_val = float(lowest_value)
rng = high_val - low_val
if rng <= 0:
return
fib382 = high_val - rng * 0.382
fib618 = high_val - rng * 0.618
close = float(candle.ClosePrice)
# Manage position
if self.Position > 0:
if close >= high_val or close < fib618:
self.SellMarket()
elif self.Position < 0:
if close <= low_val or close > fib382:
self.BuyMarket()
# Entry logic
if self.Position == 0:
if close > ema_val and close <= fib382 and close > fib618:
self.BuyMarket()
elif close < ema_val and close >= fib618 and close < fib382:
self.SellMarket()
def OnReseted(self):
super(profit_hunter_hsi_with_fibonacci_strategy, self).OnReseted()
self._bar_count = 0
def CreateClone(self):
return profit_hunter_hsi_with_fibonacci_strategy()