From ded428cfde5328f71a109e863b4ae474d09069b8 Mon Sep 17 00:00:00 2001 From: AKosylo Date: Thu, 12 Oct 2023 12:41:20 +0200 Subject: [PATCH] Order Mappers --- DXFeedFramework.xcodeproj/project.pbxproj | 28 +++++++++ .../Events/Market/AnalyticOrder.swift | 3 + .../Extensions/MarketEvent+Access.swift | 13 ++++ .../Events/Market/Extra/OrderBase.swift | 4 +- .../Events/Market/Extra/OrderSource.swift | 1 + DXFeedFramework/Events/Market/Order.swift | 3 + .../Events/Market/SpreadOrder.swift | 4 +- .../Native/Events/EventMapper.swift | 5 +- .../Events/Markets/AnalyticOrder+Ext.swift | 37 +++++++++++ .../Events/Markets/AnalyticOrderMapper.swift | 57 +++++++++++++++++ .../Native/Events/Markets/Order+Ext.swift | 34 ++++++++++ .../Native/Events/Markets/OrderMapper.swift | 54 ++++++++++++++++ .../Events/Markets/SpreadOrder+Ext.swift | 34 ++++++++++ .../Events/Markets/SpreadOrderMapper.swift | 54 ++++++++++++++++ DXFeedFrameworkTests/FeedTest.swift | 5 +- DXFeedFrameworkTests/OrderSourceTest.swift | 10 +++ DXFeedFrameworkTests/OrderTest.swift | 63 +++++++++++++++++++ 17 files changed, 404 insertions(+), 5 deletions(-) create mode 100644 DXFeedFramework/Native/Events/Markets/AnalyticOrder+Ext.swift create mode 100644 DXFeedFramework/Native/Events/Markets/AnalyticOrderMapper.swift create mode 100644 DXFeedFramework/Native/Events/Markets/Order+Ext.swift create mode 100644 DXFeedFramework/Native/Events/Markets/OrderMapper.swift create mode 100644 DXFeedFramework/Native/Events/Markets/SpreadOrder+Ext.swift create mode 100644 DXFeedFramework/Native/Events/Markets/SpreadOrderMapper.swift create mode 100644 DXFeedFrameworkTests/OrderTest.swift diff --git a/DXFeedFramework.xcodeproj/project.pbxproj b/DXFeedFramework.xcodeproj/project.pbxproj index a077358f9..07de52ece 100644 --- a/DXFeedFramework.xcodeproj/project.pbxproj +++ b/DXFeedFramework.xcodeproj/project.pbxproj @@ -281,6 +281,13 @@ 64BDDB222AD6CC9A00694210 /* SpreadOrder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB212AD6CC9A00694210 /* SpreadOrder.swift */; }; 64BDDB242AD6F10200694210 /* Scope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB232AD6F10200694210 /* Scope.swift */; }; 64BDDB262AD6F6B500694210 /* IcebergType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB252AD6F6B500694210 /* IcebergType.swift */; }; + 64BDDB282AD7D8D300694210 /* Order+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB272AD7D8D300694210 /* Order+Ext.swift */; }; + 64BDDB2A2AD7D9C700694210 /* SpreadOrder+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB292AD7D9C700694210 /* SpreadOrder+Ext.swift */; }; + 64BDDB2C2AD7DB9B00694210 /* AnalyticOrder+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB2B2AD7DB9B00694210 /* AnalyticOrder+Ext.swift */; }; + 64BDDB2E2AD7DC5E00694210 /* OrderMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB2D2AD7DC5E00694210 /* OrderMapper.swift */; }; + 64BDDB312AD7E5A600694210 /* AnalyticOrderMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB2F2AD7E5A500694210 /* AnalyticOrderMapper.swift */; }; + 64BDDB322AD7E5A600694210 /* SpreadOrderMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB302AD7E5A600694210 /* SpreadOrderMapper.swift */; }; + 64BDDB342AD7F1FE00694210 /* OrderTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB332AD7F1FE00694210 /* OrderTest.swift */; }; 64C771F22A94A224009868C2 /* Character+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C771F12A94A224009868C2 /* Character+Ext.swift */; }; 64C771F42A94A86E009868C2 /* Side.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C771F32A94A86E009868C2 /* Side.swift */; }; 64C771F62A94ADDA009868C2 /* Direction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C771F52A94ADDA009868C2 /* Direction.swift */; }; @@ -725,6 +732,13 @@ 64BDDB212AD6CC9A00694210 /* SpreadOrder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpreadOrder.swift; sourceTree = ""; }; 64BDDB232AD6F10200694210 /* Scope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scope.swift; sourceTree = ""; }; 64BDDB252AD6F6B500694210 /* IcebergType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IcebergType.swift; sourceTree = ""; }; + 64BDDB272AD7D8D300694210 /* Order+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Order+Ext.swift"; sourceTree = ""; }; + 64BDDB292AD7D9C700694210 /* SpreadOrder+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SpreadOrder+Ext.swift"; sourceTree = ""; }; + 64BDDB2B2AD7DB9B00694210 /* AnalyticOrder+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AnalyticOrder+Ext.swift"; sourceTree = ""; }; + 64BDDB2D2AD7DC5E00694210 /* OrderMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderMapper.swift; sourceTree = ""; }; + 64BDDB2F2AD7E5A500694210 /* AnalyticOrderMapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnalyticOrderMapper.swift; sourceTree = ""; }; + 64BDDB302AD7E5A600694210 /* SpreadOrderMapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpreadOrderMapper.swift; sourceTree = ""; }; + 64BDDB332AD7F1FE00694210 /* OrderTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderTest.swift; sourceTree = ""; }; 64C771F12A94A224009868C2 /* Character+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Character+Ext.swift"; sourceTree = ""; }; 64C771F32A94A86E009868C2 /* Side.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Side.swift; sourceTree = ""; }; 64C771F52A94ADDA009868C2 /* Direction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Direction.swift; sourceTree = ""; }; @@ -987,6 +1001,12 @@ 6486B9702AD0445E00D8D5FA /* UnderlyingMapper.swift */, 6486B9742AD0493F00D8D5FA /* TheoPrice+Ext.swift */, 6486B9762AD04C5800D8D5FA /* TheoPriceMapper.swift */, + 64BDDB272AD7D8D300694210 /* Order+Ext.swift */, + 64BDDB2D2AD7DC5E00694210 /* OrderMapper.swift */, + 64BDDB292AD7D9C700694210 /* SpreadOrder+Ext.swift */, + 64BDDB302AD7E5A600694210 /* SpreadOrderMapper.swift */, + 64BDDB2B2AD7DB9B00694210 /* AnalyticOrder+Ext.swift */, + 64BDDB2F2AD7E5A500694210 /* AnalyticOrderMapper.swift */, ); path = Markets; sourceTree = ""; @@ -1391,6 +1411,7 @@ 64098F662ACEB6F70020D741 /* DXConnectionStateTests.swift */, 6486B95C2AD0287E00D8D5FA /* DateTests.swift */, 649282EC2AD593F3008F0F04 /* OrderSourceTest.swift */, + 64BDDB332AD7F1FE00694210 /* OrderTest.swift */, ); path = DXFeedFrameworkTests; sourceTree = ""; @@ -2060,6 +2081,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 64BDDB322AD7E5A600694210 /* SpreadOrderMapper.swift in Sources */, 64ACBCE32A289A0700032C53 /* TimeSeriesSubscriptionSymbol.swift in Sources */, 645A34952A937C7200709F29 /* BinaryInteger+Ext.swift in Sources */, 64BA92652A306E0200BE26A0 /* Trade.swift in Sources */, @@ -2073,6 +2095,7 @@ 6469F8C22A3B169A00846831 /* MathUtil.swift in Sources */, 80FC415929C8EE8B00E6B611 /* DXEndpoint.swift in Sources */, 64C771F62A94ADDA009868C2 /* Direction.swift in Sources */, + 64BDDB312AD7E5A600694210 /* AnalyticOrderMapper.swift in Sources */, 640C3FDC2A618B2000555161 /* MarketEventSymbols.swift in Sources */, 642BE4D42A2F5D730052340A /* TimeAndSale+Ext.swift in Sources */, 64ACBCD92A279F7900032C53 /* DXEventListener.swift in Sources */, @@ -2095,6 +2118,7 @@ 642BE4CC2A2E1DB70052340A /* Mapper.swift in Sources */, 64104FC72A2613BC00D1FC41 /* ConcurrentArray.swift in Sources */, 6498E6B22AB1D41A0093A065 /* DXSchedule.swift in Sources */, + 64BDDB2C2AD7DB9B00694210 /* AnalyticOrder+Ext.swift in Sources */, 646407572AA0C44D006FF769 /* NativeInstrumentProfileCollector.swift in Sources */, 6486B9732AD045C800D8D5FA /* TheoPrice.swift in Sources */, 64ACBCDF2A2897EA00032C53 /* String+Symbol.swift in Sources */, @@ -2127,6 +2151,7 @@ 8088D76529C0FBCE00F240CB /* ThreadManager.swift in Sources */, 64DA26BE2AA20EDB005B1757 /* DXInstrumentProfileConnectionObserver.swift in Sources */, 64656F732A1D0A84006A0B19 /* EndpointListener.swift in Sources */, + 64BDDB282AD7D8D300694210 /* Order+Ext.swift in Sources */, 6486B9582AD00BDC00D8D5FA /* Summary.swift in Sources */, 64104FCC2A2629D800D1FC41 /* NativeSubscription.swift in Sources */, 64C772012A975102009868C2 /* Reference+Util.swift in Sources */, @@ -2163,6 +2188,7 @@ 641BCBC12A21077800FE23C2 /* EventCode.swift in Sources */, 64ACBCE82A28CF9700032C53 /* IndexedEventSubscriptionSymbol.swift in Sources */, 649F48882A615BED0016FDD1 /* CandleType.swift in Sources */, + 64BDDB2E2AD7DC5E00694210 /* OrderMapper.swift in Sources */, 6447A5E52A8F736E00739CCF /* TimeUtil.swift in Sources */, 64C771FC2A94D7E9009868C2 /* TradingStatus.swift in Sources */, 642BE4D22A2F5D230052340A /* TimeAndSale.swift in Sources */, @@ -2202,6 +2228,7 @@ 641AC1A92A61AE4000EF6D6C /* DXAliases.swift in Sources */, 64BA92632A306BBD00BE26A0 /* ProfileMapper.swift in Sources */, 64AAF0592A83EA0000E8942B /* Double+Ext.swift in Sources */, + 64BDDB2A2AD7D9C700694210 /* SpreadOrder+Ext.swift in Sources */, 8088D77529C3A61000F240CB /* ErrorCheck.swift in Sources */, 6486B9672AD0390800D8D5FA /* GreeksMapper.swift in Sources */, 64AAF0572A82A3FC00E8942B /* ICandleSymbolProperty.swift in Sources */, @@ -2219,6 +2246,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 64BDDB342AD7F1FE00694210 /* OrderTest.swift in Sources */, 6426C8912A531AAE00236784 /* EndpointTest.swift in Sources */, 6401A5162A582141009BA686 /* SystemPropertyTest.swift in Sources */, 64D0DBE82A29FF4B00710605 /* EventsTest.swift in Sources */, diff --git a/DXFeedFramework/Events/Market/AnalyticOrder.swift b/DXFeedFramework/Events/Market/AnalyticOrder.swift index 5649767df..ff5b08503 100644 --- a/DXFeedFramework/Events/Market/AnalyticOrder.swift +++ b/DXFeedFramework/Events/Market/AnalyticOrder.swift @@ -14,6 +14,9 @@ import Foundation /// /// [For more details see](https://docs.dxfeed.com/dxfeed/api/com/dxfeed/event/market/AnalyticOrder.html) public class AnalyticOrder: OrderBase { + public override var type: EventCode { + return .analyticOrder + } /* * Analytic flags property has several significant bits that are packed into an integer in the following way: * 31...2 1 0 diff --git a/DXFeedFramework/Events/Market/Extensions/MarketEvent+Access.swift b/DXFeedFramework/Events/Market/Extensions/MarketEvent+Access.swift index 19d588549..12009b62c 100644 --- a/DXFeedFramework/Events/Market/Extensions/MarketEvent+Access.swift +++ b/DXFeedFramework/Events/Market/Extensions/MarketEvent+Access.swift @@ -50,4 +50,17 @@ extension MarketEvent { public var theoPrice: TheoPrice { return (self as? TheoPrice)! } + /// Use only for event.type is ``EventCode/order`` + public var order: Order { + return (self as? Order)! + } + /// Use only for event.type is ``EventCode/spreadOrder`` + public var spreadOrder: SpreadOrder { + return (self as? SpreadOrder)! + } + /// Use only for event.type is ``EventCode/analyticOrder`` + public var analyticOrder: AnalyticOrder { + return (self as? AnalyticOrder)! + } + } diff --git a/DXFeedFramework/Events/Market/Extra/OrderBase.swift b/DXFeedFramework/Events/Market/Extra/OrderBase.swift index 3901ae186..1f8e90689 100644 --- a/DXFeedFramework/Events/Market/Extra/OrderBase.swift +++ b/DXFeedFramework/Events/Market/Extra/OrderBase.swift @@ -9,7 +9,7 @@ import Foundation public class OrderBase: MarketEvent, IIndexedEvent, CustomStringConvertible { - public var type: EventCode = .orderBase + public private(set) var type: EventCode = .orderBase public var eventSource: IndexedEventSource { get { @@ -101,7 +101,7 @@ public class OrderBase: MarketEvent, IIndexedEvent, CustomStringConvertible { /// Gets or sets order ID if available. /// Some actions ``OrderAction/trade``, ``OrderAction/bust`` /// have no order ID since they are not related to any order in Order book. - public let orderId: Int64 = 0 + public var orderId: Int64 = 0 /// Gets or sets order ID if available. /// Returns auxiliary order ID if available:. /// ``OrderAction/new`` ID of the order replaced by this new order. diff --git a/DXFeedFramework/Events/Market/Extra/OrderSource.swift b/DXFeedFramework/Events/Market/Extra/OrderSource.swift index 2b61871e5..bcff48da5 100644 --- a/DXFeedFramework/Events/Market/Extra/OrderSource.swift +++ b/DXFeedFramework/Events/Market/Extra/OrderSource.swift @@ -160,6 +160,7 @@ public class OrderSource: IndexedEventSource { /// Members Exchange. Record for price level book. public static let memx = try? OrderSource("memx", pubOrder) + override init(_ identifier: Int, _ name: String) { self.pubFlags = 0 self.isBuiltin = false diff --git a/DXFeedFramework/Events/Market/Order.swift b/DXFeedFramework/Events/Market/Order.swift index 7637819fb..8927e29df 100644 --- a/DXFeedFramework/Events/Market/Order.swift +++ b/DXFeedFramework/Events/Market/Order.swift @@ -15,6 +15,9 @@ import Foundation /// /// [For more details see](https://docs.dxfeed.com/dxfeed/api/com/dxfeed/event/market/Order.html) public class Order: OrderBase { + public override var type: EventCode { + return .order + } /// Gets or sets market maker or other aggregate identifier of this order. /// This value is defined for ``Scope/aggregate`` and ``Scope/order`` orders. public var marketMaker: String? diff --git a/DXFeedFramework/Events/Market/SpreadOrder.swift b/DXFeedFramework/Events/Market/SpreadOrder.swift index 8d1a47d93..c37c0d072 100644 --- a/DXFeedFramework/Events/Market/SpreadOrder.swift +++ b/DXFeedFramework/Events/Market/SpreadOrder.swift @@ -22,7 +22,9 @@ import Foundation /// /// [For more details see](https://docs.dxfeed.com/dxfeed/api/com/dxfeed/event/market/SpreadOrder.html) public class SpreadOrder: OrderBase { - + public override var type: EventCode { + return .spreadOrder + } /// Gets or sets spread symbol of this event. public var spreadSymbol: String? diff --git a/DXFeedFramework/Native/Events/EventMapper.swift b/DXFeedFramework/Native/Events/EventMapper.swift index f1cae595f..854251405 100644 --- a/DXFeedFramework/Native/Events/EventMapper.swift +++ b/DXFeedFramework/Native/Events/EventMapper.swift @@ -25,7 +25,10 @@ class EventMapper: Mapper { .summary: SummaryMapper(), .greeks: GreeksMapper(), .underlying: UnderlyingMapper(), - .theoPrice: TheoPriceMapper()] + .theoPrice: TheoPriceMapper(), + .order: OrderMapper(), + .analyticOrder: AnalyticOrderMapper(), + .spreadOrder: SpreadOrderMapper()] func fromNative(native: UnsafeMutablePointer) throws -> MarketEvent? { let code = try EnumUtil.valueOf(value: EventCode.convert(native.pointee.clazz)) diff --git a/DXFeedFramework/Native/Events/Markets/AnalyticOrder+Ext.swift b/DXFeedFramework/Native/Events/Markets/AnalyticOrder+Ext.swift new file mode 100644 index 000000000..429ba783f --- /dev/null +++ b/DXFeedFramework/Native/Events/Markets/AnalyticOrder+Ext.swift @@ -0,0 +1,37 @@ +// +// AnalyticOrder+Ext.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 12.10.23. +// + +import Foundation +@_implementationOnly import graal_api + +extension AnalyticOrder { + convenience init(native: dxfg_analytic_order_t) { + self.init(String(pointee: native.order_base.order_base.market_event.event_symbol)) + + self.eventTime = native.order_base.order_base.market_event.event_time + self.eventFlags = native.order_base.order_base.event_flags + self.index = native.order_base.order_base.index + self.timeSequence = native.order_base.order_base.time_sequence + self.timeNanoPart = native.order_base.order_base.time_nano_part + self.actionTime = native.order_base.order_base.action_time + self.orderId = native.order_base.order_base.order_id + self.auxOrderId = native.order_base.order_base.aux_order_id + self.price = native.order_base.order_base.price + self.size = native.order_base.order_base.size + self.executedSize = native.order_base.order_base.executed_size + self.count = native.order_base.order_base.count + self.flags = native.order_base.order_base.flags + self.tradeId = native.order_base.order_base.trade_id + self.tradePrice = native.order_base.order_base.trade_price + self.tradeSize = native.order_base.order_base.trade_size + + self.icebergPeakSize = native.iceberg_peak_size + self.icebergHiddenSize = native.iceberg_hidden_size + self.icebergExecutedSize = native.iceberg_executed_size + self.icebergFlags = native.iceberg_flags + } +} diff --git a/DXFeedFramework/Native/Events/Markets/AnalyticOrderMapper.swift b/DXFeedFramework/Native/Events/Markets/AnalyticOrderMapper.swift new file mode 100644 index 000000000..54f3d0b8d --- /dev/null +++ b/DXFeedFramework/Native/Events/Markets/AnalyticOrderMapper.swift @@ -0,0 +1,57 @@ +// +// AnalyticOrderMapper.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 12.10.23. +// + +import Foundation +@_implementationOnly import graal_api + +class AnalyticOrderMapper: Mapper { + let type = dxfg_analytic_order_t.self + + func fromNative(native: UnsafeMutablePointer) -> MarketEvent? { + let event = native.withMemoryRebound(to: type, capacity: 1) { native in + return AnalyticOrder(native: native.pointee) + } + return event + } + + func toNative(event: MarketEvent) -> UnsafeMutablePointer? { + let pointer = UnsafeMutablePointer.allocate(capacity: 1) + var pointee = pointer.pointee + pointee.order_base.order_base.market_event.event_symbol = event.eventSymbol.toCStringRef() + pointee.order_base.order_base.market_event.event_time = event.eventTime + + let order = event.analyticOrder + + pointee.order_base.order_base.market_event.event_time = order.eventTime + pointee.order_base.order_base.event_flags = order.eventFlags + pointee.order_base.order_base.index = order.index + pointee.order_base.order_base.time_sequence = order.timeSequence + pointee.order_base.order_base.time_nano_part = order.timeNanoPart + pointee.order_base.order_base.action_time = order.actionTime + pointee.order_base.order_base.order_id = order.orderId + pointee.order_base.order_base.aux_order_id = order.auxOrderId + pointee.order_base.order_base.price = order.price + pointee.order_base.order_base.size = order.size + pointee.order_base.order_base.executed_size = order.executedSize + pointee.order_base.order_base.count = order.count + pointee.order_base.order_base.flags = order.flags + pointee.order_base.order_base.trade_id = order.tradeId + pointee.order_base.order_base.trade_price = order.tradePrice + pointee.order_base.order_base.trade_size = order.tradeSize + + pointee.iceberg_peak_size = order.icebergPeakSize + pointee.iceberg_hidden_size = order.icebergHiddenSize + pointee.iceberg_executed_size = order.icebergExecutedSize + pointee.iceberg_flags = order.icebergFlags + + let eventType = pointer.withMemoryRebound(to: dxfg_event_type_t.self, capacity: 1) { pointer in + pointer.pointee.clazz = DXFG_EVENT_ANALYTIC_ORDER + return pointer + } + return eventType + } +} diff --git a/DXFeedFramework/Native/Events/Markets/Order+Ext.swift b/DXFeedFramework/Native/Events/Markets/Order+Ext.swift new file mode 100644 index 000000000..ec6a82a55 --- /dev/null +++ b/DXFeedFramework/Native/Events/Markets/Order+Ext.swift @@ -0,0 +1,34 @@ +// +// Order+Ext.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 12.10.23. +// + +import Foundation +@_implementationOnly import graal_api + +extension Order { + convenience init(native: dxfg_order_t) { + self.init(String(pointee: native.order_base.market_event.event_symbol)) + + self.eventTime = native.order_base.market_event.event_time + self.eventFlags = native.order_base.event_flags + self.index = native.order_base.index + self.timeSequence = native.order_base.time_sequence + self.timeNanoPart = native.order_base.time_nano_part + self.actionTime = native.order_base.action_time + self.orderId = native.order_base.order_id + self.auxOrderId = native.order_base.aux_order_id + self.price = native.order_base.price + self.size = native.order_base.size + self.executedSize = native.order_base.executed_size + self.count = native.order_base.count + self.flags = native.order_base.flags + self.tradeId = native.order_base.trade_id + self.tradePrice = native.order_base.trade_price + self.tradeSize = native.order_base.trade_size + + self.marketMaker = String(pointee: native.market_maker) + } +} diff --git a/DXFeedFramework/Native/Events/Markets/OrderMapper.swift b/DXFeedFramework/Native/Events/Markets/OrderMapper.swift new file mode 100644 index 000000000..2d3642a50 --- /dev/null +++ b/DXFeedFramework/Native/Events/Markets/OrderMapper.swift @@ -0,0 +1,54 @@ +// +// OrderMapper.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 12.10.23. +// + +import Foundation +@_implementationOnly import graal_api + +class OrderMapper: Mapper { + let type = dxfg_order_t.self + + func fromNative(native: UnsafeMutablePointer) -> MarketEvent? { + let event = native.withMemoryRebound(to: type, capacity: 1) { native in + return Order(native: native.pointee) + } + return event + } + + func toNative(event: MarketEvent) -> UnsafeMutablePointer? { + let pointer = UnsafeMutablePointer.allocate(capacity: 1) + var pointee = pointer.pointee + pointee.order_base.market_event.event_symbol = event.eventSymbol.toCStringRef() + pointee.order_base.market_event.event_time = event.eventTime + + let order = event.order + + pointee.order_base.market_event.event_time = order.eventTime + pointee.order_base.event_flags = order.eventFlags + pointee.order_base.index = order.index + pointee.order_base.time_sequence = order.timeSequence + pointee.order_base.time_nano_part = order.timeNanoPart + pointee.order_base.action_time = order.actionTime + pointee.order_base.order_id = order.orderId + pointee.order_base.aux_order_id = order.auxOrderId + pointee.order_base.price = order.price + pointee.order_base.size = order.size + pointee.order_base.executed_size = order.executedSize + pointee.order_base.count = order.count + pointee.order_base.flags = order.flags + pointee.order_base.trade_id = order.tradeId + pointee.order_base.trade_price = order.tradePrice + pointee.order_base.trade_size = order.tradeSize + + pointee.market_maker = order.marketMaker?.toCStringRef() + + let eventType = pointer.withMemoryRebound(to: dxfg_event_type_t.self, capacity: 1) { pointer in + pointer.pointee.clazz = DXFG_EVENT_ORDER + return pointer + } + return eventType + } +} diff --git a/DXFeedFramework/Native/Events/Markets/SpreadOrder+Ext.swift b/DXFeedFramework/Native/Events/Markets/SpreadOrder+Ext.swift new file mode 100644 index 000000000..1390e9435 --- /dev/null +++ b/DXFeedFramework/Native/Events/Markets/SpreadOrder+Ext.swift @@ -0,0 +1,34 @@ +// +// SpreadOrder+Ext.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 12.10.23. +// + +import Foundation +@_implementationOnly import graal_api + +extension SpreadOrder { + convenience init(native: dxfg_spread_order_t) { + self.init(String(pointee: native.order_base.market_event.event_symbol)) + + self.eventTime = native.order_base.market_event.event_time + self.eventFlags = native.order_base.event_flags + self.index = native.order_base.index + self.timeSequence = native.order_base.time_sequence + self.timeNanoPart = native.order_base.time_nano_part + self.actionTime = native.order_base.action_time + self.orderId = native.order_base.order_id + self.auxOrderId = native.order_base.aux_order_id + self.price = native.order_base.price + self.size = native.order_base.size + self.executedSize = native.order_base.executed_size + self.count = native.order_base.count + self.flags = native.order_base.flags + self.tradeId = native.order_base.trade_id + self.tradePrice = native.order_base.trade_price + self.tradeSize = native.order_base.trade_size + + self.spreadSymbol = String(pointee: native.spread_symbol) + } +} diff --git a/DXFeedFramework/Native/Events/Markets/SpreadOrderMapper.swift b/DXFeedFramework/Native/Events/Markets/SpreadOrderMapper.swift new file mode 100644 index 000000000..abb744777 --- /dev/null +++ b/DXFeedFramework/Native/Events/Markets/SpreadOrderMapper.swift @@ -0,0 +1,54 @@ +// +// SpreadOrderMapper.swift +// DXFeedFramework +// +// Created by Aleksey Kosylo on 12.10.23. +// + +import Foundation +@_implementationOnly import graal_api + +class SpreadOrderMapper: Mapper { + let type = dxfg_spread_order_t.self + + func fromNative(native: UnsafeMutablePointer) -> MarketEvent? { + let event = native.withMemoryRebound(to: type, capacity: 1) { native in + return SpreadOrder(native: native.pointee) + } + return event + } + + func toNative(event: MarketEvent) -> UnsafeMutablePointer? { + let pointer = UnsafeMutablePointer.allocate(capacity: 1) + var pointee = pointer.pointee + pointee.order_base.market_event.event_symbol = event.eventSymbol.toCStringRef() + pointee.order_base.market_event.event_time = event.eventTime + + let order = event.spreadOrder + + pointee.order_base.market_event.event_time = order.eventTime + pointee.order_base.event_flags = order.eventFlags + pointee.order_base.index = order.index + pointee.order_base.time_sequence = order.timeSequence + pointee.order_base.time_nano_part = order.timeNanoPart + pointee.order_base.action_time = order.actionTime + pointee.order_base.order_id = order.orderId + pointee.order_base.aux_order_id = order.auxOrderId + pointee.order_base.price = order.price + pointee.order_base.size = order.size + pointee.order_base.executed_size = order.executedSize + pointee.order_base.count = order.count + pointee.order_base.flags = order.flags + pointee.order_base.trade_id = order.tradeId + pointee.order_base.trade_price = order.tradePrice + pointee.order_base.trade_size = order.tradeSize + + pointee.spread_symbol = order.spreadSymbol?.toCStringRef() + + let eventType = pointer.withMemoryRebound(to: dxfg_event_type_t.self, capacity: 1) { pointer in + pointer.pointee.clazz = DXFG_EVENT_SPREAD_ORDER + return pointer + } + return eventType + } +} diff --git a/DXFeedFrameworkTests/FeedTest.swift b/DXFeedFrameworkTests/FeedTest.swift index 6e64af147..8f638c38f 100644 --- a/DXFeedFrameworkTests/FeedTest.swift +++ b/DXFeedFrameworkTests/FeedTest.swift @@ -101,7 +101,7 @@ final class FeedTest: XCTestCase { try waitingEvent(code: .candle) } - fileprivate static func checkType(_ code: EventCode, _ event: MarketEvent?) -> Bool { + static func checkType(_ code: EventCode, _ event: MarketEvent?) -> Bool { switch code { case .timeAndSale: return event is TimeAndSale @@ -132,10 +132,13 @@ final class FeedTest: XCTestCase { case .orderBase: break case .order: + return event is Order break case .analyticOrder: + return event is AnalyticOrder break case .spreadOrder: + return event is SpreadOrder break case .series: break diff --git a/DXFeedFrameworkTests/OrderSourceTest.swift b/DXFeedFrameworkTests/OrderSourceTest.swift index 1b6bc4646..0f3fc5d60 100644 --- a/DXFeedFrameworkTests/OrderSourceTest.swift +++ b/DXFeedFrameworkTests/OrderSourceTest.swift @@ -80,4 +80,14 @@ final class OrderSourceTest: XCTestCase { XCTAssert(false, "undefined error \(error)") } } + + func testVAlueOf() throws { + do { + let source1 = OrderSource.compsoiteBid + + let source = try OrderSource.valueOf(identifier: 1) + } catch { + print(error) + } + } } diff --git a/DXFeedFrameworkTests/OrderTest.swift b/DXFeedFrameworkTests/OrderTest.swift new file mode 100644 index 000000000..fb2f62faf --- /dev/null +++ b/DXFeedFrameworkTests/OrderTest.swift @@ -0,0 +1,63 @@ +// +// OrderTest.swift +// DXFeedFrameworkTests +// +// Created by Aleksey Kosylo on 12.10.23. +// + +import XCTest +@testable import DXFeedFramework + +final class OrderTest: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testOrder() throws { + try receiveOrder(code: .order) + } + + func testAnalyticOrder() throws { + try receiveOrder(code: .analyticOrder) + } + + func testSpreadOrder() throws { + try receiveOrder(code: .spreadOrder) + } + + private func receiveOrder(code: EventCode) throws { + let endpoint = try DXEndpoint.builder().withRole(.feed).withProperty("test", "value").build() + try endpoint.connect("demo.dxfeed.com:7300") + let subscription = try endpoint.getFeed()?.createSubscription(code) + let receivedEventExp = expectation(description: "Received events \(code)") + receivedEventExp.assertForOverFulfill = false + let listener = AnonymousClass { anonymCl in + anonymCl.callback = { events in + events.forEach { event in + if event.type == .order { + print(event.order.toString()) + } + + } + if events.count > 0 { + let event = events.first + if FeedTest.checkType(code, event) { + if event?.type == .order { + print(event?.order.toString()) + } +// receivedEventExp.fulfill() + } + } + } + return anonymCl + } + try subscription?.add(observer: listener) + try subscription?.addSymbols(["IBM"]) + wait(for: [receivedEventExp], timeout: 10) + } +}