根据学习,要求只在K线结束后观察是否满足开仓条件,不在K线生成过程中观察,满足后即在下根K线开盘价时开仓。
我也照做了,但现在还是遇到了信号闪烁的问题,多仓和空仓处不停的信号在来回跳动。
社区里说,把判断条件的参数调整为序时变量即可,把下面代码中的哪个调整为序时变量呢?。
请问有没有什么好办法阻止信号闪烁呢?
1、开多仓条件,观察第1根、第2根K线,第2根K线外包信第1根K线,收盘价高于第1根K线且在EMA20均线上,以第3根K线开盘价开多单。 2、开空单与开多单条件相反。 3、止损:1倍14周期ATR。 4、止盈:1.5倍14周期ATR。
Params
//此处添加参数
Numeric millsecs(1000);
Numeric ATRLength(14); // ATR周期
Numeric EMALength(20); // EMA周期
Numeric StopLossRatio(1); // 止损倍数
Numeric StopProfitRatio(1.5); // 止盈倍数
Numeric TradeVolume(1); // 交易手数
Vars
//此处添加变量
Numeric EMA20; // EMA20均线
Numeric ATR14; // 14周期ATR
Bool IsFirstBar; // 是否是第一根K线
Bool IsSecondBar; // 是否是第二根K线
Numeric FirstHigh; // 第一根K线最高价
Numeric FirstLow; // 第一根K线最低价
Numeric FirstClose; // 第一根K线收盘价
Numeric SecondHigh; // 第二根K线最高价
Numeric SecondLow; // 第二根K线最低价
Numeric SecondClose; // 第二根K线收盘价
Global Integer timerId;
Numeric EntryPrice; // 入场价格
Numeric StopLossPrice; // 止损价格
Numeric StopProfitPrice; // 止盈价格
Bool LongCondition; // 开多条件
Bool ShortCondition; // 开空条件
Bool orderSuccess; // 订单成功标志
Defs
//此处添加公式函数
Numeric calcAvg(Numeric a,Numeric b)
{
return (a+b)/2;
}
// 判断外包函数
Bool IsOutsideBar(Numeric prevHigh, Numeric prevLow, Numeric currHigh, Numeric currLow)
{
return currHigh >= prevHigh && currLow <= prevLow;
}
Events
//此处实现事件函数
//初始化事件函数,策略运行期间,首先运行且只有一次,应用在订阅数据等操作
OnInit()
{
timerId=createTimer(millsecs);
IsFirstBar = False;
IsSecondBar = False;
LongCondition = False;
ShortCondition = False;
}
//Bar更新事件函数,参数indexs表示变化的数据源图层ID数组
OnBar(ArrayRef<Integer> indexs)
{
// 计算技术指标
EMA20 = XAverage(Close, EMALength);
ATR14 = AvgTrueRange(ATRLength);
// 记录K线数据
if (!IsFirstBar && !IsSecondBar)
{
// 第一根K线
IsFirstBar = True;
FirstHigh = High;
FirstLow = Low;
FirstClose = Close;
}
else if (IsFirstBar && !IsSecondBar)
{
// 第二根K线
IsSecondBar = True;
SecondHigh = High;
SecondLow = Low;
SecondClose = Close;
// 判断开仓条件
LongCondition = IsOutsideBar(FirstHigh, FirstLow, SecondHigh, SecondLow) &&
SecondClose > FirstClose &&
SecondClose > EMA20;
ShortCondition = IsOutsideBar(FirstHigh, FirstLow, SecondHigh, SecondLow) &&
SecondClose < FirstClose &&
SecondClose < EMA20;
}
else if (IsFirstBar && IsSecondBar)
{
// 第三根K线 - 执行开仓
if (LongCondition && MarketPosition != 1)
{
// 开多单
orderSuccess = Buy(TradeVolume, Open);
if (orderSuccess)
{
// 开多成功,设置止损止盈
EntryPrice = Open;
StopLossPrice = EntryPrice - ATR14 * StopLossRatio;
StopProfitPrice = EntryPrice + ATR14 * StopProfitRatio;
}
// 重置条件
IsFirstBar = False;
IsSecondBar = False;
LongCondition = False;
}
else if (ShortCondition && MarketPosition != -1)
{
// 开空单
orderSuccess = SellShort(TradeVolume, Open);
if (orderSuccess)
{
// 开空成功,设置止损止盈
EntryPrice = Open;
StopLossPrice = EntryPrice + ATR14 * StopLossRatio;
StopProfitPrice = EntryPrice - ATR14 * StopProfitRatio;
}
// 重置条件
IsFirstBar = False;
IsSecondBar = False;
ShortCondition = False;
}
else
{
// 开仓失败或无仓位变化,重置条件
IsFirstBar = False;
IsSecondBar = False;
LongCondition = False;
ShortCondition = False;
}
}
// 检查止损止盈
if (MarketPosition == 1) // 持有多头仓位
{
if (Low <= StopLossPrice)
{
// 止损平仓
Sell(TradeVolume, StopLossPrice);
}
else if (High >= StopProfitPrice)
{
// 止盈平仓
Sell(TradeVolume, StopProfitPrice);
}
}
else if (MarketPosition == -1) // 持有空头仓位
{
if (High >= StopLossPrice)
{
// 止损平仓
BuyToCover(TradeVolume, StopLossPrice);
}
else if (Low <= StopProfitPrice)
{
// 止盈平仓
BuyToCover(TradeVolume, StopProfitPrice);
}
}
}
//在新bar的第一次执行之前调用一次,参数为新bar的图层数组
OnBarOpen(ArrayRef<Integer> indexs)
{
}
//下一个Bar开始前,重新执行当前bar最后一次,参数为当前bar的图层数组
OnBarClose(ArrayRef<Integer> indexs)
{
}
//Tick更新事件函数,需要SubscribeTick函数订阅后触发,参数evtTick表示更新的tick结构体
OnTick(TickRef evtTick)
{
}
//持仓更新事件函数,参数pos表示更新的持仓结构体
OnPosition(PositionRef pos)
{
}
//策略账户仓更新事件函数,参数pos表示更新的账户仓结构体
OnStrategyPosition(PositionRef pos)
{
}
//委托更新事件函数,参数ord表示更新的委托结构体
OnOrder(OrderRef ord)
{
}
//成交更新事件函数,参数ordFill表示更新的成交结构体
OnFill(FillRef ordFill)
{
}
//定时器更新事件函数,参数id表示定时器的编号,millsecs表示定时间的间隔毫秒值
OnTimer(Integer id,Integer intervalMillsecs)
{
}
//通用事件触发函数,参数evtName为事件名称,参数evtValue为事件内容
OnEvent(StringRef evtName,MapRef<String,String> evtValue)
{
}
//当前策略退出时触发
OnExit()
{
}
看不明白你这写的什么东西
请高手指点