From cda769df7442e8610848360d303657178135c472 Mon Sep 17 00:00:00 2001 From: Martin-Molinero <martin@quantconnect.com> Date: Tue, 14 Jan 2025 17:08:36 -0300 Subject: [PATCH] Add Nikkei 225 index support (#8529) - Add Osaka exchange for nikkei index. Adding regression test - Improve default market resolution --- .../HSIFutureHourRegressionAlgorithm.cs | 2 +- .../NikkeiIndexRegressionAlgorithm.cs | 122 ++++++++++++++++ Algorithm/QCAlgorithm.cs | 84 +++++------ Common/Currencies.cs | 7 +- Common/Market.cs | 8 +- Common/Securities/Index/IndexSymbol.cs | 27 +++- Data/index/ose/minute/n225/20210114_trade.zip | Bin 0 -> 4775 bytes Data/market-hours/market-hours-database.json | 138 ++++++++++++++++++ .../symbol-properties-database.csv | 2 + run_benchmarks.py | 5 +- 10 files changed, 338 insertions(+), 57 deletions(-) create mode 100644 Algorithm.CSharp/NikkeiIndexRegressionAlgorithm.cs create mode 100644 Data/index/ose/minute/n225/20210114_trade.zip diff --git a/Algorithm.CSharp/HSIFutureHourRegressionAlgorithm.cs b/Algorithm.CSharp/HSIFutureHourRegressionAlgorithm.cs index b7daa659a3e1..657ced59c790 100644 --- a/Algorithm.CSharp/HSIFutureHourRegressionAlgorithm.cs +++ b/Algorithm.CSharp/HSIFutureHourRegressionAlgorithm.cs @@ -52,7 +52,7 @@ public override void Initialize() SetTimeZone(TimeZones.HongKong); UniverseSettings.Resolution = Resolution; - _index = AddIndex("HSI", Resolution, market: Market.HKFE).Symbol; + _index = AddIndex("HSI", Resolution).Symbol; var future = AddFuture(Futures.Indices.HangSeng, Resolution); future.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(182)); _futureSymbol = future.Symbol; diff --git a/Algorithm.CSharp/NikkeiIndexRegressionAlgorithm.cs b/Algorithm.CSharp/NikkeiIndexRegressionAlgorithm.cs new file mode 100644 index 000000000000..633b38934160 --- /dev/null +++ b/Algorithm.CSharp/NikkeiIndexRegressionAlgorithm.cs @@ -0,0 +1,122 @@ +/* + * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. + * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +using QuantConnect.Indicators; +using QuantConnect.Interfaces; +using QuantConnect.Securities; +using System.Collections.Generic; + +namespace QuantConnect.Algorithm.CSharp +{ + /// <summary> + /// Example algorithm using nikkei index + /// </summary> + public class NikkeiIndexRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition + { + private Security _security; + private ExponentialMovingAverage _emaSlow; + private ExponentialMovingAverage _emaFast; + + /// <summary> + /// Initialize your algorithm and add desired assets. + /// </summary> + public override void Initialize() + { + SetStartDate(2021, 1, 14); + SetEndDate(2021, 1, 15); + SetCash(1000000); + + _security = AddIndex("N225"); + + var symbol = _security.Symbol; + _emaSlow = EMA(symbol, 80); + _emaFast = EMA(symbol, 200); + + Settings.DailyPreciseEndTime = true; + } + + public override void OnEndOfAlgorithm() + { + if (!_emaSlow.IsReady || !_emaFast.IsReady) + { + throw new RegressionTestException("Indicators are not ready!"); + } + if (!_security.HasData) + { + throw new RegressionTestException("Security does not have data!"); + } + } + + /// <summary> + /// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm. + /// </summary> + public virtual bool CanRunLocally { get; } = true; + + /// <summary> + /// This is used by the regression test system to indicate which languages this algorithm is written in. + /// </summary> + public virtual List<Language> Languages { get; } = new() { Language.CSharp }; + + /// <summary> + /// Data Points count of all timeslices of algorithm + /// </summary> + public virtual long DataPoints => 443; + + /// <summary> + /// Data Points count of the algorithm history + /// </summary> + public virtual int AlgorithmHistoryDataPoints => 0; + + /// <summary> + /// Final status of the algorithm + /// </summary> + public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed; + + /// <summary> + /// This is used by the regression test system to indicate what the expected statistics are from running the algorithm + /// </summary> + public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string> + { + {"Total Orders", "0"}, + {"Average Win", "0%"}, + {"Average Loss", "0%"}, + {"Compounding Annual Return", "0%"}, + {"Drawdown", "0%"}, + {"Expectancy", "0"}, + {"Start Equity", "1000000"}, + {"End Equity", "1000000"}, + {"Net Profit", "0%"}, + {"Sharpe Ratio", "0"}, + {"Sortino Ratio", "0"}, + {"Probabilistic 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"}, + {"Estimated Strategy Capacity", "$0"}, + {"Lowest Capacity Asset", ""}, + {"Portfolio Turnover", "0%"}, + {"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"} + }; + } +} diff --git a/Algorithm/QCAlgorithm.cs b/Algorithm/QCAlgorithm.cs index 280eb60d2ae8..0224eb60d098 100644 --- a/Algorithm/QCAlgorithm.cs +++ b/Algorithm/QCAlgorithm.cs @@ -56,6 +56,7 @@ using Python.Runtime; using QuantConnect.Commands; using Newtonsoft.Json; +using QuantConnect.Securities.Index; namespace QuantConnect.Algorithm { @@ -1378,11 +1379,7 @@ public void SetBenchmark(SecurityType securityType, string symbol) throw new InvalidOperationException("Algorithm.SetBenchmark(): Cannot change Benchmark after algorithm initialized."); } - string market; - if (!BrokerageModel.DefaultMarkets.TryGetValue(securityType, out market)) - { - market = Market.USA; - } + var market = GetMarket(null, symbol, securityType, defaultMarket: Market.USA); var benchmarkSymbol = QuantConnect.Symbol.Create(symbol, securityType, market); SetBenchmark(benchmarkSymbol); @@ -1886,13 +1883,7 @@ public Security AddSecurity(SecurityType securityType, string ticker, Resolution try { - if (market == null) - { - if (!BrokerageModel.DefaultMarkets.TryGetValue(securityType, out market)) - { - throw new KeyNotFoundException($"No default market set for security type: {securityType}"); - } - } + market = GetMarket(market, ticker, securityType); Symbol symbol; if (!SymbolCache.TryGetSymbol(ticker, out symbol) || @@ -2068,13 +2059,7 @@ public Equity AddEquity(string ticker, Resolution? resolution = null, string mar [DocumentationAttribute(AddingData)] public Option AddOption(string underlying, Resolution? resolution = null, string market = null, bool fillForward = true, decimal leverage = Security.NullLeverage) { - if (market == null) - { - if (!BrokerageModel.DefaultMarkets.TryGetValue(SecurityType.Option, out market)) - { - throw new KeyNotFoundException($"No default market set for security type: {SecurityType.Option}"); - } - } + market = GetMarket(market, underlying, SecurityType.Option); var underlyingSymbol = QuantConnect.Symbol.Create(underlying, SecurityType.Equity, market); return AddOption(underlyingSymbol, resolution, market, fillForward, leverage); @@ -2117,13 +2102,7 @@ public Option AddOption(Symbol underlying, string targetOption, Resolution? reso { var optionType = QuantConnect.Symbol.GetOptionTypeFromUnderlying(underlying); - if (market == null) - { - if (!BrokerageModel.DefaultMarkets.TryGetValue(optionType, out market)) - { - throw new KeyNotFoundException($"No default market set for security type: {optionType}"); - } - } + market = GetMarket(market, targetOption, optionType); Symbol canonicalSymbol; @@ -2165,14 +2144,7 @@ public Future AddFuture(string ticker, Resolution? resolution = null, string mar bool fillForward = true, decimal leverage = Security.NullLeverage, bool extendedMarketHours = false, DataMappingMode? dataMappingMode = null, DataNormalizationMode? dataNormalizationMode = null, int contractDepthOffset = 0) { - if (market == null) - { - if (!SymbolPropertiesDatabase.TryGetMarket(ticker, SecurityType.Future, out market) - && !BrokerageModel.DefaultMarkets.TryGetValue(SecurityType.Future, out market)) - { - throw new KeyNotFoundException($"No default market set for security type: {SecurityType.Future}"); - } - } + market = GetMarket(market, ticker, SecurityType.Future); Symbol canonicalSymbol; var alias = "/" + ticker; @@ -2301,13 +2273,8 @@ public IndexOption AddIndexOption(Symbol symbol, string targetOption, Resolution [DocumentationAttribute(AddingData)] public IndexOption AddIndexOption(string underlying, string targetOption, Resolution? resolution = null, string market = null, bool fillForward = true) { - if (market == null && !BrokerageModel.DefaultMarkets.TryGetValue(SecurityType.Index, out market)) - { - throw new KeyNotFoundException($"No default market set for underlying security type: {SecurityType.Index}"); - } - return AddIndexOption( - QuantConnect.Symbol.Create(underlying, SecurityType.Index, market), + QuantConnect.Symbol.Create(underlying, SecurityType.Index, GetMarket(market, underlying, SecurityType.Index)), targetOption, resolution, fillForward); } @@ -2946,13 +2913,7 @@ private T AddSecurity<T>(SecurityType securityType, string ticker, Resolution? r DataMappingMode? mappingMode = null, DataNormalizationMode? normalizationMode = null) where T : Security { - if (market == null) - { - if (!BrokerageModel.DefaultMarkets.TryGetValue(securityType, out market)) - { - throw new Exception("No default market set for security type: " + securityType); - } - } + market = GetMarket(market, ticker, securityType); Symbol symbol; if (!SymbolCache.TryGetSymbol(ticker, out symbol) || @@ -3489,6 +3450,35 @@ public CommandResultPacket RunCommand(CallbackCommand command) return true; } + /// <summary> + /// Helper method to get a market for a given security type and ticker + /// </summary> + private string GetMarket(string market, string ticker, SecurityType securityType, string defaultMarket = null) + { + if (string.IsNullOrEmpty(market)) + { + if (securityType == SecurityType.Index && IndexSymbol.TryGetIndexMarket(ticker, out market)) + { + return market; + } + + if (securityType == SecurityType.Future && SymbolPropertiesDatabase.TryGetMarket(ticker, securityType, out market)) + { + return market; + } + + if (!BrokerageModel.DefaultMarkets.TryGetValue(securityType, out market)) + { + if (string.IsNullOrEmpty(defaultMarket)) + { + throw new KeyNotFoundException($"No default market set for security type: {securityType}"); + } + return defaultMarket; + } + } + return market; + } + private string CommandLink(string typeName, object command) { var payload = new Dictionary<string, dynamic> { { "projectId", ProjectId }, { "command", command } }; diff --git a/Common/Currencies.cs b/Common/Currencies.cs index eab212a6ea8c..fcbc1efd6702 100644 --- a/Common/Currencies.cs +++ b/Common/Currencies.cs @@ -66,6 +66,11 @@ public static class Currencies /// </summary> public const string HKD = "HKD"; + /// <summary> + /// JPY (Japanese yen) currency string + /// </summary> + public const string JPY = "JPY"; + /// <summary> /// Null currency used when a real one is not required /// </summary> @@ -81,7 +86,7 @@ public static class Currencies { {USD, "$"}, {GBP, "₤"}, - {"JPY", "¥"}, + {JPY, "¥"}, {EUR, "€"}, {"NZD", "$"}, {"AUD", "$"}, diff --git a/Common/Market.cs b/Common/Market.cs index 82670df584c0..b2a1692cbd68 100644 --- a/Common/Market.cs +++ b/Common/Market.cs @@ -69,7 +69,8 @@ public static class Market Tuple.Create(Bybit, 37), Tuple.Create(Coinbase, 38), Tuple.Create(InteractiveBrokers, 39), - Tuple.Create(EUREX, 40) + Tuple.Create(EUREX, 40), + Tuple.Create(OSE, 41) }; static Market() @@ -169,6 +170,11 @@ static Market() /// </summary> public const string HKFE = "hkfe"; + /// <summary> + /// Osaka Stock Exchange + /// </summary> + public const string OSE = "ose"; + /// <summary> /// London International Financial Futures and Options Exchange /// </summary> diff --git a/Common/Securities/Index/IndexSymbol.cs b/Common/Securities/Index/IndexSymbol.cs index 132e4f1ec506..a55e77e536a2 100644 --- a/Common/Securities/Index/IndexSymbol.cs +++ b/Common/Securities/Index/IndexSymbol.cs @@ -13,6 +13,7 @@ * limitations under the License. */ +using System; using System.Collections.Generic; namespace QuantConnect.Securities.Index @@ -22,27 +23,41 @@ namespace QuantConnect.Securities.Index /// </summary> public static class IndexSymbol { - private static readonly Dictionary<string, string> _indexMarket = new Dictionary<string, string> + private static readonly Dictionary<string, string> _indexExchange = new(StringComparer.InvariantCultureIgnoreCase) { { "SPX", Market.CBOE }, { "NDX", "NASDAQ" }, { "VIX", Market.CBOE }, { "SPXW", Market.CBOE }, { "NQX", "NASDAQ" }, - { "VIXW", Market.CBOE }, - { "HSI", Market.HKFE } + { "VIXW", Market.CBOE } + }; + + private static readonly Dictionary<string, string> _indexMarket = new(StringComparer.InvariantCultureIgnoreCase) + { + { "HSI", Market.HKFE }, + { "N225", Market.OSE } }; /// <summary> /// Gets the actual exchange the index lives on /// </summary> - /// <returns>The market of the index</returns> + /// <remarks>Useful for live trading</remarks> + /// <returns>The exchange of the index</returns> public static string GetIndexExchange(Symbol symbol) { - string market; - return _indexMarket.TryGetValue(symbol.Value, out market) + return _indexExchange.TryGetValue(symbol.Value, out var market) ? market : symbol.ID.Market; } + + /// <summary> + /// Gets the lean market for this index ticker + /// </summary> + /// <returns>The market of the index</returns> + public static bool TryGetIndexMarket(string ticker, out string market) + { + return _indexMarket.TryGetValue(ticker, out market); + } } } diff --git a/Data/index/ose/minute/n225/20210114_trade.zip b/Data/index/ose/minute/n225/20210114_trade.zip new file mode 100644 index 0000000000000000000000000000000000000000..8edad96366ac527c24cfee809309a6ef51b7633f GIT binary patch literal 4775 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 literal 0 HcmV?d00001 diff --git a/Data/market-hours/market-hours-database.json b/Data/market-hours/market-hours-database.json index a18855d3acd5..ca0956353325 100644 --- a/Data/market-hours/market-hours-database.json +++ b/Data/market-hours/market-hours-database.json @@ -123903,6 +123903,144 @@ "12/31/2025": "12:00:00" }, "lateOpens": {} + }, + "Index-ose-[*]": { + "dataTimeZone": "Asia/Tokyo", + "exchangeTimeZone": "Asia/Tokyo", + "sunday": [], + "monday": [ + { + "start": "09:00:00", + "end": "11:30:00", + "state": "market" + }, + { + "start": "12:30:00", + "end": "15:30:00", + "state": "market" + } + ], + "tuesday": [ + { + "start": "09:00:00", + "end": "11:30:00", + "state": "market" + }, + { + "start": "12:30:00", + "end": "15:30:00", + "state": "market" + } + ], + "wednesday": [ + { + "start": "09:00:00", + "end": "11:30:00", + "state": "market" + }, + { + "start": "12:30:00", + "end": "15:30:00", + "state": "market" + } + ], + "thursday": [ + { + "start": "09:00:00", + "end": "11:30:00", + "state": "market" + }, + { + "start": "12:30:00", + "end": "15:30:00", + "state": "market" + } + ], + "friday": [ + { + "start": "09:00:00", + "end": "11:30:00", + "state": "market" + }, + { + "start": "12:30:00", + "end": "15:30:00", + "state": "market" + } + ], + "saturday": [], + "holidays": [], + "earlyCloses": {}, + "lateOpens": {} + }, + "Index-ose-N225": { + "dataTimeZone": "Asia/Tokyo", + "exchangeTimeZone": "Asia/Tokyo", + "sunday": [], + "monday": [ + { + "start": "09:00:00", + "end": "11:30:00", + "state": "market" + }, + { + "start": "12:30:00", + "end": "15:30:00", + "state": "market" + } + ], + "tuesday": [ + { + "start": "09:00:00", + "end": "11:30:00", + "state": "market" + }, + { + "start": "12:30:00", + "end": "15:30:00", + "state": "market" + } + ], + "wednesday": [ + { + "start": "09:00:00", + "end": "11:30:00", + "state": "market" + }, + { + "start": "12:30:00", + "end": "15:30:00", + "state": "market" + } + ], + "thursday": [ + { + "start": "09:00:00", + "end": "11:30:00", + "state": "market" + }, + { + "start": "12:30:00", + "end": "15:30:00", + "state": "market" + } + ], + "friday": [ + { + "start": "09:00:00", + "end": "11:30:00", + "state": "market" + }, + { + "start": "12:30:00", + "end": "15:30:00", + "state": "market" + } + ], + "saturday": [], + "holidays": [], + "earlyCloses": {}, + "lateOpens": {} } } } \ No newline at end of file diff --git a/Data/symbol-properties/symbol-properties-database.csv b/Data/symbol-properties/symbol-properties-database.csv index b8be25c4f13c..947fb46b2dd6 100644 --- a/Data/symbol-properties/symbol-properties-database.csv +++ b/Data/symbol-properties/symbol-properties-database.csv @@ -407,6 +407,8 @@ india,SENSEX,future,BSE S&P Sensex Index,INR,0.05,25,1.0 hkfe,HSI,future,Hang Seng Index,HKD,50,1,1.0 hkfe,[*],index,,HKD,1,0.01,1 +ose,[*],index,,JPY,1,0.01,1 + # Futures options -- will default to Futures contract specs in case no entry exists cbot,OZB,futureoption,U.S. Treasury Bond American Futures Options,USD,1000.0,0.015625,1.0 cbot,OZC,futureoption,Corn American Futures Options,USD,5000.0,0.00125,1.0,,,100 diff --git a/run_benchmarks.py b/run_benchmarks.py index 7c48fb6bb62c..a029d0e7f363 100644 --- a/run_benchmarks.py +++ b/run_benchmarks.py @@ -30,7 +30,7 @@ dataPointsPerSecond = [] benchmarkLengths = [] - for x in range(1, 2): + for x in range(1, 3): subprocess.run(["dotnet", "./QuantConnect.Lean.Launcher.dll", "--data-folder " + dataPath, @@ -42,6 +42,9 @@ cwd="./Launcher/bin/Release", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + if x == 1: + # skip first run + continue algorithmLogs = os.path.join("./Launcher/bin/Release", algorithmName + "-log.txt") file = open(algorithmLogs, 'r')