notes_works/new notes/freqtrade pandas 矢量化 Dataframe.md
2025-04-10 11:13:22 +08:00

7.2 KiB
Raw Blame History

date tags title
2025-04-10 11:01:28
策略
量化
freqtrade

😯: https://www.freqtrade.io/en/stable/strategy-customization/这个页面里的内容:Dataframe¶Freqtrade

uses pandas to store/provide the candlestick (OHLCV) data. Pandas is a great library developed for processing large amounts of data in tabular format.Each row in a dataframe corresponds to one candle on a chart, with the latest complete candle always being the last in the dataframe (sorted by date).

If we were to look at the first few rows of the main dataframe using the pandas head() function, we would see:> dataframe.head() 

date open high low close volume 0 2021-11-09 23:25:00+00:00 67279.67 67321.84 67255.01 67300.97 44.62253 1 2021-11-09 23:30:00+00:00 67300.97 67301.34 67183.03 67187.01 61.38076 2 2021-11-09 23:35:00+00:00 67187.02 67187.02 67031.93 67123.81 113.42728 3 2021-11-09 23:40:00+00:00 67123.80 67222.40 67080.33 67160.48 78.96008 4 2021-11-09 23:45:00+00:00 67160.48 67160.48 66901.26 66943.37 111.39292 

A dataframe is a table where columns are not single values, but a series of data values. As such, simple python comparisons like the following will not work:

if dataframe['rsi'] > 30:
    dataframe['enter_long'] = 1

The above section will fail with The truth value of a Series is ambiguous [...].This must instead be written in a pandas-compatible way, so the operation is performed across the whole dataframe, i.e. vectorisation.


dataframe.loc[
    (dataframe['rsi'] > 30)
, 'enter_long'] = 1

With this section, you have a new column in your dataframe, which has 1 assigned whenever RSI is above 30.Freqtrade uses this new column as an entry signal, where it is assumed that a trade will subsequently open on the next open candle.Pandas provides fast ways to calculate metrics, i.e. "vectorisation". To benefit from this speed, it is advised to not use loops, but use vectorized methods instead.Vectorized operations perform calculations across the whole range of data and are therefore, compared to looping through each row, a lot faster when calculating indicators

请帮我解释一下,没看懂


我来帮你逐步解释这段内容,这部分是关于 Freqtrade一个开源的加密货币交易框架如何使用 Pandas 数据框架Dataframe来处理和分析K线图数据OHLCV: 开盘价、最高价、最低价、收盘价、成交量)。这段文档主要是讲如何在 Freqtrade 中操作数据,并编写交易策略时的一些注意事项。以下是逐步拆解和解释:


  1. 什么是 Dataframe
  • 定义Freqtrade 使用 Python 的 Pandas 库来存储和处理K线数据。Pandas 是一个强大的数据处理工具,特别适合处理表格形式的大量数据。

  • K线数据在交易中每一根K线蜡烛图表示一段时间内的价格波动包括开盘价open、最高价high、最低价low、收盘价close和成交量volume。这些数据被存储在 Dataframe 中。

  • 结构Dataframe 是一个表格每一行代表一根K线按时间排序最后一行是最近完成的K线。

例子:

                       date      open      high       low     close     volume
0 2021-11-09 23:25:00+00:00  67279.67  67321.84  67255.01  67300.97   44.62253
1 2021-11-09 23:30:00+00:00  67300.97  67301.34  67183.03  67187.01   61.38076
  • 每一行是一个5分钟的K线从时间戳可以看出

  • date, open, high, low, close, volume分别表示时间和对应的价格/成交量数据。


  1. 为什么普通的 Python 比较不行?
  • 问题:在普通的 Python 中,你可能会写这样的代码来判断条件:

    python

    if dataframe['rsi'] > 30:
        dataframe['enter_long'] = 1
    

    这意思是:如果 RSI相对强弱指数大于 30就设置一个“买入”信号enter_long = 1

  • 为什么不行dataframe['rsi'] 不是单个数字而是一个包含多个值的序列Series比如 [25, 35, 40, ...]。Python 不知道如何直接比较一个序列和数字(> 30所以会报错“The truth value of a Series is ambiguous”。


  1. Pandas 的正确写法:向量化操作
  • 解决办法Pandas 要求你用“向量化”方式来处理整个数据表格,而不是一行一行地检查。

  • 正确代码:

    python

    dataframe.loc[(dataframe['rsi'] > 30), 'enter_long'] = 1
    
  • 解释:

    • dataframe['rsi'] > 30检查每一行的 RSI 是否大于 30返回一个布尔序列比如 [False, True, True, ...]。

    • .loc[...]Pandas 的定位方法,用来选择满足条件的行。

    • (dataframe['rsi'] > 30):条件,筛选出 RSI > 30 的行。

    • 'enter_long':目标列,表示“买入信号”。

    • = 1将满足条件的行的 'enter_long' 列设为 1。

  • 结果Dataframe 会多一列 'enter_long',其中 RSI > 30 的行值为 1其他行可能是空值NaN或默认值取决于代码逻辑

  • 用途Freqtrade 用这一列作为买入信号假设下一根K线开盘时会进入交易。


  1. 什么是向量化Vectorisation
  • 定义:向量化是指一次性对整个数据集进行操作,而不是用循环一行一行处理。

  • 为什么重要:

    • 速度快Pandas 的底层是用 C 语言实现的,向量化操作比 Python 的 for 循环快得多。

    • 适合大数据交易数据可能有成千上万根K线循环太慢。

  • 例子:

    • 不用循环dataframe['rsi'] > 30 一次性检查所有行。

    • 用循环(不推荐):

      python

      for i in range(len(dataframe)):
          if dataframe['rsi'][i] > 30:
              dataframe['enter_long'][i] = 1
      

      这种写法虽然也能跑,但效率很低。


  1. 总结:这段内容想告诉你什么?
  • 核心思想:在 Freqtrade 中,交易策略是通过操作 Dataframe 来实现的。你需要用 Pandas 的向量化方法来设置买卖信号,而不是用普通的 Python 逻辑。

  • 实际应用:

    • 你可以根据技术指标(比如 RSI、均线等生成信号列比如 enter_long、exit_long

    • Freqtrade 会根据这些信号自动执行交易。

  • 建议:避免用循环,尽量用 Pandas 的内置函数和向量化操作来计算指标和信号。


一个简单的例子

假设你的 Dataframe 是这样的:

   date                  rsi
0  2021-11-09 23:25:00  25
1  2021-11-09 23:30:00  35
2  2021-11-09 23:35:00  40

运行:

python

dataframe.loc[(dataframe['rsi'] > 30), 'enter_long'] = 1

结果变成:

   date                  rsi  enter_long
0  2021-11-09 23:25:00  25         NaN
1  2021-11-09 23:30:00  35         1.0
2  2021-11-09 23:35:00  40         1.0

Freqtrade 看到 enter_long 是 1 时就会在下一根K线开盘时买入。


如果你还有具体的问题或代码看不懂的地方,可以告诉我,我再详细解释!