动态多因子策略
策略其核心思想是通过多种技术指标的结合,动态调整交易信号,以实现更精准的市场进出和风险管理。
交易逻辑思路
1. 初始化与数据更新:
- 在每个Bar的开盘时,更新当日的最高价、最低价和收盘价。
- 计算短期和长期的移动平均线(MA)以及布林带的上轨、中轨和下轨。
2. 高低点突破判断:
- 通过比较当前价格与前一个Bar的价格,判断是否出现高点突破(DT)或低点突破(KT)。
- 进一步判断这些突破是否发生在移动平均线之上或之下。
3. 布林带计算:
- 使用不同周期的布林带来捕捉价格波动的范围和趋势。
- 布林带的上轨和下轨分别表示价格的高点和低点,中间线则表示价格的平均水平。
4. MACD指标计算:
- 计算不同周期的MACD值及其平均值,以及MACD差值。
- 通过MACD差值的正负来判断市场的多空趋势。
5. 入场条件判断:
- 结合MACD差值、高低点突破和布林带的位置,判断多头和空头的入场条件。
- 入场时需要满足特定的时间窗口和价格条件,以确保交易信号的有效性。
6. 出场条件判断:
- 设定跟踪止损机制,根据价格波动动态调整止损位。
- 当价格触及止损位或满足特定条件时,执行出场操作。
7. 过滤集合竞价:
- 在集合竞价期间,忽略交易信号,以避免因市场不稳定性导致的误操作。
策略特点
1. 多因子结合:
- 策略结合了移动平均线、布林带和MACD等多种技术指标,通过多因子的综合分析,提高交易信号的准确性和可靠性。
2. 动态调整:
- 根据市场情况动态调整布林带和MACD的计算参数,以适应不同市场环境下的交易需求。
3. 风险管理:
- 设定明确的入场和出场条件,结合跟踪止损机制,有效控制风险,保护投资收益。
4. 时间窗口限制:
- 仅在特定的开仓时间和截止时间内进行交易,避免在非交易时段产生不必要的交易信号。
5. 过滤机制:
- 通过过滤集合竞价和不满足条件的时间段,减少噪音干扰,提高策略的执行效率。
该策略通过多因子的综合分析和动态调整,旨在实现更精准的市场进出和风险管理,适用于多种市场环境下的交易需求。
策略思维导图:
//------------------------------------------------------------------------
// 简称: MyStrategy
// 名称: 动态多因子策略
// 类别: 公式应用
// 类型: 用户应用
// 输出:
//------------------------------------------------------------------------
Params
Numeric p_param1(1.3); // 系数
Numeric p_param2(0.7); // 系数
Numeric Length(127); // 布林轨周期
Numeric Length1(7); // 布林轨周期
Numeric TrailingStart(200); // 跟踪止损启动点
Numeric TrailingStop(25); // 跟踪止损幅度
Numeric tradBegin(900); // 开仓时间
Numeric tradEnd(2330); // 开仓截止时间
Numeric FastLength(4); // 快速均线周期
Numeric SlowLength(8); // 慢速均线周期
Numeric MACDLength(3); // MACD 均线周期
Numeric Offset(2); // 布林轨偏移
Numeric Offset1(2); // 布林轨偏移
Numeric OffsetPoint(2); // 偏移点数
Vars
Numeric p_dParam1(2); // 周期
Numeric p_dParam2(4); // 周期
Series<Numeric> MA1; // 均线1
Series<Numeric> MA2; // 均线2
Series<Numeric> MA3; // 均线3
Series<Bool> DT; // 高点突破标志
Series<Bool> KT; // 低点突破标志
Series<Bool> DT1; // 高点突破标志1
Series<Bool> KT1; // 低点突破标志1
Series<Bool> DT2; // 高点突破标志2
Series<Bool> KT2; // 低点突破标志2
Series<Bool> DT3; // 高点突破标志3
Series<Bool> KT3; // 低点突破标志3
Series<Bool> Condition1; // 条件1
Series<Bool> Condition2; // 条件2
Series<Bool> Condition3; // 条件3
Series<Bool> Condition4; // 条件4
Series<Numeric> UpLine; // 上轨
Series<Numeric> DownLine; // 下轨
Series<Numeric> MidLine; // 中间线
Series<Numeric> Band; // 布林带宽度
Series<Numeric> UpLine1; // 上轨1
Series<Numeric> DownLine1; // 下轨1
Series<Numeric> MidLine1; // 中间线1
Series<Numeric> Band1; // 布林带宽度1
Numeric MyExitPrice; // 出场价格
Series<Numeric> MACDValue1; // MACD值1
Series<Numeric> MACDValue3; // MACD值3
Series<Numeric> MACDValue5; // MACD值5
Series<Numeric> MACDValue15; // MACD值15
Series<Numeric> MACDValue30; // MACD值30
Series<Numeric> AvgMACD1; // MACD均线1
Series<Numeric> AvgMACD3; // MACD均线3
Series<Numeric> AvgMACD5; // MACD均线5
Series<Numeric> AvgMACD15; // MACD均线15
Series<Numeric> AvgMACD30; // MACD均线30
Series<Numeric> MACDDiff1; // MACD差值1
Series<Numeric> MACDDiff3; // MACD差值3
Series<Numeric> MACDDiff5; // MACD差值5
Series<Numeric> MACDDiff15; // MACD差值15
Series<Numeric> MACDDiff30; // MACD差值30
Series<Bool> LongEntryCon; // 多头入场条件
Series<Bool> ShortEntryCon; // 空头入场条件
Series<Bool> LongExitCon; // 多头出场条件
Series<Bool> ShortExitCon; // 空头出场条件
Numeric m_buyRange; // 买入范围
Numeric m_sellRange; // 卖出范围
Numeric m_upper; // 上轨
Numeric m_lower; // 下轨
Numeric m_minPoint; // 最小变动点
Numeric m_offset; // 偏移
Series<Numeric> m_barCnt; // 当前Bar计数
Series<Numeric> m_dayHigh; // 当日高点
Series<Numeric> m_dayLow; // 当日低点
Series<Numeric> m_dayClose; // 当日收盘价
Numeric m_highest; // 最高价
Numeric m_lowest; // 最低价
Numeric m_closeHigh; // 收盘高点
Numeric m_closeLow; // 收盘低点
Numeric i; // 循环变量
Numeric n; // 临时变量
Series<Numeric> HighestAfterEntry; // 多头盈利峰值价
Series<Numeric> LowestAfterEntry; // 空头盈利峰值价
Numeric StopLine; // 止损线
Series<Bool> bOut; // 出场标志
Numeric MyPrice; // 我的价格
Series<Numeric> ATRDD; // ATR吊灯止损
Events
OnBar(ArrayRef<Integer> indexs)
{
// 初始化变量
If(CurrentBar == 0 || Date != Date[1])
{
m_barCnt = 1;
m_dayHigh = High;
m_dayLow = Low;
}
Else
{
m_barCnt = m_barCnt + 1;
If(High > m_dayHigh)
m_dayHigh = High;
If(Low < m_dayLow)
m_dayLow = Low;
}
m_dayClose = Close;
// 计算均线
MA1 = AverageFC((High + Low + Close) / 3, MACDLength);
MA2 = AverageFC((High + Low + Close) / 3, FastLength);
MA3 = AverageFC((High + Low + Close) / 3, SlowLength);
// 判断高低点突破
DT = High > High[1];
KT = Low < Low[1];
DT1 = High > MA1;
KT1 = Low < MA1;
DT2 = MA1 > MA2;
KT2 = MA1 < MA2;
DT3 = MA2 > MA3;
KT3 = MA2 < MA3;
// 计算布林带
MidLine = AverageFC(Close, Length);
Band = StandardDev(Close, Length, 2);
UpLine = MidLine + Offset * Band;
DownLine = MidLine - Offset * Band;
MidLine1 = AverageFC(Close, Length - Length1);
Band1 = StandardDev(Close, Length - Length1, 2);
UpLine1 = MidLine1 + Offset1 * Band1;
DownLine1 = MidLine1 - Offset1 * Band1;
// 判断条件
Condition1 = UpLine1[1] < UpLine[1];
Condition2 = DownLine1[1] > DownLine[1];
Condition3 = UpLine1[1] > UpLine[1];
Condition4 = DownLine1[1] < DownLine[1];
// 计算MACD
MACDValue1 = XAverage((Low + High + Close) / 3, FastLength) - XAverage((Low + High + Close) / 3, SlowLength);
AvgMACD1 = XAverage(MACDValue1, MACDLength);
MACDDiff1 = MACDValue1 - AvgMACD1;
MACDValue3 = MinsXAverage(3, (Low + High + Close) / 3, FastLength) - MinsXAverage(3, (Low + High + Close) / 3, SlowLength);
AvgMACD3 = MinsXAverage(3, MACDValue3, MACDLength);
MACDDiff3 = MACDValue3 - AvgMACD3;
MACDValue5 = MinsXAverage(5, (Low + High + Close) / 3, FastLength) - MinsXAverage(5, (Low + High + Close) / 3, SlowLength);
AvgMACD5 = MinsXAverage(5, MACDValue5, MACDLength);
MACDDiff5 = MACDValue5 - AvgMACD5;
MACDValue15 = MinsXAverage(8, (Low + High + Close) / 3, FastLength) - MinsXAverage(8, (Low + High + Close) / 3, SlowLength);
AvgMACD15 = MinsXAverage(8, MACDValue15, MACDLength);
MACDDiff15 = MACDValue15 - AvgMACD15;
MACDValue30 = MinsXAverage(35, (Low + High + Close) / 3, FastLength) - MinsXAverage(35, (Low + High + Close) / 3, SlowLength);
AvgMACD30 = MinsXAverage(35, MACDValue30, MACDLength);
MACDDiff30 = MACDValue30 - AvgMACD30;
// 判断入场条件
LongEntryCon = MACDDiff1 > 0 && MACDDiff3 > 0 && MACDDiff5 > 0 && MACDDiff15 > 0 && MACDDiff30 > 0;
ShortEntryCon = MACDDiff1 < 0 && MACDDiff3 < 0 && MACDDiff5 < 0 && MACDDiff15 < 0 && MACDDiff30 < 0;
LongExitCon = MACDDiff15 < 0;
ShortExitCon = MACDDiff15 > 0;
// 过滤集合竞价
If(BarStatus == 2 && Time == 0.090000 && High == Low) return; // 集合竞价过滤1
If(BarStatus == 2 && Time == 0.090000 && CurrentTime < 0.090000) return; // 集合竞价过滤2
// 计算买入和卖出范围
For i = 1 To p_dParam1
{
If(i == 1)
{
n = m_barCnt;
m_highest = m_dayHigh[n];
m_lowest = m_dayLow[n];
m_closeHigh = m_dayClose[n];
m_closeLow = m_dayClose[n];
}
Else
{
n = n + m_barCnt[n];
}
If(m_dayHigh[n] > m_highest) m_highest = m_dayHigh[n];
If(m_dayLow[n] < m_lowest) m_lowest = m_dayLow[n];
If(m_dayClose[n] > m_closeHigh) m_closeHigh = m_dayClose[n];
If(m_dayClose[n] < m_closeLow) m_closeLow = m_dayClose[n];
}
m_buyRange = Max(m_highest - m_closeLow, m_closeHigh - m_lowest);
For i = 1 To p_dParam2
{
If(i == 1)
{
n = m_barCnt;
m_highest = m_dayHigh[n];
m_lowest = m_dayLow[n];
m_closeHigh = m_dayClose[n];
m_closeLow = m_dayClose[n];
}
Else
{
n = n + m_barCnt[n];
}
If(m_dayHigh[n] > m_highest) m_highest = m_dayHigh[n];
If(m_dayLow[n] < m_lowest) m_lowest = m_dayLow[n];
If(m_dayClose[n] > m_closeHigh) m_closeHigh = m_dayClose[n];
If(m_dayClose[n] < m_closeLow) m_closeLow = m_dayClose[n];
}
m_sellRange = Max(m_highest - m_closeLow, m_closeHigh - m_lowest);
// 计算上下轨
m_upper = OpenD(0) + m_buyRange * p_param1;
m_lower = OpenD(0) - m_sellRange * p_param2;
m_minPoint = PriceScale * MinMove;
// 开仓逻辑
If(MarketPosition != 1 && Time >= 0.0001 * tradBegin And Time <= tradEnd * 0.0001 And Condition2[1] And Open > MidLine[1])
{
If(High >= m_upper AND LongEntryCon[1] And DT1[1] And DT2[1] And DT3[1])
{
Buy(0, Max(Open, m_upper));
Return;
}
}
If(MarketPosition != 1 && Time >= 0.0001 * tradBegin And Time <= tradEnd * 0.0001 And Condition3[1] And Open > MidLine[1])
{
If(High >= m_upper)
{
Buy(0, Max(Open, m_upper));
Return;
}
}
If(MarketPosition != -1 && Time >= 0.0001 * tradBegin And Time <= tradEnd * 0.0001 And Condition1[1] And Open < MidLine[1])
{
If(Low <= m_lower AND ShortEntryCon[1] And KT1[1] And KT2[1] And KT3[1])
{
SellShort(0, Min(Open, m_lower));
Return;
}
}
If(MarketPosition != -1 && Time >= 0.0001 * tradBegin And Time <= tradEnd * 0.0001 And Condition4[1] And Open < MidLine[1])
{
If(Low <= m_lower)
{
SellShort(0, Min(Open, m_lower));
Return;
}
}
// 跟踪止损逻辑
If(BarsSinceEntry == 1)
{
HighestAfterEntry = AvgEntryPrice;
LowestAfterEntry = AvgEntryPrice;
}
Else If(BarsSinceEntry > 1)
{
HighestAfterEntry = Max(HighestAfterEntry[1], High[1]);
LowestAfterEntry = Min(LowestAfterEntry[1], Low[1]);
}
Else
{
HighestAfterEntry = HighestAfterEntry[1];
LowestAfterEntry = LowestAfterEntry[1];
}
If(MarketPosition == 1 And BarsSinceEntry > 0)
{
If(Close[1] <= EntryPrice - EntryPrice * TrailingStop / 1000)
{
Sell(0, Open);
PlotString("Mark", "止损", Low, White);
}
}
If(MarketPosition == -1 And BarsSinceEntry > 0)
{
If(Close[1] >= EntryPrice + EntryPrice * TrailingStop / 1000)
{
BuyToCover(0, Open);
PlotString("Mark", "止损", Low, White);
}
}
If(MarketPosition == 1 And BarsSinceEntry > 0 And HighestAfterEntry >= EntryPrice * (1 + TrailingStart / 1000))
{
If(Low <= HighestAfterEntry[1] - EntryPrice * TrailingStop / 1000)
{
MyPrice = HighestAfterEntry[1] - EntryPrice * TrailingStop / 1000;
If(Open < MyPrice) MyPrice = Open;
Sell(0, MyPrice);
bOut = True;
}
}
If(MarketPosition == -1 And BarsSinceEntry > 0 And LowestAfterEntry <= EntryPrice * (1 - TrailingStart / 1000))
{
If(High >= LowestAfterEntry[1] + EntryPrice * TrailingStop / 1000)
{
MyPrice = LowestAfterEntry[1] + EntryPrice * TrailingStop / 1000;
If(Open > MyPrice) MyPrice = Open;
BuyToCover(0, MyPrice);
bOut = True;
}
}
}
//------------------------------------------------------------------------
// 编译版本 GS2024.10.21
// 版权所有 TradeBlazer Software 2003-2025
// 更改声明 TradeBlazer Software保留对TradeBlazer平台每一版本的TradeBlazer公式修改和重写的权利
//------------------------------------------------------------------------