一个 Python 轻量级交易图表库 - lightweight-charts-python

今天这篇可能有点跨域了,其实这段时间,我一直在做交易。如果大家对自动化交易感兴趣,我也有很多内容可以写。

这两天发现一个可在 Python 显示交易图表的库,名为 lightweight-charts-python。顾名思义,它是基于 tradingview 轻量级库 lightweight-charts 开发而来。

TradingView 是一款非常流行的交易行情分析软件,而 lightweight-charts 是它提供的精简版 Js 开源库。因为 TradingView 本身就是一款专注交易的软件,lightweight-charts 有这高性能和用户体验友好的特点。

它的实现是 Python 通过 webview 集成 lightweight-charts 开发而来的库,使用 Python 的小伙伴无需学习 Javascript 也能使用 lightweight-charts 了。

通过 Python 实现,还有个优势,容易与其他框架结合,如国内非常流行的实盘框架 vnpy,它的 GUI 界面就是用 pyside6 实现,这个库非常容易集成到 pyside6 中,从而集成到 vnpy。

OK,让我们正式开始演示这个库的使用吧。

安装命令

pip install lightweight-charts

行情数据

为了体验 lightweight-charts-python 库的使用,提前准备行情数据必要的步骤。

lightweight-charts-python 的 GitHub 仓库中提供了一些样例数据,我们也可以从一些交易软件下载。不过,既然都来看这篇文章了,肯定都是会编程的,我推荐开源库获取数据。

我将用 tushare 下载行情数据,或者也可以用 akshare 等一些开源库。假设下载代码为 000001.SZ 的平安银行。

import tushare as ts

pro = ts.pro_api()
code = "000001.SZ"
df = pro.query("daily", ts_code=code, start_date="20180701", end_date="20240510")

通过 pandas 将其整理为满足 lightweight-charts 目标的数据格式,即包含 date、open、high、low、close、volume 字段,还要保证 date 为日期格式,且数据按日期升序排列。

df["date"] = pd.to_datetime(df["trade_date"])
df = df.sort_values(by="date", ascending=True)
df.rename(columns={"vol": "volume"}, inplace=True)
df = df[["date", "open", "high", "low", "close", "volume"]]

df.to_csv(f"D_{code}.csv")

目录就有了名为 D_000001.SZ.csv 的行情数据文件。依次类推,还可下载周线和月线。分钟线数据好像需要更高积分才能下载。

快速上手

首先,体验下它最基础使用方法,显示历史 K 线图表。

import time
import pandas as pd

from lightweight_charts import Chart

def main():
  chart = Chart()

  df = pd.read_csv("D_000001.SZ.csv")
  chart.set(df)

  chart.show(block=True)

if __name__ == "__main__":
  main()

如上的代码中,Chart 是它的核心类,通过 pandas 的读取 csv 文件数据并将其 DataFrame 传递给 chart 即可完成历史行情的设置。

运行代码,你将能看到如下的效果:

新增 Bar/Tick

如要实时的行情,我们可通过 Chart 提供的方法更新图表。它提供了两个方法,分别是 update 可用于更新 Bar 蜡烛图和 update_from_tick 从 tick 数据更新图表。

首先,演示新增 bar 更新图表。我们将之前准备的数据截断,df.iloc[-10:] 保留 10 个 bar 为演示数据。

chart = Chart()

df = pd.read_csv("D_000001.SZ.csv")
chart.set(df.iloc[:-10])

chart.show()

for i, bar in df.iloc[-10:].iterrows():
    chart.update(bar)
    time.sleep(1)

每隔 1 秒,新增 1 个 bar。动图效果如下:

实际场景下,实时更新 tick 才是我们的目标。只要将实时 tick 不断投喂给 chart 即可。我暂时没有接入实时数据,将用随机模拟的方式生成后续数据。

chart = Chart()

df = pd.read_csv("D_000001.SZ.csv", parse_dates=["date"])
chart.set(df)
chart.show()

last_time = df.iloc[-1]["date"] + datetime.timedelta(days=1)
last_price = df.iloc[-1]["close"]

while True:
    time.sleep(0.1)

    change_percent = 0.002
    change = last_price * random.uniform(-change_percent, change_percent)
    new_price = last_price + change
    new_time = pd.to_datetime(last_time) + datetime.timedelta(hours=1)

    tick = pd.Series({"time": new_time, "price": new_price})

    chart.update_from_tick(tick)

    last_price = new_price
    last_time = new_time

随机数据基于最新的价格和时间生成,重点就是其中这一段代码:

change_percent = 0.002
change = last_price * random.uniform(-change_percent, change_percent)
new_price = last_price + change
new_time = pd.to_datetime(last_time) + datetime.timedelta(hours=1)

将其组织成 lightweight-charts 要求的 tick 数据格式传递给 chart 即可。

tick = pd.Series({"time": new_time, "price": new_price})
chart.update_from_tick(tick)

动图效果如下:

指标创建

指标 Indicator 是交易图表不可缺少的部分,用 lightweight-charts 要实现指标只要通过 chart 的方法 create_line 创建一条 line,设置 line 数据即可。如果你的指标不是线条,而是直方图,Chart 也提供了 create_histogram

我就以简单移动平均作为演示吧。指标计算函数如下:

def sma(df, period: int = 50):
    return pd.DataFrame(
        {"time": df["date"], f"SMA {period}": df["close"].rolling(window=period).mean()}
    ).dropna()

从如上的计算函数可知,提供给 line 的数据要求包含时间和指标值,而指标值的列名要和 Line 的名称相同。主函数中新增两行代码引入指标 Line:

# 保持与 sma 返回的 SMA {period} 相同
line = chart.create_line("SMA 30")
line.set(sma(df, period=30))

效果如下:

如果要实时更新的话,计算后续数值并通过 line.update 方法更新上去即可。

SMA 均线还是主图指标,如果希望在副图上显示指标,可通过 chart.create_subchart 创建副图,在其中显示副图指标。

核心代码如下所示:

chart = Chart(inner_height=0.7)
chart.time_scale(visible=False) # 将主图的时间轴隐藏

# 获取数据省略

# sync 参数保持与主图同步
rsi_chart = chart.create_subchart(height=0.3, width=1, sync=True)
rsi_line = rsi_chart.create_line("RSI")
rsi_line.set(rsi(df))

如下 rsi 计算函数部分,其中的 RSI 指标用的是 talib 实现。

def rsi(df, period: int = 14):
    return pd.DataFrame(
        {"time": df["date"], "RSI": talib.RSI(df["close"], timeperiod=14)}
    )

效果如下:

启用图例

我们已经添加了指标,但只看到线条,如想查看实际数值,通过 chart.legend(True) 启用图例即可。

chart.legend(True) # 主图
rsi_chart.legend(True) # 副图

效果如下:

多图表支持

前面通过 create_subchart 创建副图来展示副图指标,其实我们还可以基于它创建多图表。交易员可能要在不同的图表上展示不同周期或不同资产的行情,以便于寻找交易机会。

我将以在不同图表展示统一个资产的日线、周线和月线为例,演示它的使用。

chart = Chart(inner_width=0.5, inner_height=0.5)
weekly_chart = chart.create_subchart(width=0.5, height=0.5, sync=True)
monthly_chart = chart.create_subchart(width=1, height=0.5, sync=True)

df = pd.read_csv("D_000001.SZ.csv")
weekly_df = pd.read_csv("W_000001.SZ.csv")
monthly_df = pd.read_csv("M_000001.SZ.csv")

chart.set(df)
weekly_chart.set(weekly_df)
monthly_chart.set(monthly_df)

chart.show(block=True)

如上代码创建了三个周期的 chart,分别展示日线、周线和月线。其中的周线和月线图表都是基于日线 chart 创建的。它默认是按从左到右从上到下排列的,创建的时候注意设置 chart 的宽高即可。

最终效果如下:

我在测试时发现它的同步有点问题,好像只能在父子间同步,即在日线可以同步周线和月线,在周线或月线可以同步日线,但不能保持周线和月线的同步。或许要看 JS 库才能解决了吧?

其他更多

更多内容就不一一展开了,如果大家有兴趣的话,可留言说明,我可以继续完成其他部分,如周期切换、按 symbol 搜索,指标选择自定义等等,甚至与实盘框架集成,实盘下单,如 vnpy 实盘框架,vnpy 作者自研了一个图表,但功能有限,lightweight-charts 也可直接与 PySide6 集成,集成到 vnpy 框架中。

有了这个库,我们可以做一些自己想要的能力,如手动回放回测、或者自动策略与手动相结合的回测,一切尽在掌握。毕竟,自己编程,才能丰衣足食。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Python 3.9是一种非常强大的编程语言,具有很多优点,例如易学易用、代码简洁、模块化设计等等。但是,在安装一些看似简单的扩展模块时,有时会遇到错误。本文将介绍如何解决安装Python-ldap subprocess-exited-with-error错误的方法。 Python-ldap 是Python一个开放源代码的扩展,用于与LDAP(Lightweight Directory Access Protocol)进行通信。Python-ldap扩展需要在Python环境中安装OpenLDAP开发包。这时,有可能会在安装过程中遇到“subprocess-exited-with-error”错误。这是Python-ldap扩展的一个常见错误,但并不难解决。下面是几个可能的解决方案: 1. 确保安装OpenLDAP开发包 在安装Python-ldap之前,必须确保已经按照当前操作系统的要求安装了OpenLDAP开发包。OpenLDAP是一个基于X.500标准的开放源代码目录服务,可以用于LDAP协议。在安装OpenLDAP开发包之前,需要检查是否有Linux各种发行版有对应的OpenLDAP包管理工具,如果没有则需要去下载源码从压缩包编译出.so。 2. 管理员权限 安装Python-ldap时,需要管理员权限才能处理需要的二进制文件。如果没有管理员权限,无法安装这个扩展。在Linux或Mac系统中,可以使用sudo或者su命令获得管理员权限。 3. 安装依赖 Python-ldap还依赖一些其他的Python,包括pyasn1和pyasn1-modules。使用命令pip install pyasn1 pyasn1-modules进行安装即可。 4. 安装PyCryptodome 有时候,安装python-ldap时,还需要安装PyCryptodome包。PyCryptodome是一个Python密码,它采用C扩展方式并提供了一组可用于加密、签名、验证、哈希等操作的模块。使用命令pip install pycryptodome 安装。 总之,“subprocess-exited-with-error”错误的解决办法包括:确保安装OpenLDAP开发包、获得管理员权限、安装依赖、安装PyCryptodome等等。遇到问题应该及时进行查找,保证Python的正常运行。 ### 回答2: 应该首先查看错误信息,了解安装过程中出现了什么问题。从错误信息中可以了解到是 subprocess-exited-with-error,这个错误信息比较笼统,不能够明确判断出错原因。需要进一步寻找其他信息。可以考虑执行以下命令,检查详细错误信息: ```python pip install python-ldap --global-option=build_ext --global-option="-I/usr/local/opt/openldap/include -L/usr/local/opt/openldap/lib" ``` 执行完上述命令后,自动进入了下载过程,如果命令执行失败,会给出错误信息。根据错误信息检查原因,有可能是python的版本问题,或者缺少相关依赖包。如果因为缺少依赖包无法安装python-ldap ,则可以按照以下步骤进行安装: 1. 安装OpenLDAP,指定python支持的相关: ```shell brew install openldap ``` 2. 安装pip: ```shell sudo easy_install pip ``` 3. 安装python-ldap: ```shell pip install python-ldap --global-option=build_ext --global-option="-I/usr/local/opt/openldap/include -L/usr/local/opt/openldap/lib" ``` 以上步骤可以解决在安装python-ldap过程中可能遇到的错误,确保安装成功。当然,如果无法解决错误,可以考虑更换python版本,或者寻找其他途径解决问题。 ### 回答3: Python是一种高级编程语言,它被广泛用于许多应用程序的开发Python 3.9是Python语言的最新版本,并且它包含许多新的功能和改进。安装与Python 3.9相关的软件包时,您可能会遇到一些错误。本文将重点介绍如何安装Python-ldap模块,并解决subprocess-exited-with-error错误。 Python-ldap是一个用于Python编程语言的LDAP(Lightweight Directory Access Protocol)客户端,它是使用Python连接LDAP服务器的重要工具。想要使用Python-ldap模块,您需要先安装OpenLDAP开发文件。 要在Python 3.9中安装Python-ldap模块,请按照以下步骤进行: 第一步是安装OpenLDAP开发文件: sudo apt-get update sudo apt-get install libldap2-dev libsasl2-dev libssl-dev 第二步是使用PIP安装Python-ldap模块: sudo pip install python-ldap 如果您遇到了subprocess-exited-with-error错误,请按照以下步骤进行解决: 步骤1:安装Python-ldap之前,请确保您已经安装了Python 3.9的开发文件。可以使用以下命令来安装: sudo apt-get install python3.9-dev 步骤2:如果您尝试使用sudo pip install python-ldap命令安装Python-ldap时仍然遇到了subprocess-exited-with-error错误,请使用以下命令: sudo apt-get install python3-ldap 步骤3:如果您无法通过上述方法解决问题,请使用以下命令: sudo apt-get install libsasl2-modules-gssapi-mit 安装完上述三个开发文件之后,请再次尝试使用sudo pip install python-ldap安装Python-ldap模块。您不应该再遇到subprocess-exited-with-error错误。 总而言之,Python-ldap模块是一个非常有用的工具,用于在Python编程语言中连接LDAP服务器。通过遵循以上步骤,您可以轻松地安装它,并解决subprocess-exited-with-error错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

波罗学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值