Overall Statistics |
Total Trades 46 Average Win 0.79% Average Loss -0.66% Compounding Annual Return -91.555% Drawdown 19.000% Expectancy -0.667 Net Profit -18.543% Sharpe Ratio -9.878 Loss Rate 85% Win Rate 15% Profit-Loss Ratio 1.19 Alpha -2.234 Beta -0.142 Annual Standard Deviation 0.224 Annual Variance 0.05 Information Ratio -8 Tracking Error 0.258 Treynor Ratio 15.601 Total Fees $0.00 |
using System; using System.Collections; using System.Collections.Generic; using QuantConnect.Securities; using QuantConnect.Models; namespace QuantConnect { public class TestYahooCsv : QCAlgorithm { private const string _symbol = "ITUB4F.SA"; ExponentialMovingAverage emaFast;// = new MyEMA(15); ExponentialMovingAverage emaSlow;// = new MyEMA(50); public override void Initialize() { SetStartDate(2015, 6, 1); SetEndDate(2015, 7, 1); SetCash(5000); //Quandl Indexes AddData<YahooCsv>(_symbol, Resolution.Minute); emaFast = EMA(_symbol, 15); emaSlow = EMA(_symbol, 50); } private DateTime previous; /// <summary> /// Yahoo Daily Bars Event Handler: Daily bars arrive here for processing. /// </summary> public void OnData(YahooCsv data) { //Log("data! "+data.Time); int holdings = Portfolio[_symbol].Quantity; const decimal tolerance = 0.00015m; // we only want to go long if we're currently short or flat if (holdings <= 0) { // if the fast is greater than the slow, we'll go long if (emaFast > emaSlow * (1 + tolerance)){ Log("BUY >> " + Securities[_symbol].Price); SetHoldings(_symbol, 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 && emaFast < emaSlow){ Log("SELL >> " + Securities[_symbol].Price); Liquidate(_symbol); } /*if (holdings <= 0){ if (emaFast.EMA > emaSlow.EMA){ Order(_symbol, Math.Abs(holdings)+70); } } else if (holdings >= 0){ if (emaFast.EMA < emaSlow.EMA){ Order(_symbol,-(holdings+70)); } }*/ /* // a couple things to notice in this method: // 1. We never need to 'update' our indicators with the data, the engine takes care of this for us // 2. We can use indicators directly in math expressions // 3. We can easily plot many indicators at the same time // only once per day if (previous.Date == data.Time.Date) return; // define a small tolerance on our checks to avoid bouncing const decimal tolerance = 0.00015m; var holdings = Portfolio[_symbol].Quantity; // we only want to go long if we're currently short or flat if (holdings <= 0) { // if the fast is greater than the slow, we'll go long if (fast > slow * (1 + tolerance)) { Log("BUY >> " + Securities[_symbol].Price); SetHoldings(_symbol, 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[_symbol].Price); Liquidate(_symbol); } Plot(_symbol, "Price", data.Value); Plot("Ribbon", "Price", data.Value); // easily plot indicators, the series name will be the name of the indicator Plot(_symbol, fast, slow); Plot("Ribbon", ribbon); previous = data.Time; */ } } }
using System.Globalization; namespace QuantConnect { public class YahooCsv : BaseData { public decimal Open = 0; public decimal High = 0; public decimal Low = 0; public decimal Close = 0; // public decimal AdjustedClose = 0; public decimal Volume = 0; public YahooCsv() { this.Symbol = ""; } /// <summary> /// Return the URL external source for the data: QuantConnect will download it an read it line by line automatically: /// </summary> public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLive) { //QUANDL WRAPPER ON YAHOO FINANCE API TO SORT DATA: //https://www.quandl.com/api/v1/datasets/YAHOO/INDEX_SPY.csv?trim_start=2000-01-01&trim_end=2014-12-03&sort_order=asc //return new SubscriptionDataSource("https://www.quandl.com/api/v1/datasets/YAHOO/" + config.Symbol + ".csv?trim_start=" + startDate + "&trim_end=" + endDate + "&sort_order=asc&exclude_headers=true", SubscriptionTransportMedium.RemoteFile); //var startDate = "1433769540"; //var endDate = "1433781240"; // download a single, consistent chunk of data, we could set this up to download once a week // the important this is that whe GetSorce is called, we give back the same URL when we don't want it // to be redownloaded, and a different one when we do want it to be redownloaded. The GetSource // function will be called for every tradeable date of the backtest. //var startDate = (int) (new DateTime(2015, 06, 01).Subtract(new DateTime(1970, 1,1)).TotalMilliseconds / 1000); //var endDate = (int) (new DateTime(2015, 07, 01).Subtract(new DateTime(1970, 1,1)).TotalMilliseconds / 1000); // here's an example of download data once a month var month = new DateTime(date.Year, date.Month, 01); var startDate = (int) (month.Subtract(new DateTime(1970, 1,1)).TotalMilliseconds / 1000); var endDate = (int) (month.AddMonths(1).Subtract(new DateTime(1970, 1,1)).TotalMilliseconds / 1000); var url = "http://newnode-pnucci.rhcloud.com/stock/yahoocsv?s=" + config.Symbol + "&d1=" + startDate + "&d2=" + endDate; System.Console.Error.WriteLine("DATA SOURCE:: " + url); return new SubscriptionDataSource(url, SubscriptionTransportMedium.RemoteFile); } /// <summary> /// Convert each line of the file above into an object. /// </summary> public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLive) { YahooCsv yBar = new YahooCsv(); try { string[] data = line.Split(','); //Required. yBar.Symbol = config.Symbol; //yBar.Time = DateTime.ParseExact(data[0], "yyyy-MM-dd", CultureInfo.InvariantCulture); yBar.Time = new DateTime(1970, 1, 1, 0, 0, 0, 0).AddMilliseconds(ulong.Parse(data[0])*1000); //User configured / optional data on each bar: yBar.Open = Convert.ToDecimal(data[1]); yBar.Close = Convert.ToDecimal(data[2]); yBar.High = Convert.ToDecimal(data[3]); yBar.Low = Convert.ToDecimal(data[4]); yBar.Volume = Convert.ToDecimal(data[5]); //yBar.AdjustedClose = Convert.ToDecimal(data[6]); //This is the value the engine uses for portfolio calculations yBar.Value = yBar.Close; } catch { } return yBar; } } }