Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions Lean.DataSource.OptionsUniverseGenerator/IndexHistoryProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
using QuantConnect.Logging;
using QuantConnect.Securities;
using QuantConnect.Util;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Web;

namespace QuantConnect.DataSource.OptionsUniverseGenerator
{
Expand All @@ -39,9 +41,13 @@ public partial class IndexHistoryProvider : SynchronizingHistoryProvider
private bool _resolutionLog;
private bool _dataTypeLog;
private bool _useDailyPreciseEndTime;
private readonly static string YahooFinanceApiUrl = "https://query1.finance.yahoo.com/v8/finance";
private readonly static string YahooFinanceApiUrl = "https://query1.finance.yahoo.com/";
private readonly static string BaseUri = "v8/finance";

private readonly RestClient _restClient = new(YahooFinanceApiUrl);
private readonly HttpClient _httpClient = new HttpClient
{
BaseAddress = new Uri(YahooFinanceApiUrl),
};

/// <summary>
/// Initializes this history provider to work for the specified job
Expand All @@ -51,6 +57,7 @@ public override void Initialize(HistoryProviderInitializeParameters parameters)
{
_useDailyPreciseEndTime = parameters.AlgorithmSettings.DailyPreciseEndTime;
AlgorithmSettings = parameters.AlgorithmSettings;
_httpClient.DefaultRequestHeaders.Add("User-Agent", "C#/HttpClient");
}

/// <summary>
Expand Down Expand Up @@ -141,23 +148,22 @@ public IEnumerable<BaseData> GetHistory(HistoryRequest request)
$"{request.Symbol}-{request.Resolution}-{request.TickType}.");
}

var restRequest = new RestRequest($"chart/{symbol}");
restRequest.AddQueryParameter("period1", start.ToString());
restRequest.AddQueryParameter("period2", end.ToString());
restRequest.AddQueryParameter("interval", interval);
restRequest.AddQueryParameter("includePrePost", request.IncludeExtendedMarketHours.ToString());
var query = HttpUtility.ParseQueryString(string.Empty);
query["period1"] = start.ToString();
query["period2"] = end.ToString();
query["interval"] = interval;
query["includePrePost"] = request.IncludeExtendedMarketHours.ToString();

var uri = $"{BaseUri}/chart/{symbol}?{query}";

try
{
var response = _restClient.Get(restRequest);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
if (!_httpClient.TryDownloadData(uri, out var content, out var statusCode))
{
Log.Error($"IndexHistoryProvider.GetHistory(): Failed to get history for {symbol}. Status code: {response.StatusCode}.");
Log.Error($"IndexHistoryProvider.GetHistory(): Failed to get history for {symbol}. Status code: {statusCode}.");
continue;
}

var content = response.Content;

// Log the response content for debugging purposes
Log.Trace($"IndexHistoryProvider.GetHistory(): Response content for {request.Symbol}-{request.Resolution}-{request.TickType}: {content}");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ namespace QuantConnect.DataSource.DerivativeUniverseGeneratorTests
public class ImpliedVolatilityInterpolatorTests
{
private const string _testFile = "TestData/test.csv";
private const string _sidHeader = "#symbol_id";
private const string _tickerHeader = "symbol_value";
private const string _expiryHeader = "#expiry";
private const string _strikeHeader = "strike";
private const string _rightHeader = "right";
private const string _priceHeader = "close";
private const string _ivHeader = "implied_volatility";
private const int _validCount = 236;
Expand All @@ -45,26 +46,35 @@ public void SetUp()
{
var lines = File.ReadAllLines(_testFile);
var headers = lines[0].Split(',');
var sidIndex = Array.IndexOf(headers, _sidHeader);
var tickerIndex = Array.IndexOf(headers, _tickerHeader);
var expiryIndex = Array.IndexOf(headers, _expiryHeader);
var strikeIndex = Array.IndexOf(headers, _strikeHeader);
var rightIndex = Array.IndexOf(headers, _rightHeader);
var priceIndex = Array.IndexOf(headers, _priceHeader);
var ivIndex = Array.IndexOf(headers, _ivHeader);

var underlying = lines[1].Split(',');
var undSymbol = new Symbol(SecurityIdentifier.Parse(underlying[sidIndex]), underlying[tickerIndex]);
var undSymbol = Symbol.Create("SPY", SecurityType.Equity, Market.USA);
var underlyingPrice = decimal.Parse(underlying[priceIndex]);

_data = lines.Skip(2)
.Select(line =>
{
var items = line.Split(',');
var symbol = new Symbol(SecurityIdentifier.Parse(items[sidIndex]), items[tickerIndex]);
var expiry = DateTime.ParseExact(items[expiryIndex], "yyyyMMdd", null);
var strike = decimal.Parse(items[strikeIndex]);
var right = items[rightIndex] == "C" ? OptionRight.Call : OptionRight.Put;

var symbol = Symbol.CreateOption(undSymbol, null, undSymbol.ID.Market,
undSymbol.SecurityType.DefaultOptionStyle(), right, strike, expiry);

var entry = new OptionUniverseEntry(symbol);
entry.Close = decimal.Parse(items[priceIndex]);
return entry;
})
.ToList();

var valids = 0;

foreach (var entry in _data)
{
var mirrorSymbol = OptionsUniverseGeneratorUtils.GetMirrorOptionSymbol(entry.Symbol);
Expand All @@ -77,6 +87,11 @@ public void SetUp()
greeks.Update(new TradeBar { Symbol = undSymbol, EndTime = _currentDate, Close = underlyingPrice });

entry.SetGreeksIndicators(greeks);

if (entry.ImpliedVolatility != null && entry.ImpliedVolatility.Value != 0m)
{
valids++;
}
}

_interpolator = new TestImpliedVolatilityInterpolator(_currentDate, _data, underlyingPrice, _validCount);
Expand All @@ -96,7 +111,7 @@ public void IvInterpolationAndGreeksGenerationTest()

Assert.Greater(interpolatedIv, 0m); // domain of IV :-> (0, inf]

var greekIndicator = _interpolator.GetUpdatedGreeksIndicators(symbol, interpolatedIv, OptionPricingModelType.BlackScholes,
var greekIndicator = _interpolator.GetUpdatedGreeksIndicators(symbol, interpolatedIv, OptionPricingModelType.BlackScholes,
OptionPricingModelType.BlackScholes);
var greeks = greekIndicator.GetGreeks();

Expand Down
Loading
Loading