错误、漏洞、问题 - 页 2452

 
A100:

复制数组的不是按a = b的规则,而是按ArrayCopy( a, b ) 的规则。

是你自己编的还是在什么地方写的?
让我提醒你,这是一个用于动态数组结构的隐式赋值运算符

 
Sergey Dzyublik:

是他们自己发明的还是在什么地方写的?
让我提醒你,这是有动态数组的结构的隐式赋值运算符 的工作。

这不是我的主意,是开发商的。

        uchar a[], b[]; a = b; //Error: invalid array access
为什么会出现错误?你把它包装成一个结构,错误就消失了?为什么呢?什么东西从根本上改变了?我的上述答案
 
Alexey Viktorov:

这只是一个组织行动和事件顺序的问题。

你自己引用了手册中的话,其中说到一致性是无法保证的。这就是为什么它是有风险的。

我已经开始按照Vladimir的建议重写代码了,但是我偶然发现了一种情况,当关闭的时间长于tick时--又是重复计数(计数中的过滤节点很重)。到目前为止,我还没有想出比在完全关闭前停下来更好的办法,以便与优化速度相妥协。

今天是星期五 :)也许休息一下后,我会想出一些办法。

在任何情况下,感谢你的想法--它们不会被遗失!"。

 
A100:

这不是我的主意,是开发商的。

始终不明白它是在哪里写的,但不要紧......
谢谢你给我带来的惊喜。

用拐杖支撑着它,继续跑。

struct MyArray{
   uchar data[];
   
   void operator=(MyArray &bytes){
      ArrayCopy(this.data, bytes.data);
      ArrayResize(this.data, ArraySize(bytes.data));
   }
};


MyArray GetArray(int i){
   MyArray arr;
   
   if (i%2 == 0){
      ArrayResize(arr.data, 8);
      ArrayInitialize(arr.data, 0x8);
   }else{
      ArrayResize(arr.data, 4);
      ArrayInitialize(arr.data, 0x4);
   }
   return arr;
}


void OnStart(){
   MyArray arr_1 = GetArray(1);
   ArrayPrint(arr_1.data);        // 4 4 4 4
   
   MyArray arr_2 = GetArray(2);
   ArrayPrint(arr_2.data);        // 8 8 8 8 8 8 8 8
   
   arr_2 = arr_1;
   ArrayPrint(arr_2.data);        // 4 4 4 4            
}
 
Igor Zakharov:

你自己引用了手册中的话,其中说到一致性是无法保证的。这就是为什么它是有风险的。

我已经开始按照Vladimir的建议重写代码,但我偶然发现了一种情况,当收盘时间长于tick时--又是重复计数(计数中的过滤节点很重)。到目前为止,我还没有想出比在完全关闭前停下来更好的办法,以便与优化速度相妥协。

今天是星期五 :)也许休息一下后,我会想出一些办法。

无论如何,感谢你的想法--它们不会被浪费掉的!"。

我说的是我自己的一致性。

根据我的观察,事实证明,在OnTick之后,当交易发生时,代码执行被传递到OnTradeTransaction 函数,而不等待下一个tick。因此,由其自身功能或由 OnTradeTransaction 处理平仓没有区别 但我更喜欢用 OnTradeTransaction 工作 最主要的是正确安排操作顺序,而不依赖来自服务器的交易顺序。而正确理解 这个顺序是很重要的 。同样,根据我自己的观察,序列可以在交易类型中被打破。也就是说,可以先执行TRADE_TRANSACTION_DEAL_ADD,然后再 执行TRADE_TRANSACTION_HISTORY_ADD,而从逻辑上讲,应该先将订单加入历史,然后再加入交易

ps;然后,正如我所说,通过筛选TRADE_TRANSACTION_DEAL_ADD 交易,你可以按开仓和平仓进行筛选毕竟,我们谈论的是外汇市场的专家顾问和账户,对吗?因此,没有必要在每次打喷嚏时重新计算所有位置。如果它被打开了,只需增加一个,如果它被关闭了,只需从计数中删除一个。
 
Alexey Viktorov:

的外汇市场和账户,对吗?

格:)是的。

目前的逻辑是这样的:有一个结构存储了每个格子的所有信息:符号-头寸数-暨-利润和其他一些不重要的东西......。如果有订单(多符号机器人),则利润由计时器重新计算。但在OnTradeTransaction 中重新计算了手数和数量(以防用户 "帮忙")。

我想检查一种情况,例如一个网格盈利100美元,而另一个网格亏损50美元--以50美元的利润关闭这两个网格,以防止其增长。

目前,我已经这样做了。

void  OnTradeTransaction(
   const MqlTradeTransaction&    trans,     // trade transaction structure 
   const MqlTradeRequest&        reqst,     // request structure 
   const MqlTradeResult&         reslt      // response structure 
    )
{
 int index=-1;
 for(index=0;index<symbols_total;index++)
  if(ARRAY[index].symbol==trans.symbol) break; //нашли индекс символа по которому прошла трансакция в массиве структур
 
 if(index>=0) CountOrders(index); //пересчитали элемент
}

到目前为止,我在关闭几个网格后 添加了CountOrders()对于一个战略测试员来说,这很有效。对于一个真实的账户,我将使用弗拉基米尔的方案(有一个已关闭的票据阵列)。

顺便说一下,对关闭没有证明自己 - 缩减没有大大减少,而利润削减得很好。

[删除]  
Vladimir Karputov:

我将放弃所有的while、Sleep和OnTimer来完成平仓 的任务。我的做法是:拍下平仓单--退出OnTick,在下一个tick上检查:如果有需要的票据的仓位仍然存在--再次拍下平仓单,如此循环,通过进入/退出到OnTick。

逻辑如下:平仓是第一要务,所以平仓循环是在OnTick的最开始。形成闭合票的阵列可以在OnTick的任何地方--甚至在最末端。

迟早,你会出现以下情况:你需要平仓,一个平仓指令被发送(MQL5),也就是说,一个相反类型的订单被发送,因为你没有在适当的处理程序中跟踪交易行为(或者没有在你的EA中保存仓位状态),在下一个tick上,一个平仓指令可能正在发送过程中,你将发送另一个订单。其结果是一个相反方向的位置。

 
Alexey Kozitsyn:

迟早你会出现以下情况:你需要平仓,你发送了一个平仓指令(MQL5),也就是说,你发送了一个相反类型的指令,因为你没有在相应的处理程序中跟踪交易行为(或者没有在你的EA中保存仓位状态),在下一个点上,可能正在发送平仓指令,但你发送了另一个指令。其结果是一个相反方向的位置。

对于这种情况,我们有。

10036

交易_retcode_position_closed

具有指定的 POSITION_IDENTIFIER的位置 已经被关闭

平仓是与要平仓的票据一起发送的,所以你描述的情况不太可能发生。

[删除]  
Sergey Dzyublik:

我一直不明白它是在哪里写的,但这并不重要......。
谢谢你给我带来的惊喜。

用拐杖支撑着它,继续跑。

嗯,数组的复制方式很奇怪,但有些人甚至喜欢它...

我已经在一个数组上做了一个或多或少的包裹,没有任何问题。

https://www.mql5.com/ru/forum/221917/page26#comment_11233214

 
A100:

这不是我的主意,是开发商的。

我不记得他们曾经这样说过。

赋值运算符 的目的是创建一个对象的相同副本,这是它的目的。 当你把某个东西等同于某个东西时,你显然应该在左边得到一个完整的副本,而不是其他东西。 所以这里显然有一个错误。