| 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 |
using System;
using System.Linq;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
namespace QuantConnect.Algorithm.CSharp
{
/// <summary>
/// Basic template algorithm simply initializes the date range and cash. This is a skeleton
/// framework you can use for designing an algorithm.
/// </summary>
public class BasicTemplateAlgorithm : QCAlgorithm
{
private RollingWindow<decimal> Close;
private DateTime _previous;
private SimpleMovingAverage _fast;
private SimpleMovingAverage _slow;
private SimpleMovingAverage[] _ribbon;
private string _sym = QuantConnect.Symbol.Create("BTCUSD", SecurityType.Crypto, Market.GDAX);
/// <summary>
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
/// </summary>
public override void Initialize()
{
SetStartDate(2017, 1, 1); //Set Start Date
SetEndDate(DateTime.Now); //Set End Date
SetCash(40000); //Set Strategy Cash
AddCrypto("BTCUSD", Resolution.Hour);
Securities["BTCUSD"].SetDataNormalizationMode(DataNormalizationMode.Raw);
Securities["BTCUSD"].FeeModel = new ConstantFeeTransactionModel(1);
var consolidator = new TradeBarConsolidator(3);
consolidator.DataConsolidated += HourHandler;
// create a 15 day exponential moving average
_fast = new SimpleMovingAverage(5);
_slow = new SimpleMovingAverage(18);
//SMA(_sym, 5, consolidator);
//RegisterIndicator("BTCUSD", _fast, consolidator);
// create a 30 day exponential moving average
//SMA(_sym, 18, consolidator);
//RegisterIndicator("BTCUSD", _slow, consolidator);
SubscriptionManager.AddConsolidator("BTCUSD", consolidator);
var ribbonCount = 8;
var ribbonInterval = 15;
_ribbon = Enumerable.Range(0, ribbonCount).Select(x => SMA(_sym, (x + 1)*ribbonInterval, Resolution.Hour)).ToArray();
Close = new RollingWindow<decimal>(2);
}
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="data">Slice object keyed by symbol containing the stock data</param>
private void HourHandler(object sender, BaseData consolidated)
{
Debug(Time.ToString() + " > New Bar!");
Plot(_sym, "Price", consolidated.Price);
// wait for our slow ema to fully initialize
//if (!_slow.IsReady) return;
// only once per day
//if (_previous.Date == Time.Date) return;
// define a small tolerance on our checks to avoid bouncing
const decimal tolerance = 0.00015m;
var holdings = Portfolio[_sym].Quantity;
Log("HOLDINGS " + holdings);
// we only want to go long if we're currently short or flat
if (holdings <= 0)
{
Log("FASTSMA " + _fast);
Log("SLOWSMA " + _slow);
// if the fast is greater than the slow, we'll go long
if (_fast > _slow * (1 + tolerance))
{
Log("BUY >> " + Securities[_sym].Price);
SetHoldings(_sym, 1.0);
}
}
// we only want to liquidate if we're currently long
// if the fast is less than the slow we'll liquidate our long
if (holdings > 0 && _fast < _slow)
{
Log("SELL >> " + Securities[_sym].Price);
Liquidate(_sym);
}
// if (holdings > 0) {
//Get out if drop off X percent
// if (Securities[_sym].Price < (Close[1] * 97 / 100 )) {
// Log("3% Drop get out >> " + Securities[_sym].Price);
// Liquidate(_sym);
// }
// }
// easily plot indicators, the series name will be the name of the indicator
Plot(_sym, _fast, _slow);
Plot("Ribbon", _ribbon);
_previous = Time;
}
public override void OnData(Slice data)
{
}
}
}