Overall Statistics
Total Trades
326
Average Win
0.05%
Average Loss
-0.07%
Compounding Annual Return
41.974%
Drawdown
5.600%
Expectancy
0.410
Net Profit
8.261%
Sharpe Ratio
1.796
Probabilistic Sharpe Ratio
61.645%
Loss Rate
18%
Win Rate
82%
Profit-Loss Ratio
0.72
Alpha
0.345
Beta
0.028
Annual Standard Deviation
0.195
Annual Variance
0.038
Information Ratio
0.277
Tracking Error
0.585
Treynor Ratio
12.425
Total Fees
$243.84
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;

namespace QuantConnect 
{   

    public class BasicTemplateAlgorithm : QCAlgorithm
    {
    	private OrderTicket EntryOrderUp1 { get; set; }
    	private OrderTicket EntryOrderUp2 { get; set; }
    	private OrderTicket EntryOrderUpLAST { get; set; }
        private Func<QCAlgorithm, string, decimal, DateTime, OneCancelsOtherTicketSetUp1> OnOrderFilledEventUp1 { get; set; }
        private Func<QCAlgorithm, string, decimal, DateTime, OneCancelsOtherTicketSetUp2> OnOrderFilledEventUp2 { get; set; }
        private OneCancelsOtherTicketSetUp1 ProfitLossOrdersUp1 { get; set; }
        private OneCancelsOtherTicketSetUp2 ProfitLossOrdersUp2 { get; set; }

    	public readonly TimeSpan BarPeriod1D = TimeSpan.FromMinutes(1440);
        public readonly int RollingWindowSize = 3;
        public readonly Dictionary<string, SymbolData1D> Data1D = new Dictionary<string, SymbolData1D>();

        public readonly IReadOnlyList<string> ForexSymbols = new List<string>
        {
            "EURUSD",
            "USDJPY",
            "EURGBP",
            "EURCHF",
            "USDCAD",
            "USDCHF",
            "AUDUSD",
            "NZDUSD",
        };

        
        /////////////////
		///////Average Spread
        int sprdEURUSD = 13 ;
		int sprdEURAUD = 30 ;
		int sprdEURNZD = 43 ;
		int sprdEURJPY = 20 ;
		int sprdEURCAD = 26 ;
		int sprdEURGBP = 23 ;
		int sprdEURSEK = 360 ;
		int sprdEURTRY = 780 ;
		
		////MArgin
		decimal MarEURUSD = 33.3m ;
		decimal MarEURAUD = 50m ;
		decimal MarEURNZD = 50m ;
		decimal MarEURJPY = 33.3m ;
		decimal MarEURCAD = 33.3m ;
		decimal MarEURCHF = 33.3m ;
		decimal MarEURGBP = 33.3m ;
		decimal MarEURSEK = 50m ;
		decimal MarEURTRY = 120m ;
		
		////PVALUE
		decimal PValue_EURUSD = 0.09m ;
		decimal PValue_EURAUD = 0.06m ;
		decimal PValue_EURNZD = 0.06m ;
		decimal PValue_EURJPY = 0.09m ;
		decimal PValue_EURCAD = 0.07m ;
		decimal PValue_EURCHF = 0.09m ;
		decimal PValue_EURGBP = 0.11m ;
		decimal PValue_EURSEK = 0.009m ;
		decimal PValue_EURTRY = 0.01m ;

        public override void Initialize() 
        {
            SetStartDate(2020,03, 1);         
            SetEndDate(DateTime.Now.Date.AddDays(-1));
            
            SetCash(250000);
            
            SetBrokerageModel(BrokerageName.FxcmBrokerage);

            foreach (var symbol in ForexSymbols)
            {
                var forex = AddForex(symbol);
                Data1D.Add(symbol, new SymbolData1D(forex.Symbol, BarPeriod1D, RollingWindowSize));
            }

            foreach (var kvp in Data1D)
            {
                var symbolData1D = kvp.Value;
                var consolidator1D = symbolData1D.Symbol.SecurityType == SecurityType.Equity
                    ? (IDataConsolidator)new TradeBarConsolidator(BarPeriod1D)
                    : (IDataConsolidator)new QuoteBarConsolidator(BarPeriod1D);
                consolidator1D.DataConsolidated += (sender, baseData) =>
                {
                    var bar = (IBaseDataBar)baseData;
                    symbolData1D.Bars.Add(bar);
                };
                SubscriptionManager.AddConsolidator(symbolData1D.Symbol, consolidator1D);
            }
        }


        public void OnData(Slice slice) 
        {   
        	
            foreach (var symbolData1D in Data1D.Values)
            {
                if (symbolData1D.IsReady && symbolData1D.WasJustUpdated(Time))
                {
                	bool BarPrecRed = symbolData1D.Bars[1].Open - symbolData1D.Bars[1].Close > 0 ;
                	bool BarPrecGreen = symbolData1D.Bars[1].Close - symbolData1D.Bars[1].Open > 0 ;
                	bool BarCurrentGreen = symbolData1D.Bars[0].Close - symbolData1D.Bars[0].Open > 0 ;
                	
                	bool Signal_Condition_Up =	BarCurrentGreen &&
                								(symbolData1D.Bars[0].Close - symbolData1D.Bars[0].Open > symbolData1D.Bars[0].Open * 0.001m)
                								;
                	
                	decimal UP_SL =  (symbolData1D.Bars[1].Close - symbolData1D.Bars[1].Low) ;
		        	decimal UP_TP1 =  (symbolData1D.Bars[1].Close - symbolData1D.Bars[1].Low) ;
		        	decimal UP_TP2 =  ((symbolData1D.Bars[1].Close - symbolData1D.Bars[1].Low) * 2) ;
		        	
		        	int quantity = (int)Math.Floor(Portfolio.Cash / 4);
		            int quantity_SL = quantity;
		            int quantity_TP1 = (int)Math.Floor(quantity * 0.25m);
		            int quantity_TP2 = (int)Math.Floor(quantity_TP1 * 1m);

		            if (Signal_Condition_Up && EntryOrderUp1 == null)
		            {
		                this.OnOrderFilledEventUp1 = (algo1, symbol, filledPrice, dt) =>
			            {
			            	return new OneCancelsOtherTicketSetUp1(
			            		algo1.LimitOrder(symbolData1D.Symbol, -quantity_TP1, filledPrice + UP_TP1, "TP1"),
								algo1.StopMarketOrder(symbolData1D.Symbol, -quantity_TP1, filledPrice - UP_SL, "SL_TP1"));
			             };
					     this.EntryOrderUp1 = MarketOrder(symbolData1D.Symbol, quantity_TP1, false, "Entry_TP1 : " + Time);
		            }
		            
					if (Signal_Condition_Up && EntryOrderUp2 == null)
		            {
		                this.OnOrderFilledEventUp2 = (algo2, symbol, filledPrice, dt) =>
			            {
			            	return new OneCancelsOtherTicketSetUp2(
			            		algo2.LimitOrder(symbolData1D.Symbol, -quantity_TP2, filledPrice + UP_TP2, "TP2"),
								algo2.StopMarketOrder(symbolData1D.Symbol, -quantity_TP2, filledPrice - UP_SL, "SL_TP2"));
			             };
					     this.EntryOrderUp2 = MarketOrder(symbolData1D.Symbol, quantity_TP2, false, "Entry_TP2 : " + Time);
		            }
		        }	
            }
        }

        
        public class SymbolData1D
        {
            public readonly Symbol Symbol;
            public readonly RollingWindow<IBaseDataBar> Bars;
            public readonly TimeSpan BarPeriod1D;

            public SymbolData1D(Symbol symbol, TimeSpan barPeriod1D, int windowSize)
            {
                Symbol = symbol;
                BarPeriod1D = barPeriod1D;
                Bars = new RollingWindow<IBaseDataBar>(windowSize);
            }

            public bool IsReady
            {
                get { return Bars.IsReady;}
            }

            public bool WasJustUpdated(DateTime current)
            {
                return Bars.Count > 0 && Bars[0].Time == current - BarPeriod1D;
            }
        }

        public override void OnOrderEvent(OrderEvent orderEvent)
        {
            if (EntryOrderUp1 != null)
            {
                this.EntryOrderUp1 = null;
            }
            
            if (EntryOrderUp2 != null)
            {
                this.EntryOrderUp2 = null;
            }

            if (orderEvent.Status == OrderStatus.Filled || orderEvent.Status == OrderStatus.PartiallyFilled)
            {
                if (this.OnOrderFilledEventUp1 != null)
                {
                    this.ProfitLossOrdersUp1 = OnOrderFilledEventUp1(this, orderEvent.Symbol, orderEvent.FillPrice, orderEvent.UtcTime);
                    OnOrderFilledEventUp1 = null;
                } 
	            else if (this.ProfitLossOrdersUp1 != null)
	                {
	                    this.ProfitLossOrdersUp1.Filled();
	                    this.ProfitLossOrdersUp1 = null;
	                }
            
                if (this.OnOrderFilledEventUp2 != null)
                {
                    this.ProfitLossOrdersUp2 = OnOrderFilledEventUp2(this, orderEvent.Symbol, orderEvent.FillPrice, orderEvent.UtcTime);
                    OnOrderFilledEventUp2 = null;
                } 
                else if (this.ProfitLossOrdersUp2 != null)
	                {
	                    this.ProfitLossOrdersUp2.Filled();
	                    this.ProfitLossOrdersUp2 = null;
	                }
            }
        }        
    }
}
using System.Linq;

namespace QuantConnect 
{
    public class OneCancelsOtherTicketSetUp1
    {
        public OneCancelsOtherTicketSetUp1(params OrderTicket[] orderTicketsUp1)
        {
            this.OrderTicketsUp1 = orderTicketsUp1;
        }

        private OrderTicket[] OrderTicketsUp1 { get; set; }

        public void Filled()
        {
            // Cancel all the outstanding tickets.
            foreach (var orderTicket in this.OrderTicketsUp1)
            {
                if (orderTicket.Status == OrderStatus.Submitted)
                {
                    orderTicket.Cancel();
                }
            }
    	}
    }
    
    public class OneCancelsOtherTicketSetUp2
    {
        public OneCancelsOtherTicketSetUp2(params OrderTicket[] orderTicketsUp2)
        {
            this.OrderTicketsUp2 = orderTicketsUp2;
        }

        private OrderTicket[] OrderTicketsUp2 { get; set; }

        public void Filled()
        {
            // Cancel all the outstanding tickets.
            foreach (var orderTicket in this.OrderTicketsUp2)
            {
                if (orderTicket.Status == OrderStatus.Submitted)
                {
                    orderTicket.Cancel();
                }
            }
    	}
    }
}