vnpy/examples/stock/demo_04.py

174 lines
5.8 KiB
Python
Raw Normal View History

2021-11-06 06:03:55 +00:00
# flake8: noqa
# 示例代码
# 从本地bar_data目录下读取某股票日线数据前复权后推送到K线识别出分笔、线段并找出首次破坏线段的分笔位置标注在图上
import os
import sys
import json
from datetime import datetime
vnpy_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
if vnpy_root not in sys.path:
print(f'sys.path append({vnpy_root})')
sys.path.append(vnpy_root)
os.environ["VNPY_TESTING"] = "1"
from vnpy.data.tdx.tdx_common import FakeStrategy
from vnpy.component.cta_line_bar import CtaDayBar
from vnpy.trader.ui.kline.ui_snapshot import UiSnapshot
from vnpy.trader.utility import append_data
from vnpy.trader.ui import create_qapp
from vnpy.data.common import get_stock_bars
# 本示例中输出的dist文件,主要用于图形显示一些逻辑
demo_04_dist = 'demo_04_dist.csv'
class DemoStrategy(FakeStrategy):
# 输出csv的head
dist_fieldnames = ['datetime', 'vt_symbol', 'volume', 'price',
'operation']
def __init__(self, *args, **kwargs):
super().__init__()
# 最后一个找到的符合要求的分笔位置
self.last_found_bi = None
# 如果之前存在,移除
if os.path.exists(demo_04_dist):
self.write_log(f'移除{demo_04_dist}')
os.remove(demo_04_dist)
self.vt_symbol = kwargs.get('vt_symbol')
# 创建一个日线bar的 kline对象
setting = {}
setting['name'] = f'{self.vt_symbol}_D1'
setting['bar_interval'] = 1
setting['para_ma1_len'] = 55 # 双均线
setting['para_ma2_len'] = 89
setting['para_macd_fast_len'] = 12 # 激活macd
setting['para_macd_slow_len'] = 26
setting['para_macd_signal_len'] = 9
setting['para_active_chanlun'] = True # 激活缠论
setting['is_stock'] = True
setting['price_tick'] = 1
setting['underly_symbol'] = self.vt_symbol.split('.')[0]
self.kline = CtaDayBar(strategy=self, cb_on_bar=self.on_bar, setting=setting)
def on_bar(self, *args, **kwargs):
"""
重构on_bar函数实现demo的判断逻辑
:param args:
:param kwargs:
:return:
"""
if self.kline.cur_duan is None:
return
# 当前笔的start == 找到的一笔
if self.kline.cur_bi.start == self.last_found_bi:
return
# 处理上涨线段
if self.kline.cur_duan.direction == 1:
# 当前一笔,起点== 线段的结束
if self.kline.cur_duan.end != self.kline.cur_bi.start:
return
if len(self.kline.cur_duan.bi_list) <=3:
return
# 找到次高的分笔位置
second_high = max([bi.high for bi in self.kline.cur_duan.bi_list[:-2] if bi.direction == 1])
if self.kline.cur_bi.low < second_high:
self.last_found_bi = self.kline.cur_bi.start
append_data(file_name=demo_04_dist,
field_names=self.dist_fieldnames,
dict_data={
'datetime': self.kline.cur_datetime,
'vt_symbol': self.vt_symbol,
'volume': 0,
'price': self.kline.cur_bi.low,
'operation': '上升段破坏点'
})
# 处理下跌线段
if self.kline.cur_duan.direction == -1:
# 当前一笔,起点== 线段的结束
if self.kline.cur_duan.end != self.kline.cur_bi.start:
return
if len(self.kline.cur_duan.bi_list) <= 3:
return
# 找到次低的分笔位置
second_low = min([bi.low for bi in self.kline.cur_duan.bi_list[:-2] if bi.direction == -1])
if self.kline.cur_bi.high > second_low:
self.last_found_bi = self.kline.cur_bi.start
append_data(file_name=demo_04_dist,
field_names=self.dist_fieldnames,
dict_data={
'datetime': self.kline.cur_datetime,
'vt_symbol': self.vt_symbol,
'volume': 0,
'price': self.kline.cur_bi.high,
'operation': '下跌段破坏点'
})
if __name__ == '__main__':
# 股票代码.交易所
vt_symbol = '600000.SSE'
t1 = DemoStrategy(vt_symbol=vt_symbol)
# 获取股票得日线数据,返回数据类型是barData
print('加载数据')
bars, msg = get_stock_bars(vt_symbol=vt_symbol, freq='1d', start_date='2019-01-01')
if len(msg) > 0:
print(msg)
sys.exit(0)
display_month = None
# 推送bar到kline中
for bar in bars:
if bar.datetime.month != display_month:
t1.write_log(f'推送:{bar.datetime.year}{bar.datetime.month}月数据')
display_month = bar.datetime.month
t1.kline.add_bar(bar, bar_is_completed=True)
# 获取kline的切片数据
data = t1.kline.get_data()
# 暂时不显示中枢等
data.pop('bi_zs_list', None)
data.pop('duan_zs_list', None)
snapshot = {
'strategy': "demo",
'datetime': datetime.now(),
"kline_names": [t1.kline.name],
"klines": {t1.kline.name: data}}
# 创建一个GUI界面应用app
qApp = create_qapp()
# 创建切片回放工具窗口
ui = UiSnapshot()
# 显示切片内容
ui.show(snapshot_file="",
d=snapshot, # 切片数据
dist_file=demo_04_dist, # 本地dist csv文件
dist_include_list=['上升段破坏点','下跌段破坏点']) # 指定输出的文字内容
sys.exit(qApp.exec_())