教程
信号开发
开发、清理、排名和验证交易信号
会员内容预览(英文)
Signals add an extra layer of abstraction on top of orders. Instead of specifying every detail about
what needs to be ordered at each timestamp, you can define what a typical order should look like and
then decide when to issue such an order. In VBT, this timing decision is made using signals, which
are represented as boolean masks: True stands for "order" and False means "no order". The
meaning of each signal can be changed either statically or dynamically, depending on the current
simulation state. For example, you can instruct the simulator to ignore an "order" signal if you are
already in the market, which is not possible with the "from-orders" method alone. Because VBT
emphasizes data science, it is much easier to compare multiple strategies with the same trading
conditions but different signal permutations (for example, order timings and directions). This
approach reduces errors and leads to more fair experiments.
Since buying and selling are constant activities, it is ideal to include the order direction within each signal as well. However, because booleans only have two states, they cannot represent the three possibilities: "order to buy", "order to sell", and "no order". As a result, signals are typically distributed across two or more boolean arrays, each representing a different decision dimension. The most common way to define signals is by using two direction-unaware arrays: 1️⃣ entries and 2️⃣ exits. The meaning of these two arrays changes based on the direction, which is specified using a separate variable. For instance, when only the long direction is enabled, an entry signal opens a new long position and an exit signal closes it. When both directions are enabled, an entry signal opens a new long position, and an exit signal reverses it to open a short one. For more precise control over whether to reverse a position or simply close it, you can define four direction-aware arrays: 1️⃣ long entries, 2️⃣ long exits, 3️⃣ short entries, and 4️⃣ short exits. This method provides the greatest flexibility.
For example, to open a long position, close it, open a short position, and then reverse it, the signals would look like this:
| Long entry | Long exit | Short entry | Short exit |
|---|---|---|---|
| True | False | False | False |
| False | True | False | False |
| False | False | True | False |
| True | False | False | False |
The same strategy can also be defined using an entry signal, an exit signal, and a direction:
| Entry | Exit | Direction |
|---|---|---|
| True | False | Long only |
| False | True | Long only |
| True/False | False/True | Short only/Both |
| True | False | Long only/Both |
Direction-unaware signals can be easily converted to direction-aware signals:
- True, True, Long only → True, True, False, False.
- True, True, Short only → False, False, True, True.
- True, True, Both → True, False, True, False.
However, direction-aware signals cannot be converted to direction-unaware signals if both directions are enabled and there is an exit signal present:
- False, True, False, True → ❓
Therefore, it is important to carefully evaluate which conditions you are interested in before generating signals.
You might wonder why not use an integer data type, where a positive number means "order to buy," a
negative number means "order to sell," and zero means "no order," as is done in backtrader. Boolean
arrays are much easier for users to generate and maintain. In addition, a boolean NumPy array uses
eight times less memory than a 64-bit signed integer NumPy array. Boolean masks are also much more
convenient to combine and analyze than integer arrays. For example, you can combine two masks with
the logical OR (| in NumPy) operator, or sum the elements in a mask to get the number of signals.
Since booleans are a subtype of integers, they behave just like regular integers in most math
expressions.
Comparison
Properly generating signals can sometimes be much more challenging than simulating them. This is because you need to consider not only the distribution of signals but also how they interact across multiple boolean arrays. For example, setting both an entry and exit at the same timestamp will effectively cancel both. That's why VBT offers many functions and techniques to support you in this process.
Signal generation usually begins by comparing two or more numeric arrays. Remember, when comparing entire arrays, you iterate over each row and column (that is, each element) in a vectorized way and compare their scalar values at each element. Essentially, you run the same comparison operation on every single element across all the arrays being compared. Let's look at an example using Bollinger Bands for two different assets. At each timestamp, we will place a signal whenever the low price is below the lower band, expecting the price to reverse back to its rolling mean:
信号是使用 VBT 模拟交易策略时最强大的工具之一。
✅ 学习通过向量化和迭代两种方法,将任何交易策略转换为信号,并分析其分布,以发现策略中的逻辑缺陷 🌗
会员主题(英文内容)
版权所有 © 2021–2026 Oleg Polakow。保留所有权利。
本站内容与文档供使用和评估 VectorBT PRO 以及教育用途。任何其他用途,包括开发或支持竞争产品或服务,均须事先取得书面同意。