SmartTradeLimitOrder free

by atrwcsm in category Other at 20/06/2021
Description

DISCLAIMER:
This cBot is intended to be used for educational purposes only and does not guarantee any particular outcome or profit of any kind.
Use it at your own risk.

About SmartTradeLimitOrder:

SmartTradeLimitOrder is a cBot that places Buy and Sell Limit Orders, Default Setting is Buy Limit Order !!!
SmartTradeLimitOrder will not tell the Trader when to trade and in which direction to trade.
SmartTradeLimitOrder will help and support the Trader to focus more on his strategy and decide when to trade and in which direction to trade
SmartTradeLimitOrder will do the boring work/calculation related to Position Sizing and Risk Management with the Volatility in mind.

This cBot has been developed with the Consistency, Volatility and Risk Management in focus.
To achieve this, a Virtual Balance has been introduced to allow the Trader to allocate the same amount of money
he wants to risk for each trade (e.g. 50 USD) regardless of the Account Equity or Balance as they are always changing.
The Virtual Balance can be configured as input parameter.
Max Risk per Trade can be configured as input parameter.
StopLoss and TakeProfit in Pips are calculated based on the ATR Multipliers (e.g. 0.5xATR, 1x ATR, 2xATR …) defined by the Trader.
Position Sizing is calculated based on StopLoss in Pips and the Max Risk per Trade allocated for each trade.
Target price is calculated using the distance defined as percentage of the ATR, default setting is 0.2xATR.
StopLimitRangePips can be defined as percentage of ATR, default settting is 0.1xATR
Trading Start and Stop Times can be configured as input parameters.
The cBot only works between Start Time and Stop Time.
At Stop Time the cBot will close all Positions executed with the same Shared Comment.
At Stop Time the cBot will cancel all PendingOrders placed with the same Shared Comment.

Happy Trading
atrwcsm

 

Default Setting:

 

ATRWCSM Forex Trading Signal - Live Stream

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
//
//  DISCLAIMER:
//  This cBot is intended to be used for educational purposes only and does not guarantee any particular outcome or profit of any kind.
//  Use it at your own risk.
//
//  About SmartTradeLimitOrder:
//
//  SmartTradeLimitOrder is a cBot that places Buy and Sell Limit Orders, Default Setting is Buy Limit Order !!!
//  SmartTradeLimitOrder will not tell the Trader when to trade and in which direction to trade.
//  SmartTradeLimitOrder will help and support the Trader to focus more on his strategy and decide when to trade and in which direction to trade
//  SmartTradeLimitOrder will do the boring work/calculation related to Position Sizing and Risk Management with the Volatility in mind.
//
//  This cBot has been developed with the Consistency, Volatility and Risk Management in focus.
//  To achieve this, a Virtual Balance has been introduced to allow the Trader to allocate the same amount of money
//  he wants to risk for each trade (e.g. 50 USD) regardless of the Account Equity or Balance as they are always changing.
//  The Virtual Balance can be configured as input parameter.
//  Max Risk per Trade can be configured as input parameter.
//  StopLoss and TakeProfit in Pips are calculated based on the ATR Multipliers (e.g. 0.5xATR, 1x ATR, 2xATR …) defined by the Trader.
//  Position Sizing is calculated based on StopLoss in Pips and the Max Risk per Trade allocated for each trade.
//  Target price is calculated using the distance defined as percentage of the ATR, default setting is 0.2xATR.
//  StopLimitRangePips can be defined as percentage of ATR, default settting is 0.1xATR
//  Trading Start and Stop Times can be configured as input parameters.
//  The cBot only works between Start Time and Stop Time.
//  At Stop Time the cBot will close all Positions executed with the same Shared Comment.
//  At Stop Time the cBot will cancel all PendingOrders placed with the same Shared Comment.
//
//  Happy Trading
//  atrwcsm
//
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//    
//  cBot Name:  SmartTradeLimitOrder
//  FX Pairs:   FX Majors, Minors and Crosses
//  Author:     atrwcsm
//  Version:    2021.06
//
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////





using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using System.Collections;
using System.Windows.Forms;
using System.Collections.Generic;


namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class SmartTradeStopOrder : Robot
    {
        [Parameter("Trade Direction ?", DefaultValue = TradeType.Buy)]
        public TradeType tradeDirection { get; set; }

        [Parameter("Start Time in UTC", DefaultValue = "00:00")]
        public string StartTime { get; set; }
        [Parameter("Stop Time in UTC", DefaultValue = "17:00")]
        public string StopTime { get; set; }

        [Parameter("Virtual Balance", DefaultValue = 5000)]
        public double VirtualBalance { get; set; }
        [Parameter("Max Risk per Trade in %", DefaultValue = 1)]
        public double MaxRiskPerTrade { get; set; }
        // If VirtualBalance = 5000 USD and MaxRiskPerTrade = 1
        // the expected Risk per Trade will be 50 USD

        [Parameter("Stoploss ATR Multiplier", DefaultValue = 1)]
        public double SL_ATR_Multiplier { get; set; }
        [Parameter("Takeprofit ATR Multiplier", DefaultValue = 2)]
        public double TP_ATR_Multiplier { get; set; }
        [Parameter("Distance in ATR %", DefaultValue = 0.2)]
        public double DistancePercent { get; set; }
        [Parameter("Limit Range in ATR %", DefaultValue = 0.1)]
        public double LimitRangePercent { get; set; }



        [Parameter("Show Balance Warning ?", DefaultValue = true)]
        public bool ShowBalanceWarning { get; set; }
        [Parameter("Position Label", DefaultValue = "Position Nr.1")]
        public string Label { get; set; }

        [Parameter("Shared Comment", DefaultValue = "Shared Comment")]
        public string SharedComment { get; set; }

        private MovingAverageType MAType = MovingAverageType.Simple;
        private TimeSpan TradingStartTimeSpan, TradingStopTimeSpan;

        private string cBotVersion = "2021.06";

        private int Periods = 14;
        private int totalDays = 0;

        private double CurrentAtrPips;
        private double StopLoss;
        private double TakeProfit;
        private double MaxSpread;
        private double CurrentEquity;



        //  OnStart()   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        protected override void OnStart()
        {
            Timer.Start(1);
            totalDays = Server.Time.DayOfYear;
            CurrentEquity = Account.Equity;
            Positions.Opened += OnPositionsOpened;
            Positions.Closed += OnPositionsClosed;

            Print(".");
            Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> SmartTradeLimitOrder Version: {0}", cBotVersion);

            if (ShowBalanceWarning)
                if (CurrentEquity < VirtualBalance)
                    WarningMessageBox();

            // Don't trade on Sundays
            if (Server.Time.DayOfWeek == DayOfWeek.Sunday)
            {
                Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> (STOP) - Don't trade on Sundays ...");
                Stop();
            }

            //  Only trade in planned Trading Hours.
            if (!IsTradingHours())
            {
                Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> (STOP) - Don't trade outside Trading Hours ...");
                Stop();
            }


            double currentAtrPips1 = Indicators.AverageTrueRange(MarketData.GetBars(TimeFrame.Daily, Symbol.Name), Periods, MAType).Result.Last(1);
            double currentAtrPips2 = Indicators.AverageTrueRange(MarketData.GetBars(TimeFrame.Daily, Symbol.Name), Periods, MAType).Result.Last(2);
            double currentAtrPips3 = Indicators.AverageTrueRange(MarketData.GetBars(TimeFrame.Daily, Symbol.Name), Periods, MAType).Result.Last(3);
            double currentAtrPips = (currentAtrPips1 + currentAtrPips2 + currentAtrPips3) / 3;

            CurrentAtrPips = Math.Round(currentAtrPips / Symbol.PipSize, 0);
            StopLoss = Math.Round(SL_ATR_Multiplier * CurrentAtrPips, 0);
            TakeProfit = Math.Round(TP_ATR_Multiplier * CurrentAtrPips, 0);

            // If CurrentAtrPips = 100 Pips for example the MaxSpred will be 10 Pips
            MaxSpread = Math.Round(0.1 * CurrentAtrPips, 1);

            Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> Current ATR for {0} is : {1} Pips", Symbol.Name, CurrentAtrPips);


            //  Place Limit Order   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            double Spread = Math.Round(Symbol.Spread / Symbol.PipSize, 1);
            if (Spread >= MaxSpread)
            {
                Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> Current Spread is {0} Pips", Spread);
                Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> (STOP) - The Spread is too high ...");
                Stop();
            }

            double Volume = GetVolume(StopLoss, MaxRiskPerTrade);
            double PipsAway = Math.Round(DistancePercent * CurrentAtrPips, 1);
            double RangePips = Math.Round(LimitRangePercent * CurrentAtrPips, 1);

            Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> MaxSpread for {0} is {1} Pips", Symbol.Name, MaxSpread);
            Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> Current Spread for {0} is {1} Pips", Symbol.Name, Spread);

            Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> The calculated Volume for {0} Order is {1}", Symbol.Name, Volume);
            Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> Order Distance : {0} Pips", PipsAway);
            Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> Limit Range : {0} Pips", RangePips);

            Print(".");

            if (tradeDirection == TradeType.Sell)
            {
                if (Positions.Find(Symbol.Name, Label) == null)
                    if (PendingOrders.Count(order => order.Label == Label && order.TradeType == TradeType.Sell) == 0)
                    {
                        double TargetPrice = Math.Round(Symbol.Bid + PipsAway * Symbol.PipSize, Symbol.Digits);

                        Print(".");
                        var result = PlaceStopLimitOrder(TradeType.Sell, Symbol.Name, GetVolume(StopLoss, MaxRiskPerTrade), TargetPrice, RangePips, Label, StopLoss, TakeProfit, null, SharedComment);

                        if (!result.IsSuccessful)
                        {
                            Print(".");
                            Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> {0} {1} Order Execution not successful, Error: {2} ", Symbol.Name, tradeDirection, result.Error);
                            Stop();
                        }
                    }
            }
            else
            {
                if (Positions.Find(Symbol.Name, Label) == null)
                    if (PendingOrders.Count(order => order.Label == Label && order.TradeType == TradeType.Buy) == 0)
                    {
                        double TargetPrice = Math.Round(Symbol.Bid - PipsAway * Symbol.PipSize, Symbol.Digits);

                        Print(".");
                        var result = PlaceStopLimitOrder(TradeType.Buy, Symbol.Name, GetVolume(StopLoss, MaxRiskPerTrade), TargetPrice, RangePips, Label, StopLoss, TakeProfit, null, SharedComment);

                        if (!result.IsSuccessful)
                        {
                            Print(".");
                            Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> {0} {1} Order Execution not successful, Error: {2} ", Symbol.Name, tradeDirection, result.Error);
                            Stop();
                        }
                    }
            }
            //  Place Limit Order   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


        }
        //  OnStart()   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



        // OnStop()     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
        // OnStop()     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



        //  OnTimer()   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        protected override void OnTimer()
        {
            // End of Trading Session     //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            if (Server.Time.TimeOfDay >= TradingStopTimeSpan)
                if (Positions.Count(position => position.Comment == SharedComment) != 0 || PendingOrders.Count(order => order.Comment == SharedComment) != 0)
                {
                    foreach (var position in Positions)
                        if (position != null && position.SymbolName == Symbol.Name && position.Comment == SharedComment)
                        {
                            var result = ClosePosition(position);

                            if (!result.IsSuccessful)
                            {
                                Print(">>>>>>>>>>>> OnTimer(" + totalDays + ") >>>> Closing {0} {1} Position result.NotSuccessful ??? ...", position.Label, position.TradeType);
                                Print(">>>>>>>>>>>> OnTimer(" + totalDays + ") >>>> Closing {0} {1} Position Error.Code: {2}", position.Label, position.TradeType, result.Error);
                            }

                            Print(".");
                            Print(">>>>>>>>>>>> OnTimer(" + totalDays + ") >>>>>>>>>>>> End of Trading Session, {0} {1} Position closed  ...", position.SymbolName, position.TradeType);
                        }

                    foreach (var order in PendingOrders)
                        if (order != null && order.SymbolName == Symbol.Name && order.Comment == SharedComment)
                        {
                            var result = CancelPendingOrder(order);

                            if (!result.IsSuccessful)
                            {
                                Print(">>>>>>>>>>>> OnTimer(" + totalDays + ") >>>> Cancelling {0} {1} Order result.NotSuccessful ??? ...", order.Label, order.TradeType);
                                Print(">>>>>>>>>>>> OnTimer(" + totalDays + ") >>>> Cancelling {0} {1} Order Error.Code: {2}", order.Label, order.TradeType, result.Error);
                            }

                            Print(".");
                            Print(">>>>>>>>>>>> OnTimer(" + totalDays + ") >>>>>>>>>>>> End of Trading Session, {0} {1} Order canceled ...", order.SymbolName, order.TradeType);
                        }
                }
            // End of Trading Session     //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        }
        // OnTimer()        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



        // OnTick()        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        protected override void OnTick()
        {
            // Put your core logic here
        }
        // OnTick()        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



        // OnPositionsOpened()        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        private void OnPositionsOpened(PositionOpenedEventArgs args)
        {
            var position = args.Position;

            if (position.SymbolName == Symbol.Name && position.Label == Label)
            {
                Print(".");
                Print(">>>>>>>>>>>> OnPositionsOpened(" + totalDays + ") >>>>>>>>>>>> {0} {1} Postion created successfully,  EntryPrice = {2}", position.SymbolName, position.TradeType, position.EntryPrice);
            }
        }
        // OnPositionsOpened()        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



        // OnPositionsClosed()  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            var position = args.Position;

            if (position.SymbolName == Symbol.Name && position.Label == Label)
            {
                Print(".");
                Print(">>>>>>>>>>>> OnPositionsOpened(" + totalDays + ") >>>>>>>>>>>> {0} {1} Postion closed successfully,  NetProfit = {2}", position.SymbolName, position.TradeType, position.NetProfit);
            }
        }
        // OnPositionsClosed()  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



        // GetVolume()          ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        private double GetVolume(double stopLoss, double maxRiskPerTrade)
        {
            var moneyToTradeInDepositCurrency = maxRiskPerTrade * VirtualBalance / 100;
            var moneyToTradeInQuoteCurrency = moneyToTradeInDepositCurrency / (Symbol.PipValue / Symbol.PipSize);
            var volume = moneyToTradeInQuoteCurrency / (Symbol.PipSize * stopLoss);
            var normalizedVolume = Symbol.NormalizeVolumeInUnits(volume, RoundingMode.ToNearest);
            return normalizedVolume;
        }
        // GetVolume()          //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



        // IsTradingHours()  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        private bool IsTradingHours()
        {
            // get current time
            DateTime tradingTime = Server.Time;
            bool isTradingHours = false;

            try
            {
                TradingStartTimeSpan = TimeSpan.ParseExact(StartTime, "hh\\:mm", null);
                TradingStopTimeSpan = TimeSpan.ParseExact(StopTime, "hh\\:mm", null);

                if (tradingTime.TimeOfDay > TradingStartTimeSpan && tradingTime.TimeOfDay < TradingStopTimeSpan)
                    isTradingHours = true;

            } catch (Exception exception)
            {
                Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> Invalid StarTime or StopTime entered, they must be in the fromat hh:mm , " + exception.Message.ToString());
                Stop();
            }

            return isTradingHours;
        }
        // IsTradingHours()  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



        // WarningMessageBox()          /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        private void WarningMessageBox()
        {
            string Message = "The Virtual Balance is higher than the Account Equity !\nPlease click YES if you want to continue or NO to stop the cBot";
            var result = MessageBox.Show(Message, "WARNING", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

            if (result == DialogResult.No)
            {
                Print(">>>>>>>>>>>> OnStart(" + totalDays + ") >>>>>>>>>>>> Stopping the cBot ...");
                Stop();
            }
        }
        // WarningMessageBox()          ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



    }
}
Comments
0