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