Skip to content

Commit

Permalink
OrderBase ✅
Browse files Browse the repository at this point in the history
  • Loading branch information
kosyloa committed Oct 11, 2023
1 parent 1621131 commit 6a0ab79
Show file tree
Hide file tree
Showing 10 changed files with 426 additions and 44 deletions.
16 changes: 16 additions & 0 deletions DXFeedFramework.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@
64BA92672A306E3100BE26A0 /* Trade+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BA92662A306E3100BE26A0 /* Trade+Ext.swift */; };
64BA92692A306E6000BE26A0 /* TradeBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BA92682A306E6000BE26A0 /* TradeBase.swift */; };
64BA926B2A3072CA00BE26A0 /* TradeMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BA926A2A3072CA00BE26A0 /* TradeMapper.swift */; };
64BDDB1E2AD6CC6A00694210 /* Order.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB1D2AD6CC6A00694210 /* Order.swift */; };
64BDDB202AD6CC8300694210 /* AnalyticOrder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB1F2AD6CC8300694210 /* AnalyticOrder.swift */; };
64BDDB222AD6CC9A00694210 /* SpreadOrder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB212AD6CC9A00694210 /* SpreadOrder.swift */; };
64BDDB242AD6F10200694210 /* Scope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64BDDB232AD6F10200694210 /* Scope.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 */; };
Expand Down Expand Up @@ -715,6 +719,10 @@
64BA92662A306E3100BE26A0 /* Trade+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Trade+Ext.swift"; sourceTree = "<group>"; };
64BA92682A306E6000BE26A0 /* TradeBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TradeBase.swift; sourceTree = "<group>"; };
64BA926A2A3072CA00BE26A0 /* TradeMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TradeMapper.swift; sourceTree = "<group>"; };
64BDDB1D2AD6CC6A00694210 /* Order.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Order.swift; sourceTree = "<group>"; };
64BDDB1F2AD6CC8300694210 /* AnalyticOrder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticOrder.swift; sourceTree = "<group>"; };
64BDDB212AD6CC9A00694210 /* SpreadOrder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpreadOrder.swift; sourceTree = "<group>"; };
64BDDB232AD6F10200694210 /* Scope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scope.swift; sourceTree = "<group>"; };
64C771F12A94A224009868C2 /* Character+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Character+Ext.swift"; sourceTree = "<group>"; };
64C771F32A94A86E009868C2 /* Side.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Side.swift; sourceTree = "<group>"; };
64C771F52A94ADDA009868C2 /* Direction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Direction.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -974,6 +982,9 @@
6486B9702AD0445E00D8D5FA /* UnderlyingMapper.swift */,
6486B9742AD0493F00D8D5FA /* TheoPrice+Ext.swift */,
6486B9762AD04C5800D8D5FA /* TheoPriceMapper.swift */,
64BDDB1D2AD6CC6A00694210 /* Order.swift */,
64BDDB1F2AD6CC8300694210 /* AnalyticOrder.swift */,
64BDDB212AD6CC9A00694210 /* SpreadOrder.swift */,
);
path = Markets;
sourceTree = "<group>";
Expand Down Expand Up @@ -1121,6 +1132,7 @@
6486B9782AD04F4000D8D5FA /* OrderBase.swift */,
6486B97A2AD0517A00D8D5FA /* OrderAction.swift */,
6486B97C2AD057F200D8D5FA /* OrderSource.swift */,
64BDDB232AD6F10200694210 /* Scope.swift */,
);
path = Extra;
sourceTree = "<group>";
Expand Down Expand Up @@ -2132,6 +2144,7 @@
6447A5F12A8FDD1B00739CCF /* BitUtil.swift in Sources */,
64963B6A2A8E545C001E40F7 /* IEventType.swift in Sources */,
6428EF282AB0856400F54F59 /* DXInstrumentProfileConnectionState+Ext.swift in Sources */,
64BDDB222AD6CC9A00694210 /* SpreadOrder.swift in Sources */,
640C3FCE2A61788500555161 /* CandleExchange.swift in Sources */,
641BCBBC2A20ED8100FE23C2 /* DXEndpointObserver.swift in Sources */,
6486B9792AD04F4000D8D5FA /* OrderBase.swift in Sources */,
Expand Down Expand Up @@ -2165,6 +2178,7 @@
64C771FF2A9504ED009868C2 /* SnapshotProcessor.swift in Sources */,
64C771F82A94B88C009868C2 /* TimeAndSaleType.swift in Sources */,
641BDD5B2AC72BD400236B78 /* ConcurrentWeakHashTable.swift in Sources */,
64BDDB242AD6F10200694210 /* Scope.swift in Sources */,
6447A5DF2A8E56FC00739CCF /* IIndexedEvent.swift in Sources */,
64104FC52A26059B00D1FC41 /* ConcurrentSet.swift in Sources */,
64BA925F2A306B9600BE26A0 /* Profile.swift in Sources */,
Expand All @@ -2178,6 +2192,7 @@
642BE4CA2A2E1C640052340A /* MarketEvent.swift in Sources */,
6486B95B2AD015B400D8D5FA /* PriceType.swift in Sources */,
8088D76629C0FBCE00F240CB /* IsolateThread.swift in Sources */,
64BDDB202AD6CC8300694210 /* AnalyticOrder.swift in Sources */,
64AAF0532A8113E800E8942B /* String+Range.swift in Sources */,
642BE4D02A2F1D3C0052340A /* Quote+Ext.swift in Sources */,
641AC1A92A61AE4000EF6D6C /* DXAliases.swift in Sources */,
Expand All @@ -2187,6 +2202,7 @@
6486B9672AD0390800D8D5FA /* GreeksMapper.swift in Sources */,
64AAF0572A82A3FC00E8942B /* ICandleSymbolProperty.swift in Sources */,
64437A922A9DF1DE005929B2 /* NativeInstrumentProfileReader.swift in Sources */,
64BDDB1E2AD6CC6A00694210 /* Order.swift in Sources */,
64437A8F2A9DEE6F005929B2 /* InstrumentProfile.swift in Sources */,
64C771FA2A94D692009868C2 /* ShortSaleRestriction.swift in Sources */,
64656F5E2A1B97F2006A0B19 /* NativeFeed.swift in Sources */,
Expand Down
4 changes: 2 additions & 2 deletions DXFeedFramework/Events/Market/Extra/IndexedEventSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ public class IndexedEventSource {
public let name: String

/// The default source with zero identifier for all events that do not support multiple sources.
public static let defaultSource = IndexedEventSource(identifier: 0, name: "DEFAULT")
public static let defaultSource = IndexedEventSource( 0, "DEFAULT")

/// Initializes a new instance of the ``IndexedEventSource`` class.
///
/// - Parameters:
/// - identifier: The identifier
/// - name: The name of identifier
public init(identifier: Int, name: String) {
public init(_ identifier: Int, _ name: String) {
self.name = name
self.identifier = identifier
}
Expand Down
12 changes: 10 additions & 2 deletions DXFeedFramework/Events/Market/Extra/OrderAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

import Foundation

public enum OrderAction {
public enum OrderAction: Int, CaseIterable {
/// Default enum value for orders that do not support "Full Order Book" and for backward compatibility -
/// action must be derived from other ``Order``
case undefined
case undefined = 0
/// New Order is added to Order Book.
case new
/// Order is modified and price-time-priority is not maintained (i.e. order has re-entered Order Book).
Expand All @@ -28,3 +28,11 @@ public enum OrderAction {
/// Prior Trade/Order Execution bust
case bust
}

internal class OrderActionExt {
private static let values: [OrderAction] = EnumUtil.createEnumBitMaskArrayByValue(defaultValue: .undefined, allCases: OrderAction.allCases)

public static func valueOf(value: Int) -> OrderAction {
return values[value]
}
}
176 changes: 152 additions & 24 deletions DXFeedFramework/Events/Market/Extra/OrderBase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,48 @@

import Foundation

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

var type: EventCode = .orderBase
public var type: EventCode = .orderBase

// var eventSource: IndexedEventSource {
// get {
//
//
// }
// set {
//
// }
// }
public var eventSource: IndexedEventSource {
get {
var sourceId = index >> 48
if !OrderSource.isSpecialSourceId(sourceId: Int(sourceId)) {
sourceId = index >> 32
}
if let value = try? OrderSource.valueOf(identifier: Int(sourceId)) {
return value
}
fatalError("Incorrect value for eventsource \(self)")
}
set {
let shift = OrderSource.isSpecialSourceId(sourceId: newValue.identifier) ? 48 : 32
let mask = OrderSource.isSpecialSourceId(sourceId: Int(index >> 48)) ? ~(Long(-1) << 48) : ~(Long(-1) << 32)
index = (Long(newValue.identifier << shift)) | (index & mask)
}
}

var eventFlags: Int32 = 0
public var eventFlags: Int32 = 0

var index: Long = 0
public var index: Long = 0 {
didSet {
if index < 0 {
index = 0
print("Negative index for \(self)")
}
}
}

var eventSymbol: String
public var eventSymbol: String

var eventTime: Int64 = 0
public var eventTime: Int64 = 0
/*
* Flags property has several significant bits that are packed into an integer in the following way:
* 31..15 14..11 10..4 3 2 1 0
* +--------+--------+--------+----+----+----+----+
*), \--------+--------+--------+----+----+----+----+
* | | Action |Exchange| Side | Scope |
* +--------+--------+--------+----+----+----+----+
*), \--------+--------+--------+----+----+----+----+
*/

// ACTION values are taken from OrderAction enum.
Expand All @@ -57,23 +71,23 @@ class OrderBase: MarketEvent, IIndexedEvent, CustomStringConvertible {
* Index field has 2 formats depending on whether source is "special" (see OrderSource.IsSpecialSourceId()).
* Note: both formats are IMPLEMENTATION DETAILS, they are subject to change without notice.
* 63..48 47..32 31..16 15..0
* +--------+--------+--------+--------+
*), \--------+--------+--------+--------+
* | Source |Exchange| Index | <- "special" order sources (non-printable id with exchange)
* +--------+--------+--------+--------+
*), \--------+--------+--------+--------+
* 63..48 47..32 31..16 15..0
* +--------+--------+--------+--------+
*), \--------+--------+--------+--------+
* | Source | Index | <- generic order sources (alphanumeric id without exchange)
* +--------+--------+--------+--------+
*), \--------+--------+--------+--------+
* Note: when modifying formats track usages of getIndex/setIndex, getSource/setSource and isSpecialSourceId
* methods in order to find and modify all code dependent on current formats.
*/

/*
* EventFlags property has several significant bits that are packed into an integer in the following way:
* 31..7 6 5 4 3 2 1 0
* +---------+----+----+----+----+----+----+----+
*), \---------+----+----+----+----+----+----+----+
* | | SM | | SS | SE | SB | RE | TX |
* +---------+----+----+----+----+----+----+----+
*), \---------+----+----+----+----+----+----+----+
*/

/// Gets or sets time and sequence of this order packaged into single long value
Expand Down Expand Up @@ -152,6 +166,11 @@ extension OrderBase {
public func getExchangeCode() -> Character {
return Character(BitUtil.getBits(flags: Int(flags), mask: OrderBase.exchangeMask, shift: OrderBase.exchangeShift))
}

/// Gets exchange code of this order.
public func getExchangeCode() -> Int {
return BitUtil.getBits(flags: Int(flags), mask: OrderBase.exchangeMask, shift: OrderBase.exchangeShift)
}
/// Sets exchange code of this order.
///
/// - Throws: ``ArgumentException/exception(_:)``
Expand All @@ -178,4 +197,113 @@ extension OrderBase {
}
}

/// Gets or sets time of this order.
/// Time is measured in milliseconds between the current time and midnight, January 1, 1970 UTC.
public var time: Long {
get {
((timeSequence >> 32) * 1000) + ((timeSequence >> 22) & 0x3ff)
}
set {
timeSequence = Long(TimeUtil.getSecondsFromTime(newValue) << 32) |
(Long(TimeUtil.getMillisFromTime(newValue)) << 22) |
Long(getSequence())
}
}

/// Gets sequence number of this order 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``.
public func getSequence() -> Int {
return Int(index) & Int(MarketEventConst.maxSequence)
}
/// Sets sequence number of this order to distinguish quotes 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``.
/// - Throws: ``ArgumentException/exception(_:)``
public func setSequence(_ sequence: Int) throws {
if sequence < 0 || sequence > MarketEventConst.maxSequence {
throw ArgumentException.exception(
"Sequence(\(sequence) is < 0 or > MaxSequence(\(MarketEventConst.maxSequence)"
)
}
index = Long(index & ~Long(MarketEventConst.maxSequence)) | Long(sequence)
}

/// Gets or sets timestamp of the original event in nanoseconds
/// Time is measured in nanoseconds between the current time and midnight, January 1, 1970 UTC.
public var timeNanos: Long {
get {
TimeNanosUtil.getNanosFromMillisAndNanoPart(time, timeNanoPart)
}
set {
time = TimeNanosUtil.getNanoPartFromNanos(newValue)
timeNanoPart = Int32(TimeNanosUtil.getNanoPartFromNanos(newValue))
}
}

/// Gets or sets action of this order.
/// Returns order action if available, otherwise ``OrderAction/undefined``
public var action: OrderAction {
get {
return OrderActionExt.valueOf(value: BitUtil.getBits(flags: Int(flags),
mask: OrderBase.actionMask,
shift: OrderBase.actionShift))
}
set {
flags = Int32(BitUtil.setBits(flags: Int(flags),
mask: OrderBase.actionMask,
shift: OrderBase.actionShift,
bits: newValue.rawValue))
}
}

/// Gets or sets scope of this order.
public var scope: Scope {
get {
return ScopeExt.valueOf(value: BitUtil.getBits(flags: Int(flags),
mask: OrderBase.scopeMask,
shift: OrderBase.scopeShift))
}

set {
flags = Int32(BitUtil.setBits(flags: Int(flags),
mask: OrderBase.scopeMask,
shift: OrderBase.scopeShift,
bits: newValue.rawValue))
}
}

/// Returns string representation of this candle event.
func toString() -> String {
return "OrderBase{\(baseFieldsToString())}"
}

/// Returns string representation of this candle fields.
func baseFieldsToString() -> String {
return
"""
\(eventSymbol), \
eventTime=\(TimeUtil.toLocalDateString(millis: eventTime)), \
source=\(eventSource), \
eventFlags=0x\(String(format: "%02X", eventFlags)), \
index=0x\(String(format: "%02X", index)), \
time=\(TimeUtil.toLocalDateString(millis: time)), \
sequence=\(getSequence()), \
timeNanoPart=\(timeNanoPart), \
action=\(action), \
actionTime=\(TimeUtil.toLocalDateString(millis: actionTime)), \
orderId=\(orderId), \
auxOrderId=\(auxOrderId), \
price=\(price), \
size=\(size), \
executedSize=\(executedSize), \
count=\(count), \
exchange=\(StringUtil.encodeChar(char: Int16(getExchangeCode()))), \
side=\(orderSide), \
scope=\(scope), \
tradeId=\(tradeId), \
tradePrice=\(tradePrice), \
tradeSize=\(tradeSize)
"""
}
}
Loading

0 comments on commit 6a0ab79

Please sign in to comment.