ホーム
/
戦略のサンプル
GitHub で見る
eKeyboardTrader 戦略
概要
この戦略は、StockSharp の高レベル API を使用して、MetaTrader「eKeyboardTrader」エキスパート アドバイザの動作を複製します。元のスクリプトは、手動成行注文を送信するためのキーボード ショートカットをリッスンし、チャート上にヘルパー テキストを直接表示しました。 StockSharp バージョンでは、インタラクティブな入力は戦略パラメーターとして公開されますが、実行ロジック、安全性チェック、注文保護機能は MQL の実装に忠実なままです。
取引ロジック
レベル 1 サブスクリプション – この戦略はレベル 1 の市場データをサブスクライブして、最新の最高買値と売値を受け取ります。 These quotes are required before a manual request can be executed, mimicking the MetaTrader dependency on current tick data.
手動コマンド – 3 つのブール値パラメータ (BuyRequest、SellRequest、CloseRequest) は、元のキーボード ショートカット (B、S、および C) を表します。いずれかのパラメータが true に設定されている場合、戦略は対応する市場アクションを実行し、ただちにフラグをリセットします。
レート制限 – 1 秒間のクールダウンは、MQL バージョンに実装されているタイマー チェックと同じ、偶発的な二重送信を防ぎます。 Requests raised during the cooldown wait for the next processing cycle.
注文保護 – MetaTrader ポイントで表されるオプションのストップロスとテイクプロフィットの距離は、Security.PriceStep を使用して絶対価格に変換されます。少なくとも 1 つの保護距離が設定されている場合、この戦略により StockSharp の組み込み StartProtection ロジックが有効になり、すべての手動入力が設定された保護命令を自動的に受け取るようになります。
スリッページ認識 – SlippagePoints パラメータは互換性のために保存されており、手動注文が送信されるたびにログに記載され、エキスパートアドバイザーによって表示される情報コメントをエミュレートします。
パラメーター
パラメータ
説明
OrderVolume
手動成行注文の基本量。
StopLossPoints
エントリー価格からプロテクティブストップまでの距離 (MetaTrader ポイント)。無効にするには、0 に設定します。
TakeProfitPoints
エントリー価格から保護ターゲットまでの距離 (MetaTrader ポイント)。無効にするには、0 に設定します。
SlippagePoints
各手動注文のログに表示される情報スリッページ許容値。
BuyRequest
成行買い注文を送信するには、true に設定します (処理後に自動リセット)。
SellRequest
Set to true to send a market sell order (auto-resets after processing).
CloseRequest
ネットポジションを市場価格でフラット化するには、true に設定します (処理後に自動リセット)。
MQL バージョンとの違い
The on-chart text prompts and sound notifications are not reproduced.代わりに、ログメッセージに実行されたアクションが記録されます。
保護注文は、StockSharp の StartProtection ヘルパーによって管理されます。このヘルパーは、しきい値に達したときに、個々の MetaTrader チケットを変更するのではなく、成行注文を送信します。
キーボード入力はパラメータの切り替えに置き換えられます。戦略をホストする UI は、ユーザーの操作 (キーボード、ボタン、スクリプト) をこれらのパラメーターにマップできます。
MetaTrader 取引リクエストの診断は、変換を軽量に保つためにログ ステートメントに凝縮されています。
使用上の注意
戦略を開始する前に、Security と Portfolio の両方を割り当ててください。これらのチェックは、エキスパートアドバイザーからの初期化条件を反映します。
The manual command flags are evaluated when new Level1 data arrives.静かな市場では、アクションは次に利用可能な相場に基づいて実行されます。
戦略の実行中に StopLossPoints または TakeProfitPoints を調整するには、戦略を再起動して保護モジュールを再構成し、元のスクリプトのセッションごとに 1 回の保護設定と一致させる必要があります。
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// eKeyboard Trader strategy: CCI trend following.
/// Buys when CCI crosses above +100, sells when CCI crosses below -100.
/// </summary>
public class EKeyboardTraderStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cciPeriod;
private decimal _prevCci;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public EKeyboardTraderStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_cciPeriod = Param(nameof(CciPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("CCI Period", "CCI period", "Indicators");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevCci = 0m;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var cci = new CommodityChannelIndex { Length = CciPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(cci, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal cci)
{
if (candle.State != CandleStates.Finished) return;
if (_hasPrev)
{
if (_prevCci <= 100 && cci > 100 && Position <= 0) BuyMarket();
else if (_prevCci >= -100 && cci < -100 && Position >= 0) SellMarket();
}
_prevCci = cci;
_hasPrev = true;
}
}
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 CommodityChannelIndex
from StockSharp.Algo.Strategies import Strategy
class e_keyboard_trader_strategy(Strategy):
"""
eKeyboard Trader strategy: CCI trend following.
Buys when CCI crosses above +100, sells when CCI crosses below -100.
"""
def __init__(self):
super(e_keyboard_trader_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._cci_period = self.Param("CciPeriod", 14) \
.SetDisplay("CCI Period", "CCI period", "Indicators")
self._prev_cci = 0.0
self._has_prev = False
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(e_keyboard_trader_strategy, self).OnReseted()
self._prev_cci = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(e_keyboard_trader_strategy, self).OnStarted2(time)
self._has_prev = False
cci = CommodityChannelIndex()
cci.Length = self._cci_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(cci, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, cci)
self.DrawOwnTrades(area)
def _process_candle(self, candle, cci_val):
if candle.State != CandleStates.Finished:
return
cci_val = float(cci_val)
if self._has_prev:
if self._prev_cci <= 100.0 and cci_val > 100.0 and self.Position <= 0:
self.BuyMarket()
elif self._prev_cci >= -100.0 and cci_val < -100.0 and self.Position >= 0:
self.SellMarket()
self._prev_cci = cci_val
self._has_prev = True
def CreateClone(self):
return e_keyboard_trader_strategy()