#define VERSION "1.0"
#property version VERSION

#define PROJECT_NAME MQLInfoString(MQL_PROGRAM_NAME)

#include <Trade/Trade.mqh>

input group "=============Expert Advisor Settings=============";
input int Magic = 12345; // Magic Number

input group "=============Money Management=============";
input int TpPoints = 200; // Take Profit Points
input int SlPoints = 200; // Stop Loss Points
input double Lots = 0.1;        // Lots

//=====Handles=====
int handleRSI;
int stochHandle;

//=====Trade objects=====
CTrade trade;
ulong positionTicket;

int totalBars;

int OnInit()
{
    Print("Expert Advisor ", PROJECT_NAME, " v", VERSION, " started");
    trade.SetExpertMagicNumber(Magic);
    handleRSI = iRSI(_Symbol, _Period, 14, PRICE_CLOSE);
    stochHandle = iStochastic(_Symbol, _Period, 8, 3, 3, MODE_SMMA, STO_LOWHIGH);

    return (INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
    Print("Expert Advisor ", PROJECT_NAME, " v", VERSION, " stopped. Reason: ", reason);
}

void OnTick()
{

    int bars = iBars(_Symbol, _Period);
    if (totalBars != bars && PositionsTotal() == 0) // only run on new bar and no open positions
    {
        totalBars = bars;

        double rsiBuffer[1];
        CopyBuffer(handleRSI, MAIN_LINE, 1, 1, rsiBuffer);

        double stochMainBuffer[1];
        double stochSignalBuffer[1];
        CopyBuffer(stochHandle, MAIN_LINE, 1, 1, stochMainBuffer);
        CopyBuffer(stochHandle, SIGNAL_LINE, 1, 1, stochSignalBuffer);

        // Comment("RSI: ", rsiBuffer[0], " StochMain: ", stochMainBuffer[0], " StochSignal: ", stochSignalBuffer[0]);

        if (rsiBuffer[0] > 50 && stochSignalBuffer[0] > stochMainBuffer[0])
        {
            if (trade.Buy(Lots))
            {
                positionTicket = trade.ResultOrder();
                // add take profit and stop loss
                PositionSelectByTicket(positionTicket);
                double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                double takeProfit = entryPrice + TpPoints * _Point;
                takeProfit = NormalizeDouble(takeProfit, _Digits);
                double stopLoss = entryPrice - SlPoints * _Point;
                stopLoss = NormalizeDouble(stopLoss, _Digits);

                trade.PositionModify(positionTicket, stopLoss, takeProfit);
            }
        }
        else if (rsiBuffer[0] < 50 && stochMainBuffer[0] < stochSignalBuffer[0])
        {
            if (trade.Sell(Lots))
            {
                positionTicket = trade.ResultOrder();
                // add take profit and stop loss
                PositionSelectByTicket(positionTicket);
                double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                double takeProfit = entryPrice - TpPoints * _Point;                
                takeProfit = NormalizeDouble(takeProfit, _Digits);
                double stopLoss = entryPrice + SlPoints * _Point;
                stopLoss = NormalizeDouble(stopLoss, _Digits);
                trade.PositionModify(positionTicket, stopLoss, takeProfit);
            }
        }
    }
}