Skip to content

Commit c7ee649

Browse files
author
Reed Es
committed
first commit
0 parents  commit c7ee649

File tree

86 files changed

+9871
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+9871
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.build/
2+
.swiftpm/
3+
Package.resolved

.swift-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5.4.2

LICENSE

Lines changed: 373 additions & 0 deletions
Large diffs are not rendered by default.

Package.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// swift-tools-version:5.5
2+
//
3+
// Copyright 2021, 2022 OpenAlloc LLC
4+
//
5+
// This Source Code Form is subject to the terms of the Mozilla Public
6+
// License, v. 2.0. If a copy of the MPL was not distributed with this
7+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8+
//
9+
10+
import PackageDescription
11+
12+
let package = Package(
13+
name: "FlowWorthLib",
14+
platforms: [.macOS(.v12), .iOS(.v15)],
15+
products: [
16+
.library(
17+
name: "FlowWorthLib",
18+
targets: ["FlowWorthLib"]
19+
),
20+
],
21+
dependencies: [
22+
.package(url: "https://github.com/openalloc/FlowXCT", from: "1.0.0"),
23+
.package(url: "https://github.com/openalloc/FlowBase", from: "1.0.0"),
24+
.package(url: "https://github.com/openalloc/FlowStats", from: "1.0.0"),
25+
.package(url: "https://github.com/openalloc/SwiftSeriesResampler", from: "1.0.0"),
26+
.package(url: "https://github.com/openalloc/SwiftNiceScale", from: "1.0.0"),
27+
.package(url: "https://github.com/openalloc/SwiftRegressor", from: "1.0.0"),
28+
.package(url: "https://github.com/openalloc/SwiftModifiedDietz", from: "1.0.0"),
29+
],
30+
targets: [
31+
.target(
32+
name: "FlowWorthLib",
33+
dependencies: [
34+
"FlowBase",
35+
"FlowStats",
36+
.product(name: "FlowBase", package: "FlowBase"),
37+
.product(name: "FlowStats", package: "FlowStats"),
38+
.product(name: "SeriesResampler", package: "SwiftSeriesResampler"),
39+
.product(name: "NiceScale", package: "SwiftNiceScale"),
40+
.product(name: "Regressor", package: "SwiftRegressor"),
41+
.product(name: "ModifiedDietz", package: "SwiftModifiedDietz"),
42+
],
43+
path: "Sources"
44+
),
45+
.testTarget(
46+
name: "FlowWorthLibTests",
47+
dependencies: [
48+
"FlowWorthLib",
49+
"FlowXCT",
50+
],
51+
path: "Tests"
52+
),
53+
]
54+
)

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# FlowWorthLib
2+
3+
Swift library containing support for the [FlowWorth](https://openalloc.github.io/FlowWorth/index.html) app
4+
5+
_FlowWorthLib_ is part of the [OpenAlloc](https://github.com/openalloc) family of open source Swift software tools.
6+
7+
## Unit Tests
8+
9+
Most critical functionality in this library is backed by unit tests. Coverage can likely be better than it is.
10+
11+
Note that any given unit test may have defects or bad assumptions, and can be worthy of review and re-write.
12+
13+
## See Also
14+
15+
* [FlowAllocator](https://openalloc.github.io/FlowAllocator/index.html) - portfolio rebalancing tool for macOS
16+
* [FlowWorth](https://openalloc.github.io/FlowWorth/index.html) - portfolio valuation and tracking tool for macOS
17+
* [FlowUI](https://github.com/openalloc/FlowUI) - shared UI support for the _FlowAllocator_ and _FlowWorth_ apps
18+
* [FlowAllocHigh](https://github.com/openalloc/FlowAllocHigh) - high-level support for the _FlowAllocator_ app
19+
* [FlowAllocLow](https://github.com/openalloc/FlowAllocLow) - low-level support for the _FlowAllocator_ app
20+
* [FlowWorthLib](https://github.com/openalloc/FlowWorthLib) - support for the _FlowWorth_ app
21+
* [FlowBase](https://github.com/openalloc/FlowBase) - shared support for the _FlowAllocator_ and _FlowWorth_ apps
22+
* [FlowStats](https://github.com/openalloc/FlowStats) - shared stats support for the _FlowAllocator_ and _FlowWorth_ apps
23+
* [FlowViz](https://github.com/openalloc/FlowViz) - shared visualization components for the _FlowAllocator_ and _FlowWorth_ apps
24+
* [FlowXCT](https://github.com/openalloc/FlowXCT) - shared testing components for the _FlowAllocator_ and _FlowWorth_ apps
25+
26+
## License
27+
28+
Copyright 2021, 2022 OpenAlloc LLC
29+
30+
The code for this library is licensed under the [Mozilla Public License 2](https://www.mozilla.org/en-US/MPL/2.0/), except where noted in individual modules.
31+
32+
## Contributing
33+
34+
Contributions are welcome. You are encouraged to submit pull requests to fix bugs, improve documentation, or offer new features.
35+
36+
The pull request need not be a production-ready feature or fix. It can be a draft of proposed changes, or simply a test to show that expected behavior is buggy. Discussion on the pull request can proceed from there.
37+
38+
Contributions should ultimately have adequate test coverage. See tests for current entities to see what coverage is expected.
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
//
2+
// DisplaySettings.swift
3+
//
4+
// Copyright 2021, 2022 OpenAlloc LLC
5+
//
6+
// This Source Code Form is subject to the terms of the Mozilla Public
7+
// License, v. 2.0. If a copy of the MPL was not distributed with this
8+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
9+
//
10+
11+
import Foundation
12+
13+
import FlowBase
14+
import AllocData
15+
16+
public enum ReturnsExtent: Int, CaseIterable, Codable {
17+
case positiveOnly
18+
case all
19+
case negativeOnly
20+
21+
public static let _default: ReturnsExtent = .all
22+
}
23+
24+
public enum ReturnsGrouping: Int, CaseIterable, Codable {
25+
case assets
26+
case accounts
27+
case strategies
28+
29+
public static let _default: ReturnsGrouping = .assets
30+
}
31+
32+
public enum ReturnsColor: Int, CaseIterable, Codable {
33+
case color
34+
case mono
35+
36+
public static let _default: ReturnsColor = .color
37+
}
38+
39+
40+
public enum PeriodSummarySelection: Int, CaseIterable, Codable {
41+
case deltaMarketValue
42+
case deltaTotalBasis
43+
case modifiedDietz
44+
45+
public var isDelta: Bool { self == .deltaMarketValue || self == .deltaTotalBasis }
46+
public var isDietz: Bool { self == .modifiedDietz }
47+
48+
public static let _default: PeriodSummarySelection = .deltaMarketValue
49+
}
50+
51+
public enum TabsPrimaryReturns: Int, CaseIterable, Codable {
52+
case chart
53+
case assets
54+
case accounts
55+
case strategies
56+
case forecast
57+
58+
public static let defaultTab = TabsPrimaryReturns.chart
59+
public static let storageKey = "PrimaryReturnsTab"
60+
}
61+
62+
public enum TabsSecondaryReturns: Int, CaseIterable, Codable {
63+
case assets
64+
case accounts
65+
case delta
66+
case dietz
67+
case forecast
68+
69+
public static let defaultTab = TabsSecondaryReturns.assets
70+
public static let storageKey = "SecondaryReturnsTab"
71+
}
72+
73+
public enum TabsPositionsBuilder: Int, CaseIterable, Codable {
74+
case holdings
75+
case positions
76+
case previousPositions
77+
78+
public static let defaultTab = TabsPositionsBuilder.positions
79+
public static let storageKey = "PositionsBuilderTab"
80+
}
81+
82+
public enum TabsCashflowBuilder: Int, CaseIterable, Codable {
83+
case transactions
84+
case nuCashflow
85+
case prevCashflow
86+
87+
public static let defaultTab = TabsCashflowBuilder.nuCashflow
88+
public static let storageKey = "CashflowBuilderTab"
89+
}
90+
91+
public enum TabsSummaryBuilder: Int, CaseIterable, Codable {
92+
case assets
93+
case accounts
94+
case strategies
95+
96+
public static let defaultTab = TabsSummaryBuilder.assets
97+
public static let storageKey = "SummaryBuilderTab"
98+
}
99+
100+
// settings not requiring a context-reset
101+
public struct DisplaySettings: Equatable, Codable {
102+
public var activeSidebarMenuKey: String?
103+
public var returnsExpandBottom: Bool
104+
public var showSecondary: Bool
105+
public var showChartLegend: Bool
106+
public var excludedAssetMap: [AssetKey: Bool]
107+
public var excludedAccountMap: [AccountKey: Bool]
108+
public var begSnapshotKey: SnapshotKey
109+
public var endSnapshotKey: SnapshotKey
110+
public var orderedAssetKeys: [AssetKey]
111+
public var returnsGrouping: ReturnsGrouping
112+
public var returnsColor: ReturnsColor
113+
public var returnsExtent: ReturnsExtent
114+
public var periodSummarySelection: PeriodSummarySelection
115+
public var builderCapturedAt: Date
116+
public var pendingExcludedTxnMap: [TransactionKey: Bool]
117+
public var snapshotSummaryKey: SnapshotKey
118+
public var primaryReturnsTab: TabsPrimaryReturns
119+
public var secondaryReturnsTab: TabsSecondaryReturns
120+
public var builderPositionsTab: TabsPositionsBuilder
121+
public var builderCashflowTab: TabsCashflowBuilder
122+
public var builderSummaryTab: TabsSummaryBuilder
123+
124+
public enum CodingKeys: String, CodingKey, CaseIterable {
125+
case activeSidebarMenuKey
126+
case returnsExpandBottom
127+
case showSecondary
128+
case showChartLegend
129+
case excludedAssetMap
130+
case excludedAccountMap
131+
case begSnapshotKey
132+
case endSnapshotKey
133+
case orderedAssetKeys
134+
case returnsGrouping
135+
case returnsColor
136+
case returnsExtent
137+
case periodSummarySelection
138+
case builderCapturedAt
139+
case pendingExcludedTxnMap
140+
case snapshotSummaryKey
141+
case primaryReturnsTab
142+
case secondaryReturnsTab
143+
case builderPositionsTab
144+
case builderCashflowTab
145+
case builderSummaryTab
146+
}
147+
148+
public init() {
149+
activeSidebarMenuKey = ""
150+
returnsExpandBottom = false
151+
showSecondary = false
152+
showChartLegend = false
153+
excludedAssetMap = [:]
154+
excludedAccountMap = [:]
155+
begSnapshotKey = MValuationSnapshot.Key.empty
156+
endSnapshotKey = MValuationSnapshot.Key.empty
157+
orderedAssetKeys = []
158+
returnsGrouping = ReturnsGrouping._default
159+
returnsColor = ReturnsColor._default
160+
returnsExtent = ReturnsExtent._default
161+
periodSummarySelection = PeriodSummarySelection._default
162+
builderCapturedAt = Date.init(timeIntervalSinceReferenceDate: 0)
163+
pendingExcludedTxnMap = [:]
164+
snapshotSummaryKey = MValuationSnapshot.Key.empty
165+
primaryReturnsTab = .defaultTab
166+
secondaryReturnsTab = .defaultTab
167+
builderPositionsTab = .defaultTab
168+
builderCashflowTab = .defaultTab
169+
builderSummaryTab = .defaultTab
170+
}
171+
172+
public init(from decoder: Decoder) throws {
173+
let c = try decoder.container(keyedBy: CodingKeys.self)
174+
activeSidebarMenuKey = try c.decodeIfPresent(String.self, forKey: .activeSidebarMenuKey) ?? ""
175+
returnsExpandBottom = try c.decodeIfPresent(Bool.self, forKey: .returnsExpandBottom) ?? false
176+
showSecondary = try c.decodeIfPresent(Bool.self, forKey: .showSecondary) ?? false
177+
showChartLegend = try c.decodeIfPresent(Bool.self, forKey: .showChartLegend) ?? false
178+
excludedAssetMap = try c.decodeIfPresent([AssetKey: Bool].self, forKey: .excludedAssetMap) ?? [:]
179+
excludedAccountMap = try c.decodeIfPresent([AccountKey: Bool].self, forKey: .excludedAccountMap) ?? [:]
180+
181+
begSnapshotKey = try c.decodeIfPresent(SnapshotKey.self, forKey: .begSnapshotKey) ?? MValuationSnapshot.Key.empty
182+
endSnapshotKey = try c.decodeIfPresent(SnapshotKey.self, forKey: .endSnapshotKey) ?? MValuationSnapshot.Key.empty
183+
184+
orderedAssetKeys = try c.decodeIfPresent([AssetKey].self, forKey: .orderedAssetKeys) ?? []
185+
186+
returnsGrouping = try c.decodeIfPresent(ReturnsGrouping.self, forKey: .returnsGrouping) ?? ReturnsGrouping._default
187+
returnsColor = try c.decodeIfPresent(ReturnsColor.self, forKey: .returnsColor) ?? ReturnsColor._default
188+
returnsExtent = try c.decodeIfPresent(ReturnsExtent.self, forKey: .returnsExtent) ?? ReturnsExtent._default
189+
periodSummarySelection = try c.decodeIfPresent(PeriodSummarySelection.self, forKey: .periodSummarySelection) ?? PeriodSummarySelection._default
190+
191+
builderCapturedAt = try c.decodeIfPresent(Date.self, forKey: .builderCapturedAt) ?? Date.init(timeIntervalSinceReferenceDate: 0)
192+
193+
pendingExcludedTxnMap = try c.decodeIfPresent([TransactionKey: Bool].self, forKey: .pendingExcludedTxnMap) ?? [:]
194+
195+
snapshotSummaryKey = try c.decodeIfPresent(MValuationSnapshot.Key.self, forKey: .snapshotSummaryKey) ?? MValuationSnapshot.Key.empty
196+
197+
primaryReturnsTab = try c.decodeIfPresent(TabsPrimaryReturns.self, forKey: .primaryReturnsTab) ?? .defaultTab
198+
secondaryReturnsTab = try c.decodeIfPresent(TabsSecondaryReturns.self, forKey: .secondaryReturnsTab) ?? .defaultTab
199+
200+
builderPositionsTab = try c.decodeIfPresent(TabsPositionsBuilder.self, forKey: .builderPositionsTab) ?? .defaultTab
201+
builderCashflowTab = try c.decodeIfPresent(TabsCashflowBuilder.self, forKey: .builderCashflowTab) ?? .defaultTab
202+
builderSummaryTab = try c.decodeIfPresent(TabsSummaryBuilder.self, forKey: .builderSummaryTab) ?? .defaultTab
203+
}
204+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//
2+
// ModelSettings.swift
3+
//
4+
// Copyright 2021, 2022 OpenAlloc LLC
5+
//
6+
// This Source Code Form is subject to the terms of the Mozilla Public
7+
// License, v. 2.0. If a copy of the MPL was not distributed with this
8+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
9+
//
10+
11+
import Foundation
12+
13+
import FlowBase
14+
import AllocData
15+
16+
// settings usually requiring a results/context reset
17+
// shouldn't include navigation-oriented settings, such as tab selection or navigation state
18+
// okay to include infrequently-changed formatting details, such as locale
19+
public struct ModelSettings: Equatable, Codable {
20+
public var activeStrategyKey: StrategyKey
21+
22+
public static let defaultActiveStrategyKey = MStrategy.emptyKey
23+
24+
public enum CodingKeys: String, CodingKey, CaseIterable {
25+
case activeStrategyKey
26+
}
27+
28+
public init() {
29+
activeStrategyKey = ModelSettings.defaultActiveStrategyKey
30+
}
31+
32+
public init(from decoder: Decoder) throws {
33+
let c = try decoder.container(keyedBy: CodingKeys.self)
34+
activeStrategyKey = try c.decodeIfPresent(MStrategy.Key.self, forKey: .activeStrategyKey) ?? ModelSettings.defaultActiveStrategyKey
35+
}
36+
}

0 commit comments

Comments
 (0)