Params
Numeric FastLength(10);
Numeric SlowLength(20); // 缩短周期,增加信号
Numeric Lots(10);
Numeric SlipPoint(0);
Numeric TrendPeriod(30);
Numeric TrendMode(0);
Numeric TrendATRMult(1.0);
Numeric VolumePeriod(20);
Numeric VolumeRatio(0);
Numeric ATRPeriod(14);
Numeric ATRFilter(0);
Numeric ADXPeriod(14);
Numeric ADXThreshold(0);
Numeric StopLossATR(2);
Numeric TakeProfitATR(0);
Numeric MinBars(1);
Numeric BreakoutFactor(0.8); // 同时降低多空阈值
Numeric StartTime(0.090000);
Numeric EndTime(0.150000);
Bool CloseAtEnd(True);
Vars
Series<Numeric> SlowHigh;
Series<Numeric> SlowLow;
Series<Numeric> FastHigh;
Series<Numeric> FastLow;
Series<Numeric> VolumeMA;
Series<Numeric> TrendMA;
Series<Numeric> ShortTrendMA;
Series<Numeric> LongTrendMA;
Series<Numeric> ATR;
Series<Numeric> ChannelWidth;
Series<Numeric> MyADX;
Bool BuyCond;
Bool ShortCond;
Bool ExitLongCond;
Bool ExitShortCond;
Series<Numeric> HighestAfterEntry;
Series<Numeric> LowestAfterEntry;
Series<Numeric> StopPrice;
// 多空独立信号计数器
Series<Integer> LongSignalCount;
Series<Integer> ShortSignalCount;
Bool LongSignalConfirmed;
Bool ShortSignalConfirmed;
Series<Numeric> MyEntryPrice;
Series<Numeric> TR;
Series<Numeric> PlusDM;
Series<Numeric> MinusDM;
Series<Numeric> SPlusDM;
Series<Numeric> SMinusDM;
Series<Numeric> ATR14;
Series<Numeric> DX;
Numeric DIPlus;
Numeric DIMinus;
Bool TimeOK;
Events
OnInit()
{
AddDataFlag(Enum_Data_RolloverBackWard());
AddDataFlag(Enum_Data_RolloverRealPrice());
AddDataFlag(Enum_Data_AutoSwapPosition());
AddDataFlag(Enum_Data_IgnoreSwapSignalCalc());
}
OnBar(ArrayRef<Integer> indexs)
{
SlowHigh = Highest(High[1], SlowLength);
SlowLow = Lowest(Low[1], SlowLength);
FastHigh = Highest(High[1], FastLength);
FastLow = Lowest(Low[1], FastLength);
VolumeMA = Average(Vol, VolumePeriod);
TrendMA = Average(Close, TrendPeriod);
ATR = AvgTrueRange(ATRPeriod);
ChannelWidth = SlowHigh - SlowLow;
ShortTrendMA = Average(Close, 5);
LongTrendMA = Average(Close, 20);
// ADX 计算(略)
TR = Max(High - Low, Max(Abs(High - Close[1]), Abs(Low - Close[1])));
If(High - High[1] > Low[1] - Low)
PlusDM = Max(High - High[1], 0);
Else
PlusDM = 0;
If(Low[1] - Low > High - High[1])
MinusDM = Max(Low[1] - Low, 0);
Else
MinusDM = 0;
If(CurrentBar == 0)
{
SPlusDM = PlusDM;
SMinusDM = MinusDM;
ATR14 = TR;
}
Else
{
SPlusDM = SPlusDM[1] - SPlusDM[1]/ADXPeriod + PlusDM;
SMinusDM = SMinusDM[1] - SMinusDM[1]/ADXPeriod + MinusDM;
ATR14 = ATR14[1] - ATR14[1]/ADXPeriod + TR;
}
If(ATR14 != 0)
{
DIPlus = (SPlusDM / ATR14) * 100;
DIMinus = (SMinusDM / ATR14) * 100;
}
Else
{
DIPlus = 0;
DIMinus = 0;
}
If(DIPlus + DIMinus != 0)
DX = Abs(DIPlus - DIMinus) / (DIPlus + DIMinus) * 100;
Else
DX = 0;
If(CurrentBar < ADXPeriod)
MyADX = DX;
Else
MyADX = (MyADX[1] * (ADXPeriod-1) + DX) / ADXPeriod;
// 趋势过滤
Bool TrendOK_Long = True;
Bool TrendOK_Short = True;
If(TrendMode == 1)
{
TrendOK_Long = Close > TrendMA;
TrendOK_Short = Close < TrendMA;
}
Else If(TrendMode == 2)
{
TrendOK_Long = ShortTrendMA > LongTrendMA;
TrendOK_Short = ShortTrendMA < LongTrendMA;
}
Else If(TrendMode == 3)
{
TrendOK_Long = Close > TrendMA - ATR * TrendATRMult;
TrendOK_Short = Close < TrendMA + ATR * TrendATRMult;
}
// 其他过滤
Bool VolumeSurge = (VolumeRatio <= 0) OR (Vol > VolumeMA * VolumeRatio);
Bool WidthOK = (ATRFilter <= 0) OR (ChannelWidth > ATR * ATRFilter);
Bool ADXOK = (ADXThreshold <= 0) OR (MyADX > ADXThreshold);
TimeOK = (Time >= StartTime && Time <= EndTime);
// 对称阈值
Numeric BuyThreshold = SlowHigh * BreakoutFactor;
Numeric SellThreshold = SlowLow * BreakoutFactor;
// 多空独立信号确认
If(Close > SlowHigh)
LongSignalCount = LongSignalCount + 1;
Else
LongSignalCount = 0;
If(Close < SlowLow)
ShortSignalCount = ShortSignalCount + 1;
Else
ShortSignalCount = 0;
LongSignalConfirmed = LongSignalCount >= MinBars;
ShortSignalConfirmed = ShortSignalCount >= MinBars;
// 开仓条件
If(MarketPosition != 1 && Close > BuyThreshold && TrendOK_Long && VolumeSurge && WidthOK && ADXOK && LongSignalConfirmed && TimeOK)
BuyCond = True;
Else
BuyCond = False;
If(MarketPosition != -1 && Close < SellThreshold && TrendOK_Short && VolumeSurge && WidthOK && ADXOK && ShortSignalConfirmed && TimeOK)
ShortCond = True;
Else
ShortCond = False;
// 持仓管理
If(BarsSinceEntry == 0)
{
HighestAfterEntry = High;
LowestAfterEntry = Low;
MyEntryPrice = EntryPrice;
}
Else
{
HighestAfterEntry = Max(HighestAfterEntry, High);
LowestAfterEntry = Min(LowestAfterEntry, Low);
}
If(MarketPosition == 1)
{
StopPrice = HighestAfterEntry - ATR * StopLossATR;
ExitLongCond = Low <= StopPrice[1];
If(TakeProfitATR > 0)
{
Numeric Profit = Close - MyEntryPrice;
If(Profit > ATR * TakeProfitATR) ExitLongCond = True;
}
}
Else If(MarketPosition == -1)
{
StopPrice = LowestAfterEntry + ATR * StopLossATR;
ExitShortCond = High >= StopPrice[1];
If(TakeProfitATR > 0)
{
Numeric Profit = MyEntryPrice - Close;
If(Profit > ATR * TakeProfitATR) ExitShortCond = True;
}
}
// 执行交易
If(BuyCond) Buy(Lots, Open + SlipPoint);
If(ShortCond) SellShort(Lots, Open - SlipPoint);
If(ExitLongCond) Sell(Lots, Open - SlipPoint);
If(ExitShortCond) BuyToCover(Lots, Open + SlipPoint);
If(CloseAtEnd && Time >= EndTime)
{
If(MarketPosition == 1) Sell(Lots, Open);
If(MarketPosition == -1) BuyToCover(Lots, Open);
}
// 画线
PlotNumeric("20High", SlowHigh);
PlotNumeric("20Low", SlowLow);
PlotNumeric("ATRStop", StopPrice);
PlotNumeric("30MA", TrendMA);
}