期货_期货量化交易软件:为智能系统制定品质因数

本文介绍了如何在赫兹量化期货软件中通过品质得分衡量系统性能,探讨了两种评估方法,并详细展示了如何设计一个基础交易系统,包括随机开仓规则、止损管理以及交易时段限制。系统尚未优化,OnTesterresult暂时为零,等待后续品质分数计算函数的实现。
摘要由CSDN通过智能技术生成

在本文中,赫兹量化期货软件将见识到如何制定一个品质得分,并由您的智能系统从策略测试器返回。 在下面的图例 1 中,您可以看到 “OnTester result” 值为 1.0639375,此即展示所执行系统的品质示例。 在本文中,我们将学到两种可能的方式来测量系统品质,并将看清如何记录这两个数值,因为我们只能返回其中一个值。

添加图片注释,不超过 140 字(可选)

图例 1:高亮显示的 “OnTester result” 字段。

添加图片注释,不超过 140 字(可选)

启动交易模型,并构建 EA

在解决系统品质因数之前,有必要创建一个能在测试中使用的基本系统。 我们选择了一个简单的系统:我们先选择一个随机数字,若它是偶数,我们就开仓做多;否则,我们开仓做空,因为数字是奇数。

为了保持随机抽取,我们调用 MathRand() 函数,它提供一个介于 0(零)至 32767 之间的数字。 此外,为了令系统更加平衡,我们将添加两条互补规则。 有了这三条规则,我们将努力确保系统更加可靠。 它们是:

  • 当我们无持仓时,生成一个随机数

  • 如果数字为 0 或 32767,则啥都不做

  • 如果数字为偶数,则按最小手数的交易量做多资产

  • 如果数字为奇数,则按最小手数的交易量做空资产

  • 当我们有持仓时,沿每根新烛条的方向移动止损价位,该烛条在走势方向上高于前一根烛条

  • 所用的止损价位将基于:1-周期的 ATR 指标值,经 8-周期 EMA 均化后的常规化值。 此外,它将置于距所分析两根烛条的最远端

  • 如果时间在 11:00 到 16:00 的范围之外,我们不允许开仓,且在 16:30 必须平仓。

以下是制定这些规则的代码。

 
 

//--- Indicator ATR(1) with EMA(8) used for the stop level... int ind_atr = iATR(_Symbol, PERIOD_CURRENT, 1); int ind_ema = iMA(_Symbol, PERIOD_CURRENT, 8, 0, MODE_EMA, ind_atr); //--- Define a variable that indicates that we have a deal... bool tem_tick = false; //--- An auxiliary variable for opening a position #include<Trade/Trade.mqh> #include<Trade/SymbolInfo.mqh> CTrade negocios; CSymbolInfo info; //--- Define in OnInit() the use of the timer every second //--- and start CTrade int OnInit() { //--- Set the fill type to keep a pending order //--- until it is fully filled negocios.SetTypeFilling(ORDER_FILLING_RETURN); //--- Leave the fixed deviation at it is not used on B3 exchange negocios.SetDeviationInPoints(5); //--- Define the symbol in CSymbolInfo... info.Name(_Symbol); //--- Set the timer... EventSetTimer(1); //--- Set the base of the random number to have equal tests... MathSrand(0xDEAD); return(INIT_SUCCEEDED); } //--- Since we set a timer, we need to destroy it in OnDeInit(). void OnDeinit(const int reason) { EventKillTimer(); } //--- The OnTick function only informs us that we have a new deal void OnTick() { tem_tick = true; } //+------------------------------------------------------------------+ //| Expert Advisor main function | //+------------------------------------------------------------------+ void OnTimer() { MqlRates cotacao[]; bool fechar_tudo = false; bool negocios_autorizados = false; //--- Do we have a new trade? if(tem_tick == false) return ; //--- To check, return information of the last 3 candlesticks.... if(CopyRates(_Symbol, PERIOD_CURRENT, 0, 3, cotacao) != 3) return ; //--- Is there a new candlestick since the last check? if(tem_vela_nova(cotacao[2]) == false) return ; //--- Get data from the trade window and closing... negocios_autorizados = esta_na_janela_de_negocios(cotacao[2], fechar_tudo); //--- If we are going to close everything and if there is a position, close it... if(fechar_tudo) { negocios.PositionClose(_Symbol); return ; } //--- if we are not closing everything, move stop level if there is a position... if(arruma_stop_em_posicoes(cotacao)) return ; if (negocios_autorizados == false) // are we outside the trading window? return ; //--- We are in the trading window, try to open a new position! int sorteio = MathRand(); //--- Entry rule 1.1 if(sorteio == 0 || sorteio == 32767) return ; if(MathMod(sorteio, 2) == 0) // Draw rule 1.2 -- even number - Buy { negocios.Buy(info.LotsMin(), _Symbol); } else // Draw rule 1.3 -- odd number - Sell { negocios.Sell(info.LotsMin(), _Symbol); } } //--- Check if we have a new candlestick... bool tem_vela_nova(const MqlRates &rate) { static datetime vela_anterior = 0; datetime vela_atual = rate.time; if(vela_atual != vela_anterior) // is time different from the saved one? { vela_anterior = vela_atual; return true; } return false; } //--- Check if the time is n the trade period to close positions... bool esta_na_janela_de_negocios(const MqlRates &rate, bool &close_positions) { MqlDateTime mdt; bool ret = false; close_positions = true; if(TimeToStruct(rate.time, mdt)) { if(mdt.hour >= 11 && mdt.hour < 16) { ret = true; close_positions = false; } else { if(mdt.hour == 16) close_positions = (mdt.min >= 30); } } return ret; } //--- bool arruma_stop_em_posicoes(const MqlRates &cotacoes[]) { if(PositionsTotal()) // Is there a position? { double offset[1] = { 0 }; if(CopyBuffer(ind_ema, 0, 1, 1, offset) == 1 // EMA successfully copied? && PositionSelect(_Symbol)) // Select the existing position! { ENUM_POSITION_TYPE tipo = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE); double SL = PositionGetDouble(POSITION_SL); double TP = info.NormalizePrice(PositionGetDouble(POSITION_TP)); if(tipo == POSITION_TYPE_BUY) { if (cotacoes[1].high > cotacoes[0].high) { double sl = MathMin(cotacoes[0].low, cotacoes[1].low) - offset[0]; info.NormalizePrice(sl); if (sl > SL) { negocios.PositionModify(_Symbol, sl, TP); } } } else // tipo == POSITION_TYPE_SELL { if (cotacoes[1].low < cotacoes[0].low) { double sl = MathMax(cotacoes[0].high, cotacoes[1].high) + offset[0]; info.NormalizePrice(sl); if (SL == 0 || (sl > 0 && sl < SL)) { negocios.PositionModify(_Symbol, sl, TP); } } } } return true; } // there was no position return false; }

赫兹量化期货软件简略研究一下上面的代码。 我们将经均化计算的 ATR 值来判定止损步长,即我们发现当前烛条超过前一根时,将止损价位放置在烛条的边界。 这是在函数 arruma_stop_em_posicoes 中完成的。 当其返回 true 时,已有设置,且我们无需在 OnTimer 的主代码中前进。 我使用该函数取代 OnTick,因为我不需要针对每笔执行的交易运行一遍大函数。 函数应该在所定义周期的每根新烛条建立时执行。 在 OnTick 中,设置 true 值表示前一笔交易。 这是必要的;否则,在休市期间,策略测试器将引入暂停,因为即使没有前一笔的交易,它也会执行该函数。

到该处为止,一切都严格按照定义好的计划进行,包括两个指定的窗口。 第一个是开仓交易的窗口,在 11:00 到 4:00 之间。 第二个是管理窗口,它允许算法管理持仓,移动其止损价位,直至 16:30 — 此时它应该把当天的所有交易了结。

请注意,如果我们现在用这个 EA 进行交易,“OnTester result” 将为零,如图例 2 所示,因为我们还没有为这个值提供计算函数。

添加图片注释,不超过 140 字(可选)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值