| Overall Statistics |
|
Total Trades 316 Average Win 0.11% Average Loss -0.04% Annual Return 2.347% Drawdown 2.900% Expectancy 0.425 Net Profit 5.943% Sharpe Ratio 1.1 Loss Rate 60% Win Rate 40% Profit-Loss Ratio 2.57 Trade Frequency Weekly trades |
using System;
using System.Collections;
using System.Collections.Generic;
namespace QuantConnect
{
using QuantConnect.Securities;
using QuantConnect.Models;
public partial class BasicTemplateAlgorithm : QCAlgorithm, IAlgorithm
{
string symbol = "MSFT";
bool initialized = false;
int numTrackers = 80;
decimal[] movingAverages;
decimal[] multipliers;
bool[,] direction;
decimal[,] movingAverageGain;
decimal[,] crossPrice;
decimal gainMultiplier = .2m;
int[,] crossCount;
int bestI = -1;
int bestJ = -1;
//Initialize the data and resolution you require for your strategy:
public override void Initialize()
{
//Initialize the start, end dates for simulation; cash and data required.
SetStartDate(2012, 06, 01);
SetEndDate(DateTime.Now.Date.AddDays(-1));
SetCash(30000); //Starting Cash in USD.
AddSecurity(SecurityType.Equity, symbol, Resolution.Minute); //Minute, Second or Tick
SetRunMode(RunMode.Series); //Series or Parallel for intraday strategies.
movingAverages = new decimal[numTrackers];
multipliers = new decimal[numTrackers];
direction = new bool[numTrackers, numTrackers];
movingAverageGain = new decimal[numTrackers, numTrackers];
crossPrice = new decimal[numTrackers, numTrackers];
crossCount = new int[numTrackers, numTrackers];
decimal multiplier = 1;
for (int i = 0; i < numTrackers; i++) {
multiplier *= .9m;
multipliers[i] = multiplier;
}
}
//Handle TradeBar Events: a TradeBar occurs on a time-interval (second or minute bars)
public override void OnTradeBar(Dictionary<string, TradeBar> data)
{
decimal lastPrice = data[symbol].Close;
if (initialized) {
for (int i = 0; i < numTrackers; i++) {
movingAverages[i] += (lastPrice - movingAverages[i]) * multipliers[i];
}
for (int i = 0; i < numTrackers; i++) {
for (int j = 0; j < numTrackers; j++) {
bool newDirection = movingAverages[i] > movingAverages[j];
if (direction[i, j] != newDirection) {
decimal diff = (lastPrice - crossPrice[i, j]) / crossPrice[i, j];
if (newDirection) {
movingAverageGain[i, j] += (-diff - movingAverageGain[i, j]) * gainMultiplier;
} else {
movingAverageGain[i, j] += (diff - movingAverageGain[i, j]) * gainMultiplier;
}
if (i == bestI && j == bestJ) {
Debug(bestI + ", " + bestJ + ": " + movingAverageGain[i, j]);
if (newDirection) {
if (Portfolio.HoldStock) {
Order(symbol, -200);
}
} else {
if (!Portfolio.HoldStock) {
Order(symbol, 200);
}
}
}
direction[i, j] = newDirection;
crossPrice[i, j] = lastPrice;
crossCount[i, j]++;
}
}
}
decimal maxGain = 0;
for (int i = 0; i < numTrackers; i++) {
for (int j = 0; j < numTrackers; j++) {
if (movingAverageGain[i, j] > maxGain && crossCount[i, j] > 5 && i < j) {
maxGain = movingAverageGain[i, j];
bestI = i;
bestJ = j;
}
}
}
} else {
for (int i = 0; i < numTrackers; i++) {
movingAverages[i] = lastPrice;
}
for (int i = 0; i < numTrackers; i++) {
for (int j = 0; j < numTrackers; j++) {
direction[i, j] = movingAverages[i] > movingAverages[j];
crossPrice[i, j] = lastPrice;
}
}
initialized = true;
}
}
}
}