组织订单周期 - 页 8

 
Alexey Viktorov:

我让它听起来那么复杂吗?交易所靠点差和佣金赚钱,程序员靠写代码赚钱。

其中一位交易员说,我们应该节省点差和佣金(不要尽可能多地支付)。

另一个交易员说,为了钱而写代码是不公平的(如果可能的话,不要付钱)。

他们都照顾好自己的钱包。它们之间似乎没有什么不同...

只有你,作为一个程序员,支持第一种说法,并与第二种说法争论,证明他是错的。

我理解那个想找一个更便宜的程序员的商人。我也理解那些正在寻找更好的交易条件的交易者。问题是什么?想省钱有什么错呢?

但在这里,情况就不一样了。通过自己的算法思考,使其更有效地与订单合作,从而增加系统的利润--意味着要成为一个好的开发者。在我看来,只有在对一个想法进行粗略测试的阶段,才能忽略几个点。

 
Andrey Khatimlianskii:

我理解一个想找一个更便宜的程序员的交易商。我也理解那些正在寻找更好的交易条件的交易者。问题是什么?想省钱有什么错呢?

但在这里,情况就不一样了。通过自己的算法思考,使其更有效地与订单合作,从而增加系统的利润--意味着要成为一个好的开发者。我认为只有在对一个想法进行粗略测试的阶段,我们才能忽视几个点。

很好。而且,不知为什么,我理解你不愿意多写免费的东西。也没有问题...

一般来说,我不反对试图省钱,但不反对到了疯狂的地步。你不能把节省的差价放在交易的首位...

 
Alexey Viktorov:

我不介意在一般情况下尝试省钱,但不是到了疯狂的地步。你不能把节省的差价放在交易的中心位置...

如果你计算一下,这并没有那么疯狂。但我并不是要说服。

 
Andrey Khatimlianskii:

如果你做数学题,就没那么傻了。但我并不是要说服。

你必须计算利润,而不是成本。

如果你节省成本,就很容易造成损失。如果TS的设计是为了承担费用,但它给出了利润,那么这就是一个好的TS,因为在不同的情况下,它可能会出现损失。

事实上,不存在评判优胜者的问题!

 

难道不能把当前页面的第7页移到一个单独的主题(你甚至可以像 "在此进一步讨论 "那样链接到它),并在这个主题中继续它的创建目的?

 
Vitaly Muzichenko:

你必须计算利润,而不是成本。

当你节约成本时,很容易造成损失。如果TS的设计是为了产生费用,但同时它又能带来收入,那么它就是一个好的TS,因为在另一种情况下,它可能会出现损失。

而在一般情况下,赢家是不会被评判的!

我不明白这个评论是什么意思。

是关于超级盈利策略的佣金大小不重要吗?

 
让我们在MT4欧元兑美元上运行以下专家顾问
// В случае изменения количества ордеров по основному символу, сигнализирует об их количестве

// #include <MT4Orders.mqh>

const bool Init =  EventSetMillisecondTimer(1);

int AmountOrders( const string &Symb )
{
  int Res = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderSymbol() == Symb))
      Res++;
      
  return(Res);
}

void OnTimer()
{
  static int PrevAmount = 0;
  
  const int Amount = AmountOrders(_Symbol);
  
  if (Amount != PrevAmount)
  {
    PrevAmount = Amount;
    
    Alert(Amount);
  }    
}


让我们随机打开5个欧元兑美元和5个美元兑日元的订单。现在让我们看一下AmountOrders的无害代码,想象一下以下情况

  1. 我们在运行时处于AmountOrders,其中i == 3。
  2. 我们关闭了 美元兑日元的头寸。然后在当前订单表中摇出订单。
  3. 当i == 2时,我们可能会通过OrderSelect遇到与第1点相同的订单。正因为如此,AmountOrders可能会返回一个比实际多的值。


以下是对我们所说的话的确认

#property strict

void OnStart()
{
  for (int i = 0; i < 5; i++)
    OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, 0);
    
  int PrevTicket = 0;
  
  for (int i = OrdersTotal() - 1; i > 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      const int Ticket = OrderTicket();
      
      if (Ticket == PrevTicket)
        Alert("Hello World!");
        
      PrevTicket = Ticket;
      
      if (OrderSelect(i - 1, SELECT_BY_POS))      
        OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
    }
}


结果

2017.10.06 01:28:05.885 TestTets EURUSD,M1: close #240725107  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.775 TestTets EURUSD,M1: Alert: Hello World!
2017.10.06 01:28:05.775 TestTets EURUSD,M1: close #240725108  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.673 TestTets EURUSD,M1: Alert: Hello World!
2017.10.06 01:28:05.673 TestTets EURUSD,M1: close #240725110  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.578 TestTets EURUSD,M1: Alert: Hello World!
2017.10.06 01:28:05.578 TestTets EURUSD,M1: close #240725111  buy 1.00 EURUSD at 1.17121 at price 1.17099
2017.10.06 01:28:05.480 TestTets EURUSD,M1: open #240725112  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.343 TestTets EURUSD,M1: open #240725111  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.253 TestTets EURUSD,M1: open #240725110  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.138 TestTets EURUSD,M1: open #240725108  buy 1.00 EURUSD at 1.17121 ok
2017.10.06 01:28:05.035 TestTets EURUSD,M1: open #240725107  buy 1.00 EURUSD at 1.17121 ok


同一张票可能会在无害的循环计票中出票两次!

Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
 
fxsaber:

同一张票可以在一个无害的计票周期内出票两次!这就是所谓的 "无害"。

为了打消所有的疑虑,请做以下工作。

安装专家顾问

// Советник будет алертовать, если OrderSelect соседних индексов выберет один и тот же ордер
const bool Init =  EventSetMillisecondTimer(1);

void OnTimer()
{
  int PrevTicket = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      const int Ticket = OrderTicket();
      
      if (Ticket == PrevTicket)
        Alert("Hello World!");
        
      PrevTicket = Ticket;
      
      Sleep(1); // 1 миллисекунда - это много или мало?
    }
}


启动脚本

#property strict

void OnStart()
{
  // Открыли позиции
  for (int i = 0; i < 25; i++)
    OrderSend(_Symbol, OP_BUY, 1, SymbolInfoDouble(_Symbol, SYMBOL_ASK), 100, 0, 0);

  int Tickets[];
  const int Total = OrdersTotal();
  
  ArrayResize(Tickets, Total);
  
  for (int i = 0; i < Total; i++)
    if (OrderSelect(i, SELECT_BY_POS))
      Tickets[i] = OrderTicket();
    
  // Закрыли позиции
  for (int i = 0; i < Total; i++)
    OrderClose(Tickets[i], 1, SymbolInfoDouble(_Symbol, SYMBOL_BID), 100);
}


而且我们观察到,EA在不同的指数下选择相同的订单。而这可能导致交易逻辑的完全失败。

 
fxsaber:

EA在不同的指数下选择相同的订单。而这可能导致交易逻辑的完全崩溃。

所以,这就是主要问题的全部内容!如何安排订单的循环?例如,如何正确书写这样的函数?

// Возращает количество ордеров данного символа
int AmountOrders( const string &Symb )
{
  int Res = 0;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS) && (OrderSymbol() == Symb))
      Res++;
      
  return(Res);
}


这条线的出发点是,当搜索周期中出现暂停时,指定一些重复动作的必要性。这里停顿大约一毫秒就足以看到效果。

到目前为止,这样的拐杖。

bool IsChange( const bool InitFlag = false )
{
  static int PrevTotal = 0;
  static int PrevHistoryTotal = 0;
  
  const int Total = OrdersTotal();
  const int HistoryTotal = OrdersHistoryTotal();    
  
  if (InitFlag)
  {
    PrevTotal = Total;
    PrevHistoryTotal = HistoryTotal;    
  }
  
  return(!InitFlag && ((Total != PrevTotal) || (HistoryTotal != PrevHistoryTotal)));
}

// Возращает количество ордеров данного символа
int AmountOrders( const string &Symb )
{
  int Res = 0;
  
  IsChange(true);
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (IsChange())
    {
      i = OrdersTotal();
      
      Res = 0;
    }
    else if (OrderSelect(i, SELECT_BY_POS) && (OrderSymbol() == Symb))
      Res++;
      
  return(Res);
}

但不能确定它是否总是能正确工作。

 
fxsaber:

为了打消所有的疑虑,请做以下工作。

安装专家顾问

运行脚本

而我们看到,EA在不同的指数下选择相同的订单。而这可能导致交易逻辑的完全失败。

我已经改变了

// Советник будет алертовать, если OrderSelect соседних индексов выберет один и тот же ордер
const bool Init =  EventSetMillisecondTimer(1);

bool IsChange( const bool InitFlag = false )
{
  static int PrevTotal = 0;
  static int PrevHistoryTotal = 0;
  
  const int Total = OrdersTotal();
  const int HistoryTotal = OrdersHistoryTotal();    
  
  if (InitFlag)
  {
    PrevTotal = Total;
    PrevHistoryTotal = HistoryTotal;    
  }
  
  return(!InitFlag && ((Total != PrevTotal) || (HistoryTotal != PrevHistoryTotal)));
}

void OnTimer()
{
  int PrevTicket = 0;
  
  IsChange(true);
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (IsChange())
    {
      i = OrdersTotal();
      
      PrevTicket = 0;
    }
    
    else if (OrderSelect(i, SELECT_BY_POS))
    {
      const int Ticket = OrderTicket();
      
      if (Ticket == PrevTicket)
        Alert("Hello World!");
        
      PrevTicket = Ticket;
      
      Sleep(1); // 1 миллисекунда - это много или мало?
    }
}

我们在没有警报的情况下改变了脚本。