-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[Feat/#22] portfolio UI 구현
- Loading branch information
Showing
71 changed files
with
1,880 additions
and
773 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
Projects/Folio/Shared/DesignSystem/Sources/MinimalButton.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// | ||
// MinimalButton.swift | ||
// FolioSharedDesignSystem | ||
// | ||
// Created by 송영모 on 2023/09/26. | ||
// | ||
|
||
import SwiftUI | ||
|
||
|
||
public struct MinimalButton: View { | ||
public let title: String | ||
public let isActive: Bool | ||
|
||
public var action: () -> () | ||
|
||
public init( | ||
title: String = "", | ||
isActive: Bool = false, | ||
action: @escaping () -> Void | ||
) { | ||
self.title = title | ||
self.isActive = isActive | ||
self.action = action | ||
} | ||
|
||
public var body: some View { | ||
Button(action: { | ||
action() | ||
}, label: { | ||
HStack { | ||
Spacer() | ||
|
||
Text(self.title) | ||
.font(.title3) | ||
.fontWeight(.semibold) | ||
.foregroundStyle(.white) | ||
|
||
Spacer() | ||
} | ||
.padding(.vertical, 10) | ||
}) | ||
.background(.black) | ||
.clipShape( | ||
RoundedRectangle( | ||
cornerRadius: 8, | ||
style: .continuous | ||
) | ||
) | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
Projects/Toolinder/Domain/Trade/Interface/Sources/DTO/TickerDTO.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// | ||
// TickerDTO.swift | ||
// ToolinderDomainTradeInterface | ||
// | ||
// Created by 송영모 on 2023/09/26. | ||
// | ||
|
||
import Foundation | ||
import SwiftData | ||
|
||
public class TickerDTO { | ||
public var type: TickerType? | ||
public var currency: Currency? | ||
public var name: String? | ||
|
||
public init( | ||
type: TickerType, | ||
currency: Currency, | ||
name: String | ||
) { | ||
self.type = type | ||
self.currency = currency | ||
self.name = name | ||
} | ||
|
||
func toDomain() -> Ticker { | ||
return .init( | ||
type: type, | ||
currency: currency, | ||
name: name | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
Projects/Toolinder/Domain/Trade/Interface/Sources/Entity/TickerSummaryDataEntity.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// | ||
// TickerSummaryDataEntity.swift | ||
// ToolinderDomainTradeInterface | ||
// | ||
// Created by 송영모 on 2023/09/26. | ||
// | ||
|
||
import Foundation | ||
|
||
public struct TickerSummaryDataEntity: Equatable { | ||
public let avgPrice: Double | ||
public let currentVolume: Double | ||
public let buyVolume: Double | ||
public let sellVolume: Double | ||
public let yield: Double | ||
public let profit: Double | ||
} | ||
|
||
public extension Ticker { | ||
func toTickerSummaryDataEntity() -> TickerSummaryDataEntity { | ||
let trades = (self.trades ?? []).sorted(by: { $0.date < $1.date }) | ||
|
||
var totalAmount = 0.0 | ||
var buyVolume = 0.0 | ||
var sellVoume = 0.0 | ||
var totalVolume = 0.0 | ||
var avgPrice = 0.0 | ||
var profit = 0.0 | ||
var yield = 0.0 | ||
|
||
for trade in trades { | ||
// 평단가 계산 | ||
if trade.side == .buy { | ||
totalAmount += (trade.price ?? 0) * (trade.volume ?? 0) | ||
buyVolume += (trade.volume ?? 0) | ||
} else { | ||
sellVoume += (trade.volume ?? 0) | ||
} | ||
totalVolume = buyVolume - sellVoume | ||
|
||
if !totalVolume.isZero { | ||
avgPrice = totalAmount / totalVolume | ||
} | ||
|
||
// 수익 계산 | ||
if trade.side == .sell { | ||
profit += ((trade.price ?? 0) - avgPrice) * (trade.volume ?? 0) | ||
} | ||
} | ||
// 수익률 계산 | ||
if !totalAmount.isZero { | ||
yield = (profit / totalAmount) * 100 | ||
} | ||
|
||
let result = TickerSummaryDataEntity( | ||
avgPrice: avgPrice, | ||
currentVolume: totalVolume, | ||
buyVolume: buyVolume, | ||
sellVolume: sellVoume, | ||
yield: yield, | ||
profit: profit | ||
) | ||
|
||
return result | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
Projects/Toolinder/Domain/Trade/Interface/Sources/Entity/TickerTypeChartDataEntity.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// | ||
// TickerTypeChartDataEntity.swift | ||
// ToolinderDomainTradeInterface | ||
// | ||
// Created by 송영모 on 2023/09/25. | ||
// | ||
|
||
import Foundation | ||
|
||
public struct TickerTypeChartData: Equatable, Hashable { | ||
public let tickerType: TickerType | ||
public let hold: Double | ||
} | ||
|
||
public typealias TickerTypeChartDataEntity = [TickerTypeChartData] | ||
|
||
public extension [Trade] { | ||
func toTickerTypeChartDataEntity() -> TickerTypeChartDataEntity { | ||
return TickerType.allCases.map { type in | ||
let trades = self.filter({ $0.ticker?.type == type }) | ||
let hold = trades.map { trade in | ||
let sum: Double = (trade.price ?? 0.0) * (trade.volume ?? 0.0) | ||
let sign: Double = trade.side == .buy ? 1.0 : -1.0 | ||
|
||
return sum * sign | ||
}.reduce(0.0, +) | ||
|
||
return .init( | ||
tickerType: type, | ||
hold: hold | ||
) | ||
} | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
Projects/Toolinder/Domain/Trade/Interface/Sources/Entity/TradeDateChartDataEntity.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// | ||
// TradeDateChartDataEntity.swift | ||
// ToolinderDomainTradeInterface | ||
// | ||
// Created by 송영모 on 2023/09/25. | ||
// | ||
|
||
import Foundation | ||
|
||
public struct TradeDateChartData: Equatable, Hashable { | ||
public let date: Date | ||
public let buyCount: Int | ||
public let sellCount: Int | ||
} | ||
|
||
public typealias TradeDateChartDataEntity = [TradeDateChartData] | ||
|
||
public extension [Trade] { | ||
func toTradeDateChartDataEntity(from fromDate: Date, to toDate: Date) -> TradeDateChartDataEntity { | ||
let trades = self.sorted(by: { $0.date < $1.date }) | ||
let dates = Date.dates(from: fromDate, to: toDate) | ||
|
||
return dates.map { date in | ||
let trades = trades.filter { $0.date.isEqual(date: date) } | ||
|
||
return .init( | ||
date: date, | ||
buyCount: trades.filter { $0.side == .buy }.count, | ||
sellCount: trades.filter { $0.side == .sell }.count | ||
) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
28 changes: 28 additions & 0 deletions
28
Projects/Toolinder/Domain/Trade/Interface/Sources/Repository/StorageContainer.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// | ||
// StorageRepository.swift | ||
// ToolinderDomainTradeInterface | ||
// | ||
// Created by 송영모 on 2023/09/26. | ||
// | ||
|
||
import Foundation | ||
import SwiftData | ||
|
||
public class StorageContainer { | ||
public static let shared = StorageContainer() | ||
|
||
private var container: ModelContainer? | ||
public var context: ModelContext? | ||
|
||
private init() { | ||
do { | ||
container = try ModelContainer(for: Ticker.self, Trade.self) | ||
|
||
if let container { | ||
context = ModelContext(container) | ||
} | ||
} catch { | ||
print(error) | ||
} | ||
} | ||
} |
Oops, something went wrong.