Skip to content

Commit

Permalink
OrderSource: WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
kosyloa committed Oct 11, 2023
1 parent 342a921 commit 1621131
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 30 deletions.
7 changes: 3 additions & 4 deletions DXFeedFramework/Events/Market/Extra/OrderBase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation

class OrderBase: MarketEvent, IIndexedEvent, CustomStringConvertible {
var eventSource: IndexedEventSource = .defaultSource

var type: EventCode = .orderBase

// var eventSource: IndexedEventSource {
Expand Down Expand Up @@ -113,7 +113,7 @@ class OrderBase: MarketEvent, IIndexedEvent, CustomStringConvertible {
public var tradePrice: Double = .nan
/// Gets or sets trade size for events containing trade-related action.
public var tradeSize: Double = .nan

init(_ eventSymbol: String) {
self.eventSymbol = eventSymbol
}
Expand All @@ -140,9 +140,8 @@ tradePrice: \(tradePrice), \
tradeSize: \(tradeSize)
"""
}

}

}

extension OrderBase {
/// Gets a value indicating whether this order has some size
Expand Down
21 changes: 6 additions & 15 deletions DXFeedFramework/Events/Market/Extra/OrderSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ public class OrderSource: IndexedEventSource {
static private let sourcesByName = ConcurrentDict<String, OrderSource>()
private let sourcesByIdCache = NSCache<AnyObject, OrderSource>()

private override init(identifier: Int, name: String) {
override init(identifier: Int, name: String) {
self.pubFlags = 0
self.isBuiltin = false
super.init(identifier: identifier, name: name)
}

private init(identifier: Int, name: String, pubFlags: Int) throws {
init(identifier: Int, name: String, pubFlags: Int) throws {
self.pubFlags = pubFlags
self.isBuiltin = true
super.init(identifier: identifier, name: name)
Expand Down Expand Up @@ -74,7 +74,7 @@ public class OrderSource: IndexedEventSource {
}

/// Determines whether specified source identifier refers to special order source.
///Special order sources are used for wrapping non-order events into order events.
/// Special order sources are used for wrapping non-order events into order events.
internal static func isSpecialSourceId(sourceId: Int) -> Bool {
return sourceId >= 1 && sourceId <= 6
}
Expand All @@ -88,7 +88,7 @@ public class OrderSource: IndexedEventSource {
for index in 0..<count {
let char = name[index]
try OrderSource.check(char: char)
sourceId = (sourceId << 8) | Int(char.first?.unicodeScalars.first?.value ?? 0)
sourceId = (sourceId << 8) | Int(char.first?.unicodeScalars.first?.value ?? 0)
}

return sourceId
Expand Down Expand Up @@ -124,13 +124,9 @@ public class OrderSource: IndexedEventSource {
/// Returns order source for the specified source identifier.
/// - Throws: ``ArgumentException/exception(_:)``. Rethrows exception from Java.
public static func valueOf(identifier: Int) throws -> OrderSource {
var source: OrderSource
if let source = sourcesById[identifier] {
return source
} else {
return try OrderSource.sourcesById.tryGetValue(key: identifier) {
let name = try decodeName(identifier: identifier)
let source = OrderSource(identifier: identifier, name: name)
sourcesById[identifier] = source
return source
}
}
Expand All @@ -139,16 +135,11 @@ public class OrderSource: IndexedEventSource {
/// The name must be either predefined, or contain at most 4 alphanumeric characters.
/// - Throws: ``ArgumentException/exception(_:)``. Rethrows exception from Java.
public static func valueOf(name: String) throws -> OrderSource {
var source: OrderSource
if let source = sourcesByName[name] {
return source
} else {
return try OrderSource.sourcesByName.tryGetValue(key: name) {
let identifier = try composeId(name: name)
let source = OrderSource(identifier: identifier, name: name)
sourcesByName[name] = source
return source
}

}

}
2 changes: 1 addition & 1 deletion DXFeedFramework/Events/Market/Extra/PriceType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public enum PriceType: DXPriceType, CaseIterable {
EnumUtil.createEnumBitMaskArrayByValue(defaultValue: .regular,
allCases: PriceType.allCases)
}()

public static func valueOf(_ value: Int) -> PriceType {
return PriceType.types[value]
}
Expand Down
4 changes: 2 additions & 2 deletions DXFeedFramework/Events/Market/Greeks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public class Greeks: MarketEvent, ITimeSeriesEvent, ILastingEvent, CustomStringC
public init(_ eventSymbol: String) {
self.eventSymbol = eventSymbol
}

public var description: String {
"""
DXFG_GREEKS_T \
Expand Down Expand Up @@ -96,7 +96,7 @@ extension Greeks {
(Long(TimeUtil.getMillisFromTime(newValue)) << 22) |
Int64(getSequence())
}
}
}
/// Gets sequence number of this quote to distinguish events that have the same ``time``.
/// This sequence number does not have to be unique and
/// does not need to be sequential. Sequence can range from 0 to ``MarketEventConst/maxSequence``.
Expand Down
2 changes: 1 addition & 1 deletion DXFeedFramework/Native/Events/Markets/TheoPrice+Ext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extension TheoPrice {
self.eventTime = native.market_event.event_time
self.eventFlags = native.event_flags
self.index = native.index

self.price = native.price
self.underlyingPrice = native.underlying_price
self.delta = native.delta
Expand Down
18 changes: 12 additions & 6 deletions DXFeedFramework/Utils/ConcurrentDict.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,20 @@ class ConcurrentDict<Key: Hashable, Value>: CustomStringConvertible {
}

public func tryInsert(key: Key, value: Value) -> Bool {
var result = true
writer {
if $0[key] != nil {
result = false
return accessQueue.sync {
return set.updateValue(value, forKey: key) == nil
}
}

public func tryGetValue(key: Key, generator: () throws -> Value) throws -> Value {
return try accessQueue.sync {
if let existingValue = set[key] {
return existingValue
}
$0[key] = value
let newValue = try generator()
set[key] = newValue
return newValue
}
return result
}

public func reader<U>(_ block: ([Key: Value]) throws -> U) rethrows -> U {
Expand Down
36 changes: 35 additions & 1 deletion DXFeedFrameworkTests/OrderSourceTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ final class OrderSourceTest: XCTestCase {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}


func testIsSpecialSource() throws {
XCTAssert(OrderSource.isSpecialSourceId(sourceId: 1))
XCTAssert(!OrderSource.isSpecialSourceId(sourceId: 10))
Expand Down Expand Up @@ -46,4 +45,39 @@ final class OrderSourceTest: XCTestCase {
print("\(error)")
}
}

func testCreateOrderSourceWithDuplicateName() throws {
do {
_ = try OrderSource(identifier: 44, name: "COMPOSITE_ASK", pubFlags: 0)
_ = try OrderSource(identifier: 33, name: "COMPOSITE_ASK", pubFlags: 0)
} catch ArgumentException.exception(let message) {
XCTAssert(message.contains("name"), "Wrong message \(message)")
return
} catch {
print("undefined error \(error)")
}
XCTAssert(false, "should be generated exception")
}

func testCreateOrderSourceWithDuplicateId() throws {
do {
_ = try OrderSource(identifier: 3, name: "COMPOSITE_ASK1", pubFlags: 0)
_ = try OrderSource(identifier: 3, name: "COMPOSITE_ASK3", pubFlags: 0)
} catch ArgumentException.exception(let message) {
XCTAssert(message.contains("id"), "Wrong message \(message)")
return
} catch {
print("undefined error \(error)")
}
XCTAssert(false, "should be generated exception")
}

func testCreateOrderSource() throws {
do {
_ = try OrderSource(identifier: 5, name: "COMPOSITE_ASK2", pubFlags: 0)
_ = try OrderSource(identifier: 6, name: "COMPOSITE_ASK4", pubFlags: 0)
} catch {
XCTAssert(false, "undefined error \(error)")
}
}
}

0 comments on commit 1621131

Please sign in to comment.