├── .gitignore
├── CHANGELOG.md
├── IQFeed.CSharpApiClient.sln
├── LICENSE
├── README.md
├── VERSION
├── appveyor.yml
├── data
├── dailies_newest.zip
├── dailies_oldest.zip
├── intervals_1s_newest.zip
├── intervals_1s_oldest.zip
├── intervals_5s_newest.zip
├── intervals_5s_oldest.zip
├── monthlies_newest.zip
├── monthlies_oldest.zip
├── samples
│ ├── IOPTION_sample.zip
│ └── mktsymbols_v2_sample.zip
├── ticks_newest.zip
├── ticks_oldest.zip
├── ticks_oldest60.zip
├── weeklies_newest.zip
└── weeklies_oldest.zip
├── docs
└── USING-WITH-PYTHON.md
└── src
├── IQFeed.CSharpApiClient.Examples
├── App.config
├── Common
│ ├── ConcurrentHistoricalBase.cs
│ ├── ConsoleHelper.cs
│ ├── DataType.cs
│ ├── IExample.cs
│ ├── IExampleAsync.cs
│ └── MarketData.cs
├── Examples
│ ├── BasicFileHistorical
│ │ └── BasicFileHistoricalExample.cs
│ ├── BasicHistorical
│ │ └── BasicHistoricalExample.cs
│ ├── ConcurrentFileHistorical
│ │ └── ConcurrentFileHistoricalExample.cs
│ ├── ConcurrentHistorical
│ │ └── ConcurrentHistoricalExample.cs
│ ├── ExpiredOptions
│ │ └── ExpiredOptionsExample.cs
│ ├── OptionableStocks
│ │ ├── OptionableStock.cs
│ │ └── OptionableStocksExample.cs
│ ├── StreamingLevel1
│ │ ├── StreamingLevel1DynamicExample.cs
│ │ ├── StreamingLevel1DynamicV2Example.cs
│ │ └── StreamingLevel1Example.cs
│ └── StreamingLevel2
│ │ └── StreamingLevel2Example.cs
├── IQFeed.CSharpApiClient.Examples.csproj
├── Program.cs
└── README.md
├── IQFeed.CSharpApiClient.Extensions.Tests.Integration
├── IQFeed.CSharpApiClient.Extensions.Tests.Integration.csproj
├── Lookup
│ └── Historical
│ │ └── Resample
│ │ ├── IntervalMessageExtensionsTests.cs
│ │ └── TickMessageExtensionsTests.cs
└── TestData
│ ├── TestData.cs
│ ├── TestDataTests.cs
│ └── TestDataType.cs
├── IQFeed.CSharpApiClient.Extensions.Tests
├── Common
│ ├── CultureNameTestCase.cs
│ └── TestHelper.cs
├── IQFeed.CSharpApiClient.Extensions.Tests.csproj
└── Lookup
│ └── Historical
│ ├── HistoricalBarTests.cs
│ └── Resample
│ ├── IntervalMessageExtensionsTests.cs
│ └── TickMessageExtensionsTests.cs
├── IQFeed.CSharpApiClient.Extensions
├── Common
│ └── DateTimeExtensions.cs
├── IQFeed.CSharpApiClient.Extensions.csproj
└── Lookup
│ └── Historical
│ ├── HistoricalBar.cs
│ └── Resample
│ ├── IntervalMessageExtensions.cs
│ └── TickMessageExtensions.cs
├── IQFeed.CSharpApiClient.Tests.Integration
├── App.config
├── IQFeed.CSharpApiClient.Tests.Integration.csproj
├── Lookup
│ ├── Chains
│ │ └── ChainsFacadeTests.cs
│ ├── Historical
│ │ ├── HistoricalFacadeMultiClientTests.cs
│ │ ├── HistoricalFacadeTests.cs
│ │ └── HistoricalFileFacadeTests.cs
│ ├── MarketSummary
│ │ ├── MarketSummaryFacadeTests.cs
│ │ └── MarketSummaryFileFacadeTests.cs
│ ├── News
│ │ └── NewsFacadeTests.cs
│ └── Symbol
│ │ ├── Downloader
│ │ └── FileDownloadTests.cs
│ │ ├── Settings.cs
│ │ └── SymbolFacadeTests.cs
└── Streaming
│ ├── Admin
│ └── AdminClientTests.cs
│ ├── Derivative
│ └── DerivativeClientTests.cs
│ ├── Level1
│ ├── Level1ClientDynamicFieldsetTests.cs
│ └── Level1ClientTests.cs
│ └── Level2
│ ├── Level2ClientOldProtocolTests.cs
│ └── Level2ClientTests.cs
├── IQFeed.CSharpApiClient.Tests
├── Common
│ ├── CultureNameTestCase.cs
│ ├── ExceptionFactoryTests.cs
│ └── TestHelper.cs
├── Extensions
│ ├── ByteExtensionsTests.cs
│ └── StringExtensionsTests.cs
├── IQFeed.CSharpApiClient.Tests.csproj
├── Lookup
│ ├── Chains
│ │ ├── Futures
│ │ │ └── FutureMonthCodeTests.cs
│ │ └── Messages
│ │ │ ├── EquityOptionMessageTests.cs
│ │ │ ├── FutureMessageTests.cs
│ │ │ ├── FutureOptionMessageTests.cs
│ │ │ └── FutureSpreadMessageTests.cs
│ ├── Common
│ │ ├── BaseLookupMessageHandlerTestClass.cs
│ │ └── BaseLookupMessageHandlerTests.cs
│ ├── Historical
│ │ ├── HistoricalRequestFormatterTests.cs
│ │ └── Messages
│ │ │ ├── DailyWeeklyMonthlyMessageTests.cs
│ │ │ ├── IntervalMessageTests.cs
│ │ │ └── TickMessageTests.cs
│ ├── LookupRateLimiterTests.cs
│ ├── MarketSummary
│ │ └── MarketSummaryMessageTests.cs
│ ├── News
│ │ └── NewsRequestFormatterTests.cs
│ └── Symbol
│ │ ├── Common
│ │ └── LocalCacheStrategyTests.cs
│ │ ├── Messages
│ │ └── SymbolByFilterMessageTests.cs
│ │ └── SymbolRequestFormatterTests.cs
├── Socket
│ └── SocketMessageHandlerTests.cs
└── Streaming
│ ├── Admin
│ └── AdminRequestFormatterTests.cs
│ ├── Common
│ └── Messages
│ │ ├── ErrorMessageTests.cs
│ │ ├── SymbolNotFoundMessageTests.cs
│ │ ├── SystemMessageTests.cs
│ │ └── TimestampMessageTests.cs
│ ├── Derivative
│ ├── DerivativeRequestFormatterTests.cs
│ └── Messages
│ │ └── IntervalBarMessageTest.cs
│ ├── Level1
│ ├── Dynamic
│ │ ├── Handlers
│ │ │ └── Level1DynamicMessageHandlerPerformanceTests.cs
│ │ └── Messages
│ │ │ └── UpdateSummaryDynamicMessageTypesFactoryTests.cs
│ ├── Handlers
│ │ ├── Level1MessageDynamicHandlerPerformanceTests.cs
│ │ └── Level1MessageHandlerPerformanceTests.cs
│ ├── Level1DynamicFieldsPerformanceTests.cs
│ ├── Level1DynamicFieldsTests.cs
│ ├── Level1RequestFormatterTests.cs
│ └── Messages
│ │ ├── FundamentalMessageTests.cs
│ │ ├── NewsMessageTests.cs
│ │ ├── RegionalUpdateMessageTests.cs
│ │ ├── TradeCorrectionMessageTests.cs
│ │ ├── UpdateSummaryMessagePerformanceTests.cs
│ │ └── UpdateSummaryMessageTests.cs
│ └── Level2
│ ├── Level2MessageHandlerTests.cs
│ ├── Level2RequestFormatterTests.cs
│ └── Messages
│ └── Level2MessageTests.cs
└── IQFeed.CSharpApiClient
├── Common
├── ExceptionFactory.cs
├── Exceptions
│ ├── IQFeedException.cs
│ ├── InvalidDataIQFeedException.cs
│ ├── NoDataIQFeedException.cs
│ └── SymbolNotFoundIQFeedException.cs
├── FieldParser.cs
├── Interfaces
│ ├── IClient.cs
│ └── IRequestFormatter.cs
├── InvalidMessage.cs
├── LoggingLevel.cs
├── MessageContainer.cs
├── Messages
│ └── ProtocolMessage.cs
└── RequestFormatter.cs
├── Extensions
├── ByteExtensions.cs
├── EnumExtensions.cs
├── EventExtentions.cs
├── NullableExtensions.cs
├── StringExtensions.cs
└── TaskExtensions.cs
├── IQFeed.CSharpApiClient.csproj
├── IQFeedDefault.cs
├── IQFeedLauncher.cs
├── Lookup
├── Chains
│ ├── ChainsFacade.cs
│ ├── ChainsMessageHandler.cs
│ ├── ChainsRequestFormatter.cs
│ ├── Equities
│ │ ├── EquityOption.cs
│ │ └── EquityOptionMonthCode.cs
│ ├── Futures
│ │ ├── Future.cs
│ │ ├── FutureMonthCode.cs
│ │ ├── FutureOption.cs
│ │ └── FutureSpread.cs
│ ├── IChainsFacade.cs
│ ├── IChainsFacadeSync.cs
│ ├── Messages
│ │ ├── ChainsMessage.cs
│ │ ├── EquityOptionMessage.cs
│ │ ├── FutureMessage.cs
│ │ ├── FutureOptionMessage.cs
│ │ └── FutureSpreadMessage.cs
│ ├── OptionFilterType.cs
│ ├── OptionSide.cs
│ └── OptionSideFilterType.cs
├── Common
│ ├── BaseLookupFacade.cs
│ ├── BaseLookupMessageHandler.cs
│ ├── LookupMessageFileHandler.cs
│ └── LookupMessageFileParser.cs
├── Historical
│ ├── Enums
│ │ ├── DataDirection.cs
│ │ └── LabelAtBeginning.cs
│ ├── Facades
│ │ ├── HistoricalFacade.cs
│ │ ├── HistoricalFileFacade.cs
│ │ ├── IHistoricalFacade.cs
│ │ └── IHistoricalFacadeSync.cs
│ ├── HistoricalIntervalType.cs
│ ├── HistoricalMessageHandler.cs
│ ├── HistoricalRequestFormatter.cs
│ ├── IHistoricalMessageHandler.cs
│ └── Messages
│ │ ├── DailyWeeklyMonthlyMessage.cs
│ │ ├── IDailyWeeklyMonthlyMessage.cs
│ │ ├── IHistoricalMessage.cs
│ │ ├── IIntervalMessage.cs
│ │ ├── ITickMessage.cs
│ │ ├── IntervalMessage.cs
│ │ └── TickMessage.cs
├── LookupClient.cs
├── LookupClientFactory.cs
├── LookupDefault.cs
├── LookupDispatcher.cs
├── LookupRateLimiter.cs
├── MarketSummary
│ ├── Facades
│ │ ├── IMarketSummaryFacade.cs
│ │ ├── MarketSummaryFacade.cs
│ │ └── MarketSummaryFileFacade.cs
│ ├── MarketSummaryDynamicFieldset.cs
│ ├── MarketSummaryFieldsetDescriptor.cs
│ ├── MarketSummaryHandler.cs
│ ├── MarketSummaryRequestFormatter.cs
│ └── Messages
│ │ └── MarketSummaryMessage.cs
├── News
│ ├── Enums
│ │ ├── FormatType.cs
│ │ └── NewsFormatType.cs
│ ├── INewsFacade.cs
│ ├── INewsFacadeSync.cs
│ ├── Messages
│ │ └── NewsHeadlinesMessage.cs
│ ├── NewsFacade.cs
│ ├── NewsMessageHandler.cs
│ └── NewsRequestFormatter.cs
└── Symbol
│ ├── Downloader
│ ├── FileDownloader.cs
│ ├── ILocalCacheStrategy.cs
│ └── LocalCacheStrategy.cs
│ ├── Enums
│ ├── FieldToSearch.cs
│ └── FilterType.cs
│ ├── ExpiredOptions
│ ├── ExpiredOption.cs
│ └── ExpiredOptionReader.cs
│ ├── ISymbolFacade.cs
│ ├── ISymbolFacadeDownload.cs
│ ├── ISymbolFacadeSync.cs
│ ├── ListedMarket.cs
│ ├── MarketSymbols
│ ├── MarketSymbol.cs
│ ├── MarketSymbolExchange.cs
│ ├── MarketSymbolExtensions.cs
│ ├── MarketSymbolListedMarket.cs
│ ├── MarketSymbolReader.cs
│ └── MarketSymbolSecurityType.cs
│ ├── Messages
│ ├── ListedMarketMessage.cs
│ ├── NaicsCodeInfoMessage.cs
│ ├── SecurityTypeMessage.cs
│ ├── SicCodeInfoMessage.cs
│ ├── SymbolByFilterMessage.cs
│ ├── SymbolByNaicsCodeMessage.cs
│ ├── SymbolBySicCodeMessage.cs
│ └── TradeConditionMessage.cs
│ ├── SecurityType.cs
│ ├── SymbolDefault.cs
│ ├── SymbolFacade.cs
│ ├── SymbolMessageHandler.cs
│ └── SymbolRequestFormatter.cs
├── Socket
├── SocketClient.cs
├── SocketDiagnostic.cs
├── SocketMessageEventArgs.cs
└── SocketMessageHandler.cs
└── Streaming
├── Admin
├── AdminClient.cs
├── AdminClientFactory.cs
├── AdminMessageHandler.cs
├── AdminRequestFormatter.cs
├── ClientType.cs
├── IAdminClient.cs
├── IAdminMessage.cs
├── Messages
│ ├── AutoConnectMessage.cs
│ ├── AutoConnectMessageType.cs
│ ├── ClientAppMessage.cs
│ ├── ClientAppMessageType.cs
│ ├── ClientStatsMessage.cs
│ ├── LoginIdMessage.cs
│ ├── LoginInfoMessage.cs
│ ├── LoginInfoMessageType.cs
│ ├── PasswordMessage.cs
│ └── StatsMessage.cs
└── StatsStatusType.cs
├── Common
└── Messages
│ ├── ErrorMessage.cs
│ ├── SymbolNotFoundMessage.cs
│ ├── SystemMessage.cs
│ └── TimestampMessage.cs
├── Derivative
├── DerivativeClient.cs
├── DerivativeClientFactory.cs
├── DerivativeDefault.cs
├── DerivativeIntervalType.cs
├── DerivativeMessageHandler.cs
├── DerivativeRequestFormatter.cs
├── DerivativeWatchDefinition.cs
├── IDerivativeClient.cs
├── IDerivativeEvent.cs
├── IDerivativeMessageHandler.cs
└── Messages
│ ├── IIntervalBarMessage.cs
│ ├── IntervalBarMessage.cs
│ └── IntervalBarType.cs
├── FieldsetDescriptionAttribute.cs
├── Level1
├── Dynamic
│ ├── Handlers
│ │ ├── ILevel1DynamicMessageHandler.cs
│ │ └── Level1DynamicMessageHandler.cs
│ ├── ILevel1DynamicClient.cs
│ ├── ILevel1DynamicEvent.cs
│ ├── ILevel1DynamicSnapshot.cs
│ ├── ILevel1DynamicSnapshotSync.cs
│ ├── Level1DynamicClient.cs
│ ├── Level1DynamicClientFactory.cs
│ ├── Level1DynamicSnapshot.cs
│ └── Messages
│ │ ├── IUpdateSummaryDynamicMessage.cs
│ │ └── UpdateSummaryDynamicMessageTypesFactory.cs
├── DynamicFieldset.cs
├── Handlers
│ ├── BaseLevel1MessageHandler.cs
│ ├── ILevel1MessageDynamicHandler.cs
│ ├── ILevel1MessageHandler.cs
│ ├── Level1MessageDynamicHandler.cs
│ └── Level1MessageHandler.cs
├── ILevel1Client.cs
├── ILevel1Event.cs
├── ILevel1EventCommon.cs
├── ILevel1Snapshot.cs
├── ILevel1SnapshotSync.cs
├── Level1Client.cs
├── Level1ClientBase.cs
├── Level1ClientFactory.cs
├── Level1Default.cs
├── Level1DynamicFields.cs
├── Level1RequestFormatter.cs
├── Level1Snapshot.cs
└── Messages
│ ├── FundamentalMessage.cs
│ ├── IRegionalUpdateMessage.cs
│ ├── ITradeCorrectionMessage.cs
│ ├── IUpdateSummaryMessage.cs
│ ├── NewsMessage.cs
│ ├── RegionalUpdateMessage.cs
│ ├── TradeCorrectionMessage.cs
│ ├── UpdateSummaryDynamicMessage.cs
│ └── UpdateSummaryMessage.cs
└── Level2
├── Enums
├── Level2MessageType.cs
└── Level2Side.cs
├── ILevel2Client.cs
├── ILevel2Event.cs
├── ILevel2MessageHandler.cs
├── ILevel2Snapshot.cs
├── Level2Client.cs
├── Level2ClientFactory.cs
├── Level2Default.cs
├── Level2MessageHandler.cs
├── Level2RequestFormatter.cs
├── Level2Snapshot.cs
└── Messages
├── IOrderAddUpdateSummaryMessage.cs
├── IOrderDeleteMessage.cs
├── IPriceLevelDeleteMessage.cs
├── IPriceLevelUpdateSummaryMessage.cs
├── IUpdateSummaryMessage.cs
├── MarketMakerNameMessage.cs
├── OrderAddUpdateSummaryMessage.cs
├── OrderDeleteMessage.cs
├── PriceLevelDeleteMessage.cs
├── PriceLevelOrderMessage.cs
├── PriceLevelUpdateSummaryMessage.cs
└── UpdateSummaryMessage.cs
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Mathieu Paquette
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 2.10.0
2 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | image: Visual Studio 2022
2 |
3 | version: '{build}'
4 |
5 | install:
6 | - ps: >-
7 | $FileVersion = Get-Content $env:appveyor_build_folder\VERSION
8 |
9 | $Version = If ($env:appveyor_repo_branch -eq "release") {"$FileVersion"} Else {"$FileVersion.$env:appveyor_build_number"}
10 |
11 | Update-AppveyorBuild -Version $Version
12 |
13 | dotnet_csproj:
14 | patch: true
15 | file: '**\*.csproj'
16 | version: '{version}'
17 | package_version: '{version}'
18 | assembly_version: '{version}'
19 | file_version: '{version}'
20 | informational_version: '{version}'
21 |
22 | configuration: Release
23 |
24 | before_build:
25 | - nuget restore
26 | - dotnet restore
27 |
28 | test_script:
29 | - cmd: dotnet test .\src\IQFeed.CSharpApiClient.Tests\IQFeed.CSharpApiClient.Tests.csproj
30 | - cmd: dotnet test .\src\IQFeed.CSharpApiClient.Extensions.Tests\IQFeed.CSharpApiClient.Extensions.Tests.csproj
31 | - cmd: dotnet test .\src\IQFeed.CSharpApiClient.Extensions.Tests.Integration\IQFeed.CSharpApiClient.Extensions.Tests.Integration.csproj
32 |
33 | build:
34 | project: IQFeed.CSharpApiClient.sln
35 | publish_nuget: true
36 | publish_nuget_symbols: true
37 | verbosity: normal
38 |
39 | deploy:
40 | # Deploying to NuGet feed (MyGet.org)
41 | - provider: NuGet
42 | name: MyGet
43 | server: https://www.myget.org/F/iqfeedcsharpapiclient/api/v2/package
44 | api_key:
45 | secure: UBKXVuF4UwMea9mcl8hGLaHxOTBu3GNgzPvuEUWIzU+Nf6a8eTtBRyKITBepZl6i
46 | skip_symbols: false
47 | symbol_server: https://www.myget.org/F/iqfeedcsharpapiclient/symbols/api/v2/package
48 | artifact: /.*\.nupkg/
49 |
50 | # Deploying to NuGet feed (NuGet.org)
51 | - provider: NuGet
52 | name: NuGet
53 | on:
54 | branch: release
55 | server: https://www.nuget.org/api/v2/package
56 | api_key:
57 | secure: LVcj56aqBOqfj6uavO70Bjxj6WwrXOH0kzoCfBFcZeZ+Xlmf3CEHIG7sa21TFCoq
58 | skip_symbols: true
59 | symbol_server: https://nuget.smbsrc.net/
60 | artifact: /.*\.nupkg/
61 |
--------------------------------------------------------------------------------
/data/dailies_newest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/dailies_newest.zip
--------------------------------------------------------------------------------
/data/dailies_oldest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/dailies_oldest.zip
--------------------------------------------------------------------------------
/data/intervals_1s_newest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/intervals_1s_newest.zip
--------------------------------------------------------------------------------
/data/intervals_1s_oldest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/intervals_1s_oldest.zip
--------------------------------------------------------------------------------
/data/intervals_5s_newest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/intervals_5s_newest.zip
--------------------------------------------------------------------------------
/data/intervals_5s_oldest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/intervals_5s_oldest.zip
--------------------------------------------------------------------------------
/data/monthlies_newest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/monthlies_newest.zip
--------------------------------------------------------------------------------
/data/monthlies_oldest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/monthlies_oldest.zip
--------------------------------------------------------------------------------
/data/samples/IOPTION_sample.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/samples/IOPTION_sample.zip
--------------------------------------------------------------------------------
/data/samples/mktsymbols_v2_sample.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/samples/mktsymbols_v2_sample.zip
--------------------------------------------------------------------------------
/data/ticks_newest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/ticks_newest.zip
--------------------------------------------------------------------------------
/data/ticks_oldest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/ticks_oldest.zip
--------------------------------------------------------------------------------
/data/ticks_oldest60.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/ticks_oldest60.zip
--------------------------------------------------------------------------------
/data/weeklies_newest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/weeklies_newest.zip
--------------------------------------------------------------------------------
/data/weeklies_oldest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathpaquette/IQFeed.CSharpApiClient/59804b4180b262dea8d5f090417a943b27bf4e4f/data/weeklies_oldest.zip
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/Common/ConcurrentHistoricalBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Threading.Tasks;
4 | using IQFeed.CSharpApiClient.Lookup;
5 |
6 | namespace IQFeed.CSharpApiClient.Examples.Common
7 | {
8 | public abstract class ConcurrentHistoricalBase
9 | {
10 | protected readonly LookupClient LookupClient;
11 | protected readonly ConcurrentQueue Symbols;
12 | protected int InitialCount = 0;
13 |
14 | private readonly Task[] _concurrentTasks;
15 |
16 | protected ConcurrentHistoricalBase(LookupClient lookupClient, int numberOfClients)
17 | {
18 | LookupClient = lookupClient;
19 | Symbols = new ConcurrentQueue();
20 | _concurrentTasks = new Task[numberOfClients];
21 | }
22 |
23 | public void Start()
24 | {
25 | InitialCount = Symbols.Count;
26 |
27 | Console.WriteLine($"Number of Concurrent Tasks: {_concurrentTasks.Length}");
28 | Console.WriteLine($"Number of Symbols: {InitialCount}");
29 | Console.Write("Status: ");
30 |
31 | for (var i = 0; i < _concurrentTasks.Length; i++)
32 | {
33 | _concurrentTasks[i] = Task.Run(async () => await ProcessSymbols());
34 | }
35 |
36 | Task.WaitAll(_concurrentTasks);
37 | }
38 |
39 | protected void ShowDownloadStatus()
40 | {
41 | var count = Symbols.Count;
42 | if (count % 10 != 0) return;
43 |
44 | var progress = (InitialCount - count) / (double)InitialCount * 100;
45 | Console.Write($"{progress}%...");
46 | }
47 |
48 | protected abstract Task ProcessSymbols();
49 | }
50 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/Common/ConsoleHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Examples.Common
4 | {
5 | public class ConsoleHelper
6 | {
7 | public static void ShowStarted(string name)
8 | {
9 | Console.WriteLine("");
10 | Console.WriteLine("--------------------------------------------------");
11 | Console.WriteLine($" {name} started...");
12 | Console.WriteLine("--------------------------------------------------");
13 | Console.WriteLine("");
14 | }
15 |
16 | public static void ShowFinished(string name)
17 | {
18 | Console.WriteLine("");
19 | Console.WriteLine("--------------------------------------------------");
20 | Console.WriteLine($" {name} finished!");
21 | Console.WriteLine("--------------------------------------------------");
22 | Console.WriteLine("");
23 | }
24 |
25 | public static void PressEnterToContinue()
26 | {
27 | Console.WriteLine("");
28 | Console.WriteLine("*************************************");
29 | Console.WriteLine("** PRESS ENTER TO CONTINUE **");
30 | Console.WriteLine("*************************************");
31 | Console.ReadLine();
32 | }
33 |
34 | public static void ShowExamplesCompleted()
35 | {
36 | Console.ForegroundColor = ConsoleColor.Green;
37 | Console.WriteLine(" EXAMPLE(S) COMPLETED!");
38 | Console.ForegroundColor = ConsoleColor.Gray;
39 | }
40 |
41 | public static void ShowEnableWarning()
42 | {
43 | Console.ForegroundColor = ConsoleColor.Red;
44 | Console.WriteLine("!!! WARNING !!!");
45 | Console.WriteLine(" PLEASE ENABLE AT LEAST ONE EXAMPLE BY SETTING TO TRUE THE 'ENABLE' PROPERTY FROM ONE OF THESE FILES:");
46 | Console.WriteLine("!!! WARNING !!!");
47 | Console.WriteLine("");
48 | Console.ForegroundColor = ConsoleColor.Gray;
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/Common/DataType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Examples.Common
2 | {
3 | public class DataType
4 | {
5 | public const string Tick = "tick";
6 | public const string Interval = "interval";
7 | public const string EOD = "eod";
8 | }
9 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/Common/IExample.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace IQFeed.CSharpApiClient.Examples.Common
4 | {
5 | public interface IExample
6 | {
7 | void Run();
8 | bool Enable { get; }
9 | string Name { get; }
10 | }
11 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/Common/IExampleAsync.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace IQFeed.CSharpApiClient.Examples.Common
4 | {
5 | public interface IExampleAsync : IExample
6 | {
7 | Task RunAsync();
8 | }
9 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/Examples/BasicFileHistorical/BasicFileHistoricalExample.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using IQFeed.CSharpApiClient.Examples.Common;
6 | using IQFeed.CSharpApiClient.Lookup;
7 | using IQFeed.CSharpApiClient.Lookup.Historical.Messages;
8 |
9 | namespace IQFeed.CSharpApiClient.Examples.Examples.BasicFileHistorical
10 | {
11 | public class BasicFileHistoricalExample : IExampleAsync
12 | {
13 | public bool Enable => false; // *** SET TO TRUE TO RUN THIS EXAMPLE ***
14 | public string Name => nameof(BasicFileHistoricalExample);
15 |
16 | private const string DownloadBasePath = "downloads";
17 | private const string Symbol = "AAPL";
18 |
19 | public async Task RunAsync()
20 | {
21 | // *************************************
22 |
23 | // Step 1 - !!! Configure your credentials for IQConnect in user environment variable or app.config !!!
24 | // Check the documentation for more information.
25 |
26 | // Step 2 - Run IQConnect launcher
27 | IQFeedLauncher.Start();
28 |
29 | // Step 3 - Use the appropriate factory to create the client
30 | var lookupClient = LookupClientFactory.CreateNew();
31 |
32 | // Step 4 - Connect it
33 | lookupClient.Connect();
34 |
35 | var tmpFilename = await lookupClient.Historical.File.GetHistoryTickDatapointsAsync(Symbol, 1000);
36 | // Step 5 - Make file request!
37 |
38 | // Step 6 - Move the file
39 | var basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DownloadBasePath);
40 | var fullPath = Path.Combine(basePath, $"{DateTime.Now:yyyyMMddHHmmss}-{Symbol}.csv");
41 |
42 | Directory.CreateDirectory(basePath);
43 | File.Move(tmpFilename, fullPath);
44 |
45 | // Step 7 - Parse TickMessages from saved file
46 | var ticks = TickMessage.ParseFromFile(fullPath).ToList();
47 |
48 | Console.WriteLine($"Saved {Symbol} ticks in {fullPath}");
49 | }
50 |
51 | public void Run()
52 | {
53 | throw new System.NotImplementedException();
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/Examples/BasicHistorical/BasicHistoricalExample.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Threading.Tasks;
4 | using IQFeed.CSharpApiClient.Examples.Common;
5 | using IQFeed.CSharpApiClient.Lookup;
6 |
7 | namespace IQFeed.CSharpApiClient.Examples.Examples.BasicHistorical
8 | {
9 | public class BasicHistoricalExample : IExampleAsync
10 | {
11 | public bool Enable => false; // *** SET TO TRUE TO RUN THIS EXAMPLE ***
12 | public string Name => nameof(BasicHistoricalExample);
13 |
14 | public async Task RunAsync()
15 | {
16 | // *************************************
17 |
18 | // Step 1 - !!! Configure your credentials for IQConnect in user environment variable or app.config !!!
19 | // Check the documentation for more information.
20 |
21 | // Step 2 - Run IQConnect launcher
22 | IQFeedLauncher.Start();
23 |
24 | // Step 3 - Use the appropriate factory to create the client
25 | var lookupClient = LookupClientFactory.CreateNew();
26 |
27 | // Step 4 - Connect it
28 | lookupClient.Connect();
29 |
30 | // Step 5 - Make any requests you need or want!
31 | var tickMessages = await lookupClient.Historical.GetHistoryTickDatapointsAsync("AAPL", 100);
32 | var intervalMessage = await lookupClient.Historical.GetHistoryIntervalDaysAsync("AAPL", 5, 10, 100);
33 | var dailyMessages = await lookupClient.Historical.GetHistoryDailyDatapointsAsync("AAPL", 100);
34 |
35 | Console.WriteLine($"Fetched {tickMessages.Count()} Tick messages");
36 | Console.WriteLine($"Fetched {intervalMessage.Count()} Interval messages");
37 | Console.WriteLine($"Fetched {dailyMessages.Count()} Daily messages");
38 | }
39 |
40 | void IExample.Run()
41 | {
42 | throw new System.NotImplementedException();
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/Examples/ExpiredOptions/ExpiredOptionsExample.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using IQFeed.CSharpApiClient.Examples.Common;
4 | using IQFeed.CSharpApiClient.Lookup;
5 |
6 | namespace IQFeed.CSharpApiClient.Examples.Examples.ExpiredOptions
7 | {
8 | public class ExpiredOptionsExample : IExample
9 | {
10 | public bool Enable => false; // *** SET TO TRUE TO RUN THIS EXAMPLE ***
11 | public string Name => nameof(ExpiredOptionsExample);
12 |
13 | ///
14 | /// Please note that Expired Options file is huge.
15 | /// It's about 600 MB so iterating through all rows
16 | /// will take a while, especially if you don't have SSD.
17 | ///
18 | public void Run()
19 | {
20 | var lookupClient = LookupClientFactory.CreateNew();
21 |
22 | Console.WriteLine("Downloading and Caching Expired Options file from IQFeed servers...");
23 | Console.WriteLine("*** This may take a while the first time... ***\n");
24 |
25 | // Getting the first 10000 expired options with Expiration date >= Today - 180 days
26 | var expiredOptionsGreaterThan180Days = lookupClient.Symbol.GetAllExpiredOptions()
27 | .Select(x => x.EquityOption)
28 | .Where(x => x.Expiration >= DateTime.Now.AddDays(-180))
29 | .Take(10000) // COMMENT OUT THIS LINE TO GET THEM ALL
30 | .ToList();
31 |
32 | Console.WriteLine($"Found {expiredOptionsGreaterThan180Days.Count} expired options matching Expiration date >= Today - 180 days");
33 |
34 |
35 | // Getting the first 10000 expired options for APPL stock
36 | var expiredOptionsForSpecificStock = lookupClient.Symbol.GetAllExpiredOptions()
37 | .Select(x => x.EquityOption)
38 | .Where(x => x.EquitySymbol == "AAPL")
39 | .Take(10000) // COMMENT OUT THIS LINE TO GET THEM ALL
40 | .ToList();
41 |
42 | Console.WriteLine($"Found {expiredOptionsForSpecificStock.Count} expired options for AAPL stock");
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/Examples/OptionableStocks/OptionableStock.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using IQFeed.CSharpApiClient.Lookup.Chains.Equities;
4 | using IQFeed.CSharpApiClient.Lookup.Symbol.MarketSymbols;
5 |
6 | namespace IQFeed.CSharpApiClient.Examples.Examples.OptionableStocks
7 | {
8 | public class OptionableStock
9 | {
10 | public OptionableStock(MarketSymbol marketSymbol, IEnumerable options)
11 | {
12 | MarketSymbol = marketSymbol;
13 | Options = options;
14 | }
15 |
16 | public MarketSymbol MarketSymbol { get; }
17 | public IEnumerable Options { get; }
18 |
19 | public static IEnumerable GetOptionableStocks(IEnumerable marketSymbols)
20 | {
21 | var options = new List();
22 | var equities = new List();
23 | var indexes = new List();
24 |
25 | foreach (var marketSymbol in marketSymbols)
26 | {
27 | switch (marketSymbol.SecurityType)
28 | {
29 | case MarketSymbolSecurityType.IEOPTION when !string.IsNullOrEmpty(marketSymbol.Description):
30 | options.Add(marketSymbol);
31 | break;
32 |
33 | case MarketSymbolSecurityType.EQUITY:
34 | equities.Add(marketSymbol);
35 | break;
36 |
37 | case MarketSymbolSecurityType.INDEX:
38 | indexes.Add(marketSymbol);
39 | break;
40 | }
41 | }
42 |
43 | var equityOptionsBySymbol = options.Select(x => EquityOption.Parse(x.Symbol)).GroupBy(x => x.EquitySymbol);
44 | var equitiesBySymbol = equities.Concat(indexes).ToDictionary(x => x.Symbol);
45 |
46 | foreach (var equityOptions in equityOptionsBySymbol)
47 | {
48 | if (equitiesBySymbol.TryGetValue(equityOptions.Key, out var equity))
49 | {
50 | yield return new OptionableStock(equity, equityOptions);
51 | }
52 | }
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/Examples/OptionableStocks/OptionableStocksExample.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using IQFeed.CSharpApiClient.Examples.Common;
4 | using IQFeed.CSharpApiClient.Lookup;
5 |
6 | namespace IQFeed.CSharpApiClient.Examples.Examples.OptionableStocks
7 | {
8 | public class OptionableStocksExample : IExample
9 | {
10 | public bool Enable => false; // *** SET TO TRUE TO RUN THIS EXAMPLE ***
11 | public string Name => nameof(OptionableStocksExample);
12 |
13 | public void Run()
14 | {
15 | var lookupClient = LookupClientFactory.CreateNew();
16 |
17 | Console.WriteLine("Downloading and Caching Market Symbols file from IQFeed servers...");
18 | Console.WriteLine("Please note that this file is updated every day.");
19 | Console.WriteLine("*** This may take a while the first time... ***\n");
20 |
21 | var marketSymbols = lookupClient.Symbol.GetAllMarketSymbols();
22 | var optionableStocks = OptionableStock.GetOptionableStocks(marketSymbols).ToList();
23 |
24 | foreach (var optionableStock in optionableStocks)
25 | {
26 | Console.WriteLine($"{optionableStock.MarketSymbol.Symbol} has {optionableStock.Options.Count()} options");
27 | }
28 |
29 | Console.WriteLine($"Found {optionableStocks.Count} stocks with options");
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/IQFeed.CSharpApiClient.Examples.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net472;net60
4 |
5 | Exe
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Examples/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Threading.Tasks;
4 | using IQFeed.CSharpApiClient.Examples.Common;
5 |
6 | namespace IQFeed.CSharpApiClient.Examples
7 | {
8 | class Program
9 | {
10 | static void Main(string[] args)
11 | {
12 | RunExamples().Wait();
13 | ConsoleHelper.PressEnterToContinue();
14 | }
15 |
16 | ///
17 | /// Running the examples one by one. You don't need to look here.
18 | /// Check the Example files only.
19 | ///
20 | ///
21 | static async Task RunExamples()
22 | {
23 | var examples = AppDomain.CurrentDomain.GetAssemblies()
24 | .SelectMany(s => s.GetTypes())
25 | .Where(p => typeof(IExample).IsAssignableFrom(p) && !p.IsInterface).OrderBy(x => x.Name).ToList();
26 |
27 | var enabledExamples = examples.Select(x => (IExample)Activator.CreateInstance(x)).Where(example => example.Enable).ToList();
28 |
29 | if (enabledExamples.Count == 0)
30 | {
31 | ConsoleHelper.ShowEnableWarning();
32 |
33 | foreach (var example in examples)
34 | Console.WriteLine($"{example.Name}.cs");
35 | }
36 |
37 | foreach (var example in enabledExamples)
38 | {
39 | ConsoleHelper.ShowStarted(example.Name);
40 | if (example is IExampleAsync exampleAsync)
41 | {
42 | await exampleAsync.RunAsync();
43 | }
44 | else
45 | {
46 | example.Run();
47 | }
48 | ConsoleHelper.ShowFinished(example.Name);
49 | }
50 |
51 | if (enabledExamples.Count > 0)
52 | ConsoleHelper.ShowExamplesCompleted();
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Extensions.Tests.Integration/IQFeed.CSharpApiClient.Extensions.Tests.Integration.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net472;net60
4 | OnBuildSuccess
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
23 |
24 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Extensions.Tests.Integration/Lookup/Historical/Resample/IntervalMessageExtensionsTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using IQFeed.CSharpApiClient.Extensions.Lookup.Historical.Resample;
4 | using IQFeed.CSharpApiClient.Extensions.Tests.Integration.TestData;
5 | using IQFeed.CSharpApiClient.Lookup.Historical.Enums;
6 | using IQFeed.CSharpApiClient.Lookup.Historical.Messages;
7 | using NUnit.Framework;
8 |
9 | namespace IQFeed.CSharpApiClient.Extensions.Tests.Integration.Lookup.Historical.Resample
10 | {
11 | public class IntervalMessageExtensionsTests
12 | {
13 | [Test]
14 | public void Should_Resample_Bars_From_Intervals()
15 | {
16 | // Arrange
17 | var intervals1S = IntervalMessage.ParseFromFile(TestData.TestData.GetFileName(TestDataType.Intervals_1s, DataDirection.Oldest)).ToList();
18 | var intervals5S = IntervalMessage.ParseFromFile(TestData.TestData.GetFileName(TestDataType.Intervals_5s, DataDirection.Oldest)).ToList();
19 |
20 | // Act
21 | var bars = intervals1S.ToHistoricalBars(TimeSpan.FromSeconds(5), DataDirection.Oldest).ToList().ToList();
22 |
23 | // Assert
24 | Assert.IsNotEmpty(intervals5S);
25 | Assert.AreEqual(intervals5S.Count, bars.Count);
26 |
27 | for (var i = 0; i < intervals5S.Count; i++)
28 | {
29 | var interval = intervals5S[i];
30 | var bar = bars[i];
31 |
32 | // TODO: create comparable
33 | if (interval.Timestamp == bar.Timestamp &&
34 | interval.Open == bar.Open &&
35 | interval.High == bar.High &&
36 | interval.Low == bar.Low &&
37 | interval.Close == bar.Close &&
38 | interval.PeriodVolume == bar.PeriodVolume &&
39 | interval.TotalVolume == bar.TotalVolume)
40 | {
41 | continue;
42 | }
43 |
44 | throw new Exception();
45 | }
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Extensions.Tests.Integration/TestData/TestData.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.IO.Compression;
3 | using IQFeed.CSharpApiClient.Lookup.Historical.Enums;
4 | using NUnit.Framework;
5 |
6 | namespace IQFeed.CSharpApiClient.Extensions.Tests.Integration.TestData
7 | {
8 | public class TestData
9 | {
10 | public static string GetFileName(TestDataType type, DataDirection direction, bool protocol60 = false)
11 | {
12 | var protocol60String = protocol60 ? "60" : string.Empty;
13 | var filename = $@"{type.ToString().ToLower()}_{direction.ToString().ToLower()}{protocol60String}";
14 | var path = Path.Combine(TestContext.CurrentContext.TestDirectory, "data", $@"{filename}.zip");
15 | var tmpDir = GetTemporaryDirectory();
16 | ZipFile.ExtractToDirectory(path, tmpDir);
17 | return Path.Combine(tmpDir, $@"{filename}.csv");
18 | }
19 |
20 | public static string GetTemporaryDirectory()
21 | {
22 | string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
23 | Directory.CreateDirectory(tempDirectory);
24 | return tempDirectory;
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Extensions.Tests.Integration/TestData/TestDataType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Extensions.Tests.Integration.TestData
2 | {
3 | public enum TestDataType
4 | {
5 | Dailies,
6 | Intervals_1s,
7 | Intervals_5s,
8 | Monthlies,
9 | Ticks,
10 | Weeklies
11 | }
12 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Extensions.Tests/Common/CultureNameTestCase.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using NUnit.Framework;
3 |
4 | namespace IQFeed.CSharpApiClient.Extensions.Tests.Common
5 | {
6 | public class CultureNameTestCase
7 | {
8 | public static IEnumerable CultureNames
9 | {
10 | get
11 | {
12 | yield return new TestCaseData("en-US");
13 | yield return new TestCaseData("fr-FR");
14 | yield return new TestCaseData("ru-RU");
15 | yield return new TestCaseData("ja-JP");
16 | yield return new TestCaseData("ar-SA");
17 | }
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Extensions.Tests/Common/TestHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Threading;
3 |
4 | namespace IQFeed.CSharpApiClient.Extensions.Tests.Common
5 | {
6 | public static class TestHelper
7 | {
8 | public static void SetThreadCulture(string cultureName)
9 | {
10 | var culture = CultureInfo.GetCultureInfo(cultureName);
11 | Thread.CurrentThread.CurrentCulture = culture;
12 | Thread.CurrentThread.CurrentUICulture = culture;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Extensions.Tests/IQFeed.CSharpApiClient.Extensions.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net472;net60
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Extensions.Tests/Lookup/Historical/HistoricalBarTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Extensions.Lookup.Historical;
3 | using IQFeed.CSharpApiClient.Extensions.Tests.Common;
4 | using NUnit.Framework;
5 |
6 | namespace IQFeed.CSharpApiClient.Extensions.Tests.Lookup.Historical
7 | {
8 | public class HistoricalBarTests
9 | {
10 | private HistoricalBar _historicalBar;
11 |
12 | [SetUp]
13 | public void SetUp()
14 | {
15 | _historicalBar = new HistoricalBar(new DateTime(2020, 01, 01, 9, 30, 00), 1.21, 1.22, 1.23, 1.24, 1000, 1, 100, 1, 12345.12345);
16 | }
17 |
18 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
19 | public void Should_Return_Csv(string cultureName)
20 | {
21 | // Act
22 | TestHelper.SetThreadCulture(cultureName);
23 | var csv = _historicalBar.ToCsv();
24 |
25 | // Assert
26 | var expectedCsv = "2020-01-01 09:30:00,1.21,1.22,1.23,1.24,1000,1,100,1,12345.1234";
27 | Assert.AreEqual(expectedCsv, csv);
28 | }
29 |
30 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
31 | public void Should_Parse(string cultureName)
32 | {
33 | // Arrange
34 | TestHelper.SetThreadCulture(cultureName);
35 | var csv = "2020-01-01 09:30:00,1.21,1.22,1.23,1.24,1000,1,100,1,12345.12345";
36 |
37 | // Act
38 | var parsed = HistoricalBar.Parse(csv);
39 |
40 | // Assert
41 | Assert.AreEqual(parsed, _historicalBar);
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Extensions/Common/DateTimeExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Extensions.Common
4 | {
5 | public static class DateTimeExtensions
6 | {
7 | public static DateTime Trim(this DateTime date, long roundTicks)
8 | {
9 | return new DateTime(date.Ticks - date.Ticks % roundTicks, date.Kind);
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Extensions/IQFeed.CSharpApiClient.Extensions.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net472;netstandard2.1
4 |
5 |
6 | Full
7 |
8 | true
9 | Mathieu Paquette
10 |
11 | DTN IQFeed Socket API (Client)
12 | https://github.com/mathpaquette/IQFeed.CSharpApiClient
13 | https://github.com/mathpaquette/IQFeed.CSharpApiClient
14 | LICENSE
15 | Copyright © 2020 Mathieu Paquette
16 | IQFeed.CSharpApiClient is fastest and the most well-designed C# DTN IQFeed socket API connector available to the open source community!
17 | 1.0.0.0
18 | 1.0.0.0
19 | 1.0.0
20 |
21 |
22 |
23 | True
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests.Integration/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests.Integration/IQFeed.CSharpApiClient.Tests.Integration.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net472;net60
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests.Integration/Lookup/Symbol/Downloader/FileDownloadTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using IQFeed.CSharpApiClient.Lookup.Symbol.Downloader;
4 | using NUnit.Framework;
5 |
6 | namespace IQFeed.CSharpApiClient.Tests.Integration.Lookup.Symbol.Downloader
7 | {
8 | public class FileDownloadTests
9 | {
10 | private FileDownloader _fileDownloader;
11 |
12 | [SetUp]
13 | public void SetUp()
14 | {
15 | _fileDownloader = new FileDownloader(new LocalCacheStrategy());
16 | }
17 |
18 | [Test]
19 | public void Should_Return_Text_Filename_From_Sample_Archive_File()
20 | {
21 | // Act
22 | var filename = _fileDownloader.GetFile(Settings.MarketSymbolsSampleUrl, false, TimeSpan.FromDays(1));
23 |
24 | // Assert
25 | Assert.True(filename.EndsWith("mktsymbols_v2_sample.txt"));
26 | }
27 |
28 | [Test]
29 | public void Should_Return_Text_Filename_From_Sample_Archive_File_Folder()
30 | {
31 | // Arrange
32 | var downloadPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dowload_folder");
33 | CreateDirectory(downloadPath);
34 |
35 | // Act
36 | var filename = _fileDownloader.GetFile(downloadPath, Settings.MarketSymbolsSampleUrl, false, TimeSpan.FromDays(1));
37 |
38 | // Assert
39 | Assert.True(filename.EndsWith("mktsymbols_v2_sample.txt"));
40 | }
41 |
42 | private void CreateDirectory(string path)
43 | {
44 | if (!Directory.Exists(path))
45 | {
46 | Directory.CreateDirectory(path);
47 | }
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests.Integration/Lookup/Symbol/Settings.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Tests.Integration.Lookup.Symbol
2 | {
3 | public class Settings
4 | {
5 | public const string MarketSymbolsSampleUrl = "https://github.com/mathpaquette/IQFeed.CSharpApiClient/raw/master/data/samples/mktsymbols_v2_sample.zip";
6 | public const int MarketSymbolsSampleCount = 65;
7 |
8 | public const string ExpiredOptionsSampleUrl = "https://github.com/mathpaquette/IQFeed.CSharpApiClient/raw/master/data/samples/IOPTION_sample.zip";
9 | public const int ExpiredOptionsSampleCount = 50;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests.Integration/Streaming/Level1/Level1ClientTests.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using IQFeed.CSharpApiClient.Common.Exceptions;
3 | using IQFeed.CSharpApiClient.Streaming.Level1;
4 | using IQFeed.CSharpApiClient.Streaming.Level1.Handlers;
5 | using NUnit.Framework;
6 |
7 | namespace IQFeed.CSharpApiClient.Tests.Integration.Streaming.Level1
8 | {
9 | public class Level1ClientTests
10 | {
11 | private const string Symbol = "AAPL";
12 | private const string NotFoundSymbol = "NotFoundSymbol";
13 | private ILevel1Client _level1Client;
14 |
15 | public Level1ClientTests()
16 | {
17 | IQFeedLauncher.Start();
18 | }
19 |
20 | [SetUp]
21 | public void SetUp()
22 | {
23 | _level1Client = Level1ClientFactory.CreateNew();
24 | _level1Client.Connect();
25 | }
26 |
27 | [TearDown]
28 | public void TearDown()
29 | {
30 | _level1Client.Disconnect();
31 | }
32 |
33 | [Test]
34 | public async Task Should_Return_FundamentalMessage()
35 | {
36 | // Act
37 | var fundamentalMessage = await _level1Client.GetFundamentalSnapshotAsync(Symbol);
38 |
39 | // Assert
40 | Assert.AreEqual(fundamentalMessage.Symbol, Symbol);
41 | }
42 |
43 | [Test]
44 | public async Task Should_Return_UpdateSummaryMessage()
45 | {
46 | // Act
47 | var updateSummaryMessage = await _level1Client.GetUpdateSummarySnapshotAsync(Symbol);
48 |
49 | // Assert
50 | Assert.AreEqual(updateSummaryMessage.Symbol, Symbol);
51 | }
52 |
53 | [Test]
54 | public void Should_Throw_Exceptions_When_SymbolNotFound_FundamentalSnapshot()
55 | {
56 | // Assert
57 | Assert.ThrowsAsync(async () => await _level1Client.GetFundamentalSnapshotAsync(NotFoundSymbol));
58 | }
59 |
60 | [Test]
61 | public void Should_Throw_Exceptions_When_SymbolNotFound_For_UpdateSummarySnapshot()
62 | {
63 | // Assert
64 | Assert.ThrowsAsync(async () => await _level1Client.GetUpdateSummarySnapshotAsync(NotFoundSymbol));
65 |
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Common/CultureNameTestCase.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using NUnit.Framework;
3 |
4 | namespace IQFeed.CSharpApiClient.Tests.Common
5 | {
6 | public class CultureNameTestCase
7 | {
8 | public static IEnumerable CultureNames
9 | {
10 | get
11 | {
12 | yield return new TestCaseData("en-US");
13 | yield return new TestCaseData("fr-FR");
14 | yield return new TestCaseData("ru-RU");
15 | yield return new TestCaseData("ja-JP");
16 | yield return new TestCaseData("ar-SA");
17 | }
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Common/ExceptionFactoryTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using IQFeed.CSharpApiClient.Common;
4 | using IQFeed.CSharpApiClient.Common.Exceptions;
5 | using IQFeed.CSharpApiClient.Lookup.Historical.Messages;
6 | using NUnit.Framework;
7 |
8 | namespace IQFeed.CSharpApiClient.Tests.Common
9 | {
10 | public class ExceptionFactoryTests
11 | {
12 | private readonly ExceptionFactory _exceptionFactory;
13 |
14 | public ExceptionFactoryTests()
15 | {
16 | _exceptionFactory = new ExceptionFactory();
17 | }
18 |
19 | [Test]
20 | public void Should_Return_InvalidData_Exception()
21 | {
22 | // Arrange
23 | var request = "request";
24 | var intervalMessage = new IntervalMessage(new DateTime(2000, 01, 01, 9, 30, 00), 1, 1, 1, 1, 1, 1, 0);
25 | var invalidMessages = new List>() { new InvalidMessage(intervalMessage, intervalMessage.ToCsv()) };
26 | var messages = new List() { intervalMessage };
27 |
28 | // Act
29 | var exception = _exceptionFactory.CreateNew(request, invalidMessages, messages);
30 |
31 | // Assert
32 | var expectedException = new InvalidDataIQFeedException(request, invalidMessages, messages);
33 | Assert.AreEqual(exception, expectedException);
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Common/TestHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Globalization;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading;
6 |
7 | namespace IQFeed.CSharpApiClient.Tests.Common
8 | {
9 | public static class TestHelper
10 | {
11 | public static void SetThreadCulture(string cultureName)
12 | {
13 | var culture = CultureInfo.GetCultureInfo(cultureName);
14 | Thread.CurrentThread.CurrentCulture = culture;
15 | Thread.CurrentThread.CurrentUICulture = culture;
16 | }
17 |
18 | public static byte[] GetMessageBytes(IEnumerable messages)
19 | {
20 | return Encoding.ASCII.GetBytes(messages.Aggregate((acc, msg) => acc += msg));
21 | }
22 |
23 | public static byte[] GetMessageBytes(string message)
24 | {
25 | return GetMessageBytes(new List() { message });
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Extensions/ByteExtensionsTests.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using IQFeed.CSharpApiClient.Extensions;
3 | using NUnit.Framework;
4 |
5 | namespace IQFeed.CSharpApiClient.Tests.Extensions
6 | {
7 | public class ByteExtensionsTests
8 | {
9 | private const string EndMessage = IQFeedDefault.ProtocolEndOfMessageCharacters;
10 |
11 | [Test]
12 | public void Should_Return_False_When_Count_Is_Smaller_Then_Pattern_Length()
13 | {
14 | // Arrange
15 | var buffer = new byte[10];
16 | var pattern = new byte[5];
17 |
18 | // Act
19 | var result = buffer.EndsWith(4, pattern);
20 |
21 | // Assert
22 | Assert.False(result);
23 | }
24 |
25 | [Test]
26 | public void Should_Return_False_When_Buffer_Size_Is_Smaller_Then_Pattern_Size()
27 | {
28 | // Arrange
29 | var buffer = new byte[5];
30 | var pattern = new byte[10];
31 |
32 | // Act
33 | var result = buffer.EndsWith(buffer.Length, pattern);
34 |
35 | // Assert
36 | Assert.False(result);
37 | }
38 |
39 | [Test]
40 | public void Should_Return_True_When_Buffer_Ends_With_Pattern()
41 | {
42 | // Arrange
43 | var buffer = Encoding.ASCII.GetBytes("0123456789" + EndMessage);
44 | var pattern = Encoding.ASCII.GetBytes(EndMessage);
45 |
46 | // Act
47 | var result = buffer.EndsWith(buffer.Length, pattern);
48 |
49 | // Assert
50 | Assert.True(result);
51 | }
52 |
53 | [Test]
54 | public void Should_Return_False_When_Buffer_Doesnt_Match_Pattern()
55 | {
56 | // Arrange
57 | var altMsgEnd = EndMessage.Replace("E", "X");
58 | var buffer = Encoding.ASCII.GetBytes("0123456789" + altMsgEnd);
59 | var pattern = Encoding.ASCII.GetBytes(EndMessage);
60 |
61 | // Act
62 | var result = buffer.EndsWith(buffer.Length, pattern);
63 |
64 | // Assert
65 | Assert.False(result);
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Extensions/StringExtensionsTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Extensions;
3 | using NUnit.Framework;
4 |
5 | namespace IQFeed.CSharpApiClient.Tests.Extensions
6 | {
7 | public class StringExtensionTests
8 | {
9 | [Test]
10 | public void SplitFeedMessage_ThrowsArgumentException_WhenNoProtocolDelimiterCharacterFoundInString()
11 | {
12 | // Arrange
13 | var nonDelimitedString = "nonDelimiters";
14 |
15 | // Assert
16 | Assert.Throws(() => nonDelimitedString.SplitFeedMessage(2));
17 | }
18 |
19 | [Test]
20 | public void SplitFeedMessage_ThrowsArgumentException_ExpectedPartsGreaterThanDelimitedStrings()
21 | {
22 | // Arrange
23 | var delimitedString = "not,enough";
24 |
25 | // Assert
26 | Assert.Throws(() => delimitedString.SplitFeedMessage(3));
27 | }
28 |
29 | [Test]
30 | public void SplitFeedMessage_ThrowsArgumentException_WithInvalidDelimiters()
31 | {
32 | // Arrange
33 | var delimitedString = "wrong.delimiter";
34 |
35 | // Assert
36 | Assert.Throws(() => delimitedString.SplitFeedMessage(2));
37 | }
38 |
39 | [Test]
40 | public void SplitFeedMessage_LastPartReturnsAllCharactersUpToTheLastDelimiter_IfSplitSizeLessThanSizeOfDelimitedMessage()
41 | {
42 | // Arrange
43 | var delimitedString = "one,two,my, company name,";
44 | var splitSize = 3;
45 |
46 | // Act
47 | var values = delimitedString.SplitFeedMessage(splitSize);
48 |
49 | // Assert
50 | var expectedValues = new[] { "one", "two", "my, company name" };
51 | Assert.AreEqual(values, expectedValues);
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/IQFeed.CSharpApiClient.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net472;net60
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Lookup/Chains/Futures/FutureMonthCodeTests.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Lookup.Chains.Futures;
2 | using NUnit.Framework;
3 |
4 | namespace IQFeed.CSharpApiClient.Tests.Lookup.Chains.Futures
5 | {
6 | public class FutureMonthCodeTests
7 | {
8 | [TestCase("F", 1)]
9 | [TestCase("G", 2)]
10 | [TestCase("H", 3)]
11 | [TestCase("J", 4)]
12 | [TestCase("K", 5)]
13 | [TestCase("M", 6)]
14 | [TestCase("N", 7)]
15 | [TestCase("Q", 8)]
16 | [TestCase("U", 9)]
17 | [TestCase("V", 10)]
18 | [TestCase("X", 11)]
19 | [TestCase("Z", 12)]
20 | public void Should_Return_Decoded_Month(string monthCode, int result)
21 | {
22 | // Act
23 | var month = FutureMonthCode.Decode(monthCode);
24 |
25 | // Assert
26 | Assert.AreEqual(month, result);
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Lookup/Chains/Messages/FutureMessageTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using IQFeed.CSharpApiClient.Lookup.Chains.Futures;
4 | using IQFeed.CSharpApiClient.Lookup.Chains.Messages;
5 | using IQFeed.CSharpApiClient.Tests.Common;
6 | using NUnit.Framework;
7 |
8 | namespace IQFeed.CSharpApiClient.Tests.Lookup.Chains.Messages
9 | {
10 | public class FutureMessageTests
11 | {
12 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
13 | public void Should_Parse_FutureMessage_Culture_Independent(string cultureName)
14 | {
15 | // Arrange
16 | TestHelper.SetThreadCulture(cultureName);
17 | var message = "LC,@ESU18,@ESZ18,@ESH19,@ESM19,@ESU19,";
18 | var messageWithRequestId = "TESTREQUEST,LC,@ESU18,@ESZ18,@ESH19,@ESM19,@ESU19,";
19 |
20 | // Act
21 | var futureMessageParsed = FutureMessage.Parse(message);
22 | var futureMessageWithRequestIdParsed = FutureMessage.ParseWithRequestId(messageWithRequestId);
23 | var futureMessage = new Future("@ESU18", "@ES", new DateTime(2018, 09, 01));
24 |
25 | // Assert
26 | Assert.AreEqual(futureMessageParsed.Chains.First(), futureMessage);
27 | Assert.AreEqual("TESTREQUEST", futureMessageWithRequestIdParsed.RequestId);
28 | Assert.AreEqual(futureMessageWithRequestIdParsed.Chains.First(), futureMessage);
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Lookup/Chains/Messages/FutureSpreadMessageTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using IQFeed.CSharpApiClient.Lookup.Chains;
4 | using IQFeed.CSharpApiClient.Lookup.Chains.Futures;
5 | using IQFeed.CSharpApiClient.Lookup.Chains.Messages;
6 | using IQFeed.CSharpApiClient.Tests.Common;
7 | using NUnit.Framework;
8 |
9 | namespace IQFeed.CSharpApiClient.Tests.Lookup.Chains.Messages
10 | {
11 | public class FutureSpreadMessageTests
12 | {
13 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
14 | public void Should_Parse_FutureSpreadMessage_Culture_Independent(string cultureName)
15 | {
16 | // Arrange
17 | TestHelper.SetThreadCulture(cultureName);
18 | var message = "LC,@ESU18-@ESH19,@ESU18-@ESM19,@ESU18-@ESU19,@ESU18-@ESZ18,@ESZ18-@ESH19,@ESZ18-@ESM19,@ESZ18-@ESU19,@ESH19-@ESM19,@ESH19-@ESU19,@ESM19-@ESU19,";
19 | var messageWithRequestId = "TESTREQUEST,LC,@ESU18-@ESH19,@ESU18-@ESM19,@ESU18-@ESU19,@ESU18-@ESZ18,@ESZ18-@ESH19,@ESZ18-@ESM19,@ESZ18-@ESU19,@ESH19-@ESM19,@ESH19-@ESU19,@ESM19-@ESU19,";
20 |
21 | // Act
22 | var futureSpreadMessageParsed = FutureSpreadMessage.Parse(message);
23 | var futureSpreadMessageWithRequestIdParsed = FutureSpreadMessage.ParseWithRequestId(messageWithRequestId);
24 | var futureSpread = new FutureSpread("@ESU18-@ESH19", new Future("@ESU18", "@ES", new DateTime(2018, 09, 01)), new Future("@ESH19", "@ES", new DateTime(2019, 03, 01)));
25 |
26 | // Assert
27 | Assert.AreEqual(futureSpreadMessageParsed.Chains.First(), futureSpread);
28 | Assert.AreEqual("TESTREQUEST", futureSpreadMessageWithRequestIdParsed.RequestId);
29 | Assert.AreEqual(futureSpreadMessageWithRequestIdParsed.Chains.First(), futureSpread);
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Lookup/Common/BaseLookupMessageHandlerTestClass.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Common;
3 | using IQFeed.CSharpApiClient.Lookup.Common;
4 |
5 | namespace IQFeed.CSharpApiClient.Tests.Lookup.Common
6 | {
7 | ///
8 | /// Test class to access protected static method from BaseLookupMessageHandler
9 | ///
10 | internal class BaseLookupMessageHandlerTestClass : BaseLookupMessageHandler
11 | {
12 | public new MessageContainer ProcessMessages(Func parserFunc, Func errorFunc, byte[] message, int count)
13 | {
14 | return base.ProcessMessages(parserFunc, errorFunc, message, count);
15 | }
16 |
17 | public new MessageContainer ProcessMessages(TryParseDelegate tryParseDelegate, Func errorFunc, byte[] message, int count)
18 | {
19 | return base.ProcessMessages(tryParseDelegate, errorFunc, message, count);
20 | }
21 |
22 | public new string ParseErrorMessage(string[] messages)
23 | {
24 | return base.ParseErrorMessage(messages);
25 | }
26 |
27 | public new string ParseErrorMessageWithRequestId(string[] messages)
28 | {
29 | return base.ParseErrorMessageWithRequestId(messages);
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Lookup/MarketSummary/MarketSummaryMessageTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Lookup.MarketSummary;
3 | using IQFeed.CSharpApiClient.Lookup.MarketSummary.Messages;
4 | using NUnit.Framework;
5 |
6 | namespace IQFeed.CSharpApiClient.Tests.Lookup.MarketSummary
7 | {
8 | public class MarketSummaryMessageTests
9 | {
10 | [Test]
11 | public void Should_Parse_MarketSummaryMessage()
12 | {
13 | // Arrange
14 | var requestId = "TEST";
15 | var symbol = "MSFT";
16 | var last = 1.234D;
17 | var tradeDate = new DateTime(2021, 03, 24);
18 | var tradeTime = new TimeSpan(11, 42, 12);
19 | var message1 = "RequestId,Symbol,Last,TradeDate,TradeTime";
20 | var message2 = "TEST,MSFT,1.234,20210324,114212";
21 | var values = new string[] {"TEST", "MSFT", "1.234", "20210324", "114212"};
22 |
23 | var marketSummaryHandler = new MarketSummaryHandler();
24 |
25 | // Act
26 | var marketSummaryMessage1Parsed = MarketSummaryMessage.Parse(message1, marketSummaryHandler);
27 | var marketSummaryMessage2Parsed = MarketSummaryMessage.Parse(message2, marketSummaryHandler);
28 | var marketSummaryMessage1 = new MarketSummaryMessage(symbol, 0, 0, last, null, null, tradeDate,
29 | tradeTime, null, null, null, null, null, null, null, null, null, null, null,
30 | null, null, null, null, null, null, null, null, null,
31 | null, null, null, null, null, null, null, requestId);
32 | var marketSummaryMessage2 = new MarketSummaryMessage(values, marketSummaryHandler);
33 |
34 | // Assert
35 | // MarketSummaryMessage1Parsed should be null, as it was the Fieldname pass
36 | Assert.IsNull(marketSummaryMessage1Parsed);
37 | Assert.IsNotNull(marketSummaryMessage2Parsed);
38 | Assert.AreEqual(marketSummaryMessage2Parsed, marketSummaryMessage1);
39 | Assert.AreEqual(marketSummaryMessage2Parsed, marketSummaryMessage2);
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Lookup/Symbol/Common/LocalCacheStrategyTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using IQFeed.CSharpApiClient.Lookup.Symbol.Downloader;
4 | using NUnit.Framework;
5 |
6 | namespace IQFeed.CSharpApiClient.Tests.Lookup.Symbol.Common
7 | {
8 | public class LocalCacheStrategyTests
9 | {
10 | private LocalCacheStrategy _localCacheStrategy;
11 |
12 | [SetUp]
13 | public void SetUp()
14 | {
15 | _localCacheStrategy = new LocalCacheStrategy();
16 | }
17 |
18 | [Test]
19 | public void Should_Expire_When_File_Does_Not_Exist()
20 | {
21 | // Act
22 | var expired = _localCacheStrategy.HasExpired("invalid_path.txt", TimeSpan.MaxValue);
23 |
24 | // Assert
25 | Assert.True(expired);
26 | }
27 |
28 | [Test]
29 | public void Should_Not_Expire_When_File_Recently_Written()
30 | {
31 | // Arrange
32 | var file = Path.GetTempFileName();
33 | File.AppendAllText(file, "content");
34 |
35 | // Act
36 | var expired = _localCacheStrategy.HasExpired(file, TimeSpan.FromMinutes(1));
37 |
38 | // Assert
39 | Assert.False(expired);
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Common/Messages/ErrorMessageTests.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Streaming.Common.Messages;
2 | using IQFeed.CSharpApiClient.Tests.Common;
3 | using NUnit.Framework;
4 |
5 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Common.Messages
6 | {
7 | public class ErrorMessageTests
8 | {
9 |
10 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
11 | public void Should_Parse_ErrorMessage_Culture_Indepedant(string cultureName)
12 | {
13 | // Arrange
14 | TestHelper.SetThreadCulture(cultureName);
15 | var message = "E,Disconnected from server";
16 |
17 | // Act
18 | var errorMessageParsed = ErrorMessage.Parse(message);
19 | var errorMessage = new ErrorMessage("Disconnected from server");
20 |
21 | // Assert
22 | Assert.AreEqual(errorMessageParsed, errorMessage);
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Common/Messages/SymbolNotFoundMessageTests.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Streaming.Common.Messages;
2 | using IQFeed.CSharpApiClient.Tests.Common;
3 | using NUnit.Framework;
4 |
5 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Common.Messages
6 | {
7 | public class SymbolNotFoundMessageTests
8 | {
9 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
10 | public void Should_Parse_SymbolNotFoundMessage_Culture_Independent(string cultureName)
11 | {
12 | // Arrange
13 | TestHelper.SetThreadCulture(cultureName);
14 | var message = "n,AAPL";
15 |
16 | // Act
17 | var symbolNotFoundMessageParsed = SymbolNotFoundMessage.Parse(message);
18 | var symbolNotFoundMessage = new SymbolNotFoundMessage("AAPL");
19 |
20 | // Assert
21 | Assert.AreEqual(symbolNotFoundMessageParsed, symbolNotFoundMessage);
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Common/Messages/SystemMessageTests.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Streaming.Common.Messages;
2 | using IQFeed.CSharpApiClient.Tests.Common;
3 | using NUnit.Framework;
4 |
5 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Common.Messages
6 | {
7 | public class SystemMessageTests
8 | {
9 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
10 | public void Should_Parse_SystemMessage_Culture_Invariant(string cultureName)
11 | {
12 | // Arrange
13 | TestHelper.SetThreadCulture(cultureName);
14 | var message = "S,STATS,,,0,0,1,0,0,0,,,Not Connected,6.0.0.4,474614,0,0,,0.02,0.02,,";
15 |
16 | // Act
17 | var systemMessageParsed = SystemMessage.Parse(message);
18 | var systemMessage = new SystemMessage("STATS", message);
19 |
20 | // Assert
21 | Assert.AreEqual(systemMessageParsed, systemMessage);
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Common/Messages/TimestampMessageTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Common.Messages;
3 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
4 | using IQFeed.CSharpApiClient.Tests.Common;
5 | using NUnit.Framework;
6 |
7 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Common.Messages
8 | {
9 | public class TimestampMessageTests
10 | {
11 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
12 | public void Should_Parse_TimestampMessage_Culture_Independent(string cultureName)
13 | {
14 | // Arrange
15 | TestHelper.SetThreadCulture(cultureName);
16 | var message = "T,20180709 14:18:31";
17 |
18 | // Act
19 | var timestampMessageParsed = TimestampMessage.Parse(message);
20 | var timestampMessage = new TimestampMessage(new DateTime(2018, 07, 09, 14, 18, 31));
21 |
22 | // Assert
23 | Assert.AreEqual(timestampMessageParsed, timestampMessage);
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Derivative/DerivativeRequestFormatterTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Derivative;
3 | using NUnit.Framework;
4 |
5 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Derivative
6 | {
7 | public class DerivativeRequestFormatterTests
8 | {
9 | private DerivativeRequestFormatter _derivativeRequestFormatter;
10 |
11 | [SetUp]
12 | public void SetUp()
13 | {
14 | _derivativeRequestFormatter = new DerivativeRequestFormatter();
15 | }
16 |
17 | [Test]
18 | public void Should_Format_BarWatch()
19 | {
20 | var request = _derivativeRequestFormatter.ReqBarWatch("aapl", 60, new DateTime(2018, 01, 01, 09, 30, 00), 10, 1000, new TimeSpan(9, 30, 00), new TimeSpan(16, 00, 00), "TEST", DerivativeIntervalType.S, 5);
21 | Assert.AreEqual(request, "BW,AAPL,60,20180101 093000,10,1000,093000,160000,TEST,s,,5\r\n");
22 | }
23 |
24 | [Test]
25 | public void Should_Format_BarUnwatch()
26 | {
27 | var request = _derivativeRequestFormatter.ReqBarUnwatch("aapl", "TEST");
28 | Assert.AreEqual(request, "BR,AAPL,TEST,\r\n");
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Derivative/Messages/IntervalBarMessageTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Derivative.Messages;
3 | using IQFeed.CSharpApiClient.Tests.Common;
4 | using NUnit.Framework;
5 |
6 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Derivative.Messages
7 | {
8 | public class IntervalBarMessageTest
9 | {
10 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
11 | public void Should_Parse(string cultureName)
12 | {
13 | // Arrange
14 | TestHelper.SetThreadCulture(cultureName);
15 | var message = "BC,AAPL,2018-01-01 09:30:00,100.01,101.23,99.98,100.93,143562,745,0";
16 |
17 | // Act
18 | var intervalBarMessage = new IntervalBarMessage(IntervalBarType.C, "AAPL", new DateTime(2018, 1, 1, 9, 30, 0), 100.01, 101.23, 99.98, 100.93, 143562, 745, 0);
19 | var intervalBarMessageParsed = IntervalBarMessage.Parse(message);
20 |
21 | // Assert
22 | Assert.AreEqual(intervalBarMessage, intervalBarMessageParsed);
23 | }
24 |
25 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
26 | public void Should_Parse_Without_RequestId(string cultureName)
27 | {
28 | // Arrange
29 | TestHelper.SetThreadCulture(cultureName);
30 | var message = "TESTREQUEST,BC,AAPL,2018-01-01 09:30:00,100.01,101.23,99.98,100.93,143562,745,0";
31 |
32 | // Act
33 | var intervalBarMessage = new IntervalBarMessage(IntervalBarType.C, "AAPL", new DateTime(2018, 1, 1, 9, 30, 0), 100.01, 101.23, 99.98, 100.93, 143562, 745, 0, "TESTREQUEST");
34 | var intervalBarMessageParsed = IntervalBarMessage.ParseWithRequestId(message);
35 |
36 | // Assert
37 | Assert.AreEqual(intervalBarMessage, intervalBarMessageParsed);
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Level1/Handlers/Level1MessageHandlerPerformanceTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Linq;
4 | using System.Text;
5 | using IQFeed.CSharpApiClient.Streaming.Level1.Handlers;
6 | using NUnit.Framework;
7 |
8 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Level1.Handlers
9 | {
10 | [Category("Performance")]
11 | [Explicit]
12 | public class Level1MessageHandlerPerformanceTests
13 | {
14 | [Test]
15 | public void Should_Process_Update_Message()
16 | {
17 | var level1MessageHandler = new Level1MessageHandler();
18 |
19 | // Arrange
20 | var msg = "Q,AAPL,322.7500,40,16:53:23.256494,11,37629453,322.6800,100,322.8700,100,312.6000,318.4000,312.1900,308.9500,ba,873D17,2,17\r\n";
21 | var msgBytes = Encoding.ASCII.GetBytes(msg);
22 | var count = msgBytes.Length;
23 |
24 | level1MessageHandler.Update += message => { };
25 |
26 | const int ExecutionsCount = 5;
27 | var results = new double[ExecutionsCount];
28 |
29 | for (int i = 0; i < ExecutionsCount; i++)
30 | {
31 | var sw = Stopwatch.StartNew();
32 | for (var j = 0; j < 1000000; j++)
33 | {
34 | level1MessageHandler.ProcessMessages(msgBytes, count);
35 | }
36 | sw.Stop();
37 |
38 | results[i] = sw.Elapsed.TotalMilliseconds;
39 | Console.WriteLine(sw.Elapsed.TotalMilliseconds);
40 | }
41 |
42 | Console.WriteLine($"Min: {results.Min()}");
43 | Console.WriteLine($"Avg: {results.Average()}");
44 | Console.WriteLine($"Max: {results.Max()}");
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Level1/Level1DynamicFieldsPerformanceTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using IQFeed.CSharpApiClient.Streaming.Level1;
4 | using NUnit.Framework;
5 |
6 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Level1
7 | {
8 | [Explicit]
9 | [Category("Performance")]
10 | public class Level1DynamicFieldsPerformanceTests
11 | {
12 | [Test]
13 | public void Should_Convert_SevenDayYield()
14 | {
15 | // Arrange
16 | var message = "AAPL,";
17 | var fields = new[] { DynamicFieldset.Symbol };
18 |
19 | // Act
20 | for (int i = 0; i < 5; i++)
21 | {
22 | var sw = Stopwatch.StartNew();
23 |
24 | for (int j = 0; j < 1000000; j++)
25 | {
26 | var dynamicFields = Level1DynamicFields.Parse(message, fields);
27 | }
28 |
29 | sw.Stop();
30 | Console.WriteLine(sw.Elapsed.TotalMilliseconds);
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Level1/Messages/NewsMessageTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
3 | using IQFeed.CSharpApiClient.Tests.Common;
4 | using NUnit.Framework;
5 |
6 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Level1.Messages
7 | {
8 | public class NewsMessageTests
9 | {
10 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
11 | public void Should_Parse_NewsMessage_Culture_Independent(string cultureName)
12 | {
13 | // Arrange
14 | TestHelper.SetThreadCulture(cultureName);
15 | var message = "N,1234,1122,AAPL:NFLX,20000102 152001,Very cool news,";
16 |
17 | // Act
18 | var newsMessageParsed = NewsMessage.Parse(message);
19 | var newsMessage = new NewsMessage("1234", "1122", "AAPL:NFLX",new DateTime(2000,01,02, 15,20,01),"Very cool news");
20 |
21 | // Arrange
22 | Assert.AreEqual(newsMessageParsed, newsMessage);
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Level1/Messages/RegionalUpdateMessageTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
3 | using IQFeed.CSharpApiClient.Tests.Common;
4 | using NUnit.Framework;
5 |
6 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Level1.Messages
7 | {
8 | public class RegionalUpdateMessageTests
9 | {
10 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
11 | public void Should_Parse_RegionalUpdateMessage_Culture_Independent(string cultureName)
12 | {
13 | // Arrange
14 | TestHelper.SetThreadCulture(cultureName);
15 | var message = "R,AAPL,X,1.23,100,13:00:00,1.24,200,13:00:01,0,1,2,";
16 |
17 | // Act
18 | var regionalUpdateMessageParsed = RegionalUpdateMessage.Parse(message);
19 | var regionalUpdateMessage = new RegionalUpdateMessage("AAPL", "X", 1.23, 100, new DateTime(2000, 1, 2, 13, 00, 00), 1.24, 200, new DateTime(2000, 1, 2, 13, 00, 01), 0, 1, 2);
20 |
21 | // Arrange
22 | Assert.AreEqual(regionalUpdateMessageParsed, regionalUpdateMessage);
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Level1/Messages/TradeCorrectionMessageTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
4 | using IQFeed.CSharpApiClient.Tests.Common;
5 | using NUnit.Framework;
6 |
7 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Level1.Messages
8 | {
9 | public class TradeCorrectionMessageTests
10 | {
11 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
12 | public void Should_Parse_TradeCorrectionMessage_Culture_Independent(string cultureName)
13 | {
14 | // Arrange
15 | TestHelper.SetThreadCulture(cultureName);
16 | var message = "C,AAPL,I,03/30/2021,19:59:14.503633,183.3600,13,101123,8801,17";
17 |
18 | // Act
19 | var tradeCorrectionMessageParsed = TradeCorrectionMessage.Parse(message);
20 | DateTime.TryParseExact("03/30/2021", TradeCorrectionMessage.TradeCorrectionMessageDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out var tradeDate);
21 | TimeSpan.TryParseExact("19:59:14.503633", TradeCorrectionMessage.TradeCorrectionMessageTimeFormat, CultureInfo.InvariantCulture, out var tradeTime);
22 | var tradeCorrectionMessage = new TradeCorrectionMessage("AAPL", "I", tradeDate, tradeTime, 183.3600, 13, 101123, "8801", 17);
23 |
24 | // Assert
25 | Assert.AreEqual(tradeCorrectionMessageParsed, tradeCorrectionMessage);
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Level1/Messages/UpdateSummaryMessagePerformanceTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
5 | using NUnit.Framework;
6 |
7 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Level1.Messages
8 | {
9 | [Category("Performance")]
10 | [Explicit]
11 | public class UpdateSummaryMessagePerformanceTests
12 | {
13 | public const string Message = "Q,AAPL,322.9100,13,16:53:16.164236,11,37620407,322.8700,100,323.0000,3300,312.6000,318.4000,312.1900,308.9500,O,8717,2,17";
14 |
15 | [Test]
16 | public void Should_Parse_Double()
17 | {
18 | var messages = new List();
19 |
20 | var sw = Stopwatch.StartNew();
21 |
22 | for (var i = 0; i < 1000000; i++)
23 | {
24 | var parsed = UpdateSummaryMessage.Parse(Message);
25 | messages.Add(parsed);
26 | }
27 |
28 | sw.Stop();
29 |
30 | Console.WriteLine(sw.Elapsed.Ticks);
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Level1/Messages/UpdateSummaryMessageTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
4 | using IQFeed.CSharpApiClient.Tests.Common;
5 | using NUnit.Framework;
6 |
7 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Level1.Messages
8 | {
9 | public class UpdateSummaryMessageTests
10 | {
11 | [Test, TestCaseSource(typeof(CultureNameTestCase), nameof(CultureNameTestCase.CultureNames))]
12 | public void Should_Parse_UpdateSummaryMessage_Culture_Independent(string cultureName)
13 | {
14 | // Arrange
15 | TestHelper.SetThreadCulture(cultureName);
16 | var message = "P,AAPL,188.3500,52500,19:59:14.503633,19,0,188.2500,100,188.3600,100,,,,187.9700,Cbacv,8801,2,17";
17 |
18 | // Act
19 | var updateSummaryMessageParsed = UpdateSummaryMessage.Parse(message);
20 | DateTime.TryParseExact("19:59:14.503633", UpdateSummaryMessage.UpdateMessageTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out var timestamp);
21 | var updateSummaryMessage = new UpdateSummaryMessage("AAPL", 188.35, 52500, timestamp, 19, 0, 188.25, 100, 188.36, 100, 0, 0, 0, 187.97, "Cbacv", "8801");
22 |
23 | // Assert
24 | Assert.AreEqual(updateSummaryMessageParsed, updateSummaryMessage);
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient.Tests/Streaming/Level2/Level2RequestFormatterTests.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Streaming.Level2;
2 | using NUnit.Framework;
3 |
4 | namespace IQFeed.CSharpApiClient.Tests.Streaming.Level2
5 | {
6 | public class Level2RequestFormatterTests
7 | {
8 | private Level2RequestFormatter _level2RequestFormatter;
9 | [SetUp]
10 | public void SetUp()
11 | {
12 | _level2RequestFormatter = new Level2RequestFormatter();
13 | }
14 |
15 | [Test]
16 | public void Should_Format_ReqWatch()
17 | {
18 | var request = _level2RequestFormatter.ReqWatch("aapl");
19 | Assert.AreEqual(request, "wAAPL\r\n");
20 | }
21 |
22 | [Test]
23 | public void Should_Format_ReqMarketMakerNameById()
24 | {
25 | var request = _level2RequestFormatter.ReqMarketMakerNameById("md02");
26 | Assert.AreEqual(request, "mMD02\r\n");
27 | }
28 |
29 | [Test]
30 | public void Should_Format_ReqUnwatch()
31 | {
32 | var request = _level2RequestFormatter.ReqUnwatch("aapl");
33 | Assert.AreEqual(request, "rAAPL\r\n");
34 | }
35 |
36 | [Test]
37 | public void Should_Format_ReqServerConnect()
38 | {
39 | var request = _level2RequestFormatter.ReqServerConnect();
40 | Assert.AreEqual(request, "c\r\n");
41 | }
42 |
43 | [Test]
44 | public void Should_Format_ReqServerDisconnect()
45 | {
46 | var request = _level2RequestFormatter.ReqServerDisconnect();
47 | Assert.AreEqual(request, "x\r\n");
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/ExceptionFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using IQFeed.CSharpApiClient.Common.Exceptions;
3 |
4 | namespace IQFeed.CSharpApiClient.Common
5 | {
6 | public class ExceptionFactory
7 | {
8 | private const string DefaultMessage = "IQFeed exception received.";
9 |
10 | public IQFeedException CreateNew(string request, string errorMessage, string messageTrace)
11 | {
12 | switch (errorMessage)
13 | {
14 | case IQFeedDefault.ProtocolNoDataCharacters:
15 | return new NoDataIQFeedException(request, errorMessage, messageTrace);
16 | default:
17 | return new IQFeedException(request, DefaultMessage, errorMessage, messageTrace);
18 | }
19 | }
20 |
21 | public InvalidDataIQFeedException CreateNew(string request, IEnumerable> invalidMessages, IEnumerable messages)
22 | {
23 | return new InvalidDataIQFeedException(request, invalidMessages, messages);
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/Exceptions/IQFeedException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Common.Exceptions
4 | {
5 | // ReSharper disable once InconsistentNaming
6 | public class IQFeedException : Exception
7 | {
8 | ///
9 | /// Request sent to IQFeed
10 | ///
11 | public string Request { get; }
12 |
13 | ///
14 | /// Parsed exception contained in the message
15 | ///
16 | public string ErrorMessage { get; }
17 |
18 | ///
19 | /// Last messages received by IQFeed before throwing the exception
20 | ///
21 | public string MessageTrace { get; }
22 |
23 | public IQFeedException(string request, string message, string errorMessage, string messageTrace) : base(message)
24 | {
25 | Request = request;
26 | ErrorMessage = errorMessage;
27 | MessageTrace = messageTrace;
28 | }
29 |
30 | public override string ToString()
31 | {
32 | return $"{base.ToString()}, {nameof(Request)}: {Request}, {nameof(ErrorMessage)}: {ErrorMessage}, {nameof(MessageTrace)}: {MessageTrace}";
33 | }
34 |
35 | protected bool Equals(IQFeedException other)
36 | {
37 | return Request == other.Request && ErrorMessage == other.ErrorMessage && MessageTrace == other.MessageTrace;
38 | }
39 |
40 | public override bool Equals(object obj)
41 | {
42 | if (ReferenceEquals(null, obj)) return false;
43 | if (ReferenceEquals(this, obj)) return true;
44 | if (obj.GetType() != this.GetType()) return false;
45 | return Equals((IQFeedException)obj);
46 | }
47 |
48 | public override int GetHashCode()
49 | {
50 | unchecked
51 | {
52 | var hashCode = (Request != null ? Request.GetHashCode() : 0);
53 | hashCode = (hashCode * 397) ^ (ErrorMessage != null ? ErrorMessage.GetHashCode() : 0);
54 | hashCode = (hashCode * 397) ^ (MessageTrace != null ? MessageTrace.GetHashCode() : 0);
55 | return hashCode;
56 | }
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/Exceptions/InvalidDataIQFeedException.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace IQFeed.CSharpApiClient.Common.Exceptions
4 | {
5 | // ReSharper disable once InconsistentNaming
6 | public class InvalidDataIQFeedException : IQFeedException
7 | {
8 | public IEnumerable> InvalidMessages { get; }
9 | public IEnumerable Messages { get; }
10 |
11 | public InvalidDataIQFeedException(string request, IEnumerable> invalidMessages, IEnumerable messages) :
12 | base(request, "Unable to parse received data.", "Invalid data", $"Please check ${nameof(InvalidMessages)} property.")
13 | {
14 | InvalidMessages = invalidMessages;
15 | Messages = messages;
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/Exceptions/NoDataIQFeedException.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Common.Exceptions
2 | {
3 | // ReSharper disable once InconsistentNaming
4 | public class NoDataIQFeedException : IQFeedException
5 | {
6 | private const string NoDataMessage = "IQFeed doesn't have any data for the request sent.";
7 |
8 | public NoDataIQFeedException(string request, string errorMessage, string messageTrace) : base(request, NoDataMessage, errorMessage, messageTrace) { }
9 | }
10 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/Exceptions/SymbolNotFoundIQFeedException.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Common.Exceptions
2 | {
3 | // ReSharper disable once InconsistentNaming
4 | public class SymbolNotFoundIQFeedException : IQFeedException
5 | {
6 | public SymbolNotFoundIQFeedException(string request, string symbol) : base(request, $"The specified Symbol '{symbol}' wasn't found on IQFeed.", string.Empty, string.Empty) { }
7 | }
8 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/FieldParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 |
4 | namespace IQFeed.CSharpApiClient.Common
5 | {
6 | ///
7 | /// Helper class used for parsing IQ Feed fields
8 | ///
9 | public static class FieldParser
10 | {
11 | public static double ParseDouble(string value)
12 | {
13 | double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var parsedValue);
14 | return parsedValue;
15 | }
16 |
17 | public static int ParseInt(string value)
18 | {
19 | int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var parsedValue);
20 | return parsedValue;
21 | }
22 |
23 | public static TimeSpan ParseTime(string value, string format)
24 | {
25 | DateTime.TryParseExact(value, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsedValue);
26 | return parsedValue.TimeOfDay;
27 | }
28 |
29 | public static DateTime ParseDate(string value, string format)
30 | {
31 | DateTime.TryParseExact(value, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsedValue);
32 | return parsedValue;
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/Interfaces/IClient.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Common.Interfaces
2 | {
3 | public interface IClient
4 | {
5 | void Connect();
6 | void Disconnect();
7 | }
8 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/Interfaces/IRequestFormatter.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Common.Interfaces
2 | {
3 | public interface IRequestFormatter
4 | {
5 | string SetClientName(string name);
6 | string SetProtocol(string version);
7 | }
8 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/InvalidMessage.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Common
2 | {
3 | public class InvalidMessage
4 | {
5 | public T Message { get; }
6 | public string Data { get; }
7 |
8 | public InvalidMessage(T message, string data)
9 | {
10 | Message = message;
11 | Data = data;
12 | }
13 |
14 | public override string ToString()
15 | {
16 | return $"{nameof(Message)}: {Message}, {nameof(Data)}: {Data}";
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/LoggingLevel.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Common
2 | {
3 | public enum LoggingLevel
4 | {
5 | Off = 0,
6 | Admin = 2,
7 | L1Data = 4,
8 | L1Request = 8,
9 | L1System = 16,
10 | L1Error = 32,
11 | L2Data = 64,
12 | L2Request = 128,
13 | L2System = 256,
14 | L2Error = 512,
15 | LookupData = 1024,
16 | LookupRequest = 2048,
17 | LookupError = 4096,
18 | Information = 8192,
19 | Debug = 16384,
20 | Connectivity = 32768
21 | }
22 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/MessageContainer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace IQFeed.CSharpApiClient.Common
4 | {
5 | public class MessageContainer
6 | {
7 | public IEnumerable Messages { get; }
8 | public IEnumerable> InvalidMessages { get; }
9 | public bool End { get; }
10 | public string ErrorMessage { get; }
11 | public string MessageTrace { get; }
12 |
13 | public MessageContainer(IEnumerable messages, bool end)
14 | {
15 | Messages = messages;
16 | InvalidMessages = new List>();
17 | End = end;
18 | }
19 |
20 | public MessageContainer(IEnumerable messages, IEnumerable> invalidMessages, bool end)
21 | {
22 | Messages = messages;
23 | InvalidMessages = invalidMessages;
24 | End = end;
25 | }
26 |
27 | public MessageContainer(string errorMessage, string messageTrace)
28 | {
29 | Messages = new List();
30 | InvalidMessages = new List>();
31 | End = true;
32 | ErrorMessage = errorMessage;
33 | MessageTrace = messageTrace;
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/Messages/ProtocolMessage.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Common.Messages
2 | {
3 | public class ProtocolMessage
4 | {
5 | public string Version { get; private set; }
6 |
7 | public ProtocolMessage(string version)
8 | {
9 | Version = version;
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Common/RequestFormatter.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Common.Interfaces;
2 |
3 | namespace IQFeed.CSharpApiClient.Common
4 | {
5 | public class RequestFormatter : IRequestFormatter
6 | {
7 | public string SetClientName(string name)
8 | {
9 | return $"S,SET CLIENT NAME,{name}{IQFeedDefault.ProtocolTerminatingCharacters}";
10 | }
11 |
12 | public string SetProtocol(string version)
13 | {
14 | return $"S,SET PROTOCOL,{version}{IQFeedDefault.ProtocolTerminatingCharacters}";
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Extensions/ByteExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Extensions
2 | {
3 | public static class ByteExtensions
4 | {
5 | public static int GetLastDelimeterIndex(this byte[] buffer, int offset, int length, char delimeter)
6 | {
7 | for (var i = offset + length - 1; i >= offset; i--)
8 | {
9 | if (buffer[i] == delimeter)
10 | return i;
11 | }
12 | return -1;
13 | }
14 |
15 | public static bool EndsWith(this byte[] self, int count, byte[] pattern)
16 | {
17 | var bufferIdx = count - 1;
18 |
19 | if (self.Length < pattern.Length)
20 | return false;
21 |
22 | if (count < pattern.Length)
23 | return false;
24 |
25 | for (var patternIndex = pattern.Length - 1; patternIndex >= 0; patternIndex--)
26 | {
27 | if (pattern[patternIndex] != self[bufferIdx])
28 | return false;
29 |
30 | bufferIdx--;
31 | }
32 |
33 | return true;
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Extensions/EnumExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace IQFeed.CSharpApiClient.Extensions
5 | {
6 | public static class EnumExtensions
7 | {
8 | public static TAttribute GetAttribute(this Enum value)
9 | where TAttribute : Attribute
10 | {
11 | var type = value.GetType();
12 | var name = Enum.GetName(type, value);
13 | return type.GetField(name)
14 | .GetCustomAttributes(false)
15 | .OfType()
16 | .SingleOrDefault();
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Extensions/EventExtentions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Extensions
4 | {
5 | public static class EventExtensions
6 | {
7 | public static void RaiseEvent(this EventHandler @event, object sender, EventArgs e)
8 | {
9 | if (@event != null)
10 | @event(sender, e);
11 | }
12 |
13 | public static void RaiseEvent(this EventHandler @event, object sender, T e)
14 | where T : EventArgs
15 | {
16 | if (@event != null)
17 | @event(sender, e);
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Extensions/NullableExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 |
4 | namespace IQFeed.CSharpApiClient.Extensions
5 | {
6 | public static class NullableExtensions
7 | {
8 | public static string ToInvariantString(this DateTime? date, string format)
9 | {
10 | return date.HasValue ? date.Value.ToString(format, CultureInfo.InvariantCulture) : string.Empty;
11 | }
12 |
13 | public static string ToInvariantString(this TimeSpan? time, string format)
14 | {
15 | return time.HasValue ? time.Value.ToString(format, CultureInfo.InvariantCulture) : string.Empty;
16 | }
17 |
18 | public static string ToInvariantString(this double? value)
19 | {
20 | return value.HasValue ? value.Value.ToString(CultureInfo.InvariantCulture) : string.Empty;
21 | }
22 |
23 | public static string ToInvariantString(this int? value)
24 | {
25 | return value.HasValue ? value.Value.ToString(CultureInfo.InvariantCulture) : string.Empty;
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Extensions/TaskExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace IQFeed.CSharpApiClient.Extensions
4 | {
5 | public static class TaskExtensions
6 | {
7 | ///
8 | /// Safely blocks until the specified task has completed executing
9 | ///
10 | /// The task's result type
11 | /// The task to be awaited
12 | /// The result of the task
13 | public static TResult SynchronouslyAwaitTaskResult(this Task task)
14 | {
15 | return task.ConfigureAwait(false).GetAwaiter().GetResult();
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/IQFeed.CSharpApiClient.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net472;netstandard2.1
4 |
5 |
6 | Full
7 |
8 | true
9 | Mathieu Paquette
10 |
11 | DTN IQFeed Socket API (Client)
12 | https://github.com/mathpaquette/IQFeed.CSharpApiClient
13 | https://github.com/mathpaquette/IQFeed.CSharpApiClient
14 | LICENSE
15 | Copyright © 2023 Mathieu Paquette
16 | IQFeed.CSharpApiClient is fastest and the most well-designed C# DTN IQFeed socket API connector available to the open source community!
17 | 1.0.0.0
18 | 1.0.0.0
19 | 1.0.0
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/IQFeedDefault.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient
2 | {
3 | // ReSharper disable once InconsistentNaming
4 | public class IQFeedDefault
5 | {
6 | public const string Hostname = "localhost";
7 |
8 | public const string ProtocolVersion = "6.2";
9 |
10 | public const string ProtocolTerminatingCharacters = "\r\n";
11 | public const string ProtocolEndOfMessageCharacters = "!ENDMSG!";
12 | public const string ProtocolNoDataCharacters = "!NO_DATA!";
13 | public const string ProtocolSyntaxErrorCharacters = "!SYNTAX_ERROR!";
14 |
15 | public const char ProtocolLineFeedCharacter ='\n';
16 | public const char ProtocolDelimiterCharacter = ',';
17 |
18 | public const char PrototolErrorCharacter = 'E';
19 |
20 | public const int Level1Port = 5009;
21 | public const int LookupPort = 9100;
22 | public const int Level2Port = 9200;
23 | public const int AdminPort = 9300;
24 | public const int DerivativePort = 9400;
25 | public const int LoginPort = 60020;
26 | }
27 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/ChainsMessageHandler.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Common;
2 | using IQFeed.CSharpApiClient.Lookup.Chains.Messages;
3 | using IQFeed.CSharpApiClient.Lookup.Common;
4 |
5 | namespace IQFeed.CSharpApiClient.Lookup.Chains
6 | {
7 | public class ChainsMessageHandler : BaseLookupMessageHandler
8 | {
9 | public MessageContainer GetFutureMessages(byte[] message, int count)
10 | {
11 | return ProcessMessages(FutureMessage.Parse, ParseErrorMessage, message, count);
12 | }
13 |
14 | public MessageContainer GetFutureMessagesWithRequestId(byte[] message, int count)
15 | {
16 | return ProcessMessages(FutureMessage.ParseWithRequestId, ParseErrorMessage, message, count);
17 | }
18 |
19 | public MessageContainer GetFutureSpreadMessages(byte[] message, int count)
20 | {
21 | return ProcessMessages(FutureSpreadMessage.Parse, ParseErrorMessage, message, count);
22 | }
23 |
24 | public MessageContainer GetFutureSpreadMessagesWithRequestId(byte[] message, int count)
25 | {
26 | return ProcessMessages(FutureSpreadMessage.ParseWithRequestId, ParseErrorMessage, message, count);
27 | }
28 |
29 | public MessageContainer GetFutureOptionMessages(byte[] message, int count)
30 | {
31 | return ProcessMessages(FutureOptionMessage.Parse, ParseErrorMessage, message, count);
32 | }
33 |
34 | public MessageContainer GetFutureOptionMessagesWithRequestId(byte[] message, int count)
35 | {
36 | return ProcessMessages(FutureOptionMessage.ParseWithRequestId, ParseErrorMessage, message, count);
37 | }
38 |
39 | public MessageContainer GetEquityOptionMessages(byte[] message, int count)
40 | {
41 | return ProcessMessages(EquityOptionMessage.Parse, ParseErrorMessage, message, count);
42 | }
43 | public MessageContainer GetEquityOptionMessagesWithRequestId(byte[] message, int count)
44 | {
45 | return ProcessMessages(EquityOptionMessage.ParseWithRequestId, ParseErrorMessage, message, count);
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/ChainsRequestFormatter.cs:
--------------------------------------------------------------------------------
1 | using System.Net.PeerToPeer.Collaboration;
2 |
3 | namespace IQFeed.CSharpApiClient.Lookup.Chains
4 | {
5 | public class ChainsRequestFormatter
6 | {
7 | public string ReqChainFuture(string symbol, string monthCodes, string years, int? nearMonths = null, string requestId = null)
8 | {
9 | var request = $"CFU,{symbol.ToUpper()},{monthCodes.ToUpper()},{years},{nearMonths},{requestId}{IQFeedDefault.ProtocolTerminatingCharacters}";
10 | return request;
11 | }
12 |
13 | public string ReqChainFutureSpreads(string symbol, string monthCodes, string years, int? nearMonths = null, string requestId = null)
14 | {
15 | var request = $"CFS,{symbol.ToUpper()},{monthCodes},{years},{nearMonths},{requestId}{IQFeedDefault.ProtocolTerminatingCharacters}";
16 | return request;
17 | }
18 |
19 | public string ReqChainFutureOption(string symbol, OptionSideFilterType optionSideFilter, string monthCodes, string years, int? nearMonths = null, string requestId = null)
20 | {
21 | var request = $"CFO,{symbol.ToUpper()},{optionSideFilter.ToString().ToLower()},{monthCodes},{years},{nearMonths},{requestId}{IQFeedDefault.ProtocolTerminatingCharacters}";
22 | return request;
23 | }
24 |
25 | // Protocol Update to 6.1 - Added "includeNonStandardOptions" - IQ Default is false
26 | public string ReqChainIndexEquityOption(string symbol, OptionSideFilterType optionSideFilter, string monthCodes, int? nearMonths = null,
27 | OptionFilterType optionFilter = OptionFilterType.None, int? filterValue1 = null, int? filterValue2 = null, string requestId = null, bool includeNonStandardOptions = false)
28 | {
29 | var wireFormatIncludeNonStandardOptions = includeNonStandardOptions ? 1 : 0;
30 | var request = $"CEO,{symbol},{optionSideFilter.ToString().ToLower()},{monthCodes},{nearMonths},{(int)optionFilter}," +
31 | $"{filterValue1},{filterValue2},{requestId},{wireFormatIncludeNonStandardOptions}{IQFeedDefault.ProtocolTerminatingCharacters}";
32 | return request;
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/Futures/FutureMonthCode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Lookup.Chains.Futures
4 | {
5 | public static class FutureMonthCode
6 | {
7 | public static int Decode(string monthCode)
8 | {
9 | switch (monthCode)
10 | {
11 | case "F":
12 | return 1;
13 | case "G":
14 | return 2;
15 | case "H":
16 | return 3;
17 | case "J":
18 | return 4;
19 | case "K":
20 | return 5;
21 | case "M":
22 | return 6;
23 | case "N":
24 | return 7;
25 | case "Q":
26 | return 8;
27 | case "U":
28 | return 9;
29 | case "V":
30 | return 10;
31 | case "X":
32 | return 11;
33 | case "Z":
34 | return 12;
35 | default:
36 | throw new NotSupportedException("MonthCode not supported");
37 | }
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/Futures/FutureSpread.cs:
--------------------------------------------------------------------------------
1 | using System.Text.RegularExpressions;
2 |
3 | namespace IQFeed.CSharpApiClient.Lookup.Chains.Futures
4 | {
5 | public class FutureSpread
6 |
7 | {
8 | private const string FutureSpreadSymbolPattern = "(.*)(-)(.*)";
9 |
10 | private const int FutureSymbol1Component = 1;
11 | private const int FutureSymbol2Component = 3;
12 |
13 | public string Symbol { get; }
14 | public Future Spread1 { get; }
15 | public Future Spread2 { get; }
16 |
17 | public FutureSpread(string symbol, Future spread1, Future spread2)
18 | {
19 | Symbol = symbol;
20 | Spread1 = spread1;
21 | Spread2 = spread2;
22 | }
23 |
24 | public static FutureSpread Parse(string futureSpreadSymbol)
25 | {
26 | var m = Regex.Match(futureSpreadSymbol, FutureSpreadSymbolPattern);
27 | var futureSymbol1 = m.Groups[FutureSymbol1Component].Value;
28 | var futureSymbol2 = m.Groups[FutureSymbol2Component].Value;
29 |
30 | return new FutureSpread(
31 | futureSpreadSymbol,
32 | Future.Parse(futureSymbol1),
33 | Future.Parse(futureSymbol2)
34 | );
35 | }
36 |
37 | public override bool Equals(object obj)
38 | {
39 | return obj is FutureSpread message &&
40 | Symbol == message.Symbol &&
41 | Spread1.Equals(message.Spread1) &&
42 | Spread2.Equals(message.Spread2);
43 | }
44 |
45 | public override int GetHashCode()
46 | {
47 | unchecked
48 | {
49 | var hash = 17;
50 | hash = hash * 29 + Symbol.GetHashCode();
51 | hash = hash * 29 + Spread1.GetHashCode();
52 | hash = hash * 29 + Spread2.GetHashCode();
53 | return hash;
54 | }
55 | }
56 |
57 | public override string ToString()
58 | {
59 | return $"{Spread1} - {Spread2}";
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/IChainsFacadeSync.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using IQFeed.CSharpApiClient.Lookup.Chains.Equities;
3 | using IQFeed.CSharpApiClient.Lookup.Chains.Futures;
4 |
5 | namespace IQFeed.CSharpApiClient.Lookup.Chains
6 | {
7 | public interface IChainsFacadeSync
8 | {
9 | IEnumerable GetChainFuture(string symbol, string monthCodes, string years, int? nearMonths = null, string requestId = null);
10 |
11 | IEnumerable GetChainFutureSpreads(string symbol, string monthCodes, string years, int? nearMonths = null, string requestId = null);
12 |
13 | IEnumerable GetChainFutureOption(string symbol, OptionSideFilterType optionSideFilter, string monthCodes, string years, int? nearMonths = null, string requestId = null);
14 |
15 | IEnumerable GetChainIndexEquityOption(string symbol, OptionSideFilterType optionSideFilter, string monthCodes, int? nearMonths = null, OptionFilterType optionFilter = OptionFilterType.None, int? filterValue1 = null, int? filterValue2 = null, string requestId = null);
16 | }
17 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/Messages/ChainsMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using IQFeed.CSharpApiClient.Extensions;
4 |
5 | namespace IQFeed.CSharpApiClient.Lookup.Chains.Messages
6 | {
7 | public class ChainsMessage
8 | {
9 | public const string ChainsDataId = "LC";
10 |
11 | public ChainsMessage()
12 | {
13 | Chains = new List();
14 | }
15 |
16 | public ChainsMessage(IList chains)
17 | {
18 | Chains = chains;
19 | }
20 |
21 | public IList Chains { get; private set; }
22 |
23 | public string RequestId { get; set; }
24 |
25 | protected IEnumerable GetSymbols(string message, bool hasRequestId)
26 | {
27 | // we now have either: LC,ListOfSymbols OR requestId,LC,ListOfSymbols
28 | var values = message.SplitFeedMessage();
29 | RequestId = hasRequestId ? values[0] : null;
30 | var symbolBase = hasRequestId ? 2 : 1;
31 | var length = values.Length - symbolBase;
32 | var symbols = new Memory(values, symbolBase, length).ToArray();
33 |
34 | foreach (var symbol in symbols)
35 | {
36 | // skip characters
37 | if (symbol == ":" || symbol == string.Empty || symbol == " ")
38 | continue;
39 |
40 | yield return symbol;
41 | }
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/Messages/EquityOptionMessage.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using IQFeed.CSharpApiClient.Lookup.Chains.Equities;
3 |
4 | namespace IQFeed.CSharpApiClient.Lookup.Chains.Messages
5 | {
6 | public class EquityOptionMessage : ChainsMessage
7 | {
8 | public EquityOptionMessage(string message, bool hasRequestId)
9 | {
10 | ParseInner(message, hasRequestId);
11 | }
12 |
13 | public static EquityOptionMessage Parse(string message)
14 | {
15 | return new EquityOptionMessage(message, false);
16 | }
17 |
18 | public static EquityOptionMessage ParseWithRequestId(string message)
19 | {
20 | return new EquityOptionMessage(message, true);
21 | }
22 |
23 | private void ParseInner(string message, bool hasRequestid)
24 | {
25 | foreach (var symbol in GetSymbols(message, hasRequestid))
26 | {
27 | Chains.Add(EquityOption.Parse(symbol));
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/Messages/FutureMessage.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using IQFeed.CSharpApiClient.Lookup.Chains.Futures;
3 |
4 | namespace IQFeed.CSharpApiClient.Lookup.Chains.Messages
5 | {
6 | public class FutureMessage : ChainsMessage
7 | {
8 | public FutureMessage(string message, bool hasRequestId)
9 | {
10 | ParseInner(message, hasRequestId);
11 | }
12 |
13 | public static FutureMessage Parse(string message)
14 | {
15 | return new FutureMessage(message, false);
16 | }
17 |
18 | public static FutureMessage ParseWithRequestId(string message)
19 | {
20 | return new FutureMessage(message, true);
21 | }
22 |
23 | public void ParseInner(string message, bool hasRequestId)
24 | {
25 | foreach (var symbol in GetSymbols(message, hasRequestId))
26 | {
27 | Chains.Add(Future.Parse(symbol));
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/Messages/FutureOptionMessage.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using IQFeed.CSharpApiClient.Lookup.Chains.Futures;
3 |
4 | namespace IQFeed.CSharpApiClient.Lookup.Chains.Messages
5 | {
6 | public class FutureOptionMessage : ChainsMessage
7 | {
8 | public FutureOptionMessage(string message, bool hasRequestId)
9 | {
10 | ParseInner(message, hasRequestId);
11 | }
12 |
13 | public static FutureOptionMessage Parse(string message)
14 | {
15 | return new FutureOptionMessage(message, false);
16 | }
17 |
18 | public static FutureOptionMessage ParseWithRequestId(string message)
19 | {
20 | return new FutureOptionMessage(message, true);
21 | }
22 |
23 | private void ParseInner(string message, bool hasRequestId)
24 | {
25 | foreach (var symbol in GetSymbols(message, hasRequestId))
26 | {
27 | Chains.Add(FutureOption.Parse(symbol));
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/Messages/FutureSpreadMessage.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using IQFeed.CSharpApiClient.Lookup.Chains.Futures;
3 |
4 | namespace IQFeed.CSharpApiClient.Lookup.Chains.Messages
5 | {
6 | public class FutureSpreadMessage : ChainsMessage
7 | {
8 | public FutureSpreadMessage(string message, bool hasRequestId)
9 | {
10 | ParseInner(message, hasRequestId);
11 | }
12 |
13 | public static FutureSpreadMessage Parse(string message)
14 | {
15 | return new FutureSpreadMessage(message, false);
16 | }
17 |
18 | public static FutureSpreadMessage ParseWithRequestId(string message)
19 | {
20 | return new FutureSpreadMessage(message, true);
21 | }
22 |
23 | public void ParseInner(string message, bool hasRequestId)
24 | {
25 | foreach (var symbol in GetSymbols(message, hasRequestId))
26 | {
27 | Chains.Add(FutureSpread.Parse(symbol));
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/OptionFilterType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Chains
2 | {
3 | public enum OptionFilterType
4 | {
5 | None = 0,
6 | StrikeRange = 1,
7 | NumberOfInOutTheMoneyContracts = 2
8 | }
9 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/OptionSide.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Chains
2 | {
3 | public enum OptionSide
4 | {
5 | Call,
6 | Put
7 | }
8 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Chains/OptionSideFilterType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Chains
2 | {
3 | public enum OptionSideFilterType
4 | {
5 | ///
6 | /// Call options only
7 | ///
8 | C,
9 | ///
10 | /// Put options only
11 | ///
12 | P,
13 | ///
14 | /// Call and Put options
15 | ///
16 | CP
17 | }
18 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Common/LookupMessageFileParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.IO.Compression;
5 |
6 | namespace IQFeed.CSharpApiClient.Lookup.Common
7 | {
8 | public class LookupMessageFileParser
9 | {
10 | public static IEnumerable ParseFromFile(Func parseFunc, string path)
11 | {
12 | return ParseFromFile(parseFunc, new StreamReader(path));
13 | }
14 |
15 | public static IEnumerable ParseFromFile(Func parseFunc, Stream stream)
16 | {
17 | return ParseFromFile(parseFunc, new StreamReader(stream));
18 | }
19 |
20 | public static IEnumerable ParseFromFile(Func parseFunc, StreamReader file)
21 | {
22 | using (file)
23 | {
24 | string line;
25 | while ((line = file.ReadLine()) != null)
26 | {
27 | if (string.IsNullOrEmpty(line) || line[0] == '!')
28 | continue;
29 |
30 | yield return parseFunc(line);
31 | }
32 | }
33 | }
34 |
35 | public static IEnumerable ParseFromArchive(Func parseFunc, string zipPath)
36 | {
37 | using (ZipArchive archive = ZipFile.OpenRead(zipPath))
38 | {
39 | foreach (var entry in archive.Entries)
40 | {
41 | using (var stream = entry.Open())
42 | {
43 | foreach (var message in ParseFromFile(parseFunc, stream))
44 | {
45 | yield return message;
46 | }
47 | }
48 | }
49 | }
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Historical/Enums/DataDirection.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Historical.Enums
2 | {
3 | public enum DataDirection
4 | {
5 | ///
6 | /// newest to oldest = 0 (default)
7 | ///
8 | Newest = 0,
9 | ///
10 | /// oldest to newest = 1
11 | ///
12 | Oldest = 1
13 | }
14 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Historical/Enums/LabelAtBeginning.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Historical.Enums
2 | {
3 | public enum LabelAtBeginning
4 | {
5 | End = 0,
6 | Beginning = 1 // default
7 | }
8 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Historical/HistoricalIntervalType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Historical
2 | {
3 | public enum HistoricalIntervalType
4 | {
5 | ///
6 | /// time intervals in seconds
7 | ///
8 | S,
9 |
10 | ///
11 | /// volume intervals
12 | ///
13 | V,
14 |
15 | ///
16 | /// tick intervals
17 | ///
18 | T
19 | }
20 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Historical/HistoricalMessageHandler.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Common;
2 | using IQFeed.CSharpApiClient.Lookup.Common;
3 | using IQFeed.CSharpApiClient.Lookup.Historical.Messages;
4 |
5 | namespace IQFeed.CSharpApiClient.Lookup.Historical
6 | {
7 | public class HistoricalMessageHandler : BaseLookupMessageHandler, IHistoricalMessageHandler
8 | {
9 | public const string HistoricalDataId = "LH";
10 |
11 | public static readonly TryParseDelegate TryParseTick = TickMessage.TryParse;
12 | public static readonly TryParseDelegate TryParseInterval = IntervalMessage.TryParse;
13 | public static readonly TryParseDelegate TryParseDaily = DailyWeeklyMonthlyMessage.TryParse;
14 |
15 | // tick
16 | public MessageContainer GetTickMessages(byte[] message, int count)
17 | {
18 | return ProcessMessages(TryParseTick, ParseErrorMessage, message, count);
19 | }
20 |
21 | public MessageContainer GetTickMessagesWithRequestId(byte[] message, int count)
22 | {
23 | return ProcessMessages(TickMessage.ParseWithRequestId, ParseErrorMessageWithRequestId, message, count);
24 | }
25 |
26 | // interval
27 | public MessageContainer GetIntervalMessages(byte[] message, int count)
28 | {
29 | return ProcessMessages(TryParseInterval, ParseErrorMessage, message, count);
30 | }
31 |
32 | public MessageContainer GetIntervalMessagesWithRequestId(byte[] message, int count)
33 | {
34 | return ProcessMessages(IntervalMessage.ParseWithRequestId, ParseErrorMessageWithRequestId, message, count);
35 | }
36 |
37 | // daily
38 | public MessageContainer GetDailyWeeklyMonthlyMessages(byte[] message, int count)
39 | {
40 | return ProcessMessages(TryParseDaily, ParseErrorMessage, message, count);
41 | }
42 |
43 | public MessageContainer GetDailyWeeklyMonthlyMessagesWithRequestId(byte[] message, int count)
44 | {
45 | return ProcessMessages(DailyWeeklyMonthlyMessage.ParseWithRequestId, ParseErrorMessageWithRequestId, message, count);
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Historical/IHistoricalMessageHandler.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Common;
2 | using IQFeed.CSharpApiClient.Lookup.Historical.Messages;
3 |
4 | namespace IQFeed.CSharpApiClient.Lookup.Historical
5 | {
6 | public interface IHistoricalMessageHandler
7 | {
8 | MessageContainer GetTickMessages(byte[] message, int count);
9 | MessageContainer GetTickMessagesWithRequestId(byte[] message, int count);
10 | MessageContainer GetIntervalMessages(byte[] message, int count);
11 | MessageContainer GetIntervalMessagesWithRequestId(byte[] message, int count);
12 | MessageContainer GetDailyWeeklyMonthlyMessages(byte[] message, int count);
13 | MessageContainer GetDailyWeeklyMonthlyMessagesWithRequestId(byte[] message, int count);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Historical/Messages/IDailyWeeklyMonthlyMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Lookup.Historical.Messages
4 | {
5 | public interface IDailyWeeklyMonthlyMessage : IHistoricalMessage
6 | {
7 | double Close { get; }
8 | double High { get; }
9 | double Low { get; }
10 | double Open { get; }
11 | int OpenInterest { get; }
12 | long PeriodVolume { get; }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Historical/Messages/IHistoricalMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Lookup.Historical.Messages
4 | {
5 | public interface IHistoricalMessage
6 | {
7 | DateTime Timestamp { get; }
8 | string RequestId { get; }
9 | }
10 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Historical/Messages/IIntervalMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Lookup.Historical.Messages
4 | {
5 | public interface IIntervalMessage : IHistoricalMessage
6 | {
7 | double Close { get; }
8 | double High { get; }
9 | double Low { get; }
10 | int NumberOfTrades { get; }
11 | double Open { get; }
12 | long PeriodVolume { get; }
13 | long TotalVolume { get; }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Historical/Messages/ITickMessage.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Historical.Messages
2 | {
3 | public interface ITickMessage : IHistoricalMessage
4 | {
5 | double Ask { get; }
6 | char BasisForLast { get; }
7 | double Bid { get; }
8 | double Last { get; }
9 | int LastSize { get; }
10 | long TickId { get; }
11 | int TotalVolume { get; }
12 | string TradeConditions { get; }
13 | int TradeMarketCenter { get; }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/LookupClient.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Common.Interfaces;
2 | using IQFeed.CSharpApiClient.Lookup.Chains;
3 | using IQFeed.CSharpApiClient.Lookup.Historical.Facades;
4 | using IQFeed.CSharpApiClient.Lookup.MarketSummary.Facades;
5 | using IQFeed.CSharpApiClient.Lookup.News;
6 | using IQFeed.CSharpApiClient.Lookup.Symbol;
7 |
8 | namespace IQFeed.CSharpApiClient.Lookup
9 | {
10 | public class LookupClient: IClient
11 | {
12 | private readonly LookupDispatcher _lookupDispatcher;
13 |
14 | public LookupClient(
15 | LookupDispatcher lookupDispatcher,
16 | HistoricalFacade historical,
17 | NewsFacade news,
18 | SymbolFacade symbol,
19 | ChainsFacade chains,
20 | MarketSummaryFacade marketSummary)
21 | {
22 | _lookupDispatcher = lookupDispatcher;
23 | Historical = historical;
24 | News = news;
25 | Symbol = symbol;
26 | Chains = chains;
27 | MarketSummary = marketSummary;
28 | }
29 |
30 | public HistoricalFacade Historical { get; }
31 | public NewsFacade News { get; }
32 | public SymbolFacade Symbol { get; }
33 | public ChainsFacade Chains { get; }
34 | public MarketSummaryFacade MarketSummary { get; }
35 |
36 | public void Connect()
37 | {
38 | _lookupDispatcher.ConnectAll();
39 | }
40 |
41 | public void Disconnect()
42 | {
43 | _lookupDispatcher.DisconnectAll();
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/LookupDefault.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Lookup
4 | {
5 | public class LookupDefault
6 | {
7 | ///
8 | /// Default timeout before canceling tasks (5 minutes)
9 | /// This can be changed using LookupClientFactory parameters
10 | ///
11 | public static TimeSpan Timeout = TimeSpan.FromMinutes(5);
12 |
13 | ///
14 | /// Default buffer size for Lookup SocketClient
15 | /// Note: SocketClients connected to the lookup port, we need to assign them larger buffer
16 | /// than usual because since we're waiting for the \r\n pattern to notify upper layer that we
17 | /// completed a new message, some particular responses such on GetChainIndexEquityOptionAsync
18 | /// IQFeed will return on the same line all matching symbols causing overflow
19 | ///
20 | public const int BufferSize = 32 * 1024;
21 |
22 | ///
23 | /// Default requests per second allowed by IQFeed
24 | /// IQFeed can tolerate very short burst around 75 requests/second.
25 | /// and corresponding tests for more info.
26 | ///
27 | public const int RequestsPerSecond = 50;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/MarketSummary/Facades/IMarketSummaryFacade.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Lookup.Symbol;
2 | using System;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace IQFeed.CSharpApiClient.Lookup.MarketSummary.Facades
8 | {
9 | public interface IMarketSummaryFacade
10 | {
11 | Task GetEndOfDaySummaryAsync(SecurityType securityType, int listedMarketGroupId, DateTime date, string requestId = null);
12 | Task GetEndOfDayFundamentalSummaryAsync(SecurityType securityType, int listedMarketGroupId, DateTime date, string requestId = null);
13 | Task Get5MinuteSnapshotSummaryAsync(SecurityType securityType, int listedMarketGroupId, string requestId = null);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/MarketSummary/Facades/MarketSummaryFileFacade.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Lookup.Common;
2 | using IQFeed.CSharpApiClient.Lookup.Symbol;
3 | using System;
4 | using System.Threading.Tasks;
5 |
6 | namespace IQFeed.CSharpApiClient.Lookup.MarketSummary.Facades
7 | {
8 | public class MarketSummaryFileFacade : IMarketSummaryFacade
9 | {
10 | private readonly MarketSummaryRequestFormatter _marketSummaryRequestFormatter;
11 | private readonly LookupMessageFileHandler _lookupMessageFileHandler;
12 |
13 | public MarketSummaryFileFacade(
14 | MarketSummaryRequestFormatter marketSummaryRequestFormatter,
15 | LookupMessageFileHandler lookupMessageFileHandler)
16 | {
17 | _lookupMessageFileHandler = lookupMessageFileHandler;
18 | _marketSummaryRequestFormatter = marketSummaryRequestFormatter;
19 | }
20 |
21 | public Task GetEndOfDaySummaryAsync(SecurityType securityType, int listedMarketGroupId, DateTime date, string requestId = null)
22 | {
23 | var request = _marketSummaryRequestFormatter.ReqEndOfDaySummary(securityType, listedMarketGroupId, date, requestId);
24 | return _lookupMessageFileHandler.GetFilenameAsync(request);
25 | }
26 |
27 | public Task GetEndOfDayFundamentalSummaryAsync(SecurityType securityType, int listedMarketGroupId, DateTime date, string requestId = null)
28 | {
29 | var request = _marketSummaryRequestFormatter.ReqFundamentalSummary(securityType, listedMarketGroupId, date, requestId);
30 | return _lookupMessageFileHandler.GetFilenameAsync(request);
31 | }
32 |
33 | public Task Get5MinuteSnapshotSummaryAsync(SecurityType securityType, int listedMarketGroupId, string requestId = null)
34 | {
35 | var request = _marketSummaryRequestFormatter.Req5MinuteSnapshotSummary(securityType, listedMarketGroupId, requestId);
36 | return _lookupMessageFileHandler.GetFilenameAsync(request);
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/MarketSummary/MarketSummaryDynamicFieldset.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace IQFeed.CSharpApiClient.Lookup.MarketSummary
8 | {
9 | public enum MarketSummaryDynamicFieldset
10 | {
11 | RequestId,
12 | LM, // Protocol 6.2 DataId Constant 'LM'
13 | Symbol,
14 | Exchange, // ExchangeId
15 | Type, // SecurityType
16 | Last,
17 | TradeSize,
18 | TradedMarket,
19 | TradeDate,
20 | TradeTime,
21 | Open,
22 | High,
23 | Low,
24 | Close,
25 | Bid,
26 | BidMarket,
27 | BidSize,
28 | Ask,
29 | AskMarket,
30 | AskSize,
31 | Volume,
32 | PDayVolume,
33 | UpVolume,
34 | DownVolume,
35 | NeutralVolume,
36 | TradeCount,
37 | UpTrades,
38 | DownTrades,
39 | NeutralTrades,
40 | VWAP,
41 | MutualDiv,
42 | SevenDayYield,
43 | OpenInterest,
44 | Settlement,
45 | SettlementDate,
46 | ExpirationDate,
47 | Strike
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/MarketSummary/MarketSummaryFieldsetDescriptor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace IQFeed.CSharpApiClient.Lookup.MarketSummary
8 | {
9 | ///
10 | /// Until Market Summaries are out of beta and fixed, the field names/orders/count could change,
11 | /// so we need to handle them dynamically, which is slightly slower
12 | ///
13 | public class MarketSummaryFieldsetDescriptor
14 | {
15 |
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/MarketSummary/MarketSummaryRequestFormatter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Common;
3 | using IQFeed.CSharpApiClient.Lookup.Symbol;
4 |
5 | namespace IQFeed.CSharpApiClient.Lookup.MarketSummary
6 | {
7 | public class MarketSummaryRequestFormatter : RequestFormatter
8 | {
9 | public const string SourceDataDateFormat = "yyyyMMdd";
10 |
11 | public string ReqEndOfDaySummary(SecurityType securityType, int groupId, DateTime date, string requestId = null)
12 | {
13 | // EDS,[SecurityType],[GroupID],[Date],[RequestID]
14 | var wireDate = date.ToString(SourceDataDateFormat);
15 | var request = $"EDS,{((int)securityType)},{groupId},{wireDate},{requestId}{IQFeedDefault.ProtocolTerminatingCharacters}";
16 | return request;
17 | }
18 |
19 | public string ReqFundamentalSummary(SecurityType securityType, int groupId, DateTime date, string requestId = null)
20 | {
21 | // FDS,[SecurityType],[GroupID],[Date],[RequestID]
22 | var wireDate = date.ToString(SourceDataDateFormat);
23 | var request = $"FDS,{((int)securityType)},{groupId},{wireDate},{requestId}{IQFeedDefault.ProtocolTerminatingCharacters}";
24 | return request;
25 | }
26 |
27 | public string Req5MinuteSnapshotSummary(SecurityType securityType, int groupId, string requestId = null)
28 | {
29 | // 5MS,[SecurityType],[GroupID],[Date],[RequestID]
30 | var request = $"5MS,{((int)securityType)},{groupId},{requestId}{IQFeedDefault.ProtocolTerminatingCharacters}";
31 | return request;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/News/Enums/FormatType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.News.Enums
2 | {
3 | public enum FormatType
4 | {
5 | XML,
6 | Text
7 | }
8 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/News/Enums/NewsFormatType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.News.Enums
2 | {
3 | public enum NewsFormatType
4 | {
5 | XML,
6 | Text,
7 | Email
8 | }
9 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/News/INewsFacade.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 | using IQFeed.CSharpApiClient.Lookup.News.Enums;
5 | using IQFeed.CSharpApiClient.Lookup.News.Messages;
6 |
7 | namespace IQFeed.CSharpApiClient.Lookup.News
8 | {
9 | public interface INewsFacade : INewsFacadeSync
10 | {
11 | Task> GetNewsConfigurationAsync(FormatType formatType, string requestId = null);
12 |
13 | Task> GetNewsHeadlinesAsync(string[] sources = null, string[] symbols = null, FormatType? formatType = null, int? limit = null, DateTime? date = null, string requestId = null);
14 |
15 | Task> GetNewsStoryAsync(string id, NewsFormatType? formatType = null, string deliverTo = null, string requestId = null);
16 |
17 | Task> GetNewsStoryCountAsync(string[] symbols, FormatType? formatType = null, string[] sources = null, DateTime? fromDate = null, DateTime? toDate = null, string requestId = null);
18 | }
19 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/News/INewsFacadeSync.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using IQFeed.CSharpApiClient.Lookup.News.Enums;
4 | using IQFeed.CSharpApiClient.Lookup.News.Messages;
5 |
6 | namespace IQFeed.CSharpApiClient.Lookup.News
7 | {
8 | public interface INewsFacadeSync
9 | {
10 | IEnumerable GetNewsConfiguration(FormatType formatType, string requestId = null);
11 |
12 | IEnumerable GetNewsHeadlines(string[] sources = null, string[] symbols = null, FormatType? formatType = null, int? limit = null, DateTime? date = null, string requestId = null);
13 |
14 | IEnumerable GetNewsStory(string id, NewsFormatType? formatType = null, string deliverTo = null, string requestId = null);
15 |
16 | IEnumerable GetNewsStoryCount(string[] symbols, FormatType? formatType = null, string[] sources = null, DateTime? fromDate = null, DateTime? toDate = null, string requestId = null);
17 | }
18 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/News/NewsMessageHandler.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Common;
2 | using IQFeed.CSharpApiClient.Lookup.Common;
3 | using IQFeed.CSharpApiClient.Lookup.News.Messages;
4 |
5 | namespace IQFeed.CSharpApiClient.Lookup.News
6 | {
7 | public class NewsMessageHandler : BaseLookupMessageHandler
8 | {
9 | public MessageContainer GetString(byte[] message, int count)
10 | {
11 | return ProcessMessages(s => s, ParseErrorMessage, message, count);
12 | }
13 |
14 | public MessageContainer GetStringWithRequestId(byte[] message, int count)
15 | {
16 | return ProcessMessages(s => s, ParseErrorMessageWithRequestId, message, count);
17 | }
18 |
19 | public MessageContainer GetNewsHeadlines(byte[] message, int count)
20 | {
21 | return ProcessMessages(NewsHeadlinesMessage.Parse, ParseErrorMessage, message, count);
22 | }
23 |
24 | public MessageContainer GetNewsHeadlinesWithRequestId(byte[] message, int count)
25 | {
26 | return ProcessMessages(NewsHeadlinesMessage.ParseWithRequestId, ParseErrorMessageWithRequestId, message, count);
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/Downloader/ILocalCacheStrategy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Lookup.Symbol.Downloader
4 | {
5 | public interface ILocalCacheStrategy
6 | {
7 | bool HasExpired(string path, TimeSpan expiration);
8 | }
9 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/Downloader/LocalCacheStrategy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace IQFeed.CSharpApiClient.Lookup.Symbol.Downloader
5 | {
6 | public class LocalCacheStrategy : ILocalCacheStrategy
7 | {
8 | public bool HasExpired(string path, TimeSpan expiration)
9 | {
10 | if (!File.Exists(path))
11 | return true;
12 |
13 | return DateTime.Now > File.GetCreationTime(path) + expiration;
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/Enums/FieldToSearch.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Symbol.Enums
2 | {
3 | public enum FieldToSearch
4 | {
5 | ///
6 | /// Search symbols
7 | ///
8 | Symbols = 's',
9 |
10 | ///
11 | /// Search descriptions
12 | ///
13 | Descriptions = 'd'
14 | }
15 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/Enums/FilterType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Symbol.Enums
2 | {
3 | public enum FilterType
4 | {
5 | ///
6 | /// Search within specific Listed Markets
7 | ///
8 | ListedMarkets = 'e',
9 |
10 | ///
11 | /// Search within specific Security Types
12 | ///
13 | SecurityTypes = 't'
14 | }
15 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/ExpiredOptions/ExpiredOption.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using IQFeed.CSharpApiClient.Lookup.Chains.Equities;
4 |
5 | namespace IQFeed.CSharpApiClient.Lookup.Symbol.ExpiredOptions
6 | {
7 | public class ExpiredOption
8 | {
9 | public const string LastUpdateDateTimeFormat = "yyyyMMdd";
10 |
11 | public EquityOption EquityOption { get; }
12 | public int SecurityType { get; }
13 | public string Description { get; }
14 | public int Exchange { get; }
15 | public DateTime LastUpdate { get; }
16 |
17 | public static ExpiredOption Parse(string line)
18 | {
19 | // Symbol,SecurityType,Description,ExpirationDate,Exchange,LastUpdate
20 | // CIEN1808R23.5,2,CIEN JUN 2018 P 23.50,20180608,14,20180612
21 | var values = line.Split(',');
22 |
23 | var equityOption = EquityOption.Parse(values[0]);
24 | int.TryParse(values[1], out var securityType);
25 | var title = values[2].Trim();
26 | // skip values[3] ExpirationDate already part of EquityOption
27 | int.TryParse(values[4], out var exchange);
28 | DateTime.TryParseExact(values[5], LastUpdateDateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out var lastUpdate);
29 |
30 | return new ExpiredOption(equityOption, securityType, title, exchange, lastUpdate);
31 | }
32 |
33 | public ExpiredOption(EquityOption equityOption, int securityType, string description, int exchange, DateTime lastUpdate)
34 | {
35 | EquityOption = equityOption;
36 | SecurityType = securityType;
37 | Description = description;
38 | Exchange = exchange;
39 | LastUpdate = lastUpdate;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/ExpiredOptions/ExpiredOptionReader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.IO;
3 |
4 | namespace IQFeed.CSharpApiClient.Lookup.Symbol.ExpiredOptions
5 | {
6 | public class ExpiredOptionReader
7 | {
8 | public IEnumerable GetExpiredOptions(string filename)
9 | {
10 | var lineCount = 0;
11 | using (var file = new StreamReader(filename))
12 | {
13 | string line;
14 | while ((line = file.ReadLine()) != null)
15 | {
16 | lineCount++;
17 |
18 | // ignore the header
19 | if (lineCount == 1)
20 | continue;
21 |
22 | yield return ExpiredOption.Parse(line);
23 | }
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/ISymbolFacadeDownload.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using IQFeed.CSharpApiClient.Lookup.Symbol.ExpiredOptions;
4 | using IQFeed.CSharpApiClient.Lookup.Symbol.MarketSymbols;
5 |
6 | namespace IQFeed.CSharpApiClient.Lookup.Symbol
7 | {
8 | public interface ISymbolFacadeDownload
9 | {
10 | IEnumerable GetAllMarketSymbols(string url = SymbolDefault.MarketSymbolsArchiveUrl, bool useCache = true, TimeSpan? expiration = null);
11 | IEnumerable GetAllMarketSymbols(string downloadFolder, string url = SymbolDefault.MarketSymbolsArchiveUrl, bool useCache = true, TimeSpan? expiration = null);
12 |
13 | IEnumerable GetAllExpiredOptions(string url = SymbolDefault.ExpiredOptionsArchiveUrl, bool useCache = true, TimeSpan? expiration = null);
14 | IEnumerable GetAllExpiredOptions(string downloadFolder, string url = SymbolDefault.ExpiredOptionsArchiveUrl, bool useCache = true, TimeSpan? expiration = null);
15 | }
16 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/ISymbolFacadeSync.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using IQFeed.CSharpApiClient.Lookup.Symbol.Enums;
3 | using IQFeed.CSharpApiClient.Lookup.Symbol.Messages;
4 |
5 | namespace IQFeed.CSharpApiClient.Lookup.Symbol
6 | {
7 | public interface ISymbolFacadeSync
8 | {
9 | IEnumerable GetSymbolsByFilter(FieldToSearch fieldToSearch, string searchString, FilterType? filterType, IEnumerable filterValues, string requestId = null);
10 | IEnumerable GetSymbolsBySicCode(string sicCodePrefix, string requestId = null);
11 | IEnumerable GetSymbolsByNaicsCode(string naicsCodePrefix, string requestId = null);
12 | IEnumerable GetListedMarkets(string requestId = null);
13 | IEnumerable GetSecurityTypes(string requestId = null);
14 | IEnumerable GetTradeConditions(string requestId = null);
15 | IEnumerable GetSicCodes(string requestId = null);
16 | IEnumerable GetNaicsCodes(string requestId = null);
17 | }
18 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/MarketSymbols/MarketSymbol.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Symbol.MarketSymbols
2 | {
3 | public class MarketSymbol
4 | {
5 | public string Symbol { get; private set; }
6 | public string Description { get; private set; }
7 | public string Exchange { get; private set; }
8 | public string ListedMarket { get; private set; }
9 | public string SecurityType { get; private set; }
10 | public string Sic { get; private set; }
11 | public string Frontmonth { get; private set; }
12 | public string Naics { get; private set; }
13 |
14 | public MarketSymbol(string symbol, string description, string exchange, string listedMarket, string securityType, string sic, string frontmonth, string naics)
15 | {
16 | Symbol = symbol;
17 | Description = description;
18 | Exchange = exchange;
19 | ListedMarket = listedMarket;
20 | SecurityType = securityType;
21 | Sic = sic;
22 | Frontmonth = frontmonth;
23 | Naics = naics;
24 | }
25 |
26 | public override string ToString()
27 | {
28 | return $"{nameof(Symbol)}: {Symbol}, {nameof(Description)}: {Description}, {nameof(Exchange)}: {Exchange}, {nameof(ListedMarket)}: {ListedMarket}, {nameof(SecurityType)}: {SecurityType}, {nameof(Sic)}: {Sic}, {nameof(Frontmonth)}: {Frontmonth}, {nameof(Naics)}: {Naics}";
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/MarketSymbols/MarketSymbolExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace IQFeed.CSharpApiClient.Lookup.Symbol.MarketSymbols
5 | {
6 | public static class MarketSymbolExtensions
7 | {
8 | public static IEnumerable AreEquitiesOrIndexes(this IEnumerable marketSymbols)
9 | {
10 | return marketSymbols.Where(x => x.SecurityType == MarketSymbolSecurityType.EQUITY || x.SecurityType == MarketSymbolSecurityType.INDEX);
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/MarketSymbols/MarketSymbolReader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.IO;
3 |
4 | namespace IQFeed.CSharpApiClient.Lookup.Symbol.MarketSymbols
5 | {
6 | public class MarketSymbolReader
7 | {
8 | public IEnumerable GetMarketSymbols(string filename)
9 | {
10 | var lineCount = 0;
11 |
12 | using (var file = new StreamReader(filename))
13 | {
14 | string line;
15 | string[] values;
16 |
17 | while ((line = file.ReadLine()) != null && (values = line.Split('\t')).Length == 8)
18 | {
19 | lineCount++;
20 |
21 | if (lineCount == 1) // ignore the header
22 | continue;
23 |
24 | yield return new MarketSymbol(values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7]);
25 | }
26 | }
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/MarketSymbols/MarketSymbolSecurityType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Symbol.MarketSymbols
2 | {
3 | public class MarketSymbolSecurityType
4 | {
5 | public const string STRIP = "STRIP";
6 | public const string FUTURE = "FUTURE";
7 | public const string COMBINED_FUTURE = "COMBINED_FUTURE";
8 | public const string INDEX = "INDEX";
9 | public const string COMBINED_FOPTION = "COMBINED_FOPTION";
10 | public const string FOPTION = "FOPTION";
11 | public const string STRATSPREAD = "STRATSPREAD";
12 | public const string SPREAD = "SPREAD";
13 | public const string ICSPREAD = "ICSPREAD";
14 | public const string EQUITY = "EQUITY";
15 | public const string IEOPTION = "IEOPTION";
16 | public const string BONDS = "BONDS";
17 | public const string SPOT = "SPOT";
18 | public const string MUTUAL = "MUTUAL";
19 | public const string MONEY = "MONEY";
20 | public const string FOREX = "FOREX";
21 | public const string MKTSTATS = "MKTSTATS";
22 | public const string PRECMTL = "PRECMTL";
23 | public const string MKTRPT = "MKTRPT";
24 | public const string TREASURIES = "TREASURIES";
25 | public const string FORWARD = "FORWARD";
26 | public const string SWAPS = "SWAPS";
27 | }
28 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/SecurityType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Symbol
2 | {
3 | public enum SecurityType
4 | {
5 | ///
6 | /// Equity
7 | ///
8 | EQUITY = 1,
9 |
10 | ///
11 | /// Index/Equity Option
12 | ///
13 | IEOPTION = 2,
14 |
15 | ///
16 | /// Mutual Fund
17 | ///
18 | MUTUAL = 3,
19 |
20 | ///
21 | /// Money Market Fund
22 | ///
23 | MONEY = 4,
24 |
25 | ///
26 | /// Bond
27 | ///
28 | BONDS = 5,
29 |
30 | ///
31 | /// Index
32 | ///
33 | INDEX = 6,
34 |
35 | ///
36 | /// Market Statistic
37 | ///
38 | MKTSTATS = 7,
39 |
40 | ///
41 | /// Future
42 | ///
43 | FUTURE = 8,
44 |
45 | ///
46 | /// Future Option
47 | ///
48 | FOPTION = 9,
49 |
50 | ///
51 | /// Future Spread
52 | ///
53 | SPREAD = 10,
54 |
55 | ///
56 | /// Spot (Cash) Price
57 | ///
58 | SPOT = 11,
59 |
60 | ///
61 | /// Forward
62 | ///
63 | FORWARD = 12,
64 |
65 | ///
66 | /// DTN Calculated Statistic
67 | ///
68 | CALC = 13,
69 |
70 | ///
71 | /// Calculated Strip
72 | ///
73 | STRIP = 14,
74 |
75 | ///
76 | /// Single Stock Future
77 | ///
78 | SSFUTURE = 15,
79 |
80 | ///
81 | /// Foreign Monetary Exchange
82 | ///
83 | FOREX = 16,
84 |
85 | ///
86 | /// Future Market Depth
87 | ///
88 | MKTDEPTH = 17,
89 |
90 | ///
91 | /// Precious Metals
92 | ///
93 | PRECMTL = 18,
94 | }
95 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Lookup/Symbol/SymbolDefault.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Lookup.Symbol
2 | {
3 | public class SymbolDefault
4 | {
5 | public const string MarketSymbolsArchiveUrl = "http://www.dtniq.com/product/mktsymbols_v2.zip";
6 |
7 | public const string ExpiredOptionsArchiveUrl = "http://www.iqfeed.net/downloads/beta/IEOPTION.zip";
8 |
9 | ///
10 | /// We can't check the length of values on most of the messages in this group,
11 | /// as some description fields can contain commas (giving us a variable number of
12 | /// fields, so we need to look for this DataId in the correct field instead.
13 | ///
14 | public const string SymbolsDataId = "LS";
15 | }
16 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Socket/SocketDiagnostic.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Sockets;
2 | using System.Threading;
3 |
4 | namespace IQFeed.CSharpApiClient.Socket
5 | {
6 | public static class SocketDiagnostic
7 | {
8 | public static bool IsPortOpen(string host, int port, int timeout, int retry)
9 | {
10 | var retryCount = 0;
11 | while (retryCount < retry)
12 | {
13 | if (retryCount > 0)
14 | Thread.Sleep(timeout);
15 |
16 | try
17 | {
18 | using (var client = new TcpClient(AddressFamily.InterNetwork))
19 | {
20 | var result = client.BeginConnect(host, port, null, null);
21 | var success = result.AsyncWaitHandle.WaitOne(timeout);
22 | if (success)
23 | return true;
24 |
25 | client.EndConnect(result);
26 | }
27 | }
28 | catch
29 | {
30 | // ignored
31 | }
32 | finally { retryCount++; }
33 | }
34 |
35 | return false;
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Socket/SocketMessageEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Socket
4 | {
5 | public class SocketMessageEventArgs : EventArgs
6 | {
7 | public byte[] Message { get; set;}
8 | public int Count { get; set; }
9 | }
10 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/AdminClientFactory.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Socket;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Admin
4 | {
5 | public class AdminClientFactory
6 | {
7 | public static AdminClient CreateNew(string host, int port)
8 | {
9 | return new AdminClient(
10 | new SocketClient(host, port),
11 | new AdminRequestFormatter(),
12 | new AdminMessageHandler()
13 | );
14 | }
15 |
16 | public static AdminClient CreateNew()
17 | {
18 | return new AdminClient(
19 | new SocketClient(IQFeedDefault.Hostname, IQFeedDefault.AdminPort),
20 | new AdminRequestFormatter(),
21 | new AdminMessageHandler()
22 | );
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/AdminRequestFormatter.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Common;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Admin
4 | {
5 | public class AdminRequestFormatter : RequestFormatter
6 | {
7 | public string RegisterClientApp(string productId, string productVersion)
8 | {
9 | return $"S,REGISTER CLIENT APP,{productId},{productVersion}{IQFeedDefault.ProtocolTerminatingCharacters}".ToUpper();
10 | }
11 |
12 | public string RemoveClientApp(string productId, string productVersion)
13 | {
14 | return $"S,REMOVE CLIENT APP,{productId},{productVersion}{IQFeedDefault.ProtocolTerminatingCharacters}".ToUpper();
15 | }
16 |
17 | public string SetLoginId(string userLoginId)
18 | {
19 | return $"S,SET LOGINID,{userLoginId}{IQFeedDefault.ProtocolTerminatingCharacters}";
20 | }
21 |
22 | public string SetPassword(string userPassword)
23 | {
24 | return $"S,SET PASSWORD,{userPassword}{IQFeedDefault.ProtocolTerminatingCharacters}";
25 | }
26 |
27 | public string SetSaveLoginInfo(bool on)
28 | {
29 | var value = on ? "On" : "Off";
30 | return $"S,SET SAVE LOGIN INFO,{value}{IQFeedDefault.ProtocolTerminatingCharacters}";
31 | }
32 |
33 | public string SetAutoconnect(bool on)
34 | {
35 | var value = on ? "On" : "Off";
36 | return $"S,SET AUTOCONNECT,{value}{IQFeedDefault.ProtocolTerminatingCharacters}";
37 | }
38 |
39 | public string ReqServerConnect()
40 | {
41 | return $"S,CONNECT{IQFeedDefault.ProtocolTerminatingCharacters}";
42 | }
43 |
44 | public string ReqServerDisconnect()
45 | {
46 | return $"S,DISCONNECT{IQFeedDefault.ProtocolTerminatingCharacters}";
47 | }
48 |
49 | public string SetClientStats(bool on)
50 | {
51 | var value = on ? "ON" : "OFF";
52 | return $"S,CLIENTSTATS {value}{IQFeedDefault.ProtocolTerminatingCharacters}";
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/ClientType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Admin
2 | {
3 | public enum ClientType
4 | {
5 | Admin = 0,
6 | Level1 = 1,
7 | Level2 = 2,
8 | Lookup = 3,
9 | }
10 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/IAdminClient.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Common;
2 | using IQFeed.CSharpApiClient.Common.Interfaces;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Admin
5 | {
6 | public interface IAdminClient: IClient, IAdminMessage
7 | {
8 | void RegisterClientApp(string productId, string productVersion);
9 | void RemoveClientApp(string productId, string productVersion);
10 | void SetLoginId(string userLoginId);
11 | void SetPassword(string userPassword);
12 | void SetSaveLoginInfo(bool on = true);
13 | void SetAutoconnect(bool on = true);
14 | void ReqServerConnect();
15 | void ReqServerDisconnect();
16 | void SetClientStats(bool on = true);
17 |
18 |
19 | // TODO: should be part from another interface
20 | void SetProtocol(string version);
21 | void SetClientName(string name);
22 | }
23 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/IAdminMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Common.Messages;
3 | using IQFeed.CSharpApiClient.Streaming.Admin.Messages;
4 |
5 | namespace IQFeed.CSharpApiClient.Streaming.Admin
6 | {
7 | public interface IAdminMessage
8 | {
9 | event Action Protocol;
10 | event Action ClientApp;
11 | event Action LoginId;
12 | event Action Password;
13 | event Action LoginInfo;
14 | event Action AutoConnect;
15 | event Action Stats;
16 | event Action ClientStats;
17 | }
18 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/Messages/AutoConnectMessage.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Admin.Messages
2 | {
3 | public class AutoConnectMessage
4 | {
5 | public AutoConnectMessageType Type { get; private set; }
6 |
7 | public AutoConnectMessage(AutoConnectMessageType type)
8 | {
9 | Type = type;
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/Messages/AutoConnectMessageType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Admin.Messages
2 | {
3 | public enum AutoConnectMessageType
4 | {
5 | On,
6 | Off
7 | }
8 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/Messages/ClientAppMessage.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Admin.Messages
2 | {
3 | public class ClientAppMessage
4 | {
5 | public ClientAppMessageType Type { get; private set; }
6 |
7 | public ClientAppMessage(ClientAppMessageType type)
8 | {
9 | Type = type;
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/Messages/ClientAppMessageType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Admin.Messages
2 | {
3 | public enum ClientAppMessageType
4 | {
5 | Register,
6 | Remove
7 | }
8 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/Messages/ClientStatsMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using IQFeed.CSharpApiClient.Extensions;
4 |
5 | namespace IQFeed.CSharpApiClient.Streaming.Admin.Messages
6 | {
7 | public class ClientStatsMessage
8 | {
9 | public const string ClientStatsDatetimeFormat = "yyyyMMdd HHmmss";
10 |
11 | public ClientType Type { get; private set; }
12 | public int ClientId { get; private set; }
13 | public string ClientName { get; private set; }
14 | public DateTime StartTime { get; private set; }
15 | public int? Symbols { get; private set; }
16 | public int? RegionalSymbols { get; private set; }
17 | public double KbReceived { get; private set; }
18 | public double KbSent { get; private set; }
19 | public double KbQueued { get; private set; }
20 |
21 | public ClientStatsMessage(ClientType type, int clientId, string clientName, DateTime startTime, int? symbols, int? regionalSymbols, double kbReceived, double kbSent, double kbQueued)
22 | {
23 | Type = type;
24 | ClientId = clientId;
25 | ClientName = clientName;
26 | StartTime = startTime;
27 | Symbols = symbols;
28 | RegionalSymbols = regionalSymbols;
29 | KbReceived = kbReceived;
30 | KbSent = kbSent;
31 | KbQueued = kbQueued;
32 | }
33 |
34 | public static ClientStatsMessage CreateClientStatsMessage(string[] values)
35 | {
36 | int.TryParse(values[1], out var clientTypeInt);
37 | var clientType = (ClientType)clientTypeInt;
38 | int.TryParse(values[2], out var clientId);
39 | var clientName = values[3];
40 | DateTime.TryParseExact(values[4], ClientStatsDatetimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out var startTime);
41 | var symbols = values[5].ToNullableInt();
42 | var regionalSymbols = values[6].ToNullableInt();
43 | double.TryParse(values[7], out var kbReceived);
44 | double.TryParse(values[8], out var kbSent);
45 | double.TryParse(values[9], out var kbQueued);
46 |
47 | return new ClientStatsMessage(clientType, clientId, clientName, startTime, symbols, regionalSymbols, kbReceived, kbSent, kbQueued);
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/Messages/LoginIdMessage.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Admin.Messages
2 | {
3 | public class LoginIdMessage
4 | {
5 | public string UserLoginId { get; private set; }
6 |
7 | public LoginIdMessage(string userLoginId)
8 | {
9 | UserLoginId = userLoginId;
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/Messages/LoginInfoMessage.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Admin.Messages
2 | {
3 | public class LoginInfoMessage
4 | {
5 | public LoginInfoMessageType Type { get; private set; }
6 |
7 | public LoginInfoMessage(LoginInfoMessageType type)
8 | {
9 | Type = type;
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/Messages/LoginInfoMessageType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Admin.Messages
2 | {
3 | public enum LoginInfoMessageType
4 | {
5 | Saved,
6 | NotSaved
7 | }
8 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/Messages/PasswordMessage.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Admin.Messages
2 | {
3 | public class PasswordMessage
4 | {
5 | public PasswordMessage(string userPassword)
6 | {
7 | UserPassword = userPassword;
8 | }
9 | public string UserPassword { get; private set; }
10 | }
11 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Admin/StatsStatusType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Admin
2 | {
3 | public enum StatsStatusType
4 | {
5 | NotConnected,
6 | Connected
7 | }
8 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Common/Messages/ErrorMessage.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Extensions;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Common.Messages
4 | {
5 | public class ErrorMessage
6 | {
7 | public ErrorMessage(string error)
8 | {
9 | Error = error;
10 | }
11 |
12 | public string Error { get; private set; }
13 |
14 | public static ErrorMessage Parse(string message)
15 | {
16 | var values = message.SplitFeedMessage();
17 | return new ErrorMessage(values[1]);
18 | }
19 |
20 | public override bool Equals(object obj)
21 | {
22 | return obj is ErrorMessage message && Error == message.Error;
23 | }
24 |
25 | public override int GetHashCode()
26 | {
27 | unchecked
28 | {
29 | return 2010064793 + Error.GetHashCode();
30 | }
31 | }
32 |
33 | public override string ToString()
34 | {
35 | return $"{nameof(Error)}: {Error}";
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Common/Messages/SymbolNotFoundMessage.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Extensions;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Common.Messages
4 | {
5 | public class SymbolNotFoundMessage
6 | {
7 | public SymbolNotFoundMessage(string symbol)
8 | {
9 | Symbol = symbol;
10 | }
11 |
12 | public string Symbol { get; private set; }
13 |
14 | public static SymbolNotFoundMessage Parse(string message)
15 | {
16 | var values = message.SplitFeedMessage();
17 | return new SymbolNotFoundMessage(values[1]);
18 | }
19 |
20 | public override bool Equals(object obj)
21 | {
22 | return obj is SymbolNotFoundMessage message &&
23 | Symbol == message.Symbol;
24 | }
25 |
26 | public override int GetHashCode()
27 | {
28 | unchecked
29 | {
30 | return -1758840423 + Symbol.GetHashCode();
31 | }
32 | }
33 |
34 | public override string ToString()
35 | {
36 | return $"{nameof(Symbol)}: {Symbol}";
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Common/Messages/SystemMessage.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Extensions;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Common.Messages
4 | {
5 | public class SystemMessage
6 | {
7 | public string Type { get; private set; }
8 | public string Message { get; private set; }
9 |
10 | public SystemMessage(string type, string message)
11 | {
12 | Type = type;
13 | Message = message;
14 | }
15 |
16 | public static SystemMessage Parse(string message)
17 | {
18 | var values = message.SplitFeedMessage();
19 |
20 | return new SystemMessage(values[1], message);
21 | }
22 |
23 | public override bool Equals(object obj)
24 | {
25 | return obj is SystemMessage message &&
26 | Type == message.Type &&
27 | Message == message.Message;
28 | }
29 |
30 | public override int GetHashCode()
31 | {
32 | unchecked
33 | {
34 | var hashCode = 17;
35 | hashCode = hashCode * 29 + Type.GetHashCode();
36 | hashCode = hashCode * 29 + Message.GetHashCode();
37 | return hashCode;
38 | }
39 | }
40 |
41 | public override string ToString()
42 | {
43 | return $"{nameof(Type)}: {Type}, {nameof(Message)}: {Message}";
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Common/Messages/TimestampMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using IQFeed.CSharpApiClient.Extensions;
4 |
5 | namespace IQFeed.CSharpApiClient.Streaming.Common.Messages
6 | {
7 | // T,[YYYYMMDD HH:mm:SS]
8 | public class TimestampMessage
9 | {
10 | public const string TimestampMessageDateTimeFormat = "yyyyMMdd HH:mm:ss";
11 |
12 | public TimestampMessage(DateTime timestamp)
13 | {
14 | Timestamp = timestamp;
15 | }
16 |
17 | public DateTime Timestamp { get; private set; }
18 |
19 | public static TimestampMessage Parse(string message)
20 | {
21 | var values = message.SplitFeedMessage();
22 |
23 | DateTime.TryParseExact(values[1], TimestampMessageDateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out var timestamp);
24 | return new TimestampMessage(timestamp);
25 | }
26 |
27 | public override bool Equals(object obj)
28 | {
29 | return obj is TimestampMessage message &&
30 | Timestamp == message.Timestamp;
31 | }
32 |
33 | public override int GetHashCode()
34 | {
35 | unchecked
36 | {
37 | return 227403579 + Timestamp.GetHashCode();
38 | }
39 | }
40 |
41 | public override string ToString()
42 | {
43 | return $"{nameof(Timestamp)}: {Timestamp}";
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Derivative/DerivativeClientFactory.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Socket;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Derivative
4 | {
5 | public class DerivativeClientFactory
6 | {
7 | public static DerivativeClient CreateNew(string host, int port, int bufferSize)
8 | {
9 | return new DerivativeClient(new SocketClient(host, port, bufferSize), new DerivativeRequestFormatter(), new DerivativeMessageHandler());
10 | }
11 |
12 | public static DerivativeClient CreateNew()
13 | {
14 | return CreateNew(IQFeedDefault.Hostname, IQFeedDefault.DerivativePort, DerivativeDefault.BufferSize);
15 | }
16 |
17 | public static DerivativeClient CreateNew(string host, int port)
18 | {
19 | return CreateNew(host, port, DerivativeDefault.BufferSize);
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Derivative/DerivativeDefault.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Derivative
2 | {
3 | public class DerivativeDefault
4 | {
5 | public const int BufferSize = 32 * 1024;
6 | }
7 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Derivative/DerivativeIntervalType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Derivative
2 | {
3 | public enum DerivativeIntervalType
4 | {
5 | ///
6 | /// (default) for time intervals in seconds
7 | ///
8 | S,
9 | ///
10 | /// Volume intervals
11 | ///
12 | V,
13 | ///
14 | /// Tick intervals
15 | ///
16 | T
17 | }
18 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Derivative/DerivativeRequestFormatter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Common;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Derivative
5 | {
6 | public class DerivativeRequestFormatter : RequestFormatter
7 | {
8 | public const string DerivativeTimeFormat = "hhmmss";
9 | public const string DerivativeDatetimeFormat = "yyyyMMdd HHmmss";
10 |
11 | public string ReqBarWatch(string symbol, int interval, DateTime? beginDate = null, int? maxDaysOfDatapoints = null, int? maxDatapoints = null,
12 | TimeSpan? beginFilterTime = null, TimeSpan? endFilterTime = null, string requestId = null, DerivativeIntervalType? intervalType = null, int? updateInterval = null)
13 | {
14 | // BW,[Symbol],[Interval],[BeginDate BeginTime],[MaxDaysOfDatapoints],[MaxDatapoints],[BeginFilterTime],[EndFilterTime],[RequestID],[Interval Type],[Reserved],[UpdateInterval]
15 | var request = $"BW,{symbol.ToUpper()},{interval},{beginDate?.ToString(DerivativeDatetimeFormat)},{maxDaysOfDatapoints},{maxDatapoints},{beginFilterTime?.ToString(DerivativeTimeFormat)},{endFilterTime?.ToString(DerivativeTimeFormat)},{requestId},{intervalType?.ToString().ToLower()},,{updateInterval}{IQFeedDefault.ProtocolTerminatingCharacters}";
16 | return request;
17 | }
18 |
19 | public string ReqBarUnwatch(string symbol, string requestId)
20 | {
21 | return $"BR,{symbol.ToUpper()},{requestId},{IQFeedDefault.ProtocolTerminatingCharacters}";
22 | }
23 |
24 | public string ReqWatches()
25 | {
26 | return $"S,REQUEST WATCHES,{IQFeedDefault.ProtocolTerminatingCharacters}";
27 | }
28 |
29 | public string UnwatchAll()
30 | {
31 | return $"S,UNWATCH ALL,{IQFeedDefault.ProtocolTerminatingCharacters}";
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Derivative/DerivativeWatchDefinition.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Text.RegularExpressions;
3 | using IQFeed.CSharpApiClient.Extensions;
4 |
5 | namespace IQFeed.CSharpApiClient.Streaming.Derivative
6 | {
7 | public class DerivativeWatchDefinition
8 | {
9 | private const string DerivativeWatchesPattern = "^S,WATCHES,(.*)$";
10 | private static readonly Regex DerivativeWatchesRegex = new Regex(DerivativeWatchesPattern);
11 |
12 | public DerivativeWatchDefinition(string symbol, string interval, string requestId)
13 | {
14 | Symbol = symbol;
15 | Interval = interval;
16 | RequestId = requestId;
17 | }
18 |
19 | public string Symbol { get; }
20 | public string Interval { get; }
21 | public string RequestId { get; }
22 |
23 | public static IEnumerable Parse(string message)
24 | {
25 | var match = DerivativeWatchesRegex.Match(message);
26 | if (match.Success)
27 | {
28 | var watches = match.Groups[1].Value.SplitFeedMessage();
29 | var offset = 0;
30 |
31 | while (offset < watches.Length)
32 | {
33 | yield return new DerivativeWatchDefinition(watches[offset], watches[offset + 1], watches[offset + 2]);
34 | offset += 3;
35 | }
36 | }
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Derivative/IDerivativeClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Common.Interfaces;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Derivative
5 | {
6 | public interface IDerivativeClient: IClient, IDerivativeEvent
7 | {
8 | void SetClientName(string name);
9 |
10 | void ReqBarWatch(string symbol, int interval, DateTime? beginDate = null, int? maxDaysOfDatapoints = null, int? maxDatapoints = null, TimeSpan? beginFilterTime = null,
11 | TimeSpan? endFilterTime = null, string requestId = null, DerivativeIntervalType? intervalType = null, int? updateInterval = null);
12 |
13 | void ReqBarUnwatch(string symbol, string requestId);
14 | void ReqWatches();
15 | void UnwatchAll();
16 | }
17 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Derivative/IDerivativeEvent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Common.Messages;
3 | using IQFeed.CSharpApiClient.Streaming.Derivative.Messages;
4 |
5 | namespace IQFeed.CSharpApiClient.Streaming.Derivative
6 | {
7 | public interface IDerivativeEvent
8 | {
9 | event Action Error;
10 | event Action IntervalBar;
11 | event Action SymbolNotFound;
12 | event Action System;
13 | }
14 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Derivative/IDerivativeMessageHandler.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Derivative
2 | {
3 | public interface IDerivativeMessageHandler : IDerivativeEvent
4 | {
5 | void ProcessMessages(byte[] messageBytes, int count);
6 | }
7 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Derivative/Messages/IIntervalBarMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Derivative.Messages
4 | {
5 | public interface IIntervalBarMessage
6 | {
7 | IntervalBarType Type { get; }
8 | string Symbol { get; }
9 | DateTime Timestamp { get; }
10 | double Open { get; }
11 | double High { get; }
12 | double Low { get; }
13 | double Last { get; }
14 |
15 | ///
16 | /// Last cummulative volume in the interval
17 | ///
18 | int CummulativeVolume { get; }
19 |
20 | ///
21 | /// Interval volume for the interval
22 | ///
23 | int IntervalVolume { get; }
24 |
25 | ///
26 | /// Number of trades in the interval (only valid for tick interval)
27 | ///
28 | int NumberOfTrades { get; }
29 |
30 | string RequestId { get; }
31 | }
32 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Derivative/Messages/IntervalBarType.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Derivative.Messages
2 | {
3 | public enum IntervalBarType
4 | {
5 | ///
6 | /// Update type; 'U' - updated interval bar
7 | ///
8 | U,
9 |
10 | ///
11 | /// 'H' - complete interval bar from history
12 | ///
13 | H,
14 |
15 | ///
16 | /// 'C' - complete interval bar from stream
17 | ///
18 | C
19 | }
20 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/FieldsetDescriptionAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming
4 | {
5 | internal class FieldsetDescriptionAttribute : Attribute
6 | {
7 | public string Name { get; }
8 | public Type Type { get; }
9 |
10 | public FieldsetDescriptionAttribute(string name, Type type)
11 | {
12 | Name = name;
13 | Type = type;
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Dynamic/Handlers/ILevel1DynamicMessageHandler.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Dynamic.Handlers
2 | {
3 | public interface ILevel1DynamicMessageHandler : ILevel1DynamicEvent
4 | {
5 | void ProcessMessages(byte[] messageBytes, int count);
6 | void SetDynamicFields(params DynamicFieldset[] fieldNames);
7 | }
8 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Dynamic/ILevel1DynamicClient.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Common;
2 | using IQFeed.CSharpApiClient.Common.Interfaces;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Dynamic
5 | {
6 | public interface ILevel1DynamicClient : IClient, ILevel1DynamicEvent, ILevel1DynamicSnapshot
7 | {
8 | void ReqWatch(string symbol);
9 | void ReqTradesOnlyWatch(string symbol);
10 | void ReqUnwatch(string symbol);
11 | void ReqForcedRefresh(string symbol);
12 | void ReqTimestamp();
13 | void ReqTimestamps(bool on);
14 | void ReqRegionalWatch(string symbol);
15 | void ReqRegionalUnwatch(string symbol);
16 | void ReqNews(bool on);
17 | void ReqStats();
18 | void ReqFundamentalFieldnames();
19 | void ReqUpdateFieldnames();
20 | void ReqCurrentUpdateFieldNames();
21 | void SetLogLevels(params LoggingLevel[] logLevels);
22 | void ReqWatchList();
23 | void ReqUnwatchAll();
24 | void ReqServerConnect();
25 | void ReqServerDisconnect();
26 | }
27 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Dynamic/ILevel1DynamicEvent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Level1.Dynamic.Messages;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Dynamic
5 | {
6 | public interface ILevel1DynamicEvent : ILevel1EventCommon
7 | {
8 | event Action Summary;
9 | event Action Update;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Dynamic/ILevel1DynamicSnapshot.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using IQFeed.CSharpApiClient.Streaming.Level1.Dynamic.Messages;
3 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
4 |
5 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Dynamic
6 | {
7 | public interface ILevel1DynamicSnapshot : ILevel1DynamicSnapshotSync
8 | {
9 | Task GetFundamentalSnapshotAsync(string symbol);
10 | Task GetUpdateSummarySnapshotAsync(string symbol);
11 | }
12 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Dynamic/ILevel1DynamicSnapshotSync.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Streaming.Level1.Dynamic.Messages;
2 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Dynamic
5 | {
6 | public interface ILevel1DynamicSnapshotSync
7 | {
8 | FundamentalMessage GetFundamentalSnapshot(string symbol);
9 | IUpdateSummaryDynamicMessage GetUpdateSummarySnapshot(string symbol);
10 | }
11 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Dynamic/Level1DynamicClientFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Socket;
3 | using IQFeed.CSharpApiClient.Streaming.Level1.Dynamic.Handlers;
4 |
5 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Dynamic
6 | {
7 | public static class Level1DynamicClientFactory
8 | {
9 | public static ILevel1DynamicClient CreateNew(string host, int port, TimeSpan snapshotTimeout, ILevel1DynamicMessageHandler level1DynamicMessageHandler, params DynamicFieldset[] fieldNames)
10 | {
11 | var socketClient = new SocketClient(host, port);
12 | var level1RequestFormatter = new Level1RequestFormatter();
13 |
14 | return new Level1DynamicClient(
15 | socketClient,
16 | level1RequestFormatter,
17 | level1DynamicMessageHandler,
18 | new Level1DynamicSnapshot(socketClient, level1RequestFormatter, level1DynamicMessageHandler, snapshotTimeout),
19 | fieldNames
20 | );
21 | }
22 |
23 | public static ILevel1DynamicClient CreateNew(params DynamicFieldset[] fieldNames)
24 | {
25 | return CreateNew(IQFeedDefault.Hostname, IQFeedDefault.Level1Port, Level1Default.SnapshotTimeout, new Level1DynamicMessageHandler(), fieldNames);
26 | }
27 |
28 | public static ILevel1DynamicClient CreateNew(ILevel1DynamicMessageHandler level1DynamicMessageHandler, params DynamicFieldset[] fieldNames)
29 | {
30 | return CreateNew(IQFeedDefault.Hostname, IQFeedDefault.Level1Port, Level1Default.SnapshotTimeout, level1DynamicMessageHandler, fieldNames);
31 | }
32 |
33 | public static ILevel1DynamicClient CreateNew(string host, int port, params DynamicFieldset[] fieldNames)
34 | {
35 | return CreateNew(host, port, Level1Default.SnapshotTimeout, new Level1DynamicMessageHandler(), fieldNames);
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Handlers/ILevel1MessageDynamicHandler.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Handlers
2 | {
3 | public interface ILevel1MessageDynamicHandler : ILevel1MessageHandler
4 | {
5 | void SetDynamicFields(params DynamicFieldset[] fieldNames);
6 | }
7 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Handlers/ILevel1MessageHandler.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Handlers
2 | {
3 | public interface ILevel1MessageHandler : ILevel1Event
4 | {
5 | void ProcessMessages(byte[] messageBytes, int count);
6 | }
7 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Handlers/Level1MessageDynamicHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Handlers
5 | {
6 | [Obsolete("Please use ILevel1DynamicClient instead. This handler will be removed soon!")]
7 | public class Level1MessageDynamicHandler : BaseLevel1MessageHandler, ILevel1MessageDynamicHandler
8 | {
9 | public event Action Summary;
10 | public event Action Update;
11 |
12 | private DynamicFieldset[] _dynamicFieldsets; // not thread-safe
13 |
14 | public void SetDynamicFields(params DynamicFieldset[] fieldNames)
15 | {
16 | if (fieldNames[0] != DynamicFieldset.Symbol)
17 | throw new ArgumentException("Symbol must be the first dynamic field specified.");
18 |
19 | foreach (var fieldName in fieldNames)
20 | {
21 | if (fieldName == DynamicFieldset.Type)
22 | throw new ArgumentException("Type is implicitly included in dynamic fields and must not be included in the dynamic fields requested.");
23 | }
24 |
25 | _dynamicFieldsets = fieldNames;
26 | }
27 |
28 | protected override void ProcessSummaryMessage(string msg)
29 | {
30 | var dynamicFields = Level1DynamicFields.Parse(msg, _dynamicFieldsets);
31 | Summary?.Invoke(new UpdateSummaryDynamicMessage(dynamicFields));
32 | }
33 |
34 | protected override void ProcessUpdateMessage(string msg)
35 | {
36 | var dynamicFields = Level1DynamicFields.Parse(msg, _dynamicFieldsets);
37 | Update?.Invoke(new UpdateSummaryDynamicMessage(dynamicFields));
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Handlers/Level1MessageHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Handlers
5 | {
6 | public class Level1MessageHandler : BaseLevel1MessageHandler, ILevel1MessageHandler
7 | {
8 | public event Action Summary;
9 | public event Action Update;
10 |
11 | protected override void ProcessSummaryMessage(string msg)
12 | {
13 | var updateSummaryMessage = UpdateSummaryMessage.Parse(msg);
14 | Summary?.Invoke(updateSummaryMessage);
15 | }
16 |
17 | protected override void ProcessUpdateMessage(string msg)
18 | {
19 | var updateSummaryMessage = UpdateSummaryMessage.Parse(msg);
20 | Update?.Invoke(updateSummaryMessage);
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/ILevel1Client.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Common;
2 | using IQFeed.CSharpApiClient.Common.Interfaces;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level1
5 | {
6 | public interface ILevel1Client: IClient, ILevel1Event, ILevel1Snapshot
7 | {
8 | void ReqWatch(string symbol);
9 | void ReqTradesOnlyWatch(string symbol);
10 | void ReqUnwatch(string symbol);
11 | void ReqForcedRefresh(string symbol);
12 | void ReqTimestamp();
13 | void ReqTimestamps(bool on);
14 | void ReqRegionalWatch(string symbol);
15 | void ReqRegionalUnwatch(string symbol);
16 | void ReqNews(bool on);
17 | void ReqStats();
18 | void ReqFundamentalFieldnames();
19 | void ReqUpdateFieldnames();
20 | void ReqCurrentUpdateFieldNames();
21 | void SelectUpdateFieldName(params DynamicFieldset[] fieldNames);
22 | void SetLogLevels(params LoggingLevel[] logLevels);
23 | void ReqWatchList();
24 | void ReqUnwatchAll();
25 | void ReqServerConnect();
26 | void ReqServerDisconnect();
27 | }
28 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/ILevel1Event.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level1
5 | {
6 | public interface ILevel1Event : ILevel1EventCommon
7 | {
8 | event Action Summary;
9 | event Action Update;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/ILevel1EventCommon.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Common.Messages;
3 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
4 |
5 | namespace IQFeed.CSharpApiClient.Streaming.Level1
6 | {
7 | public interface ILevel1EventCommon
8 | {
9 | event Action Fundamental;
10 | event Action System;
11 | event Action SymbolNotFound;
12 | event Action Error;
13 | event Action Timestamp;
14 | event Action Regional;
15 | event Action News;
16 | }
17 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/ILevel1Snapshot.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level1
5 | {
6 | public interface ILevel1Snapshot : ILevel1SnapshotSync
7 | {
8 | Task GetFundamentalSnapshotAsync(string symbol);
9 | Task GetUpdateSummarySnapshotAsync(string symbol);
10 | }
11 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/ILevel1SnapshotSync.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using IQFeed.CSharpApiClient.Streaming.Level1.Messages;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level1
5 | {
6 | public interface ILevel1SnapshotSync
7 | {
8 | FundamentalMessage GetFundamentalSnapshot(string symbol);
9 | IUpdateSummaryMessage GetUpdateSummarySnapshot(string symbol);
10 | }
11 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Level1ClientFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Socket;
3 | using IQFeed.CSharpApiClient.Streaming.Level1.Handlers;
4 |
5 | namespace IQFeed.CSharpApiClient.Streaming.Level1
6 | {
7 | public static class Level1ClientFactory
8 | {
9 | public static Level1Client CreateNew(string host, int port, TimeSpan snapshotTimeout, ILevel1MessageHandler level1MessageHandler)
10 | {
11 | var socketClient = new SocketClient(host, port);
12 | var level1RequestFormatter = new Level1RequestFormatter();
13 |
14 | return new Level1Client(
15 | socketClient,
16 | level1RequestFormatter,
17 | level1MessageHandler,
18 | new Level1Snapshot(socketClient, level1RequestFormatter, level1MessageHandler, snapshotTimeout)
19 | );
20 | }
21 |
22 | public static Level1Client CreateNew()
23 | {
24 | return CreateNew(IQFeedDefault.Hostname, IQFeedDefault.Level1Port, Level1Default.SnapshotTimeout, new Level1MessageHandler());
25 | }
26 |
27 | public static Level1Client CreateNew(ILevel1MessageHandler level1MessageHandler)
28 | {
29 | return CreateNew(IQFeedDefault.Hostname, IQFeedDefault.Level1Port, Level1Default.SnapshotTimeout, level1MessageHandler);
30 | }
31 |
32 | public static Level1Client CreateNew(string host, int port)
33 | {
34 | return CreateNew(host, port, Level1Default.SnapshotTimeout, new Level1MessageHandler());
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Level1Default.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Level1
4 | {
5 | public class Level1Default
6 | {
7 | public static TimeSpan SnapshotTimeout = TimeSpan.FromMinutes(1);
8 | }
9 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Messages/IRegionalUpdateMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Messages
4 | {
5 | public interface IRegionalUpdateMessage
6 | {
7 | string Symbol { get; }
8 | string Exchange { get; }
9 | double RegionalBid { get; }
10 | int RegionalBidSize { get; }
11 | DateTime RegionalBidTime { get; }
12 | double RegionalAsk { get; }
13 | int RegionalAskSize { get; }
14 | DateTime RegionalAskTime { get; }
15 | int FractionDisplayCode { get; }
16 | int DecimalPrecision { get; }
17 | int MarketCenter { get; }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Messages/ITradeCorrectionMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Messages
8 | {
9 | public interface ITradeCorrectionMessage
10 | {
11 | string Symbol { get; }
12 | string CorrectionType { get; }
13 | DateTime TradeDate { get; }
14 | TimeSpan TradeTime { get; }
15 | double TradePrice { get; }
16 | int TradeSize { get; }
17 | int TickId { get; }
18 | string TradeConditions { get; }
19 | int TradeMarketCentre { get; }
20 |
21 | DateTime TradeDateTime { get; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level1/Messages/IUpdateSummaryMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Level1.Messages
4 | {
5 | public interface IUpdateSummaryMessage
6 | {
7 | string Symbol { get; }
8 | double MostRecentTrade { get; }
9 | int MostRecentTradeSize { get; }
10 | TimeSpan MostRecentTradeTime { get; }
11 | int MostRecentTradeMarketCenter { get; }
12 | int TotalVolume { get; }
13 | double Bid { get; }
14 | int BidSize { get; }
15 | double Ask { get; }
16 | int AskSize { get; }
17 | double Open { get; }
18 | double High { get; }
19 | double Low { get; }
20 | double Close { get; }
21 | string MessageContents { get; }
22 | string MostRecentTradeConditions { get; }
23 |
24 | [Obsolete("Please use ILevel1DynamicClient instead. This field will be removed soon!")]
25 | Level1DynamicFields DynamicFields { get; }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/Enums/Level2MessageType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using IQFeed.CSharpApiClient.Streaming.Level2.Messages;
7 |
8 | namespace IQFeed.CSharpApiClient.Streaming.Level2.Enums
9 | {
10 | public enum Level2MessageType
11 | {
12 | PriceLevelOrder = 0,
13 | OrderAdd = 3,
14 | OrderLevelUpdate = 4,
15 | OrderDelete = 5,
16 | OrderLevelSummary = 6,
17 | PriceLevelSummary = 7,
18 | PriceLevelUpdate = 8,
19 | PriceLevelDelete = 9
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/Enums/Level2Side.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace IQFeed.CSharpApiClient.Streaming.Level2
8 | {
9 | public enum Level2Side
10 | {
11 | Sell,
12 | Buy
13 | }
14 |
15 | public static class Level2SideParser
16 | {
17 | public static Level2Side Parse(string text)
18 | {
19 | if (text == "S")
20 | {
21 | return Level2Side.Sell;
22 | } else if(text == "B")
23 | {
24 | return Level2Side.Buy;
25 | } else
26 | {
27 | return (Level2Side)Enum.Parse(typeof(Level2Side), text, true);
28 | }
29 | }
30 |
31 | public static bool TryParse(string text, out Level2Side result)
32 | {
33 | if (text == "S")
34 | {
35 | result = Level2Side.Sell;
36 | return true;
37 | }
38 |
39 | if (text == "B")
40 | {
41 | result = Level2Side.Buy;
42 | return true;
43 | }
44 |
45 | return Enum.TryParse(text, out result);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/ILevel2Client.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Common.Interfaces;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Level2
4 | {
5 | public interface ILevel2Client : IClient, ILevel2Event, ILevel2Snapshot
6 | {
7 | void ReqWatch(string symbol);
8 | void ReqWatchMarketByPrice(string symbol);
9 | void ReqWatchMarketByOrder(string symbol);
10 | void ReqMarketMakerNameById(string mmid);
11 | void ReqUnwatch(string symbol);
12 | void ReqServerConnect();
13 | void ReqServerDisconnect();
14 | }
15 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/ILevel2Event.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Common.Messages;
3 | using IQFeed.CSharpApiClient.Streaming.Level2.Messages;
4 |
5 | namespace IQFeed.CSharpApiClient.Streaming.Level2
6 | {
7 | public interface ILevel2Event
8 | {
9 | event Action Summary;
10 | event Action Update;
11 | event Action SymbolNotFound;
12 | event Action Query;
13 | event Action Error;
14 | event Action Timestamp;
15 | event Action System;
16 |
17 | //protocol 6.2 events
18 | event Action OrderAdd;
19 | event Action OrderUpdate;
20 | event Action OrderSummary;
21 | event Action OrderDelete;
22 | event Action PriceLevelOrder;
23 | event Action PriceLevelSummary;
24 | event Action PriceLevelUpdate;
25 | event Action PriceLevelDelete;
26 | }
27 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/ILevel2MessageHandler.cs:
--------------------------------------------------------------------------------
1 | namespace IQFeed.CSharpApiClient.Streaming.Level2
2 | {
3 | public interface ILevel2MessageHandler : ILevel2Event
4 | {
5 | void ProcessMessages(byte[] messageBytes, int count);
6 | }
7 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/ILevel2Snapshot.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using IQFeed.CSharpApiClient.Streaming.Level2.Messages;
4 |
5 | namespace IQFeed.CSharpApiClient.Streaming.Level2
6 | {
7 | public interface ILevel2Snapshot
8 | {
9 | Task> GetSummarySnapshotAsync(string symbol);
10 | }
11 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/Level2ClientFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Socket;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level2
5 | {
6 | public static class Level2ClientFactory
7 | {
8 | public static Level2Client CreateNew(string host, int port, TimeSpan snapshotTimeout, string protocolVersion = IQFeedDefault.ProtocolVersion)
9 | {
10 | var socketClient = new SocketClient(host, port);
11 | var level2RequestFormatter = new Level2RequestFormatter();
12 | var level2MessageHandler = new Level2MessageHandler();
13 |
14 | return new Level2Client(
15 | socketClient,
16 | level2RequestFormatter,
17 | level2MessageHandler,
18 | new Level2Snapshot(socketClient, level2RequestFormatter, level2MessageHandler, snapshotTimeout),
19 | protocolVersion
20 | );
21 | }
22 |
23 | public static Level2Client CreateNew(string protocolVersion = IQFeedDefault.ProtocolVersion)
24 | {
25 | return CreateNew(IQFeedDefault.Hostname, IQFeedDefault.Level2Port, Level2Default.SnapshotTimeout, protocolVersion);
26 | }
27 |
28 | public static Level2Client CreateNew(string host, int port, string protocolVersion = IQFeedDefault.ProtocolVersion)
29 | {
30 | return CreateNew(host, port, Level2Default.SnapshotTimeout, protocolVersion);
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/Level2Default.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Level2
4 | {
5 | public class Level2Default
6 | {
7 | public static TimeSpan SnapshotTimeout = TimeSpan.FromMinutes(2);
8 | }
9 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/Level2RequestFormatter.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Common;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Level2
4 | {
5 | public class Level2RequestFormatter : RequestFormatter
6 | {
7 | public string ReqWatch(string symbol)
8 | {
9 | return $"w{symbol.ToUpper()}{IQFeedDefault.ProtocolTerminatingCharacters}";
10 | }
11 |
12 | public string ReqWatchMarketByPrice(string symbol)
13 | {
14 | return $"WPL,{symbol.ToUpper()}{IQFeedDefault.ProtocolTerminatingCharacters}";
15 | }
16 |
17 | public string ReqWatchMarketByOrder(string symbol)
18 | {
19 | return $"WOR,{symbol.ToUpper()}{IQFeedDefault.ProtocolTerminatingCharacters}";
20 | }
21 |
22 | public string ReqMarketMakerNameById(string mmid)
23 | {
24 | return $"m{mmid.ToUpper()}{IQFeedDefault.ProtocolTerminatingCharacters}";
25 | }
26 |
27 | public string ReqUnwatch(string symbol)
28 | {
29 | return $"r{symbol.ToUpper()}{IQFeedDefault.ProtocolTerminatingCharacters}";
30 | }
31 |
32 | public string ReqServerConnect()
33 | {
34 | return $"c{IQFeedDefault.ProtocolTerminatingCharacters}";
35 | }
36 |
37 | public string ReqServerDisconnect()
38 | {
39 | return $"x{IQFeedDefault.ProtocolTerminatingCharacters}";
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/Messages/IOrderAddUpdateSummaryMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Level2.Enums;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level2.Messages
5 | {
6 | public interface IOrderAddUpdateSummaryMessage
7 | {
8 | ///
9 | /// Level 2 Message Type
10 | ///
11 | Level2MessageType MessageType { get; }
12 |
13 | ///
14 | /// The Security's Stock Symbol
15 | ///
16 | string Symbol { get; }
17 |
18 | ///
19 | /// The unique (per symbol) order identifier for this symbol.
20 | /// Only used in Market By Order messages.
21 | /// Will be blank for Nasdaq Level 2 messages
22 | ///
23 | UInt64 OrderId { get; }
24 |
25 | ///
26 | /// Market Maker ID - Only used for Nasdaq Level 2 messages.
27 | /// Will be blank for Market By Order Messages.
28 | ///
29 | string MMID { get; }
30 |
31 | ///
32 | /// Buy or Sell side
33 | ///
34 | Level2Side Side { get; }
35 |
36 | ///
37 | /// The price value of the price level that was added/updated
38 | ///
39 | double Price { get; }
40 |
41 | ///
42 | /// The size of this order
43 | ///
44 | int Size { get; }
45 |
46 | ///
47 | /// Used to position orders of the same price and side. Priority ranks from lowest to highest.
48 | ///
49 | UInt64 OrderPriority { get; }
50 |
51 | ///
52 | /// Number of places of decimal precision for the price field
53 | ///
54 | int Precision { get; set; }
55 |
56 | ///
57 | /// The time of this order
58 | ///
59 | TimeSpan OrderTime { get; }
60 |
61 | ///
62 | /// The date of this order
63 | ///
64 | DateTime OrderDate { get; }
65 |
66 | DateTime OrderDateTime { get; }
67 | bool Equals(object obj);
68 | int GetHashCode();
69 | string ToString();
70 | }
71 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/Messages/IOrderDeleteMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Level2.Enums;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level2.Messages
5 | {
6 | public interface IOrderDeleteMessage
7 | {
8 | ///
9 | /// Level 2 Message Type
10 | ///
11 | Level2MessageType MessageType { get; }
12 |
13 | ///
14 | /// The Security's Stock Symbol
15 | ///
16 | string Symbol { get; }
17 |
18 | ///
19 | /// The unique (per symbol) order identifier for this symbol.
20 | /// Only used in Market By Order messages.
21 | /// Will be blank for Nasdaq Level 2 messages
22 | ///
23 | UInt64 OrderId { get; }
24 |
25 | ///
26 | /// Buy or Sell side
27 | ///
28 | Level2Side Side { get; }
29 |
30 | ///
31 | /// The time of this order
32 | ///
33 | TimeSpan OrderTime { get; }
34 |
35 | ///
36 | /// The date of this order
37 | ///
38 | DateTime OrderDate { get; }
39 |
40 | DateTime OrderDateTime { get; }
41 | bool Equals(object obj);
42 | int GetHashCode();
43 | string ToString();
44 | }
45 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/Messages/IPriceLevelDeleteMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Level2.Enums;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level2.Messages
5 | {
6 | public interface IPriceLevelDeleteMessage
7 | {
8 | ///
9 | /// Level 2 Message Type
10 | ///
11 | Level2MessageType MessageType { get; }
12 |
13 | ///
14 | /// The Security's Stock Symbol
15 | ///
16 | string Symbol { get; }
17 |
18 | ///
19 | /// Buy or Sell side
20 | ///
21 | Level2Side Side { get; }
22 |
23 | ///
24 | /// The price value of the price level that was deleted
25 | ///
26 | double Price { get; }
27 |
28 | ///
29 | /// The time of this order
30 | ///
31 | TimeSpan Time { get; }
32 |
33 | ///
34 | /// The date of this order
35 | ///
36 | DateTime Date { get; }
37 |
38 | DateTime DateTime { get; }
39 | bool Equals(object obj);
40 | int GetHashCode();
41 | string ToString();
42 | }
43 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/Messages/IPriceLevelUpdateSummaryMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IQFeed.CSharpApiClient.Streaming.Level2.Enums;
3 |
4 | namespace IQFeed.CSharpApiClient.Streaming.Level2.Messages
5 | {
6 | public interface IPriceLevelUpdateSummaryMessage
7 | {
8 | ///
9 | /// Level 2 Message Type
10 | ///
11 | Level2MessageType MessageType { get; }
12 |
13 | ///
14 | /// The Security's Stock Symbol
15 | ///
16 | string Symbol { get; }
17 |
18 | ///
19 | /// Buy or Sell side
20 | ///
21 | Level2Side Side { get; }
22 |
23 | ///
24 | /// The price value of the price level that was added/updated
25 | ///
26 | double Price { get; }
27 |
28 | ///
29 | /// The total size of all orders at this price level
30 | ///
31 | int Size { get; }
32 |
33 | ///
34 | /// The total number of orders at this price level
35 | ///
36 | int OrderCount { get; }
37 |
38 | ///
39 | /// Number of places of decimal precision for the price field
40 | ///
41 | int Precision { get; set; }
42 |
43 | ///
44 | /// The time of the most current order that affected this price level
45 | ///
46 | TimeSpan Time { get; }
47 |
48 | ///
49 | /// The date of the most current order that affected this price level
50 | ///
51 | DateTime Date { get; }
52 |
53 | DateTime OrderDateTime { get; }
54 | bool Equals(object obj);
55 | int GetHashCode();
56 | string ToString();
57 | }
58 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/Messages/IUpdateSummaryMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Level2.Messages
4 | {
5 | public interface IUpdateSummaryMessage
6 | {
7 | string Symbol { get; }
8 | string MMID { get; }
9 | double Bid { get; }
10 | double Ask { get; }
11 | int BidSize { get; }
12 | int AskSize { get; }
13 | TimeSpan BidTime { get; }
14 | DateTime Date { get; }
15 | string ConditionCode { get; }
16 | TimeSpan AskTime { get; }
17 | char BidInfoValid { get; }
18 | char AskInfoValid { get; }
19 | char EndOfMessageGroup { get; }
20 | }
21 | }
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/Messages/MarketMakerNameMessage.cs:
--------------------------------------------------------------------------------
1 | using IQFeed.CSharpApiClient.Extensions;
2 |
3 | namespace IQFeed.CSharpApiClient.Streaming.Level2.Messages
4 | {
5 | public class MarketMakerNameMessage
6 | {
7 | public MarketMakerNameMessage(string mmid, string description)
8 | {
9 | MMID = mmid;
10 | Description = description;
11 | }
12 |
13 | public string MMID { get; private set; }
14 | public string Description { get; private set; }
15 |
16 | public static MarketMakerNameMessage Parse(string message)
17 | {
18 | var values = message.SplitFeedMessage();
19 | var mmid = values[1];
20 | var description = values[2];
21 |
22 | return new MarketMakerNameMessage(mmid, description);
23 | }
24 |
25 | public override bool Equals(object obj)
26 | {
27 | return obj is MarketMakerNameMessage message &&
28 | MMID == message.MMID &&
29 | Description == message.Description;
30 | }
31 |
32 | public override int GetHashCode()
33 | {
34 | unchecked
35 | {
36 | var hash = 17;
37 | hash = hash * 29 + MMID.GetHashCode();
38 | hash = hash * 29 + Description.GetHashCode();
39 | return hash;
40 | }
41 | }
42 |
43 | public override string ToString()
44 | {
45 | return $"{nameof(MMID)}: {MMID}, {nameof(Description)}: {Description}";
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/IQFeed.CSharpApiClient/Streaming/Level2/Messages/PriceLevelOrderMessage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using IQFeed.CSharpApiClient.Streaming.Level2.Enums;
7 |
8 | namespace IQFeed.CSharpApiClient.Streaming.Level2.Messages
9 | {
10 | ///
11 | /// This message is actually the same format as the OrderAddUpdateSummaryMessage
12 | ///
13 | public class PriceLevelOrderMessage : OrderAddUpdateSummaryMessage
14 | {
15 | public PriceLevelOrderMessage(
16 | Level2MessageType messageType,
17 | string symbol,
18 | UInt64 orderId,
19 | string mmid,
20 | Level2Side side,
21 | double price,
22 | int size,
23 | UInt64 orderPriority,
24 | int precision,
25 | TimeSpan orderTime,
26 | DateTime orderDate) : base(messageType, symbol, orderId, mmid, side, price, size, orderPriority, precision, orderTime, orderDate)
27 | {
28 | }
29 |
30 | public new static PriceLevelOrderMessage Parse(string message)
31 | {
32 | var messageParsed = OrderAddUpdateSummaryMessage.Parse(message);
33 | return new PriceLevelOrderMessage(
34 | messageParsed.MessageType,
35 | messageParsed.Symbol,
36 | messageParsed.OrderId,
37 | messageParsed.MMID,
38 | messageParsed.Side,
39 | messageParsed.Price,
40 | messageParsed.Size,
41 | messageParsed.OrderPriority,
42 | messageParsed.Precision,
43 | messageParsed.OrderTime,
44 | messageParsed.OrderDate
45 | );
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------