组织订单周期 - 页 9

 
fxsaber:

改变了

现在没有警报。

答案是显而易见的--如果Ticket == PrevTicket ---> 返回WRONG_VALUE

如果函数的返回值小于零,那么应该再次调用。

 
Artyom Trishkin:

答案是显而易见的--如果Ticket == PrevTicket ---> 返回WRONG_VALUE

因此,这是问题的一个特例的解决方案,我为了清楚地描述了相邻票的平等形式。

问题其实是一样的--循环过程中的索引震荡。这可能导致一些票据被跳过,或一个票据在一个票据中被重复,等等。

我还没有找到IsChange的替代品。

 
fxsaber:

因此,这是问题的一个特殊情况的解决方案,为了清楚起见,我以相邻票的平等形式描述了这个问题。

问题其实都是一样的--在周期中摇动索引。这可能导致一些票据被跳过,或一个票据在一个票据中被重复,等等。

我还没有找到IsChange的替代品。

我们在定时器中创建一个列表,然后用它来工作。

 
Artyom Trishkin:

在计时器中创建一个列表,然后用它来工作。

在代码中更好。

 
fxsaber:

在代码中更好。

这在代码中很难显示--有一整个相互关联的类库。

其思路如下--我们传递账户上的所有订单和头寸,并在定时器中填充CArrayObj列表。我们不断地更新它,以便一次性地获得实际信息。

如果需要平仓 或删除订单,我们获得这个列表,并从中选择平仓(修改)功能所需的必要订单对象及其票据。如果这个订单对象实际不存在(在这些行动中关闭或删除),我们只需转到列表中的下一个对象,因为这个对象已经被关闭,列表将在下一次定时器迭代时被更新。我想到的第一个问题是,当交易环境在清单上的行动的时间内发生变化时,清单是不相关的。但在我看来,列表中没有订单不应该给我们带来太多困扰--我们只是得到一个错误,然后转到列表中的下一个--这个列表不像在交易环境中那样被洗牌,跳过是不可能的--只是声明列表中的一个条目没有对应的订单。

这是我到目前为止 的想法,因为我还没有在我的代码中实现它。我正准备实施,但最初我需要完成一些其他的类(我问了一个关于功能分支中的函数替换的问题)。当我开始实施时,可能的问题会在那里显现出来,我将决定如何解决这些问题,并修复它们。

 
Artyom Trishkin:

答案是显而易见的--如果Ticket == PrevTicket ---> 返回WRONG_VALUE

如果该函数返回的值小于零,我们需要再次调用它。

你根本不需要做什么。遵循逻辑看起来像个白痴就够了。

我们有6个订单

  • 0 票 100
  • 1张门票 101
  • 2张票 102
  • 3 票 103
  • 4张票 104
  • 5 票 105

我们开始翻阅订单,比方说,修改。

我们选择5张105号票,检查我们是否要修改它,并修改它。

这时,我们的不洁之手删除了第2张102号订单,名单也被改变了。105号票的订单现在是列表中的第四个,即4号。 而且它又被选中进行修改。但我们在工作中不会不检查...它并不...那又怎样?谁因为订单被重新选择而受到了伤害?

 
Artyom Trishkin:

这在代码中很难显示--有一整个相互关联的类库。

其思路如下--我们传递账户上的所有订单和头寸,并在定时器中填充CArrayObj列表。我们不断地更新它,以便一次性地获得实际信息。

如果需要平仓 或删除订单,我们获得这个列表,并从中选择平仓(修改)功能所需的必要订单对象及其票据。如果这个订单对象实际不存在(在这些行动中关闭或删除),我们只需转到列表中的下一个对象,因为这个对象已经被关闭,列表将在下一次定时器迭代时被更新。我想到的第一个问题是,当交易环境在清单上的行动的时间内发生变化时,清单是不相关的。但在我看来,列表中没有订单不应该给我们带来太多困扰--我们只是得到一个错误,然后转到列表中的下一个--这个列表不像在交易环境中那样被洗牌,跳过是不可能的--只是声明列表中的一个条目没有对应的订单。

这是我到目前为止 的想法,因为我还没有在我的代码中实现它。我正准备实施,但最初我需要完成一些其他的类(我问了一个关于功能分支中的函数替换的问题)。当我开始实施时,可能的问题会在那里显现出来,我将决定如何解决这些问题,并修复它们。

下面是一个实现的方法

关于交易、自动交易系统和交易策略测试的论坛

组织一个订单循环

fxsaber, 2017.09.11 20:29

// Редкий, но правильный костяк модификации ордеров
for (int i = OrdersTotal() - 1; i >= 0; i--)
  if (OrderSelect(i, SELECT_BY_POS))
    if (OrderModify(OrderTicket(), Price, SL, TP, OrderExpiration()))     
    {
      i = OrdersTotal(); // Хотя бы так
      
      // А лучше так
//      OnTick(); break; // вместо строки выше лучше делать такой вызов (переполнения стека от рекурсивных вызовов быть не должно)
    }


在发送交易指令 后,交易环境会发生变化,因此建议在交易服务器响应后立即从头开始执行TS的所有交易逻辑。

只是它仍然需要IsChange。计时器根本就不是一个选项。即使是Sleep(1)也破坏了整个画面。

 
Alexey Viktorov:

绝对不需要做什么。带着白痴的表情走过这些逻辑就足够了。

塔基,是的,如果关闭/激活一个订单被选中,就不会有问题。
好吧,如果它自己的刻度线阵列,那么订单将只是错过。

ps.让我抛出另一个案例--如果一个挂单被设置为阻止一个真实订单(用于翻转),那么当阻止被触发时,挂单可能会被无限期地延迟开仓。也就是说,一个订单将被市场触发,而另一个订单将被挂起一定数量的点位。

 
fxsaber:

下面是一个实现的方法

只是它仍然需要IsChange。计时器根本就不是一个选项。即使是Sleep(1)也破坏了整个画面。

IsChange()正是在定时器中实现的(测试版本还没有完成)。

//+------------------------------------------------------------------+
//| Обновляет список ордеров                                         |
//+------------------------------------------------------------------+
int CMarketCollection::Refresh(void)
  {
   ::ZeroMemory(m_struct_market);
   int number_new=0, total=::OrdersTotal();
   m_list_all_orders.Clear();
   for(int i=0; i<total; i++){
      if(!::OrderSelect(i,SELECT_BY_POS)) continue;
      long ticket=::OrderTicket();
      m_struct_market.hash_sum_acc+=ticket;
      m_struct_market.total_volumes+=::OrderLots();
      ENUM_ORDER_TYPE type=(ENUM_ORDER_TYPE)::OrderType();
      if(type==ORDER_TYPE_BUY || type==ORDER_TYPE_SELL){
         CMarketOrder* order=new CMarketOrder();
         if(order==NULL) continue;
         m_list_all_orders.InsertSort(order);
         m_struct_market.total_positions++;
         }
      else{
         CMarketPending* order=new CMarketPending();
         if(order==NULL) continue;
         m_list_all_orders.InsertSort(order);
         m_struct_market.total_pending++;
         }
      }
   //--- Первый запуск
   if(m_hash_sum_acc_prev==WRONG_VALUE){
      m_hash_sum_acc_prev=m_struct_market.hash_sum_acc;
      m_total_positions_prev=m_struct_market.total_positions;
      m_total_pending_prev=m_struct_market.total_pending;
      m_total_volume_prev=m_struct_market.total_volumes;
      }
   //---
   if(m_struct_market.hash_sum_acc!=m_hash_sum_acc_prev){
      number_new=(m_struct_market.total_pending+m_struct_market.total_positions)-(m_total_positions_prev+m_total_pending_prev);
      Print(FUNC,"Хэш-сумма всех ордеров и позиций изменилась");
      //--- Увеличисля общий объём
      if(::NormalizeDouble(m_struct_market.total_volumes-m_total_volume_prev,3)>0){
         Print(FUNC,"Общий объём увеличился");
         if(m_struct_market.total_positions>m_total_positions_prev) Print(FUNC,"Количество позиций увеличилось");
         if(m_struct_market.total_pending>m_total_pending_prev) Print(FUNC,"Количество ордеров увеличилось");
         //--- Отправка EVENT в управляющий класс CEngine
         // сделать!
         }
      //--- Уменьшился общий объём
      else if(::NormalizeDouble(m_struct_market.total_volumes-m_total_volume_prev,3)<0){
         Print(FUNC,"Общий объём уменьшился");
         if(m_struct_market.total_positions<m_total_positions_prev) Print(FUNC,"Количество позиций уменьшилось");
         if(m_struct_market.total_pending<m_total_pending_prev) Print(FUNC,"Количество ордеров уменьшилось");
         //--- Отправка EVENT в управляющий класс CEngine
         // сделать!
         }
      else{
         // что-то ещё, не пойму пока что именно - не было претендентов ещё
         }
      //---
      m_hash_sum_acc_prev=m_struct_market.hash_sum_acc;
      m_total_positions_prev=m_struct_market.total_positions;
      m_total_pending_prev=m_struct_market.total_pending;
      m_total_volume_prev=m_struct_market.total_volumes;
      }
   //---
   //---
   return number_new;
  }
//+------------------------------------------------------------------+

控制类可以通过两个类的Refresh()返回的数字(在测试器中)来捕捉变化。

//+------------------------------------------------------------------+
//| Таймер                                                           |
//+------------------------------------------------------------------+
void CEngine::OnTimer(void)
  {
   //--- Обновление списка исторических ордеров и позиций
   m_new_history=History.Refresh();
   if(m_new_history>0){
      Print(FUNC,"Изменение в исторических на ",m_new_history);
      //--- реакция
      }
   //--- Обновление списка рыночных ордеров и позиций
   m_new_market=Market.Refresh();
   if(m_new_market!=0){
      Print(FUNC,"Изменение в активных на ",m_new_market);
      //--- реакция
      }
   //---
   Sym.OnTimer();
  }
//+------------------------------------------------------------------+

或在一个用户事件中,这些都还没有实现(演示,真实)。

 
Artyom Trishkin:

IsChange()正是在定时器中实现的(尚未完成测试版本)。

为什么,如果IsChange是五行?