| Overall Statistics |
|
Total Trades 12898 Average Win 0.17% Average Loss -0.16% Compounding Annual Return 7267639.429% Drawdown 2.800% Expectancy 0.578 Net Profit 15835844.526% Sharpe Ratio 24.515 Loss Rate 24% Win Rate 76% Profit-Loss Ratio 1.07 Alpha 11.088 Beta 0.496 Annual Standard Deviation 0.455 Annual Variance 0.207 Information Ratio 24.245 Tracking Error 0.455 Treynor Ratio 22.461 |
using System;
using System.Collections;
using System.Collections.Generic;
namespace QuantConnect
{
public class macd
{
private int _period_long;
private int _period_short;
private decimal _divergence;
private emovingaverage ema_short;
private emovingaverage ema_long;
public macd(int period_long, int period_short) {
_period_short = period_short;
_period_long = period_long;
ema_short = new emovingaverage(_period_short);
ema_long = new emovingaverage(_period_long);
}
public void AddSample(decimal price) {
ema_short.AddSample(price);
ema_long.AddSample(price);
_divergence = ema_long.getEMA() - ema_short.getEMA();
}
public decimal getDiv() {
return _divergence;
}
}
}using System;
using System.Collections;
using System.Collections.Generic;
namespace QuantConnect
{
/*
* QuantConnect University: Full Basic Template:
*
* The underlying QCAlgorithm class is full of helper methods which enable you to use QuantConnect.
* We have explained some of these here, but the full algorithm can be found at:
* https://github.com/QuantConnect/QCAlgorithm/blob/master/QuantConnect.Algorithm/QCAlgorithm.cs
*/
public class MACD_Trader : QCAlgorithm
{
string symbol = "CMG";
private int _bars;
macd M = new macd(26,12);
macd S = new macd(18,8);
//Initialize the data and resolution you require for your strategy:
public override void Initialize()
{
_bars = 0;
//Start and End Date range for the backtest:
SetStartDate(2014, 1, 1);
SetEndDate(DateTime.Now.Date.AddDays(-1));
//Cash allocation
SetCash(25000);
//Add as many securities as you like. All the data will be passed into the event handler:
AddSecurity(SecurityType.Equity, symbol, Resolution.Second);
}
private int orderCount;
private DateTime previous;
//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)
{
// "TradeBars" object holds many "TradeBar" objects: it is a dictionary indexed by the symbol:
//
// e.g. data["MSFT"] data["GOOG"]
decimal price = data[symbol].Close;
int holdings = Portfolio[symbol].Quantity;
_bars++;
if (_bars < 55) return;
if (previous.Date != data.Time.Date) {
orderCount = 0;
}
if (orderCount > 97) {
Liquidate();
return;
}
if (holdings == 0 || holdings < 0) {
if (M.getDiv() > 0) {
if(S.getDiv() > M.getDiv()) {
orderCount = orderCount + 1;
SetHoldings(symbol, 1.0);
}
}
} else if (holdings > 0) {
if (S.getDiv() < 0) {
orderCount = orderCount + 1;
Liquidate(symbol);
}
}
M.AddSample(price);
S.AddSample(price);
previous = data.Time;
}
}
}//Import Namespaces
using System;
using System.Collections;
using System.Collections.Generic;
namespace QuantConnect
{
//Create SMA class
public class smovingaverage
{
//Declare Variables
private int _period;
private int _slope_period;
private decimal _SMA;
private decimal _SMASlope;
private decimal[] _SMAHistory;
private decimal[] _prices;
private int _samples;
//Constructor
public smovingaverage(int period, int slope_period) {
this._period = period;
this._slope_period = slope_period;
this._samples = 0;
this._prices = new decimal[_period];
this._SMAHistory = new decimal[_slope_period];
}
//Adds a sample to SMA and calculates new values
public void AddSample(decimal price) {
//If SMA is not full
if (_samples < _period) {
_prices[_samples] = price;
_SMA = 0;
for(int i = 0; i < _samples; i++) {
_SMA = _SMA + _prices[i];
}
_SMA = _SMA / (_samples + 1);
}
//SMA is full, must shift values
else if (_samples >= _period) {
_SMA = _SMA - (_prices[0] / _period) + (price / _period);
for (int i = 0; i < _period - 1 ; i++) {
_prices[i] = _prices[i+1];
}
_prices[_period - 1] = price;
}
//SMA change before full is set to 0 to avoid erratic behavior
if (_samples < _slope_period) {
_SMAHistory[_samples] = _SMA;
_SMASlope = 0;
}
//SMA change over time calculated
else if (_samples >= _slope_period) {
_SMASlope = (_SMA - _SMAHistory[_slope_period - 1]) / _slope_period;
for (int i = 0; i < _slope_period - 1 ; i++) {
_SMAHistory[i] = _SMAHistory[i+1];
}
_SMAHistory[_slope_period - 1] = _SMA;
}
_samples++;
}
public decimal getSMASlope() {
return _SMASlope;
}
public decimal getSMA() {
return _SMA;
}
}
}using System;
using System.Collections;
using System.Collections.Generic;
namespace QuantConnect
{
public class emovingaverage
{
private int _period;
private decimal _EMA;
private int _samples;
public emovingaverage(int period) {
this._period = period;
this._samples = 0;
}
public void AddSample(decimal price) {
if (_samples == 0) {
_EMA = price;
} else {
_EMA = (1m / _period) * price + ((_period - 1m) / _period) * _EMA;
}
_samples++;
}
public decimal getEMA() {
return _EMA;
}
}
}