Skip to content

Commit

Permalink
Add more info to quote detail, need to add a migration later
Browse files Browse the repository at this point in the history
  • Loading branch information
premnirmal committed Jun 15, 2022
1 parent 68867b2 commit 78c7c98
Show file tree
Hide file tree
Showing 30 changed files with 931 additions and 478 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ dependencies {
kapt "androidx.room:room-compiler:$ROOM_VERSION"
implementation "androidx.room:room-ktx:$ROOM_VERSION"

implementation "com.robinhood.ticker:ticker:2.0.2"

prodImplementation "com.google.firebase:firebase-crashlytics:18.2.7"
prodImplementation "com.google.firebase:firebase-analytics:20.0.2"

Expand Down
81 changes: 81 additions & 0 deletions app/src/main/kotlin/com/github/premnirmal/ticker/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@ import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.github.premnirmal.ticker.components.AppClock.AppClockImpl
import com.github.premnirmal.tickerwidget.R
import com.robinhood.ticker.TickerView
import org.threeten.bp.DayOfWeek
import org.threeten.bp.ZonedDateTime
import org.threeten.bp.format.TextStyle.SHORT
import java.math.RoundingMode
import java.text.NumberFormat
import java.text.SimpleDateFormat
import java.util.Currency
import java.util.Date
import java.util.Locale

fun Drawable.toBitmap(): Bitmap {
Expand Down Expand Up @@ -147,4 +154,78 @@ fun ZonedDateTime.createTimeString(): String {
"$timeStr $day"
}
return fetched
}

fun Float.format(fractionDigits: Int = 2): String {
return NumberFormat.getInstance(Locale.getDefault()).run {
minimumFractionDigits = fractionDigits
maximumFractionDigits = fractionDigits
format(this@format)
}
}

fun Long.format(): String {
return NumberFormat.getInstance(Locale.getDefault()).format(this)
}

fun Long.formatDate(format: String): String {
return SimpleDateFormat(format, Locale.getDefault()).format(Date(this))
}

fun Long.formatBigNumbers(context: Context): String {
return when {
this < 100_000 -> NumberFormat.getInstance(Locale.getDefault()).format(this)
this < 1_000_000 -> context.getString(R.string.number_format_thousands, this.div(1000.0))
this < 1_000_000_000 -> {
context.getString(R.string.number_format_millions, this.div(1000000.0))
}
this < 1_000_000_000_000 -> {
context.getString(R.string.number_format_billions, this.div(1000000000.0))
}
else -> {
context.getString(R.string.number_format_trillions, this.div(1000000000000.0))
}
}
}

fun formatNumber(price: Float, currencyCode: String): String {
val currencyFormatter = NumberFormat.getCurrencyInstance().apply {
currency = Currency.getInstance(currencyCode)
maximumFractionDigits = 2
roundingMode = RoundingMode.FLOOR
}
return currencyFormatter.format(price)
}
fun TickerView.formatChange(change: Float) {
when {
change > 0 -> {
text = context.getString(R.string.quote_change_pos, change)
textColor = ContextCompat.getColor(context, R.color.change_positive)
}
change < 0 -> {
text = context.getString(R.string.quote_change_neg, change)
textColor = ContextCompat.getColor(context, R.color.change_negative)
}
else -> {
text = context.getString(R.string.quote_change_neg, change)
textColor = ContextCompat.getColor(context, R.color.white)
}
}
}

fun TickerView.formatChangePercent(changePercent: Float) {
when {
changePercent > 0 -> {
text = context.getString(R.string.quote_change_percent_pos, changePercent)
textColor = ContextCompat.getColor(context, R.color.change_positive)
}
changePercent < 0 -> {
text = context.getString(R.string.quote_change_percent_neg, changePercent)
textColor = ContextCompat.getColor(context, R.color.change_negative)
}
else -> {
text = context.getString(R.string.quote_change_percent_neg, changePercent)
textColor = ContextCompat.getColor(context, R.color.white)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.github.premnirmal.ticker.base

import android.graphics.Color
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.components.XAxis
Expand All @@ -11,7 +10,11 @@ import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
import com.github.premnirmal.ticker.model.IHistoryProvider.Range
import com.github.premnirmal.ticker.network.data.DataPoint
import com.github.premnirmal.ticker.ui.*
import com.github.premnirmal.ticker.ui.DateAxisFormatter
import com.github.premnirmal.ticker.ui.HourAxisFormatter
import com.github.premnirmal.ticker.ui.MultilineXAxisRenderer
import com.github.premnirmal.ticker.ui.TextMarkerView
import com.github.premnirmal.ticker.ui.ValueAxisFormatter
import com.github.premnirmal.tickerwidget.R

abstract class BaseGraphActivity : BaseActivity() {
Expand Down Expand Up @@ -106,9 +109,6 @@ abstract class BaseGraphActivity : BaseActivity() {
R.id.one_year -> range = Range.ONE_YEAR
R.id.max -> range = Range.MAX
}
val parent = v.parent as ViewGroup
(0 until parent.childCount).map { parent.getChildAt(it) }
.forEach { it.isEnabled = it != v }
fetchGraphData()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,11 @@ class StocksProvider : IStocksProvider {
val quote = if (allowCache) quoteMap[ticker] else null
quote?.let { emit(FetchResult.success(quote)) } ?: run {
try {
emit(api.getStock(ticker))
val res = api.getStock(ticker)
if (res.wasSuccessful) {
quoteMap[ticker] = res.data
}
emit(res)
} catch (ex: CancellationException) {
// ignore
} catch (ex: Exception) {
Expand Down Expand Up @@ -317,7 +321,7 @@ class StocksProvider : IStocksProvider {
}

override fun fetchStock(ticker: String): Flow<FetchResult<Quote>> {
return fetchStockInternal(ticker, true)
return fetchStockInternal(ticker, false) // todo resume caching after migration between quote and quoteRow
}

override fun getStock(ticker: String): Quote? = quoteMap[ticker]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import com.github.premnirmal.ticker.components.AppClock
import com.github.premnirmal.ticker.components.Injector
import com.github.premnirmal.ticker.model.FetchException
import com.github.premnirmal.ticker.model.FetchResult
import com.github.premnirmal.ticker.network.data.IQuoteNet
import com.github.premnirmal.ticker.network.data.Quote
import com.github.premnirmal.ticker.network.data.SuggestionsNet.SuggestionNet
import com.github.premnirmal.ticker.network.data.YahooQuoteNet
import com.github.premnirmal.tickerwidget.BuildConfig
import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -75,11 +75,11 @@ class StocksApi {

private suspend fun getStocksYahoo(tickerList: List<String>) = withContext(Dispatchers.IO) {
val query = tickerList.joinToString(",")
val quoteNets = yahooFinance.getStocks(query).quoteResponse!!.result
val quoteNets = yahooFinance.getStocks(query).quoteResponse.result
quoteNets
}

private fun List<IQuoteNet>.toQuoteMap(): MutableMap<String, Quote> {
private fun List<YahooQuoteNet>.toQuoteMap(): MutableMap<String, Quote> {
val quotesMap = HashMap<String, Quote>()
for (quoteNet in this) {
val quote = quoteNet.toQuote()
Expand All @@ -95,16 +95,45 @@ class StocksApi {
return quotes
}

private fun IQuoteNet.toQuote(): Quote {
val quote = Quote(this.symbol ?: "")
quote.name = this.name ?: ""
private fun YahooQuoteNet.toQuote(): Quote {
val quote = Quote(this.symbol)
quote.name = this.name
quote.lastTradePrice = this.lastTradePrice
quote.changeInPercent = this.changePercent
quote.change = this.change
quote.stockExchange = this.exchange ?: ""
quote.currencyCode = this.currency ?: "USD"
quote.annualDividendRate = this.annualDividendRate
quote.annualDividendYield = this.annualDividendYield
quote.region = this.region
quote.quoteType = this.quoteType
quote.currencyCode = this.currency
quote.exchange = this.exchange
quote.longName = this.longName
quote.gmtOffSetMilliseconds = this.gmtOffSetMilliseconds
quote.dayHigh = this.regularMarketDayHigh
quote.dayLow = this.regularMarketDayLow
quote.previousClose = this.regularMarketPreviousClose
quote.open = this.regularMarketOpen
quote.regularMarketVolume = this.regularMarketVolume
quote.trailingPE = this.trailingPE
quote.marketState = this.marketState
quote.tradeable = this.tradeable
quote.fiftyTwoWeekLowChange = this.fiftyTwoWeekLowChange
quote.fiftyTwoWeekLowChangePercent = this.fiftyTwoWeekLowChangePercent
quote.fiftyTwoWeekHighChange = this.fiftyTwoWeekHighChange
quote.fiftyTwoWeekHighChangePercent = this.fiftyTwoWeekHighChangePercent
quote.fiftyTwoWeekLow = this.fiftyTwoWeekLow
quote.fiftyTwoWeekHigh = this.fiftyTwoWeekHigh
quote.dividendDate = this.dividendDate?.times(1000)
quote.earningsTimestamp = this.earningsTimestamp?.times(1000)
quote.fiftyDayAverage = this.fiftyDayAverage
quote.fiftyDayAverageChange = this.fiftyDayAverageChange
quote.fiftyDayAverageChangePercent = this.fiftyDayAverageChangePercent
quote.twoHundredDayAverage = this.twoHundredDayAverage
quote.twoHundredDayAverageChange = this.twoHundredDayAverageChange
quote.twoHundredDayAverageChangePercent = this.twoHundredDayAverageChangePercent
quote.marketCap = this.marketCap
return quote
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface YahooFinance {
* @return A List of quotes.
*/
@GET(
"quote?format=json&fields=symbol,regularMarketPrice,regularMarketChange,regularMarketChangePercent,regularMarketTime,postMarketPrice,postMarketChange,postMarketChangePercent,postMarketTime,regularMarketVolume,shortName,currency,trailingAnnualDividendRate,trailingAnnualDividendYield"
"quote?format=json"
)
suspend fun getStocks(@Query(value = "symbols") query: String): YahooResponse
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,35 @@ data class Quote(var symbol: String = "") : Parcelable, Comparable<Quote> {
var position: Position? = null
var properties: Properties? = null

var region: String = ""
var quoteType: String = ""
var exchange: String? = null
var longName: String? = null
var gmtOffSetMilliseconds: Long = 0
var dayHigh: Float? = null
var dayLow: Float? = null
var previousClose: Float = 0.0f
var open: Float? = null
var regularMarketVolume: Long? = null
var trailingPE: Float? = 0.0f
var marketState: String = ""
var tradeable: Boolean = false
var fiftyTwoWeekLowChange: Float? = 0.0f
var fiftyTwoWeekLowChangePercent: Float? = 0.0f
var fiftyTwoWeekHighChange: Float? = 0.0f
var fiftyTwoWeekHighChangePercent: Float? = 0.0f
var fiftyTwoWeekLow: Float? = 0.0f
var fiftyTwoWeekHigh: Float? = 0.0f
var dividendDate: Long? = null
var earningsTimestamp: Long? = null
var fiftyDayAverage: Float? = 0.0f
var fiftyDayAverageChange: Float? = 0.0f
var fiftyDayAverageChangePercent: Float? = 0.0f
var twoHundredDayAverage: Float? = 0.0f
var twoHundredDayAverageChange: Float? = 0.0f
var twoHundredDayAverageChangePercent: Float? = 0.0f
var marketCap: Long? = null

val currencySymbol: String
get() = currencyCodes[currencyCode].orEmpty()

Expand Down Expand Up @@ -58,6 +87,7 @@ data class Quote(var symbol: String = "") : Parcelable, Comparable<Quote> {
}
return changeString
}

fun dividendInfo(): String {
return if (annualDividendRate <= 0f || annualDividendYield <= 0f) {
"--"
Expand All @@ -74,11 +104,14 @@ data class Quote(var symbol: String = "") : Parcelable, Comparable<Quote> {

fun priceString(): String = AppPreferences.SELECTED_DECIMAL_FORMAT.format(lastTradePrice)

fun averagePositionPrice(): String = AppPreferences.SELECTED_DECIMAL_FORMAT.format(positionPrice())
fun averagePositionPrice(): String =
AppPreferences.SELECTED_DECIMAL_FORMAT.format(positionPrice())

fun numSharesString(): String = AppPreferences.SELECTED_DECIMAL_FORMAT.format(totalPositionShares())
fun numSharesString(): String =
AppPreferences.SELECTED_DECIMAL_FORMAT.format(totalPositionShares())

fun totalSpentString(): String = AppPreferences.SELECTED_DECIMAL_FORMAT.format(totalPositionPrice())
fun totalSpentString(): String =
AppPreferences.SELECTED_DECIMAL_FORMAT.format(totalPositionPrice())

fun holdings(): Float = lastTradePrice * totalPositionShares()

Expand Down Expand Up @@ -136,7 +169,8 @@ data class Quote(var symbol: String = "") : Parcelable, Comparable<Quote> {
annualDividendYield = parcel.readFloat()
position = parcel.readParcelable(Position::class.java.classLoader)
properties = parcel.readParcelable(
Properties::class.java.classLoader)
Properties::class.java.classLoader
)
}

override fun writeToParcel(
Expand Down

This file was deleted.

Loading

0 comments on commit 78c7c98

Please sign in to comment.