//------------------------------------------------------------------------
// 简称: FANZHUAN1M
// 名称: 1分钟反转挂条件单策略
//------------------------------------------------------------------------
Params
Numeric Lots(1);
Numeric PriceOffset(1);
Bool EnableLimitOrder(True);
Vars
Numeric prevClose;
Numeric prevOpen;
Bool prevIsYin(False);
Bool prevIsYang(False);
Numeric targetPrice;
Bool needReverse(False);
Bool orderExecuted(False); // 控制单根K线只执行一次
Events
OnBar(ArrayRef<Integer> indexs)
{
orderExecuted = False; // 每根K线重置
If(CurrentBar > 1 And orderExecuted == False)
{
prevClose = Close[1];
prevOpen = Open[1];
prevIsYin = (prevClose < prevOpen);
prevIsYang = (prevClose > prevOpen);
Commentary("K线" + Text(CurrentBar) + ": 前一根" +
IIfString(prevIsYin, "阴柱", IIfString(prevIsYang, "阳柱", "平线")));
needReverse = False;
If(MarketPosition == -1 And prevIsYin) needReverse = True;
If(MarketPosition == 1 And prevIsYang) needReverse = True;
// --- 统一的执行逻辑(确保单根K线只执行一次)---
// 情况1:需要反向操作(先平后开)
If(needReverse And orderExecuted == False)
{
// 平仓操作
If(MarketPosition == -1) // 平空仓
{
If(EnableLimitOrder)
{
targetPrice = Open - PriceOffset * MinMove * PriceScale;
If(targetPrice >= Low)
{
BuyToCover(0, targetPrice);
orderExecuted = True;
Commentary("→ 限价平空仓:" + Text(targetPrice));
}
}
If(orderExecuted == False) // 限价单未成交,市价确保
{
BuyToCover(0, Close);
orderExecuted = True;
Commentary("→ 市价平空仓");
}
}
Else If(MarketPosition == 1) // 平多仓
{
If(EnableLimitOrder)
{
targetPrice = Open + PriceOffset * MinMove * PriceScale;
If(targetPrice <= High)
{
Sell(0, targetPrice);
orderExecuted = True;
Commentary("→ 限价平多仓:" + Text(targetPrice));
}
}
If(orderExecuted == False)
{
Sell(0, Close);
orderExecuted = True;
Commentary("→ 市价平多仓");
}
}
// 平仓后立即开反向仓
If(orderExecuted And prevIsYin) // 开多仓
{
If(EnableLimitOrder)
{
targetPrice = Open - PriceOffset * MinMove * PriceScale;
If(targetPrice >= Low)
{
Buy(Lots, targetPrice);
Commentary("→ 限价开多仓:" + Text(targetPrice));
}
Else
{
Buy(Lots, Close);
Commentary("→ 市价开多仓");
}
}
Else
{
Buy(Lots, Close);
Commentary("→ 市价开多仓");
}
}
Else If(orderExecuted And prevIsYang) // 开空仓
{
If(EnableLimitOrder)
{
targetPrice = Open + PriceOffset * MinMove * PriceScale;
If(targetPrice <= High)
{
SellShort(Lots, targetPrice);
Commentary("→ 限价开空仓:" + Text(targetPrice));
}
Else
{
SellShort(Lots, Close);
Commentary("→ 市价开空仓");
}
}
Else
{
SellShort(Lots, Close);
Commentary("→ 市价开空仓");
}
}
}
// 情况2:开新仓(无持仓时需要开仓)
Else If(MarketPosition == 0 And orderExecuted == False)
{
If(prevIsYin) // 开多仓
{
If(EnableLimitOrder)
{
targetPrice = Open - PriceOffset * MinMove * PriceScale;
If(targetPrice >= Low)
{
Buy(Lots, targetPrice);
orderExecuted = True;
Commentary("→ 限价开多仓:" + Text(targetPrice));
}
}
If(orderExecuted == False)
{
Buy(Lots, Close);
orderExecuted = True;
Commentary("→ 市价开多仓");
}
}
Else If(prevIsYang) // 开空仓
{
If(EnableLimitOrder)
{
targetPrice = Open + PriceOffset * MinMove * PriceScale;
If(targetPrice <= High)
{
SellShort(Lots, targetPrice);
orderExecuted = True;
Commentary("→ 限价开空仓:" + Text(targetPrice));
}
}
If(orderExecuted == False)
{
SellShort(Lots, Close);
orderExecuted = True;
Commentary("→ 市价开空仓");
}
}
}
// 情况3:继续持仓
Else If(orderExecuted == False)
{
Commentary("→ 继续持仓");
}
}
}
上面这个是原版本,我用任何品种1分钟K线回测或者模拟实盘都是正确的,但是挂实盘交易,期货账户的成交价格跟实盘策略的交易明细的价格不一致,策略的交易明细是符合挂单价的,而真是账户里面是用触发信号的最新价撮合成交,然后我询问了改进方法,改了A函数的版本,今天测试了几次,交易混乱,我反复研究没找到问题的原因,逻辑也是一致的,请大神费神帮我看看,给我改进的意见,让我实盘能与上面的策略保持一致,非常感谢,熬了几个晚上了,跪求。下面是改的A函数的版本。
//------------------------------------------------------------------------
// 简称: 实盘
// 名称: A函数实盘
//------------------------------------------------------------------------
Params
Numeric Lots(1);
Numeric PriceOffset(1);
Bool EnableLimitOrder(True);
Vars
Numeric prevClose;
Numeric prevOpen;
Bool prevIsYin(False);
Bool prevIsYang(False);
Numeric targetPrice;
Bool needReverse(False);
Bool orderExecuted(False);
String tradingSymbol;
Array<Integer> orderIds;
Events
OnBar(ArrayRef<Integer> indexs)
{
If(CurrentBar > 1 And orderExecuted == False)
{
orderExecuted = False;
tradingSymbol = RelativeSymbol();
prevClose = Close[1];
prevOpen = Open[1];
prevIsYin = (prevClose < prevOpen);
prevIsYang = (prevClose > prevOpen);
Commentary("K线" + Text(CurrentBar) + ": 前一根" +
IIfString(prevIsYin, "阴柱", IIfString(prevIsYang, "阳柱", "平线")) +
", 交易合约:" + tradingSymbol);
needReverse = False;
If(MarketPosition == -1 And prevIsYin) needReverse = True;
If(MarketPosition == 1 And prevIsYang) needReverse = True;
// --- 情况1:需要反向操作(先平后开)---
If(needReverse And orderExecuted == False)
{
Commentary("→ 执行反向操作");
// 平仓操作
If(MarketPosition == -1) // 平空仓
{
If(EnableLimitOrder)
{
targetPrice = Open - PriceOffset * MinMove * PriceScale;
If(targetPrice >= Low)
{
// 明确指定平1手空仓
A_SendOrderEx(tradingSymbol, Enum_Buy, Enum_Exit, 1, targetPrice, orderIds);
orderExecuted = True;
Commentary("→ 限价平空仓:" + Text(targetPrice));
}
}
If(orderExecuted == False)
{
A_SendOrderEx(tradingSymbol, Enum_Buy, Enum_Exit, 1, 0, orderIds);
orderExecuted = True;
Commentary("→ 市价平空仓");
}
}
Else If(MarketPosition == 1) // 平多仓
{
If(EnableLimitOrder)
{
targetPrice = Open + PriceOffset * MinMove * PriceScale;
If(targetPrice <= High)
{
// 明确指定平1手多仓
A_SendOrderEx(tradingSymbol, Enum_Sell, Enum_Exit, 1, targetPrice, orderIds);
orderExecuted = True;
Commentary("→ 限价平多仓:" + Text(targetPrice));
}
}
If(orderExecuted == False)
{
A_SendOrderEx(tradingSymbol, Enum_Sell, Enum_Exit, 1, 0, orderIds);
orderExecuted = True;
Commentary("→ 市价平多仓");
}
}
// 平仓后立即开反向仓
If(orderExecuted)
{
If(prevIsYin) // 开多仓
{
If(EnableLimitOrder)
{
targetPrice = Open - PriceOffset * MinMove * PriceScale;
If(targetPrice >= Low)
{
A_SendOrderEx(tradingSymbol, Enum_Buy, Enum_Entry, Lots, targetPrice, orderIds);
Commentary("→ 限价开多仓:" + Text(targetPrice));
}
Else
{
A_SendOrderEx(tradingSymbol, Enum_Buy, Enum_Entry, Lots, 0, orderIds);
Commentary("→ 市价开多仓");
}
}
Else
{
A_SendOrderEx(tradingSymbol, Enum_Buy, Enum_Entry, Lots, 0, orderIds);
Commentary("→ 市价开多仓");
}
}
Else If(prevIsYang) // 开空仓
{
If(EnableLimitOrder)
{
targetPrice = Open + PriceOffset * MinMove * PriceScale;
If(targetPrice <= High)
{
A_SendOrderEx(tradingSymbol, Enum_Sell, Enum_Entry, Lots, targetPrice, orderIds);
Commentary("→ 限价开空仓:" + Text(targetPrice));
}
Else
{
A_SendOrderEx(tradingSymbol, Enum_Sell, Enum_Entry, Lots, 0, orderIds);
Commentary("→ 市价开空仓");
}
}
Else
{
A_SendOrderEx(tradingSymbol, Enum_Sell, Enum_Entry, Lots, 0, orderIds);
Commentary("→ 市价开空仓");
}
}
}
}
// --- 情况2:开新仓(无持仓时需要开仓)---
Else If(MarketPosition == 0 And orderExecuted == False)
{
If(prevIsYin) // 开多仓
{
If(EnableLimitOrder)
{
targetPrice = Open - PriceOffset * MinMove * PriceScale;
If(targetPrice >= Low)
{
A_SendOrderEx(tradingSymbol, Enum_Buy, Enum_Entry, Lots, targetPrice, orderIds);
orderExecuted = True;
Commentary("→ 限价开多仓:" + Text(targetPrice));
}
}
If(orderExecuted == False)
{
A_SendOrderEx(tradingSymbol, Enum_Buy, Enum_Entry, Lots, 0, orderIds);
orderExecuted = True;
Commentary("→ 市价开多仓");
}
}
Else If(prevIsYang) // 开空仓
{
If(EnableLimitOrder)
{
targetPrice = Open + PriceOffset * MinMove * PriceScale;
If(targetPrice <= High)
{
A_SendOrderEx(tradingSymbol, Enum_Sell, Enum_Entry, Lots, targetPrice, orderIds);
orderExecuted = True;
Commentary("→ 限价开空仓:" + Text(targetPrice));
}
}
If(orderExecuted == False)
{
A_SendOrderEx(tradingSymbol, Enum_Sell, Enum_Entry, Lots, 0, orderIds);
orderExecuted = True;
Commentary("→ 市价开空仓");
}
}
}
// --- 情况3:继续持仓 ---
Else If(orderExecuted == False)
{
Commentary("→ 继续持仓");
}
}
}
你的代码我已经帮你整理,完整了,开市可以实验一下效果.代码我已经发帖,可以下载
在条件判断后立即将orderExecuted重置为False,这使得orderExecuted == False条件永远为真,失去了控制作用。
//===使用Array<Integer> orderIds但未初始化数组,, 没有订单状态检查和错误处理, 可能重复发送订单>>>
反向条件过于简单,没有考虑持仓数量、止损止盈等风险控制>>
在反向操作中,平仓后没有等待确认就立即发送开仓单,可能导致:
//平仓未成交时重复开仓,资金不足,超仓风险
图表策略第一大忌,图表函数 A函数混用
你的描述就非常矛盾
我来帮你看看,能否解决!