-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<RootNamespace>DxFeed.Graal.Net.Samples</RootNamespace> | ||
<TargetFrameworks>net6.0</TargetFrameworks> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> | ||
<OutputPath>../../artifacts/Debug/Samples/</OutputPath> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> | ||
<OutputPath>../../artifacts/Release/Samples/</OutputPath> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\DxFeed.Graal.Net\DxFeed.Graal.Net.csproj"/> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update="dxfeed.properties"> | ||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||
</None> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using DxFeed.Graal.Net.Api; | ||
using DxFeed.Graal.Net.Events.Market; | ||
using DxFeed.Graal.Net.Ipf; | ||
using DxFeed.Graal.Net.Ipf.Option; | ||
|
||
namespace DxFeed.Graal.Net.Samples; | ||
|
||
abstract class Program | ||
{ | ||
public static async Task Main(string[] args) | ||
{ | ||
if (args.Length != 4) | ||
{ | ||
Console.WriteLine("usage: DXFeedOptionChain <ipf-file> <symbol> <nStrikes> <nMonths>"); | ||
Console.WriteLine(" <ipf-file> is name of instrument profiles file"); | ||
Console.WriteLine(" <symbol> is the product or underlying symbol"); | ||
Console.WriteLine(" <nStrikes> number of strikes to print for each series"); | ||
Console.WriteLine(" <nMonths> number of months to print"); | ||
return; | ||
} | ||
|
||
SystemProperty.SetProperty("dxfeed.address", "demo.dxfeed.com:7300"); | ||
|
||
var argIpfFile = args[0]; | ||
var argSymbol = args[1]; | ||
var nStrikes = int.Parse(args[2]); | ||
var nMonths = int.Parse(args[3]); | ||
|
||
var feed = DXFeed.GetInstance(); | ||
|
||
// subscribe to trade to learn instrument last price | ||
Console.WriteLine($"Waiting for price of {argSymbol} ..."); | ||
using var cts = new CancellationTokenSource(); | ||
cts.CancelAfter(TimeSpan.FromSeconds(1)); | ||
var trade = await feed.GetLastEventAsync<Trade>(argSymbol, cts.Token); | ||
|
||
var price = trade.Price; | ||
Console.WriteLine($"Price of {argSymbol} is {price.ToString(CultureInfo.InvariantCulture)}"); | ||
|
||
Console.WriteLine($"Reading instruments from {argIpfFile} ..."); | ||
var instruments = new InstrumentProfileReader().ReadFromFile(argIpfFile).ToList(); | ||
|
||
Console.WriteLine("Building option chains ..."); | ||
var chains = OptionChainsBuilder<InstrumentProfile>.Build(instruments).GetChains(); | ||
if (!chains.TryGetValue(argSymbol, out var chain)) | ||
{ | ||
Console.WriteLine($"No chain found for symbol {argSymbol}"); | ||
return; | ||
} | ||
|
||
nMonths = Math.Min(nMonths, chain.GetSeries().Count); | ||
var seriesList = chain.GetSeries().Take(nMonths).ToList(); | ||
|
||
Console.WriteLine("Requesting option quotes ..."); | ||
var quotes = new Dictionary<InstrumentProfile, Task<Quote>>(); | ||
|
||
foreach (var series in seriesList) | ||
{ | ||
var strikes = series.GetNStrikesAround(nStrikes, price); | ||
foreach (var strike in strikes) | ||
{ | ||
if (series.Calls.TryGetValue(strike, out var call)) | ||
{ | ||
quotes[call] = feed.GetLastEventAsync<Quote>(call.Symbol); | ||
} | ||
|
||
if (series.Puts.TryGetValue(strike, out var put)) | ||
{ | ||
quotes[put] = feed.GetLastEventAsync<Quote>(put.Symbol); | ||
} | ||
} | ||
} | ||
|
||
await Task.WhenAll(quotes.Values); | ||
|
||
Console.WriteLine("Printing option series ..."); | ||
foreach (var series in seriesList) | ||
{ | ||
Console.WriteLine($"Option series {series}"); | ||
var strikes = series.GetNStrikesAround(nStrikes, price); | ||
Console.WriteLine($"{"C.BID",10} {"C.ASK",10} {"STRIKE",10} {"P.BID",10} {"P.ASK",10}"); | ||
foreach (var strike in strikes) | ||
{ | ||
series.Calls.TryGetValue(strike, out var call); | ||
series.Puts.TryGetValue(strike, out var put); | ||
var callQuote = call != null && quotes.TryGetValue(call, out var callTask) | ||
? callTask.Result | ||
: new Quote(); | ||
var putQuote = put != null && quotes.TryGetValue(put, out var putTask) ? putTask.Result : new Quote(); | ||
Console.WriteLine( | ||
$"{callQuote.BidPrice,10:F3} {callQuote.AskPrice,10:F3} {strike,10:F3} {putQuote.BidPrice,10:F3} {putQuote.AskPrice,10:F3}"); | ||
} | ||
} | ||
|
||
Environment.Exit(0); // shutdown when done | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// <copyright file="OptionChain.cs" company="Devexperts LLC"> | ||
// Copyright © 2024 Devexperts LLC. All rights reserved. | ||
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. | ||
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
// </copyright> | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace DxFeed.Graal.Net.Ipf.Option; | ||
|
||
public sealed class OptionChain<T> : ICloneable | ||
Check warning on line 12 in src/DxFeed.Graal.Net/Ipf/Option/OptionChain.cs GitHub Actions / Build & Test on win-x64
Check warning on line 12 in src/DxFeed.Graal.Net/Ipf/Option/OptionChain.cs GitHub Actions / Build & Test on linux-x64
|
||
{ | ||
private readonly string _symbol; | ||
|
||
private readonly SortedDictionary<OptionSeries<T>, OptionSeries<T>> seriesMap = new(); | ||
|
||
public OptionChain(string symbol) => this._symbol = symbol; | ||
Check warning on line 18 in src/DxFeed.Graal.Net/Ipf/Option/OptionChain.cs GitHub Actions / Build & Test on win-x64
Check warning on line 18 in src/DxFeed.Graal.Net/Ipf/Option/OptionChain.cs GitHub Actions / Build & Test on linux-x64
|
||
|
||
/// <summary> | ||
/// Returns a shallow copy of this option chain. | ||
/// All series are copied (cloned) themselves, but option instrument instances are shared with the original. | ||
/// </summary> | ||
/// <returns>A shallow copy of this option chain.</returns> | ||
public object Clone() | ||
{ | ||
OptionChain<T> clone = new OptionChain<T>(_symbol); | ||
foreach (OptionSeries<T> series in seriesMap.Values) | ||
{ | ||
OptionSeries<T> seriesClone = (OptionSeries<T>)series.Clone(); | ||
clone.seriesMap.Add(seriesClone, seriesClone); | ||
} | ||
Check warning on line 32 in src/DxFeed.Graal.Net/Ipf/Option/OptionChain.cs GitHub Actions / Build & Test on win-x64
Check warning on line 32 in src/DxFeed.Graal.Net/Ipf/Option/OptionChain.cs GitHub Actions / Build & Test on linux-x64
Check warning on line 32 in src/DxFeed.Graal.Net/Ipf/Option/OptionChain.cs GitHub Actions / Build & Test on osx-arm64
|
||
return clone; | ||
} | ||
|
||
/// <summary> | ||
/// Returns symbol (product or underlying) of this option chain. | ||
/// </summary> | ||
/// <returns>Symbol (product or underlying) of this option chain.</returns> | ||
public string GetSymbol() | ||
{ | ||
return _symbol; | ||
} | ||
|
||
/// <summary> | ||
/// Returns a sorted set of option series of this option chain. | ||
/// </summary> | ||
/// <returns>Sorted set of option series of this option chain.</returns> | ||
public SortedSet<OptionSeries<T>> GetSeries() | ||
{ | ||
return new SortedSet<OptionSeries<T>>(seriesMap.Keys); | ||
} | ||
|
||
internal void AddOption(OptionSeries<T> series, bool isCall, double strike, T option) | ||
{ | ||
if (!seriesMap.TryGetValue(series, out var os)) | ||
{ | ||
os = new OptionSeries<T>(series); | ||
seriesMap[os] = os; | ||
} | ||
Check warning on line 60 in src/DxFeed.Graal.Net/Ipf/Option/OptionChain.cs GitHub Actions / Build & Test on win-x64
Check warning on line 60 in src/DxFeed.Graal.Net/Ipf/Option/OptionChain.cs GitHub Actions / Build & Test on linux-x64
Check warning on line 60 in src/DxFeed.Graal.Net/Ipf/Option/OptionChain.cs GitHub Actions / Build & Test on osx-arm64
|
||
os.AddOption(isCall, strike, option); | ||
} | ||
} |