Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
5.2 kB
2
Indexable
Never
using cAlgo.API;
using cAlgo.API.Indicators;
using System;
using System.Collections.Generic;


namespace MovingAverageCrossoverBot
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MovingAverageCrossoverBot : Robot
    {
        private TimeFrame higherTimeframe = TimeFrame.Weekly; // Define the higher timeframe
        private double higherTimeframeThreshold = 0.5;
        
        private double lotSize;

        private MovingAverage fastMA;
        private MovingAverage slowMA;
        private DateTime lastBarTime;
        
        private Color regularStopLossColor = Color.Red;
        private Color trailingStopLossColor = Color.Blue;
        private Color currentStopLossColor;
                
        private double trailingStopDistanceInPips = 1000; // Adjust this value according to your preference
        private double minProfitForTrailing = 1000; // Minimum profit in pips before trailing stop becomes active
        
        protected override void OnStart()
        {   
            // Configure your symbols and timeframes
           // TimeFrame timeframe = TimeFrame.HeikinHour;

            // Configure your moving average periods
            int fastMAPeriod = 50;
            int slowMAPeriod = 200;
            
            
            // Initialize moving averages
            fastMA = Indicators.MovingAverage(Bars.ClosePrices, fastMAPeriod, MovingAverageType.Simple);
            slowMA = Indicators.MovingAverage(Bars.ClosePrices, slowMAPeriod, MovingAverageType.Simple);

            lastBarTime = Bars.OpenTimes.LastValue;
        }

        protected override void OnBar()
        {
        
   
            // Check if a new bar has formed
            if (Bars.OpenTimes.LastValue > lastBarTime)
            {
                lastBarTime = Bars.OpenTimes.LastValue;
                
                int index = Bars.ClosePrices.Count - 1; // Index of the last closed bar
                bool isHigherTimeframeUptrend = IsHigherTimeframeUptrend(); 

                foreach (var position in Positions)
                {
                
                    double unrealizedProfitInPips = position.Pips;
                    
                    if (unrealizedProfitInPips >= minProfitForTrailing)
                    {
                     string lineName = $"StopLossLine_{position.Id}";
                        double trailingStopPrice = Symbol.Bid - trailingStopDistanceInPips * Symbol.PipSize;
                        ModifyPosition(position, trailingStopPrice, position.TakeProfit);

                        currentStopLossColor = trailingStopLossColor;
                          
                        Chart.RemoveObject(lineName);
                        
                        // Draw Stop Loss Line if it exists
                        if (position.StopLoss.HasValue)
                        {
                            double stopLossPrice = position.StopLoss.Value;
                           
                            Chart.DrawHorizontalLine(lineName, stopLossPrice, currentStopLossColor, 1, LineStyle.Solid);
                           
                        }
                    }
                  
                  
                    if(!isHigherTimeframeUptrend && Positions.Count > 0)
                    {
                        ClosePosition(position);
                        Chart.RemoveAllObjects();
                        
                    }
                }
               
                if ( fastMA.Result.HasCrossedAbove(slowMA.Result, index)&& isHigherTimeframeUptrend)
                {
                
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.NormalizeVolumeInUnits(Symbol.LotSize), "Buy Order", 2000, 2000, null );

                }
            }
        }

        private void ClosePosition(TradeResult  position)
        {
            ClosePosition(position);
        }
    private bool IsHigherTimeframeUptrend()
{
    // Calculate moving averages on the higher timeframe
    double[] higherTimeframeFastMASeries = CalculateSimpleMovingAverage(Bars.ClosePrices, higherTimeframe, 50);
    double[] higherTimeframeSlowMASeries = CalculateSimpleMovingAverage(Bars.ClosePrices, higherTimeframe, 200);

    int lastIndex = Bars.ClosePrices.Count - 1;

    // Check if the slow MA on higher timeframe is below the fast MA, indicating a potential downtrend
    return higherTimeframeSlowMASeries[lastIndex] < higherTimeframeFastMASeries[lastIndex];
}

private double[] CalculateSimpleMovingAverage(DataSeries source, TimeFrame timeframe, int period)
{
    double[] smaValues = new double[source.Count];

    for (int i = 0; i < source.Count; i++)
    {
        if (i >= period - 1)
        {
            double sum = 0;

            for (int j = i - period + 1; j <= i; j++)
            {
                sum += source[j];
            }

            smaValues[i] = sum / period;
        }
        else
        {
            smaValues[i] = source[i];
        }
    }

    return smaValues;
}
       
    }
}