Overall Statistics |
Total Trades 346 Average Win 0.80% Average Loss -0.32% Compounding Annual Return -0.340% Drawdown 9.900% Expectancy -0.035 Net Profit -2.026% Sharpe Ratio -0.053 Probabilistic Sharpe Ratio 0.208% Loss Rate 72% Win Rate 28% Profit-Loss Ratio 2.48 Alpha -0.001 Beta -0.005 Annual Standard Deviation 0.038 Annual Variance 0.001 Information Ratio -0.844 Tracking Error 0.124 Treynor Ratio 0.387 Total Fees $0.00 |
using QuantConnect.Indicators.CandlestickPatterns; namespace QuantConnect.Algorithm.CSharp { public partial class TestAlgo : QCAlgorithm { //**************************************************************************************************************************************** // INITIALIASE BLOCK //**************************************************************************************************************************************** public override void Initialize() { SetStartDate(2014, 1, 1); SetEndDate(2019, 12, 31); SetAccountCurrency(_AccountCurrency); SetCash(_StartingCash); // Loop through our list of symbols and add them to our subscription manager foreach (var _symbol in _MySymbolList) { var _Forex = AddForex(_symbol, _Res, Market.Oanda, true, 20m); DataDico.Add(_symbol, new SymbolData(this, _Forex.Symbol, _Forex.BaseCurrencySymbol)); } _Drawdown_EMA = new ExponentialMovingAverage(30); SetWarmUp(TimeSpan.FromDays(_WarmUpPeriod)); SetBrokerageModel(BrokerageName.OandaBrokerage, AccountType.Margin); } //**************************************************************************************************************************************** // ONDATA BLOCK //**************************************************************************************************************************************** public override void OnData(Slice data) { //Loop through our dictionary foreach (var symbolData in DataDico.Values) { if(!data.ContainsKey(symbolData.Symbol)) { return; } //Check if algorithm is warming up and if indicators are ready, if not break if(IsWarmingUp) { return; } if(!symbolData.IsReady()) { return; } if(!symbolData.ConsolidatorFlag) { return; } symbolData.ConsolidatorFlag = false; //Update prices for dummy entry logic symbolData.Price_P2 = symbolData.Price_P1; symbolData.Price_P1 = symbolData.Price; symbolData.Price = data[symbolData.Symbol].Close; //Drawdown Calculation - Portfolio Level _TotalEquity_P1 = _TotalEquity; _TotalEquity = Portfolio.TotalPortfolioValue; _CumulativeReturn_P1 = _CumulativeReturn; try { _CumulativeReturn = (1 + _CumulativeReturn_P1) * (1 + (_TotalEquity/_TotalEquity_P1 - 1)) - 1; } catch (DivideByZeroException) { _CumulativeReturn = 0m; } _HighWatermark = Math.Max(_HighWatermark, _CumulativeReturn); _Drawdown = (1 + _CumulativeReturn) / (1 + _HighWatermark) - 1; _MaxDrawdown = Math.Min(_MaxDrawdown, _Drawdown); _Drawdown_EMA.Update(data[symbolData.Symbol].EndTime, _Drawdown); Plot($"Portfolio Equity Curve", "Cumulative Return", _CumulativeReturn); Plot($"Portfolio Equity Curve", "Drawdown", _Drawdown); Plot($"Portfolio Equity Curve", "Drawdown EMA", _Drawdown_EMA); Plot($"Portfolio Equity Curve", "High Watermark", _HighWatermark); Plot($"Portfolio Equity Curve", "Max Drawdown", _MaxDrawdown); //Dummy entry logic / exit logic if (!Portfolio[symbolData.Symbol].Invested && symbolData.ROC > 0.015m && symbolData.Price_P2 < symbolData.Price_P1 && symbolData.Price < symbolData.Price_P1 && symbolData.Price > symbolData.Price_P2) { symbolData.Holding = Math.Round(_TotalEquity / symbolData.Price, 6); MarketOrder(symbolData.Symbol, symbolData.Holding); } if(Portfolio.Invested && symbolData.Price_P2 > symbolData.Price_P1 && symbolData.Price_P1 > symbolData.Price) { symbolData.Holding = Portfolio[symbolData.Symbol].Quantity; MarketOrder(symbolData.Symbol, -symbolData.Holding); } } } } }
namespace QuantConnect.Algorithm.CSharp { public partial class TestAlgo : QCAlgorithm { //**************************************************************************************************************************************** //USER VARIABLES //**************************************************************************************************************************************** private static string _AccountCurrency = "USD"; private static decimal _StartingCash = 100000m; Resolution _Res = Resolution.Hour; // Reference resolution for our custom TradeBar private int _WarmUpPeriod = 200; public decimal _PctRisk = 0.10m; private decimal _StopLossPct = 0.05m; //***Symbol List*** Dictionary <string, SymbolData> DataDico = new Dictionary <string, SymbolData>(); List <string> _MySymbolList = new List <string> { "EURUSD", "USDJPY", "GBPUSD", "USDCAD", }; //***Indicators*** public static int _ROCperiod = 30; //***Portfolio Variables for Drawdown calculation*** private decimal _TotalEquity; private decimal _TotalEquity_P1; private decimal _CumulativeReturn; private decimal _CumulativeReturn_P1; private decimal _HighWatermark; private decimal _Drawdown; private ExponentialMovingAverage _Drawdown_EMA; private decimal _MaxDrawdown; private decimal _TotalEquity2; } }
namespace QuantConnect.Algorithm.CSharp { public partial class TestAlgo : QCAlgorithm { public class SymbolData { //***Consolidator parameters*** public static int barPerTimeSpan = 24; // Number of block of data per custum TradeBar public readonly TimeSpan barPeriod = TimeSpan.FromHours(barPerTimeSpan); // Set the size of our custum TradeBar public QuoteBarConsolidator Consolidator; public bool ConsolidatorFlag = false; // Flag whether a new custom TradeBar has been fully consolidated; used to prevent ONDATA block code to be executed otherwise //***General*** public readonly QCAlgorithm algorithm; public readonly Symbol Symbol; public readonly string BaseSymbol; public readonly string AccountSymbol; public readonly RollingWindow<IBaseDataBar> BarsWin; public readonly int windowSize = 5; public decimal Holding; public decimal Price; public decimal Price_P1; public decimal Price_P2; //***Indicators*** public RateOfChange ROC; //***SymbolData class constructor which initializes a new instance of SymbolData*** public SymbolData(QCAlgorithm algorithm, Symbol symbol, string baseSymbol) { this.algorithm = algorithm; Symbol = symbol; BaseSymbol = baseSymbol; Consolidator = new QuoteBarConsolidator(barPeriod); BarsWin = new RollingWindow<IBaseDataBar>(windowSize); ROC = new RateOfChange(Symbol, _ROCperiod); Consolidator.DataConsolidated += (sender, baseData) => { var _bar = (IBaseDataBar)baseData; ConsolidatorFlag = true; BarsWin.Add(_bar); ROC.Update(_bar.Time, _bar.Close); }; algorithm.SubscriptionManager.AddConsolidator(symbol, Consolidator); // Adding this consolidator to the Subscription Manager so it gets auto updates } //***Returns true if all the data in this instance is ready*** public bool IsReady() { return BarsWin.IsReady && ROC.IsReady; } } } }