New Features in cTrader Automate API 3.7

New Features in cTrader Automate API 3.7

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class EMA_2Cross_1Trend_RR : Robot
    {
        [Parameter("Fix Vol Trade", DefaultValue = true, Group = "Trade")]
        public bool FixVolTrade { get; set; }

        [Parameter("PerStart", DefaultValue = 1, Group = "Trade", MinValue = 1)]
        public int PerStart { get; set; }

        [Parameter("TradeWay", Group = "Trade", DefaultValue = TradeOnlyWay.Both)]
        public TradeOnlyWay WantTradeWay { get; set; }

        [Parameter("TP", Group = "Trade", DefaultValue = 50, MinValue = 1)]
        public int TP { get; set; }

        [Parameter("SL", Group = "Trade", DefaultValue = 25, MinValue = 1)]
        public int SL { get; set; }

        [Parameter("MaxOpen", Group = "Trade", DefaultValue = 1, MinValue = 1)]
        public int MaxOpen { get; set; }

        [Parameter("SymBol To Trade", Group = "Trade", DefaultValue = "AUDCAD,AUDCHF,AUDJPY,AUDNZD,AUDSGD,AUDUSD,CADCHF,CADJPY,CHFJPY,CHFSGD,EURAUD,EURCAD,EURCHF,EURGBP,EURJPY,EURNZD,EURSGD,EURUSD,GBPAUD,GBPCAD,GBPCHF,GBPJPY,GBPNZD,GBPSGD,GBPUSD,NZDCAD,NZDCHF,NZDJPY,NZDUSD,SGDJPY,USDCAD,USDCHF,USDJPY,USDSGD")]
        public string SymBolToTrade { get; set; }

        [Parameter("Strategies name", Group = "Trade", DefaultValue = "EMA_2Cross_1Trend_RR")]
        public string StrategiesName { get; set; }


        #region EMA


        [Parameter("EMA 1 Source", Group = "EMA")]
        public DataSeries EMA1Source { get; set; }

        [Parameter("EMA 1 Periods", Group = "EMA", DefaultValue = 9)]
        public int EMA1_Period { get; set; }

        [Parameter("EMA 2 Source", Group = "EMA")]
        public DataSeries EMA2Source { get; set; }

        [Parameter("EMA 2 Periods", Group = "EMA", DefaultValue = 21)]
        public int EMA2_Period { get; set; }

        [Parameter("EMA 2 Source", Group = "EMA")]
        public DataSeries EMA3Source { get; set; }

        [Parameter("EMA 3 Periods", Group = "EMA", DefaultValue = 200)]
        public int EMA3_Period { get; set; }


        #endregion

        List<Symbol> lsSymbol = new List<Symbol>();
        Dictionary<Symbol, Bars> dicSymbolBar = new Dictionary<Symbol, Bars>();
        Dictionary<Symbol, ExponentialMovingAverage> dicEMA1 = new Dictionary<Symbol, ExponentialMovingAverage>();
        Dictionary<Symbol, ExponentialMovingAverage> dicEMA2 = new Dictionary<Symbol, ExponentialMovingAverage>();
        Dictionary<Symbol, ExponentialMovingAverage> dicEMA3 = new Dictionary<Symbol, ExponentialMovingAverage>();

        List<TradeLog> _tradeLogs = new List<TradeLog>();
        double StartBalance = 0;

        protected override void OnStart()
        {
            Print("Start OnStart");

            StartBalance = Account.Balance;

            Positions.Opened += PositionsOnOpened;
            Positions.Closed += PositionsOnClosed;

            LoadSymbolsDataAndIndi();

            Print("End OnStart");
        }

        private void LoadSymbolsDataAndIndi()
        {
            try
            {
                //แยกคู่ที่ต้องการเทรดด้วย ,
                var AllSymbol = SymBolToTrade.Split(',').ToList();

                //List<Task> lsTask = new List<Task>();
                foreach (var sSymbol in AllSymbol)
                {
                    //Task aTask = new Task(() =>
                    //{
                    var bar = MarketData.GetBars(TimeFrame, sSymbol);
                    var aSymbolBars = MarketData.GetBars(TimeFrame, sSymbol);
                    var aSymbol = Symbols.GetSymbol(sSymbol);

                    lsSymbol.Add(aSymbol);
                    dicSymbolBar.Add(aSymbol, aSymbolBars);
                    dicEMA1.Add(aSymbol, Indicators.ExponentialMovingAverage(aSymbolBars.ClosePrices, EMA1_Period));
                    dicEMA2.Add(aSymbol, Indicators.ExponentialMovingAverage(aSymbolBars.ClosePrices, EMA2_Period));
                    dicEMA3.Add(aSymbol, Indicators.ExponentialMovingAverage(aSymbolBars.ClosePrices, EMA3_Period));

                    Print("Finished get data >> " + sSymbol);
                    //});
                    //lsTask.Add(aTask);
                    //aTask.Start();
                }
                //Task.WaitAll(lsTask.ToArray());
            } catch (Exception ex)
            {
                Print("ERROR LoadSymbolsDataAndIndi : " + ex.Message);
            }
        }

protected override void OnBar()
        {
            try
            {
                List<Task> lsTask = new List<Task>();
                foreach (var symbol in lsSymbol)
                {
                    //แตก thread แยกตามคู่เงิน
                    Task aTask = new Task(() =>
                    {
                        //ema1 ตัด ema2 *ลง*  && ย้อนหลังไปสองแท่งที่ยังไม่ตัดลง EMA1 ยังต้อง*มากกว่า* 2 ด้วย ไม่งั้นมันจะเข้าออเดอร์ทุกๆแท่งเอาได้  *หรือเราจะไปเช็คว่ามีออเดอร์เปิดแล้วก็ไม่ให้เปิดดีกว่านะ
                        if (dicEMA1.Where(x=>x.Key == symbol).First().Value.Result.Last(1) <= dicEMA2.Where(x => x.Key == symbol).First().Value.Result.Last(1) && dicEMA1.Where(x => x.Key == symbol).First().Value.Result.Last(2) > dicEMA2.Where(x => x.Key == symbol).First().Value.Result.Last(2))
                        {
                            //EMA 1 & 2 ต้องอยู่*ใต้* 3 ด้วย
                            if (dicEMA1.Where(x=>x.Key == symbol).First().Value.Result.Last(1) <= dicEMA3.Where(x=>x.Key == symbol).First().Value.Result.Last(1) && dicEMA2.Where(x=>x.Key == symbol).First().Value.Result.Last(1) <= dicEMA3.Where(x=>x.Key == symbol).First().Value.Result.Last(1))
                            {
                                //*ยังไม่เช็คว่ามีออเดอร์เปิดอยู่แล้ว เปิดเพิ่มได้ กรณียังไม่ tp หรือ SL แต่มันวกมาตัดขึ้น-ลงเพิ่มอีกก็เป็นไปได้
                                //เช็คกับการตั้งค่าว่าให้เล่นแต่ขาไหน จะเข้า *sell* แต่ถ้าจะเล่นแต่ขา *buy* เราก็จะไม่เปิด
                                if (WantTradeWay != TradeOnlyWay.Buy)
                                {
                                    //เช็คกรณีว่าเปิดไปแล้วกี่ไม้ และจะไม่ให้เปิดอีก เช็คเฉพาะขานั้นด้วย เพราะมีสิทธิ์มีสองขาเปิดพร้อมกันอยู่
                                    if (Positions.Where(x => x.TradeType == TradeType.Sell).Count() >= MaxOpen)
                                    {
                                        return;
                                    }
                                    ExecuteMarketOrder(TradeType.Sell, SymbolName, Symbol.NormalizeVolumeInUnits((FixVolTrade ? StartBalance : Account.Balance) * PerStart), StrategiesName, SL, TP, "");
                                }
                            }
                        }.......