你为什么这么喜欢预处理器指令? 我看到的所有代码中都有。就规范化本身而言,这个话题很有趣,但不需要预处理器指令也能实现,语言允许你这样做。
重复的代码很烦人。我喜欢简洁、高效和逻辑性。例如
fxsaber, 2016.10.19 07:59
这就是 date-to-date 的作用。CopyTicks仅仅因为名称中含有 "Copy",就试图将语法套入Copy函数,这不会带来任何便利。当你可以像下面这样使用预处理器时,才会觉得方便和合理
// 它还设置了 MT4 的常用功能:iOpen、iHigh、iLow、iClose、iTime、iVolume。
#define DEFINE_TIMESERIE(NAME,FUNC,T) \
class CLASS##NAME \
{ \
public: \
static T Get( const string Symb, const int TimeFrame, const int iShift ) \
{ \
T tValue[]; \
\
return((Copy##FUNC((Symb == NULL) ? _Symbol : Symb, _Period, iShift, 1, tValue) > 0) ? tValue[0] : -1); \
} \
\
T operator []( const int iPos ) const \
{ \
return(CLASS##NAME::Get(_Symbol, _Period, iPos)); \
} \
}; \
\
CLASS##NAME NAME; \
\
T i##NAME( const string Symb, const int TimeFrame, const int iShift ) \
{ \
return(CLASS##NAME::Get(Symb, TimeFrame, iShift)); \
}
DEFINE_TIMESERIE(Volume, TickVolume, long)
DEFINE_TIMESERIE(Time, Time, datetime)
DEFINE_TIMESERIE(Open, Open, double)
DEFINE_TIMESERIE(High, High, double)
DEFINE_TIMESERIE(Low, Low, double)
DEFINE_TIMESERIE(Close, Close, double)
按照你的交流风格--举例说明使用你的库会显示比正常化更高的速度:)
这主要取决于终端的比特率。在 MT4 上,速度差异应该特别明显。Renat 在此主题中进行了比较。
- www.mql5.com
令人讨厌的重复代码。我喜欢简洁、高效和逻辑性。例如
主要取决于终端的比特率。在 MT4 上,速度上的差异尤其明显。Renat 在此主题中进行了比较。
预处理器有用性的另一个例子
有时不可能完全拒绝使用预处理器,但你的代码只是根据预处理器指令编写的。这样的代码很难阅读。
我以清晰的方式设置变量、类型、类、函数/方法和宏的名称。如果您发现滥用,请告诉我。
我阅读 kodobase 的最大障碍是强制样式化。我在 kodobase 中的几乎所有代码都经过了这种处理。之后,我几乎无法阅读自己的代码。
变量名、类型名、类名、函数/方法名和宏名的设置都很清晰。如果发现滥用,请告诉我。
我阅读 kodobase 的最大障碍是强制样式化。我在 kodobase 中的几乎所有代码都经过了这种处理。在此之后,我几乎无法阅读自己的代码。
我不是在说我自己,任何充满宏的代码都会被阅读得很糟糕,而且调试起来也非常困难,所以我总是尽量少用预处理程序,只有在绝对必要时才使用。代码中出现的宏说明算法考虑不周,我不记得这些话是谁说的了,应该是斯特劳斯特鲁普,但它们反映了一个本质--代码应该是干净的。
{
string flag = "";
#define TICKFLAG_MACRO(A) flag += ((bool)(tickflag & TICK_FLAG_##A)) ? " TICK_FLAG_" + #A : "";
TICKFLAG_MACRO(BID)
TICKFLAG_MACRO(ASK)
TICKFLAG_MACRO(LAST)
TICKFLAG_MACRO(VOLUME)
TICKFLAG_MACRO(BUY)
TICKFLAG_MACRO(SELL)
#undef TICKFLAG_MACRO
if (flag == "")
flag = " FLAG_UNKNOWN (" + (string)tickflag + ")";
return(flag);
}
#define TOSTRING(A) " " + #A + " = " + (string)Tick.A
string TickToString( const MqlTick &Tick )
{
return(TOSTRING(time) + "." + (string)IntegerToString(Tick.time_msc %1000, 3, '0') +
TOSTRING(bid) + TOSTRING(ask) + TOSTRING(last)+ TOSTRING(volume) + GetTickFlag(Tick.flags));
}
void OnStart()
{
MqlTick Tick;
if (SymbolInfoTick(_Symbol, Tick))
Print(TickToString(Tick));
}
结果
我认为它很漂亮。否则,我们也应该放弃模板。
我不同意
{
string flag = "";
#define TICKFLAG_MACRO(A) flag += ((bool)(tickflag & TICK_FLAG_##A)) ? " TICK_FLAG_" + #A : "";
TICKFLAG_MACRO(BID)
TICKFLAG_MACRO(ASK)
TICKFLAG_MACRO(LAST)
TICKFLAG_MACRO(VOLUME)
TICKFLAG_MACRO(BUY)
TICKFLAG_MACRO(SELL)
#undef TICKFLAG_MACRO
if (flag == "")
flag = " FLAG_UNKNOWN (" + (string)tickflag + ")";
return(flag);
}
#define TOSTRING(A) " " + #A + " = " + (string)Tick.A
string TickToString( const MqlTick &Tick )
{
return(TOSTRING(time) + "." + (string)IntegerToString(Tick.time_msc %1000, 3, '0') +
TOSTRING(bid) + TOSTRING(ask) + TOSTRING(last)+ TOSTRING(volume) + GetTickFlag(Tick.flags));
}
void OnStart()
{
MqlTick Tick;
if (SymbolInfoTick(_Symbol, Tick))
Print(TickToString(Tick));
}
结果。
有点可爱。否则,你也不得不放弃模板。
你喜欢它是可以理解的 )))),但在我看来,TickToString 可以用一种纯粹的语言来实现。
问题的关键在于宏来自于 C 语言,它们是为其他目的而设计的。这就好比微型计算器--创建的目的是一样的,但在那个时代,人们开始玩 MK-62(包括我),但后来由于缺乏 PC 而被迫放弃,现在看起来要么是怀旧加变态,要么就是纯粹的变态:)。宏....当然,您可以按照自己的喜好编写代码,我只是说了吸引您眼球的地方。
在我看来,TickToString 可以用纯语言实现
当然可以!但会有多难看?
在没有宏的 TypeToBytes 库中,这不仅可怕,而且不方便。也就是说,这个库可以直接扔掉。
我认为这与语言能力有关。当我不知道/不理解 OOP 时,我不会使用它。一切都变了。
Price_Compare:
简单快捷地比较"价格"的双精度值。
作者: fxsaber