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

 
fxsaber #:

К сожалению, в такой реализации при добавлении нового поля требуется дописывать метод ToString.

Вот такой вариант:

#define TO_STR(A) #A

#include <Arrays\ArrayObj.mqh>

class Variable : public CObject {
 public:
  virtual string ToString(void) const = 0;
  virtual string TypeName(void) const = 0;
  virtual string ClassName(void) const = 0;
};

class IntVariable : public Variable {
  int value;
 public:

  IntVariable(int v) : value(v) {}
  virtual string ToString(void) const override {
    return(IntegerToString(value));
  }
  virtual string TypeName() const override {
    return(TO_STR(int));
  }
  virtual string ClassName() const override {
    return(TO_STR(IntVariable));
  }
};

class DoubleVariable : public Variable {
  double value;
 public:
  DoubleVariable(double v) : value(v) {}
  virtual string ToString(void) const override {
    return(DoubleToString(value, 8));
  }
  virtual string TypeName() const override {
    return(TO_STR(double));
  }
  virtual string ClassName() const override {
    return(TO_STR(DoubleVariable));
  }
};

class MyClass {
 public:
  CArrayObj variables;

 public:
   MyClass() {}
  ~MyClass() {
    for(int i = 0; i < variables.Total(); ++i) {
      delete variables.At(i);
    }
    variables.Clear();
  }

  string ToString(void) const {
    string result;
    for(int i = 0; i < variables.Total(); ++i) {
      Variable *var = (Variable*)variables.At(i);
      if (i > 0) result += ", ";
      result += var.ClassName() + " (" + var.TypeName() + "): " + var.ToString();
    }
    return result;
  }
};
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(void) {
  
  MyClass my_class;
  
  my_class.variables.Add(new IntVariable(10));
  my_class.variables.Add(new DoubleVariable(3.14));
  
  Print(my_class.ToString());
  
  my_class.variables.Clear();
}

//---

Результат:

IntVariable (int): 10, DoubleVariable (double): 3.14000000
 
Привет,

Помогите разобраться. Если использовать стандартные модули MoneyManagement - даже можно генератором сделать - OrderCalcMargin возвращает true, но margin при этом всегда 0.

Вот вызов функции в AccountInfo 
OrderCalcMargin(trade_operation,symbol,1.0,price,margin)

при margin 0 дальнейшее выполнение кода ведёт к использованию maxvolume символа. 10000000 лотов



Т.к. OrderCalcMargin какая-то встроенная функция без возможности дебага не могу определить что идёт не так.
Вывел переменные чтобы проверить хотя бы на значения:

   double margin, margin_rate;
   double margin_init = SymbolInfoDouble( Symbol(), SYMBOL_MARGIN_INITIAL );
   double ask = SymbolInfoDouble( Symbol(), SYMBOL_ASK );
   
   SymbolInfoMarginRate( Symbol(),ORDER_TYPE_SELL, margin_init, margin_rate);
   Print( "Init Margin: ",SymbolInfoDouble(Symbol(), SYMBOL_MARGIN_INITIAL) );
   Print( "Margin Rate: ", margin_rate);
   Print( "Price is: ", ask);
   Print( "Calc Margin is: ", (OrderCalcMargin(ORDER_TYPE_SELL,Symbol(),1.0,ask,margin)));
   Print( "Margin is: ", margin);

2024.01.16 06:06:30.260 2023.09.01 09:00:00   Init Margin: 15000.0
2024.01.16 06:06:30.260 2023.09.01 09:00:00   Margin Rate: 1.0
2024.01.16 06:06:30.260 2023.09.01 09:00:00   Price is: 95591.0
2024.01.16 06:06:30.260 2023.09.01 09:00:00   Calc Margin is: true
2024.01.16 06:06:30.260 2023.09.01 09:00:00   Margin is: 0.0
Всё выводится верно и имеет смысл кроме Margin is 0.0

В документации написано что SYMBOL_CALC_MODE_FUTURES и  SYMBOL_CALC_MODE_EXCH_FUTURES запрашивает для калькуляции маржи следующее

Margin: Lots * InitialMargin * Margin_Rate

при вызове функции Lots is 1.0, Init Margin is 15000, Margin Rate is 1. Каким образом это выливается в margin 0.0 понять не могу.

Пробовал различные символы фьючей - истекшие, текущие - результат один и тот же.

Проверить поведение можно просто сгенерировав советника и добавив MoneySizeOptimized в части где указываешь moneyManagement, с остальными модулями МаниМенеджмента такой же результат. Что ожидаемо потому что дело в этой функции OrderCalcMargin() класса 
AccountInfo.

Заранее спасибо!
Documentation on MQL5: Trade Functions / OrderCalcMargin
Documentation on MQL5: Trade Functions / OrderCalcMargin
  • www.mql5.com
OrderCalcMargin - Trade Functions - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Anatoli Kazharski #:

Вот такой вариант:

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

 
fxsaber #:

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

Можно попробовать добавить имя переменной, как строковой параметр. А доступ к значению через CHashMap.

Документация по MQL5: Стандартная библиотека / Шаблонные коллекции данных / CHashMap
Документация по MQL5: Стандартная библиотека / Шаблонные коллекции данных / CHashMap
  • www.mql5.com
CHashMap - Шаблонные коллекции данных - Стандартная библиотека - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
class A {};

void OnStart()
{
  A* a1 = A();
  A* a2 = &A();
}

Отсутствие ошибки в выделенной строке (указатель равен объекту) - правильно?

 
class A {};

template <typename T>
class B : public A
{
public:
  B( T ) {}
};

void OnStart()
{
  A* a1 = new B(0); // fatal compiler error: constructor of class 'B' not found
  A* a2 = new B<int>(0); // OK
}

Вроде, все однозначно, но компилятор ругается.

 
fxsaber #:

Вроде, все однозначно, но компилятор ругается.

Ваш код содержит несколько ошибок. Давайте разберем их по порядку:

  1. В первом блоке кода:

A* a1 = A(); A* a2 = &A();

Здесь вы пытаетесь присвоить временный объект типа  A  указателю  a1 . Это вызовет ошибку компиляции, потому что  A()  создает временный объект, который уничтожается сразу после этого выражения, и вы не можете безопасно присвоить его указателю. Вместо этого, вы должны использовать оператор  new  для создания объекта в динамической памяти:

    A* a1 = new A();

В случае с  a2 , вы пытаетесь получить адрес временного объекта, что также недопустимо.

  1. Во втором блоке кода:

A* a1 = new B(0); // fatal compiler error: constructor of class 'B' not found A* a2 = new B<int>(0); // OK

Здесь вы пытаетесь создать объект типа  B  с помощью шаблонного параметра, который не указан. Компилятор не может определить, какой тип использовать для  T  в  B(0) , поэтому возникает ошибка. Вместо этого, вы должны явно указать тип параметра, как вы делаете в следующей строке:

    A* a1 = new B<int>(0); // OK

Это исправит ошибку компиляции. Надеюсь, это помогло! Если у вас есть еще вопросы, не стесняйтесь задавать.

 
Yuriy Vasilyev #:

Ваш код содержит несколько ошибок.

Тест Тьюринга не пройден, к сожалению.
 
Коллеги, с дистрибутивом именно Ф*нама(не знаю можно ли здесь писать),

Проверьте пожалуйста корректность работы функции советника на каком-нибудь фьюче. Похоже критический баг для расчета маржи - всегда возвращает 0.

double margin;
Print( "Calc Margin is: ", OrderCalcMargin( ORDER_TYPE_BUY, Symbol(), 1.0, SymbolInfoDouble(_Symbol, SYMBOL_ASK), margin ));
Print( " Margin is: ", margin);
Если выдаёт значение отличное от нуля напишите что за билд?

Спасибо!
 
fxsaber #:
class A {}; template <typename T> class B : public A { public:   B( T ) {} }; void OnStart() {   A* a1 = new B(0); // fatal compiler error: constructor of class 'B' not found   A* a2 = new B<int>(0); // OK }
class A {};

template <typename T>
class B : public A
{
public:
  B( T ) {}
};

void OnStart()
{
  A* a1 = new B<int>(0); // OK now
  A* a2 = new B<int>(0); // OK
}