Overall Statistics |
Total Trades 267 Average Win 3.22% Average Loss -2.35% Compounding Annual Return 1395.634% Drawdown 25.700% Expectancy 0.550 Net Profit 388.278% Sharpe Ratio 2.706 Loss Rate 35% Win Rate 65% Profit-Loss Ratio 1.37 Alpha 2.214 Beta -0.494 Annual Standard Deviation 0.797 Annual Variance 0.636 Information Ratio 2.515 Tracking Error 0.813 Treynor Ratio -4.369 Total Fees $0.00 |
namespace QuantConnect { public class ForexMovingAvgCross : QCAlgorithm { //Create list of currency pairs to be traded List<string> Pairs = new List<string> { "AUDUSD", "EURUSD", "NZDUSD", "USDCAD" }; //Prepare a list for holding instances of the SymbolData object. List<SymbolData> SymbolData = new List<SymbolData>(); //Initialize the data and resolution you require for your strategy: public override void Initialize() { //Override the default fee model with Fxcm's SetBrokerageModel(BrokerageName.OandaBrokerage); //Start and End Date range for the backtest: SetStartDate(2012, 1, 1); SetEndDate(2012, 8, 1); //Cash allocation SetCash(25000); //Iterate through the pairs list and prepare data foreach (var symbol in Pairs) { //add the pair to algorithm AddForex(symbol, Resolution.Minute, Market.Oanda); //prepare the indicators required for the strategy var atr = ATR(symbol, 5, MovingAverageType.Simple, Resolution.Minute); //var fastMA = SMA(symbol, 10, Resolution.Minute); var myPsar = PSAR(symbol, 0.02m, 0.02m, 0.2m); var myHigh = SMA(symbol, 1, selector: m => ((QuoteBar)m).High); var myLow = SMA(symbol, 1, selector: m => ((QuoteBar)m).Low); var myAdx = ADX(symbol, 14, Resolution.Minute); var myRsi = RSI(symbol, 14, MovingAverageType.Exponential, Resolution.Minute); var fastMa = EMA(symbol, 14, selector: m => ((QuoteBar)m).Open); var slowMa = EMA(symbol, 14, selector: m => ((QuoteBar)m).Close); /*Intialize an object representing the pair to and add it to the symboldata list */ SymbolData.Add(new SymbolData { Symbol = symbol, Atr = atr, MyRsi = myRsi, MyPsar = myPsar, MyHigh = myHigh, MyLow = myLow, Risk = .0005m, MyAdx = myAdx, FastMa = fastMa, SlowMa = slowMa, }); } Schedule.On(DateRules.EveryDay(Pairs[0]), TimeRules.AfterMarketOpen(Pairs[0], 0), () => { ManageTrades(); }); } //Data Event Handler: public void OnData(TradeBars data) { } public void ManageTrades() { //Iterate through each currency pair foreach(var symbolObj in SymbolData) { if (symbolObj.Atr == 0m ) { continue; } //If the current pair is flat if (!Portfolio[symbolObj.Symbol].Invested) { //Check for long entry criteria if (((symbolObj.MyLow < symbolObj.MyPsar) && (symbolObj.MyAdx > 25) && (symbolObj.MyRsi < 45)))// && (symbolObj.FastMa > symbolObj.SlowMa)))) { MarketOrder(symbolObj.Symbol, symbolObj.AdjustedLotSize(Portfolio)); } //else check for short entry criteria else if (((symbolObj.MyHigh > symbolObj.MyPsar) && (symbolObj.MyAdx > 25) && (symbolObj.MyRsi > 55)))// && (symbolObj.FastMa < symbolObj.SlowMa)))) { MarketOrder(symbolObj.Symbol, -symbolObj.AdjustedLotSize(Portfolio)); } } //If the portfolio holds a long position else if (Portfolio[symbolObj.Symbol].IsLong) { //Exit long if (symbolObj.MyHigh > symbolObj.MyPsar) { //Liquidate Liquidate(symbolObj.Symbol); //MarketOrder(symbolObj.Symbol, -symbolObj.AdjustedLotSize(Portfolio)); } } //If the portfolio holds a short position else if (Portfolio[symbolObj.Symbol].IsShort) { //Exit short if (symbolObj.MyLow < symbolObj.MyPsar) { //Liquidate Liquidate(symbolObj.Symbol); //MarketOrder(symbolObj.Symbol, symbolObj.AdjustedLotSize(Portfolio)); } } } } } class SymbolData { public string Symbol; public AverageTrueRange Atr { get; set; } public RelativeStrengthIndex MyRsi { get; set; } public SimpleMovingAverage MyLow { get; set; } public ExponentialMovingAverage FastMa { get; set; } public ExponentialMovingAverage SlowMa { get; set; } public SimpleMovingAverage MyHigh { get; set; } public ParabolicStopAndReverse MyPsar { get; set; } public decimal Risk { get; set; } public AverageDirectionalIndex MyAdx { get; set; }////REMOVE IF DONT WORK // Calculate the adjusted lot size based on risk managment criteria public int AdjustedLotSize(SecurityPortfolioManager Portfolio) { //get the current account value var equity = Portfolio.TotalPortfolioValue; //determine the lotsize for the current pair var lotSize = Portfolio.Securities[Symbol].SymbolProperties.LotSize; //obtain the conversion rate for the pair var conversionRate = Portfolio.Securities[Symbol].QuoteCurrency.ConversionRate; var adjustedSize = 10000m; adjustedSize = (Risk * equity)/(Atr * conversionRate); adjustedSize = Math.Floor(adjustedSize/lotSize) * lotSize; return (int)adjustedSize; } } }