Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
Portfolio Turnover
0%
#region imports
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using QuantConnect;
using QuantConnect.Brokerages;
using QuantConnect.Util;
using QuantConnect.Algorithm;
using QuantConnect.Indicators;
using QuantConnect.Data;
using QuantConnect.Orders;
using QuantConnect.Securities;
using QuantConnect.Securities.Forex;
#endregion

namespace Nelson.Corey.QC.Trendever
{
    public class Trendever : QCAlgorithm
    {
        private Forex _forex;
        private ExponentialMovingAverage _minEma;
        private ExponentialMovingAverage _hourMa;
        private ExponentialMovingAverage _dayMa;

        private ChartManager _chartManager;

        public override void Initialize()
        {
            SetTimeZone(TimeZones.NewYork);

            InitBroker();

            if (!LiveMode)
            {
                SetStartDate(Parameters.StartDate);
                SetEndDate(Parameters.EndDate);

                SetAccountCurrency(Parameters.StartingCurrency);
                SetCash("USD", 0);
                SetCash(Parameters.StartingCurrency, Parameters.StartingCash);
            }

            _forex = AddForex("USDJPY", Resolution.Minute, Market.Oanda);
            _minEma = EMA(_forex.Symbol, Parameters.HoursPeriod*60, Resolution.Minute);
            _hourMa = EMA(_forex.Symbol, Parameters.HoursPeriod, Resolution.Hour);
            _dayMa = EMA(_forex.Symbol, Parameters.HoursPeriod/24, Resolution.Daily);

            // _market = new QCMarketWrapper(this, _forexes);

            InitCharts();

            SetWarmUp(Parameters.HoursPeriod*60, Resolution.Minute);
        }

        private void InitBroker()
        {
            SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin);
            DefaultOrderProperties = new InteractiveBrokersOrderProperties
            {
                TimeInForce = TimeInForce.GoodTilCanceled,
                OutsideRegularTradingHours = false
            };
        }

        private void InitCharts()
        {
            _chartManager = new ChartManager(this);

            _chartManager.AddSecurity(_forex, Color.Green);
            _chartManager.AddIndicator(_minEma, Color.Red);
            _chartManager.AddIndicator(_hourMa, Color.Blue);
            _chartManager.AddIndicator(_dayMa, Color.Yellow);
        }

        public override void OnData(Slice data)
        {
            if (IsWarmingUp) return;

            if(_forex.Price == 0)
            {
                throw new InvalidOperationException($"Price is 0 for {_forex.Symbol}.");
            }

            _chartManager.UpdateCharts();
        }
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using QuantConnect;

namespace Nelson.Corey.QC.Trendever
{
    public static class Parameters
    {
        private const int hour = 60;
        private const int day = 24 * hour;

        // Misc.
        public static readonly DateTime StartDate = new(2023, 12, 02);
        public static readonly DateTime EndDate = new(2023, 12, 08);

        public static readonly string StartingCurrency = "CAD";
        public static readonly decimal StartingCash = 50000;

        public static readonly int ChartUpdateHours = 1;

        public static readonly List<string> CurrencyPairs = new()
        {
            "AUD.USD", "USD.CAD", "USD.CNH", "EUR.USD", "USD.JPY", "USD.MXN", "USD.NOK", "USD.SEK", "USD.ZAR"
        };

        public static readonly int HoursPeriod = 4320;


        public static decimal LotSizeUsd = 100000;
        public static decimal LotToleranceUsd = 1000;
    }
}
#region imports
using System.Collections.Generic;
using System.Drawing;
using QuantConnect;
using QuantConnect.Indicators;
using QuantConnect.Securities;
#endregion

namespace Nelson.Corey.QC.Trendever
{
    public class ChartManager
    {
        private readonly Trendever _algo;
        private readonly Chart _nsiChart, _debugChart;

        private const string FillsSeriesName = "Fills";

        private readonly Dictionary<Security, Color> _securities = new();
        private readonly Dictionary<IndicatorBase, Color> _indicators = new();

        public ChartManager(Trendever algo)
        {
            _algo = algo;

            _nsiChart = new Chart("NSI");
            _algo.AddChart(_nsiChart);

            _debugChart = new Chart("Debug");
            _algo.AddChart(_debugChart);
        }

        private void CreateSeries(string name, in Color color)
        {
            var chart = name.Contains("EMA(") ? _debugChart : _nsiChart;
            chart.AddSeries(new Series(name, SeriesType.Line, "%", color));
        }

        internal void AddIndicator(IndicatorBase indicator, in Color color)
        {
            _indicators[indicator] = color;
            CreateSeries(indicator.Name, color);
        }

        internal void AddSecurity(Security security, in Color color)
        {
            _securities[security] = color;
            _nsiChart.AddSeries(new Series(security.Symbol.Value, SeriesType.Line, "$", color));
        }

         internal void UpdateCharts()
        {
            if (_algo.Time.Minute % 60 == 0 && _algo.Time.Hour % Parameters.ChartUpdateHours == 0)
            {
                foreach(var s in _securities.Keys) {
                    _algo.Plot(_debugChart.Name, s.Symbol.Value, s.Price);
                }

                foreach(var i in _indicators){
                    var chart = i.Key.Name.Contains("EMA(") ? _debugChart : _nsiChart;
                    _algo.Plot(chart.Name, i.Key.Name, i.Key.Current);
                }
            }
        }
    }
}