Geo 策略
当蜡烛高低比接近黄金分割时买入的策略。
细节
- 入场条件:高低比在 φ 容差范围内。
- 多/空:双向。
- 出场条件:相反条件。
- 止损:无。
- 默认值:
Tolerance= 1CandleType= TimeSpan.FromMinutes(5)
- 过滤器:
- 类别:形态
- 方向:双向
- 指标:蜡烛比率
- 止损:无
- 复杂度:基础
- 时间框架:日内 (5m)
- 季节性:无
- 神经网络:无
- 背离:无
- 风险等级:中等
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Geo strategy.
/// The candle is split at its close into the part above the low and the part below the high. When the lower part divided by the upper
/// part is within Tolerance percent of the golden ratio the close sits at the upper golden section and the strategy goes long; when the
/// upper part divided by the lower part is within tolerance it goes short. The opposite condition reverses the position.
/// </summary>
public class GeoStrategy : Strategy
{
private const decimal _phi = 1.6180339887m;
private readonly StrategyParam<decimal> _tolerance;
private readonly StrategyParam<DataType> _candleType;
/// <summary>
/// Allowed deviation from the golden ratio in percent.
/// </summary>
public decimal Tolerance
{
get => _tolerance.Value;
set => _tolerance.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public GeoStrategy()
{
_tolerance = Param(nameof(Tolerance), 1m)
.SetNotNegative()
.SetDisplay("Tolerance", "Allowed deviation from the golden ratio in percent", "Trading");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).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 OnStarted2(DateTime time)
{
base.OnStarted2(time);
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 lowerPart = candle.ClosePrice - candle.LowPrice;
var upperPart = candle.HighPrice - candle.ClosePrice;
if (lowerPart <= 0 || upperPart <= 0)
return;
var allowed = _phi * Tolerance / 100m;
if (Math.Abs(lowerPart / upperPart - _phi) <= allowed && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (Math.Abs(upperPart / lowerPart - _phi) <= allowed && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
}
}
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 geo_strategy(Strategy):
"""
Geo strategy.
The candle is split at its close into the part above the low and the part below the high. When the lower part divided by the upper
part is within Tolerance percent of the golden ratio the close sits at the upper golden section and the strategy goes long; when the
upper part divided by the lower part is within tolerance it goes short. The opposite condition reverses the position.
"""
PHI = Decimal(1.6180339887)
def __init__(self):
super(geo_strategy, self).__init__()
self._tolerance = self.Param("Tolerance", 1.0).SetNotNegative().SetDisplay("Tolerance", "Allowed deviation from the golden ratio in percent", "Trading")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Type of candles to use", "General")
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(geo_strategy, self).OnStarted2(time)
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
lower_part = candle.ClosePrice - candle.LowPrice
upper_part = candle.HighPrice - candle.ClosePrice
if lower_part <= 0 or upper_part <= 0:
return
allowed = self.PHI * Decimal(self._tolerance.Value) / Decimal(100)
if abs(lower_part / upper_part - self.PHI) <= allowed and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif abs(upper_part / lower_part - self.PHI) <= allowed and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
def CreateClone(self):
return geo_strategy()