Skip to content

Commit

Permalink
Schedule sample CL ✅
Browse files Browse the repository at this point in the history
  • Loading branch information
kosyloa committed Oct 10, 2023
1 parent 757610f commit 0ecfe2e
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 46 deletions.
6 changes: 6 additions & 0 deletions DXFeedFramework.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@
648BD56F2AC582AB004A3A95 /* DateTimeParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648BD56E2AC582AB004A3A95 /* DateTimeParserTest.swift */; };
648BD5712AC583AC004A3A95 /* TimeFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648BD5702AC583AC004A3A95 /* TimeFormat.swift */; };
648E98AA2AAF625800BFD219 /* IIndexedEvent+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648E98A92AAF625800BFD219 /* IIndexedEvent+Ext.swift */; };
649282E72AD54919008F0F04 /* ScheduleUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649282E62AD54919008F0F04 /* ScheduleUtils.swift */; };
649282E82AD54919008F0F04 /* ScheduleUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649282E62AD54919008F0F04 /* ScheduleUtils.swift */; };
64963B6A2A8E545C001E40F7 /* IEventType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64963B692A8E545C001E40F7 /* IEventType.swift */; };
6498E6B22AB1D41A0093A065 /* DXSchedule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6498E6B12AB1D41A0093A065 /* DXSchedule.swift */; };
6498E6B52AB1D4480093A065 /* NativeSchedule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6498E6B42AB1D4480093A065 /* NativeSchedule.swift */; };
Expand Down Expand Up @@ -617,6 +619,7 @@
648BD56E2AC582AB004A3A95 /* DateTimeParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTimeParserTest.swift; sourceTree = "<group>"; };
648BD5702AC583AC004A3A95 /* TimeFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeFormat.swift; sourceTree = "<group>"; };
648E98A92AAF625800BFD219 /* IIndexedEvent+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IIndexedEvent+Ext.swift"; sourceTree = "<group>"; };
649282E62AD54919008F0F04 /* ScheduleUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScheduleUtils.swift; sourceTree = "<group>"; };
64963B692A8E545C001E40F7 /* IEventType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IEventType.swift; sourceTree = "<group>"; };
6498E6B12AB1D41A0093A065 /* DXSchedule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DXSchedule.swift; sourceTree = "<group>"; };
6498E6B42AB1D4480093A065 /* NativeSchedule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeSchedule.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1067,6 +1070,7 @@
646979712A3B5AF60003A9BA /* Colors.xcassets */,
647426AC2ABC85F20012F793 /* ArgumentParser.swift */,
647426AE2ABC93900012F793 /* EventCode+String.swift */,
649282E62AD54919008F0F04 /* ScheduleUtils.swift */,
);
path = Utils;
sourceTree = "<group>";
Expand Down Expand Up @@ -1850,6 +1854,7 @@
files = (
648BD56D2AC56A04004A3A95 /* SubscriptionUtils.swift in Sources */,
648BD56B2AC4576F004A3A95 /* HelpCommand.swift in Sources */,
649282E82AD54919008F0F04 /* ScheduleUtils.swift in Sources */,
647426AF2ABC93900012F793 /* EventCode+String.swift in Sources */,
645BE8542AC3229D0028243D /* ToolsCommand.swift in Sources */,
644FE5D12AC1F34000580E3A /* LatencyMetricsPrinter.swift in Sources */,
Expand Down Expand Up @@ -1926,6 +1931,7 @@
64B436522AB9D3410003919E /* ViewController.swift in Sources */,
64148B702ABC2F7C0063110E /* Colors.swift in Sources */,
64B4364E2AB9D3410003919E /* AppDelegate.swift in Sources */,
649282E72AD54919008F0F04 /* ScheduleUtils.swift in Sources */,
64B436502AB9D3410003919E /* SceneDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "ScheduleSample /Users/akosylo/Downloads/schedule.zip /Users/akosylo/Downloads/sample.ipf.zip IBM 2011-05-26-14:15:00"
argument = "ScheduleSample /Users/akosylo/test_ipf/schedule.zip /Users/akosylo/test_ipf/sample.ipf.zip AAPL 2012-05-26-14:15:00"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
Expand Down
7 changes: 6 additions & 1 deletion DXFeedFramework/Native/Schedule/NativeSchedule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,18 @@ class NativeSchedule {
let end = try ErrorCheck.nativeCall(thread, dxfg_Session_getEndTime(thread, session))
let nativeType = try ErrorCheck.nativeCall(thread, dxfg_Session_getType(thread, session))
let isTraiding = try ErrorCheck.nativeCall(thread, dxfg_Session_isTrading(thread, session))

let day = try ErrorCheck.nativeCall(thread, dxfg_Session_getDay(thread, session))
defer {
_ = try? ErrorCheck.nativeCall(thread, dxfg_JavaObjectHandler_release(thread, &(day.pointee.handler)))
}
let yearMonthDay = try ErrorCheck.nativeCall(thread, dxfg_Day_getYearMonthDay(thread, day))
let type = dxfg_session_type_t(UInt32(nativeType))
let session = ScheduleSession(native: NativeSession(native: session),
nativeSchedule: self,
startTime: start,
endTime: end,
type: ScheduleSessionType.getValueFromNative(type),
yearMonthDay: yearMonthDay,
isTrading: isTraiding == 1)
return session
}
Expand Down
24 changes: 24 additions & 0 deletions DXFeedFramework/Schedule/ScheduleSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,37 @@ public class ScheduleSession {
public let endTime: Long
/// Returns type of this session.
public let type: ScheduleSessionType
/// Returns year, month and day numbers decimally packed in the following way:
/// YearMonthDay = year * 10000 + month * 100 + day
///
/// For example, September 28, 1977 has value 19770928.
public let yearMonthDay: Int32
/// Returns true if trading activity is allowed for this type of session.
///
/// Some sessions may have zero duration - e.g. indices that post value once a day.
/// Such sessions can be of any appropriate type, trading or non-trading.
public let isTrading: Bool

/// DateFormat for toString method
private static let dateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return formatter
}()

init(native: NativeSession,
nativeSchedule: NativeSchedule,
startTime: Long,
endTime: Long,
type: ScheduleSessionType,
yearMonthDay: Int32,
isTrading: Bool) {
self.native = native
self.nativeSchedule = nativeSchedule
self.startTime = startTime
self.endTime = endTime
self.type = type
self.yearMonthDay = yearMonthDay
self.isTrading = isTrading
}
}
Expand All @@ -80,6 +95,15 @@ extension ScheduleSession {
public func getNext(filter: SessionFilter) throws -> ScheduleSession? {
return try nativeSchedule.getNextSession(after: self, filter: filter)
}

public func toString() -> String {
let format = ScheduleSession.dateFormatter
return """
Session(\(yearMonthDay), \(type), \(isTrading), \
\(format.string(from: Date(timeIntervalSince1970: Double(startTime/1000)))), \
\(format.string(from: Date(timeIntervalSince1970: Double(endTime/1000))))
"""
}
}

extension ScheduleSession: Equatable {
Expand Down
24 changes: 18 additions & 6 deletions Samples/PerfTestCL/ScheduleCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ class ScheduleCommand: ToolsCommand {
throw ArgumentParserException.error(message: "File \(defaultFile) doesn't exist")
}
try DXSchedule.setDefaults(Data(contentsOf: URL(filePath: defaultFile)))

let reader = DXInstrumentProfileReader()
let profiles = try reader.readFromFile(address: profileFile)?.reduce(into: [String: InstrumentProfile]()) {
$0[$1.symbol] = $1
Expand All @@ -56,12 +55,25 @@ class ScheduleCommand: ToolsCommand {
fatalError("IPF Profiles is nil for \(profileFile)")
}
print("Loaded \(profiles.count) instrument profiles")
checkAllSchedules(Array(profiles.values))
guard let profile = profiles[symbol] else {
fatalError("Could not find profile for \(symbol)")
}
print("Found profile for \(symbol): \(profile.descriptionStr)")
let format = DateFormatter()
var timeArgument: Double = 0
if arguments.count == 5 {
let time = arguments[4]
format.dateFormat = "yyyy-MM-dd-HH:mm:ss"
timeArgument = format.date(from: time)?.timeIntervalSince1970 ?? 0
} else {
timeArgument = Date.now.timeIntervalSince1970
}


checkAllSchedules(Array(profiles.values))
let time = Long(timeArgument * 1000)
format.dateFormat = "yyyy-MM-dd HH:mm:ssZ"
print("Using timestamp \(format.string(from: Date(timeIntervalSince1970: timeArgument)))")
print(try ScheduleUtils.findNext5Days(profile, time: time, separator: " "))
print(try ScheduleUtils.getSessions(profile, time: time))
} catch {
print("ScheduleSample error: \(error)")
}
Expand All @@ -71,8 +83,8 @@ class ScheduleCommand: ToolsCommand {
var successes = 0
profiles.forEach { profile in
do {
let schedule = try DXSchedule(instrumentProfile: profile)
let venues = try DXSchedule.getTradingVenues(profile: profile)
_ = try DXSchedule(instrumentProfile: profile)
_ = try DXSchedule.getTradingVenues(profile: profile)
successes += 1
} catch {
print("Error getting schedule for \(profile.symbol)(\(profile.tradingHours)): \(error)")
Expand Down
40 changes: 2 additions & 38 deletions Samples/ScheduleSampleApp/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ class ViewController: UIViewController {
return
}
let next5Days = try profilesForSymbol?.map({ profile in
try self.findNext5Days(profile, time: currentTime)
try ScheduleUtils.findNext5Days(profile, time: currentTime, separator: "\n")
})
let currentSession = try profilesForSymbol?.map({ profile in
try self.getSessions(profile, time: currentTime)
try ScheduleUtils.getSessions(profile, time: currentTime)
})
var result = next5Days?.joined(separator: "") ?? ""
result += "\n"
Expand All @@ -98,42 +98,6 @@ class ViewController: UIViewController {
}
}

private func findNext5Days(_ profile: InstrumentProfile, time: Long) throws -> String {
let schedule = try DXSchedule(instrumentProfile: profile)
var day: ScheduleDay? = try schedule.getDayByTime(time: time)
var dates = [String]()
dates.append("5 next holidays for \(profile.symbol): ")
for _ in 0..<5 {
day = try day?.getNext(filter: DayFilter.holiday)
dates.append("\(day?.yearMonthDay ?? 0)")
}
return dates.joined(separator: "\n")
}

private func getSessions(_ profile: InstrumentProfile, time: Long) throws -> String {
let schedule = try DXSchedule(instrumentProfile: profile)
let session = try schedule.getSessionByTime(time: time)
let nextTradingSession = session.isTrading ? session : try session.getNext(filter: .trading)
let nearestSession = try schedule.getNearestSessionByTime(time: time, filter: .trading)

func sessionDescription(_ session: ScheduleSession?) -> String {
guard let session = session else {
return ""
}
return """
\(profile.symbol): \(session.type) \
\(TimeUtil.toLocalDateStringWithoutMillis(millis: session.startTime))\
-\(TimeUtil.toLocalDateStringWithoutMillis(millis: session.endTime))
"""
}
return """
Current session for \(profile.symbol):
\(sessionDescription(session))
\(sessionDescription(nextTradingSession))
\(sessionDescription(nearestSession))
"""
}

private func getCurrentTime() -> Long {
let date = dateFormater.date(from: timeTextField.text ?? "")
return Long((date?.timeIntervalSince1970 ?? 0)) * 1000
Expand Down
42 changes: 42 additions & 0 deletions Samples/Utils/ScheduleUtils.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// ScheduleUtils.swift
// DXFeedFramework
//
// Created by Aleksey Kosylo on 10.10.23.
//

import Foundation
import DXFeedFramework

class ScheduleUtils {
static func findNext5Days(_ profile: InstrumentProfile, time: Long, separator: String) throws -> String {
let schedule = try DXSchedule(instrumentProfile: profile)
var day: ScheduleDay? = try schedule.getDayByTime(time: time)
var dates = [String]()
dates.append("5 next holidays for \(profile.symbol):")
for _ in 0..<5 {
day = try day?.getNext(filter: DayFilter.holiday)
dates.append("\(day?.yearMonthDay ?? 0)")
}
return dates.joined(separator: separator)
}

static func getSessions(_ profile: InstrumentProfile, time: Long) throws -> String {
let schedule = try DXSchedule(instrumentProfile: profile)
let session = try schedule.getSessionByTime(time: time)
let nextTradingSession = session.isTrading ? session : try session.getNext(filter: .trading)
let nearestSession = try schedule.getNearestSessionByTime(time: time, filter: .trading)

func sessionDescription(_ session: ScheduleSession?) -> String {
guard let session = session else {
return ""
}
return session.toString()
}
return """
Current session for \(profile.symbol): \(sessionDescription(session))
Next trading session for \(profile.symbol): \(sessionDescription(nextTradingSession))
Nearest trading session for \(profile.symbol): \(sessionDescription(nearestSession))
"""
}
}

0 comments on commit 0ecfe2e

Please sign in to comment.