Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for options chain snapshot #64

Merged
merged 1 commit into from
Jan 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package io.polygon.kotlin.sdk.sample

import com.tylerthrailkill.helpers.prettyprint.pp
import io.ktor.client.plugins.*
import io.polygon.kotlin.sdk.rest.ComparisonQueryFilterParameters
import io.polygon.kotlin.sdk.DefaultOkHttpClientProvider
import io.polygon.kotlin.sdk.HttpClientProvider
import io.polygon.kotlin.sdk.rest.*
Expand All @@ -12,6 +11,7 @@ import io.polygon.kotlin.sdk.rest.experimental.ExperimentalAPI
import io.polygon.kotlin.sdk.rest.experimental.FinancialsParameters
import io.polygon.kotlin.sdk.rest.forex.HistoricTicksParameters
import io.polygon.kotlin.sdk.rest.forex.RealTimeConversionParameters
import io.polygon.kotlin.sdk.rest.options.SnapshotChainParameters
import io.polygon.kotlin.sdk.rest.reference.*
import io.polygon.kotlin.sdk.rest.stocks.GainersOrLosersDirection
import io.polygon.kotlin.sdk.rest.stocks.HistoricQuotesParameters
Expand Down Expand Up @@ -141,12 +141,25 @@ fun supportedTickersSample(polygonClient: PolygonRestClient) {

fun optionsContractsSample(polygonClient: PolygonRestClient) {
println("O:EVRI240119C00002500 contract details:")
polygonClient.referenceClient.getOptionsContractDetailsBlocking("O:EVRI240119C00002500", OptionsContractDetailsParameters()).pp()
polygonClient.referenceClient.getOptionsContractDetailsBlocking(
"O:EVRI240119C00002500",
OptionsContractDetailsParameters()
).pp()

println("AAPL contracts:")
polygonClient.referenceClient
.getOptionsContractsBlocking(OptionsContractsParameters(underlyingTicker = ComparisonQueryFilterParameters.equal("AAPL")))
.getOptionsContractsBlocking(
OptionsContractsParameters(
underlyingTicker = ComparisonQueryFilterParameters.equal(
"AAPL"
)
)
)
.pp()

println("list contracts: ")
polygonClient.referenceClient.listOptionsContracts(OptionsContractsParameters(limit = 5))
.asSequence().take(5).forEach { println("got an options contract: ${it.ticker}") }
}

fun tickerTypesSample(polygonClient: PolygonRestClient) {
Expand All @@ -163,13 +176,21 @@ fun tickerNewsSample(polygonClient: PolygonRestClient) {
println("Redfin news:")
val params = TickerNewsParametersV2(ticker = ComparisonQueryFilterParameters.equal("RDFN"), limit = 2)
polygonClient.referenceClient.getTickerNewsBlockingV2(params).pp()

println("list news:")
polygonClient.referenceClient.listTickerNewsV2(params)
.asSequence().take(10).forEach { println("news article: ${it.articleUrl}") }
}

fun splitsSample(polygonClient: PolygonRestClient) {
println("Apple splits:")
polygonClient.referenceClient
.getSplitsBlocking(SplitsParameters(ticker = ComparisonQueryFilterParameters.equal("AAPL")))
.pp()

println("list recent splits:")
polygonClient.referenceClient.listSplits(SplitsParameters(limit = 5))
.asSequence().take(15).forEach { println("split from ${it.executionDate}") }
}


Expand All @@ -189,13 +210,21 @@ fun dividendsSample(polygonClient: PolygonRestClient) {
limit = 1,
)
).pp()

println("15 most recent dividends")
polygonClient.referenceClient.listDividends(DividendsParameters(limit = 5))
.asSequence().take(15).forEach { println("got a dividend from ${it.exDividendDate}") }
}

@OptIn(ExperimentalAPI::class)
fun financialsSample(polygonClient: PolygonRestClient) {
println("RDFN financials")

@OptIn(ExperimentalAPI::class)
polygonClient.experimentalClient.getFinancialsBlocking(FinancialsParameters(ticker = "RDFN")).pp()
polygonClient.experimentalClient.listFinancials(FinancialsParameters(limit = 5))
.asSequence()
.take(15)
.forEach { println("got financials from ${it.sourceFilingURL}") }
}

fun marketStatusesSample(polygonClient: PolygonRestClient) {
Expand Down Expand Up @@ -243,6 +272,8 @@ fun dailyOpenCloseSample(polygonClient: PolygonRestClient) {
fun conditionsSample(polygonClient: PolygonRestClient) {
println("Conditions:")
polygonClient.referenceClient.getConditionsBlocking(ConditionsParameters()).pp()
polygonClient.referenceClient.listConditions(ConditionsParameters(limit = 5))
.asSequence().take(15).forEach { println("got condition #${it.id}") }
}

fun snapshotAllTickersSample(polygonClient: PolygonRestClient) {
Expand All @@ -265,6 +296,15 @@ fun optionsSnapshotSample(polygonClient: PolygonRestClient) {
polygonClient.optionsClient.getSnapshotBlocking("AAPL", "O:AAPL230616C00150000").pp()
}

fun optionsSnapshotChainSample(polygonClient: PolygonRestClient) {
print("RDFN options snapshots:")
polygonClient.optionsClient.getSnapshotChainBlocking("AAPL", SnapshotChainParameters()).pp()
polygonClient.optionsClient.listSnapshotChain("AA", SnapshotChainParameters(limit = 5))
.asSequence()
.take(15)
.forEach { println(it.details?.ticker ?: "UNKNOWN!") }
}

fun previousCloseSample(polygonClient: PolygonRestClient) {
println("RDFN Prev close:")
polygonClient.stocksClient.getPreviousCloseBlocking("RDFN", true).pp()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ internal constructor(internal val polygonClient: PolygonRestClient) {
fun listFinancials(params: FinancialsParameters, vararg opts: PolygonRestOption): RequestIterator<Financials> =
RequestIterator(
{ getFinancialsBlocking(params, *opts) },
polygonClient.requestIteratorFetch(*opts)
polygonClient.requestIteratorFetch<FinancialsResponse>(*opts)
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import io.polygon.kotlin.sdk.ext.coroutineToRestCallback
import io.polygon.kotlin.sdk.rest.PolygonRestApiCallback
import io.polygon.kotlin.sdk.rest.PolygonRestClient
import io.polygon.kotlin.sdk.rest.PolygonRestOption
import io.polygon.kotlin.sdk.rest.RequestIterator
import io.polygon.kotlin.sdk.rest.reference.PolygonReferenceClient
import kotlinx.coroutines.runBlocking
import javax.management.monitor.StringMonitor

/**
* Client for Polygon.io's Options pricing data RESTful APIs.
Expand Down Expand Up @@ -39,4 +41,43 @@ internal constructor(internal val polygonClient: PolygonRestClient) {
) =
coroutineToRestCallback(callback, { getSnapshot(underlyingAsset, contract, *opts) })

/**
* Get the snapshot of all options contracts for an underlying ticker.
*
* API Doc: https://polygon.io/docs/options/get_v3_snapshot_options__underlyingasset___optioncontract
*/
@SafeVarargs
fun getSnapshotChainBlocking(
underlyingAsset: String,
params: SnapshotChainParameters,
vararg opts: PolygonRestOption
): SnapshotChainResponse =
runBlocking { getSnapshotChain(underlyingAsset, params, *opts) }

/** See [getSnapshotChainBlocking] */
@SafeVarargs
fun getSnapshotChain(
underlyingAsset: String,
params: SnapshotChainParameters,
callback: PolygonRestApiCallback<SnapshotChainResponse>,
vararg opts: PolygonRestOption
) =
coroutineToRestCallback(callback, { getSnapshotChain(underlyingAsset, params, *opts) })

/**
* Get an iterator to iterate through all pages of results for the given parameters.
*
* See [getSnapshotChainBlocking] if you instead need to get exactly one page of results.
* See section "Pagination" in the README for more details on iterators.
*/
@SafeVarargs
fun listSnapshotChain(
underlyingAsset: String,
params: SnapshotChainParameters,
vararg opts: PolygonRestOption
): RequestIterator<Snapshot> =
RequestIterator(
{ getSnapshotChainBlocking(underlyingAsset, params, *opts) },
polygonClient.requestIteratorFetch<SnapshotChainResponse>(*opts)
)
}
66 changes: 66 additions & 0 deletions src/main/kotlin/io/polygon/kotlin/sdk/rest/options/Snapshots.kt
Original file line number Diff line number Diff line change
@@ -1,25 +1,91 @@
package io.polygon.kotlin.sdk.rest.options

import com.thinkinglogic.builder.annotation.Builder
import io.ktor.http.*
import io.polygon.kotlin.sdk.rest.ComparisonQueryFilterParameters
import io.polygon.kotlin.sdk.rest.Paginatable
import io.polygon.kotlin.sdk.rest.PolygonRestOption
import io.polygon.kotlin.sdk.rest.applyComparisonQueryFilterParameters
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

/** See [PolygonOptionsClient.getSnapshotBlocking] */
@SafeVarargs
suspend fun PolygonOptionsClient.getSnapshot(
underlyingAsset: String,
contract: String,
vararg opts: PolygonRestOption
): SnapshotResponse =
polygonClient.fetchResult({ path("v3", "snapshot", "options", underlyingAsset, contract) }, *opts)

@SafeVarargs
suspend fun PolygonOptionsClient.getSnapshotChain(
underlyingAsset: String,
params: SnapshotChainParameters,
vararg opts: PolygonRestOption
): SnapshotChainResponse =
polygonClient.fetchResult({
path("v3", "snapshot", "options", underlyingAsset)

applyComparisonQueryFilterParameters("strike_price", params.strikePrice)
applyComparisonQueryFilterParameters("expiration_date", params.expirationDate)
params.contractType?.let { parameters["contract_type"] = it }
params.order?.let { parameters["order"] = it }
params.limit?.let { parameters["limit"] = it.toString() }
params.sort?.let { parameters["sort"] = it }

}, *opts)

@Builder
data class SnapshotChainParameters(

/**
* Query by strike price of the contract.
*/
val strikePrice: ComparisonQueryFilterParameters<Double>? = null,

/**
* Query by expiration date of the contract with date format YYYY-MM-DD.
*/
val expirationDate: ComparisonQueryFilterParameters<String>? = null,

/**
* Query by the type of contract. 'call' or 'put'.
*/
val contractType: String? = null,

/**
* Order results based on the sort field.
* Can be "asc" or "desc"
*/
val order: String? = null,

/**
* Limit the number of results returned, default is 10 and max is 1000.
*/
val limit: Int? = null,

/**
* Field used for ordering. See docs for valid fields
*/
val sort: String? = null
)

@Serializable
data class SnapshotResponse(
val status: String? = null,
@SerialName("request_id") val requestId: String? = null,
val results: Snapshot? = null,
)

@Serializable
data class SnapshotChainResponse(
val status: String? = null,
@SerialName("request_id") val requestId: String? = null,
@SerialName("next_url") override val nextUrl: String? = null,
override val results: List<Snapshot> = emptyList()
) : Paginatable<Snapshot>

@Serializable
data class Snapshot(
@SerialName("break_even_price") val breakEvenPrice: Double? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ internal constructor(internal val polygonClient: PolygonRestClient) {
): RequestIterator<OptionsContract> =
RequestIterator(
{ getOptionsContractsBlocking(params, *opts) },
polygonClient.requestIteratorFetch(*opts)
polygonClient.requestIteratorFetch<OptionsContractsResponse>(*opts)
)

/**
Expand Down Expand Up @@ -255,7 +255,7 @@ internal constructor(internal val polygonClient: PolygonRestClient) {
fun listTickerNewsV2(params: TickerNewsParametersV2, vararg opts: PolygonRestOption): RequestIterator<TickerNews> =
RequestIterator(
{ getTickerNewsBlockingV2(params, *opts) },
polygonClient.requestIteratorFetch(*opts)
polygonClient.requestIteratorFetch<TickerNewsResponse>(*opts)
)

/**
Expand Down Expand Up @@ -341,7 +341,7 @@ internal constructor(internal val polygonClient: PolygonRestClient) {
fun listSplits(params: SplitsParameters, vararg opts: PolygonRestOption): RequestIterator<Split> =
RequestIterator(
{ getSplitsBlocking(params, *opts) },
polygonClient.requestIteratorFetch(*opts)
polygonClient.requestIteratorFetch<SplitsResponse>(*opts)
)

/**
Expand Down Expand Up @@ -393,7 +393,7 @@ internal constructor(internal val polygonClient: PolygonRestClient) {
fun listDividends(params: DividendsParameters, vararg opts: PolygonRestOption): RequestIterator<Dividend> =
RequestIterator(
{ getDividendsBlocking(params, *opts) },
polygonClient.requestIteratorFetch(*opts)
polygonClient.requestIteratorFetch<DividendsResponse>(*opts)
)

/**
Expand Down Expand Up @@ -481,7 +481,7 @@ internal constructor(internal val polygonClient: PolygonRestClient) {
fun listConditions(params: ConditionsParameters, vararg opts: PolygonRestOption): RequestIterator<Condition> =
RequestIterator(
{ getConditionsBlocking(params, *opts) },
polygonClient.requestIteratorFetch(*opts)
polygonClient.requestIteratorFetch<ConditionsResponse>(*opts)
)

/**
Expand Down