[新增] 股票+缠论得使用例子
This commit is contained in:
parent
a2bf8ec41b
commit
a5afa10d0b
187
examples/stock/demo_03.py
Normal file
187
examples/stock/demo_03.py
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
# flake8: noqa
|
||||||
|
|
||||||
|
# 示例代码
|
||||||
|
# 从本地bar_data目录下,读取某股票日线数据,前复权后,推送到K线,识别出顶、底分型,并识别出其强弱,在UI界面上展示出来
|
||||||
|
|
||||||
|
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_03_dist = 'demo_03_dist.csv'
|
||||||
|
|
||||||
|
|
||||||
|
class DemoStrategy(FakeStrategy):
|
||||||
|
# 输出csv的head
|
||||||
|
dist_fieldnames = ['datetime', 'vt_symbol', 'volume', 'price',
|
||||||
|
'operation']
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
# 最后一个找到的符合要求的分型index
|
||||||
|
self.last_found_fx = None
|
||||||
|
|
||||||
|
# 如果之前存在,移除
|
||||||
|
if os.path.exists(demo_03_dist):
|
||||||
|
self.write_log(f'移除{demo_03_dist}')
|
||||||
|
os.remove(demo_03_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 len(self.kline.fenxing_list) == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
cur_fx = self.kline.fenxing_list[-1]
|
||||||
|
|
||||||
|
# 如果的分型已经处理过了,就不再计算
|
||||||
|
if cur_fx.index == self.last_found_fx:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 分型是非实时的,已经走完的
|
||||||
|
if cur_fx.is_rt:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 分型前x根bar
|
||||||
|
pre_bars = [bar for bar in self.kline.line_bar[-10:] if
|
||||||
|
bar.datetime.strftime('%Y-%m-%d %H:%M:%S') < cur_fx.index]
|
||||||
|
|
||||||
|
if len(pre_bars) == 0:
|
||||||
|
return
|
||||||
|
pre_bar = pre_bars[-1]
|
||||||
|
|
||||||
|
# 分型后x根bar
|
||||||
|
extra_bars = \
|
||||||
|
[bar for bar in self.kline.line_bar[-10:] if bar.datetime.strftime('%Y-%m-%d %H:%M:%S') > cur_fx.index]
|
||||||
|
|
||||||
|
# 分型后,有三根bar
|
||||||
|
if len(extra_bars) < 3:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 处理顶分型
|
||||||
|
if cur_fx.direction == 1:
|
||||||
|
# 顶分型后第一根bar的低点,没有超过前bar的低点
|
||||||
|
if extra_bars[0].low_price >= pre_bar.low_price:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 找到正确形态,第二、第三根bar,都站在顶分型之下
|
||||||
|
if pre_bar.low_price >= extra_bars[1].high_price > extra_bars[2].high_price:
|
||||||
|
self.last_found_fx = cur_fx.index
|
||||||
|
append_data(file_name=demo_03_dist,
|
||||||
|
field_names=self.dist_fieldnames,
|
||||||
|
dict_data={
|
||||||
|
'datetime': extra_bars[-1].datetime,
|
||||||
|
'vt_symbol': self.vt_symbol,
|
||||||
|
'volume': 0,
|
||||||
|
'price': extra_bars[-1].high_price,
|
||||||
|
'operation': '强顶分'
|
||||||
|
})
|
||||||
|
|
||||||
|
# 处理底分型
|
||||||
|
if cur_fx.direction == -1:
|
||||||
|
# 底分型后第一根bar的高点,没有超过前bar的高点
|
||||||
|
if extra_bars[0].high_price <= pre_bar.high_price:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 找到正确形态,第二、第三根bar,都站在底分型之上
|
||||||
|
if pre_bar.high_price <= extra_bars[1].low_price < extra_bars[2].low_price:
|
||||||
|
self.last_found_fx = cur_fx.index
|
||||||
|
append_data(file_name=demo_03_dist,
|
||||||
|
field_names=self.dist_fieldnames,
|
||||||
|
dict_data={
|
||||||
|
'datetime': extra_bars[-1].datetime,
|
||||||
|
'vt_symbol': self.vt_symbol,
|
||||||
|
'volume': 0,
|
||||||
|
'price': extra_bars[-1].low_price,
|
||||||
|
'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('duan_list', None)
|
||||||
|
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_03_dist, # 本地dist csv文件
|
||||||
|
dist_include_list=['强底分','强顶分']) # 指定输出的文字内容
|
||||||
|
|
||||||
|
sys.exit(qApp.exec_())
|
5
examples/stock/demo_03_dist.csv
Normal file
5
examples/stock/demo_03_dist.csv
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
datetime,vt_symbol,volume,price,operation
|
||||||
|
2019-04-02 09:30:00,600000.SSE,0,107.52293310892577,强底分
|
||||||
|
2019-04-24 09:30:00,600000.SSE,0,110.91541829027662,强顶分
|
||||||
|
2020-01-09 09:30:00,600000.SSE,0,120.77593836872654,强顶分
|
||||||
|
2020-01-17 09:30:00,600000.SSE,0,119.41563013287603,强顶分
|
|
173
examples/stock/demo_04.py
Normal file
173
examples/stock/demo_04.py
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
# 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_())
|
6
examples/stock/demo_04_dist.csv
Normal file
6
examples/stock/demo_04_dist.csv
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
datetime,vt_symbol,volume,price,operation
|
||||||
|
2020-04-28 09:30:00,600000.SSE,0,101.2458,下跌段破坏点
|
||||||
|
2020-11-11 09:30:00,600000.SSE,0,93.181114,下跌段破坏点
|
||||||
|
2021-03-02 09:30:00,600000.SSE,0,102.02312,上升段破坏点
|
||||||
|
2021-04-16 09:30:00,600000.SSE,0,100.85714,上升段破坏点
|
||||||
|
2021-09-13 09:30:00,600000.SSE,0,92.1123,下跌段破坏点
|
|
162
examples/stock/demo_05.py
Normal file
162
examples/stock/demo_05.py
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
# 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_05_dist = 'demo_05_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
|
||||||
|
|
||||||
|
# 最后一个处理得中枢开始位置
|
||||||
|
self.last_found_zs = None
|
||||||
|
|
||||||
|
# 最后一个中枢得判断类型
|
||||||
|
self.last_found_type = None
|
||||||
|
|
||||||
|
# 如果之前存在,移除
|
||||||
|
if os.path.exists(demo_05_dist):
|
||||||
|
self.write_log(f'移除{demo_05_dist}')
|
||||||
|
os.remove(demo_05_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
|
||||||
|
|
||||||
|
if self.kline.cur_bi_zs is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 当前笔的start == 上一次判断过得
|
||||||
|
if self.kline.cur_bi.start == self.last_found_bi:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 当前笔中枢与上一个笔中枢得开始不同,可能是个新得笔中枢
|
||||||
|
if self.kline.cur_bi_zs.start != self.last_found_zs:
|
||||||
|
# 设置为最新判断中枢
|
||||||
|
self.last_found_zs = self.kline.cur_bi_zs.start
|
||||||
|
# 设置中枢得最后一笔开始时间,为最新判断时间
|
||||||
|
self.last_found_bi = self.kline.cur_bi_zs.bi_list[-1].start
|
||||||
|
# 设置中枢得类型为None
|
||||||
|
self.last_found_type = None
|
||||||
|
return
|
||||||
|
|
||||||
|
# K线最后一笔得开始 = 中枢最后一笔得结束
|
||||||
|
if self.kline.cur_bi.start == self.kline.cur_bi_zs.bi_list[-1].end:
|
||||||
|
# 获得类型
|
||||||
|
zs_type = self.kline.cur_bi_zs.get_type()
|
||||||
|
|
||||||
|
# 记录下,这一笔已经执行过判断了
|
||||||
|
self.last_found_bi = self.kline.cur_bi.start
|
||||||
|
|
||||||
|
# 不一致时,才写入
|
||||||
|
if zs_type != self.last_found_type:
|
||||||
|
self.last_found_type = zs_type
|
||||||
|
append_data(file_name=demo_05_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_zs.low,
|
||||||
|
'operation': zs_type
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
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_05_dist, # 本地dist csv文件
|
||||||
|
dist_include_list=['close','enlarge','balance','attact', 'defend']) # 指定输出的文字内容
|
||||||
|
|
||||||
|
sys.exit(qApp.exec_())
|
15
examples/stock/demo_05_dist.csv
Normal file
15
examples/stock/demo_05_dist.csv
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
datetime,vt_symbol,volume,price,operation
|
||||||
|
2019-08-08 09:30:00,600000.SSE,0,103.18809,close
|
||||||
|
2019-08-15 09:30:00,600000.SSE,0,103.18809,defend
|
||||||
|
2019-11-22 09:30:00,600000.SSE,0,109.01899,defend
|
||||||
|
2019-12-18 09:30:00,600000.SSE,0,103.18809,defend
|
||||||
|
2020-01-06 09:30:00,600000.SSE,0,103.18809,defend
|
||||||
|
2020-05-13 09:30:00,600000.SSE,0,99.3025,attact
|
||||||
|
2020-06-02 09:30:00,600000.SSE,0,99.3025,close
|
||||||
|
2020-06-12 09:30:00,600000.SSE,0,99.3025,defend
|
||||||
|
2020-12-08 09:30:00,600000.SSE,0,90.84916,enlarge
|
||||||
|
2021-01-25 09:30:00,600000.SSE,0,90.84916,close
|
||||||
|
2021-02-02 09:30:00,600000.SSE,0,90.84916,enlarge
|
||||||
|
2021-02-08 09:30:00,600000.SSE,0,90.84916,close
|
||||||
|
2021-05-28 09:30:00,600000.SSE,0,100.66281,enlarge
|
||||||
|
2021-09-22 09:30:00,600000.SSE,0,87.15689,enlarge
|
|
221
examples/stock/demo_06.py
Normal file
221
examples/stock/demo_06.py
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
# 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_06_dist = 'demo_06_dist.csv'
|
||||||
|
|
||||||
|
|
||||||
|
class DemoStrategy(FakeStrategy):
|
||||||
|
# 输出csv的head
|
||||||
|
dist_fieldnames = ['datetime', 'vt_symbol', 'volume', 'price',
|
||||||
|
'operation']
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
# 最后一个执行检查的分笔开始位置
|
||||||
|
self.last_check_bi = None
|
||||||
|
|
||||||
|
# 最后一个检查线段
|
||||||
|
self.last_found_duan = None
|
||||||
|
|
||||||
|
# 最后一个判断类型(趋势、盘整)
|
||||||
|
self.last_found_type = None
|
||||||
|
|
||||||
|
# 最后一个判断背驰的分型信号
|
||||||
|
self.last_found_beichi = None
|
||||||
|
|
||||||
|
# 如果之前存在,移除
|
||||||
|
if os.path.exists(demo_06_dist):
|
||||||
|
self.write_log(f'移除{demo_06_dist}')
|
||||||
|
os.remove(demo_06_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 or self.kline.cur_bi_zs is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
cur_fx = self.kline.fenxing_list[-1]
|
||||||
|
# 分型未结束,不做判断
|
||||||
|
if cur_fx.is_rt:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 当前段与上一次检查的段,开始时间不同,执行检查
|
||||||
|
if self.kline.cur_duan.start != self.last_found_duan:
|
||||||
|
|
||||||
|
# 判断条件:
|
||||||
|
# 当前线段后出现一个分笔
|
||||||
|
# 当前线段的结束时间比最后一个中枢晚
|
||||||
|
if self.kline.cur_duan.end == self.kline.cur_bi.start \
|
||||||
|
and self.kline.cur_duan.end > self.kline.cur_bi_zs.end\
|
||||||
|
and self.kline.cur_bi.start != self.last_check_bi:
|
||||||
|
|
||||||
|
# 判断是否盘整, 当前线段比上一线段短
|
||||||
|
if self.kline.pre_duan and self.kline.pre_duan.height * 0.62 > self.kline.cur_duan.height:
|
||||||
|
# 获取该线段start -> end 之间,存在的中枢
|
||||||
|
zs_list = [zs for zs in self.kline.bi_zs_list if zs.start > self.kline.cur_duan.start and zs.end < self.kline.cur_duan.end]
|
||||||
|
# 存在的一个中枢
|
||||||
|
if len(zs_list) == 1:
|
||||||
|
# 记录该笔已经检查过
|
||||||
|
self.last_check_bi = self.kline.cur_bi.start
|
||||||
|
|
||||||
|
# 盘整名称,price位置
|
||||||
|
if self.kline.cur_duan.direction == 1:
|
||||||
|
self.last_found_type = '下跌盘整'
|
||||||
|
price = self.kline.cur_duan.high
|
||||||
|
else:
|
||||||
|
self.last_found_type = '上涨盘整'
|
||||||
|
price = self.kline.cur_duan.low
|
||||||
|
|
||||||
|
# 写入记录
|
||||||
|
append_data(file_name=demo_06_dist,
|
||||||
|
field_names=self.dist_fieldnames,
|
||||||
|
dict_data={
|
||||||
|
'datetime': datetime.strptime(self.kline.cur_duan.end, '%Y-%m-%d %H:%M:%S'),
|
||||||
|
'vt_symbol': self.vt_symbol,
|
||||||
|
'volume': 0,
|
||||||
|
'price': price,
|
||||||
|
'operation': self.last_found_type
|
||||||
|
})
|
||||||
|
|
||||||
|
# 判断是否趋势
|
||||||
|
if self.kline.is_contain_zs_inside_duan(direction=self.kline.cur_duan.direction,
|
||||||
|
cur_duan=self.kline.cur_duan,
|
||||||
|
zs_num=2):
|
||||||
|
# 记录检查的一笔
|
||||||
|
self.last_check_bi = self.kline.cur_bi.start
|
||||||
|
# 记录检查的线段
|
||||||
|
self.last_found_duan = self.kline.cur_duan.start
|
||||||
|
|
||||||
|
# 趋势名称、价格
|
||||||
|
if self.kline.cur_duan.direction == 1:
|
||||||
|
self.last_found_type = '上涨趋势'
|
||||||
|
price = self.kline.cur_duan.high
|
||||||
|
else:
|
||||||
|
self.last_found_type = '下跌趋势'
|
||||||
|
price = self.kline.cur_duan.low
|
||||||
|
|
||||||
|
# 记录数据
|
||||||
|
append_data(file_name=demo_06_dist,
|
||||||
|
field_names=self.dist_fieldnames,
|
||||||
|
dict_data={
|
||||||
|
'datetime': datetime.strptime(self.kline.cur_duan.end, '%Y-%m-%d %H:%M:%S'),
|
||||||
|
'vt_symbol': self.vt_symbol,
|
||||||
|
'volume': 0,
|
||||||
|
'price': price,
|
||||||
|
'operation': self.last_found_type
|
||||||
|
})
|
||||||
|
|
||||||
|
# 判断是否走势背驰
|
||||||
|
if self.kline.is_zs_beichi_inside_duan(direction=self.kline.cur_duan.direction,
|
||||||
|
cur_duan=self.kline.cur_duan):
|
||||||
|
if cur_fx.index != self.last_found_beichi:
|
||||||
|
self.last_found_beichi = cur_fx.index
|
||||||
|
# 趋势名称、价格
|
||||||
|
if self.kline.cur_duan.direction == 1:
|
||||||
|
self.last_found_type = '上涨背驰'
|
||||||
|
price = self.kline.cur_duan.high
|
||||||
|
else:
|
||||||
|
self.last_found_type = '下跌背驰'
|
||||||
|
price = self.kline.cur_duan.low
|
||||||
|
|
||||||
|
# 记录数据
|
||||||
|
append_data(file_name=demo_06_dist,
|
||||||
|
field_names=self.dist_fieldnames,
|
||||||
|
dict_data={
|
||||||
|
'datetime': datetime.strptime(self.kline.cur_duan.end, '%Y-%m-%d %H:%M:%S'),
|
||||||
|
'vt_symbol': self.vt_symbol,
|
||||||
|
'volume': 0,
|
||||||
|
'price': price,
|
||||||
|
'operation': self.last_found_type
|
||||||
|
})
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
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_06_dist, # 本地dist csv文件
|
||||||
|
dist_include_list=['上涨趋势','下跌趋势','上涨盘整','下跌盘整','上涨背驰','下跌背驰']) # 指定输出的文字内容
|
||||||
|
|
||||||
|
sys.exit(qApp.exec_())
|
3
examples/stock/demo_06_dist.csv
Normal file
3
examples/stock/demo_06_dist.csv
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
datetime,vt_symbol,volume,price,operation
|
||||||
|
2020-07-31 09:30:00,600000.SSE,0,100.17699,下跌背驰
|
||||||
|
2021-02-19 09:30:00,600000.SSE,0,108.04734,下跌盘整
|
|
78
examples/stock/display_snapshot.py
Normal file
78
examples/stock/display_snapshot.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
# flake8: noqa
|
||||||
|
|
||||||
|
# 示例代码
|
||||||
|
# 从策略保存K线数据中,读取某一K线,并显示
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
|
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.data.tdx.tdx_stock_data import *
|
||||||
|
from vnpy.component.cta_line_bar import CtaMinuteBar
|
||||||
|
from vnpy.trader.ui.kline.ui_snapshot import UiSnapshot
|
||||||
|
from vnpy.trader.ui import create_qapp
|
||||||
|
from vnpy.data.common import get_stock_bars
|
||||||
|
|
||||||
|
snapshot_file_name = 'prod/stock_pb/data/stock_clone_value_klines.pkb2'
|
||||||
|
kline_name = '601012.SSE_D1'
|
||||||
|
def get_klines(pkb2_files):
|
||||||
|
"""
|
||||||
|
从缓存加载K线数据
|
||||||
|
:param kline_names: 指定需要加载的k线名称列表
|
||||||
|
:param vt_symbol: 指定股票代码,
|
||||||
|
如果使用该选项,加载 data/klines/strategyname_vtsymbol_klines.pkb2
|
||||||
|
如果空白,加载 data/strategyname_klines.pkb2
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if not os.path.exists(pkb2_files):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
with bz2.BZ2File(pkb2_files, 'rb') as f:
|
||||||
|
klines = pickle.load(f)
|
||||||
|
|
||||||
|
return klines
|
||||||
|
except Exception as ex:
|
||||||
|
print(f'加载缓存K线数据失败:{str(ex)}')
|
||||||
|
return {}
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
# 创建一个假的策略
|
||||||
|
t1 = FakeStrategy()
|
||||||
|
|
||||||
|
file_name = os.path.abspath(os.path.join(vnpy_root,snapshot_file_name))
|
||||||
|
klines = get_klines(file_name)
|
||||||
|
|
||||||
|
print(f'kline names:{klines.keys()}')
|
||||||
|
|
||||||
|
kline = klines.get(kline_name,None)
|
||||||
|
if kline:
|
||||||
|
# 获取kline的切片数据
|
||||||
|
data = kline.get_data()
|
||||||
|
snapshot = {
|
||||||
|
'strategy': "demo",
|
||||||
|
'datetime': datetime.now(),
|
||||||
|
"kline_names": [kline.name],
|
||||||
|
"klines": {kline.name: data}}
|
||||||
|
|
||||||
|
# 创建一个GUI界面应用app
|
||||||
|
qApp = create_qapp()
|
||||||
|
|
||||||
|
# 创建切片回放工具窗口
|
||||||
|
ui = UiSnapshot()
|
||||||
|
# 显示切片内容
|
||||||
|
ui.export(snapshot_file="",
|
||||||
|
d=snapshot,
|
||||||
|
export_file='s.png')
|
||||||
|
#sys.exit(qApp.exec_())
|
||||||
|
else:
|
||||||
|
print(f'not found {kline_name}')
|
Loading…
Reference in New Issue
Block a user