Overall Statistics |
Total Trades 566 Average Win 8.42% Average Loss -3.20% Compounding Annual Return 14.758% Drawdown 60.000% Expectancy 0.214 Net Profit 221.104% Sharpe Ratio 0.473 Loss Rate 67% Win Rate 33% Profit-Loss Ratio 2.63 Alpha NaN Beta NaN Annual Standard Deviation 0.435 Annual Variance 0.189 Information Ratio NaN Tracking Error NaN Treynor Ratio NaN Total Fees $1132.00 |
namespace QuantConnect { public class FXMomentumTests : QCAlgorithm { List<string> _symbols = new List<string>() { "EURUSD", "GBPUSD", "AUDUSD", "EURGBP", "EURJPY", "GBPAUD", "NZDUSD", "USDCAD", "USDCHF", "USDJPY" }; TradeBars _bars = new TradeBars(); private Dictionary<string, SymbolData> _symbolData = new Dictionary<string, SymbolData>(); //Initialize the data and resolution you require for your strategy: public override void Initialize() { //Start and End Date range for the backtest: SetStartDate(2007, 4, 1); SetEndDate(DateTime.Now.Date.AddDays(-1)); //Cash allocation SetCash(10000); foreach (var symbol in _symbols) { //Add as many securities as you like. All the data will be passed into the event handler: AddSecurity(SecurityType.Forex, symbol, Resolution.Daily); _symbolData.Add(symbol, new SymbolData(symbol, this)); } } //Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol. public void OnData(TradeBars data) { UpdateBars(data); if (_bars.Count != _symbols.Count) return; foreach (var _data in _symbolData.Values) { if(!_data._sd.IsReady) return; if(!_data._smaF.IsReady) return; if(!_data._smaS.IsReady) return; if(_data._sd > 0) { _data._q = _data._sd; } else { _data._q = 1; } Plot("Indicator "+_data.Symbol, "w", _data._q); if(Portfolio[_data.Symbol].IsLong && _data._smaF < _data._smaS) { Liquidate(_data.Symbol); } if(Portfolio[_data.Symbol].IsShort && _data._smaF > _data._smaS) { Liquidate(_data.Symbol); } //------------------------------------------------------------------------------------------ ENTRIES if (!Portfolio[_data.Symbol].Invested && _data._smaF > _data._smaS) { if(_data._sd != 0) { SetHoldings(_data.Symbol, 1); } } if (!Portfolio[_data.Symbol].Invested && _data._smaF < _data._smaS) { if(_data._sd != 0) { SetHoldings(_data.Symbol, -1); } } } } // end ondata //Update the global "_bars" object private void UpdateBars(TradeBars data) { foreach (var bar in data.Values) { if (!_bars.ContainsKey(bar.Symbol)) { _bars.Add(bar.Symbol, bar); } _bars[bar.Symbol] = bar; } } class SymbolData { //parameters int _fastPeriod = 20; int _slowPeriod = 120; public readonly string Symbol; public readonly SimpleMovingAverage _smaS; public readonly SimpleMovingAverage _smaF; public readonly StandardDeviation _sd; public decimal _q; public SymbolData(string symbol, QCAlgorithm algorithm) { Symbol = symbol; _smaF = algorithm.SMA(symbol, _fastPeriod, Resolution.Daily); _smaS = algorithm.SMA(symbol, _slowPeriod, Resolution.Daily); _sd = algorithm.STD(symbol, _fastPeriod, Resolution.Daily); _q = new decimal(); } } } // close algo }