【问题标题】:Iterating Through Timeseries One Day at a Time一次一天地遍历时间序列
【发布时间】:2017-03-06 17:00:39
【问题描述】:

大量修改:

好的,所以我有一个分钟级别的时间序列数据框。例如,这个数据框是一年的数据。我正在尝试创建一个分析模型,该模型将每天迭代这些数据。

该函数将: 1) 从数据框中切出一天的数据。 2) 创建每日切片的 30 分钟(一天的前 30 分钟)子切片。 3) 通过函数的分析部分传递来自两个切片的数据。 4)附加到新的数据框。 5) 继续迭代直到完成。

数据框格式如下:

                           open_price high  low   close_price volume     price
2015-01-06 14:31:00+00:00   46.3800 46.440  46.29   46.380  560221.0    46.380
2015-01-06 14:32:00+00:00   46.3800 46.400  46.30   46.390  52959.0     46.390
2015-01-06 14:33:00+00:00   46.3900 46.495  46.36   46.470  100100.0    46.470
2015-01-06 14:34:00+00:00   46.4751 46.580  46.41   46.575  85615.0     46.575
2015-01-06 14:35:00+00:00   46.5800 46.610  46.53   46.537  78175.0     46.537

在我看来,pandas datetimeindex 功能是完成这项任务的最佳方式,但我不知道从哪里开始。

(1) 似乎我可以使用 .rollforward 功能,从 df 开始日期/时间开始,并在每次迭代中前滚一天。

(2) 使用 df.loc[mask] 创建子切片。

我很确定我可以在 (2) 之后弄清楚,但我对时间序列分析或 pandas datetimeindex 功能又不是很熟悉。

最终数据框:

              high     low   retrace  time
2015-01-06    46.440  46.29  True     47
2015-01-07    46.400  46.30  True     138
2015-01-08    46.495  46.36  False    NaN
2015-01-09    46.580  46.41  True     95
2015-01-10    46.610  46.53  False    NaN

最高价 = 一天前 30 分钟的最高价

低 = 一天中前 30 分钟的低点

Retrace = 布尔值,如果价格在前 30 分钟后的一天中某个时间点返回到开盘价。

时间 = 回溯所需的时间(分钟)。

这是我的代码似乎可以工作(感谢大家的帮助!):

sample = msft_prices.ix[s_date:e_date]
sample = sample.resample('D').mean() 
sample = sample.dropna()
sample = sample.index.strftime('%Y-%m-%d')
ORTDF = pd.DataFrame()
ORDF = pd.DataFrame()
list1 = []
list2 = []
def hi_lo(prices):

        for i in sample:
            list1 = []
            if i in prices.index:

                ORTDF = prices[i+' 14:30':i+' 15:00']
                ORH = max(ORTDF['high']) #integer value
                ORHK = ORTDF['high'].idxmax()
                ORL = min(ORTDF['low']) #integer value
                ORLK = ORTDF['low'].idxmin()
                list1.append(ORH)
                list1.append(ORL)



                if ORHK < ORLK:
                    dailydf = prices[i+' 14:30':i+' 21:00']
                    if max(dailydf['high']) > ORH:
                        ORDH = max(dailydf['high'])
                        ORDHK = dailydf['high'].idxmax()
                        touched = 1
                        time_to_touch = ORDHK - ORHK
                        time_to_touch = time_to_touch.total_seconds() / 60
                        list1.append(touched)
                        list1.append(time_to_touch)
                        list2.append(list1)
                    else:
                        touched = 0
                        list1.append(touched)
                        list1.append('NaN')
                        list2.append(list1)
                elif ORHK > ORLK:
                    dailydf = prices[i+' 14:30':i+' 21:00']
                    if min(dailydf['low']) < ORL:
                        ORDL = min(dailydf['low'])
                        ORDLK = dailydf['low'].idxmin()
                        touched = 1
                        time_to_touch = ORDLK - ORLK
                        time_to_touch = time_to_touch.total_seconds() / 60
                        list1.append(touched)
                        list1.append(time_to_touch)
                        list2.append(list1)
                    else:
                        touched = 0
                        list1.append(touched)
                        list1.append('NaN')
                        list2.append(list1)


            else:
                pass


        ORDF = pd.DataFrame(list2, columns=['High', 'Low', 'Retraced', 'Time']).set_index([sample])
        return ORDF

这可能不是最优雅的方式,但是,嘿,它有效!

【问题讨论】:

  • 提示:不要使用行话!这里的大多数人都不会理解金融术语。目前还不清楚您的问题是什么。
  • 提供一个最小的、完整的和经过验证的示例会更好地为您服务。 stackoverflow.com/help/mcve
  • 嗯...我应该从头开始吗?
  • 澄清:1)我有一年或多年的一分钟时间序列数据。 2)我希望按日期切片,然后按 30 分钟切片。 3) 在 30 分钟内分析数据 4) 提取分析数据并附加到新的 df。我正在尝试查找如何使用 pandas 日期功能来执行此操作的示例,因为我使用简单索引的尝试正在失败。
  • @supernoob:编辑您的问题以包含示例数据框(只需几行即可)和您的预期输出。 (另外,请删除财务术语,它与您在此处询问的内容无关)。您肯定希望有一个具有 Datatime 类型的索引/列,然后根据它而不是索引号进行选择。

标签: python pandas dataframe time-series datetimeindex


【解决方案1】:

阅读the docs 以获得一般参考

设置(下次请在问题中自行提供!):

dates = pd.to_datetime(['19 November 2010 9:01', '19 November 2010 9:02', '19 November 2010 9:03',
                       '20 November 2010 9:05', '20 November 2010 9:06', '20 November 2010 9:07'])
df = pd.DataFrame({'low_price': [1.2, 1.8, 1.21, 2., 4., 1.201],  
                  'high_price': [3., 1.8, 1.21, 4., 4.01, 1.201]}, index=dates)
df

                    high_price  low_price
2010-11-19 09:01:00     3.000   1.200
2010-11-19 09:02:00     1.800   1.800
2010-11-19 09:03:00     1.210   1.210
2010-11-20 09:05:00     4.000   2.000
2010-11-20 09:06:00     4.010   4.000
2010-11-20 09:07:00     1.201   1.201

我将按天分组,然后每天应用一个函数来计算是否有回溯以及它发生的时间段。您的问题不清楚要操作哪一列,或者说“价格相同”的容忍度是多少,所以我将它们作为选项

def retrace_per_day(day, col='high_price', epsilon=0.5):
    """take day data and returns whether there was a retrace.
    If yes, return 1 and the minute in which it did.
    Otherwise return 0 and np.nan"""
    cond = (np.abs(day[col] - day[col][0]) < epsilon)
    cond_index = cond[cond].index
    if len(cond_index) > 1:
        retrace, period = 1, cond_index[1]
    else:
        retrace, period = 0, np.nan
    return pd.Series({'retrace': retrace, 'period' : period})

df.groupby(pd.TimeGrouper('1D')).apply(retrace_per_day)

           period   retrace
2010-11-19  NaN     0.0
2010-11-20  2010-11-20 09:06:00     1.0

如果需要,您可以使用它合并回原始数据框。

【讨论】:

  • 你的例子很好,但我需要返回值,而不是不幸的数据框(如果我的方法是正确的)。具体来说,我需要找到前 30 分钟内的最高价和最低价,它发生的顺序,然后找出价格是否从当天开始回撤。所以函数看起来像这样:在一天的前 30 分钟内识别高低,将两者都附加到 list1。识别序列,如果价格回溯返回“真”或“假”,则附加到 list1。查找一天开始和回撤之间的时间差。附加到列表 1。将 list1 附加到 list2。开始新的迭代。
  • @supenoob:我不知道在这种情况下“回溯”是什么意思。您能否将(简化的)预期输出放在您的问题上?我们不需要了解所有步骤,只需要了解您需要组合哪些部分。您可能不需要执行此附加并分隔到列表中。在我看来,您只需要创建一个名为“回撤”的新变量,例如,每天价格开始上涨的那一刻“回溯”(无论这意味着什么!),否则为零。是这样吗?这可以通过groupby-apply 组合来实现
  • 所有迭代完成后,从 list2 构建数据框。
  • '回撤'在这种情况下意味着价格在一天开始时回到开盘价。因此,如果股票开盘价为 50 美元,下跌了一点,但在当天的某个时间点又回到了 50 美元,那么它就完全回撤了。我需要确定这两点之间的时间增量。我将研究 groupby - 应用组合。
  • @supernoob:那么最终结果是什么?每天一个变量,表示股票“回撤”需要多少小时/分钟? (第 1 天:21 分钟,第 2 天:5 分钟等)如果是这样,我想我们终于找到了具体问题:) 如果这是您问题的重点,请编辑您的问题,我想我可能可以回答。
猜你喜欢
  • 2015-10-14
  • 1970-01-01
  • 2023-01-04
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-23
  • 1970-01-01
  • 2017-04-12
相关资源
最近更新 更多