【持仓】
【成交】
【订单】
颜色表示多空单!
【订单&成交】
交易函数可分为两类:填写缓存的函数和从缓存读取信息的函数
A、Position
PositionsTotal | 返回持仓数量 |
PositionGetSymbol | 返回与持仓一致的交易品种【刷新缓存】 |
PositionSelect | 选择一个持仓进行下一步工作【刷新缓存】 |
PositionSelectByTicket | 通过指定的单号选择工作持仓【刷新缓存】 |
PositionGetDouble | 返回持仓要求属性(双精度) |
PositionGetInteger | 返回持仓要求属性(日期时间或者整型) |
PositionGetString | 返回持仓要求属性(字符串) |
PositionGetTicket | 返回持仓列表中指定索引的持仓单号【刷新缓存】 |
该类型函数作用:
用于处理当前订单中的持仓单
注意:
0、选择订单之前,必须使用
1、PositionGetInteger(POSITION_TICKET)和 PositionGetInteger(POSITION_IDENTIFIER)是一样的 都是ticket号码
2、POSITION_REASON 开仓方式:分为POSITION_REASON_CLIENT或POSITION_REASON_MOBILE。分手机和客户端。
3、PositionSelect(Symbol)只能选择时间排序最前面的一单。这个函数不推荐用!! 需要和PositiongGetSymbol(index)搭配来遍历
4、刷新缓存PositionSelectByTicket和PositionGetTicket都是2016年新增。在帮助文档中没有体现说明。
B、Orders
OrdersTotal | 返回订单数 |
OrderGetTicket | 返回相应订单的订单号 |
OrderSelect | 为下一步工作选择一订单 |
OrderGetDouble | 返回订单要求属性(双精度型) |
OrderGetInteger | 返回订单要求属性(日期时间或者整型) |
OrderGetString | 返回订单要求属性(字符串) |
OrdetrsTotal只包含当前仓位挂单
C、HistoryOrder
HistorySelect | 为服务器时间的指定周期检索交易和订单历史记录 |
HistorySelectByPosition | 请求指定仓位标识符交易的历史记录 |
HistoryOrderSelect | 为下一步工作选择历史订单 |
HistoryOrdersTotal | 返回历史记录中订单数 |
HistoryOrderGetTicket | 返回历史记录中相关订单的订单号 |
HistoryOrderGetDouble | 返回(双精度)历史记录中订单需求属性 |
HistoryOrderGetInteger | 返回(日期时间或者整型)历史记录中订单需求属性 |
HistoryOrderGetString | 返回(字符串)历史记录中订单需求属性 |
关注历史所有订单,包括成交了的市价单和没有成交的挂单!
//注意
历史订单HistoryOrder包括:
D、HistoryDeal
HistoryDealSelect | 历史记录中选择一个交易便于通过适当函数进一步调用它。 |
HistoryDealsTotal | 返回历史记录交易数 |
HistoryDealGetTicket | 返回历史相关交易订单号 |
HistoryDealGetDouble | 返回历史记录中交易需求属性(双精度) |
HistoryDealGetInteger | 返回历史记录中交易需求属性(时间日期和整型) |
HistoryDealGetString | 返回历史记录中交易需求属性(字符串) |
只关注历史成交了的历史订单,不包括没有成交的挂单!
0、显示的是成交里面的所有订单。包括出金、入金、进场单(in)、结算单(out)
1、首先还是必须先使用 HistorySelect() 或者 HistorySelectByPosition() 函数。确定历史范围或者具体订单号
2、HistorySelect的话,再使用HistoryDealGetTicket()话,根据获得的订单号,获取相关Double、Integer、String每个都需要ticket。这点比较特别!
3、HistoryDealGetDouble()、HistoryDealGetInteger()、HistoryDealGetString()都是DEAL_TYPE、DEAL_VOLUME跟HistoryOrder不太一样。
4、HistoryDealGetInteger(ticket,DEAL_POSITION_ID)对应的是标准订单ticket
HistoryDealGetInteger(ticket,DEAL_TICKET)对应的是成交单ticket
5、在HistoryDeal里面遍历的是HistoryDealGetTicket(index)获取的是成交单ticket!!!
在【订单】中虽然这个SELL_LIMIT显示的订单号不一样,但是在【成交】中,读取HistoryDealGetInteger(ticket,DEAL_TICKET)结果是一样的以入场in的订单号。这个方便了我们知道统一哪个是入场
例子:
持仓挂单遍历方法:
void Loop_Order()
{
//--- 订单属性返回值的变量
ulong ticket;
double open_price;
double initial_volume;
datetime time_setup;
string symbol;
string type;
long order_magic;
long id;
//--- 当前挂单量
uint total=OrdersTotal();
//--- 反复检查通过订单
for(int i=0;i<total;i++)
{
//--- 通过列表中的仓位返回订单报价
ticket = OrderGetTicket(i);
if(ticket != 0)
{
//--- 返回订单属性
open_price =OrderGetDouble(ORDER_PRICE_OPEN);
time_setup =(datetime)OrderGetInteger(ORDER_TIME_SETUP);
symbol =OrderGetString(ORDER_SYMBOL);
order_magic =OrderGetInteger(ORDER_MAGIC);
id =OrderGetInteger(ORDER_POSITION_ID);
initial_volume=OrderGetDouble(ORDER_VOLUME_INITIAL);
type =EnumToString(ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE)));
//--- 准备和显示订单信息
printf("#ticket %d %s %G %s at %G id = %d was set up at %s",
ticket, // 订单报价
type, // 类型
initial_volume, // 已下交易量
symbol, // 交易品种
open_price, // 规定的开盘价
id,
TimeToString(time_setup)// 下订单时间
);
}
}
}
持仓成交单遍历的方法:
void Loop_Position()
{
//--- var
string symbol = "";
long pos_id = 0;
double price = 0;
double volume = 0;
ENUM_POSITION_TYPE type = 0;
long pos_magic = 0;
string comment = "";
//--- loop
int total = PositionsTotal();
for(int i=0;i<total;i++)
{
ResetLastError();
if(PositionGetTicket(i) != 0 ) //2016年 MQL5新增方法 在官方文档中没有说明
{
pos_id = PositionGetInteger(POSITION_IDENTIFIER);
price = PositionGetDouble(POSITION_PRICE_OPEN);
volume = PositionGetDouble(POSITION_VOLUME);
type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
pos_magic = PositionGetInteger(POSITION_MAGIC);
comment = PositionGetString(POSITION_COMMENT);
symbol = PositionGetSymbol(POSITION_SYMBOL);
PrintFormat("仓位 #%d 交易品种 %s: POSITION_MAGIC=%d, 价格=%G, 手数=%.2f,类型=%s, 注释=%s",
pos_id,symbol,pos_magic,price,volume,EnumToString(type),comment);
}
else // 调用 PositionGetSymbol() 没有成功
{
PrintFormat("根据索引 %d 复制仓位到缓存出错."+
" 错误代码: %d", i, GetLastError());
}
}
}
//老方法
void Loop_Position2() //遍历持仓单 老方法 注:这是最早MT5版本只能有单边持仓
{
//--- 获取仓位总数
int positions=PositionsTotal();
//--- 扫描仓位列表
for(int i=0;i<positions;i++)
{
ResetLastError();
//--- 根据仓位在列表中的编号把它复制到缓存中
string symbol=PositionGetSymbol(i); // 获取所开启仓位对应的交易品种
if(symbol != "") // 如果把仓位复制到缓存了,处理它
{
long pos_id =PositionGetInteger(POSITION_IDENTIFIER);
double price =PositionGetDouble(POSITION_PRICE_OPEN);
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
long pos_magic =PositionGetInteger(POSITION_MAGIC);
string comment =PositionGetString(POSITION_COMMENT);
PrintFormat("仓位 #%d 交易品种 %s: POSITION_MAGIC=%d, 价格=%G, 类型=%s, 注释=%s",
pos_id,symbol,pos_magic,price,EnumToString(type),comment);
}
else // 调用 PositionGetSymbol() 没有成功
{
PrintFormat("根据索引 %d 复制仓位到缓存出错."+
" 错误代码: %d", i, GetLastError());
}
}
}
历史所有订单遍历方法:
#define P(X) Print(#X , " = ", X)
void OnStart()
{
//---
Loop_HistoryOrder();
}
//+------------------------------------------------------------------+
//历史所有订单遍历方法
void Loop_HistoryOrder()
{
int Day = 0; //历史订单天数
datetime beginTime = iTime(Symbol(),PERIOD_D1,0) - PeriodSeconds(PERIOD_D1)*Day;
HistorySelect(beginTime,TimeCurrent());
ulong tk = 0;
for(int i=HistoryOrdersTotal() - 1;i>=0;i--)
{
tk = HistoryOrderGetTicket(i); if(tk == 0) continue;
{
printf("===========%d===================",tk); //遍历的也是[订单号]
P(HistoryOrderGetInteger(tk,ORDER_TICKET));
P(HistoryOrderGetInteger(tk,ORDER_TIME_SETUP));
P(HistoryOrderGetInteger(tk,ORDER_STATE));
P(HistoryOrderGetInteger(tk,ORDER_TYPE_FILLING));
P(HistoryOrderGetInteger(tk,ORDER_TYPE_TIME));
P(HistoryOrderGetInteger(tk,ORDER_REASON));
P(HistoryOrderGetInteger(tk,ORDER_POSITION_ID));
P(HistoryOrderGetInteger(tk,ORDER_POSITION_BY_ID)); //此处注意,是开仓单的[订单号] 平仓或者分批平仓需要注意这个
Print("********************");
}
}
}
历史成交单遍历方法:
#define P(X) Print(#X , " = ", X)
void OnStart()
{
//---
Loop_HistoryDeal();
}
//+------------------------------------------------------------------+
//历史成交模式
void Loop_HistoryDeal()
{
int Day = 0; //历史订单天数
datetime beginTime = iTime(Symbol(),PERIOD_D1,0) - PeriodSeconds(PERIOD_D1)*Day;
P(beginTime);
HistorySelect(beginTime,TimeCurrent());
ulong tk = 0;
for(int i=HistoryDealsTotal()-1;i>=0;i--)
{
tk = HistoryDealGetTicket(i); if(tk == 0) continue;
printf("===========%d===================",tk);
P(HistoryDealGetInteger(tk,DEAL_ORDER));
P(HistoryDealGetInteger(tk,DEAL_TIME));
P(HistoryDealGetInteger(tk,DEAL_TIME_MSC));
P(HistoryDealGetInteger(tk,DEAL_TYPE));
P(HistoryDealGetInteger(tk,DEAL_ENTRY));
P(HistoryDealGetInteger(tk,DEAL_MAGIC));
P(HistoryDealGetInteger(tk,DEAL_REASON));
P(HistoryDealGetInteger(tk,DEAL_POSITION_ID)); //此处注意,是开仓单的[订单号] 平仓或者分批平仓需要注意这个
Print("********************");
}
}
历史挂单遍历方法:类似以上,过滤type 只要挂单类型
小结
1、持仓订单
- PositionsTotal()和OrdersTotal()遍历的都是[订单号]
- 遍历之前需要刷新缓存[PositionSelectByTicket] [PositionGetTicket] [OrderGetTicket] [OrderSelect]
- 订单成交后,则有了DEAL订单号[POSITION_IDENTIFIER],在历史订单遍历中使用
- in入场下单,out出场平仓
2、历史订单
- 历史订单除了刷新缓存还要选中历史订单范围HistorySelect(begintTime,endTime)
- HistoryDealsTotal()遍历的是Deal订单号,HistoryOrdersTotal()遍历的是[订单号]
- 平仓订单的[POSITION_IDENTIFIER] 是开仓订单的【订单号】
- 只有HistoryDealsTotal()特殊的是遍历的是Deal订单号,但是 P(HistoryDealGetInteger(tk,DEAL_ORDER)); P(HistoryDealGetInteger(tk,DEAL_POSITION_ID)); 都是[订单号]
问题遗留[解决]
不知道这个ID是啥玩意儿? HistoryOrderGetInteger()和HistoryDealGetInteger()都没找到
只有在英文的帮助文档中才能找到。中文的找不到。
内部系统中的交易ID(Trade ID) - 由交易所分配的单号
即这个ID是给交易所用的,对于我们编程没有用处。并且它给我们的函数方法默认的就是返回string类型,说明它也不希望我们去用。