cAlgo 1% Risk Based Lot Size HELP

Created at 10 Apr 2019, 14:20
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!
SA

samuelbreezey

Joined 10.04.2019

cAlgo 1% Risk Based Lot Size HELP
10 Apr 2019, 14:20


Hey guys,

Okay, so I do not claim to be programmer, so I would like some help please :)

I have created an algo using FXPro Quant strategy builder and I would like to change the coding to allow for the lot size to be set automatically by setting a risk percentage. For example if my account was 10,000 I would only be risking £100 on a trade if I wanted to only risk 1%.

So, my lot size will be adjusted accordingly based on my 1% risk per trade.

Code is below :)

//+------------------------------------------------------------------+
//+                           Code generated using FxPro Quant 2.1.4 |
//+------------------------------------------------------------------+

using System;
using System.Threading;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.API.Requests;
using cAlgo.Indicators;


namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC)]
    public class Prototype : Robot
    {

        [Parameter("SL_Points", DefaultValue = 100)]
        public int _SL_Points { get; set; }
        [Parameter("Lots", DefaultValue = 0.1)]
        public double _Lots { get; set; }
        [Parameter("Candle_Points", DefaultValue = 500)]
        public int _Candle_Points { get; set; }
        [Parameter("TP_Points", DefaultValue = 200)]
        public int _TP_Points { get; set; }

        //Global declaration
        double _Open;
        double _Close;
        double _Transform;

        DateTime LastTradeExecution = new DateTime(0);

        protected override void OnStart()
        {

        }

        protected override void OnTick()
        {
            if (Trade.IsExecuting)
                return;

            //Local declaration
            TriState _Sell = new TriState();
            TriState _Buy = new TriState();

            //Step 1
            _Open = MarketSeries.Open.Last(1);
            _Close = MarketSeries.Close.Last(1);
            _Transform = Transform(_Candle_Points, 3);

            //Step 2

            //Step 3

            //Step 4

            //Step 5
            if ((((_Open - (_Close)) >= _Transform) && (MarketSeries.TickVolume.LastValue == 1)))
                _Sell = Sell(0, _Lots, 1, _SL_Points, 1, _TP_Points, 10, 1, 0, "");
            if ((((_Close - (_Open)) >= _Transform) && (MarketSeries.TickVolume.LastValue == 1)))
                _Buy = Buy(0, _Lots, 1, _SL_Points, 1, _TP_Points, 10, 1, 0, "");

        }

        bool NoOrders(string symbolCode, double[] magicIndecies)
        {
            if (symbolCode == "")
                symbolCode = Symbol.Code;
            string[] labels = new string[magicIndecies.Length];
            for (int i = 0; i < magicIndecies.Length; i++)
            {
                labels[i] = "FxProQuant_" + magicIndecies[i].ToString("F0");
            }
            foreach (Position pos in Positions)
            {
                if (pos.SymbolCode != symbolCode)
                    continue;
                if (labels.Length == 0)
                    return false;
                foreach (var label in labels)
                {
                    if (pos.Label == label)
                        return false;
                }
            }
            foreach (PendingOrder po in PendingOrders)
            {
                if (po.SymbolCode != symbolCode)
                    continue;
                if (labels.Length == 0)
                    return false;
                foreach (var label in labels)
                {
                    if (po.Label == label)
                        return false;
                }
            }
            return true;
        }

        TriState _OpenPosition(double magicIndex, bool noOrders, string symbolCode, TradeType tradeType, double lots, double slippage, double? stopLoss, double? takeProfit, string comment)
        {
            Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode);
            if (noOrders && Positions.Find("FxProQuant_" + magicIndex.ToString("F0"), symbol) != null)
                return new TriState();
            if (stopLoss < 1)
                stopLoss = null;
            if (takeProfit < 1)
                takeProfit = null;
            if (symbol.Digits == 5 || symbol.Digits == 3)
            {
                if (stopLoss != null)
                    stopLoss /= 10;
                if (takeProfit != null)
                    takeProfit /= 10;
                slippage /= 10;
            }
            int volume = Convert.ToInt32(lots * 100000);
            if (!ExecuteMarketOrder(tradeType, symbol, volume, "FxProQuant_" + magicIndex.ToString("F0"), stopLoss, takeProfit, slippage, comment).IsSuccessful)
            {
                Thread.Sleep(400);
                return false;
            }
            return true;
        }

        TriState _SendPending(double magicIndex, bool noOrders, string symbolCode, PendingOrderType poType, TradeType tradeType, double lots, int priceAction, double priceValue, double? stopLoss, double? takeProfit,
        DateTime? expiration, string comment)
        {
            Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode);
            if (noOrders && PendingOrders.__Find("FxProQuant_" + magicIndex.ToString("F0"), symbol) != null)
                return new TriState();
            if (stopLoss < 1)
                stopLoss = null;
            if (takeProfit < 1)
                takeProfit = null;
            if (symbol.Digits == 5 || symbol.Digits == 3)
            {
                if (stopLoss != null)
                    stopLoss /= 10;
                if (takeProfit != null)
                    takeProfit /= 10;
            }
            int volume = Convert.ToInt32(lots * 100000);
            double targetPrice;
            switch (priceAction)
            {
                case 0:
                    targetPrice = priceValue;
                    break;
                case 1:
                    targetPrice = symbol.Bid - priceValue * symbol.TickSize;
                    break;
                case 2:
                    targetPrice = symbol.Bid + priceValue * symbol.TickSize;
                    break;
                case 3:
                    targetPrice = symbol.Ask - priceValue * symbol.TickSize;
                    break;
                case 4:
                    targetPrice = symbol.Ask + priceValue * symbol.TickSize;
                    break;
                default:
                    targetPrice = priceValue;
                    break;
            }
            if (expiration.HasValue && (expiration.Value.Ticks == 0 || expiration.Value == DateTime.Parse("1970.01.01 00:00:00")))
                expiration = null;
            if (poType == PendingOrderType.Limit)
            {
                if (!PlaceLimitOrder(tradeType, symbol, volume, targetPrice, "FxProQuant_" + magicIndex.ToString("F0"), stopLoss, takeProfit, expiration, comment).IsSuccessful)
                {
                    Thread.Sleep(400);
                    return false;
                }
                return true;
            }
            else if (poType == PendingOrderType.Stop)
            {
                if (!PlaceStopOrder(tradeType, symbol, volume, targetPrice, "FxProQuant_" + magicIndex.ToString("F0"), stopLoss, takeProfit, expiration, comment).IsSuccessful)
                {
                    Thread.Sleep(400);
                    return false;
                }
                return true;
            }
            return new TriState();
        }

        TriState _ModifyPosition(double magicIndex, string symbolCode, int slAction, double slValue, int tpAction, double tpValue)
        {
            Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode);
            var pos = Positions.Find("FxProQuant_" + magicIndex.ToString("F0"), symbol);
            if (pos == null)
                return new TriState();
            double? sl, tp;
            if (slValue == 0)
                sl = null;
            else
            {
                switch (slAction)
                {
                    case 0:
                        sl = pos.StopLoss;
                        break;
                    case 1:
                        if (pos.TradeType == TradeType.Buy)
                            sl = pos.EntryPrice - slValue * symbol.TickSize;
                        else
                            sl = pos.EntryPrice + slValue * symbol.TickSize;
                        break;
                    case 2:
                        sl = slValue;
                        break;
                    default:
                        sl = pos.StopLoss;
                        break;
                }
            }
            if (tpValue == 0)
                tp = null;
            else
            {
                switch (tpAction)
                {
                    case 0:
                        tp = pos.TakeProfit;
                        break;
                    case 1:
                        if (pos.TradeType == TradeType.Buy)
                            tp = pos.EntryPrice + tpValue * symbol.TickSize;
                        else
                            tp = pos.EntryPrice - tpValue * symbol.TickSize;
                        break;
                    case 2:
                        tp = tpValue;
                        break;
                    default:
                        tp = pos.TakeProfit;
                        break;
                }
            }
            if (!ModifyPosition(pos, sl, tp).IsSuccessful)
            {
                Thread.Sleep(400);
                return false;
            }
            return true;
        }

        TriState _ModifyPending(double magicIndex, string symbolCode, int slAction, double slValue, int tpAction, double tpValue, int priceAction, double priceValue, int expirationAction, DateTime? expiration)
        {
            Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode);
            var po = PendingOrders.__Find("FxProQuant_" + magicIndex.ToString("F0"), symbol);
            if (po == null)
                return new TriState();
            double targetPrice;
            double? sl, tp;
            if (slValue == 0)
                sl = null;
            else
            {
                switch (slAction)
                {
                    case 0:
                        sl = po.StopLoss;
                        break;
                    case 1:
                        if (po.TradeType == TradeType.Buy)
                            sl = po.TargetPrice - slValue * symbol.TickSize;
                        else
                            sl = po.TargetPrice + slValue * symbol.TickSize;
                        break;
                    case 2:
                        sl = slValue;
                        break;
                    default:
                        sl = po.StopLoss;
                        break;
                }
            }
            if (tpValue == 0)
                tp = null;
            else
            {
                switch (tpAction)
                {
                    case 0:
                        tp = po.TakeProfit;
                        break;
                    case 1:
                        if (po.TradeType == TradeType.Buy)
                            tp = po.TargetPrice + tpValue * symbol.TickSize;
                        else
                            tp = po.TargetPrice - tpValue * symbol.TickSize;
                        break;
                    case 2:
                        tp = tpValue;
                        break;
                    default:
                        tp = po.TakeProfit;
                        break;
                }
            }
            switch (priceAction)
            {
                case 0:
                    targetPrice = po.TargetPrice;
                    break;
                case 1:
                    targetPrice = priceValue;
                    break;
                case 2:
                    targetPrice = po.TargetPrice + priceValue * symbol.TickSize;
                    break;
                case 3:
                    targetPrice = po.TargetPrice - priceValue * symbol.TickSize;
                    break;
                case 4:
                    targetPrice = symbol.Bid - priceValue * symbol.TickSize;
                    break;
                case 5:
                    targetPrice = symbol.Bid + priceValue * symbol.TickSize;
                    break;
                case 6:
                    targetPrice = symbol.Ask - priceValue * symbol.TickSize;
                    break;
                case 7:
                    targetPrice = symbol.Ask + priceValue * symbol.TickSize;
                    break;
                default:
                    targetPrice = po.TargetPrice;
                    break;
            }
            if (expiration.HasValue && (expiration.Value.Ticks == 0 || expiration.Value == DateTime.Parse("1970.01.01 00:00:00")))
                expiration = null;
            if (expirationAction == 0)
                expiration = po.ExpirationTime;
            if (!ModifyPendingOrder(po, targetPrice, sl, tp, expiration).IsSuccessful)
            {
                Thread.Sleep(400);
                return false;
            }
            return true;
        }

        TriState _ClosePosition(double magicIndex, string symbolCode, double lots)
        {
            Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode);
            var pos = Positions.Find("FxProQuant_" + magicIndex.ToString("F0"), symbol);
            if (pos == null)
                return new TriState();
            TradeResult result;
            if (lots == 0)
            {
                result = ClosePosition(pos);
            }
            else
            {
                int volume = Convert.ToInt32(lots * 100000);
                result = ClosePosition(pos, volume);
            }
            if (!result.IsSuccessful)
            {
                Thread.Sleep(400);
                return false;
            }
            return true;
        }

        TriState _DeletePending(double magicIndex, string symbolCode)
        {
            Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode);
            var po = PendingOrders.__Find("FxProQuant_" + magicIndex.ToString("F0"), symbol);
            if (po == null)
                return new TriState();
            if (!CancelPendingOrder(po).IsSuccessful)
            {
                Thread.Sleep(400);
                return false;
            }
            return true;
        }

        bool _OrderStatus(double magicIndex, string symbolCode, int test)
        {
            Symbol symbol = (Symbol.Code == symbolCode) ? Symbol : MarketData.GetSymbol(symbolCode);
            var pos = Positions.Find("FxProQuant_" + magicIndex.ToString("F0"), symbol);
            if (pos != null)
            {
                if (test == 0)
                    return true;
                if (test == 1)
                    return true;
                if (test == 3)
                    return pos.TradeType == TradeType.Buy;
                if (test == 4)
                    return pos.TradeType == TradeType.Sell;
            }
            var po = PendingOrders.__Find("FxProQuant_" + magicIndex.ToString("F0"), symbol);
            if (po != null)
            {
                if (test == 0)
                    return true;
                if (test == 2)
                    return true;
                if (test == 3)
                    return po.TradeType == TradeType.Buy;
                if (test == 4)
                    return po.TradeType == TradeType.Sell;
                if (test == 5)
                    return po.OrderType == PendingOrderType.Limit;
                if (test == 6)
                    return po.OrderType == PendingOrderType.Stop;
            }
            return false;
        }

        int TimeframeToInt(TimeFrame tf)
        {
            if (tf == TimeFrame.Minute)
                return 1;
            else if (tf == TimeFrame.Minute2)
                return 2;
            else if (tf == TimeFrame.Minute3)
                return 3;
            else if (tf == TimeFrame.Minute4)
                return 4;
            else if (tf == TimeFrame.Minute5)
                return 5;
            else if (tf == TimeFrame.Minute10)
                return 10;
            else if (tf == TimeFrame.Minute15)
                return 15;
            else if (tf == TimeFrame.Minute30)
                return 30;
            else if (tf == TimeFrame.Hour)
                return 60;
            else if (tf == TimeFrame.Hour4)
                return 240;
            else if (tf == TimeFrame.Daily)
                return 1440;
            else if (tf == TimeFrame.Weekly)
                return 10080;
            else if (tf == TimeFrame.Monthly)
                return 43200;
            return 1;
        }


        DateTime __currentBarTime = DateTime.MinValue;
        bool __isNewBar(bool triggerAtStart)
        {
            DateTime newTime = MarketSeries.OpenTime.LastValue;
            if (__currentBarTime != newTime)
            {
                if (!triggerAtStart && __currentBarTime == DateTime.MinValue)
                {
                    __currentBarTime = newTime;
                    return false;
                }
                __currentBarTime = newTime;
                return true;
            }
            return false;
        }


        TriState Sell(double magicIndex, double Lots, int StopLossMethod, double stopLossValue, int TakeProfitMethod, double takeProfitValue, double Slippage, double MaxOpenTrades, double MaxFrequencyMins, string TradeComment)
        {
            double? stopLossPips, takeProfitPips;
            int numberOfOpenTrades = 0;
            var res = new TriState();

            foreach (Position pos in Positions.FindAll("FxProQuant_" + magicIndex.ToString("F0"), Symbol))
            {
                numberOfOpenTrades++;
            }

            if (MaxOpenTrades > 0 && numberOfOpenTrades >= MaxOpenTrades)
                return res;

            if (MaxFrequencyMins > 0)
            {
                if (((TimeSpan)(Server.Time - LastTradeExecution)).TotalMinutes < MaxFrequencyMins)
                    return res;

                foreach (Position pos in Positions.FindAll("FxProQuant_" + magicIndex.ToString("F0"), Symbol))
                {
                    if (((TimeSpan)(Server.Time - pos.EntryTime)).TotalMinutes < MaxFrequencyMins)
                        return res;
                }
            }

            int pipAdjustment = Convert.ToInt32(Symbol.PipSize / Symbol.TickSize);

            if (stopLossValue > 0)
            {
                if (StopLossMethod == 0)
                    stopLossPips = stopLossValue / pipAdjustment;
                else if (StopLossMethod == 1)
                    stopLossPips = stopLossValue;
                else
                    stopLossPips = (stopLossValue - Symbol.Bid) / Symbol.PipSize;
            }
            else
                stopLossPips = null;

            if (takeProfitValue > 0)
            {
                if (TakeProfitMethod == 0)
                    takeProfitPips = takeProfitValue / pipAdjustment;
                else if (TakeProfitMethod == 1)
                    takeProfitPips = takeProfitValue;
                else
                    takeProfitPips = (Symbol.Bid - takeProfitValue) / Symbol.PipSize;
            }
            else
                takeProfitPips = null;

            Slippage /= pipAdjustment;

            long volume = Symbol.NormalizeVolume(Lots * 100000, RoundingMode.ToNearest);

            if (!ExecuteMarketOrder(TradeType.Sell, Symbol, volume, "FxProQuant_" + magicIndex.ToString("F0"), stopLossPips, takeProfitPips, Slippage, TradeComment).IsSuccessful)
            {
                Thread.Sleep(400);
                return false;
            }

            LastTradeExecution = Server.Time;
            return true;
        }


        double Transform(double Value, int Transformation)
        {
            switch (Transformation)
            {
                case 0:
                    return (Value / Symbol.TickSize);
                case 1:
                    return (Value / Symbol.PipSize);
                case 2:
                    return (Value * Symbol.TickSize);
                case 3:
                    return (Value * Symbol.PipSize);
                default:
                    return (0);
            }
        }


        TriState Buy(double magicIndex, double Lots, int StopLossMethod, double stopLossValue, int TakeProfitMethod, double takeProfitValue, double Slippage, double MaxOpenTrades, double MaxFrequencyMins, string TradeComment)
        {
            double? stopLossPips, takeProfitPips;
            int numberOfOpenTrades = 0;
            var res = new TriState();

            foreach (Position pos in Positions.FindAll("FxProQuant_" + magicIndex.ToString("F0"), Symbol))
            {
                numberOfOpenTrades++;
            }

            if (MaxOpenTrades > 0 && numberOfOpenTrades >= MaxOpenTrades)
                return res;

            if (MaxFrequencyMins > 0)
            {
                if (((TimeSpan)(Server.Time - LastTradeExecution)).TotalMinutes < MaxFrequencyMins)
                    return res;

                foreach (Position pos in Positions.FindAll("FxProQuant_" + magicIndex.ToString("F0"), Symbol))
                {
                    if (((TimeSpan)(Server.Time - pos.EntryTime)).TotalMinutes < MaxFrequencyMins)
                        return res;
                }
            }

            int pipAdjustment = Convert.ToInt32(Symbol.PipSize / Symbol.TickSize);

            if (stopLossValue > 0)
            {
                if (StopLossMethod == 0)
                    stopLossPips = stopLossValue / pipAdjustment;
                else if (StopLossMethod == 1)
                    stopLossPips = stopLossValue;
                else
                    stopLossPips = (Symbol.Ask - stopLossValue) / Symbol.PipSize;
            }
            else
                stopLossPips = null;

            if (takeProfitValue > 0)
            {
                if (TakeProfitMethod == 0)
                    takeProfitPips = takeProfitValue / pipAdjustment;
                else if (TakeProfitMethod == 1)
                    takeProfitPips = takeProfitValue;
                else
                    takeProfitPips = (takeProfitValue - Symbol.Ask) / Symbol.PipSize;
            }
            else
                takeProfitPips = null;

            Slippage /= pipAdjustment;
            long volume = Symbol.NormalizeVolume(Lots * 100000, RoundingMode.ToNearest);

            if (!ExecuteMarketOrder(TradeType.Buy, Symbol, volume, "FxProQuant_" + magicIndex.ToString("F0"), stopLossPips, takeProfitPips, Slippage, TradeComment).IsSuccessful)
            {
                Thread.Sleep(400);
                return false;
            }
            LastTradeExecution = Server.Time;
            return true;
        }

    }
}

public struct TriState
{
    public static readonly TriState NonExecution = new TriState(0);
    public static readonly TriState False = new TriState(-1);
    public static readonly TriState True = new TriState(1);
    sbyte value;
    TriState(int value)
    {
        this.value = (sbyte)value;
    }
    public bool IsNonExecution
    {
        get { return value == 0; }
    }
    public static implicit operator TriState(bool x)
    {
        return x ? True : False;
    }
    public static TriState operator ==(TriState x, TriState y)
    {
        if (x.value == 0 || y.value == 0)
            return NonExecution;
        return x.value == y.value ? True : False;
    }
    public static TriState operator !=(TriState x, TriState y)
    {
        if (x.value == 0 || y.value == 0)
            return NonExecution;
        return x.value != y.value ? True : False;
    }
    public static TriState operator !(TriState x)
    {
        return new TriState(-x.value);
    }
    public static TriState operator &(TriState x, TriState y)
    {
        return new TriState(x.value < y.value ? x.value : y.value);
    }
    public static TriState operator |(TriState x, TriState y)
    {
        return new TriState(x.value > y.value ? x.value : y.value);
    }
    public static bool operator true(TriState x)
    {
        return x.value > 0;
    }
    public static bool operator false(TriState x)
    {
        return x.value < 0;
    }
    public static implicit operator bool(TriState x)
    {
        return x.value > 0;
    }
    public override bool Equals(object obj)
    {
        if (!(obj is TriState))
            return false;
        return value == ((TriState)obj).value;
    }
    public override int GetHashCode()
    {
        return value;
    }
    public override string ToString()
    {
        if (value > 0)
            return "True";
        if (value < 0)
            return "False";
        return "NonExecution";
    }
}

public static class PendingEx
{
    public static PendingOrder __Find(this cAlgo.API.PendingOrders pendingOrders, string label, Symbol symbol)
    {
        foreach (PendingOrder po in pendingOrders)
        {
            if (po.SymbolCode == symbol.Code && po.Label == label)
                return po;
        }
        return null;
    }
}

 

Your comments will be deeply appreciated,

Samuel


@samuelbreezey
Replies

Jonkey
24 Apr 2019, 08:54

https://ctrader.com/forum/cbot-support/1573

The code you need is in here. But coupling it into your code is the fun bit (friendly sarcasm)... It's just a time thing... that I don't have right now to do it for you... and even then it might be buggy... and id have to spend time debugging it ... hope this helps but im sorry I can't be of more help.

Coding is a source, it will change your life... swear to God. : )

 

 


@Jonkey

samuelbreezey
05 May 2019, 14:32

RE:

Jonkey said:

https://ctrader.com/forum/cbot-support/1573

The code you need is in here. But coupling it into your code is the fun bit (friendly sarcasm)... It's just a time thing... that I don't have right now to do it for you... and even then it might be buggy... and id have to spend time debugging it ... hope this helps but im sorry I can't be of more help.

Coding is a source, it will change your life... swear to God. : )

 

 

Thank you

I have now been able to do this thanks to the thread you gave me. 

Much appreciated :)


@samuelbreezey