A_SendOrderEx函数下单为什么每次都会连续下单2次呢

A_SendOrderEx函数下单为什么每次都会连续下单2次呢

不管是开仓还是平仓,明明代码只执行一次,为啥总是会连续发出2次委托单呢,完整代码如下:

//------------------------------------------------------------------------
// 简称: ThreeRedSoldiersDay
// 名称: 红三兵日内
// 类别: 公式应用
// 类型: 用户应用
// 输出: Void
// 主要基于红三兵思路。一分钟k线连续2根低点抬高即在第三根k线运行时以限定价格买入开仓。
Params
	Numeric Start(10);			//开盘10分钟开始
	Numeric Add(3);				//高低点加减几跳入场
	Numeric Exit(7);			//开仓后第几根离场
	Numeric EtSecond(50);		//出场秒数(不能大于59)
	Numeric EndT(0.1458);		//收盘前平仓时间
	Numeric Loss(3);			//止损跳数
	String Period(\"1m\");		//参考周期
	String AccountID(\"\");		//绑定交易账户,只支持单个账户,如tbf_myAct01
	Numeric Lots(1);			//开仓手数
	Numeric Recall(0);			//是否回溯

Vars
	
	Global Integer IsSubs;				//是否加载多周期K线标记
	Series<String> Contract;   			//获取合约代码
	Series<String> myContract;   		//获取交易合约代码
	Bool condLong;						//多头开仓条件
	Bool condShort;						//空头开仓条件
	
	Series<Numeric> MinPoint;    		//一跳
	Series<Numeric> LossPrice;   		//止损价格
	Series<Numeric> myPrice;   			//操作价格
	Series<Numeric> IsNewBar;   		//是否新的大周期Bar
	Global Numeric MPL;   				//多头开仓状态
	Global Numeric MPS;   				//空头开仓状态
	Global Numeric BS;   				//开仓后Bar数
	
	Global Integer OrderID;				//报单号

Defs
	//此处添加公式函数
	
Events
	//此处实现事件函数
	
	//初始化事件函数,策略运行期间,首先运行且只有一次
	OnInit()
	{
		//绑定交易账户
		Array<String> Acc;
		StringSplit(AccountID,\",\",Acc);
		Integer i;
		For i = 0 To GetArraySize(Acc) - 1
        {
           A_BindTradeAccount(Acc[i]);
           Print(\"公式初始化\"+\":绑定交易账户:\"+Acc[i]);
           //Break;
        }
	}
	
	OnBarOpen(ArrayRef<Integer> indexs)
	{
		Range[1:1]
		{
			BS=BS+1;
		}
	}


	//Bar更新事件函数,参数indexs表示变化的数据源图层ID数组
	OnBar(ArrayRef<Integer> indexs)
	{
		//初始化跨周期K线数据
		If (CurrentBar==0 And IsSubs==0)
		{
			//获取合约名称
			Contract=Symbol();
			Print(\"Contract:\"+Contract);
			//订阅K线数据
			SubscribeBar(Contract,Period,BeginDateTime, 0, Enum_Data_FullPeriod);
			IsSubs=1;
		}
		
		
		//获取交易合约
		If (myContract==\"\")
		{
			If (RelativeSymbol()==\"\")
			{
				myContract=Symbol();
			}Else
			{
				myContract=RelativeSymbol();
			}
		}
		Commentary(\"当前交易合约:\"+myContract);
		
		MinPoint=MinMove()*PriceScale();
		Commentary(\"该品种1跳等于\"+Text(MinPoint)+\"点\");
		
		//重置大周期新的Bar标记
		If (Time==Data1.Time)
		{
			IsNewBar=0;
		}
		
		Commentary(\"Second:\"+Text(Second));
		
		//收盘前平仓
		//CloseMinutes
		If (BS>=0 And (MPL==1 Or MPS==1) And (Time>=EndT And Time<=0.15))
		{
			//多头离场
			If (Recall==1)
			{
				//支持回溯
				If (MarketPosition==1 And Vol>0)
				{
					myPrice=Open;
					Sell(Lots,myPrice);
					MPL=0;
					MPS=0;
					Commentary(\"收盘前平仓\");
				}
				If (MarketPosition==-1 And Vol>0)
				{
					myPrice=Open;
					BuyToCover(Lots,myPrice);
					MPL=0;
					MPS=0;
					Commentary(\"收盘前平仓\");
				}
			}Else
			{
				//不支持回溯
				Position pos;
				Bool ret = A_GetPosition(myContract, pos, \"\", 0);
				//Commentary(\"A_GetPosition:\" + IIFString(ret, \"True\", \"False\") + \",\" + Text(pos));
				If (ret)
				{
					Commentary(\"多头可平仓:\"+Text(pos.longCanSellVolume));
					Commentary(\"空头可平仓:\"+Text(pos.shortCanCoverVolume));
					MPL=Max(pos.longCanSellVolume,1);
					MPS=Max(pos.shortCanCoverVolume,1);
					//If (MPL==1 And BarStatus==2) Print(Text(Time())+\":MPL=\"+Text(MPL));
					//If (MPS==1 And BarStatus==2) Print(Text(Time())+\":MPS=\"+Text(MPS));
					Array<Integer> orderIds;			//委托ID
					//Print(\"A_BrokerID:\"+Text(A_BrokerID()));
					If (MPL==1 And Vol>0 And BarStatus==2)
					{
						A_SendOrderEx(myContract,Enum_Sell,Enum_ExitToday,Lots,Q_BidPrice() ,orderIds,\"\",\"\",A_AccountIndex(A_AccountID(),A_BrokerID()));
						OrderID=orderIds[0];
						Commentary(\"多头止损:\"+Text(Lots)+\"手\");
						Print(Text(Time())+\":多头止损:\"+Text(Lots)+\"手\");
					}
					If (MPS==1 And Vol>0 And BarStatus==2)
					{
						A_SendOrderEx(myContract,Enum_Buy,Enum_ExitToday,Lots,Q_AskPrice() ,orderIds,\"\",\"\",A_AccountIndex(A_AccountID(),A_BrokerID()));
						OrderID=orderIds[0];
						Commentary(\"空头止损:\"+Text(Lots)+\"手\");
						Print(Text(Time())+\":空头止损:\"+Text(Lots)+\"手\");
					}
				}
				
			}
				
		}
		
		//如当前持仓为零,开仓条件为连续两个k线低点抬高即第2根k线最低点比第1根k线最低点要高,
		//而后第3根k线一开始运行时即以第1根k线最低价+3个点下单买入开仓(设止损3个点)。
		//第三根k线价格只要到了第一个k线最低价+3跳 不需要大于前一个最低价 即买入
		condLong=Data1.L[1]>Data1.L[2] And L<=Data1.L[2]+ Add*MinPoint And Open>= Data1.L[2];
		condShort=Data1.H[1]<Data1.H[2] And H>=Data1.H[2]- Add*MinPoint And Open<= Data1.H[2];
		
		//符合多头开仓条件
		If (condLong And Not (Data1.H[1]<Data1.H[2]) And IsNewBar==0 And MPL==0)
		{
			//计算理论成交价格
			myPrice=Min(Open,Data1.L[2]+ Add*MinPoint);
			PlotString(\"买卖\",\"买开↑(\"+Text(myPrice)+\")\",L-1*MinPoint,Red);
			IsNewBar=1;
			//计算止损价格
			LossPrice=myPrice-Loss*MinPoint;
			//Print(\"A_BrokerID:\"+Text(A_BrokerID()));
			//开仓
			If (Recall==1)
			{
				//支持回溯
				If (MarketPosition<>1 And Vol>0)
				{
					Buy(Lots,myPrice);
					MPL=1;
					MPS=0;
					BS=0;
				}
			}Else
			{
				//不支持回溯
				Position pos;
				Bool ret = A_GetPosition(myContract, pos, \"\", 0);
				//Commentary(\"A_GetPosition:\" + IIFString(ret, \"True\", \"False\") + \",\" + Text(pos));
				If (ret)
				{
					Commentary(\"多头可平仓:\"+Text(pos.longCanSellVolume));
					Commentary(\"空头可平仓:\"+Text(pos.shortCanCoverVolume));
					MPL=Max(pos.longCanSellVolume,1);
					MPS=Max(pos.shortCanCoverVolume,1);
					If (MPL==1 And BarStatus==2) Print(Text(Time())+\":MPL=\"+Text(MPL));
					If (MPS==1 And BarStatus==2) Print(Text(Time())+\":MPS=\"+Text(MPS));
					Array<Integer> orderIds;			//委托ID
					//Print(\"A_BrokerID:\"+Text(A_BrokerID()));
					If (MPL<>1 And Vol>0 And BarStatus==2)
					{
						A_SendOrderEx(myContract,Enum_Buy,Enum_Entry,Lots,Q_ASKPrice() ,orderIds,\"\",\"\",A_AccountIndex(A_AccountID(),A_BrokerID()));
						OrderID=orderIds[0];
						Commentary(\"多头开仓:\"+Text(Lots)+\"手\");
						Print(Text(Time())+\":多头开仓:\"+Text(Lots)+\"手\");
						LossPrice=Q_ASKPrice()-Loss*MinPoint;
						BS=0;
					}
				}
			}
		}
		
		//符合空头开仓条件
		If (condShort And Not (Data1.L[1]>Data1.L[2]) And IsNewBar==0 And MPS==0)
		{
			//计算理论成交价格
			myPrice=Max(Open,Data1.H[2]- Add*MinPoint);
			PlotString(\"买卖\",\"卖开↓(\"+Text(myPrice)+\")\",H+1*MinPoint,Green);
			IsNewBar=1;
			//计算止损价格
			LossPrice=myPrice+Loss*MinPoint;
			//开仓
			If (Recall==1)
			{
				//支持回溯
				If (MarketPosition<>-1 And Vol>0)
				{
					SellShort(Lots,myPrice);
					MPL=0;
					MPS=1;
					BS=0;
				}
			}Else
			{
				//不支持回溯
				Position pos;
				Bool ret = A_GetPosition(myContract, pos, \"\", 0);
				//Commentary(\"A_GetPosition:\" + IIFString(ret, \"True\", \"False\") + \",\" + Text(pos));
				If (ret)
				{
					Commentary(\"多头可平仓:\"+Text(pos.longCanSellVolume));
					Commentary(\"空头可平仓:\"+Text(pos.shortCanCoverVolume));
					MPL=Max(pos.longCanSellVolume,1);
					MPS=Max(pos.shortCanCoverVolume,1);
					If (MPL==1 And BarStatus==2) Print(Text(Time())+\":MPL=\"+Text(MPL));
					If (MPS==1 And BarStatus==2) Print(Text(Time())+\":MPS=\"+Text(MPS));
					Array<Integer> orderIds;			//委托ID
					If (MPS<>1 And Vol>0 And BarStatus==2)
					{
						A_SendOrderEx(myContract,Enum_Sell,Enum_Entry,Lots,Q_BidPrice() ,orderIds,\"\",\"\",A_AccountIndex(A_AccountID(),A_BrokerID()));
						OrderID=orderIds[0];
						Commentary(\"空头开仓:\"+Text(Lots)+\"手\");
						Print(Text(Time())+\":空头开仓:\"+Text(Lots)+\"手\");
						LossPrice=Q_BidPrice()+Loss*MinPoint;
						BS=0;
					}
				}
			}
		}
		
		//止损
		If (BS>=0 And ( (MPL==1 And Low<=LossPrice)  Or (MPS==1 And High>=LossPrice)))
		{
			//多头离场
			If (Recall==1)
			{
				//支持回溯
				If (MarketPosition==1 And Vol>0)
				{
					myPrice=Min(Open,LossPrice);
					Sell(Lots,myPrice);
					MPL=0;
					MPS=0;
					Commentary(\"止损平仓\");
				}
				If (MarketPosition==-1 And Vol>0)
				{
					myPrice=Max(Open,LossPrice);
					BuyToCover(Lots,myPrice);
					MPL=0;
					MPS=0;
					Commentary(\"止损平仓\");
				}
			}Else
			{
				//不支持回溯
				Position pos;
				Bool ret = A_GetPosition(myContract, pos, \"\", 0);
				//Commentary(\"A_GetPosition:\" + IIFString(ret, \"True\", \"False\") + \",\" + Text(pos));
				If (ret)
				{
					Commentary(\"多头可平仓:\"+Text(pos.longCanSellVolume));
					Commentary(\"空头可平仓:\"+Text(pos.shortCanCoverVolume));
					MPL=Max(pos.longCanSellVolume,1);
					MPS=Max(pos.shortCanCoverVolume,1);
					//If (MPL==1 And BarStatus==2) Print(Text(Time())+\":MPL=\"+Text(MPL));
					//If (MPS==1 And BarStatus==2) Print(Text(Time())+\":MPS=\"+Text(MPS));
					Array<Integer> orderIds;			//委托ID
					//Print(\"A_BrokerID:\"+Text(A_BrokerID()));
					If (MPL==1 And Vol>0 And BarStatus==2)
					{
						A_SendOrderEx(myContract,Enum_Sell,Enum_ExitToday,Lots,Q_BidPrice() ,orderIds,\"\",\"\",A_AccountIndex(A_AccountID(),A_BrokerID()));
						OrderID=orderIds[0];
						Commentary(\"多头止损:\"+Text(Lots)+\"手\");
						Print(Text(Time())+\":多头止损:\"+Text(Lots)+\"手\");
					}
					If (MPS==1 And Vol>0 And BarStatus==2)
					{
						A_SendOrderEx(myContract,Enum_Buy,Enum_ExitToday,Lots,Q_AskPrice() ,orderIds,\"\",\"\",A_AccountIndex(A_AccountID(),A_BrokerID()));
						OrderID=orderIds[0];
						Commentary(\"空头止损:\"+Text(Lots)+\"手\");
						Print(Text(Time())+\":空头止损:\"+Text(Lots)+\"手\");
					}
				}
			}
				
		}
		
		//如开仓成交则在成交后第7根k线运行至第50秒时平仓
		If (BS>=Exit And Second()>=EtSecond And MPL+MPS>0)
		{
			myPrice=Open;
			//多头离场
			If (Recall==1)
			{
				//支持回溯
				If (MarketPosition==1 And Vol>0)
				{
					Sell(Lots,myPrice);
					MPL=0;
					MPS=0;
					Commentary(\"多头离场\");
				}
				If (MarketPosition==-1 And Vol>0)
				{
					BuyToCover(Lots,myPrice);
					MPL=0;
					MPS=0;
					Commentary(\"空头离场\");
				}
			}Else
			{
				//不支持回溯
				Position pos;
				Bool ret = A_GetPosition(myContract, pos, \"\", 0);
				//Commentary(\"A_GetPosition:\" + IIFString(ret, \"True\", \"False\") + \",\" + Text(pos));
				If (ret)
				{
					Commentary(\"多头可平仓:\"+Text(pos.longCanSellVolume));
					Commentary(\"空头可平仓:\"+Text(pos.shortCanCoverVolume));
					MPL=Max(pos.longCanSellVolume,1);
					MPS=Max(pos.shortCanCoverVolume,1);
					//If (MPL==1 And BarStatus==2) Print(Text(Time())+\":MPL=\"+Text(MPL));
					//If (MPS==1 And BarStatus==2) Print(Text(Time())+\":MPS=\"+Text(MPS));
					Array<Integer> orderIds;			//委托ID
					//Print(\"A_BrokerID:\"+Text(A_BrokerID()));
					If (MPL==1 And Vol>0 And BarStatus==2)
					{
						A_SendOrderEx(myContract,Enum_Sell,Enum_ExitToday,Lots,Q_BidPrice() ,orderIds,\"\",\"\",A_AccountIndex(A_AccountID(),A_BrokerID()));
						OrderID=orderIds[0];
						Commentary(\"多头平仓:\"+Text(Lots)+\"手\");
						Print(Text(Time())+\":多头平仓:\"+Text(Lots)+\"手\");
					}
					If (MPS==1 And Vol>0 And BarStatus==2)
					{
						A_SendOrderEx(myContract,Enum_Buy,Enum_ExitToday,Lots,Q_AskPrice() ,orderIds,\"\",\"\",A_AccountIndex(A_AccountID(),A_BrokerID()));
						OrderID=orderIds[0];
						Commentary(\"空头平仓:\"+Text(Lots)+\"手\");
						Print(Text(Time())+\":空头平仓:\"+Text(Lots)+\"手\");
					}
				}
				
			}
				
		}
		
	}
	
	//成交更新事件函数,参数ordFill表示更新的成交结构体
	OnFill(FillRef ordFill)
	{
		If (ordFill.side==Enum_Buy)
		{
			If (ordFill.comboffset==Enum_Entry)     //多头开仓,id1成交
			{
				MPL=1;
				BS=0;
			}
		}
		If (ordFill.side==Enum_Sell)
		{
			If (ordFill.comboffset==Enum_Entry)     //空头开仓,id1成交
			{
				MPS=1;
				BS=0;
			}
		}	
		
		If (ordFill.side==Enum_Buy)
		{
			If (ordFill.comboffset==Enum_ExitToday)     //空头平仓,id1成交
			{
				MPS=0;
			}
		}
		If (ordFill.side==Enum_Sell)
		{
			If (ordFill.comboffset==Enum_ExitToday)     //多头平仓,id1成交
			{
				MPL=0;
			}
		}	
	}


//------------------------------------------------------------------------
// 编译版本	2023/03/15 092840
// 版权所有	sweer1234
// 更改声明	TradeBlazer Software保留对TradeBlazer平台
//			每一版本的TradeBlazer公式修改和重写的权利
//------------------------------------------------------------------------


交易师每次下单都会切换到账户透视,可否不切换
A_SendOrderEx函数下单返回False
如何控制连续下单次数
下单画线为什么不能拖动?
A_SendOrderex下单的参数里头的ordid是哪里来的?
TB为什么没有画线下单?
A 函数 下单操作后
毫秒连续下单!
有没有高手研究过连续错误下单问题
为什么交易组件里盘口下单、批量下单、触发下单等都没有了?

设置一个变量big_con=0 执行一次后big_con=1,加到开仓条件里

这个无法控制,因为只写了一句A_SenderOrderEx()。但是由于存在多个数据源Data,导致程序自动产生了多条订单。

你的代码里使用了2个数据源,data0和data1,在使用A_SendOrderEx()时,没有在前面加数据源限定,所以就默认在两个数据源上同时发送订单了。可以修改为:data0.A_SendOrderEx()试试。

没有加前缀,也没有用range包起来,那么默认只对data0图层执行

我测试了,结果确实存在和楼主一样的情况:

预置条件:

单次开仓手数:1手

总持仓上限:1手

       商品合约:sp888

测试步骤:

1、在策略交易中只添加一个sp888商品合约,程序正确交易1手持仓。

2、在策略交易中只添加一个sp888商品合约后,再添加1个合约的不同周期数据源,则会出现不想要的2手持仓。

3、在策略交易中只添加一个sp888商品合约后,又添加4个合约的不同周期数据源,则会出现不想要的10手持仓。

另外,策略交易中给出的1手空仓数据是正确的。但实际持仓中的2、10手持仓数据就与期望不符了。

结果情况如下图所示:

data-href=data-href=data-href=

data-href=

你是不是先用了策略交易执行自动交易,然后交易单元打开了k线 也加载头寸执行了自动交易?

我只建了K线策略单元,在K线图上要点击启动自动交易,策略才会自动发单

那就不太清楚了 建议写日志跟踪程序的运行路径 看看每次报单的操作源到底是哪里