Topics
Replies

alfonsotradingco
24 Sep 2021, 12:24

RE:

amusleh said:

Hi,

Your code syntax is invalid, please post full code of your cBot then we will be able to help you.

Please check the simple moving average API reference examples: cAlgo API Reference - SimpleMovingAverage Interface (ctrader.com)

Hey sorry, here it is

 

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;


/*
 *  POPULAR SIMPLE MOVING AVERAGES
 *
 *  The simple moving average (SMA) is the most basic of the moving averages used for trading. 
 *  The simple moving average formula is calculated by taking the average closing price of a stock over the last "x" periods.
 *  
 *  5 - SMA  - For the hyper trader.  This short of an SMA will constantly give you signals.  The best use of a 5-SMA is as a trade trigger in conjunction with a longer SMA period.
 *  10 - SMA - popular with the short-term traders.  Great swing traders and day traders.
 *  20 - SMA - the last stop on the bus for short-term traders.  Beyond 20-SMA you are basically looking at primary trends.
 *  50 - SMA - use the trader to gauge mid-term trends.
 *  200 -SMA - welcome to the world of long-term trend followers.  Most investors will look for a cross above or below this average to represent if the stock is in a bullish or bearish trend.
 *  
 * Modifications
 * =============
 * 02.12.2017 - Added trailing stop - phayes 
 * 03.12.2017 - Added a Break-even - phayes
 */

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SMAandStoch : Robot
    {
        private double SLsimple;
        #region User defined parameters

        [Parameter("Instance Name", DefaultValue = "001")]
        public string InstanceName { get; set; }

        [Parameter("Lot Size", DefaultValue = 0.1)]
        public double LotSize { get; set; }

        [Parameter("Source SMA ")]
        public DataSeries SourceSma2 { get; set; }

        [Parameter("Slow SMA", DefaultValue = 200, MinValue = 150, MaxValue = 250)]
        public int PeriodsSma2 { get; set; }

        [Parameter("Calculate OnBar", DefaultValue = true)]
        public bool CalculateOnBar { get; set; }

        [Parameter("Include Trailing Stop", DefaultValue = true)]
        public bool IncludeTrailingStop { get; set; }

        [Parameter("Trailing Stop Trigger (pips)", DefaultValue = 20)]
        public int TrailingStopTrigger { get; set; }

        [Parameter("Trailing Stop Step (pips)", DefaultValue = 10)]
        public int TrailingStopStep { get; set; }

        [Parameter("High Stoch Level", DefaultValue = 65)]
        public int highest { get; set; }

        [Parameter("Low Stock Level", DefaultValue = 30)]
        public int lowest { get; set; }

        [Parameter("Stop Loss (pips)", DefaultValue = 100)]
        public int StopLoss { get; set; }

        [Parameter("Take Profit (pips)", DefaultValue = 100)]
        public int TakeProfit { get; set; }

        [Parameter("Trigger (pips)", DefaultValue = 10)]
        public int Trigger { get; set; }

        [Parameter("MinBalance", DefaultValue = 500)]
        public double MinBalance { get; set; }

        [Parameter("Take Profit Simple", DefaultValue = 100)]
        public double TPSimple { get; set; }

        [Parameter("Stop Loss Simple", DefaultValue = -10)]
        public double SLSimple { get; set; }

        [Parameter("K Periods", DefaultValue = 200)]
        public int kPeriods { get; set; }

        [Parameter("K Slowing", DefaultValue = 3)]
        public int kSlowing { get; set; }

        [Parameter("D Periods", DefaultValue = 3)]
        public int dPeriods { get; set; }

        [Parameter("MA Type", DefaultValue = MovingAverageType.Triangular)]
        public MovingAverageType maType { get; set; }

        [Parameter("Look Back Period ", DefaultValue = 100)]
        public int lookback { get; set; }

        [Parameter("Use Bullish Engulfing ?  ", DefaultValue = true)]
        public bool useBU { get; set; }

        [Parameter("Use Bearish Engulfing ?  ", DefaultValue = true)]
        public bool useBE { get; set; }

        #endregion

        #region Indicator declarations

        private SimpleMovingAverage _sma2 { get; set; }

        private StochasticOscillator stoch { get; set; }






        #endregion

        #region cTrader events

        /// <summary>
        /// This is called when the robot first starts, it is only called once.
        /// </summary>
        protected override void OnStart()
        {
            // construct the indicators

            _sma2 = Indicators.SimpleMovingAverage(SourceSma2, PeriodsSma2);
            stoch = Indicators.StochasticOscillator(kPeriods, kSlowing, dPeriods, maType);


        }

        /// <summary>
        /// This method is called every time the price changes for the symbol
        /// </summary>
        protected override void OnTick()
        {
            var close4 = MarketSeries.Close.Last(1);

            if (CalculateOnBar)
            {
                return;
            }

            ManagePositions();

            if (IncludeTrailingStop)
            {
                SetTrailingStop();
            }

            CloseTP();


            var positionTP = Positions.Find(InstanceName, Symbol, TradeType.Buy);
            if (positionTP != null && positionTP.GrossProfit > TPSimple)
            {
                ClosePosition(positionTP);

            }
            var positionSL = Positions.Find(InstanceName, Symbol, TradeType.Buy);
            if (positionSL != null && positionTP.GrossProfit < SLSimple)
            {
                ClosePosition(positionTP);

            }
        }
            /*
            var positionSL = Positions.Find(InstanceName, Symbol, TradeType.Buy);
            var stopLoss = positionSL.EntryPrice - SLSimple * Symbol.PipSize;
            if (positionSL != null && StopLoss < close4)
            {
                Print("Position SL price is {0}", positionSL.StopLoss);
                ClosePosition(positionSL);

            }
            */




        /// <summary>
        /// This method is called at every candle (bar) close, when it has formed
        /// </summary>
                protected override void OnBar()
        {


            var smavalue = _sma2.Result.Last(1);

            var close1 = MarketSeries.Close.Last(1);
            var close2 = MarketSeries.Close.Last(2);
            var close3 = MarketSeries.Close.Last(3);


            if (!CalculateOnBar)
            {
                return;
            }

            Print("Last Candle close price was: {0}, SMA Slow value was: {1}", close1, smavalue);

            ManagePositions();
        }

        /// <summary>
        /// This method is called when your robot stops, can be used to clean-up memory resources.
        /// </summary>
        protected override void OnStop()
        {
            // unused
        }

        #endregion

        #region Position management





        private void ManagePositions()
        {

            if (stoch.PercentK.LastValue < lowest)
            {
                if (close1 > smavalue)
                {

                    {
                        EngulfBear();

                    }
                }
            }


            /// This is all the close conditions


            if (stoch.PercentK.LastValue >= highest)
            {
                ClosePosition(TradeType.Buy);
            }

            foreach (var position in Positions.FindAll(InstanceName, Symbol))
            {
                if (position.GrossProfit > TPSimple)

                    ClosePosition(position);
            }


        }






        /// <summary>
        /// Opens a new long position
        /// </summary>
        /// <param name="type"></param>
        private void OpenPosition(TradeType type)
        {
            // calculate volume from lot size.
            long volume = Symbol.QuantityToVolume(LotSize);

            // open a new position
            ExecuteMarketOrder(type, this.Symbol, volume, InstanceName, null, null);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        private void ClosePosition(TradeType type)
        {
            var p = Positions.Find(InstanceName, this.Symbol, type);

            if (p != null)
            {
                ClosePosition(p);
            }
        }

        #endregion

        #region Candle Patterns

        private void EngulfBear()
        {
            if (!useBE)
                return;

            for (var i = 1; i <= lookback; i++)
            {
                var c = MarketSeries.Close.Last(i);
                var o = MarketSeries.Open.Last(i);
                var h = MarketSeries.High.Last(i);
                var l = MarketSeries.Low.Last(i);



                var ct = MarketSeries.Close.Last(i + 1);
                var ot = MarketSeries.Open.Last(i + 1);
                var ht = MarketSeries.High.Last(i + 1);
                var lt = MarketSeries.Low.Last(i + 1);



                if (ct < ot || c > o)
                    continue;



                if (c < ot)
                {

                    // if there is no buy position open, open one and close any sell position that is open
                    if (!IsPositionOpenByType(TradeType.Buy))
                    {
                        OpenPosition(TradeType.Buy);
                    }

                    ClosePosition(TradeType.Sell);

                }
            }
        }
        #endregion


        #region Position Information

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private bool IsPositionOpenByType(TradeType type)
        {
            var p = Positions.FindAll(InstanceName, Symbol, type);

            if (p.Count() >= 1)
            {
                return true;
            }

            return false;
        }

        #endregion

        #region Trailing Stop

        /// <summary>
        /// When the profit in pips is above or equal to Trigger the stop loss will start trailing the spot price.
        /// TrailingStop defines the number of pips the Stop Loss trails the spot price by. 
        /// If Trigger is 0 trailing will begin immediately. 
        /// </summary>
        private void SetTrailingStop()
        {
            var sellPositions = Positions.FindAll(InstanceName, Symbol, TradeType.Sell);

            foreach (Position position in sellPositions)
            {
                double distance = position.EntryPrice - Symbol.Ask;

                if (distance < TrailingStopTrigger * Symbol.PipSize)
                    continue;

                double newStopLossPrice = Symbol.Ask + TrailingStopStep * Symbol.PipSize;

                if (position.StopLoss == null || newStopLossPrice < position.StopLoss)
                {
                    ModifyPosition(position, newStopLossPrice, position.TakeProfit);
                }
            }

            var buyPositions = Positions.FindAll(InstanceName, Symbol, TradeType.Buy);

            foreach (Position position in buyPositions)
            {
                double distance = Symbol.Bid - position.EntryPrice;

                if (distance < TrailingStopTrigger * Symbol.PipSize)
                    continue;

                double newStopLossPrice = Symbol.Bid - TrailingStopStep * Symbol.PipSize;
                if (position.StopLoss == null || newStopLossPrice > position.StopLoss)
                {
                    ModifyPosition(position, newStopLossPrice, position.TakeProfit);
                }
            }
        }

        #endregion


        #region Stops and Take Profits (I.L)

        private void CloseTP()
        {

            foreach (var position in Positions.FindAll(InstanceName, Symbol))
            {
                if (position.GrossProfit > TPSimple)

                    ClosePosition(position);
            }
            return;
        }

        private void CloseSL()
        {

            foreach (var position in Positions.FindAll(InstanceName, Symbol))
            {
                if (position.GrossProfit * -1 < SLsimple)

                    ClosePosition(position);
            }
            return;
        }
        #endregion


    }
}


@alfonsotradingco