Overall Statistics
Total Trades
1
Average Win
0%
Average Loss
0%
Compounding Annual Return
-6.990%
Drawdown
8.900%
Expectancy
0
Net Profit
0%
Sharpe Ratio
-0.585
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0.022
Beta
-0.315
Annual Standard Deviation
0.079
Annual Variance
0.006
Information Ratio
-2.299
Tracking Error
0.115
Treynor Ratio
0.148
Total Fees
$2.00
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using System;
using System.Linq;

namespace QuantConnect.Algorithm.CSharp
{
    public class QCUMovingAverageCross : QCAlgorithm
    {
        int cnt = 0;
        const decimal tolerance = 0.00015m;
        private const string ticker = "EURUSD";
        Symbol symbol;
        private AverageTrueRange atr;

        private SimpleMovingAverage ma100_h1;
        private SimpleMovingAverage ma100_m30;
        private SimpleMovingAverage ma100_m15;
        private SimpleMovingAverage ma50_m30;

        public override void Initialize()
        {
            // set up our analysis span
            SetStartDate(2016, 11, 01);
            SetEndDate(2017, 03, 15);
            SetCash(1000);

            symbol = AddForex(ticker, market: Market.Oanda).Symbol;

            ma100_h1 = SMA(symbol, 100, Resolution.Hour);
            ma100_m15 = new SimpleMovingAverage(100);
            ma50_m30 = new SimpleMovingAverage(50);
            ma100_m30 = new SimpleMovingAverage(100);

            /*var fifteenMinuteConsolidator = new QuoteBarConsolidator(TimeSpan.FromMinutes(15));
            SubscriptionManager.AddConsolidator(symbol, fifteenMinuteConsolidator);
            fifteenMinuteConsolidator.DataConsolidated += FifteenMinuteConsolidator_DataConsolidated; ;*/

            var thirtyMinuteConsolidator = new QuoteBarConsolidator(TimeSpan.FromMinutes(30));
            SubscriptionManager.AddConsolidator(symbol, thirtyMinuteConsolidator);
            thirtyMinuteConsolidator.DataConsolidated += ThirtyMinuteConsolidator_DataConsolidated; ;

            atr = ATR(symbol, 360, MovingAverageType.Simple, Resolution.Minute);

            SetWarmUp(TimeSpan.FromDays(1));
        }

        private void FifteenMinuteConsolidator_DataConsolidated(object sender, QuoteBar e)
        { 
            
        }

        private void ThirtyMinuteConsolidator_DataConsolidated(object sender, QuoteBar e)
        {
        	ma100_h1.Update(new IndicatorDataPoint { Time = e.Time, Value = e.Value });
        	ma100_m15.Update(new IndicatorDataPoint { Time = e.Time, Value = e.Value });
            ma50_m30.Update(new IndicatorDataPoint { Time = e.Time, Value = e.Value });
            ma100_m30.Update(new IndicatorDataPoint { Time = e.Time, Value = e.Value });
            //atr.Update(new IndicatorDataPoint { Time = e.Time, Value = e.Value });
        }

        //private DateTime previous;

        public override void OnData(Slice data)
        {
            if (IsWarmingUp || !data.ContainsKey(symbol)) return;

            var atrLoss = atr * 3.3m;
            var atrProfit = atr * 1.5m;
            var stopLossLong = Securities[symbol].Price - atrLoss;
            var takeProfitLong = Securities[symbol].Price + atrProfit;
            var stopLossShort = Securities[symbol].Price + atrLoss;
            var takeProfitShort = Securities[symbol].Price - atrProfit;
            
            // Here you can use LINQ to select the tickets you need.
            var openLongOrderTicket = Transactions.GetOrderTickets(o => o.Status == OrderStatus.Filled && o.Quantity > 0)
                .FirstOrDefault();
                
            var openShortOrderTicket = Transactions.GetOrderTickets(o => o.Status == OrderStatus.Filled && o.Quantity < 0)
                .FirstOrDefault();

            if (enterLong() && Portfolio[symbol].Quantity == 0)//!Portfolio[symbol].Invested)
            {
            	
                Debug("long " + Securities[symbol].Price + " SL: " + stopLossLong + " TP: " + takeProfitLong);
                openLongOrderTicket = StopLimitOrder(symbol, 1000, stopLossLong, takeProfitLong, "test"); //minimum FXCM ordersize = 1K = 1000
                
                Debug(Portfolio[symbol].Quantity.ToString());
                //Debug(cnt.ToString());
            }
            
            if (enterShort() && (Portfolio[symbol].Quantity == 0))
            {
            	Debug(Portfolio[symbol].Quantity.ToString());
                Debug("short " + Securities[symbol].Price + " SL: " + stopLossShort + " TP: " + takeProfitShort);
                openShortOrderTicket = StopLimitOrder(symbol, -1000, stopLossShort, takeProfitShort, "test");
                
                Debug(Portfolio[symbol].Quantity.ToString());
                //Debug(cnt.ToString());
            }

            if (openLongOrderTicket != null)
            {
                var stopPrice = openLongOrderTicket.Get(OrderField.StopPrice);
                

                if (stopPrice < stopLossLong)
                {
                	//Debug(Portfolio.CashBook["USD"].Amount.ToString());
                    openLongOrderTicket.Update(new UpdateOrderFields { StopPrice = stopLossLong });
                }
                
            
            }
            
            if (openShortOrderTicket != null)
            {
                var stopPrice = openShortOrderTicket.Get(OrderField.StopPrice);
                if (stopPrice > stopLossShort)
                {
                	//Debug(Portfolio.CashBook["USD"].Amount.ToString());
                    openShortOrderTicket.Update(new UpdateOrderFields { StopPrice = stopLossShort });
                }
                
     
            }
            
            cnt++;
            if (cnt%2000 == 0)
            {
            	Debug(Securities[symbol].Price.ToString());
            }
        }

        public override void OnOrderEvent(OrderEvent orderEvent)
        {
            switch (orderEvent.Status)
            {
                case OrderStatus.New:
                    break;
                case OrderStatus.Submitted:
                    break;
                case OrderStatus.PartiallyFilled:
                    break;
                case OrderStatus.Filled:
                    break;
                case OrderStatus.Canceled:
                    break;
                case OrderStatus.None:
                    break;
                case OrderStatus.Invalid:
                    break;
                case OrderStatus.CancelPending:
                    break;
                default:
                    break;
            }
        }

        public override void OnEndOfDay()
        {
            Log("EOD " + Time.ToShortDateString());
        }

        private bool enterLong()
        {
            var price = Securities[symbol].Price;

            if ((price > ma100_h1 * (1 + tolerance)) &&
                (price > ma100_m30 * (1 + tolerance)) &&
                (price > ma100_m15 * (1 + tolerance)) &&
                (ma100_m30 > ma50_m30))
            {
                return true;
            }

            return false;
        }
        
        private bool enterShort()
        {
            var price = Securities[symbol].Price;

            if ((price < ma100_h1 * (1 + tolerance)) &&
                (price < ma100_m30 * (1 + tolerance)) &&
                (price < ma100_m15 * (1 + tolerance)) &&
                (ma100_m30 < ma50_m30))
            {
                return true;
            }

            return false;
        }
    }
}
namespace QuantConnect {

    //
    //	Make sure to change "BasicTemplateAlgorithm" to your algorithm class name, and that all
    //	files use "public partial class" if you want to split up your algorithm namespace into multiple files.
    //

    //public partial class BasicTemplateAlgorithm : QCAlgorithm, IAlgorithm
    //{
    //  Extension functions can go here...(ones that need access to QCAlgorithm functions e.g. Debug, Log etc.)
    //}

    //public class Indicator 
    //{
    //  ...or you can define whole new classes independent of the QuantConnect Context
    //}

}
namespace QuantConnect {

    //
    //	Make sure to change "BasicTemplateAlgorithm" to your algorithm class name, and that all
    //	files use "public partial class" if you want to split up your algorithm namespace into multiple files.
    //

    //public partial class BasicTemplateAlgorithm : QCAlgorithm, IAlgorithm
    //{
    //  Extension functions can go here...(ones that need access to QCAlgorithm functions e.g. Debug, Log etc.)
    //}

    //public class Indicator 
    //{
    //  ...or you can define whole new classes independent of the QuantConnect Context
    //}

}