在休息室谈论巴解组织的问题 - 页 4

 
Dennis Kirichenko:

说得好 。如果这些论点能有代码支持,而不是只是胡说八道,那就更好了。

支持它。

这里是我的CMyObject类。

#include <Object.mqh>

// Перечисление, в котором должны указываться все объекты, которые могут быть пронаследованны от моего объекта
enum EMyObjectTypes
{
   MOT_BASE_OBJECT                              =  0001,          // Просто CObject - фактически, никогда не должен использоваться.
   MOT_STRUCT_WRAPPER                           =  0002,          // Неинициализированный CStructWrapper
   MOT_PRICE_POINT                              =  0003,          // Класс CPricePoint   
   MOT_PRICEIDX_POINT                           =  0004,          // Класс CPriceIdxPoint  
   MOT_WPRICEIDX_POINT                          =  0005,          // Класс CWPriceIdxPoint  
   MOT_WAVE_TRIANGLE_DATA                       =  0006,          // Класс CWaveTriangleData
   MOT_WAVE_TRIANGLE                            =  0007,          // Класс CWaveTriangle
   MOT_TRADERESULT_I                            =  0008,          // Класс CTradeResultI
   MOT_TRADERESULT                              =  0009,          // Класс CTradeResult

   // Тут еще куча типов объектов - для каждого класса, свой ID
           
   MOT_UNKNOWN                                  = -0001           // Неинициализированный объект.
};

/*

Класс СMyObject - потомок от СObject, несет функциональность именования.

*/

class CMyObject: public CObject
{
protected:
   EMyObjectTypes m_motType;
   int            m_iUDCreationValue;  // Значение, определяемое пользователем при создании объекта. Предназначено для идентификации отдельных экземпляров объекта.  
   
   
   void SetMyObjectType(EMyObjectTypes motType) { m_motType = motType; };  

   // Функции вывода на печать параметров. 
   void _PrintStringParameter(string strParameterName,string strParameterValue) { Print("Object ID: " + IntegerToString(GetType()) + "; " + strParameterName + " = " + strParameterValue + "; String."); };
   void _PrintDoubleParameter(string strParameterName,double dParameterValue,int iDigits = 8) { Print("Object ID: " + IntegerToString(GetType()) + "; " + strParameterName + " = " + DoubleToString(dParameterValue,iDigits) + "; Double"); };
   void _PrintIntegerParameter(string strParameterName,long lParameterValue) {  Print("Object ID: " + IntegerToString(GetType()) + "; " + strParameterName + " = " + IntegerToString(lParameterValue) + "; Integer"); };
   void _PrintBoolParameter(string strParameterName,bool bParameterValue) { if(bParameterValue) Print("Object ID: " + IntegerToString(GetType()) + "; " + strParameterName + " = True; Bool"); else Print("Object ID: " + IntegerToString(GetType()) + "; " + strParameterName + " = False; Bool"); };
   
public:
   CMyObject(int iUDCreationValue = WRONG_VALUE) { m_iUDCreationValue = iUDCreationValue;  m_motType = MOT_UNKNOWN;  };
   
   EMyObjectTypes GetType() const { return(m_motType);    };
   bool CheckType(EMyObjectTypes motType) { return(m_motType == motType); }; 
   
   int GetUDCreationValue() { return(m_iUDCreationValue); };
   void SetUDCreationValue(int iValue) { m_iUDCreationValue = iValue; };
};

#ifdef  ASSERTION_CODE_ON

CMyObject* _PerformObjectConvertWithCheck(CMyObject* pmoObject,EMyObjectTypes motType)
{
   ASSERT_MYPOINTER(pmoObject);                    // проверим указатель
   ASSERT(pmoObject.CheckType(motType) == true);   // проверим внутренний ID типа объекта
   
   return(pmoObject);
};

#define  CONVERT_OBJECT_WITH_CHECK(objFrom,typeTo,checkType) ((typeTo*)_PerformObjectConvertWithCheck(objFrom,checkType))

#else // ASSERTION_CODE_ON

#define  CONVERT_OBJECT_WITH_CHECK(objFrom,typeTo,checkType) ((typeTo*)objFrom)

#endif // ASSERTION_CODE_ON

CONVERT_OBJECT_WITH_CHECK宏也被定义在最后,对于DEBUG版本,它根据对象类型执行额外的指针转换 检查

 
George Merts:

支持它。

这里是我的CMyObject类。

CONVERT_OBJECT_WITH_CHECK宏也被定义在最后,对于DEBUG版本,它根据对象类型执行额外的指针转换 检查


这很美。当然,这是个口味问题。但是,根据MQL的语法,我会这样写。

enum ENUM_OBJECT_TYPES
{
   OBJECT_TYPES_BASE_OBJECT                              =  0001,          // Просто CObject - фактически, никогда не должен использоваться.
   OBJECT_TYPES_STRUCT_WRAPPER                           =  0002,          // Неинициализированный CStructWrapper
   OBJECT_TYPES_PRICE_POINT                              =  0003,          // Класс CPricePoint   
   OBJECT_TYPES_PRICEIDX_POINT                           =  0004,          // Класс CPriceIdxPoint  
   OBJECT_TYPES_WPRICEIDX_POINT                          =  0005,          // Класс CWPriceIdxPoint  
   OBJECT_TYPES_WAVE_TRIANGLE_DATA                       =  0006,          // Класс CWaveTriangleData
   OBJECT_TYPES_WAVE_TRIANGLE                            =  0007,          // Класс CWaveTriangle
   OBJECT_TYPES_TRADERESULT_I                            =  0008,          // Класс CTradeResultI
   OBJECT_TYPES_TRADERESULT                              =  0009,          // Класс CTradeResult

   // Тут еще куча типов объектов - для каждого класса, свой ID
           
   OBJECT_TYPES_UNKNOWN                                  = -0001           // Неинициализированный объект.
};
 
Dennis Kirichenko:

这很美。当然,这是个口味问题。但是,根据MQL的语法,我会这样写。

是的,这是正确的。

但是,这是我衰老的 "编程风格"(你好,Volchansky和他最近的主题)。

我有所有的枚举--以E开始,然后用 "驼峰 "符号--命名。而枚举中的类型本身以枚举类型的缩写(最多四个字母)开始。

因此,由于该枚举是EMyObjectType,所有的值都以MOT_开头。

 
Комбинатор:

你是个白痴吗?)) 我没有说过一个关于F#的坏话。在发表你的愚蠢评论之前,要学会阅读和理解你被告知的内容。

如果你将OOP与FP进行比较,那么将其与纯FP语言,即Haskel进行比较是更明智的。F#已经很一般了,而python和R则完全不是。这就是我的意思。否则,我们可能会走到C++也是一种FP语言的地步。

你是一个不识字的巨魔。为了记录在案,列出的所有语言都有这样或那样的功能。去学习该学科领域。这个问题是为了了解安德烈 可能是在什么参考框架下练习FP语言之一,所以列举的内容非常笼统。

 
George Merts:

这应该是什么意思?

按照你的说法,"基本对象 "中应该有什么?

就我个人而言,在我所有的项目中,几乎所有的对象都继承自CMyObject:public CObject,(在我的对象中又增加了两个字段--类名和实例ID),并且反复发现我非常需要CObject::Compare()功能。有几次,列表指针也派上了用场。

CObject 有一个目标--提供类型控制。而且,它的管理方式很不稳定。像Next()、Prev()等方法是针对非常专业的集合。它们不属于CObject。这也与保存和加载方法有关。如果里面没有比较器就更好了,但这是没有接口的唯一解决方案。

至于Type()方法,它并不提供严格的类型,因为它返回的是通常的数字。你可以在你自己的代码的例子上看到。你定义了一个新的GetType()方法,以枚举的形式返回类型。真的没有其他办法,我自己做。这就是为什么要把标准的CObject附加到它上面,这是不正确的。

 

让我们继续讨论CObject::Compare()

我有这样一个对象CFactoryBalanceResultSeries--它是一个参考Expert Advisor工厂对象的平衡结果的系列。实际上,它是参考专家顾问交易过的历史上的平衡曲线。

因此,我有一个脚本,在那里我比较这些非常平衡的系列。

只要只有两个系列,就很容易对它们进行比较。但当有几十个时--你不能用眼睛去比较,你需要一个更正式的比较。

为了实现这一过程的自动化--我不得不写一个对这些系列进行排序的函数。在这里它是有用的,因为CFactoryBalanceResultSeries类是CObject的继承者,它的比较功能。如果我们覆盖这个函数,我们就有了对系列进行分类的可能性。

在我的案例中,这个函数看起来是这样的。

int CFactoryBalanceResultSeries::Compare(const CObject *poNode,const int iMode) const
{
   CFactoryBalanceResultSeries* pfdsAnother = CONVERT_OBJECT_WITH_CHECK(poNode,CFactoryBalanceResultSeries,MOT_FACTORYBALANCERES_SERIES);
   
   switch(iMode)
      {
      case FSM_BY_PART_OF_MAX_DD_A:    return(_CompareByPartOfMaxDDWith(pfdsAnother,true));
      case FSM_BY_PART_OF_MAX_DD_D:    return(_CompareByPartOfMaxDDWith(pfdsAnother,false));

      case FSM_BY_PART_OF_MAX_SLQUEUE_A: return(_CompareByPartOfMaxSLQueueWith(pfdsAnother,true));
      case FSM_BY_PART_OF_MAX_SLQUEUE_D: return(_CompareByPartOfMaxSLQueueWith(pfdsAnother,false));

      case FSM_BY_LAST_PRCDATA_A:      return(_CompareByLastPrcdataWith(pfdsAnother,true));
      case FSM_BY_LAST_PRCDATA_D:      return(_CompareByLastPrcdataWith(pfdsAnother,false));
      case FSM_BY_LAST_MNYDATA_A:      return(_CompareByLastMnydataWith(pfdsAnother,true));
      case FSM_BY_LAST_MNYDATA_D:      return(_CompareByLastMnydataWith(pfdsAnother,false));
      case FSM_BY_LAST_MNYLOTDATA_A:   return(_CompareByLastMnylotdataWith(pfdsAnother,true));
      case FSM_BY_LAST_MNYLOTDATA_D:   return(_CompareByLastMnylotdataWith(pfdsAnother,false));
      
      case FSM_BY_PRCYEARRECOVERY_A:   return(_CompareByYearPrcrecoveryWith(pfdsAnother,true));
      case FSM_BY_PRCYEARRECOVERY_D:   return(_CompareByYearPrcrecoveryWith(pfdsAnother,false));
      case FSM_BY_MNYYEARRECOVERY_A:   return(_CompareByMnyYearRecoveryWith(pfdsAnother,true));
      case FSM_BY_MNYYEARRECOVERY_D:   return(_CompareByMnyYearRecoveryWith(pfdsAnother,false));
      case FSM_BY_MNYLOTYEARRECOVERY_A:return(_CompareByMnylotYearRecoveryWith(pfdsAnother,true));
      case FSM_BY_MNYLOTYEARRECOVERY_D:return(_CompareByMnylotYearRecoveryWith(pfdsAnother,false));
      
      case FSM_BY_PRCVAR_A:            return(_CompareByPrcVarWith(pfdsAnother,true));
      case FSM_BY_PRCVAR_D:            return(_CompareByPrcVarWith(pfdsAnother,false));
      case FSM_BY_MNYVAR_A:            return(_CompareByMnyVarWith(pfdsAnother,true));
      case FSM_BY_MNYVAR_D:            return(_CompareByMnyVarWith(pfdsAnother,false));
      case FSM_BY_MNYLOTVAR_A:         return(_CompareByMnylotVarWith(pfdsAnother,true));
      case FSM_BY_MNYLOTVAR_D:         return(_CompareByMnylotVarWith(pfdsAnother,false));
      
      case FSM_BY_PRC_GRAILRATIO_A:    return(_CompareByPrcGrailratioWith(pfdsAnother,true));
      case FSM_BY_PRC_GRAILRATIO_D:    return(_CompareByPrcGrailratioWith(pfdsAnother,false));

      case FSM_BY_MAGIC_A:             return(_CompareByMagicWith(pfdsAnother,true));
      case FSM_BY_MAIGC_D:             return(_CompareByMagicWith(pfdsAnother,false));
      default:
         break;
      };
         
   return(NULL);
};

也就是说,根据排序的类型--我们选择所需的比较函数,这在一般的排序函数中使用。

例如,如果我们想按照最后一次缩减与最大缩减的部分对余额系列进行排序,将使用以下函数。

int CFactoryBalanceResultSeries::_CompareDblData(double dDataFirst,double dDataSecond,bool bAccending) const
{
   if(dDataFirst > dDataSecond)
      {
      if(bAccending)
         return(1);
      else   
         return(-1);
      };
   
   if(dDataFirst < dDataSecond)
      {
      if(bAccending)
         return(-1);
      else   
         return(1);
      };
      
   return(NULL);         
};

int CFactoryBalanceResultSeries::_CompareByPartOfMaxDDWith(CFactoryBalanceResultSeries* pfdsAnother,bool bAccending) const
{
   if(Total()==0 || pfdsAnother.Total() == 0 || m_pepfFactory.GetControlParams().m_dMaxPriceDrawdown == 0)
      return(NULL);
   
   double dLocalPart = GetCurPriceDD() / m_pepfFactory.GetControlParams().m_dMaxPriceDrawdown;
   double dRemotePart = pfdsAnother.GetCurPriceDD() / pfdsAnother.GetFactory().GetControlParams().m_dMaxPriceDrawdown;
      
   return(_CompareDblData(dLocalPart,dRemotePart,bAccending));   
};
 
George Merts:

我将继续使用CObject::Compare()。

从最近的

CDouble & CDoubleVector
CDouble & CDoubleVector
  • 投票: 4
  • 2018.01.09
  • nicholishen
  • www.mql5.com
A library for common rounding methods used in MQL development, primitive wrapper class for type (double), and vector for CDouble objects. MQL5 and MQL4 compatible! CDouble The CDouble class wraps a value of the primitive type double in an object. Additionally, this class provides several methods and static methods for rounding doubles and...
 
George Merts:



我认为,这不是很好看。

int CFactoryBalanceResultSeries::Compare(const CObject *poNode,const int iMode) const
{
   CFactoryBalanceResultSeries* pfdsAnother = CONVERT_OBJECT_WITH_CHECK(poNode,CFactoryBalanceResultSeries,MOT_FACTORYBALANCERES_SERIES);
   
   switch(iMode)
      {
      case FSM_BY_PART_OF_MAX_DD_A:    return(_CompareByPartOfMaxDDWith(pfdsAnother,true));
      case FSM_BY_PART_OF_MAX_DD_D:    return(_CompareByPartOfMaxDDWith(pfdsAnother,false));

      case FSM_BY_PART_OF_MAX_SLQUEUE_A: return(_CompareByPartOfMaxSLQueueWith(pfdsAnother,true));
      case FSM_BY_PART_OF_MAX_SLQUEUE_D: return(_CompareByPartOfMaxSLQueueWith(pfdsAnother,false));

你可以使用一个 指向函数的指针。

typedef int (*TCompare1)(int,bool); 
// ---
int CFactoryBalanceResultSeries::Compare(const CObject *poNode,const int iMode) const
{
   CFactoryBalanceResultSeries* pfdsAnother = CONVERT_OBJECT_WITH_CHECK(poNode,CFactoryBalanceResultSeries,MOT_FACTORYBALANCERES_SERIES);
   
   switch(iMode)
      {
      case FSM_BY_PART_OF_MAX_DD_A:    return(TCompare1(pfdsAnother,true));
      case FSM_BY_PART_OF_MAX_DD_D:    return(TCompare1(pfdsAnother,false));

      case FSM_BY_PART_OF_MAX_SLQUEUE_A: return(TCompare1(pfdsAnother,true));
      case FSM_BY_PART_OF_MAX_SLQUEUE_D: return(TCompare1(pfdsAnother,false));

.....
      }
}
 
George Merts:

是的,这是正确的。

但是,这是我衰老的 "编程风格"(你好,Wolchansky和他最近的主题)。

我有所有的枚举--以E开始,然后是 "驼峰 "记号--名称。而枚举中的类型本身以枚举类型的缩写(最多四个字母)开始。

相应地,由于EMyObjectType的枚举--所有的值都以MOT_开头。


是的,我也有同样的列举。

ZS:现在刚到电脑前。不出所料,这个话题很快就沦为垃圾)。我将尝试在以后完成关于虚拟功能 的故事。我们应该把这个论坛叫做Blah Blah Blah Blah)。

 

我看了大家不同的兴趣......我正在重新设计一个班级,建立和管理 一个虚拟 网格,我需要它。

原因: