GNU General Public License v3.0

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

EA31337-classes 技术深度分析

项目背景与痛点

在量化交易领域,MQL 是一种强大的编程语言,主要用来编写交易策略、指标和脚本。然而,直接在 MQL 中编写复杂的逻辑和算法并不容易,尤其是在需要管理和维护大量不同模块时。EA31337 framework 正是为了解决这一痛点而诞生的。它提供了一个基于 MQL 的开发框架,旨在帮助开发者更高效地编写、管理和复用交易策略、指标和脚本。

核心技术揭秘

EA31337-classes 项目的核心技术在于其模块化的设计和灵活的数据流管理。框架内部结构清晰,通过一套高度抽象的接口和组件实现交易策略、指标和脚本的模块化组织。以下是项目的核心模块及其数据流:

graph TD A[交易策略接口] --> B[指标计算模块] B --> C[交易决策模块] C --> D[订单管理模块] D --> E[日志与监控模块] A --> F[脚本执行模块] F --> E C --> F

技术架构分析

  1. 模块化接口设计:EA31337-classes 提供了多种模块化接口,用于抽象交易策略的各个环节。例如,通过「交易策略接口」,用户可以迅速定义新的策略逻辑,而不需要从零开始编写。

  2. 指标计算模块:该模块负责处理市场数据,通过内置或自定义的计算逻辑生成所需的指标数据,为后续的交易决策提供支持。

  3. 交易决策模块:结合指标数据和预设的交易策略,决策模块可以自动触发买卖操作,通过预先设置的条件与风险控制策略,做出最优的交易决策。

  4. 订单管理模块:有效地管理和追踪订单状态,确保交易执行的稳定性和安全性。

  5. 日志与监控模块:提供详细的日志记录和监控功能,方便用户跟踪系统运行状态并进行故障排查。

  6. 脚本执行模块:允许用户通过编写脚本执行复杂或自定义的操作,进一步拓展系统的灵活性。

功能亮点与差异

相比同类竞品,EA31337-classes 的优势主要体现在其高度的自定义能力和灵活的数据流管理。用户可以通过定义不同模块组合来自定义复杂的交易逻辑,而内嵌的监控与日志模块又能在生产环境中确保系统的稳定性和可维护性。

另一个关键的竞争优势在于其模块化的接口设计,使得不同模块之间可以灵活组装,大大降低了二次开发和维护的成本。同时,模块化的设计也有助于全球开发者之间共建社区,并分享和复用高质量的策略和脚本。

应用场景与落地建议

在生产环境使用时,最重要的是确保每个模块的稳定性和数据一致性。为了实现这一点,建议开发者在正式部署时进行充分的测试,特别关注系统中的日志和监控数据,以尽早发现潜在的问题。此外,EA31337-classes 特别适合那些需要快速迭代策略,支持高度定制化的量化交易环境。比如,在快节奏的高频交易场景中,开发者可以利用这个框架迅速发布与调整交易策略。

综合评价

优点:

  • 模块化设计,支持高度自定义
  • 全面的监控与日志记录,确保系统稳定性
  • 丰富的内置模块,缩短开发周期

缺点:

  • 开源社区角色与维护者需要更多协作才能确保框架的持续完善
  • 对于初学者来说,框架的学习曲线较陡

总之,EA31337-classes 提供了强大的工具和框架,使开发量化交易策略的过程更加高效。作为开发者,通过充分利用这套框架的强大功能,可以快速实现和部署更复杂的交易逻辑,成为量化交易领域的佼佼者。

关于

GitHub 原始描述(英文)

📦📈 EA31337 framework (MQL library for writing trading Expert Advisors, indicators and scripts)

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

简要分析

热度分
546
价值分
195
活跃状态
活跃

语言占比

C
C++
HLSL
MQL4
MQL5

README

EA31337 Framework

Tag License Status Status Status Channel Twitter

EA31337 framework is designed for writing trading robots for MetaTrader 4 and 5 platforms. It can be also used to convert your MQL4 code into MQL5 with minimum code changes.

Table of contents

Projects

Projects implementing this framework:

Conversion

MQL4 to MQL5 conversion

This framework can be used to convert your MQL4 code to be compatible with both MQL4 and MQL5.

Find below the table of conversion (replace code on left with the right one):

MQL4 (original) MQL4 & MQL5 (replace with) Required include file
WindowRedraw() Chart::WindowRedraw() Chart.mqh
Day() DateTime::Day() DateTime.mqh
TimeDayOfWeek() DateTime::DayOfWeek() DateTime.mqh
DayOfWeek() DateTime::DayOfWeek() DateTime.mqh
DayOfYear() DateTime::DayOfYear() DateTime.mqh
Hour() DateTime::Hour() DateTime.mqh
Month() DateTime::Month() DateTime.mqh
TimeDay() DateTime::TimeDay() DateTime.mqh
TimeDayOfYear() DateTime::TimeDayOfYear() DateTime.mqh
TimeToStr() DateTime::TimeToStr() DateTime.mqh
Year() DateTime::Year() DateTime.mqh
iAC() Indi_AC::iAC() Indicators/Indi_AC.mqh
iAD() Indi_AD::iAD() Indicators/Indi_AD.mqh
iADX() Indi_ADX::iADX() Indicators/Indi_ADX.mqh
iAO() Indi_AO::iAO() Indicators/Indi_AO.mqh
iATR() Indi_ATR::iATR() Indicators/Indi_ATR.mqh
iBWMFI() Indi_BWMFI::iBWMFI() Indicators/Indi_BWMFI.mqh
iBands() Indi_Bands::iBands() Indicators/Indi_Bands.mqh
iBearsPower() Indi_BearsPower::iBearsPower() Indicators/Indi_BearsPower.mqh
iBullsPower() Indi_BullsPower::iBullsPower() Indicators/Indi_BullsPower.mqh
iCCI() Indi_CCI::iCCI() Indicators/Indi_CCI.mqh
iDeMarker() Indi_DeMarker::iDeMarker() Indicators/Indi_DeMarker.mqh
iEnvelopes() Indi_Envelopes::iEnvelopes() Indicators/Indi_Envelopes.mqh
iForce() Indi_Force::iForce() Indicators/Indi_Force.mqh
iFractals() Indi_Fractals::iFractals() Indicators/Indi_Fractals.mqh
iGator() Indi_Gator::iGator() Indicators/Indi_Gator.mqh
iIchimoku() Indi_Ichimoku::iIchimoku() Indicators/Indi_Ichimoku.mqh
iMA() Indi_MA::iMA() Indicators/Indi_MA.mqh
iMACD() Indi_MAcD::iMACD() Indicators/Indi_MACD.mqh
iMFI() Indi_MFI::iMFI() Indicators/Indi_MFI.mqh
iMomentum() Indi_Momentum::iMomentum() Indicators/Indi_Momentum.mqh
iOBV() Indi_OBV::iOBV() Indicators/Indi_OBV.mqh
iOsMA() Indi_OsMA::iOsMA() Indicators/Indi_OsMA.mqh
iRSI() Indi_RSI::iRSI() Indicators/Indi_RSI.mqh
iRVI() Indi_RVI::iRVI() Indicators/Indi_RVI.mqh
iSAR() Indi_SAR::iSAR() Indicators/Indi_SAR.mqh
iStdDev() Indi_StdDev::iStdDev() Indicators/Indi_StdDev.mqh
iStochastic() Indi_Stochastic::iStochastic() Indicators/Indi_Stochastic.mqh
iWPR() Indi_WPR::iWPR() Indicators/Indi_WPR.mqh
RefreshRates() Market::RefreshRates() Market.mqh
delete object Object::Delete(object) Object.mqh
GetOrderProfit() Order::GetOrderProfit() Order.mqh
OrderClose() OrderStatic::Close() Order.struct.h
OrderCloseTime() OrderStatic::CloseTime() Order.struct.h
OrderCommission() OrderStatic::Commission() Order.struct.h
OrderLots() OrderStatic::Lots() Order.struct.h
OrderMagicNumber() OrderStatic::MagicNumber() Order.struct.h
OrderOpenPrice() OrderStatic::OpenPrice() Order.struct.h
OrderOpenTime() OrderStatic::OpenTime() Order.struct.h
OrderPrint() OrderStatic::Print() Order.struct.h
OrderSelect() OrderStatic::Select() Order.struct.h
OrderStopLoss() OrderStatic::StopLoss() Order.struct.h
OrderSymbol() OrderStatic::Symbol() Order.struct.h
OrderTicket() OrderStatic::Ticket() Order.struct.h
OrderType() OrderStatic::Type() Order.struct.h
OrdersTotal() TradeStatic::TotalActive() Trade.mqh

Here are the special predefined variables conversion:

MQL4 (original) MQL4 & MQL5 (replace with) Required include file
Ask SymbolInfo::GetAsk() SymbolInfo.struct.static.h
Bars ChartStatic::iBars() Chart.struct.static.h
Bid SymbolInfo::GetBid() SymbolInfo.struct.static.h
Close[] ChartStatic::iClose() Chart.struct.static.h
Digits SymbolInfo::GetDigits() SymbolInfo.struct.static.h
High[] ChartStatic::iHigh() Chart.struct.static.h
Low[] ChartStatic::iLow() Chart.struct.static.h
Open[] ChartStatic::iOpen() Chart.struct.static.h
Point SymbolInfo::GetPointSize() SymbolInfo.struct.static.h
Time[] ChartStatic::iTime() Chart.struct.static.h
Volume[] ChartStatic::iVolume() Chart.struct.static.h

Classes

Account class

The class for managing the current trading account.

Example 1 - Managing account (dynamic calls)
Account *acc = new Account();
double _balance = acc.GetBalance();
double _credit = acc.GetCredit();
double _equity = acc.GetEquity();
double _margin_free = acc.GetMarginFree();
double _margin_used = acc.GetMarginUsed();
if (acc.IsExpertEnabled() && acc.IsTradeAllowed()) {
  // Some trade code.
}
delete acc;
Example 2 - Managing account (static calls)
double _balance = Account::AccountBalance();
double _credit = Account::AccountCredit();
double _equity = Account::AccountEquity();
double _margin_free = Account::AccountFreeMargin();
double _margin_used = Account::AccountMargin();
if (Account::IsExpertEnabled() && Account::IsTradeAllowed()) {
  // Some trade code.
}

Dict class

Use this class to store the values in form of a collective attribute–value pairs, in similar way as associative arrays with a hash table work.

Example 1 - Storing string-int data structures

Example of storing key-value data with string as a key:

Dict<string, int> data1;
data1.Set("a", 1);
data1.Set("b", 2);
data1.Set("c", 3);
data1.Unset("c");
Print(data1.GetByKey("a"));

Mail class

The purpose of Mail class is to provide common functionality for managing e-mails.

Example 1 - Send e-mail on trade execution

Example sending e-mail on trade execution:

int OnInit() { // @see: https://www.mql5.com/en/docs/event_handlers/oninit
  Mail *mail = new Mail();
  mail.SetSubjectPrefix("Trading");
}
void OnTrade() { // @see: https://www.mql5.com/en/docs/event_handlers/ontrade
  if (!Terminal::IsRealtime()) {
    mail.SendMailExecuteOrder();
  }
}
int OnDeinit() { // @see: https://www.mql5.com/en/docs/event_handlers/ondeinit
  delete mail;
}

Indicator class

The purpose of Indicator class is to provide common functionality across all indicators such as storing and searching for values.

This class is used as a base class to handle technical indicator classes which can be found in Indicators/ folder.

Indicators/ classes

In Indicators/ folder there is collection of indicator classes.

Example 1 - AC indicator

The example reading value from AC indicator:

#include <EA31337-classes/Indicators/Indi_AC.mqh>
int OnInit() {
  Indi_AC ac = new Indi_AC();
  PrintFormat("%g", ac.GetValue());
  delete ac;
}
Example 2 - Alligator indicator

The example reading values from Alligator indicator:

#include <EA31337-classes/Indicators/Indi_Alligator.mqh>
int OnInit() {
  AlligatorParams alli_params(13, 8, 8, 5, 5, 3, MODE_SMMA, PRICE_MEDIAN);
  Indi_Alligator alli = new Indi_Alligator(alli_params));
  AlligatorEntry values = alli.GetEntry(0);
  if (alli.GetFlag(INDI_ENTRY_FLAG_IS_VALID)) {
    Print("Alligator values: ", values.ToString());
  }
  delete alli;
}

IndicatorData class

The purpose of IndicatorData class is to store indicator data. It is basically alternative implementation of Indicator class.

For more details, please read: Class to hold indicator values.

For implementation example, check tests/IndicatorDataTest.mq4.

Profiler class

The purpose of Profiler class is to profile functions by measuring its time of execution. The minimum threshold can be set, so only slow execution can be reported.

Example 1 - Measure execution time of function multiple times

Example to measure execution time of function multiple times, then printing the summary of all calls which took 5ms or more.

#include "Profiler.mqh"

void MyFunction() {
  PROFILER_START
  Sleep(rand()%10);
  PROFILER_STOP
}

int OnInit() {
  for (uint i = 0; i < 10; i++) {
    MyFunction();
  }
  // Set minimum threshold of 5ms.
  PROFILER_SET_MIN(5)
  // Print summary of slow executions above 5ms.
  PROFILER_PRINT
  return (INIT_SUCCEEDED);
}

void OnDeinit(const int reason) {
  PROFILER_DEINIT
}
Example 2 - Measure execution time of function multiple times

Example to measure execution time of function multiple times, then automatically printing all calls which took 5ms or more.

#include "Profiler.mqh"

void MyFunction() {
  PROFILER_START
  Sleep(rand()%10);
  // Automatically prints slow executions.
  PROFILER_STOP_PRINT
}

int OnInit() {
  // Set minimum threshold of 5ms.
  PROFILER_SET_MIN(5);
  for (uint i = 0; i < 10; i++) {
    MyFunction();
  }
  return (INIT_SUCCEEDED);
}

void OnDeinit(const int reason) {
  PROFILER_DEINIT
}

SymbolInfo class

The class to manage the symbol’s information.

Example 1 - Accessing symbol’s data (dynamic)
SymbolInfo *si = new SymbolInfo();
string symbol = si.GetSymbol();
MqlTick tick = si.GetTick()
double ask = si.GetLastAsk();
double bid = si.GetLastBid();
uint spread = si.GetSpread();
Print("MARKET: ", si.ToString());
delete si;
Example 2 - Accessing symbol’s data (static)
string symbol = SymbolInfo::GetCurrentSymbol();
MqlTick tick = SymbolInfo::GetTick(symbol)
double ask = SymbolInfo::GetAsk(symbol);
double bid = SymbolInfo::GetBid(symbol);
uint spread = SymbolInfo::GetSpread(symbol);

Timer class

The purpose ofTimer class is to measure time between starting and stopping points.

Example 1 - Single timer

Single timer:

#include "Timer.mqh"

Timer *timer = new Timer("mytimer");
timer.Start();
// Some code to measure here.
timer.Stop();
Print("Time (ms): ", timer.GetSum());
timer.PrintSummary();
delete timer;
Example 2 - Multiple timers

Multiple measurements:

#include "Timer.mqh"

Timer *timer = new Timer(__FUNCTION__);
  for (uint i = 0; i < 5; i++) {
    timer.Start();
    Sleep(10); // Some code to measure here.
    PrintFormat("Current time elapsed before stop (%d/5): %d", i + 1, timer.GetTime());
    timer.Stop();
    PrintFormat("Current time elapsed after stop (%d/5): %d", i + 1, timer.GetTime(i));
  }
timer.PrintSummary();
delete timer;
Support

评论

暂无评论