Вы находитесь на странице: 1из 7

//+------------------------------------------------------------------+

//| RC-Stochastic.mq5 |
//| Antonio Guglielmi |
//| RobotCrowd - Crowdsourcing para trading automatizado |
//| https://www.robotcrowd.com.br |
//| |
//+------------------------------------------------------------------+
// Copyright 2017 Antonio Guglielmi - RobotCrowd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "include/RCCommon.mqh"

#property copyright "Antonio Guglielmi - RobotCrowd"


#property link "https://www.robotcrowd.com.br"
#property version RC_TRADEWATCH_VER
#property description "Robo Estocastico"
#property description " "
#property description "Este robo e distribuido gratuitamente para membros da
comunidade RobotCrowd."
#property description "A utilizacao em contas reais e de inteira responsabilidade
do usuario e o site RobotCrowd nao se"
#property description "responsabiliza por eventuais perdas decorrentes da
utilizacao de qualquer um dos robos."
#property description " "
#property description "RobotCrowd - Crowdsourcing para trading automatizado"
#property icon "\\Images\\robotcrowd.ico"

#include "TradeWatch.mqh"
#include "TradeFilter.mqh"

enum StoTradeModeType {
STO_MODE_POP, // Estocastico Pop
STO_MODE_OB_OS, // Sobrecompra/Sobrevenda
STO_MODE_BOTH // Ambos
};

enum StoExitSignalType {
STO_EXIT_CROSS, // Cruzamento principal/sinal
STO_EXIT_PERCENT, // Superacao percentual SC/SV
STO_EXIT_PARTIAL, // 50% cruzando 50% percentual
STO_EXIT_NONE // Nenhum - usa o stop movel
};

input string inDescSto="==========================="; // ======== R.22.


PARAMETROS ESTOCASTICO =======
input string inEAName="RC-Stochastic"; // R.22.0 Nome do
robo para validar sets (nao alterar)
input int inKPeriod=14; // R.22.1 Periodo
%K (Numero de barras)
input int inDPeriod=3; // R.22.2 Periodo
%D (Primeira suavizacao)
input int inSlowing=3; // R.22.3 Periodo
de suavizacao final
input ENUM_MA_METHOD inSlowingType=MODE_EMA; // R.22.4 Metodo
de calculo da suavizacao (Media Movel)
input ENUM_STO_PRICE inStoPrice=STO_CLOSECLOSE; // R.22.5 Preco
considerado no estocastico
input double inOSLevel=25.0; // R.22.6 Nivel
de sobrevenda (%)
input double inOBLevel=75.0; // R.22.7 Nivel
de sobrecompra (%)
input StoTradeModeType inStoTradeMode=STO_MODE_POP; // R.22.8 Modo de
operacao pelo estocastico
input StoExitSignalType inStoExitSignal=STO_EXIT_PARTIAL; // R.22.9 Metodo
de saida da operacao

int stoHandle; // handle para o estocastico


MqlRates mrate[]; // Array dinamico para armazenar cotacoes
MqlRates lastBarRates; // Dados de preco da ultima barra
double stoMainVal[]; // Array dinamico para armazenar valores da linha principal
do stocastico
double stoSignalVal[]; // Array dinamico para armazenar valores da linha principal
do stocastico
double stopLoss; // Valor calculado para o stop loss
double takeProfit; // Valor calculado para o objetivo

bool runOnce;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{

Print("Iniciando robo do oscilador estocastico versao ", RC_TRADEWATCH_VER,


"...");
if (inSetDescription != "") Print("Usando ajuste ", inSetDescription);

stoHandle=iStochastic(_Symbol, inPeriod, inKPeriod, inDPeriod, inSlowing,


inSlowingType, inStoPrice);
if(stoHandle<0) {
Print("Erro criando indicadores iStochastic - error:
",GetLastError(),"!");
return(INIT_FAILED);
}
else if (inShowIndicators) {
int subwindow = (int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
ChartIndicatorAdd(0, subwindow, stoHandle);
}

ArraySetAsSeries(mrate,true);
ArraySetAsSeries(stoMainVal,true);
ArraySetAsSeries(stoSignalVal,true);
// Inicializa a biblioteca de gerenciamento de trades
int r = initTradeWatch();
tradew.checkSetFile(inEAName);
// Inicializa a biblioteca de filtros
initTradeFilter();

if (!filter.checkFilterHandles()) {
Print("Erro na inicializacao de filtros!!");
}

runOnce = false;

return(r);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{

IndicatorRelease(stoHandle);
deinitTradeWatch();
deinitTradeFilter();

void OnTradeTransaction(const MqlTradeTransaction &trans,


const MqlTradeRequest &request,
const MqlTradeResult &result) {

tradew.processTradeTransaction(trans, request, result);

void OnTimer() {

tradew.processTimer();

//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {

#ifndef RC_SKIP_WFO

// Sessao especifica para tratamento da otimizacao usando a biblioteca WFO

if (inWFOEnable) {
int wfo = wfo_OnTick();
if(wfo == -1) {
// Janela de negociacao ainda nao iniciada
return;
}
else if(wfo == +1) {
// Janela de negociacao ja finalizada
return;
}
}

#endif

// Verifica se existem barras suficientes


if (!tradew.checkBarCount(inKPeriod + 1)) {
Print("Nao existem barras suficientes no grafico para executar o EA...");
return;
}

// Garante que so vai executar a funcao apos o tempo de espera definido


if (!tradew.checkTickDelay()) {
return;
}

tradew.checkPosition();

// Se tivermos uma barra nova, verifica se existe algum ponto de entrada


if (tradew.checkNewBar() || (tradew.checkTradeTime() && (!runOnce))) {

// Verifica se eh a primeira barra do dia


if (tradew.checkNewDay()) {
Print("Novo dia detectado...");
runOnce = false;
}

if (tradew.buyTriggered() && (!filter.checkBuyFilter()))


tradew.cancelBuyTrade();
if (tradew.sellTriggered() && (!filter.checkSellFilter()))
tradew.cancelSellTrade();

if(CopyRates(_Symbol, inPeriod, 0, 4, mrate) < 0) {


Print("Erro copiando dados historicos - error:",GetLastError(),"!!");
ResetLastError();
return;
}

if(CopyBuffer(stoHandle, 0, 0, 4, stoMainVal) < 0) {


Print("Erro copiando buffer da linha principal do indicador iStochastic -
error:",GetLastError());
ResetLastError();
return;
}

if(CopyBuffer(stoHandle, 1, 0, 4, stoSignalVal) < 0) {


Print("Erro copiando buffer da linha de sinal do indicador iStochastic -
error:",GetLastError());
ResetLastError();
return;
}

// Salva os valores obtidos da ultima barra


lastBarRates = mrate[1];
// Condicoes de compra e venda
bool BuyCondition = false;
bool SellCondition = false;

if (tradew.checkTradeTime()) {

runOnce = true;

if (inStoTradeMode != STO_MODE_OB_OS) {
// Modo de operacao POP

// Compra ao superar percentual de sobrecompra (75%)


if ((!tradew.isBuyPosition()) && (!tradew.buyTriggered()) &&
((stoMainVal[1] > inOBLevel) && (stoMainVal[2] <= inOBLevel))) {
Print("Superacao de percentual de sobrecompra. Realizando
entrada...");
BuyCondition = true;
}
// Vende ao superar percentual de sobrevenda (25%)
else if ((!tradew.isSellPosition()) && (!tradew.sellTriggered()) &&
((stoMainVal[1] < inOSLevel) && (stoMainVal[2] >= inOSLevel))) {
Print("Superacao de percentual de sobrevenda. Realizando
entrada...");
SellCondition = true;
}
// Estrategia de saida
else if (tradew.isBuyPosition()) {
if ((stoMainVal[1] < stoSignalVal[1]) && (stoMainVal[2] >=
stoSignalVal[2])) {
// Linha principal cruzou sinal para baixo...
Print("Linha principal cruzou sinal para baixo...");
if (inStoExitSignal == STO_EXIT_CROSS) {
// Se este for o unico sinal de saida, fecha a posicao
Print("Encerrando posicao comprada...");
tradew.closePosition();
}
else if (inStoExitSignal == STO_EXIT_PARTIAL) {
// Executa realizacao parcial
Print("Executando realizacao parcial...");
tradew.execPartialProfit(inLot / 2.0);
}
}

if ((inStoExitSignal != STO_EXIT_NONE) && (stoMainVal[1] <


inOBLevel) && (stoMainVal[2] >= inOBLevel)) {
Print("Encerrando posicao comprada...");
tradew.closePosition();
}
}
else if (tradew.isSellPosition()) {
if ((stoMainVal[1] > stoSignalVal[1]) && (stoMainVal[2] <=
stoSignalVal[2])) {
// Linha principal cruzou sinal para cima...
if (inStoExitSignal == STO_EXIT_CROSS) {
// Se este for o unico sinal de saida, fecha a posicao
Print("Encerrando posicao vendida...");
tradew.closePosition();
}
else if (inStoExitSignal == STO_EXIT_PARTIAL) {
// Executa realizacao parcial
Print("Executando realizacao parcial...");
tradew.execPartialProfit(inLot / 2.0);
}
}

if ((inStoExitSignal != STO_EXIT_NONE) && (stoMainVal[1] >


inOSLevel) && (stoMainVal[2] <= inOSLevel)) {
Print("Encerrando posicao vendida...");
tradew.closePosition();
}
}
}

if (inStoTradeMode != STO_MODE_POP) {
// Modo de operacao Sobrecompra/Sobrevenda

// Compra ao superar percentual de sobrevenda (25%)


if ((!tradew.isBuyPosition()) && (!tradew.buyTriggered()) &&
((stoMainVal[1] > inOSLevel) && (stoMainVal[2] <= inOSLevel))) {
Print("Cruzamento percentual de sobrecompra. Realizando
entrada...");
BuyCondition = true;
}
// Vende ao superar percentual de sobrecompra (75%)
else if ((!tradew.isSellPosition()) && (!tradew.sellTriggered()) &&
((stoMainVal[1] < inOBLevel) && (stoMainVal[2] >= inOBLevel))) {
Print("Cruzamento percentual de sobrevenda. Realizando
entrada...");
SellCondition = true;
}
// Estrategia de saida
else if (tradew.isBuyPosition()) {
if ((stoMainVal[1] < stoSignalVal[1]) && (stoMainVal[2] >=
stoSignalVal[2])) {
// Linha principal cruzou sinal para baixo...
Print("Linha principal cruzou sinal para baixo...");
if (inStoExitSignal == STO_EXIT_CROSS) {
// Se este for o unico sinal de saida, fecha a posicao
Print("Encerrando posicao comprada...");
tradew.closePosition();
}
else if (inStoExitSignal == STO_EXIT_PARTIAL) {
// Executa realizacao parcial
Print("Executando realizacao parcial...");
tradew.execPartialProfit(inLot / 2.0);
}
}
else if ((stoMainVal[1] > inOBLevel) && (stoMainVal[2] <=
inOBLevel)) {
Print("Encerrando posicao comprada...");
tradew.closePosition();
}
}
else if (tradew.isSellPosition()) {
if ((stoMainVal[1] > stoSignalVal[1]) && (stoMainVal[2] <=
stoSignalVal[2])) {
// Linha principal cruzou sinal para cima...
if (inStoExitSignal == STO_EXIT_CROSS) {
// Se este for o unico sinal de saida, fecha a posicao
Print("Encerrando posicao vendida...");
tradew.closePosition();
}
else if (inStoExitSignal == STO_EXIT_PARTIAL) {
// Executa realizacao parcial
Print("Executando realizacao parcial...");
tradew.execPartialProfit(inLot / 2.0);
}
}
else if ((stoMainVal[1] < inOSLevel) && (stoMainVal[2] >=
inOSLevel)) {
Print("Encerrando posicao vendida...");
tradew.closePosition();
}
}

if (BuyCondition && (inTradeType != TRADE_TYPE_SELL)) {


stopLoss = tradew.calcStopLoss(lastBarRates, lastBarRates.high, BUY);
takeProfit = tradew.calcTakeProfit(lastBarRates, lastBarRates.high,
BUY);
tradew.startNewTrade(BUY, lastBarRates.high, stopLoss, takeProfit);
}
else if (SellCondition && (inTradeType != TRADE_TYPE_BUY)) {
stopLoss = tradew.calcStopLoss(lastBarRates, lastBarRates.low, SELL);
takeProfit = tradew.calcTakeProfit(lastBarRates, lastBarRates.low,
SELL);
tradew.startNewTrade(SELL, lastBarRates.low, stopLoss, takeProfit);

// Verifica os precos de mercado e envia a ordem as condicoes forem satisfeitas


tradew.checkPrices();

return;
}