如何找到 Python 数据集中的最大百分比下降? (股市)
How to find maximum percentage fall in a dataset with Python ? (stock market)
我目前正在处理股票市场分析,并试图找到一种快速算法,使我能够计算给定数据集中的最大价格跌幅,我认为这是一个值得考虑的好算法问题。因此,输入将是特定时间间隔内股票的股价,输出将是所有价格下跌的最大值。
这是一个可视化的例子,请看图片; (百分比由眼睛决定)
Stock Price Image
我粗略地表示了一些价格下降及其百分比。尽管最后一次降价是其价值的最大值,但降价 %60 的是我想要找到的那个。
提前致谢
解决方案:
您可以通过向后迭代股票价值在线性时间内完成。
您跟踪到目前为止看到的最小元素,因为最大的下降总是会到达仍然位于它之前的最小值。然后你可以计算从每个点到它前面的最小元素的相对下降,并只跟踪你找到的最大下降。
这是 Python 中的一个实现。确保您了解我在做什么以及它为什么有效,以确保它符合您所想的问题。
def getGreatestDrop(stock):
"""Calculates the greatest relative drop of a stock.
@param stock: 1-D list contianing the values of that stock
Returns a tuple with the relative drop size, the index of the start and the
index of the end of that drop.
"""
min = None # The smallest absolute value seen so far
minIndex = None # The index of the smallest absolute value smallest value
greatestDrop = None # The biggest relative drop seen so far
greatestDropStart = None # The index of the drop start
greatestDropEnd = None # The index of the drop end
# Iterating backwards through the array, starting from the last element
for index in range(len(stock)-1,-1,-1):
# Update min
if min is None or stock[index] < min:
min = stock[index]
minIndex = index
# Calculate relative drop
drop = 1-min/stock[index]
# Update greatest drop
if greatestDrop is None or drop > greatestDrop:
greatestDrop = drop
greatestDropStart = index
greatestDropEnd = minIndex
# Return values
return greatestDrop, greatestDropStart, greatestDropEnd
示例:
这是一个示例程序,我在 6 只随机生成的股票上使用了这个函数:
#!/usr/bin/env python3
import random
import numpy as np
from matplotlib import pyplot as plt
def generateRandomStock(length, volatility=1, trend=0, scale=100, lowest=500):
"""Generat
@param stock: 1-D list contianing the values of that stock
Returns a tuple with the relative drop size, the index of the start and the
index of the end of that drop.
"""
out = np.ndarray(length)
value = 0
for i in range(length):
value += volatility*(random.random()-0.5) + trend
out[i] = value
out *= scale
out -= out.min()
out += lowest
return out
def getGreatestDrop(stock):
"""Calculates the greatest relative drop of a stock.
@param stock: 1-D list contianing the values of that stock
Returns a tuple with the relative drop size, the index of the start and the
index of the end of that drop.
"""
min = None # The smallest absolute value seen so far
minIndex = None # The index of the smallest absolute value smallest value
greatestDrop = None # The biggest relative drop seen so far
greatestDropStart = None # The index of the drop start
greatestDropEnd = None # The index of the drop end
# Iterating backwards through the array, starting from the last element
for index in range(len(stock)-1,-1,-1):
# Update min
if min is None or stock[index] < min:
min = stock[index]
minIndex = index
# Calculate relative drop
drop = 1-min/stock[index]
# Update greatest drop
if greatestDrop is None or drop > greatestDrop:
greatestDrop = drop
greatestDropStart = index
greatestDropEnd = minIndex
# Return values
return greatestDrop, greatestDropStart, greatestDropEnd
if __name__ == "__main__":
# Create subplots
width = 3
height = 2
fig, axs = plt.subplots(width, height)
# Fix random seed to get the same results every time
random.seed(42)
# Draw all plots
for w in range(width):
for h in range(height):
# Generate stocks randomly
stocks = generateRandomStock(1000)
axs[w][h].plot(stocks)
# Calculate greatest drop
drop, dropStart, dropEnd = getGreatestDrop(stocks)
axs[w][h].plot([dropStart, dropEnd],[stocks[dropStart],stocks[dropEnd]], color="red")
# Set title
axs[w][h].set_title("Greatest Drop is {:.1f}% from {} to {}".format(100*drop, dropStart, dropEnd))
# Show all results
plt.show()
输出:
我目前正在处理股票市场分析,并试图找到一种快速算法,使我能够计算给定数据集中的最大价格跌幅,我认为这是一个值得考虑的好算法问题。因此,输入将是特定时间间隔内股票的股价,输出将是所有价格下跌的最大值。
这是一个可视化的例子,请看图片; (百分比由眼睛决定)
Stock Price Image
我粗略地表示了一些价格下降及其百分比。尽管最后一次降价是其价值的最大值,但降价 %60 的是我想要找到的那个。
提前致谢
解决方案:
您可以通过向后迭代股票价值在线性时间内完成。
您跟踪到目前为止看到的最小元素,因为最大的下降总是会到达仍然位于它之前的最小值。然后你可以计算从每个点到它前面的最小元素的相对下降,并只跟踪你找到的最大下降。
这是 Python 中的一个实现。确保您了解我在做什么以及它为什么有效,以确保它符合您所想的问题。
def getGreatestDrop(stock):
"""Calculates the greatest relative drop of a stock.
@param stock: 1-D list contianing the values of that stock
Returns a tuple with the relative drop size, the index of the start and the
index of the end of that drop.
"""
min = None # The smallest absolute value seen so far
minIndex = None # The index of the smallest absolute value smallest value
greatestDrop = None # The biggest relative drop seen so far
greatestDropStart = None # The index of the drop start
greatestDropEnd = None # The index of the drop end
# Iterating backwards through the array, starting from the last element
for index in range(len(stock)-1,-1,-1):
# Update min
if min is None or stock[index] < min:
min = stock[index]
minIndex = index
# Calculate relative drop
drop = 1-min/stock[index]
# Update greatest drop
if greatestDrop is None or drop > greatestDrop:
greatestDrop = drop
greatestDropStart = index
greatestDropEnd = minIndex
# Return values
return greatestDrop, greatestDropStart, greatestDropEnd
示例:
这是一个示例程序,我在 6 只随机生成的股票上使用了这个函数:
#!/usr/bin/env python3
import random
import numpy as np
from matplotlib import pyplot as plt
def generateRandomStock(length, volatility=1, trend=0, scale=100, lowest=500):
"""Generat
@param stock: 1-D list contianing the values of that stock
Returns a tuple with the relative drop size, the index of the start and the
index of the end of that drop.
"""
out = np.ndarray(length)
value = 0
for i in range(length):
value += volatility*(random.random()-0.5) + trend
out[i] = value
out *= scale
out -= out.min()
out += lowest
return out
def getGreatestDrop(stock):
"""Calculates the greatest relative drop of a stock.
@param stock: 1-D list contianing the values of that stock
Returns a tuple with the relative drop size, the index of the start and the
index of the end of that drop.
"""
min = None # The smallest absolute value seen so far
minIndex = None # The index of the smallest absolute value smallest value
greatestDrop = None # The biggest relative drop seen so far
greatestDropStart = None # The index of the drop start
greatestDropEnd = None # The index of the drop end
# Iterating backwards through the array, starting from the last element
for index in range(len(stock)-1,-1,-1):
# Update min
if min is None or stock[index] < min:
min = stock[index]
minIndex = index
# Calculate relative drop
drop = 1-min/stock[index]
# Update greatest drop
if greatestDrop is None or drop > greatestDrop:
greatestDrop = drop
greatestDropStart = index
greatestDropEnd = minIndex
# Return values
return greatestDrop, greatestDropStart, greatestDropEnd
if __name__ == "__main__":
# Create subplots
width = 3
height = 2
fig, axs = plt.subplots(width, height)
# Fix random seed to get the same results every time
random.seed(42)
# Draw all plots
for w in range(width):
for h in range(height):
# Generate stocks randomly
stocks = generateRandomStock(1000)
axs[w][h].plot(stocks)
# Calculate greatest drop
drop, dropStart, dropEnd = getGreatestDrop(stocks)
axs[w][h].plot([dropStart, dropEnd],[stocks[dropStart],stocks[dropEnd]], color="red")
# Set title
axs[w][h].set_title("Greatest Drop is {:.1f}% from {} to {}".format(100*drop, dropStart, dropEnd))
# Show all results
plt.show()
输出: