VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 92
声望: 8

经过好几天的反复,终于完成了。所谓的复盘,就是盘后把行情从新播放一遍,如果使用tick数据,就和真实的盘面一模一样,我这里使用的是1分钟数据复盘,所以简化了很多。

代码如下:

import multiprocessing
import time
from datetime import datetime
from vnpy.trader.constant import Exchange, Interval
from vnpy.trader.database import database_manager
from vnpy.chart import ChartWidget, VolumeItem, CandleItem
from vnpy.trader.ui import create_qapp, QtCore
from vnpy.trader.object import BarData
import os

bar: BarData

def putbardata(q_1m,q_5m,q_30m,q_4h,su):

#从数据库中读取1分钟数据,你的数据库必须有下载好的数据。
    bars = database_manager.load_bar_data(
        symbol="APEUSDT",
        exchange=Exchange.BINANCE,
        interval=Interval.MINUTE,
        start=datetime(2022, 5, 4),
        end=datetime(2025, 1, 1)
    )
    sudu = 0.055

    i = 0
    for bar in bars:
        q_1m.put(bar)
        q_5m.put(bar)
        q_30m.put(bar)
        q_4h.put(bar)
        if i > 1200:                                          #先快速播放一定数量的一分钟bar
            if not su.empty():
                sudu = int(su.get(True))
                print("速度已经设定为:", sudu)
            if i % 10 == 1 :
                os.system("pause")                  #正常播放以后,每10个一分钟bar暂停一下,按任意键继续,不需要这个功能的可以删掉。
        time.sleep(sudu)
        i = i + 1

def MINUTE_5m(q):
    app = create_qapp()
    widget = ChartWidget()
    widget.add_plot("candle", hide_x_axis=True)
    widget.add_plot("volume", maximum_height=180)
    widget.add_item(CandleItem, "candle", "candle")
    widget.add_item(VolumeItem, "volume", "volume")
    widget.add_cursor()
    history : BarData
    history = []
    global i_5
    i_5 = 0
    global bar_

    def update_bar():
        global i_5
        global bar_
        if not q.empty():
            bar = q.get(True)
            if i_5 == 0  :
                bar_ = bar
                i_5 =  1
                history.append(bar_)
            if i_5 == 5  :
                bar_ = bar
                i_5 = 1
                history.append(bar_)
            else :
                bar_.close_price = bar.close_price
                if bar.high_price > bar_.high_price:
                    bar_.high_price = bar.high_price
                if bar.low_price < bar_.low_price:
                    bar_.low_price = bar.low_price
                bar_.volume = bar_.volume + bar.volume
                i_5 = i_5 + 1
                history[-1] = bar_                            #这一段是把一分钟数据形成5分钟数据

            widget.clear_all()
            widget.update_history(history)            #刷新图形数据

    timer = QtCore.QTimer()
    timer.timeout.connect(update_bar)
    timer.start(50)
    widget.setWindowTitle("五分钟")            #设定五分钟窗口的标题和窗口大小以及位置
    widget.setGeometry(0, 0, 900, 550)
    widget.show()
    app.exec_()

def MINUTE_30m(q):                                     #30分钟和5分钟类似
    app = create_qapp()
    widget = ChartWidget()
    widget.add_plot("candle", hide_x_axis=True)
    widget.add_plot("volume", maximum_height=180)
    widget.add_item(CandleItem, "candle", "candle")
    widget.add_item(VolumeItem, "volume", "volume")
    widget.add_cursor()
    history: BarData
    history = []

    global i_30
    i_30 = 0
    global bar_

    def update_bar():
        global i_30
        global bar_
        if not q.empty():
            bar = q.get(True)
            if i_30 == 0  :
                bar_ = bar
                i_30 =  1
                history.append(bar_)
            if i_30 == 30  :
                bar_ = bar
                i_30 = 1
                history.append(bar_)
            else :
                bar_.close_price = bar.close_price
                if bar.high_price > bar_.high_price:
                    bar_.high_price = bar.high_price
                if bar.low_price < bar_.low_price:
                    bar_.low_price = bar.low_price
                bar_.volume = bar_.volume + bar.volume
                i_30 = i_30 + 1
                history[-1] = bar_

            widget.clear_all()
            widget.update_history(history)

    timer = QtCore.QTimer()
    timer.timeout.connect(update_bar)
    timer.start(50)
    widget.setWindowTitle("三十分钟")
    widget.setGeometry(0, 560, 900, 550)
    widget.show()
    app.exec_()

def MINUTE_4h(q):
    app = create_qapp()
    widget = ChartWidget()
    widget.add_plot("candle", hide_x_axis=True)
    widget.add_plot("volume", maximum_height=180)
    widget.add_item(CandleItem, "candle", "candle")
    widget.add_item(VolumeItem, "volume", "volume")
    widget.add_cursor()
    history: BarData
    history = []

    global i_4h
    i_4h = 0
    global bar_

    def update_bar():
        global i_4h
        global bar_
        if not q.empty():
            bar = q.get(True)
            if i_4h == 0  :
                bar_ = bar
                i_4h =  1
                history.append(bar_)
            if i_4h == 240  :
                bar_ = bar
                i_4h = 1
                history.append(bar_)
            else :
                bar_.close_price = bar.close_price
                if bar.high_price > bar_.high_price:
                    bar_.high_price = bar.high_price
                if bar.low_price < bar_.low_price:
                    bar_.low_price = bar.low_price
                bar_.volume = bar_.volume + bar.volume
                i_4h = i_4h + 1
                history[-1] = bar_

            widget.clear_all()
            widget.update_history(history)

    timer = QtCore.QTimer()
    timer.timeout.connect(update_bar)
    timer.start(50)
    widget.setWindowTitle("四小时")
    widget.setGeometry(860, 560, 1050, 530)

    widget.show()
    app.exec_()

def MINUTE(q):                     #一分钟的是最简单的,直接使用就好。
    app = create_qapp()
    widget = ChartWidget()
    widget.add_plot("candle", hide_x_axis=True)
    widget.add_plot("volume", maximum_height=180)
    widget.add_item(CandleItem, "candle", "candle")
    widget.add_item(VolumeItem, "volume", "volume")
    widget.add_cursor()

    def update_bar():
        if not q.empty():
            bar = q.get(True)
            widget.update_bar(bar)

    timer = QtCore.QTimer()
    timer.timeout.connect(update_bar)
    timer.start(50)
    widget.setWindowTitle("一分钟")
    widget.setGeometry(860, 15, 1050, 550)
    widget.show()
    app.exec_()


if __name__ == '__main__':
    manager = multiprocessing.Manager()
    q_1m = manager.Queue()
    q_5m = manager.Queue()
    q_30m = manager.Queue()
    q_4h = manager.Queue()
    su = manager.Queue()

    pw = multiprocessing.Process(target=putbardata, args=(q_1m,q_5m,q_30m,q_4h,su))
    pr_1m = multiprocessing.Process(target=MINUTE, args=(q_1m,))
    pr_5m = multiprocessing.Process(target=MINUTE_5m, args=(q_5m,))
    pr_30m = multiprocessing.Process(target=MINUTE_30m, args=(q_30m,))
    pr_4h = multiprocessing.Process(target=MINUTE_4h, args=(q_4h,))

    pw.start()
    pr_1m.start()
    pr_5m.start()
    pr_30m.start()
    pr_4h.start()

    sudu = input("请输入速度:")
    su.put(sudu)

    time.sleep(1000000)
    print('任务完成')

大概说一下原理,程序设定了5个进程,通过通道交换数据,其中一个进程发送数据,另外4个进程接受数据,接受数据的四个进程就是4个周期的窗口,把接受的一分钟数据变化成3分钟30分钟等,并用图形展示出来。
只要控制发送数据的节奏,就可以动态的把行情从新演示一遍了。

这是盘后复盘用的,可以回忆一下当天到底发生了什么。

国内期货有一个盘立方软件是可以完美复盘的,数字货币没有这个东西,tradingview有这个功能,但是每月要收费90元,而且tradingview也只能使用1分钟数据复盘。

身为程序员,当然不愿意掏钱,因为自己可以写一个。

感谢vnpy提供的ChartWidget,真的很好用。

Member
avatar
加入于:
帖子: 387
声望: 20

感谢分享!!

Member
avatar
加入于:
帖子: 25
声望: 1

感谢,请问是在哪个文件下进行的修改呢?

Member
avatar
加入于:
帖子: 92
声望: 8

woodlandnight wrote:

感谢,请问是在哪个文件下进行的修改呢?
直接运行就好。

Member
avatar
加入于:
帖子: 33
声望: 0

感谢分享!

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号-3

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】