Replies

algobeginner
17 Dec 2024, 08:31

Won’t be easier convert a logic of your indicator into calgo bot directly ?


@algobeginner

algobeginner
17 Dec 2024, 08:31

Won’t be easier convert a logic of your indicator into calgo bot directly ?


@algobeginner

algobeginner
17 Dec 2024, 07:58

Check Capital letter - it should be “OnBar” and stoploss string you have used as well one with capital other small letter . 


@algobeginner

algobeginner
16 Dec 2024, 12:04

This seem to do the trick , no memory crash and does tested multiple days
using System;
using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class HedgingMartingale : Robot
    {
        [Parameter("Initial Quantity (Lots)", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)]
        public double InitialQuantity { get; set; }

        [Parameter("Restart Initial Quantity (Lots)", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)]
        public double RestartInitialQuantity { get; set; }

        [Parameter("Take Profit / StopLoss", DefaultValue = 35)]
        public int TakeProfitStopLoss { get; set; }

        [Parameter("Max Loss In Row", DefaultValue = 11)]
        public int MaxLossInRow { get; set; }

        private const int StartHour = 12; // 12:00 UTC
        private const int EndHour = 15;   // 15:00 UTC

        private Random random = new Random();
        private int LossInRowLong = 0;
        private int LossInRowShort = 0;

        protected override void OnStart()
        {
            Positions.Closed += OnPositionsClosed;
        }

        protected override void OnTick()
        {
            var currentTime = Server.Time;

            if (currentTime.Hour >= StartHour && currentTime.Hour < EndHour)
            {
                var position = Positions.Find("HedgingMartingale");
                if (position == null)
                {
                    ExecuteOrder(RestartInitialQuantity, GetRandomTradeType());
                }
            }
        }

        private void ExecuteOrder(double quantity, TradeType tradeType)
        {
            Print("The Spread of the symbol is: {0}", Symbol.Spread);
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(quantity);
            var result = ExecuteMarketOrder(tradeType, Symbol.Name, volumeInUnits, "HedgingMartingale", TakeProfitStopLoss, TakeProfitStopLoss);

            if (result.Error == ErrorCode.NoMoney)
            {
                Print("Not enough money to execute order.");
                Stop();
            }
        }

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

            if (position.Label != "HedgingMartingale" || position.SymbolName != Symbol.Name)
                return;

            if (position.GrossProfit > 0)
            {
                if (position.TradeType == TradeType.Buy)
                {
                    LossInRowLong = 0;
                }
                else if (position.TradeType == TradeType.Sell)
                {
                    LossInRowShort = 0;
                }

                ExecuteOrder(InitialQuantity, position.TradeType);
            }
            else
            {
                if (position.TradeType == TradeType.Buy)
                {
                    LossInRowLong++;
                }
                else if (position.TradeType == TradeType.Sell)
                {
                    LossInRowShort++;
                }

                if (LossInRowLong > MaxLossInRow || LossInRowShort > MaxLossInRow)
                {
                    Print("Max loss in a row reached. Resetting.");
                    LossInRowLong = 0;
                    LossInRowShort = 0;
                }
                else
                {
                    ExecuteOrder(position.Quantity * 2, position.TradeType);
                }
            }
        }

        private TradeType GetRandomTradeType()
        {
            return random.Next(2) == 0 ? TradeType.Buy : TradeType.Sell;
        }

        protected override void OnStop()
        {
            Positions.Closed -= OnPositionsClosed; // Unsubscribe from the event
        }
    }
}

@algobeginner

algobeginner
16 Dec 2024, 11:31 ( Updated at: 16 Dec 2024, 11:53 )

I tried to update it and make it only buy for example on three white soldiers

This code seem to work , can someone make it better to use less resources ?

 

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

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None, AddIndicators = true)]
    public class ThreeWhiteSoldiersandThreeCrows : Robot
    {
        [Parameter(DefaultValue = 1000)]
        public double Volume { get; set; }

        [Parameter(DefaultValue = 10)]
        public double TakeProfit { get; set; }

        [Parameter(DefaultValue = 10)]
        public double StopLoss { get; set; }

        private const double PipSize = 0.0001; // Adjust this for different instruments (e.g., 0.01 for JPY pairs)
        private double adjustedStopLoss;

        // Define string constants for position labels
        private const string BuyLabel = "Three White Soldiers";

        protected override void OnBar()
        {
            // Three White Soldiers
            if (Bars.ClosePrices.Last(1) > Bars.OpenPrices.Last(1)
                && Bars.ClosePrices.Last(2) > Bars.OpenPrices.Last(2)
                && Bars.ClosePrices.Last(3) > Bars.OpenPrices.Last(3))
            {
                HandleBuyOrder();
            }
        }

        private void HandleBuyOrder()
        {
            var existingBuyPositions = Positions.FindAll(BuyLabel); // Fix: Use string label here
            if (existingBuyPositions.Length > 0)
            {
                // Check if the first position has reached 5 pips profit
                var firstPosition = existingBuyPositions[0];
                if (firstPosition.GrossProfit >= 5 * PipSize)
                {
                    // Adjust the stop loss of the first position
                    adjustedStopLoss = (firstPosition.StopLoss ?? 0) + 5 * PipSize; // Fix: Handle nullable StopLoss
                    var modifyResult = ModifyPosition(firstPosition, adjustedStopLoss, firstPosition.TakeProfit);
                    if (!modifyResult.IsSuccessful)
                    {
                        Print("Failed to modify position: " + modifyResult.Error);
                    }

                    // Open a new position
                    var orderResult = ExecuteMarketOrder(TradeType.Buy, Symbol.Name, Volume, BuyLabel, StopLoss, TakeProfit);
                    if (!orderResult.IsSuccessful)
                    {
                        Print("Failed to execute market order: " + orderResult.Error);
                    }
                }
            }
            else
            {
                // No existing buy positions, open a new one
                var orderResult = ExecuteMarketOrder(TradeType.Buy, Symbol.Name, Volume, BuyLabel, StopLoss, TakeProfit);
                if (!orderResult.IsSuccessful)
                {
                    Print("Failed to execute market order: " + orderResult.Error);
                }
            }
        }
    }
}

@algobeginner

algobeginner
16 Dec 2024, 11:31

I tried to update it and make it only buy for example on three white soldiers

I have tried to simplify it and make it easier but still struggling to make logic of existingBuyPosition or existingSellPositions with some label and find function, 

 

private void HandleBuyOrder()
        {
            var existingBuyPositions = Positions.FindAll(BuyLabel, TradeType.Buy);
            if (existingBuyPositions.Length > 0)
            {
                // Check if the first position has reached 5 pips profit
                var firstPosition = existingBuyPositions[0];
                if (firstPosition.GrossProfit >= 5 * PipSize)
                {
                    // Adjust the stop loss of the first position
                    adjustedStopLoss = firstPosition.StopLoss + 5 * PipSize;
                    var modifyResult = ModifyPosition(firstPosition, adjustedStopLoss, firstPosition.TakeProfit);
                    if (!modifyResult.IsSuccessful)
                    {
                        Print("Failed to modify position: " + modifyResult.Error);
                    }
                    
                    // Open a new position
                    var orderResult = ExecuteMarketOrder(TradeType.Buy, Symbol.Name, Volume, BuyLabel, StopLoss, TakeProfit);
                    if (!orderResult.IsSuccessful)
                    {
                        Print("Failed to execute market order: " + orderResult.Error);
                    }
                }
            }
            else
            {
                // No existing buy positions, open a new one
                var orderResult = ExecuteMarketOrder(TradeType.Buy, Symbol.Name, Volume, BuyLabel, StopLoss, TakeProfit);
                if (!orderResult.IsSuccessful)
                {
                    Print("Failed to execute market order: " + orderResult.Error);
                }

@algobeginner

algobeginner
16 Dec 2024, 08:29 ( Updated at: 16 Dec 2024, 09:50 )

There is option at top right corner to save it at least on Mac version ,each pass is saved into individual folder . 

From my point of view not practical ,  Excel has a row limit of 1,048,576 rows and a column limit of 16,384. 

Better option be bridge into MySQL or similar database program for quicker access to a lots of data .


@algobeginner