私募网

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz

期货量化软件:赫兹量化中模拟器的诞生

[复制链接]
发表于 2024-3-31 08:39:53 | 显示全部楼层 |阅读模式
规划! Z1 }( [. i+ G( W" p5 ^
许多人可能认为规划很容易,特别是,由于它事关转换柱线,即始终把 1-分钟柱线转换为票据(我们稍后会解释)。 然而,模拟比表面看要复杂得多。 主要问题在于我们尚未清晰地理解票据的实际行为,就去创建 1-分钟柱线。 我们只有柱线,和一些它的有关信息,但我们并不知道柱线是如何形成的。 我们将采用 1-分钟柱线,因为它们所需的难度最小。 如果您能创造一个与真实事物非常相似的复杂走位,那么您就能够再现一些非常接近真实事物的东西。! N' Z" k) Y: J) h$ f
这个细节似乎并不那么重要,因为我们通常会在市场上看到锯齿形的走位。 无论走位如何复杂,这一切都归结为在 OHCL 点之间创建锯齿形。 它始自柱线的开盘那一刻,且需不少于 9 个走位来创造这个内部的锯齿形。 它总是在柱线收盘时结束,并在下一根柱线上重复该过程。 MetaTrader 5 策略测试器采用相同的逻辑。 更多详细信息,请参阅真实与生成的基差:算法交易。 我们将从这个策略开始。 虽然对于我们的目的来说并不理想,但它将为开拓更多适合的方式提供一个起点。/ a8 K& g, i, h4 P$ |
就我而言,测试策略器不太适合回放/模拟系统,因为在策略测试器中,时间问题并不是最重要的。 这就是,没必要以这种方式创建和复现 1-分钟柱线,因为其长度本来就是 1-分钟。 事实上,它甚至更简略,在于它与现实时间并不对应。 如果是这样的话,那么测试策略就变得不可能。 想象一下,依据跨越几天甚至几年的柱运行测试,如果每根柱线复现时间与实际不同。 这将是一项不可能完成的任务。 然而,对于回放/模拟系统,我们正在寻找一种不同的行动。 我们希望按照 1-分钟间隔创建一根 1-分钟柱线,尽可能接近这个目标。
; W5 R" U+ f9 F5 d准备奠基5 d: _! c' h8 a( B
我们的重点将完全放在回放/模拟服务代码上。 此时无需担心其它方面。 故此,我们将开始修改 C_Replay 类的代码,尝试尽可能地优化我们已经开发完成并测试过的东西。 下面是类中出现的第一个过程:8 T7 Q8 {8 H9 g- `$ q  e
inline bool CheckFileIsBar(int &file, const string szFileName)
  c( w% u5 B' M+ A( C5 P{
# v0 m7 n% Q- Nstring  szInfo = "";
& l8 L' p4 v' ?# v, F; u+ y( Tbool    bRet;( M# ^$ G8 V8 m% e9 U
for (int c0 = 0; (c0 < 9) && (!FileIsEnding(file)); c0++) szInfo += FileReadString(file);! B; ?  w/ ]8 `% E+ s4 L" @9 H+ x
if ((bRet = (szInfo == def_Header_Bar)) == false)
) e5 @! \- V. S" Y+ P$ F8 k{4 }" P+ G' r* ~! m( z6 }; E
Print("File ", szFileName, ".csv is not a file with bars.");3 [9 t/ f' g- Q  |6 K
FileClose(file);
6 B, W3 P' X, {5 r- b6 x}
1 k1 ^  o) `( B* D2 P& xreturn bRet;. A* Z" E. L* C: K* T- ]% V
}4 y  J" x* v# D' x8 s
此处的目标是柱线读取函数,这些测试是为了判定指定文件是否为预览柱线文件。 这是必要的,当使用相同代码来判定柱线文件是否符合我们所需时,如此可避免重复代码。 在此状况下,这些柱线将不会用作预览柱线。 它们将被转换为模拟票据,以便在交易系统中使用。 有基于此,我们引入了另一个函数:. a+ t- F! m+ W) o
inline void FileReadBars(int &file, MqlRates &rate[])
  B# Z: b+ i2 W, X/ m1 q{; D# }6 z' g) X
rate[0].time = StringToTime(FileReadString(file) + " " + FileReadString(file));
& l* z) f! Z. U4 e1 U4 d9 f$ Orate[0].open = StringToDouble(FileReadString(file));
( Z6 |! Y2 k& c6 w# W, y: wrate[0].high = StringToDouble(FileReadString(file));# M: @" `& w. K) x3 t
rate[0].low = StringToDouble(FileReadString(file));
5 ^3 ~- e; D& hrate[0].close = StringToDouble(FileReadString(file));
5 M& s! y5 {! _9 g/ brate[0].tick_volume = StringToInteger(FileReadString(file));
4 ^# |! [) ^% [rate[0].real_volume = StringToInteger(FileReadString(file));5 ~, n$ [8 X3 Z- o- @
rate[0].spread = (int) StringToInteger(FileReadString(file));
' H& P4 V' q# U" H* G- _}3 _+ z0 T0 o- O+ r$ J
它将从指定文件里逐行读取已有柱线的数据。 我想您在理解这段代码时不会遇到任何困难。 继续这个准备阶段,此处是另一个函数:# z8 Z/ w0 h9 e" k) m
inline bool OpenFileBars(int &file, const string szFileName)  Q; K0 }/ w  B
{2 [; L( m; l- {8 O6 Q! B0 F  V
if ((file = FileOpen("Market Replay\\Bars\\" + szFileName + ".csv", FILE_CSV | FILE_READ | FILE_ANSI)) != INVALID_HANDLE)
3 x7 \* V* Y% r, R) |{6 K3 C, H% h4 A3 f6 @' H
if (!CheckFileIsBar(file, szFileName))
3 q) r1 t$ }2 C( treturn false;
( e: d1 ~& g6 _return true;; [% m: u7 V; E" W" o
}
0 s: e" k4 w9 k8 [5 X0 n7 BPrint("Falha ao acessar ", szFileName, ".csv de barras.");: E& F) j0 A% x( N4 {
return false;1 z% d* J) f* }
}& m& K1 t5 ^( g' k( D4 X4 J2 t
我们的系统现在已经完全集中化,能提供对柱线的标准访问:我们即可把它们用作预览柱线时,亦可把它们用于模拟,并转换为票据表示。 因此,之前加载预览柱线的函数也必须修改,如下所示:" s/ [6 C" i! s3 U8 ]5 c% k! X; g
bool LoadPrevBars(const string szFileNameCSV)6 r! p. n% m/ p9 j( f6 S
{: w8 l6 G* m! f2 L; f" s0 O
int     file,$ B% v: ]: p: v" u/ ]
iAdjust = 0;
  e4 @! Q9 l' tdatetime dt = 0;
% l+ v+ o& e  q' CMqlRates Rate[1];1 k# B; Y2 |% a+ R2 K
if (OpenFileBars(file, szFileNameCSV))
" k! t- X* e- S0 e0 [{
8 F- I- [) u0 F" X) \% FPrint("Loading preview bars for Replay. Please wait....");8 U; \1 D0 ^( w- X$ G4 P
while ((!FileIsEnding(file)) && (!_StopFlag))
# p) k2 R- y) r' A. }* T, M{7 h: M# R. C; P' X
FileReadBars(file, Rate);2 C2 v& m5 W6 M2 M) O8 a5 a
iAdjust = ((dt != 0) && (iAdjust == 0) ? (int)(Rate[0].time - dt) : iAdjust);6 o% Q( V4 K& q8 Y' v
dt = (dt == 0 ? Rate[0].time : dt);
( Q7 T( g. `* VCustomRatesUpdate(def_SymbolReplay, Rate, 1);
- Y- }% }3 Z. o% `1 t7 w}  N7 T" [1 w; s# p3 L
m_dtPrevLoading = Rate[0].time + iAdjust;
/ k0 |& L$ X& S- DFileClose(file);
; D8 S+ f" u- ?2 U4 y; qreturn (!_StopFlag);) q8 @1 F( f* B7 \9 a8 }1 }
}
2 l: v( i! r5 K( K  Am_dtPrevLoading = 0;
5 V2 H) S4 |1 [4 |return false;
3 ^' |" t& V( x' h0 s5 e' w}* N& [4 x) z$ e0 N$ ^/ P/ {
这个下载函数的工作方式并无变化,尽管现在有更多的调用。 从以前的函数中提取一部分,并在新位置加以运用,为我们提供了更高的安全性,因为所有代码都已经过测试。 以这种方式,我们只需要担心新函数。 现在地基已经准备就绪,我们需要在配置文件中添加新内容呢。 该函数旨在判定哪些柱线文件可用于模拟票据。 为此,我们需要添加一个新定义:
# B6 ]: F1 G* _9 u2 @#define def_STR_FilesBar        "[BARS]"
% G3 e8 n. y  i$ ?1 E# P4 E/ D; o#define def_STR_FilesTicks      "[TICKS]"
2 i. @' V/ u: x#define def_STR_TicksToBars     "[TICKS->BARS]"
' j7 y3 R9 l' Y& I#define def_STR_BarsToTicks     "[BARS->TICKS]"
  i4 ]" g1 O( p7 t+ \$ U( O/ d这样我们就可以运行一个简单的测试,这正是我们开始进行模拟所需要的。
http://www.simu001.cn/x287867x1x1.html
最好的私募社区 | 第一私募论坛 | http://www.simu001.cn

精彩推荐

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Archiver| ( 桂ICP备12001440号-3 )|网站地图

GMT+8, 2026-5-19 01:57 , Processed in 1.443483 second(s), 31 queries .

Powered by www.simu001.cn X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表