GithubHelp home page GithubHelp logo

vnpy / vnpy_ctastrategy Goto Github PK

View Code? Open in Web Editor NEW
103.0 8.0 106.0 202 KB

VeighNa框架的CTA策略模块

Home Page: https://www.vnpy.com

License: MIT License

Python 99.77% Batchfile 0.23%
vnpy veighna

vnpy_ctastrategy's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vnpy_ctastrategy's Issues

删除策略以后,只会删除cta_strategy_setting.json而不会删除cta_strategy_data.json里的数

strategy_engine.remove_strategy("xxxxx")
调用remove_strategy以后,只有cta_strategy_setting.json里的相应的数据被清理了,但是保存变量的cta_strategy_data.json里的数据没被清理。
这会导致下次如果新建一样名字的策略,会加载之前的数据。这是故意这么设计的吗?为什么呢
从语义来说,既然是删除了策略,就应该把保存的变量也清理干净,就像删除了文件,总不能创建新的同名文件还会残留之前老文件的内容吧?

论坛帖子URL:https://www.vnpy.com/forum/topic/31619-shan-chu-ce-lue-yi-hou-zhi-hui-shan-chu-cta-strategy-setting-jsoner-bu-hui-shan-chu-cta-strategy-data-jsonli-de-shu-ju

需要一个“查找策略”或者“定位策略”的按钮

在左侧面板中,现在只有“添加策略”一个按钮。最好有一个“查找策略”或者“定位策略”的按钮,能通过策略的名字或者关键字,快速查找或者定位到某个具体的策略,这样使用者就可以继续对该策略做停止或者参数修改的动作了。

可变对象在类实例化时不会重复创建,但单策略运行在多品种时需要对同一个类进行多次实例化,如何修改或避免?

parameters: list = []

在Python中,可变对象在类实例化时不会重复创建,这意味着它们在类的多次实例化中是共享的。这与不可变对象(如整数、字符串等)的行为不同,不可变对象在每次实例化时都会创建一个新的对象。

以下是一个简单的例子,说明了可变对象在类实例化中的共享特性:

class MutableObject:
    shared_list = []

    def add_item(self, item):
        self.shared_list.append(item)

# 实例化两个对象
obj1 = MutableObject()
obj2 = MutableObject()

# 在第一个对象上添加一个元素
obj1.add_item(1)

# 第二个对象也会受到影响,因为它们共享同一个可变对象
print(obj2.shared_list)  # 输出 [1]

在这个例子中,shared_list 是一个可变的类级别属性。当我们在 obj1 上添加一个元素时,shared_list 发生了变化,而 obj2 也受到了影响,因为它们都共享同一个列表对象。

这种共享特性对于某些用途可能是有用的,但在某些情况下,它也可能导致上述提到的问题,如内存占用过高、重复初始化和对象状态混乱。因此,在设计类时,我们需要注意对象的可变性,并确保适当地使用可变和不可变对象,以避免潜在的问题。

bug: array mananger 计算 bollingerbands

一个在特定数据场景下出现的 am.boll 计算的错误,这个 bug 应该是 talib 的,代码如下所示:

import numpy as np
import talib as ta

close = np.array([
    0.06357,0.06359,0.06369,0.06356,0.06364,0.06358,0.06354,0.06345,0.0634,
    0.06345,0.0634 ,0.06346,0.06345,0.06372,0.06349,0.06378,0.06375,0.06381,
    0.06377,0.06364,0.06377,0.06361,0.06365,0.06379,0.06385,0.06381,0.06371,
    0.0637 ,0.06369,0.06369,0.06369,0.0638 ,0.06396,0.06392,0.06389,0.06382,
    0.06395,0.06393,0.064  ,0.06394,0.06387,0.0638 ,0.06385,0.06391,0.06389,
    0.06392,0.06395,0.06392,0.064  ,0.064  ,0.06411,0.06408,0.06405,0.06408,
    0.06403,0.06403,0.064  ,0.06401,0.06395,0.06395
])

sma = ta.SMA(close, 30)[-1]
std = ta.STDDEV(close, 30, 1)[-1]

up = sma + 2.8 * std
down = sma - 2.8 * std

print("原有方式:", sma, std, up, down)

bbands = ta.BBANDS(close, 30, 2.8, 2.8)
print("自带的 bbands:", bbands[0][-1], bbands[2][-1])

std = close[-30:].std()
up = sma + 2.8 * std
down = sma - 2.8 * std

print("使用 np 计算 std:", sma, std, up, down)

输出如下:

原有方式: 0.06394333333333334 0.0 0.06394333333333334 0.06394333333333334
自带的 bbands: 0.06394333333333334 0.06394333333333334
使用 np 计算 std: 0.06394333333333334 9.17363371601224e-05 0.06420019507738169 0.06368647158928499

talib 的 STDDEV 计算的标准差不知道为什么在这个数据集的计算结果为 0,估计要看 talib 源码了,但是 github 上没有找到,建议换成 numpy 的 std 计算标准。

不想引入其他技术指标库了,写了一个完全用 numpy 实现的 bollinger bands。

如下代码:

import numpy as np
from numpy.lib.stride_tricks import sliding_window_view as rolling

def boll(source, window, ndev, array=False):
    rolling_source = rolling(source, window_shape=window)

    sma: np.ndarray = rolling_source.mean(axis=1)
    std: np.ndarray = rolling_source.std(axis=1)

    up: np.ndarray = sma + ndev * std
    down: np.ndarray = sma - ndev * std

    if array:
        return up, down
    return up[-1], down[-1]

文件template中,函数sell和cover注释代码不一致

bug说明:在文件template.py中
函数sell中
注释:Send sell order to close a long position.
代码:return self.send_order(
Direction.SHORT,
Offset.CLOSE,
price,
volume,
stop,
lock,
net
)
修改:这里的Direction.SHORT是不是应该改成Direction.LONG?
函数cover中
注释:Send cover order to close a short position.
代码:return self.send_order(
Direction.LONG,
Offset.CLOSE,
price,
volume,
stop,
lock,
net
)
修改:同上,这里Direction.LONG是不是应该改成Direction.SHORT?

load_strategy_class_from_folder不能识别linux目录下的策略文件

bug说明:pathname没有区分windows及linux/Mac OS,导致非linux环境下,不能找到strategies目录下的策略文件
修正:pathname需要区分是否为windows环境
示例:
import platform
platform_name: str = platform.system().lower()
if platform_name == 'windows':
pathname: str = str(path) + f"\.{suffix}"
else:
pathname: str = str(path) + f"/
.{suffix}"

callback(data)重复调用

应该把backtesting.py在load_bar函数下的callback调用加回来,把template下load_bar函数下的callback调用删掉(导致elite版本重复调用)

回测停止单被错误触发

环境

  • 操作系统: Debian
  • Python版本: 3.10
  • VeighNa版本: V3.9.0

Issue类型

Bug

重现步骤

回测的时候,在用limit_order 开单成功后,在 on_trade() 里面新下一个止损的停止单。
这个停止单会被当前bar 触发成交,这是不合理的

问题分析

backtesting 的执行逻辑如下,cross_limit_order() 里面触发 on_trade(), 然后新发出一个止损的stop_order。
这个stop_order 会被下面的 cross_stop_order() 触发成交,当前bar 已经走完,这里触发成交是不合理的。

` def new_bar(self, bar: BarData) -> None:
""""""
self.bar = bar
self.datetime = bar.datetime

    self.cross_limit_order()
    self.cross_stop_order()
    self.strategy.on_bar(bar)

`

回测成交为空报错

建议在backtesting.py中的calculate_result函数下进行results判断,没有results就输出日志,有results再给self.daily_df赋值

callback(bar) 重复调用

https://github.com/vnpy/vnpy_ctastrategy/blob/main/vnpy_ctastrategy/backtesting.py#L789

重复调用 callback(bar) 导致重复调用on_bar
vnpy_ctastrategy/template.py

    def load_bar(
        self,
        days: int,
        interval: Interval = Interval.MINUTE,
        callback: Callable = None,
        use_database: bool = False
    ) -> None:

        if not callback:
            callback: Callable = self.on_bar

        bars: List[BarData] = self.cta_engine.load_bar(
            self.vt_symbol,
            days,
            interval,
            callback,
            use_database
        )

        for bar in bars:
            callback(bar)

vnpy_ctastrategy/backtesting.py

    def load_bar(
        self,
        vt_symbol: str,
        days: int,
        interval: Interval,
        callback: Callable,
        use_database: bool
    ) -> List[BarData]:
        """"""
        self.callback = callback

        init_end = self.start - INTERVAL_DELTA_MAP[interval]
        init_start = self.start - timedelta(days=days)

        symbol, exchange = extract_vt_symbol(vt_symbol)

        bars: List[BarData] = load_bar_data(
            symbol,
            exchange,
            interval,
            init_start,
            init_end
        )

        for bar in bars:
            callback(bar)

        return bars

如果在子线程使用roll_over, 因为直接调用了 QTextEdit 的append函数,会报错。

子线程使用roll_over中进行移仓,因为直接调用了 QTextEdit 的append函数,这个时候就会出现下面的错误:
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)

代码:
def write_log(self, text: str) -> None:
""""""
now = datetime.now()
text = now.strftime("%H:%M:%S\t") + text
self.log_edit.append(text)

修改使用定义信号,改为信号槽
log_signal: QtCore.pyqtSignal = QtCore.pyqtSignal(str)

    def __init__
    ...
    self.log_signal.connect(self.log_txt_append)
    ...

def write_log(self, text: str) -> None:
	""""""
	now = datetime.now()
	text = now.strftime("%H:%M:%S\t") + text
	self.main_engine.write_log(text)
	self.log_signal.emit(text)

def log_txt_append(self,text):
	self.log_edit.append(text)
	self.log_edit.moveCursor(QtGui.QTextCursor.End)

在返回成交信息很多时候,sync_strategy_data写入卡住

在ctaEngine 中 的process_trade_event,如在开盘时候挂单成交策略较多,挂单成交信息返回较多且散时,其中的sync_strategy_data 写入variables到json文件会卡住,没有报错信息,但是有策略没有更新,虽然内存中pos持仓正确,如果突然重启发现variables错误。

可以考虑使用更新到数据库,有缓冲机制;或者thread写入json file使用单独线程

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.