Skip to content

Commit

Permalink
Issue #719 - Added support for the options contract requesting:
Browse files Browse the repository at this point in the history
- Added the new `IOptionContract` interface and two related enums: `OptionType` and `OptionStyle`.
- Added the new `IAlpacaTradingClient.ListOptionContractsAsync` method and related `OptionContractsRequest` class.
- Added the new `IAlpacaTradingClient.GetOptionContractByidAsync` and `IAlpacaTradingClient.GetOptionContractBySymbolAsync` methods.
  • Loading branch information
OlegRa committed Feb 26, 2024
1 parent ea73dab commit b24f8c0
Show file tree
Hide file tree
Showing 11 changed files with 584 additions and 3 deletions.
20 changes: 20 additions & 0 deletions Alpaca.Markets/AlpacaTradingClient.General.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,24 @@ await _httpClient.GetAsync<IReadOnlyList<IAnnouncement>, List<JsonAnnouncement>>
await request.EnsureNotNull().Validate()
.GetUriBuilderAsync(_httpClient).ConfigureAwait(false),
_rateLimitHandler, cancellationToken).ConfigureAwait(false);

public async Task<IReadOnlyList<IOptionContract>> ListOptionContractsAsync(
OptionContractsRequest request,
CancellationToken cancellationToken = default) =>
(await _httpClient.GetAsync<JsonOptionContractsPage, JsonOptionContractsPage>(
await request.EnsureNotNull().Validate()
.GetUriBuilderAsync(_httpClient).ConfigureAwait(false),
_rateLimitHandler, cancellationToken).ConfigureAwait(false)).Contracts;

public Task<IOptionContract> GetOptionContractByIdAsync(
Guid contractId,
CancellationToken cancellationToken = default) =>
_httpClient.GetAsync<IOptionContract, JsonOptionContract>(
$"v2/options/contracts/{contractId:D}", _rateLimitHandler, cancellationToken);

public Task<IOptionContract> GetOptionContractBySymbolAsync(
String symbol,
CancellationToken cancellationToken = default) =>
_httpClient.GetAsync<IOptionContract, JsonOptionContract>(
$"v2/options/contracts/{symbol.EnsureNotNull()}", _rateLimitHandler, cancellationToken);
}
63 changes: 63 additions & 0 deletions Alpaca.Markets/CompatibilitySuppressions.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Alpaca.Markets.IAlpacaTradingClient.GetOptionContractByIdAsync(System.Guid,System.Threading.CancellationToken)</Target>
<Left>lib/net6.0/Alpaca.Markets.dll</Left>
<Right>lib/net6.0/Alpaca.Markets.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Alpaca.Markets.IAlpacaTradingClient.GetOptionContractBySymbolAsync(System.String,System.Threading.CancellationToken)</Target>
<Left>lib/net6.0/Alpaca.Markets.dll</Left>
<Right>lib/net6.0/Alpaca.Markets.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Alpaca.Markets.IAlpacaTradingClient.ListOptionContractsAsync(Alpaca.Markets.OptionContractsRequest,System.Threading.CancellationToken)</Target>
<Left>lib/net6.0/Alpaca.Markets.dll</Left>
<Right>lib/net6.0/Alpaca.Markets.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>P:Alpaca.Markets.IAccount.OptionsApprovedLevel</Target>
Expand Down Expand Up @@ -29,6 +50,27 @@
<Right>lib/net6.0/Alpaca.Markets.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Alpaca.Markets.IAlpacaTradingClient.GetOptionContractByIdAsync(System.Guid,System.Threading.CancellationToken)</Target>
<Left>lib/netstandard2.0/Alpaca.Markets.dll</Left>
<Right>lib/netstandard2.0/Alpaca.Markets.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Alpaca.Markets.IAlpacaTradingClient.GetOptionContractBySymbolAsync(System.String,System.Threading.CancellationToken)</Target>
<Left>lib/netstandard2.0/Alpaca.Markets.dll</Left>
<Right>lib/netstandard2.0/Alpaca.Markets.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Alpaca.Markets.IAlpacaTradingClient.ListOptionContractsAsync(Alpaca.Markets.OptionContractsRequest,System.Threading.CancellationToken)</Target>
<Left>lib/netstandard2.0/Alpaca.Markets.dll</Left>
<Right>lib/netstandard2.0/Alpaca.Markets.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>P:Alpaca.Markets.IAccount.OptionsApprovedLevel</Target>
Expand Down Expand Up @@ -57,6 +99,27 @@
<Right>lib/netstandard2.0/Alpaca.Markets.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Alpaca.Markets.IAlpacaTradingClient.GetOptionContractByIdAsync(System.Guid,System.Threading.CancellationToken)</Target>
<Left>lib/netstandard2.1/Alpaca.Markets.dll</Left>
<Right>lib/netstandard2.1/Alpaca.Markets.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Alpaca.Markets.IAlpacaTradingClient.GetOptionContractBySymbolAsync(System.String,System.Threading.CancellationToken)</Target>
<Left>lib/netstandard2.1/Alpaca.Markets.dll</Left>
<Right>lib/netstandard2.1/Alpaca.Markets.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Alpaca.Markets.IAlpacaTradingClient.ListOptionContractsAsync(Alpaca.Markets.OptionContractsRequest,System.Threading.CancellationToken)</Target>
<Left>lib/netstandard2.1/Alpaca.Markets.dll</Left>
<Right>lib/netstandard2.1/Alpaca.Markets.dll</Right>
<IsBaselineSuppression>true</IsBaselineSuppression>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>P:Alpaca.Markets.IAccount.OptionsApprovedLevel</Target>
Expand Down
22 changes: 22 additions & 0 deletions Alpaca.Markets/Enums/OptionStyle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Alpaca.Markets;

/// <summary>
/// Supported option contract styles for Alpaca REST API.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum OptionStyle
{
/// <summary>
/// American option contract execution style.
/// </summary>
[UsedImplicitly]
[EnumMember(Value = "american")]
American,

/// <summary>
/// European option contract execution style.
/// </summary>
[UsedImplicitly]
[EnumMember(Value = "european")]
European
}
22 changes: 22 additions & 0 deletions Alpaca.Markets/Enums/OptionType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Alpaca.Markets;

/// <summary>
/// Supported option contract types for Alpaca REST API.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum OptionType
{
/// <summary>
/// Call option contract.
/// </summary>
[UsedImplicitly]
[EnumMember(Value = "call")]
Call,

/// <summary>
/// Put option contract.
/// </summary>
[UsedImplicitly]
[EnumMember(Value = "put")]
Put
}
76 changes: 75 additions & 1 deletion Alpaca.Markets/Interfaces/IAlpacaTradingClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public interface IAlpacaTradingClient : IRateLimitProvider, IDisposable
[UsedImplicitly]
Task<IReadOnlyList<IWatchList>> ListWatchListsAsync(
CancellationToken cancellationToken = default);

/// <summary>
/// Add new watch list object into Alpaca REST API endpoint.
/// </summary>
Expand Down Expand Up @@ -929,4 +928,79 @@ Task<IAnnouncement> GetAnnouncementAsync(
Task<IReadOnlyList<IAnnouncement>> ListAnnouncementsAsync(
AnnouncementsRequest request,
CancellationToken cancellationToken = default);

/// <summary>
/// Gets list of active option contracts from Alpaca REST API endpoint. By default, only active contracts that expire before the upcoming weekend are returned.
/// </summary>
/// <param name="request">Option contracts request parameters.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <exception cref="RequestValidationException">
/// The <paramref name="request"/> argument contains invalid data or some required data is missing, unable to create a valid HTTP request.
/// </exception>
/// <exception cref="HttpRequestException">
/// The request failed due to an underlying issue such as network connectivity, DNS failure, server certificate validation or timeout.
/// </exception>
/// <exception cref="RestClientErrorException">
/// The response contains an error message or the received response cannot be deserialized properly due to JSON schema mismatch.
/// </exception>
/// <exception cref="SocketException">
/// The initial TPC socket connection failed due to an underlying low-level network connectivity issue.
/// </exception>
/// <exception cref="TaskCanceledException">
/// .NET Core and .NET 5 and later only: The request failed due to timeout.
/// </exception>
/// <exception cref="ArgumentNullException">
/// The <paramref name="request"/> argument is <c>null</c>.
/// </exception>
/// <returns>Read-only list of corporate action information objects.</returns>
[UsedImplicitly]
Task<IReadOnlyList<IOptionContract>> ListOptionContractsAsync(
OptionContractsRequest request,
CancellationToken cancellationToken = default);

/// <summary>
/// Gets option contract from Alpaca REST API endpoint using contract identifier.
/// </summary>
/// <param name="contractId">Option contract unique identifier.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <exception cref="HttpRequestException">
/// The request failed due to an underlying issue such as network connectivity, DNS failure, server certificate validation or timeout.
/// </exception>
/// <exception cref="RestClientErrorException">
/// The response contains an error message or the received response cannot be deserialized properly due to JSON schema mismatch.
/// </exception>
/// <exception cref="SocketException">
/// The initial TPC socket connection failed due to an underlying low-level network connectivity issue.
/// </exception>
/// <exception cref="TaskCanceledException">
/// .NET Core and .NET 5 and later only: The request failed due to timeout.
/// </exception>
/// <returns>Read-only list of corporate action information objects.</returns>
[UsedImplicitly]
Task<IOptionContract> GetOptionContractByIdAsync(
Guid contractId,
CancellationToken cancellationToken = default);

/// <summary>
/// Gets option contract from Alpaca REST API endpoint using contract symbol name.
/// </summary>
/// <param name="symbol">Option contract unique symbol name.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <exception cref="HttpRequestException">
/// The request failed due to an underlying issue such as network connectivity, DNS failure, server certificate validation or timeout.
/// </exception>
/// <exception cref="RestClientErrorException">
/// The response contains an error message or the received response cannot be deserialized properly due to JSON schema mismatch.
/// </exception>
/// <exception cref="SocketException">
/// The initial TPC socket connection failed due to an underlying low-level network connectivity issue.
/// </exception>
/// <exception cref="TaskCanceledException">
/// .NET Core and .NET 5 and later only: The request failed due to timeout.
/// </exception>
/// <returns>Read-only list of corporate action information objects.</returns>
[UsedImplicitly]
Task<IOptionContract> GetOptionContractBySymbolAsync(
String symbol,
CancellationToken cancellationToken = default);
}
108 changes: 108 additions & 0 deletions Alpaca.Markets/Interfaces/IOptionContract.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
namespace Alpaca.Markets;

/// <summary>
///
/// </summary>
public interface IOptionContract
{
/// <summary>
/// Gets unique option contract identifier used by Alpaca.
/// </summary>
[UsedImplicitly]
Guid ContractId { get; }

/// <summary>
/// Get option contract symbol.
/// </summary>
String Symbol { get; }

/// <summary>
/// Gets option contract name.
/// </summary>
[UsedImplicitly]
String Name { get; }

/// <summary>
/// Get option contract status in API.
/// </summary>
[UsedImplicitly]
AssetStatus Status { get; }

/// <summary>
/// Returns <c>true</c> if asset is tradable.
/// </summary>
[UsedImplicitly]
Boolean IsTradable { get; }

/// <summary>
/// Get option contract size.
/// </summary>
[UsedImplicitly]
Decimal Size { get; }

/// <summary>
/// Get option contract type.
/// </summary>
[UsedImplicitly]
OptionType OptionType { get; }

/// <summary>
/// Get option contract strike price.
/// </summary>
[UsedImplicitly]
Decimal StrikePrice { get; }

/// <summary>
/// Get option contract expiration date.
/// </summary>
[UsedImplicitly]
DateOnly ExpirationDate { get; }

/// <summary>
/// Get option contract execution style.
/// </summary>
[UsedImplicitly]
OptionStyle OptionStyle { get; }

/// <summary>
/// Get option contract root asset <see cref="IAsset.Symbol"/> property.
/// </summary>
[UsedImplicitly]
String RootSymbol { get; }

/// <summary>
/// Get option contract underlying asset <see cref="IAsset.Symbol"/> property.
/// </summary>
[UsedImplicitly]
String UnderlyingSymbol { get; }

/// <summary>
/// Get option contract underlying asset <see cref="IAsset.AssetId"/> property.
/// </summary>
[UsedImplicitly]
Guid UnderlyingAssetId { get; }

/// <summary>
/// Get option contract open interest.
/// </summary>
[UsedImplicitly]
Decimal? OpenInterest { get; }

/// <summary>
/// Get option contract open interest date.
/// </summary>
[UsedImplicitly]
DateOnly? OpenInterestDate { get; }

/// <summary>
/// Get option contract close price.
/// </summary>
[UsedImplicitly]
Decimal? ClosePrice { get; }

/// <summary>
/// Get option contract close price date.
/// </summary>
[UsedImplicitly]
DateOnly? ClosePriceDate { get; }
}
Loading

0 comments on commit b24f8c0

Please sign in to comment.