Ошибки, баги, вопросы - страница 2451

 
В сторадж невозможно внести файл, в имени которого есть символ #. Это нормальное поведение или баг?
 

Если речь о FX, то там тики не сильно меняет цену (обычно). Но на других рынках ордер может серьёзно проскользнуть при потиковом подходе. Я все-таки за попытки между тиками - вреда не вижу, потенциальная польза - есть. 

Надо пробовать...

 
Гистерезис в действии... на примере работы неявного оператора копирования присваивания в структурах.

#define PRINT(x) Print(#x, ":", string(x))

struct MyArray{
   uchar data[];
};


void OnStart(){
   MyArray tmp_arr;
   
   MyArray huge_arr;
   ArrayResize(huge_arr.data, 1000);
   ArrayInitialize(huge_arr.data, 0x8);
   
   MyArray small_arr;
   ArrayResize(small_arr.data, 10);
   ArrayInitialize(small_arr.data, 0x1);
   
   
   tmp_arr = small_arr;
   Print("\r\nTest with small_arr");
   PRINT(ArraySize(tmp_arr.data));
   PRINT(tmp_arr.data[0]);
   PRINT(tmp_arr.data[ArraySize(tmp_arr.data)-1]);
   
   tmp_arr = huge_arr;
   Print("\r\nTest with huge_arr");
   PRINT(ArraySize(tmp_arr.data));
   PRINT(tmp_arr.data[0]);
   PRINT(tmp_arr.data[ArraySize(tmp_arr.data)-1]);
   
   tmp_arr = small_arr;
   Print("\r\nTest with small_arr");
   PRINT(ArraySize(tmp_arr.data));
   PRINT(tmp_arr.data[0]);
   PRINT(tmp_arr.data[ArraySize(tmp_arr.data)-1]);
}

Результат:
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   Test with small_arr
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   ArraySize(tmp_arr.data):10
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   tmp_arr.data[0]:1
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   tmp_arr.data[ArraySize(tmp_arr.data)-1]:1
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   Test with huge_arr
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   ArraySize(tmp_arr.data):1000
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   tmp_arr.data[0]:8
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   tmp_arr.data[ArraySize(tmp_arr.data)-1]:8
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   Test with small_arr
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   ArraySize(tmp_arr.data):1000
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   tmp_arr.data[0]:1
2019.05.03 14:29:14.005 Test_push (EURUSD,H1)   tmp_arr.data[ArraySize(tmp_arr.data)-1]:8
 
Sergey Dzyublik:
Гистерезис в действии... на примере работы неявного оператора копирования в структурах.

Наверное, чтобы обнаружить такое, нужно было в поисках ошибки в своем коде дойти до внутреннего состояния/упорства "здесь ничего не может не работать, но все равно проверю".

 
fxsaber:

Наверное, чтобы обнаружить такое, нужно было в поисках ошибки в своем коде дойти до внутреннего состояния/упорства "здесь ничего не может не работать, но все равно проверю".

Код парсил поток байтов под определенный протокол.
Не сходились размеры распакованных и не распакованных данных (данных для следующего уровня инкапсуляции).

 
Sergey Dzyublik:

Код парсил поток байтов под определенный протокол.
Не сходились размеры распакованных и не распакованных данных (данных для следующего уровня инкапсуляции).

С такой задачей не сложно обнаружить. Повезло.
 
Sergey Dzyublik:
Гистерезис в действии... на примере работы неявного оператора копирования в структурах.

А в чем вопрос?

void OnStart()
{
        int a[]; ArrayResize( a, 3 ); ArrayInitialize( a, 3 );
        int b[]; ArrayResize( b, 2 ); ArrayInitialize( b, 2 );

в MQL условная запись

//                 a = b;

равносильна

        ArrayCopy( a,  b );

Результат:

        ArrayPrint( a );
}

2 2 3

 
A100:

А в чем вопрос?


Оператор копирования присваивания, на мой взгляд, должен копировать не только сами элементы массива, но и их количество, оставив действительным количество зарезервированной памяти.

А сейчас происходит практически следующее:

int size;
size = 4; // size == 4
size = 8; // size == 8
size = 4; // size == 8



Исходный код:

struct MyArray{
   uchar 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 8 8 8 8
}
 
Sergey Dzyublik:


Оператор копирования должен копировать не только сами элементы массива, но и их количество, оставив действительным количество зарезервированной памяти.

А почему тогда

struct MyArray {
        uchar data[];
};
void OnStart()
{
        { uchar   a[], b[]; a = b; } //(1) Error
        { MyArray a,   b;   a = b; } //(2) нормально
}

в (1) случае ошибка, а во (2) все нормально!? Какая разница?

А такая что копированиe массивов происходит не по правилам a = b, а по правилам ArrayCopy( a,  b )

Не по правилам a = b, потому что его нету, если бы оно было, то ошибки (1) не было бы


 
Igor Zakharov:

Если считать на каждом тике - это ресурсоёмко, особенно заметно в тестере стратегий. Не правильнее ли пересчёт делать только при событии Trade, т.е. когда реально меняется что-то в перечне открытых позиций? С OnTradeTransaction() упрощается контроль за вмешательством пользователя в работу советника. (есть прецеденты :)

В данном роботе тестил возможность закрытия сеток по схеме: убыточная + прибыльная > Х , то закрыть обе (как правило, на разных символах). Но сбой получается, т.к. не смотря на то, что они закрыты, тестер не знает об этом, и переходит к следующей итерации, ошибочно "спаривая" существующие с уже закрытыми. Т.е. пришлось добавить пересчёт после каждого закрытия.

Пересчёт у меня со сбросом счётчика и сначала по всем отрытым, не +1 / -1

Согласен, рисковано было изначально использовать OnTradeTransaction() Вообще, наверное, откажусь от неё в случаях когда запросы не асинхронные - одни проблемы от неё.

Нисколько не рискованно. Вопрос только в организации последовательности действий и событий. Барабашка правильно дальше сказал, закрыл пару и вышел из цикла до следующего тика. На следующем тике не факт что цены будут хуже чем есть. Может и лучше будет закрыть чуть позже, зато не будет путаницы что с чем закрылось.

Второй вариант: цикл организовать не по PositionsTotal, а по массиву созданному заранее. И при закрытии какой-то пары эти тикеты удалять из массива. Это не даст попасть закрытым позициям повторно на закрытие. В общем полёт фантазии и логика действий.