ホーム
/
戦略のサンプル
GitHub で見る
スウェッテン戦略
概要
Swetten は、もともと MetaTrader 4 用に配布されたニューラル ネットワーク主導のブレイクアウト戦略です。これは、長期 233 期間の単純移動平均と、1 分ローソク足で計算された 10 個のより速い移動平均の間のスプレッドを評価します。スプレッドは、強気または弱気のアクティベーション レベルを生成する放射状ベーシス ネットワークに供給されます。アクティベーションがプラスの場合、戦略はロングに入り、マイナスの場合、ショートに入ります。
市場と時間枠
主要なFXペア向けに設計されています(元のコードはEURUSDをターゲットとしていました)。
分析には 1 分間のローソク足が使用され、決定は完了したローソク足に基づいてのみ行われます。
シグナルは 2 時間ごとの正午 (00:00、02:00、…、22:00 交換時間) に評価されます。土曜日や日曜日には取引は行われません。
指標と特徴
期間付きの単純移動平均: 233 (ベースライン)、144、89、55、34、21、13、8、5、3、2。
ニューラル ネットワークの入力は、233 期間の平均と各高速平均の差です。
ネットワークに渡す前に、入力はトレーニングされた範囲にクランプされ、正規化され、元の DLL で使用されているのと同じ係数でスケーリングされます。
The radial basis network is replicated exactly from the exported EURUSDn function, consisting of 38 Gaussian features whose outputs are averaged to obtain the final activation.
取引ルール
平日の偶数時間に終了する 1 分ローソク足の終値を待ちます。
移動平均の広がりからニューラル ネットワークの活性化を計算します。
アクティベーション > 0 で、現在のポジションが長くない場合は、TradeVolume + abs(current position) ロットの成行買いを送信します。
アクティベーション < 0 で、現在のポジションがショートではない場合は、TradeVolume + abs(current position) ロットの成行売りを送信します。
ポジションは以下によって保護されます。
価格ステップ (TakeProfitPoints) で定義された固定テイクプロフィット。
価格ステップ (StopLossPoints) で定義された固定ストップロス。
ローソクの高値/安値の極値を使用していずれかのレベルに触れると、ポジションは成行注文によって閉じられます。
パラメーター
名前
説明
デフォルト
CandleType
計算に使用されるローソク足シリーズ。
1分の時間枠
TradeVolume
ロット単位の基本注文量。
0.1
SlowPeriod
ベースライン単純移動平均の期間。
233
TakeProfitPoints
価格ステップでの利益目標距離。
150
StopLossPoints
価格ステップのストップロス距離。
40
変換メモ
MetaTrader の DLL ベースのニューラル ネットワークは、エクスポートされた関数をマネージド コードに変換することで C# に完全に移植されました。
保護的出口は、価格ステップのしきい値に対してローソク足の高値と安値をチェックすることで、元の OrderClose の条件を模倣します。
エントリー管理は、エグジットを実際の約定と一致させるために、OnNewMyTrade を介して最新の約定価格を追跡します。
すべてのコメントは英語で書き直され、コードは変換ガイドラインの要求に従って高レベルの StockSharp API (SubscribeCandles、Bind) を使用しています。
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Swetten strategy: multi-SMA spread crossover system.
/// Uses fast SMA (5) and slow SMA (50) to generate trend signals.
/// Buys when fast crosses above slow, sells when fast crosses below slow.
/// </summary>
public class SwettenStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private decimal _prevFast;
private decimal _prevSlow;
private bool _isReady;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int FastPeriod
{
get => _fastPeriod.Value;
set => _fastPeriod.Value = value;
}
public int SlowPeriod
{
get => _slowPeriod.Value;
set => _slowPeriod.Value = value;
}
public SwettenStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle type for strategy", "General");
_fastPeriod = Param(nameof(FastPeriod), 8)
.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 34)
.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");
}
/// <inheritdoc />
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_isReady = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = 0;
_prevSlow = 0;
_isReady = false;
var fast = new SMA { Length = FastPeriod };
var slow = new SMA { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, slow, OnProcess)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fast);
DrawIndicator(area, slow);
DrawOwnTrades(area);
}
}
private void OnProcess(ICandleMessage candle, decimal fastVal, decimal slowVal)
{
if (candle.State != CandleStates.Finished)
return;
if (!_isReady)
{
_prevFast = fastVal;
_prevSlow = slowVal;
_isReady = true;
return;
}
// Fast crosses above slow = buy
if (_prevFast <= _prevSlow && fastVal > slowVal)
{
if (Position < 0)
BuyMarket();
if (Position <= 0)
BuyMarket();
}
// Fast crosses below slow = sell
else if (_prevFast >= _prevSlow && fastVal < slowVal)
{
if (Position > 0)
SellMarket();
if (Position >= 0)
SellMarket();
}
_prevFast = fastVal;
_prevSlow = slowVal;
}
}
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class swetten_strategy(Strategy):
"""Fast/slow SMA crossover (8/34)."""
def __init__(self):
super(swetten_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 8).SetDisplay("Fast SMA", "Fast SMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 34).SetDisplay("Slow SMA", "Slow SMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Candle type for strategy", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(swetten_strategy, self).OnReseted()
self._prev_fast = 0
self._prev_slow = 0
self._is_ready = False
def OnStarted2(self, time):
super(swetten_strategy, self).OnStarted2(time)
self._prev_fast = 0
self._prev_slow = 0
self._is_ready = False
fast = SimpleMovingAverage()
fast.Length = self._fast_period.Value
slow = SimpleMovingAverage()
slow.Length = self._slow_period.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(fast, slow, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def OnProcess(self, candle, fast_val, slow_val):
if candle.State != CandleStates.Finished:
return
if not self._is_ready:
self._prev_fast = fast_val
self._prev_slow = slow_val
self._is_ready = True
return
if self._prev_fast <= self._prev_slow and fast_val > slow_val:
if self.Position < 0:
self.BuyMarket()
if self.Position <= 0:
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and fast_val < slow_val:
if self.Position > 0:
self.SellMarket()
if self.Position >= 0:
self.SellMarket()
self._prev_fast = fast_val
self._prev_slow = slow_val
def CreateClone(self):
return swetten_strategy()