Overall Statistics
Total Trades
367
Average Win
0.11%
Average Loss
-0.11%
Compounding Annual Return
-2.164%
Drawdown
13.100%
Expectancy
-0.268
Net Profit
-6.358%
Sharpe Ratio
-0.485
Probabilistic Sharpe Ratio
0.109%
Loss Rate
64%
Win Rate
36%
Profit-Loss Ratio
1.01
Alpha
-0.015
Beta
-0.03
Annual Standard Deviation
0.031
Annual Variance
0.001
Information Ratio
-0.302
Tracking Error
0.069
Treynor Ratio
0.491
Total Fees
$170.09
Estimated Strategy Capacity
$480000.00
Lowest Capacity Asset
USDCNH 8G
using QuantConnect.Algorithm.Framework;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Risk;
using QuantConnect.Brokerages;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using QuantConnect.Securities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QuantConnect.Algorithm.CSharp.Btfd
{
    public class China : QCAlgorithm
    {
        public override void Initialize()
        {
            int startYear = int.Parse(GetParameter("START_YEAR"));
            int endYear = int.Parse(GetParameter("END_YEAR"));

            var forex = AddForex("USDCNH", Resolution.Daily);
            AddEquity("SPY", Resolution.Daily, Market.USA);

            SetStartDate(new DateTime(startYear, 1, 1));
            SetEndDate(new DateTime(endYear, 1, 1));
            SetCash(100000);

            UniverseSettings.Resolution = Resolution.Daily;
            SetWarmup(new TimeSpan(365, 0, 0, 0));
            EnableAutomaticIndicatorWarmUp = true;

            SetBrokerageModel(BrokerageName.FxcmBrokerage);

            AddAlpha(new ChinaAlpha(forex, this));
            SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
            SetExecution(new ImmediateExecutionModel());
            AddRiskManagement(new MaximumUnrealizedProfitPercentPerSecurity(0.1m));
        }


        private class ChinaAlpha : AlphaModel
        {
            private readonly Maximum _spyHigh;
            private readonly Minimum _spyLow;
            private readonly Security _forexSecurity;

            public ChinaAlpha(Security forexSecurity, QCAlgorithm algo)
            {
                _forexSecurity = forexSecurity;
                var spy = algo.Securities["SPY"].Symbol;
                _spyHigh = new Maximum(253);
                _spyLow = new Minimum(253);
                algo.RegisterIndicator(spy, _spyHigh, Resolution.Daily);
                algo.RegisterIndicator(spy, _spyLow, Resolution.Daily);
            }

            public override IEnumerable<Insight> Update(QCAlgorithm algo, Slice data)
            {
                List<Insight> insights = new List<Insight>();
                decimal currentSpyPrice = algo.Securities["SPY"].Price;
                if (currentSpyPrice >= _spyHigh.Current.Value)
                {
                    // Passed 52 week high
                    // if not already, short forex
                    if (algo.Securities[_forexSecurity.Symbol].Holdings.IsLong || !algo. Portfolio.Invested)
                    {
                        insights.Add(new Insight(_forexSecurity.Symbol, new TimeSpan(30,0,0,0), InsightType.Price, InsightDirection.Down));
                    }
                }
                else if (currentSpyPrice == _spyLow.Current.Value)
                {
                    // Passed 52 week low
                    // if not already, long forex
                    if (!algo.Securities[_forexSecurity.Symbol].Holdings.IsLong || !algo.Portfolio.Invested)
                    {
                        insights.Add(new Insight(_forexSecurity.Symbol, new TimeSpan(30, 0, 0, 0), InsightType.Price, InsightDirection.Up));
                    }
                }
                return insights;
            }
        }

        //private class TakeProfitRiskManagement : RiskManagementModel
        //{
        //    private Dictionary<Symbol, decimal> _purchasePrices = new Dictionary<Symbol, decimal>();
        //    private decimal _returnPercentage;

        //    public TakeProfitRiskManagement(decimal returnPercentage = 0.1m)
        //    {
        //        _returnPercentage = returnPercentage;
        //    }

        //    public override IEnumerable<IPortfolioTarget> ManageRisk(QCAlgorithm algorithm, IPortfolioTarget[] targets)
        //    {
        //        ManagePurchasePrices(algorithm);
        //        List<PortfolioTarget> portfolioTargets = new List<PortfolioTarget>();
        //        foreach (var security in algorithm.ActiveSecurities)
        //        {
        //            Symbol symbol = security.Key;
        //            if (algorithm.Securities[symbol].Invested)
        //            {
        //                decimal purchasePrice = _purchasePrices[symbol];
        //                decimal currentPrice = algorithm.Securities[symbol].Price;
        //                var currentReturn = ((currentPrice - purchasePrice) / purchasePrice) * 100.0m;
        //                if (currentReturn >= _returnPercentage)
        //                {
        //                    PortfolioTarget newTarget = new PortfolioTarget(symbol, 0);
        //                    portfolioTargets.Add(newTarget);
        //                }
        //            }
        //        }
        //        return portfolioTargets;
        //    }

        //    private void ManagePurchasePrices(QCAlgorithm algorithm)
        //    {
        //        foreach (var security in algorithm.ActiveSecurities)
        //        {
        //            Symbol symbol = security.Key;
        //            if (algorithm.Securities[symbol].Invested)
        //            {
        //                // If we havn't recorded the purchase price, we add it
        //                if (!_purchasePrices.ContainsKey(symbol))
        //                {
        //                    decimal purchasePrice = algorithm.Securities[symbol].Price;
        //                    _purchasePrices.Add(symbol, purchasePrice);
        //                }
        //            }
        //            else
        //            {
        //                if (!algorithm.Securities[symbol].Invested)
        //                {
        //                    // If the price is not invested, we remove it from the prices dictionary
        //                    if (_purchasePrices.ContainsKey(symbol))
        //                    {
        //                        _purchasePrices.Remove(symbol);
        //                    }
        //                }
        //            }
        //        }

        //    }
        //}

        //private class TakeProfitRiskManagement2 : RiskManagementModel
        //{
        //    private decimal _purchasePrice;
        //    private bool _isInvested = false;
        //    private Security _security;

        //    public TakeProfitRiskManagement2(Security security)
        //    {
        //        _security = security;
        //    }

        //    public override IEnumerable<IPortfolioTarget> ManageRisk(QCAlgorithm algo, IPortfolioTarget[] targets)
        //    {
        //        List<IPortfolioTarget> adjustedTargets = new List<IPortfolioTarget>();
        //        var currency = algo.Securities[_security.Symbol];
        //    }

        //    public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
        //    {
        //        if (changes.AddedSecurities.Contains(_security))
        //        {
        //            _isInvested = true;
        //            _purchasePrice = algorithm.Securities[_security.Symbol].Price;
        //        }
        //        else if(changes.RemovedSecurities.Contains(_security))
        //        {
        //            _isInvested = false;
        //        }
        //    }
        //}
    }
}