私募

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

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

[复制链接]
发表于 2024-3-31 08:39:53 | 显示全部楼层 |阅读模式
规划
2 i7 k  i" j  h: ~  m8 l' F许多人可能认为规划很容易,特别是,由于它事关转换柱线,即始终把 1-分钟柱线转换为票据(我们稍后会解释)。 然而,模拟比表面看要复杂得多。 主要问题在于我们尚未清晰地理解票据的实际行为,就去创建 1-分钟柱线。 我们只有柱线,和一些它的有关信息,但我们并不知道柱线是如何形成的。 我们将采用 1-分钟柱线,因为它们所需的难度最小。 如果您能创造一个与真实事物非常相似的复杂走位,那么您就能够再现一些非常接近真实事物的东西。+ Y; g7 |" X- s
这个细节似乎并不那么重要,因为我们通常会在市场上看到锯齿形的走位。 无论走位如何复杂,这一切都归结为在 OHCL 点之间创建锯齿形。 它始自柱线的开盘那一刻,且需不少于 9 个走位来创造这个内部的锯齿形。 它总是在柱线收盘时结束,并在下一根柱线上重复该过程。 MetaTrader 5 策略测试器采用相同的逻辑。 更多详细信息,请参阅真实与生成的基差:算法交易。 我们将从这个策略开始。 虽然对于我们的目的来说并不理想,但它将为开拓更多适合的方式提供一个起点。
4 G5 u) u% r. A. G* z  W/ _# S就我而言,测试策略器不太适合回放/模拟系统,因为在策略测试器中,时间问题并不是最重要的。 这就是,没必要以这种方式创建和复现 1-分钟柱线,因为其长度本来就是 1-分钟。 事实上,它甚至更简略,在于它与现实时间并不对应。 如果是这样的话,那么测试策略就变得不可能。 想象一下,依据跨越几天甚至几年的柱运行测试,如果每根柱线复现时间与实际不同。 这将是一项不可能完成的任务。 然而,对于回放/模拟系统,我们正在寻找一种不同的行动。 我们希望按照 1-分钟间隔创建一根 1-分钟柱线,尽可能接近这个目标。6 Z! `$ [% q% v9 U. k! T2 T3 Q
准备奠基
- J% k: R- U; Q$ ~. I我们的重点将完全放在回放/模拟服务代码上。 此时无需担心其它方面。 故此,我们将开始修改 C_Replay 类的代码,尝试尽可能地优化我们已经开发完成并测试过的东西。 下面是类中出现的第一个过程:
, U3 m$ `+ u7 g$ _/ O9 r% vinline bool CheckFileIsBar(int &file, const string szFileName)  b6 G2 C# h) N0 h) S
{  v# z& J6 S! t  H& L% {
string  szInfo = "";
+ U9 k$ Z3 ]% G9 Hbool    bRet;7 }: n; Z- i3 T' L
for (int c0 = 0; (c0 < 9) && (!FileIsEnding(file)); c0++) szInfo += FileReadString(file);- L9 ~$ V8 E- C; d
if ((bRet = (szInfo == def_Header_Bar)) == false)# C4 H/ M' R" t- }* y4 J/ e
{
! `& F1 k$ i! LPrint("File ", szFileName, ".csv is not a file with bars.");
7 ^' k6 H' c7 H; [5 H7 M6 ]: DFileClose(file);( O! t# r2 m9 o/ y
}
( L, l- {$ w; C0 S$ a! Qreturn bRet;
8 }3 F7 z# g) T2 G8 Y; z' r# e9 j}
( _* ?9 P/ @- R% ~3 g  o# O此处的目标是柱线读取函数,这些测试是为了判定指定文件是否为预览柱线文件。 这是必要的,当使用相同代码来判定柱线文件是否符合我们所需时,如此可避免重复代码。 在此状况下,这些柱线将不会用作预览柱线。 它们将被转换为模拟票据,以便在交易系统中使用。 有基于此,我们引入了另一个函数:6 e/ A' p# U7 K' s  K  y/ [
inline void FileReadBars(int &file, MqlRates &rate[])& Q* o. |6 K. c: o8 E: u, i, V
{
$ e$ x) g9 z7 \" V* L( z( B/ C; {rate[0].time = StringToTime(FileReadString(file) + " " + FileReadString(file));7 D: Z+ }7 H1 [& Y
rate[0].open = StringToDouble(FileReadString(file));
2 K0 w: C/ o6 l$ M: ?: r0 Xrate[0].high = StringToDouble(FileReadString(file));
1 J2 Z8 d! h& y" Grate[0].low = StringToDouble(FileReadString(file));
2 ]: X) Q& a4 N2 A5 W9 J0 xrate[0].close = StringToDouble(FileReadString(file));$ f( x* m: B4 [' {  t
rate[0].tick_volume = StringToInteger(FileReadString(file));7 H3 \/ F5 m( `( D5 U3 u- \  R
rate[0].real_volume = StringToInteger(FileReadString(file));/ l! S( _+ m, s4 h5 Y
rate[0].spread = (int) StringToInteger(FileReadString(file));9 T: h8 s+ \5 C( s* @5 O; ?
}, `) H4 i2 k& y
它将从指定文件里逐行读取已有柱线的数据。 我想您在理解这段代码时不会遇到任何困难。 继续这个准备阶段,此处是另一个函数:: W. k$ _! u5 D9 R8 V
inline bool OpenFileBars(int &file, const string szFileName)! ]8 W# M& k6 v
{
; o+ S6 R$ S: Sif ((file = FileOpen("Market Replay\\Bars\\" + szFileName + ".csv", FILE_CSV | FILE_READ | FILE_ANSI)) != INVALID_HANDLE)$ @: o5 v$ _9 g$ T" Y: C7 F/ W
{
9 `# r! L2 m4 L& F+ D& yif (!CheckFileIsBar(file, szFileName))$ H+ J3 J4 o# f* k
return false;) d7 x# {( R& }3 w7 s. y
return true;
& e8 |" v# H0 R" t}
3 \8 d9 E7 R1 t9 l6 \5 E/ BPrint("Falha ao acessar ", szFileName, ".csv de barras.");. @  n  Y# q9 }; y
return false;2 A6 w6 u7 I3 H9 E
}
6 C6 x; N2 j: ^0 ~0 N我们的系统现在已经完全集中化,能提供对柱线的标准访问:我们即可把它们用作预览柱线时,亦可把它们用于模拟,并转换为票据表示。 因此,之前加载预览柱线的函数也必须修改,如下所示:& |3 u& T( M4 f0 y- `
bool LoadPrevBars(const string szFileNameCSV)
& ?7 }* p6 P) L, t$ V{
/ m6 y( X" c1 Z1 tint     file,, X1 \; c( b* w& z. H: o
iAdjust = 0;- Z9 a. R4 l# t0 }
datetime dt = 0;
5 {* w$ R8 _+ h4 G4 v% ~0 cMqlRates Rate[1];% k- t, P, Z9 Q1 r: ?+ ^
if (OpenFileBars(file, szFileNameCSV))
& `5 l, W- T% i  I9 v$ e{5 E7 [$ J" d* w. Q5 ]
Print("Loading preview bars for Replay. Please wait....");
) ~5 }3 }$ C, t8 Y1 Ywhile ((!FileIsEnding(file)) && (!_StopFlag))5 R7 C7 H6 t6 o4 z* n* n
{* K8 M1 V- {7 a% s( G3 c3 d- j' {
FileReadBars(file, Rate);+ ]3 s' A1 H' `
iAdjust = ((dt != 0) && (iAdjust == 0) ? (int)(Rate[0].time - dt) : iAdjust);
0 t& @2 H# h4 K5 tdt = (dt == 0 ? Rate[0].time : dt);
& V0 h$ E2 h" E5 a$ [CustomRatesUpdate(def_SymbolReplay, Rate, 1);- ~) v% v& f9 c
}( k1 M+ r0 O% G5 t
m_dtPrevLoading = Rate[0].time + iAdjust;4 l: w* `# v9 B4 i5 w* B! B, S
FileClose(file);
; b: h9 R5 |" C) c; g: [return (!_StopFlag);
3 A6 k5 B7 w. V- d8 u}# q3 O4 Z% d7 y: d+ U4 {
m_dtPrevLoading = 0;
: M% v. U8 h8 e! E) Freturn false;. T0 C* p& T* Y8 ~6 O
}
! E; I7 a5 v3 {( i0 {4 Z1 C( E这个下载函数的工作方式并无变化,尽管现在有更多的调用。 从以前的函数中提取一部分,并在新位置加以运用,为我们提供了更高的安全性,因为所有代码都已经过测试。 以这种方式,我们只需要担心新函数。 现在地基已经准备就绪,我们需要在配置文件中添加新内容呢。 该函数旨在判定哪些柱线文件可用于模拟票据。 为此,我们需要添加一个新定义:% |* [) }! V3 k- X& S' ]' L
#define def_STR_FilesBar        "[BARS]"0 o6 F" E* g+ w
#define def_STR_FilesTicks      "[TICKS]"% `2 q& b, q; w4 T8 a
#define def_STR_TicksToBars     "[TICKS->BARS]"
# O. e2 l7 A1 E#define def_STR_BarsToTicks     "[BARS->TICKS]"; D* |# K6 M# ?) p
这样我们就可以运行一个简单的测试,这正是我们开始进行模拟所需要的。
http://www.simu001.cn/x287867x1x1.html
最好的私募社区 | 第一私募论坛 | http://www.simu001.cn

精彩推荐

回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-1 00:09 , Processed in 0.728166 second(s), 33 queries .

Powered by www.simu001.cn X3.4

Copyright © 2001-2021, Tencent Cloud.

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