MFI Bot

by afhacker in category Range at 18/09/2016
Description

This bot is based on Money Flow Index indicator and Heiken Ashi, The strategy is very simple it buys when a bullish HA candle closed and MFI was above a user defined level(default 40) and it sells when a bearish HA candle closed and MFI was below a user defined level(default 70).

It's not some martingale or grid type bot so it will have losing days, weeks and even consecutive losing months but it keeps your risk low and avoid big draw downs.

The above back test result time period was from 29/01/2012 to 16/09/2016 and the data type was tick data with $40 commission per standard lot.

Back test parameters file : https://drive.google.com/file/d/0B93GK1Ip4NSMbUt4aFA4dmxaVkU/view?usp=sharing

Download
475 downloads
How to install
Warning! Executing the following cBot may result in loss of funds. Use it at your own risk.
Notification Publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section you may use the Copyright Infringement Notification form to submit a claim.
Formula / Source Code
Language: C#
Trading Platform: cAlgo
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;


/*

Version 1.0
Developed by afhacker (Ahmad Noman Musleh)
Email : afhackermubasher@gmail.com

*/


namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MFIBot : Robot
    {
        [Parameter("ATR Periods", DefaultValue = 20)]
        public int atrPeriod { get; set; }

        [Parameter("ATR Multiplier", DefaultValue = 3)]
        public int atrMultiplier { get; set; }

        [Parameter("MFI Periods", DefaultValue = 20)]
        public int moneyFlowIndexPeriods { get; set; }

        [Parameter("Buy Above", DefaultValue = 40)]
        public int moneyFlowIndexBuy { get; set; }

        [Parameter("Sell Below", DefaultValue = 70)]
        public int moneyFlowIndexSell { get; set; }

        [Parameter("Time Filter", DefaultValue = false)]
        public bool timeFilter { get; set; }

        [Parameter("Start Hour", DefaultValue = 7, MinValue = 0, MaxValue = 23)]
        public int startHour { get; set; }

        [Parameter("End Hour", DefaultValue = 13, MinValue = 0, MaxValue = 23)]
        public int endHour { get; set; }

        [Parameter("Order Distance", DefaultValue = 1, MinValue = 1)]
        public double orderDistance { get; set; }

        [Parameter("% Risk Per Trade", DefaultValue = 1, MinValue = 0.1, MaxValue = 10.0)]
        public double riskPercentage { get; set; }




        private AverageTrueRange atr;
        private HeikenAshi ha;
        private MoneyFlowIndex moneyFlowIndex;
        private string label;

        protected override void OnStart()
        {
            label = "MoneyFlowIndexBot";
            if (IsBacktesting)
                label += " BT";

            atr = Indicators.AverageTrueRange(atrPeriod, MovingAverageType.Exponential);
            ha = Indicators.GetIndicator<HeikenAshi>(1);
            moneyFlowIndex = Indicators.MoneyFlowIndex(moneyFlowIndexPeriods);
        }



        protected override void OnBar()
        {

            foreach (var order in PendingOrders)
            {
                if (order.Label == label && order.SymbolCode == Symbol.Code)
                {
                    CancelPendingOrder(order);
                }
            }


            bool heikenAshiOk = false;
            bool bullishSignal = false;
            bool bearishSignal = false;
            if (ha.Close.Last(1) > ha.Open.Last(1) && ha.Close.Last(2) < ha.Open.Last(2))
            {
                heikenAshiOk = true;
                bullishSignal = true;
            }
            else if (ha.Close.Last(1) < ha.Open.Last(1) && ha.Close.Last(2) > ha.Open.Last(2))
            {
                heikenAshiOk = true;
                bearishSignal = true;

            }


            // Money Flow Index Filter
            bool moneyFlowIndexOk = false;
            if (bullishSignal && moneyFlowIndex.Result.Last(1) > moneyFlowIndexBuy && moneyFlowIndex.Result.Last(2) < moneyFlowIndexBuy)
            {
                moneyFlowIndexOk = true;
            }
            else if (bearishSignal && moneyFlowIndex.Result.Last(1) < moneyFlowIndexSell && moneyFlowIndex.Result.Last(2) > moneyFlowIndexSell)
            {
                moneyFlowIndexOk = true;
            }



            // Time Filter
            bool isTimeCorrect = false;
            if (timeFilter)
                isTimeCorrect = timeFilterCheck();
            else
                isTimeCorrect = true;


            // Placing The stop order
            if (heikenAshiOk && moneyFlowIndexOk && isTimeCorrect)
            {
                // Order Attributes
                double stopLoss = Math.Round((atr.Result.LastValue * Math.Pow(10, Symbol.Digits - 1)) * atrMultiplier, 1);

                long posVolume = PositionVolume(stopLoss);

                if (bullishSignal)
                {
                    PlaceStopOrder(TradeType.Buy, Symbol, posVolume, ha.High.Last(1) + (Symbol.PipSize * orderDistance), label, stopLoss, stopLoss * 2);
                }
                else if (bearishSignal)
                {
                    PlaceStopOrder(TradeType.Sell, Symbol, posVolume, ha.Low.Last(1) - (Symbol.PipSize * orderDistance), label, stopLoss, stopLoss * 2);
                }

            }
        }



        // Position volume calculator
        private long PositionVolume(double stopLossInPips)
        {
            double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100;
            double positionSizeForRisk = Math.Round((Account.Balance * riskPercentage / 100) / (stopLossInPips * costPerPip), 2);

            if (positionSizeForRisk < 0.01)
                positionSizeForRisk = 0.01;
            return Symbol.QuantityToVolume(positionSizeForRisk);

        }


        // Checking the opening time of candle
        private bool timeFilterCheck()
        {
            bool timeOk = false;
            if (timeFilter && MarketSeries.OpenTime.Last(1).Hour >= startHour && MarketSeries.OpenTime.Last(1).Hour <= endHour)
                timeOk = true;
            else if (!timeFilter)
                timeOk = true;

            if (timeOk)
                return true;
            else
                return false;
        }

    }
}
Comments

hove - September 19, 2016 @ 19:08

Cool idea and bot looks solid - def gonna give it a spin.

However - a small bug -  got your excellent HeikinAshi indicator from the equally excellent HA bot here: http://ctdn.com/algos/cbots/show/1266

Your HA indicator from above link exposes "xClose/xOpen/xHigh/xLow" output and the MFI bot references "Close/Open/High/Low" - so some updating needed to compile.

Not a difficult fix, but thought I'd mention it - I'm assuming here of course that you envisioned the MFI bot for use with the HA indicator from the HA bot above?

Thanks,

afhacker - September 19, 2016 @ 23:03

@hove

Yeah you are right.

0