Risk based lot sizes

Created at 16 Jan 2014, 17:19
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
GD

GDPR-24_141216

Joined 16.01.2014 Blocked

Risk based lot sizes
16 Jan 2014, 17:19


Currently I use MT4 and I'm looking to move to cTrader.

However within MT4 I use a cutsom script that places trades based on stated risk and where I've moved my SL line to on the chart (and limit/stop order if relevant) i.e it places trades at a lot size dependant on my stated risk and SL size.

Is there a way to create the equivalent of the MT4 script (Easy Order) in cTrader if I was to contact a programmer to do this for me?

 

 


Replies

Spotware
17 Jan 2014, 11:30

Yes, a cBot may be coded to create trades based on input such as risk and existing positions stop loss and then stop. 


@Spotware

cvphuoc
17 Jan 2014, 14:21

RE:

Spotware said:

Yes, a cBot may be coded to create trades based on input such as risk and existing positions stop loss and then stop. 

Yes, i definitely need this for my trading on Ctrader. Position Sizing is my most important thing and i miss this function when switching from MT4 to Ctrader. Hope anybody kindly help us in this regard.

 


@cvphuoc

GDPR-24_141216
18 Jan 2014, 17:51

RE:

Spotware said:

Yes, a cBot may be coded to create trades based on input such as risk and existing positions stop loss and then stop. 

Thanks, I would happy to pay someone to code a cBot that can replicate the functions available in the MT4 script detailed in the link below.

 

http://www.forexfactory.com/showthread.php?t=281772

 

Otherwise cTrader is a no go for me.

 


daemon
21 Jan 2014, 10:31

Do you want the lot calculation or the whole system because with cTrader you can modify the sl/tp by dragging the lines with out scripts. I think I can make a robot to place trades based on that and then you can use cTrader to drag the sl/tp lines or price for pending orders. Let me know if there is something I missed.

Quote from forexfactory:

I made this simple tool to give me the ability to specify sl/tp for new order by using mouse (dragging line object). Input sl/tp manually is a boring task, especially for lazy trader.
It also monitor existing trade sl/tp, which means it will modify existing sl/tp and open price (for pending order) when it detected a different value between order's sl/tp and the corresponding sl/tp line object.
Other feature : 
- lot size calculated automatically based on the specified risk.
- a simple popup menu that allows you to quickly close an order based on ticket number
Unlike most line object based trading tools, this program doesn't use EA for monitoring lines object every tick, or a script which uses continuous looping with certain delay. It detects mouse dragging activities (hence why it uses dll) and fire the necessary script. All script will return once its job (opening new order / modifying existing orders) finished.


@daemon

GDPR-24_141216
21 Jan 2014, 10:52

RE:

daemon said:

Do you want the lot calculation or the whole system because with cTrader you can modify the sl/tp by dragging the lines with out scripts. I think I can make a robot to place trades based on that and then you can use cTrader to drag the sl/tp lines or price for pending orders. Let me know if there is something I missed.

Quote from forexfactory:

I made this simple tool to give me the ability to specify sl/tp for new order by using mouse (dragging line object). Input sl/tp manually is a boring task, especially for lazy trader.
It also monitor existing trade sl/tp, which means it will modify existing sl/tp and open price (for pending order) when it detected a different value between order's sl/tp and the corresponding sl/tp line object.
Other feature : 
- lot size calculated automatically based on the specified risk.
- a simple popup menu that allows you to quickly close an order based on ticket number
Unlike most line object based trading tools, this program doesn't use EA for monitoring lines object every tick, or a script which uses continuous looping with certain delay. It detects mouse dragging activities (hence why it uses dll) and fire the necessary script. All script will return once its job (opening new order / modifying existing orders) finished.

The lot calculation based on SL/TP via draggable lines.

MT4 also introduced draggable SL/TP once a trade is in play after this script was created, so like cTrader no need to monitor, it's purely for opening a position i.e.  I'd need draggable lines on the chart to start with to specify the SL/TP through and then it's case of using the script to open a market order or limit order based on the stated %risk and SL/TP size.

I have a slightly modified version of the original as the original only worked with USD denominated accounts.

Many thanks for your help.

 

 


daemon
21 Jan 2014, 12:51

Maybe I'm missing something in the usage or perhaps I don't have the right files. I don't get how the lot size is calculated from the dragable lines. Only the SL and TP are modified if I drag the lines.


@daemon

GDPR-24_141216
21 Jan 2014, 13:12

RE:

daemon said:

Maybe I'm missing something in the usage or perhaps I don't have the right files. I don't get how the lot size is calculated from the dragable lines. Only the SL and TP are modified if I drag the lines.

This short video should help.

http://screencast.com/t/9I0jlzzleF

1. Drag the EasyOrder script onto the chart.

2. Decide on order type, in this case a Buy Limit - EasyOrder then places 3 lines on the chart, a price line, a SL line and a TP line. 

3. You drag the lines to where you want and click submit - EasyOrder then places a Buy Limit at the lot size that is calculated based on the distance between the price line and the SL line and based on the stated risk %.

4. The same is shown for a market order, except this time you of course don't have the price line.

Long after this script was first made, MT4 introduced draggalbe SL and TP lines (once a trade is in play), hence this Easy Order version has been amended to remove it's own SL/TP object lines once the trade is placed (to avoid double lines from EasyOrder and MT4) - so the SL/TP lines you see once the order is placed are MT4 lines (much like cTrader has the same SL/TP lines).

So what I would like is the ability to place trades on the chart through a similar method, a small GUI to state the risk, choose order type and to submit the order request and draggable SL/TP/Price lines.

 

 


daemon
21 Jan 2014, 14:02

It seems I have the wrong files because I cannot move the lines prior to submit. But anyway, I don't think I can code it. I can just calculate the lot based on risk and SL/TP input.


@daemon

GDPR-24_141216
21 Jan 2014, 18:35

RE:

daemon said:

It seems I have the wrong files because I cannot move the lines prior to submit. But anyway, I don't think I can code it. I can just calculate the lot based on risk and SL/TP input.

Ok, thanks for looking into it in anycase.

 

 


atrader
28 Jan 2014, 18:02

using System;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot]
    public class OnePercentRiskBot : Robot
    {
        private Rates _rate = Rates.Direct;

        [Parameter(DefaultValue = "Volume on Risk")]
        public string MyLabel { get; set; }

        [Parameter("0:Buy 1:Sell", DefaultValue = 0)]
        public int TType { get; set; }

        [Parameter("Stop Loss", DefaultValue = 10, MinValue = 0, MaxValue = 500)]
        public int StopLoss { get; set; }

        [Parameter("Take Profit", DefaultValue = 10, MinValue = 0, MaxValue = 500)]
        public int TakeProfit { get; set; }

        // Modify DefaultValue, MinValue, MaxValue
        [Parameter("Risk Percentage", DefaultValue = 1, MinValue = 0.01, MaxValue = 5)]
        public double RiskPercent { get; set; }


        protected TradeType Trade_Type
        {
            get
            {
                return
                    TType == 0 ? TradeType.Buy : TradeType.Sell;
            }
        }

        protected override void OnStart()
        {
            Positions.Opened += PositionsOnOpened;
            // Initialize _rate variable
            SetRate();
            int volume = GetVolume();
            Print("Volume = {0}", volume);
            ExecuteMarketOrder(Trade_Type, Symbol, volume, MyLabel);
        }

        private void PositionsOnOpened(PositionOpenedEventArgs args)
        {
            double risk = 0;
            foreach (Position position in Positions)
            {
                Symbol symbol = MarketData.GetSymbol(position.SymbolCode);
                if (position.StopLoss != null)
                {
                    double stopLoss = Math.Abs(position.EntryPrice - (double) position.StopLoss)/symbol.PipSize;
                    risk += stopLoss*symbol.PipValue*position.Volume - position.Commissions*2;
                }
            }
            Print(risk);
        }

        private int GetVolume()
        {
            double risk = RiskPercent/100.0;
            double volume;

            switch (_rate)
            {
                case Rates.Direct:
                    volume = Account.Equity*risk/(StopLoss*Symbol.PipValue);
                    break;
                case Rates.Indirect:
                    double stopLossPrice = Trade_Type == TradeType.Buy
                                               ? Symbol.Ask + StopLoss*Symbol.PipSize
                                               : Symbol.Bid - StopLoss*Symbol.PipSize;
                    volume = Account.Equity*risk*stopLossPrice/(StopLoss*Symbol.PipValue);
                    break;
                default: // pending
                    volume = 0;
                    break;
            }

            return (int) Symbol.NormalizeVolume(volume);
        }

        private void SetRate()
        {
            switch (Symbol.Code)
            {
                case "EURUSD":
                case "GBPUSD":
                case "AUDUSD":
                case "NZDUSD":
                    _rate = Rates.Direct;
                    break;
                case "USDJPY":
                case "USDCHF":
                case "USDCAD":
                    _rate = Rates.Indirect;
                    break;
                default:
                    _rate = Rates.Cross;
                    break;
            }
        }

        #region Nested type: Rates

        private enum Rates
        {
            Direct,
            Indirect,
            Cross
        };

        #endregion
    }
}

Maybe this is a start...


@atrader

cvphuoc
29 Jan 2014, 04:53

RE:

atrader said:

using System;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot]
    public class OnePercentRiskBot : Robot
    {
        private Rates _rate = Rates.Direct;

        [Parameter(DefaultValue = "Volume on Risk")]
        public string MyLabel { get; set; }

        [Parameter("0:Buy 1:Sell", DefaultValue = 0)]
        public int TType { get; set; }

        [Parameter("Stop Loss", DefaultValue = 10, MinValue = 0, MaxValue = 500)]
        public int StopLoss { get; set; }

        [Parameter("Take Profit", DefaultValue = 10, MinValue = 0, MaxValue = 500)]
        public int TakeProfit { get; set; }

        // Modify DefaultValue, MinValue, MaxValue
        [Parameter("Risk Percentage", DefaultValue = 1, MinValue = 0.01, MaxValue = 5)]
        public double RiskPercent { get; set; }


        protected TradeType Trade_Type
        {
            get
            {
                return
                    TType == 0 ? TradeType.Buy : TradeType.Sell;
            }
        }

        protected override void OnStart()
        {
            Positions.Opened += PositionsOnOpened;
            // Initialize _rate variable
            SetRate();
            int volume = GetVolume();
            Print("Volume = {0}", volume);
            ExecuteMarketOrder(Trade_Type, Symbol, volume, MyLabel);
        }

        private void PositionsOnOpened(PositionOpenedEventArgs args)
        {
            double risk = 0;
            foreach (Position position in Positions)
            {
                Symbol symbol = MarketData.GetSymbol(position.SymbolCode);
                if (position.StopLoss != null)
                {
                    double stopLoss = Math.Abs(position.EntryPrice - (double) position.StopLoss)/symbol.PipSize;
                    risk += stopLoss*symbol.PipValue*position.Volume - position.Commissions*2;
                }
            }
            Print(risk);
        }

        private int GetVolume()
        {
            double risk = RiskPercent/100.0;
            double volume;

            switch (_rate)
            {
                case Rates.Direct:
                    volume = Account.Equity*risk/(StopLoss*Symbol.PipValue);
                    break;
                case Rates.Indirect:
                    double stopLossPrice = Trade_Type == TradeType.Buy
                                               ? Symbol.Ask + StopLoss*Symbol.PipSize
                                               : Symbol.Bid - StopLoss*Symbol.PipSize;
                    volume = Account.Equity*risk*stopLossPrice/(StopLoss*Symbol.PipValue);
                    break;
                default: // pending
                    volume = 0;
                    break;
            }

            return (int) Symbol.NormalizeVolume(volume);
        }

        private void SetRate()
        {
            switch (Symbol.Code)
            {
                case "EURUSD":
                case "GBPUSD":
                case "AUDUSD":
                case "NZDUSD":
                    _rate = Rates.Direct;
                    break;
                case "USDJPY":
                case "USDCHF":
                case "USDCAD":
                    _rate = Rates.Indirect;
                    break;
                default:
                    _rate = Rates.Cross;
                    break;
            }
        }

        #region Nested type: Rates

        private enum Rates
        {
            Direct,
            Indirect,
            Cross
        };

        #endregion
    }
}

Maybe this is a start...

This would be nice if Gold (XAUUSD) is added up as well.


@cvphuoc

fxMinnow
29 Jan 2014, 14:48

hi,

good info.


@fxMinnow

soso
11 Mar 2014, 10:04

Hi,

 

Is there any news about a tool like this? I think is something really needed.


@soso

ForexGump
19 Apr 2015, 14:58

atrader: your cbot is pretty good. Do you have something similar that places pending orders instead of market orders? Would place a pending stop order at the next round 5 pip level. Would actually need two cbots: one for pending buy stop and another one for pending sell stop


@ForexGump

Chistabo
02 May 2015, 14:25

RE:

ForexGump said:

atrader: your cbot is pretty good. Do you have something similar that places pending orders instead of market orders? Would place a pending stop order at the next round 5 pip level. Would actually need two cbots: one for pending buy stop and another one for pending sell stop

No need for two cBots, all you need is add another external parameter, i.e. [Parameter("0:Instant 1:Pending", DefaultValue = 0)] public int OrderType { get; set; }, and then add some logic into the code.

 

Until cTrader / cAlgo implements a method to Find/Get properties of the ChartObjects, the cBot as per original post (with horizontal line movements) is not easy to do; I guess one needs to have own methods to Find/Get ChartObjects properties.

 

Best regards,

Simon

S love nia


@Chistabo

mgalona74
24 Sep 2015, 08:16

RE: RE:

Chistabo said:

ForexGump said:

atrader: your cbot is pretty good. Do you have something similar that places pending orders instead of market orders? Would place a pending stop order at the next round 5 pip level. Would actually need two cbots: one for pending buy stop and another one for pending sell stop

No need for two cBots, all you need is add another external parameter, i.e. [Parameter("0:Instant 1:Pending", DefaultValue = 0)] public int OrderType { get; set; }, and then add some logic into the code.

 

Until cTrader / cAlgo implements a method to Find/Get properties of the ChartObjects, the cBot as per original post (with horizontal line movements) is not easy to do; I guess one needs to have own methods to Find/Get ChartObjects properties.

 

Best regards,

Simon

S love nia

 

Wow this bot is good this is something I need. Only needs now is a visible horizontal line for placing stop loss before it gets executed. And a pending order for but stop sell stop too. Please can someone add this to the bot? I really don't know how to code....

 


@mgalona74

mgalona74
24 Sep 2015, 08:19

RE:

atrader said:

using System;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot]
    public class OnePercentRiskBot : Robot
    {
        private Rates _rate = Rates.Direct;

        [Parameter(DefaultValue = "Volume on Risk")]
        public string MyLabel { get; set; }

        [Parameter("0:Buy 1:Sell", DefaultValue = 0)]
        public int TType { get; set; }

        [Parameter("Stop Loss", DefaultValue = 10, MinValue = 0, MaxValue = 500)]
        public int StopLoss { get; set; }

        [Parameter("Take Profit", DefaultValue = 10, MinValue = 0, MaxValue = 500)]
        public int TakeProfit { get; set; }

        // Modify DefaultValue, MinValue, MaxValue
        [Parameter("Risk Percentage", DefaultValue = 1, MinValue = 0.01, MaxValue = 5)]
        public double RiskPercent { get; set; }


        protected TradeType Trade_Type
        {
            get
            {
                return
                    TType == 0 ? TradeType.Buy : TradeType.Sell;
            }
        }

        protected override void OnStart()
        {
            Positions.Opened += PositionsOnOpened;
            // Initialize _rate variable
            SetRate();
            int volume = GetVolume();
            Print("Volume = {0}", volume);
            ExecuteMarketOrder(Trade_Type, Symbol, volume, MyLabel);
        }

        private void PositionsOnOpened(PositionOpenedEventArgs args)
        {
            double risk = 0;
            foreach (Position position in Positions)
            {
                Symbol symbol = MarketData.GetSymbol(position.SymbolCode);
                if (position.StopLoss != null)
                {
                    double stopLoss = Math.Abs(position.EntryPrice - (double) position.StopLoss)/symbol.PipSize;
                    risk += stopLoss*symbol.PipValue*position.Volume - position.Commissions*2;
                }
            }
            Print(risk);
        }

        private int GetVolume()
        {
            double risk = RiskPercent/100.0;
            double volume;

            switch (_rate)
            {
                case Rates.Direct:
                    volume = Account.Equity*risk/(StopLoss*Symbol.PipValue);
                    break;
                case Rates.Indirect:
                    double stopLossPrice = Trade_Type == TradeType.Buy
                                               ? Symbol.Ask + StopLoss*Symbol.PipSize
                                               : Symbol.Bid - StopLoss*Symbol.PipSize;
                    volume = Account.Equity*risk*stopLossPrice/(StopLoss*Symbol.PipValue);
                    break;
                default: // pending
                    volume = 0;
                    break;
            }

            return (int) Symbol.NormalizeVolume(volume);
        }

        private void SetRate()
        {
            switch (Symbol.Code)
            {
                case "EURUSD":
                case "GBPUSD":
                case "AUDUSD":
                case "NZDUSD":
                    _rate = Rates.Direct;
                    break;
                case "USDJPY":
                case "USDCHF":
                case "USDCAD":
                    _rate = Rates.Indirect;
                    break;
                default:
                    _rate = Rates.Cross;
                    break;
            }
        }

        #region Nested type: Rates

        private enum Rates
        {
            Direct,
            Indirect,
            Cross
        };

        #endregion
    }
}

Maybe this is a start...

Can you please add a movable horizontal line for placing SL and pending order availability for buy and sell stops? 


@mgalona74

mgalona74
24 Sep 2015, 08:29

RE:

atrader said:

using System;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot]
    public class OnePercentRiskBot : Robot
    {
        private Rates _rate = Rates.Direct;

        [Parameter(DefaultValue = "Volume on Risk")]
        public string MyLabel { get; set; }

        [Parameter("0:Buy 1:Sell", DefaultValue = 0)]
        public int TType { get; set; }

        [Parameter("Stop Loss", DefaultValue = 10, MinValue = 0, MaxValue = 500)]
        public int StopLoss { get; set; }

        [Parameter("Take Profit", DefaultValue = 10, MinValue = 0, MaxValue = 500)]
        public int TakeProfit { get; set; }

        // Modify DefaultValue, MinValue, MaxValue
        [Parameter("Risk Percentage", DefaultValue = 1, MinValue = 0.01, MaxValue = 5)]
        public double RiskPercent { get; set; }


        protected TradeType Trade_Type
        {
            get
            {
                return
                    TType == 0 ? TradeType.Buy : TradeType.Sell;
            }
        }

        protected override void OnStart()
        {
            Positions.Opened += PositionsOnOpened;
            // Initialize _rate variable
            SetRate();
            int volume = GetVolume();
            Print("Volume = {0}", volume);
            ExecuteMarketOrder(Trade_Type, Symbol, volume, MyLabel);
        }

        private void PositionsOnOpened(PositionOpenedEventArgs args)
        {
            double risk = 0;
            foreach (Position position in Positions)
            {
                Symbol symbol = MarketData.GetSymbol(position.SymbolCode);
                if (position.StopLoss != null)
                {
                    double stopLoss = Math.Abs(position.EntryPrice - (double) position.StopLoss)/symbol.PipSize;
                    risk += stopLoss*symbol.PipValue*position.Volume - position.Commissions*2;
                }
            }
            Print(risk);
        }

        private int GetVolume()
        {
            double risk = RiskPercent/100.0;
            double volume;

            switch (_rate)
            {
                case Rates.Direct:
                    volume = Account.Equity*risk/(StopLoss*Symbol.PipValue);
                    break;
                case Rates.Indirect:
                    double stopLossPrice = Trade_Type == TradeType.Buy
                                               ? Symbol.Ask + StopLoss*Symbol.PipSize
                                               : Symbol.Bid - StopLoss*Symbol.PipSize;
                    volume = Account.Equity*risk*stopLossPrice/(StopLoss*Symbol.PipValue);
                    break;
                default: // pending
                    volume = 0;
                    break;
            }

            return (int) Symbol.NormalizeVolume(volume);
        }

        private void SetRate()
        {
            switch (Symbol.Code)
            {
                case "EURUSD":
                case "GBPUSD":
                case "AUDUSD":
                case "NZDUSD":
                    _rate = Rates.Direct;
                    break;
                case "USDJPY":
                case "USDCHF":
                case "USDCAD":
                    _rate = Rates.Indirect;
                    break;
                default:
                    _rate = Rates.Cross;
                    break;
            }
        }

        #region Nested type: Rates

        private enum Rates
        {
            Direct,
            Indirect,
            Cross
        };

        #endregion
    }
}

Maybe this is a start...

Really awesome. What I did is added the bot twice one is to buy and the other is to sell so I just click the right bot to buy or sell. Thank you very much. I really wish the horizontal line option for placing stops would be visible first prior to actually sending the order so that I don't have to use the cross hair to calculate the stop based on pips. Anyway, still awesome bot.Thanks again. 


@mgalona74

kricka
02 Oct 2015, 18:05

Risk management cBot

Have a look at this cBot. Lots to trade 1.0.

Easy to setup and to retrieve information on how many lots to trade according to basic risk management principles.

Free to download here: Lots to trade 1.0


@kricka

exportwork
15 Mar 2016, 22:17

RE: Risk management cBot

kricka said:

Have a look at this cBot. Lots to trade 1.0.

Easy to setup and to retrieve information on how many lots to trade according to basic risk management principles.

Free to download here: Lots to trade 1.0

No this is not what I want?.. 

I want something like where if I tell the system my pending entry stop & stop loss order it will automatically calculate my equity percentage risk and place the order in market on that basis.


@exportwork

exportwork
15 Mar 2016, 22:23

RE:

Can you please code where if I tell the system my pending entry stop & stop loss order it will automatically calculate my equity percentage risk and place the order in market on that basis (it is also called position sizing entry order system). Following is the mt4 indicator, can we convert it to c# for ctrader purpose please:

//+------------------------------------------------------------------+
//|                                       PositionSizeCalculator.mq4 |
//|                             Copyright © 2012-2015, Andriy Moraru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2012-2015, Andriy Moraru"
#property link      "http://www.earnforex.com"
#property version   "1.26"

#property description "Calculates position size based on account balance/equity,"
#property description "currency, currency pair, given entry level, stop-loss level"
#property description "and risk tolerance (set either in percentage points or in base currency)."
#property description "Can display reward/risk ratio based on take-profit."
#property description "Can also show total portfolio risk based on open trades and pending orders."
#property description "2015-12-12, ver. 1.26 - added DrawTextAsBackground parameter, fixed minor bugs."
// 2015-12-01, ver. 1.25 - fixed rounding bug.
// 2015-11-30, ver. 1.24 - added pips distance, fixed bugs, simplified things.
// 2015-07-01, ver. 1.23 - fixed SL between Ask/Bid bug, fixed minor bug with colors.
// 2015-04-08, ver. 1.22 - added line height parameter, minor bug fixes.
// 2015-04-04, ver. 1.21 - fixed line width bug.
// 2015-03-19, ver. 1.20 - added input parameters to hide some lines.
// 2015-03-08, ver. 1.19 - commission support, minor bug fixes.
// 2015-02-27, ver. 1.18 - two indicator versions - Separate or Main window.
// 2015-02-16, ver. 1.17 - separate window, input/output values, more warnings.
// 2015-02-13, ver. 1.16 - margin, warnings, number formatting, rounding down.
// 2015-01-30, ver. 1.15 - values read from lines are now rounded. DeleteLines also clears old lines when attaching.
// 2014-12-19, ver. 1.14 - fixed minor bug when restarting MT4; also, lines are no longer hidden from object list.
// 2014-10-03, ver. 1.13 - added portfolio risk calculation.
// 2014-09-17, ver. 1.12 - position size is now rounded down.
// 2014-04-11, ver. 1.11 - added potential reward display and color/style input parameters.
// 2013-11-11, ver. 1.10 - added optional Ask/Bid tracking for Entry line.
// 2013-02-11, ver. 1.8 - completely revamped calculation process.
// 2013-01-14, ver. 1.7 - fixed "division by zero" error.
// 2012-12-10, ver. 1.6 - will use local values if both Entry and SL are missing.
// 2012-11-02, ver. 1.5 - a more intelligent name prefix/postfix detection.
// 2012-10-13, ver. 1.4 - fixed contract size in lot size calculation.
// 2012-10-13, ver. 1.3 - proper lot size calculation for gold, silver and oil.
// 2012-09-29, ver. 1.2 - improved account currency and reference pair detection.
// 2012-05-10, ver. 1.1 - added support for setting risk in money.
#property description "WARNING: There is no guarantee that the output of this indicator is correct. Use at your own risk."

#property indicator_chart_window

int second_column_x = 0;
#include "PositionSizeCalculator_Base.mqh"
extern int MaxNumberLength = 10; // How many digits will there be in numbers as maximum?

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
{
   IndicatorShortName("Position Size Calculator");
   Window = 0;
   Initialization();
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   ObjectDelete("EntryLevel");
   if (DeleteLines) ObjectDelete("EntryLine");
   ObjectDelete("StopLoss");
   if (DeleteLines) ObjectDelete("StopLossLine");
   if (CommissionPerLot > 0) ObjectDelete("CommissionPerLot");
   ObjectDelete("Risk");
   ObjectDelete("AccountSize");
   ObjectDelete("Divider");
   ObjectDelete("RiskMoney");
   ObjectDelete("PositionSize");
  	ObjectDelete("StopLossLabel");
  	ObjectDelete("TakeProfitLabel");
   if (TakeProfitLevel > 0)
   {
      ObjectDelete("TakeProfit");
      if (DeleteLines) ObjectDelete("TakeProfitLine");
      ObjectDelete("RR");
      ObjectDelete("PotentialProfit");
   }
   if (ShowPortfolioRisk)
   {
      ObjectDelete("CurrentPortfolioMoneyRisk");
      ObjectDelete("CurrentPortfolioRisk");
      ObjectDelete("PotentialPortfolioMoneyRisk");
      ObjectDelete("PotentialPortfolioRisk");
   }
   if (ShowMargin)
   {
      ObjectDelete("PositionMargin");
      ObjectDelete("FutureUsedMargin");
      ObjectDelete("FutureFreeMargin");
   }
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

and following is the MT4 Script that puts the order in mt4 based on the above indicator code:

//+------------------------------------------------------------------+
//|                                                   simpleopen.mq4 |
//|                                    Copyright 2015, EarnForex.com |
//|                                         http://www.earnforex.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, EarnForex.com"
#property link      "http://www.earnforex.com"
#property version   "1.00"
#property strict
#include <stdlib.mqh>

/*

This script works with Position Size Calculator indicator:
http://www.earnforex.com/metatrader-indicators/Position-Size-Calculator

It can open pending or instant orders using the position size calculated by PSC.

You can change the maximum tolerated slippage via the 'slippage' variable below.

*/

int slippage = 3;

enum ENTRY_TYPE
{
   Instant,
   Pending
};

//+------------------------------------------------------------------+
//| Script execution function.                                       |
//+------------------------------------------------------------------+
void OnStart()
{
   int Window;

   string ps = ""; // Position size string.
   double el = 0, sl = 0, tp = 0; // Entry level, stop-loss, and take-profit.
   int ot; // Order type.
   ENTRY_TYPE entry_type;

   Window = WindowFind("Position Size Calculator");

   if (Window == -1)
   {
      ps = ObjectGetString(0, "PositionSize", OBJPROP_TEXT);
      if (!ps)
      {
         Alert("Position Size Calculator not found!");
         return;
      }
   }
   
   ps = ObjectGetString(0, "PositionSize", OBJPROP_TEXT);
   if (!ps)
   {
      Alert("Position Size object not found!");
      return;
   }
   
   int len = StringLen(ps);
   string ps_proc = "";
   for (int i = len - 1; i >= 0; i--)
   {
      string c = StringSubstr(ps, i, 1);
      if (c != " ") ps_proc = c + ps_proc;
      else break;
   }
   
   double PositionSize = StringToDouble(ps_proc);
   
   Print("Detected position size: ", PositionSize, ".");
   
   if (PositionSize <= 0)
   {
      Print("Wrong position size value!");
      return;
   }
   
   el = ObjectGetDouble(0, "EntryLine", OBJPROP_PRICE);
   if (el <= 0)
   {
      Alert("Entry Line not found!");
      return;
   }
   
   el = NormalizeDouble(el, Digits);
   Print("Detected entry level: ", DoubleToString(el, Digits), ".");

   RefreshRates();
   
   if ((el == Ask) || (el == Bid)) entry_type = Instant;
   else entry_type = Pending;
   
   Print("Detected entry type: ", EnumToString(entry_type), ".");
   
   sl = ObjectGetDouble(0, "StopLossLine", OBJPROP_PRICE);
   if (sl <= 0)
   {
      Alert("Stop-Loss Line not found!");
      return;
   }
   
   sl = NormalizeDouble(sl, Digits);
   Print("Detected stop-loss level: ", DoubleToString(sl, Digits), ".");
   
   
   tp = ObjectGetDouble(0, "TakeProfitLine", OBJPROP_PRICE);
   if (tp > 0)
   {
      tp = NormalizeDouble(tp, Digits);
      Print("Detected take-profit level: ", DoubleToString(tp, Digits), ".");
   }
   else Print("No take-profit detected.");
   
   if (entry_type == Pending)
   {
      // Sell
      if (sl > el)
      {
         // Stop
         if (el < Bid) ot = OP_SELLSTOP;
         // Limit
         else ot = OP_SELLLIMIT;
      }
      // Buy
      else
      {
         // Stop
         if (el > Ask) ot = OP_BUYSTOP;
         // Limit
         else ot = OP_BUYLIMIT;
      }
   }
   // Instant
   else
   {
      // Sell
      if (sl > el) ot = OP_SELL;
      // Buy
      else ot = OP_BUY;
   }
         
   int ticket = OrderSend(Symbol(), ot, PositionSize, el, slippage, sl, tp);
   if (ticket == -1)
      Print("Execution failed. Error: ", ErrorDescription(GetLastError()), ".");
   else Print("Order executed. Ticket: ", ticket, ".");
}
//+------------------------------------------------------------------+

Much appreciated.. please email me your reply at:    exportwork@yahoo.com

 

Cheers,

Paras.

atrader said:

using System;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot]
    public class OnePercentRiskBot : Robot
    {
        private Rates _rate = Rates.Direct;

        [Parameter(DefaultValue = "Volume on Risk")]
        public string MyLabel { get; set; }

        [Parameter("0:Buy 1:Sell", DefaultValue = 0)]
        public int TType { get; set; }

        [Parameter("Stop Loss", DefaultValue = 10, MinValue = 0, MaxValue = 500)]
        public int StopLoss { get; set; }

        [Parameter("Take Profit", DefaultValue = 10, MinValue = 0, MaxValue = 500)]
        public int TakeProfit { get; set; }

        // Modify DefaultValue, MinValue, MaxValue
        [Parameter("Risk Percentage", DefaultValue = 1, MinValue = 0.01, MaxValue = 5)]
        public double RiskPercent { get; set; }


        protected TradeType Trade_Type
        {
            get
            {
                return
                    TType == 0 ? TradeType.Buy : TradeType.Sell;
            }
        }

        protected override void OnStart()
        {
            Positions.Opened += PositionsOnOpened;
            // Initialize _rate variable
            SetRate();
            int volume = GetVolume();
            Print("Volume = {0}", volume);
            ExecuteMarketOrder(Trade_Type, Symbol, volume, MyLabel);
        }

        private void PositionsOnOpened(PositionOpenedEventArgs args)
        {
            double risk = 0;
            foreach (Position position in Positions)
            {
                Symbol symbol = MarketData.GetSymbol(position.SymbolCode);
                if (position.StopLoss != null)
                {
                    double stopLoss = Math.Abs(position.EntryPrice - (double) position.StopLoss)/symbol.PipSize;
                    risk += stopLoss*symbol.PipValue*position.Volume - position.Commissions*2;
                }
            }
            Print(risk);
        }

        private int GetVolume()
        {
            double risk = RiskPercent/100.0;
            double volume;

            switch (_rate)
            {
                case Rates.Direct:
                    volume = Account.Equity*risk/(StopLoss*Symbol.PipValue);
                    break;
                case Rates.Indirect:
                    double stopLossPrice = Trade_Type == TradeType.Buy
                                               ? Symbol.Ask + StopLoss*Symbol.PipSize
                                               : Symbol.Bid - StopLoss*Symbol.PipSize;
                    volume = Account.Equity*risk*stopLossPrice/(StopLoss*Symbol.PipValue);
                    break;
                default: // pending
                    volume = 0;
                    break;
            }

            return (int) Symbol.NormalizeVolume(volume);
        }

        private void SetRate()
        {
            switch (Symbol.Code)
            {
                case "EURUSD":
                case "GBPUSD":
                case "AUDUSD":
                case "NZDUSD":
                    _rate = Rates.Direct;
                    break;
                case "USDJPY":
                case "USDCHF":
                case "USDCAD":
                    _rate = Rates.Indirect;
                    break;
                default:
                    _rate = Rates.Cross;
                    break;
            }
        }

        #region Nested type: Rates

        private enum Rates
        {
            Direct,
            Indirect,
            Cross
        };

        #endregion
    }
}

Maybe this is a start...

 


@exportwork

deansi
29 May 2016, 13:54

RE: RE:

How did this go for you, found a way that does the job?


@deansi

matt92
08 Aug 2019, 00:52

RE: Risk management cBot

kricka said:

Have a look at this cBot. Lots to trade 1.0.

Easy to setup and to retrieve information on how many lots to trade according to basic risk management principles.

Free to download here: Lots to trade 1.0

I can't seem to get that from the link. Any chance you have a direct download link!? Thanks


@matt92