研究PrintFormat()并应用现成的示例·进阶篇
「用 PrintFormat 把浮点打印成不同进制与精度」
在 MT5 脚本调试里,PrintFormat 比 Print 更可控,能用类 C 的格式化串把同一笔数据按多种表示法输出,方便比对点位精度或极值溢出。下面这段演示了 e/E 科学计数与 a/A 十六进制浮点的差异:value1=255 在 e 格式下是 2.550000e+02,而 a 格式直接给出 0x1.fe00000000000p+7 的底层位模式。 另一组调用把 Point()(默认品种下常见为 0.00001)和 DBL_MAX 打出来:%-22f 给到 0.000010,%-#22g 则是 1.79769e+308,能直观看到双精度上限量级。把 EMPTY_VALUE 套上 %-#22.5f 与 %-#22G,输出 0.00001 与 1.79769E+308,说明空值在 double 层本质仍是 DBL_MAX。 开 MT5 新建脚本粘入下方代码,跑完看日志:若你经纪商黄金点差是 0.01,Point() 会变成 0.01,浮点尾数位宽不变但小数位缩短,这类细节只有实盘品种能暴露。外汇与贵金属波动剧烈,点值精度误差可能在剥头皮策略里放大风险,建议先回测再上实盘。
class="type">class="kw">string header=""; class=class="str">"cmt">// Data header class="type">class="kw">double value1=class="num">0; class=class="str">"cmt">// First value class="type">class="kw">double value2=class="num">0; class=class="str">"cmt">// Second value class=class="str">"cmt">//--- The first line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;e&class="macro">#x27; format class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;E&class="macro">#x27; format header="Header1"; value1=class="num">255; value2=class="num">1024; PrintFormat("%-16s(e) %-22e(E) %-class="macro">#22E",header,(class="type">class="kw">double)value1,(class="type">class="kw">double)value2); class=class="str">"cmt">//--- The second line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;a&class="macro">#x27; format class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;A&class="macro">#x27; format header="Header2"; value1=class="num">255; value2=class="num">1024; PrintFormat("%-16s(a) %-class="macro">#22a(A) %-class="macro">#22A",header,(class="type">class="kw">double)value1,(class="type">class="kw">double)value2); class=class="str">"cmt">/* Sample output: Header1(e) class="num">2.550000e+02 (E) class="num">1.024000E+03 Header2(a) 0x1.fe00000000000p+class="num">7 (A) 0X1.0000000000000P+class="num">10 */ } class="type">void OnStart() { class=class="str">"cmt">//--- Declare the variables to be printed class="type">class="kw">string header=""; class=class="str">"cmt">// Data header class="type">class="kw">double value1=class="num">0; class=class="str">"cmt">// First value class="type">class="kw">double value2=class="num">0; class=class="str">"cmt">// Second value class=class="str">"cmt">//--- The first line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;f&class="macro">#x27; format with class="kw">default precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;g&class="macro">#x27; format header="Header1"; value1=Point(); value2=DBL_MAX; PrintFormat("%-16s(f) %-22f(g) %-class="macro">#22g",header,(class="type">class="kw">double)value1,(class="type">class="kw">double)value2); class=class="str">"cmt">//--- The second line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;f&class="macro">#x27; format with class="num">5-character precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;G&class="macro">#x27; format header="Header2"; value1=Point(); value2=EMPTY_VALUE; PrintFormat("%-16s(f) %-#class="num">22.5f(G) %-class="macro">#22G",header,(class="type">class="kw">double)value1,(class="type">class="kw">double)value2); class=class="str">"cmt">/* Sample output: Header1(f) class="num">0.000010 (g) class="num">1.79769e+308 Header2(f) class="num">0.00001 (G) class="num">1.79769E+308 */ } class="type">void OnStart() { class=class="str">"cmt">//--- Declare the variables to be printed class="type">class="kw">string header=""; class=class="str">"cmt">// Data header class="type">class="kw">double value1=class="num">0; class=class="str">"cmt">// First value
◍ PrintFormat 的星号字段与浮点格式实战
在 MT5 的 PrintFormat 里,用 *- 这类星号宽度占位符可以把字段宽度推迟到参数里传,而不是写死在格式串中。上面第一段代码把表头塞进 16 字符左对齐域,两个数据各占 22 字符左对齐域,第二域用 %f 默认精度、第三域用 %g 科学计数。
跑出来的样例里,Point() 在多数外汇品种下输出 0.00001,DBL_MAX 走 %g 显示成 1.79769e+308;把格式换成 %G 后同一数变成 1.79769E+308,仅大小写与指数标记差异。
第二段改用十六进制浮点:%a 把 Point() 打成 0x1.4f8b588e368f1p-17,%A 把 DBL_MAX 打成 0X1.FFFFFFFFFFFFFP+1023。限定 .5a 后尾数截断到 5 位十六进制即 0x1.4f8b6p-17,EMPTY_VALUE 在 %A 下显示为 0X2.0000000P+1023。
别把正态当圣经:这些输出依赖当前品种 Point 精度与双精度极值,换贵金属点位或 ECn 账户可能末位不同,开 MT5 切品种复跑即可验证。
class="type">class="kw">double value2=class="num">0; class=class="str">"cmt">// Second value class=class="str">"cmt">//--- The first line with a header in a *-character field(class="num">16) and data in *-character fields(class="num">22) class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;f&class="macro">#x27; format with class="kw">default precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;g&class="macro">#x27; format header="Header1"; value1=Point(); value2=DBL_MAX; PrintFormat("%-*s(f) %-*f(g) %-#*g",class="num">16,header,class="num">22,(class="type">class="kw">double)value1,class="num">22,(class="type">class="kw">double)value2); class=class="str">"cmt">//--- The second line with a header in a *-character field(class="num">16) and data in *-character fields(class="num">22) class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;f&class="macro">#x27; format with class="num">5-character precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;G&class="macro">#x27; format header="Header2"; value1=Point(); value2=EMPTY_VALUE; PrintFormat("%-*s(f) %-#*.5f(G) %-#*G",class="num">16,header,class="num">22,(class="type">class="kw">double)value1,class="num">22,(class="type">class="kw">double)value2); class=class="str">"cmt">/* Sample output: Header1(f) class="num">0.000010 (g) class="num">1.79769e+308 Header2(f) class="num">0.00001 (G) class="num">1.79769E+308 */ } class="type">void OnStart() { class=class="str">"cmt">//--- Declare the variables to be printed class="type">class="kw">string header=""; class=class="str">"cmt">// Data header class="type">class="kw">double value1=class="num">0; class=class="str">"cmt">// First value class="type">class="kw">double value2=class="num">0; class=class="str">"cmt">// Second value class=class="str">"cmt">//--- The first line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;a&class="macro">#x27; format with class="kw">default precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;A&class="macro">#x27; format with class="kw">default precision header="Header1"; value1=Point(); value2=DBL_MAX; PrintFormat("%-16s(a) %-22a(A) %-class="macro">#22A",header,(class="type">class="kw">double)value1,(class="type">class="kw">double)value2); class=class="str">"cmt">//--- The second line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;a&class="macro">#x27; format with class="num">5-character precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;A&class="macro">#x27; format with class="num">7-character precision header="Header2"; value1=Point(); value2=EMPTY_VALUE; PrintFormat("%-16s(a) %-#class="num">22.5a(A) %-#class="num">22.7A",header,(class="type">class="kw">double)value1,(class="type">class="kw">double)value2); class=class="str">"cmt">/* Sample output: Header1(a) 0x1.4f8b588e368f1p-class="num">17 (A ) 0X1.FFFFFFFFFFFFFP+class="num">1023 Header2(a) 0x1.4f8b6p-class="num">17 (A) 0X2.0000000P+class="num">1023 */ } class="type">void OnStart() { class=class="str">"cmt">//--- Declare the variables to be printed class="type">class="kw">string header=""; class=class="str">"cmt">// Data header class="type">class="kw">double value1=class="num">0; class=class="str">"cmt">// First value class="type">class="kw">double value2=class="num">0; class=class="str">"cmt">// Second value
PrintFormat 多进制与浮点格式混排实测
在 MT5 的 EA 或脚本里,PrintFormat 能像 C 语言 printf 那样用格式符把同一条日志压成对齐的表格。上面这段把 INT_MAX(2147483647)分别用十进制、八进制、十六进制小写和大写打印,终端里会看到 Header1 行第三列输出 02147483647,Header3 行第二列输出 0xffc00000,字段宽度锁死在 16 和 22 字符,左对齐靠 %- 控制。 浮点侧换 DBL_MAX 进场,%e 与 %E 决定科学计数法的大小写,%f 则走定点小数。把 value1、value2 改成 SymbolInfoDouble(Symbol(), SYMBOL_ASK) 就能直接把当前品种卖价按 4 位和 11 位精度打出来,EURUSD 这类小数位多的报价差异一眼可辨。 外汇与贵金属报价跳动快、点差随机,用这种格式做本地日志比对时,记得多跑几根 Bar 看精度截断是否影响你的判断。开 MT5 新建脚本粘入下方代码,改 Symbol 就能验证你经纪商的实际输出。
class="type">class="kw">double value2=class="num">0; class=class="str">"cmt">// Second value class=class="str">"cmt">//--- The first line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;d&class="macro">#x27; format with class="num">4-character precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;i&class="macro">#x27; format with class="num">11-character precision header="Header1"; value1=INT_MAX; value2=INT_MAX; PrintFormat("%-16s(d) %-class="num">22.4d(i) %-#class="num">22.11i",header,(class="type">int)value1,(class="type">int)value2); class=class="str">"cmt">//--- The second line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;u&class="macro">#x27; format with class="num">4-character precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;o&class="macro">#x27; format with class="num">11-character precision header="Header2"; value1=INT_MAX; value2=INT_MAX; PrintFormat("%-16s(u) %-#class="num">22.4u(o) %-#class="num">22.11o",header,(class="type">class="kw">double)value1,(class="type">class="kw">double)value2); class=class="str">"cmt">//--- The third line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;x&class="macro">#x27; format with class="num">4-character precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;X&class="macro">#x27; format with class="num">11-character precision header="Header3"; value1=INT_MAX; value2=INT_MAX; PrintFormat("%-16s(x) %-#class="num">22.4x(X) %-#class="num">22.11X",header,(class="type">class="kw">double)value1,(class="type">class="kw">double)value2); class=class="str">"cmt">/* Sample output: Header1(d) class="num">2147483647 (i) class="num">02147483647 Header2(u) class="num">4290772992 (o) class="num">037760000000 Header3(x) 0xffc00000 (X) 0X000FFC00000 */ } class="type">void OnStart() { class=class="str">"cmt">//--- Declare the variables to be printed class="type">class="kw">string header=""; class=class="str">"cmt">// Data header class="type">class="kw">double value1=class="num">0; class=class="str">"cmt">// First value class="type">class="kw">double value2=class="num">0; class=class="str">"cmt">// Second value class=class="str">"cmt">//--- The first line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;e&class="macro">#x27; format with class="num">4-character precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;E&class="macro">#x27; format with class="num">11-character precision header="Header1"; value1=DBL_MAX; value2=DBL_MAX; PrintFormat("%-16s(e) %-class="num">22.4e(E) %-#class="num">22.11E",header,(class="type">class="kw">double)value1,(class="type">class="kw">double)value2); class=class="str">"cmt">//--- The second line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;f&class="macro">#x27; format with class="num">4-character precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;f&class="macro">#x27; format with class="num">11-character precision header="Header2"; value1=SymbolInfoDouble(Symbol(),SYMBOL_ASK); value2=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
「用 PrintFormat 对齐报价与极值输出」
在 MT5 脚本里做价格行为日志时,PrintFormat 的格式化串比手动拼字符串更省事。下面这段把表头固定占 16 字符、数据域占 22 字符且全部左对齐,第二列用 (g) 格式保留 4 位有效数,第三列用 (G) 格式保留 11 位有效数。 实际跑出来,Header1 行第二列会打出 1.798e+308(即 DBL_MAX),第三列是当时 SYMBOL_ASK 的 1.2731600000;Header2 行反过来,第二列只显示 1.273(精度截断到 4 位),第三列是 1.7976931349E+308。外汇与贵金属报价跳动快,这种对齐方式便于你肉眼比对跨品种点差。 若把第三列格式换成 (s) 并强转 string,就能直接把 SymbolInfoDouble 取到的 ask 当文本落盘,避免浮点格式在日志里被四舍五入。开 MT5 新建脚本粘入下方代码,改 Symbol() 为具体品种如 XAUUSD,即可验证不同格式串的差异。
class="type">void OnStart() { class=class="str">"cmt">//--- Declare the variables to be printed class="type">class="kw">string header=""; class=class="str">"cmt">// Data header class="type">class="kw">double value1=class="num">0; class=class="str">"cmt">// First value class="type">class="kw">double value2=class="num">0; class=class="str">"cmt">// Second value class=class="str">"cmt">//--- The first line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;g&class="macro">#x27; format with class="num">4-character precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;G&class="macro">#x27; format with class="num">11-character precision header="Header1"; value1=DBL_MAX; value2=SymbolInfoDouble(Symbol(),SYMBOL_ASK); PrintFormat("%-16s(g) %-class="num">22.4g(G) %-#class="num">22.11G",header,(class="type">class="kw">double)value1,(class="type">class="kw">double)value2); class=class="str">"cmt">//--- The second line with a header in a class="num">16-character field and data in class="num">22-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;g&class="macro">#x27; format with class="num">4-character precision class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;G&class="macro">#x27; format with class="num">11-character precision header="Header2"; value1=SymbolInfoDouble(Symbol(),SYMBOL_ASK); value2=DBL_MAX; PrintFormat("%-16s(g) %-#class="num">22.4g(G) %-#class="num">22.11G",header,(class="type">class="kw">double)value1,(class="type">class="kw">double)value2); }
◍ PrintFormat 里 c/C 与 d/i 的格式差异
在 MT5 脚本排错时,PrintFormat 的格式符直接决定终端里你能看到什么。用 %c 打印 char 类型 65 得到字母 A,用 %C 打印 66 得到 B;换成 %d 或 %i 打印同样数值,终端只显示整数 65、66。 left-align 的 %-10c 和 %-10C 都占 10 字符宽,但大小写格式符对 char 的解释输出一致,仅语义上区分单字节与宽字符。 下面这段可直接贴进 EA 的 OnStart 验证:声明 header 为空串、value1/value2 为 char 初值 0,随后分三行打印。第一行 Header1 配 (c) A (C) B,第二行 Header2 配 (c) C (C) D,第三行 Header3 用 (d) 65 (i) 66。跑完在专家日志里对照样例输出,能确认格式串没写错。 外汇与贵金属行情里 SymbolInfoDouble(Symbol(),SYMBOL_ASK) 取到的卖价,若用 %-#22.4s 截断成 4 字符精度,1.2872 会显示成 1.28。这种截断在快速扫日志时有用,但高频策略里可能漏看小数点后细微跳动,属高风险品种下的信息损失,建议只在人工巡检时用。
class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;s&class="macro">#x27; format with class="num">4-character precision header="Header2"; value1=DBL_MAX; value2=SymbolInfoDouble(Symbol(),SYMBOL_ASK); PrintFormat("%-16s(g) %-#class="num">22.5g(s) %-#class="num">22.4s",header,(class="type">class="kw">double)value1,(class="type">class="kw">string)value2); class=class="str">"cmt">/* Sample output: Header1(g) class="num">1.798e+308 (s) class="num">1.2872 Header2(g) class="num">1.7977e+308 (s) class="num">1.28 */ } class="type">void OnStart() { class=class="str">"cmt">//--- Declare the variables to be printed class="type">class="kw">string header=""; class=class="str">"cmt">// Data header class="type">char value1=class="num">0; class=class="str">"cmt">// First value class="type">char value2=class="num">0; class=class="str">"cmt">// Second value class=class="str">"cmt">//--- The first line with a header in a class="num">16-character field and data in class="num">10-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;c&class="macro">#x27; format class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;C&class="macro">#x27; format header="Header1"; value1=class="num">65; value2=class="num">66; PrintFormat("%-16s(c) %-10c(C) %-10C",header,(class="type">char)value1,(class="type">char)value2); class=class="str">"cmt">//--- The second line with a header in a class="num">16-character field and data in class="num">10-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;c&class="macro">#x27; format class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;C&class="macro">#x27; format header="Header2"; value1=class="num">67; value2=class="num">68; PrintFormat("%-16s(c) %-10c(C) %-10C",header,(class="type">char)value1,(class="type">char)value2); class=class="str">"cmt">//--- The third line with a header in a class="num">16-character field and data in class="num">10-character fields class=class="str">"cmt">//--- The header and data of all fields are pressed to the left edge. class=class="str">"cmt">//--- Data values of the second field are displayed together with the &class="macro">#x27;d&class="macro">#x27; format class=class="str">"cmt">//--- Data values of the third field are displayed together with the &class="macro">#x27;i&class="macro">#x27; format header="Header3"; value1=class="num">65; value2=class="num">66; PrintFormat("%-16s(d) %-10d(i) %-10i",header,(class="type">int)value1,(class="type">int)value2); class=class="str">"cmt">/* Sample output: Header1(c) A(C) B Header2(c) C(C) D Header3(d) class="num">65 (i) class="num">66 */ }
把账户属性整齐打进日志的写法
MT5 里读账户信息分三族函数:AccountInfoInteger 取整数、AccountInfoDouble 取实数、AccountInfoString 取字符串。与其每次把全部属性罗列出来,不如给每类属性单独封一个打印函数,用的时候按需要拼装,日志可读性高得多。 封装时建议传两个参数:标题字段宽度 header_width 和从左边缘的缩进 indent。若 header_width 传 0,函数内部自动取标题文本长度 +1,等于不做对齐强制;indent 传 0 则无缩进。这样单属性调试能直接调,批量输出时再统一给宽度和缩进。 格式串里 %*s 是关键:星号位置由参数填缩进值,对应传一个空字符串,就能用空格垫出任意空字段;标题宽度也用 %-*s 接 w 变量控制。下面这段摘了登录号和账户类型的打印函数,能看到整数直接转型输出,枚举型先 EnumToString 再截掉前缀、首字母大写。 [CODE] //+------------------------------------------------------------------+
| // | Print a description of the account number into the journal |
|---|
//+------------------------------------------------------------------+ void AccountLoginPrint(const uint header_width=0,const uint indent=0) { //--- Define the header text and the width of the header field //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1 string header="Login:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Print the property value in the log with a header with the required width and indentation PrintFormat("%*s%-*s%-s",indent,"",w,header,(string)AccountInfoInteger(ACCOUNT_LOGIN)); /* Sample output: Login: 68008618 */ } //+------------------------------------------------------------------+
| // | Print a trading account type into the journal |
|---|
//+------------------------------------------------------------------+ void AccountTradeModePrint(const uint header_width=0,const uint indent=0) { //--- Get the value of the trading account type ENUM_ACCOUNT_TRADE_MODE trade_mode=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE); //--- "Cut out" the name of the trading account type from the line obtained from enum string mode=StringSubstr(EnumToString(trade_mode),19); //--- Convert the characters of the resulting line to lower case and replace the first letter from small to capital if(mode.Lower()) mode.SetChar(0,ushort(mode.GetChar(0)-0x20)); //--- Define the header text and the width of the header field //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1 string header="Trade mode:"; uint w=(header_width==0 ? header.Length()+1 : header_width); //--- Print the property value in the log with a header with the required width and indentation PrintFormat("%*s%-*s%-s",indent,"",w,header,mode); /* Sample output: Trade mode: Demo */ } //+------------------------------------------------------------------+
| // | Print a description of the provided leverage size in the journal |
|---|
//+------------------------------------------------------------------+ 逐行拆解:AccountLoginPrint 中 header 写死 "Login:",w 在零宽时取字符串长+1;PrintFormat 的 "%*s%-*s%-s" 依次吃 indent、空串、w、header、登录号转字符串,样例输出 Login: 68008618。AccountTradeModePrint 先读 ACCOUNT_TRADE_MODE 整数转枚举,EnumToString 后从索引 19 截掉 "ACCOUNT_TRADE_MODE_" 前缀,Lower 再手动把首字母加 0x20 变大写,最后同样用 PrintFormat 输出,样例得 Trade mode: Demo。 真要一次看全貌,写个总函数按 ENUM_ACCOUNT_INFO_INTEGER、ENUM_ACCOUNT_INFO_DOUBLE、ENUM_ACCOUNT_INFO_STRING 顺序调一遍子函数即可。脚本里用标题宽 20、缩进 2 调用,日志里每行前面空两格、标题占 20 宽,扫一眼就能核对杠杆、净值、信用等字段。外汇和贵金属账户这类属性随券商策略变动,高杠杆意味着回撤可能被放大,核对完记得结合风控参数看。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Print a description of the account number into the journal | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void AccountLoginPrint(const class="type">uint header_width=class="num">0,const class="type">uint indent=class="num">0) { class=class="str">"cmt">//--- Define the header text and the width of the header field class=class="str">"cmt">//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + class="num">1 class="type">class="kw">string header="Login:"; class="type">uint w=(header_width==class="num">0 ? header.Length()+class="num">1 : header_width); class=class="str">"cmt">//--- Print the class="kw">property value in the log with a header with the required width and indentation PrintFormat("%*s%-*s%-s",indent,"",w,header,(class="type">class="kw">string)AccountInfoInteger(ACCOUNT_LOGIN)); class=class="str">"cmt">/* Sample output: Login: class="num">68008618 */ } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Print a trading account type into the journal | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void AccountTradeModePrint(const class="type">uint header_width=class="num">0,const class="type">uint indent=class="num">0) { class=class="str">"cmt">//--- Get the value of the trading account type ENUM_ACCOUNT_TRADE_MODE trade_mode=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE); class=class="str">"cmt">//--- "Cut out" the name of the trading account type from the line obtained from enum class="type">class="kw">string mode=StringSubstr(EnumToString(trade_mode),class="num">19); class=class="str">"cmt">//--- Convert the characters of the resulting line to lower case and replace the first letter from small to capital if(mode.Lower()) mode.SetChar(class="num">0,class="type">class="kw">ushort(mode.GetChar(class="num">0)-0x20)); class=class="str">"cmt">//--- Define the header text and the width of the header field class=class="str">"cmt">//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + class="num">1 class="type">class="kw">string header="Trade mode:"; class="type">uint w=(header_width==class="num">0 ? header.Length()+class="num">1 : header_width); class=class="str">"cmt">//--- Print the class="kw">property value in the log with a header with the required width and indentation PrintFormat("%*s%-*s%-s",indent,"",w,header,mode); class=class="str">"cmt">/* Sample output: Trade mode: Demo */ } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Print a description of the provided leverage size in the journal | class=class="str">"cmt">//+------------------------------------------------------------------+