IPF Data Provider
Provider supplying a list of data about trading instruments that can be set on the chart, along with their trading hours.
import Combine/// Protocol for receiving instrument profile data - array of InstrumentData.////// When loading DXChart framework, an array of instruments, their descriptions, etc. are taken from this interface////// When connecting DXChart framework, developer can implement this interface or use the default implementation [link on the default implementation] and pass it to the framework using DXChart.DataProvider classpublic protocol IPFDataProvider {/// Publisher of receiving instrument profile data.////// Instrument profile data is represented by array of InstrumentData.var dataPublisher: AnyPublisher<Result<[DXChart.Instrument], Error>, Never> { get }/// Provide information about loading status.var isLoading: AnyPublisher<Bool, Never> { get }}
Possible Server Errors:
public enum ServerError: Error {case unknowncase noDatacase parseErrorcase urlErrorcase tooManyRequestscase unknown}
InstrumentData structure uses following parameters:
/// A structure that represents a financial instrument.////// The `Instrument` struct stores essential information about a financial instrument, such as its type, symbol, description, time zone, price increments, and trading schedule.////// - Note: This struct conforms to `Codable`, allowing it to be easily encoded and decoded for serialization purposes.////// - Properties:/// - `type`: The type of the instrument (e.g., `STOCK`, `CRYPTO`)./// - `symbol`: The symbol of the instrument (e.g., `GOOG`, `TSLA`, `AAPL`)./// - `description`: A description of the instrument (e.g., `Alphabet Inc. - Class C Capital Stock`)./// - `timezone`: The time zone associated with the instrument (e.g., `America/New_York`)./// - `priceIncrements`: The minimum price increment for the instrument (e.g., `0.01`)./// - `schedule`: The trading schedule for the instrument, including session breaks and extended hours. This property is optional.public struct Instrument: Codable {/// The type of the instrument (e.g., `STOCK`, `CRYPTO`).public var type: String/// The symbol of the instrument (e.g., `GOOG`, `TSLA`, `AAPL`).public var symbol: String/// A description of the instrument (e.g., `Alphabet Inc. - Class C Capital Stock`).public var description: String/// The time zone associated with the instrument (e.g., `America/New_York`).public var timezone: String/// The minimum price increment for the instrument (e.g., `0.01`).public var priceIncrements: String/// The trading schedule for the instrument, including session breaks and extended hours./// This property is optional and can be `nil` if no schedule is available.public var schedule: Trading.Schedule?}@available(*, deprecated, renamed: "Instrument", message: "This typealias is deprecated and will be removed in a future version. Use `Instrument` directly instead.")/// A deprecated typealias for `Instrument`.////// This typealias is provided for backward compatibility and will be removed in a future version./// Use `Instrument` directly instead.public typealias InstrumentData = Instrument
- type - Type of instrument (f.e. STOCK, CRYPTO)
- symbol - Symbol of the instrument (e.g., "GOOG", "TSLA", "AAPL").
- description - Description of the instrument (e.g., "Alphabet Inc. - Class C Capital Stock").
- timezone - Raw data about timezone of the instrument (e.g., "Asia/Istanbul", "America/New_York").
- sessionBreaks - Parsed trading hours of the instrument. (e.g., "BIST(name=BIST;tz=Asia/Istanbul;hd=TR;sd=TR;td=12345;de=+0000;0=10001800)").
- priceIncrements - Minimal price increments of the instrument (e.g., "0.01 20; 0.02 50; 0.05 100; 0.1 250; 0.25 500; 0.5 1000; 1 2500; 2.5").
Received data about instruments is displayed in the list of instruments:
Default implementation
If you haven't implemented an IPF data provider earlier and are using `DXFeedFramework` to retrieve data, you can use our default provider. To work with it and `DXFeedFramework`, you need an `IPF Address` to obtain instrument information. Please contact your DXFeed sales manager or visit https://dxfeed.com/contact-sales/ for assistance.
Default implementation code:
import Combineimport DXChartimport DXFeedFrameworkfinal class DXFeedIPFDataProvider: DXChart.IPFDataProvider {typealias IPFResult = Result<[DXChart.Instrument], Error>let address: Stringprivate let dataStorage = DataStorage.sharedprivate var instruments: [DXChart.Instrument]?private var _isLoading = PassthroughSubject<Bool, Never>()var isLoading: AnyPublisher<Bool, Never> {_isLoading.eraseToAnyPublisher()}lazy var dataPublisher: AnyPublisher<IPFResult, Never> = Deferred { [weak self] inFuture<IPFResult, Never> { promise inguard let self else { return promise(.success(.failure(ServerError.noData)))}if let instruments = self.instruments {return promise(.success(.success(instruments)))}DispatchQueue.global(qos: .userInitiated).async {self._isLoading.send(true)defer { self._isLoading.send(false) }let reader = DXInstrumentProfileReader()do {let result = try reader.readFromFile(address: self.address)guard let result else {return promise(.success(.failure(ServerError.noData)))}let instrumentsData = result.map { ipf inlet timeZone = ipf.tradingHours.sliceMultipleTimes(from: "tz=", to: ";")let data = Instrument(type: ipf.type,symbol: ipf.symbol,description: ipf.descriptionStr,timezone: timeZone.first ?? "America/New_York",priceIncrements: ipf.priceIncrements)self.dataStorage.setTradingHours(symbol: ipf.symbol, tradingHours: ipf.tradingHours)return data}self.instruments = instrumentsDatareturn promise(.success(.success(instrumentsData)))} catch {return promise(.success(.failure(ServerError.unknown)))}}}}.eraseToAnyPublisher()init(_ address: String) {self.address = address}}fileprivate extension String {func sliceMultipleTimes(from: String, to: String) -> [String] {components(separatedBy: from).dropFirst().compactMap { sub in(sub.range(of: to)?.lowerBound).flatMap { endRange inString(sub[sub.startIndex ..< endRange])}}}}