diff --git a/Algorithm.CSharp/CustomDataPropertiesRegressionAlgorithm.cs b/Algorithm.CSharp/CustomDataPropertiesRegressionAlgorithm.cs index fba19955843a..cdc54b1de847 100644 --- a/Algorithm.CSharp/CustomDataPropertiesRegressionAlgorithm.cs +++ b/Algorithm.CSharp/CustomDataPropertiesRegressionAlgorithm.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using Newtonsoft.Json; using QuantConnect.Data; using QuantConnect.Interfaces; @@ -40,8 +41,8 @@ public class CustomDataPropertiesRegressionAlgorithm : QCAlgorithm, IRegressionA /// public override void Initialize() { - SetStartDate(2020, 01, 05); - SetEndDate(2020, 01, 10); + SetStartDate(2018, 04, 05); + SetEndDate(2018, 04, 10); //Set the cash for the strategy: SetCash(100000); @@ -109,7 +110,7 @@ public override void OnEndOfAlgorithm() /// /// Data Points count of all timeslices of algorithm /// - public long DataPoints => 57; + public long DataPoints => 50; /// /// Data Points count of the algorithm history @@ -129,31 +130,31 @@ public override void OnEndOfAlgorithm() {"Total Orders", "1"}, {"Average Win", "0%"}, {"Average Loss", "0%"}, - {"Compounding Annual Return", "34781.071%"}, - {"Drawdown", "4.300%"}, + {"Compounding Annual Return", "-45.767%"}, + {"Drawdown", "4.000%"}, {"Expectancy", "0"}, {"Start Equity", "100000"}, - {"End Equity", "110102.2"}, - {"Net Profit", "10.102%"}, - {"Sharpe Ratio", "283.719"}, - {"Sortino Ratio", "1123.876"}, - {"Probabilistic Sharpe Ratio", "81.716%"}, + {"End Equity", "98999.21"}, + {"Net Profit", "-1.001%"}, + {"Sharpe Ratio", "0.907"}, + {"Sortino Ratio", "3.722"}, + {"Probabilistic Sharpe Ratio", "48.891%"}, {"Loss Rate", "0%"}, {"Win Rate", "0%"}, {"Profit-Loss Ratio", "0"}, - {"Alpha", "184.11"}, - {"Beta", "-6.241"}, - {"Annual Standard Deviation", "0.635"}, - {"Annual Variance", "0.403"}, - {"Information Ratio", "260.511"}, - {"Tracking Error", "0.689"}, - {"Treynor Ratio", "-28.849"}, + {"Alpha", "0.514"}, + {"Beta", "0.649"}, + {"Annual Standard Deviation", "0.5"}, + {"Annual Variance", "0.25"}, + {"Information Ratio", "1.127"}, + {"Tracking Error", "0.485"}, + {"Treynor Ratio", "0.699"}, {"Total Fees", "$0.00"}, {"Estimated Strategy Capacity", "$0"}, {"Lowest Capacity Asset", "BTC.Bitcoin 2S"}, - {"Portfolio Turnover", "16.73%"}, + {"Portfolio Turnover", "16.93%"}, {"Drawdown Recovery", "2"}, - {"OrderListHash", "b890a8e73bf118e943ad2f2e712f12d0"} + {"OrderListHash", "b9aecea6ebe672324d20a389ac004b1e"} }; /// @@ -216,12 +217,9 @@ public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, return new SubscriptionDataSource("https://www.bitstamp.net/api/ticker/", SubscriptionTransportMedium.Rest); } - //return "http://my-ftp-server.com/futures-data-" + date.ToString("Ymd") + ".zip"; - // OR simply return a fixed small data file. Large files will slow down your backtest - return new SubscriptionDataSource("https://www.quantconnect.com/api/v2/proxy/nasdaq/api/v3/datatables/QDL/BITFINEX.csv?code=BTCUSD&api_key=WyAazVXnq7ATy_fefTqm") - { - Sort = true - }; + // Read from a local data file so the test is deterministic instead of depending on a remote source + var source = Path.Combine(Globals.DataFolder, "crypto", "coinbase", "daily", "btcusd_trade.zip"); + return new SubscriptionDataSource(source, SubscriptionTransportMedium.LocalFile, FileFormat.Csv); } /// @@ -251,24 +249,22 @@ public override BaseData Reader(SubscriptionDataConfig config, string line, Date return coin; } - //Example Line Format: - // code date high low mid last bid ask volume - // BTCUSD 2024-10-08 63248.0 61940.0 62246.5 62245.0 62246.0 62247.0 5.929230648356 + // Example Line Format: + // date open high low close volume + // 20180405 00:00 6791.68 6933.11 6568.64 6785.85 13832.668772 try { - string[] data = line.Split(','); - coin.Time = DateTime.Parse(data[1], CultureInfo.InvariantCulture); + var data = line.Split(','); + coin.Time = DateTime.ParseExact(data[0], "yyyyMMdd HH:mm", CultureInfo.InvariantCulture); coin.EndTime = coin.Time.AddDays(1); + 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.Mid = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture); - coin.Close = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture); - coin.Bid = Convert.ToDecimal(data[6], CultureInfo.InvariantCulture); - coin.Ask = Convert.ToDecimal(data[7], CultureInfo.InvariantCulture); - coin.VolumeBTC = Convert.ToDecimal(data[8], CultureInfo.InvariantCulture); + coin.Close = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture); + coin.VolumeBTC = Convert.ToDecimal(data[5], CultureInfo.InvariantCulture); coin.Value = coin.Close; } - catch { /* Do nothing, skip first title row */ } + catch { /* Do nothing, skip malformed rows */ } return coin; } diff --git a/Algorithm.Python/CustomDataPropertiesRegressionAlgorithm.py b/Algorithm.Python/CustomDataPropertiesRegressionAlgorithm.py index 4f373c3c5f38..359789ddd4dd 100644 --- a/Algorithm.Python/CustomDataPropertiesRegressionAlgorithm.py +++ b/Algorithm.Python/CustomDataPropertiesRegressionAlgorithm.py @@ -25,8 +25,8 @@ class CustomDataPropertiesRegressionAlgorithm(QCAlgorithm): def initialize(self) -> None: - self.set_start_date(2020, 1, 5) # Set Start Date - self.set_end_date(2020, 1, 10) # Set End Date + self.set_start_date(2018, 4, 5) # Set Start Date + self.set_end_date(2018, 4, 10) # Set End Date self.set_cash(100000) # Set Strategy Cash # Define our custom data properties and exchange hours @@ -67,11 +67,9 @@ def get_source(self, config: SubscriptionDataConfig, date: datetime, is_live_mod if is_live_mode: return SubscriptionDataSource("https://www.bitstamp.net/api/ticker/", SubscriptionTransportMedium.REST) - #return "http://my-ftp-server.com/futures-data-" + date.to_string("Ymd") + ".zip" - # OR simply return a fixed small data file. Large files will slow down your backtest - subscription = SubscriptionDataSource("https://www.quantconnect.com/api/v2/proxy/nasdaq/api/v3/datatables/QDL/BITFINEX.csv?code=BTCUSD&api_key=WyAazVXnq7ATy_fefTqm") - subscription.sort = True - return subscription + # Read from a local data file so the test is deterministic instead of depending on a remote source + source = f"{Globals.data_folder}/crypto/coinbase/daily/btcusd_trade.zip" + return SubscriptionDataSource(source, SubscriptionTransportMedium.LOCAL_FILE, FileFormat.CSV) def reader(self, config: SubscriptionDataConfig, line: str, date: datetime, is_live_mode: bool) -> DynamicData: coin = Bitcoin() @@ -103,24 +101,20 @@ def reader(self, config: SubscriptionDataConfig, line: str, date: datetime, is_l return coin # Example Line Format: - #code date high low mid last bid ask volume - #BTCUSD 2024-10-08 63248.0 61940.0 62246.5 62245.0 62246.0 62247.0 5.929230648356 - if not (line.strip() and line[7].isdigit()): return coin - + # date open high low close volume + # 20180405 00:00 6791.68 6933.11 6568.64 6785.85 13832.668772 try: data = line.split(',') - coin.time = datetime.strptime(data[1], "%Y-%m-%d") + coin.time = datetime.strptime(data[0], "%Y%m%d %H:%M") coin.end_time = coin.time + timedelta(1) - coin.value = float(data[5]) + coin.value = float(data[4]) + coin["Open"] = float(data[1]) coin["High"] = float(data[2]) coin["Low"] = float(data[3]) - coin["Mid"] = float(data[4]) - coin["Close"] = float(data[5]) - coin["Bid"] = float(data[6]) - coin["Ask"] = float(data[7]) - coin["VolumeBTC"] = float(data[8]) + coin["Close"] = float(data[4]) + coin["VolumeBTC"] = float(data[5]) return coin except ValueError: - # Do nothing, possible error in json decoding + # Do nothing, skip malformed rows return coin