灵客论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 283|回复: 11

[资源分享] 三角套利的EA模型(整套)3/1

[复制链接]

该用户从未签到

333

主题

1978

帖子

1万

积分

论坛元老

Rank: 8Rank: 8

灵客宝
18
金钱
5625
在线时间
200 小时
注册时间
2018-6-28
发表于 2018-9-18 10:43:19 | 显示全部楼层 |阅读模式
开发可靠规律的三角套利话题经常出现在论坛上。那么它究竟是什么呢? "套利" 意味着有些偏向行情的中立性。"三角" 是指投资组合由三个金融工具组成。

我们举一个最流行的例子: "欧元 — 英镑 — 美元" 三角。就货币对而言, 可以描述如下: EURUSD + GBPUSD + EURGBP。所需的中立性包括尝试同时买入和卖出相同的金融工具, 从而赚取利润。

这看起来如下。这个例子中的任何一个货币对都可通过另外两个货币对来表示:

EURUSD=GBPUSD*EURGBP,

或 GBPUSD=EURUSD/EURGBP,

或 EURGBP=EURUSD/GBPUSD。

所有这些变体是相同的, 下面会更详细地讨论它们中的所有选择。同时, 我们来研究第一个选项。

首先, 我们需要看出竞买价和竞卖价。流程如下:

买入 EURUSD, 即使用 竞卖 价。这意味着, 我们在余额中增加 EUR 占比, 并消减 USD。

我们来通过其它两个货币对评估 EURUSD。

GBPUSD: 这里面没有 EUR。代之, 我们需要抛售这里面的 USD。为了抛售 GBPUSD 当中的 USD, 我们需要买入这个货币对。意即, 我们使用 竞卖价。当买入时, 我们在余额中增加 GBP 占比, 同时消减 USD。

EURGBP: 我们需要买入 EUR, 抛售我们不需要的 GBP。买入 EURGBP, 使用 竞卖价。我们在余额中增加 EUR 占比, 并消减 GBP。

总计我们拥有: (竞买价) EURUSD = (竞买价) GBPUSD * (竞买价) EURGBP。我们已获得了必要的等价。为了令其盈利, 我们应该一边买入一边卖出。这里有两种可能的选项:

比我们抛售 EURUSD 更便宜地买入, 但以不同的方式展现: (竞卖价) EURUSD < (竞买价) GBPUSD * (竞买价) EURGBP

比我们买入 EURUSD 的更高价格抛售, 但以不同的方式展现: (竞买价) EURUSD > (竞卖价) GBPUSD * (竞卖价) EURGBP

现在, 我们所要做的就是检测这种情况, 并从中获利。

注意, 三角可以用另一种方式来移动, 这三个货币对在一个方向上移动, 并与 1 比较。所有变体都相同, 但我相信, 上面描述的变体更容易理解和解释。

通过形势跟踪, 我们可以寻找一个同时买入和卖出的时刻。在这种情况下, 会即时盈利, 但这样的时刻是罕见的。

更常见的情况是, 当我们能够更便宜地买入一方时, 却无法在抛售另一方时盈利。那么我们只得等待这种不平衡消失。交易对我们来说是安全的, 因为我们的持仓相互抵消近乎为零, 意即我们游离于市场之外。虽然, 此处请注意 "近乎" 这个词。为了交易量的完美程度, 我们所需的精确度并未得到。交易量往往四舍五入到小数点后两位, 对于我们的策略来说这太粗糙了。

现在我们已经研究了这个理论, 现在是编写 EA 的时候了。EA 是以面向过程的风格开发的, 所以新入行的程序员, 以及那些因为某种原因不喜欢 OOP 的人都可以理解。

简要的 EA 描述

首先, 我们创建所有可能的三角, 将它们正确放置, 并获得每个货币对的所有必要数据。

所有这些信息都存储在 MxThree 结构数组中。每个三角都有 status (状态) 字段。它的初始值是 0。如果需要三角开单, 状态设置为 1。确认三角完全开单后, 状态变为 2。如果三角形部分开单, 或者平单时间已到, 则状态变为 3。一旦三角成功平单, 状态将返回到 0。

三角开单和平单均被保存到一个日志文件, 令我们能够检查动作的正确性并重温历史。日志文件名称为 Three Point Arbitrage Control YYYY.DD.MM.csv。

为了执行测试, 请将所有必要的货币对载入到测试器。为此, 在运行测试器之前, 在 "创建品种文件" 模式中启动 EA。如果不存在这样的文件, EA 将在默认的 EUR + GBP + USD 三角上运行测试。

使用的变量

在我的开发过程中, 任何机器人的代码都是从包含头文件开始的。它会列出所有包含内容, 函数库, 等等。这个机器人也不例外: 说明模块之后紧随 #include "head.mqh" 等等:

此列表目前对您来说也许无法完全理解, 但本文会遵循这些代码, 因此程序结构在此并未被违反。往下一切都将变得清晰。所有函数, 类和代码单元都放在单独的文件中, 以方便使用。就我而言, 除了标准库之外, 每个包含文件也以 #include "head.mqh" 开头。允许在包含文件中使用 IntelliSense (智能感知), 因此不必在内存中保存所有必要实体的名称。

之后, 为测试器连接文件。我们不能在任意地方进行这一步, 所以我们要在此声明。这个字符串是多币种测试器加载品种所需的:

#property tester_file FILENAME

接下来, 我们描述程序中使用的变量。描述可以在单独的 var.mqh 文件中找到:

———————————————————————————————————————

源代码如下:

// 宏定义

#define DEVIATION       3                                                                 // 最大可能的滑点

#define FILENAME        "Three Point Arbitrage.csv"                                       // 操作品种存储在这里

#define FILELOG         "Three Point Arbitrage Control "                                  // 日志文件名称部分

#define FILEOPENWRITE(nm)  FileOpen(nm,FILE_UNICODE|FILE_WRITE|FILE_SHARE_READ|FILE_CSV)  // 打开文件写入

#define FILEOPENREAD(nm)   FileOpen(nm,FILE_UNICODE|FILE_READ|FILE_SHARE_READ|FILE_CSV)   // 打开文件读取

#define CF              1.2                                                               // 提高保证金比例

#define MAGIC           200                                                               // 应用的魔幻数字范围

#define MAXTIMEWAIT     3                                                                 // 三角开单后的最长等待时间, 以秒为单位

// 货币对结构

struct stSmb

{

string            name;            // 货币对

int               digits;          // 报价中的小数位数

uchar             digits_lot;      // 手数的四舍五入小数位数

int               Rpoint;          // 1/point, 以便在方程中乘以 (而不是除以)  该值

double            dev;             // 可能的滑点。一次性转换成点数

double            lot;             // 货币对的交易量

double            lot_min;         // 最小交易量

double            lot_max;         // 最大交易量

double            lot_step;        // 手数增量

double            contract;        // 合约大小

double            price;           // 在三角中的货币对开单价。净持模式需要

ulong             tkt;             // 交易开单所用的订单票号。对冲账户所需

MqlTick           tick;            // 当前货币对价格

double            tv;              // 当前分笔报价

double            mrg;             // 当前用于开单的保证金

double            sppoint;         // 点差, 单位为点数的整数值

double            spcost;          // 当前开单的每手点差, 以资金为单位

stSmb(){price=0;tkt=0;mrg=0;}

};

// 三角结构

struct stThree

{

stSmb             smb1;

stSmb             smb2;

stSmb             smb3;

double            lot_min;          // 整个三角的最小交易量

double            lot_max;          // 整个三角的最大交易量

ulong             magic;            // 三角的魔幻数字

uchar             status;           // 三角状态。0 - 未使用。1 - 发送开单。2 - 成功开单。3 - 发送平单

double            pl;               // 三角盈利

datetime          timeopen;         // 发送三角开单的时间

double            PLBuy;            // 买入三角时的潜在利润

double            PLSell;           // 抛售三角时的潜在利润

double            spread;           // 所有三个点差的总价 (含佣金!)

stThree(){status=0;magic=0;}

};

// EA 操作模式

enum enMode

{

STANDART_MODE  =  0, /*Symbols from Market Watch*/                  // 标准操作模式。市场观察品种

USE_FILE       =  1, /*Symbols from file*/                          // 使用品种文件

CREATE_FILE    =  2, /*Create file with symbols*/                   // 为测试器或操作创建文件

//END_ADN_CLOSE  =  3, /*Not open, wait profit, close & exit*/      // 您的所有交易平单并结束操作

//CLOSE_ONLY     =  4  /*Not open, not wait profit, close & exit*/

};

stThree  MxThree[];           // 主数组存储正在操作的三角和所有必要的附加数据

CTrade         ctrade;        // 标准库的 CTrade 类

CSymbolInfo    csmb;          // 标准库的 CSymbolInfo 类

CTerminalInfo  cterm;         // 标准库的 CTerminalInfo 类

int         glAccountsType=0; // 账户类型: 对冲或净持

int         glFileLog=0;      // 日志文件句柄

// 输入

sinput      enMode      inMode=     0;          // 操作模式

input       double      inProfit=   0;          // 佣金

input       double      inLot=      1;          // 交易量

input       ushortinMaxThree= 0;          // 三角已开单

sinput      ulong       inMagic=    300;        // EA 魔幻数字

sinput      string      inCmnt=     "R ";       // 注释

——————————————————————————————————————————————

由于它们很简单并附有注释, 故先行定义。我相信, 它们很容易理解。

它们跟着两个结构 — stSmb 和 stThree。逻辑如下: 任何三角由三个货币对组成。因此, 一旦描述其一并使用三次之后, 我们得到一个三角。stSmb — 描述货币对的结构及其规格: 可能的交易量, _Digits 和 _Point 变量, 开单时的当前价格和一些其它值。在 stThree 结构当中, stSmb 使用了三次。这就是我们的三角的形成过程。此外, 还会添加一些与三角相关的属性 (当前利润, 魔幻数字, 开单时间等)。然后, 是我们将在稍后介绍的操作模式和输入变量。输入也在注释中说明了。我们要仔细看看其中两个:

inMaxThree 参数中存储了可同时开单的最大三角可能数量。0 — 未用。例如, 如果参数设置为 2, 则不能有两个以上的三角同时开单。

inProfit 参数包含佣金值, 如果有的话。

初始设置

在我们描述过包含文件和使用变量之后, 我们进入 OnInint() 模块。

在启动 EA 之前, 请务必检查输入参数的正确性, 并在必要时接收初始数据。如果一切顺利的话, 我们就开始吧。我通常在 EA 中设置尽可能少的输入量, 这个机器人也不例外。

六个输入中只有一个也许阻止 EA 操作, 这就是交易量。我们不能以负数交易量开单交易。所有其它设置不影响操作。这些检查在 OnInit() 模块函数中最先执行。

我们来看看它的代码。

由于机器人是以面向过程风格编写的, 所以我们必须创建几个全局变量。其中之一是日志文件句柄。该名称由一个固定部分和机器人开始日期组成 - 这是为了便于控制, 因此您不必在同一个文件中搜索特定日志的起始位置。请注意, 名称在每次重新启动时都会变更, 并删除前一个同名文件 (如果有的话)。

EA 在其操作中使用两个文件: 含有检测到三角的文件 (由用户自行决定), 和记录三角开单和平单时间的日志文件, 开单价格和一些方便控制的附加数据。日志记录始终处于活动状态。

形成三角

为了形成三角, 我们需要考虑以下几个方面:

数据来自市场观察窗口或预先准备的文件。

我们是否在测试器中?如果是的话, 则将品种上传到市场观察。上传所有可能的品种是没有意义的, 因为普通的家用电脑无法承受负载。搜索预先准备的包含测试器品种的文件。否则, 在标准三角: EUR + USD + GBP 上测试策略。

为了简化代码, 引入一个限制: 所有的三角品种应有相同的合约大小。

不要忘记, 三角只能以货币对构成。

第一个必要的函数是利用来自市场观察的品种形成三角。

—————————————————————————————————————

源代码如下:

void fnGetThreeFromMarketWatch(stThree &MxSmb[])

{

// 获取品种总数

int total=SymbolsTotal(true);

// 用来比较合约大小的变量

double cs1=0,cs2=0;

// 使用第一次循环列表中的第一个品种

for(int i=0;i<total-2 && !IsStopped();i++)

{//1

string sm1=SymbolName(i,true);

// 检查品种的各种限制

if(!fnSmbCheck(sm1)) continue;

// 获取合约大小, 并将之常规化, 因为我们稍后会比较这个值

if (!SymbolInfoDouble(sm1,SYMBOL_TRADE_CONTRACT_SIZE,cs1)) continue;

cs1=NormalizeDouble(cs1,0);

// 获取基准货币和盈利货币, 因为它们要用来比较 (而非货币对名称)

string sm1base=SymbolInfoString(sm1,SYMBOL_CURRENCY_BASE);

string sm1prft=SymbolInfoString(sm1,SYMBOL_CURRENCY_PROFIT);

// 从第二次循环列表中取下一个品种

for(int j=i+1;j<total-1 && !IsStopped();j++)

{//2

string sm2=SymbolName(j,true);

if(!fnSmbCheck(sm2)) continue;

if (!SymbolInfoDouble(sm2,SYMBOL_TRADE_CONTRACT_SIZE,cs2)) continue;

cs2=NormalizeDouble(cs2,0);

string sm2base=SymbolInfoString(sm2,SYMBOL_CURRENCY_BASE);

string sm2prft=SymbolInfoString(sm2,SYMBOL_CURRENCY_PROFIT);

// 在第一个和第二个货币对中应该有一种货币相匹配。

// 否则, 它们不能形成一个三角。

// 进行全面的匹配测试没有意义。例如, 这是不可能的

// 形成 eurusd 和 eurusd.xxx 的三角.

if(sm1base==sm2base || sm1base==sm2prft || sm1prft==sm2base || sm1prft==sm2prft); else continue;

// 合约应有相似的大小

if (cs1!=cs2) continue;

// 搜索第三次循环中的最后一个三角品种

for(int k=j+1;k<total && !IsStopped();k++)

{//3

string sm3=SymbolName(k,true);

if(!fnSmbCheck(sm3)) continue;

if (!SymbolInfoDouble(sm3,SYMBOL_TRADE_CONTRACT_SIZE,cs1)) continue;

cs1=NormalizeDouble(cs1,0);

string sm3base=SymbolInfoString(sm3,SYMBOL_CURRENCY_BASE);

string sm3prft=SymbolInfoString(sm3,SYMBOL_CURRENCY_PROFIT);

// 我们知道第一个和第二个品种有一个共同的货币。若要形成一个三角, 我们应该找到

// 第三个货币对内应有一种货币与第一个品种中的货币相匹配, 且其第二个货币匹配

// 第二个品种中的货币如果没有匹配, 这个货币对不能用来形成一个三角。

if(sm3base==sm1base || sm3base==sm1prft || sm3base==sm2base || sm3base==sm2prft);else continue;

if(sm3prft==sm1base || sm3prft==sm1prft || sm3prft==sm2base || sm3prft==sm2prft);else continue;

if (cs1!=cs2) continue;

// 到达这个阶段, 意味着所有的检查都已经通过了, 且三个已检测货币对适于形成一个三角

// 将其写入数组

int cnt=ArraySize(MxSmb);

ArrayResize(MxSmb,cnt+1);

MxSmb[cnt].smb1.name=sm1;

MxSmb[cnt].smb2.name=sm2;

MxSmb[cnt].smb3.name=sm3;

break;

}//3

}//2

}//1

}

——————————————————————————————————

第二个必要的函数是从文件中读取三角

———————————————————————————————————————

源代码如下:

void fnGetThreeFromFile(stThree &MxSmb[])

{

// 如果没有找到含有品种的文件, 显示相应的消息并停止工作

int fh=FileOpen(FILENAME,FILE_UNICODE|FILE_READ|FILE_SHARE_READ|FILE_CSV);

if(fh==INVALID_HANDLE)

{

Print("未能读到品种文件!");

ExpertRemove();

}

// 将指针移动到文件的开头

FileSeek(fh,0,SEEK_SET);

// 跳过标题行 (文件的第一行)

while(!FileIsLineEnding(fh)) FileReadString(fh);

while(!FileIsEnding(fh) && !IsStopped())

{

// 得到三角的三个品种。我们来进行数据可用性的基本检查

// 机器人能够自动形成三角文件。如果一位用户

// 未能正确修改它, 我们假定这是故意的

string smb1=FileReadString(fh);

string smb2=FileReadString(fh);

string smb3=FileReadString(fh);

// 如果品种的数据可用, 在到达行尾后将它们写入我们的三角数组

if (!csmb.Name(smb1) || !csmb.Name(smb2) || !csmb.Name(smb3)) {while(!FileIsLineEnding(fh)) FileReadString(fh);continue;}

int cnt=ArraySize(MxSmb);

ArrayResize(MxSmb,cnt+1);

MxSmb[cnt].smb1.name=smb1;

MxSmb[cnt].smb2.name=smb2;

MxSmb[cnt].smb3.name=smb3;

while(!FileIsLineEnding(fh)) FileReadString(fh);

}

}

本节所需的最后一个函数是前两个函数的包装。它负责根据 EA 输入来选择三角的来源。另外, 检查机器人的启动位置。如果在测试器当中, 无论用户选择什么, 都可以从文件中上传三角。如果没有文件, 下载默认的 EURUSD + GBPUSD + EURGBP 三角。

———————————————————————————————————————

源代码如下:

void fnSetThree(stThree &MxSmb[],enMode mode)

{

// 重置我们的三角数组

ArrayFree(MxSmb);

// 检查我们是否在测试器中

if((bool)MQLInfoInteger(MQL_TESTER))

{

// 如果是的话, 查找一个品种文件并从文件启动三角的上传

if(FileIsExist(FILENAME)) fnGetThreeFromFile(MxSmb);

// 如果未找到文件, 遍历所有可用品种查找其中默认的 EURUSD + GBPUSD + EURGBP 三角

else{

char cnt=0;

for(int i=SymbolsTotal(false)-1;i>=0;i--)

{

string smb=SymbolName(i,false);

if ((SymbolInfoString(smb,SYMBOL_CURRENCY_BASE)=="EUR" && SymbolInfoString(smb,SYMBOL_CURRENCY_PROFIT)=="GBP") ||

(SymbolInfoString(smb,SYMBOL_CURRENCY_BASE)=="EUR" && SymbolInfoString(smb,SYMBOL_CURRENCY_PROFIT)=="USD") ||

(SymbolInfoString(smb,SYMBOL_CURRENCY_BASE)=="GBP" && SymbolInfoString(smb,SYMBOL_CURRENCY_PROFIT)=="USD"))

{

if (SymbolSelect(smb,true)) cnt++;

}

else SymbolSelect(smb,false);

if (cnt>=3) break;

}

// 在市场观察中上载默认的三角之后, 启动三角

fnGetThreeFromMarketWatch(MxSmb);

}

return;

}

// 如果我们不在测试器当中, 查看用户选择的模式:

// 从市场观察或从文件中获取品种

if(mode==STANDART_MODE || mode==CREATE_FILE) fnGetThreeFromMarketWatch(MxSmb);

if(mode==USE_FILE) fnGetThreeFromFile(MxSmb);

——————————————————————————————————————————————

此处我们使用一个辅助函数 — fnSmbCheck()。它检查所用品种是否有任何限制。若是, 则跳过。下面是它的代码。

——————————————————————————————————

源代码如下:

bool fnSmbCheck(string smb)

{

// 三角只能由货币对组成

if(SymbolInfoInteger(smb,SYMBOL_TRADE_CALC_MODE)!=SYMBOL_CALC_MODE_FOREX) return(false);

// 如果有交易限制, 跳过此品种

if(SymbolInfoInteger(smb,SYMBOL_TRADE_MODE)!=SYMBOL_TRADE_MODE_FULL) return(false);

// 如果是合约的开始或结束, 也跳过该品种, 因为在处理货币时不使用该参数

if(SymbolInfoInteger(smb,SYMBOL_START_TIME)!=0)return(false);

if(SymbolInfoInteger(smb,SYMBOL_EXPIRATION_TIME)!=0) return(false);

// 可用的订单类型。虽然机器人只进行市价订单交易, 但不应有限制

int som=(int)SymbolInfoInteger(smb,SYMBOL_ORDER_MODE);

if((SYMBOL_ORDER_MARKET&som)==SYMBOL_ORDER_MARKET); else return(false);

if((SYMBOL_ORDER_LIMIT&som)==SYMBOL_ORDER_LIMIT); else return(false);

if((SYMBOL_ORDER_STOP&som)==SYMBOL_ORDER_STOP); else return(false);

if((SYMBOL_ORDER_STOP_LIMIT&som)==SYMBOL_ORDER_STOP_LIMIT); else return(false);

if((SYMBOL_ORDER_SL&som)==SYMBOL_ORDER_SL); else return(false);

if((SYMBOL_ORDER_TP&som)==SYMBOL_ORDER_TP); else return(false);

// 为了数据可用性检查标准库

if(!csmb.Name(smb)) return(false);

// 以下检查仅在实际操作中需要, 因为在某些情况下, 出于某些原因 SymbolInfoTick 接收价格

// 而竞卖价或竞买价依旧为 0。

// 在测试器中禁用, 因为价格可能会在稍后出现。

if(!(bool)MQLInfoInteger(MQL_TESTER))

{

MqlTick tk;

if(!SymbolInfoTick(smb,tk)) return(false);

if(tk.ask<=0 ||  tk.bid<=0) return(false);

}

return(true);

}

——————————————————————————————————————————————

所以, 三角就形成了。forming 函数置于 fnSetThree.mqh 包含文件中。检查品种限制的函数置于单独的 fnSmbCheck.mqh 文件中。

  • TA的每日心情
    开心
    2019-5-29 15:26
  • 签到天数: 45 天

    [LV.5]常住居民I

    313

    主题

    1921

    帖子

    4912

    积分

    论坛元老

    Rank: 8Rank: 8

    灵客宝
    2
    金钱
    2987
    在线时间
    250 小时
    注册时间
    2018-6-27
    发表于 2018-9-18 11:55:32 | 显示全部楼层
    感谢分享,写的很详细,找了很久!
    回复
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    5 小时前
  • 签到天数: 36 天

    [LV.5]常住居民I

    6

    主题

    114

    帖子

    307

    积分

    中级会员

    Rank: 3Rank: 3

    灵客宝
    38
    金钱
    117
    在线时间
    22 小时
    注册时间
    2019-5-12
    发表于 2019-5-27 16:52:25 | 显示全部楼层
    这个厉害啊
    回复
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    7 小时前
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    0

    主题

    50

    帖子

    106

    积分

    注册会员

    Rank: 2

    灵客宝
    12
    金钱
    32
    在线时间
    12 小时
    注册时间
    2019-3-12
    发表于 4 天前 | 显示全部楼层
    路过向大神学习学习
    回复
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    10 小时前
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    0

    主题

    33

    帖子

    79

    积分

    注册会员

    Rank: 2

    灵客宝
    11
    金钱
    24
    在线时间
    23 小时
    注册时间
    2019-6-4
    发表于 4 天前 | 显示全部楼层
    来拜读一下,高手之作
    回复
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    20

    帖子

    39

    积分

    新手上路

    Rank: 1

    灵客宝
    8
    金钱
    3
    在线时间
    3 小时
    注册时间
    2019-6-8
    发表于 4 天前 | 显示全部楼层
    来拜读一下,高手之作
    回复
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    3 天前
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    0

    主题

    45

    帖子

    270

    积分

    中级会员

    Rank: 3Rank: 3

    灵客宝
    52
    金钱
    121
    在线时间
    7 小时
    注册时间
    2019-3-23
    发表于 4 天前 | 显示全部楼层
    虽然看不懂,膜拜一下高手
    回复
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    20

    帖子

    39

    积分

    新手上路

    Rank: 1

    灵客宝
    8
    金钱
    3
    在线时间
    3 小时
    注册时间
    2019-6-8
    发表于 3 天前 | 显示全部楼层
    不错 学习学习啊
    回复
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    9 小时前
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    1

    主题

    28

    帖子

    84

    积分

    注册会员

    Rank: 2

    灵客宝
    12
    金钱
    32
    在线时间
    11 小时
    注册时间
    2019-4-29
    发表于 3 天前 | 显示全部楼层
    由三个金融工具组
    回复
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    20

    帖子

    39

    积分

    新手上路

    Rank: 1

    灵客宝
    8
    金钱
    3
    在线时间
    3 小时
    注册时间
    2019-6-8
    发表于 昨天 09:08 | 显示全部楼层
    直接弄个EA的了啊
    回复
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-5-30 14:04
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    1

    主题

    66

    帖子

    351

    积分

    中级会员

    Rank: 3Rank: 3

    灵客宝
    74
    金钱
    137
    在线时间
    25 小时
    注册时间
    2019-2-28
    发表于 昨天 10:55 | 显示全部楼层
    6666666666666!
    回复
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    0

    主题

    20

    帖子

    39

    积分

    新手上路

    Rank: 1

    灵客宝
    8
    金钱
    3
    在线时间
    3 小时
    注册时间
    2019-6-8
    发表于 9 小时前 | 显示全部楼层
    拜读 虽然搞不懂
    回复
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    展开

    手机版|小黑屋|灵客社区
    灵客外汇论坛-全国最大的外汇ea论坛交流社区

    GMT+8, 2019-6-17 22:56 , Processed in 1.266601 second(s), 33 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

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