交易处理函数,用于EA和脚本中。
指标不能直接调用这些函数进行交易。
为了在EA和脚本中进行交易,在程序交易环境(智能交易和脚本的自动交易的环境)中,只为它提供了一个线程。所以如果这个交易环境被一个智能交易操作占用,就会出现146错码(ERR_TRADE_CONTEXT_BUSY),其他EA或脚本此时就不能成功调用。为了判断是否有交易正在进行,可用 IsTradeAllowed() 函数进行检测。
为消除交易环境下访问共享,可使用个基于全局变量的交易信号,其值可以使用 GlobalVariableSetOnCondition() 函数改变。
bool OrderSelect(int 单序号或单编号, int 选单方式, void 现仓或历史仓)
此函数只为选择一个订单. (目的为做下一步地处理)
返回值: 如果选择成功,返回TRUE,如果选择失败,返回FALSE。
如果按编号选订单,pool参数应忽略。此订单编号是其唯一识别符。从所选订单的列表,对订单时间进行分析。如果订单时间为零,此订单就是开单或挂单,或从终端开仓部位列表中选出。我们可以从订单类型区别开单和挂单。如果订单的平仓时间非0,说明此单是一个已经平仓的订单,或是一个已删除的挂单,也可能是从终端历史中被选出来的,他们同样可以根据定单类型相互区别。
参数:
index - 订单序号或订单号,这取决于第2个参数(select)
select - 选定模式。可以为以下的任意值:
SELECT_BY_POS - 按订单表中的排序号码的选择方式 (即从存在自己电脑上交易的排序号中选择)
SELECT_BY_TICKET - 按订单编号选择方式 (即从平台交易给出的编号进行选择)
pool - 当选择模式为 SELECT_BY_POS参数时使用的以下索引值:
MODE_TRADES (默认)- 来自正在交易中的订单 (包括开仓单和挂单),
MODE_HISTORY - 来自历史中的订单 (包括已平仓或取消的订单)。
示例:
if(OrderSelect(12470, SELECT_BY_TICKET)==true){
Print("订单 #12470 开价格", OrderOpenPrice());
Print("订单 #12470 收盘价格 ", OrderClosePrice());
}
else
Print("OrderSelect 返回的错误 ",GetLastError());
bool OrderClose(int 号, double 手, double 价, int 滑, void 色)
平仓。
参数:
ticket - 订单号。
lots - 平仓手数。
price - 平仓价格。
slippage - 最高滑点数。
Color - 图表中平仓箭头颜色。如果参数丢失或用CLR_NONE值,将不会在图表中画出。
i示例:
//--单数过多时,当余额与初始余额相等时,全平
//--无单时,记录成篮子期始资金
if(OrdersTotal()<1){
初始余额= AccountBalance();
}
if(OrdersTotal()>=单数限制){
if(MathAbs(AccountBalance()-初始余额))<2){
全消全平子();
Print("单数过多,保本平仓!");
}
}
//------------------结束所有头寸子()--------------------+
bool 全消全平子()
{
for(int i=0; i<OrdersTotal(); i++){
Sleep(3000);
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)==false)
break;
if(OrderSymbol()==Symbol() && OrderMagicNumber()==魔术号){
//消挂
if(OrderType()>1)
OrderDelete(OrderTicket(), Black);
//平仓
else
if(OrderType()==OP_BUY)
OrderClose(OrderTicket(), OrderLots(), Bid, 3, White);
else
if(OrderType()==OP_SELL)
OrderClose(OrderTicket(), OrderLots(), Ask, 3, White);
}
}
//不再开仓
if(使用连续在市==false)
可交易= false;
return(true);
}
bool OrderCloseBy(int 号, int 对冲单号, void 色)
相反头寸平仓
(此函数只在允许对冲的平台上可用该函数)
用相反订单对已开仓位进行平仓。如果函数成功,返回TRUE。如果函数失败,返回FALSE。获得详细错误信息,请查看GetLastError()函数。
参数:
ticket - 订单号。
opposite - 相反订单的订单号。
Color - 图表中平仓箭头颜色。如果参数丢失或用CLR_NONE值,将不会在图表中画出。
i示例:
iif(iRSI(NULL, 0, 14, PRICE_CLOSE, 0)>75){
OrderCloseBy(订单号, opposite_id);
return(0);
}
double OrderClosePrice()
订单平仓价。
对于已经平仓的订单返回平仓时价格, 对于未平仓单则返回该订单货币对的当前实时价格。
注:定单必须用 OrderSelect() 函数提前选定。
i示例:
if(OrderSelect(ticket, SELECT_BY_POS)==true)
Print(''订单号为:",ticket,"的平仓价为:", OrderClosePrice());
else
Print("选择订单时出错,错码为:", GetLastError());
datetime OrderCloseTime()
订单的平仓时间。
如果订单的平仓时间非0,所选的订单会从账户历史重新尝试。而未平仓单和挂单交易的平仓时间为0。
(注:必须用 OrderSelect() 函数提前选定。)
示例:
void 物件显示历史成交单子()
{
//string 内容;
for(int i=0; i<OrdersHistoryTotal(); i++){
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)==false)
break;
if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=魔术号)
continue;
if(OrderType()==OP_SELL)
color 线色= Blue ;
if(OrderType()==OP_BUY)
线色= Red;
if(ObjectFind("趋势线"+i)==-1){
ObjectCreate("趋势线"+i, OBJ_TREND, 0, OrderOpenTime(), OrderOpenPrice(), OrderCloseTime(), OrderClosePrice());
ObjectSet("趋势线"+i, OBJPROP_COLOR, 线色);
ObjectSet("趋势线"+i, OBJPROP_RAY, false);
ObjectSet("趋势线"+i, OBJPROP_STYLE, STYLE_DOT);
}
}
}
string OrderComment()
订单的注释。
(注:须用 OrderSelect() 函数提前选定。)
示例:
//-------------被止损或是被止赢------------+
switch(OrderType()){
//--买单的
case OP_BUY: if(OrderStopLoss()!=0.0 && StringFind(OrderComment(), "[sl]")>=0 || OrderClosePrice()<=OrderStopLoss()) // 买单被止损
亏幅= OrderStopLoss()-OrderClosePrice();
else
if(OrderTakeProfit()!=0.0 && StringFind(OrderComment(), "[tp]")>=0 || OrderClosePrice()>=OrderTakeProfit()) // 买单被止赢
赢幅= OrderTakeProfit()-OrderClosePrice();
break;
//--卖单的
case OP_SELL: if(OrderStopLoss()!=0.0 && StringFind(OrderComment(), "[sl]")>=0 || OrderClosePrice()>=OrderStopLoss()) // 卖单被止损
亏幅= OrderClosePrice()-OrderStopLoss();
else
if(OrderTakeProfit()!=0.0 && StringFind(OrderComment(), "[tp]")>=0 || OrderClosePrice()<=OrderTakeProfit()) // 卖单被止赢
赢幅= OrderClosePrice()-OrderTakeProfit();
}
double OrderCommission()
订单的佣金数额。
(注:须用 OrderSelect() 函数提前选定。)
示例:
void f0_19()
{
double 率值;
if(OrderSymbol()==Symbol()
&& OrderCloseTime()!=0
&& OrderLots()!=0.0
&& OrderClosePrice()!=OrderOpenPrice()
&& OrderProfit()!=0.0
&& MarketInfo(Symbol(), MODE_LOTSIZE)!=0.0
&& OrderComment()!="partial close"
&& StringFind(OrderComment(), "[sl]from #")==-1
&& StringFind(OrderComment(), "[tp]from #")==-1) {
gi_932= TRUE;
率值= MathAbs(OrderProfit() / (OrderClosePrice()-OrderOpenPrice()));
gd_940= 率值 / OrderLots() / MarketInfo(Symbol(), MODE_LOTSIZE);
gd_948= (-OrderCommission()) / 率值;
Print(g_count_1100 + ": Commission_Rate : " + f0_39(gd_948));
}
}
bool OrderDelete(int 号, void 色)
删除指定单号的挂单。
参数:
ticket - 要删除的订单(挂单)号。
Color - 图表中平仓箭头颜色。如果参数丢失或用CLR_NONE值,将不会在图表中画出。
示例:
// [Script] 全消挂单
.#property show_inputs
.#include <stdlib.mqh>
.#include <WinUser32.mqh>
//----------------主函数-----------------+
int start()
{
if(MessageBox("是否要全消? ", "全消!", MB_YESNO|MB_ICONQUESTION)!=IDYES)
return;
for(int i=OrdersTotal()-1; i>=0; i--){
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)
continue;
if(OrderType()<2)
continue;
while(true){
if(OrderDelete(OrderTicket())!=true)
Print("取消挂单未成功,错因:", ErrorDescription(GetLastError()));
else
break;
}
}
return(0);
}
//-----------------------------------------+
datetime OrderExpiration()
当前挂单的有效时间。
(注:须用 OrderSelect() 函数提前选定。)
示例:
if(OrderSelect(10, SELECT_BY_TICKET)==true)
Print("#10 挂单 有效日期为",OrderExpiration());
else
Print("选择挂单出错", GetLastError());
double OrderLots()
订单的手数。
(注:须用 OrderSelect() 函数提前选定。)
示例:
//--历史亏损单手数加倍
最后历单平仓时= 0;
手数= 初始固定手;
for(int pos= OrdersHistoryTotal()-1; pos>=0; pos--){
if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY)){
if(OrderSymbol()==Symbol() && OrderMagicNumber()==魔术号){
//--找到最后一口历史亏损单
if(最后历单平仓时<OrderCloseTime()){
最后历单平仓时= OrderCloseTime();
if(OrderProfit()<0.0)
//--亏损则手数加倍
手数= NormalizeDouble(OrderLots()*手倍数, 手位数);
//--未亏则仍使用初始固定手数参数值
else
手数= 初始固定手;
}
}
}
int OrderMagicNumber()
订单的魔术号。
(注:须用 OrderSelect() 函数提前选定。)
示例:
if(OrderSelect(10,SELECT_BY_POS)==true)
Print("订单第10号的魔术号是: ", OrderMagicNumber());
else
Print("选单出错 ", GetLastError());
bool OrderModify(int 号, double 价, double 损, double 赢, datetime 效, void 色)
修改订单
修改以前的开仓或挂单的订单参数。如果函数成功,返回TRUE。如果函数失败,返回FALSE。如果想获取详细的错误信息,请调用GetLastError()函数。
注:只有挂单才能修改开仓价和过期时间!
如果修改时仍用原参数值,将会产生错误代码为1的信息 (ERR_NO_RESULT)。
有些平台服务器上,挂单的过期时间是被禁用的。这种情况下,当在过期参数中指定一个非零值时,将生成147错误(ERR_TRADE_EXPIRATION_DENIED)。
参数:
ticket - 要修改的订单(挂单)号。
price - 新的开仓价格。(对于挂单有效)
stoploss - 新止损价位。
takeprofit - 新止盈价位。
expiration - 挂单有效时间。(仅对挂单有效)
Color - 图表中平仓箭头颜色。如果不输入该参数或用CLR_NONE值,将不会在图表中画出。
示例:
if(跟踪止损>0){
if(!OrderSelect(12345, SELECT_BY_TICKET))
break;
if(Bid-OrderOpenPrice()>跟踪止损Point){
if(Bid-OrderStopLoss()>跟踪止损Point){
OrderModify(OrderTicket(), OrderOpenPrice(), Bid-跟踪止损*Point, OrderTakeProfit(), 0, Blue);
return(0);
}
}
}
double OrderOpenPrice()
订单的开仓价。
(注:须用 OrderSelect() 函数提前选定。)
示例:
extern int 魔术号= 0;
double 全部平均开仓价= 0,
买单平均开仓价= 0,
卖单平均开仓价= 0;
double 全部手数和= 0,
买单手数和= 0,
卖单手数和= 0;
//---------------主函数----------------+
int start()
{
计算平均开仓价位子();
return(0);
}
//-----------计算平均开仓价----------+ (未验证)
void 计算平均开仓价位子()
{
int 订单总数= 0;
int 买单总数= 0;
int 卖单总数= 0;
全部平均开仓价= 0;
买单平均开仓价= 0;
卖单平均开仓价= 0;
全部手数和= 0;
买单手数和= 0;
卖单手数和= 0;
for(int i=OrdersTotal()-1; i>=0; i--){
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderSymbol() != Symbol() || OrderMagicNumber()!=魔术号)
continue;
if(OrderSymbol()==Symbol() && OrderMagicNumber()==魔术号){
if(OrderType()==OP_BUY || OrderType()==OP_SELL){
全部平均开仓价 += OrderOpenPrice()*OrderLots();
全部手数和 += OrderLots();
订单总数++;
if(OrderType()==OP_BUY){
买单平均开仓价 += OrderOpenPrice()*OrderLots();
买单手数和 += OrderLots();
买单总数++;
}
if(OrderType()==OP_SELL){
卖单平均开仓价 += OrderOpenPrice()*OrderLots();
卖单手数和 += OrderLots();
卖单总数++;
}
}
}
}
if(订单总数>0)
全部平均开仓价= NormalizeDouble(全部平均开仓价 /全部手数和, Digits);
if(买单总数>0)
买单平均开仓价= NormalizeDouble(买单平均开仓价 /买单手数和, Digits);
if(卖单总数>0)
卖单平均开仓价= NormalizeDouble(卖单平均开仓价 /卖单手数和, Digits);
}
datetime OrderOpenTime()
订单的开仓时间。
(注:须用 OrderSelect() 函数提前选定。)
示例:
//-----------------判断开仓时间间隔是否达到------------------+
bool 检查时隔子()
{
bool 达到时隔;
if(OrdersTotal()>=1)
OrderSelect(OrdersTotal()-1, SELECT_BY_POS, MODE_TRADES);
datetime 最后开仓时= OrderOpenTime();
if(TimeCurrent()-最后开仓时>Period()*60)
达到时隔= true;
else
达到时隔= false;
return(达到时隔);
void OrderPrint()
打印日志中当前订单信息
打印格式如下:
单编号; 开仓时间; 交易币种; 手数; 开仓价; 止损价; 止盈价; 平仓时间; 平仓价; 佣金; 掉期; 盈利; 注释; 魔术号; 挂单有效日期
(注:须用 OrderSelect() 函数提前选定。)
示例:
if(OrderSelect(10, SELECT_BY_TICKET)==true)
OrderPrint();
else
Print("选择订单失败 错码是",GetLastError());
double OrderProfit()
订单的盈亏金额 (不包括掉期和佣金)。
对于开仓订单当前为浮动盈亏; 对于已平仓单则为固定盈亏。
(注:须用 OrderSelect() 函数提前选定。)
示例:
if(OrderSelect(10, SELECT_BY_POS)==true)
Print("订单10# 盈亏额为:",OrderProfit());
else
Print("选择订单失败, 错码",GetLastError());
int OrderSend(string 对, int 类, double 手, double 价, int 滑, double 损, double 赢, void 评, void 魔, void 效,void 色)
开仓(包括挂单)
如果开或挂成功,由交易服务器返回订单的单号,如果失败,返回-1。
注:按市价订单交易时(即用OP_SELL或OP_BUY类型开仓),只可使用最新的叫卖价(Bid)或叫买价(Ask)( 如果采用指定的货币对,则必须使用带有MODE_BID或MODE_ASK参数的Marketlnfo() 函数来获得该货币对最新的报价)。 预测的或是不标准的价格不可用。
如果在市场的报价中没有所要的开仓价或者没有按照小数点后位数的要求标准化,将会导致129错误(ERR_INVALID_PRICE);
如果要求的开仓价日期已经过期,将会导致138错误(ERR_REQUOTE);如果所请求的价格过期了,但仍处于市价里,则按现价或仍在price+-slippage(现价+-滑点)范围内现价开仓。
止损价和止盈价不能太靠近市价。最小的止损水平点数可用带MODE_STOPLEVEL参数的 MarketInfo() 函数得到。在出错或止损位设置不正确的情况下,将会导致130错误(ERR_INVALID_STOPS)。
在发出挂单时,开仓挂价也不能太靠近市价。挂单价和当前市价之间最小的点数也用带MODE_STOPLEVEL参数的 MarketInfo() 函数得到。在挂单开盘价错误的情况下,将会导致130错误(ERR_INVALID_STOPS)。
有些平台服务器会禁用使用挂单交易的过期时间。在这种情况下,如果expiration(过期)参数指定了非零值,反而会导致147错误(ERR_TRADE_EXPIRATION_DENIED)产生。
一某些交易服务器上,开仓单和挂单的总数有限制。如果超出限数,就不能再开仓,或者不能再挂单了。这样如果再开仓或挂单,交易服务器会返回148错误(ERR_TRADE_TOO_MANY_ORDERS)。
参数:
symbol - 交易货币对。
cmd - 交易类型。
volume - 交易手数。
price - 交易价格。
slippage - 最大允许滑点数。
stoploss - 止损价格。
takeprofit - 止盈价格。
comment - 注释文本。注释的最后部分可以由服务器修改。
magic - 订单魔术编号。可以作为用户指定识别码使用。
expiration - 订单有效时间(只限挂单)。
arrow_color - 图表上箭头颜色。如果未写参数或为CLR_NONE则价格箭头将不会在图表中标出。
示例:
int ticket;
if(iRSI(NULL,0,14,PRICE_CLOSE,0)<25){
ticket= OrderSend(Symbol(),OP_BUY,1,Ask,3,Ask-25Point,Ask+25Point,"My order #2",16384,0,Green);
if(ticket<0){
Print("选单失败, 错码: ",GetLastError());
return(0);
}
}
int OrdersHistoryTotal()
载入到终端账户历史表中的已平仓订单总数。
(历史表的范围大小取决于终端”Accounthistory(账户历史)”标签中的当前设置。)
示例:
//--来自交易历史的订单信息
int i, 历史单总数= OrdersHistoryTotal();
for(i=0; i<历史单总数; i++){
//--检查选择结果
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false){
Print("访问历史表数据出错,错误信息:",GetLastError());
break;
....
double OrderStopLoss()
订单止损价。
注:须用 OrderSelect() 函数提前选定。
示例:
if(OrderSelect(ticket,SELECT_BY_POS)==true)
Print("对于ticket为:"ticket""单的止损价为", OrderStopLoss());
else
Print("订单选择失败,错码 ",GetLastError());
int OrdersTotal()
已成单和挂单的总数。
(魔号或货币对等条件未指定时的订单总数)
示例:
//--选择订单
if(OrdersTotal()>0){
//--按序号选择第OrdersTotal()-1个订单
if(OrderSelect(OrdersTotal()-1, SELECT_BY_POS, MODE_TRADES)==True)
//--找到最后单的开仓价
double 最后开仓价= OrderOpenPrice();
//--选择序号为0的订单
if(OrderSelect(0, SELECT_BY_POS, MODE_TRADES)==True)
//--首个订单开仓价
double 首个开仓价= OrderOpenPrice();
//--打印观察一下
Print(" 最后开仓价 (OrdersTotal()-1)= ",最后开仓价," 首个开仓价 (0)= ",首个开仓价);
}
//--
int 文件手柄= FileOpen("OrdersReport.csv",FILE_WRITE|FILE_CSV,"\t");
if(文件手柄<0)
return(0);
//--写内容
FileWrite(文件手柄,"#","开仓价格","开仓时间","货币对","开仓手数");
int 订单总数= OrdersTotal();
//--编写订单命令
for(int pos=0; pos<订单总数; pos++){
if(OrderSelect(pos,SELECT_BY_POS)==false)
continue;//?
FileWrite(文件手柄,
OrderTicket(),OrderOpenPrice(),OrderOpenTime(),OrderSymbol(),OrderLots());
}
FileClose(文件手柄);
double OrderSwap()
订单的掉期值。
注:须用 OrderSelect() 函数提前选定。
示例:
if(OrderSelect(order_id, SELECT_BY_TICKET)==true)
Print("对于订单 #", order_id, "的掉期为 ", OrderSwap());
else
Print("选择订单失败,错码",GetLastError());
string OrderSymbol()
订单的交易品种名。
注:须用 OrderSelect() 函数提前选定。
示例:
if(OrderSelect(12, SELECT_BY_POS)==true)
Print("订单 #12", OrderTicket(), " 货币对是", OrderSymbol());
else
Print("选择订单失败,错码",GetLastError());
double OrderTakeProfit()
订单的止盈价。
注:须用 OrderSelect() 函数提前选定。
示例:
if(OrderSelect(12, SELECT_BY_POS)==true)
Print("订单 #12",OrderTicket()," 止赢价: ", OrderTakeProfit());
else
Print("OrderSelect() 返回错误 - ",GetLastError());
int OrderTicket()
订单的编号
注:须用 OrderSelect() 函数提前选定。
示例:
//--按序号找到第12个的订单编号
if(OrderSelect(12, SELECT_BY_POS)==true)
单号= OrderTicket();
else
Print("OrderSelect 失败,错误代码",GetLastError());
int OrderType()
订单的交易类型
(返回值为 交易类型列表 下的值....
0,1,2,3,4,5 (略)
)
注:须用 OrderSelect() 函数提前选定。
示例:
int 订单类型= -1;
if(OrderSelect(12, SELECT_BY_POS)==true){
订单类型= OrderType();
// ...
}
else
Print("OrderSelect() ,错误 - ",GetLastError());