| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
/*
* TODO dont reload data for first minutes if same contract?
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Brokerages;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using QuantConnect.Securities;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// </summary>
public class FuturesAlgo: QCAlgorithm
{
FuturesContract _contract = null;
FuturesContract _nextContract = null;//holds the next contract, for warmup
BollingerBands _bb = null;
BollingerBands _nextBb = null;//holds the next FuturesContract
bool _newDay = true;
bool reset = true;
public override void Initialize()
{
SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin);
SetStartDate(year: 2017, month:6, day: 5);
SetEndDate(year: 2017, month:6, day: 20);
SetCash(100000);
SetWarmUp(TimeSpan.FromDays(5));
var future = AddFuture(Futures.Indices.SP500EMini, Resolution.Minute);
future.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(185));
}
public override void OnData(Slice slice)
{
if (Time.Minute == 0)
Log("OnData");
if (!InitContract(slice))
{
return;
}
if(reset)
{
//need to roll/close contract in position if any
reset = false;
}
if (Time.Minute == 0)
{
if (_bb != null && _bb.IsReady)
{
var price = 0m;
if (slice.Bars.ContainsKey(_contract.Symbol))
price = slice.Bars[_contract.Symbol].Close;
Log("OnData:" + Time.ToString() + " " + _contract.ToString()
+ " price: " + price
+ " BBL: " + _bb.LowerBand
+ " BBM: " + _bb.MiddleBand
+ " BBU: " + _bb.UpperBand);
if (slice.Bars.ContainsKey(_nextContract.Symbol))
price = slice.Bars[_nextContract.Symbol].Close;
Log("OnData:" + Time.ToString() + " " + _nextContract.ToString()
+ " NEXT price: " + price
+ " BBL: " + _nextBb.LowerBand
+ " BBM: " + _nextBb.MiddleBand
+ " BBU: " + _nextBb.UpperBand);
}
else
{
Log("BB not ready");
}
}
return;
}
private bool InitContract(Slice slice)
{
if (!_newDay)//reset daily everyday we chekc whther futures need to be rolled
{
return true;
}
if (_contract != null && (_contract.Expiry -Time.Date).TotalDays >=3) //rolling 3 days before expiry
{
return true;
}
//On Expiry we will reset contracts
foreach (var chain in slice.FutureChains)
{
Log(chain.ToString());
//when selecting contract if on expiry date, then skip first as it woudl be the same one!
int skip = 0;
if (_contract!= null)
Log("Expiry days away " + (_contract.Expiry -Time.Date).TotalDays + " - " + _contract.Expiry + " - " + Time.Date);
if (_contract!= null && (_contract.Expiry -Time.Date).TotalDays <=3)
skip = 1;
//only in the case of the first initialisation can we have skip=0 where we take the first future no matter what
//else we will skip the first future as it is the current one not yet expired!
var chainContracts = (
from futuresContract in chain.Value.OrderBy(x => x.Expiry)
//where futuresContract.Expiry > Time.Date.AddDays(90)
select futuresContract
).ToArray();
if (chainContracts.Count() < skip+2)
return false;
FuturesContract first = chainContracts[skip];
FuturesContract second = chainContracts[skip+1];
if (first != null && second != null)
{
Log("RESET: " + first.Symbol + " - " + second.Symbol);
reset = true;
if (first != null && (_contract == null || _contract.Symbol != first.Symbol))
{
if (_nextContract != null)
{
_bb = _nextBb;
_contract = _nextContract;
}
else
{
_contract = first;
var oneHour = new TradeBarConsolidator(TimeSpan.FromMinutes(60));
oneHour.DataConsolidated += OnHour;
//register the consolidator for data.
SubscriptionManager.AddConsolidator(_contract.Symbol, oneHour);
_bb = BB(_contract.Symbol, 20, 2, MovingAverageType.Exponential, Resolution.Hour);
//the algo won't warmup this bit so we have to call up the history and feed it the hour points
//however the History call seems to return 0 bars for hour resolution, so we call 50 * 60 miute for a 50 hours warmup
//var history = History(_contract.Symbol, 50*60, Resolution.Hour);
var history = History(_contract.Symbol, 50*60, Resolution.Minute);
Log(history.Count().ToString());
foreach (var bar in history)
{
if (bar.EndTime.Minute == 0 // on the hour
&& (Time - bar.EndTime).TotalMinutes >= 2) // probably unecessary but not this one as it would conflict
{
Log(bar.ToString());
_bb.Update(new IndicatorDataPoint(_contract.Symbol, bar.EndTime, bar.Close));
}
}
Log(_bb.IsReady.ToString());
}
}
if (second != null && (_nextContract == null || _nextContract.Symbol != second.Symbol))
{
_nextContract = second;
var oneHour = new TradeBarConsolidator(TimeSpan.FromMinutes(60));
//bind event handler to data consolidated event.
oneHour.DataConsolidated += OnHour;
//register the consolidator for data.
SubscriptionManager.AddConsolidator(_nextContract.Symbol, oneHour);
_nextBb = BB(_nextContract.Symbol, 20, 2, MovingAverageType.Exponential, Resolution.Hour);
}
_newDay = false;
return true;
}
}
return false;
}
public void OnHour(object sender, TradeBar bar)
{
//Log("do something and make sure indicators are udpated");
}
public override void OnEndOfDay()
{
_newDay = true;
}
}
}