Skip to content

Commit

Permalink
Fix sorting again, and use market state for real time fetching
Browse files Browse the repository at this point in the history
  • Loading branch information
premnirmal committed Jun 18, 2022
1 parent 5788195 commit b4d4815
Show file tree
Hide file tree
Showing 13 changed files with 315 additions and 34 deletions.
278 changes: 278 additions & 0 deletions app/schemas/com.github.premnirmal.ticker.repo.QuotesDB/6.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
{
"formatVersion": 1,
"database": {
"version": 6,
"identityHash": "a9411595d733a02f3a0d29b7aba56959",
"entities": [
{
"tableName": "QuoteRow",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`symbol` TEXT NOT NULL, `name` TEXT NOT NULL, `last_trade_price` REAL NOT NULL, `change_percent` REAL NOT NULL, `change` REAL NOT NULL, `exchange` TEXT NOT NULL, `currency` TEXT NOT NULL, `is_post_market` INTEGER NOT NULL, `annual_dividend_rate` REAL NOT NULL, `annual_dividend_yield` REAL NOT NULL, `dayHigh` REAL, `dayLow` REAL, `previousClose` REAL NOT NULL, `open` REAL, `regularMarketVolume` REAL, `peRatio` REAL, `fiftyTwoWeekLowChange` REAL, `fiftyTwoWeekLowChangePercent` REAL, `fiftyTwoWeekHighChange` REAL, `fiftyTwoWeekHighChangePercent` REAL, `fiftyTwoWeekLow` REAL, `fiftyTwoWeekHigh` REAL, `dividendDate` REAL, `earningsDate` REAL, `marketCap` REAL, `isTradeable` INTEGER, `isTriggerable` INTEGER, `marketState` TEXT, PRIMARY KEY(`symbol`))",
"fields": [
{
"fieldPath": "symbol",
"columnName": "symbol",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "lastTradePrice",
"columnName": "last_trade_price",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "changeInPercent",
"columnName": "change_percent",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "change",
"columnName": "change",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "stockExchange",
"columnName": "exchange",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "currency",
"columnName": "currency",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "isPostMarket",
"columnName": "is_post_market",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "annualDividendRate",
"columnName": "annual_dividend_rate",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "annualDividendYield",
"columnName": "annual_dividend_yield",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "dayHigh",
"columnName": "dayHigh",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "dayLow",
"columnName": "dayLow",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "previousClose",
"columnName": "previousClose",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "open",
"columnName": "open",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "regularMarketVolume",
"columnName": "regularMarketVolume",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "peRatio",
"columnName": "peRatio",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "fiftyTwoWeekLowChange",
"columnName": "fiftyTwoWeekLowChange",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "fiftyTwoWeekLowChangePercent",
"columnName": "fiftyTwoWeekLowChangePercent",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "fiftyTwoWeekHighChange",
"columnName": "fiftyTwoWeekHighChange",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "fiftyTwoWeekHighChangePercent",
"columnName": "fiftyTwoWeekHighChangePercent",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "fiftyTwoWeekLow",
"columnName": "fiftyTwoWeekLow",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "fiftyTwoWeekHigh",
"columnName": "fiftyTwoWeekHigh",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "dividendDate",
"columnName": "dividendDate",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "earningsDate",
"columnName": "earningsDate",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "marketCap",
"columnName": "marketCap",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "isTradeable",
"columnName": "isTradeable",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "isTriggerable",
"columnName": "isTriggerable",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "marketState",
"columnName": "marketState",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"symbol"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "HoldingRow",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `quote_symbol` TEXT NOT NULL, `shares` REAL NOT NULL, `price` REAL NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "quoteSymbol",
"columnName": "quote_symbol",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "shares",
"columnName": "shares",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "price",
"columnName": "price",
"affinity": "REAL",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "PropertiesRow",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `properties_quote_symbol` TEXT NOT NULL, `notes` TEXT NOT NULL, `alert_above` REAL NOT NULL, `alert_below` REAL NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "quoteSymbol",
"columnName": "properties_quote_symbol",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "notes",
"columnName": "notes",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "alertAbove",
"columnName": "alert_above",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "alertBelow",
"columnName": "alert_below",
"affinity": "REAL",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a9411595d733a02f3a0d29b7aba56959')"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import org.threeten.bp.format.FormatStyle.MEDIUM
import java.io.File
import java.text.DecimalFormat
import java.text.Format
import java.util.Random
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.random.Random

/**
* Created by premnirmal on 2/26/16.
Expand All @@ -28,9 +28,6 @@ class AppPreferences {
@Inject internal lateinit var sharedPreferences: SharedPreferences
@Inject internal lateinit var clock: AppClock

// Not using clock here because this doesn't need a specific time.
private val random = Random(System.currentTimeMillis())

init {
Injector.appComponent.inject(this)
INSTANCE = this
Expand Down Expand Up @@ -132,7 +129,7 @@ class AppPreferences {
fun hasUserAlreadyRated() = sharedPreferences.getBoolean(DID_RATE, false)

fun shouldPromptRate(): Boolean = // if the user hasn't rated, ask them again but not too often.
!hasUserAlreadyRated() && (random.nextInt() % 10 == 0)
!hasUserAlreadyRated() && (Random.nextInt() % 10 == 0)

fun clock(): AppClock = clock

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.github.premnirmal.ticker.repo.migrations.MIGRATION_1_2
import com.github.premnirmal.ticker.repo.migrations.MIGRATION_2_3
import com.github.premnirmal.ticker.repo.migrations.MIGRATION_3_4
import com.github.premnirmal.ticker.repo.migrations.MIGRATION_4_5
import com.github.premnirmal.ticker.repo.migrations.MIGRATION_5_6
import com.github.premnirmal.ticker.widget.WidgetDataProvider
import dagger.Module
import dagger.Provides
Expand Down Expand Up @@ -67,6 +68,7 @@ class AppModule(private val app: StocksApp) {
.addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4)
.addMigrations(MIGRATION_4_5)
.addMigrations(MIGRATION_5_6)
.build()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ data class Quote constructor(

val priceFormat: PriceFormat
get() = currencyCodes[currencyCode]?.let {
PriceFormat(currencyCode = currencyCode, symbol = it, prefix = prefixCurrencies[it] ?: true)
PriceFormat(currencyCode = currencyCode, symbol = it, prefix = prefixCurrencies[currencyCode] ?: true)
} ?: PriceFormat(currencyCode, currencyCode)

fun hasAlertAbove(): Boolean =
Expand Down Expand Up @@ -158,6 +158,9 @@ data class Quote constructor(
return "$symbol $name"
}

val isMarketOpen: Boolean
get() = "CLOSED" != marketState.uppercase()

override operator fun compareTo(other: Quote): Int =
other.changeInPercent.compareTo(changeInPercent)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.transform
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject

class QuoteDetailViewModel(application: Application) : AndroidViewModel(application) {
Expand Down Expand Up @@ -155,14 +156,14 @@ class QuoteDetailViewModel(application: Application) : AndroidViewModel(applicat
) {
viewModelScope.launch {
do {
var triggerable = false
var isMarketOpen = false
val result = stocksProvider.fetchStock(symbol, allowCache = false)
if (result.wasSuccessful) {
triggerable = result.data.triggerable
isMarketOpen = result.data.isMarketOpen
_quote.emit(result)
}
delay(IStocksProvider.DEFAULT_INTERVAL_MS)
} while (isActive && result.wasSuccessful && triggerable)
} while (isActive && result.wasSuccessful && isMarketOpen)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,9 @@ class PortfolioFragment : BaseFragment(), ChildFragment, QuoteClickListener, OnS
view_flipper.displayedChild = 1
}
viewModel.portfolio.observe(viewLifecycleOwner) {
stocksAdapter.refresh(it)
}
lifecycleScope.launch {
viewModel.fetchPortfolioInRealTime().collect {
stocksAdapter.refresh(it)
}
stocksAdapter.refresh()
}
viewModel.fetchPortfolioInRealTime()
lifecycleScope.launch {
widgetData.autoSortEnabled.collect {
update()
Expand Down
Loading

0 comments on commit b4d4815

Please sign in to comment.