Skip to content

Commit

Permalink
Merge pull request #25 from folio-world/feat/#24-trade
Browse files Browse the repository at this point in the history
[Feat/#24] Trade 기능 작업 마무리
  • Loading branch information
mooyoung2309 authored Sep 30, 2023
2 parents 5e06165 + 6ec8b0c commit a702817
Show file tree
Hide file tree
Showing 66 changed files with 347 additions and 245 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public extension DeploymentTarget {
switch product {
case .Minimal: return .iOS(targetVersion: "16.0", devices: [.iphone])
case .Dying: return .iOS(targetVersion: "16.0", devices: [.iphone])
case .Toolinder: return .iOS(targetVersion: "17.0", devices: [.iphone])
case .Toolinder: return .iOS(targetVersion: "17.0", devices: [.iphone, .ipad])
default: return .iOS(targetVersion: "16.0", devices: [.iphone])
}
}
Expand All @@ -33,6 +33,7 @@ public extension DeploymentTarget {
case .macOS: return nil
case .watchOS: return .watchOS(product)
case .tvOS: return nil
case .visionOS: return nil
@unknown default: return nil
}
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 5 additions & 3 deletions Projects/Toolinder/App/Support/ToolinderAppIOS-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIRequiresFullScreen</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
Expand All @@ -15,9 +17,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1</string>
<string>2</string>
<key>CFBundleVersion</key>
<string>1</string>
<string>2.0.0</string>
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-2392187154020666~7018659983</string>
<key>GADIsAdManagerApp</key>
Expand Down Expand Up @@ -232,6 +234,6 @@
<string>remote-notification</string>
</array>
<key>UILaunchStoryboardName</key>
<string>Launch</string>
<string>LaunchScreen</string>
</dict>
</plist>
2 changes: 2 additions & 0 deletions Projects/Toolinder/App/ToolinderIOS.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import Foundation
import SwiftData

public class TickerDTO {
public var type: TickerType?
public var currency: Currency?
public var name: String?
public var type: TickerType
public var currency: Currency
public var name: String

public init(
type: TickerType,
Expand All @@ -24,7 +24,7 @@ public class TickerDTO {
}

func toDomain() -> Ticker {
return .init(
return Ticker(
type: type,
currency: currency,
name: name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,42 @@ import Foundation
import SwiftData

public struct TradeDTO {
public var side: TradeSide?
public var price: Double?
public var volume: Double?
public var images: [Data] = []
public var note: String?
public var date: Date = Date()
public var side: TradeSide
public var price: Double
public var volume: Double
public var fee: Double
public var images: [Data]
public var note: String
public var date: Date

public var ticker: Ticker?

public init(
side: TradeSide? = nil,
price: Double? = 0.0,
volume: Double? = 0.0,
side: TradeSide = .buy,
price: Double = 0,
volume: Double = 0,
fee: Double = 0,
images: [Data] = [],
note: String? = "",
date: Date = Date(),
ticker: Ticker? = nil
note: String = "",
date: Date = .now,
ticker: Ticker
) {
self.side = side
self.images = images
self.price = price
self.volume = volume
self.fee = fee
self.note = note
self.date = date
self.ticker = ticker
}

func toDomain() -> Trade {
return .init(
return Trade(
side: side,
price: price,
volume: volume,
fee: fee,
images: images,
note: note,
date: date,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@ public extension Ticker {
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)
switch trade.side {
case .buy:
totalAmount += trade.price * trade.volume
buyVolume += trade.volume

case .sell:
totalAmount -= avgPrice * trade.volume
sellVoume += trade.volume
}

totalVolume = buyVolume - sellVoume

if !totalVolume.isZero {
Expand All @@ -44,7 +47,7 @@ public extension Ticker {

// 수익 계산
if trade.side == .sell {
profit += ((trade.price ?? 0) - avgPrice) * (trade.volume ?? 0)
profit += (trade.price - avgPrice) * trade.volume
}
}
// 수익률 계산
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public extension [Trade] {
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 sum: Double = trade.price * trade.volume
let sign: Double = trade.side == .buy ? 1.0 : -1.0

return sum * sign
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,31 @@
import Foundation

public enum Currency: String, Codable, CaseIterable, Equatable {
case dollar = "USD"
case yen = "JPY"
case sterling = "GBP"
case franc = "CHF"
case dollar = "USD" // 미국: 달러
case euro = "EUR" // 유럽: 유로
case yen = "JPY" // 일본: 옌
case sterling = "GBP" // 영국: 스털링
case australianDollar = "AUD" // 오스트레일리아: 오스트레일리아 달러
case canadianDollar = "CAD" // 캐나다: 캐나다 달러
case franc = "CHF" // 스위스: 프랑
case krona = "SEK" // 스웨덴: 크로나
case peso = "MXN" // 멕시코: 페소
case newZealandDollar = "NZD" // 뉴질랜드: 뉴질랜드 달러
case singaporeDollar = "SGD" // 싱가포르: 싱가포르 달러
case hongKongDollar = "HKD" // 홍콩: 홍콩 달러
case krone = "NOK" // 노르웨이: 크로네
case won = "KRW" // 대한민국: 원

case bitcoin = "BTC" // 비트코인
/*
case florin = "AWG"
case turkishlira = "TRY"
case ruble = "RUB"
case euro = "EUR"
case dong = "VND"
case indianrupee = "INR"
case tenge = "KZT"
case peseta = "ESP"
case peso = "MXN"
case kip = "LAK"
case won = "KRW"
case austral = "AUD"
case hryvnia = "UAH"
case naira = "NGN"
case guarani = "PYG"
Expand All @@ -34,6 +43,6 @@ public enum Currency: String, Codable, CaseIterable, Equatable {
case manat = "AZN"
case baht = "THB"
case lari = "GEL"
case bitcoin = "BTC"
case brazilianreal = "BRL"
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ import Foundation
public enum TickerType: String, Codable, CaseIterable, Equatable {
case stock = "Stock"
case crypto = "Crypto"
case gold = "Gold"
case realEstate = "Real Estate"
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import SwiftData

@Model
public class Ticker {
public var type: TickerType? = TickerType.stock
public var currency: Currency? = Currency.dollar
public var name: String? = ""
public var type: TickerType = TickerType.stock
public var currency: Currency = Currency.dollar
public var name: String = ""

@Relationship(deleteRule: .cascade, inverse: \Trade.ticker) public var trades: [Trade]? = []

public init(
type: TickerType?,
currency: Currency?,
name: String?
type: TickerType,
currency: Currency,
name: String
) {
self.type = type
self.currency = currency
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,31 @@ import SwiftData

@Model
public class Trade {
public var side: TradeSide?
public var price: Double?
public var volume: Double?
public var side: TradeSide = TradeSide.buy
public var price: Double = 0
public var volume: Double = 0
public var fee: Double = 0
public var images: [Data] = []
public var note: String?
public var date: Date = Date()
public var note: String = ""
public var date: Date = Date.now

@Relationship public var ticker: Ticker?

public init(
side: TradeSide? = nil,
price: Double? = 0.0,
volume: Double? = 0.0,
images: [Data] = [],
note: String? = "",
date: Date = Date(),
ticker: Ticker? = nil
side: TradeSide,
price: Double,
volume: Double,
fee: Double,
images: [Data],
note: String,
date: Date,
ticker: Ticker?
) {
self.side = side
self.images = images
self.price = price
self.volume = volume
self.fee = fee
self.note = note
self.date = date
self.ticker = ticker
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import SwiftData

public protocol TickerRepositoryInterface {
func fetchTickers(descriptor: FetchDescriptor<Ticker>) -> Result<[Ticker], TickerError>
func saveTicker(ticker: Ticker) -> Result<Ticker, TickerError>
func updateTicker(model: Ticker, dto: TickerDTO) -> Result<Ticker, TickerError>
func deleteTicker(ticker: Ticker) -> Result<Ticker, TickerError>
func saveTicker(_ ticker: Ticker) -> Result<Ticker, TickerError>
func updateTicker(_ ticker: Ticker, new newTicker: TickerDTO) -> Result<Ticker, TickerError>
func deleteTicker(_ ticker: Ticker) -> Result<Ticker, TickerError>

func isValidatedSaveTicker(new: Ticker) -> Bool
func isValidatedUpdateTicker(origin: Ticker, new: TickerDTO) -> Bool
func isValidatedDeleteTicker(origin: Ticker) -> Bool
func isValidatedSaveTicker(_ ticker: Ticker) -> Bool
func isValidatedUpdateTicker(_ ticker: Ticker, new newTicker: TickerDTO) -> Bool
func isValidatedDeleteTicker(_ ticker: Ticker) -> Bool
}

public class TickerRepository: TickerRepositoryInterface {
Expand All @@ -32,48 +32,47 @@ public class TickerRepository: TickerRepositoryInterface {
}
}

public func saveTicker(ticker: Ticker) -> Result<Ticker, TickerError> {
if isValidatedSaveTicker(new: ticker) {
public func saveTicker(_ ticker: Ticker) -> Result<Ticker, TickerError> {
if isValidatedSaveTicker(ticker) {
context?.insert(ticker)
return .success(ticker)
} else {
return .failure(.unknown)
}
}

public func updateTicker(model: Ticker, dto: TickerDTO) -> Result<Ticker, TickerError> {
if isValidatedUpdateTicker(origin: model, new: dto) {
let ticker = model
ticker.type = dto.type
ticker.currency = dto.currency
ticker.name = dto.name
public func updateTicker(_ ticker: Ticker, new newTicker: TickerDTO) -> Result<Ticker, TickerError> {
if isValidatedUpdateTicker(ticker, new: newTicker) {
ticker.type = newTicker.type
ticker.currency = newTicker.currency
ticker.name = newTicker.name
return .success(ticker)
} else {
return .failure(.unknown)
}
}

public func deleteTicker(ticker: Ticker) -> Result<Ticker, TickerError> {
if isValidatedDeleteTicker(origin: ticker) {
public func deleteTicker(_ ticker: Ticker) -> Result<Ticker, TickerError> {
if isValidatedDeleteTicker(ticker) {
context?.delete(ticker)
return .success(ticker)
} else {
return .failure(.unknown)
}
}

public func isValidatedSaveTicker(new: Ticker) -> Bool {
public func isValidatedSaveTicker(_ ticker: Ticker) -> Bool {
return true
}

public func isValidatedUpdateTicker(origin: Ticker, new: TickerDTO) -> Bool {
if new.type != nil && new.currency != nil && new.name?.isEmpty == false {
public func isValidatedUpdateTicker(_ ticker: Ticker, new newTicker: TickerDTO) -> Bool {
if !newTicker.name.isEmpty {
return true
}
return false
}

public func isValidatedDeleteTicker(origin: Ticker) -> Bool {
public func isValidatedDeleteTicker(_ ticker: Ticker) -> Bool {
return true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public class TradeRepository: TradeRepositoryInterface {
}

public func isValidatedUpdateTicker(origin: Ticker, new: TickerDTO) -> Bool {
if new.type != nil && new.currency != nil && new.name?.isEmpty == false {
if new.type != nil && new.currency != nil && new.name.isEmpty == false {
return true
}
return false
Expand Down
Loading

0 comments on commit a702817

Please sign in to comment.