Python 中的 VWAP 算法策略

[文献精汇]Python 中的 VWAP 算法策略

使用 Python 中的 VWAP 和移动平均线策略进行比特币算法交易回测。我们将深入探讨算法交易的 VWAP(成交量加权平均价格)和移动平均线 (MA) 指标的详细比较。

VWAP 和移动平均线是交易者中流行的工具,每种工具都提供独特的见解。移动平均线提供了简单的价格平均值,而 VWAP 通过结合交易量提供了更微妙的视角。这种区别对于确定证券是被高估还是被低估至关重要。我们将讨论为什么 VWAP 经常受到交易者的青睐,以及它如何作为动态支撑位和阻力位。

我将指导您完成 VWAP 的计算,强调由于其成交量加权性质,它相对于移动平均线的重要性。

第 1 步:数据导入和预处理

第一步,我们导入并预处理比特币交易数据,为分析做准备。该过程涉及以下操作:

复制代码
import pandas as pd

# Load the Bitcoin trading data from a CSV file
df = pd.read_csv("BTCUSD_Candlestick_15_M_ASK_05.08.2019-29.04.2022.csv")

# Clean the "Gmt time" column by removing the ".000" suffix
df["Gmt time"] = df["Gmt time"].str.replace(".000", "")

# Convert the "Gmt time" column to datetime format
df['Gmt time'] = pd.to_datetime(df['Gmt time'], format='%d.%m.%Y %H:%M:%S')

# Set the "Gmt time" column as the index of the DataFrame
df.set_index("Gmt time", inplace=True)

# Remove rows where the high and low prices are equal
df = df[df.High != df.Low]
  • Clean the "Gmt time" column 清理时间列:通过从时间戳字符串中删除".000"后缀来清理"Gmt 时间"列,以确保日期时间格式正确。
  • Convert the "Gmt time" column 转换为日期时间:使用 pd.to_datetime 函数将清理后的"Gmt 时间"列转换为日期时间格式,并指定正确的解析格式。
  • Remove rows 过滤数据:从 DataFrame 中删除最高价和最低价相等的行,以确保交易数据有意义。

第 2 步:计算指标

第二步,我们使用 pandas_ta 库计算 VWAP (成交量加权平均价格) 和 EMA (指数移动平均线) 指标。

复制代码
import pandas_ta as ta

# Calculate VWAP (Volume Weighted Average Price) and add it to the DataFrame
df["VWAP"] = ta.vwap(df.High, df.Low, df.Close, df.Volume)

# Calculate EMA (Exponential Moving Average) with a length of 100 periods and add it to the DataFrame
df["EMA"] = ta.ema(df.Close, length=100)
  • 计算 VWAP:VWAP 指标使用最高价、最低价、收盘价和成交量数据计算。VWAP 将作为名为 "VWAP" 的新列添加到 DataFrame 中。
  • 计算 EMA:EMA 指标是针对指定长度为 100 个周期的收盘价计算的。EMA 将作为名为 "EMA" 的新列添加到 DataFrame 中。

第 3 步:生成 EMA 信号

在第三步中,我们根据指数移动平均线 (EMA) 生成交易信号。这些信号将帮助我们确定潜在的买入和卖出机会。我们根据指定回溯期内的最高价、最低价和 EMA 值之间的关系来识别潜在的交易信号。

该信号检查回溯期内的所有蜡烛是否完全高于或完全低于 EMA。如果它们都在上方,则表明上升趋势;如果它们都低于下方,则表明 backcandles 窗口内出现下降趋势。

复制代码
# Initialize the EMASignal list with zeros
emasignal = [0] * len(df)

# Define the lookback period
backcandles = 6

# Loop through the DataFrame starting from the lookback period to the end
for row in range(backcandles, len(df)):
    upt = 1
    dnt = 1
    # Check the conditions for the past backcandles periods
    for i in range(row - backcandles, row + 1):
        if df.High[i] >= df.EMA[i]:
            dnt = 0
        if df.Low[i] <= df.EMA[i]:
            upt = 0
    # Set the EMASignal based on the conditions
    if upt == 1and dnt == 1:
        emasignal[row] = 3
    elif upt == 1:
        emasignal[row] = 2
    elif dnt == 1:
        emasignal[row] = 1

# Add the EMASignal to the DataFrame
df['EMASignal'] = emasignal

/var/folders/d9/rbb57jqn3g133_ynk3vgz02c0000gn/T/ipykernel_38122/1407699409.py:13: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  if df.High[i] >= df.EMA[i]:
/var/folders/d9/rbb57jqn3g133_ynk3vgz02c0000gn/T/ipykernel_38122/1407699409.py:15: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  if df.Low[i] <= df.EMA[i]:
  • 初始化信号列表:我们创建一个名为 emasignal 的列表,其中填充了零,对应于 DataFrame 的长度。
  • 设置回溯周期: 我们定义一个变量 backcandles 来指定我们将回溯以检查信号条件的周期数。
  • 遍历数据:我们从 backcandles 索引开始遍历 DataFrame,直到 DataFrame 的末尾。
  • 检查条件:对于每一行,我们将两个变量 upt 和 dnt 初始化为 1,分别表示上升和下降趋势。然后,我们遍历过去的 backcandles 周期以检查以下条件:
  • 如果当前蜡烛的最高价大于或等于 EMA,则将 dnt 设置为 0。
  • 如果当前蜡烛的最低价小于或等于 EMA,则设置为 0。
  • 设置信号:
  • 如果 upt 和 dnt 都保持 1,则将信号设置为 3(表示没有明显的趋势)。
  • 如果只有 upt 为 1,则将信号设置为 2 (表示潜在的上升趋势)。
  • 如果只有 dnt 为 1,则将信号设置为 1(表示潜在的下降趋势)。

向 DataFrame 添加信号:最后,我们将生成的信号添加到 DataFrame 中名为 EMASignal 的新列中。

python 代码也可以使用切片编写,这更像是一种 python 编码方式:

复制代码
# Initialize the EMASignal list with zeros
emasignal = [0] * len(df)

# Define the lookback period
backcandles = 6

# Loop through the DataFrame starting from the lookback period to the end
for row in range(backcandles, len(df)):
    # Slicing the relevant window of high, low, and EMA values
    high_slice = df.High[row - backcandles: row + 1]
    low_slice = df.Low[row - backcandles: row + 1]
    ema_slice = df.EMA[row - backcandles: row + 1]

    # Check the conditions for uptrend and downtrend
    upt = all(high_slice >= ema_slice)
    dnt = all(low_slice <= ema_slice)

    # Set the EMASignal based on the conditions
    if upt and dnt:
        emasignal[row] = 3
    elif upt:
        emasignal[row] = 2
    elif dnt:
        emasignal[row] = 1

# Add the EMASignal to the DataFrame
df['EMASignal'] = emasignal
相关推荐
云深麋鹿1 分钟前
C++ | 模板
开发语言·c++
m0_743106465 分钟前
【浙大&南洋理工最新综述】Feed-Forward 3D Scene Modeling(五)
人工智能·算法·计算机视觉·3d·几何学
m0_746752301 小时前
c++怎么利用std--variant处理多种二进制子协议包的自动分支解析【进阶】
jvm·数据库·python
m0_734949798 小时前
MySQL如何配置定时清理过期备份文件_find命令与保留周期策略
jvm·数据库·python
t***5448 小时前
Clang 编译器在 Orwell Dev-C++ 中的局限性
开发语言·c++
m0_514520578 小时前
MySQL索引优化后性能没提升_通过EXPLAIN查看索引命中率
jvm·数据库·python
H Journey9 小时前
Python 国内pip install 安装缓慢
python·pip·install 加速
oy_mail9 小时前
QoS质量配置
开发语言·智能路由器·php
oyzz1209 小时前
PHP操作redis
开发语言·redis·php
kobesdu9 小时前
人形机器人SLAM:技术挑战、算法综述与开源方案
算法·机器人·人形机器人