Skip to content

Commit

Permalink
add DXFeedConnect sample
Browse files Browse the repository at this point in the history
  • Loading branch information
kosyloa committed Jan 8, 2024
1 parent 0c4741a commit dbf047c
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 6 deletions.
2 changes: 2 additions & 0 deletions DXFeedFramework.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,7 @@
64ECD6812A9DDC2800B36935 /* DXInstrumentProfileReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DXInstrumentProfileReader.swift; sourceTree = "<group>"; };
64ECD6842A9DDF6200B36935 /* DXInstrumentProfileCollector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DXInstrumentProfileCollector.swift; sourceTree = "<group>"; };
64ECD6862A9DDFBE00B36935 /* DXInstrumentProfileConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DXInstrumentProfileConnection.swift; sourceTree = "<group>"; };
64F9C6C12B4BFD8F003ED014 /* DXFeedconnect.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = DXFeedconnect.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
803BAC0D29BFA50700FFAB1C /* DXFeedFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DXFeedFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
803BAC1029BFA50700FFAB1C /* DxFeedSwiftFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DxFeedSwiftFramework.h; sourceTree = "<group>"; };
803BAC1529BFA50700FFAB1C /* DXFeedFrameworkTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DXFeedFrameworkTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -1043,6 +1044,7 @@
640885C52B1F553C00E6CF88 /* DXFeedLiveIpfSample.playground */,
640885C62B1F657300E6CF88 /* ScheduleSample.playground */,
641C64AE2B344E770023CFAD /* PublishProfiles.playground */,
64F9C6C12B4BFD8F003ED014 /* DXFeedconnect.playground */,
);
path = Playgrounds;
sourceTree = "<group>";
Expand Down
8 changes: 8 additions & 0 deletions DXFeedFramework/Api/DXEndpoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,14 @@ public class DXEndpoint {
public static func builder() -> Builder {
Builder()
}

/// Returns a set of all event types supported by this endpoint. The resulting set cannot be modified.
///
/// - Throws: GraalException. Rethrows exception from Java.
public func getEventTypes() throws -> [EventCode] {
return try endpointNative.getEventTypes()
}

/// Gets ``DXFeed`` that is associated with this endpoint.
/// - Returns: ``DXFeed``
public func getFeed() -> DXFeed? {
Expand Down
2 changes: 1 addition & 1 deletion DXFeedFramework/Api/DXFeedTimeSeriesSubscription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class DXFeedTimeSeriesSubscription: DXFeedSubscription {
/// - Parameters:
/// - fromTime: fromTime the timestamp
/// - Throws: ``GraalException`` Rethrows exception from Java, ``ArgumentException/argumentNil``
func set(fromTime: Long) throws {
public func set(fromTime: Long) throws {
try native?.set(fromTime: fromTime)
}
}
19 changes: 19 additions & 0 deletions DXFeedFramework/Native/Endpoint/NativeEndpoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,25 @@ class NativeEndpoint {
return self.publisher
}

func getEventTypes() throws -> [EventCode] {
let thread = currentThread()
let list = try ErrorCheck.nativeCall(thread, dxfg_DXEndpoint_getEventTypes(
thread, endpoint))
defer {
_ = try? ErrorCheck.nativeCall(thread,
dxfg_CList_EventClazz_release(thread, list))
}
var events = [EventCode]()
if let elements = list.pointee.elements {
for index in 0..<Int(list.pointee.size) {
if let element = elements[index]?.pointee, let code = EventCode.convert(element) {
events.append(code)
}
}
}
return events
}

func addListener(_ listener: EndpointListener) throws {
removeListener()
let weakListener = WeakListener(value: listener)
Expand Down
25 changes: 25 additions & 0 deletions DXFeedFrameworkTests/EndpointTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,29 @@ final class EndpointTest: XCTestCase {
testGetInstance(role: .feed, count: 150)
testGetInstance(role: .publisher, count: 150)
}


func testGetEventTypes() throws {
let endpoint = try DXEndpoint.create().connect("demo.dxfeed.com:7300")
let feed = endpoint.getFeed()
let connectedExpectation = expectation(description: "Connected")

let stateListener: TestEndpoointStateListener? = TestEndpoointStateListener { listener in
listener.callback = { state in
if state == .connected {
print("Connected")
do {
let types = try endpoint.getEventTypes()
print(types)
} catch {
print(error)
}
connectedExpectation.fulfill()
}
}
return listener
}
endpoint.add(listener: stateListener!)
wait(for: [connectedExpectation], timeout: 1)
}
}
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,9 @@ is a simple demonstration of how to get live updates for Instrument Profiles
- [ ] DxFeedPublishProfiles is a simple demonstration of how to publish market events
- [x] [ScheduleSample](https://github.com/dxFeed/dxfeed-graal-swift-api/blob/swift/Samples/Playgrounds/ScheduleSample.playground/Contents.swift)
is a simple demonstration of how to get various scheduling information for instruments

- [x] [DXFeedconnect](https://github.com/dxFeed/dxfeed-graal-swift-api/blob/swift/Samples/Playgrounds/DXFeedconnect.playground/Contents.swift)
is a simple demonstration of how to subscribe to different events using TimeSeriesSubscription

## Current State

### Endpoint Roles
Expand Down Expand Up @@ -366,9 +368,8 @@ is a simple demonstration of how to get live updates for Instrument Profiles
- [x] [DXFeedSubscription](https://docs.dxfeed.com/dxfeed/api/com/dxfeed/api/DXFeedSubscription.html)
is a subscription for a set of symbols and event types

- [ ] [DXFeedTimeSeriesSubscription](https://docs.dxfeed.com/dxfeed/api/com/dxfeed/api/DXFeedTimeSeriesSubscription.html)
- [x] [DXFeedTimeSeriesSubscription](https://docs.dxfeed.com/dxfeed/api/com/dxfeed/api/DXFeedTimeSeriesSubscription.html)
extends `DXFeedSubscription` to conveniently subscribe to time series events for a set of symbols and event types
([Java API sample](https://github.com/devexperts/QD/blob/master/dxfeed-samples/src/main/java/com/dxfeed/sample/api/DXFeedConnect.java))

- [x] [ObservableSubscription](https://github.com/devexperts/QD/blob/master/dxfeed-api/src/main/java/com/dxfeed/api/osub/ObservableSubscription.java) is an observable set of subscription symbols for the specific event type ([Java API sample](https://github.com/devexperts/QD/blob/master/dxfeed-samples/src/main/java/com/dxfeed/sample/_simple_/PublishProfiles.java))

Expand Down
78 changes: 78 additions & 0 deletions Samples/Playgrounds/DXFeedconnect.playground/Contents.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import Cocoa
import PlaygroundSupport
import DXFeedFramework

// Empty Listener with handler
class Listener: DXEventListener, Hashable {

static func == (lhs: Listener, rhs: Listener) -> Bool {
lhs === rhs
}

func hash(into hasher: inout Hasher) {
hasher.combine("\(self):\(stringReference(self))")
}
var callback: ([MarketEvent]) -> Void = { _ in }

func receiveEvents(_ events: [MarketEvent]) {
self.callback(events)
}

init(overrides: (Listener) -> Listener) {
_ = overrides(self)
}
}

let allTypes = [Candle.self,
Trade.self,
TradeETH.self,
Quote.self,
TimeAndSale.self,
Profile.self,
Summary.self,
Greeks.self,
Underlying.self,
TheoPrice.self,
Order.self,
AnalyticOrder.self,
SpreadOrder.self,
Series.self,
OptionSale.self]

let argSymbols = ["ETH/USD:GDAX"]
let argTime: String? = nil

// To avoid release inside internal {} scope
//let endpoint = try DXEndpoint.create().connect("demo.dxfeed.com:7300")
let feed = try DXEndpoint.getInstance().connect("demo.dxfeed.com:7300").getFeed()
var feedSubscription: DXFeedSubscription? = nil
let listener = Listener { listener in
listener.callback = { events in
events.forEach { event in
print(event.toString())
}
}
return listener
}

if let argTime = argTime, let time: Long = try DXTimeFormat.defaultTimeFormat?.parse(argTime) {
let types: [ITimeSeriesEvent.Type] = allTypes.compactMap({ event in
event as? ITimeSeriesEvent.Type
})
let subscription = try feed?.createTimeSeriesSubscription(types)
try subscription?.add(listener: listener)
try subscription?.set(fromTime: time)
try subscription?.addSymbols(argSymbols)
feedSubscription = subscription
} else {
let subscription = try feed?.createSubscription(allTypes)
try subscription?.add(listener: listener)
try subscription?.addSymbols(argSymbols)
feedSubscription = subscription
}

// infinity execution
PlaygroundPage.current.needsIndefiniteExecution = true

// to finish execution run this line
PlaygroundPage.current.finishExecution()
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='macos' buildActiveScheme='true' importAppTypes='true'>
<timeline fileName='timeline.xctimeline'/>
</playground>
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import UIKit
import PlaygroundSupport
import DXFeedFramework

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios' buildActiveScheme='true' importAppTypes='true'>
<playground version='5.0' target-platform='macos' buildActiveScheme='true' importAppTypes='true'>
<timeline fileName='timeline.xctimeline'/>
</playground>

0 comments on commit dbf047c

Please sign in to comment.