| 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;
}
}
}