TA-lib使用介绍(以Vegas通道为例)
1. TA-lib安装
TA-Lib,全称“Technical Analysis Library”, 是Python金融量化的高级库,涵盖了150多种股票、期货交易软件中常用的技术分析指标,如MACD、RSI、KDJ、动量指标、布林带等等。
安装
pip install TA-Lib
# or
conda install TA-Lib
如果安装报错的话,需要先自己编译然后再pip install
:
wget https://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz
untar ta-lib-0.4.0-src.tar.gz
cd ta-lib
./configure --prefix=/usr
make
sudo make install
2. Pandas安装
Pandas 是一个基于 Python 构建的专门进行数据操作和分析的开源软件库,可提供数据结构和运算,进行功能现强大、灵活且易于使用的数据分析和操作。Pandas 为热门编程语言赋予了处理类似电子表格的数据的能力,从而增强了 Python 功能,除其他关键功能外,加快了加载、对齐、操作和合并的速度。
pip install pandas
# or
conda install pandas
3. Vegas通道
Vegas通道是一个比较简单的指标,只需要用到几根均线,因此很适合新手入门练手写写代码。以下是具体说明,来自:https://tw.tradingview.com/chart/BTCUSD/Anln2YJ0/
起源:在距今20多年前,有一位华尔街顶级对冲基金经理名为Vegas, 他靠自己开发的交易方法在市场中赚取了巨额利润之后将这套交易方法在网上进行了公开,并以自己的名字命名。名为“Vegas隧道交易法”,从此这套交易法逐步开始走向大众的视野。
定义:Vegas隧道交易法所采用的指标工具为EMA,其指标参数为:EAM144, EMA169, EMA12, EMA576, EMA676。其中EMA144和EMA169为“隧道区”Vegas本人认为是价格多空力量主要分水岭,起到支撑位和压力位作用,EMA12做为“过滤器”使用,EMA576和EMA676做为大趋势方向的研判和辅助。
具体用法:当价格和EMA12同时向上突破隧道区(EMA144和EMA169),并且价格处于EMA576和EMA676之上时,则后市行情看多。当价格和EMA12向下跌破隧道区,并且价格处于EMA576和EMA676之下时,则后市行情看空,多空头寸止损为隧道区的另一侧。
注意:
EMA12做为过滤器使用,其作用是区分真假突破,当价格突破隧道区但EMA12没有突破时,视为假突破,不参与操作,只有当价格和EMA12同时突破隧道区时才视为真突破。
EMA576和EMA676做为大趋势方向研判方法,其核心逻辑是顺应趋势方向,无论何时都要顺着EMA576和EMA676方向操作,主动放弃方向不一致的交易机会。
Vegas交易法开发者本人在公开的时候有所保留,比如具体的止盈位置,仓位比例等等,都是学习者需要进行优化的地方,或者使用该方法进行行情参考。
4. EMA计算
在TA-Lib中,像均线这种指标的计算只需简单调用内置函数即可:
# Vegas通道参数
ema_12 = ta.EMA(COIN_df['Close'], 12)
ema_144 = ta.EMA(COIN_df['Close'], 144)
ema_169 = ta.EMA(COIN_df['Close'], 169)
ema_288 = ta.EMA(COIN_df['Close'], 288)
ema_338 = ta.EMA(COIN_df['Close'], 338)
ema_144
和ema_269
作为支撑隧道,另外两个ema_288
和ema_338
用作判断大趋势(由于我这里主要是短线,为了提高交易频率就没有使用576和677均线了),但是这两条均线暂时也不会用到,就是作一个示例。
ema_12
用作过滤线,只有当它突破支撑时才触发买/卖信号。
5. 判断突破
那要怎么写判断突破的逻辑呢?
我的思路是先得到隧道中处于需要突破一方的值(如向上突破就取最大值,反之取最小值),然后判断当前时间的ema_12
与上一时间是否正好突破这个值,从上到下或从下到上。
# ema_12上穿Vegas隧道
def upCross(ema_12, ema_144, ema_169):
max_vegas = max(ema_144.iloc[-1], ema_169.iloc[-1])
if ema_12.iloc[-1] >= max_vegas and ema_12.iloc[-2] < max_vegas:
return True
return False
# ema_12下穿Vegas隧道
def downCross(ema_12, ema_144, ema_169):
min_vegas = min(ema_144.iloc[-1], ema_169.iloc[-1])
if ema_12.iloc[-1] <= min_vegas and ema_12.iloc[-2] > min_vegas:
return True
return False
6. 实时更新数据
通过实时获取数据,来判断是否达到触发条件,使用之前的接口获取最新的一条价格信息,如果时间戳发生变化则剔除最早的一条数据插入最新的数据,如果时间戳没变则更新最后一条数据,保持数据总量不会随时间变化,并且重新计算ema。
while True:
COIN_df_now = pd.DataFrame(exchange.fetch_ohlcv(COIN, timeframe='5m', limit=1))
COIN_df_now.columns = ['Timestamp', 'Open', 'High', 'Low', 'Close', 'Vol']
COIN_df_now['Datetime'] = COIN_df_pre['Timestamp'].apply(
lambda x: time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(x / 1000.)))
COIN_df_now['Datetime'] = pd.to_datetime(COIN_df_now['Datetime'])
COIN_df_now.set_index('Datetime', inplace=True)
if COIN_df_now['Timestamp'].iloc[0] == COIN_df['Timestamp'].iloc[-1]: # 如果和最后一条相同就替换掉
COIN_df.iloc[-1] = COIN_df_now.iloc[0]
else:
COIN_df = pd.concat([COIN_df, COIN_df_now], ignore_index=True)
COIN_df = COIN_df.drop(COIN_df.index[0])
# 更新EMA
ema_12 = ta.EMA(COIN_df['Close'], 12)
ema_144 = ta.EMA(COIN_df['Close'], 144)
ema_169 = ta.EMA(COIN_df['Close'], 169)
ema_288 = ta.EMA(COIN_df['Close'], 288)
ema_338 = ta.EMA(COIN_df['Close'], 338)
time.sleep(1)
7. 邮件通知
这篇文章暂时还不涉及自动交易,先使用邮箱发送预警尝试。首先写一个发送邮件的模块:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
# 邮件配置
sender_email = 'xxxxxxxxxxxxxxxxx'
receiver_email = ['xxxxxxxxxxxxxxx']
# SMTP服务器配置
smtp_server = 'smtp.qq.com'
smtp_port = 465
# 邮件登录凭据
smtp_username = 'xxxxxxxxxxxxxxxx'
smtp_password = 'xxxxxxxxxxxxxxxx'
def sendEmail(subject, content, image_path=None):
server = smtplib.SMTP_SSL(smtp_server, smtp_port)
msg = MIMEMultipart('related')
msg['From'] = sender_email
msg['To'] = ', '.join(receiver_email)
msg['Subject'] = subject
# 创建邮件正文,将图片嵌入到 HTML 中
msg_text = MIMEText('<img src="cid:image1"><br>' + content, 'html')
msg.attach(msg_text)
# 打开图片文件,并创建一个MIMEImage对象
if image_path:
with open(image_path, 'rb') as f:
mime = MIMEImage(f.read())
mime.add_header('Content-ID', '<image1>')
msg.attach(mime)
server.login(smtp_username, smtp_password)
server.sendmail(sender_email, receiver_email, msg.as_string())
server.quit()
这里使用qq邮箱的邮件服务器,具体教程不是本文的重点就不细说了。
发送预警信息的同时还会发送画的均线图。
然后再刚刚获取数据的循环中加入:
# 打印日志最新价格
print(f"[INFO {datetime.now(pytz.timezone('Asia/Shanghai'))}] Price: {COIN_df['Close'].iloc[-1]}")
if upCross(ema_12, ema_144, ema_169) and COIN_df['Timestamp'].iloc[-1] != last_cross:
plt.clf()
filePath = plotVegas(close=None, ema_12=ema_12, ema_144=ema_144, ema_169=ema_169, ema_288=ema_288, ema_338=ema_338)
print(f"[WARN {datetime.now(pytz.timezone('Asia/Shanghai'))}] {COIN}上穿Vegas通道, 考虑做多")
sendEmail(f"{COIN}考虑做多", f"[{datetime.now(pytz.timezone('Asia/Shanghai'))}] {COIN} EMA12上穿Vegas通道", filePath)
os.remove(filePath)
last_cross = COIN_df['Timestamp'].iloc[-1]
if downCross(ema_12, ema_144, ema_169) and COIN_df['Timestamp'].iloc[-1] != last_cross:
plt.clf()
filePath = plotVegas(close=None, ema_12=ema_12, ema_144=ema_144, ema_169=ema_169, ema_288=ema_288, ema_338=ema_338)
print(f"[WARN {datetime.now(pytz.timezone('Asia/Shanghai'))}] {COIN}下穿Vegas通道, 考虑做空")
sendEmail(f"{COIN}考虑做空", f"[{datetime.now(pytz.timezone('Asia/Shanghai'))}] {COIN} EMA12下穿Vegas通道", filePath)
os.remove(filePath)
last_cross = COIN_df['Timestamp'].iloc[-1]
在每一次ema_12
上传或下跌Vegas通道都会发送邮件到指定的邮箱:
总结
最后总结以下,这篇文章主要是让初学者了解一下TA-Lib这个库的使用,使用一个简单的策略来作为例子练手。但是不涉及自动交易,仅仅通过邮件发送预警信号,之后根据我的学习还会写一些文章深入。