UP3x1 Premium 策略
UP3x1 Premium 策略是 MetaTrader 指标 up3x1_premium_v2M 的 StockSharp 版本。策略结合快/慢 EMA 交叉、宽幅 K 线过滤以及日线趋势背景,在捕捉动量突破的同时使用固定目标和移动止损控制风险。
工作流程
趋势识别
- 在工作级别计算两条 EMA(默认 12 和 26 周期)。
- 保存前两个 EMA 数值,用于重现原始 MQL 中的交叉判定。
- 在日线级别计算一条 EMA,用于判断大周期方向。
入场条件
- 出现下列任一情形即触发做多:
- 快 EMA 从下向上穿越慢 EMA,且前两根 K 线开盘价逐步抬高。
- 上一根 K 线为宽幅阳线,实体大于设定的阈值。
- 当地时间午夜出现新 K 线时,如果上一日线大幅收低,则允许博弈反弹。
- 当前价格高于日线 EMA,说明大周期偏多。
- 做空条件为上述情形的镜像(快 EMA 下穿、宽幅阴线或午夜出现向下反转信号)。
- 如果多空信号同时出现,则依据当前 EMA 相对位置来决定方向。
- 出现下列任一情形即触发做多:
出场管理
- 以下任一条件满足时平仓:
- EMA 之间的距离缩小到 ±0.1% 以内,表明趋势动能减弱。
- 价格触及设定的止盈或止损(以绝对价格单位定义)。
- 启用移动止损时,止损被逐渐上移/下移并被触发。
- 以下任一条件满足时平仓:
仓位控制
- 仅在空仓状态下开新仓,与原始 EA 保持一致。
OrderVolume参数控制每次下单的合约数量。
参数说明
| 参数 | 说明 |
|---|---|
OrderVolume |
每次交易的下单数量或手数。 |
FastEmaLength / SlowEmaLength |
工作级别快/慢 EMA 的周期。 |
DailyEmaLength |
日线 EMA 的周期。 |
TakeProfit |
绝对止盈距离,0 表示关闭。 |
StopLoss |
绝对止损距离,0 表示关闭。 |
TrailingStop |
移动止损距离,价格达到阈值后开始跟随。 |
RangeThreshold |
认定上一根 K 线为宽幅线所需的最小波动范围。 |
BodyThreshold |
判定动量实体所需的最小 K 线实体。 |
DailyReversalThreshold |
午夜过滤所需的前一日 K 线反转幅度。 |
CandleType |
主交易逻辑使用的时间框架。 |
DailyCandleType |
用于日线趋势过滤的高一级别时间框架。 |
使用建议
- 默认参数沿用原始 EA 中的常数(已从点值转换为绝对价格单位)。
- 请根据交易品种的最小跳动单位,调整止盈、止损、移动止损及宽幅/实体阈值。
- 在此移植版本中,日线 EMA 用于替代原脚本中“永远做多”的偏向,使交易更贴合高周期趋势。
- 在真实交易前,请务必先进行历史回测和模拟盘前向测试。
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Port of the UP3x1 Premium expert advisor that relies on EMA momentum with daily context.
/// </summary>
public class Up3x1PremiumStrategy : Strategy
{
private readonly StrategyParam<decimal> _orderVolume;
private readonly StrategyParam<int> _fastEmaLength;
private readonly StrategyParam<int> _slowEmaLength;
private readonly StrategyParam<int> _dailyEmaLength;
private readonly StrategyParam<decimal> _takeProfit;
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<decimal> _trailingStop;
private readonly StrategyParam<decimal> _rangeThreshold;
private readonly StrategyParam<decimal> _bodyThreshold;
private readonly StrategyParam<decimal> _dailyReversalThreshold;
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<DataType> _dailyCandleType;
private decimal? _fastPrev;
private decimal? _fastPrev2;
private decimal? _slowPrev;
private decimal? _slowPrev2;
private ICandleMessage _prevCandle;
private ICandleMessage _prevPrevCandle;
private decimal? _dailyEmaValue;
private decimal? _prevDailyOpen;
private decimal? _prevDailyClose;
private decimal? _entryPrice;
private decimal? _stopPrice;
private decimal? _takeProfitPrice;
private decimal? _trailingStopPrice;
public Up3x1PremiumStrategy()
{
_orderVolume = Param(nameof(OrderVolume), 1m)
.SetGreaterThanZero()
.SetDisplay("Order Volume", "Volume for each trade", "Trading")
;
_fastEmaLength = Param(nameof(FastEmaLength), 12)
.SetGreaterThanZero()
.SetDisplay("Fast EMA Length", "Length of the fast EMA", "Indicators")
;
_slowEmaLength = Param(nameof(SlowEmaLength), 26)
.SetGreaterThanZero()
.SetDisplay("Slow EMA Length", "Length of the slow EMA", "Indicators")
;
_dailyEmaLength = Param(nameof(DailyEmaLength), 10)
.SetGreaterThanZero()
.SetDisplay("Daily EMA Length", "EMA length for the daily trend filter", "Indicators")
;
_takeProfit = Param(nameof(TakeProfit), 0.015m)
.SetNotNegative()
.SetDisplay("Take Profit", "Absolute take profit distance", "Risk")
;
_stopLoss = Param(nameof(StopLoss), 0.01m)
.SetNotNegative()
.SetDisplay("Stop Loss", "Absolute stop loss distance", "Risk")
;
_trailingStop = Param(nameof(TrailingStop), 0.001m)
.SetNotNegative()
.SetDisplay("Trailing Stop", "Distance for trailing stop updates", "Risk")
;
_rangeThreshold = Param(nameof(RangeThreshold), 0.006m)
.SetNotNegative()
.SetDisplay("Range Threshold", "Minimum candle range to qualify as wide", "Filters")
;
_bodyThreshold = Param(nameof(BodyThreshold), 0.005m)
.SetNotNegative()
.SetDisplay("Body Threshold", "Minimum candle body for momentum", "Filters")
;
_dailyReversalThreshold = Param(nameof(DailyReversalThreshold), 0.006m)
.SetNotNegative()
.SetDisplay("Daily Reversal Threshold", "Minimum prior day reversal size", "Filters")
;
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Primary working timeframe", "General");
_dailyCandleType = Param(nameof(DailyCandleType), TimeSpan.FromDays(1).TimeFrame())
.SetDisplay("Daily Candle Type", "Higher timeframe for daily context", "General");
}
/// <summary>
/// Trade volume expressed in security lots.
/// </summary>
public decimal OrderVolume
{
get => _orderVolume.Value;
set => _orderVolume.Value = value;
}
/// <summary>
/// Length of the fast EMA on the working timeframe.
/// </summary>
public int FastEmaLength
{
get => _fastEmaLength.Value;
set => _fastEmaLength.Value = value;
}
/// <summary>
/// Length of the slow EMA on the working timeframe.
/// </summary>
public int SlowEmaLength
{
get => _slowEmaLength.Value;
set => _slowEmaLength.Value = value;
}
/// <summary>
/// Length of the EMA used on the daily candles.
/// </summary>
public int DailyEmaLength
{
get => _dailyEmaLength.Value;
set => _dailyEmaLength.Value = value;
}
/// <summary>
/// Absolute take profit expressed in price units.
/// </summary>
public decimal TakeProfit
{
get => _takeProfit.Value;
set => _takeProfit.Value = value;
}
/// <summary>
/// Absolute stop loss expressed in price units.
/// </summary>
public decimal StopLoss
{
get => _stopLoss.Value;
set => _stopLoss.Value = value;
}
/// <summary>
/// Distance used for trailing stop updates.
/// </summary>
public decimal TrailingStop
{
get => _trailingStop.Value;
set => _trailingStop.Value = value;
}
/// <summary>
/// Minimum candle range that activates the momentum filter.
/// </summary>
public decimal RangeThreshold
{
get => _rangeThreshold.Value;
set => _rangeThreshold.Value = value;
}
/// <summary>
/// Minimum candle body needed to qualify as a thrust.
/// </summary>
public decimal BodyThreshold
{
get => _bodyThreshold.Value;
set => _bodyThreshold.Value = value;
}
/// <summary>
/// Size of the prior daily reversal required during the midnight check.
/// </summary>
public decimal DailyReversalThreshold
{
get => _dailyReversalThreshold.Value;
set => _dailyReversalThreshold.Value = value;
}
/// <summary>
/// Working timeframe for the main signals.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Higher timeframe used for the daily EMA filter.
/// </summary>
public DataType DailyCandleType
{
get => _dailyCandleType.Value;
set => _dailyCandleType.Value = value;
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType), (Security, DailyCandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_fastPrev = null;
_fastPrev2 = null;
_slowPrev = null;
_slowPrev2 = null;
_prevCandle = null;
_prevPrevCandle = null;
_dailyEmaValue = null;
_prevDailyOpen = null;
_prevDailyClose = null;
ClearTradeLevels();
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
Volume = OrderVolume;
// Create EMA indicators for the working timeframe.
var fastEma = new EMA { Length = FastEmaLength };
var slowEma = new EMA { Length = SlowEmaLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastEma, slowEma, ProcessCandle)
.Start();
// Daily subscription provides the higher timeframe confirmation.
var dailyEma = new EMA { Length = DailyEmaLength };
var dailySubscription = SubscribeCandles(DailyCandleType);
dailySubscription
.Bind(dailyEma, ProcessDailyCandle)
.Start();
StartProtection(null, null);
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fastEma);
DrawIndicator(area, slowEma);
DrawOwnTrades(area);
}
}
private void ProcessDailyCandle(ICandleMessage candle, decimal emaValue)
{
if (candle.State != CandleStates.Finished)
return;
// Store the latest completed daily information for intraday decisions.
_dailyEmaValue = emaValue;
_prevDailyOpen = candle.OpenPrice;
_prevDailyClose = candle.ClosePrice;
}
private void ProcessCandle(ICandleMessage candle, decimal fastEma, decimal slowEma)
{
if (candle.State != CandleStates.Finished)
return;
// Manage an existing position before looking for fresh entries.
ManageOpenPosition(candle);
var haveHistory = _prevCandle != null && _prevPrevCandle != null &&
_fastPrev.HasValue && _fastPrev2.HasValue && _slowPrev.HasValue && _slowPrev2.HasValue;
if (Position == 0m && haveHistory && IsFormedAndOnlineAndAllowTrading())
{
var bullishCross = _fastPrev2.Value < _slowPrev2.Value && _fastPrev.Value > _slowPrev.Value &&
_prevPrevCandle.OpenPrice < _prevCandle.OpenPrice;
var wideBullish = (_prevCandle.HighPrice - _prevCandle.LowPrice) > RangeThreshold &&
_prevCandle.ClosePrice > _prevCandle.OpenPrice &&
(_prevCandle.ClosePrice - _prevCandle.OpenPrice) > BodyThreshold;
var midnight = candle.OpenTime.Hour == 0;
var dailyBounce = midnight &&
_prevDailyOpen is decimal dayOpen &&
_prevDailyClose is decimal dayClose &&
dayOpen > dayClose &&
(dayOpen - dayClose) > DailyReversalThreshold;
var priceAboveDaily = _dailyEmaValue is decimal daily && candle.ClosePrice >= daily;
var longSignal = bullishCross || wideBullish || dailyBounce || priceAboveDaily;
var bearishCross = _fastPrev2.Value > _slowPrev2.Value && _fastPrev.Value < _slowPrev.Value &&
_prevPrevCandle.OpenPrice > _prevCandle.OpenPrice;
var wideBearish = (_prevCandle.HighPrice - _prevCandle.LowPrice) > RangeThreshold &&
_prevCandle.OpenPrice > _prevCandle.ClosePrice &&
(_prevCandle.OpenPrice - _prevCandle.ClosePrice) > BodyThreshold;
var midnightSell = midnight &&
_prevDailyOpen is decimal dayOpenSell &&
_prevDailyClose is decimal dayCloseSell &&
dayOpenSell < dayCloseSell &&
(dayCloseSell - dayOpenSell) > DailyReversalThreshold;
var shortSignal = bearishCross || wideBearish || midnightSell;
if (longSignal && shortSignal)
{
// Break ties with the latest EMA relationship.
if (_fastPrev.Value >= _slowPrev.Value)
shortSignal = false;
else
longSignal = false;
}
if (longSignal && OrderVolume > 0m)
{
BuyMarket();
_entryPrice = candle.ClosePrice;
_stopPrice = StopLoss > 0m ? _entryPrice - StopLoss : null;
_takeProfitPrice = TakeProfit > 0m ? _entryPrice + TakeProfit : null;
_trailingStopPrice = TrailingStop > 0m ? _entryPrice - TrailingStop : null;
}
else if (shortSignal && OrderVolume > 0m)
{
SellMarket();
_entryPrice = candle.ClosePrice;
_stopPrice = StopLoss > 0m ? _entryPrice + StopLoss : null;
_takeProfitPrice = TakeProfit > 0m ? _entryPrice - TakeProfit : null;
_trailingStopPrice = TrailingStop > 0m ? _entryPrice + TrailingStop : null;
}
}
// Preserve history to mimic the MQL index-based access pattern.
_prevPrevCandle = _prevCandle;
_prevCandle = candle;
_fastPrev2 = _fastPrev;
_fastPrev = fastEma;
_slowPrev2 = _slowPrev;
_slowPrev = slowEma;
}
private void ManageOpenPosition(ICandleMessage candle)
{
if (Position > 0m)
{
UpdateTrailingStopForLong(candle);
var exit = AreEmaNear(_fastPrev, _slowPrev);
if (!exit && _takeProfitPrice is decimal tp && candle.HighPrice >= tp)
exit = true;
if (!exit && _stopPrice is decimal sl && candle.LowPrice <= sl)
exit = true;
if (!exit && _trailingStopPrice is decimal trail && candle.LowPrice <= trail)
exit = true;
if (exit)
{
SellMarket();
ClearTradeLevels();
}
}
else if (Position < 0m)
{
UpdateTrailingStopForShort(candle);
var exit = AreEmaNear(_fastPrev, _slowPrev);
if (!exit && _takeProfitPrice is decimal tp && candle.LowPrice <= tp)
exit = true;
if (!exit && _stopPrice is decimal sl && candle.HighPrice >= sl)
exit = true;
if (!exit && _trailingStopPrice is decimal trail && candle.HighPrice >= trail)
exit = true;
if (exit)
{
BuyMarket();
ClearTradeLevels();
}
}
}
private void UpdateTrailingStopForLong(ICandleMessage candle)
{
if (TrailingStop <= 0m || _entryPrice is not decimal entry)
return;
var move = candle.HighPrice - entry;
if (move < TrailingStop)
return;
var newStop = candle.HighPrice - TrailingStop;
if (_trailingStopPrice is null || newStop > _trailingStopPrice)
_trailingStopPrice = newStop;
}
private void UpdateTrailingStopForShort(ICandleMessage candle)
{
if (TrailingStop <= 0m || _entryPrice is not decimal entry)
return;
var move = entry - candle.LowPrice;
if (move < TrailingStop)
return;
var newStop = candle.LowPrice + TrailingStop;
if (_trailingStopPrice is null || newStop < _trailingStopPrice)
_trailingStopPrice = newStop;
}
private static bool AreEmaNear(decimal? fast, decimal? slow)
{
if (fast is not decimal fastValue || slow is not decimal slowValue)
return false;
if (slowValue == 0m)
return false;
var diff = Math.Abs(fastValue - slowValue);
return diff <= Math.Abs(slowValue) * 0.001m;
}
private void ClearTradeLevels()
{
_entryPrice = null;
_stopPrice = null;
_takeProfitPrice = null;
_trailingStopPrice = null;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates, Unit, UnitTypes
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class up3x1_premium_strategy(Strategy):
def __init__(self):
super(up3x1_premium_strategy, self).__init__()
self._order_volume = self.Param("OrderVolume", 1.0)
self._fast_ema_length = self.Param("FastEmaLength", 12)
self._slow_ema_length = self.Param("SlowEmaLength", 26)
self._take_profit = self.Param("TakeProfit", 0.015)
self._stop_loss = self.Param("StopLoss", 0.01)
self._trailing_stop = self.Param("TrailingStop", 0.001)
self._range_threshold = self.Param("RangeThreshold", 0.006)
self._body_threshold = self.Param("BodyThreshold", 0.005)
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4)))
self._fast_prev = None
self._fast_prev2 = None
self._slow_prev = None
self._slow_prev2 = None
self._prev_candle_open = None
self._prev_candle_close = None
self._prev_candle_high = None
self._prev_candle_low = None
self._prev_prev_candle_open = None
self._entry_price = None
self._stop_price = None
self._take_profit_price = None
self._trailing_stop_price = None
@property
def OrderVolume(self):
return self._order_volume.Value
@OrderVolume.setter
def OrderVolume(self, value):
self._order_volume.Value = value
@property
def FastEmaLength(self):
return self._fast_ema_length.Value
@FastEmaLength.setter
def FastEmaLength(self, value):
self._fast_ema_length.Value = value
@property
def SlowEmaLength(self):
return self._slow_ema_length.Value
@SlowEmaLength.setter
def SlowEmaLength(self, value):
self._slow_ema_length.Value = value
@property
def TakeProfit(self):
return self._take_profit.Value
@TakeProfit.setter
def TakeProfit(self, value):
self._take_profit.Value = value
@property
def StopLoss(self):
return self._stop_loss.Value
@StopLoss.setter
def StopLoss(self, value):
self._stop_loss.Value = value
@property
def TrailingStop(self):
return self._trailing_stop.Value
@TrailingStop.setter
def TrailingStop(self, value):
self._trailing_stop.Value = value
@property
def RangeThreshold(self):
return self._range_threshold.Value
@RangeThreshold.setter
def RangeThreshold(self, value):
self._range_threshold.Value = value
@property
def BodyThreshold(self):
return self._body_threshold.Value
@BodyThreshold.setter
def BodyThreshold(self, value):
self._body_threshold.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(up3x1_premium_strategy, self).OnStarted2(time)
self._fast_prev = None
self._fast_prev2 = None
self._slow_prev = None
self._slow_prev2 = None
self._prev_candle_open = None
self._prev_candle_close = None
self._prev_candle_high = None
self._prev_candle_low = None
self._prev_prev_candle_open = None
self._entry_price = None
self._stop_price = None
self._take_profit_price = None
self._trailing_stop_price = None
fast_ema = ExponentialMovingAverage()
fast_ema.Length = self.FastEmaLength
slow_ema = ExponentialMovingAverage()
slow_ema.Length = self.SlowEmaLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast_ema, slow_ema, self.ProcessCandle).Start()
self.StartProtection(
Unit(2000.0, UnitTypes.Absolute),
Unit(1000.0, UnitTypes.Absolute))
def ProcessCandle(self, candle, fast_ema_val, slow_ema_val):
if candle.State != CandleStates.Finished:
return
fast_val = float(fast_ema_val)
slow_val = float(slow_ema_val)
close = float(candle.ClosePrice)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
open_price = float(candle.OpenPrice)
self._manage_open_position(candle)
have_history = (self._prev_candle_open is not None and
self._prev_prev_candle_open is not None and
self._fast_prev is not None and self._fast_prev2 is not None and
self._slow_prev is not None and self._slow_prev2 is not None)
tp = float(self.TakeProfit)
sl = float(self.StopLoss)
trail = float(self.TrailingStop)
range_th = float(self.RangeThreshold)
body_th = float(self.BodyThreshold)
if self.Position == 0 and have_history:
bullish_cross = (self._fast_prev2 < self._slow_prev2 and
self._fast_prev > self._slow_prev and
self._prev_prev_candle_open < self._prev_candle_open)
wide_bullish = (self._prev_candle_high is not None and
self._prev_candle_low is not None and
(self._prev_candle_high - self._prev_candle_low) > range_th and
self._prev_candle_close > self._prev_candle_open and
(self._prev_candle_close - self._prev_candle_open) > body_th)
long_signal = bullish_cross or wide_bullish
bearish_cross = (self._fast_prev2 > self._slow_prev2 and
self._fast_prev < self._slow_prev and
self._prev_prev_candle_open > self._prev_candle_open)
wide_bearish = (self._prev_candle_high is not None and
self._prev_candle_low is not None and
(self._prev_candle_high - self._prev_candle_low) > range_th and
self._prev_candle_open > self._prev_candle_close and
(self._prev_candle_open - self._prev_candle_close) > body_th)
short_signal = bearish_cross or wide_bearish
if long_signal and short_signal:
if self._fast_prev >= self._slow_prev:
short_signal = False
else:
long_signal = False
if long_signal:
self.BuyMarket()
self._entry_price = close
self._stop_price = close - sl if sl > 0.0 else None
self._take_profit_price = close + tp if tp > 0.0 else None
self._trailing_stop_price = close - trail if trail > 0.0 else None
elif short_signal:
self.SellMarket()
self._entry_price = close
self._stop_price = close + sl if sl > 0.0 else None
self._take_profit_price = close - tp if tp > 0.0 else None
self._trailing_stop_price = close + trail if trail > 0.0 else None
self._prev_prev_candle_open = self._prev_candle_open
self._prev_candle_open = open_price
self._prev_candle_close = close
self._prev_candle_high = high
self._prev_candle_low = low
self._fast_prev2 = self._fast_prev
self._fast_prev = fast_val
self._slow_prev2 = self._slow_prev
self._slow_prev = slow_val
def _manage_open_position(self, candle):
high = float(candle.HighPrice)
low = float(candle.LowPrice)
trail = float(self.TrailingStop)
if self.Position > 0:
if trail > 0.0 and self._entry_price is not None:
move = high - self._entry_price
if move >= trail:
new_stop = high - trail
if self._trailing_stop_price is None or new_stop > self._trailing_stop_price:
self._trailing_stop_price = new_stop
do_exit = False
if self._take_profit_price is not None and high >= self._take_profit_price:
do_exit = True
if not do_exit and self._stop_price is not None and low <= self._stop_price:
do_exit = True
if not do_exit and self._trailing_stop_price is not None and low <= self._trailing_stop_price:
do_exit = True
if not do_exit and self._are_ema_near():
do_exit = True
if do_exit:
self.SellMarket()
self._clear_trade_levels()
elif self.Position < 0:
if trail > 0.0 and self._entry_price is not None:
move = self._entry_price - low
if move >= trail:
new_stop = low + trail
if self._trailing_stop_price is None or new_stop < self._trailing_stop_price:
self._trailing_stop_price = new_stop
do_exit = False
if self._take_profit_price is not None and low <= self._take_profit_price:
do_exit = True
if not do_exit and self._stop_price is not None and high >= self._stop_price:
do_exit = True
if not do_exit and self._trailing_stop_price is not None and high >= self._trailing_stop_price:
do_exit = True
if not do_exit and self._are_ema_near():
do_exit = True
if do_exit:
self.BuyMarket()
self._clear_trade_levels()
def _are_ema_near(self):
if self._fast_prev is None or self._slow_prev is None:
return False
if self._slow_prev == 0.0:
return False
diff = abs(self._fast_prev - self._slow_prev)
return diff <= abs(self._slow_prev) * 0.001
def _clear_trade_levels(self):
self._entry_price = None
self._stop_price = None
self._take_profit_price = None
self._trailing_stop_price = None
def OnReseted(self):
super(up3x1_premium_strategy, self).OnReseted()
self._fast_prev = None
self._fast_prev2 = None
self._slow_prev = None
self._slow_prev2 = None
self._prev_candle_open = None
self._prev_candle_close = None
self._prev_candle_high = None
self._prev_candle_low = None
self._prev_prev_candle_open = None
self._clear_trade_levels()
def CreateClone(self):
return up3x1_premium_strategy()