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
相关推荐
大白同学4212 小时前
【C++】用哈希表封装unordered_XX
开发语言·c++·散列表
chian-ocean4 小时前
Bright Data 代理 + MCP :解决 Google 搜索反爬的完整方案
人工智能·python
GIS小天5 小时前
AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年8月25日第170弹
人工智能·算法·机器学习·彩票
PAK向日葵6 小时前
【算法导论】XM 0823 笔试题解
算法·面试
岁月栖迟6 小时前
leetcode 49. 字母异位词分组
windows·算法·leetcode
Asmalin6 小时前
【代码随想录day 21】 力扣 77. 组合
算法·leetcode·职场和发展
XH华7 小时前
C语言第十一章内存在数据中的存储
c语言·开发语言
AndrewHZ8 小时前
【python与生活】如何用Python写一个简单的自动整理文件的脚本?
开发语言·python·生活·脚本·文件整理
拉法豆粉9 小时前
在压力测试中如何确定合适的并发用户数?
java·开发语言
枯萎穿心攻击9 小时前
Unity VS UE 性能工具与内存管理
开发语言·游戏·unity·ue5·游戏引擎·虚幻·虚幻引擎