有没有更好的方法来改进我的股票市场下跌算法



我正在计算每只股票的提款。提款定义为

提款是投资、交易账户或基金在特定时期内的峰谷跌幅。

简单地说,跌幅是指股票从峰值暴跌到低谷的幅度。除此之外,当峰值价格在稍后某个时候恢复时,就会记录到下跌。

为了计算缩编,我将分解为2个点

  1. 查找峰值(价格大于相邻两天的价格(和波谷(价格低于相邻两天的价格(

  2. 当峰值的价格已经恢复时,该峰值、低谷就变成了下跌

这里有一个股票报价的例子:

data class Quote(val price: Int, val date: String)
...
//example of quote     
Quote(price:1, date:"20080102"),
Quote(price:2, date:"20080103"),
Quote(price:3, date:"20080104"),
Quote(price:1, date:"20080107"),
Quote(price:2, date:"20080108"),
Quote(price:3, date:"20080109"),
Quote(price:2, date:"20080110"),
Quote(price:4, date:"20080111"),
Quote(price:5, date:"20080114"),
Quote(price:6, date:"20080115"),
Quote(price:7, date:"20080116"),
Quote(price:8, date:"20080117"),
Quote(price:9, date:"20080118"),
Quote(price:7, date:"20080122"),
Quote(price:6, date:"20080123"),
Quote(price:8, date:"20080124"),
Quote(price:11,date:"20080125"),

list of drawdowns by date: 
(peak: "20080104", trough:"20080107", daysTakenToRecover: 3),
(peak: "20080109", trough:"20080110", daysTakenToRecover: 2),
(peak: "20080118", trough:"20080123", daysTakenToRecover: 4),

以下是为测试用例编写的内容:

class Drawdown {
var peak: Quote? = null
var trough: Quote? = null
var recovered: Quote? = null
var percentage: Double? = null
var daysToRecover: String? = null
}
data class Quote(
val price: Double,
val date: String
)

class Test {
private fun findDrawdowns(): List<Drawdown> {
val list = mutableListOf<Drawdown>()
var peak: Quote? = null
var trough: Quote? = null
var recovered: Quote? = null
for (quotation in quotations) {
val currentIdx = quotations.indexOf(quotation)
if (currentIdx in 1 until quotations.size - 1) {
val prevClosing = quotations[currentIdx - 1].price
val nextClosing = quotations[currentIdx + 1].price
val closing = quotation.price
recovered = when {
peak == null -> null
closing >= peak.price -> {
if (peak.date != quotation.date) {
//can possibly be new peak
Quote(closing, quotation.date)
} else null
}
else -> null
}
peak = if (closing > prevClosing && closing > nextClosing) {
if ((peak == null || peak.price < closing) && recovered == null) {
Quote(closing, quotation.date)
} else peak
} else peak
trough = if (closing < prevClosing && closing < nextClosing) {
if (trough == null || trough.price > closing) {
Quote(closing, quotation.date)
} else trough
} else trough

if (recovered != null) {
val drawdown = Drawdown()
val percentage = (peak!!.price - trough!!.price) / peak.price
drawdown.peak = peak
drawdown.trough = trough
drawdown.recovered = recovered
drawdown.percentage = percentage
drawdown.daysToRecover =
ChronoUnit.DAYS.between(
LocalDate.of(
peak.date.substring(0, 4).toInt(),
peak.date.substring(4, 6).toInt(),
peak.date.substring(6, 8).toInt()
),
LocalDate.of(
recovered.date.substring(0, 4).toInt(),
recovered.date.substring(4, 6).toInt(),
recovered.date.substring(6, 8).toInt()
).plusDays(1)
).toString()
list += drawdown
peak = if (closing > prevClosing && closing > nextClosing) {
Quote(recovered.price, recovered.date)
} else {
null
}
trough = null
recovered = null
}
}
}
val drawdown = Drawdown()
val percentage = (peak!!.price - trough!!.price) / peak.price
drawdown.peak = peak
drawdown.trough = trough
drawdown.recovered = recovered
drawdown.percentage = percentage
list += drawdown
return list
}

对于那些想在github中阅读我的代码的人,这里有一个要点:

在Kotlin找到提款,点击我!!!

我运行了一些测试用例,结果显示没有错误。

到目前为止,我相信这需要一个O(n(,但我想让它更有效率。

我该如何改进?欢迎任何意见和想法!

谢谢你,新年快乐。

有两点

  1. 不幸的是,当前的复杂性是O(N^2(
for (quotation in quotations) {
val currentIdx = quotations.indexOf(quotation)
....

你有一个遍历所有报价的循环,在其中你可以找到每个报价的索引。查找索引是O(N(-查看indexOf文档。所以总的复杂度将是O(N^2(

但是你可以很容易地把它固定为O(N(。只需将foreach循环+indexOf替换为forEachIndexed,例如:

quotations.forEachIndexed { index, quote ->
// TODO
}
  1. 我认为不可能使它比O(N(更快,因为你需要检查每个报价

最新更新