using QuantConnect.Algorithm;
using QuantConnect.Data;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using QuantConnect.Securities;
using System;
using System.Collections.Generic;
using System.Linq;
namespace QuantConnect
{
public class ConsolidationAlgorithm : QCAlgorithm
{
private const decimal stop_loss = 100m;
private const decimal take_profit = 200m;
// Tradebar quoteBar;
private const string RootSP500 = Futures.Indices.Dow30EMini;
private readonly HashSet<Symbol> _futureContracts = new HashSet<Symbol>();
private decimal new_SL = 0.0m;
private decimal new_TP = 0.0m;
// int quantity = 1;
int count = 0;
int loss = 1;
public Symbol _symbol = QuantConnect.Symbol.Create(RootSP500, SecurityType.Future, Market.USA);
private Dictionary<FuturesContract, WilliamsPercentR> _williamsRs;
//MyMarginModel = FutureMarginModel
public override void Initialize()
{
SetStartDate(year: 2013, month: 10, day: 7);
SetEndDate(year: 2014, month: 10, day: 11);
SetCash(startingCash: 350000);
// Portfolio.MarginCallModel = MarginCallModel.Null;
SetBrokerageModel(Brokerages.BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin);
var futureSP500 = AddFuture(RootSP500);
futureSP500.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(value: 91));
futureSP500.MarginModel = new PatternDayTradingMarginModel() ;
SetBenchmark(x => 0);
_williamsRs = _williamsRs = new Dictionary<FuturesContract, WilliamsPercentR>();
}
public override void OnData(Slice slice)
{
foreach (var chain in slice.FutureChains)
{
foreach (var contract in chain.Value)
{
if (!_futureContracts.Contains(contract.Symbol))
{
_futureContracts.Add(contract.Symbol);
var consolidator = new TradeBarConsolidator(TimeSpan.FromMinutes(5));
consolidator.DataConsolidated += OnDataConsolidated;
SubscriptionManager.AddConsolidator(contract.Symbol, consolidator);
_williamsRs[contract] = (new WilliamsPercentR(14));
RegisterIndicator(contract.Symbol, _williamsRs[contract], consolidator);
//Log("|||||Added new consolidator for " + contract.Symbol.Value);
}
}
}
}
private void OnDataConsolidated(object sender, TradeBar quoteBar)
{
// Log("OnDataConsolidated called");
var indicators = _williamsRs.Where(x => x.Key.Symbol == quoteBar.Symbol).ToList();
decimal price = quoteBar.Value;
// Log("price" + quoteBar.Value);
foreach (var willR in indicators)
{
if (willR.Key.Expiry < Time)
{
// Drop expirxed indicators
//var msg = string.Format("Drop Williams R for {0} at expiration.", willR.Key.Symbol);
//Log(msg);
_williamsRs.Remove(willR.Key);
}
else
{
//var msg = string.Format("Williams R for {0} is {1:F4}", willR.Key.Symbol, willR.Value.Current.Value);
//Log(msg);
if (willR.Value.IsReady)
{
if (willR.Value <= -80.0 && count <= 5)
{
count++;
//Log("Counting Oversold " + count);
}
else
{
count = 0;
//Log("Reset Count" + count);
}
if (count == 5 && !Portfolio.HoldStock)
{
int quantity =1 ;
MarketOrder(willR.Key.Symbol, quantity);
Log("Ordering ES Mini : " + quantity);
}
}
if (Portfolio.HoldStock)
{
// Log("price " + price);
// Log("new_SL " + new_SL);
// Log("new_TP" + new_TP);
if (price < new_SL)
{
//Log("SL " + new_SL);
loss++;
Log("Stop_Loss_Counter " + loss);
Liquidate();
}
else if (price > new_TP)
{
loss = 1;
Log("Take Profit: Reset " + loss);
Liquidate();
}
}
}
}
}
public override void OnOrderEvent(OrderEvent fill)
{
// Only process filled orders
if (!fill.Status.IsFill()) return;
var orderId = fill.OrderId;
// Only considers thisOrder
// if(thisOrder.OrderId != orderId) return;
var orderTicket = Transactions.GetOrderTicket(orderId);
var fill_price = orderTicket.AverageFillPrice;
var quantity = orderTicket.QuantityFilled;
// Debug("Order Price " + fill_price) ;
decimal SL = (fill_price - stop_loss);
decimal TP = (fill_price + take_profit);
// Debug("Stop Loss " + SL) ;
// Debug("Take Profit " + TP) ;
// Do not use StopMarketOrder LimitOrder, but use a line
new_SL = SL;
new_TP = TP;
}
}
}