Grid Tendence V1戦略
利益率のステップに基づいてポジションを再オープンまたは反転するグリッドトレーディング戦略です。
ロングで開始し、利益が指定されたパーセントに達すると決済して同じ方向で再オープンします。損失がそのパーセントに達すると決済して反対方向でオープンします。
詳細
- エントリー条件: 常にマーケットに参加し、ロングから開始。利益または損失が
Percentに達したときに再オープンまたは反転。 - ロング/ショート: 両方向。
- エグジット条件: 利益または損失のしきい値。
- ストップ: なし。
- デフォルト値:
Percent= 1.0CandleType= TimeSpan.FromMinutes(1)
- フィルター:
- カテゴリ: グリッド
- 方向: 両方
- インジケーター: なし
- ストップ: いいえ
- 複雑さ: 基本
- 時間軸: イントラデイ (1m)
- 季節性: いいえ
- ニューラルネットワーク: いいえ
- ダイバージェンス: いいえ
- リスクレベル: 中
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Grid Tendence V1 strategy.
/// Always in the market, starting long. When the open position gains Percent percent from its entry price it is closed and
/// reopened in the same direction; when it loses Percent percent it is closed and a position in the opposite direction is opened.
/// </summary>
public class GridTendenceV1Strategy : Strategy
{
private readonly StrategyParam<decimal> _percent;
private readonly StrategyParam<DataType> _candleType;
private decimal _entryPrice;
/// <summary>
/// Profit or loss percent that triggers a reopen or a reversal.
/// </summary>
public decimal Percent
{
get => _percent.Value;
set => _percent.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public GridTendenceV1Strategy()
{
_percent = Param(nameof(Percent), 1.0m)
.SetGreaterThanZero()
.SetDisplay("Percent", "Profit or loss percent that reopens or reverses the position", "Trading");
_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 OnReseted()
{
base.OnReseted();
_entryPrice = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_entryPrice = 0m;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
if (Position == 0)
{
// The first entry is always long.
BuyMarket(Volume);
_entryPrice = close;
return;
}
if (_entryPrice <= 0m)
{
_entryPrice = close;
return;
}
var change = (close - _entryPrice) / _entryPrice * 100m;
var profit = Position > 0 ? change : -change;
if (profit >= Percent)
{
if (Position > 0)
{
SellMarket(Position);
BuyMarket(Volume);
}
else
{
BuyMarket(-Position);
SellMarket(Volume);
}
_entryPrice = close;
}
else if (profit <= -Percent)
{
if (Position > 0)
SellMarket(Volume + Math.Abs(Position));
else
BuyMarket(Volume + Math.Abs(Position));
_entryPrice = close;
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Strategies import Strategy
class grid_tendence_v1_strategy(Strategy):
"""
Grid Tendence V1 strategy.
Always in the market, starting long. When the open position gains Percent percent from its entry price it is closed and
reopened in the same direction; when it loses Percent percent it is closed and a position in the opposite direction is opened.
"""
def __init__(self):
super(grid_tendence_v1_strategy, self).__init__()
self._percent = self.Param("Percent", 1.0).SetGreaterThanZero().SetDisplay("Percent", "Profit or loss percent that reopens or reverses the position", "Trading")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._entry_price = 0.0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(grid_tendence_v1_strategy, self).OnReseted()
self._entry_price = 0.0
def OnStarted2(self, time):
super(grid_tendence_v1_strategy, self).OnStarted2(time)
self._entry_price = 0.0
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
close = float(candle.ClosePrice)
if self.Position == 0:
# The first entry is always long.
self.BuyMarket(self.Volume)
self._entry_price = close
return
if self._entry_price <= 0.0:
self._entry_price = close
return
change = (close - self._entry_price) / self._entry_price * 100.0
profit = change if self.Position > 0 else -change
percent = float(self._percent.Value)
if profit >= percent:
if self.Position > 0:
self.SellMarket(self.Position)
self.BuyMarket(self.Volume)
else:
self.BuyMarket(-self.Position)
self.SellMarket(self.Volume)
self._entry_price = close
elif profit <= -percent:
if self.Position > 0:
self.SellMarket(self.Volume + abs(self.Position))
else:
self.BuyMarket(self.Volume + abs(self.Position))
self._entry_price = close
def CreateClone(self):
return grid_tendence_v1_strategy()