/* * 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 System; using System.Collections.Generic; using System.Globalization; using System.Linq; using QuantConnect.Data; namespace QuantConnect.Algorithm.CSharp { /// /// This demonstration imports indian NSE index "NIFTY" as a tradable security in addition to the USDINR currency pair. We move into the /// NSE market when the economy is performing well.s /// /// /// /// public class CustomDataNiftyAlgorithm : QCAlgorithm { //Create variables for analyzing Nifty private CorrelationPair _today = new CorrelationPair(); private readonly List _prices = new List(); private const int _minimumCorrelationHistory = 50; /// /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. /// public override void Initialize() { SetStartDate(2008, 1, 8); SetEndDate(2014, 7, 25); //Set the cash for the strategy: SetCash(100000); //Define the symbol and "type" of our generic data: var rupee = AddData("USDINR", Resolution.Daily).Symbol; var nifty = AddData("NIFTY", Resolution.Daily).Symbol; Settings.AutomaticIndicatorWarmUp = true; var rupeeSma = SMA(rupee, 20); var niftySma = SMA(rupee, 20); Log($"SMA - Is ready? USDINR: {rupeeSma.IsReady} NIFTY: {niftySma.IsReady}"); } /// /// Event Handler for Nifty Data Events: These Nifty objects are created from our /// "Nifty" type below and fired into this event handler. /// /// One(1) Nifty Object, streamed into our algorithm synchronised in time with our other data streams public override void OnData(Slice slice) { if (slice.ContainsKey("USDINR")) { _today = new CorrelationPair(Time) { CurrencyPrice = Convert.ToDouble(slice["USDINR"].Close) }; } if (!slice.ContainsKey("NIFTY")) { return; } try { _today.NiftyPrice = Convert.ToDouble(slice["NIFTY"].Close); if (_today.Date == slice["NIFTY"].Time) { _prices.Add(_today); if (_prices.Count > _minimumCorrelationHistory) { _prices.RemoveAt(0); } } //Strategy var quantity = (int)(Portfolio.MarginRemaining * 0.9m / slice["NIFTY"].Close); var highestNifty = (from pair in _prices select pair.NiftyPrice).Max(); var lowestNifty = (from pair in _prices select pair.NiftyPrice).Min(); if (Time.DayOfWeek == DayOfWeek.Wednesday) //prices.Count >= minimumCorrelationHistory && { //List niftyPrices = (from pair in prices select pair.NiftyPrice).ToList(); //List currencyPrices = (from pair in prices select pair.CurrencyPrice).ToList(); //double correlation = Correlation.Pearson(niftyPrices, currencyPrices); //double niftyFraction = (correlation)/2; if (Convert.ToDouble(slice["NIFTY"].Open) >= highestNifty) { var code = Order("NIFTY", quantity - Portfolio["NIFTY"].Quantity); Debug("LONG " + code + " Time: " + Time.ToShortDateString() + " Quantity: " + quantity + " Portfolio:" + Portfolio["NIFTY"].Quantity + " Nifty: " + slice["NIFTY"].Close + " Buying Power: " + Portfolio.TotalPortfolioValue); } else if (Convert.ToDouble(slice["NIFTY"].Open) <= lowestNifty) { var code = Order("NIFTY", -quantity - Portfolio["NIFTY"].Quantity); Debug("SHORT " + code + " Time: " + Time.ToShortDateString() + " Quantity: " + quantity + " Portfolio:" + Portfolio["NIFTY"].Quantity + " Nifty: " + slice["NIFTY"].Close + " Buying Power: " + Portfolio.TotalPortfolioValue); } } } catch (RegressionTestException err) { Debug("Error: " + err.Message); } } /// /// End of a trading day event handler. This method is called at the end of the algorithm day (or multiple times if trading multiple assets). /// /// Method is called 10 minutes before closing to allow user to close out position. public override void OnEndOfDay(Symbol symbol) { Plot("Nifty Closing Price", _today.NiftyPrice); } } /// /// NIFTY Custom Data Class /// public class Nifty : BaseData { /// /// Opening Price /// public decimal Open { get; set; } /// /// High Price /// public decimal High { get; set; } /// /// Low Price /// public decimal Low { get; set; } /// /// Closing Price /// public decimal Close { get; set; } /// /// Default initializer for NIFTY. /// public Nifty() { Symbol = "NIFTY"; } /// /// Return the URL string source of the file. This will be converted to a stream /// public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLiveMode) { return new SubscriptionDataSource("https://www.dropbox.com/s/rsmg44jr6wexn2h/CNXNIFTY.csv?dl=1", SubscriptionTransportMedium.RemoteFile); } /// /// Reader converts each line of the data source into BaseData objects. Each data type creates its own factory method, and returns a new instance of the object /// each time it is called. /// public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode) { //New Nifty object var index = new Nifty(); try { //Example File Format: //Date, Open High Low Close Volume Turnover //2011-09-13 7792.9 7799.9 7722.65 7748.7 116534670 6107.78 var data = line.Split(','); index.Time = DateTime.Parse(data[0], CultureInfo.InvariantCulture); index.EndTime = index.Time.AddDays(1); index.Open = Convert.ToDecimal(data[1], CultureInfo.InvariantCulture); index.High = Convert.ToDecimal(data[2], CultureInfo.InvariantCulture); index.Low = Convert.ToDecimal(data[3], CultureInfo.InvariantCulture); index.Close = Convert.ToDecimal(data[4], CultureInfo.InvariantCulture); index.Symbol = "NIFTY"; index.Value = index.Close; } catch { } return index; } } /// /// Dollar Rupe is a custom data type we create for this algorithm /// public class DollarRupee : BaseData { /// /// Open Price /// public decimal Open { get; set; } = 0; /// /// High Price /// public decimal High { get; set; } = 0; /// /// Low Price /// public decimal Low { get; set; } = 0; /// /// Closing Price /// public decimal Close { get; set; } /// /// Default constructor for the custom data class. /// public DollarRupee() { Symbol = "USDINR"; } /// /// Return the URL string source of the file. This will be converted to a stream /// public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLiveMode) { return new SubscriptionDataSource("https://www.dropbox.com/s/m6ecmkg9aijwzy2/USDINR.csv?dl=1", SubscriptionTransportMedium.RemoteFile); } /// /// Reader converts each line of the data source into BaseData objects. Each data type creates its own factory method, and returns a new instance of the object /// each time it is called. /// public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode) { //New USDINR object var currency = new DollarRupee(); try { var data = line.Split(','); currency.Time = DateTime.Parse(data[0], CultureInfo.InvariantCulture); currency.EndTime = currency.Time.AddDays(1); currency.Close = Convert.ToDecimal(data[1], CultureInfo.InvariantCulture); currency.Symbol = "USDINR"; currency.Value = currency.Close; } catch { } return currency; } } /// /// Correlation Pair is a helper class to combine two data points which we'll use to perform the correlation. /// public class CorrelationPair { /// /// Date of the correlation pair /// public DateTime Date { get; set; } /// /// Nifty price for this correlation pair /// public double NiftyPrice { get; set; } /// /// Currency price for this correlation pair /// public double CurrencyPrice { get; set; } /// /// Default initializer /// public CorrelationPair() { } /// /// Date based correlation pair initializer /// public CorrelationPair(DateTime date) { Date = date.Date; } } }