Three Kilos BTC 15m 戦略
Three Kilos BTC 15m戦略は、3つのトリプル指数移動平均(TEMA)とSupertrendフィルターを組み合わせます。中間TEMAが短期TEMAを上抜け、低速TEMAより上にあり、Supetrendが上昇トレンドを示す場合にロングポジションを建てます。短期TEMAが中間TEMAを上抜け、低速TEMAより下にあり、Supetrendが下降トレンドを示す場合にショートポジションを建てます。固定パーセンテージのテイクプロフィットとストップロスでリスクを管理します。
詳細
- エントリー条件:
- ロング: TEMA2がTEMA1を上抜け、TEMA2 > TEMA3、Supertrend上昇トレンド。
- ショート: TEMA1がTEMA2を上抜け、TEMA2 < TEMA3、Supertrend下降トレンド。
- ロング/ショート: 両方。
- エグジット条件:
- テイクプロフィットまたはストップロス。
- ストップ: テイクプロフィット1%およびストップロス1%。
- デフォルト値:
ShortPeriod= 30LongPeriod= 50Long2Period= 140AtrLength= 10Multiplier= 2TakeProfit= 1%StopLoss= 1%
- フィルター:
- カテゴリ: トレンドフォロー
- 方向: 両方
- インジケーター: TEMA, Supertrend, ATR
- ストップ: テイクプロフィットとストップロス
- 複雑さ: 中程度
- 時間軸: 15m
- 季節性: いいえ
- ニューラルネットワーク: いいえ
- ダイバージェンス: いいえ
- リスクレベル: 中
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>
/// Three Kilos BTC 15m strategy.
/// Three TEMAs (ShortPeriod, LongPeriod, Long2Period) with a Supertrend filter. A long opens when TEMA2 crosses above TEMA1 while
/// TEMA2 is above TEMA3 and the Supertrend is up; a short opens when TEMA1 crosses above TEMA2 while TEMA2 is below TEMA3 and the
/// Supertrend is down. Positions close by a percent take profit or stop loss.
/// </summary>
public class ThreeKilosBtc15mStrategy : Strategy
{
private readonly StrategyParam<int> _shortPeriod;
private readonly StrategyParam<int> _longPeriod;
private readonly StrategyParam<int> _long2Period;
private readonly StrategyParam<int> _atrLength;
private readonly StrategyParam<decimal> _multiplier;
private readonly StrategyParam<decimal> _takeProfit;
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevTema1;
private decimal? _prevTema2;
/// <summary>
/// Period of TEMA1.
/// </summary>
public int ShortPeriod
{
get => _shortPeriod.Value;
set => _shortPeriod.Value = value;
}
/// <summary>
/// Period of TEMA2.
/// </summary>
public int LongPeriod
{
get => _longPeriod.Value;
set => _longPeriod.Value = value;
}
/// <summary>
/// Period of TEMA3.
/// </summary>
public int Long2Period
{
get => _long2Period.Value;
set => _long2Period.Value = value;
}
/// <summary>
/// ATR length of the Supertrend.
/// </summary>
public int AtrLength
{
get => _atrLength.Value;
set => _atrLength.Value = value;
}
/// <summary>
/// ATR multiplier of the Supertrend.
/// </summary>
public decimal Multiplier
{
get => _multiplier.Value;
set => _multiplier.Value = value;
}
/// <summary>
/// Take profit percentage.
/// </summary>
public decimal TakeProfit
{
get => _takeProfit.Value;
set => _takeProfit.Value = value;
}
/// <summary>
/// Stop loss percentage.
/// </summary>
public decimal StopLoss
{
get => _stopLoss.Value;
set => _stopLoss.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public ThreeKilosBtc15mStrategy()
{
_shortPeriod = Param(nameof(ShortPeriod), 30)
.SetGreaterThanZero()
.SetDisplay("Short Period", "Period of TEMA1", "Indicators");
_longPeriod = Param(nameof(LongPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("Long Period", "Period of TEMA2", "Indicators");
_long2Period = Param(nameof(Long2Period), 140)
.SetGreaterThanZero()
.SetDisplay("Long2 Period", "Period of TEMA3", "Indicators");
_atrLength = Param(nameof(AtrLength), 10)
.SetGreaterThanZero()
.SetDisplay("ATR Length", "ATR length of the Supertrend", "Supertrend");
_multiplier = Param(nameof(Multiplier), 2m)
.SetGreaterThanZero()
.SetDisplay("Multiplier", "ATR multiplier of the Supertrend", "Supertrend");
_takeProfit = Param(nameof(TakeProfit), 1m)
.SetNotNegative()
.SetDisplay("Take Profit %", "Take profit percentage", "Risk");
_stopLoss = Param(nameof(StopLoss), 1m)
.SetNotNegative()
.SetDisplay("Stop Loss %", "Stop loss percentage", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).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();
_prevTema1 = null;
_prevTema2 = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevTema1 = null;
_prevTema2 = null;
var tema1 = new TripleExponentialMovingAverage { Length = ShortPeriod };
var tema2 = new TripleExponentialMovingAverage { Length = LongPeriod };
var tema3 = new TripleExponentialMovingAverage { Length = Long2Period };
var superTrend = new SuperTrend { Length = AtrLength, Multiplier = Multiplier };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(tema1, tema2, tema3, superTrend, ProcessCandle)
.Start();
StartProtection(new Unit(TakeProfit, UnitTypes.Percent), new Unit(StopLoss, UnitTypes.Percent), useMarketOrders: true);
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, tema1);
DrawIndicator(area, tema2);
DrawIndicator(area, tema3);
DrawIndicator(area, superTrend);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue tema1Value, IIndicatorValue tema2Value, IIndicatorValue tema3Value, IIndicatorValue superTrendValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!tema1Value.IsFormed || !tema2Value.IsFormed || !tema3Value.IsFormed || !superTrendValue.IsFormed)
return;
var tema1 = tema1Value.ToDecimal();
var tema2 = tema2Value.ToDecimal();
var tema3 = tema3Value.ToDecimal();
var isUpTrend = ((SuperTrendIndicatorValue)superTrendValue).IsUpTrend;
var prevTema1 = _prevTema1;
var prevTema2 = _prevTema2;
_prevTema1 = tema1;
_prevTema2 = tema2;
if (prevTema1 is not decimal p1 || prevTema2 is not decimal p2)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var tema2CrossesUp = p2 <= p1 && tema2 > tema1;
var tema1CrossesUp = p1 <= p2 && tema1 > tema2;
if (tema2CrossesUp && tema2 > tema3 && isUpTrend && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (tema1CrossesUp && tema2 < tema3 && !isUpTrend && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
clr.AddReference("StockSharp.BusinessEntities")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates, Unit, UnitTypes
from StockSharp.Algo.Indicators import TripleExponentialMovingAverage, SuperTrend
from StockSharp.Algo.Strategies import Strategy
class three_kilos_btc_15m_strategy(Strategy):
"""
Three Kilos BTC 15m strategy.
Three TEMAs (ShortPeriod, LongPeriod, Long2Period) with a Supertrend filter. A long opens when TEMA2 crosses above TEMA1 while
TEMA2 is above TEMA3 and the Supertrend is up; a short opens when TEMA1 crosses above TEMA2 while TEMA2 is below TEMA3 and the
Supertrend is down. Positions close by a percent take profit or stop loss.
"""
def __init__(self):
super(three_kilos_btc_15m_strategy, self).__init__()
self._short_period = self.Param("ShortPeriod", 30).SetGreaterThanZero().SetDisplay("Short Period", "Period of TEMA1", "Indicators")
self._long_period = self.Param("LongPeriod", 50).SetGreaterThanZero().SetDisplay("Long Period", "Period of TEMA2", "Indicators")
self._long2_period = self.Param("Long2Period", 140).SetGreaterThanZero().SetDisplay("Long2 Period", "Period of TEMA3", "Indicators")
self._atr_length = self.Param("AtrLength", 10).SetGreaterThanZero().SetDisplay("ATR Length", "ATR length of the Supertrend", "Supertrend")
self._multiplier = self.Param("Multiplier", 2.0).SetGreaterThanZero().SetDisplay("Multiplier", "ATR multiplier of the Supertrend", "Supertrend")
self._take_profit = self.Param("TakeProfit", 1.0).SetNotNegative().SetDisplay("Take Profit %", "Take profit percentage", "Risk")
self._stop_loss = self.Param("StopLoss", 1.0).SetNotNegative().SetDisplay("Stop Loss %", "Stop loss percentage", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._reset_state()
@property
def candle_type(self):
return self._candle_type.Value
def _reset_state(self):
self._prev_tema1 = None
self._prev_tema2 = None
def OnReseted(self):
super(three_kilos_btc_15m_strategy, self).OnReseted()
self._reset_state()
def OnStarted2(self, time):
super(three_kilos_btc_15m_strategy, self).OnStarted2(time)
self._reset_state()
tema1 = TripleExponentialMovingAverage()
tema1.Length = self._short_period.Value
tema2 = TripleExponentialMovingAverage()
tema2.Length = self._long_period.Value
tema3 = TripleExponentialMovingAverage()
tema3.Length = self._long2_period.Value
super_trend = SuperTrend()
super_trend.Length = self._atr_length.Value
super_trend.Multiplier = Decimal(self._multiplier.Value)
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(tema1, tema2, tema3, super_trend, self._process_candle).Start()
self.StartProtection(Unit(Decimal(self._take_profit.Value), UnitTypes.Percent), Unit(Decimal(self._stop_loss.Value), UnitTypes.Percent), useMarketOrders=True)
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, tema1)
self.DrawIndicator(area, tema2)
self.DrawIndicator(area, tema3)
self.DrawIndicator(area, super_trend)
self.DrawOwnTrades(area)
def _process_candle(self, candle, tema1_value, tema2_value, tema3_value, super_trend_value):
if candle.State != CandleStates.Finished:
return
if not tema1_value.IsFormed or not tema2_value.IsFormed or not tema3_value.IsFormed or not super_trend_value.IsFormed:
return
tema1 = tema1_value.GetValue[Decimal](None)
tema2 = tema2_value.GetValue[Decimal](None)
tema3 = tema3_value.GetValue[Decimal](None)
is_up_trend = super_trend_value.IsUpTrend
prev_tema1 = self._prev_tema1
prev_tema2 = self._prev_tema2
self._prev_tema1 = tema1
self._prev_tema2 = tema2
if prev_tema1 is None or prev_tema2 is None:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
tema2_crosses_up = prev_tema2 <= prev_tema1 and tema2 > tema1
tema1_crosses_up = prev_tema1 <= prev_tema2 and tema1 > tema2
if tema2_crosses_up and tema2 > tema3 and is_up_trend and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif tema1_crosses_up and tema2 < tema3 and not is_up_trend and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
def CreateClone(self):
return three_kilos_btc_15m_strategy()