Untitled

mail@pastecode.io avatar
unknown
plain_text
2 months ago
16 kB
3
Indexable
Never
using System;
using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SupertrendStrategy : Robot
    {
        private Supertrend supertrend10;
        private Supertrend supertrend11;
        private Supertrend supertrend12;
        
        private ExponentialMovingAverage ema10;
        private ExponentialMovingAverage ema50;
        private ExponentialMovingAverage ema200;
        private AverageTrueRange atr;
        private DateTime lastTradeTime;
        private BollingerBands bollingerBands;
        private RelativeStrengthIndex rsi;
        
        private OnBalanceVolume obv;
        
       // [Parameter("OBV Period", DefaultValue = 14)]
       // public int OBVPeriod { get; set; }
      
        
        [Parameter("TRAILINGSTOPLOSS", DefaultValue = false)]
        public bool TRAILINGSTOPLOSS { get; set; }
       
        [Parameter("TAKEPROFIT", DefaultValue = 6)]
        public int TAKEPROFIT { get; set; }
        
        [Parameter("STOPLOSS", DefaultValue = 3)]
        public int STOPLOSS { get; set; }

        [Parameter("Supertrend Period (ATR 10)", DefaultValue = 10)]
        public int SupertrendPeriod10 { get; set; }

        [Parameter("Supertrend Multiplier (ATR 10)", DefaultValue = 1.0)]
        public double SupertrendMultiplier10 { get; set; }
        
        [Parameter("Supertrend Period (ATR 11)", DefaultValue = 11)]
        public int SupertrendPeriod11 { get; set; }

        [Parameter("Supertrend Multiplier (ATR 11)", DefaultValue = 2.0)]
        public double SupertrendMultiplier11 { get; set; }
        
        [Parameter("Supertrend Period (ATR 12)", DefaultValue = 12)]
        public int SupertrendPeriod12 { get; set; }

        [Parameter("Supertrend Multiplier (ATR 12)", DefaultValue = 3.0)]
        public double SupertrendMultiplier12 { get; set; }
        
        [Parameter("RSI Period", DefaultValue = 14)]
        public int RSIPeriod { get; set; }

        [Parameter("RSI Overbought Level", DefaultValue = 68)]
        public int RSIOverboughtLevel { get; set; }

        [Parameter("RSI Oversold Level", DefaultValue = 33)]
        public int RSIOversoldLevel { get; set; }

        [Parameter("MACD Fast EMA Period", DefaultValue = 12)]
        public int MacdFastPeriod { get; set; }
        
        [Parameter("MACD Slow EMA Period", DefaultValue = 26)]
        public int MacdSlowPeriod { get; set; }
        
        [Parameter("MACD Signal Smoothing Period", DefaultValue = 9)]
        public int MacdSignalPeriod { get; set; }
        
        [Parameter("EMA 10 Period", DefaultValue = 10)]
        public int EMA10Period { get; set; }
        
        [Parameter("EMA 50 Period", DefaultValue = 50)]
        public int EMA50Period { get; set; }

        [Parameter("EMA 200 Period", DefaultValue = 200)]
        public int EMA200Period { get; set; }

        [Parameter("ATR Period", DefaultValue = 14)]
        public int ATRPeriod { get; set; }

        [Parameter("Volume (Lots)", DefaultValue = 1.0)]
        public double Volume { get; set; }

        [Parameter("Trade Cooldown (Minutes)", DefaultValue = 1)]
        public int TradeCooldownMinutes { get; set; }
        
        [Parameter("Bollinger Bands Period", DefaultValue = 20)]
        public int BollingerPeriod { get; set; }

        [Parameter("Bollinger Bands Deviation", DefaultValue = 2.0)]
        public double BollingerDeviation { get; set; }
        
        public DataSeries Source { get; set; }
        [Output("Main")]
        
        private MacdHistogram macdHistogram;

        private Position lastTrade;
   
        protected override void OnStart()
        {
            supertrend10 = Indicators.Supertrend(SupertrendPeriod10, SupertrendMultiplier10);
            supertrend11 = Indicators.Supertrend(SupertrendPeriod11, SupertrendMultiplier11);
            supertrend12 = Indicators.Supertrend(SupertrendPeriod12, SupertrendMultiplier12);
            bollingerBands = Indicators.BollingerBands(MarketSeries.Close, BollingerPeriod, BollingerDeviation, MovingAverageType.Simple);
            ema10 = Indicators.ExponentialMovingAverage(MarketSeries.Close, EMA10Period);
            ema50 = Indicators.ExponentialMovingAverage(MarketSeries.Close, EMA50Period);
            ema200 = Indicators.ExponentialMovingAverage(MarketSeries.Close, EMA200Period);
            atr = Indicators.AverageTrueRange(ATRPeriod, MovingAverageType.Simple);
            lastTradeTime = MarketSeries.OpenTime.LastValue;
            rsi = Indicators.RelativeStrengthIndex(MarketSeries.Close, RSIPeriod);
            macdHistogram = Indicators.MacdHistogram(MarketSeries.Close, MacdFastPeriod, MacdSlowPeriod, MacdSignalPeriod);
            obv = Indicators.OnBalanceVolume(Source);

        }
     
        
        protected override void OnBar()
        {         

         
                int lastIndex = MarketSeries.Close.Count - 1;
                
                DateTime serverTime = Server.Time.ToLocalTime(); // Convert server time to local time
                
                            // Check if the current time is within the allowed trading window (8:00 AM - 17:00 AM)
                            if (!(serverTime.Hour >= 13 && serverTime.Hour < 22))
                            {
                        
                                return;
                            }
                              // Calculate the Average True Range (ATR)
                double atrValue1 = atr.Result[lastIndex];
                
                // Define the threshold for ATR to identify a ranging market
                double maxAtrForTrend = 0.0001; // Adjust as needed
                
                // Check if ATR is below the threshold, indicating a potential ranging market
                bool isRangingMarket = atrValue1 < maxAtrForTrend;
                
                // Avoid trading in a ranging market
                if (isRangingMarket)
                {
                    Print("Avoiding trade due to ranging market (low ATR).");
                    return;
                }
                
                // Define the maximum distance (in pips) between 10 EMA and 200 EMA for entering a trade
                double maxDistanceBetweenEMAs = 0.0012; // Adjust as needed
                
                // Check the distance between 10 EMA and 200 EMA
                double ema10DistanceTo200 = Math.Abs(ema10.Result[lastIndex] - ema200.Result[lastIndex]);
                
                // Convert the distance to pips
                double emaDistanceInPips = Symbol.PipSize * ema10DistanceTo200;
                
                // Check if the distance is less than the allowed threshold
                bool isEMADistanceValid = emaDistanceInPips < maxDistanceBetweenEMAs;
                
                // Avoid trading if the distance is too large
                if (!isEMADistanceValid)
                {
                    Print("Avoiding trade due to large distance between 10 EMA and 200 EMA.");
                    return;
                }

                 // Calculate the highest high and lowest low within a specified period
                int lookbackPeriod = 50; // Adjust the period as needed
                double highestHigh = MarketSeries.High.Maximum(lookbackPeriod);
                double lowestLow = MarketSeries.Low.Minimum(lookbackPeriod);
                
                bool isOverbought = rsi.Result.LastValue >= RSIOverboughtLevel;
                bool isOverSold = rsi.Result.LastValue <= RSIOversoldLevel;

                // Check conditions for Supertrend 10 (ATR 10, Multiplier 1)
                bool isUpTrend10 = supertrend10.UpTrend.IsRising();
                bool isDownTrend10 = supertrend10.DownTrend.IsFalling();

                // Check conditions for Supertrend 11 (ATR 11, Multiplier 2)
                bool isUpTrend11 = supertrend11.UpTrend.IsRising();
                bool isDownTrend11 = supertrend11.DownTrend.IsFalling();

                // Check conditions for Supertrend 12 (ATR 12, Multiplier 3)
                bool isUpTrend12 = supertrend12.UpTrend.IsRising();
                bool isDownTrend12 = supertrend12.DownTrend.IsFalling();

                // Check if the last 2 bars were above SMA for buy trade
                bool isAboveSMA10 = IsAboveSMA10(MarketSeries.Close, lastIndex, 2);
                
                bool isAboveSMA50 = IsAboveSMA50(MarketSeries.Close, lastIndex, 2);
                                
                bool isAboveSMA200 = IsAboveSMA200(MarketSeries.Close, lastIndex, 2);

                // Check if the last 2 bars were below SMA for sell trade
                bool IsBelowSMA10 = isBelowSMA10(MarketSeries.Close, lastIndex, 2);
                
                bool IsBelowSMA50 = isBelowSMA50(MarketSeries.Close, lastIndex, 2);
                
                bool IsBelowSMA200 = isBelowSMA200(MarketSeries.Close, lastIndex, 2);
                                
                 // Check Bollinger Bands conditions
                bool isAboveUpperBand = MarketSeries.Close[lastIndex] > bollingerBands.Top[lastIndex];
                bool isBelowLowerBand = MarketSeries.Close[lastIndex] < bollingerBands.Bottom[lastIndex];
                
                // Calculate the OBV values for the previous and current bars
                double prevOBV = obv.Result[1];
                double currentOBV = obv.Result[0];
                
                double minATR = 0.0005; // Set your desired minimum ATR value
                bool hasMinATR = atr.Result[lastIndex] > minATR;
                
                // Check OBV conditions
                bool isBullishOBV = currentOBV > prevOBV && prevOBV > obv.Result[1];
                bool isBearishOBV = currentOBV < prevOBV && prevOBV < obv.Result[2];
                
                // Check if the market is in a range-bound condition
                bool isMarketInARange = IsMarketInARange(lastIndex, 300); // Adjust the period as needed
                
                            // Calculate the range as a percentage of the Average True Range (ATR)
                double atrValue = atr.Result[lastIndex];
                double range = (highestHigh - lowestLow) / atrValue;
            
                // Define a threshold for how close to the highest high or lowest low you want to avoid trading
                double avoidThreshold = 0.2; // Example threshold, adjust as needed
                            
                // Check if the market is close to the highest high or lowest low
                bool isCloseToHighestHigh = MarketSeries.Close[lastIndex] > highestHigh - (atrValue * avoidThreshold);
                bool isCloseToLowestLow = MarketSeries.Close[lastIndex] < lowestLow + (atrValue * avoidThreshold);
         
                        // Open new positions for buy trade if all Supertrends are rising, and the last 10 bars were above SMA
                if (Positions.Count == 0 &&
                    isUpTrend10 && isUpTrend11 && isUpTrend12 &&
                    isAboveSMA10 &&
                     isAboveSMA50 &&
                     isAboveSMA200// &&
                   //isAboveUpperBand //&&

                   // !isCloseToHighestHigh &&
                   
                    // hasMinATR //&&
                   // Symbol.Spread < 1.1
                     &&  rsi.Result[lastIndex] < RSIOverboughtLevel
                       )
                {
         
                    // Buy signal (All Supertrends are rising, and the last 10 bars were above SMA)
                  ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.NormalizeVolumeInUnits(Symbol.LotSize), "Buy Order", STOPLOSS, TAKEPROFIT ,null,TRAILINGSTOPLOSS);
               
      
                }
                  if (Positions.Count == 0 &&
                    isDownTrend10 && isDownTrend11 && isDownTrend12 
                  &&  IsBelowSMA200 
                   &&  IsBelowSMA50 
                    &&  IsBelowSMA10 

                    // &&  
              //    &&  !isMarketInARange
                 //  isAboveUpperBand &&

              //     !isCloseToLowestLow &&
                   
                //     hasMinATR &&
               //      Symbol.Spread < 0.6
                     &&  rsi.Result[lastIndex] < RSIOversoldLevel
                       )
                {
        
                    // Sell signal (All Supertrends are rising, and the last 10 bars were above SMA)
                  ExecuteMarketOrder(TradeType.Sell, SymbolName, Symbol.NormalizeVolumeInUnits(Symbol.LotSize), "Sell Order", STOPLOSS, TAKEPROFIT ,null,TRAILINGSTOPLOSS);
      
                }
            
            
              }


        private bool IsMarketInARange(int index, int period)
        {
            // Calculate the range by finding the highest and lowest prices within the specified period
            double highestHigh = MarketSeries.High.Maximum(period);
            double lowestLow = MarketSeries.Low.Minimum(period);

            // Calculate the range as a percentage of ATR (you can adjust this threshold)
            double rangeThreshold = 1.5; // Example threshold, adjust as needed
            double atrValue = atr.Result[index];
            double range = (highestHigh - lowestLow) / atrValue;

            return range <= rangeThreshold;
        }

        private bool IsAboveSMA10(DataSeries series, int index, int period)
        {
            for (int i = 0; i < period; i++)
            {
                if (series[index - i] <= ema10.Result[index - i])
                {
                    return false;
                }
            }
            return true;
        }
              private bool IsAboveSMA50(DataSeries series, int index, int period)
        {
            for (int i = 0; i < period; i++)
            {
                if (series[index - i] <= ema50.Result[index - i])
                {
                    return false;
                }
            }
            return true;
        }
              private bool IsAboveSMA200(DataSeries series, int index, int period)
        {
            for (int i = 0; i < period; i++)
            {
                if (series[index - i] <= ema200.Result[index - i])
                {
                    return false;
                }
            }
            return true;
        }
        
           private bool isBelowSMA10(DataSeries series, int index, int period)
        {
            for (int i = 0; i < period; i++)
            {
                if (series[index - i] >= ema10.Result[index - i])
                {
                    return false;
                }
            }
            return true;
        }
              private bool isBelowSMA50(DataSeries series, int index, int period)
        {
            for (int i = 0; i < period; i++)
            {
                if (series[index - i] >= ema50.Result[index - i])
                {
                    return false;
                }
            }
            return true;
        }
              private bool isBelowSMA200(DataSeries series, int index, int period)
        {
            for (int i = 0; i < period; i++)
            {
                if (series[index - i] >= ema200.Result[index - i])
                {
                    return false;
                }
            }
            return true;
        }
   
    }
}
Leave a Comment