Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio NaN Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio NaN Tracking Error NaN Treynor Ratio NaN Total Fees $0.00 |
using System; using System.Globalization; using Newtonsoft.Json; using QuantConnect.Algorithm; using QuantConnect.Data; using QuantConnect.Data.Market; namespace QuantConnect { public class TestingCustomDataAlgo : QCAlgorithm { /// <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(new DateTime(2015, 03, 01)); SetEndDate(2015, 04, 01); AddSecurity(SecurityType.Forex, "USDJPY", Resolution.Minute); var consolidator = new DailyTradeBarConsolidator(); consolidator.DataConsolidated += DayBarHandler; SubscriptionManager.AddConsolidator("USDJPY", consolidator); } /// <summary> /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. /// </summary> /// <param name="data">TradeBars IDictionary object with your stock data</param> public void OnData(Bitcoin data) { if (!Portfolio.Invested) { MarketOrder("BTC", 100); } } private void DayBarHandler(object sender, BaseData consolidated) { Console.WriteLine("Consolidated Time: " + consolidated.Time.DayOfWeek + " - " + consolidated.Time); } } public class DailyTradeBarConsolidator : DataConsolidator<TradeBar> { private TradeBar _working; public override Type OutputType { get { return typeof (TradeBar); } } public override void Update(TradeBar data) { if (_working != null && _working.Time.Date != data.Time.Date) { OnDataConsolidated(_working); _working = null; } AggregateBar(ref _working, data); } /// <summary> /// Aggregates the new 'data' into the 'workingBar'. The 'workingBar' will be /// null following the event firing /// </summary> /// <param name="workingBar">The bar we're building, null if the event was just fired and we're starting a new trade bar</param> /// <param name="data">The new data</param> protected void AggregateBar(ref TradeBar workingBar, TradeBar data) { if (workingBar == null) { workingBar = new TradeBar { Time = data.Time, Symbol = data.Symbol, Open = data.Open, High = data.High, Low = data.Low, Close = data.Close, Volume = data.Volume, DataType = MarketDataType.TradeBar, Period = data.Period }; } else { //Aggregate the working bar workingBar.Close = data.Close; workingBar.Volume += data.Volume; workingBar.Period += data.Period; if (data.Low < workingBar.Low) workingBar.Low = data.Low; if (data.High > workingBar.High) workingBar.High = data.High; } } } /// <summary> /// Custom Data Type: Bitcoin data from Quandl - http://www.quandl.com/help/api-for-bitcoin-data /// </summary> public class Bitcoin : BaseData { //Set the defaults: /// <summary> /// Open Price /// </summary> public decimal Open = 0; /// <summary> /// High Price /// </summary> public decimal High = 0; /// <summary> /// Low Price /// </summary> public decimal Low = 0; /// <summary> /// Closing Price /// </summary> public decimal Close = 0; /// <summary> /// Volume in BTC /// </summary> public decimal VolumeBTC = 0; /// <summary> /// Volume in USD: /// </summary> public decimal WeightedPrice = 0; /// <summary> /// Default Constructor Required. /// </summary> public Bitcoin() { Symbol = "BTC"; } /// <summary> /// Source URL's of Backtesting and Live Streams: /// </summary> public override string GetSource(SubscriptionDataConfig config, DateTime date, DataFeedEndpoint datafeed) { var source = ""; switch (datafeed) { //Historical backtesting data: case DataFeedEndpoint.FileSystem: case DataFeedEndpoint.Backtesting: source = "http://www.quandl.com/api/v1/datasets/BITCOIN/BITSTAMPUSD.csv?sort_order=asc"; break; //Live socket for bitcoin prices: case DataFeedEndpoint.LiveTrading: //Live refreshing endpoint. source = "https://www.bitstamp.net/api/ticker/"; break; } return source; } /// <summary> /// Backtesting & Live Bitcoin Decoder: /// </summary> public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, DataFeedEndpoint datafeed) { Bitcoin coin = new Bitcoin(); switch (datafeed) { //Example Line Format: //Date Open High Low Close Volume (BTC) Volume (Currency) Weighted Price //2011-09-13 5.8 6.0 5.65 5.97 58.37138238, 346.0973893944 5.929230648356 case DataFeedEndpoint.FileSystem: case DataFeedEndpoint.Backtesting: try { string[] data = line.Split(','); coin.Time = DateTime.Parse(data[0]); coin.Open = Convert.ToDecimal(data[1], CultureInfo.InvariantCulture); coin.High = Convert.ToDecimal(data[2], CultureInfo.InvariantCulture); coin.Low = Convert.ToDecimal(data[3], CultureInfo.InvariantCulture); coin.Close = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture); coin.VolumeBTC = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture); coin.WeightedPrice = Convert.ToDecimal(data[7], CultureInfo.InvariantCulture); coin.Symbol = "BTC"; coin.Value = coin.Close; } catch { /* Do nothing, skip first title row */ } break; //Example Line Format: //{"high": "441.00", "last": "421.86", "timestamp": "1411606877", "bid": "421.96", "vwap": "428.58", "volume": "14120.40683975", "low": "418.83", "ask": "421.99"} case DataFeedEndpoint.LiveTrading: try { var liveBTC = JsonConvert.DeserializeObject<LiveBitcoin>(line); coin.Time = DateTime.Now; coin.Open = liveBTC.Last; coin.High = liveBTC.High; coin.Low = liveBTC.Low; coin.Close = liveBTC.Last; coin.VolumeBTC = liveBTC.Volume; coin.WeightedPrice = liveBTC.VWAP; coin.Symbol = "BTC"; coin.Value = coin.Close; } catch { /* Do nothing, possible error in json decoding */ } break; } return coin; } } /// <summary> /// Live data structure /// </summary> public class LiveBitcoin { public int Timestamp = 0; public decimal Last = 0; public decimal High = 0; public decimal Low = 0; public decimal Bid = 0; public decimal Ask = 0; public decimal VWAP = 0; public decimal Volume = 0; } }