@clawhub-zhangxinyu0330-23b4534876
A universal tutoring skill for teaching any complex or unfamiliar subject to a complete beginner through structured dialogue, then producing a polished tutor...
---
name: beginner-tutor
description: >
A universal tutoring skill for teaching any complex or unfamiliar subject to a
complete beginner through structured dialogue, then producing a polished tutorial
document for archiving and sharing. Use this skill whenever a user says they are
new to a topic, wants to learn something from scratch, needs to understand a subject
for their job, or asks "can you teach me about X". Also use when a user wants to
create a beginner-friendly tutorial, explainer, or learning guide on any topic.
This skill is domain-agnostic: it works for technical fields (finance, engineering,
medicine), professional domains (law, marketing, design), and academic subjects alike.
Trigger even for vague requests like "I don't understand X at all", "help me learn
about Y", or "I need to get up to speed on Z fast".
---
# Universal Beginner Tutor Skill
A structured dialogue-first workflow for teaching any complex subject to a complete
beginner, ending in a polished, shareable tutorial document.
The core philosophy: **understanding first, document second.**
Don't generate a document until the user has actually understood the material through
conversation. The document is a record of real understanding, not a substitute for it.
---
## Phase 1: Intake — Understand the Learner
Before teaching anything, collect three pieces of information.
Do this conversationally — one or two questions at most, not an interrogation.
Infer from context wherever possible.
### 1A. What do they want to learn?
Get a clear subject. If vague, narrow it down:
- "Finance" → "which part? investing, accounting, corporate finance, quantitative?"
- "Programming" → "for what purpose? web, data analysis, automation?"
- "Medicine" → "general biology, a specific condition, how healthcare works?"
Don't over-narrow. Let the user's goal guide the scope, not your assumptions.
### 1B. What is their background?
This is the most important variable. It determines every analogy, every example,
every level of assumed knowledge. Identify the closest match:
| Background Type | Key Signal | Teaching Approach |
|---|---|---|
| **Technical/Engineering** | mentions code, systems, math | Use structural analogies, pseudocode, data models |
| **Non-technical/General** | no domain-specific language | Use everyday life analogies, stories, visual descriptions |
| **Adjacent domain** | knows a related field | Bridge from what they know to what they're learning |
| **Practitioner, new skill** | experienced professional learning adjacent topic | Skip basics of their own domain; focus on the bridge |
If unclear, default to the general approach and adjust as the conversation develops.
### 1C. What is their goal?
Why are they learning this? The goal shapes what depth and angle to take:
- "I need to explain this to others" → focus on clear mental models, not depth
- "I need to use this in my job" → focus on practical application
- "I'm just curious" → follow their interest, don't force a structure
- "I need to pass an exam" → focus on definitions and key distinctions
Once you have these three, confirm your understanding briefly and propose a starting point.
---
## Phase 2: Teach — Structured Dialogue
Work through the subject conversationally, one concept at a time.
Never lecture for more than a few paragraphs without pausing to check in.
### The Teaching Loop (repeat for each concept)
```
1. ANCHOR → Connect to something the learner already knows
2. INTUITION → Explain what the concept is and why it exists
3. EXAMPLE → Give a concrete, specific, worked example
4. FORMULA → Introduce any formal definition or notation (if needed)
5. CHECK → Invite questions; look for signals of understanding
6. BRIDGE → Connect to the next concept
```
Never skip steps 1–3. Steps 4 and 6 can be omitted for simpler concepts.
### Analogy Principles
Analogies are the most powerful teaching tool. Use them aggressively.
**A good analogy:**
- Uses something the learner definitely already understands
- Maps the *structure* of the new concept, not just the surface
- Has clear limits (know when the analogy breaks down and say so)
**Analogy selection by background:**
- Technical → use systems, data structures, algorithms, engineering processes
- General → use everyday situations: shopping, cooking, weather, sports, jobs
- Adjacent domain → use their existing domain as the analogy
**Multiple analogies**: If the first analogy doesn't land, try a completely different one.
Don't repeat the same analogy with different words.
### Explaining "Why", Not Just "What"
For every concept, especially every processing step or formula, explain:
1. What problem does this solve?
2. What goes wrong if you skip it?
Example pattern:
> "We do X because without it, Y happens. Here's a concrete case where Y happens: [example]."
This is especially important for steps that seem arbitrary (e.g., "why normalize?",
"why skip the most recent month in momentum?", "why use median instead of mean?").
### Handling Good Questions
When the learner asks a question that reveals they've made a connection or insight,
**explicitly confirm and reinforce it**:
> "Exactly — you've identified the core reason."
> "That's exactly right, and it's a subtle point most people miss."
> "Yes, and the fact that you noticed that means you really understand X."
This builds confidence and makes the learning stick.
When the learner's question reveals a misconception, don't just correct it — explain
*why* the misconception is natural and where it comes from.
### Pacing and Depth
- Cover one concept fully before moving to the next
- If the learner seems lost, try a different analogy before adding more detail
- If the learner seems bored or ahead, accelerate and skip basics
- Always ask before diving deep: "Do you want me to go deeper on this, or shall we move on?"
### Concept Sequencing
Build a dependency map mentally as you go. Ensure prerequisites are taught before
dependents. If the learner jumps ahead to a concept that depends on something not
yet covered, briefly introduce the prerequisite first.
General sequencing principle:
```
What is this field / why does it exist?
↓
What are the key objects / entities?
↓
What data / information is involved?
↓
What are the core operations / processes?
↓
How are results evaluated?
↓
How are new things discovered / created in this field?
```
---
## Phase 3: Consolidate — Build the Mental Model
After covering the core material, help the learner consolidate before generating the document.
### Summary Map
Offer to draw a concept map or summary showing how everything connects:
```
[Concept A] → required for → [Concept B]
[Concept B] + [Concept C] → combine into → [Concept D]
```
This helps the learner see the structure, not just a list of disconnected ideas.
### Key Insight Check
Ask the learner to articulate 2–3 key things they learned in their own words.
This surfaces gaps and reinforces retention. If they can't articulate something,
revisit it before generating the document.
### Common Misconceptions Review
Briefly flag the most common misconceptions in this domain and confirm the learner
hasn't absorbed them:
> "One thing people often get wrong here is [X]. Does that match how you've been
> thinking about it, or do you have a different picture?"
---
## Phase 4: Document — Generate the Tutorial
Only generate the document after Phase 2 and 3 are complete, or when the learner
explicitly asks for it. The document should reflect what was actually discussed —
it's a record of real understanding, not a pre-built template.
### Before Writing, Confirm Three Things
1. **Audience**: Who will read this? (same background as the learner, or different?)
2. **Scope**: Which concepts are in scope? What's intentionally excluded?
3. **Format**: Markdown (recommended for sharing), Word (.docx), or inline display?
### Document Structure
Use this structure as the default. Adjust based on the subject and audience.
```
# [Subject] 入门教程 / Beginner's Guide to [Subject]
## 前言 / Introduction
- Who this is for (background assumed)
- What you'll learn
- What this guide does NOT cover
## Chapter 1: Why This Field Exists
- The problem this field solves
- Why it matters in the real world
## Chapter 2–N: Core Concepts (one chapter per major concept cluster)
Each chapter follows the teaching loop structure:
- Intuition / analogy
- Formal definition (if needed)
- Worked example with numbers/concrete details
- Common mistakes / misconceptions
## Final Chapter: The Complete Picture
- How all concepts connect (the mental model map)
- Suggested next steps for further learning
## Appendix: Quick Reference
- Key terms and one-line definitions
- Formulas (if applicable)
- Further reading
```
### Writing Principles for the Document
**Lead with intuition, not definition.**
Never open a section with a formal definition. Always start with the "why" or an analogy.
**Use concrete examples throughout.**
Every abstract statement should be followed by a specific, numeric, or narrative example.
"Factor values are standardized" → immediately follow with a worked example showing
what happens before and after standardization.
**Match the audience's language.**
- Technical audience: precise terminology is fine; include code snippets where useful
- General audience: avoid jargon; if jargon is unavoidable, define it immediately
- Mixed audience: use plain language, with technical terms in parentheses
**Tables for comparisons, prose for explanations.**
Use tables to compare options (e.g., "method A vs method B").
Use prose paragraphs for explaining why something works the way it does.
Don't put explanations in bullet points — they fragment reasoning.
**Explicit "why" sections.**
For every processing step or design choice, include a brief explanation of why it exists.
Label these clearly: "Why do we do this?" or "Why not just...?"
**Quick reference at the end.**
Always include a glossary / key terms table. This is the section people return to most.
### Language
Write the document in the same language used in the conversation.
If the conversation was in Chinese, write in Chinese.
If mixed, default to Chinese unless the user specifies otherwise.
---
## Phase 5: Iterate
After presenting the document, invite feedback:
- "Does this capture what you learned today?"
- "Is there anything missing or that should be explained differently?"
- "Is the level right for the intended audience?"
Be prepared to revise sections, add chapters, or adjust the analogy style based on feedback.
---
## Principles Summary
These principles distill everything above into a quick reference for applying this skill:
```
1. Background first Learn who you're teaching before you teach anything
2. Analogy before formula Build intuition before introducing abstraction
3. Why before what Explain the problem before the solution
4. One concept at a time Don't move on until understanding is confirmed
5. Reinforce insights When the learner connects dots, say so explicitly
6. Document last The document records understanding, not replaces it
7. Match the audience The document's language and style must fit its reader
```
---
## Reference Files
- `references/analogy-patterns.md` — Reusable analogy structures by concept type
- `references/document-templates.md` — Full document templates by audience type
FILE:references/analogy-patterns.md
# Analogy Patterns by Concept Type
A library of reusable analogy structures. When teaching a new concept, find the
closest pattern here and adapt it to the subject matter.
---
## Pattern 1: The Scoring System
**Use for**: Indices, metrics, composite scores, rankings, standardization
> "Think of it like a college application score. GPA, test scores, and extracurriculars
> are all measured on different scales. To combine them fairly, you have to convert
> them all to a common scale — like percentile rank — before adding them up.
> Otherwise GPA (out of 4.0) would be drowned out by test scores (out of 1600)."
**Applies to**: Factor standardization, composite indices, weighted scoring models,
multi-metric evaluation, normalization in ML.
---
## Pattern 2: The Sensor Fusion
**Use for**: Combining multiple signals, ensemble methods, multi-factor models
> "A self-driving car doesn't rely on just one sensor. It uses cameras, LIDAR, radar,
> and GPS together. Each sensor has blind spots. Combined, they cover each other's
> weaknesses. The car is more reliable than any single sensor alone."
**Applies to**: Multi-factor models, ensemble ML, triangulation in research,
cross-referencing sources, diversification.
---
## Pattern 3: The Two Views of a Spreadsheet
**Use for**: Time series vs. cross-section, row vs. column operations, longitudinal vs. lateral
> "Imagine a spreadsheet where rows are dates and columns are items (stocks, people,
> products). Reading down one column = time series (one item over time).
> Reading across one row = cross-section (all items at one moment)."
**Applies to**: Any domain with panel data, before/after comparisons, cohort analysis,
longitudinal studies.
---
## Pattern 4: The Recipe Adjustment
**Use for**: Normalization, scaling, adjusting for confounds, removing baseline effects
> "A recipe says 'add 2 cups of flour' — but that's for 4 servings.
> If you're making 12 servings, you scale everything up proportionally.
> Normalization is the same: adjusting a value so it's comparable regardless of
> the 'serving size' (time period, market conditions, population size)."
**Applies to**: Per-capita adjustments, seasonal adjustment, inflation adjustment,
log transformation, adjusted prices.
---
## Pattern 5: The Track Record
**Use for**: Backtesting, historical validation, using past performance to estimate future
> "Before hiring a contractor, you check their past projects. You're not guaranteed
> the future will match the past — but it's the best evidence you have.
> Backtesting is the same: checking how a strategy would have performed historically
> to estimate whether it's likely to work going forward."
**Applies to**: Backtesting, A/B test history, model validation, evidence-based
decision making, clinical trial history.
---
## Pattern 6: The Exam Grader
**Use for**: Prediction accuracy, correlation, IC value, model evaluation
> "Imagine a student who always predicts 'sunny' for tomorrow's weather.
> Sometimes they're right. But a good forecaster should be right *systematically*,
> not just occasionally. The IC (or correlation) measures whether high predictions
> consistently match high outcomes — not just whether any single prediction was right."
**Applies to**: Correlation, prediction accuracy, precision/recall, IC in finance,
any metric measuring systematic predictive power.
---
## Pattern 7: The Contaminated Evidence
**Use for**: Look-ahead bias, data leakage, confounded experiments
> "Imagine a detective who 'solves' cases by reading tomorrow's newspaper.
> They're always right — but completely useless in real life.
> Look-ahead bias in data analysis is the same: accidentally using information
> that wouldn't have been available at decision time makes results look great
> but impossible to replicate."
**Applies to**: Data leakage in ML, look-ahead bias in backtesting, hindsight bias
in case studies, survivorship bias, contaminated control groups.
---
## Pattern 8: The Class Average Problem
**Use for**: Survivorship bias, selection bias, incomplete populations
> "You survey 'successful entrepreneurs' about what made them successful.
> But you only interviewed people who succeeded — you can't interview the
> thousands who tried the same things and failed. Your conclusions are biased
> toward success stories."
**Applies to**: Survivorship bias, selection bias, publication bias, sampling bias,
analyzing only existing customers (ignoring churned ones).
---
## Pattern 9: The Tuning Dial
**Use for**: Parameters, hyperparameters, optimization, overfitting
> "Think of it like tuning a radio. Turn too little and you get static (underfitting).
> Turn exactly right and you get a clear signal. Turn too much and you get a different
> station (overfitting — you've tuned so precisely to one frequency that you lose
> generalizability)."
**Applies to**: Hyperparameter tuning, overfitting/underfitting, regularization,
calibration, any adjustable parameter with a sweet spot.
---
## Pattern 10: The Job Interview Panel
**Use for**: Weighted voting, committee decisions, multi-rater evaluation, IC weighting
> "A hiring committee has 5 interviewers. Some have better judgment than others —
> they've historically made better hiring decisions. A smart process gives more
> weight to their opinions. IC weighting is the same: give more influence to the
> signals that have historically been most accurate."
**Applies to**: IC weighting, ensemble weighting, expert aggregation, Bayesian
updating, peer review weighting.
---
## How to Use This Library
1. Identify the **type** of concept you're explaining (scoring, combining signals,
two views, adjustment, validation, accuracy, bias, overfitting, weighting)
2. Find the matching pattern above
3. Adapt the specific domain details to your subject
4. Test whether it lands — if not, try a different pattern
When adapting, keep the *structure* of the analogy intact but swap the surface domain.
The structure is what makes the analogy work.
FILE:references/document-templates.md
# Document Templates by Audience Type
Use these templates as starting points when generating the tutorial document.
Select based on the intended reader's background, then adapt to the subject.
---
## Template A: Technical/Engineering Audience
Best for: Readers with CS, engineering, math, or data science backgrounds.
Tone: Precise, structured, no hand-holding on technical concepts.
Style: Concept → structure → formula → code-like example → edge cases.
```markdown
# [Subject]: A Technical Primer
## Who This Is For
This guide assumes familiarity with [prerequisite technical concepts].
No prior knowledge of [subject] is required.
## Why [Subject] Exists
[Subject] solves the problem of [core problem].
In [reader's domain], the equivalent challenge is [bridge to their domain].
## Core Concepts
### [Concept 1]
**What it is**: [One-sentence definition]
**The structure**:
[Diagram, pseudocode, or data model showing the concept's structure]
**Formal definition**:
[Formula or precise definition]
**Example**:
[Worked numeric or code example with real values]
**Edge cases / common mistakes**:
- [Mistake 1]: [Why it happens and how to avoid it]
- [Mistake 2]: ...
### [Concept 2]
...
## How the Concepts Connect
[Dependency diagram or written explanation of the full mental model]
## Quick Reference
| Term | Definition | Formula / Notes |
|---|---|---|
| [Term 1] | [Definition] | [Formula if applicable] |
| ...
## Next Steps
[Specific, actionable next steps: tools to explore, topics to study next,
hands-on exercises to try]
```
---
## Template B: General / Non-Technical Audience
Best for: Readers with no technical background, from any walk of life.
Tone: Warm, approachable, curiosity-driven. No jargon without explanation.
Style: Story → concept → analogy → example → implication.
```markdown
# 零基础学懂 [Subject] / Understanding [Subject] from Scratch
## 这份教程适合谁 / Who This Is For
你不需要任何 [subject] 的基础。只要你对 [subject] 感到好奇,或者
工作中需要了解这个领域,这份教程就是为你写的。
You don't need any background in [subject]. If you're curious about it,
or need to understand it for work, this guide is for you.
## [Subject] 是什么,为什么重要 / What Is [Subject] and Why Does It Matter
[Subject] 解决的核心问题是 ___。
想象这样一个场景:[vivid, everyday scenario that illustrates the core problem].
[Subject] 就是用来解决这类问题的系统方法。
## 核心概念 / Core Concepts
### [Concept 1]: [Plain-language name]
**先说直觉** / The intuition first:
想象一下 [relatable everyday analogy]. [Subject] 中的 [concept] 就是同样的道理——
[explanation connecting analogy to concept].
**具体是什么** / What it actually is:
[Non-jargon explanation of the concept]
**一个例子** / A concrete example:
[Specific, worked example with real numbers or a mini-story]
**常见误解** / Common misconception:
很多人以为 [misconception]. 实际上 [correction], 因为 [reason].
### [Concept 2]
...
## 把所有概念串起来 / Putting It All Together
[Visual or narrative description of how all concepts connect]
## 你现在理解了什么 / What You Now Understand
读完这份教程,你应该能够:
- [Outcome 1]
- [Outcome 2]
- [Outcome 3]
## 关键词速查 / Key Terms
| 词汇 / Term | 解释 / Meaning |
|---|---|
| [Term] | [Plain-language definition] |
| ...
## 如果你想继续学 / If You Want to Go Deeper
[Approachable next steps: specific books, courses, tools, or communities]
```
---
## Template C: Practitioner / Adjacent Domain Audience
Best for: Experienced professionals learning an adjacent field.
Tone: Peer-to-peer, respects existing expertise, emphasizes the bridge.
Style: Bridge from known → new concept → practical application → differences from their domain.
```markdown
# [Subject] for [Their Profession]: What You Already Know Applies
## For the Experienced [Their Profession] Reader
This guide assumes deep familiarity with [their domain].
It's specifically designed to bridge from what you already know
to the new concepts in [subject].
## The Core Parallel
In [their domain], you deal with [analogous challenge].
[Subject] deals with exactly the same challenge, applied to [new context].
Most of the structure will feel familiar.
## What Maps Directly
| [Their Domain] | [New Subject] | Notes |
|---|---|---|
| [Familiar concept 1] | [New concept 1] | [Differences if any] |
| [Familiar concept 2] | [New concept 2] | ... |
## What's Genuinely New
These concepts don't have direct equivalents in [their domain]:
- **[New concept]**: [Explanation using their domain as a springboard]
## Practical Application
[Subject]-specific workflow applied to problems a [their profession] would recognize.
## Key Differences to Watch Out For
[Subject] differs from [their domain] in these important ways:
- [Difference 1]
- [Difference 2]
## Quick Reference
[Focused glossary of new terms only — skip things they already know]
```
---
## Choosing the Right Template
| Intended Reader | Template |
|---|---|
| Developer, data scientist, engineer | A: Technical |
| General public, student, non-technical professional | B: General |
| Doctor learning data science, lawyer learning finance, etc. | C: Adjacent Domain |
| Mixed audience | B as base, add technical details in callout boxes |
## Customization Notes
- Always replace "[Subject]" with the actual subject throughout
- For Chinese-speaking audiences, use Template B's bilingual approach or write fully in Chinese
- For short topics (< 5 concepts), collapse chapters; don't force structure onto thin content
- Always keep the Quick Reference / Key Terms section — it's the most-referenced part
DolphinDB 时序数据库完整技术文档与最佳实践。包含1490个技术文档 + 3份官方白皮书。涵盖数据库设计、流计算、量化回测、函数查询等全场景。
---
name: dolphindb
description: DolphinDB 时序数据库完整技术文档与最佳实践。包含1490个技术文档 + 3份官方白皮书。涵盖数据库设计、流计算、量化回测、函数查询等全场景。
version: 2.0.0
source: https://docs.dolphindb.cn + Official Whitepapers
author: Optimized by Skill Creator
tags:
- database
- time-series
- streaming
- quantitative-trading
- backtesting
- dolphindb
---
# DolphinDB 完整技术文档与实战指南
**版本**: 2.0.0 (优化版)
**文档数量**: 1490 个技术文档 + 3 份官方白皮书
**DolphinDB版本**: 3.00.4
**更新时间**: 2026-01-22
**文档来源**: https://docs.dolphindb.cn
---
## 📚 核心资源概览
### 🎯 官方白皮书(深度最佳实践)
提供生产级架构设计和完整工作流程指南:
1. **[数据库白皮书](references/whitepapers/database.md)** (1073行)
- DolphinDB 核心架构与分布式设计
- TSDB vs OLAP 存储引擎详解
- 分区策略、高可用、备份恢复
- SQL优化与库内计算
- **适用场景**: 系统架构设计、性能优化、生产部署
2. **[流数据白皮书](references/whitepapers/streaming.md)** (2279行)
- 流计算框架与发布订阅机制
- 7大流计算引擎详解
- 流批一体架构与历史回放
- 金融与物联网场景应用
- **适用场景**: 实时计算、CEP、流式ETL
3. **[中高频回测白皮书](references/whitepapers/backtest.md)** (2205行)
- 完整回测系统架构
- 数据回放与模拟撮合引擎
- DolphinScript/Python/C++ 策略开发
- 量化策略实战案例
- **适用场景**: 量化回测、算法交易、策略研发
### 📖 在线技术文档(1490篇)
按功能领域分类的完整API参考和操作指南:
| 分类 | 文档数量 | 说明 |
|------|---------|------|
| 函数参考/其他函数 | 1171 | 系统函数、网络函数等 |
| 其他 | 97 | 其他技术文档 |
| 函数参考/统计函数 | 61 | 相关性、协方差、标准差等统计指标 |
| 函数参考/数学函数 | 42 | 基础数学运算、三角函数、对数等 |
| 函数参考/SQL函数 | 41 | 查询、关联、聚合等SQL操作 |
| 函数参考/时间序列函数 | 26 | 日期时间处理、时序窗口计算 |
| 流数据处理 | 22 | 流表、订阅、流计算引擎 |
| 数据库核心 | 13 | 存储引擎、分区、事务、高可用 |
| 部署与配置 | 9 | 集群部署、参数配置 |
| 函数参考/字符串函数 | 5 | 字符串操作、正则表达式 |
| API与连接器 | 1 | Python、Java、C++ API |
| 运维管理 | 1 | 监控、备份、权限管理 |
| 教程与示例 | 1 | 快速入门、场景案例 |
**完整文档索引**: 详见 [CATALOG.md](CATALOG.md)
---
## 🚀 常见问题快速导航
### 新手入门
- **如何快速上手DolphinDB?** → [关于 DolphinDB](references/doc_1201.md)
- **如何部署集群?** → [分布式架构](references/doc_6249.md)
- **如何选择存储引擎?** → 查阅 [数据库白皮书](references/whitepapers/database.md) 第3-4章
### 数据库设计
- **如何选择分区策略?** → [数据分区](references/doc_9485.md) + [数据库白皮书](references/whitepapers/database.md)
- **TSDB vs OLAP 如何选择?** → [TSDB存储引擎](references/doc_6240.md) 和 [OLAP存储引擎](references/doc_7837.md)
- **如何优化查询性能?** → [数据库白皮书](references/whitepapers/database.md) 第5章
### 流计算开发
- **如何实现实时计算?** → [流数据白皮书](references/whitepapers/streaming.md)
- **流计算引擎有哪些?** → [流数据白皮书](references/whitepapers/streaming.md) 第3章
- **如何实现流批一体?** → [流数据白皮书](references/whitepapers/streaming.md) 第4章
### 量化回测
- **如何搭建回测系统?** → [回测白皮书](references/whitepapers/backtest.md)
- **如何实现模拟撮合?** → [回测白皮书](references/whitepapers/backtest.md) 第3章
- **如何进行中高频回测?** → [回测白皮书](references/whitepapers/backtest.md) 第4-7章
### 高级功能
- **如何实现高可用?** → [高可用](references/doc_3934.md)
- **如何进行数据备份?** → [数据库白皮书](references/whitepapers/database.md) 第6章
- **如何管理权限?** → [数据库白皮书](references/whitepapers/database.md) 第6.4节
---
## 📝 常用代码示例
### 1. 创建TSDB存储引擎的分区表
```dolphindb
// 组合分区: VALUE(日期) + HASH(股票代码)
db_date = database("", VALUE, 2024.01.01..2024.12.31)
db_sym = database("", HASH, [SYMBOL, 10])
db = database("dfs://stock_data", COMPO, [db_date, db_sym])
// TSDB引擎,支持排序列和去重
schemaTable = table(
1:0,
`trade_time`symbol`price`volume,
[TIMESTAMP, SYMBOL, DOUBLE, LONG]
)
pt = db.createPartitionedTable(
table=schemaTable,
tableName="stock_tick",
partitionColumns=`trade_date`symbol,
sortColumns=`symbol`trade_time, // 排序键
keepDuplicates=LAST, // 去重策略
engine="TSDB"
)
```
### 2. 创建OLAP存储引擎的分区表
```dolphindb
// OLAP引擎适合追加式写入和批量分析
db = database("dfs://stock_analysis", VALUE, 2024.01M..2024.12M)
schemaTable = table(
1:0,
`trade_date`symbol`open`high`low`close`volume,
[DATE, SYMBOL, DOUBLE, DOUBLE, DOUBLE, DOUBLE, LONG]
)
pt = db.createPartitionedTable(
table=schemaTable,
tableName="daily_kline",
partitionColumns=`trade_date,
engine="OLAP"
)
```
### 3. 流计算 - 实时K线合成
```dolphindb
// 1. 创建流表
share streamTable(1:0, `time`sym`price`vol, [TIMESTAMP, SYMBOL, DOUBLE, INT]) as tickStream
share streamTable(1:0, `time`sym`open`high`low`close`volume,
[TIMESTAMP, SYMBOL, DOUBLE, DOUBLE, DOUBLE, DOUBLE, LONG]) as klineStream
// 2. 创建时序聚合引擎
tsEngine = createTimeSeriesEngine(
name="kline_1min",
windowSize=60000, // 1分钟窗口
step=60000,
metrics=<[first(price), max(price), min(price), last(price), sum(vol)]>,
dummyTable=tickStream,
outputTable=klineStream,
timeColumn=`time,
keyColumn=`sym
)
// 3. 订阅流表
subscribeTable(tableName="tickStream", actionName="kline", handler=append!{tsEngine})
// 4. 插入数据测试
insert into tickStream values(2024.01.01T09:30:00.000, `600000, 10.5, 1000)
```
### 4. 中高频回测完整流程
```dolphindb
// 1. 清理环境
try{ unsubscribeTable(tableName="replayStream", actionName="backtest") }catch(ex){}
try{ dropStreamEngine("backtestEngine") }catch(ex){}
// 2. 创建回放流表
share streamTable(1:0, `time`sym`price`vol, [TIMESTAMP, SYMBOL, DOUBLE, INT]) as replayStream
// 3. 创建回测引擎(需要加载回测插件)
loadPlugin("/path/to/backtest_plugin.so")
backtestEngine = createBacktestEngine(
name="my_strategy",
initialCapital=10000000,
commission=0.0003
)
// 4. 订阅回放数据
subscribeTable(tableName="replayStream", actionName="backtest", handler=backtestEngine)
// 5. 数据回放
histData = loadTable("dfs://stock_data", "stock_tick")
ds = replayDS(sqlObj=<select * from histData where trade_date=2024.01.01>,
dateColumn=`trade_date,
timeColumn=`trade_time)
replay(inputTables=ds, outputTables=replayStream, dateColumn=`trade_date,
timeColumn=`trade_time, replayRate=1000)
// 6. 获取回测结果
backtestEngine.getPositions() // 持仓
backtestEngine.getOrders() // 订单
backtestEngine.getTrades() // 成交
backtestEngine.getMetrics() // 绩效指标
```
### 5. 高级SQL示例
```dolphindb
// Context By - 组内窗口计算
select
trade_date, symbol, close,
movingAvg(close, 5) as ma5,
movingAvg(close, 20) as ma20
from loadTable("dfs://stock", "daily")
context by symbol
// Pivot By - 数据透视
select close
from loadTable("dfs://stock", "daily")
where symbol in `600000`600001`600002
pivot by trade_date, symbol
// Asof Join - 时序非精确关联
select *
from tick_data aj snapshot_data
on tick_data.time = snapshot_data.time and tick_data.symbol = snapshot_data.symbol
```
---
## 💡 最佳实践工作流
### 1. 数据库设计流程
```
需求分析 → 存储引擎选择 → 分区策略设计 → 性能测试 → 生产部署
↓ ↓ ↓ ↓ ↓
数据特征 TSDB/OLAP COMPO分区 压力测试 高可用配置
```
**决策要点**:
- **高频写入 + 点查** → TSDB引擎 + sortColumns
- **批量分析** → OLAP引擎
- **时序数据** → VALUE(日期) + HASH(Symbol) 组合分区
- **查询优化** → 合理使用分区裁剪、并行计算
**参考文档**: [数据库白皮书](references/whitepapers/database.md) 第2-4章
### 2. 流计算开发流程
```
数据源接入 → 流表设计 → 引擎选择 → 订阅处理 → 结果输出
↓ ↓ ↓ ↓ ↓
Kafka等 streamTable 7种引擎 subscribeTable 入库/推送
```
**引擎选择**:
- **滑动窗口聚合** (K线合成) → TimeSeriesEngine
- **横截面计算** (全市场排名) → CrossSectionalEngine
- **复杂状态逻辑** (多因子计算) → ReactiveStateEngine
- **异常检测** → AnomalyDetectionEngine
**参考文档**: [流数据白皮书](references/whitepapers/streaming.md) 第3章
### 3. 量化回测完整流程
```
数据准备 → 历史回放 → 模拟撮合 → 策略执行 → 绩效分析
↓ ↓ ↓ ↓ ↓
分区表 replay Exchange BacktestEngine Sharpe/回撤
```
**核心技术点**:
- 使用 `replay` 或 `replayDS` 严格按时序回放
- `createExchange` 实现"价格优先、时间优先"撮合
- 支持逐笔、快照、分钟频等多种数据源
- C++插件可提升10倍以上性能
**参考文档**: [回测白皮书](references/whitepapers/backtest.md) 完整内容
---
## 🔍 如何使用本Skill
### 按场景查找
1. **我是新手,想快速上手**
- 先阅读: [关于 DolphinDB](references/doc_1201.md)
- 然后看: [数据库白皮书](references/whitepapers/database.md) 第1章
2. **我要设计生产数据库**
- 必读: [数据库白皮书](references/whitepapers/database.md) 第2-6章
- 参考: [数据分区](references/doc_9485.md)、[高可用](references/doc_3934.md)
3. **我要开发实时计算应用**
- 必读: [流数据白皮书](references/whitepapers/streaming.md) 全文
- 速查: 本文档中的"流计算代码示例"
4. **我要搭建量化回测系统**
- 必读: [回测白皮书](references/whitepapers/backtest.md) 全文
- 实战: 白皮书第5-7章策略案例
5. **我要查特定函数用法**
- 使用: [CATALOG.md](CATALOG.md) 按分类查找
- 或在 `references/` 目录搜索关键词
### 按角色查找
| 角色 | 推荐阅读路径 |
|------|-------------|
| **架构师** | 数据库白皮书 → 分布式架构 → 高可用方案 |
| **DBA** | 数据库白皮书 → 运维章节 → 备份恢复 |
| **后端开发** | 流数据白皮书 → API文档 → 代码示例 |
| **量化研究员** | 回测白皮书 → 策略开发 → 绩效分析 |
| **数据分析师** | SQL函数参考 → Context By → Pivot By |
---
## 📊 版本信息
- **Skill版本**: 2.0.0 (相比1.x版本的改进)
- ✅ 新增完整文档索引 (CATALOG.md)
- ✅ 新增常见问题快速导航
- ✅ 新增5大类代码示例
- ✅ 优化文档分类 (14个细分类别)
- ✅ 明确DolphinDB版本对应关系
- **DolphinDB版本**: 3.00.4
- **文档同步时间**: 2026-01-20
- **维护策略**: 季度更新 / 重大版本发布时同步
---
## 🔗 相关资源
- **官网**: https://www.dolphindb.com
- **文档中心**: https://docs.dolphindb.cn
- **社区论坛**: https://community.dolphindb.com
- **GitHub**: https://github.com/dolphindb
---
**Generated by Skill Creator v2.0** | 优化时间: 2026-01-22
FILE:CATALOG.md
# DolphinDB 技术文档完整目录
本目录包含所有1490个技术文档的完整索引,按功能分类组织。
---
## API与连接器 (1个文档)
1. [连接器 & API](references/doc_5576.md)
## 其他 (97个文档)
1. [3.00.4](references/doc_1696.md)
2. [DolphinDB 终端](references/doc_940.md)
3. [DolphinDB 脚本语言](references/doc_2263.md)
4. [GUI 客户端](references/doc_5604.md)
5. [Grafana 数据源插件](references/doc_4375.md)
6. [Jupyter Notebook 客户端](references/doc_308.md)
7. [K 线计算](references/doc_914.md)
8. [MCP](references/doc_63.md)
9. [MyTT 指标库](references/doc_8809.md)
10. [SQL Trace](references/doc_9381.md)
11. [SQL 语句](references/doc_3418.md)
12. [VS Code 插件](references/doc_7287.md)
13. [Web 操作手册](references/doc_1063.md)
14. [WorldQuant 101 Alpha 因子指标库](references/doc_5642.md)
15. [[HINT_EXPLAIN]](references/doc_6564.md)
16. [alter](references/doc_6970.md)
17. [any/all](references/doc_5822.md)
18. [asof join](references/doc_1954.md)
19. [between](references/doc_8055.md)
20. [case](references/doc_2892.md)
21. [cgroup by](references/doc_9598.md)
22. [coalesce](references/doc_7780.md)
23. [context by](references/doc_8101.md)
24. [create](references/doc_6767.md)
25. [cross join](references/doc_3711.md)
26. [delete](references/doc_4815.md)
27. [distinct](references/doc_5546.md)
28. [drop](references/doc_8552.md)
29. [eachAt(@)](references/doc_4598.md)
30. [easyNSQ 实时行情数据接入功能模块](references/doc_3687.md)
31. [easyTLDataImport 通联历史数据自动化导入功能模块](references/doc_8753.md)
32. [equi join](references/doc_1996.md)
33. [exec](references/doc_4344.md)
34. [exists](references/doc_3011.md)
35. [full join/full outer join](references/doc_3114.md)
36. [getTraces](references/doc_7228.md)
37. [group by](references/doc_2397.md)
38. [having](references/doc_1523.md)
39. [in](references/doc_8823.md)
40. [inner join](references/doc_7840.md)
41. [insert into](references/doc_23.md)
42. [interval](references/doc_6760.md)
43. [is null](references/doc_2649.md)
44. [left join/left outer join](references/doc_3462.md)
45. [like/LIKE](references/doc_876.md)
46. [limit](references/doc_433.md)
47. [map](references/doc_3411.md)
48. [module](references/doc_9647.md)
49. [notBetween/NOTBETWEEN](references/doc_5841.md)
50. [notIn/NOTIN](references/doc_9663.md)
51. [notLike/NOTLIKE](references/doc_2080.md)
52. [order by](references/doc_9131.md)
53. [partition](references/doc_4603.md)
54. [pivot by](references/doc_3372.md)
55. [prefix join](references/doc_7911.md)
56. [right join/right outer join](references/doc_254.md)
57. [sample](references/doc_9651.md)
58. [select](references/doc_8438.md)
59. [setTraceMode](references/doc_9159.md)
60. [share](references/doc_7878.md)
61. [timer](references/doc_7988.md)
62. [top](references/doc_2220.md)
63. [union/union all](references/doc_6805.md)
64. [update](references/doc_8103.md)
65. [use](references/doc_9665.md)
66. [viewTraceInfo](references/doc_8520.md)
67. [where](references/doc_7893.md)
68. [window join](references/doc_2997.md)
69. [with](references/doc_3907.md)
70. [交互编程](references/doc_8969.md)
71. [交易日历](references/doc_7520.md)
72. [关于 DolphinDB](references/doc_1201.md)
73. [功能配置](references/doc_2337.md)
74. [参数配置](references/doc_8706.md)
75. [国泰君安 191 Alpha 因子库](references/doc_2627.md)
76. [基于 DataX 的 DolphinDB 数据导入工具](references/doc_8011.md)
77. [基于 DolphinDB 的多因子风险模型实践](references/doc_4409.md)
78. [多范式编程](references/doc_2274.md)
79. [实时检测传感器状态变化](references/doc_3544.md)
80. [建库建表](references/doc_4421.md)
81. [异步复制](references/doc_6436.md)
82. [快速上手](references/doc_2977.md)
83. [技术分析(Technical Analysis)指标库](references/doc_3964.md)
84. [插件](references/doc_5126.md)
85. [操作手册](references/doc_1958.md)
86. [故障排查](references/doc_5020.md)
87. [数据备份以及恢复 (1.30.20/2.00.8及之后版本)](references/doc_5013.md)
88. [数据导入方法](references/doc_8009.md)
89. [数据导入最容易忽略的十个细节](references/doc_7191.md)
90. [数据迁移方法](references/doc_7739.md)
91. [模块](references/doc_5922.md)
92. [物联网应用范例](references/doc_3592.md)
93. [用户权限管理](references/doc_4723.md)
94. [第三方工具](references/doc_7388.md)
95. [编程语言](references/doc_5868.md)
96. [量化金融范例](references/doc_7605.md)
97. [错误代码](references/doc_8642.md)
## 函数参考/SQL函数 (41个文档)
1. [addGroupMember](references/doc_6058.md)
2. [appendForJoin](references/doc_3716.md)
3. [createAsofJoinEngine](references/doc_5102.md)
4. [createEqualJoinEngine](references/doc_5767.md)
5. [createEquiJoinEngine](references/doc_9579.md)
6. [createGroup](references/doc_1547.md)
7. [createLeftSemiJoinEngine](references/doc_2105.md)
8. [createLookupJoinEngine](references/doc_6182.md)
9. [createSnapshotJoinEngine](references/doc_5260.md)
10. [createWindowJoinEngine](references/doc_9714.md)
11. [declareStreamingSQLTable](references/doc_670.md)
12. [deleteGroup](references/doc_3750.md)
13. [deleteGroupMember](references/doc_9749.md)
14. [dynamicGroupCumcount](references/doc_9768.md)
15. [dynamicGroupCumsum](references/doc_9774.md)
16. [getGroupAccess](references/doc_9374.md)
17. [getGroupAccessByCluster](references/doc_8570.md)
18. [getGroupListOfAllClusters](references/doc_5910.md)
19. [getMemLimitOfTaskGroupResult](references/doc_3459.md)
20. [getStreamingRaftGroups](references/doc_1950.md)
21. [getUsersByGroupId](references/doc_5598.md)
22. [groupby](references/doc_1278.md)
23. [groups](references/doc_6964.md)
24. [join](references/doc_3875.md)
25. [join!](references/doc_9323.md)
26. [listStreamingSQLTables](references/doc_6330.md)
27. [loadTableBySQL](references/doc_1035.md)
28. [registerStreamingSQL](references/doc_7248.md)
29. [regroup](references/doc_2294.md)
30. [revokeStreamingSQL](references/doc_2965.md)
31. [revokeStreamingSQLTable](references/doc_7239.md)
32. [rowGroupby](references/doc_9202.md)
33. [setMemLimitOfTaskGroupResult](references/doc_7235.md)
34. [sql](references/doc_2146.md)
35. [sqlCol](references/doc_1884.md)
36. [sqlColAlias](references/doc_3910.md)
37. [sqlDS](references/doc_3327.md)
38. [sqlDelete](references/doc_9736.md)
39. [subscribeStreamingSQL](references/doc_7012.md)
40. [ungroup](references/doc_8734.md)
41. [unsubscribeStreamingSQL](references/doc_6412.md)
## 函数参考/其他函数 (1171个文档)
1. [accumulate](references/doc_4194.md)
2. [acf](references/doc_7622.md)
3. [acos](references/doc_8598.md)
4. [acosh](references/doc_9957.md)
5. [adaBoostClassifier](references/doc_4296.md)
6. [adaBoostRegressor](references/doc_5996.md)
7. [add](references/doc_6110.md)
8. [addAccessControl](references/doc_341.md)
9. [addColumn](references/doc_7529.md)
10. [addFunctionView](references/doc_1097.md)
11. [addMCPPrompt](references/doc_7620.md)
12. [addMCPTool](references/doc_4225.md)
13. [addMarketHoliday](references/doc_9639.md)
14. [addMetrics](references/doc_6643.md)
15. [addNode](references/doc_3035.md)
16. [addRangePartitions](references/doc_8862.md)
17. [addReactiveMetrics](references/doc_4728.md)
18. [addValuePartitions](references/doc_5297.md)
19. [addVolumes](references/doc_6037.md)
20. [adfuller](references/doc_4009.md)
21. [aggrTopN](references/doc_3615.md)
22. [align](references/doc_746.md)
23. [all](references/doc_7368.md)
24. [all](references/doc_9187.md)
25. [amortizingFixedRateBondDirtyPrice](references/doc_9996.md)
26. [and](references/doc_7723.md)
27. [anova](references/doc_2222.md)
28. [any](references/doc_5225.md)
29. [any](references/doc_6917.md)
30. [append!](references/doc_4871.md)
31. [appendMsg](references/doc_475.md)
32. [appendTuple!](references/doc_7470.md)
33. [arima](references/doc_2200.md)
34. [array](references/doc_9034.md)
35. [arrayVector](references/doc_9209.md)
36. [asFreq](references/doc_6538.md)
37. [asin](references/doc_4143.md)
38. [asinh](references/doc_4845.md)
39. [asis](references/doc_7051.md)
40. [asof](references/doc_8367.md)
41. [at](references/doc_1122.md)
42. [atImax](references/doc_3378.md)
43. [atImin](references/doc_9147.md)
44. [atan](references/doc_3785.md)
45. [atanh](references/doc_2155.md)
46. [attributeNames](references/doc_4487.md)
47. [attributeValues](references/doc_8984.md)
48. [avg](references/doc_8128.md)
49. [backup](references/doc_680.md)
50. [backupDB](references/doc_671.md)
51. [backupSettings](references/doc_7159.md)
52. [backupTable](references/doc_3236.md)
53. [bar](references/doc_3597.md)
54. [base64Decode](references/doc_1877.md)
55. [base64Encode](references/doc_7860.md)
56. [beta](references/doc_2893.md)
57. [between](references/doc_5315.md)
58. [bfill!](references/doc_5163.md)
59. [bigarray](references/doc_9333.md)
60. [binsrch](references/doc_1882.md)
61. [bitAnd](references/doc_2310.md)
62. [bitOr](references/doc_2579.md)
63. [bitXor](references/doc_5528.md)
64. [blob](references/doc_890.md)
65. [bondAccrInt](references/doc_3593.md)
66. [bondCalculator](references/doc_2952.md)
67. [bondCashflow](references/doc_289.md)
68. [bondConvexity](references/doc_1194.md)
69. [bondDirtyPrice](references/doc_1849.md)
70. [bondDuration](references/doc_9815.md)
71. [bondFuturesPricer](references/doc_1604.md)
72. [bondInstrumentCalculator](references/doc_5698.md)
73. [bondPricer](references/doc_1851.md)
74. [bondYield](references/doc_1634.md)
75. [bondYieldCurveBuilder](references/doc_9797.md)
76. [bool](references/doc_8859.md)
77. [boxcox](references/doc_3314.md)
78. [brentq](references/doc_7065.md)
79. [brute](references/doc_3842.md)
80. [bucket](references/doc_375.md)
81. [bucketCount](references/doc_2985.md)
82. [businessDay](references/doc_8757.md)
83. [businessMonthBegin](references/doc_731.md)
84. [businessMonthEnd](references/doc_472.md)
85. [businessQuarterBegin](references/doc_5921.md)
86. [businessQuarterEnd](references/doc_889.md)
87. [businessYearBegin](references/doc_3603.md)
88. [businessYearEnd](references/doc_9020.md)
89. [bvls](references/doc_2664.md)
90. [byColumn](references/doc_7197.md)
91. [byRow](references/doc_5227.md)
92. [cacheDS!](references/doc_4284.md)
93. [cacheDSNow](references/doc_4855.md)
94. [cachedTable](references/doc_5286.md)
95. [call](references/doc_9376.md)
96. [callMCPTool](references/doc_3320.md)
97. [cancelConsoleJob](references/doc_2863.md)
98. [cancelJob](references/doc_3576.md)
99. [cancelRecoveryTask](references/doc_5324.md)
100. [cast](references/doc_1838.md)
101. [cbrt](references/doc_907.md)
102. [cdfBeta](references/doc_2190.md)
103. [cdfBinomial](references/doc_2881.md)
104. [cdfChiSquare](references/doc_6341.md)
105. [cdfF](references/doc_5480.md)
106. [cdfGamma](references/doc_8652.md)
107. [cdfKolmogorov](references/doc_1877.md)
108. [cdfNormal](references/doc_5523.md)
109. [cdfPoisson](references/doc_2123.md)
110. [cdfStudent](references/doc_1943.md)
111. [cdfUniform](references/doc_3610.md)
112. [cdfWeibull](references/doc_5001.md)
113. [cdfZipf](references/doc_7491.md)
114. [cds](references/doc_6976.md)
115. [ceil](references/doc_6315.md)
116. [cell](references/doc_3218.md)
117. [cells](references/doc_5400.md)
118. [changePwd](references/doc_7551.md)
119. [char](references/doc_9257.md)
120. [charAt](references/doc_5103.md)
121. [checkBackup](references/doc_5437.md)
122. [chiSquareTest](references/doc_4738.md)
123. [cholesky](references/doc_3051.md)
124. [clear!](references/doc_9293.md)
125. [clearAllCache](references/doc_1062.md)
126. [clearAllIOTDBLatestKeyCache](references/doc_4821.md)
127. [clearAllTSDBSymbolBaseCache](references/doc_3020.md)
128. [clearCachedModules](references/doc_6249.md)
129. [clearComputeNodeCache](references/doc_4942.md)
130. [clearComputeNodeDiskCache](references/doc_9650.md)
131. [clearDSCache!](references/doc_9221.md)
132. [clearDSCacheNow](references/doc_6957.md)
133. [clearTablePersistence](references/doc_527.md)
134. [clip](references/doc_5522.md)
135. [clip!](references/doc_8110.md)
136. [close](references/doc_3795.md)
137. [closeSessions](references/doc_4666.md)
138. [coevent](references/doc_4413.md)
139. [coint](references/doc_4923.md)
140. [col](references/doc_8330.md)
141. [cols](references/doc_1472.md)
142. [columnNames](references/doc_2835.md)
143. [complex](references/doc_4711.md)
144. [compose](references/doc_9113.md)
145. [compress](references/doc_5266.md)
146. [concat](references/doc_1359.md)
147. [concatMatrix](references/doc_9521.md)
148. [condValueAtRisk](references/doc_8018.md)
149. [conditionalFilter](references/doc_6856.md)
150. [conditionalIterate](references/doc_5302.md)
151. [constantDesc](references/doc_3117.md)
152. [contextCount](references/doc_7768.md)
153. [contextSum](references/doc_5411.md)
154. [contextSum2](references/doc_7782.md)
155. [contextby](references/doc_1821.md)
156. [convertEncode](references/doc_2383.md)
157. [convertExcelFormula](references/doc_9972.md)
158. [convertTZ](references/doc_4165.md)
159. [convertibleFixedRateBondDirtyPrice](references/doc_653.md)
160. [copy](references/doc_8982.md)
161. [copyReplicas](references/doc_5936.md)
162. [cos](references/doc_1141.md)
163. [cosh](references/doc_5230.md)
164. [count](references/doc_9307.md)
165. [countNanInf](references/doc_3453.md)
166. [covar](references/doc_1885.md)
167. [covarMatrix](references/doc_7493.md)
168. [crc32](references/doc_7492.md)
169. [createAnomalyDetectionEngine](references/doc_7930.md)
170. [createCrossSectionalEngine](references/doc_2668.md)
171. [createCryptoOrderBookEngine](references/doc_6888.md)
172. [createDimensionTable](references/doc_8050.md)
173. [createDistributedInMemoryTable](references/doc_3793.md)
174. [createIPCInMemoryTable](references/doc_2908.md)
175. [createOrderBookSnapshotEngine](references/doc_8948.md)
176. [createPartitionedTable](references/doc_4130.md)
177. [createRuleEngine](references/doc_6104.md)
178. [createSchema](references/doc_5694.md)
179. [createSessionWindowEngine](references/doc_3860.md)
180. [createStreamDispatchEngine](references/doc_8687.md)
181. [createTable](references/doc_4985.md)
182. [createUser](references/doc_3752.md)
183. [crmwCBond](references/doc_7967.md)
184. [cross](references/doc_6113.md)
185. [cubicHermiteSplineFit](references/doc_8033.md)
186. [cubicSpline](references/doc_9445.md)
187. [cubicSplinePredict](references/doc_1266.md)
188. [cumPositiveStreak](references/doc_8859.md)
189. [cumavg](references/doc_3387.md)
190. [cumbeta](references/doc_4052.md)
191. [cumcount](references/doc_9546.md)
192. [cumcovar](references/doc_5870.md)
193. [cumfirstNot](references/doc_2480.md)
194. [cumlastNot](references/doc_1811.md)
195. [cummax](references/doc_2959.md)
196. [cummdd](references/doc_2506.md)
197. [cummed](references/doc_3262.md)
198. [cummin](references/doc_7760.md)
199. [cumnunique](references/doc_4185.md)
200. [cumpercentile](references/doc_8468.md)
201. [cumprod](references/doc_3882.md)
202. [cumrank](references/doc_5636.md)
203. [cumsum](references/doc_8027.md)
204. [cumsum2](references/doc_8852.md)
205. [cumsum3](references/doc_3240.md)
206. [cumsum4](references/doc_3709.md)
207. [cumvar](references/doc_6261.md)
208. [cumvarp](references/doc_1596.md)
209. [cumwavg](references/doc_6393.md)
210. [cumwsum](references/doc_4352.md)
211. [curvePredict](references/doc_6663.md)
212. [cut](references/doc_7529.md)
213. [cutPoints](references/doc_3300.md)
214. [dailyAlignedBar](references/doc_5028.md)
215. [database](references/doc_8454.md)
216. [dayOfMonth](references/doc_2529.md)
217. [dayOfWeek](references/doc_5525.md)
218. [dayOfYear](references/doc_3732.md)
219. [daysInMonth](references/doc_8702.md)
220. [decimal128](references/doc_4282.md)
221. [decimal32](references/doc_6147.md)
222. [decimal64](references/doc_4575.md)
223. [decimalFormat](references/doc_6496.md)
224. [decimalMultiply](references/doc_956.md)
225. [decodeShortGenomeSeq](references/doc_9691.md)
226. [decompress](references/doc_10.md)
227. [deepCopy](references/doc_8321.md)
228. [defined](references/doc_1440.md)
229. [defs](references/doc_1993.md)
230. [deg2rad](references/doc_9530.md)
231. [deleteReplicas](references/doc_104.md)
232. [deleteScheduledJob](references/doc_3229.md)
233. [deleteUser](references/doc_2043.md)
234. [deltas](references/doc_4478.md)
235. [dema](references/doc_4590.md)
236. [demean](references/doc_1430.md)
237. [denseRank](references/doc_8842.md)
238. [deny](references/doc_4788.md)
239. [derivative](references/doc_3612.md)
240. [det](references/doc_5003.md)
241. [diag](references/doc_9661.md)
242. [dict](references/doc_3189.md)
243. [differentialEvolution](references/doc_6263.md)
244. [digitize](references/doc_8451.md)
245. [disableActivePartition](references/doc_2208.md)
246. [disableQueryMonitor](references/doc_4619.md)
247. [disableResourceTracking](references/doc_6718.md)
248. [disableTSDBAsyncSorting](references/doc_4171.md)
249. [disableTablePersistence](references/doc_4605.md)
250. [distance](references/doc_1102.md)
251. [distinct](references/doc_3289.md)
252. [div](references/doc_9582.md)
253. [dividedDifference](references/doc_2306.md)
254. [dot](references/doc_1931.md)
255. [double](references/doc_8763.md)
256. [drop](references/doc_9525.md)
257. [dropAggregator](references/doc_4054.md)
258. [dropColumns!](references/doc_8161.md)
259. [dropDatabase](references/doc_8239.md)
260. [dropDistributedInMemoryTable](references/doc_6069.md)
261. [dropFunctionView](references/doc_6687.md)
262. [dropIPCInMemoryTable](references/doc_1296.md)
263. [dropMCPPrompt](references/doc_7688.md)
264. [dropMCPTool](references/doc_3803.md)
265. [dropPartition](references/doc_3248.md)
266. [dropSchema](references/doc_355.md)
267. [dropStreamEngine](references/doc_4683.md)
268. [dropStreamTable](references/doc_9693.md)
269. [dropTable](references/doc_2686.md)
270. [dropna](references/doc_6586.md)
271. [dumpHeapSample](references/doc_9493.md)
272. [duration](references/doc_3432.md)
273. [each](references/doc_2801.md)
274. [eachLeft](references/doc_2617.md)
275. [eachPost](references/doc_3033.md)
276. [eachPre](references/doc_6367.md)
277. [eachRight](references/doc_1350.md)
278. [eig](references/doc_7260.md)
279. [elasticNet](references/doc_8883.md)
280. [elasticNetCV](references/doc_5573.md)
281. [ema](references/doc_4081.md)
282. [enableActivePartition](references/doc_3810.md)
283. [enableQueryMonitor](references/doc_5080.md)
284. [enableResourceTracking](references/doc_4105.md)
285. [enableTSDBAsyncSorting](references/doc_9177.md)
286. [enableTableCachePurge](references/doc_7533.md)
287. [enableTablePersistence](references/doc_4898.md)
288. [enableTableShareAndCachePurge](references/doc_6156.md)
289. [enableTableShareAndPersistence](references/doc_9573.md)
290. [encodeShortGenomeSeq](references/doc_2444.md)
291. [endsWith](references/doc_9737.md)
292. [enlist](references/doc_5991.md)
293. [eq](references/doc_5533.md)
294. [eqFloat](references/doc_8747.md)
295. [eqObj](references/doc_6057.md)
296. [eqPercent](references/doc_55.md)
297. [erase!](references/doc_5721.md)
298. [esd](references/doc_3996.md)
299. [euclidean](references/doc_1985.md)
300. [eval](references/doc_1305.md)
301. [ewmCov](references/doc_4381.md)
302. [ewmMean](references/doc_4800.md)
303. [ewmVar](references/doc_8786.md)
304. [exists](references/doc_3345.md)
305. [existsDatabase](references/doc_7864.md)
306. [existsPartition](references/doc_807.md)
307. [existsStreamTable](references/doc_9164.md)
308. [existsSubscriptionTopic](references/doc_193.md)
309. [existsTable](references/doc_7819.md)
310. [extractInstrument](references/doc_1617.md)
311. [extractMktData](references/doc_5757.md)
312. [extractTextSchema](references/doc_8182.md)
313. [eye](references/doc_90.md)
314. [fTest](references/doc_9113.md)
315. [ffill](references/doc_9752.md)
316. [ffill!](references/doc_5296.md)
317. [fflush](references/doc_5040.md)
318. [file](references/doc_7286.md)
319. [files](references/doc_9225.md)
320. [fill!](references/doc_4904.md)
321. [find](references/doc_4511.md)
322. [first](references/doc_4857.md)
323. [firstHit](references/doc_2936.md)
324. [firstNot](references/doc_6952.md)
325. [fixedLengthArrayVector](references/doc_4570.md)
326. [flatten](references/doc_433.md)
327. [flip](references/doc_2998.md)
328. [floatingRateBondDirtyPrice](references/doc_450.md)
329. [floor](references/doc_853.md)
330. [flushComputeNodeMemCache](references/doc_9492.md)
331. [flushOLAPCache](references/doc_1661.md)
332. [flushTSDBCache](references/doc_2843.md)
333. [fmin](references/doc_7913.md)
334. [fminBFGS](references/doc_2853.md)
335. [fminLBFGSB](references/doc_7592.md)
336. [fminNCG](references/doc_1382.md)
337. [fminSLSQP](references/doc_8156.md)
338. [forceTriggerOrderBookSnapshot](references/doc_47.md)
339. [form](references/doc_6619.md)
340. [format](references/doc_3649.md)
341. [fromJson](references/doc_454.md)
342. [fromUTF8](references/doc_7170.md)
343. [funcByName](references/doc_391.md)
344. [fxEuropeanOptionPricer](references/doc_2650.md)
345. [fxForwardPricer](references/doc_2903.md)
346. [fxSwapPricer](references/doc_4707.md)
347. [fxVolatilitySurfaceBuilder](references/doc_8691.md)
348. [fy5253](references/doc_3267.md)
349. [fy5253Quarter](references/doc_1540.md)
350. [garch](references/doc_216.md)
351. [gaussianKde](references/doc_9061.md)
352. [gaussianKdePredict](references/doc_4768.md)
353. [gaussianNB](references/doc_5847.md)
354. [ge](references/doc_3292.md)
355. [gema](references/doc_9230.md)
356. [genShortGenomeSeq](references/doc_7667.md)
357. [getActiveMaster](references/doc_8857.md)
358. [getAggregator](references/doc_6425.md)
359. [getAllClusters](references/doc_9375.md)
360. [getAllDBGranularity](references/doc_1097.md)
361. [getAllDBs](references/doc_1249.md)
362. [getAuthenticatedUsers](references/doc_1329.md)
363. [getBackupList](references/doc_2979.md)
364. [getBackupMeta](references/doc_187.md)
365. [getChunkPath](references/doc_1110.md)
366. [getChunksMeta](references/doc_3156.md)
367. [getClusterDFSDatabases](references/doc_9280.md)
368. [getClusterDFSTables](references/doc_5956.md)
369. [getClusterPerf](references/doc_4159.md)
370. [getClusterVolumeUsage](references/doc_8273.md)
371. [getCompletedQueries](references/doc_5961.md)
372. [getComputeNodeCacheDetails](references/doc_7777.md)
373. [getComputeNodeCachingDelay](references/doc_4964.md)
374. [getConfig](references/doc_1459.md)
375. [getConfigure](references/doc_2939.md)
376. [getConnections](references/doc_3839.md)
377. [getConsoleJobs](references/doc_5857.md)
378. [getCurrentSessionAndUser](references/doc_15.md)
379. [getDFSDatabases](references/doc_6216.md)
380. [getDFSDatabasesByOwner](references/doc_7577.md)
381. [getDatabasesByCluster](references/doc_8398.md)
382. [getDynamicConfig](references/doc_8342.md)
383. [getEnv](references/doc_9130.md)
384. [getHomeDir](references/doc_7854.md)
385. [getInstrumentCalendar](references/doc_9448.md)
386. [getInstrumentCoupon](references/doc_6267.md)
387. [getInstrumentCreditRating](references/doc_5604.md)
388. [getInstrumentCurrency](references/doc_8215.md)
389. [getInstrumentCurrencyPair](references/doc_3363.md)
390. [getInstrumentDayCountConvention](references/doc_1219.md)
391. [getInstrumentDelivery](references/doc_1231.md)
392. [getInstrumentDirection](references/doc_5621.md)
393. [getInstrumentFarDelivery](references/doc_890.md)
394. [getInstrumentFarStrike](references/doc_4489.md)
395. [getInstrumentField](references/doc_3779.md)
396. [getInstrumentFixedDayCountConvention](references/doc_8989.md)
397. [getInstrumentFixedRate](references/doc_1865.md)
398. [getInstrumentFloatingDayCountConvention](references/doc_6250.md)
399. [getInstrumentFrequency](references/doc_6570.md)
400. [getInstrumentIborIndex](references/doc_1552.md)
401. [getInstrumentInstrumentId](references/doc_990.md)
402. [getInstrumentIssuePrice](references/doc_2931.md)
403. [getInstrumentKeys](references/doc_2235.md)
404. [getInstrumentMaturity](references/doc_7703.md)
405. [getInstrumentNearDelivery](references/doc_4091.md)
406. [getInstrumentNearStrike](references/doc_3180.md)
407. [getInstrumentNominal](references/doc_2251.md)
408. [getInstrumentNominalCouponRate](references/doc_2746.md)
409. [getInstrumentNotional](references/doc_8685.md)
410. [getInstrumentPayReceive](references/doc_4575.md)
411. [getInstrumentPayoffType](references/doc_8536.md)
412. [getInstrumentRate](references/doc_333.md)
413. [getInstrumentSettlement](references/doc_3874.md)
414. [getInstrumentSpread](references/doc_4908.md)
415. [getInstrumentStart](references/doc_7787.md)
416. [getInstrumentStrike](references/doc_1140.md)
417. [getInstrumentSubType](references/doc_4593.md)
418. [getInstrumentUnderlying](references/doc_5241.md)
419. [getJobMessage](references/doc_8533.md)
420. [getLeftStream](references/doc_7328.md)
421. [getLoadedPlugins](references/doc_1535.md)
422. [getMCPPrompt](references/doc_7490.md)
423. [getMarketCalendar](references/doc_5452.md)
424. [getMemLimitOfAllTempResults](references/doc_5501.md)
425. [getMemLimitOfQueryResult](references/doc_6624.md)
426. [getNodeAlias](references/doc_620.md)
427. [getNodeHost](references/doc_9677.md)
428. [getNodePort](references/doc_9768.md)
429. [getNodeType](references/doc_9138.md)
430. [getOLAPCacheEngineSize](references/doc_6935.md)
431. [getOLAPCachedSymbolBaseMemSize](references/doc_6554.md)
432. [getOS](references/doc_2911.md)
433. [getOSBit](references/doc_1605.md)
434. [getOauthClientSecret](references/doc_6844.md)
435. [getPKEYMetaData](references/doc_6361.md)
436. [getPerf](references/doc_7193.md)
437. [getPersistenceMeta](references/doc_56.md)
438. [getPrefetchComputeNodeData](references/doc_7054.md)
439. [getReactiveMetrics](references/doc_4312.md)
440. [getRecentJobs](references/doc_9166.md)
441. [getRecentSlaveReplicationInfo](references/doc_1083.md)
442. [getRecoveryWorkerNum](references/doc_8181.md)
443. [getRightStream](references/doc_3735.md)
444. [getRules](references/doc_7856.md)
445. [getRunningQueries](references/doc_5941.md)
446. [getScheduledJobs](references/doc_4223.md)
447. [getSchemasByCluster](references/doc_5542.md)
448. [getSnapshotMsgId](references/doc_560.md)
449. [getStreamEngine](references/doc_312.md)
450. [getStreamEngineList](references/doc_2136.md)
451. [getStreamTableCacheOffset](references/doc_354.md)
452. [getStreamTableFilterColumn](references/doc_4104.md)
453. [getStreamTables](references/doc_4469.md)
454. [getStreamingLeader](references/doc_9657.md)
455. [getSubscriptionTopic](references/doc_8179.md)
456. [getSupportBundle](references/doc_3525.md)
457. [getSystemCpuUsage](references/doc_1470.md)
458. [getSystemLoadAvg](references/doc_8499.md)
459. [getTSDBCachedSymbolBaseMemSize](references/doc_4164.md)
460. [getTSDBMetaData](references/doc_2929.md)
461. [getTableAccessByCluster](references/doc_3805.md)
462. [getTableSchemaByCluster](references/doc_2992.md)
463. [getTables](references/doc_1918.md)
464. [getTablesByCluster](references/doc_7044.md)
465. [getTablesOfAllClusters](references/doc_6595.md)
466. [getTablet](references/doc_8603.md)
467. [getTabletsMeta](references/doc_9765.md)
468. [getTopicProcessedOffset](references/doc_7239.md)
469. [getUnresolvedTxn](references/doc_5611.md)
470. [getUserAccess](references/doc_7833.md)
471. [getUserAccessByCluster](references/doc_505.md)
472. [getUserHardwareUsage](references/doc_3918.md)
473. [getUserList](references/doc_2699.md)
474. [getUserListOfAllClusters](references/doc_8703.md)
475. [getUserTableAccessRecords](references/doc_5651.md)
476. [glm](references/doc_3431.md)
477. [gmd5](references/doc_7354.md)
478. [gmm](references/doc_2072.md)
479. [gram](references/doc_9018.md)
480. [gramSchmidt](references/doc_4500.md)
481. [grant](references/doc_549.md)
482. [gt](references/doc_5873.md)
483. [haStreamTable](references/doc_450.md)
484. [hasNull](references/doc_7039.md)
485. [hashBucket](references/doc_4660.md)
486. [head](references/doc_1407.md)
487. [hex](references/doc_1046.md)
488. [highDouble](references/doc_6120.md)
489. [highLong](references/doc_8936.md)
490. [histogram2d](references/doc_827.md)
491. [hmac](references/doc_5170.md)
492. [hour](references/doc_6301.md)
493. [hourOfDay](references/doc_9223.md)
494. [ifNull](references/doc_9132.md)
495. [ifValid](references/doc_8376.md)
496. [ifirstHit](references/doc_8504.md)
497. [ifirstNot](references/doc_7143.md)
498. [iif](references/doc_6102.md)
499. [ilastNot](references/doc_4960.md)
500. [ilike](references/doc_1968.md)
501. [imax](references/doc_399.md)
502. [imaxLast](references/doc_6811.md)
503. [imin](references/doc_1207.md)
504. [iminLast](references/doc_6428.md)
505. [imr](references/doc_5716.md)
506. [in](references/doc_7463.md)
507. [indexedSeries](references/doc_6858.md)
508. [indexedTable](references/doc_3801.md)
509. [initcap](references/doc_9355.md)
510. [installPlugin](references/doc_7820.md)
511. [instrumentPricer](references/doc_5208.md)
512. [int](references/doc_9486.md)
513. [int128](references/doc_280.md)
514. [integral](references/doc_4400.md)
515. [interpolate](references/doc_9448.md)
516. [intersection](references/doc_6738.md)
517. [invBeta](references/doc_2943.md)
518. [invBinomial](references/doc_1372.md)
519. [invChiSquare](references/doc_5336.md)
520. [invF](references/doc_5138.md)
521. [invGamma](references/doc_6071.md)
522. [invNormal](references/doc_2628.md)
523. [invPoisson](references/doc_6682.md)
524. [invStudent](references/doc_4981.md)
525. [invUniform](references/doc_6927.md)
526. [invWeibull](references/doc_725.md)
527. [inverse](references/doc_1571.md)
528. [ipaddr](references/doc_9336.md)
529. [irCrossCurrencyCurveBuilder](references/doc_8102.md)
530. [irDepositPricer](references/doc_1939.md)
531. [irFixedFloatingSwapPricer](references/doc_2900.md)
532. [irSingleCurrencyCurveBuilder](references/doc_8864.md)
533. [irs](references/doc_516.md)
534. [isAlNum](references/doc_7784.md)
535. [isAlpha](references/doc_2332.md)
536. [isControllerInitialized](references/doc_671.md)
537. [isDataNodeInitialized](references/doc_7715.md)
538. [isDigit](references/doc_6511.md)
539. [isDuplicated](references/doc_1645.md)
540. [isIndexedMatrix](references/doc_2291.md)
541. [isIndexedSeries](references/doc_8320.md)
542. [isLeapYear](references/doc_4077.md)
543. [isLower](references/doc_1217.md)
544. [isMonotonic](references/doc_1364.md)
545. [isMonotonicDecreasing](references/doc_7585.md)
546. [isMonotonicIncreasing](references/doc_2965.md)
547. [isMonthEnd](references/doc_2792.md)
548. [isMonthStart](references/doc_1260.md)
549. [isNanInf](references/doc_1661.md)
550. [isNothing](references/doc_7780.md)
551. [isNull](references/doc_7042.md)
552. [isNumeric](references/doc_7322.md)
553. [isOrderedDict](references/doc_7243.md)
554. [isPeak](references/doc_2424.md)
555. [isQuarterEnd](references/doc_55.md)
556. [isQuarterStart](references/doc_4956.md)
557. [isSorted](references/doc_7968.md)
558. [isSpace](references/doc_936.md)
559. [isTitle](references/doc_7043.md)
560. [isUpper](references/doc_1327.md)
561. [isValid](references/doc_4337.md)
562. [isValley](references/doc_8602.md)
563. [isVoid](references/doc_2666.md)
564. [isYearEnd](references/doc_3642.md)
565. [isYearStart](references/doc_3451.md)
566. [isort](references/doc_1581.md)
567. [isort!](references/doc_8372.md)
568. [isortTop](references/doc_7984.md)
569. [iterate](references/doc_8373.md)
570. [jsonExtract](references/doc_2501.md)
571. [kama](references/doc_8548.md)
572. [kendall](references/doc_8445.md)
573. [kernelRidge](references/doc_1368.md)
574. [keyedStreamTable](references/doc_7151.md)
575. [keyedTable](references/doc_346.md)
576. [keys](references/doc_2841.md)
577. [kmeans](references/doc_1610.md)
578. [knn](references/doc_2316.md)
579. [kroghInterpolate](references/doc_5733.md)
580. [kroghInterpolateFit](references/doc_8252.md)
581. [ksTest](references/doc_5593.md)
582. [kurtosis](references/doc_469.md)
583. [lasso](references/doc_1285.md)
584. [lassoBasic](references/doc_7984.md)
585. [lassoCV](references/doc_1069.md)
586. [last](references/doc_366.md)
587. [lastNot](references/doc_2916.md)
588. [lastWeekOfMonth](references/doc_2025.md)
589. [latestIndexedTable](references/doc_2544.md)
590. [latestKeyedStreamTable](references/doc_341.md)
591. [latestKeyedTable](references/doc_5469.md)
592. [le](references/doc_2187.md)
593. [left](references/doc_2275.md)
594. [lfill](references/doc_5776.md)
595. [lfill!](references/doc_8962.md)
596. [license](references/doc_4279.md)
597. [like](references/doc_6354.md)
598. [linearInterpolateFit](references/doc_6994.md)
599. [linprog](references/doc_2720.md)
600. [listAllMarkets](references/doc_9784.md)
601. [listMCPPrompts](references/doc_8801.md)
602. [listMCPTools](references/doc_7990.md)
603. [listPluginsByCluster](references/doc_7720.md)
604. [listRemotePlugins](references/doc_829.md)
605. [loadBackup](references/doc_7793.md)
606. [loadDistributedInMemoryTable](references/doc_2563.md)
607. [loadIPCInMemoryTable](references/doc_6492.md)
608. [loadModel](references/doc_6286.md)
609. [loadModule](references/doc_4097.md)
610. [loadModuleFromScript](references/doc_407.md)
611. [loadMvccTable](references/doc_7013.md)
612. [loadNpy](references/doc_3161.md)
613. [loadNpz](references/doc_8119.md)
614. [loadPlugin](references/doc_157.md)
615. [loadRecord](references/doc_7421.md)
616. [loadTable](references/doc_9750.md)
617. [loadText](references/doc_6511.md)
618. [loadTextEx](references/doc_3368.md)
619. [loadVocab](references/doc_8767.md)
620. [loc](references/doc_2358.md)
621. [loess](references/doc_9747.md)
622. [long](references/doc_2663.md)
623. [loop](references/doc_9111.md)
624. [lowDouble](references/doc_4066.md)
625. [lowLong](references/doc_8499.md)
626. [lowRange](references/doc_8916.md)
627. [lower](references/doc_3426.md)
628. [lowerBound](references/doc_6023.md)
629. [lpad](references/doc_9502.md)
630. [lshift](references/doc_1179.md)
631. [lt](references/doc_2488.md)
632. [ltrim](references/doc_5805.md)
633. [lu](references/doc_863.md)
634. [mLowRange](references/doc_4089.md)
635. [mTopRange](references/doc_5928.md)
636. [ma](references/doc_9939.md)
637. [mad](references/doc_9280.md)
638. [makeCall](references/doc_2875.md)
639. [makeKey](references/doc_7082.md)
640. [makeSortedKey](references/doc_304.md)
641. [makeUnifiedCall](references/doc_2185.md)
642. [mannWhitneyUTest](references/doc_667.md)
643. [manova](references/doc_391.md)
644. [mask](references/doc_4508.md)
645. [matrix](references/doc_9550.md)
646. [mavg](references/doc_3636.md)
647. [mavgTopN](references/doc_6657.md)
648. [max](references/doc_4436.md)
649. [maxDrawdown](references/doc_5582.md)
650. [maxIgnoreNull](references/doc_911.md)
651. [maxPositiveStreak](references/doc_9091.md)
652. [mbeta](references/doc_8672.md)
653. [mbetaTopN](references/doc_3841.md)
654. [mcount](references/doc_9661.md)
655. [mcovar](references/doc_7001.md)
656. [mcovarTopN](references/doc_9069.md)
657. [md5](references/doc_6762.md)
658. [mdd](references/doc_9504.md)
659. [mean](references/doc_6143.md)
660. [med](references/doc_5793.md)
661. [mem](references/doc_3571.md)
662. [member](references/doc_2101.md)
663. [memberModify!](references/doc_9220.md)
664. [merge](references/doc_3403.md)
665. [mfirst](references/doc_1081.md)
666. [microsecond](references/doc_3540.md)
667. [mifirstNot](references/doc_2797.md)
668. [migrate](references/doc_7615.md)
669. [milastNot](references/doc_4544.md)
670. [millisecond](references/doc_5852.md)
671. [mimax](references/doc_8253.md)
672. [mimaxLast](references/doc_1552.md)
673. [mimin](references/doc_860.md)
674. [miminLast](references/doc_1604.md)
675. [min](references/doc_3682.md)
676. [minIgnoreNull](references/doc_2785.md)
677. [minute](references/doc_399.md)
678. [minuteOfHour](references/doc_8402.md)
679. [mkdir](references/doc_9369.md)
680. [mkurtosis](references/doc_6525.md)
681. [mlast](references/doc_3346.md)
682. [mlastNot](references/doc_3975.md)
683. [mmad](references/doc_632.md)
684. [mmax](references/doc_5243.md)
685. [mmaxPositiveStreak](references/doc_196.md)
686. [mmed](references/doc_3289.md)
687. [mmin](references/doc_7769.md)
688. [mmse](references/doc_5636.md)
689. [mod](references/doc_6754.md)
690. [mode](references/doc_7022.md)
691. [month](references/doc_9546.md)
692. [monthBegin](references/doc_5356.md)
693. [monthEnd](references/doc_454.md)
694. [monthOfYear](references/doc_2090.md)
695. [move](references/doc_9304.md)
696. [moveChunksAcrossVolume](references/doc_3611.md)
697. [moveHotDataToColdVolume](references/doc_6445.md)
698. [moveReplicas](references/doc_821.md)
699. [moving](references/doc_6447.md)
700. [movingTopNIndex](references/doc_5829.md)
701. [movingWindowIndex](references/doc_2525.md)
702. [mpercentile](references/doc_4120.md)
703. [mpercentileTopN](references/doc_431.md)
704. [mprod](references/doc_7663.md)
705. [mr](references/doc_1842.md)
706. [mrank](references/doc_8189.md)
707. [mskew](references/doc_2713.md)
708. [mslr](references/doc_7621.md)
709. [msum](references/doc_2722.md)
710. [msum2](references/doc_9235.md)
711. [msumTopN](references/doc_198.md)
712. [mul](references/doc_9832.md)
713. [multiTableRepartitionDS](references/doc_8907.md)
714. [multinomialNB](references/doc_6426.md)
715. [mutualInfo](references/doc_6774.md)
716. [mvar](references/doc_5376.md)
717. [mvarTopN](references/doc_8.md)
718. [mvarp](references/doc_4867.md)
719. [mvarpTopN](references/doc_1438.md)
720. [mvccTable](references/doc_3972.md)
721. [mwavg](references/doc_1309.md)
722. [mwsum](references/doc_8943.md)
723. [mwsumTopN](references/doc_595.md)
724. [nanInfFill](references/doc_1768.md)
725. [nanosecond](references/doc_6470.md)
726. [ne](references/doc_8690.md)
727. [neg](references/doc_6183.md)
728. [neville](references/doc_7930.md)
729. [next](references/doc_9334.md)
730. [norm](references/doc_1506.md)
731. [normal](references/doc_3659.md)
732. [not](references/doc_5850.md)
733. [now](references/doc_2287.md)
734. [ns](references/doc_8719.md)
735. [nss](references/doc_9184.md)
736. [nssPredict](references/doc_9254.md)
737. [nullCompare](references/doc_1102.md)
738. [nullFill](references/doc_9275.md)
739. [nullFill!](references/doc_2877.md)
740. [nullIf](references/doc_15.md)
741. [nunique](references/doc_7063.md)
742. [objByName](references/doc_3262.md)
743. [objectChecksum](references/doc_6502.md)
744. [objs](references/doc_1885.md)
745. [ols](references/doc_1601.md)
746. [olsEx](references/doc_1706.md)
747. [oneHot](references/doc_6487.md)
748. [ops 运维函数库](references/doc_9338.md)
749. [optionVolPredict](references/doc_4633.md)
750. [or](references/doc_3568.md)
751. [osqp](references/doc_970.md)
752. [pack](references/doc_9490.md)
753. [pair](references/doc_401.md)
754. [panel](references/doc_1858.md)
755. [parseInstrument](references/doc_1157.md)
756. [parseInt](references/doc_1372.md)
757. [parseInteger](references/doc_5102.md)
758. [parseJsonTable](references/doc_3335.md)
759. [parseMktData](references/doc_261.md)
760. [partial](references/doc_9707.md)
761. [pca](references/doc_2225.md)
762. [pcall](references/doc_9250.md)
763. [pchipInterpolateFit](references/doc_1450.md)
764. [pcross](references/doc_8739.md)
765. [peach](references/doc_8589.md)
766. [percentChange](references/doc_1069.md)
767. [percentile](references/doc_9791.md)
768. [percentileRank](references/doc_244.md)
769. [piecewiseLinFit](references/doc_2007.md)
770. [pipeline](references/doc_2421.md)
771. [pivot](references/doc_5890.md)
772. [ploadText](references/doc_2262.md)
773. [ploop](references/doc_9333.md)
774. [plot](references/doc_8883.md)
775. [plotHist](references/doc_7423.md)
776. [pnodeRun](references/doc_85.md)
777. [point](references/doc_7318.md)
778. [poly1d](references/doc_5955.md)
779. [polyFit](references/doc_4113.md)
780. [polyPredict](references/doc_4810.md)
781. [polynomial](references/doc_7145.md)
782. [pop!](references/doc_2920.md)
783. [portfolioPricer](references/doc_4428.md)
784. [pow](references/doc_1747.md)
785. [predict](references/doc_7645.md)
786. [prev](references/doc_7245.md)
787. [prod](references/doc_6000.md)
788. [publishMCPPrompts](references/doc_3531.md)
789. [publishMCPTools](references/doc_3528.md)
790. [purgeCacheEngine](references/doc_7711.md)
791. [push!](references/doc_6905.md)
792. [pwlfPredict](references/doc_3375.md)
793. [qclp](references/doc_8927.md)
794. [qr](references/doc_2650.md)
795. [quadprog](references/doc_4800.md)
796. [quantile](references/doc_648.md)
797. [quantileSeries](references/doc_9126.md)
798. [quarterBegin](references/doc_8020.md)
799. [quarterEnd](references/doc_9871.md)
800. [rad2deg](references/doc_8025.md)
801. [rand](references/doc_7002.md)
802. [randBeta](references/doc_8637.md)
803. [randBinomial](references/doc_6029.md)
804. [randChiSquare](references/doc_5832.md)
805. [randDiscrete](references/doc_577.md)
806. [randF](references/doc_9617.md)
807. [randGamma](references/doc_9058.md)
808. [randMultivariateNormal](references/doc_6398.md)
809. [randNormal](references/doc_4890.md)
810. [randPoisson](references/doc_5738.md)
811. [randStudent](references/doc_2410.md)
812. [randUniform](references/doc_4252.md)
813. [randWeibull](references/doc_9575.md)
814. [randomForestClassifier](references/doc_5479.md)
815. [randomForestRegressor](references/doc_6711.md)
816. [rank](references/doc_4758.md)
817. [ratio](references/doc_9914.md)
818. [ratios](references/doc_4861.md)
819. [rdp](references/doc_5975.md)
820. [read!](references/doc_3093.md)
821. [readBytes](references/doc_8320.md)
822. [readLine](references/doc_7451.md)
823. [readLines](references/doc_9650.md)
824. [readLines!](references/doc_1826.md)
825. [readObject](references/doc_1022.md)
826. [readRecord!](references/doc_9214.md)
827. [rebalanceChunksAmongDataNodes](references/doc_4486.md)
828. [rebalanceChunksWithinDataNode](references/doc_9768.md)
829. [reciprocal](references/doc_4014.md)
830. [reduce](references/doc_7083.md)
831. [refCount](references/doc_5502.md)
832. [regexCount](references/doc_4416.md)
833. [regexFind](references/doc_8673.md)
834. [regexFindStr](references/doc_1354.md)
835. [regexReplace](references/doc_1048.md)
836. [remoteRun](references/doc_1810.md)
837. [remoteRunCompatible](references/doc_6890.md)
838. [remoteRunWithCompression](references/doc_8238.md)
839. [removeHead!](references/doc_8643.md)
840. [removeNode](references/doc_9919.md)
841. [removeTail!](references/doc_4832.md)
842. [removeTopicOffset](references/doc_4897.md)
843. [rename!](references/doc_800.md)
844. [renameSchema](references/doc_6992.md)
845. [renameTable](references/doc_7830.md)
846. [reorderColumns!](references/doc_3618.md)
847. [repartitionDS](references/doc_2530.md)
848. [repeat](references/doc_7471.md)
849. [replace](references/doc_257.md)
850. [replace!](references/doc_6744.md)
851. [replaceColumn!](references/doc_223.md)
852. [replay](references/doc_7504.md)
853. [replayDS](references/doc_6405.md)
854. [repmat](references/doc_8999.md)
855. [resample](references/doc_7941.md)
856. [resetDBDirMeta](references/doc_3503.md)
857. [resetPwd](references/doc_4303.md)
858. [resetRecoveryWorkerNum](references/doc_3153.md)
859. [reshape](references/doc_2577.md)
860. [residual](references/doc_9542.md)
861. [restore](references/doc_684.md)
862. [restoreDB](references/doc_2450.md)
863. [restoreDislocatedTablet](references/doc_9420.md)
864. [restoreSettings](references/doc_3404.md)
865. [restoreTable](references/doc_5672.md)
866. [resumeRecovery](references/doc_5824.md)
867. [reverse](references/doc_7657.md)
868. [revoke](references/doc_1731.md)
869. [ridge](references/doc_1893.md)
870. [ridgeBasic](references/doc_8543.md)
871. [right](references/doc_7509.md)
872. [rm](references/doc_7416.md)
873. [rmdir](references/doc_4983.md)
874. [rms](references/doc_5126.md)
875. [rolling](references/doc_8385.md)
876. [rollingPanel](references/doc_5107.md)
877. [round](references/doc_4367.md)
878. [row](references/doc_7175.md)
879. [rowAlign](references/doc_614.md)
880. [rowAnd](references/doc_4232.md)
881. [rowAt](references/doc_1043.md)
882. [rowAvg](references/doc_867.md)
883. [rowBeta](references/doc_5573.md)
884. [rowCount](references/doc_1493.md)
885. [rowCovar](references/doc_8137.md)
886. [rowDenseRank](references/doc_2445.md)
887. [rowDot](references/doc_4521.md)
888. [rowEuclidean](references/doc_8265.md)
889. [rowGmd5](references/doc_8655.md)
890. [rowImax](references/doc_824.md)
891. [rowImaxLast](references/doc_6610.md)
892. [rowImin](references/doc_1989.md)
893. [rowIminLast](references/doc_2193.md)
894. [rowKurtosis](references/doc_6257.md)
895. [rowMax](references/doc_2178.md)
896. [rowMin](references/doc_6601.md)
897. [rowMove](references/doc_5549.md)
898. [rowNames](references/doc_2297.md)
899. [rowNext](references/doc_9760.md)
900. [rowNo](references/doc_7538.md)
901. [rowOr](references/doc_2253.md)
902. [rowPrev](references/doc_5531.md)
903. [rowProd](references/doc_9889.md)
904. [rowRank](references/doc_3296.md)
905. [rowSize](references/doc_2048.md)
906. [rowSkew](references/doc_8345.md)
907. [rowSum](references/doc_5938.md)
908. [rowSum2](references/doc_8205.md)
909. [rowTanimoto](references/doc_8878.md)
910. [rowVar](references/doc_6065.md)
911. [rowVarp](references/doc_4173.md)
912. [rowWavg](references/doc_3817.md)
913. [rowWsum](references/doc_3590.md)
914. [rowXor](references/doc_458.md)
915. [rows](references/doc_378.md)
916. [rpad](references/doc_556.md)
917. [rpc](references/doc_9005.md)
918. [rshift](references/doc_561.md)
919. [rtrim](references/doc_7671.md)
920. [saveAsNpy](references/doc_276.md)
921. [saveDatabase](references/doc_2234.md)
922. [saveDualPartition](references/doc_5792.md)
923. [saveModel](references/doc_8731.md)
924. [saveModule](references/doc_8465.md)
925. [savePartition](references/doc_8803.md)
926. [saveTable](references/doc_3984.md)
927. [saveText](references/doc_7878.md)
928. [saveTextFile](references/doc_6055.md)
929. [scheduleJob](references/doc_9382.md)
930. [schema](references/doc_2829.md)
931. [schur](references/doc_3087.md)
932. [scramClientFinal](references/doc_3475.md)
933. [scramClientFirst](references/doc_9159.md)
934. [scs](references/doc_2354.md)
935. [searchK](references/doc_5014.md)
936. [seasonalEsd](references/doc_147.md)
937. [second](references/doc_4914.md)
938. [secondOfMinute](references/doc_7691.md)
939. [seek](references/doc_6642.md)
940. [segment](references/doc_7715.md)
941. [segmentby](references/doc_7469.md)
942. [sem](references/doc_9389.md)
943. [semiMonthBegin](references/doc_8909.md)
944. [semiMonthEnd](references/doc_1134.md)
945. [semiannualBegin](references/doc_7910.md)
946. [semiannualEnd](references/doc_9068.md)
947. [seq](references/doc_8518.md)
948. [sessionWindow](references/doc_7418.md)
949. [set](references/doc_7213.md)
950. [setAtomicLevel](references/doc_2321.md)
951. [setColumnComment](references/doc_7067.md)
952. [setComputeNodeCachingDelay](references/doc_5106.md)
953. [setDatabaseForClusterReplication](references/doc_6891.md)
954. [setDatanodeRestartInterval](references/doc_4202.md)
955. [setDynamicConfig](references/doc_836.md)
956. [setIPConnectionLimit](references/doc_1917.md)
957. [setIndexedMatrix!](references/doc_91.md)
958. [setIndexedSeries!](references/doc_4256.md)
959. [setMaxBlockSizeForReservedMemory](references/doc_3072.md)
960. [setMaxConnections](references/doc_8508.md)
961. [setMaxJobParallelism](references/doc_5315.md)
962. [setMaxJobPriority](references/doc_2.md)
963. [setMaxMemSize](references/doc_2697.md)
964. [setMemLimitOfAllTempResults](references/doc_4379.md)
965. [setMemLimitOfQueryResult](references/doc_8979.md)
966. [setMemLimitOfTempResult](references/doc_8425.md)
967. [setOLAPCacheEngineSize](references/doc_8739.md)
968. [setPrefetchComputeNodeData](references/doc_2140.md)
969. [setRandomSeed](references/doc_2795.md)
970. [setReservedMemSize](references/doc_2449.md)
971. [setRetentionPolicy](references/doc_503.md)
972. [setStreamTableFilterColumn](references/doc_9502.md)
973. [setSystem](references/doc_2468.md)
974. [setTSDBCacheEngineSize](references/doc_6917.md)
975. [setTableComment](references/doc_6586.md)
976. [shape](references/doc_8939.md)
977. [shapiroTest](references/doc_8119.md)
978. [shell](references/doc_539.md)
979. [short](references/doc_2462.md)
980. [shuffle](references/doc_1013.md)
981. [shuffle!](references/doc_6452.md)
982. [signbit](references/doc_3244.md)
983. [signum](references/doc_3898.md)
984. [sin](references/doc_4854.md)
985. [sinh](references/doc_9712.md)
986. [size](references/doc_909.md)
987. [skew](references/doc_8179.md)
988. [skipClusterReplicationTask](references/doc_7574.md)
989. [sleep](references/doc_9272.md)
990. [slice](references/doc_6990.md)
991. [sliceByKey](references/doc_1032.md)
992. [sma](references/doc_8589.md)
993. [snippet](references/doc_3364.md)
994. [socp](references/doc_713.md)
995. [solve](references/doc_3977.md)
996. [sort](references/doc_2467.md)
997. [sort!](references/doc_8788.md)
998. [sortBy!](references/doc_1921.md)
999. [spearmanr](references/doc_51.md)
1000. [splev](references/doc_420.md)
1001. [spline](references/doc_3533.md)
1002. [splrep](references/doc_2579.md)
1003. [sqrt](references/doc_6493.md)
1004. [square](references/doc_8442.md)
1005. [startClusterReplication](references/doc_8923.md)
1006. [startDataNode](references/doc_5055.md)
1007. [startHeapSample](references/doc_7233.md)
1008. [startsWith](references/doc_7349.md)
1009. [stl](references/doc_9561.md)
1010. [stopClusterReplication](references/doc_9558.md)
1011. [stopDataNode](references/doc_4056.md)
1012. [stopHeapSample](references/doc_5390.md)
1013. [strReplace](references/doc_1017.md)
1014. [streamEngineParser](references/doc_7794.md)
1015. [streamTable](references/doc_355.md)
1016. [stretch](references/doc_6323.md)
1017. [strip](references/doc_3770.md)
1018. [strlen](references/doc_1158.md)
1019. [strlenu](references/doc_7420.md)
1020. [strpos](references/doc_2233.md)
1021. [sub](references/doc_5656.md)
1022. [subarray](references/doc_9206.md)
1023. [submitJob](references/doc_9461.md)
1024. [submitJobEx](references/doc_7986.md)
1025. [submitJobEx2](references/doc_3804.md)
1026. [subscribeTable](references/doc_3003.md)
1027. [subtuple](references/doc_1796.md)
1028. [sum](references/doc_7384.md)
1029. [sum2](references/doc_7316.md)
1030. [sum3](references/doc_5347.md)
1031. [sum4](references/doc_9815.md)
1032. [sumbars](references/doc_7675.md)
1033. [summary](references/doc_6988.md)
1034. [suspendRecovery](references/doc_9521.md)
1035. [svd](references/doc_2006.md)
1036. [symbol](references/doc_3461.md)
1037. [symbolCode](references/doc_4952.md)
1038. [symmetricDifference](references/doc_6602.md)
1039. [syncDict](references/doc_9445.md)
1040. [syntax](references/doc_7550.md)
1041. [t3](references/doc_5990.md)
1042. [tTest](references/doc_1226.md)
1043. [table](references/doc_4241.md)
1044. [tableInsert](references/doc_834.md)
1045. [tableUpsert](references/doc_7074.md)
1046. [tail](references/doc_1257.md)
1047. [take](references/doc_7848.md)
1048. [talib](references/doc_6622.md)
1049. [talibNull](references/doc_7081.md)
1050. [tan](references/doc_5965.md)
1051. [tanh](references/doc_2936.md)
1052. [tanimoto](references/doc_9985.md)
1053. [tema](references/doc_2483.md)
1054. [temporalAdd](references/doc_4892.md)
1055. [temporalDeltas](references/doc_8585.md)
1056. [temporalDiff](references/doc_6735.md)
1057. [temporalFormat](references/doc_3283.md)
1058. [temporalParse](references/doc_1619.md)
1059. [temporalSeq](references/doc_5171.md)
1060. [tensor](references/doc_245.md)
1061. [textChunkDS](references/doc_5108.md)
1062. [til](references/doc_3974.md)
1063. [tmLowRange](references/doc_7506.md)
1064. [tmTopRange](references/doc_4616.md)
1065. [tmavg](references/doc_1219.md)
1066. [tmbeta](references/doc_1621.md)
1067. [tmcount](references/doc_4769.md)
1068. [tmcovar](references/doc_2931.md)
1069. [tmfirst](references/doc_2925.md)
1070. [tmkurtosis](references/doc_7591.md)
1071. [tmlast](references/doc_1739.md)
1072. [tmmax](references/doc_2597.md)
1073. [tmmed](references/doc_2226.md)
1074. [tmmin](references/doc_2527.md)
1075. [tmove](references/doc_4317.md)
1076. [tmoving](references/doc_1842.md)
1077. [tmpercentile](references/doc_3261.md)
1078. [tmprod](references/doc_5659.md)
1079. [tmrank](references/doc_3368.md)
1080. [tmskew](references/doc_2624.md)
1081. [tmsum](references/doc_1981.md)
1082. [tmsum2](references/doc_4278.md)
1083. [tmvar](references/doc_7536.md)
1084. [tmvarp](references/doc_5818.md)
1085. [tmwavg](references/doc_452.md)
1086. [tmwsum](references/doc_3271.md)
1087. [toCharArray](references/doc_143.md)
1088. [toJson](references/doc_3990.md)
1089. [toUTF8](references/doc_9075.md)
1090. [today](references/doc_3142.md)
1091. [tokenizeBert](references/doc_1608.md)
1092. [topRange](references/doc_8656.md)
1093. [transDS!](references/doc_1005.md)
1094. [transFreq](references/doc_767.md)
1095. [transpose](references/doc_9914.md)
1096. [treasuryConversionFactor](references/doc_8855.md)
1097. [triggerNodeReport](references/doc_9734.md)
1098. [triggerTSDBCompaction](references/doc_5473.md)
1099. [tril](references/doc_2459.md)
1100. [trim](references/doc_3048.md)
1101. [trima](references/doc_393.md)
1102. [triu](references/doc_7353.md)
1103. [trueRange](references/doc_6480.md)
1104. [truncate](references/doc_5542.md)
1105. [tupleSum](references/doc_6812.md)
1106. [twindow](references/doc_4908.md)
1107. [type](references/doc_7186.md)
1108. [typestr](references/doc_1594.md)
1109. [undef](references/doc_9146.md)
1110. [unifiedCall](references/doc_8136.md)
1111. [union](references/doc_4130.md)
1112. [unionAll](references/doc_1461.md)
1113. [unloadVocab](references/doc_9086.md)
1114. [unlockUser](references/doc_4793.md)
1115. [unpack](references/doc_6852.md)
1116. [unpivot](references/doc_9509.md)
1117. [unsubscribeTable](references/doc_7186.md)
1118. [upper](references/doc_1052.md)
1119. [upsert!](references/doc_5823.md)
1120. [uuid](references/doc_518.md)
1121. [valueAtRisk](references/doc_2367.md)
1122. [valueChanged](references/doc_8197.md)
1123. [values](references/doc_7795.md)
1124. [vanillaOption](references/doc_7930.md)
1125. [var](references/doc_2110.md)
1126. [varma](references/doc_7652.md)
1127. [varp](references/doc_3507.md)
1128. [vectorAR](references/doc_7033.md)
1129. [version](references/doc_9262.md)
1130. [volumeBar](references/doc_2460.md)
1131. [warmupComputeNodeCache](references/doc_7031.md)
1132. [warmupStreamEngine](references/doc_1378.md)
1133. [wavg](references/doc_5822.md)
1134. [wc](references/doc_861.md)
1135. [wcovar](references/doc_870.md)
1136. [weekBegin](references/doc_4573.md)
1137. [weekEnd](references/doc_6079.md)
1138. [weekOfMonth](references/doc_3670.md)
1139. [weekOfYear](references/doc_2884.md)
1140. [weekday](references/doc_6305.md)
1141. [wilder](references/doc_6097.md)
1142. [window](references/doc_2687.md)
1143. [winsorize](references/doc_3111.md)
1144. [winsorize!](references/doc_7821.md)
1145. [withNullFill](references/doc_9431.md)
1146. [withdrawMCPPrompts](references/doc_9759.md)
1147. [withdrawMCPTools](references/doc_7628.md)
1148. [wls](references/doc_6627.md)
1149. [wma](references/doc_6087.md)
1150. [write](references/doc_952.md)
1151. [writeBytes](references/doc_911.md)
1152. [writeLine](references/doc_4785.md)
1153. [writeLines](references/doc_4693.md)
1154. [writeObject](references/doc_1959.md)
1155. [writeRecord](references/doc_8559.md)
1156. [wsum](references/doc_1017.md)
1157. [xdb](references/doc_427.md)
1158. [xor](references/doc_4681.md)
1159. [year](references/doc_395.md)
1160. [yearBegin](references/doc_1120.md)
1161. [yearEnd](references/doc_2270.md)
1162. [zTest](references/doc_4141.md)
1163. [zigzag](references/doc_2813.md)
1164. [zscore](references/doc_9323.md)
1165. [函数分类](references/doc_5614.md)
1166. [函数分类](references/doc_4491.md)
1167. [函数参考](references/doc_225.md)
1168. [流计算引擎](references/doc_3500.md)
1169. [滑动窗口系列(m 系列)](references/doc_6914.md)
1170. [系列函数](references/doc_4668.md)
1171. [累计窗口系列(cum 系列)](references/doc_8366.md)
## 函数参考/字符串函数 (5个文档)
1. [split](references/doc_1621.md)
2. [string](references/doc_5622.md)
3. [stringFormat](references/doc_2325.md)
4. [substr](references/doc_6241.md)
5. [substru](references/doc_1193.md)
## 函数参考/数学函数 (42个文档)
1. [abs](references/doc_2790.md)
2. [binaryExpr](references/doc_4331.md)
3. [cdfExp](references/doc_1470.md)
4. [cdfLogistic](references/doc_4564.md)
5. [cleanOutdateLogFiles](references/doc_5727.md)
6. [createCatalog](references/doc_8740.md)
7. [dropCatalog](references/doc_3855.md)
8. [existsCatalog](references/doc_2049.md)
9. [exp](references/doc_5122.md)
10. [exp2](references/doc_1177.md)
11. [expm1](references/doc_3325.md)
12. [expr](references/doc_7258.md)
13. [getAclAuditLog](references/doc_7642.md)
14. [getAllCatalogs](references/doc_585.md)
15. [getAuditLog](references/doc_1625.md)
16. [getCatalogsByCluster](references/doc_7650.md)
17. [getInstrumentExpiry](references/doc_9455.md)
18. [getInstrumentFarExpiry](references/doc_3518.md)
19. [getInstrumentNearExpiry](references/doc_9142.md)
20. [getLicenseExpiration](references/doc_6363.md)
21. [getRedoLogGCStat](references/doc_8267.md)
22. [getSchemaByCatalog](references/doc_6157.md)
23. [imtForceGCRedolog](references/doc_2263.md)
24. [invExp](references/doc_6462.md)
25. [invLogistic](references/doc_5048.md)
26. [isLoggedIn](references/doc_8915.md)
27. [log](references/doc_5756.md)
28. [log10](references/doc_4409.md)
29. [log1p](references/doc_2752.md)
30. [log2](references/doc_545.md)
31. [login](references/doc_4333.md)
32. [logisticRegression](references/doc_7103.md)
33. [logout](references/doc_7196.md)
34. [parseExpr](references/doc_6228.md)
35. [randExp](references/doc_3244.md)
36. [randLogistic](references/doc_7882.md)
37. [renameCatalog](references/doc_3185.md)
38. [setDefaultCatalog](references/doc_6176.md)
39. [setLogLevel](references/doc_3828.md)
40. [unifiedExpr](references/doc_9288.md)
41. [writeLog](references/doc_2237.md)
42. [writeLogLevel](references/doc_506.md)
## 函数参考/时间序列函数 (26个文档)
1. [concatDateTime](references/doc_7485.md)
2. [createDailyTimeSeriesEngine](references/doc_6683.md)
3. [createTimeBucketEngine](references/doc_7405.md)
4. [createTimeSeriesEngine](references/doc_603.md)
5. [date](references/doc_6727.md)
6. [datehour](references/doc_6031.md)
7. [datetime](references/doc_2698.md)
8. [dictUpdate!](references/doc_1387.md)
9. [evalTimer](references/doc_7984.md)
10. [gmtime](references/doc_8329.md)
11. [imtUpdateChunkVersionOnDataNode](references/doc_7630.md)
12. [linearTimeTrend](references/doc_9142.md)
13. [localtime](references/doc_275.md)
14. [nanotime](references/doc_5035.md)
15. [nanotimestamp](references/doc_2136.md)
16. [setChunkLastUpdateTime](references/doc_445.md)
17. [setStreamTableTimestamp](references/doc_6564.md)
18. [setTimeoutTick](references/doc_6322.md)
19. [sqlUpdate](references/doc_5856.md)
20. [time](references/doc_550.md)
21. [timestamp](references/doc_5299.md)
22. [update!](references/doc_4618.md)
23. [updateLicense](references/doc_5427.md)
24. [updateMCPPrompt](references/doc_3301.md)
25. [updateMCPTool](references/doc_5363.md)
26. [updateMarketHoliday](references/doc_1968.md)
## 函数参考/统计函数 (61个文档)
1. [autocorr](references/doc_6151.md)
2. [clearAllIOTDBStaticTableCache](references/doc_6744.md)
3. [corr](references/doc_3986.md)
4. [corrMatrix](references/doc_3466.md)
5. [createDualOwnershipReactiveStateEngine](references/doc_9574.md)
6. [createNarrowReactiveStateEngine](references/doc_4956.md)
7. [createReactiveStateEngine](references/doc_6673.md)
8. [crossStat](references/doc_8784.md)
9. [cumcorr](references/doc_2624.md)
10. [cumstd](references/doc_109.md)
11. [cumstdp](references/doc_8623.md)
12. [ewmCorr](references/doc_111.md)
13. [ewmStd](references/doc_1438.md)
14. [fromStdJson](references/doc_9396.md)
15. [genericStateIterate](references/doc_6532.md)
16. [genericTStateIterate](references/doc_9636.md)
17. [getAggregatorStat](references/doc_1193.md)
18. [getBackupStatus](references/doc_1488.md)
19. [getClusterChunksStatus](references/doc_5915.md)
20. [getClusterStatus](references/doc_3794.md)
21. [getComputeGroupChunksStatus](references/doc_1297.md)
22. [getComputeNodeCacheStat](references/doc_5783.md)
23. [getComputeNodeCacheWarmupJobStatus](references/doc_8146.md)
24. [getJobStat](references/doc_2382.md)
25. [getJobStatus](references/doc_1761.md)
26. [getLevelFileIndexCacheStatus](references/doc_4758.md)
27. [getLocalIOTDBStaticTable](references/doc_5351.md)
28. [getMemoryStat](references/doc_5585.md)
29. [getOLAPCacheEngineStat](references/doc_9469.md)
30. [getPKEYCompactionTaskStatus](references/doc_2801.md)
31. [getQueryStatus](references/doc_8159.md)
32. [getRecoveryTaskStatus](references/doc_8957.md)
33. [getSessionMemoryStat](references/doc_5643.md)
34. [getSlaveReplicationQueueStatus](references/doc_9726.md)
35. [getSlaveReplicationStatus](references/doc_5459.md)
36. [getStreamEngineStat](references/doc_4535.md)
37. [getStreamingSQLStatus](references/doc_1153.md)
38. [getStreamingStat](references/doc_6846.md)
39. [getTSDBCompactionTaskStatus](references/doc_5399.md)
40. [getTSDBDataStat](references/doc_5241.md)
41. [getTSDBTableIndexCacheStatus](references/doc_4134.md)
42. [getTransactionStatus](references/doc_9893.md)
43. [mcorr](references/doc_3270.md)
44. [mcorrTopN](references/doc_5077.md)
45. [mstd](references/doc_2646.md)
46. [mstdTopN](references/doc_6538.md)
47. [mstdp](references/doc_6784.md)
48. [mstdpTopN](references/doc_8493.md)
49. [nextState](references/doc_1015.md)
50. [prevState](references/doc_6013.md)
51. [rowCorr](references/doc_995.md)
52. [rowStd](references/doc_9599.md)
53. [rowStdp](references/doc_8844.md)
54. [stat](references/doc_6841.md)
55. [stateIterate](references/doc_7716.md)
56. [std](references/doc_2497.md)
57. [stdp](references/doc_9279.md)
58. [tmcorr](references/doc_4673.md)
59. [tmstd](references/doc_3967.md)
60. [tmstdp](references/doc_99.md)
61. [toStdJson](references/doc_5532.md)
## 教程与示例 (1个文档)
1. [教程](references/doc_8158.md)
## 数据库核心 (13个文档)
1. [OLAP 存储引擎](references/doc_7837.md)
2. [OLTP 内存存储引擎(非嵌入式版)使用教程](references/doc_6414.md)
3. [TSDB 存储引擎](references/doc_6240.md)
4. [主键存储引擎](references/doc_9706.md)
5. [分布式事务](references/doc_3187.md)
6. [分布式架构](references/doc_6249.md)
7. [分级存储](references/doc_5899.md)
8. [向量存储引擎](references/doc_9470.md)
9. [数据分区](references/doc_9485.md)
10. [数据平衡](references/doc_8252.md)
11. [数据库](references/doc_2718.md)
12. [物联网点位管理引擎](references/doc_4396.md)
13. [高可用](references/doc_3934.md)
## 流数据处理 (22个文档)
1. [Altair 连接 DolphinDB 数据源](references/doc_7220.md)
2. [Orca 实时计算平台](references/doc_1659.md)
3. [Python API 接入数据](references/doc_7284.md)
4. [StreamEngineParser 解析原理](references/doc_7377.md)
5. [会话窗口引擎](references/doc_1649.md)
6. [入门示例](references/doc_761.md)
7. [内置多数据源流式关联引擎](references/doc_3813.md)
8. [功能简介](references/doc_6332.md)
9. [历史数据回放](references/doc_6220.md)
10. [响应式状态引擎](references/doc_1096.md)
11. [复杂事件处理(CEP)引擎](references/doc_742.md)
12. [实时流数据接入](references/doc_3101.md)
13. [异常检测引擎](references/doc_5125.md)
14. [时序聚合引擎](references/doc_7885.md)
15. [横截面引擎](references/doc_7217.md)
16. [流式 SQL](references/doc_3242.md)
17. [流式计算算子](references/doc_9830.md)
18. [流批一体](references/doc_3049.md)
19. [流数据](references/doc_8004.md)
20. [流数据高可用](references/doc_2767.md)
21. [流计算状态监控](references/doc_7423.md)
22. [节点内部订阅](references/doc_710.md)
## 运维管理 (1个文档)
1. [系统运维](references/doc_3896.md)
## 部署与配置 (9个文档)
1. [Linux 系统部署准备](references/doc_5216.md)
2. [单服务器集群部署与升级](references/doc_7984.md)
3. [单节点部署与升级](references/doc_1710.md)
4. [单节点部署与升级 (ARM)](references/doc_5524.md)
5. [基于 Docker 部署 DolphinDB](references/doc_5479.md)
6. [多服务器集群部署与升级](references/doc_9483.md)
7. [如何采集服务器指纹生成 DolphinDB License](references/doc_5208.md)
8. [部署](references/doc_8935.md)
9. [高可用集群部署与升级](references/doc_8250.md)
FILE:README.md
# DolphinDB Skill - 完整技术文档库
> **版本**: 2.0.0 (优化版) | **评分**: 9.5/10 ⭐
> **DolphinDB版本**: 3.00.4 | **更新时间**: 2026-01-22
一站式DolphinDB时序数据库技术文档与最佳实践指南。包含1493个技术文档 + 3份官方白皮书,涵盖数据库设计、流计算、量化回测等全场景。
---
## 📚 核心资源
### 🎯 官方白皮书 (4557行深度内容)
| 白皮书 | 行数 | 适用场景 |
|--------|------|---------|
| [数据库白皮书](references/whitepapers/database.md) | 1073 | 架构设计、性能优化、生产部署 |
| [流数据白皮书](references/whitepapers/streaming.md) | 2279 | 实时计算、CEP、流式ETL |
| [回测白皮书](references/whitepapers/backtest.md) | 2205 | 量化回测、算法交易、策略研发 |
### 📖 技术文档 (1490篇)
| 分类 | 数量 | 说明 |
|------|------|------|
| 函数参考 | 1171+ | 数学、统计、时序、SQL等 |
| 流数据处理 | 22 | 流表、订阅、引擎 |
| 数据库核心 | 13 | 存储引擎、分区、事务 |
| 部署与配置 | 9 | 集群部署、参数配置 |
| 其他 | 97+ | API、运维、教程等 |
**完整索引**: 见 [CATALOG.md](CATALOG.md) (1536行)
---
### **前置准备(必看)**:
1. 确保已安装 DolphinDB 相关环境,具体环境部署可参考 [部署](https://docs.dolphindb.cn/zh/deploy/deploy_intro.html);
2. 安装 VS Code 客户端 ;
3. 安装 GitHub Copilot 和 DolphinDB 扩展,具体 DolphinDB 扩展安装可参考 [VS Code 插件](https://docs.dolphindb.cn/zh/db_distr_comp/vscode.html);


4. 克隆本仓库到本地目录:
| **类型** | **VSCODE** | Antigravity | **CLAUDE** |
| :--------- | :------------------- | ----------------------------------------------- | :------------------ |
| 项目 Skill | `.github/skills/` | <workspace-root>/.agents/skills/<skill-folder>/ | `.claude/skills/` |
| 个人 Skill | `~/.copilot/skills/` | ~/.gemini/antigravity/skills/<skill-folder>/ | `~/.claude/skills/` |
保证层级目录为:
```
skills/
└── dolphindb_skill/
├── assets/
├── ...
└── SKILL.md
```
项目路径:适用于团队协作或特定项目开发,将 DolphinDB Skill 放入当前开发项目根目录下的 `.github/skills/` 文件夹中,仅对当前项目生效,不影响其他项目的 AI 代理配置,方便团队共享统一的 Skill 版本。
个人路径:适用于个人日常开发,将 DolphinDB Skill 放入个人用户目录下的 `.copilot/skills/` 文件夹中,全局生效,无论打开哪个 DolphinDB 开发项目,都能调用该 Skill,无需重复配置。
其他 AI Agent 使用 DolphinDB Skill,可以将其配置到对应的目录下,例如配置 Google Antigravity 的Global Skill,可以将其配置到 `~/.gemini/antigravity/skills/<skill-folder>/` 目录下,重启 Google Antigravity 即可直接使用,具体可参考 [Google Antigravity Documentation](https://antigravity.google/docs/skills) 。
#### Step 1:配置 DolphinDB Skill
打开 VS Code,进入 GitHub Copilot 插件设置,找到“Chat: Use Agent Skills”配置项并启用。

配置完成后,如果 `/dolphindb` 指令可被正常查找到,则证明 DolphinDB Skill 配置成功。

#### Step 2:3 个高频场景,解锁 AI 辅助开发
温馨提示:以下所有场景的提问前,需添加 `/dolphindb` ,才能成功调用 DolphinDB Skill
#### **场景 1:自然语言转脚本**
打开 Copilot 聊天视图,输入自然语言指令,比如:
“/dolphindb 帮我写一个创建 TSDB 存储引擎分区表的脚本,采用 VALUE+HASH 组合分区,要求有字段 time, symbol,price,并且生成20条模拟数据,使用 dolphindb 的标准 sql 语句实现”
“/dolphindb 写一个流计算实时 K 线合成的脚本”
Copilot 会生成符合语法规范的完整脚本,可直接复制使用,还能通过内联聊天精准调整。

#### **场景 2:概念与知识点讲解**
在 Copilot 聊天视图输入提问,比如:
“/dolphindb 解释一下 DolphinDB 的 TSDB 和 OLAP 存储引擎的区别”
“/dolphindb DolphinDB 中时序聚合引擎的用法”
DolphinDB Skill 会结合官方文档内容,用通俗语言拆解知识点+搭配示例,边开发边学习,无需额外查文档。

#### 场景 3:调试与优化
生成脚本后,若出现语法报错,可直接在聊天界面提问,快速获取针对性解决方案。

### 为什么值得用?
1. 零成本上手:依托 VS Code+Copilot 熟悉操作,简单配置即可使用;
2. 精准适配:专为 DolphinDB 设计,同步官方文档核心内容;
3. 效率翻倍:节省语法记忆、调试、查文档时间,新手快速入门,资深开发者提效;
4. 边学边练:支持知识点讲解,边开发边夯实基础。
---
## 📖 主要文档说明
| 文件 | 大小 | 用途 |
|------|------|------|
| **SKILL.md** | 12KB | 主文档,包含完整指南、代码示例、工作流 |
| **CATALOG.md** | 64KB | 1493个文档的完整索引,按13类组织 |
| **metadata.json** | 209KB | 元数据,包含所有文档的详细信息 |
| **references/** | ~7.8MB | 所有技术文档和白皮书 |
| **assets/** | - | 图片等资源文件 |
---
## 🔍 快速查找
### 按问题查找
| 问题 | 答案位置 |
|------|---------|
| 如何选择TSDB vs OLAP? | [SKILL.md](SKILL.md) → 存储引擎选择 |
| 如何设计分区策略? | [数据库白皮书](references/whitepapers/database.md) 第2.2节 |
| 流计算引擎有哪些? | [流数据白皮书](references/whitepapers/streaming.md) 第3章 |
| 如何实现高可用? | [doc_3934.md](references/doc_3934.md) |
### 按角色查找
| 角色 | 推荐路径 |
|------|---------|
| **架构师** | 数据库白皮书 → 分布式架构 → SKILL.md工作流 |
| **量化工程师** | 回测白皮书 → SKILL.md代码示例 → CATALOG函数查询 |
| **后端开发** | 流数据白皮书 → SKILL.md流计算示例 → API文档 |
| **数据分析师** | SKILL.md SQL示例 → CATALOG函数参考 |
---
## 💡 v2.0 核心特性
相比v1.x版本,v2.0优化版提供:
✅ **完整文档索引** - CATALOG.md覆盖所有1493个文档
✅ **3份官方白皮书** - 4557行深度技术内容
✅ **场景化导航** - 15个常见问题快速定位
✅ **5大类代码示例** - 可直接运行的完整示例
✅ **13个细分类别** - 更精准的文档分类
✅ **版本信息明确** - 标注DolphinDB 3.00.4
---
## 📊 目录结构
```
dolphindb_skill/
├── README.md # 本文件 (快速入门)
├── SKILL.md # 主文档 (详细指南)
├── CATALOG.md # 文档索引 (1493个文档)
├── metadata.json # 元数据
├── assets/ # 资源文件
│ └── images/
└── references/ # 参考文档
├── whitepapers/ # 官方白皮书
│ ├── database.md # 数据库白皮书
│ ├── streaming.md # 流数据白皮书
│ ├── backtest.md # 回测白皮书
│ └── images/
└── doc_*.md # 1490篇技术文档
```
---
## 🔗 相关资源
- **官网**: https://www.dolphindb.com
- **文档中心**: https://docs.dolphindb.cn
- **社区论坛**: https://ask.dolphindb.cn/
- **GitHub**: https://github.com/dolphindb
---
## 📞 技术支持
遇到问题?
1. 先查阅 [SKILL.md](SKILL.md) 常见问题导航
2. 使用 [CATALOG.md](CATALOG.md) 搜索相关文档
3. 访问 [DolphinDB社区](https://ask.dolphindb.cn/)
4. 联系官方技术支持
---
## 📝 更新日志
### v2.0 (2026-01-22)
- ✅ 整合3份官方白皮书 (4557行)
- ✅ 生成完整文档索引 CATALOG.md
- ✅ 新增15个常见问题快速导航
- ✅ 补充5大类可运行代码示例
- ✅ 优化为13个细分类别
- ✅ 更新DolphinDB版本信息至3.00.4
### v1.x (2025-01-20)
- 初始版本,包含1490个技术文档
---
**Skill版本**: 2.0.0 | **DolphinDB版本**: 3.00.4 | **质量评分**: 9.5/10 ⭐
**维护**: Skill Creator | **许可**: MIT
FILE:references/doc_10.md
# decompress
**URL**: https://docs.dolphindb.cn/zh/funcs/d/decompress.html
**来源**: DolphinDB 官方文档
---
decompress
语法
decompress(X)
详情
对一个压缩后的向量进行解压缩。
参数
X
是一个压缩后的向量。
返回值
返回一个向量。
例子
x=1..100000000
y=compress(x, "delta");
y.typestr();
// output: HUGE COMPRESSED VECTOR
z=decompress(y);
z.size();
// output: 100000000
相关函数:
compress
FILE:references/doc_1005.md
# transDS!
**URL**: https://docs.dolphindb.cn/zh/funcs/t/transDS_.html
**来源**: DolphinDB 官方文档
---
transDS!
语法
transDS!(ds, tranFunc)
详情
将函数应用到数据源。
参数
ds
是数据源或数据源列表。
tranFunc
是一个函数。它的参数必须是一个表。
返回值
无。
例子
下例将分布式表 trades1 的时间列从 TIMESTAMP 类型转换成 NANOTIMESTAMP 类型后插入到分布式表
trades2中。
db=database("dfs://stock1",VALUE,`A`B`C`D)
n=200000
trade_time=2018.01.02T06:12:03.458+1..n
sym=rand(`A`B`C`D,n)
qty=rand(100.0,n)
price=rand(100.0,n)
t=table(trade_time,sym,qty,price)
trades1=db.createPartitionedTable(t,`trades1,`sym).append!(t);
ds=sqlDS(<select * from trades1>);
def convertNanotimestamp(t){
return select nanotimestamp(trade_time), sym, qty, price from t
}
ds.transDS!(convertNanotimestamp);
db=database("dfs://stock2",VALUE,`A`B`C`D)
t=table(1:0,`trade_time`sym`qty`price,[NANOTIMESTAMP,SYMBOL,DOUBLE,DOUBLE])
trades2=db.createPartitionedTable(t,`trades2,`sym);
mr(ds,append!{trades2},,,false);
exec count(*) from trades2;
// output
200000
FILE:references/doc_1013.md
# shuffle
**URL**: https://docs.dolphindb.cn/zh/funcs/s/shuffle.html
**来源**: DolphinDB 官方文档
---
shuffle
语法
shuffle(X)
shuffle!
是
shuffle
的原地计算的版本。
详情
对数据重组后,返回一个新的向量或矩阵。
参数
x
可以是向量或矩阵。
返回值
数据重组后,返回一个新的向量或矩阵。
例子
x=(1..6).shuffle();
x;
// output
[1,6,3,5,4,2]
x.shuffle!();
// output
[5,4,1,3,2,6]
x=(1..6).reshape(3:2);
x;
#0
#1
1
4
2
5
3
6
x.shuffle();
#0
#1
5
3
2
1
4
6
FILE:references/doc_1015.md
# nextState
**URL**: https://docs.dolphindb.cn/zh/funcs/n/nextState.html
**来源**: DolphinDB 官方文档
---
nextState
语法
nextState(X)
详情
X
中连续且相同的元素标记为同一状态,空值无状态。每个元素的状态等于其元素值。对于
X
中的每一个元素,返回当前状态的下一个状态。若当前元素为空,则返回下一个邻近状态。
X
是矩阵时,则在矩阵每一列进行上述计算。
参数
X
时间类型,布尔类型或者数值型的向量/矩阵。
返回值
返回一个与输入
X
相同数据类型和形式的对象。
例子
X = [1, 2.2, NULL, 2.2, 2.3, 1, 1.2]
next(X)
// output
[2.2,,2.2,2.3,1,1.2,]
nextState(X)
// output
[2.2,2.2,2.2,2.3,1,1.2,]
X = matrix([1.0, 1.1, 1.0, 0.9], [NULL, 1.3, 2.5, 5.5], [5.5, 4.2, 1.6, 1.8])
nextState(X)
#0
#1
#2
1.1
1.3
4.2
1
2.5
1.6
0.9
5.5
1.8
相关函数:
prevState
FILE:references/doc_1017.md
# wsum
**URL**: https://docs.dolphindb.cn/zh/funcs/w/wsum.html
**来源**: DolphinDB 官方文档
---
wsum
语法
wsum(X, Y)
详情
返回
X
和
Y
的内积。即使
X
和
Y
都是整型,返回结果仍为
DOUBLE 类型。
参数
X
和
Y
可以是标量、向量、矩阵或表。
返回值
DOUBLE 类型的标量/向量/表。
例子
wsum(7 8 9, 1 2 3);
// output
50
// 7*1 + 8*2 + 9*3 = 50
相关函数:
wavg
FILE:references/doc_1022.md
# readObject
**URL**: https://docs.dolphindb.cn/zh/funcs/r/readObject.html
**来源**: DolphinDB 官方文档
---
readObject
语法
readObject(handle)
详情
可以读取句柄中所有的数据类型,包括标量、向量、矩阵、集合、字典和表。该函数必须要用户登录后才能执行。
参数
handle
是文件句柄。
返回值
返回读取的内容。
例子
a1=10.5
a2=1..10
a3=cross(*,1..5,1..10)
a4=set(`IBM`MSFT`GOOG`YHOO)
a5=dict(a4.keys(),125.6 53.2 702.3 39.7)
a6=table(1 2 3 as id, `Jenny`Tom`Jack as name)
a7=(1 2 3, "hello world!", 25.6)
fout=file("test.bin","w")
fout.writeObject(a1)
fout.writeObject(a2)
fout.writeObject(a3)
fout.writeObject(a4)
fout.writeObject(a5)
fout.writeObject(a6)
fout.writeObject(a7)
fout.close();
上述的脚本把 7 个不同类型的对象写到一个文件中。下述的脚本将这 7 个对象从文件中读取出来,并为每个对象打印一个简短的描述。
fin = file("test.bin")
for(i in 0:7) print typestr fin.readObject()
fin.close();
// output
DOUBLE
FAST INT VECTOR
INT MATRIX
STRING SET
STRING->DOUBLE Dictionary
TABLE
ANY VECTOR
FILE:references/doc_1032.md
# sliceByKey
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sliceByKey.html
**来源**: DolphinDB 官方文档
---
sliceByKey
语法
sliceByKey(table, rowKeys, [colNames], [preserveOrder=false])
详情
从键值表或索引内存表中获取含有索引列指定值(由参数
rowKeys
指定)的行以及指定列(由
colNames
参数指定)的数据。耗时约为相应的 SQL 语句的50%。
如果是键值表,
rowKeys
参数必须含有所有
keyColumns
的值。
如果是索引内存表,可指定前 n 个
keyColumns
的值,若其中有一列指定值为向量,所有指定列的指定值均需为同等长度的向量。
若不指定
colNames
参数,则会输出所有列。
结果的数据结构取决于
colNames
。若
colNames
为标量,返回一个向量;若
colNames
为向量,返回一个内存表。
参数
table
是键值表或索引内存表。
rowKeys
是标量或向量,表示索引列的指定值。
colNames
可选参数,是字符串标量或向量,表示要选择的列的列名。
preserveOrder
可选参数,布尔标量,表示是否按照
rowKeys
中值的顺序返回结果。默认为 false,此时输出顺序可能不同于
rowKeys
的顺序。
返回值
返回结果的数据结构取决于 colNames。若 colNames 为标量,返回一个向量;若 colNames 为向量,返回一个内存表。
例子
t = indexedTable(`sym`side, 10000:0, `sym`side`price`qty, [SYMBOL,CHAR,DOUBLE,INT])
insert into t values(`IBM`MSFT`IBM, ['B','S','S'], 125.27 208.9 125.29, 1000 800 200)
a=sliceByKey(t,"IBM", 'price');
a;
// output
[125.27,125.29]
typestr(a);
// output
FAST DOUBLE VECTOR
a=sliceByKey(t,("IBM",'S'));
a;
sym
side
price
qty
IBM
S
125.29
200
typestr(a);
// output
IN-MEMORY TABLE
t1 = keyedTable(`sym`side, 10000:0, `sym`side`price`qty, [SYMBOL,CHAR,DOUBLE,INT])
insert into t1 values(`IBM`MSFT`IBM, ['B','S','S'], 125.27 208.9 125.29, 1000 800 200)
sliceByKey(t1, [["IBM", "MSFT"], ['B', 'S']]);
sym
side
price
qty
IBM
B
125.27
1000
MSFT
S
208.9
800
指定
preserveOrder
=true,可按索引列的输入顺序返回结果。
sliceByKey(table=t1, rowKeys=[["MSFT", "IBM"], ['S', 'B']], preserveOrder=true);
sym
side
price
qty
MSFT
S
208.9
800
IBM
B
125.27
1000
FILE:references/doc_1035.md
# loadTableBySQL
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadTableBySQL.html
**来源**: DolphinDB 官方文档
---
loadTableBySQL
语法
loadTableBySQL(sql)
详情
把分区表中满足 SQL 查询的记录行加载到内存中。返回的是分区的内存表,其分区机制与分区表一致。
注:
该函数用于根据
sql
创建分区内存表,存在一些查询限制。因此,在大数据量查询场景下,使用该函数可能会出现内存占用多的情况。建议在这种情况下直接使用 SQL 语句进行查询。
参数
sql
是表示 SQL 查询的元代码。它可以用 WHERE 子句来过滤分区或记录行,也可以用 SELECT
语句选择包括计算列在内的列,但不能包含 TOP 子句、GROUP BY 子句、 ORDER BY 子句、CONTEXT BY 子句和 LIMIT 子句。
返回值
一张表。
例子
n=1000000
t=table(rand('A'..'Z',n) as sym, 2000.01.01+rand(365,n) as date, 10.0+rand(2.0,n) as price1, 100.0+rand(20.0,n) as price2, rand(10,n) as qty1, rand(100,n) as qty2)
db = database("dfs://tradeDB", VALUE, 'A'..'Z')
trades=db.createPartitionedTable(t,`trades,`sym).append!(t)
sample=select * from loadTableBySQL(<select * from trades where date between 2000.03.01 : 2000.05.01>)
sample=select * from loadTableBySQL(<select sym, date, price1, qty1 from trades where date between 2000.03.01 : 2000.05.01>)
dates = 2000.01.16 2000.02.14 2000.08.01
st = sql(<select sym, date, price1, qty1>, trades, expr(<date>, in, dates))
sample = select * from loadTableBySQL(st)
colNames =`sym`date`qty2`price2
st= sql(sqlCol(colNames), trades)
sample = select * from loadTableBySQL(st)
FILE:references/doc_104.md
# deleteReplicas
**URL**: https://docs.dolphindb.cn/zh/funcs/d/deleteReplicas.html
**来源**: DolphinDB 官方文档
---
deleteReplicas
语法
deleteReplicas(chunkId, nodeAlias)
详情
把节点上的一个或多个 chunk 的副本删除。该命令只能由管理员在控制节点上执行。
参数
chunkId
是字符串标量或向量,表示 chunk 的 ID。
nodeAlias
是一个字符串,表示节点的别名。
返回值
无。
例子
删除 “node1” 上所有 chunk 的副本。
chunkIds=exec chunkId from pnodeRun(getChunksMeta) where node="node1"
deleteReplicas(chunkIds,"node1");
FILE:references/doc_1043.md
# rowAt
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowAt.html
**来源**: DolphinDB 官方文档
---
rowAt
语法
rowAt(X, [Y])
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行取出
X
中对应索引的元素。
若
Y
是整型向量,
Y
的每个元素表示
X
每行的列索引,逐行取出
X
中对应索引的元素,返回一个与
Y
长度相同的向量。若索引无对应元素或索引超出
X
的有效索引范围,则返回空值。
若
Y
是布尔类型的矩阵或数组向量(或列式元组),则取出
X
对应于
Y
中 true 值的元素,返回一个与
Y
行数相同的数组向量。若
Y
中某一行的所有元素值都是
false,则该行返回空值。其中,当 Y 是布尔类型矩阵时,X 只能是矩阵。
若
Y
是整型数组向量(或列式元组),
Y
的每个元素表示
X
每行的列索引,逐行取出
X
中对应索引的元素,返回一个与
Y
维度相同的数组向量(或列式元组)。若索引无对应元素或索引超出
X
的有效索引范围,则返回空值。
若
Y
不指定,
X
必须是布尔类型的矩阵或数组向量(或列式元组)。该函数逐行取出
X
中元素值是 true 的索引。返回一个整型数组向量(或列式元组),其行数和
X
的行数相同。若
X
中某一行的所有元素值都是空值或 false,则该行返回空值。
参数
X
矩阵
、数组向量或列式元组
。
Y
整型向量、布尔型矩阵、整型或布尔型数组向量或列式元组
。
返回值
返回一个与
Y
长度相同的向量。若索引无对应元素或索引超出
X
的有效索引范围,则返回空值。
例子
m = matrix(3.1 4.5 2.2, 4.2 4.3 5.1, 6.2 7.1 2.2, 1.8 6.1 5.3, 7.1 8.4 3.5)
index = 4 0 2
rowAt(m, index)
// output
[7.1,4.5,2.2]
trades = table(10:0,`time`sym`p1`p2`p3`p4`p5`vol1`vol2`vol3`vol4`vol5,[TIMESTAMP,SYMBOL,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,INT,INT,INT,INT,INT])
insert into trades values(2022.01.01T09:00:00, `A, 33.2, 33.8, 33.6, 33.3, 33.1, 200, 180, 180, 220, 200)
insert into trades values(2022.01.01T09:00:00, `A, 33.1, 32.8, 33.2, 34.3, 32.3, 150, 280, 190, 100, 220)
insert into trades values(2022.01.01T09:00:00, `A, 31.2, 32.6, 33.6, 35.3, 34.5, 220, 160, 130, 100, 110)
insert into trades values(2022.01.01T09:00:00, `A, 30.2, 32.5, 33.6, 35.3, 34.1, 200, 180, 150, 140, 120)
insert into trades values(2022.01.01T09:00:00, `A, 33.2, 33.8, 33.6, 33.3, 33.1, 180, 160, 160, 180, 200)
select rowAt(matrix(p1, p2, p3, p4, p5), rowImin(vol1, vol2, vol3, vol4, vol5)) as price1, rowAt(matrix(p1, p2, p3, p4, p5), rowImax(vol1, vol2, vol3, vol4, vol5)) as price2 from trades
表
1
.
查询返回
price1
price2
33.8
33.3
34.3
32.8
35.3
31.2
34.1
30.2
33.8
33.1
index = array(INT[], 0, 10).append!([0 1, 2 4, 3 4 5])
rowAt(m, index)
// output
[[3.1,4.2],[7.1,8.4],[5.3,3.5,]]
x = array(DOUBLE[], 0, 10).append!([3.3 3.6 3.8, 3.7 3.4 3.5, 3.4 3.4 3.5])
index = array(INT[], 0, 10).append!([0 1, 2, 0 2])
rowAt(x, index)
// output
[[3.3,3.6],[3.5],[3.4,3.5]]
2.00.10.2 及以上版本,当
X
是布尔类型矩阵或数组向量时,
Y
可以不指定,此时
rowAt
返回每行中 true 元素的索引。
m = matrix(true false false, false true false, true true false)
R=rowAt(m)
R
// output
[[0,2],[1,2],]
typestr(R)
// output
FAST INT[] VECTOR
m = matrix(3.1 4.5 2.2, 2.2 4.3 5.1, 1.2 7.1 2.2, 1.8 6.1 5.3, 1 4 3)
rowAt(m, m>4)
// output
[,[4.5,4.3,7.1,6.1],[5.1,5.3]]
x = array(DOUBLE[], 0, 10).append!([3.3 3.6 3.8, 3.7 3.4 3.5, 3.4 3.4 3.5])
rowAt(x, x>3.5)
// output
[[3.6,3.8],[3.7],]
对列式元组与数组向量应用
rowAt
:
x = ([1, 2, 3], [4, 5, 6]).setColumnarTuple!()
y = fixedLengthArrayVector([1, 4], [2, 5], [3, 6])
rowAt(x, x > 1)
// output
([2,3],[4,5,6])
rowAt(y, y>1)
// output
[[2,3],[4,5,6]]
FILE:references/doc_1046.md
# hex
**URL**: https://docs.dolphindb.cn/zh/funcs/h/hex.html
**来源**: DolphinDB 官方文档
---
hex
语法
hex(X, [reverse=false])
详情
把如下数据类型转换为十六进制数据显示:
INTEGRAL
FLOAT
COMPLEX
BINARY
参数
X
是一个整型标量或向量。
reverse
是一个布尔值,表示高低位是否互换。默认值是 false。
返回值
STRING 类型的标量或向量,表示数据对应的十六进制数。
例子
hex(16 25);
//output: ["00000010","00000019"]
hex(16 25,true);
//output: ["10000000","19000000"]
hex(compress(1 2 3));
//output: ["00","05","ff","01","04","04","00","00","ff","ff","ff","ff","03","00","00","00","ff","ff","ff","ff","0d","00","00","80","c0","01","00","00","00","02","00","00","00","03","00","00","00"]
a = hex(123.456 3.1415926)
print a
//output: ["405edd2f1a9fbe77","400921fb4d12d84a"]
FILE:references/doc_1048.md
# regexReplace
**URL**: https://docs.dolphindb.cn/zh/funcs/r/regexReplace.html
**来源**: DolphinDB 官方文档
---
regexReplace
语法
regexReplace(str, pattern, replacement,
[offset])
详情
从
str
的第
offset
个位置开始搜索与
pattern
匹配的字符串,如果找到匹配字符串,则把匹配字符串替换成
replacement
,然后返回替换后的字符串。
参数
str
是一个字符串或字符串向量。
pattern
是一个字符串,表示搜索的模式字符串(
正则表达式
)。模式字符串可以包含字面量字符、元字符或两者的组合。
replacement
是字符串标量,表示替换的字符串。
offset
是一个非负整数,默认值为0。它是一个可选参数,表示从
str
的第
offset
个位置开始搜索。
str
的第一个位置为0。
返回值
STRING 类型标量或向量。
例子
regexReplace("abc234 ff456", "[a-z]", "z");
// output
zzz234 zz456
regexReplace("abc234 ff456", "[a-z]+", "zzz");
// output
zzz234 zzz456
regexReplace("abc234 ff456", "[0-9]+", "zzz");
// output
abczzz ffzzz
FILE:references/doc_1052.md
# upper
**URL**: https://docs.dolphindb.cn/zh/funcs/u/upper.html
**来源**: DolphinDB 官方文档
---
upper
语法
upper(X)
详情
upper
函数把字符串或字符串列表中的所有字符转换为大写。
参数
X
是一个字符串标量或向量。
返回值
字符串标量或向量。
例子
x = `Ibm`C`AapL;
x.upper();
// output: ["IBM","C","AAPL"]
(`Thl).upper();
// output: THL
相关函数:
lower
FILE:references/doc_1062.md
# clearAllCache
**URL**: https://docs.dolphindb.cn/zh/funcs/c/clearAllCache.html
**来源**: DolphinDB 官方文档
---
clearAllCache
语法
clearAllCache()
详情
清除以下缓存数据:
维度表在内存中的缓存
OLAP 引擎分区表中已经载入内存的数据
TSDB 引擎的 Level File 索引的缓存
TSDB 引擎中 SYMBOL 类型的字典编码的缓存
分布式计算中 map-reduce 任务的中间结果
参数
无。
返回值
无。
例子
clearAllCache();
FILE:references/doc_1063.md
# Web 操作手册
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db_man/web/intro.html
**来源**: DolphinDB 官方文档
---
Web 操作手册
用户可以在集群管理器的 Web 界面对同一集群中的代理节点、数据节点和计算节点进行管理。
图
1
.
控制节点下的 Web 集群管理器
注:
使用 Web 集群管理器前,请确保浏览器版本满足以下要求:
Chrome/Firefox/Edge 浏览器:版本高于 100
Safari 浏览器:版本高于 16
FILE:references/doc_1069.md
# percentChange
**URL**: https://docs.dolphindb.cn/zh/funcs/p/percentChange.html
**来源**: DolphinDB 官方文档
---
percentChange
语法
percentChange(X,[n])
详情
计算两个元素之间的值变化比例。即,对于
X
中的每一个元素,计算 (X
i
/ X
i-n
) - 1。
若
X
是矩阵,在每列内进行上述计算,返回一个与
X
维度相同的矩阵。
参数
X
是一个向量或矩阵。
n 为可选参数,整型,用于指定计算 X 中两个元素值变化百分比时的元素间隔数,默认值为 1。
在不指定 n 值时,percentChange 计算相邻元素值的变化百分比;
当 n 为大于 1 的整数时,例如,当 X = 3 4 6 9,n = 2 时,计算 X 中 6 和 3 之间、9 和 4
之间的值变化百分比,得到的结果为:[,,1,1.25],即 100% 和 125%。
当 n 为负整数时,例如, X = 3 4 6 9,n = -2 时,计算 X 中 3 和 6 之间、4 和 9
之间的值变化百分比,得到的结果为:[-0.5, -0.5555555555555556,,]。
返回值
DOUBLE 类型向量或矩阵。
例子
percentChange([1,2,3]);
//output: [,1,0.5]
percentChange(85 90 95);
//output:[,0.058824,0.055556]
m=matrix(100 105 109 112 108 116, 200 212 208 199 206 210);
m
返回:
#0
#1
100
200
105
212
109
208
112
199
108
206
116
210
percentChange(m);
返回:
#0
#1
0.05
0.06
0.038095238095238
-0.018867924528302
0.027522935779817
-0.043269230769231
-0.035714285714286
0.035175879396985
0.074074074074074
0.019417475728155
以下例子中,X 是一个从 1 到 10 递增的向量。n = 3,即 1 和 4 比较,2 和 5 比较, 3 和 6 比较,以此类推。
X = 1..10;
n = 3;
r = percentChange(X,n);
print r;
//output: [,,,3,1.5,1,0.75,0.6,0.5,0.428571428571429]
以下例子中,X 是一个矩阵。
m=matrix(1 3 2 NULL 6 9 3, 0 8 NULL 7 6 2 8);
n = 3;
result = percentChange(m,n);
result;
返回:
0
1
1
-0.25
3.5
0.14285714285714285
当 n 为负整数时,
x = 3 4 6 9
n = -2
r2= percentChange(x,n)
r2
返回:
0
1
2
3
-0.5
-0.5555555555555556
FILE:references/doc_1081.md
# mfirst
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mfirst.html
**来源**: DolphinDB 官方文档
---
mfirst
语法
mfirst(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
的第一个元素。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
当
X
是向量时,返回一个向量。
当
X
是矩阵时,返回一个矩阵。
当
X
是表时,对表的每列进行计算,返回相应的结果。
当
X
是元组时,对元组中的每个向量分别计算,返回相应的结果。
例子
index = second(08:20:00)+1..7
x = 2 1 3 NULL 6 5 4
x = index.indexedSeries(x)
mfirst(x,3s)
label
col1
08:20:01
2
08:20:02
2
08:20:03
2
08:20:04
1
08:20:05
3
08:20:06
08:20:07
6
m = matrix(1 5 9 0 2, 9 10 2 NULL 2)
m.rename!((date(2020.09.08)+1..3) join 2020.09.16 join 2020.09.26, `A`B)
m.setIndexedMatrix!()
mfirst(m, 3d)
label
A
B
2020.09.09
1
9
2020.09.10
1
9
2020.09.11
1
9
2020.09.16
0
2020.09.26
2
2
mfirst(m, 1w)
label
A
B
2020.09.09
1
9
2020.09.10
1
9
2020.09.11
1
9
2020.09.16
5
10
2020.09.26
2
2
相关函数:
first
,
last
FILE:references/doc_1083.md
# getRecentSlaveReplicationInfo
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getRecentSlaveReplicationInfo.html
**来源**: DolphinDB 官方文档
---
getRecentSlaveReplicationInfo
语法
getRecentSlaveReplicationInfo()
详情
查看跨集群异步复制进程中,连接到主集群的各从集群最近一次的任务状态。该函数只能由管理员在主集群的控制节点调用。
参数
无
返回值
返回一个表对象,包含以下字段:
connectedController:从集群的 controller 的 ip:port。
allControllersInRaft:若从集群为高可用集群,则将显示 raft 组所有控制节点的 ip:port。
lastFinishedTaskId:最近一次执行完成的异步复制任务 id。
lastPullTime:从集群最近一次连接到主集群拉取异步复制任务的时间。
例子
getRecentSlaveReplicationInfo()
输出返回:
connectedController
allControllersInRaft
lastFinishedTaskId
lastPullTime
192.168.2.2:1111
192.168.2.2:1111,192.168.2.2:1112,192.168.2.2:1113
233
2022.11.11T11:11:11
FILE:references/doc_109.md
# cumstd
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumstd.html
**来源**: DolphinDB 官方文档
---
cumstd
语法
cumstd(X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累计标准差。
返回值
DOUBLE 类型,其数据形式同
X
。
例子
x = [1,2,4,NULL,8];
cumstd(x);
// output
[,0.707107,1.527525,1.527525,3.095696]
m=matrix(0.15 0.08 0.03 -0.14 -0.09, 0.2 -0.12 -0.16 0.08 0.16);
m;
#0
#1
0.15
0.2
0.08
-0.12
0.03
-0.16
-0.14
0.08
-0.09
0.16
cumstd(m);
#0
#1
0.049497474683058
0.226274169979695
0.060277137733417
0.19731531449265
0.123558353285671
0.169705627484771
0.119707978013163
0.16346253393362
相关函数:
std
FILE:references/doc_1096.md
# 响应式状态引擎
**URL**: https://docs.dolphindb.cn/zh/stream/reactive_state_engine.html
**来源**: DolphinDB 官方文档
---
响应式状态引擎
DolphinDB 的响应式状态引擎每输入一条数据引擎都将触发一条结果输出,且针对生产业务中的常见状态函数(滑动窗口函数、累积函数、序列相关函数和 topN
相关函数等)进行特殊优化,大幅提升了这些函数在响应式状态引擎中的计算效率。响应式状态引擎目前仅支持系统优化过的状态函数。如果 DolphinDB
用户需要使用自定义函数封装复杂的状态函数,可以用 @state
进行声明。响应式状态引擎应用广泛,例如金融场景下计算有状态的高频因子、主买成交量占比,以及大小单资金流等;物联网场景下检测传感器数据流中的温度是否在持续上升等。
金融高频因子计算示例
本节通过一个金融高频因子计算的示例,介绍高频因子计算中的挑战。以下的因子表达式以 DolphinDB
脚本语言编写,使用了用户自定义函数
sum\_diff
和内置函数
ema
(exponential moving
average)。
sum_diff
是一个无状态函数,
ema
是一个有状态的函数,依赖历史数据。更为棘手的是,如以下计算分解图所示,需要使用
ema
函数的多重嵌套。
def
sum_diff(x, y){
return
(x-y)/(x+y)
}
ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
10
) - ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
20
)
面对此类场景,我们需要解决以下几个问题:
投研阶段能否使用历史数据快速为每只股票计算 100~1000 个类似的因子?
实盘阶段能否在每个行情tick数据到来时为每只股票计算 100~1000 个类似的因子?
批处理和流计算的代码实现是否高效?批和流能否统一代码?正确性校验是否便捷?
现有解决方案的优缺点
Python pandas/numpy 目前是研究阶段最常用的高频因子解决方案。pandas
对历史面板数据处理有非常成熟的解决方案,而且内置了大部分高频因子计算需要用到的算子,可快速开发高频因子。但 pandas
无论对历史数据计算,还是对实时数据计算的性能都较差。对历史数据计算时,单线程的计算性能也存在较大提升空间,此外,由于 python 的 Global
interpreter lock 的限制,无法进行并行计算;对实时数据进行计算时,由于 python
仅支持全量计算,不支持增量计算,所以无法达到实时计算的性能要求。
为生产环境中的性能考虑,很多机构会用 C++
重新实现研究(历史数据)代码。不过,这种方法需要维护两套代码,开发成本(时间和人力)会大幅增加。此外,还要耗费大量精力确保两套系统的结果完全一致。
Flink 是一种批流统一的解决方案。Flink 支持 SQL 和窗口函数,高频因子用到的基本算子在 Flink 中已经内置实现。因此,简单的因子用 Flink
实现比较高效,运行性能也较好。但 Flink 最大的问题是无法实现复杂的高频因子计算。如前一章中提到的例子,需要多个窗口函数的嵌套,无法直接用 Flink
实现。这也正是 DolphinDB 开发响应式状态引擎的动机所在。
响应式状态引擎(Reactive State Engine)
响应式状态引擎(Reactive State Engine)实际上是一个计算黑盒,输入在历史数据上已经验证的 DolphinDB
因子代码(表达式或函数)以及实时行情数据,输出实时因子值。由于在静态的历史数据集上开发和验证高频因子远比在流数据上开发更为简单,响应式状态引擎显著降低了流式高频因子的开发成本和难度。
def
sum_diff(x, y){
return
(x-y)/(x+y)
}
factor1 = <ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
10
) - ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
20
)>
share streamTable(
1
:
0
, `sym`price, [STRING,DOUBLE])
as
tickStream
result = table(
1000
:
0
, `sym`factor1, [STRING,DOUBLE])
rse = createReactiveStateEngine(name=
"reactiveDemo"
, metrics=factor1, dummyTable=tickStream, outputTable=result, keyColumn=
"sym"
)
subscribeTable(tableName=`tickStream, actionName=
"factors"
, handler=tableInsert{rse})
以上代码在 DolphinDB 中实现前述因子的流式计算。factor1 是前述因子在历史数据上的实现,不做任何改变,直接传递给响应式状态引擎
rse,即可实现流式计算。通过订阅函数
subscribeTable
,将流数据表
tickStream
与状态引擎
rse 进行关联。每一批次实时数据的注入,都会触发状态引擎的计算,并输出因子值到结果表
result
。以下代码产生随机数据,并注入到流数据表。结果与通过
SQL 语句计算的结果完全相同。
data = table(take(
"A"
,
100
)
as
sym, rand(
10.0
,
100
)
as
price)
tickStream.append!(data)
factor1Hist = select sym, ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
10
) - ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
20
)
as
factor1
from
data context by sym
assert
each(eqObj, result.values(), factor1Hist.values())
工作原理
如上图所示,一个有状态的高频因子计算过程可以分解成有一个有向无环图(DAG)。图中的节点有3种:数据源(如 price)、有状态的算子(如 a, b, d,
e)、无状态的算子(如 c 和 result)。从数据源节点开始,按照既定的路径,层层推进,得到最后的因子输出。这非常类似 excel
中的单元格链式计算。当一个单元格的数据发生变化时,相关联的单元格依次发生变化。响应式状态引擎的名称也是从这一点引申出来的。
无状态的算子比较简单,使用 DolphinDB 已有的脚本引擎,就可以表示和计算。因此,问题转化为两点:(1)如何解析得到一个优化的
DAG,(2)如何优化每个有状态的算子的计算。
解析和优化
DolphinDB 的脚本语言是支持向量化和函数化的多范式编程语言。通过函数的调用关系,不难得到计算步骤的 DAG。在解析的时候,因为输入消息的 schema
是已知的,我们可以快速推断出每一个节点的输入数据类型和输出数据类型。输入参数类型确定,函数名称确定,每个状态算子的具体实例就可以创建出来。
每一个算子(有状态和无状态)在 DolphinDB 中都可以转化为一个唯一的字符串序列。据此,我们可以删除重复的算子,提高计算效率。
内置状态函数
状态算子计算时需要用到历史状态。如果每一次计算都使用全量数据,性能不佳。状态函数的优化,也就是增量方式的流式实现非常关键。下列状态函数在 DolphinDB
的响应式状态引擎中的实现均得到了优化。目前,状态引擎不允许使用未经优化的状态函数,且需避免使用聚合函数。
累计窗口函数:
cumavg
,
cumsum
,
cumprod
,
cumcount
,
cummin
,
cummax
,
cumvar
,
cumvarp
,
cumstd
,
cumstdp
,
cumcorr
,
cumcovar
,
cumbeta
,
cumwsum
,
cumwavg
,
cumfirstNot
,
cumlastNot
,
cummed
,
cumpercentile
,
cumnunique
,
cumPositiveStreak
,
cummdd
滑动窗口函数:
ema
,
mavg
,
msum
,
mcount
,
mprod
,
mvar
,
mvarp
,
mstd
,
mstdp
,
mskew
,
mkurtosis
,
mmin
,
mmax
,
mimin
,
mimax
,
mmed
,
mpercentile
,
mrank
,
mcorr
,
mcovar
,
mbeta
,
mwsum
,
mwavg
,
mmad
,
mfirst
,
mlast
,
mslr
,
tmove
,
tmfirst
,
tmlast
,
tmsum
,
tmsum2
,
tmavg
,
tmcount
,
tmvar
,
tmvarp
,
tmstd
,
tmstdp
,
tmprod
,
tmskew
,
tmkurtosis
,
tmmin
,
tmmax
,
tmmed
,
tmpercentile
,
tmrank
,
tmcovar
,
tmbeta
,
tmcorr
,
tmwavg
,
tmwsum
,
tmoving
,
moving
,
sma
,
wma
,
dema
,
tema
,
trima
,
linearTimeTrend
,
talib
,
t3
,
ma
,
gema
,
wilder
,
mmaxPositiveStreak
,
movingWindowData
,
tmovingWindowData
序列相关函数:
deltas
,
ratios
,
ffill
,
move
,
prev
,
iterate
,
ewmMean
,
ewmVar
,
ewmStd
,
ewmCov
,
ewmCorr
,
prevState
,
percentChange
topN相关函数:
msumTopN
,
mavgTopN
,
mstdpTopN
,
mstdTopN
,
mvarpTopN
,
mvarTopN
,
mcorrTopN
,
mbetaTopN
,
mcovarTopN
,
mwsumTopN
,
cumsumTopN
,
cumwsumTopN
,
cumvarTopN
,
cumvarpTopN
,
cumstdTopN
,
cumstdpTopN
,
cumcorrTopN
,
cumbetaTopN
,
cumavgTopN
,
cumskewTopN
,
cumkurtosisTopN
,
mskewTopN
,
mkurtosisTopN
,
tmsumTopN
,
tmavgTopN
,
tmstdTopN
,
tmstdpTopN
,
tmvarTopN
,
tmvarpTopN
,
tmskewTopN
,
tmkurtosisTopN
,
tmbetaTopN
,
tmcorrTopN
,
tmcovarTopN
,
tmwsumTopN
高阶函数:
segmentby
(参数
func
暂支持 cumsum, cummax, cummin, cumcount,
cumavg, cumstd, cumvar, cumstdp, cumvarp),
moving
,
byColumn
,
accumulate
,
window
其他函数:
talibNull
,
dynamicGroupCumsum
,
dynamicGroupCumcount
,
topRange
,
lowRange
,
trueRange
,
sumbars
特殊函数(仅支持在引擎内使用):
stateIterate
,
conditionalIterate
,
genericStateIterate
,
genericTStateIterate
注:
talib
作为状态函数时,第一个参数
func
只能是响应式状态引擎支持的状态函数。
自定义状态函数
响应式状态引擎中可使用自定义状态函数。需要注意以下几点:
需在定义前添加声明 "@state"。状态函数只能包含赋值语句和 return 语句。
自
2.00.9
版本起,支持使用 if-else
条件语句,且条件只能是标量。
自
2.00.11
版本起,支持使用 for 循环(包含 break, continue
语句),请注意不支持嵌套 for 循环,且循环次数须小于 100 次。
状态引擎中可以使用无状态函数或者状态函数。但不允许在无状态函数中嵌套使用状态函数。
若赋值语句的右值是一个多返回值的函数(内置函数或自定义函数),则需要将多个返回值同时赋予多个变量。例如:两个返回值的函数 linearTimeTrend
应用于自定义状态函数中,正确写法为:
@state
def forcast2(S, N){
linearregIntercept, linearregSlope = linearTimeTrend(S, N)
return (N - 1) * linearregSlope + linearregIntercept
}
如果仅允许使用一个表达式来表示一个因子,会带来很多局限性。首先,在某些情况下,仅使用表达式无法实现一个完整的因子。下面的例子返回线性回归的 alpha,beta
和 residual。
@state
def
slr(y, x){
alpha, beta = mslr(y, x,
12
)
residual = mavg(y,
12
) - beta * mavg(x,
12
) - alpha
return
alpha, beta, residual
}
其次,很多因子可能会使用共同的中间结果,定义多个因子时,代码会更简洁。自定义函数可以同时返回多个结果。下面的函数
multiFactors
定义了 5 个因子。
@state
def
multiFactors(lowPrice, highPrice, volumeTrade, closePrice, buy_active, sell_active, tradePrice, askPrice1, bidPrice1, askPrice10, agg_vol, agg_amt){
a = ema(askPrice10,
30
)
term0 = ema((lowPrice - a) / (ema(highPrice,
30
) - a),
50
)
term1 = mrank((highPrice - a) / (ema(highPrice,
5
) - a), true,
15
)
term2 = mcorr(askPrice10, volumeTrade,
10
) * mrank(mstd(closePrice,
20
,
20
), true,
10
)
buy_vol_ma = mavg(buy_active,
6
)
sell_vol_ma = mavg(sell_active,
6
)
zero_free_vol = iif(agg_vol==
0
,
1
, agg_vol)
stl_prc = ffill(agg_amt \ zero_free_vol \
20
).nullFill(tradePrice)
buy_prop = stl_prc
spd = askPrice1 - bidPrice1
spd_ma = round(mavg(iif(spd <
0
,
0
, spd),
6
),
5
)
term3 = buy_prop * spd_ma
term4 = iif(spd_ma ==
0
,
0
, buy_prop / spd_ma)
return
term0, term1, term2, term3, term4
}
最后,某些表达式冗长,缺乏可读性。第一节中的因子表达式改为下面的自定义状态函数
factor1
后,计算逻辑简洁明了。
@state
def
factor1(price) {
a = ema(price,
20
)
b = ema(price,
40
)
c =
1000
* sum_diff(a, b)
return
ema(c,
10
) - ema(c,
20
)
}
输出结果过滤
状态引擎会对输入的每一条消息做出计算响应,产生一条记录作为结果。计算的结果在默认情况下都会输出到结果表,也就是说输入 n 个消息,输出 n
条记录。如果希望仅输出一部分结果,可以启用过滤条件,只有满足条件的结果才会输出。
下面的例子检查股票价格是否有变化,只有价格变化的记录才会输出。
share streamTable(
1
:
0
, `sym`price, [STRING,DOUBLE])
as
tickStream
result = table(
1000
:
0
, `sym`price, [STRING,DOUBLE])
rse = createReactiveStateEngine(name=
"reactiveFilter"
, metrics =[<price>], dummyTable=tickStream, outputTable=result, keyColumn=
"sym"
, filter=<prev(price) != price>)
subscribeTable(tableName=`tickStream, actionName=
"filter"
, handler=tableInsert{rse})
快照机制
为了满足生产环境业务持续性的需要,DolphinDB 内置的流式计算引擎包括响应式状态引擎均支持快照(snapshot)输出。
响应式状态引擎的快照包括已处理的最后一条消息的 ID
以及引擎当前的状态(中间计算结果)。当系统出现异常,重新初始化状态引擎时,可恢复到最后一个快照的状态,并且从已处理的消息的下一条开始订阅。
def
sum_diff(x, y){
return
(x-y)/(x+y)
}
factor1 = <ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
10
) - ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
20
)>
share streamTable(
1
:
0
, `sym`price, [STRING,DOUBLE])
as
tickStream
result = table(
1000
:
0
, `sym`factor1, [STRING,DOUBLE])
rse = createReactiveStateEngine(name=
"reactiveDemo"
, metrics =factor1, dummyTable=tickStream, outputTable=result, keyColumn=
"sym"
, snapshotDir=
"/home/data/snapshot"
, snapshotIntervalInMsgCount=
400000
)
msgId = getSnapshotMsgId(rse)
if
(msgId >=
0
) msgId +=
1
subscribeTable(tableName=`tickStream, actionName=
"factors"
, offset=msgId, handler=appendMsg{rse}, handlerNeedMsgId=true)
响应式状态引擎要启用快照机制,创建时需要指定两个额外的参数:
snapshotDir
:用于指定存储快照的目录。
snapshotIntervalInMsgCount
。用于指定处理多少条消息后产生一个快照。
引擎初始化时,系统会检查快照目录下是否存在一个以引擎名称命名,后缀为 snapshot 的文件。以上面的代码为例,如果存在文件
/home/data/snapshot/reactiveDemo.snapshot,则加载这个快照。函数
getSnapshotMsgId
可以获取最近一个快照对应的 msgId。如果不存在快照,返回 -1。
状态引擎要启用快照机制,调用
subscribeTable
函数也需相应的修改:
首先必须指定消息的 offset。
其次,
handler
必须使用
appendMsg
函数。
appendMsg
函数接受两个参数,
msgBody
和
msgId
。
再次,参数
handlerNeedMsgId
必须指定为 true。
并行处理
当需要处理大量消息时,可在 DolphinDB 消息订阅函数
subscribeTable
中指定可选参数
filter
与
hash
,让多个订阅客户端并行处理消息。
参数
filter
用于指定消息过滤逻辑。目前支持三种过滤方式,分别为值过滤,范围过滤和哈希过滤。
参数
hash
可以指定一个哈希值,确定这个订阅由哪个线程来执行。例如,配置参数
subExecutors
为
4,用户指定了哈希值 5,那么该订阅的计算任务将由第二个线程来执行。
下面是响应式状态引擎并行计算因子的例子。假设配置参数
subExecutors
= 4,创建 4
个状态引擎,每个状态引擎根据流数据表的股票代码的哈希值来订阅不同股票的数据,并且指定不同的订阅线程来处理,最终将结果输出到同一个输出表中。
def
sum_diff(x, y){
return
(x-y)/(x+y)
}
factor1 = <ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
10
) - ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
20
)>
share streamTable(
1
:
0
, `sym`price, [STRING,DOUBLE])
as
tickStream
setStreamTableFilterColumn(tickStream, `sym)
share streamTable(
1000
:
0
, `sym`factor1, [STRING,DOUBLE])
as
resultStream
for
(i
in
0.
.3
){
rse = createReactiveStateEngine(name=
"reactiveDemo"
+string(i), metrics =factor1, dummyTable=tickStream, outputTable=resultStream, keyColumn=
"sym"
)
subscribeTable(tableName=`tickStream, actionName=
"sub"
+string(i), handler=tableInsert{rse}, msgAsTable = true, hash = i, filter = (
4
,i))
}
n=
2000000
tmp = table(take(
"A"
+string(
1.
.4000
), n)
as
sym, rand(
10.0
, n)
as
price)
tickStream.append!(tmp)
重要:
如果多个状态引擎使用同一个输出表,则该输出表必须是一个共享表。没有共享的表不是线程安全的,并行写入可能会导致系统崩溃。
流批统一解决方案
金融高频因子的流批统一处理在 DolphinDB 中有两种实现方法。
第一种方法,使用函数或表达式实现金融高频因子,代入不同的计算引擎进行历史数据或流数据的计算。代入 SQL
引擎,可以实现对历史数据的计算;代入响应式状态引擎,可以实现对流数据的计算。这在第3章的序言部分已经举例说明。在这种模式下用 DolphinDB
脚本语言表示的表达式或函数实际上是对因子语义的一种描述,而不是具体的实现。因子计算的具体实现交由相应的计算引擎来完成,从而实现不同场景下的最佳性能。
第二种方法,历史数据通过回放,转变成流数据,然后使用流数据计算引擎来完成计算。我们仍然以教程开始部分的因子为例,唯一的区别是流数据表
tickStream
的数据源来自于历史数据库的
replay。使用这种方法计算历史数据的因子值,效率不高是一个缺点。
def
sum_diff(x, y){
return
(x-y)/(x+y)
}
factor1 = <ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
10
) - ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
20
)>
share streamTable(
1
:
0
, `sym`date`time`price, [STRING,DATE,TIME,DOUBLE])
as
tickStream
result = table(
1000
:
0
, `sym`factor1, [STRING,DOUBLE])
rse = createReactiveStateEngine(name=
"reactiveDemo"
, metrics =factor1, dummyTable=tickStream, outputTable=result, keyColumn=
"sym"
)
subscribeTable(tableName=`tickStream, actionName=
"factors"
, handler=tableInsert{rse})
//从历史数据库dfs://TAQ的trades表中加载一天的数据,回放到流数据表 tickStream 中
inputDS = replayDS(<select sym, date, time, price
from
loadTable(
"dfs://TAQ"
,
"trades"
) where date=
2021.03
.
08
>, `date, `time,
08
:
00
:
00.000
+ (
1.
.10
) *
3600000
)
replay(inputDS, tickStream, `date, `time,
1000
, true,
2
)
性能测试
我们测试了响应式状态引擎计算因子的性能。测试使用模拟数据,并使用
warmupStreamEngine
函数模拟状态引擎已经处理部分数据的情况。测试共包括 20 个不同复杂度度的因子,其中两个自定义状态函数分别返回 3 个和 5
个因子。为方便测试,计算仅使用单线程处理。
@state
def
slr(y, x){
alpha, beta = mslr(y, x,
12
)
residual = mavg(y,
12
) - beta * mavg(x,
12
) - alpha
return
alpha, beta, residual
}
@state
def
multiFactors(lowPrice, highPrice, volumeTrade, closePrice, buy_active, sell_active, tradePrice, askPrice1, bidPrice1, askPrice10, agg_vol, agg_amt){
a = ema(askPrice10,
30
)
term0 = ema((lowPrice - a) / (ema(highPrice,
30
) - a),
50
)
term1 = mrank((highPrice - a) / (ema(highPrice,
5
) - a), true,
15
)
term2 = mcorr(askPrice10, volumeTrade,
10
) * mrank(mstd(closePrice,
20
,
20
), true,
10
)
buy_vol_ma = mavg(buy_active,
6
)
sell_vol_ma = mavg(sell_active,
6
)
zero_free_vol = iif(agg_vol==
0
,
1
, agg_vol)
stl_prc = ffill(agg_amt \ zero_free_vol \
20
).nullFill(tradePrice)
buy_prop = stl_prc
spd = askPrice1 - bidPrice1
spd_ma = round(mavg(iif(spd <
0
,
0
, spd),
6
),
5
)
term3 = buy_prop * spd_ma
term4 = iif(spd_ma ==
0
,
0
, buy_prop / spd_ma)
return
term0, term1, term2, term3, term4
}
metrics = array(ANY,
14
)
metrics[
0
] = <ema(
1000
* sum_diff(ema(close,
20
), ema(close,
40
)),
10
) - ema(
1000
* sum_diff(ema(close,
20
), ema(close,
40
)),
20
)>
metrics[
1
] = <mslr(high, volume,
8
)[
1
]>
metrics[
2
] = <mcorr(low, high,
11
)>
metrics[
3
] = <mstdp(low,
15
)>
metrics[
4
] = <mbeta(high, value,
63
)>
metrics[
5
] = <mcovar(low, value,
71
)>
metrics[
6
] = <(close/mavg(close,
1.
.6
)-
1
)*
100
>
metrics[
7
] = <mmin(high,
15
)>
metrics[
8
] = <mavg(((high+low)/
2
+(mavg(high,
2
)+mavg(low,
2
))/
2
)*(high-low)/volume,
7
,
2
)>
metrics[
9
] = <mslr(mavg(close,
14
), volume,
63
)[
1
]>
metrics[
10
] = <mcorr(mavg(open,
25
), volume,
71
)>
metrics[
11
] = <mbeta(high, mstdp(close,
8
),
77
)>
metrics[
12
] = <slr(close, volume)>
metrics[
13
] = <multiFactors(low, high, volume, close, numTrade, numTrade, close, value, close, open, volume, numTrade)>
dummy = streamTable(
10000
:
0
, `symbol`market`date`time`quote_type`preclose`open`high`low`close`numTrade`volume`value`position`recvtime,[SYMBOL,SHORT,DATE,TIME,SHORT,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,LONG,DOUBLE,LONG,TIMESTAMP])
def
prepareData(tickNum, batch){
total = tickNum*batch
data=table(total:total, `symbol`market`date`time`quote_type`preclose`open`high`low`close`numTrade`volume`value`position`recvtime,[SYMBOL,SHORT,DATE,TIME,SHORT,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,LONG,DOUBLE,LONG,TIMESTAMP])
data[`market]=rand(
10
, total)
data[`date]=take(date(now()), total)
data[`time]=take(time(now()), total)
data[`symbol]=take(
"A"
+string(
1.
.tickNum), total)
data[`open]=rand(
100.0
, total)
data[`high]=rand(
100.0
, total)
data[`low]=rand(
100.0
, total)
data[`close]=rand(
100.0
, total)
data[`numTrade]=rand(
100
, total)
data[`volume]=rand(
100
, total)
data[`value]=rand(
100.0
, total)
data[`recvtime]=take(now(), total)
return
data
}
dropStreamEngine(
"demo1"
)
dropStreamEngine(
"demo2"
)
dropStreamEngine(
"demo3"
)
dropStreamEngine(
"demo4"
)
//
4000
个股票,
20
个因子
hisData = prepareData(
4000
,
100
)
realData = prepareData(
4000
,
1
)
colNames = [
"symbol"
].append!(
"factor"
+string(
0.
.19
))
colTypes = [SYMBOL].append!(take(DOUBLE,
20
))
resultTable = streamTable(
10000
:
0
, colNames, colTypes)
engine1 = createReactiveStateEngine(name=
"demo1"
, metrics=metrics, dummyTable=dummy, outputTable=resultTable, keyColumn=
"symbol"
)
warmupStreamEngine(engine1, hisData)
timer(
10
) engine1.append!(realData)
dropStreamEngine(
"demo1"
)
//
1
个股票,
20
个因子
hisData = prepareData(
1
,
100
)
realData = prepareData(
1
,
1
)
colNames = [
"symbol"
].append!(
"factor"
+string(
0.
.19
))
colTypes = [SYMBOL].append!(take(DOUBLE,
20
))
resultTable = streamTable(
10000
:
0
, colNames, colTypes)
engine2 = createReactiveStateEngine(name=
"demo2"
, metrics=metrics, dummyTable=dummy, outputTable=resultTable, keyColumn=
"symbol"
)
warmupStreamEngine(engine2, hisData)
timer(
10
) engine2.append!(realData)
dropStreamEngine(
"demo2"
)
//
4000
个股票,
1
个因子
hisData = prepareData(
4000
,
100
)
realData = prepareData(
4000
,
1
)
metrics3 = metrics[
0
]
colNames = [
"symbol"
,
"factor0"
]
colTypes = [SYMBOL, DOUBLE]
resultTable = streamTable(
10000
:
0
, colNames, colTypes)
engine3 = createReactiveStateEngine(name=
"demo3"
, metrics=metrics3, dummyTable=dummy, outputTable=resultTable, keyColumn=
"symbol"
)
warmupStreamEngine(engine3, hisData)
timer(
10
) engine3.append!(realData)
//
200
个股票,
20
个因子
hisData = prepareData(
200
,
100
)
realData = prepareData(
200
,
1
)
colNames = [
"symbol"
].append!(
"factor"
+string(
0.
.19
))
colTypes = [SYMBOL].append!(take(DOUBLE,
20
))
resultTable = streamTable(
10000
:
0
, colNames, colTypes)
engine4 = createReactiveStateEngine(name=
"demo4"
, metrics=metrics, dummyTable=dummy, outputTable=resultTable, keyColumn=
"symbol"
)
warmupStreamEngine(engine4, hisData)
timer(
10
) engine4.append!(realData)
我们统计了 10 次的总耗时,取平均值作为单次的耗时。测试使用的服务器 CPU 为 Intel(R) Xeon(R) Silver 4216 CPU @
2.10GHz。单线程情况下,测试结果如下:
股票个数
因子个数
耗时(单位:ms)
4000
20
6
1
20
0.07
4000
1
0.8
200
20
0.2
多个引擎的流水线处理
DolphinDB
内置的流计算引擎包括响应式状态引擎,时间序列聚合引擎,横截面引擎和异常检测引擎。这些引擎均实现了数据表(table)的接口,因此多个引擎流水线处理变得异常简单,只要将后一个引擎作为前一个引擎的输出即可。引入流水线处理,可以解决更为复杂的因子计算问题。譬如,因子计算经常需要使用面板数据,完成时间序列和横截面两个维度的计算,只要把响应式状态引擎和横截面两个引擎串联处理即可完成。
下面的例子是 World Quant 101个 Alpha 因子中的 1 号因子公式的流数据实现。
rank
函数是一个横截面操作。
rank
的参数部分用响应式状态引擎实现。
rank
函数本身用横截面引擎实现。横截面引擎作为状态引擎的输出。
Alpha
#001公式:rank(Ts_ArgMax(SignedPower((returns<0?stddev(returns,20):close), 2), 5))-0.5
//创建横截面引擎,计算每个股票的 rank
dummy = table(
1
:
0
, `sym`time`maxIndex, [SYMBOL, TIMESTAMP, DOUBLE])
resultTable = streamTable(
10000
:
0
, `time`sym`factor1, [TIMESTAMP, SYMBOL, DOUBLE])
ccsRank = createCrossSectionalAggregator(name=
"alpha1CCS"
, metrics=<[sym, rank(maxIndex, percent=true) -
0.5
]>, dummyTable=dummy, outputTable=resultTable, keyColumn=`sym, triggeringPattern=
'keyCount'
, triggeringInterval=
3000
, useSystemTime=false, timeColumn=`time)
@state
def
wqAlpha1TS(close){
ret = ratios(close) -
1
v = iif(ret <
0
, mstd(ret,
20
), close)
return
mimax(signum(v)*v*v,
5
)
}
//创建响应式状态引擎,输出到前面的横截面引擎 ccsRank
input = table(
1
:
0
, `sym`time`close, [SYMBOL, TIMESTAMP, DOUBLE])
rse = createReactiveStateEngine(name=
"alpha1"
, metrics=<[time, wqAlpha1TS(close)]>, dummyTable=input, outputTable=ccsRank, keyColumn=
"sym"
)
流水线处理(也称为引擎多级级联)和多个流数据表的级联处理有很大的区别。两者可以完成相同的任务,但是效率上有很大的区别。后者涉及多个流数据表与多次订阅。前者实际上只有一次订阅,所有的计算均在一个线程中依次顺序完成,因而有更好的性能。
上面的例子是由用户来区分哪一部分是横截面操作,哪一部分是时间序列操作以实现多个引擎的流水线。在 1.30.16/2.00.4 及之后的版本中,新增函数
streamEngineParser
,支持将
metrics
自动分解成多个内置流计算引擎的流水线。在
streamEngineParser
中以行函数(
rowRank
,
rowSum
等)表示横截面操作的语义,以
rolling
函数表示时间序列操作,从而系统能够自动识别一个因子中的横截面操作和时间序列操作,进一步自动构建引擎流水线。因此,上述因子可以用
streamEngineParser
更简洁的实现,
metrics
几乎等同于因子的数学公式表达,而不需要考虑不同类型引擎的选择:
@state
def
wqAlpha1TS(close){
ret = ratios(close) -
1
v = iif(ret <
0
, mstd(ret,
20
), close)
return
mimax(signum(v)*v*v,
5
)
}
//构建计算因子
metrics=<[sym, rowRank(wqAlpha1TS(close), percent=true)-
0.5
]>
streamEngine=streamEngineParser(name=
"alpha1_parser"
, metrics=metrics, dummyTable=input, outputTable=resultTable, keyColumn=`sym, timeColumn=`time, triggeringPattern=
'keyCount'
, triggeringInterval=
3000
)
FILE:references/doc_1097.md
# getAllDBGranularity
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getAllDBGranularity.html
**来源**: DolphinDB 官方文档
---
getAllDBGranularity
语法
getAllDBGranularity()
详情
该函数只能在数据节点上执行,用于列出该节点上所有数据库的分区粒度。
参数
无
返回值
返回结果是一个字典,其中:
key:数据库的名称。
value:分区粒度,结果为 TABLE 或者 DATABASE。详细说明可参考
database
的参数
chunkGranularity
。
例子
getAllDBGranularity()
// output:
/valuedb->TABLE
FILE:references/doc_1102.md
# nullCompare
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/nullCompare.html
**来源**: DolphinDB 官方文档
---
nullCompare
语法
nullCompare(func, X, Y)
详情
返回一个布尔值,是表达式 “func(X,Y)” 的结果。涉及 NULL 值的计算结果均为 NULL。该函数不受配置项
nullAsMinValueForComparison 影响。
参数
func
是<, >, >=, <=运算符,或函数 between,
in。
X
和
Y
可以是标量、数据对、向量、矩阵或集合。当
X
和
Y
都是向量或矩阵时,它们的长度或维度必须相同。
注:
X
和
Y
暂不支持以下数据类型:STRING, SYMBOL, IPADDR, UUID,
BLOB 和I NT128。
返回值
一个布尔值。
例子
配置项
nullAsMinValueForComparison
= true 时,在比较运算中,NULL
元素取相应数据类型的最小值。若使用 nullCompare,则不受该配置影响,依然取 NULL 值。
NULL < 3
// output
true
nullCompare(<, NULL, 3)
// output
NULL
m1=matrix(1 2 NULL, NULL 8 4, 4 7 2 )
m2 = 1..9$3:3
m1>m2
col1
col2
col3
false
false
false
false
true
false
false
false
false
nullCompare(>,m1,m2)
col1
col2
col3
false
false
false
true
false
false
false
nullCompare(between, 4 5 NULL, 4:9)
// output
[1,1,]
FILE:references/doc_111.md
# ewmCorr
**URL**: https://docs.dolphindb.cn/zh/funcs/e/ewmCorr.html
**来源**: DolphinDB 官方文档
---
ewmCorr
语法
ewmCorr(X, [com], [span], [halfLife], [alpha], [minPeriods=0],
[adjust=true], [ignoreNA=false], [other], [bias=false])
详情
返回
X
和
other
的指数加权移动相关系数。该函数必须指定
com
,
span
,
halfLife
,
alpha
四个参数中的一个。
参数
X
是一个数值型向量、矩阵或表。若
X
是表,只对其内数值型和布尔型的列进行计算。
com
是一个大于等于0的数值型标量,表示质心。
span
是一个大于等于1的数值型标量,表示跨度。
halfLife
是一个大于0的数值型标量,表示半衰期。
alpha
是一个(0,1]之间的浮点数,表示平滑系数。
minPeriods
是一个整数,表示窗口中的最小观察数。默认值为0。
adjust
是一个布尔值,表示是否除以开始阶段的衰减调整因子。默认值为 true。
ignoreNA
是一个布尔值,表示计算权重时是否忽略NULL值。默认值为 false。
other
当
X
是向量时,
other
只能是一个与
X
长度相同的数值型向量;当
X
是矩阵时,
other
是一个长度与
X
行数相同的数值型向量,或维度与
X
相同的矩阵;当
X
是表时,
other
是一个长度与
X
行数相同的数值型向量,或维度与
X
相同的表。
bias
是一个布尔值,表示是否校正系统偏差。默认值为 false。
返回值
DOUBLE 类型,数据形式同
X
。
例子
a=[0,1,2,int(),4]
b=[2,4,3,6,5]
ewmCorr(X=a,other=b,com=0.5);
// output
[,1.0000,-0.0533,-0.0533,0.9146]
ewmCorr(X=a,other=b,com=0.5,ignoreNA=true);
// output
[,1.0000,-0.0533,-0.0533,0.8934]
n = 20
colNames = `time`sym`qty`price
colTypes = [TIME,SYMBOL,INT,DOUBLE]
t1 = table(n:0, colNames, colTypes)
insert into t1 values(09:30:00.001,`AAPL,100,56.5)
insert into t1 values(09:30:00.001,`AAPL,200,30.5)
insert into t1 values(09:30:00.001,`DELL,150,35.5)
insert into t1 values(09:30:00.001,`DELL,170,60.5)
insert into t1 values(09:30:00.001,`DELL,130,40.5)
b=[2,4,3,6,5]
ewmCorr(X=t1,other=b,com=0.5);
time
sym
qty
price
09:30:00.001
AAPL
09:30:00.001
AAPL
1.0000
-1.0000
09:30:00.001
DELL
1.0000
-0.8481
09:30:00.001
DELL
0.5536
0.8747
09:30:00.001
DELL
0.3064
0.7050
相关函数:
ewmCov
,
ewmMean
,
ewmStd
,
ewmVar
FILE:references/doc_1110.md
# getChunkPath
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getChunkPath.html
**来源**: DolphinDB 官方文档
---
getChunkPath
语法
getChunkPath(ds)
详情
返回指定数据源代表数据块的路径。
参数
ds
是一个或多个数据源。
返回值
字符串向量。
例子
if(existsDatabase("dfs://valuedb")){
dropDatabase("dfs://valuedb")
}
db=database("dfs://valuedb", VALUE, 1..10)
n=1000000
t=table(rand(1..10, n) as id, rand(100.0, n) as val)
pt=db.createPartitionedTable(t, `pt, `id).append!(t);
ds=sqlDS(<select * from pt where id in 1..3>)
getChunkPath(ds);
// output
["/valuedb/1/p","/valuedb/2/p","/valuedb/3/p"]
FILE:references/doc_1120.md
# yearBegin
**URL**: https://docs.dolphindb.cn/zh/funcs/y/yearBegin.html
**来源**: DolphinDB 官方文档
---
yearBegin
语法
yearBegin(X, [startingMonth=1], [offset],
[n=1])
详情
返回
X
所在的以
startingMonth
为起始月份的年份的第一天。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
年更新一次。注意,
offset
和
n
须同时指定,且只有当
n
>1时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP 类型的标量或向量。
startingMonth
是1到12之间的整数,表示一年的起始月份。默认值是1。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
一个 DATE 类型的标量或向量。
例子
yearBegin(2012.06.12, 10);
// output
2011.10.01
yearBegin(2012.06.12, 4);
// output
2012.04.01
yearBegin(2012.06.12);
// output
2012.01.01
yearBegin(2012.06.12, 1, 2009.04.03, 2);
// output
2011.01.01
date=2011.04.25+(1..10)*365
time = take(09:30:00, 10);
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
t1;
date
time
sym
qty
price
2012.04.24
09:30:00
MSFT
2200
49.6
2013.04.24
09:30:00
MSFT
1900
29.46
2014.04.24
09:30:00
MSFT
2100
29.52
2015.04.24
09:30:00
MSFT
3200
30.02
2016.04.23
09:30:00
MSFT
6800
174.97
2017.04.23
09:30:00
MSFT
5400
175.23
2018.04.23
09:30:00
MSFT
1300
50.76
2019.04.23
09:30:00
MSFT
2500
50.32
2020.04.22
09:30:00
MSFT
8800
51.29
2021.04.22
09:30:00
MSFT
4500
52.38
select avg(price),sum(qty) from t1 group by yearBegin(date, 10, 2010.10.01, 2);
yearBegin_date
avg_price
sum_qty
2010.10.01
49.6
2200
2012.10.01
29.49
4000
2014.10.01
102.495
10000
2016.10.01
112.995
6700
2018.10.01
50.805
11300
2020.10.01
52.38
4500
相关函数:
yearEnd
,
businessYearBegin
,
businessYearEnd
FILE:references/doc_1122.md
# at
**URL**: https://docs.dolphindb.cn/zh/funcs/a/at.html
**来源**: DolphinDB 官方文档
---
at
语法
at(X, [index])
详情
只指定一个参数 X:
如果 X 是布尔表达式或向量,函数返回
X
中结果为 true 的元素位置。
如果 X 是整型向量,则函数返回一个向量,该向量是根据 X
中每个位置的数值重复该位置的索引得到,其功能相当于
take(til(count(X)), X)
。例如
at(3 0 2)
结果为
[0,0,0,2,2]
。若某个位置的值为非正数,则跳过该位置。
指定两个参数:
如果
index
是布尔表达式,
at
函数返回
X
中
index
为 true 的位置的元素。
at
函数等价于中括号运算符 []。
比如,
X.at(X>3)
和
X[X>3]
相同。
如果
index
是向量,以向量中的值作为索引值,寻找
X
中该索引位置的值并返回。
若
X
是函数,
index
为元组,则
index
中每一个元素均作为
X
的参数使用。
如果
index
是数据对,如 a:b, 则表示索引范围为 [a,b),寻找
X
中该范围的值并返回。
如果
index
是数组向量,对于
index
中的每行元素都作为一个索引值,寻找
X
中对应该索引位置的元素,然后返回一个和
index
结构相同的数组向量。
注:
index
作为索引值或索引范围时,若其值不在 [0, size(
X
) - 1] 内,则超出 [0,
size(
X
) - 1] 的值所对应的位置返回空值。
若
X
是函数,
index
为元组,则 index 中每一个元素均作为 X 的参数适用。
参数
如果只指定了一个参数,
X
可以是布尔表达式/向量,或是整型向量。
如果指定了两个参数:
X
可以是一个标量、向量(常规向量/元组
/数组向量
)、矩阵、表、字典、数据对、函数。
index
可以是一个布尔表达式/布尔值、标量、向量(常规向量/元组
/数组向量
)、数据对。
返回值
如果只指定了一个参数,则返回一个向量;如果指定了两个参数,则返回向量、数组向量或矩阵
例子
x = 2 3 -1 0 1
at(x)
// output:[0,0,1,1,1,4]
x=5 7 0 4 2 3
at(x>3)
//output:[0, 1, 3]
// 在位置 0, 1 和 3,x>3 为 true
// 和 x>3 相比
x>3;
//output:[1, 1, 0, 1, 0, 0]
x[x>3]
//output:[5, 7, 4]
x at x>3
//output:[5, 7, 4]
x=5 7 0 0 0 3
at(x==0)
//output:[2, 3, 4]
x[x==0]
//output:[0, 0, 0]
shares=500 1000 1000 600 2000
prices=25.5 97.5 19.2 38.4 101.5
prices[shares>800]
//output:[97.5, 19.2, 101.5]
prices at shares>800
//output: [97.5, 19.2, 101.5]
m=(1..6).reshape(2:3)
m;
0
1
2
1
3
5
2
4
6
at(m>3)
//output:[3,4,5]
m[m>3] // 等价于 m at m>3
返回:
col1
col2
col3
5
4
6
注意区分
index
是向量和元组的两种不同场景:
m at [0,2] // 选择第 0 列和第 2 列
0
1
1
5
2
6
m at (0,2) // 查找特定行列的元素
//output: 5
m at 0:2 // 选择第 0 列和第 1 列
返回:
0
1
1
3
2
4
index
是数组向量的情况:
a = array(INT[], 0, 10).append!([0 2 3, 0 5, 0 8 8, 9 10])
b =[1, 2, 3]
at(b, a)
//output: [[1,3, ], [1, ], [1, , ], [ , ]]
at(a,a>3)
//output: [,[5],[8,8],[9,10]]
下例中,score 是一个简单元组,包含 2 个元素,60 和 70。第二行中,
at
函数使用
add
函数作为
X
,将 score 中的每个元素作为
add
的入参,并将
at
的计算结果赋予 result。
score = (60, 70);
result = at(add,score)
print result
//output: 130
FILE:references/doc_1134.md
# semiMonthEnd
**URL**: https://docs.dolphindb.cn/zh/funcs/s/semiMonthEnd.html
**来源**: DolphinDB 官方文档
---
semiMonthEnd
语法
semiMonthEnd(X, [dayOfMonth=15], [offset],
[n=1])
详情
返回
X
所在半月的最后一天。假设
X
为该月的第 d 天:
如果d<
dayOfMonth
,那么
semiMonthBegin
返回
X
所在月份的上一个月的最后一天。
如果d>=
dayOfMonth
,那么
semiMonthBegin
返回X所在月份的第
dayOfMonth
天。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
个半月更新一次。注意,
offset
和
n
须同时指定,且只有当
n>1
时,
offset
才会生效。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
dayOfMonth
是2到27之间的整数。它是一个可选参数,默认值为15。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量。
例子
semiMonthEnd(2012.06.12);
// output
012.05.31
semiMonthEnd(2012.06.24);
// output
012.06.15
semiMonthEnd(2012.06.15);
// output
012.06.15
semiMonthEnd(2012.06.16, 16);
// output
012.06.16
date=2016.04.07+(1..10)*7
time = take(09:30:00, 10);
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
t1;
date
time
sym
qty
price
2016.04.14
09:30:00
MSFT
2200
49.6
2016.04.21
09:30:00
MSFT
1900
29.46
2016.04.28
09:30:00
MSFT
2100
29.52
2016.05.05
09:30:00
MSFT
3200
30.02
2016.05.12
09:30:00
MSFT
6800
174.97
2016.05.19
09:30:00
MSFT
5400
175.23
2016.05.26
09:30:00
MSFT
1300
50.76
2016.06.02
09:30:00
MSFT
2500
50.32
2016.06.09
09:30:00
MSFT
8800
51.29
2016.06.16
09:30:00
MSFT
4500
52.38
select avg(price),sum(qty) from t1 group by semiMonthEnd(date);
semiMonthEnd_date
avg_price
sum_qty
2016.03.31
49.6
2200
2016.04.15
29.49
4000
2016.04.30
102.495
10000
2016.05.15
112.995
6700
2016.05.31
50.805
11300
2016.06.15
52.38
4500
相关函数:
monthBegin
,
monthEnd
,
semiMonthBegin
FILE:references/doc_1140.md
# getInstrumentStrike
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentstrike.html
**来源**: DolphinDB 官方文档
---
getInstrumentStrike
语法
getInstrumentStrike(instrument)
详情
根据输入的金融工具,获取该工具的执行价格。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DOUBLE 类型标量或向量。
例子
forward = {
"productType": "Forward",
"forwardType": "FxForward",
"version": 0,
"expiry": 2025.09.24,
"delivery": 2025.09.26,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E8],
"strike": 7.2
}
instrument = parseInstrument(forward)
getInstrumentStrike(instrument)
// output: 7.2
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_1141.md
# cos
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cos.html
**来源**: DolphinDB 官方文档
---
cos
语法
cos(X)
详情
返回
X
的余弦。
参数
X
可以是标量、向量或矩阵。
返回值
DOUBLE 类型标量、向量或矩阵。
例子
cos 0 1 2;
// output
[1,0.540302,-0.416147]
相关函数:
asin
,
acos
,
atan
,
sin
,
tan
,
asinh
,
acosh
,
atanh
,
sinh
,
cosh
,
tanh
FILE:references/doc_1153.md
# getStreamingSQLStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getStreamingSQLStatus.html
**来源**: DolphinDB 官方文档
---
getStreamingSQLStatus
语法
getStreamingSQLStatus([queryId])
详情
查看流式 SQL 查询的运行状态。
若指定
queryId
,则返回该查询的状态。
若不指定
queryId
,返回当前用户注册的所有流式 SQL 查询的状态。如果调用者是管理员(admin),则返回所有用户注册的流式 SQL
查询的状态。
参数
queryId
可选参数,字符串标量,表示已注册的流式 SQL 查询 ID。
返回值
一个表,包含如下字段:
queryId:流式 SQL 查询的 ID。
user:注册该查询的用户名。
registerTime:注册该查询的时间。
status:当前查询的状态,取值包括:
SQL_REGISTERED:已注册,未运行。
SQL_RUNNING:正常运行中,结果实时更新。
SQL_STOPPED:已暂停。
INTERNAL_ERROR:运行异常。
sqlQuery:流式 SQL 查询的语句。
involvedTables:查询涉及的表。
lastErrorMessage:最近一次错误的信息(如有)。
例子
t=table(1..10 as id,rand(100,10) as val)
share t as st
declareStreamingSQLTable(st)
registerStreamingSQL("select avg(val) from st","sql_avg")
// 查看流式 SQL 查询的状态
getStreamingSQLStatus("sql_avg")
queryId
user
registerTime
status
sqlQuery
involvedTables
lastErrorMessage
sql_avg
admin
2025.08.09 03:33:40.781
SQL_REGISTERED
select avg(val) from st
st
相关函数:
declareStreamingSQLTable
,
registerStreamingSQL
FILE:references/doc_1157.md
# parseInstrument
**URL**: https://docs.dolphindb.cn/zh/funcs/p/parseInstrument.html
**来源**: DolphinDB 官方文档
---
parseInstrument
语法
parseInstrument(obj)
详情
将输入的金融工具产品描述(
obj
)转换成一个 INSTRUMENT 类型对象(金融工具),用于后续建模和定价。可解析的金融工具详见下文说明。
注意:
parseInstrument
会在序列化或反序列化过程中保留非标准标量或向量字段(即不属于金融工具预定义属性的字段)。
参数
obj
可以是字典、由字典组成的元组、内存表、字符串标量或向量,表示要解析的金融工具描述。注意,如果
obj
指定为表,则该表只能存储单一类型的金融工具。
返回值
一个 INSTRUMENT 类型对象,表示金融工具。
例子
使用字典存储付息债的描述,通过
parseInstrument
解析该字典,以获得该付息债的 INSTRUMENT 类型对象。
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"instrumentId": "230205.IB",
"start": "2023.03.06",
"maturity": "2033.03.06",
"issuePrice": 100.0,
"coupon": 0.0302,
"calendar": "CFET",
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA",
"subType": "CDB_BOND",
"issuer": "国家开发银行"
}
parseInstrument(bond)
通过
parseInstrument
解析由字典组成的元组,得到3个债券的 INSTRUMENT 类型对象。
bond1 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "DiscountBond",
"instrumentId": "259924.IB",
"start": 2025.04.17,
"maturity": 2025.07.17,
"issuePrice": 99.664,
"dayCountConvention": "ActualActualISDA",
"subType": "TREASURY_BOND",
"issuer": "中华人民共和国财政部"
}
bond2 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "ZeroCouponBond",
"instrumentId": "250401.IB",
"start": 2025.01.09,
"maturity": 2026.02.05,
"coupon": 0.0119,
"dayCountConvention": "ActualActualISDA",
"subType": "CDB_BOND",
"issuer": "国家农业发展银行"
}
parseInstrument([bond,bond1,bond2])
使用内存表存储金融工具描述,其每一列代表一个字段。通过
parseInstrument
解析该表,得到 INSTRUMENT
类型对象。
注意:若某列对应的字段在某个产品中不存在,则在插入该产品时将该列设为 NULL。
create table t (
productType STRING,
assetType STRING,
bondType STRING,
version INT,
instrumentId STRING,
start DATE,
maturity DATE,
issuePrice DOUBLE,
coupon DOUBLE,
calendar STRING,
frequency STRING,
dayCountConvention STRING,
subType STRING,
issuer STRING
)
go
insert into t values( "Cash", "Bond", "FixedRateBond", 0, "230205.IB", 2023.03.06, 2033.03.06, 100.0, 0.0302, "CFET", "Annual", "ActualActualISDA", "CDB_BOND", "国家开发银行")
insert into t values( "Cash", "Bond", "DiscountBond", 0, "259924.IB", 2025.04.17, 2025.07.17, 99.664, NULL, NULL, NULL, "ActualActualISDA", "TREASURY_BOND", "中华人民共和国财政部")
insert into t values( "Cash", "Bond", "ZeroCouponBond", 0, "250401.IB", 2025.01.09, 2026.02.05, NULL, 0.0119, NULL, NULL, "ActualActualISDA", "CDB_BOND", "国家农业发展银行")
parseInstrument(t)
使用字符串描述金融工具,通过
parseInstrument
解析该字符串,得到 INSTRUMENT 类型对象。
bond1Str = '{"productType": "Cash","assetType": "Bond","bondType": "FixedRateBond","coupon": 0.0302,"frequency": "Annual","version": 0,"instrumentId": "230205.IB","nominal": 100,"start": "2023.03.06","maturity": "2033.03.06","dayCountConvention": "ActualActualISDA","calendar": "CFET","currency": "CNY","cashflow": [{"paymentDate": "2024.03.06","coupon": 3.026804551238871,"notional": 0,"total": 3.026804551238871},{"paymentDate": "2025.03.06","coupon": 3.01319544876113,"notional": 0,"total": 3.01319544876113},{"paymentDate": "2026.03.06","coupon": 3.02,"notional": 0,"total": 3.02},{"paymentDate": "2027.03.06","coupon": 3.02,"notional": 0,"total": 3.02},{"paymentDate": "2028.03.06","coupon": 3.026804551238871,"notional": 0,"total": 3.026804551238871},{"paymentDate": "2029.03.06","coupon": 3.01319544876113,"notional": 0,"total": 3.01319544876113},{"paymentDate": "2030.03.06","coupon": 3.02,"notional": 0,"total": 3.02},{"paymentDate": "2031.03.06","coupon": 3.02,"notional": 0,"total": 3.02},{"paymentDate": "2032.03.06","coupon": 3.026804551238871,"notional": 0,"total": 3.026804551238871},{"paymentDate": "2033.03.06","coupon": 3.01319544876113,"notional": 100,"total": 103.013195448761123}],"discountCurve": "","spreadCurve": "","subType": "CDB_BOND","issuePrice": 100,"issuer": "国家开发银行"}'
parseInstrument(bondStr)
通过
parseInstrument
解析该字符串向量,得到多个 INSTRUMENT 类型对象。
bond2Str = '{"productType": "Cash","assetType": "Bond","bondType": "DiscountBond","issuePrice": 99.664000000000001,"version": 0,"instrumentId": "259924.IB","nominal": 100,"start": "2025.04.17","maturity": "2025.07.17","dayCountConvention": "ActualActualISDA","calendar": "","currency": "CNY","cashflow": [{"paymentDate": "2025.07.17","coupon": 0,"notional": 100,"total": 100}],"discountCurve": "","spreadCurve": "","subType": "TREASURY_BOND","issuer": "中华人民共和国财政部"}'
bond3Str = '{"productType": "Cash","assetType": "Bond","bondType": "ZeroCouponBond","coupon": 0.0119,"version": 0,"instrumentId": "250401.IB","nominal": 100,"start": "2025.01.09","maturity": "2026.02.05","dayCountConvention": "ActualActualISDA","calendar": "","currency": "CNY","cashflow": [{"paymentDate": "2026.01.09","coupon": 1.190000000000002,"notional": 0,"total": 1.190000000000002},{"paymentDate": "2026.02.05","coupon": 0.088027397260282,"notional": 100,"total": 100.088027397260276}],"discountCurve": "","spreadCurve": "","subType": "CDB_BOND","issuer": "国家农业发展银行"}'
parseInstrument([bond1Str,bond2Str,bond3Str])
金融工具支持与字段要求
INSTRUMENT 为 DophinDB 在 3.00.4 版本上新增的数据类型,用于支持金融工具的存储,为后续各类金融产品的定价与风险计量提供基础。
在金融工具的描述中,需要包含若干关键字段,
parseInstrument
将根据这些字段生成相应的金融工具对象。请注意,"version" 为系统保留字段,为避免冲突,请勿将此名称用于自定义字段。
目前仅支持生成下图分类树中叶节点所示的金融工具类型:
贴现债(DiscountBond)
字段名
类型
描述
是否必填
productType
STRING
固定填 "Cash"
是
assetType
STRING
固定填 "Bond"
是
bondType
STRING
固定填 "DiscountBond"
是
nominal
DOUBLE
名义金额,默认值 100
否
instrumentId
STRING
债券代码,如 "259926.IB"
否
start
DATE
起息日
是
maturity
DATE
到期日
是
dayCountConvention
STRING
日期计数惯例,可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
issuePrice
DOUBLE
发行价格
是
currency
STRING
货币,默认为 "CNY"
否
cashFlow
TABLE
债券现金流表
否
discountCurve
STRING
定价时参考的贴现曲线名称,如 "CNY_TRASURY_BOND"
否
spreadCurve
STRING
定价时参考的利差曲线名称
否
subType
STRING
债券子类型,中国债券可选值为:
"TREASURY_BOND":国债
"CENTRAL_BANK_BILL":央行票据
"CDB_BOND":政策性金融债(国开)
"EIBC_BOND":政策性金融债(进出口行)
"ADBC_BOND":政策性金融债(农发行)。
"MTN":中期票据
"CORP_BOND":企业债。
"UNSECURED_CORP_BOND":无担保企业债
"SHORT_FIN_BOND":短期融资券
"NCD":同业存单
"LOC_GOV_BOND":地方政府债
"COMM_BANK_FIN_BOND":商业银行普通金融债
"BANK_SUB_CAP_BOND":商业银行二级资本债
"ABS":资产支持证券
"PPN":非公开发行债
否
creditRating
STRING
信用等级类型,可选值为:"B", "BB", "BBB", "BBB+", "A-", "A", "A+", "AA-",
"AA", "AA+", "AAA-", "AAA", "AAA+"
否
下例定义了一个 DiscountBond 类型的 INSTRUMENT 对象。
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "DiscountBond",
"instrumentId": "259924.IB",
"start": 2025.04.17,
"maturity": 2025.07.17,
"issuePrice": 99.664,
"dayCountConvention": "ActualActualISDA"
}
instrument = parseInstrument(bond)
print(instrument)
零息债(ZeroCouponBond)
字段名
类型
描述
是否必填
productType
STRING
固定填 "Cash"
是
assetType
STRING
固定填 "Bond"
是
bondType
STRING
固定填 "ZeroCouponBond"
是
nominal
DOUBLE
名义金额,默认值 100
否
instrumentId
STRING
债券代码,如 "250401.IB"
否
start
DATE
起息日
是
maturity
DATE
到期日
是
coupon
DOUBLE
票面利率,如 0.03 表示 3%
是
frequency
STRING
付息频率
否
dayCountConvention
STRING
日期计数惯例,可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
currency
STRING
货币,默认为 "CNY"
否
cashFlow
TABLE
债券现金流表
否
discountCurve
STRING
定价时参考的贴现曲线名称,如 "CNY_TRASURY_BOND"
否
spreadCurve
STRING
定价时参考的利差曲线名称
否
subType
STRING
债券子类型,中国债券可选值为:
"TREASURY_BOND":国债
"CENTRAL_BANK_BILL":央行票据
"CDB_BOND":政策性金融债(国开)
"EIBC_BOND":政策性金融债(进出口行)
"ADBC_BOND":政策性金融债(农发行)。
"MTN":中期票据
"CORP_BOND":企业债。
"UNSECURED_CORP_BOND":无担保企业债
"SHORT_FIN_BOND":短期融资券
"NCD":同业存单
"LOC_GOV_BOND":地方政府债
"COMM_BANK_FIN_BOND":商业银行普通金融债
"BANK_SUB_CAP_BOND":商业银行二级资本债
"ABS":资产支持证券
"PPN":非公开发行债
否
creditRating
STRING
信用等级类型,可选值为:"B", "BB", "BBB", "BBB+", "A-", "A", "A+", "AA-",
"AA", "AA+", "AAA-", "AAA", "AAA+"
否
下例定义了一个 ZeroCouponBond 类型的 INSTRUMENT 对象。
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "ZeroCouponBond",
"instrumentId": "250401.IB",
"start": 2025.01.09,
"maturity": 2026.02.05,
"coupon": 0.0119,
"dayCountConvention": "ActualActualISDA"
}
instrument = parseInstrument(bond)
print(instrument)
固定利率债(FixedRateBond)
字段名
类型
描述
是否必填
productType
STRING
固定填 "Cash"
是
assetType
STRING
固定填 "Bond"
是
bondType
STRING
固定填 "FixedRateBond"
是
nominal
DOUBLE
名义金额,默认值 100
否
instrumentId
STRING
债券代码,如 "250401.IB"
否
start
DATE
起息日
是
maturity
DATE
到期日
是
coupon
DOUBLE
票面利率,如0.03表示3%
是
frequency
STRING
付息频率
是
dayCountConvention
STRING
日期计数惯例,可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
currency
STRING
货币,默认为 "CNY"
否
cashFlow
TABLE
债券现金流表
否
discountCurve
STRING
定价时参考的贴现曲线名称,如 "CNY_TRASURY_BOND"
否
spreadCurve
STRING
定价时参考的利差曲线名称
否
subType
STRING
债券子类型,中国债券可选值为:
"TREASURY_BOND":国债
"CENTRAL_BANK_BILL":央行票据
"CDB_BOND":政策性金融债(国开)
"EIBC_BOND":政策性金融债(进出口行)
"ADBC_BOND":政策性金融债(农发行)。
"MTN":中期票据
"CORP_BOND":企业债。
"UNSECURED_CORP_BOND":无担保企业债
"SHORT_FIN_BOND":短期融资券
"NCD":同业存单
"LOC_GOV_BOND":地方政府债
"COMM_BANK_FIN_BOND":商业银行普通金融债
"BANK_SUB_CAP_BOND":商业银行二级资本债
"ABS":资产支持证券
"PPN":非公开发行债
否
creditRating
STRING
信用等级类型,可选值为:"B", "BB", "BBB", "BBB+", "A-", "A", "A+", "AA-",
"AA", "AA+", "AAA-", "AAA", "AAA+"
否
下例定义了一个 FixedRateBond 类型的 INSTRUMENT 对象。
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"instrumentId": "240021.IB",
"start": 2024.10.25,
"maturity": 2025.10.25,
"issuePrice": 100,
"coupon": 0.0133,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA"
}
instrument = parseInstrument(bond)
print(instrument)
国债期货(BondFutures)
字段名
类型
描述
是否必填
productType
STRING
固定值为 "Futures"
是
futuresType
STRING
固定值为 "BondFutures"
是
nominal
DOUBLE
名义金额,默认值 100
是
instrumentId
STRING
国债期货代码,如 "T2509"
否
maturity
DATE
到期日
是
settlement
DATE
结算日
是
underlying
字典
固定利率债券结构,表示标的可交割债券
是
nominalCouponRate
DOUBLE
名义票面利率
是
下例定义了一个 BondFutures 类型的 INSTRUMENT 对象。
bond ={
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"instrumentId": "220010.IB",
"start": 2020.12.25,
"maturity": 2031.12.25,
"issuePrice": 100.0,
"coupon": 0.0149,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA"
}
futures = {
"productType": "Futures",
"futuresType": "BondFutures",
"instrumentId": "T2509", //期货代码
"nominal": 100.0,
"maturity": "2022.09.09",
"settlement": "2022.09.11",
"underlying": bond,
"nominalCouponRate": 0.03 //与国债期货品种匹配的名义利率,可从中金所获取
}
instrument = parseInstrument(futures)
print(instrument)
存款(Deposit)
字段名
类型
描述
是否必填
productType
STRING
固定填 "Cash"
是
assetType
STRING
固定填 "Deposit"
是
notional
ANY 向量
名义本金,格式如 ["USD", 1.0]。
是
instrumentId
STRING
存款参考利率指数,如 "SHIBOR_3M"
否
start
DATE
起息日
是
maturity
DATE
到期日
是
rate
DOUBLE
存款利率
是
dayCountConvention
STRING
日期计数惯例, 可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
payReceive
STRING
收付标识,"Pay" 表示支付,"Receive" 表示收取
是
disconutCurve
STRING
定价时参考的贴现曲线名称,人民币存款默认为 "CNY_FR_007"
否
calendar
STRING
交易日历
否
下例定义了一个 Deposit 类型的 INSTRUMENT 对象。
deposit = {
"productType": "Cash",
"assetType": "Deposit",
"start": 2025.05.15,
"maturity": 2025.08.15,
"rate": 0.02,
"dayCountConvention": "Actual360",
"notional":["CNY", 1E6],
"payReceive": "Receive"
}
instrument = parseInstrument(deposit)
print(instrument)
利率互换(IrFixedFloatingSwap)
字段名
类型
描述
是否必填
productType
STRING
固定填 "Swap"
是
swapType
STRING
固定填 "IrSwap"
是
irSwapType
STRING
固定填 "IrFixedFloatingSwap"
是
notional
ANY 向量
名义本金,格式如 ["USD", 1.0]
是
instrumentId
STRING
利率互换名称,可填 "CNY_FR_007 , "CNY_SHIBOR_3M"
否
start
DATE
起息日
是
maturity
DATE
到期日
是
fixedRate
DOUBLE
固定端利率
是
calender
STRING
交易日历
是
fixedDayCountConvention
STRING
固定端日期计数惯例,可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
floatingDayCountConvention
STRING
浮动端日期计数惯例,可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
spread
DOUBLE
利差
是
iborIndex
STRING
浮动端参考利率,可选FR_007和SHIBOR_3M
是
frequency
STRING
付息频率
是
payReceive
STRING
收付标识,可选:
"Pay":本方支付固定利率、接收浮动利率(pay fixed / receive
floating)
"Receive":本方接收固定利率、支付浮动利率(receive fixed / pay
floating)
是
domesticCurve
STRING
定价时参考的贴现曲线名称
否
foreignCurve
STRING
定价时参考的远期曲线名称
否
下例定义了一个 IrFixedFloatingSwap 类型的 INSTRUMENT 对象。
swap = {
"productType": "Swap",
"swapType": "IrSwap",
"irSwapType": "IrFixedFloatingSwap",
"start": 2021.05.15,
"maturity": 2023.05.15,
"frequency": "Quarterly",
"fixedRate": 0.02,
"calendar": "CFET",
"fixedDayCountConvention": "Actual365",
"floatingDayCountConvention": "Actual360",
"payReceive": "Pay",
"iborIndex": "SHIBOR_3M",
"spread": 0.0005,
"notional":["CNY", 1E8]
}
instrument = parseInstrument(swap)
print(instrument)
外汇远期(FxForward)
字段名
类型
描述
是否必填
productType
STRING
产品名称,固定值为 "Forward"
是
forwardType
STRING
远期类型,固定值为 "FxForward"
是
notional
ANY 向量
名义本金,格式如 ["USD", 1.0]
是
instrumentId
STRING
金融工具 ID
否
expiry
DATE
到期日
是
delivery
DATE
交割日
是
currencyPair
STRING
货币对,格式如:"EURUSD","EUR.USD" 或 "EUR/USD"。支持如下货币对:
EURUSD:欧元兑美元
USDCNY:美元兑人民币
EURCNY:欧元兑人民币
GBPCNY:英镑兑人民币
JPYCNY:日元兑人民币
HKDCNY:港币兑人民币
是
direction
STRING
交易方向。可选:"Buy"、"Sell"
是
strike
DOUBLE
执行价格
是
domesticCurve
STRING
定价时参考的本币贴现曲线名称
否
foreignCurve
STRING
定价时参考的外币贴现曲线名称
否
下例定义了一个 FxForward 类型的 INSTRUMENT 对象。
forward = {
"productType": "Forward",
"forwardType": "FxForward",
"expiry": 2025.09.24,
"delivery": 2025.09.26,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E8],
"strike": 7.2
}
instrument = parseInstrument(forward)
print(instrument)
外汇掉期(FxSwap)
字段名
类型
描述
是否必填
productType
STRING
产品名称,固定值为 "Swap"
是
swapType
STRING
远期类型,固定值为 "FxSwap"
是
notional
ANY 向量
名义本金,格式如 ["USD", 1.0]
是
currencyPair
STRING
货币对,格式如:"EURUSD","EUR.USD" 或 "EUR/USD"。支持如下货币对:
EURUSD:欧元兑美元
USDCNY:美元兑人民币
EURCNY:欧元兑人民币
GBPCNY:英镑兑人民币
JPYCNY:日元兑人民币
HKDCNY:港币兑人民币
是
nearExpiry
DATE
近端到期日。
是
nearDelivery
DATE
近端交割日,实际资金交割发生的日期。
是
direction
STRING
交易方向,可选值:
"Buy":在近端买入外币(买 near),在远端卖出外币(卖 far)。
"Sell":在近端卖出外币(卖 near),在远端买回外币(买 far)。
是
nearStrike
DOUBLE
近端行权价格
是
farExpiry
DATE
远端到期日
是
farDelivery
DATE
远端交割日,实际发生第二次资金交换的日期
是
farStrike
DOUBLE
远端行权价格
是
domesticCurve
STRING
定价时参考的本币贴现曲线名称
否
foreignCurve
STRING
定价时参考的外币贴现曲线名称
否
下例定义了一个 FxSwap 类型的 INSTRUMENT 对象。
swap = {
"productType": "Swap",
"swapType": "FxSwap",
"currencyPair": "EURUSD",
"direction": "Buy",
"notional": ["EUR", 1E6],
"nearStrike": 1.1,
"nearExpiry": 2025.12.08,
"nearDelivery": 2025.12.10,
"farStrike": 1.2,
"farExpiry": 2026.06.08,
"farDelivery": 2026.06.10
}
instrument = parseInstrument(swap)
print(instrument)
外汇欧式期权(FxEuropeanOption)
字段名
类型
描述
是否必填
productType
STRING
固定填 "Option"
是
optionType
STRING
固定填 "EuropeanOption"
是
assetType
STRING
固定填 "FxEuropeanOption"
是
notional
ANY 向量
名义本金,格式如 ["USD", 1.0]
是
instrumentId
STRING
金融工具 ID
否
maturity
DATE
到期日
是
underlying
STRING
货币对,格式如:"EURUSD","EUR.USD" 或 "EUR/USD"。支持如下货币对:
EURUSD:欧元兑美元
USDCNY:美元兑人民币
EURCNY:欧元兑人民币
GBPCNY:英镑兑人民币
JPYCNY:日元兑人民币
HKDCNY:港币兑人民币
是
direction
STRING
交易方向。可选值为:"Buy"、"Sell"。
是
strike
DOUBLE
执行价格。
是
dayCountConvention
STRING
日期计数惯例,可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
payoffType
STRING
收益类型,可选值为 "Call"、 "Put"
是
domesticCurve
STRING
定价时参考的本币贴现曲线名称
否
foreignCurve
STRING
定价时参考的外币贴现曲线名称
否
下例定义了一个 FxEuropeanOption 类型的 INSTRUMENT 对象。
option = {
"productType": "Option",
"optionType": "EuropeanOption",
"assetType": "FxEuropeanOption",
"notional": ["EUR", 1000000.0],
"strike": 1.2,
"maturity": "2025.10.08",
"payoffType": "Call",
"dayCountConvention": "Actual365",
"underlying": "EURUSD"
}
instrument = parseInstrument(option)
print(instrument)
用户自定义
支持用户自定义金融工具,除 producType 外,所有字段均可自定义。
字段名
类型
描述
是否必填
productType
STRING
固定填 "UserDefined"
是
相关函数:
bondPricer
(债券定价)、
irDepositPricer
(存款定价)、
bondFuturesPricer
(国债期货定价)、
fxForwardPricer
(外汇远期定价)、
fxSwapPricer
(外汇掉期定价)、
irFixedFloatingSwapPricer
(利率互换定价)、
fxEuropeanOptionPricer
(外汇欧式期权定价)
FILE:references/doc_1158.md
# strlen
**URL**: https://docs.dolphindb.cn/zh/funcs/s/strlen.html
**来源**: DolphinDB 官方文档
---
strlen
语法
strlen(X)
详情
获取目标字符串的长度。
参数
X
是目标字符串。它可以是标量或向量。
返回值
INT 类型标量或向量。
例子
strlen('abcdefg');
// output
7
strlen("I am a boy.");
// output
11
strlen(["abc","123456789"]);
// output
[3,9]
FILE:references/doc_1177.md
# exp2
**URL**: https://docs.dolphindb.cn/zh/funcs/e/exp2.html
**来源**: DolphinDB 官方文档
---
exp2
语法
exp2(X)
详情
返回2的
X
次方。
参数
X
可以是标量、数据对、向量、矩阵或表。
返回值
DOUBLE 类型,其数据形式同
X
。
例子
exp2(3);
// output
8
exp2(2 4 NULL 6);
// output
[4,16,,64]
exp2(1..4$2:2);
#0
#1
2
8
4
16
FILE:references/doc_1179.md
# lshift
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lshift.html
**来源**: DolphinDB 官方文档
---
lshift
语法
lshift(X, a)
或
X<<a
详情
lshift
是将
X
按二进制展开后整体往左移动
a
位数。右侧的位数用 0 填充。
参数
X
可以是整数标量、数据对、向量、矩阵或表;
a
是移动的位数。
返回值
返回与 X 形式一致的整型。
例子
lshift(2, 10);
// output
2048
1..10 << 1;
// output
[2,4,6,8,10,12,14,16,18,20]
1..10 << 10;
// output
[1024,2048,3072,4096,5120,6144,7168,8192,9216,10240]
1:10<<10;
// output
1024 : 10240
相关函数:
rshift
.
FILE:references/doc_1193.md
# substru
**URL**: https://docs.dolphindb.cn/zh/funcs/s/substru.html
**来源**: DolphinDB 官方文档
---
substru
语法
substru(X, offset, [length])
详情
从
X
的指定位置开始截取指定长度的字符串。
X
的第一个字符的位置为0。 如果
length
超过了
X
的长度,则到
X
的尾部结束。
参数
X
是 Unicode 编码的字符串。它可以是标量或向量。
offset
是一个非负整数。
length
是一个正整数。
返回值
STRING 类型标量或向量。
例子
substru("这是测试字符串",0,4)
// output
这是测试
substru("这是测试字符串",4,3)
// output
字符
substru("这是测试字符串",2)
// output
测试字符串
substru("这是测试字符串",2,10)
// output
测试字符串
相关函数:
substr
FILE:references/doc_1194.md
# bondConvexity
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bondconvexity.html
**来源**: DolphinDB 官方文档
---
bondConvexity
语法
bondConvexity(start, maturity, issuePrice, coupon,
frequency, dayCountConvention, bondType, settlement, price, priceType,
[benchmark='Excel'])
别名:fiConvexity
详情
返回面值为 100 的债券的凸性。凸性指债券价格与利率间非线性关系的一种量度,表示为债券价格对利率的二阶导数。
参数
注意:所有输入向量必须等长,输入标量将自动扩展以匹配其它向量的长度。
start
DATE 类型标量或向量,表示债券的起息日。
maturity
与
start
等长的 DATE 类型标量或向量,表示债券的到期日。
issuePrice
与
start
等长的数值型标量或向量,表示债券的发行价格。贴现债需指定真实发行价(通常小于100);其他债券通常为100。
coupon
数值型标量或向量,表示债券的票面利率。例如 0.03,表示票息为 3%。
frequency
整型或 STRING 类型的标量或向量,表示债券的付息频率。可选值为:
0/“Once”:到期一次还本付息
1/“Annual”:每年付息一次
2/“Semiannual:每半年付息一次
4/“Quarterly”:每季度付息一次
12/“Monthly”:每月付息一次
dayCountConvention
STRING 类型的标量或向量,表示债券的计息日数惯例。可选值为:
"Thirty360US":US (NASD) 30/360
"ActualActualISMA":实际/实际(ISMA 规则)
"Actual360":实际/360
"Actual365":实际/365
"Thirty360EU":欧洲 30/360
"ActualActualISDA":实际/实际(ISDA 规则)
bondType
STRING 类型标量或向量,表示债券的类型。可选值为:
"FixedRate":固定利率债券,定期按息票利率支付利息。
"Discount":贴现债券,没有利息支付,以贴现方式发行的债券,期末FV=面值。
"ZeroCoupon":零息债券,期末一次性支付利息和面值,期末FV=面值+利息。
settlement
DATE 类型标量或向量,表示债券的结算日,即购买日期。
price
数值型标量或向量,表示债券的到期收益率。
priceType
STRING 类型的标量或向量,用于指定债券价格类型。目前仅支持 "YTM"(到期收益率)。
benchmark
可选参数,STRING 类型标量,表示算法参考基准。目前仅支持 “Excel”(excel
中的算法)。
返回值
DOUBLE 类型标量或向量。
例子
bondConvexity(start=2023.01.01, maturity=2030.12.31, issuePrice=100, coupon=0.05, frequency=1, dayCountConvention="ActualActualISMA", bondType="FixedRate", settlement=2023.04.01, price=0.03, priceType="YTM")
// output: 51.864347713454684
相关函数
:
bondCalculator
FILE:references/doc_1201.md
# 关于 DolphinDB
**URL**: https://docs.dolphindb.cn/zh/about/ddb_intro.html
**来源**: DolphinDB 官方文档
---
关于 DolphinDB
欢迎阅读 DolphinDB 技术文档!
DolphinDB 是一款基于高性能时序数据库,支持复杂分析与流计算的实时计算平台。DolphinDB
针对数据存储、统计分析、实时计算和机器学习等多种需求,提供高效读写、快速查询、复杂分析、分布式并行计算、低延迟流处理等功能,支持高可用与水平扩展。
如下为 DolphinDB 的系统架构图:
图
1
.
DolphinDB 系统架构图
结合架构图,以下对 DolphinDB 的核心组件进行详细介绍。
分布式架构
自研的
分布式存储机制
,数据有序分散存储在不同的数据节点上,由控制节点统一精准地管理所有分区的元数据信息,包括分区和副本信息、分区版本号等要素,从而确保各节点上分区数据和副本的一致性,以提升集群的容错性和可扩展性。
提供在线和离线扩展方式、支持横向(添加更多节点)和纵向(增加单个节点的资源)的扩展系统、并且提供无缝高效的
数据迁移
和
再平衡
技术。
提供控制节点、数据节点和客户端的
高可用
方案,以确保系统在任何单节点故障下都能提供稳定的服务,从而有力保障业务的连续性。
具备全面灵活的
备份与恢复
机制,以保障数据安全,为业务保驾护航。
提供高容错性的
异步复制
方案,其具有低延迟、高吞吐量的特点,方便实现数据跨节点、跨地域的异步复制,从而增强数据资产的安全性。
多模存储引擎
支持 TSDB、OLAP、
PKEY、
IMOLTP
、VECTORDB
存储引擎。分别满足不同场景需求:
TSDB 引擎
采用 PAX
行列混存,提供性能卓越的大数据分析与点查分析。
OLAP 引擎
采用列式存储,与 TSDB
引擎相比,更适合用于对时间跨度较长的某些列数据进行聚合计算。
PKEY 引擎
是提供主键唯一性保证的,支持实时更新和高效查询的存储引擎,能够有效满足从 OLTP 数据库的主键表 CDC
到 DolphinDB 中进行数据分析的需求。
IMOLTP 引擎
是内存数据库,以行存的形式来组织数据,不仅支持事务,同时通过创建 B+ 树索引
(主键索引和二级索引) 的方式来应对高频度、高并发的更新和查询操作,该引擎将所有数据都存储在内存中。
VECTORDB
引擎
支持对向量数据创建索引,并实现了快速的近似最近邻搜索,满足对大规模向量数据高效检索和响应的需求。
保证事务
ACID
特性,提供快照级别的隔离机制。
支持多种无损数据
压缩
算法,包括 LZ4,
delta-of-delta, zstd, chimp,字典压缩等,压缩率可达 4:1~10:1。
支持
分级存储
,区分热数据和冷数据存储,减少存储成本。
批计算处理
使用内嵌的
分布式文件系统
,不仅简化数据管理流程,还显著增强了分布式计算环境的负载均衡能力,同时提供了强大的容错机制,确保数据的高可用性和计算任务的连续执行。
内置 2000+ 多领域、多种类、多功能的
函数
,覆盖广泛的数据处理需求,并开放接口支持用户自定义函数,帮助用户轻松应对各类复杂应用场景的挑战。
分布式计算框架集成了
pipeline
、
Map-Reduce
和迭代计算等多种计算模型,为用户提供性能最优的一站式多样化数据解决方案。
通过 SQL 语言与函数、表达式的无缝结合,以及
向量化计算
,开拓性地助力用户直接在数据库层面进行复杂的数据分析及运算,从而显著提升数据处理的速度和效率。
充分利用多机多核 CPU 资源,凭借精细的
并行处理
策略与高效的任务调度算法,实现了对海量数据的快速处理。
流数据处理
支持通过流数据表进行
流数据
订阅与发布。
内置
时间序列聚合
、
横截面处理
、
响应式状态处理
、
异常检测
、
会话窗口
、
多表关联
等流式计算引擎,提供
滑动窗口
、
累计窗口
、
统计函数
等算子。用户可通过串联调用计算引擎构建高效强大的计算流水线,或借助流数据引擎解析器(streamEngineParser)自动构建计算流水线,从而满足复杂多变的业务需求。
支持
回放历史数据
,支持 1 对 1,N 对 N,N 对 1
三种回放形式。
支持
流批一体
,即将研发环境中基于历史数据建模分析得到的因子或表达式直接应用于生产环境的实时数据中,并保证流计算的结果和批量计算完全一致。该功能可为用户的测试、验证和回溯分析提供极大便利。
支持从多种数据源
接入实时流数据
实时写入 DolphinDB
中,并自动处理数据格式转换和同步问题。
内置
CEP 引擎
(Complex Event
Processing,复杂事件处理),能够接收实时数据流,定义事件并从事件流中检测特定事件,进而对满足指定规则的事件执行预设的操作。
实现亚毫秒级的延迟,确保实时数据处理的极致性能。
多范式编程语言
DolphinDB 内置图灵完备的编程语言。其支持命令式编程、函数式编程、向量化编程、SQL 编程等
多范式编程语言
,凭借语言简洁灵活、表达能力强的优势,帮助用户实现开发效率的飞跃式提升。
支持
SQL-92 标准
,更在此基础上扩展了如组内计算、透视表等多种功能。同时兼容 Oracle 和 MySQL 等主流 SQL 方言。
良好生态
提供丰富全面的
SDK
生态,包括
Python
,
C++
,
C#
,
Go
,
R
和
JavaScript
等多种主流编程语言。
多种客户端,包括
Web 集群管理器
、
DolphinDB VS Code
、
JAVA GUI
、
Jupyter Notebook
、
DolphinDB 终端
。
多领域、多种类、多方式的
插件
,涵盖数据存取、行情接入、金融相关、消息队列、数值计算、机器学习、网络、云存储、文件等。
提供
模块
化设计,为用户提供便捷的
技术分析指标库
、
指标库
、
因子库
、
因子指标库
、
运维函数库
、
历史数据导入
、
行情数据接入模块
、
多因子风险模型
、
交易日历
等,旨在简化功能代码的调用流程和优化系统维护效率。
集成专属的
DataX
、
Grafana
等第三方工具,可衔接数据传输与可视化等多种解决方案。
FILE:references/doc_1207.md
# imin
**URL**: https://docs.dolphindb.cn/zh/funcs/i/imin.html
**来源**: DolphinDB 官方文档
---
imin
语法
imin(X)
详情
若
X
是向量,返回最小元素的位置。如果有多个相同的最小值,返回左起第一个最小值的位置。与所有其它聚合函数一致,计算时忽略 NULL
值。
若
X
为矩阵,计算在每列内部进行,返回一个向量。
若
X
为表,计算在每列内部进行,返回一个表。
参数
X
可以是标量、向量、矩阵或表。
例子
x = 1.2 2 NULL -1 6 -1
imin(x);
// output
3
x = 5 3 1 6 4 1 $ 3:2
imin(x);
// output
[2,2]
m=matrix(1 3 2 4, 4 2 3 1);
m;
#0
#1
1
4
3
2
2
3
4
1
imin(m);
// output
[0,3]
相关函数:
iminLast
FILE:references/doc_1217.md
# isLower
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isLower.html
**来源**: DolphinDB 官方文档
---
isLower
语法
isLower(X)
详情
判断字符串中的字母是否全部为小写。对于空字符串,该函数返回 false。
参数
X
是字符或字符串类型的标量、向量或表。
返回值
当
X
是标量时,返回布尔标量。
当
X
是向量时,返回布尔向量。
当
X
是表时,返回一个表。
例子
isLower("this is string example....wow!!!");
// output: true
isLower("THIS is string example....wow!!!");
// output: false
isLower("123456abc");
// output: true
isLower("123");
// output: false
isLower([" ",string()]);
// output: [false,false]
相关函数:
isUpper
,
isTitle
FILE:references/doc_1219.md
# tmavg
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmavg.html
**来源**: DolphinDB 官方文档
---
tmavg
语法
tmavg(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
元素的平均值。
返回值
DOUBLE 类型向量。
例子
T = 1 1 1 2 5 6
X = 1 4 2 -1 2 4
m = table(T as t,X as x)
select *, tmavg(t, x, 3) from m
t
x
tmavg_t
1
1
1
1
4
2.5
1
2
2.3333
2
-1
1.5
5
2
2
6
4
3
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = 1 4 2 -1 2 4
m = table(T as t,X as x)
select *, tmavg(t, x, 3d) from m
t
x
tmavg_t
2021.01.02
1
1
2021.01.02
4
2.5
2021.01.04
2
2.3333
2021.01.05
-1
0.5
2021.01.07
2
0.5
2021.01.08
4
3
select *, tmavg(t, x, 1w) from m
t
x
tmavg_t
2021.01.02
1
1
2021.01.02
4
2.5
2021.01.04
2
2.3333
2021.01.05
-1
1.5
2021.01.07
2
1.6
2021.01.08
4
2
相关函数:
mavg
,
avg
FILE:references/doc_1226.md
# tTest
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tTest.html
**来源**: DolphinDB 官方文档
---
tTest
语法
tTest(X, [Y], [mu=0.0], [confLevel=0.95], [equalVar=false])
详情
对未知方差的数据进行t检验。
如果没有指定
Y
,对正态分布
X
进行单样本 t 检验;如果指定了
Y
,对独立正态分布
X
和
Y
进行双样本 t 检验。
参数
X
是一个数值向量,表示用于t检验的样本。
Y
是一个数值向量,表示用于独立双样本t检验的另一个样本。它是可选参数。
mu
是一个浮点数,默认值是0。如果没有指定
Y
,
mu
表示
X
的均值的假设值;如果指定了
Y
,
mu
表示
X
,
Y
均值之差的假设值。
confLevel
是0到1之间的浮点数,表示置信区间的置信水平。
equalVar
是一个布尔值,表示
X
,
Y
的方差是否相等。
返回值
返回一个字典,包含以下 key:
stat:一张表,包含三种不同备择假设下的 p 值和置信区间
df:t 分布的自由度
confLevel:置信水平
tValue:t 统计量
例子
单样本 t 检验:
x = norm(10.0, 1.0, 20)
tTest(x, , 10.0);
// output
stat->
alternativeHypothesis pValue lowerBound upperBound
---------------------------- -------- ---------- ----------
true mean is not equal to 10 0.499649 9.68582 10.621998
true mean is less than 10 0.750176 -Infinity 10.540616
true mean is greater than 10 0.249824 9.767202 Infinity
df->19
confLevel->0.95
method->One sample t-test
tValue->0.688192
独立同方差双样本 t 检验:
x = norm(10.0, 1.0, 20)
y = norm(4.0, 1.0, 10)
tTest(x, y, 6.0, , true);
// output
stat->
alternativeHypothesis pValue lowerBound upperBound
------------------------------------ -------- ---------- ----------
difference of mean is not equal to 6 0.438767 5.539812 7.03262
difference of mean is less than 6 0.780616 -Infinity 6.906078
difference of mean is greater than 6 0.219384 5.666354 Infinity
df->28
confLevel->0.95
method->Two sample t-test
tValue->0.785483
独立不同方差双样本 t 检验:
x = norm(10.0, 1.0, 20)
y = norm(1.0, 2.0, 10)
tTest(x, y, 9.0);
// output
stat->
alternativeHypothesis pValue lowerBound upperBound
------------------------------ ----------------- ---------- ----------
true difference of mean is n...0.983376 7.752967 10.271656
true difference of mean is l...0.508312 -Infinity 10.04285
true difference of mean is g...0.491688 7.981773 Infinity
df->12.164434
confLevel->0.95
method->Welch two sample t-test
tValue->0.021269
FILE:references/doc_1231.md
# getInstrumentDelivery
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentdelivery.html
**来源**: DolphinDB 官方文档
---
getInstrumentDelivery
语法
getInstrumentDelivery(instrument)
详情
根据输入的金融工具,获取该工具的交割日期(Delivery Date)。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DATE 类型标量或向量。
例子
forward = {
"productType": "Forward",
"forwardType": "FxForward",
"version": 0,
"expiry": 2025.09.24,
"delivery": 2025.09.26,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E8],
"strike": 7.2
}
ins = parseInstrument(forward)
getInstrumentDelivery(ins)
// output: 2025.09.26
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_1249.md
# getAllDBs
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getAllDBs.html
**来源**: DolphinDB 官方文档
---
getAllDBs
语法
getAllDBs()
详情
获取当前节点上的分布式数据库。
2.00.09 版本起
,
当该函数由管理员或拥有 DB_MANAGE 权限的用户执行时,返回当前节点上所有分布式数据库;
否则,仅返回该用户有 DB_OWNER 权限的数据库。
参数
无
返回值
返回的结果是字典,key 是数据库名称,不包含 dfs://部分,value
是表名,后面的数字分别是该数据库中表的编号(从1开始)和是否已被删除。
例子
getAllDBs();
FILE:references/doc_1257.md
# tail
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tail.html
**来源**: DolphinDB 官方文档
---
tail
语法
tail(obj, [n=1])
详情
tail
返回向量的最后
n
个元素,或者矩阵的最后
n
列,或者表的最后
n
行。如果
n
没有指定,
n
取默认值 1。
参数
obj
可以是向量、矩阵或表。
n
是一个正整数。
返回值
返回一个与输入
obj
相同数据类型和形式的对象。
例子
x=1..10;
tail(x);
// output
10
tail(x,2);
// output
[9,10]
x=1..10$2:5;
x;
#0
#1
#2
#3
#4
1
3
5
7
9
2
4
6
8
10
x.tail();
// output
[9,10]
tail(x,2);
#0
#1
7
9
8
10
x=table(1..5 as a, 6..10 as b);
x;
a
b
1
6
2
7
3
8
4
9
5
10
tail(x);
// output
b->10
a->5
x.tail(2);
a
b
4
9
5
10
相关函数:
head
FILE:references/doc_1260.md
# isMonthStart
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isMonthStart.html
**来源**: DolphinDB 官方文档
---
isMonthStart
语法
isMonthStart(X)
详情
判断
X
是否为月初第一天。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
返回值
布尔型标量或向量。
例子
isMonthStart(2012.05.01);
// output: true
isMonthStart([2012.05.01,2012.05.02]);
// output: [true,false]
相关函数:
isMonthEnd
FILE:references/doc_1266.md
# cubicSplinePredict
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cubicsplinepredic.html
**来源**: DolphinDB 官方文档
---
cubicSplinePredict
语法
cubicSplinePredict(model, x)
详情
根据
model
给出的三次样条曲线,预测 x 对应的 y。
参数
model
是一个字典,包含两个 key:c 和 x,其中 c 的值是三次样条函数的分段多项式的系数,x 的值是分段多项式的分段点,c 的长度=(x
的长度-1)*4。c 和 x 的值均不可包含空值。
model
可由
cubicSpline
函数生成。
x
是一个数值型标量或向量要预测的自变量。
返回值
DOUBLE 类型向量。
例子
n = 10
x = 0..(n-1)
y = sin(x)
model = cubicSpline(x, y, bc_type="not-a-knot")
newx = [-0.5, 0.5, 0.7, 1.2, 4.5, 8.9, 9.3]
ret = cubicSplinePredict(model, newx)
返回:
[-0.632383304169291,0.501747281896522,0.658837295715183,0.924963051153032,-0.974025627606784,0.515113155358425,0.03881591118089]
FILE:references/doc_1278.md
# groupby
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/groupby.html
**来源**: DolphinDB 官方文档
---
groupby
语法
groupby(func, funcArgs, groupingCol)
或
funcArg func:G groupingCol
或
func:G(funcArgs, groupingCol)
详情
对
groupingCol
排序后分组,然后在每个分组中计算
func(funcArgs)。每组的计算结果可以是标量,向量或字典。该函数的输出结果是一个表,它的行数与分组数相等。
参数
func
是一个函数。
funcArgs
是函数 func 的参数。如果有多个参数,则用元组表示。
groupingCol
表示分组变量。可以是向量,表示一个分组列;也可以是等长向量组成的元组,表示多个分组列。
groupingCol
和
funcArgs
中的每个参数都是相同长度的向量。
注:
对于第二种情况,
func
表示的函数只能有一个参数。
返回值
一张表。
例子
sym=`IBM`IBM`IBM`MS`MS`MS$symbol;
price=172.12 170.32 175.25 26.46 31.45 29.43;
qty=5800 700 9000 6300 2100 5300;
trade_date=2013.05.08 2013.05.06 2013.05.07 2013.05.08 2013.05.06 2013.05.07;
groupby(avg, price, sym);
sym
avg_price
IBM
172.563333
MS
29.113333
price avg :G sym;
sym
avg_price
IBM
172.563333
MS
29.113333
groupby(wavg, [price, qty], sym);
// 计算每个股票标记数量加权后的平均价格
sym
avg_price
IBM
173.856129
MS
28.373869
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
groupby(max, price, [sym,minute(timestamp)])
sym
groupingKey
max_price
C
09:34m
50.76
C
09:38m
51.29
IBM
09:32m
174.97
IBM
09:35m
175.23
MS
09:36m
30.02
FILE:references/doc_1285.md
# lasso
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lasso.html
**来源**: DolphinDB 官方文档
---
lasso
语法
lasso(ds, yColName, xColNames, [alpha=1.0], [intercept=true],
[normalize=false], [maxIter=1000], [tolerance=0.0001], [positive=false],
[swColName], [checkInput=true])
详情
进行 lasso 回归估计。
最小化以下目标函数:
参数
ds
是内存表或通常用
sqlDS
函数生成的数据源。
yColName
是字符串,表示数据源中因变量的列名。
xColNames
是字符串标量或向量,表示数据源中自变量的列名。
alpha
是浮点数,表示乘以 L1 范数惩罚项的系数。默认值是1.0。
intercept
是布尔值,表示是否回归模型包含截距。默认值为 true。
normalize
是布尔值。默认值为 false。若设为 true,则所有自变量均会进行如下标准化:减去平均值,然后除以 L2 范数。若
intercept
为 false,该参数会被忽略。
maxIter
是正整数,表示最大迭代次数。默认值是1000。
tolerance
是浮点数,表示迭代中止的边界差值。默认值是0.0001。
positive
是布尔值,表示是否强制系数为正数。默认值是 false。
swColName
字符串,表示列名,必须为
ds
中存在的列名。如果未指定该参数,则所有样本的权重都默认为1;如果指定该参数,则将指定的列作为样本的权重。
checkInput
布尔值,表示是否检查输入参数(
yColName
,
xColNames
和
swColName
)的合法性。
若
checkInput
=true(默认值),则会检查这些参数中是否存在无效值(NULL),若存在,则会报错;
若
checkInput
=false,则不检查无效值。
注:
强烈建议开启
checkInput
,以检查输入参数的有效性。如果不开启
checkInput
,则必须确保输入参数中不存在无效值,并且中间计算过程中不会产生无效值,否则可能得到一个无用的模型。
返回值
一个字典,包含以下 key:
modelName:模型名称。
coefficients:模型的回归系数。
intercept:截距。
dual_gap:优化结束时的对偶间隙。
tolerance:迭代中止的边界差值。
iterations:迭代次数。
xColNames:数据源中自变量的列名。
predict:用于预测的函数。
例子
y = [225.720746,-76.195841,63.089878,139.44561,-65.548346,2.037451,22.403987,-0.678415,37.884102,37.308288];
x0 = [2.240893,-0.854096,0.400157,1.454274,-0.977278,-0.205158,0.121675,-0.151357,0.333674,0.410599];
x1 = [0.978738,0.313068,1.764052,0.144044,1.867558,1.494079,0.761038,0.950088,0.443863,-0.103219];
t = table(y, x0, x1);
lasso(t, `y, `x0`x1);
如果 t 是一个 DFS 表,则应使用数据源作为输入:
lasso(sqlDS(<select * from t>), `y, `x0`x1);
FILE:references/doc_1296.md
# dropIPCInMemoryTable
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropIPCInMemoryTable.html
**来源**: DolphinDB 官方文档
---
dropIPCInMemoryTable
语法
dropIPCInMemoryTable(tableName)
详情
删除跨进程共享内存表。
注:
此函数仅适用于 Linux 系统。
server 关机并不能删除跨进程共享内存表,仍然需要通过
dropIPCInMemoryTable
进行删除。
参数
tableName
字符串,表示跨进程共享内存表的名称。
返回值
一个字符串,表示删除的跨进程共享内存表的名称。
例子
删除函数
createIPCInMemoryTable
例子中创建的表 ipc_table。
dropIPCInMemoryTable(`ipc_table)
// output
ipc_table
FILE:references/doc_1297.md
# getComputeGroupChunksStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getcomputegroupchunksstatus.html
**来源**: DolphinDB 官方文档
---
getComputeGroupChunksStatus
语法
getComputeGroupChunksStatus([computeGroup])
详情
应用于控制节点,获取指定或所有计算组中缓存的所有 chunk (包括 file chunk 和 tablet chunk)的元数据信息。
参数
computeGroup
可选参数,字符串标量,表示计算组名称。
返回值
返回一个表,包含以下列:
chunkId:chunk 的唯一标识
file:分区路径
routedTo:计算节点别名,控制节点会将对该分区的查询调度到此计算节点。
cachedOn:缓存分区的计算节点别名,形式为 alias:[version],例如:orca2:[29] 表示名为 orca2
的计算节点缓存了分区版本号为 29 的数据。
computeGroup:缓存分区的计算组名字。一个分区可能被多个计算组缓存。
size:file chunk 占用磁盘空间,单位为 byte。对于 tablet chunk,返回 0,需要使用 getTabletsMeta
来查看它们实际占用的磁盘空间。
version:版本号。
vcLength:版本链长度。
versionChain:版本链。
state:chunk 状态。CONSTRUCTING:正在事务中; RECOVERING:正在 recovery
中;COMPLETE:已经处于事务终止状态。
dataNodeReplicas:数据节点上副本的分布信息。
dataNodeReplicaCount:数据节点上副本的数量。
lastUpdated:上一次更新的时间戳。
permission:CHUNK 的权限。CHUNK 的权限分为 READ_ONLY 以及
READ_WRITE(默认权限)两类。正在进行迁移的分区,或存储在 s3 的分区权限均为 READ_ONLY。
例子
getComputeGroupChunksStatus()
chunkId
path
routedTo
cachedOn
computeGroup
size
version
vcLength
versionChain
state
dataNodeReplicas
dataNodeReplicaCount
lastUpdated
permission
abec288a-49f7-61b9-464e-56bf134c8340
/Storage_compute_separation_tsdb/20120110/Key19/2
orca3
[NOT CACHED]
orca
0
1
1
1466:0:1:1466 ->
COMPLETE
dnode2:1:0:false:0
1
2024.10.12 17:26:51.757
READ_WRITE
fdb95a8e-72f0-21a7-0443-2cbe02feeca2
/Storage_compute_separation_tsdb/20120229/Key1/2
orca1
[NOT CACHED]
orca
0
1
1
1463:0:1:1463 ->
COMPLETE
dnode3:1:0:false:0
1
2024.10.12 17:26:51.708
READ_WRITE
55020019-8b2c-75a1-3b40-7ad2469abe48
/Storage_compute_separation_tsdb/20120110/Key13/2
orca3
[NOT CACHED]
orca
0
1
1
1458:0:1:1458 ->
COMPLETE
dnode3:1:0:false:0
1
2024.10.12 17:26:51.618
READ_WRITE
96678f5f-6ae5-2b98-9944-5d4370473dee
/Storage_compute_separation_tsdb/20120110/Key7/2
orca2
[NOT CACHED]
orca
0
1
1
1456:0:1:1456 ->
COMPLETE
dnode1:1:0:false:0
1
2024.10.12 17:26:51.583
READ_WRITE
FILE:references/doc_1305.md
# eval
**URL**: https://docs.dolphindb.cn/zh/funcs/e/eval.html
**来源**: DolphinDB 官方文档
---
eval
语法
eval(expr)
详情
解析给定的元代码。
参数
expr
是元代码。
例子
eval(<1+2>);
// output
3
eval(<1+2+3=10>);
// output
0
eval(expr(6,<,8));
// output
1
eval(expr(sum, 1 2 3));
// output
6
a=6; b=9;
eval(expr(<a>,+,<b>));
// output
15
FILE:references/doc_1309.md
# mwavg
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mwavg.html
**来源**: DolphinDB 官方文档
---
mwavg
语法
mwavg(X, Y, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内,以
Y
为权重(权重会自动缩放,使其元素之和为1),计算
X
元素的加权平均。
注:
与
mavg
以 size(
weight
)
长度的窗口进行滑动窗口计算不同,
mwavg
的权重
Y
必须和
X
具有相同的长度。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
Y
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
price=2.1 2.2 2.3 2.5 2.6 2.8 2.7 2.5;
volume=10 20 10 40 10 40 10 20;
mwavg(price, volume, 4);
// output: [,,,2.35,2.4125,2.61,2.65,2.6875]
mwavg(price, volume, 4, 2);
// output: [,2.166667,2.2,2.35,2.4125,2.61,2.65,2.6875]
price1 = indexedSeries(date(2020.06.05)+1..8, price)
volume1 = indexedSeries(date(2020.06.05)+1..8, volume)
mwavg(price1,volume1, 4d)
label
col1
2020.06.06
2.1
2020.06.07
2.1667
2020.06.08
2.2
2020.06.09
2.35
2020.06.10
2.4125
2020.06.11
2.61
2020.06.12
2.65
2020.06.13
2.6875
mwavg(price1,volume1, 1w)
label
col1
2020.06.06
2.1
2020.06.07
2.1667
2020.06.08
2.2
2020.06.09
2.35
2020.06.10
2.3788
2020.06.11
2.5077
2020.06.12
2.5214
2020.06.13
2.5467
相关函数:
wavg
,
mavg
FILE:references/doc_1327.md
# isUpper
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isUpper.html
**来源**: DolphinDB 官方文档
---
isUpper
语法
isUpper(X)
详情
判断字符串中的字母是否全部为大写。对于空字符串,该函数返回 false。
参数
X
是字符或字符串类型的标量或向量。
返回值
布尔标量或向量。
例子
isUpper("THIS IS STRING EXAMPLE....WOW!!!");
// output: true
isUpper("THIS is string example....wow!!!");
// output: false
isUpper("123456ABC");
// output: true
isUpper("123");
// output: false
isUpper([" ",string()]);
// output: [false,false]
相关函数:
isLower
,
isTitle
FILE:references/doc_1329.md
# getAuthenticatedUsers
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getAuthenticatedUsers.html
**来源**: DolphinDB 官方文档
---
getAuthenticatedUsers
语法
getAuthenticatedUsers()
详情
获取所有节点已经登录的用户信息。
参数
无
返回值
返回一个字符串向量,包含所有已登录用户的名称。
例子
getAuthenticatedUsers()
// output
["admin","a1","a3","a2","a4"]
FILE:references/doc_1350.md
# eachRight
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/eachRight.html
**来源**: DolphinDB 官方文档
---
eachRight
语法
eachRight(func, X, Y,
[assembleRule|consistent=false])
func:R(X, Y)
或
X <operator>:R
Y
表示不指定
assembleRule
,使用默认值
func:RC(X, Y)
或
X <operator>:RC Y
表示指定
assembleRule
,此例中指定为 C(Consistent)
详情
把 func 应用到
Y
的每个元素上,即依次执行 func(X,Y(i))。
对于向量,Y(i) 为每个元素
对于矩阵,Y(i) 为每一列
对于表,Y(i) 为每一行
对于数组向量,Y(i) 为每一行
对于字典,Y(i) 为字典的每一个 value
如果 func 支持向量操作,并且输入数据是一个向量,为性能考虑,应直接使用向量函数或运算符,不要使用
eachRight
。
参数
func
是一个二元函数。
X
和
Y
可以是向量,矩阵、表
、数组向量
或字典。
assembleRule
可选参数,表示如何将子任务的结果合并为函数最终结果。接受一个整数或字符串作为输入,可选值如下:
0 (或 "D"):默认值,表示 DolphinDB
规则,即根据所有子任务的结果来决定最终输出的数据类型和形式。当所有子结果具有相同的数据类型和形式时,多个标量合并为一个向量、多个向量合并为一个矩阵、多个矩阵合并为一个元组、多个字典合并为一张表;否则将所有子结果合并为一个元组输出。
1(或 "C"):表示 Consistent
规则,即认为所有子结果的数据类型和形式都与第一个子结果相同,根据第一个子结果来选择最终结果的数据类型和形式。如果后续子任务返回的结果与第一个子任务的结果类型不一致,系统会尝试对后续结果进行类型转换。如果转换失败则抛出异常。因此,此规则只可在已知子结果的数据类型及形式一致时指定。此规则可使系统免于逐一缓存并检查每个子任务的计算结果,从而提升性能。
2(或 "U"):表示 Tuple 规则,系统不再对各子结果的类型和形式一致性进行检查,而是直接将子结果组装成一个元组输出。
3(或 "K"):表示 kdb+ 规则。与 DolphinDB 规则类似,都会根据所有子结果来决定最终结果形式。主要区别在于,kdb+
规则下,只要有任一子任务返回向量,则最终结果必为一个元组;而在 DolphinDB
规则下,子任务结果若均为长度相同的向量,则最终结果为一个矩阵。其他情况下,kdb+ 规则的输出与 DolphinDB 规则相同。
注:
自 2.00.15
/3.00.3
版本起,新增了
assembleRule
参数。该参数不仅实现了原
consistent
参数的功能,还提供了更多的结果合并选项。
consistent
是一个布尔值,默认值为 false,相当于
assembleRule
="D";若为 true,则相当于
assembleRule
="C"。为保持兼容性,用户仍可使用
consistent
参数。如果同时指定
assemble
和
consistent
,将以
consistent
的值为准。
assembleRule
也可在高阶函数对应的函数模式符号后指定,通过字符 D/C/U/K 表示。以
eachPre (:P)
为例,形如
sub:PU(X)
。不指定则使用默认值 D。
返回值
取决于
assembleRule
的值。
例子
eachRight
作用于两个向量:
x = 4 3 2 1
y = 3 0 6;
eachRight(add, x, y);
3
0
6
7
4
10
6
3
9
5
2
8
4
1
7
x pow :R y;
3
0
6
64
1
4096
27
1
729
8
1
64
1
1
1
eachRight
作用于一个矩阵以及一个向量:
x=1..6$2:3;
x;
col1
col2
col3
1
3
5
2
4
6
1 1 ** :R x;
// output
[3,7,11]
eachRight
作用于两个矩阵:
y=6..1$3:2;
y;
col1
col2
6
3
5
2
4
1
eachRight(**, x, y);
// output
(#0
--
41
56
,#0
--
14
20
)
eachRight
作用于一个字典和一个向量:
d=dict(`a`b`c, [[1, 2, 3],[4, 5, 6], [7, 8, 9]])
eachRight(add,10 20 30,d)
// output
a->[11,22,33]
b->[14,25,36]
c->[17,28,39]
FILE:references/doc_1354.md
# regexFindStr
**URL**: https://docs.dolphindb.cn/zh/funcs/r/regexfindstr.html
**来源**: DolphinDB 官方文档
---
regexFindStr
语法
regexFindStr(str, pattern, [onlyFirst=true],
[offset])
详情
不同于
regexFind
返回满足条件的字符串位置,
regexFindStr
从第
offset
个位置开始搜索,返回
str
中满足正则表达式
pattern
的字符串。
注:
该函数新增于
2.00.11.1版本
。
参数
str
字符串或字符串向量,表示待搜索的对象。
pattern
字符串,表示搜索的模式字符串(正则表达式)。模式字符串可以包含字面量字符、元字符或两者的组合。
onlyFirst
布尔标量,表示是否只返回与正则表达式匹配的第一个子字符串:
默认值为 true,此时针对 str 中的每一个字符串,仅返回第一个满足正则表达式的子字符串;
设置为 false 时,针对 str 中的每一个字符串,返回所有满足正则表达式的非重叠匹配的子字符串。
offset
非负整数,表示从
str
的第
offset
个位置开始搜索。默认值为0,即
str
的第一个位置。
返回值
当
str
为标量,且
onlyFirst
为 true
时,若存在满足条件的子字符串,则返回一个字符串标量,否则返回一个空的字符串。
当
str
为标量,且
onlyFirst
为 false
时,若存在满足条件的子字符串,则返回一个字符串向量,其元素为所有满足条件的子串。
当
str
为向量,且
onlyFirst
为 true 时,返回一个字符串向量,其中每个元素都是
str
中对应位置元素中第一个匹配正则表达式的子字符串。
当
str
为向量,且
onlyFirst
为 false 时,返回一个元组,其中每个元素都是
str
对应位置元素中所有匹配正则表达式的子字符串的向量。
例子
str
为标量,且
onlyFirst
为 true 时:
regexFindStr('234AA(2)BBB S&P', '([A|B|C|+|-]*)', true)
返回:AA
str
为标量,且
onlyFirst
为
false
时:
regexFindStr('234AA(2)BBB S&P', '([A|B|C|+|-]*)', false)
返回:["AA","BBB"]
str
为向量,且
onlyFirst
为 true 时:
regexFindStr(['234AA(2)BBBS&P', '234AA(2)BBBS&P'], '([A|B|C|+|-]*)', true)
返回:["AA","AA"]
str
为向量,且
onlyFirst
为 false 时:
regexFindStr(['234AA(2)BBBS&P', '234AA(2)BBBS&P'], '([A|B|C|+|-]*)', false)
返回:(["AA","BBB"],["AA","BBB"])
FILE:references/doc_1359.md
# concat
**URL**: https://docs.dolphindb.cn/zh/funcs/c/concat.html
**来源**: DolphinDB 官方文档
---
concat
语法
concat(X, Y)
详情
如果
X
是字符串或字符:
当
X
为空时,若
Y
是空字符串或空字符,该函数返回一个空字符串;若
Y
是非空字符串或非空字符,该函数返回字符串
Y
。
当
X
非空时,无论
Y
是否为空,该函数将
Y
连接到
X
之后,返回新的字符串。
如果
X
是字符串向量或字符向量:
当
X
为空时,无论
Y
是否为空,该函数总是返回一个空字符串。
当
X
非空时,若
Y
是空字符串或空字符,该函数将
X
的每个元素依次连接成一个新的字符串并返回;若
Y
非空,该函数依次连接
X
中每个字符串(字符),并使用
Y
对分隔它们隔,返回新的字符串。
注:
concat
在进行连接之前会将所有参数隐式转换为字符串类型,将空值隐式转换为空字符串。
参数
X
可以是字符串标量/向量、字符标量/向量。
Y
是字符串或字符。
若
X
或
Y
未指定,则它们将被处理为空字符串。
返回值
字符串(STRING)
例子
// 连接两个字符串
concat (`hello, `world);
// output
helloworld
// 返回在 IBM, GOOG 和 APPL 间用 "," 分隔的结果
x = concat(`IBM`GOOG`APPL, ",");
x;
// output
IBM,GOOG,APPL
typestr x;
// output
STRING
size x;
// output
1
concat(string([]),"a")
// output
NULL
concat("55","")
// output
55
// Y 未指定,将 X 的每个元素直接拼接为1个字符串
concat(`a`b`c`d,)
// output
abcd
FILE:references/doc_1364.md
# isMonotonic
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isMonotonic.html
**来源**: DolphinDB 官方文档
---
isMonotonic
是
isMonotonicIncreasing
的别名。
FILE:references/doc_1368.md
# kernelRidge
**URL**: https://docs.dolphindb.cn/zh/funcs/k/kernelRidge.html
**来源**: DolphinDB 官方文档
---
kernelRidge
语法
kernelRidge(ds, yColName, xColNames, [alpha=1.0], [kernel='linear'],
[gamma=0], [degree=3], [coef0=1], [swColName])
详情
该函数基于核函数和岭回归的正则化技术,拟合数据间的复杂非线性关系,输出回归预测模型。
目标函数为:
参数
ds
是内存表或由
sqlDS
生成的数据源。
yColName
是字符串,表示数据源中因变量的列名,对应目标函数中的 y 。
xColNames
是字符串标量或向量,表示数据源中自变量的列名。对应目标函数中的 X。
alpha
可选参数,是正数,表示正则化强度。默认值为 1.0。 对应目标函数中的 alpha。
kernel
可选参数,是字符串,表示核函数的类型。对应目标函数中的
Φ
。支持以下核函数:
'linear':线性核函数
<x, y>
'rbf':径向基函数核(高斯核)
exp(-gamma * ||x - y||²)
'poly'/'polynomial':多项式核函数
(gamma * <x, y> +
coef0)^degree
'sigmoid':Sigmoid核函数
tanh(gamma * <x, y> + coef0)
'laplacian':拉普拉斯核函数
exp(-gamma * ||x - y||₁)
'cosine':余弦相似度核函数
<x, y> / (||x|| * ||y||)
'additive_chi2':加性卡方核函数
-∑[(x - y)² / (x + y)]
'chi2':卡方核函数
exp(-gamma * ∑[(x - y)² / (x + y)])
gamma
可选参数,是数值标量,表示核函数参数。默认值为 0,此时根据特征数自动设置。
degree
可选参数,是数值标量,表示多项式核函数的次数。默认值为 3 。
coef0
可选参数,是数值标量,表示核函数中的常数项系数。默认值为 1.0 。
swColName
可选参数,是字符串,指定
ds
中的一个列名,将该列作为样本权重。默认所有样本的权重都为 1 。
返回值
返回一个字典,包含以下键:
modelName: 字符串标量,表示模型名称,即 kernelRidge 方法对应的模型名为 “kernelRidge”。
coefficients: 数值向量,表示参数向量,对应目标函数中的 w 向量。
xColNames: 字符串向量,表示特征变量列名。
xFit: 数值矩阵,用于存储输入数据源中的自变量。
alpha: 数值标量,与参数中的
alpha
相同。
kernel: 字符串标量,与参数中的
kernel
相同。
gamma: 数值标量,与参数中的
gamma
相同。
degree: 数值标量,与参数中的
degree
相同。
coef0: 数值标量,与参数中的
coef0
相同。
predict: 模型的预测函数。
例子
x1 = [-1.5, 2.3, 4.2, 1.6];
x2 = [-2.2, 3.9, 2.8, 0.5];
sw = [2, 5, 8, 1];
y = [0.0, 0.9, 3.2, 3.1];
t = table(y, x1, x2, sw);
m = kernelRidge(t, `y, `x1`x2, 1, 'laplacian', 0, 3, 1, `sw);
m
/*
modelName->kernelRidge
coefficients->#0
------------------
-0.061436450468451
0.09192514209272
2.716894143137368
1.428547958639275
xColNames->["x1","x2"]
xFit->#0 #1
----------------- ----
-1.5 -2.2
2.3 3.9
4.200000000000001 2.8
1.6 0.5
alpha->1
kernel->laplacian
gamma->0.5
degree->3
coef0->1
predict->kernelRidgePredict
*/
x1 = [-1.2, 4.6, 2.4];
x2 = [-1.0, 2.8, -4.7];
t_test = table(x1, x2);
predict(m, t_test);
/*
#0
-----------------
0.166070925673076
2.34188781136904
0.095783250622374
*/
FILE:references/doc_1372.md
# parseInt
**URL**: https://docs.dolphindb.cn/zh/funcs/p/parseInt.html
**来源**: DolphinDB 官方文档
---
parseInt
是
parseInteger
的别名。
FILE:references/doc_1378.md
# warmupStreamEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/w/warmupStreamEngine.html
**来源**: DolphinDB 官方文档
---
warmupStreamEngine
语法
warmupStreamEngine(engine, msgs)
详情
把数据写入流数据引擎,但是不输出结果。下一批次数据写入此流数据引擎,可以利用已计算的结果来加速计算。
目前仅支持响应式状态引擎,时间序列聚合引擎和日级时间序列引擎。
参数
engine
是创建流数据引擎时返回的表对象。
msgs
是一个数据表。
返回值
无。
例子
trade=table(1000:0, `date`sym`price`volume, [DATE, SYMBOL, DOUBLE, INT])
n=3000*100
date=take(2021.03.08, n)
sym=take("A"+string(1..3000), n)
price=round(rand(100.0, n), 2)
volume=rand(100, n)
table1 = table(date, sym, price, volume)
outputTable = table(n:0, `sym`factor1, [STRING,DOUBLE])
engine = createReactiveStateEngine("test", <ema(volume, 40)>, table1, outputTable, "sym")
warmupStreamEngine(engine, table1)
date=take(2021.03.09, n)
sym=take("A"+string(1..3000), n)
price=round(rand(100.0, n), 2)
volume=rand(100, n)
table2 = table(date, sym, price, volume)
engine.append!(table2)
FILE:references/doc_1382.md
# fminNCG
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fminncg.html
**来源**: DolphinDB 官方文档
---
fminNCG
语法
fminNCG(func, X0, fprime, fhess, [xtol=1e-5], [maxIter],
[c1=1e-4], [c2=0.9])
详情
使用牛顿共轭梯度法(Newton conjugate gradient;也称为截断牛顿法,Truncated Newton
method)对目标函数进行无约束最小化。本方法适用于解决大型非线性优化问题。
参数
func
函数名,表示需要最小化的目标函数。注意:函数返回值须是数值标量类型。
X0
数值类型的标量或向量,表示使目标函数最小化的参数的初始猜测。
fprime
函数名,表示计算
func
梯度的函数。
fhess
函数名,表示计算
func
的 Hessian 矩阵的函数。
xtol
可选参数,正数值标量,用于判断是否结束迭代的步长衡量值。如果两次迭代间参数变化量的范数小于
xtol*size(X0)
,则认为算法收敛,停止迭代。默认值为 1e-5。
maxIter
可选参数,非负整数标量,表示执行的最大迭代次数。
c1
可选参数,数值标量,值域为(0,1),
c1
应小于
c2
,表示 Armijo 条件规则的参数。默认值为 1e-4。
c2
可选参数,数值标量,值域为(0,1),
c2
应大于
c1
,表示曲率条件规则参数。默认值为 0.9。
返回值
返回一个字典,字典有以下成员:
xopt:浮点数向量,使目标函数最小化的参数值。
fopt:浮点数标量,目标函数最小值。fopt=func(xopt)。
iterations:整数标量,优化过程中执行的总迭代数。
fcalls:整数标量,优化过程中的目标函数调用次数。
gcalls:整数标量,优化过程中的梯度函数调用次数。
hcalls:整数标量,优化过程中的计算 Hessian 函数的调用次数。
warnFlag:整数标量,有四个可能值:
0:表示成功执行算法全过程。
1:表示已达最大迭代次数,算法停止执行。
2:表示由于精度损失问题,线搜索失败。
3:表示结果产生 NULL 值。
例子
本例自定义条件,传入参数
f
,
X0
,
fprime
,
fhess
,使用牛顿共轭梯度法找到目标函数
rosen
的最小值。
def rosen(x) {
N = size(x);
return sum(100.0*power(x[1:N]-power(x[0:(N-1)], 2.0), 2.0)+power(1-x[0:(N-1)], 2.0));
}
def rosen_der(x) {
N = size(x);
xm = x[1:(N-1)]
xm_m1 = x[0:(N-2)]
xm_p1 = x[2:N]
der = array(double, N)
der[1:(N-1)] = (200 * (xm - xm_m1*xm_m1) - 400 * (xm_p1 - xm*xm) * xm - 2 * (1 - xm))
der[0] = -400 * x[0] * (x[1] - x[0]*x[0]) - 2 * (1 - x[0])
der[N-1] = 200 * (x[N-1] - x[N-2]*x[N-2])
return der
}
def diag1(x, k) {
N = size(x)
m = matrix(type(x), N+1,N+1)
if (k == 1) {
for(i in 0:N){
m[i, i+1] = x[i]
}
} else {
for(i in 0:N){
m[i+1, i] = x[i]
}
}
return m
}
def rosen_hess(x) {
N = size(x);
x1= x[0:(N-1)] * 400
H = diag1(-x1, 1) - diag1(x1, -1)
diagonal = array(type(x), N)
diagonal[0] = 1200 * x[0]*x[0] - 400 * x[1] + 2
diagonal[N-1] = 200
diagonal[1:(N-1)] = 202 + 1200 * x[1:(N-1)]*x[1:(N-1)] - 400 * x[2:N]
H = H + diag(diagonal)
return H
}
X0 = [4, -2.5]
fminNCG(rosen, X0, rosen_der, rosen_hess)
/* Ouput:(返回顺序可能略有不同)
xopt->[0.999999966120496,0.999999932105584]
fopt->1.149654357653714E-15
iterations->34
fcalls->45
gcalls->45
hcalls->34
warnFlag->0
*/
FILE:references/doc_1387.md
# dictUpdate!
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dictUpdate_.html
**来源**: DolphinDB 官方文档
---
dictUpdate!
语法
dictUpdate!(dictionary, function, keys, parameters,
[initFunc=copy])
详情
更新字典中的特定的键的值。
参数
dictionary
是一个字典。
function
是一个函数。
keys
可以是标量或向量,表示对哪些键应用函数。
parameters
和
keys
具有相同长度。应用函数的参数是
parameters
和字典的初始值。
initFunc
是一个一元函数。当更新的键不存在时,执行该函数。只有当字典的值是 ANY 类型时,才能指定该参数。
返回值
无。
例子
x=dict(1 2 3, 1 1 1);
x;
// output
3->1
1->1
2->1
dictUpdate!(x, add, 2 3, 1 2);
// output
3->3
1->1
2->2
x.dictUpdate!(mul, 3 4, 2 4);
// output
4->4
3->6
1->1
2->2
d = dict(`IBM`MSFT, [1 2, 3 4])
msg = table(`IBM`MSFT`GOOG as symbol, 2 3 2 as ap)
d.dictUpdate!(append!, msg.symbol, msg.ap, x->array(x.type(), 0, 512).append!(x))
d;
// output
MSFT->[3,4,3]
GOOG->[2]
IBM->[1,2,2]
FILE:references/doc_1407.md
# head
**URL**: https://docs.dolphindb.cn/zh/funcs/h/head.html
**来源**: DolphinDB 官方文档
---
head
语法
head(X, [n=1])
详情
head
返回向量的前
n
个元素,或矩阵的前
n
列,或表的前
n
行。如果
n
没有指定,
n
取默认值1。
参数
X
可以是向量、矩阵或表。
n
是一个正整数。
返回值
标量、向量、矩阵、字典或表。
例子
x=1..10; head(x);
// output
1
x=1..10$2:5;
x;
#0
#1
#2
#3
#4
1
3
5
7
9
2
4
6
8
10
x.head();
// output
[1,2]
head(x,2);
#0
#1
1
3
2
4
x=table(1..5 as a, 6..10 as b);
x;
a
b
1
6
2
7
3
8
4
9
5
10
head(x);
// output
b->6
a->1
x.head(2);
a
b
1
6
2
7
相关函数:
tail
FILE:references/doc_143.md
# toCharArray
**URL**: https://docs.dolphindb.cn/zh/funcs/t/toCharArray.html
**来源**: DolphinDB 官方文档
---
toCharArray
语法
toCharArray(X)
详情
将字符串拆分字符向量。
参数
X
STRING/BLOB/SYMBOL 类型标量或向量。
返回值
若
X
是标量,返回一个 CHAR 类型向量。
若
X
是向量,返回一个 CHAR 类型数组向量。
例子
str = "It is great!\n"
print str.toCharArray()
// output
['I','t',' ','i','s',' ','g','r','e','a','t','!',10]
str1 = ["A#", "B C", "D\t"]
print str1.toCharArray()
// output
[['A','#'],['B',' ','C'],['D',9]]
将一个包含了 BLOB 类型的数据写入文件,需要使用
toCharArray
进行转换,以保证写入的数据正确。
//将一个向量压缩后,存入一个二进制文件
x=1..100
//BLOB 类型的字符串开头会使用4个字节来标识它的长度
y=blob(compress(x).concat())
dir = WORK_DIR+"/toCharArray.bin"
g = file(dir, "w")
//使用 toCharArray 函数对 BLOB 类型的字符串进行转换,则只会将正确的数据写入文件(头部的4个字节不会写入)
g.write(y.toCharArray()) //实际写入了467个字节
g.close()
// output
dir1 = WORK_DIR+"/toCharArray1.bin"
g1 = file(dir1, "w")
g1.write(y) //实际写入了471个字节
g1.close()
相关函数:
split
FILE:references/doc_1430.md
# demean
**URL**: https://docs.dolphindb.cn/zh/funcs/d/demean.html
**来源**: DolphinDB 官方文档
---
demean
语法
demean(X)
详情
对一组数据进行去均值化(零均值化)操作,空值不参与计算。
参数
X
数值型标量、向量、矩阵或表。
返回值
返回一个和
X
维度相同的 DOUBLE 类型对象。
若
X
为向量,计算 X - avg(X);
若
X
为矩阵,则在矩阵每一列进行计算;
若
X
为表,则只对数值列进行计算。
例子
x = 1 NULL 2 3
demean(x)
输出返回:[-1,,0,1]
v = 1 0 1 1 8 2 -4 0
demean(v)
输出返回:[-0.125,-1.125,-0.125,-0.125,6.875,0.875,-5.125,-1.125]
FILE:references/doc_1438.md
# mvarpTopN
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mvarpTopN.html
**来源**: DolphinDB 官方文档
---
mvarpTopN
语法
mvarpTopN(X, S, window, top, [ascending=true],
[tiesMethod='oldest'])
参数说明和窗口计算规则请参考:
mTopN
详情
在给定长度(以元素个数衡量)的滑动窗口内,根据
ascending
指定的排序方式将
X
按照
S
进行稳定排序后,取前
top
个元素计算总体方差。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
X = 1..7
S = 0.3 0.5 0.1 0.1 0.5 0.2 0.4
mvarpTopN(X, S, 4, 2)
// output: [0,0.25,1,0.25,0.25,0.25,1]
X = NULL 1 2 3 4 NULL 5
S = 3 5 1 1 5 2 4
mvarpTopN(X, S, 4, 2)
// output: [,0,0,0.25,0.25,0.25,0]
X = matrix(1..5, 6..10)
S = 2022.01.01 2022.02.03 2022.01.23 2022.04.06 2021.12.29
mvarpTopN(X, S, 3, 2)
#0
#1
0
0
0.25
0.25
1
1
0.25
0.25
1
1
X = matrix(1..5, 6..10)
S = matrix(2022.01.01 2022.02.03 2022.01.23 NULL 2021.12.29,NULL 2022.02.03 2022.01.23 2022.04.06 NULL)
mvarpTopN(X, S, 3, 2)
#0
#1
0
0.25
0
1
0.25
0.25
0.25
1
0.25
相关函数:
mvarp
FILE:references/doc_1440.md
# defined
**URL**: https://docs.dolphindb.cn/zh/funcs/d/defined.html
**来源**: DolphinDB 官方文档
---
defined
语法
defined(names, [type=VAR])
详情
返回一个标量/向量,表示
names
中的每个元素是否已被定义。
参数
names
可以是字符串标量或向量,表示对象名。
type
可为 VAR(本地变量),SHARED(共享变量)或 DEF(函数定义)。默认值为 VAR。
例子
x=10
y=20
def f(a){return a+1}
share table(1..3 as x, 4..6 as y) as t1;
defined(["x","y","f",`t1]);
// output
[1,1,0,0]
defined(["x","y","f",`t1], DEF);
// output
[0,0,1,0]
defined(["x","y","f",`t1], SHARED);
// output
[0,0,0,1]
FILE:references/doc_1450.md
# pchipInterpolateFit
**URL**: https://docs.dolphindb.cn/zh/funcs/p/pchipInterpolateFit.html
**来源**: DolphinDB 官方文档
---
pchipInterpolateFit
语法
pchipInterpolateFit(X, Y, [extrapolate=true])
详情
对一组数值向量
X
和
Y
进行分段三次 Hermite 多项式插值(PCHIP)。
参数
X
数值型向量,表示用于插值的点的 x 坐标(自变量)。
X
必须严格递增,且至少包含两个元素。
Y
与
X
等长的数值型向量,表示用于插值的点的 y 坐标(因变量)。
extrapolate
可选参数,布尔标量,表示当预测点超出已知数据范围时是否进行外插。默认为 true。
返回值
一个字典,包含以下键值对:
modelName:字符串“PchipInterpolate”,表示模型名称。
X:DOUBLE 向量,表示输入参数
X
。
extrapolate:BOOL 标量,即输入参数
extrapolate
。
coeffs:数值型向量,表示根据输入数据点拟合得到的多项式系数。
predict:模型的预测函数,可以通过
model.predict(X)
或
predict(model,
X)
调用,其中:
model:字典,即当前函数
pchipInterpolateFit
的返回。
X:数值型向量,表示需要求值的点的 x 坐标,
predict
函数将返回在
X
点处的插值结果。
例子
对 x 和 y 进行进行分段三次 Hermite 多项式插值。
def linspace(start, end, num, endpoint=true){
if(endpoint) return end$DOUBLE\(num-1), start + end$DOUBLE\(num-1)*0..(num-1)
else return start + end$DOUBLE\(num-1)*0..(num-1)
}
x_observed = linspace(0.0, 10.0, 11)[1]
y_observed = sin(x_observed)
model = pchipInterpolateFit(x_observed, y_observed)
model;
/* output:
modelName->PchipInterpolate
X->[0,1,2,3,4,5,6,7,8,9,10]
coeffs->#0 #1 #2 #3
------------------ ------------------ ------------------ ------------------
-0.32911446845195 -0.057707802943105 1.228293256202952 0
-0.01011863907468 -0.047589163868426 0.125534244960891 0.841470984807897
0.708356730424705 -1.476534149190519 0 0.909297426825682
0.637878921149598 -0.707803317410469 -0.827998107106924 0.141120008059867
0.074275580231352 0.053570618892506 -0.329967978479069 -0.756802495307928
-0.571482233207003 1.250991009671215 0 -0.958924274663138
-0.594663658922633 0.743530436118926 0.787535319721422 -0.279415498198926
-0.174138080617811 0.015904513331029 0.490605215191374 0.656986598718789
0.434603140426252 -1.011842901807877 0 0.989358246623382
0.046813296419378 -0.283076510213506 -0.719876382336998 0.412118485241757
extrapolate->true
predict->cubicHermiteSplinePredict
*/
相关函数:
predict
cubicHermiteSplineFit
FILE:references/doc_1459.md
# getConfig
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getConfig.html
**来源**: DolphinDB 官方文档
---
getConfig
语法
getConfig([key])
详情
获取系统配置信息。系统内部将配置项按安全级别划分为敏感、标准和不敏感三类。
敏感配置项:clusterReplicationExecutionPassword、s3SecretAccessKey、oauthClientSecret、metricsToken。
不敏感配置项:webLoginRequired、webModules、oauth、oauthWebType、oauthAuthUri、oauthRedirectUri、oauthClientId
、oauthAllowPasswordLoginNodes
。
标准配置项:除上述两类之外的其他配置。
当启用配置访问控制(
enableConfigAccessControl=true
)时,函数仅返回当前用户有权限访问的配置项;若未启用访问控制,则不进行权限验证。
不同用户权限说明
用户角色
不敏感配置
标准配置
敏感配置
未登录用户
可以查看
不能查看
不能查看
普通用户
可以查看
可以查看
不能查看
管理员用户
可以查看
可以查看
不能查看
配置参数详情可查看
参数配置
。
参数
key
是一个字符串,表示配置参数名称,为可选参数。
返回值
若不指定
key
,返回一个字典,包含当前用户有权限读取的所有配置项及其对应值。
若指定
key
若为有效配置参数且用户具有读取权限,返回字符串标量或向量,表示配置值;
若不是配置参数,或是有效配置但用户没有读取权限,则返回空值。
FILE:references/doc_1461.md
# unionAll
**URL**: https://docs.dolphindb.cn/zh/funcs/u/unionAll.html
**来源**: DolphinDB 官方文档
---
unionAll
语法
unionAll(tableA, tableB, [byColName=false])
或
unionAll(tables, [partition=true], [byColName=false])
或
unionAll(tables, tableB)
详情
第一种用法只能将两个表合并成一个表,返回的结果是未分区的内存表。
第二种用法可以多个表合并成一个表。如果
partition
为 false,返回的结果是未分区的内存表;如果
partition
为 true,返回的结果是一个顺序分区的内存表。默认值为 true。
当
byColName
=true 时,各表可有不同数量的列。若某列在某些表中不存在,结果中会以空值填充。
当
byColName
=false 时,各表必须有相同数量的列。
第三种用法是将多个表追加到指定的表,并返回该表。常用于
mr
函数的 finalFunc。
参数
用法一:
tableA
和
tableB
是列数相同的内存表。
用法二:
tables
是一个元组,其中每个元素都是一个表,并且它们具有相同的列数。
partition
是布尔值,表示是否进行顺序分区(SEQ),默认值是
true。
byColName
是一个布尔值。若设为
true,表示表合并时,依照列名进行,各表中相同列名的列进行合并,缺失的列用空值填充。若设为
false,表示表合并时仅基于列顺序,不管列名是否一致。
用法三:
tables
是一个元组,其中每个元素都是一个内存表,并且它们具有相同的列数。
tableB
是一个和
tables
中表列数相同的内存表。
注:
tableA
,
tableB
,
tables
支持以下内存表:table,
keyedTable, indexedTable, latestKeyedTable, latestIndexedTable。此外,用法三的
tableB
还可以是一个分区内存表。
返回值
一个表。
例子
用法一:合并两个内存表
t1=table(1 2 3 as id, 11 12 13 as x)
t2=table(4 5 6 as id, 14 15 16 as x)
re=unionAll(t1,t2)
re;
id
x
1
11
2
12
3
13
4
14
5
15
6
16
typestr(re);
// output
IN-MEMORY TABLE
用法二:合并多个内存表
t1=table(1 2 3 as id, 11 12 13 as x)
t2=table(4 5 6 as id, 14 15 16 as x)
t3=table(7 8 as id, 17 18 as x)
re=unionAll([t1,t2,t3])
select * from re;
id
x
1
11
2
12
3
13
4
14
5
15
6
16
7
17
8
18
typestr(re);
// output
SEGMENTED IN-MEMORY TABLE
指定 byColName:
t1=table(1 2 3 as id, 11 12 13 as x)
t2=table(14 15 16 as x, 4 5 6 as id)
unionAll(t1,t2,true);
id
x
1
11
2
12
3
13
4
14
5
15
6
16
t1=table(1 2 3 as id, 11 12 13 as x)
t2=table(14 15 16 as x, 4 5 6 as id)
unionAll(t1,t2);
id
x
1
11
2
12
3
13
14
4
15
5
16
6
上例中可见,若不指定
byColName
(即
byColName
=false),请务必确认各表中列名顺序一致,否则会产生错误结果。
t1=table(1 2 3 as id, 11 12 13 as x, 21 22 23 as y)
t2=table(4 5 6 as id, 14 15 16 as x)
unionAll(t1,t2,true);
id
x
y
1
11
21
2
12
22
3
13
23
4
14
5
15
6
16
t1=table(1 2 3 as id, 11 12 13 as x, 21 22 23 as y)
t2=table(4 5 6 as id, 14 15 16 as x)
unionAll(t1, t2) => The number of columns of the table to insert must be the same as that of the original table.
上例中可见,若各表中列数不一致,必须将
byColName
设为 true。
用法三:将多个内存表合并到分区内存表
def testFunc(data, off){
return select *, price * (1-off) as `discountPrice from data
}
n = 100
dates = 2021.01.01..2021.12.31
t = table(take(dates, 365 * n).sort() as `date, `sym + take(1..n, 365 * n).sort()$STRING as `sym, round(10 + norm(0, 2, 365 * n), 2) as `price)
db = database("", VALUE, 2021.01.01..2021.12.31)
trade = db.createPartitionedTable(table=t, tableName="trade", partitionColumns=`date).append!(t)
db = database("", RANGE, date(month(dates.first()) .. (month(dates.last()) + 1)))
outputT=table(1:0, `date`sym`price`discountPrice, [DATE,SYMBOL,DOUBLE,DOUBLE])
ports = db.createPartitionedTable(outputT, "ports", `date)
//map reduce
mr(sqlDS(<select * from trade>), testFunc{,0.3},,unionAll{,ports})
select * from ports
FILE:references/doc_147.md
# seasonalEsd
**URL**: https://docs.dolphindb.cn/zh/funcs/s/seasonalEsd.html
**来源**: DolphinDB 官方文档
---
seasonalEsd
语法
seasonalEsd(data, period, [hybrid], [maxAnomalies], [alpha])
详情
使用 S-ESD(Seasonal Extreme Studentized Deviate)
算法对周期性的时间序列进行异常检测。
参数
data
是一个数值向量,表示时间序列。
period
是一个大于1的整数,表示时间序列的周期。
hybrid
是一个布尔值,表示是否用中位数和绝对中位差代替 Grubb's test 中 zscore
计算的平均值和标准差。如果
hybrid
为 true,算法更具鲁棒性。默认值为 false。
maxAnomalies
是一个正整数或(0, 0.5)之间的浮点数。默认值为0.1。
如果
maxAnomalies
是正整数,且
maxAnomalies
必须小于
data 长度的一半,函数最多检测
maxAnomalies
个异常点。
如果
maxAnomalies
是(0, 0.5)之间的浮点数,函数最多检测
int(size(data) *
maxAnomalies
) 个异常点。
alpha
是一个正数,表示显著度。
alpha
越大,数据越有可能被判断为异常点。
返回值
返回结果是包含了异常值的表,该表有两列,index 列记录原始数据中异常值的下标,anoms 列记录异常值。
例子
定时执行一个函数:
n = 100
trend = 6 * sin(1..n \ 200)
seasonal = sin(pi / 6 * 1..n)
residual = rand(1.0, n) - 0.5
data = trend + seasonal + residual
data[20 50 70] += 20;
seasonalEsd(data, 12);
index
anoms
50
22.6365
70
21.141346
20
19.174165
相关函数:
stl
,
esd
FILE:references/doc_1470.md
# getSystemCpuUsage
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getSystemCpuUsage.html
**来源**: DolphinDB 官方文档
---
getSystemCpuUsage
语法
getSystemCpuUsage()
详情
返回当前节点上 DolphinDB 进程实时占用 CPU 的百分比。
注意,若 DolphinDB 进程占用多个 CPU,则返回各个 CPU 占用率的总和。
参数
无
返回值
DOUBLE 标量。
例子
getSystemCpuUsage();
// output: 1.771654
FILE:references/doc_1472.md
# cols
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cols.html
**来源**: DolphinDB 官方文档
---
cols
语法
cols(X)
详情
返回
X
中列的数目。参见相关函数:
rows
。
参数
X
可以是任意数据形式的对象。
返回值
INT 类型标量。
例子
x=1..6$2:3;
x;
#0
#1
#2
1
3
5
2
4
6
cols x;
// output
3
a=table(1..3 as x,`IBM`C`AAPL as y);
a;
x
y
1
IBM
2
C
3
AAPL
cols a;
// output
2
y=1 2 3;
cols(y);
// output
1
// 向量可以被视为一个 n*1 的矩阵
FILE:references/doc_1488.md
# getBackupStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getBackupStatus.html
**来源**: DolphinDB 官方文档
---
getBackupStatus
语法
getBackupStatus([userName])
详情
查看指定用户的 backup/restore 任务。
注:
一次 backup 执行过程产生的任务数与其备份的分区的个数相同。
管理员调用该函数时,若指定了
userName
,则返回指定用户的
backup/restore 任务;否则返回所有用户的 backup/restore 任务。
非管理员调用该函数时,只能返回当前用户的 backup/restore 任务。
参数
userName
表示用户名的字符串。
返回值
返回一个表,每一行为一个任务的信息。包含以下字段:
userName:用户名。
type:备份或恢复的类型。
BACKUP_BY_SQL/RESTORE_BY_SQL: 表示使用 SQL
元代码方式的备份/恢复。
BACKUP_BY_COPY_FILE/RESTORE_BY_COPY_FILE:表示使用拷贝文件方式的备份/恢复。
startTime:任务开始的时间。
dbName:数据库的路径。
tableName:表的名称。
totalPartitions:待备份/恢复的分区数量。
completedPartitions:完成备份/恢复的分区数量。
percentComplete:任务完成百分比。
endTime:若任务已完成,则返回任务完成的时间,否则返回预估完成时间。
completed :任务完成状态。若全部完成,则为1,否则为0。
例子
getBackupStatus()
userName
type
startTime
dbName
tableName
totalPartitions
completedPartitions
percentComplete
endTime
completed
u1
BACKUP_BY_COPY_FILE
2022.09.21T17:18:04.264
dfs://valuedb
pt
1
1
100
2022.09.21T17:18:04.269
1
u1
BACKUP_BY_SQL
2022.09.21T17:13:04.344
dfs://valuedb
pt
4
4
100
2022.09.21T17:13:04.413
1
u1
BACKUP_BY_COPY_FILE
2022.09.21T17:18:04.264
dfs://valuedb
pt1
1
1
100
2022.09.21T17:18:04.265
1
admin
BACKUP_BY_COPY_FILE
2022.09.21T16:47:42.798
dfs://valuedb
pt
4
4
100
2022.09.21T16:47:42.859
1
admin
BACKUP_BY_COPY_FILE
2022.09.21T16:37:33.725
dfs://valuedb
pt
4
4
100
2022.09.21T16:37:33.790
1
admin
BACKUP_BY_SQL
2022.09.21T15:10:05.016
dfs://compoDB
pt2
10
10
100
2022.09.21T15:10:05.075
1
FILE:references/doc_1493.md
# rowCount
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowCount.html
**来源**: DolphinDB 官方文档
---
rowCount
语法
rowCount(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行非空值的统计操作
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL]);
rowCount(m);
// output
[3,3,2]
t1=table(1 NULL 3 NULL 5 as x, 6..10 as y);
t2=table(5 NULL 3 NULL 1 as a, 10..6 as b);
rowCount(t1);
// output
[2,1,2,1,2]
rowCount(t1[`x], t2, 1 NULL 2 NULL NULL);
// output
[4,1,4,1,3]
t=table(`AAPL`MS`IBM`IBM`C as sym, [49.6, NULL, 29.52, NULL, 174.97] as price1, [175.23, NULL, 50.32, 51.29, 26.23] as price2);
select sym,rowCount(price1,price2) as count from t;
sym
count
AAPL
2
MS
0
IBM
2
IBM
1
C
2
相关函数:
rowSize
,
count
FILE:references/doc_15.md
# nullIf
**URL**: https://docs.dolphindb.cn/zh/funcs/n/nullIf.html
**来源**: DolphinDB 官方文档
---
nullIf
语法
nullIf(X, Y)
参数
X
和
Y
可以是标量或向量,也可以是返回标量或向量的表达式。
详情
若
X
和
Y
都是标量,比较
X
和
Y
的类型和值是否相同,若相同返回 NULL 值,否则返回 X。
若
X
和
Y
是等长的向量,则将
X
和
Y
的元素一一进行上述比较。
若
X
和
Y
一个是标量一个是向量,则将标量和向量中的元素一一进行上述比较。
例子
t = table(`APPL`IBM`AMZN`IBM`APPL`AMZN as sym, 10.1 11.2 11.3 12 10.6 10.8 as val)
select nullIf(sym, `AMZN) from t
输出返回:
nullIf_sym
APPL
IBM
IBM
APPL
select * from t where nullIf(sym, `AMZN)!=NULL
输出返回:
sym
val
APPL
10.1
IBM
11.2
IBM
12
APPL
10.6
FILE:references/doc_1506.md
# norm
**URL**: https://docs.dolphindb.cn/zh/funcs/n/norm.html
**来源**: DolphinDB 官方文档
---
norm
语法
norm(mean, std, count)
详情
返回一个长度(维度)为
count
的向量(矩阵),服从期望值为
mean
,标准差为
std
的正态分布。
参数
mean
数值型标量,表示正态分布的期望值。
std
数值型标量,表示正态分布的标准差。
count
整型标量或数据对。若为标量,表示输出向量的长度;若为数据对,表示输出矩阵的维度。
返回值
DOUBLE 类型向量或矩阵。
例子
norm(2.0,0.1,3);
// output
[2.026602,1.988621,2.101107]
mean norm(3,1,10000);
// output
3.007866
std norm(3,1,10000);
// output
0.995806
// 生成随机矩阵
norm(0, 1, 3:2)
col1
col2
-0.5399
-0.8475
-1.0029
1.811
-0.0485
-0.4339
FILE:references/doc_1523.md
# having
**URL**: https://docs.dolphindb.cn/zh/progr/sql/having.html
**来源**: DolphinDB 官方文档
---
having
having子句总是跟在group by或者context by后,用来将结果进行过滤,只返回满足指定条件组结果。
如果having用在group by后,having只可与聚合函数一起使用,结果为符合聚合函数条件的每组产生一条记录。
如果having用在context by后,并且只与聚合函数一起使用,结果是符合聚合函数条件的分组,每组记录与输入数据中记录数一致。
如果having用在context by后,与非聚合函数一起使用,结果是符合指定条件的分组。
例子
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t1 = table(timestamp, sym, qty, price);
t1;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
select sum(qty) as totalqty from t1 group by sym having sum(qty)>10000;
sym
totalqty
C
14800
IBM
12200
select * from t1 context by sym having count(sym)>2 and sum(qty)>10000;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
select * from t1 context by sym having rank(qty)>1;
timestamp
sym
qty
price
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
09:36:59
MS
3200
30.02
select * from t1 context by sym having rank(qty)>1 and sum(qty)>10000;
timestamp
sym
qty
price
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
在select语句中,对符合having条件的记录进行计算:
select *, min(qty) from t1 context by sym having rank(qty)>1;
timestamp
sym
qty
price
min_qty
09:34:26
C
2500
50.32
1300
09:38:12
C
8800
51.29
1300
09:36:59
MS
3200
30.02
1900
top语句可以与context by语句和having语句一起使用。
select top 2 * from t1 context by sym having sum(qty)>8000;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:34:16
C
1300
50.76
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
FILE:references/doc_1535.md
# getLoadedPlugins
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getloadedplugins.html
**来源**: DolphinDB 官方文档
---
getLoadedPlugins
语法
getLoadedPlugins()
详情
获取当前节点已加载的插件列表。
参数
无
返回值
一张表,包含以下字段:
plugin:STRING,插件名称。
version:STRING,插件的版本(
PluginXXX.txt
文件的版本)
user:STRING,加载该插件的用户名称。
time:TIMESTAMP,加载该插件的时间。
例子
login("admin","123456")
loadPlugin("zip")
login("user1","123456")
loadPlugin("httpclient")
getLoadedPlugins()
返回结果:
plugin
version
user
time
zip
3.00.1
admin
2024.09.01T10:00:01.000
httpClient
3.00.1
user1
2024.09.01T10:00:02.000
FILE:references/doc_1540.md
# fy5253Quarter
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fy5253Quarter.html
**来源**: DolphinDB 官方文档
---
fy5253Quarter
语法
fy5253Quarter(X, [weekday=0], [startingMonth=1],
[qtrWithExtraWeek=1], [nearest=true], [offset], [n=1])
详情
采用52-53周财年(4-4-5历),该函数返回X所在财政季度的起始日期。
如果
nearest
=true,表示将最接近
startingMonth
最后一天的
weekday
的日期作为财政年度的起始日期。
如果
nearest
=false,表示将
startingMonth
中最后一个
weekday
的日期作为财政年度的起始日期。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
个季度更新一次。注意,只有当
n
>1 时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
weekday
是0到6之间的整数,表示星期编号。0表示星期一,1表示星期二,... ,6表示星期日。默认值为0。
startingMonth
是1到12之间的整数,表示一年的起始月份。默认值是1。
qtrWithExtraWeek
是1到4之间的整数。如果有闰季(一般一个季度有13周,闰季有14周),它表示闰季所在的季度。
nearest
是一个布尔值。默认值为 true。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
fy5253Quarter(2019.12.01,0,1,1,true);
// output
2019.11.04
fy5253Quarter(2019.12.01,0,1,4,true);
// output
2019.10.28
// 2019年的财年起始日期是2019.01.28,2020年的财年起始日期是2020.02.03,两者相差53周,说明有一个闰季。qtrWithExtraWeek=1表示第一个季度为闰季,它包含14周,因此2019.12.01所在季度的起始日期为2019.11.01;qtrWithExtraWeek=4表示第4个季度为闰季,它包含14周,因此2019.12.01所在季度的起始日期是2019.10.28。
date=2016.01.12 2016.02.25 2016.05.12 2016.06.28 2016.07.10 2016.08.18 2016.09.02 2016.10.16 2016.11.26 2016.12.30
time = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12,09:38:13]
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
select avg(price),sum(qty) from t1 group by fy5253Quarter(date,0,1,1,true,2016.01.01,2);
fy5253Quarter_date
avg_price
sum_qty
2015.11.02
39.53
4100
2016.05.02
85.136667
21300
2016.10.31
51.835
13300
相关函数:
fy5253
FILE:references/doc_1547.md
# createGroup
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createGroup.html
**来源**: DolphinDB 官方文档
---
createGroup
语法
createGroup(groupId, [userIds])
详情
创建组。
组中的用户必须是已经创建了的用户。
注:
该函数只能由管理员在控制节点、数据节点和计算节点运行。
参数
groupId
是表示组名的字符串。只能包含字母、数字、下划线(_)、或短横线(-),且必须以字母开头,长度不得超过 30 个字符。
userId
是表示组成员的字符串标量或向量。
返回值
无。
例子
创建组 "production",并且把用户 "JohnSmith" 添加到该组。
createGroup(`production, `JohnSmith);
FILE:references/doc_1552.md
# mimaxLast
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mimaxlast.html
**来源**: DolphinDB 官方文档
---
mimaxLast
语法
mimaxLast(X, window, [minPeriods])
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
中最大元素的位置。如果窗口内存在多个相同的最大值,则返回右起第一个最大值的位置。与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
当
X
是向量时,返回一个整型向量,长度与输入向量相同。
当
X
是矩阵时,返回一个整型矩阵,形状与输入矩阵相同。
当
X
是表时,对表的每列进行计算,返回相应的结果。
当
X
是元组时,对元组中的每个向量分别计算,返回相应的结果。
例子
x = 1.2 2 NULL -1 6 -1
mimaxLast(x,3);
// output: [,,1,0,2,1]
m=matrix(3 2 4 4 2, 1 4 2 4 3);
mimaxLast(m,3)
#0
#1
2
1
2
2
1
1
t=table(3 3 2 as c1, 1 4 4 as c2)
mimaxLast(t,3)
#0
#1
1
2
x = [NULL, 2, NULL, NULL, 3.2]
date = [0, 1, 3, 8, 9] + 2020.01.01
X = indexedSeries(date, x)
mimaxLast(X, 3d)
#0
2020.01.01
-1
2020.01.02
1
2020.01.04
0
2020.01.09
-1
2020.01.10
1
相关函数:
mimax
FILE:references/doc_157.md
# loadPlugin
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadPlugin.html
**来源**: DolphinDB 官方文档
---
loadPlugin
语法
loadPlugin(filepath)
详情
加载 DolphinDB 插件。该函数必须要用户登录后才能执行。
注:
在产品体验阶段,如果未自行创建用户或管理员账号,可以使用 DolphinDB
提供的初始管理员账号(admin)及密码(123456)。在生产环境中,务必使用具备中等以上安全强度的用户或管理员密码。
加载前请确保有对应插件的使用权限。收费插件需要另行购买。
来自 DolphinDB 插件市场的插件在使用
installPlugin
命令安装后,会在
<server路径>/plugins/<插件名称>
路径下生成一个命名方式为
"Plugin" + "插件名称"的 txt 格式的插件描述文件和相关的二进制文件(Windows 版本下为 .dll,Linux 版本下为 .so)。例如,安装在
Windows 版本 DolphinDB server 2.00.10 的 odbc 插件描述文件存储于:
../DolphinDB_Win64_V2.
00.10
/server/plugins/odbc/PluginODBC.txt
该文件包含以下内容:
odbc,libPluginODBC.dll,2.00.10
odbcQuery,query,system,2,5,0
odbcConnect,connect,system,1,2,0
odbcClose,close,system,1,1,0
odbcExecute,execute,system,2,2,0
odbcAppend,append,system,3,5,0
该文件格式如下:
第一行:插件名称、lib 文件、版本号,用 “,” 分隔;
其他行用于描述该插件提供的函数,依次包含以下信息:lib 文件中的某个函数的名称、对应的 DolphinDB 函数的名称、函数的类型(operator
表示运算符,system 表示系统函数)、函数所需的最小参数个数、函数所需的最大参数个数、是否为聚合函数(1 表示聚合函数,0
表示非聚合函数)、是否为序列函数(1表示序列函数,0表示非序列函数)。
参数
filepath
是文本文件的绝对路径。例如:
/home/DolphinDB_Linux64_V2.00.10/server/plugins/mysql/PluginMySQL.txt
。
自2.00.11版本起,
可以将其指定为插件名(大小写敏感)。系统会根据插件名称和配置项
pluginDir
拼接出插件的加载路径。
返回值
无。
例子
加载来自插件市场的插件
以在 Windows 操作系统上安装 MQTT 插件为例,加载方法有两种:
使用插件描述文件的绝对路径加载插件:
installPlugin("mqtt")
loadPlugin("D:/TEST/DolphinDB_Win64_V2.00.10/server/plugins/mqtt/PluginMQTT.txt")
注:
在 Windows
操作系统中使用绝对路径加载插件时,务必确保路径中使用"/"代替"\"。
或指定插件名称:
installPlugin("mqtt")
loadPlugin("mqtt")
加载自行编译的插件
以 DolphinDB Linux 版本的 odbc 插件为例,其描述文件 odbc.txt 内容如下:
odbc,libPluginODBC.so,2.00.10
odbcQuery,query,system,2,5,0
odbcConnect,connect,system,1,2,0
odbcClose,close,system,1,1,0
odbcExecute,execute,system,2,2,0
odbcAppend,append,system,3,5,0
odbc 插件提供了 5 个函数:
query
,
connect
,
close
,
execute
和
append
,需要加载插件后才能使用。下面的例子介绍了如何加载 odbc 插件,并调用 odbc 插件提供的函数。
loadPlugin("/home/DolphinDB/server/plugins/odbc/odbc.txt")
//或者通过插件名进行加载
loadPlugin("odbc")
use odbc
ConnStr="Driver=MySQL;Data Source=odbc_test;Server=127.0.0.1;Uid=root;Pwd=123456;Database=odbc_test"
conn=connect(connStr) // 创建 MySQL 连接
t=query(conn,"select * from test")
close(conn)
FILE:references/doc_1571.md
# inverse
**URL**: https://docs.dolphindb.cn/zh/funcs/i/inverse.html
**来源**: DolphinDB 官方文档
---
inverse
语法
inverse(X)
详情
如果
X
可逆,返回矩阵
X
的逆矩阵。
参数
X
是一个矩阵。
返回值
如果
X
可逆,返回矩阵
X
的逆矩阵。否则报错。
例子
x=1..4$2:2;
x;
#0
#1
1
3
2
4
x.inverse();
#0
#1
-2
1.5
1
-0.5
FILE:references/doc_1581.md
# isort
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isort.html
**来源**: DolphinDB 官方文档
---
isort
语法
isort(X, [ascending=true])
详情
和
sort!
返回一个排序后的数组不同,
isort
返回排序后的每个元素在原始向量中的索引。
X[isort X] 等价于 sort(X)。
参数
X
是一个向量或一个由多个等长向量组成的元组。
ascending
是布尔值标量或向量,表示按升序排序还是按降序排序。默认值为 true(按升序排序)。
返回值
一个整型向量,表示排序后的每个元素在原始向量中的索引。
例子
x = 4 1 3 2;
y = isort(x);
y;
// output: [1,3,2,0]
// 对于排序后的 x: [1 2 3 4],第一个元素 1 在原始的 x 中的位置是 1,第二个元素 2 在原始 x 中的位置是 3,... 以此类推。
x[y];
// output: [1,2,3,4]
// 等价于 sort(x)
z=isort(x, false);
z;
// output: [0,2,3,1]
x[z];
// output: [4,3,2,1]
x=2 2 1 1
y=2 1 1 2
isort([x,y]);
// output: [2,3,1,0]
isort([x,y],[0,0]);
// output: [0,1,3,2]
基于表的单列排序:
t2 = table(4 2 3 1 as x, 9 6 7 3 as y);
t2;
x
y
4
9
2
6
3
7
1
3
t2[isort(t2.x)];
x
y
1
3
2
6
3
7
4
9
t2[isort(t2.x, false)];
x
y
4
9
3
7
2
6
1
3
基于表的多列排序:
a=5 5 5 3 3 8 7 7;
b=`MSFT`GOOG`IBM`YHOO`X`YHOO`C`ORCL;
t=table(a,b);
t;
a
b
5
MSFT
5
GOOG
5
IBM
3
YHOO
3
X
8
YHOO
7
C
7
ORCL
t[isort([a,b], false true)];
// 先基于 a 降序排序,再基于 b 升序排序
a
b
8
YHOO
7
C
7
ORCL
5
GOOG
5
IBM
5
MSFT
3
X
3
YHOO
t[isort([a,b], false)];
// 等价于 t[isort([a,b], false false)];
a
b
8
YHOO
7
ORCL
7
C
5
MSFT
5
IBM
5
GOOG
3
YHOO
3
X
FILE:references/doc_1594.md
# typestr
**URL**: https://docs.dolphindb.cn/zh/funcs/t/typestr.html
**来源**: DolphinDB 官方文档
---
typestr
语法
typestr(X)
详情
返回一个表明
X
的数据类型的字符串。详细信息参见
数据类型
。
参数
X
可以是系统支持的任意数据类型。
返回值
STRING 类型标量。
FILE:references/doc_1596.md
# cumvarp
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumvarp.html
**来源**: DolphinDB 官方文档
---
cumvarp
语法
cumvarp(X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累计总体方差。
返回值
DOUBLE 类型,其数据形式同
X
。
例子
cumvarp(1 2 3 NULL 4);
// output
[ , 0.25, 0.666666666666667, 0.666666666666667, 1.25]
m=matrix(1.1 3 5.0 7.5 9.2, 1 4.3 7.1 10.6 13.5);
m;
col1
col2
1.1
1
3
4.3
5
7.1
7.5
10.6
9.2
13.5
cumvarp(m);
col1
col2
0
0
0.9025
2.7225
2.5356
6.2156
5.6425
12.5025
8.5944
19.612
相关函数:
var
FILE:references/doc_1601.md
# ols
**URL**: https://docs.dolphindb.cn/zh/funcs/o/ols.html
**来源**: DolphinDB 官方文档
---
ols
语法
ols(Y, X, [intercept=true], [mode=0]
, [method="default"], [usePinv=true]
)
详情
返回对
X
和
Y
计算普通最小二乘回归的结果。需要注意的是,该函数会将
X
和
Y
中的空值替换为0后进行计算。
参数
Y
是因变量;
X
是自变量。
Y
是一个向量;
X
是一个向量、元组、矩阵或表。当
X
是矩阵时,如果行数等于
Y
的长度,
X
的每一列都是一个因子;如果行数不等于
Y
的长度,并且如果列数等于
Y
的长度,
X
的每一行都是一个因子。
intercept
是一个布尔变量,表示是否包含回归中的截距。默认值是 true。当它为 true 时,系统自动给
X
添加一列 "1"
以生成截距。
mode
是一个整数,默认值为 0,可取以下 3 个值
0:输出一个系数估计向量
1:输出一个具有系数估计,标准差,t 统计量和 p 值的表
2:输出一个具有 ANOVA(方差分析)、RegressionStat(回归统计)、Cofficient(系数)和
Residual(残差)的字典,具体含义见下表:
键 ANOVA 对应值:
Source of Variance
自由度(Degree of freedom)
平方和(Sum of Square)
均方差(Mean of square)
F统计量
Significance
Regression(回归)
变量个数(p)
回归平方和(SSR)
回归均方差(MSR=SSR/R)
MSR 对 MSE 的比值
显著性,即统计出的 P 值
Residual(残差)
残差自由度(n-p-1)
残差平方和(SSE)
残差均方差(MSE=MSE/E)
Total
样本自由度
不包括常数项(n-1)
总离差平方和(SST)
键 RegressionStat 对应值:
item
统计值
R2
R 决定系数,描述回归曲线对真实数据点拟合程度的统计量。范围在 [0,1]之间,越接近1
,说明对y的解释能力越强,拟合越好。
AdjustedR2
经自由度修正后的决定系数,通过样本数量与模型数量对 R-squared 进行修正。
StdError
回归残差标准误差,残差经自由度修正后的标准差。
Observations
观察样本个数。
键 Coefficient 对应值:
元素
说明
factor
自变量名称
beta
回归系数估计值
stdError
回归系数标准误差。
tstat
T统计值,衡量系数的统计显著性。
键 Residual 对应每一个预测值和实际值之间的残差。
method
是一个字符串,表示求解最小二乘问题采用的方法。
默认值为“default”,表示采用构造系数矩阵和逆矩阵的方式求解;
设置为“svd”,采用奇异值分解的方式。
usePinv
一个布尔值,表示计算过程中求矩阵的逆时,是否求矩阵的伪逆。
默认值为 true,表示求矩阵的伪逆,奇异矩阵必须指定为 true。
若为 false,表示求矩阵的逆,只适用于非奇异矩阵。
返回值
返回值形式由
mode
参数决定:
mode
=0:返回一个系数估计向量
mode
=1:返回一个表,包含系数估计,标准差,t 统计量和 p 值。
mode
=2:返回一个字典,包含 ANOVA(方差分析)、RegressionStat(回归统计)、Cofficient(系数)和
Residual(残差)。
例子
x1=1 3 5 7 11 16 23
x2=2 8 11 34 56 54 100
y=0.1 4.2 5.6 8.8 22.1 35.6 77.2;
ols(y, x1);
// output
[-9.912821,3.378632]
ols(y, (x1,x2));
// output
[-9.494813,2.806426,0.13147]
ols(y, (x1,x2), 1, 1);
factor
beta
stdError
tstat
pvalue
intercept
-9.494813
5.233168
-1.814353
0.143818
x1
2.806426
1.830782
1.532911
0.20007
x2
0.13147
0.409081
0.321379
0.764015
ols(y, (x1,x2), 1, 2);
// output
Coefficient->
factor beta stdError tstat pvalue
--------- --------- -------- --------- --------
intercept -9.494813 5.233168 -1.814353 0.143818
x1 2.806426 1.830782 1.532911 0.20007
x2 0.13147 0.409081 0.321379 0.764015
Residual->[6.525447,4.223774,-0.383487,-5.820153,-6.638199,-6.907387,9.000005]
RegressionStat->
item statistics
------------ ----------
R2 0.940241
AdjustedR2 0.910361
StdError 8.173444
Observations 7
ANOVA->
Breakdown DF SS MS F Significance
---------- -- ----------- ----------- --------- ------------
Regression 2 4204.416396 2102.208198 31.467739 0.003571
Residual 4 267.220747 66.805187
Total 6 4471.637143
x=matrix(1 4 8 2 3, 1 4 2 3 8, 1 5 1 1 5);
x;
#0
#1
#2
1
1
1
4
4
5
8
2
1
2
3
1
3
8
5
ols(1..5, x);
// output
[1.156537,0.105505,0.91055,-0.697821]
ols(1..5, x.transpose());
// output
[1.156537,0.105505,0.91055,-0.697821]
// 系统会调整因变量和自变量的维数,以便进行回归
x = table([13.9782,13.4688,13.4336,12.9642,12.7905,13.4771,13.0423,12.6588,13.8933,13.9006] as col0, [195.3904,181.4090,180.4627,168.0723,163.5973,181.6342,170.1017,160.2477,193.0241,193.2270] as col1, [2731.2089,2443.3656,2424.2715,2178.9356,2092.4947,2447.9167,2218.5185,2028.5594,2681.7456,2685.9754] as col2)
y = [-0.4002,-0.8004,-0.2002,-1.0002,-0.2001,-0.5001,-0.2501,0.0000,0.0000,0.0000]
ols(y, x, true, 0, "default")
[2.968166,13.023638,-2.016390,0.076485]
ols(y, x, true, 0, "svd")
[3266.457957,-722.195120,53.157806,-1.302769]
x1=1 1 1
x2=2 2 2
y = 1 1 1
ols(y, (x1, x2))
// output:[0.16666666666666669 0.16666666666666669 0.33333333333333326]
ols(y, (x1, x2), usePinv=false)
// ERR: The input matrix is singular and cannot be inverted.
由于在求解过程中,参与求逆的矩阵是奇异的,因此 usePinv=false 时报错。
相关函数:
olsEx
,
bvls
FILE:references/doc_1604.md
# miminLast
**URL**: https://docs.dolphindb.cn/zh/funcs/m/miminlast.html
**来源**: DolphinDB 官方文档
---
miminLast
语法
miminLast(X, window, [minPeriods])
窗口计算规则请参考:
滑动窗口系列(m 系列)
详情
在给定长度(以元素个数衡量或时间长度)的滑动窗口内计算
X
中最小元素的位置。如果窗口内存在多个相同的最小值,则返回右起第一个最小值的位置。与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
当
X
是向量时,返回一个整型向量,长度与输入向量相同。
当
X
是矩阵时,返回一个整型矩阵,形状与输入矩阵相同。
当
X
是表时,对表的每列进行计算,返回相应的结果。
当
X
是元组时,对元组中的每个向量分别计算,返回相应的结果。
例子
x = 1.2 2 NULL -1 6 -1
miminLast(x,3)
// output: [,,0,2,1,2]
m=matrix(3 2 2 4 2, 1 4 2 1 3);
miminLast(m,3)
#0
#1
2
0
1
2
2
1
t=table(3 2 2 as c1, 1 1 4 as c2)
miminLast(t,3)
#0
#1
2
1
x = [NULL, 2, NULL, NULL, 3.2]
date = [0, 1, 3, 8, 9] + 2020.01.01
X = indexedSeries(date, x)
miminLast(X, 3d)
#0
2020.01.01
-1
2020.01.02
1
2020.01.04
0
2020.01.09
-1
2020.01.10
1
相关函数:
mimin
FILE:references/doc_1605.md
# getOSBit
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getOSBit.html
**来源**: DolphinDB 官方文档
---
getOSBit
语法
getOSBit()
详情
查询 DolphinDB server 所在操作系统的位数。
参数
无
返回值
INT 类型标量。
例子
getOSBit();
// output: 64
FILE:references/doc_1608.md
# tokenizeBert
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tokenizeBert.html
**来源**: DolphinDB 官方文档
---
tokenizeBert
语法
tokenizeBert(text, vocabName, [addSpecialTokens=true])
详情
应用指定词库对输入文本
text
进行分词。本函数使用 WordPiece 分词算法,适用于 BERT(Bidirectional Encoder
Representations from Transformers) 模型。
参数
text
LITERAL 类型标量,待分词的字符串。
vocabName
字符串标量,指定用于分词的词库。
addSpecialTokens
可选参数,布尔值,表示是否要在文本的首尾添加特殊 token。目前仅支持在开头加入
[CLS]
,在结尾加入
[SEP]
。默认为 true。
返回值
返回一个表,包含以下三列:
tokens: 分词后的 token 列表。
input_ids: 对应的 token ID 列表。
attention_mask: 目前仅返回值为 1 的掩码,用于模型输入。
例子
loadVocab("/home/data/vocab.txt", "vocab1")
tokenizeBert("apple ```\n—— abcd1234", "vocab1", true)
相关函数:
loadVocab
,
unloadVocab
FILE:references/doc_1610.md
# kmeans
**URL**: https://docs.dolphindb.cn/zh/funcs/k/kmeans.html
**来源**: DolphinDB 官方文档
---
kmeans
语法
kmeans(X, k, [maxIter=300], [randomSeed], [init='random'])
详情
对训练集执行 K-Means 聚类。
参数
X
是一个表,表示训练集。
k
是一个正整数,表示要生成的聚类数。
maxIter
是一个正整数,表示质心更新的最大迭代次数。默认值是300。
randomSeed
是一个整数,表示质心初始化时随机算法的种子。默认值为 NULL。
init
可以是一个字符串或者一个矩阵,表示初始值的选择方式。默认值是 'random'。
若
init
是一个字符串,则可选参数为 'random' 或
'k-means++'。'random' 表示根据
randomSeed
随机生成,'kmeans++' 表示根据
kmeans++ 算法生成。
若
init
是一个矩阵,表示自定义的质心。其列数与表
X
需保持一致,行数为
k
。
返回值
返回一个字典,包含以下 key:
centers:一个
k
行 m 列的矩阵(m 是
X
的列数),包含各个类的质心坐标。
predict:一个聚类模型预测函数,数据类型是 FUNCTIONDEF。
modelName:字符串 'KMeans'。
model:保存的模型,数据类型为 RESOURCE,用于预测。
labels:一个向量,表示
X
中每一行数据对应的聚类的类标签。
例子
使用模拟数据训练一个 K-Means 模型:
t = table(100:0, `x0`x1, [DOUBLE, DOUBLE])
x0 = norm(1.0, 1.0, 50)
x1 = norm(1.0, 1.5, 50)
insert into t values (x0, x1)
x0 = norm(2.0, 1.0, 50)
x1 = norm(-1.0, 1.5, 50)
insert into t values (x0, x1)
x0 = norm(-1.0, 1.0, 50)
x1 = norm(-3.0, 1.5, 50)
insert into t values (x0, x1);
model = kmeans(t, 3);
model;
// output
centers->
#0 #1
--------- ---------
-1.048027 -3.809539
1.110899 1.24216
1.677974 -1.19158
predict->kmeansPredict
modelName->KMeans
model->KMeans
labels->[2,2,2,2,2,2,3,2,3,2,...]
FILE:references/doc_1617.md
# extractInstrument
**URL**: https://docs.dolphindb.cn/zh/funcs/e/extractInstrument.html
**来源**: DolphinDB 官方文档
---
extractInstrument
语法
extractInstrument(instrument)
详情
提取 INSTRUMENT 类型对象内部的数据。
参数
instrument
INSTRUMENT 类型标量,或由多个 INSTRUMENT 组成的元组。
返回值
instrument
是标量时,返回一个字典。
instrument
是元组时,返回一个由字典组成的元组。
例子
fxFwd1 = {
"productType": "Forward",
"forwardType": "FxForward",
"version": 0,
"expiry": 2025.10.08,
"delivery": 2025.10.10,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E6],
"strike": 7.2
}
fxFwdUsdCny = parseInstrument(fxFwd1)
fxFwd2 = {
"productType": "Forward",
"forwardType": "FxForward",
"version": 0,
"expiry": 2025.10.08,
"delivery": 2025.10.10,
"currencyPair": "EURCNY",
"direction": "Buy",
"notional": ["EUR", 1E6],
"strike": 8.2
}
fxFwdEurCny = parseInstrument(fxFwd2)
print extractInstrument([fxFwdUsdCny, fxFwdEurCny])
/* output
(productType->Forward
forwardType->FxForward
version->0
instrumentId->
expiry->2025.10.08
delivery->2025.10.10
currencyPair->USDCNY
direction->Buy
notional->("USD",1000000)
strike->7.200000000000001
domesticCurve->
foreignCurve->
,productType->Forward
forwardType->FxForward
version->0
instrumentId->
expiry->2025.10.08
delivery->2025.10.10
currencyPair->EURCNY
direction->Buy
notional->("EUR",1000000)
strike->8.199999999999999
domesticCurve->
foreignCurve->
)
*/
相关函数:
parseInstrument
FILE:references/doc_1619.md
# temporalParse
**URL**: https://docs.dolphindb.cn/zh/funcs/t/temporalParse.html
**来源**: DolphinDB 官方文档
---
temporalParse
语法
temporalParse(X, format)
别名:
datetimeParse
详情
把字符串转换成 DolphinDB 中的时序类型数据。如果系统不能识别时序格式,将返回 NULL。
DolphinDB 具有以下时序格式:
格式
含义
范围
yyyy
年份(4个数字)
1000-9999
yy
年份(2个数字)
00-99. (00-39: 2000-2039; 40-99: 1940-1999)
MM
月份
1月12日
MMM
月份
JAN, FEB, ... DEC (不区分大小写)
dd
日期
1月31日
HH
时(24小时制)
0-23
hh
时(12小时制)
0-11
mm
分钟
0-59
ss
秒
0-59
aa
上午/下午
AM, PM. (不区分大小写)
SSS
毫秒
0-999
nnnnnn
微秒
0-999999
nnnnnnnnn
纳秒
0-999999999
temporalParse
函数中的
format
参数有以下两种表示方式:
使用分隔符
对于
format
参数 ,除了 y, M, d, H, h, m, s, a, S, n
以外的符号的字符都可以作为分隔符。
format
参数中的分隔符需要与输入字符串中的分隔符一致。
temporalParse("14-02-2018","dd-MM-yyyy");
// output
2018.02.14
temporalParse("14-02-2018","dd/MM/yyyy");
// output
00d
temporalParse("14//02//2018","dd//MM//yyyy");
// output
2018.02.14
temporalParse("14//02//2018","dd/MM/yyyy");
// output
00d
temporalParse("14//02//2018","dd..MM..yyyy");
// output
00d
我们可以使用单个字母来简化格式。例如,使用 "y/M/d" 代替 "yyyy/MM/dd"。因为 "y" 可以表示
"yyyy" 和 "yy", 系统会根据数字的个数采用 "yyyy" 或 "yy"。
temporalParse("14-02-18","d-M-y");
// output
2018.02.14
temporalParse("2018/2/6 02:33:01 PM","y/M/d h:m:s a");
// output
2018.02.06T14:33:01
"MMM","SSS", "nnnnnn" , "nnnnnnnnn" 不能使用单个字母。
temporalParse("02-FEB-2018","d-MMM-y");
// output
2018.02.02
temporalParse("02-FEB-2018","d-M-y");
// output
00d
temporalParse("13:30:10.001","H:m:s.SSS");
// output
13:30:10.001
temporalParse("13:30:10.001","H:m:s.S");
// output
Invalid temporal format: 'H:m:s.S'. Millisecond (S) must have three digits.
temporalParse("13:30:10.008001","H:m:s.nnnnnn");
// output
13:30:10.008001000
temporalParse("13:30:10.008001","H:m:s.n");
// output
Invalid temporal format: 'H:m:s.n'. Nanosecond (n) must have six or nine digits.
temporalParse
函数解释输入字符串中数字个数的方式是非常灵活的。
temporalParse("2-4-18","d-M-yy");
// output
2018.04.02
temporalParse("2-19-6","H-m-s");
// output
02:19:06
temporalParse("002-019-006","H-m-s");
// output
02:19:06
对于毫秒,微秒和纳秒,对应的数字位个数必须是3, 6, 9。
temporalParse("2018/2/6 13:30:10.001","y/M/d H:m:s.SSS");
// output
2018.02.06T13:30:10.001
temporalParse("2018/2/6 13:30:10.01","y/M/d H:m:s.SSS");
// output
00T
temporalParse("2018/2/6 13:30:10.000001","y/M/d H:m:s.nnnnnn");
// output
2018.02.06T13:30:10.000001000
temporalParse("2018/2/6 13:30:10.0000010","y/M/d H:m:s.nnnnnn");
// output
00N
不使用分隔符
对于这种表示方式,
format
参数必须与上述表格中的格式对应,不能使用单个字母来表示格式。
temporalParse("20180214","yyyyMMdd");
// output
2018.02.14
temporalParse("122506","MMddyy");
// output
2006.12.25
temporalParse("155950","HHmmss");
// output
15:59:50
temporalParse("035901PM","hhmmssaa");
// output
15:59:01
temporalParse("02062018155956001000001","MMddyyyyHHmmssnnnnnnnnn");
// output
2018.02.06T15:59:56.001000001
参数
X
是一个字符串。
format
是表示时间序列对象格式的字符串。
返回值
时序类型标量或向量。
FILE:references/doc_1621.md
# tmbeta
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmbeta.html
**来源**: DolphinDB 官方文档
---
tmbeta
语法
tmbeta(T, Y, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间长度衡量)的移动窗口中,计算
Y
在
X
上的回归系数的最小二乘估计。
返回值
DOUBLE 类型向量。
例子
T = 1 1 1 2 5 6
X = 1 4 2 -1 2 4
Y = 2 5 -3 6 9 1
m = table(T as t,X as x, Y as y)
select *, tmbeta(t, y, x, 3) from m
t
x
y
tmbeta_t
1
1
2
1
4
5
1
1
2
-3
1.4286
2
-1
6
-0.3846
5
2
9
6
4
1
-4
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = 1 4 2 -1 2 4
Y = 2 5 -3 6 9 1
m = table(T as t,X as x, Y as y)
select *, tmbeta(t, y, x, 3d) from m
t
x
y
tmbeta_t
2021.01.02
1
2
2021.01.02
4
5
1
2021.01.04
2
-3
1.4286
2021.01.05
-1
6
-3
2021.01.07
2
9
1
2021.01.08
4
1
-4
select *, tmbeta(t, y, x, 1w) from m
t
x
y
tmbeta_t
2021.01.02
1
2
2021.01.02
4
5
1
2021.01.04
2
-3
1.4286
2021.01.05
-1
6
-0.3846
2021.01.07
2
9
-0.1818
2021.01.08
4
1
-0.4444
相关函数:
mbeta
,
beta
FILE:references/doc_1625.md
# getAuditLog
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getauditlog.html
**来源**: DolphinDB 官方文档
---
getAuditLog
语法
getAuditLog([userId], [startTime], [endTime], [opType])
详情
查询用户 userId 在 startTime 到 endTime 这段时间内完成的,类型为 opType 的 DDL 操作记录。
opType 的所有取值及其对应的 opDetail 示例如下:
opType
opDetail
Description
CREATE_DB
创建数据库
DROP_DB
删除数据库
CREATE_TABLE
创建维度表
CREATE_PARTITIONED_TABLE
创建分区表
DROP_TABLE
删除表
DROP_PARTITION
deletedPartitions=xxx
删除分区
RENAME_TABLE
tableName=[xxx], newTableName=[xxx]
给表重命名
SQL_DELETE
script=[xxx], deletedRows=xxx
SQL 语句 delete 数据
SQL_UPDATE
script=[xxx], updatedRows=xxx
SQL 语句 update 数据
UPSERT
insertedRows=xxx, updatedRows=xxx
调用函数 upsert! 更新数据
ADD_COLUMN
colName=[xxx], colType=[xxx]
增加列
SET_COLUMN_COMMENT
colName=[xxx], colComment=[xxx]
给列添加注释
TRUNCATE_TABLE
删除表所有数据并保留表结构
RENAME_COLUMN
colName=[xxx], newColName=[xxx]
给列重命名
REPLACE_COLUMN
colName=[xxx], colType=[xxx], newColType=[xxx]
调用函数 replaceColumn! 替换表中的列
DROP_COLUMN
columnName=[xxx]
删除列
ADD_RANGE_PARTITION
调用 addRangePartitions 增加 RANGE 类型分区
ADD_VALUE_PARTITION
调用 addValuePartitions 增加 VALUE 类型分区
APPEND
appendedRows=xxx
向 atomic='TRANS’ 的库表或向 atomic='CHUNKS’ 的库里的维度表中写入数据
APPEND_CHUNK_GRANULARITY
appendedRows=xxx
向 atomic='CHUNKS’ 的库里的分区表中写入数据
参数
userId
字符串标量或向量,表示要查询的用户。默认为 NULL,表示查询所有用户的 DDL 操作日志。
startTime
整数标量或者时间标量,时间标量支持DATE, MONTH, DATETIME, TIMESTAMP, DATEHOUR,
NANOTIMESTAMP 类型。表示查询的起始时间点。默认值为 1970.01.01 。
endTime
整数标量或者时间标量,时间标量支持DATE, MONTH, DATETIME, TIMESTAMP, DATEHOUR,
NANOTIMESTAMP 类型。表示查询的结束时间点。默认值为空,表示结束时间为当前时间。endTime 必须大于 startTime。
opType
字符串标量或向量,表示查询的操作类型。默认为 NULL,表示查询所有 DDL 操作类型。
注:
startTime 和 endTime 规定的是 DDL 操作结束的时间范围。
返回值
返回一个表,其结构如下:
列名
类型
含义
userId
STRING
执行操作的用户名称
startTime
NANOTIMESTAMP
事务的开始时间
endTime
NANOTIMESTAMP
事务的结束时间
dbName
STRING
数据库名
tbName
STRING
表名
opType
STRING
操作类型
opDetail
STRING
操作细节说明
tid
LONG
事务ID
cid
LONG
commit ID
remoteIp
IPADDR
提交该操作的客户端 IP
remotePort
INT
提交该操作的客户端端口
例子
// 用户 admin 进行一系列 DDL 操作
login("admin","123456")
n = 3
id = rand(`st0001`st0002`st0003`st0004`st0005, n)
sym = rand(`A`B, n)
tradeDate = take(2022.01.01..2022.01.10, 3)
val = 1..n
dummyTb = table(id, sym,tradeDate, val)
dbPath = "dfs://auditTest"
if(existsDatabase(dbPath)){dropDatabase(dbPath)}
db = database(directory=dbPath, partitionType=VALUE, partitionScheme=2022.01.01..2022.01.05, engine='TSDB')
pt = createPartitionedTable(dbHandle=db, table=dummyTb, tableName="snap", partitionColumns=`TradeDate, sortColumns=`id`tradeDate, keepDuplicates=ALL)
pt.append!(dummyTb)
renameTable(db, `snap, `snap_2)
// 查询 DDL 操作记录
getAuditLog()
返回:
userId
startTime
endTime
dbName
tbName
opType
opDetail
tid
cid
remoteIp
admin
2024.03.26 14:40:43.659196080
2024.03.26 14:40:43.676082419
dfs://auditTest
CREATE_DB
1
1
192.168.0.140
admin
2024.03.26 14:40:43.676154581
2024.03.26 14:40:43.687319577
dfs://auditTest
snap
CREATE_PARTITIONED_TABLE
2
2
192.168.0.140
admin
2024.03.26 14:40:45.135000207
2024.03.26 14:40:45.160530442
dfs://auditTest
snap
RENAME_TABLE
tableName=[snap], newTableName=[snap_2]
4
4
192.168.0.14
FILE:references/doc_1634.md
# bondYield
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bondyield.html
**来源**: DolphinDB 官方文档
---
bondYield
语法
bondYield(start, maturity, issuePrice, coupon, frequency, dayCountConvention,
bondType, settlement, price, priceType, [method='newton'], [maxIter=100],
[benchmark='Excel'])
详情
通过债券净价(Clean Price)或全价(Dirty Price)计算债券的到期收益率 (Yield To Maturity)。
注意:
如果结算日(settlement)距离到期日(maturity)不足一个票息期(coupon period),则收益率按以下方式计算:
部分参数说明:
A:票息期开始日至结算日之间的天数(应计利息天数)。
DSR:从结算日期到赎回日期之间的天数。
E :一个票息期内的天数。
如果在到期日之前有多个票息期,则通过牛顿法等优化算法迭代地调整收益率的值,使基于该收益率计算得到的债券净价接近用户输入的实际价格。本函数将收益率的初值设置为年息票利率(Annual
Coupon Rate)。
参数
注意:所有输入向量必须等长,输入标量将自动扩展以匹配其它向量的长度。
start
DATE 类型标量或向量,表示债券的起息日。
maturity
与
start
等长的 DATE 类型标量或向量,表示债券的到期日。
issuePrice
与
start
等长的数值型标量或向量,表示债券的发行价格。贴现债需指定真实发行价(通常小于100);其他债券通常为100。
coupon
数值型标量或向量,表示债券的票面利率。例如 0.03,表示票息为 3%。
frequency
整型或 STRING 类型的标量或向量,表示债券的付息频率。可选值为:
0/“Once”:到期一次还本付息
1/“Annual”:每年付息一次
2/“Semiannual:每半年付息一次
4/“Quarterly”:每季度付息一次
12/“Monthly”:每月付息一次
dayCountConvention
STRING 类型的标量或向量,表示债券的计息日数惯例。可选值为:
"Thirty360US":US (NASD) 30/360
"ActualActualISMA":实际/实际(ISMA 规则)
"Actual360":实际/360
"Actual365":实际/365
"Thirty360EU":欧洲 30/360
"ActualActualISDA":实际/实际(ISDA 规则)
bondType
STRING 类型标量或向量,表示债券的类型。可选值为:
"FixedRate":固定利率债券,定期按息票利率支付利息。
"Discount":贴现债券,没有利息支付,以贴现方式发行的债券,期末FV=面值。
"ZeroCoupon":零息债券,期末一次性支付利息和面值,期末FV=面值+利息。
settlement
DATE 类型标量或向量,表示债券的结算日,即购买日期。
price
数值型标量或向量,具体含义取决于 priceType 的取值:
当
priceType
为 "CleanPrice" 时,
price
表示债券的净价;
当
priceType
为 "DirtyPrice" 时,
price
表示债券的全价。
priceType
STRING 类型的标量或向量,用于指定债券价格类型,可选值为:
"CleanPrice":净价
"DirtyPrice":全价
method
可选参数,字符串标量或向量,表示求解收益率所使用的优化算法,可选值为:
"newton":表示使用 Newton 算法,默认值。
"brent":表示使用 brent 算法。
"nm":表示使用 Nelder-Mead 单纯形算法。
"bfgs":表示使用 bfgs 算法。
"lbfgs":表示使用 lbfgs 算法。
maxIter
可选参数,整型标量或向量,表示求解收益率时优化算法的最大迭代次数。默认值为 100。
benchmark
可选参数,STRING 类型标量,表示算法参考基准。目前仅支持 “Excel”(excel
中的算法)。
返回值
DOUBLE 类型标量或向量。
例子
bondYield(start=2023.01.01, maturity=2030.12.31, issuePrice=100, coupon=0.05, frequency=1, dayCountConvention="ActualActualISMA", bondType="FixedRate", settlement=2023.04.01, price=100.2143, priceType="CleanPrice", method = ['newton', 'nm', 'brentq', 'bfgs','lbfgs'])
// output: [0.049630,0.049628,0.049630,0.049630,0.049635]
相关函数
:
bondCalculator
FILE:references/doc_1645.md
# isDuplicated
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isDuplicated.html
**来源**: DolphinDB 官方文档
---
isDuplicated
语法
isDuplicated(X, [keep=FIRST])
详情
判断向量中是否包含重复值。如果输入向量中有多个重复值,
keep
的取值为 FIRST 表示,返回结果中第一个重复值对应位置的值为
false,其他重复值对应位置的值为 true。
keep
的取值为 LAST 表示,返回结果中最后一个重复值对应位置的值为
false,其他重复值对应位置的值为 true。
keep
的取值为 NONE 表示,返回结果中所有重复值对应位置的值都为 true。
参数
X
是一个向量或包含多个等长向量的元组。
keep
是一个常量,表示系统处理多个重复值的方式。它的取值可以是 FIRST, LAST 或 NONE。它是一个可选参数,默认值为 FIRST。
返回值
如果
X
是一个向量,返回的结果是一个与
X
长度相同的布尔向量。
如果
X
是一个元组,返回的结果是一个与
X
中每个元素等长的布尔向量。
例子
下面通过一个例子说明
keep
参数不同取值的区别。
v = [1,3,1,-6,NULL,2,NULL,1]
isDuplicated(v,FIRST);
//output: [false,false,true,false,false,false,true,true]
// 1在向量 v 中出现了三次,所在的位置是第0、第2和第7位,由于 isDuplicated 的第二个参数为 FIRST,因此返回结果中第0位为 false,第2和第7位为 true。
v = [1,3,1,-6,NULL,2,NULL,1]
isDuplicated(v,LAST);
//output: [true,false,true,false,true,false,false,false]
// 1在向量 v 中出现了三次,所在的位置是第0、第2和第7位,由于 isDuplicated 的第二个参数为 LAST,因此返回结果中第7位为 false,第0和第2位为 true。
v = [1,3,1,-6,NULL,2,NULL,1]
isDuplicated(v,NONE);
//output: [true,false,true,false,true,false,true,true]
// 1在向量 v 中出现了三次,所在的位置是第0、第2和第7位,由于 isDuplicated 的第二个参数为 NONE,因此返回结果中第0、第2位和第7位都为 true。
isDuplicated
函数可以去除表中的重复记录。
t=table(1 2 4 8 4 2 7 1 as id, 10 20 40 80 40 20 70 10 as val);
t;
id
val
1
10
2
20
4
40
8
80
4
40
2
20
7
70
1
10
select * from t where isDuplicated([id,val],FIRST)=false;
// 保留第一条重复的记录,去除表中其他重复的记录
id
val
1
10
2
20
4
40
8
80
7
70
下例展示
isDuplicated
判断 BLOB 类型数据。
a=[blob("s1"), blob("s2")]
isDuplicated(a)
//output: [false, false]
a1=[blob("s1"), blob("s2"), blob("s1"), blob("s2")]
isDuplicated(a1)
//output: [false, false, true, true]
FILE:references/doc_1649.md
# 会话窗口引擎
**URL**: https://docs.dolphindb.cn/zh/stream/session_window_engine.html
**来源**: DolphinDB 官方文档
---
会话窗口引擎
会话窗口可以理解为一个活动阶段(数据产生阶段)。其前后都是非活动阶段(无数据产生阶段)。
会话窗口引擎与时间序列引擎极为相似,它们计算规则和触发计算的方式相同。不同之处在于时间序列引擎具有固定的窗口长度和滑动步长,但会话窗口引擎的窗口不是按照固定的频率产生的,其窗口长度也不是固定的。以引擎收到的第一条数据的时间戳作为第一个会话窗口的起始时间。会话窗口收到某条数据之后,若在指定的等待时间内仍未收到下一条新数据,则(该数据的时间戳
+ 等待时间)是该窗口的结束时间。窗口结束后收到的第一条新数据的时间戳是新的会话窗口的起始时间。
以物联网场景为例,根据设备在线时间段的不同,可能某些时间段有大量数据产生,而某些时间段完全没有数据。若对这类特征的数据进行滑动窗口计算,无数据的窗口会增加不必要的计算开销。因此
DolphinDB 开发了会话窗口引擎,以解决此类问题。
会话窗口引擎由
createSessionWindowEngine
函数创建。其语法如下:
createSessionWindowEngine(name, sessionGap, metrics,
dummyTable, outputTable, [timeColumn], [useSystemTime=false], [keyColumn],
[updateTime], [useSessionStartTime=true], [snapshotDir],
[snapshotIntervalInMsgCount], [raftGroup], [forceTriggerTime])
它的大多数参数与 createTimeSeriesEngine 相同,唯一不同的是
sessionGap
和
useSessionStartTime
两个参数。
sessionGap
决定了一个会话窗口的结束时间,而
useSessionStartTime
则决定输出表中时间列是以各个窗口的起始时刻还是结束时刻为准。
其他参数的详细含义可以参考:
createSessionWindowEngine
。
计算规则
若某条数据之后,经过
sessionGap
指定的时间长度内,没有新数据到来,就进行一次窗口截断(以截断前最后一条数据的时间戳 +
sessionGap
作为窗口的结束时刻)。窗口结束后新到来的一条数据将触发该窗口的计算。
注:
若指定了
keyColumn
,则按照分组分别进行窗口计算。
应用示例
例1. 创建一个会话窗口引擎,在指定等待 5 毫秒内没有收到新数据时,该引擎就会结束当前窗口。
share streamTable(
1000
:
0
, `time`sym`volume, [TIMESTAMP, SYMBOL, INT])
as
trades
output1 = table(
10000
:
0
, `time`sym`sumVolume, [TIMESTAMP, SYMBOL, INT])
engine_sw = createSessionWindowEngine(name =
"engine_sw"
, sessionGap =
5
, metrics = <sum(volume)>, dummyTable = trades, outputTable = output1, timeColumn = `time, keyColumn=`sym)
subscribeTable(tableName=
"trades"
, actionName=
"append_engine_sw"
, offset=
0
, handler=append!{engine_sw}, msgAsTable=true)
n =
5
timev =
2018.10
.
12
T10:
01
:
00.000
+ (
1.
.n)
symv=take(`A`B`C,n)
volumev = (
1.
.n)%
1000
insert into trades values(timev, symv, volumev)
n =
5
timev =
2018.10
.
12
T10:
01
:
00.010
+ (
1.
.n)
volumev = (
1.
.n)%
1000
symv=take(`A`B`C,n)
insert into trades values(timev, symv, volumev)
n =
6
timev =
2018.10
.
12
T10:
01
:
00.020
+
1
2
3
8
14
20
volumev = (
1.
.n)%
1000
symv=take(`A`B`C,n)
insert into trades values(timev, symv, volumev)
select *
from
output1;
输出返回:
time
sym
sumVolume
2018.10.12T10:01:00.001
A
5
2018.10.12T10:01:00.002
B
7
2018.10.12T10:01:00.003
C
3
2018.10.12T10:01:00.011
A
5
2018.10.12T10:01:00.012
B
7
2018.10.12T10:01:00.013
C
3
2018.10.12T10:01:00.021
A
1
2018.10.12T10:01:00.022
B
2
2018.10.12T10:01:00.023
C
3
清理环境:
dropStreamEngine(`engine_sw)
unsubscribeTable(, tableName="trades", actionName="append_engine_sw")
重新创建会话引擎,此时指定
forceTriggerTime
为
1000ms,在引擎收到最后一条消息后,经过1000ms,将触发所有分组数据的计算和输出
share streamTable(
1000
:
0
, `time`sym`volume, [TIMESTAMP, SYMBOL, INT])
as
trades
output1 = table(
10000
:
0
, `time`sym`sumVolume, [TIMESTAMP, SYMBOL, INT])
engine_sw = createSessionWindowEngine(name =
"engine_sw"
, sessionGap =
5
, metrics = <sum(volume)>, dummyTable = trades, outputTable = output1, timeColumn = `time, keyColumn=`sym, forceTriggerTime=
1000
)
subscribeTable(tableName=
"trades"
, actionName=
"append_engine_sw"
, offset=
0
, handler=append!{engine_sw}, msgAsTable=true)
n =
5
timev =
2018.10
.
12
T10:
01
:
00.000
+ (
1.
.n)
symv=take(`A`B`C,n)
volumev = (
1.
.n)%
1000
insert into trades values(timev, symv, volumev)
n =
5
timev =
2018.10
.
12
T10:
01
:
00.010
+ (
1.
.n)
volumev = (
1.
.n)%
1000
symv=take(`A`B`C,n)
insert into trades values(timev, symv, volumev)
n =
6
timev =
2018.10
.
12
T10:
01
:
00.020
+
1
2
3
8
14
20
volumev = (
1.
.n)%
1000
symv=take(`A`B`C,n)
insert into trades values(timev, symv, volumev)
sleep(
1100
)
select *
from
output1;
再次查询输出表,可以得到以下结果:
time
sym
sumVolume
2018.10.12T10:01:00.001
A
5
2018.10.12T10:01:00.002
B
7
2018.10.12T10:01:00.003
C
3
2018.10.12T10:01:00.011
A
5
2018.10.12T10:01:00.012
B
7
2018.10.12T10:01:00.013
C
3
2018.10.12T10:01:00.021
A
1
2018.10.12T10:01:00.022
B
2
2018.10.12T10:01:00.023
C
3
2018.10.12T10:01:00.028
A
4
2018.10.12T10:01:00.034
B
5
2018.10.12T10:01:00.040
C
6
FILE:references/doc_1659.md
# Orca 实时计算平台
**URL**: https://docs.dolphindb.cn/zh/stream/orca.html
**来源**: DolphinDB 官方文档
---
Orca 实时计算平台
1. Orca 概述
随着多集群部署逐渐成为常态,企业对流数据产品提出了更高的要求。多集群的流数据访问、计算和运维需求日益复杂,而传统流计算架构难以应对复杂任务之间的依赖关系表达、资源调度与高可用需求,逐渐成为业务发展的瓶颈。
当前流计算方案面临以下核心问题:
编码复杂,出错率高
用户需要手动推导不同引擎间的表结构,自行编写并行逻辑、级联关系、资源清理等代码,导致编码繁琐且出错风险高。
暴露底层概念,心智负担重
缺乏抽象层,比如流表的发布依赖
share
关键字,用户还需理解共享会话机制等系统细节,导致使用门槛较高。
部署与运维复杂
用户需手动指定流任务部署在哪台物理节点上。节点重启后,整套流计算框架需要重新搭建,缺乏自动恢复机制。
运维操作割裂
查看流表、写入数据、引擎预热等操作必须连接到特定节点执行,不利于统一管理和自动化调度。
Orca 在 DolphinDB 现有流数据产品之上提供了一层抽象与增强,核心目标是:
计算抽象
提供一套声明式
API,支持链式编程风格,简化流计算框架构建流程。用户无需关心表结构推导、并行度拆分、级联订阅与资源清理。
自动调度
系统根据构建的流图,结合集群拓扑与资源状况,自动完成任务的部署与执行,无需用户干预。
计算任务高可用
通过内置 Checkpoint
机制,当节点发生故障或机器宕机时,可自动恢复至最近一次快照状态,确保计算任务不遗漏任何待处理的数据。
2. 核心概念
本节将介绍 Orca 的基础概念,包括声明式 API 的编程模型、流图的类别与生命周期、流表的作用划分、子图与流任务的拆解等。
2.1 全限定名
DolphinDB 支持数据目录(catalog),用于统一组织各类数据库对象,包括对分布式表的支持。现在,Orca 进一步扩展了 catalog
的应用范围,将流图、流表和流引擎也注册进 catalog 中,使用户能够通过一种统一的方式访问各类元素。
为了唯一标识 catalog 中的对象,当前版本采用了
<catalog>.<schema>.<name>
的三段式命名方式,称其为全限定名(Fully Qualified Name,FQN)。
在为对象命名时,用户只需指定 name,系统将自动补全 FQN:
catalog 由当前 catalog 决定
schema 根据对象是流图、流表、引擎分别命名为 orca_graph, orca_table, orca_engine。
2.2 声明式 API
Orca 提供了一套声明式 API(Declarative Stream API,DStream API),用于简洁地构建实时流计算图。该 API
屏蔽了底层并行调度、订阅关系、资源清理等复杂逻辑,让用户聚焦于业务本身的表达。
用户无需手动推导表结构,编写并行引擎构建逻辑,显式订阅数据,编写任务清理与销毁逻辑。系统会将用户定义的 DStream API 转换为 DolphinDB
的函数调用(如
streamTable
、
subscribeTable
、
createReactiveStateEngine
等),并自动封装为可调度的流任务分发至各个节点执行。
DStream API 主要包含以下几类调用:
节点定义类:如
source
,
buffer
,
sink
,
timeSeriesEngine
,
reactiveStateEngine
等;
节点修饰类:如
setEngineName
,
parallelize
,
sync
等;
边操作类:如
map
、
fork
等。
接口列表见
9. 附录
。用户的思维模式应类似构造链式数据结构:不断向尾部添加或修饰节点,逐步完成整个流图的拼装。
2.3 流图
使用 DStream API 构建的计算流程被抽象为一个有向无环图,即流图(Stream
Graph),其中每个节点代表一个流表或引擎,每条边表示节点之间的数据传递关系(如级联或订阅)。
流图可分为逻辑流图和物理流图:
逻辑流图
是用户调用 DStream API 一步步构建的流图,它代表实际业务逻辑。如图 2-1 所示。
物理流图
是用户提交(
submit
)逻辑流图时,系统经过添加私有流表、应用调度优化、拆分子图与并行任务等过程得到的流图,它定义了实际的流任务。如图
2-2 所示。
图
1
.
图 2-1 逻辑流表
图
2
.
图 2-2 物理流表
为了管理流图的生命周期,Orca 定义了一系列状态和状态转移。分别是:
building
:任务已调度。当前系统中任务未分发、正在执行级联或构建订阅。
running
:任务已构建。流计算任务正常运行。
error
:可恢复错误。例如任务出现资源上的异常,需要重新调度。
failed
:不可恢复错误。例如任务本身逻辑有误,需要用户介入修改脚本,或是运行时内存溢出。
destroying
:用户请求销毁流图。当前系统正在销毁。
destroyed
:流图已销毁。状态机终止。
2.4 流表
Orca 支持两类流表,用于数据中转与存储:
私有流表
是非持久化的流表,仅供当前流图使用,用于缓存中间结果、并行度匹配、多下游订阅等,不支持直接通过 SQL
语句查询。销毁流图时,会销毁流图中的所有私有流表。
公共流表
是持久化流表,可同时被多个流图订阅,用于与外部交互、持久化输出或作为数据源,可直接通过 SQL
语句查询。当无任何流图订阅某公共流表时,该表将自动销毁并释放其全限定名。
2.5 子图与流任务
当用户提交逻辑流图时,系统会对逻辑流图进行如下处理:
检查环
:通过拓扑排序检查是否成环,若存在环则报错;
添加流表
:添加私有流表缓存中间结果。比如某引擎存在多个输出或上下游节点并行度不同等情况。因为引擎只能级联输出,不可以被订阅,所以当有多个下游出现时,必须添加流表进行中转。上下游节点并行度不同时,需要中间流表,将上游数据汇总后按照下游并发度重新分发,这个过程称为
shuffle。
优化
:删除多余的新增私有流表。
分割子图
:将整个图拆分成并行度相同的、尽量长的
子图(Subgraph)
。这一步的目的是尽可能减少需要并行执行的任务数。
拆分计算任务
:在子图内按照并行度拆分出
流任务(Stream
Task)
。流任务是分发执行的单位,每个任务都会被调度到一个线程上运行,即一个流任务内部的引擎和流表构成级联关系,由一个线程按顺序执行。而流任务之间通过订阅传递数据。任务数的总量决定了系统线程的使用上限。Orca
会尽量减少任务数量以提升资源利用率。
添加 Channel
:为了在流任务执行 Checkpoint 时对齐 Barrier(在数据流中插入的标记,详见 Checkpoint
机制),系统需要添加 Channel 。
如图 2-3 所示,红色方框代表子图,蓝色方框代表流任务:
图
3
.
图 2-3 子图与流任务
3. 系统架构
Orca 采用典型的 Master-Worker 架构,结合 DolphinDB
的分布式文件系统(DFS)实现流图的自动部署、任务调度与容错恢复。系统中各组件职责明确,通过集中式状态管理,实现了高可用的流计算平台。
3.1 整体架构
Orca 架构如图 3-1 所示:
用户通过调用 Orca 接口,提交流图定义;
Stream Master 接收逻辑流图,并根据拓扑和资源状况生成物理流图和调度计划;
Stream Worker 负责实际构建流表与引擎、运行任务、进行 Checkpoint;
所有核心状态(包括流图结构、调度记录、流表位置、Checkpoint 元信息等)均持久化至 DFS 表;
系统内部通过心跳检测、状态上报与 Barrier 机制实现计算图的高可用运行。
图
4
.
图 3-1 Orca 架构
3.2 Stream Master
Stream Master 部署在控制节点(Controller)上,其职责如下:
接收用户请求(流图提交、删除、状态查询等);
接收 Stream Worker 的状态上报;
执行流图状态机(构建 → 运行 → 错误恢复 → 销毁);
分配任务到各个节点,管理并行度与资源隔离;
定时触发 Checkpoint,协调流图内所有任务执行快照;
维护元信息,持久化到 DFS 表。
3.3 Stream Worker
Stream Worker 部署在数据节点(data node)或计算节点(compute node),其职责如下:
接收 Stream Master 分发的任务,构建流表、引擎、级联与订阅结构;
执行并监控流任务(如聚合计算、状态计算、指标生成);
完成本地状态快照,上传Checkpoint。
Stream Worker 的数据处理完全在内存中实现,除公共流表以外,不做本地持久化。引擎状态通过 Checkpoint 记录。
4. 流任务调度
为实现任务的合理分发与高效执行,Orca
内置一套分布式调度算法,基于节点资源打分、调度规则匹配与流图拓扑解析,动态完成流任务的分配。系统还支持错误恢复重调度、计算组隔离等功能,确保资源隔离与运行稳定性。
4.1 调度原则
调度器遵循以下原则:
均衡负载
:优先将任务分配至空闲资源充足的节点,避免 CPU、内存或磁盘资源过载;
计算组隔离
:同一流图内的任务运行在同一计算组中;
流表调度约束
:公共流表部署在数据节点;
Siblings 任务亲和性
:具有相同上游和下游的任务称为 siblings 任务,将它们分配至同一节点,减少通信代价;
4.2 节点打分机制
系统根据每个候选节点的资源,计算一个评分值表示该节点的调度优先级。对不同节点类型采取不同的评分标准:
计算节点的评分由其 CPU 使用率和内存使用率计算得到。
数据节点的评分由其 CPU 使用率、内存使用率和磁盘使用率计算得到。
4.3 调度流程与任务分配
调度过程基于贪心策略,整体流程如下:
任务复杂度排序
:系统根据流任务中的算子数量,评估其复杂度,越复杂的任务越早被调度。
候选节点评分
:按前述规则计算所有符合调度约束的节点分数。
节点优先筛选:
若任务包含公共流表,则限定在数据节点中筛选;
若任务不包含公共流表,限定在同一个计算组内筛选计算节点;
若某一节点已分配同流图 siblings 任务 ,则增大其评分值。
任务分配
:将任务分配给得分最高的节点,并更新其评分值,确保后续任务感知当前负载变化。
5.计算任务高可用
为保障流计算任务在分布式环境中的稳定运行,Orca
通过流图级别的 Checkpoint 机制,在任何节点宕机、网络或存储故障场景下都能快速恢复计算任务,保证数据不丢失。
5.1 Checkpoint 机制
Orca 的 Checkpoint 实现基于 Chandy–Lamport 分布式快照算法,引入
Barrier
标记流图内部的数据流的一致性边界,从而获得全局一致快照。
Checkpoint 的核心流程如下:
Checkpoint Coordinator 组件定期触发 Checkpoint 任务,并向所有 source 节点注入 Barrier。
source 节点在收到 Barrier 后将其原子性地写入流表,并记录当前流表的数据偏移量(offset)。
流图中的引擎或流表在收到上游的 Barrier 时,将自身状态做一次快照,然后将 Barrier 向下游传递。
当 sink 节点收到 Barrier,标志其上游所有节点均已完成快照。当所有 sink 节点都收到 Barrier,标志此次 Checkpoint
完成。
5.2 端到端一致性
一致性语义包含以下两种类型:
AT_LEAST_ONCE:数据至少处理一次,即不会丢失,但可能会被重复处理。
EXACTLY_ONCE:数据仅处理一次,既不丢失,也不重复。
Orca 的端到端一致性是指从数据源( source 节点)到数据接收端( sink 节点)的一致性,包括 source 端一致性,计算任务(除
source、sink 外的中间节点)的一致性和 sink 端一致性。如前文所述,Checkpoint
机制已确保了计算任务的一致性。若要实现端到端的一致性,还需实现 source 端和 sink 端的一致性:
source 端一致性:
source
端的一致性依赖于系统在重启后能够从指定位置恢复数据。由于使用了持久化的流表,可通过偏移量(offset)记录数据的回放位置,因此 source
端天然实现一致性。
计算任务一致性 :
Orca 通过实现 Chandy-Lamport 分布式快照算法,保证计算任务在分布式环境中的全局一致性。
sink 端一致性
:sink 端一致性由流表类型决定,只有当除了 source 以外的所有公共流表都是 keyedStreamTable
或 latestKeyedStreamTable 时,依靠这两种流表的去重功能,将上游的重复数据过滤,才能实现端到端的EXACTLY_ONCE
一致性,否则只能实现端到端的 AT_LEAST_ONCE 一致性。
注:
EXACTLY_ONCE 由于依靠键值的去重功能实现,因此只能保证内存中数据的主键唯一性。当某一主键被持久化后,keyedStreamTable 和
latestKeyedStreamTable 仍然能够接受新插入的相同主键。
这种方案可以确保内存中数据键值的唯一性,而不是全局唯一性。尽管如此,仍足以应对多路写入或网络延迟可能导致的重复提交问题。
5.3 Barrier 对齐
对于 EXACTLY_ONCE 一致性,在引擎或流表传递 Barrier 的过程中,如果有多个上游,则需要等收到所有上游的 Barrier
后再做快照。这个过程称作 Barrier 对齐。
Orca 引入了轻量级中间组件 Channel,该组件位于除 source 节点外的所有流任务中,用于实现 Barrier 对齐:
Channel 位于引擎或流表的每一个上游通路上,接收到 Barrier 时会暂停该通路上的数据传输;
待所有 Channel 均收到 Barrier,则推动该流任务中所有下游引擎或流表依次完成快照。
完成后将 Barrier 转发至该任务的输出流表中,从而将其向下游传递。
6. 运维与权限
为了支持流计算任务的稳定运行与高效排障,Orca 提供了完善的运维接口与可视化支持。
6.1 流图运维
Orca 提供了丰富的运维函数,可对流图进行全面监控,详情请参考
9. 附录
。
6.2 可视化界面支持
除运维函数外,Orca 还提供了 Web 可视化模块,用于图形化展示流图结构与运行状态。该模块可展示当前集群中所有流图。图 6-1
展示了流图中某个节点的状态:
图
5
.
图 6-1 Web 可视化界面
6.3 权限控制
Orca 的权限控制基于 DolphinDB 权限系统:
提交、删除等对流图的操作要求用户具有 COMPUTE_GROUP_EXEC 权限。
7. 使用示例:构建一分钟 K 线聚合与指标计算流图
本节将通过一个完整示例,演示如何使用 Orca 构建一个流计算图,实现对逐笔交易数据的 1 分钟 K 线聚合和常见技术指标(如
EMA、MACD、KDJ)的实时计算。
整个流程共分为五步,以下所有脚本均在计算节点运行。本示例脚本在集群的 cnode1 节点执行,集群总览如下:
图
6
.
图 7-1 集群总览
7.1 准备工作
增加必要配置项:
在配置文件 cluster.cfg 中配置
persistenceDir
,用于持久化公共流表数据;
定义 catalog、指标函数与算子:
if (!existsCatalog("demo")) {
createCatalog("demo")
}
go
use catalog demo
编写技术指标函数:
@state
def EMA(S, N) {
return ::ewmMean(S, span = N, adjust = false)
}
@state
def RD(N, D = 3) {
return ::round(N, D)
}
@state
def HHV(S, N) {
return ::mmax(S, N)
}
@state
def LLV(S, N) {
return ::mmin(S, N)
}
@state
def MACD(CLOSE, SHORT_ = 12, LONG_ = 26, M = 9) {
DIF = EMA(CLOSE, SHORT_) - EMA(CLOSE, LONG_)
DEA = EMA(DIF, M)
MACD = (DIF - DEA) * 2
return RD(DIF, 3), RD(DEA, 3), RD(MACD, 3)
}
@state
def KDJ(CLOSE, HIGH, LOW, N = 9, M1 = 3, M2 = 3) {
RSV = (CLOSE - LLV(LOW, N)) \ (HHV(HIGH, N) - LLV(LOW, N)) * 100
K = EMA(RSV, (M1 * 2 - 1))
D = EMA(K, (M2 * 2 - 1))
J = K * 3 - D * 2
return K, D, J
}
定义聚合算子与指标算子:
aggerators = [
<first(price) as open>,
<max(price) as high>,
<min(price) as low>,
<last(price) as close>,
<sum(volume) as volume>
]
indicators = [
<time>,
<high>,
<low>,
<close>,
<volume>,
<EMA(close, 20) as ema20>,
<EMA(close, 60) as ema60>,
<MACD(close) as `dif`dea`macd>,
<KDJ(close, high, low) as `k`d`j>
]
7.2 构建流图并提交
使用 DStream API 定义流图,并提交。
g = createStreamGraph("indicators")
g.source("trade", `time`symbol`price`volume, [DATETIME,SYMBOL,DOUBLE,LONG])
.parallelize(`symbol,3)
.timeSeriesEngine(windowSize=60, step=60, metrics=aggerators, timeColumn=`time, keyColumn=`symbol)
.sync()
.buffer("one_min_bar")
.parallelize(`symbol,2)
.reactiveStateEngine(metrics=indicators, keyColumn=`symbol)
.sync()
.buffer("one_min_indicators")
g.submit()
等待流图状态转为 running 后再进行后续操作,期间可通过以下接口查看流图运行状态:
getStreamGraphMeta()
示例输出(已转为运行中):
id
fqn
status
semantics
checkpointConfig
...
df83...08
demo.orca_graph.indicators
running
at-least-once
...
...
如图 7-2 所示,在 Web 页面的流图监控模块中可以看到,cnode1 提交的流图在拆分后被分发至同属计算组 group1 的 cnode2 和 cnode3
执行。为确保计算资源隔离,系统不会将任务分发至其他计算组的节点。
图
7
.
图 7-2 流图监控
7.3 插入模拟数据
以下脚本模拟写入了股票的秒级 K 线数据:
sym = symbol(`600519`601398`601288`601857)
ts = 2025.01.01T09:30:00..2025.01.01T15:00:00
n =size(ts) * size(sym)
symbol = stretch(sym, n)
timestamp = take(ts, n)
price = 100+cumsum(rand(0.02, n)-0.01)
volume = rand(1000, n)
trade = table(timestamp, symbol, price, volume)
appendOrcaStreamTable("trade", trade)
7.4 查询结果
通过 SQL 获取 1 分钟聚合 K 线和指标:
select * from demo.orca_table.trade
select * from demo.orca_table.one_min_bar
select * from demo.orca_table.one_min_indicators
7.5 清理流图
以下脚本会清理流图中定义的所有引擎和流表:
dropStreamGraph("indicators")
8. 未来规划
为持续提升 Orca 的功能完备性、灵活性与性能表现,未来我们将围绕以下方向进行优化:
8.1 功能增强
跨集群能力:
支持跨 DolphinDB 集群的数据流动,包括跨集群订阅、跨集群流表访问以及跨集群 Join,满足多集群业务整合需求。
更丰富的状态控制能力:
支持计算任务的灵活管理,例如暂停计算、重置流图状态等,提升运维与调试便利性。
更精细的参数调整:
允许用户调整 DStream API
中自动生成的参数,如订阅参数(
subscribeTable
)、私有流表配置(
enableTableShareAndCachePurge
)等,实现更细粒度的性能调优。
声明式 API 的扩展:
丰富 API 能力,支持用户在定义流表时显式指定分区数,支持在同一流图中使用 sourceByName
等高级用法,提升图构建灵活性。
可选的高可用协议:
引入可选的流数据高可用协议,支持在不同容错级别与延迟表现之间灵活权衡,满足多样化业务需求。
可选的调度算法:
提供灵活的流图调度策略,支持高吞吐与低延迟之间的自定义权衡,进一步允许接入用户自定义调度算法。
8.2 性能优化
物理流图优化:
优化表连接性能,提升跨节点表连接的执行效率,减少数据 shuffle。
运行时优化:
用级联代替订阅,进一步减小时延,提升运行效率。
Checkpoint 性能优化:
针对 Barrier 对齐进行进一步优化,引入增量快照与异步快照机制,降低 Checkpoint
对计算性能的影响,缩短容错恢复时间。
9. 附录
Orca 提供了关于流图、流表、引擎、Checkpoint 等多种类型的接口:
分类
接口
功能简述
定义
createStreamGraph
创建一个 StreamGraph 对象
StreamGraph::setConfigMap
设置图的私有流表和订阅的配置项
StreamGraph::source / keyedSource / latestKeyedSource /
haSource / haKeyedSource
定义流图输入源流表
StreamGraph::sourceByName
获取一个 Orca 创建的公共流表
DStream::anomalyDetectionEngine
定义异常检测引擎
DStream::asofJoinEngine
定义 asof join 引擎
DStream::crossSectionalEngine
定义横截面计算引擎
DStream::cryptoOrderBookEngine
定义数字货币实时订单簿引擎
DStream::dailyTimeSeriesEngine
定义日级时间序列引擎
DStream::dualOwnershipReactiveStateEngine
定义 Dual Ownership 响应式状态引擎
DStream::narrowReactiveStateEngine
定义生成窄表的响应式状态引擎
DStream::orderBookSnapshotEngine
定义订单簿引擎
DStream::reactiveStateEngine
定义响应式状态引擎
DStream::reactiveStatelessEngine
定义响应式无状态引擎
DStream::ruleEngine
定义规则引擎
DStream::sessionWindowEngine
定义会话窗口引擎
DStream::timeBucketEngine
定义自定义窗口长度(长度相同或不同)的时间序列聚合引擎
DStream::timeSeriesEngine
定义时间序列聚合引擎
DStream::equalJoinEngine
定义等值连接引擎
DStream::leftSemiJoinEngine
定义左半等值连接引擎
DStream::lookupJoinEngine
定义 lookup join 引擎
DStream::snapshotJoinEngine
定义快照连接引擎
DStream::windowJoinEngine
定义窗口连接引擎
DStream::buffer / keyedBuffer /
latestKeyedBuffer
定义中间结果流表
DStream::sink / keyedSink / latestKeySink / haSource /
haKeyedSource
定义数据输出流表
DStream::map
定义数据转换逻辑
DStream::udfEngine
创建支持副作用和状态持久化的自定义函数
DStream::fork
定义流图分叉
DStream::parallelize
设置并行度
DStream::sync
汇总上游计算结果
DStream::setEngineName
设置当前引擎名称
DStream::getOutputSchema
获取表结构用于下游定义
DStream::timerEngine
定义一个时间触发引擎
流图管理
StreamGraph::submit
提交流图以启动运行
getStreamGraph
获取流图对象
dropStreamGraph
销毁流图
purgeStreamGraphRecords
删除流图记录
startStreamGraph / stopStreamGraph
启、停流图
DStream::timerEngine / stopTimerEngine /
resumeTimerEngine
提交、暂停、恢复基于时间触发的任务
流表操作
appendOrcaStreamTable
向流表插入数据
useOrcaStreamTable
远程调用并操作指定流表
select * from orca_table.<name> 或select * from
<catalog>.orca_table.<name>
查询流表内容
引擎操作
warmupOrcaStreamEngine
预热流引擎以提升首批计算效率
监控运维
getStreamGraphInfo/getStreamGraphMeta
获取流图元信息
getOrcaStreamTableMeta
获取流表元信息
getOrcaStreamEngineMeta
获取流引擎元信息
getOrcaStreamTaskSubscriptionMeta
获取订阅元信息
getOrcaStateMachineEventTaskStatus
获取状态机任务状态
StreamGraph::toGraphviz / str
输出拓扑结构
getUdfEngineVariable
查询自定义函数中指定外部变量的当前值。
stopTimerEngine
暂停由
DStream::timerEngine
提交的任务
resumeTimerEngine
恢复执行由
DStream::timerEngine
提交的任务。
Checkpoint 管理
setOrcaCheckpointConfig
配置 Checkpoint 参数
getOrcaCheckpointConfig
查看 Checkpoint 配置
getOrcaCheckpointJobInfo
查看 Checkpoint Job 运行信息
getOrcaCheckpointSubjobInfo
查看 Checkpoint 子任务运行信息
FILE:references/doc_1661.md
# isNanInf
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isNanInf.html
**来源**: DolphinDB 官方文档
---
isNanInf
语法
isNanInf(X, [includeNull=false])
详情
检测
X
中的每一个元素是否为 NaN 或 Inf。若
includeNull
设为 true,NULL
值会被视为 Nan 或 Inf,默认为 false。
参数
X
是 DOUBLE 类型的标量/向量/矩阵。
includeNull
是一个布尔值。
返回值
返回布尔类型,数据形式同 X。
相关函数:
countNanInf
FILE:references/doc_1696.md
# 3.00.4
**URL**: https://docs.dolphindb.cn/zh/rn/server/3_00_4.html
**来源**: DolphinDB 官方文档
---
3.00.4
注:
同时建议阅读
兼容性说明
。
版本下载
版本号:3.00.4 二级兼容 3.00.3
发行日期: 2025-09-05
下载地址:
最新版:
https://dolphindb.cn/product#downloads
历史版本:
https://dolphindb.cn/history-versions
新功能
新增配置项
oauthAllowPasswordLoginNodes
,指定允许使用账号密码方式登录的节点别名。(
3.00.4.2
)
新增函数
attributeTypes
,用于获取类中所有属性及其对应的类型。(
3.00.4.2
)
MCP Server 支持(
3.00.4.2
):
从 dify 连接;
DolphinDB Server 为集群模式部署。
低延时引擎增加 License 控制,需申请特殊 License 才可使用。(
3.00.4.2
)
socp
函数新增返回退出代码(Exitcode)。(
3.00.4.2
)
新增函数
bondInstrumentCalculator
,用于实现债券到期收益率、净价和全价三者之间的互算。(
3.00.4.1
)
新增支持在单点登录流程中使用 HTTP 协议。(
3.00.4.1
)
新增配置项
maxRecursiveDepth
,用于设置最大递归深度。(
3.00.4.1
)
新增函数
histogram
,用于计算数据样本的直方图。(
3.00.4.1
)
新增系列函数,用于获取金融工具的对应成员值。(
3.00.4.1
)
新增支持 UserDefined 类型金融工具。(
3.00.4.1
)
新增函数
bondYieldCurveBuilder
,用于构建债券收益率曲线(到期推即期)。
新增函数
irSingleCurrencyCurveBuilder
,用于构建单货币利率互换收益率曲线。
新增函数
irCrossCurrencyCurveBuilder
,用于构建交叉货币利率互换(外币隐含收益率)曲线。
新增函数
fxVolatilitySurfaceBuilder
,用于构建外汇期权波动率曲面。
新增函数
bondPricer
,用于单张债券的定价。
新增函数
bondFuturesPricer
,用于国债期货合约的定价。
新增函数
irDepositPricer
,用于存款的定价。
新增函数
irFixedFloatingSwapPricer
,用于固定-浮动利率互换合约的定价。
新增函数
fxForwardPricer
,用于外汇远期合约的定价。
新增函数
fxSwapPricer
,用于外汇掉期合约的定价。
新增函数
fxEuropeanOptionPricer
,用于外汇欧式期权合约的定价。
新增函数
instrumentPricer
,用于对金融合约进行批量定价。
新增函数
portfolioPricer
,用于金融合约组合定价。
新增函数
parseInstrument
,用于序列化金融合约成 INSTRUMENT 类型对象。
新增函数
parseMktData
,用于序列化市场数据成 MKTDATA 类型对象。
新增函数
extractInstrument
,用于反序列化 INSTRUMENT 对象。
新增函数
extractMktData
,用于反序列化 MKTDATA 对象。
新增函数
curvePredict
,用于在给定的曲线上,预测指定时间的值。
新增函数
optionVolPredict
,用于在给定的波动率曲面上,预测指定时间和执行价的波动率。
新增函数
StreamGraph::updateRule
和
StreamGraph::deleteRule
,用于持久化更新 Orca 规则引擎的规则集。
新增函数
DStream::udfEngine
,用于创建支持副作用和状态持久化的自定义函数;新增函数
getUdfEngineVariable
查询
DStream::udfEngine
中定义的外部变量值。
新增函数
getOrcaDataLineage
用于查询流图数据表的血缘关系和 Orca 时间触发引擎的任务信息。
新增函数
createNearestJoinEngine
和 Orca API
DStream::nearestJoinEngine
,用于创建流计算最近邻关联引擎。
新增函数
StreamGraph::dropGraph
,用于销毁流图。
新增函数
renameCatalogName
,用于修改全限定名的
name
部分
。
新增函数
createOrcaStreamTable
,
createOrcaKeyedStreamTable
,
createOrcaLatestKeyedStreamTable
,
createOrcaHaStreamTable
,
createOrcaHaKeyedStreamTable
,用于在不创建流图的前提下创建
Orca 流表。
新增函数
dropOrcaStreamTable
,用于删除 Orca 流表。
新增
addMCPTool
,
updateMCPTool
,
dropMCPTool
,
callMCPTool
,
listMCPTools
,
publishMCPTools
,
withdrawMCPTools
用于开发管理 MCP tools。
新增
addMCPPrompt
,
updateMCPPrompt
,
dropMCPPrompt
,listMCPPrompts
,
getMCPPrompt
,
publishMCPPrompts
,
withdrawMCPPrompts
,用于开发管理
MCP prompt 模板。
新增权限 MCP_MANAGE,MCP_DEVELOP,MCP_EXEC。
新增函数
getClusterVolumeUsage
,用于检查集群中各节点的磁盘使用情况。
函数
createTimeBucketEngine
,
createNarrowReactiveStateEngine
,
createCryptoOrderBookEngine
,
createOrderBookSnapshotEngine
,
createRuleEngine
,
createReactiveStatelessEngine
新增参数
snapshotDir
和
snapshotIntervalInMsgCount
支持快照机制。
新增函数
getIPConnectionLimit
,
setIPConnectionLimit
,用于根据 IP 管理外部连接数。
新增流式 SQL 功能,用于对实时数据的持续查询和即时更新。
新增函数
matchFuzzy
,用于 TextDB 模糊匹配查找。
新增函数
getExecDir
和
getWorkDir
,用于获取 dolphindb
可执行文件所在目录和启动 dolphindb 时的工作目录。
新增配置项
enableRawScriptLog
,
rawScriptLogRetentionTime
,
maxRawScriptLogSize
用于控制是否记录原始脚本及其执行信息的日志,并设置日志的保存周期和文件大小上限。同时新增函数
getRawScriptLog
,用于查询所有原始脚本日志。
新增函数
recursiveSplitText
,可根据分隔符对文本进行递归分段。
新增文本向量化功能。
新增配置项
enableSharedVarCreationControl
,用于控制是否允许用户创建共享变量。
新增函数
createExternalTable
用于创建外部表。
多集群管理支持表连接。
新增函数
dropDataViewEngine
用于删除 CEP 引擎中指定的 DataView 引擎。
新增配置项
processVectorFunctionOverTupleByRow
,用于控制处理向量函数在处理元组(所有元素是标量或等长向量)或字典时的应用方式。
新增函数
createOrderReconstituteEngine
用于还原缺失的原始委托信息。
新增配置项
streamingRaftLearners
和
crossClusterRaftWorkerNum
用于配置 Raft
Learner 节点。
新增函数
semiannualBegin
,
semiannualEnd
用于返回日期所在半年期的第一天和最后一天。
新增函数
startStreamGraph
和
stopStreamGraph
用于控制流图的运行状态。
新增函数
roll
,与 CONTEXT BY 搭配使用,用于定义自定义滑动窗口。
新增配置项
streamingRaftGroupAliases
,用于为已配置的 Raft 组指定别名。
功能优化
函数
createorderbooksnapshotengine
支持将上交所基金的即时成交信息统计到委托明细。(
3.00.4.2
)
优化
subscribeTable
的线程分配算法,在不指定
hash
时
优先分配空闲线程。(
3.00.4.2
)
优化
getStreamingStat
,数据没有被消费时,subWorkers 表仍会显示
workerId。(
3.00.4.2
)
优化单点登录(SSO)流程(
3.00.4.2
):
修复 SSO 请求中默认端口导致的 HTTP 请求错误问题。
优化
oauthUserField
配置项,支持从嵌套 JSON 中解析用户名。
优化债券和国债期货的 instrument 和 marketData 的匹配规则。(
3.00.4.2
)
优化语法异常信息,新增输出出错所在的行号。(
3.00.4.2
)
createCrossSectionalEngine
支持处理列式元组。(
3.00.4.1
)
优化 licenseServer 客户端启动流程,支持备机认证启动。(
3.00.4.1
)
优化 Orca 流图中输出数据时出现表结构不一致时的报错信息。
函数
getStreamGraphInfo
返回增加引擎的
metric
信息。
函数
StreamGraph::haSource
、
StreamGraph::haKeyedSource
、
DStream::haBuffer
、
DStream::haKeyedBuffer
、
DStream::haSink
、
DStream::haKeyedSink
的参数
raftGroup
支持使用 Raft 组的别名。
函数
subscribeTable
支持跨集群订阅 Orca 流表。
支持对 Orca 流表进行权限管理。
函数
dropStreamGraph
新增参数
includeTables
,用于设置在删除流图时是否同时删除该流图中用户显式创建的流表。
函数
createGPLearnEngine
新增参数
dimReduceCol
, 支持挖掘降频因子。
Shark Graph 新增支持 rowAvg,rowSkew, rowVar, rowVarp, rowStd, rowStdp 算子。
优化磁盘管理机制。
提升对 TIMESTAMP 类型列按天进行值分区,查询日期最大值/最小值时的性能。
优化分区剪枝,提升形如
select * from t where id in ids
的查询在 ids 为 TABLE
类型时的剪枝性能。
提升查询 VALUE 分区表时,过滤条件包含对分区列的 < 或 <= 运算情况下的查询性能。
优化系统高并发场景的性能。
优化脚本引擎,提升表达式执行性能。
createOrderBookSnapshotEngine
支持输出
residualDetail(剩余委托明细)中的 ResidualBidOrderNoList 和
ResidualAskOrderNoList。
withdrawDetail(撤单明细)中的 withdrawBuyOrderNoList 和
withdrawSellOrderNoList。
createCryptoOrderBookEngine
输入表的 eventTime 列支持 NANOTIMESTAMP
类型。
license
函数支持获取指标平台、回测和模拟撮合模块名称 Beluga、 Backtest 和
MatchingEngineSimulator,以及产品名称 ORCA,DOLPHINX
函数
getStreamingStat
新增参数
stat
,用于指定需要返回的状态表名。
函数
sliceByKey
新增参数
preserveOrder
,用于设置是否按照
rowKeys
中值的顺序返回结果。
函数
createTimeSeriesEngine
和
createDailyTimeSeriesEngine
的参数
metrics
支持常量标量或向量。
TextDB 新增参数
scoreColName
用于查询文本匹配得分。
函数
log
新增参数
Y
,用于设置底数。
函数
at
的参数
X
支持整型向量。
函数
replay
的参数
outputTables
支持设置为
setStreamTableTimestamp
指定过时间戳列的流表。
函数
addEventListener
的参数
handler
支持调用 monitor
类之外的函数。
函数
reverse
支持内存表和有序字典。
字典、元组支持双目运算。
函数
rank
,
enlist
支持字典。
调用
dropStreamEngine
释放流数据分发引擎时,强制终止后台线程。
优化
getConsoleJobs
返回字段 jobType 和 desc 信息。
函数
parseJsonTable
支持解析 JSON 中的数组。
create table 增加参数校验。
函数
loadText
支持解析 TIME/SECOND/NANOTIME 类型为 TIME/NANOTIME 类型,解析
DATETIME/TIMESTAMP 类型为NANOTIMESTAMP。
故障修复
adfuller
在
regression
='n' 时,若返回值中的 adfStat>0,则 pValue
计算错误。(
3.00.4.2
)
响应式状态引擎开启低延时时,写入数据导致节点偶发崩溃。(
3.00.4.2
)
从 3.00.0.x - 3.00.2.x 升级至 3.00.4.x 时,旧版本中若存在包含 Catalog
相关脚本的函数视图或定时作业,可能导致节点无法启动。(
3.00.4.2
)
在使用
update ... context by ...
语句更新共享内存表时,系统报错:A snapshot table
doesn't support data update。(
3.00.4.2
)
通过
INSERT
语句插入数据时,如果某列以连续两个 VOID 类型的 NULL
开头,插入将失败。(
3.00.4.2
)
将 SYMBOL 类型字段设置为 TSDB 引擎的 sortKey,导致节点偶发崩溃。(
3.00.4.2
)
若在
createReactiveStateEngine
的
metrics
中使用无状态函数,并且通过
as
指定的返回值别名与该函数的入参同名,则会报错。(
3.00.4.2
)
通过 WebSocket 订阅流表时,即使过滤结果为空仍会向前端推送数据。(
3.00.4.2
)
registerStreamingSQL
解析驼峰命名的字段名失败。(
3.00.4.2
)
createReactiveStateEngine
的
metrics
返回多个数组向量时报错。(
3.00.4.2
)
在计算组的计算节点上执行 WHERE 子句包含
true==true
的查询时报错。(
3.00.4.2
)
在 3.00.X 版本集群上订阅 2.00.X 版本集群发布的流数据失败。(
3.00.4.2
)
在计算二重积分时,若积分上下限设置为 NULL,
integral
函数报错。(
3.00.4.1
)
由于
mr
函数缺少入参类型验证,在传入空的数据源时,导致 server 崩溃。(
3.00.4.1
)
在
createReactiveStateEngine
的
metrics
中非法使用自定义类方法,导致
server 崩溃。(
3.00.4.1
)
在高可用集群中,当控制节点配置 lanCluster=0 时,从节点无法安全关机。(
3.00.4.1
)
在并发提交多个任务时,偶发任务调度异常导致系统无法响应。(
3.00.4.1
)
在高可用集群中,当各 controller 并发执行
getClusterPerf
的数量超过工作线程的数量时,可能导致系统无响应。(
3.00.4.1
)
流订阅包含 ANY 类型字段的数据时偶发报错。(
3.00.4.1
)
当通过
enableTableShareAndCachePurge
设置自动清理共享流数据表时,如果订阅是通过断开连接而非
unsubscribe
取消的,缓存数据未能被正确清理,导致表行数超过设定的
cacheSize
限制。(
3.00.4.1
)
SQL 聚合计算偶发导致服务器崩溃。(
3.00.4.1
)
getUserHardwareUsage
返回的内存值可能因自动类型转换错误导致精度不足,从而出现异常(负数)。该问题由
2.00.15 版本引入。(
3.00.4.1
)
SQL 语句内换行,行首为运算符报错。(
3.00.4.1
)
在执行分区更新后,TSDB 引擎过度打印日志导致日志文件异常增大并占满磁盘。此为 2.00.15 版本引入的问题。(
3.00.4.1
)
向通过
setStreamTableTimestamp
指定时间戳列的流表中插入空向量数据时可能导致系统崩溃。(
3.00.4.1
)
查询表时,如果聚合计算的 GROUP BY 列包含 BLOB 类型可能发生内存泄漏。此为 2.00.11
版本引入的问题。(
3.00.4.1
)
通过
subscribeTable
订阅流表时,若
filter
参数指定的函数中输出表结构与输入流表不一致,系统不会输出数据,也不会报错。(
3.00.4.1
)
写入 TSDB 数据库时,若 symbol 数量超过上限,导致系统卡死。(
3.00.4.1
)
增加配置项访问安全校验:
新增配置项
enableConfigAccessControl
,用于控制在访问配置项时是否启用权限校验。(
3.00.4.1
)
新增函数
getOauthClientSecret
,用于管理员用户安全地获取敏感配置项
oauthClientSecret
的值。(
3.00.4.1
)
修改函数
getConfig/getConfigure
执行逻辑,当启用配置访问控制时,将会依据配置项安全级别及当前用户权限过滤返回结果。(
3.00.4.1
)
当流式 SQL 左连接的左表先更新数据,右表再更新数据时,结果不符合预期。(
3.00.4.1
)
当流式 SQL 查询的键值表写入单条包含列式元组的数据时报错。(
3.00.4.1
)
某些特殊字符导致
bfill
函数处理错误。
事务意外终止后立即重启,临时文件没有回收。
启用客户端高可用时,controller 内存泄漏。
当系统处于高负载时,定时任务偶发不执行,订阅偶发卡住。
在分级存储数据迁移过程中,因意外中断而导致文件残留。
SYMBOL 列包含以 '\r' 结尾的数据时可能导致的查询失败。
特殊情况下 IoTEngine 内存泄漏。
线程退出时偶发未完全回收资源而导致泄露。
分区很多时(大于1000万),从数据节点恢复控制节点元数据失败。
CEP 引擎中不支持
isVoid
等函数。
在 SELECT 子句中为 GROUP BY 字段指定别名时报错。
使用
interval
的查询结果不符合预期。
并发访问流表时偶发卡住。
IMOLTP 引擎在删除数据时内存不释放。
mstd
,
mstdp
,
mvar
,
mvarp
等函数在
X
无法填满
window
时可能错误地返回 0。
当
mstdp
,
mvarp
函数的
X
是首元素为 NULL
的向量时,计算结果不符合预期。
使用
dropCatalog
删除 catalog 时,未同时删除其内部 Orca 流图。
废弃功能
已弃用函数 createPricingEngine。(
3.00.4.1
)
FILE:references/doc_1706.md
# olsEx
**URL**: https://docs.dolphindb.cn/zh/funcs/o/olsEx.html
**来源**: DolphinDB 官方文档
---
olsEx
语法
olsEx(ds, Y, X, [intercept=true], [mode=0])
详情
返回对
X
和
Y
计算普通最小二乘回归的结果。
X
和
Y
是分布式表中的列。
注:
该函数会将
X
和
Y
中的空值替换为0后进行计算。
因为
olsEX
不支持输出残差,可以通过
residual
获取残差。
参数
ds
是存储在元组中的数据源集合。它通常是由
sqlDS
函数生成。
Y
是一个字符串,表示
ds
表中因变量的列名。
X
是字符串标量或向量,表示
ds
表中自变量的列名。
intercept
是一个布尔变量,指示是否包含回归中的截距。默认值是 true。当它为 true 时,系统自动给
X
添加一列 "1" 以生成截距。
mode
是一个整数,默认值为 0,取以下 3 个值之一
0:输出一个系数估计向量
1:输出一个具有系数估计,标准差,t统计量和p值的表
2:输出一个具有 ANOVA(方差分析)、RegressionStat(回归统计)和 Cofficient(系数)的字典,具体含义见下表:
键 ANOVA 对应值:
Source of Variance
自由度(Degree of freedom)
平方和(Sum of Square)
均方差(Mean of square)
F 统计量
Significance
Regression(回归)
变量个数(p)
回归平方和(SSR)
回归均方差(MSR=SSR/R)
MSR 对 MSE 的比值
显著性,即统计出的P值
Residual(残差)
残差自由度(n-p-1)
残差平方和(SSE)
残差均方差(MSE=MSE/E)
Total
样本自由度
不包括常数项(n-1)
总离差平方和(SST)
键RegressionStat对应值:
item
统计值
R2
R 决定系数,描述回归曲线对真实数据点拟合程度的统计量。范围在 [0,1]之间,越接近1
,说明对y的解释能力越强,拟合越好。
AdjustedR2
经自由度修正后的决定系数,通过样本数量与模型数量对 R-squared 进行修正。
StdError
回归残差标准误差,残差经自由度修正后的标准差。
Observations
观察样本个数。
键Coefficient对应值:
元素
说明
factor
自变量名称
beta
回归系数估计值
stdError
回归系数标准误差。标准差越大,回归系数的估计值越不靠谱。
tstat
T 统计值,衡量系数的统计显著性。
返回值
返回值形式由
mode
参数决定:
mode
=0:返回一个系数估计向量
mode
=1:返回一个表,包含系数估计,标准差,t 统计量和 p 值。
mode
=2:返回一个字典,包含 ANOVA(方差分析)、RegressionStat(回归统计)、Cofficient(系数)和
Residual(残差)。
例子
n=10000
ID=rand(100, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
vol=rand(1..10 join int(), n)
price=rand(100,n)
t=table(ID, date, vol,price)
saveText(t, "/home/DolphinDB/Data/t.txt");
if(existsDatabase("dfs://rangedb")){
dropDatabase("dfs://rangedb")
}
db = database(directory="dfs://rangedb", partitionType=RANGE, partitionScheme=0 51 101)
USPrices=loadTextEx(dbHandle=db,tableName=`USPrices, partitionColumns=`ID, filename="/home/DolphinDB/Data/t.txt");
ds=sqlDS(<select vol as VS, price as SBA from USPrices where vol>5>)
rs=olsEx(ds, `VS, `SBA, true, 2)
rs;
// output
RegressionStat->
item statistics
------------ ----------
R2 0.000848
AdjustedR2 0.000628
StdError 1.404645
Observations 4535
ANOVA->
Breakdown DF SS MS F Significance
---------- ---- ----------- -------- -------- ------------
Regression 1 7.592565 7.592565 3.848178 0.049861
Residual 4533 8943.739298 1.973029
Total 4534 8951.331863
Coefficient->
factor beta stdError tstat pvalue
--------- -------- -------- ---------- --------
intercept 7.953084 0.04185 190.039423 0
SBA 0.001422 0.000725 1.961677 0.049861
FILE:references/doc_1710.md
# 单节点部署与升级
**URL**: https://docs.dolphindb.cn/zh/tutorials/standalone_server.html
**来源**: DolphinDB 官方文档
---
单节点部署与升级
本教程用于单节点的部署、升级、过期 License 升级,并对常见问题做出解答,便于用户快速上手 DolphinDB。包含以下主题:
在 Linux 操作系统部署 DolphinDB 单节点
第一步:下载
官方下载地址:https://dolphindb.cn/product#downloads
也可以通过 Shell 指令下载。下载方式如下:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_Vrelease.zip -O dolphindb.zip
其中,
release
代表版本。例如:下载 2.00.11.3 版本的 Linux64 server,使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_V2.00.11.3.zip -O dolphindb.zip
如需下载 ABI 或 JIT 版本 server,则需要在版本号后以下划线连接 ABI 或 JIT。例如:下载 2.00.11.3 版本的 Linux64 ABI server, 使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_V2.00.11.3_ABI.zip -O dolphindb.zip
下载 2.00.11.3 版本的 Linux64 JIT 版本 server,使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_V2.00.11.3_JIT.zip -O dolphindb.zip
以此类推。
执行以下 Shell 指令解压安装包至指定路径(
/path/to/directory
):
unzip dolphindb.zip -d </path/to/directory>
注意
: 安装路径的目录名中不能含有空格字符或中文字符,否则启动数据节点时会失败。
第二步:更新软件授权许可
如果用户拿到企业版试用授权许可,只需用其替换如下文件即可。
/DolphinDB/server/dolphindb.lic
如果用户没有申请企业版试用授权许可,可以直接使用程序包中的社区版试用授权许可。社区试用版指定 DolphinDB 单节点最大可用内存为 8GB,有效期为20年。
第三步:启动单节点
进入
/DolphinDB/server
目录,第一次启动时需要修改文件权限,执行以下 Shell 指令:
chmod +x dolphindb
前台运行
执行以下 Shell 指令:
./dolphindb
系统默认端口号是8848。如果需要指定其它端口(例如8900)可以执行以下 Shell 指令:
./dolphindb -localSite localhost:8900:local8900
后台运行
执行以下 Shell 指令:
sh startSingle.sh
可以执行以下 Shell 指令以验证节点是否成功启动:
ps aux|grep dolphindb
返回如下信息说明后台启动成功:
第四步:Web 管理界面检查节点运行状态
在浏览器中输入部署服务器 IP 地址和部署端口号(默认是 8848)即可进入 Web 管理界面,
教程中的部署服务器 IP 地址为 10.0.0.82,部署端口为 8848,所以访问地址为 10.0.0.82:8848,
打开后的 Web 管理界面如下:
注意
:如果浏览器与 DolphinDB 不是部署在同一台服务器,应事先关闭防火墙或者打开对应的部署端口,Web 管理界面才能正常打开。
在 Windows 操作系统部署 DolphinDB 单节点
第一步:下载
官方下载地址:http://www.dolphindb.cn/downloads.html
解压安装包,例如解压到如下目录:
C:\DolphinDB
注意
:安装路径的目录名中不能含有空格字符或中文字符,否则启动数据节点时会失败。例如不要装到 Windows 系统的
Program Files
目录下。
第二步:更新软件授权许可
如果用户拿到企业版试用授权许可,只需用其替换如下文件即可:
C:\DolphinDB\server\dolphindb.lic
如果用户没有申请企业版试用授权许可,可以直接使用程序包中的社区版试用授权许可。社区试用版指定 DolphinDB 单节点最大可用内存为 8GB,有效期为 20 年。
第三步:启动单节点
进入
C:\DolphinDB\server
目录,可以看到如下内容:
前台运行
双击运行
dolphindb.exe
,出现如下界面:
系统默认端口号是 8848,可以通过修改配置文件
dolphindb.cfg
中的
localSite
参数指定其它端口。
后台运行
双击运行
backgroundSingle.vbs
,然后打开 Windows 任务管理就可以查看到 DolphinDB 后台进程:
也可以打开命令提示符,执行以下指令查看 DolphinDB 后台进程,确认是否启动成功:
tasklist|findstr "dolphindb"
第四步:Web 管理界面检查节点运行状态
在浏览器中输入部署服务器 IP 地址和部署端口号(默认是 8848)即可进入 Web 管理界面,
教程中的部署服务器 IP 地址为 10.0.0.82,部署端口为 8848,所以访问地址为 10.0.0.82:8848,
打开后的 Web 管理界面如下:
注意
:如果浏览器与 DolphinDB 不是部署在同一台服务器,需要关闭防火墙或者打开对应的部署端口,web 管理界面才能正常打开。
单节点升级
Linux 单节点升级
第一步:正常关闭单节点
进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
./stopAllNode.sh
第二步:备份旧版本的元数据文件
单节点元数据的默认存储目录:
/DolphinDB/server/local8848/dfsMeta/
/DolphinDB/server/local8848/storage/CHUNK_METADATA/
可在
/DolphinDB/server
目录执行以下 Shell 指令备份单节点元数据:
mkdir backup
cp -r local8848/dfsMeta/ backup/dfsMeta
cp -r local8848/storage/CHUNK_METADATA/ backup/CHUNK_METADATA
注意
:元数据文件可能通过配置文件指定存储在其它目录,如果在默认路径没有找到上述文件,可以通过查询配置文件中的
dfsMetaDir
参数和
chunkMetaDir
参数确认元数据文件的存储目录。若配置中未指定
dfsMetaDir
参数和
chunkMetaDir
参数,但是配置了
volumes
参数,则
CHUNK_METADATA
目录在相应的
volumes
参数指定的目录下。
第三步:升级
注意
:当 server 升级到某个版本后,使用的插件也应升级到与此对应的版本。
在线升级
进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
./upgrade.sh
运行后将会出现如下提示:
输入 y 并点击回车后会出现如下提示:
输入 1 选择在线更新,并点击回车后会出现如下提示:
输入所需更新的版本号再点击回车即可,以更新至 2.00.9.1 版本为例,输入 2.00.9.1 后点击回车,出现如下界面则表示升级成功:
离线升级
下载升级所需版本的安装包,官方下载地址:
http://www.dolphindb.cn/downloads.html
。
将下载好的安装包上传至
/DolphinDB/server/clusterDemo
目录下,以更新至 2.00.9.1 版本为例:
进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
./upgrade.sh
运行后将会出现如下提示:
输入 y 并点击回车后会出现如下提示:
输入 2 选择离线更新,并点击回车后会出现如下提示:
输入所需更新的版本号再点击回车即可,以更新至 2.00.9.1 版本为例,输入 2.00.9.1 后点击回车,出现如下界面则表示升级成功:
第四步:重新启动单节点
进入
/DolphinDB/server
目录执行以下 Shell 指令,后台运行 DolphinDB:
sh startSingle.sh
成功启动后,打开 Web 管理界面,在交互编程界面执行以下代码,查看 DolphinDB 当前版本:
version()
Windows 单节点升级
第一步:正常关闭单节点
如果是前台运行,关闭前台程序窗口
如果是后台运行,打开 Windows 任务管理器,找到 DolphinDB 的后台进程并关闭
第二步:备份旧版本的元数据文件
单节点元数据的默认存储目录:
C:\DolphinDB\server\local8848\dfsMeta\
C:\DolphinDB\DolphinDB\server\local8848\storage\CHUNK_METADATA\
进入
C:\DolphinDB
目录,在该目录下创建文件夹
backup
,
然后把
C:\DolphinDB\server\local8848
文件夹下的
dfsMeta
文件及
C:\DolphinDB\server\local8848\storage
文件夹下的
CHUNK_METADATA
文件复制到上面创建的
backup
文件夹下,
如下图所示:
注意
:元数据文件可能通过配置文件指定存储在其它目录,如果在默认路径没有找到上述文件,可以通过查询配置文件中的
dfsMetaDir
参数和
chunkMetaDir
参数确认元数据文件的存储目录。若配置中未指定
dfsMetaDir
参数和
chunkMetaDir
参数,但是配置了
volumes
参数,
CHUNK_METADATA
目录在相应的
volumes
参数指定的目录下。
第三步:升级
下载所需升级版本的安装包,官方下载地址:https://dolphindb.cn/product#downloads
将新版本
server
目录下除
dolphindb.cfg
以及
dolphindb.lic
外的所有文件覆盖替换旧版文件
第四步:重新启动单节点
双击运行
dolphindb.exe
后在前台运行 DolphinDB。
成功启动后,打开 Web 管理界面,在交互编程界面执行以下代码,查看 DolphinDB 当前版本:
version()
授权许可文件过期更新
第一步:替换授权许可文件
用新的授权许可文件
dolphindb.lic
替换旧的授权许可文件。
Linux 环境授权许可文件位置:
/DolphinDB/server/dolphindb.lic
Windows 环境授权许可文件位置:
C:\DolphinDB\server\dolphindb.lic
第二步:更新授权许可文件
在线更新
打开 Web 管理界面,在交互编程界面执行以下代码完成更新:
updateLicense()
注意
:在线更新有如下要求:
License 授权的客户名称必须与原来的 License 相同。
授权的节点个数,内存大小,CPU 核数不能比原来的小。
更新只在执行该函数的节点生效。因此在集群环境下,需要在所有控制节点、代理节点、计算节点和数据节点上运行该函数。
License 的类型必须是 commercial(付费)类型和 free 类型。
离线更新
关闭 DolphinDB 后,重新启动,即可完成更新。
常见问题解答(FAQ)
端口被其它程序占用导致启动失败怎么办?
DolphinDB 单节点默认启动端口是 8848,如果遇到无法启动 DolphinDB 的情况,
建议打开
/DolphinDB/server
目录下的
dolphindb.log
日志文件,若出现如下错误:
<ERROR> :Failed to bind the socket on port 8848 with error code 98
说明选用的端口被其他程序占用,导致 DolphinDB 无法正常启动,修改配置文件中的端口为其它空闲端口后即可正常启动。
Web 管理界面无法访问怎么办?
DolphinDB 正常启动后,在浏览器输入正确的访问地址,但 Web 管理界面无法正常打开,如下图所示:
出现上述问题的原因通常是由于浏览器与 DolphinDB 不是部署在同一台服务器,
且部署 DolphinDB 的服务器开启了防火墙。可以通过关闭部署了 DolphinDB 的服务器的防火墙或者打开对应的部署端口,解决这个问题。
Linux 升级失败如何版本回退?
如果升级以后,不能正常开启单节点 DolphinDB ,可按以下方式回退到旧版本。
第一步:恢复旧版本元数据文件
在
/DolphinDB/server
目录执行以下 Shell 指令恢复已备份的单节点元数据:
cp -r backup/dfsMeta/ local8848/dfsMeta
cp -r backup/CHUNK_METADATA/ local8848/storage/CHUNK_METADATA
第二步:恢复旧版本程序文件
在官方下载旧版本程序包,把重新下载的旧版本
server
目录下除
dolphindb.cfg
以及
dolphindb.lic
外的所有文件覆盖替换升级失败的文件。
Windows 升级失败如何版本回退?
如果升级以后,不能正常开启单节点 DolphinDB ,可按以下方式回退到旧版本。
第一步:恢复旧版本元数据文件
用升级前备份在
backup
目录下的
dfsMeta
文件复制替换
local8848
目录下的
dfsMeta
文件。
用升级前备份在
backup
目录下的
CHUNK_METADATA
文件复制替换
local8848/storage
目录下的
CHUNK_METADATA
文件。
第二步:恢复旧版本程序文件
在官方下载旧版本程序包,将重新下载的旧版本
server
目录下除
dolphindb.cfg
以及
dolphindb.lic
外的所有文件覆盖替换升级失败的文件。
在线更新授权文件失败怎么办?
在线更新授权文件需要满足
更新授权许可文件
中在线更新的要求。如果不满足其中的要求,可以通过离线方式进行更新,或在DolphinDB官网申请企业版 License。
如何进行配置参数调优?
可以参考 DolphinDB 官方参数配置说明进行配置参数调优:
参数配置
。
如果遇到性能问题,请添加微信号13306510479 或扫描下面二维码,客服会邀您进群,由 DolphinDB 技术支持工程师会解答您的问题。
FILE:references/doc_1731.md
# revoke
**URL**: https://docs.dolphindb.cn/zh/funcs/r/revoke.html
**来源**: DolphinDB 官方文档
---
revoke
语法
revoke(id, accessType, [objs])
详情
revoke
函数执行以下操作:
(1)撤销某个用户或某个组的之前被赋予或禁止的权限。
(2)撤销
grant
给某个用户的内存约束,包含:查询返回结果的内存上限(指定
accessType
= QUERY_RESULT_MEM_LIMIT)和发送的批量子查询占用的内存上限(指定
accessType
= TASK_GROUP_MEM_LIMIT)。撤销后,将恢复为系统的默认值。
管理员可以通过该命令撤销用户所有权限(
accessType
),但普通用户在拥有相关的 OWNER 权限后,只能通过该命令撤销以下权限:TABLE_READ,
TABLE_WRITE, TABLE_INSERT, TABLE_UPDATE, TABLE_DELETE, DB_READ, DB_WRITE, DB_INSERT,
DB_UPDATE, DB_DELETE, DBOBJ_DELETE, DBOBJ_CREATE 和 VIEW_EXEC。
可被撤销的权限类型,参见
grant
。
注:
该函数只能由管理员在控制节点、数据节点和计算节点运行。
参数
userId
|
groupId
是表示用户名或组名的字符串。
accessType
权限类型/内存限制。
objs
标量或向量,表示权限类型的应用对象/约束规则。也可以指定为 *,表示全局。
当
accessType
指定为 COMPUTE_GROUP_EXEC 时,
objs
必须为对应的计算组名。
注:
管理共享内存表、流数据表或流计算引擎的权限时,
objs
必须为 "tableName@nodeAlias"
或"nodeAlias:tableName"。
管理 IMOLTP 引擎库表权限时,
objs
必须为 "oltp://database/table@nodeAlias" 或
"oltp://database@nodeAlias"。
accessType
和
objs
的取值请参照
用户权限管理
权限类型表。
例子
撤销组 "production" 的所有成员读取所有数据库表的权限:
revoke(`production, TABLE_READ, "*")
撤销组 "research" 的所有成员读写表 dfs://db1/t1 的权限:
revoke(`research, TABLE_WRITE, "dfs://db1/t1")
撤销组 "research" 的所有成员在数据库 dfs://db1 和 dfs://db2 创建表的权限:
revoke("research", DBOBJ_CREATE, ["dfs://db1","dfs://db2"])
撤销用户 "AlexSmith" 创建和删除数据库的权限:
revoke("AlexSmith", DB_MANAGE)
撤销用户 "AlexSmith" 执行脚本的权限:
revoke("AlexSmith", SCRIPT_EXEC)
撤销用户 "AlexSmith" 测试脚本的权限:
revoke("AlexSmith", TEST_EXEC)
FILE:references/doc_1739.md
# tmlast
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmlast.html
**来源**: DolphinDB 官方文档
---
tmlast
语法
tmlast(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
的最后一个元素。
返回值
返回一个与输入
X
相同数据类型的向量。
例子
T = 1 1 1 2 5 6
X = 1 4 NULL -1 NULL 4
m = table(T as t,X as x)
select *, tmlast(t, x, 3) from m
t
x
tmlast_t
1
1
1
1
4
4
1
2
-1
-1
5
6
4
4
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = NULL 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmlast(t, x, 3d) from m
t
x
tmlast_t
2021.01.02
2021.01.02
4
4
2021.01.04
2021.01.05
-1
-1
2021.01.07
2
2
2021.01.08
4
4
select *, tmlast(t, x, 1w) from m
t
x
tmlast_t
2021.01.02
2021.01.02
4
4
2021.01.04
2021.01.05
-1
-1
2021.01.07
2
2
2021.01.08
4
4
相关函数:
mlast
,
last
FILE:references/doc_1747.md
# pow
**URL**: https://docs.dolphindb.cn/zh/funcs/p/pow.html
**来源**: DolphinDB 官方文档
---
pow
语法
pow(X, Y)
详情
返回以
X
中的元素为底,以
Y
中元素为指数计算得到的值。当
X
和
Y
为整数时,结果仍然是 DOUBLE 类型。
参数
X
和
Y
可以是标量、向量或矩阵。
返回值
DOUBLE 类型标量、向量或矩阵。
例子
x=1 2 3;
pow(x,3);
//output:[1,8,27]
pow(3,x);
//output:[3,9,27]
y=4.5 5.5 6.5;
pow(x,y);
//output:[1,45.254834,1262.665039]
pow(y,x);
//output: [4.5,30.25,274.625]
m=1..10$2:5;
m;
返回:
#0
#1
#2
#3
#4
1
3
5
7
9
2
4
6
8
10
typestr(pow(3,4));
//output: DOUBLE
FILE:references/doc_1761.md
# getJobStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getJobStatus.html
**来源**: DolphinDB 官方文档
---
getJobStatus
语法
getJobStatus(jobId)
详情
取得批处理作业返回的对象。
参数
jobId
是批处理作业的 ID,是一个字符串。
返回值
返回一个表,包含以下字段:
参数
含义
node
本地节点的别名。
userID
提交作业任务的用户 ID。
jobId
在提交批作业时指定的作业名。
rootJobId
系统中作业的唯一标识。
jobDesc
用于描述作业的字符串。
priority
作业的优先级,为 0-9 之间的整数。
parallelism
作业的并行度,即分配给该作业的线程数上限。
clientIp
发起作业任务的客户端 IP。
clientPort
发起作业任务的客户端端口号。
receivedTime
作业接收的时间,为 TIMESTAMP 类型。
startTime
作业开始时间,为 TIMESTAMP 类型。
endTime
作业结束时间,为 TIMESTAMP 类型。
errorMsg
报错信息。
详情请参考
BatchJobManagement
。
例子
def job1(n){
s = 0
for (x in 1 : n) {
s += sum(sin rand(1.0, 100000000)-0.5)
print("iteration " + x + " " + s)
}
return s
}
job1_ID=submitJob("job1_ID","", job1, 100);
getJobStatus(job1_ID);
返回:
node
userID
jobId
rootJobId
jobDesc
priority
parallelism
clientIP
clientPort
receivedTime
startTime
endTime
errorMsg
controller2
guest
job1_ID20210428...
b9263bfd-50b8-70b3-9845-e595f9b0c506
job1
4
1
115.204.199.28
61537
2023.12.12T02:50:32.598
在作业的状态中,
EndTime
是空的。这意味着作业还在执行中。作业完成后,就能在状态中看到 EndTime。
getJobStatus(job1_ID);
node
userID
jobId
rootJobId
jobDesc
priority
parallelism
clientIP
clientPort
receivedTime
startTime
endTime
errorMsg
controller2
guest
job1_ID20210428...
b9263bfd-50b8-70b3-9845-e595f9b0c506
job1
4
1
115.204.199.28
61537
2023.12.12T02:50:32.598
2023.12.12T02:50:32.599
2023.12.12T02:52:32.477
FILE:references/doc_1768.md
# nanInfFill
**URL**: https://docs.dolphindb.cn/zh/funcs/n/nanInfFill.html
**来源**: DolphinDB 官方文档
---
nanInfFill
语法
nanInfFill(X,Y)
详情
在 DolphinDB 中,浮点数中出现的 NaN 和 Inf
值自动替换为空值。而在外部数据导入或计算过程中,可能出现极端场景,导致上述两个特殊值的引入。该函数用于替换这两个特殊值。
可使用指定
Y
值对
X
中存在的 NaN 或 Inf 值进行替换。
注:
当
X
为字典时,该函数仅对 value 值进行替换。s
参数
X
是除集合外任一数据形式的浮点数。
Y
是一个浮点数。
返回值
返回浮点型,数据形式同
X
。
例子
x = [float(`inf), 2, 3, float(`nan), 5, 6, 7]
nanInfFill (x, 2.2)
x = matrix(1..3, [float(`inf), float(`nan), 1.0])
nanInfFill(x, 1.2)
相关函数:
isNanInf
,
countNanInf
FILE:references/doc_1796.md
# subtuple
**URL**: https://docs.dolphindb.cn/zh/funcs/s/subtuple.html
**来源**: DolphinDB 官方文档
---
subtuple
语法
subtuple(X, range)
详情
创建
X
的只读子元组。
subtuple
几乎能在瞬间创建一个只读向量,相比之下,创建一个新的元组需要耗费更多时间。
参数
X
是一个元组,它的每个元素必须是长度相同的向量。
range
是一个整型数据对,表示范围,只包含下限不包含上限。
返回值
一个元组。
例子
例1:
x=(1..10, 11..20, 21..30, 31..40)
subtuple(x, 2:4);
// output
([3,4],[13,14],[23,24],[33,34])
例2:
m=1000.0
n=20000000
a=(rand(m,n), rand(m,n))
k=10000000;
timer each(avg, a.subtuple(0:k));
// output
Time elapsed: 30.87 ms
timer each(avg, (a[0][0:k], a[1][0:k]));
// output
Time elapsed: 46.508 ms
例3:
x=(1..10, 11..20)
subtuple(x, 2:4)=([4, 5], [14, 15]);
// output
Syntax Error: [line #2] Please use '==' rather than '=' as equal operator in non-sql expression.
subtuple
函数创建的元组只能读取,不能写入。
FILE:references/doc_1810.md
# remoteRun
**URL**: https://docs.dolphindb.cn/zh/funcs/r/remoteRun.html
**来源**: DolphinDB 官方文档
---
remoteRun
语法
remoteRun(conn, script, args)
详情
将脚本或函数传输到远程数据库执行。
参数
conn
是远程数据库的连接句柄。
script
是要执行的脚本或函数名。
args
可选的可变长度参数。如果
script
是函数名,
args
是函数的参数。
返回值
script
的执行结果。
例子
第一种用法:在远程节点上执行脚本。
conn = xdb("localhost",81);
remoteRun(conn, "x=rand(1.0,10000000); y=x pow 2; avg y");
输出返回:0.333254
第二种用法:
如果 functionName
加了单引号,双引号或者反引号,那么表示在远程节点上调用函数。函数是定义在远程节点上,但是参数由本地节点传过去。
h=xdb("localhost",80);
x=remoteRun(h, "sum",1..100);
x;
输出返回:5050
如果 functionName
没有加单引号,双引号或者反引号,那么表示调用的函数定义在本地节点上。参数也是由本地节点传过去。
假设在本地节点,我们有一个表
EarningsDates,该表有两列:股票代码和日期。表中3个股票中的每一个,都有2006年第三季度公布盈利的日期。在远程节点有一个表
USPrices,节点的名字为 localhost,端口号为8081。它包含所有美国股票的每日股票价格。我们希望从远程节点获得在宣布收益后的一周内所有
EarningsDates 表中股票的价格。 在远程节点,我们导入数据文件创建表 USPrices,然后将其共享为名叫 sharedUSPrices
的表。
USPrices = loadText("c:/DolphinDB/Data/USPrices.csv");
share USPrices as USPrices;
当我们创建到远程节点的连接时,远程节点将为此连接创建一个新的会话。此新会话与远程节点上的其他会话完全隔离。这对于开发来说很方便,因为开发人员不必担心名称冲突。
然而,有时候我们也希望在同一节点上的多个会话之间共享数据。这时我们可以使用函数
share
来共享对象。目前只能在
DolphinDB 中共享表。 在本地节点上,我们创建 EarningsDates
表,然后用脚本将其传输到远程节点。在执行完毕后,结果被返回到本地节点。
EarningsDates=table(`XOM`AAPL`IBM as TICKER, 2006.10.26 2006.10.19 2006.10.17 as date)
def loadDailyPrice(data){
dateDict = dict(data.TICKER, data.date)
return select date, TICKER, PRC from objByName("sharedUSPrices") where dateDict[TICKER]<date<=dateDict[TICKER]+7
}
conn = xdb("localhost",8081)
prices = conn.remoteRun(loadDailyPrice, EarningsDates);
prices;
输出返回:
date
TICKER
PRC
2006.10.27
XOM
71.46
2006.10.30
XOM
70.84
2006.10.31
XOM
71.42
2006.11.01
XOM
71.06
2006.11.02
XOM
71.19
2006.10.18
IBM
89.82
2006.10.19
IBM
89.86
2006.10.20
IBM
90.48
2006.10.23
IBM
91.56
2006.10.24
IBM
91.49
2006.10.20
AAPL
79.95
2006.10.23
AAPL
81.46
2006.10.24
AAPL
81.05
2006.10.25
AAPL
81.68
2006.10.26
AAPL
82.19
相关函数:
remoteRunCompatible
FILE:references/doc_1811.md
# cumlastNot
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumlastNot.html
**来源**: DolphinDB 官方文档
---
cumlastNot
语法
cumlastNot(X, [k])
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
若
X
是向量:
如果没有指定
k
,对
X
内的每个元素,返回其之前所有元素中最后一个不为 NULL 的元素。
如果指定
k
,对
X
内的每个元素,返回其之前所有元素中最后一个不为
k
的元素。
若
X
是矩阵,在每列内进行上述计算,返回一个与
X
维度相同的矩阵。
参数
k
一个标量。
返回值
返回一个与输入
X
相同数据类型和形式的对象。
例子
x=[NULL,1,2,6,NULL,3,4,NULL]
cumlastNot(x);
// output
[,1,2,6,6,3,4,4]
cumlastNot(x, 4)
// output
[,1,2,6,6,3,3,3]
m=matrix(1 2 3 NULL 4, NULL NULL 8 8 9);
m;
#0
#1
1
2
3
8
8
4
9
cumlastNot(m);
#0
#1
1
2
3
8
3
8
4
9
相关函数:
lastNot
FILE:references/doc_1821.md
# contextby
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/contextby.html
**来源**: DolphinDB 官方文档
---
contextby
语法
contextby(func, funcArgs, groupingCol, [sortingCol],
[semanticFilter=1])
或
funcArg func:X groupingCol
或
func:X(funcArgs, groupingCol, [sortingCol],
[semanticFilter=1])
详情
根据 groupingCol 分组,并在组内进行指定计算。
如果func是聚合函数,每组内的所有结果相同。若指定了sortingCol,在计算前,依此列进行组内排序。
注:
当 func 为聚合函数时,用于定义该聚合函数的关键词为 defg。
参数
func
是一个函数。
注意
:对于第二种用法,func表示的函数只能有一个参数。
funcArgs
是函数func的参数。如果有多个参数,则用元组表示。
groupingCol
是分组变量,可为一组或多组。
sortingCol
是可选参数,表示在应用函数func前,依此列进行组内排序。
semanticFilter
可选参数,当
funcArgs
指定为表时,用于指定表中参与计算的字段。它是一个正整数,可取以下值:
0:所有列。
1(默认值):数值列(FLOATING/INTEGRAL/DECIMAL 分类,COMPRESSED 除外)。
2:时间列(TEMPORAL 类型)。
3:字符串列(LITERAL 类型,BLOB 除外)。
4:数值列和时间列。
funcArgs
,
groupingCol
和
sortingCol
中包含的向量长度相等。
返回值
一个与输入参数长度相同的向量。
例子
sym=`IBM`IBM`IBM`MS`MS`MS
price=172.12 170.32 175.25 26.46 31.45 29.43
qty=5800 700 9000 6300 2100 5300
trade_date=2013.05.08 2013.05.06 2013.05.07 2013.05.08 2013.05.06 2013.05.07;
contextby(avg, price, sym);
输出返回:[172.563,172.563,172.563,29.113,29.113,29.113]
price avg :X sym;
输出返回:[172.563,172.563,172.563,29.113,29.113,29.113]
price at price>contextby(avg, price,sym);
输出返回:[175.25,31.45,29.43]
price at price>price avg :X sym;
输出返回:[175.25,31.45,29.43]
sym at price>contextby(avg, price,sym);
输出返回:["IBM","MS","MS"]
contextby(wavg, [price, qty], sym);
输出返回:[173.856,173.856,173.856,28.374,28.374,28.374]
// 计算数量加权的平均值
contextby(ratios, price, sym, trade_date) - 1;
输出返回:[-0.01786,,0.028946,-0.100917,,-0.064229]
groupingCol 可包含多个向量:
sym=`IBM`IBM`IBM`IBM`IBM`IBM`MS`MS`MS`MS`MS`MS
date=2020.12.01 + 0 0 0 1 1 1 0 0 0 1 1 1
qty=5800 700 9000 1000 3500 3900 6300 2100 5300 7800 1200 4300
contextby(cumsum, qty, [sym,date]);
输出返回:[5800,6500,15500,1000,4500,8400,6300,8400,13700,7800,9000,13300]
contextby
高阶函数可在 SQL 查询中使用:
t1=table(trade_date,sym,qty,price);
t1;
输出返回:
trade_date
sym
qty
price
2013.05.08
IBM
5800
172.12
2013.05.06
IBM
700
170.32
2013.05.07
IBM
9000
175.25
2013.05.08
MS
6300
26.46
2013.05.06
MS
2100
31.45
2013.05.07
MS
5300
29.43
// 选出价格高于组内平均价的交易记录
select trade_date, sym, qty, price from t1 where price > contextby(avg, price,sym);
输出返回:
trade_date
sym
qty
price
2013.05.07
IBM
9000
175.25
2013.05.06
MS
2100
31.45
2013.05.07
MS
5300
29.43
// t1 的所有交易日期都增加一天
contextby(temporalAdd{,1d}, t1, t1.sym,,2)
trade_date
sym
qty
price
2013.05.09
IBM
5,800
172.12
2013.05.07
IBM
700
170.32
2013.05.08
IBM
9,000
175.25
2013.05.09
MS
6,300
26.46
2013.05.07
MS
2,100
31.45
2013.05.08
MS
5,300
29.43
FILE:references/doc_1826.md
# readLines!
**URL**: https://docs.dolphindb.cn/zh/funcs/r/readLines_.html
**来源**: DolphinDB 官方文档
---
readLines!
语法
readLines!(handle, holder, [offset=0], [length=1])
详情
从句柄中读取给定数量的字符串,并从指定位置开始,把读取结果保存至
holder
表示的变量中。
readLines
函数的每次调用都创建了一个字符串向量并返回。创建字符串向量需要一定的时间开销,所以如果在重复执行函数调用时,能重用相同的向量作为缓冲区的话,可以节约时间。
readLines!
函数接受已存在的缓冲区作为数据容器。
下述的两个例子读取相同数量的数据 100 次,结果显示:
readLines!
函数比
readLines
函数更快。
参数
handle
是文件句柄。
holder
是用于保存读取的数据的变量。
offset
表示数据保存至holder的起始位置。
length
是从文件中读取的行数。
返回值
返回实际读取的行数。
例子
timer(100){
fin = file("test.txt")
do{ y=fin.readLines(1024) } while(y.size()==1024)
fin.close()
};
// output
Time elapsed: 79.511 ms
timer(100){
fin = file("test.txt")
y=array(STRING,1024)
do{ lines = fin.readLines!(y,0,1024) } while(lines==1024)
fin.close()
};
// output
Time elapsed: 56.034 ms
FILE:references/doc_1838.md
# cast
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cast.html
**来源**: DolphinDB 官方文档
---
cast
语法
cast(X, Y)
或
X $ Y
详情
把一个数据类型转换成另一个
改变一个矩阵的形状
将向量转换成矩阵
参数
X
可以是任意数据形式。
Y
是数据类型或数据对。
返回值
取决于
Y
的数据类型与形式。
例子
x=8.9$INT;
x;
返回:9
x=1..10;
x;
返回:[1,2,3,4,5,6,7,8,9,10]
typestr x;
返回:FAST INT VECTOR
x/2;
返回:[0,1,1,2,2,3,3,4,4,5]
x=x$DOUBLE;
typestr x;
返回:FAST DOUBLE VECTOR
x/2;
返回:[0.5,1,1.5,2,2.5,3,3.5,4,4.5,5]
x=`IBM`MS;
typestr x;
返回:STRING VECTOR
x=x$SYMBOL;
typestr x;
返回:FAST SYMBOL VECTOR
x=`128.9;
typestr x;
返回:STRING
x=x$INT;
x;
返回:128
typestr x;
返回:INT
以下这个例子将向量转换为矩阵:
m=1..8$2:4;
m;
得到:
0
1
2
3
1
3
5
7
2
4
6
8
以下例子改变一个矩阵的形状:
m$4:2;
得到:
0
1
1
5
2
6
3
7
4
8
m$1:size(m);
得到:
0
1
2
3
4
5
6
7
1
2
3
4
5
6
7
8
FILE:references/doc_1842.md
# mr
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mr.html
**来源**: DolphinDB 官方文档
---
mr
语法
mr(ds, mapFunc, [reduceFunc], [finalFunc], [parallel=true])
详情
Map-Reduce 函数是 DolphinDB 通用分布式计算框架的核心功能。
参数
ds
数据源列表。该参数必选,且必须是元组,元组的每个元素都是数据源对象。即使只有一个数据源,我们仍然需要一个元组来包装数据源。
mapFunc
map 函数。它只接受一个参数,即相应数据源的物化数据实体。如果希望 map
函数接受除了物化数据源之外更多的参数,可以使用
部分应用
将多参数函数转换为一个参数的函数。map 函数调用的次数是数据源的数量。map
函数返回一个常规对象(标量,对,数组,矩阵,表,集合或字典)或一个元组(包含多个常规对象)。
reduceFunc
二元 reduce 函数组合了两个 map 函数调用结果。在大多数情况下,reduce
函数是不重要的。一个例子是加法函数,reduce 函数是可选的。如果没有指定 reduce 函数,则系统将所有单独的 map 调用结果返回到最终函数。
finalFunc
final 函数,只接受一个参数。该函数的输入是最后一个 reduce
函数的输出。如果未指定,系统将返回所有 map 函数调用结果。
parallel
指示是否在本地并行执行 map 函数的可选布尔标志。默认值为
true,即启用并行计算。当可用内存有限和每个 map
调用需要大量的内存时,我们可以禁用并行计算以防止内存不足问题。我们也可能要禁用并行选项以确保线程安全。例如,如果多个线程同时写入同一个文件,则可能会发生错误。
返回值
一个表。
例子
以下是分布式线性回归的示例。X 是自变量的矩阵,y 是因变量。X 和 y 存储在多个数据源中。为了估计最小二乘参数,我们需要计算 X
T
X 和 X
T
y 。我们可以从每个数据源计算 (X
T
X, X
T
y) 的元组,然后将所有数据源的结果相加,以获得整个数据集的 X
T
X 和 X
<sup>T</sup> y。
def myOLSMap(table, yColName, xColNames, intercept){
if(intercept)
x = matrix(take(1.0, table.rows()), table[xColNames])
else
x = matrix(table[xColNames])
xt = x.transpose();
return xt.dot(x), xt.dot(table[yColName])
}
def myOLSFinal(result){
xtx = result[0]
xty = result[1]
return xtx.inv().dot(xty)[0]
}
def myOLSEx(ds, yColName, xColNames, intercept){
return mr(ds, myOLSMap{, yColName, xColNames, intercept}, +, myOLSFinal)
}
在上面的例子中,我们定义了 map 函数和 final
函数。实践中,我们也可为数据源定义转换函数。这些功能仅需在本地实例中定义,用户不需要编译它们或将其部署到远程实例。DolphinDB
的分布式计算框架可以为最终用户快速处理这些复杂的问题。
作为经常使用的分析工具,分布式最小二乘线性回归已经在我们的核心库中实现。内置版本(
olsEx
)提供更多功能。
FILE:references/doc_1849.md
# bondDirtyPrice
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bondDirtyPrice.html
**来源**: DolphinDB 官方文档
---
bondDirtyPrice
语法
bondDirtyPrice(start, maturity, issuePrice, coupon,
frequency, dayCountConvention, bondType, settlement, price, priceType,
[benchmark='Excel'])
别名:fiDirtyPrice
详情
返回面值为 100 的债券的全价。
参数
注意:所有输入向量必须等长,输入标量将自动扩展以匹配其它向量的长度。
start
DATE 类型标量或向量,表示债券的起息日。
maturity
与
start
等长的 DATE 类型标量或向量,表示债券的到期日。
issuePrice
与
start
等长的数值型标量或向量,表示债券的发行价格。贴现债需指定真实发行价(通常小于100);其他债券通常为100。
coupon
数值型标量或向量,表示债券的票面利率。例如 0.03,表示票息为 3%。
frequency
整型或 STRING 类型的标量或向量,表示债券的付息频率。可选值为:
0/“Once”:到期一次还本付息
1/“Annual”:每年付息一次
2/“Semiannual:每半年付息一次
4/“Quarterly”:每季度付息一次
12/“Monthly”:每月付息一次
dayCountConvention
STRING 类型的标量或向量,表示债券的计息日数惯例。可选值为:
"Thirty360US":US (NASD) 30/360
"ActualActualISMA":实际/实际(ISMA 规则)
"Actual360":实际/360
"Actual365":实际/365
"Thirty360EU":欧洲 30/360
"ActualActualISDA":实际/实际(ISDA 规则)
bondType
STRING 类型标量或向量,表示债券的类型。可选值为:
"FixedRate":固定利率债券,定期按息票利率支付利息。
"Discount":贴现债券,没有利息支付,以贴现方式发行的债券,期末FV=面值。
"ZeroCoupon":零息债券,期末一次性支付利息和面值,期末FV=面值+利息。
settlement
DATE 类型标量或向量,表示债券的结算日,即购买日期。
price
数值型标量或向量,具体含义取决于 priceType 的取值:
当
priceType
为 "YTM" 时,
price
表示债券的到期收益率;
当
priceType
为 "CleanPrice" 时,
price
表示债券的净价;
priceType
STRING 类型的标量或向量,用于指定债券价格类型,可选值为:
"YTM":到期收益率
"CleanPrice":净价
benchmark
可选参数,STRING 类型标量,表示算法参考基准。目前仅支持 “Excel”(excel
中的算法)。
返回值
DOUBLE 类型标量或向量。
例子
bondDirtyPrice(start=2023.01.01, maturity=2030.12.31, issuePrice=100, coupon=0.05, frequency=1, dayCountConvention="ActualActualISMA", bondType="FixedRate", settlement=2023.04.01, price=100.2143, priceType="CleanPrice")
// output: 101.447176
相关函数
:
bondCalculator
FILE:references/doc_1851.md
# bondPricer
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bondPricer.html
**来源**: DolphinDB 官方文档
---
bondPricer
语法
bondPricer(instrument, pricingDate, discountCurve,
[spreadCurve], [setting])
详情
用于对单只债券进行定价,输出净现值(NPV),同时可计算多种风险指标,包括一阶敏感度(Delta)、二阶敏感度(Gamma)以及关键利率久期(Key Rate
Duration)。
参数
instrument
INSTRUMENT 类型,表示需要定价的债券产品。不同类型的债券产品所需的关键字段各不相同,详见债券
产品字段要求
。
pricingDate
DATE 类型标量,表示定价日期。
discountCurve
MKTDATA 类型对象(IrYieldCurve),表示贴现曲线。贴现曲线所需包含的关键字段见
曲线字段要求
。
spreadCurve
可选参数,MKTDATA 类型对象(IrYieldCurve),表示信用利差曲线。若未提供,则默认使用 0%
利率的平坦曲线。利差曲线所需包含的关键字段见
曲线字段要求
。
setting
可选参数,字典(Dictionary<STRING, ANY>),用于定价设置,包括以下键值对:
键
值类型
描述
"calcDiscountCurveDelta"
BOOL
是否计算债券对贴现曲线的一阶敏感度
"calcDiscountCurveGamma"
BOOL
是否计算债券对贴现曲线的二阶敏感度
"calcDiscountCurveKeyRateDuration"
BOOL
是否计算债券的关键利率久期
"discountCurveShift"
DOUBLE 标量
贴现曲线的平行扰动,比如一个 bp(0.0001)
"discountCurveKeyTerms"
DOUBLE 标量或向量
关键期限年数,比如 [1.0, 3.0, 5.0]
"discountCurveKeyShifts"
DOUBLE 标量或向量
关键期限的扰动幅度, 与 discountCurveKeyTerms 等长,比如 [0.0001, 0.0002,
0.0015]
返回值
若未指定
setting
,返回 NPV(DOUBLE 类型标量)。
若指定
setting
,返回 Dictionary<STRING, ANY>,键为指标名称,值为相应结果:
"npv":DOUBLE 标量
"discountCurveDelta":DOUBLE 标量
"discountCurveGamma":DOUBLE 标量
"discountCurveKeyRateDuration":DOUBLE 向量
例子
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "240025.IB",
"start": 2024.12.25,
"maturity": 2031.12.25,
"issuePrice": 100.0,
"coupon": 0.0149,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA"
}
pricingDate = 2025.08.18
curve = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": pricingDate,
"currency": "CNY",
"curveName": "CNY_TREASURY_BOND",
"dayCountConvention": "ActualActualISDA",
"compounding": "Compounded",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates":[2025.09.18, 2025.11.18, 2026.02.18, 2026.08.18, 2027.08.18, 2028.08.18, 2030.08.18,
2032.08.18, 2035.08.18, 2040.08.18, 2045.08.18, 2055.08.18,2065.08.18, 2075.08.18],
"values":[1.3000, 1.3700, 1.3898, 1.3865, 1.4299, 1.4471, 1.6401,
1.7654, 1.7966, 1.9930, 2.1834, 2.1397, 2.1987, 2.2225] / 100.0
}
instrument = parseInstrument(bond)
discountCurve = parseMktData(curve)
setting = dict(STRING, ANY)
setting["calcDiscountCurveDelta"] = true
setting["calcDiscountCurveGamma"] = true
setting["calcDiscountCurveKeyRateDuration"] = true
setting["discountCurveShift"] = 0.0001
setting["discountCurveKeyTerms"] = [1.0, 3.0, 5.0]
setting["discountCurveKeyShifts"] = [0.0002, 0.0003, 0.0001]
results = bondPricer(instrument, pricingDate, discountCurve, setting=setting)
print(results)
/* output:
npv->99.600846811350891
discountCurveDelta->-592.25994127828585
discountCurveGamma->4223.064257757869199
discountCurvekeyRateDuration->[0.012669167121743,0.069982332985636,1.955786205709234]
*/
相关函数:
parseInstrument
,
parseMktData
债券产品字段要求
贴现债
字段名
类型
描述
是否必填
productType
STRING
固定填 "Cash"
是
assetType
STRING
固定填 "Bond"
是
bondType
STRING
固定填 "DiscountBond"
是
nominal
DOUBLE
名义金额,默认值 100
否
instrumentId
STRING
债券代码,如 "259926.IB"
否
start
DATE
起息日
是
maturity
DATE
到期日
是
dayCountConvention
STRING
日期计数惯例,可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
issuePrice
DOUBLE
发行价格
是
currency
STRING
货币,默认为 "CNY"
否
cashFlow
TABLE
债券现金流表
否
discountCurve
STRING
定价时参考的贴现曲线名称,如 "CNY_TRASURY_BOND"
否
spreadCurve
STRING
定价时参考的利差曲线名称
否
subType
STRING
债券子类型,中国债券可选值为:
"TREASURY_BOND":国债
"CENTRAL_BANK_BILL":央行票据
"CDB_BOND":政策性金融债(国开)
"EIBC_BOND":政策性金融债(进出口行)
"ADBC_BOND":政策性金融债(农发行)。
"MTN":中期票据
"CORP_BOND":企业债。
"UNSECURED_CORP_BOND":无担保企业债
"SHORT_FIN_BOND":短期融资券
"NCD":同业存单
"LOC_GOV_BOND":地方政府债
"COMM_BANK_FIN_BOND":商业银行普通金融债
"BANK_SUB_CAP_BOND":商业银行二级资本债
"ABS":资产支持证券
"PPN":非公开发行债
否
creditRating
STRING
信用等级类型,可选值为:"B", "BB", "BBB", "BBB+", "A-", "A", "A+", "AA-",
"AA", "AA+", "AAA-", "AAA", "AAA+"
否
零息债
字段名
类型
描述
是否必填
productType
STRING
固定填 "Cash"
是
assetType
STRING
固定填 "Bond"
是
bondType
STRING
固定填 "ZeroCouponBond"
是
nominal
DOUBLE
名义金额,默认值 100
否
instrumentId
STRING
债券代码,如 "250401.IB"
否
start
DATE
起息日
是
maturity
DATE
到期日
是
coupon
DOUBLE
票面利率,如 0.03 表示 3%
是
frequency
STRING
付息频率
否
dayCountConvention
STRING
日期计数惯例,可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
currency
STRING
货币,默认为 "CNY"
否
cashFlow
TABLE
债券现金流表
否
discountCurve
STRING
定价时参考的贴现曲线名称,如 "CNY_TRASURY_BOND"
否
spreadCurve
STRING
定价时参考的利差曲线名称
否
subType
STRING
债券子类型,中国债券可选值为:
"TREASURY_BOND":国债
"CENTRAL_BANK_BILL":央行票据
"CDB_BOND":政策性金融债(国开)
"EIBC_BOND":政策性金融债(进出口行)
"ADBC_BOND":政策性金融债(农发行)。
"MTN":中期票据
"CORP_BOND":企业债。
"UNSECURED_CORP_BOND":无担保企业债
"SHORT_FIN_BOND":短期融资券
"NCD":同业存单
"LOC_GOV_BOND":地方政府债
"COMM_BANK_FIN_BOND":商业银行普通金融债
"BANK_SUB_CAP_BOND":商业银行二级资本债
"ABS":资产支持证券
"PPN":非公开发行债
否
creditRating
STRING
信用等级类型,可选值为:"B", "BB", "BBB", "BBB+", "A-", "A", "A+", "AA-",
"AA", "AA+", "AAA-", "AAA", "AAA+"
否
固定利率债
字段名
类型
描述
是否必填
productType
STRING
固定填 "Cash"
是
assetType
STRING
固定填 "Bond"
是
bondType
STRING
固定填 "FixedRateBond"
是
nominal
DOUBLE
名义金额,默认值 100
否
instrumentId
STRING
债券代码,如 "250401.IB"
否
start
DATE
起息日
是
maturity
DATE
到期日
是
coupon
DOUBLE
票面利率,如0.03表示3%
是
frequency
STRING
付息频率
是
dayCountConvention
STRING
日期计数惯例,可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
currency
STRING
货币,默认为 "CNY"
否
cashFlow
TABLE
债券现金流表
否
discountCurve
STRING
定价时参考的贴现曲线名称,如 "CNY_TRASURY_BOND"
否
spreadCurve
STRING
定价时参考的利差曲线名称
否
subType
STRING
债券子类型,中国债券可选值为:
"TREASURY_BOND":国债
"CENTRAL_BANK_BILL":央行票据
"CDB_BOND":政策性金融债(国开)
"EIBC_BOND":政策性金融债(进出口行)
"ADBC_BOND":政策性金融债(农发行)。
"MTN":中期票据
"CORP_BOND":企业债。
"UNSECURED_CORP_BOND":无担保企业债
"SHORT_FIN_BOND":短期融资券
"NCD":同业存单
"LOC_GOV_BOND":地方政府债
"COMM_BANK_FIN_BOND":商业银行普通金融债
"BANK_SUB_CAP_BOND":商业银行二级资本债
"ABS":资产支持证券
"PPN":非公开发行债
否
creditRating
STRING
信用等级类型,可选值为:"B", "BB", "BBB", "BBB+", "A-", "A", "A+", "AA-",
"AA", "AA+", "AAA-", "AAA", "AAA+"
否
曲线字段要求
字段名
类型
描述
是否必填
mktDataType
STRING
固定填 "Curve"
是
referenceDate
DATE
参考日期
是
curveType
STRING
固定填 "IrYieldCurve"
是
dayCountConvention
STRING
曲线的日期计数惯例,可选值为:
"Actual360":实际天数除以360
"Actual365":实际天数除以365(不区分闰年)
"ActualActualISMA":实际天数/实际天数(ISMA规则)
"ActualActualISDA":实际天数/实际天数(ISDA规则)
是
interpMethod
STRING
内插方法,可选值为:
"Linear":线性插值
"CubicSpline":三次样条插值
"CubicHermiteSpline":三次埃尔米特样条插值
是
extrapMethod
STRING
外插方法,可选值为:
"Flat":平插
"Linear":线性插值
是
dates
DATE 向量
数据点的日期
是
values
DOUBLE 向量
数据点的值,与
dates
中的元素一一对应
是
curveName
STRING
曲线名称
否
currency
STRING
货币,可选值为"CNY", "USD", "EUR", "GBP", "JPY", "HKD"
是
compounding
STRING
复利类型,可选值为:
"Simple":单利
"Compounded":离散复利
"Continuous":连续复利
是
settlement
DATE
结算日,如果指定了结算日,则后续期限间隔的计算都将从
settlement
开始,而不是
referenceDate
否
frequency
INTEGRAL或 STRING
计息频率,可选值为:
-1 或 "NoFrequency":无效计息频率
0 或 "Once":到期一次还本付息
1 或 "Annual":每年付息一次
2 或 "Semiannual":每半年付息一次
3 或 "EveryFourthMonth":每四个月付息一次
4 或 "Quarterly":每季度付息一次
6 或 "BiMonthly":每两月付息一次
12 或 "Monthly":每月付息一次
13 或 "EveryFourthWeek":每四周付息一次
26 或 "BiWeekly":每两周付息一次
52 或 "Weekly":每周付息一次
365 或 "Daily":每日付息一次
999 或 "Other":其他计息频率
否
curveModel
STRING
曲线构建模型,可选值为 "Bootstrap"(默认),"NS","NSS"。
当取值 "NSS" 或 "NS",无需传
interpMethod
、
extrapMethod
、
dates
、
values
字段。
否
curveParams
DICT
模型的参数,当
curveModel
取值 "NSS" 或 "NS" 时必填:
curveModel = "NS":应包含键 'beta0', 'beta1', 'beta2',
'lambda'
curveModel = "NSS":应包含键'beta0', ‘beta1', 'beta2',
'beta3', 'lambda0', 'lambda1'
否
FILE:references/doc_1858.md
# panel
**URL**: https://docs.dolphindb.cn/zh/funcs/p/panel.html
**来源**: DolphinDB 官方文档
---
panel
语法
panel(row, col, metrics, [rowLabel], [colLabel], [parallel=false])
详情
将指标列按给定行与列维度进行透视操作,生成一个或多个矩阵。每一个矩阵对应一个指标列(metrics)。
panel
函数同
pivotBy
语句类似,将数据表中的数据按照两个维度重新排列。两者的不同之处在于,SQL 中,exec... pivot by... 只能指定一个指标列, 生成一个矩阵,而
panel
函数可以指定一个或多个指标列,生成一个或多个矩阵。
参数
row
是一个向量,其中每个元素对应结果矩阵中的一行。
col
是一个向量,其中每个元素对应结果矩阵中的一列。
metrics
是一个或多个指标列。每个指标列产生一个矩阵。
rowLabel
是一个向量,为结果矩阵的行标签。必须升序排列,而且没有重复值。结果中仅包括
rowLabel
中指定的行。
colLabel
是一个向量,为结果矩阵的列标签。必须升序排列,而且没有重复值。结果中仅包括
colLabel
中指定的列。
parallel
是一个布尔值,表示是否并行计算。默认值为 false。
返回值
一个或多个矩阵。
例子
t = table(1 1 2 2 2 3 3 as id, 2020.09.01 + 1 3 1 2 3 2 3 as date, 1..7 as value);
t;
id
date
value
1
2020.09.02
1
1
2020.09.04
2
2
2020.09.02
3
2
2020.09.03
4
2
2020.09.04
5
3
2020.09.03
6
3
2020.09.04
7
panel
面板数据生成的表中,指定的
row
和
col
会自动按升序排序。
panel(t.date, t.id, t.value);
1
2
3
2020.09.02
1
3
2020.09.03
4
6
2020.09.04
2
5
7
panel(t.date, t.id, t.value, 2020.09.02 2020.09.03, 1 2);
1
2
2020.09.02
1
3
2020.09.03
4
panel(t.date, t.id, [t.value, t.value>0], 2020.09.02 2020.09.03, 1 2);
1
2
2020.09.02
1
3
2020.09.03
4
1
2
2020.09.02
1
1
2020.09.03
1
利用
panel
生成的矩阵,计算每只股票的累积最大股价。
syms = "sym"+string(1..2)
dates = 2021.12.07..2021.12.11
t = table(loop(take{, size(syms)}, dates).flatten() as trade_date, take(syms, size(syms)*size(dates)) as code, rand(1000, (size(syms)*size(dates))) as volume)
volume = panel(t.trade_date, t.code, t.volume, dates)
cummax(volume)
FILE:references/doc_1865.md
# getInstrumentFixedRate
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentfixedrate.html
**来源**: DolphinDB 官方文档
---
getInstrumentFixedRate
语法
getInstrumentFixedRate(instrument)
详情
根据输入的金融工具,获取该工具的固定端利率。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DOUBLE 类型标量或向量。
例子
swap = {
"productType": "Swap",
"swapType": "IrSwap",
"irSwapType": "IrFixedFloatingSwap",
"version": 0,
"start": 2021.05.15,
"maturity": 2023.05.15,
"frequency": "Quarterly",
"fixedRate": 0.02,
"calendar": "CFET",
"fixedDayCountConvention": "Actual365",
"floatingDayCountConvention": "Actual360",
"payReceive": "Pay",
"iborIndex": "SHIBOR_3M",
"spread": 0.0005,
"notional":["CNY", 1E8]
}
instrument = parseInstrument(swap)
getInstrumentFixedRate(instrument)
// output: 0.02
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_187.md
# getBackupMeta
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getBackupMeta.html
**来源**: DolphinDB 官方文档
---
getBackupMeta
语法
getBackupMeta(backupDir, dbPath, partition,
tableName)
详情
查询指定某分布式数据表中某个分区的备份信息。
参数
backupDir
是字符串,表示存放备份数据的目录。
dbPath
是字符串,表示分布式数据库的名称,例如
"dfs://demo"
。
partition
是字符串,表示分区在数据库内的路径,例如
"/20190101/GOOG"
。
请注意:若使用 2.00.4 到 2.00.6 版本
server,对表级分区数据进行备份和恢复时,该参数必须指定路径到物理索引(可通过函数
listTables
获取),例如分区
"/compoDB/20170807/0_50"
下表的物理索引为8,则 partition 需指定为
"/compoDB/20170807/0_50/8"
。
tableName
是字符串,表示数据库中表的名称。
返回值
返回的结果是一个字典,包含以下 key:
schema:该数据表的结构。
dfsPath:该分区的完整路径。
rows:分区数据包含的行数。
chunkID:该分区的 ID。
cid:版本号。
例子
查看数据库
dfs://valuedb
中数据表 "pt" 在
"/200001M"
分区的备份信息。
getBackupMeta("/home/DolphinDB/backup","dfs://valuedb", "/200001M","pt")
// output
schema->
name typeString typeInt extra comment
----- ---------- ------- ----- -------
month MONTH 7
x INT 4
dfsPath->dfs://valuedb/200001M/b39
rows->750000
chunkID->0061427c-4b24-e3b6-425c-c0e1553d3c35
cid->13349
FILE:references/doc_1877.md
# cdfKolmogorov
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfKolmogorov.html
**来源**: DolphinDB 官方文档
---
cdfKolmogorov
语法
cdfKolmogorov(X)
详情
返回 Kolmogorov 分布的累计密度函数的值。
参数
X
是数值型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfKolmogorov([0.1, 0.3, 0.5, 0.7, 0.9]);
// output
[1, 0.999991, 0.963945, 0.711235, 0.392731]
cdfKolmogorov([1,2,3]);
// output
[0.27, 0.000671, 3.045996E-8]
FILE:references/doc_1882.md
# binsrch
**URL**: https://docs.dolphindb.cn/zh/funcs/b/binsrch.html
**来源**: DolphinDB 官方文档
---
binsrch
语法
binsrch(X, Y)
详情
binsrch
即二分查找。对于每一个
Y
中的元素,
binsrch
确定它在
X
中的位置。如果没有找到,返回 -1。
为了充分发挥性能,应当使用
binsrch
在一个有序的长向量
X
中查找一个较短的
Y
。要在一个长的未排序的向量中查找一个较长向量,应当使用
find
函数,后者使用散列表实现。但是构造一个散列表会花一些时间和内存。另外也请参见相关函数
in
。
参数
X
必须是一个递增向量;
Y
可以是标量、向量、元组、
数组向量、
矩阵、字典、表。
返回值
INT 类型,其数据形式同
Y
。
例子
1..100 binsrch 12 6 88 102;
// output
[11,5,87,-1]
FILE:references/doc_1884.md
# sqlCol
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sqlCol.html
**来源**: DolphinDB 官方文档
---
sqlCol
语法
sqlCol(colName, [func], [alias], [qualifier])
详情
生成表示选择某些列或对某些列进行计算的元代码。一般与函数
sql
和
eval
共同使用,用于动态生成 SQL 语句。
参数
colName
是一个字符串标量或向量,表示列名。
func
是一个一元函数。
alias
是一个字符串标量或向量,表示选择列或计算结果列的别名。
qualifier
是一个字符串标量,表示表名。多表连接时,可以通过该参数指定含有相同名字的非连接列属于哪个表。
返回值
CODE 类型标量。
例子
t = table(`GME`AMC`KOSS as symbol, 325 13.26 64 as price);
colName="symbol";
sql(select=sqlCol(colName), from=t).eval();
symbol
GME
AMC
KOSS
colName="price";
sql(select=sqlCol(colName, max, `maxPrice), from=t).eval();
maxPrice
325
t1 = table(1 2 3 3 as id, 7.8 4.6 5.1 0.1 as value, 4 3 2 1 as x);
t2 = table(5 3 1 as id, 300 500 800 as qty, 44 66 88 as x) ;
sql(select=(sqlCol(`id),sqlCol(colName=`x, alias="t1_x", qualifier="t1"),sqlCol(colName=`x, alias="t2_x", qualifier=`t2)), from=<ej(t1,t2,`id)>).eval()
id
t1_x
t2_x
1
4
88
3
2
66
3
1
66
FILE:references/doc_1885.md
# objs
**URL**: https://docs.dolphindb.cn/zh/funcs/o/objs.html
**来源**: DolphinDB 官方文档
---
objs
语法
objs([shared=false])
参数
shared
布尔值,默认为 false。
false:返回当前会话中所有变量的信息;
true:返回当前会话中所有变量的信息以及所有会话共享的变量信息;
详情
获取内存中缓存的各变量的内存占用情况等信息。
注意,该函数不返回函数定义。我们应该用 defs 检查函数定义,或通过
memSize
查看函数定义的内存占用。
返回值
一个表,它具有以下几列:
name: 变量名。
type: 变量的数据类型。
form: 变量的数据形式。
rows:
若 form 为向量/字典/集合,则返回所有元素(包含 NULL)的个数
若 form 为矩阵/表,则返回它们的行数
columns:
若 form 为向量/字典/集合,则返回 1
若 form 为矩阵/表,则返回它们的列数
bytes: 变量占用的内存大小,单位为字节
shared: 是否为共享变量
extra: 分布式表的逻辑路径,格式为
"dfs://dbName/tableName"
owner:共享变量的创建者。只有设置 shared=true 时才会显示该字段。对于本地变量,此字段值为空。
例子
// 创建分布式数据库
if(existsDatabase("dfs://listdb")){
dropDatabase("dfs://listdb")
}
n=1000000
ticker = rand(`MSFT`GOOG`FB`ORCL`IBM,n);
ticker[0..5]
x=rand(1.0, n)
t=table(ticker, x)
db=database(directory="dfs://listdb", partitionType=HASH, partitionScheme=[STRING, 5])
pt=db.createPartitionedTable(t, `pt, `ticker)
pt.append!(t)
// 共享内存表
time = take(2021.08.20 00:00:00..2021.08.30 00:00:00, 40);
id = 0..39;
value = rand(100, 40);
tmp = table(time, id, value);
share tmp as st
// 创建 set
s = set([1,2,3,4,5])
// 创建 dict
x=1 2 3
y=4.5 7.8 4.3
z=dict(x,y);
// 创建 matrix
m = matrix(1 2 3, 4 5 6)
// 创建 pair
p = 1:2
objs(true)
name
type
form
rows
columns
bytes
shared
extra
owner
n
INT
SCALAR
1
1
16
false
ticker
SYMBOL
VECTOR
1,000,000
1
4,000,000
false
x
INT
VECTOR
3
1
12
false
t
BASIC
TABLE
1,000,000
2
12,000,312
false
db
HANDLE
SCALAR
1
1
24
false
pt
ALIAS
TABLE
0
2
12,000,000
false
dfs://listdb/pt
time
DATETIME
VECTOR
40
1
160
false
id
INT
VECTOR
40
1
160
false
value
INT
VECTOR
40
1
160
false
tmp
BASIC
TABLE
40
3
832
false
s
INT
SET
5
1
28
false
y
DOUBLE
VECTOR
3
1
24
false
z
DOUBLE
DICTIONARY
3
1
199
false
m
INT
MATRIX
3
2
24
false
p
INT
PAIR
2
1
8
false
st
BASIC
TABLE
40
3
832
true
admin
FILE:references/doc_1893.md
# ridge
**URL**: https://docs.dolphindb.cn/zh/funcs/r/ridge.html
**来源**: DolphinDB 官方文档
---
ridge
语法
ridge(ds, yColName, xColNames, [alpha=1.0], [intercept=true],
[normalize=false], [maxIter=1000], [tolerance=0.0001], [solver='svd'],
[swColName])
详情
进行 ridge 回归估计。
最小化以下目标函数:
参数
ds
是一个内存表或通常用
sqlDS
函数生成的数据源。
yColName
是字符串,表示数据源中因变量的列名。
xColNames
是字符串标量或向量,表示数据源中自变量的列名。
alpha
是浮点数,表示乘以 L1 范数惩罚项的系数。默认值是1.0。
intercept
是布尔值,表示是否回归模型包含截距。默认值为true。
normalize
是布尔值。默认值为 false。若设为 true,则所有自变量均会进行如下标准化:减去平均值,然后除以 L2 范数。若
intercept
为 false,该参数会被忽略。
maxIter
是正整数,表示最大迭代次数。默认值是1000。
tolerance
是浮点数,表示迭代中止的边界差值。默认值是0.0001。
solver
是字符串,表示回归算法模型。可取值 'svd' 或 'cholesky'。若ds为多个数据源,则
solver
必须为
'cholesky'。
swColName
字符串,表示列名,必须为
ds
中存在的列名。如果未指定该参数,则所有样本的权重都默认为1;如果指定该参数,则将指定的列作为样本的权重。
返回值
返回一个字典,包含以下键值:modelName,coefficients,intercept,xColNames,predict。
例子
y = [225.720746,-76.195841,63.089878,139.44561,-65.548346,2.037451,22.403987,-0.678415,37.884102,37.308288]
x0 = [2.240893,-0.854096,0.400157,1.454274,-0.977278,-0.205158,0.121675,-0.151357,0.333674,0.410599]
x1 = [0.978738,0.313068,1.764052,0.144044,1.867558,1.494079,0.761038,0.950088,0.443863,-0.103219]
t = table(y, x0, x1);
ridge(t, `y, `x0`x1);
如果 t 是一个 DFS 表,则应使用数据源作为输入:
ridge(sqlDS(<select * from t>), `y, `x0`x1);
FILE:references/doc_1917.md
# setIPConnectionLimit
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setIPConnectionLimit.html
**来源**: DolphinDB 官方文档
---
setIPConnectionLimit
语法
setIPConnectionLimit(IP, limit)
详情
设置每个 IP 对当前节点连接数限制。该限制适用于 API 连接和
xdb
连接,不会限制集群内部节点间的连接(如
rpc
等)。
仅支持管理员调用,仅支持 Linux 系统部署的 server。
参数
IP
字符串,表示要设置连接数限制的 IP 地址。
limit
正整数或 -1。正整数表示连接数限制。-1 表示无限制。
例子
设置 IP 地址 "192.168.1.56" 的最大连接数为 10:
setIPConnectionLimit("192.168.1.56", 10);
取消 IP 地址 "192.168.1.56" 的连接数限制:
setIPConnectionLimit("192.168.1.56", -1);
相关函数:
getIPConnectionLimit
FILE:references/doc_1918.md
# getTables
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getTables.html
**来源**: DolphinDB 官方文档
---
getTables
语法
getTables(dbHandle)
详情
查询指定数据库中的所有表。
参数
dbHandle
是数据库句柄。
返回值
字符串向量。
例子
n=1000000
ID=rand(10, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
y=rand(10, n)
t1=table(ID, date, x)
t2=table(ID, date, y)
db = database("dfs://valueDB", VALUE, 2017.08.07..2017.08.11)
pt1 = db.createPartitionedTable(t1, `pt1, `date)
pt1.append!(t1)
pt2 = db.createPartitionedTable(t2, `pt2, `date)
pt2.append!(t2);
getTables(db);
输出返回:["pt1","pt2"]
FILE:references/doc_1921.md
# sortBy!
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sortBy_.html
**来源**: DolphinDB 官方文档
---
sortBy!
语法
sortBy!(table, sortColumns, [sortDirections])
详情
根据指定列和指定的排序方向对一个表进行就地排序。如果是分区表,将对每个分区进行排序,而不是对整个表进行排序。
如果 table 是分区表并且启用了并行处理功能(即配置参数 localExcutors >
0),那么该操作是并行操作。
参数
table
是 DolphinDB 中 Table 类型的表。它可以是分区或未分区的内存表。
sortColumns
是一个字符串标量或向量,表示某列,该表按照该列进行排序。它也可以是表达式的元代码。
sortDirections
是一个布尔值,表示排序方向。1表示按照升序排序,0表示按照降序排序。如果
sortColumns
是向量而
sortDirections
是标量,那么所有的排序列都根据
sortDirections
表示的排序方向排序。
返回值
返回一个表。
例子
对未分区表进行排序:
n=20000000
trades=table(rand(`IBM`MSFT`GM`C`YHOO`GOOG,n) as sym, 2000.01.01+rand(365,n) as date, 10.0+rand(2.0,n) as price, rand(1000,n) as qty);
trades.sortBy!(`sym`date, [0,1]);
对分区表进行排序:
workDir = "C:/DolphinDB/Data"
if(!exists(workDir)) mkdir(workDir)
trades.saveText(workDir + "/trades.txt")
db = database(workDir + "/trade",VALUE,`IBM`MSFT`GM`C`YHOO`GOOG)
db.loadTextEx("trades","sym", workDir + "/trades.txt")
trades = db.loadTable("trades",`IBM`GM`YHOO,1)
trades.sortBy!(`date)
trades.sortBy!(`date, false)
trades.sortBy!(`date`qty, false)
trades.sortBy!(`date`qty, false true)
trades.sortBy!(<qty*price>)
trades.sortBy!(<[date, sym]>)
trades.sortBy!(<[sym, qty*price]>, true false)
FILE:references/doc_193.md
# existsSubscriptionTopic
**URL**: https://docs.dolphindb.cn/zh/funcs/e/existsSubscriptionTopic.html
**来源**: DolphinDB 官方文档
---
existsSubscriptionTopic
语法
existsSubscriptionTopic([server], tableName, [actionName])
别名:
existSubscriptionTopic
详情
查询共享流数据表的订阅主题是否存在。存在返回 true,不存在则返回 false。
参数
server
是一个字符串,表示订阅的流数据表所在节点的别名或远程连接的句柄。如果未指定或者为空字符串,表示流数据所在的服务器是本地实例。
tableName
是一个字符串,表示一个共享流数据表的名称。
actionName
是一个字符串,表示订阅任务的名称。它可以包含字母,数字和下划线。如果创建订阅时指定了
actionName
,查询订阅时必须指定
actionName
。
返回值
布尔类型标量。
例子
t=streamTable(1000000:0,`date`time`sym`qty`price`exch,[DATE,TIME,SYMBOL,INT,DOUBLE,SYMBOL])
share t as trades
trades_1=streamTable(1000000:0,`date`time`sym`qty`price`exch,[DATE,TIME,SYMBOL,INT,DOUBLE,SYMBOL])
subscribeTable(tableName=`trades, actionName=`vwap, offset=-1, handler=append!{trades_1})
existsSubscriptionTopic(,`trades,`vwap)
// output
true
FILE:references/doc_1931.md
# dot
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dot.html
**来源**: DolphinDB 官方文档
---
dot
语法
dot(X, Y)
或
X**Y
详情
返回
X
和
Y
的矩阵乘法。如果
X
和
Y
是具有相同长度的向量,返回它们的内积。
参数
X
和
Y
可以是标量、向量或矩阵。如果
X
和
Y
都是向量,他们必须具有相同的长度。如果
X
或
Y
的其中一个是矩阵,另一个必须是维度满足矩阵乘法规则的向量或矩阵。
返回值
返回一个标量、向量或矩阵。
例子
x=1..6$2:3;
y=1 2 3;
x dot y;
#0
22
28
x=1..6$2:3;
y=6..1$3:2;
x**y;
#0
#1
41
14
56
20
y**x;
#0
#1
#2
12
30
48
9
23
37
6
16
26
a=1 2 3;
shape a;
// output
3:1
x**a;
#0
22
28
b=1 2;
shape b;
// output
2:1
b**x;
// 对于矩阵和向量之间的矩阵乘法,系统会自动转换向量的维度以便完成乘法。
#0
#1
#2
5
11
17
x=1 2 3;
y=4 5 6;
x ** y;
// output
32
// 两个向量之间的内积。等价于 1*4 + 2*5 + 3*6
x ** 2;
// output
[2,4,6]
x=1..6$2:3
x ** 2;
// output
Use * rather than ** for scalar and matrix multiplication.
相关函数:
rowDot
FILE:references/doc_1939.md
# irDepositPricer
**URL**: https://docs.dolphindb.cn/zh/funcs/i/irDepositPricer.html
**来源**: DolphinDB 官方文档
---
irDepositPricer
语法
irDepositPricer(instrument, pricingDate,
discountCurve)
详情
计算存款(Certificate of Deposit, CD)的定价。
参数
instrument
INSTRUMENT 类型标量,一个 Deposit 对象,表示需要定价的存款。
pricingDate
DATE 类型标量,表示定价日期。
discountCurve
MKTDATA 类型标量,一个 IrYieldCurve 对象,表示用于计算折现因子的即期曲线。
返回值
DOUBLE 类型标量。
例子
deposit = {
"productType": "Cash",
"assetType": "Deposit",
"version": 0,
"start": 2025.05.15,
"maturity": 2025.08.15,
"rate": 0.02,
"dayCountConvention": "Actual360",
"notional":["CNY", 1E6],
"payReceive": "Receive"
}
rate = deposit["rate"]
instrument = parseInstrument(deposit)
print(instrument)
pricingDate = 2025.06.10
curve_dict = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"version": 0,
"referenceDate": pricingDate,
"currency": "CNY",
"dayCountConvention": "Actual365",
"compounding": "Continuous", //连续复利
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates":[2025.07.25, 2030.09.25],
"values":[0.015, 0.015]
}
discountCurve = parseMktData(curve_dict)
irDepositPricer(instrument,2025.06.10,discountCurve)
// output:1002388.613154108868911
相关函数:
parseInstrument
,
parseMktData
FILE:references/doc_1943.md
# cdfStudent
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfStudent.html
**来源**: DolphinDB 官方文档
---
cdfStudent
语法
cdfStudent(df, X)
详情
返回 t 分布的累计密度函数的值。
参数
df
是正数,表示 t 分布的自由度。
X
是数值型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfStudent(1, [-1, 0, 0.5, 1, 2]);
// output
[0.25, 0.5, 0.647584, 0.75, 0.852416]
cdfStudent(1, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output
[0.531726, 0.592774, 0.647584, 0.6944, 0.733262]
FILE:references/doc_1950.md
# getStreamingRaftGroups
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getStreamingRaftGroups.html
**来源**: DolphinDB 官方文档
---
getStreamingRaftGroups
语法
getStreamingRaftGroups()
详情
获取当前节点所在的流数据 Raft 组的信息。
参数
无
返回值
一个表,第一列表示 Raft 组的 id,第二列表示 Raft 组包含的数据节点/计算节点信息。
例子
getStreamingRaftGroups();
id
sites
12
192.168.1.135:18102:NODE1,192.168.1.135:18103:NODE2,192.168.1.135:18104:NODE3
11
192.168.1.135:18102:NODE1,192.168.1.135:18103:NODE2,192.168.1.135:18105:NODE4
使用以下脚本可以获取当前集群所有流数据 Raft 组的信息。
select id,sites from pnodeRun(getStreamingRaftGroups) where isDuplicated([id,sites],FIRST)=false;
FILE:references/doc_1954.md
# asof join
**URL**: https://docs.dolphindb.cn/zh/progr/sql/asofjoin.html
**来源**: DolphinDB 官方文档
---
asof join
语法
aj(leftTable, rightTable, matchingCols, [rightMatchingCols])
参数
leftTable
和
rightTable
是连接的表。
matchingCols
是表示连接列的字符串标量或向量。
rightMatchingCols
是表示右表连接列的字符串标量或向量。当
leftTable和rightTable
至少有一个连接列不同时,必须指定
rightMatchingCols
。返回结果中的连接列与左表的连接列名称相同。
详情
asof join 和左连接函数十分相似,但有以下区别:
假设最后一个连接列为 time,对于左表中某 time=t 的行:
如果右表中其它连接列都匹配的记录中有 time=t 的记录,则取之(若有多行,则取其中最后一行);
若没有 time=t 的记录,则取这些记录中在 t 之前的最近时间对应的行(若有多行,则取其中最后一行)。
如果只有 1 个连接列,则 aj 函数假定右表已按照连接列排过序。如果有多个连接列,则 aj
函数假定右表根据除最后一个连接列外的其他连接列定义分组,每个分组根据最后一个连接列排序。右表的其他连接列不需要排序。如果这些条件不符合,处理将与期望值不符。左表不需要排序。
asof join 的最后一个连接列通常为时间类型,也可为整数类型,以及UUID或IPADDR类型。
注:
若
leftTable
不是分布式表,则其
rightTable
也不能是分布式表。
若
leftTable
和
rightTable
为分区表时,用于分组的连接列(即除了最后一个连接列之外的所有连接列)必须包含全部分区字段。
例子
t1 = table(2015.01.01+(0 31 59 90 120) as date, 1.2 7.8 4.6 5.1 9.5 as value)
t2 = table(2015.02.01+(0 15 89 89) as date, 1..4 as qty);
t1;
返回:
date
value
2015.01.01
1.2
2015.02.01
7.8
2015.03.01
4.6
2015.04.01
5.1
2015.05.01
9.5
t2;
返回:
date
qty
2015.02.01
1
2015.02.16
2
2015.05.01
3
2015.05.01
4
select * from lsj(t1, t2, `date);
返回:
date
value
qty
2015.01.01
1.2
2015.02.01
7.8
1
2015.03.01
4.6
2015.04.01
5.1
2015.05.01
9.5
3
select * from aj(t1, t2, `date);
返回:
date
value
t2_date
qty
2015.01.01
1.2
2015.02.01
7.8
2015.02.01
1
2015.03.01
4.6
2015.02.16
2
2015.04.01
5.1
2015.02.16
2
2015.05.01
9.5
2015.05.01
4
select * from aj(t1, t2, `date) where t1.date>=2015.03.01;
返回:
date
value
t2_date
qty
2015.03.01
4.6
2015.02.16
2
2015.04.01
5.1
2015.02.16
2
2015.05.01
9.5
2015.05.01
4
asof 连接的常用场景是在时间字段上作连接,用来获取最新信息。
假设有三张表,全部按照 minute 字段排过序。
minute = 09:30m 09:32m 09:33m 09:35m
price = 174.1 175.2 174.8 175.2
t1 = table(minute, price)
minute = 09:30m 09:31m 09:33m 09:34m
price = 29.2 28.9 29.3 30.1
t2 = table(minute, price)
minute =09:30m 09:31m 09:34m 09:36m
price = 51.2 52.4 51.9 52.8
t3 = table(minute, price);
t1;
返回:
minute
price
09:30m
174.1
09:32m
175.2
09:33m
174.8
09:35m
175.2
t2;
返回:
minute
price
09:30m
29.2
09:31m
28.9
09:33m
29.3
09:34m
30.1
t3;
返回:
minute
price
09:30m
51.2
09:31m
52.4
09:34m
51.9
09:36m
52.8
t2 = aj(t2, t3, `minute);
t2;
返回:
minute
price
t3_minute
t3_price
09:30m
29.2
09:30m
51.2
09:31m
28.9
09:31m
52.4
09:33m
29.3
09:31m
52.4
09:34m
30.1
09:34m
51.9
aj(t1, t2, `minute);
返回:
minute
price
t2_minute
t2_price
t3_minute
t3_price
09:30m
174.1
09:30m
29.2
09:30m
51.2
09:32m
175.2
09:31m
28.9
09:31m
52.4
09:33m
174.8
09:33m
29.3
09:31m
52.4
09:35m
175.2
09:34m
30.1
09:34m
51.9
注意,t2 和 t3 在 09:32m 时没有匹配记录,所以最近的 09:31m 时的价格被选中。而 t3 的 09:33m
时的价格,以及 t2 和 t3 在 09:35m
处的价格也使用了最近的前一条记录用来替代缺失的记录。这个功能在需要生成特定时间点的数据时特别有用。比如说,一些信息于每周或者每月更新一次。在设计一个日交易策略时,可以使用那些更新不是很频繁的数据,通过
asof 连接来生成每日数据集。
asof 最后一个连接列为 uuid 类型:
t1 = table(2015.01.01 2015.02.01 2015.03.01 2015.04.01 2015.05.01 as date, uuid(["5d212a78-cc48-e3b1-4235-b4d91473ee81", "5d212a78-cc48-e3b1-4235-b4d91473ee83", "5d212a78-cc48-e3b1-4235-b4d91473ee85", "5d212a78-cc48-e3b1-4235-b4d91473ee87", "5d212a78-cc48-e3b1-4235-b4d91473ee89"]) as uid)
t2 = table(2015.01.15 2015.01.20 2015.01.25 2015.03.01 as date,uuid(["5d212a78-cc48-e3b1-4235-b4d91473ee81", "5d212a78-cc48-e3b1-4235-b4d91473ee83", "5d212a78-cc48-e3b1-4235-b4d91473ee85", "5d212a78-cc48-e3b1-4235-b4d91473ee87"]) as uid)
select * from aj(t1, t2, `uid);
返回:
date
uid
t2_date
t2_uid
2015.01.01
5d212a78-cc48-e3b1-4235-b4d91473ee81
2015.01.15
5d212a78-cc48-e3b1-4235-b4d91473ee81
2015.02.01
5d212a78-cc48-e3b1-4235-b4d91473ee83
2015.01.20
5d212a78-cc48-e3b1-4235-b4d91473ee83
2015.03.01
5d212a78-cc48-e3b1-4235-b4d91473ee85
2015.01.25
5d212a78-cc48-e3b1-4235-b4d91473ee85
2015.04.01
5d212a78-cc48-e3b1-4235-b4d91473ee87
2015.03.01
5d212a78-cc48-e3b1-4235-b4d91473ee87
2015.05.01
5d212a78-cc48-e3b1-4235-b4d91473ee89
2015.03.01
5d212a78-cc48-e3b1-4235-b4d91473ee87
FILE:references/doc_1958.md
# 操作手册
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/clients.html
**来源**: DolphinDB 官方文档
---
操作手册
本节介绍用于数据库管理的 DolphinDB 客户端的用法和示例。
Web 集群管理器。基于浏览器的网页版客户端。
DolphinDB VS Code 插件。
基于 JAVA 开发的 GUI 客户端。
基于网页的 Jupyter Notebook 客户端。
基于命令行的 DolphinDB 终端。
详见以下各节。
FILE:references/doc_1959.md
# writeObject
**URL**: https://docs.dolphindb.cn/zh/funcs/w/writeObject.html
**来源**: DolphinDB 官方文档
---
writeObject
语法
writeObject(handle, object)
详情
object
是要写入的数据,可以把所有类型的数据结构(包括标量、向量、矩阵、集合、字典和表)写入句柄。该函数必须要用户登录后才能执行。
返回值
无。
例子
a1=10.5
a2=1..10
a3=cross(*,1..5,1..10)
a4=set(`IBM`MSFT`GOOG`YHOO)
a5=dict(a4.keys(),125.6 53.2 702.3 39.7)
a6=table(1 2 3 as id, `Jenny`Tom`Jack as name)
a7=(1 2 3, "hello world!", 25.6);
fout=file("test.bin","w")
fout.writeObject(a1)
fout.writeObject(a2)
fout.writeObject(a3)
fout.writeObject(a4)
fout.writeObject(a5)
fout.writeObject(a6)
fout.writeObject(a7)
fout.close();
FILE:references/doc_196.md
# mmaxPositiveStreak
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mmaxPositiveStreak.html
**来源**: DolphinDB 官方文档
---
mmaxPositiveStreak
语法
mmaxPositiveStreak(X, window)
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数衡量)的滑动窗口内统计
X
中连续正数之和的最大值。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
返回值
返回值类型与形式与
X
相同。
例子
x = 1 -1 1 -2 10 3 3 9 0 6 5
w = 5
mmaxPositiveStreak(x, w)
// output: [,,,,10,13,16,25,25,15,12]
x = 5 NULL 3 2 1 5 10 9 NULL 9 10 -1 NULL
w = 5
mmaxPositiveStreak(x, w)
// output: [,,,,6,11,21,27,25,24,19,19,19]
// 搭配 signum 函数用于统计向量中出现的连续正数的最大个数
mmaxPositiveStreak(signum(x), w)
// output: [,,,,3,4,5,5,4,3,2,2,2]
FILE:references/doc_1968.md
# updateMarketHoliday
**URL**: https://docs.dolphindb.cn/zh/funcs/u/updateMarketHoliday.html
**来源**: DolphinDB 官方文档
---
updateMarketHoliday
语法
updateMarketHoliday(marketName, holiday)
详情
在线覆盖内存中文件名为
marketName
的交易市场节假日
或交易日
文件,并同步更新至
marketHolidayDir
;若内存中不存在该文件,则报错。
注:
该函数只能由管理员调用。
该函数仅对当前节点有效。集群环境中,可通过
pnodeRun
调用该函数,使其在其它节点生效。
若手动修改了
marketHolidayDir
下的交易日历,想要在不关机的情况下,同步修改内容到内存,可以通过
loadText
将已修改的 csv
文件加载到内存表,并转换表数据为向量(holiday),然后通过该函数将
holiday
更新至内存。
参数
marketName
字符串标量,表示交易日历标识,例如:国外交易所的 ISO Code、国内交易所简称或自定义交易日历名称。
holiday
DATE 类型向量,用于指定交易日历的日期。其具体含义取决于该交易日历的日期类型:
若日期类型为“节假日”(默认),则
holiday
应指定为非周末的休市日期。
若日期类型为“交易日”,则
holiday
应指定为交易日期。
返回值
无。
例子
temporalAdd(2022.01.01,1,"CCFX")
返回:2022.01.04
index = [2022.01.01, 2022.01.02, 2022.01.03, 2022.01.04]
s = indexedSeries(index, 1..4)
s.resample("CCFX", sum);
返回:
label
col1
2021.12.31
6
2022.01.04
4
updateMarketHoliday("CCFX",2022.01.03 2022.01.04)
temporalAdd(2022.01.01,1,"CCFX")
返回:2022.01.05
FILE:references/doc_198.md
# msumTopN
**URL**: https://docs.dolphindb.cn/zh/funcs/m/msumTopN.html
**来源**: DolphinDB 官方文档
---
msumTopN
语法
msumTopN(X, S, window, top, [ascending=true],
[tiesMethod='oldest'])
参数说明和窗口计算规则请参考:
mTopN
详情
在给定长度(以元素个数衡量)的滑动窗口内,根据
ascending
指定的排序方式将
X
按照
S
进行稳定排序后,取前
top
个元素进行求和计算。
返回值
输入为向量时,返回一个与输入等长的向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
X = 1..7
S = 0.3 0.5 0.1 0.1 0.5 0.2 0.4
msumTopN(X, S, 4, 2)
// output: [1,3,4,7,7,7,10]
X = NULL 1 2 3 4 NULL 5
S = 3 5 1 1 5 2 4
msumTopN(X, S, 4, 2)
// output: [,1,2,5,5,5,3]
X = matrix(1..5, 6..10)
S = 2022.01.01 2022.02.03 2022.01.23 2022.04.06 2021.12.29
msumTopN(X, S, 3, 2)
#0
#1
1
6
3
13
4
14
5
15
8
18
X = matrix(1..5, 6..10)
S = matrix(2022.01.01 2022.02.03 2022.01.23 NULL 2021.12.29,NULL 2022.02.03 2022.01.23 2022.04.06 NULL)
msumTopN(X, S, 3, 2)
#0
#1
1
3
7
4
15
5
15
8
17
某行情数据的数据表,包含四列:股票代码 code,交易日期 date,收盘价 close 和交易量 volume。
t = table(take(`IBM`APPL, 20) as code, 2020.01.01 + 1..20 as date, rand(100,20) + 20 as volume, rand(10,20) + 100.0 as close)
code
date
volume
close
IBM
2020.01.02
50
107
APPL
2020.01.03
55
100
IBM
2020.01.04
75
100
APPL
2020.01.05
84
108
IBM
2020.01.06
46
103
APPL
2020.01.07
100
101
IBM
2020.01.08
96
100
APPL
2020.01.09
84
102
IBM
2020.01.10
60
107
APPL
2020.01.11
40
103
IBM
2020.01.12
92
105
APPL
2020.01.13
61
106
IBM
2020.01.14
86
107
APPL
2020.01.15
41
102
IBM
2020.01.16
85
103
APPL
2020.01.17
72
105
IBM
2020.01.18
46
108
APPL
2020.01.19
25
100
IBM
2020.01.20
114
102
APPL
2020.01.21
50
104
对每只股票计算窗口期内交易量最大的3条记录的收盘价之和。
select code, date, msumTopN(close, volume, 5, 3, false) from t context by code
code
date
msumTopN_close
APPL
2020.01.03
100
APPL
2020.01.05
208
APPL
2020.01.07
309
APPL
2020.01.09
311
APPL
2020.01.11
311
APPL
2020.01.13
311
APPL
2020.01.15
309
APPL
2020.01.17
313
APPL
2020.01.19
313
APPL
2020.01.21
315
IBM
2020.01.02
107
IBM
2020.01.04
207
IBM
2020.01.06
310
IBM
2020.01.08
307
IBM
2020.01.10
307
IBM
2020.01.12
305
IBM
2020.01.14
312
IBM
2020.01.16
312
IBM
2020.01.18
315
IBM
2020.01.20
314
相关函数:
msum
FILE:references/doc_1981.md
# tmsum
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmsum.html
**来源**: DolphinDB 官方文档
---
tmsum
语法
tmsum(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
的元素和。
返回值
X
为整型,返回 LONG 类型向量,
X
为浮点数,返回 DOUBLE 类型向量。
例子
tmsum(1 1 3 5 8 15 15 20, 5 2 4 1 2 8 9 10, 3)
// output
[5,7,11,5,2,8,17,10]
index = take(datehour(2019.06.13 13:30:10),4) join (datehour(2019.06.13 13:30:10)+1..6)
data = 1 NULL 3 4 5 NULL 3 NULL 5 3
tmsum(index, data, 4h)
// output
[1,1,4,8,13,13,16,8,8,11]
tmsum(index, data, 1d)
// output
[1,1,4,8,13,13,16,16,21,24]
相关函数:
msum
,
sum
FILE:references/doc_1985.md
# euclidean
**URL**: https://docs.dolphindb.cn/zh/funcs/e/euclidean.html
**来源**: DolphinDB 官方文档
---
euclidean
语法
euclidean(X, Y)
详情
若
X
和
Y
是标量或向量,计算
X
和
Y
之间的欧氏距离。
若
X
和
Y
是矩阵,计算每列元素之间的欧式距离,返回一个向量。 注意,若
X
或
Y
同时为索引矩阵或索引序列,会自动对齐标签,返回标签相同的行的计算结果,忽略标签不同的行。
与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
和
Y
是长度相同的数值型标量/向量/矩阵。
返回值
DOUBLE 类型标量或向量。
例子
a=[100, 0, 0]
b=[0, 51, NULL]
euclidean(a,b)
// output
112.254176
s1=indexedSeries(1 2 4, 10.4 11.2 9)
s2=indexedSeries(1 2 5, 23.5 31.2 26)
euclidean(s1,s2)
// output
23.9084
m=matrix(23 56 47, 112 94 59)
euclidean(a,m)
// output
[106.1791,111.6288]
m1=matrix(11 15 89, 52 41 63)
euclidean(m,m1)
// output
[59.9083,80.1561]
m.rename!(2020.01.01..2020.01.03, `A`B)
m.setIndexedMatrix!()
m1.rename!(2020.01.01 2020.01.03 2020.01.04, `A`B)
m1.setIndexedMatrix!()
euclidean(m,m1)
// output
[34.176,62.6418]
相关函数:
rowEuclidean
FILE:references/doc_1989.md
# rowImin
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowImin.html
**来源**: DolphinDB 官方文档
---
rowImin
语法
rowImin(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
返回每行元素中最小元素的索引。如果有多个相同的最小值,返回左起第一个最小值的索引。
返回值
结果为一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5 3.2, 1.5 4.8 5.9 1.7, 4.9 2.0 NULL 5.5])
rowImin(m)
返回:[1,2,0,1]
trades = table(10:0,`time`sym`p1`p2`p3`p4`p5`vol1`vol2`vol3`vol4`vol5,[TIMESTAMP,SYMBOL,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,INT,INT,INT,INT,INT])
insert into trades values(2022.01.01T09:00:00, `A, 33.2, 33.8, 33.6, 33.3, 33.1, 200, 180, 180, 220, 200)
insert into trades values(2022.01.01T09:00:00, `A, 33.1, 32.8, 33.2, 34.3, 32.3, 150, 280, 190, 100, 220)
insert into trades values(2022.01.01T09:00:00, `A, 31.2, 32.6, 33.6, 35.3, 34.5, 220, 160, 130, 100, 110)
insert into trades values(2022.01.01T09:00:00, `A, 30.2, 32.5, 33.6, 35.3, 34.1, 200, 180, 150, 140, 120)
insert into trades values(2022.01.01T09:00:00, `A, 33.2, 33.8, 33.6, 33.3, 33.1, 180, 160, 160, 180, 200)
select rowAt(matrix(p1, p2, p3, p4, p5), rowImin(vol1, vol2, vol3, vol4, vol5)) as price from trades
返回:
price
33.8
34.3
35.3
34.1
33.8
当 args 是数组向量时,返回每行元素中的最小元素的索引,结果为一个向量:
a = 1 8 3 8 1
b = 5 7 1 3 9
c = 5 5 4 3 6
x = fixedLengthArrayVector(a, b, c)
rowImin(x)
返回:[0,2,1,1,0]
FILE:references/doc_1993.md
# defs
**URL**: https://docs.dolphindb.cn/zh/funcs/d/defs.html
**来源**: DolphinDB 官方文档
---
defs
语法
defs([X])
详情
如果没有指定参数,将以表格的形式返回系统的所有函数。
如果指定了
X
,将以
X
的格式返回所有函数的名称。
参数
X
是字符串。它支持通配符"%"和"?"。"%"表示0,1或多个字符,“?”表示1个字符。
例子
defs();
name
isCommand
userDefined
minParamCount
maxParamCount
syntax
!=_2
0
0
2
2
(X, Y)
!_1
0
0
1
1
(X)
$_2
0
0
2
2
(obj, type)
%_2
0
0
2
2
(X, Y)
&&_2
0
0
2
2
(X, Y)
&_2
0
0
2
2
(X, Y)
**_2
0
0
2
2
(X, Y)
*_2
0
0
2
2
(X, Y)
+_2
0
0
2
2
(X, Y)
-_1
0
0
1
1
(X)
...
typestr defs();
// output
IN-MEMORY TABLE;
select * from defs() where name like "bit%";
name
isCommand
userDefined
minParamCount
maxParamCount
syntax
bitAnd
0
0
2
2
(X, Y)
bitNot
0
0
1
1
(X)
bitOr
0
0
2
2
(X, Y)
bitXor
0
0
2
2
(X, Y)
defs("bit%");
name
isCommand
userDefined
minParamCount
maxParamCount
syntax
bitAnd
0
0
2
2
(X, Y)
bitNot
0
0
1
1
(X)
bitOr
0
0
2
2
(X, Y)
bitXor
0
0
2
2
(X, Y)
defs("%sin");
name
isCommand
userDefined
minParamCount
maxParamCount
syntax
asin
0
0
1
1
(X)
sin
0
0
1
1
(X)
defs("?sin");
name
isCommand
userDefined
minParamCount
maxParamCount
syntax
asin
0
0
1
1
(X)
FILE:references/doc_1996.md
# equi join
**URL**: https://docs.dolphindb.cn/zh/progr/sql/equijoin.html
**来源**: DolphinDB 官方文档
---
equi join
语法
等值连接
ej(leftTable, rightTable, matchingCols, [rightMatchingCols], [leftFilter], [rightFilter])
兼容SQL的语法
select *
from leftTable
[inner] join rightTable on t1.matchingCol=t2.rightMatchingCol
[where leftFilter and rightFilter]
有序等值连接:
sej(leftTable, rightTable, matchingCols, [rightMatchingCols], [leftFilter], [rightFilter])
兼容SQL的语法
select *
from leftTable
[inner] join rightTable on leftTable.matchingCol=rightTable.rightMatchingCol
[where leftFilter and rightFilter]
order by matchingCol
参数
leftTable
和
rightTable
是连接的表。
matchingCols
是表示连接列的字符串标量或向量。
rightMatchingCols
是表示右表连接列的字符串标量或向量。当
leftTable
和
rightTable
至少有一个连接列不同时,必须指定
rightMatchingCols
。返回结果中的连接列与左表的连接列名称相同。
leftFilter
和
rightFilter
条件表达式,作为左右表字段的过滤条件。多个条件之间用 and 或 or
连接。注意:若
leftTable
/
rightTable
指定为维度表或分区表,不支持指定
leftFilter
,
rightFilter
。
详情
返回与连接列匹配的行。有序等值连接 sej 的结果表会根据连接字段进行排序。
例子
例1. 两个表等值连接,除了连接列外没有其他名称相同的列
t1= table(1 2 3 3 as id, 7.8 4.6 5.1 0.1 as value)
t2 = table(5 3 1 as id, 300 500 800 as qty);
t1;
id
value
1
7.8
2
4.6
3
5.1
3
0.1
t2;
id
qty
5
300
3
500
1
800
ej(t1, t2,`id);
等价于
select * from t1 inner join t2 on t1.id=t2.id
id
value
qty
1
7.8
800
3
5.1
500
3
0.1
500
ej(t2, t1,`id);
等价于
select * from t2 inner join t1 on t2.id=t1.id
id
qty
value
3
500
5.1
3
500
0.1
1
800
7.8
ej(t1, t2,`id,, t1.id==3);
等价于
select * from t1 inner join t2 on t1.id=t2.id where t1.id=3
id
value
qty
3
5.1
500
3
0.1
500
例2. 等值连接两张表,它们含有相同名字的列,但是不以它作为连接列:
t1 = table(1 2 3 3 as id, 7.8 4.6 5.1 0.1 as value, 4 3 2 1 as x);
t1;
id
value
x
1
7.8
4
2
4.6
3
3
5.1
2
3
0.1
1
t2 = table(5 3 1 as id, 300 500 800 as qty, 44 66 88 as x) ;
t2;
id
qty
x
5
300
44
3
500
66
1
800
88
select id, value, qty, x from ej(t1, t2, `id);
等价于
select id, value, qty, x from t1 inner join t2 on t1.id=t2.id
id
value
qty
x
1
7.8
800
4
3
5.1
500
2
3
0.1
500
1
我们无需指定value和qty来自哪个表。系统首先会在左表中定位这两个列,如果左表没有这两个列,系统会在右表定位。
select id, value, qty, t2.x from ej(t1, t2, `id);
等价于
select id, value, qty, t2.x from t1 inner join t2 on t1.id=t2.id
id
value
qty
x
1
7.8
800
88
3
5.1
500
66
3
0.1
500
66
ej(t1, t2, `id);
等价于
select * from t1 inner join t2 on t1.id=t2.id
id
value
x
qty
t2_x
1
7.8
4
800
88
3
5.1
2
500
66
3
0.1
1
500
66
ej选择了t1和t2中的两个x,然后将t2中的x重命名成t2_x。
例3. 多个连接列:
t1=table(1 1 2 2 3 3 as x, 1 2 2 3 3 4 as y, 1..6 as a);
t2=table(0 1 1 2 2 3 as x, 1 2 3 3 4 5 as y, 11..16 as b);
t1;
x
y
z
1
1
1
1
2
2
2
2
3
2
3
4
3
3
5
3
4
6
t2;
x
y
b
0
1
11
1
2
12
1
3
13
2
3
14
2
4
15
3
5
16
ej(t1, t2, `x`y);
// x, y是连接列
等价于
select * from t1 inner join t2 on t1.x=t2.x and t1.y=t2.y
x
y
a
b
1
2
2
12
2
3
4
14
t2.rename!(`x`y, `x2`y2);
x2
y2
b
0
1
11
1
2
12
1
3
13
2
3
14
2
4
15
3
5
16
ej(t1, t2, `x`y, `x2`y2);
// t1.x, t1.y t2.x2, t2.y2是连接列
等价于
select * from t1 inner join t2 on t1.x=t2.x2 and t1.y=t2.y2
x
y
a
b
1
2
2
12
2
3
4
14
例4. 连接表时,可以使用表的别名:
table1=table(1 1 2 2 3 3 as x, 1 2 2 3 3 4 as y, 1..6 as a, 21..26 as c)
table2=table(0 1 1 2 2 3 as x, 1 2 3 3 4 5 as y, 4..9 as a, 11..16 as b);
select * from ej(table1 as t1, table2 as t2, `x`y) where t2.a<7;
x
y
a
c
t2_a
b
1
2
2
22
5
12
在自连接时,必须使用表的别名:
t = table(`A`A`A`A`B`B`B`B as id, 1 3 6 9 1 9 12 17 as time, 1 2 6 3 5 9 4 0 as x)
select * from ej(t as a, t as b, `id) where a.time=b.time+3;
等价于
select * from t as a inner join t as b on a.id=b.id where a.time=b.time+3
id
time
x
b_time
b_x
A
6
6
3
2
A
9
3
6
6
B
12
4
9
9
例5. 指定
leftFilter
和
rightFilter
t1= table(1 2 3 3 as id1, 7.8 4.6 5.1 0.1 as value)
t2 = table(5 3 1 as id2, 300 500 800 as qty);
select * from ej(t1, t2, `id1, `id2, t1.value>1 and t1.value<6, t2.qty>300)
等价于
select * from t1 inner join t2 on t1.id1=t2.id2 where t1.value>1 and t1.value<6 and t2.qty>300
id1
value
qty
3
5.1
500
FILE:references/doc_2.md
# setMaxJobPriority
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setMaxJobPriority.html
**来源**: DolphinDB 官方文档
---
setMaxJobPriority
语法
setMaxJobPriority(userId, maxPriority)
详情
为给定用户指定其提交作业的最高优先级。该函数必须要用户登录后才能执行。
注:
该函数可在控制节点、数据节点和计算节点运行。
参数
userId
是一个字符串,表示用户名。
maxPriority
是一个0到8之间的整数,表示给定用户提交作业的最高优先级。
例子
login(`admin,`123456)
createUser(`KyleMurray, `Cardinals2020QB)
setMaxJobPriority(`KyleMurray, 7);
FILE:references/doc_2006.md
# svd
**URL**: https://docs.dolphindb.cn/zh/funcs/s/svd.html
**来源**: DolphinDB 官方文档
---
svd
语法
svd(obj, [fullMatrices=true], [computeUV=true])
详情
计算矩阵的奇异分解。
参数
obj
是一个矩阵。
fullMatrices
是一个布尔值,其默认值为 true。
computeUV
是一个布尔值,默认值为 true。
返回值
假设输入矩阵 A 的行数为 m,列数为 n:
若
fullMatrices
=true,结果为一个 m*m 矩阵 U(以左奇异向量为列的矩阵),一个
n*n 矩阵 V(以右奇异向量为行的矩阵)和一个向量 s(按降序排列的奇异值),并满足以下条件:A=U*S*V。其中 S 是一个 m*n
矩阵,其对角线元素为s。
若
fullMatrices
=false,S 矩阵仅保留有奇异值的那部分方阵,即矩阵 S 为
k*k,其中 k=min(m,n),并将与删除的这些行或列相乘的 U 与 V 中的行或列删除。矩阵 U 为 m*k,矩阵 V 为 k*n。
若
computeUV
=false时,只返回向量 s。
例子
m=matrix([[2,1,0],[1,3,1],[0,1,4],[1,2,3]]);
U,s,V=svd(m);
U;
#0
#1
#2
-0.233976
0.57735
-0.782254
-0.560464
0.57735
0.593756
-0.79444
-0.57735
-0.188498
s;
// output
[6.029042,3,1.284776]
V;
#0
#1
#2
#3
-0.170577
-0.449459
-0.620036
-0.620036
0.57735
0.57735
-0.57735
0
-0.755582
0.630862
-0.12472
-0.12472
-0.258199
-0.258199
-0.516398
0.774597
U,s,V=svd(m,fullMatrices=false);
V;
#0
#1
#2
#3
-0.170577
-0.449459
-0.620036
-0.620036
0.57735
0.57735
-0.57735
0
-0.755582
0.630862
-0.12472
-0.12472
FILE:references/doc_2007.md
# piecewiseLinFit
**URL**: https://docs.dolphindb.cn/zh/funcs/p/piecewiselinfit.html
**来源**: DolphinDB 官方文档
---
piecewiseLinFit
语法
piecewiseLinFit(X, Y, numSegments, [XC], [YC], [bounds],
[lapackDriver='gelsd'], [degree=1], [weights], [method='de'], [maxIter],
[initialGuess], [seed])
详情
通过给定数据点集和给定线段数,拟合一个连续的分段线性回归函数;并使用差分进化算法通过最小化平方误差之和,找到给定数量的线段断点的最优位置。
注意:由于差分进化算法的随机性,本函数每次运行结果会略有区别。
参数
X
数值向量,表示数据点的 x 坐标值。仅在
method
='de' 时生效。注意:不可传入 NULL 值。
Y
数值向量,表示数据点的 y 坐标值。仅在
method
='de' 时生效。注意:不可传入 NULL 值。
numSegments
正整数,表示用于拟合的线段数量。
XC
可选参数,数值向量,表示分段线性函数将被强制通过的数据点的 x 位置。
YC
可选参数,数值向量,表示分段线性函数将被强制通过的数据点的 y 位置。
bounds
可选参数,数值矩阵,表示在优化中每个断点位置的边界。形状为(numSegments - 1, 2),每一行为对应断点的边界。
lapackDriver
可选参数,字符串标量,表示使用具体的某个 LAPACK 程序来求解最小二乘问题。可选值为'gelsd', 'gelsy' 和
'gelss'。
degree
可选参数,非负整数标量,表示要使用的多项式的阶数。degree=1 表示使用线性模型;degree=0 表示使用常数模型。
weights
可选参数,数值向量,表示加权最小二乘法中的权重。单个权重通常是每个数据点标准偏差的倒数,即
weights[i]
为第 i
个数据点标准差的倒数。注意:不可传入 NULL 值。
method
可选参数,字符串标量,表示在拟合过程中使用的最优化算法。可选值为:
“nm“:表示使用 Nelder-Mead 单纯形算法。
“bfgs“:表示使用 bfgs 算法。
“lbfgs“ :表示使用 lbfgs 算法。
'slsqp':表示顺序最小二乘编程方法(SLSQP)算法。
'de':表示差分进化(Differential Evolution)算法,默认值。
maxIter
可选参数,整型标量或向量,表示拟合过程中优化算法的最大迭代次数。
initialGuess
可选参数,数值向量,表示分段断点位置的初始猜测,长度为
numSegments
- 1。
seed
可选参数,整数标量,表示差分进化算法中使用的随机数种子,仅在
method
='de' 或
initialGuess
为空时生效。若
method
='de' 或
initialGuess
为空,且不指定
seed
,则采用非确定性的随机数生成器。
seed
参数用于确保结果的可复现性。
返回值
返回一个字典,字典有以下成员:
breaks:浮点数向量,表示模型拟合后得到的线段断点位置。
beta:浮点数向量,表示模型拟合后的参数值。
xData:浮点数向量,表示输入的数据点的 x 坐标值。
yData:浮点数向量,表示输入的数据点的 y 坐标值。
XC:浮点数向量,表示分段线性函数将被强制通过的数据点的 x 位置。
YC:浮点数向量,表示分段线性函数将被强制通过的数据点的 y 位置。
weights:浮点数向量,表示加权最小二乘法中的权重。
degree:整数标量,表示要使用的多项式的阶数。
lapackDriver:字符串标量,表示使用的具体 LAPACK 程序来求解最小二乘问题。
numParameters:整数标量,表示模型的参数数量。
predict:模型的预测函数。其使用方法为
model.predict(X, [beta],
[breaks])
,详情见
pwlfPredict
。
modelName:表示模型类型,值为字符串”Piecewise Linear Regression”。
例子
本例自定义条件,传入参数
X
,
Y
,
numSegments
,拟合一个连续的分段线性回归函数,并找到 3
个线段断点的最优位置。
def linspace(start, end, num, endpoint=true){
if(endpoint) return end$DOUBLE\(num-1), start + end$DOUBLE\(num-1)*0..(num-1)
else return start + end$DOUBLE\(num-1)*0..(num-1)
}
X = linspace(0.0, 1.0, 10)[1]
Y = [0.41703981, 0.80028691, 0.12593987, 0.58373723, 0.77572962, 0.41156172, 0.72300284, 0.32559528, 0.21812564, 0.41776427]
model = piecewiseLinFit(X, Y, 3)
model;
/* Output:
breaks->[0.0,0.258454644769,0.366954310101,1.000000000000]
numParameters->4
degree->1
xData->[0.0,0.111111111111,0.222222222222,0.333333333333,0.444444444444,0.555555555555,0.666666666666,0.777777777777,0.888888888888,1.000000000000]
predict->pwlfPredict
yData->[0.417039810000,0.800286910000,0.125939870000,0.583737230000,0.775729620000,0.411561720000,0.723002840000,0.325595280000,0.218125640000,0.417764270000]
yC->
xC->
weights->
beta->[0.593305500750,-1.309949743583,5.703647584013,-5.105351630664]
lapackDriver->gelsd
*/
承接上例,
piecewiseLinFit
也可结合函数
pwlfPredict
使用。如下自定义参数,使用拟合后的连续分段线性回归模型来对输入的数据点进行预测。
xHat = linspace(0.0, 1.0, 20)[1]
model.predict(xHat)
/* Output:
[0.593305499919518 0.524360777381737 0.455416054843957 0.386471332306177 0.317526609768396 0.368043438179296 0.529813781212159 0.691584124245021 0.69295837868457 0.655502915538459 0.618047452392347 0.580591989246236 0.543136526100125 0.505681062954014 0.468225599807903 0.430770136661792 0.393314673515681 0.35585921036957 0.318403747223459 0.280948284077348]
*/
相关函数:
pwlfPredict
FILE:references/doc_2025.md
# lastWeekOfMonth
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lastWeekOfMonth.html
**来源**: DolphinDB 官方文档
---
lastWeekOfMonth
语法
lastWeekOfMonth(X, [weekday=0], [offset],
[n=1])
详情
返回
X
所在月份或上一个月份中最后一个
weekday
对应的日期。假设
X
所在月份的最后一个
weekday
对应日期为 d:
如果
X<d
,
lastWeekOfMonth
函数返回
X
的上一个月中最后一个
weekday
对应的日期。
如果
X>=d
,
lastWeekOfMonth
函数返回
X
所在月份的最后一个
weekday
对应的日期。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
个月更新一次。注意,只有当
n
>1时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
weekday
是0到6之间的整数,表示星期编号。0表示星期一,1表示星期二,... ,6表示星期日。默认值为0。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,offset默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型的标量或向量。
例子
lastWeekOfMonth(2019.11.24,2);
// output
2019.10.30
// 2019年11月最后一个星期三为2019.11.27,2019.11.24在2019.11.27之前,因此返回2019年10月的最后一个星期三
lastWeekOfMonth(2019.11.29,2);
// output
2019.11.27
date=2012.01.02 2012.02.03 2012.03.07 2012.04.08 2012.05.12 2012.06.16 2012.07.18 2012.08.20 2012.09.25 2012.10.28
time = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12,09:38:13]
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
select avg(price),sum(qty) from t1 group by lastWeekOfMonth(date,4,2012.01.01,2);
lastWeekOfMonth_date
avg_price
sum_qty
2011.12.30
39.53
4100
2012.02.24
29.77
5300
2012.04.27
175.1
12200
2012.06.29
50.54
3800
2012.08.31
51.29
8800
2012.10.26
52.38
4500
FILE:references/doc_2043.md
# deleteUser
**URL**: https://docs.dolphindb.cn/zh/funcs/d/deleteUser.html
**来源**: DolphinDB 官方文档
---
deleteUser
语法
deleteUser(userId)
详情
删除一个用户。
注:
该函数只能由管理员在控制节点、数据节点和计算节点运行。
参数
userId
是表示用户名的字符串。
返回值
无。
例子
deleteUser(`JohnSmith);
FILE:references/doc_2048.md
# rowSize
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowSize.html
**来源**: DolphinDB 官方文档
---
rowSize
语法
rowSize(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行元素统计(包含空值)操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL]);
rowSize(m);
// output
[3,3,3]
t1=table(1 NULL 3 NULL 5 as x, 6..10 as y);
t2=table(5 NULL 3 NULL 1 as a, 10..6 as b);
rowSize(t1);
// output
[2,2,2,2,2]
rowCount(t1[`x], t2, 1 NULL 2 NULL NULL);
// output
[4,1,4,1,3]
rowSize(t1[`x], t2, 1 NULL 2 NULL NULL);
// output
[4,4,4,4,4]
t=table(`AAPL`MS`IBM`IBM`C as sym, [49.6, NULL, 29.52, NULL, 174.97] as price1, [175.23, NULL, 50.32, 51.29, 26.23] as price2);
select sym,rowSize(price1,price2) as size from t;
输出返回:
sym
size
AAPL
2
MS
2
IBM
2
IBM
2
C
2
相关函数:
rowCount
,
size
FILE:references/doc_2049.md
# existsCatalog
**URL**: https://docs.dolphindb.cn/zh/funcs/e/existsCatalog.html
**来源**: DolphinDB 官方文档
---
existsCatalog
语法
existsCatalog(catalog)
详情
检查指定 catalog 是否存在。
参数
catalog
字符串标量,表示 catalog 的名称。
返回值
布尔类型标量。 false 和 true 分别表示指定的 catalog 不存在、存在。
FILE:references/doc_2072.md
# gmm
**URL**: https://docs.dolphindb.cn/zh/funcs/g/gmm.html
**来源**: DolphinDB 官方文档
---
gmm
语法
gmm(X, k, [maxIter=300], [tolerance=1e-4], [randomSeed], [mean],
[sigma])
详情
通过数据集训练 GMM(高斯混合模型)。
参数
X
训练数据集。若为一元数据,则
X
是一个向量;若为多元数据,则
X
是一个矩阵或表,矩阵的每列代表一个样本数据。
k
正整数。表示混合模型中子模型的数量。
maxlter
正整数,表示最大的迭代次数。默认为 300。
tolerance
浮点数,表示 EM 迭代中止的边界差值。如果相邻两次迭代的对数似然函数值的差值小于
tolerance
,则停止迭代。默认为
1e-4。
randomSeed
随机数种子。
mean
可选参数,向量/矩阵。表示模型初始化的均值。若
X
为一元数据,则
mean
是元素个数为
k
的向量;若
X
为多元数据,则
mean
是列数为
k
,行数与
X
的元数相同的矩阵。若不指定,系统随机从
X
中选择
k
个值作为模型的初始化均值。
sigma
可选参数,向量/元组,元素个数为
k
。若
X
为一元数据,表示每个子模型初始化的方差;若
X
为多元数据,表示每个子模型初始化的协方差矩阵。若不指定,系统使用 1 作为方差,或单位矩阵作为协方差矩阵。
返回值
返回一个字典,包含以下键值:
modelName:字符串 "Gaussian Mixture Model"。
prior:观测数据属于各子模型的先验概率。
mean:训练获得的每个子模型的期望。
sigma:若
X
为 一元数据,表示训练获得的每个子模型的方差;若
X
为多元数据,表示训练获得的每个子模型的协方差矩阵。
例子
dataT = 6.8 7.2 5.3 9.4 6.5 11.2 25.6 0.6 8.9 4.3 2.2 1.9 8.7 0.2 1.5
mean = [2, 2]
re = gmm(dataT, 2, 300, 1e-4, 42, mean)
re
// output
sigma->[36.759822,36.759822]
modelName->Gaussian Mixture Model
prior->[0.5,0.5]
mean->[6.686667,6.686667]
dataT = transpose(matrix(3.2 1.5 2.6 7.8 6.3 4.2 5.1 8.9 11.2 25.8, 25.6 4.6 8.9 4.3 2.2 1.9 8.7 0.2 1.5 9.3))
mean = transpose(matrix([1, 0], [0, 1]))
re = gmm(dataT, 2, 300, 1e-4, 42, mean)
re
// output
sigma->(#0 #1
51.001369 18.273032
18.273032 9.34789
,#0 #1
1.718475 0.629584
0.629584 67.713701
)
modelName->Gaussian Mixture Model
prior->[0.558683,0.441317]
mean->
#0 #1
11.152841 3.238262
3.341493 10.996997
FILE:references/doc_2080.md
# notLike/NOTLIKE
**URL**: https://docs.dolphindb.cn/zh/progr/sql/notlike.html
**来源**: DolphinDB 官方文档
---
notLike/NOTLIKE
NOTLIKE 是与 LIKE 相反的操作,用于确定特定字符串是否与指定模式不匹配。其功能与
notLike
函数、NOT LIKE 相同。notLike 支持内存表和分布式表。
语法
match_expression notLike pattern
参数
match_expression
任何有效的字符串类型的表达式。
pattern
要在 match_expression 中搜索并且可以包含有效通配符的字符串(区分大小写)。有效通配符如下:
% 匹配零个或多个字符的任何字符串。
? 匹配任何单个字符。
用法
如果 match_expression 与 pattern 不匹配,则 notLike 返回 true;否则,notLike返回 false。
notLike 通常和 where 子句搭配使用,根据指定的模式过滤数据。例如:使用 notLike 来查找不以 “A“ 开头、不以 “b“ 结尾、或不包含
“Ca“ 的数据。
例子
t= table(`a1`a2`a3`b`b2`b3`ca1`ca2 as id, 7 4 NULL 1 8 NULL 12 NULL as val)
select * from t where id notLike "a%"
// 等价于 select * from t where id not like "a%"
id
val
b
1
b2
8
b3
ca1
12
ca2
查询 id 列中不以 “b” 结尾的记录
select * from t where id notLike "%b"
id
val
a1
7
a2
4
a3
b2
8
b3
ca1
12
ca2
查询 id 列中不包含字符串 “a” 的记录
select * from t where id notLike "%a%"
id
val
b
1
b2
8
b3
FILE:references/doc_2090.md
# monthOfYear
**URL**: https://docs.dolphindb.cn/zh/funcs/m/monthOfYear.html
**来源**: DolphinDB 官方文档
---
monthOfYear
语法
monthOfYear(X)
详情
返回
X
中的月份。
参数
X
可以是 DATE, MONTH, DATETIME, TIMESTAMP 或 NANOTIMESTAMP 类型的标量、向量或表。
返回值
整型标量或向量。
例子
monthOfYear(2012.07.02);
// output: 7
monthOfYear([2012.06.12T12:30:00,2012.10.28T12:35:00,2013.01.06T12:36:47,2013.04.06T08:02:14]);
// output: [6,10,1,4]
相关函数:
dayOfYear
,
dayOfMonth
,
quarterOfYear
,
weekOfYear
,
hourOfDay
,
minuteOfHour
,
secondOfMinute
,
millisecond
,
microsecond
,
nanosecond
FILE:references/doc_2101.md
# member
**URL**: https://docs.dolphindb.cn/zh/funcs/m/member.html
**来源**: DolphinDB 官方文档
---
member
语法
member(X, Y)
或
X.Y
详情
返回对象的指定成员/属性。
参数
X
可以是表或字典。
Y
是
X
的一个成员或属性。若使用 member(X, Y) 方式,
Y
必须是字符串。
例子
x=1 2 3
y=4 5 6
t=table(x,y);
t.x;
// output: [1,2,3]
t.y;
// output: [4,5,6]
t.rows();
// output: 3
t.cols();
// output: 2
t.size();
// output: 3
// 表的 size 定义为它的行数
d = dict(1 2 3, 4 5 6);
d;
// output
3->6
1->4
2->5
d.2;
// output: 5
FILE:references/doc_2105.md
# createLeftSemiJoinEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createLeftSemiJoinEngine.html
**来源**: DolphinDB 官方文档
---
createLeftSemiJoinEngine
语法
createLeftSemiJoinEngine(name, leftTable, rightTable,
outputTable, metrics, matchingColumn, [garbageSize=5000],
[updateRightTable=false]
, [snapshotDir],
[snapshotIntervalInMsgCount]
)
详情
创建流数据左半等值连接引擎,返回一个左、右表关联后的表对象。对于左表每一条数据,都去匹配右表相同
matchingColumn
的数据,若无匹配的右表记录,则不输出。若匹配多条右表记录,则由
updateRightTable
参数决定连接右表的第一条记录还是最新一条记录。
注:
右表根据
updateRightTable
指定的策略,同一
matchingColumn
只保留第一条或者最新一条数据,历史数据不再进行垃圾回收,因此用户需要控制
matchingColumn
的唯一值数量,否则可能会导致内存溢出。
参数
name
表示流数据 left semi join
引擎的名称,作为其在一个数据节点/计算节点上的唯一标识。可包含字母,数字和下划线,但必须以字母开头。
leftTable
表对象。可以不包含数据,但结构必须与输入的流数据表相同。
自 2.00.11
版本开始,该参数支持 array vector。
rightTable
表对象。可以不包含数据,但结构必须与输入的流数据表相同。
自 2.00.11
版本开始,该参数支持 array vector。
outputTable
为计算结果的输出表。在使用
createLeftSemiJoinEngine
函数之前,需要将输出表预先设立为一个空表,并指定各列列名以及数据类型。
自 2.00.11
版本开始,引擎支持通过自定义聚合函数,将多个计算结果以 array vector 的形式输出,此时必须在该参数中指定对应列类型为 array
vector。
输出表的各列的顺序如下:
连接列。与
matchingColumn
中的列以及其顺序一致,可为多列。
计算结果列。可为多列。
metrics
以元代码的格式表示计算指标,支持输入元组。有关元代码的更多信息可参考
Metaprogramming
。
计算指标可以是一个或多个表达式、系统内置或用户自定义函数、一个常量标量/向量。当指定为常量向量时,对应的输出列必须设置为数组向量类型,例子参见
createReactiveStateEngine
中的例4。
metrics
内支持调用具有多个返回值的函数,且必须指定列名,例如 <func(price) as
`col1`col2>。
若在
metrics
指定了
leftTable
和
rightTable
中具有相同名称的列,默认取左表的列,可以通过 "tableName.colName"
指定该列来自哪个表。
注:
metrics
中使用的列名大小写不敏感,不需要与输入表的列名大小写保持一致。
matchingColumn
表示连接列的字符串标量/向量或字符串向量组成的 tuple,支持 Integral,
Temporal 或 Literal(UUID 除外)类型。
matchingColumn
指定规则:
只有一个连接列。当左表和右表的连接列名相同时,
matchingColumn
是一个字符串标量,否则是一个长度为 2 的
tuple。例如:左表连接列名为 sym,右表连接列名为 sym1,则
matchingColumn
=
[[`sym],[`sym1]]。
有多个连接列。当左表和右表的连接列名相同时,
matchingColumn
是一个字符串向量,否则是一个长度为 2 的
tuple。例如:左表连接列名为 timestamp, sym,右表连接列名为 timestamp, sym1,则
matchingColumn
= [[`timestamp, `sym], [`timestamp,`sym1]]。
garbageSize
可选参数,正整数,默认值是 5,000(单位为行)。和其他连接引擎不同,该函数的
garbageSize
参数只用于清理左表的历史数据。当左表发生过 join 的记录数超过
garbageSize
时,系统会触发清理。
updateRightTable
可选参数,布尔值,默认为 false,表示右表存在多条相同
matchingColumn
的记录时,是保留第一条(false)还是最新一条记录(true)。
若要开启快照机制 (snapshot),必须指定
snapshotDir
与
snapshotIntervalInMsgCount
。
snapshotDir
可选参数,字符串,表示保存引擎快照的文件目录。
指定的目录必须存在,否则系统会提示异常。
创建流数据引擎时,如果指定了
snapshotDir
,会检查该目录下是否存在快照。如果存在,会加载该快照,恢复引擎的状态。
多个引擎可以指定同一个目录存储快照,用引擎的名称来区分快照文件。
一个引擎的快照可能会使用三个文件名:
临时存储快照信息:文件名为 <engineName>.tmp;
快照生成并刷到磁盘:文件保存为 <engineName>.snapshot;
存在同名快照:旧快照自动重命名为 <engineName>.old。
snapshotIntervalInMsgCount
可选参数,为整数类型,表示每隔多少条数据保存一次流数据引擎快照。
返回值
返回一个表对象。
例子
share streamTable(1:0, `time`sym`price, [TIMESTAMP, SYMBOL, DOUBLE]) as leftTable
share streamTable(1:0, `time`sym1`vol, [TIMESTAMP, SYMBOL, INT]) as rightTable
share table(100:0, `time`sym`price`vol`total, [TIMESTAMP, SYMBOL, DOUBLE, INT, DOUBLE]) as output
lsjEngine=createLeftSemiJoinEngine(name="test1", leftTable=leftTable, rightTable=rightTable, outputTable=output, metrics=<[price, vol,price*vol]>, matchingColumn=[[`time,`sym], [`time,`sym1]], updateRightTable=true)
subscribeTable(tableName="leftTable", actionName="joinLeft", offset=0, handler=appendForJoin{lsjEngine, true}, msgAsTable=true)
subscribeTable(tableName="rightTable", actionName="joinRight", offset=0, handler=appendForJoin{lsjEngine, false}, msgAsTable=true)
v = [1, 5, 10, 15]
tp1=table(2012.01.01T00:00:00.000+v as time, take(`AAPL, 4) as sym, rand(100,4) as price)
leftTable.append!(tp1)
v = [1, 1, 3, 4, 5, 5, 5, 15]
tp2=table(2012.01.01T00:00:00.000+v as time, take(`AAPL, 8) as sym, rand(100,8) as vol)
rightTable.append!(tp2)
select * from output
time
sym
price
vol
total
2012.01.01T00:00:00.001
AAPL
44
76
3344
2012.01.01T00:00:00.005
AAPL
15
64
960
2012.01.01T00:00:00.015
AAPL
24
75
1800
若要再次执行以上脚本,需要先删除引擎并取消订阅:
dropStreamEngine("test1")
lsjEngine=NULL
unsubscribeTable(tableName="leftTable", actionName="joinLeft")
unsubscribeTable(tableName="rightTable", actionName="joinRight")
FILE:references/doc_2110.md
# var
**URL**: https://docs.dolphindb.cn/zh/funcs/v/var.html
**来源**: DolphinDB 官方文档
---
var
语法
var(X)
详情
若
X
为向量,返回
X
的方差(variance)。
若
X
为矩阵,计算每列的方差,返回一个向量。
若
X
为表,计算每列的方差,返回一个表。
与所有其它聚合函数一致,计算时忽略 NULL 值。
请注意,返回无偏样本方差(unbiased sample variance),而不是总体方差。
无偏样本方差的公式如下:
s
2
=
1
n
-
1
∑
i
=
1
n
(
x
i
-
x
¯
)
2
参数
X
可以是标量、向量、矩阵或表。
返回值
DOUBLE 类型标量/向量/表。
例子
var(1 1 1);
// output
0
var(1 2 3);
// output
1
m=matrix(1 3 5 7 9, 1 4 7 10 13);
m;
#0
#1
1
1
3
4
5
7
7
10
9
13
var(m);
// output
[10,22.5]
相关函数:
covar
和
corr
FILE:references/doc_2123.md
# cdfPoisson
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfPoisson.html
**来源**: DolphinDB 官方文档
---
cdfPoisson
语法
cdfPoisson(mean, X)
详情
返回泊松分布的累计分布函数的值。
参数
mean
是泊松分布的均值。
X
是整型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfPoisson(1, [-1, 0, 1, 2, 3]);
// output
[0, 0.367879, 0.735759, 0.919699, 0.981012]
cdfPoisson(1, [1, 3, 5, 7, 9]);
// output
[0.735759, 0.981012, 0.999406, 0.99999, 1]
FILE:references/doc_2136.md
# nanotimestamp
**URL**: https://docs.dolphindb.cn/zh/funcs/n/nanotimestamp.html
**来源**: DolphinDB 官方文档
---
nanotimestamp
语法
nanotimestamp(X)
详情
返回由日期和精确到纳秒的时间组成的时间戳。返回值类型是 NANOTIMESTAMP,时间类型变量。如果参数
X
不是日期和时间,则返回值是 1970.01.01 00:00:00.000000000 +
X
纳秒的时间戳。
注:
自 2.00.12 版本起,支持转换 MONTH 类型的数据。
参数
X
可以是整型标量或向量、时间标量或向量。
返回值
NANOTIMESTAMP 类型标量或向量。
例子
nanotimestamp(1);
返回:1970.01.01 00:00:00.000000001
nanotimestamp(1000000000);
返回:1970.01.01 00:00:01.000000000
nanotimestamp(2012.12.03 12:06:09 2012.12.03 13:08:01);
返回:[2012.12.03 12:06:09.000000000,2012.12.03 13:08:01.000000000]
nanotimestamp(2012.12.03 01:22:01.123456789);
返回:2012.12.03 01:22:01.123456789
nanotimestamp('2012.12.03 13:30:10.008007006');
返回:2012.12.03 13:30:10.008007006
nanotimestamp(now());
返回:2024.02.22 16:14:28.627000000
nanotimestamp(2012.01M)
返回:2012.01.01T00:00:00.000000000
FILE:references/doc_2140.md
# setPrefetchComputeNodeData
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setprefetchcomputenodedata.html
**来源**: DolphinDB 官方文档
---
setPrefetchComputeNodeData
语法
setPrefetchComputeNodeData(flag)
详情
在线设置当前节点下配置项
enableComputeNodePrefetchData
的生效值。只能由管理员在控制节点执行。
参数
flag
布尔值,表示配置项
enableComputeNodePrefetchData
的内存生效值。
例子
setPrefetchComputeNodeData(false)
相关函数:
getPrefetchComputeNodeData
FILE:references/doc_2146.md
# sql
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sql.html
**来源**: DolphinDB 官方文档
---
sql
语法
sql(select, from, [where], [groupBy], [groupFlag],
[csort], [ascSort], [having], [orderBy], [ascOrder], [limit], [hint],
[exec=false], [map=false])
详情
动态生成 SQL 语句。使用函数
eval
执行生成的 SQL
语句。
参数
select
是表示选取的列的元代码。每列由函数
sqlCol
或
sqlColAlias
生成。若选择多列,使用元组表示。
from
选取数据的表对象或表名称。
where
where 条件。如果有多个 where 条件,使用 ANY 向量来表示,每个元素对应一个条件的元代码。
groupBy
group by 后面的关键字(列名)。如果有多个 group by 关键字,使用 ANY
向量来表示,每个元素对应一个列名的元代码。
groupFlag
1表示 group by,0表示 context by,2表示 pivot by。默认值为1。
csort
csort 后面的关键字(列名)。只有当
groupFlag
=0,即使用 context by 时,才能指定该参数。如果有多个
csort 关键字,使用元组来表示,每个元素对应一个列名的元代码。
ascSort
表示 csort 关键字按升序或降序排列的整型标量或向量。1表示升序,0表示降序。默认值为1。
having
having 条件。如果有多个 having 条件,使用 ANY 向量来表示,每个元素对应一个条件的元代码。
orderBy
order by 后面的关键字(列名)。如果有多个 order by 关键字,使用 ANY
向量来表示,每个元素对应一个列名的元代码。
ascOrder
表示 order by 后面的关键字按升序或降序排列的整型标量或向量。1表示升序,0表示降序。默认值为1。
limit
整数或整型数据对,用于指定返回记录的行范围,语义对应 SQL 中的 top 语句。
limit
为整数(例如 n)时,表示返回前 n 行。
limit 为数据对(start:end)时,表示返回从 start 行开始(含)到第 end 行(不含)的记录。
如果指定了
groupBy
且
groupFlag
=0,则
limit
在每个分组内单独应用。
hint
常量。目前该参数可以是 HINT_HASH、HINT_SNAPSHOT 或 HINT_KEEPORDER。HINT_HASH 表示执行 group
by 查询时采用哈希算法,HINT_SNAPSHOT 表示从快照引擎中查询数据,HINT_KEEPORDER 表示执行context by
后的结果仍然按输入数据中的顺序排列。
exec
表示是否使用 exec 子句。默认值为 false。若设置为 true,可以生成一个标量或者一个向量,与 pivot by
共同使用,可以生成一个矩阵。
map
布尔类型的标量,表示是否使用 map 关键字,默认值为 false。
返回值
CODE 类型标量。
例子
symbol = take(`GE,6) join take(`MSFT,6) join take(`F,6)
date=take(take(2017.01.03,2) join take(2017.01.04,4), 18)
price=31.82 31.69 31.92 31.8 31.75 31.76 63.12 62.58 63.12 62.77 61.86 62.3 12.46 12.59 13.24 13.41 13.36 13.17
volume=2300 3500 3700 2100 1200 4600 1800 3800 6400 4200 2300 6800 4200 5600 8900 2300 6300 9600
t1 = table(symbol, date, price, volume);
t1;
symbol
date
price volume
GE
2017.01.03
31.82 2300
GE
2017.01.03
31.69 3500
GE
2017.01.04
31.92 3700
GE
2017.01.04
31.8 2100
GE
2017.01.04
31.75 1200
GE
2017.01.04
31.76 4600
MSFT
2017.01.03
63.12 1800
MSFT
2017.01.03
62.58 3800
MSFT
2017.01.04
63.12 6400
MSFT
2017.01.04
62.77 4200
MSFT
2017.01.04
61.86 2300
MSFT
2017.01.04
62.3 6800
F
2017.01.03
12.46 4200
F
2017.01.03
12.59 5600
F
2017.01.04
13.24 8900
F
2017.01.04
13.41 2300
F
2017.01.04
13.36 6300
F
2017.01.04
13.17 9600
x=5000
whereConditions = [<symbol=`MSFT>,<volume>x>]
havingCondition = <sum(volume)>200>;
sql(sqlCol("*"), t1);
//output:< select * from t1 >
sql(sqlCol("*"), t1, whereConditions);
//output:< select * from t1 where symbol == "MSFT",volume > x >
sql(select=sqlColAlias(<avg(price)>), from=t1, where=whereConditions, groupBy=sqlCol(`date));
//output:< select avg(price) as avg_price from t1 where symbol == "MSFT",volume > x group by date >
sql(select=sqlColAlias(<avg(price)>), from=t1, groupBy=[sqlCol(`date),sqlCol(`symbol)]);
//output:< select avg(price) as avg_price from t1 group by date,symbol >
sql(select=(sqlCol(`symbol),sqlCol(`date),sqlColAlias(<cumsum(volume)>, `cumVol)), from=t1, groupBy=sqlCol(`date`symbol), groupFlag=0);
//output:< select symbol,date,cumsum(volume) as cumVol from t1 context by date,symbol >
sql(select=(sqlCol(`symbol),sqlCol(`date),sqlColAlias(<cumsum(volume)>, `cumVol)), from=t1, where=whereConditions, groupBy=sqlCol(`date), groupFlag=0);
//output:< select symbol,date,cumsum(volume) as cumVol from t1 where symbol == "MSFT",volume > x context by date >
sql(select=(sqlCol(`symbol),sqlCol(`date),sqlColAlias(<cumsum(volume)>, `cumVol)), from=t1, where=whereConditions, groupBy=sqlCol(`date), groupFlag=0, csort=sqlCol(`volume), ascSort=0);
//output:< select symbol,date,cumsum(volume) as cumVol from t1 where symbol == "MSFT",volume > x context by date csort volume desc >
sql(select=(sqlCol(`symbol),sqlCol(`date),sqlColAlias(<cumsum(volume)>, `cumVol)), from=t1, where=whereConditions, groupBy=sqlCol(`date), groupFlag=0, having=havingCondition);
//output:< select symbol,date,cumsum(volume) as cumVol from t1 where symbol == "MSFT",volume > x context by date having sum(volume) > 200 >
sql(select=sqlCol("*"), from=t1, where=whereConditions, orderBy=sqlCol(`date), ascOrder=0);
//output:< select * from t1 where symbol == "MSFT",volume > x order by date desc >
sql(select=sqlCol("*"), from=t1, limit=1);
//output:< select top 1 * from t1 >
sql(select=sqlCol("*"), from=t1, groupBy=sqlCol(`symbol), groupFlag=0, limit=1);
//output:< select top 1 * from t1 context by symbol >
sql(select=(sqlCol(`symbol),sqlCol(`date),sqlColAlias(<cumsum(volume)>, `cumVol)), from=t1, groupBy=sqlCol(`date`symbol), groupFlag=0, hint=HINT_KEEPORDER);
//output:< select [128] symbol,date,cumsum(volume) as cumVol from t1 context by date,symbol >
whereConditions1 = <symbol=`MSFT or volume>x>
sql(select=sqlCol("*"), from=t1, where=whereConditions1, orderBy=sqlCol(`date), ascOrder=0);
//output:< select * from t14059d76a00000000 where symbol == "MSFT" or volume > x order by date desc >
sql(select=sqlCol("*"), from=t1, where=whereConditions, orderBy=sqlCol(`date), ascOrder=0, map=true);
//output:< select [256] * from t17092a30500000000 where symbol == "MSFT",volume > x order by date desc map >
可以定义一个函数使用
sql
函数来动态生成 SQL 语句。
def f1(t, sym, x){
whereConditions=[<symbol=sym>,<volume>x>]
return sql(sqlCol("*"),t,whereConditions).eval()
};
f1(t1, `MSFT, 5000);
symbol
date
price volume
MSFT
2017.01.04
63.12 6400
MSFT
2017.01.04
62.3 6800
f1(t1, `F, 9000);
symbol
date
price volume
F
2017.01.04
13.17 9600
def f2(t, sym, colNames, filterColumn, filterValue){
whereConditions=[<symbol=sym>,expr(sqlCol(filterColumn),>,filterValue)]
return sql(sqlCol(colNames),t,whereConditions).eval()
};
f2(t1,`GE, `symbol`date`volume, `volume, 3000);
symbol
date
volume
GE
2017.01.03
3500
GE
2017.01.04
3700
GE
2017.01.04
4600
f2(t1,`F, `symbol`date`volume,`price,13.2);
symbol
date
volume
F
2017.01.04
8900
F
2017.01.04
2300
F
2017.01.04
6300
设置参数
exec
=true,配合 pivot by 语句,生成一个矩阵:
date = 2020.09.21 + 0 0 0 0 1 1 1 1
sym = `MS`MS`GS`GS`MS`MS`GS`GS$SYMBOL
factorNum = 1 2 1 2 1 2 1 2
factorValue = 1.2 -3.4 -2.5 6.3 1.1 -3.2 -2.1 5.6
t = table(date, sym, factorNum, factorValue);
sql(select=sqlCol(`factorValue), from=t, groupBy=[sqlCol(`date), sqlCol(`sym)], groupFlag=2, exec=true)
//output:< exec factorValue from t pivot by date,sym >
FILE:references/doc_2155.md
# atanh
**URL**: https://docs.dolphindb.cn/zh/funcs/a/atanh.html
**来源**: DolphinDB 官方文档
---
atanh
语法
atanh(X)
详情
返回
X
的反双曲正切。
参数
X
可以是标量、向量、矩阵或表。
返回值
返回结果的数据形式与输入保持一致:若输入为标量,返回标量;若输入为向量、矩阵或表,返回相同维度的结果。
例子
atanh 0.000000 0.557408 -0.185040;
// output
[0,0.629065,-0.187196]
相关函数:
asin
,
acos
,
atan
,
sin
,
cos
,
tan
,
asinh
,
acosh
,
sinh
,
cosh
,
tanh
FILE:references/doc_216.md
# garch
**URL**: https://docs.dolphindb.cn/zh/funcs/g/garch.html
**来源**: DolphinDB 官方文档
---
garch
语法
garch(ds, endogColName, order, [maxIter=50])
详情
使用广义自回归条件异方差模型(Generalized Autoregressive Conditional Heteroskedasticity,简称 GARCH
模型)来分析单变量时间序列。返回一个字典,表示 GARCH 模型的分析结果,详细说明请参见“返回值”小节。
参数
ds
一张内存表或者一个 DataSource 类型构成的向量,包含需要分析的单变量时间序列。注意:不可为空。
endogColName
字符串标量,表示
ds
中需要分析的时间序列所对应的列名。
order
长度为 2 的正整数向量,表示 GARCH 模型的阶数。比如
order=[1,2]
表示 GARCH 模型的
p=1,q=2,其中 p 为 GARCH 项个数,q 为 ARCH 项阶数。
maxIter
可选参数,正整数标量,表示优化时的最大迭代次数,默认值为 50。
返回值
返回一个字典,表示 GARCH 模型的分析结果,字典有以下成员:
volConstant:浮点数标量,表示优化得到的 Vol Constant。
returnsConstant:浮点数标量,表示优化得到的 Returns Constant。
archTerm:浮点数向量,表示优化得到的 ARCH Term。
garchTerm:浮点数向量,表示优化得到的 GARCH Term。
iterations:整数标量,表示优化迭代次数。
aic:浮点数标量,表示 aic 准则的值。
bic:浮点数标量,表示 bic 准则的值。
nobs:整数标量,表示时间序列的观测数量,即拟合使用的数据量。
model:字典类型,包含拟合后模型的基本信息,有以下成员:
order:长度为 2 的正整数向量,表示模型的阶数。
endog:浮点数矩阵类型,表示从
ds
中转换而来的观测数据。
start:浮点数向量类型,表示经过拟合后的外生变量的值。
predict:函数指针, 指向预测函数,使用方法为
model.predict(x)
。其中,
model
表示 garch 函数的输出结果,
x
为一个正整数,表示预测的步长。预测函数返回一个数组,数组中每个元素分别表示每一步的预测值。
例子
传入
macrodata.csv
文件,自定义相关参数,计算其使用 GARCH 模型进行分析的结果。
data = loadText("macrodata.csv");
model = garch(data, "realgdp", [1,1]);
print(model)
// out:
volConstant->0.000005999433551
returnsConstant->0.008474617943101
archTerm->[0.70725452294378]
garchTerm->[0.248859733003604]
aic->-1353.789403416915774
bic->-1340.576183784679415
nobs->201
iterations->38
predict->garchPredict
model->order->[1,1]
endog->#0
------------------
0.024942130816387
-0.001192952110668
0.003494532654372
...
coefficients->[-12.023845501294935,-1.104702991485461,0.882087052766567,0.008474617943101]
FILE:references/doc_2178.md
# rowMax
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowMax.html
**来源**: DolphinDB 官方文档
---
rowMax
语法
rowMax(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行取最大值的操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL])
rowMax(m);
返回:[4.9,4.8,5.9]
t1=table(1..5 as x, 6..10 as y)
t2=table(5..1 as a, 10..6 as b);
rowMax(t1);
返回:[6,7,8,9,10]
rowMax(t1[`y], t2, take(8, 5));
返回:[10,9,8,9,10]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2);
select sym,rowMax(price1,price2) as max from t;
返回:
sym
max
AAPL
175.23
MS
50.76
IBM
50.32
IBM
51.29
C
174.97
FILE:references/doc_2185.md
# makeUnifiedCall
**URL**: https://docs.dolphindb.cn/zh/funcs/m/makeUnifiedCall.html
**来源**: DolphinDB 官方文档
---
makeUnifiedCall
语法
makeUnifiedCall(func, args)
详情
它使用指定参数调用一个函数并生成脚本。 高阶函数
unifiedCall
与
makeUnifiedCall
的区别是,
makeUnifiedCall
不执行脚本。
参数
func
是一个函数。
args
是一个 tuple, 由所调用函数的参数所构成。
从版本 2.00.11.3 起,args
可以是一个元代码的标量,其代码是一个元组表达式。
返回值
一个元代码。
例子
mc = makeUnifiedCall(matrix, (1 2 3, 4 5 6));
mc;
// output: < matrix([1,2,3], [4,5,6]) >
mc.eval();
col1
col2
1
4
2
5
3
6
从版本2.00.11.3 起, args 支持传入一个元代码标量,其代码是一个元组表达式。
通过下例的对比可以看到:
当 args 是一个元组时,会将元组中变量的值传入,此时 a 的值为 < add(3, 5) >
当 args 是一个元组表达式的元代码时,会将变量作为函数的参数,生成元代码,此时 b 的值为 < add(x, y) >
x=3
y=5
a = makeUnifiedCall(add, (x,y)) // < add(3, 5) >
b = makeUnifiedCall(add, <(x,y)>) // < add(x, y) >
因此,当 x 或 y 的值改变,b
的执行结果会将 x 和 y 的值动态传入,而 a 的执行结果不会随 x 和 y 的值变化
x = 6
a.eval() //计算 3+5
结果为 8 。
b.eval() // 计算 6+5
结果为 11 。
下例中,函数
makeUnifiedCall
以
sqlTuple
生成的元组表达式的元代码为参数,调用自定义函数 f,其结果作为函数 sql 的参数 select
,从而生成元代码 c 。
// 自定义函数
f = def (x,y)->(x-y)/(x+y)
// 定义待查询的表
t = table(1.0 2.0 3.0 as qty1, 1.0 3.0 7.0 as qty2)
// 生成查询的元代码
c = sql(select=makeUnifiedCall(f, sqlTuple(`qty1`qty2)), from=t)
// 执行对应元代码
c.eval()
_qty1
0
-0.2
-0.4
FILE:references/doc_2187.md
# le
**URL**: https://docs.dolphindb.cn/zh/funcs/l/le.html
**来源**: DolphinDB 官方文档
---
le
语法
le(X, Y)
或
X<=Y
详情
如果
X
和
Y
都不是集合,返回逐个元素比较
X
<=
Y
的结果。
如果
X
和
Y
都是集合,则检查
X
是否为
Y
的子集。
参数
X
和
Y
可以是标量、数据对、向量、矩阵或集合。如果
X
或
Y
的其中一个是数据对、向量或矩阵,另一个必须是一个标量,或具有相同长度或维度的数据对、向量或矩阵。
返回值
一个布尔值标量/向量/矩阵。
例子
1 2 3 <= 2;
// output
[true,true,false]
1 2 3<=0 2 4;
// output
[false,true,true]
2:3<=1:6;
// output
[false,true]
m1=1..6$2:3;
m1;
#0
#1
#2
1
3
5
2
4
6
m1 le 4;
#0
#1
#2
true
true
false
true
true
false
m2=6..1$2:3;
m2;
#0
#1
#2
6
4
2
5
3
1
m1<=m2;
#0
#1
#2
true
true
false
true
false
false
集合操作:如果
X
<
Y
,则
X
是
Y
的子集。
x=set(4 6);
y=set(4 6 8);
x<=y;
// output
true
x<=x;
// output
tue
FILE:references/doc_2190.md
# cdfBeta
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfBeta.html
**来源**: DolphinDB 官方文档
---
cdfBeta
语法
cdfBeta(alpha, beta, X)
详情
返回 Beta 分布的累计密度函数的值。
参数
形状参数
alpha
和
beta
都是正数。
X
是数值型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfBeta(2.31, 0.627, [0.001, 0.5, 0.999]);
// output
[0, 0.116056, 0.976416]
cdfBeta(2.31, 0.627, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output
[0.002451, 0.032995, 0.116056, 0.280532, 0.597694]
FILE:references/doc_2193.md
# rowIminLast
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowiminlast.html
**来源**: DolphinDB 官方文档
---
rowIminLast
语法
rowIminLast(args…)
详情
返回每行元素中最小元素的索引。如果有多个相同的最小值,返回右起第一个最小值的索引。
参数
row 系列函数通用参数说明和计算规则请参考:
行计算系列(row
系列)
返回值
结果为一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5 3.2, 1.5 4.8 5.9 1.7, 4.9 2.0 NULL 5.5])
rowIminLast(m)
// output
[1,2,0,1]
trades = table(10:0,`time`sym`p1`p2`p3`p4`p5`vol1`vol2`vol3`vol4`vol5,[TIMESTAMP,SYMBOL,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,INT,INT,INT,INT,INT])
insert into trades values(2022.01.01T09:00:00, `A, 33.2, 33.8, 33.6, 33.3, 33.1, 200, 180, 180, 220, 200)
insert into trades values(2022.01.01T09:00:00, `A, 33.1, 32.8, 33.2, 34.3, 32.3, 150, 280, 190, 100, 220)
insert into trades values(2022.01.01T09:00:00, `A, 31.2, 32.6, 33.6, 35.3, 34.5, 220, 160, 130, 100, 110)
insert into trades values(2022.01.01T09:00:00, `A, 30.2, 32.5, 33.6, 35.3, 34.1, 200, 180, 150, 140, 120)
insert into trades values(2022.01.01T09:00:00, `A, 33.2, 33.8, 33.6, 33.3, 33.1, 180, 160, 160, 180, 200)
select rowAt(matrix(p1, p2, p3, p4, p5), rowIminLast(vol1, vol2, vol3, vol4, vol5)) as price from trades
// output
price
33.6
34.3
35.3
34.1
33.6
相关函数:
rowImin
FILE:references/doc_2200.md
# arima
**URL**: https://docs.dolphindb.cn/zh/funcs/a/arima.html
**来源**: DolphinDB 官方文档
---
arima
语法
arima(ds, endogColName, order, [seasonalOrder], [exog], [trend],
[enforceStationarity=true], [enforceInvertibility=true],
[concentrateScale=false], [trendOffset=1], [maxIter=50])
详情
差分整合移动平均自回归(ARIMA, Autoregressive Integrated Moving
Average)模型是一种单变量时间序列分析模型,主要由三部分构成,分别为自回归模型(AR)、差分过程(I)和移动平均模型(MA)。
arima
函数是 ARIMA 类模型的通用接口,可以通过
arima
函数构建以下时间序列分析模型:
自回归模型 AR:用于捕捉数据与其历史值的关系
移动平均模型 MA:专注于处理随机波动
自回归移动平均模型 ARMA
差分整合移动平均自回归模型 ARIMA
季节性模型 SARIMA:处理周期性数据
整合外部回归变量的带误差项模型 ARIMAX
参数
ds
内存表或数据源(DATASOURCE)向量,指定包含单变量时间序列的数据。
endogColName
字符串标量,指定
ds
中的列名,该列为待分析的单变量时间序列数据。
order
长度为 3 的非负整数向量,表示 ARIMA 模型的 (p, d, q) 阶数。其中,p 表示自回归(AR)部分的阶数,d 表示差分阶数,q
表示移动平均(MA)部分的阶数。
seasonalOrder
可选参数。长度为 4 的非负整数向量, 表示季节性 ARIMA 模型的 (P, D, Q, s) 阶数。其中,P,D,Q
分别表示模型中季节性成分的 AR、差分、MA 阶数,s 表示该季节性序列的周期大小。默认值为 [0, 0, 0, 0],表示无季节性。
exog
可选参数。数值矩阵,表示外生变量。矩阵每一列表示一个外生变量的时间序列,矩阵行数为时间序列样本数,与
ds
的行数相等。
trend
可选参数。字符串标量, 用于控制确定性趋势。可选值为:
“n”:不使用常量和趋势(当
d
> 0 或者 D>0 时,以此为默认值);
”c”:仅使用常量(当
d
= 0 且 D = 0 时,以此为默认值);
”t”:仅使用线性趋势;
”ct”:同时使用常量和线性趋势;
enforceStationarity
可选参数。BOOL 类型标量, 表示是否强制自回归 AR部分满足平稳性条件。默认值为 true。
enforceInvertibility
可选参数。BOOL 类型标量, 表示是否强制移动平均 MA 部分满足可逆性条件。默认值为 true。
concentrateScale
可选参数。BOOL 类型标量,
表示是否在似然性之外集中标度(误差项的方差),从而减少一个参数。仅在使用数值最大似然估计时适用。默认值为 false。
trendOffset
可选参数。整数类型标量, 指定开始时间趋势值的偏移量。默认值为 1,因此如果
trend
='t',则趋势等于 1,
2, ..., nobs。
maxIter
可选参数。正整数,表示拟合时最大的迭代次数,默认值为 50。
返回值
一个字典,表示 ARIMA 模型的拟合结果,包含以下键值:
params:浮点数向量,表示 ARIMA 模型拟合得到的参数
llf:浮点数标量,表示 ARIMA 模型的对数似然值
aic:浮点数标量,表示 Akaike 信息准则
bic:浮点数标量,表示 Bayesian 信息准则
hqic:浮点数标量,表示 Hannan-Quinn 信息准则
例子
以下代码使用 1959-2009 年的季度经济指标数据,对实际 GDP(
realgdp
)进行 ARIMA 模型拟合。假设通过分析确定使用
ARIMA(1,0,0) 模型,即自回归阶数为 1,无需差分,移动平均阶数为 0:
data = loadText("./macrodata.csv")
res = arima(data, "realgdp", [1,0,0]);
res;
/*
params->[0.007795600187477,0.306055792984419,0.000069811276429]
llf->679.783769203580163
aic->-1353.567538407160327
bic->-1343.64273531495678
hqic->-1349.551945119058927
*/
macrodata.csv
FILE:references/doc_2208.md
# disableActivePartition
**URL**: https://docs.dolphindb.cn/zh/funcs/d/disableActivePartition.html
**来源**: DolphinDB 官方文档
---
disableActivePartition
语法
disableActivePartition(dbHandle)
详情
断开与历史数据库的连接。
参数
dbHandle
是历史数据库的句柄。
返回值
无。
例子
histdb = database("C:\DolphinDBDemo\example\data\dbspace\historical-A\Trades2ndDomain")
activeNodeAlias = getNodeAlias()
activeDate = today()
enableActivePartition(histdb, activeDate, activeNodeAlias);
disableActivePartition(histdb);
FILE:references/doc_2220.md
# top
**URL**: https://docs.dolphindb.cn/zh/progr/sql/top.html
**来源**: DolphinDB 官方文档
---
top
top 子句返回指定数量的记录,从表的第一个记录开始,可以在 top 子句中使用一个标量值或一个范围。范围下标从 0 开始而不是 1,并且不包含结束下标值。
例子
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t1 = table(timestamp, sym, qty, price);
t1;
select top 3 * from t1;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
select top 2:4 * from t1;
timestamp
sym
qty
price
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
top 子句中的标量值或范围必须是整型常量,不允许使用变量或表达式。
x=2;
select top x * from t1;
Syntax Error: [line #2] integer constant expected after keyword top
select top (1+2) * from t1;
Syntax Error: [line #1] integer constant expected after keyword top
top 子句不能和 pivot by 子句共同使用,但是可以与 group by, context by 子句共同使用。参考
contextBy
。
FILE:references/doc_2222.md
# anova
**URL**: https://docs.dolphindb.cn/zh/funcs/a/anova.html
**来源**: DolphinDB 官方文档
---
anova
语法
anova(X)
详情
对
X
进行单因素方差分析(one-way ANOVA)。
X
中的每一列都被视为一个单独的组。
参数
X
是一个矩阵或所有列均为数值的表。
返回值
一个字典,包含以下 key 值:
pValue:p 值
fValue:F 统计量
ssBetween:组间平方和
dfBetween:组间自由度
ssWithin:组内平方和
dfWithin:组内自由度
例子
a=300 287 301 400 211 399 412 312 390 412
b=240 259 302 311 210 402 390 298 347 380
c=210 230 213 210 220 208 290 300 201 201
m=matrix(a,b,c)
anova(m);
// output
pValue->0.000515
fValue->10.15459
ssBetween->70528.066667
dfBetween->2
ssWithin->93763.4
dfWithin->27
FILE:references/doc_2225.md
# pca
**URL**: https://docs.dolphindb.cn/zh/funcs/p/pca.html
**来源**: DolphinDB 官方文档
---
pca
语法
pca(ds, [colNames], [k], [normalize], [maxIter], [svdSolver],
[randomState])
详情
对数据源中指定列中的数据进行主成分分析。
参数
ds
是一个或多个数据源,通常由
sqlDS
函数生成。
colNames
是字符串向量,表示数据源中的列名。默认值是数据源中所有列的列名。
k
是一个正整数,表示需要计算的主成分的个数。默认值是数据源中的列数。
normalize
是一个布尔值,表示是否将数据减去均值再除以标准差。默认值为 false。
maxIter
是一个正整数,表示参数
svdSolver
=randomized 时的迭代次数。若未指定,当
k
<0.1*cols 时,
maxIter
= 7,否则
maxIter
= 4。这里 cols 表示数据源中的列数。
svdSolver
是一个字符串,表示如何对数据源进行 svd 运算。它的取值可以是 "full", "randomized" 或
"auto"。
svdSolver
= "full" 适合
k
值与数据源的列数相近的情况;
svdSolver
=
"randomized" 适合
k
值与数据源的列数相差较大的情况。默认值为 "auto",此时系统会自动判断使用 "full" 还是
"randomized"。
randomState
是一个整数,表示随机数种子,仅在参数
svdSolver
="randomized" 时起作用,默认为
int(time(now()))。
返回值
一个字典,包含以下键:
components:对应长度为 size(
colNames
)*
k
的主成分分析矩阵。
explainedVarianceRatio:对应长度为
k
的向量,包含前
k
个主成分分别解释的方差权重。
singularValues:对应长度为
k
的向量,包含主成分方差(协方差矩阵特征值)。
例子
x = [7,1,1,0,5,2]
y = [0.7, 0.9, 0.01, 0.8, 0.09, 0.23]
t=table(x, y)
ds = sqlDS(<select * from t>);
pca(ds);
// output
components->
#0 #1
--------- ---------
-0.999883 0.015306
-0.015306 -0.999883
explainedVarianceRatio->[0.980301,0.019699]
singularValues->[6.110802,0.866243]
FILE:references/doc_2226.md
# tmmed
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmmed.html
**来源**: DolphinDB 官方文档
---
tmmed
语法
tmmed(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
元素的中位数。
返回值
DOUBLE 类型向量。
例子
T = 1 1 1 2 5 6
X = 1 4 NULL -1 NULL 4
m = table(T as t,X as x)
select *, tmmed(t, x, 3) from m
t
x
tmmed_t
1
1
1
1
4
2.5
1
2.5
2
-1
1
5
6
4
4
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = NULL 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmmed(t, x, 3d) from m
t
x
tmmed_t
2021.01.02
2021.01.02
4
4
2021.01.04
4
2021.01.05
-1
-1
2021.01.07
2
0.5
2021.01.08
4
3
select *, tmmed(t, x, 1w) from m
t
x
tmmed_t
2021.01.02
2021.01.02
4
4
2021.01.04
4
2021.01.05
-1
1.5
2021.01.07
2
2
2021.01.08
4
3
相关函数:
mmed
,
med
FILE:references/doc_223.md
# replaceColumn!
**URL**: https://docs.dolphindb.cn/zh/funcs/r/replaceColumn_.html
**来源**: DolphinDB 官方文档
---
replaceColumn!
语法
replaceColumn!(table, colName, newCol)
详情
当
table
为内存表时:
使用向量替换
table
中指定列。替换后,指定列的数据类型与向量的数据类型一致。
支持替换多列(请注意该操作目前不保证原子性,即在遇到一些系统错误时可能出现部分列替换失败的情况)。
replaceColumn!
与 SQL 中的
update
语句的区别在于,前者可以修改列的值或数据类型,而后者只能修改列的值。
当
table
为 OLAP 分布式表时,
replaceColumn!
仅修改列的数据类型,并遵循以下规则:
SYMBOL 类型不支持转换,即不能将 SYMBOL 转换为其他类型,其他类型也不能转换为 SYMBOL。
除 SYMBOL 外,同类别的数据类型间支持相互转换。
INTEGRAL 和 FLOATING 类型支持相互转换。
INTEGRAL, FLOATING, LITERAL, TEMPORAL 类型支持转换为 STRING 类型。
注:
暂不支持替换 DECIMAL 类型列。
参数
table
非共享内存表
或分布式表(仅支持 OLAP 引擎)
。
colName
字符串,表示要替换列的列名。
当
table
是内存表时,
colName
也可以是字符串向量,表示多列的列名。
newCol
表示用于替换的列值。当
table
是内存表时,
当
colName
为标量时,
newCol
是一个长度与
table
行数相同的向量;当
colName
为向量时,
newCol
是一个元组,其元素个数与
colName
一致,且每一个元素是一个长度与
table
行数相同的向量。当
table
是 OLAP
分布式表时,newCol 仅用于提供目标数据类型。
返回值
返回替换后的表。
例子
sym = `C`MS`MS`MS`IBM`IBM`C`C`C
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t = table(timestamp, sym, qty, price)
schema(t).colDefs;
输出返回:
name
typeString
typeInt
extra
comment
timestamp
SECOND
10
sym
STRING
18
qty
INT
4
price
DOUBLE
16
把 sym 列的数据类型修改为 SYMBOL 类型:
syms=symbol(exec sym from t)
replaceColumn!(t,`sym,syms);
schema(t).colDefs;
输出返回:
name
typeString
typeInt
extra
comment
timestamp
SECOND
10
sym
SYMBOL
17
qty
INT
4
price
DOUBLE
16
对 price 列和 timestamp
列进行替换:
newPrice =round(t.qty)
newTimestamp = minute(t.timestamp)
replaceColumn!(t, `price`timestamp, (newPrice,newTimestamp))
schema(t).colDefs;
输出返回:
name
typeString
typeInt
extra
comment
timestamp
MINUTE
9
sym
SYMBOL
17
qty
INT
4
price
INT
4
login("admin","123456")
if(existsDatabase("dfs://replaceColumn")){
dropDatabase("dfs://replaceColumn")
}
n=10
month=take(2012.06.13..2012.06.13, n);
x=rand(1.0, n);
t=table(month, x);
db=database("dfs://replaceColumn", VALUE, 2012.06.13..2012.06.23)
pt = db.createPartitionedTable(t, `pt, `month);
pt.append!(t);
schema(pt).colDefs
输出返回:
name
typeString
typeInt
extra
comment
month
DATE
6
x
DOUBLE
16
newCols=array(INT,0)
replaceColumn!(loadTable("dfs://replaceColumn",`pt), `x, newCols)
schema(pt).colDefs
输出返回:
name
typeString
typeInt
extra
comment
month
DATE
6
x
INT
4
FILE:references/doc_2233.md
# strpos
**URL**: https://docs.dolphindb.cn/zh/funcs/s/strpos.html
**来源**: DolphinDB 官方文档
---
strpos
语法
strpos(X, str)
别名:
strFind
详情
检查
X
是否包含
str
。
参数
X
是在该字符串中搜索。它可以是标量或向量。
str
是被搜索的目标字符串。它必须是标量。
返回值
如果 X 中包含 str,返回 str 在 X 中的起始位置; 否则返回-1。
例子
strpos("abcdefg","cd");
// output
2
strpos("abcdefg","d");
// output
3
strpos("abcdefg","ah");
// output
-1
FILE:references/doc_2234.md
# saveDatabase
**URL**: https://docs.dolphindb.cn/zh/funcs/s/saveDatabase.html
**来源**: DolphinDB 官方文档
---
saveDatabase
语法
saveDatabase(dbHandle)
详情
保存数据库句柄。该命令必须要用户登录后才能执行。这个命令和
database
函数配合使用。
第一次创建数据库之后,我们需要用
saveDatabase
命令保存数据库。如果数据库位于一个已经包含了 DolphinDB 表相关文件的目录下,函数
database
会重新打开之前创建的数据库,且不需要用
saveDatabase
命令保存。
参数
dbHandle
是 DolphinDB 数据库句柄。
例子
db=database("C:/DolphinDB/")
saveDatabase(db);
FILE:references/doc_2235.md
# getInstrumentKeys
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getInstrumentKeys.html
**来源**: DolphinDB 官方文档
---
getInstrumentKeys
语法
getInstrumentKeys(instrument)
详情
根据输入的金融工具,获取该工具所包含的字段。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
当
instrument
是标量时,返回 STRING 类型向量。
当
instrument
是向量时,返回由 STRING 类型向量组成的元组。
例子
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "ZeroCouponBond",
"version": 0,
"instrumentId": "0001",
"start": 1996.03.01,
"maturity": 2032.05.15,
"dayCountConvention": "ActualActualISDA",
"coupon": 0.0276,
"issuePrice": 100.0,
"frequency": "Semiannual",
"subType":"TREASURY_BOND",
"creditRating":"B",
"settlement": 2022.05.15
}
ins = parseInstrument(bond)
getInstrumentKeys(ins)
// output: ["coupon","subType","discountCurve","cashflow","currency","calendar","dayCountConvention","start","nominal","instrumentId","creditRating","maturity","bondType","version","spreadCurve","productType","assetType","settlement","frequency","cashFlow","issuePrice"]
相关函数:
parseInstrument
、
getInstrumentField
FILE:references/doc_2237.md
# writeLog
**URL**: https://docs.dolphindb.cn/zh/funcs/w/writeLog.html
**来源**: DolphinDB 官方文档
---
writeLog
语法
writeLog(X1, [X2, X3....Xn])
详情
在日志文件中写入日志。该函数必须要用户登录后才能执行。
参数
X1
,
X2
,
X3
...
Xn
是要写入日志文件的字符串。每个字符串都是日志文件中的一行。
返回值
无。
例子
writeLog("This is a message written into the log file.")
writeLog("line1.","line2.","line3");
// Check the log file.
// output
Sun Aug 06 16:41:05 2017 <INFO> :This is a message written into the log file.
Sun Aug 06 16:50:35 2017 <INFO> :line1.
Sun Aug 06 16:50:35 2017 <INFO> :line2.
Sun Aug 06 16:50:35 2017 <INFO> :line3
FILE:references/doc_225.md
# 函数参考
**URL**: https://docs.dolphindb.cn/zh/funcs/funcs_intro.html
**来源**: DolphinDB 官方文档
---
函数参考
基本语法
对于一个参数的函数,我们使用 X 作为参数。对于两个参数的函数,我们使用 X 和 Y 分别作为第一个和第二个参数。如果没有说明,X 或 Y
表示标量,向量,矩阵,字典或表的对象。我们有一些需要一个标量作为参数之一的函数,比如
take
,
rand
,
norm
。对于这些情况,我们使用小写字母,比如 "a", "b". [ ] 里的内容是可选项。
一个参数的函数语法:
标准函数调用:
<function>(X)
将函数名放在参数 X 前时,X 两边的括号可以省略。
<function> X
注:
该用法不适于嵌套函数调用。
当 X 是一个对象时,X 两边的括号可以省略。
X.<function>()
注:
该用法更合适嵌套函数调用。
两个参数的函数语法:
标准函数调用
<function>(X, Y)
将函数名放在两个参数之间。
X <function> Y
注:
该用法不适于嵌套函数调用。
当 X 是一个对象时,X 两边的括号可以省略。
X.<function> (Y)
可以对常量和变量用面向对象的风格调用一个函数。
为了简明,我们在这章中,对所以一元和两个参数的函数,都只介绍第一种调用形式,即
<function>(X)
或
<function>(Y)
。
函数调用示例
以下例子展示 3 种调用函数
log
的方法:
方法一:
log(10);
输出返回:
2.302585
方法二:
log 10;
输出返回:
2.302585
方法三:
(10).log();
输出返回:
2.302585
。在此用法中,为了将常数
10 视为一个对象,需要为其加一对括号。
注:
而在以下例子中,由于 x 是一个向量对象,因此 x 两边的括号可以省略。
x = 5 3 1 10;
log(x);
输出返回:
[1.609438,1.098612,0,2.302585]
log x
输出返回:
[1.609438,1.098612,0,2.302585]
x.log();
输出返回:
[1.609438,1.098612,0,2.302585]
(5 3 1 10).log()
输出返回:
[1.609438,1.098612,0,2.302585]
。在此用法中,为了将向量常数 5 3 1 10
视为一个向量对象,需要在向量常数的左右加一对括号。
提示:
大多数二元运算符/函数不要求两个参数是同样的数据类型。系统会用最佳方式转换类型。但不推荐使用不同的数据类型,因为大量的类型转换会造成性能的损耗。
FILE:references/doc_2251.md
# getInstrumentNominal
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentnominal.html
**来源**: DolphinDB 官方文档
---
getInstrumentNominal
语法
getInstrumentNominal(instrument)
详情
根据输入的金融工具,获取该工具的名义金额(nominal)。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DOUBLE 类型标量或向量。
例子
deposit = {
"productType": "Cash",
"assetType": "Deposit",
"nominal":100,
"version": 0,
"start": 2025.05.15,
"maturity": 2025.08.15,
"rate": 0.02,
"dayCountConvention": "Actual360",
"notional":["CNY", 1E6],
"payReceive": "Receive"
}
ins = parseInstrument(deposit)
getInstrumentNominal(ins)
// output: 100
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_2253.md
# rowOr
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowOr.html
**来源**: DolphinDB 官方文档
---
rowOr
语法
rowOr(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行逻辑或操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([true false false, true true true, true true true])
rowOr(m);
// output
[1,1,1]
t1=table(false true true true false as x, false true false true true as y)
rowOr(t1);
0,1,1,1,1]]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2)
select * from t where rowOr(price1>30, price2>100);
sym
price1
price2
AAPL
49.6
175.23
IBM
30.02
51.29
C
174.97
26.23
相关函数:
or
FILE:references/doc_2262.md
# ploadText
**URL**: https://docs.dolphindb.cn/zh/funcs/p/ploadText.html
**来源**: DolphinDB 官方文档
---
ploadText
语法
ploadText(filename, [delimiter], [schema], [skipRows=0]
, [arrayDelimiter], [containHeader],
[arrayMarker]
)
详情
将数据文件并行加载到内存中。当文件大于 16MB 时,
ploadText
返回一个顺序分区的内存表;否则返回一个普通内存表。
注:
ploadText
返回的分区表数据均匀分配到各个分区,且每个分区中的数据量介于8MB与16MB之间。
与
loadText
函数相比,进行并行加载时,
ploadText
速度更快。
从 2.00.10 版本开始,
loadText
支持加载一条记录中包含多个换行符的数据文件。
参数
参数与
loadText
相同。
返回值
一个内存表。
例子
n=1000000
timestamp=09:30:00+rand(18000,n)
ID=rand(100,n)
qty=100*(1+rand(100,n))
price=5.0+rand(100.0,n)
t1 = table(timestamp,ID,qty,price)
saveText(t1, "C:/DolphinDB/Data/t1.txt");
timer tt1=loadText("C:/DolphinDB/Data/t1.txt");
// output
Time elapsed: 437.236 ms
timer tt2=ploadText("C:/DolphinDB/Data/t1.txt");
// output
Time elapsed: 241.126 ms
typestr(tt2);
// output
SEGMENTED IN-MEMORY TABLE
更多例子请参考
loadText
。
FILE:references/doc_2263.md
# DolphinDB 脚本语言
**URL**: https://docs.dolphindb.cn/zh/progr/lang_intro.html
**来源**: DolphinDB 官方文档
---
DolphinDB 脚本语言
DolphinDB 脚本编程涉及的核心概念包括:数据类型与形式、对象、运算符、编程语句、数据操作、函数化编程、文件操作和 SQL 语句。
值得注意的是,DolphinDB 脚本语言是大小写敏感的,所有标识符(如变量、函数名、类名)及保留字(关键字)严格区分大小写。
FILE:references/doc_2270.md
# yearEnd
**URL**: https://docs.dolphindb.cn/zh/funcs/y/yearEnd.html
**来源**: DolphinDB 官方文档
---
yearEnd
语法
yearEnd(X, [endingMonth=12], [offset], [n=1])
详情
返回
X
所在的以
endingMonth
为结束月份的年份的最后一天。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
年更新一次。注意,
offset
和
n
须同时指定,且只有当
n
>1时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP 类型的标量或向量。
endingMonth
是1到12之间的整数,表示一年的结束月份。默认值是12。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
一个 DATE 类型的标量或向量。
例子
yearEnd(2012.06.12, 3);
// output
2013.03.31
yearEnd(2012.06.12, 9);
// output
2012.09.30
yearEnd(2012.06.12);
// output
2012.12.31
yearEnd(2012.06.12, 12, 2009.04.03, 2);
// output
2013.12.31
date=2011.04.25+(1..10)*365
time = take(09:30:00, 10);
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
t1;
date
time
sym
qty
price
2012.04.24
09:30:00
MSFT
2200
49.6
2013.04.24
09:30:00
MSFT
1900
29.46
2014.04.24
09:30:00
MSFT
2100
29.52
2015.04.24
09:30:00
MSFT
3200
30.02
2016.04.23
09:30:00
MSFT
6800
174.97
2017.04.23
09:30:00
MSFT
5400
175.23
2018.04.23
09:30:00
MSFT
1300
50.76
2019.04.23
09:30:00
MSFT
2500
50.32
2020.04.22
09:30:00
MSFT
8800
51.29
2021.04.22
09:30:00
MSFT
4500
52.38
select avg(price),sum(qty) from t1 group by yearEnd(date, 4, 2010.04.01, 2);
yearEnd_date
avg_price
sum_qty
2012.04.30
49.6
2200
2014.04.30
29.49
4000
2016.04.30
102.495
10000
2018.04.30
112.995
6700
2020.04.30
50.805
11300
2022.04.30
52.38
4500
相关函数:
yearBegin
,
businessYearBegin
,
businessYearEnd
FILE:references/doc_2274.md
# 多范式编程
**URL**: https://docs.dolphindb.cn/zh/tutorials/hybrid_programming_paradigms.html
**来源**: DolphinDB 官方文档
---
多范式编程
开发大数据应用,不仅需要一个能支撑海量数据的分布式数据库,一个能高效利用多核多节点的分布式计算框架,更需要一门能与分布式数据库和分布式计算有机融合,高性能易扩展,表达能力强,满足快速开发和建模需要的编程语言。DolphinDB从流行的SQL和Python语言汲取了灵感,设计了大数据处理脚本语言。本教程讲解如何通过混合范式编程,快速开发大数据分析的应用。从中你也可以了解DolphinDB的编程语言(以下简称DolphinDB)如何与数据库和分布式计算融合。
向量化编程(Vector Programming)
向量化编程是 DolphinDB 中最基本的编程范式。DolphinDB中绝大部分函数支持向量作为函数的输入参数。根据函数的返回值的不同,函数可分为两种:一种是聚合函数(aggregate function),返回标量(scalar);另一种是向量函数,返回与输入向量等长的向量。
向量化操作有三个主要优点:
代码简洁
大幅降低脚本语言的解释成本
可对很多算法进行优化
时间序列数据通常可以用一个向量来表示,用于数据分析的列式数据库的每一个列也都可以用向量来表示。DolphinDB作为一个内存计算引擎或者作为一个分析型的数据仓库,在进行时间序列数据分析时,特别适合使用向量化编程。
以两个长度为一千万的向量相加作为一个简单例子。用命令式编程的for语句,不仅语句冗长,而且耗时是向量化编程的百倍以上。
n = 10000000
a = rand(1.0, n)
b = rand(1.0, n)
//采用for语句编程:
c = array(DOUBLE, n)
for(i in 0 : n)
c[i] = a[i] + b[i]
//采用向量化编程:
c = a + b
向量化编程实际上是对一组同质数据的批处理,不仅在编译阶段可以利用vectorization对指令进行优化,在很多算法上也可以优化。以经常使用的时间序列数据滑动窗口(sliding window)指标之一的移动平均(moving average)为例。假设总的数据量是n,窗口大小为k,如果不采用批量计算,时间复杂度是O(nk)。但是因为计算完一个窗口的移动平均后,计算下一个窗口时,只有一个数据点发生了变化,所以只要调整这一个点的值,就可以算出新窗口的移动平均,所以批量计算的时间复杂度是O(n)。DolphinDB中,大部分计算滑动窗口指标的函数都经过了优化,性能近似于O(n)。这些函数包括
mmax
,
mmin
,
mimax
,
mimin
,
mavg
,
msum
,
mcount
,
mstd
,
mvar
,
mrank
,
mcorr
,
mcovar
,
mbeta
和
mmed
。在下例中,经过优化的
mavg
函数的性能超过对每一个窗口使用
avg
函数300倍。
n = 10000000
a = rand(1.0, n)
window = 60
//对每一个窗口分别使用avg计算:
timer moving(avg, a, window);
Time elapsed: 4039.23 ms
//采用mavg函数批量计算:
timer mavg(a, window);
Time elapsed: 12.968 ms
向量化编程也有其局限性。首先,不是所有的操作都可以用向量化计算来完成。在机器学习和统计分析中,在某些场景下,只能对逐行数据进行迭代处理,无法向量化计算。对于这种场景,可使用DolphinDB的JIT(即时编译)版本,将用for语句编写的逐行处理代码在运行时动态编译成机器码执行,从而显著提升性能。
其次,向量化计算通常要将整个向量全部加载到一段连续内存中,Matlab和R都有这样的要求。有时候因为内存碎片原因,无法找到大段的连续内存。DolphinDB针对内存碎片,特别引入了big array,可以将物理上不连续的内存块组成一个逻辑上连续的向量。系统是否采用big array是动态决定的,对用户透明。通常,对big array进行扫描,性能损耗对于连续内存而言,在1%~5%之间;对big array进行随机访问,性能损耗在20%~30%左右。在此方面,DolphinDB是以可以接受的少量性能损失来换取系统的更高可用性。
SQL编程(SQL Programming)
SQL是一个面向问题的语言。用户只需要给出问题的描述,SQL引擎会产生结果。通常SQL引擎属于数据库的一部分,其它系统通过JDBC,ODBC或Native API 与数据库交流。DolphinDB脚本语言的SQL语句不仅支持SQL的标准功能,而且为大数据的分析,尤其是时间序列大数据的分析做了很多扩展,可极大简化代码,方便用户使用。
SQL与编程语言的融合
在DolphinDB中,脚本语言与SQL语言是无缝融合在一起的。这种融合主要体现在几个方面:
SQL语句是DolphinDB语言的一个子集,一种表达式。SQL语句可以直接赋给一个变量或作为一个函数的参数。
SQL语句中可以使用上下文中的创建的变量和函数。如果SQL语句涉及到分布式表,这些变量和函数会自动序列化到相应的节点。
SQL语句不再是一个简单的字符串,而是可以动态生成的代码。
SQL语句不仅可以对数据表(table)进行操作,也可对其它数据结构如scalar,vector,matrix,set,dictionary进行操作。数据表可以与其它数据结构进行转换。
请注意,DolphinDB编程语言区分大小写。在DolphinDB中所有的SQL关键词均必须使用小写。
下面例子中,首先生成一个员工工资表:
empWages = table(take(1..10, 100) as id, take(2017.10M + 1..10, 100).sort() as month, take(5000 5500 6000 6500, 100) as wage);
然后计算给定的一组员工的平均工资。员工列表存储在一个本地变量empIds中。
empIds = 3 4 6 7 9
select avg(wage) from empWages where id in empIds group by id;
id avg_wage
-- --------
3 5500
4 6000
6 6000
7 5500
9 5500
除计算平均工资外,同时显示员工的姓名。员工姓名使用一个字典empName来获取。
empNames = dict(1..10, `Alice`Bob`Jerry`Jessica`Mike`Tim`Henry`Anna`Kevin`Jones)
select empNames[first(id)] as name, avg(wage) from empWages where id in empIds group by id;
id name avg_wage
-- ------- --------
3 Jerry 5500
4 Jessica 6000
6 Tim 6000
7 Henry 5500
9 Kevin 5500
上面的两个例子中,SQL语句的where子句和select子句分别用到了上下文中定义的数组和字典,使得本来需要通过子查询和多表联结来解决的问题,通过简单的hash table就解决了。如果SQL涉及到分布式数据库,这些上下文变量会自动序列化到相应的节点。这不仅让代码看上去更简洁,有更好的可读性,而且提升了性能。
SQL的select语句返回的数据表可以直接赋给一个本地变量,做进一步的处理分析。DolphinDB还引入了exec关键词,与select相比,EXEC语句返回的结果可以是一个matrix,vector或scalar,更便于数据分析。下面的例子中,exec与pivot by配合使用,直接返回一个矩阵。
exec wage from empWages pivot by month, id;
1 2 3 4 5 6 7 8 9 10
---- ---- ---- ---- ---- ---- ---- ---- ---- ----
2017.11M|5000 5500 6000 6500 5000 5500 6000 6500 5000 5500
2017.12M|6000 6500 5000 5500 6000 6500 5000 5500 6000 6500
2018.01M|5000 5500 6000 6500 5000 5500 6000 6500 5000 5500
2018.02M|6000 6500 5000 5500 6000 6500 5000 5500 6000 6500
2018.03M|5000 5500 6000 6500 5000 5500 6000 6500 5000 5500
2018.04M|6000 6500 5000 5500 6000 6500 5000 5500 6000 6500
2018.05M|5000 5500 6000 6500 5000 5500 6000 6500 5000 5500
2018.06M|6000 6500 5000 5500 6000 6500 5000 5500 6000 6500
2018.07M|5000 5500 6000 6500 5000 5500 6000 6500 5000 5500
2018.08M|6000 6500 5000 5500 6000 6500 5000 5500 6000 6500
对面板数据(Panel Data)的友好支持
SQL的group by子句将数据分成多组,每组产生一个值,也就是一行。因此使用group by子句后,行数一般会大大减少。
在对面板数据进行分组后,每一组数据通常是时间序列数据,譬如按股票分组,每一个组内的数据是一个股票的价格序列。处理面板数据时,有时候希望保持每个组的数据行数,也就是为组内的每一行数据生成一个值。例如,根据一个股票的价格序列生成回报序列,或者根据价格序列生成一个移动平均价格序列。其它数据库系统(例如SQL Server,PostGreSQL),用窗口函数(window function)来解决这个问题。DolphinDB引入了context by子句来处理面板数据。context by与窗口函数相比,除了语法更简洁,设计更系统化(与group by和pivot by一起组成对分组数据处理的三个子句)以外,表达能力上也更强大,具体表现在下面三个方面:
不仅能与select配合在查询中使用,也可以与update配合更新数据。
绝大多数数据库系统在窗口函数中只能使用表中现有的字段分组。context by子句可以使用任何现有字段和计算字段。
窗口函数仅限于少数几个函数。context by不仅不限制使用的函数,而且可以使用任意表达式,譬如多个函数的组合。
context by可以与having子句配合使用,以过滤每个组内部的行。
假定trades数据表记录了每个股票每天的日终价格,可以使用context by子句方便的计算每个股票每天的回报以及每天的排名。首先按股票代码进行分组,计算每个股票每天的回报。这里假设每个股票的数据是时间顺序排列的。
update trades set ret = ratios(price) - 1.0 context by symbol;
按日期进行分组,计算每天每个股票的回报降序排名:
select date, symbol, ret, rank(ret, false) + 1 as rank from trades where isValid(ret) context by date;
选择每天回报排名前10的股票:
select date, symbol, ret from trades where isValid(ret) context by date having rank(ret, false) < 10;
下面我们以一个更为复杂的实际例子演示context by子句如何高效的解决面板数据问题。一篇论文
101 Formulaic Alphas
介绍了华尔街的顶级量化对冲基金WorldQuant所使用的101个量化Alpha因子。某基金公司用C#来计算这些因子,其中代表性的98号因子既用到了纵向时间序列数据的多个指标的嵌套,又用到了横向截面数据的排序信息,实现使用了几百行代码。使用中国股市3000多个股票10年近9百万行的历史数据,计算98号Alpha因子耗时约30分钟。而改用DolphinDB实现,如下图所示只用了4行核心代码,耗时仅2秒钟,达到了接近三个数量级的性能提升。
def alpha98(stock){
t = select code, valueDate, adv5, adv15, open, vwap from stock order by valueDate
update t set rank_open = rank(open), rank_adv15 = rank(adv15) context by valueDate
update t set decay7 = mavg(mcorr(vwap, msum(adv5, 26), 5), 1..7), decay8 = mavg(mrank(9 - mimin(mcorr(rank_open, rank_adv15, 21), 9), true, 7), 1..8) context by code
return select code, valueDate, rank(decay7)-rank(decay8) as A98 from t context by valueDate
}
对时间序列数据的友好支持
DolphinDB的数据库采用列式数据存储,计算的时候又采用向量化的编程,对时间序列数据天然友好。
DolphinDB支持不同精度的时间类型。可以通过SQL语句方便的将高频数据转换成不同精度的低频数据,例如秒级、分钟级、小时级, 也可以通过
bar
函数和group by子句的配合使用,转换成任意时间间隔的数据。
DolphinDB支持对时间序列数据的序列关系进行建模,包括领先(lead),滞后(lag),滑动窗口(sliding window),累积窗口(cumulative window)等。更重要的是在这类建模中用到的常用指标和函数,DolphinDB都做了优化,性能优于其它系统1~2个数量级。
DolphinDB提供了专门为时间序列设计的高效而常用的表联结方式:asof join和window join。
我们以一个简单的例子来解释window join。譬如要统计一组人员在某些时间点前三个月的平均工资。我们可以简单的用window join(
wj
)来实现。window join函数的具体解释请参考用户手册。
p = table(1 2 3 as id, 2018.06M 2018.07M 2018.07M as month)
s = table(1 2 1 2 1 2 as id, 2018.04M + 0 0 1 1 2 2 as month, 4500 5000 6000 5000 6000 4500 as wage)
select * from wj(p, s, -3:-1,<avg(wage)>,`id`month)
id month avg_wage
-- -------- -----------
1 2018.06M 5250
2 2018.07M 4833.333333
3 2018.07M
上面的问题,在其它数据库系统中,可以使用equal join(id字段)和 non-equal join(month字段),以及group by子句来解决。但除了写法更为复杂外,与DolphinDB的window join相比,其它系统性能落后两个数量级以上。
window join在金融领分析领域有着广泛的应用。一个经典的应用就是将交易(trades)表和报价(quotes)表进行关联,计算交易成本。
以下为交易表(trades),不分区或者按日期和股票代码分区:
sym date time price qty
---- ---------- ------------ ------ ---
IBM 2018.06.01 10:01:01.005 143.19 100
MSFT 2018.06.01 10:01:04.006 107.94 200
以下为报价表(quotes),不分区或者按日期和股票代码分区:
sym date time bid ask bidSize askSize
---- ---------- ------------ ------ ------ ------- -------
IBM 2018.06.01 10:01:01.006 143.18 143.21 400 200
MSFT 2018.06.01 10:01:04.010 107.92 107.97 800 100
使用asof join为每一个交易找到最近的一个报价,并利用报价的中间价作为交易成本的基准:
dateRange = 2018.05.01 : 2018.08.01
select sum(abs(price - (bid+ask)/2.0)*qty)/sum(price*qty) as cost from aj(trades, quotes, `date`sym`time) where date between dateRange group by sym;
使用window join为每一个交易找到前10毫秒的报价,计算平均中间价作为交易成本的基准:
select sum(abs(price - mid)*qty)/sum(price*qty) as cost from pwj(trades, quotes, -10:0, <avg((bid + ask)/2.0) as mid>,`date`sym`time) where date between dateRange group by sym;
SQL的其它扩展
为满足大数据分析的要求,DolphinDB对SQL还做了很多其他扩展。这儿我们例举一些常用功能。
用户自定义的函数无需编译、打包和部署,即可在本节点或分布式环境的SQL中使用此函数。
如5.4节所示,DolphinDB中的SQL与分布式计算框架紧密集成,实现库内计算(in-database analytics)变得更加便捷和高效。
DolphinDB支持组合字段(composite column),可将复杂分析函数的多个返回值输出到数据表的一行。
如果要在SQL语句中使用组合字段,函数的输出结果必须是简单的键值对(key-value pair)或者数组。如果不是这两种类型,可以用自定义函数进行转换。组合字段的详细用法请参考用户手册。
factor1=3.2 1.2 5.9 6.9 11.1 9.6 1.4 7.3 2.0 0.1 6.1 2.9 6.3 8.4 5.6
factor2=1.7 1.3 4.2 6.8 9.2 1.3 1.4 7.8 7.9 9.9 9.3 4.6 7.8 2.4 8.7
t=table(take(1 2 3, 15).sort() as id, 1..15 as y, factor1, factor2);
为每个id运行ols,y = alpha + beta1 * factor1 + beta2 * factor2, 输出参数alpha, beta1, beta2。
select ols(y, [factor1,factor2], true, 0) as `alpha`beta1`beta2 from t group by id;
id alpha beta1 beta2
-- --------- --------- ---------
1 1.063991 -0.258685 0.732795
2 6.886877 -0.148325 0.303584
3 11.833867 0.272352 -0.065526
在输出参数的同时,输出R2。使用自定义函数包装输出结果。
def myols(y,x){
r=ols(y,x,true,2)
return r.Coefficient.beta join r.RegressionStat.statistics[0]
}
select myols(y,[factor1,factor2]) as `alpha`beta1`beta2`R2 from t group by id;
id alpha beta1 beta2 R2
-- --------- --------- --------- --------
1 1.063991 -0.258685 0.732795 0.946056
2 6.886877 -0.148325 0.303584 0.992413
3 11.833867 0.272352 -0.065526 0.144837
命令式编程(Imperative Programming)
DolphinDB与主流的脚本语言(Python和JavaScript等)和编译型强类型语言(C++,C和Java)一样,支持命令式编程,即一步一步告诉计算机先做什么再做什么。DolphinDB目前支持18种语句(详细参考用户手册第五章),包括最常用的赋值语句,分支语句if..else,以及循环语句for和do..while等。
DolphinDB支持对单变量和多变量进行赋值。
x = 1 2 3
y = 4 5
y += 2
x, y = y, x //swap the value of x and y
x, y =1 2 3, 4 5
DolphinDB目前支持的循环语句包括for语句和do..while语句。for语句的循环体可以包括数据对(pair)(左闭右开区间)、数组(vector)、矩阵(matrix)和表(table)。
1到100累加求和:
s = 0
for(x in 1:101) s += x
print s
数组中的元素求和:
s = 0;
for(x in 1 3 5 9 15) s += x
print s
打印矩阵每一列的均值:
m = matrix(1 2 3, 4 5 6, 7 8 9)
for(c in m) print c.avg()
计算数据表中每一个行两列之乘积:
t= table(["TV set", "Phone", "PC"] as productId, 1200 600 800 as price, 10 20 7 as qty)
for(row in t) print row.productId + ": " + row.price * row.qty
DolphinDB的分支语句if..else与其它语言一致。
if(condition){
<true statements>
}
else{
<false statements>
}
对处理海量数据时,不推荐利用控制语句(for语句,if..else语句)对数据逐行处理。这些控制语句一般用于上层模块的处理和调度,比较底层的数据处理模块建议使用向量编程,函数编程,SQL编程等方式来处理。
函数化编程(Functional Programming)
DolphinDB支持函数式编程的大部分功能,包括:
纯函数(pure function)
自定义函数(user-defined function,或简称udf)
lambda函数
高阶函数(higher order function)
部分应用(partial application)
详细请参考用户手册第七章。
自定义函数和lambda函数
DolphinDB中可以创建自定义函数,函数可以有名称或者没有名称(通常是lambda函数)。创建的函数符合纯函数的要求,也就是说只有函数的输入参数可以影响函数的输出结果。DolphinDB与Python不同,函数体内只能引用函数参数和函数内的局部变量,不能使用函数体外定义的变量。从软件工程的角度看,这牺牲了一部分语法糖的灵活性,但对提高软件质量大有裨益。
def getWeekDays(dates){
return dates[def(x):weekday(x) between 1:5]
}
getWeekDays(2018.07.01 2018.08.01 2018.09.01 2018.10.01)
[2018.08.01, 2018.10.01]
上面的例子中,我们定义了一个函数
getWeekDays
,该函数接受一组日期,返回其在周一和周五之间的日期。函数的实现采用了向量的过滤功能,也就是接受一个布尔型单目函数用于数据的过滤。我们定义了一个lambda函数用于数据过滤。
高阶函数(Higher Order Function)
高阶函数是指可以接受另一个函数作为参数的函数。在DolphinDB中,高阶函数主要用作数据处理的模板函数,通常第一个参数是另外一个函数,用于具体的数据处理。譬如说,A对象有m个元素,B对象有n个元素,一种常见的处理模式是,A中的任意一个元素和B中的任意一个元素两两计算,最后产生一个m*n的矩阵。DolphinDB将这种数据处理模式抽象成一个高阶函数
cross
。DolphinDB提供了很多类似的高阶函数,包括
all
,
any
,
each
,
loop
,
eachLeft
,
eachRight
,
eachPre
,
eachPost
,
accumulate
,
reduce
,
groupby
,
contextby
,
pivot
,
cross
,
moving
,
rolling
等。
下面的一个例子我们使用三个高阶函数,只用三行代码,根据股票日内tick级别的交易数据,计算出每两只股票之间的相关性。
模拟生成10000000个数据点(股票代码,交易时间和价格):
n=10000000
syms = rand(`FB`GOOG`MSFT`AMZN`IBM, n)
time = 09:30:00.000 + rand(21600000, n)
price = 500.0 + rand(500.0, n)
利用
pivot
函数生成股价透视矩阵,每列为一支股票,每行为一分钟:
priceMatrix = pivot(avg, price, time.minute(), syms)
each
和
ratios
函数配合使用,对股价矩阵每列进行操作,将股价转为收益率:
retMatrix = each(ratios, priceMatrix) - 1
cross
和
corr
函数配合使用,计算每两支股票收益率的相关性:
corrMatrix = cross(corr, retMatrix, retMatrix)
结果为:
AMZN FB GOOG IBM MSFT
--------- --------- --------- --------- ---------
AMZN|1 0.015181 -0.056245 0.005822 0.084104
FB |0.015181 1 -0.028113 0.034159 -0.117279
GOOG|-0.056245 -0.028113 1 -0.039278 -0.025165
IBM |0.005822 0.034159 -0.039278 1 -0.049922
MSFT|0.084104 -0.117279 -0.025165 -0.049922 1
部分应用(Partial Application)
部分应用指当一个函数的一部分或全部参数给定后生成一个新的函数。在DolphinDB中,函数调用使用圆括号(),部分应用使用{}。3.2节中的例子用到的
ratios
函数的具体实现就是高阶函数
eachPre
的一个部分应用 eachPre。
以下两行代码同构:
retMatrix = each(ratios, priceMatrix) - 1
retMatrix = each(eachPre{ratio}, priceMatrix) - 1
部分应用经常用于高阶函数。使用高阶函数时,通常对某些参数有特定要求,通过部分应用,可以确保所有参数符合要求。例如,计算一个向量a与一个矩阵m中的每一列的相关性,可以将函数
corr
与高阶函数
each
配合使用。但是若直接将向量与矩阵在
each
中列为
corr
的参数,系统将会试图计算向量的某个元素与矩阵的某个列的相关性,导致产生错误。这时,可利用部分应用把函数
corr
与向量a组成一个新的函数
corr{a}
,再与高阶函数
each
配合使用于矩阵的每一列,如下例所示。我们也可以利用for语句来解决这个问题,但代码冗长且增加耗时。
a = 12 14 18
m = matrix(5 6 7, 1 3 2, 8 7 11)
使用each和部分应用计算向量a与矩阵中的每一列的相关性:
each(corr{a}, m)
使用for语句解决上述问题:
cols = m.columns()
c = array(DOUBLE, cols)
for(i in 0:cols)
c[i] = corr(a, m[i])
部分应用的另一个妙用是使函数保持状态。通常我们希望函数是无状态的,即函数的输出结果完全是由输入参数决定的。但有时候我们希望函数是有“状态”的。譬如说,在流计算中,用户通常需要给定一个消息处理函数(message handler),接受一条新的信息后返回一个结果。如果我们希望消息处理函数返回的是迄今为止所有接收到的数据的平均数,可以通过部分应用来解决。
def cumulativeAverage(mutable stat, newNum){
stat[0] = (stat[0] * stat[1] + newNum)/(stat[1] + 1)
stat[1] += 1
return stat[0]
}
msgHandler = cumulativeAverage{0.0 0.0}
each(msgHandler, 1 2 3 4 5)
[1,1.5,2,2.5,3]
远程过程调用编程(RPC Programming)
远程过程调用(Remote Procedure Call)是分布式系统最常用的基础设施之一。DolphinDB的分布式文件系统实现,分布式数据库实现,分布式计算框架实现都采用了
DolphinDB自己设计
的RPC系统。DolphinDB的脚本语言通过RPC可以在远程机器上执行代码。DolphinDB在使用RPC时有以下特点:
不仅可以执行在远程机器上已经注册的函数,也可以将本地自定义的函数序列化到远程节点执行。在远程机器运行代码时的权限等同于当前登录用户在本地的权限。
函数的参数既可以是常规的scalar,vector,matrix,set,dictionary和table,也可以是函数包括自定义的函数。
既可以使用两个节点之间的独占连接,也可以使用集群数据节点之间的共享连接。
使用remoteRun执行远程函数
DolphinDB使用
xdb
创建一个到远程节点的连接。远程节点可以是任何运行DolphinDB的节点,不必属于当前集群的一部分。创建连接之后可以在远程节点上执行远程节点上注册的函数或本地自定义的函数。
h = xdb("localhost", 8081);
在远程节点上执行一段脚本:
remoteRun(h, "sum(1 3 5 7)");
16
上述远程调用也可以简写成:
h("sum(1 3 5 7)");
16
在远程节点上执行一个在远程节点注册的函数:
h("sum", 1 3 5 7);
16
在远程系节点上执行本地的自定义函数:
def mysum(x) : reduce(+, x)
h(mysum, 1 3 5 7);
16
在远程节点(localhost:8081)上创建一个共享表sales:
h("share table(2018.07.02 2018.07.02 2018.07.03 as date, 1 2 3 as qty, 10 15 7 as price) as sales");
如果本地的自定义函数有依赖,所依赖的自定义函数会自动序列化到远程节点:
defg salesSum(tableName, d): select mysum(price*qty) from objByName(tableName) where date=d
h(salesSum, "sales", 2018.07.02);
40
使用rpc执行远程函数
DolphinDB使用远程过程调用功能的另一个途径是
rpc
函数。
rpc
函数接受远程节点的名称,需要执行的函数定义以及需要的参数。
rpc
只能在同一个集群内的控制节点及数据节点之间使用,但是不需要创建一个新的连接,而是复用已经存在的网络连接。这样做的好处是可以节约网络资源和免去创建新连接带来的延迟。当节点的用户很多时,这一点非常有意义。
rpc
函数只能在远程节点执行一个函数。如果要运行脚本,请把脚本封装在一个自定义函数内。
下面的例子必须在一个DolphinDB集群内使用。nodeB是远程节点的别名,nodeB上已经有共享表sales。
rpc("nodeB", salesSum, "sales",2018.07.02);
40
在使用
rpc
时,为增加代码的可读性,建议使用部分应用,将函数参数和函数定义写在一起,形成一个新的零参数的函数定义。
rpc("nodeB", salesSum{"sales", 2018.07.02});
40
master是控制节点的别名。DolphinDB只能在控制节点上创建用户:
rpc("master", createUser{"jerry", "123456"});
rpc
函数需要的参数也可以是另外一个函数包括内置函数和自定义函数:
rpc("nodeB", reduce{+, 1 2 3 4 5});
15
使用其它函数间接执行远程函数
remoteRun
和
rpc
都可以在一个远程节点上执行用户在本地自定义的函数。这是DolphinDB的RPC子系统与其它RPC系统最大的不同之处。在其它系统中,通常RPC的客户端只能被动调用远程节点已经暴露的注册函数。在大数据分析领域,数据科学家根据新的研发项目经常会提出新的接口需求。如果等待IT部门发布新的API接口,通常需要很长的周期,这会严重影响研发的效率和周期。如果要在远程节点执行自定义的函数,自定义的函数目前必须使用DolphinDB的脚本来开发。另外,对数据的安全性也提出了更高的要求,必须仔细规划和设置用户的访问权限。如果限制用户只能使用注册的函数,用户的访问权限管理可以十分的简单,只要拒绝外部用户访问一切数据,授权外部用户访问注册的视图函数就可以了。
除了直接使用
remoteRun
和
rpc
函数外,DolphinDB也提供了很多函数间接的使用远程过程调用。例如,在分布式数据库的线性回归就用到了
rpc
与
olsEx
。另外,
pnodeRun
用于在集群的多个节点上并行运行同一个函数,并将返回的结果合并。这在集群的管理中十分有用。
每个数据节点返回最近的10个正在运行或已经完成的批处理作业:
pnodeRun(getRecentJobs{10});
返回节点nodeA和nodeB的最近10个SQL query:
pnodeRun(getCompletedQueries{10}, `nodeA`nodeB);
清除所有数据节点上的缓存:
pnodeRun(clearAllCache);
分布式计算
mr
用于开发基于MapReduce的分布式计算;
imr
用于开发基于迭代的MapReduce的分布式计算。用户只需要指定分布式数据源和核心函数,譬如map函数,reduce函数,final函数等。下面我们演示使用分布式数据计算中位数和线性回归的例子。
n=10000000
x1 = pow(rand(1.0,n), 2)
x2 = norm(3.0, 1.0, n)
y = 0.5 + 3 * x1 - 0.5*x2 + norm(0.0, 1.0, n)
t=table(rand(10, n) as id, y, x1, x2)
login(`admin,"123456")
db = database("dfs://testdb", VALUE, 0..9)
db.createPartitionedTable(t, "sample", "id").append!(t)
利用自定义的map函数
myOLSMap
,内置的reduce函数(+),自定义的final函数
myOLSFinal
,以及内置的map-reduce框架函数
mr
,构建一个在分布式数据源上运行线性回归的函数
myOLSEx
。
def myOLSMap(table, yColName, xColNames){
x = matrix(take(1.0, table.rows()), table[xColNames])
xt = x.transpose();
return xt.dot(x), xt.dot(table[yColName])
}
def myOLSFinal(result){
xtx = result[0]
xty = result[1]
return xtx.inv().dot(xty)[0]
}
def myOLSEx(ds, yColName, xColNames){
return mr(ds, myOLSMap{, yColName, xColNames}, +, myOLSFinal)
}
使用用户自定义的分布式算法和分布式数据源计算线性回归系数:
sample = loadTable("dfs://testdb", "sample")
myOLSEx(sqlDS(<select * from sample>), `y, `x1`x2);
[0.4991, 3.0001, -0.4996]
使用内置的函数ols和未分的数据计算线性回归的系数,得到相同的结果:
ols(y, [x1,x2],true);
[0.4991, 3.0001, -0.4996]
下面这个例子中,我们构造一个算法,在分布式数据源上计算一组数据的近似中位数。算法的基本原理是利用
bucketCount
函数,在每一个节点上分别计算一组内的数据个数,然后把各个节点上的数据累加。这样我们可以找到中位数应该落在哪个区间内。如果这个区间不够小,进一步细分这个区间,直到小于给定的精度要求。中位数的算法需要多次迭代,我们因此使用了迭代计算框架
imr
。
def medMap(data, range, colName): bucketCount(data[colName], double(range), 1024, true)
def medFinal(range, result){
x= result.cumsum()
index = x.asof(x[1025]/2.0)
ranges = range[1] - range[0]
if(index == -1)
return (range[0] - ranges*32):range[1]
else if(index == 1024)
return range[0]:(range[1] + ranges*32)
else{
interval = ranges / 1024.0
startValue = range[0] + (index - 1) * interval
return startValue : (startValue + interval)
}
}
def medEx(ds, colName, range, precision){
termFunc = def(prev, cur): cur[1] - cur[0] <= precision
return imr(ds, range, medMap{,,colName}, +, medFinal, termFunc).avg()
}
使用以上近似中位数算法,计算分布式数据的中位数:
sample = loadTable("dfs://testdb", "sample")
medEx(sqlDS(<select y from sample>), `y, 0.0 : 1.0, 0.001);
-0.052973
使用内置的med函数计算未分区的数据的中位数:
med(y);
-0.052947
元编程(Metaprogramming)
元编程指使用程序代码来创建可以动态运行的程序代码。元编程的目的一般是延迟执行代码或动态创建代码。
DolphinDB支持使用元编程来动态创建表达式,譬如函数调用的表达式,SQL查询表达式。很多业务细节无法在编码阶段确定。譬如说客户定制报表,只有运行时,客户选择了表格,字段和字段格式,才可以确定一个完整的SQL查询表达式。
延迟执行代码一般分为这几种情况:
提供一个回调函数
延迟执行为整体优化创造条件
问题描述在程序编码阶段完成,但是问题实现在程序运行阶段完成
DolphinDB实现元编程的途径有两个,一是使用一对尖括号<>来表示需要延后执行的动态代码,二是使用函数来创建各种表达式。常用的用于元编程的函数包括
objByName
,
sqlCol
,
sqlColAlias
,
sql
,
expr
,
eval
,
partial
,
makeCall
。
使用<>来生成延后执行的动态表达式:
a = <1 + 2 * 3>
a.typestr();
CODE
a.eval();
7
使用函数来生成延后执行的动态表达式:
a = expr(1, +, 2, *, 3)
a.typestr();
CODE
a.eval();
7
可使用元编程来定制报表。用户的输入包括数据表,字段名称和字段相应的格式字符串。下例中,根据输入的数据表,字段名称和格式,以及过滤条件,动态生成SQL表达式并执行。
def generateReport(tbl, colNames, colFormat, filter){
colCount = colNames.size()
colDefs = array(ANY, colCount)
for(i in 0:colCount){
if(colFormat[i] == "")
colDefs[i] = sqlCol(colNames[i])
else
colDefs[i] = sqlCol(colNames[i], format{,colFormat[i]})
}
return sql(colDefs, tbl, filter).eval()
}
模拟生成一个100行的数据表:
t = table(1..100 as id, (1..100 + 2018.01.01) as date, rand(100.0, 100) as price, rand(10000, 100) as qty);
输入过滤条件,字段和格式,定制报表。过滤条件使用了元编程。
generateReport(t, ["id","date","price","qty"], ["000","MM/dd/yyyy", "00.00", "#,###"], < id<5 or id>95 >);
id date price qty
--- ---------- ----- -----
001 01/02/2018 50.27 2,886
002 01/03/2018 30.85 1,331
003 01/04/2018 17.89 18
004 01/05/2018 51.00 6,439
096 04/07/2018 57.73 8,339
097 04/08/2018 47.16 2,425
098 04/09/2018 27.90 4,621
099 04/10/2018 31.55 7,644
100 04/11/2018 46.63 8,383
DolphinDB的一些内置函数的参数需要使用元编程。
窗口连接(window join)
中,需要为右表的窗口数据集指定一个或多个聚合函数以及这些函数运行时需要的参数。由于问题的描述和执行在两个不同的阶段,我们采用元编程来实现延后执行。
t = table(take(`ibm, 3) as sym, 10:01:01 10:01:04 10:01:07 as time, 100 101 105 as price)
q = table(take(`ibm, 8) as sym, 10:01:01+ 0..7 as time, 101 103 103 104 104 107 108 107 as ask, 98 99 102 103 103 104 106 106 as bid)
wj(t, q, -2 : 1, < [max(ask), min(bid), avg((bid+ask)*0.5) as avg_mid]>, `time);
sym time price max_ask min_bid avg_mid
--- -------- ----- ------- ------- -------
ibm 10:01:01 100 103 98 100.25
ibm 10:01:04 101 104 99 102.625
ibm 10:01:07 105 108 103 105.625
DolphinDB中另一个使用元编程的内置功能是更新内存分区表。当然内存分区表的更新,删除,排序等功能也可以通过SQL语句来完成。
创建一个以日期为分区的内存分区数据库,并模拟生成trades表:
db = database("", VALUE, 2018.01.02 2018.01.03)
date = 2018.01.02 2018.01.02 2018.01.02 2018.01.03 2018.01.03 2018.01.03
t = table(`IBM`MSFT`GOOG`FB`IBM`MSFT as sym, date, 101 103 103 104 104 107 as price, 0 99 102 103 103 104 as qty)
trades = db.createPartitionedTable(t, "trades", "date").append!(t);
删除qty为0的记录,并在每个分区中按交易量进行升序排序:
trades.erase!(<qty=0>).sortBy!(<price*qty>);
增加一个新的字段logPrice:
trades[`logPrice]=<log(price)>;
更新股票IBM的交易数量:
trades[`qty, <sym=`IBM>]=<qty+100>;
小结
DolphinDB是一门为数据分析而生的编程语言。DolphinDB支持向量化计算和分布式计算,具有极快的运行速度。与其它数据分析语言Matlab,SAS,pandas等不同,DolphinDB与分布式数据库和分布式计算紧密集成,天生具备处理海量数据的能力。DolphinDB支持SQL编程,函数化编程和元编程,语言简洁灵活,表达能力强,大大提高了数据科学家的开发效率。
FILE:references/doc_2275.md
# left
**URL**: https://docs.dolphindb.cn/zh/funcs/l/left.html
**来源**: DolphinDB 官方文档
---
left
语法
left(X,n)
详情
返回
X
左边
n
个字符。
当
X
是表时,函数仅作用于其中字符串列,其他类型的列将被忽略。
参数
X
是字符串类型的标量、向量,或表。
n
必须是一个非负整数。
返回值
返回值的类型和形式与
X
保持一致。
例子
返回左边的6个字符(包含空格)。
left("I love this game!", 6);
// output
I love
FILE:references/doc_2287.md
# now
**URL**: https://docs.dolphindb.cn/zh/funcs/n/now.html
**来源**: DolphinDB 官方文档
---
now
语法
now([nanoSecond=false])
详情
返回当前的时间戳。
注:
由于 Windows
操作系统对时间精度的支持存在差异,某些版本可能无法实现纳秒级别的精度。因此,即使在调用函数时设置
nanoSecond
=true,返回的时间戳仍可能仅精确到毫秒。
参数
nanoSecond
是布尔值,表示是否精确到纳秒。它是可选参数,默认值为 false,表示精确到毫秒。
返回值
TIMESTAMP/NANOTIMESTAMP 类型标量。
例子
now();
// output
2016.05.12T19:32:49.613
now(true);
// output
2016.05.12T19:32:49.614243000
FILE:references/doc_2291.md
# isIndexedMatrix
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isIndexedMatrix.html
**来源**: DolphinDB 官方文档
---
isIndexedMatrix
语法
isIndexedMatrix(X)
详情
判断
X
是否为有索引的矩阵。
参数
X
是一个矩阵。
返回值
布尔标量。
例子
m=matrix(1..10, 11..20)
m.rename!(2020.01.01..2020.01.10, `A`B);
isIndexedMatrix(m);
// output: false
m.setIndexedMatrix!()
isIndexedMatrix(m);
// output: true
FILE:references/doc_2294.md
# regroup
**URL**: https://docs.dolphindb.cn/zh/funcs/r/regroup.html
**来源**: DolphinDB 官方文档
---
regroup
语法
regroup(X, label, func, [byRow=true])
详情
按给定的行/列标签对矩阵进行分组聚合的操作。
数据表的分组聚合可以通过 SQL 的 group by 语句实现。而通过
regroup
函数,可以实现矩阵的分组聚合操作。
注意:建议参数
func
优先指定为系统内置的聚合函数,因为系统内部对内置函数进行了优化处理。(参考下例 2)
参数
X
矩阵。
label
向量,表示用于分组计算的标签。当
byRow
= true 时,
label
的长度必须与矩阵行数相等,否则与矩阵列数相等。
func
单目聚合函数,可以是用户自定义聚合函数,也可以是内置函数。对具有相同标签的分组应用该函数进行聚合。
byRow
布尔值,默认值 true,表示按行聚合。若为 false,则表示按列聚合。
返回值
一个矩阵。
例子
例1:按行/列标签分组聚合
m = rand(20, 4:5)
m;
col1
col2
col3
col4
col5
11
6
6
10
4
6
7
5
2
16
2
16
14
19
9
17
6
13
10
2
# 按照列标签重组
label = `A`A`B`A`B
regroup(X=m, label=label, func=firstNot, byRow=false)
A
B
11
6
6
5
2
14
17
13
# 按照行标签重组
label = 1 2 1 2
regroup(X=m, label=label, func=firstNot, byRow=true)
label
col1
col2
col3
col4
col5
1
11
6
6
10
4
2
6
7
5
2
16
例2:内置函数和用户自定函数的性能对比
m = rand(1000.0, 10000)$100:100
defg my_avg(v):avg(v)
timer(1000) regroup(m, take(1 2 3 4 5, 100), avg)
// output
Time elapsed: 176.175 ms
timer(1000) regroup(m, take(1 2 3 4 5, 100), my_avg)
// output
Time elapsed: 1062.553 ms
例3:对面板数据进行分钟聚合
n=1000
timestamp = 09:00:00 + rand(10000, n).sort!()
id = take(`st1`st2`st3, n)
vol = 100 + rand(10.0, n)
vt = table(timestamp, id, vol)
m = exec vol from vt pivot by timestamp, id
regroup(m, minute(m.rowNames()), avg)
FILE:references/doc_2297.md
# rowNames
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowNames.html
**来源**: DolphinDB 官方文档
---
rowNames
语法
rowNames(X)
详情
返回矩阵
X
的行名。参见相关函数:
columnNames
参数
X
是一个矩阵
返回值
返回一个向量。
例子
x=1..6$2:3;
x
#0
#1
#2
1
3
5
2
4
6
x.rename!(1 2, `a`b`c);
a
b
c
1
1
3
5
2
2
4
6
rowNames x;
// output
[1,2]
FILE:references/doc_23.md
# insert into
**URL**: https://docs.dolphindb.cn/zh/progr/sql/insertInto.html
**来源**: DolphinDB 官方文档
---
insert into
用于使用
VALUES
子句向表插入数据。
注:
若要向分布式表中插入数据,请先调整配置项 enableInsertStatementForDFSTable。
语法
insert into
table_name1 (colName1 [, colName2, ...])
values (X [, Y, ...]) | select col_name(s) from table_name2
其中, colName 指定目标表中的列名,可以有以下三种方式:
不加引号的列名
colName
双引号括起来的列名
"colName"
前加下划线的双引号列名
_"colName"
例子
t=table(`XOM`GS`FB as ticker, 100 80 120 as volume);
t;
ticker
volume
XOM
100
GS
80
FB
120
insert into t values(`GOOG, 200);
t;
ticker
volume
XOM
100
GS
80
FB
120
GOOG
200
insert into t values(`AMZN`NFLX, 300 250);
t;
ticker
volume
XOM
100
GS
80
FB
120
GOOG
200
AMZN
300
NFLX
250
insert into t values(('AMD','NVDA'), (60 400));
t;
ticker
volume
XOM
100
GS
80
FB
120
GOOG
200
AMZN
300
NFLX
250
AMD
60
NVDA
400
上例还有另一种写法,即按照 SQL 标准写法,直接向表 t 传入多行数据。可得结果一致。
insert into t values ('AMD', 60), ('NVDA', 400);
t;
ticker
volume
XOM
100
GS
80
FB
120
GOOG
200
AMZN
300
NFLX
250
AMD
60
NVDA
400
只往部分列插入新的记录:
insert into t(ticker, volume) values(`UBER`LYFT, 0 0);
t;
ticker
price
volume
XOM
98.5
100
GS
12.3
80
FB
40.6
120
GOOG
100.6
200
AMZN
120
300
NFLX
56.6
250
AMD
78.6
60
NVDA
33.1
400
UBER
0
LYFT
0
FILE:references/doc_2306.md
# dividedDifference
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dividedDifference.html
**来源**: DolphinDB 官方文档
---
dividedDifference
语法
dividedDifference(X, Y, resampleRule, [closed='left'], [origin='start_day'],
[outputX=false])
详情
该函数根据
resampleRule
,
closed
,
origin
确定的采样规则,对
X
进行重采样操作。并根据重采样后的
X
,对
Y
进行均差插值(DividedDifference
Interpolation)。
若不指定
outputX
,仅返回一个对
Y
插值后的向量。若指定
outputX
=
true,则返回一个 tuple,其第一个元素为
X
重采样后的向量,第二个元素为对
Y
插值后的向量。
参数
X
严格递增的时间类型向量。
Y
同
X
等长的数值型向量。
resampleRule
一个字符串,可选值请参考
resample
的
rule
参数。
closed
和
origin
同
resample
的
closed
和
origin
参数。
outputX
布尔类型,表示是否输出
X
按照
resampleRule
,
closed
,
origin
重采样后的向量。默认值为 false。
例子
dividedDifference([2016.02.14 00:00:00, 2016.02.15 00:00:00, 2016.02.16 00:00:00], [1.0, 2.0, 4.0], resampleRule=`60min);
// output
[1,1.0217,1.0451,1.0703,1.0972,1.1259,1.1562,1.1884,1.2222,1.2578,
1.2951,1.3342,1.375,1.4175,1.4618,1.5078,1.5556,1.605,1.6562,1.7092,
1.7639,1.8203,1.8785,1.9384,2,2.0634,2.1285,2.1953,2.2639,2.3342,
2.4062,2.48,2.5556,2.6328,2.7118,2.7925,2.875,2.9592,3.0451,3.1328,
3.2222,3.3134,3.4062,3.5009,3.5972,3.6953,3.7951,3.8967,4]
FILE:references/doc_2310.md
# bitAnd
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bitAnd.html
**来源**: DolphinDB 官方文档
---
bitAnd
语法
bitAnd(X, Y)
或
X & Y
详情
返回位运算与(
bitAnd
)的结果。
参数
X
和
Y
可以是数值型的标量,向量,矩阵,或数据表。
返回值
数值类型标量/向量/矩阵/表。
例子
x=1 0 1;
y=0 1 1;
x&y;
// output
[0,0,1]
FILE:references/doc_2316.md
# knn
**URL**: https://docs.dolphindb.cn/zh/funcs/k/knn.html
**来源**: DolphinDB 官方文档
---
knn
语法
knn(Y, X, type, nNeighbor, [power=2])
详情
通过 K 邻近算法(暴力搜索法)对表中的数据进行训练。
参数
Y
是一个长度与X的行数相等的向量,表示X中每个样本对应的标签。
X
是一张表,表示训练集。表中的每一行表示一个样本,每一列表示一个特征。
type
是一个字符串。它的取值可以是 'regressor' 或 'classifier'。
nNeighbor
是一个正整数,表示 K 邻近算法的邻近节点个数。
power
是一个正整数,表示闵可夫斯基距离(Minkowski Distance)的参数。默认值是2,表示使用欧几里得距离(Euclidean
Distance)。如果
power
=1,表示使用曼哈顿距离(Manhattan Distance)。
返回值
返回一个字典,包含以下 key:
nNeighbor:训练时所用的邻近节点个数
modelName:模型的名称,为字符串 "KNN"
model:内部模型
power:训练时所用的闵可夫斯基距离
type:字符串 "regressor" 或 "classifier"
例子
height = 158 158 158 160 160 163 163 160 163 165 165 165 168 168 168 170 170 170
weight = 58 59 63 59 60 60 61 64 64 61 62 65 62 63 66 63 64 68
t=table(height, weight)
labels=take(1,7) join take(2,11)
model = knn(labels,t,"classifier", 5);
FILE:references/doc_2321.md
# setAtomicLevel
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setAtomicLevel.html
**来源**: DolphinDB 官方文档
---
setAtomicLevel
语法
setAtomicLevel(dbHandle, atomic)
详情
修改分布式数据库的并发写入权限。
参数
dbHandle
是
database
函数返回的分布式数据库句柄。
atomic
表示写入事务的原子性层级,决定了是否允许并发写入同一分区。可选值为 'TRANS' 和 'CHUNK',默认值为 'TRANS'。
设置为'TRANS',写入事务的原子性层级为事务,即一个事务写入多个分区时,若某个分区被其他写入事务锁定而出现写入冲突,则该事务的写入全部失败。因此,该设置下,不允许并发写入同一个分区。
设置为'CHUNK',写入事务的原子性层级为分区。若一个事务写入多个分区时,某分区被其它写入事务锁定而出现冲突,系统会完成其他分区的写入,同时对之前发生冲突的分区不断尝试写入,尝试数分钟后仍冲突才放弃。此设置下,允许并发写入同一个分区,但由于不能完全保证事务的原子性,可能出现部分分区写入成功而部分分区写入失败的情况。同时由于采用了重试机制,写入速度可能较慢。
例子
dbPath="dfs://test"
mydb=database(dbPath, VALUE, ['AMZN','NFLX', 'NVDA'])
mydb.schema()
// output
databaseDir->dfs://test
partitionSchema->[NVDA,AMZN,NFLX]
partitionSites->
partitionTypeName->VALUE
partitionType->1
atomic->TRANS
setAtomicLevel(mydb, `CHUNK)
mydb.schema()
// output
databaseDir->dfs://test
partitionSchema->[NVDA,AMZN,NFLX]
partitionSites->
partitionTypeName->VALUE
partitionType->1
atomic->CHUNK
FILE:references/doc_2325.md
# stringFormat
**URL**: https://docs.dolphindb.cn/zh/funcs/s/stringFormat.html
**来源**: DolphinDB 官方文档
---
stringFormat
语法
stringFormat(format, [args...])
详情
对字符串进行格式化处理,即将用户传入的值按指定的格式进行处理后填充到字符串中。在占位符内部,可以通过格式符指定进制格式、字段宽度、精度、对齐方式等选项,以便对输出进行更精确的控制。
表一:占位符支持的数据类型列表
类型
占位符(%数据类型符号)
args 示例
BOOL
%b
1b, 0b, true, false
CHAR
%c
'a', 97c
SHORT
%h
122h
十进制整数(INT)
%i
21
八进制整数
%o
31
十六进制整数(小写)
%x
2f
十六进制整数(大写)
%X
2F
LONG
%l
25l
DATE
%d
2022.01.01
MONTH
%M
2022.05M
TIME
%t
13:00:10.706
MINUTE
%m
13:30m
SECOND
%s
13:30:10
DATETIME
%D
2012.06.13 13:30:10, 2012.06.13T13:30:10
TIMESTAMP
%T
2012.06.13 13:30:10.008,
2012.06.13T13:30:10.008
NANOTIME
%n
13:30:10.008007006
NANOTIMESTAMP
%N
2012.06.13 13:30:10.008007006,
2012.06.13T13:30:10.008007006
FLOAT
%f
2.1f
DOUBLE
%F
2.1
SYMBOL
%S
symbol(["aaa","bbb"])
STRING
%W
"Hello"
ANY(元组)
%A
(1, 45, 'sah')
注意:若字符串包含 "%" ,则须通过百分号进行转义,即写为 "%%" 。
在占位符内部(即在
%
与数据类型符号之间)插入一个或多个格式化操作符,对输出格式进行控制,书写形式为
%[(var)][#][±][0][m/*][.][n/*]数据类型符号
。
表二:以小数点为分隔,下表解释小数点前的部分支持的符号:
符号
功能
用法示例
m (一个正整数)
支持在 %f, %F, %W 中使用。- 当占位符类型是 f 或 F
时,表示输出字符串的
最小
总宽度,默认使用空格填充宽度。 当 m
小于浮点数实际位数时,输出完整的浮点数(保留至小数点后六位);当 m 大于浮点数实际位数时,默认填充空格。- 当占位符类型是 W
时,表示输出字符串的
最小
位数:当 m 小于字符串长度时,输出完整的字符串;当 m
大于字符串长度时,默认填充空格。默认对齐方式为右对齐。
stringFormat("%10f",
pi)
输出:
··3.141593
stringFormat("%2f",
12345.0)
输出:
12345.000000
stringFormat("%10W",
"6chars")
输出:
····6chars
*
与 m 功能类似,通过参数(
args
)指定输出字符串的宽度。在对应的
args
中指定具体宽度数值,形式为一个元组:
(宽度值,格式化字符串)
。
定义宽度:
stringFormat("%*f",
(10,pi))
输出:`··3.141593`
0
当宽度不足时,在输出的字符串前填充“0”来实现指定宽度(左对齐时,从右边开始填充)。若不指定,则使用空格填充。
stringFormat("%010f",
pi)
输出:
003.141593
-
左对齐,仅适用于数值类型。若不指定该符号,则默认为右对齐。
stringFormat("%-10.3f",
pi)
输出:
3.142
+
在正数前显示加号(+)。
stringFormat('%+f',
pi)
输出:
+3.141593
(var)
映射变量,var 只能是字典形式。不可与其他操作符混用。
employee = {"name":"Lisa Mill", "year":2010}
stringFormat("%(name)W joined the company in %(year)i",
employee)
输出:
Lisa Mill joined the company in
2010
#
在八进制数前显示 “0o”;在十六进制前显示 ”0x“ (当数据类型符号为 “x“时)或者
“0X”(当数据类型符号为 “X” 时)。
stringFormat("%#o",
33)
输出:
0o41
stringFormat("%#X",
33)
输出:
0X21
表三:小数点后的部分支持的符号(
仅支持在 %f, %F 和 %W 中使用
):
符号
功能
用法示例
n(一个正整数)
- 当占位符类型是 f 或 F 时,表示小数点后保留位数。若 n
小于浮点数的小数位数,则会将浮点数四舍五入至指定位数;若该数字大于浮点数的小数位数,则会补零对齐。- 当占位符类型是 W
时,表示保留字符串位数。n 小于字符串长度时对字符串截断,大于字符串长度时不补充。
stringFormat("%10.5f",
pi)
输出:
···3.14159
stringFormat('%10.3f' ,
3.1)
输出:
·····3.100
stringFormat("%2.10W",
"6chars")
输出:
6chars
*
与 n 功能类似,在对应的
args
中指定输出字符串的小数点后的位数,形式为一个元组:
([宽度], [精度值],
格式化字符串的值)
。
定义小数点后位数:
stringFormat("%.*f",
(5,pi))
输出:
3.14159
同时定义宽度与小数点位数:
stringFormat("%0*.*f",
(10,5,pi))
输出:
···3.14159
参数
format
包含0个或多个占位符的字符串。
args...
可选参数,1个或多个填入格式化字符串的值。若指定,则其数量和数据类型必须与
format
中的占位符的数量和类型一致。若不指定,则直接输出
format
。
返回值
STRING 类型标量。
例子
stringFormat("date: %d, time: %t", 2022.12.01, 10:12:45.065)
输出返回:date: 2022.12.01, time: 10:12:45.065
stringFormat("Students account for %i%% of our customers.", 50)
输出返回:Students account for 50% of our customers.
t = datetime(now())
stringFormat("The current time is %D.", t)
输出返回:The current time is 2023.01.02T20:36:03.
a = 7.596
stringFormat("%-+10.5f", a)
输出返回:+7.59600
stringFormat("%010.3f", a)
输出返回:000007.596
product = {"item":"Eggs", "price_per_unit":2}
stringFormat("%(item)W: $ %(price_per_unit)i", product)
输出返回:Eggs: $ 2
FILE:references/doc_2332.md
# isAlpha
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isAlpha.html
**来源**: DolphinDB 官方文档
---
isAlpha
语法
isAlpha(X)
详情
判断
X
是否只包含字母。如果
X
中的所有字符都是字母,该函数返回 true,反之,返回
false。对于空字符串(STRING 类型的 NULL 值),该函数返回 false。
参数
X
是字符或字符串类型的标量、向量或表。
返回值
当
X
是标量时,返回布尔标量。
当
X
是向量时,返回布尔向量。
当
X
是表时,返回一个表。
例子
isAlpha("hello");
// output: true
isAlpha("hello world");
// output: false
isAlpha("1And1");
// output: false
isAlpha(string());
// output: false
FILE:references/doc_2337.md
# 功能配置
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/cfg/function_configuration.html
**来源**: DolphinDB 官方文档
---
功能配置
安全与稳定
配置参数
解释
配置节点
enableClientAuth
设置是否开启用户登录验证。默认为 false。设置为 true
时,访客用户必须登录才能执行脚本。具体限制规则参见
isClientAuth
。
控制节点
strictSecurityPolicy
为集群启用严格的安全策略。启用后的主要变化包括支持设置会话过期时间、自动释放用户自定义对象等。
控制节点
thirdPartyAuthenticator
指定一个函数视图(其参数和 login 函数的参数一致),用于第三方系统校验用户权限。用户通过
DolphinDB 的 HttpClient
等插件与第三方用户系统建立连接。通过指定该参数,在用户登录时,系统会通过第三方系统进行权限验证。
注:
该配置项指定的函数视图,在回调时仍要求调用者具有相关权限。
控制节点
thirdPartyCreateUserCallback
指定一或多个函数视图名称,用于在创建用户时回调从而验证权限。为该配置项指定多个函数视图时,函数视图名称之间以逗号分隔,回调顺序由左向右顺序执行。
注:
该配置项指定的函数视图在回调过程中出现异常时,异常将被忽略并分别记录于日志中。回调结束后,最后一次的回调异常消息(例如:
Failed
to call createUser callback [func1] with error
xxx
)将会抛出。
该配置项指定的函数视图,在回调时仍要求调用者具有相关权限。
控制节点
thirdPartyDeleteUserCallback
指定一或多个函数视图名称,用于在删除用户时回调从而验证权限。为该配置项指定多个函数视图时,函数视图名称之间以逗号分隔,回调由左向右顺序执行。
注:
该配置项指定的函数视图在回调过程中出现异常时,异常将被忽略并分别记录于日志中。回调结束后,最后一次的回调异常消息(例如:
Failed
to call deleteUser callback [func1] with error
xxx
)将会抛出。
该配置项指定的函数视图,在回调时仍要求调用者具有相关权限。
控制节点
enhancedSecurityVerification=false
布尔值,表示是否启用密码复杂性验证,及约束密码重试次数的功能。默认值为 false,不启用;若设置为
true,则启用该功能,此时:
创建或修改的密码必须满足以下条件:
字符个数默认为 6~20。可通过
passwordMinLength
和
passwordMaxLength
调整范围。
至少包含一个大写字母
至少包含以下字符之一:!"#$%&'()*+,-./:;<=>?@[]^_`{|}~。
当某个用户登录时,默认情况下,在 10 分钟内连续输入错误密码 5 次,系统将禁止该用户通过相同 IP
地址进行登录。经过 10 分钟后才允许该用户通过相同 IP 地址再次登录。可通过
failedLoginLockTime
和
failedLoginAttempts
调整时间和尝试次数。
注:
配置项
failedLoginLockTime
,
failedLoginAttempts
,
passwordMinLength
,
passwordMaxLength
,
passwordMinUpperCase
,
passwordMinLowerCase
,
passwordMinDigital
,
passwordMinSpecial
仅在
enhancedSecurityVerification
=true
时生效。
控制节点
failedLoginLockTime
用户连续登录失败后被锁定的时间,单位为分钟,默认值为 10。
控制节点
failedLoginAttempts
用户在最近
failedLoginLockTime
分钟内,连续登录失败
failedLoginAttempts
次,将被锁定
failedLoginLockTime
分钟。
控制节点
passwordMinLength
密码的最小长度,默认值为 6。
控制节点
passwordMaxLength
密码的最大长度,默认值为 20。
控制节点
passwordMinUpperCase
密码包含大写字母(A-Z)的最少个数,默认值为 1。
控制节点
passwordMinLowerCase
密码包含小写字母(a-z)的最少个数,默认值为 0。
控制节点
passwordMinDigital
密码包含数字(0-9)的最少个数,默认值为 0。
控制节点
passwordMinSpecial
密码包含特殊字符的最少个数,默认值为 1。
特殊字符包括:!"#$%&'()*+,-./:;<=>?@[]^_`{|}~
控制节点
passwordEffectTime
密码的有效期,单位为天。默认值为 0,表示不设置有效期。
控制节点
passwordNotifyTime
密码过期前的提醒时间。系统会在密码到期前
passwordNotifyTime
天,在用户登录时提醒其修改密码。默认值为 7。
控制节点
strictPermissionMode
设置在当前节点,是否对磁盘读写、加载插件等操作进行严格权限限制:
默认值为 false,表示所有非 guest 用户都可执行上述操作。
当设置为 true 时,只有管理员用户可以执行。
注:
通常所有需要严格权限限制的节点都需要添加此配置项。受其影响的操作:
saveTextFile,
saveAsNpy, backup, restore, restoreDB, restoreTable,
backupDB, backupTable, migrate, file, files, writeObject,
readObject, loadPlugin, close, fflush, mkdir, rmdir, rm,
writeLog, run, runScript, test, saveTable, savePartition,
saveDualPartition, saveDatabase, saveText, loadText,
loadModule, saveModule
控制节点、数据节点、计算节点
enableShellFunction
设置是否允许用户调用
shell
函数:
默认为 false,禁止任何用户调用。
当设置为 true 时,仅允许管理员用户调用。
控制节点、数据节点、计算节点
enableCoreDump=true
dolphindb 进程启动时,是否检查并修改 core dump 的启用情况。默认值为
true,此时若发现 core dump 未启用,则在系统硬限制允许的情况下为进程开启 core dump;如果发现 core dump
已开启,则不会做任何修改。当设置为 false 时,则不会进行检查。仅 Linux 系统支持该配置项。
数据节点
disableCoreDumpOnShutdown=true
设置安全关机时是否禁用 core dump。默认值为 true,表示安全关机时禁用 core
dump。此参数仅对配置文件对应的节点生效。
数据节点
enableHctEncryption
布尔值,设置是否使用海光密码技术 HCT(Hygon Cryptographic
Technology)对静态加密、DolphinModule 加密进行加速。默认值为 false,不会对加密操作进行加速。
在海光机器上使用 HCT 时,系统会动态加载操作系统中已存在的 hct.so
相关动态库。若未找到对应路径,则会记录日志:
Failed to initialize the
HCT engine for encryption. Using the default
engine
. 此时,需要通过环境变量
OPENSSL_ENGINES
指定动态库路径,例如
OPENSSL_ENGINES="/usr/lib64/engines-1.1"
.
在海光机器上加载成功时,会记录 DEBUG 日志:Using HCT engine.
在非海光机器上配置该配置项,不会对加密操作进行加速,并记录日志:
Failed to initialize
the HCT engine for encryption. Using the default
engine
.
数据节点
TDEKeyDir
字符串标量,指定系统加载 TDE 密钥文件目录的绝对路径。仅 Linux
系统支持该配置项。如需启用数据静态加密,集群模式下,需要修改所有控制节点和数据节点配置文件(
controller.cfg
和
cluster.cfg
)。
控制节点、数据节点
enableSharedVarCreationControl
布尔值,用于控制是否允许用户创建共享变量,默认值为 false,表示不进行权限检查,所有用户都可以创建共享变量。若设置为
true,系统将在创建共享变量时检查用户权限(CREATE_SHARED_VAR),只有具备相应权限的用户才可创建共享变量。
数据节点、计算节点
在 redo log
章节介绍了重做日志相关的配置项。重做日志机制的目的就是为了防止节点宕机后数据丢失。启用重做日志机制,必须启用参考
Cache
Engine
相关内容,同时配置对应的日志存储路径。
在集群环境下,若某个节点发起的事务未完成时,发生了节点宕机。此时,用户可选择手动重启节点,或者经过
datanodeRestartInterval 的时间,集群会自动重启该节点。
配置参数
解释
配置节点
datanodeRestartInterval=0
表示不会自动启动数据/计算节点,为一个非负 INT 类型,单位为秒。默认值为
0。配置该参数可以实现以下功能:
控制节点启动后自动启动数据/计算节点(需要启动 agent);
数据/计算节点离线的时间超过设置时长(t)后自动重启该节点(需要启动 agent)。
注:
若 server 的版本号小于 2.00.9.4,则该参数必须设置为
100+t,其中100是系统预定义值。
控制节点
datanodeRestartLevel=CRASH
指定触发控制节点自动重启数据节点/计算节点的条件。包含如下可选值(区分大小写):
CRASH(默认值):当节点不是通过
stopDataNode
命令关闭,且超过
datanodeRestartInterval
时间没有发送心跳给控制节点时,控制节点将会自动启动该节点。
OFFLINE:节点不在线,且超过
datanodeRestartInterval
的时间没有发送心跳给控制节点时,控制节点将自动启动该节点。
控制节点
存算分离
自
3.00.2
版本起,DolphinDB
实现了存算分离架构。该架构通过引入计算组,将计算节点加入计算组,实现真正的存算分离。计算节点可以缓存部分数据。以下将介绍计算节点缓存的相关配置。
注:
为所有计算组或匹配的计算组指定
computeNodeCacheDir
或
computeNodeCacheMeta
时,必须使用宏变量
<ALIAS>(例如:computeNodeCacheDir=/SCSeparationDDB/Disaggregation/<ALIAS>);但在为计算节点指定这两个参数时,不能使用宏变量
<ALIAS>。
配置参数
解释
配置节点
computeNodeCacheDir =
<HomeDir>/Disaggregation
计算节点的缓存目录。支持一个节点上指定多个物理路径作为缓存目录,路径间以逗号(
,
)分隔,系统将根据磁盘负载进行分配。例如:/volume0/path/to/cache,
/volume1/path/to/cache, /volume2/path/to/cache。
计算节点
computeNodeCacheMeta
计算节点缓存元数据的唯一地址,默认为
<computeNodeCacheDir>/meta
。如果
computeNodeCacheDir
指定了多个路径,取第一个。
计算节点
computeNodeMemCacheSize
非负整数,表示计算节点的内存缓存容量上限,单位为 GB,默认值为 1。其取值范围为 [0, 50% *
maxMemSize],如果设置的值超过了 50% * maxMemSize,将被自动调整为 50% *
maxMemSize。
计算节点
computeNodeDiskCacheSize
非负整数,表示计算节点的磁盘缓存容量上限,单位为 GB,默认值为 64。
计算节点
enableComputeNodeCacheEvictionFromQueryThread
布尔值,默认为
true。表示是否允许查询线程执行缓存驱逐。缓存驱逐机制提高缓存清理的效率,更好地管理内存和磁盘的使用,减少因内存不足(OOM)导致的错误。然而,当缓存容量紧张时,这种机制可能导致查询延迟增加。
计算节点
computeNodeCachingDelay
非负整数,表示时间间隔,单位为秒,默认值为
360。该参数规定了一个分区在最后一次更新后,需经过设定的时间间隔,才能被缓存到计算节点。
控制节点
computeNodeCachingQueryThreshold
非负整数,表示访问次数。取值范围为 [0, 32767],默认值为
1。当一个分区的访问次数超过设定的阈值后,才允许将该分区缓存到计算节点。
控制节点
enableComputeNodePrefetchData
布尔值。若设置为
true(默认值),在计算组中,如果某个分区的缓存没有命中(即请求的数据不在缓存中),系统会将该查询请求下推到数据节点执行,同时会异步地在计算节点中执行相同的查询,以缓存数据(这称为”预热缓存“)。若设置为
false,即使缓存没有命中,系统也不会将查询请求下推到数据节点执行,意味着查询只能在计算节点中处理。开启数据预取可以减少查询时因缓存未命中而导致的延迟,但由于需要执行两次查询,这可能会增加网络和
CPU 的负担。
控制节点
多集群管理
自 3.00.2 版本起,DolphinDB
新增多集群管理工具,能够实现多集群网络互通、跨集群资源调度(跨集群访问数据)等功能。多集群管理中的角色有两种:集群管理者(MoM
集群)和成员集群。这里将给出适用于不同角色的配置项说明。
配置参数
解释
配置节点
isMasterOfMaster
布尔值,表示该节点是否为 MoM 节点。
单节点、控制节点
momHeartbeatHandler
字符串,表示回调函数的函数视图名称。当多集群的管理者(Master of Master,简称 MoM)收到成员集群的 Master
汇报的心跳信息时,将心跳信息作为参数调用回调函数。若指定多个函数视图名称,名称之间以逗号分隔。回调函数将按照从左到右的顺序依次执行。
MoM 节点
masterOfMasterSite
字符串,格式为host:port,表示 MoM 节点的 IP 地址和端口号。
成员集群的控制节点
clusterName
字符串,表示当前集群的名称。命名规则见
变量
。
MoM 节点、成员集群的控制节点
高可用
控制节点存储了集群访问所需的元数据信息。普通集群只包含一个控制节点,若控制节点发生宕机,将造成集群瘫痪。为了避免这种情况,DolphinDB 允许多个控制节点组成
raft 组,来实现控制节点的高可用。
启用控制节点高可用,需要在 raft 组中各个 controller 的 config 文件(默认
controller.cfg)中指定配置项 dfsHAMode=Raft。
配置参数
解释
配置节点
dfsHAMode=Raft
多个控制节点是否组成 raft 组。
控制节点
同时需要修改所有 agent 的 config 文件(默认为 agent.cfg),代理节点配置的 controllerSite
可指定为 raft 组的任一节点。在代理节点信息后必须增加 sites 参数,需包含本机器代理节点和所有控制节点的局域网信息。
配置参数
解释
配置节点
sites
用于指定其它节点局域网信息。格式同 localSite,多个节点间用 "," 隔开。
代理节点
同时需要在 nodesFile 增加所有集群节点的网络信息。
此外,DolphinDB 还提供了配置参数用于设置 raft。该参数需在控制节点的 config 文件配置。
配置参数
解释
配置节点
raftElectionTick=800
确定一个时间区间(单位为10ms):[raftElectionTick, 2
raftElectionTick]。follower 在收到上一个心跳后,经过该区间内一个随机时刻之后仍然没有收到 leader
的心跳,则会发出竞选 leader 的请求。默认值为800,即8s,确定的时间区间为[8s, 16s]。注意:需要保持 raft
组内所有控制节点的配置一致。
控制节点
为了保证数据的安全和高可用,DolphinDB
支持在不同的服务器上存储多个数据副本,并且采用二阶段提交协议实现数据副本之间以及数据和元数据之间的强一致性。即使一台机器上的数据损坏,也可以通过访问其他机器上的副本数据来保证数据服务不中断。要开启副本数和备份机制,需在控制节点的
config 文件配置以下参数:
配置参数
解释
配置节点
dfsReplicationFactor=2
每个表数据块的所有副本数。集群的默认副本数是2,单节点的默认副本数为1。注意:写入数据时 on-line
的数据节点数必须大于等于 dfsReplicationFactor 的值,否则会抛出异常。
控制节点
dfsReplicaReliabilityLevel=0
多个副本是否可以在同一个物理服务器上。
0表示可以;1表示不可以;2表示在资源允许情况下,副本优先部署在多台物理服务器。默认值是0。
控制节点
多副本集群环境下,若某个数据节点宕机,将会造成集群的副本数和配置项 dfsReplicationFactor 不一致。此时若配置了
dfsRecoveryWaitTime,系统将在等待 dfsRecoveryWaitTime 时间后,将不一致的副本复制给其它节点。该参数默认值为
0,表示一直等待节点恢复,不发起副本复制任务。该参数也需在控制节点的 config 文件配置。
配置参数
解释
配置节点
dfsRecoveryWaitTime=0
数据节点宕机后,控制节点需要把此节点的数据副本在其它数据节点重新恢复,以保持副本数的一致。恢复前的等待时间可通过该参数进行配置(单位为毫秒)。默认值是0,表示不开启恢复。若不为
0,则系统内部最小等待时间为60000毫秒,也就是60秒,如果填入的数值小于60000,则会被设置为60000。
控制节点
日志
运行日志:log
server 启动后,系统将会自动产生运行时信息,可以通过命令行配置参数 stdoutLog
决定是否将信息输出到命令行或运行日志(log)中。log 文件的路径信息可由配置项 logFile 进行指定:
配置参数
解释
配置节点
logFile=DolphinDBlog
日志文件的路径和名称。日志文件包含服务器配置的详细内容,警告和错误信息。该参数只能在命令行中指定。
控制节点、代理节点、数据节点
单个日志文件大小存在上限,由
StandaloneMode
章节提到的配置参数 maxLogSize 决定。超过该值后,DolphinDB
将自动生成一个前缀为时间戳(精确到秒)的新的日志文件,以此类推。当旧的系统日志占用大量系统资源时,可通过配置 logRetentionTime
定时删除。
配置参数
解释
配置节点
logRetentionTime=30
设置系统日志的保留时间。超过指定保留时间的日志将被删除。默认值为
30,单位是“天”,类型为浮点型,如:0.5 表示 12 小时。若设置为 0,表示不进行清理。
控制节点、代理节点、数据节点
为了更快定位问题,DolphinDB 支持输出指定等级的日志。可通过配置项 logLevel
在启动前配置,或通过函数
setLogLevel
在线修改。
配置参数
解释
配置节点
logLevel=INFO
日志文件的保留层次。默认值为 INFO。可设置值从低到高为 DEBUG,INFO,WARNING
和 ERROR。日志文件只保留等于或高于 logLevel 取值的日志记录。
控制节点、代理节点、数据节点
重做日志:redo log
当事务完成后,系统会自动检测回收其对应的 redo log。DolphinDB 提供了配置项,支持对 redo log
的回收过程进行调优。
配置参数
解释
配置节点
redoLogPurgeInterval=30
删除重做日志(redo log)的时间间隔(单位是秒),默认值是30。每隔
redoLogPurgeInterval 秒,系统会自动删除已完成事务的重做日志。
单节点、数据节点
redoLogPurgeLimit=4
重做日志(redo log)占用磁盘空间的上限(单位是
GB),默认值是4。如果重做日志占用磁盘超过
redoLogPurgeLimit,系统会自动删除已完成事务的重做日志。
单节点、数据节点
作业日志:job log
用户提交的批处理作业和定时作业的执行信息均保存在 batchJobDir 目录下。
配置参数
解释
配置节点
batchJobDir
保存批量作业和定时作业日志和结果的文件夹目录。如果没有指定,单节点模式下,默认目录是
<HomeDir>/batchJobs。集群模式下,默认目录是<HomeDir>/<nodeAlias>/batchJobs。
数据节点
batchJobFileRetentionTime
设置批处理作业和定时任务的输出(保存在 *.msg 文件中) 和返回值(保存在 *.obj
文件中)的最长保留时间,避免长期累积占用过多磁盘空间。此参数为 double 类型,单位是天。默认值为
0,表示不清理任务输出和返回值。
数据节点
节点查询信息日志
集群环境下,系统还保存了各节点的查询信息的日志(job log)。
配置参数
解释
配置节点
jobLogFile=nodeAlias_job.log
节点工作日志的存储路径,用于记录每个节点上已经执行的所有查询的描述性信息。默认和 logFile
指定 log 文件存储在同一路径下。工作日志文件的默认名是
nodeAlias_job.log
。
数据节点
jobLogRetentionTime=0
当节点的查询信息日志(*_job.log)大小超过 1GB 时,系统会将该日志文件存档,并将后续日志写入新的文件。此参数为
double 类型,单位是天,用于指定存档的最长保留时间。默认值为 0,表示不清理存档。
数据节点
DolphinDB 在 2.00.11.1 版本中为数据节点加入 enableDFSQueryLog 配置项。
配置参数
解释
配置节点
enableDFSQueryLog=false
用于记录所有对分布式表已完成和进行中的查询和子查询。默认为 false。启用
perfMonitoring 配置项且该配置项设置为 true
后,
nodeAlias_job.log
所在目录下会生成一个名为
nodeAlias_query.log
的查询日志文件,包含以下字段:
node
,
userId
,
sessionId
,
rootId
,
type
,
level
,
time
,
database
,
table
,
jobDesc
,其中
database
和
table
字段在子查询记录中显示为空。
数据节点
queryLogRetentionTime=0
当节点查询日志文件
nodeAlias_query.log
的大小超过 1GB
时,系统会将该日志文件存档,并将后续日志写入新的文件。此参数类型为浮点型,单位是天,用于指定存档的最长保留时间。默认值为
0,表示不清理存档。
数据节点
注:
nodeAlias_query.log
与
nodeAlias_job.log
尽管在功能和记录字段上相似,但不同之处在于:
nodeAlias_job.log
仅记录成功的查询;
nodeAlias_query.log
不仅记录成功的查询,也记录进行中的查询。
该配置项的使用有助于发现正在执行中的耗时过长的查询或节点故障时正在执行的查询命令,从而排查可能导致节点阻塞或死锁的原因。
SQL Trace 日志
SQL Trace 日志的存储位置由 traceLogDir 指定。
配置参数
解释
配置节点
traceLogDir
SQL Trace 过程日志的存储路径,默认为
<HomeDir>/traces。
单节点、数据节点
审计操作日志
DolphinDB 可以将数据库上执行的 DDL 操作记录到独立的审计日志文件 <logFile>/<ALIAS>_audit.log 中,同时将
ACL 操作(登录登出,权限修改、新建连接和配置文件修改)记录到独立的审计日志文件 <logFile>/<ALIAS>_aclAudit.log
中。当
enableStructuredAuditLog
设置为 true 时,审计日志将以二进制格式存储,文件名分别为
<ALIAS>_audit.audit 和 <ALIAS>_aclAudit.audit。二进制审计日志无法直接读取或修改,用户可以通过
getAuditLog
和
getAclAuditLog
函数获取对应的审计日志信息。
单个日志文件的大小上限为 128M ,超过该值后,DolphinDB 将自动生成一个前缀为时间戳(精确到秒)的日志文件用于存储历史日志。历史日志可通过配置参数
logRetentionTime
定时删除。
配置参数
解释
配置节点
enableAuditLog
是否将数据库上执行的 DDL、ACL(登录登出、权限修改、新建连接和配置文件修改等)操作记录到独立的日志文件中。默认值为
false,表示不开启此功能。
注:
对于集群部署,如果只记录 DDL
操作,不需要在控制节点配置 enableAuditLog;如果要记录权限相关日志,需要在控制节点配置
enableAuditLog。
数据节点/控制节点
auditLogRetentionTime
设置历史日志的保留时间。超过指定时间的日志将被删除。单位是“天”,类型为浮点型。例如:0.5 表示 12 小时。默认值为
0 ,代表不清理存档。
数据节点
原始代码日志
配置参数
解释
配置节点
enableRawScriptLog
是否记录用户脚本的原始代码和执行信息。默认为 false。设置为 true 后,每次用户脚本执行时,会将信息以 CSV
格式记录到
<node>_rawScript.log
文件中,字段之间用
0x1f
分隔符分隔。
数据节点
maxRawScriptLogSize
单个原始代码日志文件的大小上限,单位为 MB。默认值为 128。超出该值后,DolphinDB
将自动生成一个前缀为时间戳(单位为秒)的日志文件用于存储历史日志。
数据节点
rawScriptLogRetentionTime
指定原始代码日志的保存时间,浮点型,单位为天。默认值为 0,表示不自动清理历史日志。
数据节点
线程
DolphinDB 采用多线程技术,有以下几种常见的线程类型:
worker:常规交互作业的工作线程,接收客户端请求,将任务分解为多个小任务,根据任务的粒度自己执行或者发送给
local executor 或 remote executor 执行。
从
2.00.10
版本开始,DolphinDB 引入了多级任务算法,即将作业及其拆分出来的子任务区分为不同的层级,并分配给相应层级的 worker
来处理。DolphinDB 提供了0~5个级别的 worker。 客户端提交至节点的作业为0级,由0级 worker
处理。根据作业所涉及到的分区,0级 worker 将作业分解为多个子任务,其中本地节点上的子任务由0级或1级 worker
并行执行;需要由远程节点执行的子任务则降低为1级,并通过 remote executor 发送到对应节点上的1级 worker
处理。以此类推,若某个级别的子任务需要进一步拆解,则拆分出来的由远程节点执行的子任务降低一级,发送至远程节点上对应层级的 worker 处理。
这种根据任务层级分配不同层级 worker 的线程工作机制,可以有效避免因各个子任务执行期间彼此依赖而导致的死锁问题。
remote
executor:远程执行线程,将子任务发动到远程节点的独立线程。远程执行线程具有容错机制。在多个计算机都包含任务所需数据的副本的情况下,如果一台计算机出现故障,远程执行线程将该任务发送到另一台计算机。
batch job worker:批处理作业的工作线程。其上限通过配置项 maxBatchJobWorker
设置,默认值是workerNum。该线程在任务执行完后若闲置60秒则会被系统自动回收,不再占用系统资源。
dynamic worker:动态工作线程,作为 worker 的补充。其上限通过配置项
maxDynamicWorker 设置,默认值是
workerNum。如果所有的工作线程被占满,有新任务时,系统会创建动态工作线程来执行任务。根据系统并发任务的繁忙程度,总共可以创建三组动态工作线程,每一个级别可以创建
maxDynamicWorker 个动态工作线程。该线程在任务执行完后若闲置60秒则会被系统自动回收,不再占用系统资源。
web worker:处理 HTTP 请求的工作线程。DolphinDB 提供了基于 web
的集群管理界面,用户可以通过web 与 DolphinDB 节点进行交互。其上限通过配置项 webWorkerNum 设置,默认值是1。
urgent worker:紧急工作线程,只接收一些特殊的系统级任务,譬如登录,取消作业等。其上限通过配置项
urgentWorkerNum 设置,默认为1。
注:
worker 的数量直接决定了系统的并发计算的能力。
相关配置参数:
配置参数
解释
配置节点
workerNum
常规作业的工作线程的数量。默认值是 CPU 的内核数。
单节点、控制节点、代理节点、数据节点、计算节点
remoteExecutors=1
远程执行线程的数量。默认值是 1,建议配置为集群节点数减 1。
单节点、控制节点、代理节点、数据节点、计算节点
maxBatchJobWorker=4
批处理作业的最大工作线程数量。默认值是 workerNum 的值。
单节点、控制节点、代理节点、数据节点、计算节点
maxDynamicWorker=4
动态工作线程数量的最大值。默认值是 workerNum 的值。
单节点、控制节点、代理节点、数据节点、计算节点
webWorkerNum=1
处理HTTP请求的工作线程的数量。默认值是 1。
单节点、控制节点、代理节点、数据节点、计算节点
urgentWorkerNum=1
紧急工作线程的数量。默认值是 1。
单节点、控制节点、代理节点、数据节点、计算节点
enableMultiThreadMerge
布尔值,表示是否允许在执行 SELECT 查询的分区任务后按列多线程合并结果表。默认值为
false,表示禁用多线程合并。该配置参数对具有大量分区数量和分区查询结果的场景会有明显提升效果。注意:该参数设置为 true
后,须保证分区查询结果的列数不小于 2、且总行数 * 总列数大于 5000
万,满足该条件才会进行多线程合并;否则不生效。
单节点、数据节点
crossClusterRaftWorkerNum=4
设置跨集群 Raft Learner 通信线程的数量,默认值是 4。
数据节点
参考线程教程:
线程模型
下述配置参数应用于编程时,可能影响计算规则或者计算性能:
配置参数
解释
配置节点
openblasThreads
openBLAS 可以工作的线程数。应用于矩阵计算场景。
数据节点
计算
配置参数
解释
配置节点
maxRecursiveDepth
正整数,表示递归调用的最大深度。当实际递归深度超过该值时,系统将抛出异常。默认值为
1000。仅在配置节点上生效。
控制节点、数据节点、计算节点
内存
在使用 DolphinDB 进行大数据查询和计算时,可能会遇到内存不足导致的 OOM(内存溢出)问题。为尽量避免这种情况,DolphinDB
提供了一些内存调优参数,帮助管理内存使用。
最大内存限制(
maxMemSize
指定)决定了 DolphinDB
运行在服务器的内存上限,它是常规内存区、小对象内存区(
reservedMemSize
指定)和紧急内存区(
emergencyMemSize
)三部分的总和。具体来说:
当使用内存超过常规内存时,DolphinDB 会进入“小对象分配”状态,避免一次性申请过多内存导致溢出。会对每次分配的内存大小进行限制,通过
maxBlockSizeForReservedMemory
控制。
当小对象内存区用满后,系统会停止为常规任务分配内存。此时,紧急内存区会为一些紧急任务分配内存,例如存储引擎的刷盘操作,或分布式写入事务提交时的关键步骤等。
当紧急内存区也用满,即
maxMemSize
完全用满后,DolphinDB 将停止为所有任务分配内存,仅允许管理员取消任务(详见
系统卡死
)。
配置参数详情如下:
配置参数
解释
配置节点
maxMemSize=0
分配给 DolphinDB 的最大内存空间(以 GB 为单位)。如果该参数设为0,表明
DolphinDB 的内存使用没有限制。建议设置为比机器内存容量低的值。
单节点、控制节点、代理节点、数据节点、计算节点
reservedMemSize=5% * maxMemSize
一个大于 0 的数字,单位为GB。当 DolphinDB 的可用内存小于 reservedMemSize
时,但仍有新的内存申请时,DolphinDB 将仅分配由 maxBlockSizeForReservedMemory
指定大小的内存块,这是为了尽可能保证报错、事务回滚等需要内存量少但较为关键的操作能有足够的内存,以降低此类操作失败的概率。例如,当因内存不足导致写入失败时,尽量保证仍然能正常回滚,避免数据不一致。若不指定该参数,系统默认按照
maxMemSize 的5%预留内存(此时,预留内存最小为64MB,最大为1GB)。
emergencyMemSize
与
reservedMemSize
的总和不可超过
maxMemSize
的 50% 。
单节点、控制节点、代理节点、数据节点、计算节点
emergencyMemSize=5% * maxMemSize
用于配置紧急内存区的大小,单位为GB。
注意:(1)不可超过
maxMemSize
的50%;(2)emergencyMemSize 与
reservedMemSize 的总和不可超过
maxMemSize
的50% 。
若不指定时,默认为
maxMemSize
的5%,最小不低于512M,最大不能超过5G。
单节点、控制节点、代理节点、数据节点、计算节点
maxBlockSizeForReservedMemory=8
表示 DolphinDB 可使用内存少于 reservedMemSize
时,每次申请内存的请求可以分配的最大内存块(单位为KB),默认值为
8。不建议设置过大值,否则系统可能因内存被占满,而导致关键操作申请不到内存,进而出现异常或崩溃。
单节点、控制节点、代理节点、数据节点、计算节点
当内存占用达到 warningMemSize 时,系统会自动清理数据库的缓存,释放一部分内存,以避免 OOM。
配置参数
解释
配置节点
warningMemSize
当内存使用量超过 warningMemSize (以 GB
为单位)时,系统会自动清理部分数据库的缓存,以避免出现 OOM 异常。默认值为 maxMemSize 的75%。
单节点、控制节点、代理节点、数据节点、计算节点
用户也可限制事务的最大
写入
大小,从而避免出现内存问题:
配置参数
解释
配置节点
maxTransactionRatio=0.2
0.1~1.0之间的浮点数,表示 TSDB 或 OLAP存储引擎的单次写入事务大小上限与 cache
engine 大小的比值。假设TSDB Cache Engine=16G,此参数设置为0.2,则表示
写入
事务不能超过 16
* 0.2 = 3.2G。若多节点 Cache Engine 大小不同(如
Node1=4G,Node2=2G),则按平均值(3G)计算。
注意
:若 OLAP 引擎未开启 cache
engine,此参数对OLAP 的事务写入无限制。
单节点、数据节点
IOTDB相关内存参数:
配置参数
解释
配置节点
IOTDBLatestKeyCacheSize
浮点数,用于管理最新值缓存表的最大值,单位为 GB。默认值为
maxMemSize
的
5%。
单节点、数据节点
IOTDBStaticTableDir
用于配置静态表目录路径。默认值为 Home 目录下的 IOTDBStaticTable
目录。
单节点、数据节点
IOTDBStaticTableCacheSize
浮点数,用于管理静态表缓存最大值,默认为maxMamSIze 的 5%。
单节点、数据节点
此外 DolphinDB 还提供了配置项,用来调整内存释放的速度。该参数等价于设置了
TCMalloc
的 tcmalloc_release_rate。
配置参数
解释
配置节点
memoryReleaseRate=5
将未使用的内存释放给操作系统的速率,是0到10之间的浮点数。 memoryReleaseRate=0
表示不会主动释放未使用的内存,memoryReleaseRate=10 表示以最快的速度释放内存。默认值是5。
单节点、控制节点、代理节点、数据节点、计算节点
设置 dataSync=1 后,每个节点的内存将维护 OLAP Cache Engine
和 TSDB Cache Engine
。该参数配置需在 controller 的 config
文件配置(默认为 controller.cfg)。
配置参数
解释
配置节点
dataSync=0
表示是否采用数据强制刷盘策略。默认值为0,表示是否由操作系统决定什么时候刷盘。如果
dataSync=1,表示将 redo log、数据和元数据强制刷盘。
单节点、控制节点
DolphinDB 提供普通数组(array)和大数组(bigArray)两种数组类型,array
要求连续内存,优点是性能稍高,缺点是如果要求的内存太大,系统可能由于无法提供连续的内存而分配失败;bigarray
不要求连续内存,优点是可以利用碎片小内存提供大的内存请求,缺点是性能会稍差。
DolphinDB 提供了
regularArrayMemoryLimit
参数来设置普通数组 array
的最大内存上限,如果超过该限制,那么 array 定义的变量会采用 bigArray 方式分配内存。
配置参数
解释
配置节点
regularArrayMemoryLimit=2048
常规数组的内存限制(以 MB 为单位)。该参数必须是2的指数幂。默认值为 2048,系统运行时的实际值为
min(regularArrayMemoryLimit, maxMemSize/2)。
单节点、控制节点、代理节点、数据节点、计算节点
磁盘
DolphinDB 数据存储的路径取决于配置参数 volumes。
配置参数
解释
配置节点
volumes=
/hdd/hdd1/volumes/<ALIAS>,
/hdd/hdd2/volumes/<ALIAS>,
/hdd/hdd3/volumes/<ALIAS>,
/hdd/hdd4/volumes/<ALIAS>
数据文件目录。如果没有指定,单节点模式下,默认目录是
<HomeDir>/storage。集群模式下,默认目录是<HomeDir>/<nodeAlias>/storage。
数据节点
allowVolumeCreation=true
布尔值,当 volumes 指定的路径不存在时,是否允许自动创建该路径。默认值为
true,表示允许自动创建。若配置为 false,当 volumes 指定的路径不存在时,系统会自动退出,同时输出错误日志到 log
文件。
数据节点
volumeUsageThreshold=0.97
浮点数,范围为(0, 1],默认值为
0.97。设置数据节点上磁盘卷的使用率阈值,仅适用于数据节点。当一个数据节点指定的磁盘卷的总使用率达到该值时,该节点将无法新增
chunk,但仍可继续向已存在的 chunk 写入数据。
系统在新建分区或向已存在的 chunk 写入数据时,会分别检查节点下每个
volume 的使用率。根据情况决定是否写入数据:
使用率 <
volumeUsageThreshold
,可写入。
使用率 ≥ volumeUsageThreshold:
剩余空间 ≥ 50GB,可写入
剩余空间 10GB~50GB 且使用率 < 98%,可写入
否则,不可写入
数据节点
在对读写要求较高的场景下,用户可以选择指定多个
volumes,并将其配置在多个磁盘上。此外,用户可以通过配置磁盘读写线程的数量,来提升磁盘的 I/O。
配置参数
解释
配置节点
diskIOConcurrencyLevel=1
读写磁盘数据的线程数,默认为1。若设置 diskIOConcurrencyLevel =
0,表示使用当前任务执行的线程来读写磁盘数据;若设置 diskIOConcurrencyLevel >
0,则会创建指定个数的线程来读写磁盘数据。合理设置该参数,可以优化读写性能,因此建议配置如下:若 volumes 配置了 SSD
硬盘,建议设置 diskIOConcurrencyLevel = 0;若 volumes 全部配置为 HDD 硬盘,建议
diskIOConcurrencyLevel 设置为同 HDD 硬盘个数相同的值。
数据节点
某些文件系统不支持 hardLink 功能,需修改配置 hardLink = false。
配置参数
解释
配置节点
useHardLink=true
是否使用文件系统 hardlink 的功能。若为 true,表示使用文件系统 hardlink
功能;若为 false,则不使用 hardlink 功能。默认值为 true。
数据节点
通过 maxFileHandles 配置项可以调整一个 dolphindb 进程允许打开文件数。
配置参数
解释
配置节点
maxFileHandles=1024
一个进程维护的文件描述符上限。
数据节点
2.00.9
版本开始支持自定义交易日历。以下函数
temporalAdd
,
resample
,
asFreq
,
transFreq
中指定交易日历。
配置参数
解释
配置节点
marketHolidayDir
交易市场节假日文件的存储目录,可以是绝对路径或者是相对目录,默认为 <HomeDir>/marketHoliday。
系统搜寻相对目录的顺序如下:先到节点的 home 目录寻找,再到节点的工作目录寻找,最后到可执行文件所在目录寻找。
存储的文件必须满足以下条件:文件格式为 csv;仅包含一个 DATE 类型的列。
数据节点
根据
marketHolidayDir
下已存在的节假日文件生成交易日历,并采用文件名作为交易日历的标识。交易日历文件在系统启动时被加载到内存中。需要注意:
系统默认周末为节假日,因此文件内只需填写非周末的休市日期。
建议将交易日历文件以交易所编码命名,如 “CEFG.csv”。
数据节点的元数据文件为
editlog.xxx
和
checkpoint.xxx
,其存储路径可通过下述参数配置。
配置参数
解释
配置节点
chunkMetaDir
数据节点的元数据目录。如果没有指定,默认目录为配置参数 volumes
指定的第一个路径。
数据节点
分布式文件系统中,集群的元数据信息存储在控制节点上,对应文件为:
DFSMetaLog.xxx
和
DFSMetaCheckpoint.xxx
。可通过下述配置项指定存储目录:
配置参数
解释
配置节点
dfsMetaDir
分布式文件系统的元数据信息的存储路径。单节点模式下,该文件默认存储在
<HomeDir>/<nodeAlias>/dfsMeta 文件夹下。普通集群模式下,该文件默认存储在控制节点的
<HomeDir> 文件夹下。高可用集群模式下,该文件默认存储在
<HomeDir>/<nodeAlias>/dfsMeta,其中 <nodeAlias> 为
leader 控制节点的别名。
控制节点
注:
该配置项需在 controller 的 config 文件中配置(默认为 controller.cfg)。
网络
为了减少网络传输的开销,建议集群所有节点配置在同一局域网下。
单节点模式下默认 server 的 ip 为本机 ip,端口号为 8848。若端口号被占用,可前往 config 指定的配置文件进行修改。
配置参数
解释
配置节点
localSite
节点的局域网信息,格式为 host:port:alias。单节点模式中默认值为
localhost:8848:local8848。
单节点、控制节点、代理节点、数据节点、计算节点
集群环境下,控制节点和代理节点启动前,需在各自的 config 文件中配置自身的 localSite;代理节点还需额外配置
controllerSite。
配置参数
解释
配置节点
controllerSite
代理节点的控制节点的局域网信息,必须与 controller.cfg 中某个控制节点的
localSite 相同。代理节点启动时,会使用该参数与控制节点通讯。
代理节点
localSite 中的 host:port 为节点的 ip 和端口号,alias
将作为节点的别名。设置别名可以便于脚本编程中快速定位到指定节点,并与之建立通信连接,如
subscribeTable
函数中指定 server
参数为远端节点的别名,即可订阅远端节点发布的流数据表。用户可在线调用
getNodeAlias
获取当前节点的别名,或
getControllerAlias
获取控制节点的别名。
节点的属性通过配置项 mode 声明,目前的可选值为
controller(控制节点),agent(代理节点),datanode(数据节点)以及 computenode(计算节点)。该配置项需在所有节点 config
文件声明。
配置参数
解释
配置节点
mode
节点的模式
单节点、控制节点、代理节点、数据节点、计算节点
若需要配置计算组,需要在属性 computeGroup 中进行声明。
配置参数
解释
配置节点
computeGroup
计算组名称,只能在计算节点后添加。添加后表示该计算节点属于该组。例如:host:port:alias,computenode,orca
计算节点
除了 config 文件外,controller 服务器配置的 nodesFile
文件中,也包含了所有集群代理节点、数据节点和计算节点的 localSite 和 mode,该文件为 controller
提供了集群的网络信息,以便控制节点可以访问到其它节点。
节点与节点之间基于 TCP 协议传输数据,DolphinDB 提供了 TCP 配置选项
tcpNoDelay,便于用户在实际生产场景下,进行通信调优。启用该参数在一定程度上可以减小传输延迟,但可能带来更大的网络负载。
配置参数
解释
配置节点
tcpNoDelay=true
启动
TCP_NODELAY
套接字选项。默认值是 false。
单节点、控制节点、代理节点、数据节点、计算节点
tcpUserTimeout=300000
设置
TCP_USER_TIMEOUT
套接字选项,单位是毫秒,默认值为300000。
单节点、集群中的所有节点
控制节点通过心跳机制监控其它节点的存活状态,心跳可以采用 TCP/UDP 传输,通过配置项 lanCluster
指定。该参数需配置在代理节点、数据节点和计算节点的 config 文件。若心跳超时,则控制节点会认为该节点已经宕机。因此,在网络较差的场景下,建议配置较大的
dfsChunkNodeHeartBeatTimeout。
配置参数
解释
配置节点
lanCluster=true
集群是否建立在 LAN(local area network)上。若为 true,心跳采用 UDP
协议;若为 false,心跳采用 TCP 协议。默认值为 true。对部署在云上的集群,应当设为 false。
单节点、控制节点、代理节点、数据节点、计算节点
dfsChunkNodeHeartBeatTimeout=8
INT
类型,控制节点配置项,用于设置数据节点、计算节点、代理节点心跳超时的临界时间(单位为秒)。若超过该值,控制节点仍未收到对应节点的心跳,则认为该节点已宕机。默认值是
8s。
单节点、控制节点、代理节点、数据节点、计算节点
集群内每个节点都与集群其它远程节点相连接。每个节点连接上限数取决于配置项 maxConnectionPerSite。
配置参数
解释
配置节点
maxConnectionPerSite
从本地节点到远程节点可以创建的最大连接数量,不能小于 16。默认值是
max(
workernum
+
webworkernum
+1, 16) 。
单节点、控制节点、代理节点、数据节点、计算节点
特别地,DolphinDB 设计开发了 RDMA(Remote Direct Memory
Access,远程直接数据存取)全新通讯架构。区别于 TCP/IP 网络架构, RDMA
实现了对远程计算机内存的直接访问能力,特别适用于需要高速、低延迟通信的场景,如使用分布式内存表、处理 RPC 操作等(不支持处理流数据)。
在使用 RDMA 功能时,可直接延用已传入的参数
ip
和
port
,且原有代码可以实现完全复用。目前
RDMA 仅支持 Linux 系统中集群内部调用 RPC(远程过程调用)的情况。
使用时,请确保已在当前机器中下载依赖的
libibverbs
库,并且在当前的所有节点(包括
controller、datanode、computenode 和 agent)的配置中都已启用 RDMA 功能。否则集群无法正常工作。以下为配置项的具体介绍。
配置参数
解释
配置节点
enableRDMA
BOOL 类型,表示是否开启 RDMA。默认值是 false,表示不开启。
单节点、控制节点、代理节点、数据节点、计算节点
注意:开启 RDMA 后不可使用 SSL 功能。
用户通过 API, GUI, Web notebook
开启一个会话,并通过会话和对应节点建立一个连接。每个节点的最大外部会话连接上限数由配置参数
maxConnections
决定。
配置参数
解释
配置节点
maxConnections=64
最多可以从多少个外部 GUI,API 或其它节点连接到本地节点。Windows
的默认值为64,有效最大值也是64;Linux 的默认值为512。
单节点、控制节点、代理节点、数据节点、计算节点
Web notebook、VS Code 等编辑器与 DolphinDB server 默认采用 HTTP 协议传输数据。可通过配置
enableHTTPS,决定是否采用安全传输协议 HTTPS 进行传输。
配置参数
解释
配置节点
enableHTTPS=false
是否启用 HTTPS 安全协议,默认值为 false。
单节点、控制节点、代理节点、数据节点、计算节点
自 2.00.15 版本开始,DolphinDB 在 TCP 基础上集成了 SSL/TLS 加密传输功能,实现集群内部节点间的加密传输。
配置参数
解释
配置节点
enableRpcSSL
布尔值,用于指定是否在集群内部节点之间的数据传输和使用
rpc
函数时启用 SSL
协议进行加密传输。默认值为 false。
注意
:开启
enableRpcSSL
需要所有节点同时配置
enableHTTPS
=
true,否则连接失败。
控制节点、代理节点、数据节点、计算节点
局域网环境下通过控制节点的 ip:port 可以直接访问集群的 web
管理器,若控制节点和其它节点不在同一局域网下,需指定控制节点的外网网络信息。该配置项需在 controller 的 config 文件进行配置(默认为
controller.cfg)。
配置参数
解释
配置节点
publicName
控制节点外网 IP 或域名。如果 enableHTTPS 为 true,publicName
必须为域名。
控制节点
自
3.00.2
版本起,DolphinDB
支持软件许可证管理,即公网 license server。在 license server 的架构中,主要分为服务端和客户端两部分。license server
通过心跳机制与客户端保持通信,监控客户端的资源使用情况,并在客户端节点状态变化时做出相应处理。
若需要使用 license server,必须使用 Type3 类型的 license,且需要进行调用函数进行用户与资源注册,并通过配置项进行相关配置。详情咨询技术支持。
license server 配置包括服务器和客户端两部分,相关配置项如下:
服务端
配置参数
解释
配置节点
isLicenseServer
布尔值,表示当前节点是否为 license server。仅当 license 的 type 是 3 时,将该参数配置为
true,才能将该节点设置为 license server。
license server 以单机模式运行。其结合 license 文件,给集群中各节点(代理节点除外)分配硬件资源。
单节点
客户端
用户需要先联系 DolphinDB 取得 licenseServer.lic
文件,并将其放至节点所在目录中。然后,在节点的配置文件(controller.cfg/agent.cfg/cluster.cfg)中设置
useLicenseServer,并可以选配 coreAffinity。
配置参数
解释
配置节点
useLicenseServer
布尔值,若设置为 true,则表示以 license server 方式启动。否则,以普通节点启动,并使用本地 license
文件。
单节点、控制节点、数据节点、计算节点、代理节点
coreAffinity
字符串,为节点指定 CPU 内核编号。多个编号间用","分隔;连续的编号可用"-"连接起始编号。例如,绑定 1 到 4
的内核,可写为 1, 2, 3, 4 或 1-4。仅向 license server 申请资源的节点可配置该参数:
指定该参数时,进程将在指定内核上运行;
不指定该参数时,则绑定前
workerNum
个内核。
注意,必须满足以下两点才能成功启动节点:
所指定的 CPU 内核在物理机上存在;
绑定的核数小于等于
workerNum
。
单节点、控制节点、数据节点、计算节点、代理节点
恢复(recovery)和再平衡(rebalance)
处于宕机、离线和同步恢复中的节点,不参与事务的处理。在此期间,若其它节点发起的事务涉及到该节点上的
CHUNK,根据集群是否为多副本,可分为以下两种情况:
集群为单副本,事务无法进行;
集群为多副本,系统将发起节点间恢复。
节点间恢复分为在线增量恢复和全量同步恢复。系统会优先尝试在线增量恢复,即通过其它节点的副本数据,增量补齐该节点由于无法参与事务而缺失的数据量。若存在数据不一致等问题,造成增量的在线恢复无法进行,系统将自动转换全量同步恢复。
节点间的全量恢复将以 CHUNK 副本为单位,将完整的副本复制到宕机节点中,因此网络开销较大。
节点间的在线增量恢复,只需复制缺失的事务数据,数据量较小。其通常分为两个阶段,异步恢复和同步恢复。当数据量较大时,同步恢复会导致源节点长时间阻塞,无法参与任何事务。因此在线恢复的第一阶段采用异步恢复,源节点在此期间仍可参与其它事务。等待恢复的数据量小于
dfsSyncRecoveryChunkRowSize 配置的值时,开始第二阶段的同步恢复,在较短的时间便可以完成。
配置参数
解释
配置节点
dfsSyncRecoveryChunkRowSize=1000
一个正整数,默认值为1000。节点间进行数据恢复时,默认采用异步恢复,当待恢复的目的 chunk
的记录数与最新版本的记录数的差值小于该设置值,就会启用同步复制。
数据节点
为了进一步提升节点间数据恢复任务的速度,可以通过调整配置项 dfsRecoveryConcurrency
来增加任务的并发度。
配置参数
解释
配置节点
dfsRecoveryConcurrency
节点恢复时,执行 recovery 任务的并发度(worker
的数量),默认是集群数据节点个数的2倍。
数据节点
同步恢复阶段,执行恢复任务的工作线程数可由参数 recoveryWorkers 配置。
配置参数
解释
配置节点
recoveryWorkers=1
INT 类型,用于设置当前数据节点用于执行 recovery 的线程数量,默认值为 1。
注意:
如果当前线程数少于新配置线程数,则会创建缺少数量的线程;如果当前线程数大于新配置线程数,系统会阻塞回收多余数量的线程。
对 recoveryWorkers 的上限没有做硬限制,但是会受到操作系统限制。
数据节点
数据再均衡(rebalance)分为节点内数据均衡和节点间数据均衡。
节点内数据均衡主要指某个节点配置了多个磁盘卷,增加新的磁盘卷后,需要把数据重新分配,以提高 I/O 效率。对应函数
rebalanceChunksWithinDataNode
。
节点间数据均衡指由于集群数据在各个节点上分配不均,可通过再均衡重新分配,提高分布式计算的效率。对应函数
rebalanceChunksAmongDataNodes
。
在均衡的工作并发度可通过配置项 dfsRebalanceConcurrency 指定。
配置参数
解释
配置节点
dfsRebalanceConcurrency
节点数据再均衡时,执行 rebalance 任务的并发度(worker
的数量),默认是集群数据节点个数的2倍。
数据节点
在节点恢复过程中,为了避免节点宕机或离线对恢复过程造成太大影响,可以开启节点恢复事务的重做日志,配置
enableDfsRecoverRedo = true。开启后,在节点恢复的过程中,会将恢复事务相关的数据先写入 recover redo log 中。
配置参数
解释
配置节点
enableDfsRecoverRedo=true
启用节点恢复过程的重做日志。
数据节点
recoverLogDir=<HomeDir>/recoverLog
节点恢复事务重做日志的存储路径,默认路径为
<LogDir>/recoverLog。需和数据目录存储在不同的磁盘,建议配置为 SSD 高速磁盘的路径。
数据节点
异步复制
自 2.00.15 版本起,异步复制支持主从集群间使用 SSL 协议进行加密传输,可通过以下配置开启。
配置参数
解释
配置节点
enableClusterReplicationSSL
布尔值,用于指定是否在主从集群异步复制时启用 SSL 协议进行加密传输。默认值为 false。
注意
:开启
enableClusterReplicationSSL
需要主集群同时配置
enableHTTPS
= true,否则连接失败。
主从集群的控制节点、数据节点、计算节点
主集群
clusterReplicationSlaveNum 和 clusterReplicationMode 为必选参数。
配置参数
解释
配置节点
clusterReplicationSlaveNum=2
允许配置的从集群数量上限。
控制节点
clusterReplicationMode
集群间的异步复制模式。可选值为 master 和
slave,表示主集群和从集群。
数据节点
clusterReplicationWorkDir=<HomeDir>
指定异步复制的工作目录,存储写任务的数据。默认为数据节点的<HomeDir>/clusterReplication。建议配置为容量比较大的
SSD 高速磁盘的路径。
数据节点
clusterReplicationSyncPersistence=false
布尔值,表示是否开启写任务数据的同步持久化,默认为为
false,表示持久化异步进行。注意:开启异步持久化,数据节点宕机可能造成数据丢失;开启同步持久化,会降低主集群的事务效率。
数据节点
从集群
clusterReplicationMasterCtl
和
clusterReplicationMode
为必选参数。
参数名
解释
配置节点
clusterReplicationMasterCtl
指定主集群控制节点的 ip:port。若主集群为高可用集群,则指定为控制节点 raft
组中的任意节点即可。
控制节点
clusterReplicationMode
集群间的异步复制模式。可选值为 master 和
slave,表示主集群和从集群。
数据节点
clusterReplicationExecutionUsername=admin
用于执行集群间异步复制的用户名,默认为
admin。必须确保该用户有事务操作的相关权限,否则异步复制任务会失败。进行回放任务时,用户必须登录。
数据节点
clusterReplicationExecutionPassword=123456
用于执行集群间异步复制的用户密码,默认为 123456。
注:
自
3.00.1
版本起,采用 RSA
加密算法进行身份认证,用户无需指定此参数。
数据节点
clusterReplicationQueue
执行队列的数量,必须是正整数,默认值是数据节点数量的4倍。
控制节点
clusterReplicationWorkerNum
每个数据节点执行任务的工作线程数,默认值是max(workerNum/4,
4)。
数据节点
slaveReplicationDBScope
用于指定回放的数据库范围。可以通过输入数据库路径来设置该范围,多个数据库之间以逗号分隔,例如:dfs://db1,dfs://db2,dfs://db3。若不配置该参数,则回放所有数据库的任务。
控制节点
作业
参考教程:
作业管理
。
DolphinDB
中有两类作业形式,同步作业和异步作业。绝大部分脚本提交的任务都称为同步作业。异步作业主要指批处理作业、定时作业。
同步作业
一个节点能同时执行的同步作业数取决于 worker 数量(使用非 web 客户端时,通过配置项 workerNum 设置)和
web worker 数量(使用 web 客户端时,通过配置项 webWorkerNum 设置)。
配置参数
解释
配置节点
workerNum=4
常规作业的工作线程的数量。默认值是 CPU 的内核数。
单节点、控制节点、代理节点、数据节点、计算节点
webWorkerNum=1
处理HTTP请求的工作线程的数量。默认值是1。
单节点、控制节点、代理节点、数据节点、计算节点
异步作业
批处理作业指使用
submitJob
或
submitJobEx
函数创建的作业任务。在系统中,批处理作业工作线程数的上限是由配置参数 maxBatchJobWorker
设置的。如果批处理作业的数量超过了限制,新的批处理作业将会进入队列等待,队列深度由配置参数 maxCachedBatchJobNum
设置。批处理作业工作线程在闲置超过60秒后会自动销毁。
配置参数
解释
配置节点
maxBatchJobWorker=4
批处理作业的最大工作线程数量。默认值是 workerNum 的值。
单节点、控制节点、代理节点、数据节点、计算节点
maxCachedBatchJobNum=2048
批处理作业队列的最大深度,即队列中最多的批处理作业数量,默认值是 2048。
单节点、控制节点、代理节点、数据节点、计算节点
作业并行度管理
配置参数
解释
配置节点
jobParallelismHardLimit=false
布尔值。
值为 false 时,不限制任务最多使用的 worker 的数量;
值为 true 时,表示将任务最多使用的 worker 数设置为该任务的并行度。
控制节点、代理节点、数据节点
defaultJobParallelism=2
用户提交任务的默认并行度。正整数,默认值:2,值域为:(0, 64]。
注:
该配置项赋值应遵守值域限定,否则会造成 server
启动失败,并在错误日志中显示为:
defaultJobParallelism must be an
integer between 1 and 64.
控制节点
流数据
参考教程:
流数据教程
。
DolphinDB 提供了流数据持久化的功能,其作用主要为:
备份恢复流数据表,避免发布节点宕机,造成流数据表数据丢失。
避免流数据表过大造成内存不足。
支持从任意位置开始重新订阅。
开启持久化只需为发布节点的配置以下选项:
配置参数
解释
配置节点
persistenceDir=/home/DolphinDB/Data/Persistence
共享流数据表的保存路径。如果要将流数据表保存到磁盘上,必须指定
persistenceDir。在集群模式中,需要保证同一机器上的数据节点配置了不同的 persistenceDir。
数据节点
persistenceWorkerNum=1
负责以异步模式保存流数据表的工作线程数。若为高可用流数据表,该参数的默认值为 1;否则默认值为
0。
数据节点
发布节点
发布节点支持配置一些发布数据相关的信息,如发布的消息块大小,消息队列深度。此外还需指定可以连接的订阅节点的连接数上限
maxPubConnections,由于该参数默认为 0,因此若启用流数据必须指定该参数为一个正数。
配置参数
解释
配置节点
maxMsgNumPerBlock=1024
一个消息块中最多的记录条数。默认值为1024。
数据节点
maxPersistenceQueueDepth=10000000
把流数据表保存到磁盘时,消息队列的最大深度(记录条数)。默认值为10,000,000。
数据节点
maxPubQueueDepthPerSite=10000000
发布节点的消息队列的最大深度(记录条数)。默认值为10,000,000。
数据节点
maxPubConnections=0
发布节点可以连接的订阅节点数量上限,默认值为0。只有指定 maxPubConnections
为正整数后,该节点才可作为发布节点。
数据节点
订阅节点
订阅节点订阅流数据表数据。其同发布节点一样,支持指定订阅消息的队列深度以及连接发布节点的数量上限(可以选择不指定,按默认值即可)。此外,订阅节点还可以对流数据进行消费,因此还支持对消息处理的线程数、消息处理时间间隔等进行配置。
配置参数
解释
配置节点
subPort=8000
订阅线程监听的端口号。对于2.00.9之前版本,若要该节点作为订阅节点,必须指定该参数;2.00.9及之后版本无需指定。
数据节点
maxSubConnections=64
该订阅节点可以连接的的发布节点数量上限。默认值为 64。
数据节点
maxSubQueueDepth=10000000
该订阅节点的消息队列的最大深度(记录条数)。
数据节点
subExecutorPooling=false
表示流计算线程是否为 pooling 模式。默认值为
false。注意:使用响应式状态引擎时,必须设置该参数为 false。
数据节点
subExecutors=1
该订阅节点中消息处理线程的数量。只有当启用订阅功能时,该参数才有意义。默认值为1。
数据节点
subThrottle
正整数,单位为毫秒,默认值为
1000。系统检查订阅函数(
subscribeTable
)消息处理情况的时间间隔。若
subscribeTable
的
throttle
参数指定了小于配置参数
subThrottle
的值,则触发消息处理的时间间隔为
subThrottle
。若要设置订阅函数消息处理的时间间隔小于1秒,则需要先修改配置项
subThrottle
。例如:要使
throttle=0.001
秒生效,需设置
subThrottle =1
。
注:
指定
subscribeTable
函数的参数
batchSize
后,该参数设置才会生效。
数据节点
localSubscriberNum=1
设置本地订阅对发布队列中的消息进行分发的线程数量,默认为1。若设置为大于1的数,则会分配相应数量的分发线程,并行分发消息至本地订阅消息处理线程中。
数据节点
若订阅节点消费流数据时发生宕机,重启后可能会无法获知之前消费的进度。DolphinDB
支持将订阅消费数据的偏移量进行持久化,以避免此类情况的发生。
配置参数
解释
配置节点
persistenceOffsetDir=/home/DolphinDB/streamlog
持久化订阅端消费数据偏移量的保存路径,用于保存订阅消费数据的偏移量。若没有指定
persistenceOffsetDir
,但指定了
persistenceDir
,则会保存至
persistenceDir
目录;如果既没指定
persistenceOffsetDir
也没指定
persistenceDir
,会在节点目录下生成
streamlog
目录。
数据节点
高可用
参考教程:
DolphinDB教程:流数据高可用
流数据高可用和集群高可用一样采用 raft
机制,不同的是集群高可用是控制节点的高可用,而流数据高可用为数据节点的高可用。流数据高可用分为发布端、订阅端、流数据计算引擎高可用三种,其高可用的
raft 组都通过 streamingRaftGroups 参数进行配置。
发布端高可用(高可用流数据表):开启发布端高可用后,高可用流数据表自动在 raft
组内的节点进行同步。订阅端只需向 leader 节点订阅高可用流数据即可。若发布端 raft 组 leader
宕机,系统也可以迅速重新选举出新的 leader,供订阅端继续订阅。
订阅端高可用:需在订阅函数
subscribeTable
中设置
reconnect=true,并指定 raftGroup。若订阅端 raft 组 leader 宕机,系统也可以迅速重新选举出新的
leader,继续从发布端订阅数据。
流数据计算引擎高可用:通过配置引擎创建函数的参数 snapshot 和 raftGroup
实现高可用。参考流计算引擎详情页:
流计算引擎
。
注:
启用高可用流数据表,必须开启发布节点的流数据表持久化。
配置参数
解释
配置节点
streamingHAMode=raft
高可用功能采用的协议,目前固定配置为 Raft,表明流数据高可用功能采用了 Raft 协议。
数据节点、计算节点
streamingRaftGroups=2:NODE1:NODE2:NODE3,3:NODE3:NODE4:NODE5
Raft 组信息,包含 ID 和组成 Raft 组的数据节点别名,使用冒号分隔。Raft 组的 ID
必须是大于1的整数,一个 Raft 组至少包含3个不同的数据节点。如果有多个 Raft 组,使用逗号分隔每个 Raft
组的信息。
数据节点、计算节点
streamingHADir=/home/DolphinDB/Data/NODE1/log/streamLog
流数据 Raft 日志文件的存储目录。如果没有指定,默认值为 <HomeDir>/log/streamLog
。每个数据节点应当配置不同的 streamingHADir。
数据节点、计算节点
streamingHAPurgeInterval=300
Raft 日志垃圾回收周期。默认值300,单位为秒。
数据节点、计算节点
streamingRaftGroupAliases
为已配置的 Raft 组指定别名,每个别名对应一个 Raft 组
ID。格式为:alias:ID,多组别名使用逗号分隔。配置别名后,可在高可用组的相关操作中直接使用别名。
数据节点、计算节点
streamingRaftLearners
为已配置的 Raft 组添加 Learner 节点。每个 Raft 组可以包含一个或多个 Learner
节点。Learner 节点可与其他节点(Leader 或 Follower)位于同一集群,也可跨集群部署。
同集群配置格式如:3:NODE1:NODE2
跨集群配置格式:3:NODE1@ClusterName:NODE2@ClusterName
注:需先完成多集群配置才能启用跨集群 Raft Learner。
数据节点、计算节点
Orca
配置参数
解释
配置节点
enableORCA
布尔类型标量,表示是否开启 Orca。默认值为 true 代表开启。
控制节点、数据节点、计算节点
orcaMaxGraphRescheduleAttempts
正整数,表示 ERROR 状态的流图最大的重试次数。默认值为 10。
控制节点
SQL 查询
集群环境下,用户在所连接的节点(协调节点)发起一次分布式表的查询,协调节点首先会根据查询所涉及的分区拆分为子查询语句并 map
到相关的节点。在该过程中,查询的分区数若过多,数据量过大可能造成最后汇总数据时,造成内存溢出。DolphinDB 提供了一系列配置参数来限制查询。
配置参数
解释
配置节点
maxPartitionNumPerQuery=65536
单个查询语句可查找的最大分区数。默认值是65536。
数据节点、计算节点
checkExistingPartitionNumForQuery
开启该配置参数后,
maxPartitionNumPerQuery
将根据从控制节点获取到的实际分区数来估计查询分区限制。若不配置则默认为 false,表示关闭。注意:仅对 DFS
表有效。
数据节点、计算节点
memLimitOfQueryResult
设置单次查询结果占用的内存上限。默认取值为 min(50% * maxMemSize,8G)。若配置该参数,则设置值必须小于
80% * maxMemSize。
数据节点、计算节点
memLimitOfTaskGroupResult
在 map
阶段,单次查询任务被分解为若干个子任务,需要由远端节点执行的子任务批量发送给远端节点。该参数用于设置当前节点发送的批量子查询占用的内存上限。默认取值为
min(20% * maxMemSize,2G)。若配置该参数,则设置值必须小于 50% * maxMemSize。
数据节点、计算节点
memLimitOfTempResult=1
在表连接操作过程中,可能会产生多个临时数据表,该配置项用于设置每个临时数据表允许占用的内存上限,单位是
GB。它的默认值是1,最大值取决于 maxMemSize 的设置值。
若单个临时数据表的内存超过配置值,则会被存放到磁盘的一个临时目录中(由
tempResultsSpillDir
设置)。在表连接完成后,临时文件会被自动回收。
注:
自
3.00.1
版本起,该配置项不再生效。可使用
memLimitOfAllTempResults
。
数据节点、计算节点
tempResultsSpillDir=tempResults
在某些计算过程(例如表连接操作)中,可能会产生临时表用于存储中间结果。该配置项用于指定存储这些中间结果表的临时目录,以避免内存不足或性能问题。默认目录是
<HomeDir>/tempResults。当所有中间结果表的数据量达到
memLimitOfAllTempResults
的设置值时,数据文件会被临时存放到该目录中。计算完成后,由其产生的数据文件会被自动删除。注意:每次 server
启动时,该目录及其下的所有内容会被先删除,然后重新创建。
数据节点、计算节点
memLimitOfAllTempResults
某些分布式查询操作(例如表连接、GROUP BY、CONTEXT BY、PIVOT
BY),可能会产生临时表用于存储查询中产生的结果。该配置项用于设置所有临时表允许占用的内存上限,单位是 GB,默认值是
maxMemSize
* 20%。若所有临时表的内存超过配置值,则会被存放到磁盘的一个临时目录中(由
tempResultsSpillDir
设置)。在查询完成后,临时文件会被自动回收。
数据节点、计算节点
maxQueryExecutionTime=0
单个查询语句的最长执行时间,单位为秒。为整型标量,默认值为 0。当取值小于或等于 0
时,表示不限制执行时间。
数据节点、计算节点
maxJoinTaskRetry
正整数,设置内存紧张时单个 SQL JOIN 子任务的最大重试次数。默认值为
2147483647,表示无限次重试。当子任务重试达到
maxJoinTaskRetry
上限后,包含该子任务的 SQL
查询将被取消。
数据节点、计算节点
创建数据库和数据表时,除了直接指定函数参数进行配置,DolphinDB 还提供了一部分配置文件中的配置项:
流式 SQL
流式 SQL 允许将共享内存表(包括普通内存表、键值内存表、索引内存表)声明为流式 SQL 表,并基于这些表注册 SQL 查询,实现对数据的实时计算。
配置参数
解释
配置节点
streamingSQLExecutors=0
非负整数,执行流式 SQL 的工作线程数。默认值为0。需要设置为大于 0 才能启用流式 SQL 功能。
数据节点、计算节点
maxStreamingSQLQueriesPerTable=64
单个表允许注册的流式 SQL 查询数量上限。默认值为 64。
数据节点、计算节点
数据库与数据表
配置参数
解释
配置节点
enableChunkGranularityConfig=false
DolphinDB 内 chunk 的粒度决定了事务锁的位置。写入一个 chunk 时,系统会对该
chunk 上锁,不允许其他事务写入。2.00.4之前的版本,chunk
的粒度为数据库级别,即数据库的每个分区(partition)为一个
chunk。此时,不允许并发写入同一个分区的不同表。2.00.4版本引入了该配置项,默认为 false,表示 chunk
的粒度为表级别,即每个分区(partition)下的每个表为一个 chunk。此时,允许并发写入同一分区的不同表。设置为 true
时,允许通过 database 的 chunkGranularity 参数指定 chunk 的粒度为数据库级或表级。
数据节点
newValuePartitionPolicy=skip
对于值分区(或复合分区中的值分区)的数据库,若新增数据不属于已有分区,如何处理。它的取值可以是 add,
skip 和 fail。 默认值是
skip,表示如果新增数据中包含分区方案外的数据,系统会保留分区方案中的数据,不保留分区方案外的数据。 注意:从 2.00.10
版本开始,新增了配置项allowMissingPartitions。当 allowMissingPartitions=true(默认值)
时,skip 的行为保持不变。但是当 allowMissingPartitions=false 时,skip
的行为将变成:如果新增数据中包含分区方案外的数据,则系统不会写入任何数据,且抛出异常。 如果
newValuePartitionPolicy=add,表示系统会自动划分新的分区,保留分区方案外的数据。 如果
newValuePartitionPolicy=fail,表示如果新增数据中包含分区方案外的数据,系统不会保留任何数据,且抛出异常。根据大多数场景需求,推荐设置
newValuePartitionPolicy= add。
数据节点
oldChunkVersionRetentionTime=60
设置过期版本 chunk 的保留时长,默认为 60(单位:分钟),上限为 240。执行 SQL
update/upsert/delete 操作时,系统会先生成一个新的 chunk
副本(以”物理表名_tid”命名),并在该副本上进行数据的更新和删除。操作完成后,旧的 chunk 不会被立即删除。系统最多保留 5
个历史 chunk,且每个历史 chunk 的保留时长由此配置参数指定。
数据节点
allowMissingPartitions=true
当新增数据中包含分区方案外的数据时,是否忽略(不保留)分区方案范围外的数据。默认为
true,即保留分区方案中的数据,不保留分区方案外的数据。若设置为 false,则不会写入任何数据,且抛出异常。 注意:对于 VALUE
分区,当 newValuePartitionPolicy 为 add 或 fail
时,是否会忽略分区方案范围外的数据不受该配置项的影响。
数据节点
enableLocalDatabase=true
布尔值,表示是否允许创建本地磁盘数据库。默认值为 true,允许;若设置为
false,则不允许。一旦配置,则对集群内的所有节点都生效。该配置项的配置节点为控制节点。
数据节点
enableInsertStatementForDFSTable
BOOL 类型,表示是否支持使用 insert into 语句插入 DFS 表。默认为
false,即不支持。
数据节点
配置参数
解释
配置节点
enableConcurrentDimensionalTableWrite=false
是否允许维度表并发写入、修改、删除。默认值为 false。若为
true,表示允许维度表并发写入、修改、删除。
数据节点
removeSpecialCharInColumnName=false
是否规范化包含特殊符号的列名,默认值是
false,表示自动产生的数据表的列名允许包含特殊符号,即列名可以以非字母和中文开头,且可以包含下划线之外的符号。如果要跟以前版本兼容,可以将该变量配置为
true。
数据节点
每个持久化的 mvcc 表都有一个 log 文件。对 mvcc 表的增、删、改操作会先写入
log,直至操作次数达到一定数量,才会创建 mvcc 表检测点(checkpoint), 将数据写入 mvcc 表,并清空 log。通过
loadMvccTable
加载 mvcc 表时,需要回放 log
文件。若 log 的数据量过大,可能导致回放耗时过长,甚至出现 OOM。 为解决此类问题,DolphinDB 提供以下配置项,用于控制 log 中的数据量。
配置参数
解释
配置节点
mvccCheckpointThreshold=5000000
设置创建检查点的操作次数阈值。当对 mvcc table
的操作次数达到此值时,会创建检查点。取值范围为:[100,000, 2^31-1],默认值为 5,000,000。增、删、改对应的
mvcc table 的操作次数定义如下:新增(append!, tableInsert, insert
into),更新(update)操作的行数 * 列数 - 删除(delete)操作的行数。
数据节点
TSDB
DolphinDB TSDB 引擎的 redo log 的存储路径可通过以下参数进行配置:
配置参数
解释
配置节点
TSDBRedoLogDir=/TSDBRedo
TSDB 存储引擎重做日志(redo log)的目录。默认值是
/log/TSDBRedo
。
数据节点
其中,TSDBMeta(包含 level file 元数据)与 TSDBRedo 位于同级目录,存放于
<HomeDir>/log 目录。事务数据存放于 <HomeDir>/storage/CHUNKS 目录。 配置方式如下:
使用相对路径, 即不以 '/' 开头;
路径中包含 <ALIAS>, 如
/home/xxx/<ALIAS>/redolog;
每个节点单独配置:node1.TSDBRedoLogDir=/home/xxx/node1/redolog,
node2.TSDBRedoLogDir=/home/xxx/node2/redolog
在集群模式中,需要保证同一机器上的数据节点配置了不同的 TSDBRedoLogDir。
TSDB 引擎在读取或写入数据时,会对相关分区的 symbolBase 数据进行缓存。系统采用 LRU(最近最少使用)策略管理 symbolBase
缓存,提供以下两个配置项,可以根据缓存时间或缓存容量来决定何时逐出未被使用的 symbolBase 数据。其中,未被使用的 symbolBase
是指其对应的分区数据不在 Cache Engine 中,也不在执行的任何事务中。
配置参数
解释
配置节点
TSDBSymbolBaseEvictTime=3600
一个正整数,表示一个 symbolBase可以缓存的最大时长。单位为秒,默认值为 3600。当未被使用的
symbolBase 在缓存中停留时长超过设置值时,系统会将其逐出缓存。
数据节点
TSDBCachedSymbolBaseCapacity
一个大于 0 的数字,表示内存中最多可以缓存的 symbolBase 总容量。单位为 GB,默认值为
maxMemSize
* 5%,最小值为 128MB。当总容量超过设置值时,系统将按照 symbolBase
的时间戳从旧到新的顺序,依次逐出当前未被使用的 symbolBase,直至总容量小于等于设置值。
数据节点
DolphinDB TSDB 引擎的 Cache Engine 的大小可通过以下配置项设置:
配置参数
解释
配置节点
TSDBCacheEngineSize=1
设置 TSDB 存储引擎 Cache Engine 的容量(单位为GB),必须为正数,默认值为1。当
Cache Engine 的内存占用达到设置值的一半时,系统开始对内存中的数据刷盘,数据可继续写入;当 Cache Engine
的内存占用达到设置值时,写入线程将被阻塞。TSDBCacheEngineSize 需合理设置,若设置过小,可能导致 Cache
Engine 频繁刷盘,影响系统性能;若设置过大,由于 Cache Engine 内缓存的数据量很大,但由于未达到 Cache
Engine
的一半大小(且未达到十分钟),因此数据尚未刷盘,此时若发生了机器断电或关机,重启后就需要回放大量事务,导致系统启动过慢。
数据节点
根据 TSDB 引擎的数据模型,数据写入需要经过“排序-压缩-落盘”三个阶段。
排序在 Cache Engine 内部进行,排序的线程数可通过配置项
TSDBAsyncSortingWorkerNum 设置。
落盘时,为提升 TSDB Cache Engine 的刷盘速度,可以配置
TSDBCacheFlushWorkNum 设置工作线程数。
配置参数
解释
TSDBAsyncSortingWorkerNum=1
非负整数,默认值为1,用于指定 TSDB Cache Engine
异步排序的工作线程数。若该参数设置为0,表示写入和排序同步进行。TSDB 写入 Cache Engine 中的数据将会根据
sortColumns 排序。数据写入 Cache Engine
和排序任务可以同步或异步进行,异步可以提升写入性能。注意:异步排序可以提高数据写入性能,但会降低查询性能,因为查询需要等待相关
chunk 的异步排序线程结束才能进行。
数据节点
TSDBCacheTableBufferThreshold=16384
TSDB 引擎缓存数据进行批量排序的阈值。当缓存数据的记录数达到该值后,Cache Engine
将对该部分数据进行排序。
数据节点
TSDBCacheFlushWorkNum
配置 TSDB Cache Engine 刷盘的工作线程数。默认值是 volumes
指定的磁盘卷数。若配置值小于磁盘卷数,则仍取默认值。
数据节点
除了 Cache Engine, TSDB 引擎在内存还维护了到 level file 数据块的索引,索引大小可由配置项
TSDBLevelFileIndexCacheSize 指定。
配置参数
解释
配置节点
TSDBLevelFileIndexCacheSize=5% * maxMemSize
设置 TSDB 存储引擎 level file 元数据内存占用空间上限。单位为
GB,类型为浮点型。默认值为 DolphinDB 系统可使用(由
maxMemSize
设置)的5%,最小值为0.1(GB)。
数据节点
若读取的索引超过 TSDBLevelFileIndexCacheSize,DolphinDB
内部会根据访问时间,将最不常访问的索引进行置换。
配置参数
解释
配置节点
TSDBLevelFileIndexCacheInvalidPercent=0.95
TSDB 引擎 level file 索引缓存淘汰算法的阈值,默认值是 0.95。
数据节点
allowTSDBLevel3Compaction
系统是否启用 level 3 层级的 Level File 的合并:
默认值为 false,此时系统不会主动触发 level 3 层级 Level File 的合并。
当设置为 true 时,对于
keepDuplicates
设置为 FIRST 和 LAST
的表,满足合并条件时将触发 level 3 层级 Level File 的合并;而对于
keepDuplicates
设置为 ALL 的表,其 Level File
不受此参数影响,始终不会合并 level 3 层级。
数据节点
为提高计算资源利用率,降低使用 TSDB 引擎时合并 level file 的耗时,以及尽可能平衡负载,DolphinDB 在 2.00.11 版本提供了用于调整每个
volume 下可处理合并任务的线程数量(worker)的配置项
compactWorkerNumPerVolume
。
配置参数
解释
配置节点
compactWorkerNumPerVolume
一个 volume 下用于合并 level file 的 worker 数量,默认值是
1。
数据节点
为了提升向量索引的查询速度,TSDB 引擎维护了向量索引缓存,大小可通过配置项 TSDBVectorIndexCacheSize
设置。系统采用 LRU(最近最少使用)策略管理缓存。
配置参数
解释
配置节点
TSDBVectorIndexCacheSize=0
非负浮点数,指定 TSDB 向量索引的缓存大小,单位为 GB。默认值为 0,表示关闭缓存;当配置项大于 0
时,此功能将启用。
数据节点
OLAP
DolphinDB OLAP 引擎的 redo log 的存储路径可通过以下参数进行配置:
配置参数
解释
配置节点
redoLogDir=/redoLog
OLAP 存储引擎重做日志(redo log)的目录。默认值是
/log/redoLog
。在集群模式中,需要保证同一机器上的数据节点配置了不同的
redoLogDir。
数据节点
DolphinDB OLAP 引擎的 Cache Engine 的大小可通过以下配置项设置:
配置参数
解释
配置节点
OLAPCacheEngineSize=0 Alias:
chunkCacheEngineMemSize
指定 OLAP 存储引擎 Cache Engine 的容量(单位为 GB)。 Cache Engine
开启后,写入数据时,系统会先把数据写入缓存,当缓存中的数据量达到
OLAPCacheEngineSize
的30%时,才写入磁盘。默认值是0,即不开启 Cache
Engine。开启 Cache Engine 的同时,必须设置 dataSync=1。
数据节点
PKEY
配置参数
解释
配置节点
enablePKEYEngine
表示是否开启 PKEY 引擎。默认值为 true。
数据节点
PKEYMetaLogDir
元数据日志的存储目录。默认值为
<ALIAS>/log/PKEYMeta
。
数据节点
PKEYRedoLogDir
重做日志(redo log)的存储目录。默认值为
<ALIAS>/log/PKEYRedo
。
数据节点
PKEYCacheEngineSize
设置 PKEY 存储引擎 cache engine 的容量(单位为GB),必须为正数,默认值为1。如果写入压力太大,系统
cache engine 内存占用可能会达到该参数值的2倍大小。因为若当前申请的大小为 PKEYCacheEngineSize
的内存写满后,该内存中的数据开始刷盘,此时若有数据继续写入,系统会再分配一块内存来接收新数据。需要注意的是,若数据刷盘不及时,可能导致新分配的内存也达到
PKEYCacheEngineSize 大小,此时写入线程会被阻塞。PKEYCacheEngineSize
需合理设置,若设置过小,可能导致 cache engine 频繁刷盘,影响系统性能;若设置过大,由于 cache engine
内缓存的数据量很大,但由于未达到 cache engine
的大小(且未达到十分钟),因此数据尚未刷盘,此时若发生了机器断电或关机,重启后就需要回放大量事务,导致系统启动过慢。
数据节点
PKEYBlockCacheSize
设置 PKEY 存储引擎的block cache容量,单位为GB,必须为正数,默认值为1。
数据节点
PKEYDeleteBitmapUpdateThreshold
设置PKEY存储引擎的delete bitmap的更新阈值,单位为MB,必须为正数,默认值为100。
为了在后台批量更新 delete bitmap,需要在刷盘时暂存主键和 CID 列。当暂存缓冲区大小到达阈值时,将触发一次
delete bitmap 的更新,并清空该缓冲区。
该参数需合理设置。若设置过小,将导致 delete bitmap 频繁更新,占用磁盘带宽,进而影响查询、cache engine
刷盘及后台 compaction
任务。若设置过大,则查询的去重开销增加,查询时间延长。过大的设置还会导致重启后的恢复过程变慢。
数据节点
PKEYStashedPrimaryKeyBufferSize
设置 PKEY 存储引擎的暂存主键缓冲区的容量,单位为 MB,必须为正数,默认值为
1024。该参数在系统面对高写入压力时,可防止暂存缓冲区无限增长导致 OOM
的问题。在高写入压力下,缓冲区大小可能会达到该参数的两倍。
如果系统写入压力过大,会导致 cache engine 频繁刷盘并暂存主键和 CID 列。而delete bitmap
的更新速度较慢,因此缓冲区会持续增长。为防止暂存缓冲区大小无限增长,系统会按照该参数来暂停刷盘。
数据节点
PKEYBackgroundWorkerNumPerVolume
配置每个 volume 的 PKEY 后台工作线程数,后台工作包括 compaction 和 delete bitmap
更新。默认值和最小值均为1。(后台总工作线程数为 volumes 数量乘以该参数值,若未手动指定 volumes
参数,则volumes数量为1)
数据节点
PKEYCacheFlushWorkerNumPerVolume
配置每个 volume 的 PKEY Cache Engine 刷盘工作线程数,默认值和最小值均为1。(PKEY
刷盘总工作线程数为 volumes 数量乘以该参数值,若未手动指定 volumes 参数,则 volumes 数量为1)
数据节点
IMOLTP
配置参数
解释
配置节点
enableIMOLTPEngine
bool 类型。表示是否开启 OLTP 引擎。默认为 false。
数据节点
enableIMOLTPRedo
bool 类型。表示是否开启预写日志(WAL, Write-Ahead-Log),开启之后才能保证数据不会丢失。默认为
true。
数据节点
IMOLTPRedoFilePath
string 类型。表示 redo 文件(即 WAL
文件)的文件路径,可以设置为绝对路径或相对路径。当设置为相对路径时,其相对性以
home
目录下的
IMOLTP
目录作为参照。默认为 home
目录下的
IMOLTP/im_oltp.redo
。
注:
设置该参数时,必须确保路径实际存在且唯一,否则将导致 OLTP
启动失败。
数据节点
IMOLTPSyncOnTxnCommit
bool 类型。表示当 WAL 开启时,是否在事务对数据修改前预先写日志到持久化存储,默认为 false。该参数及
enableIMOLTPRedo 均设置为 true
后,事务会在修改数据前写日志至磁盘存储。该配置项有助于在系统崩溃后,通过重新启动系统并回放 redo
文件里的日志,从而将数据库恢复到崩溃前的状态。
注:
如果该配置项保持默认值,事务在 commit
成功后预先写的日志存储于系统缓存而非磁盘存储,因此无助于断电后的数据恢复。
数据节点
enableIMOLTPCheckpoint
bool 类型。表示是否开启数据检查点机制(checkpoint),即将内存中的数据定期写入磁盘,以确保数据持久化和可靠性。默认为
true。
数据节点
IMOLTPCheckpointFilePath
string 类型。表示 checkpoint
文件的路径(文件路径而非文件所在目录),可以设置为绝对路径或相对路径。当设置为相对路径时,其相对性以
home
目录下的
IMOLTP
目录作为参照。默认为 home
目录下的
IMOLTP/im_oltp.ckp
。
注:
设置该参数时,必须确保路径实际存在且唯一,否则将导致 OLTP
启动失败。
数据节点
IMOLTPCheckpointThreshold
long 类型。单位为 MiB。用于将 redo 文件中 log 的大小作为触发 checkpoint 机制的条件。默认为 100
MiB。
数据节点
IMOLTPCheckpointInterval
long 类型。单位为秒。用于设置强制执行 checkpoint 的周期。默认为 60 秒。
数据节点
TextDB
在 TextDB 中,中文分词器必须加载相应的字典才能正常运行。字典目录
dict
所在目录可通过配置项 jiebaDictDir
指定。如果没有指定,或指定的目录不存在,则会依次在
HOME_DIR
WORKING_DIR
EXEC_DIR
下寻找名为
dict
的目录。
dict
目录的预期结构如下,如果找到的目录不符合该结构,同样视为未找到
dict
目录。
dict
├── hmm_model.utf8
├── idf.utf8
├── jieba.dict.utf8
├── stop_words.utf8
└── user.dict.utf8
配置参数
解释
配置节点
jiebaDictDir
string 类型。表示字典文件的存放目录。
数据节点
分级存储
详情参考:
TieredStorage
要开启分级存储,首先需要配置冷数据存储的磁盘路径。
配置参数
解释
配置节点
coldVolumes=
[file://home/mypath/hdd](file://home/mypath/hdd),
s3://bucket1/data
用于配置冷数据的存储目录。通过函数
moveHotDataToColdVolume
和
setRetentionPolicy
开启分级存储后,过期的冷数据将从 volumes 迁移至
coldVolumes。
数据节点
若需要将过期数据存储在云端,DolphinDB 提供了 AWS S3 的相关配置:
配置参数
解释
配置节点
s3AccessKeyId
S3 访问账户的 id。
数据节点
s3SecretAccessKey
S3 访问账户的密钥。
数据节点
s3Region
S3 存储桶所在的区域。
数据节点
s3Endpoint
用于访问 S3 的端点。
数据节点
注:
配置了 AWS S3 的相关配置后,须配置 preloadModules=plugins::awss3,确保 server
顺利初始化。
preloadModules
参数说明见
单节点模式
。
s3Endpoint
不能包含
http://
和
https://
。
在配置
s3Endpoint
时,支持在 endpoint 后再输入一个 BOOL 值,以表示通过 HTTP 或者 HTTPS 协议访问
endpoint,其默认值为 false,表示以 HTTPS 协议访问。例如
s3Endpoint=192.168.1.160:980,true
,表示以 HTTP 协议访问
192.168.1.160:980。
s3Region
默认为 us-west-1,如果配置的
s3Endpoint
属于该区域,则可以不配置
s3Region
,否则该配置项不可省略。
单点登录
OAuth 是单点登录(SSO)的一种实现方式。目前 DolphinDB 已支持其三种鉴权方式:Authentication Code(授权码模式,支持
Web)、Implicit(隐式授权模式,支持 Web)、Client Credentials(客户端凭证模式,支持 API)。在启用 OAuth
单点登录时,用户须先在 DolphinDB server 中指定相关配置项以获取权限,然后在 DolphinDB 的 Web
页面中进行具体使用。如下为相关配置参数的介绍。
配置参数
解释
配置节点
oauth
布尔值,是否在 Web 页面启用 OAuth 单点登录功能。默认值为 0,表示不启用。
单节点、控制节点、数据节点、计算节点
oauthWebType
可选参数,字符串类型,用来指定 Web 使用的 OAuth 类型。 可选值为:'authorization code'(默认),
'implicit' 。
单节点、控制节点、数据节点、计算节点
oauthAuthUri
字符串类型,用来指定授权服务器的 URI。
单节点、控制节点、数据节点、计算节点
oauthClientId
字符串类型,用来指定客户端的 ID。
单节点、控制节点、数据节点、计算节点
oauthClientSecret
字符串类型,用来指定客户端的密码。若
oauthWebType
为 authorization code
时则该参数为必填。
单节点、控制节点、数据节点、计算节点
oauthRedirectUri
可选参数,字符串类型,用来指定 Web 的地址。注意:若配置该参数,则须和第三方 callback URL
保持一致;若不配置,则将默认按第三方 callback 进行跳转。
单节点、控制节点、数据节点、计算节点
oauthTokenUri
可选参数,字符串类型,用来指定 token 接口的地址。
若
oauthWebType
为 authorization code 时则必填该参数。
若
oauthWebType
为 implicit 时则不填该参数。
单节点、控制节点、数据节点、计算节点
oauthTokenRequestMethod
可选参数,字符串类型,用来指定获取 token 接口请求方法。可选值为:'GET', 'POST'(默认)。
单节点、控制节点、数据节点、计算节点
oauthUserUri
字符串类型,用来指定获取用户名的接口地址。如'
x.com
'。
单节点、控制节点、数据节点、计算节点
oauthUserRequestMethod
可选参数,字符串类型,用来指定获取用户名的接口请求方法。可选值为:'GET'(默认), 'POST'。
单节点、控制节点、数据节点、计算节点
oauthUserField
字符串类型,用来指定获取用户名的接口响应字段。注意:若配置与返回不一致会导致报错。
单节点、控制节点、数据节点、计算节点
oauthAllowPasswordLoginNodes
字符串,用于指定允许使用账号密码登录的节点别名。多个节点别名间使用英文逗号分隔;支持设置为 "all"
表示集群中全部节点。
单节点、控制节点、数据节点、计算节点
注意:配置参数如
oauthAuthUri
,
oauthRedirectUri
,
oauthTokenUri
,
oauthUserUri
等,仅支持传入有引号包裹的字符串;含有
&
,
;
等 Shell 特殊符号的值需要用引号包裹整个输入值。
性能监控与资源跟踪
通过下述参数开启系统性能监控后,可以通过
getCompletedQueries
,
getRunningQueries
函数,获取查询的性能和状态信息;或者通过
getSystemCpuUsage
,
getSystemLoadAvg
获取系统的性能信息。
配置参数
解释
配置节点
perfMonitoring=1
启用性能监控。在单实例中,默认值是 false;在集群中,默认值是 true。
单节点、控制节点
DolphinDB 提供了能够追踪数据节点或计算节点上用户级别的资源使用情况和查询分布式表操作的功能。此功能包括获取 CPU 和 内存使用量、记录用户对分布式表发起的
SQL 查询的次数、读取表的行数及数据量大小等能。配置这些功能通常涉及一些参数,用户可以根据具体的需求对这些配置项进行设置。
配置参数
解释
配置节点
resourceSamplingInterval=-1
整数,控制是否开启资源跟踪功能及设置开启后采样的时间间隔,单位为秒。默认值为 -1,表示不开启资源跟踪功能。
数据节点、计算节点
resourceSamplingMaxLogSize=1024
正整数,表示资源跟踪日志切割阈值。默认值为1024,单位为
MB。开启资源跟踪功能后,采样的信息将写入文件中。为防止文件大小持续增长,DolphinDB
采用日志滚动策略,一旦文件大小达到阈值就会生成滚动日志文件。文件名以时间戳作为前缀。例如20231101162302_access.log,表示
2023.11.01T16:23:02 拆分出来的滚动日志。
数据节点、计算节点
resourceSamplingLogRetentionTime=-1
整数,指定资源跟踪日志的最长保留时间。单位为天,默认值是-1,表示不回收。
数据节点、计算节点
resourceSamplingLogDir
字符串,表示资源跟踪日志的存储路径,默认为 <HomeDir>/resource。
数据节点、计算节点
注:
2.00.13/3.00.1 之前版本、1.30.xx 系列版本:数据访问量的依据是存储引擎返回的表的大小。但这会造成结果不准确。比如在 OLAP
分布式表上查询行数。存储引擎会从元数据里获取行数,然后构造一个相同行数的表并返回给计算层。此时在计算层记录表的行数会是整个表的行数,但实际上存储引擎并没有真正地扫描文件。
3.00.1
及之后版本:数据访问量的依据是存储引擎中真实扫描的数据量。其中:
OLAP 引擎:从分区文件、分区缓存、分区对象本身中获取实际行数。
TSDB 引擎:从数据块、Cache Engine 和 Block Cache 中获取实际行数。注意:TSDB 引擎支持
KEEP_LAST 和 KEEP_FIRST,支持在查询时对 sortColumns 相同的行做去重。比如一次查询访问多个
LevelFile 后,经过去重会返回一行数据,但实际上可能扫描了多个 block。该情况下,资源跟踪会记录去重前的、多个 block
的行数。
PKEY 引擎:从数据块、Cache Engine 和 Block Cache
中获取实际行数。注意:PKEY 引擎能保证查询结果的主键唯一性,支持在查询时对 primaryKeys
相同的行做去重。比如一次查询访问多个 LevelFile 后,经过去重会返回一行数据,但实际上可能扫描了多个
block。该情况下,资源跟踪会记录去重前的、多个 block 的行数。
兼容性配置
配置参数
解释
配置节点
processVectorFunctionOverTupleByRow=true
布尔值,用于控制向量函数在处理元组(所有元素是标量或等长向量)或字典时的应用方式。
true(默认):按行调用向量函数。
false:按列整体调用向量函数。
数据节点
3.00.3
以下版本,内存表中由元素类型相同的元组(ANY)构成的列,会被系统自动转换为列式元组(ColumnarTuple)。转换后该列仅允许插入相同类型的数据,否则会报错。自
3.00.3
起,系统默认不再进行此类自动转换,保留为普通 ANY 类型列,可插入不同类型的数据。为兼容旧行为,引入了配置项
autoConversionToColumnarTuple
。如已有代码因该变更出现兼容性问题,可选择以下任一方式处理:
使用
setColumnarTuple!
将原始列显式转换为 Columnar Tuple(推荐);
将
autoConversionToColumnarTuple
设置为 true,启用自动转换。
配置参数
解释
配置节点
autoConversionToColumnarTuple=false
布尔值,用于控制在构造内存表时是否自动将 tuple
列转换为列数元组(ColumnarTuple)。默认值为 false,表示不自动转换,保留为原始的 ANY 类型。
数据节点
DECIMAL 与其他类型之间的转换规则发生变化,包括以下场景:
浮点数字符串解析为 DECIMAL 类型(例如 loadText 等函数加载数据文件)
浮点数转换为 DECIMAL 类型
DECIMAL 类型转换为整型
高精度的 DECIMAL 类型数转换为低精度 DECIMAL 类型
2.00.10 版本,浮点数字符串解析为 DECIMAL 类型的情况,采用的舍入模式由直接截断修改为四舍五入;
其他场景在 2.00.12 版本之前一直采用直接截断的方式。
2.00.12 版本提供了配置项 decimalRoundingMode 统一设置舍入模式。
配置参数
解释
配置节点
decimalRoundingMode
表示在以上场景采取的舍入模式。默认为 round,表示四舍五入;如果设置为 trunc,则直接截断。
数据节点
在采用值分区,且以类型为 STRING 或 SYMBOL 的列作为分区列的分布式数据表中,若分区列写入的字符包含 ':' 和 '.',
2.00.11
之前的版本会忽略 ':'
和 '.',而
2.00.11
版本提供了配置项
ignoreSpecialCharacterInPartitionId
用于设置是否忽略它们。
配置参数
解释
配置节点
ignoreSpecialCharacterInPartitionId=true
布尔值,设置创建分区路径时是否忽略分区列中的字符 ':' 和 '.'。默认为 true,即忽略。若设置为
false,则不会忽略。例如:当需要向分区列写入 ".a:bc." 和 "abc" 时,若设置
ignoreSpecialCharacterInPartitionId
=true,则在创建分区路径时会忽略
'.a:bc.' 中的 ':' 和 '.',导致两个不同分区的数据拥有相同的分区路径 'abc'。而如果设置
ignoreSpecialCharacterInPartitionId
=false,则在分区路径中不会忽略
".a:bc." 中的 ':' 和 '.' ,而会写为 ".a:bc.",从而有效避免上述问题。
数据节点
keepTupleInRowFunction
表示 row 系列的向量函数和参数
func
是向量函数的
byRow
函数,在输入是列式元组时,返回的结果是否是列式元组。默认值为true,此时返回结果是列式元组;若设为
false,则返回结果为数组向量。
数据节点
2.00.11
版本新增配置项
movingIndexedObjectByIndexedLabel
:
配置参数
解释
配置节点
movingIndexedObjectByIndexedLabel
部分m系列函数在作用于索引矩阵和索引向量时,按照索引列操作还是按照行操作。默认值为true,表示按照索引列操作;当设置为false时,按照行操作。此配置参数影响的函数包括:
move
,
mcovar
,
mcorr
,
mbeta
,
mwavg
,
mwsum
,
mpercentile
,
mrank
,
mcount
,
mfirst
,
mlast
,
mavg
,
mmed
,
mprod
,
msum
,
msum2
,
mstd
,
mvar
,
mstdp
,
mvarp
,
mskew
,
mkurtosis
,
mmin
,
mmax
数据节点
2.00.5
以下版本,NULL 值被当作最小值处理。及以上版本可通过配置项
nullAsMinValueForComparison
改变这种行为:
配置参数
解释
配置节点
nullAsMinValueForComparison=true
NULL 值在比较运算符操作中是否当作对应数据类型的最小值处理,默认值为 true。若设置为
false,则 NULL 元素对应的结果为 NULL。
数据节点
2.00.9.4
以下版本,
or
函数不忽略操作符中的 NULL,所以始终返回 NULL。对于
2.00.9.4
及以上版本,由配置项
logicOrIgnoreNull
控制是否忽略 NULL;若需要保持
or
函数的这种行为,则应该设置
logicOrIgnoreNull=false。
配置参数
解释
配置节点
logicOrIgnoreNull=true
设置 or 函数在一个操作数包含 NULL 时是否忽略 NULL。设置为
true(默认值)时:当另一个操作数非零时,返回 true; 当另一个操作数为零时,返回 false。当另一个操作数为 NULL
时,返回 NULL。设置为 false 时:无论另一个操作数的值如何,始终返回 NULL。
数据节点
2.00.10
以前版本,在执行
JOIN 操作时,连接列中的 NULL 与 NULL 被视为匹配成功,这不符合 ANSI SQL 语义;为提高对 ANSI SQL 的兼容性:
自
2.00.10
版本起,在
DolphinDB 中执行 JOIN 操作时,连接列中的 NULL 与 NULL 视为匹配失败。
为进一步提高 NULL 值匹配的灵活性,自 2.00.12 版本起,增加以下配置项,用于设置 NULL 值的匹配逻辑。
配置参数
解释
配置节点
enableNullSafeJoin
设置执行 JOIN 操作时,连接列中的 NULL 与 NULL 是否可以匹配成功。
true:匹配成功,得到 NULL 的结果。
false(默认值):匹配不成功。
数据节点
配置参数
解释
配置节点
removeSpecialCharInColumnName=false
是否规范化包含特殊符号的列名,默认值是
false,表示自动产生的数据表的列名允许包含特殊符号,即列名可以以非字母和中文开头,且可以包含下划线之外的符号。如果要跟以前版本兼容,可以将该变量配置为
true。
数据节点
appendTupleAsAWhole=true
通过
append!
追加或通过
join!
合并元组,是否将元组作为一个整体。默认值为 true,表示将元组作为整体追加或合并。设为 false
时,将元组的每个元素逐一追加或合并。
数据节点
2.00.10.4 以下版本,系统默认将小数常量解析为 DOUBLE 类型。对于 2.00.10.4 及以上版本,可通过配置项
parseDecimalAsFloatingNumber
设置系统解析小数常量类型的默认行为。
配置参数
解释
配置节点
parseDecimalAsFloatingNumber=true
是否将小数常量解析为浮点数的 DOUBLE 类型,默认值为 true。若设置为
false,系统则会将小数常量解析为定点数的 DECIMAL64 类型。
数据节点
FILE:references/doc_2354.md
# scs
**URL**: https://docs.dolphindb.cn/zh/funcs/s/scs.html
**来源**: DolphinDB 官方文档
---
scs
语法
scs(f, [P], [A], [b], [Aeq], [beq], [lb], [ub], [x0], [c], [eps],
[alpha])
详情
求解目标函数在约束条件下的最优解。具体模型如下:
参数
注:
以下参数中,除
lb
,
ub
可以为空外,其它参数都不可包含空值。
f
二次规划中的一次项系数向量。必须和 x0 长度相同。
P
一个矩阵,通过将二次项系数矩阵的对角线元素乘以2得到。例如:所有二次项组成上三角矩阵
将对角线上的系数乘以2,其它系数不变,得到的矩阵就是
P
。
A
线性不等式约束的系数矩阵。列数必须和 x 的长度相同。
b
线性不等式约束的右端向量。
Aeq
线性等式约束的系数矩阵。列数必须和 x 的长度相同。
beq
线性等式约束的右端向量。
lb
变量的下界。可以是标量或与 x 等长的向量。注意:当
lb
为空时,表示 x 无下界约束。
ub
变量的上界。可以是标量或与 x 等长的向量。注意:当
lb
为空时,表示 x 无上界约束。
若
lb
或
ub
是标量,则所有变量都受同一个下界或上界约束。若
lb
或
ub
为NULL,表示 x
无相应的下界或上界约束。
若
lb
或
ub
是向量,则 x 中的元素受
lb
或
ub
中相应位置的元素约束。若向量
lb
或
ub
中某元素为 NULL,表示此位置的 x 元素无相应的下界或上界约束
x0
向量绝对值不等式约束的系数向量。必须和 f 长度相同。
c
一个非负数字,表示绝对值不等式约束的右侧常量系数。
eps
正浮点数,表示求解的精度。默认值为1e-6,范围为 [1e-4,
1e-9]。通过减小该参数值以获得更高精度的解。如果该参数设置值超过规定范围,则会自动调整为默认值。
alpha
正浮点数,表示松弛参数。默认值为1.5,范围为 (0, 2)。通过增加
alpha
的值来加快求解速度。如果该参数设置值超过规定范围,则会自动调整为默认值。
返回值
具有两个元素的元组。第一个元素是目标函数的最小值,第二个元素是目标函数取最小值时,x 的取值。
例子
求 x, y 满足以下约束条件时,目标函数 x
2
+ y
2
的最小值
// 目标函数中没有一次项,所以系数都为0,f取值如下
f = [0, 0];
// 仅存在二次项x^2 和 y^2,系数为均为1,则 P 的取值为
P = [2, 0, 0, 2]$2:2;
// 绝对值不等式的约束系数和右端向量
x0 = [0.4, 0.6];
c = 0.5;
// 线性等式为 x+y=1,因此 Aeq 和 beq 的取值为
Aeq = [1, 1]$1:2;
beq = [1];
// 由 x,y>0 得到变量的下界
lb = [0, 0];
re = scs(f=f,P=P,Aeq=Aeq,beq=beq,lb=lb,x0=x0,c=c);
re[1]
// output
[0.500000043984074,0.499999955746447]
相关函数:
linprog
,
quadprog
FILE:references/doc_2358.md
# loc
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loc.html
**来源**: DolphinDB 官方文档
---
loc
语法
loc(obj, rowFilter, [colFilter], [view=false])
详情
通过标签或布尔向量获取矩阵指定的行和列的元素,返回一个原矩阵的副本/视图。
参数
obj
矩阵对象,可以是普通矩阵、索引序列以及索引矩阵。
rowFilter
/
colFilter
可以为以下类型:
布尔向量,只有为 true 的行/列可以被保留。其长度必须和矩阵的行数/列数相等。
与行/列标签【类型兼容】的标量,向量或数据对(表示范围,包含左、右边界)。
注:
如果 rowFilter/colFilter 为数据对,则 obj
必须是索引序列或索引矩阵。
类型兼容:INT, SHORT, LONG, CHAR 互相兼容, FLOAT 和 DOUBLE
类型互相兼容,SYMBOL 和 STRING 类型互相兼容。
view
布尔值,默认值是 false,表示生成一个原矩阵的副本(深拷贝)。若为
true,只会生成原矩阵的一个视图(浅拷贝),若原数据发生改变,视图的数据也会相应变化。
返回值
一个原矩阵的副本/视图。
例子
m=rand(12, 3:4)
m;
col1
col2
col3
col4
3
10
6
5
4
11
6
0
7
2
1
8
a = m.loc(colFilter=[true, true, true, false], view=true)
b = m.loc(colFilter=[true, true, true, false], view=false)
a;
col1
col2
col3
3
10
6
4
11
6
7
2
1
b;
col1
col2
col3
3
10
6
4
11
6
7
2
1
// 若原矩阵发生变化则视图也会改变,副本则不发生变化
m[0,0] = -1
a;
col1
col2
col3
-1
10
6
4
11
6
7
2
1
b;
col1
col2
col3
3
10
6
4
11
6
7
2
1
m = rand(48, 6:8)
m;
col1
col2
col3
col4
col5
col6
col7
col8
27
31
47
21
12
43
22
11
3
20
13
37
3
46
27
27
13
5
14
11
26
42
4
18
45
9
31
33
12
19
42
17
2
19
30
25
36
27
21
6
9
36
15
10
29
37
31
42
// 通过布尔值过滤
m.loc(rowFilter=[true, true, false, false, true, false])
col1
col2
col3
col4
col5
col6
col7
col8
27
31
47
21
12
43
22
11
3
20
13
37
3
46
27
27
2
19
30
25
36
27
21
6
m.loc(colFilter=[true, true, false, false, true, false, false, true])
col1
col2
col3
col4
27
31
12
11
3
20
3
27
13
5
26
18
45
9
12
17
2
19
36
6
9
36
29
42
// 通过标签过滤
m.rename!(`A`A`B`A`B`B, 2022.01.01 + 0..7)
m;
label
2022.01.01
2022.01.02
2022.01.03
2022.01.04
2022.01.05
2022.01.06
2022.01.07
2022.01.08
A
27
31
47
21
12
43
22
11
A
3
20
13
37
3
46
27
27
B
13
5
14
11
26
42
4
18
A
45
9
31
33
12
19
42
17
B
2
19
30
25
36
27
21
6
B
9
36
15
10
29
37
31
42
m.loc(rowFilter=`A);
label
2022.01.01
2022.01.02
2022.01.03
2022.01.04
2022.01.05
2022.01.06
2022.01.07
2022.01.08
A
27
31
47
21
12
43
22
11
A
3
20
13
37
3
46
27
27
A
45
9
31
33
12
19
42
17
m.loc(colFilter=2022.01.02);
label
2022.01.02
A
31
A
20
B
5
A
9
B
19
B
36
m.loc(rowFilter=`B, colFilter=2022.01.03)
label
2022.01.03
B
14
B
30
B
15
若
rowFilter
/
colFilter
是数据对,则 obj 必须是索引矩阵,可通过函数
setIndexedMatrix!
将一个带标签的矩阵设置为索引矩阵。
m = rand(30, 5:6).rename!(1..5, 2022.01.01 + 0..5)
m.setIndexedMatrix!()
m;
label
2022.01.01
2022.01.02
2022.01.03
2022.01.04
2022.01.05
2022.01.06
1
5
27
26
18
29
3
2
11
12
21
15
3
3
3
1
23
29
17
7
18
4
1
6
12
27
23
23
5
15
7
3
19
4
8
m.loc(rowFilter=2:4, colFilter=2022.01.03:2022.01.06)
label
2022.01.03
2022.01.04
2022.01.05
2022.01.06
2
21
15
3
3
3
29
17
7
18
4
12
27
23
23
相关函数:
at
FILE:references/doc_2367.md
# valueAtRisk
**URL**: https://docs.dolphindb.cn/zh/funcs/v/var_0.html
**来源**: DolphinDB 官方文档
---
valueAtRisk
语法
valueAtRisk(returns, method,
[confidenceLevel=0.95])
详情
风控指标(Value at Risk),用于量化在给定的置信水平(例如 95% 或 99%)和特定时间范围内金融资产可能遭受的最大损失。该函数将返回最低收益率的绝对值,为
DOUBLE 类型。
参数
returns
数值型向量,表示收益率序列。注意,表示收益率的每个元素都应大于 -1 且不能为空。
method
字符串类型,表示计算 VaR 的方法,可选值为:
'normal' 正态参数法。
'logNormal' 对数正态参数法。
'historical' 历史模拟法。
'monteCarlo' 蒙特卡洛模拟法,使用正态分布进行模拟。
confidenceLevel
数值型标量,表示置信水平,合法值域为(0,1),默认值为 0.95。
返回值
DOUBLE 类型标量。
例子
本例中给定一个假设的收益率序列,通过历史模拟法,计算置信水平为 0.9 的风控指标。
returns = [0.0, -0.0023816107391389394, -0.0028351258634076834, 0.00789570628538656, 0.0022056267475062397, -0.004515475812603498, 0.0031189325339843646, 0.010774648811452205, 0.0030816164453268957, 0.02172541561228001, 0.011106185767699728, -0.005369098699244845, -0.0096490689793588, 0.0025152212699484314, 0.017822140037111668, -0.02837536728283525, 0.018373545076599204, -0.0026401111537113003, 0.019524374522517898, -0.010800546314337627, 0.014073362622486131, -0.00398277532382243, 0.008398647051501285, 0.0024056749358184904, 0.007093080335863512, -0.005332549248384733, -0.008471915938733665, -0.0038788486165083342, -0.01308504169086584, 0.00350496242864784, 0.009036118926745962, 0.0013358223875250545, 0.0036426642608267563, 0.003974568474545581, -0.003944066366522669, -0.011969668605022311, 0.015116930499066374, 0.006931427295653037, -0.0032650627551519267, 0.003407880132851648]
valueAtRisk(returns, 'historical', 0.9);
//output:0.009764216712
相关函数
:
condValueAtRisk
FILE:references/doc_2382.md
# getJobStat
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getJobStat.html
**来源**: DolphinDB 官方文档
---
getJobStat
语法
getJobStat()
详情
监控正在执行或者队列中的作业和任务的数量。
参数
无
返回值
返回一个字典,其 key 的含义为:
参数
含义
queuedLocalTasks
等待执行的本地任务数。
runningLocalTasks
正在执行的本地任务数。
queuedJobs
队列中的作业数。
runningJobs
正在执行的作业数。
queuedRemoteTasks
发送到远程执行的任务数。
例子
getJobStat();
返回:
queuedLocalTasks->0
runnningJobs->0
queuedRemoteTasks->0
queuedJobs->0
runningLocalTasks->0
FILE:references/doc_2383.md
# convertEncode
**URL**: https://docs.dolphindb.cn/zh/funcs/c/convertEncode.html
**来源**: DolphinDB 官方文档
---
convertEncode
语法
convertEncode(str, srcEncode, destEncode)
详情
转换字符串编码。DolphinDB 对编码名称的大小写敏感,所有编码名称必须用小写表示。
Window 版本目前仅支持 gbk 和 utf-8 两种编码的相互转换。Linux 版本支持任意两种编码之间的转换。
参数
str
是一个字符串标量/向量,值为字符串类型的字典,或表。
srcEncode
是一个字符串,表示
str
原来的编码名称。
destEncode
是一个字符串,表示
str
的目标编码名称。
返回值
STRING 类型标量/向量/字典/表。
例子
convertEncode("高性能分布式时序数据库","utf-8","gbk");
// output: 高性能分布式时序数据库
convertEncode(["hello","DolphinDB"],"gbk","utf-8");
// output: ["hello","DolphinDB"]
convertEncode
可以对字典中的符串类型的值进行转换。
x=1 2 3
y= `C1`C2`D1
d=dict(x,y)
convertEncode(d, "UTF-8", "GBK")
// output:
1: C1
2: C2
3: D1
*/
convertEncode
函数会自动识别并转换表中所有字符串类型的列,其他数据类型的列将被自动忽略。
t=table(["t1", "t1", "t2", "t3"] as type, [11, 11.5, 10, 14] as price)
convertEncode(t, "UTF-8", "GBK")
type
price
t1
11
t1
11.5
t2
10
t3
14
相关函数:
fromUTF8
,
toUTF8
FILE:references/doc_2397.md
# group by
**URL**: https://docs.dolphindb.cn/zh/progr/sql/groupby.html
**来源**: DolphinDB 官方文档
---
group by
关键字会自动加入到结果集中,用户可以不在select语句中指定该列。生成的表的顺序为:group by中select未指定的字段排列在前,select指定的字段排列在后。
例子
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t1 = table(timestamp, sym, qty, price);
t1;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.2
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
select count(sym) as counts from t1 group by sym;
sym
counts
C
4
MS
3
IBM
2
和 top 子句一起使用:
select top 2:3 count(sym) as counts from t1 group by sym;
sym
counts
IBM
2
select max(price), sym from t1 group by sym, minute(timestamp)
minute_timestamp
max_price
sym
09:34m
50.76
C
09:36m
30.02
MS
09:32m
174.97
IBM
09:35m
175.23
IBM
09:38m
51.29
C
select avg(qty) from t1 group by sym;
sym
avg_qty
C
3700
MS
2400
IBM
6100
select wavg(price, qty) as vwap, sum(qty) from t1 group by sym;
sym
vwap
sum_qty
C
50.828378
14800
IBM
175.085082
12200
MS
29.726389
7200
select wsum(price, qty) as dollarVolume, sum(qty) from t1 group by minute(timestamp) as ts;
ts
dollarVolume
sum_qty
09:32m
1.189796e+006
6800
09:34m
300908
6000
09:35m
946242
5400
09:36m
214030
7200
09:38m
451352
8800
select sum(qty) from t1 group by sym, timestamp.minute() as minute;
sym
minute
sum_qty
C
09:34m
6000
C
09:38m
8800
IBM
09:32m
6800
IBM
09:35m
5400
MS
09:36m
7200
group by和order by配合使用。order by的字段必须是group by结果表中的字段。
select sum(qty) from t1 group by sym, timestamp.minute() as minute order by minute;
sym
minute
sum_qty
IBM
09:32m
6800
C
09:34m
6000
IBM
09:35m
5400
MS
09:36m
7200
C
09:38m
8800
在上述例子中,每个分组的函数结果都是标量。在其他情况下,函数可能输出向量或者字典,而不是输出标量。比如,
stat
函数输出字典;
ols
输出一个系数向量或一个含有参数估计如t-stat,
R²的字典等。为了在多列中输出结果,需要将向量或字典输出转换成多个标量值。换而言之,需要将一个合成列转换成多个列。我们可以通过as关键字和一个代表列名的常量字符串向量来完成这项工作。
y=1..15
factor1=3.2 1.2 5.9 6.9 11.1 9.6 1.4 7.3 2.0 0.1 6.1 2.9 6.3 8.4 5.6
factor2=1.7 1.3 4.2 6.8 9.2 1.3 1.4 7.8 7.9 9.9 9.3 4.6 7.8 2.4 8.7
id=take(1 2 3, 15).sort();
t=table(id, y, factor1, factor2);
t;
id
y
factor1
factor2
1
1
3.2
1.7
1
2
1.2
1.3
1
3
5.9
4.2
1
4
6.9
6.8
1
5
11.1
9.2
2
6
9.6
1.3
2
7
1.4
1.4
2
8
7.3
7.8
2
9
2
7.9
2
10
0.1
9.9
3
11
6.1
9.3
3
12
2.9
4.6
3
13
6.3
7.8
3
14
8.4
2.4
3
15
5.6
8.7
select ols(y,(factor1,factor2),true,0) as `int`factor1`factor2 from t group by id;
id
int
factor1
factor2
1
1.063991
-0.258685
0.732795
2
6.886877
-0.148325
0.303584
3
11.833867
0.272352
-0.065526
select ols(y,(factor1,factor2),true,2).Coefficient.tstat[1:] as `t1`t2 from t group by id;
id
t1
t2
1
-0.891868
2.253451
2
-5.73315
11.433117
3
0.510866
-0.183903
若想要忽略函数的一些输出元素,可将列名留空。
select ols(y,(factor1,factor2),true,2).Coefficient.beta as ``factor1`factor2 from t group by id;
id
factor1
factor2
1
-0.258685
0.732795
2
-0.148325
0.303584
3
0.272352
-0.065526
若想要自定义输出格式,可以写一个简单的包装函数。下面例子中,输出包含了系数估计和R²:
def myols(y,x) {
r=ols(y,x,true,2)
return r.Coefficient.beta join r.RegressionStat.statistics[0]
}
select myols(y,(factor1,factor2)) as `int`factor1`factor2`R2 from t group by id;
id
int
factor1
factor2
R2
1
1.063991
-0.258685
0.732795
0.946056
2
6.886877
-0.148325
0.303584
0.992413
3
11.833867
0.272352
-0.065526
0.144837
FILE:references/doc_2410.md
# randStudent
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randStudent.html
**来源**: DolphinDB 官方文档
---
randStudent
语法
randStudent(df, count)
详情
生成指定个数的 t 分布随机数。
参数
df
是正数,表示t分布的自由度。
count
是正整数,表示生成的随机数个数。
返回值
长度为
count
的 DOUBLE 类型向量。
例子
randStudent(2.31, 2);
// output
[-0.543993, 0.375804]
FILE:references/doc_2421.md
# pipeline
**URL**: https://docs.dolphindb.cn/zh/funcs/p/pipeline.html
**来源**: DolphinDB 官方文档
---
pipeline
语法
pipeline(initTasks, followers,
[queueDepth=2])
详情
通过多线程优化符合如下条件的任务:
(1) 可分解为多个子任务。
(2) 每个子任务包含多个步骤。
(3) 第i个子任务的第 k 个步骤必须在第i个子任务的第 k-1 个步骤以及第 i-1 个子任务的第 k 个步骤完成后才能执行。
参数
initTasks
是所有任务初始步骤的集合,其中每个任务都是由无参数的函数表示。例如,我们有10个任务,那么
initTasks
是一个包含10个无参数函数的元组。
followers
是一元函数的集合,每个函数代表初始步骤之后的一个步骤。如果一个任务有 N
个步骤,
followers
具有N-1个一元函数。
followers
的输出是下一个
followers
的输入。最后一个
followers
有可能返回一个对象。任务的初始步骤是在主线程(接受任务的线程)中执行的,剩下的步骤在单独的线程中执行。如果
pipeline
函数用于执行 N 个步骤的任务,系统会创建 N-1 个线程并且这些线程会在工作完成后销毁。
queueDepth
是队列的最大长度。每个步骤的中间结果保存在队列中,用于下一个步骤。若队列满了,执行会中止,直到下一个步骤使用了队列中的数据。队列的长度越长,下一个步骤的等待时间越短。但是,长的队列会占用更多内存。
queueDepth
的默认值是2。
返回值
如果最后一个步骤返回一个对象,
pipeline
函数返回一个元组,否则不返回任何内容。
例子
下例中,需要把分区表 stockData 转换成一个 csv
文件。该表包含了2008年到2018年的数据,超过了系统的可用内存,因此不能把整个表加载到内存后,再转换成 csv
文件。可把任务分为多个子任务,每个子任务包含两个步骤:加载一个月的数据到内存,然后将这些数据存储到 csv 文件中。每个月的数据存储到 csv
文件中时,必须保证该月数据已加载到内存,并且上个月的数据已经存储到 csv 文件中。
v = 2000.01M..2018.12M
def loadData(m){
return select * from loadTable("dfs://stockDB", "stockData") where TradingTime between datetime(date(m)) : datetime(date(m+1))
}
def saveData(tb){
tb.saveText("/hdd/hdd0/data/stockData.csv",',', true)
}
pipeline(each(partial{loadData}, v),saveData);
FILE:references/doc_2424.md
# isPeak
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isPeak.html
**来源**: DolphinDB 官方文档
---
isPeak
语法
isPeak(X, [strict=true])
详情
若
X
为向量,计算
X
中的每个元素是否为峰值点,若是则返回 true,否则返回 false。
若
X
为矩阵,在每列进行上述计算,返回值一个同
X
维度相同的矩阵。若
X
为表,则只对数值型的列进行上述计算。
参数
X
数值型向量/矩阵/表。
strict
布尔值,默认值为 true。
若
strict
= true,相邻元素不为空且严格小于该元素
若
strict
= false,相邻元素不为空且小于等于该元素
返回值
当
X
是向量时,返回布尔向量。
当
X
是矩阵时,返回布尔矩阵。
当
X
是表时,返回一个表。
例子
v = [1, 2.2, 2.2, 2.2, 2.3, 1, 1.2]
isPeak(v)
// output: [false,false,false,false,true,false,false]
v = [1, 2.2, 2.2, 2.2, 1.6, 1, 1.2]
isPeak(v)
// output: [false,false,false,false,false,false,false]
isPeak(v, false)
// output: [false,true,true,true,false,false,false]
// 矩阵在每列单独计算
m = matrix(3.3 2.8 5.6 NULL 2.5 1.2, 4.5 3.5 4.6 2.8 3.9 NULL)
isPeak(m)
#0
#1
false
false
false
false
false
true
false
false
false
false
false
false
// 表只在数值列进行计算
t = table(`01`01`00`01`02`00 as id, 388.3 390.6 390.8 390.6 390.3 391.5 as price)
isPeak(t)
id
price
01
false
01
false
00
true
01
false
02
false
00
false
相关函数:
isValley
FILE:references/doc_244.md
# percentileRank
**URL**: https://docs.dolphindb.cn/zh/funcs/p/percentileRank.html
**来源**: DolphinDB 官方文档
---
percentileRank
语法
percentileRank(X, score, [method='excel'])
详情
计算一个数值在数值向量中的百分位数(0~100)。计算时忽略 NULL 值。
参数
X
是一个数值型向量、矩阵或表。若为矩阵,每列计算百分位,输出一个向量。若为表,每列计算百分位,输出一个表。
score
是一个数值型标量,表示需要得到其排位的值。
method
是一个字符串,表示计算百分位的方法,包含以下取值,默认值为 "excel":
"excel":小于
score
的元素个数占不等于
score
的元素个数的百分比;若
score
不在
X
中,其百分位计算公式为:
其中,
和
为数据集X中的紧邻score的前、后两个数值,
和
分别为
和
的百分位。
"rank":小于等于
score
的元素个数占元素总数的百分比。当有多个值相等的
score
时,取它们百分位的平均值;
"strict":严格小于
score
的元素个数占元素总数的百分比;
"weak":小于等于
score
的元素个数占元素总数的百分比;
"mean":"strict" 和 "weak" 的平均值。
返回值
DOUBLE 类型标量/向量,或一个包含 DOUBLE 类型结果的表。
例子
a = 2 3 4 4 5;
percentileRank(a, 4);
// output: 66.666667
percentileRank(a, 3);
// output: 25
percentileRank(a, 4, "rank");
// output: 70
percentileRank(a,4,"weak");
// output: 80
percentileRank(a,5,"strict");
// output: 40
percentileRank(a,5,"mean");
// output: 60
percentileRank(1 5 8, 6, "excel")
// output: 66.666667
FILE:references/doc_2444.md
# encodeShortGenomeSeq
**URL**: https://docs.dolphindb.cn/zh/funcs/e/encodeShortGenomeSeq.html
**来源**: DolphinDB 官方文档
---
encodeShortGenomeSeq
语法
encodeShortGenomeSeq(X)
别名:
encodeSGS
详情
对 DNA 序列(由 A, T, C, G 自由组合)进行编码。通过编码,可以减小 DNA 序列的存储空间,提高计算效率。
注意:
若
X
指定为空字符(""),则函数返回0。
若
X
中包含了除 A, T, C, G(大小写敏感)以外的字符,则返回空值。
若
X
指定的字符串所包含的字符个数超过了28,则返回空值。
参数
X
STRING 类型标量或向量、CHAR 类型向量。
返回值
长整型(LONG)或长整型向量(FAST LONG VECTOR)。
例子
a=encodeShortGenomeSeq("TCGATCG")
a;
// output
465691
typestr(a)
// output
LONG
b=encodeShortGenomeSeq("TCGATCG" "TCGATCGCCC")
// output
[465691,168216298]
typestr(b)
// output
FAST LONG VECTOR
// "TCGATCG"重复5次后,因长度超过了28,所以返回了空值。
encodeShortGenomeSeq(repeat("TCGATCG" "TCGAT", 5))
// output
[,1801916404867712433]
y=toCharArray("TCGATCGCCC")
encodeShortGenomeSeq(y)
// output
168216298
encodeShortGenomeSeq("TC G")
// output
00l
encodeShortGenomeSeq("TCtG")
// output
00l
// 基因序列中出现 N,编码返回空。
encodeShortGenomeSeq("NNNNNNNNTCGGGGCAT")
// output
00l
encodeShortGenomeSeq("TCGGGGCATNGCCCG")
// output
00l
encodeShortGenomeSeq("GCCCGATNNNNN")
// output
00l
相关函数:
decodeShortGenomeSeq
,
genShortGenomeSeq
FILE:references/doc_2445.md
# rowDenseRank
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowDenseRank.html
**来源**: DolphinDB 官方文档
---
rowDenseRank
语法
rowDenseRank(X, [ascending=true], [ignoreNA=true], [percent=false])
详情
逐行计算
X
的元素连续排名,排名方式请参照
denseRank
。
参数
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
。
ascending
是一个布尔值,表示排序方向。true 表示升序,false 表示降序。默认值为 true。它是一个可选参数。
ignoreNA
是一个布尔值,表示是否忽略 NULL 值。true 表示忽略 NULL 值,false 表示 NULL 值参与排名。默认值为
true。它是一个可选参数。NULL 值参与排序时,NULL 值为最小值。
percent
是一个布尔值,表示是否以百分比形式显示返回的排名。
返回值
返回一个和
X
维度相同的矩阵。
例子
m = matrix(1 5 8 5 9, 2 8 2 5 2, 6 5 3 3 4)
rowDenseRank(m)
返回:
col1
col2
col3
0
1
2
0
1
0
2
0
1
1
1
0
2
0
1
返回:
y=matrix(1 3 3, 6 5 6, NULL 0 9)
rowDenseRank(y)
返回:
col1
col2
col3
0
1
1
2
0
0
1
2
rowDenseRank(y, ignoreNA=false)
返回:
col1
col2
col3
1
2
0
1
2
0
0
1
2
FILE:references/doc_2449.md
# setReservedMemSize
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setReservedMemSize.html
**来源**: DolphinDB 官方文档
---
setReservedMemSize
语法
setReservedMemSize(memSizeGB)
详情
在线修改系统预留内存空间的大小。该命令只能由管理员执行。
请注意:
此命令修改的配置值在系统重启后将失效。若需要配置值永久生效,请更改配置文件中的
reservedMemSize
。
此函数所设置的预留内存空间大小(对应配置项
reservedMemSize
)与紧急内存区空间大小(对应配置项
emergencyMemSize
或通过
setMaxMemSize
在线修改),其值相加不可超过当前最大内存空间(对应配置项
maxMemSize
或通过
setMaxMemSize
在线修改)的 50%。
参数
memSizeGB
一个数值型标量(单位为GB),必须大于0,且不能超过
maxMemSize
* 0.5。
FILE:references/doc_245.md
# tensor
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tensor.html
**来源**: DolphinDB 官方文档
---
tensor
语法
tensor(X)
详情
将
X
转换为一个 tensor。转换规则如下:
X
转换结果
标量
1 维 tensor
常规向量
1 维 tensor
列式元组
2 维 tensor
矩阵
2 维 tensor
表(每一列具有相同类型)
2 维 tensor
tuple(每个元素都是具有相同类型的向量,tuple of vector)
2 维 tensor
tuple(每个元素都是维度和类型都相同的矩阵,tuple of matrix)
3 维 tensor
tuple(每个元素都是 tuple,且子 tuple 的每个元素都是类型相同的向量,tuple of
tuple)
3 维 tensor
多个 tuple 嵌套
n 维 tensor,n<=10
目前 tensor 主要应用于 DolphinDB 插件(如 LibTorch 等),与深度学习框架进行数据交换。DolphinDB 中的 tensor
目前暂不支持直接存储和计算,并且不支持直接访问和修改其元素。
参数
X
可以是标量、向量、元组、列式元组、矩阵或表。目前仅支持以下数据类型:BOOL, CHAR, SHORT, INT, LONG, FLOAT,
DOUBLE。
返回值
返回一个数据类型同
X
的张量。
例子
// 标量转为 tensor
tensor(3)
/* 输出一个长度为 1 的 1 维 tensor<int[1]>:
0: int 3
*/
// 向量转为 tensor
tensor(1 2 3)
/* 输出一个长度为 3 的 1 维 tensor<int[3]>:
0: int 1
1: int 2
2: int 3
*/
//列式元组转为 tensor
tp = [[1.3,2.5,2.3], [4.1,5.3,5], [4.1,5.3,5]]
tp.setColumnarTuple!()
tensor(tp)
/* 输出一个 2 维 tensor<double[3][3]>:
0: double[3] [1.3, 2.5, 2.3]
1: double[3] [4.1, 5.3, 5]
2: double[3] [4.1, 5.3, 5]
*/
//矩阵转为 tensor
m= 1..6$2:3
tensor(m)
/* 输出一个 2 维 tensor<int[2][3]>:
0: int[3] [1, 3, 5]
1: int[3] [2, 4, 6]
*/
// 表转为 tensor
t=table(1..5 as id1, 6..10 as id2)
tensor(t)
/* 输出一个 2 维 tensor<int[5][2]>:
0: int[2] [1, 6]
1: int[2] [2, 7]
2: int[2] [3, 8]
3: int[2] [4, 9]
4: int[2] [5, 10]
*/
// 元组转为 tensor
tp1 = [[1.3,2.5,2.3], [4.1,5.3,5], [4.1,5.3,5]]
tensor(tp1)
/* 输出一个 2 维 tensor<double[3][3]>:
0: double[3] [1.3, 4.1, 4.1]
1: double[3] [2.5, 5.3, 5.3]
2: double[3] [2.3, 5, 5]
*/
// tuple of matrix 转为 tensor
m1= 1..6$2:3
m2=4..9$2:3
tensor([m1,m2])
/* 输出一个 3 维 tensor<int[2][2][3]>:
0: int[2][3]
1: int[2][3]
*/
// tuple of tuple 转为 tensor
tp1 = [[1.3,2.5,2.3], [4.1,5.3,5], [4.1,5.3,5]]
tp2 = [[1.1,1.2,1.4], [1.5,1.2,1.6], [1.3,1.5,1.8]]
tensor([tp1, tp2])
/* 输出一个 3 维 tensor<double[2][3][3]>:
0: double[3][3]
1: double[3][3]
*/
// tuple 嵌套转为 tensor
tp1 = [[1.3,2.5,2.3], [4.1,5.3,5], [4.1,5.3,5]]
tp2 = [[1.1,1.2,1.4], [1.5,1.2,1.6], [1.3,1.5,1.8]]
tp3 = [[2.1,6.2,4.4], [3.5,1.9,3.6], [1.8,3.5,9.8]]
tensor([[tp1, tp2],[tp1, tp3]])
/* 输出一个 4 维 tensor<double[2][2][3][3]>:
0: double[2][3][3]
1: double[2][3][3]
*/
FILE:references/doc_2450.md
# restoreDB
**URL**: https://docs.dolphindb.cn/zh/funcs/r/restoreDB.html
**来源**: DolphinDB 官方文档
---
restoreDB
语法
restoreDB(backupDir, dbPath, [newDBPath], [keyPath])
详情
恢复备份的数据到数据库。
该函数与
migrate
类似,都可恢复整个数据库下的所有表,区别见表相关内容。
注:
该函数仅支持恢复以拷贝文件方式(即
backup
时指定
dbPath
参数)进行的备份。
恢复时需要确保备份数据与待恢复数据库的引擎类型(engine)一致,且
partitionScheme
(VALUE 除外)也保持一致。
当采用 VALUE 分区时,须保证备份数据中的分区方案是待恢复数据库的分区方案的子集。例如:备份文件的分区方案是
database("dfs://xxx", VALUE, 2017.08.07..2017.08.11), 则待恢复数据库的 VALUE
分区范围必须不小于 2017.08.07..2017.08.11。
参数
backupDir
字符串,表示存放备份数据的目录
dbPath
字符串,表示已备份的分布式数据库的路径
newDBPath
字符串,表示新数据库的名称。如果没有指定,默认值为
dbPath
。
keyPath
字符串标量,指定恢复加密表备份的密钥路径。仅 Linux
系统支持该参数。恢复数据使用的密钥必须与备份时指定的密钥版本一致。注意恢复加密表时,备份表与目标表必须指定相同的加密方式(即建表时指定相同的
encryptMode
参数)。
返回值
返回包含数据库名称和表名称的表,每一行为完成恢复的数据库及表名称。
例子
dbName = "dfs://compoDB2"
n=1000
ID=rand("a"+string(1..10), n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10, n)
t=table(ID, date, x)
db1 = database(, VALUE, 2017.08.07..2017.08.11)
db2 = database(, HASH,[INT, 20])
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db = database(dbName, COMPO,[ db1,db2])
// 创建2个表
pt1 = db.createPartitionedTable(t, `pt1, `date`x).append!(t)
pt2 = db.createPartitionedTable(t, `pt2, `date`x).append!(t)
backupDB(backupDir, dbName)
restoreDB(backupDir, dbName)
dbName
tableName
dfs://compoDB2
pt1
dfs://compoDB2
pt2
相关函数:
restore
,
restoreTable
,
migrate
,
backup
,
backupDB
,
backupTable
FILE:references/doc_2459.md
# tril
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tril.html
**来源**: DolphinDB 官方文档
---
tril
语法
tril(X, [k=0])
详情
若未指定
k
: 返回矩阵
X
的下三角部分,其余元素设为0。
若指定
k
: 返回矩阵
X
的第
k
条对角线上以及该对角线下方的元素,其余元素设为0。矩阵的主对角线为其第0条对角线。
参数
X
是一个矩阵。
k
是一个整数。
返回值
返回一个矩阵,其数据类型同
X
。
例子
m=matrix(1 2 3, 4 5 6, 7 8 9);
m;
col1
col2
col3
1
4
7
2
5
8
3
6
9
tril(m);
col1
col2
col3
1
0
0
2
5
0
3
6
9
tril(m,1);
col1
col2
col3
1
4
0
2
5
8
3
6
9
tril(m,-1);
col1
col2
col3
0
0
0
2
0
0
3
6
0
相关函数:
triu
FILE:references/doc_2460.md
# volumeBar
**URL**: https://docs.dolphindb.cn/zh/funcs/v/volumeBar.html
**来源**: DolphinDB 官方文档
---
volumeBar
语法
volumeBar(X, interval, [label='seq'])
详情
对
X
进行累加,并根据指定的阈值进行分组,返回数据所属分组的组号。分组规则为:
依次累加
X
中的元素
若阈值为正数,则从第一个元素开始累加,直到累加和大于等于阈值,将这些元素划分为一组。然后从下一个元素重新开始累加,并分组,以此类推。最后剩余的累加和小于阈值的元素划分为一组。
若阈值为负数,则从第一个元素开始累加,直到累加和小于等于阈值,将这些元素划分为一组。然后从下一个元素重新开始累加,并分组,以此类推。最后剩余的累加和大于阈值的元素划分为一组。
interval
确定了累加分组的阈值,可以是一个定值也可以是一个百分比:
当
interval
∈ (0, 1) 时, 表示一个百分比,阈值为 sum(X) *
interval。注意,系统会将阈值转换为与
X
相同的类型再进行比较。例如,
X
是整型,则累加和将与
floor(sum(X) * interval)进行比较。
否则,
interval
表示一个定值,即阈值为
interval
。
参数
X
是数值型向量。
interval
非零的数值,表示一个定值或百分比。
label
为标记分组的方法,有以下三种类型:
'seq':默认值,表示按 0, 1, 2, 3… 的顺序标记组号。
'left':当前分组第一个元素前所有元素的累加和作为组号。第1个分组的组号为 0。
'right':
X
从第一个元素开始累加到当前分组中最后一个元素的值作为组号。
返回值
INT/LONG 类型向量。
例子
X = 1 3 4 2 2 1 1 1 1 6 8
volumeBar(X, 4)
输出返回:[0,0,1,2,2,3,3,3,3,4,5]
volumeBar(X, 4, 'left')
输出返回:[0,0,4,8,8,12,12,12,12,16,22]
volumeBar(X, 4, 'right')
输出返回:[4,4,8,12,12,16,16,16,16,22,30]
volumeBar(X, 0.3)
输出返回:[0,0,0,0,1,1,1,1,1,1,2]
X = -6 2 -4 -5 -1 3 -2 -1
volumeBar(X, -2)
输出返回:[0,1,1,2,3,3,3,3]
volumeBar(X, -2, 'left')
输出返回:[0,-6,-6,-8,-13,-13,-13,-13]
volumeBar(X, -2, 'right')
输出返回:[-6,-8,-8,-13,-14,-14,-14,-14]
应用
volumeBar
函数生成等量 K 线。
time = [09:30:00, 09:32:15, 09:35:00, 09:37:30, 09:40:00, 09:45:00, 09:47:30, 09:50:00, 09:55:00, 10:00:00]
price = [100.0, 100.1, 100.05, 99.9, 100.2, 100.15, 100.1, 100.05, 100.0, 99.95]
volume = [200, 800, 250, 300, 1200, 250, 180, 400, 600, 350]
t = table(time, price, volume)
select
first(time) as barStartTime,
first(price) as open,
max(price) as high,
min(price) as low,
last(price) as close,
sum(volume) as totalVolume
from t
group by volumeBar(tradeVolume, 1500) as volumeBarNo
volumeBarNo
barStartTime
open
high
low
close
totalVolume
0
09:30:00
100
100.1
99.9
99.9
1,550
1
09:40:00
100.2
100.2
100.1
100.1
1,630
2
09:50:00
100.05
100.05
99.95
99.95
1,350
FILE:references/doc_2462.md
# short
**URL**: https://docs.dolphindb.cn/zh/funcs/s/short.html
**来源**: DolphinDB 官方文档
---
short
语法
short(X)
详情
将输入的数据类型转换为 SHORT。
参数
x
可以是任意数据类型。
返回值
SHORT 类型对象。
例子
x=short();
x;
返回:null
typestr x;
返回:SHORT
short(`12.3);
返回:12
short(`120.9c);
返回:120
short(32767);
返回:32,767
注:
SHORT 数据类型的范围是[ -2
15
+1, 2
15
-1] =
[-32767, 32767]。如果
X
超出了该范围,将会发生
溢出
。
short(32768);
//Output
null
short(65578);
//Output
42
short(32789)
//Output
-32747
FILE:references/doc_2467.md
# sort
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sort.html
**来源**: DolphinDB 官方文档
---
sort
语法
sort(X, [ascending=true])
sort!
是
sort
的原地版本。
详情
返回一个排序后的向量或矩阵。
参数
X
可以是向量或矩阵。
ascending
是一个布尔值,表示按升序排序还是按降序排序。默认值为 true(按升序排序)。
返回值
返回一个排序后的向量或矩阵。
例子
x=9 1 5;
x;
// output
[9,1,5]
y=sort(x);
y;
// output
[1,5,9]
sort(x, false); // 逆序排序
// output
[9,5,1]
x=1 4 2 5 6 3$2:3;
x;
#0
#1
#2
1
2
6
4
5
3
sort x;
#0
#1
#2
1
3
5
2
4
6
sort! 函数排序并修改输入。
x=9 1 5;
sort!(x);
x;
[1 5 9];
相关函数:
isort
FILE:references/doc_2468.md
# setSystem
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setSystem.html
**来源**: DolphinDB 官方文档
---
setSystem
语法
setSystem(paramName, paramValue)
详情
setSystem
用于设置以下的系统级参数:
在命令行窗口显示的对象的最大行数
在命令行窗口显示的对象的最大行宽
只有管理员有权限执行
setSystem
命令。
参数
paramName
是参数名,
paramValue
是对应的参数值。
例子
setSystem("rows", 30);
setSystem("width", 200);
FILE:references/doc_2480.md
# cumfirstNot
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumfirstNot.html
**来源**: DolphinDB 官方文档
---
cumfirstNot
语法
cumfirstNot(X, [k])
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
若
X
是向量:
如果没有指定
k
,对
X
内的每个元素,返回其之前所有元素中第一个不为 NULL 的元素。
如果指定
k
,对
X
内的每个元素,返回其之前所有元素中第一个不为
k
的元素。
若
X
是矩阵,在每列内进行上述计算,返回一个与
X
维度相同的矩阵。
参数
k
一个标量。
返回值
返回一个与输入
X
相同数据类型和形式的对象。
例子
x=[NULL,1,2,6,NULL,3,4,NULL]
cumfirstNot(x);
// output
[,1,1,1,1,1,1,1]
cumfirstNot(x, 1)
// output
[,,2,2,2,2,2,2]
m=matrix(1 2 3 NULL 4, NULL NULL 8 8 9);
m;
#0
#1
1
2
3
8
8
4
9
cumfirstNot(m);
#0
#1
1
1
1
8
1
8
1
8
相关函数:
firstNot
FILE:references/doc_2483.md
# tema
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tema.html
**来源**: DolphinDB 官方文档
---
tema
语法
tema(X, window)
TA-lib 系列函数参数说明和窗口计算规则请参考:
TAlib
详情
在给定长度(以元素个数衡量)的滑动窗口内,计算
X
的三重指数移动平均(Triple Exponential
Moving Average)。
其计算公式为:
返回值
DOUBLE 类型,数据形式同
X
。
例子
x=12.1 12.2 12.6 12.8 11.9 11.6 11.2
tema(x,3);
// output
[,,,,,,11.24444444444444]
x=matrix(12.1 12.2 12.6 12.8 11.9 11.6 11.2, 14 15 18 19 21 12 10)
tema(x,3);
col1
col2
11.2444
10.6296
相关函数:
ema
,
dema
FILE:references/doc_2488.md
# lt
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lt.html
**来源**: DolphinDB 官方文档
---
lt
语法
lt(X, Y)
或
X<Y
详情
如果
X
和
Y
都不是集合,返回逐个元素比较
X
<
Y
的结果。
如果
X
和
Y
都是集合,则检查
X
是否为
Y
的真子集。
参数
X
和
Y
可以是标量、数据对、向量、矩阵或集合。如果
X
或
Y
中的其中一个是数据对、向量或矩阵,另一个必须是一个标量,或具有相同长度或维度的数据对、向量或矩阵。
返回值
返回布尔类型的标量、向量、数据对或矩阵。
例子
1 2 3 < 2;
// output
[1,0,0]
1 2 3<0 2 4;
// output
[0,0,1]
2:3<1:6;
// output
0 : 1
m1=1..6$2:3;
m1;
#0
#1
#2
1
3
5
2
4
6
m1 lt 4;
#0
#1
#2
1
1
0
1
0
0
m2=6..1$2:3;
m2;
#0
#1
#2
6
4
2
5
3
1
m1<m2;
#0
#1
#2
1
1
0
1
0
0
集合操作:如果
X
<
Y
,则
X
是
Y
的真子集。
x=set(4 6);
x;
// output
set(6,4)
y=set(8 9 4 6);
y;
// output
set(6,4,9,8)
x<y;
// output
1
y<x;
// output
0
x<x;
// output
0
# x is not a proper subset of x
FILE:references/doc_2497.md
# std
**URL**: https://docs.dolphindb.cn/zh/funcs/s/std.html
**来源**: DolphinDB 官方文档
---
std
语法
std(X)
详情
若
X
为向量,返回
X
的标准差。
若
X
为矩阵,计算每列的标准差,返回一个向量。
若
X
为表,计算每列的标准差,返回一个表。
与所有其它聚合函数一致,计算时忽略 NULL 值。
注:
该函数返回无偏差样本标准差(unbiased sample standard
deviation),而不是总体标准差。
参数
X
可以是标量、向量、矩阵或表。
返回值
一个标量、向量或表。
例子
std(1 2 3);
// output
1
m=matrix(1 3 5 7 9, 1 4 7 10 13);
m;
#0
#1
1
1
3
4
5
7
7
10
9
13
std(m);
// output
[3.162277660168379,4.743416490252569]
相关函数:
std
,
cumstd
FILE:references/doc_2501.md
# jsonExtract
**URL**: https://docs.dolphindb.cn/zh/funcs/j/jsonextract.html
**来源**: DolphinDB 官方文档
---
jsonExtract
语法
jsonExtract(json, location, type)
详情
查询 JSON 对象中指定位置的数据,并按指定类型输出结果。
参数
json
LITERAL 类型标量或向量,表示符合标准 JSON 字符串。
location
标量/向量/元组。每个元素可以是字符串或非零整数,用于指定相应维度的位置。
如果为字符串,表示查询指定键对应的元素。
如果为整数:表示查询该整数对应位置的元素。正整数表示从头开始查询,负整数表示从尾部开始查询。
type
字符串标量,表示返回结果的类型,可选值为 "long", "int", "double", "string" 。
返回值
当参数
json
为标量时,返回标量结果;为向量时,返回向量结果。
返回值类型由参数
type
指定。
如果参数
location
指定的元素不存在,或无法解析为指定的类型,则返回空值 。
例子
例1 基础用法
A = '{"a": "hello", "b": [-100, 200.5, 300], "c": { "b" : 2} }'
jsonExtract(A, [2, 1], "int")
// output: -100
jsonExtract(A, 1, "int")
// output: NULL
jsonExtract(A, 999, "int")
// output: NULL
jsonExtract(A, ["b", 2], "int")
// output: 200
jsonExtract(A, ["c", "b"], "double")
// output: 2
B = '{"a": "hello", "b": [200, 300]}'
jsonExtract([A, B], ["c", "b"], "int")
// output: [2, NULL]
jsonExtract([A, B], [2, -1], "int")
// output: [300, 300]
例2 查询表中 JSON 字符串里指定位置的数据。
A1 = '{"a": "a1","c": { "b" : 2} }'
A2 = '{"a": "a2", "c": { "b" : 3} }'
B1 = '{"a": "b1", "c": { "b" : 3} }'
B2 = '{"a": "b2", "c": { "b" : 4} }'
t1 = table([A1, A2] as json, [2,3] as val)
t2 = table([B1, B2] as json, [3,4] as val)
select
jsonExtract(t1.json, "a", "string") as json1,
jsonExtract(t2.json, "a", "string") as json2
from t1
join t2 on t1.val = t2.val
json1
json2
a2
b1
FILE:references/doc_2506.md
# cummdd
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cummdd.html
**来源**: DolphinDB 官方文档
---
cummdd
语法
cummdd(X, [ratio=true])
详情
累计计算传入向量数据的最大回撤。
参数
X
数值向量,表示用于计算最大回撤的输入数据,一般指累积的收益或收益率。注意:不可为空。
ratio
布尔标量,表示是否返回最大回撤率。默认值为 true。
若为 true,表示返回最大回撤率,即相对于峰值的最大下降百分比,计算公式为:
若为 false,表示返回基于下降金额绝对值的最大回撤,计算公式为:
注意:计算时将忽略空值。
窗口计算规则请参考:
累计窗口系列(cum 系列)
返回值
DOUBLE 类型向量。
例子
假设有一个投资组合在一段时间内的累积收益变化如下(以天为单位):
日期
累积收益
2024-10-01
36
2024-10-02
96
2024-10-03
42
2024-10-04
100
2024-10-05
59
2024-10-06
86
2024-10-07
25
2024-10-08
72
使用
cummdd
计算该数据的累计最大回撤。
x = [36,96,42,100,59,86,25,64,72]
cummdd(x)
// Output: [0,0,0.5625,0.5625,0.5625,0.5625,0.75,0.75,0.75]
cummdd(x, false)
// Output: [0,0,54,54,54,54,75,75,75]
相关函数:
maxDrawdown
FILE:references/doc_2525.md
# movingWindowIndex
**URL**: https://docs.dolphindb.cn/zh/funcs/m/movingWindowIndex.html
**来源**: DolphinDB 官方文档
---
movingWindowIndex
语法
movingWindowIndex(X, window, [fixed=false])
详情
用于返回向量
X
在每个滑动窗口内的元素所对应的索引。
参数
X
是一个向量。
window
必须是不小于2的正整数,表示窗口长度。
fixed
是一个布尔值。表示输出的数组向量每行的长度是否固定为
window
。默认值为 false。设置为 true 时
表示所有窗口的长度相同,前 (
window
- 1)个窗口内缺少的索引用 NULL 填充。
返回值
返回一个数组向量,表示
X
在每一个窗口内的元素所对应的索引。
例子
S = 1 2 3 4 5 6 7 8 9 0;
m = movingWindowIndex(X=S,window=3);
m;
// output
[[0],[0,1],[0,1,2],[1,2,3],[2,3,4],[3,4,5],[4,5,6],[5,6,7],[6,7,8],[7,8,9]]
mi = movingWindowIndex(X=S,window=3,fixed=true);
mi;
// output
[[,,0],[,0,1],[0,1,2],[1,2,3],[2,3,4],[3,4,5],[4,5,6],[5,6,7],[6,7,8],[7,8,9]]
// 获取每个窗口第一个元素的值
S[m[0]]
// output
[1,1,1,2,3,4,5,6,7,8]
S[mi[0]]
// output
[,,1,2,3,4,5,6,7,8]
FILE:references/doc_2527.md
# tmmin
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmmin.html
**来源**: DolphinDB 官方文档
---
tmmin
语法
tmmin(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
元素的最小值。
返回值
X
为整型,返回 LONG 类型向量,
X
为浮点数,返回 DOUBLE 类型向量。
例子
T = 1 1 1 2 5 6
X = 1 4 NULL -1 NULL 4
m = table(T as t,X as x)
select *, tmmin(t, x, 3) from m
t
x
tmmin_t
1
1
1
1
4
1
1
1
2
-1
-1
5
6
4
4
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = NULL 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmmin(t, x, 3d) from m
t
x
tmmin_t
2021.01.02
2021.01.02
4
4
2021.01.04
4
2021.01.05
-1
-1
2021.01.07
2
-1
2021.01.08
4
2
select *, tmmin(t, x, 1w) from m
t
x
tmmin_t
2021.01.02
2021.01.02
4
4
2021.01.04
4
2021.01.05
-1
-1
2021.01.07
2
-1
2021.01.08
4
-1
相关函数:
mmin
,
min
FILE:references/doc_2529.md
# dayOfMonth
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dayOfMonth.html
**来源**: DolphinDB 官方文档
---
dayOfMonth
语法
dayOfMonth(X)
详情
计算
X
在当月的第几天。
参数
X
可以是 DATE, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
返回值
整数类型的标量或向量。
例子
dayOfMonth(2011.01.01);
// output
1
dayOfMonth([2012.06.12T12:30:00,2012.07.28T12:35:00]);
// output
[12,28]
相关函数:
dayOfYear
,
quarterOfYear
,
monthOfYear
,
weekOfYear
,
hourOfDay
,
minuteOfHour
,
secondOfMinute
,
millisecond
,
microsecond
,
nanosecond
FILE:references/doc_2530.md
# repartitionDS
**URL**: https://docs.dolphindb.cn/zh/funcs/r/repartitionDS.html
**来源**: DolphinDB 官方文档
---
repartitionDS
语法
repartitionDS(query, [column], [partitionType], [partitionScheme],
[local=true])
详情
使用新的分区类型和分区方案重新划分数据源。
如果
query
是一个 SQL 查询的元代码,必须指定
column
参数。对于
COMPO 分区类型的表,可以不指定
partitionType
和
partitionScheme
参数,
repartitionDS
函数会根据
column
列原始的分区类型和分区方案划分数据源。
如果
query
是包含多个 SQL 查询元代码的元组,无需指定
column
、
partitionType
和
partitionScheme
参数,
repartitionDS
函数会返回一个和
query
长度相同的元组,每个元素都是
query
中的元代码对应的数据源。
当
local
设置为 true 时:将数据源获取到执行该函数的节点上。
当
local
设置为 false
时:如果在指定了计算组的计算节点上执行该函数时,仅将数据源获取到同组内的所有计算节点上;否则将数据源获取到集群中所有数据节点、未指定计算组的计算节点上。
参数
query
是一个 SQL 查询的元代码,或一个元组,其中每个元素都是 SQL 查询的元代码。
column
是一个字符串,表示
query
中的一个列名。
repartitionDS
函数会根据该列划分数据源。
partitionType
表示分区类型,它的取值可以是 RANGE, VALUE 或 HASH。
partitionScheme
是一个向量,表示分区方案。
local
可选参数,布尔值,表示是否将数据源获取到当前节点进行计算。默认值为 true。
返回值
该函数会返回一个元组,包含一组数据源。
例子
创建分布式数据库和表:
n=1000000
ID=rand(100, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x)
dbDate = database(, VALUE, 2017.08.07..2017.08.11)
dbID = database(, RANGE, 0 50 100)
db = database("dfs://compoDB", COMPO, [dbDate, dbID])
pt = db.createPartitionedTable(t, `pt, `date`ID)
pt.append!(t);
例1:
query
是一个 SQL 查询的元代码,指定了
partitionType
和
partitionScheme
。
repartitionDS(<select * from pt>,`date,RANGE,2017.08.07 2017.08.09 2017.08.11);
// output
[DataSource< select [4] * from pt where date >= 2017.08.07,date < 2017.08.09 >,DataSource< select [4] * from pt where date >= 2017.08.09,date < 2017.08.11 >]
例2:
query
是一个 SQL 查询的元代码,没有指定
partitionType
和
partitionScheme
。
repartitionDS(<select * from pt>,`ID)
// output
[DataSource< select [4] * from pt [partition = */0_50] >,DataSource< select [4] * from pt [partition = */50_100] >]
例3:
query
是包含多个 SQL 查询元代码的元组。
repartitionDS([<select * from pt where id between 0:50>,<select * from pt where id between 51:100>]);
// output
[DataSource< select [4] * from pt where id between 0 : 50 >,DataSource< select [4] * from pt where id between 51 : 100 >]
FILE:references/doc_254.md
# right join/right outer join
**URL**: https://docs.dolphindb.cn/zh/progr/sql/rightjoin.html
**来源**: DolphinDB 官方文档
---
right join/right outer join
语法
右连接
SELECT column_name(s)
FROM leftTable RIGHT [OUTER] JOIN rightTable
ON leftTable.matchingCol=rightTable.rightMatchingCol and [filter]
注:
目前 RIGHT JOIN 不支持以下几点:
暂不支持同时连接两个以上的表。
如果有多个连接列,必须使用 AND 连接。
不能和 UPDATE 关键字一起使用。
参数
filter
为条件表达式,作为连接时的过滤条件。暂时只支持通过 AND 连接多个过滤条件,不支持 OR。
详情
右连接返回右表中所有与左表匹配的记录。如果左表中没有匹配的记录,将会返回NULL。如果左表中有多条匹配记录,将会返回所有的匹配记录。因此,右连接返回结果的行数有可能比右表的行数多。
例子
例1. 两个表右连接,除了连接列之外没有其他相同列名:
t1= table(1 2 3 3 as id, 7.8 4.6 5.1 0.1 as value)
t2 = table(5 3 1 as id, 300 500 800 as qty);
t1;
id
value
1
7.8
2
4.6
3
5.1
3
0.1
t2;
id
qty
5
300
3
500
1
800
SELECT id, value, qty FROM t1 RIGHT OUTER JOIN t2 ON t1.id=t2.id
//等价于 SELECT id, value, qty FROM t1 RIGHT JOIN t2 ON t1.id=t2.id
id
value
qty
300
3
5.1
500
3
0.1
500
1
7.8
800
我们无需指定value和qty来自哪个表。系统首先会在左表中定位这两个列,如果左表没有这两个列,系统会在右表定位。
SELECT id, value, qty FROM t2 RIGHT JOIN t1 ON t2.id=t1.id
id
value
qty
1
7.8
800
4.6
3
5.1
500
3
0.1
800
例2. 两个表右连接,它们具有相同列名,但是不作为连接列:
t1 = table(1 2 3 3 as id, 7.8 4.6 5.1 0.1 as value, 4 3 2 1 as x)
t2 = table(5 3 1 as id, 300 500 800 as qty, 44 66 88 as x);
t1;
id
value
x
1
7.8
4
2
4.6
3
3
5.1
2
3
0.1
1
t2;
id
qty
x
5
300
44
3
500
66
1
800
88
SELECT id, value, qty, x FROM t1 RIGHT JOIN t2 ON t1.id=t2.id
id
value
qty
x
300
3
5.1
500
2
3
0.1
500
1
1
7.8
800
4
SELECT id, value, qty, t1.x FROM t1 RIGHT JOIN t2 ON t1.id=t2.id
id
value
qty
x
300
3
5.1
500
2
3
0.1
500
1
1
7.8
800
4
如果左表(t1)和右表(t2)有除连接列以外其他相同的字段名(x),我们从右表(t2)中选择字段名为x的数据时,需要指定x所在的表:t2.x。
SELECT * FROM t1 RIGHT JOIN t2 ON t1.id=t2.id
value
x
id
qty
t2_x
5
300
44
5.1
2
3
500
66
0.1
1
3
500
66
7.8
4
1
800
88
在上面的例子中,从t1和t2选择字段名为x的数据,并且把结果中t2的x字段重命名为t2_x。
例3. 多个连接列:
t1=table(1 1 2 2 3 3 as x, 1 2 2 3 3 4 as y, 1..6 as a);
t2=table(0 1 1 2 2 3 as x, 1 2 3 3 4 5 as y, 11..16 as b);
t1;
x
y
z
1
1
1
1
2
2
2
2
3
2
3
4
3
3
5
3
4
6
t2;
x
y
b
0
1
11
1
2
12
1
3
13
2
3
14
2
4
15
3
5
16
SELECT * FROM t1 RIGHT JOIN t2 ON t1.x=t2.x AND t1.y=t2.y
// x, y是连接列
a
x
y
b
0
1
11
2
1
2
12
1
3
13
4
2
3
14
2
4
15
3
5
16
t2.rename!(`x`y, `x2`y2);
t2
x2
y2
b
0
1
11
1
2
12
1
3
13
2
3
14
2
4
15
3
5
16
SELECT * FROM t1 RIGHT JOIN t2 ON t1.x=t2.x2 AND t1.y=t2.y2
// t1.x, t1.y t2.x2, t2.y2是连接列
a
x2
y2
b
0
1
11
2
1
2
12
1
3
13
4
2
3
14
2
4
15
3
5
16
例4. 指定过滤条件
t1= table(1 2 3 3 as id1, 7.8 4.6 5.1 0.1 as value)
t2 = table(5 3 1 as id2, 300 500 800 as qty);
SELECT * FROM t1 RIGHT JOIN t2 ON t1.id1=t2.id2 AND t1.value>1 AND t1.value<6 AND t2.qty>300
value
id2
qty
5
300
5.1
3
500
1
800
FILE:references/doc_2544.md
# latestIndexedTable
**URL**: https://docs.dolphindb.cn/zh/funcs/l/latestIndexedTable.html
**来源**: DolphinDB 官方文档
---
latestIndexedTable
语法
latestIndexedTable(keyColumns, timeColumn, [X1], [X2], .....)
或
latestIndexedTable(keyColumns, timeColumn, capacity:size, colNames,
colTypes)
或
latestIndexedTable(keyColumns, timeColumn, table)
详情
该函数用于创建索引内存表,包含一个主键。主键可由一个或多个字段组成。其相较于
indexedTable,除主键外,还包含一个时间列,用于判断是否更新记录。
向表中添加新记录时,系统自动检查新记录的主键值。如果新记录的主键值与已有记录的主键值相同,且新记录的时间戳大于等于已有记录的时间戳,则更新表中对应的记录,否则不更新。因为在写入数据时会判断时间列,对相同主键的记录进行去重,所以
latestIndexedTable
写入性能较
indexedTable
差,但查询性能不受影响。
注:
不允许对主键进行更新操作。
优化查询 latestIndexedTable 的方法和相关案例请参照函数 indexedTable。
参数
在
indexedTable
的基础上,增加了
timeColumn
参数。
timeColumn
字符串,表示时间列,可以为整型或时间类型。
返回值
一张表。
例子
例1. 创建索引表
第一种写法:
sym=`A`B`C`D`E
id=5 4 3 2 1
val=52 64 25 48 71
timeCol = 2022.12.07T00:00:00.001+0..4
t=latestIndexedTable(`sym`id,`timeCol,sym,id,timeCol,val)
t;
输出返回:
sym
id
timeCol
val
A
5
2022.12.07T00:00:00.001
52
B
4
2022.12.07T00:00:00.002
64
C
3
2022.12.07T00:00:00.003
25
D
2
2022.12.07T00:00:00.004
48
E
1
2022.12.07T00:00:00.005
71
第二种写法:
t=latestIndexedTable(`sym`id,`timeCol, 1:0,`sym`id`timeCol`val,[SYMBOL,INT,TIMESTAMP, INT])
insert into t values(`A`B`C`D`E,5 4 3 2 1,2022.12.07T00:00:00.001+0..4,52 64 25 48 71);
第三种写法:
tmp=table(sym, id, timeCol, val)
t=latestIndexedTable(`sym`id, `timeCol, tmp);
例2. 更新内存表
插入新记录,并且新记录中的主键值与表中主键值重复,根据时间列来确定保留哪条记录:
insert into t values(`A`A`E,5 5 1, 2022.12.07T00:00:00.001 2022.12.07T00:00:00.007 2022.12.07T00:00:00.003, 44 66 28);
t;
输出返回:
sym
id
timeCol
val
A
5
2022.12.07T00:00:00.007
66
B
4
2022.12.07T00:00:00.002
64
C
3
2022.12.07T00:00:00.003
25
D
2
2022.12.07T00:00:00.004
48
E
1
2022.12.07T00:00:00.005
71
相关函数:
keyedTable
,
indexedTable
,
latestKeyedTable
FILE:references/doc_2563.md
# loadDistributedInMemoryTable
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadDistributedInMemoryTable.html
**来源**: DolphinDB 官方文档
---
loadDistributedInMemoryTable
语法
loadDistributedInMemoryTable(tableName)
详情
返回分布式共享内存表的句柄。该函数只能在数据节点/计算节点上执行。
参数
tableName
字符串标量,表示分布式共享内存表的名称。
返回值
一个分布式共享内存表的句柄。
例子
pt = createDistributedInMemoryTable(`dt, `time`id`value, `DATETIME`INT`LONG, HASH, [INT, 2],`id)
time = take(2021.08.20 00:00:00..2021.08.30 00:00:00, 40);
id = 0..39;
value = rand(100, 40);
tmp = table(time, id, value);
pt = loadDistributedInMemoryTable(`dt)
pt.append!(tmp);
select * from pt;
相关函数:
dropDistributedInMemoryTable
,
createDistributedInMemoryTable
FILE:references/doc_257.md
# replace
**URL**: https://docs.dolphindb.cn/zh/funcs/r/replace.html
**来源**: DolphinDB 官方文档
---
replace
语法
replace(X, oldValue, newValue)
详情
返回将
oldValue
替换成
newValue
后的向量或矩阵。
replace!
是
replace
的原地改变版本。
参数
X
可以是向量、矩阵。
oldValue
标量,与
X/newValue
具有相同数据类别,表示将被替换的值。
newValue
标量,与
X/oldValue
具有相同数据类别,表示新的值。
返回值
与
X
类型相同的向量或矩阵。
例子
x=1 1 3;
x=x.replace(1,2);
x
// output
[2,2,3];
m=1..4$2:2;
m
#0
#1
1
3
2
4
m=m.replace(2,1);
m
#0
#1
1
3
1
4
m.replace!(1,6);
#0
#1
6
3
6
4
FILE:references/doc_2577.md
# reshape
**URL**: https://docs.dolphindb.cn/zh/funcs/r/reshape.html
**来源**: DolphinDB 官方文档
---
reshape
语法
reshape(obj, [dim])
详情
改变矩阵的形状。如果没有指定
dim
,则将
obj
重组为一个向量。
参数
obj
是一个向量或矩阵。
dim
是一个数据对,表示返回结果的行数和列数。它是一个可选参数。
返回值
返回一个改变形状后的矩阵。如果没有指定
dim
,则返回一个向量。
例子
x=1..6;
x=x.reshape(3:2);
x
#0
#1
1
4
2
5
3
6
x=x.reshape(2:3);
x
#0
#1
#2
1
3
5
1
4
6
x=x.reshape(6:1)
x
#0
1
2
3
4
5
6
x.reshape()
// output
[1,2,3,4,5,6] // 将 x 重组为一个向量
FILE:references/doc_2579.md
# splrep
**URL**: https://docs.dolphindb.cn/zh/funcs/s/splrep.html
**来源**: DolphinDB 官方文档
---
splrep
语法
splrep(x, y, t)
详情
splrep
全称 Spline Representation,即样条插值函数,要求找到一维曲线的
B 样条表示。在给定数据点集 (x[i], y[i]) 后,使用该函数可确定在区间 x[0] <= x <= x[size(x)-1] 上的度数为 3
的平滑样条逼近。注意,若
x
,
y
,
t
传入参数中包含 NULL 将直接填充为 0。
参数
x
/
y
Integral/Temporal/Floating 类型向量,定义三次样条曲线 y =
f(x) 的数据点。
注:
x
与
y
的输入值须保证相同长度,且
y
的输入值须为递增向量。
t
向量,可选,表示结点。样条在结点两边可以是不同的多项式。
t
须满足
Schoenberg-Whitney 条件,如必须存在一个数据点的子集 x[j] 对于所有的 j=0, 1,...,n-5,满足 t[j] < x[j] <
t[j+4]。
返回值
返回值为一个长度为3的元组,其各个元素的含义如下:
第一个元素:向量,表示样条曲线的结点。
第二个元素:向量,表示 B 样条系数。
第三个元素:标量,表示样条的次数。
例子
x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
y = [0, 3, 5, 6, 5, 3, 1, 2, 4, 5]
t=[1,3,5,8]
tck= splrep(x, y, t=t)
print(tck)
//output
([0,0,0,0,1,3,5,8,9,9,9,9],[0,2.234794827972243,2.999908797063527,8.195517483732592,0.982766102937427,0.416533320193195,6.868465914739519,5,0,0,0,0],3)
相关函数:
splev
FILE:references/doc_2597.md
# tmmax
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmmax.html
**来源**: DolphinDB 官方文档
---
tmmax
语法
tmmax(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
元素的最大值。
返回值
X
为整型,返回 LONG 类型向量,
X
为浮点数,返回 DOUBLE 类型向量。
例子
T = 1 1 1 2 5 6
X = 1 4 NULL -1 NULL 4
m = table(T as t,X as x)
select *, tmmax(t, x, 3) from m
t
x
tmmax_t
1
1
1
1
4
4
1
4
2
-1
4
5
6
4
4
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = NULL 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmmax(t, x, 3d) from m
t
x
tmmax_t
2021.01.02
2021.01.02
4
4
2021.01.04
4
2021.01.05
-1
-1
2021.01.07
2
2
2021.01.08
4
4
select *, tmmax(t, x, 1w) from m
t
x
tmmax_t
2021.01.02
2021.01.02
4
4
2021.01.04
4
2021.01.05
-1
4
2021.01.07
2
4
2021.01.08
4
4
相关函数:
mmax
,
max
FILE:references/doc_261.md
# parseMktData
**URL**: https://docs.dolphindb.cn/zh/funcs/p/parseMktData.html
**来源**: DolphinDB 官方文档
---
parseMktData
语法
parseMktData(dict)
详情
将输入的字典或 JSON 字符串解析为 MKTDATA 类型。
参数
dict
字典或表示该字典的 JSON 格式字符串(STRING 标量),用于指定待解析的市场数据内容。
返回值
一个 MKTDATA 类型对象。
市场数据支持与字段要求
MKTDATA 为 DolphinDB 新增的数据类型,为金融产品定价需要用到的市场数据提供支撑。
目前支持以下类型:
即期价格:FxSpot(外汇即期汇率)
期限结构曲线:IrYieldCurve(利率收益率曲线), AssetPriceCurve(资产价格曲线)
波动率曲面:FxVolatilitySurface(外汇波动率曲面)
各种类型数据所需字段如下(注:"version" 为系统保留字段,为避免冲突,请勿将此名称用于自定义字段。):
FxSpot
字段名
类型
描述
是否必填
mktDataType
STRING
固定填 "Spot"
是
referenceDate
DATE
参考日期
是
spotDate
DATE
即期交割日,默认使用内部静态数据
否
spotType
STRING
即期价格类型,固定填 "FxSpot"
是
value
DOUBLE
即期价格
是
unit
STRING
即期价格的单位,可选值为"EURUSD", "USDCNY", "EURCNY", "GBPCNY", "JPYCNY",
"HKDCNY"。
货币对的表示也可由
.
或
/
分隔,例如
"EURUSD" 也可写为 "EUR.USD" 或 "EUR/USD"。
是
下例定义了一个 FxSpot 对象:
fxSpot = {
"mktDataType": "Spot",
"referenceDate": 2025.08.18,
"spotDate": 2025.08.20,
"spotType": "FxSpot",
"value": 7.2659,
"unit": "USDCNY"
}
mktData = parseMktData(fxSpot)
print(mktData)
IrYieldCurve
字段名
类型
描述
是否必填
mktDataType
STRING
固定填 "Curve"
是
referenceDate
DATE
参考日期
是
curveType
STRING
固定填 "IrYieldCurve"
是
dayCountConvention
STRING
曲线的日期计数惯例,可选值为:
"Actual360":实际天数除以360
"Actual365":实际天数除以365(不区分闰年)
"ActualActualISMA":实际天数/实际天数(ISMA规则)
"ActualActualISDA":实际天数/实际天数(ISDA规则)
是
interpMethod
STRING
内插方法,可选值为:
"Linear":线性插值
"CubicSpline":三次样条插值
"CubicHermiteSpline":三次埃尔米特样条插值
是
extrapMethod
STRING
外插方法,可选值为:
"Flat":平插
"Linear":线性插值
是
dates
DATE 向量
数据点的日期
是
values
DOUBLE 向量
数据点的值,与
dates
中的元素一一对应
是
curveName
STRING
曲线名称
否
currency
STRING
货币,可选值为"CNY", "USD", "EUR", "GBP", "JPY", "HKD"
是
compounding
STRING
复利类型,可选值为:
"Simple":单利
"Compounded":离散复利
"Continuous":连续复利
是
settlement
DATE
结算日,如果指定了结算日,则后续期限间隔的计算都将从
settlement
开始,而不是
referenceDate
否
frequency
INTEGRAL或 STRING
计息频率,可选值为:
-1 或 "NoFrequency":无效计息频率
0 或 "Once":到期一次还本付息
1 或 "Annual":每年付息一次
2 或 "Semiannual":每半年付息一次
3 或 "EveryFourthMonth":每四个月付息一次
4 或 "Quarterly":每季度付息一次
6 或 "BiMonthly":每两月付息一次
12 或 "Monthly":每月付息一次
13 或 "EveryFourthWeek":每四周付息一次
26 或 "BiWeekly":每两周付息一次
52 或 "Weekly":每周付息一次
365 或 "Daily":每日付息一次
999 或 "Other":其他计息频率
否
curveModel
STRING
曲线构建模型,可选值为 "Bootstrap"(默认),"NS","NSS"。
当取值 "NSS" 或 "NS",无需传
interpMethod
、
extrapMethod
、
dates
、
values
字段。
否
curveParams
DICT
模型的参数,当
curveModel
取值 "NSS" 或 "NS" 时必填:
curveModel = "NS":应包含键 'beta0', 'beta1', 'beta2',
'lambda'
curveModel = "NSS":应包含键'beta0', ‘beta1', 'beta2',
'beta3', 'lambda0', 'lambda1'
否
下例定义了一个 IrYieldCurve 对象:
aod = 2025.07.01
curve = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": aod,
"currency": "CNY",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"dates":[2025.07.07,2025.07.10,2025.07.17,2025.07.24,2025.08.04,2025.09.03,2025.10.09,2026.01.05,
2026.04.03,2026.07.03,2027.01.04,2027.07.05,2028.07.03],
"values":[0.015785,0.015931,0.016183,0.016381,0.016493,0.016503,0.016478,0.016234,0.016321,
0.016378,0.015508,0.015185,0.014901],
"settlement": aod+2
}
mktData = parseMktData(curve)
print(mktData)
AssetPriceCurve
字段名
类型
描述
是否必填
mktDataType
STRING
固定填 "Curve"
是
referenceDate
DATE
参考日期
是
curveType
STRING
固定填 "AssetPriceCurve"
是
dates
DATE 向量
数据点的日期
是
values
DOUBLE 向量
数据点的值,与
dates
中的元素一一对应
是
curveName
STRING
曲线名称
否
下例定义了一个 AssetPriceCurve 对象:
curve = {
"mktDataType": "Curve",
"curveType": "AssetPriceCurve",
"referenceDate": 2024.06.28,
"curveName": "PRICE_SHIBOR_3M",
"dates": [2024.06.21, 2024.06.24, 2024.06.25, 2024.06.26,2024.06.27],
"values": [1.923, 1.922, 1.921, 1.919, 1.918]/100
}
mktData = parseMktData(curve)
print(mktData)
FxVolatilitySurface
字段名
类型
描述
是否必填
mktDataType
STRING
固定填 "Surface"
是
referenceDate
DATE
参考日期
是
surfaceType
STRING
固定填 "FxVolatilitySurface"
是
smileMethod
STRING
波动率微笑方法,可选值为:
"Linear":线性微笑
"CubicSpline":三次样条微笑
"SVI":SVI 模型微笑
"SABR":SABR 模型微笑
是
volSmiles
DICT(STRING, ANY) 向量
波动率微笑向量,向量中每个元素为一条波动率微笑。
包含以下成员:
strikes
: DOUBLE 类型向量,表示不同的行权价
vols
: DOUBLE 类型向量,表示行权价对应的波动率,与
strikes
等长
curveParams
:字典DICT(STRING,
DOUBLE)类型,表示波动率微笑方法的模型参数,只在
smileMethod
取值
"SVI" 或 "SABR" 时生效:
smileMethod = 'SVI': 应包含键 'a', 'b', 'rho', 'm',
'sigma'
smileMethod = 'SABR': 应包含键 'alpha', 'beta',
'rho', 'nu'
fwd
:可选,DOUBLE 类型标量,当
smileMethod
取值
"SVI" 或 "SABR" 时必填,表示远期值
是
termDates
DATE 向量
volSmiles
中每条波动率微笑对应的期限日期
是
surfaceName
STRING
曲面名称
否
currencyPair
STRING
外汇的货币对,可选值为"EURUSD", "USDCNY", "EURCNY", "GBPCNY", "JPYCNY",
"HKDCNY"。
货币对的表示也可由
.
或
/
分隔,例如
"EURUSD" 也可写为 "EUR.USD" 或 "EUR/USD"。
是
下例定义了一个 FxVolatilitySurface 对象:
surf = {
"surfaceName": "USDCNY",
"mktDataType": "Surface",
"surfaceType": "FxVolatilitySurface",
"referenceDate": "2025.08.18",
"smileMethod": "Linear",
"termDates": [
"2025.08.21",
"2026.08.20"
],
"volSmiles":[{"strikes": [6.5,7,7.5],"vols": [0.1,0.1,0.1]},{"strikes": [6.5,7,7.5],"vols": [0.1,0.1,0.1]}],
"currencyPair": "USDCNY"
}
surfUsdCny = parseMktData(surf)
FILE:references/doc_2617.md
# eachLeft
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/eachLeft.html
**来源**: DolphinDB 官方文档
---
eachLeft
语法
eachLeft(func, X, Y, [assembleRule|consistent=false])
func:L(X, Y)
或
X <operator>:L Y
表示不指定
assembleRule
,使用默认值
func:LC(X, Y)
或
X <operator>:LC Y
表示指定
assembleRule
,此例中指定为 C(Consistent)
详情
把 func 应用到
X
的每个元素上,即依次执行 func(X(i),Y)。
对于向量,X(i) 为每个元素
对于矩阵,X(i) 为每一列
对于表,X(i) 为每一行
对于数组向量,X(i) 为每一行
对于字典,X(i) 为字典的每一个 value
如果 func 支持向量操作,并且输入数据是一个向量,使用向量函数或运算符比使用 eachLeft 更为高效。
参数
func
是一个二元函数。
X
和
Y
可以是向量、矩阵、表
、数组向量
或字典。
assembleRule
可选参数,表示如何将子任务的结果合并为函数最终结果。接受一个整数或字符串作为输入,可选值如下:
0 (或 "D"):默认值,表示 DolphinDB
规则,即根据所有子任务的结果来决定最终输出的数据类型和形式。当所有子结果具有相同的数据类型和形式时,多个标量合并为一个向量、多个向量合并为一个矩阵、多个矩阵合并为一个元组、多个字典合并为一张表;否则将所有子结果合并为一个元组输出。
1(或 "C"):表示 Consistent
规则,即认为所有子结果的数据类型和形式都与第一个子结果相同,根据第一个子结果来选择最终结果的数据类型和形式。如果后续子任务返回的结果与第一个子任务的结果类型不一致,系统会尝试对后续结果进行类型转换。如果转换失败则抛出异常。因此,此规则只可在已知子结果的数据类型及形式一致时指定。此规则可使系统免于逐一缓存并检查每个子任务的计算结果,从而提升性能。
2(或 "U"):表示 Tuple 规则,系统不再对各子结果的类型和形式一致性进行检查,而是直接将子结果组装成一个元组输出。
3(或 "K"):表示 kdb+ 规则。与 DolphinDB 规则类似,都会根据所有子结果来决定最终结果形式。主要区别在于,kdb+
规则下,只要有任一子任务返回向量,则最终结果必为一个元组;而在 DolphinDB
规则下,子任务结果若均为长度相同的向量,则最终结果为一个矩阵。其他情况下,kdb+ 规则的输出与 DolphinDB 规则相同。
注:
自 2.00.15
/3.00.3
版本起,新增了
assembleRule
参数。该参数不仅实现了原
consistent
参数的功能,还提供了更多的结果合并选项。
consistent
是一个布尔值,默认值为 false,相当于
assembleRule
="D";若为 true,则相当于
assembleRule
="C"。为保持兼容性,用户仍可使用
consistent
参数。如果同时指定
assemble
和
consistent
,将以
consistent
的值为准。
assembleRule
也可在高阶函数对应的函数模式符号后指定,通过字符 D/C/U/K 表示。以
eachPre (:P)
为例,形如
sub:PU(X)
。不指定则使用默认值 D。
返回值
取决于
assembleRule
的值。
例子
eachLeft
作用于两个向量:
x = 4 3 2 1
y = 3 0 6;
x +:L y;
4
3
2
1
7
6
5
4
4
3
2
1
10
9
8
7
eachLeft(pow, x, y);
4
3
2
1
64
27
8
1
1
1
1
1
4096
729
64
1
eachLeft
作用于一个矩阵以及一个向量:
x=1..6$2:3;
x;
col1
col2
col3
1
3
5
2
4
6
x ** :L 1 1;
// output
[3,7,11]
eachLeft
作用于两个矩阵:
y=6..1$2:3;
y;
col1
col2
col3
6
4
2
5
3
1
z = x **:L y;
z;
// output
(#0 #1 #2
-- -- --
16 10 4
,#0 #1 #2
-- -- --
38 24 10
,#0 #1 #2
-- -- --
60 38 16
)
typestr z;
// output
ANY VECTOR
eachLeft
作用于一个字典和一个向量:
d=dict(`a`b`c, [[1, 2, 3],[4, 5, 6], [7, 8, 9]])
eachLeft(add,d,10 20 30)
// output
a->[11,22,33]
b->[14,25,36]
c->[17,28,39]
FILE:references/doc_2624.md
# tmskew
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmskew.html
**来源**: DolphinDB 官方文档
---
tmskew
语法
tmskew(T, X, window, [biased=true])
部分通用参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
的斜度。
参数
biased
是一个布尔值,表示是否是有偏估计。默认值为 true,表示有偏估计。
返回值
DOUBLE 类型向量。
例子
tmskew(1 1 3 5 8 15 15 20, 5 2 4 1 2 8 9 10, 3)
// output
[,0,-0.381801774160607,0,,,0,]
index = take(datehour(2019.06.13 13:30:10),4) join (datehour(2019.06.13 13:30:10)+1..6)
data = 1 NULL 3 4 5 NULL 3 NULL 5 3
tmskew(index, data, 4h)
// output
[,,,-0.3818,,,0,0,0,0.7071]
tmskew(index, data, 2d)
// output
[,,0,-0.3818,-0.4347,-0.4347,-0.37,-0.37,-0.5653,-0.4363]
相关函数:
mskew
,
skew
FILE:references/doc_2627.md
# 国泰君安 191 Alpha 因子库
**URL**: https://docs.dolphindb.cn/zh/modules/gtja191Alpha/191alpha.html
**来源**: DolphinDB 官方文档
---
国泰君安 191 Alpha 因子库
国泰君安 191 Alpha 因子
来源于国泰君安 2017 年 6 月份公布的研报《基于短周期价量特征的多因子选股体系——数量化专题之九十三》,属于短周期价量因子。为了使用户更方便地计算因子,本模块使用 DolphinDB 脚本实现了所有 191 个因子的函数,并封装在 DolphinDB 模块 gtja191Alpha 中。
本文将为大家介绍该因子库的基本规范,并以其中几个因子为例,展示因子库在批计算、流计算中的应用。
注意
:本教程包含的所有代码兼容 DolphinDB 2.00.9,1.30.21 及以上版本。
1. 函数命名规则与入参规范
gtja191Alpha 模块中的所有函数命名规则为 gtjaAlpha + 因子序号, 如 gtjaAlpha1 ,gtjaAlpha29 ,gtjaAlpha166 。
每一个因子的入参字段有所不同,具体参考
附录1-因子入参一览表
。本教程涉及到的所有字段如下:
参数名称 / 标准字段名称
参数含义
tradetime
交易时间
securityid
股票代码
open
开盘价
close
收盘价
high
最高价
low
最低价
vol
交易量
vwap
成交量加权平均价格
index_open
指数开盘价
index_close
指数收盘价
gtja191Alpha 模块中的所有因子均为矩阵入参。
2. 批计算使用范例
本章节将从环境配置、数据准备、计算调用方法等方面具体介绍 gtja191Alpha.dos 模块的用法。
2.1. 环境准备
把附件的 gtja191Alpha.dos 放在 [home]/modules 目录下,[home] 目录由系统配置参数 home 决定,可以通过
getHomeDir()
函数查看。
更多 DolphinDB 模块的说明,请参阅
DolphinDB 教程:模块
。
2.2. 数据准备
本文提供了因子测试用的
日频数据文件 (datatest.csv)
,该数据包含了国泰君安 191 因子
所需的字段
。如使用其他数据,请对照
所需的字段
自行添加缺少字段。
对于数据,需要保证当前数据的表字段名与模块字段名一致。为方便使用,本教程准备了一个辅助模块
gtja191Prepare.dos
来帮助统一字段名。调用前辅助模块前,需将该辅助模块放置在 gtja191Alpha 同级目录下。
辅助模块中有三类函数:
prepareData 函数,可将数据与标准字段的名称对齐。函数的参数中,rawData 为使用的数据源,startTime 与 endTime 为需要的数据的起始时间和结束时间,其余参数为现有字段名与标准字段的对应名称。
gtjaPrepare 函数,将表中字段提取成计算所需的矩阵并用字典存储。
gtjaCalAlpha# 函数,最终计算函数,会调用 gtjaPrepare 函数及 gtja191Alpha 模块中的计算函数。
辅助模块具体用法将在本节及下一节中介绍。
一般来说,数据准备阶段,用户需调用辅助模块中的 prepareData 函数将数据与标准字段名称对齐。
注意
:如若用户采用的数据字段名与输入字段中的标准字段名一致,无需调用准备函数 prepareData 。
载入模块和数据方法如下,data 为准备好的数据:
use gtja191Alpha
use gtja191Prepare
login(
'admin'
,
'123456'
)
rawData = loadText(
"/YOUR_DIR/datatest.csv"
)
startTime = timestamp(
2010.01
.
01
)
endTime = timestamp(
2010.01
.
31
)
data = prepareData(rawData=rawData, startTime=startTime, endTime=endTime, securityidName=
"securityid"
, tradetimeName=
"tradetime"
, openName=
"open"
, closeName=
"close"
, highName=
"high"
, lowName=
"low"
, volumeName=
"vol"
, vwapName=
"vwap"
, indexCloseName=
"index_close"
, indexOpenName=
"index_open"
)
2.3. 使用范例
gtja191Alpha 模块中的所有因子均为矩阵入参,故用户需先准备矩阵,再调用对应的 gtjaAlpha# 函数,返回的结果亦为矩阵。由于不同因子计算时用到的参数不同,用户需通过查询
附录1-因子入参一览表
来确定所需的参数。
以国泰君安 Alpha 第1号因子为例,计算方法如下:
use gtja191Alpha
open, close, vol = panel(data.tradetime, data.securityid, [data.open, data.close, data.vol])
res = gtjaAlpha1(open, close, vol)
//or you can use dictionary
input = dict(`open`close`vol, panel(data.tradetime, data.securityid, [data.open, data.close, data.vol]))
res = gtjaAlpha1(input.open, input.close, input.vol)
为了更加便于用户计算,省去查询参数这一步骤,因子计算
辅助函数模块 gtja191Prepare.dos
提供了所需的矩阵准备函数 gtjaPrepare 和计算函数 gtjaCalAlpha#,用户可将其作为模块导入。
以 gtjaAlpha 第 1 号因子为例,辅助模块内的函数如下:
def gtjaPrepare(data, startTime, endTime){
t = select securityid, tradetime, vol, low, high, close, open, vwap, index_close, index_open from data where tradetime between startTime : endTime
return
dict(`vol`low`high`close`open`vwap`index_close`index_open, panel(t.tradetime, t.securityid, [t.vol, t.low, t.high, t.close, t.open, t.vwap, t.index_close, t.index_open]))
}
def gtjaCalAlpha1(data, startTime, endTime){
input = gtjaPrepare(data, startTime, endTime)
return
gtja191Alpha::gtjaAlpha1(input.open,input.close,input.vol)
}
//调用方法如下:
use gtja191Prepare
res = gtjaCalAlpha1(data, startTime, endTime)
注意
:直接调用计算模块及辅助模块的整体调用方式请参考
gtja191Alpha 模块调用脚本
2.4. 注意事项
gtja191Alpha 模块中部分因子的原公式定义并不明确,gtja191Alpha 模块对这些做了一定的调整:
因子内做 RANK(A) 或 TSRANK(A, n) 计算时,默认用百分比的形式返回排名。
计算 SMA(A, n, m) 值时,取用数据A过去n天的加权平均值,其中平滑系数参数alpha=n/m。
原论文中定义 SUMAC(A, n) 为计算 A 的前 n 项的累加,实际计算时与计算 SUM(A, n) 无异。
3. 实时流计算使用范例
国泰君安 191 Alpha 因子中大多数因子的实现方式都较为复杂,在流计算中,需要创建多个引擎级联完成。DolphinDB 提供了一个解析引擎
streamEngineParser
来代替人工创建并串联多个引擎,大大提高效率。除此之外,gtja191Alpha 模块也实现了批流一体,即做流计算时无需修改计算代码,直接在流引擎
streamEngineParser
中调用即可。
streamEngineParser
解析本模块因子计算的大致逻辑如下,用户如自行写因子函数时可以做参考:
涉及到 row 系列函数 的计算,会解析为横截面引擎(
createCrossSectionalEngine
)。
如若计算中用到了
rolling
函数,会解析为时间序列聚合引擎(
createTimeSeriesEngine
)。
其余计算会解析为响应式状态引擎(
createReactiveStateEngine
)。
本小节以国泰君安 Alpha 第 1 号因子为例,演示如何调用 gtja191Alpha 模块,实现流计算:
首先定义输入输出的表结构:
inputSchema = table(
1
:
0
, [
"SecurityID"
,
"TradeTime"
,
"open"
,
"close"
,
"vol"
], [SYMBOL,TIMESTAMP,DOUBLE,DOUBLE,DOUBLE])
resultStream = table(
10000
:
0
, [
"SecurityID"
,
"TradeTime"
,
"factor"
], [SYMBOL,TIMESTAMP,DOUBLE])
调用 gtja191Alpha 模块,并在
streamEngineParser
中使用 gtjaAlpha1 函数:
use gtja191Alpha
metrics = <[SecurityID,gtjaAlpha1(open,close,vol)]>
streamEngine = streamEngineParser(name=
"gtjaAlpha1Parser"
, metrics=metrics, dummyTable=inputSchema, outputTable=resultStream, keyColumn=
"SecurityID"
, timeColumn=`tradetime, triggeringPattern=
'keyCount'
, triggeringInterval=
4000
)
部分因子可能会创建多个引擎,可以调用
getStreamEngineStat()
查看总共串联了哪些引擎:
getStreamEngineStat()
// output
ReactiveStreamEngine->
name user status lastErrMsg numGroups numRows numMetrics memoryInUsed snapshotDir ...
------------- ----------- ------ ---------- --------- ------- ---------- ------------ -----------
gtjaAlpha1P...guest OK
4000
84000
5
800928
...
gtjaAlpha1P...guest OK
4000
84000
2
1264872
...
CrossSectionalEngine->
name user status lastErrMsg numRows numMetrics metrics triggering...triggering......
------------ -------- ------ ------------ ---------- ---------- ------------ ------------------ --------------- ---
gtjaAlpha1...guest OK
4000
3
SecurityID...keyCount
4000
...
将数据注入引擎,即可在 resultStream 输出表中查看结果:
streamEngine.append!((select SecurityID, TradeTime, close, high, low from data order by TradeTime))
//check the result
res = exec factor from resultStream pivot by TradeTime, SecurityID
注意
:完整 国泰君安 191 Alpha 流计算流程代码可查看
国泰君安191Alpha流计算完整过程
。
4. 小结
本文介绍了
gtja191Alpha
模块的用法。该模块用 DolphinDB 内置函数实现了 国泰君安 191 Alpha 因子,具有简单便捷、批流一体的特点。
5. 附录
5.1. 附录1-因子入参一览表
因子序号
所需参数
因子序号
所需参数
因子序号
所需参数
15, 37, 54, 184, 185
open, close
119
open,vol,vwap
9, 68, 123
high,low,vol
55, 107, 137, 171
open,close,high,low
10, 14, 18, 19, 20, 21, 22, 23, 24, 27, 31, 34, 46, 53, 58, 63, 65, 66, 67, 71, 79, 86, 88, 89, 98, 106, 112, 116, 122, 127, 129, 135, 143, 146, 147, 151, 152, 153, 157, 160, 162, 165, 166, 167, 169, 173, 174, 183, 189, 190
close
77, 130
high,low,vol,vwap
140
open,close,high,low,vol
2, 3, 28, 47, 57, 59, 72, 78, 82, 96, 110, 126, 158, 159, 161, 164, 172, 175, 186
close,high,low
8, 13
high,low,vwap
1, 136
open,close,vol
11, 52, 60, 111, 115, 117, 128, 150, 176, 191
close,high,low,vol
5, 32, 42, 62, 83, 141
high,vol
39, 45
open,close,vol,vwap
114
close,high,low,vol,vwap
108
high,vol,vwap
12
open,close,vwap
104
close,high,vol
103
low
6, 187
open,high
101, 163, 170
close,high,vol,vwap
44, 61, 74, 138, 179
low,vol,vwap
118
open,high,low
33, 91
close,low,vol
80, 81, 97, 100, 102, 145, 155, 168
vol
56, 69
open,high,low,vol
4, 25, 29, 40, 43, 48, 76, 84, 85, 94, 99, 113, 134, 142, 178, 180
close,vol
16, 36, 70, 90, 95, 121, 132, 154
vol,vwap
87
open,high,low,vwap
7, 64, 73, 92, 125, 131, 144
close,vol,vwap
41
vwap
93
open,low
17, 26, 120, 124
close,vwap
30, 149, 181
close,index_close
156
open,low,vwap
38, 177
high
75, 182
close,open,index_close,index_open
35, 105, 139, 148
open,vol
49, 50, 51, 109, 133, 188
high,low
5.2. 附录2
国泰君安 191 Alpha 因子模块
下载日频数据文件
国泰君安191 Alpha 辅助模块
国泰君安191Alpha流计算完整过程
gtja191Alpha 模块调用脚本
FILE:references/doc_2628.md
# invNormal
**URL**: https://docs.dolphindb.cn/zh/funcs/i/invNormal.html
**来源**: DolphinDB 官方文档
---
invNormal
语法
invNormal(mean, stdev, X)
详情
返回均值为
mean
,标准差为
stdev
的正态分布的累计密度函数的逆函数值。
参数
mean
是正态分布的均值。
stdev
是正态分布的标准差。
X
是0到1之间的浮点型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
invNormal(0,1,0.33);
// output: -0.439913
invNormal(10, 20, [0.1, 0.2, 0.3]);
// output: [-15.631031, -6.832425, -0.48801]
FILE:references/doc_2646.md
# mstd
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mstd.html
**来源**: DolphinDB 官方文档
---
mstd
语法
mstd(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
的样本标准差。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
mstd(1 2 5 4 3, 3);
// output: [,,2.081666,1.527525,1]
mstd(1 2 5 4 3, 3, 2);
// output:
[,0.707107,2.081666,1.527525,1]
m=matrix(1 6 2 9 4 5, 11 12 18 23 21 10);
m;
#0
#1
1
11
6
12
2
18
9
23
4
21
5
10
mstd(m,3);
#0
#1
2.645751311064591
3.78593889720018
3.511884584284247
5.507570547286101
3.605551275463989
2.516611478423591
2.645751311064591
7
m=matrix(1 NULL 4 NULL 8 6 , 9 NULL NULL 10 NULL 2)
m.rename!(date(2020.04.06)+1..6, `col1`col2)
m.setIndexedMatrix!()
mstd(m,4d)
label
col1
col2
2020.04.07
2020.04.08
2020.04.09
2.1213
2020.04.10
2.1213
0.7071
2020.04.11
2.8284
2020.04.12
2
5.6569
mstd(m,1w)
label
col1
col2
2020.04.07
2020.04.08
2020.04.09
2.1213
2020.04.10
2.1213
0.7071
2020.04.11
3.5119
0.7071
2020.04.12
2.9861
4.3589
相关函数:
mmin
,
mmax
,
mavg
,
msum
,
mvar
FILE:references/doc_2649.md
# is null
**URL**: https://docs.dolphindb.cn/zh/progr/sql/isnull.html
**来源**: DolphinDB 官方文档
---
is null
用法
is null 谓词用于检测空值,其功能等价于 isNull 函数。
is not null 谓词用于检测非空值。
注意
:支持在分布式查询中使用。
例子
t= table(`a1`a2`a3`b1`b2`b3`c1`c2 as id, 7 4 NULL 1 8 NULL 12 NULL as val)
select id from t where val is null
// 等价于 select id from t where isNull(val)
id
a3
b3
c2
select id from t where val is not null
// 等价于 select id from t where not isNull(val)
id
a1
a2
b1
b2
c1
FILE:references/doc_2650.md
# qr
**URL**: https://docs.dolphindb.cn/zh/funcs/q/qr.html
**来源**: DolphinDB 官方文档
---
qr
语法
qr(obj, [mode='full'], [pivoting=false])
详情
计算矩阵的 QR(正交三角)分解,将矩阵分解成一个标准正交矩阵 Q 与上三角形矩阵 R。若输入矩阵为 A,结果满足
A=Q*R。
假设 A 的行数为 m,列数为 n:
若
mode
="full",返回矩阵 Q 与 R,形状分别为 m*m 和 m*n。
若
mode
="economic",返回矩阵 Q 与 R,形状分别为 m*k 和 k*n,其中
k=min(m,n)。
若
mode
="r",仅返回矩阵 R,形状为 m*n。
若
pivoting
=true,返回结果还包含一个与输入矩阵列数相同长度的向量 P。P
为置换矩阵的秩显,表示置换矩阵中1所在列的位置。
参数
obj
是一个矩阵。
mode
是一个字符串,表示返回信息的类型。它的取值可以是 "full", "economic", "raw" 或 "r"。默认值是 "full"。
pivoting
是一个布尔值,表示是否返回置换矩阵的秩显,默认值为 false。
返回值
元组或矩阵。
例子
A = matrix([2,5,7,5], [5,2,5,4], [8,2,6,4]);
Q,R = qr(A);
Q;
#0
#1
#2
#3
-0.197066
0.903357
0.300275
0.234404
-0.492665
-0.418267
0.459245
0.609449
-0.68973
-0.02475
0.170745
-0.703211
-0.492665
0.091573
-0.818398
0.281284
R;
#0
#1
#2
-10.148892
-7.38997
-8.670898
0
3.922799
6.608121
0
0
1.071571
0
0
0
Q,R=qr(A,mode='economic');
Q;
#0
#1
#2
-0.197066
0.903357
0.300275
-0.492665
-0.418267
0.459245
-0.68973
-0.02475
0.170745
-0.492665
0.091573
-0.818398
R;
#0
#1
#2
-10.148892
-7.38997
-8.670898
0
3.922799
6.608121
0
0
1.071571
Q,T,R=qr(A,mode='raw');
R;
#0
#1
#2
-10.148892
-7.38997
-8.670898
0.41156
3.922799
6.608121
0.576184
0.3046
1.071571
0.41156
0.156539
0.900419
T;
// output
[1.197066,1.790053,1.104512]
R
#0
#1
#2
-10.148892
-7.38997
-8.670898
0
3.922799
6.608121
0
0
1.071571
Q,T,R,P = qr(A,mode='raw',pivoting=true);
Q;
#0
#1
#2
-10.954451
-8.033264
-8.215838
0.105516
-6.20215
-1.45111
0.316548
0.37699
-0.627918
0.211032
0.284188
0.936372
T;
// output
[1.730297,1.635478,1.065648]
R
#0
#1
#2
-10.954451
-8.033264
-8.215838
0
-6.20215
-1.45111
0
0
-0.627918
P;
// output
[2,0,1]
FILE:references/doc_2663.md
# long
**URL**: https://docs.dolphindb.cn/zh/funcs/l/long.html
**来源**: DolphinDB 官方文档
---
long
语法
long(X)
详情
将
X
的数据类型转换为 LONG。
参数
X
可以是任意数据类型。
返回值
LONG 类型的结果。
例子
x=long();
x;
返回:null
typestr x;
返回:LONG
long(`10.9);
返回:10
long(9223372036854775807l);
返回:9,223,372,036,854,775,807
注:
LONG 数据类型的最大值是2
63
-1 =
9,223,372,036,854,775,807。
long(9223372036854775808l);
返回:9,223,372,036,854,775,807
FILE:references/doc_2664.md
# bvls
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bvls.html
**来源**: DolphinDB 官方文档
---
bvls
语法
bvls(Y, X, bounds, [maxIter], [tolerance=1e-10],
[intercept=true], [mode=0])
详情
执行有界变量最小二乘法(Bounded-Variable Least-Square)。
参数
Y
是一个数值型向量,表示因变量。
X
是一个数值型向量、元组、矩阵或表,表示自变量。
X
是矩阵时:
如果行数等于
Y
的长度,
X
的每一列都是一个因子。
如果行数不等于
Y
的长度,并且如果列数等于
Y
的长度,
X
的每一行都是一个因子。
注意:
X
与
Y
中的值会转为 DOUBLE 后进行运算,转换后的空值将被视为 0。
bounds
包含两个元素的元组,分别定义下界(lb)和上界(ub)。元组的元素可以是:
标量:为所有因子指定相同的边界值。
向量:向量长度等于因子数,分别为每个因子指定边界值。
maxIter
可选参数,正整数,表示最大迭代次数。如未定义,默认为变量的数量。
tolerance
可选参数,DOUBLE 类型,表示允许的误差,默认值为 1e-10 。如果相邻两次迭代的损失函数值的差值小于
tolerance
,或在
tolerance
误差下满足 Karush-Kuhn-Tucker 条件时,停止迭代。
intercept
可选参数,布尔值,表示是否在回归中包含截距。默认为 true。为 true 时,系统自动给 X 添加一列 1 以生成截距。
mode
可选参数,表示输出模式。目前仅支持 0 (默认),表示返回系数估计向量。
返回值
DOUBLE 向量,表示回归系数估计值。
例子
x1 = [1, 3, 5, 7, 11, 16, 23]
x2 = [2, 8, 11, 34, 56, 54, 100]
y = [0.1, 4.2, 5.6, 8.8, 22.1, 35.6, 77.2]
bounds = (0.0, 10.0)
bvls(y, x1, bounds)
// output: [0,2.717777777777778]
bvls(y, (x1, x2), bounds)
// output: [0,1.409643685501234,0.315943584131198]
相关函数:
ols
FILE:references/doc_2666.md
# isVoid
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isVoid.html
**来源**: DolphinDB 官方文档
---
isVoid
语法
isVoid(X)
详情
检查一个对象是否是 VOID 类型。有两种 VOID 类型的对象:一种是 NULL 对象;另一种是 Nothing 对象。参见
isNothing
。
参数
X
可以是系统支持的任意数据形式。
参数
布尔类型,数据形式同
X
。
例子
isVoid(NULL);
// output: true
isVoid(1 NULL 2);
// output: false
// 和 isNull 相比
isNull(1 NULL 2);
// output: [false,true,false]
isVoid(matrix(NULL 2 NULL, NULL 2 1))
// output: false
FILE:references/doc_2668.md
# createCrossSectionalEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createCrossSectionalEngine.html
**来源**: DolphinDB 官方文档
---
createCrossSectionalEngine
语法
createCrossSectionalEngine(name, [metrics], dummyTable,
[outputTable], keyColumn, [triggeringPattern='perBatch'],
[triggeringInterval=1000], [useSystemTime=true], [timeColumn],
[lastBatchOnly=false], [contextByColumn], [snapshotDir],
[snapshotIntervalInMsgCount], [raftGroup], [outputElapsedMicroseconds=false],
[roundTime=true], [keyFilter], [updatedContextGroupsOnly=false])
别名:
createCrossSectionalAggregator
详情
创建横截面引擎,返回一个以
keyColumn
作为键值的键值表。
该表记录了每组最新记录的时间戳(可以是数据自身的时间戳或者系统时间,由参数
timeColumn
和
useSystemTime
指定)。每次新数据的到来都会更新该表。若指定了
lastBatchOnly
=
true,此时引擎维护的键值表只会保留最新时间戳上不同组的数据。
如果没有指定
metrics
或
outputTable
,横截面引擎不会利用表中的数据进行任何运算和输出,仅更新表中记录。
如果指定了
metrics
和
outputTable
,横截面引擎会首先更新表中记录,然后对表中的最新记录进行运算,并把结果输出到
outputTable
中。
更多流数据引擎的应用场景说明可以参考
流计算引擎
。
计算规则
可选按数据量或时间触发计算。如果设置
triggeringPattern
=
“keyCount”,输入流数据表中时间列(
timeColumn
)所指示的时间戳必须递增;如果同时指定了分组列(
keyColumn
),组内数据的时间戳必须递增。否则,乱序数据将被直接丢弃,不参与计算。详情请参考
triggeringPattern
和
triggeringInterval
的参数说明。
注:
若指定了
contextByColumn
,则数据将按照指定字段分组后在组内进行计算。
引擎的其他功能
快照机制:启用快照机制之后,系统若出现异常,可及时将流数据引擎恢复到最新的快照状态。(详情请参考
snapshotDir
和
snapshotIntervalInMsgCount
的参数说明)
流数据引擎高可用:若要启用引擎高可用,需在订阅端 raft 组的 leader 节点创建引擎并通过
raftGroup
参数开启高可用。开启高可用后,当 leader 节点宕机时,会自动切换新 leader
节点重新订阅流数据表。(详情请参考
raftGroup
的参数说明)
参数
name
字符串标量,表示横截面引擎的名称,作为其在一个数据节点/计算节点上的唯一标识。可包含字母,数字和下划线,但必须以字母开头。
metrics
以元代码的格式表示计算指标,支持输入元组。有关元代码的更多信息可参考
元编程
。
计算指标可以是系统内置或用户自定义的函数,如 <[sum(qty), avg(price)]>;可以对计算结果使用表达式,如
<[avg(price1)-avg(price2)]>;也可以对多列进行运算,如 <[std(price1-price2)]>。
metrics
内支持调用具有多个返回值的函数,例如 <func(price) as `col1`col2>(可不指定列名)。
metrics
中使用的列名大小写不敏感,不要求与输入表的列名大小写保持一致。
dummyTable
一个表对象,和输入的流数据表的 schema 一致,可以含有数据,亦可为空表。从
3.00.2
版本开始
dummyTable
支持包含
array vector 类型列。
outputTable
计算结果的输出表,可以是内存表或分布式表。使用
createCrossSectionalEngine
函数之前,需要将输出表预先设立为一个空表,并指定各列列名以及数据类型。
如果没有指定
contextByColumn
, 则输出表各列的顺序如下:
第一列为 TIMESTAMP 类型,用于存放发生计算的时间戳(如果指定了
timeColumn
则是对应记录的时间戳);
计算结果列,可为多列。其数据类型必须与
metrics
返回结果的数据类型一致。
耗时列,存储引擎内每个 batch 的计算耗时(单位:微秒),数据类型为 LONG。仅在指定
outputElapsedMicroseconds
= true 时输出。
记录数列。存储引擎内每个 batch 的记录数,数据类型为 INT,仅在指定
outputElapsedMicroseconds
=
true 时输出。
如果指定
contextByColumn
, 则输出表各列的顺序如下:
第一列为 TIMESTAMP 类型,用于存放发生计算的时间戳(如果指定了
timeColumn
则是对应记录的时间戳);
第二列为
contextByColumn
指定的列;
计算结果列,可为多列。其数据类型必须与
metrics
返回结果的数据类型一致。
耗时列,存储引擎内每个 batch 的计算耗时(单位:微秒),数据类型为 LONG。仅在指定
outputElapsedMicroseconds
= true 时输出。
记录数列。存储引擎内每个 batch 的记录数,数据类型为 INT,仅在指定
outputElapsedMicroseconds
=
true 时输出。
keyColumn
字符串标量或向量,指定流数据表中某列的值为横截面引擎的键值。横截面引擎的计算时,仅使用每个键值对应的最新一行记录。
triggeringPattern
字符串标量,表示触发计算的方式,每触发一次计算,输出一条结果到输出表。该字符串可选值如下:
'perBatch':
triggeringPattern
的默认值。每插入一次数据触发一次计算。
'perRow':插入的每一行数据都会触发一次计算。
'interval':基于系统时间间隔触发计算。
'keyCount':若相同时间戳的数据分批次到达,则只有在当前时间戳的记录数达到
triggeringInterval
,或有更新时间戳的数据到达时,才会触发计算。使用该参数值时,必须指定
timeColumn
,且
useSystemTime
= false。若设置
triggeringPattern
= 'keyCount',收到的数据中出现的乱序数据会被丢弃,不参与计算。
'dataInterval':基于数据时间间隔触发计算。使用该参数值时,必须指定
timeColumn
,且指定
useSystemTime
= false。
triggeringInterval
整数或元组,触发计算规则如下:
triggeringPattern
取值为 'interval' 时,
triggeringInterval
是一个正整数,表示触发计算的时间间隔,单位为毫秒,默认值为 1000。每经过
triggeringInterval
指定的时间间隔,检查引擎中的数据是否被计算。若存在未被计算的数据,则触发一次计算。
triggeringPattern
取值为 'keyCount' 时:
triggeringInterval
可以是一个整数。设置后,在更新的时间戳的数据到来前,当前时间戳的记录数需要累积到
triggeringInterval
才会触发计算。
triggeringInterval
也可以是一个长度为 2 的
元组。元组的第一个元素是整数,表示触发计算的最新时间戳的记录数量。元组的第二个值可以是整数或者 duration 类型数据。假设设置
triggeringInterval
= (c1, c2):
当 c2 为整数时,若收到的最新时间戳 t1 的数据数量小于 c1,这批数据不会触发计算,系统可以继续缓存更新时间戳
t2(t2>t1) 的数据,当 t2 的数据量达到 c2 或者收到更新的时间戳 t3(t3>t2)
的数据时,会触发时间戳 t1 对应数据的计算。注意必须满足 c2 < c1。
当 c2 为 duration 时,若收到的最新时间戳 t1 的数据数量小于
c1,这批数据不会触发计算,系统收到更新的时间戳 t2(t2>t1) 的数据后,会等待 duration
指定的时间,若在此期间继续收到了 t1 的数据且满足 t1 时间戳的数据总量达到 c1,或者在此期间又收到了更新的时间戳
t3(t3>t2) 的数据,则直接触发 t1 对应数据的计算,等待时间结束后不再触发计算。否则,等待
duration 设置的时间后才会触发 t1 数据的计算。
triggeringPattern
取值为 'dataInterval' 时,
triggeringInterval
是一个正整数,单位和数据时间的单位一致,默认值为 1000。从第一条数据的时间戳开始一个窗口,窗口长度为
triggeringInterval
。一个窗口结束后到达的第一条数据会触发当前窗口内数据的计算输出。输出表的时间为窗口结束的时间戳。
注:
在
2.00.11.2
及之前版本,每个窗口都会输出。
从版本
2.00.11.3
起,仅当窗口内有数据插入时才会触发输出。
useSystemTime
可选参数,布尔值,表示是否使用数据注入引擎时的系统时间作为计算参照的时间列。
若
useSystemTime
= true,
outputTable
中第一列(时间列)为系统时间;
若
useSystemTime
= false,必须指定
timeColumn
,
outputTable
中第一列(时间列)为数据的时间戳。
timeColumn
是一个字符串。当
useSystemTime
= false
时,指定订阅的流数据表中时间列的名称。仅支持 TIMESTAMP 类型。
lastBatchOnly
可选参数。横截面引擎是否只保留最新时间戳上的数据。当
lastBatchOnly
= true 时,只能指定
triggeringPattern
=
'keyCount',此时横截面引擎维护的键值表只保存最新时间戳的键值数据;否则,更新并保留所有时间戳上的键值数据。
contextByColumn
可选参数,字符串标量或向量。设置后,将对横截面引擎中数据按照指定的字段或字段组合分组,并在组内进行指定计算。
设置该参数,必须指定
metrics
和
outputTable
.
如果
metrics
全为聚合函数,则分组计算结果和 groupby 分组计算结果一致,否则和 contextby
分组计算结果一致。
若要开启快照机制 (snapshot),必须指定
snapshotDir
与
snapshotIntervalInMsgCount
。
snapshotDir
可选参数,字符串,表示保存引擎快照的文件目录。
指定的目录必须存在,否则系统会提示异常。
创建流数据引擎时,如果指定了
snapshotDir
,会检查该目录下是否存在快照。如果存在,会加载该快照,恢复引擎的状态。
多个引擎可以指定同一个目录存储快照,用引擎的名称来区分快照文件。
一个引擎的快照可能会使用三个文件名:
临时存储快照信息:文件名为 <engineName>.tmp;
快照生成并刷到磁盘:文件保存为 <engineName>.snapshot;
存在同名快照:旧快照自动重命名为 <engineName>.old。
snapshotIntervalInMsgCount
可选参数,为整数类型,表示每隔多少条数据保存一次流数据引擎快照。
raftGroup
是流数据高可用订阅端 raft 组的 ID (大于 1 的整数,由流数据高可用相关的配置项
streamingRaftGroups
指定)。设置该参数表示开启计算引擎高可用。在 leader 节点创建流数据引擎后,会同步在
follower 节点创建该引擎。每次保存的 snapshot 也会同步到 follower。当 raft 组的 leader 节点宕机时,会自动切换新 leader
节点重新订阅流数据表。注意,若要指定
raftGroup
,必须同时指定
snapshotDir
。
outputElapsedMicroseconds
布尔值,表示是否输出每个 batch 中数据从注入引擎到计算输出的总耗时,以及每个 batch
包含的总记录数,默认为 false,不输出。
注:
outputElapsedMicroseconds
= true 时,若同时指定
useSystemTime
=true,则
metrics
中不可使用聚合函数。
roundTime
可选参数,布尔值。用于对第一个数据窗口的起始时间进行规整,仅在
triggeringPattern
=dataInterval 时有效。系统将根据该参数、triggeringInterval
和时间精度来确定规整尺度(alignmentSize)。窗口规整规则同
时序引擎
。
keyFilter
可选参数,以元代码形式表示的过滤条件。过滤条件是一个表达式或者函数调用,应用于截面数据中的列(列值为
key),返回一个布尔向量。引擎会从截面数据中过滤出 key 满足条件的数据进行计算。
updatedContextGroupsOnly
可选参数,布尔标量,默认值为 false。决定是否仅计算相较上次输出存在更新的分组数据。
返回值
一个表。
例子
例1. 横截面引擎 csEngineDemo1 触发计算的方式为 "perRow"。6 行数据写入流数据表 trades1,结果亦为
6 行。
share streamTable(10:0,`time`sym`price`volume,[TIMESTAMP,SYMBOL,DOUBLE,INT]) as trades1
share table(1:0, `time`avgPrice`volume`dollarVolume`count, [TIMESTAMP,DOUBLE,INT,DOUBLE,INT]) as outputTable
csEngine1=createCrossSectionalEngine(name="csEngineDemo1", metrics=<[avg(price), sum(volume), sum(price*volume), count(price)]>, dummyTable=trades1, outputTable=outputTable, keyColumn=`sym, triggeringPattern="perRow", useSystemTime=false, timeColumn=`time)
subscribeTable(tableName="trades1", actionName="tradesStats", offset=-1, handler=append!{csEngine1}, msgAsTable=true)
insert into trades1 values(2020.08.12T09:30:00.000 + 123 234 456 678 890 901, `A`B`A`B`B`A, 10 20 10.1 20.1 20.2 10.2, 20 10 20 30 40 20);
select * from trades1;
time
sym
price
volume
2020.08.12T09:30:00.123
A
10
20
2020.08.12T09:30:00.234
B
20
10
2020.08.12T09:30:00.456
A
10.1
20
2020.08.12T09:30:00.678
B
20.1
30
2020.08.12T09:30:00.890
B
20.2
40
2020.08.12T09:30:00.901
A
10.2
20
select * from outputTable;
time
avgPrice
volume
dollarVolume
count
2020.08.12T09:30:00.123
10
20
200
1
2020.08.12T09:30:00.234
15
30
400
2
2020.08.12T09:30:00.456
15.05
30
402
2
2020.08.12T09:30:00.678
15.1
50
805
2
2020.08.12T09:30:00.890
15.15
60
1010
2
2020.08.12T09:30:00.901
15.2
60
1012
2
例2. 横截面引擎 csEngineDemo2 触发计算的方式为 "perBatch"。数据分为 2 个批次写入流数据表
trades2,结果为 2 行。
share streamTable(10:0,`time`sym`price`volume,[TIMESTAMP,SYMBOL,DOUBLE,INT]) as trades2
share table(1:0, `time`avgPrice`volume`dollarVolume`count, [TIMESTAMP,DOUBLE,INT,DOUBLE,INT]) as outputTable
csEngine2=createCrossSectionalEngine(name="csEngineDemo2", metrics=<[avg(price), sum(volume), sum(price*volume), count(price)]>, dummyTable=trades2, outputTable=outputTable, keyColumn=`sym, triggeringPattern="perBatch", useSystemTime=false, timeColumn=`time)
subscribeTable(tableName="trades2", actionName="tradesStats", offset=-1, handler=append!{csEngine2}, msgAsTable=true)
insert into trades2 values(2020.08.12T09:30:00.000 + 123 234 456, `A`B`A, 10 20 10.1, 20 10 20);
sleep(1)
insert into trades2 values(2020.08.12T09:30:00.000 + 678 890 901, `B`B`A, 20.1 20.2 10.2, 30 40 20);
select * from outputTable;
time
avgPrice
volume
dollarVolume
count
2020.08.12T09:30:00.456
15.05
30
402
2
2020.08.12T09:30:00.901
15.2
60
1012
2
例3. 横截面引擎 csEngineDemo4 触发计算的方式为 "keyCount"。设置
lastBatchOnly
= true,只有最新时间戳上的数据会参与计算。因为
metrics
里聚合函数和非聚合函数混合使用,所以,输出记录行数等于输入记录行数,聚合结果重复输出多行。
share streamTable(10:0,`time`sym`price`volume,[TIMESTAMP,SYMBOL,DOUBLE,INT]) as trades1
share table(1:0, `time`factor1`factor2, [TIMESTAMP, DOUBLE,INT]) as outputTable
agg=createCrossSectionalAggregator(name="csEngineDemo4", metrics=<[price+ 0.1, sum(volume)]>, dummyTable=trades1, outputTable=outputTable, keyColumn=`sym, triggeringPattern="keyCount", triggeringInterval=5, useSystemTime=false, timeColumn=`time,lastBatchOnly=true)
subscribeTable(tableName=`trades1, actionName="csEngineDemo4", msgAsTable=true, handler=append!{agg})
num=10
time=array(TIMESTAMP)
time=take(2018.01.01T09:30:00.000,num)
sym=take("A"+string(1..10),num)
price=1..num
volume=1..num
tmp=table(time, sym, price, volume)
trades1.append!(tmp)
// 第二次输入 5 条数据,lastBatchOnly=true,所以只有最新的 5 条数据参与计算。
num=5
time = array(TIMESTAMP)
time=take(2018.01.01T09:30:01.000,num)
sym=take("A"+string(1..10),num)
price=6..10
volume=6..10
tmp=table(time, sym, price, volume)
trades1.append!(tmp)
time
factor1
factor2
2018.01.01T09:30:00.000
1.1
55
2018.01.01T09:30:00.000
2.1
55
2018.01.01T09:30:00.000
3.1
55
2018.01.01T09:30:00.000
4.1
55
2018.01.01T09:30:00.000
5.1
55
2018.01.01T09:30:00.000
6.1
55
2018.01.01T09:30:00.000
7.1
55
2018.01.01T09:30:00.000
8.1
55
2018.01.01T09:30:00.000
9.1
55
2018.01.01T09:30:00.000
10.1
55
2018.01.01T09:30:01.000
6.1
40
2018.01.01T09:30:01.000
7.1
40
2018.01.01T09:30:01.000
8.1
40
2018.01.01T09:30:01.000
9.1
40
2018.01.01T09:30:01.000
10.1
40
例4. 横截面引擎 csEngineDemo3 触发计算的方式为 "interval",每 500
毫秒触发一次计算。向流数据表中写入6行数据,第一次批量写入,间隔 500 毫秒后再次写入。请注意,这里没有指定
useSystemTime
参数为
false,会返回计算发生的时刻。
share streamTable(10:0,`time`sym`price`volume,[TIMESTAMP,SYMBOL,DOUBLE,INT]) as trades3
share table(1:0, `time`avgPrice`volume`dollarVolume`count, [TIMESTAMP,DOUBLE,INT,DOUBLE,INT]) as outputTable
csEngine3=createCrossSectionalEngine(name="csEngineDemo3", metrics=<[avg(price), sum(volume), sum(price*volume), count(price)]>, dummyTable=trades3, outputTable=outputTable, keyColumn=`sym, triggeringPattern="interval", triggeringInterval=500)
subscribeTable(tableName="trades3", actionName="tradesStats", offset=-1, handler=append!{csEngine3}, msgAsTable=true);
insert into trades3 values(2020.08.12T09:30:00.000, `A, 10, 20)
insert into trades3 values(2020.08.12T09:30:00.000 + 500, `B, 20, 10)
insert into trades3 values(2020.08.12T09:30:00.000 + 1000, `A, 10.1, 20)
insert into trades3 values(2020.08.12T09:30:00.000 + 2000, `B, 20.1, 30)
sleep(500)
insert into trades3 values(2020.08.12T09:30:00.000 + 2500, `B, 20.2, 40)
insert into trades3 values(2020.08.12T09:30:00.000 + 3000, `A, 10.2, 20);
sleep(500)
select * from outputTable;
time
avgPrice
volume
dollarVolume
count
2022.03.02T11:17:02.341
15.1
50
805
2
2022.03.02T11:17:02.850
15.2
60
1,012
2
triggeringPattern
= "interval" 时,系统每隔 500ms 触发一次计算,输出一条结果。在计算被触发时,即使同一个 key
有多条记录未被计算,系统也只取最新时间戳上的数据进行计算。
例5. 在股票数据中,有些股票在某一时刻之后就不再更新数据了,此时可通过
keyFilter
参数指定过滤条件。当之后收到其它股票数据并触发截面计算时不会计算该股票的数据。以在截面引擎中过滤出1小时内未更新的数据为例:
// 定义休市和过滤数据的逻辑
def checkTime(time){
maxTime = max(time)
if(between(maxTime, 2024.05.22T13:00:00.000:2024.05.22T13:30:00.000)){
return time > maxTime - 120*60*1000
} else{
return time > maxTime - 30*60*1000
}
}
// 定义截面引擎
share streamTable(10:0,`time`sym`price`volume,[TIMESTAMP,SYMBOL,DOUBLE,INT]) as trades1
t=keyedTable(`sym,10:0,`time`sym`price`volume,[TIMESTAMP,SYMBOL,DOUBLE,INT])
share table(1:0, `time`factor1`factor2, [TIMESTAMP, DOUBLE, DOUBLE]) as outputTable
// 指定 keyFilter 为一个函数,过滤出1小时内未更新的数据。
csEngine5=createCrossSectionalEngine(name="csEngineDemo5", metrics=<[avg(price), sum(volume)]>, dummyTable=trades1, outputTable=outputTable, keyColumn=`sym, keyFilter=<checkTime(time)>)
// 模拟数据,A1 从 2024.05.22T09:32:00.000 之后未收到新的数据
time = 2024.05.22T09:30:00.000 join 2024.05.22T09:31:00.000 join 2024.05.22T09:32:00.000 join 2024.05.22T13:30:00.000 join 2024.05.22T13:31:00.000
sym=`A1`A2`A1`A2`A2
price=100.0 100.5 100.3 100.8 100.6
volume=100 110 112 200 120
tmp=table(time, sym, price, volume)
csEngine5.append!(tmp)
// 查看截面引擎中的数据
select * from csEngine5
time
sym
price
volume
2024.05.22T09:32:00.000
A1
100.3
112
2024.05.22T13:31:00.000
A2
100.6
120
上面代码通过
keyFilter
找到截面引擎中仅 A2 的数据满足要求,因此结果表中仅 A2
的数据参与了计算。
select * from outputTable
time
factor1
factor2
2024.05.22T05:11:12.259
100.6
120
在以上的例子中,
createCrossSectionalEngine
的返回结果(以下称为横截面表)是为计算提供的一个中间结果,但横截面表亦可为最终结果。例如若需要定时刷新某只股票的最新交易价格,
按照常规思路是从实时交易表中按代码筛选股票并取出最后一条记录,而交易表的数据量是随着时间快速增长的,如果频繁做这样的查询,无论从系统的资源消耗还是从查询的效能来看都不是最优的做法。
而横截面表永远只保存所有股票的最近一次交易数据,数据量是稳定的,对于这种定时轮询的场景非常合适。
要将横截面表作为最终结果,需要在对
createCrossSectionalEngine
中的
metrics
与
outputTable
这两个参数置空。
tradesCrossEngine=createCrossSectionalEngine(name="CrossSectionalDemo", dummyTable=trades, keyColumn=`sym, triggeringPattern=`perRow)
例6. 按照 volume 分组,引擎每插入一行数据,就触发一次计算。
try {
dropAggregator(`csEngineDemo)
} catch(ex) {}
try {
dropStreamTable(`trades1)
} catch(ex) {}
share streamTable(10:0, `time`sym`price`volume, [SECOND, SYMBOL, DOUBLE, INT]) as trades1
outputTable = table(1:0, `time`volume`factor1`factor2, [SECOND, INT, DOUBLE, DOUBLE])
agg1 = createCrossSectionalEngine(
name="csEngineDemo",
metrics=<[avg(price), sum(volume)]>,
dummyTable=trades1,
outputTable=outputTable,
keyColumn=`sym,
triggeringPattern="perRow",
useSystemTime=false,
timeColumn=`time,
outputElapsedMicroseconds=false,
contextByColumn=`volume,
updatedContextGroupsOnly=false
)
num = 4
time = take(09:30:00, num)
sym = take(`A1`B1`C1`D1, num)
price = rand(100.0, num)
volume = take(1 1 2 2, num)
tmp = table(time, sym, price, volume)
agg1.append!(tmp)
outputTable
以上创建的引擎根据 volume 分组后得到 1 和 2 两个分组。由于设置了
updatedContextGroupsOnly
=
false,引擎不会检查各个分组的数据是否有更新。每当插入一行数据时,都会触发所有分组的计算和输出,因此, outputTable 中将输出 6 行数据。
time
volume
factor1
factor2
09:30:00
1
82.3447
1
09:30:00
1
69.9793
2
09:30:00
1
69.9793
2
09:30:00
2
95.262
2
09:30:00
1
69.9793
2
09:30:00
2
80.5988
4
try{dropAggregator(`csEngineDemo)}catch(ex){}
try{dropStreamTable(`trades1)}catch(ex){}
share streamTable(10:0,`time`sym`price`volume,[SECOND,SYMBOL,DOUBLE,INT]) as trades1
outputTable = table(1:0, `time`volume`factor1`factor2, [SECOND, INT, DOUBLE, DOUBLE])
agg1=createCrossSectionalEngine(name="csEngineDemo", metrics=<[avg(price), sum(volume)]>, dummyTable=trades1, outputTable=outputTable, keyColumn=`sym, triggeringPattern="perRow",useSystemTime=false, timeColumn=`time, outputElapsedMicroseconds=false, contextByColumn=`volume, updatedContextGroupsOnly=false)
num=4
time = take(09:30:00, num)
sym= take(`A1`B1`C1`D1, num)
price=rand(100.0, num)
volume=take(1 1 2 2, num)
tmp=table(time, sym, price, volume)
agg1.append!(tmp)
outputTable
设置
updatedContextGroupsOnly
= true 后,引擎将仅计算本次插入的分组数据,因此,outputTable 中将输出 4
行数据。
time
volume
factor1
factor2
09:30:00
1
54.6926
1
09:30:00
1
40.5904
2
09:30:00
2
73.1741
2
09:30:00
2
46.0153
4
FILE:references/doc_2686.md
# dropTable
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropTable.html
**来源**: DolphinDB 官方文档
---
dropTable
语法
dropTable(dbHandle, tableName)
详情
删除指定的表。该命令只能在数据节点/计算节点上执行,不能在控制节点和代理节点上执行。
参数
dbHandle
是数据库句柄。
tableName
是一个字符串,表示表名。
返回值
无。
例子
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x)
db=database("dfs://rangedb", RANGE, 0 5 10)
pt = db.createPartitionedTable(t, `pt, `ID)
pt.append!(t)
dropTable(db,`pt);
FILE:references/doc_2687.md
# window
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/window.html
**来源**: DolphinDB 官方文档
---
window
语法
window(func, funcArgs, range)
详情
应用函数/运算符到给定对象的滑动窗口。对给定对象的每一个元素,滑动窗口由
range
决定。结果的维度与
funcArgs
的维度相同(若
funcArgs
是一个元组, 结果的维度与该元组中每个元素的维度相同)。
滑动窗口的确定规则(假设
range
参数为 d1:d2):
若
funcArgs
为向量,
range
必须为整型。对
funcArgs
中第 i 位的元素,窗口所含元素的位置区间为 [i+d1, i+d2] 。
若
funcArgs
为索引序列或索引矩阵:
若
funcArgs
的索引为时间类型,对
funcArgs
中索引为
fi 的元素,其对应的窗口索引范围为 [temporalAdd(fi, d1), temporalAdd(fi, d2)]。
若
funcArgs
的索引为整型,
range
必须亦为整型。对
funcArgs
中索引为 fi 的元素,其对应的窗口索引范围为 [fi+d1, fi+d2] 。
与
moving
函数相比,
window
函数具有更灵活的窗口。
moving
可以视为
window
指定
range
右边界为 0 的特殊情况。但需要注意以下两点:
元素个数决定窗口长度时,窗口内元素个数不足时,
moving
函数将输出空值,但
window
会输出计算结果。
时间长度决定窗口长度时,
moving
确定的窗口左开右闭,但
window
确定窗口左闭右闭。详见以下说明:
假定索引类型为 DATETIME, 需要指定一个长度为 “3d” 的窗口进行滑动窗口计算。对于索引中的某个时间点
“2022.01.05T09:00:00”,
moving
函数根据该时间点确定的窗口为
(2022.01.02T09:00:00,2022.01.05T09:00:00],
window
指定
range
为 “-2d:0d”, 确定的窗口为 [2022.01.03T09:00:00,2022.01.05T09:00:00]。
参数
func
是一个聚合函数。
funcArgs
是
func
的参数。
func
有多个参数时,它是一个元组。
range
是一个整型数据对或 DURATION 数据对,左右边界都包含在内。
注:
如果
range
是 DURATION 类型,则
funcArgs
必须是一个索引矩阵(indexed matrix)或者是索引序列(indexed series)。
返回值
一个向量,其类型由第一个窗口的计算结果类型决定。
例子
funcArgs
为向量, 确定窗口位置区间为 [i+1,i+3], i 是 x 的下标。
x = 5 4 NULL -1 2 4
window(min, x, 1:3)
// output
[-1, -1, -1, 2, 4, ]
y = 4.8 9.6 7.1 3.3 5.9 2.7
window(corr, (x, y), 1:3)
// output
[1, 1, -0.623, -1, , ]
funcArgs
为索引序列, 索引为时间类型,确定的窗口范围为 [temporalAdd(ti, 1d), temporalAdd(ti, 3d)],ti
是 t 第 i 个元素对应的值。
t = 2021.01.02 2021.01.05 2021.01.06 2021.01.09 2021.01.10 2021.01.12
x1 = indexedSeries(t, x)
window(min, x1, 1d:3d)
label
col1
2021.01.02
4
2021.01.05
2021.01.06
-1
2021.01.09
2
2021.01.10
4
2021.01.12
funcArgs
为索引矩阵, 索引为时间,确定索引对应的窗口范围 [temporalAdd(ti, 1d), temporalAdd(ti,
3d)],ti 是 t 第 i 个元素对应的值。 以 a, b 列分组进行滑动窗口计算。
t= 2021.01.02 2021.01.05 2021.01.06 2021.01.09 2021.01.10 2021.01.12
m=matrix(5 4 NULL -1 2 4, 3 2 8 1 0 5)
m1=m.rename!(t, `a`b).setIndexedMatrix!()
window(min, m1, 1d:3d)
label
a
b
2021.01.02
4
2
2021.01.05
8
2021.01.06
-1
1
2021.01.09
2
0
2021.01.10
4
5
2021.01.12
t1 = table(`A`A`B`B`C`C as sym, 09:56:03 09:56:07 09:56:02 09:56:05 09:56:04 09:56:06 as time, 10.6 10.7 20.6 11.6 11.7 19.6 as price)
select *, window(avg, t1.time.indexedSeries(t1.price), 2s:4s) from t1 context by sym
sym
time
price
window_avg
A
09:56:03
10.6
10.7
A
09:56:07
10.7
B
09:56:02
20.6
11.6
B
09:56:05
11.6
C
09:56:04
11.7
19.6
C
09:56:06
19.6
FILE:references/doc_2697.md
# setMaxMemSize
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setMaxMemSize.html
**来源**: DolphinDB 官方文档
---
setMaxMemSize
语法
setMaxMemSize(memSizeGB, [emergencyMemSizeGB])
详情
在线修改可以分配给 DolphinDB 的最大内存空间和紧急内存区大小。该命令只能由管理员执行。可通过
getClusterPerf().maxMemSize 查看修改后的设置是否生效。
当动态设置最大内存空间 (即配置项
maxMemSize
)后,若用户不进行其他修改,系统会自动调整小内存分配区(reservedMemSize)和紧急内存区(emergencyMemSize)大小:
小内存分配区将调整为传入的
memSizeGB
的5%,最小不低于64M、最大不超过 1G。
紧急内存区(如果没有指定)调整为
memSizeGB
的5%,最小不低于 256M,最大不超过 5G。
关于 DolphinDB 内存管理相关配置参数及策略,参见
功能配置-内存
。
注:
此命令修改的配置值在系统重启后将失效。若需要配置值永久生效,请更改配置文件中的
maxMemSize
和
emergencyMemSize
。
参数
memSizeGB
一个数值型标量(单位为 GB),必须大于0且不能大于 DolphinDB 的许可证文件配置的
maxMemoryPerNode
(通过函数
license
查看),否则系统会报错。
emergencyMemSizeGB
可选参数,一个数值型标量(单位为 GB),用于在线修改紧急内存区的大小,必须大于 0 且小于
memSizeGB
的 50%
。
最小不低于
256 M,最大不能超过5G。
若不指定,默认保持配置项
emergencyMemSize
的值不变。
FILE:references/doc_2698.md
# datetime
**URL**: https://docs.dolphindb.cn/zh/funcs/d/datetime.html
**来源**: DolphinDB 官方文档
---
datetime
语法
datetime(X)
详情
返回日期和精确到秒的时间值。如果参数
X
中未包含前述时间类型标量或向量,则返回值是 1970.01.01 +
X
秒的日期与时间。
注:
DATETIME 类型的可用时间范围是 [1901.12.13T20:45:53, 2038.01.19T03:14:07]。
自 2.00.12 版本起,支持转换 MONTH 类型的数据。
参数
X
可以是时间标量或向量,或整数。
返回值
返回一个 DATETIME 类型的标量或向量。
例子
datetime(1)
返回:1970.01.01 00:00:01
datetime(2009.11.10);
返回:2009.11.10 00:00:00
typestr datetime(2009.11.10);
返回:DATETIME
datetime(now());
返回:2024.02.22 15:55:39
datetime(2012.01M)
返回:2012.01.01T00:00:00
FILE:references/doc_2699.md
# getUserList
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getUserList.html
**来源**: DolphinDB 官方文档
---
getUserList
语法
getUserList()
详情
返回包含除管理员之外的所有用户名称的向量。
注:
该函数只能由管理员在控制节点、数据节点和计算节点运行。
返回值
字符串向量。
例子
login(`admin, `123456);
getUserList().sort();
// output: ["AA","AAA","BB","BBB","CC","DeionSanders","EliManning","JoeFlacco"]
FILE:references/doc_2713.md
# mskew
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mskew.html
**来源**: DolphinDB 官方文档
---
mskew
语法
mskew(X, window, [biased=true], [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
的斜度。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
biased
是一个布尔值,表示是否是有偏估计。默认值为 true,表示有偏估计。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
mskew(1 2 3 10 100 4 3, 3);
// output
[,,0,0.665469,0.693810, 0.697217,0.706851]
m=matrix(1 6 2 9 4 5 100, 100 11 12 18 23 21 10);
m;
#0
#1
1
100
6
11
2
12
9
18
4
23
5
21
100
10
mskew(m,3);
#0
#1
0.595170064139498
0.706802122668126
-0.172800544078651
0.65201211704403
0.470330460336986
-0.110780117654834
0.595170064139498
-0.239063146929565
0.706845142811354
-0.642723256123865
m.rename!(date(2020.04.06)+1..7, `col1`col2)
m.setIndexedMatrix!()
mskew(m, 3d)
label
col1
col2
2020.04.07
2020.04.08
0
0
2020.04.09
0.5952
0.7068
2020.04.10
-0.1728
0.652
2020.04.11
0.4703
-0.1108
2020.04.12
0.5952
-0.2391
2020.04.13
0.7068
-0.6427
mskew(m, 1w)
label
col1
col2
2020.04.07
2020.04.08
0
0
2020.04.09
0.5952
0.7068
2020.04.10
0.2743
1.1373
2020.04.11
0.4079
1.4398
2020.04.12
0.3298
1.7107
2020.04.13
2.0188
1.9363
相关函数:
skew
FILE:references/doc_2718.md
# 数据库
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/cfg/db_intro.html
**来源**: DolphinDB 官方文档
---
数据库
DolphinDB 是一款高性能分布式时序数据库,采用分布式架构作为基础,在此基础上实现了多模态存储、支持 ACID
事务特性,并通过 MVCC 进行多版本并发控制,其在海量数据的存储、查询以及计算的性能上具有显著优势。
DolphinDB 有两种运行模式:单实例模式和集群模式。
单实例模式仅有一个数据节点,无计算节点、控制节点和代理节点。
集群模式包含四种角色:控制节点、代理节点、数据节点和计算节点。
控制节点。一个集群可以有一个或多个控制节点。控制节点是 DolphinDB
集群的核心部分。它负责收集代理/数据节点/计算节点的心跳,监控每个节点的工作状态,管理分布式文件系统的元数据和事务。
代理节点。代理节点负责执行控制节点发出的启动和关闭数据/计算节点的命令。在一个集群中,每台物理服务器有且仅有一个代理节点。
数据节点。在数据节点上可以进行数据存储和查询操作(或更加复杂的计算)。每台物理服务器可以配置多个数据节点。
计算节点。只用于计算的节点,应用于包括流计算、分布式关联、机器学习等场景。计算节点不存储数据,但可以在该节点上执行建库建表语句,系统会在数据节点上创建数据库。计算节点可以通过
loadTable
加载数据进行计算。
在集群模式下,代理节点、数据节点和计算节点默认通过 UDP 广播,用户也可以修改配置参数 lanCluster=0 来启用 TCP
广播。代理节点、数据节点和计算节点每秒钟发送一次心跳给控制节点,以确认其存活状态。如果控制节点连续 3 秒没有收到某一节点的心跳,就认为该节点已掉线。
单实例模式和集群模式的数据模型并无差异,并且都支持事务。两者的区别在于,集群模式支持高可用等。本章将重点介绍 DolphinDB
数据库相关的操作、分布式架构具备的关键功能、以及多种存储引擎的实现原理和适用场景,以帮助用户全面了解并合理利用 DolphinDB。
FILE:references/doc_2720.md
# linprog
**URL**: https://docs.dolphindb.cn/zh/funcs/l/linprog.html
**来源**: DolphinDB 官方文档
---
linprog
语法
linprog(f, [A], [b], [Aeq], [beq], [lb], [ub], [method='simplex'])
详情
求线性目标函数在约束条件下的最优解。具体模型如下:
参数
f
是线性规划中的一次项向量。
A
是线性不等约束的系数矩阵。
b
是线性不等约束的右端向量。
Aeq
是线性等式约束的系数矩阵。
beq
是线性等式约束的右端向量。
lb
表示变量的下界。
ub
表示变量的上界。
method
是字符串,表示算法,目前支持 'simplex' 和 'interior-point'。推荐使用
simplex 算法,部分特殊场景下建议使用 interior-point 算法。
linprog 函数的参数有以下要求:
A
和
Aeq
必须是列数相同的矩阵
f
,
b
和
beq
是向量
lb
和
ub
可以是标量,也可以是和x等长的向量。
若
lb
或
ub
是标量,则所有变量都受同一个下界或上界约束。若
lb
或
ub
为NULL,表示x无相应的下界或上界约束。
若
lb
或
ub
是向量,则x中的元素受
lb
或
ub
中相应位置的元素约束。若向量
lb
或
ub
中某元素为NULL,表示此位置的x元素无相应的下界或上界约束
返回值
返回具有两个元素的元组。第一个元素是目标函数的最小值,第二个元素是目标函数取最小值时,x的取值。
例子
例1. 求 x,y 满足以下约束条件时,目标函数 x+2y 的最小值。
f = [1, 2];
A = [-1, -1]$1:2;
b = [-2];
ub = 2;
re = linprog(f, A, b, , , , ub);
re[0];
// output
2
re[1];
// output
[2,0]
下面详细解释如何获取上例中的 A, b 和 ub。不等式约束条件为
x+y>=2,而模型中的不等式约束条件的符号为<=,因此需要转换成 -x-y<=-2。因此,不等式约束条件的系数矩阵为
[-1,-1]$1:2,不等式约束条件的右端向量为-2。变量 x, y 的上界都是2,因此 ub 可用标量表示。
例2. 求 x,y 满足以下约束条件时,目标函数 -3x1-2x2 的最小值。
f = [-3, -2];
A = [2, 1, 1, 1]$2:2;
b = [10, 8];
ub = [4, NULL];
re = linprog(f, A, b, , , , ub);
re[0];
// output
-18
re[1];
// output
[2,6]
相关函数:
scs
,
quadprog
FILE:references/doc_2722.md
# msum
**URL**: https://docs.dolphindb.cn/zh/funcs/m/msum.html
**来源**: DolphinDB 官方文档
---
msum
语法
msum(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
的元素和。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
X = 2 1 3 7 6 5 4
Y = 2 1 3 NULL 6 5 4
msum(X, 3);
// output: [,,6,11,16,18,15]
msum(Y, 3);
// output: [,,6,4,9,11,15]
msum(Y, 3, minPeriods=1);
// output: [2,3,6,4,9,11,15]
m = matrix(1 NULL 4 NULL 8 6 , 9 NULL NULL 10 NULL 2)
m.rename!(date(2020.04.06)+1..6, `col1`col2)
m.setIndexedMatrix!()
msum(m, 3d) // 等价于 msum(m, 3)
label
col1
col2
2020.04.07
1
9
2020.04.08
1
9
2020.04.09
5
9
2020.04.10
4
10
2020.04.11
12
10
2020.04.12
14
12
msum(m, 1w)
label
col1
col2
2020.04.07
1
9
2020.04.08
1
9
2020.04.09
5
9
2020.04.10
5
19
2020.04.11
13
19
2020.04.12
19
21
相关函数:
sum
FILE:references/doc_2746.md
# getInstrumentNominalCouponRate
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentnominalcouponrate.html
**来源**: DolphinDB 官方文档
---
getInstrumentNominalCouponRate
语法
getInstrumentNominalCouponRate(instrument)
详情
根据输入的金融工具,获取该工具的名义票面利率。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DOUBLE 类型标量或向量。
例子
futures = {
"productType": "Futures",
"futuresType": "BondFutures",
"version": 0,
"instrumentId": "T2509",
"nominal": 100.0,
"maturity": "2022.09.09",
"settlement": "2022.09.11",
"underlying": bond,
"nominalCouponRate": 0.03
}
instrument = parseInstrument(futures)
getInstrumentNominalCouponRate(instrument)
// output: 0.03
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_275.md
# localtime
**URL**: https://docs.dolphindb.cn/zh/funcs/l/localtime.html
**来源**: DolphinDB 官方文档
---
localtime
语法
localtime(X)
详情
把零时区时间
X
转换成本地时间。
参数
X
可以是 DATETIME, TIMESTAMP, NANOTIMESTAMP
类型的标量、向量或表,表示零时区时间。
返回值
返回值的类型和形式与
X
保持一致。
例子
以下例子在美国东部时区执行:
localtime(2018.01.22T15:20:26);
// output
2018.01.22T10:20:26
localtime(2017.12.16T18:30:10.001);
// output
2017.12.16T13:30:10.001
FILE:references/doc_2752.md
# log1p
**URL**: https://docs.dolphindb.cn/zh/funcs/l/log1p.html
**来源**: DolphinDB 官方文档
---
log1p
语法
log1p(X)
详情
返回 log(1+X) 的结果。
参数
X
可以是标量、向量、数据对、矩阵或表。
返回值
返回数值类型的结果,形式与
X
一致。
例子
log1p(2);
// output
1.098612
log1p(2 4 6);
// output
[1.098612,1.609438,1.94591]
log1p(1..4$2:2);
#0
#1
0.693147
1.386294
1.098612
1.609438
FILE:references/doc_276.md
# saveAsNpy
**URL**: https://docs.dolphindb.cn/zh/funcs/s/saveAsNpy.html
**来源**: DolphinDB 官方文档
---
saveAsNpy
语法
saveAsNpy(obj, fileName)
详情
将一个 DolphinDB 向量或矩阵保存为 Python Numpy 支持的 npy 格式的二进制文件。该函数必须要用户登录后才能执行。
注:
obj
中的 NULL 值会转换为负无穷(-inf)。
参数
obj
是一个数值向量或矩阵。
fileName
是服务器端输出文件的绝对路径或相对路径。
例子
v = 1..1000
v.saveAsNpy("/home/DolphinDB/intVec.npy")
m = (1..1000 + 0.5)$20:50
m.saveAsNpy("/home/DolphinDB/doubleMat.npy")
在 Python 中加载保存的文件。
import numpy as np
v = np.load("/home/DolphinDB/intVec.npy")
m = np.load("/home/DolphinDB/doubleMat.npy")
FILE:references/doc_2767.md
# 流数据高可用
**URL**: https://docs.dolphindb.cn/zh/stream/str_ha.html
**来源**: DolphinDB 官方文档
---
流数据高可用
DolphinDB
支持流数据的发布、订阅、预处理、实时内存计算、复杂指标的滚动窗口计算等,既能处理分析实时数据,也能对历史数据进行计算分析,帮助用户利用、发挥这些数据的价值。为满足流数据服务不中断的需求,DolphinDB
提供了流数据的高可用功能。
一个发布订阅流数据系统包含三个角色: Publisher(生产者),Broker 和 Subscriber(消费者)。在 DolphinDB 流数据框架中,Broker 由
DolphinDB 的数据节点或计算节点担任,Publisher 和 Subscriber 由 DolphinDB 数据节点、计算节点或第三方 API 程序担任。
如上图所示,DolphinDB 流数据高可用功能采用了基于 Raft 协议的高可用多副本架构:
相同流数据的副本存储在 Raft 组内不同节点上,Raft 协议用来维护多个副本的一致性。
Raft 组具有自动恢复的性质,当少数节点失效的时候不影响 Raft 组的正常工作,当大多数节点失效的时候,Raft 组则会停止服务。Raft
组能够容忍小于半数的节点宕机,例如包含三个节点的组,可以容忍一个节点出现故障;包含五个节点的组,可以容忍两个节点出现故障。
正常情况下 Raft 组内只有一个 Leader(领导节点)负责响应来自所有客户端的请求、为客户端提供服务,其他节点都是 Follower(追随节点)。
DolphinDB 流数据的高可用包括 Broker 的高可用、生产者和消费者的高可用,并具有以下特性:
每个节点上可以定义一个或多个 Raft 组,一个 Raft 组可以接纳多个流数据表。
一个流数据表创建时可指定一个 Raft 组,表明该表为高可用的流数据表。如果没有指定 Raft 组,就是普通的流数据表,不具备高可用功能。
Publisher 向 Leader 写入数据。若写入失败或者收到非 Leader 异常,就自动切换到新的 Leader 节点写入。
Subscriber 从 Leader 订阅流数据。Leader 重新选举后,从 Leader 变换为 Follower 时,Broker 会主动断开这个
Raft 组内所有的流表对应的订阅端连接。Subscriber 连接被断开,或者收到新的 Leader 选出的通知后,会自动向新的 Leader
发起订阅。
以下内容介绍如何使用 Broker 的高可用功能、生产者和消费者的高可用功能,以及如何提高高可用流数据流表的写入性能。
Broker 的高可用
集群配置
在启用流数据高可用功能前,需要先在多个服务器上部署 DolphinDB
集群(目前高可用功能仅在集群中支持,在单节点模式中不支持),然后根据流数据教程配置相关参数,再创建高可用流数据表。
高可用相关的配置项主要的有:
streamingHAMode:指定高可用功能采用的协议,当设置为 Raft 时,表示流数据高可用功能采用了 Raft 协议。
streamingRaftGroups:配置 Raft
组。格式为:"groupId:node_name1:node_name2:node_name3",其中 groupId 表示 Raft
组号,为大于等于 2 的整数,node_name 为数据节点或计算节点的节点名字,须配置至少 3
个,中间用冒号分隔。系统支持配置多组,用逗号分隔。建议每组的数据节点分别位于不同的服务器上,以防止一台服务器宕机,组内节点都不可用。
persistenceDir:流数据表的保存路径。高可用流数据表数据要保存到磁盘上,必须配置
persistenceDir
。在集群模式中,应当为每个节点配置不同的
persistenceDir
。
streamingHADir:流数据 Raft 日志文件的存储目录。Raft
日志包括注册表、删除表、append(追加)数据等信息。为保证断电后不丢失数据,DolphinDB 会调用 fsync 把日志刷到磁盘上。一般
HDD 硬盘上 fsync 性能比较差,例如有的 HDD 硬盘刷一次要 10-30 毫秒,为了保证性能,建议这个目录配置在 SSD
硬盘上。如果不配置,系统默认值为
<HomeDir>/log/streamLog。如果在同一个服务器上部署了多个数据节点,每个节点应当配置不同的
streamingHADir
。
streamingHAPurgeInterval:Raft 日志垃圾回收周期。在系统运行时,节点中的 Raft
日志信息若不断增长,会影响节点恢复时状态回放的效率。Raft 采用 Checkpoint(检查点)的方式来截断日志。做 Checkpoint
有一些需要注意的性能点:不要做得太频繁,否则消耗磁盘带宽;也不要做得太不频繁,否则一旦节点重启需要回放大量日志,影响可用性。系统默认值300,单位为秒。
用户需要在集群
cluster.cfg
配置文件中配置上述参数。以下例子配置了 2 个 Raft 组,组 2 包含 3 个数据节点,分别为
DataNode1、DataNode3 和 DataNode5。组 3 包含 3 个数据节点,分别为 DataNode2、DataNode4 和
DataNode6。其中
<ALIAS>
是宏变量,会自动替换为不同节点的别名。
streamingHAMode=raft
streamingRaftGroups=
2
:DataNode1:DataNode3:DataNode5,
3
:DataNode2:DataNode4:DataNode6
persistenceDir=/ssd/dolphindb/persistenceDir/<ALIAS>
streamingHADir=/ssd/dolphindb/streamLog/<ALIAS>
注意:
streamingRaftGroups
配置的节点名字,必须和配置文件
cluster.nodes
中配置的数据节点或计算节点名字一致
persistenceDir
和
streamingHADir
配置的路径必须根据实际服务器的目录情况配置
获取 Raft 组
可使用
getStreamingRaftGroups
函数以获取与验证用户在集群配置的 Raft 组。
此函数只能获取当前数据节点上配置的 Raft 组。例如在上述例子中配置的
DataNode1上运行
getStreamingRaftGroups()
,结果如下:
id
sites
2
192.168.1.11:19151:DataNode1,192.168.1.12:19153:DataNode3,192.168.1.13:19155:DataNode5
获取 Raft 组的 Leader
在集群中配置 Raft 组后,每个 Raft 组会自动选出 Leader,组中其他节点为 Follower,由 Leader 为客户端提供流数据订阅服务。当
Leader 出现故障不可用时,系统会自动选举出新的 Leader 来提供流数据服务。获取指定 raft 组的
Leader,可以调用函数
getStreamingLeader
。函数语法如下:
getStreamingLeader(groupId)
其中参数
groupId
是 Raft 组的编号。
需要注意的是,要获取指定 Raft 组的 Leader,只能在该组配置的数据节点上运行该函数。例如要获取上述例子配置的 Raft 组 2 的 Leader,可以在
DataNode1、DataNode3 或 DataNode5 上运行下列代码:
getStreamingLeader(
2
)
若要在其他节点上获取组 2 的 Leader,需要先获取配置了该组的任意节点,然后使用
rpc
函数到该节点获取
Leader。例子如下:
t =
exec
top
1
id,node
from
pnodeRun(getStreamingRaftGroups) where id =
2
leader = rpc(t.node[
0
],getStreamingLeader,t.id[
0
])
创建高可用流数据表
创建高可用流数据表使用函数
haStreamTable
。语法如下:
haStreamTable(raftGroup, table, tableName, cacheLimit, [keyColumn], [retentionMinutes=
1440
])
参数
raftGroup
是一个大于 1 的整数,表示 Raft 组的 ID,它必须是通过 streamingRaftGroups 配置的 Raft
组中的一个成员。
可选参数
keyColumn
是一个字符串,表示主键。设置了
keyColumn
后,系统能根据
keyColumn
自动过滤重复数据。比如从设备采集的流数据,这个
keyColumn
产生规则可以是设备编号+每个设备的消息唯一号;从股市获取的股票信息,
keyColumn
可以是股票编码+每个股票消息的唯一号,这样从多个采集源采集入库或重复入库,都能保证数据不重复。
一个 Raft 组可以包含多个高可用流数据表。这里要注意以下几点:
高可用流数据表在日志中持久化了表结构信息,重启后不需要重新建表。普通流数据表在节点重启后,需要重新创建流数据表。
客户端只需订阅 Raft 组中任意一个数据节点上的高可用流数据表,并启用订阅的自动重连功能。Leader
上的高可用流数据表会向客户端发布数据。如果 Raft 组中的 Leader 宕机,系统会选举出新的 Leader
继续发布数据,客户端会自动切换订阅到新的 Leader 上的高可用流数据表。
在启动高可用流数据功能后,普通流数据表和高可用流数据表可共存于同一个数据节点上。普通流数据表与高可用流数据表也可互相兼容,但从普通流数据表转化为同名高可用流数据表时,要注意清除之前普通流数据表的数据和日志(使用
dropStreamTable
命令进行删除)。与普通流数据表一样,查看高可用流数据表的元数据信息可使用
getPersistenceMeta
函数。
下面的例子在 Raft 组2上创建了一个高可用流数据表
haDevSt
,其中
cacheLimit
是100000,
keyColumn
是 id。
tmp = table(
1
:
0
, [
"id"
,
"source_address"
,
"source_port"
,
"destination_address"
,
"destination_port"
], [STRING,INT,INT,INT,INT])
haStreamTable(
2
, tmp,
"haDevSt"
,
100000
,
"id"
)
删除高可用流数据表
删除高可用流数据表可调用命令
dropStreamTable
。语法如下:
dropStreamTable(tableName)
用户需要在取消所有订阅客户端后才能删除流数据表。
注:
dropStreamTable
也支持删除普通流数据表。普通流数据表还可以用
clearTablePersistence(objByName( tableName))
(若有持久化)和
undef(tableName, SHARED)
命令删除。
生产者和消费者的高可用
写入流数据
生产者向流数据表写入数据,只能向 Leader 节点写入,向 Follower 节点写数据会抛出 NotLeader 异常。目前 JAVA API、C++ API
和 Python API 已支持流数据生产者的高可用,能自动捕获这个异常,并获取异常中携带的新 Leader 的节点信息,然后向新 Leader
继续写入数据。在 API 中,要求在
connect
函数中指定
highAvailabilitySites
参数。
highAvailabilitySites
是一个 String 类型的 Array,每个 String 都是 host:port
格式。这样在 Leader 切换时,就能自动切换到
highAvailabilitySites
中的另一个节点,即新的 Leader。JAVA
API 代码举例如下:
String[] haSites = new String[]{
"192.168.1.11:19151"
,
"192.168.1.12:19153"
,
"192.168.1.13:19155"
};
conn.connect(host,port,
"admin"
,
"123456"
, initScript, true,haSites);
Python API 代码举例如下:
conn.connect(host, port,
"admin"
,
"123456"
, initScript, True, [
"192.168.1.2:9921"
,
"192.168.1.3:9921"
,
"192.168.1.4:9921"
])
订阅流数据
客户端只需订阅 Raft 组中任意一个数据节点上的高可用流数据表,并启用订阅的自动重连功能(即把
subscribeTable
的
reconnect
参数设置为 true)。Leader 上的高可用流数据表会向订阅端发布数据。如果 Raft 组中的 Leader
宕机,系统会选举出新的 Leader 继续发布数据,客户端会自动切换订阅到新 Leader 上的高可用流数据表。
同时针对高可用流数据表,
subscribeTable
提供了持久化保存最新一条已经处理过的订阅数据的偏移量的功能,以避免在重订阅时部分未处理的数据丢失,通过设置参数
persistOffset
= true 可开启该功能。偏移量可以通过
getTopicProcessedOffset
函数获取。
下面的例子在 Raft 组2上创建了一个高可用流数据表
haDevSt
。然后在集群中的某个节点上执行
subscribeTable
,向 Leader 节点订阅
haDevSt
。
subscribeTable
的参数
reconnect
和
persistOffset
设为 true。
t1=table(
1
:
0
, [
"id"
,
"source_address"
,
"source_port"
,
"destination_address"
,
"destination_port"
], [STRING,INT,INT,INT,INT] )
haStreamTable(
2
,t1,
"haDevSt"
,
100000
,
"id"
)
t=select id,node
from
pnodeRun(getStreamingRaftGroups) where id =
2
def
msgProc(msg){ //todo
}
subscribeTable(server=t.node[
0
], tableName=
"haDevSt"
, handler=msgProc{}, reconnect=true, persistOffset=true)
当流数据表启用高可用时,API 客户端连接必须启用重连功能。目前 JAVA API、C++ API 和 Python API
已支持流数据消费者的高可用。其实现原理如下:
客户端订阅时,保存 raftGroup 中所有节点的 site(节点信息)。
Leader 变为 Follower 时,Broker 会主动关闭这个组中所有的流数据表对应的订阅,所以客户端就会发起重连。
客户端重连时如果连接到了 Follower 上,会收到 Not Leader Exception 的异常,这个异常中还携带了目前新 Leader
的信息(如果 Leader 尚未被选出,Follower 就返回自身节点信息)。客户端收到这个异常之后,等待一段时间后再尝试连接新的
Leader。
客户端重连一个节点多次都失败时,则开始尝试连接其他配置的节点。
流数据高可用的设计
流数据高可用架构采用 Raft 协议实现一致性。Raft 采用分而治之的办法,将复杂问题分解为三个子问题:选举(Leader election)、日志复制(Log
replication)和安全性(Safety)。Raft 开始时先在组内选举出 Leader 负责日志复制的管理,Leader
接受来自客户端的事务请求(日志),并将它们复制给组内其它节点,然后负责通知组内其它节点提交日志,Leader 负责保证其它节点与它的日志同步,当 Leader
宕机后组内其它节点会发起选举选出新的 Leader。
DolphinDB 的 Raft 日志内容包含流数据表的增删信息和流数据表记录的添加信息,系统对 Raft
日志采取同步顺序写的方式保存到磁盘。当流数据表较大时,为了避免内存不足,系统会把流数据表中较旧的数据从内存中清理,保存到磁盘。因此消费者订阅比较旧的数据时,就需要从数据文件中加载。Raft
日志顺序存放,获取流数据时就需要从头回放,不能满足快速订阅的需求,所以流数据存储时引入了数据日志并建立索引,发布时用索引来帮助系统快速定位到订阅的起始行。系统对每个
Raft 日志记录一个 LSN(Log Sequence Number),对每个数据文件也记录一个 LSN(表示对数据文件进行修改的最新 Raft
日志记录),每次异步写入数据文件之后更新 LSN。在恢复的时候,对比日志记录的 LSN 与数据文件的 LSN,若 Raft 日志的 LSN 小于数据文件的
LSN,那么表明这个日志已经写入数据文件,可以不用重做(Redo),否则需要重做。Raft 日志会不断增长,当 Raft 日志达到一定大小时,系统采用
Checkpoint(检查点)的方式截断日志,以免日志膨胀。
流数据生产者写入流数据时,把数据发送到 Leader,Leader 收到之后,先写入 log 记录到 Raft日志,然后一边复制 Raft 日志到
Follower,一边异步写入数据文件,等复制 Raft 日志和写数据文件都完成后,再回复生产者写入成功。收到 Leader 发来的日志后,Follower
节点直接异步把日志写入数据文件。通过 Raft 日志、数据日志和 Raft 一致性协议,保证了生产者成功写入的流数据是不会丢失的。当一个节点宕机或重启时,Raft
协议能保证 Leader 把 Follower
离线时写入的数据同步更新到这个节点,最终保持与组内其他副本的一致,以保证数据不丢失。但这个同步过程可能耗时过长,影响正常日志条目的复制,所以当这个节点离线时间较长、写入流数据量已很大时,建议在系统空闲时再重新加入
Raft 组。
流数据写入和订阅都不是事务的,所以不能保证不写入重复数据,比如在 Leader
向生产者发送成功写入确认消息时,因网络或其他原因,生产者没收到这个消息,那生产者就可能重写这些数据导致重复。订阅者收到消息并处理后会把消息编号记录下来,下次重订阅时会根据记录的消息编号,订阅下一个消息。若在处理消息的过程中出了异常,导致数据已入库,但消息编号还没记录下来,那就可能重复订阅这个消息。DolphinDB
系统提供了流数据表的主键功能,设置主键后,系统能根据主键自动过滤重复数据,以免在生产端写入重复数据。
高可用流数据表的性能
高可用流数据表因为需要向 Follower 节点复制副本,难免会影响写入性能。那这个影响有多大呢?我们在三台服务器上部署一个集群进行了比较测试。为减少网络传输、磁盘 IO
对性能的影响,三台服务器之间用万兆网卡连接,流数据 Raft
日志文件的存储目录配置在固态硬盘上,流数据表的记录保存路径配置在机械硬盘上。高可用流数据表、普通流数据表的保存模式、压缩模式保持一致,都设为同步保存和不压缩。写入流数据的
API 客户端与 Leader 节点运行在同一台服务器上。在测试时,我们让高可用表的 Leader
节点写入和普通流数据表的写入都在同一台服务器的同一个磁盘上进行,每次测试前,把流数据表及数据都清除干净以保持环境一致。
流数据表定义详见附件,其中普通流数据表和高可用流数据表的列数保持一致,每列的数据类型也保持一致,为了测试每行记录字节总数对性能的影响,我们测了列数较少(11 列)和列数较多(211
列)两种情况。因为每写入一批都要对 Raft
日志刷盘一次,增加单批写入的记录数可提高系统吞吐量,所以还测试了不同单批数量的情况。一般用多线程能提升整体处理性能,所以还测了 4
个线程的情况。列数较少时测试结果如下表:
总写入记录数
线程数
单批数量/线程
写入次数/线程
高可用写入耗时ms
高可用写入速率(条/秒)
普通写入耗时
普通写入速率(条/秒)
高可用/普通速率比
10,000
1
1
10,000
14,884
671.9
6,597
1,515.8
44.3%
1,000,000
1
100
10,000
419,572
2,383.4
407,980
2,451.1
97.2%
10,000,000
1
1,000
10,000
440,250
22,714.4
421,990
23,697.2
95.9%
10,000,000
1
10,000
1,000
26,382
379,046.3
18,868
529,997.9
71.5%
40,000
4
1
10,000
45,213
884.7
7,120
5,618.0
15.7%
4,000,000
4
100
10,000
421,568
9,488.4
40,150
9,776.4
97.1%
40,000,000
4
1,000
10,000
446,746
89,536.3
427,825
93,496.2
95.8%
40,000,000
4
10,000
1,000
59,203
675,641.4
35,509
1,126,475.0
60.0%
列数较多时测试结果如下表:
总写入记录数
线程数
单批数量/线程
写入次数/线程
高可用写入耗时ms
高可用写入速率(条/秒)
普通写入耗时
普通写入速率(条/秒)
高可用/普通速率比%
10,000
1
1
10,000
427,502
23.4
419,282
23.9
98.1%
1,000,000
1
100
10,000
256,728
3,895.2
242,651
4,121.1
94.5%
10,000,000
1
1,000
10,000
458,010
2,1833.6
339,780
29,430.8
74.2%
10,000,000
1
10,000
1,000
167,349
59,755.4
112,188
89,136.1
67.0%
40,000
4
1
10,000
429,201
93.2
415,907
96.2
96.9%
4,000,000
4
100
10,000
295,807
13,522.3
171,150
23,371.3
57.9%
40,000,000
4
1,000
10,000
519,405
77,011.2
372,236
107,458.7
71.7%
40,000,000
4
10,000
1,000
589,830
67,816.2
327,665
122,075.9
55.6%
从上述测试结果中可以发现,当列数较少、每批量特别小(如每批写记录为个位数)时,由于高可用流数据表 Raft
日志网络传输的开销在整个处理时间中占比相对较大,所以对高可用流数据表的写入性能影响较大。当列数较多或批量较大(如
100-1000)时,刷盘需要的时间增加,而因为万兆网卡的高性能传输,其对性能的影响相比刷盘的较大开销,有所减弱,所以高可用流数据表与普通流数据表的写入性能差别就不太明显。从测试结果也可以发现,通过增加线程数和单批写入数,可以提高写入的吞吐量。
总结
DolphinDB 流数据内置框架采用基于 Raft 协议的高可用多副本架构,实现了 Broker
的高可用、生产者和消费者的高可用。性能测试结果显示,当列数较少、每批量特别小(如每批写记录为个位数)时,对高可用流表的写入性能影响较大。当列数较多或批量较大(如100-1000)时,高可用流表与普通流表的写入性能差别就不太明显。
附录脚本
FILE:references/doc_2785.md
# minIgnoreNull
**URL**: https://docs.dolphindb.cn/zh/funcs/m/minignorenull.html
**来源**: DolphinDB 官方文档
---
minIgnoreNull
语法
minIgnoreNull(X, Y)
详情
一个二元标量函数,返回两个数(
X
和
Y
)中的最小值。
它与
min
作为二元标量函数区别在于对空值的处理:
min
:当配置项
nullAsMinValueForComparison=
true
时,空值被视为最小值进行比较;否则空值不参与比较,结果返回空值。
minIgnoreNull
:不受配置项
nullAsMinValueForComparison
的影响。返回
X
或
Y
中的非空值,或者如果两者都非空,返回最小值。
参数
X
和
Y
是数值型、LITERAL 或 TEMPORAL 型的标量/数据对/向量/矩阵。
返回值
输入标量时,返回标量。
输入向量时,返回向量(逐元素比较)。
输入矩阵时,返回矩阵(逐元素比较)。
输入数据对时,返回数据对。
例子
minIgnoreNull(2,matrix(1 NULL -4,-1 -4 0))
#0
#1
1
-1
2
-4
-4
0
minIgnoreNull(matrix(10 3 NULL, 1 7 4),matrix(1 NULL -4,-1 -4 0))
#0
#1
1
-1
3
-4
-4
0
使用
reduce
结合
minIgNoreNull
,计算元组中存储的同形状矩阵每个位置的最小值,忽略空值。
n1 = matrix(1 1 1, 5 5 5)
n2 = matrix(10 11 12, 0 NULL -5)
n3 = matrix(-1 1 NULL, -3 0 10)
reduce(minIgnoreNull, [n1,n2,n3])
相关函数:
min
,
maxIgnoreNull
FILE:references/doc_2790.md
# abs
**URL**: https://docs.dolphindb.cn/zh/funcs/a/abs.html
**来源**: DolphinDB 官方文档
---
abs
语法
abs(X)
详情
对
X
内每个元素求绝对值并返回。
参数
X
是可以标量、数据对、向量、矩阵、字典或表。
返回值
返回结果的数据形式和数据类型与输入
X
保持一致。若
X
为标量,返回标量;若为向量、矩阵或表,返回相同维度的向量、矩阵或表。
例子
abs(-2.0);
// output:
2
abs(-2 -3 4);
// output:
[2, 3, 4]
FILE:references/doc_2792.md
# isMonthEnd
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isMonthEnd.html
**来源**: DolphinDB 官方文档
---
isMonthEnd
语法
isMonthEnd(X)
详情
判断
X
是否为月末最后一天。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
返回值
布尔型标量或向量。
例子
isMonthEnd(2012.05.31);
// output: true
isMonthEnd([2012.05.30,2012.05.31]);
// output: [false,true]
相关函数:
isMonthStart
FILE:references/doc_2795.md
# setRandomSeed
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setRandomSeed.html
**来源**: DolphinDB 官方文档
---
setRandomSeed
语法
setRandomSeed(seed)
详情
设置随机数种子。
参数
seed
是一个整数,表示随机数种子。
例子
setRandomSeed(5);
rand(10, 10);
输出返回:[2,0,8,8,2,3,9,9,4,0]
FILE:references/doc_2797.md
# mifirstNot
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mifirstNot.html
**来源**: DolphinDB 官方文档
---
mifirstNot
语法
mifirstNot(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
的第一个非空元素的下标。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
当
X
是向量时,返回一个向量。
当
X
是矩阵时,返回一个矩阵。
当
X
是表时,对表的每列进行计算,返回相应的结果。
当
X
是元组时,对元组中的每个向量分别计算,返回相应的结果。
例子
v = NULL NULL 2 3 4 8 NULL 5 -2 3 -1 0 NULL
mifirstNot(v, 3)
// output: [,,2,1,0,0,0,0,1,0,0,0,0]
m = matrix(NULL 1 2 3, 1 NULL 2 3, NULL NULL 3 4, 1 2 3 4)
n = mifirstNot(m, 2)
n
#1
#2
#3
#4
1
0
-1
0
0
1
1
0
0
0
0
0
T = [2022.01.01, 2022.01.02, 2022.01.03, 2022.01.06, 2022.01.07]
X = NULL 2 NULL 4 5
X1 = indexedSeries(T, X)
mifirstNot(X1, 2, 1)
#1
2022.01.01
-1
2022.01.02
1
2022.01.03
0
2022.01.06
0
2022.01.07
0
FILE:references/doc_280.md
# int128
**URL**: https://docs.dolphindb.cn/zh/funcs/i/int128.html
**来源**: DolphinDB 官方文档
---
int128
语法
int128(X)
详情
把字符串转换为 INT128 类型。
参数
X
是一个字符串标量或向量。
返回值
INT128 类型标量或向量。
例子
a=int128("e1671797c52e15f763380b45e841ec32")
返回:e1671797c52e15f763380b45e841ec32
typestr(a);
返回:INT128
FILE:references/doc_2801.md
# each
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/each.html
**来源**: DolphinDB 官方文档
---
each
语法
each(func, args...)
(把一个函数应用到指定参数中的每个元素。)
或
F :E X
(把一个函数应用到X中的每个元素。)
或
X <operator> :E Y
(把一个函数应用到X和Y中的每个元素,X和Y长度相同。)
或
func:E(args...)
详情
将指定函数(func)或运算符(operator)按以下规则应用到输入对象(args, X, Y)上:
对于矩阵,把函数应用到每一列;
对于表,把函数应用到每一行;
对于数组向量,把函数应用到每一行;
对于字典,把函数应用到字典的每一个 value。
func(X) 和 func :E X 的区别是前者将X视作一个输入变量,而后者取遍X中的每一个参数。如果 func
是一个向量函数,应该避免使用 "each (:E) " ,因为在元素比较多的时候,元素的比对就会很慢。
peach
是并行计算版本的
each
高阶函数。对于执行时间较长的任务,
peach
比
each
能节省大量的时间。但对于小任务,
peach
可能执行时间要比each更长,因为并行函数调用的开销很大。
参数
func
是一个函数。
args
是func的参数。
operator
是一个二元运算符。
X
和
Y
可以是数据对、向量、矩阵、表
、数组向量
或字典。
返回值
each 根据每个子任务计算结果的数据类型和形式,决定返回值的数据形式。若所有子任务的数据类型和形式都相同,则返回 Vector 或
Matrix,否则返回 Tuple。
例子
假设需要计算3个员工的日薪,员工的工时存放在向量x=[9,6,8]中,员工的时薪在8小时以下是$10,在8小时以上是$20。考虑下面的
wage
函数:
x=[9,6,8]
def wage(x){if(x<=8) return 10*x; else return 20*x-80}
wage x;
The vector can't be converted to bool scalar.
wage(x)
不返回结果,因为x<=8,即 [9,6,8]<=8 返回了一个向量的条件值[0,1,1],而不是if 需要的标量。
可使用以下方案来解决这个问题:
each(wage, x);
[100,60,80]
wage :E x;
[100,60,80]
def wage2(x){return iif(x<=8, 10*x, 20*x-80)};
// iif 函数是一个逐元素的条件操作
wage2(x);
[100,60,80]
类似的,
each
也可以用于有多个参数的函数:
def addeven(x,y){if (x%2==0) return x+y; else return 0}
x1=1 2 3
x2=4 5 6;
each(addeven, x1, x2);
[0,7,0]
each
所用数据可以是数据对:
t = table(1 2 3 as id, 4 5 6 as value, `IBM`MSFT`GOOG as name);
t;
id
value
name
1
4
IBM
2
5
MSFT
3
6
GOOG
each(max, t[`id`value]);
[3,6]
each
所用数据可以是矩阵:
m=1..12$4:3;
m;
col1
col2
col3
1
5
9
2
6
10
3
7
11
4
8
12
each(add{1 2 3 4}, m);
// add{1 2 3 4}是一个部分应用,each将向量[1, 2, 3, 4]与矩阵m的每列相加。
col1
col2
col3
2
6
10
4
8
12
6
10
14
8
12
16
x=1..6$2:3;
y=6..1$2:3;
x;
col1
col2
col3
1
3
5
2
4
6
y;
col1
col2
col3
6
4
2
5
3
1
each(**, x, y);
[16,24,16]
// 比如,24=3*4+4*3
当输入对象有多个时,每次取出每个对象相同位置的元素,作为指定函数的参数。例如:
m1 = matrix(1 3 6, 4 6 8, 5 -1 3)
m2 = matrix(3 -6 0, 2 NULL 3, 6 7 9)
each(corr, m1, m2)
// 等价于 corr(m1[0], m2[0]) join corr(m1[1], m2[1]) join corr(m1[2], m2[2])
[-0.216777, 1, -0.142857]
从 2.00.9 版本开始,
each
所用数据可以是字典:
d=dict(`a`b`c, [[1, 2, 3],[4, 5, 6], [7, 8, 9]])
each(sum, d)
b->15
c->24
a->6
下例中,我们在一个部分应用中使用了
call
函数,该部分应用将向量[1 2 3]作为参数,分别调用函数
sin
与
log
。
// 当 "functionName" 为空时,将动态地选择一个函数名字。
each(call{, 1..3},(sin,log));
sin
log
0.841471
0
0.909297
0.693147
0.14112
1.098612
func 为自定义函数,对字典进行操作。当字典的 key 的类型是字符串时,
each
会对字典进行合并,返回一个表。合并规则如下:
根据第一个字典确定表的 schema,并将字典的 value 写入表中第一行。字段名为该字典的 keys,列数为该字典的 keys
的个数。无论后续被遍历字典 keys 的个数如何变化,表的 schema 不会被修改。
在遍历后续字典时,每一个字典对应表中一行数据。若某个 key 与表字段名相同,则将其 value 追加到表中,若某个 key
与表字段不同,则追加空值到表中。
days = 2023.01.01..2023.01.10
def mf(day) {
out = dict(STRING, ANY)
if(day==2023.01.05){
out["v"] = 3
}
else{
out["day"] = day
out["v"] = 1
}
return out
}
each(mf, days)
v
day
1
2023.01.01
1
2023.01.02
1
2023.01.03
1
2023.01.04
3
1
2023.01.06
1
2023.01.07
1
2023.01.08
1
2023.01.09
1
2023.01.10
从2.00.12和3.00.0版本开始,each 可以接受多元函数且第一个参数为字典。
对于表 t 中 id 列的每个元素,计算其向前累加直到不小于3经过的周期数(可用
sumbars
函数实现);对 id2
的每个元素,计算其向前累加直到不小于5经过的周期数。因为用
sumbars
计算每列数据时,
Y
不同(分别是3和5),必须用一个二元函数跟 each
搭配使用。对一个表转置(
transpose
),返回一个以列名为键值,列为数值的字典。对字典应用转置函数,则还原为表。
t = table(1..10 as id, 2..11 as id2)
sumbars:E(t.transpose(), 3 5).transpose()
id
id2
0
0
2
2
1
2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
提示:
对于执行时间长的任务,使用
peach
进行并行计算,可以节约任务执行时间。
m=rand(1,20000:5000)
timer f=peach(mskew{,8},m)
Time elapsed: 3134.71 ms
timer f=mskew(m,8)
Time elapsed: 8810.485 ms
当元素数量很多时候,不推荐使用
:E (each)
高阶函数,可以使用更高效的向量解决方案。
x=rand(16, 1000000);
timer(10){each(wage, x)};
Time elapsed: 38164.9 ms
timer(10){iif(x<8,10*x,20*x-80)};
Time elapsed: 81.516 ms
FILE:references/doc_2813.md
# zigzag
**URL**: https://docs.dolphindb.cn/zh/funcs/z/zigzag.html
**来源**: DolphinDB 官方文档
---
zigzag
语法
zigzag(HL, [change=10], [percent=true], [retrace=false],
[lastExtreme=true])
详情
zigzag
主要用于过滤掉
HL
中较小波动的值,只有满足条件的极值点会被输出。
参数
HL
数值向量或者包含两列的数值矩阵。
change
极值波动的最小阈值。
percent
布尔值,表示
change
是否是一个百分数。
retrace
是一个布尔值,默认为 false。
true:
change
当前值相对于前一次波动的回撤。
false:
change
当前值相对于两端极值点间的变化。
注:
当
percent
=false 时,
retrace
的 true 值将不生效。
lastExtreme
布尔值,表示有多个连续且值相同的极值点时,是否输出最后一个极值点,默认为 true。
返回值
若
HL
是向量,返回一个与
HL
长度相同的向量;若
HL
是矩阵,返回与
HL
行数相同的向量。
例子
t = table(1.1 2.3 4.45 3.67 4.9 as `low, 1.3 2.8 4.9 3.73 6.28 as `high)
HL = matrix(t[`low], t[`high])
zz = zigzag(HL, change=10, percent=true, retrace=false, lastExtreme=true)
zz;
0
1
2
3
4
1.2
4.45
3.73
4.9
HL = 1.2 3 3.1 14 14.5 14.7 25.0 17.8 19 10
zz = zigzag(HL, change=10, percent=true, retrace=false, lastExtreme=true)
zz;
0
1
2
3
4
5
6
7
8
9
1.2
25
10
FILE:references/doc_2829.md
# schema
**URL**: https://docs.dolphindb.cn/zh/funcs/s/schema.html
**来源**: DolphinDB 官方文档
---
schema
语法
schema(table|dbHandle)
详情
显示指定数据表或数据库的结构信息。
参数
参数可为一个数据表,亦可为一个数据库句柄 (dbHandle)。
返回值
返回一个无序字典,包含以下字段(按首字母排序):
atomic:写入事务的原子性层级。
chunkGranularity:分区粒度。
clusterReplicationEnabled:集群间异步复制的开启状态。若开启,则该值为 true,否则为 false。
colDefs:数据表各字段的结构信息。
name:列名
typeString:列的类型
typeInt:列类型对应的ID
extra:仅在列类型为 DECIMAL 时,显示 DECIMAL 的 scale
comment:列字段的注释信息
sensitive:该列是否已设置为敏感列,仅当 DFS 表返回此列。
compressMethods:分布式表各列的压缩算法类型。
name:列名
compressMethods:压缩算法类型。lz4,delta (即 delta-of-delta encoding 算法)或
zstd
databaseDir:数据库的保存目录的路径。
databaseOwner:数据库创建者名称。
dbUrl:DFS 表所在分布式数据库的路径。仅当
table
为 DFS 表时返回。
encryptMode:建表时指定的表加密方式。仅当
table
为 DFS 表时返回。
engineType:存储引擎的类型,OLAP 或者 TSDB。
keepDuplicates:数据保留策略。
keyColumn:键值列列名。仅当
table
包含键值列时返回。
partitionColumnIndex:分区列在表字段中对应的下标。维度表时,该值为 -1。
partitionColumnName:分区列的名称。
partitionColumnType:分区列类型对应的 ID,参照数据类型章节。
partitionSchema:分区的结构。
partitionSites:若
database
函数配置了
locations
参数,则该字段将列出
locations 指定节点的 ip:port 信息。
partitionTypeName / partitionType:分区的类型名和对应的 ID。VALUE(1), RANGE(2), LIST(3),
COMPO(4), HASH(5)。
sortColumns:数据表的排序列。
softDelete:创建的表开启了软删除。仅在通过 TSDB 存储引擎创建的库中的表的 schema 返回值中可见。该功能开启时,softDelete
返回字段中显示为 true;否则显示为 false。
sortKeyMappingFunction:索引列的映射函数。
tableComment:表的注释。
tableName:DFS 表的表名。仅当
table
为 DFS 表时返回。
tableOwner:表创建者名称。
partitionFunction:处理分区列数据的函数。是一个字符串向量,每个元素是一个函数签名。若某个元素为
asis,则表示建表时未指定函数对象。例如:
partitionFunction->[myPartitionFunc{, 6,
8},asis]
。
latestKeyCache:该分区表是否开启最新值缓存功能。
compressHashSortKey:该分区表是否开启静态表 sortKey 压缩功能。
例子
应用于 OLAP 引擎下的数据库:
n=1000000 // 设置变量n为1000000
ID=rand(10, n) // 生成一个随机整数数组ID
x=rand(1.0, n) // 生成一个随机浮点数数组x
t=table(ID, x) // 创建表t,包含ID和x两列
db=database("dfs://rangedb101", RANGE, 0 5 10) // 创建分布式数据库dfs://rangedb101,使用RANGE分布方式
pt = db.createPartitionedTable(t, `pt, `ID) // 创建分区表pt,使用ID作为分区键
pt.append!(t) // 将表t的数据追加到分区表pt中
pt=loadTable(db,`pt); // 从数据库db中加载分区表pt
schema(db); // 显示数据库db的模式信息
返回:
databaseDir->dfs://rangedb101
partitionSchema->[0,5,10]
partitionSites->
atomic->TRANS
chunkGranularity->TABLE
partitionType->2
partitionTypeName->RANGE
partitionColumnType->4
clusterReplicationEnabled->1
databaseOwner->admin
应用于 OLAP 引擎下的数据表时:
schema(pt);
返回:
chunkGranularity->TABLE
tableOwner->admin
compressMethods->
name compressMethods
---- ---------------
ID lz4
x lz4
colDefs->
name typeString typeInt comment
---- ---------- ------- -------
ID INT 4
x DOUBLE 16
chunkPath->
partitionColumnIndex->0
partitionColumnName->ID
partitionColumnType->4
partitionType->2
partitionTypeName->RANGE
partitionSchema->[0,5,10]
partitionSites->
应用于 TSDB 引擎下的数据库:
n = 10000 // 设置变量n为10000
SecurityID = rand(`st0001`st0002`st0003`st0004`st0005, n) // 从指定的证券ID中随机选择n个值赋给SecurityID
sym = rand(`A`B, n) // 从符号A和B中随机选择n个值赋给sym
TradeDate = 2022.01.01 + rand(100,n) // 从2022年1月1日至100天后的日期中随机选择n个日期赋给TradeDate
TotalVolumeTrade = rand(1000..3000, n) // 生成n个介于1000和3000之间的随机整数赋给TotalVolumeTrade
TotalValueTrade = rand(100.0, n) // 生成n个小数赋给TotalValueTrade
schemaTable_snap = table(SecurityID, TradeDate, TotalVolumeTrade, TotalValueTrade).sortBy!(`SecurityID`TradeDate)
// 创建表schemaTable_snap,并按SecurityID和TradeDate排序
dbPath = "dfs://TSDB_STOCK" // 设置数据库路径为dfs://TSDB_STOCK
if (existsDatabase(dbPath)){dropDatabase(dbPath)} // 如果数据库路径存在,则删除该数据库
db_snap = database(dbPath, VALUE, 2022.01.01..2022.01.05, engine='TSDB') // 创建名为db_snap的数据库,时间范围为2022年1月1日至2022年1月5日,引擎为TSDB
schema(db_snap) // 显示db_snap的模式信息
返回:
databaseDir->dfs://TSDB_STOCK
partitionSchema->[2022.01.01,2022.01.02,2022.01.03,2022.01.04,2022.01.05]
partitionSites->
engineType->TSDB
atomic->TRANS
chunkGranularity->TABLE
partitionType->1
partitionTypeName->VALUE
partitionColumnType->6
clusterReplicationEnabled->1
databaseOwner->admin
应用于 TSDB 引擎下的数据表:
// 定义名为myHashFunc的函数,该函数接受一个参数x,并返回x的哈希桶编号,桶数为10
def myHashFunc(x){
return hashBucket(x, 10)
}
// 使用db_snap中的schemaTable_snap创建一个分区表snap,表名为"snap"
// 以TradeDate分区,以SecurityID和TradeDate排序
// 保留重复值,排序键映射函数为myHashFunc
snap = createPartitionedTable(dbHandle=db_snap, table=schemaTable_snap, tableName="snap", partitionColumns=`TradeDate, sortColumns=`SecurityID`TradeDate, keepDuplicates=ALL, sortKeyMappingFunction=[myHashFunc])
// 显示snap表的模式信息
schema(snap)
返回:
engineType->TSDB
keepDuplicates->ALL
chunkGranularity->TABLE
sortColumns->["SecurityID","TradeDate"]
sortKeyMappingFunction->["def myHashFunc(x){
return hashBucket(x, 10)
}"]
softDelete->0
tableOwner->admin
compressMethods->
name compressMethods
---------------- ---------------
SecurityID lz4
TradeDate lz4
TotalVolumeTrade lz4
TotalValueTrade lz4
colDefs->
name typeString typeInt extra comment
---------------- ---------- ------- ----- -------
SecurityID SYMBOL 17
TradeDate DATE 6
TotalVolumeTrade INT 4
TotalValueTrade DOUBLE 16
chunkPath->
partitionColumnIndex->1
partitionColumnName->TradeDate
partitionColumnType->6
partitionType->1
partitionTypeName->VALUE
partitionSchema->[2022.01.01,2022.01.02,2022.01.03,2022.01.04,2022.01.05]
partitionSites->
建立一个点位管理表,复合分区方案按 id 和 ts 分区,创建了一个名为 pt 的点位管理表。该表使用 ticket 和 id2
作为唯一识别一个点位的两列;启用最新值缓存,且 value 为 IOTANY 类型,可存储不同类型的测点数据;启用了 hashSortKey
压缩。
dbName = "pt"
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db1 = database(, partitionType=HASH, partitionScheme=[INT, 10])
db2 = database(, partitionType=VALUE, partitionScheme=2017.08.07..2017.08.11)
db = database(dbName, COMPO, [db1, db2], engine='IOTDB')
create table "dfs://db"."pt" (
id INT,
ticket SYMBOL,
id2 LONG,
ts TIMESTAMP,
id3 IOTANY
)
partitioned by id, ts,
sortColumns = [`ticket, `id2, `ts],
sortKeyMappingFunction = [hashBucket{, 50}, hashBucket{, 50}],
latestKeyCache = true,
compressHashSortKey = true
print schema(loadTable(dbName, `pt))
返回:
/*
engineType->IOTDB
keepDuplicates->ALL
chunkGranularity->TABLE
sortColumns->["deviceId","location","timestamp"]
sortKeyMappingFunction->["hashBucket{, 50}","hashBucket{, 50}"]
softDelete->0
tableOwner->admin
compressMethods->name compressMethods
--------- ---------------
deviceId lz4
location lz4
timestamp lz4
value lz4
tableComment->
latestKeyCache->1
compressHashSortKey->0
colDefs->name typeString typeInt extra comment
--------- ---------- ------- ----- -------
deviceId INT 4
location SYMBOL 17
timestamp TIMESTAMP 12
value IOTANY 41
chunkPath->
partitionColumnIndex->[0,2]
partitionColumnName->["deviceId","timestamp"]
partitionColumnType->[4,6]
partitionType->[5,1]
partitionTypeName->["HASH","VALUE"]
partitionSchema->(20,[2017.08.07,2017.08.08,2017.08.09,2017.08.10,2017.08.11,2024.10.12])
partitionSites->
*/
FILE:references/doc_2835.md
# columnNames
**URL**: https://docs.dolphindb.cn/zh/funcs/c/columnNames.html
**来源**: DolphinDB 官方文档
---
columnNames
语法
columnNames(X)
详情
返回
X
的列名的向量。参见相关函数:
rowNames
。
参数
X
可以是矩阵或表。
返回值
STRING 类型向量。
例子
x=1..6$2:3;
x;
#0
#1
#2
1
3
5
2
4
6
x.rename!(`a`b`c);
a
b
c
1
3
5
2
4
6
x.columnNames();
// output
["a","b","c"]
t = table(1 2 3 as id, 4 5 6 as value, `IBM`MSFT`GOOG as name);
t;
id
value
name
1
4
IBM
2
5
MSFT
3
6
GOOG
columnNames t;
// output
["id","value","name"]
t[t.columnNames().tail()];
// output
["IBM","MSFT","GOOG"]
// 获取表的最后一列,返回的结果是一个向量
FILE:references/doc_2841.md
# keys
**URL**: https://docs.dolphindb.cn/zh/funcs/k/keys.html
**来源**: DolphinDB 官方文档
---
keys
语法
keys(X)
详情
返回一个字典中的所有键作为一个向量,或一个数据表中的列名作为一个向量,或将一个集合转化为一个向量。
参数
X
是一个字典、数据表,或集合。
返回值
一个向量,数据类型取决于
X
的字典键/表列名/集合元素。
例子
z=dict(INT,DOUBLE)
z[5]=7.9
z[3]=6
z.keys();
// output
[3,5]
t = table(1 2 3 as id, 4 5 6 as x, `IBM`MSFT`GOOG as name);
keys(t);
// output
["id","x","name"]
a=set(1 2 4)
a.keys();
// output
[4,2,1]
相关函数:
values
FILE:references/doc_2843.md
# flushTSDBCache
**URL**: https://docs.dolphindb.cn/zh/funcs/f/flushTSDBCache.html
**来源**: DolphinDB 官方文档
---
flushTSDBCache
语法
flushTSDBCache()
详情
将 TSDB 引擎缓冲区里已经完成的事务强制写入数据库。请注意,使用该函数前,需配置
TSDBCacheEngineSize
。
参数
无
返回值
无
FILE:references/doc_2853.md
# fminBFGS
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fminbfgs.html
**来源**: DolphinDB 官方文档
---
fminBFGS
语法
fminBFGS(func, X0, [fprime], [gtol=1e-5], [norm],
[epsilon], [maxIter], [xrtol=0], [c1=1e-4], [c2=0.9])
详情
使用 BFGS 算法找到目标函数的最小值。
参数
func
函数名,表示需要最小化的目标函数。注意:函数返回值须是数值标量类型。
X0
数值类型的标量或向量,表示使目标函数最小化的参数的初始猜测。
fprime
可选参数,函数名,表示计算
func
梯度的函数。如果为空,则使用数值微分方法来获取函数梯度。
gtol
可选参数,正数值标量,判断是否停止迭代的梯度范数衡量值。如果梯度的范数小于
gtol
,则停止迭代。默认值为 1e-5。
norm
可选参数,正数值标量,表示范数的阶数,默认使用最大值范数。
epsilon
可选参数,正数值标量,表示当使用数值近似方法来求解函数梯度时使用的步长。默认值为
1.4901161193847656e-08
。
maxIter
可选参数,非负整数标量,表示执行的最大迭代次数,默认值为
X0
的长度乘以200。
xrtol
可选参数,非负数值标量,用于判断是否结束迭代的步长衡量值。如果步长小于
xk *
xrtol
(
xk
为当前参数向量),则停止迭代。默认值为 0。
c1
可选参数,数值标量,值域为(0,1),
c1
应小于
c2
,表示 Armijo 条件规则的参数。默认值为 1e-4。
c2
可选参数,数值标量,值域为(0,1),
c2
应大于
c1
,表示曲率条件规则参数。默认值为 0.9。
返回值
返回一个字典,字典有以下成员:
xopt:浮点数向量,使目标函数最小化的参数值。
fopt:浮点数标量,目标函数最小值,fopt=func(xopt)。
gopt:浮点数向量,目标函数最小值处的梯度,func'(xopt),应接近 0。
Hinv:浮点数矩阵,目标函数最小值处Hessian矩阵的逆矩阵。
iterations:整数标量,优化过程中执行的总迭代数。
fcalls:整数标量,优化过程中的目标函数调用次数。
gcalls:整数标量,优化过程中的梯度函数调用次数。
warnFlag:整数标量,有四个可能值:
0:表示成功执行算法全过程。
1:表示已达最大迭代次数,算法停止执行。
2:表示线搜索失败或者目标函数值出现极值。
3:表示计算结果中出现 NULL 值。
例子
本例自定义条件,传入参数
func
,
X0
,
fprime
,使用 BFGS 算法找到目标函数
quadratic_cost
的最小值。
def quadratic_cost(x, Q) {
return dot(dot(x, Q), x)
}
def quadratic_cost_grad(x, Q) {
return 2 * dot(Q, x)
}
x0 = [-3, -4]
cost_weight = diag([1., 10.])
fminBFGS(quadratic_cost{,cost_weight}, x0, quadratic_cost_grad{,cost_weight})
/* Ouput:
fcalls->8
warnFlag->0
xopt->[0.000002859166,-4.54371E-7]
Hinv->
#0 #1
0.508225788096 -0.001307222772
-0.001307222772 0.050207740748
gopt->[0.000005718332,-0.000009087439]
fopt->1.0E-11
gcalls->8
iterations->7
*/
相关函数:
fminBFGSB
FILE:references/doc_2863.md
# cancelConsoleJob
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cancelConsoleJob.html
**来源**: DolphinDB 官方文档
---
cancelConsoleJob
语法
cancelConsoleJob(rootJobId)
详情
取消已经提交但是尚未完成的交互式任务。如果要取消批处理作业,请使用
cancelJob
。
cancelConsoleJob
在当前正在执行的子任务完成后,才会取消任务。因此,
cancelConsoleJob
并不是马上生效。如果
cancelConsoleJob
的对象是没有子任务的任务,该命令不生效。
参数
rootJobId
是作业的 ID,是一个字符串标量或者向量。若为向量,表示同时取消多个作业。
返回值
无。
例子
在一个节点的某个会话中,执行以下代码:
pt = loadTable("dfs://TAQ", `quotes)
select count(*) from pt;
在同一个节点的其他会话中,使用
getConsoleJobs
获取要取消的交互式任务的 ID,然后使用
cancelConsoleJob
来取消该任务。
cancelConsoleJob("bf768327-776d-40a7-8a8d-00a6cfd054e3");
FILE:references/doc_2875.md
# makeCall
**URL**: https://docs.dolphindb.cn/zh/funcs/m/makeCall.html
**来源**: DolphinDB 官方文档
---
makeCall
语法
makeCall(F, args...)
详情
它使用指定参数调用一个函数并生成脚本。高阶函数
call
与
makeCall
的区别是,
makeCall
不执行脚本。
参数
F
是一个函数。
args
是
F
需要的参数。
返回值
一个元代码。
例子
在下列例子中,我们创建了
generateReport
函数。它能够以指定格式显示表的某些列。
def generateReport(tbl, colNames, colFormat): sql(sqlColAlias(each(makeCall{format},sqlCol(colNames),colFormat),colNames), tbl).eval();
t = table(1..100 as id, (1..100 + 2018.01.01) as date, rand(100.0, 100) as price, rand(10000, 100) as qty, rand(`A`B`C`D`E`F`G, 100) as city);
t;
id
date
price
qty
city
1
2018.01.02
77.9896
375
A
2
2018.01.03
8.1332
7864
F
3
2018.01.04
56.7185
4912
B
4
2018.01.05
72.4173
534
E
5
2018.01.06
8.2019
31
B
6
2018.01.07
74.7275
4139
A
7
2018.01.08
7.5421
2725
D
8
2018.01.09
59.1689
3095
C
9
2018.01.10
55.8454
5443
D
10
2018.01.11
32.1285
6998
G
...
generateReport(t, ["id", "date","price","qty"], ["0", "MM/dd/yyyy", "0.00", "#,###"]);
id
date
price
qty
1
01/02/2018
77.99
375
2
01/03/2018
8.13
7,864
3
01/04/2018
56.72
4,912
4
01/05/2018
72.42
534
5
01/06/2018
8.20
31
6
1/07/2018
74.73
4,139
7
01/08/2018
7.54
2,725
8
01/09/2018
59.17
3,095
9
01/10/2018
55.85
5,443
10
01/11/2018
32.13
6,988
...
与之等效的 SQL 脚本是:
def generateReportSQL(tbl, colNames, colFormat): sql(sqlColAlias(each(makeCall{format},sqlCol(colNames),colFormat),colNames), tbl)
generateReportSQL(t, ["id", "date","price","qty"], ["0", "MM/dd/yyyy", "0.00", "#,###"]);
// output
< select format(id, "0") as id,format(date, "MM/dd/yyyy") as date,format(price, "0.00") as price,format(qty, "#,###") as qty from t >
FILE:references/doc_2877.md
# nullFill!
**URL**: https://docs.dolphindb.cn/zh/funcs/n/nullFill_.html
**来源**: DolphinDB 官方文档
---
nullFill!
是
nullFill
的别名。
nullFill!
是
nullFill
函数原地修改版本,它会改变输入对象的值。
FILE:references/doc_2881.md
# cdfBinomial
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfBinomial.html
**来源**: DolphinDB 官方文档
---
cdfBinomial
语法
cdfBinomial(trials, p, X)
详情
返回二项分布的累计密度函数的值。
参数
trials
是正整数。
p
是0到1之间的浮点数。
trials
和
p
是形状参数。
X
是数值型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfBinomial(10, 0.1, [1, 5, 9]);
// output
[0.736099, 0.999853, 1]
cdfBinomial(12,0.627, [1, 3, 5, 7, 9]);
// output
[0.000154, 0.009085, 0.114844, 0.483879, 0.88373]
FILE:references/doc_2884.md
# weekOfYear
**URL**: https://docs.dolphindb.cn/zh/funcs/w/weekOfYear.html
**来源**: DolphinDB 官方文档
---
weekOfYear
语法
weekOfYear(X)
详情
计算
X
的周数(1~53)。
注:
该函数假设一周的第一天是周日,且每年的第一周至少有4天。
如果12月31日是星期一、星期二或星期三,则该周为下一年的第 01
周。如果是星期四,则该周为刚刚结束的一年的第53周;如果是星期五,则该周为第52周(如果刚刚结束的年份是闰年,则该周为第53周);如果是周六或周日,则该周为刚刚结束的一年的第52周。
参数
X
可以是 DATE, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
返回值
一个整型标量或向量。
例子
weekOfYear(2012.01.07);
输出返回:1
weekOfYear(2013.01.07);
输出返回:2
weekOfYear(2012.07.02);
输出返回:27
weekOfYear([2012.06.12T12:30:00,2012.10.28T12:35:00,2013.01.06T12:36:47,2013.04.06T08:02:14]);
输出返回:[24,43,1,14]
相关函数:
dayOfYear
,
dayOfMonth
,
quarterOfYear
,
monthOfYear
,
hourOfDay
,
minuteOfHour
,
secondOfMinute
,
millisecond
,
microsecond
,
nanosecond
FILE:references/doc_289.md
# bondCashflow
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bondCashflow.html
**来源**: DolphinDB 官方文档
---
bondCashflow
语法
bondCashflow(start, maturity, coupon, frequency, dayCountConvention,
bondType, [mode='Vector'])
详情
计算面值为 100 元的债券的现金流,支持固息债券,零息债券和贴现债券。
参数
注意:所有输入向量必须等长,输入标量将自动扩展以匹配其它向量的长度。
start
DATE 类型标量或向量,表示债券的起息日。
maturity
与
start
等长的 DATE 类型标量或向量,表示债券的到期日。
coupon
数值型标量或向量,表示债券的票面利率。例如 0.03,表示票息为 3%。
frequency
整型或 STRING 类型的标量或向量,表示债券的付息频率。可选值为:
0/“Once”:到期一次还本付息
1/“Annual”:每年付息一次
2/“Semiannual:每半年付息一次
4/“Quarterly”:每季度付息一次
12/“Monthly”:每月付息一次
dayCountConvention
STRING 类型的标量或向量,表示债券的计息日数惯例。可选值为:
"Thirty360US":US (NASD) 30/360
"ActualActualISMA":实际/实际(ISMA 规则)
"Actual360":实际/360
"Actual365":实际/365
"Thirty360EU":欧洲 30/360
"ActualActualISDA":实际/实际(ISDA 规则)
bondType
STRING 类型标量或向量,表示债券的类型。可选值为:
"FixedRate":固定利率债券,定期按息票利率支付利息。
"Discount":贴现债券,没有利息支付,以贴现方式发行的债券,期末FV=面值。
"ZeroCoupon":零息债券,期末一次性支付利息和面值,期末FV=面值+利息。
mode
可选参数,STRING 类型标量,用于指定结果的输出格式。可选值包括:
"Vector"(默认值):只返回现金流金额。
"Table":返回现金流明细表。
返回值
若
mode
= "Vector",则返回 DOUBLE 类型的向量或数组向量,表示单只或多只债券的现金流金额。
若
mode
= "Table",则返回一个表或由表组成的元组,表示单只或多只债券的现金流明细。每个表包含以下字段:
paymentDate:支付日,DATE 类型。
coupon:利息金额,DOUBLE 类型。
notional:本金,DOUBLE 类型。
total:总金额,DOUBLE 类型。
例子
frequency="Annual"
start=2022.09.28
maturity=2025.09.28
coupon=0.078
bondCashflow(start=start, maturity=maturity, coupon=coupon, frequency=frequency, dayCountConvention="Thirty360US", bondType="FixedRate")
// output: [7.8,7.8,107.799999]
bondCashflow(start=start, maturity=maturity, coupon=coupon, frequency=frequency, dayCountConvention="Thirty360US", bondType="FixedRate", mode="Table")
/* output:
paymentDate coupon notional total
----------- ------ -------- ----------
2023.09.28 7.8 0 7.8
2024.09.28 7.8 0 7.8
2025.09.28 7.8 100 107.799999
相关函数
:
bondCalculator
FILE:references/doc_2892.md
# case
**URL**: https://docs.dolphindb.cn/zh/progr/sql/case.html
**来源**: DolphinDB 官方文档
---
case
case 是一个控制流语句,用于 SQL 的条件判断语句,其作用与 if-else 语句相似。
case 语句至少包含一组 when…then… 语句,当满足 when 条件,则返回 then 结果,否则返回 else 后的表达式结果;若没有指定
else,则返回空值。case 语句多个条件的返回结果类型必须一致。case when 语句支持在分布式查询中使用。
语法
case
when condition_1 then expression_1
[when condition_2 then expression_2]
...
[when condition_n then expression_n]
[else expression_end]
end
从
2.00.10
版本开始,不再要求 when 和 then 必须在同一行。
例子
t = table(`st0`st1`st2`st4`st5`st6 as sym, 80 200 150 220 130 190 as vol)
select sym, case
when vol < 100 then -1
when vol < 200 then 0
else 1
end as flag
from t
sym
flag
st0
-1
st1
1
st2
0
st4
1
st5
0
st6
0
t = table(2022.01.01 2022.01.01 2022.01.01 2022.01.01 2022.01.01 2022.01.01 as date, `a`a`b`b`a`b as id, 300 290 302 296 304 320 as val)
select date, case when t.id == `a then val end as `GroupA, case when t.id == `b then val end as `GroupB from t
date
GroupA
GroupB
2022.01.01
300
2022.01.01
290
2022.01.01
302
2022.01.01
296
2022.01.01
304
2022.01.01
320
select sum(val) as total from t group by case when t.val < 300 then 0 else 1 end as flag
flag
total
1
1,226
0
586
支持在 case 语句中使用分析函数
t = table([2023.06M,2023.07M,2023.08M,2023.07M,2023.07M,2023.06M,2023.08M,2023.06M,2023.08M] as month, ["A","A","B","B","C","C","A","B","C"] as flag, [1200,1500,1200,1300,1400,1400,1400,1000,1300] as val)
t
month
flag
val
2023.06M
A
1,200
2023.07M
A
1,500
2023.08M
B
1,200
2023.07M
B
1,300
2023.07M
C
1,400
2023.06M
C
1,400
2023.08M
A
1,400
2023.06M
B
1,000
2023.08M
C
1,300
当 flag 为 A 时,按月分组计算 val 的偏差;当 flag 不为 A 时,按月分组计算 val 的标准差。
select month,flag,(case when flag = "A"
then (val - avg(val)over(partition by month))
else std(val)over(partition by month) end) as value
from t
month
flag
value
2023.06M
A
0
2023.07M
A
100
2023.08M
B
100
2023.07M
B
100
2023.07M
C
100
2023.06M
C
200
2023.08M
A
100
2023.06M
B
200
2023.08M
C
100
FILE:references/doc_2893.md
# beta
**URL**: https://docs.dolphindb.cn/zh/funcs/b/beta.html
**来源**: DolphinDB 官方文档
---
beta
语法
beta(Y, X)
详情
返回
Y
在
X
上的回归系数的最小二乘估计。
参数
Y
和
X
是相同长度的数值型向量、维度相同的矩阵或表。若
X
是表,只对其内数值型和布尔型的列进行计算。
返回值
DOUBLE 类型标量/向量/表。
例子
x=1 3 5 7 11 16 23
y=0.1 4.2 5.6 8.8 22.1 35.6 77.2;
beta(y,x);
// output
3.378632
FILE:references/doc_2900.md
# irFixedFloatingSwapPricer
**URL**: https://docs.dolphindb.cn/zh/funcs/i/irFixedFloatingSwapPricer.html
**来源**: DolphinDB 官方文档
---
irFixedFloatingSwapPricer
语法
irFixedFloatingSwapPricer(instrument, pricingDate,
discountCurve, forwardCurve, assetPriceCurve, [setting])
详情
计算固定利率互换(IR Fixied-Floating Swap, IRS)的定价。
参数
instrument
INSTRUMENT 类型标量,一个 IrFixedFloatingSwap 对象,表示需要定价的固定利率互换。
pricingDate
DATE 类型标量,表示定价日期。
discountCurve
MKTDATA 类型标量,一个 IrYieldCurve 对象,表示用于计算折现因子的即期曲线。
forwardCurve
MKTDATA 类型标量,一个 IrYieldCurve 对象,表示用于计算远期利率的即期曲线。
assetPriceCurve
MKTDATA 类型标量,一个 AssetPriceCurve 对象,用于传入利率互换浮动端参考利率的历史数据。
setting
可选参数,一个键为 STRING 类型,值为 ANY 类型的字典,用于指定计算设置,支持的键值对包括:
key
value
说明
calcCashFlow
BOOL
是否计算现金流
返回值
当
setting
设置 calcCashFlow 时返回一个字典。
否则,返回一个 DOUBLE 标量。
例子
例1. 以 FR_007 为参考利率的利率互换定价。
irs = {
"productType": "Swap",
"swapType": "IrSwap",
"irSwapType": "IrFixedFloatingSwap",
"version": 0,
"start": 2025.06.16,
"maturity": 2028.06.16,
"frequency": "Quarterly",
"fixedRate": 0.018,
"calendar": "CFET",
"fixedDayCountConvention": "Actual365",
"floatingDayCountConvention": "Actual365",
"payReceive": "Pay",
"iborIndex": "FR_007",
"spread": 0.0001,
"notional":["CNY", 1E8]
}
pricingDate = 2025.08.18
curve = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"version": 0,
"referenceDate": pricingDate,
"currency": "CNY",
"curveName": "CNY_FR_007",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates":[2025.08.21, 2025.08.27, 2025.09.03, 2025.09.10, 2025.09.22, 2025.10.20, 2025.11.20,
2026.02.24, 2026.05.20, 2026.08.20, 2027.02.22, 2027.08.20,2028.08.21],
"values":[1.4759, 1.5331, 1.5697, 1.5239, 1.4996, 1.5144, 1.5209,
1.5539, 1.5461, 1.5316, 1.5376, 1.5435,1.5699] / 100
}
// 为了计算定价日后面的第一笔现金流用到的浮动利率,需要传入参考利率的历史数据
// 因为 FR_007 利率互换的付息频率为季度,建议传入的 FR_007 的历史定盘数据不少于 70 个交易日
fr007HistCurve = {
"mktDataType": "Curve",
"curveType": "AssetPriceCurve",
"version": 0,
"referenceDate": pricingDate,
"currency": "CNY",
"dates":[2025.05.09, 2025.05.12, 2025.05.13, 2025.05.14, 2025.05.15, 2025.05.16, 2025.05.19, 2025.05.20, 2025.05.21, 2025.05.22,
2025.05.23, 2025.05.26, 2025.05.27, 2025.05.28, 2025.05.29, 2025.05.30, 2025.06.03, 2025.06.04, 2025.06.05, 2025.06.06,
2025.06.09, 2025.06.10, 2025.06.11, 2025.06.12, 2025.06.13, 2025.06.16, 2025.06.17, 2025.06.18, 2025.06.19, 2025.06.20,
2025.06.23, 2025.06.24, 2025.06.25, 2025.06.26, 2025.06.27, 2025.06.30, 2025.07.01, 2025.07.02, 2025.07.03, 2025.07.04,
2025.07.07, 2025.07.08, 2025.07.09, 2025.07.10, 2025.07.11, 2025.07.14, 2025.07.15, 2025.07.16, 2025.07.17, 2025.07.18,
2025.07.21, 2025.07.22, 2025.07.23, 2025.07.24, 2025.07.25, 2025.07.28, 2025.07.29, 2025.07.30, 2025.07.31, 2025.08.01,
2025.08.04, 2025.08.05, 2025.08.06, 2025.08.07, 2025.08.08, 2025.08.11, 2025.08.12, 2025.08.13, 2025.08.14, 2025.08.15
],
"values":[1.6000, 1.5600, 1.5300, 1.5500, 1.5500, 1.6300, 1.6500, 1.6000, 1.5900, 1.5800,
1.6300, 1.7000, 1.7000, 1.7000, 1.7500, 1.7500, 1.5900, 1.5800, 1.5700, 1.5600,
1.5500, 1.5500, 1.5600, 1.5900, 1.5900, 1.5700, 1.5500, 1.5600, 1.5679, 1.6000,
1.5700, 1.8500, 1.8300, 1.8400, 1.8500, 1.9500, 1.6036, 1.5800, 1.5200, 1.5000,
1.5000, 1.5100, 1.5100, 1.5300, 1.5200, 1.5500, 1.6000, 1.5400, 1.5400, 1.5000,
1.5000, 1.4800, 1.5000, 1.6000, 1.7500, 1.6400, 1.6200, 1.6300, 1.6000, 1.5000,
1.4800, 1.4700, 1.4800, 1.4900, 1.4600, 1.4600, 1.4600, 1.4800, 1.4800, 1.4900
]\100
}
instrument = parseInstrument(irs)
curve = parseMktData(curve)
discountCurve = curve
forwardCurve = curve
assetPriceCurve = parseMktData(fr007HistCurve)
// 仅计算 npv
npv = irFixedFloatingSwapPricer(instrument, pricingDate, discountCurve, forwardCurve, assetPriceCurve)
print(npv)
// 计算包括 npv、现金流
setting = {
"calcCashFlow": true
}
results = irFixedFloatingSwapPricer(instrument, pricingDate, discountCurve, forwardCurve, assetPriceCurve, setting)
print(results)
例2. 以 SHIBOR_3M 为参考利率的利率互换定价。
irs = {
"productType": "Swap",
"swapType": "IrSwap",
"irSwapType": "IrFixedFloatingSwap",
"version": 0,
"start": 2025.06.16,
"maturity": 2028.06.16,
"frequency": "Quarterly",
"fixedRate": 0.018,
"calendar": "CFET",
"fixedDayCountConvention": "Actual365",
"floatingDayCountConvention": "Actual360",
"payReceive": "Receive",
"iborIndex": "SHIBOR_3M",
"spread": 0.0001,
"notional":["CNY", 1E8]
}
pricingDate = 2025.08.18
curve1 = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"version": 0,
"referenceDate": pricingDate,
"currency": "CNY",
"curveName": "CNY_FR_007",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates":[2025.08.21, 2025.08.27, 2025.09.03, 2025.09.10, 2025.09.22, 2025.10.20, 2025.11.20,
2026.02.24, 2026.05.20, 2026.08.20, 2027.02.22, 2027.08.20,2028.08.21],
"values":[1.4759, 1.5331, 1.5697, 1.5239, 1.4996, 1.5144, 1.5209,
1.5539, 1.5461, 1.5316, 1.5376, 1.5435,1.5699] / 100
}
curve2 = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"version": 0,
"referenceDate": pricingDate,
"currency": "CNY",
"curveName": "CNY_SHIBOR_3M",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates":[2025.08.21, 2025.08.27, 2025.09.03, 2025.09.10, 2025.09.22, 2025.10.20, 2025.11.20,
2026.02.24, 2026.05.20, 2026.08.20, 2027.02.22, 2027.08.20,2028.08.21],
"values":[1.5113, 1.5402, 1.5660, 1.5574, 1.5556, 1.5655, 1.5703,
1.5934, 1.6040, 1.6020, 1.5928, 1.5842, 1.6068] / 100
}
// 为了计算定价日后面的第一笔现金流用到的浮动利率,需要传入参考利率的历史数据
// 因为 SHIBOR_3M 利率互换的付息频率为季度,建议传入的 SHIBOR_3M 的历史定盘数据不少于 70 个交易日
shibor3mHistCurve = {
"mktDataType": "Curve",
"curveType": "AssetPriceCurve",
"version": 0,
"referenceDate": pricingDate,
"currency": "CNY",
"dates":[2025.05.09, 2025.05.12, 2025.05.13, 2025.05.14, 2025.05.15, 2025.05.16, 2025.05.19, 2025.05.20, 2025.05.21, 2025.05.22,
2025.05.23, 2025.05.26, 2025.05.27, 2025.05.28, 2025.05.29, 2025.05.30, 2025.06.03, 2025.06.04, 2025.06.05, 2025.06.06,
2025.06.09, 2025.06.10, 2025.06.11, 2025.06.12, 2025.06.13, 2025.06.16, 2025.06.17, 2025.06.18, 2025.06.19, 2025.06.20,
2025.06.23, 2025.06.24, 2025.06.25, 2025.06.26, 2025.06.27, 2025.06.30, 2025.07.01, 2025.07.02, 2025.07.03, 2025.07.04,
2025.07.07, 2025.07.08, 2025.07.09, 2025.07.10, 2025.07.11, 2025.07.14, 2025.07.15, 2025.07.16, 2025.07.17, 2025.07.18,
2025.07.21, 2025.07.22, 2025.07.23, 2025.07.24, 2025.07.25, 2025.07.28, 2025.07.29, 2025.07.30, 2025.07.31, 2025.08.01,
2025.08.04, 2025.08.05, 2025.08.06, 2025.08.07, 2025.08.08, 2025.08.11, 2025.08.12, 2025.08.13, 2025.08.14, 2025.08.15
],
"values":[1.6960, 1.6720, 1.6620, 1.6530, 1.6450, 1.6470, 1.6450, 1.6420, 1.6400, 1.6400,
1.6420, 1.6430, 1.6440, 1.6470, 1.6520, 1.6520, 1.6520, 1.6520, 1.6520, 1.6510,
1.6490, 1.6450, 1.6420, 1.6390, 1.6380, 1.6360, 1.6340, 1.6300, 1.6300, 1.6290,
1.6290, 1.6290, 1.6300, 1.6300, 1.6300, 1.6300, 1.6280, 1.6195, 1.6060, 1.5970,
1.5790, 1.5700, 1.5620, 1.5590, 1.5570, 1.5610, 1.5590, 1.5590, 1.5570, 1.5550,
1.5530, 1.5490, 1.5510, 1.5530, 1.5590, 1.5600, 1.5600, 1.5640, 1.5660, 1.5630,
1.5590, 1.5580, 1.5590, 1.5600, 1.5544, 1.5490, 1.5480, 1.5480, 1.5490, 1.5470
]\100
}
instrument = parseInstrument(irs)
discountCurve = parseMktData(curve1) //CNY_FR_007
forwardCurve = parseMktData(curve2) //CNY_SHIBOR_3M
assetPriceCurve = parseMktData(shibor3mHistCurve)
// 仅计算 npv
npv = irFixedFloatingSwapPricer(instrument, pricingDate, discountCurve, forwardCurve, assetPriceCurve)
print(npv)
// 计算包括 npv、现金流
setting = {
"calcCashFlow": true
}
results = irFixedFloatingSwapPricer(instrument, pricingDate, discountCurve, forwardCurve, assetPriceCurve, setting)
print(results)
相关函数:
parseInstrument
,
parseMktData
FILE:references/doc_2903.md
# fxForwardPricer
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fxForwardPricer.html
**来源**: DolphinDB 官方文档
---
fxForwardPricer
语法
fxForwardPricer(instrument, pricingDate, spot,
domesticCurve, foreignCurve)
详情
基于给定的即期汇率、本币与外币的贴现曲线,以及定价日期,计算外汇远期合约的净现值(NPV)。
参数
instrument
一个 INSTRUMENT 类型对象(FxForward)。表示需要定价的外汇远期。外汇远期所需的关键字段见
FxForward 字段要求
。
pricingDate
DATE 类型标量,表示定价日期。
spot
DOUBLE 类型标量,表示即期汇率。
domesticCurve
MKTDATA 类型对象(IrYieldCurve),表示本币贴现曲线。曲线所需包含的关键字段见
曲线字段要求
。
foreignCurve
MKTDATA 类型对象(IrYieldCurve),表示外币贴现曲线。曲线所需包含的关键字段见
曲线字段要求
。
返回值
DOUBLE 类型标量。
例子
pricingDate = 2025.08.18
fxForward = {
"productType": "Forward",
"forwardType": "FxForward",
"version": 0,
"expiry": 2025.12.16,
"delivery": 2025.12.18,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E6],
"strike": 7.1
}
curveDates = [2025.08.21,
2025.08.27,
2025.09.03,
2025.09.10,
2025.09.22,
2025.10.20,
2025.11.20,
2026.02.24,
2026.05.20,
2026.08.20,
2027.02.22,
2027.08.20,
2028.08.21]
domesticCurveInfo = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": pricingDate,
"currency": "CNY",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": curveDates,
"values":[1.5113,
1.5402,
1.5660,
1.5574,
1.5556,
1.5655,
1.5703,
1.5934,
1.6040,
1.6020,
1.5928,
1.5842,
1.6068]/100
}
foreignCurveInfo = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": pricingDate,
"currency": "USD",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": curveDates,
"values":[4.3345,
4.3801,
4.3119,
4.3065,
4.2922,
4.2196,
4.1599,
4.0443,
4.0244,
3.9698,
3.7740,
3.6289,
3.5003]/100
}
instrument = parseInstrument(fxForward)
domesticCurve = parseMktData(domesticCurveInfo)
foreignCurve = parseMktData(foreignCurveInfo)
spot = 7.1627
npv = fxForwardPricer(instrument, pricingDate, spot, domesticCurve, foreignCurve)
print(npv)
// output: 1919.8118
相关函数:
parseInstrument
,
parseMktData
远期字段要求
字段名
类型
描述
是否必填
productType
STRING
产品名称,固定值为 "Forward"
是
forwardType
STRING
远期类型,固定值为 "FxForward"
是
notional
ANY 向量
名义本金,格式如 ["USD", 1.0]
是
instrumentId
STRING
金融工具 ID
否
expiry
DATE
到期日
是
delivery
DATE
交割日
是
currencyPair
STRING
货币对,格式如:"EURUSD","EUR.USD" 或 "EUR/USD"。支持如下货币对:
EURUSD:欧元兑美元
USDCNY:美元兑人民币
EURCNY:欧元兑人民币
GBPCNY:英镑兑人民币
JPYCNY:日元兑人民币
HKDCNY:港币兑人民币
是
direction
STRING
交易方向。可选:"Buy"、"Sell"
是
strike
DOUBLE
执行价格
是
domesticCurve
STRING
定价时参考的本币贴现曲线名称
否
foreignCurve
STRING
定价时参考的外币贴现曲线名称
否
曲线字段要求
字段名
类型
描述
是否必填
mktDataType
STRING
固定填 "Curve"
是
referenceDate
DATE
参考日期
是
version
INT
版本号,默认值 0
否
curveType
STRING
固定填 "IrYieldCurve"
是
dayCountConvention
STRING
曲线的日期计数惯例,可选值为:
"Actual360":实际天数除以360
"Actual365":实际天数除以365(不区分闰年)
"ActualActualISMA":实际天数/实际天数(ISMA规则)
"ActualActualISDA":实际天数/实际天数(ISDA规则)
是
interpMethod
STRING
内插方法,可选值为:
"Linear":线性插值
"CubicSpline":三次样条插值
"CubicHermiteSpline":三次埃尔米特样条插值
是
extrapMethod
STRING
外插方法,可选值为:
"Flat":平插
"Linear":线性插值
是
dates
DATE 向量
数据点的日期
是
values
DOUBLE 向量
数据点的值,与
dates
中的元素一一对应
是
curveName
STRING
曲线名称
否
currency
STRING
货币,可选值为"CNY", "USD", "EUR", "GBP", "JPY", "HKD"
是
compounding
STRING
复利类型,可选值为:
"Simple":单利
"Compounded":离散复利
"Continuous":连续复利
是
settlement
DATE
结算日,如果指定了结算日,则后续期限间隔的计算都将从
settlement
开始,而不是
referenceDate
否
frequency
INTEGRAL或 STRING
计息频率,可选值为:
-1 或 "NoFrequency":无效计息频率
0 或 "Once":到期一次还本付息
1 或 "Annual":每年付息一次
2 或 "Semiannual":每半年付息一次
3 或 "EveryFourthMonth":每四个月付息一次
4 或 "Quarterly":每季度付息一次
6 或 "BiMonthly":每两月付息一次
12 或 "Monthly":每月付息一次
13 或 "EveryFourthWeek":每四周付息一次
26 或 "BiWeekly":每两周付息一次
52 或 "Weekly":每周付息一次
365 或 "Daily":每日付息一次
999 或 "Other":其他计息频率
否
curveModel
STRING
曲线构建模型,目前仅支持 "Bootstrap"。
否
curveParams
DICT
模型的参数。
否
FILE:references/doc_2908.md
# createIPCInMemoryTable
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createIPCInMemoryTable.html
**来源**: DolphinDB 官方文档
---
createIPCInMemoryTable
语法
createIPCInMemoryTable(size, tableName, columnNames,
columnTypes)
详情
创建一个跨进程共享内存表的句柄。跨进程共享内存表通常作为流计算的输出表。在对时延要求极高的场景下,用户进程通过插件直接访问共享内存获取数据,极大减小了 TCP
等网络传输的时延。
跨进程共享内存表通过共享内存(由操作系统管理)进行跨进程通信。共享内存表仅支持在同一物理机内共享,不支持在集群不同物理节点间进行共享。
跨进程共享内存表支持读写,但不支持对跨进程共享内存表的表结构进行修改。向跨进程共享内存表写数据的方法,与普通内存表一致。若一次性插入的数据量大于共享内存,系统会抛出异常。
读写机制:将写入共享内存的进程作为生产者,从共享内存中读取数据的进程作为消费者。一次写入的数据将作为一个整体,供一次读取消费,且读进程依次按顺序对写入的数据进行消费。例如:第一写入
100 条数据,第二次写入 200 条数据,则第一次会读到 100 条数据,第二次会读到第二批写入的 200
条数据,以此类推。读取数据时,共享内存表中的所有数据均已被消费,则读进程会被阻塞,直到有新写入的可消费数据时,才能将数据读出。
DolphinDB
支持多进程并发写入共享内存表,以及在写入的同时进行读操作。但注意,只能同时存在一个读进程。参考上述读写机制,读取是一次性的,若不同进程并发读取,将会得到不同阶段写入的数据。
注:
此函数仅适用于 Linux 系统。
参数
size
整数,表示 table 能缓存的记录数。该值必须大于 1,000,000,否则系统自动取 1,000,000。
tableName
字符串,表示跨进程共享内存表的名称。
columnNames
字符串向量,用于指定表的列名。
columnTypes
向量,表示每列的数据类型。可使用表示数据类型的系统保留字或相应的字符串。
返回值
一个共享内存表句柄。
例子
创建一个跨进程共享内存表,并作为流数据订阅的输出表。
share streamTable(10000:0,`timestamp`temperature, [TIMESTAMP,DOUBLE]) as pubTable
ipc_t = createIPCInMemoryTable(1000000, "ipc_table", `timestamp`temperature, [TIMESTAMP, DOUBLE])
def shm_append(mutable table, msg) {
table.append!(msg)
}
subscribeTable(tableName="pubTable", actionName="act3", offset=0, handler=shm_append{ipc_t}, msgAsTable=true)
// 写入数据
n = 200
timestamp = 2022.01.01T09:00:00.000 + 1..n
temp = 30 + rand(5.0,n)
tableInsert(pubTable,timestamp,temp)
FILE:references/doc_2911.md
# getOS
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getOS.html
**来源**: DolphinDB 官方文档
---
getOS
语法
getOS()
详情
查询 DolphinDB server 所在操作系统的类型。
参数
无
返回值
字符串标量。
例子
getOS();
// output: linux
FILE:references/doc_2916.md
# lastNot
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lastNot.html
**来源**: DolphinDB 官方文档
---
lastNot
语法
lastNot(X, [k])
详情
若
X
是向量:
如果没有指定
k
,返回
X
中最后一个不为 NULL 的元素。
如果指定
k
,返回
X
中最后一个不为
k
或 NULL 的元素。
若
X
是矩阵或表,在每列内进行上述计算,返回一个向量。
lastNot
函数也支持查询分布式表和分区表。
参数
X
是向量、矩阵或表。
k
是标量。它是一个可选参数。
返回值
如果
X
是一个向量,返回一个标量。
如果
X
是一个矩阵,返回一个向量。
如果
X
是一张表,返回一张表。
例子
lastNot(1 6 0 0 0, 0);
输出返回:6
lastNot(1 6 0 0 0 2 3 0 NULL, 0);
输出返回:3
lastNot(1 6 0 0 0 2 3 0 NULL);
输出返回:0
t=table(1 1 1 1 1 2 2 2 2 2 as id, 1 2 0 0 0 3 NULL NULL 0 0 as x);
t;
输出返回:
表
1
.
id
x
1
1
1
2
1
0
1
0
1
0
2
3
2
2
2
0
2
0
select lastNot(x, 0) from t group by id;
输出返回:
id
lastNot_x
1
2
2
3
m=matrix(2 NULL 1 0 NULL, NULL 2 NULL 6 0);
m;
输出返回:
#0
#1
2
2
1
0
6 0
lastNot(m, 0);
输出返回:[1,6]
FILE:references/doc_2920.md
# pop!
**URL**: https://docs.dolphindb.cn/zh/funcs/p/pop_.html
**来源**: DolphinDB 官方文档
---
pop!
语法
pop!(X)
详情
移除
X
中的最后一个元素。
参数
X
是一个向量。
返回值
一个标量,类型同
X
,表示被移除的元素。
例子
x = 1 2 3;
pop!(x);
// output
3
x;
// output
[1,2]
FILE:references/doc_2925.md
# tmfirst
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmfirst.html
**来源**: DolphinDB 官方文档
---
tmfirst
语法
tmfirst(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
的第一个元素。
返回值
返回一个与输入
X
相同数据类型的向量。
例子
T = 1 1 1 2 5 6
X = 1 4 NULL -1 NULL 4
m = table(T as t,X as x)
select *, tmfirst(t, x, 3) from m
t
x
tmfirst_t
1
1
1
1
4
1
1
1
2
-1
1
5
6
4
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = 3 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmfirst(t, x, 3d) from m
t
x
tmfirst_t
2021.01.02
3
3
2021.01.02
4
3
2021.01.04
3
2021.01.05
-1
2021.01.07
2
-1
2021.01.08
4
2
select *, tmfirst(t, x, 1w) from m
t
x
tmfirst_t
2021.01.02
3
3
2021.01.02
4
3
2021.01.04
3
2021.01.05
-1
3
2021.01.07
2
3
2021.01.08
4
3
相关函数:
mfirst
,
first
FILE:references/doc_2929.md
# getTSDBMetaData
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getTSDBMetaData.html
**来源**: DolphinDB 官方文档
---
getTSDBMetaData
语法
getTSDBMetaData()
详情
获取 TSDB 引擎下所有 chunk 的元数据。该函数只能在数据节点上执行。
参数
无
返回值
返回一个表,包含以下列:
chunkId:chunk 的唯一标识
chunkPath:分区的物理路径
level:数据文件所在的 level 级别
table:数据表名称
files:数据文件名称,即 level file 名称
首发版本
:2.00.4
例子
getTSDBMetaData()
chunkId
chunkPath
level
table
files
7e0c65ca-5e4a-4594-2948-fa0b5...
/hdd/hdd7/test/v...
0
pt_2
0_00211490,0_002115580
7e0c65ca-5e4a-4594-2948-fa0b5...
/hdd/hdd7/test/v...
1
pt_2
1_00013041
FILE:references/doc_2931.md
# tmcovar
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmcovar.html
**来源**: DolphinDB 官方文档
---
tmcovar
语法
tmcovar(T, X, Y, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间长度衡量)的滑动窗口内,计算
X
和
Y
元素的协方差。
返回值
DOUBLE 类型向量。
例子
T = 1 1 1 2 5 6
X = 1 4 2 -1 2 4
Y = 2 5 -3 6 9 1
m = table(T as t,X as x, Y as y)
select *, tmcovar(t, y, x, 3) from m
t
x
y
tmcovar_t
1
1
2
1
4
5
4.5
1
2
-3
3.3333
2
-1
6
-1.6667
5
2
9
6
4
1
-8
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = 1 4 2 -1 2 4
Y = 2 5 -3 6 9 1
m = table(T as t,X as x, Y as y)
select *, tmcovar(t, y, x, 3d) from m
t
x
y
tmcovar_t
2021.01.02
1
2
2021.01.02
4
5
4.5
2021.01.04
2
-3
3.3333
2021.01.05
-1
6
-13.5
2021.01.07
2
9
4.5
2021.01.08
4
1
-8
select *, tmcovar(t, y, x, 1w) from m
t
x
y
tmcovar_t
2021.01.02
1
2
2021.01.02
4
5
4.5
2021.01.04
2
-3
3.3333
2021.01.05
-1
6
-1.6667
2021.01.07
2
9
-0.6
2021.01.08
4
1
-1.6
相关函数:
mcovar
,
covar
FILE:references/doc_2936.md
# tanh
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tanh.html
**来源**: DolphinDB 官方文档
---
tanh
语法
tanh(X)
详情
返回
X
的双曲正切。
参数
X
可以是标量、向量或矩阵。
返回值
DOUBLE 类型,数据形式同
X
。
例子
tanh(0 1 2);
// output
[0,0.761594,0.964028]
相关函数:
asin
,
acos
,
atan
,
sin
,
cos
,
tan
,
asinh
,
acosh
,
atanh
,
sinh
,
cosh
FILE:references/doc_2939.md
# getConfigure
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getConfigure.html
**来源**: DolphinDB 官方文档
---
getConfigure
是
getConfig
的别名。
FILE:references/doc_2943.md
# invBeta
**URL**: https://docs.dolphindb.cn/zh/funcs/i/invBeta.html
**来源**: DolphinDB 官方文档
---
invBeta
语法
invBeta(alpha, beta, X)
详情
返回 Beta 分布的累计密度函数的逆函数值。
参数
形状参数
alpha
和
beta
都是正数。
X
是 0 到 1 之间的浮点型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
invBeta(2.31, 0.627, [0.001, 0.5, 0.999]);
// output
[0.068102, 0.852866, 0.999994]
invBeta(2.31, 0.627, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output
[0.471316, 0.717156, 0.852866, 0.939378, 0.989912]]
FILE:references/doc_2952.md
# bondCalculator
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bondCalculator.html
**来源**: DolphinDB 官方文档
---
bondCalculator
语法
bondCalculator(start, maturity, issuePrice, coupon, frequency,
dayCountConvention, bondType, calendar, businessDayConvention, settlement,
price, priceType, [calcRisk=false], [benchmark='Qeubee'])
详情
该函数用于实现债券到期收益率、净价和全价三者之间的互算,同时支持计算久期、凸度等风险指标。
参数
注意:所有输入向量必须等长,输入标量将自动扩展以匹配其它向量的长度。
start
DATE 类型标量或向量,表示债券的起息日。
maturity
与
start
等长的 DATE 类型标量或向量,表示债券的到期日。
issuePrice
与
start
等长的数值型标量或向量,表示债券的发行价格。贴现债需指定真实发行价(通常小于100);其他债券通常为100。
coupon
数值型标量或向量,表示债券的票面利率。例如 0.03,表示票息为 3%。
frequency
整型或 STRING 类型的标量或向量,表示债券的付息频率。可选值为:
0/“Once”:到期一次还本付息
1/“Annual”:每年付息一次
2/“Semiannual:每半年付息一次
4/“Quarterly”:每季度付息一次
12/“Monthly”:每月付息一次
dayCountConvention
STRING 类型的标量或向量,表示债券的计息日数惯例。可选值为:
"Thirty360US":US (NASD) 30/360
"ActualActualISMA":实际/实际 (ISMA 规则)
"Actual360":实际/360
"Actual365":实际/365
"Thirty360EU":欧洲 30/360
"ActualActualISDA":实际/实际 (ISDA 规则)
bondType
STRING 类型标量或向量,表示债券的类型。可选值为:
"FixedRate":固定利率债券,定期按息票利率支付利息。
"Discount":贴现债券,没有利息支付,以贴现方式发行的债券,期末FV=面值。
"ZeroCoupon":零息债券,期末一次性支付利息和面值,期末FV=面值+利息。
calendar
STRING 类型标量,表示使用的交易日历。目前仅支持 “CFET”,表示中国人民银行债券交易日历(以 .IB 结尾的债券)。
businessDayConvention
STRING 类型的标量,表示把非工作日调整到工作日的方法。目前仅支持
“Unadjusted”,表示不作调整。
settlement
DATE 类型标量或向量,表示债券的结算日,即购买日期。
price
数值型标量或向量,具体含义取决于 priceType 的取值:
当
priceType
为 "YTM" 时,
price
表示债券的到期收益率;
当
priceType
为 "CleanPrice" 时,
price
表示债券的净价;
当
priceType
为 "DirtyPrice" 时,
price
表示债券的全价。
priceType
STRING 类型的标量或向量,用于指定债券价格类型,可选值为:
"YTM":到期收益率
"CleanPrice":净价
"DirtyPrice":全价
calcRisk
可选参数,布尔值,默认为 false,只计算输出全价、净价、应计利息和收益率。若设置为
true,除上述4项外,还会计算并输出麦考利久期、修正久期、凸度、基点价值。
benchmark
可选参数,STRING 类型标量,表示算法参考基准。目前仅支持 “Qeubee”(国内债券算法)。
返回值
字典或元组。
例子
例1. 计算固定利率债券的价格、到期收益率、应计利息和风险指标。
bondCalculator(start=2022.07.15, maturity=2072.07.15, issuePrice=100, coupon=0.034, frequency="Semiannual", dayCountConvention="ActualActualISMA", bondType="FixedRate", calendar="CFET", businessDayConvention="Unadjusted", settlement=2025.04.10, price=0.02, priceType="YTM", calcRisk=true);
/* Output:
pvbp->0.3902
ytm->0.0200
macaulayDuration->27.4761
dirtyPrice->143.4689
accruedInterest->0.7983
cleanPrice->142.6705
modifiedDuration->27.2041
convexity->1025.4003
*/
bondCalculator(start=2022.07.15, maturity=2072.07.15, issuePrice=100, coupon=0.034, frequency="Semiannual", dayCountConvention="ActualActualISMA", bondType="FixedRate", calendar="CFET", businessDayConvention="Unadjusted", settlement=2072.04.18, price=100.2143, priceType="CleanPrice", calcRisk=false);
/* Output:
accruedInterest->0.8780
cleanPrice->100.2143
ytm->0.0250
dirtyPrice->101.0923
*/
例2. 计算零息债券的价格、到期收益率、应计利息和风险指标。
bondCalculator(start=2025.01.09, maturity=2026.02.05, issuePrice=100, coupon=0.0119, frequency="Annual", dayCountConvention="ActualActualISMA", bondType="ZeroCoupon", calendar="CFET", businessDayConvention="Unadjusted", settlement=2025.04.10, price=0.025, priceType="YTM", calcRisk=true);
/* Output:
pvbp->0.0080
ytm->0.0250
macaulayDuration->0.8246
dirtyPrice->99.2322
accruedInterest->0.2966
cleanPrice->98.9355
modifiedDuration->0.8079
convexity->1.3057
*/
例3. 计算贴现债券的价格、到期收益率、应计利息和风险指标。
bondCalculator(start=2025.02.13, maturity=2025.05.15, issuePrice=99.663, coupon=0.0, frequency="Once", dayCountConvention="ActualActualISMA", bondType="Discount", calendar="CFET", businessDayConvention="Unadjusted", settlement=2025.04.10, price=0.02, priceType="YTM", calcRisk=true);
/* Output:
pvbp->0.0009
ytm->0.0200
macaulayDuration->0.0958
dirtyPrice->99.8085
accruedInterest->0.2073
cleanPrice->99.6012
modifiedDuration->0.0957
convexity->0.0183
*/
例4. 同时计算多种债券的价格、到期收益率、应计利息和风险指标。
result = bondCalculator(start=[2025.02.13, 2025.01.09, 2022.07.15], maturity=[2025.05.15, 2026.02.05, 2072.07.15], issuePrice=[99.663, 100, 100], coupon=[0.0, 0.0119, 0.034], frequency=["Once", "Annual", "Semiannual"], dayCountConvention=["ActualActualISMA", "ActualActualISMA", "ActualActualISMA"], bondType=["Discount", "ZeroCoupon", "FixedRate"], calendar=["CFET", "CFET", "CFET"], businessDayConvention=["Unadjusted", "Unadjusted", "Unadjusted"], settlement=[2025.04.10, 2025.04.10, 2072.04.18], price=[0.02, 0.025, 100.2143], priceType=["YTM", "YTM", "CleanPrice"], calcRisk=true);
print result
/* Output:
(dirtyPrice->99.808586272901294
cleanPrice->99.601201657516682
ytm->0.02
accruedInterest->0.207384615384617
macaulayDuration->0.095890410958904
modifiedDuration->0.095706863549357
convexity->0.018319607460911
pvbp->0.000955236674747
,dirtyPrice->99.232212603180983
cleanPrice->98.935527671674137
ytm->0.025
accruedInterest->0.296684931506849
macaulayDuration->0.824657534246575
modifiedDuration->0.80799946312328
convexity->1.305726264815019
pvbp->0.008017957450791
,dirtyPrice->101.092321978021971
cleanPrice->100.214299999999994
ytm->0.025000792220527
accruedInterest->0.878021978021978
macaulayDuration->0.240437158469945
modifiedDuration->0.239000497930427
convexity->0.114242476021984
pvbp->0.002416111528969
)
*/
相关函数:
bondAccrInt
、
bondConvexity
、
bondDirtyPrice
、
bondDuration
、
bondYield
FILE:references/doc_2959.md
# cummax
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cummax.html
**来源**: DolphinDB 官方文档
---
cummax
语法
cummax(X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累计最大值。
返回值
返回一个与输入
X
相同数据类型和形式的对象。
例子
x = [7,4,5,8,9]
cummax(x);
// output
[7,7,7,8,9]
m = matrix(6 5 7 8 1, 3 9 4 2 10);
m;
#0
#1
6
3
5
9
7
4
8
2
1
10
cummax(m);
#0
#1
6
3
6
9
7
9
8
9
8
10
相关函数:
cummin
,
max
FILE:references/doc_2965.md
# revokeStreamingSQL
**URL**: https://docs.dolphindb.cn/zh/funcs/r/revokeStreamingSQL.html
**来源**: DolphinDB 官方文档
---
revokeStreamingSQL
语法
revokeStreamingSQL(queryId)
详情
注销一个通过
registerStreamingSQL
注册的流式 SQL 查询。只能注销当前用户自己注册的查询。
参数
queryId
字符串标量,表示已注册的流式 SQL 查询的 ID。
例子
t=table(1..10 as id,rand(100,10) as val)
share t as st
declareStreamingSQLTable(st)
registerStreamingSQL("select avg(val) from st","sql_avg")
// 查看流式 SQL 查询的状态
getStreamingSQLStatus("sql_avg")
// 注销流式 SQL 查询
revokeStreamingSQL("sql_avg")
相关函数:
declareStreamingSQLTable
,
getStreamingSQLStatus
,
registerStreamingSQL
FILE:references/doc_2977.md
# 快速上手
**URL**: https://docs.dolphindb.cn/zh/getstarted/chap1_getstarted.html
**来源**: DolphinDB 官方文档
---
快速上手
本节以简短的例子展示如何在使用 DolphinDB 的初期完成快速部署、建立数据库、建立数据表、写入数据、导入数据、查询数据等基本操作。DolphinDB
为用户提供了更多丰富内容,请点击页面左侧的相应主题章节以了解更多细节。
1. 安装使用
1.1 下载与安装
步骤一:前往
DolphinDB 官网
下载 DolphinDB server 压缩包。
步骤二:将 DolphinDB server 压缩包解压到本地目录。
1.2 启动 server
server
目录中包含 Web 集群管理工具、服务端程序以及 license
文件。解压完成后不需要进一步安装。若有更多部署需求,可参考文档:
单节点部署与升级
单服务器集群部署与升级
多服务器集群部署与升级
高可用集群部署与升级
云环境部署
下面以单节点为例。进入 server 目录直接启动执行文件。以下是不同系统的启动指令示例:
Linux 系统前台运行:
cd path_to_DolphinDB_server //请修改为当前 DolphinDB/server 所在的实际路径
chmod +x dolphindb //首次启动时需要修改文件权限
./dolphindb
图
1
.
图 1-1 Linux 系统中 server 成功启动后的界面
Windows 系统:双击
dolphindb.exe
文件,或者右键单击文件后选择“打开”。
图
2
.
图 1-2 Windows 系统中 server 成功启动后的界面
图 1-1 和图 1-2 中都会显示当前 server 的版本号、许可证的授权类型(trial 试用版/test 测试版/commercial
商业版,可替换)和到期时间、server 的最新编译时间。
注:
如使用其他版本 license,则将 license 文件名改为
dolphindb.lic
,并将其替换社区版中的同名文件即可使用。
系统默认端口号为 8848。如需自定义端口,请编辑同级目录下的配置文件
dolphindb.cfg
,并修改
localSite
配置项
。例如修改为“localSite=localhost:8890:datanode”,修改后保存文件,并重新启动
server。
1.3 连接客户端
DolphinDB 提供
VSCode
Extension
,
Web Console
,
Java GUI
等多种
客户端
,其中更推荐用户使用 VSCode
Extension,本节为方便介绍如何快速上手,将以 Web Console (后文将简称为 Web)为例进行说明。
注:
防火墙需要开放对应端口。
步骤一:在浏览器地址栏中输入
<ip>:<port>
即 DolphinDB 所在服务器的 IP 和端口号。例如,通过 Web
访问在本机部署的单节点服务器的地址为:
http://localhost:8848
步骤二:登录
点击 Web
客户端左上区域的“去登录”。在登录界面中输入正确的用户名和密码(首次登录请使用账号“admin”和密码“123456”),最后点击“登录”。
注:
若不登录依然可以执行脚本,但无法查看分布式数据库的结构,且可能无法使用部分权限。
2. 建库建表
DolphinDB 可以通过
database
/
table
函数或者 SQL 语句来建库建表。此处以 SQL 编程为例,创建一个按 SYMBOL
类型的值分区的数据库,并在该数据库中创建一个数据表。下图为 Web 界面的简易说明,更多详细文档可参考
DolphinDB-交互编程
。
图
3
.
图 2-1 Web 界面简易说明
在后文中,将以简单的股票数据为例,包含
TradeTime(日期时间)、SecurityID(证券代码)、TotalVolumeTrade(累计成交量)、TotalValueTrade(累计成交金额)四类基本信息,并根据这些信息进行库表查询操作。
首先使用
create 语句
创建名为 db
的分布式数据库(以 OLAP 引擎为例)。复制粘贴下述代码至 DolphinDB Web 的编辑器中,选中需要执行代码点击执行(执行快捷键:Ctrl+E)即可。
CREATE DATABASE "dfs://db"
PARTITIONED BY VALUE(2020.01.01..2021.01.01), HASH([SYMBOL, 4])
然后使用 create 语句在 db 数据库中创建名为 tb 的数据表。其中分区列为
TradeTime
和
SecurityID
。在编辑器中输入并选中下述脚本,然后执行。
注:
DolphinDB
支持在数据库层面进行多种类型的分区,此处仅为示例。选择合适的分区类型,不仅利于用户根据业务特点对数据进行均匀分割,还可以降低系统响应延迟、提高数据吞吐量。更多说明可阅读文档
数据分区
。
CREATE TABLE "dfs://db"."tb"(
TradeTime TIMESTAMP
SecurityID SYMBOL
TotalVolumeTrade LONG
TotalValueTrade DOUBLE
)
partitioned by TradeTime, SecurityID
点击数据库浏览器上方的刷新按钮,可以查看前述步骤创建的数据库和数据表。
图
4
.
图 2-2 分区数据库表结构
运行不报错,即说明执行成功。
可以执行下述代码查看分区表的表结构信息:
loadTable("dfs://db", "tb").schema().colDefs
返回结果:
图
5
.
图 2-3 分区表结构
3. 导入数据
下载示例数据
testdata.csv
,并上传到
DolphinDB 部署的 server 目录下。执行下述代码,将 CSV
文本数据从磁盘导入到分布式数据表中。(
"path_to_testdata.csv"
请替换为具体路径的数据文件)
tmp = loadTable("dfs://db", "tb").schema().colDefs
schemaTB = table(tmp.name as name, tmp.typeString as type)
loadTextEx(dbHandle=database("dfs://db"), tableName="tb", partitionColumns=`TradeTime`SecurityID, filename="path_to_testdata.csv", schema=schemaTB)
成功导入后可以执行下述代码,将表数据
加载
至内存中进行查看:
select * from loadTable("dfs://db", "tb")
返回结果:
图
6
.
图 3-1 导入表数据
注:
在当前示例 Web 中规定小数位数为 2 位,用户亦可自行设置。
关于 DolphinDB
数据导入的更多说明如表头包含数字的正确处理、如何实现自动解析数据类型、手动导入日期与时间格式数据的方法、提升数据导入效率的技巧等问题可参阅教程
数据导入最容易忽略的十个细节
。
4. 查询数据
基于前文已经建立的表,指定条件进行查询操作。
例 1
查询分区表 tb 中所有总记录数。
SELECT count(*) FROM loadTable("dfs://db", "tb")
//Output: 16
例 2
查询分区表 tb 中所有 SecurityID = A00001 的数据。
SELECT * FROM loadTable("dfs://db", "tb") WHERE SecurityID = `A00001
返回结果:
图
7
.
图 4-1 例 2 返回结果
例 3
根据 SecurityID 分组,使用
group
by
查询每支股票中 TotalVolumeTrade 列的平均值和 TotalValueTrade 列的最大值。
SELECT avg(TotalVolumeTrade), max(TotalValueTrade) FROM loadTable("dfs://db", "tb") group by SecurityID
返回结果:
图
8
.
图 4-2 例 3 返回结果
例 4
根据 SecurityID 分组,使用
context
by
查询每支股票最后两条记录。
注:
context by 是 DolphinDB 的独有功能,能够简化对时间序列数据的操作。
select * from loadTable("dfs://db", "tb") context by SecurityID limit -2
图
9
.
图 4-3 例 4 返回结果
例 5
使用
pivot by
将表 tb 的
TradeTime 列作为行索引,SecurityID 列作为列索引,查看 TotalValueTrade 列的值。
注:
pivot by 是 DolphinDB 的独有功能,能够将表中一列或多列的内容按照两个维度重新排列等。
select TotalValueTrade from loadTable("dfs://db", "tb") pivot by TradeTime, SecurityID
图
10
.
图 4-4 例 5 返回结果
5. 学习建议
针对不同角色的专业人士,我们为您量身定制了学习路径:
若您是数据分析工程师,建议您深入探索
SQL
查询
的重要操作,包括聚合操作、时序数据处理以及表关联技巧。同时,
流数据框架
中的订阅机制和引擎级联计算也值得您重点关注,这将大大提升您应对吞吐量大、时延要求高、复杂实时分析等业务场景的能力。(点击了解
DolphinDB 中的 SQL
标准化
)
若您是数据库开发工程师,则可以将重心放在
数据库核心概念
和
DolphinDB
编程语言
上。这些知识将帮助您充分利用 DolphinDB 的高性能特性,开发出更加高效的数据应用。
若您是数据库运维工程师,
系统运维
和
故障排查
章节将是您的必修课。掌握这些内容,您将能够确保DolphinDB 系统的稳定运行和高效管理。
最后,诚邀您了解并参与 DolphinDB 数据库专员(DolphinDB Certified Associate) 、DolphinDB
数据分析专员(DolphinDB Certified Data Analytics Associate) 的
认证考试
。您将获得来自 DolphinDB 官方的权威认可,同时探索数据领域的更多内容。
6. 技术支持
若在使用 DolphinDB 的过程中碰到无法解决的问题,您可通过以下途径获取帮助信息和技术支持:
渠道
说明
ASK 社区
在
DolphinDB 问答社区
提问。技术支持人员会尽可能在 1
个工作日内回复。
请注意:提问时请尽量描述清使用的 server 版本号(如 2.00.12 JIT)/API 版本号(如
3.0.0.0)/插件版本号,操作系统(win / linux),OS
内核版本号等信息,另请尽量描述清遇到的问题,同时上传文件、截图等,以方便工作人员解答。
教程文档
DolphinDB 准备了覆盖不同场景、不同需求的
使用教程
。用户可根据需求自行阅读。
智臾科技知乎主页
知乎的
智臾科技公司主页
是 DolphinDB
产品对外发布的主要社媒平台。与产品相关的技术和测评类文章,都可以在知乎上找到。常设专栏:
DolphinDB
与量化金融
DolphinDB
与物联网
DolphinDB
测评报告
DolphinDB
视频教程
DolphinDB
客户故事
电子邮件
发邮件至:[email protected]。DolphinDB 技术支持人员尽可能在 1
个工作日内回复您的问题。较为复杂的问题可能需要更多的时间进行分析和答复。我们希望您:
尽量详细描述您遇到的问题、软硬件环境、问题发生的业务场景等。
附上电话或微信等联系方式,以便深入交流。
技术交流群
扫描下方二维码,或者添加客服微信:13306510479,加入技术交流群:
7. 视频课程
DolphinDB 在国内外主流视频平台投放技术探讨、产品介绍、公开课录屏等精品视频:
国内平台:
DolphinDB 数据库入门
:以视频形式生动讲解
DolphinDB 的基本安装,如何在 DolphinDB
中建库建表、写入数据、查询数据、备份恢复、权限管理与作业管理,DolphinDB TSDB
引擎的深度讲解,以及如何进行DolphinDB 的运维等。
DolphinDB 流数据入门
:通过视频演示如何在
DolphinDB 中部署和发布流数据、如何使用强大的流数据计算引擎,以及发布-订阅模型的详细介绍等。
DolphinDB 公开课
:TSDB
存储引擎、模拟撮合引擎、窗口计算、流数据、Python API、C++ API、Java API……
更多
:直播回放、教程视频、……
国外平台:
YouTube
FILE:references/doc_2979.md
# getBackupList
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getBackupList.html
**来源**: DolphinDB 官方文档
---
getBackupList
语法
getBackupList(backupDir, dbPath, tableName)
详情
查看指定分布式表的所有备份信息。
参数
backupDir
是字符串,表示存放备份数据的目录。
dbPath
是字符串,表示分布式数据库的名称。
tableName
是字符串,表示数据库中表的名称。
返回值
返回一个表,包含指定分布式表的备份信息,每个分区对应表中的一行。其中表中各字段的含义如下:
chunkID:分区的 ID。
chunkPath:分区的完整路径。
cid:版本号。
rows:分区数据包含的行数。
updateTime:chunk 最后一次更新的时间戳。
例子
if(existsDatabase("dfs://valuedb")){
dropDatabase("dfs://valuedb")
}
n=3000000
month=take(2000.01M..2000.04M, n);
x=1..n
t=table(month,x);
db=database("dfs://valuedb", VALUE, 2000.01M..2000.04M)
pt = db.createPartitionedTable(t, `pt, `month);
pt.append!(t);
backup("/home/DolphinDB/backup","dfs://valuedb",tableName="pt");
getBackupList("/home/DolphinDB/backup","dfs://valuedb","pt");
chunkID
chunkPath
cid
rows
updateTime
0061427c-4b24-e3b6-425c-c0e1553d3c35
dfs://valuedb/200001M/b39
13,348
750,000
2022.09.21T15:45:50.931
dabbd90d-6001-f8a9-4d3e-8000d96eba68
dfs://valuedb/200002M/b39
13,348
750,000
2022.09.21T15:45:50.931
f5c259b4-4be3-f385-46d4-1a1a2d224e9d
dfs://valuedb/200003M/b39
13,348
750,000
2022.09.21T15:45:50.931
6ed58eb9-a2ae-6197-4f81-3186ca1e8b20
dfs://valuedb/200004M/b39
13,348
750,000
2022.09.21T15:45:50.931
FILE:references/doc_2985.md
# bucketCount
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bucketCount.html
**来源**: DolphinDB 官方文档
---
bucketCount
语法
bucketCount(vector, dataRange, bucketNum,
[includeOutbound=false])
详情
函数
bucketCount
有和
bucket
相同的参数,但是返回每个桶中元素的计数。
参数
vector
一个数值或时间向量。
dataRange
一对表示数据范围的值,包括下限,不包括上限。
bucketNum
桶的数量。当
dataRange
是整型数据对时,它的范围大小必须是
bucketNum
的整数倍。
includeOutbound
一个可选的布尔值,表明是否包括小于下限的值,和大于等于上限的值。默认值为 false。
返回值
返回一个长度为
bucketNum
的 INT 类型向量。
例子
bucketCount(9 23 54 36 46 12, 12:54, 2);
// output
[2,2]
bucketCount(9 23 54 36 46 12, 12:54, 2, 1);
// output
[1,2,2,1]
FILE:references/doc_2992.md
# getTableSchemaByCluster
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getTableSchemaByCluster.html
**来源**: DolphinDB 官方文档
---
getTableSchemaByCluster
语法
getTableSchemaByCluster(clusterName, dbUrl, table)
详情
获取指定表的 schema。只能由管理员在 MoM(Master of Master,管理集群)上执行该函数。
参数
clusterName
字符串标量,表示要查询的集群名称。
dburl
字符串标量,表示要查询的数据库路径。
table
字符串标量,表示要查询的表名。
返回值
一个字典,与
schema(table)
的结果相同。
例子
getTableSchemaByCluster("MoMSender", "dfs://db1", "dt")
/* Output:
colDefs->name typeString typeInt extra comment
--------- ---------- ------- ----- -------
timestamp SECOND 10
sym STRING 18
qty INT 4
price DOUBLE 16
chunkPath->
partitionColumnIndex->-1
*/
相关函数:
schema
FILE:references/doc_2997.md
# window join
**URL**: https://docs.dolphindb.cn/zh/progr/sql/windowjoin.html
**来源**: DolphinDB 官方文档
---
window join
语法
窗口连接
wj(leftTable, rightTable, window, aggs, matchingCols, [rightMatchingCols])
现行窗口连接
pwj(leftTable, rightTable, window, aggs, matchingCols, [rightMatchingCols])
参数
leftTable
和
rightTable
是连接的表。
注:
rightTable
不能是分布式表。
window
一个整型数据对或 DURATION 数据对,表示以左表中最后一个连接列的值 t
为基准,在右表中查找匹配记录的窗口边界(数值范围),其中左右边界都包含在内。
aggs
表示聚合函数的元代码,详情请参考
元编程
,支持输入元组。聚合函数中的参数必须是右表中的数值类型列。
支持输出右表字段的不定长 array vector。
matchingCols
是表示连接列的字符串标量或向量。
rightMatchingCols
是表示右表连接列的字符串标量或向量。当
leftTable
和
rightTable
至少有一个连接列不同时,必须指定
rightMatchingCols
。返回结果中的连接列与左表的连接列名称相同。
详情
window join 是 asof join 的扩展。与 asof join 一样:
如果只有 1 个连接列,则 window join 假定右表已按照连接列排过序;
如果有多个连接列,则 window join
假定右表根据除最后一个连接列外的其他连接列定义分组,每个分组根据最后一个连接列排序。右表的其他连接列不需要排序;
如果这些条件不符合,处理将与期望值不符。左表不需要排序。
若连接分区表,分组字段必须包含全部分区列。
连接逻辑:
当
window = w1:w2
时,左表中每条记录的最后一个连接列的值记为
t
,在右表中查找满足以下条件的记录:
其他连接列与当前左表记录对应列的值相等;
最后一个连接列的值位于 [t + w1, t + w2] 范围内(闭区间);
然后对这些匹配的右表记录应用聚合函数。
wj
和
pwj
的区别:
如果右表没有与 t+w1(窗口左边界)匹配的值,
wj
的窗口左边界值为空,而
pwj
会选择 (t+w1) 前的最后一个值,将其并入窗口。
如果右表有多个与 t+w1(窗口左边界)匹配的值时,
wj
的窗口会包含所有重复的值,而
pwj
只包含最后一行。
特殊情况:
如果
window
= 0:0 ,右表的计算窗口将由左表两条数据的时间戳决定。假设左表某一条记录时间戳为
t,上一条记录的时间戳为 t0,则右表根据
matchingCols
其他列匹配后的计算窗口为 [t0, t)。
优化函数:
以下聚合函数经过优化,使得它们在 window join 中的计算速度更快:
avg
,
beta
,
count
,
corr
,
covar
,
first
,
last
,
max
,
med
,
min
,
percentile
,
std
,
sum
,
sum2
,
var
,
wavg
,
kurtosis
,
prod
,
skew
,
stdp
,
varp
,
atImin
,
atImax
firstNot
,
lastNot
注:
在 window join 中,当
aggs
中使用 atImax 和 atImin
进行计算时,如果计算窗口内中有多个相同的最值,默认取最大索引值对应的记录。
例子
例1. 基础功能示例
t1 = table(`A`A`B as sym, 09:56:06 09:56:07 09:56:06 as time, 10.6 10.7 20.6 as price)
t2 = table(take(`A,10) join take(`B,10) as sym, take(09:56:00+1..10,20) as time, (10+(1..10)\10-0.05) join (20+(1..10)\10-0.05) as bid, (10+(1..10)\10+0.05) join (20+(1..10)\10+0.05) as offer, take(100 300 800 200 600, 20) as volume);
t1;
sym
time
price
A
09:56:06
10.6
A
09:56:07
10.7
B
09:56:06
20.6
t2;
sym
time
bid
offer
volume
A
09:56:01
10.05
10.15
100
A
09:56:02
10.15
10.25
300
A
09:56:03
10.25
10.35
800
A
09:56:04
10.35
10.45
200
A
09:56:05
10.45
10.55
600
A
09:56:06
10.55
10.65
100
A
09:56:07
10.65
10.75
300
A
09:56:08
10.75
10.85
800
A
09:56:09
10.85
10.95
200
A
09:56:10
10.95
11.05
600
B
09:56:01
20.05
20.15
100
B
09:56:02
20.15
20.25
300
B
09:56:03
20.25
20.35
800
B
09:56:04
20.35
20.45
200
B
09:56:05
20.45
20.55
600
B
09:56:06
20.55
20.65
100
B
09:56:07
20.65
20.75
300
B
09:56:08
20.75
20.85
800
B
09:56:09
20.85
20.95
200
B
09:56:10
20.95
21.05
600
wj(t1, t2, -5s:0s, <avg(bid)>, `sym`time);
sym
time
price
avg_bid
A
09:56:06
10.6
10.3
A
09:56:07
10.7
10.4
B
09:56:06
20.6
20.3
wj(t1, t2, -5:-1, <[wavg(bid,volume), wavg(offer,volume)]>, `sym`time);
sym
time
price
wavg_bid
wavg_offer
A
09:56:06
10.6
10.295
10.395
A
09:56:07
10.7
10.32
10.42
B
09:56:06
20.6
20.295
20.395
t3=t2
t3.rename!(`time, `second)
wj(t1, t3, -2:2, <[wavg(bid,volume), wavg(offer,volume)]>, `sym`time, `sym`second);
sym
time
price
wavg_bid
wavg_offer
A
09:56:06
10.6
10.595
10.695
A
09:56:07
10.7
10.645
10.745
B
09:56:06
20.6
20.595
20.695
计算市场上买入价和卖出价之间的平均差占卖出价平均值的比例。
wj(t1, t2, -5s:0s, <avg(offer-bid)/avg(offer)>, `sym`time);
sym
time
price
avg_bid_div
A
09:56:06
10.6
0.0096
A
09:56:07
10.7
0.0095
B
09:56:06
20.6
0.0049
window join是asof join的扩展:
wj(t1, t2, -100:0, <[last(bid) as bid, last(offer) as offer]>, `sym`time);
sym
time
price
bid
offer
A
09:56:06
10.6
10.55
10.65
A
09:56:07
10.7
10.65
10.75
B
09:56:06
20.6
20.55
20.65
select sym, time, price, bid, offer from aj(t1, t2, `sym`time);
sym
time
price
bid
offer
A
09:56:06
10.6
10.55
10.65
A
09:56:07
10.7
10.65
10.75
B
09:56:06
20.6
20.55
20.65
prevailing window join:
delete from t2 where 09:56:04<=time<=09:56:06;
t2;
sym
time
bid
offer
volume
A
09:56:01
10.05
10.15
100
A
09:56:02
10.15
10.25
300
A
09:56:03
10.25
10.35
800
A
09:56:07
10.65
10.75
300
A
09:56:08
10.75
10.85
800
A
09:56:09
10.85
10.95
200
A
09:56:10
10.95
11.05
600
B
09:56:01
20.05
20.15
100
B
09:56:02
20.15
20.25
300
B
09:56:03
20.25
20.35
800
B
09:56:07
20.65
20.75
300
B
09:56:08
20.75
20.85
800
B
09:56:09
20.85
20.95
200
B
09:56:10
20.95
21.05
600
wj(t1, t2, -1:1, <[first(bid), avg(offer)]>, `sym`time);
sym
time
price
first_bid
avg_offer
A
09:56:06
10.6
10.65
10.75
A
09:56:07
10.7
10.65
10.8
B
09:56:06
20.6
20.65
20.75
例2. 以 tuple 方式动态传参给 aggs。
aggs = array(ANY, 3) //定义一个包含元代码的aggs元组
aggs[0] = <min(bid)>
aggs[1] = <min(offer)>
aggs[2] = <min(volume)>
wj(t1, t2, -5s:0s, aggs, `sym`time);
sym
time
price
min_bid
min_offer
min_volume
A
09:56:06
10.6
10.05
10.15
100
A
09:56:07
10.7
10.15
10.25
100
B
09:56:06
20.6
20.05
20.15
100
例3. pwj 函数示例
pwj(t1, t2, -1:1, <[first(bid), avg(offer)]>, `sym`time);
sym
time
price
first_bid
avg_offer
A
09:56:06
10.6
10.25
10.55
A
09:56:07
10.7
10.25
10.65
B
09:56:06
20.6
20.25
20.55
在上面的例子中,以左表的第一条记录为例,wj 和 pwj 会在右表中查找 (09:56:06-1) 到 (09:56:06+1) 的数据,wj 使用右表 sym 列中
"A" 在 09:56:07 的数据来计算 first(bid) 和 avg(offer),然而
pwj
使用的是右表 sym 列中
"A" 在 09:56:03 和 09:56:07 的数据。
特殊用法:
wj(t1, t2, 0:0, <[last(bid), bid]>, `sym`time)
返回:
sym
time
price
last_bid
bid
A
09:56:06
10.6
10.45
[10.05, 10.15, 10.25, 10.35, 10.45]
A
09:56:07
10.7
10.55
[10.55]
B
09:56:06
20.6
20.45
[20.05, 20.15, 20.25, 20.35, 20.45]
FILE:references/doc_2998.md
# flip
**URL**: https://docs.dolphindb.cn/zh/funcs/f/flip.html
**来源**: DolphinDB 官方文档
---
flip
是
transpose
的别名。
FILE:references/doc_3003.md
# subscribeTable
**URL**: https://docs.dolphindb.cn/zh/funcs/s/subscribeTable.html
**来源**: DolphinDB 官方文档
---
subscribeTable
语法
subscribeTable([server],tableName,[actionName],[offset=-1],handler,[msgAsTable=false],[batchSize=0],[throttle=1],[hash=-1],[reconnect=false],[filter],[persistOffset=false],[timeTrigger=false],[handlerNeedMsgId=false],[raftGroup],[userId=""],[password=""]
,[udpMulticast=false]
)
详情
从客户端节点订阅本地或远程服务器的流数据表。可在
handler
调用函数来处理订阅数据。
跨集群订阅 Orca 流表,需先完成多集群配置,通过指定
tableName
实现。若跨集群订阅的 Orca
表是一个高可用流表,其所属的
raftGroup
在本地集群存在一个 Learner,则订阅时将优先订阅本地副本。
如果指定了
batchSize
,当未处理消息数量达到
batchSize
或距离上次
handler
被触发已过去
throttle
秒,
handler
将会被触发。
如果订阅的表被重定义了,为了保证订阅能够正常使用,需要使用
unsubscribeTable
命令取消订阅,然后重新创建订阅。
在高可用订阅流数据写入分布式表的场景下,订阅节点构成的 raft 组发生 leader
切换或集群重启时,可能导致之前登录的用户退出。由于 guest 用户无权限写入分布式表,写入会被中断(可以通过
getCurrentSessionAndUser
函数查看当前的用户)。若配置
userId
和
password
参数,用户退出后系统会自动尝试重新登录,以保证订阅数据成功写入分布式表。
需要注意的是,从 2.00.10.10 开始,用户可以通过配置项
enhancedSecurityVerification
控制在登录时是否约束密码重试的次数。若不设置
enhancedSecurityVerification
,则不约束;若设置
enhancedSecurityVerification
=true,则当用户登录时,在1分钟内连续5次使用了错误密码,会导致用户被锁定,必须等待10分钟后才可以再次登录。
如果使用 UDP 组播作为订阅发布方式,为保证组播性能,需要为发布端所在服务器的 socket 缓冲区设置合理的数值,推荐数值大于或等于 1MB。在 Linux 中的
socket 缓冲区的设置方法如下:
在 Linux 终端中,运行以下命令:
sudo sysctl -w net.core.rmem_default=1048576
sudo sysctl -w net.core.rmem_max=1048576
sudo sysctl -w net.core.wmem_default=1048576
sudo sysctl -w net.core.wmem_max=1048576
也可以编辑
/etc/sysctl.conf
文件,添加或修改
net.core.rmem_default
,
net.core.rmem_max
,
net.core.wmem_default
和
net.core.wmem_max
的值为 1048576
后运行
sudo sysctl -p
注:
在 TCP 和 UDP 之间切换订阅发布方式时,需要先使用
unsubscibeTable
取消已有订阅,再使用
subscribeTable
建立新的订阅任务。
注:
为流数据 join 引擎订阅数据时,
handler
参数需要为
appendForJoin
、
getLeftStream
或
getRightStream
函数。
参数
只有
tableName
和
handler
两个参数是必选参数。其他所有参数都是可选参数。
server
是一个字符串,表示服务器的别名或远程连接的句柄。如果未指定或者为空字符串,表示流数据所在的服务器是本地实例。
tableName
是被订阅的数据表名。该表必须为共享的流数据表。
跨集群订阅 Orca 流表时,格式为
fqn@cluster_identifier
,例如
demo.orca_table.trades@cluster_BeiJing
。
actionName
是一个字符串,表示订阅任务的名称。它可以包含字母,数字和下划线,并以字母开头。如果一个节点有多个订阅任务均订阅了同一张表,则每个订阅必须指定唯一的
actionName
。
offset
是一个整数,指定订阅任务的起始位置,对应流数据表中的一行记录。正整数表示从指定位置的记录开始订阅。其特殊取值含义如下:
当
offset
= -1(默认)时,订阅将从流数据表的
当前最新行
开始,接收实时新增的数据。
当
offset
= 0
时,系统将从流表的
第一条记录
开始订阅。注意:若流表开启了持久化,系统会清理超过指定保留时间的数据,此时设置
offset
=
0 可能会导致订阅失败,建议指定 offset =
getPersistenceMeta
(StreamTable).diskOffset,从持久化流表
磁盘上的第一行记录
开始订阅。
若流表开启持久化,指定
offset
= -2,且
persistOffset
=
true,系统会从
上一次流订阅结束的位置
开始订阅。
当
offset
= -3
时,从流表的
当前可获取的最早一条记录
开始订阅,包括内存中和持久化在磁盘上的数据。
注意:
offset
是相对于流数据表创建时的第一行的定位,内存数据回收不会影响持久化数据的定位。
handler
是一元函数、二元函数或数据表,用于处理订阅的数据。
一元函数:它唯一的参数是订阅的数据。订阅的数据可以是一个表或元组,订阅数据表的每个列是元组的一个元素。
handlerNeedMsgId
= true 时,
handler
必须是二元函数,其两个参数分别是订阅的数据(msgBody)和数据偏移量(msgId)。详见
handlerNeedMsgId
参数说明。
数据表:可以是流数据引擎、共享流数据表、共享内存表、共享键值表、共享索引表或 DFS 表。订阅数据会直接插入到该表中。
msgAsTable
是布尔值,表示订阅的数据是否为表。默认值是 false,表示订阅的数据是由列组成的元组。
batchSize
是一个整数,用于指定触发消息处理的最小未处理消息数。
当
batchSize
> 0 时,表示当未处理消息数量累计达到或超过
batchSize
时,
handler
才会处理消息。
当
batchSize
未指定或 ≤ 0 时,
handler
会在每批消息到达后立即处理。
注:
batchSize
并不是严格的分批大小,而是一个
触发阈值
。设置
batchSize
= n 时,
handler
可能处理 n 条或更多消息
,而不会对上游单次发布的数据进行强制拆分。比如
batchSize
= 300,若上游一次发布 400
条消息,则
handler
会一次性处理 400 条消息;若上游多次发布,每次 200 条,则在未处理的消息累计超过 300
条后触发处理。
throttle
是一个浮点数,单位为秒,默认值为1。表示继上次
handler
处理消息之后,若
batchSize
条件一直未达到,多久后再次处理消息。如果没有指定
batchSize
,
throttle
即使指定,也不起作用。 若
throttle
需要设置小于1秒,则需要先修改配置项
subThrottle
。
hash
是一个非负整数,指定某个订阅线程处理进来的消息。如果没有指定该参数,系统会自动分配一个线程。如果需要使用同一个线程来处理多个订阅任务的消息,可把这些订阅任务的 hash
设置为相同的值。
reconnect
是一个布尔值,表示订阅中断后,是否会自动重新订阅。默认值为 false。如果
reconnect
= true,有以下三种情况:
如果发布端与订阅端处于正常状态,但是网络中断,那么订阅端会在网络正常时,自动从中断位置重新订阅。
如果发布端崩溃,订阅端会在发布端重启后不断尝试重新订阅。
如果发布端对流数据表启用了持久化,发布端重启后会首先读取硬盘上的数据,直到发布端读取到订阅中断位置的数据,订阅端才能成功重新订阅。
如果发布端没有对流数据表启用持久化,那么订阅端将自动重新订阅失败。
如果订阅端崩溃,订阅端重启后不会自动重新订阅,需要重新执行
subscribeTable
函数。
注:
如果订阅高可用流数据表,需要设置
reconnect
为 true,以保证 leader
发生切换时可以成功连接新的 leader。
filter
用来指定过滤条件。主要分以下两种用法:
若配合
setStreamTableFilterColumn
函数一起使用来指定流数据表的过滤列,则流数据表过滤列在
filter
中的数据才会发布到订阅端,不在
filter
中的数据不会发布。
filter
不支持过滤 BOOL
类型数据。
filter
参数可以使用以下三种方法指定。
值过滤:一个向量。
范围过滤:一个数据对。范围包含下限值,但不包括上限值。
哈希过滤:一个元组。第一个元素表示 bucket 的个数;第二个元素是一个标量或数据对,其中标量表示 bucket
的索引(从0开始),数据对表示 bucket 的索引范围(包含下限值,但不包括上限值)。
若传入自定义函数进行灵活过滤,可以通过如下两种方式传入:
函数:直接传入一个函数,则订阅的数据会以表的形式传入函数,并把函数返回的结果发送给订阅者。
字符串:传入表示函数名称的字符串,或者是一个 lambda 表达式的字符串。
persistOffset
是一个布尔值,表示是否持久化保存最新一条已经处理的订阅数据的偏移量。持久化保存的偏移量用于重订阅,可通过
getTopicProcessedOffset
函数获取。默认值为 false。
注:
若要订阅高可用流数据表,需要设置
persistOffset
为 true,以防止订阅端丢失数据。
设置
persistOffset
为
true,且取消订阅(
unsubscribeTable
)时,设置
removeOffset
=
false,再次订阅时才会从持久化保存的偏移量开始订阅。
timeTrigger
是一个布尔值。若设为 true,表示即使没有新的消息进入,
handler
也会在
throttle
参数所设定的时间间隔被触发。
handlerNeedMsgId
是一个布尔值,默认值为 false。
若设为 true,
handler
必须支持两个参数:一个是 msgBody(传入的消息),一个是
msgId(消息的偏移量)。如:以部分应用的形式固定
appendMsg
的
engine
参数后,将其作为二元应用传入
handler
。
若设为 false,
handler
仅支持一个参数:msgBody。调用
handler
时,只传入消息本身。
raftGroup
是 raft 组的 ID。设置该参数表示开启订阅端高可用,不设置则表示普通订阅。设置
raftGroup
参数以指定 raft 组后,在对应 raft 组内 leader 发生切换时,新的 leader 会重新订阅。
注:
subscribeTable
函数如果指定了
raftGroup
,则只能在 leader 上执行。若同时指定
handlerNeedMsgId
= true,则
handler
只能是计算引擎,即
handler
= engine(创建引擎时的句柄变量)或
handler
= getStreamEngine(engineName)。
userId
字符串,表示用户名。
password
字符串,表示用户密码。
udpMulticast
布尔值,默认为 false。用于设置是否开启 UDP (User Datagram
Protocol)Multicast 数据传输协议。设置为 true 后,发布端将通过 UDP 协议、以组播的方式将订阅数据发布到组播通道上。
使用 TCP 和 UDP 组播进行发布订阅的性能差异如下:
协议
优点
缺点
适用场景
TCP
数据传输可靠,能够确保按序到达订阅端
能够检测和纠正传输中的错误
一对一的连接方式决定了当订阅端为多个时,需要占用发布端大量的服务器资源及网络带宽
可靠性要求高
顺序性要求高
UDP Multicast
可以一次性将数据发布给多个订阅端,适合实时数据传输
发布端服务器资源和网络带宽占用少
数据包可能会缺失或乱序
有多个订阅端、要求快速实时传输数据
注:
启用该参数前,需要确保
reconnect
,
persisitOffset
,
timeTrigger
设置为
false,以及
raftGroup
设置为 -1。
目前仅 Linux 版本的 DolphinDB Server 支持该参数。
在使用该参数前,请确保发布端和接收端所在的网络的路由器或交换机是否支持 UDP Multicast 协议栈。
返回值
返回一个订阅主题(topic),即一个订阅的名称。它是一个字符串,由订阅表所在节点的别名、流数据表名称和订阅任务名称(如果指定了 actionName)组合而成,使用 "/" 分隔。如果订阅主题已经存在,函数将会抛出异常。
例子
例1
下面是关于流计算的例子。在本例中,集群有两个节点:DFS_NODE1 和 DFS_NODE2。我们需要在
cluster.cfg 中指定
maxPubConnections和subPort
参数来启动发布/订阅功能。例如:
maxPubConnections=32
DFS_NODE1.subPort=9010
DFS_NODE1.persistenceDir=C:/DolphinDB/Data
DFS_NODE2.subPort=9011
在 DFS_NODE1 上执行以下脚本:
创建一个共享的流数据表 trades_stream,并以同步模式保存。此时,表 trades_stream
有0行记录。
n=20000000
colNames = `time`sym`qty`price
colTypes = [TIME,SYMBOL,INT,DOUBLE]
enableTableShareAndPersistence(table=streamTable(n:0, colNames, colTypes), tableName="trades_stream", asynWrite=false, cacheSize=n)
go
创建一个分布式表 trades。此时,表 trades
有0行记录。
if(existsDatabase("dfs://STREAM_TEST")){
dropDatabase("dfs://STREAM_TEST")
}
dbDate = database(directory="", partitionType=VALUE, partitionScheme=temporalAdd(date(today()),0..30,'d'))
dbSym= database(directory="", partitionType=RANGE, partitionScheme=string('A'..'Z') join "ZZZZ")
db = database(directory="dfs://STREAM_TEST", partitionType=COMPO, partitionScheme=[dbDate, dbSym])
colNames = `date`time`sym`qty`price
colTypes = [DATE,TIME,SYMBOL,INT,DOUBLE]
trades = db.createPartitionedTable(table=table(1:0, colNames, colTypes), tableName="trades", partitionColumns=`date`sym)
创建表 trades_stream 的本地订阅。使用 saveTradesToDFS 函数把表 trades_stream 的流数据和今天的日期保存至表
trades。
def saveTradesToDFS(mutable dfsTrades, msg): dfsTrades.append!(select today() as date,* from msg)
subscribeTable(tableName="trades_stream", actionName="trades", offset=0, handler=saveTradesToDFS{trades}, msgAsTable=true, batchSize=100000, throttle=60)
创建表 trades_stream 的另一个本地订阅。使用每分钟的流数据计算成交量加权平均价格(vwap),并以异步模式把结果保存至共享的流数据表
vwap_stream
中。
n=1000000
tmpTrades = table(n:0, colNames, colTypes)
lastMinute = [00:00:00.000]
colNames = `time`sym`vwap
colTypes = [MINUTE,SYMBOL,DOUBLE]
enableTableShareAndPersistence(table=streamTable(n:0, colNames, colTypes), tableName="vwap_stream")
go
def calcVwap(mutable vwap, mutable tmpTrades, mutable lastMinute, msg){
tmpTrades.append!(msg)
curMinute = time(msg.time.last().minute()*60000l)
t = select wavg(price, qty) as vwap from tmpTrades where time < curMinute, time >= lastMinute[0] group by time.minute(), sym
if(t.size() == 0) return
vwap.append!(t)
t = select * from tmpTrades where time >= curMinute
tmpTrades.clear!()
lastMinute[0] = curMinute
if(t.size() > 0) tmpTrades.append!(t)
}
subscribeTable(tableName="trades_stream", actionName="vwap", offset=0, handler=calcVwap{vwap_stream, tmpTrades, lastMinute}, msgAsTable=true, batchSize=100000, throttle=60)
在 DFS_NODE2 上执行以下脚本,创建表 trades_stream 的远程订阅,并以异步模式把流数据保存至表
trades_stream_slave 中。
n=20000000
colNames = `time`sym`qty`price
colTypes = [TIME,SYMBOL,INT,DOUBLE]
enableTableShareAndPersistence(table=streamTable(n:0, colNames, colTypes), tableName="trades_stream_slave", cacheSize=n)
go
subscribeTable(server="DFS_NODE1", tableName="trades_stream", actionName="slave", offset=0, handler=trades_stream_slave)
在 DFS_NODE1
上执行以下脚本,模拟3支股票在10分钟内的流数据。每支股票每分钟生成2,000,000条记录。每分钟的数据被插入到流数据表 trades_stream
的600个数据块中。每两个数据块有100毫秒的时间间隔。
n=10
ticks = 2000000
rows = ticks*3
startMinute = 09:30:00.000
blocks=600
for(x in 0:n){
time = startMinute + x*60000 + rand(60000, rows)
indices = isort(time)
time = time[indices]
sym = array(SYMBOL,0,rows).append!(take(`IBM,ticks)).append!(take(`MSFT,ticks)).append!(take(`GOOG,ticks))[indices]
price = array(DOUBLE,0,rows).append!(norm(153,1,ticks)).append!(norm(91,1,ticks)).append!(norm(1106,20,ticks))[indices]
indices = NULL
blockSize = rows / blocks
for(y in 0:blocks){
range =pair(y * blockSize, (y+1)* blockSize)
insert into trades_stream values(subarray(time,range), subarray(sym,range), 10+ rand(100, blockSize), subarray(price,range))
sleep(100)
}
blockSize = rows % blocks
if(blockSize > 0){
range =pair(rows - blockSize, rows)
insert into trades_stream values(subarray(time,range), subarray(sym,range), 10+ rand(100, blockSize), subarray(price,range))
}
}
在 DFS_NODE1 上执行以下脚本来检查结果:
trades=loadTable("dfs://STREAM_TEST", `trades)
select count(*) from trades
预期结果有 60,000,000 条记录。
select * from vwap_stream
表 vwap_stream 预期有 27 条记录。
在 DFS_NODE2 上执行以下脚本:
select count(*) from trades_stream_slave
我们看到的结果小于 60,000,000 行,因为部分表的记录已经保存到磁盘中。
FILE:references/doc_3011.md
# exists
**URL**: https://docs.dolphindb.cn/zh/progr/sql/exists.html
**来源**: DolphinDB 官方文档
---
exists
和 where 子句搭配使用,通过子查询过滤外查询。
语法
where [not] exists(subquery)
subquery:select / exec 语句,其过滤条件中可以包含外查询的字段。
详情
若子查询涉及到外查询的字段,即相关子查询:
先执行一遍外查询并缓存查询结果。
然后循环将外查询的每一行结果作为子查询的条件进行查询:
若子查询有返回结果,则 exists 子句返回 true,外查询的该行结果将作为最终结果输出;
否则 exists 子句返回 false,该行结果不输出。
若子查询和外查询无关,即不相关子查询,则 exists 将根据下述规则进行计算:
如果子查询结果集非空,输出所有外查询结果。
如果子查询结果集为空,则外查询结果为空。 not exists 的计算逻辑和 exists 相反。
注意
:暂不支持在分布式查询中使用。
例子
t1 = table(`a`b`c`a`e`f as sym, 3.1 2.9 3.0 2.8 3.2 2.9 as val)
t2 = table(`a`b`c as sym, 0 1 -1 as flag)
查询1:相关子查询
select * from t1 where exists(select * from t2 where t1.sym in t2.sym)
sym
val
a
3.1
b
2.9
c
3
a
2.8
select * from t1 where not exists(select * from t2 where t1.sym in t2.sym)
sym
val
e
3.2
f
2.9
查询2:不相关子查询
select * from t1 where exists(select * from t2 where flag >= 0)
sym
val
a
3.1
b
2.9
c
3
a
2.8
e
3.2
f
2.9
select * from t1 where not exists(select * from t2 where flag >= 0)
//返回值为空
查询3:子查询无返回结果
select * from t1 where exists(select * from t2 where sym=`e)
//返回值为空
select * from t1 where not exists(select * from t2 where sym=`e)
sym
val
a
3.1
b
2.9
c
3
a
2.8
e
3.2
f
2.9
FILE:references/doc_3020.md
# clearAllTSDBSymbolBaseCache
**URL**: https://docs.dolphindb.cn/zh/funcs/c/clearalltsdbsymbolbasecache.html
**来源**: DolphinDB 官方文档
---
clearAllTSDBSymbolBaseCache
语法
clearAllTSDBSymbolBaseCache()
详情
清除缓存中所有未被使用的 symbolBase。其中,未被使用的 symbolBase 是指其对应分区的数据不在 Cache Engine
中,也不在执行的任何事务中。
参数
无。
返回值
无。
例子
clearAllTSDBSymbolBaseCache();
FILE:references/doc_3033.md
# eachPost
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/eachPost.html
**来源**: DolphinDB 官方文档
---
eachPost
语法
eachPost(func, X, [post],
[assembleRule|consistent=false])
func:O(X, [post])
或
X <operator>:O
[post]
表示不指定
assembleRule
,使用默认值
func:OC(X, [post])
或
X <operator>:OC [post]
表示指定
assembleRule
,此例中指定为 C(Consistent)
详情
将给定函数/运算符应用到所有相邻的数据对上。
eachPost
高阶函数等同于:F(X[0], X[1]), F(X[1], X[2]), ..., F(X[n],
post).
参数
func
是一个二元函数。
X
可以是向量、矩阵或表。当
X
是向量时,
post
必须是标量;当
X
是矩阵时,
post
必须是标量或向量;当
X
是表时,
post
是标量或表;当
post
未指定时,结果的最后一个元素为 NULL。
post
是可选参数,用于为
X
的最后一个元素提供后序值,其数据形式要求取决于
X
的数据形式。
assembleRule
可选参数,表示如何将子任务的结果合并为函数最终结果。接受一个整数或字符串作为输入,可选值如下:
0 (或 "D"):默认值,表示 DolphinDB
规则,即根据所有子任务的结果来决定最终输出的数据类型和形式。当所有子结果具有相同的数据类型和形式时,多个标量合并为一个向量、多个向量合并为一个矩阵、多个矩阵合并为一个元组、多个字典合并为一张表;否则将所有子结果合并为一个元组输出。
1(或 "C"):表示 Consistent
规则,即认为所有子结果的数据类型和形式都与第一个子结果相同,根据第一个子结果来选择最终结果的数据类型和形式。如果后续子任务返回的结果与第一个子任务的结果类型不一致,系统会尝试对后续结果进行类型转换。如果转换失败则抛出异常。因此,此规则只可在已知子结果的数据类型及形式一致时指定。此规则可使系统免于逐一缓存并检查每个子任务的计算结果,从而提升性能。
2(或 "U"):表示 Tuple 规则,系统不再对各子结果的类型和形式一致性进行检查,而是直接将子结果组装成一个元组输出。
3(或 "K"):表示 kdb+ 规则。与 DolphinDB 规则类似,都会根据所有子结果来决定最终结果形式。主要区别在于,kdb+
规则下,只要有任一子任务返回向量,则最终结果必为一个元组;而在 DolphinDB
规则下,子任务结果若均为长度相同的向量,则最终结果为一个矩阵。其他情况下,kdb+ 规则的输出与 DolphinDB 规则相同。
注:
自 2.00.15
/3.00.3
版本起,新增了
assembleRule
参数。该参数不仅实现了原
consistent
参数的功能,还提供了更多的结果合并选项。
consistent
是一个布尔值,默认值为 false,相当于
assembleRule
="D";若为 true,则相当于
assembleRule
="C"。为保持兼容性,用户仍可使用
consistent
参数。如果同时指定
assemble
和
consistent
,将以
consistent
的值为准。
assembleRule
也可在高阶函数对应的函数模式符号后指定,通过字符 D/C/U/K 表示。以
eachPre (:P)
为例,形如
sub:PU(X)
。不指定则使用默认值 D。
返回值
取决于
assembleRule
的值。
例子
x=1..10;
eachPost(sub, x);
// output
[-1,-1,-1,-1,-1,-1,-1,-1,-1,]
// 等同于 [1-2, 2-3, ..., 9-10, NULL]
+:O x;
// output
[3,5,7,9,11,13,15,17,19,]
// 等同于 [1+2, 2+3, ..., 9+10, NULL]
x +:O 0;
// output
[3,5,7,9,11,13,15,17,19,10]
// 等同于 [1+2, 2+3, ..., 9+10, 10+0]
x=1..12$3:4;
x;
col1
col2
col3
col4
1
4
7
10
2
5
8
11
3
6
9
12
-:O x;
col1
col2
col3
col4
-3
-3
-3
-3
-3
-3
-3
-3
-3
eachPost(\, x, x[0]);
col1
col2
col3
col4
0.25
0.571429
0.7
10
0.4
0.625
0.727273
5.5
0.5
0.666667
0.75
4
def f1(a,b){
return (a[`x])+(a[`y])+(b[`x])+(b[`y])
}
t = table(1 2 3 as x,2 3 4 as y)
t1 = table(1 as x,2 as y)
eachPost(f1,t,t1)
// output
(8,12,[10])
FILE:references/doc_3035.md
# addNode
**URL**: https://docs.dolphindb.cn/zh/funcs/a/addNode.html
**来源**: DolphinDB 官方文档
---
addNode
语法
addNode(host, port, alias, [saveConfig=true],
[nodeType='datanode'], [computeGroup]), [zone]
详情
增加数据节点或计算节点。仅限 admin 用户调用。
新增加的节点为关闭状态,需要通过 Web 集群管理器或命令行启动它。
注:
在新服务器上增加节点前需要先部署代理节点。详情参考教程:
多服务器集群部署
。
参数
host
是字符串标量或向量,表示新增节点的 IP 地址。
port
是正整数标量或向量,表示新增节点的端口号。
alias
是字符串标量或向量,表示新增节点的别名。
saveConfig
是一个布尔值,表示是否在增加节点的同时,将节点信息保存到 cluster.nodes 配置文件。默认值为 true。
nodeType
是字符串标量或向量,表示新增节点类型。支持 'datanode' 和 'computenode' 两个选项。
computeGroup
可选参数,字符串标量,用于指定计算节点所属的计算组名称。若未设置此参数,则表示该计算节点未加入任何计算组,不会缓存数据。
zone
可选参数,字符串标量,指定节点所属的区域名称。若 cluster.nodes 文件中已经指定了 zone,则该参数为必填,且只能指定
cluster.nodes 文件中已有的 zone,不能指定未定义的 zone 或默认 zone。
注:
参数
host
,
port
,
alias
,
nodeType
的长度须保持一致。
例子
增加一个别名为 “node1” 的数据节点。
addNode("192.168.1.103",8900,"node1");
增加一个别名为 “orca4” 的计算节点到计算组 "orca"。
addNode("192.168.1.243", 23796, "orca4", true, 'computenode', "orca");
FILE:references/doc_304.md
# makeSortedKey
**URL**: https://docs.dolphindb.cn/zh/funcs/m/makeSortedKey.html
**来源**: DolphinDB 官方文档
---
makeSortedKey
语法
makeSortedKey(args...)
详情
对于输入的多个
args
,将它们的值组合为一个 BLOB 标量或向量。相较于
makeKey
,
makeSortedKey
内部会保存组合值的排序结果,但输出结果与
makeKey
相同。
参数
args
是多个标量或长度相同的向量。
返回值
BLOB 标量或向量。
例子
makeSortedKey([`b,`a,`c], [`4,`2,`1])
// output: ["b4","a2","c1"]
set(makeSortedKey(1 2, 4 5))
FILE:references/doc_3048.md
# trim
**URL**: https://docs.dolphindb.cn/zh/funcs/t/trim.html
**来源**: DolphinDB 官方文档
---
trim
语法
trim(X)
详情
去掉每个字符串首尾的空格。
参数
X
是一个字符串标量或向量。
返回值
STRING 类型标量或向量。
例子
x=[" t1", " t2 "];
trim(x);
// output
["t1","t2"]
相关函数:
strip
FILE:references/doc_3049.md
# 流批一体
**URL**: https://docs.dolphindb.cn/zh/stream/str_batch.html
**来源**: DolphinDB 官方文档
---
流批一体
流批一体是指将研发环境中基于历史数据建模分析得到的因子或表达式直接应用于生产环境的实时数据中,并保证流计算的结果和批量计算完全一致,二者使用同一套代码,称为“流批一体”。
处理架构
DolphinDB
将历史数据和实时数据分析计算整合,在研发环境中开发的核心因子表达式可以直接应用于生产环境的实时数据中。实时行情订阅、行情数据收录、交易实时计算、盘后研究建模,全都用同一套代码完成,保证在历史回放和生产交易当中数据完全一致。相比传统的
Python 与 C++ 两套代码的方案,开发上线周期可缩短 90% 以上。在生产环境中,DolphinDB
提供了实时流计算框架。在流计算框架下,用户在投研阶段封装好的基于批量数据开发的因子函数,可以无缝投入交易和投资方面的生产程序中。同时,流计算框架在算法路径上进行了精细的优化,兼顾了高效开发和计算性能的优势。用户无需维护两套代码,节约了开发成本,还规避了两套体系可能带来的批计算与流计算结果不一致的问题。
图
1
.
流批一体处理架构
流批一体在 DolphinDB 中有两种实现方法:
方法一
使用一套核心函数定义或表达式,代入不同的计算引擎实现历史数据或流数据的计算。
流数据引擎可以直接重用批处理(研发阶段)中基于历史数据编写的表达式或函数,避免在生产环境重写代码,降低了维护研发和生产两套代码的负担。DolphinDB
脚本语言表示的表达式实际上是对因子语义的描述,因子计算的具体实现则交由相应的计算引擎完成。DolphinDB
确保流式计算的结果与批量计算完全一致,因此代码只要在历史数据的批量计算中验证正确,即可保证流数据的实时计算正确,极大降低了实时计算的调试成本。实际应用中,投研批处理阶段定义的因子表达式无需修改,在生产阶段只需创建流式计算引擎指定该指标即可实现增量流计算。
例如,计算每天主买成交量占全部成交量的比例,可以自定义函数
buyTradeRatio
:
@state
def
buyTradeRatio(buyNo, sellNo, tradeQty){
return
cumsum(iif(buyNo>sellNo, tradeQty,
0
))\cumsum(tradeQty)
}
在批处理模式下,可以使用 SQL 查询,发挥库内并行计算的优势,使用
csort
语句对组内数据按照时间顺序排序:
factor = select TradeTime, SecurityID, `buyTradeRatio
as
factorname, buyTradeRatio(BuyNo, SellNo, TradeQty)
as
val
from
loadTable(
"dfs://tick_SH_L2_TSDB"
,
"tick_SH_L2_TSDB"
) where date(TradeTime)<
2020.01
.
31
and
time(TradeTime)>=
09
:
30
:
00.000
context by SecurityID, date(TradeTime) csort TradeTime
在流处理模式下,可以通过响应式状态引擎指定该因子实现增量计算。在批计算中定义的因子函数
buyTradeRatio
,只需增加
@state
标识声明其为状态函数即可在流式计算中复用。通过以下代码创建响应式状态引擎 demo,以 SecurityID
作为分组键,输入的消息格式同内存表
tickStream
。
tickStream = table(
1
:
0
, `SecurityID`TradeTime`TradePrice`TradeQty`TradeAmount`BuyNo`SellNo, [SYMBOL,DATETIME,DOUBLE,INT,DOUBLE,LONG,LONG])
result = table(
1
:
0
, `SecurityID`TradeTime`Factor, [SYMBOL,DATETIME,DOUBLE])
factors = <[TradeTime, buyTradeRatio(BuyNo, SellNo, TradeQty)]>
demoEngine = createReactiveStateEngine(name=
"demo"
, metrics=factors, dummyTable=tickStream, outputTable=result, keyColumn=
"SecurityID"
)
方法二
回放历史数据模拟实时数据流入,使用流数据计算引擎完成计算。
为确保研发和生产环境使用同一套代码,可以研发阶段需将历史数据严格按照事件发生的时间顺序进行回放,以此模拟交易环境。使用这种方法计算历史数据的因子值,效率会略逊与基于
SQL 的批量计算。
下例通过用户自定义函数
sum_diff
与内置函数
ema
(exponential moving
average) 计算高频因子 factor1:
def
sum_diff(x, y){
return
(x-y)/(x+y)
}
factor1 = <ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
10
) - ema(
1000
* sum_diff(ema(price,
20
), ema(price,
40
)),
20
)>
// 定义响应式状态引擎实现因子流式计算
share streamTable(
1
:
0
, `sym`date`time`price, [STRING,DATE,TIME,DOUBLE])
as
tickStream
result = table(
1
:
0
, `sym`factor1, [STRING,DOUBLE])
rse = createReactiveStateEngine(name=
"reactiveDemo"
, metrics =factor1, dummyTable=tickStream, outputTable=result, keyColumn=
"sym"
)
subscribeTable(tableName=`tickStream, actionName=
"factors"
, handler=tableInsert{rse})
回放历史数据模拟实时数据注入引擎触发计算:
// 从 trades 表中加载一天的数据,回放到流数据表 tickStream 中
inputDS = replayDS(<select sym, date, time, price
from
loadTable(
"dfs://TAQ"
,
"trades"
) where date=
2021.03
.
08
>, `date, `time,
08
:
00
:
00.000
+ (
1.
.10
) *
3600000
)
replay(inputDS, tickStream, `date, `time,
1000
, true,
2
)
FILE:references/doc_3051.md
# cholesky
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cholesky.html
**来源**: DolphinDB 官方文档
---
cholesky
语法
cholesky(obj, [lower=true])
详情
对矩阵进行 Cholesky 分解。
参数
obj
是一个对称正定矩阵。
lower
是一个布尔值,表示是否使用输入矩阵的下三角来计算分解。默认值为 true,表示使用下三角计算。如果
lower
为
false,表示使用上三角计算。
返回值
DOUBLE 类型矩阵。
例子
m=[1, 0, 1, 0, 2, 0, 1, 0, 3]$3:3
L=cholesky(m);
L;
#0
#1
#2
1
0 96.56
0
0
1.414214
0
1
0
1.414214
L**transpose(L);
#0
#1
#2
1
0
1
0
2
0
1
0
3
cholesky(m, false);
#0
#1
#2
1
0
1
0
1.414214
0
0
0
1.414214
FILE:references/doc_3072.md
# setMaxBlockSizeForReservedMemory
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setMaxBlockSizeForReservedMemory.html
**来源**: DolphinDB 官方文档
---
setMaxBlockSizeForReservedMemory
语法
setMaxBlockSizeForReservedMemory(blockSizeKB)
详情
在线修改系统预留内存可以分配的最大内存块大小。该命令只能由管理员在数据节点/计算节点上执行。
请注意,此命令修改的配置值只对当前节点有效,且在系统重启后将失效。若需要配置值永久生效,请更改配置文件中的
maxBlockSizeForReservedMemory
。
参数
blockSizeKB
一个数值型标量(单位为KB),必须大于0。
FILE:references/doc_308.md
# Jupyter Notebook 客户端
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/jupyter.html
**来源**: DolphinDB 官方文档
---
Jupyter Notebook 客户端
Jupyter Notebook
是基于网页的用于交互计算的应用程序,可被应用于全过程计算:开发、文档编写、运行代码和展示结果。用户可以直接通过浏览器编辑和交互式运行代码。DolphinDB database
提供了Jupyter Notebook 的插件。
DolphinDB Jupyter Notebook 扩展插件提供以下功能:
为用户提供 Jupyter Notebook 连接DolphinDB Server 的配置界面。
使 Jupyter Notebook 支持 DolphinDB 脚本语言的执行。
下载安装
在命令行中,首先使用pip安装 DolphinDB Jupyter Notebook 插件:
pip install dolphindb_notebook
安装完成后启用插件:
jupyter nbextension enable dolphindb/main
插件配置
Jupyter Notebook内核(kernels)是编程语言特定的进程,它们独立运行并与Jupyter应用程序及其用户界面进行交互。DolphinDB Jupyter
Notebook 扩展插件提供了运行DolphinDB脚本的内核。用户需要通过以下步骤配置Jupyter
Notebook的工作路径,以便在程序运行时DolphinDB内核能够顺利导入。
通过命令行
jupyter kernelspec list
查看Jupyter
Notebook Kernel的工作路径
Linux系统
>jupyter kernelspec list
Available kernels:
dolphindb /home/admin/.local/share/jupyter/kernels/dolphindb
python3 /home/admin/.local/share/jupyter/kernels/python3
将/home/admin/.local/share/jupyter/kernels复制下来,方便下一步配置时粘贴。
Windows系统
>jupyter kernelspec list
Available kernels:
dolphindb C:\Users\admin\appdata\local\programs\python3\python37\share\jupyter\kernels\dolphindb
python3 C:\Users\admin\appdata\local\programs\python3\python37\share\jupyter\kernels\python3
将
C:\Users\admin\appdata\local\programs\python3\python37\share\jupyter\kernels
复制下来,方便下一步配置时粘贴。
通过命令行
jupyter notebook
--generate-config
生成一个配置文件jupyter_notebook_config.py,打开这个配置文件,找到c.NotebookApp.notebook_dir选项,设为上一步复制下来的工作路径,并去掉注释#。
注:
Windows系统中,需要将路径中的一个反斜杠\都替换成两个反斜杠\\,因为一个反斜杠\会被系统误认为是转义字符。
连接服务器
在命令行输入
jupyter notebook
,启动Jupyter Notebook。
在Jupyter Notebook的页面右侧点击新建,选择DolphinDB,新建一个DolphinDB notebook。
点击notebook工具栏的 Connect to DolphinDB Server
按钮。选择相应的server,然后点击右下角Connect按钮,即与DolphinDB
server建立连接(如果不需要该server,可以点击Delete按钮删除)。
也可以通过New按钮,输入新的server信息,然后点击Save & Connect按钮即与DolphinDB
server建立连接,并保存该信息以便下次使用。
编辑和运行脚本
连接DolphinDB
Server后,在代码块区域编写DolphinDB脚本,点击运行即可运行相应代码块。每次运行DolphinDB脚本后,运行结果都会在相应的代码块下方展示。对于DolphinDB的绘图功能,以PNG展示结果。
注:
对于一些数据量较大的结果,可能会出现IOPub数据率超出限制的问题,可以启用Jupyter
Notebook配置文件中的c.NotebookApp.iopub_data_rate_limit一项,去掉注释符号后,按需调高数值。
对于超出60行的表格,只显示前五行与后五行。
FILE:references/doc_3087.md
# schur
**URL**: https://docs.dolphindb.cn/zh/funcs/s/schur.html
**来源**: DolphinDB 官方文档
---
schur
语法
schur(obj, [sort])
详情
计算矩阵的 Schur(舒尔)分解。
参数
obj
是一个方阵。
sort
是一个字符串,表示根据所选参数对高特征值进行排序。它的可选参数可以是
'lhp'(特征值为小于零的实数),'rhp'(特征值为大于零的实数),'iuc'(特征值的绝对值<=1.0),或
'ouc'(特征值的绝对值>1.0)。
注:
若没有指定该参数,表示不进行排序。
返回值
假设输入方阵为 A:
如果不指定
sort
参数,返回两个矩阵:T 矩阵(矩阵 A 的 schur 形式,正交矩阵)与酉矩阵
Z(对于实数矩阵而言,Z 的转置矩阵与其逆矩阵相等),使得 A = Z
T
Z-1 。
如果指定
sort
参数,返回结果还包含一个整数,表示满足排序条件的特征值的数量。
例子
m=matrix([[0,0,1],[2,1,0],[2,2,1]]);
T,Z=schur(m)
T;
#0
#1
#2
2.658967
1.424405
-1.929334
0
-0.329484
-0.490637
0
1.311789
-0.329484
Z
#0
#1
#2
0.727116
-0.601562
0.330796
0.528394
0.798019
0.289768
0.438294
0.035904
-0.898114
T,Z,s=schur(m, 'lhp');
T;
#0
#1
#2
-0.329484
1.570974
2.251318
-0.40969
-0.329484
-0.092398
0
0
2.658967
Z
#0
#1
#2
0.703818
-0.632169
0.324042
0.509043
0.766983
0.390655
-0.495495
-0.109999
0.861618
s
// output
2
T,Z,s=schur(m, 'rhp');
s;
// output
1
m=matrix([[0,0,9],[-2,1,0],[2,2,1]]);
T,Z,s=schur(m, 'iuc');
s;
// output
0
T,Z,s=schur(m, 'ouc');
s;
// output
1
FILE:references/doc_3093.md
# read!
**URL**: https://docs.dolphindb.cn/zh/funcs/r/read_.html
**来源**: DolphinDB 官方文档
---
read!
语法
read!(handle, holder, [offset=0], [length=1])
详情
从文件句柄中读取指定数目的数据点,并从指定位置开始,把读取结果保存至
holder
表示的变量中。读入的数据和
holder
具有相同的数据类型。
readBytes
函数总是返回一个新的 CHAR
向量。创建一个新的向量缓冲区时会花费一定时间。为了提高性能,可以创建一个缓冲区,并重复利用。
read!
函数就是使用这样的方式提高速度。
使用
read!
的另一个好处是,用户不需要知道确切的读取字节数。函数在文件到达结尾时返回,并给出读取的字节数。如果返回的字节数小于预期,表明文件已经到达结尾。
参数
handle
是文件句柄。
holder
是用于保存读取的数据的变量。
offset
表示数据保存至
holder
的起始位置。
length
是读取的数据点数量。
返回值
返回实际读入的数据点的个数。
例子
// 用 read! 和 write 函数定义一个复制函数
def fileCopy(source, target){
s = file(source)
t = file(target,"w")
buf = array(CHAR,1024)
do{
numByte = s.read!(buf,0,1024)
t.write(buf,0, numByte)
}while(numByte==1024)
}
fileCopy("test.txt","testcopy.txt");
FILE:references/doc_3101.md
# 实时流数据接入
**URL**: https://docs.dolphindb.cn/zh/stream/realtime_data_acces.html
**来源**: DolphinDB 官方文档
---
实时流数据接入
实时流数据接入是指将数据从数据源实时写入 DolphinDB 流数据表以进行实时计算,或将流数据存入分布式数据库中以便后续进行清洗和计算。本章将介绍如何通过 API
接入各类实时数据,或通过插件接入不同的行情数据。
FILE:references/doc_3111.md
# winsorize
**URL**: https://docs.dolphindb.cn/zh/funcs/w/winsorize.html
**来源**: DolphinDB 官方文档
---
winsorize
语法
winsorize(X, limit, [inclusive=true], [nanPolicy='upper'])
详情
将向量
X
中指定百分比的极值掩盖。将第 (limits [0]) 个最低值设置为第 (limits [0])
个百分位数,将第 (limits [1]) 个最高值设置为第 (1-limits [1]) 个百分位数。
winsorize!
是
winsorize
的原地改变版本。
参数
X
是一个向量。
limit
是一个标量或两个元素组成的向量,表示相对于未屏蔽数据的数目,数组的每一侧要掩盖的百分比,取值为0到1之间。若为标量,表示每侧均要掩盖的百分比。若
X
有 n 个元素(包括 NULL值 ),第 (n * limit[0]) 个最小的元素和第 (n * limit[1])
个最大的元素被屏蔽,未屏蔽的数据总数为 n *(1-sum(limit))。若
limit
中一个元素为0,表示此侧不掩盖。
inclusive
是一个标量或两个元素组成的向量,表示在每一侧被屏蔽的数据数量应被截断(true)还是四舍五入(false)。
nanPolicy
是一个字符串,表示如何处理 NULL 值。可取以下值,默认值为 'upper'。
'upper':将 NULL 值视为最大值进行掩盖。
'lower':将 NULL 值视为最小值进行掩盖。
'raise':抛出异常。
'omit':不掩盖 NULL 值。
返回值
一个与
X
长度相同的向量。
例子
x=1..10
// output
winsorize(x, 0.1);
[2,2,3,4,5,6,7,8,9,9]
winsorize(x, 0.12 0.17);
// output
[2,2,3,4,5,6,7,8,9,9]
winsorize(x, 0.12 0.17, inclusive=false);
// output
[2,2,3,4,5,6,7,8,8,8]
x=1..20;
x[19:]=NULL;
x;
// output
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,]
winsorize(x, 0.1);
// output
[3,3,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18,18]
winsorize(x, 0.1, nanPolicy='upper');
// output
[3,3,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18,18]
winsorize(x, 0.1, nanPolicy='lower');
// output
[2,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,17,17,2]
FILE:references/doc_3114.md
# full join/full outer join
**URL**: https://docs.dolphindb.cn/zh/progr/sql/fulljoin.html
**来源**: DolphinDB 官方文档
---
full join/full outer join
语法
fj(leftTable, rightTable, matchingCols, [rightMatchingCols])
参数
leftTable
和
rightTable
是连接的表。
matchingCols
是表示连接列的字符串标量或向量。
rightMatchingCols
是表示右表连接列的字符串标量或向量。当
leftTable
和
rightTable
至少有一个连接列不同时,必须指定
rightMatchingCols
。返回结果中的连接列与左表的连接列名称相同。
兼容 SQL 的语法
select column_name(s)
from leftTable full [outer] join rightTable
on leftTable.matchingCol=rightTable.rightMatchingCol
注意
:
兼容 SQL 语法的 full join 不支持以下几点:
如果有多个连接列,必须使用 and 连接。
不能和 update 关键字一起使用。
若
leftTable
不是分布式表,则其
rightTable
也不能是分布式表。
详情
完全连接除了返回等值连接的结果集之外,还会返回左表或右表中不匹配的行。
例子
t1= table(1 2 3 3 as id, 7.8 4.6 5.1 0.1 as value);
t1;
id
value
1
7.8
2
4.6
3
5.1
3
0.1
t2 = table(5 3 1 as id, 300 500 800 as qty);
t2;
id
qty
5
300
3
500
1
800
fj(t1, t2, `id);
id
value
t2_id
qty
1
7.8
1
800
2
4.6
3
5.1
3
500
3
0.1
3
500
5
300
select * from fj(t1, t2, `id) where id=3;
//等价于 select * from t1 full join t2 on t1.id=t2.id where id=3
id
value
t2_id
qty
3
5.1
3
500
3
0.1
3
500
FILE:references/doc_3117.md
# constantDesc
**URL**: https://docs.dolphindb.cn/zh/funcs/c/constantdesc.html
**来源**: DolphinDB 官方文档
---
constantDesc
语法
constantDesc(obj)
详情
返回一个字典,描述对象
obj
的相关属性。字典可能包含的 key 及说明如下:
key
说明
form
数据形式
vectorType
向量类型,仅当
obj
是向量时才有此 key
isIndexedMatrix
是否是索引矩阵,仅当 obj 是矩阵时才有此 key
isIndexedSeries
是否是索引序列,仅当 obj 是矩阵时才有此 key
nullFlag
是否存在 NULL 值,仅当
obj
是向量、数据对或矩阵时才有此 key
isView
是否是视图,仅当
obj
是向量、数据对或矩阵时才有此 key
tableType
表的类型,仅当 obj 是表时才有此 key
type
数据类型
codeType
元代码的类型,仅当 obj 是元代码时才有此 key
functionDefType
函数类型,仅当 obj 是函数是才有此 key
isTransformFunction
是否是转换函数
isAggregateFunction
是否是聚合函数
isOrderSensitiveFunction
是否是顺序敏感函数
isHigherOrderFunction
是否是高阶函数
scale
保留的小数位数,仅当 obj 是 DECIMAL 类型数据时才有此 key
isColumnarTuple
是否是列式元组,仅当 obj 是元组且不是视图时才有此 key
category
数据类型分类
isTemporary
是否是临时对象
isIndependent
是否独立对象
isReadonly
是否只读对象
isReadonlyArgument
是否是只读参数
isStatic
是否是静态对象
isTransient
是否是瞬态对象
copyOnWrite
是否写时拷贝
refCount
被引用的次数
address
地址的十六进制表示
rows
包含行数
columns
包含列数
memoryAllocated
已分配的内存
参数
obj
一个对象。
例子
t = table(1..3 as id, 4..6 as val)
constantDesc(t)
/*
form->TABLE
tableType->BASIC
type->DICTIONARY
category->MIXED
isTemporary->false
isIndependent->true
isReadonly->false
isReadonlyArgument->false
isStatic->false
isTransient->false
copyOnWrite->false
refCount->1
address->0000000028d2d1e0
rows->3
columns->2
memoryAllocated->208
*/
constantDesc(lj)
/*
form->SCALAR
type->FUNCTIONDEF
functionDefType->SYSTEM FUNCTION
category->SYSTEM
isTemporary->true
isIndependent->true
isReadonly->false
isReadonlyArgument->false
isStatic->false
isTransient->false
copyOnWrite->false
refCount->6
address->000000000cabce00
rows->1
columns->1
memoryAllocated->10
*/
FILE:references/doc_312.md
# getStreamEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getStreamEngine.html
**来源**: DolphinDB 官方文档
---
getStreamEngine
语法
getStreamEngine(name)
详情
返回流数据引擎的句柄,可以作为
subscribeTable
函数的
handler
参数。
参数
name
是一个字符串,表示流数据引擎的名称。它可以包含字母,数字和下划线,但必须以字母开头。
返回值
一个流数据引擎对象。
例子
share streamTable(1000:0, `time`sym`qty, [TIMESTAMP, SYMBOL, INT]) as trades
outputTable = table(10000:0, `time`sym`sumQty, [TIMESTAMP, SYMBOL, INT])
tradesAggregator = createTimeSeriesEngine("StreamAggregatorDemo",3, 3, <[sum(qty)]>, trades, outputTable, `time, false,`sym, 50)
subscribeTable(, "trades", "tradesAggregator", 0, append!{tradesAggregator}, true)
def writeData(n){
timev = 2018.10.08T01:01:01.001 + timestamp(1..n)
symv =take(`A`B, n)
qtyv = take(1, n)
insert into trades values(timev, symv, qtyv)
}
writeData(6);
h = getStreamEngine("StreamAggregatorDemo")
FILE:references/doc_3142.md
# today
**URL**: https://docs.dolphindb.cn/zh/funcs/t/today.html
**来源**: DolphinDB 官方文档
---
today
语法
today()
详情
返回当前系统的日期。
参数
无
返回值
DATE 类型标量。
FILE:references/doc_3153.md
# resetRecoveryWorkerNum
**URL**: https://docs.dolphindb.cn/zh/funcs/r/resetRecoveryWorkerNum.html
**来源**: DolphinDB 官方文档
---
resetRecoveryWorkerNum
语法
resetRecoveryWorkerNum(newWorkerNum)
详情
在线修改当前节点用于 chunk 恢复的工作线程数。该命令只能由管理员在数据节点执行。
请注意,此命令修改的配置值在系统重启后将失效。若需要配置值永久生效,请更改配置文件中的
recoveryWorkers
(默认值是 1)。
参数
newWorkerNum
正整数,指定用于 chunk 恢复的工作线程数。
例子
resetRecoveryWorkerNum(2)
相关函数:
getRecoveryWorkerNum
FILE:references/doc_3156.md
# getChunksMeta
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getChunksMeta.html
**来源**: DolphinDB 官方文档
---
getChunksMeta
语法
getChunksMeta([chunkPath], [top = 1024])
详情
返回本地节点上指定数据库 chunk 的元数据。若不指定
chunkPath
,返回本地节点上所有数据库 chunk 的元数据。
参数
chunkPath
是一个或多个 chunk 的 DFS 路径,支持使用通配符 %,* 以及?。
top
是一个正整数,表示结果中返回的 chunk 的最多个数。默认值为1024。若设置
top
= -1,则不限制返回的
chunk的数量。
返回值
返回一个表,包含以下列
site:节点别名
chunkId:chunk 的唯一标识
path:分区的物理路径
dfsPath:分区 DFS 路径
type:分区类型。0表示 file chunk;1表示 tablet chunk。
flag:删除标志。若 flag=0,表示此 chunk 数据可以正常被查询和访问。若 flag=1,表示此
chunk 数据已在逻辑上被标记为删除,不可被查询,但仍然占用磁盘空间。
size:表示 file chunk 占用磁盘空间,单位为字节。对于 tablet chunk,返回0,需要使用
getTabletsMeta
函数来查看其占用的磁盘空间。
version:版本号
state:chunk 的状态。
0:表示 chunk 的最终状态,即所涉及的事务最终正确完成,或者 rollback。
1:before commit,提交事务之前,即 chunk 上正在执行事务。比如正在写数据或者删除数据。
2: after commit,已经 commit 事务。
3: waiting for recovery,等待恢复的状态,比如发生版本不一致或者数据损坏时,数据节点向控制节点发起 recovery
请求后,等待控制节点发起 recovery 时,则会处于这种状态。
4: in recovery 状态,在 recovery 状态中,接收到控制节点的 recovery 请求,开始启动
recovery,则处于这个状态。recovery 完成后变为最终状态(0)。
versionList:版本链
resolved:表示 chunk 的事务是否处于决议(commit)状态。true 表示决议状态,false
表示决议后的最终状态。
例子
if(existsDatabase("dfs://testDB")){
dropDatabase("dfs://testDB")
}
db=database("dfs://testDB", VALUE, 1..10)
n=1000000
t=table(rand(1..10, n) as id, rand(100.0, n) as x)
n=2000000
t=table(rand(1..10, n) as id, rand(100.0, n) as x, rand(100, n) as y)
db.createPartitionedTable(t, `pt2, `id).append!(t)
getChunksMeta("/testDB%");
site
chunkId
path
dfsPath
type
flag
size
version
state
versionList
resolved
P2-node1
092d5e12-e595-6f9e-b049-83cba1716997
/ssd/ssd5/jzVol...
/testDB/pt2.tbl
0
0
49
1
0
2052:49;
false
P2-node1
d31e6b47-18f0-37a6-0146-45bf6e266c56
/ssd/ssd6/jzVol...
/testDB/7
1
0
0
2
0
cid : 2053,pt1...
false
P2-node1
cd99d9ef-d864-f3bc-4945-f97017d43bf1
/ssd/ssd5/jzVol...
/testDB/2
1
0
0
2
0
cid : 2053,pt1...
false
P2-node1
8da4bea8-31d0-31b5-784f-67aa6339633d
/ssd/ssd5/jzVol...
/testDB/pt1.tbl
0
0
41
1
0
2050:41;
false
P2-node1
dd5fc885-f6a6-bfae-8543-254f9fb92484
/ssd/ssd6/jzVol...
/testDB/10
1
0
0
2
0
cid : 2053,pt1...
false
P2-node1
4b8aaed1-2dd6-acb7-5148-4add878c3b33
/ssd/ssd6/jzVol...
/testDB/domain
0
0
88
1
0
2049:88;
false
P2-node1
28cb59ec-185a-0ebf-a849-267e769936af
/ssd/ssd6/jzVol...
/testDB/8
1
0
0
2
0
cid : 2053,pt1...
false
P2-node1
b2facbd2-e301-428f-f94f-8579023f78af
/ssd/ssd6/jzVol...
/testDB/3
1
0
0
2
0
cid : 2053,pt1...
false
P2-node1
8bec6445-bc6d-3693-7f46-d1bcdd350182
/ssd/ssd6/jzVol...
/testDB/5
1
0
0
2
0
cid : 2053,pt1...
false
FILE:references/doc_3161.md
# loadNpy
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadNpy.html
**来源**: DolphinDB 官方文档
---
loadNpy
语法
loadNpy(fileName)
详情
读取 Python Numpy 的 npy 格式二进制文件,并转化为 DolphinDB 的向量或矩阵。Numpy 对象中的 NaN
值会被转化为 DolphinDB 的 NULL 值。
参数
filename
是字符串,表示 npy 文件的路径。
返回值
一个向量或矩阵。
例子
在 Python 中导出 npy 格式文件:
import numpy as np
np.save("intVec.npy", np.array([5,6,1,3,4,8]))
np.save("doubleMat.npy", np.array([[1.5,5.6,-7.87],[-1.0,3.4,4.5]]))
在 DolphinDB 中加载 npy 文件:
loadNpy("intVec.npy");
输出返回:[5,6,1,3,4,8]
loadNpy("doubleMat.npy");
输出返回:
#0
#1
#2
1.5
5.6
-7.87
-1
3.4
4.5
相关函数:
saveAsNpy
FILE:references/doc_3180.md
# getInstrumentNearStrike
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentnearstrike.html
**来源**: DolphinDB 官方文档
---
getInstrumentNearStrike
语法
getInstrumentNearStrike(instrument)
详情
根据输入的金融工具,获取该工具的近端行权价格。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DOUBLE 类型标量或向量。
例子
swap = {
"productType": "Swap",
"swapType": "FxSwap",
"version": 0,
"currencyPair": "EURUSD",
"direction": "Buy",
"notional": ["EUR", 1E6],
"nearStrike": 1.1,
"nearExpiry": 2025.12.08,
"nearDelivery": 2025.12.10,
"farStrike": 1.2,
"farExpiry": 2026.06.08,
"farDelivery": 2026.06.10
}
instrument = parseInstrument(swap)
getInstrumentNearStrike(instrument)
// output: 1.1
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_3185.md
# renameCatalog
**URL**: https://docs.dolphindb.cn/zh/funcs/r/renameCatalog.html
**来源**: DolphinDB 官方文档
---
renameCatalog
语法
renameCatalog(oldCatalog, newCatalog)
详情
重命名 catalog。
参数
oldCatalog
字符串标量,表示要修改的 catalog 的原名称。
newCatalog
字符串标量,表示要修改的 catalog 的新名称。
例子
renameCatalog("catalog1", "catalog2")
FILE:references/doc_3187.md
# 分布式事务
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db/transaction.html
**来源**: DolphinDB 官方文档
---
分布式事务
事务是指对数据库中的数据对象进行的一系列增、删、改等操作。一次事务的所有操作全部纳入一个不可分割的执行单元,该执行单元里的所有操作要么都成功,要么都失败,只要其中任一操作执行失败,整个事务都将回滚。在分布式系统中,各个节点之间在物理上相互独立,通过网络进行沟通和协调。分布式事务是指分布式系统中的事务,一个分布式事务可能涉及到不同节点和分区的操作。同样,分布式事务要去对参与事务的所有节点的操作,要么全部成功,要么全部回滚,不能出现部分提交的情况。时序数据的某些场景,如物联网中的数据采集,丢失一部分数据并不会带来严重的后果。但作为一个分布式数据库,保证各节点上的数据一致性非常关键。DolphinDB
通过两阶段提交(Two-Phase Commit, 2PC)和多版本并发控制机制(MVCC, Multi-Version Concurrency
Control)实现分布式事务,能够确保每个事务的原子性(Atomicity)、数据的一致性(Consistency)、读写操作之间的隔离性(Isolation)以及已写入数据的持久性(Durability)。
原子性
事务是一个原子操作单元,数据写入要么全都执行,要么全都不执行。比如,写入的数据涉及到多个分区,要么全部分区写入成功,要么全部分区写入失败。如果数据有多个副本,要么所有副本写入成功,要么所有副本写入失败。
一致性
DolphinDB 的一个事务可以包含对不同分区的写入操作,事务成功或回滚,每个分区的各个副本的状态总是一致的。在集群模式中,DolphinDB
还能确保某一时刻任何节点上查询得到的数据都是一致的。
隔离性
DolphinDB 通过多版本并发控制机制(MVCC, Multi-Version Concurrency
Control)实现事务隔离。每进行一次写入或删除操作,数据库的版本号都会增加。如果事务成功(commit),原先的版本会被覆盖,反之则回滚(roll
back)。当用户同时对数据库进行读写操作时,读和写的并发事务会相互隔离。多个事务可以同时对一个分区的不同表进行写入操作。
持久性
事务完成后,它对数据的操作是永久性的。
分布式事务实现
在传统的单机应用中,所有的操作都在本地进行,事务管理相对简单。而在分布式系统中,实现事务时需要考虑数据分片、网络延迟、节点故障等因素,因此需要设计专门的事务管理机制,如分布式事务协议、事务日志和读写分离等,以确保分布式系统中事务的正确性和高可用性。
一个分布式事务涉及不同节点和分区的操作,所有参与节点要么全部成功执行,要么全部回滚,不能出现部分提交的情况。在 DolphinDB
中对分布式表进行的每一次写入、更新或删除操作被视为一个分布式事务。DolphinDB 通过两阶段提交(Two-Phase Commit,
2PC)、日志记录和多版本并发控制等机制(MVCC, Multi-Version Concurrency
Control),实现分布式事务管理,确保每个事务具备原子性(Atomicity)、数据的一致性(Consistency)、读写操作之间的隔离性(Isolation)以及已写入数据的持久性(Durability)。
基本事务流程
DolphinDB 采用两阶段事务提交机制,每次由事务的发起节点作为协调者(coordinator)推进整个事务的执行流程。
协调者提出请求(例如写入数据),创建一个事务,向控制节点申请事务 ID(tid),得到事务所涉及分区在数据节点上的分布情况。
协调者将数据分发到相应的数据节点,各个数据节点将数据写入磁盘。如果存在某个数据节点数据写入失败,则终止该事务。
协调者准备提交,向控制节点申请 commit id(cid)。
协调者向控制节点和所有参与事务的数据节点 commit 事务,开始两阶段提交的第一阶段。如果控制节点或任意数据节点 commit
失败,则终止并回滚事务。
协调者向控制节点和所有参与事务的数据节点 complete 事务,开始两阶段提交的第两阶段。不管控制节点或数据节点是否 complete
失败,该事务都结束。如果存在 complete 失败的情况,则通过事务决议和 recovery 机制恢复。
开启 Redo Log 与 Cache Engine 的事务流程
Redo Log 是确保事务持久性的关键机制,即使在系统崩溃时,也能保障数据一致性。缺乏 Redo
Log,事务的持久性将会受到影响,因为数据库无法记录事务所做的修改,从而无法在故障或崩溃发生时进行恢复。DolphinDB 利用 Redo Log 和
Cache Engine 来确保事务的持久性并提升写入性能。
DolphinDB 重做日志(Redo Log)与 预写式日志(Write-Ahead
Logging,WAL)的概念相似,其核心理念是:只有在描述事务更改的日志记录已经刷新到持久化存储介质之后,才对数据库的数据文件进行修改。这样做可以避免在每次提交事务时都需要将数据页刷新到磁盘上,同时可以保证数据库发生宕机时,可以通过日志来恢复数据,所有尚未应用的更改都可以通过日志记录回放并重做。
Cache Engine 是 DolphinDB 中的一种数据写入缓存机制。数据在写入 Redo Log 的同时写入 Cache Engine。在 Cache
Engine 中的数据累积到一个阈值或者达到一定时间后,再由 Cache Engine
一次性异步写入数据文件。在一个事务涉及多个分区且数据量较小的情况下,如果每次事务结束都立即写入磁盘,写入效率将会受到影响。而利用 Cache Engine
先将这些事务缓存起来,待累积到一定数量后,以批量的方式一次性写入磁盘,则可以提供较高的压缩比此外,批量顺序写入也有助于提高IO吞吐量,从而有效提升整体系统性能。
一旦数据写入磁盘,事务完成,系统首先回收该事务的 Cache Engine 缓存,再回收 Redo Log 中的事务。DolphinDB 提供三种
Cache Engine 中事务的回收机制:定期回收、待缓存数据量达到阈值、或通过函数手动清理。同时提供两种 Redo
Log的回收机制:定期回收和文件大小达到阈值时回收。
事务决议
由上文事务流程可知,DolphinDB
采用两阶段提交(2PC)机制,涉及数据/计算节点与控制节点的协同工作。当任一方出现故障,导致事务无法推进时,需要通过事务决议来确定最终状态。
在 DolphinDB 中,控制节点作为第一阶段提交过程中的最后提交节点,其状态决定了事务的最终状态。因此,无需通过 RPC
从所有参与者收集信息,这简化了决策过程并提高了效率。在两阶段提交过程中,事务参与者检查日志或进行垃圾回收,当发现事务状态是第一阶段完成(COMMITTED)时,主动向控制节点发起决议请求。详细决议流程如下:
处理决议请求:
控制节点接收到决议请求后,根据事务的 tid、cid 和 chunkId
信息查询决议结果。首先查看决议结果缓存,如果缓存中可以查到结果,则直接返回结果。否则进行以下 2 步:
事务状态查询:
如果控制节点发起请求,则其事务状态为 COMMITTED,此时直接返回事务状态。
如果数据节点发起请求,则需要依次进行下面两步从控制节点查询事务状态,直至查到事务状态并返回。
从预写入日志(edit log)查询,若查询到结果则返回,否则进入第 3 步。
从分区的版本链查询,若查询到结果则返回,否则返回 ROLLBACK。
处理决议结果:
根据第 2 步查询到的状态,处理决议结果。可能的事务状态包括 UNCOMMITTED, COMMITTED, COMPLETE 和
ROLLBACK。
UMCOMMITTED:表示控制节点上的事务还未提交完成,暂时不能给出最后的状态,需要推迟决议时间,即将当前决议请求放入队列,等待后续再次决议。
COMMITTED:表示控制节点上的事务已提交完成,在控制节点上完成事务,更新事务状态为
COMPLETE,并将该状态广播给所有参与者。
COMPLETE 或 ROLLBACK:直接广播相应结果给所有事务参与者。
DolphinDB
的事务决议结果仅依赖于控制节点上的信息,无需从各个参与者收集信息。这一设计有效避免了因数据节点未恢复而导致的信息收集延迟,从而防止事务决议过程长时间停滞(尤其是在控制节点发起决议时,分区在此期间无法进行写入)。此外,这种方式也减少了因信息收集不足而导致的事务结果错误的风险。
事务并发控制
当多个事务不是先后顺序关系时,它们被称为并发事务。在并发情况下,多个事务同时读写同一个分区可能会导致冲突。本节将介绍 DolphinDB
的写写并发控制和读写并发控制机制。
写写并发控制
当多个客户端并发写入同一个分区时,会产生写写冲突。DolphinDB 确保同一时间内,一个分区只能被一个事务写入。在发生写写冲突时,DolphinDB 根据数据库
atomic
参数设置(“TRANS” 或
“CHUNK”)决定冲突的处理方式。这两种设置的主要区别在于,是否尝试自动解决检测到的冲突。
当
atomic
设置为 “TRANS” 时,写入流程如下:
客户端发起写入请求。
数据节点收到写入请求后,计算涉及的分区。
数据节点向控制节点申请事务的 tid。
使用步骤3中的 tid,向控制节点申请涉及分区的分布式锁。如果所有锁申请成功,进入步骤 5;否则,进入步骤 6。
开始向涉及的分区写入数据,事务完成后释放分布式锁,并向客户端返回写入成功。
放弃写入,向客户端返回异常,并返回写入失败的原因。
由以上流程可知,在 TRANS 模式下,当检测到写入冲突时,系统会放弃写入并返回写入失败的原因。因此,用户需要确保不能对同一个分区进行并发写入。
当
atomic
设置为 “CHUNK” 时,系统会尝试自动解决冲突,写入流程如下:
客户端发起写入请求。
数据节点收到写入请求后,计算涉及的分区。
数据节点向控制节点申请事务的 tid。
使用步骤 3 中的 tid, 向控制节点申请涉及分区的分布式锁。如果至少有一个分区的锁申请成功,则进入步骤 5;否则,进入步骤 6。
向成功申请锁的分区写入数据,完成事务后释放已写入分区的锁。当所有分区的事务都完成,转入步骤 7 ,否则转步骤 3。
等待一段时间后,回到步骤 3,尝试重新写入。直到多次(最多 250 次)尝试写入都失败,则返回写入失败。
写客户端返回写入成功。
尽管在 CHUNK
模式下,系统能够自动解决写写冲突,但其缺点在于一次写入会被分为多个事务,不能保证事务的原子性。如果发生回滚,可能导致某次写入操作只写入了一部分数据。
读写并发控制
DolphinDB 采用两阶段事务机制,结合多版本并发控制机制(MVCC, Multi-Version Concurrency
Control),实现读写快照级别隔离。MVCC
通过保存数据多个事务的数据快照来进行控制,允许同一个数据记录拥有多个不同的版本,记录了一个版本链。每进行一次写入、更新或删除操作,数据的版本号都会增加,从而确保在用户同时对数据库进行读写操作时,读和写的并发事务能够相互隔离。为了有效管理版本,系统会定期回收版本链。
DolphinDB 的分布式事务提供基于 sid(snapshot id)的快照隔离。结合前文介绍的两阶段提交流程,接下来详细说明 DolphinDB
的读写隔离机制:
协调者创建事务,向控制节点申请事务 tid。
当事务第一次 commit 时,控制节点会生成一个全局递增的 cid,并将其记录在参与事务的所有数据节点上。此时,数据节点会生成一个新的
CHUNK 副本(以”物理表名_cid”命名),并在该副本上进行数据的操作;为了防止 CHUNK 目录无限增长,数据节点最多保留5个旧版本的
CHUNK 目录,并根据设置的保留时长进行定期回收。
在完成两阶段提交时,控制节点生成一个全局递增的 sid(snapshot id),并将其记录在版本链上。sid
的主要作用是协助控制节点获取已完成事务中的最大 cid 并将该 cid 返回给协调节点。如果我们不引入 sid,在查询时直接使用
cid,存在一个潜在问题,即可能某个事务已经完成,但仍然有另一个小于该事务 cid
的事务尚未完成。这种情况可能导致在查询时无法查到最新的已完成事务的数据。通过引入全局唯一的 sid,确保了所有已完成的事务都能被查询到。
当协调者向控制节点请求查询最新的元数据信息时,控制节点通过当前版本链上的最大 sid,查询到满足小于等于这个 sid 的最新的
cid,并返回给数据节点。对应这个 cid 的 CHUNK 版本即为当前可读的最新版本的 CHUNK 数据。
协调者根据获取的 cid 到相应的数据节点上读取此 cid 对应版本的数据。
多副本写入事务控制
DolphinDB 支持多副本机制,允许在不同节点上存储分区的多个副本数据。本节将重点介绍多副本写入时的事务控制流程。
当事务开始时,协调者将事务所涉及的分区信息告知控制节点。
控制节点收集写入事务所涉及分区的元数据和存活副本的信息。如果为新增分区,控制节点会创建该分区,并从数据节点中挑选一个或多个节点(由配置项
dfsReplicationFactor
决定)来存储副本数据。
控制节点将分区元数据和存活副本的信息告知协调者。协调者根据副本信息,通过 RPC 向各个副本发起事务操作。
当所有副本的事务 complete
时,控制节点会更新每个参与事务的副本的版本号。如果在事务过程中某个副本节点出现因宕机等无法继续推进事务,该事务将终止并回滚。
副本一致性
数据节点定期向控制节点发送心跳信息。如果某个数据节点因意外宕机等原因变为离线状态,则控制节点将其标为未存活节点。当该节点重启后,它会向控制节点报告其所有分区的信息(包括版本号等)。控制节点将比较其存储的版本号与该节点报告的副本版本号。如果发现副本版本号落后,控制节点会推动自动进行在线恢复,以确保副本之间的数据一致性。关于在线恢复的机制和流程,参考
在线恢复
。
事务高可用
事务高可用指在分布式系统或数据库中,确保事务处理在各种故障情况下仍然能够持续进行和完成的能力。DolphinDB 的分布式事务也具备高可用的能力。DolphinDB
通过实现事务高可用性来确保在节点故障的情况下也能持续推进事务。下面将根据参与事务的节点分类,分别介绍 DolphinDB 事务高可用实现。
控制节点故障下的事务高可用
控制节点高可用采用 Raft 算法,能够容忍少于一半的控制节点不可用。当控制节点中出现故障的数量少于一半时,高可用机制可以通过 Raft
算法将事务状态同步到大多数控制节点。这样即使发生 Leader 切换,新的 Leader 也能获取当前进行中的事务信息。两阶段提交的协调者可以继续与新的
Leader 进行通信,以推进事务的执行;如果需要做出事务决议,新的 Leader 也能直接给出决议结果。
数据节点故障下的事务高可用
在数据节点故障的情况下,其余数据节点依然可以通过两阶段提交协议确定事务的最终结果,故障节点不会影响事务的决策。故障节点恢复后,只需向当前 Leader
请求事务决议即可了解事务的最终状态,如果存在数据副本落后,可以通过恢复机制进行同步。
支持事务的 SQL 操作
对分布式表的写入、更新和删除操作均支持分布式事务。本节将列出相关的语句和函数。
DDL:
create
(database/table),
alter
,
drop
。
DML:
insert into
,
update
,
delete
。
表连接语句:
表连接
分布式数据库/表相关操作函数:
addColumn
,
addRangePartitions
,
addValuePartitions
,
createdimensiontable
,
createPartitionedTable
,
database
,
dropColumns!
,
dropDatabase
,
dropPartition
,
dropTable
,
rename!
,
renameTable
,
reorderColumns!
,
replaceColumn!
,
tableInsert
,
tableUpsert
,
truncate
,
upsert!
备份恢复函数:
backup
,
backupDB
,
backupTable
,
restore
,
restoreDB
,
restoreTable
FILE:references/doc_3189.md
# dict
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dict.html
**来源**: DolphinDB 官方文档
---
dict
语法
dict(keyObj, valueObj, [ordered=false])
或
dict(keyType, valueType, [ordered=false])
详情
返回一个无序字典或有序字典对象。
参数
对于第一种情形,
keyObj
是表示键的向量,
valueObj
是表示值的向量。
对于第二种情形,
keyType
是字典键的数据类型,
valueType
是字典值的数据类型。系统支持以下键的数据类型:Literal、Integral(COMPRESS 除外)、Floating 和 Temporal。字典中的值不支持
COMPLEX,POINT 类别。
ordered
一个布尔值,默认为 false,表示创建一个无序字典。当
ordered
= true
时,创建一个有序字典。无序字典在输出或进行遍历时,其键值对不保留输入时的顺序;有序字典在输出或进行遍历时,键值对的顺序与输入顺序保持一致。
例子
x=
1
6
3
y=
4.5
7.8
4.3
z=dict(x,y);
z;
// output
3
->
4.3
1
->
4.5
6
->
7.8
z=dict(INT,DOUBLE);
z[
5
]=
7.9
;
z;
// output
5
->
7.9
z[
3
]=
6
;
z;
// output
3
->
6
5
->
7.9
dt=dict([`test], [
1
]);
dt;
// output
test->
1
// 创建有序字典
z=dict(x,y,true)
z;
// output
1
->
4.5
6
->
7.8
3
->
4.3
// y 为 DECIMAL32 类型的向量,将 y 作为 value 值创建有序字典 z
x=
1
3
2
y = decimal32(
1.23
3
3.14
,
3
)
z=dict(x,y,true);
z;
// output
1
->
1.230
3
->
3.000
2
->
3.140
获取键和值:
x=
1
6
3
y=
4.5
7.8
4.3
z=dict(x,y);
z.keys();
// output
[
3
,
1
,
6
]
z.values();
// output
[
4.3
,
4.5
,
7.8
]
相关函数:
array
,
matrix
,
dictUpdate!
,
syncDict
FILE:references/doc_3218.md
# cell
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cell.html
**来源**: DolphinDB 官方文档
---
cell
语法
cell(obj, row, col)
详情
返回一个位于对应行列的标量,等价于
obj[row, col]
。
cell
函数通常比
obj[row,
col]
运行地更快。
参数
obj
矩阵或表。
row
非负整数,表示行坐标。
col
非负整数,表示列坐标。
返回值
一个标量,与
obj
中对应位置元素的数据类型保持一致。
例子
x=(1..6).reshape(3:2);
x;
0
1
1
4
2
5
3
6
x.cell(0,0);
// output
1
x.cell(0,1);
// output
4
cell(x,1,1);
// output
5
cell(x,2,0);
// output
3
FILE:references/doc_3229.md
# deleteScheduledJob
**URL**: https://docs.dolphindb.cn/zh/funcs/d/deleteScheduledJob.html
**来源**: DolphinDB 官方文档
---
deleteScheduledJob
语法
deleteScheduledJob(jobId)
详情
删除一个定时任务。如果指定的任务 ID 不存在,则抛出异常。
参数
jobId
是一个表示定时任务 ID 的字符串。
返回值
无。
例子
deleteScheduledJob(`dailyJob1);
FILE:references/doc_3236.md
# backupTable
**URL**: https://docs.dolphindb.cn/zh/funcs/b/backupTable.html
**来源**: DolphinDB 官方文档
---
backupTable
语法
backupTable(backupDir, dbPath, tableName, [keyPath])
详情
备份数据库中的表到指定路径。
该函数是
backup
函数的特例,其等价于调用
backup(backupDir,
dbPath, force=false, parallel=true, snapshot=true, tableName)
。
调用该函数可以简化代码,方便用户一次性备份数据库的一张表。
参数
backupDir
字符串,表示存放备份数据的目录。
dbPath
字符串,表示数据库路径。
tableName
字符串,表示表名。
keyPath
字符串标量,指定备份时使用的密钥文件路径。仅 Linux 系统支持该参数。该密钥用于对备份数据进行加密。设置为空即不加密。
返回值
INT 类型标量,表示备份成功的表数量。
例子
dbName = "dfs://compoDB2"
n=1000
ID=rand("a"+string(1..10), n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10, n)
t=table(ID, date, x)
db1 = database(, VALUE, 2017.08.07..2017.08.11)
db2 = database(, HASH,[INT, 20])
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db = database(dbName, COMPO,[ db1,db2])
// 创建2个表
pt1 = db.createPartitionedTable(t, `pt1, `date`x).append!(t)
pt2 = db.createPartitionedTable(t, `pt2, `date`x).append!(t)
backupTable(backupDir,dbName,`pt1)
// output
50
相关函数:
backup
,
backupDB
,
restore
,
restoreDB
,
restoreTable
,
migrate
FILE:references/doc_3240.md
# cumsum3
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumsum3.html
**来源**: DolphinDB 官方文档
---
cumsum3
语法
cumsum3(X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累计立方和。
返回值
DOUBLE 类型,其数据形式同
X
。
例子
x=[2,3,4];
cumsum3 x;
// output
[8,35,99]
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
cumsum3(m);
#0
#1
1
64
9
189
36
405
相关函数:
sum
FILE:references/doc_3242.md
# 流式 SQL
**URL**: https://docs.dolphindb.cn/zh/stream/streaming_sql.html
**来源**: DolphinDB 官方文档
---
流式 SQL
1. 概述
自 3.00.4 版本起,DolphinDB 提供了流式 SQL 功能,通过增量计算和订阅计算结果,实现对实时数据的持续查询和即时更新。用户可以将共享内存表声明为流式
SQL 表,在这些表上注册流式 SQL
查询。系统只会对新到达或发生变更的数据进行计算(而非全量重算),并且仅将增量结果推送给订阅端,从而显著降低计算开销与网络传输成本,实现低延迟、实时响应。
DolphinDB 流式 SQL 核心功能包括:
支持复杂 SQL 查询,涵盖 SELECT、WHERE、JOIN 和 ORDER BY 等常用操作。
通过增量更新避免全量扫描,降低计算开销和延迟。
通过订阅机制仅传输增量结果,减少网络开销。
2. 系统架构与实现原理
2.1 架构
DolphinDB 流式 SQL 的架构围绕三大机制展开:
作业管理
:将每条注册的流式 SQL 查询视为一个独立作业(job)。统一管理其元数据和执行状态。
持续流式处理
:SQL 引擎持续运行,实时捕获数据变更,推动增量数据进入查询处理流水线。
增量更新推送
:查询结果采用增量更新策略,系统会对比新旧结果的差异,仅当结果发生实质性变化时,将变更部分(delta)发送给订阅客户端。此机制显著减少网络传输和客户端负载,提高整体系统响应效率。
2.2 增量计算流程
用户提交流式 SQL 查询后,系统生成相应的执行计划,并初始化各算子的中间状态。当新的增量数据到达时,算子基于这些数据执行增量计算,生成相应的变更日志。
这些变更日志沿查询执行链路自下而上传递,逐步更新最终的查询结果。系统仅将实际发生变化的结果差异(delta)推送给客户端订阅者,有效减少网络传输和计算资源消耗,实现高效且实时的结果更新。
2.3 订阅发布机制
流式 SQL 查询注册时,系统会为该查询自动生成一个变更日志流表,用于记录该查询结果的增量变化。订阅端通过订阅该变更日志流表,获取实时的结果变更。
当客户端取消订阅时,系统自动停止向该订阅端推送增量变更,释放相关资源。若所有订阅端取消订阅,则变更日志流表会停止更新,作业资源得到回收。
3. 使用限制
流式 SQL 中的连接操作需要在内存中保存参与连接的表数据和中间结果,因此会占用较多内存资源。为了保证系统稳定性,目前存在以下限制:
为保证性能,目前仅支持最多连接三张表的查询,超过三表连接的复杂查询暂不支持。
当连接条件发生变化时,相关计算会重新执行。
除了连接操作,其他算子(如过滤和排序)可以并行处理,支持多个独立的查询流水线。
4. 接口函数说明
函数名
函数介绍
declareStreamingSQLTable
声明指定表为流式 SQL 输入表,只有被声明的表才能注册流式 SQL 查询。声明不会影响该表在普通 SQL 中的使用。
getStreamingSQLStatus
查询流式 SQL 查询状态,支持查询单条或所有查询。管理员可查看所有用户查询。
listStreamingSQLTables
列举当前用户声明的所有流式 SQL 表,管理员可查看所有用户声明。返回表包含表名、共享状态及声明用户列表。
registerStreamingSQL
注册流式 SQL 查询,返回查询 ID,并自动生成结果变更日志流表。支持 SELECT、WHERE、JOIN(仅支持等值连接,且仅支持
ej、lj、rj、fj 类型)、ORDER BY 等关键字。
revokeStreamingSQL
注销已注册的流式 SQL 查询。
revokeStreamingSQLTable
注销之前声明的流式 SQL 表。注销前须先取消该表上的所有流式 SQL 查询订阅。只能注销当前用户声明的表。注销仅移除流式 SQL
功能,不删除表或数据。
subscribeStreamingSQL
订阅指定流式 SQL 查询结果,订阅端执行查询并维护实时更新的共享结果表。
unsubscribeStreamingSQL
取消订阅指定流式 SQL 查询结果,订阅端停止更新结果表。
5. 使用示例
使用流式 SQL 前,需先启用该功能。在配置文件中,将
streamingSQLExecutors
设置为大于 0 的整数。根据实际情况调整
maxStreamingSQLQueriesPerTable
参数。单节点环境修改 dolphindb.cfg,集群环境修改
cluster.cfg。
以下代码实时计算两个表中同一 id 的 value 值之和,随着数据更新,查询结果自动增量刷新。
// define keyedTables
share keyedTable(`id, 1:0, `id`value, [INT, DOUBLE]) as leftTable;
share keyedTable(`id, 1:0, `id`value, [INT, DOUBLE]) as rightTable;
go;
// 将两个共享键值内存表声明为流式 SQL 输入表。
declareStreamingSQLTable(leftTable);
declareStreamingSQLTable(rightTable);
// 注册流式 SQL 查询
queryId = registerStreamingSQL("select id, leftTable.value + rightTable.value from leftTable left join rightTable on leftTable.id=rightTable.id");
// 查看已注册的流式 SQL 查询运行状态
getStreamingSQLStatus()
// 订阅上述注册的 SQL 查询
table = subscribeStreamingSQL(,queryId)
// 向左、右表中插入数据
t = table(1 2 3 4 5 as id, 0.1 0.2 0.3 0.4 0.5 as value);
leftTable.append!(t);
t = table(1 2 3 4 5 as id, 0.1 0.2 0.3 0.4 0.5 as value)
rightTable.append!(t)
// 查看订阅结果表的最新值
sleep(20)
select * from table
// 再次向左、右表中插入数据
t = table(2 3 6 as id, 2.0 3.0 6.0 as value);
leftTable.append!(t);
t = table(6 as id, 6.0 as value);
rightTable.append!(t);
// 查看订阅结果表的最新值
sleep(20)
select * from table
// 清理环境
unsubscribeStreamingSQL(queryId=queryId)
revokeStreamingSQL(queryId)
revokeStreamingSQLTable("leftTable")
revokeStreamingSQLTable("rightTable")
6. 未来规划
为了持续提升流式 SQL 的性能与功能,DolphinDB 将重点推进以下工作:
优化查询执行计划,提升整体计算效率。
增强执行引擎的调度能力,实现更高效的流数据处理。
改进各类算子的增量计算逻辑。
支持和加速流式子查询的执行。
实现算子资源共享,减少重复计算。
FILE:references/doc_3244.md
# signbit
**URL**: https://docs.dolphindb.cn/zh/funcs/s/signbit.html
**来源**: DolphinDB 官方文档
---
signbit
语法
signbit(X)
详情
获取输入数据的符号位。
参数
X
:一个整型或者浮点型的标量。
返回值
负号返回 true;正号返回 false。
例子
signbit('a')
false
signbit(-21)
true
signbit(-2.1)
true
b=complex(10,-5)//创建一个复数
b
10.0-5.0i
signbit(highDouble(b)) //判断虚部符号
true
signbit(lowDouble(b)) //判断实部符号
false
FILE:references/doc_3248.md
# dropPartition
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropPartition.html
**来源**: DolphinDB 官方文档
---
dropPartition
语法
dropPartition(dbHandle, partitionPaths, [tableName],
[forceDelete=false]
,
[deleteSchema=false]
)
详情
删除数据库中指定分区的数据。
如果指定了
tableName
:删除指定表中符合指定条件的分区数据。
如果没有指定
tableName
:删除指定数据库所有表中符合指定条件的分区数据。
参数
dbHandle
分布式数据库的句柄。
partitionPaths
有两种指定模式:
指定路径:以 "/" 开头的字符串或字符串向量,表示数据库目录下单个或多个分区的路径。请注意对组合分区,路径必须包括所有层次分区。
指定条件:以分区列的一个或多个值组成的标量或向量作为过滤条件,系统会找到并删除这些值所在的分区。对于组合分区,partitionPaths
是由每层分区的过滤条件组成的元组,如果某层分区不需要过滤,那么相应的过滤条件需置为空。
tableName
字符串,表示表名。若分区粒度为数据库级(
database
:
chunkGranularity
= 'DATABASE'),可以不指定
tableName
,否则必须指定该参数。
forceDelete
布尔值,默认值为 false,表示不开启强制删除。如果
forceDelete
=true,即使指定的分区正在恢复,系统也会将其强制删除。
deleteSchema
布尔值,默认值为
false,表示仅删除分区数据,分区方案(partitionSchema)中仍保留其对应的分区方案信息。
如果
deleteSchema
=true,在满足以下条件时,删除分区数据及其对应的分区方案信息(可通过
schema
.partitionSchema 函数查看):
数据库只包含一个表;
单级分区时采用 VALUE 分区,或多级分区的第一级为 VALUE 分区;
dropPartition
仅删除第一级分区的数据。
返回值
无。
例子
下面例子中的脚本需要在集群中的数据节点/计算节点执行。
n=1000000
ID=rand(150, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x)
dbDate = database(, VALUE, 2017.08.07..2017.08.11)
dbID = database(, RANGE, 0 50 100 150)
db = database("dfs://compoDB", COMPO, [dbDate, dbID])
pt = db.createPartitionedTable(t, `pt, `date`ID)
pt.append!(t);
上面的代码创建了组合分区的数据库,第一层分区为基于日期的值分区,第二层分区为基于值的范围分区。
例 1. 删除某个分区的数据
例如,删除表 pt "/20170807/0_50" 分区,有以下两种方法:
(1) 指定路径:
dropPartition(dbHandle=database("dfs://compoDB"), partitionPaths="/20170807/0_50", tableName=`pt);
注:
这里使用
database("dfs://compoDB")
获取数据库
dfs://compoDB 的句柄,参数
dbHandle
也可指定为创建数据库时返回的句柄
db
。
(2) 指定条件:
dropPartition(dbHandle=database("dfs://compoDB"), partitionPaths=[2017.08.07, 0], tableName=`pt);
注意:"/20170807/0_50" 分区中的 ID 的可取值范围是从 0 到 49,不包括 50。以上脚本中,可以使用 0 到 49 的任一数字来代表此分区。
例 2. 删除一级分区的数据
例如,删除表 pt 的一级分区 2017.08.08,有以下两种方法:
(1) 使用向量指定该一级分区之下所有分区的路径:
partitions=["/20170808/0_50","/20170808/50_100","/20170808/100_150"]
dropPartition(dbHandle=database("dfs://compoDB"), partitionPaths=partitions, tableName=`pt);
(2) 指定条件:
dropPartition(dbHandle=database("dfs://compoDB"), partitionPaths=2017.08.08, tableName=`pt);
删除分区数据后,我们使用
schema
函数查看数据库的分区方案:
schema(database("dfs://compoDB"));
/*
databaseDir->dfs://compoDB
partitionSchema->([2017.08.07,2017.08.08,2017.08.09,2017.08.10,2017.08.11],[0,50,100,150])
partitionSites->
engineType->OLAP
atomic->TRANS
chunkGranularity->TABLE
partitionType->[1,2]
partitionTypeName->["VALUE","RANGE"]
partitionColumnType->[6,4]
clusterReplicationEnabled->1
databaseOwner->admin
*/
可以发现,2017.08.08 仍然在分区方案中,这是因为
dropPartition
只删除了
2017.08.08 这个分区中的数据,并不会将 2017.08.08 从数据库的分区方案中移除。由于该例删除的是一级 VALUE 分区,通过指定
deleteSchema
= true,来同步删除分区方案中的对应分区信息。
dropPartition(dbHandle=database("dfs://compoDB"), partitionPaths=2017.08.08, tableName=`pt, deleteSchema = true);
使用
schema
函数查看数据库的分区方案:
schema(database("dfs://compoDB"));
// output
partitionSchema->([2017.08.11,2017.08.10,2017.08.09,2017.08.07],[0,50,100,150])
...
例 3. 删除二级分区的数据
例如,删除表 pt 的二级分区 [0,50),有以下两种方法:
(1) 使用向量指定含有该二级分区的所有分区的路径:
partitions=["/20170807/0_50","/20170808/0_50","/20170809/0_50","/20170810/0_50","/20170811/0_50"]
dropPartition(dbHandle=database("dfs://compoDB"), partitionPaths=partitions, tableName=`pt);
(2) 指定条件:
dropPartition(dbHandle=database("dfs://compoDB"), partitionPaths=[,[0]], tableName=`pt);
例 4. 删除多个二级分区的数据
例如,删除表 pt 的二级分区 [0,50) 和 [100,150):
dropPartition(dbHandle=database("dfs://compoDB"), partitionPaths=[,[0,100]], tableName=`pt);
例 5. 修改分布式数据库中的数据
在 DolphinDB 中,如果要修改分布式数据库中的数据,需要先把相关分区的数据加载到内存中进行修改,然后使用
dropPartition
将数据库中的相关分区删除,最后将内存中修改好的分区数据重新追加到数据库中。
例如,将分布式表 pt 中 date=2017.08.10, ID=88 的记录 x+10。
首先,将包含 date=2017.08.10, ID=88 的所有相关分区数据加载到内存中,这些数据位于 "20170810/50_100" 分区中:
tmp=select * from loadTable("dfs://compoDB","pt") where date=2017.08.10 and 50<=ID<100 ;
接着,将内存表 tmp 中 date=2017.08.10, ID=88 的记录 x+10。:
update tmp set x=x+10 where date=2017.08.10 and ID=88;
然后,删除表 pt 中 "20170810/50_100" 分区中的数据:
dropPartition(dbHandle=database("dfs://compoDB"), partitionPaths="/20170810/50_100", tableName=`pt);
最后,将内存中修改好的记录追加到表 pt 中:
pt.append!(tmp);
FILE:references/doc_3261.md
# tmpercentile
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmpercentile.html
**来源**: DolphinDB 官方文档
---
tmpercentile
语法
tmpercentile(T, X, percent, window, [interpolation='linear'])
部分通用参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
元素在其对应窗口内的百分位数。
参数
percent
是0到100之间的整数或小数。
interpolation
是一个字符串,表示当选中的分位点位于在
X
的第 i 和第 i+1
个元素之间时,采用的插值方法。它具有以下取值:
'linear':
其中
'lower':
'higher':
'nearest':
和
之中最接近分位点的数据
'midpoint':
如果没有指定
interpolation
,默认采用 'linear'。
返回值
DOUBLE 类型向量。
例子
T = 1 1 1 2 5 6
X = 1 4 NULL -1 NULL 4
m = table(T as t,X as x)
select *, tmpercentile(t, x, 50, 3) from m
t
x
tmpercentile_t
1
1
1
1
4
2.5
1
2.5
2
-1
1
5
6
4
4
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = NULL 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmpercentile(t, x, 50, 3d) from m
t
x
tmpercentile_t
2021.01.02
2021.01.02
4
4
2021.01.04
4
2021.01.05
-1
-1
2021.01.07
2
0.5
2021.01.08
4
3
select *, tmpercentile(t, x, 50, 1w) from m
t
x
tmpercentile_t
2021.01.02
2021.01.02
4
4
2021.01.04
4
2021.01.05
-1
1.5
2021.01.07
2
2
2021.01.08
4
3
相关函数:
percentile
,
mpercentile
FILE:references/doc_3262.md
# objByName
**URL**: https://docs.dolphindb.cn/zh/funcs/o/objByName.html
**来源**: DolphinDB 官方文档
---
objByName
语法
objByName(name, [sharedVar])
详情
DolphinDB 在执行脚本之前先解析脚本。解析脚本的过程是检查变量是否在本地定义。如果没有在本地定义,则抛出异常。
假设我们在本地定义一个函数,然后在远程节点上执行。这个函数会查询共享表。但是,共享表在远程节点上而不在本地节点上。如果在函数的
SQL 语句中直接调用表名,系统将不能解析脚本。
为了解决这个问题,系统函数
objByName
在执行时会根据名称返回对象。
如果没有指定
sharedVar
参数,系统首先搜索会话中的局部变量,再搜索共享变量。如果
sharedVar
为true,表示只搜索共享变量。如果
sharedVar
为false,表示只搜索局部变量。
参数
name
是一个字符串,表示表名。
sharedVar
是一个布尔值。
返回值
一个对象,与
name
具有相同的数据类型与形式。
例子
假设在本地节点上有一个表 EarningsDates,它包含两列:Ticker 和 date。主机名为localhost 服务器的
8081 端口上的远程节点有一个表 USPrices。它包含所有美国股票的每日价格。我们想要从远程节点取得 EarningsDates
表中所有股票在公布收益后一周的价格。
在远程节点,导入数据文件创建表 USPrices,然后在所有节点间共享。
USPrices = loadText("c:/DolphinDB/Data/USPrices.csv")
share USPrices as sharedUSPrices;
在本地节点,创建表 EarningsDates,然后把表和脚本发送到远程节点。执行完成后,结果会发送回本地节点。
EarningsDates=table(`XOM`AAPL`IBM as TICKER, 2006.10.26 2006.10.19 2006.10.17 as date)
def loadDailyPrice(data){
dateDict = dict(data.TICKER, data.date)
return select date, TICKER, PRC from objByName("sharedUSPrices") where dateDict[TICKER]<date<=dateDict[TICKER]+7
}
conn = xdb("localhost",8081)
prices = conn(loadDailyPrice, EarningsDates);
prices;
date
TICKER
PRC
2006.10.27
XOM
71.46
2006.10.30
XOM
70.84
2006.10.31
XOM
71.42
2006.11.01
XOM
71.06
2006.11.02
XOM
71.19
2006.10.18
IBM
89.82
2006.10.19
IBM
89.86
2006.10.20
IBM
90.48
2006.10.23
IBM
91.56
2006.10.24
IBM
91.49
2006.10.20
AAPL
79.95
2006.10.23
AAPL
81.46
2006.10.24
AAPL
81.05
2006.10.25
AAPL
81.68
2006.10.26
AAPL
82.19
FILE:references/doc_3267.md
# fy5253
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fy5253.html
**来源**: DolphinDB 官方文档
---
fy5253
语法
fy5253(X, [weekday=0], [startingMonth=1], [nearest=true],
[offset], [n=1])
详情
采用52-53周财年(4-4-5历),该函数返回X所在财政年度的起始日期。
如果
nearest
=true,表示将最接近
startingMonth
最后一天的
weekday
的日期作为财政年度的起始日期。
如果
nearest
=false,表示将
startingMonth
中最后一个
weekday
的日期作为财政年度的起始日期。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
年更新一次。注意,只有当
n
>1 时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
weekday
是0到6之间的整数,表示星期编号。0表示星期一,1表示星期二,... ,6表示星期日。默认值为0。
startingMonth
是1到12之间的整数,表示一年的起始月份。默认值是1。
nearest
是一个布尔值。默认值为 true。
offset
是与
X
类型相同的标量,并且它必须小于等于X中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
fy5253(2016.11.01,0,1,true);
// output
2016.02.01
// 最接近2016.01.31的周一是2016.02.01
fy5253(2016.11.01,0,1,false);
// output
2016.01.25
// 2016年1月中最后一个周一是2016.01.25
date=2011.10.25 2012.10.25 2013.10.25 2014.10.25 2015.10.25 2016.10.25 2017.10.25 2018.10.25 2019.10.25 2020.10.25
time = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12,09:38:13]
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
select avg(price),sum(qty) from t1 group by fy5253(date,0,1,true,2011.10.01,2);
fy5253_date
avg_price
sum_qty
2011.01.31
39.53
4100
2013.01.28
29.77
5300
2015.02.02
175.1
12200
2017.01.30
50.54
3800
2019.01.28
51.835
13300
相关函数:
fy5253Quarter
FILE:references/doc_3270.md
# mcorr
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mcorr.html
**来源**: DolphinDB 官方文档
---
mcorr
语法
mcorr(X, Y, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内,计算
X
和
Y
元素的相关性。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
Y
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
计算结果为 DOUBLE 类型,形式同输入参数。
例子
x=1..8
y=9 5 3 4 5 4 7 1
mcorr(x,y,5);
// output: [,,,,-0.624038,0,0.834058,-0.29173]
mcorr(x,y,5,3);
// output: [,,-0.981981,-0.834497,-0.624038,0,0.834058,-0.29173]
x1 = indexedSeries(date(2020.06.05)+1..8, x)
y1 = indexedSeries(date(2020.06.05)+1..6 join 2020.06.15 join 2020.06.16, y)
mcorr(x1,y1,5d)
label
col1
2020.06.06
2020.06.07
-1
2020.06.08
-0.982
2020.06.09
-0.8345
2020.06.10
-0.624
2020.06.11
0
2020.06.12
0.6325
2020.06.13
0
mcorr(x1,y1,1w)
label
col1
2020.06.06
2020.06.07
-1
2020.06.08
-0.982
2020.06.09
-0.8345
2020.06.10
-0.624
2020.06.11
-0.6116
2020.06.12
-0.6116
2020.06.13
0
相关函数:
corr
,
mmin
,
mmax
,
mavg
,
msum
,
mstd
,
mvar
FILE:references/doc_3271.md
# tmwsum
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmwsum.html
**来源**: DolphinDB 官方文档
---
tmwsum
语法
tmwsum(T, X, Y, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间长度衡量)的滑动窗口内,计算
X
和
Y
元素的内积。
返回值
DOUBLE 类型向量。
例子
T = 1 1 1 1 2 5 6 8 9 10
X = 1..10
Y = double(1..10)\10
m = table(T as t,X as x, Y as y)
select *, tmwsum(t, y, x, 3) from m
t
x
y
tmwsum_t
1
1
0.1
0.1
1
2
0.2
0.5
1
3
0.3
1.4
1
4
0.4
3
2
5
0.5
5.5
5
6
0.6
3.6
6
7
0.7
8.5
8
8
0.8
11.3
9
9
0.9
14.5
10
10
1
24.5
T = 2021.01.02 2021.01.06 join 2021.01.07..2021.01.14
X = 1..10
Y = double(1..10)\10
m=table(T as t,X as x, Y as y)
select *, tmwsum(t, y, x, 3) from m
t
x
y
tmwsum_t
2021.01.02
1
0.1
0.1
2021.01.06
2
0.2
0.4
2021.01.07
3
0.3
1.3
2021.01.08
4
0.4
2.9
2021.01.09
5
0.5
5
2021.01.10
6
0.6
7.7
2021.01.11
7
0.7
11
2021.01.12
8
0.8
14.9
2021.01.13
9
0.9
19.4
2021.01.14
10
1
24.5
select *, tmwsum(t, y, x, 1w) from m
t
x
y
tmwsum_t
2021.01.02
1
0.1
0.1
2021.01.06
2
0.2
0.5
2021.01.07
3
0.3
1.4
2021.01.08
4
0.4
3
2021.01.09
5
0.5
5.4
2021.01.10
6
0.6
9
2021.01.11
7
0.7
13.9
2021.01.12
8
0.8
20.3
2021.01.13
9
0.9
28
2021.01.14
10
1
37.1
相关函数:
wsum
,
mwsum
FILE:references/doc_3283.md
# temporalFormat
**URL**: https://docs.dolphindb.cn/zh/funcs/t/temporalFormat.html
**来源**: DolphinDB 官方文档
---
temporalFormat
语法
temporalFormat(X, format)
别名:
datetimeFormat
详情
把 DolphinDB 时序类型的数据转换成指定格式的字符串。详情请参考:
日期和时间的调整及格式
。
参数
X
是一个时间序列标量或向量。
format
是表示时间格式的字符串。
返回值
STRING 类型标量或向量。
例子
temporalFormat(2018.02.14,"dd-MM-yyyy");
// output: 14-02-2018
temporalFormat(2018.02.14,"dd-MMM-yy");
// output: 14-FEB-18
temporalFormat(02:19:06,"HH.mm.ss");
// output: 02.19.06
temporalFormat(2018.02.06T13:30:10.001, "y-M-d-H-m-s-SSS");
// output: 2018-2-6-13-30-10-001
temporalFormat(14:19:06,"hhmmssaa");
// output: 021906PM
FILE:references/doc_3289.md
# mmed
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mmed.html
**来源**: DolphinDB 官方文档
---
mmed
语法
mmed(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
元素的中位数。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
DOUBLE 类型,数据形式与
X
相同。
例子
X = 2 1 3 7 6 5 4
Y = 2 1 3 NULL 6 5 4
mmed(X, 3);
// output
[,,2,3,6,6,5]
mmed(Y, 3);
// output
[,,2,2,4.5,5.5,5]
mmed(Y, 3, minPeriods=1);
// output
[2,1.5,2,2,4.5,5.5,5]
m = matrix(1 5 9 0 2, 9 10 2 NULL 2)
m.rename!(date(2020.09.08)+1..5, `A`B)
m.setIndexedMatrix!()
m.mmed(3d)
label
col1
col2
2020.09.09
1
9
2020.09.10
3
9.5
2020.09.11
5
9
2020.09.12
5
6
2020.09.13
2
2
m.mmed(1w)
label
col1
col2
2020.09.09
1
9
2020.09.10
3
9.5
2020.09.11
5
9
2020.09.12
3
9
2020.09.13
2
5.5
相关函数:
med
FILE:references/doc_3292.md
# ge
**URL**: https://docs.dolphindb.cn/zh/funcs/g/ge.html
**来源**: DolphinDB 官方文档
---
ge
语法
ge(X, Y)
或
X>=Y
详情
如果
X
和
Y
都不是集合,返回逐个元素比较
X
>=
Y
的结果。
如果
X
和
Y
都是集合,则检查
Y
是否为
X
的子集。
参数
X
和
Y
可以是标量、数据对、向量、矩阵或集合。如果
X
或
Y
的其中一个是数据对、向量或矩阵,另一个必须是标量,或具有相同长度或维度的数据对、向量或矩阵。
返回值
当
X
和
Y
都不是集合时,返回布尔类型的结果,形式与输入参数的形式相同。
当
X
和
Y
都是集合时,返回布尔值标量,表示
Y
是否为
X
的子集。
例子
X
是向量:
1 2 3 >= 2;
// output
[0,1,1]
1 2 3 >= 0 2 4;
// output
[1,1,0]
2:3>=1:6;
// output
1 : 0
m1=1..6$2:3;
m1;
#0
#1
#2
1
3
5
2
4
6
m1 ge 4;
#0
#1
#2
0
0
1
0
1
1
m2=6..1$2:3;
m2;
#0
#1
#2
6
4
2
5
3
1
m1>=m2;
#0
#1
#2
0
0
1
0
1
1
集合操作:如果
X
>=
Y
,则
Y
是
X
的子集。
x=set(4 6);
x;
// output
set(6,4)
y=set(8 9 4 6);
y;
// output
set(6,4,9,8)
y>=x;
// output
1
x>=y;
// output
0
x>=x;
// output
1
// x 是 x 的子集
FILE:references/doc_3296.md
# rowRank
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowRank.html
**来源**: DolphinDB 官方文档
---
rowRank
语法
rowRank(X, [ascending=true], [groupNum], [ignoreNA=true],
[tiesMethod='min'], [percent=false], [precision])
详情
逐行计算
X
的元素排名或组排名,排名方式请参照
rank
。
参数
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
。
ascending
是一个布尔值,表示排序方向。true 表示升序,false 表示降序。默认值为 true。它是一个可选参数。
groupNum
是一个正整数,表示排序形成的组的数量。它是一个可选参数。
ignoreNA
是一个布尔值,表示是否忽略 NULL 值。true 表示忽略 NULL 值,false 表示 NULL 值参与排名。默认值为
true。它是一个可选参数。NULL 值参与排序时,NULL 值为最小值。
tiesMethod
是一个字符串,表示如何对具有相同值的元素进行排名。
'min'表示取最小排名。
'max'表示取最大排名。
'average'表示取排名的均值。
'first' 表示按照原数据的顺序排名。
percent
是一个布尔值,表示是否以百分比形式显示返回的排名。
precision
是一个 [1, 15] 范围内的整数,用于设置参与排序的值的精度。若两个值之差的绝对值小于等于 10^(-precision)
,则认为两值相等。
注:
指定
precision
参数后,
X
只能是数值型对象。且
tiesMethod
不能指定为 'first'。
返回值
返回一个和
X
维度相同的矩阵。
例子
m=matrix(3 1 2 4 7 6 9 8 5, 9 NULL 2 3 5 6 3 2 8).transpose();
m
返回:
#0
#1
#2
#3
#4
#5
#6
#7
#8
3
1
2
4
7
6
9
8
5
9
2
3
5
6
3
2
8
m.rowRank();
返回:
#0
#1
#2
#3
#4
#5
#6
#7
#8
2
0
1
3
6
5
8
7
4
7
0
2
4
5
2
0
6
m.rowRank(false);
返回:
#0
#1
#2
#3
#4
#5
#6
#7
#8
6
8
7
5
2
3
0
1
4
0
6
4
3
2
4
6
1
m.rowRank(groupNum=3);
返回:
#0
#1
#2
#3
#4
#5
#6
#7
#8
0
0
0
1
2
1
2
2
1
2
0
0
1
1
0
0
2
m.rowRank(ignoreNA=false);
返回:
#0
#1
#2
#3
#4
#5
#6
#7
#8
2
0
1
3
6
5
8
7
4
8
0
1
3
5
6
3
1
7
m.rowRank(ignoreNA=false, tiesMethod='max');
返回:
#0
#1
#2
#3
#4
#5
#6
#7
#8
2
0
1
3
6
5
8
7
4
8
0
2
4
5
6
4
2
7
m.rowRank(ignoreNA=false, tiesMethod='first');
返回:
col1
col2
col3
col4
col5
col6
col7
col8
col9
2
0
1
3
6
5
8
7
4
8
0
1
3
5
6
4
2
7
FILE:references/doc_3300.md
# cutPoints
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cutPoints.html
**来源**: DolphinDB 官方文档
---
cutPoints
语法
cutPoints(X, binNum, [freq])
详情
返回具有(
binNum
+1)个元素的向量,这样
X
中的数据均匀地分布
binNum
个桶中。每个桶由向量中相邻的两个元素决定,只包含下边界不包含上边界。
cutPoints
可以用于获取 RANGE 分区数据库的分区方案。
参数
X
是一个向量。
binNum
是产生桶的数量。
freq
是与
X
等长的向量。它是
X
中每个元素的频率。它是一个可选参数,如果指定了
freq
,
X
中的所有元素必须是唯一的,并且按升序存储。
返回值
返回一个向量,其数据类型同
X
。
例子
cutPoints(2 3 1 4, 2);
// output
[1,3,5]
cutPoints(1 2 3 4, 2, 1 1 1 3);
// output
[1,4,5]
FILE:references/doc_3301.md
# updateMCPPrompt
**URL**: https://docs.dolphindb.cn/zh/funcs/u/updateMCPPrompt.html
**来源**: DolphinDB 官方文档
---
updateMCPPrompt
语法
updateMCPPrompt(name, [message], [description], [extraInfo])
详情
更新一个 MCP prompt 模板。
如果某个参数没有提供,则不修改对应的信息。空字符串会被视为没有提供参数,因此如要清空描述信息,请使用空格代替空字符串。
参数
name
STRING 类型标量,表示 prompt 模板的名称。
message
STRING 类型标量,表示 prompt 模板内容,允许包含
{}
占位符。
description
可选参数,STRING 类型标量,表示 prompt 模板说明。
extraInfo
可选参数,一个字典,键是 STRING 类型,值是 ANY 或 STRING 类型,用于指定其他信息。目前键支持
"title"。
返回值
一个字符串,表示更新 MCP prompt 模板的名称。
例子
// 定义 prompt 模板
addMCPPrompt(
name = "stock_summary",
message = "请用一句话总结 stock 从 startDate 到 endDate 的走势。",
description = "生成某个股票在一段时间内的自然语言概述",
extraInfo = {title : "股票走势总结"}
)
// 更新 prompt 模板
updateMCPPrompt(
name = "stock_summary",
message = "请总结 stock 在 startDate 至 endDate 的表现。",
description = "更新后的 Prompt 描述"
)
FILE:references/doc_3314.md
# boxcox
**URL**: https://docs.dolphindb.cn/zh/funcs/b/boxcox.html
**来源**: DolphinDB 官方文档
---
boxcox
语法
boxcox(X, [lmbda])
详情
使用 Box-Cox 变换方法对
X
进行转换。
Box-Cox 变换由下式给出:
参数
X
数值型向量,表示要转换的输入向量。如果未指定
lmbda
参数,
X
不能包含空值或非正数,且
X
的所有元素不能相同。
lmbda
可选参数,数值类型标量或向量,表示 lambda 参数。若为向量,
X
与
lmbda
的长度必须相同。
返回值
如果指定了
lmbda
参数,返回值为与
X
等长的 DOUBLE 类型向量。
如果
lmbda
是标量,则返回值是使用
lmbda
对
X
进行 Box-Cox
转换的结果。
如果
lmbda
是向量,则返回值的每个元素分别为 boxcox(X
i
,
lmbda
i
)。
如果未指定
lmbda
参数,返回值为元组,包含两个元素:
第一个元素为 DOUBLE 类型的向量,表示对
X
进行 Box-Cox 转换的结果。
第二个元素为 DOUBLE 类型的标量,表示最优的 lambda 参数。
例子
data = [1.5, 2.3, 3.1, 4.8, 5.5, 6.7, 8.2, 9.0, 10.1, 12.4]
lmb = 2
boxcox(data)
// output: ([0.4541,1.0562,1.5689,2.4892,2.82394,3.3559,3.9636,4.267,4.6653,5.4393],0.5495)
boxcox(data, lmb)
// output: [0.625,2.145,4.305,11.02,14.625,21.945,33.12,40,50.505,76.38]
FILE:references/doc_3320.md
# callMCPTool
**URL**: https://docs.dolphindb.cn/zh/funcs/c/callMCPTool.html
**来源**: DolphinDB 官方文档
---
callMCPTool
语法
callMCPTool(name, [args], [published])
详情
调用指定的 MCP Tool。
参数
name
STRING 类型标量,表示 tool 的名称。
args
可选参数,一个字典,键是 STRING 类型,值是 ANY 或 STRING 类型,表示传入 tool 的参数。
published
可选参数,布尔值,表示是否调用已发布的版本。默认为 false,表示调用尚未发布的版本。
返回值
STRING 类型标量。
例子
// 定义 tool 并发布
def myTool(x) {
return x * 2 + 1
}
info = {
"title": "DolphinDB Tool"
}
addMCPTool(name="myTool", func=myTool, argNames=["a"], argTypes=["number"], description="This is a tool", extraInfo=info)
publishMCPTools(names="myTool")
// 更新 tool,不发布
def myNewTool(x) {
return 100 * x
}
updateMCPTool(name="myTool", func=myNewTool)
// 调用发布的 myTool
callMCPTool(name="myTool", args={"a":3}, published=true)
//output:'7'
// 调用更新后未发布的 myTool
callMCPTool(name="myTool", args={"a":3}, published=false)
//output: '300'
FILE:references/doc_3325.md
# expm1
**URL**: https://docs.dolphindb.cn/zh/funcs/e/expm1.html
**来源**: DolphinDB 官方文档
---
expm1
语法
expm1(X)
详情
返回 exp(X)-1 的结果。
参数
X
可以是标量、数据对、向量、矩阵或表。
返回值
DOUBLE 类型,其数据形式同
X
。
例子
expm1(5);
// output
147.413159
expm1(1 2 3 NULL);
// output
[1.718282,6.389056,19.085537,]
expm1(1..4$2:2);
#0
#1
1.718282
19.085537
6.389056
53.59815
FILE:references/doc_3327.md
# sqlDS
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sqlDS.html
**来源**: DolphinDB 官方文档
---
sqlDS
语法
sqlDS(sqlObj, [forcePartition=false])
详情
根据输入的 SQL 元代码创建数据源列表。如果 SQL 查询中的数据表有 n 个分区,
sqlDS
生成 n 个数据源。如果 SQL 查询没有包含任何分区表,
sqlDS
返回包含一个数据源的元组。
参数
sqlObj
是 SQL 元代码。元代码的详情请参考
Metaprogramming
。
forcePartition
是一个布尔值。默认值为 false。如果
forcePartition
=false,系统会检查该查询能够拆分为多个子查询。如果不能拆分为多个子查询,系统不会在分区上拆分查询,并且会抛出异常。如果
forcePartition
=true,系统会在分区上拆分查询,并且在选中的分区中执行查询。下面两种情况的查询不能拆分为多个子查询:(1)
group by 关键字不是分区列;(2) 指定了 order by 子句。
返回值
一个元组。
例子
n=1000000
date=take(2019.01.01..2019.01.03,n)
sym = take(`C`MS`MS`MS`IBM`IBM`IBM`C`C$SYMBOL,n)
price= take(49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29,n)
qty = take(2200 1900 2100 3200 6800 5400 1300 2500 8800,n)
t=table(date, sym, price, qty)
db1=database("",VALUE,2019.01.01..2019.01.03)
db2=database("",VALUE,`C`MS`IBM)
db=database("dfs://stock",COMPO,[db1,db2])
trades=db.createPartitionedTable(t,`trades,`date`sym).append!(t)
ds=sqlDS(<select * from trades where date=2019.01.02>);
typestr ds;
// output
ANY VECTOR
size ds;
// output
3
ds[0];
// output
DataSource< select [7] * from trades [partition = /stock/20190102/C] >
ds[1];
// output
DataSource< select [7] * from trades [partition = /stock/20190102/IBM] >
ds[2];
// output
DataSource< select [7] * from trades [partition = /stock/20190102/MS] >
FILE:references/doc_333.md
# getInstrumentRate
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentrate.html
**来源**: DolphinDB 官方文档
---
getInstrumentRate
语法
getInstrumentRate(instrument)
详情
根据输入的金融工具,获取该工具的存款利率。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DOUBLE 类型标量或向量。
例子
deposit = {
"productType": "Cash",
"assetType": "Deposit",
"version": 0,
"start": 2025.05.15,
"maturity": 2025.08.15,
"rate": 0.02,
"dayCountConvention": "Actual360",
"notional":["CNY", 1E6],
"payReceive": "Receive"
}
instrument = parseInstrument(deposit)
getInstrumentRate(instrument)
// output: 0.02
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_3335.md
# parseJsonTable
**URL**: https://docs.dolphindb.cn/zh/funcs/p/parsejsontable.html
**来源**: DolphinDB 官方文档
---
parseJsonTable
语法
parseJsonTable(json, [schema],
[keyCaseSensitive=true])
详情
将 JSON 对象解析为内存表。
当
json
是包含多个 JSON 对象的字符串时,每个对象都将转换为表的一行数据;例如,
{"ID":10,
"NAME":"Riquelme","Club":"Boca Juniors"}
;
当
json
是字符串向量时,向量中每个 json 元素转换为表的一行数据。例如,[json1, json2, json3]。
当以上两种条件中的 json 包含空值时,即 {},在转换后的表中,该空值所在行的位置相应留空。
参数
json
包含 JSON 对象的字符串标量或向量。当
json
是字符串标量时,可以包含1个或多个 JSON 对象。暂不支持 JSON
数组和递归 JSON 对象。
schema
可选参数,表对象,用于指定各字段的数据类型。它可以包含以下列(必须包含 name 和 type 列):
列名
含义
name
字符串,表示列名
type
字符串,表示各列的数据类型。
format
字符串,表示数据文件中日期或时间列的格式
如果不指定
schema
,则函数将前10个 JSON 对象,自动解析表结构。
keyCaseSensitive
可选参数,表示 key 的名称是否大小写敏感。true(默认值)表示大小写敏感,false 表示大小写不敏感。
返回值
一个表对象。
例子
json1='{"ID":1, "NAME":"cc"}{"NAME":"dd"}'
parseJsonTable(json1)
返回:
ID
NAME
1
cc
dd
json2 = '{"col_test":"20190522150407"}'
schemaTB = table(["col_test"] as name, ["DATETIME"] as type, ["yyyyMMddHHmmss"] as format)
parseJsonTable(json2, schemaTB)
返回:
col_test
2019.05.22T15:04:07
当
json
是包含两个 JSON 对象的字符串时:
json3='{"ID":11, "NAME":"dd"}'
schemaTB1 = table(["ID", "NAME", "col_test"] as name, ["INT", "STRING", "DATETIME"] as type, [,,"yyyyMMddHHmmss"] as format)
parseJsonTable(concat([json2,json3]),schemaTB1)
返回:
ID
NAME
col_test
2019.05.22T15:04:07
11
dd
当
json
是字符串向量时:
parseJsonTable([json2,json3],schemaTB1)
返回:
ID
NAME
col_test
2019.05.22T15:04:07
11
dd
下例中定义了一个有三行数据的 json 对象 home,第三行数据为空({})。在第四行中,
parseJsonTable
按照第三行中
schemaLiga
中定义的
schema
转换为名为 formation 的内存表。
home = ['{"Num":10, "Name":"Ronaldo","Goal":"3","MatchDay":"20120322"}','{"Num":3, "Name":"Carlos","Goal":"1","MatchDay":"20120322"}','{}'];
schemaLiga = table(["Num","Name","Goal","MatchDay"] as name, ["INT","STRING","INT","DATE"] as type, [,,,"yyyyMMdd"] as format);
formation = parseJsonTable(home,schemaLiga);
formation;
返回:
Num
Name
Goal
MatchDay
10
Ronaldo
3
2012.03.22
3
Carlos
1
2012.03.22
打印结果显示,原属于 json 对象 home 的第三行显示为空。
FILE:references/doc_3345.md
# exists
**URL**: https://docs.dolphindb.cn/zh/funcs/e/exists.html
**来源**: DolphinDB 官方文档
---
exists
语法
exists(path)
详情
检查指定的文件或文件夹是否存在。
exists
函数也能在分布式文件系统中使用。
参数
path
字符串标量或向量,表示服务器端文件或文件夹的路径。
返回值
布尔类型标量或向量。
例子
t=table(1..10 as ID, rand(1.0, 10) as x);
saveText(t, "/home/DolphinDB/Data/t.txt");
exists("/home/DolphinDB/Data/t.txt");
// output
true
exists("/home/DolphinDB/Data/t1.txt");
// output
false
exists("/home/DolphinDB/Data");
// output
true
exists(["/home/DolphinDB/Data/t.txt","/home/DolphinDB/Data/t1.txt","/home/DolphinDB/Data"]);
// output
[true,false,true]
在分布式文件系统中检查文件或文件夹是否存在(以下脚本需要在集群中的数据节点/计算节点中执行):
n=1000000
ID=rand(10, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x)
db = database("dfs://valueDB", VALUE, 2017.08.07..2017.08.11)
pt = db.createPartitionedTable(t, `pt, `date);
pt.append!(t);
exists("dfs://valueDB/20170807");
// output
true
FILE:references/doc_3346.md
# mlast
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mlast.html
**来源**: DolphinDB 官方文档
---
mlast
语法
mlast(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
的最后一个元素。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算最后一个元素。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
index = second(08:20:00)+1..7
x = 2 1 3 NULL 6 5 4
x = index.indexedSeries(x)
mlast(x,3s)
label
col1
08:20:01
2
08:20:02
1
08:20:03
3
08:20:04
08:20:05
6
08:20:06
5
08:20:07
4
m = matrix(1 5 9 0 2, 9 10 2 NULL 2)
m.rename!((date(2020.09.08)+1..3) join 2020.09.16 join 2020.09.26, `A`B)
m.setIndexedMatrix!()
mlast(m, 3d)
label
A
B
2020.09.09
1
9
2020.09.10
5
10
2020.09.11
9
2
2020.09.16
0
2020.09.26
2
2
mlast(m, 1w)
label
A
B
2020.09.09
1
9
2020.09.10
5
10
2020.09.11
9
2
2020.09.16
0
2020.09.26
2
2
相关函数:
last
,
first
FILE:references/doc_3363.md
# getInstrumentCurrencyPair
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentcurrencypair.html
**来源**: DolphinDB 官方文档
---
getInstrumentCurrencyPair
语法
getInstrumentCurrencyPair(instrument)
详情
根据输入的金融工具,获取该工具的货币对。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
STRING 类型标量或向量。
例子
forward = {
"productType": "Forward",
"forwardType": "FxForward",
"version": 0,
"expiry": 2025.09.24,
"delivery": 2025.09.26,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E8],
"strike": 7.2
}
ins = parseInstrument(forward)
getInstrumentCurrencyPair(ins)
// output: USDCNY
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_3364.md
# snippet
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sinppet.html
**来源**: DolphinDB 官方文档
---
snippet
语法
snippet(X)
详情
获取打印结果。
参数
X
任意数据。
返回值
返回一个字符串标量。
例子
a = [["a","b"],"c"]
snippet(a)
//output
"(["a","b"],"c")"
snippet(date(2023.01.01))
//output
"2023.01.01"
FILE:references/doc_3368.md
# tmrank
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmrank.html
**来源**: DolphinDB 官方文档
---
tmrank
语法
tmrank(T, X, ascending, window, [ignoreNA=true], [tiesMethod='min'],
[percent=false])
部分通用参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
元素在其对应窗口内的排名。
参数
ascending
是一个布尔值,表示是否按升序排序。默认值是 true。
ignoreNA
是一个布尔值,表示是否忽略 NULL 值。true 表示忽略 NULL 值(默认值),false 表示 NULL 值参与排名,此时
NULL 值为最小值。
tiesMethod
是一个字符串,表示窗口内若存在重复值时,排名如何选取。
'min'表示取最小排名。
'max'表示取最大排名。
'average'表示取排名的均值。
percent
是一个布尔值,表示是否以百分比形式显示返回的排名,默认值为 false。
返回值
与
X
长度相同的 INT 类型向量。
例子
tmrank(1 1 3 5 8 15 15 20, 5 2 4 1 2 8 9 10, ascending=true, window=3)
// output
[0,0,1,0,0,0,1,0]
index = take(datehour(2019.06.13 13:30:10),4) join (datehour(2019.06.14 13:30:10)+1..6)
data = 1 NULL 3 4 5 NULL 3 NULL 5 3
tmrank(index, data, ascending=true, window=4h)
// output
[0,,1,2,0,,0,,1,0]
tmrank(index, data, ascending=true, window=2d)
// output
[0,,1,2,3,,1,,4,1]
相关函数:
mrank
,
rank
FILE:references/doc_3372.md
# pivot by
**URL**: https://docs.dolphindb.cn/zh/progr/sql/pivotBy.html
**来源**: DolphinDB 官方文档
---
pivot by
pivot by
是 DolphinDB 的独有功能,是对标准 SQL
语句的拓展。它将表中一列或多列的内容按照两个维度重新排列,亦可配合数据转换函数使用。与 select 子句一起使用时返回一个表,而和 exec
语句一起使用时返回一个矩阵。若重新排列后行维度存在多个相同值,则会进行去重,只保留最后一个值。 参考
pivot
和
unpivot
。
从 2.00.10.4 版本开始,
pivot by
支持搭配 select
子句查询表中的数组向量列,返回一个表,且支持对数组向量列应用聚合函数(row 系列函数除外);
pivot by
支持搭配 exec
子句对数组向量列应用返回标量的聚合函数(例如 max, sum 等),此时返回一个矩阵,详见例6。
pivot by
在以下版本中进行了优化:
优化版本
优化内容
1.20.4
pivot by
后面的列数可为两个以上,其中最后一列为列维度,其它各列均为行维度。 使用
pivot by
时,select 子句可使用多个指标。
2.00.9
对满足以下2个条件的
pivot by
语句进行了优化:
对查询的列不使用以下函数时:聚合函数(例如
sum
)、序列相关函数(例如:
last
)、行函数(例如:
rowMin
)、填充(例如:
ffill
)函数。
pivot by
最后一列为分区列。
2.00.10.4
若
pivot by
后面的列在原表中存在多个相同的组合值,当同时满足以下条件时,对至少一个查询列应用
asis
函数,则不会对数据去重而是保留所有数据:
查询的表是 DFS 表。
from
子句不包含各种类型的表连接(
join
语句)
pivot by
子句的前 n-1 列不能是 DECIMAL128 类型。
pivot by
子句的最后一列是分区列。
查询的列不含聚合函数、序列函数、行处理函数和填充函数,且查询列不包含空值。
原始数据可以填满
pivot by
的宽表结果,即
pivot
by
前 n-1 列的每个取值组合对应的行数虽不要求严格相等,但对于
pivot
by
前 n-1 列的每个取值组合内,
pivot by
最后一列的取值的个数必须相等。
例子
例1:行维度为一列(即 pivot by 之后仅有两列)
sym = `C`MS`MS`MS`IBM`IBM`C`C`C
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:35:42,09:36:51,09:36:59,09:35:47,09:36:26,09:34:16,09:35:26,09:36:12]
t2 = table(timestamp, sym, qty, price);
t2;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:35:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:35:47
IBM
6800
174.97
09:36:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:35:26
C
2500
50.32
09:36:12
C
8800
51.29
将表 t2 的 timestamp 列作为行索引,sym 列作为列索引,查看 price 列的值。
select price from t2 pivot by timestamp, sym;
timestamp
C
IBM
MS
09:34:07
49.6
09:34:16
50.76
09:35:26
50.32
09:35:42
29.46
09:35:47
174.97
09:36:12
51.29
09:36:26
175.23
09:36:51
29.52
09:36:59
30.02
查看表 t2 每一分钟,不同 sym 对应的 price。
a=select price from t2 pivot by timestamp.minute(), sym;
a;
minute_timestamp
C
IBM
MS
09:34m
50.76
09:35m
50.32
174.97
29.46
09:36m
51.29
175.23
30.02
typestr a;
// output
TABLE
//pivot by 与 exec 搭配使用,查看一分钟内各个 sym 对应的 price 的数量,结果为一个矩阵
b=exec count(price) from t2 pivot by timestamp.minute(), sym;
b;
label
C
IBM
MS
09:34m
2
09:35m
1
1
1
09:36m
1
1
2
typestr b;
// output
FAST DOUBLE MATRIX
例2:计算 ETF 的内在价值
为简便起见,假设 ETF 有两个成分股:AAPL 和 FB,其成分权重为 [0.6, 0.4]。
symbol=take(`AAPL, 6) join take(`FB, 5)
time=2019.02.27T09:45:01.000000000+[146, 278, 412, 445, 496, 789, 212, 556, 598, 712, 989]
price=173.27 173.26 173.24 173.25 173.26 173.27 161.51 161.50 161.49 161.50 161.51
quotes=table(symbol, time, price)
weights=dict(`AAPL`FB, 0.6 0.4)
ETF = select symbol, time, price*weights[symbol] as price from quotes;
select price from ETF pivot by time, symbol;
Time
AAPL
FB
2019.02.27T09:45:01.000000146
103.962
2019.02.27T09:45:01.000000212
64.604
2019.02.27T09:45:01.000000278
103.956
2019.02.27T09:45:01.000000412
103.944
2019.02.27T09:45:01.000000445
103.95
2019.02.27T09:45:01.000000496
103.956
2019.02.27T09:45:01.000000556
64.6
2019.02.27T09:45:01.000000598
64.596
2019.02.27T09:45:01.000000712
64.6
2019.02.27T09:45:01.000000789
103.962
2019.02.27T09:45:01.000000989
64.604
以上结果为在每个时间戳经过 ETF 权重调整的股票价格。 为了计算 ETF 在每个时间戳的内在价值,需要使用
ffill
函数来填充每个股票的 NULL
值,然后将所有股票价格相加。可在一个 SQL 语句中完成。
select rowSum(ffill(price)) from ETF pivot by time, symbol;
Time
rowSum
2019.02.27T09:45:01.000000146
103.962
2019.02.27T09:45:01.000000212
168.566
2019.02.27T09:45:01.000000278
168.56
2019.02.27T09:45:01.000000412
168.548
2019.02.27T09:45:01.000000445
168.554
2019.02.27T09:45:01.000000496
168.56
2019.02.27T09:45:01.000000556
168.556
2019.02.27T09:45:01.000000598
168.552
2019.02.27T09:45:01.000000712
168.556
2019.02.27T09:45:01.000000789
168.562
2019.02.27T09:45:01.000000989
168.566
例3:使用 pivot by 时某些新建列名的自动转换
版本说明
:
2.00.2
版本以前,DolphinDB 中列名仅可使用中文或英文字母、数字或下划线
(_),且必须以中文或英文字母开头。
2.00.2
版本开始,由
pivot by
,
addColumn
操作产生的列名,支持包含特殊字符,或以数字开头。
详情可以参考:
创建表章节
。
date = take(2021.08.01 2021.08.02 2021.08.03, 12)
sym = take(["IBM N", "_MSFTN", "3_GOOGS", ""], 12).sort()
value = 1..12
t=table(date, sym, value)
re = select value from t pivot by date, sym
date
NULL
3_GOOGS
IBM N
_MSFTN
2021.08.01
1
4
7
10
2021.08.02
2
5
8
11
2021.08.03
3
6
9
12
select _"NULL" from re
NULL
1
2
3
select _"3_GOOGS" from re
3_GOOGS
4
5
6
下例中,设置
removeSpecialCharInColumnName
= true,股票代码
"600300" 与 "600600" 在成为列名后,系统自动将其处理为 "C600300" 与 "C600600"。
symbol=take(`600300, 6) join take(`600600, 5)
time=2019.02.27T09:45:01.000000000+[146, 278, 412, 445, 496, 789, 212, 556, 598, 712, 989]
price=173.27 173.26 173.24 173.25 173.26 173.27 161.51 161.50 161.49 161.50 161.51
quotes=table(symbol, time, price)
weights=dict(`600300`600600, 0.6 0.4)
ETF = select symbol, time, price*weights[symbol] as price from quotes;
select last(price) from ETF pivot by time, symbol;
time
C600300
C600600
2019.02.27T09:45:01.000000146
103.962
2019.02.27T09:45:01.000000212
64.604
2019.02.27T09:45:01.000000278
103.956
2019.02.27T09:45:01.000000412
103.944
2019.02.27T09:45:01.000000445
103.95
2019.02.27T09:45:01.000000496
103.956
2019.02.27T09:45:01.000000556
64.6
2019.02.27T09:45:01.000000598
64.596
2019.02.27T09:45:01.000000712
64.6
2019.02.27T09:45:01.000000789
103.962
2019.02.27T09:45:01.000000989
64.604
例4:行维度为多列(即 pivot by 之后多于两列)
date = 2020.09.21 + 0 0 0 0 1 1 1 1
sym = `MS`MS`GS`GS`MS`MS`GS`GS$SYMBOL
factorNum = 1 2 1 2 1 2 1 2
factorValue = 1.2 -3.4 -2.5 6.3 1.1 -3.2 -2.1 5.6
t = table(date, sym, factorNum, factorValue);
t;
date
sym
factorNum
factorValue
2020.09.21
MS
1
1.2
2020.09.21
MS
2
-3.4
2020.09.21
GS
1
-2.5
2020.09.21
GS
2
6.3
2020.09.22
MS
1
1.1
2020.09.22
MS
2
-3.2
2020.09.22
GS
1
-2.1
2020.09.22
GS
2
5.6
将表 t 的 date 列和 sym 列作为行索引,factorNum 列作为列索引,查看 factorValue 列的值。
select factorValue from t pivot by date, sym, factorNum;
date
sym
1
2
2020.09.21
GS
-2.5
6.3
2020.09.21
MS
1.2
-3.4
2020.09.22
GS
-2.1
5.6
2020.09.22
MS
1.1
-3.2
返回每个 factorNum
对应的多个指标
select factorValue, factorValue>0 as factorSign from t pivot by date, sym, factorNum;
date
sym
factorValue_1
factorValue_2
factorSign_1
factorSign_2
2020.09.21
GS
-2.5
6.3
0
1
2020.09.21
MS
1.2
-3.4
1
0
2020.09.22
GS
-2.1
5.6
0
1
2020.09.22
MS
1.1
-3.2
1
0
例5:应用
asis
函数保留全量数据。
本例中满足以下条件:
pt 是 DFS 表
from 子句不包含表连接
pivot by
子句的前 n-1 列,即 time 列不含 DECIMAL128 类型
pivot by
子句最后一列 sym 是分区列
查询语句 select value 不含聚合函数、行处理函数和填充函数,且 value 列不含空值
数据可以填满
pivot by
的宽表结果,即对于 time 列的每个不同的取值,
pivot
by
最后一列的取值的个数必须相等, time=10:20:44 时,sym 的取值 A、B、C
对应的行数均为1;time=10:20:45 时,sym 的取值 A、B、C 对应的行数均为1;time=10:20:46 时,sym 的取值
A、B、C 对应的行数均为2。
此时对查询列 value 应用
asis
函数,可以保留全量数据。
time = [10:20:44,10:20:44,10:20:44,10:20:45,10:20:45,10:20:45,10:20:46,10:20:46,10:20:46,10:20:46,10:20:46,10:20:46]
sym = ["A","B","C","A","B","C","A","B","C","A","B","C"]
value = [510,434,999,837,402,615,495,885,745,968,975,165]
t = table(time,sym,value)
db = database("dfs://test_pivot",VALUE,`A`B`C)
pt = db.createPartitionedTable(t,`pt,`sym)
pt.append!(t)
select value from pt pivot by time,sym
time
A
B
C
10:20:44
510
434
999
10:20:45
837
402
615
10:20:46
968
975
165
select asis(value) from pt pivot by time,sym
time
A
B
C
10:20:44
510
434
999
10:20:45
837
402
615
10:20:46
495
885
745
10:20:46
968
975
165
例6:
pivot by
搭配 select/exec 子句查询数组向量列并进行聚合计算。
首先创建一个内存表,其中 val1
为数组向量列
id = `A`B`B`B`C`C`D`D`D
val1 = array(DOUBLE[], 0, 10).append!([1.0, 2.1 2.2 2.4, 2.1 2.2 2.4, 3, 5, 1.6 7, 8.9 100, 2.3, 1.1 4 5.1 4]);
val2 = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:35:42,09:36:51,09:36:59,09:35:47,09:36:26,09:34:16,09:35:26,09:36:12]
t = table(timestamp, id, val1, val2);
//对查询每分钟各个 id 对应的 val1 值
select val1 from t pivot by timestamp.minute(), id;
minute_timestamp
A
B
C
D
09:34m
[1.0000]
[]
[]
[8.9000,100.0000]
09:35m
[]
[2.1000,2.2000,2.4000]
[5.0000]
[2.3000]
09:36m
[]
[3.0000]
[1.6000,7.0000]
[1.1000,4.0000,5.1000,4.0000]
搭配 select,对 val1
应用聚合函数,返回一个表
select max(val1) from t pivot by timestamp.minute(), id;
label
A
B
C
D
09:34m
1.0000
100.0000
09:35m
2.4000
5.0000
2.3000
09:36m
3.0000
7.0000
5.1000
FILE:references/doc_3375.md
# pwlfPredict
**URL**: https://docs.dolphindb.cn/zh/funcs/p/pwlfpredict.html
**来源**: DolphinDB 官方文档
---
pwlfPredict
语法
pwlfPredict(model, X, [beta], [breaks])
详情
本函数须结合函数
piecewiseLinFit
共同使用,即使用
piecewiseLinFit
拟合后的连续分段线性回归模型来对输入的数据点进行预测。
参数
model
字典类型,由
piecewiseLinFit
函数返回的分段线性回归模型。
X
数值向量,表示需要预测的数据点的 x 坐标。注意:不可传入 NULL 值。
beta
可选参数,数值向量,表示分段线性回归模型的参数。注意:不可传入 NULL 值。
breaks
可选参数,数值向量,表示每段线段终点处的 x 坐标,每段线段的终点又被称为每段线段的断点。注意:不可传入 NULL 值。
返回值
浮点数向量,表示模型的预测值。
例子
本例先自定义参数条件,使用
piecewiseLinFit
拟合生成连续分段线性回归模型;再传入预测的数据点的 x 坐标
xHat
,最后使用
pwlfPredict
计算模型的预测值。
def linspace(start, end, num, endpoint=true){
if(endpoint) return end$DOUBLE\(num-1), start + end$DOUBLE\(num-1)*0..(num-1)
else return start + end$DOUBLE\(num-1)*0..(num-1)
}
X = linspace(0.0, 1.0, 10)[1]
Y = [0.41703981, 0.80028691, 0.12593987, 0.58373723, 0.77572962, 0.41156172, 0.72300284, 0.32559528, 0.21812564, 0.41776427]
model = piecewiseLinFit(X, Y, 3)
xHat = linspace(0.0, 1.0, 20)[1]
pwlfPredict(model, xHat)
/*
output:
[0.593305499919518 0.524360777381737 0.455416054843957 0.386471332306177 0.317526609768396 0.368043438179296 0.529813781212159 0.691584124245021 0.69295837868457 0.655502915538459 0.618047452392347 0.580591989246236 0.543136526100125 0.505681062954014 0.468225599807903 0.430770136661792 0.393314673515681 0.35585921036957 0.318403747223459 0.280948284077348]
*/
相关函数:
piecewiseLinFit
FILE:references/doc_3378.md
# atImax
**URL**: https://docs.dolphindb.cn/zh/funcs/a/atImax.html
**来源**: DolphinDB 官方文档
---
atImax
语法
atImax(location, value)
详情
找出
location
中最大值所在的位置,然后返回
value
中该位置对应的值。如果
location
中有多个相同的最大值,则取第一个最大值所在的位置。
若
location
和
value
是矩阵,则
location
和
value
的每列一一对应,分别计算
atImax
。
atImax(location, value) 相当于 value[imax(location)]。
参数
location
和
value
是向量、矩阵或表。
返回值
根据输入形式返回不同的结果:若输入为向量,返回标量;若输入为矩阵,返回向量。
数据类型与 value 一致。
例子
atImax(3 5 1 2, 9 7 5 3)
// output
7
m1=matrix(9 2 1 5 6 9, 3 1 3 NULL 5 2, 2 8 1 2 3 4)
m2=matrix(1..6, 1..6, 1..6)
atImax(m1,m2)
// output
[1,5,2]
相关函数:
imax
,
atImin
FILE:references/doc_3387.md
# cumavg
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumavg.html
**来源**: DolphinDB 官方文档
---
cumavg
语法
cumavg(X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累积平均值。
返回值
DOUBLE 类型,其数据形式同
X
。
例子
x=[2,3,NULL,4];
cumavg(x);
[2,2.5,2.5,3]
m=matrix(1 2 3 NULL 4, 5 6 NULL 7 8);
m;
#0
#1
1
5
2
6
3
7
4
8
cumavg(m);
#0
#1
1
5
1.5
5.5
2
5.5
2
6
2.5
6.5
相关函数:
avg
FILE:references/doc_3403.md
# merge
**URL**: https://docs.dolphindb.cn/zh/funcs/m/merge.html
**来源**: DolphinDB 官方文档
---
merge
语法
merge(left, right, [how='inner'])
详情
联结两个索引序列或两个索引矩阵。
参数
left
与
right
均为索引序列,或均为索引矩阵。
how
是字符串,表示如何对数据进行联结。可取值为 'inner', 'outer', 'left', 'right' 与 'asof'。默认值为
‘inner’。
返回值
一个矩阵。
例子
a = indexedSeries(2012.01.01..2012.01.04, 1..4)
b = indexedSeries([2012.01.01, 2012.01.03, 2012.01.05, 2012.01.06], 5..8)
merge(a, b);
series1
series2
2012.01.01
1
5
2012.01.03
3
6
merge(a, b, 'left');
series1
series2
2012.01.01
1
5
2012.01.02
2
2012.01.03
3
6
2012.01.04
4
m1 = matrix([1.2, 7.8, 4.6, 5.1, 9.5], [0.15, 1.26, 0.45, 1.02, 0.33]).rename!([2012.01.01, 2015.02.01, 2015.03.01, 2015.04.01, 2015.05.01], `x1`x2).setIndexedMatrix!()
m2 = matrix([1.0, 2.0, 3.0, 4.0], [0.14, 0.26, 0.35, 0.48]).rename!([2015.02.01, 2015.02.16, 2015.05.01, 2015.05.02], `y1`y2).setIndexedMatrix!()
m = merge(m1, m2, 'asof');
x1
x2
y1
y2
2012.01.01
1.2
0.15
2015.02.01
7.8
1.26
1
0.14
2015.03.01
4.6
0.45
2
0.26
2015.04.01
5.1
1.02
2
0.26
2015.05.01
9.5
0.33
3
0.35
FILE:references/doc_3404.md
# restoreSettings
**URL**: https://docs.dolphindb.cn/zh/funcs/r/restoresettings.html
**来源**: DolphinDB 官方文档
---
restoreSettings
语法
restoreSettings(fileName, [overwrite=false])
详情
此函数只能由管理员在控制节点执行,将备份文件中保存的用户、用户权限和函数视图恢复到当前集群。
备份文件由函数
backupSettings
生成,与之搭配可以在数据库迁移时实现用户、用户权限及函数视图的迁移。
参数
fileName
STRING 类型标量,指定备份文件的路径,可以为绝对路径或相对于 <HomeDir> 的相对路径。
overwrite
BOOL 类型标量,表示是否将当前数据库系统的用户、用户权限和函数视图更新为与备份文件完全一致:
false:默认值,表示在恢复过程中仅添加备份文件中存在但当前系统中不存在的用户及其权限、函数视图。对于当前系统已存在的用户和函数视图,不会做任何修改。
true:表示将当前系统的用户、用户权限和函数视图设置为与备份文件完全一致,即删除当前系统中不存在于备份文件中的用户和函数视图,并添加备份文件中保存的用户及其权限、函数视图。
返回值
函数返回一个向量,依次列出已成功恢复的用户名和函数视图名称。
例子
下例以用户及权限为例,函数视图规则与之类似。
当前集群有用户 A 和 B,备份文件中保存了用户 A,C 。
// 集群中A、B及其权限不变,增加用户C及其权限
restoreSettings(fileName="/home/ddb/backup/permission.back", overwrite=false)
// 集群中A的权限更新为与备份文件一致,删除用户B,增加用户C及其权限
restoreSettings(fileName="/home/ddb/backup/permission.back", overwrite=true)
相关函数:
backupSettings
FILE:references/doc_341.md
# latestKeyedStreamTable
**URL**: https://docs.dolphindb.cn/zh/funcs/l/latestkeyedstreamtable.html
**来源**: DolphinDB 官方文档
---
latestKeyedStreamTable
语法
latestKeyedStreamTable(keyColumns, timeColumn, [X1], [X2],
.....)
或
latestKeyedStreamTable(keyColumns, timeColumn, capacity:size, colNames,
colTypes)
详情
创建一个键值流数据表,该表包含一个主键,且该主键不允许重复值。主键可由一个或多个字段组成。其相较于
keyedStreamTable,除主键外,还包含一个时间列,用于判断是否添加记录。
向表中添加新记录时,系统会自动检查新记录的主键值:
如果新记录的主键值与内存中已有记录的主键值相同,且新记录的时间戳大于已有记录的时间戳,则将新记录添加至表中,否则直接舍弃。
一次性批量插入新记录时,若有多条记录具有相同的主键值,且该主键值与已有记录的主键值不同,只有时间戳最大的记录可以插入成功。
参数
在
keyedStreamTable
的基础上,增加了
timeColumn
参数。
timeColumn
字符串标量或长度为 2 的向量,分别用于指定 1 个或 2 个时间列。当仅指定 1 个时间列时,该列可以为整型或时间类型;当指定 2
个时间列时,第 1 列必须是 DATE 类型,第 2 列则是 TIME, SECOND 或 NANOTIME 类型。通过这两列,可以共同确定唯一的时间值。
返回值
一张表。
例子
例1. 主键为 1 个字段
第一种写法:
id = `A`B`C`D`E
x = 1 2 3 4 5
timeCol = 2024.09.10T00:00:00.001+0..4
t1 = latestKeyedStreamTable(`id, `timeCol, id, x, timeCol)
t1;
id
x
timeCol
A
1
2024.09.10T00:00:00.001
B
2
2024.09.10T00:00:00.002
C
3
2024.09.10T00:00:00.003
D
4
2024.09.10T00:00:00.004
E
5
2024.09.10T00:00:00.005
第二种写法:
t2=latestKeyedStreamTable(`id, `timeCol, 100:0, `id`x`timeCol, [INT,INT,TIMESTAMP])
insert into t2 values(1 2 3, 10 20 30, [2024.09.10T00:00:00.001,
2024.09.10T00:00:00.002, 2024.09.10T00:00:00.003])
t2
id
x
timeCol
1
10
2024.09.10T00:00:00.001
2
20
2024.09.10T00:00:00.002
3
30
2024.09.10T00:00:00.003
向表 t1 中插入新记录,并且新记录中的主键值与表中主键值相同时,将根据
timeColumn
来确定是否插入新记录:
insert into t1 values(`D`E`F, 6 7 8, [2024.09.10T00:00:00.005,
2024.09.10T00:00:00.005, 2024.09.10T00:00:00.005])
t1
id
x
timeCol
A
1
2024.09.10T00:00:00.001
B
2
2024.09.10T00:00:00.002
C
3
2024.09.10T00:00:00.003
D
4
2024.09.10T00:00:00.004
E
5
2024.09.10T00:00:00.005
D
6
2024.09.10T00:00:00.005
F
8
2024.09.10T00:00:00.005
可以看到,新插入了 id=`D 和 id=`F 的记录,而 id=`E 的记录被丢弃了。新增的 id 为 D 的记录因为时间戳大于已存在的 id 为 D
的记录,所以插入成功;id 为 E 的记录因为时间戳等于已有的 id 为 E 的记录,所以被舍弃;因为已有记录中没有 id 为 F 的记录,所以它被成功插入。
例2. 主键为多个字段
t3 = latestKeyedStreamTable(`id`x, `timeCol, id, x, timeCol)
insert into t3 values(`D`E, 4 5, [2024.09.10T00:00:00.004, 2024.09.10T00:00:00.005])
insert into t3 values(`D`F, 6 7, [2024.09.10T00:00:00.004, 2024.09.10T00:00:00.005])
t3
id
x
timeCol
A
1
2024.09.10T00:00:00.001
B
2
2024.09.10T00:00:00.002
C
3
2024.09.10T00:00:00.003
D
4
2024.09.10T00:00:00.004
E
5
2024.09.10T00:00:00.005
D
6
2024.09.10T00:00:00.004
F
7
2024.09.10T00:00:00.005
例3. 时间列指定为两列
id = `A`B`C`D`E
dateCol = take(2024.09.10, 5)
timeCol = 00:00:00.001+0..4
t4 = latestKeyedStreamTable(`id, `dateCol`timeCol, id, x, dateCol, timeCol)
t4
id
x
dateCol
timeCol
A
1
2024.09.10
00:00:00.001
B
2
2024.09.10
00:00:00.002
C
3
2024.09.10
00:00:00.003
D
4
2024.09.10
00:00:00.004
E
5
2024.09.10
00:00:00.005
向表 t4 中插入新记录,并且新记录中的主键值与表中主键值相同时,将根据
concatDateTime(dateCol, timeCol)
的值来确定是否插入新记录:
insert into t4 values(`D`E, 4 5, [2024.09.10, 2024.09.11], [00:00:00.004, 00:00:00.005]);
t4
id
x
dateCol
timeCol
A
1
2024.09.10
00:00:00.001
B
2
2024.09.10
00:00:00.002
C
3
2024.09.10
00:00:00.003
D
4
2024.09.10
00:00:00.004
E
5
2024.09.10
00:00:00.005
E
5
2024.09.11
00:00:00.005
FILE:references/doc_3411.md
# map
**URL**: https://docs.dolphindb.cn/zh/progr/sql/map.html
**来源**: DolphinDB 官方文档
---
map
使用 map 关键字,SQL 语句会在每个分区内分别执行,然后输出每个分区的执行结果。
适合使用 map 关键字的场景:
场景一:需要在每个分区内进行查询的场景(见 例子 1)
场景二:分组查询计算提升性能(见 例子 2)
对分组数据进行查询和计算时,通常先在各个分区单独计算,然后将结果进行进一步计算以保证最终结果的正确性。如果分区的粒度大于分组的粒度,从而可以确保数据的查询和计算不会跨分区进行,则可添加
map 关键字,避免进一步计算的开销,从而提升查询性能。
注:
SQL where 子句中一般不允许使用聚合函数或序列相关函数,原因在于:
若允许则会进行全表扫描计算,无法进行分区剪枝。
但若使用 map 关键字,则允许在 where
子句中使用聚合函数或序列相关函数,在每个分区内部进行指定计算以过滤记录。(见 例子 3)
例子
分区计算
t = table(0..9 as id, take(1 2 3, 10) as qty)
db=database("dfs://rangedb", RANGE, 0 5 10)
pt = db.createPartitionedTable(t, `pt, `id)
pt.append!(t);
select * from pt;
id
qty
0
1
1
2
2
3
3
1
4
2
5
3
6
1
7
2
8
3
9
1
select first(id), count(*) from pt map;
first_id
count
0
5
5
5
合理使用 map 关键字
合理使用 map 关键字有助于在分组查询和计算时提升性能:
t = table(2022.01.01T00:00:00 + rand(10000000, 10000) as dateTime, rand(1000, 10000) as qty)
if(existsDatabase("dfs://valuedb")) dropDatabase("dfs://valuedb")
db=database("dfs://valuedb", VALUE, 2022.02.01..2022.02.05)
pt = db.createPartitionedTable(t, `pt, `dateTime)
pt.append!(t)
timer(1000) select count(*) from pt group by bar(dateTime, 60)
Time elapsed: 4010.31 ms
timer(1000) select count(*) from pt group by bar(dateTime, 60) map
Time elapsed: 3607.331 ms
跨分区查询
跨分区查询时,指定 map 关键字,以支持在 where 子句中使用聚合函数或者序列相关函数进行条件过滤
t = table(0..9 as id, take(1 2 3, 10) as qty)
db=database("dfs://rangedb", RANGE, 0 5 10)
pt = db.createPartitionedTable(t, `pt, `id)
pt.append!(t);
select * from pt where isDuplicated([id,qty]) = false map;
id
qty
0
1
1
2
2
3
3
1
4
2
5
3
6
1
7
2
8
3
9
1
FILE:references/doc_3418.md
# SQL 语句
**URL**: https://docs.dolphindb.cn/zh/progr/sql/sql_intro.html
**来源**: DolphinDB 官方文档
---
SQL 语句
DolphinDB 中 SQL 语句的基本语法和用法
DolphinDB 中的 SQL 语句
在以下内容中,您将了解到 SQL 语句在 DolphinDB
中访问、获取以及操作数据的使用方法。DolphinDB 的 SQL 格式与主流关系型数据库管理系统中的 SQL 语言十分相似,例如 MySQL, Oracle, SQL
Server 等。
语法
SELECT
[top_clause] column_expressions
FROM
table_name
| table_expression
[
WHERE
filtering_conditions]
[grouping_clause [having_clause] | order_clause]
对 ANSI SQL 92 标准的支持
DolphinDB SQL 对 ANSI SQL 92 (下文简称 SQL-92)标准的支持历史如下:
支持 select, insert, update, delete
语句分别用于查询、插入、更新、删除数据表中的记录。从
2.00.5
版本开始,DolphinDB 支持 create
语句创建数据库(表),alter 语句为表增加列。从
2.00.10
版本开始,DolphinDB 的 SQL 关键字也可以采用全部大写的形式,例如
SELECT, FROM, WHERE 等。
支持 where 条件。
支持分组 (group by) 和排序 (order by) 子句。
支持表连接:inner join, left join, left semijoin, full join。
从版本
2.00.10
开始,支持将 SQL 语句分成多行编写。但请注意以下2点:
由 2 个单词组成的关键字(例如:order by, group by, context by,
pivot by, union all, inner join, nulls first 等)不能在中间拆分换行。
为字段或表指定别名时,若不使用关键字 as,则别名必须紧跟在原名称后面,不能换行。
DolphinDB SQL 与 SQL 92 的区别
可在 SQL 查询中直接使用绝大部分函数。
其它区别如下表所示:
表
1
.
DolphinDB SQL与 SQL-92 的语法差异
SQL-92 语法
DolphinDB 语法
说明
N/A
context by
context by
是 DolphinDB
的独有的创新,它使得在处理各组内时间序列时非常方便。
context
by
与
group by
相似,但是
group
by
的结果为每一组返回一个标量值,而
context by
的结果为
每一组返回一个与组内记录数同样长度的向量。
N/A
pivot by
pivot
by
将数据转换成二维视图。
N/A
cgroup by
N/A
map
将 SQL 语句在每个分区分别执行,然后将结果合并。
N/A
aj
asof
连接。它把左表中的每一条记录作为标准,并且检查右表中是否有匹配行。如果没有完全匹配的行,将会选择最近的行。如果有多个匹配行,将会选择最后一行。
N/A
wj
,
pwj
窗口连接和现行窗口连接。它们是
asof
连接的扩展。对于左表中的每一行,窗口连接把聚合函数应用到在滑动窗口中右表的行。如果右表中没有与窗口匹配的值,现行窗口连接会选择滑动窗口的前一个值,并对它使用聚合函数。
SQL 方言兼容
自
2.00.10
版本开始,DolphinDB 实现了对 Oracle 和 MySQL 方言的兼容性。除了支持 SQL-92
语法外,还解决了因不同方言的扩展特性导致同名函数执行行为不一致的问题。通过会话(session)选择方言模式,便可在该会话中执行相应语言编写的脚本。目前有三种模式可选:DolphinDB,
Oracle 和 MySQL。
注:
Oracle 和 MySQL 方言模式也能正确解析使用 DolphinDB 语言编写的脚本。
仅支持 Oracle 和 MySQL 的部分功能和函数,见下表:
SQL 方言
支持功能
支持函数(无分大小写)
Oracle
注释符:--、/**/
字符串拼接符:||
asciistr, concat, decode, instr, length,
listagg, nvl, nvl2, rank, regexp_like, replace, to_char, to_date,
to_number, trunc, wm_concat
注:
to_char
只接收数值类型和 DATE, DATEHOUR, DATETIME 类型的参数。有关 Oracle SQL
函数的语法参考,请访问:
SQL Language
Reference
MySQL
sysdate
注:
有关
MySQL 函数的语法参考,请访问:
MySQL :: MySQL 8.0 Reference
Manual :: 12 Functions and Operators
FILE:references/doc_3426.md
# lower
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lower.html
**来源**: DolphinDB 官方文档
---
lower
语法
lower(X)
详情
lower
函数把字符串或字符串列表中的所有字符转换为小写。
当
X
是表时,函数仅作用于其中 CHAR、STRING、SYMBOL 列,其他类型的列将被忽略。
参数
X
是字符/字符串/SYMBOL 类型的标量、向量,或表。
返回值
返回值的类型和形式与
X
一致,所有字符均为小写。
例子
x= `Ibm`C`AapL;
x.lower();
// output
["ibm","c","aapl"]
lower(`Thl);
// output
thl
相关函数:
upper
FILE:references/doc_3431.md
# glm
**URL**: https://docs.dolphindb.cn/zh/funcs/g/glm.html
**来源**: DolphinDB 官方文档
---
glm
语法
glm(ds, yColName, xColNames, [family], [link], [tolerance=1e-6],
[maxIter=100])
详情
训练广义线性模型。
参数
ds
是数据源,通常由
sqlDS
函数生成。
yColName
是字符串,表示数据源中作为因变量的列名。
xColNames
是字符串标量或向量,表示数据源中作为自变量的列名。
family
是字符串标量,表示指数族分布的类型。它的取值可以是 gaussian, poisson, gamma, inverseGaussian,
binomial。
link
是字符串标量,表示
link
函数的类型。对于不同取值的
family
,
link
的默认值如下表所示。
tolerance
是浮点数,表示迭代中止的边界差值。如果相邻两次迭代的对数似然函数值的差值小于
tolerance
,则停止迭代。默认值为0.000001。
maxIter
是正整数,表示最大的迭代次数。默认值为100。
family
参数对
link
参数、因变量的限制如下:
family
的取值
link
可选值
默认的
link
取值
因变量的取值
gaussian
identity, inverse, log
identity
DOUBLE 类型
poisson
log, sqrt, identity
log
非负整数
gamma
inverse, identity, log
inverse
大于等于0
inverseGaussian
inverseOfSquare, inverse, identity, log
inverseOfSquare
大于等于0
binomial
logit, probit
logit
0或1
返回值
返回一个字典,包含以下 key:coefficients, link, tolerance, family, xColNames,
tolerance, modelName, residualDeviance, iterations 和 dispersion。其中,coefficients
是一张表,包括计算得到的自变量系数值、每个系数的标准误差、t 值、p 值;modelName 为 "Generalized Linear
Model";iterations 是实际迭代次数;dispersion 是模型的规范系数。
例子
下面的例子使用模拟数据训练一个广义线性模型:
x1 = rand(100.0, 100)
x2 = rand(100.0, 100)
b0 = 6
b1 = 1
b2 = -2
err = norm(0, 10, 100)
y = b0 + b1 * x1 + b2 * x2 + err
t = table(x1, x2, y)
model = glm(sqlDS(<select * from t>), `y, `x1`x2, `gaussian, `identity);
model;
// output
coefficients->
beta stdError tstat pvalue
-------- -------- ---------- --------
1.027483 0.032631 31.487543 0
-1.99913 0.03517 -56.842186 0
5.260677 2.513633 2.092858 0.038972
link->identity
tolerance->1.0E-6
family->gaussian
xColNames->["x1","x2"]
modelName->Generalized Linear Model
residualDeviance->8873.158697
iterations->5
dispersion->91.475863
把模型用于预测:
predict(model, t);
把模型保存到磁盘:
saveModel(model, "C:/DolphinDB/Data/GLMModel.txt");
把模型加载到内存中:
loadModel("C:/DolphinDB/Data/GLMModel.txt");
FILE:references/doc_3432.md
# duration
**URL**: https://docs.dolphindb.cn/zh/funcs/d/duration.html
**来源**: DolphinDB 官方文档
---
duration
语法
duration(X)
详情
将一个字符串标量转换为 DURATION 类型。表示一个时间区间。
注:
用于分组的时间区间单位应需不小于时间列的单位。
时间单位区分大小写,例如:M 表示月份,m 表示分钟;若分组的时间区间单位为 M,时间列需要通过函数
month
转换为对应月份。
DURATION 类型数据之间不能进行任何运算。例如,不能进行比较运算:
duration('20ms') >=
duration('10ms')
。
参数
X
是一个字符串,为一个数字与时间单位所组成。支持以下时间单位:y, M, w, d, B, H, m, s, ms,
us, ns
和由四个大写英文字母构成的交易日历标识(
duration
函数不会校验交易日历文件是否存在于
marketHolidayDir
中)
。例如:"2y", "3M", "30m",
"100ms"
, "3XNYS"
等。
返回值
DURATION 类型标量。
例子
y=duration("20H")
y
返回:20H
typestr(y)
返回:DURATION
duration("3XNYS")
返回:3XNYS
不指定时间单位,取时间列 time 的单位 s:
t=table(take(2018.01.01T01:00:00+1..10,10) join take(2018.01.01T02:00:00+1..10,10) join take(2018.01.01T08:00:00+1..10,10) as time, rand(1.0, 30) as x);
select max(x) from t group by bar(time, 5);
bar_time
max_x
2018.01.01T01:00:00
0.8824
2018.01.01T01:00:05
0.8027
2018.01.01T01:00:10
0.572
2018.01.01T02:00:00
0.8875
2018.01.01T02:00:05
0.8542
2018.01.01T02:00:10
0.4287
2018.01.01T08:00:00
0.9294
2018.01.01T08:00:05
0.9804
2018.01.01T08:00:10
0.2147
指定单位为 m,对时间列按照1分钟进行分组:
select max(x) from t group by bar(time, 1m);
bar_time
max_x
2018.01.01T01:00:00
0.8824
2018.01.01T02:00:00
0.8875
2018.01.01T08:00:00
0.9804
FILE:references/doc_3451.md
# isYearStart
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isYearStart.html
**来源**: DolphinDB 官方文档
---
isYearStart
语法
isYearStart(X)
详情
判断
X
是否为年初第一天。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
返回值
布尔标量或向量。
例子
isYearStart(2012.01.01);
// output: true
isYearStart([2012.01.01,2012.02.01]);
// output: [true,false]
相关函数:
isYearEnd
FILE:references/doc_3453.md
# countNanInf
**URL**: https://docs.dolphindb.cn/zh/funcs/c/countNanInf.html
**来源**: DolphinDB 官方文档
---
countNanInf
语法
countNanInf(X, [includeNull=false])
详情
聚合函数,用于统计
X
中 NaN 或 Inf 值的数量。若
includeNull
设为 true,NULL 值也会被统计,默认为
false。
相关函数:
isNanInf
参数
X
是 DOUBLE 类型 的标量/向量/矩阵。
includeNull
是一个布尔值。
返回值
INT 类型标量。
FILE:references/doc_3459.md
# getMemLimitOfTaskGroupResult
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getMemLimitOfTaskGroupResult.html
**来源**: DolphinDB 官方文档
---
getMemLimitOfTaskGroupResult
语法
getMemLimitOfTaskGroupResult()
详情
获取当前节点发送的批量子查询占用的内存上限(单位为字节)。
参数
无
返回值
DOUBLE 类型标量。
例子
setMemLimitOfTaskGroupResult(10)
getMemLimitOfTaskGroupResult() / 1024 / 1024 / 1024
// output: 10
相关函数:
setMemLimitOfTaskGroupResult
FILE:references/doc_346.md
# keyedTable
**URL**: https://docs.dolphindb.cn/zh/funcs/k/keyedTable.html
**来源**: DolphinDB 官方文档
---
keyedTable
语法
keyedTable(keyColumns, X, [X1], [X2], .....)
或
keyedTable(keyColumns, capacity:size, colNames, colTypes)
或
keyedTable(keyColumns, table)
详情
创建键值内存表。一个键值内存表有一个主键。主键可由一个或多个字段组成。键值内存表基于哈希表实现,将主键字段的组合值存成一个键值,每个键值对应表中的一行数据。在查询时,指定主键的所有字段,便可通过键值定位数据,而无需进行全表扫描。
向表中添加新记录时,系统会自动检查新记录的主键值,如果新记录的主键值与已有记录的主键值重复时,系统会更新表中对应的记录,否则向表中添加记录。
键值表对单行的更新和查询效率很高,是数据缓存的理想选择。键值表也可作为时间序列聚合引擎的输出表,用于实时更新输出表的结果。
关于对键值内存表和
索引内存表
使用怎样的查询语句以及如何进行查询优化,详见下表:
keyedTable
indexedTable
查询优化
查询语句必须包含
keyColumns
所有列。
过滤条件中只能使用 =, in 或 and,且对不同列使用 in 的次数不超过2次;
建议调用
sliceByKey
以提高性能。
查询语句必须包含
keyColumns
的第 1 列,且该列过滤条件中只能使用 =, in 或
and;
除 keyColumns 的第 1 列外,其它列可以通过
between、比较运算符等进行范围查询,且查询效率高于使用 in 谓词。
所有过滤条件中,对不同列使用的 in 的次数不超过2次;
建议调用
sliceByKey
以提高性能。
查询语句特点
包含 keyColumns 的所有列。此时查询性能优于 indexedTable。
只需要包含
keyColumns
的第 1 列,而无需包含所有列。
参数
keyColumns
是一个字符串标量或向量,表示主键。主键的数据类型必须属于以下类别: INTEGRAL,
TEMPORAL 或 LITERAL。
第一种用法中,
X
,
X1
,
X2
...
可以是向量、数组向量、矩阵或元组。每个向量、元组、数组向量的长度,以及矩阵中每列长度都必须相同。
当 Xk 是元组时:
若 Xk 的元素是等长的向量,
元组的每个元素将作为表的一列。
元组的长度必须等于表的行数。
若 Xk 包含不同类型或不等长元素,
则将单独作为表的一列(列类型为 ANY),其每个元素将作为该列每行的元素值。
Xk
的长度仍然必须和表的行数保持一致。
第二种用法中:
capacity
是正整数,表示建表时系统为该表分配的内存(以记录数为单位)。当记录数超过
capacity
时,系统首先会分配
capacity
1.2~2倍的新的内存空间,然后复制数据到新的内存空间,最后释放原来的内存。对于规模较大的表,此类操作的内存占用会很高。因此,建议建表时预先分配一个合理的
capacity
。
size
是整数,表示该表新建时的行数。若
size
=0,创建一个空表。 若
size
>0,则建立一个只包含 size 条记录的表,记录初始值如下:
BOOL 类型默认值为 false;
数值类型、时间类型、IPADDR、COMPLEX、POINT 的默认值为 0;
Literal, INT128 类型的默认值为 NULL。
注:
如果
colTypes
指定为数组向量,
size
必须为0。
colNames
是一个向量,表示列名。
colTypes
是一个向量,表示每列的数据类型,允许主键外的其它列指定为数组向量类型或元组(ANY)类型。可使用表示数据类型的系统保留字或相应的字符串。
第三种用法中,
table
是一个表。注意,
table
中的
keyColumns
不能包含重复值。
返回值
一个表。
例子
例1. 创建键值表
第一种写法:
sym=`A`B`C`D`E
id=5 4 3 2 1
val=52 64 25 48 71
t=keyedTable(`sym`id,sym,id,val)
t;
sym
id
val
A
5
52
B
4
64
C
3
25
D
2
48
E
1
71
第二种写法:
t=keyedTable(`sym`id,1:0,`sym`id`val,[SYMBOL,INT,INT])
insert into t values(`A`B`C`D`E,5 4 3 2 1,52 64 25 48 71);
第三种写法:
tmp=table(sym, id, val)
t=keyedTable(`sym`id, tmp);
创建键值内存分区表:
sym=`A`B`C`D`E
id=5 4 3 2 1
val=52 64 25 48 71
t=keyedTable(`sym`id,sym,id,val)
db=database("",VALUE,sym)
pt=db.createPartitionedTable(t,`pt,`sym).append!(t);
例2. 更新键值表
t=keyedTable(`sym,1:0,`sym`datetime`price`qty,[SYMBOL,DATETIME,DOUBLE,DOUBLE])
insert into t values(`APPL`IBM`GOOG,2018.06.08T12:30:00 2018.06.08T12:30:00 2018.06.08T12:30:00,50.3 45.6 58.0,5200 4800 7800)
t;
sym
datetime
price
qty
APPL
2018.06.08T12:30:00
50.3
5200
IBM
2018.06.08T12:30:00
45.6
4800
GOOG
2018.06.08T12:30:00
58
7800
插入新记录,并且新记录中的主键值与表中主键值重复:
insert into t values(`APPL`IBM`GOOG,2018.06.08T12:30:01 2018.06.08T12:30:01 2018.06.08T12:30:01,65.8 45.2 78.6,5800 8700 4600)
t;
sym
datetime
price
qty
APPL
2018.06.08T12:30:01
65.8
5800
IBM
2018.06.08T12:30:01
45.2
8700
GOOG
2018.06.08T12:30:01
78.6
4600
插入新记录,并且新记录中的主键值重复:
insert into t values(`MSFT`MSFT,2018.06.08T12:30:01 2018.06.08T12:30:01,45.7 56.9,3600 4500)
t;
sym
datetime
price
qty
APPL
2018.06.08T12:30:01
65.8
5800
IBM
2018.06.08T12:30:01
45.2
8700
GOOG
2018.06.08T12:30:01
78.6
4600
MSFT
2018.06.08T12:30:01
56.9
4500
主键不允许更新:
update t set sym="C_"+sym;
// output: Can't update a key column.
例3. 查询键值内存表
当过滤条件不使用 or,包含所有
keyColumns
,并且每个条件都使用了等值谓词(=)或 in 谓词,且 in
谓词数量不超过两个时,键值内存表的查询性能优于普通内存表。
以下例子将比较键值内存表和普通内存表的查询性能。首先,分别创建包含100万条记录的普通内存表 t 和键值内存表 kt。
id=shuffle(1..1000000)
date=take(2012.06.01..2012.06.10, 1000000)
type=rand(9, 1000000)
val=rand(100.0, 1000000)
t=table(id, date, type, val)
kt=keyedTable(`id`date`type, id, date, type, val);
例3.1
timer(100) select * from t where id=500000, date=2012.06.01, type=0;
// output: Time elapsed: 161.574 ms
timer(100) select * from kt where id=500000, date=2012.06.01, type=0;
// output: Time elapsed: 1.483 ms
timer(100) sliceByKey(t1, (500000, 2012.06.01, 0))
// output: Time elapsed: 0.705 ms
例3.2
timer(100) select * from t where id in [1, 500000], date in 2012.06.01..2012.06.05, type=5;
// output: Time elapsed: 894.241 ms
timer(100) select * from kt where id in [1, 500000], date in 2012.06.01..2012.06.05, type=5;
// output: Time elapsed: 2.322 ms
in 谓词数量超过两个时,键值内存表不会进行查询优化:
例3.3
timer(100) select * from t where id in [1, 500000], date in 2012.06.01..2012.06.05, type in 1..5;
// output: Time elapsed: 801.347 ms
timer(100) select * from kt where id in [1, 500000], date in 2012.06.01..2012.06.05, type in 1..5;
// output: Time elapsed: 834.184 ms
若过滤条件没有包括所有
keyColumns
,键值内存表亦不会进行查询优化:
例3.4
timer(100) select * from t where id=500000, date in 2012.06.01..2012.06.05;
// output: Time elapsed: 177.113 ms
timer(100) select * from kt where id=500000, date in 2012.06.01..2012.06.05;
// output: Time elapsed: 163.265 ms
例4. 使用
keyedTable
保留每只股票卖方委托的最新五档报价。
sym=["a","b","c "]
time=22:58:52.827 22:58:53.627 22:58:53.827
volume=array(INT[]).append!([[100,110,120,115,125],[200,230,220,225,230],[320,300,310,315,310]])
price=array(DOUBLE[]).append!([[10.5,10.6,10.7,10.77,10.85],[8.6,8.7,8.76,8.83,8.9],[6.3,6.37,6.42,6.48,6.52]])
t=keyedTable(`sym,sym,time,volume,price)
t
sym
time
volume
price
a
22:58:52.827
[100, 110, 120, 115, 125]
[10.5, 10.6, 10.7, 10.77, 10.85]
b
22:58:53.627
[200, 230, 220, 225, 230]
[8.6, 8.7, 8.76, 8.83, 8.9]
c
22:58:53.827
[320, 300, 310, 315, 310]
[6.3, 6.37, 6.42, 6.48, 6.52]
//最新的报价数量和价格
newVolume=array(INT[]).append!([[130,110,110,115,120]])
newPrice= array(DOUBLE[]).append!([[10.55,10.57,10.62,10.68,10.5]])
//更新名为 a 的股票的最新报价
update t set volume=newVolume, price=newPrice where sym="a"
t
sym
time
volume
price
a
22:58:52.827
[130, 110, 110, 115, 120]
[10.55, 10.57, 10.62, 10.68, 10.5]
b
22:58:53.627
[200, 230, 220, 225, 230]
[8.6, 8.7, 8.76, 8.83, 8.9]
c
22:58:53.827
[320, 300, 310, 315, 310]
[6.3, 6.37, 6.42, 6.48, 6.52]
需要注意的是,更新 array vector
列的数据时,新记录中各行向量的元素个数必须和原记录中对应行向量的元素个数相同,否则会出现报错。如下例,新记录向量中有4个元素,而已有记录对应行的向量中有5个元素,数量不相同,出现报错:
newVolume=array(INT[]).append!([[130,110,110,120]])
newPrice= array(DOUBLE[]).append!([[10.55,10.57,10.62,10.5]])
update t set volume=newVolume, price=newPrice where sym="a"
// error: Failed to update column: volume
相关函数:
indexedTable
FILE:references/doc_3461.md
# symbol
**URL**: https://docs.dolphindb.cn/zh/funcs/s/symbol.html
**来源**: DolphinDB 官方文档
---
symbol
语法
symbol(X)
详情
把输入转换为一个符号向量。
参数
X
是字符串或符号的向量。
返回值
一个 SYMBOL 向量。
例子
x=`XOM`y;
typestr(x);
返回:STRING VECTOR
y=symbol(x);
y;
返回:["XOM","y"]
typestr(y);
返回:FAST SYMBOL VECTOR
FILE:references/doc_3462.md
# left join/left outer join
**URL**: https://docs.dolphindb.cn/zh/progr/sql/leftjoin.html
**来源**: DolphinDB 官方文档
---
left join/left outer join
语法
左连接
lj(leftTable, rightTable, matchingCols, [rightMatchingCols], [leftFilter], [rightFilter])
兼容SQL的左连接语法
select column_name(s)
from leftTable left [outer] join rightTable
on leftTable.matchingCol=rightTable.rightMatchingCol and [filter]
左半连接
lsj(leftTable, rightTable, matchingCols, [rightMatchingCols], [leftFilter], [rightFilter])
兼容SQL的左半连接语法
select column_name(s)
from leftTable left semijoin rightTable
on leftTable.matchingCol=rightTable.rightMatchingCol and [filter]
注意
:兼容 SQL 语法的 left join 与 left semijoin 不支持以下几点:
如果有多个连接列,必须使用 and 连接。
不能和 update 关键字一起使用。
若
leftTable
不是分布式表,则其
rightTable
也不能是分布式表。
参数
leftTable
和
rightTable
是连接的表。
matchingCols
是表示连接列的字符串标量或向量。
rightMatchingCols
是表示右表连接列的字符串标量或向量。当
leftTable
和
rightTable
至少有一个连接列不同时,必须指定
rightMatchingCols
。返回结果中的连接列与左表的连接列名称相同。
filter
为条件表达式,作为连接时的过滤条件。暂时只支持通过 and 连接多个过滤条件,不支持 or。
leftFilter
和
rightFilter
条件表达式,作为左右表字段的过滤条件。多个条件之间用 and 或 or
连接。
详情
左连接(lj)返回左表中所有与右表匹配的记录。如果右表中没有匹配的记录,将会返回NULL。如果右表中有多条匹配记录,将会返回所有的匹配记录。因此,lj返回结果的行数有可能比左表的行数多。
左半连接(lsj)和左连接(lj)的唯一区别是,如果右表中有多条匹配记录,lsj将会取第一条的匹配记录。因此,lsj返回结果的行数与左表的行数相等。
例子
例1. 两个表左连接,除了连接列之外没有其他相同列名:
t1= table(1 2 3 3 as id, 7.8 4.6 5.1 0.1 as value)
t2 = table(5 3 1 as id, 300 500 800 as qty);
t1;
id
value
1
7.8
2
4.6
3
5.1
3
0.1
t2;
id
qty
5
300
3
500
1
800
select id, value, qty from lj(t1, t2, `id);
//等价于 select id, value, qty from t1 left join t2 on t1.id=t2.id
id
value
qty
1
7.8
800
2
4.6
3
5.1
500
3
0.1
500
我们无需指定value和qty来自哪个表。系统首先会在左表中定位这两个列,如果左表没有这两个列,系统会在右表定位。
select id, value, qty from lj(t2, t1, `id);
//等价于 select id, value, qty from t2 left join t1 on t2.id=t1.id
id
value
qty
5
300
3
5.1
500
3
0.1
500
1
7.8
800
select id, value, qty from lsj(t2, t1, `id);
//等价于 select id, value, qty from t2 left semijoin t1 on t2.id=t1.id
id
value
qty
5
300
3
5.1
500
1
7.8
800
通过上面的例子,我们可以看到lj和lsj的区别。lj返回了右表中所有id=3的记录,lsj只返回了右表中第一条id=3的记录。
例2. 两个表左连接,它们具有相同列名,但是不作为连接列:
t1 = table(1 2 3 3 as id, 7.8 4.6 5.1 0.1 as value, 4 3 2 1 as x)
t2 = table(5 3 1 as id, 300 500 800 as qty, 44 66 88 as x);
t1;
id
value
x
1
7.8
4
2
4.6
3
3
5.1
2
3
0.1
1
t2;
id
qty
x
5
300
44
3
500
66
1
800
88
select id, value, qty, x from lj(t1, t2, `id);
//等价于 select id, value, qty, x from t1 left join t2 on t1.id=t2.id
id
value
qty
x
1
7.8
800
4
2
4.6
3
3
5.1
500
2
3
0.1
500
1
select id, value, qty, t2.x from lj(t1, t2, `id);
//等价于 select id, value, qty, t2.x from t1 left join t2 on t1.id=t2.id
id
value
qty
x
1
7.8
800
88
2
4.6
3
5.1
500
66
3
0.1
500
66
如果左表(t1)和右表(t2)有除连接列以外其他相同的字段名(x),我们从右表(t2)中选择字段名为x的数据时,需要指定x所在的表:t2.x。
lj(t1, t2, `id);
id
value
x
qty
t2_x
1
7.8
4
800
88
2
4.6
3
3
5.1
2
500
66
3
0.1
1
500
66
在上面的例子中,从t1和t2选择字段名为x的数据,并且把结果中t2的x字段重命名为t2_x。
例3. 多个连接列:
t1=table(1 1 2 2 3 3 as x, 1 2 2 3 3 4 as y, 1..6 as a);
t2=table(0 1 1 2 2 3 as x, 1 2 3 3 4 5 as y, 11..16 as b);
t1;
x
y
a
1
1
1
1
2
2
2
2
3
2
3
4
3
3
5
3
4
6
t2;
x
y
b
0
1
11
1
2
12
1
3
13
2
3
14
2
4
15
3
5
16
lj(t1, t2, `x`y);
// x, y是连接列
x
y
a
b
1
1
1
1
2
2
12
2
2
3
2
3
4
14
3
3
5
3
4
6
t2.rename!(`x`y, `x2`y2);
x2
y2
b
0
1
11
1
2
12
1
3
13
2
3
14
2
4
15
3
5
16
lj(t1, t2, `x`y, `x2`y2);
// t1.x, t1.y t2.x2, t2.y2是连接列
x
y
a
b
1
1
1
1
2
2
12
2
2
3
2
3
4
14
3
3
5
3
4
6
例4. 指定过滤条件
t1= table(1 2 3 3 as id1, 7.8 4.6 5.1 0.1 as value)
t2 = table(5 3 1 as id2, 300 500 800 as qty);
select * from lj(t1, t2, `id1, `id2, t1.value>1 and t1.value<6, t2.qty>300)
id1
value
qty
1
7.8
2
4.6
3
5.1
500
3
0.1
t1= table(1 2 3 3 6 8 as id, 7.8 4.6 5.1 0.1 0.5 1.2 as value)
t2 = table(5 3 1 2 6 8 as id, 300 500 800 400 600 700 as qty);
select * from t1 left join t2 on t1.id=t2.id and t2.qty>=550
id
value
qty
1
7.8
800
2
4.6
3
5.1
3
0.1
6
0.5
600
8
1.2
700
FILE:references/doc_3466.md
# corrMatrix
**URL**: https://docs.dolphindb.cn/zh/funcs/c/corrMatrix.html
**来源**: DolphinDB 官方文档
---
corrMatrix
语法
corrMatrix(X)
详情
设矩阵
X
有 n 列,将其每一列作为一维向量,求 n 维向量的相关矩阵(correlation matrix)。
注:
如果矩阵中含有空值,会默认将空值转化为0,然后进行计算。而由于
corr
函数计算时忽略 NULL 值,因此调用
cross/pcross(corr, X)
函数计算相关矩阵时也会忽略 NULL 值。
在不含 NULL 值的情况下,虽然该函数计算结果等价于
cross(corr,
X)
,但该函数内部进行了优化,其性能较
cross/pcross(corr, X)
函数有大幅提升。
参数
X
是一个矩阵。
返回值
DOUBLE 类型矩阵。
例子
m = rand(10.0, 30)$10:3
corrMatrix(m)
输出返回:
#0
#1
#2
1
0.167257129736134
0.224955585716037
0.167257129736134
1
-0.12066768907057
0.224955585716037
-0.12066768907057
1
a = rand(1.0, 30000000).reshape(10000:3000)
a.rename!("s" + string(1..3000))
timer corrMatrix(a)
输出返回:Time elapsed: 2986.932 ms
timer pcross(corr, a)
输出返回:Time elapsed: 45629.6 ms
相关函数:
covarMatrix
FILE:references/doc_3475.md
# scramClientFinal
**URL**: https://docs.dolphindb.cn/zh/funcs/s/scramClientFinal.html
**来源**: DolphinDB 官方文档
---
scramClientFinal
语法
scramClientFinal(user, combinedNonce, clientProof)
详情
scramClientFinal
是 SCRAM 认证过程的第二阶段服务端函数。该函数验证客户端提供的凭证及
combined_nonce 有效性。
注:
SCRAM 完整认证流程如下所示:
1. 客户端发起认证请求
生成一个客户端 nonce(一次性随机值),然后将其与用户名一起发给服务端。
2. 服务端响应认证请求
服务端收到信息后,通过
scramClientFirst
函数生成用于加密的哈希盐值、密码哈希的迭代次数,并生成 nonce
与客户端 nonce 拼接,然后将这些信息返回给客户端。
3. 客户端生成认证凭证,然后再次提交认证请求
客户端根据收到的信息将明文密码转化为密钥,最终生成客户端凭证,然后向服务端提交带凭证的认证请求。
4. 服务端验证认证请求
服务端收到请求后,通过
scramClientFinal
对拼接后的 nonce
以及客户端凭证进行验证。若验证成功,返回服务端签名发送给客户端。
5. 客户端验证服务端签名
客户端对服务端返回的签名进行认证。若签名验证通过,则用户登录成功;若不通过,则断开会话连接。
参数
user
是表示用户名的字符串。它只能包含字母、下划线或数字,并且它不能以数字开头。长度不能超过30个字符。
combinedNonce
客户端 nonce 和服务器端 nonce 的 base64 编码组合,即
scramClientFirst
函数在此前返回的 combined_nonce
字段。
clientProof
客户端生成的凭证,base64 编码。
返回值
返回 Base64 编码的服务端签名。
例子
以下脚本是一个完整的示例,展示了如何在 Python 客户端完成用户(”user01”)SCRAM 模式登录,其中服务端的操作通过 DolphinDB Python
API 的相关接口实现(详见
Python API
手册
)。
import dolphindb as ddb
# 建立与 DolphinDB 的会话连接
s = ddb.session("183.134.101.133", 8888)
s.run("print", 1, 2, 3)
##########################
import hashlib
import hmac
import os
import base64
import hashlib
# ------------------ 服务端函数 ------------------
def server_handle_client_first(username, client_nonce):
"""处理第一次认证请求,返回 salt、迭代次数和合并后的 nonce"""
salt, iter_count, nonce = s.run("scramClientFirst", username, client_nonce)
return {
"salt": salt,
"iteration_count": iter_count,
"combined_nonce": nonce
}
def server_handle_client_final(user, combined_nonce, client_proof):
"""处理最终认证请求,验证 client_proof,返回 server_signature"""
return s.run("scramClientFinal", user, combined_nonce, client_proof)
# ------------------ 客户端函数 ------------------
def client_initiate_authentication(username):
"""客户端发起认证,生成 client_nonce"""
client_nonce = base64.b64encode(os.urandom(16)).decode()
return {
"username": username,
"client_nonce": client_nonce
}
def client_generate_proof(user, password, salt, iteration_count, cnonce, combined_nonce):
"""生成 client_proof"""
# 计算SaltedPassword
salted_password = hashlib.pbkdf2_hmac(
'sha256',
password.encode(),
base64.b64decode(salt),
iteration_count
)
# 生成密钥
client_key = hmac.new(salted_password, b"Client Key", hashlib.sha256).digest()
stored_key = hashlib.sha256(client_key).digest()
server_key = hmac.new(salted_password, b"Server Key", hashlib.sha256).digest()
# 构造AuthMessage
auth_message = (
f"n={user},r={cnonce}," # client-first-bare
f"r={combined_nonce},s={salt},i={iteration_count}," # server-first
f"c=biws,r={combined_nonce}" # client-final-without-proof
)
# 计算ClientProof
client_signature = hmac.new(stored_key, auth_message.encode(), hashlib.sha256).digest()
client_proof = bytes([ck ^ cs for ck, cs in zip(client_key, client_signature)])
return {
"client_proof": base64.b64encode(client_proof).decode(),
"server_key": server_key,
"auth_message": auth_message
}
# ------------------ SCRAM 模式登录 ------------------
if __name__ == "__main__":
# 客户端发起认证
client_data = client_initiate_authentication("user01")
# 服务端处理首次请求
server_response = server_handle_client_first(
client_data["username"],
client_data["client_nonce"]
)
password = "123456"
# 客户端生成证明
client_proof_data = client_generate_proof(
"user01",
password,
server_response["salt"],
server_response["iteration_count"],
client_data["client_nonce"],
server_response["combined_nonce"]
)
# 服务端验证并返回签名
# auth_sessions[server_response["combined_nonce"]]["auth_message"] = client_proof_data["auth_message"]
server_signature = server_handle_client_final(
"user01",
server_response["combined_nonce"],
client_proof_data["client_proof"]
)
# 客户端验证服务端签名
computed_server_sig = hmac.new(
client_proof_data["server_key"],
client_proof_data["auth_message"].encode(),
hashlib.sha256
).digest()
# 若匹配则认证成功
assert server_signature == base64.b64encode(computed_server_sig).decode()
print("SCRAM authentication succeeded!")
# 查看当前会话与用户
print(s.run("getCurrentSessionAndUser()"))
FILE:references/doc_3500.md
# 流计算引擎
**URL**: https://docs.dolphindb.cn/zh/funcs/themes/streamingEngine.html
**来源**: DolphinDB 官方文档
---
流计算引擎
在流数据处理中,要求持续高效地进行实时计算。为此,DolphinDB
研发了适合流计算场景的多种引擎,采用增量计算,提高实时计算的性能。流计算引擎的计算结果可以输出到共享内存表、流数据表、消息中间件、数据库、API
等终端,以做进一步的处理。计算复杂表达式时,亦可将多个流数据引擎通过级联的方式合并成一个复杂的数据流拓扑。
本节将介绍 DolphinDB 单数据源的流计算引擎。
FILE:references/doc_3503.md
# resetDBDirMeta
**URL**: https://docs.dolphindb.cn/zh/funcs/r/resetDBDirMeta.html
**来源**: DolphinDB 官方文档
---
resetDBDirMeta
语法
resetDBDirMeta(dbDir)
详情
跨磁盘卷转移元数据时, 由于元数据中包含了 DATABASE 存储路径相关的信息,所以转移元数据前,必须调用
resetDBDirMeta
修改元数据中 DATABASE 存储的路径为目的路径。该命令只能在数据节点上执行。
请注意:
只能在同一个数据节点上进行跨磁盘卷转移元数据的操作。
进行该操作前,需要停止写入,保证所有事务都已完成,并将所有缓冲区的数据刷入磁盘。
假设将 metalog 目录 从 volumeA 转移至 volumeB,完整过程如下:
执行命令 resetDBDirMeta('volumeB/DATABASE') 后关闭 server。
手动拷贝 volumeA 下的目录 CHUNK_METADATA, DATABASE, IOTRAN_TYPE 和 LOG 到 volumeB。
删除 volumeA 下的目录 CHUNK_METADATA,DATABASE,IOTRAN_TYPE 和 LOG。
修改配置
chunkMetaDir
= volumeB/CHUNK_METADATA 后启动 server。
首发版本
:2.00.4
参数
dbDir
是一个字符串,格式如:"volumeB/DATABASE"。表示 DATABASE 将要转移到的目的路径。
FILE:references/doc_3507.md
# varp
**URL**: https://docs.dolphindb.cn/zh/funcs/v/varp.html
**来源**: DolphinDB 官方文档
---
varp
语法
varp(X)
详情
若
X
为向量,返回
X
的总体方差。
若
X
为矩阵,计算每列的总体方差,返回一个向量。
若
X
为表,计算每列的总体方差,返回一个表。
与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
可以是向量、矩阵或表。
返回值
DOUBLE 类型标量/向量/表。
例子
varp(1 1 1);
// output
0
varp(1 2 3);
// output
0.666667
m=matrix(1 3 5 7 9, 1 4 7 10 13);
m;
#0
#1
1
1
3
4
5
7
7
10
9
13
varp(m);
// output
[8,18]
相关函数:
cumvarp
FILE:references/doc_3518.md
# getInstrumentFarExpiry
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentfarexpiry.html
**来源**: DolphinDB 官方文档
---
getInstrumentFarExpiry
语法
getInstrumentFarExpiry(instrument)
详情
根据输入的金融工具,获取该工具的远端到期日(far expiry date)。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DATE 类型标量或向量。
例子
swap = {
"productType": "Swap",
"swapType": "FxSwap",
"version": 0,
"currencyPair": "EURUSD",
"direction": "Buy",
"notional": ["EUR", 1E6],
"nearStrike": 1.1,
"nearExpiry": 2025.12.08,
"nearDelivery": 2025.12.10,
"farStrike": 1.2,
"farExpiry": 2026.06.08,
"farDelivery": 2026.06.10
}
ins = parseInstrument(swap)
getInstrumentFarExpiry(ins)
// output: 2026.06.08
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_3525.md
# getSupportBundle
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getSupportBundle.html
**来源**: DolphinDB 官方文档
---
getSupportBundle
语法
getSupportBundle([dir])
详情
生成一个包含所有配置信息的文件,并返回文件路径。该函数只能在数据节点/计算节点调用。
配置文件包含以下信息:
模块名
含义
信息来源
VERSION
server 的版本信息。
version()
CONFIGS
配置信息。单机环境下,返回单节点的配置信息;集群环境下,包含集群、控制节点、
和数据节点/计算节点的配置。
单机: dolphindb.cfg 集群: cluster.cfg, cluster.nodes,
controller.cfg
DB AND TABLE SCHEMA
所有数据库和表的结构。
schema
LICENSE AND MACHINE INFO
license、机器核数和内存信息。 节点绑定的 CPU 内核绑定和端口信息。
许可证: dolphindb.lic
OLAP CACHE ENGINE STATUS
OLAP 引擎 cache Engine
的状态信息,包含各节点的内存信息以及当前节点的状态表。
pnodeRun(getOLAPCacheEngineSize)
pnodeRun(getOLAPCacheEngineStat)
TSDB META
TSDB 引擎下所有 chunk 的元数据。
pnodeRun(getTSDBMetaData)
REDO LOG GC STATUS
事务 redo log 回收的状态。
pnodeRun(getRedoLogGCStat)
TRANSACTION STATUS
事务的状态。
pnodeRun(getTransactionStatus)
TABLETS META
集群中行数最多的前100个 chunk 的元数据信息。
select top 100 * from pnodeRun(getTable
tsMeta{“%”,”%”,false,-1}) order by rowNum desc
ANOMALOUS CHUNK STATUS (only in cluster
mode)
处于异常状态的 chunk 信息。异常状态包含处于 recovery 状态,版本号不一致,
副本数不一致等。
getClusterChunksStatus()
参数
dir
可选参数,用于指定存储路径。若不指定该参数,单节点环境下默认存储至 <HomeDir>(可通过
getHomeDir
查看
<HomeDir>);集群环境下默认存储至 <HomeDir> 同级目录。
返回值
字符串标量。
例子
getSupportBundle()
// output
/home/dolphindb/server/getSupportBundle.1655869793424
getSupportBundle("/home/dolphindb/sup")
// output
/home/dolphindb/sup/getSupportBundle.1655869853178
FILE:references/doc_3528.md
# publishMCPTools
**URL**: https://docs.dolphindb.cn/zh/funcs/p/publishMCPTools.html
**来源**: DolphinDB 官方文档
---
publishMCPTools
语法
publishMCPTools([names])
详情
发布 MCP tool 。
参数
names
可选参数,STRING 类型标量或向量,表示 tool 的名称。
返回值
STRING 类型向量,表示发布成功的 tool 名称。
例子
publishMCPTools("myTool")
FILE:references/doc_3531.md
# publishMCPPrompts
**URL**: https://docs.dolphindb.cn/zh/funcs/p/publishMCPPrompts.html
**来源**: DolphinDB 官方文档
---
publishMCPPrompts
语法
publishMCPPrompts([names])
详情
发布 MCP prompt 模板。
参数
names
可选参数,STRING 类型标量或向量,表示 prompt 模板的名称。
返回值
STRING 类型向量,表示发布成功的 prompt 模板名称。
例子
publishMCPPrompts("stock_summary")
// output:["stock_summary"]
FILE:references/doc_3533.md
# spline
**URL**: https://docs.dolphindb.cn/zh/funcs/s/spline.html
**来源**: DolphinDB 官方文档
---
spline
语法
spline(X, Y, resampleRule, [closed='left'], [origin='start_day'],
[outputX=false])
详情
该函数根据
resampleRule
,
closed
,
origin
确定的采样规则,对
X
进行重采样操作。并根据重采样后的
X
,对
Y
进行三次样条插值(Cubic Spline
Interpolation)。
参数
X
严格递增的时间类型向量。
Y
同
X
等长的数值型向量。
resampleRule
一个字符串,可选值请参考
resample
的
rule
参数。
closed
和
origin
同
resample
的
closed
和
origin
参数。
outputX
布尔类型,表示是否输出
X
按照
resampleRule
,
closed
,
origin
重采样后的向量。默认值为 false。
返回值
若不指定
outputX
,仅返回一个对
Y
插值后的向量。若指定
outputX
=
true,则返回一个 tuple,其第一个元素为
X
重采样后的向量,第二个元素为对
Y
插值后的向量。
例子
spline([2016.02.14 00:00:00, 2016.02.15 00:00:00, 2016.02.16 00:00:00], [1.0, 2.0, 4.0], resampleRule=`60min);
// output
[1,1.0313,1.0626,1.0942,1.1262,1.1585,1.1914,1.225,1.2593,1.2944,1.3306,1.3678,1.4062,1.446,1.4871,1.5298,1.5741,1.6201,1.668,1.7178
,1.7697,1.8237,1.8801,1.9388,2,2.0638,2.1301,2.1987,2.2697,2.3428,2.418,2.4951,2.5741,2.6548,2.7371,2.821,2.9062,2.9928,3.0806,3.1694
,3.2593,3.35,3.4414,3.5335,3.6262,3.7192,3.8126,3.9063,4]
FILE:references/doc_354.md
# getStreamTableCacheOffset
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getstreamtablecacheoffset.html
**来源**: DolphinDB 官方文档
---
getStreamTableCacheOffset
语法
getStreamTableCacheOffset(streamTable)
详情
查看指定的流表在内存中的最旧的记录相较于流表已写入的总记录数的偏移量(offset),即总记录数减去内存中数据行的值。
参数
streamTable
是一个自动清理的非持久化流表,即由
enableTableShareAndCachePurge
创建的流表,或由
enableTableCachePurge
设置后的流表。
返回值
整型标量。
例子
t = streamTable(1000:0, `time`sym`volume, [DATETIME, SYMBOL, INT])
enableTableShareAndCachePurge(table=t, tableName=`st, cachePurgeTimeColumn=`time,
cachePurgeInterval=30m, cacheRetentionTime=20m)
time = datetime(2024.01.01T09:00:00) +1..1000*2
sym=take(`a`b`c, 1000)
volume = rand(10,1000)
insert into t values([time, sym, volume])
getStreamTableCacheOffset(t)
//0
time = datetime(2024.01.01T09:35:00) +1..1000*2
sym=take(`a`b`c, 1000)
volume = rand(10,1000)
insert into t values([time, sym, volume])
getStreamTableCacheOffset(t)
//999
FILE:references/doc_3540.md
# microsecond
**URL**: https://docs.dolphindb.cn/zh/funcs/m/microsecond.html
**来源**: DolphinDB 官方文档
---
microsecond
语法
microsecond(X)
详情
返回
X
中的微秒数。
参数
X
可以是 TIME, TIMESTAMP, NANOTIME 或 NANOTIMESTAMP
类型的标量或向量。
返回值
整型标量或向量。
例子
microsecond(13:30:10.008);
// output: 8000
microsecond([2012.12.03 01:22:01.999999000, 2012.12.03 01:22:01.000456000, 2012.12.03 01:25:08.000000234]);
// output: [999999,456,0]
相关函数:
dayOfYear
,
dayOfMonth
,
quarterOfYear
,
monthOfYear
,
weekOfYear
,
hourOfDay
,
minuteOfHour
,
secondOfMinute
,
millisecond
,
nanosecond
FILE:references/doc_3544.md
# 实时检测传感器状态变化
**URL**: https://docs.dolphindb.cn/zh/tutorials/ddb_str_app_iot.html
**来源**: DolphinDB 官方文档
---
实时检测传感器状态变化
工业物联网领域,能否对从传感器采集到的包括湿度、温度、压力、液位、流速等多方面的海量数据进行快速的实时处理,对各种工业智能制造应用至关重要。DolphinDB 提供了流数据表 (stream table) 和流计算引擎用于实时数据处理,助力智能制造。
DolphinDB 流计算引擎实现传感器数据异常检测
一文介绍了怎么用内置的异常检测引擎 (Anomaly Detection Engine) 和自定义计算引擎实现异常检测的需求。目前 DolphinDB 内置了更多的计算引擎,本文将介绍如何用响应式状态引擎和会话窗口引擎实现传感器状态变化的实时监测。
1. 应用需求
假定有一个监控系统,对所有传感器每 5 秒钟采集 1 次数据,并将采集后的数据以 json 格式写入 mqtt 服务器,典型样本数据如下所示:
tag ts value
motor.C17156B.m1 2022.11.05T15:32:02.750 1
motor.C17156C.m1 2022.11.05T15:32:05.265 2
motor.C17156G.m146 2022.11.05T15:32:05.734 0
motor.C17156B.m1 2022.11.05T15:32:07.750 1
motor.C17156C.m1 2022.11.05T15:32:10.265 2
motor.C17156G.m146 2022.11.05T15:32:10.734 0
motor.C17156B.m1 2022.11.05T15:32:12.750 1
motor.C17156C.m1 2022.11.05T15:32:15.265 2
motor.C17156G.m146 2022.11.05T15:32:15.734 0
motor.C17156B.m1 2022.11.05T15:32:17.750 1
其中 tag 是传感器标签,ts 是采集时间戳,value 是设备测量值,取值范围是 0~4,分别表示设备的 5 种状态(0 表示待运行,1 表示运行,2 表示节能,3 表示阻塞,4 表示过载)。现有以下实时检测需求:
传感器状态变化监控:当监测到当前记录的传感器测量值与该传感器前一条记录的测量值不一样,即状态有变化时,输出这条记录,若不变就丢弃这条记录。
传感器数据丢失告警:若传感器数据丢失,即 30 秒钟内某个传感器没有采集到数据,系统告警。报警方式为,在侦测到传感器数据采集异常后,向一个流数据表中写一条记录。
2. 实验环境准备
实验环境配置如下:
服务器环境
CPU 类型:Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
逻辑 CPU 总数:4
内存:32 GB
OS:64 位 Ubuntu 20.04
DolphinDB server 部署
server 版本:2.00.8 Linux 64 JIT,社区版
部署模式:单节点模式
DolphinDB GUI:1.30.14 版本
MQTT 服务器:
mosquitto-2.0.15
3. 设计思路
DolphinDB 的流计算框架目前已提供时序聚合引擎、横截面聚合引擎、异常检测引擎、会话窗口引擎和响应式状态引擎等 10 余种计算引擎应对不同计算场景。本文主要介绍如何用响应式状态引擎和会话窗口引擎实现传感器状态变化的实时监测。
会话窗口引擎
会话窗口可以理解为一个活动阶段(数据产生阶段),其前后都是非活动阶段(无数据产生阶段)。会话窗口引擎与时间序列引擎极为相似,它们计算规则和触发计算的方式相同。不同之处在于时间序列引擎具有固定的窗口长度和滑动步长,但会话窗口引擎的窗口不是按照固定的频率产生的,其窗口长度也不是固定的。会话窗口引擎以引擎收到的第一条数据的时间戳作为第一个会话窗口的起始时间。会话窗口收到某条数据之后,若在指定的等待时间内仍未收到下一条新数据,则(该数据的时间戳 + 等待时间)是该窗口的结束时间。窗口结束后收到的第一条新数据的时间戳是新的会话窗口的起始时间。
响应式状态引擎
DolphinDB 流数据引擎所计算的因子可分为无状态因子与有状态因子。无状态因子仅根据最新一条数据即可完成计算,不需要之前的数据,亦不依赖之前的计算结果。有状态因子计算除需要最新的数据,还需要历史数据或之前计算得到的中间结果,统称为状态。因此有状态因子计算需要存储状态,以供后续因子计算使用,且每次计算都会更新状态。响应式状态引擎每输入一条数据都将触发一条结果输出,因此输入和输出数据量一致。响应式状态引擎的算子中只能包含向量函数,DolphinDB 针对生产业务中的常见状态算子(滑动窗口函数、累积函数、序列相关函数和 topN 相关函数等)进行了优化,大幅提升了这些算子在响应式状态引擎中的计算效率。
对于第一个需求即传感器状态变化,可使用响应式状态引擎。响应式状态引擎可以设置过滤条件,通过过滤条件判断当前记录的状态值与前一条记录相同,只有符合过滤条件的结果才被输出。
对于第二个需求即检测是否有数据丢失,可使用会话窗口引擎。对于每个传感器,会话窗口收到该传感器某条数据之后,若在 30 秒内仍未收到该传感器的下一条新数据,则认为该窗口结束,输出报警。
4. 实现步骤
4.1. 定义输入输出流数据表
首先,定义一个流数据表用于接收实时采集的传感器数据,表结构包含三列,即标签 tag、时间 ts 和标签值 value。通过
enableTableShareAndPersistence
函数共享流数据表并持久化到硬盘上。通过
cacheSize
参数将内存中可保存的最大数据量设定为 10 万行。代码如下:
stream01=streamTable(100000:0,`tag`ts`value,[SYMBOL,TIMESTAMP, INT])
enableTableShareAndPersistence(table=stream01,tableName=`inputSt,asynWrite=false,compress=true, cacheSize=100000)
其次,定义响应式状态引擎的输出表。引擎的输出表可以是内存表或分布式表。本文定义如下所示流数据表 outputSt1 为满足第一个需求的跟踪状态变化的输出表,并参考
createReactiveStateEngine
各参数的设置说明完成对输出表的定义。根据
keyColumn
(分组列)的设置,输出表的前几列必须和
keyColumn
设置的列及其顺序保持一致,后面是计算结果列。本例的
keyColumn
为 tag,计算结果列为 ts 和 value,与输入表一致。建表代码如下:
out1 =streamTable(10000:0,`tag`ts`value,[SYMBOL,TIMESTAMP, INT])
enableTableShareAndPersistence(table=out1,tableName=`outputSt1,asynWrite=false,compress=true, cacheSize=100000)
最后,定义用于告警信息输出的流数据表 outputSt2,以满足第二个场景需求。参考
createSessionWindowEngine
各参数的设置说明完成对输出表的定义。它的第一列必须是时间类型,其时间为各个窗口的起始时刻或者结束时刻。如果
keyColumn
(分组列)参数不为空,则其后几列和
keyColumn
设置的列及其顺序保持一致。最后为计算结果列,可为多列,在本例中,仅记录丢失数据前最后一条记录的标签测量值。建表代码如下:
out2 =streamTable(10000:0,`ts`tag`lastValue,[TIMESTAMP,SYMBOL, INT])
enableTableShareAndPersistence(table=out2,tableName=`outputSt2,asynWrite=false,compress=true, cacheSize=100000)
4.2. 创建响应式状态引擎实现传感器状态变化实时监测
响应式状态引擎中,设置分组列(keyColumn)为传感器标签 tag,2 个计算指标为
ts 和 value
,表示原样输出。需要注意的是
filter
参数的设置:
<value!=prev(value) && prev(value)!=NULL>
,这里以元代码的形式表示过滤条件。只有符合过滤条件的结果,即 value 值与该分组的上一个 value 值不相同才会被输出到通过
outputTable
设置的输出表,其中
prev(value)!=NULL
表示不输出每个分组的第一条记录。参考
createReactiveStateEngine
页面内容完成对其他参数的设置。代码如下:
reactivEngine = createReactiveStateEngine(name=`reactivEngine, metrics=<[ts, value]>, dummyTable=stream01,
outputTable= outputSt2,keyColumn= "tag",filter=<value!=prev(value) && prev(value)!=NULL>)
4.3. 创建会话窗口引擎实现传感器丢失数据实时报警
会话窗口引擎中,设置
keyColumn
(分组列)为传感器标签 tag,
timeColumn
(时间列)为 ts。检测需求是 30 秒内无数据,所以
sessionGap
为 30000(单位为毫秒,同 ts 列),表示收到某条数据后经过该时间的等待仍无新数据到来,就终止当前窗口。设置
useSessionStartTime
为 false,表示输出表中的时刻为数据窗口结束时刻,即每个窗口中最后一条数据的时刻 +
sessionGap
。并对
createSessionWindowEngine
完成对其他参数的设置。代码如下:
swEngine = createSessionWindowEngine(name = "swEngine", sessionGap = 30000, metrics = < last(value)>,
dummyTable = stream01, outputTable = outputSt1, timeColumn = `ts, keyColumn=`tag,useSessionStartTime=false)
4.4. 订阅流数据
本例定义了 handler 处理函数
process
,把收到的流数据分别写入上述会话窗口引擎和响应式状态引擎,代码如下:
def process(mutable engine1,mutable engine2,msg){
engine1.append!(msg)
engine2.append!(msg)
}
subscribeTable(tableName="inputSt", actionName="monitor", offset=0,
handler=process{swEngine,reactivEngine}, msgAsTable=true)
注意:
本例没启用快照(snapshot)机制。为了满足生产环境业务持续性的需要,DolphinDB 内置的流式计算引擎包括会话窗口引擎、响应式状态引擎均支持快照输出。若需要启用快照机制,则引擎创建时需要指定两个额外的参数
snapshotDir
和
snapshotIntervalInMsgCount
。
snapshotDir
用于指定存储快照的目录。
snapshotIntervalInMsgCount
指定处理多少条消息后产生一个快照。此外,引擎启用快照机制,调用
subscribeTable
函数订阅流数据也需相应的修改:
首先,必须指定消息的 offset。
其次,handler 必须使用
appendMsg
函数。
appendMsg
函数接受两个参数,
msgBody
和
msgId
。
再次,参数
handlerNeedMsgId
必须指定为 true。
更详细的说明请参阅
流数据教程
或会话窗口引擎、响应式状态引擎的说明。
若设备极多,数据采集频率很高,可能需要处理大量消息。这时可在 DolphinDB 消息订阅函数
subscribeTable
中指定可选参数
filter
与
hash
,让多个订阅客户端并行处理消息。相关详细说明请参阅
流数据教程
或
subscribeTable
和
setStreamTableFilterColumn
的说明。
4.5. 从 MQTT 服务器接收数据
DolphinDB 提供了
MQTT
插件用于订阅 MQTT 服务器的数据。DolphinDB server 2.00.8 linux 64 JIT 版本已包含 MQTT 插件在 server/plugins/mqtt 目录下,不用下载插件即可直接加载使用。用户可以使用
mqtt::subscribe
从 MQTT 服务器订阅数据,在订阅时需要数据格式解析函数,目前插件提供了 json 和 csv 格式的解析函数,本例使用
mqtt::createJsonParser
解析 json 格式数据。示例代码如下:
loadPlugin(getHomeDir()+"/plugins/mqtt/PluginMQTTClient.txt")// 也可用 preloadModules=plugins::mqtt 自动加载
go
sp = mqtt::createJsonParser([SYMBOL,TIMESTAMP, INT], `tag`ts`value)
mqtt::subscribe(host, port, topic, sp, inputSt)
5. 模拟写入与验证
附录中的样本文件包含了 46 个 tag 的约 18 分钟的数据,共 9985 条记录,下列代码可把样本文件中的数据推送并写入 MQTT 服务器:
t=loadText(getHomeDir()+"/deviceState.csv")// 加载样本文件到内存,目录需根据实际情况修改
f = createJsonFormatter()//json 格式打包函数
batchsize=100 // 每批打包 100 行记录发往 MQTT 服务器
submitJob("submit_pub1", "submit_p1", publishTableData{host,topic,f, batchsize,t})
运行后,outputSt1 产生 409 条记录,用下列代码可验证结果是否正确:
t=loadText(getHomeDir()+"/deviceState.csv")
t1=select tag,ts,value from t context by tag having deltas(value)!=0 and prev(value)!=NULL
t2=select * from outputSt1 order by tag
assert eqObj(t1.values(),t2.values())==true
outputSt2 产生如下所示 2 条记录:
ts tag lastValue
2022.11.05T15:45:37.750 motor.C17156B.m1 2
2022.11.05T15:49:52.750 motor.C17156B.m1 0
通过下列示例代码可发现样本中有 2 次丢了 30 秒以上的数据:
t=loadText(getHomeDir()+"/deviceState.csv")
select tag,ts,prev(ts),deltas(ts) from t context by tag having deltas(ts)>30000
执行后结果:
tag ts prev_ts deltas_ts
motor.C17156B.m1 2022.11.05T15:45:47.750 2022.11.05T15:45:07.750 40,000
motor.C17156B.m1 2022.11.05T15:50:07.750 2022.11.05T15:49:22.750 45,000
告警都在 prev_ts 30 秒后发生,符合预期。
注意:为简化调试,也可不经过 MQTT 服务器和插件,直接通过回放的方式写入流数据表,回放的示例代码如下供参考:
t=loadText(getHomeDir()+"/deviceState.csv")
replay(t, inputSt, `ts, `ts)
本文中使用的代码样例可见于附件中的 deviceState.txt。
6. 附录
样本文件:
deviceState.csv
案例代码:
deviceState.txt
FILE:references/doc_355.md
# streamTable
**URL**: https://docs.dolphindb.cn/zh/funcs/s/streamTable.html
**来源**: DolphinDB 官方文档
---
streamTable
语法
streamTable(X, [X1], [X2], .....)
或
streamTable(capacity:size, colNames, colTypes)
详情
创建
流数据表
。流数据表可处理并发的读写操作。
参数
第一种用法中,
X
,
X1
,
X2
...
可以是向量、数组向量、矩阵或元组。每个向量、元组、数组向量的长度,以及矩阵中每列长度都必须相同。
当 Xk 是元组时:
若 Xk 的元素是等长的向量,
元组的每个元素将作为表的一列。
元组的长度必须等于表的行数。
若 Xk 包含不同类型或不等长元素,
则将单独作为表的一列(列类型为 ANY),其每个元素将作为该列每行的元素值。
Xk
的长度仍然必须和表的行数保持一致。
第二种用法中:
capacity
是正整数,表示建表时系统为该表分配的内存(以记录数为单位)。当记录数超过
capacity
时,系统首先会分配
capacity
1.2~2倍的新的内存空间,然后复制数据到新的内存空间,最后释放原来的内存。对于规模较大的表,此类操作的内存占用会很高。因此,建议建表时预先分配一个合理的
capacity
。
size
是整数,表示该表新建时的行数。若
size
=0,创建一个空表。 若
size
>0,则建立一个只包含 size 条记录的表,记录初始值如下:
BOOL 类型默认值为 false;
数值类型、时间类型、IPADDR、COMPLEX、POINT 的默认值为 0;
Literal, INT128 类型的默认值为 NULL。
注:
如果
colTypes
指定为数组向量,
size
必须为0。
colNames
是一个向量,表示列名。
colTypes
是一个向量,表示每列的数据类型,支持数组向量类型和元组(ANY)类型。可使用表示数据类型的系统保留字或相应的字符串。
返回值
一个流表对象。
例子
id=`XOM`GS`AAPL
x=102.1 33.4 73.6
rt=streamTable(id, x);
rt=streamTable(`XOM`GS`AAPL as id, 102.1 33.4 73.6 as x);
colName=["Name","Age"]
colType=["string","int"]
rt=streamTable(100:10, colName, colType);
FILE:references/doc_3568.md
# or
**URL**: https://docs.dolphindb.cn/zh/funcs/o/or.html
**来源**: DolphinDB 官方文档
---
or
语法
or(X, Y)
或
X||Y
详情
按元素逐个返回
X
逻辑或
(OR)Y
的结果。
注意:若
or
或
||
的操作数包含 NULL 时,||
返回的对应结果为 NULL,而
or
针对不同 server 版本,返回的结果不同。
对于小于 2.00.9.4 的版本,
or
返回的对应结果为 NULL。
对于 2.00.9.4 及以上版本,
or
返回的结果由配置项
logicOrIgnoreNull
控制,见下表:
操作数
操作数
返回值(
logicOrIgnoreNull
= true 时)
返回值(
logicOrIgnoreNull
= false 时)
非零
NULL
true
NULL
零
NULL
true
NULL
NULL
NULL
true
NULL
参数
X
和
Y
可以是标量、数据对、向量或矩阵。
返回值
布尔类型,其形式与
X
/
Y
的形式相同。
例子
1 || 0;
输出返回:true
x=1 0 1;
x || 0;
输出返回:[true,false,true]
y=0 1 0;
x or y;
输出返回:[true,true,true]
t=table(1..3 as id, 4..6 as value);
t;
输出返回:
id
value
1
4
2
5
3
6
select id, value from t where id=2 or id=3;
输出返回:
id
value
2
5
3
6
相关函数:
and
,
not
FILE:references/doc_3571.md
# mem
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mem.html
**来源**: DolphinDB 官方文档
---
mem
语法
mem([freeUnusedBlocks=false])
详情
显示本地节点内存使用情况。
结果中,allocatedBytes 为已分配内存;freeBytes 是可用内存。两者之差为已占用内存。
如果
freeUnusedBlocks
=true,系统将会释放未使用的内存块。
参数
freeUnusedBlocks
为 DOUBLE 类型,取值范围为 0~1,表示释放的百分比。默认值为
false。
返回值
一个字典。
例子
undef all;
t1=table(1 2 3 as a, `x`y`z as b, 10.8 7.6 3.5 as c)
mem();
// output
freeBytes->492904
allocatedBytes->8454144
x=bigarray(INT,100000,10000000)
mem();
// output
freeBytes->491056
allocatedBytes->12648448
undef all;
mem();
// output
freeBytes->4687936
allocatedBytes->12648448
FILE:references/doc_3576.md
# cancelJob
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cancelJob.html
**来源**: DolphinDB 官方文档
---
cancelJob
语法
cancelJob(jobId)
详情
取消已经提交但尚未完成的批处理作业。
2.00.7 版本后,
若执行 cancelJob 时,发现某个 jobId 不存在,系统不再抛出异常,而是将包含 jobId
的报错信息输出到日志。
从
2.00.11
版本开始,系统对该操作进行了权限管理的增强。管理员(包括普通管理员和超级管理员)具有取消任何用户创建的批处理作业的权限,而普通用户只能取消自己创建的批处理作业。
参数
jobId
是批处理作业的 ID,是一个字符串标量或向量。若为向量,表示同时取消多个批处理作业。
返回值
无。
例子
def writeData(num){
n=10
month=take(2000.01M..2016.12M, n)
x=rand(1.0, n)
tt=table(month, x)
if(existsDatabase("dfs://test_db")){
dropDatabase("dfs://test_db")
}
db=database("dfs://test_db", VALUE, 2000.01M..2016.12M)
pt = db.createPartitionedTable(tt, `pt, `month)
for(x in 1..num){
pt.append!(tt)
sleep(1000)
}
}
myJobId="writeData"+temporalFormat(datetime(now()),"yyyyMMddHHmmss")
submitJob(myJobId,"write data to dfs table",writeData,120);
cancelJob(myJobId);
取消集群中所有未完成的 job。
def cancelAllBatchJob(){
jobids=exec jobid from getRecentJobs() where endTime=NULL
cancelJob(jobids)
}
pnodeRun(cancelAllBatchJob)
FILE:references/doc_3590.md
# rowWsum
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowWsum.html
**来源**: DolphinDB 官方文档
---
rowWsum
语法
rowWsum(X, Y)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行计算
X
和
Y
的内积。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m1=matrix(2 -1 4, 8 3 2, 9 0 1)
m2=matrix(8 11 10, 8 17 4, 14 6 4)
rowWsum(m1, m2)
// output
[206, 40, 52]
m3=matrix(8 NULL 10, 8 NULL 4, 14 NULL NULL)
rowWsum(m1, m3)
// output
[206, , 48]
a= -10 12.3 4 -8
b= 17.9 9 7.5 -4
c= 5.5 6.4 -7 8
x=array(DOUBLE[],0, 10).append!([a, b, c])
y=array(DOUBLE[],0, 10).append!([b, a, c])
rowWsum(x, y)
// output
[0.63, -6.3 , 184.21]
相关函数:
wsum
FILE:references/doc_3592.md
# 物联网应用范例
**URL**: https://docs.dolphindb.cn/zh/tutorials/iot_examples.html
**来源**: DolphinDB 官方文档
---
物联网应用范例
本教程介绍物联网领域 DolphinDB 用户在安装部署、分布式数据库设计、数据写入和查询、流计算和高可用测试等过程中的常见问题、相应的解决方案与注意事项,以帮助新用户快速入门。
1. 快速体验
1.1. 安装部署单节点服务
入门用户可先部署一个单节点模式 DolphinDB 以快速体验。单节点模式拥有与集群模式相同的功能,区别在于单节点模式不支持扩展节点和高可用,而集群模式可以方便地扩展到多个服务器节点以及支持高可用。安装的第一步是在官网下载
DolphinDB 社区试用版
。
选择 Windows 版本还是 Linux 版本?Linux 服务器比 Windows 服务器更稳定,建议生产环境选用 Linux 版本。若您现有环境是 Windows,亦可选择 Windows 版本进行体验。
选择稳定版还是最新版?目前一般 1-2 周会发布一个最新版。新版本不仅包含 bug 修复,还可能包含新功能、改进、性能优化等其他内容的更新,可能会带来新的 bug。若用于生产环境,出于对稳定性的要求,请选择稳定版。稳定版只修复 bug,不增加新功能。若进行体验与测试,可选择最新版。
若选择了最新版,选择
JIT(即时编译)
版本还是非 JIT 版本?DolphinDB 的即时编译功能显著提高了 for 循环,while 循环和 if-else 等语句的运行速度,特别适合于无法使用向量化运算但又对运行速度有极高要求的场景。但另一方面,DolphinDB 的 JIT 版本使用一个动态库,安装包要增加 10 多兆字节,这对原本仅 20 来兆的安装包相当可观。所以请综合考虑是否需要即时编译功能以及是否对安装包大小敏感,以决定是否下载 JIT 版本。
下载后,请参照
单节点部署教程
部署 DolphinDB。以 Linux 系统为例,步骤如下:
wget https://www.dolphindb.com/downloads/DolphinDB_Linux64_V1.30.7.zip
unzip DolphinDB_Linux64_V1.30.7.zip -d dolphindb
cd dolphindb/server
chmod +x dolphindb
./dolphindb
安装路径名不要含有空格或中文字符,否则会提示异常:Cannot open configuration file。
安装过程若出现错误提示:Failed to bind the socket on port 8848,说明 8848 端口已被其他程序占用,请更换端口。假设修改端口为 8900,可在配置文件 dolphindb.cfg 中进行如下修改:
localSite=localhost:8900:local8900
启动后出现如下界面。然后在 Console 中输入
1+1;
,若输出 2,即安装成功。
注意
:
上述命令中 DolphinDB_Linux64_V1.30.7.zip 表明下载的是 1.30.7 版本,若是其他版本,请修改文件名中的版本号。
上述命令中采用前台运行的方式,若要后台运行,修改
./dolphindb
命令为
nohup ./dolphindb -console 0 &
或
sh startSingle.sh
,然后用命令
ps aux | grep dolphindb
查看 dolphindb 进程是否已启动。若启动失败,请打开安装目录下的日志文件 dolphindb.log,查看日志中的错误提示信息。
数据文件默认存放在
<DolphinDB安装包>/server/local8848/storage/CHUNKS
。请选择容量较大的磁盘存放数据文件,并通过参数 volumes 配置数据文件存放目录。
DolphinDB 通过参数 maxMemSize 设置节点的最大内存使用量,默认设置为 0,表示内存使用没有限制。内存对于改进节点的计算性能非常明显,尽可能高配,但也不能设置太大。例如一台机器内存为 16GB,并且只部署 1 个节点,建议将该参数设置为 12GB 左右。否则使用内存接近或超过实际物理内存,有可能会触发操作系统强制关闭进程。如果在数据库使用过程中发生奔溃,可以用
dmesg -T | grep dolphindb
查看一下 Linux 日志,确认一下是否被操作系统 kill。
修改配置后,需要重启 DolphinDB 服务。前台用
quit
命令退出,后台用
kill -9 <进程号>
退出。
1.2. 测试 GUI 和 Web 连接
1.2.1. GUI 连接
DolphinDB 提供了多种方式与数据库交互,如 GUI、VSCode 插件、Web Notebook、Jupyter Notebook、命令行等。对入门用户,建议使用 DolphinDB GUI 编写 DolphinDB 脚本。请到 DolphinDB 官网下载
DolphinDB GUI
。安装前,需要确保已经安装 Java 8 及以上 64bit 版本。DolphinDB GUI 无需安装,开箱即用。在 Windows 环境下,双击 gui.bat 即可。在 Linu 和 Mac 环境下,在 Terminal 中输入:
cd /your/gui/folder
chmod +x gui.sh
./gui.sh
若 GUI 无法启动,请在 GUI 安装目录下运行:
java -version
若系统不能显示 Java 版本信息,说明 Java 没有安装或 Java 的安装路径不在系统路径中。在 Windows 上,需要查看是否在
Path
中;在 Linux 上,需要查看是否在
PATH
中。
若命令显示了 Java 版本信息,请检查版本是否符合要求。DolphinDB GUI 使用环境需要 64 位 Java 8 及以上版本。32 位的 Java 由于只支持 Client 模式,不支持 Server 模式,所以无法启动 GUI。符合要求的 Java 版本示例如下:
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
如果版本信息的最后一行如下所示,那么 DolphinDB GUI 将无法正常启动,需要到
Oracle 官网
重新下载安装。
Java HotSpot(TM) Client VM
GUI 启动后,首先根据提示,选择一个文件夹作为工作区。然后请参照
GUI 帮助手册
的说明,连接 DolphinDB 服务器,新建项目和脚本文件,再运行脚本。执行脚本时若出现错误提示:Failed to connect to selected server,请检查:
DolphinDB 端口是否被防火墙屏蔽。若端口没有开放,需要在防火墙打开该端口。
DolphinDB server 的 license 是否过期。
中文出现乱码
请在菜单栏点击 File-Preferences,在 Font 中设置中文字体,例如微软雅黑 (Microsoft Yahei)。然后执行 print(变量名),查看输出结果,乱码是否消失。
浮点数精度丢失
DolphinDB GUI 默认精度是 4 位,如果需要更高或低的精度,请在菜单栏点击 File-Preferences, 在 Default number of decimal places 中调整精度,例如设置为 8。
执行脚本提示:java.lang.OutOfMemoryError: Java heap space
这意味着发生 GUI 内存溢出,说明 GUI 的默认 2048MB 启动内存不能满足需要。这种情况一般是由于执行了结果的数据量较大的 SQL 查询且未将查询结果赋值予一个变量(例如直接执行 select ... from ...),因为此种操作会将结果的全部数据返回 GUI,占用 GUI 的内存。要避免此种情况下的 GUI 内存溢出,只需将结果赋值于一个变量,例如 t = select ... from ... 即可。此类语句在 server 端执行,不占用 GUI 内存。
假设需将 GUI 的内存扩大至 4096MB,可修改 gui/gui.bat 或者 gui/gui.sh 中的 -Xmx 启动参数,如下:
start javaw -classpath dolphindb.jar;dolphingui.jar;jfreechart-1.0.1.jar;jcommon-1.0.0.jar;jxl-2.6.12.jar;rsyntaxarea.jar;autocomplete.jar -Dlook=cross -Xmx4096m com.xxdb.gui.XXDBMain
关于 DolphinDB GUI 的更多细节,请参阅
DolphinDB GUI 客户端
。
1.2.2. Web 连接
Web 客户端是 DolphinDB 安装包自带的、基于网页的图形化交互工具,主要用于系统监控、日志查看、以及数据浏览,也可用于快速编辑执行代码、查看变量、以及基本的画图功能。与 GUI 不同,Web 客户端更适合临时任务,不适于执行复杂的开发任务。为了保证 DolphinDB 服务器的性能,若 10 分钟内无命令执行,系统会自动关闭会话以释放 DolphinDB 系统资源。在单节点模式下,启动 DolphinDB 服务器后,只要在浏览器输入网址 (http://IP:PORT,默认为 http://localhost:8848 ) 即可访问。若无法访问,请检查:
DolphinDB 端口是否被防火墙屏蔽。若端口没有开放,需要在防火墙打开该端口。
DolphinDB server 的 license 是否过期。
http 是否写成了 https。若需要使用 https 协议访问 web,请按照
权限管理和安全
第 3 节"使用 HTTPS 实现安全通信"进行配置。
DolphinDB 不会强制用户登录服务器,但是有些功能例如浏览/创建数据库或分区表需要登录才能访问。如果需要将权限设置为用户登录后才能执行脚本,单节点模式下可在配置文件 dolphindb.cfg 中添加配置项:
webLoginRequired=true;
若用户成功登录,会在屏幕上方显示登录用户名。如果 10 分钟内无命令执行,会自动退出登录。
有关如何使用 Web 客户端的更多信息,请参阅
DolphinDB Web 客户端
。
1.3. 使用脚本建库建表
DolphinDB 采用数据分区技术,按照用户指定的规则将大规模数据集水平分区,每个分区内的数据采用列式存储。在数据存储时,一个分区是一个目录。以按天分区为例,一天的数据存于同一个目录下。借助数据分区,在后续的查询过程中可直接跳过不必要的数据目录,从而提升查询性能。合理地利用分区,还可以实现数据的更新与删除操作,譬如数据表按天分区,那么数据就可以按天的粒度被更新或删除。
DolphinDB 的每个分布式数据库采用一种分区机制,一个数据库内的多个事实表(fact table)共享这种分区机制,而且同一个分区的多个子表(tablet chunk)数据落在同一个节点上,保证同一个数据库的多个事实表连接 (join) 的效率非常高。除了分布式的事实表,DolphinDB 还提供了不分区的维度表(dimension table),通常用于存储不经常更新的小数据集。这类数据的数据量通常不会随着时间的积累而增长,而且数据内容变化较小。维度表可与任何采用分区机制的事实表关联。
在 DolphinDB 中,数据库使用
database
函数创建,分区表和维度表分别使用
createPartitionedTable
和
createTable
函数创建。
DolphinDB 不提供行级的索引,而是将分区作为数据库的物理索引。一个分区字段相当于数据表的一个物理索引。如果查询时用到了该分区字段做数据过滤,SQL 引擎就能快速定位需要的数据块,而无需对整表进行扫描。为提高查询和计算性能,每个分区的数据量不宜过大、也不宜过小,一般建议每个分区压缩前的数据量控制在 100MB 左右(第 2 章会详细介绍,亦可参阅
分区数据库教程
)。
下例中假设有 1000 台设备,每台设备有 50 个指标,每个指标的数据类型都是 float,每秒采集一次数据。假设常用的查询基于时间段和设备进行,因此按时间和设备标识这 2 个维度进行分区。每台设备每天产生的数据约 16MB,因此数据库可按 2 个维度分区,第一个维度按天(datetime 列)值分区,第二个维度按设备编号(machineId 列)范围分区,10 个设备一个区,每个分区数据量约 160MB。建库建表代码如下:
db1 = database("",VALUE,2020.10.01..2020.12.30)
db2 = database("",RANGE,0..100*10+1)
db = database("dfs://iot",COMPO,[db1,db2])
m = "tag" + string(1..50)
schema = table(1:0, `machineId`datetime join m, [INT,DATETIME] join take(FLOAT,50) )
db.createPartitionedTable(schema,"machines",`datetime`machineId)
上述代码新建分布式数据库 dfs://iot 与该库中的分布式数据表 machines。代码中,schema 是一个内存表,作为分区表的模板,指定了分区表的结构,包括设备编号列 machineNo、时间列 datetime 以及 50 个指标列 tag1~tag50,以及相应的数据类型。schema 表的第一个参数 1:0 分别为 capacity:size,其中 capacity 表示建表时系统为该表分配的内存(以行数为单位),size 表示该表新建时的行数。size=0 表示创建一个空表,仅仅作为分区表的模板使用。上述 schema 因为列名有规律、类型一致,所以用函数
join
进行了简化,实际等价于下面 2 种写法,可根据列名、类型情况进行仿写:
schema = table(1:0, `machineId`datetime`tag1`tag2`tag3`tag4`tag5`tag6`tag7`tag8`tag9`tag10`tag11`tag12`tag13`tag14`tag15`tag16`tag17`tag18`tag19`tag20`tag21`tag22`tag23`tag24`tag25`tag26`tag27`tag28`tag29`tag30`tag31`tag32`tag33`tag34`tag35`tag36`tag37`tag38`tag39`tag40`tag41`tag42`tag43`tag44`tag45`tag46`tag47`tag48`tag49`tag50,
[INT,DATETIME,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT,FLOAT] )
schema=table(
array(INT,0) as machineId,
array(DATETIME,0) as datetime,
array(FLOAT,0) as tag1,
array(FLOAT,0) as tag2,
array(FLOAT,0) as tag3,
array(FLOAT,0) as tag4,
array(FLOAT,0) as tag5,
array(FLOAT,0) as tag6,
array(FLOAT,0) as tag7,
array(FLOAT,0) as tag8,
array(FLOAT,0) as tag9,
array(FLOAT,0) as tag10,
array(FLOAT,0) as tag11,
array(FLOAT,0) as tag12,
array(FLOAT,0) as tag13,
array(FLOAT,0) as tag14,
array(FLOAT,0) as tag15,
array(FLOAT,0) as tag16,
array(FLOAT,0) as tag17,
array(FLOAT,0) as tag18,
array(FLOAT,0) as tag19,
array(FLOAT,0) as tag20,
array(FLOAT,0) as tag21,
array(FLOAT,0) as tag22,
array(FLOAT,0) as tag23,
array(FLOAT,0) as tag24,
array(FLOAT,0) as tag25,
array(FLOAT,0) as tag26,
array(FLOAT,0) as tag27,
array(FLOAT,0) as tag28,
array(FLOAT,0) as tag29,
array(FLOAT,0) as tag30,
array(FLOAT,0) as tag31,
array(FLOAT,0) as tag32,
array(FLOAT,0) as tag33,
array(FLOAT,0) as tag34,
array(FLOAT,0) as tag35,
array(FLOAT,0) as tag36,
array(FLOAT,0) as tag37,
array(FLOAT,0) as tag38,
array(FLOAT,0) as tag39,
array(FLOAT,0) as tag40,
array(FLOAT,0) as tag41,
array(FLOAT,0) as tag42,
array(FLOAT,0) as tag43,
array(FLOAT,0) as tag44,
array(FLOAT,0) as tag45,
array(FLOAT,0) as tag46,
array(FLOAT,0) as tag47,
array(FLOAT,0) as tag48,
array(FLOAT,0) as tag49,
array(FLOAT,0) as tag50
)
注意
:
创建或访问分布式数据库和表需要相应的用户权限。若不登录,会出现类似"<NotAuthenticated>Not granted to ..."这样的错误提示。DolphinDB 的默认管理员用户是"admin",其默认密码是"123456"。登录命令如下:
login(`admin, `123456)
登录后使用函数
changePwd
修改密码。更多权限管理细节,请参阅
权限管理和安全
。
库表创建后,可使用函数
getAllDBs()
显示当前所有数据库,使用函数
schema
显示某个表或某个数据库的结构信息。例如查询上述
dfs://iot
数据库的设备分区信息可用如下代码:
database("dfs://iot").schema().partitionSchema[1]
查询上述 machines 的表结构可用如下代码:
loadTable("dfs://iot","machines").schema().colDefs
- 数据库创建后,无法通过
database
函数修改分区类型或分区方案,若要修改,请先删库再重新创建。删除数据库可使用
dropDatabase
函数。若删除某个数据表,可使用
dropTable
。分布式表支持增加列,不支持修改列和删除列。增加列可使用
addColumn
函数。
1.4. 数据库增删改查
分布式表 (DFS table) 不支持使用
insert into
插入数据,仅支持使用
append!
或
tableInsert
函数插入数据。即使只插入一条数据,也要用表的形式来表示新增的数据。插入数据的代码示例如下,其中自定义函数
genData
输入设备编号集,开始时间和每台设备记录数,返回一个包含所有模拟记录的内存表。
下面首先为 1000 个设备产生 1 小时的数据,然后举例说明如何查询、修改和删除数据库记录:
def genData(uniqueMachineId, startDateTime, freqPerMachine){
numMachines = size(uniqueMachineId)
numRecords = numMachines * freqPerMachine
machineId = array(INT, numRecords)
for(i in 0:numMachines) machineId[(i*freqPerMachine) : ((i+1)*freqPerMachine)] = uniqueMachineId[i]
t = table(machineId, take(startDateTime + (0..(freqPerMachine-1)), numRecords) as ts)
m = "tag" + string(1..50)
for (i in 0 : 50) t[m[i]] =rand(10.0, numRecords)
return t
}
machines = loadTable("dfs://iot", "machines")
t=genData(1..1000, datetime(2020.10.05), 3600)
machines.append!(t)
与其他关系数据库、NoSQL、NewSQL 等数据库不同,DolphinDB 将数据库、编程语言和分布式计算三者融为一体,这种设计使得 DolphinDB 可以一站式轻量化的解决海量大数据的存储与计算。但也使得数据库和表在 DolphinDB 中只是一个普通变量,引用数据库和表时,有可能会与脚本中的其他变量名发生冲突,所以不能直接使用数据库或表名,必须使用
loadTable
函数先加载数据表。上例中,加载数据库 dfs://iot 中的数据表 machines,并把这个表对象赋值给变量 machines,之后就可以使用变量 machines 来访问这个数据表。
例 1. 查询每个设备的记录总数:
select count(*) from machines group by machineId
若查询到的记录数是 0,请检查一下写入数据的分区字段值是否超出了分区范围。比如这个数据库日期分区是 2020.10.01 到 2020.12.30,若数据的时间是在 2020.10.01 之前或 2020.12.30 之后,就会写入失败。为了解决这个问题,请参照用户手册中
增加分区
这小节的说明,在配置文件中增加配置项 newValuePartitionPolicy=add 并重启 DolphinDB 节点。
例 2. 查询设备 1 在 2020.10.05 这一天的历史记录:
select * from machines where machineId=1 and datetime between 2020.10.05T00:00:00 : 2020.10.05T23:59:59
查询时需要注意:系统在执行分布式查询时,首先根据 where 条件确定相关分区。大多数分布式查询只涉及分布式表的部分分区,系统不必全表扫描,从而节省大量时间。但若不能根据 where 条件做分区剪枝,就会全表扫描,影响查询性能。另外,还可能出现类似下列错误:
The number of partitions [372912] relevant to the query is too large. Please add more specific filtering conditions on partition columns in WHERE clause, or consider changing the value of the configuration parameter maxPartitionNumPerQuery.
配置参数 maxPartitionNumPerQuery 指定一个查询最多可以涉及的分区数量,默认值是 65535,用于防止生产环境中有人手误提交超级大的 query,影响性能。请注意,若 where 子句中的过滤条件不符合分区剪枝的规则,即使计算只使用了少数分区,在确定相关分区的过程中仍可能进行全表扫描,导致涉及的分区数量多于 maxPartitionNumPerQuery 的值。例如,若例 2 中的涉及日期的 where 条件写为 date(datetime)=2020.10.05,即使计算实质使用的分区数量不变,但由于违反了分区剪枝的规则,会全表扫描,耗时会显著增加。
可以使用以下方法解决这个问题:
查询中限定尽可能精确的分区范围。
定义数据库的分区机制时,时间戳列的定义不要包含将来的日期,可以在系统中将 newValuePartitionPolicy 设置成 add。这样新的日期出现时,系统会自动更新数据库定义。
将 maxPartitionNumPerQuery 的值调大。不推荐这种方法,因为若不小心忘记设定查询的过滤条件或将过滤条件设置过松,则该查询会耗时过久,浪费系统资源。
例 3. 查询设备 1 在 2020.10.05 这一天的最早的 10 条历史记录:
select top 10 * from machines where machineId=1 and datetime between 2020.10.05T00:00:00 : 2020.10.05T23:59:59
DolphinDB 的分区之间存在先后顺序;分区内的数据按照写入顺序存储。查询或计算的时候,如果需要,可以用 order by、csort 等排序。下面我们选择不同分区的 1 号设备和 11 号设备,先写入 2020.10.06T00:00:01 各一条记录,然后写入 2020.10.06T00:00:00 各一条记录。再查询 top 2 记录:
t=genData([1,11],2020.10.06T00:00:01,1)
machines.append!(t)
t=genData([1,11],2020.10.06T00:00:00,1)
machines.append!(t)
select top 2 * from machines where datetime >= 2020.10.06T00:00:00
查询结果如下所示。从中可见,虽然 11 号设备的 2020.10.06T00:00:01 的数据先写入,但因为它属于符合 where 条件(即 2020.10.06 日)第二个分区(每 10 台机器一个分区),所以结果中没有它,而是返回了第一个分区 1 号设备 2020.10.06T00:00:00 的数据。在第一个分区里,虽然 2020.10.06T00:00:00 的时间早,但它写入晚,所以先返回了 2020.10.06T00:00:01 的数据。如果查询 top 1,则只有 2020.10.06T00:00:01 的数据被返回。
machineId datetime tag1 ... tag50
1 2020.10.06T00:00:01 1.7039 ... 7.8002
1 2020.10.06T00:00:00 7.9393 ... 2.7662
例 4. 查询每个设备的最新一条记录:
select top 1 * from machines context by machineId csort datetime desc
此查询通过 SQL 的
context by
子句对表内记录进行分组,然后在组内按时间戳列进行 csort 降序排序,再与 top 一起使用,获取每个分组中的最新记录。
SQL 的
context by
子句为 DolphinDB 对标准 SQL 进行的拓展,在处理面板数据 (panel data) 时极为方便。更多细节请参考用户手册的
context by
的介绍。
若在生产环境中不断写入的情况下进行查询,为了减少查询范围,可增加一个查询条件,即限制 datetime 为最近一小时,如下所示:
select top 1 * from machines where datetime >= datetimeAdd(now().datetime(),-1,`h) context by machineId csort datetime desc
若数据是按时间顺序插入,系统内存资源充足,此查询也可使用快照引擎实现。快照引擎性能更佳,但目前仅支持单节点服务模式。
另外,在测试查询性能时,DolphinDB 提供了
timer
函数用于计算查询耗费的时间。譬如在 GUI 中查询 21 号设备在 2020.10.05 的记录:
timer select * from machines where machineId=21, datetime between 2020.10.05T00:00:00 : 2020.10.05T23:59:59
返回如下信息:
2020.10.28 19:34:34.181: executing code (line 2489)...
Time elapsed: 9.52 ms
2020.10.28 19:34:34.227: execution was completed [46ms]
这里打印了 2 个时间。第一个时间 9.52 ms 是
timer
返回的时间,为这个查询在服务器上运行耗费的时间;第二个时间 46 ms 则是从脚本命令发送到接收返回结果的整个过程花费的时间,两者之差为序列化/反序列化和网络传输的耗时。类似 select * from table 即返回整个数据集到 GUI 这样的查询语句,若数据量特别大,序列化/反序列化和网络传输的耗时可能会远远超过在服务器上运行的耗时。
从 1.30.6 版本起,DolphinDB 支持使用 SQL update 和 delete 语句修改分布式表(包括维度表和分区表)
。
例 5. 更新设备 1 在 2020.10.05T00:00:00 时间点 tag1 值为 1.0:
update machines set tag1 = 1.0 where machineId=1 and datetime=2020.10.05T00:00:00
例 6. 删除设备 1 在 2020.10.05T00:00:01 时间点的记录:
delete from machines where machineId=1 and datetime=2020.10.05T00:00:01
1.5. Grafana 连接 DolphinDB
DolphinDB 提供了标准协议的 SQL 查询接口,与第三方分析可视化系统如 Grafana、Redash 和帆软等可轻松实现集成与对接。本节以 Grafana 为例,介绍 DolphinDB 与第三方可视化系统的连接与展示。
1.5.1. 安装配置
安装 Grafana 请参考
Grafana 官网教程
。安装后,若本机浏览器中可以打开 http://localhost:3000/ ,说明 Grafana 安装成功,否则请检查 3000 这个端口是否被防火墙屏蔽或被其他应用占用。
DolphinDB 为了支持使用 Grafana 来实时展示时序数据,提供了 Grafana 的 dolphindb-datasource 插件,并且实现了对 Grafana 的 HTTP 数据接口,可以通过类 SQL 的查询脚本将 DolphinDB 的数据表以直观的方式展示在 Grafana 的 Dashboard 上。插件的下载与安装请参阅
插件教程
。
1.5.2. 显示数据
在 GUI 中运行以下脚本模拟 1 号设备每一秒产生一条数据,其中 gen 为 1.4 节描述的自定义函数,使用
submitJob
函数把自定义的
writeIOTData
函数提交批处理作业:
def writeIoTData(){
login("admin", "123456")
machines = loadTable("dfs://iot", "machines")
for (i in 0:86400) {
t=genData(1, now().datetime(), 1)
machines.append!(t)
sleep(1000)
}
}
submitJob("jobId1","writeDataToMachine1",writeIoTData)
在 Grafana 的 Home 界面点击"Create Dashboard",然后点击"Add new panel",在如下图所示界面的 Query options 中选择 DolphinDB 数据源后,数据源下方会出现一个用于输入脚本的文本输入框,输入以下查询语句以读取 1 号设备前 5 分钟的 tag1 数据:
login('admin', '123456'); select gmtime(timestamp(datetime)) as time_sec, tag1 from loadTable('dfs://iot', 'machines') where machineId=1 and datetime> now().datetime()-5*60
在右上角设置定时刷新及数据时间段的长度,就可以看到实时的数据变化走势图。
上图若不能正常显示,请检查:
在 GUI 中运行函数
getRecentJobs
,查看作业运行是否有错,若有错,返回结果中 errorMsg 会显示错误信息。取消作业用
cancelJob
。
Grafana 默认返回 timer_series 格式,SQL 中返回的第一个字段必须是 timestamp 类型。
DFS 数据库需要登录后才能访问,所以 select 语句前需要先登录。
检查查询语句中是否含有双引号,若有双引号,改其为单引号。
若上述方法还不能解决问题,建议用 Goole Chrome 浏览器运行 Grafana,然后按 F12 调试,可以查看一下网络交互信息是否提示了异常。
1.6. DolphinDB 与其他数据库异同点小结
物联网历史数据有可能达到几百 TB 甚至 PB 级别。传统的关系型数据库(如 Oracle,SQL Server,MySQL 等)受到行式存储和数据索引的限制,处理如此量级数据的性能非常低下,即使分库分表,效果也不理想。DolphinDB 采用了分区机制,可以轻松应对 PB 级别的海量数据。DolphinDB 通过数据分区而不是索引的方式来快速定位数据,适合海量数据的存储,检索和计算。在数据量不是非常大时,创建索引可以显著提高系统的性能,但在海量数据场景下,随着数据量的不断增加,索引会不断膨胀(需要占用的内存甚至可能超过了服务器的内存),反而导致系统性能下降。
DolphinDB 将分布式数据库、分布式计算和编程语言从底层进行一体化设计,这种设计使得 DolphinDB 可以一站式轻量化的解决海量大数据的存储与计算。但是,引用数据库和表时,因为可能会与脚本中的变量名发生冲突,所以不能直接使用数据库或表名,必须使用
loadTable
函数先加载数据表。
与关系型数据库不同,DolphinDB 分布式表不支持使用
insert into
插入数据,仅支持使用
append!
或
tableInsert
函数以表的形式插入数据。DolphinDB 支持事务,客户端每次写入都是一个事务但是用户层面不提供事务操作,不需要用户像关系数据库一样显式地开始事务、提交事务等。
相比其他时序数据库,DolphinDB 是一个非常轻量级的系统,用 GNU C++ 开发,核心程序仅 20 余兆字节,无任何依赖,开箱即用。DolphinDB 已适配国产的 X86、ARM、MIPS(龙芯)等 CPU,可以运行在 Linux 和 Windows 操作系统上。
2. 分布式数据库设计和测试
2.1. DolphinDB 存储引擎
DolphinDB 利用分布式文件系统实现数据库的存储和基本事务机制。数据库以分区(chunk)为单位进行管理。分区的元数据(元数据指"../tools/grafana.md"小,存储位置等)存储在控制节点,副本数据存储在各数据节点,统一由分布式文件系统进行管理。一个数据库的数据可能存储在多个服务器上,系统内部通过事务机制和二阶段提交协议保证数据的强一致性和完整性,对于外部用户来说,这些机制是完全透明的。每个分区副本的数据采用列式增量压缩存储。压缩算法采用了 LZ4 或 DELTA 算法,在实际生产环境中,磁盘数据的无损压缩比约 5:1,在有些重复较多、变动范围较小、写入批量大的场景,也能做到更高的压缩比。
一个数据库最多可以支持三个维度的分区,支持百万甚至千万级的分区数。为尽可能保证每个分区的大小平衡,DolphinDB 提供了值(VALUE)分区,范围(RANGE)分区,哈希(HASH)分区,列表(LIST)分区和复合(COMPO)分区等多种分区方式,用户可以灵活使用,合理规划分区。在查询时,加载数据的最小单位是一个分区的一个列。DolphinDB 不提供行级的索引,而是将分区作为数据库的物理索引。一个分区字段相当于数据表的一个物理索引。如果查询时用到了该分区字段做数据过滤,SQL 引擎就能快速定位需要的数据块,而无需对整表进行扫描。在物联网领域,查询分析大多基于某一个时间段、某个设备或某个指标进行,因此时间和设备/指标标识是物联网领域最常用的分区维度。
下面展示一个数据库的存储目录和文件,其中数据库按照两个维度分区,第一个维度按天(ts 列)进行值分区,第二个维度按照标签编号(tagid 列)范围分区,建库建表以及测试数据写入代码如下所示:
schema = table(1:0,`tagid`ts`data,[INT,TIMESTAMP,INT]);
db1 = database("",VALUE,2020.01.01..2020.01.02)
db2 = database("",RANGE,1 11 21 31)
db = database("dfs://demo",COMPO,[db1,db2])
db.createPartitionedTable(schema,"sensor",`ts`tagid)
t=table(1..30 as tagid,take(2020.01.01T00:00:00.000 2020.01.02T00:00:00.000,30) as time,rand(10,30) as data )
loadTable("dfs://demo","sensor").append!(t)
写入测试数据后,存储目录和数据文件如下所示,
[root@188 CHUNKS]# tree ./demo/
./demo/
├── 20200101
│ ├── 1_11
│ │ └── sensor
│ │ ├── data.col
│ │ ├── tagid.col
│ │ └── ts.col
│ ├── 11_21
│ │ └── sensor
│ │ ├── data.col
│ │ ├── tagid.col
│ │ └── ts.col
│ └── 21_31
│ └── sensor
│ ├── data.col
│ ├── tagid.col
│ └── ts.col
├── 20200102
│ ├── 1_11
...
├── dolphindb.lock
├── domain
└── sensor.tbl
从中可以看到,一个分区维度对应一层子目录,譬如按天分区的子目录名是 20200101,20200102 等,按标签编号范围分区的子目录名是 1_11,11_21 等,表中每一列保存为一个后缀名为 col 的文件,如 data.col,tagid.col 等。
DolphinDB 对分布式数据库表的读写支持事务,保证多行写入数据(可以跨越多个分区,支持多个副本)的原子性和持久性。断电不影响写入的数据,也不破坏数据库的完整性。DolphinDB 采用多版本机制实现快照级别的隔离。当用户同时对数据库进行读写操作时,读和写的并发事务会相互隔离。在这种隔离机制下,数据的读操作和写操作互不阻塞,可以最大程度优化数据仓库读的性能。目前绝大部分的时序数据库不提供事务功能,因此有可能发生一致性和完整性问题,譬如写入两条记录可能一条成功,另一条不成功;已经写入的数据在断电重启后可能丢失最后几条数据;查询的时候可能查到正在写入的数据(尚未全部完成)。
2.2. 单值模型
数据库通用的设计模式有两种,即单值模型和多值模型。单值模型针对测点建模。一个被监控的指标称为一个测点,例如电量仪中会有电压、电流、功率等测点,温湿度计中有温度、湿度测点。单值模型在写入时每一个测点为一行,所有采集的传感器指标值,无论种类,均存于同一列中。单值模型适合各测点采集频率不一致的应用场景,不适合不同指标之间要做很多协同处理的场景。单值模型数据占用的存储空间大,写入性能和查询性能也不如多值模型。
假设某厂有 100 个机组,每台机组有 50 个测点,共有 100*50=5000 个测点。每个测点采集一个指标的数据,每秒采集一次数据,均为 float 类型。所有机组采集相同的 50 个指标的数据并存入数据库。
对测点按顺序进行编号:一号机组的测点为 1~50,二号机组的测点是 51~100,以此类推。
本案例若按单值模型设计,表结构可定义如下:
列名
数据类型
备注
id
INT
测点编号
datetime
DATETIME
时间
value
FLOAT
指标值
单值模型适合的常用查询基于测点编号与时间段,可按测点编号和时间这 2 个维度进行分区。时间维度一般情况下可按天进行值(VALUE)分区,但也可根据数据量和典型查询场景采用其它分区方案。若某些场景下,查询时间跨度不是很长,而单位时间内的数据量又较大,也可以按小时进行分区。若数据量比较小,又常按一个月或几个月进行查询和计算,也可以按月分区。
物联网设备监控场景的各指标的采集频率一般固定,比较容易计算单位时间的数据量大小,因此指标维度的分区通常采用范围(RANGE)或值(VALUE)方法。DolphinDB 中组合分区的多个列在逻辑上是并列的,不存在从属关系或优先级关系。如果时间维度有 n 个分区,指标维度有 m 个分区,最多可能有 n * m 个分区。为提高查询和计算性能,每个分区的数据量不宜过大、也不宜过小。一般建议每个分区压缩前的数据量控制在 100MB 左右(详情请参阅
分区数据库教程
)。
本案例中,每 100 个测点(即两个机组)每天的数据约 100MB(12 字节/条*86400 条*100 测点)。所以第一个分区维度采用值分区,每天为一个分区;第二个分区维度采用范围(RANGE)分区,每 100 个测点(即两台机组)为一个分区。参考代码如下:
numMachines=100
numMetrics=50
numMachinesPerPartition=2
ps1=2020.09.01..2020.12.31
ps2=(numMetrics*numMachinesPerPartition)*(0..(numMachines/numMachinesPerPartition))+1
def createDatabase(dbName,tableName, ps1, ps2){
tableSchema = table(1:0,`id`datetime`value,[INT,DATETIME,FLOAT]);
db1 = database("", VALUE, ps1)
db2 = database("", RANGE, ps2)
db = database(dbName,COMPO,[db1,db2])
dfsTable = db.createPartitionedTable(tableSchema,tableName,`datetime`id)
}
createDatabase("dfs://svmDemo","sensors", ps1, ps2)
以上建立的数据库 dfs://svmDemo 中的 svm 代表 single-value model(单值模型)。
2.3. 多值模型
多值模型通常针对数据源(在物联网领域通常是设备)建模,写入时每一个设备在同一时刻被测量的所有指标值为一行。上一小节中案例若用多值建模,表结构定义如下:
列名
数据类型
备注
id
INT
机组编号
datetime
DATETIME
时间
TAG1
FLOAT
1 号指标
...
TAG50
FLOAT
50 号指标
多值模型适合的常用查询基于时间段和设备,因此多值模型的分区字段可选择时间和设备这 2 个维度。时间维度通常按天、按小时或按月进行值(VALUE)分区,由数据量和典型查询场景决定。若查询时间段跨度不大且单位时间内采集数据量大,可按小时进行分区;若查询时间段跨度大且单位时间内数据量不大,可按月分区。设备维度的分区可以采用哈希、范围、值、列表等多种方法,原则就是要根据业务特点对数据进行均匀分割,让每个分区压缩前的大小控制在 100MB 左右。但如果数据表为宽表(几百甚至几千个字段),若单个应用只会使用一小部分字段,因为未用到的字段不会加载到内存,不影响查询效率,这种情况可以适当放大分区上限的范围。数据库分区也可按三个维度进行。比如采集设备的网络日志,常用的查询基于时间段、源 IP 地址和目的 IP 地址,就可以考虑采用时间、源 IP 地址和目的 IP 地址三个分区维度。
本案例每机组每天的记录数为 86400 条,每天的数据量约 16MB。常用查询按天和设备进行,因此可采用复合分区,按天进行值分区,按机组进行范围分区,每 10 个机组为一个分区。参考代码如下:
numMachines=100
numMachinesPerPartition=10
ps1=2020.09.01..2020.12.31
ps2=numMachinesPerPartition*(0..(numMachines/numMachinesPerPartition))+1
def createDatabase(dbName,tableName, ps1, ps2, numMetrics){
m = "tag" + string(1..numMetrics)
schema = table(1:0,`id`datetime join m, [INT,DATETIME] join take(FLOAT,50) )
db1 = database("",VALUE,ps1)
db2 = database("",RANGE,ps2)
db = database(dbName,COMPO,[db1,db2])
db.createPartitionedTable(schema,tableName,`datetime`id)
}
createDatabase("dfs://mvmDemo","machines", ps1, ps2, 50)
以上建立的数据库 dfs://mvmDemo 中的 mvm 代表 multiple-value model(多值模型)。
2.4. 使用脚本生成测试数据
若没有实际生产数据,可使用脚本模拟产生测试数据。
单值模型的脚本见
附件 1
此脚本生成分布式表 dfs://svmDemo/sensors 多天的模拟数据。函数 generate1DayData 用于产生一天的模拟数据;函数 singleThreadWriting 调用 generate1DayData 产生模拟数据,并将数据用单线程写入分布式表中。singleThreadWriting 中每次写入操作写入一个分区的全部数据,这样每个分区的数据文件只需打开一次就全部写入,可提高写入性能。多线程并行写入能进一步提升写入性能。
函数 multipleThreadWriting 用
cut
函数把测点标号向量按线程数平均分隔,然后用
ploop
并行调用 singleThreadWriting 多线程写入数据库。
代码中线程数设为 20,实际写入时请根据主机内存情况调整。写入开始后,可以使用
getRecentJobs
函数查看作业处理情况,若返回结果中 endtime 等 endtime 全部显示出来了。使用
getClusterPerf
函数查看系统 CPU 与内存等资源使用情况。
若有 1000 台机器,50 个指标,写入 5 天,在普通台式机上约需 50-100 分钟左右写入,在 I/O 性能较好的服务器上约需 4 分钟写入。磁盘上数据文件约为 160GB。
多值模型的脚本见
附件 2
这个脚本可以生成分布式表 dfs://mvmDemo/equip 多天的模拟数据,脚本逻辑与单值模型类似。
要提升写入性能,可采取以下措施:
批量写入每批次的数据量不宜过小,一般几十 MB 比较合适。
以上述单值模型案例为例,100 个测点共写入 90 天的数据,即 777,600,000 条记录,用不同批量大小在一台 PowerEdge R730xd linux 主机上测试。DolphinDB 采用单节点部署,限制使用 32G 内存,16 核 CPU。元数据写入 SSD,数据写入 HDD,其他都采用默认配置。测试结果如下:
每批记录数
写入耗时(秒)
每秒写入记录数
100
8,086
96,166
6,000
165
471,272
360,000
38
20,463,157
每次写入数据涉及的分区数量不宜过多。DolphinDB 存储时,每个分区每个列存为一个文件。若每次写入 3 列数据,涉及 3,600 个分区,那么每次需要写入 3,600*3=10,800 个文件,会严重影响写入性能。例如在上述测试环境中,还是每批写入 360,000 条,并写入一样多的记录总数,但每批涉及分区 3,600 个,耗时 7,922 秒,是每次写入单个分区耗时的 200 余倍。
对小批量写入,启用 Redo Log 和写入数据缓存 (Cache Engine) 功能,能把多次少量的写入缓存起来,一次批量写入,能大大提高写入吞吐量。以上述 100 个测点共写入 777,600,000 条记录为例,在同样的测试环境,但设置了 dataSync=1(表示将 Redo log、数据和元数据强制刷盘)和 chunkCacheEngineMemSize=1(缓存为 1GB)。测试结果显示,每批写入 100 条记录,仅耗时 81 秒,吞吐量提高约 100 倍。有关 Redo Log 和 Cache Engine 的更多信息,请参阅
Cache Engine 与数据库日志
使用多个客户端多线程并行写入,但注意多个 writer 不能同时向同一个分区写入。
下面用
单值模型脚本
在一台台式机上测试,台式机 CPU 为 6 核 12 线程的 Intel I7,内存 32GB,128GB SSD 和 2TB 7200RPM HDD。DolphinDB 采用单节点部署,限制使用 16G 内存,启动 Redo Log 和写入缓存。元数据和 Redo Log 写入 SSD,数据写入 HDD。1000 台设备,50 个指标,写入 5 天历史数据,如下表所示,5 个线程是单线程写入性能快约 1.5 倍,10 线程时受硬件资源限制,与 5 线程相比提升不明显。
线程数
写入耗时(秒)
每秒写入记录数
1
4081
5,292,820
5
2925
7,384,615
10
2907
7,430,340
不同的数据节点配置不同的磁盘,每个数据节点挂载多卷(Volumes),可并行利用多个磁盘的 I/O 接口,大幅提升节点的整体读写吞吐性能。例如下面配置 diskIOConcurrencyLevel 为 4,volumes 配置 4 个磁盘,也即为每一个挂载的硬盘配置一个读写线程,将对一个磁盘的读写任务串行化到一个队列,避免了并发线程之间的磁盘读写竞争。
diskIOConcurrencyLevel=4
volumes=/hdd/hdd1/volumes,/hdd/hdd2/volumes,/hdd/hdd3/volumes,/hdd/hdd4/volumes
3. 历史数据查询
本章节所用数据均为第 2 章中所建之单值模型 sensors 分布式表。请注意,由于 sensors 中 value 列的数据为随机生成,所以以下结果中涉及到 value 的数值会与您得到的结果有所差别。
首先将 sensors 表元数据载入内存:
login("admin","123456")
sensors=loadTable("dfs://svmDemo","sensors")
3.1. 趋势查询
将一天内 10 个指定测点的数据,按每 2 分钟分成若干时间段,每个时间段内计算最大值、最小值、开始值与结束值。
select first(value), last(value), max(value), min(value)
from sensors
where id in [1,2,51,52,101,102,151,152,201,202] and datetime between 2020.09.01T00:00:00 : 2020.09.07T23:59:59
group by id, bar(datetime,120)
3.2. 对比查询
查询某天内 1,2,3 号设备中的 1 号指标每分钟的平均值,将结果按分钟与设备编号排列,以便于对比。
DolphinDB 支持在 SQL 中使用
pivot by
子句将表中某列的内容按照两个维度重新排列,亦可配合数据转换函数使用。
pivot by
是 DolphinDB 对标准 SQL 语句的拓展。此查询的代码如下所示:
select avg(value) from sensors
where id in [1,51,101], datetime between 2020.09.01T00:00:00 : 2020.09.01T23:59:59
pivot by datetime.minute() as time, id
结果如下:
time C1 C51 C101
00:00m 0.5375 0.4846 0.4858
00:01m 0.5422 0.5549 0.5073
00:02m 0.4576 0.5358 0.4846
...
3.3. 分组查询 top N
查询指定 1 小时内 CPU 平均利用率最高的三台设备。假设 CPU 利用率为指标 1。这里使用嵌套查询,先分组计算平均值,然后根据平均值排序,再对结果使用 top 子句(或 limit 子句)。代码如下:
select top 3 id
from (
select avg(value) as avg
from sensors
where mod(id, 50)=1, datetime between 2020.09.01T00:00:00 : 2020.09.01T00:59:59
group by id order by avg desc
)
以上脚本亦可写为:
select id
from (
select avg(value) as avg
from sensors
where mod(id, 50)=1, datetime between 2020.09.01T00:00:00 : 2020.09.01T00:59:59
group by id order by avg desc
) limit 3
注意这里 id 查询条件用了 mod(id, 50)=1,查询时不能分区剪枝,是因为这个查询本身就需要扫描全部 id 的分区,若只在部分设备中查询,建议用 id in [1,51,...]的方式。
3.4. 关联查询
DolphinDB 支持如下 7 种关联查询:
equal join (
ej
)
left join (
lj
)
cross join (
cj
)
full join (
fj
)
asof join (
aj
)
window join (
wj
)
prefix join (
pj
)
例 1:分布式表 sensors 中只存储了测点编号,现提供这些测点的描述信息,在查询分析时需与这些信息进行关联查询和计算。
这些测点信息可以存储在维度表中。维度表是分布式数据库中没有分区的表,一般用于存储不频繁更新的小数据集。维度表可与任何分布式表,维度表以及内存表进行关联。DolphinDB 自动会在各个节点上缓存 (cache) 维度表,以提升查询和关联的性能。下面例子创建维度表 tagInfo 并插入一些样本数据:
db = database("dfs://svmDemo")
schema = table(1:0, `tagId`machineId`tagName`organization`description, [INT,INT,SYMBOL,SYMBOL,SYMBOL])
dt = db.createTable(schema,`tagInfo)
tagInfo=loadTable("dfs://svmDemo","tagInfo")
t = table(1 2 51 52 as tagId,1 1 2 2 as machineId,`speed`temperature`speed`temperature as tagName,`hangzhou`hangzhou`shanghai`shanghai as organization,
"Speed/No.1 Wind Turbine in Hangzhou" "Temperature/No.1 Wind Turbine in Hangzhou" "Speed/No.2 Wind Turbine in Shanghai" "Temperature/No.2 Wind Turbine in Shanghai" as description )
tagInfo.append!(t)
sensors 与 tagInfo 进行 equal join 关联查询:
select tagId,datetime,value,machineId,tagName,organization from ej(sensors,tagInfo,`id,`tagid) where machineId in [1,2], datetime between 2020.09.01T00:00:00 : 2020.09.01T00:59:59 order by datetime
结果如下:
tagId
datetime
value
machineId
tagName
organization
1
2020.09.01T00:00:00
95.4607
1
speed
hangzhou
2
2020.09.01T00:00:00
97.5109
1
temperature
hangzhou
51
2020.09.01T00:00:00
67.7972
2
speed
shanghai
52
2020.09.01T00:00:00
76.0762
2
temperature
shanghai
1
2020.09.01T00:00:01
49.3085
1
speed
hangzhou
...
例 2:根据温度异常指标记录表(t1)以及 sensors 表,寻找温度(3 号指标)异常发生时,同一机器的湿度(4 号指标)的最新值。
函数
aj
(asof join) 的常用场景是在时间字段上进行非同时连接,为左表中每条记录,在右表中获取符合指定条件的组中该时刻之前(包括该时刻)的最后一条记录。
在本例中,为了展示 asof join,我们将 sensors 中的数据进行了改动,假设温度异常发生之前,有一段时间内 sensors 表中不存在湿度的数据。
示例代码如下:
t1 = table(3 53 as id, 1 2 as machineId, 2020.09.01T09:56:06 2020.09.01T09:58:12 as datetime, 50.6 50.7 as anomalyMetrics)
t2_1 = select *, 1 as machineId from sensors where id=4, datetime between 2020.09.01T09:00:00 : 2020.09.01T09:54:00
t2_2 = select *, 2 as machineId from sensors where id=54, datetime between 2020.09.01T09:00:00 : 2020.09.01T09:57:00
t2 = unionAll(t2_1, t2_2)
select * from aj(t1, t2, `machineId`datetime);
asof join 和 left join 的区别为:假设连接列是时间,对于左表中时间 t 对应的行,如果右表中没有与之匹配的记录,则取右表中在 t 之前的最近时间对应的行。
例 3:t1 是异常指标记录表,现需要了解异常指标发生时间之前 5 秒钟的原始数据中的指标平均值、最大和最小值。
此场景可使用函数
wj
(window join),为左表中每条记录,在右表中获取符合指定条件的组基于该时刻的指定时间范围的记录并进行计算。示例代码如下:
t1 = table(1 51 as id, 2020.09.01T09:56:06 2020.09.01T09:56:07 as datetime, 50.6 50.7 as anomalyMetrics)
t2 = select * from sensors where id in [1,51], datetime between 2020.09.01T09:00:00 : 2020.09.01T09:59:59
wj(t1, t2, -5000:0, <[avg(value),max(value),min(value)]>, `id`datetime)
例 4:现有一张告警表,记录了设备的当前告警信息。告警后,用户需要对告警进行确认和清除。查询时,需要显示告警信息以及告警状态。
告警表 Alarm 是分布式表,不支持单行更新。因此创建一张告警操作流水表 AlarmAction 记录告警确认和清除信息。每确认或清除一次,往操作流水表中添加一条记录。查询时将告警表和操作流水表通过
lj
关联。示例代码如下:
//创建告警表和告警操作流水表
alarm = table(1:0, `ID`deviceID`time`priority`desc, [UUID,SYMBOL, DATETIME, INT, STRING])
db1 = database(, VALUE, 2020.01.01..2020.12.31)
db2 = database(, HASH, [SYMBOL, 10])
db = database("dfs://demo", COMPO, [db1,db2])
db.createPartitionedTable(alarm, "alarm", `time`deviceID)
alarmAction = table(1:0, `ID`deviceID`time`action`actionTime`user`remark, [UUID,SYMBOL,DATETIME, SYMBOL, DATETIME, SYMBOL, STRING])
db = database("dfs://demo")
db.createPartitionedTable(alarmAction, "alarmAction", `time`deviceID)
//告警表中模拟写入3条记录
alarm = loadTable("dfs://demo","alarm")
action = loadTable("dfs://demo","alarmAction")
t = table([uuid("b9f36c85-43ce-45a3-8427-b3529a6c41cc"),uuid("baba6fe6-67b9-4c18-885a-3fd6edd3002e"),uuid("b510c959-4f9b-4eaf-81a7-ee7e420810c0")] as UUID,"BDSA11_PSCADA" "DMS01" "XKZDEPOT_CCTV_DI20" as deviceID,take(now().datetime(),3) as time,1..3 as priority,"CONN_FAIL" "OFFLINE" "ERROR" as descs)
alarm.append!(t)
//确认2条告警,写入告警操作流水表
arrUUID = uuid(["b9f36c85-43ce-45a3-8427-b3529a6c41cc","baba6fe6-67b9-4c18-885a-3fd6edd3002e"])
tmp = select ID,deviceId, time,"CONFIRM" as action, now().datetime() as actionTime, "admin" as actionUser, "test confirm" as remark from alarm where time > today().datetime(), ID in arrUUID
action.tableInsert(tmp)
//清除1条告警,写入告警操作流水表
tmp = select ID,deviceId, time,"CLEAR" as action, now().datetime() as actionTime, "admin" as actionUser, "test clear" as remark from alarm where time > today().datetime(), ID =uuid("b9f36c85-43ce-45a3-8427-b3529a6c41cc")
action.tableInsert(tmp)
//查询告警信息以及确认、清除信息
t1 = select ID,time, deviceID, actionTime,user as confirmUser, remark as confirmRemark from action where time > today().datetime(), action="CONFIRM"
t2 = select ID, actionTime, user as clearUser, remark as clearRemark from action where time > today().datetime(), action="CLEAR"
tmp = lsj(t1,t2,`ID)
select * from lj(alarm, tmp,`time`deviceId`ID,`time`deviceID`ID) where time > today().datetime()
查询结果如下:
ID
deviceID
time
priority
desc
actionTime
confirmUser
confirmRemark
t2_actionTime
clearUser
clearRemark
b9f...
BDSA11_PSCADA
2020.11.05T17:10:11
1
CONN_FAIL
2020.11.05T17:19:26
admin
test confirm
2020.11.05T17:30:53
admin
test clear
bab...
DMS01
2020.11.05T17:10:11
2
OFFLINE
2020.11.05T17:19:26
admin
test confirm
b51...
XKZDEPOT_CCTV_DI20
2020.11.05T17:10:11
3
ERROR
3.5. 降精度
DolphinDB 支持最高纳秒级精度的时间序列数据,可将高精度大数据集聚合转换成低精度小数据集。支持多种时间精度分组抽样:月(month)、天(date)、分钟 (minute)、秒 (second),以及其他任意时间精度。
例 1:计算一天内指定测点每分钟的平均值。
select avg(value) as avg
from sensors
where id in [1,51,101,151,201], datetime between 2020.09.01T00:00:00 : 2020.09.01T23:59:59
group by id, minute(datetime)
例 2:计算一天内指定测点每 30 秒的平均值。
select avg(value) as avg
from sensors
where id in [1,51,101,151,201], datetime between 2020.09.01T00:00:00 : 2020.09.07T23:59:59
group by id, bar(datetime,30)
例 3:先对每个指定测点求每 10 秒的平均值,再对每测点的平均值结果求最小值。
select min(avg) as minAvg from(
select avg(value) as avg
from sensors
where id in [1,51,101,151,201], datetime between 2020.09.01T00:00:00 : 2020.09.01T00:59:59
group by id, bar(datetime,10)
) group by id
3.6. 插值查询
在物联网领域经常会发生采集的数据缺失。对数据中的空值,DolphinDB 提供了
interpolate
用于插值查询,插值的方式支持:linear(线性插值),pad(使用已有的值填充),nearest(使用最接近 NULL 值的有效值填充)和 krogh(使用 krogh 多项式插值)。
DolphinDB 还提供了以下 4 个填充 NULL 值的函数:向前/向后取非空值(
bfill
/
ffill
),线性填充(
lfill
)和指定值填充(
nullFill
)。用户也可以通过脚本或 C++ 插件扩充新的插值函数。
例 1:使用 ffill 函数进行填充空值。在脚本中,首先制造一分钟的空值。
t = select * from sensors where id=1, datetime between 2020.09.01T00:00:00 : 2020.09.01T00:59:59
update t set value=NULL where datetime between 2020.09.01T00:08:00 : 2020.09.01T00:09:00
update t set value=value.ffill()
例 2:查询一段时间内每分钟的平均值,如果某一分钟内没有原始数据,需要插值。
DolphinDB 从 1.30.7 版本起在 group by 子句中引入了 dummy 函数
interval(X, duration, fill)
来实现插值功能,fill 的方式有 5 种,分别是:prev,缺失值使用前一个值填充;post,缺失值使用后一个值填充;linear,缺失值使用线性插值填充(注意如果列是非数值列,则无法使用线性插值填充,这种情况下会回退到使用 prev 的方式填充);null,缺失值使用 null 值填充;numericValue,以一个指定的 numeric 值来填充。例子如下,插值的方式用了线性插值:
select avg(value) as value
from sensors
where id = 1 and date(datetime)=2020.09.01 group by id, interval(datetime, 1m, "linear")
注意
:1.30.7 前的版本,要用下面的方法实现,先生成时间戳表做为左表,然后用 lsj 连接:
timeRange = 2020.09.01T00:00:00+(0..1439)*60
t = table(timeRange as time,take(1,size(timeRange)) as id)
t1=select avg(value) as value
from sensors
where id = 1 and datetime between 2020.09.01T00:00:00 : 2020.09.01T23:59:59
group by id,bar(datetime,60) as time
delete from t1 where rowNo(id)%2=1 //为了查看插值效果,特意删去t1偶数行
select time,interpolate(value) as value ,t.id from lsj(t,t1,`time)
3.7. 去重
若从设备采集的数据有重复,或者一个时间间隔内有多条记录,但查询时每个时间间隔只需要一条记录,这些场景就需要去除表中的重复记录。DolphinDB 的数据模型支持重复数据,在插入时也不检测重复数据。若要去除分布式表中的重复记录,可以使用 context by 子句去重。
context by 是 DolphinDB 独有的功能,是对标准 SQL 语句的拓展。context by 与 group by 类似,都对数据进行分组,但是使用 group by 时,每一组返回一个标量值,而使用 context by 时,每一组返回一个和组内元素数量相同的向量。context by 与 limit 一起使用能够获取表中每个分组前 n 条记录或最后 n 条记录。用 context by 去重的例子如下:
select * from sensors where id in [1,51,101,151,201], datetime between 2020.09.01T00:00:00 : 2020.09.03T23:59:59 context by id, datetime limit -1
上述代码 limit 后面为负数,表示取每个分组的最后一条记录。
3.8. 函数视图
函数视图是封装了访问数据库以及相关计算语句的自定义函数。它类似关系数据库中的存储过程,可以封装复杂的业务逻辑,方便用户调用。与其他自定义函数会话隔离不同,函数视图可以实现会话之间的共享。函数视图的定义持久化存储在控制节点,因此如果 DolphinDB 集群重启,之前定义的函数视图仍然可以使用。
下面例子使用
addFunctionView
函数定义了一个函数视图 task1。其中先用 pivot by 对指定设备的第 1-6 个指标按分钟分组按列转置,然后对转置后的表进行列名修改,再对每列分别进行计算。
def task1(MachineId){
t=select avg(value) from loadTable("dfs://svmDemo","sensors")
where id in 1..6 + (MachineId-1)*50, datetime >datetimeAdd(now(),-1,`h).datetime()
pivot by datetime.minute() as time, id
t.rename!(`time`tag1`tag2`tag3`tag4`tag5`tag6)
return select time, log(tag1) as target1, sqrt(tag2) as target2, tan(tag3) as target3, sin(tag4) as target4, floor(tag5) as target5, abs(tag6) as target6 from t
}
addFunctionView(task1)
3.9. API 查询数据
DolphinDB 提供 Python, C++, Java, C#, Go, JavaScript, Rust 等常用语言的 API 用于读写数据库。通常数据查询的流程如下:
建立一个连接并登录
通过 run("DolphinDBScript") 运行查询语句查询或 run("DolphinDBFunctionName",args) 运行函数或函数视图查询。
使用 Python API 从分布式表中读取数据的例子如下。其中第一个 run 是运行查询语句,第二个 run 是运行上一小节定义的函数视图:
import
dolphindb
as
ddb
import
pandas
as
pd
s = ddb.session()
try
:
s.connect(
"127.0.0.1"
,
8848
,
"admin"
,
"123456"
)
except
Exception
as
e:
print
e
exit(
1
)
script=
"""
select * from loadTable('dfs://svmDemo','sensors')
where id=1, datetime between 2020.09.01T00:00:00 : 2020.09.03T23:59:59
"""
try
:
t = s.run(script)
print
(t)
t = s.run(
"task1"
,
1
)
print
(t)
except
Exception
as
e:
print
e
注意:
run 方法可接受的脚本最大长度为 65,535 字节。
脚本如果是多行,可以采用三引号的方式将脚本格式化,这样更易于维护。
在 run 前,不需要判断连接是否正常,直接 run 即可。系统会判断有没有连接,若没有,就会自动尝试重连,连不上或执行脚本失败,会抛出异常,因此代码中需要俘获异常并进行处理。
使用 Java API 从分布式表中读取数据的例子如下:
在 Java API 中,数据表保存为 BasicTable 对象。由于 BasicTable 是列式存储,所以若要在 Java API 中读取行数据需要先取出需要的列,再取出行。
public
void
getBasicTable(BasicTable table1)
throws
Exception{
BasicIntVector idVec = (BasicIntVector) table1.getColumn(
"id"
);
BasicDateTimeVector timeVec = (BasicDateTimeVector) table1.getColumn(
"time"
);
BasicFloatVector valueVec = (BasicFloatVector) table1.getColumn(
"value"
);
for
(
int
ri=
0
; ri<table1.rows(); ri++){
System.out.println(idVec.getInt(ri));
LocalDateTime timestamp = timeVec.getDatetime(ri);
System.out.println(timestamp);
System.out.println(valueVec.getDouble(ri));
}
}
DBConnection conn =
new
DBConnection();
try
{
conn.connect(SERVER, PORT, USER, PASSWORD);
BasicTable table1=conn.run(String.format(
"select * from loadTable('%s','%s') where id=1, datetime between 2020.09.01T00:00:00 : 2020.09.07T23:59:59"
,dbPath,tableName);
getBasicTable(table1) ;
}
catch
(IOException e) {
e.printStackTrace();
}
对于返回大结果集的查询,JAVA API 提供了分段读取方法 (此方法仅适用于 DolphinDB 1.20.5 及其以上版本)。即在 run 方法中使用参数 fetchSize 指定分段大小,查询结果保存到 EntityBlockReader 对象,然后通过 read() 方法一段段的读取数据。代码示例如下:
DBConnection conn =
new
DBConnection();
conn.connect(SERVER, PORT, USER, PASSWORD);
EntityBlockReader v = (EntityBlockReader)conn.run(
"select * from loadTable('dfs://svmDemo','sensors') where datetime between 2020.09.01T00:00:00 : 2020.09.07T23:59:59"
,(ProgressListener) null,
4
,
4
,
10000
);
BasicTable data = (BasicTable)v.read();
while
(v.hasNext()){
BasicTable t = (BasicTable)v.read();
data = data.combine(t);
}
在使用上述分段读取的方法时,若数据未读取完毕,需要放弃后续数据的读取时,必须调用 skipAll 方法,否则会导致套接字缓冲区滞留数据,引发后续数据的反序列化失败。正确使用的示例代码如下:
EntityBlockReader v = (EntityBlockReader)conn.run(
"select * from loadTable('dfs://svmDemo','sensors') where datetime between 2020.09.01T00:00:00 : 2020.09.07T23:59:59"
,(ProgressListener) null,
4
,
4
,
10000
);
BasicTable data = (BasicTable)v.read();
v.skipAll();
BasicTable t1 = (BasicTable)conn.run(
"select * from loadTable('dfs://svmDemo','sensors') where datetime between 2020.09.01T00:00:00 : 2020.09.03T23:59:59"
);
//若没有 skipAll 此段会抛出异常。
在 DolphinDB 中,分页查询还可以通过 top 关键字实现,比如查询第 50 到 100 行:
select top 50:100 * from sensors where datetime between 2020.09.01T00:00:00 : 2020.09.03T23:59:59
但这种方法每获取一页都要重新查询一次,效率较低。
有关 API 查询数据更详细的信息,请参阅
Python API
与
JAVA API
等教程。
4. 生产数据写入
DolphinDB 提供 Python, C++, Java, C#, Go, JavaScript, Rust 等常用语言的 API,将从设备采集的数据写入到 DolphinDB 数据库中。DolphinDB 中内存表可以像传统数据库那样利用循环调用 insert into 语句写入数据。对分布式表,DolphinDB 推荐一种更为高效的批量写入数据方式,即将数据组织成一个 table 对象,利用
tableInsert
方式来批量写入。
通常数据写入的流程如下:
1-建立一个连接并登录。
2-将待写入的数据组织成各 API 语言的本地对象。
3-通过连接对象调用 tableInsert 函数,将本地对象上传并写入数据库中。
以下为各 API 的写入示例代码:
4.1. Java API
DBConnection conn =
new
DBConnection();
try
{
conn.connect(SERVER, PORT, USER, PASSWORD);
List<String> colNames = Arrays.asList(
"id"
,
"datetime"
,
"value"
)
ArrayList<Integer> idArray =
new
ArrayList<Integer>(Arrays.asList(
1
,
2
));
ArrayList<Long> datetimeArray =
new
ArrayList<Long>(Arrays.asList(
1600735563458l
,
16007355634582l
));
ArrayList<Double> valueArray =
new
ArrayList<Double>(Arrays.asList(
22.3
,
43.1
));
List<Vector> cols = Arrays.asList(
new
BasicIntVector(idArray),
new
BasicTimestampVector(datetimeArray),
new
BasicDoubleVector(valueArray));
BasicTable data =
new
BasicTable(colNames,cols);
List<Entity> args =
new
ArrayList<Entity>(
1
);
args.add(data);
conn.run(String.format(
"tableInsert{loadTable('%s','%s')}"
,dbPath,tableName), args);
}
catch
(IOException ex){
ex.printStackTrace();
}
4.2. C# API
DBConnection conn =
new
DBConnection();
try
{
conn.connect(SERVER, PORT, USER, PASSWORD);
List<String> colNames =
new
List<
string
>() {
"id"
,
"datetime"
,
"value"
};
List<
int
> idArray =
new
List<
int
>() {
1
,
2
};
List<
long
> datetimeArray =
new
List<
long
>() {
1600735563458
,
16007355634582
};
List<Double> valueArray =
new
List<Double>() {
22.3
,
43.1
};
List<IVector> cols =
new
List<IVector>() {
new
BasicIntVector(idArray.ToArray()),
new
BasicTimestampVector(datetimeArray.ToArray()),
new
BasicDoubleVector(valueArray.ToArray()) };
BasicTable data =
new
BasicTable(colNames, cols);
List<IEntity> args =
new
List<IEntity>(
1
);
args.Add(data);
conn.run(String.Format(
"tableInsert{{loadTable('{0}','{1}')}}"
,
"dfs://svmDemo"
,
"sensors"
), args);
}
catch
(IOException ex)
{
Console.WriteLine(ex.StackTrace);
}
4.3. Python API
s = ddb.session()
s.connect(SERVER, PORT, USER, PASSWORD)
data = {
'id'
: np.array([
1
,
2
], dtype=np.int32),
'datetime'
: np.array([
1600735563458
,
16007355634582
]),
'value'
: np.array([
22.3
,
43.1
])}
try
:
s.run(
"tableInsert{{loadTable('{db}', `{tb})}}"
.format(db=dbPath,tb=tableName), pd.DataFrame(data))
except
Exception
as
e:
print
e
4.4. C++ API
TableSP createDemoTable(long rows) {
vector<string> colNames = {"id","time","value"};
vector<DATA_TYPE> colTypes = {DT_INT, DT_DATETIME, DT_FLOAT};
int colNum = 3, rowNum = rows, indexCapacity = rows;
ConstantSP table =
Util::createTable(colNames, colTypes, rowNum, indexCapacity);
vector<VectorSP> columnVecs;
for (int i = 0; i < colNum; i++)
columnVecs.push_back(table->getColumn(i));
for ( int i = 0; i < rowNum; i++) {
columnVecs[0]->setInt(i, i % 500 +1);
columnVecs[1]->setInt(i, Util::getEpochTime()/1000);
columnVecs[2]->setFloat(i, 1.0);
}
return table;
}
DBConnection conn;
try {
bool ret = conn.connect(hString, pLong, "admin", "123456");
if (!ret) {
cout << "Failed to connect to the server" << endl;
return 0;
}
} catch (exception &ex) {
cout << "Failed to connect with error: " << ex.what();
return -1;
}
TableSP table = createDemoTable(cLong, sLong, 1);
vector<ConstantSP> args;
args.push_back(table);
try {
conn.run("tableInsert{loadTable('dfs://svmDemo', `sensors)}", args);
} catch (exception &ex) {
cout << "Failed to run with error: " << ex.what();
}
C++ API 读写 Vector、Table 等数据类型有多种方法,不同场景不同的读写方法有较大的性能差异,详情请参阅
C++ API 数据读写指南
。
4.5. 提升写入性能
API 的写入性能的优化主要可通过以下几个方面:
批量写入:每次组织大批量数据写入能够有效提升性能。
并行写入:将不同分区的数据,分多个任务并行写入。
DolphinDB 的最小存储单元是分区,同一个分区不允许多个线程同时写入,否则会抛出异常。所以在并行写入时,需要考虑将数据按分区进行分流,避免同时向一个分区写入数据。具体多线程写入的实现案例请参阅
C++ 多线程并行写入示例代码
。
异步写入:异步写入在写入时不需要等待 server 回复确认消息,可显著提高连续写入的速度,适用于对写入速度要求高但可靠性要求不苛刻的场景。使用异步写入的方法是在声明 DBConnection 类变量的时候,置 enableAYSN 参数值为 true 即可。适用于 DolphinDB 1.10.17、1.20.6 及以上 linux64 版本。
4.6. 提升数据压缩比
DolphinDB 压缩算法支持压缩效果和解压缩时间综合性能较高的 LZ4 和 DELTA 算法。系统默认使用 LZ4 压缩算法,时间/日期类型或者相邻数据变化较小的整型建议采用 DELTA 算法。DolphinDB 采用增量压缩策略,每次对新增数据进行压缩。对小批量写入的场景,DolphinDB 提供了写入缓存(Cache Engine)机制。写完 WAL 之后,数据写入缓存,到达一定阈值以后,开始异步将缓存中的数据写入磁盘中。这相当于把少量多次的写入变成了批次写入,不仅能提升写入性能,也能提高压缩率。
文件
compressDemo.tar.bz2
保存了从一个地震计采集的某分量一天的实际数据。数据分三个字段:tagId,标签标识,值都是 1;time 时间戳,每个间隔 10 毫秒;data,采用值,是相邻数据变化较小的整数。下面测试了用 2 种算法,每批写入不同记录数时它们压缩后的字节数。未启用写入缓存机制,测试结果如下:
每批写入记录数
tagId 用 LZ4
tagId 用 DELTA
time 用 LZ4
time 用 DELTA
data 用 LZ4
data 用 DELTA
10
15,528,746
24,155,816
45,994,143
31,057,472
37,596,365
31,047,336
100
1,639,168
3,105,776
35,960,194
3,795,960
27,385,932
11,447,608
10,000
150,136
1,100,840
34,870,756
1,138,784
24,756,356
9,546,840
100,000
145,647
1,094,972
34,863,223
1,118,460
24,782,836
9,540,884
8,627,069
144,304
1,093,160
34,862,003
1,116,356
24,787,171
9,539,072
启用写入缓存机制,测试结果如下:
每批写入记录数
tagId 用 LZ4
tagId 用 DELTA
time 用 LZ4
time 用 DELTA
data 用 LZ4
data 用 DELTA
10
146,337
1,093,420
34,863,946
1,118,788
24,782,183
9,541,456
100
144,532
1,093,176
34,862,534
1,116,636
24,787,829
9,539,412
10,000
144,337
1,093,168
34,862,092
1,116,372
24,786,148
9,539,120
100,000
144,312
1,094,972
34,862,011
1,116,364
24,787,179
9,539,080
8,627,069
144,312
1,093,168
34,862,011
1,116,356
24,787,171
9,539,080
从测试结果可以发现,这个数据集的标签标识用 LZ4 算法、时间戳和采样值用 DELTA 算法压缩压缩效果较好。若标签标识用 LZ4 算法、时间戳和采样值用 DELTA 算法压缩,时间戳和采样值两个字段的综合压缩比达到 10:1,标签标识、时间戳和采样值三个字段的综合压缩比达到 13:1。在未启用写入缓存(Cache Engine)机制时,随着每批写入记录数越多,压缩效果越好。启用写入缓存机制后,小批量写入也能达到与大批量写入同样的压缩效果。
测试脚本
下载
。
5. 实时数据和流计算
DolphinDB 提供了流数据表 (stream table) 和流计算引擎用于实时数据处理。内置流计算框架目前已支持
时序聚合引擎
、
横截面聚合引擎
、
异常检测引擎
和自定义流计算引擎。
时序聚合引擎 (Time-series Aggregator):能对设备状态进行纵向聚合计算(按时间序列聚合),或者将多个设备状态横向聚合后再按时间聚合。时序聚合支持滑动窗口的流式计算。DolphinDB 对内置的窗口聚合函数均进行了性能优化,单核 CPU 每秒可完成近百万状态的时序聚合。
横截面聚合引擎 (Cross-sectional Aggregator):是快照引擎的扩展,对设备状态进行横向聚合计算,比如计算一批设备的最新温度均值。
异常检测引擎 (Anomaly Detection Engine):能实时检测数据是否符合用户自定义的警报指标,如发现异常数据,将它们输出到表中,满足物联网实时监控和预警的需求。
自定义流计算引擎:当以上三种引擎都不能满足需求时,用户也可以使用 DolphinDB 脚本或 API 语言自定义消息处理函数。
5.1. 数据写入流数据表
在 DolphinDB 中执行如下脚本定义流数据表:
t = streamTable(1:0,`id`datetime`value,[INT,DATETIME,FLOAT]);
enableTableShareAndPersistence(table=t, tableName =`iot_stream, cacheSize=1000000, preCache=0)
5.2. API 写入
使用 API 写入流数据表与写入分布式表的方法非常相似,不同的地方主要有两点:一是流数据表与分布式数据库不同,流数据表的数据类型需要用户保证一致,不会自动转换;二是流数据表没有分区概念,多线程可以同时写入。
当用户写入的数据与流数据表的定义结构不一致需要转换时,通常可以通过自定义写入函数来实现。比如写入数据的时间戳是长整型表示的值,而 DolphinDB 字段是 Datetime 类型,这个转换可以用一个自定义写入函数来完成,在下例中用 java 代码来展示,其他语言的 API 也支持用同样的方式实现。
在 java 环境中写入 dolphindb 的示例代码如下:
DBConnection conn =
new
DBConnection();
try
{
conn.connect(
"localhost"
,
8848
,
"admin"
,
"123456"
,
"def saveData(iot_stream, data){t = select id, datetime(timestamp(datetime)) as datetime,value from data;iot_stream.tableInsert(t)}"
);
List<String> colNames = Arrays.asList(
"id"
,
"datetime"
,
"value"
);
ArrayList<Integer> idArray =
new
ArrayList<Integer>(Arrays.asList(
1
,
2
));
ArrayList<Long> datetimeArray =
new
ArrayList<Long>(Arrays.asList(
1600735563458l
,
16007355634582l
));
ArrayList<Double> valueArray =
new
ArrayList<Double>(Arrays.asList(
22.3
,
43.1
));
List<Vector> cols = Arrays.asList(
new
BasicIntVector(idArray),
new
BasicTimestampVector(datetimeArray),
new
BasicDoubleVector(valueArray));
BasicTable data =
new
BasicTable(colNames, cols);
List<Entity> args =
new
ArrayList<Entity>(
1
);
args.add(data);
conn.run(
"saveData{iot_stream}"
, args);
}
catch
(IOException ex){
ex.printStackTrace();
}
DolphinDB 支持通过插件从 opc 和 mqtt 服务器获取数据。
对于常用插件,建议在节点配置文件中通过 preloadModules 方式预加载,这样节点启动后在脚本中可以直接使用插件,无需再调用 loadPlugin。
preloadModules=plugins::opc,plugins::mqtt
以下代码是 DolphinDB 脚本调用 OPC UA 插件来订阅 opc server 数据:
loadPlugin("/plugins/opcua/PluginOPCUA.txt") //预加载可省略
conn = opcua::connect(EndpointUrl,"myclient")
opcua::subscribe(conn, 3, ["Counter","Expression","Random","Sawtooth"],iot_stream)
以下代码是 DolphinDB 脚本调用 mqtt 插件来订阅 mqtt server 数据:
loadPlugin("/plugins/mqtt/PluginMQTTClient.txt") //预加载可省略
p = createCsvParser([INT, TIMESTAMP, FLOAT], ',', ';' )
conn = mqtt::subscribe("127.0.0.1",1883,"sensor/#", p, iot_stream)
上述插件均使用了后台任务的方式订阅数据,后台任务在调用订阅函数
subscribe
启动,运行在服务器上。通过
unsubscribe
函数可终止订阅任务。
5.3. 使用内置计算引擎
DolphinDB 提供了时序聚合引擎和横截面聚合引擎来配合流数据订阅处理实时数据。通过订阅将实时数据写入聚合引擎,然后由聚合引擎输出计算结果。
这里我们通过一个例子来展示如何使用聚合引擎来做实时计算。通常分为如下几个步骤:
根据计算的业务需求选择合适的聚合引擎。
根据聚合引擎定义结果输出表。
根据需求设定订阅过滤器,仅订阅计算所需的数据。
比如下例中使用了 Speed 类测点的数据,假设一共 100 个设备,每一个设备 50 个测点,其中 1 号测点是 speed,那么在订阅时可以使用 DolphinDB 脚本:filter = (0..99)*50+1 以设定 filter[1,51,101,151...]。
通过
subscribeTable
设立流数据订阅以及写入聚合引擎的规则。
数据进入流数据表后触发订阅及聚合引擎计算。
5.3.1. 时序聚合引擎:每秒钟计算风机过去 5 分钟的实时转数均值、最大值、最小值与方差。
share streamTable(10000:0, `time`id`avgSpeed`minSpeed`maxSpeed`stdSpeed, [DATETIME, INT,DOUBLE, DOUBLE,DOUBLE,DOUBLE]) as outputTable1
model = table(1:0,`id`datetime`value,[INT,DATETIME,FLOAT])
speedAggregator = createTimeSeriesAggregator(name="speedAggregator", windowSize=300, step=1, metrics=<[avg(value), max(value), min(value), std(value)]>, dummyTable=model, outputTable=outputTable1,timeColumn= `datetime,keyColumn= `id)
subscribeTable(tableName="iot_stream", actionName="speed_calc", offset=0,handler= append!{speedAggregator}, msgAsTable=true)
时序聚合引擎的更多信息请参阅
流数据时序聚合引擎
。
5.3.2. 横截面聚合引擎:计算当前所有风机的平均转速与最大最小转速差。
share table(1:0, `time`avgSpeed`spanSpeed, [TIMESTAMP,DOUBLE,DOUBLE]) as outputTable2
model = table(1:0,`id`datetime`value,[INT,DATETIME,FLOAT])
speedCrossAggregator=createCrossSectionalAggregator(name="speedCrossAggregator",metrics=<[avg(value), max(value)-min(value)]>,dummyTable=model,outputTable=outputTable2, keyColumn=`id, triggeringPattern=`perRow)
subscribeTable(tableName="iot_stream",actionName="speedCrossAggregator",offset=0,handler=append!{speedCrossAggregator}, msgAsTable=true)
横截面聚合引擎的更多信息请参阅
流数据横截面聚合引擎
。
5.4. 异常检测引擎:实时转速超出 10,或低于 0.1,以及转速差超出 0.2 时,输出异常信号。
用户只需指定异常指标,异常检测引擎就可以实时地进行异常数据检测并输出信号。
share streamTable(1000:0, `time`anomalyType`anomalyString, [DATETIME, INT, SYMBOL]) as outputTable3
model = table(1:0,`id`datetime`value,[INT,DATETIME,FLOAT])
engine = createAnomalyDetectionEngine(name="engine1", metrics=<[value > 10, value < 0.1, abs(deltas(value))>0.2]>, dummyTable=model, outputTable=outputTable3,timeColumn=`datetime,windowSize=6, step=3)
异常检测引擎的更多信息,请参阅
流数据异常检测引擎
和
流计算引擎实现传感器数据异常检测
。
5.5. 自定义计算引擎
除了内置的聚合引擎之外,
subscribeTable
函数的 handler 可以指定任意一个自定义函数作为消息处理函数,例如:当风机的 5 分钟转速均值超出一个阈值时,需要邮件告警并采取人工介入,那么可以通过实时自定义函数来达到这一目标。对于阈值设定,系统中有一个表 (threshold) 来保存每类指标的阈值。
category
max
min
SPD
25
10
PRS
2.2
0.8
ELE
3.7
0.2
在前述案例中,通过时序聚合引擎已经得到了过去 5 分钟的转速均值指标输出到 outputTable1,可以直接订阅 outputTable1 表来获得 5 分钟均值。当检测到超限数据时,利用 DolphinDB 的 httpClient 插件,可以发送告警到邮件或到其他消息平台。
def alertHandler(userId, pwd, msg){
try(loadPlugin("plugins/httpclient/PluginHttpClient.txt")) catch(ex){}
threshold = select first(max), as max, first(min) as min from loadTable("dfs://thresholdDB","threshold") where category=="SPD"
max = threshold.max[0]
min = threshold.min[0]
overLimited = select Id, avgSpeed from msg where avgSpeed >max or avgSpeed < min
if(overLimited.size()>0){
httpClient::sendEmail(userId,pwd,"[email protected]", "转速超限告警" , string(overLimited))
}
}
subscribeTable(, "outputTable1", "alertSub", -1, alertHandler{userId, pwd}, true)
注意:订阅的 handler 必须是一个一元函数,仅接受一个 msg 参数 (msg 即订阅到的实时数据),若函数有多个参数,需要将除 msg 之外的参数通过部分应用来固化,生成一个符合要求的一元函数。
6. 高可用测试
DolphinDB 支持高可用,多个元数据节点和多个数据副本之间保证强一致性。DolphinDB 的高可用机制包括:
数据高可用。DolphinDB 采用多副本机制,相同数据块的副本存储在不同的数据节点上。一个数据库可以包含上百万个分区,分区的多副本之间使用改良的二阶段提交协议实现分区副本的强一致性。当分区副本数为 N 的时候,在 N-1 个节点宕机的情况下,保证系统可以持续写入和读取。分区的多副本之间没有采用 Raft 协议,主要是考虑到:(1)DolphinDB 集群是为海量数据设计的,单个集群可以支持千万级以上分区数,使用 Raft 和 Paxos 等算法创建千万级的协议组,成本太高;(2)使用 Raft 和 Paxos 等算法,查询数据时只有一个副本可用,对于 OLAP 应用场景来说过于浪费资源;(3)写入的数据如果跨分区,即使采用了 Raft 和 Paxos 等算法,仍然需要二阶段提交协议保证事务的 ACID。
元数据高可用。DolphinDB 的元数据存储在控制节点上。为了保证元数据的高可用,DolphinDB 通过配置多个控制节点来组成一个 Raft 组。组内节点采用 Raft 协议实现强一致性。Raft 组中只有一个 Leader,其他都是 Follower,Leader 和 Follower 上的元数据保持强一致性。数据节点只能和 Leader 进行交互。如果当前 Leader 不可用,Raft 组会立即选举出新的 Leader 来提供元数据服务。Raft 组能够容忍小于半数的控制节点宕机。
客户端高可用。DolphinDB API 提供了自动重连和切换机制。使用 API 与 DolphinDB 的数据节点交互时,如果连接的数据节点宕机,API 会先尝试重连,若重连失败会自动切换连接到集群中其他可用的数据节点,继续执行未完成的任务。切换连接数据节点对用户是透明的。
6.1. 数据高可用测试
要使用数据高可用功能,至少需要 2 台物理服务器部署 DolphinDB 集群,每台部署 2 个数据节点。集群部署请参考
多服务器集群部署教程
。其中副本的个数在 controller.cfg 中配置。例如,把副本数设置为 2:
dfsReplicationFactor=2
默认情况下,DolphinDB 允许相同数据块的副本分布在同一台机器上。为了保证数据高可用,需要把相同数据块的副本分布在不同的机器上。请在 controller.cfg 添加以下配置项:
dfsReplicaReliabilityLevel=2
这里设置 dfsReplicaReliabilityLevel=2,即在资源允许情况下,副本优先部署在多台物理服务器。若集群中服务器台数大于副本数时,可设置 dfsReplicaReliabilityLevel=1。
使用 API 与数据节点进行交互时,如果连接的数据节点宕机,API 会尝试重连,若重连失败会自动切换到其他可用的数据节点。这对用户是透明的。目前 Java、C#、C++ 和 Python API 支持高可用。以下例子设置 Java API 高可用:
import com.xxdb;
DBConnection conn = new DBConnection();
String[] sites=["115.239.209.228:21142", "115.239.209.228:21143", "115.239.209.224:21142", "115.239.209.224:21143"]
boolean success = conn.connect(host="115.239.209.228", port=21142, userid="admin", password="123456", highAvailability=True, highAvailabilitySites=sites)
如果数据节点 115.239.209.228:21142 宕机,API 会自动连接到其他可用的数据节点。
6.2. 元数据高可用测试
6.2.1. 环境部署
要使用元数据高可用功能,至少需要三台物理服务器,每台部署一个控制节点(controller),一个代理节点(agent)和"cpp_data_io.md" node)。具体部署请参阅
高可用集群部署教程
,配置两个副本,其他主要配置如下:
agent.cfg 文件中配置
mode =agent
localSite=192.168.1.13:22215:agent2
controllerSite=192.168.1.12:22216:controller1
sites=192.168.1.13:22215:agent2:agent,192.168.1.12:22216:controller1:controller,192.168.1.13:22216:controller2:controller,192.168.1.14:22216:controller3:controller
lanCluster=0
chunkCacheEngineMemSize=4
cluster.cfg 文件中配置
lanCluster=0
maxPubConnections=64
maxMemSize=16
workerNum=4
newValuePartitionPolicy=add
chunkCacheEngineMemSize=4
controller.cfg 文件中配置
mode=controller
localSite=192.168.1.13:22216:controller2
dfsReplicationFactor=2
dfsReplicaReliabilityLevel=1或dfsReplicaReliabilityLevel=2
dfsHAMode=Raft
dataSync=1
maxConnections=128
maxMemSize=16
webWorkerNum=4
workerNum=4
节点配置信息 cluster.nodes 如下
localSite,mode
192.168.1.12:22216:controller1,controller
192.168.1.13:22216:controller2,controller
192.168.1.14:22216:controller3,controller
192.168.1.12:22215:agent1,agent
192.168.1.13:22215:agent2,agent
192.168.1.14:22215:agent3,agent
192.168.1.12:22217:NODE1,datanode
192.168.1.12:22218:NODE2,datanode
192.168.1.13:22217:NODE2241,datanode
192.168.1.13:22218:NODE2242,datanode
192.168.1.14:22217:NODE2281,datanode
192.168.1.14:22218:NODE2282,datanode
~
API 中启用高可用,配置要切换的节点见如下所示 sites 字符串变量:
String[] sites={"192.168.1.12:22217", "192.168.1.12:22218", "192.168.1.13:22217", "192.168.1.13:22218", "192.168.1.14:22217", "192.168.1.14:22218"}
s.connect(host="192.168.1.12", port=21117, userid="admin", password="123456", highAvailability=True, highAvailabilitySites=sites)
6.2.2. 测试步骤
测试步骤参考如下:
序号
测试步骤
预期结果
是否符合预期
原因
1
启动集群的所有节点
所有都节点正常能启动,浏览器打开 controller 面板,显示 leader 为 controller1(若不为 controller1,多次重启使其为 controller1)
符合
Raft 组中只有一个 Leader,其他都是 Follower
2
API 连接节点,创建 1000 个分区的分布式表并开始持续读写,前 1000 次每次同时向每个已存在分区和一个新分区添加一组数据并读取总行数,之后每次随机向分区写入共 10000 条数据
API 成功连接到 controller1 的数据节点,创建数据表并开始读写,正确打印总行数,副本存储在不同节点上
符合
3
在前 1000 次读写时,关闭正在读写的 NODE1
API 成功连接到 NODE2241,继续开始读写,写入的新分区副本不存在 NODE1 上
符合
使用 API 与 DolphinDB 的数据节点交互时,如果连接的数据节点宕机,API 会先尝试重连,若重连失败会自动切换连接到集群中其他可用的数据节点,继续执行未完成的任务。
4
前 1000 次内重启 NODE1
NODE1 上的副本恢复。新的分区副本可以放在 NODE1 里
符合
副本之间保持强一致性,只要数据库存在一个副本,就可以恢复
5
一段时间后,前 1000 次内关闭 controller1
leader 切换到 controller2(或 controller3,后面步骤假设为 controller2),数据停顿几秒后继续读写,不影响 NODE1 和 NODE2 使用
符合
由于数据节点和代理节点正常,因此还可以正常读写,但是由于采用 Raft 协议,Raft 组会立即选举出新的 Leader 来提供元数据服务,因此 leader 变成 controller2
6
重启 controller1
对数据读写没有影响,leader 仍然是 controller2
符合
7
一段时间后关闭 controller2
leader 切换回 controller1,数据停顿几秒后继续读写
符合
同 5
8
重启 controller2
对数据读写没有影响,leader 仍然是 controller1
符合
9
关闭 NODE1 和 NODE2
节点切换到 NODE2281,继续读写
符合
由于在不同机器上存储数据副本,即使一台服务器节点失效,访问其他机器上的副本也可以数据服务
10
关闭 controller1
leader 切换到 controller2
符合
11
打开 NODE1 和 NODE2
leader 不变,NODE1 和 NODE2 上数据恢复
符合
12
重启 controller1
leader 不变,数据读写没有影响
符合
13
长时间持续的数据读写后,重复以上步骤
结果相同
符合
示例 Java API 代码
下载
。
6.3. 跨机房容灾
跨机房异步容灾组网架构如下图:
主备系统部署方案:
主备系统分别部署在两个不同的机房,配置相同,流数据表以及 DFS 数据库参数配置一致,主系统、备系统都保存所有的历史数据;流数据表为键值流数据表,该表的主键不允许包含重复值。
正常情况下,数据源写入主系统流数据表;备系统从主系统订阅流数据。
读数据库数据的客户端程序启动时,配置主备两个 IP 地址和端口组,启动时优先连接主系统,当主系统宕机时,自动切换到备系统读取数据。
主系统宕机后,数据源写入备系统。备系统停止从主系统订阅流数据,备系统变为主系统。
原主系统宕机后系统恢复流程:
检测到主系统在运行,将自己降为备系统。
从主系统订阅流数据,以同步数据。
同步完数据后,再主备切换。
6.4. 数据备份和恢复
6.4.1. 数据备份
DolphinDB 提供了
backup
函数对分布式数据库进行备份。备份是以分区为单位进行的,可对指定数据表的部分或全部分区进行备份,支持全量备份与增量备份。
备份需要指定存放备份文件的路径 backupDir 与数据(用 SQL 语句表示)。备份后,系统会在
<backupDir>/<dbName>/<tbName>
目录下生成元数据文件_metaData.bin 和数据文件.bin,每个分区备份为一个数据文件。
例如备份 2020.09.01 到 2020.09.03 这三天的数据:
backup(backupDir="/hdd/hdd1/backup/"+today().format("yyyyMMdd"),sqlObj=<select * from loadTable("dfs://svmDemo","sensors") where datetime between 2020.09.01T00:00:00 : 2020.09.03T23:59:59 >,force=false,parallel=true)
备份后,登录服务器,用 tree 命令列出目录的内容如下。从中可以看到,备份目录下根据数据库名和表名生成了 2 层子目录 svmDemo/sensors,在其下还有 1500 个分区数据文件和 1 个元数据文件_metaData:
[dolphindb@cnserver3 ~]$ tree /hdd/hdd1/backup/2020.09.20 -L 3
/hdd/hdd1/backup/2020.09.20
└── svmDemo
└── sensors
├── 001f4f62-7a7c-ecbc-a74c-edbfe071c358
├── 0023a6f3-84d6-8fa0-354b-8b97b4024e9a
├── 004c4795-3f7d-a3be-ec45-06089ab723ef
├── dolphindb.lock
├── e0363761-7f9a-5fa5-8f4a-c0cfff1749a6
...
├── fec45f79-8163-a587-644d-2f260a9e358e
└── _metaData
2 directories, 1502 files
若要每天备份,可用定时作业来实现,下面的例子每天 00:05:00 备份前一天的数据:
login(`admin,`123456)
scheduleJob(`backupJob, "backupDB", backup{"/hdd/hdd1/backupDemo/"+(today()-1).format("yyyyMMdd"),<select * from loadTable("dfs://svmDemo","sensors") where datetime between datetime(today()-1) : (today().datetime()-1) >,false,true}, 00:05m, today(), 2030.12.31, 'D');
6.4.2. 数据恢复
DolphinD 提供两种数据恢复的方法:
使用
migrate
函数
使用
restore
函数
两者的主要区别为:
migrate
函数以表为单位恢复,可以批量恢复多个表的全部数据,而
restore
函数以分区为单位恢复,每次恢复一个表中部分或全部分区的数据。
migrate
函数无需用户创建新数据库,系统会自动创建新数据库,而
restore
需要用户先建库建表。
下面的例子恢复 2020 年 9 月份的数据到原表,其中备份文件是上一小节的定时作业按天生成:
day=2020.01.01
for(i in 1:31){
path="/hdd/hdd1/backupDemo/"+temporalFormat(day, "yyyyMMdd") + "/";
day=datetimeAdd(day,1,`d)
if(!exists(path)) continue;
print "restoring " + path;
restore(backupDir=path,dbPath="dfs://svmDemo",tableName="sensors",partition="%",force=true);
}
下面的例子把 2020 年 9 月份的数据恢复到一个新的数据库 dfs://db1 和表 sensors,其中先用
migrate
恢复第一天的数据,然后用
migrate
把剩余备份数据恢复到临时表,再导入 sensors:
migrate(backupDir="/hdd/hdd1/backupDemo/20200901/",backupDBPath="dfs://svmDemo",backupTableName="sensors",newDBPath="dfs://db1",newTableName="sensors")
day=2020.09.02
newTable=loadTable("dfs://db1","sensors")
for(i in 2:31){
path="/hdd/hdd1/backupDemo/"+temporalFormat(day, "yyyyMMdd") + "/";
day=datetimeAdd(day,1,`d)
if(!exists(path)) continue;
print "restoring " + path;
t=migrate(backupDir=path,backupDBPath="dfs://svmDemo",backupTableName="sensors",newDBPath="dfs://db1",newTableName="tmp")
if(t['success'][0]==false){
print t['errorMsg'][0]
continue
}
newTable.append!(select * from loadTable("dfs://db1","tmp") where datetime between datetime(day-1) : (day.datetime()-1) > )
database("dfs://db1").dropTable("tmp")
}
FILE:references/doc_3593.md
# bondAccrInt
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bondaccrint.html
**来源**: DolphinDB 官方文档
---
bondAccrInt
语法
bondAccrInt(start, maturity, issuePrice, coupon, frequency,
dayCountConvention, bondType, settlement, [benchmark='Excel'])
别名:
fiAccrInt
详情
计算债券的应计利息(Accrued Interest)。应计利息是指债券自上一次付息日至交易结算日之间累积的未付利息。
应计利息(Accrued Interest)常用来计算净价(Clean Price)。相关计算公式为:净价(Clean Price)= 全价(Dirty Price)-
应计利息(Accrued Interest)。
参数
注意:所有输入向量必须等长,输入标量将自动扩展以匹配其它向量的长度。
start
DATE 类型标量或向量,表示债券的起息日。
maturity
与
start
等长的 DATE 类型标量或向量,表示债券的到期日。
issuePrice
与
start
等长的数值型标量或向量,表示债券的发行价格。贴现债需指定真实发行价(通常小于100);其他债券通常为100。
coupon
数值型标量或向量,表示债券的票面利率。例如 0.03,表示票息为 3%。
frequency
整型或 STRING 类型的标量或向量,表示债券的付息频率。可选值为:
0/“Once”:到期一次还本付息
1/“Annual”:每年付息一次
2/“Semiannual:每半年付息一次
4/“Quarterly”:每季度付息一次
12/“Monthly”:每月付息一次
dayCountConvention
STRING 类型的标量或向量,表示债券的计息日数惯例。可选值为:
"Thirty360US":US (NASD) 30/360
"ActualActualISMA":实际/实际(ISMA 规则)
"Actual360":实际/360
"Actual365":实际/365
"Thirty360EU":欧洲 30/360
"ActualActualISDA":实际/实际(ISDA 规则)
bondType
STRING 类型标量或向量,表示债券的类型。可选值为:
"FixedRate":固定利率债券,定期按息票利率支付利息。
"Discount":贴现债券,没有利息支付,以贴现方式发行的债券,期末FV=面值。
"ZeroCoupon":零息债券,期末一次性支付利息和面值,期末FV=面值+利息。
settlement
DATE 类型标量或向量,表示债券的结算日,即购买日期。
benchmark
可选参数,STRING 类型标量,表示算法参考基准。目前仅支持 “Excel”(excel
中的算法)。
返回值
DOUBLE 类型标量或向量。
例子
假设有一张面值为 1000 的债券,购买日期为 2024 年 1 月 1 日,到期日期为 2030 年 12 月 31 日,年息票利率为 10%,每年付息 2
次(半年付息),以 US (NASD) 30/360 为日计数基准。
bondAccrInt(start=2024.01.01, maturity=2030.12.31, issuePrice=100, coupon=0.1, frequency=2, dayCountConvention="Thirty360US", bondType="FixedRate", settlement=2024.05.15)
// output: 3.75
相关函数
:
bondCalculator
FILE:references/doc_3597.md
# bar
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bar.html
**来源**: DolphinDB 官方文档
---
bar
语法
bar(X, interval, [closed='left'])
相关函数:
dailyAlignedBar
详情
bar
基于
interval
指定的长度,根据分组计算公式,对
X
进行分组。
参数
X
是一个整型/时间类型的标量或向量。
interval
是一个大于0的整型/DURATION 类型的标量或和
X
长度相同的向量。
interval
是 DURATION 类型时,支持以下时间单位(区分大小写):w, d, H, m, s, ms,
us, ns。
注:
由于
interval
不支持年(y)和月(M)的时间单位,如果需要对
X
以年或月进行分组时,可以调用
year
或
month
对
X
进行转换后,指定
interval
为整数进行计算。可以参考例2。
closed
字符串,可选值为 'left' 或 'right'。 表示
X
中可被
interval
整除的元素,归为某个分组的左边界(即该组第一个元素,此时
closed
=‘left’),还是归为某个分组的右边界(即该组最后一个元素,此时
closed
=‘right’)。
对应的分组计算公式为:
closed
= 'left'时,
X
-(
X
%
interval
),表示将余数为 0 的值作为一个分组的左边界。
closed
= 'right'时,iif((
X
%
interval
) == 0,
X
,
X
+ (
interval
-(
X
%
interval
))),表示将余数为 0
的值作为一个分组的右边界。
返回值
返回一个和
X
具有相同长度的向量。
例子
例1.
bar(100,3); // 100-(100%3)=100-1=99
// output
99
bar(0..15, 3)
// output
[0,0,0,3,3,3,6,6,6,9,9,9,12,12,12,15]
x=[7,4,5,8,9,3,3,5,2,6,12,1,0,-5,32]
bar(x, 5)
// output
[5,0,5,5,5,0,0,5,0,5,10,0,0,-5,30]
t=table(2021.01.01T01:00:00..2021.01.01T01:00:29 as time, rand(1.0, 30) as x)
select max(x) from t group by bar(time,5s)
bar_time
max_x
2021.01.01T01:00:00
0.539024
2021.01.01T01:00:05
0.793327
2021.01.01T01:00:10
0.958522
2021.01.01T01:00:15
0.96987
2021.01.01T01:00:20
0.827086
2021.01.01T01:00:25
0.617353
例2. 以3个月进行分组,需要将
bar
函数中的
X
转为月份:
t=table(take(2018.01.01T01:00:00+1..10,10) join take(2018.02.01T02:00:00+1..10,10) join take(2018.03.01T08:00:00+1..10,10) join take(2018.04.01T08:00:00+1..10,10) join take(2018.05.01T08:00:00+1..10, 10) as time, rand(1.0, 50) as x)
select max(x) from t group by bar(month(time), 3);
bar
max_x
2018.01M
0.9868
2018.04M
0.9243
例3. 将日期按照周分组,计算每周的最大值。根据
closed
不同,计算结果有所区别。
t=table(2022.01.01 + 1..20 as time, rand(100, 20) as x)
time
x
2022.01.02
6
2022.01.03
29
2022.01.04
71
2022.01.05
56
2022.01.06
93
2022.01.07
34
2022.01.08
77
2022.01.09
18
2022.01.10
62
2022.01.11
33
2022.01.12
34
2022.01.13
64
2022.01.14
80
2022.01.15
63
2022.01.16
17
2022.01.17
66
2022.01.18
85
2022.01.19
27
2022.01.20
77
2022.01.21
27
select max(x) from t group by bar(time, 7d);
bar_time
max_x
2021.12.30
71
2022.01.06
93
2022.01.13
85
2022.01.20
77
print select max(x) from t group by bar(time, 7d, closed='right');
bar_time
max_x
2021.01.06
93
2022.01.13
77
2022.01.20
85
2022.01.27
27
例4. 计算分钟 k 线时,n 需要转换为 NANOTIMESTAMP,此时若使用整型计算可能造成类型溢出,需要将数据类型转换成
LONG。
n = 1000000
nano = (09:30:00.000000000 + rand(long(6.5*60*60*1000000000), n)).sort!()
price = 100+cumsum(rand(0.02, n)-0.01)
volume = rand(1000, n)
symbol = rand(`600519`000001`600000`601766, n)
tradeNano = table(symbol, nano, price, volume).sortBy!(`symbol`nano)
undef(`nano`price`volume`symbol)
barMinutes = 7
itv = barMinutes*60*long(1000000000)
OHLC_nano=select first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume from tradeNano group by symbol, bar(nano, itv) as barStart
FILE:references/doc_3603.md
# businessYearBegin
**URL**: https://docs.dolphindb.cn/zh/funcs/b/businessYearBegin.html
**来源**: DolphinDB 官方文档
---
businessYearBegin
语法
businessYearBegin(X, [startingMonth=1], [offset],
[n=1])
详情
返回最近一个小于等于
X
的年度首个工作日(周一到周五)。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
年更新一次。注意,
offset
和
n
须同时指定,且只有当
n
> 1时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
startingMonth
是1到12之间的整数,表示一年的起始月份。默认值是1。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
businessYearBegin(2012.06.12);
// output
2012.01.02
businessYearBegin(2022.01.01);
// output
2021.01.01
businessYearBegin(2012.06.13 10:10:10.008,5);
// output
2012.05.01
date=2011.10.25 2012.10.25 2013.10.25 2014.10.25 2015.10.25 2016.10.25 2017.10.25 2018.10.25 2019.10.25 2020.10.25
time = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12,09:38:13]
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
select avg(price),sum(qty) from t1 group by businessYearBegin(date,1,2011.10.01,2)
businessYearBegin_date
avg_price
sum_qty
2011.01.03
39.53
4100
2013.01.01
29.77
5300
2015.01.01
175.1
12200
2017.01.02
50.54
3800
2019.01.01
51.835
13300
相关函数:
businessYearEnd
,
yearBegin
,
yearEnd
FILE:references/doc_3610.md
# cdfUniform
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfUniform.html
**来源**: DolphinDB 官方文档
---
cdfUniform
语法
cdfUniform(lower, upper, X)
详情
返回均匀分布的累计密度函数的值。
参数
lower
和
upper
是数值型标量,表示连续均匀分布的下限和上限。
X
是数值型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfUniform(0.627, 2.31, [0.001, 0.5, 0.999]);
// output
[0, 0, 0.221034]
cdfUniform(0.627, 2.31, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output
[0, 0, 0, 0.043375, 0.16221]
FILE:references/doc_3611.md
# moveChunksAcrossVolume
**URL**: https://docs.dolphindb.cn/zh/funcs/m/moveChunksAcrossVolume.html
**来源**: DolphinDB 官方文档
---
moveChunksAcrossVolume
注:
此函数将于近期版本中废弃,推荐使用函数
moveReplicas
实现相关功能。
语法
moveChunksAcrossVolume(srcPath, destPath, chunkIds,
[isDelSrc=true])
详情
将一个磁盘卷 chunks 文件转移至指定的路径。
isDelSrc
= true 时,源路径下的 chunks
被成功转移后,将被删除;否则,仍被保留。如果转移失败,保留源路径下的所有 chunks,清空目标路径下已经拷贝完成的文件。
注意:
只能在同一个节点下进行 chunks 文件的转移。
进行该操作前,需要停止写入,保证所有事务都已完成,并将所有缓冲区的数据刷入磁盘。
配置项
volumes
必须包含
srcPath
和
destPath
指定路径所在的磁盘卷,且该配置已经生效(修改配置项后重启使其生效)。
destPath
指定的 chunks 目录必须为空目录。
参数
srcPath
是一个字符串,格式如:
"volumeA/CHUNKS"
。表示源 chunks 的路径。
destPath
是一个字符串,格式如:
"volumeB/CHUNKS"
。表示要转移到的目的 chunks 的路径。
chunkIds
是一个字符串或者字符串向量。表示需要移动的 chunks 的 id 值。
isDelSrc
布尔值,默认为 true。表示拷贝后是否删除源 chunks。
注:
srcPath
、
destPath
和
chunkIds
可以通过
getChunksMeta
获取。
FILE:references/doc_3612.md
# derivative
**URL**: https://docs.dolphindb.cn/zh/funcs/d/derivative.html
**来源**: DolphinDB 官方文档
---
derivative
语法
derivative(func, X, [dx =1.0], [n=1], [order=3])
详情
返回函数
func
在
X
位置的
n
阶导数值。
参数
func
是一元函数。
X
是数值型标量或向量,表示求导位置。
dx
是数值型的标量,表示求导间隔。
dx
默认值是1.0,取值范围为大于0的浮点数。
n
是整型的标量,表示导数的阶数。
n
的默认是1。当前函数仅支持计算1阶导数。
order
是整型的标量,表示选取点的数量。
order
必须是奇数,默认值是3,取值范围为[3, 1023]。
返回值
DOUBLE 类型标量或向量。
例子
derivative(acos, 0.458, 1e-3);
// output
-1.12492
a=[0.25, -4.53, 1.85, 12.45, 2.0];
derivative(cbrt, a, 1e-3, 1, 5);
// output
[0.83995,0.121753,0.221189,0.062053,0.209987]
derivative(pow{3,}, 5);
// output
324
FILE:references/doc_3615.md
# aggrTopN
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/aggrTopN.html
**来源**: DolphinDB 官方文档
---
aggrTopN
语法
aggrTopN(func, funcArgs, sortingCol, top, [ascending=true])
详情
将
sortingCol
根据
ascending
指定方式进行排序后,得到
funcArgs
中对应的前
top
个元素,使用
func
指定的聚合函数进行计算。
sortingCol
包含的 NULL 值当作最小值处理。
参数
func
必须是一个聚合函数。
funcArgs
是
func
的参数,可以是标量或向量。
func
有多个参数时,它是一个元组。
sortingCol
是一个数值类型或时间类型的向量,提供
funcArgs
的排序指标。
top
可以是整数或者浮点数。
如果是整数,表示选取的前
top
行数据;
如果是浮点数,表示百分比,必须小于1.0。根据
funcArgs
的总行数
top
来确定需要选取的行数。若结果不是整数,则向下取整,至少取一行。
ascending
是一个布尔值,表示是否按升序排序。 默认值是 true。
其他相关 TopN 系列函数参数说明和窗口计算规则请参考:
TopN
返回值
一个数值型标量。
例子
aggrTopN(func=sum, funcArgs=1 2 3 4 5, sortingCol=5 1 2 3 4, top=3, ascending=false)
// output
10
aggrTopN(func=corr,funcArgs=[1..5, 3 9 4 2 5], sortingCol=2 3 4 5 3, top=3)
// output
0.052414
top
=3,aggrTopN严格取前3个元素进行计算,下例中有3个3对应第三位,只取满足
top
数量的值进行计算
aggrTopN(func=min,funcArgs=1 6 4 -6 4 5, sortingCol=2 3 3 3 4 5, top=3)
// output
1
计算每个股票每天最大交易量前25%的交易平均价格。
t = table(`A`A`A`B`B`B`B`B`B`B`B as sym, 09:30:06 09:30:28 09:31:46 09:31:59 09:30:19 09:30:43 09:31:23 09:31:56 09:30:44 09:31:25 09:31:57 as time, 10 20 10 30 20 40 30 30 30 20 40 as volume, 10.05 10.06 10.07 10.05 20.12 20.13 20.14 20.15 20.12 20.13 20.16 as price);
t;
sym
time
volume
price
A
09:30:06
10
10.05
A
09:30:28
20
10.06
A
09:31:46
10
10.07
B
09:31:59
30
10.05
B
09:30:19
20
20.12
B
09:30:43
40
20.13
B
09:31:23
30
20.14
B
09:31:56
30
20.15
B
09:30:44
30
20.12
B
09:31:25
20
20.13
B
09:31:57
40
20.16
select aggrTopN(func=avg, funcArgs=price, sortingCol=volume, top=0.25, ascending=false) from t group by sym, time
sym
time
aggrTopN_avg
A
09:30:06
10.05
A
09:30:28
10.06
A
09:31:46
10.07
B
09:30:19
20.12
B
09:30:43
20.13
B
09:30:44
20.12
B
09:31:23
20.14
B
09:31:25
20.13
B
09:31:56
20.15
B
09:31:57
20.16
B
09:31:59
10.05
FILE:references/doc_3618.md
# reorderColumns!
**URL**: https://docs.dolphindb.cn/zh/funcs/r/reorderColumns_.html
**来源**: DolphinDB 官方文档
---
reorderColumns!
语法
reorderColumns!(table, reorderedColNames)
详情
调整表中各列的顺序。该命令直接在原有的表中修改,不会产生新的表。
参数
table
是一个没有被共享的内存表。
reorderedColNames
是一个字符串向量,表示调整顺序后的列名。此参数中只需写出表中发生顺序改变的列以及所有在其之前的列名。例如,将表中第3列于第6列的位置对换,则此参数只需写出前6列的列名。
返回值
返回一个表。
例子
sym = `C`MS`MS`MS`IBM`IBM`C`C`C
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t = table(timestamp, sym, qty, price);
t;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
reorderColumns!(t,`sym`timestamp`price`qty)
t;
sym
timestamp
price
qty
C
09:34:07
49.6
2200
MS
09:36:42
29.46
1900
MS
09:36:51
29.52
2100
MS
09:36:59
30.02
3200
IBM
09:32:47
174.97
6800
IBM
09:35:26
175.23
5400
C
09:34:16
50.76
1300
C
09:34:26
50.32
2500
C
09:38:12
51.29
8800
reorderColumns!(t,`timestamp`sym);
t;
timestamp
sym
price
qty
09:34:07
C
49.6
2200
09:36:42
MS
29.46
1900
09:36:51
MS
29.52
2100
09:36:59
MS
30.02
3200
09:32:47
IBM
174.97
6800
09:35:26
IBM
175.23
5400
09:34:16
C
50.76
1300
09:34:26
C
50.32
2500
09:38:12
C
51.29
8800
FILE:references/doc_3636.md
# mavg
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mavg.html
**来源**: DolphinDB 官方文档
---
mavg
语法
mavg(X, window|weights, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
计算滑动窗口内的移动平均值。支持按固定窗口长度或指定权重向量进行计算。
window
:在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
元素的平均值。
weights
:表示权重向量,用于在长度为 size(
weights
)的滑动窗口中计算
X
的加权平均值。权重顺序与窗口中数据一一对应。size(
weights
) 的有效范围是[0,
1024]。结果中前(size(
weights
) - 1)个元素为 NULL。若指定了
weights
,则
minPeriods
无效。
若
X
为矩阵/表则在每一列进行计算。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
当
X
为向量时:返回与
X
长度相同的向量。
若
X
为矩阵/表,返回与输入具有相同维度的矩阵或表。
例子
X = 7 4 6 0 -5 32 9 8;
Y = 7 4 6 NULL -5 32 9 8;
weight = 2 3 5
mavg(X, 4);
// output: [,,,4.25,1.25,8.25,9,11]
mavg(Y, 4);
// output: [,,,5.67,1.67,11,12,11]
mavg(Y, weight);
// output: [,,5.6,5.2,-1.8571,18.125,13.1,13.1]
m=matrix(1 NULL 4 NULL 8 6 , 9 NULL NULL 10 NULL 2)
m.rename!(2020.01.06 2020.01.07 2020.01.09 2020.01.11 2020.01.12 2020.01.15, `col1`col2)
m.setIndexedMatrix!()
mavg(m, 3d) // 等价于 mavg(m, 3)
label
col1
col2
2020.01.06
1
9
2020.01.07
1
9
2020.01.09
4
2020.01.11
4
10
2020.01.12
8
10
2020.01.15
6
2
mavg(m, 1w)
label
col1
col2
2020.01.06
1
9
2020.01.07
1
9
2020.01.09
2.5
9
2020.01.11
2.5
9.5
2020.01.12
4.3333
9.5
2020.01.15
6
6
相关函数:
avg
FILE:references/doc_3642.md
# isYearEnd
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isYearEnd.html
**来源**: DolphinDB 官方文档
---
isYearEnd
语法
isYearEnd(X)
详情
判断
X
是否为年末最后一天。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
返回值
布尔标量或向量。
例子
isYearEnd(2012.12.31);
// output: true
isYearEnd([2012.12.30,2012.12.31]);
// output: [false,true]
相关函数:
isYearStart
FILE:references/doc_3649.md
# format
**URL**: https://docs.dolphindb.cn/zh/funcs/f/format.html
**来源**: DolphinDB 官方文档
---
format
语法
format(X, format)
详情
把指定格式应用到给定对象。
根据输入对象的数据类型,
format
函数调用
decimalFormat
或
temporalFormat
。
有关从数字向指定格式字符串的转换,参考(表中的备注列,请参考
decimalFormat
):
标志
含义
备注
0
强制数字位数
备注1
#
可选数字位数
备注2
.
小数点
%
百分号
备注3
E
科学计数法的符号
备注4
,
分隔符
备注5
;
表示正数和负数的符号
备注6
有关 DolphinDB 时序对象的格式,参考:
格式
含义
范围
yyyy
年份(4个数字)
1000-9999
yy
年份(2个数字
00-99. (00-39: 2000-2039; 40-99: 1940-1999)
MM
月份
1-12
MMM
月份
JAN, FEB, ... DEC (不区分大小写)
dd
日期
1-31
HH
时(24小时制)
0-23
hh
时(12小时制)
0-11
mm
分钟
0-59
ss
秒
0-59
aa
上午/下午
AM, PM. (不区分大小写)
SSS
毫秒
0-999
nnnnnn
微秒
0-999999
nnnnnnnnn
纳秒
0-999999999
参数
X
可以是标量或向量。
format
是表示
X
格式的字符串。
返回值
字符串标量或向量。
例子
t = table(1..100 as id, (1..100 + 2018.01.01) as date, rand(100.0, 100) as price, rand(10000, 100) as qty);
t;
id
date
price
qty
1
2018.01.02
70.832104
1719
2
2018.01.03
12.22557
6229
3
2018.01.04
8.695886
1656
4
2018.01.05
24.324535
2860
5
2018.01.06
0.443173
6874
6
2018.01.07
90.302176
3277
7
2018.01.08
78.556843
3424
8
2018.01.09
45.836447
8636
9
2018.01.10
57.416425
707
10
2018.01.11
98.879764
2267
...
select id, date.format("MM/dd/yyyy") as date, price.format("00.00") as price, qty.format("#,###") as qty from t;
id
date
price
qty
1
01/02/2018
70.83
1,719
2
01/03/2018
12.23
6,229
3
01/04/2018
08.70
1,656
4
01/05/2018
24.32
2,860
5
01/06/2018
00.44
6,874
6
01/07/2018
90.30
3,277
7
01/08/2018
78.56
3,424
8
01/09/2018
45.84
8,636
9
01/10/2018
57.42
707
10
01/11/2018
98.88
2,267
...
FILE:references/doc_3659.md
# normal
**URL**: https://docs.dolphindb.cn/zh/funcs/n/normal.html
**来源**: DolphinDB 官方文档
---
normal
是
norm
的别名。
FILE:references/doc_366.md
# last
**URL**: https://docs.dolphindb.cn/zh/funcs/l/last.html
**来源**: DolphinDB 官方文档
---
last
语法
last(X)
或
last X
详情
返回向量的最后一个元素,或矩阵、表的最后一行。
注:
若向量的最后一个元素为 NULL,则返回 NULL。若要返回最后一个非 NULL 的元素,请使用
lastNot
函数。
参数
X
可以是标量、向量、矩阵或表。
返回值
如果
X
是一个标量/向量,返回一个标量。
如果
X
是一个矩阵,返回一个向量。
如果
X
是一张表,返回一张表。
例子
last(`hello `world);
输出返回:world
last(1..10);
输出返回:10
m = matrix(1 2 3, 4 5 6);
m;
输出返回:
#0
#1
1
4
2
5
3
6
last(m);
输出返回:[3,6]
相关函数:
first
FILE:references/doc_3670.md
# weekOfMonth
**URL**: https://docs.dolphindb.cn/zh/funcs/w/weekOfMonth.html
**来源**: DolphinDB 官方文档
---
weekOfMonth
语法
weekOfMonth(X, [week=0], [weekday=0], [offset],
[n=1])
详情
返回
X
所在月份或上一个月中第
week
个
weekday
对应的日期。假设
X
所在月份的第
week
个
weekday
对应日期为 d:
如果
X
<
d
,
weekOfMonth
函数返回
X
的上一个月中第
week
个
weekday
对应的日期。
如果
X
>=
d
,
weekOfMonth
函数返回
X
所在月份的第
week
个
weekday
对应的日期。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
个月更新一次。注意,只有当
n
>1时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
week
是0到3的整数,表示第几个星期。默认值为0。
weekday
是0到6之间的整数,表示星期编号。0表示星期一,1表示星期二,... ,6表示星期日。默认值为0。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
一个 DATE 类型的标量或向量。
例子
weekOfMonth(2019.11.01,2,4);
// output
2019.10.18
//2019年11月的第三个星期五为2019.11.15,2019.11.01在2019.11.15之前,因此返回2019年10月的第三个星期五
weekOfMonth(2019.11.20,2,4);
2019.11.15
date=2012.01.02 2012.02.03 2012.03.07 2012.04.08 2012.05.12 2012.06.16 2012.07.18 2012.08.20 2012.09.25 2012.10.28
time = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12,09:38:13]
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
select avg(price),sum(qty) from t1 group by weekOfMonth(date,3,4,2012.01.01,2);
weekOfMonth_date
avg_price
sum_qty
2011.12.23
39.53
4100
2012.02.24
29.77
5300
2012.04.27
175.1
12200
2012.06.22
50.54
3800
2012.08.24
51.29
8800
2012.10.26
52.38
4500
FILE:references/doc_3682.md
# min
**URL**: https://docs.dolphindb.cn/zh/funcs/m/min.html
**来源**: DolphinDB 官方文档
---
min
语法
min(X, [Y])
详情
返回输入数据中的最小值。
支持以下两种调用方式:
仅输入一个参数
X
,用于计算
X
的最小值。比较时忽略 NULL 值。
输入两个参数,用于按元素比较两个数据对象,返回较小值。比较时不忽略 NULL 值。
请注意,从 2.00.8 版本开始,min 处理时间类型数据的行为(之前版本统一转换为长整型)修改为:
若
X
和
Y
是时间类型标量,系统会将时间类型统一为两者中较高精度对应的类型,再比较大小。
若
X
或
Y
是向量、矩阵或表,则必须具有相同的时间类型。
参数
X
可以是标量、向量、矩阵或表。
Y
为可选参数,可以是标量或者是和
X
长度相同的向量或者矩阵。
返回值
单参数调用:
若
X
是向量,返回一个标量。
若
X
为矩阵,返回一个向量。
若
X
为表,返回一个表。
双参数调用:
若
Y
是标量,返回与
X
维度相同的对象,每个元素为
min(X[i], Y)
。
若
Y
和
X
类型和长度一致,返回对应位置较小值组成的对象。
例子
min(1 2 3);
// output
1;
min(2.0 1.1 0.1 NULL);
// output
0.1
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
min(m);
// output
[1,4]
min(1 2 3, 2)
// output
1 2 2
n = matrix(1 1 1, 5 5 5)
n;
#0
#1
1
5
1
5
1
5
min(m, n);
#0
#1
1
4
1
5
1
5
min
可以搭配 select 使用, 返回某列的最小值:
t = table(`abb`aac`aaa as sym, 1.8 2.3 3.7 as price);
select min price from t;
min_price
1.8
min
可以应用于字符串,返回字典序最小的字符串:
select min sym from t;
min_sym
aaa
相关函数:
mmin
FILE:references/doc_3687.md
# easyNSQ 实时行情数据接入功能模块
**URL**: https://docs.dolphindb.cn/zh/modules/easyNSQ/easynsq.html
**来源**: DolphinDB 官方文档
---
easyNSQ 实时行情数据接入功能模块
为了实时获取 level-2 行情数据,DolphinDB 对接恒生 NSQ 极速行情服务软件,开发了能够获取上海和深圳市场行情数据的 NSQ 插件。安装好插件后,用户需要创建用于接收实时数据的持久化共享流表和分区表,并且发起相关订阅。为了方便用户快速搭建 NSQ 实时行情数据的流计算环境,DolphinDB 开发了 DolphinDBModules::easyNSQ 模块(简称 easyNSQ 模块),主要用于 NSQ 实时行情数据的自动化接收和存储。目前已经支持的数据源包括上海和深圳市场的:
现货逐笔委托行情主推回调(OnRtnSecuTransactionEntrustData->orders)
现货逐笔成交行情主推回调(OnRtnSecuTransactionTradeData->trade)
现货深度行情主推回调(OnRtnSecuDepthMarketData->snapshot)
注意
:DolphinDB 仅提供对接 HSNsqApi 的 NSQ 插件,数据源和接入服务可咨询数据服务商或证券公司。
NSQ 插件的版本支持情况请参考
插件市场下载页
。本模块基于 DolphinDB 2.00.11 版本开发,请在使用本模块时确保安装了 2.00.11 及以上版本的 DolphinDB server。
1. 安装说明
使用 DolphinDBModules::easyNSQ 模块前,请确保在 DolphinDB 服务器上正确安装和加载了 NSQ 插件和 DolphinDBModules::easyNSQ 模块文件。
注意
:对于之前从未使用过 DolphinDB 插件和模块功能的读者,推荐在阅读以下章节的同时阅读
DolphinDB NSQ 行情插件文档
以及
DolphinDB 模块说明
。
easyNSQ 模块依赖于 NSQ 插件,
请确保先加载 NSQ 插件,再加载 easyNSQ 模块
。
1.1 安装 NSQ 插件
在线安装插件
用户可以通过 DolphinDB 官方的插件市场在线安装 NSQ 插件,具体操作步骤如下:
在 DolphinDB 客户端(DolphinDB GUI、Web 页面或者 Vscode 插件)中运行
listRemotePlugins
函数,查看插件市场中与当前 DolphinDB server 适配的 NSQ 插件及其版本信息。
listRemotePlugins("nsq")
该函数执行后会返回一个如下的表。
图 1-1 listRemotePlugins 函数的返回结果示例
使用
installPlugin
函数从插件市场下载并安装 NSQ 插件。
installPlugin("nsq")
该函数会在安装完成后返回插件的安装路径。
图 1-2 installPlugin 函数的返回结果示例
离线安装插件
如果 DolphinDB server 所在机器与插件市场的网络不互通,用户还可以选择使用离线方式安装 NSQ 插件。
根据 DolphinDB server 版本和及其所在机器的操作系统,从
DolphinDB 插件市场
或者
Github
和
Gitee
下载 NSQ 插件。注意,如果从 Github 或 Gitee 代码仓库下载 NSQ 插件,部分版本可能需要用户自行编译,插件编译的步骤可以参考
此文档
。
将 NSQ 插件的所有文件(包括动态库文件)放到 DolphinDB server 所在机器的该路径下:
/DolphinDB/server/plugins/nsq
。
若使用 Linux 系统,还需要将 NSQ 插件的路径添加到 Linux 环境变量,然后重启 DolphinDB:
export LD_LIBRARY_PATH=/DolphinDB/server/plugins/nsq/:$LD_LIBRARY_PATH
1.2 加载 NSQ 插件
手动加载插件
安装 NSQ 插件完之后,可以使用
loadPlugin
函数加载插件。任意会话中成功加载插件,即可在当前 server 节点的其他会话中使用插件。若 DolphinDB server 重启,则需要重新加载插件。
2.00.11 及以上版本的 server,支持使用插件名来加载插件。
loadPlugin("nsq")
也可以使用插件描述文件的绝对路径来加载插件。
loadPlugin("/DolphinDB/server/plugins/nsq/PluginNsq.txt")
若插件加载成功,该函数会返回一个包含所有插件函数的向量。
图 1-3 loadPlugin 函数的返回结果示例
自动预加载插件
DolphinDB server 启动后,插件只需加载一次就会一直生效,但是如果 server 重启就需要重新加载插件。为了避免重复手动加载插件的麻烦,DolphinDB 提供了自动预加载插件的功能。可以通过配置项
preloadModules
指定系统启动后自动加载的插件或模块。
在配置文件
dolphindb.cfg
中加上:
preloadModules=plugins::nsq
然后启动 DolphinDB,系统自动会到
/DolphinDB/server/plugins/
目录下加载 NSQ 插件。
验证加载
可以运行以下代码来验证 NSQ 插件加载成功:
defs("nsq::%")
以上代码用于查询 DolphinDB 系统中 ”nsq“ 命名空间的函数,插件加载成功会返回如下列表:
图 1-4 defs 函数的返回结果示例
1.3 安装 easyNSQ 模块
以 Linux 单节点为例,将模块文件拷贝到
/DolphinDB/server/modules/
目录下,即模块脚本
easyNSQ.dos
的路径应为
/DolphinDB/server/modules/DolphinDBModules/easyNSQ.dos 。
模块文件安装好,运行以下代码加载模块:
use DolphinDBModules::easyNSQ
如果没有返回错误信息,则说明 easyNSQ 模块已经成功加载。
安装插件时常见的错误信息如下:
插件与 DolphinDB server 版本不匹配,需要改用适配 server 版本的插件:
The first line must be the module name, dynamic library file name and version, separated by comma
或
Failed to loadPlugin file [...] for the plugin version [...] is not same to the server version [...]
没有将 NSQ 插件的路径添加到 Linux 环境变量,需要添加环境变量再重启 DolphinDB server :
Couldn't load the dynamic library [.../libPluginNsq.so]: libHSNsqApi.so: cannot open shared object file: No such file or directory [...]
如果遇到其他问题,可以在社区中交流或者联系 DolphinDB 的技术支持工程师。
2. 使用示例
第一步:
按照上一章节的说明,安装并加载 NSQ 行情插件和 easyNSQ 模块。
第二步
:准备好 NSQ 行情数据服务器配置文件
sdk_config.ini
,上传到 DolphinDB server 所在的服务器上。下图中,配置文件放置在
server/plugins/nsq/
路径。
图 2-1 server/plugins/ 文件结构示例
第三步
:打开浏览器,在地址栏输入 DolphinDB server 的 IP 地址与端口号,连接到该节点的 Web 管理页面。点击右上角的用户按钮进行登录。
图 2-2 DolphinDB Web 管理页面示例
第四步
:在交互编程页面,执行以下脚本订阅行情数据和落库存储:
// 加载插件
try{ loadPlugin("nsq") } catch(ex) { print(ex) }
go
// 调用模块
use DolphinDBModules::easyNSQ
// nsq 行情配置文件路径
configFilePath = "<your_path_to>/nsq_sdk_config.ini";
// nsq 账号(可选参数)
nsq_username = "<your_nsq_username>";
nsq_password = "<your_nsq_password>";
// 数据接收选项(可选参数)
nsq_data_option = dict(STRING, ANY)
nsq_data_option["receivedTime"]=true // 在行情数据中增加一列接收时间
nsq_data_option["getAllFieldNames"]=true // 接受 nsq 原始行情中所有字段
// 初始化环境
iniNsqEnv()
iniNsqDfs()
// 建立对沪深交易所L2快照、逐笔委托和逐笔成交行情数据的订阅,接收数据后自动落库存储
subscribeNsq(configFilePath, "orders", ["sh","sz"], merge=true, saveToDfs=true, options=nsq_data_option, username=nsq_username, password=nsq_password)
subscribeNsq(configFilePath, "trade", ["sh","sz"], merge=true, saveToDfs=true, options=nsq_data_option, username=nsq_username, password=nsq_password)
subscribeNsq(configFilePath, "snapshot", ["sh","sz"], merge=true, saveToDfs=true, options=nsq_data_option, username=nsq_username, password=nsq_password)
/*
// 不使用 nsq 账号和数据接收选项的订阅方式
subscribeNsq(configFilePath, "orders", ["sh","sz"], merge=true, saveToDfs=true)
subscribeNsq(configFilePath, "trade", ["sh","sz"], merge=true, saveToDfs=true)
subscribeNsq(configFilePath, "snapshot", ["sh","sz"], merge=true, saveToDfs=true)
*/
第五步
:查询订阅状态
使用插件函数
nsq::getSubscriptionStatus()
可以获取 NSQ 行情的订阅状态。
nsq::getSubscriptionStatus()
图 2-3 nsq::getSubscriptionStatus 函数的返回结果示例
第六步
:查询流数据表。
(1)逐笔委托
select * from nsqStockOrdersStream limit 10
图 2-4 逐笔委托流表的查询结果示例
(2)逐笔成交
select * from nsqStockTradeStream limit 10
图 2-5 逐笔成交流表的查询结果示例
(3)L2 快照
select * from nsqStockSnapshotStream limit 10
图 2-6 L2 快照流表的查询结果示例
第七步
:查询分区表
(1)逐笔委托
select * from loadTable("dfs://nsqStockOrders", "orders") limit 10
图 2-7 逐笔委托分区表的查询结果示例
(2)逐笔成交
select * from nsqStockTradeStream limit 10
图 2-8 逐笔成交分区表的查询结果示例
(3)L2 快照
select * from loadTable("dfs://nsqStockSnapshot", "snapshot") limit 10
图 2-9 L2 快照分区表的查询结果示例
3. 实时行情数据存储说明
3.1 接收行情数据到流数据表
图 3-1 easyNSQ 模块接收行情数据到流数据表
用户指定希望接收的行情数据源(逐笔委托、逐笔成交或 L2 快照),easyNSQ 模块会根据用户的需要创建不同的持久化共享流表,并通过 NSQ 插件订阅交易所数据,将上海和深圳市场的实时行情数据写入持久化共享流表中。
持久化共享流表是进行共享并做了持久化处理的流数据表。将流表共享是为了让该流表在连接当前节点其它会话中也可见。比如通过 C++ API 实时查询流数据表的会话与定义流表的会话不会是同一个,如果不将流表共享,查询的需求就无法实现。
对流数据表进行持久化的目的主要有以下两点:
控制该表的最大内存占用。通过设置
enableTableShareAndPersistence
函数中的
cacheSize
参数,可以控制流表在内存中最多保留多少条记录,超出的部分被写入持久化数据文件、从内存中清除,进而控制该表的最大内存占用。
在节点异常关闭的极端情况下,可以从持久化数据文件中恢复已经写入流数据表但是未消费的数据,保证流数据“至少消费一次”的需求。
流数据表持久化采用异步的方式进行,对流表写入吞吐量几乎没有影响。
注意
:
虽然名字里带有“持久化”,但是持久化流表并不能满足行情数据持久化存储的需求。
首先,流数据表持久化到磁盘上的数据的规模在增长到一定大小,或者超过一定时间之后,会触发系统的回收校验,并不能做到真正的永久化存储。
其次,流数据表持久化到磁盘上的数据并没有进行结构化的存储,查询和更新的效率比不上在分区表中存储的数据,不适合用于实际生产环境。
如果用户有将行情数据在磁盘上进行持久化存储的需求,请阅读本篇文档
2.2
及
2.3
小节的方案说明。
用户可以为这些持久化的共享流表指定名字,也可以选择使用模块默认的表名。在用户没有指定表名的情况下,模块对持久化共享流表的命名如下:
上交所逐笔委托:流表名称为 ”nsqStockOrdersSHStream“。
深交所逐笔委托:流表名称为 ”nsqStockOrdersSZStream"。
上交所逐笔成交:流表名称为 “nsqStockTradeSHStream"。
深交所逐笔成交:流表名称为 ”nsqStockTradeSZStream"。
上交所 L2 所快照:流表名称为 “nsqStockSnapshotSHStream"。
深交所 L2 所快照:流表名称为 ”nsqStockSnapshotSZStream“。
基于过往项目的实践,推荐如下的持久化共享流表参数配置方案:
配置项
配置值
asynWrite
true
compress
true
cacheSize
500,000
preCache
100,000
retentionMinutes
1440
flushMode
0
3.2 接收行情数据到流数据表,并持久化到分区表
图 3-2 easyNSQ 模块接收行情数据到流数据表,并持久化到分区表
easyNSQ 模块还支持将实时行情数据写入分区表进行持久化的存储。在此种订阅模式下,用户指定希望接收的行情数据源(逐笔委托、逐笔成交或 L2 快照),easyNSQ 模块会通过 NSQ 插件订阅交易所数据,将上海和深圳市场的实时行情数据分别写入持久化共享流表,然后通过 DolphinDB 内置的订阅-发布功能,将流表的增量数据实时写入分区表。
用户可以指定用于存储行情数据的数据库和分区表的名字。在用户没有指定数据库和分区表名字的情况下,模块会使用默认名字的数据库和分区表:
上交所逐笔委托:数据库名称为 "dfs://nsqStockOrders",分区表名称为 "ordersSH"。
深交所逐笔委托:数据库名称为 "dfs://nsqStockOrders",分区表名称为 "ordersSZ"。
上交所逐笔成交:数据库名称为 "dfs://nsqStockTrade",分区表名称为 "tradeSH"。
深交所逐笔成交:数据库名称为 "dfs://nsqStockTrade",分区表名称为 "tradeSZ"。
上交所 L2 所快照:数据库名称为 "dfs://nsqStockSnapshot",分区表名称为 "snapshotSH"。
深交所 L2 所快照:数据库名称为 "dfs://nsqStockSnapshot",分区表名称为 "snapshotSZ"。
细心的读者已经注意到 easyNSQ 模块会将同一行情数据源的数据放在同一个数据库中,比如上交所逐笔委托和深交所逐笔委托数据都会存储在数据库 "dfs://nsqStockOrders"。这样的做法,部分是出于业务逻辑的考虑,即后续往往会对上交所和深交所的逐笔委托数据进行同样的处理操作;此外,NSQ 插件已经对上海和深圳市场的行情数据表结构做了统一处理,上交所和深交所的数据适用于同一套数据库分区规则,可以存储在同一个数据库中。
注意
:
出于数据安全的考虑,easyNSQ 模块在存储数据到分区表的过程中,如果发现要做写入的分区表不存在,会创建新分区表;如果发现同名分区表已存在,会直接向该分区表写入数据,而不是进行删除和重新创建。
因此,用户在使用 easyNSQ 模块时,需要注意:如果已存在分区表的表结构与行情数据结构不同,写入数据的时候就会抛出异常。建议用户使用 easyNSQ 模块时,在订阅行情数据前对用于行情数据入库存储的分区表进行检查。
基于过往项目的实践,对分区表确定了如下的分区方案:
行情数据类型
分区方案
分区列
排序列
逐笔委托(orders)
组合分区:时间维度按天分区 + 证券代码维度 HASH 25 分区
TradeDate + InstrumentID
InstrumentID + TransactTime
逐笔成交(trade)
组合分区:时间维度按天分区 + 证券代码维度 HASH 25 分区
TradeDate + InstrumentID
InstrumentID + TransactTime
L2 快照(snapshot)
组合分区:时间维度按天分区 + 证券代码维度 HASH 25 分区
TradeDate + InstrumentID
InstrumentID + UpdateTime
3.3 合并存储上海和深圳市场行情数据
图 3-3 easyNSQ 模块对沪深市场的行情数据进行合并处理
easyNSQ 模块支持将上海和深圳市场的实时行情数据进行合并处理。用户可以指定用于接收实时数据的流数据表的名字,以及用于存储行情数据的数据库和分区表的名字。在用户没有进行指定的情况下,模块会使用默认的名字:
逐笔委托:流表名称为 ”nsqStockOrdersStream“, 数据库名称为 "dfs://nsqStockOrders",分区表名称为 "orders"。
逐笔成交:流表名称为 ”nsqStockTradeStream“,数据库名称为 "dfs://nsqStockTrade",分区表名称为 "trade"。
L2 所快照:流表名称为 ”nsqStockSnapshotStream“,数据库名称为 "dfs://nsqStockSnapshot",分区表名称为 "snapshot"。
对于沪深行情数据合并存储,持久化共享流表的参数配置方案同沪深行情分开存储的参数配置方案。而分区表的分区方案如下:
行情数据类型
分区方案
分区列
排序列
逐笔委托(orders)
组合分区:时间维度按天分区 + 证券代码维度 HASH 50 分区
TradeDate + InstrumentID
InstrumentID + TransactTime
逐笔成交(trade)
组合分区:时间维度按天分区 + 证券代码维度 HASH 50 分区
TradeDate + InstrumentID
InstrumentID + TransactTime
L2 快照(snapshot)
组合分区:时间维度按天分区 + 证券代码维度 HASH 50 分区
TradeDate + InstrumentID
InstrumentID + UpdateTime
4. easyNSQ 模块接口介绍
4.1 subscribeNsq
语法
easyNSQ::subscribeNsq(configFilePath, dataSource, [markets], [merge], [saveToDfs], [streamTableNames],
[dbPath], [tableNames], [options], [username], [password])
参数
configFilePath
:一个字符串,表示 NSQ 行情服务器配置文件
sdk_config.ini
的绝对路径;若拷贝配置文件至
dolphindb server
,则可以是相对于
dolphindb server
的相对路径。
dataSource
:一个字符串,表示行情的类型,可以是以下值:
“orders”:表示回调函数 OnRtnSecuDepthMarketData(主推 - 现货深度行情)获取的行情数据。
”trade”:表示回调函数 OnRtnSecuDepthMarketData(主推 - 现货深度行情)获取的行情数据。
“snapshot”:表示回调函数 OnRtnSecuDepthMarketData(主推 - 现货深度行情)获取的行情数据。
markets
: 可选参数。一个字符串或字符串向量,表示行情市场,上海证券交易所用
sh
表示,深圳证券交易所用
sz
表示,参数默认值为
["sz", "sh"]
。
merge
: 可选参数。一个布尔值,表示是否合并处理上海和深圳市场的行情数据,参数默认值为 false。
saveToDfs
: 可选参数。一个布尔值,表示是否持久化存储到分区表,参数默认值为 false。
streamTableNames
: 可选参数。一个字符串或字符串向量,表示用于接收实时数据的流数据表的名字,
将使用这个名字创建新的持久化共享流数据表
。
dbPath
: 可选参数。一个字符串,表示用于持久化存储数据的数据库的名字。若数据库不存在,将创建新数据库。
tableNames
:可选参数。一个字符串或字符串向量,表示用于持久化存储数据的分区表的名字。若分区表不存在,将创建新分区表。
若同名分区表已存在,则直接向该表写入
。
options
:可选参数。一个字典标量,表示行情订阅的扩展参数。当前版本只支持以 “receivedTime” 和 “getAllFieldNames” 作为字典的键。receivedTime 表示是否显示接收时间,对应值为布尔类型标量。 getAllFieldNames 表示是否接受所有字段数据,对应值为布尔类型标量。详见后续的 ”行情数据表结构“章节以及
NSQ 插件函数接口文档
。
username
:可选参数。一个字符串,表示登录 NSQ 行情服务器的用户名。
password
:可选参数。一个字符串,表示登录 NSQ 行情服务器用户名对应的密码。
函数详情
自动化接收和存储 NSQ 实时行情数据。对应行情市场和行情类型的实时数据会被接收到持久化共享流表,并根据用户需要,同时将数据持久化存储到分区表。 函数执行成功会返回流数据表的名字(如果
saveToDfs
为 true,还会返回数据库和分区表的名字),若执行不成功则返回 NULL。
streamTableNames = subscribeNsq(configFilePath, "snapshot", ["sh","sz"], merge=true)
streamTableNames, dbPath, tableNames = subscribeNsq(configFilePath, "orders", "sh", saveToDfs=true)
用户没有使用可选参数
streamTableNames
、
dbPath
和
tableNames
时,easyNSQ 模块默认使用以下名字:
行情类型
行情市场
流数据表
数据库
分区表
orders
sh
nsqStockOrdersSHStream
dfs://nsqStockOrders
ordersSH
orders
sz
nsqStockOrdersSZStream
dfs://nsqStockOrders
ordersSZ
orders
合并存储
nsqStockOrdersStream
dfs://nsqStockOrders
orders
trade
sh
nsqStockTradeSHStream
dfs://nsqStockTrade
tradeSH
trade
sz
nsqStockTradeSZStream
dfs://nsqStockTrade
tradeSZ
trade
合并存储
nsqStockTradeStream
dfs://nsqStockTrade
trade
snapshot
sh
nsqStockSnapshotSHStream
dfs://nsqStockSnapshot
snapshotSH
snapshot
sz
nsqStockSnapshotSZStream
dfs://nsqStockSnapshot
snapshotSZ
snapshot
合并存储
nsqStockSnapshotStream
dfs://nsqStockSnapshot
snapshot
4.2 closeNsqConnection
语法
easyNSQ::closeNsqConnection()
参数
无
函数详情
断开与行情服务器的连接,本函数执行后会取消所有已建立的对实时行情数据的订阅。
函数执行成功返回 true,若有执行异常则会返回 false。
4.3 iniNsqEnv
语法
easyNSQ::iniNsqEnv([streamTableNames])
参数
streamTableNames
:可选参数。一个字符串或字符串向量,表示要清理的流数据表。
函数详情
初始化流计算环境,清理指定的流数据表及其订阅。若用户没有使用可选参数
streamTableNames
,则会根据 easyNSQ 模块默认使用的流表进行清理,请参考
easyNSQ::subscribeNsq
的函数详情说明。
注意
:
iniNsqEnv
函数在没有传入参数时,会根据 easyNSQ 模块默认使用的流表名字,对同名流表及其订阅进行清理。请用户注意这一行为可能会导致数据被误删除。
4.4 iniNsqDfs
语法
easyNSQ::iniNsqDfs([dbName], [tbNames])
参数
dbName
: 可选参数。一个字符串,表示要清理的分区表的数据路径。
tbNames
:可选参数。一个字符串或字符串向量,表示要清理的分区表的表名。
函数详情
初始化环境,清理已指定的分区表。若用户没有使用可选参数
dbName
和
tbNames
,则会根据 easyNSQ 模块默认使用的分区表进行清理,请参考
easyNSQ::subscribeNsq
的函数详情说明。
注意
:
iniNsqDfs
函数在没有传入参数时,会根据 easyNSQ 模块默认使用的数据库路径和分区表名字,对分区表进行清理。请用户注意这一行为可能会导致数据被误删除。
5. easyNSQ 模块使用示例
本章节为四个不同的使用场景提供了脚本示例,并在最后提供了脚本用于关闭 NSQ 连接和清理例子运行时创建的流表、分区表。
5.1 例1-接收深圳市场 snapshot 实时行情数据
// 加载插件
try{ loadPlugin("nsq") } catch(ex) { print(ex) }
go
// 调用模块
use DolphinDBModules::easyNSQ
configFilePath = "<your_path_to>/nsq_sdk_config.ini";
// 初始化化境并拉起订阅
iniNsqEnv()
streamTableNames = subscribeNsq(configFilePath, "snapshot", "sz")
// 检查订阅情况
nsq::getSubscriptionStatus()
select count(*) from objByName(streamTableNames[0])
select top 100 * from objByName(streamTableNames[0])
// 停止订阅
nsq::unsubscribe("snapshot", "sz")
nsq::getSubscriptionStatus()
5.2 例2-接收上海市场所有类型实时行情数据,并持久化存储
// 加载插件
try{ loadPlugin("nsq") } catch(ex) { print(ex) }
go
// 调用模块
use DolphinDBModules::easyNSQ
configFilePath = "<your_path_to>/nsq_sdk_config.ini";
// 数据接收选项(非必填)
nsq_data_option = dict(STRING, ANY)
nsq_data_option["receivedTime"]=true // 在行情数据中增加一列接收时间
nsq_data_option["getAllFieldNames"]=true // 接受 nsq 原始行情中所有字段
// 初始化环境并拉起订阅
iniNsqEnv()
iniNsqDfs()
subscribeNsq(configFilePath, "orders", "sh", saveToDfs=true, options=nsq_data_option)
subscribeNsq(configFilePath, "trade", "sh", saveToDfs=true, options=nsq_data_option)
subscribeNsq(configFilePath, "snapshot", "sh", saveToDfs=true, options=nsq_data_option)
// 检查订阅情况
nsq::getSubscriptionStatus()
existsSubscriptionTopic(,"nsqStockOrdersSHStream","easyNSQ_saveToDfsTable")
existsSubscriptionTopic(,"nsqStockTradeSHStream","easyNSQ_saveToDfsTable")
existsSubscriptionTopic(,"nsqStockSnapshotSHStream","easyNSQ_saveToDfsTable")
select count(*) from objByName("nsqStockOrdersSHStream")
select count(*) from loadTable("dfs://nsqStockOrders", "ordersSH")
select count(*) from objByName("nsqStockTradeSHStream")
select count(*) from loadTable("dfs://nsqStockTrade", "tradeSH")
select count(*) from objByName("nsqStockSnapshotSHStream")
select count(*) from loadTable("dfs://nsqStockSnapshot", "snapshotSH")
// 仅停止 orders 行情数据的订阅
nsq::unsubscribe("orders", "sh")
nsq::getSubscriptionStatus()
// 停止所有订阅
closeNsqConnection()
nsq::getSubscriptionStatus()
5.3 例3-停止所有订阅后,重新接收上海市场 orders 数据
保留之前持久化的数据
// 加载插件
try{ loadPlugin("nsq") } catch(ex) { print(ex) }
go
// 调用模块
use DolphinDBModules::easyNSQ
configFilePath = "<your_path_to>/nsq_sdk_config.ini";
// 数据接收选项(非必填)
nsq_data_option = dict(STRING, ANY)
nsq_data_option["receivedTime"]=true // 在行情数据中增加一列接收时间
nsq_data_option["getAllFieldNames"]=true // 接受 nsq 原始行情中所有字段
// 初始化流环境并拉起订阅
iniNsqEnv("nsqStockOrdersSHStream")
streamTableNames, dbPath, tableNames = subscribeNsq(configFilePath, "orders", "sh", saveToDfs=true, options=nsq_data_option)
// 检查订阅情况
nsq::getSubscriptionStatus()
existsSubscriptionTopic(,streamTableNames[0],"easyNSQ_saveToDfsTable")
select count(*) from objByName(streamTableNames[0])
select count(*) from loadTable(dbPath, tableNames[0])
// 停止订阅
nsq::unsubscribe("orders", "sh")
不保留之前持久化的数据
// 加载插件
try{ loadPlugin("nsq") } catch(ex) { print(ex) }
go
// 调用模块
use DolphinDBModules::easyNSQ
configFilePath = "<your_path_to>/nsq_sdk_config.ini";
// 数据接收选项(非必填)
nsq_data_option = dict(STRING, ANY)
nsq_data_option["receivedTime"]=true // 在行情数据中增加一列接收时间
nsq_data_option["getAllFieldNames"]=true // 接受 nsq 原始行情中所有字段
// 初始化环境并拉起订阅
iniNsqEnv("nsqStockOrdersSHStream")
iniNsqDfs("dfs://nsqStockOrders", "ordersSH")
subscribeNsq(configFilePath, "orders", "sh", saveToDfs=true, options=nsq_data_option)
// 检查订阅情况
nsq::getSubscriptionStatus()
existsSubscriptionTopic(,"nsqStockOrdersSHStream","easyNSQ_saveToDfsTable")
select count(*) from objByName("nsqStockOrdersSHStream")
select count(*) from loadTable("dfs://nsqStockOrders", "ordersSH")
// 停止订阅
nsq::unsubscribe("orders", "sh")
5.4 例4-接收上海和深圳市场所有类型的实时行情数据,并持久化存储
合并处理上海和深圳市场数据
// 加载插件
try{ loadPlugin("nsq") } catch(ex) { print(ex) }
go
// 调用模块
use DolphinDBModules::easyNSQ
configFilePath = "<your_path_to>/nsq_sdk_config.ini";
// nsq 账号(非必填)
nsq_username = "<your_nsq_username>";
nsq_password = "<your_nsq_password>";
// 数据接收选项(非必填)
nsq_data_option = dict(STRING, ANY)
nsq_data_option["receivedTime"]=true // 在行情数据中增加一列接收时间
nsq_data_option["getAllFieldNames"]=true // 接受 nsq 原始行情中所有字段
// 初始化环境并拉起订阅
iniNsqEnv()
iniNsqDfs()
subscribeNsq(configFilePath, "orders", ["sh","sz"], merge=true, saveToDfs=true, options=nsq_data_option, username=nsq_username, password=nsq_password)
subscribeNsq(configFilePath, "trade", ["sh","sz"], merge=true, saveToDfs=true, options=nsq_data_option, username=nsq_username, password=nsq_password)
subscribeNsq(configFilePath, "snapshot", ["sh","sz"], merge=true, saveToDfs=true, options=nsq_data_option, username=nsq_username, password=nsq_password)
// 检查订阅情况
nsq::getSubscriptionStatus()
existsSubscriptionTopic(,"nsqStockOrdersStream","easyNSQ_saveToDfsTable")
existsSubscriptionTopic(,"nsqStockTradeStream","easyNSQ_saveToDfsTable")
existsSubscriptionTopic(,"nsqStockSnapshotStream","easyNSQ_saveToDfsTable")
// 停止订阅
closeNsqConnection()
分开处理上海和深圳市场数据(用户自定义流表和分区表名字)
// 加载插件
try{ loadPlugin("nsq") } catch(ex) { print(ex) }
go
// 调用模块
use DolphinDBModules::easyNSQ
configFilePath = "<your_path_to>/nsq_sdk_config.ini";
// nsq 账号(非必填)
nsq_username = "<your_nsq_username>";
nsq_password = "<your_nsq_password>";
// 数据接收选项(非必填)
nsq_data_option = dict(STRING, ANY)
nsq_data_option["receivedTime"]=true // 在行情数据中增加一列接收时间
nsq_data_option["getAllFieldNames"]=true // 接受 nsq 原始行情中所有字段
// 初始化环境并拉起订阅
iniNsqEnv(["myNsqOrdersSHStream", "myNsqOrdersSZStream", "myNsqTradeSHStream", "myNsqTradeSZStream","myNsqSnapshotSHStream", "myNsqSnapshotSZStream"])
iniNsqDfs("dfs://myNsqOrders", `myNsqOrdersSH`myNsqOrdersSZ)
iniNsqDfs("dfs://myNsqTrade", `myNsqTradeSH`myNsqTradeSZ)
iniNsqDfs("dfs://myNsqSnapshot", `myNsqSnapshotSH`myNsqSnapshotSZ)
subscribeNsq(configFilePath, "orders", ["sh","sz"], saveToDfs=true, streamTableNames=["myNsqOrdersSHStream", "myNsqOrdersSZStream"], dbPath="dfs://myNsqOrders", tableNames=["myNsqOrdersSH", "myNsqOrdersSZ"], options=nsq_data_option, username=nsq_username, password=nsq_password)
subscribeNsq(configFilePath, "trade", ["sh","sz"], saveToDfs=true, streamTableNames=["myNsqTradeSHStream", "myNsqTradeSZStream"], dbPath="dfs://myNsqTrade", tableNames=["myNsqTradeSH", "myNsqTradeSZ"], options=nsq_data_option, username=nsq_username, password=nsq_password)
subscribeNsq(configFilePath, "snapshot", ["sh","sz"], saveToDfs=true, streamTableNames=["myNsqSnapshotSHStream", "myNsqSnapshotSZStream"], dbPath="dfs://myNsqSnapshot", tableNames=["myNsqSnapshotSH", "myNsqSnapshotSZ"], options=nsq_data_option, username=nsq_username, password=nsq_password)
// 检查订阅情况
nsq::getSubscriptionStatus()
select * from getStreamingStat().subWorkers where topic like "%easyNSQ_saveToDfsTable%"
// 停止订阅
closeNsqConnection()
关闭 NSQ 连接和清理以上例子运行时创建的流表和分区表
// 停止订阅和关闭 nsq 连接
closeNsqConnection()
// 清理流表和分区表
iniNsqEnv()
iniNsqDfs()
iniNsqEnv(["myNsqOrdersSHStream", "myNsqOrdersSZStream", "myNsqTradeSHStream", "myNsqTradeSZStream","myNsqSnapshotSHStream", "myNsqSnapshotSZStream"])
iniNsqDfs("dfs://myNsqOrders", `myNsqOrdersSH`myNsqOrdersSZ)
iniNsqDfs("dfs://myNsqTrade", `myNsqTradeSH`myNsqTradeSZ)
iniNsqDfs("dfs://myNsqSnapshot", `myNsqSnapshotSH`myNsqSnapshotSZ)
6. 设置节点启动时自动订阅 NSQ 行情数据
由于 DolphinDB 流数据表和流表的订阅只存在于内存中,在节点关闭后,先前创建的 DolphinDB 流数据表及其订阅会消失。所以每次节点启动时,都需要重新创建流数据表和发起订阅。如果每次重新启动后都要求用户进行手动操作,在使用上无疑是不便的。考虑到这一点,DolphinDB 实现了启动时自动执行用户指定脚本的功能。
DolphinDB 系统启动流程如下图所示:
图 6-1 DolphinDB 系统启动流程
用户启动脚本(
startup.dos
)
用户启动脚本是通过配置参数
startup
后才会执行,单机 single 模式在
dolphindb.cfg
中配置,集群模式在
cluster.cfg
中配置,可配置绝对路径或相对路径。若配置了相对路径或者没有指定目录,系统会依次搜索本地节点的
home
目录、工作目录和可执行文件所在目录。
以 Linux 单节点为例,在
dolphindb.cfg
添加如下的配置项:
startup=/DolphinDB/server/startup.dos
然后在
/DolphinDB/server/
路径下创建
startup.dos
脚本文件即可完成配置。之后每次节点启动时,都会自动执行
/DolphinDB/server/startup.dos
脚本文件中的代码。
假设用户希望接收上海和深证两个市场的 NSQ 行情数据、持久化存储,并对沪深行情数据做分开存储。用户的
startup.dos
应当如下:
// 登录数据库
login(`admin, `123456)
go
// 加载插件
try{ loadPlugin("nsq") } catch(ex) { print(ex) }
go
// 调用模块
use DolphinDBModules::easyNSQ
go
configFilePath = "<your_path_to>/nsq_sdk_config.ini";
// 初始化环境(不删除分区表)
iniNsqEnv()
// 拉起订阅
subscribeNsq(configFilePath, "orders", ["sh","sz"], saveToDfs=true)
subscribeNsq(configFilePath, "trade", ["sh","sz"], saveToDfs=true)
subscribeNsq(configFilePath, "snapshot", ["sh","sz"], saveToDfs=true)
7. 行情数据表结构
目前 NSQ 插件对上海和深圳市场的行情数据表结构做了统一处理,具体表结构如下:
7.1 逐笔委托(orders)
name
type
ExchangeID
SYMBOL
InstrumentID
SYMBOL
TransFlag
INT
SeqNo
LONG
ChannelNo
INT
TradeDate
DATE
TransactTime
TIME
OrdPrice
DOUBLE
OrdVolume
LONG
OrdSide
CHAR
OrdType
CHAR
OrdNo
LONG
BizIndex
LONG
开启
receivedTime
订阅选项,会在行情表中增加时间戳字段,表示插件接收消息的时刻。
name
type
receivedTime
NANOTIMESTAMP
7.2 逐笔成交(trade)
默认模式
name
type
ExchangeID
SYMBOL
InstrumentID
SYMBOL
TransFlag
INT
SeqNo
LONG
ChannelNo
INT
TradeDate
DATE
TransactTime
TIME
TrdPrice
DOUBLE
TrdVolume
LONG
TrdMoney
DOUBLE
TrdBuyNo
LONG
TrdSellNo
LONG
TrdBSFlag
CHAR
BizIndex
LONG
开启
receivedTime
订阅选项,会在行情表中增加时间戳字段,表示插件接收消息的时刻。
name
type
receivedTime
NANOTIMESTAMP
7.3 L2 快照(snapshot)
默认模式
name
type
name
type
name
type
ExchangeID
SYMBOL
BidVolume0-9
LONG
EtfSellBalance
DOUBLE
InstrumentID
SYMBOL
AskVolume0-9
LONG
TotalWarrantExecVolume
LONG
LastPrice
DOUBLE
TradesNum
LONG
WarrantLowerPrice
DOUBLE
PreClosePrice
DOUBLE
InstrumentTradeStatus
CHAR
WarrantUpperPrice
DOUBLE
OpenPrice
DOUBLE
TotalBidVolume
LONG
CancelBuyNum
INT
HighPrice
DOUBLE
TotalAskVolume
LONG
CancelSellNum
INT
LowPrice
DOUBLE
MaBidPrice
DOUBLE
CancelBuyVolume
LONG
ClosePrice
DOUBLE
MaAskPrice
DOUBLE
CancelSellVolume
LONG
UpperLimitPrice
DOUBLE
MaBondBidPrice
DOUBLE
CancelBuyValue
DOUBLE
LowerLimitPrice
DOUBLE
MaBondAskPrice
DOUBLE
CancelSellValue
DOUBLE
TradeDate
DATE
YieldToMaturity
DOUBLE
TotalBuyNum
INT
UpdateTime
TIME
IOPV
DOUBLE
TotalSellNum
INT
TradeVolume
LONG
EtfBuycount
INT
DurationAfterBuy
INT
TradeBalance
DOUBLE
EtfSellCount
INT
DurationAfterSell
INT
AveragePrice
DOUBLE
EtfBuyVolume
LONG
BidOrdersNum
INT
BidPrice0-9
DOUBLE
EtfBuyBalance
DOUBLE
AskOrdersNum
INT
AskPrice0-9
DOUBLE
EtfSellVolume
LONG
PreIOPV
DOUBLE
开启
getAllFieldNames
订阅选项,会在行情表中增加最优报价的50档委托等信息,如下所示。
name
type
Bid1Count
INT
MaxBid1Count
INT
Ask1Count
INT
MaxAsk1Count
INT
Bid1Qty0-49
LONG
Ask1Qty0-49
LONG
开启
receivedTime
订阅选项,会在行情表中增加时间戳字段,表示插件接收消息的时刻。
name
type
receivedTime
NANOTIMESTAMP
8. 附件
模块文件:
easyNSQ.dos
startup脚本:
startup.dos
使用示例:
example.txt
FILE:references/doc_3709.md
# cumsum4
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumsum4.html
**来源**: DolphinDB 官方文档
---
cumsum4
语法
cumsum4(X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累计四次方和。
返回值
DOUBLE 类型,其数据形式同
X
。
例子
x=[2,3,4];
cumsum4 x;
// output
[16,97,353]
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
cumsum4(m);
#0
#1
1
256
17
881
98
2177
相关函数:
sum4
FILE:references/doc_3711.md
# cross join
**URL**: https://docs.dolphindb.cn/zh/progr/sql/crossjoin.html
**来源**: DolphinDB 官方文档
---
cross join
语法
cj(leftTable, rightTable)
参数
leftTable
和
rightTable
是连接的表。
在DolphinDB中,该语句的使用兼容 SQL 的语法:
select column_name(s) from leftTable cross join rightTable
详情
交叉连接函数返回两张表的笛卡尔积的结果集。如果左表有n行,右表有m行,那么笛卡尔积结果集含有n*m行。
例子
a = table(2010 2011 2012 as year)
b = table(`IBM`C`AAPL as Ticker);
a;
year
2010
2011
2012
b;
Ticker
IBM
C
AAPL
cj(a,b);
year
Ticker
2010
IBM
2010
C
2010
AAPL
2011
IBM
2011
C
2011
AAPL
2012
IBM
2012
C
2012
AAPL
select * from cj(a,b) where year>2010;
// 等价于 select * from a cross join b where year>2010
year
Ticker
2011
IBM
2011
C
2011
AAPL
2012
IBM
2012
C
2012
AAPL
相反,
join
只是简单地合并两张表的列。
join(a,b);
year
Ticker
2010
IBM
2011
C
2012
AAPL
FILE:references/doc_3716.md
# appendForJoin
**URL**: https://docs.dolphindb.cn/zh/funcs/a/appendForJoin.html
**来源**: DolphinDB 官方文档
---
appendForJoin
语法
appendForJoin(engine, isLeftTable, data)
详情
将数据插入流数据 join 引擎中。
注:
使用订阅函数
subscribeTable
为流数据 join
引擎订阅数据时,
handler
参数需要为
appendForJoin
、
getLeftStream
或
getRightStream
函数。
参数
engine
是流数据 join 引擎,即
createAsofJoinEngine
等函数返回的抽象表对象。目前支持以下 join 引擎:
createAsofJoinEngine
createEquiJoinEngine
createLookupJoinEngine
createWindowJoinEngine
createLeftSemiJoinEngine
isLeftTable
布尔类型,插入左表还是右表。
data
将要插入表中的数据。
返回值
例子
leftTable=table(1:0, `timestamp`sym`price, [TIMESTAMP, SYMBOL, DOUBLE])
rightTable=table(1:0, `timestamp`sym`val, [TIMESTAMP, SYMBOL, DOUBLE])
output=table(100:0, `timestamp`sym`price`val`total, [TIMESTAMP, SYMBOL, DOUBLE, DOUBLE, DOUBLE])
ajEngine=createAsofJoinEngine("test1", leftTable, rightTable, output, <[price, val, price*val]>, `sym, `timestamp, false, 7)
tmp1=table(take(2012.01.01T00:00:00.000+[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 20) as timestamp, take(`AAPL, 10) join take(`IBM, 10) as sym, double(1..20) as price)
tmp2=table(take(2012.01.01T00:00:00.000+[1, 2, 3, 4, 4, 4, 4, 4, 4, 4], 20) as timestamp, take(`AAPL, 10) join take(`IBM, 10) as sym, double(1..20) as val)
appendForJoin(ajEngine, true, (select * from tmp1 where timestamp=2012.01.01T00:00:00.001))
appendForJoin(ajEngine, false, (select * from tmp2 where timestamp=2012.01.01T00:00:00.001))
appendForJoin(ajEngine, true, (select * from tmp1 where timestamp=2012.01.01T00:00:00.002))
appendForJoin(ajEngine, false, (select * from tmp2 where timestamp=2012.01.01T00:00:00.002))
appendForJoin(ajEngine, true, (select * from tmp1 where timestamp=2012.01.01T00:00:00.003))
appendForJoin(ajEngine, false, (select * from tmp2 where timestamp=2012.01.01T00:00:00.003))
appendForJoin(ajEngine, true, (select * from tmp1 where timestamp=2012.01.01T00:00:00.004))
appendForJoin(ajEngine, false, (select * from tmp2 where timestamp=2012.01.01T00:00:00.004))
appendForJoin(ajEngine, true, (select * from tmp1 where timestamp=2012.01.01T00:00:00.005))
appendForJoin(ajEngine, true, (select * from tmp1 where timestamp=2012.01.01T00:00:00.006))
appendForJoin(ajEngine, true, (select * from tmp1 where timestamp=2012.01.01T00:00:00.007))
appendForJoin(ajEngine, true, (select * from tmp1 where timestamp=2012.01.01T00:00:00.008))
appendForJoin(ajEngine, true, (select * from tmp1 where timestamp=2012.01.01T00:00:00.009))
appendForJoin(ajEngine, true, (select * from tmp1 where timestamp=2012.01.01T00:00:00.010))
sleep(5000)
FILE:references/doc_3732.md
# dayOfYear
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dayOfYear.html
**来源**: DolphinDB 官方文档
---
dayOfYear
语法
dayOfYear(X)
详情
计算
X
是当年中的第几天。返回的结果是整型。
参数
X
可以是 DATE, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
返回值
整数类型的标量或向量。
例子
dayOfYear(2011.01.01);
// output
1
dayOfYear([2011.12.31,2012.12.31]);
// output
[365,366]
dayOfYear([2012.06.12T12:30:00,2012.07.12T12:35:00]);
// output
[164,194]
相关函数:
dayOfMonth
,
quarterOfYear
,
monthOfYear
,
weekOfYear
,
hourOfDay
,
minuteOfHour
,
secondOfMinute
,
millisecond
,
microsecond
,
nanosecond
FILE:references/doc_3735.md
# getRightStream
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getRightStream.html
**来源**: DolphinDB 官方文档
---
getRightStream
语法
getRightStream(joinEngine)
详情
返回连接引擎右表的表结构对象。向该对象注入的数据,会注入到
joinEngine
中。
通过该函数,可以将一个引擎的计算结果直接注入到连接引擎中,实现引擎间的级联。
使用案例请参考
getLeftStream
。
参数
joinEngine
创建连接引擎返回的对象。目前 DolphinDB 支持的连接引擎有:
createAsofJoinEngine
createEquiJoinEngine
createLookupJoinEngine
createWindowJoinEngine
createLeftSemiJoinEngine
返回值
一个表。
FILE:references/doc_375.md
# bucket
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bucket.html
**来源**: DolphinDB 官方文档
---
bucket
语法
bucket(vector, dataRange, bucketNum, [includeOutbound=false])
详情
返回一个和
vector
相同长度的向量,表明根据
dataRange
和
bucketNum
所给出的分类规则,每一个元素应该属于哪个桶。
例如,
dataRange
是 0:10,
bucketNum
是 2,则两个桶分别是 [0, 5) 和 [5,
10),桶的编号分别为0和1。如果
includeOutbound
为true,这个例子会产生 4 个桶,即 <0, [0, 5), [5,10)
和 >=10。如果
includeOutbound
为false,任何小于下限或大于等于上限的值会返回 NULL。
参数
vector
一个数值或时间向量。
dataRange
一对表示数据范围的值,包括下限,不包括上限。
bucketNum
桶的数量。当
dataRange
是整型数据对时,它的范围大小必须是
bucketNum
的整数倍。
includeOutbound
一个可选的布尔值,表明是否包括小于下限的值,以及大于或等于上限的值。默认值为 false。
返回值
返回一个和
vector
相同长度的 INT 类型向量。
例子
bucket(9 23 54 36 46 12, 12:54, 2);
// output
[,0,,1,1,0]
bucket(9 23 54 36 46 12, 12:54, 2, 1);
// output
[0,1,3,2,2,1]
FILE:references/doc_3750.md
# deleteGroup
**URL**: https://docs.dolphindb.cn/zh/funcs/d/deleteGroup.html
**来源**: DolphinDB 官方文档
---
deleteGroup
语法
deleteGroup(groupName)
详情
删除一个群组。这可能会影响群组内所有成员的权限。
注:
该函数只能由管理员在控制节点、数据节点和计算节点运行。
参数
groupName
是表示群组名称的字符串。
返回值
无。
例子
deleteGroup(`Production);
FILE:references/doc_3752.md
# createUser
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createUser.html
**来源**: DolphinDB 官方文档
---
createUser
语法
createUser(userId, password, [groupIds], [isAdmin=false],
[authMode])
详情
创建用户。
groupIds
表示的组必须是已经创建了的组。
注:
该函数只能由管理员运行。
参数
userId
是表示用户名的字符串。是表示用户名的字符串。只能包含字母、数字、下划线(_)、或短横线(-),且必须以字母开头,长度不得超过 30 个字符。
password
是表示用户密码的字符串。它不能包含空格或控制字符。
从 2.00.10.10 开始,用户可以通过配置项
enhancedSecurityVerification
控制是否对 password 进行复杂性校验。若不设置
enhancedSecurityVerification
,则不校验;若设置
enhancedSecurityVerification
=true,则要求密码必须满足以下条件:
字符个数为8~20
至少包含一个大写字母
至少包含以下字符之一:!"#$%&'()*+,-./:;<=>?@[]^_`{|}~。
groupIds
可选参数,是表示用户所属组的字符串标量或向量。
isAdmin
可选参数,是表示用户是否为管理员的布尔值。
authMode
可选参数,指定该用户的登录认证方式。默认为”sha256”,即用户通过
login
函数登录,使用
SHA-256 算法认证。另支持指定为”scram”,使用 SCRAM (Salted Challenge Response Authentication
Mechanism) 协议登录。
注:
SCRAM 基于
IETF's RFC 5802
标准
实现,通过高强度的哈希算法,双向验证等措施,为用户通过密码登录的方式提供更高的安全性。
DolphinDB 的 API 已支持 SCRAM 认证方式:
通过 API 的原生方法连接 DolphinDB 服务器时, API 端将优先采用 SCRAM 方式登录。
如该用户未启用 SCRAM 认证,则自动回退至默认登录方式。
若不使用 API 提供的封装好的接口,自行使用 SCRAM 登录时,需调用 DolphinDB 服务端函数
scramClientFirst
和
scramClientFinal
。具体流程与配置要求请见对应函数文档。
启用 SCRAM 认证后,
login
,
resetPwd
,
changePwd
等密码相关函数仍然有效。
返回值
无。
例子
创建一个名称为 "JohnSmith",密码为 'Qb0507#$' 的非管理员用户,登录时默认使用 SHA-256
算法进行认证。该用户属于组 "research" 和组 "production"。
createUser(`JohnSmith, "Qb0507#$", `research`production);
FILE:references/doc_3770.md
# strip
**URL**: https://docs.dolphindb.cn/zh/funcs/s/strip.html
**来源**: DolphinDB 官方文档
---
strip
语法
strip(X)
详情
去掉首尾所有空格,制表符,换行和回车符号。
参数
X
是字符串标量或向量。
返回值
STRING 类型标量。
例子
x="\nhello world\t\n";
x;
// output
hello world
strip x;
// output
hello world
相关函数:
trim
FILE:references/doc_3779.md
# getInstrumentField
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getInstrumentField.html
**来源**: DolphinDB 官方文档
---
getInstrumentField
语法
getInstrumentField(instrument, key,
[default])
详情
从金融工具中提取指定字段(
key
)对应的值:
未设置
default
时,若字段存在有效值,则返回该值,否则返回空值;
设置
default
时,若字段存在有效值,则将其类型转为
default
的类型返回,否则返回
default
。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
key
STRING 类型标量,表示金融工具的字段,需与
instrument
中定义的字段名一致。
default
一个标量,表示
key
的默认值。目前支持如下类型:LOGICAL, INTEGRAL(COMPRESSED 除外),
TEMPORAL(DATEHOUR 除外), FLOATING, LITERAL, DECIMAL。
返回值
当
instrument
是标量时,返回一个标量。
当
instrument
是向量时,返回一个与
instrument
等长的向量。
例子
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "ZeroCouponBond",
"version": 0,
"instrumentId": "0001",
"start": 1996.03.01,
"maturity": 2032.05.15,
"dayCountConvention": "ActualActualISDA",
"coupon": 0.0276,
"issuePrice": 100.0,
"frequency": "Semiannual",
"subType":"TREASURY_BOND",
"creditRating":"B",
"settlement": 2022.05.15
}
ins = parseInstrument(bond)
getInstrumentField(ins, "productType")
// output: Cash
相关函数:
parseInstrument
、
getInstrumentKeys
FILE:references/doc_378.md
# rows
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rows.html
**来源**: DolphinDB 官方文档
---
rows
语法
rows(X)
详情
返回
X
中的行数。参见相关函数:
cols
。
参数
X
可以是任意数据形式的对象。
返回值
一个 INT 标量。
例子
y=1 2 3;
rows(y);
// output
3
// 一个向量可以被视为一个 n* 1 的矩阵
x=1..6$2:3;
X
#0
#1
#2
1
3
5
2
4
6
rows X
// output
2
a=table(1..3 as x,`IBM`C`AAPL as y);
a
x
y
1
IBM
2
C
3
AAPL
rows a;
// output
3
FILE:references/doc_3785.md
# atan
**URL**: https://docs.dolphindb.cn/zh/funcs/a/atan.html
**来源**: DolphinDB 官方文档
---
atan
语法
atan(X)
详情
返回
X
的反正切。
参数
X
可以是标量、向量、矩阵或表。
返回值
返回结果的数据形式与输入保持一致:若输入为标量,返回标量;若输入为向量、矩阵或表,返回相同维度的结果。
例子
atan 0.000000 1.557408 -2.185040;
// output
[0,1,-1.141593]
相关函数:
asin
,
acos
,
sin
,
cos
,
tan
,
asinh
,
acosh
,
atanh
,
sinh
,
cosh
,
tanh
FILE:references/doc_3793.md
# createDistributedInMemoryTable
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createDistributedInMemoryTable.html
**来源**: DolphinDB 官方文档
---
createDistributedInMemoryTable
语法
createDistributedInMemoryTable(tableName, colNames,
colTypes, globalPartitionType, globalPartitionScheme, globalPartitionColumn,
[localPartitionType], [localPartitionScheme], [localPartitionColumn])
详情
创建一个分布式共享内存表,按指定分区方案,将数据存储在不同在节点上。该函数只能在数据节点/计算节点执行。
按全局分区方案将分布式共享内存表的数据分散地存储在不同节点(数据节点/计算节点)的内存中。每个节点最多只能存放一个分区的数据。分布式共享内存表支持并行读写,因此,它适用于需要对内存表进行分布式计算的场景。
分布式共享内存表的分区分为两级:
第一级为全局分区。全局分区可以将内存表的数据按照分区存放在不同的节点上。
第二级为局部分区(可选配置)。局部分区对存储在单个节点内的分区数据进行再分区。
若同时配置了全局分区和局部分区,等同于对分布式共享内存表进行了组合分区。
注:
仅支持在集群模式下创建分布式共享内存表。
全局分区的数量必须不小于2,且不能超过数据节点和计算节点总数。
其它节点访问分布式共享内存表前,需要执行
loadDistributedInMemoryTable
函数加载表。
通过命令
dropDistributedInMemoryTable
删除分布式共享内存表。
分布式共享内存表的操作暂不支持事务。
参数
tableName
字符串标量,表示分布式共享内存表的名称。
colNames
字符串向量,用于指定表的列名。
colTypes
由数据类型组成的向量,用于指定
colNames
各列的类型。
globalPartitionType
必选参数,表示集群全局的分区类型,仅支持范围分区(RANGE),哈希分区(HASH),数值分区(VALUE),列表分区(LIST)。
globalPartitionScheme
必选参数,表示集群全局的分区方案。
分区类型及对应的分区方案见下表:
分区类型
分区符号
分区方案
范围分区
RANGE
向量。向量的任意两个相邻元素定义分区的范围。
哈希分区
HASH
元组。第一个元素是分区列的数据类型,第二个元素是分区的数量。
值分区
VALUE
向量。向量的每个元素定义了一个分区。
列表分区
LIST
向量。向量的每个元素定义了一个分区。
globalPartitionColumn
必选参数,字符串标量,表示集群全局的分区列。
以上参数对应整个集群的分区配置,分布式共享内存表将按照上述分区方案将数据分区后存储到各个节点。各个节点的数据可以通过以下参数,进行节点内部的二次分区。
localPartitionType
可选参数,表示节点内部的分区类型,仅支持范围分区(RANGE),哈希分区(HASH),数值分区(VALUE),列表分区(LIST)。
localPartitionScheme
可选参数,表示节点内部的分区方案。
localPartitionColumn
可选参数,字符串标量,表示节点内部的分区列。
返回值
一个表。
例子
创建分布式共享内存表
本例的集群拥有两个数据节点 node1 和 node2,在 node1
上创建一个分布式共享内存表。因为分区的数量不能超过数据节点和计算节点数总和,建议进行 HASH 分区。
pt = createDistributedInMemoryTable(`dt, `time`id`value, `DATETIME`INT`LONG, HASH, [INT, 2],`id)
加载分布式共享内存表
在 node2 上加载分布式共享内存表,并插入数据。
time = take(2021.08.20 00:00:00..2021.08.30 00:00:00, 40);
id = 0..39;
value = rand(100, 40);
tmp = table(time, id, value);
pt = loadDistributedInMemoryTable(`dt)
pt.append!(tmp);
select * from pt;
查看分布式共享内存表是否存在。
objs(true)
删除分布式共享内存表
dropDistributedInMemoryTable(`dt)
FILE:references/doc_3794.md
# getClusterStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getClusterStatus.html
**来源**: DolphinDB 官方文档
---
getClusterStatus
语法
getClusterStatus(clusterName)
详情
查询指定集群当前的状态。只能由管理员在 MoM(Master of Master,管理集群)上执行该函数。
参数
clusterName
字符串标量或向量,表示集群名称。
返回值
返回一个表,除 clusterName 和 computeGroup 字段外,其它字段与
getClusterPerf
函数的结果一致:
clusterName:集群名称。
computeGroup:计算组名称。若集群中无计算组,则该字段为空。
例子
getClusterStatus("ShangHai_cluster2")
clusterName
computeGroup
host
port
site
mode
state
agentSite
maxConnections
maxMemSize
workerNum
executorNum
connectionNum
name
memoryUsed
memoryAlloc
cpuUsage
avgLoad
medLast10QueryTime
maxLast10QueryTime
medLast100QueryTime
maxLast100QueryTime
maxRunningQueryTime
runningJobs
queuedJobs
runningTasks
queuedTasks
jobLoad
diskCapacity
diskFreeSpace
diskFreeSpaceRatio
diskWriteRate
diskReadRate
lastMinuteWriteVolume
lastMinuteReadVolume
networkSendRate
networkRecvRate
lastMinuteNetworkSend
lastMinuteNetworkRecv
publicName
lastMsgLatency
cumMsgLatency
isLeader
ShangHai_cluster2
localhost
8,921
localhost:8921:agent1
1
1
localhost:8921:agent1
32
4
4
0
0
agent1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
ShangHai_cluster2
localhost
8,923
localhost:8923:cnode1
4
0
localhost:8921:agent1
0
0
0
0
0
cnode1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
ShangHai_cluster2
localhost
8,922
localhost:8922:dnode1
0
0
localhost:8921:agent1
0
0
0
0
0
dnode1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
ShangHai_cluster2
localhost
8,920
localhost:8920:controller8920
2
1
512
8
4
0
2
controller8920
123,862,496
127,377,408
16.049382716049383
0.16049382716049382
0
0
0
0
0
0
0
0
0
0
0
0
0
148
0
21,028
0
0
0
0
0
0
0
FILE:references/doc_3795.md
# close
**URL**: https://docs.dolphindb.cn/zh/funcs/c/close.html
**来源**: DolphinDB 官方文档
---
close
语法
close(X)
详情
关闭一个已打开的文件或远程连接。该函数必须要用户登录后才能执行。
参数
X
是一个文件句柄或远程连接。
返回值
无。
例子
fout=file("test.txt","w");
fout.writeLine("hello world!");
// output
1
fout.close();
fin = file("test3.txt");
print fin.readLine();
hello world!
fin.close();
FILE:references/doc_3801.md
# indexedTable
**URL**: https://docs.dolphindb.cn/zh/funcs/i/indexedTable.html
**来源**: DolphinDB 官方文档
---
indexedTable
语法
indexedTable(keyColumns, X, [X1], [X2], .....)
或
indexedTable(keyColumns, capacity:size, colNames, colTypes)
或
indexedTable(keyColumns, table)
详情
创建索引内存表(indexed
table)。一个索引内存表有一个主键。主键可由一个或多个字段组成。索引内存表使用红黑树存储主键索引。在查询时,只要查询条件中包含主键的第1个列字段,便可通过索引定位数据,而无需进行全表扫描。
向表中添加新记录时,系统会检查新记录的主键值。如果新记录的主键值与已有记录的主键值重复,系统会更新表中对应的记录;否则,系统会将新记录添加到表中。
键值内存表在指定所有键值字段时才能达到最佳的查询性能。然而,在实际应用中,并不总是需要查询所有键值字段的信息。对于那些只需查询部分键值字段的情况,可以考虑使用索引内存表。
关于对索引内存表和
键值内存表
使用怎样的查询语句以及如何进行查询优化,详见下表:
indexedTable
keyedTable
查询优化
查询语句必须包含
keyColumns
的第 1 列,且该列过滤条件中只能使用 =, in 或
and;
除 keyColumns 的第 1 列外,其它列可以通过
between、比较运算符等进行范围查询,且查询效率高于使用 in 谓词。
所有过滤条件中,对不同列使用的 in 的次数不超过2次;
建议调用
sliceByKey
以提高性能。
查询语句必须包含
keyColumns
所有列。
过滤条件中只能使用 =, in 或 and,且对不同列使用 in 的次数不超过2次;
建议调用
sliceByKey
以提高性能。
查询语句特点
只需要包含
keyColumns
的第 1 列,而无需包含所有列。
包含 keyColumns 的所有列。此时查询性能优于 indexedTable。
参数
keyColumns
是一个字符串标量或向量,表示主键。主键的数据类型必须属于以下类别: INTEGRAL,
TEMPORAL 或 LITERAL。
第一种用法中,
X
,
X1
,
X2
...
可以是向量、数组向量、矩阵或元组。每个向量、元组、数组向量的长度,以及矩阵中每列长度都必须相同。
当 Xk 是元组时:
若 Xk 的元素是等长的向量,
元组的每个元素将作为表的一列。
元组的长度必须等于表的行数。
若 Xk 包含不同类型或不等长元素,
则将单独作为表的一列(列类型为 ANY),其每个元素将作为该列每行的元素值。
Xk
的长度仍然必须和表的行数保持一致。
第二种用法中:
capacity
是正整数,表示建表时系统为该表分配的内存(以记录数为单位)。当记录数超过
capacity
时,系统首先会分配
capacity
1.2~2倍的新的内存空间,然后复制数据到新的内存空间,最后释放原来的内存。对于规模较大的表,此类操作的内存占用会很高。因此,建议建表时预先分配一个合理的
capacity
。
size
是整数,表示该表新建时的行数。若
size
=0,创建一个空表。 若
size
>0,则建立一个只包含 size 条记录的表,记录初始值如下:
BOOL 类型默认值为 false;
数值类型、时间类型、IPADDR、COMPLEX、POINT 的默认值为 0;
Literal, INT128 类型的默认值为 NULL。
注:
如果
colTypes
指定为数组向量,
size
必须为0。
colNames
是一个向量,表示列名。
colTypes
是一个向量,表示每列的数据类型,允许主键外的其它列指定为数组向量类型或元组(ANY)类型。可使用表示数据类型的系统保留字或相应的字符串。
第三种用法中,
table
是一个表(非流数据表)。注意,
table
中的
keyColumns
不能包含重复值。
例子
例1. 创建索引表
第一种写法:
sym=`A`B`C`D`E
id=5 4 3 2 1
val=52 64 25 48 71
t=indexedTable(`sym`id,sym,id,val)
t;
sym
id
val
A
5
52
B
4
64
C
3
25
D
2
48
E
1
71
第二种写法:
t=indexedTable(`sym`id,1:0,`sym`id`val,[SYMBOL,INT,INT])
insert into t values(`A`B`C`D`E,5 4 3 2 1,52 64 25 48 71);
第三种写法:
tmp=table(sym, id, val)
t=indexedTable(`sym`id, tmp);
创建索引内存分区表:
t=indexedTable(`sym`id,sym,id,val)
db=database("",VALUE, sym)
pt=db.createPartitionedTable(t,`pt,`sym).append!(t);
例2. 更新索引表
t=indexedTable(`sym,1:0,`sym`datetime`price`qty,[SYMBOL,DATETIME,DOUBLE,DOUBLE])
insert into t values(`APPL`IBM`GOOG,2018.06.08T12:30:00 2018.06.08T12:30:00 2018.06.08T12:30:00,50.3 45.6 58.0,5200 4800 7800)
t;
sym
datetime
price
qty
APPL
2018.06.08T12:30:00
50.3
5200
IBM
2018.06.08T12:30:00
45.6
4800
GOOG
2018.06.08T12:30:00
58
7800
插入新记录,并且新记录中的
keyColumns
的值与表中
keyColumns
的值重复:
insert into t values(`APPL`IBM`GOOG,2018.06.08T12:30:01 2018.06.08T12:30:01 2018.06.08T12:30:01,65.8 45.2 78.6,5800 8700 4600)
t;
sym
datetime
price
qty
APPL
2018.06.08T12:30:01
65.8
5800
IBM
2018.06.08T12:30:01
45.2
8700
GOOG
2018.06.08T12:30:01
78.6
4600
keyColumns
的值不允许更新:
update t set sym="C_"+sym;
// output: Can't update a key column.
例3. 查询索引内存表
SQL 语句中若不使用 or,且某个过滤条件包含
keyColumns
的第1列,且该过滤条件使用 = 或 in
谓词,且 in 谓词使用不超过两次,则查询索引内存表的性能优于查询普通内存表。与之对比,若希望查询键值表的性能优于普通内存表,过滤条件必须包含全部
keyColumns
。
首先,分别创建包含100万条记录的普通内存表 t 和索引内存表 t1。
id=shuffle(1..1000000)
date=take(2012.06.01..2012.06.10, 1000000)
type=take(0..9, 1000000)
val=rand(100.0, 1000000)
t=table(id, date, type, val)
t1=indexedTable(`id`date`type, id, date, type, val);
使用
keyColumns
的第一列进行过滤:
timer(100) select * from t where id=500000;
// output: Time elapsed: 177.286 ms
timer(100) select * from t1 where id=500000;
// output: Time elapsed: 1.245 ms
timer(100) sliceByKey(t1, 500000)
// output: Time elapsed: 0.742 ms
timer(100) select * from t where id in [500000, 600000, 700000];
// output: Time elapsed: 1134.429 ms
timer(100) select * from t1 where id in [500000, 600000, 700000];
// output: Time elapsed: 1.377 ms
若
keyColumns
第一列的过滤条件不使用 = 或 in ,则查询索引内存表的性能不会优化:
timer(100) select * from t where id between 500000:500010;
// output: Time elapsed: 641.544 ms
timer(100) select * from t1 where id between 500000:500010;
// output: Time elapsed: 599.752 ms
使用
keyColumns
的第一列与第三列进行过滤:
timer(100) select * from t where id=500000, type in [3,6];
// output: Time elapsed: 172.808 ms
timer(100) select * from t1 where id=500000, type in [3,6];
// output: Time elapsed: 1.664 ms
若不使用第一列
keyColumns
进行过滤,则查询索引内存表的性能不会优化:
timer(100) select * from t where date in [2012.06.03, 2012.06.06];
// output: Time elapsed: 490.182 ms
timer(100) select * from t1 where date in [2012.06.03, 2012.06.06];
// output: Time elapsed: 544.015 ms
timer(100) select * from t where date=2012.06.03, type=8;
// output: Time elapsed: 205.443 ms
timer(100) select * from t1 where date=2012.06.03, type=8;
// output: Time elapsed: 204.532 ms
若过滤条件使用超过两个 in 谓词,则查询索引内存表的性能不会优化:
timer(100) select * from t where id in [100,200], date in [2012.06.03, 2012.06.06], type in [3,6];
// output: Time elapsed: 208.714 ms
timer(100) select * from t1 where id in [100,200], date in [2012.06.03, 2012.06.06], type in [3,6];
// output: Time elapsed: 198.674 ms
例4. 使用
indexedTable
保留每只股票卖方委托的最新五档报价。
sym=["a","b","c "]
time=22:58:52.827 22:58:53.627 22:58:53.827
volume=array(INT[]).append!([[100,110,120,115,125],[200,230,220,225,230],[320,300,310,315,310]])
price=array(DOUBLE[]).append!([[10.5,10.6,10.7,10.77,10.85],[8.6,8.7,8.76,8.83,8.9],[6.3,6.37,6.42,6.48,6.52]])
t=indexedTable(`sym,sym,time,volume,price)
t
sym
time
volume
price
a
22:58:52.827
[100, 110, 120, 115, 125]
[10.5, 10.6, 10.7, 10.77, 10.85]
b
22:58:53.627
[200, 230, 220, 225, 230]
[8.6, 8.7, 8.76, 8.83, 8.9]
c
22:58:53.827
[320, 300, 310, 315, 310]
[6.3, 6.37, 6.42, 6.48, 6.52]
//最新的报价数量和价格
newVolume=array(INT[]).append!([[130,110,110,115,120]])
newPrice= array(DOUBLE[]).append!([[10.55,10.57,10.62,10.68,10.5]])
//更新名为 a 的股票的最新报价
update t set volume=newVolume, price=newPrice where sym="a"
t
sym
time
volume
price
a
22:58:52.827
[130, 110, 110, 115, 120]
[10.55, 10.57, 10.62, 10.68, 10.5]
b
22:58:53.627
[200, 230, 220, 225, 230]
[8.6, 8.7, 8.76, 8.83, 8.9]
c
22:58:53.827
[320, 300, 310, 315, 310]
[6.3, 6.37, 6.42, 6.48, 6.52]
需要注意的是,更新 array vector
列的数据时,新记录中各行向量的元素个数必须和原记录中对应行向量的元素个数相同,否则会出现报错。如下例,新记录向量中有4个元素,而已有记录对应行的向量中有5个元素,数量不相同,出现报错:
newPrice= array(DOUBLE[]).append!([[10.55,10.57,10.62,10.5]])
update t set volume=newVolume, price=newPrice where sym="a"
// error: Failed to update column: price
相关函数:
keyedTable
FILE:references/doc_3803.md
# dropMCPTool
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropMCPTool.html
**来源**: DolphinDB 官方文档
---
dropMCPTool
语法
dropMCPTool(name)
详情
删除一个 MCP tool。如果该 tool 已被发布,需要先调用
withdrawMCPTools
撤销发布后才能删除。
参数
name
STRING 类型标量,表示 tool 的名称。
返回值
一个字符串,表示删除 tool 的名称。
例子
dropMCPTool("myTool")
FILE:references/doc_3804.md
# submitJobEx2
**URL**: https://docs.dolphindb.cn/zh/funcs/s/submitJobEx2.html
**来源**: DolphinDB 官方文档
---
submitJobEx2
语法
submitJobEx2(jobId, jobDesc, priority, parallelism, onComplete, jobDef,
args...)
详情
提交批处理作业到本地节点并返回作业的 ID,待作业完成后,执行回调函数。
注:
submitJobEx2
与
submitJobEx
的区别在于:执行完成后,
submitJobEx2
会执行回调函数。
参数
jobId
是作业的 ID,字符串类型。
jobDesc
是字符串,用于描述作业。
priority
是 0 到 9 之间的整数,表示作业的优先级。9 表示优先级最高。
parallelism
是正整数,表示分配给该作业的线程数上限。
onComplete
是回调函数,当批处理作业执行完毕(包括有异常的情况)后,会执行该函数。该函数接受 4 个参数:
jobId:作业的ID
jobDesc:作业的描述。
success:布尔值,表示作业是否执行成功。
result:作业的结果。
jobDef
是用于定义作业的本地函数。
注:
该参数是一个函数对象,而非表示函数名的字符串,因此不可使用引号。
args…
是函数的参数。如果函数没有参数,它可以不指定。
返回值
STRING 类型标量,表示作业的 ID。
例子
def jobDemo(n){
s = 0
for (x in 1 : n) {
s += sum(sin rand(1.0, 100000000)-0.5)
print("iteration " + x + " " + s)
}
return s
}
def cbFunc(jobId, jobDesc, success, result){
desc = jobId + " " + jobDesc
if(success){
desc += " successful " + result
}
else{
desc += " with error: " + result
}
writeLog(desc)
}
submitJobEx2("jobDemo1","job demo", 8, 12, cbFunc, jobDemo, 100)
FILE:references/doc_3805.md
# getTableAccessByCluster
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getTableAccessByCluster.html
**来源**: DolphinDB 官方文档
---
getTableAccessByCluster
语法
getTableAccessByCluster(table)
详情
获取指定表的所有用户权限。只能由管理员在 MoM(Master of Master,管理集群)上执行该函数。
参数
table
字符串标量,表示一个表,形如:
{catalog}.{schema}.{pt}@{cluster}
。
返回值
一个表,字段与
getTableAccess
函数的返回结果一致。
例子
getTableAccessByCluster("catalog1.schema1.dt@MoMSender")
name
type
TABLE_READ
TABLE_INSERT
TABLE_UPDATE
TABLE_DELETE
admin
user
ALLOW
ALLOW
ALLOW
ALLOW
相关函数:
getTableAccess
FILE:references/doc_3810.md
# enableActivePartition
**URL**: https://docs.dolphindb.cn/zh/funcs/e/enableActivePartition.html
**来源**: DolphinDB 官方文档
---
enableActivePartition
语法
enableActivePartition(db, activeDate,
siteAlias)
详情
创建活动数据库和历史数据库之间的连接。
参数
db
是历史数据库的句柄。
activeDate
是活动数据库的日期。
setAlias
是活动数据库所在节点的别名。
返回值
无。
例子
histdb = database("C:\DolphinDBDemo\example\data\dbspace\historical-A\Trades2ndDomain")
activeNodeAlias = getNodeAlias()
activeDate = today()
enableActivePartition(histdb, activeDate, activeNodeAlias);
FILE:references/doc_3813.md
# 内置多数据源流式关联引擎
**URL**: https://docs.dolphindb.cn/zh/stream/str_join_engine.html
**来源**: DolphinDB 官方文档
---
内置多数据源流式关联引擎
在进行数据分析时经常需要对多个不同的数据源进行关联操作,因此在各类数据库的 SQL 语言中均包含了丰富的 join 语句,以支持批计算中的多种关联操作。 DolphinDB
不仅通过 join
语法支持了对于全量历史数据的关联处理,而且在要求低延时的实时计算场景中,也提供了多种流数据连接引擎来支持对不断增长的数据流进行实时的关联处理。流数据连接引擎在内部实现上以增量计算为原则,在大数据流量下依然能够保持毫秒级的时延性能。
本节系统地介绍 DolphinDB 中的 5 种不同的流数据连接引擎,从实时数据流关联、DolphinDB
连接引擎分类、用连接引擎实现金融应用场景等方面层层递进,帮助用户深入理解 DolphinDB 的流计算连接引擎和快速上手多数据源实时关联处理。
注:
DolphinDB 2.00.8 及以上版本支持本教程所有代码。
流数据实时关联
DolphinDB 批计算表关联
在批计算场景中, DolphinDB SQL 语句中不仅提供了与传统关系型数据库类似的 equi join, full join, left join,
prefix join, cross join 等表连接方式,还提供了两种专门为时序数据设计的连接方式:asof join 和 window join。
以下是一个简单的 asof join 批计算的示例,更详细应用介绍请参考:
应用教程:使用 Asof Join, Window Join 快速估计个股交易成本
。我们将通过它进一步分析实时连接中的挑战。
// data
t1 = table(take(`A,
4
)
as
Sym,
10
:
10
:
03.000
+(
10
2100
2890
6030
)
as
Time,
12.5
12.5
12.6
12.6
as
Price)
t2 = table(take(`A,
4
)
as
Sym,
10
:
10
:
00.000
+(
0
3000
6000
9000
)
as
Time,
12.6
12.5
12.7
12.6
as
BidPrice)
// asof join calculation
select *
from
aj(t1, t2, `Time)
asof join 能够关联当前时刻或距离当前时刻最近时刻的数据。指定连接列为 Time 字段后,如上图所示,
t1
表的每行记录总是关联
t2
表中 Time 值小于它的 Time 值的那一行
t2
记录。关联后的结果如下:
实时数据流关联面临的挑战
批计算的关联操作,作为计算输入的
t1
表和
t2
表的数据是有界的,关联操作作用在全量输入数据上,计算结果一次性全量输出。现在考虑一下实时关联的场景,首先在输入上,
t1
,
t2
的记录数会不断增长,表现为数据无界且无法预知下一条记录何时到来,比如股票市场中的交易数据、行情快照数据,而对于关联结果,我们会希望在每一条输入到来后尽快且尽可能正确地输出结果记录,这时计算是不断增量进行的。
那么,对于流式的实时关联场景,我们需要解决以下两个问题:
何时触发计算并输出:以上面的 asof join 为例,数据流
t1
中第一条记录(Time
值为10:10:03:010)到达系统时,假设
t2
数据流中也有一条记录(Time
为10:10:00.000),此时实时计算模块是决定关联目前 t2
中最近的一条记录并输出,还是等待某个触发条件再关联输出,这是技术实现上要解决的问题。
如何管理内存:为了能够正确地关联到两个数据流,实时计算模块需要缓存历史的数据流,而输入是源源不断的,则需要历史数据的清理机制。
流数据连接引擎
DolphinDB 提供了
createAsofJoinEngine
,
createWindowJoinEngine
,
createEquiJoinEngine
,
createLeftSemiJoinEngine
,
createLookupJoinEngine
等 5 种不同的流计算连接引擎函数,不同连接引擎的关联规则基本上与批计算中相应的
join 类似,差异将在后续小节中详细说明。本章首先概述 DolphinDB 流计算引擎,之后依次介绍各个引擎的原理和效果。
流计算连接引擎是 DolphinDB 中对数据流进行实时关联的计算模块,可以理解为一个设置了关联规则的计算黑盒,输入为 2 条数据流,输出为 1
条数据流,引擎内部会自动维护计算状态。
以下代码是 asof join SQL 的流计算实现的脚本,首先创建 2 个流数据表作为输入、1 个流数据表作为输出,然后通过函数
createAsofJoinEngine
创建流计算引擎,之后通过函数
subscribeTable
分别订阅 2
个流数据表并将数据实时注入流计算引擎的左、右表。之后当数据不断写入两个流数据表时,输出结果表
output
中的记录数会相应地增加。流数据订阅功能更详细的介绍见:
流数据功能应用
。
// create table
share streamTable(
1
:
0
, `Sym`Time`Price, [SYMBOL, TIME, DOUBLE])
as
trade
share streamTable(
1
:
0
, `Sym`Time`BidPrice, [SYMBOL, TIME, DOUBLE])
as
snapshot
share table(
1
:
0
, `Time`Sym`Price`t2_Time`BidPrice, [TIME, SYMBOL, DOUBLE, TIME, DOUBLE])
as
output
// create engine
ajEngine = createAsofJoinEngine(name=
"asofJoin"
, leftTable=trade, rightTable=snapshot, outputTable=output, metrics=<[Price, snapshot.Time, BidPrice]>, matchingColumn=`Sym, timeColumn=`Time, useSystemTime=false, delayedTime=
1000
)
// subscribe topic
subscribeTable(tableName=
"trade"
, actionName=
"joinLeft"
, offset=
0
, handler=getLeftStream(ajEngine), msgAsTable=true)
subscribeTable(tableName=
"snapshot"
, actionName=
"joinRight"
, offset=
0
, handler=getRightStream(ajEngine), msgAsTable=true)
以下代码构造输入数据并写入 2 个流数据表,查看结果表
output
将看到引擎计算的结果。
// generate data
t1 = table(take(`A,
4
)
as
Sym,
10
:
10
:
03.000
+(
10
2100
2890
6030
)
as
Time,
12.5
12.5
12.6
12.6
as
Price)
t2 = table(take(`A,
4
)
as
Sym,
10
:
10
:
00.000
+(
0
3000
6000
9000
)
as
Time,
12.6
12.5
12.7
12.6
as
BidPrice)
// input data
snapshot.append!(t2)
trade.append!(t1)
流计算连接引擎通过内置实现和简单的参数接口来解决上一章提到的实时数据流关联的问题。对于内存管理,每个引擎都提供了
garbageSize
参数来清理不再需要的历史数据。对于触发计算的机制,不同的引擎会稍有不同,可以大致分为以下几类:
若关联计算依赖数据的时间顺序,则处理的方式有:
以数据注入引擎时的系统时间为时序标准
以数据中的时间列为时序标准,这种情况下因为无法预知后续将到达的数据的时间戳,则时序判断以最新的时间戳为依据,认为时间戳早于它的全部数据都已经到齐,同时辅以超时强制触发的规则
关联计算不依赖数据的时间顺序,则处理的方式有:
在数据注入引擎时立即计算输出
等待到匹配数据后才计算输出,同时辅以超时强制触发的规则
关联规则和触发规则决定了引擎的计算结果,下面我们详细介绍每一个连接引擎的原理和关联效果。
流数据连接引擎的比较
连接引擎
连接列
关联机制
类似的 SQL join
结果表行数
应用场景
AsofJoinEngine
matchingColumn
左表每到来一条记录,匹配右表连接列一致且时间戳最近的一条记录。
asof join
小于或等于左表行数
计算个股交易成本
WindowJoinEngine
matchingColumn
左表每到来一条记录,匹配右表中连接列一致,且在由左表时间戳确定的窗口范围内的数据。
window join
小于或等于左表行数
将行情快照和逐笔成交数据融合
EquiJoinEngine
matchingColumn+timeColumn
左(右)表每到来一条记录,匹配右(左)表连接列一致的最新的一条记录。
equi join
等于左右表能完全等值匹配的行数(在左右表中的连接列均唯一的前提下)
拼接不同数据源的实时分钟指标
LookupJoinEngine
matchingColumn
左表每到来一条记录,匹配右表连接列一致的记录。
left join/equi join
默认情况下等于左表的行数
将实时行情与历史日频指标关联
LeftSemiJoinEngine
matchingColumn
对于左表的每一条记录,匹配右表连接列一致的第一条或最后一条记录。
equi join
小于或等于左表行数
对逐笔成交数据补充原始委托信息
、
关联股票和指数行情并计算相关性
。
SnapshotJoinEngine
matchingColumn
左(右)表每到来一条记录,匹配右(左)表连接列一致的全部或最新的一条记录。
left join
大于等于左表与右表行数之和
风控场景:实时连接账户资产表和资产市价表以计算杠杆率,净值等指标衡量风险。
总结
DolphinDB 提供了 5
个不同的流数据连接引擎,引擎均内置实现了高效的关联计算、实时触发规则和内存管理机制,开发人员通过简单的引擎参数配置便能够快速实现复杂的实时关联需求。本文重点介绍了各个连接引擎的原理、关联效果、实际应用案例,并在文末简要总结各个引擎的特点,旨在降低开发人员在实时数据流关联处理中的开发门槛。结合
DolphinDB
流数据框架中其他流计算引擎、流水线处理、并行计算等重要特性,开发人员可以将自己的业务场景实时化,通过提升速度掌握更及时的信息、挖掘更多的业务价值。
FILE:references/doc_3817.md
# rowWavg
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowWavg.html
**来源**: DolphinDB 官方文档
---
rowWavg
语法
rowWavg(X, Y)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行计算
X
以
Y
为权重的加权平均。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m1=matrix(2 -1 4, 8 3 2, 9 0 1)
m2=matrix(8 11 10, 8 17 4, 14 6 4)
rowWavg(m1, m2)
// output
[6.8667, 1.1765, 2.8889]
m3=matrix(2 NULL 4, 8 NULL 2, 9 NULL NULL)
rowWavg(m3, m2)
// output
[6.8667, , 3.4286]
a= -10 12.3 -10 -8
b= 17.9 9 7.5 -4
c= 5.5 5.5 -7 8
rowWavg(matrix(a, b, c), matrix(b, a, c))
// output
[-24.459, 9.3899, 10.6316, -32]
x=array(DOUBLE[],0, 10).append!([a, b, c])
y=array(DOUBLE[],0, 10).append!([b, a, c])
rowWavg(x, y)
// output
[-3.6612, 7.0892, 14.4583]
相关函数:
wavg
FILE:references/doc_3828.md
# setLogLevel
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setLogLevel.html
**来源**: DolphinDB 官方文档
---
setLogLevel
语法
setLogLevel(logLevel)
详情
在线设置当前节点的日志文件的等级。设置后,系统只打印当前 logLevel 及以上级别的日志。该命令只能由管理员调用。
参数
logLevel
日志等级,从低到高可选值为:DEBUG, INFO, WARNING, ERROR。
FILE:references/doc_3839.md
# getConnections
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getConnections.html
**来源**: DolphinDB 官方文档
---
getConnections
语法
getConnections()
详情
获取当前节点的所有网络连接信息,可以在所有节点上执行。
参数
无
返回值
返回一个表,包含三列,第一列(server)为当前节点自己的 IP 和端口信息,第二列(client)为网络连接对端的 IP
和端口信息,第三列(startTime)为连接建立时间。
例子
getConnections()
server
client
startTimem
localhost:8848
127.0.0.1:62546
2021.09.02T16:50:57.814
localhost:8848
127.0.0.1:63081
2021.09.02T10:50:16.350
localhost:8848
127.0.0.1:57559
2021.09.02T16:50:57.736
FILE:references/doc_3841.md
# mbetaTopN
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mbetaTopN.html
**来源**: DolphinDB 官方文档
---
mbetaTopN
语法
mbetaTopN(X, Y, S, window, top, [ascending=true],
[tiesMethod='oldest'])
参数说明和窗口计算规则请参考:
mTopN
详情
在给定长度(以元素个数衡量)的滑动窗口内,根据
ascending
指定的排序方式将
X
和
Y
按照
S
进行稳定排序后,取前
top
个元素,然后计算
Y
在
X
上的回归系数的最小二乘估计。
返回值
计算结果为 DOUBLE 类型,形式同输入参数。
例子
x = NULL 3 8 4 0
y = 2 3 1 7 3
s = 5 NULL 8 9 4
mbetaTopN(x, y, s, 3, 2)
// output: [ , , , -0.66, -4]
s2=2021.01.01 2021.02.03 2021.01.23 2021.04.06 2021.12.29
mbetaTopN(x, y, s2, 3, 2)
// output: [ , , , -2.5, -0.6667]
x1 = matrix(x, 4 3 6 2 3)
y1=matrix(3 7 9 3 2, y)
s1=matrix(2 3 1 7 3, s)
mbetaTopN(x, y1, s1, 3, 2)
col1
col2
2.5
-2.5
1.1429
-4
mbetaTopN(x1, y1, s, 3, 2)
col1
col2
-1
-1
2.5
-1.5
1.1429
-1.5
n = 3000
ids = 1..3000
dates = take(2021.01.01..2021.10.01,n)
prices = rand(1000,n)
vals = rand(1000,n)
t = table(ids as id,dates as date,prices as price,vals as val)
dbName = "dfs://test_mbetaTopN_2"
if(existsDatabase(dbName))dropDB(dbName)
db = database(dbName,VALUE,1..5000)
pt = db.createPartitionedTable(t,"pt",`id).append!(t)
select mbetaTopN(price, val, id, 10, 5, true) from pt where date>2021.05.01
相关函数:
mbeta
FILE:references/doc_3842.md
# brute
**URL**: https://docs.dolphindb.cn/zh/funcs/b/brute.html
**来源**: DolphinDB 官方文档
---
brute
语法
brute(func, ranges, [ns=20], [finish=fmin])
详情
通过穷举法在给定范围内最小化一个函数。穷举法使用网格搜索,即计算多维网格点上每个点处的函数值,以找到函数的全局最小值。
注意:穷举法效率低下,其原因是网格点的数量呈指数级增加。因此,即使网格间距较粗、或者问题仅为中等大小等情况,也可能需要很长的运行时间,还可能遇到内存限制。
参数
func
函数名,表示需要最小化的目标函数。注意:其返回值须是数值标量类型。
ranges
元组类型,表示每个参数分量的数值范围。
ranges
中每个元素为形如
(low,
high)
或
(low, high, num)
的元组。其中
low
和
high
都是数值类型,
low
表示该参数分量的最低取值,
high
表示该参数分量的最高取值;
num
为正整数,表示沿轴线的网格点数量,即该参数分量在范围内的取值个数。
ns
可选参数,正整数标量,表示沿轴线的网格点数量。优先取
ranges
元素
(low, high,
num)
中的
num
值;若
ranges
中未设置
,
则
num
为
ns
。该参数默认值为 20。
finish
可选参数,函数名,表示一个优化函数。其输入需满足
finish(func,
X)
;输出应返回一个字典,包含键
"xopt"
和
"fopt"
,且值为数值类型。默认值为函数
fmin
。将穷举法网格搜索的结果作为初始猜测,使用该函数对目标函数进行优化。注意:也可传入“NULL”,表示直接返回穷举法网格搜索的结果,不进行优化。
返回值
返回一个字典,字典有以下成员:
xopt:浮点数向量,使目标函数最小化的参数值。
fopt:浮点数标量,目标函数最小值。fopt=func(xopt)。
例子
以下自定义一个函数
f
,传入指定
ranges
和
ns
值,计算
f
函数在
ranges
内最小化的参数值和对应的最小值。
def f(z) {
a = 2
b = 3
c = 7
d = 8
ee = 9
f = 10
g = 44
h = -1
i = 2
j = 26
k = 1
l = -2
scale = 0.5
x = z[0]
y = z[1]
f1 = a * square(x) + b * x * y + c * square(y) + d * x + ee* y + f
f2 = -g * exp(-(square(x-h)+square(y-i)) / scale)
f3 = -j * exp(-(square(x-k)+square(y-l)) / scale)
return f1+f2+f3
}
ranges=((-4, 3.75),(-4, 3.75))
brute(f, ranges, 32)
/* Ouput:
fopt->-3.408581876799
xopt->[-1.056651921797,1.808348429512]
*/
FILE:references/doc_3855.md
# dropCatalog
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropCatalog.html
**来源**: DolphinDB 官方文档
---
dropCatalog
语法
dropCatalog(catalog)
详情
删除指定的 catalog。
参数
catalog
字符串标量,表示 catalog 的名称。
返回值
无。
例子
dropCatalog("catalog1")
FILE:references/doc_3860.md
# createSessionWindowEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createSessionWindowEngine.html
**来源**: DolphinDB 官方文档
---
createSessionWindowEngine
语法
createSessionWindowEngine(name, sessionGap, metrics,
dummyTable, outputTable, [timeColumn], [useSystemTime=false], [keyColumn],
[updateTime], [useSessionStartTime=true], [snapshotDir],
[snapshotIntervalInMsgCount], [raftGroup], [forceTriggerTime])
详情
创建流数据会话窗口引擎。
createSessionWindowEngine
的参数绝大多数与
createTimeSeriesEngine
一样,只有
sessionGap
和
useSessionStartTime
是它独有的参数。
sessionGap
决定了一个会话窗口何时结束,
useSessionStartTime
决定了输出表时间列的时间为各个窗口的起始时刻还是结束时刻。
更多流数据引擎的应用场景说明可以参考
流计算引擎
。
自 2.00.11 版本开始,
dummyTable
和
outputTable
支持 array
vector,但不支持在计算中使用 array vector,即
metrics
中不能包含 array vector 列。
计算规则
若某条数据之后,经过
sessionGap
指定的时间长度内,没有新数据到来,就进行一次窗口截断(以截断前最后一条数据的时间戳 +
sessionGap
作为窗口的结束时刻)。窗口结束后新到来的一条数据将触发该窗口的计算。
注:
如果不使用数据输入引擎时的系统时间作为时间列进行计算,输入流数据表中时间列(
timeColumn
)所指示的时间戳必须递增;如果同时指定了分组列(
keyColumn
),则按照分组分别进行计算,组内数据的时间戳必须递增。否则,乱序数据将被直接丢弃,不参与计算。
参数
由于会话窗口引擎的绝大多数参数与时间序列引擎重合,请参照
createTimeSeriesEngine
中参数介绍。这里仅介绍与时间序列引擎不同的参数:
sessionGap
必选参数,正整数标量,是判断窗口结束的时间指标,表示某条数据到来后若等待该时间仍无更新的数据到来,就终止当前窗口。此参数的时间精度取决于
useSystemTime
参数。
useSessionStartTime
: 可选参数,布尔值,默认值为
true,表示输出表中的时刻是否为数据窗口起始时刻,即每个窗口中第一条数据的时间戳。若设置为
false,则表示输出表中的时刻为数据窗口结束时刻,即每个窗口中最后一条数据的时刻+
sessionGap
。如果指定
updateTime
,
useSessionStartTime
必须为 true。
forceTriggerTime
可选参数,非负整数,单位与
timeColumn
的时间精度一致。该参数仅在设置
useSystemTime
= false 时起效。当系统收到最后一条数据后,经过
forceTriggerTime
时间,将强制触发未计算的窗口进行计算。
注:
若设置了
keyColumn
,则各分组内进行上述操作。
返回值
返回一个表对象。
例子
share streamTable(1000:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT]) as trades
share table(10000:0, `time`sym`sumVolume, [TIMESTAMP, SYMBOL, INT]) as output1
engine_sw = createSessionWindowEngine(name = "engine_sw", sessionGap = 5, metrics = <sum(volume)>, dummyTable = trades, outputTable = output1, timeColumn = `time, keyColumn=`sym)
subscribeTable(tableName="trades", actionName="append_engine_sw", offset=0, handler=append!{engine_sw}, msgAsTable=true)
n = 5
timev = 2018.10.12T10:01:00.000 + (1..n)
symv=take(`A`B`C,n)
volumev = (1..n)%1000
insert into trades values(timev, symv, volumev)
n = 5
timev = 2018.10.12T10:01:00.010 + (1..n)
volumev = (1..n)%1000
symv=take(`A`B`C,n)
insert into trades values(timev, symv, volumev)
n = 6
timev = 2018.10.12T10:01:00.020 + 1 2 3 8 14 20
volumev = (1..n)%1000
symv=take(`A`B`C,n)
insert into trades values(timev, symv, volumev)
select * from output1;
输出返回:
time
sym
volume
2018.10.12T10:01:00.001
A
5
2018.10.12T10:01:00.002
B
7
2018.10.12T10:01:00.003
C
3
2018.10.12T10:01:00.011
A
5
2018.10.12T10:01:00.012
B
7
2018.10.12T10:01:00.013
C
3
2018.10.12T10:01:00.021
A
1
2018.10.12T10:01:00.022
B
2
2018.10.12T10:01:00.023
C
3
指定
forceTriggerTime
为 1000 ms,收到最后一条消息后,经过 1000
ms,触发所有分组数据计算输出。用以下代码替换上述引擎创建部分的代码。
engine_sw = createSessionWindowEngine(name = "engine_sw", sessionGap = 5, metrics = <sum(volume)>, dummyTable = trades, outputTable = output1, timeColumn = `time, keyColumn=`sym, forceTriggerTime=1000)
再次查询输出表,可以得到以下结果:
time
sym
volume
2018.10.12T10:01:00.001
A
5
2018.10.12T10:01:00.002
B
7
2018.10.12T10:01:00.003
C
3
2018.10.12T10:01:00.011
A
5
2018.10.12T10:01:00.012
B
7
2018.10.12T10:01:00.013
C
3
2018.10.12T10:01:00.021
A
1
2018.10.12T10:01:00.022
B
2
2018.10.12T10:01:00.023
C
3
2018.10.12T10:01:00.028
A
4
2018.10.12T10:01:00.034
B
5
2018.10.12T10:01:00.040
C
6
FILE:references/doc_3874.md
# getInstrumentSettlement
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentsettlement.html
**来源**: DolphinDB 官方文档
---
getInstrumentSettlement
语法
getInstrumentSettlement(instrument)
详情
根据输入的金融工具,获取该工具的结算日(Settlement Date)。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DATE 类型标量或向量。
例子
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "ZeroCouponBond",
"version": 0,
"instrumentId": "0001",
"start": 1996.03.01,
"maturity": 2032.05.15,
"dayCountConvention": "ActualActualISDA",
"coupon": 0.0276,
"issuePrice": 100.0,
"frequency": "Semiannual",
"subType":"TREASURY_BOND",
"creditRating":"B",
"settlement": 2022.05.15
}
ins = parseInstrument(bond)
getInstrumentSettlement(ins)
// output: 2022.05.15
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_3875.md
# join
**URL**: https://docs.dolphindb.cn/zh/funcs/j/join.html
**来源**: DolphinDB 官方文档
---
join
语法
join(X,Y)
或
X<-Y
详情
合并
X
和
Y
。
参数
X
和
Y
可以是标量、向量、元组、矩阵或表。
返回值
返回值的形式取决于
X
和
Y
,详情请参考下方的例子。
例子
如果
X
是标量,
Y
可以是标量或向量,结果是一个向量;
Y
可以是元组,结果是一个元组
1 <- 3;
// output
[1,3]
4<-1 2 3;
// output
[4,1,2,3]
1 <- (2,"A")
// 配置参数 appendTupleAsAWhole=true 时
// output
(1,(2,"A"))
// 配置参数 appendTupleAsAWhole=false 时
// output
(1,2,"A")
如果
X
是向量,
Y
可以是标量、向量或元素类型与 X 相同的元组。它将产生一个更长的向量。
[1,2,3] <- 4;
// output
[1,2,3,4]
[1,2,3] <- [4,5,6];
// output
[1,2,3,4,5,6]
如果 X
是元组,Y可以是标量、向量或元组。它将产生一个更长的元组。
x = (1,"A")
y = 2
x <- y
(1,"A",2)
y = [2,3]
(1,"A",[2,3])
y = (2,"B")
// 配置参数 appendTupleAsAWhole=true 时
// output
(1,"A",(2,"B"))
// 配置参数 appendTupleAsAWhole=false 时
// output
(1,"A",2,"B")
如果
X
是矩阵,
Y
必须是和
X
具有相同行数的向量或矩阵。结果是一个和
X
具有相同行数的矩阵。
1..6$2:3 <- [7,8];
#0
#1
#2
#3
1
3
5
7
2
4
6
8
(1..6$2:3) <- (7..12$2:3);
#0
#1
#2
#3
#4
#5
1
3
5
7
9
11
2
4
6
8
10
12
如果
X
是一个表,
Y
必须是一个和
X
具有相同行数的向量或表。结果是一个和
X
具有相同行数的表。
a=table(1..3 as x, 4.5 6.7 8.5 as y);
a;
x
y
1
4.5
2
6.7
3
8.5
b=table(700 500 800 as z);
b
z
700
500
800
c=join(a,b);
c;
x
y
z
1
4.5
700
2
6.7
500
3
8.5
800
a=table(1..3 as x, `IBM`C`AAPL as y);
b=table(172.3 25 106.5 as z);
c=a<-b;
c
x
y
z
1
IBM
172.3
2
C
25
3
AAPL
106.5
相关函数:
cj (cross_join)
FILE:references/doc_3882.md
# cumprod
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumprod.html
**来源**: DolphinDB 官方文档
---
cumprod
语法
cumprod(X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累计乘积。
返回值
LONG/DOUBLE 类型,其数据形式同
X
。
例子
cumprod(2 3 4);
// output
[2,6,24]
# 等价于 [2, 2*3, 2*3*4]
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
cumprod(m);
#0
#1
1
4
2
20
6
120
相关函数:
prod
FILE:references/doc_3896.md
# 系统运维
**URL**: https://docs.dolphindb.cn/zh/sys_man/om_intro.html
**来源**: DolphinDB 官方文档
---
系统运维
本章介绍系统运维相关内容,包括集群管理、任务管理、运维监控和安全与容灾等方面。通过学习这些内容,用户将能够获得有关如何高效、安全且可靠地运行系统的实用指导。
另外,DolphinDB 还提供了更完整的运维手册,可以查看
https://docs.dolphindb.cn/zh/omc/index.html
FILE:references/doc_3898.md
# signum
**URL**: https://docs.dolphindb.cn/zh/funcs/s/signum.html
**来源**: DolphinDB 官方文档
---
signum
语法
signum(X)
别名:
sign
详情
返回
X
的符号标志。
参数
X
是布尔值或数值类型的标量、向量或矩阵。
返回值
如果
X
为正数,返回1; 如果
X
为0,返回0;如果
X
为负数,返回-1;如果
X
中元素为 NULL,则返回 NULL。
例子
signum(8.2 0 -6 NULL);
// output
[1,0,-1, ]
FILE:references/doc_3907.md
# with
**URL**: https://docs.dolphindb.cn/zh/progr/sql/with.html
**来源**: DolphinDB 官方文档
---
with
with
语句又称为子查询重构语句,其将子查询的结果保存在一个临时表变量中。
通过
with
语句编写 SQL 脚本,有以下优势:
将复杂的 SQL 脚本改写为
with
语句,既增强了代码的可读性,也减轻了脚本的编写负担。
使用临时表存储每个子查询的结果,只做一次查询,后续 SQL 语句可反复使用该临时表数据,提升了查询性能。
子查询结果保存到临时表中,当语句执行完后即被释放,降低了变量定义的空间开销。
注:支持在分布式查询中使用。
语法
with table_name_1[(colNames..)] as (select_statement_1),
table_name_2[(colNames..)] as (select_statement_2),
...
table_name_n[(colNames..)] as (select_statement_n)
final_select_statement
注:
with
后的子查询语句不能以";"结尾。
可以写多条子查询,每条子查询间使用逗号(",")分隔。最后一个子查询语句后不加逗号。
支持在
table_name
后指定参数,用于对 as 后的结果列进行重命名。
不支持在自定义函数中使用
with as
语法。
参数
table_name
临时表名称。
colNames..
用于重命名
as
返回结果列。注意
colNames
是一个变量而不是字符串。
colNames
的数量需要和
as
返回结果的列数一致。
select_statement
select
语句或者
exec
语句。
例子
t1 = table(1 3 4 5 8 as id, 2 2.5 2.4 2.2 2.9 as val)
t2 = table(1 2 4 6 8 as id, `a`a`b`d`c as sym)
with tmp as (select * from t1 inner join t2 on t1.id=t2.id) select count(*) from tmp
3
FILE:references/doc_391.md
# manova
**URL**: https://docs.dolphindb.cn/zh/funcs/m/manova.html
**来源**: DolphinDB 官方文档
---
manova
语法
manova(X, group)
详情
对
X
进行多因素方差分析(MANOVA)。
参数
X
是一个矩阵或所有列均为数值的表。
group
是一个与
X
中每一列长度相同的向量,表示分组。
返回值
一个字典。
例子
a=29.6 24.3 1.5 20.2 2.6 44.5 2.4 20 9.5
b=27.3 68.4 3.8 34.8 4.6 26.3 5.9 20 5.6
c=50.8 60.2 1.0 30.1 2.1 27.9 2.3 20 8.8
g=1 1 2 1 2 1 2 1 2
t=table(a,b,c,g)
manova(select a,b,c from t, t.g);
// output
dfT->8
dfB->1
gnames->[1,2]
gmdist->
#0 #1
--------- ---------
0 16.458055
16.458055 0
mdist->[5.35501,5.171516,0.132336,1.335303,0.043425,5.384036,0.07295,2.844008,0.661416]
chisq->[10.056959]
B->
#0 #1 #2
----------- ----------- -----------
1250.307556 1601.627111 1805.355556
1601.627111 2051.662722 2312.636111
1805.355556 2312.636111 2606.805556
lambda->[0.160648]
W->
#0 #1 #2
-------- --------- --------
453.968 -151.966 16.31
-151.966 1477.6995 1008.395
16.31 1008.395 1182.63
T->
#0 #1 #2
----------- ----------- -----------
1704.275556 1449.661111 1821.665556
1449.661111 3529.362222 3321.031111
1821.665556 3321.031111 3789.435556
chisqdf->[3]
P->[0.018088]
dfW->7
eigenval->[5.224779,2.757998E-16,-1.552556E-15]
eigenvec->
#0 #1 #2
-------- --------- ---------
0.099362 0.08179 0.023313
0.029973 -0.010892 0.107448
0.023044 -0.046981 -0.111469
canon->
#0 #1 #2
--------- --------- ---------
2.047837 -0.369203 -2.271294
2.969714 -1.691977 0.973456
-2.596193 -0.071875 0.09971
0.861618 -0.247207 0.622822
-2.437568 -0.042299 0.088698
2.970655 1.936238 0.521256
-2.413867 -0.082213 0.201424
0.165404 0.372149 0.153761
-1.567601 0.196387 -0.389832
FILE:references/doc_3910.md
# sqlColAlias
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sqlColAlias.html
**来源**: DolphinDB 官方文档
---
sqlColAlias
语法
sqlColAlias(colDefs, [colNames])
详情
使用元代码和可选择的别名来定义一个列。它通常用于计算列。
参数
colDefs
是给定的元代码;
colNames
是表示别名的字符串。
返回值
CODE 类型标量。
例子
sqlColAlias(<x>, `y);
// output
< x as y >
sqlColAlias(<avg(PRC)>, `avgPRC);
// output
< avg(PRC) as avgPRC >
sqlColAlias(<avg(PRC)>);
// output
< avg(PRC) as avg_PRC >
FILE:references/doc_3918.md
# getUserHardwareUsage
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getUserHardwareUsage.html
**来源**: DolphinDB 官方文档
---
getUserHardwareUsage
语法
getUserHardwareUsage([from=0], [to])
详情
从资源使用日志(
<HomeDir>/resource/hardware.log
)获取特定时间段内用户的硬件资源使用情况。该函数仅在资源跟踪功能开启时(配置
resourceSamplingInterval
)调用,且仅限管理员在数据节点上调用。
参数
from
整型或时间类型,表示查询的起始时间点。默认值为0,表示查询从1970.01.01零点开始的记录。
to
整型或时间类型,表示查询的结束时间点。默认为空,表示查询到目前时间点为止的记录。
from
必须小于等于
to
。
返回值
返回一个表,包含以下字段:
timestamp:NANOTIMESTAMP 类型的时间戳。
userId:用户名。
cpu:当前用户占用的工作线程数量。
memory:内存使用量,当前用户使用的所有变量的内存占用大小。单位是字节。
send:单次采集间隔内发送的数据量。单位是字节。
recv:单次采集间隔内接收的数据量。单位是字节。需要注意的是,统计的接收数据量可能会有一定误差,最大误差范围在 2KB 以内。
例子
login("admin", "123456")
select sum(send), sum(recv) from pnodeRun(getUserHardwareUsage) group by userId, node
返回:
userId
node
sum_send
sum_recv
admin
datanode8902
197,783
464
admin
datanode8903
375,911
438
admin
datanode8904
1,080,171
735,817
guest
datanode8902
2,144
216
guest
datanode8903
120
0
guest
datanode8904
399
0
user1
datanode8902
80,222
0
user1
datanode8903
120
0
user1
datanode8904
83,361
328
user2
datanode8902
80,100
0
FILE:references/doc_393.md
# trima
**URL**: https://docs.dolphindb.cn/zh/funcs/t/trima.html
**来源**: DolphinDB 官方文档
---
trima
语法
trima(X, window)
TA-lib 系列函数参数说明和窗口计算规则请参考:
TAlib
详情
在给定长度(以元素个数衡量)的滑动窗口内,计算
X
的三角移动平均(Triangular Moving
Average)。
其计算公式为:
其中
w1 = (window + 1)/2
向上取整;
w2 = (window + 1)/2
向下取整。
返回值
DOUBLE 类型向量/矩阵/表,数据形式同
X
。
例子
x=12.1 12.2 12.6 12.8 11.9 11.6 11.2
trima(x,3);
// output
[,,12.274999999999998,18.625,18.662500000000001,15.225000000000001,11.59375]
x=matrix(12.1 12.2 12.6 12.8 11.9 11.6 11.2, 14 15 18 19 21 12 10)
trima(x,3);
col1
col2
12.2749
15.5000
12.5499
17.5000
12.5249
19.2500
12.0499
18.2500
11.5750
13.7500
相关函数:
sma
,
wma
,
trima
FILE:references/doc_3934.md
# 高可用
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db/ha.html
**来源**: DolphinDB 官方文档
---
高可用
DolphinDB
提供多层次的高可用机制,确保在不同层面的故障场景下系统仍能持续运行。高可用能力覆盖数据存储、集群管理(元数据)、流式计算(流表) 和客户端连接。
DolphinDB
分布式架构提供数据、元数据和客户端的高可用方案,
即使数据库节点发生故障,数据库仍然可以正常运作,保证业务不会中断。
数据高可用
在分布式环境下,为保证数据读写服务的高可用,DolphinDB
会把同一个分区的数据同时写入到集群中的多个不同的节点上。同一个分区在不同节点上的数据拷贝称为副本(Replica)。DolphinDB
集群支持处理千万级以上的分区数据,为了保证数据的强一致性和事务 ACID 特性,它采用了轻量、高效且可行的两阶段提交协议(Two-phase
Commit)来管理数据副本之间的一致性。这种方式确保了即使某个节点上的数据出现损坏,仍然可以通过访问其他节点上的副本数据来持续提供数据服务,从而保证了服务的不中断性。同时,针对数据损坏或其它原因导致的副本数据不一致的情况,系统会通过
recovery 机制将数据恢复到一致状态。
在生产环境中,一般把副本个数设置为大于2,可以保证数据的高可用。
集群高可用(controller 高可用)
DolphinDB 控制节点存储的元数据记录了分区分布的节点,版本信息等。在一个集群中可以部署多个控制节点,通过元数据冗余来保证元数据服务不中断。DolphinDB 采用
Raft 协议保证控制节点的高可用性。一个集群中的所有控制节点组成一个 Raft 组,一个 Raft 组中只有一个 Leader,其他都是 Follower。只有
Leader 与数据节点进行交互,当它收到接收数据节点的请求后,先写入本地日志文件中,并向集群中的每一个 Follower
发送同步日志的请求,当日志同步到大多数节点后告诉 Follower 提交日志。Follower 接收并持久化 Leader 同步的日志,在 Leader
告知提交后,提交日志,这样就能保证 Leader 和 Follower上元数据的强一致性。如果当前 Leader 宕机,系统会立即选举出新的 Leader
来提供元数据服务。Raft
组能够容忍小于半数的控制节点宕机,只要宕机的控制节点少于半数,集群仍然可以提供服务,因此可以保证控制节点上元数据的一致性。例如包含三个控制节点的集群可以容忍一个控制节点出现故障,包含五个控制节点的集群可以容忍两个控制节点出现故障。要设置元数据高可用,集群中控制节点的数量至少为3个,同时需要设置数据高可用,即副本数必须大于1。
流表高可用(Raft Learner)
针对流式计算场景,DolphinDB 提供基于 Raft Learner 的流表高可用能力(需预先配置
多集群管理
)。
Raft Learner 是 Raft 共识算法的一种特殊成员角色,用于从 Raft 主集群同步日志,但不参与投票和主节点选举。借助这一机制,DolphinDB
可以在不同集群间建立流表数据的实时复制,实现:
跨集群容灾:当主集群不可用时,远端 Learner 仍保留完整数据,可用于恢复或容灾。
读写隔离:Learner 节点可用于承载只读流式计算或下游消费,降低对主集群的影响。
高性能:写入路径保持在单集群内完成,不受跨地域网络延迟影响。
传统 Raft 限定一个 Raft 组运行在单个集群内部,所有 Voter 节点(Leader 与 Follower)需频繁通信。为支持跨集群高可用,DolphinDB
对 Raft 机制做了如下扩展:
仅 Learner 节点允许跨集群部署;
Voter 节点(Leader 与 Follower)必须在同一集群内,不允许跨集群分布。
这种机制在保证数据一致性和性能的前提下,拓展了高可用范围,使 DolphinDB 能在流式计算场景下实现跨集群数据保护与容灾能力。
客户端高可用
DolphinDB API 提供了强大的自动重连和切换机制,旨在确保与数据节点/计算节点的交互始终保持高可用性。使用 DolphinDB API 与 DolphinDB
的数据节点/计算节点进行交互时,如果连接的节点宕机,API 会尝试自动重新建立连接,若尝试重连失败,API
会自动连接到集群中其他可用的数据节点/计算节点,以保证客户端与服务器之间连接的稳定性。而且切换过程对用户来说是完全透明的,用户不会察觉到当前连接的节点已经发生了切换。
FILE:references/doc_395.md
# year
**URL**: https://docs.dolphindb.cn/zh/funcs/y/year.html
**来源**: DolphinDB 官方文档
---
year
语法
year(X)
详情
根据输入的值得到其对应的年份。
参数
X
是一个时间标量或向量。
返回值
一个 INT 类型的标量或向量。
例子
year(2012.12.03);
返回:2012
year(2012.12.03 2011.11.05);
返回:[2012,2011]
(2012.12.03).year();
返回:2012
FILE:references/doc_3964.md
# 技术分析(Technical Analysis)指标库
**URL**: https://docs.dolphindb.cn/zh/modules/ta/ta.html
**来源**: DolphinDB 官方文档
---
技术分析(Technical Analysis)指标库
TA-Lib
是一个 Python 库,封装了用 C 语言实现的金融交易技术分析的诸多常用指标。为了方便用户在 DolphinDB 中计算这些技术指标,我们使用 DolphinDB 脚本实现了 TA-Lib 中包含的指标函数,并封装在 DolphinDB ta module 中。因为 DolphinDB ta module 是基于 DolphinDB V1.10.3 开发的,所以使用 ta 模块要求 DolphinDB V1.10.3 或以上版本。
为了更好地支持 ta module 中的函数在 DolphinDB 的流式增量计算引擎中使用,我们基于 DolphinDB V1.30.20 和 DolphinDB V2.00.8 对 ta module 进行了修订。
匹配不同 DolphinDB 版本的 ta module:
V1.10.3:
ta.dos
V1.30.20, V2.00.8:
ta.dos
注意
: 如果 DolpinDB 版本高于 V1.30.20 或 V2.00.8,选择支持 V1.30.20, V2.00.8 版本的 ta.dos。
1. 函数及参数的命名与用法规范
与 TA-Lib 中所有函数名大写以及所有参数名小写的规范不同,ta 模块中,函数名及参数名均采用驼峰式命名法。
例如,TA-Lib 中 DEMA 函数的语法为
DEMA(close, timeperiod=30)
。在 ta 模块中相应的函数为
dema(close, timePeriod)
。
TA-Lib 中某些函数有可选参数。ta 模块中,如果应用于流计算中,所有参数皆为必选。
为得到有意义的结果,ta 模块中函数的参数 timePeriod 要求至少是2。
2. 使用范例
2.1. 脚本中直接使用指标函数
对一个向量直接使用 ta 模块中的
wma
函数进行计算:
use ta
close = 7.2 6.97 7.08 6.74 6.49 5.9 6.26 5.9 5.35 5.63
x = wma(close, 5);
2.2. 在 SQL 语句中分组使用
用户经常需要在数据表中对多组数据在每组内进行计算。在以下例子中,我们构造了一个包含2个股票的数据表:
close = 7.2 6.97 7.08 6.74 6.49 5.9 6.26 5.9 5.35 5.63 3.81 3.935 4.04 3.74 3.7 3.33 3.64 3.31 2.69 2.72
date = (2020.03.02 + 0..4 join 7..11).take(20)
symbol = take(`F,10) join take(`GPRO,10)
t = table(symbol, date, close)
对其中每只股票使用 ta 模块中的
wma
函数进行计算:
update t set wma = wma(close, 5) context by symbol
2.3. 返回多个列的结果
某些函数会返回多个列的结果,例如函数
bBands
。
直接使用的例子:
close = 7.2 6.97 7.08 6.74 6.49 5.9 6.26 5.9 5.35 5.63
low, mid, high = bBands(close, 5, 2, 2, 2);
在 SQL 语句中使用的例子:
close = 7.2 6.97 7.08 6.74 6.49 5.9 6.26 5.9 5.35 5.63 3.81 3.935 4.04 3.74 3.7 3.33 3.64 3.31 2.69 2.72
date = (2020.03.02 + 0..4 join 7..11).take(20)
symbol = take(`F,10) join take(`GPRO,10)
t = table(symbol, date, close)
select *, bBands(close, 5, 2, 2, 2) as `high`mid`low from t context by symbol
symbol date close high mid low
------ ---------- ----- -------- -------- --------
F 2020.03.02 7.2
F 2020.03.03 6.97
F 2020.03.04 7.08
F 2020.03.05 6.74
F 2020.03.06 6.49 7.292691 6.786 6.279309
F 2020.03.09 5.9 7.294248 6.454 5.613752
F 2020.03.10 6.26 7.134406 6.328667 5.522927
F 2020.03.11 5.9 6.789441 6.130667 5.471892
F 2020.03.12 5.35 6.601667 5.828 5.054333
F 2020.03.13 5.63 6.319728 5.711333 5.102939
GPRO 2020.03.02 3.81
GPRO 2020.03.03 3.935
GPRO 2020.03.04 4.04
GPRO 2020.03.05 3.74
GPRO 2020.03.06 3.7 4.069365 3.817333 3.565302
GPRO 2020.03.09 3.33 4.133371 3.645667 3.157962
GPRO 2020.03.10 3.64 4.062941 3.609333 3.155726
GPRO 2020.03.11 3.31 3.854172 3.482667 3.111162
GPRO 2020.03.12 2.69 3.915172 3.198 2.480828
GPRO 2020.03.13 2.72 3.738386 2.993333 2.24828
3. 函数计算性能
本节将以
EMA
函数为例做直接使用的性能对比,同时使用真实股票日频数据对所有函数进行分组使用性能对比。
3.1. 直接使用性能对比
在 DolphinDB 中:
use ta
close = 7.2 6.97 7.08 6.74 6.49 5.9 6.26 5.9 5.35 5.63
close = take(close, 10000000)
timer x = ta::ema(close, 30)
对一个长度为10000000的向量直接使用 ta 模块中的
ema
函数,耗时为42ms。
与之对应的 Python 代码如下:
import numpy as np
import talib
import time
close = np.array([7.2,6.97,7.08,6.74,6.49,5.9,6.26,5.9,5.35,5.63])
close = np.tile(close,10000000)
start_time = time.time()
x = talib.EMA(close, 30)
print("--- %s seconds ---" % (time.time() - start_time))
Python TA-Lib 库中的
EMA
函数耗时为418ms,是 DolphinDB ta module 中的
ema
函数的10倍左右。
3.2. 分组使用性能对比
测试数据为上海证券交易所2020年,全年2919个证券(筛选交易日大于120)日频交易数据,总记录数为686,104条。下载
测试数据
,解压后放置于[home]下。
计算逻辑为按照股票代码进行分组计算各指标。
为了测试函数计算性能,DolphinDB 和 Python 测试代码都是单线程运行。
测试结果如下表所示:
序号
函数
Python(ms)
DolphinDB(ms)
运行时间比
1
VAR
294
17
17
2
STDDEV
255
21
12
3
BETA
390
42
9
4
SMA
286
16
17
5
EMA
262
14
19
6
WMA
267
17
16
7
DEMA
256
19
13
8
TEMA
262
30
9
9
TRIMA
271
26
10
10
KAMA
273
19
14
11
T3
265
31
9
12
MA
244
19
13
13
BBANDS
298
54
5
14
RSI
278
51
5
15
STOCHF
516
83
6
16
STOCH
477
93
5
17
STOCHRSI
263
133
2
18
TRIX
243
32
7
19
CORREL
327
35
9
20
LINEARREG_SLOPE
229
21
11
21
LINEARREG_INTERCEPT
238
21
11
22
LINEARREG_ANGLE
265
32
8
23
LINEARREG
288
56
5
24
TSF
254
55
5
25
BOP
505
40
12
26
CCI
444
75
6
27
TRANGE
454
25
18
28
PLUS_DM
345
54
6
29
PLUS_DI
413
117
4
30
MINUS_DM
331
58
6
31
MINUS_DI
428
78
5
32
DX
417
118
4
33
ADX
419
110
4
34
ADXR
415
118
4
35
CMO
238
53
4
36
MACD
283
59
5
37
MACDEXT
296
72
4
38
MACDFIX
285
56
5
39
MIDPRICE
365
48
8
40
MIDPOINT
256
44
6
41
MOM
274
17
16
42
ROC
249
23
11
43
ROCP
246
21
11
44
ROCR
248
17
14
45
ROCR100
243
20
12
46
PPO
256
39
6
47
MAVP
401
127
3
48
APO
259
33
8
49
AROON
361
62
6
50
AROONOSC
371
59
6
51
ULTOSC
476
202
2
52
WILLR
435
65
7
53
AD
502
42
12
54
OBV
329
47
7
55
AVGPRICE
503
45
11
56
MEDPRICE
334
20
17
57
TYPPRICE
443
27
16
58
WCLPRICE
411
28
15
59
ATR
422
31
14
60
NATR
419
37
11
61
MFI
510
103
5
从测试结果分析可知:
DolphinDB ta module 中的函数计算性能都超过了 Python TA-Lib 库,最大的性能差距达到18倍,普遍性能差距在9倍左右。
Python pandas测试核心代码
data.groupby("symbol").apply(lambda x: talib.EMA(np.array(x.close), 30))
DolphinDB测试核心代码
select ta::ema(close, timePeriod=30) as `EMA from data context by symbol
4. 正确性验证
基于
分组使用性能对比
中的测试数据和代码,验证 DolphinDB ta module 中函数的计算结果是否和 Python TA-Lib 库一致。
4.1. NULL 值的处理
若 TA-Lib 的输入向量开始包含空值,则从第一个非空位置开始计算。ta 模块采用了相同的策略。
对一个滚动/累积窗口长度为 k 的函数,每组最初的 (k-1) 个位置的结果均为空。这一点 ta 模块与 TA-Lib 模块的结果一致。但若一组中第一个非空值之后再有空值,该组此空值位置以及所有以后位置在 TA-Lib 函数中的结果有可能均为空值。对 ta 模块函数,除非窗口中非空值数据的数量不足以计算指标(例如计算方差时只有一个非空值),否则在这些位置均会产生非空的结果。
DolphinDB 代码与结果:
close = [99.9, NULL, 84.69, 31.38, 60.9, 83.3, 97.26, 98.67]
ta::var(close, 5, 1);
[,,,,670.417819,467.420569,539.753584,644.748976]
Python 代码与结果:
close = np.array([99.9, np.nan, 84.69, 31.38, 60.9, 83.3, 97.26, 98.67])
talib.VAR(close, 5, 1)
array([nan, nan, nan, nan, nan, nan, nan, nan])
上面的总体方差计算中,因为 close 的第二个值为空值,ta 模块和 TA-Lib 的输出不同,TA-Lib 输出全部为空值。如果替换空值为非空值 81.11,ta 模块和 TA-Lib 得到相同的结果。在第一个元素 99.9 之前加一个空值,两者的结果仍然相同。
简而言之,当输入参数中空值,若存在的话,只集中在开始的位置时,ta 模块和 TA-Lib 的输出结果才会完全一致。
4.2. 中间值近似问题
结果有差异的函数:
BETA, CORREL
原因:
BETA, CORREL指标函数的公式为:
在 TA-Lib 中,会对两个分母值用
TA_IS_ZERO
进行判断,如果为真,结果值为0.0,以beta为例,Python TA-Lib部分代码如下:
其中,
TA_IS_ZERO
的定义为:
而在 DolphinDB 的 ta 模块中,我们直接使用内置函数
mbeta
和
mcorr
来计算:
//beta
@state
def beta(high, low, timePeriod=5){
return talib(mbeta, low.ratios() - 1, high.ratios() - 1, timePeriod)
}
//correl
@state
def correl(high, low, timePeriod=30){
high_, low_ = talibNull(high, low)
return talib(mcorr, high, low, timePeriod)
}
这里没有与Python TA-Lib 相同的
TA_IS_ZERO
判断,所以会导致某些结果会与Python TA-Lib计算结果不同。但是使用内置函数
mbeta
和
mcorr
来计算不光能提高计算效率,同时也能以极简的代码实现指标的计算。
4.3. 浮点数精度优化
结果有差异的函数:
CCI, STOCHRSI, MFI
原因:
Python TA-Lib 中,
CCI, MFI
的浮点数精度问题与4.2中所提及的问题相似,会涉及到一些对中间值的判断,如:
/* CCI */
if( (tempReal != 0.0) && (tempReal2 != 0.0) )
...
else
/* MFI */
if( tempValue2 < 0 )
...
else if( tempValue2 > 0 )
...
else
对计算中间值判断是否大于零、小于零、等于或不等于零很有可能会让我们陷入到机器误差造成的麻烦中,举一个例子,在 Python中 运行:
(2.86 + 2.7 + 2.73) - (2.81 + 2.7 + 2.78)
1.7763568394002505e-15
上述计算结果应该是为0,但是由于浮点数的存储机制,最终计算结果就变成了一个很小的正数,这样便会导致判断语句走向错误的分支,使得最终计算结果与正确的结果相差甚远。很明显这并不是 TA-Lib 作者的本意,是浮点数精度问题导致的误差。
另外,
STOCHRSI
也是由于浮点数的细微精度问题造成最终结果与预想的结果相差很大的一个指标。具体来说,
STOCHRSI
可以简单的理解为
STOCH(RSI(close, period), period, fastkPeriod, fastdPeriod, fastdMatype)
,以第一个结果 slowk 为例:
在 Python TA-Lib 中,直接调用了
RSI
,并没有对其做任何处理,这样就会让极小的机器误差对最终结果造成极大的影响。这里举一个例子:
这里计算了一组RSI并打印出了最后5个值,可以看到,close中最后5个值都是2.14,那么RSI最后5个值应该是相等的,但是实际上计算的结果值会有10E-14数量级的误差。也就是说,Python TA-Lib在计算RSI的时候会有一个很小的误差,如果我们只需得到RSI的计算结果,那么这个很小的误差完全是可以忽略的。但如果将RSI的计算结果不加任何处理地作为STOCH的输入的话,这个机器误差就会对最终的结果造成非常大的影响。继续往下,我们用上述例子继续计算slowk,窗口内最大值为
37.95876021268321
,最小值为
37.95876021268319
,当前值为
37.958760212683195
,最终计算得到slowk为 33.33,与真实值 0 相差非常之大!综上所述,
STOCHRSI
同样也是 Python TA-Lib 计算不准确的地方。
针对以上两种浮点数精度造成的问题,DolphinDB 的 ta 模块采取了舍弃部分精度的方法来避免计算中间值的微小机器误差造成的最终结果的巨大误差,从而可以计算出更精确的结果,具体代码如下:
//CCI
@state
def cci(high, low, close, timePeriod=14){
high_, low_, close_ = talibNull(high, low, close)
tp= (high_ + low_ + close_) / 3.0
tmp = tp - talib(mavg, tp, timePeriod)
return iif(abs(tmp) > 1E-12, tmp \ (0.015 * talib(mmad, tp, timePeriod)), 0.0)
}
//MFI
@state
def mfi(high, low, close, volume, timePeriod=14){
tp = round((high + low + close) / 3.0, 8)
deltasTp = deltas(tp)
pos = iif(nullCompare(>, deltasTp, 0), tp, 0)
neg = iif(nullCompare(<, deltasTp, 0), tp, 0)
return talib(msum, pos * volume, timePeriod) * 100 / (talib(msum, pos * volume , timePeriod) + talib(msum, neg * volume , timePeriod))
}
//STOCHRSI
@state
def stochRsi(close, timePeriod=14, fastkPeriod=5, fastdPeriod=3, fastdMatype=0) {
rsidx = round(rsi(close, timePeriod), 8)
high_, low_, close_ = talibNull(rsidx, rsidx, rsidx)
lowestLow = talib(mmin, low_, fastkPeriod)
fastk = (close_ - lowestLow) \ (talib(mmax, high_, fastkPeriod) - lowestLow) * 100
fastd = ma(fastk, fastdPeriod, fastdMatype)
fastk_, fastd_ = talibNull(fastk, fastd)
return fastk_, fastd_
}
5. 实时流计算案例
DolphinDB V1.30.3 版本发布的响应式状态引擎(
createReactiveStateEngine
)是许多金融场景流批统一计算中的重要构件,DolphinDB ta module 对其做了适配,使得 ta 模块中的大部分函数可以在响应式状态引擎中实现增量计算。
当前无法在响应式状态引擎中使用的指标函数:
mavp
。
示例代码如下:
//clean environment
def cleanEnvironment(){
try{ unsubscribeTable(tableName="inputTable",actionName="calculateTA") } catch(ex){ print(ex) }
try{ dropStreamEngine("taReactiveSateEngine") } catch(ex){ print(ex) }
try{ dropStreamTable(`inputTable) } catch(ex){ print(ex) }
try{ dropStreamTable(`outputTable) } catch(ex){ print(ex) }
undef all
}
cleanEnvironment()
go
//load module
use ta
//load data
schema = table(`tradedate`symbol`high`low`open`close`volume`bs`periods as name, `DATE`SYMBOL`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`BOOL`INT as type)
data=loadText("/data/DolphinDB/200.8/server/testData.csv" ,schema=schema)
//define stream table
share streamTable(1:0, `tradedate`symbol`high`low`open`close`volume`bs`periods, `DATE`SYMBOL`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`BOOL`INT) as inputTable
share streamTable(1:0, `symbol`tradedate`EMA`RSI`ROC`WILLR, `SYMBOL`DATE`DOUBLE`DOUBLE`DOUBLE`DOUBLE) as outputTable
//register stream computing engine
reactiveStateMetrics=<[
tradedate,
ta::ema(close, timePeriod=30) as `EMA,
ta::rsi(close, timePeriod=14) as `RSI,
ta::roc(close, timePeriod=10) as `ROC,
ta::willr(high, low, close, timePeriod=14) as `WILLR
]>
createReactiveStateEngine(name="taReactiveSateEngine", metrics=reactiveStateMetrics, dummyTable=inputTable, outputTable=outputTable, keyColumn=`symbol, keepOrder=true)
subscribeTable(tableName="inputTable", actionName="calculateTA", offset=-1, handler=getStreamEngine("taReactiveSateEngine"), msgAsTable=true, reconnect=true)
//replay data
submitJob("replay", "replay", replay{data, inputTable, `tradedate, `tradedate, 1000, true})
6. DolphinDB ta 指标列表
6.1. Overlap Studies
函数
语法
解释
bBands
bBands(close, timePeriod, nbDevUp, nbDevDn, maType)
Bollinger Bands
dema
dema(close, timePeriod)
Double Exponential Moving Average
ema
ema(close, timePeriod)
Exponential Moving Average
kama
kama(close, timePeriod)
Kaufman Adaptive Moving Average
ma
ma(close, timePeriod, maType)
Moving average
mavp
mavp(inReal, periods, minPeriod, maxPeriod, maType)
Moving average with variable period
midPoint
midPoint(close, timePeriod)
MidPoint over period
midPrice
midPrice(low, high, timePeriod)
Midpoint Price over period
sma
sma(close, timePeriod)
Simple Moving Average
t3
t3(close, timePeriod, vfactor)
Triple Exponential Moving Average (T3)
tema
tema(close, timePeriod)
Triple Exponential Moving Average
trima
trima(close, timePeriod)
Triangular Moving Average
wma
wma(close, timePeriod)
Weighted Moving Average
6.2. Momentum Indicators
函数
语法
解释
adx
adx(high, low, close, timePeriod)
Average Directional Movement Index
adxr
adxr(high, low, close, timePeriod)
Average Directional Movement Index Rating
apo
apo(close,fastPeriod,slowPeriod,maType)
Absolute Price Oscillator
aroon
aroon(high,low,timePeriod)
Aroon
aroonOsc
aroonOsc(high, low, timePeriod)
Aroon Oscillator
bop
bop(open, high, low, close)
Balance Of Power
cci
cci(high, low, close, timePeriod)
Commodity Channel Index
cmo
cmo(close, timePeriod)
Chande Momentum Oscillator
dx
dx(high, low, close, timePeriod)
Directional Movement Index
macd
macd(close, fastPeriod, slowPeriod, signalPeriod)
Moving Average Convergence/Divergence
macdExt
macdExt(close, fastPeriod, fastMaType, slowPeriod, slowMaType, signalPeriod, signalMaType)
MACD with controllable MA type
macdFix
macdFix(close, signalPeriod)
Moving Average Convergence/Divergence Fix 12/26
mfi
mfi(high, low, close, volume, timePeriod)
Money Flow Index
minus_di
minus_di(high, low, close, timePeriod)
Minus Directional Indicator
minus_dm
minus_dm(high, low, timePeriod)
Minus Directional Movement
mom
mom(close, timePeriod)
Momentum
plus_di
plus_di(high, low, close, timePeriod)
Plus Directional Indicator
plus_dm
plus_dm(high, low, timePeriod)
Plus Directional Movement
ppo
ppo(close, fastPeriod, slowPeriod, maType)
Percentage Price Oscillator
roc
roc(close, timePeriod)
Rate of change : ((price/prevPrice)-1)*100
rocp
rocp(close, timePeriod)
Rate of change Percentage: (price-prevPrice)/prevPrice
rocr
rocr(close, timePeriod)
Rate of change ratio: (price/prevPrice)
rocr100
rocr100(close, timeperiod)
Rate of change ratio 100 scale: (price/prevPrice)*100
rsi
rsi(close, timePeriod)
Relative Strength Index
stoch
stoch(high, low, close, fastkPeriod, slowkPeriod, slowkMatype, slowdPeriod, slowdMatype)
Stochastic
stochf
stochf(high, low, close, fastkPeriod, fastdPeriod, fastdMatype)
Stochastic Fast
stochRsi
stochRsi(real, timePeriod, fastkPeriod, fastdPeriod, fastdMatype)
Stochastic Relative Strength Index
trix
trix(close, timePeriod)
1-day Rate-Of-Change (ROC) of a Triple Smooth EMA
ultOsc
ultOsc(high, low, close, timePeriod1, timePeriod2, timePeriod3)
Ultimate Oscillator
willr
willr(high, low, close, timePeriod)
Williams' %R
6.3. Volume Indicators
函数
语法
解释
ad
ad(high, low, close, volume)
Chaikin A/D Line
obv
obv(close, volume)
On Balance Volume
6.4. Volatility Indicators
函数
语法
解释
atr
atr(high, low, close, timePeriod)
Average True Range
natr
natr(high, low, close, timePeriod)
Normalized Average True Range
trange
trange(high, low, close)
True Range
6.5. Price Transform
函数
语法
解释
avgPrice
avgPrice(open, high, low, close)
Average Price
medPrice
medPrice(high, low)
Median Price
typPrice
typPrice(high, low, close)
Typical Price
wclPrice
wclPrice(high, low, close)
Weighted Close Price
6.6. Statistic Functions
函数
语法
解释
beta
beta(high, low, timePeriod)
Beta
correl
correl(high, low, timePeriod)
Pearson's Correlation Coefficient (r)
linearreg
linearreg(close, timePeriod)
Linear Regression
linearreg_angle
linearreg_angle(close, timePeriod)
Linear Regression Angle
linearreg_intercept
linearreg_intercept(close, timePeriod)
Linear Regression Intercept
linearreg_slope
linearreg_slope(close, timePeriod)
Linear Regression Slope
stdDev
stdDev(close, timePeriod, nbdev)
Standard Deviation
tsf
tsf(close, timePeriod)
Time Series Forecast
var
var(close, timePeriod, nbdev)
Variance
6.7. 其它说明
对 TA-Lib 中的 Math Transform 与 Math Operators 类函数,可使用相应的 DolphinDB 内置函数代替。例如,TA-Lib 中的 SQRT, LN, SUM 函数,可分别使用DolphinDB中的
sqrt
,
log
,
msum
函数代替。
下列 TA-Lib 函数尚未在 ta 模块中实现:所有 Pattern Recognition 与 Cycle Indicators 类函数,以及 HT_TRENDLINE(Hilbert Transform - Instantaneous Trendline), ADOSC(Chaikin A/D Oscillator), MAMA(MESA Adaptive Moving Average), SAR(Parabolic SAR), SAREXT(Parabolic SAR - Extended) 函数。
7. 路线图(Roadmap)
尚未实现的 TA-Lib 函数将在未来版本中实现。
完善现有的 TA-Lib 函数:
T3
,
PLUS_DM
,
PLUS_DI
,
MINUS_DM
,
MINUS_DI
,
DX
,
ADX
,
ADXR
,
AROON
,
AROONOSC
。
8. 附件
V1.10.3:
ta.dos
V1.30.20, V2.00.8:
ta.dos
DolphinDB 运行时间测试代码
DolphinDB, Python 运行时间对比测试代码
DolphinDB, Python 正确性验证测试代码
DolphinDB 流批一致性测试代码
下载测试数据
FILE:references/doc_3967.md
# tmstd
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmstd.html
**来源**: DolphinDB 官方文档
---
tmstd
语法
tmstd(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
的样本标准差。
返回值
DOUBLE 类型向量。
例子
T = 1 1 3 5 8 15 15 20
X = 5 2 4 1 2 8 9 10
m=table(T as t, X as x)
select *, tmstd(t, x, 3) from m
t
x
tmstd_t
1
5
1
2
2.1213
3
4
1.5275
5
1
2.1213
8
2
15
8
15
9
0.7071
20
10
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = NULL 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmstd(t, x, 3d) from m
t
x
tmstd_t
2021.01.02
2021.01.02
4
2021.01.04
2021.01.05
-1
2021.01.07
2
2.1213
2021.01.08
4
1.4142
select *, tmstd(t, x, 1w) from m
t
x
tmstd_t
2021.01.02
2021.01.02
4
2021.01.04
2021.01.05
-1
3.5355
2021.01.07
2
2.5166
2021.01.08
4
2.3629
相关函数:
mstd
,
std
FILE:references/doc_3972.md
# mvccTable
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mvccTable.html
**来源**: DolphinDB 官方文档
---
mvccTable
语法
mvccTable(X, [X1], [X2], .....)
或
mvccTable(capacity:size, colNames, colTypes, [path],
[tableName]
, [defaultValues],
[allowNull]
)
详情
创建一个多版本并发控制的表(MVCC
表)。我们可以对该表进行并发读写。多版本并发控制的表适用于频繁读写但很少更新和删除记录的场景。
如果指定了
path
和
tableName
参数,会把表持久化到硬盘上。通过
loadMvccTable
函数,可以把磁盘上的表加载到内存中。
注:
不支持对 MVCC
表进行以下操作:addColumn、reorderColumns!、upsert!、drop、erase!。
当
size
=0 时,即使对某列设置
allowNull
=false,也可以成功创建空表,但不能向该列追加空值。
参数
对于第一种用法,
X
,
X1
,
X2
...是向量。
对于第二种用法:
capacity
是正整数,表示表的容量,即建表时系统为该表分配的内存(以记录数为单位)。当记录数超过
capacity
时,系统会自动扩充容量。系统首先会分配当前容量1.2~2倍的内存,然后复制数据到新的内存空间,最后释放原来的内存。对于规模较大的表,扩容时的内存占用会很高。因此,建议创建内存表时预先分配一个合理的容量。
size
是正整数,表示该表新建时的行数。若
size
=0,创建一个空表;若
size
>0,则新建表中记录的初始值由
defaultValues
决定。
colNames
是字符串向量,表示列名。
colTypes
是向量,表示列的数据类型。
path
是一个字符串,表示保存表的路径。只能指定磁盘路径,不支持指定为分布式数据库路径。
tableName
是一个字符串,表示保存到磁盘上的表名。
defaultValues
是与
colNames
等长的元组,表示建表时各列的默认值。若不指定,则:
BOOL 类型默认值为 false;
数值类型、时间类型、IPADDR、COMPLEX、POINT 的默认值为 0;
Literal, INT128 类型的默认为 NULL。
allowNull
是与
colNames
等长的布尔类型向量,表示是否允许各列包含空值。默认值为
true,允许包含空值。
例子
例1:介绍两种创建 MVCC 表的方法
第一种用法:
id=`XOM`GS`AAPL
x=102.1 33.4 73.6
mvccTable(id, x);
id
x
XOM
102.1
GS
33.4
AAPL
73.6
第二种用法:
mvccTable(200:10, `name`id`value, [STRING,INT,DOUBLE],"/home/DolphinDB/Data","t1");
name
id
value
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
"/home/DolphinDB/Data"
目录下会有一个名为 "t1"
文件夹、t1.tbl 文件和 t1.sym 文件。如果需要删除磁盘上的表,需要把这三个文件都删除。
例2:创建分区 MVCC
内存表:
n=200000
colNames = `time`sym`qty`price
colTypes = [TIME,SYMBOL,INT,DOUBLE]
trades_mvcc1 = mvccTable(n:0, colNames, colTypes)
trades_mvcc2 = mvccTable(n:0, colNames, colTypes)
db=database(, VALUE, `A`D)
trades = createPartitionedTable(db,table=[trades_mvcc1, trades_mvcc2], tableName="", partitionColumns=`sym)
在 2.00.10.4 版本之前,只支持对分区 MVCC
内存表的子表进行更新、插入和删除操作:
insert into trades_mvcc1 values(09:30:00.001,`A,100,56.5)
insert into trades_mvcc2 values(09:30:01.001,`D,100,15.5)
insert into trades values(09:30:00.001,`D,100,26.5)
// 报错:Can't append data to a segmented table that contains external partitions.
select * from trades;
表
1
.
time
sym
qty
price
09:30:00.001
A
100
56.5
09:30:01.001
D
100
15.5
2.00.10.4 版本开始支持直接对分区 MVCC
内存表进行更新、插入和删除操作:
insert into trades values(09:30:00.001,`D,100,26.5)
select * from trades;
表
2
.
time
sym
qty
price
09:30:00.001
A
100
56.5
09:30:01.001
D
100
15.5
09:30:01.001
D
100
26.5
delete from trades where sym=`A
select * from trades;
表
3
.
time
sym
qty
price
09:30:01.001
D
100
15.5
09:30:01.001
D
100
26.5
update trades set price=price*10 where sym=`D
select * from trades;
表
4
.
time
sym
qty
price
09:30:01.001
D
100
155
09:30:01.001
D
100
265
需要注意的是,直接向子表插入数据时,系统不会校验向子表插入的数据是否与该表匹配。如果插入了不匹配的数据,会导致分区 MVCC
内存表的数据混乱。 因此,为了确保数据的准确性,建议用户直接对分区 MVCC 内存表进行操作,而不要操作子表。
FILE:references/doc_3974.md
# til
**URL**: https://docs.dolphindb.cn/zh/funcs/t/til.html
**来源**: DolphinDB 官方文档
---
til
语法
til(n)
详情
返回 0 到
n
-1 的整型向量。注意:若
n
为 0,则返回空向量。
注:
返回值的类型与
n
的类型保持一致,如:若
n
类型是 LONG,则返回值的类型是 FAST
LONG VECTOR。
参数
n
非负整数。
例子
til(0);
// output
[]
til(5);
// output
[0,1,2,3,4]
n = 10;
t = table(2022.01.01 + til(n) as date, rand(10.0, n) as val);
t;
// output
date val
2022.01.01 8.403
2022.01.02 9.424
2022.01.03 0.4779
2022.01.04 1.8934
2022.01.05 9.6637
2022.01.06 1.7993
2022.01.07 7.1143
2022.01.08 8.3044
2022.01.09 2.6919
2022.01.10 1.9294
相关函数:
take
,
rand
FILE:references/doc_3975.md
# mlastNot
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mlastnot.html
**来源**: DolphinDB 官方文档
---
mlastNot
语法
mlastNot(X, window, [k=NULL], [minPeriods=1])
窗口计算规则请参考:
mFunctions
详情
若
X
是向量:
如果没有指定
k
,计算给定长度(以元素个数或时间长度衡量)的滑动窗口内
X
中最后一个不为 NULL 的元素。
如果指定
k
,计算给定长度(以元素个数或时间长度衡量)的滑动窗口内
X
中最后一个不为
k
或 NULL
的元素。
若
X
是矩阵或表,则在每列内进行上述计算。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
k
可选参数,是一个数值或字符串类型的标量,表示用于匹配的数据。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
当
X
是向量时,返回一个向量。
当
X
是矩阵时,返回一个矩阵。
当
X
是表时,对表的每列进行计算,返回相应的结果。
当
X
是元组时,对元组中的每个向量分别计算,返回相应的结果。
例子
例 1
mlastNot(NULL 2 NULL 4 5, 2)
// output: [,2,2,4,5]
例 2
mlastNot(X=matrix(1..5,2..6,3..7), window=2, k=4, minPeriods=2)
#0
#1
#2
2
3
3
3
3
5
3
5
6
5
6
7
例 3
x=table(["s1", "s2", "", "s4", "s5"] as col1, ["s1", "", "s3", "", "s5"] as col2)
mlastNot(X=x, window=2)
#0
#1
s2
s1
s2
s3
s4
s3
s5
s5
例 4
T = [2022.01.01, 2022.01.02, 2022.01.03, 2022.01.06, 2022.01.07, 2022.01.08, 2022.01.10, 2022.01.11]
X = 1..8
X1 = indexedSeries(T, X)
mlastNot(X=X1, window=3, k=1, minPeriods=1)
#0
2022.01.01
2022.01.02
2
2022.01.03
3
2022.01.06
4
2022.01.07
5
2022.01.08
6
2022.01.10
7
2022.01.11
8
FILE:references/doc_3977.md
# solve
**URL**: https://docs.dolphindb.cn/zh/funcs/s/solve.html
**来源**: DolphinDB 官方文档
---
solve
语法
solve(X, Y)
详情
返回线性方程 X*b=Y 的解 b。
参数
X
是矩阵;
Y
是向量。
返回值
一个向量。
例子
m=1..4$2:2;
m;
#0
#1
1
3
2
4
m.solve(7 10);
// output
[1, 2]
FILE:references/doc_3984.md
# saveTable
**URL**: https://docs.dolphindb.cn/zh/funcs/s/saveTable.html
**来源**: DolphinDB 官方文档
---
saveTable
语法
saveTable(dbHandle, table, [tableName], [append=false],
[compression=false])
详情
将一个表保存在未分区的本地磁盘表中。该命令必须要用户登录后才能执行。
如果要把表保存至分区数据库中,需要先使用
createPartitionedTable
函数创建分区表,再使用
append!
函数或
tableInsert
函数把数据保存至分区表中。
注:
磁盘表仅应用于备份数据和本地计算的场景,其相较于分布式表,在使用上具有一定局限,例如不能进行权限控制等。
参数
dbHandle
是一个未分区的数据库的句柄。
table
是将要被保存的内存中的表。
tableName
是要保存的表的名称。如果没有指定,将会与内存中的表的名称相同。它需要用反引号(`)或双引号引用。
append
设置了追加模式。当它为 true 时,新的表会被追加到旧的表之后。默认的设置是 false。
compression
设置压缩模式。当它为 true 时,表会以压缩模式保存到磁盘中。默认的设置是
false。
例子
db=database("C:/DolphinDB/Data/db1")
t=table(take(1..10,10000000) as id, rand(10,10000000) as x, rand(10.0,10000000) as y);
把表 t 保存为本地磁盘表:
saveTable(db, t);
指定
tableName
:
saveTable(db, t, `t1);
指定
tableName
,并把
append
设置为 true:
saveTable(db, t, `t2, 1);
指定
tableName
,并把
compression
设置为 true:
saveTable(db, t, `t3, 0, 1);
FILE:references/doc_3986.md
# corr
**URL**: https://docs.dolphindb.cn/zh/funcs/c/corr.html
**来源**: DolphinDB 官方文档
---
corr
语法
corr(X,Y)
详情
计算
X
和
Y
之间的相关性(correlation)。
当
X
或
Y
的方差为 0 时,返回值为 NULL。
参数
Y
和
X
是相同长度的数值型向量、维度相同的矩阵或表。若
X
是表,只对其内数值型和布尔型的列进行计算。
返回值
DOUBLE 类型标量/向量/表。
例子
x = 7 4 5 8 9 3 3 5 2 6 12 1 0 -5 32
y=1.1 7 8 9 9 5 4 8.6 2 1 -9 -3 5 8 13
corr(x,y);
// output
0.238769
FILE:references/doc_399.md
# minute
**URL**: https://docs.dolphindb.cn/zh/funcs/m/minute.html
**来源**: DolphinDB 官方文档
---
minute
语法
minute(X)
详情
返回对应的分钟数。
参数
X
可以是整数标量或向量、时间标量或向量。
返回值
MINUTE 类型标量或向量。
例子
minute();
返回:null
minute(1)
返回:00:01m
minute(now());
返回:16:02m
FILE:references/doc_3990.md
# toJson
**URL**: https://docs.dolphindb.cn/zh/funcs/t/toJson.html
**来源**: DolphinDB 官方文档
---
toJson
语法
toJson(X)
详情
将 DolphinDB 对象转换为 JSON 字符串。该 JSON
字符串包含了5个键值对:name(变量名),form(数据结构),type(数据类型),size(长度),value(值)。
针对不同数据形式,
toJson
最大可转换的数据长度不同:
数据形式
最大长度
matrix
300000
set
300000
vector
300000
dict 键值对
300000
table
100000
参数
X
可以是任意数据类型。
返回值
STRING 类型标量。
例子
x=1 2 3
y=toJson(x)
y;
// output
{"name":"x","form":"vector","type":"int","size":"3","value":[1,2,3]}
t=table(1 2 3 as id, 10 20 30 as val)
toJson(t);
// output
{"name":"t","form":"table","size":"3","value":[{"name":"id","form":"vector","type":"int","size":"3","value":[1,2,3]},{"name":"val","form":"vector","type":"int","size":"3","value":[10,20,30]}]}
//set的长度超过30000,toJson最多只能转换前30000个元素
x=set(1..400001)
y=toJson(x)
size(fromJson(y))
// output
300000
相关函数:
fromJson
FILE:references/doc_3996.md
# esd
**URL**: https://docs.dolphindb.cn/zh/funcs/e/esd.html
**来源**: DolphinDB 官方文档
---
esd
语法
esd(data, [hybrid], [maxAnomalies], [alpha])
详情
使用 ESD (Extreme Studentized Deviate) 算法对时间序列进行异常检测。
参数
data
是一个数值向量。
hybrid
是一个布尔值,表示是否用中位数和绝对中位差代替 Grubb's test 中 zscore
计算的平均值和标准差。如果
hybrid
为 true,算法更具鲁棒性。默认值为 false。
maxAnomalies
是一个正整数或(0, 0.5)之间的浮点数。默认值为0.1。
如果
maxAnomalies
是正整数,
maxAnomalies
必须小于
data
长度的一半,函数最多检测
maxAnomalies
个异常点。
如果
maxAnomalies
是(0, 0.5)之间的浮点数,函数最多检测
int(size(data) * maxAnomalies) 个异常点。
alpha
是一个正数,表示检验的显著度。
alpha
越大,数据越有可能被判断为异常点。
返回值
返回一个包含异常值的表,该表有两列,index 列记录原始数据中异常值的下标,anoms 列记录异常值。
例子
n = 1000
ts = rand(10.0, n)
ts[500 600 700 999] += 20
esd(ts);
index
anoms
600
29.815742
700
25.517493
500
25.17515
999
24.748516
相关函数:
stl
,
seasonalEsd
FILE:references/doc_4009.md
# adfuller
**URL**: https://docs.dolphindb.cn/zh/funcs/a/adfuller.html
**来源**: DolphinDB 官方文档
---
adfuller
语法
adfuller(X, [maxLag], [regression="c"], [autoLag="aic"], [store=false],
[regResults=false])
详情
进行 Augmented Dickey-Fuller (ADF) 单位根检验。用于在序列相关性存在的情况下测试单变量过程中是否存在单位根。
参数
X
数值向量,表示需要进行单位根检验的时间序列数据。
X
中的所有元素不能完全相同且不能包含空值。
maxLag
非负整数,指定检验中使用的最大滞后期,默认值为 12*(nobs/100)^(1/4),其中 nobs 代表样本数量。
regression
字符串,指定在回归中使用的常数和趋势阶数。取值有如下选择:
"c":默认值,表示只使用常数。
"ct:使用常数和趋势。
"ctt":使用常数、线性趋势和二次趋势。
"n":不使用常数和趋势。
autoLag
字符串,指定在 0~maxLag 中自动确定滞后期长度时使用的方法。取值有如下选择:
"aic":默认值,表示使用 Akaike Information Criterion 来确定滞后期数值。
"bic":表示使用 Bayesian information criterion 来确定滞后期数值。
"tstat":将滞后期初始值设为 maxLag,然后逐步减 1,直到上一个滞后期数值的 t 统计量在 5% 显著性水平上显著。
"max":将滞后期数值设置为 maxLag。
store
:布尔标量。设置为 true 时,除了返回 ADF 统计值,还会把回归结果放在一个字典中返回。默认值为 false。
regResults
:布尔值。设置为 true 时,返回完整的回归结果,相比于
store
=true 的结果额外包含一个字典
autoLagResult,记录在自动滞后阶数选择过程中使用的信息准则的结果。默认值为 false。
返回值
以字典的形式输出 ADF 检验的结果,字典包括以下内容:
adfStat:浮点数标量,表示检验的统计值
pValue:浮点数标量,表示 MacKinnon 近似 p 值
usedLag:整数标量,使用的滞后期的数值
nobs:整数标量,用于 ADF 回归和关键值计算的观测数量
criticalValues:字典,在 1%、5% 和 10% 水平上的检验统计量的临界值
icBest:浮点数标量,仅在 autoLag 不设置为"max" 时返回,表示最大化的信息准则
resultStore:字典,当 regResults 或者 store 设置为 true 时,把回归结果保存在 resultStore 中返回
例子
data = 234 267 289 301 312 323 334 345 356 367
adfuller(data);
输出为字典:
pValue->0.000375626192024
usedLag->0
nobs->9
icBest->-195.234657936244450
adfStat->-4.341905848945339
criticalValues->[-4.473135048010974,-3.289880603566529,-2.772382345679012]
FILE:references/doc_401.md
# pair
**URL**: https://docs.dolphindb.cn/zh/funcs/p/pair.html
**来源**: DolphinDB 官方文档
---
pair
语法
pair(a, b)
或
a:b
详情
返回一个数据对。
参数
a
和
b
必须是标量。
返回值
数据对标量,类型同
a
/
b
。
例子
1:3+1;
// output: 2:4
1:3<0:6;
// output: 0 : 1
FILE:references/doc_4014.md
# reciprocal
**URL**: https://docs.dolphindb.cn/zh/funcs/r/reciprocal.html
**来源**: DolphinDB 官方文档
---
reciprocal
语法
reciprocal(X)
详情
返回
X
的倒数。
参数
X
可以是数值型标量、向量或矩阵。
返回值
返回结果为 DOUBLE 类型。
例子
reciprocal(10);
// output
0.1
reciprocal(1 2 4 8);
// output
[1,0.5,0.25,0.125]
reciprocal(1 2 4 8$2:2);
#0
#1
1
0.25
0.5
0.125
FILE:references/doc_4052.md
# cumbeta
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumbeta.html
**来源**: DolphinDB 官方文档
---
cumbeta
语法
cumbeta(Y, X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
累积计算
Y
在
X
上的回归系数的最小二乘估计。
返回值
DOUBLE 类型,其数据形式取决于
X
(
Y
)。
例子
x=1 3 5 7 11 16 23
y=1 6 9 8 15 23 34;
cumbeta(y,x);
// output
[,2.5,2,1.2,1.256757,1.365322,1.440948]
相关函数:
beta
FILE:references/doc_4054.md
# dropAggregator
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropAggregator.html
**来源**: DolphinDB 官方文档
---
dropAggregator
是
dropStreamEngine
的别名。
FILE:references/doc_4056.md
# stopDataNode
**URL**: https://docs.dolphindb.cn/zh/funcs/s/stopDataNode.html
**来源**: DolphinDB 官方文档
---
stopDataNode
语法
stopDataNode(X)
详情
用于在集群控制器上停止数据节点/计算节点。
参数
X
是一个向量。包含了要停止的数据节点/计算节点的信息。
例子
x = ["192.168.1.27:8506","192.168.1.27:8502","192.168.1.27:8527"]
stopDataNode(x);
FILE:references/doc_4066.md
# lowDouble
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lowDouble.html
**来源**: DolphinDB 官方文档
---
lowDouble
语法
lowDouble(X)
详情
返回值为
X
的低位8字节的数据,为 DOUBLE 类型。
参数
X
是一个标量或向量,必须是16字节的数据类型。
例子
x=1 2 3 4
y=4 3 2 1
points = point(x, y)
x1 = lowDouble(points)
输出返回:[1,2,3,4]
获取一个复数的实部(实数):
a=complex(2, 5)
lowDouble(a)
输出返回:2
FILE:references/doc_407.md
# loadModuleFromScript
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadmodulefromscript.html
**来源**: DolphinDB 官方文档
---
loadModuleFromScript
语法
loadModuleFromScript(moduleNamespace, moduleScript,
[reload=false])
详情
解析包含模块定义的字符串,并加载该模块。如果模块脚本中包含模块引用,则无需关注其依赖顺序,函数会自动解析。
参数
moduleNamespace
:字符串标量或向量,表示模块的命名空间。如果模块之间存在依赖,则需要输入全部模块的命名空间。
moduleScript
:字符串标量或向量,表示模块的脚本。
reload
:布尔标量,表示是否重新加载模块,默认值为 false。如果之前已加载同名模块,要使更新的
moduleScript
生效,必须将此参数设置为 true。
返回值
无。
例子
moduleName = "test"
moduleScript = "module test \n def testFunc(x,y){ return x+y }"
loadModuleFromScript(moduleName,moduleScript)
go
test::testFunc(2,3)
// output
5
如果模块脚本中包含模块引用:
moduleNames = ["test2","test1"]
moduleScripts = [
"module test2
use test1
def func4(x,y){
return func1(x) + func2(y)
}
",
"module test1
def func1(x){
return x+1
}
def func2(x){
return x+2
}
def func3(x){
print(func1(x)+func2(x))
}
"
]
loadModuleFromScript(moduleNames,moduleScripts)
go
test1::func3(2)
// output
7
test2::func4(2,3)
// output
8
FILE:references/doc_4077.md
# isLeapYear
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isLeapYear.html
**来源**: DolphinDB 官方文档
---
isLeapYear
语法
isLeapYear(X)
详情
判断
X
是否为闰年。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
返回值
布尔标量或向量。
例子
isLeapYear(2012.06.12T12:30:00);
// output: true
isLeapYear([2012.01.01,2013.01.01,2014.01.01,2015.01.01]);
// output: [true,false,false,false]
FILE:references/doc_4081.md
# ema
**URL**: https://docs.dolphindb.cn/zh/funcs/e/ema.html
**来源**: DolphinDB 官方文档
---
ema
语法
ema(X, window, warmup=false)
TA-lib 系列函数参数说明和窗口计算规则请参考:
TA-lib 系列
详情
在给定长度(以元素个数衡量)的滑动窗口内,计算
X
的指数移动平均(Exponential Moving
Average)。
其计算公式为:
warmup
=false:
warmup
=true:
其中:EMA
k
为第 k 个指数移动平均值,n 为移动窗口长度,X
k
为向量 X 中第 k
个元素。
参数
warmup
布尔值,默认为 false,即计算结果的前
window
-1 个元素为空值。若为 true,则结果的前
window
-1 元素将由详情给出的公式计算得出。
返回值
返回 DOUBLE 类型,数据形式同
X
。
例子
x=12.1 12.2 12.6 12.8 11.9 11.6 11.2
ema(x,3);
// output
[,,12.3,12.55,12.225,11.9125,11.55625]
ema(x,3, warmup=true)
// output
[12.1,12.2,12.4667,12.6333,12.2667,11.9333,11.5667]
x=matrix(12.1 12.2 12.6 12.8 11.9 11.6 11.2, 14 15 18 19 21 12 10)
ema(x,3);
#0
#1
12.30
15.666667
12.55
17.333333
12.225
19.166667
11.9125
15.583333
11.55625
12.791667
相关函数:
gema
,
wilder
,
dema
,
tema
FILE:references/doc_4089.md
# mLowRange
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mlowrange.html
**来源**: DolphinDB 官方文档
---
mLowRange
语法
mLowRange(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内,统计每个元素 Xi 左侧相邻且连续大于它的元素个数。NULL 被视为最小值。
若
X
是矩阵,在每列内进行上述计算。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的 INT 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,在每列内分别进行计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
x = [NULL, 3.1, NULL, 3.0, 2.9, 2.8, 3.1, NULL, 3.2]
mLowRange(x, window=3)
// output: [,,1,0,1,2,0,2,0]
mLowRange(x, window=3, minPeriods=1)
// output: [,0,1,0,1,2,0,2,0]
mLowRange(x, window=3, minPeriods=2)
// output: [,,,0,1,2,0,2,0]
date = [0, 1, 2, 3, 7, 8, 9, 10, 11] + 2020.01.01
X = indexedSeries(date, x)
mLowRange(X, 3d)
#0
2020.01.01
2020.01.02
0
2020.01.03
1
2020.01.04
0
2020.01.08
0
2020.01.09
1
2020.01.10
0
2020.01.11
2
2020.01.12
0
m = matrix(1 2 3 NULL, 1 2 NULL 3, 1 3 NULL NULL, 1 2 3 4)
mLowRange(m, 2)
#0
#1
#2
#3
0
0
0
0
0
1
1
0
1
0
0
FILE:references/doc_4091.md
# getInstrumentNearDelivery
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentneardelivery.html
**来源**: DolphinDB 官方文档
---
getInstrumentNearDelivery
语法
getInstrumentNearDelivery(instrument)
详情
根据输入的金融工具,获取该工具的近端交割日期(near delivery date)。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DATE 类型标量或向量。
例子
swap = {
"productType": "Swap",
"swapType": "FxSwap",
"version": 0,
"currencyPair": "EURUSD",
"direction": "Buy",
"notional": ["EUR", 1E6],
"nearStrike": 1.1,
"nearExpiry": 2025.12.08,
"nearDelivery": 2025.12.10,
"farStrike": 1.2,
"farExpiry": 2026.06.08,
"farDelivery": 2026.06.10
}
ins = parseInstrument(swap)
getInstrumentNearDelivery(ins)
// output: 2025.12.10
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_4097.md
# loadModule
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadModule.html
**来源**: DolphinDB 官方文档
---
loadModule
语法
loadModule(name, [moduleDir])
详情
将模块或插件中的函数加载成系统的内置函数。如果加载的模块依赖了其他模块,系统会一并加载其他模块。该函数必须要用户登录后才能执行。
系统启动时,根据配置项
moduleDir
的设置,寻找并决定模块所在目录:
配置项
moduleDir
设置为一个绝对目录,则该目录即为搜索模块所在的目录。
配置项
moduleDir
设置为一个相对目录,系统会依次在
HOMEDIR
,
WORKDIR
和
EXECDIR
三个目录下搜索。如果找到了,就以该目录作为
moduleDir
;如果搜索不到,就以
<HOMEDIR>
+ “/” +
<moduleDir>
作为 modules 的绝对目录
配置项
moduleDir
没有设置,搜索方式同相对目录。
如果
modules
目录中包含同名的 dos 文件和 dom 文件,系统仅会加载 dom 文件。
注:
该函数只能在系统的初始化脚本(默认为
dolphindb.dos
文件)中使用。
loadModule
函数与配置参数
preloadModules
的功能相同。
参数
name
是一个字符串,表示模块的名称。
moduleDir
是一个字符串,表示模块 dos 文件或 dom 文件所在的目录。
返回值
无。
例子
例1. 加载模块
loadModule("ta");
loadModule("system::log::fileLog");
例2. 加载插件
loadModule("plugins::mysql");
loadModule("plugins::odbc");
FILE:references/doc_4104.md
# getStreamTableFilterColumn
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getStreamTableFilterColumn.html
**来源**: DolphinDB 官方文档
---
getStreamTableFilterColumn
语法
getStreamTableFilterColumn(streamTable)
详情
返回由函数
setStreamTableFilterColumn
指定的流数据表中过滤列的名称。
参数
streamTable
是流数据表。
返回值
字符串标量。
例子
share streamTable(10000:0,`time`symbol`price, [TIMESTAMP,SYMBOL,INT]) as trades
setStreamTableFilterColumn(trades, `symbol)
trades_1=table(10000:0,`time`symbol`price, [TIMESTAMP,SYMBOL,INT])
filter=symbol(`IBM`GOOG)
subscribeTable(tableName=`trades, actionName=`trades_1, handler=append!{trades_1}, msgAsTable=true, filter=filter);
n=100
time=take(2018.01.01T09:30:00.000,n)
symbol=take((`IBM`GOOG`AAPL`C`BABA),n)
price=1..n
t=table(time,symbol,price)
trades.append!(t)
// 获取流数据表trades由setStreamTableFilterColumn函数指定的过滤列名
getStreamTableFilterColumn(trades) ;
// output: symbol
FILE:references/doc_4105.md
# enableResourceTracking
**URL**: https://docs.dolphindb.cn/zh/funcs/e/enableresourcetracking.html
**来源**: DolphinDB 官方文档
---
enableResourceTracking
语法
enableResourceTracking()
详情
在线开启资源跟踪。仅当
resourceSamplingInterval
设置为正整数时才能调用该函数。该函数仅限管理员在数据节点上调用。
成功启动资源跟踪后,各个数据节点会根据
resourceSamplingInterval
设置的时间间隔获取以下资源:CPU、内存和数据使用量、查询分布式表的信息。
CPU、内存和数据使用量写入一个 CSV 日志文件,路径是
<HomeDir>/resource/hardware.log
。日志记录了以下信息:
timestamp:NANOTIMESTAMP 类型的时间戳。
userId:登录用户名。
cpu:当前用户占用的工作线程数量。
memory:内存使用量,当前用户使用的所有变量的内存占用大小。单位是字节。
send:单次采集间隔内发送的数据量。单位是字节。
recv:单次采集间隔内接收的数据量。单位是字节。需要注意的是,统计的接收数据量可能会有一定误差,最大误差范围在 2KB 以内。
查询分布式表的信息写入另一个 CSV
日志文件,路径是
<HomeDir>/resource/access.log
。目前仅支持 SQL SELECT
语句,并且在跟踪过程中不会记录非标准 SQL-92 嵌套表连接中的表信息,例如在 ej(ej(t1, t2, `id), t3, `id) 查询中,t1
和 t2 的信息将不会被记录。日志记录了以下内容:
timestamp:NANOTIMESTAMP 类型的时间戳。如果 type 是 sql,则这里记录开始执行 SQL 的时间戳;如果
type 是 rowCount 或 memUsage,则这里记录的是读出数据的时间戳。
rootQueryId:SQL 查询任务的 ID,是分布式 SQL 查询任务的唯一标识符。一个分布式查询会按分区拆分为多个 SQL
子查询。该 ID 为分布式查询及其拆分出的子查询的根 ID。
userId:用户名。
database:数据库名。
table:表名。
type:记录的信息类型,包括3类:sql, rowCount, memUsage。
value:
当类型为 sql 时,为 SQL 查询任务的执行次数。该值总是为1。
当类型为 rowCount 时,为读出的行数。
当类型为 memUsage 时,为读出的表的数据量。单位是字节。
注意:这里只记录每次访问表的行数和数据量。例如维度表读入内存后,会记录每次访问该表的行数和数据量,而非第一次读入内存的数据量。
script:当类型为 sql 时,记录 SQL 脚本,其他类型则为空字符串。
为防止文件大小持续增长,DolphinDB
对这两个文件都采用日志滚动策略,一旦文件大小达到阈值就会生成滚动日志文件。文件名以时间戳作为前缀。例如20231101162302_access.log,表示
2023.11.01T16:23:02 拆分出来的滚动日志。
系统会根据
resourceSamplingLogRetentionTime
的配置值自动清理资源跟踪日志。此自动清理机制不受资源跟踪功能的开启或关闭影响。
参数
无。
返回值
无。
相关函数:
disableResourceTracking
FILE:references/doc_4113.md
# polyFit
**URL**: https://docs.dolphindb.cn/zh/funcs/p/polyfit.html
**来源**: DolphinDB 官方文档
---
polyFit
语法
polyFit(X, Y, n, mode)
详情
使用最小二乘法基于给定的数据点
X
和
Y
,计算 n 次多项式的最佳拟合系数。
参数
X
数值型向量,表示自变量数据点,不能包含空值。
Y
与
X
等长的数值型向量,表示因变量数据点,不能包含空值。
n
非负整型标量,表示拟合多项式的次数。
mode
布尔标量,用于控制返回字典或者向量,默认为 0,表示返回向量。
返回值
DOUBLE 类型向量,是按升幂排列的系数。
例子
x = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0]
y = [0.0, 0.8, 0.9, 0.1, -0.8, -1.0]
z = polyFit(x, y, 3)
z
[-0.0397,1.6931,-0.8135,0.087]
z = polyFit(x, y, 3, 1)
/*output:
modelName->polyFit
z->[-0.039682539682536,1.693121693121692,-0.813492063492063,0.087037037037037]
predict->polyPredict
FILE:references/doc_4120.md
# mpercentile
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mpercentile.html
**来源**: DolphinDB 官方文档
---
mpercentile
语法
mpercentile(X, percent, window, [interpolation='linear'],
[minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
元素在其对应窗口内的百分位数。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
percent
是0到100之间的整数或小数。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
interpolation
是一个字符串,表示当选中的分位点位于在
X
的第 i 和第 i+1
个元素之间时,采用的插值方法。它具有以下取值:
'linear':
,其中,
'lower':
'higher':
'nearest':
和
之中最接近分位点的数据
'midpoint':
如果没有指定
interpolation
,默认采用 'linear'。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
x=2 1 3 7 6 5 4;
mpercentile(x, percent=50, window=3);
// output: [,,2,3,6,6,5]
mpercentile(x, percent=25, window=3, interpolation="lower");
// output: [,,1,1,3,5,4]
mpercentile(x, percent=75, window=3, interpolation="higher")
// output: [,,3,7,7,7,6]
mpercentile(x, percent=5, window=3, interpolation="nearest")
// output: [,,1,1,3,5,4]
mpercentile(x, percent=15, window=3, interpolation="midpoint")
// output: [,,1.5,2,4.5,5.5,4.5]
mpercentile(x, percent=50, window=3, interpolation="linear", minPeriods=1);
// output: [2,1.5,2,3,6,6,5]
m=matrix(2 1 3 7 6 5 4, 1..7);
m;
#0
#1
2
1
1
2
3
3
7
4
6
5
5
6
4
7
mpercentile(m, percent=50, window=3, interpolation="linear", minPeriods=1);
#0
#1
2
1
1.5
1.5
2
2
3
3
6
4
6
5
5
6
m.rename!(date(2020.09.08)+1..7, `A`B)
m.setIndexedMatrix!()
mpercentile(m, percent=50, window=3d, interpolation="linear", minPeriods=1);
label
col1
col2
2020.09.09
2
1
2020.09.10
1.5
1.5
2020.09.11
2
2
2020.09.12
3
3
2020.09.13
6
4
2020.09.14
6
5
2020.09.15
5
6
mpercentile(m, percent=50, window=1w, interpolation="linear", minPeriods=1);
label
col1
col2
2020.09.09
2
1
2020.09.10
1.5
1.5
2020.09.11
2
2
2020.09.12
2.5
2.5
2020.09.13
3
3
2020.09.14
4
3.5
2020.09.15
4
4
相关函数:
percentile
FILE:references/doc_4130.md
# union
**URL**: https://docs.dolphindb.cn/zh/funcs/u/union.html
**来源**: DolphinDB 官方文档
---
union
语法
union(X, Y)
或
X|Y
详情
返回两个集合的并集。
参数
X
和
Y
是集合
返回值
一个集合。
例子
x=set([5,5,3,4]);
y=set(8 9 9 4 6);
x | y;
// output: set(8,9,6,4,3,5)
FILE:references/doc_4134.md
# getTSDBTableIndexCacheStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/gettsdbtableindexcachestatus.html
**来源**: DolphinDB 官方文档
---
getTSDBTableIndexCacheStatus
语法
getTSDBTableIndexCacheStatus()
详情
TSDB 引擎在查询 Level File 时,会将其尾部的索引信息(包括 zonemap 等)加载 Level File
时加载到内存中。该函数用于获取已加载的数据库中表的 Level File 索引所占用的内存(单位为字节)。结合 getTSDBDataStat 函数,可以评估内存中的
Level File 对应的表的 sort key 设置是否合理。
参数
无。
返回值
一个表,包含以下字段:
dbName:数据库名称。
chunkId:chunk 的唯一标识。
tableName:chunk 所属的表名称。
memUsage:Level File 索引占用的内存,单位为字节。
例子
t = table(1 2 1 1 2 2 3 as month, `Rome`Paris`London`Paris`Rome`London`Rome as city, 200 500 100 300 300 400 400 as sold)
db_name = "dfs://tsdb_01"
if (existsDatabase(db_name)) {
dropDatabase(db_name)
}
db = database(db_name, HASH, [INT, 4], , 'TSDB')
pt = db.createPartitionedTable(t, "pt", "month", ,"sold")
pt.append!(t)
pt1 = db.createPartitionedTable(t, "pt1", "month", ,"sold")
pt1.append!(t)
flushTSDBCache()
getTSDBTableIndexCacheStatus()
dbName
chunkId
tableName
memUsage
dfs://tsdb_01
01e891fa-f66d-7599-7544-4e0449f4e608
pt1_3
680
dfs://tsdb_01
81c0f8f7-e195-b298-da4a-d007492f4733
pt1_3
680
dfs://tsdb_01
17f8bc0b-946e-f688-374c-955c586faccf
pt_2
296
dfs://tsdb_01
1df88c41-bccf-449b-504c-5978df9cc03f
pt_2
680
dfs://tsdb_01
10371e0c-685a-51b1-3042-1ba289514bb9
pt1_3
296
dfs://tsdb_01
0be81d1e-1962-108b-274e-3dc2632921bc
pt_2
680
FILE:references/doc_4141.md
# zTest
**URL**: https://docs.dolphindb.cn/zh/funcs/z/zTest.html
**来源**: DolphinDB 官方文档
---
zTest
语法
zTest(X, [Y], [mu=0.0], [sigmaX=1.0], [sigmaY=1.0],
[confLevel=0.95])
详情
如果没有指定
Y
,对正态分布
X
进行单样本 Z 检验。如果指定了
Y
,对独立正态分布
X
和
Y
进行双样本 Z 检验。
参数
X
是一个数值向量,表示用于 Z 检验的样本。
Y
是一个数值向量,表示用于独立双样本 Z 检验的另一个样本。它是一个可选参数。
mu
是一个浮点数,默认值是0。如果没有指定
Y
,
mu
表示
X
的均值的假设值;如果指定了
Y
,
mu
表示
X
、
Y
均值之差的假设值。
sigmaX
是一个浮点数,表示
X
的标准差。默认值是1。
sigmaY
是一个浮点数,表示
Y
的标准差。默认值是1。
confLevel
是0到1之间的浮点数,表示置信区间的置信水平。
返回值
一个字典,包含以下 key:
stat:一张表,包含三种不同备择假设下的 p 值和置信区间
confLevel:置信水平
method:如果没有指定
Y
,为字符串 "One sample z-test";如果指定了
Y
,为字符串 "Two sample z-test"
zValue:z 的统计量
例子
单样本 Z 检验:
x = norm(5.0, 2.0, 30)
zTest(x, , 5.0, 2.0);
// output
stat->
alternativeHypothesis pValue lowerBound upperBound
--------------------------- -------- ---------- -----------
true mean is not equal to 5 0.035765 3.517659 4.949014
true mean is less than 5 0.017882 -Infinity 4.833952
true mean is greater than 5 0.982118 3.632721 Infinity
confLevel->0.95
method->One sample z-test
zValue->-2.099594
双样本 Z 检验:
x = norm(5.0, 2.0, 30)
y = norm(10.0, 3.0, 40)
zTest(x, y, -5.0, 2.0, 3.0);
// output
stat->
------------------------------------- -------- ---------- -----------
alternativeHypothesis pValue lowerBound upperBound
difference of mean is not equal to -5 0.976133 -6.191162 -3.844655
difference of mean is less than -5 0.488067 -Infinity -4.033283
difference of mean is greater than -5 0.511933 -6.002533 Infinity
confLevel->0.95
method->Two sample z-test
zValue->-0.029917
FILE:references/doc_4143.md
# asin
**URL**: https://docs.dolphindb.cn/zh/funcs/a/asin.html
**来源**: DolphinDB 官方文档
---
asin
语法
asin(X)
详情
返回
X
的反正弦。
参数
X
可以是标量、向量、矩阵或表。
返回值
返回结果的数据形式与输入保持一致:若输入为标量,返回标量;若输入为向量、矩阵或表,返回相同维度的结果。
例子
asin(0 0.5 1);
// output
[0,0.523599,1.570796]
相关函数:
acos
,
atan
,
sin
,
cos
,
tan
,
asinh
,
acosh
,
atanh
,
sinh
,
cosh
,
tanh
FILE:references/doc_4159.md
# getClusterPerf
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getClusterPerf.html
**来源**: DolphinDB 官方文档
---
getClusterPerf
语法
getClusterPerf([includeMaster=false])
详情
获取每个节点的多个配置和性能监控度量值。注意:代理节点的 connectionNum 是一个随机值,可以忽略。
参数
includeMaster
表示获取的节点信息中是否包含控制节点的信息。
返回值
返回一个表对象,包含以下几列:
computeGroup:计算节点所属的计算组。
host:节点的主机名。
port:节点的端口号。
site:节点的局域网信息。
mode:节点的类型。0 表示集群的数据节点,1 表示集群的代理节点,2 表示集群的控制节点,3 表示 single mode 的节点,4
表示计算节点。
state:节点是否存活。
agentSite:当前节点的代理节点信息。
maxConnections:最多可以从多少个外部 GUI ,API 或其它节点连接到本地节点。
maxMemSize:当前节点的内存空间上限(单位:GB)。
workerNum:常规作业的工作线程的数量。默认值是 CPU 的内核数。
executorNum:本地执行线程的数量。默认值是 CPU 内核数减1。
connectionNum:连接到本地节点的连接数。
name:节点别名。
memoryUsed:节点的内存占用量(单位:字节)。
memoryAlloc:系统已分配给当前节点的内存(单位:字节)。
cpuUsage:CPU 使用率。
avgLoad:CPU 平均负载。
medLast10QueryTime:前 10 个完成的查询执行所耗费时间的中间值(单位:纳秒)。注意:必须指定 perfMonitoring=1
才会返回该字段。
maxLast10QueryTime:前 10 个完成的查询执行所耗费时间的最大值(单位:纳秒)。注意:必须指定 perfMonitoring=1
才会返回该字段。
medLast100QueryTime:前 100 个完成的查询执行所耗费时间的中间值(单位:纳秒)。注意:必须指定 perfMonitoring=1
才会返回该字段。
maxLast100QueryTime:前100个完成的查询执行所耗费时间的最大值(单位:纳秒)。注意:必须指定 perfMonitoring=1
才会返回该字段。
maxRunningQueryTime:当前正在执行的查询的耗费时间的最大值(单位:纳秒)。
runningJobs:正在执行中的 Job 个数。
queuedJobs:队列中的 Job 个数。
runningTasks:正在执行中的 Task 个数。
queuedTasks:队列中的 Task 个数。
jobLoad:作业负载。
diskCapacity:磁盘容量(单位:字节)。
diskFreeSpace:磁盘剩余空间(单位:字节)。
diskFreeSpaceRatio:磁盘可用空间占比。
diskWriteRate:磁盘写速率 (单位:字节/秒)。
diskReadRate:磁盘读速率(单位:字节/秒)。
lastMinuteWriteVolume:前一分钟写磁盘容量(单位:字节)。
lastMinuteReadVolume:前一分钟读磁盘容量(单位:字节)。
networkSendRate:网络发送速率(单位:字节/秒)。
networkRecvRate:网络接收速率(单位:字节/秒)。
lastMinuteNetworkSend:前一分钟网络发送字节数(单位:字节)。
lastMinuteNetworkRecv:前一分钟网络接收字节数 (单位:字节)。
publicName:若为控制节点,且配置了 publicName,则显示 publicName;否则显示控制节点所在服务器的
网卡地址。若为数据节点或代理节点,则显示数据节点或代理节点所在服务器的网卡地址。
lastMsgLatency:流数据订阅节点最后收到的消息的延时(单位:纳秒)。
cumMsgLatency:流数据订阅节点所有已接收的消息的平均延时(单位:纳秒)。
isLeader:是否是 raft 组的 leader,该字段仅在配置了控制节点高可用时才生效。请注意,若 raft 组存在宕机的节点,则该节点的
isLeader 将返回空值。
zone:数据节点或计算节点所属的区域。
例子
getClusterPerf()
FILE:references/doc_4164.md
# getTSDBCachedSymbolBaseMemSize
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getTSDBCachedSymbolBaseMemSize.html
**来源**: DolphinDB 官方文档
---
getTSDBCachedSymbolBaseMemSize
语法
getTSDBCachedSymbolBaseMemSize()
详情
获取 TSDB 引擎中 SYMBOL 类型的字典编码的缓存大小,单位是字节。
参数
无
返回值
LONG 类型标量。
FILE:references/doc_4165.md
# convertTZ
**URL**: https://docs.dolphindb.cn/zh/funcs/c/convertTZ.html
**来源**: DolphinDB 官方文档
---
convertTZ
语法
convertTZ(obj, srcTZ, destTZ)
详情
把
srcTZ
时区的时间
obj
转换成
destTZ
时区的时间。
参数
obj
可以是 DATETIME, TIMESTAMP, NANOTIMESTAMP 类型的时间标量或向量。
srcTZ
和
destTZ
都是字符串,表示时区。
返回值
返回一个与输入
obj
相同数据类型和形式的对象。
例子
convertTZ(2016.04.25T08:25:45,"US/Eastern","Asia/Shanghai");
// output
2016.04.25T20:25:45
FILE:references/doc_4171.md
# disableTSDBAsyncSorting
**URL**: https://docs.dolphindb.cn/zh/funcs/d/disableTSDBAsyncSorting.html
**来源**: DolphinDB 官方文档
---
disableTSDBAsyncSorting
语法
disableTSDBAsyncSorting()
详情
TSDB 写入 Cache Engine 中的数据会根据
sortColumns
排序。写入任务和排序任务可以同步或异步进行,该命令用于关闭异步进行数据排序的功能。只能由管理员在数据节点上执行。
参数
无。
返回值
无。
相关函数
:
enableTSDBAsyncSorting
FILE:references/doc_4173.md
# rowVarp
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowVarp.html
**来源**: DolphinDB 官方文档
---
rowVarp
语法
rowVarp(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行元素求总体方差操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL]);
rowVarp(m);
// output
[2.302222222222225,1.448888888888887,4.84]
t1=table(1..5 as x, 10..6 as y, take(3, 5) as z);
t2=table(5..1 as a, 6..10 as b, take(8, 5) as c);
rowVarp(t1);
// output
[14.888888888888891,9.555555555555557,5.555555555555558,2.888888888888891,1.555555555555557]
rowVarp(t1[`x], t2, 1 1 2 2 2);
// output
[7.76,7.440000000000001,6.96,8.8,11.760000000000001]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2);
select sym,rowVarp(price1,price2) as varp from t;
sym
varp
AAPL
3945.7242
MS
113.4225
IBM
108.16
IBM
113.1032
C
5530.8969
相关函数:
rowVar
,
varp
FILE:references/doc_4185.md
# cumnunique
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumnunique.html
**来源**: DolphinDB 官方文档
---
cumnunique
语法
cumnunique(X, [ignoreNull=false])
参数说明和窗口计算规则请参考:
cumFunctions
详情
统计
X
元素的累计唯一值数量。若指定
ignoreNull
=true,则统计唯一值时将不考虑 NULL 值;否则将会统计 NULL
值。
参数
ignoreNull
是一个布尔值,表示是否忽略
X
中 NULL 值。若指定
ignoreNull
=true,则统计唯一值时将不考虑 NULL 值;否则将会统计 NULL 值。默认值为 false。
返回值
INT 类型,其数据形式同
X
。
例子
v = [NULL, 1, 2, -6, 0, 1, 2]
cumnunique(v)
// output: [1,2,3,4,5,5,5]
cumnunique(v,true)
// output: [0,1,2,3,4,4,4]
t = table(`a`a`b`c`a`b as id, 20 20 10 40 30 20 as val)
select cumnunique(id) as cumVal from t
cumVal
1
1
2
3
3
3
FILE:references/doc_4194.md
# accumulate
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/accumulate.html
**来源**: DolphinDB 官方文档
---
accumulate
语法
accumulate(func, X, [init],
[assembleRule|consistent=false])
[init] <operator>:A X
或
func:A([init],
X)
表示不指定
assembleRule
,使用默认值
[init] <operator>:AC X
或
func:AC([init], X)
表示指定
assembleRule
,此例中指定为 C(Consistent)
详情
当 func 是一元函数时,accumulate 先输出
init
,再应用
func
在
init
上,然后迭代地应用
func
到前一个结果上,直至满足
X
指定地迭代条件后输出结果。
X
为整数时,表示
func
进行迭代的次数,输出结果包含
X
+ 1 个元素。注意,X 为负数时,将按0处理。
X
为一元函数时,表示终止条件,返回结果必须为一个布尔标量。若
X
应用在前一个结果上的返回值为 true,
func
继续迭代;否则,
func
停止迭代。
X
没有设置或为 NULL,
func
将进行迭代计算直至输出的结果与前一个结果相同时停止迭代。
当
func
是二元函数时,
accumulate
先应用函数 /
运算符在
init
和
X[0]
上,再迭代地应用函数 / 运算符在前一个结果和当前元素上。当
init
缺失时,
accumulate
返回值的第一个元素是
X[0]
。
accumulate
等同于下面伪代码的执行过程:
result[0]=iif(init==NULL,X[0],<function>(init,X[0]));
for(i:1~size(X)-1){
result[i]=<function>(result[i-1], X[i]);
}
return result;
当
func
是三元函数时,其迭代规则等同于二元函数。
与
reduce
返回最后一个结果不同,
accumulate
输出所有中间结果。
参数
func
:函数。
当
func
是一元函数时,
X
可以是非负整数、一元函数或空值。
init
表示
func
的参数,必须指定。
func
是二元函数时,
X
是向量、矩阵或表。
init
表示初始值。
func
是三元函数时,
X
必须是一个
Tuple,包含2个元素,分别表示
func
的后两个参数。
assembleRule
可选参数,表示如何将子任务的结果合并为函数最终结果。接受一个整数或字符串作为输入,可选值如下:
0 (或 "D"):默认值,表示 DolphinDB
规则,即根据所有子任务的结果来决定最终输出的数据类型和形式。当所有子结果具有相同的数据类型和形式时,多个标量合并为一个向量、多个向量合并为一个矩阵、多个矩阵合并为一个元组、多个字典合并为一张表;否则将所有子结果合并为一个元组输出。
1(或 "C"):表示 Consistent
规则,即认为所有子结果的数据类型和形式都与第一个子结果相同,根据第一个子结果来选择最终结果的数据类型和形式。如果后续子任务返回的结果与第一个子任务的结果类型不一致,系统会尝试对后续结果进行类型转换。如果转换失败则抛出异常。因此,此规则只可在已知子结果的数据类型及形式一致时指定。此规则可使系统免于逐一缓存并检查每个子任务的计算结果,从而提升性能。
2(或 "U"):表示 Tuple 规则,系统不再对各子结果的类型和形式一致性进行检查,而是直接将子结果组装成一个元组输出。
3(或 "K"):表示 kdb+ 规则。与 DolphinDB 规则类似,都会根据所有子结果来决定最终结果形式。主要区别在于,kdb+
规则下,只要有任一子任务返回向量,则最终结果必为一个元组;而在 DolphinDB
规则下,子任务结果若均为长度相同的向量,则最终结果为一个矩阵。其他情况下,kdb+ 规则的输出与 DolphinDB 规则相同。
注:
自 2.00.15
/3.00.3
版本起,新增了
assembleRule
参数。该参数不仅实现了原
consistent
参数的功能,还提供了更多的结果合并选项。
consistent
是一个布尔值,默认值为 false,相当于
assembleRule
="D";若为 true,则相当于
assembleRule
="C"。为保持兼容性,用户仍可使用
consistent
参数。如果同时指定
assemble
和
consistent
,将以
consistent
的值为准。
assembleRule
也可在高阶函数对应的函数模式符号后指定,通过字符 D/C/U/K 表示。以
eachPre (:P)
为例,形如
sub:PU(X)
。不指定则使用默认值 D。
其他相关的 cum 系列函数的参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
返回值
取决于
assembleRule
参数的值。
例子
例1. 当
func
是一元函数时:
通过以下方式定义一个一元函数:
def func1(x){
if(x<5){
return x*3
}
else{
return x+3
}
}
当 X 为整数时,输出结果长度为 X + 1:
accumulate(func1, 5, 1)
返回:[1,3,9,12,15,18]。
当 X 为一元函数 condition 时,第3次迭代时因 condition 返回 false,停止迭代并输出前 2 次的迭代结果。
def condition(x){
return x<9
}
accumulate(func1, condition, 1)
返回:[1,3,9]。
当 X 为 NULL(或不指定)时,自定义函数 func2 作为迭代的函数。由于第 4 次迭代结果和第 3 次相同,停止迭代并输出前 3 次迭代结果。
def func2(x){
if(x<5){
return x*3
}
else{
return 6
}
}
accumulate(func2,NULL,1)
返回:[1,3,9,6]。
例2.
func
是二元函数时,在一个向量上执行 accumulate:
x = 1 2 3;
accumulate(add, 1 2 3);
返回:[1,3,6]。这样的运算等同于 [1, 1+2, 3+3]。
1 +:A x;
返回:[2,4,7]。这样的运算等同于 [1+1, 2+2, 4+3]。
accumulate(-, x, 2);
返回:[1,-1,-4]。这样的运算等同于 [2-1, 1-2, -1-3]。
accumulate(mul, x);
返回:[1,2,6]。这样的运算等同于 [1, 1*2, 2*3]。
通过以下方式计算累积因式分解:
def facts(a) {return 1*:A 1..a;};
facts 5;
返回:[1,2,6,24,120]
通过以下方式计算 log(1) 到 log(i) 之间的累加和。其中,第一行的结果用作第二行
accumulate
的第一个参数值:
def f1(a,b): a+log(b);
accumulate(f1, 1..5, 0);
返回:[0,0.693147,1.791759,3.178054,4.787492]。这等同于:
0+log(1)=0,
0+log(2)=0.693147, 0.693147+log(3)=1.791759, ......
在下面这个例子中,由于忽略了初始条件,输入向量的第一个元素的数据类型决定了返回值的数据类型。
accumulate(f1, 1..5);
返回:[1,1.693147,2.791759,4.178053,5.787491]。
对一个矩阵执行
accumulate
:
x=1..12$3:4;
x;
得到:
col1
col2
col3
col4
1
4
7
10
2
5
8
11
3
6
9
12
+ :A x;
得到:
col1
col2
col3
col4
1
5
12
22
2
7
15
26
3
9
18
30
例3.
func
是三元函数时:
def fun3(x,y,z){
return x+y+z
}
accumulate(fun3,[[1,2,3],[10,10,10]],5)
返回:[16,28,41]。
例 4. 根据两个标志列计算状态列。
假设有一张表包含两个标志列 flag1 和 flag2,希望构造一个状态列 state,其计算逻辑如下:
初始值为 0;
当
state == 0
且
flag1 == 1
时,状态切换为 1;
当
state == 1
且
flag2 == 1
时,状态切换为 0;
否则保持不变。
id = 1..10
flag1 = [0, 1, 1, 0, 0, 0, 0, 0, 0, 0]
flag2 = [0, 0, 0, 0, 0, 1, 1, 0, 0, 0]
t = table(id, flag1, flag2)
def updateStateByFlags(state, f1, f2): iif(state==0 && f1==1, 1, iif(state==1 && f2==1, 0, state))
select *,
accumulate(updateStateByFlags, [flag1, flag2], 0) as state
from t
id
flag1
flag2
state
1
0
0
0
2
1
0
1
3
1
0
1
4
0
0
1
5
0
0
1
6
0
1
0
7
0
1
0
8
0
0
0
9
0
0
0
10
0
0
0
FILE:references/doc_420.md
# splev
**URL**: https://docs.dolphindb.cn/zh/funcs/s/splev.html
**来源**: DolphinDB 官方文档
---
splev
语法
splev(x, tck)
详情
splev
全称 Spline Evaluation,即评估 B 样条曲线或其导数。给定 B
样条表示的节点和系数,使用该函数可求解平滑多项式及其导数的值。若 x, tck 传入参数中包含 None 将直接填充为 0。
注:
不建议自定义
tck
,如果
tck
不是由 splrep 生成,则返回的 y
可能是随机值,也可能全为0。
参数
x
Integral/Temporal/Floating 类型向量。一组点,用来获得样条上的对应的值。
tck
三元组或 B 样条曲线对象。若传入元组,则应为长度为3的序列;若传入 B 样条曲线对象,则应包含节点 t、B 样条系数 c 和样条次数
k,可使用函数
splrep
生成。注意,须遵守
1<=k<=5。
返回值
DOUBLE 类型的向量,表示在 x 点处求解的样条函数值的数组。
例子
x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
y = [0, 3, 5, 6, 5, 3, 1, 2, 4, 5]
newx = [0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]
t=[1,3,5,8]
tck= splrep(x, y, t=t)
print(tck)
// output
([0,0,0,0,1,3,5,8,9,9,9,9],
[0,2.234794827972243,2.999908797063527,8.195517483732592,0.982766102937427,0.416533320193195,6.868465914739519,5,0,0,0,0],
3)
newy = splev(newx, tck)
print(newy)
// output
[2.147514374187927,3.928180605155257,5.780093403045226,5.788551610920491,3.842319632145274,1.928386784305488,1.343262026468735,2.600266282317609,5.680148059970901,-0.902321655035049]
相关函数:
splrep
FILE:references/doc_4202.md
# setDatanodeRestartInterval
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setDatanodeRestartInterval.html
**来源**: DolphinDB 官方文档
---
setDatanodeRestartInterval
语法
setDatanodeRestartInterval(interval)
详情
在线设置控制节点自动重启计算节点/数据节点的功能。该命令只能由管理员在控制节点上调用。
若
interval
=0,则控制节点不会自动重启数据节点/计算节点。
若
interval
>0,则当节点离线时长超过 interval 时,控制节点会自动启动该节点。
注:
该命令并不会改变配置文件中的 datanodeRestartInterval 值。因此,一旦控制节点重启,通过该命令设置的 interval
将失效。
高可用环境下,Leader 节点通过该命令设置的 interval 并不会同步到其它 Follower 节点。
相关函数:
getDatanodeRestartInterval
参数
interval
非负整数,表示时间,单位为秒。
FILE:references/doc_4223.md
# getScheduledJobs
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getScheduledJobs.html
**来源**: DolphinDB 官方文档
---
getScheduledJobs
语法
getScheduledJobs([jobIdPattern])
详情
以表格的形式返回定时任务。如果
jobIdPattern
没有指定,返回所有已有的定时作业。
参数
jobIdPattern
是表示任务 ID 或任务 ID 模式的字符串。它支持通配符“%”和“?”。
返回值
一个表,包含以下字段:
参数
含义
userId
用户 ID。
jobId
在提交定时作业时指定的作业名。
jobDesc
作业描述。
startDate
定时作业的开始日期,为 DATE 类型。
endDate
定时作业的结束日期,为 DATE 类型。
frequency
定时作业的执行频率。
scheduledTime
定时作业的执行间隔,为 MINUTE 类型。
days
frequency 为 'W' 或 'M' 时,执行定时任务的日期。
例子
getScheduledJobs();
userId
jobId
jobDesc
startDate
endDate
frequency
scheduleTime
days
root
monthly
Monthly Job
2018.01.01
2018.12.31
M
17:00m
1
root
weekly
Weekly Job
2018.01.01
2018.12.31
W
17:30m
2
root
daily
Daily Job
2018.01.01
2018.12.31
D
18:00m
FILE:references/doc_4225.md
# addMCPTool
**URL**: https://docs.dolphindb.cn/zh/funcs/a/addMCPTool.html
**来源**: DolphinDB 官方文档
---
addMCPTool
语法
addMCPTool(name, func, [argNames], [argTypes],
[description], [extraInfo])
详情
定义一个 MCP tool。
参数
name
STRING 类型标量,表示 tool 的名称。
func
自定义函数。
argNames
STRING 类型向量,表示参数名。如无参数,请用
[]
表示。
argTypes
STRING 类型向量,表示参数类型,既可指定为 DolphinDB 数据类型,也可指定为 JSON
数据类型。支持的数据类型如下:
DolphinDB 数据类型
JSON 数据类型
STRING
"string"
TEMPORAL
"string"
DOUBLE
"number"
BOOL
"boolean"
STRING[]
"array<string>"
TEMPORAL[]
"array<string>"
DOUBLE[]
"array<number>"
BOOL[]
"array<boolean>"
description
可选参数,STRING 类型标量,表示 tool 的描述。
extraInfo
可选参数,一个字典,键是 STRING 类型,值是 ANY 或 STRING 类型,用于指定其他信息。目前键支持
"title"。
返回值
一个字符串,表示新增 tool 的名称。
例子
def myTool(x) {
return x * 2 + 1
}
info = {
"title": "DolphinDB Tools"
}
addMCPTool(name="myTool", func=myTool, argNames=["a"], argTypes=["number"], description="This is a tool", extraInfo=info)
FILE:references/doc_4232.md
# rowAnd
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowAnd.html
**来源**: DolphinDB 官方文档
---
rowAnd
语法
rowAnd(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行逻辑与操作
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([true false false, true true true, true true true])
rowAnd(m);
// output
[1,0,0]
t1=table(false true true true false as x, false true false true true as y)
rowAnd(t1);
// output
[0,1,0,1,0]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2)
// output
select * from t where rowAnd(price1>30, price2>50);
sym
price1
price2
AAPL
49.6
175.23
IBM
30.02
51.29
相关函数:
and
FILE:references/doc_4241.md
# table
**URL**: https://docs.dolphindb.cn/zh/funcs/t/table.html
**来源**: DolphinDB 官方文档
---
table
语法
table(X, [X1], [X2], .....)
或
table(capacity:size, colNames,
colTypes)
详情
用法一:将单个或多个向量/矩阵/元组,或多个向量和元组的混合数据形式转换成表。
用法二:创建一个固定数据类型的空表或初始化的表。
参数
第一种用法中,
X
,
X1
,
X2
...
可以是向量、数组向量、矩阵或元组。每个向量、元组、数组向量的长度,以及矩阵中每列长度都必须相同。
当 Xk 是元组时:
若 Xk 的元素是等长的向量,
元组的每个元素将作为表的一列。
元组的长度必须等于表的行数。
若 Xk 包含不同类型或不等长元素,
则将单独作为表的一列(列类型为 ANY),其每个元素将作为该列每行的元素值。
Xk
的长度仍然必须和表的行数保持一致。
第二种用法中:
capacity
是正整数,表示建表时系统为该表分配的内存(以记录数为单位)。当记录数超过
capacity
时,系统首先会分配
capacity
1.2~2倍的新的内存空间,然后复制数据到新的内存空间,最后释放原来的内存。对于规模较大的表,此类操作的内存占用会很高。因此,建议建表时预先分配一个合理的
capacity
。
size
是整数,表示该表新建时的行数。若
size
=0,创建一个空表。 若
size
>0,则建立一个只包含 size 条记录的表,记录初始值如下:
BOOL 类型默认值为 false;
数值类型、时间类型、IPADDR、COMPLEX、POINT 的默认值为 0;
Literal, INT128 类型的默认值为 NULL。
注:
如果
colTypes
指定为数组向量,
size
必须为0。
colNames
是一个向量,表示列名。
colTypes
是一个向量,表示每列的数据类型,支持数组向量类型和元组(ANY)类型。可使用表示数据类型的系统保留字或相应的字符串。
返回值
返回一个表,数据类型同
Xk
/
colTypes
。
例子
第一种用法:
id=`XOM`GS`AAPL
x=102.1 33.4 73.6
table(id, x);
id
x
XOM
102.1
GS
33.4
AAPL
73.6
table(`XOM`GS`AAPL as id, 102.1 33.4 73.6 as x);
id
x
XOM
102.1
GS
33.4
AAPL
73.6
m=matrix(1 2, 3 4, 5 6);
m;
#0
#1
#2
1
3
5
2
4
6
table(m);
C0
C1
C2
1
3
5
2
4
6
m.rename!(1 2, `a`b`x);
m;
a
b
x
1
1
3
5
2
2
4
6
table(m);
a
b
x
1
3
5
2
4
6
x=1..6
y=matrix(11..16, 17..22)
z=(101..106, 201..206)
t=table(x,y,z)
t.rename!(`x`y1`y2`z1`z2);
t;
x
y1
y2
z1
z2
1
11
17
101
201
2
12
18
102
202
3
13
19
103
203
4
14
20
104
204
5
15
21
105
205
6
16
22
106
206
元素类型相同且等长的元组将转换为多列(每个元素为一列),混合类型或元素长度不等的元组将转换为 ANY
类型的列:
id = 1 2 3
val = [[1,2,3], [4,5,6],[7,8,9]]
metrics = [`A,[2.2 3.2], 3.2]
t = table(id, val, metrics)
id
col1
col2
col3
metrics
1
1
4
7
A
2
2
5
8
([2.2,3.2])
3
3
6
9
3.2
第二种用法:
table(100:5, `name`id`value, [STRING,INT,DOUBLE]);
name
id
value
0
0
0
0
0
0
0
0
0
0
table(100:5, `name`id`value, `STRING`INT`DOUBLE);
name
id
value
0
0
0
0
0
0
0
0
0
0
table(100:1, [`value], [DOUBLE]);
value
0
FILE:references/doc_4252.md
# randUniform
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randUniform.html
**来源**: DolphinDB 官方文档
---
randUniform
语法
randUniform(lower, upper, count)
详情
生成指定个数的均匀分布随机数。
参数
lower
和
upper
是数值型标量,表示连续均匀分布的下限和上限。
count
是正整数,表示生成的随机数个数。
返回值
长度为
count
的 DOUBLE 类型向量。
例子
randUniform(0.61, 2.31, 2);
// output
[2.064851, 2.263172]
FILE:references/doc_4256.md
# setIndexedSeries!
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setIndexedSeries_.html
**来源**: DolphinDB 官方文档
---
setIndexedSeries!
语法
setIndexedSeries!(X, [on=true])
详情
将一个有行标签的单列矩阵转化为有索引的序列。
参数
X
是一个有行标签的单列矩阵。行标签须严格递增,无重复项。
on
布尔值,表示普通矩阵和索引序列之间的转换。默认为 true,表示将普通矩阵转换成索引序列;若为 false, 表示将索引序列转换为普通矩阵。
返回值
返回一个向量或索引向量。
例子
s = matrix(1..10).rename!(2012.01.01..2012.01.10, ).setIndexedSeries!();
s;
#0
2012.01.01
1
2012.01.02
2
2012.01.03
3
2012.01.04
4
2012.01.05
5
2012.01.06
6
2012.01.07
7
2012.01.08
8
2012.01.09
9
2012.01.10
10
FILE:references/doc_427.md
# xdb
**URL**: https://docs.dolphindb.cn/zh/funcs/x/xdb.html
**来源**: DolphinDB 官方文档
---
xdb
语法
xdb(siteAlias, [userId], [password],
[enableSSL])
或
xdb(host, port, [userId], [password],
[enableSSL])
详情
连接到节点的远程站点。如果连接成功,则返回远程连接的句柄。
参数
siteAlias
是远程节点的别名。它需要在配置文件中定义。
host
是远程节点的主机名(IP 地址或站点)。
port
整型,是远程节点的端口号。
userId
和
password
可选参数。基于用户的配置文件。如果管理员启用用户访问控制,需要输入用户名和密码。
enableSSL
可选参数。布尔值,表示是否使用 SSL 协议进行加密通信。默认值为 false。
返回值
HANDLE 类型,表示远程连接的句柄。
例子
h2=xdb("local8081");
h2;
// output
"Conn[localhost:8081:1166953221]"
h21=xdb("localhost",8081);
h21;
// output
"Conn[localhost:8081:1441295757]"
h4=xdb("local8083","userAdm","passAdm");
h4;
// output
"Conn[localhost:8083:1166953221]"
h41=xdb("localhost",8083, "user001","pass001");
h41;
// output
"Conn[localhost:8083:597793698]"
FILE:references/doc_4278.md
# tmsum2
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmsum2.html
**来源**: DolphinDB 官方文档
---
tmsum2
语法
tmsum2(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
元素的平方和。
返回值
DOUBLE 类型向量。
例子
tmsum2(1 1 3 5 8 15 15 20, 5 2 4 1 2 8 9 10, 3)
// output
[25,29,45,17,4,64,145,100]
index = take(datehour(2019.06.13 13:30:10),4) join (datehour(2019.06.13 13:30:10)+1..6)
data = 1 NULL 3 4 5 NULL 3 NULL 5 3
tmsum2(index, data, 4h)
// output
[1,1,10,26,51,51,60,34,34,43]
tmsum2(index, data, 1d)
// output
[1,1,10,26,51,51,60,60,85,94]
相关函数:
msum2
,
sum2
FILE:references/doc_4279.md
# license
**URL**: https://docs.dolphindb.cn/zh/funcs/l/license.html
**来源**: DolphinDB 官方文档
---
license
语法
license([fileName], [pubKeyFile], [read=false])
详情
显示 DolphinDB 的许可证信息。
注:
若不指定
fileName
,则默认读取保存在内存中的 license 信息
参数
fileName
可选参数。需要指定的 license 文件的路径。
pubKeyFile
可选参数。需要指定的公钥文件的路径。
read
可选参数。布尔值,表示是否关闭对 license 文件的校检功能。默认值为 false,表示进行校检。
返回值
一个字典,包含以下 Key:
Key
含义
authorization
授权的类型:trial(试用版)/test(测试版)/commercial(商业版)。
licenseType
许可证验证类型,有以下可选值:1:机器指纹绑定;2:在线验证;3:license
server;0:其他方式
maxMemoryPerNode
每个节点的内存上限,单位为 GB。
bindCores
进程绑定的 CPU 内核的编号(从0开始)。注意,仅当 bindCPU 为 true
时有效。
maxCoresPerNode
每个节点允许最大 CPU 核数。
clientName
客户名称。
port
为节点绑定的端口号。仅 License Server 和连接它的节点会返回此字段。
bindCPU
进程是否绑定 CPU。
expiration
许可证到期时间。
maxNodes
集群允许的最大节点数。
version
server 的版本号。用户只能使用不高于 version 版本的
server。若为空,则对版本没有限制。
modules
可用模块的编码。若为 13 则表示支持所有模块;若为 -1 则表示不支持任何模块。
moduleNames
与
modules
有关,返回具体的模块名。目前支持返回:orderbook, internalFunction,
cep, gpu, starfish, Beluga
, Backtest,
MatchingEngineSimulator
。社区版返回为空。
productKey
当前产品类型。目前支持返回:DOLPHIN, IOTBASIC, IOTPRO, SHARK, SWORDFISH
, ORCA, DOLPHINX
。
例子
license();
返回:
clientName->internal
bindCPU->true
maxNodes->128
moduleNames-> orderbook internalFunction cep gpu
productKey->DOLPHIN
version->3.10
modules->15
authorization->trial
maxMemoryPerNode->512
licenseType->0
bindCores->
maxCoresPerNode->128
port->0
expiration->2024.09.30
FILE:references/doc_4282.md
# decimal128
**URL**: https://docs.dolphindb.cn/zh/funcs/d/decimal128.html
**来源**: DolphinDB 官方文档
---
decimal128
语法
decimal128(X, scale)
详情
将输入的数据类型转换为 DECIMAL128 类型。
参数
X
整型/浮点型/字符串类型标量或向量。
scale
整型标量,表示保留的小数位数。
返回值
DECIMAL128 类型的标量或向量。
例子
a=decimal128(142, 2)
a
返回:142.00
b=decimal128(1\7, 6)
b
返回:0.142857
a+b
返回:142.142857
a*b
返回:20.28569400
decimal128("3.1415926535", 4)
返回:3.1416
一个 DECIMAL 类型向量里的所有元素的类型和 scale 必须相同,例如:
d1=[1.23$DECIMAL128(4), 3$DECIMAL128(4), 3.14$DECIMAL128(4)];
返回:[1.2300,3.0000,3.1400]
typestr(d1);
返回:FAST DECIMAL128 VECTOR
如果元素的 scale 不同,则会创建并输出元组:
d2=[1.23$DECIMAL128(4), 3$DECIMAL128(4), 3.14$DECIMAL128(3)];
返回:(1.2300,3.0000,3.140)
typestr(d2);
返回:ANY VECTOR
FILE:references/doc_4284.md
# cacheDS!
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cacheDS_.html
**来源**: DolphinDB 官方文档
---
cacheDS!
语法
cacheDS!(ds)
详情
函数
cacheDS!
会在下次执行,并缓存数据。
参数
ds
是数据源或数据源列表。
返回值
返回 true 或 false 表示此操作成功或失败。
例子
PTNDB_DIR = "/home/db_testing"
dbName = database(PTNDB_DIR + "/NYSETAQByName")
Trades = dbName.loadTable(`Trades)
ds=sqlDS(<select Time,Exchange,Symbol,Trade_Volume as Vol, Trade_Price as Price from Trades>)
ds.cacheDS!() // cache the data
ds.clearDSCache!() // clear the cache
FILE:references/doc_4296.md
# adaBoostClassifier
**URL**: https://docs.dolphindb.cn/zh/funcs/a/adaBoostClassifier.html
**来源**: DolphinDB 官方文档
---
adaBoostClassifier
语法
adaBoostClassifier(ds, yColName, xColNames, numClasses,
[maxFeatures=0], [numTrees=10], [numBins=32], [maxDepth=10],
[minImpurityDecrease=0.0], [learningRate=0.1], [algorithm='SAMME.R'],
[randomSeed])
详情
进行 AdaBoost 分类。
生成的模型可以作为
predict
函数的输入。
参数
ds
是数据源,通常用
sqlDS
函数生成。
yColName
是字符串,表示数据源中作为因变量(所属分类)的列名。
xColNames
是字符串标量或向量,表示数据源中作为自变量的列名。
numClasses
是正整数,表示分类数目。y 列的取值必须是[0, numClasses)之间的整数。
maxFeatures
是一个整数或浮点数,表示一次分裂节点选取的特征个数或比例。默认值是0。
如果
maxFeatures
为正整数,则在一次分裂时选取
maxFeatures
个特征。
如果
maxFeatures
=0,则在一次分裂时选取全部特征。
如果
maxFeatures
是一个0和1之间的浮点数,则在一次分裂时选取 int(特征列数量
*
maxFeatures
)个特征。
numTrees
是正整数,表示产生树的最大个数,即停止提升时的最大迭代次数。如果能够完美训练,学习会提前中止。默认值为10。
numBins
是正整数,表示离散化连续特征时的桶数。默认值为32。增加
numBins
会使算法考虑更多的分裂节点的决策值,产生更好的分裂结果,但也会提高计算量和通讯量。
maxDepth
是正整数,表示树的最大深度。默认值为10。
minImpurityDecrease
是浮点数,如果分裂产生的基尼指数纯度减少值大于或等于这个值,节点会继续分裂。
learningRate
是正浮点数,表示迭代过程中的每个分类器对下一个分类器的样本权重的影响。
algorithm
是一个字符串,表示所使用的算法,可以取值 "SAMME.R" 或 "SAMME"。默认值为 "SAMME.R"。
randomSeed
是随机数生成器使用的种子。
返回值
返回一个字典,包含以下 key:numClasses, minImpurityDecrease, maxDepth, numBins, numTrees, maxFeatures, model, modelName, xColNames, learningRate,algorithm。其中 model 是一个元组,保存了训练生成的树;modelName 为 "AdaBoost Classifier"
例子
用模拟数据训练一个 AdaBoost 分类模型
t = table(100:0, `cls`x0`x1, [INT,DOUBLE,DOUBLE])
n=5
cls = take(0, n)
x0 = norm(0, 10, n)
x1 = norm(0, 10, n)
insert into t values (cls, x0, x1)
cls = take(1, n)
x0 = norm(1, 10, n)
x1 = norm(1, 10, n)
insert into t values (cls, x0, x1)
model = adaBoostClassifier(sqlDS(<select * from t>), `cls, `x0`x1, 2);
把模型用于预测
t1 = table(-0.5 0 1 2 as x0, -2 0 1 3 as x1)
predict(model, t1);
保存模型到磁盘,以及加载保存的模型
saveModel(model, "C:/DolphinDB/data/classifierModel.bin");
loadModel("C:/DolphinDB/data/classifierModel.bin");
相关函数:
adaBoostRegressor
,
randomForestClassifier
,
randomForestRegressor
FILE:references/doc_4303.md
# resetPwd
**URL**: https://docs.dolphindb.cn/zh/funcs/r/resetPwd.html
**来源**: DolphinDB 官方文档
---
resetPwd
语法
resetPwd(userId, newPwd)
详情
重置用户的密码。
注:
该函数只能由管理员在控制节点、数据节点和计算节点运行。
参数
userId
表示用户名的字符串。
newPwd
表示用户新密码的字符串。它不能包含空格或控制字符。
从 2.00.10.10 开始,用户可以通过配置项
enhancedSecurityVerification
控制是否对
newPwd
进行复杂性校验。若不设置
enhancedSecurityVerification
,则不校验;若设置
enhancedSecurityVerification
=true,则要求新密码必须满足以下条件:
字符个数为8~20
至少包含一个大写字母
至少包含以下字符之一:!"#$%&'()*+,-./:;<=>?@[]^_`{|}~。
例子
resetPwd("AlexEdwards", "T51pm363.");
FILE:references/doc_431.md
# mpercentileTopN
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mpercentiletopn.html
**来源**: DolphinDB 官方文档
---
mpercentileTopN
语法
mpercentileTopN(X, S, percent, window, top, [interpolation], [ascending],
[tiesMethod='oldest'])
参数说明和窗口计算规则请参考:
mTopN
详情
若
X
是向量,在长度为
window
的滑动窗口内,根据
ascending
指定的排序方式将
X
在窗口内的元素按照
S
进行稳定排序,取其前
top
个元素计算对应的
percent
百分位数。
若
X
是矩阵或表,在每列内进行上述计算,返回同样数据类型和数据维度的结果。
参数
percent
是 0 到 100之间的数,表示计算的百分位数。
interpolation
是一个字符串,表示当选中的分位点位于在
X
的第 i 和第 i+1
个元素之间时,采用的插值方法。它具有以下取值,默认值为 'linear':
‘linear’:X
i
+ ( X
i+1
- X
i
) * fraction,其中
fraction 为
'lower':X
i
'higher’:X
i+1
'nearest': X
i+1
和 X
i
之中最接近分位点的数据
'midpoint':(X
i+1
+ X
i
)/2
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
x = [2,,8,0,4,,6,3,5,7]
s = [,1,8,7,9,6,5,0,4,3]
mpercentileTopN(x, s, percent=25, window=6, top=3, interpolation="lower")
// output:[,,8,0,0,0,6,3,3,3]
mpercentileTopN(x, s, percent=75, window=6, top=3, interpolation="higher")
// output:[,,8,8,8,0,6,6,6,7]
mpercentileTopN(x, s, percent=5, window=6, top=3, interpolation="nearest")
// output:[,,8,0,0,0,6,3,3,3]
mpercentileTopN(x, s, percent=15, window=6, top=3, interpolation="midpoint")
// output:[,,8,4,4,0,6,4.5,4,4]
mpercentileTopN(x, s, percent=50, window=6, top=3, interpolation="linear")
// output:[,,8,4,4,0,6,4.5,5,5]
X = [2.0, , 8.0, 0.0, 4.0, , 6.0, 3.0, 5.0, 7.0]
S = [, 1, 8, 7, 9, 2, 1, 0, 1, 1]
mpercentileTopN(X, S, percent=25, window=6, top=3, ascending=true,
interpolation="lower", tiesMethod="oldest");
// output: [, , 8.0, 0.0, 0.0, 0.0, 6.0, 3.0, 3.0, 3.0]
下图以 mpercentileTopN(x, s, percent=50, window=6, top=3, interpolation="midpoint");
为例,展示函数的计算过程。
其中用蓝框包围的部分为从当前滑动窗口中选取的
S
的元素,虚线框上方为
top
选出的数据,红色箭头表示计算出的结果值。
x = [8,,1,6,9,2,0,,5,3,2,,8,0,4,,6,3,5,7]$10:2
s = [,1,8,7,9,6,5,0,4,3]
mpercentileTopN(x, s, percent=15, window=6, top=3, interpolation="midpoint")
结果为:
#0
#1
1
8
3.5
4
3.5
4
4
0
1
6
1
4.5
2.5
4
4
4
FILE:references/doc_4312.md
# getReactiveMetrics
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getreactivemetrics.html
**来源**: DolphinDB 官方文档
---
getReactiveMetrics
语法
getReactiveMetrics(name)
详情
获取指定名称的 narrowReactiveStateEngine 的计算指标列。
参数
name
字符串,表示 narrowReactiveStateEngine 的名称。
返回值
返回一个表,第一列为 metricName,第二列为 metricCode。
例子
dummy = streamTable(1:0, ["securityID1","securityID2","securityID3","createTime","updateTime","upToDatePrice","qty","value"], [STRING,STRING,STRING,TIMESTAMP,TIMESTAMP,DOUBLE,DOUBLE,INT])
outputTable = streamTable(1:0,["securityID1","securityID2","securityID3","createTime","updateTime","metricNames","factorValue"], [STRING,STRING,STRING, TIMESTAMP,TIMESTAMP,STRING,DOUBLE])
factor = [<createTime>, <updateTime>,<cumsum(qty)>]
Narrowtest = createNarrowReactiveStateEngine(name="narrowtest1",metrics=factor,metricNames="factor1",dummyTable=dummy,outputTable=outputTable,keyColumn=["securityID1","securityID2","securityID3"])
getReactiveMetrics("narrowtest1")
metricName
metricCode
factor1
cumsum(qty)
相关函数:
createNarrowReactiveStateEngine
,
addReactiveMetrics
FILE:references/doc_4317.md
# tmove
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmove.html
**来源**: DolphinDB 官方文档
---
tmove
语法
tmove(T, X, window)
详情
返回
T
向前偏移
window
后对应的
X
中元素。即:对于
T
中每个时间T
i
,向前偏移
window
后为T
i
-
window
, 返回T
i
-
window
对应的
X
中的元素,若
T
中无对应时间,则返回T
i
-
window
前一个临近时间对应的
X
中的元素。
参数
T
是一个递增的整型或时间类型的向量,且不能包含 NULL 值。
X
是一个与
T
长度相同的向量。
window
是一个正整数或一个
duration
。表示向前移动的区间。
返回值
返回一个与输入
X
相同数据类型的向量。
例子
T = 1 1 1 2 5 6
X = 1 4 NULL -1 NULL 4
m = table(T as t,X as x)
select *, tmove(t, x, 3) from m
t
x
tmove_t
1
1
1
4
1
2
-1
5
-1
6
4
-1
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.09
X = 5 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmove(t, x, 3d) from m
t
x
tmove_t
2021.01.02
5
2021.01.02
4
2021.01.04
2021.01.05
-1
4
2021.01.07
2
2021.01.09
4
-1
select *, tmove(t, x, 1w) from m
t
x
tmove_t
2021.01.02
5
2021.01.02
4
2021.01.04
2021.01.05
-1
2021.01.07
2
2021.01.09
4
4
FILE:references/doc_433.md
# limit
**URL**: https://docs.dolphindb.cn/zh/progr/sql/limit.html
**来源**: DolphinDB 官方文档
---
limit
limit 子句可使用整型标量或代表整型标量的变量,以限制返回记录的数量,亦可与context by子句一同使用,以限制结果中每组记录的数量。
limit子句和top子句功能类似。两者的区别在于:
top子句中的整型常量不能为负数。在与context
by子句一同使用时,limit子句标量值可以为负整数,返回每个组最后指定数目的记录。其他情况limit子句标量值为非负整数。
可使用limit子句从某行开始选择一定数量的行。
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t = table(timestamp, sym, qty, price);
t;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.2
select * from t limit 2;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
select * from t limit 2, 5;
timestamp
sym
qty
price
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
rowOffset = 2
rowCount = 5
select * from t limit rowOffset, rowCount;
timestamp
sym
qty
price
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
select * from t context by sym order by qty limit -1;
timestamp
sym
qty
price
09:36:59
MS
3200
30.02
09:35:26
IBM
5400
175.23
09:38:12
C
8800
51.29
FILE:references/doc_4331.md
# binaryExpr
**URL**: https://docs.dolphindb.cn/zh/funcs/b/binaryExpr.html
**来源**: DolphinDB 官方文档
---
binaryExpr
语法
binaryExpr(X, Y, optr)
详情
使用
optr
指定的二元运算符,将
X
与
Y
连接,生成一个二元运算的元代码。使用
eval
函数可以执行
binaryExpr
函数生成的元代码。
参数
X
可以是一个标量/向量/矩阵。
Y
可以是一个标量或者和
X
具有相同类型的量。
optr
是一个二元运算符。
返回值
CODE 类型元代码。
例子
binaryExpr(1, 1, +).eval()
// output
2
binaryExpr(1 2.2 3, 1 2 3, *).eval()
// output
[1 4.4 9]
binaryExpr(`id`st`nm, `fff, +).eval()
// output
["idfff","stfff","nmfff"]
a = matrix(1 2, 3 4)
b = matrix(4 2, 5 1)
binaryExpr(a, b, dot).eval()
#0
#1
10
8
16
14
相关函数:
unifiedExpr
FILE:references/doc_4333.md
# login
**URL**: https://docs.dolphindb.cn/zh/funcs/l/login.html
**来源**: DolphinDB 官方文档
---
login
语法
login(userId, password)
详情
用户可在控制节点或数据节点/计算节点上登录。
从 2.00.10.10 开始,用户可以通过配置项
enhancedSecurityVerification
控制在登录时是否约束密码重试的次数。若不设置
enhancedSecurityVerification
,则不约束;若设置
enhancedSecurityVerification
=true,则当某个用户登录时,在1分钟内连续5次输入错误密码,系统会锁定这个用户的登录。10分钟后才允许该用户再次登录。
参数
userId
是表示用户名的字符串。注:包含短横线(-)的用户名必须用双引号来包裹,不能用反引号`。
password
是表示密码的字符串。
返回值
无。
例子
login("JohnSmith", "Qb05078.");
FILE:references/doc_4337.md
# isValid
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isValid.html
**来源**: DolphinDB 官方文档
---
isValid
语法
isValid(X)
详情
检查每个元素是否为有效数(非 NULL 值)。如果是,返回 true;否则返回 false。
参数
X
可以是标量、数据对、向量或矩阵。
返回值
布尔标量、数据对、向量或矩阵。
例子
isValid(00i);
// output: false
isValid(1 NULL NULL 6 NULL 7);
// output: [true,false,false,true,false,true]
isValid(1/0);
// output: false
FILE:references/doc_4344.md
# exec
**URL**: https://docs.dolphindb.cn/zh/progr/sql/exec.html
**来源**: DolphinDB 官方文档
---
exec
select子句总是生成一张表,即使只选择一列亦是如此。若需要生成一个标量或者一个向量,可使用exec子句。
当与pivot by 共同使用时,exec语句生成一个矩阵,详情参考
pivotBy
。
例子
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t1 = table(timestamp, sym, qty, price);
t1;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
x = select count(price) from t1;
x;
count_price
9
typestr x;
TABLE
y = exec count(price) from t1;
y;
9
typestr y;
INT
x = select price from t1;
x;
price
49.6
29.46
29.52
30.02
174.97
175.23
50.76
50.32
51.29
typestr x;
TABLE
y = exec price from t1;
y;
[49.6,29.46,29.52,30.02,174.97,175.23,50.76,50.32,51.29]
typestr y;
FAST DOUBLE VECTOR
如果exec语句选择了多列,那么结果和select语句一致,为table类型。
y = exec price, qty from t1;
y;
price
qty
49.6
2200
29.46
1900
29.52
2100
30.02
3200
174.97
6800
175.23
5400
50.76
1300
50.32
2500
51.29
8800
typestr y;
TABLE
FILE:references/doc_4352.md
# cumwsum
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumwsum.html
**来源**: DolphinDB 官方文档
---
cumwsum
语法
cumwsum(X, Y)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
和
Y
的累计内积。
返回值
DOUBLE 类型,其数据形式同
X
(
Y
)。
例子
cumwsum(2.2 1.1 3.3, 4 5 6);
// output
[8.8,14.3,34.1]
cumwsum(1 NULL 1, 1 1 1);
// output
[1,1,2]
相关函数:
wsum
FILE:references/doc_4367.md
# round
**URL**: https://docs.dolphindb.cn/zh/funcs/r/round.html
**来源**: DolphinDB 官方文档
---
round
语法
round(X, [precision])
详情
round
函数按照指定小数位数对
X
进行四舍五入运算。
floor
和
ceil
函数分别将一个实数映射到不大于
X
的最大整数和不小于
X
的最小整数。
参数
X
可以是标量、向量或矩阵。
precision
是 0 到 10 的整数,表示保留小数点后几位。默认值是 0。
返回值
数据类型和数据形式与
X
相同。
例子
round 2.1;
//output: 2
round 2.9;
//output: 3
round -2.1;
//output: -2
round(2.154,2);
//output: 2.15
round(2.156,2);
//output: 2.16
ceil 2.1;
//output: 3
ceil 2.9;
//output: 3
ceil -2.1;
//output: -2
floor 2.1;
//output: 2
floor 2.9;
//output: 2
floor -2.1;
//output: -3
m = 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10$2:5;
m;
返回:
#0
#1
#2
#3
#4
1.1
3.3
5.5
7.7
9.9
2.2
4.4
6.6
8.8
10
round m;
返回:
#0
#1
#2
#3
#4
1
3
6
8
10
2
4
7
9
10
FILE:references/doc_4375.md
# Grafana 数据源插件
**URL**: https://docs.dolphindb.cn/zh/tools/grafana_overview.html
**来源**: DolphinDB 官方文档
---
Grafana 数据源插件
Grafana 是一个开源的数据可视化 Web 应用程序,常用于动态展示时序数据、支持多种数据源等。用户可通过配置连接的数据源、编写查询脚本,进而实现在浏览器中展示数据图表。
对此,DolphinDB 特别开发了 Grafana 数据源插件,使得用户能够在 Grafana 面板 (Dashboard) 上通过编写查询脚本、订阅流数据表的方式与 DolphinDB 进行交互,实现 DolphinDB 时序数据的可视化。
DolphinDB Dashboard 界面
双版本的 Grafana 数据源插件
目前,DolphinDB 提供了两种版本的 Grafana 数据源插件,其在功能和使用场景上存在明显区别。用户可根据自身需求选择使用。
dolphindb-datasource:使用前端连接数据库的插件,使用 WebSocket 进行通信。使用该插件需要浏览器和数据库处于同一网络下。
dolphindb-datasource-next:使用 Go 编程语言编写,运行在 Grafana 后端的插件。使用该插件需要 Grafana Server 和数据库部署在同一网络下,或 Grafana Server 可以连接到数据库。dolphindb-datasource-go 支持 Grafana Alert(警报)功能,可以自定义时间间隔查询,并在查询结果满足指定条件时发出警报。
FILE:references/doc_4379.md
# setMemLimitOfAllTempResults
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setmemlimitofalltempresults.html
**来源**: DolphinDB 官方文档
---
setMemLimitOfAllTempResults
语法
setMemLimitOfAllTempResults()
详情
某些分布式查询操作(例如表连接、GROUP BY、CONTEXT BY、PIVOT
BY),可能会产生临时表用于存储查询中产生的结果。该函数用于在线设置这些临时表允许占用的内存上限,单位为 GB。可通过
getMemLimitOfAllTempResults
查看设置是否生效。
注:
该函数只能由管理员在数据节点/计算节点上执行。
此函数修改的配置值在系统重启后将失效。若需要配置值永久生效,请更改配置文件中的
memLimitOfAllTempResults
。
参数
memLimit
一个数值型标量,必须大于0且不能大于
maxMemSize
的设置值。
例子
setMemLimitOfAllTempResults(3.0)
相关函数:
getMemLimitOfAllTempResults
FILE:references/doc_4381.md
# ewmCov
**URL**: https://docs.dolphindb.cn/zh/funcs/e/ewmCov.html
**来源**: DolphinDB 官方文档
---
ewmCov
语法
ewmCov(X, [com], [span], [halfLife], [alpha], [minPeriods=0], [adjust=true],
[ignoreNA=false], [other], [bias=false])
详情
返回
X
和
other
的指数加权移动协方差。该函数必须指定
com
,
span
,
halfLife
,
alpha
四个参数中的一个。
参数
X
是一个数值型向量、矩阵或表。若
X
是表,只对其内数值型和布尔型的列进行计算。
com
是一个大于等于0的数值型标量,表示质心。
span
是一个大于等于1的数值型标量,表示跨度。
halfLife
是一个大于0的数值型标量,表示半衰期。
alpha
是一个(0,1]之间的浮点数,表示平滑系数。
minPeriods
是一个整数,表示窗口中的最小观察数。默认值为0。
adjust
是一个布尔值,表示是否除以开始阶段的衰减调整因子。默认值为 true。
ignoreNA
是一个布尔值,表示计算权重时是否忽略 NULL 值。默认值为 false。
other
当
X
是向量时,
other
只能是一个与
X
长度相同的数值型向量;当
X
是矩阵时,
other
是一个长度与
X
行数相同的数值型向量,或维度与
X
相同的矩阵;当
X
是表时,
other
是一个长度与
X
行数相同的数值型向量,或维度与
X
相同的表。
bias
是一个布尔值,表示是否校正系统偏差。默认值为 false。
返回值
DOUBLE 类型,数据形式同
X
。
例子
a=[0,1,2,int(),4]
b=[2,4,3,6,5]
ewmCov(X=a,other=b,com=0.5);
// output
[,1,-0.038462,-0.038462,2.112637]
ewmCov(X=a,other=b,com=0.5,ignoreNA=true);
// output
[,1,-0.038462,-0.038462,1.969231]
n = 20
colNames = `time`sym`qty`price
colTypes = [TIME,SYMBOL,INT,DOUBLE]
t1 = table(n:0, colNames, colTypes)
insert into t1 values(09:30:00.001,`AAPL,100,56.5)
insert into t1 values(09:30:00.001,`AAPL,200,30.5)
insert into t1 values(09:30:00.001,`DELL,150,35.5)
insert into t1 values(09:30:00.001,`DELL,170,60.5)
insert into t1 values(09:30:00.001,`DELL,130,40.5)
b=[2,4,3,6,5]
ewmCov(X=t1,other=b,com=0.5);
time
sym
qty
price
09:30:00.001
AAPL
09:30:00.001
AAPL
100
-26
09:30:00.001
DELL
30.7692
-6.1538
09:30:00.001
DELL
25.2308
29.5346
09:30:00.001
DELL
9.405
10.0012
相关函数:
ewmCorr
,
ewmMean
,
ewmStd
,
ewmVar
FILE:references/doc_4396.md
# 物联网点位管理引擎
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db/iotdb.html
**来源**: DolphinDB 官方文档
---
物联网点位管理引擎
DolphinDB 提供物联网点位管理引擎(IOTDB
引擎)以对海量测点进行精细化、低延时的点位管理。用户能够在建表时使用含可变类型的列,并且系统会自动缓存每个点位的最新值数据,从而大幅提升查询性能(目前可达毫秒级)。
基础概念
本节将介绍物联网点位管理引擎中的一些基本概念。
点位
在物联网(Internet of Things,简称
IoT)中,“点位”通常指被监控或管理的物理对象上的具体信息点或数据采集点。这些点位可以是传感器、执行器、控制器等物联网设备上的具体接口或参数,也可以是设备本身作为一个整体被监控的标识。其中数据对象包括静态属性(ID,名称等)和动态属性(温度,压力,湿度,状态等)。
点位数据特点
数量巨多
:在电网、车联网、工业制造场景中,点位数从几百万到上亿点不等。
采样频率高
:某些极端场景下,点位的采样频率高达 100KHz。
数据类型复杂
:点位数据类型涵盖布尔型、整型、浮点型、枚举型等。
数据传输形式多样
:同一设备的点位数据,可能同一时间采集、同一批次上传,也可能不同时间采集、单独上传。
物联网点位管理引擎 / IOTDB 引擎
DolphinDB 在
3.00.2
版本中推出的基于 TSDB 引擎自研的、针对物联网场景中海量点位数据进行高效管理的存储引擎。
IOTANY 列
值类型可变的列,能够在单值模型的字段里存储不同类型的属性值。
最新值缓存功能
系统实时更新最新值缓存,并直接从缓存而非磁盘中读取数据,创建以分区为单位的最新值缓存表。最新值缓存功能可在 create 或
createPartitionedTable
中通过
latestKeyCache
参数开启。功能说明小节将详细介绍其原理。
点位管理表
包含 IOTANY 列的表。(推荐)
使用物联网点位管理引擎(IOTDB 引擎)、且开启最新值缓存功能的分布式表、流数据表或共享内存表。
静态表
对 sortColumns 中指定的除最后时间列外的其它列进行映射。将其映射为内部 ID。在后续的存储和缓存操作中,系统将通过内部 ID
来代指某个测点,以达到节省存储空间的目的。该表与 SymbolBase 类似,以分区为单位。该映射会存储于静态表中,用户无感知。
功能说明
本节将从原理、使用、管理等多个角度详细介绍 IOTANY 列和最新值查询优化。
IOTANY 列
IOTANY 列即值类型可变的列,建表时最多可以创建一个 IOTANY 列。IOTANY 列类型只能用在 create
语句中,不能单独建一个该类型的向量或者表。DolphinDB 在存储 IOTANY 列数据时, 将在
TSDB
Level File
层级单独存储不同类型的值。
关于 TSDB 存储引擎,物联网点位管理引擎:
规定将唯一标识一组测点的
多个列(一般为 id 列+各种 tag 列)+时间列
设置为 sortColumns。
支持两种去重策略:ALL(保留所有数据,为默认值), LAST(仅保留最新数据)。
支持 HashMappingFunction。
暂不支持 softDelete。
最新值查询功能暂不支持 snapshot read。
暂不支持 level 4 compaction。
暂不支持向量数据库等。
暂不支持添加 IOTANY 列。
不支持 sortColumns 中包含 DECIMAL 类型。
不支持 upsert! 时设置 ignoreNull=true。
不支持 upsert! 时传入 IOTANY 向量。
最新值查询优化
最新值查询的优化有最新值缓存表和最新值查询优化两种方式。
一般情况下,我们通过
context by
id+tag 列
csort
时间列
limit
-1
语法来查询最新值:
select deviceId, timestamp, metrics1... from pt
where deviceId = xxx context by deviceId csort timestamp limit -1
针对最新值查询,物联网点位管理引擎引入两种优化:
最新值缓存表
:引入以分区为单位的最新值缓存表。系统将
实时更新
最新值缓存,并直接从
缓存
而非磁盘中读取数据。此外,物联网点位管理引擎提供预热机制,重启后自动加载最近时间分区的缓存数据,优化冷启动场景。
存储引擎层的最新值查询优化
:在存储引擎层实现 context by 最新值算法,根据 index zonemap
进行过滤,只读取磁盘上部分的 block。用于支持缓存表 cache miss 的情况。
以下介绍两种优化方法的使用前提和优先顺序:
优化逻辑
使用前提(符合任一)
最新值缓存表
查询语句不包含任何 where 条件。
查询语句包含 where 条件,过滤条件仅包含部分或全部 firstSortKey
列,firstSortKey 支持的过滤类型:=, <, <=, >, >=,
between, in。
查询语句的 where 过滤条件涉及 lastSortKey 列且不涉及其他任何非
sortKey 列,lastSortKey列支持的过滤类型为<, <=, >, >=,
between。
最新值查询优化
查询的 where 条件需要包含所有的 firstSortKey
列,并且可以包含时间列(时间列 where 条件支持的过滤类型:=, <, <=, >,
>=, between)。
如果 firstSortKey 有多列,则每一列的过滤条件只支持等值过滤(即=)。
如果 firstSortKey 只有一列,则过滤条件支持等值过滤和 in 过滤。
注意:
最新值缓存表的条件三中,当 lastSortKey 列的过滤类型为 <, <=, between
时,需要最新值缓存表内 lastSortKey 列中的所有数据均满足 where
过滤条件才会通过缓存表返回结果。例如,最新值缓存表 lastSortKey
列
ts
的范围为
[2024.01.01,
2024.01.15]
,且 where 条件为
ts <
2024.01.16
,此时可以通过查询最新值缓存表获取查询结果。
若满足最新值缓存的使用条件,则优先从最新值缓存表中读取数据。
若不满足最新值缓存的使用条件,则尝试最新值查询优化。
若均不符合条件,则遵循先前版本逻辑。
假设一个 TSDB 分布式表 test 的 sortColumns
为
`c1`c2`timestamp
(其中称 c1, c2 为 firstSortKey,timestamp 为
lastSortKey),则可以按照以下格式指定最新值查询:
select [cols] from test
[where] context by c1,c2 csort timestamp limit
-1.
下面给出一些查询语句示例以及这些查询会使用的优化方式:
sortColumns
SQL
方式1:最新值缓存表
方式2:最新值查询优化
c1, c2, timestamp
select [cols] from pt context by c1, c2 csort
timestamp limit -1
(不包含任何过滤条件)
可使用
c1, c2, timestamp
select [cols] from pt where c1 in [x,x,x] and c2 = xxx context by c1, c2 csort
timestamp limit -1
(多个firstSortKey,且有firstSortKey的过滤类型为非等值过滤)
可使用
c1, c2, timestamp
select [cols] from pt where c1 = xx and c2 = xx and timestamp >= xxx context by c1, c2
csort timestamp limit -1
(涵盖所有firstSortKey,并且有lastSortKey过滤)
可使用
可使用
c1, c2, timestamp
select [cols] from pt where c1 = xx and c2 = xx context by c1, c2 csort timestamp
limit -1
(过滤条件包含所有firstSortKey)
可使用
可使用
c1, c2, timestamp
select [cols] from pt where c1 = xx and timestamp > xxx context by c1, c2 csort
timestamp limit -1
(过滤条件包含部分firstSortKey以及lastSortKey)
可使用
c1, timestamp
select [cols] from pt where c1 in [x,x,x] context by c1, c2 csort timestamp limit
-1
(过滤条件包含所有firstSortKey,且firstSortKey过滤类型为in)
可使用
可使用
c1, timestamp
select [cols] from pt where c1 in [x,x,x] and timestamp between xxx and xxx context
by c1, c2 csort timestamp limit -1
(过滤条件包含所有firstSortKey和lastSortKey)
可使用
可使用
c1, timestamp
select [cols] from pt where c1 > x context by c1, c2 csort timestamp limit
-1
(过滤条件包含所有firstSortKey,firSortKey过滤类型不是
in
或
=
)
可使用
通过 HINT_EXPLAIN 查看是否使用优化
可以通过 HINT_EXPLAIN 查看是否使用、以及具体使用了什么优化。
如果查询是最新值查询(即 context by firstSortKey 列,csort lastSortKey 列,并且 limit
为-1),则查询开启HINT_EXPLAIN 后,将可以在输出中看到 lastQuery 字段,该字段包含以下三种可能的输出形式:
采用最新值缓存查询:
"lastQuery": { "optimizationMethod":
LatestKeyCache },
采用最新值查询优化查询:
"lastQuery": { "optimizationMethod":
LatestKeyQuery },
两种优化方式均不满足:
"lastQuery": { "optimizationMethod": None
},
有重复数据时的最新值查询语义
如果存在两条 id 相同、时间戳相同的数据,当使用 context by 查询最新值时,只会保留其中的一条。比如:
id
timestamp
value
1
10:00
1
1
10:00
2
select * from pt where id = 1 context by id csort timestamp limit -1
当对普通分区表使用 context by 时,并未明确规定保留对象,故将随机保留一条数据。但在 IOTDB 引擎中,对点位管理表使用 context by
时,已明确规定
保留最新一条
,不会被 KEEP_LAST 或 KEEP_ALL 的设定影响。
最新值缓存表管理
最新值缓存表以分区为单位,存储该分区内所有测点的最新值。写入时实时更新,随 Cache Engine 一同flush。持久化保存在每个分区的
tableDir 目录下。文件名为
timeseries.cache
。
缓存管理与 symbolBase 一致,定期移除最近未使用的分区。参数
IOTDBLatestKeyCacheSize
专用于控制最新值缓存表管理,默认为 maxMemSize 的 5%。
IOTDBLatestKeyCacheSize=0.5 //浮点数,单位为G
数据类型
IOTANY 类型目前支持如下几种类型:
categroy
类型
Integral
CHAR
SHORT
INT
LONG
Logical
BOOL
Floating
FLOAT
DOUBLE
Literal
SYMBOL
STRING
使用示例
本节将对创建点位管理表,表数据写入和查询、最新值查询等操作进行示例说明。
创建示例
推荐通过 create 语句创建含 IOTANY 列的点位管理表。
下例中,我们通过复合分区方案按 deviceId 和 timestamp 分区,创建了一个名为 pt 的点位管理表。该表使用 deviceId 和
location 作为唯一识别一个点位的两列,启用最新值缓存,且 value 为 IOTANY 类型,可存储不同类型的测点数据;启用了 hashSortKey
压缩。
dbName = "dfs://db"
if (existsDatabase(dbName)) {
dropDatabase(dbName)
}
// 创建数据库,存储引擎为IOTDB
create database "dfs://db" partitioned by HASH([INT, 20]),VALUE(2017.08.07..2017.08.11), engine='IOTDB'
// 创建点位表,其中 firstSortKey 为 deviceId 和 location,lastSortKey(时间戳列)为 timestamp
create table "dfs://db"."pt" (
deviceId INT,
location SYMBOL,
timestamp TIMESTAMP,
value IOTANY
)
partitioned by deviceId, timestamp,
sortColumns = [`deviceId, `location, `timestamp],
latestKeyCache = true
写入示例
对于每个测点,第一次写入时会确定其 IOTANY 列的类型,如果之后对该测点写入不同的类型,会报错。
在
非 KEEP_LAST
的情况下,可以使用 update 语句修改测点 IOTANY 列的类型,但是
where
条件里只能包含firstSortKey
,这样能保证每次更新所有该测点的记录,以确保同一个测点的 IOTANY 列的类型一直统一。
基于上例已建立的表,进行写入对比操作。首先第一次写入数据,结果为可以正常写入,测点[1, `loc1`]的类型确定为
INT。
// 测点[1, `loc1`] 第一次写入
pt = loadTable("dfs://db", "pt")
t = table([1] as deviceId,
[`loc1] as location,
[now()] as timestamp,
[int(233)] as value)
pt.append!(t)
第二次写入该测点,value 类型为
DOUBLE。因为类型不匹配,故结果为不能写入。
// 测点[1, `loc1`] 第二次写入,value类型为double
t = table([1] as deviceId,
[`loc1] as location,
[now()] as timestamp,
[double(233)] as value)
pt.append!(t)
尝试修改测点类型。
// 修改测点类型为double
// 修改失败,where条件只能包含firstSortKey
update pt set value=double(233) where deviceId = 1 and location=`loc1 and timestamp >= 2017.08.07
// 修改成功
update pt set value=double(233) where deviceId = 1 and location=`loc1
此时再次执行第二次写入的脚本,结果为写入成功。
更新示例
在非 KEEP_LAST 的设置情况下,支持调用 update 时变更某个点位 IOTANY 列的类型。
在写入示例的最后也涉及到了更新操作,此处聚焦后再次讲解。
当更新列为 IOTANY列 时,where 中不能包含除 first sort key
以外的列,否则会报错。这样是为了保证修改类型时要更新所有该点位的记录,以确保同一个点位的 IOTANY
列的类型一直统一。
t = table([`dev1] as deviceId,
[now()] as timestamp,
[`loc1] as location,
[int(233)] as value)
pt.append!(t) //该测点的类型为INT
update pt set value = 2.33 where deviceId = `dev1 and location = `loc1
// 将测点值更新为double
update pt set value = 2.33 where deviceId = `dev1
// ok
update pt set value = 2.33 where deviceId = `dev1 and location = `loc1 and timestamp > xxx
// 不行,一次需要更新该点位所有的记录
IOTANY 列查询示例
基于已建立的表,进行如下查询操作:
select deviceId, location, sum(long(value)), timestamp from pt where deviceId = 1 and
location = `loc1 and timestamp >= 2017.08.07
//成功执行
IOTANY 列计算示例
基于已建立的表,进行如下计算:
// 判断相等关系
select * from pt where value = 233
// 聚合计算
select deviceId, location, sum(value), timestamp from pt where deviceId = 1 and
location = `loc1 and timestamp >= 2017.08.07
最新值查询(context by)示例
前文介绍,最新值查询的优化有最新值缓存表和最新值查询优化两种方式。在满足不同条件时会用到不同的优化策略。本例为方便展示,将创建一个新的点位管理表。
dbName = "dfs://test";
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
// 创建数据库,存储引擎为IOTDB
create database "dfs://test"
partitioned by HASH([LONG,1]),HASH([DATE, 1]),
engine = 'IOTDB'
dummy = table(1000000:0, `date`deviceId`key1`val_any, [DATE, LONG, INT, DOUBLE])
// 创建点位表,其中 firstSortKey 为 deviceId 和 key1,lastSortKey(时间戳列)为 date
create table "dfs://test"."pt1"(
date DATE,
deviceId LONG,
key1 INT,
val_any DOUBLE
)
partitioned by deviceId, date
sortColumns = [`deviceId,`key1,`date]
keepDuplicates = ALL
latestKeyCache = true
pt1 = loadTable(dbName, "pt1")
// 导入测试数据
n = 200000
date = rand(2012.01.01..2012.12.31, n)
key1 = take(200199..(200199+n), n)
deviceId = take(200..(200+n), n)
val = rand(double(n), n)
t = table(date, deviceId, key1, val)
pt1.append!(t)
以下查询将使用最新值缓存优化:
select [HINT_EXPLAIN] * from pt1 where deviceId in [200, 201, 202]
context by deviceId, key1 csort date
limit -1
// HINT_EXPLAIN 输出
{
.......
"lastQuery": {
"optimizationMethod": LatestKeyCache
},
......
}
以下查询将使用最新值查询优化:
select [HINT_EXPLAIN] * from pt1 where deviceId = 200 and key1 = 200199
and date > 2010.12.31
context by deviceId, key1 csort date
limit -1
// HINT_EXPLAIN 输出
{
.......
"lastQuery": {
"optimizationMethod": LatestKeyQuery
},
......
}
以下查询不会使用存储层的任何优化(过滤条件中包含了非 sortkey
列):
select [HINT_EXPLAIN] * from pt1 where deviceId = 200
and val_any = 123
context by deviceId, key1 csort date
limit -1
// HINT_EXPLAIN 输出
{
.......
"lastQuery": {
"optimizationMethod": None
},
......
}
相关文档:
create
createPartitionedTable
schema
getSessionMemoryStat
参数配置
FILE:references/doc_4400.md
# integral
**URL**: https://docs.dolphindb.cn/zh/funcs/i/integral.html
**来源**: DolphinDB 官方文档
---
integral
语法
integral(func, start, end, [start2], [end2])
详情
返回
func
在
start
和
end
范围内的积分,或在平面区域
start
≤ x ≤
end
和
start2
≤ y ≤
end2
上
func
的积分。
当结果中出现无穷值或者计算过程中出现有关复数的计算时会返回 NULL。
参数
func
是一元或二元函数。
start
是一个数值标量或向量,表示开始值。
start
用 NULL 值表示负无穷。
end
是一个数值标量或向量,表示结束值。
end
用 NULL 值表示正无穷。
start2
是一个数值标量,向量或一元函数,表示二重积分第二维度的开始值。
start2
用 NULL 值表示负无穷。
end2
是一个数值标量,向量或一元函数,表示二重积分第二维度的结束值。
end2
用 NULL 值表示正无穷。
如果
start
和
end
都是向量,或需要计算二重积分时,
start
,
end
,
start2
和
end2
为向量,则它们的长度必须相同。如果部分为标量,其余为向量时,则会将标量当作与向量长度相同,所有元素值等于该标量的向量。
返回值
DOUBLE 类型标量或向量。
例子
integral(abs, -10, 10);
// output
100
integral(acos, [0.1, -0.10], [0.3, 0.10]);
// output
[0.273816,0.314159]
integral(acosh, [1, 2, 9, 9], 10);
// output
[19.982354,19.080489,2.941187,2.941187]
integral(pow{,3}, 5, 9);
// output
1484
integral(abs, NULL, NULL);
// output
00F
def f(x1,x2){
fx=100*(x2-x1*2)+square(1-x1)
return fx
}
integral(f,0,1,7,1)
// output
-1802
integral(f,[0,1,2,3],7,2,[0,1,2,3])
// output
[8255.333333, 8256, 7856.666667, 7061.333333]
FILE:references/doc_4409.md
# 基于 DolphinDB 的多因子风险模型实践
**URL**: https://docs.dolphindb.cn/zh/tutorials/multi_factor_risk_model.html
**来源**: DolphinDB 官方文档
---
基于 DolphinDB 的多因子风险模型实践
2018 年 MSCI 发布了中国 A 股全市场股票模型(即 CNE6
模型)。与传统的时间序列回归模型有所不同,多因子风险模型能够更高效准确地捕捉横截面上机构头寸在各种因子(包括市值等风格因子)上的暴露。并且当模型中纳入具有时序记忆的变量时,它可以共享截面回归和时序回归模型的一些优良性质。该模型采用多层次的因子体系,能够更精细地预测和解释中国股票市场的风险,对中国
A 股的风险评估、组合优化和量化策略产生了积极且广泛的影响。
本文将详细介绍通过 DolphinDB 实现多因子风险模型的整个流程。
1. 多因子模型简介
1.1. 多因子模型
多因子模型基于多因子回归体系,将风格因子、市场因子和行业因子与收益率进行联合建模,以获取收益率和特质收益率。本文构建的多因子风险模型以 CNE6
模型为准。
CNE6 模型是面向中国股票市场的多因子模型。该模型考虑了一个国家因子、多个行业因子以及多个风格因子。假设市场中共有 N 支股票,P 个行业,以及 Q
个风格因子。在任意给定时间点,该模型使用因子暴露和个股收益率构建截面回归(cross-sectional regression)如下
图
1
.
CNE6 模型
其中
r
n
是第 n 支股票的收益率,
r
f
是无风险收益率。
X
n
I
p
是股票 n 在行业
I
p
的暴露。假设一个公司只能属于一个行业,那么
X
n
I
p
的取值为0(代表该股票不属于这个行业)或者
1(代表该股票属于这个行业)。
X
n
s
q
是股票 n 在风格因子
S
q
的暴露,它的取值经过了某种标准化(标准化的方法会在下文说明)。
u
n
为股票 n 的超额收益中无法被因子解释的部分,因此也被称为该股票的特异性收益。
f
C
为国家因子的因子收益率(所有股票在国家因子上的暴露都是 1);
f
I
p
为行业
I
p
因子的因子收益率;
f
s
q
为风格因子
S
q
的因子收益率。
下图为多因子模型的流程图。从计算初始因子开始,对每个因子进行单因子模型检验,包括稳定性、有效性和一致性的相关检验;根据检验结果,使用 DolphinDB
接口合成指定的一级和二级因子。对于已合成的因子,DolphinDB 建立了收益预测模型和风险矩阵调整,并从拟合优度、偏差统计量以及 Q
统计量等角度对模型进行了评估。最后,基于收益风险模型对投资组合进行风险评估和组合优化。
1.2. 收益风险模型
多因子模型的核心目的在于准确评估个股和因子的风险,并通过时序的收益风险评估辅助投资判断。基于 CNE6
模型,可以简化个股收益率为因子收益率和个股特异性收益率的线性组合。
其中,
r
为 N 个个股收益率的向量(N*1 维),
X
为当期因子暴露矩阵(N*k 维,k 为因子个数),
f
为 k
个因子的收益率向量(k*1 维),
u
为 N 个个股的特异性收益率的向量(N*1 维)。
对上述等式左右两边分别求协方差矩阵得到如下公式,将个股协方差矩阵
V
分解为因子收益率协方差矩阵
V
f
、特质收益协方差矩阵Δ。公式如下:
若从股票收益率的协方差矩阵的角度评估风险,可能存在由于股票数 N 远大于交易日期数 252 导致股票收益率协方差矩阵满秩的问题,且需要计算 N*(N+1)/2
次,复杂度很高。基于多因子风险模型,为求得股票收益率的风险矩阵
V
,只需要分别求得因子收益率的风险矩阵
V
f
以及个股特异性收益的风险矩阵 Δ,只需要计算 n* (n + 1) / 2 + n 次,进一步规避了收益率协方差矩阵满秩的问题。
2. 基于 DolphinDB 的因子合成
本文首先基于
RiskFactorsCal
模块得到用于建模的多因子窄表,具体流程如下:
基于
getXXXX
函数计算风格因子。
基于
getIndustryFactors
函数计算行业因子。
基于
getRegTable
函数对风格因子、行业因子合并,并填充缺失值得到用于单因子模型检验的回归因子表。
基于
getFactorsValidation
函数针对回归因子表生成每个因子对应的 IC、 指标。
针对不同因子加权方法,基于
getFSLevelFactor
函数合成三级因子得到用于建立多因子模型的一级因子窄表。
2.1. 风格因子计算
首先计算单个三级风格因子,一级、二级风格因子基于如下风格因子关系表合成得到。其中具有预测属性的 ETOPF_STD, ETOPF, EGRLF, DTOPF
等因子对模型的影响不稳定,暂不考虑。
一级因子
二级因子
三级因子
定义
三级因子调用函数
三级因子计算入参
Quality
Earnings Quality
ABS
资产负债表应计项目
getAbs
ACF_TTM
现金流量表应计项目_滚动
getAcf
method='TTM'
ACF_LYR
现金流量表应计项目_静态
getAcf
method='LYR'
Earnings Variability
VSAL_TTM
营收波动_滚动
getVsal
method='TTM'
VSAL_LYR
营收波动_静态
getVsal
method='LYR'
VERN_TTM
盈利波动_滚动
getVern
method='TTM'
VERN_LYR
盈利波动_静态
getVern
method='LYR'
VFLO_TTM
现金流波动_滚动
getVflo
method='TTM'
VFLO_LYR
现金流波动_静态
getVflo
method='LYR'
Investment Quality
AGRO
总资产增长率
getAgro
IGRO
新发股增长率
getIgro
CXGRO
资本支出增长率
getCxgro
Leverage
MLEV
市场杠杆
getMlev
BLEV
账面杠杆
getBlev
DTOA
资产负债比
getDtoa
Profitability
ATO_TTM
资产周转率_滚动
getAto
method='TTM'
ATO_LYR
资产周转率_静态
getAto
method='LYR'
GP_TTM
资产毛利率_滚动
getGp
method='TTM'
GP_LYR
资产毛利率_静态
getGp
method='LYR'
GPM_TTM
销售毛利率_滚动
getGpm
method='TTM'
GPM_LYR
销售毛利率_静态
getGpm
method='LYR'
ROA_TTM
总资产收益率_滚动
getRoa
method='TTM'
ROA_LYR
总资产收益率_静态
getRoa
method='LYR'
Value
Btop
BTOP
账面市值比
getBtop
Earning Yield
CETOP_TTM
现金盈利价格比_滚动
getCetop
method='TTM'
CETOP_LYR
现金盈利价格比_静态
getCetop
method='LYR'
ETOP_TTM
预测盈利收益率_滚动
getEtop
method='TTM'
ETOP_LYR
预测盈利收益率_静态
getEtop
method='LYR'
EM
企业盈利价值比率
getEm
Long-Term Reversal
LTRSTR
长期反转相对强度
getLtrstr
LTHALPHA
长期反转超额收益
getLthalpha
Growth
Growth
EGRO_TTM
每股营收增长率_滚动
getEgro
method='TTM'
EGRO_LYR
每股营收增长率_静态
getEgro
method='LYR'
SGRO_TTM
每股收益增长率_滚动
getSgro
method='TTM'
SGRO_LYR
每股收益增长率_静态
getSgro
method='LYR'
Liquidity
Liquidity
STOM
月换手率
getStom
STOQ
季换手率
getStoq
STOA
年换手率
getStoa
ATVR
年化交易比率
getAtvr
Volatility
Beta
HBETA
贝塔
getHbeta
Residual Volatility
HSIGMA
特异波动率
getHsigma
DASTD
波动率
getDastd
CMRA
累计收益
getCmra
Size
Size
LNCAP
对数市值
getLncap
Mid Cap
MIDCAP
中市值
getMidcap
Momentum
Momentum
RSTR
市场相对强度
getRstr
HALPHA
历史超额收益
getHalpha
Dividend Yield
Dividend Yield
DTOP
股息收益率
getDtop
在调用计算单个三级风格因子时,采用 get + 因子名(首字母大写),例如,Blev(Beta Leverage), Stom(Size Turnover
Momentum), Stoq(Stock Quality)因子计算如下:
getBlev(startTime = 2022.01.03,windows = 365,endTime = 2023.01.02)
getStom(startTime = 2022.01.03,windows = 21,endTime = 2023.01.02)
getStoq(startTime = 2022.01.03,windows = 63,endTime = 2023.01.02)
单个因子计算函数的返回结果均是窄表,返回结果大致如下:
图
2
.
单个因子计算函数返回的窄表结果示例图
2.2. 行业因子计算
采用申万一级
SW_2021
、中信一级
CITIC
行业分类哑变量因子,CNLT
依据市值给出权重,接口中提供行业因子市值加权。
接口
说明
getIndustry
获取原始行业因子
步骤一:获取月末交易日和行业交易代码。
步骤二:基于交易日数据获取行业数据。
步骤三:基于 onehot 编码生成宽表并求和汇总。
getIndusrtyWeighted
获取行业因子权重
步骤一:获取月末交易日和行业交易代码。
步骤二:基于交易日数据获取各行业数据、市场数据。
步骤三:关联上述两表,计算每个行业占总行业的权重,并找出在指定行业中占比最大的个股。
getIndusrtyFactor
获取加权后的行业因子
步骤一:
getIndustry
获取原始行业因子。
步骤二:
getIndusrtyWeighted
获取行业权重。
部分返回结果如下:
getIndustry(startTime = 2022.01.01,endTime = 2023.01.02,method = 'SW_2021')
图
3
.
对应的部分返回结果图一
getIndusrtyWeighted(startTime = 2022.01.03,endTime = 2023.01.02,method = 'SW_2021')
图
4
.
对应的部分返回结果图二
getIndusrtyFactor(startTime = 2022.01.03,endTime = 2023.01.02,method = 'SW_2021')
图
5
.
对应的部分返回结果图三
2.3. 因子预处理
在对原始三级风格因子进行计算后,通常需要经过一定的标准化的数据清洗流程才能进一步合成因子,DolphinDB 使用了 MAD 法去极值并采用 CNLT
中的市值标准化流程。
2.3.1. 风格因子 MAD 法去极值
MAD 方法(median absolute deviation
方法),该方法使用中位数,较于传统的均值标准差具有稳健(robust)性质,不会被极端异常值影响结果,是对减均值后标准差处理的改进方法。MAD
方法相对于其他离群值检测方法的优点在于它对离群值的鲁棒性较强。本文中 MAD 方法对应接口函数
winsorized
。
/* winsorized
对因子表进行winsorized处理
因子表必须包含三列:记录日期、股票代码和原始因子,其中原始因子必须是第三列
Input :
tbName
Output:
factor table after winsorized */
MAD 方法的具体实现步骤如下:
计算数据集的中位数(Median)作为数据的中心位置。
对每个数据点,计算其与中位数的绝对偏差(Absolute Deviation)。
计算所有绝对偏差的中位数,即 Median Absolute Deviation。
确定离群值的阈值。通常,离群值被定义为与中位数的偏差超过一定倍数(如 3 倍)的 MAD 的数据点。
鉴定离群值。对于超过阈值的数据点,可以将其标记为离群值或进行进一步的分析。
2.3.2. 风格因子市值加权标准化
市值加权标准化是为了去除极端市值对因子计算贡献产生影响(CNLT )。该方法是为了将因子量纲统一在相接近的水平。对于第
n
个个股的第
k
个原始因子暴露
x
n,k
Raw
,标准化流程为:
其中
μ
k
和
σ
k
分别是对应因子的市值加权均值、等权标准差。(CNLT)
本文市值加权标准化对应接口函数
standardized
,其中
adjusted=true
表示采纳市值中性化处理。
/* standardized
对因子表进行标准化和市值中性化处理
因子表必须有三列:记录日期、股票代码和原始因子,原始因子必须是第三列
Input :
tbName
adjusted Market-neutralize or not
Output:
factor table after standardized */
2.3.3. 风格因子、行业因子合并
以上两种接口函数
winsorized
,
standardized
嵌入在
getAllFactors
函数中,
getAllFactors
通过指定参数
normlizing
和
scaling
分别实现标准化和去极值的过程。此外在得到行业因子、风格因子后,基于
getAllFactors
函数可以得到合并了上述所有因子的宽表,可进一步用于单因子的有效性检验。
/* getAllFactors
获取所有因子
Input: normlizing true (Default) 标准化
scaling true (Default) 去极值
decap true (Default) 市值中性化
industry_weighted true (Default) 行业市值权重加权
industry_method 'CITIC' (Default)、'SW_2021'
startTime 2022.01.03(Default)
endTime 2023.01.02(Default)
Output:
factor table */
Factors = getAllFactors(st=st,et =et, normlizing = true,
scaling = true,decap = false,industry_method = 'CITIC',
industry_weighted = false)
select * from Factors limit 100
2.3.4. 因子缺失值处理
在构建因子回归模型前,为避免因子缺失值对于回归模型结果的影响,需要对因子缺失值做进一步的处理。本文中针对所有原始因子的缺失值处理的函数接口为
getRegTable
,本文选择采用均值填充以处理缺失值。
/* getRegTable
获取用于回归的经过处理的回归因子表、包含个股收益率、因子暴露、行业因子、行业变量、回归权重
Input:
factorsTable false (Default) 是否使用提供的初始因子表
tbName NULL (Default) 初始因子表
normlizing true (Default) 标准化
scaling true (Default) 去极值
decap true (Default) 回归市值中性化
industry_weighted true (Default) 行业因子加权重
industry_method 'CITIC' (Default)、'SW_2021'
st 2022.01.03(Default)
et 2023.01.02(Default)
Output:
regression table
*/
注:
初始因子表
tbName
,当且仅当
factorsTable
为 true 时,需要传入已经使用
getAllFactors
函数标准化过、去极值过、市值中性化过、行业因子加权重过的全因子表(或者筛选过股票后的部分个股因子表)。并且若提供因子表,该函数相应参数
normlizing
,
scaling
,
decap
,
weighted
是 false
或 true 对结果没有影响,即
tmpReg = getRegTable(factorsTable = true,tbName =
Factors,st= st,et = et)
。
通过调用:
fTable = getRegTable(factorsTable = true,tbName = Factors,st= st,
et = et,normlizing = normlizing ,scaling = scaling,
decap = decap, industry_method = industry_method,
industry_weighted = industry_weighted)
执行上述命令可以实现如下效果:
处理之前,
getAllFactors
得到的原始三级因子宽表:
处理之后,
getRegTable
处理后的三级因子宽表:
2.4. 单因子模型检验
2.4.1. WLS 回归模型
针对风格因子
s
,单因子的检验回归模型如下:
此处使用(Weighted Least
Squares,加权最小二乘)以
r
n,t
为因变量,以风格因子
s
的因子载荷
x
n,s,t
为自变量,预测
f
s.t
(风格因子的收益率)。
针对行业因子
i
,单因子的检验回归模型如下:
此处使用以
r
n,t
为因变量,以行业因子
i
的因子载荷
x
n,i,t
为自变量,预测
f
i.t
(行业因子的收益率)。
本文的回归模型的接口为
getOneFactorValidate
,函数嵌套在
styleValidate
风格因子检验函数、
industryValidate
行业因子检验函数中。
/* getOneFactorValidate
获取moving wls单因子回归结果统计量的聚合函数
Input: y 因变量
x 自变量
w 权重
Output:
wls stat "beta","tstat","R2","AdjustedR2", "Residual" */
2.4.2. T 检验
T 值检验是检验对应变量的因子收益是否显著区别于 0,可以用来衡量因子的有效性以及一致性。其计算方法为:
其中
SE
(
f
^
i,t
) 为估计因子收益
f
^
i,t
的标准误差。本文的 T 检验主要基于
getOneFactorValidate
接口的回归模型得到的 t 统计量进行评估。
2.4.3. Factor Stability Coefficient
在构建多因子模型时,必须要考虑到因子暴露的稳定性。如果因子暴露矩阵每次计算时的变化特别大,那么该模型的稳健性较差。故本文引入因子稳定性系数(Factor
Stability Coefficient, FSC)指标,其定义为这个月的因子暴露矩阵与下个月因子暴露矩阵的相关性。
通常情况下,FSC 指标是通过比较从不同数据集或不同时间点上进行的、两个独立的因子分析所得到的因子载荷来进行计算的。本文通过
getFactorsValidation
函数基于斯皮尔曼相关系数(Spearman's Rank
Correlation Coefficient)计算 FSC 指标,令
d
t
为因子暴露
x
n,i,t
的第
t
期与第
t+1
期的位次值之差。
,则 FSC系数计算方法为:
研究人员通常使用阈值来解释 Factor Stability Coefficient。例如,FSC 大于 0.8通常被认为表示较好的稳定性或一致性,而低于
0.5 的值可能表示稳定性较差。
2.4.4. Information Coefficient
Information Coefficient(IC)值是因子对下期收益率的预测与下期实际收益率的相关性,IC
代表的是预测值和实现值之间的相关性,通常用于评价预测能力(即选股能力)。在实际计算中,因子 𝑘 的 IC 值一般是指个股第 𝑇 期在因子
𝑘 上的暴露度与 𝑇 +1 期的收益率的相关系数。因子 IC
值反映的是个股下期收益率和本期因子暴露度的线性相关程度,表示使用该因子进行收益率预测的稳健性。IC 的计算方式有两种:normal
IC、rank IC。本文在
getFactorsValidation
函数基于
Spearman
相关系数计算 Rank IC 值。
IC 值被认为在 0.03 上时与市场存在一致或相反的波动规律,此时该因子存在一定的有效性。
2.4.5. 基于 DolphinDB 实现单因子有效性检验
本文的单因子有效性检验的对应接口函数
getFactorsValidation
。该函数通过输入计算得到的全因子表,给出了每一个单因子模型的单因子收益,t
统计量,拟合优度,FSC 指标和 IC 值。通过这些值可以全面系统地对所有因子进行分析,如下列图所示:
Input:
factorsTable false (Default) 是否使用提供的因子表
tbName NULL (Default) 回归因子表
normlizing true (Default) 标准化
scaling true (Default) 去极值
decap true (Default) 市值中性化
industry_weighted true (Default) 行业因子加权重
industry_method 'CITIC' (Default)、'SW_2021'
st 2022.01.03(Default)
et 2023.01.02(Default)
Output:
factor test table factor_return、tstat、R2、fsc、IC
*/
步骤一:首先获取所有因子的检验指标。
// 获取单风格因子有效性、一致性、稳定性检验
factorsValid = getFactorsValidation(factorsTable = true,tbName = out,st=2022.01.03,
et =2023.01.02, normlizing = true,scaling = true,
decap = true,industry_method = 'CITIC',
industry_weighted = true)
步骤二:绘制因子的 FSC
月频时序图,评价因子稳定性。
tmp = select record_date,valueType.regexReplace("_stat","") as valueType,
fsc from factorsValid
tmppivot = select fsc from tmp pivot by record_date,valueType
tbfsc = sql(select = sqlCol(tmppivot.columnNames()[11:20]),from = tmppivot).eval()
plot(tbfsc,tmppivot.record_date,extras={multiYAxes: false},title = "因子fsc 月频时序图")
FSC 大部分处于 0.8 以上的因子被公认为因子具备较高的稳定性。上图中除 em, dastd, dtoa
外的其他因子具备较好的稳定性。
步骤三:绘制因子的 IC 月频时序图,评价因子一致性。IC 值被认为在 0.03
上时与市场存在一致或相反的波动规律,此时该因子存在一定的有效性。
tmp1 = select record_date,valueType.regexReplace("_stat","") as valueType,
abs(ic) as ic from factorsValid
tmppivot1 = select ic from tmp1 pivot by record_date,valueType
tbic = sql(select = sqlCol(tmppivot1.columnNames()[2:10]),from = tmppivot1).eval()
baseline = take(0.03,(shape tbic)[0])
plot(table(tbic,baseline),tmppivot1.record_date,
extras={multiYAxes: false},title = "因子ic 月频时序图")
可以观察到 atvr(Annualized Traded Value Ratio,年交易比值)因子在 2017
年前保持着较强的相关性,而 2018-2022 年期间 8 个因子呈现周期性起伏的规律。
步骤四:绘制因子
t_stat,评价因子有效性。
tmp2 = select record_date,valueType.regexReplace("_stat","") as valueType,
tstat from factorsValid
tmppivot2 = select tstat from tmp2 pivot by record_date,valueType
tbstat = sql(select = sqlCol(tmppivot2.columnNames()[11:20]),from = tmppivot2).eval()
baseline_neg = take(-0.03,(shape tbstat)[0])
baseline_pos = take(0.03,(shape tbstat)[0])
plot(table(tbstat,baseline_neg,baseline_pos),tmppivot2.record_date,
extras={multiYAxes: false},title = "因子t_stat 月频时序图")
图中大部分因子的 t 值距离基线 0.03 和 -0.03 有相当的距离。例如 dastd 和 cmra,一个显著高于
0.03,另一个则显著低于 -0.03。由此可得结论:在 18 年之前,这两个因子与市场存在着显著的正负相关性。
2.5. 多因子合成
针对已经得到的三级因子和因子的有效性识别的结果,用户可以进行下一步因子的合成。因子合成的方法参考华泰证券中给出的部分方法,例如等权法和历史信息法。
等权法(equal),对相应的三级因子等权合成二级、一级因子。例如对 ABS、ACF_TTM 这两个因子各赋1/2的权重合成 Earnings
Quality 因子。
历史收益率加权方法(ir),根据在单因子模型检验获得中的三级因子收益率标准化后得到加权系数加权得到二级因子。
信息系数比率法(ic_ir),由因子检验获得的 IC 值对因子进行合成。举例来说,设
K
×
T
维的矩阵
X
为过去
T
个截面期上的
K
个因子的 IC 矩阵,
x̄
是矩阵
X
的行均值,
K
×
K
的矩阵
V
是
X
的协方差阵,则可以取 V
-1
x̄
作为权重加权得到各级因子。
本文因子合成的对应接口函数
getFSLevelFactor
,其中
firstFactors
中二级因子的名称需要与
secondFactors
中的二级因子的名称一一对应;
secondFactors
中的三级因子需要与输入的因子表
factorsTable
字段名对应(支持大小写匹配)。
Input:
factorsTable NULL (Default) (getRegTable函数返回的全因子表)
factorsValid NULL (Default) (getFactorsValdition接口返回的单因子收益和检验表)
firstFactors NULL 一级因子二级因子关系json
secondFactors NULL 二级因子三级因子关系json
normlizing true 是否对合成的因子标准化
method "equal"等权、 "ir"历史收益率、"ic_ir"信息系数比率 合成因子方法
level "S"、"F" 指定一级二级因子 合成二级(S)一级(F)风格因子
Output:
factorsTable 返回按指定关系合成的(可直接用于回归模型的)风格大类因子和行业因子
st = 2022.01.03
et = 2023.01.02
normlizing = true
scaling = true
decap = true
industry_method = 'CITIC'
industry_weighted = true
Factors = getAllFactors(st= st,et = et, normlizing = normlizing,scaling = scaling,
decap = decap,industry_method = industry_method,
industry_weighted = industry_weighted)
select * from Factors limit 100
// 对原始因子宽表的缺失值进行处理
fTable = getRegTable(factorsTable = true,tbName = Factors,st= st,et = et,
normlizing = normlizing ,scaling = scaling ,
decap = decap,industry_method = industry_method,
industry_weighted = industry_weighted)
// 因子有效性检验
// 获取单风格因子有效性、一致性、稳定性检验
factorsValid = getFactorsValidation(factorsTable = true,tbName = Factors,st = st,
et = et , normlizing = normlizing,scaling = scaling,
decap = decap,industry_method = industry_method,
industry_weighted = industry_weighted)
factorsValid
update factorsValid set tstat = abs(tstat)
// 计算fsc
tmp = select record_date,valueType.regexReplace("_stat","") as valueType,
fsc from factorsValid
tmppivot = select fsc from tmp pivot by record_date,valueType
tbfsc = sql(select = sqlCol(tmppivot.columnNames()[11:20]),from = tmppivot).eval()
plot(tbfsc,tmppivot.record_date,extras={multiYAxes: false},title = "因子fsc 月频时序图")
// 计算ic
tmp1 = select record_date,valueType.regexReplace("_stat","") as valueType,
abs(ic) as ic from factorsValid
tmppivot1 = select ic from tmp1 pivot by record_date,valueType
tbic = sql(select = sqlCol(tmppivot1.columnNames()[2:10]),from = tmppivot1).eval()
baseline = take(0.03,(shape tbic)[0])
plot(table(tbic,baseline),tmppivot1.record_date,
extras={multiYAxes: false},title = "因子ic 月频时序图")
// 计算tstat
tmp2 = select record_date,valueType.regexReplace("_stat","") as valueType,
tstat from factorsValid
tmppivot2 = select tstat from tmp2 pivot by record_date,valueType
tbstat = sql(select = sqlCol(tmppivot2.columnNames()[11:20]),from = tmppivot2).eval()
baseline_neg = take(-0.03,(shape tbstat)[0])
baseline_pos = take(0.03,(shape tbstat)[0])
plot(table(tbstat,baseline_neg,baseline_pos),
tmppivot2.record_date,extras={multiYAxes: false},
title = "因子t_stat 月频时序图")
由如下的合成一级因子结果可以看到
'abs','acf_ttm','acf_lyr','vsal_ttm','vsal_lyr' 等因子被合成为 Quality 等一级因子。
合成因子前:
合成后的一级因子:
2.6. 自定义因子的多因子合成
2.6.1. 基于对自定义因子预处理
对已有因子数据做预处理,可以调用因子预处理的
winsorized
、
standardized
等函数以实现对风格因子实现极值化、标准化处理。
对上述步骤处理后的因子数据处理缺失值,避免因子缺失值对于回归模型结果的影响。
假设最后的因子表为
Factors
表,则可以通过如下方式调用
getRegTable
函数进行缺失值处理。
fTable= getRegTable(factorsTable = true,tbName = Factors,st= st,et = et)
2.6.2. 对自定义进行单因子模型检验
假设最后的因子表为
Factors
表,则可以通过如下方式调用
getFactorsValidation
函数进行单因子模型检验,进一步筛选有效因子。
factorsValid= getFactorsValidation(factorsTable = true,tbName = Factors,st= st,et = et)
2.6.3. 基于自定义因子进行多因子合成
在指定与自定义因子一一对应的一级因子、二级因子后,通过
getFSLevelFactor
函数生成基于自定义因子合成后的一级、二级因子。
getFSLevelFactor(fTable,factorsValid,firstFactors,secondFactors,false , "ir",level = "F")
getFSLevelFactor(fTable,factorsValid,firstFactors,secondFactors,false , "ir",level = "S")
3. 基于 DolphinDB 的收益风险模型
合成一级因子后,用户就可以基于全部的因子给出收益和风险的模型构建过程,包括所有因子收益、偏差统计量和拟合优度。偏差统计量可以给出模型预测的风险与实际风险的偏差。而拟合优度则反应的是所有因子对市场收益的解释力度,拟合优度越接近于
1 说明模型的稳健性,准确程度越高。
本文收益风险模型对应接口函数
getRetTable
,函数输出为:计算返回因子风险协方差矩阵、特质性收益风险协方差矩阵、bias_statistic、stR2、tstat
和因子收益率。通过这些返回值可以给出因子风险和特异性风险,以及模型估计的风险准确性评估(bias),模型的解释力度评估(stR2)。
/* getRetTable
Input:
facTable NULL (Default) (getFSLevelFactor函数返回的)全因子表
adjust true (Default) 是否进行Newey_West调整
shrink true (Default) 是否进行贝叶斯收缩
eigenfactor true (Default) 是否进行特征因子调整
Output:
factorsRetTable
*/
3.1. 基于 WLS 构建多因子模型
首先通过 moving wls 多因子回归模型,函数接口为
getAllFactorValidate
。
/* getAllFactorValidate
获取moving wls多因子回归结果统计量的聚合函数
Input: y 因变量
x 自变量
w 权重
Output:
wls stat "beta","tstat","R2","AdjustedR2","Residual" */
在构建得到多因子回归模型后,再基于
getRetTable
函数计算如下模型评估指标:
stR
2
:该值为多因子模型中定义的
Studentized R_2
,计算方法为:
其中 r
n
为个股
n
的超额收益,
ε
n
为截面回归的残差,
w
n
是个股的加权权重,
H
nn
为 H = X(X'X)
-1
X' 的第
n
个对角元,
X
是因子暴露矩阵。
t 检验:该值为标准的
t
统计量,用来衡量回归系数的统计显著性。
偏差统计量(bias_statistic):该统计量是一种通用的衡量模型预测程度的统计量,直观来看,该统计量计算的是实际的风险比上预测的风险。令
R
nt
为组合
n
在
t
时刻的收益率,
σ
nt
是
t
时刻的波动率预测。计算方法为:令
可理解为对
R
nt
的波动率进行标准化,则预测准确则
b
nt
的标准差为 1。组合
n
在
t
时刻的偏差统计量为:
其中
T
是总截面时间数。当收益率符合正态分布的假设下,偏差统计量
B
n
的 95% 置信区间为:
因此当观测发现
B
n
接近 1 时,则可以初步推断模型的预测值是比较准确的。
Q 统计量(Q_statistic):基于偏差统计量中计算的
b
nt
,该统计量惩罚了欠拟合或者过拟合的情况,Q
统计量的计算方法为: 令
3.2. 风险调整
在构建得到多因子回归模型后,若要求解多因子模型中的个股收益率协方差矩阵,则需要分别求解因子收益率协方差矩阵
V
f
、特质收益协方差矩阵 Δ。然而基于样本求解得到的
V
f
、Δ
估计结果都是有偏的,因此需要分别对因子收益率风险矩阵、特质收益协方差矩阵分别进行协方差调整。
3.2.1. 因子收益率风险调整
3.2.1.1. Newey_West 调整
多因子模型必须进行 Newey-West 协方差调整的原因主要有以下两点:
多因子模型是日频的,然而风险预测模型是月频的,因此需要对日频的协方差矩阵通过尺度变化,转化成月频的协方差矩阵,而这个过程必须考虑日频因子收益率的自相关性。
实际应用中,基于多因子模型预测的因子收益率往往存在时序相关性。此时样本风险矩阵并不是真实收益率风险矩阵的相合估计(随着样本数增加,相合估计会收敛于真实值,这有助于计算估计量的估计误差),因此需要调整由计算出来的日收益率存在
q 阶序列性导致因子收益率的风险矩阵
V
f
。
本文 Newey-West 协方差调整的接口为
Newye_West
函数,在
getRetTable
函数的
adjust=true
时调用。
/* Newye_West
Newye_West调整得到协方差矩阵
Input:
ret 收益率表
q 收益率自相关阶数
Output:
cov Newye_West调整后的协方差阵
*/
上述接口主要实现步骤如下:
假设
F
t
可满足
MA(q)
过程,则可先基于移动平均过程进行简单校验,如下:
其中
为不考虑自相关性的样本协方差矩阵,
代表着由当期的收益率向量以及滞后期的收益率向量所得到的自协方差矩阵,但
Γ
i
本身并不对称,因此对于任何的滞后期 i ,都需要
Γ
i
和
Γ
i
'
成对出现。
对
Γ
i
的修正加入 Bartlett 权重系数
该系数与滞后期成反比,若收益率向量间的滞后期越长,则赋予
Γ
i
的权重则越小。经过证明可以发现,该修正后所得到的样本风险矩阵
V
f
是真实的风险矩阵的相合估计,且是半正定矩阵。
3.2.1.2. Eigenfactor 调整
令
V
f
是
K
×
K
的因子协方差矩阵,利用特征分解,可以将
V
f
写成对角形式
,其中
U
0
是
V
f
中相应特征值的特征向量组成的特征向量旋转矩阵。业务上来说,假设有 N 支股票,则
U
0
的每一列都是一个特征因子投资组合权重(N*1 维),以该权重构建得到 eigenfactor portfolio(特征因子投资组合,来自特征向量
eigenvector),其中
D
0
的每一个对角元则是相应的 eigenfactor portfolio
的波动风险。eigenfactor portfolio 在构建投资组合的最优化构建中有很大的意义:
eigenfactor 之间彼此独立,两两之间的协方差为零。
方差最小的 eigenfactor 代表以最小化组合方差为目标函数实现的组合,而方差最大的 eigenfactor
代表以最大化组合方差为目标函数实现的组合。
然而若直接特征分解会存在偏差,其中风险越小的 eigenfactor portfolio 的偏差反而较大,因此需要进行 Eigenfactor
调整。本文 Eigenfactor 调整对应的接口为
eigenCovAdjusted
函数,在
getRetTable
函数中当参数
eigenfactor=true
时被调用。
/* eigenCovAdjusted
eigenCovAdjusted调整风格因子协方差
Input:
cov 因子收益率协方差阵
M 蒙特卡罗模拟:重采样次数
Output:
cov eigenCovAdjusted调整后的协方差阵
*/
上述接口的主要实现步骤如下:
步骤一,首先基于蒙特卡洛模拟构造出相对于“真实值”的具有偏差的协方差矩阵
,即“模拟协方差矩阵”。
生成服从均值为 0,协方差为
D
0
的
K
×
T
维的多元正态因子收益
b
m
,每一行代表一个 eigenfactor
的收益率序列。因此
f
m
= U
0
b
m
代表了原因子的模拟的收益时间序列,其对应的协方差矩阵
即为得到的模拟协方差矩阵。
进一步特征分解,即可得到模拟的 eigenfactor 的协方差矩阵
D
m
=
U
m
'V
m
U
m
。
步骤二,以上模拟的 eigenfactor
U
m
实际上是以样本协方差矩阵
V
f
作为真实的因子收益率协方差矩阵的得到的,其中
V
f
可以理解为
V
m
的真实值,
V
m
是
V
f
的无偏估计;因此模拟的“真实协方差矩阵”为
步骤三,计算缩放量/偏差调整系数。由以上得到的
D
m
和
D
m
~
的对角元
D
m
(k)
和
D
m
~
(k)
,可以计算得到偏差调整系数
其中
M
为
Bootstrap
模拟总次数。
步骤四,调整基于样本计算得到的 eigenfactor 矩阵
D
0
:
D
0
~
=
v
2
D
0
,其中
v
是由
v(k)
生成的对角矩阵,最终可以给出经过调整后的协方差矩阵
3.2.2. 基于贝叶斯收缩的个股特异性收益率风险调整
贝叶斯收缩(Bayesian
Shrinkage)是一个常见的将先验和样本估计值结合起来的手段
。
进行贝叶斯收缩调整的主要原因是,基于多因子风险模型使用样本内数据计算出的特异性波动率在样本外的持续性很差,极高或极低的个股波动率可能会出现均值回归的情况,那么波动率会被高估或低估。
本文的贝叶斯收缩的接口为
BayesShrinkage
函数,在
getRetTable
函数中当参数
shrink=true
时被调用。
/* BayesShrinkage
BayesShrinkage调整特质波动率
Input:
cov 特质收益率协方差阵
weight 市值权重
q λ_F 压缩系数
Output:
cov BayesShrinkage调整后的协方差阵
*/
上述接口的实现步骤如下:
步骤一,计算样本估计值——基于 WLS 预测得到的特异性收益的风险
σ
^
n
。
步骤二,计算先验值——首先选择与目标个股处在同一市值的所有股票,再基于市值加权计算的特异性收益率的波动的平均值。
其中多因子风险模型把所有个股按照市值分成十档,
s
n
表示对应的市值档位,
σ
^
n
为同处在
s
n
市值档位下的 n
支股票的特异性收益率的波动,
w
n
表示 n 支股票按照市值计算的权重。
步骤三,贝叶斯收缩(使样本估计值向先验靠拢),计算后验估计。
v
n
是在收缩时赋予先验的权重(称为收缩强度系数),具体公式如下:
其中
N(s
n
)
是当前个股市值档位中的个股总数,
为样本特异性波动率与先验的偏离程度,
为
s
n
市值档位下样本特异性波动率与先验的偏离程度的标准差,
q
为经验压缩系数,其意义在于更偏重组内的标准差还是更偏重股票相对组内均值的偏差。当
越高,即目标股票的特异性收益率的波动的偏离程度越高,此时样本估计值越不靠谱,因此赋予先验的权重
v
n
则越高。
3.3. 基于 DolphinDB 的收益风险模型展示
如下,首先基于
getRetTable
接口得到的收益风险模型,并绘制得到的对应的模型评估指标(R2、T
统计量、Bias 统计量等)。如下绘制模型的
𝑆𝑡𝑢𝑑𝑒𝑛𝑡𝑖𝑧𝑒𝑑 R_2
,可知 12 年至 22
年模型的解释力最低为 5%,最高为 84%,平均为 37%,因此模型的解释力度较高。
// 一级因子收益率回归
retOut1 = getRetTable(facTable1,adjust = true)
// adjust采用Newey-West协方差调整、当市场收益率存在序列自相关时采用此方法
retOut1 = getRetTable(facTable1,adjust = false,shrink = false)
// shrink采用贝叶斯收缩调整特异性风险、推荐使用
retOut1 = getRetTable(facTable1,adjust = true,shrink = true)
// 特异性风险采用bayesian shrinkage
retOut1 = getRetTable(facTable1,adjust = true,shrink = true,eigenfactor = true)
// 因子风险采用eigenfactor adjust,当市场关联密切时采用此方法
retOut1 = getRetTable(facTable1,adjust = true,shrink = true,eigenfactor = true)
// 综上,推荐使用
retOut1 = getRetTable(facTable1,adjust = false,shrink = true,eigenfactor = true)
// 综上,推荐使用
retOut1 = getRetTable(facTable1,adjust = false,shrink = true,eigenfactor = true)
// 综上,推荐使用
retOut1 = getRetTable(fTable,adjust = false,shrink = true,eigenfactor = false)
// 综上,推荐使用
undef(`retOut)
retOut = getRetTable(facTable1,adjust = true,shrink = false ,eigenfactor = false)
// 综上,推荐使用
retOut1.stock_risk[string(2022.12.30)] // 12.30的特质收益协方差矩阵
retOut1.fac_risk[string(2022.12.30)] // 12.30的风险因子协方差矩阵
retOut1.R2 // R2
retOut1.res // 特质收益
retOut1.tstat // t-stat
retOut1.fac_ret // 因子收益
retOut1.bias // bias统计量
plot(retOut1.R2.stR2,retOut1.R2.record_date,"𝑆𝑡𝑢𝑑𝑒𝑛𝑡𝑖𝑧𝑒𝑑 R2 月频时序图")
4. 基于 DolphinDB 的多因子模型应用
4.1. 预测个股收益
预测个股收益的方法比较多样,可以通过经济学或其他模型实现通过时间序列
f
m,t
,
f
i,t
,
f
s,t
和
u
n,t
给出 t+1
期的预测因子收益,再得到预测个股收益。由于多因子模型建立时没有考虑可投资性的要求,因此基于多因子模型的预测收益应用较少。为简化模型,DolphinDB
给出基于多因子风险模型的滞后一期预测模型。
注意:到第
t
期末时,已经获得第
t
期的个股收益
r
n,t
,
x
n,i,,t-1
,
x
n,s,t-1
和
x
n,i,t
,
x
n,s,t
。将
r
n,t
,
x
n,i,t-1
和
x
n,s,t-1
代入模型后可以得到滞后一期具备预测性的
f
m,t
,
f
i,t
,
f
s,t
和
u
n,t
,此时结合
t
期末的
x
n,i,t
,
x
n,s,t
,即可得到预测的
t
期的个股收益。与直接的多因子建模预测相比:此建模使得模型估计出的
f
m,t
,
f
i,t
,
f
s,t
和
u
n,t
具备滞后一阶的部分预测性。
本文因此基于上述模型预测个股收益的对应接口函数
getPredicOut
,假设待预测的因子为全因子表的最后一期(全因子表前
t-1 数据必须完整),则基于本月初(即上月末的因子暴露预测本月末的个股收益)可计算预期因子收益率,并返回预期模型的因子协方差矩阵
(因子风险)、特质性收益协方差矩阵 (个股风险)、拟合优度
R
2
、校正后的拟合优度
adR
2
、校正后的拟合优度
stR
2
、
tstat
统计量,以评估模型预测准确度。
/* getPredicOut
Input:
facTable NULL (Default) (必须)因子表
Output:
predictRetTable
*/
如下为调用
getPredicOut
接口的具体脚本:
predictOut = getPredicOut(facTable1)
pr = select * from predictOut.predict_ret // 利用本期因子暴露预测最后一期的收益率
predictOut.R2 // 预测模型R2
predictOut.res // 预测模型特质收益
predictOut.tstat // 预测模型t-stat
predictOut.fac_ret // 预测模型因子收益
predictOut.bias // 预测模型bias统计量
注:
predictOut = getPredicOut(facTable1)
的结果较多。如需查看,推荐持久化后再查看结果,或者可以取出来部分较少的结果,除去预测收益外,包含
R2、t-stat、月频的因子收益、特质收益、风险因子协方差矩阵、特质风险表、bias 统计量的所有结果。
4.2. 组合权重优化
组合权重优化在多因子模型中起到了至关重要的作用。组合权重优化的目的在于将组合的风险特征完全定量化,使得投资经理可以清楚地了解组合的收益来源和风险暴露。权重优化的目标函数,优化目标多种多样,例如可以控制最小预测收益并最小组合风险、控制最小本期收益并最小组合风险、控制最大风险并最大化预测收益、控制最大风险并最大化本期收益等等。组合权重优化的过程包含
2 个因素:目标函数和约束条件。
4.2.1. 目标函数
假设投资组合中的每只股票的特质因子收益率与共同因子收益率不相关,并且每只股票的特质因子收益率也不相关,因此若
w
T
表示投资组合中各股票的权重,则投资组合
P
的风险矩阵可表示为如下表达式:
4.2.2. 约束条件
行业中性
行业中性是指多头组合的行业配置与对冲基准的行业配置相一致。行业中性配置的目的在于剔除行业因子对策略收益的影响,仅考察行业内部个股的超额收益。假设
H
为样本股票的行业因子哑变量矩阵,
h
为沪深 300 中 30
个行业的对应权重,那么行业中性的权重
w
满足:
风格因子中性
风格因子中性是指多头组合的风格因子较之对冲基准的风险暴露为
0。风格因子中性配置的目的是消除投资组合与市场风格因子之间的风险暴露,使投资组合的收益主要来源于阿尔法收益,而不是某一特定的市场风格。假设
X
为样本第
k
个因子的载荷截面,
w
bench
为沪深
300 指数对应权重,那么因子
k
的风格中性权重
w
满足:
现金中性
现金中性是指多空市值保持一致,不留方向性敞口。则现金中性的权重
w
满足:
最小收益预测
控制最小预测收益是多因子模型中组合权重优化的一个约束条件,其目的是确保投资组合具备一定的最低收益水平,并帮助控制风险、避免非理性配置以及维持模型一致性。这样可以使投资组合更符合投资目标和风险偏好,并提高整体投资组合的稳定性和可预测性。假设
r
min
为基准收益率,则投资组合的权重
w
应满足:
4.2.3. 基于 DolphinDB 实现组合权重优化
本文给出行业基准中性和风格基准中性下的控制最小预测收益并最小组合风险方法,对应接口函数
getOptimizeWeights
,即实现如下的优化目标。在此接口函数中,可以通过
deIndustry
和
deStyle
指定是否行业中性和风格中性:
/* getOptimizeWeights
组合权重优化中的聚合函数
Input:
covf 因子收益协方差矩阵
delta 特质收益协方差矩阵
st 2022.01.03(Default)
et 2023.01.02(Default)
ret 预期收益
r 0.05 设置的最小预测收益
tbName 因子暴露
deIndustry true 行业中性
deStyle true 风格中性
Output:
weightTable 返回预测的资产配置权重
*/
基于
getOptimizeWeights
接口,可以通过如下脚本实现在控制最小收益下的最小化风险:
optionCode = exec stock_code from getPredicOut(facTable1).predict_ret
order by return_day desc limit 20
// 初步筛选stock1
optionCode = exec stock_code from getPredicOut(facTable2).predict_ret
order by return_day desc limit 20
// 控制收益、最小化风险模型
portWeight1 = getOptimizeWeights(facTable = facTable1,retOut = retOut1,
st = st,et = et, method ="minRiskControlRet",
r = 0.05,optionCode = optionCode)
// 获得权重组合
portWeight2 = getOptimizeWeights(facTable = facTable2,retOut = retOut2,
st = st,et = et, method ="minRiskControlRet",
r = 0.05, optionCode = optionCode)
index_code = '000300'
CodePre = set(exec stock_code from getPredicOut(facTable1).predict_ret
order by return_day desc limit 200)
// 初步筛选stock2
CodeWeight = set(exec stock_code
from getBenchMark(st=st,et=et,code = index_code)
where i_weight != 0)
CodeFac =set(exec stock_code from facTable1 )
optionCode = (CodePre&CodeWeight&CodeFac).keys()
portWeight3 = getOptimizeWeights(facTable = facTable1,retOut = retOut1,
st = st,et = et, method ="minRiskControlRet",
r = 0.005,deStyle = true,optionCode = optionCode)
// 获得权重组合,并实现在风格上的风险敞口为0
portWeight3 = getOptimizeWeights(facTable = facTable1,retOut = retOut1,st = st,
et = et, method ="minRiskControlRet",r = 0.005,
deIndustry = true,optionCode = optionCode)
// 获得权重组合,并实现在行业上的风险敞口为0
portWeight4 = getOptimizeWeights(facTable = facTable2,retOut = retOut2,st = st,
et = et, method ="minRiskControlRet",r = 0.05,
optionCode = optionCode)
4.3. 资产配置评估
4.3.1. 评估事后资产配置
事后资产配置指在实际收益数据可用之后,根据实际的历史收益数据进行的资产配置。这个过程发生在投资决策之后,基于实际观察到的历史收益数据对资产进行重新配置。因此根据市值或者是等权法评估已有指数的
Bias,可以计算出指定组合的偏差统计量和 Q 统计量,以对事后资产配置进行评估。
因子(组合)Bias
资产(组合)Bias
本文基于
getFacSpecialBias
函数,计算事后资产配置的 Bias 统计量,以评估事后资产配置。
/*
获取因子的Bias时序统计量和获取个股的特质收益统计量
Input:
retOut getRetTable()函数返回的结果
index_name 指数代码
method 等权方法或者流通市值方法 'equal','float_market'
Output:
Bias统计量
*/
4.3.1.1. 事后因子组合评估
如下脚本,假设
facTable1
为实际投资的所有因子组合表,基于
getFacSpecialBias
计算因子收益率的 Bias、个股特异性的 Bias
以评估事后因子组合。
// 因子组合
retOut = getRetTable(facTable1,adjust = true,shrink = false ,eigenfactor = false)
// 综上,推荐使用
// 获取所有因子的时序bias统计量的值和所有个股的时序bias统计量值
biasOut = getFacSpecialBias(retOut)
// 因子bias
tmpfBias = select bias_stat from biasOut.fac_bias pivot by record_date,valueType
tmpfBias = tmpfBias[23:]
tbfBias = sql(select = sqlCol(tmpfBias.columnNames()[1:9]),from = tmpfBias).eval()
plot(tbfBias,tmpfBias.record_date,extras={multiYAxes: false},
title = "因子模型因子Bias统计量时序图")
plot(tbfBias,tmpfBias.record_date,extras={multiYAxes: false})
code0 = parseExpr("rowAvg("+ concat(tmpfBias.columnNames()[1:],',') + ")")
avgfBias = sql(select = sqlColAlias(code0,'avg_bias_stat'),from = tmpfBias ).eval()
plot(avgfBias,tmpfBias.record_date,extras={multiYAxes: false},
title = "因子均值Bias统计量时序图")
plot(avgfBias,tmpfBias.record_date,extras={multiYAxes: false})
// 个股特异bias
tmpsBias = select mean(bias_stat) from biasOut.stock_bias group by record_date
tmpsBias = tmpsBias[23:]
plot(tmpsBias.avg_bias_stat,tmpsBias.record_date,
extras={multiYAxes: false},title = "因子模型特异风险Bias统计量时序图")
如下,分别绘制事后多因子模型的因子 Bias 统计量时序图以及因子均值 Bias 统计量时序图,其中 CNLT 月频模型的八类风格因子 Bias
统计量长期来看均处于 1 附近,均值为 0.9962,模型对因子的风险预估较为准确,而因子均值 Bias
统计量也长期稳定在1附近,因此可以看出,不论是从因子风险角度还是特异风险角度,本模型的估计均较为准确。
因子均值 Bias 曲线:
因子模型特异风险 Bias 统计量评估:
4.3.1.2. 事后资产组合评估
以沪深 300 指数的等权资产组合为例,基于
getFacSpecialBias
计算其 Bias
统计量,并绘制沪深 300 的等权资产组合 Bias 如下所示。
/* 简单资产配置评估 */
// 计算指数配置的Bias统计量
tmpIndexbiasbn = getFacSpecialBias(retOut,'000300','equal').stock_bias
tmpIndexBias = select wavg(bias_stat,weight) from tmpIndexbiasbn group by record_date
plot(tmpIndexBias.wavg_bias_stat,tmpIndexBias.record_date,extras={multiYAxes: false})
tmpIndexbiasbn = getFacSpecialBias(retOut,'000300','float_market').stock_bias
tmpIndexBias = select wavg(bias_stat,weight) from tmpIndexbiasbn group by record_date
plot(tmpIndexBias.wavg_bias_stat,tmpIndexBias.record_date,extras={multiYAxes: false})
上图中 Bias 均值为 1.08,说明对沪深 300 的等权资产配置风险预测与实际风险较为一致。
上图中 Bias 均值为 1.08,说明对沪深 300 的流通市值加权资产配置风险预测与实际风险也较为一致。
4.3.2. 评估事前预测模型资产配置
事前资产配置指在实际收益数据可用之前,根据模型的预测和假设进行的资产配置。这个过程发生在投资决策之前,基于模型的预测结果和投资者的目标、约束条件等进行资产配置。根据已经由优化目标得到组合权重或是给定的组合权重,可以计算出指定组合的偏差统计量和
Q 统计量,观察指定资产配置组合权重的合理性或是评估优化权重的好坏。
我们基于
getPortfolioAccuracy
接口以评估事前资产配置组合。
/* getPortfolioAccuracy
计算资产组合的时序偏差统计量、Q-统计量
Input:
facTable NULL (Default) (getFSLevelFactor函数返回的)全因子回归表
retOut NULL (Default) (getRetTable函数返回的)全因子收益表
st 2022.01.03(Default)
et 2023.01.02(Default)
index_code 指定资产组合 '000300'、'399101'
method 权重配比方法 "float_value" 流通市值加权,"equal" 等权
Output:
accuracyTable
*/
假设以沪深 300 指数的等权资产组合为例,基于
getPortfolioAccuracy
函数计算事前预测资产组合的偏差,发现 B
n
统计量的均值为 0.335<1,但此处 Bias
结果与事前预测得到的组合权重有关,因此说明沪深 300 指数的等权组合对未来风险的可预测性较弱,建议重新配置资产组合。
/* 计算预测模型的bias、q统计量 */
index_code = '000300'
st = 2022.01.03
et = 2023.01.02
outAccurary = getPortfolioAccuracy(st,et,facTable1,retOut,index_code,'equal')
outAccurary = outAccurary[2:]
baseline = take(1,(shape outAccurary)[0])
plot(table(outAccurary.bias_statistic,baseline),outAccurary.record_date, extras={multiYAxes: false})
mean(outAccurary)
5. 基于 DolphinDB 的多因子风险模型实现和应用
本章节将从环境配置、数据准备、计算调用方法等方面详细介绍多因子风险模型模块的用法。
5.1.
环境准备
把附件中的 RiskFactors 文件夹下的 helper 文件夹、RiskFactorsCal.dom、RiskFactorsModel.dom 放在
[home]/modules 目录下,[home] 目录由系统配置参数 home 决定,可以通过
getHomeDir
函数查看。
有关模块使用的更多细节,请参见:
DolphinDB 教程:模块
。
5.2 数据准备
本文提供了因子测试用的因子对应表(因子对应表.xlsx),该数据包含了构建RiskFactors多因子模型所涉及到的所有库表结构及所需的字段。对于数据,需要保证当前数据的表字段名与模块字段名一致。为方便使用,本教程准备了一个辅助模块
RiskFactorsPrepare.dos 来帮助统一字段名。调用前辅助模块前,需将该辅助模块放置在RiskFactors同级目录下。
辅助模块中有以下几类函数:
prepareMockData
函数,可生成模拟的测试数据。startTime 与 endTime
为需要的数据的起始时间和结束时间。
prepareModelData
函数,基于本地数据生成因子有效性检验结果、因子合成结果。
plotFactorsValidation
函数,基于因子有效性检验结果绘制相应结果。
Assessment
函数,资产配置评估函数。
载入模块和数据方法如下:
use RiskFactors::RiskFactorsCal
use RiskFactors::RiskFactorsModel
use RiskFactors::helper::RiskFactorsPrepare
startTime,endTime = 2018.01.01, 2023.01.01
prepareMockData(startTime,endTime)
5.3 RiskFactors 模块使用范例
为了方便用户计算,附件中的 RiskFactorsTest.dos 提供了全流程构建 RiskFactors 多因子模型的使用范例,以下提供脚本均可参考
RiskFactorsTest.dos。
5.3.1 因子计算
若要计算某个风格因子可通过get+风格因子名的函数获取。以 ABS 因子为例,可通过
getAbs()
函数计算得到,调用方法如下:
// Get raw style fatcors,some sample codes:
getAbs(startTime = 2022.01.03,endTime = 2023.01.02)
在计算得到单个风格因子后,可以通过调用
getIndustry
、
getIndustryFactor
等函数获得行业因子。以中信一级 CITIC
行业分类为例,计算方法如下:
// Get raw industry factors,some sample codes:
getIndustry(startTime = 2022.01.01,endTime = 2023.01.02,method = 'CITIC')
// Get Industry Factor Weights,some sample codes:
getIndustryWeighted(startTime = 2022.01.03,endTime = 2023.01.02,method = 'CITIC')
// Get weighted industry factors
getIndustryFactor(startTime = 2022.01.03,endTime = 2023.01.02,method = 'CITIC')
5.3.2 因子合成
RiskFactors 模块中的因子合成流程较为复杂,需要按照如下链路逐一处理
基于
getAllFactors
获取所有因子
基于
getGetRegTable
对原始因子表的缺失值进行处理
基于
getFactorsValidation
对所有因子表进行有效性检验
基于
getFSLevelFactor
合成因子
本文为便于用户进一步构建 RiskFactors 模型,用户可基于
prepareModelData
函数对上述流程统一调用。假设需要合成得到时间范围为
2022.01.03~2023.01.02、原始因子需要进行市值加权标准化、去极值处理、行业分类以中信一级
CITIC
行业分类为准、按照等权法合成的一级因子表,使用示例如下(若无需合成,指定 merge_level=NULL):
st = 2022.01.03
et = 2023.01.02
normlizing = true
scaling = true
decap = true
// also you can choose industry_method = 'SW_2021'
industry_method = 'CITIC'
industry_weighted = true
// Get ALL FIRST level of factors and factor Validatiion table
factorsValid,facTable1=prepareModelData(st,et,normlizing,scaling,decap,
industry_method,industry_weighted,
merge_method="equal",merge_level="F")
select * from facTable1 limit 100
此外,基于上述得到的
factorsValid
因子有效性检验指标,用户可进一步评估因子的有效性指标,使用示例如下:
x,y=plotFactorsValidation(factorsValid,"fsc")
plot(x,y,extras={multiYAxes: false},title = "因子fsc 月频时序图")
x,y=plotFactorsValidation(factorsValid,"ic")
plot(x,y,extras={multiYAxes: false},title = "因子ic月频时序图")
x,y=plotFactorsValidation(factorsValid,"t")
plot(x,y,extras={multiYAxes: false},title = "因子t_stat月频时序图")
5.3.3 因子模型
基于
getRetTable
函数,用户可以基于因子表构建 RiskFactors
多因子模型,假设当市场收益率存在序列自相关、当市场关联密切且需要对个股特异性风险进行调整时,使用示例如下:
retOut1 = getRetTable(facTable1,adjust = true,shrink = true,eigenfactor = true)
// the output of getRetTable function
// the trait return covariance matrix for 12.30
retOut1.stock_risk[string(2022.12.30)]
// risk factor covariance matrix for 12.30
retOut1.fac_risk[string(2022.12.30)]
// R2
retOut1.R2
// trait return
retOut1.res
// t-stat
retOut1.tstat
// factor returns
retOut1.fac_ret
// bias statistic
retOut1.bias
// R2 Monthly Frequency Timing Chart
plot(retOut1.R2.stR2,retOut1.R2.record_date,"𝑆𝑡𝑢𝑑𝑒𝑛𝑡𝑖𝑧𝑒𝑑 R2 月频时序图")
5.3.4 投资组合优化
以最小风险为目标,假设预测得到的下一期个股收益率前20的股票为股票池,且无风险利率为0.05,则求得最优投资组合的使用示例如下:
// Initial screening stock1
optionCode = exec stock_code from getPredicOut(facTable1).predict_ret
order by return_day desc limit 20
// Controlled return, minimized risk model
// Obtaining weight combinations
portWeight1 = getOptimizeWeights(facTable = facTable1,retOut = retOut1,st = st,et = et,
method ="minRiskControlRet",r = 0.05,
optionCode = optionCode)
5.3.5 资产配置评估
若用户需要进行事后的因子投资组合评估,并绘制因子模型因子 Bias 统计量时序图、因子模型特异风险 Bias 统计量时序图,使用示例如下:
x,y=FactorCombinationAssessment(retOut = retOut1,plot_index="bias_stat")
plot(x,y,title = "因子模型因子Bias统计量时序图")
x,y = FactorCombinationAssessment(retOut = retOut1,plot_index="avg_bias_stat")
plot(x,y,extras={multiYAxes: false},title = "因子均值Bias统计量时序图")
x,y = FactorCombinationAssessment(retOut = retOut1,plot_index="stock_bias_stat")
plot(x,y,extras={multiYAxes: false},title = "因子模型特异风险Bias统计量时序图")
以沪深300指数为例,并以等权法构建指数,指数的简单资产配置评估使用示例如下:
x,y =AssetPortfolioAssessment(retOut = retOut1,index_code="000300",
index_weight="equal")
plot(x,y,extras={multiYAxes: false})
5.4. 注意事项
目前 DolphinDB 的 RiskFactors 多因子模块是基于本地的数据库表实现的,若用户需要基于本地已有库表实现 RiskFactors
多因子模型,暂时需要修改 RiskFactors 模块函数内部的部分库表名及列名,后续会完善相应接口,使得用户能更加方便地使用模块。其中 RiskFactors
多因子模型模块中使用的因子对应的数据源表见附件。
6. 总结
本文基于 DolphinDB 内置的丰富统计分析函数库、分布式架构下的高性能查询、便捷的向量化编程等特性,完整实现了 RiskFactors 多因子模型 CNLT
的整个流程。DolphinDB 将自身的强大功能与 RiskFactors
多因子模型进行深度融合,帮助用户更准确地分析市场因子对投资组合的影响,同时进一步优化投资策略以实现更高的投资回报。
7. 参考文献
通联数据。通联数据风险模型评测报告[R].中国:通联数据,2022。
通联数据.风险模型库介绍[R].中国:通联数据,2023。
JAY YAO.RiskFactors China A Total Market Equity Model for Long-Term
Investors[R].Andrei Morozov:MSCI,August 2018。
刘富兵,李辰.基于组合权重优化的风格中性多因子选股策略[R].中国:国泰君安证券,2015.04.26。
Newey, W. K. and K. D. West (1987). A simple, positive semi-definite,
heteroskedasticity and autocorrelation consistent covariance matrix.
Econometrica, Vol. 55(3), 703 – 708。
Menchero, J., D. J. Orr, and J. Wang (2011). The RiskFactors US Equity Model
(USE4). MSCI RiskFactors Research Notes。
Ledoit, Olivier, and Michael Wolf. "Improved estimation of the covariance matrix
of stock returns with an application to portfolio selection." Journal of
empirical finance 10.5 (2003): 603-621。
林晓明,陈烨.因子合成方法实证分析华泰多因子系列之十[R].中国:华泰证券,2018。
林晓明,陈烨.华泰多因子模型体系初华泰多因子系列之一[R].中国:华泰证券,2016。
8. 附录
因子对应数据源表:
因子对应表.xlsx
因子计算公司:
因子计算公式
建库建表和模拟数据:
createTable.dos
RiskFactors 模块:
RiskFactors
RiskFactors 模块和测试脚本:
RiskFactorsTest.dos
FILE:references/doc_4413.md
# coevent
**URL**: https://docs.dolphindb.cn/zh/funcs/c/coevent.html
**来源**: DolphinDB 官方文档
---
coevent
语法
coevent(event, eventTime, window, [orderSensitive=false])
详情
统计给定的时间间隔内出现事件对的次数。如果
eventTime
中包含 NULL 值,系统会忽略这条记录。
返回的结果是一个表,包含 event1, event2 和 hits 三个字段。event1 和 event2 的数据类型与
event
相同,hits
是整数,表示事件对出现的次数。
参数
event
是一个向量,表示事件。
eventTime
是一个时间类型或整型类型的向量,表示事件发生时间。它的长度必须与
event
相同。
window
是一个非负整数,表示时间间隔长度。
orderSensitive
是一个可选的布尔值,表示是否区分两个事件的先后顺序。默认值是 false。
返回值
返回的结果是一个表,包含 event1, event2 和 hits 三个字段。event1 和 event2 的数据类型与
event
相同,hits 是整数,表示事件对出现的次数。
例子
下例中,sensor_id 与 time 分别为发现异常的传感器编号以及发现异常时刻。使用
coevent
函数统计2秒钟内两个传感器同时出现异常的次数。
sensor_id=`A`B`C`D`C`A`B
time=[2012.06.13T12:30:00,2012.06.13T12:30:02,2012.06.13T12:30:04,2012.06.13T12:30:05,2012.06.13T12:30:06,2012.06.13T12:30:09,2012.06.13T12:30:10];
coevent(sensor_id, time, 2);
event1
event2
hits
B
C
1
C
D
2
C
C
1
A
B
2
coevent(sensor_id, time, 2, true);
event1
event2
hits
C
C
1
B
C
1
C
D
1
D
C
1
A
B
2
FILE:references/doc_4416.md
# regexCount
**URL**: https://docs.dolphindb.cn/zh/funcs/r/regexCount.html
**来源**: DolphinDB 官方文档
---
regexCount
语法
regexCount(str, pattern, [offset=0])
详情
从
str
的第
offset
个位置开始搜索,返回与
pattern
匹配的字符串在
str
中出现的次数。
参数
str
是一个字符串或字符串向量。
pattern
是一个字符串,表示搜索的模式字符串(
正则表达式
)。模式字符串可以包含字面量字符、元字符或两者的组合。
offset
是一个非负整数,默认值为0。它是一个可选参数,表示从
str
的第
offset
个位置开始搜索。
str
的第一个位置为0。
返回值
INT 类型标量。
例子
regexCount("1231hsdU777_ DW#122ddd", "[0-9]+");
// output
3
regexCount("1231hsdU777_ DW#122ddd", "[0-9]+$");
// output
0
regexCount("1231hsdU777_ DW#122ddd", "^[0-9]+");
// output
1
regexCount("abc234 ff456", "[a-z]", 3);
// output
2
FILE:references/doc_4421.md
# 建库建表
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db_oper/create_db_tb.html
**来源**: DolphinDB 官方文档
---
建库建表
在 DolphinDB 中,创建数据库和表既可以通过 SQL 语句实现,也可以使用函数来完成。本文将分别以这两种方式进行介绍。
注:
本文中 SQL 语句的关键字对大小写不敏感;对于前文创建过的数据库,后文将直接使用而非再次定义。
创建数据库
在 DolphinDB 中,数据库分为分布式数据库和内存数据库。本节将分别举例介绍他们的创建方式。
创建分布式数据库
只有具备 DB_OWNER 权限的用户才可以通过数据节点或计算节点创建分布式数据库。可通过
getUserAccess
查看当前用户是否具有该权限,如果没有,请联系管理员赋权。
若您刚刚下载 DolphinDB ,可登录默认管理员账号:
login(`admin,`123456)
DolphinDB 支持通过 CREATE DATABASE 语句和
database
函数两种方式创建数据库。下例分别使用这两种方式,创建了一个名为 “dfs://valuedb“ 的分布式数据库。其中 “dfs://“
是分布式数据库的标识;指定了分区类型为值分区;设置了 2023.01.01 到 2023.12.31 共 365 个初始分区;并指定存储引擎的类型为
TSDB。执行前须确保不存在同名数据库。
通过
CREATE DATABASE
语句:
CREATE DATABASE "dfs://valuedb"
PARTITIONED BY VALUE(2023.01.01..2023.12.31),
ENGINE="TSDB"
通过
database
函数:
database(directory="dfs://valuedb", partitionType=VALUE,
partitionScheme=2023.01.01..2023.12.31, engine='TSDB')
两种方式的区别在于:CREATE DATABASE 语句没有返回值;
database
函数会返回一个数据库句柄(dbHandle)。
关于 CREATE DATABASE 语句,细节请参见
create
。
关于
database
函数,细节请参见
database
。
关于数据分区:
DolphinDB 支持 5 种分区类型
(
partitionType
),分别是值分区、哈希分区、范围分区、列表分区与复合分区。分区类型一经确定,不可更改。
数据分区方式的选择应保证每个分区的大小均匀,且大小在 100M-1G 之间。
同一数据库下的所有表都是采用相同的分区方案。
数据库分区方案 (
partitionScheme
) 设定后,分布式表的值分区(VALUE)允许增加分区;分布式表的范围分区 (RANGE)
允许在最后一个现有数据分区后面增加分区;其它分布类型不允许增加分区。
更多关于数据分区的内容请参考
数据分区
。
关于存储引擎(
engine
):DolphinDB 支持
TSDB
,
OLAP
,
PKEY
等多种存储引擎,一个数据库的存储引擎一经确定,不可修改。
类似的,若要创建组合分区数据库:
通过
CREATE DATABASE
语句
CREATE DATABASE "dfs://compodb"
PARTITIONED BY VALUE(2020.01.01..2021.01.01),HASH([SYMBOL,25])
通过
database
函数
db1 = database("", VALUE, 2020.01.01..2021.01.01)
db2 = database("", HASH, [SYMBOL,25])
compoDb=database(directory="dfs://compodb", partitionType=COMPO, partitionScheme=[db1,db2])
创建内存数据库
内存数据库将数据直接存储在内存中,相较于传统的磁盘数据库,它具有更快的数据访问速度和更低的延迟。此外,在内存数据库中创建内存分区表,可对内存表进行并行处理,从而进一步提升数据处理效率。
内存数据库只支持通过函数
database
创建。当函数
database
的参数
directory
设置为空时,代表创建一个内存数据库。示例脚本如下:
mdb = database(directory="", partitionType=VALUE, partitionScheme=1..10)
创建表
DolphinDB 中,数据表分为内存表和分布式表。本节将分别举例介绍他们的创建方式。
创建分布式表
只有具备 DBOBJ_CREATE 和 DB_MANAGE 权限的用户或当前数据库创建者才能够创建分布式表。可通过
getUserAccess
查看当前用户是否具有创建分区表的权限,如果没有,请联系管理员赋权。
创建分区表
通过
CREATE TABLE
语句创建 TSDB 分区表
CREATE DATABASE "dfs://valuedb" PARTITIONED BY VALUE(2023.01.01..2023.12.31),engine="TSDB"
CREATE TABLE "dfs://valuedb"."pt"(
date DATE,
time TIME,
sym SYMBOL,
price DOUBLE
)
PARTITIONED BY date,
sortColumns=`time
通过函数
createPartitionedTable
创建 TSDB 分区表
// 获取已创建的数据库句柄
valueDb = database("dfs://valuedb")
// 创建内存表 schemaTb
schemaTb = table(1:0,`date`time`sym`price,[DATE,TIME,SYMBOL,DOUBLE])
// 根据内存表 schemaTb 的结构创建 TSDB 分区表
pt = createPartitionedTable(dbHandle=valueDb, table=schemaTb, tableName=`pt, partitionColumns=`date, sortColumns=`sym`time)
更多实用细节请参考
createPartitionedTable
。
对于组合分区的数据库,在创建分区表时,分区列个数应匹配对应的分区方案:
通过
CREATE TABLE
语句
CREATE TABLE "dfs://compodb"."pt"(
date DATE,
time TIME,
sym SYMBOL,
price DOUBLE
)
partitioned by date, sym
通过
createPartitionedTable
函数
// 获取已创建的数据库句柄
compoDb = database("dfs://compodb")
// 创建内存表 schemaTb
schemaTb = table(1:0,`date`time`sym`price,[DATE,TIME,SYMBOL,DOUBLE])
// 根据内存表 schemaTb 的结构创建组合分区表
pt = createPartitionedTable(dbHandle=compoDb, table=schemaTb, tableName=`pt, partitionColumns=`date`sym)
创建维度表
通过
CREATE TABLE
语句创建维度表
CREATE TABLE "dfs://valuedb"."dt"(
date DATE,
time TIME,
sym SYMBOL,
price DOUBLE
)
sortColumns=`sym`time
通过函数
createDimensionTable
创建维度表
// 获取已创建的数据库句柄
valueDb = database("dfs://valuedb")
// 创建内存表 schemaTb
schemaTb = table(1:0,`date`time`sym`price,[DATE,TIME,SYMBOL,DOUBLE])
// 根据内存表 schemaTb 的结构创建维度表
dt = createDimensionTable(dbHandle=valueDb, table=schemaTb, tableName=`dt, sortColumns=`sym`time)
更多使用细节,请参考
createDimensionTable
。
创建内存表
DolphinDB 支持多种内存表,包括普通内存表、索引内存表、键值内存表、流数据表、mvcc 内存表、内存分区表和缓存表等,详情请见
表
。
通过
CREATE LOCAL TEMPORARY TABLE
语句创建普通内存表
CREATE LOCAL TEMPORARY TABLE t(
col1 INT,
col2 DOUBLE,
col3 STRING
)
通过函数
table
创建普通内存表
创建空表
t = table(1:0, `ool1`col2`col3, [INT,DOUBLE,STRING])
根据现有数据创建内存表
t = table(1 2 as col1, 1.1 2.2 as col2, `A1`B2 as col3)
通过 CREATE 语句和
table
函数创建内存表的区别在于,
table
函数可以通过现有向量创建含有数据的内存表,CREATE 语句只能创建空表。
通过函数
createPartitionedTable
可以创建内存分区表
// 创建一个内存数据库
mdb = database("", VALUE, 1..10)
// 创建一个内存表
t = table(1:0,`id`sym`price`qty,[INT,SYMBOL,DOUBLE,INT])
// 根据内存表 t 的结构创建内存分区表
mpt = createPartitionedTable(dbHandle=mdb, table=t, tableName=`pt, partitionColumns=`id)
FILE:references/doc_4428.md
# portfolioPricer
**URL**: https://docs.dolphindb.cn/zh/funcs/p/portfolioPricer.html
**来源**: DolphinDB 官方文档
---
portfolioPricer
语法
portfolioPricer(instrument, amount, pricingDate,
marketData)
详情
对一个或多个金融合约(可为相同类型或不同类型)进行组合定价。
参数
instrument
INSTRUMENT 类型对象,表示需要定价的金融工具。可以是单个合约,也可以是多个合约。
amount
INT 类型标量或向量,与
instrument
等长,表示对应的合约数量。
pricingDate
DATE 类型标量,表示定价日,即计算合约价值所对应的日期。
marketData
MKTDATA 类型向量,或者嵌套字典,表示市场数据。
MKTDATA 类型向量:
若为曲线类市场数据,需指定 curveName 字段。
若为曲面类市场数据,需指定 surfaceName 字段。
嵌套字典的结构如下:
第一层:key 为数据类别,可选值:"Spot", "Curve", "Surface"。
第二层:key 为定价日期(DATE 类型标量)。
第三层:key 为曲线或曲面名称,value 为对应的 MKTDATA 类型标量。
返回值
DOUBLE 类型标量。
instrument 和 marketData 的匹配规则
目前支持下图分类树中叶节点所示的金融工具类型:
在定价过程中,系统会按照以下优先级确定市场数据:
若
instrument
中已显式指定市场数据,则直接使用该数据;
若未指定,则系统根据预定义规则自动匹配合适的市场数据。
以下将对不同类型金融工具的匹配规则进行说明。
债券(Bond)
债券定价需要用到折现曲线。用户可以通过 discountCurve 字段指定折现曲线名称,例如:
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "1382011.IB",
"start": "2013.01.14",
"maturity": "2028.01.14",
"issuePrice": 100.0,
"coupon": 0.058,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA",
"currency": "CNY", //可选字段
"subType": "MTN", //可选字段
"creditRating": "AAA", //可选字段
"discountCurve": "CNY_MTN_AAA" //可选字段
}
折现曲线选择规则如下:
如果 discountCurve 已指定,则优先使用 discountCurve 的值。
如果 discountCurve 未指定:
指定了 currency,subType 和 creditRating,系统会选择名为 currency + "_" +
subType + "_" + creditRating 的折现曲线。
指定了 currency,且 subType 为
TREASURY_BOND
,
CENTRAL_BANK_BILL
,
CDB_BOND
,
EIBC_BOND
,
ADBC_BOND
之一,则不需要 creditRating,系统会选择名为 currency + "_" + subType
的折现曲线。
指定了 currency,且 subType 不为
TREASURY_BOND
,
CENTRAL_BANK_BILL
,
CDB_BOND
,
EIBC_BOND
,
ADBC_BOND
之一,同时未指定 creditRating,系统会选择名为 currency + "_TREASURY_BOND"
的折现曲线。
指定了 currency,且未指定 subType 和 creditRating,系统会选择名为 currency +
"_TREASURY_BOND" 的折现曲线。
currency,subType 和 creditRating 均未指定,系统会选择名为
"CNY_TREASURY_BOND" 的折现曲线。
国债期货(BondFutures)
无需指定 discountCurve,函数会使用其标的债券(underlying)的 dicountCurve。
存款(Deposit)
存款定价仅需指定折现曲线 discountCurve:
如果 discountCurve 已指定,则使用用户指定的曲线进行定价。
如果未指定,则根据币种自动匹配折现曲线,规则如下:
currency
discountCurve
CNY
CNY_FR_007
USD
USD_SOFR
EUR
EUR_ESTR
利率互换(IrFixedFloatingSwap)
利率互换定价需要传入三条曲线:discountCurve、forwardCurve 和 assetPriceCurve。当前版本仅支持以 FR_007 和
SHIBOR_3M 作为浮动参考利率的利率互换。
如果用户在
instrument
中指定了相应曲线,则使用用户指定的曲线进行定价。
如果未指定,则根据币种和浮动利率基准自动匹配三条默认曲线,如下表所示:
currency
iborIndex
discountCurve
forwardCurve
assetPriceCurve
CNY
FR_007
CNY_FR_007
CNY_FR_007
PRICE_FR_007
CNY
SHIBOR_3M
CNY_FR_007
CNY_SHIBOR_3M
PRICE_SHIBOR_3M
其中 assetPriceCurve 填入的是浮动参考利率的历史数据,用于计算定价日起第一笔现金流的浮动利率。
外汇远期(FxForward)/ 外汇掉期(FxSwap)
这两类线性产品定价需要绑定 domesticCurve 和 foreignCurve,并基于 currencyPair 获取相应的 FxSpot。
若用户在
instrument
中指定了 domesticCurve 和
foreignCurve,则直接使用用户指定的曲线。
若未指定,则系统会根据货币对自动匹配默认曲线,如下表所示:
currencyPair
domesticCurve
foreignCurve
USDCNY
CNY_FR_007
USD_USDCNY_FX
EURCNY
CNY_FR_007
EUR_EURCNY_FX
EURUSD
USD_SOFR
EUR_EURUSD_FX
其中 foreignCurve 是根据外汇掉期交易,并结合利率平价公式推导得到的外币隐含即期曲线。
外汇欧式期权(FxEuropeanOption)
外汇期权定价除需使用 domesticCurve 与 foreignCurve 外,还依赖 FxSpot 和 FxVolatilitySurface。
这两个市场数据均可根据期权的 underlying(货币对) 自动匹配。
若用户在
instrument
中明确指定,则优先使用用户提供的 domesticCurve、foreignCurve。
若未指定,则系统会根据
currencyPair
自动匹配,规则如下:
currencyPair
fxSpot
domesticCurve
foreignCurve
volSurf
USDCNY
USDCNY
CNY_FR_007
USD_USDCNY_FX
USDCNY
EURCNY
EURCNY
CNY_FR_007
EUR_EURCNY_FX
EURCNY
EURUSD
EURUSD
USD_SOFR
EUR_EURUSD_FX
EURUSD
例子
// instrument
//外汇远期
fxFwd1 = {
"productType": "Forward",
"forwardType": "FxForward",
"version": 0,
"expiry": 2025.10.08,
"delivery": 2025.10.10,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E6],
"strike": 7.2
}
fxFwdUsdCny = parseInstrument(fxFwd1)
fxFwd2 = {
"productType": "Forward",
"forwardType": "FxForward",
"version": 0,
"expiry": 2025.10.08,
"delivery": 2025.10.10,
"currencyPair": "EURCNY",
"direction": "Buy",
"notional": ["EUR", 1E6],
"strike": 8.2
}
fxFwdEurCny = parseInstrument(fxFwd2)
//外汇掉期
fxSwap1 = {
"productType": "Swap",
"swapType": "FxSwap",
"version": 0,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E6],
"nearStrike": 7.2,
"nearExpiry": 2025.12.08,
"nearDelivery": 2025.12.10,
"farStrike": 7.3,
"farExpiry": 2026.06.08,
"farDelivery": 2026.06.10
}
fxSwapUsdCny = parseInstrument(fxSwap1)
fxSwap2 = {
"productType": "Swap",
"swapType": "FxSwap",
"version": 0,
"currencyPair": "EURCNY",
"direction": "Buy",
"notional": ["EUR", 1E6],
"nearStrike": 8.2,
"nearExpiry": 2025.12.08,
"nearDelivery": 2025.12.10,
"farStrike": 8.3,
"farExpiry": 2026.06.08,
"farDelivery": 2026.06.10
}
fxSwapEurCny = parseInstrument(fxSwap2)
//外汇欧式期权
fxOption1 = {
"productType": "Option",
"optionType": "EuropeanOption",
"assetType": "FxEuropeanOption",
"version": 0,
"notional": ["USD", 1E6],
"strike": 7.0,
"maturity": 2025.12.08,
"payoffType": "Call",
"dayCountConvention": "Actual365",
"underlying": "USDCNY"
}
fxOptionUsdCny = parseInstrument(fxOption1)
fxOption2 = {
"productType": "Option",
"optionType": "EuropeanOption",
"assetType": "FxEuropeanOption",
"version": 0,
"notional": ["EUR", 1E6],
"strike": 8.0,
"maturity": 2025.12.08,
"payoffType": "Call",
"dayCountConvention": "Actual365",
"underlying": "EURCNY"
}
fxOptionEurCny= parseInstrument(fxOption2)
//债券
bond1 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "220010.IB",
"start": 2020.12.25,
"maturity": 2031.12.25,
"issuePrice": 100.0,
"coupon": 0.0149,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA",
"discountCurve": "CNY_TREASURY_BOND"
}
bond = parseInstrument(bond1)
//国债期货
bondFut1 = {
"productType": "Futures",
"futuresType": "BondFutures",
"version": 0,
"instrumentId": "T2509",
"nominal": 100.0,
"maturity": "2025.09.12",
"settlement": "2025.09.16",
"underlying": bond1,
"nominalCouponRate": 0.03
}
bondFut = parseInstrument(bondFut1)
//存款
deposit1 = {
"productType": "Cash",
"assetType": "Deposit",
"version": 0,
"start": 2025.06.15,
"maturity": 2025.12.15,
"rate": 0.02,
"dayCountConvention": "Actual360",
"notional":["CNY", 1E6],
"payReceive": "Receive"
}
deposit = parseInstrument(deposit1)
//利率互换
irs1 = {
"productType": "Swap",
"swapType": "IrSwap",
"irSwapType": "IrFixedFloatingSwap",
"version": 0,
"start": 2025.06.16,
"maturity": 2028.06.16,
"frequency": "Quarterly",
"fixedRate": 0.018,
"calendar": "CFET",
"fixedDayCountConvention": "Actual365",
"floatingDayCountConvention": "Actual365",
"payReceive": "Pay",
"iborIndex": "FR_007",
"spread": 0.0001,
"notional":["CNY", 1E8]
}
irs = parseInstrument(irs1)
//mktData
aod = 2025.08.18
fxSpot1 = {
"mktDataType": "Spot",
"spotType": "FxSpot",
"version": 0,
"spotDate": aod+2 ,
"referenceDate": aod ,
"value": 7.1627,
"unit": "USDCNY"
}
fxSpotUsdCny = parseMktData(fxSpot1)
fxSpot2 = {
"mktDataType": "Spot",
"spotType": "FxSpot",
"version": 0,
"spotDate": aod+2 ,
"referenceDate": aod ,
"value": 8.3768,
"unit": "EURCNY"
}
fxSpotEurCny = parseMktData(fxSpot2)
curve1 = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"curveName": "CNY_FR_007",
"referenceDate": aod,
"currency": "CNY",
"dayCountConvention": "ActualActualISDA",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"dates":[2025.08.21, 2025.08.27, 2025.09.03, 2025.09.10, 2025.09.22, 2025.10.20, 2025.11.20,
2026.02.24,2026.05.20, 2026.08.20, 2027.02.22, 2027.08.20, 2028.08.21],
"values":[1.4759, 1.5331, 1.5697, 1.5239, 1.4996, 1.5144, 1.5209,
1.5539, 1.5461, 1.5316, 1.5376, 1.5435, 1.5699] / 100.0
}
curveCnyFr007 = parseMktData(curve1)
curve2 = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"curveName": "USD_USDCNY_FX",
"referenceDate": aod ,
"currency": "USD",
"dayCountConvention": "ActualActualISDA",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"dates":[2025.08.21, 2025.08.27, 2025.09.03, 2025.09.10, 2025.09.22, 2025.10.20, 2025.11.20,
2026.02.24,2026.05.20, 2026.08.20, 2027.02.22, 2027.08.20, 2028.08.21],
"values":[4.3345, 4.3801, 4.3119, 4.3065, 4.2922, 4.2196, 4.1599,
4.0443, 4.0244, 3.9698, 3.7740, 3.6289, 3.5003] / 100.0
}
curveUsdUsdCnyFx = parseMktData(curve2)
curve3 = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"curveName": "EUR_EURCNY_FX",
"referenceDate": aod,
"currency": "EUR",
"dayCountConvention": "ActualActualISDA",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"dates":[2025.08.21, 2025.08.27, 2025.09.03, 2025.09.10, 2025.09.22, 2025.10.20, 2025.11.20,
2026.02.24,2026.05.20, 2026.08.20, 2027.02.22, 2027.08.20, 2028.08.21],
"values":[1.9165, 1.9672, 1.8576, 1.8709, 1.8867, 1.8749,1.8700,
1.8576, 1.9253, 1.9738, 1.9908, 1.9850, 2.0362] / 100.0
}
curveEurEurCnyFx = parseMktData(curve3)
surf1 = {
"surfaceName": "USDCNY",
"mktDataType": "Surface",
"surfaceType": "FxVolatilitySurface",
"version": 0,
"referenceDate": "2025.08.18",
"smileMethod": "Linear",
"termDates": [
"2025.08.21",
"2026.08.20"
],
"volSmiles":[{"strikes": [6.5,7,7.5],"vols": [0.1,0.1,0.1]},{"strikes": [6.5,7,7.5],"vols": [0.1,0.1,0.1]}],
"currencyPair": "USDCNY"
}
surfUsdCny = parseMktData(surf1)
surf2 = {
"surfaceName": "EURCNY",
"mktDataType": "Surface",
"surfaceType": "FxVolatilitySurface",
"version": 0,
"referenceDate": "2025.08.18",
"smileMethod": "Linear",
"termDates": [
"2025.08.21",
"2026.08.20"
],
"volSmiles":[{"strikes": [7.5,8.0,8.5],"vols": [0.1,0.1,0.1]},{"strikes": [7.5,8.0,8.5],"vols": [0.1,0.1,0.1]}],
"currencyPair": "EURCNY"
}
surfEurCny = parseMktData(surf2)
bondCurve = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": aod,
"currency": "CNY",
"curveName": "CNY_TREASURY_BOND",
"dayCountConvention": "ActualActualISDA",
"compounding": "Compounded",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
// 0.083 0.25 0.5 1.0 2.0 3.0 5.0 7.0 10.0 15.0 20.0 30.0 40.0 50.0
"dates":[2025.09.18, 2025.11.18, 2026.02.18, 2026.08.18, 2027.08.18, 2028.08.18, 2030.08.18,
2032.08.18, 2035.08.18, 2040.08.18, 2045.08.18, 2055.08.18,2065.08.18, 2075.08.18],
"values":[1.3000, 1.3700, 1.3898, 1.3865, 1.4299, 1.4471, 1.6401,
1.7654, 1.7966, 1.9930, 2.1834, 2.1397, 2.1987, 2.2225] / 100.0
}
curveCnyTreasuryBond = parseMktData(bondCurve)
fr007HistCurve = {
"mktDataType": "Curve",
"curveType": "AssetPriceCurve",
"curveName": "PRICE_FR_007",
"version": 0,
"referenceDate": aod,
"currency": "CNY",
"dates":[2025.05.09, 2025.05.12, 2025.05.13, 2025.05.14, 2025.05.15, 2025.05.16, 2025.05.19, 2025.05.20, 2025.05.21, 2025.05.22,
2025.05.23, 2025.05.26, 2025.05.27, 2025.05.28, 2025.05.29, 2025.05.30, 2025.06.03, 2025.06.04, 2025.06.05, 2025.06.06,
2025.06.09, 2025.06.10, 2025.06.11, 2025.06.12, 2025.06.13, 2025.06.16, 2025.06.17, 2025.06.18, 2025.06.19, 2025.06.20,
2025.06.23, 2025.06.24, 2025.06.25, 2025.06.26, 2025.06.27, 2025.06.30, 2025.07.01, 2025.07.02, 2025.07.03, 2025.07.04,
2025.07.07, 2025.07.08, 2025.07.09, 2025.07.10, 2025.07.11, 2025.07.14, 2025.07.15, 2025.07.16, 2025.07.17, 2025.07.18,
2025.07.21, 2025.07.22, 2025.07.23, 2025.07.24, 2025.07.25, 2025.07.28, 2025.07.29, 2025.07.30, 2025.07.31, 2025.08.01,
2025.08.04, 2025.08.05, 2025.08.06, 2025.08.07, 2025.08.08, 2025.08.11, 2025.08.12, 2025.08.13, 2025.08.14, 2025.08.15
],
"values":[1.6000, 1.5600, 1.5300, 1.5500, 1.5500, 1.6300, 1.6500, 1.6000, 1.5900, 1.5800,
1.6300, 1.7000, 1.7000, 1.7000, 1.7500, 1.7500, 1.5900, 1.5800, 1.5700, 1.5600,
1.5500, 1.5500, 1.5600, 1.5900, 1.5900, 1.5700, 1.5500, 1.5600, 1.5679, 1.6000,
1.5700, 1.8500, 1.8300, 1.8400, 1.8500, 1.9500, 1.6036, 1.5800, 1.5200, 1.5000,
1.5000, 1.5100, 1.5100, 1.5300, 1.5200, 1.5500, 1.6000, 1.5400, 1.5400, 1.5000,
1.5000, 1.4800, 1.5000, 1.6000, 1.7500, 1.6400, 1.6200, 1.6300, 1.6000, 1.5000,
1.4800, 1.4700, 1.4800, 1.4900, 1.4600, 1.4600, 1.4600, 1.4800, 1.4800, 1.4900
]\100
}
priceCurveFr007 = parseMktData(fr007HistCurve)
instrument = [fxFwdUsdCny, fxFwdEurCny, fxSwapUsdCny, fxSwapEurCny,
fxOptionUsdCny, fxOptionEurCny, bond, bondFut, deposit, irs]
mktData= [fxSpotUsdCny, fxSpotEurCny, curveCnyFr007,
curveUsdUsdCnyFx, curveEurEurCnyFx, surfUsdCny,
surfEurCny, curveCnyTreasuryBond, priceCurveFr007]
pricingDate = aod
amount = [1, 2, 3, 4, 5, 6, -7, -8, 9, 10]
// case1: mktData is a vector
results1 = portfolioPricer(instrument, amount, pricingDate, mktData)
print(results1)
// case2: mktData is a dict
spots = dict(string, MKTDATA)
spots["USDCNY"] = fxSpotUsdCny
spots["EURCNY"] = fxSpotEurCny
curves = dict(string, MKTDATA)
curves["CNY_FR_007"] = curveCnyFr007
curves["USD_USDCNY_FX"] = curveUsdUsdCnyFx
curves["EUR_EURCNY_FX"] = curveEurEurCnyFx
curves["CNY_TREASURY_BOND"] = curveCnyTreasuryBond
curves["PRICE_FR_007"] = priceCurveFr007
surfs = dict(string, MKTDATA)
surfs["USDCNY"] = surfUsdCny
surfs["EURCNY"] = surfEurCny
dSpots = dict(DATE, ANY)
dSpots[aod] = spots
dCurves = dict(DATE, ANY)
dCurves[aod] = curves
dSurfs = dict(DATE, ANY)
dSurfs[aod] = surfs
mktData2 = dict(STRING, ANY)
mktData2 = {"Spot": dSpots,
"Curve": dCurves,
"Surface": dSurfs}
results2 = portfolioPricer(instrument, amount, pricingDate, mktData2)
print(results2)
相关函数:
instrumentPricer
FILE:references/doc_4436.md
# max
**URL**: https://docs.dolphindb.cn/zh/funcs/m/max.html
**来源**: DolphinDB 官方文档
---
max
语法
max(X, [Y])
详情
返回输入数据中的最大值。
支持以下两种调用方式:
仅输入一个参数
X
,用于计算
X
的最大值。比较时忽略 NULL 值。
输入两个参数,用于按元素比较两个数据对象,返回较大值。比较时不忽略 NULL 值。
请注意,从 2.00.8 版本开始,
max
处理时间类型数据的行为(之前版本统一转换为长整型)修改为:
若
X
和
Y
是时间类型标量,系统会将时间类型统一为两者中较高精度对应的类型,再比较大小。
若
X
或
Y
是向量、矩阵或表,则必须具有相同的时间类型。
参数
X
可以是标量、向量、矩阵或表。
Y
为可选参数,可以是标量或者是和
X
长度相同的向量或者矩阵。
返回值
单参数调用:
若
X
是向量,返回一个标量。
若
X
为矩阵,返回一个向量。
若
X
为表,返回一个表。
双参数调用:
若
Y
是标量,返回与
X
维度相同的对象,每个元素为
max(X[i], Y)
。
若
Y
和
X
类型和长度一致,返回对应位置较大值组成的对象。
例子
max(1 2 3);
// output: 3
max(7.8 9 5.4);
// output: 9
(5 8 2 7).max();
// output: 8
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
max(m);
// output: [3,6]
max(1 2 3, 2)
// output: 2 2 3
n = matrix(1 1 1, 5 5 5)
n;
#0
#1
1
5
1
5
1
5
max(m, n);
#0
#1
1
5
2
5
3
6
max
可以搭配 select 使用, 返回某列的最大值:
t = table(`abb`aac`aaa as sym, 1.8 2.3 3.7 as price);
select max price from t;
max_price
3.7
max 可以应用于字符串,返回字典序最大的字符串:
select max sym from t;
max_sym
abb
相关函数:
mmax
FILE:references/doc_445.md
# setChunkLastUpdateTime
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setChunkLastUpdateTime.html
**来源**: DolphinDB 官方文档
---
setChunkLastUpdateTime
语法
setChunkLastUpdateTime(chunkId, lastUpdateTime)
详情
手动设置指定分区的上次更新时间(可通过函数
getClusterChunksStatus
返回的 lastUpdated
字段查看)。
该函数仅支持管理员用户在单节点、或集群模式中的控制节点上调用。
参数
chunkId
字符串向量,用于指定分区 ID。
lastUpdateTime
TIMESTAMP 类型,指定分区的更新时间。
例子
setChunkLastUpdateTime(["32953d51-980c-59a1-5f43-c90bfddd5a63","d957b444-be92-9296-ba4a-9d8a41682168"], timestamp(2016.05.12T19:32:49))
FILE:references/doc_4469.md
# getStreamTables
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getstreamtables.html
**来源**: DolphinDB 官方文档
---
getStreamTables
语法
getStreamTables([option=0])
详情
获取流数据表的信息。
参数
option
整型标量,表示需要获取的流表的类型。可取以下值:
0:获取所有流表
1:获取持久化流表
2:获取非持久化流表
返回值
返回一个表,包含如下列:
name:表的名称。
shared:是否为共享表。
persisted:是否为持久化表。
cachePurgeEnabled:是否为定时清理的非持久化流表。
loaded:是否已加载到内存。
columns:表所包含的列数。
rowsInMemory:内存中的行数。
totalRows:写入流表的总行数。
memoryUsed:表所占用的内存大小,单位为字节。
注:
若持久化表没被加载到内存时,则只返回 name, persisted 和 loaded 字段,其它字段返回
NULL。
例子
id=`XOM`GS`AAPL;
x=102.1 33.4 73.6;
rt=streamTable(id, x);
share streamTable(10:0,`time`sym`price`volume,[TIMESTAMP,SYMBOL,DOUBLE,INT]) as trades1;
share streamTable(10:0,`time`sym`price`volume,[TIMESTAMP,SYMBOL,DOUBLE,INT]) as trades2;
getStreamTables()
name
shared
persisted
cachePurgeEnabled
loaded
columns
rowsInMemory
totalRows
memoryUsed
rt
false
false
false
true
2
3
3
152
trades1
true
false
false
true
4
0
0
240
trades2
true
false
false
true
4
0
0
240
FILE:references/doc_4478.md
# deltas
**URL**: https://docs.dolphindb.cn/zh/funcs/d/deltas.html
**来源**: DolphinDB 官方文档
---
deltas
语法
deltas(X,[n])
详情
对于
X
中的每一个元素,计算
X
i
-
X
i-n
,NULL 值不参与计算。
参数
X
是一个向量、矩阵或表。
n
可选参数,一个整数,用于减数相较于被减数的索引偏移。默认是1。
返回值
若
X
是向量,返回一个包含
X
中两个元素之差的向量。
若
X
是矩阵,在每列内进行上述计算,返回一个与
X
维度相同的矩阵。
若
X
是表,在每列内进行上述计算,返回一个与
X
行数与列数都相同的表。
例子
x=7 4 5 8 9;
deltas(x);
//output: [,-3,1,3,1]
//等价于 [, 4-7, 5-4, 8-5, 9-8]
x=NULL 1 2 NULL 3;
deltas(x);
//output: [,,1,,]
m=matrix(1 3 2 5 6, 0 8 NULL 7 6);
m;
#0
#1
1
0
3
8
2
5
7
6
6
deltas(m);
#0
#1
2
8
-1
3
1
-1
n
是正整数时:
deltas(m,2)
0
1
1
2
-1
4
n
为负整数时:
deltas(m,-2)
0
1
-1
-2
1
-4
FILE:references/doc_4486.md
# rebalanceChunksAmongDataNodes
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rebalanceChunksAmongDataNodes.html
**来源**: DolphinDB 官方文档
---
rebalanceChunksAmongDataNodes
语法
rebalanceChunksAmongDataNodes([exec = false], [updatedBeforeDays =
7.0])
详情
在集群中的所有磁盘间平衡数据,以保证集群达到最佳性能。在集群中增加节点、磁盘后,或者在磁盘负载过高时,通常需要执行此操作。只能由管理员在控制节点上执行。
调用该函数后,可以在控制节点上执行
getRecoveryTaskStatus
查看任务执行的状态。
调用该函数后,系统会打印 INFO
级别的日志,输出每个磁盘的原始使用率以及平衡后的使用率。日志内容的格式如下:
[rebalance] Expected change of disk usage rate is 原本占有率->搬运后占有率
[rebalance] Change of disk usage rate in 磁盘所在IP@磁盘fsid(1/磁盘数) is 原本占有率->搬运后占有率
[rebalance] Change of disk usage rate in 磁盘所在IP@磁盘fsid(2/磁盘数) is 原本占有率->搬运后占有率
...
参数
exec
布尔值,表示是否进行数据平衡。默认值为 false,表示输出数据平衡的执行计划,并不执行数据迁移。若设置为
true,则系统会执行数据迁移。
updatedBeforeDays
非负浮点数,用于确定可以进行平衡的数据的时间范围,默认值是7,单位是天。表示数据块(chunk)的最后一次写入或更新(修改)时间发生在7天前时,才会进行平衡。
返回值
返回一个表,包含以下列:
列名
含义
srcNode
源节点的别名
chunkId
chunk 的唯一标识
destNode
目标节点的别名
destVolume
目标磁盘卷的路径
例子
rebalanceChunksAmongDataNodes()
srcNode
chunkId
destNode
destVolume
node1
99279094-ca12-3b87-48b6-520cbb986f39
node2
/home/xxx/node2/storage
node1
45f612b8-42f5-aebd-4cef-e522b6ae1fc8
node2
/home/xxx/node2/storage
FILE:references/doc_4487.md
# attributeNames
**URL**: https://docs.dolphindb.cn/zh/funcs/a/attributenames.html
**来源**: DolphinDB 官方文档
---
attributeNames
语法
attributeNames(obj)
详情
获取类实例的所有属性名称。
参数
obj
类实例。
返回值
字符串向量
例子
class Person {
name :: STRING
age :: INT
def Person(name_, age_) {
name = name_
age = age_
}
}
p = Person("Sam", 12)
attributeNames(p)
// output: ["name","age"]
FILE:references/doc_4489.md
# getInstrumentFarStrike
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getInstrumentFarStrike.html
**来源**: DolphinDB 官方文档
---
getInstrumentFarStrike
语法
getInstrumentFarStrike(instrument)
详情
根据输入的金融工具,获取该工具的远端行权价格。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DOUBLE 类型标量或向量。
例子
swap = {
"productType": "Swap",
"swapType": "FxSwap",
"version": 0,
"currencyPair": "EURUSD",
"direction": "Buy",
"notional": ["EUR", 1E6],
"nearStrike": 1.1,
"nearExpiry": 2025.12.08,
"nearDelivery": 2025.12.10,
"farStrike": 1.2,
"farExpiry": 2026.06.08,
"farDelivery": 2026.06.10
}
instrument = parseInstrument(swap)
getInstrumentFarStrike(instrument)
// output: 1.2
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_4491.md
# 函数分类
**URL**: https://docs.dolphindb.cn/zh/funcs/funcs_by_topics.html#funcs_by_topics_math_statis
**来源**: DolphinDB 官方文档
---
函数分类
DolphinDB 的函数按照功能可以分为以下类别:
数据操作
数据类型与转换:
array
,
arrayVector
,
bigarray
,
blob
,
bool
,
cast
,
ceil
,
char
,
complex
,
date
,
datehour
,
datetime
,
decimal32
,
decimal64
,
decimal128
,
decimalFormat
,
decimalMultiply
,
deg2rad
,
dict
,
double
,
duration
,
enlist
,
fixedLengthArrayVector
,
floor
,
form
,
format
,
fromJson
,
fromStdJson
,
hex
,
highDouble
,
highLong
,
indexedSeries
,
int
,
int128
,
ipaddr
,
isIndexedMatrix
,
isIndexedSeries
,
isOrderedDict
,
jsonExtract
,
long
,
lowDouble
,
lowLong
,
makeKey
,
makeSortedKey
,
matrix
,
minute
,
month
,
nanotime
,
nanotimestamp
,
pair
,
parseInt
,
parseInteger
,
parsejsonTable
,
point
,
rad2deg
,
reverse
,
round
,
second
,
seq
,
set
,
setIndexedMatrix!
,
setIndexedSeries!
,
short
,
string
,
subtuple
,
symbol
,
symbolCode
,
syncDict
,
temporalFormat
,
temporalParse
,
tensor
,
time
,
timestamp
,
toJson
,
toStdJson
,
transpose
/
flip
,
type
,
typestr
,
uuid
生成:
eye
,
panel
,
rollingPanel
,
seq
,
stretch
,
take
,
til
追加:
append!
/
push!
,
appendTuple!
,
memberModify!
删除、清理:
clear!
,
drop
,
dropna
,
erase!
,
pop!
,
removeHead!
,
removeTail!
查找:
at
,
binsrch
,
cell
,
cells
,
col
,
eachAt(@)
,
find
,
first
,
firstHit
,
firstNot
,
head
,
ifirstHit
,
ifirstNot
,
ilastNot
,
last
,
lastNot
,
loc
,
milastNot
,
row
,
searchK
,
slice
,
sliceByKey
,
subarray
,
tail
排序:
denseRank
,
isort
,
isort!
,
isortTop
,
isSorted
,
rank
,
sort
,
sort!
,
sortBy!
空值查找、填充:
bfill!
,
ffill
,
ffill!
,
fill!
,
hasNull
,
ifNull
,
ifValid
,
interpolate
,
isNanInf
,
isNothing
,
isNull
,
isValid
,
isVoid
,
lfill
,
lfill!
,
nanInfFill
,
nullFill
,
nullFill!
替换:
replace
,
replace!
移动:
lshift
,
move
,
next
,
nextState
,
prev
,
prevState
,
rshift
合并:
concatMatrix
,
join
,
join!
,
merge
,
union
,
unionAll
分割:
cut
过滤:
conditionalFilter
对齐:
align
展开、重组:
flatten
,
regroup
,
reshape
,
shuffle
,
shuffle!
,
ungroup
分组:
bar
,
bucket
,
cutPoints
,
dailyAlignedBar
,
digitize
,
groups
,
segment
,
volumeBar
加载:
loadNpy
,
loadNpz
,
loadRecord
,
loadTable
,
loadText
,
loadTextEx
,
ploadText
编码转换:
base64Decode
,
base64Encode
,
compress
,
decodeShortGenomeSeq
,
decompress
,
encodeShortGenomeSeq
,
genShortGenomeSeq
,
oneHot
,
pack
,
rdp
,
unpack
累积窗口:
cumavg
,
cumbeta
,
cumcorr
,
cumcount
,
cumcovar
,
cumfirstNot
,
cumlastNot
,
cummax
,
cummed
,
cummin
,
cumnunique
,
cumpercentile
,
cumPositiveStreak
,
cumprod
,
cumrank
,
cumstd
,
cumstdp
,
cumsum
,
cumsum2
,
cumsum3
,
cumsum4
,
cumvar
,
cumvarp
,
cumwavg
,
cumwsum
,
dynamicGroupCumsum
,
dynamicGroupCumcount
m 系列:
mavg
,
mbeta
,
mcorr
,
mcount
,
mcovar
,
mfirst
,
mfirstNot
,
mifirstNot
,
milastNot
,
mimax
,
mimin
,
mkurtosis
,
mlast
,
mlastNot
,
mLowRange
,
mmad
,
mmax
,
mmaxPositiveStreak
,
mmed
,
mmin
,
mmse
,
movingTopNIndex
,
movingWindowIndex
,
mpercentile
,
mprod
,
mrank
,
mskew
,
mslr
,
mstd
,
mstdp
,
msum
,
msum2
,
mTopRange
,
mvar
,
mvarp
,
mwavg
,
mwsum
tm 系列:
tmavg
,
tmbeta
,
tmcorr
,
tmcount
,
tmcovar
,
tmfirst
,
tmkurtosis
,
tmlast
,
tmLowRange
,
tmmax
,
tmmed
,
tmmin
,
tmpercentile
,
tmprod
,
tmrank
,
tmskew
,
tmstd
,
tmstdp
,
tmsum
,
tmsum2
,
tmTopRange
,
tmvar
,
tmvarp
,
tmwavg
,
tmwsum
mTopN:
mavgTopN
,
mbetaTopN
,
mcorrTopN
,
mcovarTopN
,
mpercentileTopN
,
mstdpTopN
,
mstdTopN
,
msumTopN
,
mvarpTopN
,
mvarTopN
,
mwsumTopN
,
row 系列:
rowAlign
,
rowAnd
,
rowAt
,
rowAvg
,
rowBeta
,
rowCorr
,
rowCount
,
rowCovar
,
rowDenseRank
,
rowDot
,
rowEuclidean
,
rowGmd5
,
rowImax
,
rowImin
,
rowKurtosis
,
rowMax
,
rowMin
,
rowMove
,
rowNext
,
rowOr
,
rowPrev
,
rowProd
,
rowRank
,
rowSize
,
rowSkew
,
rowStd
,
rowStdp
,
rowSum
,
rowSum2
,
rowTanimoto
,
rowVar
,
rowVarp
,
rowWavg
,
rowWsum
,
rowXor
TA-lib 系列:
dema
,
ema
,
gema
,
kama
,
linearTimeTrend
,
ma
,
sma
,
t3
,
tema
,
trima
,
wilder
,
wma
字符串:
charAt
,
concat
,
convertEncode
,
crc32
,
endsWith
,
fromUTF8
,
gmd5
,
ilike
,
initcap
,
isAlNum
,
isAlpha
,
isDigit
,
isLower
,
isNumeric
,
isSpace
,
isTitle
,
isUpper
,
left
,
like
,
lower
,
lpad
,
ltrim
,
md5
,
regexCount
,
regexFind
,
regexFindStr
,
regexReplace
,
repeat
,
right
,
rpad
,
rtrim
,
split
,
startsWith
,
stringFormat
,
strip
,
strlen
,
strlenu
,
strpos
,
strReplace
,
substr
,
substru
,
toCharArray
,
toUTF8
,
trim
,
upper
时间处理:
addMarketHoliday
,
asFreq
,
businessDay
,
businessMonthBegin
,
businessMonthEnd
,
businessQuarterBegin
,
businessQuarterEnd
,
businessYearBegin
,
businessYearEnd
,
concatDateTime
,
convertTZ
,
date
,
dayOfMonth
,
dayOfWeek
,
dayOfYear
,
daysInMonth
,
fy5253
,
fy5253Quarter
,
getMarketCalendar
,
gmtime
,
hour
,
hourOfDay
,
isLeapYear
,
isMonthEnd
,
isMonthStart
,
isQuarterEnd
,
isQuarterStart
,
isYearEnd
,
isYearStart
,
lastWeekOfMonth
,
listAllMarkets
,
localtime
,
microsecond
,
millisecond
,
minuteOfHour
,
month
,
monthBegin
,
monthEnd
,
monthOfYear
,
nanosecond
,
now
,
quarterBegin
,
quarterEnd
,
secondOfMinute
,
semiannualBegin
,
semiannualEnd
,
semiMonthBegin
,
semiMonthEnd
,
temporalAdd
,
temporalDeltas
,
temporalDiff
,
temporalSeq
,
today
,
transFreq
,
updateMarketHoliday
,
weekBegin
,
weekday
,
weekEnd
,
weekOfMonth
,
weekOfYear
,
year
,
yearBegin
,
yearEnd
数据库/数据表
库表操作:
addColumn
,
addFunctionView
,
addRangePartitions
,
addValuePartitions
,
backup
,
backupDB
,
backupTable
,
cacheDS!
,
cacheDSNow
,
cachedTable
,
checkBackup
,
clearAllTSDBSymbolBaseCache
,
clearDSCache!
,
clearDSCacheNow
,
columnNames
,
createDimensionTable
,
createDistributedInMemoryTable
,
createIPCInMemoryTable
,
createPartitionedTable
,
createTable
,
database
,
disableActivePartition
,
disableQueryMonitor
,
disableTSDBAsyncSorting
,
dropColumns!
,
dropDatabase
,
dropDistributedInMemoryTable
,
dropFunctionView
,
dropIPCInMemoryTable
,
dropPartition
,
dropTable
,
enableActivePartition
,
enableQueryMonitor
,
enableTSDBAsyncSorting
,
existsDatabase
,
existsPartition
,
existsTable
,
extractTextSchema
,
flushOLAPCache
,
flushTSDBCache
,
getAllDBGranularity
,
getAllDBs
,
getBackupList
,
getBackupMeta
,
getBackupStatus
,
getChunkPath
,
getChunksMeta
,
getClusterChunksStatus
,
getClusterDFSDatabases
,
getClusterDFSTables
,
getClusterVolumeUsage
,
getConfigure
/
getConfig
,
getDFSDatabases
,
getDFSDatabasesByOwner
,
getDFSTablesByDatabase
,
getFunctionViews
,
getLevelFileIndexCacheStatus
,
getLocalIOTDBStaticTable
,
getMemLimitOfQueryResult
,
getMemLimitOfTaskGroupResult
,
getOLAPCacheEngineSize
,
getOLAPCacheEngineStat
,
getOLAPCachedSymbolBaseMemSize
,
getPKEYCompactionTaskStatus
,
getPKEYMetaData
,
getRecoveryTaskStatus
,
getRecoveryWorkerNum
,
getRedoLogGCStat
,
getTables
,
getTablet
,
getTabletsMeta
,
getTransactionStatus
,
getTSDBCachedSymbolBaseMemSize
,
getTSDBCacheEngineSize
,
getTSDBCompactionTaskStatus
,
getTSDBMetaData
,
getUnresolvedTxn
,
imr
,
indexedTable
,
keyedTable
,
latestIndexedTable
,
latestKeyedStreamTable
,
latestKeyedTable
,
loadBackup
,
loadDistributedInMemoryTable
,
loadIPCInMemoryTable
,
loadMvccTable
,
loadTableBySQL
,
migrate
,
mr
,
multiTableRepartitionDS
,
mvccTable
,
purgeCacheEngine
,
rename!
,
renameTable
,
reorderColumns!
,
repartitionDS
,
replaceColumn!
,
replay
,
replayDS
,
resetRecoveryWorkerNum
,
restore
,
restoreDB
,
restoreTable
,
rowNames
,
rowNo
,
saveDatabase
,
saveDualPartition
,
savePartition
,
saveTable
,
schema
,
setAtomicLevel
,
setChunkLastUpdateTime
,
setColumnComment
,
setMaxBlockSizeForReservedMemory
,
setMaxConnections
,
setMaxMemSize
,
setMemLimitOfQueryResult
,
setMemLimitOfTaskGroupResult
,
setMemLimitOfTempResult
,
setOLAPCacheEngineSize
,
setReservedMemSize
,
setTableComment
,
setTSDBCacheEngineSize
,
sqlDS
,
table
,
tableInsert
,
tableUpsert
,
textChunkDS
,
transDS!
,
triggerTSDBCompaction
,
truncate
,
tupleSum
,
update!
,
upsert!
catalog相关操作:
createCatalog
,
createSchema
,
dropCatalog
,
dropSchema
,
existsCatalog
,
getAllCatalogs
,
getCurrentCatalog
,
getSchemaByCatalog
,
renameCatalog
,
renameSchema
,
setDefaultCatalog
集群操作:
addNode
,
addVolumes
,
cancelRecoveryTask
,
copyReplicas
,
deleteReplicas
,
getActiveMaster
,
getActiveMaster
,
getConnections
,
getDatabaseClusterReplicationStatus
,
getMasterReplicationStatus
,
getNodeAlias
,
getNodeHost
,
getNodePort
,
getNodeType
,
getRecentSlaveReplicationInfo
,
getSlaveReplicationStatus
,
getSlaveReplicationQueueStatus
,
isControllerInitialized
,
isDataNodeInitialized
,
moveChunksAcrossVolume
,
moveReplicas
,
pnodeRun
,
rebalanceChunksAmongDataNodes
,
rebalanceChunksWithinDataNode
,
remoteRun
,
remoteRunCompatible
,
remoteRunWithCompression
,
removeNode
,
resetDBDirMeta
,
restoreDislocatedTablet
,
resumeRecovery
,
rpc
,
setDatabaseForClusterReplication
,
setTimeoutTick
,
skipClusterReplicationTask
,
startClusterReplication
,
startDataNode
,
stopClusterReplication
,
stopDataNode
,
suspendRecovery
,
triggerNodeReport
,
xdb
多集群操作:
getAllClusters
,
getCatalogsByCluster
,
getClusterStatus
,
getDatabasesByCluster
,
getGroupAccessByCluster
,
getGroupListOfAllClusters
,
getSchemasByCluster
,
getTableAccessByCluster
,
getTablesByCluster
,
getTablesOfAllClusters
,
getTableSchemaByCluster
,
getUserAccessByCluster
,
getUserListOfAllClusters
,
listPluginsByCluster
计算组相关操作:
clearComputeNodeCache
,
clearComputeNodeDiskCache
,
flushComputeNodeMemCache
,
getComputeGroupChunksStatus
,
getComputeNodeCacheDetails
,
getComputeNodeCacheStat
,
getComputeNodeCacheWarmupJobStatus
,
getComputeNodeCachingDelay
,
getPrefetchComputeNodeData
,
setComputeNodeCachingDelay
,
setPrefetchComputeNodeData
,
warmupComputeNodeCache
SQL
关键字:
alter
,
any/all
,
between
,
case
,
cgroup by
,
coalesce
,
context by
,
create
,
delete
,
distinct
,
drop
,
exec
,
exists
,
group by
,
having
, [
HINT_EXPLAIN
],
in
,
insert into
,
interval
,
is null
,
like/LIKE
,
limit
,
map
,
notBetween/NOTBETWEEN
,
notIn/NOTIN
,
notLike/NOTLIKE
,
nullIf
,
order by
,
partition
,
pivot by
,
sample
,
select
,
SQL Trace
,
top
,
union/union all
,
unpivot
,
update
,
where
,
with
表连接:
aj
,
cj
,
ej
,
fj
(full join),
inner join
,
lj
(left join),
lsj
(left semi join),
pj
,
pwj
,
right join
,
sej
,
wj
状态查看:
getCompletedQueries
,
getQueryStatus
,
getRunningQueries
,
getTraces
,
setTraceMode
,
viewTraceInfo
数学和统计
数学:
abs
,
acos
,
acosh
,
add
,
asin
,
asinh
,
atan
,
atanh
,
cbrt
,
clip
,
clip!
,
cos
,
cosh
,
cholesky
,
derivative
,
diag
,
div
,
det
,
eig
,
exp
,
exp2
,
expm1
,
gram
,
gramSchmidt
,
integral
,
inverse
,
intersection
,
iterate
,
log
,
log1p
,
log2
,
log10
,
lu
,
mod
,
mul
,
neg
,
pow
,
ratio
,
reciprocal
,
repmat
,
sin
,
sinh
,
sqrt
,
square
,
sub
,
symmetricDifference
,
svd
,
tan
,
tanh
,
tril
,
triu
,
schur
,
signbit
,
signum
,
qr
统计:
atImax
,
atImin
,
avg
,
boxcox
,
contextSum
,
contextSum2
,
count
,
covar
,
covarMatrix
,
crossStat
,
cubicHermiteSplineFit
,
cumnunique
,
demean
,
dot
,
ewmCov
,
ewmMean
,
ewmStd
,
ewmVar
,
gaussianKde
,
gaussianKdePredict
,
imax
,
imin
,
kurtosis
,
mad
,
max
,
maxIgnoreNull
,
med
,
mean
,
min
,
minIgnoreNull
,
mode
,
mmed
,
nunique
,
percentChange
,
percentile
,
percentileRank
,
prod
,
quantile
,
quantileSeries
,
rms
,
sem
,
skew
,
std
,
stdp
,
summary
,
sum
,
sum2
,
sum3
,
sum4
,
stat
,
var
,
varp
,
wavg
,
wc
,
wcovar
,
wsum
,
histogram2d
,
kroghInterpolateFit
,
linearInterpolateFit
相关性:
acf
,
autocorr
,
corr
,
corrMatrix
,
distance
,
ewmCorr
,
euclidean
,
kendall
,
mutualInfo
,
rowEuclidean
,
rowTanimoto
,
spearmanr
,
tanimoto
序列分析:
isMonotonicIncreasing
/
isMonotonic
,
isMonotonicDecreasing
,
isPeak
,
isValley
,
zigzag
分布与假设检验:
adfuller
,
anova
,
cdfBeta
,
cdfBinomial
,
cdfChiSquare
,
cdfExp
,
cdfF
,
cdfGamma
,
cdfKolmogorov
,
cdfLogistic
,
cdfNormal
,
cdfPoisson
,
cdfStudent
,
cdfUniform
,
cdfWeibull
,
cdfZipf
,
chiSquareTest
,
coint
,
esd
,
fTest
,
invBeta
,
invBinomial
,
invChiSquare
,
invExp
,
invF
,
invGamma
,
invLogistic
,
invNormal
,
invStudent
,
invPoisson
,
invUniform
,
invWeibull
,
ksTest
,
mannWhitneyUTest
,
manova
,
norm
/
normal
,
rand
,
randBeta
,
randBinomial
,
randChiSquare
,
randDiscrete
,
randExp
,
randF
,
randGamma
,
randLogistic
,
randMultivariateNormal
,
randNormal
,
randPoisson
,
randStudent
,
randUniform
,
randWeibull
,
seasonalEsd
,
shapiroTest
,
tTest
,
zTest
数据处理:
all
,
any
,
asis
,
asof
,
bucketCount
,
coevent
,
cols
,
deepCopy
,
copy
,
contextCount
,
countNanInf
,
cumPositiveStreak
,
deltas
,
dictUpdate!
,
distinct
,
dynamicGroupCumcount
,
dynamicGroupCumsum
,
hashBucket
,
iif
,
imaxLast
,
iminLast
,
isDuplicated
,
keys
,
linearTimeTrend
,
lowerBound
,
lowRange
,
mask
,
maxPositiveStreak
,
mimaxLast
,
miminLast
,
mmaxPositiveStreak
,
pca
,
ratios
,
resample
,
rowImaxLast
,
rowIminLast
,
rows
,
sessionWindow
,
shape
,
size
,
stl
,
sumbars
,
talibNull
,
tmove
,
topRange
,
valueChanged
,
values
,
winsorize!
,
winsorize
,
zscore
,
differentialEvolution
插值:
cubicSpline
,
cubicSplinePredict
,
dividedDifference
,
kroghInterpolate
,
loess
,
neville
,
pchipInterpolateFit
,
spline
,
splrep
,
splev
优化:
brute
,
brentq
,
fmin
,
fminBFGS
,
fminLBFGSB
,
fminNCG
,
fminSLSQP
,
linprog
,
osqp
,
qclp
,
quadprog
,
scs
,
solve
,
socp
运算符
逻辑:
and
,
bitAnd
,
bitOr
,
bitXor
,
not
,
or
,
xor
关系:
between
,
eq
,
eqFloat
,
eqObj
,
eqPercent
,
ge
,
gt
,
in
,
le
,
lt
,
ne
流数据
流表操作:
appendForJoin
,
appendMsg
,
clearTablePersistence
,
disableTablePersistence
,
dropStreamTable
,
enableTableCachePurge
,
enableTablePersistence
,
enableTableShareAndCachePurge
,
enableTableShareAndPersistence
,
existsStreamTable
,
existsSubscriptionTopic
,
getStreamTables
,
haStreamTable
,
keyedStreamTable
,
removeTopicOffset
,
setStreamTableFilterColumn
,
setStreamTableTimestamp
,
share
,
subscribeTable
,
unsubscribeTable
,
streamTable
计算引擎:
createAnomalyDetectionEngine
,
createAsofJoinEngine
,
createCrossSectionalEngine
,
createDailyTimeSeriesEngine
,
createDualOwnershipReactiveStateEngine
,
createEquiJoinEngine
/
createEqualJoinEngine
,
createLeftSemiJoinEngine
,
createLookupJoinEngine
,
createNarrowReactiveStateEngine
,
createOrderBookSnapshotEngine
,
createReactiveStateEngine
,
createRuleEngine
,
createSessionWindowEngine
,
createSnapshotJoinEngine
,
createStreamDispatchEngine
,
createTimeBucketEngine
,
createTimeSeriesEngine
,
createWindowJoinEngine
,
streamEngineParser
,
createCryptoOrderBookEngine
工具函数:
addMetrics
,
addReactiveMetrics
,
conditionalIterate
,
dropStreamEngine
/
dropAggregator
,
getComputeNodeCacheWarmupJobStatus
,
forceTriggerOrderBookSnapshot
,
getLeftStream
/
getRightStream
,
getPersistenceMeta
,
getReactiveMetrics
,
getSnapshotMsgId
,
getStreamEngine
/
getAggregator
,
getStreamEngineList
,
getStreamEngineStat
/
getAggregatorStat
,
getRules
,
getStreamingLeader
,
getStreamingRaftGroups
,
getStreamingStat
,
getStreamTableCacheOffset
,
getStreamTableFilterColumn
,
getSubscriptionTopic
,
getTopicProcessedOffset
,
stateIterate
,
warmupComputeNodeCache
,
warmupStreamEngine
流式 SQL:
declareStreamingSQLTable
,
getStreamingSQLStatus
,
listStreamingSQLTables
,
registerStreamingSQL
,
revokeStreamingSQL
,
revokeStreamingSQLTable
,
subscribeStreamingSQL
,
unsubscribeStreamingSQL
元编程
binaryExpr
,
eval
,
expr
,
funcByName
,
makeCall
,
makeUnifiedCall
,
parseExpr
,
sql
,
sqlCol
,
sqlColAlias
,
sqlDelete
,
sqlUpdate
,
unifiedExpr
高阶函数
accumulate (:A)
,
aggrTopN
,
all
,
any
,
byColumn (:V)
,
byRow (:H)
,
call
,
compose
,
contextby (:X)
,
cross (:C)
/
pcross
,
each (:E)
,
eachLeft (:L)
,
eachPost (:O)
,
eachPre (:P)
,
eachRight (:R)
,
groupby (:G)
,
loop (:U)
/
ploop
,
moving
,
nullCompare
,
pcall
,
pivot
,
reduce (:T)
,
rolling
,
rowGroupby
,
segmentby
,
talib
,
tmoving
,
twindow
,
unifiedCall
,
window
,
withNullFill
金融分析
金融分析:
amortizingFixedRateBondDirtyPrice
,
arima
,
nss
,
ns
,
condValueAtRisk
,
convertibleFixedRateBondDirtyPrice
,
nssPredict
,
trueRange
,
valueAtRisk
,
irs
,
varma
,
bondCashflow
,
bondYield
,
floatingRateBondDirtyPrice
,
treasuryConversionFactor
,
crmwCBond
,
cds
,
vanillaOption
,
maxDrawdown
,
mdd
,
cummdd
FICC:
bondAccrInt
,
bondCalculator
,
bondInstrumentCalculator
,
bondConvexity
,
bondDirtyPrice
,
bondDuration
,
,
bondFuturesPricer
,
bondPricer
,
bondYieldCurveBuilder
,
curvePredict
,
fxEuropeanOptionPricer
,
fxForwardPricer
,
fxSwapPricer
,
fxVolatilitySurfaceBuilder
,
instrumentPricer
,
irCrossCurrencyCurveBuilder
,
irDepositPricer
,
irFixedFloatingSwapPricer
,
irSingleCurrencyCurveBuilder
,
optionVolPredict
,
portfolioPricer
FICC 工具:
extractInstrument
,
extractMktData
,
parseInstrument
,
parseMktData
,
getInstrumentCalendar
,
getInstrumentCoupon
,
getInstrumentCreditRating
,
getInstrumentCurrency
,
getInstrumentCurrencyPair
,
getInstrumentDayCountConvention
,
getInstrumentDelivery
,
getInstrumentDirection
,
getInstrumentExpiry
,
getInstrumentFarDelivery
,
getInstrumentFarExpiry
,
getInstrumentFarStrike
,
getInstrumentField
,
getInstrumentFixedDayCountConvention
,
getInstrumentFixedRate
,
getInstrumentFloatingDayCountConvention
,
getInstrumentFrequency
,
getInstrumentIborIndex
,
getInstrumentInstrumentId
,
getInstrumentIssuePrice
,
getInstrumentKeys
,
getInstrumentMaturity
,
getInstrumentNearDelivery
,
getInstrumentNearExpiry
,
getInstrumentNearStrike
,
getInstrumentNominal
,
getInstrumentNominalCouponRate
,
getInstrumentNotional
,
getInstrumentPayReceive
,
getInstrumentPayoffType
,
getInstrumentRate
,
getInstrumentSettlement
,
getInstrumentSpread
,
getInstrumentStart
,
getInstrumentStrike
,
getInstrumentSubType
,
getInstrumentUnderlying
机器学习
机器学习:
adaBoostClassifier
,
adaBoostRegressor
,
beta
,
bvls
,
elasticNet
,
elasticNetCV
,
gaussianNB
,
glm
,
gmm
,
kernelRidge
,
kmeans
,
knn
,
lasso
,
lassoBasic
,
lassoCV
,
logisticRegression
,
mmse
,
msl
,
multinomialNB
,
ols
,
olsEx
,
piecewiseLinFit
,
poly1d
,
polyPredict
,
polyFit
,
polynomial
,
predict
,
pwlfPredict
,
randomForestClassifier
,
randomForestRegressor
,
residual
,
ridge
,
ridgeBasic
,
vectorAR
,
wls
,
garch
文本处理:
loadVocab
,
tokenizeBert
,
unloadVocab
权限与安全
addAccessControl
,
addGroupMember
,
backupSettings
,
changePwd
,
createGroup
,
createUser
,
deleteGroup
,
deleteGroupMember
,
deleteUser
,
deny
,
getAuthenticatedUsers
,
getGroupAccess
,
getGroupList
,
getGroupsByUserId
,
getOauthClientSecret
,
getUserAccess
,
getUserList
,
getUsersByGroupId
,
grant
,
isLoggedIn
,
login
,
logout
,
resetPwd
,
restoreSettings
,
revoke
,
scramClientFinal
,
scramClientFirst
,
unlockUser
文件系统
cleanOutdateLogFiles
,
close
,
exists
,
fflush
,
file
,
files
,
loadModel
,
mkdir
,
read!
,
readBytes
,
readLine
,
readLines
,
readLines!
,
readObject
,
readRecord!
,
rm
,
rmdir
,
saveAsNpy
,
saveModel
,
saveText
,
saveTextFile
,
seek
,
write
,
writeBytes
,
writeLine
,
writeLines
,
writeLog
,
writeLogLevel
,
writeObject
,
writeRecord
系统管理
cancelConsoleJob
,
cancelJob
,
closeSessions
,
defined
,
defs
,
deleteScheduledJob
,
disableResourceTracking
,
dumpHeapSample
,
enableResourceTracking
,
evalTimer
,
getAclAuditlog
,
getAuditLog
,
getClusterPerf
,
getConsoleJobs
,
getCurrentSessionAndUser
,
getDatanodeRestartInterval
,
getDynamicConfig
,
getIPConnectionLimit
,
getJobMessage
,
getJobReturn
,
getJobStat
,
getJobStatus
,
getLicenseExpiration
,
getMachineFingerprint
,
getMemLimitOfAllTempResults
,
getPerf
,
getRecentJobs
,
getScheduledJobs
,
getSessionMemoryStat
,
getSupportBundle
,
getTSDBDataStat
,
getTSDBTableIndexCacheStatus
,
getUserHardwareUsage
,
getUserTableAccessRecords
,
imtForceGCRedolog
,
imtUpdateChunkVersionOnDataNode
,
installPlugin
,
license
,
listRemotePlugins
,
loadModule
,
loadModuleFromScript
,
loadPlugin
,
member
,
module
,
objByName
,
objs
,
partial
,
pipeline
,
refCount
,
saveModule
,
scheduleJob
,
setDatanodeRestartInterval
,
setDynamicConfig
,
,
setLogLevel
,
setMaxJobParallelism
,
setMaxJobPriority
,
setMemLimitOfAllTempResults
,
setRandomSeed
,
setRetentionPolicy
,
setSystem
,
startHeapSample
,
stopHeapSample
,
submitJob
,
submitJobEx
,
submitJobEx2
,
syntax
,
timer
,
undef
,
updateLicense
,
use
,
version
,
getLoadedPlugins
MCP
addMCPPrompt
,
addMCPTool
,
callMCPTool
,
dropMCPPrompt
,
dropMCPTool
,
getMCPPrompt
,
listMCPPrompts
,
listMCPTools
,
publishMCPPrompts
,
publishMCPTools
,
updateMCPPrompt
,
updateMCPTool
,
withdrawMCPPrompts
,
withdrawMCPTools
环境
clearAllCache
,
clearCachedModules
,
getDiskIOStat
,
getEnv
,
getHomeDir
,
getMemoryStat
,
getOS
,
getOSBit
,
getSystemCpuUsage
,
getSystemLoadAvg
,
mem
,
moveHotDataToColdVolume
,
shell
,
sleep
,
clearAllIOTDBStaticTableCache
,
clearAllIOTDBLatestKeyCache
其它
attributeNames
,
attributeValues
,
,
constantDesc
,
convertExcelFormula
,
hmac
,
genericStateIterate
,
genericTStateIterate
,
objectChecksum
,
plot
,
plotHist
,
snippet
FILE:references/doc_450.md
# haStreamTable
**URL**: https://docs.dolphindb.cn/zh/funcs/h/haStreamTable.html
**来源**: DolphinDB 官方文档
---
haStreamTable
语法
haStreamTable(raftGroup, table, tableName, cacheLimit, [keyColumn],
[retentionMinutes=1440])
详情
创建高可用流数据表。该函数只能在启用流数据高可用后使用。要启用流数据高可用,用户需要在集群配置文件 cluster.cfg
中指定配置参数
streamingHAMode
和
streamingRaftGroups
。系统启动时,配置参数
streamingRaftGroup
指定的数据节点/计算节点组成 Raft 组,一个数据节点/计算节点作为
Leader,其他数据节点/计算节点作为 Follower。Raft 组的每个数据节点/计算节点上都有流数据表的副本。
客户端只需订阅 Raft 组中任意一个数据节点/计算节点上的高可用流数据表,并启用订阅的自动重连功能,即把
reconnect
参数设置为 true。Leader 上的高可用流数据表会向客户端发布数据。如果 Raft 组中的 Leader
宕机,系统会选举出新的 Leader 继续发布数据,客户端会自动切换订阅到新的 Leader 上的高可用流数据表。
一个 Raft 组可以包含多个高可用流数据表。
参数
raftGroup
是一个大于1的整数,表示 Raft 组的 ID。
table
是一个表对象。它必须是一个由
table
函数创建的空表。
tableName
是一个字符串,表示高可用流数据表的名称。
cacheLimit
是一个整数,表示高可用流数据表在内存中最多保留多少行。如果
cacheLimit
是小于1000的正整数,它会被自动调整为1000。
keyColumn
可选参数,是一个字符串标量或向量,表示主键。
retentionMinutes
可选参数,是一个整数,表示保留大小超过 1GB 的 log
文件的时间(从文件的最后修改时间开始计算),单位是分钟。默认值是1440,即一天。
返回值
一张表。
例子
假设配置参数
streamingRaftGroup
=11:NODE1:NODE2:NODE3,在 Raft
组的任意一个节点如 NODE1 上执行以下脚本创建高可用流数据表 trades:
colNames = `timestamp`sym`qty`price
colTypes = [TIMESTAMP,SYMBOL,INT,DOUBLE]
t=table(1:0,colNames,colTypes)
haStreamTable(11,t,`trades,100000);
在集群的另外一个节点 NODE4 上执行以下脚本订阅表 trades,把订阅的数据保存至分布式数据库中。
if(existsDatabase("dfs://stock")){
dropDatabase("dfs://stock")
}
db=database(directory="dfs://stock",partitionType=VALUE,partitionScheme=2018.08.01..2019.12.30)
t=table(1:0,`timestamp`sym`qty`price,[TIMESTAMP,SYMBOL,INT,DOUBLE])
trades_slave=db.createPartitionedTable(table=t,tableName=`trades_slave,partitionColumns=`timestamp);
subscribeTable(server=NODE2,tableName=`trades,actionName=`sub_trades,offset=-1,handler=append!{trades_slave},msgAsTable=true,batchSize=1000,throttle=1,hash=-1,reconnect=true);
// 这里subscribeTable函数的第一个参数可以是NODE1,NODE2,NODE3中的任意一个,reconnect参数必须为true。
在 NODE4 上执行以下脚本取消订阅:
unsubscribeTable(server=NODE2,tableName=`trades,actionName=`sub_trades);
// 这里unsubscribeTable函数的第一个参数可以是 NODE1, NODE2, NODE3 中的任意一个。
相关函数:
dropStreamTable
,
getStreamingLeader
,
getStreamingRaftGroups
FILE:references/doc_4500.md
# gramSchmidt
**URL**: https://docs.dolphindb.cn/zh/funcs/g/gramSchmidt.html
**来源**: DolphinDB 官方文档
---
gramSchmidt
语法
gramSchmidt(X, [normalize = false])
详情
将列满秩矩阵转换为一个列向量正交的矩阵。
参数
X
一个列满秩矩阵(每个列向量均线性无关),且不能包含空值。
normalize
可选参数,一个布尔值,表示是否输出标准正交矩阵,默认值为 false。
返回值
DOUBLE 类型矩阵。
例子
x = matrix([2 3 5, 3 6 2, 8 3 6]);
gramSchmidt(x)
// output
col1 col2 col3
2.0000 1.2105 4.7932
3.0000 3.3157 -2.1968
5.0000 -2.4736 -0.5991
// 指定 normalize=true,则输出标准正交矩阵。
gramSchmidt(x, true)
// output
col1 col2 col3
0.3244 0.2808 0.9033
0.4867 0.7693 -0.414
0.8111 -0.5739 -0.1129
// 矩阵的列向量线性相关时,则会报错
x = matrix([1 4, 2 5, 3 6]);
gramSchmidt(x)
// output
vector set must be linearly independent
FILE:references/doc_4508.md
# mask
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mask.html
**来源**: DolphinDB 官方文档
---
mask
语法
mask(X, Y)
详情
对
X
中每个元素应用条件
Y
。若结果为 false,保留该元素。若结果为 true,将其替换为
NULL。
参数
X
是一个标量、向量或矩阵。
Y
是一个布尔表达式。
返回值
返回一个长度与
X
相同的对象。
例子
x=1..10
mask(x, x>6);
// output: [1,2,3,4,5,6,,,,]
m=matrix(1 2 3, 4 5 6, 7 8 9);
m;
#0
#1
#2
1
4
7
2
5
8
3
6
9
mask(m, m<6);
#0
#1
#2
7
8
6
9
FILE:references/doc_4511.md
# find
**URL**: https://docs.dolphindb.cn/zh/funcs/f/find.html
**来源**: DolphinDB 官方文档
---
find
语法
find(X, Y)
详情
若
X
是向量,对
Y
中每一个元素,返回其第一次出现在
X
中的位置;如果没有在X中出现,返回 -1。若要查找所有出现的位置,可使用
at
函数
。
若
X
是字典,对
Y
中每一个元素,若其为
X
的键,返回
X
中对应的值;若不是
X
的键,返回 NULL。
若
X
是单列内存表,对
Y
中每一个元素,返回其第一次出现在
X
的唯一列中的位置;如果没有在
X
的唯一列中出现,返回-1。
注意:表中单列的类型不能是
Array Vector。
若
X
是键值内存表或索引内存表,对
Y
中每一个元素,返回其第一次出现在
X
的主键中的位置; 如果没有在
X
的主键中出现,返回 -1。
通过
find
函数,用一个大向量搜索另一个大向量时,系统将建立一个字典,用以优化性能。但如果只是用几个值搜索一个向量,系统可能不会为了优化性能建立字典。是否建立字典是动态决定的。如果需要在已经排序的向量中搜索少量数据,我们推荐使用
binsrch
函数。
参数
X
可以是向量、字典、单列内存表、键值表或者索引内存表。
Y
可以是标量、向量、
数组向量、
元组、字典、矩阵、表。
返回值
当
X
为向量、单列内存表、键值表或者索引内存表时,返回值为整型标量或向量。
当
X
为字典时,返回值类型与 X 中对应值的类型一致。
例子
X
是向量:
find(7 3 3 5, 3);
// output
1
at(7 3 3 5 == 3);
// output
[1,2]
(7 3 3 5 6).find(2 4 5);
// output
[-1,-1,3]
X
是字典:
z=dict(1 2 3,4.5 6.6 3.2);
z;
// output
3->3.2
1->4.5
2->6.6
find(z,3);
// output
3.2
find(z,5);
// output
00F
X
是单列内存表:
t = table(1 3 5 7 9 as id)
find(t, 2 3)
// output
[-1,1]
X
是键值表或者索引内存表:
kt = keyedTable(`name`id,1000:0,`name`id`age`department,[STRING,INT,INT,STRING])
insert into kt values(`Tom`Sam`Cindy`Emma`Nick, 1 2 3 4 5, 30 35 32 25 30, `IT`Finance`HR`HR`IT)
find(kt,(`Emma`Sam, 4 1));
// output
[3,-1]
t1 = indexedTable(`sym`side, 10000:0, `sym`side`price`qty, [SYMBOL,CHAR,DOUBLE,INT])
insert into t1 values(`IBM`MSFT`GOOG, ['B','S','B'], 10.01 10.02 10.03, 10 10 20)
find(t1, (`GOOG`MSFT, ['B','S']))
// output
[2,1]
FILE:references/doc_452.md
# tmwavg
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmwavg.html
**来源**: DolphinDB 官方文档
---
tmwavg
语法
tmwavg(T, X, Y, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间长度衡量)的滑动窗口内,以
Y
为权重(权重会自动缩放,使其元素之和为1),计算
X
元素的加权平均。
返回值
DOUBLE 类型向量。
例子
T= 1 1 1 1 2 5 6 8 9 10
X = 1..10
Y = double(1..10)\10
m = table(T as t,X as x, Y as y)
select *, tmwavg(t, x, y, 3) from m
t
x
y
tmwavg_t
1
1
0.1
1
1
2
0.2
1.6667
1
3
0.3
2.3333
1
4
0.4
3
2
5
0.5
3.6667
5
6
0.6
6
6
7
0.7
6.5385
8
8
0.8
7.5333
9
9
0.9
8.5294
10
10
1
9.0741
T = 2021.01.02 2021.01.06 join 2021.01.07..2021.01.14
X = 1..10
Y = double(1..10)\10
m=table(T as t,X as x, Y as y)
select *, tmwavg(t, y, x, 3) from m
t
x
y
tmwavg_t
2021.01.02
1
0.1
0.1
2021.01.06
2
0.2
0.2
2021.01.07
3
0.3
0.26
2021.01.08
4
0.4
0.3222
2021.01.09
5
0.5
0.4167
2021.01.10
6
0.6
0.5133
2021.01.11
7
0.7
0.6111
2021.01.12
8
0.8
0.7095
2021.01.13
9
0.9
0.8083
2021.01.14
10
1
0.9074
select *, tmwavg(t, y, x, 1w) from m
t
x
y
tmwavg_t
2021.01.02
1
0.1
0.1
2021.01.06
2
0.2
0.1667
2021.01.07
3
0.3
0.2333
2021.01.08
4
0.4
0.3
2021.01.09
5
0.5
0.3857
2021.01.10
6
0.6
0.45
2021.01.11
7
0.7
0.5148
2021.01.12
8
0.8
0.58
2021.01.13
9
0.9
0.6667
2021.01.14
10
1
0.7571
相关函数:
wavg
,
mwavg
FILE:references/doc_4521.md
# rowDot
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowDot.html
**来源**: DolphinDB 官方文档
---
rowDot
语法
rowDot(X, Y)
详情
若
X
和
Y
同时为向量/矩阵,按行计算
X
和
Y
的内积。若
X
和
Y
同时为索引矩阵,会对齐标签,对标签相同的行进行计算,标签不同的行直接返回 NULL。
若
X
和
Y
一个为向量,一个为矩阵,则向量的长度必须与矩阵的列数相同,计算向量与矩阵每一行的内积。
若
X
和
Y
是数组向量,计算
X
和
Y
对应位置的向量的内积,即 dot(X.row(i),Y.row(i))。
若
X
和
Y
一个为向量,一个为数组向量,计算向量与数组向量内每个向量的内积。两个向量的长度相同时返回计算结果,长度不相同时返回 NULL。
与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
和
Y
是长度相同的数值型向量或数组向量,或维度相同的矩阵。若
X
和
Y
为数组向量,它们对应位置的向量必须具有相同长度。
返回值
一个向量。
例子
rowDot(13.5 15.2 6.3, 18.6 14.8 15.5)
// output
[251.1,224.96,97.65]
s1=indexedSeries(2020.01.01..2020.01.03, 10.4 11.2 9)
s2=indexedSeries(2020.01.01 2020.01.03 2020.01.04, 23.5 31.2 26)
rowDot(s1,s2)
// output
[244.4,349.44,234]
m=matrix(23 56 47, 112 94 59)
m1=matrix(11 15 89, 52 41 63)
rowDot(m,m1)
// output
[6077,4694,7900]
m.rename!(2020.01.01..2020.01.03, `A`B)
m.setIndexedMatrix!()
m1.rename!(2020.01.01 2020.01.03 2020.01.04, `A`B)
m1.setIndexedMatrix!()
rowDot(m,m1)
// output
[6077,NULL,3124,NULL]
a=array(DOUBLE[],0,10)
a.append!([[10.5, 11.8, 9],[15, NULL], [2.5, 2.2, 1.3, 1.5]])
b=array(DOUBLE[],0,10)
b.append!([[1.1, 1.8, 6],[5, 6.9], [3.5, 2, 3, 2.8]])
rowDot(a,b)
// output
[86.79,75,21.25]
相关函数:
dot
FILE:references/doc_4535.md
# getStreamEngineStat
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getStreamEngineStat.html
**来源**: DolphinDB 官方文档
---
getStreamEngineStat
语法
getStreamEngineStat()
别名:
getAggregatorStat
详情
查询流数据引擎的状态。
参数
无
返回值
返回一个字典,包含以下表:
表 TimeSeriesEngine 返回时间序列引擎的状态。它包含以下列:
列名
含义
name
时间序列引擎的名称
user
创建时间序列引擎的用户名
status
时间序列引擎的状态,"OK"表示可用,"FATAL"表示不可用
lastErrMsg
最后一条错误信息
windowTime
窗口的长度
step
计算的时间间隔
useSystemTime
时间序列引擎中 useSystemTime 参数值
garbageSize
触发内存清理的阈值
numGroups
时间序列引擎中的分组数
numRows
时间序列引擎中的记录行数
numMetrics
时间序列引擎使用的聚合指标的数量
metrics
时间序列引擎使用的聚合指标的元代码
memoryUsed
时间序列引擎所占用内存量,单位为字节
snapshotDir
保存引擎快照的文件目录
snapshotInterval
每隔多少条数据保存一次引擎快照
snapshotMsgId
最后一个 snapshot 的 msgId
snapshotTimestamp
引擎快照的时间戳
表 CrossSectionalEngine 返回横截面聚合引擎的状态。它包含以下列:
列名
含义
name
横截面引擎的名称
user
创建横截面引擎的用户名
status
横截面引擎的状态,"OK" 表示可用,"FATAL" 表示不可用
lastErrMsg
最后一条错误信息
numRows
横截面引擎中的记录行数
numMetrics
横截面引擎使用的聚合指标的数量
metrics
横截面引擎使用的聚合指标的元代码
triggeringPattern
横截面引擎触发计算的方式
triggeringInterval
横截面引擎触发计算的时间间隔
memoryUsed
横截面引擎所占用内存量,单位为字节
表 AnomalyDetectionEngine 返回异常检测引擎的状态。它包含以下列:
列名
含义
name
异常检测引擎的名称
user
创建异常检测引擎的用户名
status
异常检测引擎的状态,"OK" 表示可用,"FATAL" 表示不可用
lastErrMsg
最后一条错误信息
numGroups
异常检测引擎中的分组数
numRows
异常检测引擎中的记录行数
numMetrics
异常指标的数量
metrics
异常指标的元代码
snapshotDir
保存引擎快照的文件目录
snapshotInterval
每隔多少条数据保存一次引擎快照
snapshotMsgId
最后一个 snapshot 的 msgId
snapshotTimestam
引擎快照的时间戳
garbageSize
触发内存清理的阈值
memoryUsed
异常检测引擎所占用内存量,单位为字节
表 ReactiveStreamEngine 返回响应式状态引擎的状态。它包含以下列:
列名
含义
name
响应式状态引擎的名称
user
创建响应式状态引擎的用户名
status
响应式状态引擎的状态,"OK" 表示可用,"FATAL" 表示不可用
lastErrMsg
最后一条错误信息
numGroups
响应式状态引擎中的分组数
numRows
响应式状态引擎中的记录行数
numMetrics
指标的数量
memoryInUsed
响应式状态引擎所占用内存量,单位为字节
snapshotDir
保存引擎快照的文件目录
snapshotInterval
每隔多少条数据保存一次引擎快照
snapshotMsgId
最后一个 snapshot 的 msgId
snapshotTimestamp
引擎快照的时间戳
表 SessionWindowEngine 返回会话窗口引擎的状态。它包含以下列:
列名
含义
name
会话窗口引擎的名称
user
创建会话窗口引擎的用户名
status
会话窗口引擎的状态,"OK" 表示可用,"FATAL" 表示不可用
lastErrMsg
最后一条错误信息
sessionGap
每个会话窗口之间的时间间隔
useSystemTime
会话窗口聚合引擎计算的触发方式
numGroups
会话窗口引擎中的分组数
numRows
会话窗口引擎中的记录行数
numMetrics
指标的数量
Metrics
会话窗口聚合引擎使用的聚合指标的元代码
memoryUsed
会话窗口引擎所占用内存量,单位为字节
snapshotDir
会话窗口引擎快照保存的文件目录
snapshotInterval
每隔多少条数据保存一次引擎快照
snapshotMsgId
最后一个 snapshot 的 msgId
snapshotTimestamp
触发保存快照的时间戳
表 DailyTimeSeriesEngine 返回日级时间序列引擎的状态。它包含以下列:
列名
含义
name
日级时间序列引擎的名称
user
创建日级时间序列引擎的用户名
status
日级时间序列引擎的状态,"OK" 表示可用,"FATAL" 表示不可用
lastErrMsg
最后一条错误信息
windowTime
数据窗口的长度
step
计算的时间间隔
useSystemTime
日级时间序列引擎中 useSystemTime 参数值
garbageSize
触发内存清理的阈值
numGroups
日级时间序列引擎中的分组数
numRows
日级时间序列引擎中的记录行数
numMetrics
日级时间序列引擎使用的聚合指标的数量
metrics
日级时间序列引擎使用的聚合指标的元代码
memoryUsed
日级时间序列引擎所占用内存量,单位为字节
snapshotDir
日级时间序列聚合引擎快照保存的文件目录
snapshotInterval
每隔多少条数据保存一次引擎快照
snapshotMsgId
最后一个 snapshot 的 msgId
snapshotTimestamp
触发保存快照的时间戳
表 TimeBucketEngine 返回时间序列分组引擎的状态。它包含以下列:
列名
含义
name
时间序列分组引擎的名称
user
创建时间序列分组引擎的用户名
status
时间序列分组引擎的状态,"OK"表示可用,"FATAL"表示不可用
lastErrMsg
最后一条错误信息
numGroups
时间序列分组引擎中的分组数
numRows
时间序列分组引擎中的记录行数
numMetrics
时间序列分组引擎使用的聚合指标的数量
metrics
时间序列分组引擎使用的聚合指标的元代码
memoryUsed
时间序列分组引擎所占用内存量,单位为字节
表 AsofJoinEngine 返回 asof join 引擎的状态。它包含以下列:
列名
含义
name
asof join 引擎的名称
user
创建 asof join 引擎的用户名
status
asof join 引擎的状态,"OK" 表示可用,"FATAL" 表示不可用
lastErrMsg
最后一条错误信息
useSystemTime
asof join 引擎中 useSystemTime 参数值
delayedTime
asof join 引擎中 delayedTime 参数值
garbageSize
触发内存清理的阈值
leftTableNumRows
asof join 引擎左表中的记录行数
rightTableNumRows
asof join 引擎右表中的记录行数
numMetrics
asof join 引擎使用的指标的数量
metrics
asof join 引擎使用的指标的元代码
memoryUsed
asof join 引擎所占用内存量,单位为字节
表 EqualJoinEngine 返回等值连接引擎的状态。它包含以下列:
列名
含义
name
等值连接引擎的名称
user
创建等值连接引擎的用户名
status
等值连接引擎的状态,"OK" 表示可用,"FATAL" 表示不可用
lastErrMsg
最后一条错误信息
garbageSize
触发内存清理的阈值
leftTableNumRows
等值连接引擎左表中的记录行数
rightTableNumRows
等值连接引擎右表中的记录行数
numMetrics
等值连接引擎使用的指标的数量
metrics
等值连接引擎使用的指标的元代码
memoryUsed
等值连接引擎所占用内存量,单位为字节
表 WindowJoinEngine 返回 window join 引擎的状态。它包含以下列:
列名
含义
name
window join 引擎的名称
user
创建 window join 引擎的用户名
status
window join 引擎的状态,"OK" 表示可用,"FATAL"
表示不可用
lastErrMsg
最后一条错误信息
garbageSize
触发内存清理的阈值
leftTableNumRows
window join 引擎左表中的记录行数
rightTableNumRows
window join 引擎右表中的记录行数
numMetrics
window join 引擎使用的指标的数量
metrics
window join 引擎使用的指标的元代码
memoryUsed
window join 引擎所占用内存量,单位为字节
numGroups
window join 引擎中的分组个数。
表 LookupJoinEngine 返回 lookup join 引擎的状态。它包含以下列:
列名
含义
name
lookup join 引擎的名称
user
创建 lookup join 引擎的用户名
status
lookup join 引擎的状态,"OK" 表示可用,"FATAL" 表示不可用
lastErrMsg
最后一条错误信息
leftTableNumRows
lookup join 引擎左表中的记录行数
rightTableNumRows
lookup join 引擎右表中的记录行数
numMetrics
lookup join 引擎使用的指标的数量
metrics
lookup join 引擎使用的指标的元代码
memoryUsed
lookup join 引擎所占用内存量,单位为字节
表 LeftSemiJoinEngine 返回左半等值连接引擎的状态。它包含以下列:
列名
含义
name
左半等值连接引擎的名称
user
创建左半等值连接引擎的用户名
status
左半等值连接引擎的状态,"OK" 表示可用,"FATAL" 表示不可用
lastErrMsg
最后一条错误信息
garbageSize
触发内存清理的阈值
leftTableNumRows
左半等值连接引擎左表中的记录行数
rightTableNumRows
左半等值连接引擎右表中的记录行数
numMetrics
左半等值连接引擎使用的指标的数量
metrics
左半等值连接引擎使用的指标的元代码
memoryUsed
左半等值连接引擎所占用内存量,单位为字节
表 StreamFilter 返回流数据过滤引擎的状态。它包含以下列:
列名
含义
name
流数据过滤引擎的名称
user
创建流数据过滤引擎的用户名
status
流数据过滤引擎的状态,"OK" 表示可用,"FATAL" 表示不可用
lastErrMsg
最后一条错误信息
numRows
流数据过滤引擎中的记录行数
filters
流数据过滤引擎的过滤条件
表 StreamDispatchEngine 返回流数据分发引擎的状态。它包含以下列:
列名
含义
name
分发引擎的名称
user
创建分发引擎的用户名
status
分发引擎的状态,”OK”表示可用,”FATAL”表示不可用
lastErrMsg
最后一条错误信息
numRows
分发引擎中的记录行数
memoryUsed
分发引擎所占用内存量,单位为字节
表 ReactiveStateEngine 返回响应式状态引擎的状态。它包含以下列:
列名
含义
name
响应式状态引擎的名称
metrics
响应式状态引擎使用的计算公式的元代码
dummyTable
表对象,可以含有数据,亦可为空表
outputTable
计算结果的输出表,可以是内存表或分布式表
keyColumn
分组列名
filter
过滤条件的元代码
snapshotDir
保存引擎快照的文件目录
snapshotIntervalInMsgCount
每隔多少条数据保存一次流数据引擎快照
keepOrder
输出表数据是否按照输入时的顺序排序
keyPurgeFilter
清理条件的元代码
keyPurgeFreqInSecond
触发数据清理需要满足的时间间隔(以秒为单位)
raftGroup
流数据高可用订阅端 raft 组的 ID
outputElapsedMicroseconds
是否输出每个 batch 中数据从注入引擎到计算输出的总耗时,以及每个 batch
包含的总记录数
keyCapacity
建表时系统为该表预分配的 key 分组数量
parallelism
并行计算的工作线程数
表 DualOwnershipReactiveStateEngine 返回 Dual Ownership Reactive State Engine
的状态。它包含以下列:
列名
含义
name
Dual Ownership Reactive State Engine 的名称
metrics
Dual Ownership Reactive State Engine
使用的计算公式的元代码
dummyTable
表对象,可以含有数据,亦可为空表
outputTable
计算结果的输出表,可以是内存表或分布式表
keyColumn
分组列名
filter
过滤条件的元代码
snapshotDir
保存引擎快照的文件目录
snapshotIntervalInMsgCount
每隔多少条数据保存一次流数据引擎快照
keepOrder
输出表数据是否按照输入时的顺序排序
keyPurgeFilter
清理条件的元代码
keyPurgeFreqInSecond
触发数据清理需要满足的时间间隔(以秒为单位)
raftGroup
流数据高可用订阅端 raft 组的 ID
outputElapsedMicroseconds
是否输出每个 batch 中数据从注入引擎到计算输出的总耗时,以及每个 batch
包含的总记录数
keyCapacity
建表时系统为该表预分配的 key 分组数量
parallelism
并行计算的工作线程数
表 NarrowReactiveStateEngine 返回生成窄表的响应式状态引擎的状态。它包含以下列:
列名
含义
name
生成窄表的响应式状态引擎的名称
metrics
需要输出到
outputTable
中的除
keyColumn
外的输入表中的列或计算指标,用元代码表示
metricNames
输出到
outputTable
中的指标的名称
dummyTable
表对象,可以含有数据,亦可为空表
outputTable
计算结果的输出表,可以是内存表或分布式表
keyColumn
分组列名
filter
过滤条件的元代码
keepOrder
输出表数据是否按照输入时的顺序排序
keyPurgeFilter
清理条件的元代码
keyPurgeFreqInSecond
触发数据清理需要满足的时间间隔(以秒为单位)
outputElapsedMicroseconds
是否输出每个 batch 中数据从注入引擎到计算输出的总耗时,以及每个 batch
包含的总记录数
keyCapacity
建表时系统为该表预分配的 key 分组数量
parallelism
并行计算的工作线程数
表 SnapshotJoinEngine 返回快照连接引擎的状态。它包含以下列:
列名
含义
name
快照连接引擎的名称
user
创建快照连接引擎的用户名
status
快照连接引擎的状态,"OK" 表示可用,"FATAL" 表示不可用
lastErrMsg
最后一条错误信息
leftTableNumRows
快照连接引擎左表中的记录行数
rightTableNumRows
快照连接引擎右表中的记录行数
numMetrics
快照连接引擎使用的指标的数量
metrics
快照连接引擎使用的指标的元代码
memoryUsed
快照连接引擎所占用内存量,单位为字节
例子
share streamTable(10:0,`time`sym`price`qty,[TIMESTAMP,SYMBOL,DOUBLE,INT]) as trades
outputTable1 = table(10000:0, `time`sym`sumQty, [TIMESTAMP, SYMBOL, INT])
outputTable2 = table(1:0, `time`avgPrice`sumqty`Total, [TIMESTAMP,DOUBLE,INT,DOUBLE])
tradesTsAggregator = createTimeSeriesEngine(name="TimeSeriesDemo", windowSize=3, step=3, metrics=<[sum(qty)]>, dummyTable=trades, outputTable=outputTable1, timeColumn=`time, keyColumn=`sym, garbageSize=50)
tradesCsAggregator=createCrossSectionalEngine(name="CrossSectionalDemo", metrics=<[avg(price), sum(qty), sum(price*qty)]>, dummyTable=trades, outputTable=outputTable2, keyColumn=`sym, triggeringPattern=`perRow)
subscribeTable(tableName="trades", actionName="tradesTsAggregator", offset=0, handler=append!{tradesTsAggregator}, msgAsTable=true)
subscribeTable(tableName="trades", actionName="tradesCsAggregator", offset=0, handler=append!{tradesCsAggregator}, msgAsTable=true)
def writeData(n){
timev = 2000.10.08T01:01:01.001 + timestamp(1..n)
symv =take(`A`B, n)
pricev=take(102.1 33.4 73.6 223,n)
qtyv = take(60 74 82 59, n)
insert into trades values(timev, symv, pricev,qtyv)
}
writeData(4);
getStreamEngineStat().TimeSeriesEngine;
getStreamEngineStat().CrossSectionalEngine;
FILE:references/doc_454.md
# monthEnd
**URL**: https://docs.dolphindb.cn/zh/funcs/m/monthEnd.html
**来源**: DolphinDB 官方文档
---
monthEnd
语法
monthEnd(X, [offset], [n=1])
详情
返回
X
所在月份的最后一天。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
月更新一次。注意,
offset
和
n
须同时指定,且只有当
n
> 1 时,
offset
才会生效。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP 类型的标量、向量或表。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
monthEnd(2016.12.06);
// output
2016.12.31
date=2016.04.12 2016.04.25 2016.05.12 2016.06.28 2016.07.10 2016.07.18 2016.08.02 2016.08.16 2016.09.26 2016.09.30
time = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12,09:38:13]
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
select avg(price),sum(qty) from t1 group by monthEnd(date,2016.01.01,2);
monthEnd_date
avg_price
sum_qty
2016.05.31
36.193333
6200
2016.07.31
126.74
15400
2016.09.30
51.1875
17100
相关函数:
monthBegin
,
businessMonthBegin
,
businessMonthEnd
,
semiMonthBegin
,
semiMonthEnd
FILE:references/doc_4544.md
# milastNot
**URL**: https://docs.dolphindb.cn/zh/funcs/m/milastNot.html
**来源**: DolphinDB 官方文档
---
milastNot
语法
milastNot(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
的最后一个非空元素的下标。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
当
X
是向量时,返回一个向量。
当
X
是矩阵时,返回一个矩阵。
当
X
是表时,对表的每列进行计算,返回相应的结果。
当
X
是元组时,对元组中的每个向量分别计算,返回相应的结果。
例子
v = NULL NULL 2 3 4 8 NULL 5 -2 3 -1 0 NULL
milastNot(v, 3)
// output: [,,2,2,2,2,1,2,2,2,2,2,1]
m = matrix(1 2 3 NULL, 1 2 NULL 3, 1 3 NULL NULL, 1 2 3 4)
milastNot(m, 2)
#0
#1
#2
#3
1
1
1
1
1
0
0
1
0
1
-1
1
T = [2022.01.01, 2022.01.02, 2022.01.03, 2022.01.06, 2022.01.07]
X = NULL 2 NULL 4 5
X1 = indexedSeries(T, X)
milastNot(X1, 2, 1)
#0
2022.01.01
-1
2022.01.02
1
2022.01.03
0
2022.01.06
0
2022.01.07
1
FILE:references/doc_4564.md
# cdfLogistic
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfLogistic.html
**来源**: DolphinDB 官方文档
---
cdfLogistic
语法
cdfLogistic(mean, s, X)
详情
返回 Logistic 分布的累计密度函数的值。
参数
mean
是 Logistic 分布的均值。
s
是 Logistic 分布的尺度参数。
X
是数值型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfLogistic( 2.31, 0.627, [0.5, 0.3, 0.5, 0.7, 0.1]);
输出返回:[0.052812, 0.03895, 0.052812, 0.071241, 0.028617]
FILE:references/doc_4570.md
# fixedLengthArrayVector
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fixedLengthArrayVector.html
**来源**: DolphinDB 官方文档
---
fixedLengthArrayVector
语法
fixedLengthArrayVector(args…)
详情
将向量、矩阵或表拼接为一个数组向量。其拼接方式如下图所示(对应例1),输出的数组向量每一行(每个数组元素)的长度相等,等于所有输入数据列数的总和:
注:
向量的长度(元组中每个向量的长度)、矩阵、表的行数必须相同。
参数
args
可以是一个或多个向量/固定长度数组向量/元组/矩阵或表。
args
的每个元素必须具有相同的数据类型,且必须是数组向量支持的类型。
返回值
一个数组向量。
例子
例1. 图例代码
vec = 1 5 3
tp = [3 4 5, 4 5 6]
m = matrix(5 0 7, 7 6 9, 1 9 0)
tb = table(6 9 4 as v1, 1 4 3 as v2)
f = fixedLengthArrayVector(vec, tp, m, tb)
f;
[[1,3,4,5,7,1,6,1],[5,4,5,0,6,9,9,4],[3,5,6,7,9,0,4,3]]
typestr(f);
// output
FAST INT[] VECTOR
例2. 将多列合并成一列
下例简单示意了将 2 档 bid 报价存储为数组向量的例子。
login("admin","123456")
syms="A"+string(1..30)
datetimes=2019.01.01T00:00:00..2019.01.31T23:59:59
n=200
if(existsDatabase("dfs://stock")) {
dropDatabase("dfs://stock")
}
db=database("dfs://stock", RANGE, cutPoints(syms,3), engine="TSDB");
t=table(take(datetimes,n) as trade_time, take(syms,n) as sym,take(500+rand(10.0,n), n) as bid1, take(500+rand(20.0,n),n) as bid2)
t1=select trade_time, sym, fixedLengthArrayVector(bid1,bid2) as bid from t
quotes=db.createPartitionedTable(t1,`quotes,`sym, sortColumns=`sym`trade_time).append!(t1)
select * from quotes
trade_time
sym
bid
2019.01.01T00:00:00
A1
[503.111142,507.55833]
2019.01.01T00:00:30
A1
[502.991382,501.734092]
2019.01.01T00:01:00
A1
[500.790709,509.200963]
2019.01.01T00:01:30
A1
[501.127932,507.972508]
2019.01.01T00:02:00
A1
[500.678614,514.947117]
通过索引可以取出单档 bid 的数据,单独进行计算。对 bid 列应用函数计算,相当于将所有档的 bid 数据一起计算。
select avg(bid[0]) as avg_bid1, avg(bid[1]) as avg_bid2, avg(bid) as avg_bid from quotes
avg_bid1
avg_bid2
avg_bid
505.0263
509.2912
507.16
现实场景下,可能需要将 50
档甚至更多的报价存储为数组向量,编写脚本十分不便。由于报价字段名通常以表示报价类型的字符串加编号的形式存储,可以通过以下方式编写脚本:
// 随机生成 50 档报价
n = 200
t=table(take(datetimes,n) as trade_time, take(syms,n) as sym)
for(i in 1:51){
t["bid"+string(i)] = take(500+rand(10.0,n), n)
}
// 将 50 档报价存储为数组向量
t["bid"]=fixedLengthArrayVector(t["bid"+string(1..50)])
t1=select trade_time, sym, bid from t
例3. 将多个数组向量合并存储为一个数组向量。参考前例,此处随机生成交易所 A、B 的 5 档行情,然后将交易所 A、B 的 5 档报价分别存储为数组向量,最后将交易所
A、B 的报价数组向量合并存储为一个数组向量。
//随机生成交易所A、B的5档行情
syms = "A" + string(1..5)
datetimes = 2019.01.01T00:00:00..2019.01.31T23:59:59
n = 10
t1 = table(take(datetimes, n) as trade_time, take(syms, n) as sym)
for(i in 1:6){
t1["bid" + string(i)] = take(50 + rand(10.0, n), n)
}
t2 = table(take(datetimes, n) as trade_time, take(syms, n) as sym)
for(i in 1:6){
t2["bid" + string(i)] = take(50 + rand(10.0, n), n)
}
// 将交易所A、B的5档报价分别存储为数组向量
t1["bid"] = fixedLengthArrayVector(t1["bid" + string(1..5)])
t2["bid"] = fixedLengthArrayVector(t2["bid" + string(1..5)])
// 将交易所A、B的报价合并存储为一个数组向量
t1["bid"] = fixedLengthArrayVector(t1["bid"], t2["bid"])
t3 = select trade_time, sym, bid from t1
表
1
.
t3
trade_time
sym
bid
2019.01.01T00:00:01
A2
[58.97,50.65,54.38,50.11,56.26,52.35,52.79,55.43,52.16,53.35]
2019.01.01T00:00:02
A3
[50.25,53.45,52.68,58.19,56.51,57.54,55.22,51.74,58.63,57.43]
2019.01.01T00:00:03
A4
[56.42,50.28,57.04,52.45,51.83,57.75,55.04,57.34,57.82,53.28]
2019.01.01T00:00:04
A5
[59.90,51.73,55.54,57.74,53.48,59.62,57.26,53.99,52.67,57.82]
2019.01.01T00:00:05
A1
[53.16,59.27,52.97,50.41,58.30,57.83,54.93,56.91,52.51,57.95]
2019.01.01T00:00:06
A2
[53.14,50.87,52.62,54.47,59.97,56.99,55.32,54.66,56.77,58.39]
2019.01.01T00:00:07
A3
[58.33,59.80,52.34,57.52,57.39,54.67,51.19,52.11,55.27,53.07]
2019.01.01T00:00:08
A4
[55.21,54.88,54.38,52.36,56.56,53.81,57.84,53.24,54.87,54.63]
2019.01.01T00:00:09
A5
[52.98,55.72,55.83,50.60,51.01,57.02,54.07,54.63,55.44,59.28]
2019.01.01T00:00:00
A1
[56.68,54.55,53.11,53.38,59.60,57.35,59.92,50.62,56.06,54.69]
相关函数
:
arrayVector
FILE:references/doc_4573.md
# weekBegin
**URL**: https://docs.dolphindb.cn/zh/funcs/w/weekBegin.html
**来源**: DolphinDB 官方文档
---
weekBegin
语法
weekBegin(X, [weekday=0], [offset], [n=1])
详情
返回
X
所在星期或上一个星期中
weekday
对应的日期。
如果参数
weekday
>
weekday
(
X
,
false
),返回
X
所在星期的上一个星期中
weekday
对应的日期。
如果参数
weekday
<=
weekday
(
X
,
false
),返回X所在星期中
weekday
对应的日期。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
个星期更新一次。
注:
offset
和
n
须同时指定,且只有当
n
>1时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
weekday
是0到6之间的整数,0表示星期一,1表示星期二,... ,6表示星期日。默认值为0。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
一个 DATE 类型的标量或向量。
例子
例1:
t = table(2017.12.01..2017.12.14 as date);
update t set weekday=weekday(date, false), weekBegin=weekBegin(date), weekBegin4=weekBegin(date,4);
t;
得到:
date
weekday
weekBegin
weekBegin4
2017.12.01
4
2017.11.27
2017.12.01
2017.12.02
5
2017.11.27
2017.12.01
2017.12.03
6
2017.11.27
2017.12.01
2017.12.04
0
2017.12.04
2017.12.01
2017.12.05
1
2017.12.04
2017.12.01
2017.12.06
2
2017.12.04
2017.12.01
2017.12.07
3
2017.12.04
2017.12.01
2017.12.08
4
2017.12.04
2017.12.08
2017.12.09
5
2017.12.04
2017.12.08
2017.12.10
6
2017.12.04
2017.12.08
2017.12.11
0
2017.12.11
2017.12.08
2017.12.12
1
2017.12.11
2017.12.08
2017.12.13
2
2017.12.11
2017.12.08
2017.12.14
3
2017.12.11
2017.12.08
例2:
t = table(2018.01.03+0..10*3 as date, 0..10 as x);
update t set weekday=weekday(date, false), weekBegin=weekBegin(date,,2018.01.02,2);
t;
得到:
date
x
weekday
weekBegin
2018.01.03
0
2
2018.01.01
2018.01.06
1
5
2018.01.01
2018.01.09
2
1
2018.01.01
2018.01.12
3
4
2018.01.01
2018.01.15
4
0
2018.01.15
2018.01.18
5
3
2018.01.15
2018.01.21
6
6
2018.01.15
2018.01.24
7
2
2018.01.15
2018.01.27
8
5
2018.01.15
2018.01.30
9
1
2018.01.29
2018.02.02
10
4
2018.01.29
例3:
date=2012.10.02 2012.10.03 2012.10.07 2012.10.08 2012.10.12 2012.10.16 2012.10.18 2012.10.20 2012.10.25 2012.10.28
time=[09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12,09:38:13]
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
t1;
得到:
date
time
sym
qty
price
2012.10.02
09:34:07
MSFT
2200
49.6
2012.10.03
09:36:42
MSFT
1900
29.46
2012.10.07
09:36:51
MSFT
2100
29.52
2012.10.08
09:36:59
MSFT
3200
30.02
2012.10.12
09:32:47
MSFT
6800
174.97
2012.10.16
09:35:26
MSFT
5400
175.23
2012.10.18
09:34:16
MSFT
1300
50.76
2012.10.20
09:34:26
MSFT
2500
50.32
2012.10.25
09:38:12
MSFT
8800
51.29
2012.10.28
09:38:13
MSFT
4500
52.38
select avg(price),sum(qty) from t1 group by weekBegin(date, 4, 2012.10.01, 2);
得到:
weekBegin_date
avg_price
sum_qty
2012.09.28
34.65
9400
2012.10.12
100.514
24800
2012.10.26
52.38
4500
FILE:references/doc_4575.md
# getInstrumentPayReceive
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentpayreceive.html
**来源**: DolphinDB 官方文档
---
getInstrumentPayReceive
语法
getInstrumentPayReceive(instrument)
详情
根据输入的金融工具,获取该工具的收付标识。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
STRING 类型标量或向量。
例子
swap = {
"productType": "Swap",
"swapType": "IrSwap",
"irSwapType": "IrFixedFloatingSwap",
"version": 0,
"start": 2021.05.15,
"maturity": 2023.05.15,
"frequency": "Quarterly",
"fixedRate": 0.02,
"calendar": "CFET",
"fixedDayCountConvention": "Actual365",
"floatingDayCountConvention": "Actual360",
"payReceive": "Pay",
"iborIndex": "SHIBOR_3M",
"spread": 0.0005,
"notional":["CNY", 1E8]
}
ins = parseInstrument(swap)
getInstrumentPayReceive(ins)
// output: Pay
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_458.md
# rowXor
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowXor.html
**来源**: DolphinDB 官方文档
---
rowXor
语法
rowXor(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行逻辑异或操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([true false false, true true true, true true true]);
rowXor(m);
// output
[1,0,0]
t=table(true false false true false true as x, false true false true false true as y, false false true true false false as z);
t;
x
y
z
1
0
0
0
1
0
0
0
1
1
1
1
0
0
0
1
1
0
rowXor(t);
// output
[1,1,1,1,0,0]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2);
select * from t where rowXor(price1$ 30, price2$ 50);
sym
price1
price2
MS
29.46
50.76
IBM
29.52
50.32
C
174.97
26.23
相关函数:
xor
FILE:references/doc_4590.md
# dema
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dema.html
**来源**: DolphinDB 官方文档
---
dema
语法
dema(X, window)
TA-lib 系列函数参数说明和窗口计算规则请参考:
TA-lib 系列
详情
在给定长度(以元素个数衡量)的滑动窗口内,计算
X
的双重指数移动平均(Double Exponential
Moving Average)。
其计算公式为:
返回值
若
X
是一个向量,则返回一个 与
X
长度相同的向量,包含每个位置计算得到的 DEMA 值。
若
X
是一个矩阵,则返回一个与
X
维度相同的矩阵,每一列计算对应列的 DEMA 值。
若
X
是一个表,则返回一个与
X
维度相同的表,计算表中每一列的 DEMA 值。
例子
x=12.1 12.2 12.6 12.8 11.9 11.6 11.2
dema(x,3);
// output
[,,,,12.091666666666668,11.689583333333335,11.266666666666665]
x=matrix(12.1 12.2 12.6 12.8 11.9 11.6 11.2, 14 15 18 19 21 12 10)
dema(x,3);
col1
col2
12.0917
20.9444
11.6896
14.6806
11.2667
10.9444
相关函数:
ema
,
tema
FILE:references/doc_4593.md
# getInstrumentSubType
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentsubtype.html
**来源**: DolphinDB 官方文档
---
getInstrumentSubType
语法
getInstrumentSubType(instrument)
详情
根据输入的金融工具,获取它的债券子类型。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
STRING 类型标量或向量。
例子
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "ZeroCouponBond",
"version": 0,
"instrumentId": "0001",
"start": 1996.03.01,
"maturity": 2032.05.15,
"dayCountConvention": "ActualActualISDA",
"coupon": 0.0276,
"issuePrice": 100.0,
"frequency": "Semiannual",
"subType":"TREASURY_BOND",
"creditRating":"B",
"settlement": 2022.05.15
}
ins = parseInstrument(bond)
getInstrumentSubType(ins)
// output: TREASURY_BOND
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_4598.md
# eachAt(@)
**URL**: https://docs.dolphindb.cn/zh/progr/operators/eachAt.html
**来源**: DolphinDB 官方文档
---
eachAt(@)
语法
X@index
eachAt(X, index)
参数
X
可以是一个标量、向量(常规向量/元组
/数组向量
)、矩阵、表、字典、数据对、单目函数。
index
可以是一个布尔表达式/布尔值、向量(常规向量/元组
/数组向量
)、数据对
详情
当 index 是布尔表达式时, 返回 X 中满足于 index 为 True 的元素;否则返回以 index 为索引的元素。若 X
是函数,则 index 将作为函数的参数。
eachAt 和 at 用法类似,其不同点在于:
(1) 当 index 是元组时:
at 会将 index 的元素作为 X 每个维度的索引。例如:若 X 是一个向量组成的元组,则 index =
(0, 1) 则返回 X 的第 1 个元素中下标为 1 的元素值。
eachAt,则将 index 中的每个元素都作为一维索引,返回 X 中对应 index 的元素。例如:若 X
是一个向量组成的元组,则 index = (0, 1) 则返回 X 的第 1 个元素和第 2 个元素。
(2) 当 X 是函数时:
at 既支持单目函数又支持多目函数。
eachAt 仅支持单目函数。
对不同数据形式查找的支持性见下表。
X/index
条件表达式/布尔值
标量
常规向量
数组向量
元组
数据对
标量
√
√
√
×
√
√
常规向量
√
√
√
√
√
√
元组
√
√
√
×
√
√
数组向量
√
√
√
×
√
√
矩阵
√
√
√
×
√
√
表
√
√
√
×
√
√
字典
×
√
√
×
√
×
数据对
√
√
√
×
√
√
单目函数
√
√
√
√
√
√
例子
v = 3.1 2.2 4.5 5.9 7.1 2.9
eachAt(v, v > 3)
输出返回:[3.1,4.5,5.9,7.1]
v @ 1:3
输出返回:[2.2,4.5]
v @ (:4)
输出返回:[3.1,2.2,4.5,5.9]
v @ (3:)
输出返回:[5.9,7.1,2.9]
// 当 index 是索引时 eachAt 和 at 的区别
tp = [2.3 2.1 2.2, 3.1 2.9 2.8, 5.7 6.9]
tp @ [1 2 3, 0 1 2]
输出返回:(([3.1,2.9,2.8],[5.7,6.9],),([2.3,2.1,2.2],[3.1,2.9,2.8],[5.7,6.9]))
tp at [1 2 3, 0 1 2]
输出返回:([3.1,2.9,2.8],[5.7,6.9,],)
sum @ 6 2 3 NULL 2 -3
输出返回:10
// 由于 seq(..) 优先级比 @ 低,所以此处必须添加括号
sum @ (1..10)
输出返回:55
相关函数:
at
FILE:references/doc_4603.md
# partition
**URL**: https://docs.dolphindb.cn/zh/progr/sql/partition.html
**来源**: DolphinDB 官方文档
---
partition
语法
partition(partitionCol, keys)
参数
partitionCol
是字符串,表示分区列。对于组合分区,可以指定任意一个分区列。
keys
可以是不含空值的标量/向量,表示需要选择的分区。不同分区方案对应的 keys 的选取规则如下:
分区方案
keys
VALUE
分区向量的一个元素
RANGE
每个分区的编号,从0开始
HASH
分区列的哈希余数
LIST
每个分区的编号,从0开始
注:
keys
指定的分区需包含在分区表的分区范围内,否则会出现指定分区键超出范围的报错。
详情
用于选择分区表中的分区,以进行过滤。只能在 where 子句中使用。对于以哈希,列表或范围进行分区的分区表,通过此函数可以方便选取具体的分区。
例子
dbName="dfs://test_topic_partition"
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db=database(dbName, LIST, ["A"+string(1..10), "A"+string(11..20), "A"+string(21..30)])
n=20
date=rand(2012.01.01..2012.01.10, n)
sym=rand("A"+string(1..30), n)
qty=rand(100, n)
t=table(date, sym, qty)
pt=db.createPartitionedTable(t, `pt, `sym).append!(t)
select * from pt where partition(sym, 0 1)
date
sym
qty
2012.01.06
A4
32
2012.01.03
A10
34
2012.01.03
A17
51
2012.01.04
A14
47
2012.01.06
A16
50
2012.01.04
A15
56
2012.01.04
A16
80
2012.01.02
A11
69
2012.01.01
A14
68
dbName="dfs://test_topic_partition"
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db1=database("", HASH, [SYMBOL, 10])
db2=database("", LIST, ["A"+string(1..10), "B"+string(1..10), "C"+string(1..10)])
db=database(dbName, COMPO, [db1, db2])
n=20
id=symbol(string(rand(uuid(), n)))
sym=rand(["A"+string(1..10), "B"+string(1..10), "C"+string(1..10)].flatten(), n)
qty=rand(100, n)
t=table(id, sym, qty)
pt=db.createPartitionedTable(t, `pt, `id`sym).append!(t)
select * from pt where partition(id, 2 3), partition(sym, 1 2) order by id, sym, qty
id
sym
vqty
19e8591f-8b7c-c611-bd3e-582d00a414430
C6
69
2db9074a-0502-27ad-06d5-8d1bf3270245
B4
2
73c1ae86-51c9-3e04-c1dd-6c4b62d8a129
B9
65
99d78d5e-14bb-dc7e-7210-7bc5ad0cda5d
C10
11
FILE:references/doc_4605.md
# disableTablePersistence
**URL**: https://docs.dolphindb.cn/zh/funcs/d/disableTablePersistence.html
**来源**: DolphinDB 官方文档
---
disableTablePersistence
语法
disableTablePersistence(table)
详情
停止把表持久化到磁盘,后续表更新的内容将不会持久化到磁盘上。
colName=["time","x"]
colType=["timestamp","int"]
t = streamTable(100:0, colName, colType);
share t as st
enableTablePersistence(table=st, cacheSize=1200000)
for(s in 0:200){
n=10000
time=2019.01.01T00:00:00.000+s*n+1..n
x=rand(10.0, n)
insert into st values(time, x)
}
disableTablePersistence(st);
参数
table
是一个表对象。
返回值
无。
相关函数
:
enableTablePersistence
,
clearTablePersistence
FILE:references/doc_4616.md
# tmTopRange
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmtoprange.html
**来源**: DolphinDB 官方文档
---
tmTopRange
语法
tmTopRange(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内,统计每个元素 Xi 左侧相邻且连续小于它的元素个数。NULL 被视为最小值。
返回值
INT 类型向量。
例子
t = [0, 1, 2, 3, 7, 8, 9, 10, 11]
x = [NULL, 3.1, NULL, 3.0, 2.9, 2.8, 3.1, NULL, 3.2];
tmTopRange(t, x, window=3);
//output: [,1,0,1,0,0,2,0,2]
tmTopRange(t, x, window=4);
// output: [,1,0,1,0,0,2,0,3]
index = take(datehour(2019.06.13 13:30:10),4) join (datehour(2019.06.13 13:30:10)+1..6)
data = 1 NULL 3 4 5 NULL 3 NULL 5 3
tmTopRange(index, data, 4h)
// output: [0,0,2,3,4,0,1,0,3,0]
FILE:references/doc_4618.md
# update!
**URL**: https://docs.dolphindb.cn/zh/funcs/u/update_.html
**来源**: DolphinDB 官方文档
---
update!
语法
update!(table, colNames, newValues, [filter])
详情
就地更新表中的列。如果
colNames
中的某列不存在,将会创建新列。如果指定了过滤条件,只有符合过滤条件的记录行会被更新。
如果
table
是分区表并且启用了并行处理功能(即配置参数
localExcutors
>
0),那么该操作是并行操作。
参数
table
是 DolphinDB 中 Table 类型的表。它可以是分区的内存表。
colNames
是一个字符串标量/向量,表示要更新的列。
newValues
是对指定列的操作的元代码。元代码是对象或表达式,它们包含在<>中。详情请参考元编程。
filter
是表示过滤条件的元代码。
例子
n=20000000
workDir = "C:/DolphinDB/Data"
if(!exists(workDir)) mkdir(workDir)
trades=table(rand(`IBM`MSFT`GM`C`YHOO`GOOG,n) as sym, 2000.01.01+rand(365,n) as date, 10.0+rand(2.0,n) as price, rand(1000,n) as qty)
trades.saveText(workDir + "/trades.txt");
trades = ploadText(workDir + "/trades.txt")
select top 10 * from trades;
sym
date
price
qty
MSFT
2000.10.09
10.123936
569
IBM
2000.09.22
10.825785
834
MSFT
2000.09.13
10.467937
418
IBM
2000.08.06
10.159152
252
IBM
2000.09.01
10.614444
400
MSFT
2000.05.03
10.40847
253
MSFT
2000.02.20
11.470027
431
YHOO
2000.11.09
11.570013
518
GOOG
2000.03.02
10.206973
630
C
2000.07.09
10.477621
287
trades.update!(`qty, <qty+10>)
select top 10 * from trades;
sym
date
price
qty
MSFT
2000.10.09
10.123936
579
IBM
2000.09.22
10.825785
844
MSFT
2000.09.13
10.467937
428
IBM
2000.08.06
10.159152
262
IBM
2000.09.01
10.614444
410
MSFT
2000.05.03
10.40847
263
MSFT
2000.02.20
11.470027
441
YHOO
2000.11.09
11.570013
528
GOOG
2000.03.02
10.206973
640
C
2000.07.09
10.477621
297
trades.update!(`qty`price, <[qty*2, price/2]>)
select top 10 * from trades;
sym
date
price
qty
MSFT
2000.10.09
5.061968
1158
IBM
2000.09.22
5.412893
1688
MSFT
2000.09.13
5.233969
856
IBM
2000.08.06
5.079576
524
IBM
2000.09.01
5.307222
820
MSFT
2000.05.03
5.204235
526
MSFT
2000.02.20
5.735014
882
YHOO
2000.11.09
5.785007
1056
GOOG
2000.03.02
5.103487
1280
C
2000.07.09
5.238811
594
trades.update!(`qty`price, <[qty*2, price/2]>, <(sym in `IBM`MSFT`GM`GOOG) and date>=2000.07.01>)
select top 10 * from trades;
sym
date
price
qty
MSFT
2000.10.09
2.530984
2316
IBM
2000.09.22
2.706446
3376
MSFT
2000.09.13
2.616984
1712
IBM
2000.08.06
2.539788
1048
IBM
2000.09.01
2.653611
1640
MSFT
2000.05.03
5.204235
526
MSFT
2000.02.20
5.735014
882
YHOO
2000.11.09
5.785007
1056
GOOG
2000.03.02
5.103487
1280
C
2000.07.09
5.238811
594
FILE:references/doc_4619.md
# disableQueryMonitor
**URL**: https://docs.dolphindb.cn/zh/funcs/d/disableQueryMonitor.html
**来源**: DolphinDB 官方文档
---
disableQueryMonitor
语法
disableQueryMonitor()
详情
关闭监控查询任务状态的功能。
由于监控查询任务状态具有一定的内存开销,内存资源紧张时,可以关闭该功能。注意:调用该命令后,用户将无法调用
getQueryStatus
函数获取查询任务的状态。
参数
无。
返回值
无。
相关函数:
enableQueryMonitor
FILE:references/doc_4633.md
# optionVolPredict
**URL**: https://docs.dolphindb.cn/zh/funcs/o/optionVolPredict.html
**来源**: DolphinDB 官方文档
---
optionVolPredict
语法
optionVolPredict(volsurf, dt, strike)
详情
给定点位的时间和行权价,从指定的波动率曲面上预测点位对应的波动率。
参数
volsurf
MKTDATA 类型对象(VolatilitySurface)。
dt
DOUBLE 类型标量/向量,或 DATE 类型标量/向量。
当类型为 DOUBLE 时,表示以“年”为单位的时间。
当类型为 DATE 时,表示具体的日期。
strike
DOUBLE 类型标量/向量,表示执行价格。
返回值
DOUBLE 类型矩阵,形状为size(dt) * size(strike)。行对应输入的
dt
(到期时间/日期),列对应输入的
strike
(执行价)。
例子
refDate = 2025.08.18
ccyPair = "USDCNY"
quoteTerms = ['1d', '1w', '2w', '3w', '1M', '2M', '3M', '6M', '9M', '1y', '18M', '2y', '3y']
quoteNames = ["ATM", "D25_RR", "D25_BF", "D10_RR", "D10_BF"]
quotes = [0.030000, -0.007500, 0.003500, -0.010000, 0.005500,
0.020833, -0.004500, 0.002000, -0.006000, 0.003800,
0.022000, -0.003500, 0.002000, -0.004500, 0.004100,
0.022350, -0.003500, 0.002000, -0.004500, 0.004150,
0.024178, -0.003000, 0.002200, -0.004750, 0.005500,
0.027484, -0.002650, 0.002220, -0.004000, 0.005650,
0.030479, -0.002500, 0.002400, -0.003500, 0.005750,
0.035752, -0.000500, 0.002750, 0.000000, 0.006950,
0.038108, 0.001000, 0.002800, 0.003000, 0.007550,
0.039492, 0.002250, 0.002950, 0.005000, 0.007550,
0.040500, 0.004000, 0.003100, 0.007000, 0.007850,
0.041750, 0.005250, 0.003350, 0.008000, 0.008400,
0.044750, 0.006250, 0.003400, 0.009000, 0.008550]
quotes = reshape(quotes, size(quoteNames):size(quoteTerms)).transpose()
spot = 7.1627
curveDates = [2025.08.21,
2025.08.27,
2025.09.03,
2025.09.10,
2025.09.22,
2025.10.20,
2025.11.20,
2026.02.24,
2026.05.20,
2026.08.20,
2027.02.22,
2027.08.20,
2028.08.21]
domesticCurveInfo = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": refDate,
"currency": "CNY",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": curveDates,
"values":[1.5113,
1.5402,
1.5660,
1.5574,
1.5556,
1.5655,
1.5703,
1.5934,
1.6040,
1.6020,
1.5928,
1.5842,
1.6068]/100
}
foreignCurveInfo = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": refDate,
"currency": "USD",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": curveDates,
"values":[4.3345,
4.3801,
4.3119,
4.3065,
4.2922,
4.2196,
4.1599,
4.0443,
4.0244,
3.9698,
3.7740,
3.6289,
3.5003]/100
}
domesticCurve = parseMktData(domesticCurveInfo)
foreignCurve = parseMktData(foreignCurveInfo)
surf = fxVolatilitySurfaceBuilder(refDate, ccyPair, quoteNames, quoteTerms, quotes, spot, domesticCurve, foreignCurve)
optionVolPredict(surf, 2025.10.18, 7)
7
2025.10.18
0.035427
optionVolPredict(surf, 2025.10.18, [7.1,7.2])
7.1
7.2
2025.10.18
0.02946679951336248
0.02926808425498284
optionVolPredict(surf, [2025.10.18, 2026.10.18], 7)
7
2025.10.18
0.03542772267328074
2026.10.18
0.04045352876306188
optionVolPredict(surf, [2025.10.18, 2026.10.18], [7.1, 7.2])
7.1
7.2
2025.10.18
0.02946679951336248
0.02926808425498284
2026.10.18
0.04218869392416815
0.04440856375512336
相关函数:
parseMktData
FILE:references/doc_4660.md
# hashBucket
**URL**: https://docs.dolphindb.cn/zh/funcs/h/hashBucket.html
**来源**: DolphinDB 官方文档
---
hashBucket
语法
hashBucket(X, buckets)
详情
将
X
中的每个元素哈希到指定数量的桶中,并返回对应的桶编号。
参数
X
可以是标量或向量。
buckets
是一个正整数。
返回值
一个标量或向量,表示桶编号。
例子
hashBucket(34 45 67, 10);
// output
[4,5,7]
hashBucket(`AAPL`TSLA`GS`MS`GE`BA`UAL`WMT, 10);
// output
[9,4,1,8,3,7,5,2]
FILE:references/doc_4666.md
# closeSessions
**URL**: https://docs.dolphindb.cn/zh/funcs/c/closeSessions.html
**来源**: DolphinDB 官方文档
---
closeSessions
语法
closeSessions(sessionId)
详情
关闭一个或多个 session。
参数
sessionId
是一个 LONG 类型的标量或向量,表示一个或多个 session ID。
返回值
无。
例子
getSessionMemoryStat();
userId
sessionId
memSize
remoteIP
remotePort
createTime
lastActiveTime
_DimensionalTable_
0
0.0.0.0
_SharedTable_
0
0.0.0.0
_OLAPTablet_
0
0.0.0.0
_OLAPCacheEngine_
0
0.0.0.0
_OLAPCachedSymbolBase_
0
0.0.0.0
_DFSMetadata_
13,571
0.0.0.0
_TSDBCacheEngine_
0
0.0.0.0
_TSDBLevelFileIndex_
0
0.0.0.0
_TSDBCachedSymbolBase_
0
0.0.0.0
_StreamingPubQueue_
0
0.0.0.0
_StreamingSubQueue_
0
0.0.0.0
guest
1,769,725,800
16
36.27.51.13
63,133
1970.01.01T00:00:00.000
2023.08.31T22:35:27.385
admin
2,882,591,513
6,449
36.27.51.13
60,812
1970.01.01T00:00:00.000
2023.08.31T22:18:27.562
closeSessions(getSessionMemoryStat().sessionId[11]);
FILE:references/doc_4668.md
# 系列函数
**URL**: https://docs.dolphindb.cn/zh/funcs/themes/themes.html
**来源**: DolphinDB 官方文档
---
系列函数
系列函数为同类函数提供了一个主题页面,总体介绍同类函数的函数结构以及计算方法,便于用户更好地理解和使用。
FILE:references/doc_4673.md
# tmcorr
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmcorr.html
**来源**: DolphinDB 官方文档
---
tmcorr
语法
tmcorr(T, X, Y, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间长度衡量)的滑动窗口内,计算
X
和
Y
元素的相关性。
返回值
DOUBLE 类型向量。
例子
T = 1 1 1 2 5 6
X = 1 4 2 -1 2 4
Y = 2 5 -3 6 9 1
m = table(T as t,X as x, Y as y)
select *, tmcorr(t, y, x, 3) from m
t
x
y
tmcorr_t
1
1
2
1
4
5
1
1
2
-3
0.5399
2
-1
6
-0.1981
5
2
9
6
4
1
-1
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = 1 4 2 -1 2 4
Y = 2 5 -3 6 9 1
m = table(T as t,X as x, Y as y)
select *, tmcorr(t, y, x, 3d) from m
t
x
y
tmcorr_t
2021.01.02
1
2
2021.01.02
4
5
1
2021.01.04
2
-3
0.5399
2021.01.05
-1
6
-1
2021.01.07
2
9
1
2021.01.08
4
1
-1
select *, tmcorr(t, y, x, 1w) from m
t
x
y
tmcorr_t
2021.01.02
1
2
2021.01.02
4
5
1
2021.01.04
2
-3
0.5399
2021.01.05
-1
6
-0.1981
2021.01.07
2
9
-0.0726
2021.01.08
4
1
-0.1995
相关函数:
mcorr
,
corr
FILE:references/doc_4681.md
# xor
**URL**: https://docs.dolphindb.cn/zh/funcs/x/xor.html
**来源**: DolphinDB 官方文档
---
xor
语法
xor(X, Y)
详情
按元素逐个返回
X
逻辑异或 (
XOR
)
Y
的结果。
参数
X
和
Y
可以是标量、数据对、向量、矩阵或表。
返回值
布尔型标量、数据对、向量、矩阵或表,表示
X
逻辑异或
Y
的结果。
例子
1 xor 0
// output: true
x = 5 6 7
x xor 0
// output: [true,true,true]
x = 1 2 3
y = 2 1 3
x xor y
// output: [false,false,false]
true xor false
// output: true
相关函数:
or
,
not
FILE:references/doc_4683.md
# dropStreamEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropStreamEngine.html
**来源**: DolphinDB 官方文档
---
dropStreamEngine
语法
dropStreamEngine(name)
别名:
dropAggregator
详情
释放指定的流数据引擎的定义。
参数
name
:字符串,表示一个流数据引擎的名称。需指定为已创建的引擎名称,否则会抛出异常。通过
getStreamEngineStat
可查看已创建的引擎名称。
返回值
无。
例子
share streamTable(1000:0, `time`sym`qty, [TIMESTAMP, SYMBOL, INT]) as trades
outputTable = table(10000:0, `time`sym`sumQty, [TIMESTAMP, SYMBOL, INT])
tradesAggregator = createTimeSeriesAggregator(name="StreamAggregatorDemo", windowSize=3, step=3, metrics=<[sum(qty)]>, dummyTable=trades, outputTable=outputTable, timeColumn=`time, useSystemTime=false, keyColumn=`sym, garbageSize=50)
subscribeTable(tableName="trades", actionName="tradesAggregator", offset=0, handler=append!{tradesAggregator}, msgAsTable=true)
def writeData(n){
timev = 2018.10.08T01:01:01.001 + timestamp(1..n)
symv =take(`A`B, n)
qtyv = take(1, n)
insert into trades values(timev, symv, qtyv)
}
writeData(6);
select * from outputTable;
time
sym
sumQty
2018.10.08T01:01:01.003
A
1
2018.10.08T01:01:01.006
A
1
2018.10.08T01:01:01.006
B
2
dropStreamEngine("StreamAggregatorDemo");
FILE:references/doc_469.md
# kurtosis
**URL**: https://docs.dolphindb.cn/zh/funcs/k/kurtosis.html
**来源**: DolphinDB 官方文档
---
kurtosis
语法
kurtosis(X, [biased=true])
详情
计算
X
的峰度。
kurtosis
函数在计算时会忽略 NULL 值。
若
biased
=true,表示结果为有偏估计,计算公式为:
若
biased
=false,表示结果为无偏估计,计算公式为:
若
X
为矩阵,计算每列的峰度,返回一个向量。
若
X
为表,计算每列的峰度,返回一个表。
kurtosis
函数也支持校正偏差查询分区表和分布式表。
DolphinDB 的
kurtosis
默认情况(当
biased
=true
时)存在偏差,而 pandas 和 Excel 的 kurt 默认为无偏估计,且减去了正态分布的峰度3。参考下面例子,可以使 DolphinDB 的峰度计算结果与
pandas 和 excel 的结果保持一致:
python
m = [1111, 323, 43, 51]
df = pandas.DataFrame(m)
y = df.kurt()
// output
2.504252
dolphindb
m=matrix(1111 323 43 51)
kurtosis(m, false) - 3
// output
2.5043
参数
X
是一个向量、矩阵或表。
biased
是一个布尔值,表示是否为有偏估计。默认值为 true,表示为有偏估计。
返回值
DOUBLE 类型标量/向量/表。
例子
下面的例子使用了
norm
函数生成数据,每次生成的数据都会有细微差别,因此每次计算的结果会有所偏差。
x=norm(0, 1, 1000000);
kurtosis(x);
// output
3.000249
x[0]=100;
kurtosis(x);
// output
100.626722
m=matrix(1..10, 1 2 3 4 5 6 7 8 9 100);
m;
#0
#1
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
100
kurtosis(m);
// output
[1.775757575757576,7.997552566718839]
FILE:references/doc_4693.md
# writeLines
**URL**: https://docs.dolphindb.cn/zh/funcs/w/writeLines.html
**来源**: DolphinDB 官方文档
---
writeLines
语法
writeLines(handle, object, [offset=0], [length],
[windowsLineEnding])
详情
向句柄中写入给定的行数。
参数
length
是往句柄中写入的行数。
其他参数同
writeLine
函数。
返回值
整型标量,表示成功写入的行数。
例子
timer(10){
x=rand(`IBM`MSFT`GOOG`YHOO`ORCL,10240)
eachRight(writeLine, file("test.txt","w"),x)
fin = file("test.txt")
do{ y=fin.readLine() } while(!y.isVoid())
fin.close()
};
// output
Time elapsed: 277.548 ms
timer(10){
x=rand(`IBM`MSFT`GOOG`YHOO`ORCL,10240)
file("test.txt","w").writeLines(x)
fin = file("test.txt")
do{ y=fin.readLines(1024) } while(y.size()==1024)
fin.close()
};
// output
Time elapsed: 28.003 ms
FILE:references/doc_47.md
# forceTriggerOrderBookSnapshot
**URL**: https://docs.dolphindb.cn/zh/funcs/f/forceTriggerOrderBookSnapshot.html
**来源**: DolphinDB 官方文档
---
forceTriggerOrderBookSnapshot
语法
forceTriggerOrderBookSnapshot(engine, [time])
详情
该函数用于强制触发订单簿快照输出,适用于不满足常规触发条件(如时间窗口或数据)但仍需生成快照的场景。调用后,快照会立即生成并输出。
注意,仅在同时满足以下条件时可调用该函数:
createOrderBookSnapshotEngine
设置
triggerType
=
"mutual",且
useSystemTime
= false。
订单簿快照引擎已事先共享。
参数
engine
订单簿引擎名称或引擎对象。
time
可选参数,TIME 类型标量,设置输出快照的时间戳,即输出表中该条记录的 timestamp
值。若不指定该参数,则时间戳将为当前引擎中最后一条数据的时间戳。
返回值
无
例子
def createInputTable(){
name = `SecurityID`Date`Time`SourceType`Type`Price`Qty`BSFlag`BuyNo`SellNo`ApplSeqNum`ChannelNo`ReceiveTime
type = `STRING`DATE`TIME`INT`INT`LONG`LONG`INT`LONG`LONG`LONG`INT`NANOTIMESTAMP
it = table(1:0, name, type)
itMap = dict( `codeColumn`timeColumn`typeColumn`priceColumn`qtyColumn`buyOrderColumn`sellOrderColumn`sideColumn`msgTypeColumn`seqColumn`receiveTime, `SecurityID`Time`Type`Price`Qty`BuyNo`SellNo`BSFlag`SourceType`ApplSeqNum`ReceiveTime )
return it, itMap
}
data = table(take("600010.SH", 3) join take("600020.SH", 3) join take("600010.SH", 2) join take("600020.SH", 3) join take("600010.SH", 2) join take("600020.SH", 1) as SecurityID, take(today(), 14) as date, [14:56:51.000, 14:56:52.000, 14:56:52.000, 14:56:53.000, 14:56:54.000, 14:56:55.000, 14:56:56.000, 14:56:57.000, 14:56:58.000, 14:56:59.000, 14:56:59.000, 14:57:00.000, 14:57:00.000, 14:57:01.000] as time, [0,0,1, 0,0,1,0,0,0,0,1,1,0,0] as SourceType, [2,2,0,2,2,0,2,2,2,2,0,0,2,2] as Type, [229000, 219000, 229000, 229000, 219000, 229000, 229000, 219000, 229000, 219000, 229000, 229000, 219000, 219000]as price, [2000, 1000, 1000, 2000, 1000, 1000, 2000, 1000, 2000, 1000, 1000, 1000, 2000, 2000] as qty, [1,2,2,1,2,2,1,2,1,2,2,2,1,1] as BSFlag, [1,2,1,6,7,6,3,4,8,9,6,1,5,10] as BuyNo, [1,2,2,6,7,7,3,4,8,9,9,4,5,10] as SellNo, 1..14 as ApplSeqNum, take(101, 14) as Channel, take(2023.02.20T04:01:42.499000000, 14) as receiveTime)
try{dropStreamEngine("engine1")} catch(exp){}
orderbookDepth = 10
outlist = lower(genOutputColumnsForOBSnapshotEngine(true, true, (10, true), true, true, true,5, true, true, true)[0])
outputTable = streamTable(genOutputColumnsForOBSnapshotEngine(true, true, (10, true), true, true, true,5, true, true, true)[1])
inputTable = createInputTable()[0]
inputColMap = createInputTable()[1]
dic = dict(["600010.SH", "600020.SH"], [1023, 1265])
maxdic = dict(["600010.SH", "600020.SH"], [3521, 3278])
mindic = dict(["600010.SH", "600020.SH"], [2531, 2210])
engine = createOrderBookSnapshotEngine(name="engine1", exchange="XSHE", orderbookDepth=orderbookDepth, intervalInMilli = 300, date=today(), startTime=09:15:00.000, prevClose=dic, maxPrice = maxdic, minPrice = mindic, priceNullFill = 0.0, precision = 3, orderBySeq = true, skipCrossedMarket = false, dummyTable=inputTable, outputTable=outputTable, inputColMap=inputColMap, outputColMap = outlist, orderBookAsArray=true, triggerType = "mutual", endTime = 15:30:00.000, outputCodeMap = ["600010.SH", "600020.SH"], orderBookDetailDepth = 5)
engine.append!(data)
select * from outputTable
查看订单簿快照结果,600010.SH 和 600020.SH 对应的最后一条快照的时间戳为 2025.05.26 14:57:00.000。其中,600020.SH
的最后一条数据未能满足触发条件,导致未输出对应的快照。此时,可通过
forceTriggerOrderBookSnapshot
触发
600020.SH 的最后一条数据输出。
share engine as engine1
forceTriggerOrderBookSnapshot(engine1)
select * from outputTable
执行后,可见输出了时间戳为 2025.05.26 15:00:00.000 的 600010.SH 和 600020.SH 的订单簿快照。
FILE:references/doc_4707.md
# fxSwapPricer
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fxSwapPricer.html
**来源**: DolphinDB 官方文档
---
fxSwapPricer
语法
fxSwapPricer(instrument, pricingDate, spot, domesticCurve,
foreignCurve)
详情
计算外汇掉期的净现值。
参数
instrument
INSTRUMENT 类型标量,一个 FxSwap 对象,表示需要定价的外汇掉期。
pricingDate
DATE 类型标量,表示定价日期。
spot
数值类型标量,表示汇率即期价格。
domesticCurve
MKTDATA 类型标量,一个 IrYieldCurve 对象,表示本币折现曲线。
foreignCurve
MKTDATA 类型标量,一个 IrYieldCurve 对象,表示外币折现曲线。
返回值
DOUBLE 类型标量。
例子
pricingDate = 2025.08.18
fxSwap = {
"productType": "Swap",
"swapType": "FxSwap",
"version": 0,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E6],
"nearStrike": 7.15,
"nearExpiry": pricingDate + 60,
"nearDelivery": pricingDate + 62,
"farStrike": 7.18,
"farExpiry": pricingDate + 180,
"farDelivery": pricingDate + 182
}
curveDates = [2025.08.21,
2025.08.27,
2025.09.03,
2025.09.10,
2025.09.22,
2025.10.20,
2025.11.20,
2026.02.24,
2026.05.20,
2026.08.20,
2027.02.22,
2027.08.20,
2028.08.21]
domesticCurveInfo = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": pricingDate,
"currency": "CNY",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": curveDates,
"values":[1.5113,
1.5402,
1.5660,
1.5574,
1.5556,
1.5655,
1.5703,
1.5934,
1.6040,
1.6020,
1.5928,
1.5842,
1.6068]/100
}
foreignCurveInfo = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": pricingDate,
"currency": "USD",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": curveDates,
"values":[4.3345,
4.3801,
4.3119,
4.3065,
4.2922,
4.2196,
4.1599,
4.0443,
4.0244,
3.9698,
3.7740,
3.6289,
3.5003]/100
}
instrument = parseInstrument(fxSwap)
domesticCurve = parseMktData(domesticCurveInfo)
foreignCurve = parseMktData(foreignCurveInfo)
spot = 7.1627
npv = fxSwapPricer(instrument, pricingDate, spot, domesticCurve, foreignCurve)
print(npv)
// output:84379.328782705269986
相关函数:
parseInstrument
,
parseMktData
FILE:references/doc_4711.md
# complex
**URL**: https://docs.dolphindb.cn/zh/funcs/c/complex.html
**来源**: DolphinDB 官方文档
---
complex
语法
complex(X, Y)
详情
创建复数 X+Y*i。
复数类型的数据长度为16字节,其中低8位的数据存储于
X
中,高8位的数据存储于
Y
中。
参数
X
和
Y
是数值型的标量、数据对、向量或矩阵,支持的数据类型为 INTEGRAL
类(COMPRESSED、INT128 除外)和 FLOATING 类。
返回值
COMPLEX 类型标量或向量。
例子
complex(2, 5)
// output: 2.0+5.0i
a=1.0 2.3
b=3 4
complex(a,b)
// output:[1+3i,2.3+4i]
FILE:references/doc_472.md
# businessMonthEnd
**URL**: https://docs.dolphindb.cn/zh/funcs/b/businessMonthEnd.html
**来源**: DolphinDB 官方文档
---
businessMonthEnd
语法
businessMonthEnd(X, [offset], [n=1])
详情
返回
X
所在月份的最后一个工作日(周一到周五)。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
月更新一次。注意,
offset
和
n
须同时指定,且只有当
n
>1 时,
offset
才会生效。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP 类型的标量或向量。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
businessMonthEnd(2010.10.12);
// output
2010.10.29
businessMonthEnd(2010.10.12, 2000.03.31, 3);
// output
2010.12.31
date=2016.04.12+(1..10)*30
time = take(09:30:00, 10)
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
t1;
date
time
sym
qty
price
2016.05.12
09:30:00
MSFT
2200
49.6
2016.06.11
09:30:00
MSFT
1900
29.46
2016.07.11
09:30:00
MSFT
2100
29.52
2016.08.10
09:30:00
MSFT
3200
30.02
2016.09.09
09:30:00
MSFT
6800
174.97
2016.10.09
09:30:00
MSFT
5400
175.23
2016.11.08
09:30:00
MSFT
1300
50.76
2016.12.08
09:30:00
MSFT
2500
50.32
2017.01.07
09:30:00
MSFT
8800
51.29
2017.02.06
09:30:00
MSFT
4500
52.38
select avg(price),sum(qty) from t1 group by businessMonthEnd(date,2016.01.31,2);
businessMonthEnd_date
avg_price
sum_qty
2016.06.30
39.53
4100
2016.08.31
29.77
5300
2016.10.31
175.1
12200
2016.12.30
50.54
3800
2017.02.28
51.835
13300
相关函数:
businessMonthBegin
,
monthBegin
,
monthEnd
,
semiMonthBegin
,
semiMonthEnd
FILE:references/doc_4723.md
# 用户权限管理
**URL**: https://docs.dolphindb.cn/zh/tutorials/ACL_and_Security.html
**来源**: DolphinDB 官方文档
---
用户权限管理
在数据库产品使用过程中,为保证数据不被窃取、不遭破坏,我们需要通过用户权限来限制用户对数据库、数据表、视图等功能的操作范围,以保证数据库安全性。为此,DolphinDB
提供了具备以下主要功能的权限管理系统:
提供用户和组角色,方便权限控制
提供 20 种权限控制类别,适应各种场景
丰富的权限控制函数
函数视图兼顾保护数据隐私与提供分析结果
对任务调度和流数据任务动态鉴权,保证系统安全
使用 RSA 对用户关键信息加密
支持 SSO,保证安全通信,方便系统扩展
DolphinDB 在 1.30.21 和 2.00.9 版本中对权限管理主要做了如下升级,使权限控制更加精确、完善和方便:
新增数据库层面权限类型:DB_READ、DB_WRITE、DB_UPDATE、DB_DELETE、DB_INSERT
将原本的 TABLE_WRITE 权限细分为 TABLE_INSERT、TABLE_UPDATE、TABLE_DELETE
新增用户内存限制权限类型:QUERY_RESULT_MEM_LIMIT、TASK_GROUP_MEM_LIMIT
支持在数据节点执行权限相关函数
角色
在未进行登录操作前,用户以 guest 身份访问 DolphinDB server,此时没有任何访问或操作数据库表的权限,也无法被赋予任何权限,需要执行
login
函数登录用户,具体的角色分类及创建用户方式等将在下述文章中介绍。
1.1. 角色分类
1.1.1. 用户和组
在权限管理系统中,DolphinDB 引入组的概念,便于对具有相同权限的用户进行权限配置和管理。
当权限管理需求发生变化,只需要修改一次组的权限,就可以应用于组内所有用户。
组的新成员可以获得组拥有的所有权限。
一个用户可以属于 0,1 或多个组,一个组里也可以包括 0,1 或多个用户。
用户和组都是权限的载体。我们可以赋予或禁止一个用户、一个组某项权限。用户最终的实际权限是用户本身的权限,加上所属组的权限的结果(详见
用户和组权限确定规则
)。
1.1.2. 管理员和超级管理员
DolphinDB 将管理员分超级管理员(super admin)和普通管理员(admin)。
DolphinDB 集群第一次启动时,会自动创建用户名为 "admin",密码为 "123456"
的超级管理员。此超级管理员初始时便拥有所有的权限,且无法被删除,其权限也无法被剥夺。
所有用户(包括超级管理员)都可以通过
changePwd
修改自己的密码,或者通过管理员
resetPwd
修改密码。
1.1.3. 管理员和普通用户
除管理员以外的用户即为普通用户。
管理员可以通过
createUser
函数的
isAdmin
参数决定是否将创建的用户设置为管理员。
只有管理员可以创建、删除用户和组,赋予或禁止、撤销其他管理员,用户和组的权限,获取其他用户和组的相关信息。
只有管理员才能执行如下用户管理函数:
resetPwd
,
createGroup
,
deleteGroup
,
createUser
,
deleteUser
,
addGroupMember
,
deleteGroupMember
。
以下为超级管理员、管理员和普通用户的初始权限对照表:
超级管理员
管理员
非管理员用户
是否需要手动创建
否
是
是
是否可以被删除
否
是
是
是否会被
getUserList
函数列出
否
是
是
是否有权创建和删除管理员、用户、组
是
是
否
是否有权赋予和禁止管理员、用户、组的权限
是
是
否
是否有权创建和删除函数视图
是
是
否
是否有权删除其他用户提交的任务
是
是
否
是否拥有所有类型的权限(权限类型介绍见
权限类别
)
是
否
否
1.2. 角色管理
注意
:2.00.9 和 1.30.21 版本后,角色管理函数可以在数据节点执行,之前版本只允许在控制节点操作。
1.2.1. 管理用户
只有管理员可以创建用户:
login(`admin, "123456");//超级管理员登录
createUser("admin1","123456",,true)//创建普通管理员
login("admin1","123456")//普通管理员登录
createUser("user1","123456",,false)//普通管理员创建普通用户
createUser("user2","123456",,true)//普通管理员创建普通管理员
所有用户都可以修改自己的密码:
login("user1","123456")//登录用户
changePwd("123456","123456@")//修改自己的密码
logout("user1")
login("user1","123456@")//修改密码成功
只有管理员可以修改其他用户的密码:
login("admin1","123456")//登录管理员用户
resetPwd("user1","123456")//修改其他用户密码
login("user1","123456")//修改密码成功
只有管理员可以删除用户:
login("admin1","123456")//登录管理员用户
deleteUser("user1")//删除用户
login("user1","123456")//用户删除成功
=> The user name or password is incorrect
1.2.2. 管理组
只有管理员可以进行组的管理操作。
创建组:
createGroup("group1",["admin1"])
添加组成员:
addGroupMember(["user2"],"group1")
删除组成员:
deleteGroupMember(["user2"],"group1")
删除组:
deleteGroup("group1")
删除组将不会删除组内成员,但会回收组的权限,单独对成员限权的操作不变;添加成员到组里后,该用户的权限会发生变化,详细权限判定规则见
用户和组权限确定规则
部分内容。
1.2.3. 查看角色信息
getGroupList
:返回所有组名列表,只能由管理员执行
getUsersByGroupId
:返回属于指定组的用户,只能由管理员执行
getGroupsByUserId
:返回用户所在的组,只能由管理员执行
getGroupAccess
:返回组的权限,只能由管理员执行
getUserList
:获取除管理员之外的所有用户名,只能由管理员执行
getUserAccess
:返回指定用户所单独被赋予的权限,不包括用户所属组的权限。管理员可以查看所有用户的权限,普通用户只能查看自己的权限,没有指定
userId 时,返回当前登录用户的权限
相关函数用法,参考
函数
。
2. 权限管理
用户可以使用
grant
,
deny
和
revoke
命令来赋予权限、禁止权限,以及撤销权限设置,对应的权限状态为 Allow,Deny 和 None。
注意
:2.00.9 和 1.30.21 版本后权限管理函数操作可以在数据节点执行,之前版本只允许在控制节点操作。
grant 命令:授予某个用户或某个用户组各类权限:
grant(`user2, DBOBJ_CREATE,"*")
getUserAccess("user2")
revoke 命令:撤销某个用户或某个组的之前被赋予或禁止的权限:
revoke(`user2, DBOBJ_CREATE,"*")
getUserAccess("user2")
deny 命令:拒绝某个用户或某个组的权限:
deny(`user2, DBOBJ_CREATE,"*")
getUserAccess("user2")
3. 权限确定规则
3.1. 用户和组权限确定规则
将用户本身也视为一个特殊的组,用户本身的权限就是这个组的权限。用户的最终权限是其所属的所有组的权限共同决定的结果。组的存在简化了对用户权限的管理,与此同时也不免出现权限冲突的情况,以下为权限确定规则:
若用户在至少一组中被赋予某项权限,并且在其他组中没有禁止该项权限,则用户拥有该项权限
若用户在至少一组中被禁止某项权限,即使在其他组中被赋予该项权限,此用户的该项权限依然被禁止
例 1
:若用户只属于一个组,用户对某个权限的状态为 Deny,所在组对当前权限的状态为 Allow,则最终用户对该权限的状态为 Deny:
login("admin","123456")
createUser("user2","123456")
createGroup("group1",["user2"])
deny(`user2, DB_OWNER)//禁止 user2 拥有 DB_OWNER 权限
grant(`group1, DB_OWNER)//赋予 group1DB_OWNER 权限
login("user2","123456")
database("dfs://test",VALUE,1..10)//user2 没有 DB_OWNER 权限
=> <NoPrivilege>Not granted to create
or
delete databases
例 2
:若用户只属于一个组,用户对某个权限的状态为 None,所在组对当前权限的状态为 Allow,则最终用户对该权限的状态为 Allow:
login("admin","123456")
revoke(`user2, DB_OWNER)//撤销禁止 user2 的 DB_OWNER 权限
grant(`group1, DB_OWNER)//赋予 group1DB_OWNER 权限
login("user2","123456")
database("dfs://test",VALUE,1..10)//user2 拥有 DB_OWNER 权限
例 3
:若用户只属于一个组,用户对某个权限的状态为 None,所在组对当前权限的状态为 Deny,则最终用户对该权限的状态为 Deny:
login("admin","123456")
revoke(`user2, DB_OWNER)//撤销禁止 user2 的 DB_OWNER 权限
deny(`group1, DB_OWNER)//赋予 group1DB_OWNER 权限
login("user2","123456")
database("dfs://test",VALUE,1..10)//user2 没有 DB_OWNER 权限
=> <NoPrivilege>Not granted to create
or
delete databases
例 4
:若用户属于多个组,某个组对某个权限的状态为 Deny,其他组对当前权限的状态为 Allow,则最终用户对该权限的状态为 Deny:
login("admin","123456")
createGroup("group2",["user2"])
createGroup("group3",["user2"])
deny(`group1, DB_OWNER)
grant(`group2, DB_OWNER)
grant(`group3, DB_OWNER)
login("user2","123456")
database("dfs://test",VALUE,1..10)//user2 没有 DB_OWNER 权限
=> <NoPrivilege>Not granted to create
or
delete databases
例 5
:若用户属于多个组,某个组对某个权限的状态为 None,其他组对当前权限的状态为 Allow,则最终用户对该权限的状态为 Allow:
login("admin","123456")
revoke(`group1, DB_OWNER)
grant(`group2, DB_OWNER)
grant(`group3, DB_OWNER)
login("user2","123456")
database("dfs://test",VALUE,1..10)//user2 拥有 DB_OWNER 权限
例 6
:若用户属于多个组,某个组对某个权限的状态为 None,其他组对当前权限的状态为 Deny,则最终用户对该权限的状态为 Deny:
login("admin","123456")
revoke(`group1, DB_OWNER)
deny(`group2, DB_OWNER)
deny(`group3, DB_OWNER)
login("user2","123456")
database("dfs://test",VALUE,1..10)//user2 没有 DB_OWNER 权限
=> <NoPrivilege>Not granted to create
or
delete databases
例 7
:若用户所在的组被删除,则以用户本身被赋予的权限为准:
login("admin","123456")
createUser("user2","123456")
createGroup("group1",["user2"])
grant(`user2, DB_OWNER)//赋予 user2 DB_OWNER 权限
deny(`group1, DB_OWNER)//禁止 group1 DB_OWNER 权限
deleteGroup(`group1)//删除 group1
login("user2","123456")
database("dfs://test",VALUE,1..10)//user2 拥有 DB_OWNER 权限
----------------------------------------------------------------
login("admin","123456")
createGroup("group1",["user2"])
revoke(`user2, DB_OWNER)//回收 user2 DB_OWNER 权限
grant(`group1, DB_OWNER)//赋予 group1 DB_OWNER 权限
deleteGroup(`group1)//删除 group1
login("user2","123456")
database("dfs://test",VALUE,1..10)//user2 没有 DB_OWNER权限
3.2. 数据库表权限确定规则
权限作用的对象范围从大到小可以分为:全局 (*),数据库,表。
以下为库表级权限确定规则:
先小范围赋予/撤销/禁止权限,再大范围操作权限,此时小范围权限失效,会被大范围的权限覆盖
先大范围 allow, 再小范围 deny,此时 deny 操作生效,allow 权限覆盖的除 deny 以外的范围依旧是 allow
先大范围 allow, 再小范围 revoke,此时 revoke 操作无效,allow 权限覆盖的范围依旧是 allow
先大范围 deny, 再小范围 revoke,此时 revoke 操作无效,deny 权限覆盖的范围依旧是 deny
先大范围 deny, 再小范围 grant,1.30.21 和 2.00.9 版本前 grant 可以生效,deny 权限覆盖的除 grant
以外的范围依旧是 deny,1.30.21 和 2.00.9 版本后不支持此操作
先大范围 revoke, 再小范围操作权限,此时小范围权限操作生效
例 1
:对用户 user1
deny
表级的 TABLE_READ 权限,然后
grant
全局 TABLE_READ 权限,此时 user1 拥有所有表的 TABLE_READ 权限:
login("admin", "123456")
createUser("user1","123456")
dbName = "dfs://test"
if
(existsDatabase(dbName)){
dropDatabase(dbName)
}
t = table(1..10
as
id , rand(100, 10)
as
val)
db=database(dbName, VALUE, 1..10)
pt= db.createPartitionedTable(t, "pt", "id")
pt.append!(t)
deny("user1", TABLE_READ, dbName+"/pt")
grant("user1", TABLE_READ, "*")
login("user1", "123456")
select *
from
loadTable(dbName, "pt")//user1 获得读 "dfs://test"的权限
例 2
:对用户 user2
grant
表级的 TABLE_READ 权限,然后
deny
全局 TABLE_READ 权限,此时 user2 被禁止所有表的 TABLE_READ 权限:
login("admin", "123456")
createUser("user2","123456")
dbName = "dfs://test"
if
(existsDatabase(dbName)){
dropDatabase(dbName)
}
t = table(1..10
as
id , rand(100, 10)
as
val)
db=database(dbName, VALUE, 1..10)
pt= db.createPartitionedTable(t, "pt", "id")
pt.append!(t)
grant("user2", TABLE_READ, dbName+"/pt")
deny("user2", TABLE_READ, "*")
login("user2", "123456")
select *
from
loadTable(dbName, "pt")//user2 被禁止读 "dfs://test"
例 3
:对用户 user3
grant
表级的 TABLE_READ 权限,然后
revoke
全局 TABLE_READ 权限,此时 user3 被回收所有表的 TABLE_READ 权限:
login("admin", "123456")
createUser("user3","123456")
dbName = "dfs://test"
if
(existsDatabase(dbName)){
dropDatabase(dbName)
}
t = table(1..10
as
id , rand(100, 10)
as
val)
db=database(dbName, VALUE, 1..10)
pt= db.createPartitionedTable(t, "pt", "id")
pt.append!(t)
grant("user3", TABLE_READ, dbName+"/pt")
revoke("user3", TABLE_READ, "*")
login("user3", "123456")
select *
from
loadTable(dbName, "pt")//user 被撤回读 "dfs://test" 的权限
例 4
:先对用户 user1
grant
全局的 TABLE_READ 权限,然后
deny
"dfs://test/pt" 表 TABLE_READ 权限,此时 user1 拥有除
"dfs://test/pt" 表外所有表的 TABLE_READ 权限:
login("admin", "123456")
createUser("user1","123456")
dbName = "dfs://test"
t = table(1..10
as
id , rand(100, 10)
as
val)
if
(existsDatabase(dbName)){
dropDatabase(dbName)
}
db=database(dbName, VALUE, 1..10)
pt= db.createPartitionedTable(t, "pt", "id")
pt.append!(t)
grant("user1", TABLE_READ, "*")
deny("user1", TABLE_READ, dbName+"/pt")
login("user1", "123456")
select *
from
loadTable(dbName, "pt")//user1被禁止读"dfs://test/pt"
例 5
:先对用户 user1
grant
全局的 TABLE_READ 权限,然后
revoke
"dfs://test/pt" 表 TABLE_READ 权限,此时 user1 仍然拥有所有表的
TABLE_READ 权限:
login("admin", "123456")
createUser("user1","123456")
dbName = "dfs://test"
t = table(1..10
as
id , rand(100, 10)
as
val)
if
(existsDatabase(dbName)){
dropDatabase(dbName)
}
db=database(dbName, VALUE, 1..10)
pt= db.createPartitionedTable(t, "pt", "id")
pt.append!(t)
grant("user1", TABLE_READ, "*")
revoke("user1", TABLE_READ, dbName+"/pt")
login("user1", "123456")
select *
from
loadTable(dbName, "pt")//user1 有读 "dfs://test/pt" 的权限
例 6
:先对用户 user1
deny
全局的 TABLE_READ 权限,然后
revoke
"dfs://test/pt" 表 TABLE_READ 权限,此时 user1 仍然被拒绝所有表的
TABLE_READ 权限:
login("admin", "123456")
createUser("user1","123456")
dbName = "dfs://test"
if
(existsDatabase(dbName)){
dropDatabase(dbName)
}
t = table(1..10
as
id , rand(100, 10)
as
val)
db=database(dbName, VALUE, 1..10)
pt= db.createPartitionedTable(t, "pt", "id")
pt.append!(t)
deny("user1", TABLE_READ, "*")
revoke("user1", TABLE_READ, dbName+"/pt")
getUserAccess("user1")//TABLE_READ 依旧是 deny
例 7
:先对用户 user1
deny
全局的 TABLE_READ 权限,然后
grant
"dfs://test/pt" 表 TABLE_READ 权限,1.30.21 和 2.00.9
版本前,此时 user1 被赋予读 "dfs://test/pt" 表的权限,被拒绝其他所有表的 TABLE_READ 权限,而新版本则在执行
grant
的时候抛出异常:
login("admin", "123456")
createUser("user1","123456")
dbName = "dfs://test"
if
(existsDatabase(dbName)){
dropDatabase(dbName)
}
t = table(1..10
as
id , rand(100, 10)
as
val)
db=database(dbName, VALUE, 1..10)
pt= db.createPartitionedTable(t, "pt", "id")
pt1= db.createPartitionedTable(t, "pt1", "id")
pt.append!(t)
pt1.append!(t)
deny("user1", TABLE_READ, "*")
//新版本中执行grant报错 'Invalid grant: grant [dfs://test/pt] and [deny *] are in conflict'
grant("user1", TABLE_READ, dbName+"/pt")
login("user1", "123456")
select *
from
loadTable(dbName, "pt")//老版本有读 dbName+"/pt" 的权限
select *
from
loadTable(dbName, "pt1")//老版本没有读其他表的权限
3.3. 权限确定规则兼容性
1.30.21 和 2.00.9 版本前,如果某个用户对两张不同表分别
grant
和
deny
相同的表层面权限(TABLE_READ 或 TABLE_WRITE),升级到新版本后该用户会拥有除
deny
的表以外所有表的该权限。举例如下:
1.30.21 和 2.00.9 版本以前,使用
grant
命令赋予或使用
deny
命令禁用用户 'user1'不同表对象的 TABLE_READ 权限后,'user1' 将只有 "dfs://valuedb/pt1" 表的读权限:
login("admin","123456")
createUser("user1","123456")
grant("user1",TABLE_READ,"dfs://valuedb/pt1")
deny("user1",TABLE_READ,"dfs://valuedb/pt2")
升级到新版本后,user1 拥有 "dfs://valuedb" 库中除 pt2 以外所有表的读权限,等同于执行:
grant("user1",TABLE_READ,"dfs://valuedb/pt1")
deny("user1",TABLE_READ,"dfs://valuedb/pt2")
4. 权限类别
注意
:1.30.21 和 2.00.9 版本新增权限 DB_READ, DB_WRITE, DB_INSERT,DB_UPDATE, DB_DELETE,
TABLE_INSERT, TABLE_UPDATE, TABLE_DELETE。
4.1. catalog 级权限类别
CATALOG_MANAGE:管理 catalog 的相关操作,如添加 schema、删除、重命名 catalog 等操作。
CATALOG_READ:管理 catalog 下所有表的数据读取操作。
CATALOG_WRITE:管理 catalog 下所有表的数据写入操作,包括插入、更新、删除。
CATALOG_INSERT:管理 catalog 下所有表的数据插入操作。
CATALOG_UPDATE:管理 catalog 下所有表的数据更新操作。
CATALOG_DELETE:管理 catalog 下所有表的数据删除操作。
4.2.
库级权限类别
DB_MANAGE:1.30.21 和 2.00.9 版本之前,可以创建以及删除数据库,可删除任何人所建数据库,包括具有 DB_OWNER
权限之用户所建数据库;1.30.21 和 2.00.9 版本之后不能创建数据库,只能删除数据库。
DB_OWNER:创建数据库并管理其创建的数据库,包括删除数据库、创建或删除数据表、增加或删除分区、可赋予、禁止或取消其他用户对自己创建的数据库的以下权限:TABLE_READ,
TABLE_WRITE, TABLE_INSERT, TABLE_UPDATE, TABLE_DELETE, DBOBJ_CREATE,
DBOBJ_DELETE, DB_READ, DB_WRITE, DB_INSERT, DB_UPDATE, DB_DELETE。
DBOBJ_CREATE:允许在数据库中建表。
DBOBJ_DELETE:允许在数据库中删除表。
DB_WRITE:允许写数据库所有表,包含表的增删改权限。
DB_INSERT:允许追加数据到某库所有表。
DB_UPDATE:允许更新某库所有表的数据。
DB_DELETE:允许删除某库所有表的数据。
DB_READ:允许读某库所有表。
DB_SENSITIVE_VIEW:允许访问某库所有表的敏感列的明文数据。
4.3.
表级权限类别
TABLE_WRITE:允许增删改所有/指定数据表。
TABLE_READ:允许读取所有/指定数据表。
TABLE_INSERT:允许追加数据到指定表。
TABLE_UPDATE:允许更新指定表的数据。
TABLE_DELETE:允许删除指定表的数据。
TABLE_SENSITIVE_VIEW:允许访问指定表的敏感列的明文数据。
4.4.
列级权限类别
TABLE_SENSITIVE_VIEW:允许访问指定敏感列的明文数据。
4.5.
其他权限类别
VIEW_OWNER:普通用户(组)创建视图的权限。只有管理员才能 grant/deny/revoke 这个权限,此为
2.00.10.4/1.30.22.4 版本新增功能。普通用户(组)被赋予该权限后,可以进行以下操作:
可以创建视图(addFunctionView),且在创建视图后自动拥有该视图的 VIEW_EXEC 权限。
drop 自己创建的视图(dropFunctionView)。
为其它用户 grant/deny/revoke 自己所创建视图的 VIEW_EXEC 权限。
通过 getFunctionViews 查看自己创建的所有视图。
VIEW_EXEC:视图执行权限。
SCRIPT_EXEC:脚本执行权限。
TEST_EXEC:测试脚本执行权限。
QUERY_RESULT_MEM_LIMIT:限制用户的查询内存大小。
TASK_GROUP_MEM_LIMIT:限制用户发送的批量子查询占用的内存大小。
COMPUTE_GROUP_EXEC:连接计算组的权限。
TABLE_SENSITIVE_VIEW:允许访问指定敏感列的明文数据。
MAX_PARTITION_NUM_PER_QUERY:限制用户单次查询的最大分区数。
CREATE_SHARED_VARS:允许用户创建共享变量。
MCP_MANAGE:MCP tools 发布权限。
MCP_DEVELOP:MCP tools 开发权限。
MCP_EXEC:MCP tools 使用权限。
4.6.
权限类别兼容性
1.30.21 和 2.00.9 版本前创建的用户,如果只拥有 DB_MANAGE 权限而没有 DB_OWNER
权限,升级到新版本就无法创建库,需要重新赋予 DB_OWNER 权限。
1.30.21 和 2.00.9 版本前创建的用户,如果被赋予 TABLE_WRITE 权限,升级到新版本后将同时拥有 TABLE_INSERT,
TABLE_UPDATE, TABLE_DELETE 权限。
1.30.21 和 2.00.9 版本起,accessType=DB_OWNER 时
grant
/
deny
/
revoke
命令中的 objs
若作用于库必须以"*"结尾,表示指定某个 dbName
的前缀范围:
login("admin", "123456")
createUser("user1","123456")
grant("user1", DB_OWNER,"*")//用户可以创建任意名称的数据库,且拥有该数据库的 DB_OWNER 权限
grant("user1", DB_OWNER,"dfs://test0*")//用户拥有以 "dfs://test0" 为前缀的数据库 DB_OWNER 权限
1.30.21 和 2.00.9 版本起,accessType=DB_MANAGE 时,使用
grant
/
deny
/
revoke
命令需确保 objs
中指定的数据库已存在,否则将报错:
login("admin", "123456")
createUser("user1","123456")
grant("user1", DB_MANAGE,"dfs://test0") => The database [dfs://test0] does
not
exist
grant("user1", DB_MANAGE, ["dfs://db1","dfs://db2"]) => The database [dfs://db1] does
not
exist
4.7.
权限回收
表级别的权限在指定表或用户删除的时候回收,库级别的权限在指定库或用户删除的时候回收,DB_OWNER 权限只在用户和该用户下所有库都删除的时候回收。
当权限操作的访问对象为共享内存表、流数据引擎时,权限不会因 server
重启或共享内存表、流数据引擎的删除而回收。当再次创建同名共享内存表、流数据引擎并对其进行访问控制时,对用户的权限操作依然生效。
例 1
: "user1" 拥有 "dfs://valuedb/pt" 表的 TABLE_READ 权限,删除 "dfs://valuedb/pt"
表后重新创建,user1 用户的 TABLE_READ 权限被回收:
login("admin", "123456")
dbName = "dfs://valuedb"
t = table(1..10
as
id , rand(100, 10)
as
val)
if
(existsDatabase(dbName)){
dropDatabase(dbName)
}
db=database(dbName, VALUE, 1..10)
pt= db.createPartitionedTable(t, "pt", "id").append!(t)
createUser("user1","123456")
grant("user1", TABLE_READ,"dfs://valuedb/pt")
login("user1", "123456")
select *
from
loadTable( "dfs://valuedb",`pt)//此时user1 拥有"dfs://valuedb/pt"表的TABLE_READ权限
login("admin", "123456")
dropTable(db,`pt)
pt= db.createPartitionedTable(t, "pt", "id").append!(t)
login("user1", "123456")
select *
from
loadTable( "dfs://valuedb",`pt)//user1用户的TABLE_READ权限被回收
例 2
: "user1" 拥有 "dfs://valuedb" 库的 DB_MANAGE 权限,删除 "dfs://valuedb"
库后重新创建,user1 用户的 DB_MANAGE 权限被回收:
login("admin", "123456")
dbName = "dfs://valuedb"
t = table(1..10
as
id , rand(100, 10)
as
val)
if
(existsDatabase(dbName)){
dropDatabase(dbName)
}
db=database(dbName, VALUE, 1..10)
pt= db.createPartitionedTable(t, "pt", "id").append!(t)
createUser("user1","123456")
grant("user1", DB_MANAGE,"dfs://valuedb")
getUserAccess("user1")
此时 user1 拥有 "dfs://valuedb" 库的 DB_MANAGE 权限。
login("admin", "123456")
if
(existsDatabase(dbName)){
dropDatabase(dbName)
}
db=database(dbName, VALUE, 1..10)
pt= db.createPartitionedTable(t, "pt", "id").append!(t)
getUserAccess("user1")
此时 user1 用户的 DB_MANAGE 权限被回收。
例 3
: "u1" 用户拥有流数据表 "trades"、"output1" 和流引擎 "agg1" 的读写权限:
login(`admin, `123456)
createUser(`u1, "111111");
enableTableShareAndPersistence(streamTable(1000:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT]),`trades)
share streamTable(1000:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT])
as
output1
agg1 = createTimeSeriesEngine(name="agg1", windowSize=600, step=600, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output1, timeColumn=`time, useSystemTime=false, keyColumn=`sym, garbageSize=50, useWindowStartTime=false)
grant("u1", TABLE_READ, "agg1")
grant("u1", TABLE_WRITE, "agg1")
grant("u1", TABLE_READ, "trades")
grant("u1", TABLE_WRITE, "trades")
grant("u1", TABLE_READ, "output1")
grant("u1", TABLE_WRITE, "output1")
getUserAccess(`u1)
重启或删除并创建同名流数据表 "trades"、"output1" 和流引擎 "agg1",此时三个对象都没有访问控制,任何用户可以对其进行读写:
login(`admin, `123456)
enableTableShareAndPersistence(streamTable(1000:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT]),`trades)
share streamTable(1000:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT])
as
output1
agg1 = createTimeSeriesEngine(name="agg1", windowSize=600, step=600, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output1, timeColumn=`time, useSystemTime=false, keyColumn=`sym, garbageSize=50, useWindowStartTime=false)
增加访问控制:
addAccessControl(`trades)
addAccessControl(output1)
addAccessControl(agg1)
此时只有用户 "u1" 和三个对象的创建者 "admin" 可以访问对象:
login(`u1, "111111")
insert into agg1 values(2018.10.08T01:01:01.785,`A,10)
insert into output1 values(2018.10.08T01:01:01.785,`A,10)
insert into trades values(2018.10.08T01:01:01.785,`A,10)
其他用户被拒绝访问:
login(`u2, "111111")
insert into agg1 values(2018.10.08T01:01:01.785,`A,10)=> No access to table [agg1]'
insert into output1 values(2018.10.08T01:01:01.785,`A,10) => No access to table [output1]'
insert into trades values(2018.10.08T01:01:01.785,`A,10) => No access to table [trades]'
5. 相关函数的权限校验
本章将介绍相关函数在 1.30.21 和 2.00.9 版本前(旧版)和后(新版)涉及的权限对比。
5.1. DDL 和 DML 相关函数
分布式表 DDL 和 DML 操作所需权限如下表所示:
操作
新版权限
旧版权限
database 新建数据库
拥有 DB_OWNER 权限用户可以创建全局或指定前缀的数据库。
拥有 DB_MANAGE 或者 DB_OWNER 权限可以新建所有名字的数据库。
database 加载已有的库
无校验
无校验
dropDatabase
DB_MANAGE 用户可以删除任意或指定数据库;DB_OWNER 用户可以删除自己创建的数据库。
DB_MANAGE 用户可以删除任何用户的数据库;DB_OWNER 用户可以删除自己创建的数据库。
createTable
DB_MANAGE 用户可以创建任意或指定数据库下的表;DB_OWNER
用户可以在自己创建的数据库下建表;DBOBJ_CREATE 用户可以创建任意或指定数据库下的表。
当前数据库的创建者或者对当前数据库有 DBOBJ_CREATE 权限的用户可以创建该数据库下的表。
dropTable
DB_MANAGE 用户可以删除任意或指定数据库下的表;DB_OWNER
用户可以在自己创建的数据库下删除表;DBOBJ_DELETE 用户可以删除任意或指定数据库下的表。
DB_OWNER 权限用户可以删除自己创建的数据库下任何用户所创建的表;DB_MANAGE
用户可以删除自己创建的表;对当前数据库有 DBOBJ_DELETE 权限的用户可以删除该库中所有表。
createPartitionedTable
DB_MANAGE 用户可以创建任意或指定数据库下的表;DB_OWNER
用户可以在自己创建的数据库下建表;DBOBJ_CREATE 用户可以创建任意或指定数据库下的表。
当前数据库的创建者或者对当前数据库有 DBOBJ_CREATE 权限的用户可以创建该数据库下的表。
addPartitions(addValuePartitions/addRangePartitions)
DB_MANAGE 用户可以增加任意或指定数据库的分区;DB_OWNER
用户可以增加自己创建的数据库的分区。
DB_MANAGE 用户可以增加任何数据库的分区;DB_OWNER 用户可以增加自己创建的数据库的分区。
newValuePartitionPolicy=add 配置项
所有拥有写入表权限的用户,写入新分区会自动添加。
所有拥有写入表权限的用户,写入新分区会自动添加。
dropPartition(deleteSchema=false)
DB_MANAGE 用户可以删除任意或指定数据库的分区;DB_OWNER 用户可以删除自己创建的数据库的分区;
DB_DELETE 权限可以删除任意或指定数据库的分区;TABLE_DELETE
权限为全局时可以删除所有数据库分区。
DB_OWNER 用户可以删除自己创建的数据库的分区;DBOBJ_DELETE
权限可以删除指定或全部数据库的分区。
dropPartition(deleteSchema=true)
DB_MANAGE 用户可以删除任意或指定数据库的分区;DB_OWNER
用户可以删除自己创建的数据库的分区。
DB_OWNER 用户可以删除自己创建的数据库的分区;DBOBJ_DELETE
权限可以删除指定或全部数据库的分区。
renameTable
DB_MANAGE 用户可以 rename 任意或指定数据库下的表;DB_OWNER 用户可以在自己创建的数据库下
rename 表;DBOBJ_CREATE 用户可以 rename 任意或指定数据库下的表。
DB_OWNER 权限用户可以 rename 自己数据库下的表;DBOBJ_DELETE 权限用户可以 rename
指定数据库下的表。
addColumn
DB_MANAGE 可以增加任意或指定数据库下表的列;DB_OWNER
用户可以增加自己创建的数据库下表的列;DBOBJ_CREATE 用户可以增加任意或指定数据库下表的列。
拥有 DB_OWNER、DB_MANAGE 权限的用户可以对自己创建的表进行
addColumn
;拥有 DBOBJ_CREATE 权限的用户可以对指定数据库下的表
addColumn
。
dropColumns!
DB_MANAGE 可以删除任意或指定数据库下表的列;DB_OWNER
用户可以删除自己创建的数据库下表的列;DBOBJ_CREATE 用户可以删除自己创建的表的列;DBOBJ_DELETE
用户可以删除任意或指定数据库下表的列。
DB_MANAGE 用户可以删除任何数据库下表的列;DB_OWNER 用户可以删除自己的数据库下表的列。
rename!
DB_MANAGE 可以 rename 任意或指定数据库下表的列;DB_OWNER 用户可以 rename
自己创建的数据库下表的列;DBOBJ_CREATE 用户可以 rename 任意或指定数据库下表的列。
DB_MANAGE 用户可以 rename 任何数据库下表的列;DB_OWNER 用户可以 rename
自己的数据库下表的列。
replaceColumn!
DB_MANAGE 用户可以 replace 任意或指定数据库下表的列;DB_OWNER 用户可以 replace
自己创建的数据库下表的列;DBOBJ_CREATE 用户可以 replace 任意或指定数据库下表的列。
DB_MANAGE 用户可以 replace 任何数据库下表的列;DB_OWNER 用户可以 replace
自己的数据库下表的列。
setColumnComment
DB_MANAGE
可以对任意或指定数据库下的表
setColumnComment
;DB_OWNER
用户可以对自己创建的数据库下表
setColumnComment
;DBOBJ_CREATE
用户可以对任意或指定数据库下表
setColumnComment
。
拥有 DB_OWNER、DB_MANAGE 权限的用户可以对自己创建的表进行
setColumnComment
;拥有 DBOBJ_CREATE
权限的用户可以对指定数据库下的表
setColumnComment
。
truncate
拥有 DBOBJ_CREATE、DB_OWNER、DB_MANAGE 权限的用户可以对自己创建的表进行
truncate
;拥有
TABLE_WRITE/TABLE_DELETE/DB_WRITE/DB_DELETE 权限的用户可以对指定表进行
truncate
;拥有 VIEW_EXEC 权限的用户可以执行视图中的
truncate
。
拥有 DBOBJ_CREATE、DB_OWNER、DB_MANAGE 权限的用户可以对自己创建的表进行
truncate
;拥有
TABLE_WRITE
权限的用户可以对指定表进行
truncate
;拥有 VIEW_EXEC
权限的用户可以执行视图中的
truncate
。
append!
拥有 DBOBJ_CREATE、DB_OWNER、DB_MANAGE 权限的用户可以对自己创建的表进行
append!
;拥有
TABLE_WRITE、TABLE_INSERT、DB_WRITE、DB_INSERT 权限的用户可以对指定表进行
append!
;拥有 VIEW_EXEC 权限的用户可以执行视图中的
append!
。
拥有 DBOBJ_CREATE、DB_OWNER、DB_MANAGE 权限的用户可以对自己创建的表进行
append!
;拥有 TABLE_WRITE 权限的用户可以对该表进行
append!
;拥有 VIEW_EXEC 权限的用户可以执行视图中的
append!
。
upsert/SQL update
拥有 DBOBJ_CREATE、DB_OWNER、DB_MANAGE 权限的用户可以对自己创建的表进行
upsert
/
update
;拥有
TABLE_WRITE、TABLE_UPDATE、DB_DELETE、DB_UPDATE 权限的用户可以对指定表进行
upsert
/
update
;拥有 VIEW_EXEC
权限的用户可以执行视图中的
upsert
/
update
。
拥有 DBOBJ_CREATE、DB_OWNER、DB_MANAGE 权限的用户可以对自己创建的表进行
upsert
/
update
;拥有
TABLE_WRITE
权限的用户可以对该表进行
upsert
/
update
;拥有
VIEW_EXEC 权限的用户可以执行视图中的
upsert
/
update
。
SQL delete
拥有 DBOBJ_CREATE、DB_OWNER、DB_MANAGE 权限的用户可以对自己创建的表进行
delete
;拥有
TABLE_WRITE、TABLE_DELETE、DB_WRITE、DB_DELETE 权限的用户可以对指定表进行
delete
;拥有 VIEW_EXEC 权限的用户可以执行视图中的
delete
。
拥有 DBOBJ_CREATE、DB_OWNER、DB_MANAGE 权限的用户可以对自己创建的表进行
delete
;拥有 TABLE_WRITE 权限的用户可以对该表进行
delete
;拥有 VIEW_EXEC 权限的用户可以执行视图中的
delete
。
注意
:在执行
addColumn
、
dropColumns!
、
renameColumns
、
replaceColumns
、
setColumnComment
、
rename!
、
renameTable
函数时,若用户所操作的表对象为其他用户所创建,需要给当前用户赋予表对象的 TABLE_READ 权限。
例如
:
在用户 user1 创建的数据库中赋予 user2 DBOBJ_CREATE 权限并创建表 pt1:
login("admin", "123456")
createUser("user1","123456",,true)
createUser("user2","123456",,true)
grant(`user1, DB_OWNER,"dfs://test*")
login("user1", "123456")
dbName = "dfs://test"
if
(existsDatabase(dbName)){
dropDatabase(dbName)
}
t = table(1..10
as
id , rand(100, 10)
as
val)
db=database(dbName, VALUE, 1..10)
grant(`user2, DBOBJ_CREATE ,"dfs://test")
login("user2", "123456")
pt1= db.createPartitionedTable(t, "pt1",`id).append!(t)
此时若 user1 想要 rename 表 pt1 某一列,会报错:
login("user1", "123456")
rename!(pt1,`val,`val1)// <NoPrivilege>Not granted to read table dfs://test/pt1'
需要赋予 user1 对 pt1 表的读权限:
login("admin", "123456")
grant(`user1, TABLE_READ,"dfs://test/pt1")
此时 rename 成功:
login("user1", "123456")
rename!(pt1,`val,`val1)
schema(loadTable(dbName,`pt1)).colDefs
------------------------------------------
name typeString typeInt extra comment
---- ---------- ------- ----- -------
id INT 4
val1 INT 4
5.2. 可见性函数
可见性函数所需权限如下表所示:
函数
新版权限
旧版权限
getClusterDFSTables
管理员可以返回当前集群中任一分布式表;其他用户执行时仅返回:(1)拥有 DB_OWNER, DB_MANAGE,
DB_READ, DB_WRITE, DB_INSERT, DB_UPDATE, DB_DELETE
权限的数据库所对应的分布式表;(2)该用户自己创建的、或拥有 TABLE_READ, TABLE_WRITE,
TABLE_INSERT, TABLE_UPDATE, TABLE_DELETE 权限的分布式表。
返回集群中所有的分布式数据库。
getAllDBs
管理员返回当前节点上所有分布式数据库;其他用户仅返回自己拥有 DB_MANAGE
权限或自己创建的分布式数据库
所有用户返回当前节点上所有分布式数据库
getTables
返回指定数据库中的所有表
返回指定数据库中的所有表
getClusterDFSDatabases
管理员返回当前集群中所有分布式数据库;其他用户返回其在集群中拥有以下权限的分布式数据库:DB_MANAGE,
DB_OWNER, DB_READ, DB_INSERT, DB_UPDATE, DB_DELETE,
DBOBJ_CREATE, DBOBJ_DELETE。
所有用户返回当前节点上所有分布式数据库
getDFSDatabases
管理员返回当前节点上所有分布式数据库;其他用户仅返回自己拥有 DB_MANAGE
权限或自己创建的分布式数据库
所有用户返回当前节点上所有分布式数据库
getDFSTablesByDatabase
管理员可以返回当前节点上任一分布式表;其他用户执行时仅返回: (1)拥有 DB_OWNER, DB_MANAGE,
DB_READ, DB_WRITE, DB_INSERT, DB_UPDATE, DB_DELETE
权限的数据库所对应的分布式表; (2)拥有 TABLE_READ, TABLE_WRITE, TABLE_INSERT,
TABLE_UPDATE, TABLE_DELETE 权限的分布式表。
所有用户返回当前节点上所有分布式数据库中的表
注意
:在新版本中,仅拥有 VIEW_EXEC 权限的用户无法获取上述函数结果。
6. 权限操作
本章将分别介绍权限操作在分布式数据库、共享内存表、流数据表、流数据引擎、视图、定时作业中的部分应用场景。
6.1. 分布式数据库
在分布式数据库中,可以通过
grant
/
deny
/
revoke
命令设置用户或者组的权限。在
库级权限类别
及
表级权限类别
节中的所有权限,可作为上述三个命令的
accessType
参数值。
其中,TABLE_READ,TABLE_WRITE,TABLE_INSERT,TABLE_UPDATE,TABLE_DELETE
权限作用范围为全局或表级。DBOBJ_CREATE,DBOBJ_DELETE,DB_READ,DB_WRITE,DB_INSERT,DB_UPDATE,DB_DELETE,DB_MANAGE,DB_OWNER
权限作用范围为全局或库级。
例 1
:赋予用户 "user1" 全局的 TABLE_READ 权限:
grant(`user1, TABLE_READ, "*")
例 2
:赋予 "user1" 用户 "dfs://valuedb" 库下 pt 表的 TABLE_READ 权限:
grant(`user1, TABLE_READ,"dfs://valuedb/pt")
例 3
:赋予 "user1" 用户 "dfs://valuedb" 库的 DBOBJ_CREATE 权限:
grant(`user1, DBOBJ_CREATE,"dfs://valuedb")
例 4
:授权某个用户对某数据库中所有表的读写权限(1.30.21 和 2.00.9 版本新增功能):
login("admin","123456")
createUser("user1","123456")
grant("user1",DB_READ,"dfs://valuedb")
grant("user1",DB_WRITE,"dfs://valuedb")
此时 user1 拥有 "dfs://valuedb" 库中所有增删改查权限。
例 5
:限制用户创建并管理以 "dfs://db0" 为前缀的数据库(1.30.21 和 2.00.9 版本新增功能):
login("admin","123456")
createUser("AlexSmith","123456")
grant("AlexSmith", DB_OWNER, "dfs://db0*")
此时若用户 "AlexSmith" 创建以 "dfs://db1" 命名的数据库,会被拒绝。
例 6
:赋予一个组中所有组员读某张表的权限,但只有部分组员有写权限:
login("admin","123456")
createUser("user1","123456")
createUser("user2","123456")
createUser("user3","123456")
createGroup("group1",["user1","user2","user3"])
grant("group1", TABLE_READ, "dfs://valuedb/pt")
createUser("user4","123456")
addGroupMember("user4","group1")
grant("user1", TABLE_WRITE, "dfs://valuedb/pt")
grant("user4", TABLE_WRITE, "dfs://valuedb/pt")
此时 user1 和 user4 拥有对 "dfs://valuedb/pt" 表的增删改查权限,user2 和 user3 只有对其查看的权限。
例 7
:可以使用
grant
或
deny
对所有对象 (以*代表)
赋予或禁止权限。例如,赋予用户 JoeFlacco 可读任何 DFS 数据表的权限:
grant("JoeFlacco",TABLE_READ,"*")
当
grant
或
deny
所有对象后,若要撤销操作,只能使用
revoke
撤销所有对象的权限,若只撤销某个指定对象的权限,则操作无效:
revoke("JoeFlacco",TABLE_READ,"dfs://db1/t1")
以上命令无效。
revoke("JoeFlacco",TABLE_READ,"*")
以上命令取消了用户 JoeFlacco 可读任何 DFS 数据表的权限。
与之类似,使用
grant
或
deny
对组赋予或禁止权限后,只能对该组使用
revoke
来取消该权限设置。若对某个组员使用
revoke
来取消该权限,则无法生效。
例 8
:有 DB_OWNER 权限的用户可以赋予别的用户对自己创建的数据库的权限。
管理员创建了两个用户,CliffLee 和 MitchTrubisky,其中用户 MitchTrubisky 拥有 DB_OWNER 的权限:
createUser(`CliffLee, "GH456$%")
createUser(`MitchTrubisky, "JI3564^")
grant(`MitchTrubisky,DB_OWNER);
MitchTrubisky 创建数据表 "dfs://dbMT/dt", 并赋予用户 CliffLee 读取该数据表的权限:
login(`MitchTrubisky, "JI3564^");
db = database("dfs://dbMT", VALUE, 1..10)
t=table(1..1000
as
id, rand(100, 1000)
as
x)
dt = db.createTable(t, "dt").append!(t)
grant(`CliffLee, TABLE_READ, "dfs://dbMT/dt");
尽管用户 CliffLee 之前没有被系统管理员赋予任何权限,但是 CliffLee 最后的权限为:可以访问 MitchTrubisky 创建的数据表
"dfs://dbMT/dt"。
6.2. 共享内存表
共享内存表会被共享到所有会话中,因此也会有权限管理的需求。系统支持对共享内存表进行写入和读取的权限管理,语法与数据库表权限管理一致。其中
accessType
仅支持 TABLE_READ 和 TABLE_WRITE,分别表示对共享内存表的读和增删改权限。
注意
:
只有创建表的用户或者管理员可以限制其他用户对该表的操作权限。
若用户使用
addAccessControl
函数限制其他用户访问该用户创建的共享表,其他用户只有被管理员赋予访问权限后,才可访问该用户创建的共享表。
如果管理员已经为其他用户
grant
/
deny
/
revoke
该表的权限,则该表自动添加权限限制,其他未经授权的用户无法再访问该表。
在集群中,通过
grant
/
deny
/
revoke
管理用户对共享内存表的权限时,权限对象必须为
"nodeAlias:tableName"。
例子
:
创建管理员 MitchTrubisky,登录 MitchTrubisky 并创建共享内存表 trades:
login(`admin, "123456");
createUser("MitchTrubisky","JI3564^",,true)
login(`MitchTrubisky, "JI3564^")
share streamTable(1000:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT])
as
trades
此时所有用户都有读写 trades 表的权限:
createUser("CliffLee","JI3564^",,false)
login("CliffLee","JI3564^")
insert into trades values(1970.01.01T00:00:00.001,`sym,1)
select *
from
trades
赋予用户 CliffLee 读取 trades 表的权限:
login(`MitchTrubisky, "JI3564^")
grant("CliffLee", TABLE_READ, "trades")
如果在集群中,权限对象必须为 "nodeAlias:tableName",例如 trades 在节点 dnode1:
grant("CliffLee", TABLE_READ, "dnode1:trades")
此时用户 CliffLee 拥有读取权限而写入则没有权限:
login("CliffLee","JI3564^")
select *
from
trades
insert into trades values(1970.01.01T00:00:00.001,`sym,1) => No access to table [trades]
如上对该表进行过第一次权限操作之后,该表自动添加权限限制。此时只有管理员和表创建者 MitchTrubisky 对该表有读写权限。
也可以取消用户 CliffLee 读取的权限:
login(`MitchTrubisky, "JI3564^")
revoke("CliffLee", TABLE_READ, "trades")
login("CliffLee","JI3564^")
select *
from
trades => No access to shared table [trades]
若在建表后希望仅自己和管理员对共享内存表有访问权限,可以使用
addAccessControl
对于表增加权限控制:
share table(1:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT])
as
st2
addAccessControl(st2)
6.3. 流数据
在集群中,通过
grant
/
deny
/
revoke
管理用户对流数据引擎或流表的权限时,权限对象必须为 "nodeAlias:tableName"。
6.3.1. 流数据引擎
用户可以使用命令
addAccessControl
限制其他用户访问流数据引擎。
例
:
用户 u1 创建流数据引擎 agg1:
login(`admin, `123456)
createUser(`u1, "111111");
createUser(`u2, "222222");
login(`u1, "111111")
share streamTable(1000:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT])
as
trades
output1 = table(10000:0, `time`sym`sumVolume, [TIMESTAMP, SYMBOL, INT])
agg1 = createTimeSeriesEngine(name="agg1", windowSize=600, step=600, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output1, timeColumn=`time, useSystemTime=false, keyColumn=`sym, garbageSize=50, useWindowStartTime=false)
给 agg1 增加访问控制:
addAccessControl(agg1)
用户 u2 注入数据到引擎失败:
login(`u2, "222222")
insert into agg1 values(2018.10.08T01:01:01.785,`A,10) // ERROR: No access to table [agg1]
给用户 u2 流数据引擎的写入权限:
login(`admin, `123456)
grant("u2", TABLE_WRITE, "agg1")
如果在集群中,权限对象必须为 "nodeAlias:tableName",例如 agg1 在节点 dnode1:
grant("u2", TABLE_READ, "dnode1:agg1")
用户 u2 访问时注入数据到引擎成功:
login(`u2, "222222")
insert into agg1 values(2018.10.08T01:01:01.785+1..600,take(`A,600),1..600)
6.3.2. 订阅流数据表到流数据表
用户订阅流数据表到流数据表时需要有订阅表的 TABLE_READ 权限和写入流数据表的 TABLE_READ 和 TABLE_WRITE 权限。
例 1
:u1 用户创建发布流数据表 trades 和订阅流数据表 output1 并调用
addAccessControl
对表进行访问管理:
login(`admin, `123456)
createUser(`u1, "111111");
login(`u1, "111111")
share streamTable(1000:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT])
as
trades
share streamTable(10000:0, `time`sym`sumVolume, [TIMESTAMP, SYMBOL, INT])
as
output1
addAccessControl(`trades)
addAccessControl(`output1)
u2 用户被赋予 trades 表的 TABLE_READ 权限和 output1 表的 TABLE_READ 和 TABLE_WRITE
权限后可以成功订阅:
login(`admin, `123456)
grant("u2", TABLE_READ, "trades")
grant("u2", TABLE_WRITE, "output1")
grant("u2", TABLE_READ, "output1")
login(`u2, "222222")
subscribeTable(tableName="trades", actionName="agg1", offset=0, handler=append!{output1}, msgAsTable=true);
例 2
:在集群中,权限对象必须为 "nodeAlias:tableName" 。
在远程节点 NODE2 创建发布表 trades 并进行权限管理:
login(`admin, `123456)
def
pubTable(){
share (streamTable(1000:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT]), `trades)
addAccessControl(`trades)
}
rpc(`NODE2,pubTable)
share streamTable(10000:0, `time`sym`sumVolume, [TIMESTAMP, SYMBOL, INT])
as
output1
本地节点用户订阅需要 NODE2 节点 trades 表的 TABLE_READ 权限:
createUser(`u1, "111111");
grant("u1", TABLE_READ, "NODE2:trades")
login(`u1, "111111")
subscribeTable(server=`NODE2,tableName="trades", actionName="agg1", offset=0, handler=append!{output1}, msgAsTable=true);
6.3.3. 订阅流数据表到分布式表
用户订阅流数据表到分布式表时需要分布式表的 TABLE_WRITE 权限。
例
:管理员创建发布表 trades 和订阅分布式数据库 "dfs://valuedb/pt":
login(`admin, `123456)
dbName = "dfs://valuedb"
t = table(10000:0, `time`sym`sumVolume, [TIMESTAMP, SYMBOL, INT])
insert into t values(2018.10.08T01:01:01.785+1..600,take(`A,600),1..600)
if
(existsDatabase(dbName)){
dropDatabase(dbName)
}
db=database(dbName, VALUE, 1..10)
pt= db.createPartitionedTable(t, "pt", "sumVolume").append!(t)
share streamTable(1000:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT])
as
trades
授权 u2 用户订阅分布式表的 TABLE_WRITE 权限:
createUser(`u2, "222222");
grant("u2", TABLE_WRITE,"dfs://valuedb/pt")
u2 成功订阅到数据:
login(`u2, "222222")
def
saveTradesToDFS(mutable dfsTrades, msg): dfsTrades.append!(msg)
subscribeTable(tableName="trades", actionName="agg1", offset=0, handler=saveTradesToDFS{pt}, msgAsTable=true);
login(`admin, `123456)
select *
from
loadTable(dbName,`pt)
6.4. 视图权限
函数视图
提供了一种灵活的方式来控制用户访问数据库和表。在视图的基础上,函数视图提供了函数功能,可以同时访问数据库并进行相关计算。
注意
:
只有系统管理员有创建和删除函数视图的权限。用户即使不具备读写数据库原始数据的权限,也可通过执行函数视图,间接访问数据库,得到所需计算结果
如果函数视图和本地的函数重名,调用时系统会解析为本地函数
某些操作只需要 VIEW_EXEC 权限就可以在 FunctionView 中执行,详见表
DDL 和 DML 相关函数
VIEW_EXEC 的权限作用对象(objs)由高到低分为全局 (*)、命名空间
(<namespace>::*)、函数视图三个层级。权限可以设置为对所有函数视图生效,或针对特定函数视图生效,也可以按命名空间进行批量管理。当命名空间存在多层嵌套时,权限必须设置到
module 一层,暂不支持在更高层次的命名空间进行批量权限管理。
例 1
:管理员定义一个函数视图:
def
countTradeAll(){
return
exec
count(*)
from
loadTable("dfs://TAQ","Trades")
}
addFunctionView(countTradeAll)
grant("NickFoles",VIEW_EXEC,"countTradeAll")
以用户名 NickFoles 登录,执行视图 "countTradeAll":
countTradeAll()
在此例中,虽然用户 NickFoles 没有访问表 "dfs://TAQ/Trades" 的权限,但是可以运行函数视图 "countTradeAll"
获取表的行数。
例 2
:函数视图也可以带参数。用户在使用的时候可以输入参数获取相应的结果。
创建一个函数视图,获取某一个股票在某一天的所有交易记录:
def
getTrades(s, d){
return
select *
from
loadTable("dfs://TAQ","Trades") where sym=s, date=d
}
addFunctionView(getTrades)
grant("NickFoles",VIEW_EXEC,"getTrades")
同样在此例中,用户 NickFoles 没有访问表"dfs://TAQ/Trades"的权限,但是可以执行视图“getTrades”,指定股票代码 IBM
和日期 2018.07.09,获得 IBM 在 2018.07.09 这一天的所有交易记录:
getTrades("IBM", 2018.07.09)
例 3
:通过命名空间对函数视图进行批量管理。
在 [home]/modules/dir1/myModule.dos 文件中定义函数,并在文件第一行声明为模块,文件内容如下:
module dir1::myModule
def
f1(){
print
"dir1::myModule::f1"
}
def
f2(){
print
"dir1::myModule::f2"
}
使用 use 语句引用后,可通过
addFunctionView
函数一次将该模块中所有函数添加为函数视图。
use dir1::myModule
addFunctionView(moduleName="dir1::myModule")
getFunctionViews()
name
body
dir1::myModule::f1
def f1(){ print("dir1::myModule::f1")}
dir1::myModule::f2
def f2(){ print("dir1::myModule::f2")}
为用户 user1 授权执行 dir1::myModule 命名空间下的所有函数视图
grant(userId="user1", accessType=VIEW_EXEC, objs="dir1::myModule::*")
禁止用户 user2 执行 dir1::myModule 命名空间下的所有函数视图
deny(userId="user2", accessType=VIEW_EXEC, objs="dir1::myModule::*")
命名空间必须明确到 module 层级。例如 dir1::myModule 模块,不能在 dir1 层级进行权限管理。
grant(userId="user1", accessType=VIEW_EXEC, objs="dir1::*")// Error:The Module [dir1::*] does not exist.
6.5. 定时作业权限
定时作业是指用户指定在特定的时间,以特定的频率执行一系列任务,多用于批处理类业务场景。
当用户创建定时作业(函数
scheduleJob
)时,若作业中包含库/表的读写或修改操作,不需要具备相关的权限也能成功创建。但执行定时作业时,需要具备与对象相关的权限,否则无法执行
系统管理员可以
deleteScheduledJob
删除其他用户定时作业,非管理员用户只能删除自己创建的定时作业
login("NickFoles","AB123!@")
def
readTable(){
read_t1=loadTable("dfs://db1","t1")
return
exec
count(*)
from
read_t1
}
scheduleJob("readTableJob","read DFS table",readTable,minute(now()),date(now()),date(now())+1,'D');
不管 NickFoles 有没有读 "dfs://db1/t1" 的权限,"readTable" 任务都能设置成功。
在 "readTable" 任务实际运行时,如果用户 NickFoles 有读 "dfs://db1/t1" 的权限,则成功执行,否则鉴权失败。
6.6. 脚本执行权限
SCRIPT_EXEC,TEST_EXEC 权限作用范围为全局。
用户执行
run
函数,或在客户端运行脚本都需要 SCRIPT_EXEC 权限:
login(`admin, `123456)
createUser(`user1, "123456");
grant(`user1,SCRIPT_EXEC)
login(`user1, "123456")
run("test.txt")
用户执行
test
函数,或在客户端执行 unittest 都需要 TEST_EXEC 权限:
login(`admin, `123456)
createUser(`user1, "123456");
grant(`user1,TEST_EXEC)
login(`user1, "123456")
test("test.txt")
6.7. 内存限制权限
grant
指定
accessType
= QUERY_RESULT_MEM_LIMIT
来限制某个用户查询返回结果的内存上限和
accessType
= TASK_GROUP_MEM_LIMIT
限制发送的批量子查询占用的内存上限,等同于
setMemLimitOfQueryResult
函数和
setMemLimitOfTaskGroupResult
函数,区别在于
grant
只对指定用户生效(暂不支持用户组),
setMemLimitOfQueryResult
函数和
setMemLimitOfTaskGroupResult
函数对所有用户生效。
下述脚本限制用户“AlexSmith”查询时,查询结果所占用的内存大小不能超过 4 GB:
grant("AlexSmith", QUERY_RESULT_MEM_LIMIT, 4)
下述脚本限制用户“AlexSmith”查询时,发送的批量子查询占用的内存不能超过 4 GB:
grant("AlexSmith", TASK_GROUP_MEM_LIMIT, 4)
6.8. 敏感列权限
管理员用户、库表的创建者以及具有 DB_MANAGE 权限的用户可通过 DB_SENSITIVE_VIEW 或 TABLE_SENSITIVE_VIEW
权限类别对用户是否有权访问敏感列的明文数据进行管理。其中,DB_SENSITIVE_VIEW
的权限作用范围为全局或库级,TABLE_SENSITIVE_VIEW 的权限作用范围为全局、表级或列级。
例 1:赋予用户 user1 全局的 DB_SENSITIVE_VIEW 权限
grant(`user1, DB_SENSITIVE_VIEW, "*")
例 2:赋予用户 user1 对 “dfs://sensitive” 库的 DB_SENSITIVE_VIEW 权限
grant(`user1, DB_SENSITIVE_VIEW, "dfs://sensitive")
例 3:赋予用户 user1 对 “dfs://sensitive/pt” 表的 TABLE_SENSITIVE_VIEW 权限
grant(`user1, TABLE_SENSITIVE_VIEW, "dfs://sensitive/pt")
例 4:赋予用户 user1 对 “dfs://sensitive/pt” 表中列 col1 的 TABLE_SENSITIVE_VIEW 权限
grant(`user1, TABLE_SENSITIVE_VIEW, "dfs://sensitive/pt:col1")
6.9. 查询分区限制权限
grant
指定
accessType
= MAX_PARTITION_NUM_PER_QUERY
,可限制某个用户单次查询的最大分区数。该权限的作用与配置项 maxPartitionNumPerQuery
相同,区别在于:
grant
仅对指定用户或用户组限制,而配置项对所有用户生效。
用户单次查询的最大分区数按以下规则确定:
若为用户设置了 MAX_PARTITION_NUM_PER_QUERY 权限,则以该值为准;
否则,若用户所属组中存在设置该权限的情况,则取各组设置值的最大值;
若以上均未设置,则使用配置项 maxPartitionNumPerQuery 的值。
以下脚本设置用户 “AlexSmith“ 单次查询最多 100 个分区。
grant("AlexSmith", MAX_PARTITION_NUM_PER_QUERY, 100)
以下脚本取消对用户 “AlexSmith“ 的 MAX_PARTITION_NUM_PER_QUERY 权限限制。
revoke("AlexSmith", MAX_PARTITION_NUM_PER_QUERY)
6.10. MCP 权限
MCP_MANAGE 限制用户发布和撤销发布 MCP tools,仅具备该权限的用户可调用
publishMCPTools
,
withdrawMCPTools
。
MCP_DEVELOP 限制用户开发 MCP tools,仅具备该权限的用户可调用
addMCPTool
,
updateMCPTool
,
dropMCPTool
,
callMCPTool
。
MCP_EXEC 限制用户通过 MCP server 调用发布的 tool。可作用于全部
tool(
tools/*
),或仅针对指定
tool(
tools/<toolName>
)。
例 1:赋予用户 user1 MCP_MANAGE 权限
grant(`user1, MCP_MANAGE)
例 2:赋予用户 user1 MCP_DEVELOP 权限
grant(`user1, MCP_DEVELOP)
例 3:赋予用户 user1 调用除 myTool 以外所有 tool 的执行权限
grant(`user1, MCP_EXEC, "tools/*")
deny(`user1, MCP_EXEC, "tools/myTool")
7. 使用 HTTPS 实现安全通信
DolphinDB 支持使用 HTTPS 安全协议与 web notebook、VSCode 等编辑器进行通信。
7.1. 使用 HTTPS 配置
DolphinDB 提供两种配置 HTTPS 的方法:
在控制节点的配置文件中添加
enableHTTPS=true
在启动控制节点的命令行添加
-enableHTTPS
true
./dolphindb -enableHTTPS true -home master -publicName www.psui.com -mode controller -localSite 192.168.1.30:8500:rh8500 -logFile ./log/master.log
7.2. HTTPS 证书设置
DolphinDB
使用服务端证书验证的安全策略。默认情况下,会生成自制证书,客户需要安装服务端的证书,否则浏览器提示不安全连接。在集群环境中,每个节点分布在不同的物理机器上,每台物理
server 需要一份证书,因此控制节点和代理节点需要生成证书,数据节点使用同一个物理服务器上代理节点生成的证书。用户也可购买经过第三方认证的证书。
7.2.1. 第三方认证证书
将第三方证书重命名为 server.crt,并且拷贝到控制节点和代理节点的
home
目录下的
keys
文件夹中,若
keys
文件夹不存在,则需手动创建。由于第三方证书经过公认的权威授权机构颁布,所以浏览器默认信任该证书,不需要再手动安装。绝大部分应用场景适合使用此方式。
7.2.2. 安装自制证书
在小型封闭集群内部通信时,用户也可以使用自制证书进行 OPENSSL 安全通信,具体过程如下:
把 publicName 设置为计算机的域名。
在集群控制节点的配置文件 (
controller.cfg
)
中加上
publicName=www.ABCD.com
,或者在命令行窗口启动控制节点时加上
-publicName www.ABCD.com
。
检查证书是否生成。
启动控制节点,并且检查证书文件
server.crt
和服务器的独立密钥
serverPrivate.key 是否存在主目录的
keys
目录下。
把自签名证书安装到浏览器的证书颁发机构,例如:
在 Google Chrome,选择 设置->隐私和安全->安全->管理设备证书->Import,把
server.crt
导入。
在浏览器地址栏中输入 "https://www.ABCD.com:8500/" 连接到 DolphinDB 集群管理器,其中
8500 是控制节点的端口。
8. 支持 SSO (Single Sign On)
DolphinDB 的控制节点通过 OpenSSL ticket 为客户端提供安全通信支持。
DolphinDB 提供两个用于 SSO 的 API 函数:
getAuthenticatedUserTicket()
获取当前登录用户的加密 ticket
authenticateByTicket(ticket)
使用上面获取的 ticket 登录系统
DolphinDB 的开发者可以方便安全的使用这些接口来对系统进行扩展。
FILE:references/doc_4728.md
# addReactiveMetrics
**URL**: https://docs.dolphindb.cn/zh/funcs/a/addreactivemetrics.html
**来源**: DolphinDB 官方文档
---
addReactiveMetrics
语法
addReactiveMetrics(name, metricNames, metrics)
详情
动态增加 narrowReactiveStateEngine 的计算指标。更新后的计算指标在引擎后续注入的数据时生效。
参数
name
字符串,表示需要增加指标的 narrowReactiveStateEngine 的名称。
metricNames
字符串标量或向量,表示 narrowReactiveStateEngine 增加的计算指标的名称。
metrics
以元代码的格式表示计算指标,支持输入元组,表示流数据引擎增加的计算指标。计算指标与
metricNames
指定的名称一一对应。
例子
dummy = streamTable(1:0, ["securityID1","securityID2","securityID3","createTime","updateTime","upToDatePrice","qty","value"], [STRING,STRING,STRING,TIMESTAMP,TIMESTAMP,DOUBLE,DOUBLE,INT])
outputTable = streamTable(1:0,["securityID1","securityID2","securityID3","createTime","updateTime","metricNames","factorValue"], [STRING,STRING,STRING, TIMESTAMP,TIMESTAMP,STRING,DOUBLE])
factor = [<createTime>, <updateTime>,<cumsum(qty)>]
Narrowtest = createNarrowReactiveStateEngine(name="narrowtest1",metrics=factor,metricNames="factor1",dummyTable=dummy,outputTable=outputTable,keyColumn=["securityID1","securityID2","securityID3"])
num = 5
tmp = table(take("A" + lpad(string(1..4),4,"0"),num) as securityID1,take("CC.HH" + lpad(string(21..34),4,"0"),num) as securityID2,take("FFICE" + lpad(string(13..34),4,"0"),num) as securityID3, 2023.09.01 00:00:00+(1..num) as createTime, 2023.09.01 00:00:00+(1..num) as updateTime,100.0+(1..num) as upToDatePrice, 130.0+(1..num) as qty,take(1..3,num) as value)
Narrowtest.append!(tmp)
select * from outputTable
securityID1
securityID2
securityID3
createTime
updateTime
metricNames
factorValue
A0001
CC.HH0021
FFICE0013
2023.09.01T00:00:01.000
2023.09.01T00:00:01.000
factor1
131
A0002
CC.HH0022
FFICE0014
2023.09.01T00:00:02.000
2023.09.01T00:00:02.000
facto1
132
A0003
CC.HH0023
FFICE0015
2023.09.01T00:00:03.000
2023.09.01T00:00:03.000
facto1
133
A0004
CC.HH0024
FFICE0016
2023.09.01T00:00:04.000
2023.09.01T00:00:04.000
facto1
134
A0001
CC.HH0025
FFICE0017
2023.09.01T00:00:05.000
2023.09.01T00:00:05.000
facto1
135
metrics = [<cumavg(upToDatePrice)>]
addReactiveMetrics("narrowtest1", "factor2", metrics)
//新增计算指标后,再次向引擎注入数据,则会输出更新后的指标计算结果
tmp1 = table("A5" as securityID1,"CC.HH0033" as securityID2,"FFICE0034" as securityID3, 2023.09.01 00:00:11 as createTime, 2023.09.01 00:00:09 as updateTime,59 as upToDatePrice,100 as qty,13 as value)
Narrowtest.append!(tmp1)
select * from outputTable where securityID1="A5"
securityID1
securityID2
securityID3
createTime
updateTime
metricNames
factorValue
A5
CC.HH0033
FFICE0034
2023.09.01T00:00:11.000
2023.09.01T00:00:09.000
facto1
100
A5
CC.HH0033
FFICE0034
2023.09.01T00:00:11.000
2023.09.01T00:00:09.000
facto2
59
相关函数:
createNarrowReactiveStateEngine
,
getReactiveMetrics
FILE:references/doc_4738.md
# chiSquareTest
**URL**: https://docs.dolphindb.cn/zh/funcs/c/chiSquareTest.html
**来源**: DolphinDB 官方文档
---
chiSquareTest
语法
chiSquareTest(X, [Y])
详情
如果
X
是一个向量,进行 Chi-square Goodness-of-fit 检验
X
是否与
Y
的概率分布一致;如果
X
是矩阵或表,对
X
进行 Pearson's Chi-squared 检验。
参数
X
是一个数值向量、矩阵或表。
如果
X
是一个向量,那么
Y
是一个与
X
长度相同的向量;如果
X
是矩阵或表,那么无需指定
Y
。
返回值
返回一个字典,包含以下 key:
pValue:p 值
df:自由度
chiSquaredValue:chi-square 统计量
method:如果
X
为向量,
method
为字符串 "Chi-square goodness of fit test";如果
X
为矩阵或表,
method
为字符串 "Pearson's Chi-squared test"。
例子
例1.
X
是一个向量。
x=rand(10.0,50)
y=rand(10.0,50)
chiSquareTest(x,y);
// output
pValue->0
df->49
chiSquaredValue->947.388015
method->Chi-square goodness of fit test
例2.
X
是一个矩阵。
x = matrix([762, 484], [327, 239], [468, 477])
x.rename!(`female`male, `Democrat`Independent`Republican)
x;
Democrat
Independent
Republican
female
762
327
468
male
484
239
477
chiSquareTest(x);
// output
pValue->2.953589E-7
df->2
chiSquaredValue->30.070149
method->Pearson's Chi-squared test
FILE:references/doc_475.md
# appendMsg
**URL**: https://docs.dolphindb.cn/zh/funcs/a/appendMsg.html
**来源**: DolphinDB 官方文档
---
appendMsg
语法
appendMsg(engine, msgBody, msgId)
详情
当流数据引擎启用快照机制(snapshot)且未开启 RaftGroup 时,订阅函数
subscribeTable
的handler参数必须为
appendMsg
函数,将数据写入流数据引擎。
参数
engine
是内置流数据引擎,即
createReactiveStateEngine
等函数返回的抽象表对象。
msgBody
是将要写入流数据引擎的消息。
msgId
是写入数据之前,流数据引擎已接收到的最后一条消息的 ID。ID 从订阅发布的第一条消息开始计数。
例子
share streamTable(10000:0,`time`sym`price, [TIMESTAMP,SYMBOL,DOUBLE]) as trades
output1 =table(10000:0, `time`sym`avgPrice, [TIMESTAMP,SYMBOL,DOUBLE]);
engine1 = createTimeSeriesEngine(name=`engine1, windowSize=100, step=50, metrics=<avg(price)>, dummyTable=trades, outputTable=output1, timeColumn=`time, keyColumn=`sym, snapshotDir="C:/DolphinDB/Data/snapshotDir", snapshotIntervalInMsgCount=100)
subscribeTable(tableName="trades", actionName="engine1", offset=0, handler=appendMsg{engine1}, msgAsTable=true, handlerNeedMsgId=true)
n=500
timev=2021.03.12T15:00:00.000 + (1..n join 1..n)
symv = take(`A, n) join take(`B, n)
pricev = (100+cumsum(rand(1.0,n)-0.5)) join (200+cumsum(rand(1.0,n)-0.5))
t=table(timev as time, symv as sym, pricev as price).sortBy!(`time)
trades.append!(t)
select * from output1
FILE:references/doc_4758.md
# rank
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rank.html
**来源**: DolphinDB 官方文档
---
rank
语法
rank(X, [ascending=true],
[groupNum], [ignoreNA=true], [tiesMethod='min'], [percent=false],
[precision])
详情
基于
ascending
指定的排序顺序,返回
X
中每个元素的排名(从0开始排序)。
若
X
是向量,返回一个与
X
等长的向量:
如果指定了
groupNum
,则将排序后的
X
分成
groupNum
个组。返回
X
中每个元素对应的组编号(从0开始编号)。
注:
若
X
不能被均分,则前 mod(size(X), groupNum) 组将多存放一个元素。例如
X
的元素个数为6,
groupNum
=
4,排名后的第1和2个元素属于组0,第3和4个元素属于组1,第5个和第6个元素分别属于组2和组3。
若
X
中相同元素分别属于不同的组,则所有相同元素返回最小的组号。
如果
ignoreNA
= true,则 NULL 值不参与排序,结果中 NULL
值的排名为空。
若
X
是矩阵或表,在每列内进行上述计算,返回一个与
X
维度相同的矩阵或表。
若
X
是字典,则按字典的值进行排序,并返回各元素的排名。
参数
X
是一个向量、矩阵、表或字典。
ascending
是一个布尔值,表示是否按升序排序。默认值是 true。
groupNum
是一个正整数,指定该参数后,元素将分成指定数量的组,按组进行排序。
ignoreNA
是一个布尔值,表示是否忽略 NULL 值,默认值为 true。false 表示 NULL 作为最小值参与排名。
tiesMethod
是一个字符串,表示如何对具有相同值的元素进行排名。
'min' 表示取最小排名。
'max' 表示取最大排名。
'average' 表示取排名的均值。
'first' 表示按照原数据的顺序排名。
percent
是一个布尔值,表示是否以百分比形式显示返回的排名。
precision
是一个 [1, 15] 范围内的整数,用于设置参与排序的值的精度。若两个值之差的绝对值小于等于 10^(-precision)
,则认为两值相等。
注:
指定
precision
参数后,
X
只能是数值型对象。且
tiesMethod
不能指定为 'first'。
返回值
INT 类型的向量。
例子
rank(45 16 32 21);
// output
[3,0,2,1]
rank(45 16 32 21, false);
// output
[0,3,1,2]
rank(9 1 6 1 3 3);
// output
[5,0,4,0,2,2]
// 两个相同的元素有相同的排名
rank(X=9 5 4 8 1 3 6 2 7, groupNum=3);
// output
[2,1,1,2,0,0,1,0,2]
rank(X=9 5 4 8 1 3 6 2 7, groupNum=6)
// output
[5,2,1,4,0,1,2,0,3]
rank(X=9 5 4 8 1 3 6 2 7, ascending=false, groupNum=3);
// output
[0,1,1,0,2,2,1,2,0]
rank(X=1 2 2 3, tiesMethod='min');
// output
[0,1,1,3]
rank(X=1 2 2 3, tiesMethod='average');
// output
[0,1.5,1.5,3]
rank(X=1 2 2 3, tiesMethod='first');
// output
[0,1,2,3]
rank(1 NULL NULL 3);
// output
[0,,,1]
rank(X=1 NULL NULL 3, ignoreNA=false);
// output
[2,0,0,3]
t=table(1 1 1 2 2 2 2 as id, 3 5 4 6 2 7 1 as x)
t
id
x
1
3
1
5
1
4
2
6
2
2
2
7
2
1
select *, rank(x) from t context by id;
id
x
rank_x
1
3
0
1
5
2
1
4
1
2
6
2
2
2
1
2
7
3
2
1
0
rank(dict(`a`b`c, [4, 1, 2],true))
// output: [2, 0, 1]
FILE:references/doc_4768.md
# gaussianKdePredict
**URL**: https://docs.dolphindb.cn/zh/funcs/g/gaussiankdepredict.html
**来源**: DolphinDB 官方文档
---
gaussianKdePredict
语法
gaussianKdePredict(model,X)
详情
gaussianKde
对应的预测函数。使用其生成的模型对数据进行预测。
参数
model
字典类型,表示
gaussianKde
生成的字典。
X
数值向量、矩阵、元组或表类型,表示需要预测的数据。其维度必须和
gaussianKde
的数据集合的维度相同。
返回值
函数返回一个浮点型向量,大小和
X
的行数相同,表示
X
中每个数据点的预测结果。
例子
下例中先使用
gaussianKde
生成模型。传入指定的
trainset.txt
,使用高斯核估计来预测数据的概率密度。然后调用
predict
函数,通过模型和传入的
testset.txt
文件生成对应的预测结果。
trainData = loadText("trainset.txt"," ");
testData = loadText("testset.txt"," ");
model = gaussianKde(trainData)
gaussianKdePredict(model, testData)
/*
->[0.0623,0.0730,0.0336,0.0030,0.0001,0.0552....]
*/
相关函数:
gaussianKde
FILE:references/doc_4769.md
# tmcount
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmcount.html
**来源**: DolphinDB 官方文档
---
tmcount
语法
tmcount(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内统计
X
中的非 NULL 元素个数。
返回值
INT 类型向量。
例子
T = 1 1 1 2 5 6
X = 1 4 NULL -1 NULL 4
m = table(T as t,X as x)
select *, tmcount(t, x, 3) from m
t
x
tmcount_t
1
1
1
1
4
2
1
2
2
-1
3
5
0
6
4
1
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.09
X = NULL 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmcount(t, x, 3d) from m
t
x
tmcount_t
2021.01.02
0
2021.01.02
4
1
2021.01.04
1
2021.01.05
-1
1
2021.01.07
2
2
2021.01.09
4
2
select *, tmcount(t, x, 1w) from m
t
x
tmcount_t
2021.01.02
0
2021.01.02
4
1
2021.01.04
1
2021.01.05
-1
2
2021.01.07
2
3
2021.01.09
4
3
相关函数:
mcount
,
count
FILE:references/doc_4785.md
# writeLine
**URL**: https://docs.dolphindb.cn/zh/funcs/w/writeLine.html
**来源**: DolphinDB 官方文档
---
writeLine
语法
writeLine(handle, string,
[windowsLineEnding])
详情
在给定的句柄中写一行。函数自动将一个行分隔符添加到字符串结尾。所以字符串不应该以行分隔符结尾。如果该操作成功,函数返回
1;否则,将抛出一个 IOException。
参数
handle
句柄,指向目标文件或套接字的对象。
string
字符串,表示要写入的一行文本,末尾不需要加换行符。
windowsLineEnding
可选参数,布尔值,用于指定是否强制使用 Windows 风格的换行符(
\r\n)。如果未指定该参数,换行符的默认行为如下:
如果句柄是一个套接字,行结束符是 \r\n
如果句柄是一个文件,且操作系统不是 Windows,行结束符是 \n
如果句柄是一个文件,且操作系统是 Windows,行结束符是 \r\n
返回值
数字 1。
例子
x=`IBM`MSFT`GOOG`YHOO`ORCL
eachRight(writeLine, file("test.txt","w"), x);
// output
[1,1,1,1,1]
fin = file("test.txt")
do{
x=fin.readLine()
if(x.isVoid()) break
print x
}
while(true);
// output
IBM
MSFT
GOOG
YHOO
ORCL
FILE:references/doc_4788.md
# deny
**URL**: https://docs.dolphindb.cn/zh/funcs/d/deny.html
**来源**: DolphinDB 官方文档
---
deny
语法
deny(userId|groupId, accessType, [objs])
详情
拒绝某个用户或某个组的权限。管理员可以通过该命令拒绝用户所有权限(
accessType
),但普通用户在拥有相关的 OWNER
权限后,只能通过该命令拒绝以下权限:TABLE_READ, TABLE_WRITE, TABLE_INSERT, TABLE_UPDATE, TABLE_DELETE,
DB_READ, DB_WRITE, DB_INSERT, DB_UPDATE, DB_DELETE, DBOBJ_DELETE, DBOBJ_CREATE 和
VIEW_EXEC。
可被拒绝的权限类型,参见
grant
。
注:
该函数可在控制节点、数据节点和计算节点运行。
参数
userId
|
groupId
是表示用户名或组名的字符串。
accessType
权限类型/内存限制。
objs
标量或向量,表示权限类型的应用对象/约束规则。也可以指定为 *,表示全局。
当
accessType
指定为 COMPUTE_GROUP_EXEC 时,
objs
必须为对应的计算组名。
注:
管理共享内存表、流数据表或流计算引擎的权限时,
objs
必须为 "tableName@nodeAlias"
或"nodeAlias:tableName"。
管理 IMOLTP 引擎库表权限时,
objs
必须为 "oltp://database/table@nodeAlias" 或
"oltp://database@nodeAlias"。
accessType
和
objs
的取值请参照
用户权限管理
权限类型表。
返回值
无。
例子
组 "research" 中的所有成员都不能向表 dfs://db1/t1 中写入数据:
deny(`research, TABLE_WRITE, "dfs://db1/t1")
组 "research" 中的所有成员都不能在数据库 dfs://db1 和 dfs://db2 中创建表:
deny("research", DBOBJ_CREATE, ["dfs://db1","dfs://db2"])
用户 "AlexSmith" 不能删除数据库:
deny("AlexSmith", DB_MANAGE)
用户 "AlexSmith" 不能执行脚本:
deny("AlexSmith", SCRIPT_EXEC)
用户 "AlexSmith" 不能测试脚本:
deny("AlexSmith", TEST_EXEC)
FILE:references/doc_4793.md
# unlockUser
**URL**: https://docs.dolphindb.cn/zh/funcs/u/unlockUser.html
**来源**: DolphinDB 官方文档
---
unlockUser
语法
unlockUser(userId)
详情
解锁用户
userId
。该函数仅限管理员用户调用,调用时须开启配置项
enhancedSecurityVerification
。
参数
userId
是表示用户名的字符串。
返回值
无。
例子
unlockUser("user1")
相关函数:
lockUser
FILE:references/doc_4800.md
# quadprog
**URL**: https://docs.dolphindb.cn/zh/funcs/q/quadprog.html
**来源**: DolphinDB 官方文档
---
quadprog
语法
quadprog(H, f, [A], [b], [Aeq], [beq])
详情
求二元目标函数在线性约束条件下的最优解。具体模型如下:
返回结果是具有两个元素的元组。第一个元素是目标函数的最小值,第二个元素是目标函数取最小值时,x的取值。
参数
H
是二次规划中的二次项矩阵,且必须是对称正定矩阵。
f
是二次项规划中的一次项向量。
A
是线性不等约束的系数矩阵。
b
是线性不等约束的右端向量。
Aeq
是线性等式约束的系数矩阵。
beq
是线性等式约束的右端向量。
H
,
A
和
Aeq
必须是列数相同的矩阵。
f
,
b
和
beq
是向量。
返回值
长度为2的元组。第一个元素是目标函数的最小值。第二个元素是使目标函数达到最小值的变量值。
例子
求以下目标函数的最小值。
例1:没有约束条件
H=matrix([2 -2,-2 6])
f=[-5,4]
x=quadprog(H,f);
x[0];
// output
-6.375
x[1];
// output
[2.75,0.25]
例2:添加不等式约束条件:
H=matrix([2 -2,-2 6])
f=[-5,4]
A=matrix([1 -1 6, 1 3 1])
b=[10, 8, 5]
x=quadprog(H,f,A,b);
x[0];
// output
-4.092975
x[1];
// output
[0.904959, -0.429752]
例3:添加不等式约束条件和等式约束条件:
H=matrix([2 -2,-2 6])
f=[-5,4]
A=matrix([1 -1 6, 1 3 1])
b=[10, 8, 5]
Aeq=matrix([1],[2])
beq=[1]
x=quadprog(H,f,A,b,Aeq,beq);
x[0];
// output
-3.181818
x[1];
// output
[0.818182,0.090909]
目标函数在没有约束条件的情况下,最优解的值最小。约束条件越多,最优解的值越大。
相关函数:
linprog
,
scs
FILE:references/doc_4810.md
# polyPredict
**URL**: https://docs.dolphindb.cn/zh/funcs/p/polyPredict.html
**来源**: DolphinDB 官方文档
---
polyPredict
语法
polyPredict(model, X)
别名:
poly1d
详情
利用给定的多项式系数
z
和自变量
x
,计算因变量的值。
参数
model
数值型向量,表示多项式系数,以升幂排列,不能包含空值。
x
数值型标量或向量,表示自变量数据点,不能包含空值。
返回值
一个和
x
等长的数值型向量。
例子
例子
一个 3 次多项式
2x^3 + 3x^2 + 4x +
5
,它的系数按升幂排序的向量是[5,4,3,2]:
model = [5,4,3,2]
x = [2.0,5.0,3.0,3.0,4.0,5.0]
y = poly1d(model,x)
y
//output: [41,350,98,98,197,350]
使用上述代码中的 model 和 y,通过
polyFit
函数可以计算出 3
次多项式的系数(按升幂排序)。
polyFit(x,y,3)
//output:[5,4,3,2]
FILE:references/doc_4815.md
# delete
**URL**: https://docs.dolphindb.cn/zh/progr/sql/delete.html
**来源**: DolphinDB 官方文档
---
delete
delete 语句用于删除表中的记录。
delete 语句不仅可用于内存表,也可用于 DFS 表(分布式表与维度表)。请注意,对分布式表使用 delete 语句时,系统把要删除记录所在的分区整体删除后更新;对维度表使用
delete 语句时,系统将该表删除后更新。因此对 DFS 表使用 delete
语句仅适用于低频删除任务,例如分钟级删除任务,不适用于高频删除任务,例如毫秒级删除任务。
删除采取了多版本的方式,并且支持事务。系统会创建一个新的版本以存储新的数据。提交事务之前,其他 SQL
语句仍然访问旧版本的数据。若删除涉及多个分区,只要其中某一个分区删除失败,系统会回滚所有分区的修改。
在
2.00.1
及以上版本中,delete 支持 map 子句,即支持将 delete 语句在每个分区内分别执行。若 where
子句中使用结果与次序有关的函数,如: isDuplicated, first, firstNot 等,且涉及到多个分区,则必须使用 map 关键字。
自 3.00.0 版本起,支持 catalog 结构。
语法
方法一
delete from table_name
where condition(s);
如果没有使用 where 条件,删除表中所有记录。
方法二
delete table_name from table_joiner(table_names)
[where condition(s)];
结合 join 子句删除数据时:
支持 ej 和 lj
要删除的表必须作为 join 的左表
如果没有指定 where 条件,将删除表左表中所有与右表连接成功的数据
对于嵌套 join 的情况,只允许最外层 join 中包含分布式表
对于内存表 join 分区表的情况,需要将右表(分区表)加载到内存,故使用前应合理评估内存用量,避免 OOM
当分区表所在数据库的
chunkGranularity
为 “CHUNK” 时,分区表仅可作为左表,即此时不允许两个分布式表
join。
不支持两个不同数据库的表之间 join。
例子
对内存表进行删除操作
t = table(1 1 1 2 2 2 3 3 3 3 as id, 1..10 as x);
t;
id
x
1
1
1
2
1
3
2
4
2
5
2
6
3
7
3
8
3
9
3
10
delete from t where id=1;
t;
id
x
2
4
2
5
2
6
3
7
3
8
3
9
3
10
delete from t where id=3, x>8;
t;
id
x
2
4
2
5
2
6
3
7
3
8
delete from t;
t;
id
x
对分布式表进行删除操作
login(`admin, `123456)
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x)
db=database("dfs://rangedb124", RANGE, 0 5 10)
pt=db.createPartitionedTable(t, `pt, `ID)
pt.append!(t)
select count(*) from pt;
1000000
delete from pt where ID=5;
select count(*) from pt;
删除分布式表数据且where条件与数据行次序相关
删除分布式表数据,且 where 过滤条件与数据行的次序有关,必须使用 map 子句,在分区内分别执行。
n=10000
ID=take(0..4, n)
date=take(2017.08.07..2017.11.11, n)
ts=rand(timestamp(1..n),n)
int=take(1..50,n)
str=rand(string(1..n),n)
sym=rand(symbol(string(1..n)),n)
x=rand(10.0, n)
t=table(ID, date,ts,int,str,sym, x)
if(existsDatabase("dfs://compoDB")){
dropDatabase("dfs://compoDB")
}
db = database("dfs://compoDB", VALUE,2017.08M..2017.10M)
pt = db.createPartitionedTable(t, `pt, `date)
pt.append!(t);
delete from pt where isDuplicated([ID,int])=false map;
delete 语句结合 join 子句进行删除操作
t1 = table(1..5 as id, [1,2,2,1,1] as flag)
id
flag
1
1
2
2
3
2
4
1
5
1
t2 = table(3..7 as id, [100,200,100,150,100] as profit)
id
profit
3
100
4
200
5
100
6
150
7
100
delete t2 from ej(t2, t1, `id) where flag=1
t2
id
profit
3
100
6
150
7
100
FILE:references/doc_4821.md
# clearAllIOTDBLatestKeyCache
**URL**: https://docs.dolphindb.cn/zh/funcs/c/clearalliotdblatestkeycache.html
**来源**: DolphinDB 官方文档
---
clearAllIOTDBLatestKeyCache
语法
clearAllIOTDBLatestKeyCache()
详情
用于清理最新值缓存表缓存。
参数
无。
返回值
无。
例子
clearAllIOTDBLatestKeyCache()
FILE:references/doc_4832.md
# removeTail!
**URL**: https://docs.dolphindb.cn/zh/funcs/r/removeTail_.html
**来源**: DolphinDB 官方文档
---
removeTail!
语法
removeTail!(obj, n)
详情
删除向量
obj
的后
n
个元素。
参数
obj
是一个向量。
n
是一个正整数,表示要删除的位于向量尾部的元素的个数。
返回值
与
obj
同类型的向量。
例子
x=11..20;
x.removeTail!(3);
// output
[11,12,13,14,15,16,17]
FILE:references/doc_4845.md
# asinh
**URL**: https://docs.dolphindb.cn/zh/funcs/a/asinh.html
**来源**: DolphinDB 官方文档
---
asinh
语法
asinh(X)
详情
计算
X
的反双曲正弦。
参数
X
可以是标量、向量、矩阵或表。
返回值
返回结果的数据形式与输入保持一致:若输入为标量,返回标量;若输入为向量、矩阵或表,返回相同维度的结果。
例子
asinh(0.841471 0.909297 0.141120);
// output
[0.764725,0.815761,0.140656]
相关函数:
asin
,
acos
,
atan
,
sin
,
cos
,
tan
,
acosh
,
atanh
,
sinh
,
cosh
,
tanh
FILE:references/doc_4854.md
# sin
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sin.html
**来源**: DolphinDB 官方文档
---
sin
语法
sin(X)
详情
返回
X
的正弦。
参数
X
可以是标量、向量或矩阵。
返回值
DOUBLE 类型的标量、向量或矩阵。
例子
sin(1 2 3);
// output
[0.841471,0.909297,0.141120]
相关函数:
asin
,
acos
,
atan
,
cos
,
tan
,
asinh
,
acosh
,
atanh
,
sinh
,
cosh
,
tanh
FILE:references/doc_4855.md
# cacheDSNow
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cacheDSNow.html
**来源**: DolphinDB 官方文档
---
cacheDSNow
语法
cacheDSNow(ds)
详情
函数
cacheDSNow
立即执行并缓存数据源和缓存行的总数。
参数
ds
是数据源或数据源列表。
返回值
INT 类型标量。
例子
PTNDB_DIR = "/home/db_testing"
dbName = database(PTNDB_DIR + "/NYSETAQByName")
Trades = dbName.loadTable(`Trades)
ds=sqlDS(<select Time,Exchange,Symbol,Trade_Volume as Vol, Trade_Price as Price from Trades>)
ds.cacheDSNow() # cache the data immediately
ds.clearDSCacheNow() # clear the cache immediately
FILE:references/doc_4857.md
# first
**URL**: https://docs.dolphindb.cn/zh/funcs/f/first.html
**来源**: DolphinDB 官方文档
---
first
语法
first(X)
或
first X
详情
返回向量的第一个元素,或矩阵、表的第一行。
注:
若向量的第一个元素为 NULL,则返回 NULL。若要返回第一个非 NULL 的元素,请使用
firstNot
函数。
参数
X
可以是标量、数据对、向量、矩阵或表。
返回值
一个标量或向量,其数据类型同
X
。
例子
first(`hello `world);
输出返回:hello
first(1..10);
输出返回:1
m = matrix(1 2 3, 4 5 6);
m;
输出返回:
#0
#1
1
4
2
5
3
6
first(m);
输出返回:[1,4]
相关函数:
last
FILE:references/doc_4861.md
# ratios
**URL**: https://docs.dolphindb.cn/zh/funcs/r/ratios.html
**来源**: DolphinDB 官方文档
---
ratios
语法
ratios(X)
详情
若
X
是向量,返回 X(n)\X(n-1) 的值。返回结果的第一个元素是 NULL。
若
X
是矩阵,在每列内进行上述计算,返回一个与
X
维度相同的矩阵。
参数
X
是一个向量或矩阵。
返回值
数据类型和形式与
X
相同。
例子
x=3 12 0 -5 32;
ratios x;
// output
[,4,0,,-6.4]
x=2 3 6 NULL 28 7;
ratios x;
// output
[,1.5,2,,,0.25]
m=matrix(100 105 109 112 108 116, 200 212 208 199 206 210);
m;
#0
#1
100
200
105
212
109
208
112
199
108
206
116
210
ratios(m);
#0
#1
1.05
1.06
1.038095238095238
0.981132075471698
1.027522935779817
0.956730769230769
0.964285714285714
1.035175879396985
1.074074074074074
1.019417475728155
FILE:references/doc_4867.md
# mvarp
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mvarp.html
**来源**: DolphinDB 官方文档
---
mvarp
语法
mvarp(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
的总体方差。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
mvarp(1..6, 5);
// output: [,,,,2,2]
mvarp(1..6, 5, 2);
// output: [,0.25,0.666666666666667,1.25,2,2]
m=matrix(1 6 2 9 4 5, 11 12 18 23 21 10);
m;
#0
#1
1
11
6
12
2
18
9
23
4
21
5
10
mvarp(m,3);
#0
#1
4.666666666666667
9.555555555555542
8.222222222222223
20.22222222222221
8.666666666666666
4.222222222222248
4.666666666666667
32.666666666666664
m=matrix(1 NULL 4 NULL 8 6 , 9 NULL NULL 10 NULL 2)
m.rename!(date(2020.04.06)+1..6, `col1`col2)
m.setIndexedMatrix!()
mvarp(m,4d)
label
col1
col2
2020.04.07
0
0
2020.04.08
0
0
2020.04.09
2.25
0
2020.04.10
2.25
0.25
2020.04.11
4
0
2020.04.12
2.6667
16
mvarp(m,1w)
label
col1
col2
2020.04.07
0
0
2020.04.08
0
0
2020.04.09
2.25
0
2020.04.10
2.25
0.25
2020.04.11
8.2222
0.25
2020.04.12
6.6875
12.6667
相关函数:
varp
FILE:references/doc_4871.md
# append!
**URL**: https://docs.dolphindb.cn/zh/funcs/a/append!.html
**来源**: DolphinDB 官方文档
---
append!
语法
append!(obj, newData)
别名:
push!
详情
将
newData
中的数据追加到
obj
。在 DolphinDB
中,函数中的感叹号(!)表示直接修改数据本身(就地操作)。
注:
该函数不会检查两表中各列列名与顺序,只要两表中对应位置的列的数据类型一致,即可执行。如果两表中各列顺序有差别,该操作不会自动对齐各列。所以,对数据表进行
append!
操作时,请检查两表中各列列名与顺序,以免出错。绝大部分情况下两表中各列列名与顺序应当完全一致。
请注意:若数据库为分区,且分区列为字符串类型,则追加的分区列数据不能包含空格, “/t”。
参数
obj
必须是本地变量:向量、元组、矩阵、表或集合。
newData
可以是标量、向量、元组、表或集合。
如果
obj
是向量,则
newData
必须是标量或向量、或元素类型与
obj
中元素类型一致的元组。结果是比
obj
更长的向量。
如果
obj
是元组,则
newData
必须是标量、向量或元组。若
newData
为向量,则作为整体追加到元组;若
newData
为元组,当配置项
appendTupleAsAWhole
=true
时,作为整体追加,
appendTupleAsAWhole
=false 时,将
newData
的每一个元素依次追加。
如果
obj
是矩阵,则
newData
必须是长度为
obj
行数倍数的向量。结果是新的矩阵,行数和
obj
相同,具有更多的列数。
如果
obj
是表,则
newData
必须是一个列数和
obj
相同的表。结果是和
obj
具有相同列数和列名的表,但行数比
obj
多。
如果
newData
和
obj
的数据类型不同,
append!
函数会尝试将
newData
转换为
obj
的数据类型。如果无法转换,将返回一个错误信息。
返回值
数据类型和数据形式与
obj
一致。
例子
x = 1 2 3
x.append!(4)
x
// output
[1,2,3,4]
append!(x, 5 6)
x
// output
[1,2,3,4,5,6]
x.append!(7.2)
x
// output
[1,2,3,4,5,6,7]
// 7.2 的数据类型从 DOUBLE 转化为 INT,所以值变为7
x.append!(`XOM)
// output
Incompatible type. Expected: INT, Actual: STRING
x=array(INT, 0, 10)
// x 是一个空的向量
x
// output
[]
x.append!(1)
x
// output
[1]
x=array(SYMBOL, 0, 100)
append!(x, `TEST)
x
// output
["TEST"]
x=1..6$3:2
x
0
1
1
4
2
5
3
6
x.append!(7..12)
x
0
1
2
3
1
4
7
10
2
5
8
11
3
6
9
12
x=set(1 2 3 4)
x.append!(6)
// output
x
set(6,1,2,3,4)
t1=table(1 2 3 as x, 4 5 6 as y)
t2=table(1.1 2.2 3.3 as a, 4.4 5.5 6.6 as b)
t1.append!(t2)
t1
x
y
1
4
2
5
3
6
1
4
2
6
3
7
使用
append!
把数据添加到分布式表。下面的例子需要在集群中执行。相关配置可参考:
功能配置
。
n=1000000
t=table(rand(`IBM`MS`APPL`AMZN,n) as symbol, rand(10.0, n) as value)
db = database("dfs://rangedb_tradedata", RANGE, `A`F`M`S`ZZZZ)
Trades = db.createPartitionedTable(t, "Trades", "symbol")
上面的脚本根据表 t 的结构创建了空表 Trades。接着,把表 t 的数据追加到表 Trades 中。
Trades.append!(t)
select count(*) from Trades;
// output
1000000
把其他表的数据追加到表 Trades 中。
n=500000
t1=table(rand(`FB`GE`MSFT,n) as symbol, rand(100.0, n) as value)
Trades.append!(t1)
select count(*) from Trades
// output
1500000
配置项
appendTupleAsAWhole
的不同设置值将影响追加元组的行为。
x = (1,"X")
y = (2,"Y")
x.append!(y)
print(x)
// 配置参数 appendTupleAsAWhole=true 时
(1,"X",(2,"Y"))
// 配置参数 appendTupleAsAWhole=false 时
(1,"X",2,"Y")
FILE:references/doc_4890.md
# randNormal
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randNormal.html
**来源**: DolphinDB 官方文档
---
randNormal
语法
randNormal(mean, stdev, count)
详情
生成指定个数的正态分布随机数。
参数
mean
是正态分布的均值。
stdev
是正态分布的标准差。
count
是正整数,表示生成的随机数个数。
返回值
长度为
count
的 DOUBLE 类型向量。
例子
randNormal(2.31, 0.671, 2);
// output
[2.805524, 2.148019]
FILE:references/doc_4892.md
# temporalAdd
**URL**: https://docs.dolphindb.cn/zh/funcs/t/temporalAdd.html
**来源**: DolphinDB 官方文档
---
temporalAdd
语法
temporalAdd(obj, duration, [unit])
别名:
datetimeAdd
详情
为时间变量加上一个指定的值。
参数
obj
是时间类型的标量或向量。
duration
是一个整数或 DURATION 类型数据。
unit
是一个字符串标量。
duration
是整数时,
unit
表示:
duration
的单位,取值可以是:"ns"(nanosecond),
"us"(microsecond), "ms"(millisecond), "s"(second), "m"(minute),
"H"(hour), "d"(day), "w"(week), "M"(month), "y"(year),
“B”(business day)
交易日历的标识,例如:国外交易所的 ISO
Code、国内交易所简称或自定义交易日历名称。对应的文件必须保存在 marketHolidayDir 中。
duration
是 DURATION 类型数据时,
unit
无需设置。
注:
时间单位为 year 或 month 时,计算结果与 mysql 保持一致。Pandas
提供了一个时间偏移对象(Date offsets)来完成时间偏移工作,当 DateOffset 参数取 months 或 years 时,与
temporalAdd
单位为 M 或 y 的计算结果也一致。
返回值
时间类型标量或向量。
例子
temporalAdd(2017.01.16,1,"d");
// output
2017.01.17
temporalAdd(2017.01.16,1,"w");
// output
2017.01.23
temporalAdd(2016.12M,2,"M");
// output
2017.02M
temporalAdd(2012.07.31T13:30:10.008,-1,'M');
// output
2012.06.30T13:30:10.008
temporalAdd(2012.07.31T13:30:10.008,1,'y');
// output
2013.07.31T13:30:10.008
temporalAdd(13:30:10.008007006,100,"ns");
// output
13:30:10.008007106
x=[12:23:34, 23:34:45];
temporalAdd(x, 10m);
// output
[12:33:34,23:44:45]
为 2021.08.06 增加 4 个工作日。
temporalAdd(2021.08.06, 4B)
// output
2021.08.12
按照 CFFEX 的交易日历,为 date 增加 2 个交易日。
date=[2023.01.01, 2023.01.02, 2023.01.03, 2023.01.04]
temporalAdd(date,2,`CFFEX)
// output
[2023.01.04,2023.01.04,2023.01.05,2023.01.06]
temporalAdd(datetime(2020.08.31), -2M)
// output
2020.06.30T00:00:00
# pandas中 DateOffset 传入参数 months,计算结果一致
pd1 = pd.Timestamp("2020.08.31")
print(pd1 -pd.offsets.DateOffset(months=2))
// output
2020-06-30 00:00:00
temporalAdd(datetime(2020.02.29), -1y)
// output
2019.02.28T00:00:00
temporalAdd(datetime(2020.02.29), -4y)
// output
2016.02.29T00:00:00
// pandas 中 offset 设为1年
pd1 = pd.Timestamp("2020.02.29")
print(pd1 - pd.offsets.DateOffset(years=1))
// output
2019-02-28 00:00:00
// pandas 中 offset 设为4年
pd2 = pd.Timestamp("2020.02.29")
print(pd2 - pd.offsets.DateOffset(years=4))
// output
2016-02-29 00:00:00
FILE:references/doc_4897.md
# removeTopicOffset
**URL**: https://docs.dolphindb.cn/zh/funcs/r/removeTopicOffset.html
**来源**: DolphinDB 官方文档
---
removeTopicOffset
语法
removeTopicOffset(topic)
详情
删除给定订阅主题(topic)的持久化保存的最新一条已经处理订阅数据的偏移量(在
subscribeTable
函数中通过指定
persistOffset
参数为 true 获得)。
参数
topic
是
subscribeTable
函数返回的订阅主题。
FILE:references/doc_4898.md
# enableTablePersistence
**URL**: https://docs.dolphindb.cn/zh/funcs/e/enableTablePersistence.html
**来源**: DolphinDB 官方文档
---
enableTablePersistence
语法
enableTablePersistence(table, [asynWrite=true], [compress=true], [cacheSize],
[retentionMinutes=1440],
[flushMode=0],[cachePurgeTimeColumn],[cachePurgeInterval],[cacheRetentionTime],[preCache])
详情
该命令将共享的流计算表保存到磁盘上。
为保证该命令能够正常执行,需要在配置文件中(单节点:
dolphindb.cfg
,集群:
cluster.cfg
)指定配置参数
persistenceDir
,配置参考
功能配置
。流数据表在磁盘上的存储目录是
<PERSISTENCE_DIR>/<TABLE_NAME>
。目录包含两种类型的文件:数据文件(名称类型
data0.log, data1.log...
)和索引文件
index.log
。把这些数据保存到磁盘后,如果重启系统,该命令会把磁盘中的数据加载到内存中。
参数
asynWrite
会告知系统是否以异步模式保存表。在异步模式中,追加的数据会被放进队列,之后用于保存的工作线程把数据写入磁盘。在同步模式中,表的追加数据操作直到追加数据被保存到磁盘中才完成。该参数的默认值是
true,即为异步模式。通常情况下,异步模式实现更高的吞吐量,但是如果服务器崩溃,可能会丢失最后追加的行。在异步模式中,保存表的工作是由单个工作线程完成,并且一个工作线程可能处理多个表。如果只保存一个表,增加工作线程的数量并不会提升性能。
默认情况下,流数据表将所有数据保存在内存中。如果流数据表太大,系统可能会出现内存不足的情况。为了避免内存不足的问题,可以通过以下两种方式之一来清理内存中的数据:
配置
cacheSize
参数时,如果插入的数据使内存中流数据表的行数达到
cacheSize
设置的阈值,系统将清理内存中较旧的已发布记录。阈值确定规则如下:
每次 append 的数据都不超过
cacheSize
时,内存中的记录数不会大于
cacheSize
的 2.5
倍。
否则,当 append 的数据超过
cacheSize
时,内存中的记录数不会超过追加行数和
cacheSize
之和的 1.2 倍。
同时配置
cachePurgeTimeColumn
,
cachePurgeInterval
和
cacheRetentionTime
,系统将根据时间列清理数据。每次插入新数据时,系统会计算新数据与内存中第一条数据的时间戳差值,当差值大于等于
cachePurgeInterval
时,系统仅保留时间戳与新数据时间戳差值小于等于
cacheRetentionTime
的数据,清理其它数据。
注:
如果手动重启 server,建议调用
fflush
函数先把缓存区的数据写入磁盘再使用
kill -15
命令终止进程。
如果设置
flushMode
=0,则 server 发生 crash
时可能会丢失一部分数据。
参数
table
是一个空的流数据表。
asynWrite
是一个布尔值,表示是否异步持久化数据到磁盘。默认值为
true,流数据写入内存即为写入成功,持久化到磁盘的操作将会由另一个线程执行。
注:
持久化数据到磁盘包含两个步骤:
写内存数据到操作系统缓存
写缓存数据到磁盘(是否开启同步刷盘由参数
flushMode
决定)
compress
是一个布尔值。可选参数,表示是否以压缩模式模式保存至磁盘。默认值为 true。
cacheSize
整数,可选参数,表示流数据表在内存中最多保留多少行。如果它为0或者没有指定,所有记录行都会保存在内存中。如果
cacheSize
设置为小于 1000 的正整数,它会被自动调整为 1000。
retentionMinutes
是一个整数,表示保留大小超过 1GB 的 log 文件的时间(从文件的最后修改时间开始计算),单位是分钟。默认值是
1440,即一天。
flushMode
是一个整数,表示是否开启同步刷盘,取值只能为 0 或 1。默认值是
0,表示异步刷盘,内存中的流数据写入操作系统缓存即为写入成功,并进行下一批数据的写入。 若为
1,则表示同步刷盘,当前批次的流数据必须落盘完成,才会进行下一批数据的写入。
cachePurgeTimeColumn
字符串标量,需要指定为持久化流表中的时间列名称。
cachePurgeInterval
DURATION 类型标量,表示触发清理内存中数据的时间间隔。
cacheRetentionTime
DURATION 类型标量,表示内存中数据的最长保留期限。
preCache
可选参数,是一个整数,表示从磁盘加载到内存的记录条数。如果没有指定该参数,默认会把所有记录加载到内存中。
注:
自
3.00.2
版本起,该函数要求参数
cacheRetentionTime
必须小于
cachePurgeInterval
。
返回值
无。
例子
例1.
colName=["time","x"]
colType=["timestamp","int"]
t = streamTable(100:0, colName, colType);
share t as st
enableTablePersistence(table=st, cacheSize=1200000)
for(s in 0:200){
n=10000
time=2019.01.01T00:00:00.000+s*n+1..n
x=rand(10.0, n)
insert into st values(time, x)
}
getPersistenceMeta(st);
/* output:
persistenceDir->/data/ssd/DolphinDBDemo/persistence3/st
retentionMinutes->1440
hashValue->0
asynWrite->true
diskOffset->0
sizeInMemory->800000
compress->1
memoryOffset->1200000
totalSize->2000000
sizeOnDisk->2000000
*/
注:
以上代码先使用
share
命令共享流数据表,再通过
enableTablePersistence
命令持久化流数据表。我们推荐使用
enableTableShareAndPersistence
函数将共享和持久化组织成原子性操作。
例2. 本例将说明
cachePurgeTimeColumn
,
cachePurgeInterval
和
cacheRetentionTime
的使用方法。
colName=["time","x"]
colType=["timestamp","int"]
t1 = streamTable(100:0, colName, colType);
share t1 as st1
enableTablePersistence(table=st1,cachePurgeTimeColumn = `time, cachePurgeInterval = duration("7H"),cacheRetentionTime = duration("2H"))
time=2019.01.01T00:00:00.000
for(s in 0:6000){
time = temporalAdd(time,1,"m");
x=rand(10.0, 1)
insert into st1 values(time, x)
}
getPersistenceMeta(st1);
//通过查看流数据表的元数据,看到该表中的总记录数是 6000 行,系统根据时间列的自动清理内存后,在内存中仅保留了 300 行数据。
/* output:
lastLogSeqNum->-1
sizeInMemory->300
totalSize->6000
asynWrite->true
compress->true
raftGroup->-1
memoryOffset->5700
retentionMinutes->1440
sizeOnDisk->6000
persistenceDir->/data/ssd/DolphinDBDemo/persistence3/st1
hashValue->0
diskOffset->0
*/
FILE:references/doc_4904.md
# fill!
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fill_.html
**来源**: DolphinDB 官方文档
---
fill!
语法
fill!(obj, index, value)
详情
将
obj
中
index
对应位置的值设为
value
,相当于赋值语句
obj[index]=value。
参数
obj
可以是一个向量、元组、矩阵、字典或表。
如果
obj
是向量、元组或矩阵,
index
是整数,表示下标;如果
obj
是字典或表,
index
是字符串,分别表示 key 或列名。
value
是标量或向量,表示新的值。
返回值
返回填充空缺值后的对象,其类型与形式同
obj
。
例子
例1. 向量
a=[1,2,3,4];
fill!(a,3,12);
a;
// output
[1,2,3,12]
fill!(a,[0,1],[10,11]);
// output
[10,11,3,12]
例2. 元组
a=([1,2,3],["a","b","c"]);
fill!(a,0,[4,2]);
a[0];
// output
[4,2]
// 创建一个长度为20,并且每个元素为 FLOAT 类型的 NULL 值
array(ANY, 20).fill!(0:20, float());
// 相当于以下语句
t = array(ANY, 20);
t[0:20] = float()
例3. 矩阵
m=1..12$3:4;
fill!(m,2,5); // 将第2列的值全部设为5
m;
#0
#1
#2
#3
1
4
5
10
2
5
5
11
3
6
5
12
fill!(m,[1,2],5); // 将第1,2列的值全部设为5
m;
#0
#1
#2
#3
1
5
5
10
2
5
5
11
3
5
5
12
fill!(m,(1,),9); // 将第1行的值设为9
m;
#0
#1
#2
#3
1
5
5
10
9
9
9
9
3
5
5
12
m.fill!((1,2),10).fill!((2,2),12); // 将第1行,第2列的值设为10,第2行第2列的值设为12
m;
#0
#1
#2
#3
1
5
5
10
9
9
10
9
3
5
12
12
例4. 表
t=table(1 2 3 as id,10.2 45.2 12.3 as val);
fill!(t,`id,4 5 6);
t;
id
val
4
10.2
5
45.2
6
12.3
fill!(t,`qty,452 142 48);
t;
id
val
qty
4
10.2
452
5
45.2
142
6
12.3
48
例5. 字典
d=dict(`a`b`c,1 2 3);
fill!(d,`a,4);
d;
// output
c->3
a->4
b->2
FILE:references/doc_4908.md
# twindow
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/twindow.html
**来源**: DolphinDB 官方文档
---
twindow
语法
twindow(func, funcArgs, T, range, [prevailing=false]
,
[excludedPeriod]
)
详情
应用函数/运算符到给定对象的滑动窗口。对给定对象的每一个元素,滑动窗口由
T
和
range
决定。
结果的维度与
funcArgs
的维度相同(若
funcArgs
是一个元组,结果的维度与该元组中每个元素的维度相同)。
滑动窗口的确定规则(假设
range
参数为 d
1
:d
2
):
range
是整型数据对时:
T
如果为整型向量,对
T
内元素 T
i
,可以确定
T
对应的窗口范围为 [T
i
+d
1
,
T
i
+d
2
]。
T
如果为时间类型向量,
range
的精度默认为
T
的精度,对于
T
内元素 T
i
,确定的窗口范围为
[temporalAdd(T
i
, d
1
, unit),
temporalAdd(T
i
, d
2
, unit)],其中 unit 是
T
的精度。
range
是 DURATION 数据对时,
T
只能是时间类型向量,对于
T
内元素 T
i
,确定
T
对应的窗口元素范围为
[temporalAdd(T
i
, d
1
), temporalAdd(T
i
,
d
2
)]。
与
tmoving
函数相比,
twindow
函数具有更灵活的窗口。
tmoving
可以视为
twindow
指定
range
右边界为 0 的特殊情况, 但需要注意以时间长度衡量窗口时,两者对窗口边界的处理有区别:
twindow
窗口的右边界与多条相同的值匹配时,该窗口会包含所有重复匹配的记录。当其窗口左边界与多条相同的值匹配时, 若
prevailing
=
true,则窗口只包含最后一个值;若
prevailing
= false,则窗口亦会包含所有重复值。
tmoving
函数的窗口范围为(T
i
- window,
T
i
] 或 (temporalAdd(T
i
- window), T
i
],即
tmoving
函数只基于当前滑动到的记录,确定一个向前的窗口,
不考虑右边界是否有重复值;且左边界不包含在内。
参数
func
是一个聚合函数。
funcArgs
是
func
的参数。
func
有多个参数时,它是一个元组。
T
是一个非严格递增的整型或时间类型的向量。
range
是一个整型数据对或 DURATION 数据对,左右边界都包含在内。
prevailing
只能为 0/false,1/true 或 2。
如果
prevailing
= 0/false,则滑动窗口不对边界重复值做处理,请阅读详情部分。
如果
prevailing
= 1/true,则滑动窗口边界的选取规则同
pwj
。
如果
prevailing
= 2,(假设
range
参数为 d1:d2):
若 d1 为 0,则滑动窗口将把当前索引对象作为边界,窗口左边的重复值不参与计算。
若 d2 为 0,则滑动窗口将把当前索引对象作为边界,窗口右边的重复值不参与计算。
当前情况下不可以同时设置参数
excludedPeriod
。
excludedPeriod
是 TIME、NANOTIME、MINUTE 和 SECOND
类型的数据对。用于设定一个交易日内的非交易时间段(该时间段被排除在计算窗口之外)。若设置该参数,必须同时保证以下3点:
数据对中的右值必须大于左值。
时间段长度必须小于 (24 -
range
)
T
中不能包含
excludedPeriod
区间内的时间,且数据类型必须是 TIMESTAMP,
NANOTIMESTAMP, TIME 或 NANOTIME。
返回值
一个向量,数据类型为 VOID、INT、LONG 或 DOUBLE。
例子
prevailing
= false,左边界对应多个重复值,计算窗口会包含所有重复值
t = 2021.01.02 2021.01.02 2021.01.06 2021.03.09 2021.03.10 2021.03.12 2021.03.12
x = -5 5 NULL -1 2 4 -8
twindow(func=min,funcArgs=x,T=t,range=0:2)
输出返回:[-5, -5, , -1, -8, -8, -8]
prevailing
= true,左边界对应多个重复值,计算窗口只包含最后一个值
twindow(func=min, funcArgs=x, T=t, range=0:3, prevailing=true)
输出返回:[5, 5, ,-8, -8, -8, -8]
twindow(func=max, funcArgs=x, T=t, range=0d:3d)
输出返回:[5, 5, , 4, 4, 4, 4]
twindow(func=max, funcArgs=x, T=t, range=0:3, prevailing=true)
输出返回:[5, 5, , 4, 4, -8, -8]
twindow(func=max, funcArgs=x, T=t, range=0M:3M)
输出返回:[5, 5, 4, 4, 4, 4, 4]
twindow(func=max, funcArgs=x, T=t, range=0M:3M, prevailing=true)
输出返回:[5, 5, 4, 4, 4, -8, -8]
y = 4.8 9.6 7.1 3.3 5.9 2.7 6.9
twindow(func=corr, funcArgs=(x,y), T=t, range=0:3)
输出返回:[1, 1, , -0.685, -0.7893, -1, -1]
t1 = table(`A`A`B`B`C`C as sym, 09:56:03 09:56:07 09:56:02 09:56:05 09:56:04 09:56:06 as time, 10.6 10.7 20.6 11.6 11.7 19.6 as price)
select *, twindow(func=avg, funcArgs=t1.price, T=t1.time, range=2s:4s) from t1 context by sym
返回:
sym
time
price
window_avg
A
09:56:03
10.6
10.7
A
09:56:07
10.7
B
09:56:02
20.6
11.6
B
09:56:05
11.6
C
09:56:04
11.7
19.6
C
09:56:06
19.6
下例通过
excludedPeriod
参数指定股市上午的休市时间,计算长度为一分钟的滑动窗口内的价格平均值。
excludedPeriod=(11:30:00:13:00:00)
ts=timestamp(2023.11.01T11:21:00+1..500) join timestamp(2023.11.01T13:00:00+1..500)
t=table(ts, rand(10.0,size(ts)) as price)
// 通过 excludedPeriod 指定休市时间为11:30:00 到 13:00:00,则此段时间被忽略,不会被作为计算窗口。
res1=select ts, twindow(func=avg, T=ts, funcArgs=price, range=-1m:0m, excludedPeriod=excludedPeriod) from t
// 不指定 excludedPeriod 时,休市时间也会被考虑为计算窗口。
res2=select ts, twindow(func=avg, T=ts, funcArgs=price, range=-1m:0m) from t
// 对比是否指定 excludedPeriod 的计算结果。
select * from res1 where ts between timestamp(2023.11.01T13:00:00) and timestamp(2023.11.01T13:01:00)
select * from res2 where ts between timestamp(2023.11.01T13:00:00) and timestamp(2023.11.01T13:01:00)
只传入前四个参数,且设置
prevailing
为
2。
t=[09:30:00.020,09:30:00.020,09:30:00.020,09:30:00.030,09:30:00.040,09:30:00.040]
v=0 1 2 3 5 4
twindow(min,v,t,0ms:10ms,prevailing = 2)
//Output: [0,1,2,3,4,4]
twindow(min,v,t,-10ms:0ms,prevailing = 2)
//Output: [0,0,0,0,3,3]
//非法输入
twindow(min,v,t,-10ms:10ms,prevailing = 2)
//Output: Usage: twindow(func, funcArgs, T, range, [prevailing=0], [excludedPeriod]). left offset or right offset must be zero when prevailing =2.
twindow(min,v,t,0ms:0ms,prevailing = 2)
//Output: Usage: twindow(func, funcArgs, T, range, [prevailing=0], [excludedPeriod]). 0:0 is illegal window when prevailing =2.
FILE:references/doc_4914.md
# second
**URL**: https://docs.dolphindb.cn/zh/funcs/s/second.html
**来源**: DolphinDB 官方文档
---
second
语法
second(X)
详情
返回对应的秒数,返回值的类型是 SECOND,一个时间值。
参数
X
可以是整数/时间类型/字符串类型的标量或向量。
返回值
SECOND 类型的标量或向量。
例子
second();
返回:null
second(1)
返回:00:00:01
second("19:36:12");
返回:19:36:12
second(now());
返回:16:01:32
second 2012.12.03 01:22:01;
返回:01:22:01
second(61);
返回:00:01:01
second("09:00:01")
返回:09:00:01
FILE:references/doc_4923.md
# coint
**URL**: https://docs.dolphindb.cn/zh/funcs/c/coint.html
**来源**: DolphinDB 官方文档
---
coint
语法
coint(Y0, Y1, [trend="c"], [method="aeg"],
[maxLag], [autoLag="aic"])
详情
检验单变量方程中是否存在协整性。
参数
Y0
数值向量,元素不可为空值,表示协整系统中的第一个元素。
Y1
数值向量或数值矩阵,元素不可为空值,且元素个数与 Y0 相同。表示协整系统中的其余元素。
trend
字符串,指定协整方程的回归中使用的趋势项。取值有如下选择:
"c":默认值,表示只使用常数。
"ct":使用常数和趋势。
"ctt":使用常数、线性趋势和二次趋势。
"n":不使用常数和趋势。
method
字符串,指定协整检验所使用的方法,支持取值为 “aeg”,代表增广 Engle-Granger 两步协整性检验。
maxLag
非负整数,作为调用 adfuller 时传递的参数,指定 adfuller 检验中使用的最大滞后期。
autoLag
字符串,作为调用
adfuller
时传递的参数,指定在 0~maxLag
中自动确定滞后期长度时使用的方法。取值有如下选择:
"aic":默认值,表示使用 Akaike Information Criterion 来确定滞后期数值。
"bic":表示使用 Bayesian information criterion 来确定滞后期数值。
"tstat":将滞后期初始值设为 maxLag,然后逐步减 1,直到上一个滞后期数值的 t 统计量在 5% 显著性水平上显著。
"max":将滞后期数值设置为 maxLag。
返回值
结果以字典的形式返回,包括:
tStat:浮点数标量,表示残差的单位根检验的 t 统计量
pValue:浮点数标量,表示 MacKinnon 近似 p 值
criticalValues:字典,表示基于回归曲线,在1%、5%和10%水平上的检验统计量的临界值
例子
Y0 = 234 267 289 301 312 323 334 345 356;
Y1 = 267 289 301 312 323 334 345 356 367;
coint(Y0, Y1);
输出为字典:
tValue->-1.498236972489574
pValue->0.761867238199341
criticalValues->[-5.789286875000001,-4.206501875,-3.6171]
FILE:references/doc_4942.md
# clearComputeNodeCache
**URL**: https://docs.dolphindb.cn/zh/funcs/c/clearcomputenodecache.html
**来源**: DolphinDB 官方文档
---
clearComputeNodeCache
语法
clearComputeNodeCache(database, [table], [partition])
详情
应用于计算组中的计算节点上,尝试清空该节点的内存缓存和磁盘缓存。
参数
database
字符串,表示数据库名称。
table
字符串,表示数据表名。可以包含以下通配符:
"*" 表示匹配所有(默认值)
"?" 表示单个字符
"%" 表示0,1或多个字符。
partition
字符串标量或向量,表示分区的逻辑路径。若不指定,则表示所有分区。
返回值
无。
例子
清除 database_compute 数据库的内存缓存和磁盘缓存。
clearComputeNodeCache("dfs://database_compute")
清除 database_compute 数据库中以 pt 开头的表的内存缓存和磁盘缓存。
clearComputeNodeCache("dfs://database_compute","pt%")
FILE:references/doc_4952.md
# symbolCode
**URL**: https://docs.dolphindb.cn/zh/funcs/s/symbolCode.html
**来源**: DolphinDB 官方文档
---
symbolCode
语法
symbolCode(X)
详情
查看 SYMBOL 类型数据的内部编码。空字符串的内部编码为0。
SYMBOL 类型是特殊的字符串类型,在系统内部的存储结构为一个编码字典。将设备名,股票名等字符串重复较多的向量存储为 SYMBOL
类型,可以达到向量压缩的目的。
参数
X
是 SYMBOL 类型的向量或矩阵。
返回值
一个与
X
相同维度的整型向量或矩阵。
例子
a=symbol(`IBM`APPL)
symbolCode(a)
输出返回:[1,2]
x=symbol(`MS`AMZN`AAPL`MS`IBM`AAPL)$3:2
symbolCode(x)
输出返回:
#0
#1
1
1
2
4
3
3
FILE:references/doc_4956.md
# isQuarterStart
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isQuarterStart.html
**来源**: DolphinDB 官方文档
---
isQuarterStart
语法
isQuarterStart(X)
详情
判断
X
是否为季度第一天。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
返回值
布尔标量或向量。
例子
isQuarterStart(2012.04.01);
// output: true
isQuarterStart([2012.04.01,2012.05.01]);
// output: [true,false]
相关函数:
isQuarterEnd
FILE:references/doc_4960.md
# ilastNot
**URL**: https://docs.dolphindb.cn/zh/funcs/i/ilastNot.html
**来源**: DolphinDB 官方文档
---
ilastNot
语法
ilastNot(X)
详情
查找最后一个非空元素的下标位置。
如果
X
是一个向量,返回最后一个非空元素的下标。如果
X
中的所有元素都为空,返回-1。
如果
X
是一个元组,返回最后一个所有向量中均不为空的位置的下标。
如果
X
是一个矩阵,返回每列中最后一个非空元素的下标。返回一个向量。
如果
X
是一个表,返回每列中最后一个非空元素的下标。返回一个表。
参数
X
可以是一个向量,也可以是由多个等长向量组成的元组,亦可是一个矩阵或表。
返回值
当 X 是向量或元组时,返回 INT 类型标量。
当 X 是矩阵时,返回 INT 类型向量。
当 X 是表时,返回表。
例子
ilastNot(NULL NULL 2 4 8 1 NULL);
// output: 5
ilastNot(take(int(),5));
// output: -1
x=NULL NULL 4 7 8 NULL
y=1 NULL NULL 4 NULL NULL
ilastNot([x,y]);
// output: 3
x=NULL NULL 4 7 8 NULL
y=1 2 NULL NULL NULL 6
ilastNot([x,y]);
// output: -1
m=matrix(2 NULL 1 0 NULL, NULL 2 NULL 6 0);
m;
#0
#1
2
2
1
0
6
0
ilastNot(m);
// output: [3,4]
相关函数:
ifirstNot
,
lastNot
,
firstNot
FILE:references/doc_4964.md
# getComputeNodeCachingDelay
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getcomputenodecachingdelay.html
**来源**: DolphinDB 官方文档
---
getComputeNodeCachingDelay
语法
getComputeNodeCachingDelay()
详情
查看当前节点下配置项
computeNodeCachingDelay
的生效值,单位为秒。
参数
无
详情
整型标量。
例子
getComputeNodeCachingDelay()
// output: 580
相关函数:
setComputeNodeCachingDelay
FILE:references/doc_4981.md
# invStudent
**URL**: https://docs.dolphindb.cn/zh/funcs/i/invStudent.html
**来源**: DolphinDB 官方文档
---
invStudent
语法
invStudent(df, X)
详情
返回 t 分布的累计密度函数的逆函数值。
参数
df
是正数,表示t分布的自由度。
X
是0到1之间的浮点型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
invStudent(1, [0.15, 0.25, 0.35]);
// output: [-1.962611, -1, -0.509525]
invStudent(1, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output: [-3.077684, -0.726543, 0, 0.726543, 3.077684]
FILE:references/doc_4983.md
# rmdir
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rmdir.html
**来源**: DolphinDB 官方文档
---
rmdir
语法
rmdir(directory,
[recursive=false]
,
[keepRootDir=false]
)
详情
删除目录。默认情况下,要删除的目录必须为空。如果目录不为空仍然要删除它时,请设置
recursive
的值为true。
注:
该命令在用户登录后才能执行。
参数
directory
必备参数,用于指定要删除的文件夹名称。如果该目录不为空,则通过设定
recursive
的值为 true
可以删除所有子目录和文件
recursive
布尔值,可选参数,用于是否删除所有指定文件夹所有子目录及其中文件。默认值为 false。
keepRootDir
布尔值,可选参数,用于指定是否保留根目录。默认值为 false。当设置为 true
时,仅删除子目录和文件,而不会删除根目录。
注:
若设置
keepRootDir
=true,则必须设置
recursive
=true。
例子
files("/home/test");
filename
isDir
fileSize
lastAccessed
lastModified
dir1
1
0
1496650004836
1496650004836
dir2
1
0
1496650002210
1496650002210
dir3
1
0
1496649999597
1496649999597
// delete a directory. dir1 is empty, dir2 is not empty.
rmdir("/home/test/dir1");
rmdir("/home/test/dir2");
// output
Failed to remove directory [/home/test/dir2] with error code 145
// Delete a directory recursively
rmdir("/home/test/dir2", true);
files("/home/test");
filename
isDir
fileSize
lastAccessed
lastModified
dir3
1
0
1496649999597
1496649999597
FILE:references/doc_4985.md
# createTable
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createTable.html
**来源**: DolphinDB 官方文档
---
createTable
是
createDimensionTable
的别名。
FILE:references/doc_5001.md
# cdfWeibull
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfWeibull.html
**来源**: DolphinDB 官方文档
---
cdfWeibull
语法
cdfWeibull(alpha, beta, X)
详情
返回 Weibull 分布的累计密度函数的值。
参数
形状参数
alpha
和
beta
都是正数。
X
是数值型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfWeibull(2.31, 0.627, [0.001, 0.5, 0.999]);
// output
[0, 0.447241, 0.946762]
cdfWeibull(2.31,0.627, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output
[0.014295, 0.166535, 0.447241, 0.724646, 0.90021]
FILE:references/doc_5003.md
# det
**URL**: https://docs.dolphindb.cn/zh/funcs/d/det.html
**来源**: DolphinDB 官方文档
---
det
语法
det(X)
详情
返回矩阵
X
的行列式(determinant)。在计算中,NULL 值用 0 代替。
参数
X
是一个矩阵。
返回值
DOUBLE 类型标量。
例子
x=1..4$2:2;
x;
#0
#1
1
3
2
4
x.det();
// output
-2
x=1 2 3 6 5 4 8 7 0$3:3;
x;
#0
#1
#2
1
6
8
2
5
7
3
4
0
det(x);
// output
42
x=1 2 3 6 5 4 8 7 NULL $3:3;
x;
#0
#1
#2
1
6
8
2
5
7
3
4
det(x);
// output
42
FILE:references/doc_5013.md
# 数据备份以及恢复 (1.30.20/2.00.8及之后版本)
**URL**: https://docs.dolphindb.cn/zh/tutorials/backup-restore-new.html
**来源**: DolphinDB 官方文档
---
数据备份以及恢复 (1.30.20/2.00.8及之后版本)
本文适用于 DolphinDB 如下版本:
130系列:1.30.20及以后的版本
200系列:2.00.8及以后的版本。
1. 适用场景
本教程适用于整个集群/数据库/表/分区的数据备份、恢复,以及大数据量的数据迁移。如果进行小规模的集群间数据同步,可以参考
集群间数据库在线方式
。
2. 特性
同2.00.8/1.30.20以前的版本的备份恢复功能相比,有如下的改进:
DolphinDB提供了拷贝文件的备份和恢复分布式数据库的方法,大大增加了备份和恢复的性能;
DolphinDB利用底层的
backup
和
restore
函数封装了不同场景下的备份和恢复函数。用户可以根据需要选择函数进行备份以及恢复。这大大增加了备份恢复功能的易用性;
DolphinDB 提供了更强大的备份文件校验功能,你可以在备份文件之后立刻检验文件的正确性以及完整性。
3. 模拟数据
本教程对应的数据生成脚本见
附件1
。数据库结构如下图:
可以看到,我们构建了两个数据库,分别是OLAP和TSDB数据库。在OLAP数据库中有两张表,
quotes
和
quotes_2
。
本教程各章节中使用的脚本,集合在
附件2
。
备份和恢复任务有两种提交方式,一种是直接在客户端运行函数启动任务,另一种是通过
submitJob
提交任务到后台执行。鉴于备份和恢复的使用场景通常是大数据量,所需时间较长,建议将备份和恢复任务提交到后台执行,之后的脚本也都将采用这种方式。
后台任务的状态可以通过
getRecentJobs
查询
数据生成脚本运行之后,将往磁盘上写150G左右的数据,所以运行此脚本,请确保有足够的磁盘容量。如果磁盘容量不够,可以调节脚本里的
smallDates
变量,以减小数据量
4. 数据备份
DolphinDB 提供了3种备份数据的方式:
(1) 备份单个数据库的数据
(2) 备份单张表的数据
(3) 备份部分分区的数据
注意
:
到2.00.8版本,备份暂时只能将文件放在运行备份任务的数据节点所在的机器的目录下。
DolphinDB 的备份保证了备份的是在同一时间点的数据。为此,DolphinDB在备份时会给数据加锁(如果使用backupDB则对数据库加锁,如果使用backupTable则对整个表加锁)。加锁期间数据可读但是不可写入。为了避免数据写入失败,请尽量选择没有写入任务的时候进行数据备份
4.1. 备份单个数据库
要备份单个数据库,可使用
backupDB
命令。
用例:将数据库
testdb
备份到
/home/$USER/backupDB
目录下(其中$USER为用户名称)
dbPath="dfs://testdb"
backupDir="/home/$USER/backupDB"
submitJob("backupDB","backup testdb",backupDB,backupDir,dbPath)
backupDB
有以下特性:
支持断线续备:如果备份中断,再次运行
backupDB
即可从刚才中断时正在备份的分区开始备份,已备份好的分区无需重新备份一遍。
支持分区级别的增量备份:对于在数据库和备份文件里同时存在的分区,
backupDB
会检查数据库的分区和备份文件里对应的分区的更新时间。DolphinDB 只会对更新时间不一致的分区,用数据库里的数据覆盖备份文件里的。
备份数据和数据库备份开始时的数据一致:备份文件中存在,而数据库中不存在的分区会被从备份文件中删除;备份文件中不存在,而数据库中存在的分区将会被备份;备份文件和数据库中都存在的分区,参见
特性
中第2点
4.2. 备份单张表
要备份一张表,可使用
backupTable
命令。
用例:将数据库
testdb
的
quotes_2
表备份到
/home/$USER/backupTb
目录下(其中$USER为用户名称)
dbPath="dfs://testdb"
tbName=`quotes_2
backupDir="/home/$USER/backupTb"
submitJob("backupTable","backup quotes_2 in testdb",backupTable,backupDir,dbPath,tbName)
backupTable
和
backupDB
有类似的特性,只不过
backupTable
是针对分布式表的,而
backupDB
是针对数据库的。
4.3. 备份分区
要备份同一个表的部分或全部分区,可以将他们的分区路径放入一个向量,并将这个向量传入backup函数中
用例:将数据库
testdb
的
quotes_2
表的
/Key3/tp/20120101
和
/Key4/tp/20120101
分区备份到
/home/$USER/backupPar
目录下
dbPath="dfs://testdb"
tbName=`quotes_2
backupDir="/home/$USER/backupPar"
pars=["/Key3/tp/20120101","/Key4/tp/20120101"]
submitJob("backupPartitions","backup some partitions in quotes_2 in testdb",backup,backupDir,dbPath,false,true,true,tbName,pars)
5. 备份文件检验函数
运行备份任务之后,一个很重要的步骤是检查备份是否成功完成,以及备份文件的完整性。DolphinDB提供了多个函数,用以监控备份任务、检验备份文件:
getBackupStatus
:可以用来查看指定用户的backup/restore任务进度
getBackupList
:可以查看备份的所有分区的基本信息,
getBackupMeta
:可以查看备份文件的元数据信息,包括表的schema等信息
checkBackup
:可以用来检查备份文件的完整性
接下来我们将分别介绍这些函数,并且在最后给出检查备份文件的最佳实践。
注意
:以上的操作需要在进行备份任务的数据节点运行。你可以通过
getNodeAlias
函数查看自己当前所在的数据节点别名。
5.1. getBackupStatus
getBackupStatus可以用来查看指定用户的backup/restore任务进度,同时可以预估任务完成时间。
用例:作为管理员使用
getBackupStatus
查看所有用户的 backup/restore 任务
login(`admin, `123456)
getBackupStatus()
管理员调用该函数时,若指定了 userName,则返回指定用户的 backup/restore 任务;否则返回所有用户的 backup/restore 任务
非管理员调用该函数时,只能返回当前用户的 backup/restore 任务。
返回如下:
这张表里会返回每个任务涉及到的数据库和表名,涉及多少个分区,当前已完成了多少分区,和完成百分比。
如果任务还未完成,endTime会返回预估完成时间;如果任务已完成,endTime返回实际完成时间。
注意事项:
返回的表里对每张表的备份/恢复任务都有一行新纪录。例如上图的表里返回了两条记录,虽然只进行了一次备份
getBackupStatus只会返回这次数据节点启动之后的backup任务的进度。如果重启数据节点,之前的backup任务的进度将丢失
5.2. getBackupList
getBackupList
会返回一个分布式表的备份信息。返回为一张表,表里包含备份文件里这个表的所有的分区。每个分区对应表中的一行。表中会有chunkID、chunkPath、版本号、每个分区包含的行数和最后一次更新的时间戳。
用例:getBackupList获得
testdb
数据库中
quotes_2
的表的备份信息。
dbPath="dfs://testdb"
backupDir="/home/$USER/backupDB"
getBackupList(backupDir,dbPath,`quotes_2)
部分信息见下图:
5.3. getBackupMeta
使用
getBackupMeta
可以获得某一个分区的相关信息,比如所在的表的表结构,分区的完整路径,行数,ID,版本号等等。详情参见
DolphinDB用户手册
5.4. checkBackup
checkBackup
会检查备份文件中每个分区的 checksum。返回一张包含 checksum 检查不通过的分区的表。
用例:检查“备份单个数据库”里的备份文件的完整性
dbPath="dfs://testdb"
backupDir="/home/$USER/backupDB"
checkBackup(backupDir,dbPath)
checkBackup运行需要的时间和备份文件时所需的时间相近。
如果发现检查不通过的分区,需要通过backup,并设定force为true强制重新备份。如果设置force=false,只会检查分区的元数据信息,那么就有可能不会重新备份有问题的分区。
为了展示这个函数的用法,我们将做如下操作:
运行 checkBackup
将之前备份好的文件,选取一个移动到别的目录下,并建一个同名的空文件,再运行checkBackup
将移除文件涉及的分区重新备份,并再次运行 checkBackup
为了更快返回结果,我们选择检查OLAP数据库中 quotes_2 的备份文件:
checkBackup(backupDir,dbPath,`quotes_2)
返回为空,说明校验通过。
然后将
086b0c1e-0386-95a4-4b4a-5038f4fd5d51
分区中volume.col文件移除,并添加一个同名的空文件。
再次运行checkBackukp,得到结果
接下来我们将这个分区重新备份:
backup(backupDir=backupDir,dbPath=dbPath,force=true,parallel=true,snapshot=true,tableName=`quotes_2,partition="/Key4/tp/20120103")
再运行checkBackup,返回为空,说明校验通过。
所以checkBackup可以检查一个备份文件在备份完成之后是否损坏。
5.5. 备份文件检查最佳实践
备份文件检查分为两个阶段,第一个阶段是备份任务结束之后,需要判断其是否正常完成。第二个阶段是在恢复之前,需要检查备份文件是否有损坏。以下的命令都需要在备份任务所在的节点执行。
5.5.1. 判断备份任务是否正常完成
使用
getBackupStatus
,返回备份任务信息。每一行代表一个表的备份。如果此次备份任务涉及的各行的completed列都为1,则说明任务成功。
如果
getBackupStatus
查不到相关的表的备份信息,说明这个备份任务开始到查询期间,数据节点重启过,那么可以用
getBackupList
函数获取备份的各分区的行数,和数据库中对应的分区的行数进行比对。
在2.00.9版本及之后,可以在log中查到backup成功或者失败的日志信息
如果您提交的是后台备份任务,可以到您配置的
homeDir/<nodeAlias>/batchJobs
下寻找对应的任务。以“备份单张表”中的任务为例,可以查询
backupTable.msg
,返回如下:
如果有"The job is done." 则说明任务已完成。
5.5.2. 判断备份文件是否损坏
使用
checkBackup
函数。具体方法见
checkbackup
。
6. 数据恢复
现在 DolphinDB 提供了4种恢复数据的方式:
恢复单个数据库
恢复单张表
恢复部分分区
恢复整个集群
与备份不同,在数据恢复时,不会对涉及分区加锁。比如,在对一张表做恢复的同时,允许对这张表进行写入操作。不过我们建议在恢复的同时不要写入,否则会出现一些无法预测的行为,比如新的写入可能会留在数据库,也可能被恢复任务覆盖。
6.1. 恢复单个数据库
要恢复单个数据库的数据,可使用
restoreDB
命令。
用例1:将“备份单个数据库”中备份的数据恢复到新集群中
dbPath="dfs://testdb"
backupDir="/home/$USER/backupDB"
submitJob("restoreDB","restore testdb in new cluster",restoreDB,backupDir,dbPath)
注意
:此处我们只是声明了备份文件的路径和需要恢复的数据库路径,而
restoreDB
函数会在新集群按照备份文件创建
testdb
数据库及库里所有的表,并将所有表的数据导入这个数据库
也可以将单个数据库的数据恢复到同一个集群的另一个数据库中,只需要指定数据库的路径即可。下例将“备份单个数据库”中备份的数据恢复到 restoredb 中。
dbPath="dfs://testdb"
backupDir="/home/$USER/backupDB"
restoreDBPath="dfs://restoredb"
submitJob("restoreDB2","restore testdb to restoredb in the original cluster",restoreDB,backupDir,dbPath,restoreDBPath)
restoreDB
有以下特性:
支持断线续恢复:如果恢复中断,再次运行
restoreDB
即可从刚才中断时正在恢复的分区开始恢复,已恢复好的分区无需重新恢复一遍。
支持分区级别的增量恢复:对于在新数据库和备份文件里同时存在的分区,
restoreDB
会检查新数据库的分区和备份文件里对应的分区的更新时间。DolphinDB 只会对更新时间不一致的分区,用备份文件里的数据覆盖新数据库里的。
备份数据和新数据库恢复开始时的数据一致:备份文件中存在,而新数据库中不存在的分区会被恢复到新数据库中;备份文件中不存在,而数据库中存在的分区将会从新数据库中被删去;备份文件和数据库中都存在的分区,参见
特性
中第2点。
6.2. 恢复单张表
要恢复单张表的数据,可使用
restoreTable
命令。
用例1:将“备份单张表”中备份的数据恢复到新集群中
dbPath="dfs://testdb"
tbName=`quotes_2
backupDir="/home/$USER/backupTb"
submitJob("restoreTable","restore quotes_2 in testdb to new cluster",restoreTable,backupDir,dbPath,tbName)
注意:此处我们只是声明了备份文件的路径和需要恢复的表名,而
restoreTable
会在新集群按照备份文件创建
testdb
数据库和
quotes
表,并将数据恢复到这张表
也可以将单张表的数据恢复到同一个集群的另一个数据库中,只需要指定数据库的路径即可:
# 将"备份单张表"备份的数据恢复到 restoredb2 的 quotes_2 表中
dbPath="dfs://testdb"
tbName=`quotes_2
backupDir="/home/$USER/backupTb"
restoreDBPath="dfs://restoredb2"
submitJob("restoreTable2","restore quotes_2 in testdb to quotes_2 in restoredb",restoreTable,backupDir,dbPath,tbName,restoreDBPath)
也可以将单张表的数据恢复到同一个数据库的另一张表中,只需要指定表名即可
# 将“备份单张表”中备份的数据恢复到 testdb 的 quotes_restore 表中。
dbPath="dfs://testdb"
tbName=`quotes_2
backupDir="/home/$USER/backupTb"
restoreTb="quotes_restore"
submitJob("restoreTable3","restore quotes_2 to quotes_restore in testdb",restoreTable,backupDir,dbPath,tbName,,restoreTb)
restoreTable
和
restoreDB
有类似的特性,只不过
restoreTable
是针对分布式表的,而
restoreDB
是针对数据库的。
6.3. 恢复单个分区
要恢复同一个表的部分分区,可以使用
restore
函数。和backup备份分区时略有不同,restore中的partition参数只支持传入一个标量,这个标量中可以使用通配符,去匹配多个分区。比如,
%/Key4/tp/%
可以匹配
/Key4/tp/20120101
,
/Key4/tp/20120103
,
/Key4/tp/20120104
...等分区。
用例:将
备份分区
中备份的分区恢复到新数据库中
dbPath="dfs://testdb"
backupDir="/home/$USER/backupPar"
tbName=`quotes_2
pars=["/testdb/Key3/tp/20120101","/testdb/Key4/tp/20120101"]
for (par in pars){
restore(backupDir,dbPath,tbName,par,false,,true,true)
}
6.4. 恢复整个集群
如果需要将整个集群的数据进行迁移,可以先将各个数据库备份至同一个目录下,然后通过
migrate
函数进行恢复。
用例:备份两个数据库
testdb
和
testdb_tsdb
至目录下,然后使用migrate在新集群恢复
//旧集群备份testdb和testdb_tsdb
dbPath="dfs://testdb"
dbPath2="dfs://testdb_tsdb"
backupDir="/home/$USER/migrate"
submitJob("backupForMigrate","backup testdb for migrate",backupDB,backupDir,dbPath)
submitJob("backupForMigrate2","backup testdb_tsdb for migrate",backupDB,backupDir,dbPath2)
//备份完成后,在新集群恢复这两个数据库
backupDir="/home/$USER/migrate"
submitJob("migrate","migrate testdb and testdb_tsdb to new cluster",migrate,backupDir)
migrate
和
restoreDB
类似,但是有如下两个区别:
migrate可以恢复多个数据库,而restoreDB只能恢复单个数据库。
当恢复后的数据库名称、表名称与原数据库、原表一致时,migrate 要求原数据库、原表已经被删除,否则无法恢复,而 restoreDB 无此限制。所以migrate无法用于增量恢复和断点续恢复,而一般用于新的集群刚部署完成的时候的数据迁移。
6.5. 判断恢复任务是否正常完成
恢复的任务信息也可以通过
getBackupStatus
查询。若要判断恢复任务是否完成,可以参考
判断备份任务是否正常完成
。
7. 备份恢复的性能
本次性能测试使用的机器 CPU 为Intel(R) Xeon(R) Silver 4314 CPU @ 2.40GHz
使用的DolphinDB集群为 DolphinDB 普通集群,1个 controller,3个 datanode,每个 datanode 挂载1个普通SSD盘,读写速度约为500MB/s。备份文件所在的磁盘也是SSD盘,读写速度也为500MB/s。
cluster.cfg配置如下:
maxMemSize=256
maxConnections=512
workerNum=8
chunkCacheEngineMemSize=16
newValuePartitionPolicy=add
maxPubConnections=64
subExecutors=4
subPort=8893
lanCluster=0
enableChunkGranularityConfig=true
diskIOConcurrencyLevel=0
运行备份时,落库为50G大小的数据,观察备份文件所在的磁盘IO,写入速度为490MB/s左右,基本达到了磁盘的性能瓶颈。
运行恢复时,因为是写入多个磁盘,我们用数据量/时间来估算写入速度。备份文件大小为50G,恢复花费了2分20秒,速度约为365MB/s,低于备份速度。
8. 常见问题
8.1. 是否支持恢复到某个时间点?
不支持,DolphinDB的增量备份并不是添加新的binlog,而是直接覆盖原文件。所以,增量备份功能只是跳过了不需要备份的分区,从而加速了备份,而不支持恢复到某个时间点。在 DolphinDB 中,如果你需要恢复到到一周前的任意一天,那么你需要在一周前的每一天都备份一份数据,并且放在不同的目录中。
8.2. 备份时所有分区的时间点是否一致?
一致。
8.3. 是否支持断点续备/恢复?
支持。具体见
备份单个数据库
。
8.4. 是否支持增量备份/恢复?
支持。具体见
备份单个数据库
。
8.5. 如何查看备份进度?
使用
getBackupStatus
函数。具体见
getbackupstatus
8.6. 如何检查备份是否完成?
见
判断备份任务是否正常完成
。
8.7. 如何检查恢复是否完成?
见
判断恢复任务是否正常完成
FILE:references/doc_5014.md
# searchK
**URL**: https://docs.dolphindb.cn/zh/funcs/s/searchK.html
**来源**: DolphinDB 官方文档
---
searchK
语法
searchK(X, k)
详情
返回第
k
小的元素,忽略 NULL 值。
参数
X
是一个向量。
返回值
数据类型与
X
相同的标量。
例子
searchK(1 7 3 5 3 9 6 1 NULL, 1);
输出返回:1
searchK(1 7 3 5 3 9 6 1 NULL, 2);
输出返回:1
searchK(1 7 3 5 3 9 6 1 NULL, 3);
输出返回:3
FILE:references/doc_5020.md
# 故障排查
**URL**: https://docs.dolphindb.cn/zh/error_codes/troubleshooting.html
**来源**: DolphinDB 官方文档
---
故障排查
本章介绍 DolphinDB 使用过程中一些常见的故障及其排查方式。我们将详细说明各种常见故障的原因及其解决步骤,帮助客户独立诊断和修复这些问题。
FILE:references/doc_5028.md
# dailyAlignedBar
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dailyAlignedBar.html
**来源**: DolphinDB 官方文档
---
dailyAlignedBar
语法
dailyAlignedBar(X, timeOffset, n, [timeEnd],
[mergeSessionEnd=false])
相关函数:
bar
详情
按照给定的起始时刻
timeOffset
(与结束时刻
timeEnd
)以及时间区间长度(由
n
指定),划分时间区间,返回
X
中每个元素所属的时间区间起始时刻,结果为与
X
长度相同的向量。具体而言,对于
X
中的每个元素,计算
X-((X-timeOffset)%n)。
时间区间一般包括左边界,不包括右边界。但若指定
mergeSessionEnd
=
true,且某个时段的最后时刻为某个区间的起始时刻,则将其并入之前的区间。
该函数支持隔夜时段。
参数
X
时间类型向量,支持以下的类型:SECOND, TIME, NANOTIME, DATETIME, TIMESTAMP 或
NANOTIMESTAMP。
timeOffset
标量或向量,表示每个时段的起始时刻。与
X
精度一致,可以是 SECOND、TIME 或 NANOTIME
类型的标量或向量。如果
timeOffset
是一个向量,它必须是递增的。
n
是一个正整数或 DURATION 类型数据,表示时间区间长度。
n
取正整数时,其单位为
timeOffset
的最小精度。
n
取 DURATION 类型数据时,其单位不能是 y, M, w, d, B。
timeEnd
可选参数,表示每个时段的结束时刻。和 timeOffset 的类型和长度必须一致。
mergeSessionEnd
为可选参数,是一个布尔值,表示若某个时段的最后时刻为某个区间的起始时刻,是否将其并入之前的区间。默认值为
false。
返回值
返回一个与 X 长度相同的时间类型向量,表示 X 中每个元素所属的时间区间起始时刻。
例子
以下例子中均使用了随机模拟数据。结果中的 price 列之值每次执行均会有所不同。
例1. 中国股票市场每天有两个交易时段:上午9:30-11:30和下午1:00-3:00。计算每个交易时段中的60分钟均价。
sessionsBegin = 09:30:00 13:00:00
ts = 2019.11.01T09:30:00..2019.11.01T11:30:00 join 2019.11.01T13:00:00..2019.11.01T15:00:00
t = table(ts, rand(10.0, size(ts)) as price);
select avg(price) as price, count(*) as count from t group by dailyAlignedBar(ts, sessionsBegin, 60*60) as k60;
k60
price
count
2019.11.01T09:30:00
5.031685383252463
3600
2019.11.01T10:30:00
5.022667285786399
3600
2019.11.01T11:30:00
4.930270051117987
1
2019.11.01T13:00:00
4.931854071494632
3600
2019.11.01T14:00:00
4.979529541734115
3600
2019.11.01T15:00:00
0.961996954865754
1
由于每个区间包括左边界,不包括右边界,若每个交易时段的结束时刻(上午11:30与下午3:00)恰好是区间边界,若不指定
timeEnd
与
mergeSessionEnd
,则时段的结束时刻会单独作为一区间,如上例所示。多数情况下,会希望此类结束时刻归入前一区间。可参照以下脚本。
sessionsEnd = 11:30:00 15:00:00;
select avg(price) as price, count(*) as count from t group by dailyAlignedBar(ts, sessionsBegin, 60*60, sessionsEnd, true) as k60;
k60
price
count
2019.11.01T09:30:00
5.031685383252463
3600
2019.11.01T10:30:00
5.022641627015316
3601
2019.11.01T13:00:00
4.931854071494632
3600
2019.11.01T14:00:00
4.978413870368697
3601
例2. 隔夜时段。期货市场每天有两个交易时段:下午1:30-4:30和晚上10:30-凌晨2:30。使用
dailyAlignedBar
函数计算每个交易时段中的7分钟均价。
sessions = 13:30:00 22:30:00
ts = 2019.11.01T13:30:00..2019.11.01T16:30:00 join 2019.11.01T22:30:00..2019.11.02T02:30:00
ts = ts join (ts+60*60*24)
t = table(ts, rand(10.0, size(ts)) as price)
select avg(price) as price, count(*) as count from t group by dailyAlignedBar(ts, sessions, 7m) as k7;
例3. 计算分钟 k 线时,
n
需要转换为
NANOTIMESTAMP,此时若使用整型计算可能造成类型溢出,需要将数据类型转换成 LONG。
n = 1000000
nano=(09:30:00.000000000 + rand(long(6.5*60*60*1000000000), n)).sort!()
sessionStartNano=09:30:00.000000000
price = 100+cumsum(rand(0.02, n)-0.01)
volume = rand(1000, n)
symbol = rand(`600519`000001`600000`601766, n)
tradeNano=table(symbol, nano, price, volume).sortBy!(`symbol`nano)
undef(`nano`price`volume`symbol)
barMinutes=7
itv = barMinutes*60*long(1000000000)
OHLC_nano=select first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume from tradeNano group by symbol, dailyAlignedBar(nano, sessionStartNano, itv) as barStart
FILE:references/doc_503.md
# setRetentionPolicy
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setRetentionPolicy.html
**来源**: DolphinDB 官方文档
---
setRetentionPolicy
语法
setRetentionPolicy(dbHandle, retentionHours,
[retentionDimension], [hoursToColdVolume])
详情
设置数据保留策略以及
TieredStorage
策略。若用户只通过该函数配置分级存储策略,建议将参数
retentionHours
指定为一个尽可能大的值。
分级存储和数据保留策略都以分区为单位进行,因此
retentionHours
和
hoursToColdVolume
配置的时间必须是分区精度的倍数,如按天分区,则需要为 24 的整数倍。
数据库会根据当前系统的机器时间,保留数据时间戳为最近
retentionHours
小时的数据。其中最新
hoursToColdVolume
小时的数据将继续存储在 volumes 中。在 [当前时间 -
hoursToColdVolume
- 10天,当前时间 -
hoursToColdVolume
) 范围内的数据将被迁移到
coldVolumes
。若
coldVolumes
配置了多个路径,则数据将随机分布在各个存储路径下 。
对于保留时间外的数据,只会删除 [当前时间 -
retentionHours
- 10 天, 当前时间 -
retentionHours
) 范围的数据。若需要删除之前的数据,可以调用
dropPartition
函数实现。
注:
该函数只能对分布式数据库使用。
可以通过
schema
函数查看数据库的数据保留时间。
参数
dbHandle
分布式数据库的句柄。数据库的分区方案必须包含 DATE 类型或 DATEHOUR 类型。
retentionHours
正整数,表示数据保留时间,单位是小时。
retentionDimension
整数,表示时间分区所在的层次。默认值是0,表示第一层分区是按时间分区。
hoursToColdVolume
正整数,表示 volumes 数据的保留时间,单位是小时。存储在 volumes
中的数据,经过
hoursToColdVolume
指定的时间后,将会自动迁移至
coldVolumes(该配置项需在配置文件中预先指定)。若不指定该参数,则 volumes 数据不会自动迁移。
注:
必须满足
retentionHours
-
hoursToColdVolume
> 7 *
24(即 7 天)
例子
db=database("dfs://db1",VALUE,2019.06.01..date(now()))
retentionHour=9*24
hoursToColdVolume=1*24
setRetentionPolicy(db,retentionHour,0, hoursToColdVolume);
schema(db);
// output
partitionSchema->[2022.05.05,2022.05.04,2022.05.03,2022.05.02,2022.05.01,2022.04.30,2022.04.29,2022.04.28,2022.04.27,2022.04.26,...]
partitionSites->
partitionTypeName->VALUE
hoursToColdVolume->24
atomic->TRANS
databaseDir->dfs://db1
engineType->OLAP
chunkGranularity->TABLE
retentionDimension->0
partitionType->1
retentionHours->216
FILE:references/doc_5035.md
# nanotime
**URL**: https://docs.dolphindb.cn/zh/funcs/n/nanotime.html
**来源**: DolphinDB 官方文档
---
nanotime
语法
nanotime(X)
详情
返回相应的纳秒。返回值类型是 NANOTIME,时间类型的变量。
参数
X
可以是整型标量或向量、时间标量或向量。
返回值
NANOTIME 类型标量或向量。
例子
nanotime(1000000000);
返回:00:00:01.000000000
nanotime(12:06:09 13:08:01);
返回:[12:06:09.000000000,13:08:01.000000000]
nanotime(2012.12.03 01:22:01.123456789);
返回:01:22:01.123456789
nanotime('13:30:10.008007006');
返回:13:30:10.008007006
FILE:references/doc_5040.md
# fflush
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fflush.html
**来源**: DolphinDB 官方文档
---
fflush
语法
fflush(obj)
详情
将缓冲区中的数据写入操作系统的文件系统。该函数必须要用户登录后才能执行。
注:
将数据写入文件,建议通过
close
关闭该文件或通过
fflush
强制将缓冲区的数据写入文件,否则可能丢失数据。
该命令并没有将数据刷入磁盘,因此,发生意外宕机时可能会出现数据丢失。
参数
obj
是一个文件句柄。通常使用函数
file
打开一个文件获得一个文件句柄。
返回值
无。
例子
rows = 10
t=table(1..rows as id, 1..rows+100 as value)
f1=file("test.bin", "w")
f1.writeRecord(t)
// 没有关闭文件或者将缓冲区数据刷入文件。此时读取的文件并不包含新写入的数据
t1 = table(rows:0,`id`value,`INT`INT)
f=file('test.bin')
f.readRecord!(t1)
// readRecord!(f, t1) => Reach the end of a file or a buffer.
// 调用 fflush
f1.fflush()
t1 = table(rows:0,`id`value,`INT`INT)
f=file('test.bin')
f.readRecord!(t1)
10
FILE:references/doc_5048.md
# invLogistic
**URL**: https://docs.dolphindb.cn/zh/funcs/i/invLogistic.html
**来源**: DolphinDB 官方文档
---
invLogistic
语法
invLogistic(mean, s, X)
详情
返回 Logistic 分布的累计密度函数的逆函数值。
参数
mean
是 Logistic 分布的均值。
s
是Logistic分布的尺度参数。
X
是0到1之间的浮点型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
invLogistic( 2.31, 0.627, [0.5, 0.3, 0.5, 0.7, 0.1]);
// output: [2.31, 1.778744, 2.31, 2.841256, 0.93234]
FILE:references/doc_505.md
# getUserAccessByCluster
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getUserAccessByCluster.html
**来源**: DolphinDB 官方文档
---
getUserAccessByCluster
语法
getUserAccessByCluster(users, cluster, finalAccess)
详情
查询指定用户在多集群系统中的权限信息。只能由管理员在 MoM(Master of Master,管理集群)上执行该函数。
参数
users
字符串向量,表示要查询的用户名称。
cluster
字符串标量,表示要查询的用户所在集群的名称。
finalAccess
布尔标量,表示是否获取用户及其所属组权限叠加的结果。
返回值
一个表,字段与
getUserAccess
函数的返回结果一致。
例子
getUserAccessByCluster(["admin"], "masterOfMaster", true)
userId
groups
isAdmin
ACCESS_READ
ACCESS_INSERT
ACCESS_UPDATE
ACCESS_DELETE
VIEW_EXEC
SCRIPT_EXEC
TEST_EXEC
DBOBJ_CREATE
...
admin
1
allow
allow
allow
allow
allow
allow
allow
allow
...
相关函数:
getUserAccess
FILE:references/doc_5055.md
# startDataNode
**URL**: https://docs.dolphindb.cn/zh/funcs/s/startDataNode.html
**来源**: DolphinDB 官方文档
---
startDataNode
语法
startDataNode(X)
详情
用于在集群控制器上启动数据节点/计算节点。
参数
X
是一个向量。包含了要启动的数据节点/计算节点的信息。
例子
x = ["192.168.1.27:8506","192.168.1.27:8502","192.168.1.27:8527"]
startDataNode(x);
FILE:references/doc_506.md
# writeLogLevel
**URL**: https://docs.dolphindb.cn/zh/funcs/w/writeloglevel.html
**来源**: DolphinDB 官方文档
---
writeLogLevel
语法
writeLogLevel(level,X1,[X2, X3,...,Xn])
详情
在日志文件中写入指定等级的日志。该命令只能由管理员调用。
注:
level
的等级必须等于或高于配置项
logLevel
或命令
setLogLevel
设置的等级,否则不会输出日志到文件中。
参数
level
日志等级,从低到高可选值为:DEBUG, INFO, WARNING, ERROR,分别对应数字 0,
1, 2, 3。
X1
,
X2
,
X3
...
Xn
要写入日志文件的内容。每个 Xi
都是日志文件中的一行。支持以下数据类型:Logical, Integral, Temporal, Floating, Literal, Decimal。
返回值
无。
例子
writeLogLevel(INFO,111111111111,"This is an INFO message")
// Check the log file.
<INFO> :111111111111
<INFO> :This is an INFO message
FILE:references/doc_5077.md
# mcorrTopN
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mcorrTopN.html
**来源**: DolphinDB 官方文档
---
mcorrTopN
语法
mcorrTopN(X, Y, S, window, top, [ascending=true],
[tiesMethod='oldest'])
参数说明和窗口计算规则请参考:
mTopN
详情
在给定长度(以元素个数衡量)的滑动窗口内,根据
ascending
指定的排序方式将
X
和
Y
按照
S
进行稳定排序后,取前
top
个元素,然后计算
Y
和
X
的相关性。
返回值
计算结果为 DOUBLE 类型,形式同输入参数。
例子
a = 2 5 3 1 9
b = 2 3 1 7 13
s = 6 8 4 2 7
mcorrTopN(a, b, s, 4, 3)
// output: [ , 1, 0.6547, -0.9333, 0.7206]
s2=2021.01.01 2021.02.03 2021.01.23 2021.04.06 2021.12.29
mcorrTopN(a, b, s2, 4, 3)
// output: [ , 1, 0.6547, 0.6547, -0.6547]
a1 = matrix(a, 4 3 6 2 3)
b1=matrix(3 7 9 3 2, b)
s1=matrix(2 3 1 7 3, s)
mcorrTopN(a, b1, s1, 4, 3)
col1
col2
1
1
0.5
0.6547
0.5
-0.9333
-0.9986
0.7206
mcorrTopN(a1, b1, s, 4, 3)
col1
col2
1
-1
0.5
-0.982
0.866
-0.9333
-0.4018
-0.7206
mcorrTopN(a1, b1, s1, 4, 3)
col1
col2
1
-1
0.5
-0.982
0.5
-0.9333
-0.9986
-0.7206
n = 3000
ids = 1..3000
dates = take(2021.01.01..2021.10.01,n)
prices = rand(1000,n)
vals = rand(1000,n)
t = table(ids as id,dates as date,prices as price,vals as val)
dbName = "dfs://test_mcorrTopN_2"
if(existsDatabase(dbName))dropDB(dbName)
db = database(dbName,VALUE,1..5000)
pt = db.createPartitionedTable(t,"pt",`id).append!(t)
select mcorrTopN(price, val, id, 10, 5, true) from pt where date>2021.05.01
相关函数:
mcorr
FILE:references/doc_5080.md
# enableQueryMonitor
**URL**: https://docs.dolphindb.cn/zh/funcs/e/enableQueryMonitor.html
**来源**: DolphinDB 官方文档
---
enableQueryMonitor
语法
enableQueryMonitor()
详情
启用监控查询任务状态的功能。系统默认会开启该功能。
参数
无
返回值
无。
相关函数:
disableQueryMonitor
FILE:references/doc_51.md
# spearmanr
**URL**: https://docs.dolphindb.cn/zh/funcs/s/spearmanr.html
**来源**: DolphinDB 官方文档
---
spearmanr
语法
spearmanr(X, Y)
详情
计算
X
和
Y
的 Spearman 等级相关系数。
spearman
函数在计算时会忽略 NULL 值。Spearman
相关性是两个数据集之间关系的单调性的非参数度量,该系数在-1和+1之间变化,其中0表示无相关。-1或+1意味着确切的单调关系。正相关表明,随着
X
的增加,
Y
也随之增加。负相关性表示随着
X
增加,
Y
减少。
若
X
或
Y
是矩阵,计算每列的 Spearman 等级相关系数,返回一个向量。
参数
X
是一个向量或矩阵。
Y
是一个向量或矩阵。
返回值
若 X 或 Y 是向量,返回一个标量。
若 X 或 Y 是矩阵,返回一个向量。
例子
x=[2013.06.13, 2013.06.14, 2013.06.15]
y=1 5 3
spearmanr(x, y)
// output
0.5
x = [33,21,46,-11,78,47,18,20,-5,66]
y = [1,NULL,10,6,10,3,NULL,NULL,5,3]
spearmanr(x, y)
// output
0.109109
如果
X
是矩阵,
Y
可以是标量、向量或者是与
X
行数相同的矩阵。返回结果是与
X
列数相同的向量。
m1 = [34,77,35,-40,-39,-86,49,-55,15,72,NULL,-24,16,20,26,-82,80,-93,-65,99,45,90,44,46]$4:6
m2 = [0, 25, 7, 3]
spearmanr(m1, m2)
// output
[0.8, -0.4, 0.5, 0.6, -0.8, 0.4]
FILE:references/doc_5102.md
# parseInteger
**URL**: https://docs.dolphindb.cn/zh/funcs/p/parseInteger.html
**来源**: DolphinDB 官方文档
---
parseInteger
语法
parseInteger(X, type, [radix=10])
别名:
parseInt
详情
按照不同进制把字符串转换为指定的整数类型。该函数从
X
的第一个字符开始转换,直到遇到第一个非法字符,即返回此前的转换结果。当 X
为集合时,将输出相同类型的集合。
注意:
转换时会忽略前导空格和前导 0。
不支持转换小数,'.'字符属于非法字符。
如果(忽略前导空格后)字符串为空,则返回 NULL。
如果在遇到非法字符前没有遇到过合法字符,函数将抛出异常。
前导空格后的第一个字符可以为'+'/'-'以表示正/负语义,其余位置上的'+'/'-'为非法字符。
参数
X
表示待转换的字符串,支持标量、矩阵、向量和数据对。
type
表示转换后的类型,支持 CHAR/SHORT/INT/LONG。
radix
表示基数,可选参数,有效范围为[2, 16],默认为 10。如
radix
为2,那么
X
的“合法字符”就指{“0”, “1”};
radix
为11,那么”合法字符”就指[0, 9]和 A/a(不区分大小写)。特别的,如果
radix
为16,那么前导的”0x”或”0X”不会被认为非法字符。
返回值
整型标量、矩阵、向量或数据对。
例子
以下给出几个简单示例。
parseInteger([" ", "000", "012", " 12","12a", "1a2","+12a", "-12"], INT)
//output: [ , 0, 12, 12, 12, 1, 12, -12]
parseInteger("a12", INT)
//Error: 'Invalid string to parse.'
parseInteger(["012", " 12","12a", "1a2","1A2", "-1A2"], INT, 11)
//output: [13, 13, 153, 233, 233, -233]
parseInteger(["0x16", "0X16"], INT)//output:[0, 0]
parseInteger(["0x16", "0X16"], INT, 16)//output:[22, 22]
parseInteger( "9" , INT, 8)
//Error: 'Invalid string to parse.'
FILE:references/doc_5103.md
# charAt
**URL**: https://docs.dolphindb.cn/zh/funcs/c/charAt.html
**来源**: DolphinDB 官方文档
---
charAt
语法
charAt(X, Y)
详情
返回字符串中指定位置的字符。返回的结果是 CHAR 类型。
参数
X
是字符串标量或向量。
Y
是整型标量或与
X
长度相同的整型向量。
返回值
CHAR 类型标量或向量。
例子
s=charAt("abc",2);
s;
// output
'c'
typestr(s);
// output
CHAR
charAt(["hello","world"],[3,4]);
// output
['l','d']
FILE:references/doc_5106.md
# setComputeNodeCachingDelay
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setcomputenodecachingdelay.html
**来源**: DolphinDB 官方文档
---
setComputeNodeCachingDelay
语法
setComputeNodeCachingDelay(delay)
详情
在线设置当前节点下配置项
computeNodeCachingDelay
的生效值。只能由管理员在控制节点执行。
参数
delay
非负整数,表示时间间隔,单位为秒。
例子
setComputeNodeCachingDelay(580)
相关函数:
getComputeNodeCachingDelay
FILE:references/doc_5107.md
# rollingPanel
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rollingPanel.html
**来源**: DolphinDB 官方文档
---
rollingPanel
语法
rollingPanel(X, window, [groupingCol])
详情
滚动截取数据表
X
中固定数量的行,产生一个新的数据表。若
groupingCol
指定,分组进行上述操作。
结果中 panelNumber 列为每次截取的数据的编号,从0开始。
参数
X
是一个数据表。
window
是一个正整数,表示窗口长度。
groupingCol
是一个字符串标量或向量,表示数据表
X
中的某个或某些列。
返回值
返回一个表。
例子
t=table(1 1 1 1 1 2 2 2 2 2 as id, 1..10 as x);
rollingPanel(t, 3, `id);
id
x
panelNumber
1
1
0
1
2
0
1
3
0
1
2
1
1
3
1
1
4
1
1
3
2
1
4
2
1
5
2
2
6
3
2
7
3
2
8
3
2
7
4
2
8
4
2
9
4
2
8
5
2
9
5
2
10
5
FILE:references/doc_5108.md
# textChunkDS
**URL**: https://docs.dolphindb.cn/zh/funcs/t/textChunkDS.html
**来源**: DolphinDB 官方文档
---
textChunkDS
语法
textChunkDS(filename, chunkSize, [delimiter], [schema], [skipRows=0]
,
[arrayDelimiter],
[containHeader],
[arrayMarker]
)
详情
将文件划分为多个数据源,每个数据源的大小为
chunkSize
。如果需要将大文本文件加载到 DolphinDB, 可以使用
textChunkDS
函数将文本文件划分为多个小文件数据源,再通过
mr
函数写入到数据库中。与直接把大文本文件加载到数据库对比,这种方法占用的内存更少。
当 DolphinDB
加载数据文件时,会进行随机抽样,并基于样本决定每列的数据类型。这个方法不一定每次都能准确决定各列的数据类型。因此我们建议,在加载数据前,使用
extractTextSchema
函数查看 DolphinDB
识别每列的数据类型。如果 DolphinDB 识别的数据类型不符合预期,可以在
schema
的 type 列中指定数据类型。对于日期列或时间列,如果
DolphinDB 识别的数据类型不符合预期,不仅需要在
schema
的 type 列指定时间类型,还需要在 format
列中指定数据文件中日期或时间的格式(用字符串表示),如 "MM/dd/yyyy"。如何表示日期和时间格式请参考
日期和时间的调整及格式
。
参数
filename
一个字符串,表示文件的绝对路径。仅支持 CSV 格式的文件。若传入其他格式文件,则无法保证数据准确性。
chunkSize
1 到 2048 之间的整数,表示文件块的大小,单位是 MB。
delimiter
字符串标量,表示数据文件中各列的分隔符。分隔符可以是一个或多个字符,默认是逗号(",")。
schema
表对象,用于指定各字段的数据类型。具体请参考
loadText
的
schema
参数。
skipRows
0 到 1024 之间的整数,表示从文件头开始忽略的行数。它是一个可选参数。默认值为 0。
arrayDelimiter
数据文件中数组向量列的分隔符。默认是逗号。由于不支持自动识别数组向量,必须同步修改
schema
的 type 列修为数组向量类型。
containHeader
布尔值,表示数据文件是否包含标题行,默认为空。具体请参考
loadText
的
containHeader
参数。
arrayMarker
包含两个字符的字符串或或 CHAR
类型数据对,两个字符分别表示数组向量左右边界的标识符。默认标识符为双引号(")。
不能包含空格、Tab(
\t
)
和换行符(
\t
和
\n
)。
不能包含数字或字母。
如果其中一个为双引号("),另一个也必须为双引号。
如果标识符为
'
,
"
或
\
,需视情况添加转义符。例如
arrayMarker="\"\""
。
如果
delimiter
是单个字符,则
arrayMarker
不能包含与其相同的字符。
如果
delimiter
是多个字符,则
arrayMarker
左边界不能与
delimiter
的首个字符相同。
返回值
DATASOURCE 元组。
例子
首先,通过以下脚本生成一个大约 3.2G 的文本文件:
n=30000000
workDir = "/home/DolphinDB"
if(!exists(workDir)) mkdir(workDir)
trades=table(rand(`IBM`MSFT`GM`C`FB`GOOG`V`F`XOM`AMZN`TSLA`PG`S,n) as sym, 2000.01.01+rand(365,n) as date, 10.0+rand(2.0,n) as price1, 100.0+rand(20.0,n) as price2, 1000.0+rand(200.0,n) as price3, 10000.0+rand(2000.0,n) as price4, 10000.0+rand(3000.0,n) as price5, 10000.0+rand(4000.0,n) as price6, rand(10,n) as qty1, rand(100,n) as qty2, rand(1000,n) as qty3, rand(10000,n) as qty4, rand(10000,n) as qty5, rand(10000,n) as qty6)
trades.saveText(workDir + "/trades.txt");
通过
textChunkDS
函数和
mr
函数将该文件导入到分布式数据库中:
db=database("dfs://db1",VALUE, `IBM`MSFT`GM`C`FB`GOOG`V`F`XOM`AMZN`TSLA`PG`S)
pt=db.createPartitionedTable(trades,`pt,`sym)
ds=textChunkDS(workDir + "/trades.txt",500)
mr(ds,append!{pt},,,false)
注:
每个小文件数据源可能包含相同分区的数据。DolphinDB 不允许多个线程同时对相同分区进行写入,因此要将
mr
函数
parallel
参数设置为 false,否则会抛出异常。
FILE:references/doc_5122.md
# exp
**URL**: https://docs.dolphindb.cn/zh/funcs/e/exp.html
**来源**: DolphinDB 官方文档
---
exp
语法
exp(X)
详情
返回 e 的
X
次方。e 是一个常数,为2.71828。
参数
X
可以是标量、数据对、向量、矩阵或表。
返回值
DOUBLE 类型,其数据形式同
X
。
例子
exp(1 2 3);
// output
[2.718282,7.389056,20.085537]
log(exp(1));
// output
1
FILE:references/doc_5125.md
# 异常检测引擎
**URL**: https://docs.dolphindb.cn/zh/stream/anomaly_detection_engine.html
**来源**: DolphinDB 官方文档
---
异常检测引擎
物联网设备(如机床、锅炉、电梯、水表、气表等)无时无刻不在产生海量的设备状态数据和业务消息数据。在这些数据的采集、计算和分析过程中,常常需要进行异常数据的检测。
为满足这一需求,DolphinDB
提供了基于流数据框架的异常检测引擎函数。用户只需指定异常指标,异常检测引擎就可以实时地进行异常数据检测。该引擎会根据用户指定的条件指标,自动筛查数据,并仅输出符合指标条件的数据。它常用于对实时数据进行监控的场景,因此在物联网场景下有较广泛的应用,金融领域的风控场景也可以使用该引擎。
物联网:对设备进行监测,例如监测设备温度、湿度;电力监控,例如电压,用电量等。
金融:风控场景,例如根据指定规则过滤订单,监控股票成交量,设置超量预警信号等。
概念介绍
异常检测引擎由
createAnomalyDetectionEngine
函数创建。语法如下:
createAnomalyDetectionEngine(name, metrics, dummyTable,
outputTable, timeColumn, [keyColumn], [windowSize], [step], [garbageSize],
[roundTime=true], [snapshotDir], [snapshotIntervalInMsgCount],
[raftGroup],[anomalyDescription])
异常指标
异常指标是以元代码的格式提供一组处理流数据的布尔表达式。通常是一个函数或一个表达式,其中可以包含聚合函数,以支持复杂的场景。当指标中包含聚合函数时,必须指定窗口长度和计算的时间间隔,每隔一段时间,在固定长度的移动窗口中计算指标。
异常指标一般有以下三种类型:
某个列与常量对比、列与列之间对比或非聚合函数中没有嵌套聚合函数,例如 qty < 4, qty > price, lt(qty,
prev(qty)), isNull(qty) == false
等。对于这类指标,异常检测引擎会对每一条数据进行计算,判断是否符合条件并决定输出。
聚合函数的结果与某个常量值对比、聚合函数结果之间的对比、非聚合函数中仅嵌套聚合函数和常量,例如 avg(qty - price) > 10,
percentile(qty, 90) < 100, max(qty) < avg(qty) * 2, le(sum(qty), 5)
等。对于这类指标,异常检测引擎会在每个窗口计算时判断计算结果是否符合条件并决定输出。
聚合函数的结果与列对比、非聚合函数中同时嵌套聚合函数和列,例如 avg(qty) > qty, le(med(qty), price)
等。对于这类指标,每当数据到达时,异常检测引擎会将数据与上一个计算窗口的聚合结果对比,判断计算结果是否符合条件并决定输出,直到触发下一次聚合计算。
数据窗口
当异常指标中包含聚合函数时,用户必须指定数据窗口。流数据聚合计算是每隔一段时间,在固定长度的移动窗口中进行。窗口长度由参数
windowSize
设定;计算的时间间隔由参数
step
设定。
在有多组数据的情况下,若每组都根据各自第一条数据进入系统的时间来构造数据窗口的边界,则一般无法将各组的计算结果在相同数据窗口中进行对比。考虑到这一点,系统按照参数
step
值确定一个整型的规整尺度
alignmentSize
,以对各组第一个数据窗口的边界值进行规整处理。
当数据时间类型为MONTH时,会以第一条数据对应年份的1月作为窗口的上边界。
当数据的时间类型为DATE时,不对第一个数据窗口的边界值进行规整。
若数据的时间精度为分钟,如 MINUTE(HH:mm) 类型,alignmentSize 取值如下:
若 roundTime = false
:
step
alignmentSize
0~2
2
3
3
4~5
5
6~10
10
11~15
15
16~20
20
21~30
30
>30
60 (1小时)
若 roundTime = true
:
当 step <= 30 时,alignmentSize 取值同上表。当 step > 30
时,alignmentSize 取值见下表:
step
alignmentSize
31~60
60 (1小时)
61~120
120 (2小时)
121~180
180 (3小时)
181~300
300 (5小时)
301~600
600 (10小时)
601~900
900 (15小时)
901~1200
1200 (20小时)
1201~1800
1800 (30小时)
>1800
3600 (60小时)
若数据的时间精度为秒,如 DATETIME(yyyy-MM-dd HH:mm:ss) 与
SECOND(HH:mm:ss) 类型,alignmentSize 的 取值如下:
若
roundTime = false
:
step
alignmentSize
0~2
2
3
3
4~5
5
6~10
10
11~15
15
16~20
20
21~30
30
>30
60 (1分钟)
若 roundTime = true
:
当 step <= 30
时,alignmentSize 取值同上表。当 step > 30 时,alignmentSize 取值见下表:
step
alignmentSize
31~60
60 (1分钟)
61~120
120 (2分钟)
121~180
180 (3分钟)
181~300
300 (5分钟)
301~600
600 (10分钟)
601~900
900 (15分钟)
901~1200
1200 (20分钟)
1201~1800
1800 (30分钟)
>1800
3600 (1小时)
若数据的时间精度为毫秒,如 TIMESTAMP(yyyy-MM-dd HH:mm:ss.mmm) 与
TIME(HH:mm:ss.mmm) 类型,alignmentSize 的取值如下:
若 roundTime = false
:
step
alignmentSize
0~2
2
3~5
5
6~10
10
11~20
20
21~25
25
26~50
50
51~100
100
101~200
200
201~250
250
251~500
500
501~1000
1000(1秒)
1001~2000
2000(2秒)
2001~3000
3000(3秒)
3001~5000
5000(5秒)
5001~10000
10000(10秒)
10001~15000
15000(15秒)
15001~20000
20000(20秒)
20001~30000
30000(30秒)
>30000
60000(1分钟)
若 roundTime = true
:
若
step
<= 30000,alignmentSize 取值同上表;若
step
> 30000,alignmentSize 取值见下表:
step
alignmentSize
30001~60000
60000(1分钟)
60001~120000
120000(2分钟)
120001~300000
300000(5分钟)
300001~600000
600000(10分钟)
600001~900000
900000(15分钟)
900001~1200000
1200000(20分钟)
1200001~1800000
1800000(30分钟)
>1800000
3600000(1小时)
若数据的时间精度为纳秒,如 NANOTIMESTAMP(yyyy-MM-dd
HH:mm:ss.nnnnnnnnn) 与 NANOTIME(HH:mm:ss.nnnnnnnnn) 类型,alignmentSize
的取值如下:
若 roundTime = false
:
step
alignmentSize
0~2ns
2ns
3ns~5ns
5ns
6ns~10ns
10ns
11ns~20ns
20ns
21ns~25ns
25ns
26ns~50ns
50ns
51ns~100ns
100ns
101ns~200ns
200ns
201ns~250ns
250ns
251ns~500ns
500ns
>500ns
1000ns
若 roundTime = true
:
step
alignmentSize
1000ns~1ms
1ms
1ms~10ms
10ms
10ms~100ms
100ms
100ms~1s
1s
1s~2s
2s
2s~3s
3s
3s~5s
5s
5s~10s
10s
10s~15s
15s
15s~20s
20s
20s~30s
30s
>30s
1min
假设第一条数据的时间为 x,
那么根据其类型,第一个数据窗口的左边界的计算规则为:
timeType_cast(x/alignmentSize*alignmentSize+step-windowSize)
。其中,timeType_cast
表示依据时间精度,需要强制转换的时间类型;'/' 表示整除。例如,第一条数据的时间为 2018.10.08T01:01:01.365,windowSize 为
120000,step 为 60000,那么 alignmentSize 为 60000,第一个数据窗口的左边界为
timestamp(2018.10.08T01:01:01.365/60000*60000+60000-120000)
,即
2018.10.08T01:00:00.000。
应用示例1
现模拟传感器设备采集温度。假设窗口长度为 4ms,每隔 2ms 移动一次窗口,每隔 1ms 采集一次温度,规定以下异常指标:
单次采集的温度超过 65;
单次采集的温度超过上一个窗口中 75% 的值;
采集的数据存放到流数据表中,异常检测引擎通过订阅流数据表来获取实时数据,并进行异常检测,符合异常指标的数据输出到另外一个表中。
实现步骤如下:
(1) 定义流数据表
sensor
来存放采集的数据:
share streamTable(
1000
:
0
, `time`temp, [TIMESTAMP, DOUBLE])
as
sensor
(2) 定义异常检测引擎和输出表
outputTable
,输出表也是流数据表:
share streamTable(
1000
:
0
, `time`anomalyType`anomalyString, [TIMESTAMP, INT, SYMBOL])
as
outputTable
engine = createAnomalyDetectionEngine(name=
"engine1"
, metrics=<[temp >
65
, temp > percentile(temp,
75
)]>, dummyTable=sensor, outputTable=outputTable, timeColumn=`time, windowSize=
6
, step=
3
)
(3) 异常检测引擎 engine 订阅流数据表
sensor
:
subscribeTable(,
"sensor"
,
"sensorAnomalyDetection"
,
0
, append!{engine}, true)
(4) 向流数据表
sensor
中写入 10 次数据模拟采集温度:
timev =
2018.10
.
08
T01:
01
:
01.001
+
1.
.10
tempv =
59
66
57
60
63
51
53
52
56
55
insert into sensor values(timev, tempv)
查看流数据表
sensor
的内容:
time
temp
2018.10.08T01:01:01.002
59
2018.10.08T01:01:01.003
66
2018.10.08T01:01:01.004
57
2018.10.08T01:01:01.005
60
2018.10.08T01:01:01.006
63
2018.10.08T01:01:01.007
51
2018.10.08T01:01:01.008
53
2018.10.08T01:01:01.009
52
2018.10.08T01:01:01.010
56
2018.10.08T01:01:01.011
55
再查看结果表
outputTable
:
time
anomalyType
anomalyString
2018.10.08T01:01:01.003
0
temp > 65
2018.10.08T01:01:01.003
1
temp > percentile(temp, 75)
2018.10.08T01:01:01.005
1
temp > percentile(temp, 75)
2018.10.08T01:01:01.006
1
temp > percentile(temp, 75)
下面详细解释异常检测引擎的计算过程。为方便阅读,对时间的描述中省略相同的 2018.10.08T01:01:01 部分,只列出毫秒部分。
(1)指标
temp > 65
只包含不作为函数参数的列 temp,因此会在每条数据到达时计算。模拟数据中只有 003
时的温度满足检测异常的指标。
(2)指标
temp > percentile(temp, 75)
中,temp
列既作为聚合函数
percentile
的参数,又单独出现,因此会在每条数据到达时,将其中的
temp
与上一个窗口计算得到的
percentile(temp,
75)
比较。第一个窗口基于第一行数据的时间 002 进行对齐,对齐后窗口起始边界为 000,第一个窗口是从 000 到 002,只包含
002 一条记录,计算
percentile(temp, 75)
的结果是 59,数据 003 到 005
与这个值比较,满足条件的有 003 和 005。第二个窗口是从 002 到 005,计算
percentile(temp,
75)
的结果是 60,数据 006 到 008 与这个值比较,满足条件的有 006。第三个窗口是从 003 到
008,计算
percentile(temp, 75)
的结果是 63,数据 009 到 011
与这个值比较,其中没有满足条件的行。最后一条数据 011 到达后,尚未触发新的窗口计算。
监控异常检测引擎的状态
getStreamEngineStat().AnomalyDetectionEngine
name
user
status
lastErrMsg
numGroups
numRows
numMetrics
metrics
snapshotDir
snapshotInterval
snapshotMsgId
snapshotTimestamp
garbageSize
memoryUsed
engine1
admin
OK
1
10
2
temp > 65, temp > percentile(temp, 75)
-1
2,000
8,524
应用例子 2
快照机制可以用于系统出现异常之后,对引擎进行恢复。通过以下这个例子,可以理解
snapshotDir
和
snapshotIntervalInMsgCount
的作用。如果启用snapshot,引擎订阅流表时,
handler
需是
appendMsg
函数,需指定
handlerNeedMsgId
=
true,用来记录快照的消息位置。
WORK_DIR=
"/home/root/WORK_DIR"
mkdir(WORK_DIR+
"/snapshotDir"
)
enableTableShareAndPersistence(table = streamTable(
10000
:
0
,`time`sym`price`qty, [TIMESTAMP,SYMBOL,DOUBLE,INT]) , tableName=
"trades"
, cacheSize=
1000000
)
enableTableShareAndPersistence(table = streamTable(
10000
:
0
, `time`sym`type`metric, [TIMESTAMP,STRING,INT,STRING]), tableName =
"output"
, cacheSize=
1000000
)
go
adengine = createAnomalyDetectionEngine(name=
"test"
, metrics=<[avg(qty)>
1
]>, dummyTable=trades, outputTable=output, timeColumn=`time, keyColumn=`sym, windowSize=
10
, step=
10
, snapshotDir=WORK_DIR+
"/snapshotDir"
, snapshotIntervalInMsgCount=
100
)
subscribeTable(server=
""
, tableName=
"trades"
, actionName=
"adengine"
,offset=
0
, handler=appendMsg{adengine}, msgAsTable=true, handlerNeedMsgId=true)
def
writeData(mutable t){
do{
batch =
10
tmp = table(batch:batch, `time`sym`price`qty, [TIMESTAMP, SYMBOL, DOUBLE, DOUBLE])
tmp[`time] = take(now(), batch)
tmp[`sym] =
"A"
+string(
1.
.batch)
tmp[`price] = round(rand(
100.0
, batch),
2
)
tmp[`qty] = rand(
10
, batch)
t.append!(tmp)
sleep(
1000
)
}
while
(true)
}
job1=submitJob(
"write"
,
""
, writeData, trades)
//执行一段时间后重启server
enableTableShareAndPersistence(table = streamTable(
10000
:
0
,`time`sym`price`qty, [TIMESTAMP,SYMBOL,DOUBLE,INT]) , tableName=
"trades"
, cacheSize=
1000000
)
enableTableShareAndPersistence(table = streamTable(
10000
:
0
, `time`sym`type`metric, [TIMESTAMP,STRING,INT,STRING]), tableName =
"output"
, cacheSize=
1000000
)
select last(time)
from
output
>
2021.03
.
16
T11:
59
:
10.920
select last(time)
from
trades
>
2021.03
.
16
T11:
59
:
13.916
WORK_DIR=
"/home/root/WORK_DIR"
adengine = createAnomalyDetectionEngine(name=
"test"
, metrics=<[avg(qty)>qty]>, dummyTable=trades, outputTable=output, timeColumn=`time, keyColumn=`sym, windowSize=
10
, step=
10
, snapshotDir=WORK_DIR+
"/snapshotDir"
, snapshotIntervalInMsgCount=
100
)
ofst = getSnapshotMsgId(adengine)
print
(ofst)
>
299
select count(*)
from
trades
>
390
//从第300条数据开始订阅
subscribeTable(server=
""
, tableName=
"trades"
, actionName=
"adengine"
,offset=ofst+
1
, handler=appendMsg{adengine}, msgAsTable=true, handlerNeedMsgId=true)
FILE:references/doc_5126.md
# 插件
**URL**: https://docs.dolphindb.cn/zh/plugins/plg_intro.html
**来源**: DolphinDB 官方文档
---
插件
插件一览
类型
插件名称
图像
GP
数据存取
HBase
Kdb+
MongoDB
MySQL
ODBC
OPCUA
OPC
Redis
Schemaless
Writer
HDFS
LDAP
金融
amdQuote
INSIGHT
NSQ
Matching
Engine
模拟撮合引擎
Backtest
CTP
EFH
DataFeed
XTP
SSEQuotationFile
WindTDF
MDL
SimulatedExchangeEngine
消息队列
Kafka
zmq
mqtt
pulsar
RabbitMQ
RocketMQ
数值计算
Signal
gurobi
网络
HTTP
Client
TCPSocket
WebSocket
云存储
AWS
机器学习
xgboost
SVM
扩展接口
Py(3.9
及以上版本)
、
Py(3.6/3.7版本)
格式处理
Feather
Arrow
mseed
mat
Parquet
HDF5
EncoderDecoder
ORC
Zip
Zlib
注:
有关插件使用的一般规则、插件开发的相关介绍,参考:
插件开发教程
。
插件下载
下载途径
安装方法
官网插件市场
前往
https://marketplace.dolphindb.cn/
注册个人用户。
如已创建,跳过此步。
在
https://marketplace.dolphindb.cn/
中选择所需插件。
点击
下载安装包
。
选择
DolphinDB 版本
以及面向
不同操作系统
的插件安装包后下载。
解压下载的插件压缩包到
/server/plugins/
目录下。
在客户端中使用
loadPlugin
命令加载插件。以下载 MySQL
插件为例,加载方法为:
loadPlugin("mysql")
。
客户端
参考:
通过插件仓库安装插件
Gitee
由于某些插件尚未上线插件仓库,您可以访问
DolphinDB
插件
,选择版本分支,在以插件名称命名的插件目录下载插件的安装文件。例如:与 DolphinDB server
2.00.11 版本对齐的插件可通过选择 release200.11 分支。下载后,将插件包放置在
/server/plugins/
目录下,在客户端中使用
loadPlugin
命令加载插件。
通过插件仓库安装插件
以安装 MySQL 插件为例,从插件仓库中获取并安装插件的步骤如下:
在 DolphinDB 客户端中使用
listRemotePlugins
命令查看插件仓库中的插件信息。
login("admin", "123456")
listRemotePlugins()
注:
本步骤中使用的登录账号为初始管理员账号。请根据实际的管理员账号和密码相应调整。
使用
installPlugin
命令完成插件安装。以
MySQL
插件为例:
installPlugin("mysql")
注:
某些插件存在多个版本,例如 amdQuote,此时需要在使用
installPlugin
命令指定包含了版本号的插件名称。例如:
installPlugin("amdQuote401")
。其中,
"401" 对应华锐 AMD 平台 SDK 的版本号,以此类推。
使用
loadPlugin
命令加载插件。依然以 MySQL
插件为例:
loadPlugin("mysql")
注:
部分插件存在多个版本号时,例如 amdQuote,此时需要在使用
loadPlugin
命令指定包含了版本号的插件名称。例如:
loadPlugin("amdQuote401")
FILE:references/doc_5138.md
# invF
**URL**: https://docs.dolphindb.cn/zh/funcs/i/invF.html
**来源**: DolphinDB 官方文档
---
invF
语法
invF(numeratorDF, denominatorDF, X)
详情
返回F分布的累计密度函数的逆函数值。
参数
numeratorDF
和
denominatorDF
都是正数,表示F分布的自由度。
X
是0到1之间的浮点型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
invF(2.31, 0.627, [0.001, 0.5, 0.7]);
// output: [0.002024, 2.69427, 14.992595]
invF(2.31,0.627, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output: [0.146649, 0.718555, 2.69427, 14.992595, 508.444221]
FILE:references/doc_516.md
# irs
**URL**: https://docs.dolphindb.cn/zh/funcs/i/irs.html
**来源**: DolphinDB 官方文档
---
irs
语法
irs(settlement, resetInterval, start, maturity, notional, fixedRate, spread, curve, frequency, calendar, [convention='ModifiedFollowing'], [basis=1], [rateType=0])
详情
本函数返回对于浮动利率支付方的利率互换估值。
利率互换是一种金融交易,交易双方同意交换未来一段时间内的利率支付流,一方支付固定利率,另一方支付浮动利率(通常是基于某个利率基准,如
SHIBOR),持续多个周期,直到合约结束。市场上的利率互换产品的互换间隔有1个月、3个月、半年、一年等。
参数
settlement
DATE 类型标量或向量,表示交易日,即利率互换估值日。
resetInterval
DURATION 标量或向量,表示利率的重置间隔。比如对于标的利率 FR007 来说,resetInterval 应设置为
7d,表示每 7 天重置一次利率。
start
DATE 类型标量或向量,表示第一次利率互换的日期。
maturity
DATE 类型标量或向量,表示最后一次利率互换的日期。
notional
数值型标量或向量,表示利率互换所基于的本金。
fixedRate
数值型标量或向量,表示利率互换中固定利率支付方所支付的利率,在整个利率互换期间该利率不变。
spread
数值型标量或向量,表示浮动利率的利差。
curve
字典类型标量或向量,表示拟合后的利率曲线。
frequency
表示利率互换的频率,支持两种输入类型:
整型标量或向量:表示一年内进行利率互换的次数;比如输入 1,表示每年互换 1 次;输入 2,表示每年互换 2 次。
DURATION 标量或向量:表示隔多久进行一次利率互换。比如输入 3M,表示每隔 3 个月互换一次。
可选值
含义
1 / 1y
表示每年付息1次
2 / 6M
表示每年付息2次 / 每6个月付息1次
3 / 4M
表示每年付息3次 / 每4个月付息1次
4 / 3M
表示每年付息4次 / 每3个月付息1次
6 / 2M
表示每年付息6次 / 每2个月付息1次
12 / 1M
表示每年付息12次 / 每月付息1次
13 / 4w
表示每年付息13次 / 每4周付息1次
26 / 2w
表示每年付息26次 / 每2周付息1次
52 / 1w
表示每年付息52次 / 每周付息1次
365 / 1d
表示每年付息365次 / 每天付息1次
calendar
字符串类型标量或向量,表示使用的市场日历类型,请参阅
交易日历
。
convention
可选参数,字符串标量或向量,表示把非工作日调整到工作日的方法,可选值为:
'Following':表示选择给定假日后的第一个工作日。
'ModifiedFollowing':表示选择给定假日后的第一个工作日,除非该工作日属于不同的月份,此时应选择假日前的第一个工作日,默认值。
'Preceding':表示选择给定假日前的第一个工作日。
'ModifiedPreceding':表示选择给定假日前的第一个工作日,除非该工作日属于不同的月份,此时应选择假日后的第一个工作日。
'Unadjusted':表示不作调整。
'HalfMonthModifiedFollowing':表示选择给定假日后的第一个工作日,除非该工作日跨越了月中(15日)或月末,此时应选择假日前的第一个工作日。
'Nearest':表示选择离给定假日最近的工作日。如果前一个和后一个工作日距离给定假日同样远,则默认选择后一个工作日。
basis
可选参数,整型或 STRING 类型的标量或向量,表示要使用的日计数基准类型。如果省略此参数,则使用默认值 1。可选值为:
Basis
日计数基准
0 / "Thirty360US"
US (NASD) 30/360
1 / "ActualActual" (默认值)
实际/实际
2 / "Actual360"
实际/360
3 / "Actual365"
实际/365
4 / "Thirty360EU"
欧洲 30/360
rateType
可选参数,整型或 STRING 类型的标量或向量,表示估值过程使用的复利类型,可选值为:
0 / "CC":表示使用连续复利,默认值。
1 / "C":表示使用普通复利。
注意:如果输入参数中,部分为标量,其余为向量时,则会将标量当作与向量长度相同,所有元素值等于该标量的向量。所有向量的长度必须一致。
返回值
DOUBLE 类型的标量或向量。
例子
本例为 2023 年 7 月 10 日交易的一笔利率互换进行估值。其本金为 100 万人民币,利率互换频率为每周一次,2023 年 1 月 10
日进行第一次互换,5年后(2028 年 1 月 10 日)到期,采用上交所的交易日历。固定利率为 2.765%,浮动利率规定在
curveRateValue
中,日计数基准为 US (NASD)
30/360,估值过程使用连续复利。
settlement = 2023.07.10
calendar = `SSE
day0 = temporalAdd(settlement, 0, calendar)
curveRateTime = [10y, 14d, 1d, 1M, 1y, 2y, 3M, 3y, 4y, 5y, 6M, 7d, 7y, 9M]
curveRateValue = [ 2.7013, 1.8, 1.27, 1.9425, 2.0263, 2.1265, 1.9725, 2.2438, 2.3575, 2.4538, 1.9938, 1.86, 2.5863, 2.0088] * 0.01
dates = []
for (dur in curveRateTime) {
dates.append!(temporalAdd(settlement, dur))
}
X = (dates - day0)$INT
// a curve for base rate (without spread)
curve = linearInterpolateFit(X, curveRateValue)
resetIntv = 7d
startDay = 2023.01.10
endDay = 2028.01.10
par = 100.0
fixRate = 0.02765
spread = 0.0
freq = 3M
basis = 0
irs(settlement, resetIntv, startDay, endDay, par, fixRate, spread, curve, freq, calendar, basis=basis)
// -1.5451083233900798
FILE:references/doc_5163.md
# bfill!
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bfill_.html
**来源**: DolphinDB 官方文档
---
bfill!
语法
bfill!(obj, [limit])
详情
如果
obj
是一个向量,使用 NULL 值后的非空元素来填充 NULL 值。
如果
obj
是一个表,对于表中的每一列,使用 NULL 值后的非空元素来填充 NULL 值。
参数
obj
可以是向量或表。
limit
是正整数,表示需要填充的 NULL 值的数量。
返回值
返回填充空缺值后的对象,其类型与形式同
obj
。
例子
x=1 2 3 NULL NULL NULL 4 5 6
x.bfill!()
x;
// output
[1,2,3,4,4,4,4,5,6]
x=1 2 3 NULL NULL NULL 4 5 6
x.bfill!(1)
x;
// output
[1,2,3,,,4,4,5,6]
date=[2012.06.12,,2012.06.13,2012.06.14,2012.06.15]
sym=["IBM","MSFT","IBM","MSFT","MSFT"]
price=[40.56,26.56,,,50.76]
qty=[2200,4500,1200,5600,]
timestamp=[09:34:07,,09:36:42,09:36:51,09:36:59]
t=table(date,timestamp,sym,price,qty)
bfill!(t)
t
date
timestamp
sym
price
qty
2012.06.12
09:34:07
IBM
40.56
2200
2012.06.13
09:36:42
MSFT
26.56
4500
2012.06.13
09:36:42
IBM
50.76
1200
2012.06.14
09:36:51
MSFT
50.76
5600
2012.06.15
09:36:59
MSFT
50.76
如果只需要填充表中的某些列,需要使用
update
语句和
bfill
函数。具体请参考
bfill
的例子。
FILE:references/doc_5170.md
# hmac
**URL**: https://docs.dolphindb.cn/zh/funcs/h/hmac.html
**来源**: DolphinDB 官方文档
---
hmac
语法
hmac(key, message, [digest='sha256'])
详情
采用 HMAC(Hash-based Message Authentication
Code,基于哈希的消息认证码)机制,根据给定的密钥和加密信息,通过指定的加密算法生成并返回一个哈希值。
参数
key
LITERAL 类型标量,表示密钥。
message
LITERAL 类型标量,表示需要加密的信息。
digest
可选参数,STRING 类型标量,表示加密使用的哈希算法。默认值为 sha256。可选值为 sha1, sha224, sha256, sha
384, sha512, md5。
返回值
一个 STRING 类型的哈希值。
例子
hmac(key="myKey", message="myMessage", digest="sha256")
// output:'71e5f5ca5f64550ee4524909f7cead7b81d8674a657383aec1b003a8a3f05b04'
hmac(key="myKey", message="myMessage", digest="sha1")
// output:'5033197fa89dedf5088eed6100dfa5a0f67ef1ce'
hmac(key="myKey2", message="myMessage", digest="sha256")
// output:'40e2a700754cec30ace1e82abfe7fd233f8f6c299050cc21b0e0a4ea42428126'
FILE:references/doc_5171.md
# temporalSeq
**URL**: https://docs.dolphindb.cn/zh/funcs/t/temporalSeq.html
**来源**: DolphinDB 官方文档
---
temporalSeq
语法
temporalSeq(start, end, rule, [closed], [label],
[origin='start_day'])
详情
根据
rule
指定的频率,对由
start
开始,
end
结尾的时间序列进行重采样,并返回新生成的时间序列。
参数
start
时间类型标量。
end
时间类型标量。必须和
start
的类型相同,且值必须大于
start
。
rule
字符串,可取以下值:
rule 参数取值
对应 DolphinDB 函数
"B"
businessDay
"W"
weekEnd
"WOM"
weekOfMonth
"LWOM"
lastWeekOfMonth
"M"
monthEnd
"MS"
monthBegin
"BM"
businessMonthEnd
"BMS"
businessMonthBegin
"SM"
semiMonthEnd
"SMS"
semiMonthBegin
"Q"
quarterEnd
"QS"
quarterBegin
"BQ"
businessQuarterEnd
"BQS"
businessQuarterBegin
"REQ"
fy5253Quarter
"A"
yearEnd
"AS"
yearBegin
"BA"
businessYearEnd
"BAS"
businessYearBegin
"RE"
fy5253
"D"
date
"H"
hourOfDay
"U"
microsecond
"L"
millisecond
"min"
minuteOfHour
"N"
nanosecond
"S"
secondOfMinute
"SA"
semiannualEnd
"SAS"
semiannualBegin
上述字符串亦可配合使用数字,例如 "2M" 表示频率为每两个月月末。此外,
rule
也可以是交易日历标识,例如:国外交易所的 ISO Code、国内交易所简称或自定义交易日历名称。
closed
字符串,表示重采样时间窗口的闭合边界。可取值为 "left", "right"。
rule
为 'M', 'A', 'Q', 'BM', 'BA', 'BQ' 和 'W' 时,
closed
的默认取值为
'right' ,否则,
closed
的默认取值为 'left'。
origin
取 'end' 或者 'end_day' 时,
closed
的默认值为
'right'。
label
字符串,表示重采样时间窗口的标签位置。可取值为 "left", "right"。
rule
为 'M', 'A', 'Q', 'BM', 'BA', 'BQ' 和 'W'
时,label 的默认取值为 'right' ,否则,
label
的默认取值为 'left'。
origin
取 'end' 或者 'end_day' 时,
label
的默认值为 'right'。
origin
字符串或与
start/end
具有相同时间类型的标量,表示重采样的基准时间点,即重采样的起始点。
origin
的取值为 'epoch', start', 'start_day', 'end', 'end_day' 或自定义的时间对象,默认值为 'start_day'。
字符串,表示重采样时间窗口的标签位置。可取值为 "left", "right"。
'epoch':分组起始点为1970-01-01。
'start':分组起始点为
start
参数指定的值。
'start_day':分组起始点是
start
参数指定值对应日期的午夜零点。
'end':分组起始点是
end
参数指定的值。
'end_day':分组起始点是
end
参数指定值对应日期的午夜24点(即下一日的零点)。
返回值
Temporal 类型向量。
例子
temporalSeq(start=2022.01.01 00:01:00,end=2022.01.01 00:08:00,rule="3min")
输出返回:
[2022.01.01T00:00:00,2022.01.01T00:03:00,2022.01.01T00:06:00]
temporalSeq(start=2022.01.01 00:01:00, end=2022.01.01 00:08:00, rule="3min", closed=`right)
输出返回:
[2022.01.01T00:00:00,2022.01.01T00:03:00,2022.01.01T00:06:00]
temporalSeq(start=2022.01.01 00:01:00, end=2022.01.01 00:08:00, rule="3min", closed=`right, origin=`end)
输出返回:
[2022.01.01T00:02:00,2022.01.01T00:05:00,2022.01.01T00:08:00]
temporalSeq(start=2022.01.01 00:01:00, end=2022.01.01 00:08:00, rule="3min", closed=`right, origin=2022.10.01 00:00:10)
输出返回:
[2022.01.01T00:00:10,2022.01.01T00:03:10,2022.01.01T00:06:10]
FILE:references/doc_518.md
# uuid
**URL**: https://docs.dolphindb.cn/zh/funcs/u/uuid.html
**来源**: DolphinDB 官方文档
---
uuid
语法
uuid(X)
详情
把字符串转换成 UUID 类型。通过 rand(uuid(), n) 可以随机生成 n 个 UUID 类型的数据。
参数
X
是一个字符串标量或向量。
返回值
UUID 类型标量或向量。
例子
uuid("");
返回:00000000-0000-0000-0000-000000000000
a=uuid("9d457e79-1bed-d6c2-3612-b0d31c1881f6");
a;
返回:9d457e79-1bed-d6c2-3612-b0d31c1881f6
typestr(a);
返回:UUID
FILE:references/doc_5208.md
# instrumentPricer
**URL**: https://docs.dolphindb.cn/zh/funcs/i/instrumentPricer.html
**来源**: DolphinDB 官方文档
---
instrumentPricer
语法
instrumentPricer(instrument, pricingDate,
marketData)
详情
对一个或多个金融合约(可为相同类型或不同类型)进行批量定价。
在 DolphinDB 中,每个金融合约可抽象为一个 INSTRUMENT 类型,定价需要用到的每一个市场数据(即期/曲线/曲面)也可抽象为一个 MKTDATA
类型。系统根据既定规则,将合约与对应的市场数据自动匹配,从而进行批量定价。
参数
instrument
INSTRUMENT 类型对象,表示需要定价的金融工具。可以是单个合约,也可以是多个合约。
pricingDate
DATE 类型标量,表示定价日,即计算合约价值所对应的日期。
marketData
MKTDATA 类型向量,或者嵌套字典,表示市场数据。
MKTDATA 类型向量:
若为曲线类市场数据,需指定 curveName 字段。
若为曲面类市场数据,需指定 surfaceName 字段。
嵌套字典的结构如下:
第一层:key 为数据类别,可选值:"Spot", "Curve", "Surface"。
第二层:key 为定价日期(DATE 类型标量)。
第三层:key 为曲线或曲面名称,value 为对应的 MKTDATA 类型标量。
返回值
若
instrument
为标量:返回 DOUBLE 类型标量,表示该合约的定价结果。
若
instrument
为向量:返回 DOUBLE 类型向量,依次表示输入合约的定价结果。
instrument 和 marketData 的匹配规则
目前支持下图分类树中叶节点所示的金融工具类型:
在定价过程中,系统会按照以下优先级确定市场数据:
若
instrument
中已显式指定市场数据,则直接使用该数据;
若未指定,则系统根据预定义规则自动匹配合适的市场数据。
以下将对不同类型金融工具的匹配规则进行说明。
债券(Bond)
债券定价需要用到折现曲线。用户可以通过 discountCurve 字段指定折现曲线名称,例如:
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "1382011.IB",
"start": "2013.01.14",
"maturity": "2028.01.14",
"issuePrice": 100.0,
"coupon": 0.058,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA",
"currency": "CNY", //可选字段
"subType": "MTN", //可选字段
"creditRating": "AAA", //可选字段
"discountCurve": "CNY_MTN_AAA" //可选字段
}
折现曲线选择规则如下:
如果 discountCurve 已指定,则优先使用 discountCurve 的值。
如果 discountCurve 未指定:
指定了 currency,subType 和 creditRating,系统会选择名为 currency + "_" +
subType + "_" + creditRating 的折现曲线。
指定了 currency,且 subType 为
TREASURY_BOND
,
CENTRAL_BANK_BILL
,
CDB_BOND
,
EIBC_BOND
,
ADBC_BOND
之一,则不需要 creditRating,系统会选择名为 currency + "_" + subType
的折现曲线。
指定了 currency,且 subType 不为
TREASURY_BOND
,
CENTRAL_BANK_BILL
,
CDB_BOND
,
EIBC_BOND
,
ADBC_BOND
之一,同时未指定 creditRating,系统会选择名为 currency + "_TREASURY_BOND"
的折现曲线。
指定了 currency,且未指定 subType 和 creditRating,系统会选择名为 currency +
"_TREASURY_BOND" 的折现曲线。
currency,subType 和 creditRating 均未指定,系统会选择名为
"CNY_TREASURY_BOND" 的折现曲线。
国债期货(BondFutures)
无需指定 discountCurve,函数会使用其标的债券(underlying)的 dicountCurve。
存款(Deposit)
存款定价仅需指定折现曲线 discountCurve:
如果 discountCurve 已指定,则使用用户指定的曲线进行定价。
如果未指定,则根据币种自动匹配折现曲线,规则如下:
currency
discountCurve
CNY
CNY_FR_007
USD
USD_SOFR
EUR
EUR_ESTR
利率互换(IrFixedFloatingSwap)
利率互换定价需要传入三条曲线:discountCurve、forwardCurve 和 assetPriceCurve。当前版本仅支持以 FR_007 和
SHIBOR_3M 作为浮动参考利率的利率互换。
如果用户在
instrument
中指定了相应曲线,则使用用户指定的曲线进行定价。
如果未指定,则根据币种和浮动利率基准自动匹配三条默认曲线,如下表所示:
currency
iborIndex
discountCurve
forwardCurve
assetPriceCurve
CNY
FR_007
CNY_FR_007
CNY_FR_007
PRICE_FR_007
CNY
SHIBOR_3M
CNY_FR_007
CNY_SHIBOR_3M
PRICE_SHIBOR_3M
其中 assetPriceCurve 填入的是浮动参考利率的历史数据,用于计算定价日起第一笔现金流的浮动利率。
外汇远期(FxForward)/ 外汇掉期(FxSwap)
这两类线性产品定价需要绑定 domesticCurve 和 foreignCurve,并基于 currencyPair 获取相应的 FxSpot。
若用户在
instrument
中指定了 domesticCurve 和
foreignCurve,则直接使用用户指定的曲线。
若未指定,则系统会根据货币对自动匹配默认曲线,如下表所示:
currencyPair
domesticCurve
foreignCurve
USDCNY
CNY_FR_007
USD_USDCNY_FX
EURCNY
CNY_FR_007
EUR_EURCNY_FX
EURUSD
USD_SOFR
EUR_EURUSD_FX
其中 foreignCurve 是根据外汇掉期交易,并结合利率平价公式推导得到的外币隐含即期曲线。
外汇欧式期权(FxEuropeanOption)
外汇期权定价除需使用 domesticCurve 与 foreignCurve 外,还依赖 FxSpot 和 FxVolatilitySurface。
这两个市场数据均可根据期权的 underlying(货币对) 自动匹配。
若用户在
instrument
中明确指定,则优先使用用户提供的 domesticCurve、foreignCurve。
若未指定,则系统会根据
currencyPair
自动匹配,规则如下:
currencyPair
fxSpot
domesticCurve
foreignCurve
volSurf
USDCNY
USDCNY
CNY_FR_007
USD_USDCNY_FX
USDCNY
EURCNY
EURCNY
CNY_FR_007
EUR_EURCNY_FX
EURCNY
EURUSD
EURUSD
USD_SOFR
EUR_EURUSD_FX
EURUSD
例子
创建外汇远期。
fxFwd1 = {
"productType": "Forward",
"forwardType": "FxForward",
"version": 0,
"expiry": 2025.10.08,
"delivery": 2025.10.10,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E6],
"strike": 7.2
}
fxFwdUsdCny = parseInstrument(fxFwd1)
fxFwd2 = {
"productType": "Forward",
"forwardType": "FxForward",
"version": 0,
"expiry": 2025.10.08,
"delivery": 2025.10.10,
"currencyPair": "EURCNY",
"direction": "Buy",
"notional": ["EUR", 1E6],
"strike": 8.2
}
fxFwdEurCny = parseInstrument(fxFwd2)
创建外汇掉期。
fxSwap1 = {
"productType": "Swap",
"swapType": "FxSwap",
"version": 0,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E6],
"nearStrike": 7.2,
"nearExpiry": 2025.12.08,
"nearDelivery": 2025.12.10,
"farStrike": 7.3,
"farExpiry": 2026.06.08,
"farDelivery": 2026.06.10
}
fxSwapUsdCny = parseInstrument(fxSwap1)
fxSwap2 = {
"productType": "Swap",
"swapType": "FxSwap",
"version": 0,
"currencyPair": "EURCNY",
"direction": "Buy",
"notional": ["EUR", 1E6],
"nearStrike": 8.2,
"nearExpiry": 2025.12.08,
"nearDelivery": 2025.12.10,
"farStrike": 8.3,
"farExpiry": 2026.06.08,
"farDelivery": 2026.06.10
}
fxSwapEurCny = parseInstrument(fxSwap2)
创建外汇欧式期权。
fxOption1 = {
"productType": "Option",
"optionType": "EuropeanOption",
"assetType": "FxEuropeanOption",
"version": 0,
"notional": ["USD", 1E6],
"strike": 7.0,
"maturity": 2025.12.08,
"payoffType": "Call",
"dayCountConvention": "Actual365",
"underlying": "USDCNY"
}
fxOptionUsdCny = parseInstrument(fxOption1)
fxOption2 = {
"productType": "Option",
"optionType": "EuropeanOption",
"assetType": "FxEuropeanOption",
"version": 0,
"notional": ["EUR", 1E6],
"strike": 8.0,
"maturity": 2025.12.08,
"payoffType": "Call",
"dayCountConvention": "Actual365",
"underlying": "EURCNY"
}
fxOptionEurCny= parseInstrument(fxOption2)
创建债券。
bond1 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "220010.IB",
"start": 2020.12.25,
"maturity": 2031.12.25,
"issuePrice": 100.0,
"coupon": 0.0149,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA",
"discountCurve": "CNY_TREASURY_BOND"
}
bond = parseInstrument(bond1)
创建国债期货。
bondFut1 = {
"productType": "Futures",
"futuresType": "BondFutures",
"version": 0,
"instrumentId": "T2509",
"nominal": 100.0,
"maturity": "2025.09.12",
"settlement": "2025.09.16",
"underlying": bond1,
"nominalCouponRate": 0.03
}
bondFut = parseInstrument(bondFut1)
创建存款。
deposit1 = {
"productType": "Cash",
"assetType": "Deposit",
"version": 0,
"start": 2025.06.15,
"maturity": 2025.12.15,
"rate": 0.02,
"dayCountConvention": "Actual360",
"notional":["CNY", 1E6],
"payReceive": "Receive"
}
deposit = parseInstrument(deposit1)
创建利率互换。
irs1 = {
"productType": "Swap",
"swapType": "IrSwap",
"irSwapType": "IrFixedFloatingSwap",
"version": 0,
"start": 2025.06.16,
"maturity": 2028.06.16,
"frequency": "Quarterly",
"fixedRate": 0.018,
"calendar": "CFET",
"fixedDayCountConvention": "Actual365",
"floatingDayCountConvention": "Actual365",
"payReceive": "Pay",
"iborIndex": "FR_007",
"spread": 0.0001,
"notional":["CNY", 1E8]
}
irs = parseInstrument(irs1)
创建市场数据。
aod = 2025.08.18
fxSpot1 = {
"mktDataType": "Spot",
"spotType": "FxSpot",
"version": 0,
"spotDate": aod+2 ,
"referenceDate": aod ,
"value": 7.1627,
"unit": "USDCNY"
}
fxSpotUsdCny = parseMktData(fxSpot1)
fxSpot2 = {
"mktDataType": "Spot",
"spotType": "FxSpot",
"version": 0,
"spotDate": aod+2 ,
"referenceDate": aod ,
"value": 8.3768,
"unit": "EURCNY"
}
fxSpotEurCny = parseMktData(fxSpot2)
curve1 = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"curveName": "CNY_FR_007",
"referenceDate": aod,
"currency": "CNY",
"dayCountConvention": "ActualActualISDA",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"dates":[2025.08.21, 2025.08.27, 2025.09.03, 2025.09.10, 2025.09.22, 2025.10.20, 2025.11.20,
2026.02.24,2026.05.20, 2026.08.20, 2027.02.22, 2027.08.20, 2028.08.21],
"values":[1.4759, 1.5331, 1.5697, 1.5239, 1.4996, 1.5144, 1.5209,
1.5539, 1.5461, 1.5316, 1.5376, 1.5435, 1.5699] / 100.0
}
curveCnyFr007 = parseMktData(curve1)
curve2 = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"curveName": "USD_USDCNY_FX",
"referenceDate": aod ,
"currency": "USD",
"dayCountConvention": "ActualActualISDA",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"dates":[2025.08.21, 2025.08.27, 2025.09.03, 2025.09.10, 2025.09.22, 2025.10.20, 2025.11.20,
2026.02.24,2026.05.20, 2026.08.20, 2027.02.22, 2027.08.20, 2028.08.21],
"values":[4.3345, 4.3801, 4.3119, 4.3065, 4.2922, 4.2196, 4.1599,
4.0443, 4.0244, 3.9698, 3.7740, 3.6289, 3.5003] / 100.0
}
curveUsdUsdCnyFx = parseMktData(curve2)
curve3 = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"curveName": "EUR_EURCNY_FX",
"referenceDate": aod,
"currency": "EUR",
"dayCountConvention": "ActualActualISDA",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"dates":[2025.08.21, 2025.08.27, 2025.09.03, 2025.09.10, 2025.09.22, 2025.10.20, 2025.11.20,
2026.02.24,2026.05.20, 2026.08.20, 2027.02.22, 2027.08.20, 2028.08.21],
"values":[1.9165, 1.9672, 1.8576, 1.8709, 1.8867, 1.8749,1.8700,
1.8576, 1.9253, 1.9738, 1.9908, 1.9850, 2.0362] / 100.0
}
curveEurEurCnyFx = parseMktData(curve3)
surf1 = {
"surfaceName": "USDCNY",
"mktDataType": "Surface",
"surfaceType": "FxVolatilitySurface",
"version": 0,
"referenceDate": "2025.08.18",
"smileMethod": "Linear",
"termDates": [
"2025.08.21",
"2026.08.20"
],
"volSmiles":[{"strikes": [6.5,7,7.5],"vols": [0.1,0.1,0.1]},{"strikes": [6.5,7,7.5],"vols": [0.1,0.1,0.1]}],
"currencyPair": "USDCNY"
}
surfUsdCny = parseMktData(surf1)
surf2 = {
"surfaceName": "EURCNY",
"mktDataType": "Surface",
"surfaceType": "FxVolatilitySurface",
"version": 0,
"referenceDate": "2025.08.18",
"smileMethod": "Linear",
"termDates": [
"2025.08.21",
"2026.08.20"
],
"volSmiles":[{"strikes": [7.5,8.0,8.5],"vols": [0.1,0.1,0.1]},{"strikes": [7.5,8.0,8.5],"vols": [0.1,0.1,0.1]}],
"currencyPair": "EURCNY"
}
surfEurCny = parseMktData(surf2)
bondCurve = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": aod,
"currency": "CNY",
"curveName": "CNY_TREASURY_BOND",
"dayCountConvention": "ActualActualISDA",
"compounding": "Compounded",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
// 0.083 0.25 0.5 1.0 2.0 3.0 5.0 7.0 10.0 15.0 20.0 30.0 40.0 50.0
"dates":[2025.09.18, 2025.11.18, 2026.02.18, 2026.08.18, 2027.08.18, 2028.08.18, 2030.08.18,
2032.08.18, 2035.08.18, 2040.08.18, 2045.08.18, 2055.08.18,2065.08.18, 2075.08.18],
"values":[1.3000, 1.3700, 1.3898, 1.3865, 1.4299, 1.4471, 1.6401,
1.7654, 1.7966, 1.9930, 2.1834, 2.1397, 2.1987, 2.2225] / 100.0
}
curveCnyTreasuryBond = parseMktData(bondCurve)
fr007HistCurve = {
"mktDataType": "Curve",
"curveType": "AssetPriceCurve",
"curveName": "PRICE_FR_007",
"version": 0,
"referenceDate": aod,
"currency": "CNY",
"dates":[2025.05.09, 2025.05.12, 2025.05.13, 2025.05.14, 2025.05.15, 2025.05.16, 2025.05.19, 2025.05.20, 2025.05.21, 2025.05.22,
2025.05.23, 2025.05.26, 2025.05.27, 2025.05.28, 2025.05.29, 2025.05.30, 2025.06.03, 2025.06.04, 2025.06.05, 2025.06.06,
2025.06.09, 2025.06.10, 2025.06.11, 2025.06.12, 2025.06.13, 2025.06.16, 2025.06.17, 2025.06.18, 2025.06.19, 2025.06.20,
2025.06.23, 2025.06.24, 2025.06.25, 2025.06.26, 2025.06.27, 2025.06.30, 2025.07.01, 2025.07.02, 2025.07.03, 2025.07.04,
2025.07.07, 2025.07.08, 2025.07.09, 2025.07.10, 2025.07.11, 2025.07.14, 2025.07.15, 2025.07.16, 2025.07.17, 2025.07.18,
2025.07.21, 2025.07.22, 2025.07.23, 2025.07.24, 2025.07.25, 2025.07.28, 2025.07.29, 2025.07.30, 2025.07.31, 2025.08.01,
2025.08.04, 2025.08.05, 2025.08.06, 2025.08.07, 2025.08.08, 2025.08.11, 2025.08.12, 2025.08.13, 2025.08.14, 2025.08.15
],
"values":[1.6000, 1.5600, 1.5300, 1.5500, 1.5500, 1.6300, 1.6500, 1.6000, 1.5900, 1.5800,
1.6300, 1.7000, 1.7000, 1.7000, 1.7500, 1.7500, 1.5900, 1.5800, 1.5700, 1.5600,
1.5500, 1.5500, 1.5600, 1.5900, 1.5900, 1.5700, 1.5500, 1.5600, 1.5679, 1.6000,
1.5700, 1.8500, 1.8300, 1.8400, 1.8500, 1.9500, 1.6036, 1.5800, 1.5200, 1.5000,
1.5000, 1.5100, 1.5100, 1.5300, 1.5200, 1.5500, 1.6000, 1.5400, 1.5400, 1.5000,
1.5000, 1.4800, 1.5000, 1.6000, 1.7500, 1.6400, 1.6200, 1.6300, 1.6000, 1.5000,
1.4800, 1.4700, 1.4800, 1.4900, 1.4600, 1.4600, 1.4600, 1.4800, 1.4800, 1.4900
]\100
}
priceCurveFr007 = parseMktData(fr007HistCurve)
将以上多个金融工具对象(外汇远期、外汇掉期、欧式期权、债券、利率互换等)组合为一个 INSTRUMENT 类型的向量,以便通过
instrumentPricer
批量定价。
instrument = [fxFwdUsdCny, fxFwdEurCny, fxSwapUsdCny, fxSwapEurCny,
fxOptionUsdCny, fxOptionEurCny, bond, bondFut, deposit, irs]
mktData= [fxSpotUsdCny, fxSpotEurCny, curveCnyFr007, curveUsdUsdCnyFx, curveEurEurCnyFx, surfUsdCny, surfEurCny, curveCnyTreasuryBond, priceCurveFr007]
pricingDate = aod
results1 = instrumentPricer(instrument, pricingDate, mktData)
print(results1)
将各类市场数据组织成一个嵌套字典,外层按数据类型(Spot、Curve、Surface)区分,内层按参考日再区分具体市场对象,然后传入
instrumentPricer
进行定价。
spots = dict(string, MKTDATA)
spots["USDCNY"] = fxSpotUsdCny
spots["EURCNY"] = fxSpotEurCny
curves = dict(string, MKTDATA)
curves["CNY_FR_007"] = curveCnyFr007
curves["USD_USDCNY_FX"] = curveUsdUsdCnyFx
curves["EUR_EURCNY_FX"] = curveEurEurCnyFx
curves["CNY_TREASURY_BOND"] = curveCnyTreasuryBond
curves["PRICE_FR_007"] = priceCurveFr007
surfs = dict(string, MKTDATA)
surfs["USDCNY"] = surfUsdCny
surfs["EURCNY"] = surfEurCny
dSpots = dict(DATE, ANY)
dSpots[aod] = spots
dCurves = dict(DATE, ANY)
dCurves[aod] = curves
dSurfs = dict(DATE, ANY)
dSurfs[aod] = surfs
mktData2 = dict(STRING, ANY)
mktData2 = {"Spot": dSpots,
"Curve": dCurves,
"Surface": dSurfs}
results2 = instrumentPricer(instrument, pricingDate, mktData2)
print(results2)
FILE:references/doc_5216.md
# Linux 系统部署准备
**URL**: https://docs.dolphindb.cn/zh/tutorials/prep_linux_for_deploy.html
**来源**: DolphinDB 官方文档
---
Linux 系统部署准备
本文主要介绍在新服务器部署 DolphinDB 时需要使用哪些系统配置,以及如何选择 DolphinDB 部署方式以符合业务需求。合适的系统配置可以提高 DolphinDB 系统的稳定性和可维护性,而合适的部署方式可以提高业务执行的效率。如果已有 Linux 服务器,则可以跳过本教程。
操作系统配置
在 Linux 系统使用 DolphinDB 要求内核版本为 Linux 2.6.19 或以上。对于 DolphinDB 2.00.16/3.00.3 以下版本,推荐使用
CentOS 7 稳定版
;对于 2.00.16/3.00.3 或以上版本,推荐使用
Rocky Linux 9 稳定版
。
本文以 CentOS 7.9.2009 为例,介绍 DolphinDB 相关的系统配置方法。
平台要求与推荐
支持的平台
平台
处理器架构
是否支持
Linux
x86
是
arm
是
龙芯
是
注意:应确保 x86 架构 CPU 支持 avx 指令集。
可通过 lscpu | grep avx 查看当前环境的 CPU 是否支持该指令集。返回输出中如果包含 avx 指令集,则说明当前环境 CPU 支持 avx 指令集。
若使用 Ubuntu 系统,注意以下几点:
需要在系统安装时在 Storage configuration 中选择 /home 目录的格式为 xfs,以方便后续将 /home 目录格式化为 xfs 文件系统;
Ubuntu 系统使用 ufw 防火墙,关闭防火墙命令为
sudo ufw disable
,其他命令请参考
man ufw
;
Ubuntu 系统使用 apport 处理 core dump,若需要自定义 core dump,需要禁用 apport,命令为
sudo systemctl disable apport.service
依赖软件
DolphinDB 依赖 gcc 4.8.5 或以上版本。以在 CentOS 7 稳定版上安装为例:
# yum install -y gcc
推荐硬件配置
需要为 DolphinDB 元数据,redo log 以及数据实体配置不同的硬盘,以优化系统性能。
元数据和 redo log
:建议配一块小容量 SSD;若对可靠性要求较高,建议配置两块 SSD 做 RAID1;
数据实体
:如果无需节约成本,优先考虑多块 SSD 以获得较好的读写性能;如果需要节约成本,优先考虑配置多块机械硬盘以实现并行读写,提高读写吞吐量。
注意
:
硬盘容量取决于实际业务。
数据实体存在1块 SSD 或多块 HDD 的读写性能差距取决于实际情况。
文件系统与 inode 数量
文件系统说明
推荐
:在 Linux 下推荐使用 xfs 文件系统类型,因为 xfs 文件系统不仅支持硬链接,还支持动态调整
inode
数量。在 DolphinDB 运行期间,若可用的 inode 不足,将导致 DolphinDB 无法写入数据,可以通过动态增加 inode 数量解决此类问题。
不推荐
:不支持硬链接的文件系统类型,例如 beegfs。其相较于支持硬链接的系统,其数据更新的性能较差。
root 用户(或有 root 权限的用户,下文命令前面添加 sudo)通过 SSH 连接到全新安装的 CentOS 服务器。首先使用
df -T
命令查看文件系统类型:
# df -T
文件系统 类型 1K-块 已用 可用 已用% 挂载点
devtmpfs devtmpfs 3992420 0 3992420 0% /dev
tmpfs tmpfs 4004356 0 4004356 0% /dev/shm
tmpfs tmpfs 4004356 8748 3995608 1% /run
tmpfs tmpfs 4004356 0 4004356 0% /sys/fs/cgroup
/dev/mapper/centos-root xfs 52403200 1598912 50804288 4% /
/dev/sda1 xfs 1038336 153388 884948 15% /boot
tmpfs tmpfs 800872 0 800872 0% /run/user/0
/dev/mapper/centos-home xfs 42970624 33004 42937620 1% /home
/home 目录对应的文件系统类型为 xfs,因此可以将 DolphinDB 数据文件目录配置在该目录下。
注意
:只强烈推荐数据文件目录的文件系统为 xfs,DolphinDB 安装目录、元数据目录、日志目录的文件系统可以为 ext4 等其他文件系统。
若 /home 目录文件系统类型为 ext4 等不支持动态调整 inode 数量的类型,需要将其格式化为 xfs 类型。格式化步骤如下:
备份 /home 数据
# cd /
# cp -R /home /tmp
卸载 /home 并删除对应逻辑卷
# umount /home
# lvremove /dev/mapper/centos-home
Do you really want to remove active logical volume centos/home? [y/n]: y
Logical volume "home" successfully removed
查看硬盘剩余可用空间
# vgdisplay | grep Free
Free PE / Size 10527 / 41.12 GiB # 剩余可用空间为 41.12 GB
新建 /home 逻辑卷并格式化为 xfs
# lvcreate -L 41G -n home centos # 根据剩余可用空间填写创建大小
WARNING: xfs signature detected on /dev/centos/home at offset 0. Wipe it? [y/n]: y
Wiping xfs signature on /dev/centos/home.
Logical volume "home" created.
# mkfs.xfs /dev/mapper/centos-home
挂载 /home 并恢复数据
# mount /dev/mapper/centos-home /home
# mv /tmp/home/* /home/
# chown owner /home/owner # 重新赋予 home 目录文件的权限给对应 owner,需要根据用户名自行修改
xfs 文件系统动态调整 inode 数量
若使用 DolphinDB 时出现磁盘空间足够,但因没有可用 inode 导致无法写入文件,可通过增加 inode 数量解决问题,步骤如下:
查看 inode 信息:
# xfs_info /dev/mapper/centos-home | grep imaxpct
data = bsize=4096 blocks=10747904, imaxpct=25 # 即 /dev/mapper/centos-home 的 25% 的空间用于存放 inode
# df -i | grep /dev/mapper/centos-home
文件系统 Inode 已用(I) 可用(I) 已用(I)% 挂载点
/dev/mapper/centos-home 21495808 7 21495801 1% /home
可见配置了 /dev/mapper/centos-home 卷下的 25 % 的空间用于存放 inode,当前可用 inode 数为 21495801 个。
增加 inode 数量:
# xfs_growfs -m 30 /dev/mapper/centos-home
meta-data=/dev/mapper/centos-home isize=512 agcount=4, agsize=2686976 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0 spinodes=0
data = bsize=4096 blocks=10747904, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal bsize=4096 blocks=5248, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
inode max percent changed from 25 to 30
再次查看 inode 信息
# df -i | grep /dev/mapper/centos-home
/dev/mapper/centos-home 25794944 7 25794937 1% /home
可见当前可用 inode 数增加到了 25794937 个。
ext 文件系统设定合适的 inode 数量
如果必须使用 ext4 等不支持动态调整 inode 数量的文件系统类型,则需要在格式化硬盘时预估文件使用情况和增长速度以设定合适的 inode 数量。例如通过
mkfs.ext4
命令的
-N
选项指定 inode 数量。尤其当硬盘空间特别大时,ext4 文件系统默认的 inode 数量往往相对较少,建议设置较大的值。
挂载新硬盘
硬盘 IO 性能提升对于大数据处理非常重要,推荐硬件配置见
推荐硬件配置
。
物理安装新硬盘或通过云服务商增加新硬盘后,通过 SSH 连接到 CentOS 服务器。本节通过虚拟机添加容量为 50G 的新硬盘,步骤如下:
使用
fdisk -l
查看硬盘信息:
# fdisk -l
...
磁盘 /dev/sdb:53.7 GB, 53687091200 字节,104857600 个扇区
Units = 扇区 of 1 * 512 = 512 bytes
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
...
可见 /dev/sdb 为新加的 50G 硬盘。
使用
mkfs.xfs
命令格式化新硬盘为 xfs 文件系统类型:
# mkfs.xfs /dev/sdb
meta-data=/dev/sdb isize=512 agcount=4, agsize=3276800 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=13107200, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=6400, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
创建挂载点并挂载
# mkdir -p /mnt/dev1
# mount /dev/sdb /mnt/dev1
查看新硬盘挂载情况
# df -Th
文件系统 类型 容量 已用 可用 已用% 挂载点
devtmpfs devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs tmpfs 3.9G 8.6M 3.9G 1% /run
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/mapper/centos-root xfs 50G 1.6G 49G 4% /
/dev/sda1 xfs 1014M 150M 865M 15% /boot
/dev/mapper/centos-home xfs 41G 33M 41G 1% /home
tmpfs tmpfs 783M 0 783M 0% /run/user/0
/dev/sdb xfs 50G 33M 50G 1% /mnt/dev1
设置开机自动挂载
# blkid /dev/sdb
/dev/sdb: UUID="29ecb452-6454-4288-bda9-23cebcf9c755" TYPE="xfs"
# vi /etc/fstab
UUID=29ecb452-6454-4288-bda9-23cebcf9c755 /mnt/dev1 xfs defaults 0 0
注意
:这里使用了 UUID 来标识新硬盘,避免了磁盘更换位置导致识别出错。
开启 core dump
core dump
指当程序出错而异常中断时,操作系统会把程序工作的当前状态存储成一个 core 文件。core 文件可以帮助技术支持人员定位问题。因此,在空间足够的情况下,建议开启 core dump。开启步骤如下:
创建存放 core 文件的路径
# mkdir /var/crash # 可自行修改存放目录
注意
:
为目录预留足以存放若干 core 文件的空间,其中core文件最大约为 maxMemSize 配置项的值;
确保 DolphinDB 在该目录具备写权限。
设置开启 core dump
# vi /etc/security/limits.conf
* soft core unlimited
* hard core unlimited
* 指为所有用户开启,也可以指定用户名只为 DolphinDB 用户开启;soft 软限制指用户可配置的最大值,hard 硬限制指软限制的最大值;unlimited 指 core 文件大小无限制。
设置 core 文件输出路径与格式
# vi /etc/sysctl.conf
kernel.core_pattern = /var/crash/core-%e-%s-%u-%g-%p-%t
格式说明:
%e – 程序执行文件名
%s – 生成 core 文件时收到的信号
%u – 进程用户 ID
%p – 进程号
%g – 进程用户组 ID
%t – 生成 core 文件的时间戳
%h – 主机名
重启后查看是否生效
# ulimit -c
unlimited
# ulimit -Hc
unlimited
配置完毕后,建议启动 dolphindb 单节点验证 core dump 配置是否生效,步骤如下:
$ cd /path_to_dolphindb
$ chmod +x ./startSingle.sh
$ ./startSingle.sh
$ kill -11 dolphindb_pid
$ ls /var/crash/ | grep dolphindb_pid # 检查目录下是否有对应core文件
安装 gdb 用于查看 core dump 内容
# yum install gdb
增大文件最大打开数量
DolphinDB 运行时同时打开的文件数量可能会大于 CentOS 7 的文件最大打开数量默认值 1024 个,建议配置文件最大打开数量为 102400 个。配置步骤如下:
查看文件最大打开数量
# ulimit -n # 用户级软限制
1024
# ulimit -Hn # 用户级硬限制
1024
# cat /proc/sys/fs/file-max # 系统级
763964
可见用户级文件最大打开数量为 1024 个,系统级为 763964 个。DolphinDB 为用户级,修改用户级文件最大打开数量为 102400 个即可。
修改用户级文件最大打开数量
# vi /etc/security/limits.conf
* soft nofile 102400
* hard nofile 102400
* 指对所有用户生效,也可以配置为指定用户名只对 DolphinDB 用户生效;soft 软限制指用户可配置的最大值,hard 硬限制指软限制的最大值。
若系统级最大打开文件数量的配置值小于 102400 个,需要修改为不小于 102400 的值:
# vi /etc/sysctl.conf
fs.file-max = 102400
本文例子中系统级文件最大打开数量为 763964 个,大于 102400个,故不做修改。
重启后查看配置是否生效
# ulimit -n # 用户级
102400
# cat /proc/sys/fs/file-max # 系统级
763964
NTPD
若部署多机集群模式,需要配置 NTPD(Network Time Protocol Daemon)进行时间同步,以确保事务发生的先后顺序正确。本文使用两台虚拟机分别配置为 NTPD 服务端和客户端,配置如下:
虚拟机名称
IP
子网掩码
NTPD 配置
虚拟机1
192.168.0.30
255.255.254.0
服务端,与 cn.pool.ntp.org 时间同步
虚拟机2
192.168.0.31
255.255.254.0
客户端,与 192.168.0.30 时间同步
配置步骤如下:
分别在两台虚拟机上安装 ntpd
# yum install ntp
在虚拟机1上配置与
cn.pool.ntp.org
时间同步
# vi /etc/ntp.conf
...
# Hosts on local network are less restricted.
restrict 192.168.0.0 mask 255.255.254.0 nomodify notrap
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 0.cn.pool.ntp.org iburst
server 1.cn.pool.ntp.org iburst
server 2.cn.pool.ntp.org iburst
server 3.cn.pool.ntp.org iburst
...
其中第 4 行配置 IP 网段在 192.168.0.0 且子网掩码为 255.255.254.0 的本地网络请求本机的 NTP 服务,nomodify 指客户端不能修改服务端的参数配置,notrap 指不提供 trap 远程登录。
如果需要配置本地机器时间为时间源,配置如下:
# vi /etc/ntp.conf
...
# Hosts on local network are less restricted.
restrict 192.168.0.0 mask 255.255.254.0 nomodify notrap
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 127.127.1.0 iburst prefer
fudge 127.127.1.0 stratum 10
...
在虚拟机1上配置防火墙,添加 ntp 服务
# firewall-cmd --add-service=ntp --permanent
# firewall-cmd --reload
在虚拟机2上配置与虚拟机1时间同步
# vi /etc/ntp.conf
...
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 192.168.0.30 iburst
# server 0.centos.pool.ntp.org iburst
# server 1.centos.pool.ntp.org iburst
# server 2.centos.pool.ntp.org iburst
# server 3.centos.pool.ntp.org iburst
...
分别在两台虚拟机上启动 ntpd
# systemctl enable ntpd
# systemctl restart ntpd
等待若干秒后,查看 ntpd 运行状况
虚拟机1:
# ntpstat
synchronised to NTP server (202.112.31.197) at stratum 2
time correct to within 41 ms
polling server every 64 s
虚拟机2:
# ntpstat
synchronised to NTP server (192.168.0.30) at stratum 3
time correct to within 243 ms
polling server every 64 s
防火墙配置
运行 DolphinDB 前,需要配置防火墙开放 DolphinDB 的各个节点的端口,或者关闭防火墙。
具体开放哪些端口取决于集群配置,以开放 8900 ~ 8903 TCP 端口为例:
# firewall-cmd --add-port=8900-8903/tcp --permanent
# firewall-cmd --reload
# systemctl restart firewalld
若不需要防火墙,可通过如下命令关闭:
# systemctl stop firewalld
# systemctl disable firewalld.service
Swap
Swap 即交换分区,在物理内存不够用时,操作系统会从物理内存中把部分暂时不被使用的数据转移到交换分区,从而为当前运行的程序留出足够的物理内存空间,保证程序的正常运行,但会造成系统性能下降。如果系统物理内存充足,且用户比较重视性能,建议关闭 Swap,步骤如下:
检查 Swap 是否已关闭
# free -h
total used free shared buff/cache available
Mem: 7.6G 378M 7.1G 8.5M 136M 7.1G
Swap: 7.9G 0B 7.9G
可见 Swap 的 total 值为 7.9G,未关闭。
临时关闭 Swap
# swapoff -a
再次检查 Swap 是否已关闭
# free -h
total used free shared buff/cache available
Mem: 7.6G 378M 7.1G 8.5M 136M 7.1G
Swap: 0B 0B 0B
可见 Swap 的 total 值为 0B,已关闭。
永久关闭 Swap,注释掉第 2 列值为 swap 的行
# vi /etc/fstab
...
# /dev/mapper/centos-swap swap swap defaults 0 0
...
部署 DolphinDB
系统配置好后,即可根据业务需求选择合适的部署方式部署 DolphinDB。
单节点、单机集群、多机集群的选择
本节介绍不同部署方式之间的比较重要的差异,不同部署方式的功能和应用场景的完整列表见
《DolphinDB 安装使用指南》
。
相同单机资源,部署单节点和单机集群的差异
单节点指在单机上部署一个 DolphinDB 单机节点,单机集群指在单机上部署多个 DolphinDB 分布式节点。
单机集群通常适合密集型计算场景,将计算任务分发到不同的节点(进程)上,可以有效的隔离内存资源竞争,提高计算效率。
集群与单节点的另外两个差异,一是集群支持横向扩展,即支持在线加入新的数据节点,提高整个集群的最大负载;二是集群支持高可用,容错率更高。
综上,单机部署时,建议部署集群模式。
相同节点的情况下,部署单机集群和多机集群的差异
多机集群部署指将 DolphinDB 分布式节点分别部署到多台机器上。
多机可以充分利用各个节点(机器)的计算资源和存储资源。但是节点间通信引入了网络开销,故建议部署在内网并配置万兆网络以降低网络开销。
另外,假设每台机器故障概率相同,多机比单机更容易出现故障,但由于节点分布在多机上,通过开启高可用支持,多机集群容错率更高。
单机多硬盘与多机部署的差异
对于大吞吐量、低计算的任务来说,单机多硬盘集群模式因网络开销小而具有更好的性能。对于小吞吐量、重计算的场景,多机集群的分布式计算优势更明显。
元数据和redo log的存储,相关配置项包括:
chunkMetaDir
: 元数据目录
dfsMetaDir
: 该目录保存控制器节点上的分布式文件系统的元数据
redoLogDir
: OLAP 存储引擎重做日志(redo log)的目录
TSDBRedoLogDir
: TSDB 存储引擎重做日志(redo log)的目录
这些配置项建议指定到 SSD 以提高读写性能。
数据实体的存储,相关配置项包括:
volumes
: 数据文件目录。多个目录用 ',' 隔开,例如: /hdd/hdd1/volumes,/hdd/hdd2/volumes,/hdd/hdd3/volumes
diskIOConcurrencyLevel
: 读写磁盘数据的线程数,默认为1,若 volumes 全部配置为 HDD 硬盘,建议 diskIOConcurrencyLevel 设置为同 HDD 硬盘个数相同的值
Docker 和非 Docker 环境运行的选择
Docker 只是轻量化的资源隔离,DolphinDB 部署在 Docker 环境和非 Docker 环境下的运行性能差异不明显,可根据业务需求选择合适的运行环境。
生产环境配置参数实践
以搭建元数据和流数据高可用集群为例介绍如何配置集群各节点。设集群机器硬件配置相同,集群机器信息如下:
名称
IP
备注
centos-1
175.178.100.3
1控制节点,1代理节点,1数据节点
centos-2
119.91.229.229
1控制节点,1代理节点,1数据节点
centos-3
175.178.100.213
1控制节点,1代理节点,1数据节点
3 台机器上 cluster.nodes 与 cluster.cfg 配置文件内容均相同,而 controller.cfg 和 agent.cfg 需要根据机器 IP 和端口号做相应配置。注意下面只列出部分重要配置。
cluster.nodes
cluster.cfg
diskIOConcurrencyLevel=0
node1.volumes=/ssd1/dolphindb/volumes/node1,/ssd2/dolphindb/volumes/node1
node1.redoLogDir=/ssd1/dolphindb/redoLog/node1
node1.chunkMetaDir=/ssd1/dolphindb/metaDir/chunkMeta/node1
node1.TSDBRedoLogDir=/ssd1/dolphindb/tsdb/node1/redoLog
chunkCacheEngineMemSize=2
TSDBCacheEngineSize=2
...
controller.cfg
localSite=175.178.100.3:8990:controller1
dfsMetaDir=/ssd1/dolphindb/metaDir/dfsMeta/controller1
dfsMetaDir=/ssd1/dolphindb/metaDir/dfsMeta/controller1
dataSync=1
...
agent.cfg
localSite=175.178.100.3:8960:agent1
sites=175.178.100.3:8960:agent1:agent,175.178.100.3:8990:controller1:controller,119.91.229.229:8990:controller2:controller,175.178.100.213:8990:controller3:controller
...
关于如何配置部分重要配置参数,见下表:
文件
配置参数
说明
cluster.cfg
node1.volumes=/ssd1/dolphindb/volumes/node1,/ssd2/dolphindb/volumes/node1
配置多个 SSD 硬盘达到并发读写,以提高读写性能。
cluster.cfg
diskIOConcurrencyLevel=0
合理设置该参数,可以优化读写性能。建议配置如下:若 volumes 配置了 SSD 硬盘,建议设置 diskIOConcurrencyLevel = 0;若 volumes 全部配置为 HDD 硬盘,建议 diskIOConcurrencyLevel 设置为同 HDD 硬盘个数相同的值。
cluster.cfg
chunkCacheEngineMemSize=2
TSDBCacheEngineSize=2
DolphinDB 目前要求 cache engine 和 redo log 必须搭配使用。若在 cluster.cfg 配置了chunkCacheEngineMemSize 和 TSDBCacheEngineSize(即启动 cache engine)则必须在 controller.cfg 里配置 dataSync=1。
controller.cfg
dataSync=1
部署流程
DolphinDB为各种部署方式提供了详细的教程,在决定部署方式和配置后,根据教程部署即可,本文涉及的部署方式教程链接如下:
单节点部署
单节点部署(嵌入式ARM版本)
单服务器集群部署
多服务器集群部署
高可用集群部署教程
如何扩展集群节点和存储
基于 Docker单机部署方案
基于Docker-Compose的DolphinDB多容器集群部署
注意
:在 windows 系统下部署时,部署路径不能包含中文。
启动流程
以启动前文配置的高可用集群为例,将配置文件相应放在 centos-1、centos-2、centos-3 机器的 DolphinDB 安装目录
/clusterDemo/config
目录下。
注意
:启动脚本使用了相对路径,故需要到脚本所在目录执行。
启动控制节点
分别在 centos-1、centos-2、centos-3 机器上执行如下命令:
$ cd DolphinDB/clusterDemo/
$ ./startController.sh
启动代理节点
分别在 centos-1、centos-2、centos-3 机器上执行如下命令:
$ cd DolphinDB/clusterDemo/
$ ./startAgent.sh
启动数据节点
进入任意一个控制节点的 Web 集群管理界面,如 [http://175.178.100.3:8990](http://175.178.100.3:8990),会自动跳转到 leader 节点的集群管理界面。在节点列表选中所有数据节点,点击启动按钮启动即可。Web 集群管理界面具体介绍见
DolphinDB Web 集群管理界面
。
附件
cluster.nodes
cluster.cfg
controller.cfg
agent.cfg
FILE:references/doc_5225.md
# any
**URL**: https://docs.dolphindb.cn/zh/funcs/a/any.html
**来源**: DolphinDB 官方文档
---
any
语法
any(X)
详情
如果
X
中有至少一个元素为 true 或非0,则返回 1;否则返回 0。NULL 值不参与计算。
参数
X
可以是标量、数据对、向量或矩阵。
返回值
一个布尔值。
例子
any(1 0 2)
// output
1
any(0 0 0)
// output
0
any(0 0 NULL)
// output
0
any(true false)
// output
1
any(false false)
// output
0
any(0..9$2:5)
// output
1
相关函数:
all
FILE:references/doc_5227.md
# byRow
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/byRow.html
**来源**: DolphinDB 官方文档
---
byRow
语法
byRow(func, X
, [Y]
)
或
func:H(X)
或
func:H(X, [Y])
详情
func
为单目函数时,
对矩阵
X
的每一行应用指定函数。
func
为双目函数时,对
X
和
Y
的每行执行 func(Xi, Yi) 。
计算规则
如果
X/Y
是矩阵、表或元组:byRow 首先将对象转置,然后对转置后的对象的每一列应用指定函数。
当
func
是向量函数时,byRow 会把
func
的计算结果转置后输出。
当
func
是聚合函数时,输出结果是一个向量,无需进行转置操作。特别地,当
func
是以下聚合函数时,byRow 进行了优化,不会对
X
/
Y
进行上步的转置操作,从而提高了计算性能:sum,
sum2, avg, min, max, count, imax, imin, imaxLast, iminLast, prod,
std, stdp, var, varp, skew, kurtosis, any, all, corr, covar, wavg,
wsum, beta, euclidean, dot, tanimoto。
如果 X/Y 是数组向量或列式元组,byRow 对 X/Y的每一行数据应用指定函数。
参数
func
是一个函数。该函数可以是向量函数(输入与输出均为等长向量),亦可为聚合函数。
X
是一个矩阵
、表、元组、数组向量、列式元组
。
Y
可以是矩阵、表、元组、数组向量或列式元组。
其他相关的 row 系列函数的参数说明和窗口计算规则请参考:
行计算系列(row 系列)
返回值
当
func
是聚合函数时,输出结果是一个向量。向量的长度与
X/Y
的行数相同。
当
func
是向量函数时,输出结果的形式、维度和
X/Y
的形式、维度相同。
注:
通过 byRow 函数,可以实现与内置 row
系列函数相同的功能,并且计算结果和性能与 row 系列函数相同。例如 byRow(sum, X) 等效于 rowSum(X)。因此 byRow
函数可以应用于所有需要进行行计算的场景中。
例子
入参是矩阵:
m=matrix([1 3 4 2,1 2 2 1])
max:H(m)
[1,3,4,2]
cummax:H(m)
col1 col2
1 1
3 3
4 4
2 2
n=matrix([11 5 9 2,8 5 3 2])
corr:H(m,n)
[,,1,]
入参是表:
qty1 = 2200 1900 2100 3200 6800 5400 1300 2500 8800
qty2 = 2100 1800 6800 5400 1300 2400 8500 4100 3200
t = table(qty1, qty2);
max:H(t)
[2200,1900,6800,5400,6800,5400,8500,4100,8800]
cummax:H(t)
qty1 qty2
2,200 2,200
1,900 1,900
2,100 6,800
3,200 5,400
6,800 6,800
5,400 5,400
1,300 8,500
2,500 4,100
8,800 8,800
qty3 = 7800 5400 5300 2500 1800 2200 3900 3100 1200
qty4 = 3200 2800 6400 8300 2300 3800 2900 1600 2900
t1 = table(qty3, qty4);
corr:H(t,t1)
[1,1,1,1,-1,-1,-1,-1,-1]
入参是元组:
tp=[1 3 4 2,1 2 2 1]
sum:H(tp)
[2,5,6,3]
cummax:H(tp)
([1,3,4,2],[1,3,4,2])
tp1=[11 23 14 21,10 12 32 21]
corr:H(tp,tp1)
[,1,-1,]
入参是数组向量:
a=array(INT[], 0, 10).append!([1 2 3, 4 5 4, 6 7 8, 1 9 10]);
sum:H(a)
[6,13,21,20]
cummax:H(a)
[[1,2,3],[4,5,5],[6,7,8],[1,9,10]]
b=array(DOUBLE[], 0, 10).append!([11.8 21.2 23.9, 83.3 90.2 78.2, 86.5 52 36.5, 10.1 12.4 16.8])
corr:H(a,b)
[0.95,0.90,-0.97,0.82]
入参是列式元组:
ctp=[1 3 4 2,1 2 2 1]
ctp.setColumnarTuple!()
sum:H(ctp)
[10,6]
cummax:H(ctp)
([1,3,4,4],[1,2,2,2])
ctp1=[11 23 14 21,10 12 32 21]
ctp1.setColumnarTuple!()
corr:H(ctp,ctp1)
[0.25, 0.37]
m=matrix(1 1, 2 3, 2 1);
m;
col1
col2
col3
1
2
2
1
3
1
byRow(add{10 20 30},m);
col1
col2
col3
11
22
32
11
23
31
byRow(mode,m);
// output
[2,1]
b=array(DOUBLE[], 0, 10).append!([11.8 21.2 23.9, 83.3 90.2 78.2 86.5, 10.1 12.4 16.8])
byRow(add{100},b)
// output
[111.8 121.2 123.9,183.3 190.2 178.2 86.5,110.1 112.4 116.8]
byRow(imax,b)
// output
[2,1,2]
FILE:references/doc_5230.md
# cosh
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cosh.html
**来源**: DolphinDB 官方文档
---
cosh
语法
cosh(X)
详情
返回
X
的双曲余弦。
参数
X
可以是标量、向量或矩阵。
返回值
DOUBLE 类型标量、向量或矩阵。
例子
cosh 0 1 2;
// output
[1,1.543081,3.762196]
相关函数:
asin
,
acos
,
atan
,
sin
,
cos
,
tan
,
asinh
,
acosh
,
atanh
,
sinh
,
tanh
FILE:references/doc_5241.md
# getTSDBDataStat
**URL**: https://docs.dolphindb.cn/zh/funcs/g/gettsdbdatastat.html
**来源**: DolphinDB 官方文档
---
getTSDBDataStat
语法
getTSDBDataStat([dbName="*"],[tableName="*"],[chunkId])
详情
获取当前节点上 TSDB 引擎存储的表的所有或指定 chunk 下的 Level File 和 sortKeyEntry 的数量。
结合 pnodeRun 函数,可以查看一个集群内(某个)表的 Level File 和 sortKeyEntry 的数量。
参数
dbName
字符串,表示数据库的名称。可以包含通配符(“*“, “%”和”?”)。
tableName
字符串,表示数据表名。可以包含通配符(“*“, “%”和”?”)。
通配符 ”*” 表示匹配所有,”?”表示单个字符,”%”表示0,1或多个字符。
chunkId
字符串标量或向量,表示 chunk 的 ID。若指定该参数,则
dbName
和
tableName
必须为空或者 *。
返回值
返回一个表,包含以下列:
levelFileCount
: 每个分区内表的 Level File 的数量。
sortKeyEntryCount
:每个分区内所有 Level File 文件里未去重的 sortKeyEntry 数量。
例子
t = table(1 2 1 1 2 2 3 as month, `Rome`Paris`London`Paris`Rome`London`Rome as city, 200 500 100 300 300 400 400 as sold)
db_name = "dfs://window_function"
if (existsDatabase(db_name)) {
dropDatabase(db_name)
}
db = database(db_name, HASH, [INT, 4], , 'TSDB')
pt = db.createPartitionedTable(t, "pt", "month", ,"sold")
pt.append!(t)
pt1 = db.createPartitionedTable(t, "pt1", "month", ,"sold")
pt1.append!(t)
flushTSDBCache()
获取以
dfs://window
开头的数据库下所有表的 Level File 和 sortKeyEntry 的数量
getTSDBDataStat("dfs://window%")
dbName
chunkId
tableName
levelFileCount
sortKeyEntryCount
dfs://window_function
d334ffab-741a-dcbd-174e-42b412058877
pt1
1
1
dfs://window_function
c3de728c-4efb-7e8e-024c-cfafd46c506c
pt1
1
3
dfs://window_function
572b1660-790e-e3a0-3944-9b81e50f4eb4
pt1
1
3
dfs://window_function
e9ea31f6-4e12-2881-b04a-c540dc3947c8
pt
1
1
dfs://window_function
673a7c12-c0d4-72bf-6a42-9c374589e2d6
pt
1
3
dfs://window_function
57ceedc9-4aaf-2aad-aa43-37924da3d32e
pt
1
3
获取以
dfs://window
开头的数据库下表 pt 的 Level File 和 sortKeyEntry
的数量
getTSDBDataStat("dfs://window%","pt")
dbName
chunkId
tableName
levelFileCount
sortKeyEntryCount
dfs://window_function
e9ea31f6-4e12-2881-b04a-c540dc3947c8
pt
1
1
dfs://window_function
673a7c12-c0d4-72bf-6a42-9c374589e2d6
pt
1
3
dfs://window_function
57ceedc9-4aaf-2aad-aa43-37924da3d32e
pt
1
3
获取指定 chunkId 的分区下的 Level File 和 sortKeyEntry 的数量。
getTSDBDataStat(chunkId=["e9ea31f6-4e12-2881-b04a-c540dc3947c8", "673a7c12-c0d4-72bf-6a42-9c374589e2d6"])
dbName
chunkId
tableName
levelFileCount
sortKeyEntryCount
dfs://window_function
673a7c12-c0d4-72bf-6a42-9c374589e2d6
pt
1
3
dfs://window_function
57ceedc9-4aaf-2aad-aa43-37924da3d32e
pt
1
3
FILE:references/doc_5243.md
# mmax
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mmax.html
**来源**: DolphinDB 官方文档
---
mmax
语法
mmax(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
元素的最大值。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
X = 2 1 3 7 6 5 4
Y = 2 1 3 NULL 6 5 4
mmax(X, 3);
// output
[,,3,7,7,7,6]
mmax(Y, 3);
// output
[,,3,3,6,6,6]
mmax(Y, 3, minPeriods=1);
// output
[2,2,3,3,6,6,6]
m = matrix(1 5 9 0 2, 9 10 2 NULL 2)
m.rename!(date(2020.09.08)+1..5, `A`B)
m.setIndexedMatrix!()
m.mmax(3d)
label
col1
col2
2020.09.09
1
9
2020.09.10
5
10
2020.09.11
9
10
2020.09.12
9
10
2020.09.13
9
2
m.mmax(1w)
label
col1
col2
2020.09.09
1
9
2020.09.10
5
10
2020.09.11
9
10
2020.09.12
9
10
2020.09.13
9
10
相关函数:
max
FILE:references/doc_5260.md
# createSnapshotJoinEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createsnapshotjoinengine.html
**来源**: DolphinDB 官方文档
---
createSnapshotJoinEngine
语法
createSnapshotJoinEngine(name, leftTable, rightTable, outputTable, metrics,
matchingColumn, [timeColumn], [outputElapsedMicroseconds=false],
[keepLeftDuplicates=false], [keepRightDuplicates=false], [isInnerJoin=true]
, [snapshotDir],
[snapshotIntervalInMsgCount]
)
详情
创建流数据表的快照连接引擎。该引擎以
matchingColumn
作为连接列,将两个流数据表进行实时的内连接(等值连接)或外连接(左/右连接)。
注:
不支持乱序处理机制,用户需要自行保证输入的数据有序。
参数
name
:字符串标量,表示 Snapshot join
引擎的名称,作为其在一个数据节点/计算节点上的唯一标识。可包含字母,数字和下划线,但必须以字母开头。
leftTable
:表对象,表示左表,其结构必须与输入的流数据表相同。
rightTable
:表对象,表示右表,其结构必须与输入的流数据表相同。
outputTable
:计算结果的输出表。在使用
createSnapshotJoinEngine
函数之前,需要将输出表预先设立为一个空表,并指定各列列名以及数据类型。
输出表的各列的顺序如下:
连接列。与
matchingColumn
中的列以及其顺序一致,可为多列。
时间列(两列)。如果指定了
timeColumn
,则分别为左表和右表的时间列,类型与
timeColumn
列一致;如果未指定
timeColumn
,则两列分别是 leftTable 和 rightTable 的数据到达时间,类型为
TIMESTAMP。
计算结果列。可为多列。
耗时列。如果指定
outputElapsedMicroseconds
= true,则指定一个 LONG
类型的列用于记录单次响应计算耗时(单位:微秒)。
batchSize 列。如果指定
outputElapsedMicroseconds
= true,
则指定一个INT类型的列,记录单次响应的数据条数。
metrics
:以元代码的格式表示计算指标,支持输入元组。有关元代码的更多信息可参考
Metaprogramming
。
计算指标可以是一个或多个表达式、系统内置或用户自定义函数,但不能是聚合函数。
metrics
内支持调用具有多个返回值的函数,且必须指定列名,例如 <func(price) as
`col1`col2>。
若在
metrics
指定了
leftTable
和
rightTable
中具有相同名称的列,默认取左表的列,可以通过 "tableName.colName" 指定该列来自哪个表。
注:
metrics
中使用的列名大小写不敏感,不需要与输入表的列名大小写保持一致。
matchingColumn:
表示连接列的字符串标量/向量或字符串向量组成的 tuple,支持 Integral,
Temporal 或 Literal(UUID 除外)类型。
matchingColumn
指定规则:
只有一个连接列。当左表和右表的连接列名相同时,
matchingColumn
是一个字符串标量,否则是一个长度为 2 的
tuple。例如:左表连接列名为 sym,右表连接列名为 sym1,则
matchingColumn
=
[[`sym],[`sym1]]。
有多个连接列。当左表和右表的连接列名相同时,
matchingColumn
是一个字符串向量,否则是一个长度为 2 的
tuple。例如:左表连接列名为 timestamp, sym,右表连接列名为 timestamp, sym1,则
matchingColumn
= [[`timestamp, `sym],
[`timestamp,`sym1]]。
timeColumn:
字符串标量或向量,可选参数。用于指定 leftTable 和 rightTable
中时间列的名称。两表的时间列名称可以不同,但数据类型需保持一致。当 leftTable 和 rightTable 时间列名称相同时,timeColumn
是字符串标量,否则,timeColumn 是长度为2的字符串向量。
outputElapsedMicroseconds
:布尔值,可选参数,表示是否输出单次响应计算的耗时(从触发计算的数据注入引擎到计算完成的耗时),默认为
false。指定参数
outputElapsedMicroseconds
后,在定义 outputTable 时需要在计算结果列后增加一个 LONG
类型的列和 INT 类型的列,详见
outputTable
参数说明。
keepLeftDuplicates
:布尔值,可选参数,表示在进行右连接时,是否匹配左表各分组内的所有数据。
若设置为 false(默认值):仅匹配左表各分组内的最新一条数据。
若设置为 true:匹配左表各分组内的所有数据。
keepRightDuplicates
:布尔值,可选参数,表示在进行左连接时,是否保留右表各分组内的所有数据。
若设置为 false(默认值):仅匹配右表各分组内的最新一条数据。
若设置为 true:匹配右表各分组内的所有数据。
isInnerJoin:
布尔值,可选参数,表示是否进行内连接。
若设置为 true(默认值):进行内连接,只有左右两表匹配的记录被计算输出。
若设置为 false:进行左连接或右连接,保留两个表中的所有记录。对于左右两表中匹配的记录进行计算,而未匹配的记录输出空值。
若要开启快照机制 (snapshot),必须指定
snapshotDir
与
snapshotIntervalInMsgCount
。
snapshotDir
可选参数,字符串,表示保存引擎快照的文件目录。
指定的目录必须存在,否则系统会提示异常。
创建流数据引擎时,如果指定了
snapshotDir
,会检查该目录下是否存在快照。如果存在,会加载该快照,恢复引擎的状态。
多个引擎可以指定同一个目录存储快照,用引擎的名称来区分快照文件。
一个引擎的快照可能会使用三个文件名:
临时存储快照信息:文件名为 <engineName>.tmp;
快照生成并刷到磁盘:文件保存为 <engineName>.snapshot;
存在同名快照:旧快照自动重命名为 <engineName>.old。
snapshotIntervalInMsgCount
可选参数,为整数类型,表示每隔多少条数据保存一次流数据引擎快照。
返回值
返回一个左、右两表连接后的表对象。
连接行为
由
isInnerJoin
参数决定连接方式:
当
isInnerJoin
=true
时,进行内连接,即每次数据注入引擎左表时,会在右表中查找与连接列字段相匹配的记录,匹配成功才会将两表匹配的记录进行连接,并计算
metrics
后输出。每次数据注入引擎右表时,亦会做同样操作。
当
isInnerJoin
=false 时,进行外连接,即每次数据注入引擎左表时,与右表进行左连接。无论在右表中是否找到匹配的记录,都会计算
metrics
并输出(右表未匹配的记录输出空值)。每次数据注入引擎右表时,亦会做同样操作。
当 keepLeftDuplicates=false 时,仅与左表中根据
matchingColumn
分组后的最新一条数据进行匹配连接。当
keepLeftDuplicates=true 时,与左表所有数据进行匹配连接。
当 keepRightDuplicates=false 时,仅与右表中根据
matchingColumn
分组后的最新一条数据进行匹配连接。当 keepRightDuplicates=true 时,与右表所有数据进行匹配连接。
snapshot join 引擎与 lookup join、equi join 引擎很相似,主要区别如下:
lookup join 引擎只能由左表的新记录触发连接;而 snapshot join 引擎可以由左表或右表的新记录触发连接。
equi join 引擎仅匹配最新记录,且没有缓存;而 snapshot join 引擎可以选择与右表/左表所有记录或最新记录进行匹配,且有缓存。
例子
例1. 不指定
outputElapsedMicroseconds,
指定
isInnerJoin
=true,同时指定
keepLeftDuplicates
=true,
keepRightDuplicates
=true。此时,引擎进行内连接,且匹配左/右表各分组内的所有数据。
//定义输入、输出表
share streamTable(1:0, `timestamp`sym1`id`price`val, [TIMESTAMP, SYMBOL, INT, DOUBLE, DOUBLE]) as leftTable
share streamTable(1:0, `timestamp`sym2`id`price`qty, [TIMESTAMP, SYMBOL, INT, DOUBLE, DOUBLE]) as rightTable
output=table(100:0, ["id","sym", "timestamp1", "timestamp2", "factor1", "factor2"],
[INT, SYMBOL, TIMESTAMP, TIMESTAMP, DOUBLE, DOUBLE])
test_metrics = [<val*10>, <qty>]
// 创建引擎
test_engine = createSnapshotJoinEngine(name = "test_SJE", leftTable=leftTable, rightTable=rightTable,
outputTable=output, metrics=test_metrics, matchingColumn = [["id","sym1"],["id","sym2"]],
timeColumn = `timestamp, isInnerJoin=true, keepLeftDuplicates=true,keepRightDuplicates=true)
//将左表数据注入引擎
timestamp = 2024.10.10T15:12:01.507+1..10
sym = take(["a","b","c","d"],10)
id = [1,1,2,1,5,2,4,4,1,4]
price = [2.53,7.61,8.07,7.87,7.29,9.39,5.98,9.49,9.20,9.17]
val = [101,108,101,109,104,100,108,100,107,104]
left_data = table(timestamp as timestamp,sym as sym1,id as id,price as price,val as val)
appendForJoin(test_engine,true, left_data)
//将右表数据注入引擎,此时会触发两表进行右连接
timestamp = 2024.10.10T15:12:01.507+1..10
sym = take(["a","b","c","d"],10)
id = [1,2,4,3,5,5,4,2,5,5]
price = [1.08,9.08,9.97,7.60,1.91,6.77,7.81,8.81,0.61,5.92]
qty = [208,200,203,202,204,201,206,207,205,205]
right_data = table(timestamp as timestamp,sym as sym2,id as id,price as price,qty as qty)
appendForJoin(test_engine,false, right_data)
select * from output
结果表中将保留左表所有匹配记录。
id
sym
timestamp1
timestamp2
factor1
factor2
1
a
2024.10.10T15:12:01.508
2024.10.10T15:12:01.508
1,010
208
1
a
2024.10.10T15:12:01.516
2024.10.10T15:12:01.508
1,070
208
2
b
2024.10.10T15:12:01.513
2024.10.10T15:12:01.509
1,000
200
4
c
2024.10.10T15:12:01.514
2024.10.10T15:12:01.510
1,080
203
5
a
2024.10.10T15:12:01.512
2024.10.10T15:12:01.512
1,040
204
4
c
2024.10.10T15:12:01.514
2024.10.10T15:12:01.514
1,080
206
5
a
2024.10.10T15:12:01.512
2024.10.10T15:12:01.516
1,040
205
例2. 不指定
outputElapsedMicroseconds
,指定
isInnerJoin
=true,
keepLeftDuplicate
s=false,
keepRightDuplicates
=true。此时,引擎进行内连接,且匹配左表各分组内的最新一条数据。
//首先取消上例中定义的引擎
dropStreamEngine("test_SJE")
//定义输入、输出表
share streamTable(1:0, `timestamp`sym1`id`price`val, [TIMESTAMP, SYMBOL, INT, DOUBLE, DOUBLE]) as leftTable
share streamTable(1:0, `timestamp`sym2`id`price`qty, [TIMESTAMP, SYMBOL, INT, DOUBLE, DOUBLE]) as rightTable
output=table(100:0, ["id","sym", "timestamp1", "timestamp2", "factor1", "factor2"],
[INT, SYMBOL, TIMESTAMP, TIMESTAMP, DOUBLE, DOUBLE])
test_metrics = [<val*10>, <qty>]
// 创建引擎
test_engine = createSnapshotJoinEngine(name = "test_SJE", leftTable=leftTable, rightTable=rightTable,
outputTable=output, metrics=test_metrics, matchingColumn = [["id","sym1"],["id","sym2"]],
timeColumn = `timestamp, isInnerJoin=true, keepLeftDuplicates=false,keepRightDuplicates=true)
//将左表数据注入引擎
timestamp = 2024.10.10T15:12:01.507+1..10
sym = take(["a","b","c","d"],10)
id = [1,1,2,1,5,2,4,4,1,4]
price = [2.53,7.61,8.07,7.87,7.29,9.39,5.98,9.49,9.20,9.17]
val = [101,108,101,109,104,100,108,100,107,104]
left_data = table(timestamp as timestamp,sym as sym1,id as id,price as price,val as val)
appendForJoin(test_engine,true, left_data)
//将右表数据注入引擎,此时会触发两表进行右连接
timestamp = 2024.10.10T15:12:01.507+1..10
sym = take(["a","b","c","d"],10)
id = [1,2,4,3,5,5,4,2,5,5]
price = [1.08,9.08,9.97,7.60,1.91,6.77,7.81,8.81,0.61,5.92]
qty = [208,200,203,202,204,201,206,207,205,205]
right_data = table(timestamp as timestamp,sym as sym2,id as id,price as price,qty as qty)
appendForJoin(test_engine,false, right_data)
select * from output
结果表中仅保留左表每个分组中的最新记录,因此比例1中的结果少了一行记录。
id
sym
timestamp1
timestamp2
factor1
factor2
1
a
2024.10.10T15:12:01.516
2024.10.10T15:12:01.508
1,070
208
2
b
2024.10.10T15:12:01.513
2024.10.10T15:12:01.509
1,000
200
4
c
2024.10.10T15:12:01.514
2024.10.10T15:12:01.510
1,080
203
5
a
2024.10.10T15:12:01.512
2024.10.10T15:12:01.512
1,040
204
4
c
2024.10.10T15:12:01.514
2024.10.10T15:12:01.514
1,080
206
5
a
2024.10.10T15:12:01.512
2024.10.10T15:12:01.516
1,040
205
例3. 不指定
outputElapsedMicroseconds
,指定
isInnerJoin
=false,
keepLeftDuplicates
=false,
keepRightDuplicates
=true。此时,引擎进行左连接或右连接。在左连接时,匹配右表各分组内的所有数据;在进行右连接时,仅匹配左表各分组内的最新一条数据。
//首先取消上例中定义的引擎
dropStreamEngine("test_SJE")
//定义输入、输出表
share streamTable(1:0, `timestamp`sym1`id`price`val, [TIMESTAMP, SYMBOL, INT, DOUBLE, DOUBLE]) as leftTable
share streamTable(1:0, `timestamp`sym2`id`price`qty, [TIMESTAMP, SYMBOL, INT, DOUBLE, DOUBLE]) as rightTable
output=table(100:0, ["id","sym", "timestamp1", "timestamp2", "factor1", "factor2"],
[INT, SYMBOL, TIMESTAMP, TIMESTAMP, DOUBLE, DOUBLE])
test_metrics = [<val*10>, <qty>]
// 创建引擎
test_engine = createSnapshotJoinEngine(name = "test_SJE", leftTable=leftTable, rightTable=rightTable,
outputTable=output, metrics=test_metrics, matchingColumn = [["id","sym1"],["id","sym2"]],
timeColumn = `timestamp, isInnerJoin=false, keepLeftDuplicates=false,keepRightDuplicates=true)
//将左表数据注入引擎
timestamp = 2024.10.10T15:12:01.507+1..10
sym = take(["a","b","c","d"],10)
id = [1,1,2,1,5,2,4,4,1,4]
price = [2.53,7.61,8.07,7.87,7.29,9.39,5.98,9.49,9.20,9.17]
val = [101,108,101,109,104,100,108,100,107,104]
left_data = table(timestamp as timestamp,sym as sym1,id as id,price as price,val as val)
appendForJoin(test_engine,true, left_data)
//将右表数据注入引擎,此时会触发两表进行右连接
timestamp = 2024.10.10T15:12:01.507+1..10
sym = take(["a","b","c","d"],10)
id = [1,2,4,3,5,5,4,2,5,5]
price = [1.08,9.08,9.97,7.60,1.91,6.77,7.81,8.81,0.61,5.92]
qty = [208,200,203,202,204,201,206,207,205,205]
right_data = table(timestamp as timestamp,sym as sym2,id as id,price as price,qty as qty)
appendForJoin(test_engine,false, right_data)
select * from output
由于引擎进行了右连接,仅保留左表每个分组中的最新记录。
id
sym
timestamp1
timestamp2
factor1
factor2
1
a
2024.10.10T15:12:01.508
1,010
1
b
2024.10.10T15:12:01.509
1,080
2
c
2024.10.10T15:12:01.510
1,010
1
d
2024.10.10T15:12:01.511
1,090
5
a
2024.10.10T15:12:01.512
1,040
2
b
2024.10.10T15:12:01.513
1,000
4
c
2024.10.10T15:12:01.514
1,080
4
d
2024.10.10T15:12:01.515
1,000
1
a
2024.10.10T15:12:01.516
1,070
4
b
2024.10.10T15:12:01.517
1,040
1
a
2024.10.10T15:12:01.516
2024.10.10T15:12:01.508
1,070
208
2
b
2024.10.10T15:12:01.513
2024.10.10T15:12:01.509
1,000
200
4
c
2024.10.10T15:12:01.514
2024.10.10T15:12:01.510
1,080
203
3
d
2024.10.10T15:12:01.511
202
5
a
2024.10.10T15:12:01.512
2024.10.10T15:12:01.512
1,040
204
5
b
2024.10.10T15:12:01.513
201
4
c
2024.10.10T15:12:01.514
2024.10.10T15:12:01.514
1,080
206
2
d
2024.10.10T15:12:01.515
207
5
a
2024.10.10T15:12:01.512
2024.10.10T15:12:01.516
1,040
205
5
b
2024.10.10T15:12:01.517
205
例4. 指定
outputElapsedMicroseconds
= true,输出耗时列和 batchSize 列。
//首先取消上例中定义的引擎
dropStreamEngine("test_SJE")
//定义输入、输出表
share streamTable(1:0, `timestamp`sym1`id`price`val, [TIMESTAMP, SYMBOL, INT, DOUBLE, DOUBLE]) as leftTable
share streamTable(1:0, `timestamp`sym2`id`price`qty, [TIMESTAMP, SYMBOL, INT, DOUBLE, DOUBLE]) as rightTable
output=table(100:0, ["id","sym", "timestamp1", "timestamp2", "factor1", "factor2", "timecost","batchsize"],
[INT, SYMBOL, TIMESTAMP, TIMESTAMP, DOUBLE, DOUBLE, LONG, INT])
test_metrics = [<val*10>, <qty>]
// 创建引擎
test_engine = createSnapshotJoinEngine(name = "test_SJE", leftTable=leftTable, rightTable=rightTable,
outputTable=output, metrics=test_metrics, matchingColumn = [["id","sym1"],["id","sym2"]],
timeColumn = `timestamp, outputElapsedMicroseconds=true, isInnerJoin=true,
keepLeftDuplicates=false,keepRightDuplicates=true)
//将左表数据注入引擎
timestamp = 2024.10.10T15:12:01.507+1..10
sym = take(["a","b","c","d"],10)
id = [1,1,2,1,5,2,4,4,1,4]
price = [2.53,7.61,8.07,7.87,7.29,9.39,5.98,9.49,9.20,9.17]
val = [101,108,101,109,104,100,108,100,107,104]
left_data = table(timestamp as timestamp,sym as sym1,id as id,price as price,val as val)
appendForJoin(test_engine,true, left_data)
//将右表数据注入引擎,此时会触发两表进行右连接
timestamp = 2024.10.10T15:12:01.507+1..10
sym = take(["a","b","c","d"],10)
id = [1,2,4,3,5,5,4,2,5,5]
price = [1.08,9.08,9.97,7.60,1.91,6.77,7.81,8.81,0.61,5.92]
qty = [208,200,203,202,204,201,206,207,205,205]
right_data = table(timestamp as timestamp,sym as sym2,id as id,price as price,qty as qty)
appendForJoin(test_engine,false, right_data)
select * from output
id
sym
timestamp1
timestamp2
factor1
factor2
timecost
batchsize
1
a
2024.10.10T15:12:01.516
2024.10.10T15:12:01.508
1,070
208
109
10
2
b
2024.10.10T15:12:01.513
2024.10.10T15:12:01.509
1,000
200
109
10
4
c
2024.10.10T15:12:01.514
2024.10.10T15:12:01.510
1,080
203
109
10
5
a
2024.10.10T15:12:01.512
2024.10.10T15:12:01.512
1,040
204
109
10
4
c
2024.10.10T15:12:01.514
2024.10.10T15:12:01.514
1,080
206
109
10
5
a
2024.10.10T15:12:01.512
2024.10.10T15:12:01.516
1,040
205
109
10
例5.
keepRightDuplicates
、
keepLeftDuplicates
为 false,不指定时间列
timeColumn
,此时输出表中的两个时间列为左表、右表数据到达的时间。
//首先取消上例中定义的引擎
dropStreamEngine("test_SJE")
//定义输入、输出表
share streamTable(1:0, `timestamp`sym1`id`price`val, [TIMESTAMP, SYMBOL, INT, DOUBLE, DOUBLE]) as leftTable
share streamTable(1:0, `timestamp`sym2`id`price`qty, [TIMESTAMP, SYMBOL, INT, DOUBLE, DOUBLE]) as rightTable
output=table(100:0, ["id","sym", "timestamp1", "timestamp2", "factor1", "factor2"],
[INT, SYMBOL, TIMESTAMP, TIMESTAMP, DOUBLE, DOUBLE])
test_metrics = [<val*10>, <qty>]
// 创建引擎
test_engine = createSnapshotJoinEngine(name = "test_SJE", leftTable=leftTable, rightTable=rightTable,
outputTable=output, metrics=test_metrics, matchingColumn = [["id","sym1"],["id","sym2"]], isInnerJoin=true)
//将左表数据注入引擎
timestamp = 2024.10.10T15:12:01.507+1..10
sym = take(["a","b","c","d"],10)
id = [1,1,2,1,5,2,4,4,1,4]
price = [2.53,7.61,8.07,7.87,7.29,9.39,5.98,9.49,9.20,9.17]
val = [101,108,101,109,104,100,108,100,107,104]
left_data = table(timestamp as timestamp,sym as sym1,id as id,price as price,val as val)
appendForJoin(test_engine,true, left_data)
//将右表数据注入引擎,此时会触发两表进行右连接
timestamp = 2024.10.10T15:12:01.507+1..10
sym = take(["a","b","c","d"],10)
id = [1,2,4,3,5,5,4,2,5,5]
price = [1.08,9.08,9.97,7.60,1.91,6.77,7.81,8.81,0.61,5.92]
qty = [208,200,203,202,204,201,206,207,205,205]
right_data = table(timestamp as timestamp,sym as sym2,id as id,price as price,qty as qty)
appendForJoin(test_engine,false, right_data)
select * from output
id
sym
timestamp1
timestamp2
factor1
factor2
1
a
2024.12.20T15:05:49.603
2024.12.20T15:05:49.603
1,070
208
2
b
2024.12.20T15:05:49.603
2024.12.20T15:05:49.603
1,000
200
4
c
2024.12.20T15:05:49.603
2024.12.20T15:05:49.603
1,080
203
5
a
2024.12.20T15:05:49.603
2024.12.20T15:05:49.603
1,040
204
4
c
2024.12.20T15:05:49.603
2024.12.20T15:05:49.603
1,080
206
5
a
2024.12.20T15:05:49.603
2024.12.20T15:05:49.603
1,040
205
FILE:references/doc_5266.md
# compress
**URL**: https://docs.dolphindb.cn/zh/funcs/c/compress.html
**来源**: DolphinDB 官方文档
---
compress
语法
compress(X, [method='lz4'])
详情
使用指定压缩算法对向量或数据表进行压缩。压缩某个变量后,需要使用函数
decompress
将其解压缩后方可使用该变量。
参数
X
是一个向量或数据表。
method
是一个字符串,为压缩算法,可取值为 "lz4", "delta" (delta-of-delta encoding), "zstd" 或
"chimp",默认值为 "lz4"。其中,
lz4 适用于几乎所有数据类型,它侧重于压缩和解压速度,虽然压缩比不是最高的,但解压速度快,适用于需要快速解压的场景。
zstd 同样适用于几乎所有数据类型,其压缩比高于 lz4,但解压缩速度较 lz4 慢约1倍。它适用于对压缩比有较高要求的场景。
delta 使用 delta of delta 算法,适用于 SHORT, INT, LONG 与时间或日期类型数据。
chimp 适用于小数部分长度在三位以内的 DOUBLE 类型的数据。
返回值
返回一个压缩后的向量或表。
例子
x=1..100000000
y=compress(x, "delta");
y.typestr();
// output: HUGE COMPRESSED VECTOR
z=compress(x, "zstd");
z.typestr();
// output: HUGE COMPRESSED VECTOR
select name, bytes from objs() where name in `x`y;
name
bytes
x
402653952
y
13634544
注:
对向量 x 压缩后的结果(y )使用
size
函数,结果为 y 的长度,而不是 x
的长度。若要从 y 中获取 x 的长度或其它信息,需先将 y 解压缩:
y.size();
// output: 12670932
z=decompress(y);
z.size();
// output: 100000000
相关函数:
decompress
FILE:references/doc_527.md
# clearTablePersistence
**URL**: https://docs.dolphindb.cn/zh/funcs/c/clearTablePersistence.html
**来源**: DolphinDB 官方文档
---
clearTablePersistence
语法
clearTablePersistence(table)
详情
停止将流数据表持久化到磁盘,然后删除磁盘上表的内容,但仍然保留表的结构。
参数
table
是一个表。
返回值
无。
例子
colName=["time","x"]
colType=["timestamp","int"]
t = streamTable(100:0, colName, colType);
enableTableShareAndPersistence(table=t, tableName=`st, cacheSize=1200000)
go;
for(s in 0:200){
n=10000
time=2019.01.01T00:00:00.000+s*n+1..n
x=rand(10.0, n)
insert into st values(time, x)
}
clearTablePersistence(st);
相关函数:
enableTablePersistence
,
disableTablePersistence
FILE:references/doc_5286.md
# cachedTable
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cachedTable.html
**来源**: DolphinDB 官方文档
---
cachedTable
语法
cachedTable(updateFunc, retentionSeconds)
详情
创建一种特殊类型的内存表:缓存表。如果查询缓存表的时间与上次数据更新时间相距等于或超过
retentionSeconds
秒,会自动执行
updateFunc
以更新缓存表。
如果需要多线程访问缓存表,需要将缓存表共享。
参数
updateFunc
是一个函数。它必须是无参数的,并且返回对象是一个表。
retentionSeconds
是一个正整数,表示数据更新的时间间隔,单位是秒。
返回值
一个表。
例子
下例定义一个一元函数 f1,在传入 cachedTable 时,需要通过部分应用的方式将 f1 转为无参数函数,即为 cachedTable 的
updateFunc
参数传入 f1{t}。
def f1(mutable t){
update t set id=id+1
return t
}
t=table(1..5 as id, 15 25 35 45 55 as val)
ct=cachedTable(f1{t}, 2);
select * from ct;
id
val
2
15
3
25
4
35
5
45
6
55
sleep(2100)
select * from ct
id
val
3
15
4
25
5
35
6
45
7
55
ct=NULL;
FILE:references/doc_5296.md
# ffill!
**URL**: https://docs.dolphindb.cn/zh/funcs/f/ffill_.html
**来源**: DolphinDB 官方文档
---
ffill!
语法
ffill!(obj,[limit])
详情
如果
obj
是一个向量,使用 NULL 值前的非空元素来填充 NULL 值。
如果
obj
是一个矩阵或表,对于表中的每一列,使用 NULL 值前的非空元素来填充 NULL
值。
注意:
该函数会改变输入的对象;而函数
ffill
会生成新的对象,不会改变输入的对象。
参数
obj
可以是向量、矩阵或表。
limit
是正整数,表示需要填充的 NULL 值的数量。
返回值
返回填充空缺值后的对象,其类型与形式同
obj
。
例子
例1.
x=1 2 3 NULL NULL NULL 4 5 6
x.ffill!();
x;
// x 中的空值被填充了
[1,2,3,3,3,3,4,5,6]
例2. 通过
limit
参数,指定需要填充 1 个NULL值:
x=1 2 3 NULL NULL NULL 4 5 6
x.ffill!(1);
// output
[1,2,3,3,,,4,5,6]
例3.
obj
指定为一个表
date=[2012.06.12,,2012.06.13,2012.06.14,2012.06.15]
sym=["IBM","MSFT","IBM","MSFT","MSFT"]
price=[40.56,26.56,,,50.76]
qty=[2200,4500,1200,5600,]
timestamp=[09:34:07,,09:36:42,09:36:51,09:36:59]
t=table(date,timestamp,sym,price,qty);
ffill!(t);
t;
输出返回:
date
timestamp
sym
price
qty
2012.06.12
09:34:07
IBM
40.56
2200
2012.06.12
09:34:07
MSFT
26.56
4500
2012.06.13
09:36:42
IBM
26.56
1200
2012.06.14
09:36:51
MSFT
26.56
5600
2012.06.15
09:36:59
MSFT
50.76
5600
FILE:references/doc_5297.md
# addValuePartitions
**URL**: https://docs.dolphindb.cn/zh/funcs/a/addValuePartitions.html
**来源**: DolphinDB 官方文档
---
addValuePartitions
语法
addValuePartitions(dbHandle, newValues, [level=0],
[locations])
详情
给数据库增加新的分区。目标数据库必须是 VALUE 分区类型或 COMPO 分区类型并且至少其中一层分区为 VALUE
类型。
如果配置参数
newValuePartitionPolicy
=add,系统会自动为新的数据增加分区。
参数
dbHandle
是数据库句柄。
newValues
是标量或向量,表示新的分区。
level
是整数。当分区类型为 COMPO,并且某层分区为 VALUE 时,需要使用
level
参数指定 VALUE 分区所在的层。它是可选参数。默认值为0
locations
是字符串标量或向量。如果目标数据库创建时,指定了
locations
参数,增加新的分区时可以使用
locations
参数指定新增分区的位置。它是可选参数。
返回值
返回的结果是一个整数,表示新增的分区数量。
例子
下面的例子是给分区类型为 COMPO 的数据库新增2017.08.12到2017.08.20分区。
n=1000000
ID=rand(100, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x)
dbID=database(, RANGE, 0 50 100);
dbDate = database(, VALUE, 2017.08.07..2017.08.11)
db = database("dfs://compoDB", COMPO, [dbID, dbDate]);
pt = db.createPartitionedTable(t, `pt, `ID`date)
pt.append!(t)
addValuePartitions(db,2017.08.12..2017.08.20,1)
// output
9
添加新的分区后,需要重新加载数据库。
db=database("dfs://compoDB")
pt=loadTable(db,"pt")
t1=table(0..99 as ID,take(2017.08.12,100) as date,rand(10.0,100) as x)
pt.append!(t1)
select count(*) from loadTable("dfs://compoDB","pt")
// output
1000100
FILE:references/doc_5299.md
# timestamp
**URL**: https://docs.dolphindb.cn/zh/funcs/t/timestamp.html
**来源**: DolphinDB 官方文档
---
timestamp
语法
timestamp(X)
详情
返回由日期和精确到毫秒的时间组成的时间戳。返回的数据类型是 TIMESTAMP,一个时间值。如果参数
X
不是日期和时间,则返回值是 1970.01.01 00:00:00.000 +
X
毫秒的时间戳。
参数
X
是一个时间标量或向量。
注:
自 2.00.12 版本起,支持转换 MONTH 类型的数据。
返回值
TIMESTAMP 类型标量或向量。
例子
timestamp(1)
返回:1970.01.01 00:00:00.001
timestamp(2016.10.12);
返回:2016.10.12 00:00:00.000
timestamp(2016.10.12)+1;
返回:2016.10.12 00:00:00.001
timestamp(now());
返回:2024.02.22 15:57:33.291
timestamp(2012.01M)
返回:2012.01.01T00:00:00.000
FILE:references/doc_5302.md
# conditionalIterate
**URL**: https://docs.dolphindb.cn/zh/funcs/c/conditionalIterate.html
**来源**: DolphinDB 官方文档
---
conditionalIterate
语法
conditionalIterate(cond, trueValue,
falseIterFunc)
该函数只能用作响应式状态引擎
metrics
中的函数。
详情
通过条件迭代实现因子中的递归逻辑。
假设该函数计算结果对应输出表的列为 factor,且迭代仅基于前一个值,对于第 k 条记录(k = 0, 1, 2 …),其计算逻辑为:
cond[k] == true:factor[k] = trueValue
cond[k] == false:factor[k] = falseIterFunc(factor)[k-1]
注:
若
falseIterFunc
为窗口函数,则会基于前多个 factor
值进行计算。
参数
cond
布尔表达式/返回值是布尔类型的函数。需要包含输入表中的字段,不支持常量/常量表达式。
trueValue
计算公式。计算结果将作为
cond
为 true 时的输出值。
falseIterFunc
用于进行迭代计算的函数。必须是一个单目函数,其唯一参数是
conditionalIterate
对应输出表中的字段。目前只支持以下函数(非单目函数以部分应用形式给出其他参数):
滑动窗口函数:
tmove
,
tmavg
,
tmmax
,
tmmin
,
tmsum
,
mavg
,
mmax
,
mmin
,
mcount
,
msum
累计窗口函数:
cumlastNot
,
cumfirstNot
序列相关函数:
ffill
,
move
若当前记录的
cond
为 true 时,触发
trueValue
的计算;若当前记录的
cond
为 false,则基于
conditionalIterate
的历史结果,调用
falseIterFunc
进行迭代计算。
注:
由于迭代是基于历史数据进行的,因此当前记录的输出是由输出表中的历史结果计算得到的。
tm系列函数计算时,时间窗口由当前记录的时间戳确定。由于迭代不包含当前记录,因此实质上的,且计算窗口范围为 (T - window,
T)。
trueValue
和
falseIterFunc
计算结果的类型需要兼容,且需要确保
trueValue
结果的精度和数据范围大于
falseIterFunc
。
例子
例1. 通过一个简单的例子,快速了解
conditionalIterate
函数的计算逻辑:
trade = table(take("A", 10) as sym, take(1 3 6, 10) as val0, take(10, 10) as val1)
trade
sym
val0
val1
A
1
10
A
3
10
A
6
10
A
1
10
A
3
10
A
6
10
A
1
10
A
3
10
A
6
10
A
1
10
创建一个响应式状态引擎,并按 sym 列分组进行计算。组内的计算逻辑如下:
若满足 val0 > 5,若返回 true,则
factor[k]=trueValue
,即以 val1 值作为输出。
若不满足 val0 > 5,则对应计算公式为
factor[k]=falseIterFunc(factor)[k-1]。当 k=3 时,对应 val0=1,val1=10,factor=[NULL,
NULL, 10],带入公式计算即 msum([NULL, NULL, 10], 3)[2]=10;当 k=4 时,对应
val0=3,val1=10,factor=[NULL, NULL, 10, 10],带入公式计算即 msum([NULL, NULL, 10,
10], 3)[3]=20,以此类推。
inputTable = streamTable(1:0, `sym`val0`val1, [SYMBOL, INT, INT])
outputTable = table(100:0, `sym`factor, [STRING, DOUBLE])
rse = createReactiveStateEngine(name="rsTest", metrics=<conditionalIterate(val0 > 5, val1, msum{, 3})>, dummyTable=inputTable, outputTable=outputTable, keyColumn="sym")
rse.append!(trade)
select * from outputTable
sym
factor
A
A
A
10
A
10
A
20
A
10
A
40
A
70
A
10
A
120
例2. 某因子在函数中算法逻辑如下:
def factor(TotalVolumeTrade, TotalValueTrade, HighPx, LowPx){
factorValue = iif(TotalVolumeTrade < 1500000, pow(HighPx*LowPx, 0.5)-(TotalVolumeTrade/TotalValueTrade), mavg(factor(TotalVolumeTrade, TotalValueTrade, HighPx, LowPx), 3))
return factorValue
}
该函数包含了一个递归操作。若需要在响应式状态引擎中实现上述逻辑,可以通过函数
conditionalIterate
实现。具体实现脚本如下:
@state
def factor1(TotalVolumeTrade, TotalValueTrade, HighPx, LowPx){
factorValue = conditionalIterate(TotalVolumeTrade < 1500000, (pow(HighPx*LowPx, 0.5)-(TotalVolumeTrade/TotalValueTrade)), mavg{,3})
return factorValue
}
SecurityID = ["000001.SZ","000001.SZ","000001.SZ","000001.SZ","000001.SZ","000001.SZ","000001.SZ","000001.SZ","000001.SZ","000001.SZ"]$SYMBOL
Date = [2022.04.01,2022.04.01,2022.04.01,2022.04.01,2022.04.01,2022.04.01,2022.04.01,2022.04.01,2022.04.01,2022.04.01]
Time = [09:30:00.000,09:30:03.000,09:30:06.000,09:30:09.000,09:30:12.000,09:30:15.000,09:30:18.000,09:30:21.000,09:30:24.000,09:30:27.000]
TotalVolumeTrade = [844800,1035700,1240100,1304500,1457800,1522400,1550900,1663800,1692100,1767100]
TotalValueTrade = [12982101,15908020,19038479,20022525,22363886,23349799,23784950,25506625.75,25937850.75,27080561.75]
HighPx = [15.37,15.37,15.37,15.37,15.37,15.37,15.37,15.37,15.37,15.37]
LowPx = [15.3,15.3,15.29,15.28,15.24,15.24,15.24,15.22,15.22,15.22]
trade = table(SecurityID, Date, Time, TotalVolumeTrade, TotalValueTrade, HighPx, LowPx)
result = table(1:0, `SecurityID`Date`Time`Factor, `SYMBOL`DATE`TIME`DOUBLE)
factor=[<Date>,<Time>, <factor1(TotalVolumeTrade, TotalValueTrade, HighPx, LowPx)>]
rse = createReactiveStateEngine(name="rsTest", metrics=factor, dummyTable=trade, outputTable=result, keyColumn="SecurityID")
rse.append!(trade)
trade1 = select *, (pow(HighPx*LowPx, 0.5)-(TotalVolumeTrade/TotalValueTrade)) as Factor0 from trade
select * from lj(trade1, result, `SecurityID`Date`Time)
dropStreamEngine("rsTest")
部分输出结果如图:
对于上述蓝框部分的数据,触发
trueValue
计算逻辑,因此 Factor 的值等于 Factor0 的计算结果;红框部分的数据触发
falseIterFunc
计算逻辑,每条记录的 Factor 是输出表中该记录前三条 Factor 的平均值。
FILE:references/doc_5315.md
# setMaxJobParallelism
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setMaxJobParallelism.html
**来源**: DolphinDB 官方文档
---
setMaxJobParallelism
语法
setMaxJobParallelism(userId, maxParallelism)
详情
为给定用户指定其提交的作业最多可以有多少个子任务同时并行执行。该命令必须要用户登录后才能执行。
若未执行该函数,管理员的作业的默认最大并行度为64;非管理员用户的作业的默认最大并行度为2。
注:
该函数可在控制节点、数据节点和计算节点运行。
参数
userId
是一个字符串,表示用户名。
maxParallelism
是一个1到64之间的整数,表示该用户的作业的最大并行度,即最多可以有多少个子任务同时并行执行。
例子
login(`admin,`123456)
createUser(`ElonMusk, `superman)
setMaxJobParallelism(`ElonMusk, 64);
FILE:references/doc_5324.md
# cancelRecoveryTask
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cancelRecoveryTask.html
**来源**: DolphinDB 官方文档
---
cancelRecoveryTask
语法
cancelRecoveryTask(taskId)
详情
取消已经提交但尚未开始执行的副本恢复任务。该命令只能由管理员在控制节点上执行。
参数
taskId
是一个字符串标量或向量,表示副本恢复任务的 ID,可以通过
getRecoveryTaskStatus
获得。
返回值
无。
FILE:references/doc_5336.md
# invChiSquare
**URL**: https://docs.dolphindb.cn/zh/funcs/i/invChiSquare.html
**来源**: DolphinDB 官方文档
---
invChiSquare
语法
invChiSquare(df, X)
详情
返回卡方分布的累计密度函数的逆函数值。
参数
df
是正数,表示卡方分布的自由度。
X
是0到1之间的浮点型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
invChiSquare(1, [0, 0.05, 0.15, 0.25]);
// output
[0, 0.003932, 0.035766, 0.101531]
invChiSquare(1, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output
[0.015791, 0.148472, 0.454936, 1.074194, 2.705543]
FILE:references/doc_5347.md
# sum3
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sum3.html
**来源**: DolphinDB 官方文档
---
sum3
语法
sum3(X)
详情
若
X
为向量,返回
X
中所有元素的立方和。
若
X
为矩阵,计算每列元素的立方和,返回一个向量。
若
X
为表,计算每列元素的立方和,返回一个表。
与所有其它聚合函数一致,计算时忽略 NULL 值。
即使
X
的数据类型是 INT 或 LONG,返回结果的数据类型总是 DOUBLE 类型。如果
X
中的所有元素为 NULL,返回的结果为
NULL。
参数
X
可以是标量、向量、矩阵或表。
返回值
返回标量、向量或表。
例子
sum3(1 2 3);
// output
36
sum3(1 NULL NULL);
// output
1
sum3(1.5 4.6 7.8);
// output
575.263
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
sum3(m);
// output
[36,405]
FILE:references/doc_5351.md
# getLocalIOTDBStaticTable
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getLocalIOTDBStaticTable.html
**来源**: DolphinDB 官方文档
---
getLocalIOTDBStaticTable
语法
getLocalIOTDBStaticTable(dbUrl, tableName, [dfsPath])
详情
该函数仅支持对该表有 TABLE_READ 权限或对该数据库有 DB_READ 权限的用户在数据节点调用。
参数
dbUrl
STRING 类型标量,表示分布式数据库的路径。
tableName
STRING 类型标量,表示表名。
dfsPath
STRING 类型标量,表示 chunk 的 DFS 路径。该参数可由
getChunksMeta
的返回值 dfsPath 列,去掉时间维度及之后内容获得,例如某 chunk 的 dfsPath 为
/db/Key1/20250428/gP
,则该参数应设置为
/db/Key1
。默认返回当前节点该表的所有静态表。
返回值
返回一个表,包含以下字段:
innerId: 测点对应的内部 ID。
测点列:列数和列名取决于 sort key,即建表时 sortColumns 中除最后一列以外的列。如果这些列中存在名为 innerId 或 valueType
的列,返回表中将自动重命名为 _innerId_ 和 _valueType_。
valueType: 测点对应的 IOTANY 列的类型。
例子
getLocalIOTDBStaticTable(dbUrl="dfs://db", tableName="pt", dfsPath="/db/Key1")
innerId
deviceId
location
valueType
1
1
loc2
DOUBLE
0
1
loc1
INT
FILE:references/doc_5356.md
# monthBegin
**URL**: https://docs.dolphindb.cn/zh/funcs/m/monthBegin.html
**来源**: DolphinDB 官方文档
---
monthBegin
语法
monthBegin(X, [offset], [n=1])
别名:
monthStart
详情
返回
X
所在月份的第一天。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
月更新一次。注意,
offset
和
n
须同时指定,且只有当
n
> 1 时,
offset
才会生效。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP 类型的标量、向量或表。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
monthBegin(2016.12.06);
// output: 2016.12.01
date=2016.04.12 2016.04.25 2016.05.12 2016.06.28 2016.07.10 2016.07.18 2016.08.02 2016.08.16 2016.09.26 2016.09.30
time = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12,09:38:13]
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
select avg(price),sum(qty) from t1 group by monthBegin(date,2016.01.01,2);
monthBegin_date
avg_price
sum_qty
2016.03.01
39.53
4100
2016.05.01
29.77
5300
2016.07.01
112.82
16000
2016.09.01
51.835
13300
相关函数:
monthEnd
,
businessMonthBegin
,
businessMonthEnd
,
semiMonthBegin
,
semiMonthEnd
FILE:references/doc_5363.md
# updateMCPTool
**URL**: https://docs.dolphindb.cn/zh/funcs/u/updateMCPTool.html
**来源**: DolphinDB 官方文档
---
updateMCPTool
语法
updateMCPTool(name, [func], [argNames], [argTypes],
[description], [extraInfo])
详情
更新一个 MCP tool。
如果某个参数没有提供,则不修改 tool 对应的信息。空字符串会被视为没有提供参数,因此如要清空描述信息,请使用空格代替空字符串。
参数
name
STRING 类型标量,表示 tool 的名称。
func
可选参数,自定义函数。
argNames
可选参数,STRING 类型向量,表示参数名。如无参数,请用
[]
表示。
argTypes
可选参数,STRING 类型向量,表示参数类型,既可指定为 DolphinDB 数据类型,也可指定为 JSON
数据类型。支持的数据类型如下:
DolphinDB 数据类型
JSON 数据类型
STRING
"string"
TEMPORAL
"string"
DOUBLE
"number"
BOOL
"boolean"
STRING[]
"array<string>"
TEMPORAL[]
"array<string>"
DOUBLE[]
"array<number>"
BOOL[]
"array<boolean>"
description
可选参数,STRING 类型标量,表示 tool 描述。
extraInfo
可选参数,一个字典,键是 STRING 类型,值是 ANY 或 STRING 类型,可指定其他信息。目前键支持 "title"。
返回值
一个字符串,表示更新 tool 的名称。
例子
// 定义 tool
def myTool(x) {
return x * 2 + 1
}
info = {
"title": "DolphinDB Tools"
}
addMCPTool("myTool", myTool, ["a"], ["number"], "This is a tool", info)
// 更新 tool
def myNewTool(x, y) {
return x * 2 + y
}
updateMCPTool("myTool", myNewTool, ["a","b"], ["number","number"], " ")
// 只更新额外信息
newInfo = {
"title": "Updated Tools"
}
updateMCPTool(name="myTool", extraInfo=newInfo)
FILE:references/doc_5376.md
# mvar
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mvar.html
**来源**: DolphinDB 官方文档
---
mvar
语法
mvar(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
的样本方差。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
mvar(1..6, 5);
// output: [,,,,2.5,2.5]
mvar(1..6, 5, 2);
// output: [,0.5,1,1.666667,2.5,2.5]
m=matrix(1 6 2 9 4 5, 11 12 18 23 21 10);
m;
#0
#1
1
11
6
12
2
18
9
23
4
21
5
10
mvar(m,3);
#0
#1
7
14.333333333333314
12.333333333333335
30.333333333333314
13
6.333333333333372
7
49
m=matrix(1 NULL 4 NULL 8 6 , 9 NULL NULL 10 NULL 2)
m.rename!(date(2020.04.06)+1..6, `col1`col2)
m.setIndexedMatrix!()
mvar(m,4d)
label
col1
col2
2020.04.07
2020.04.08
2020.04.09
4.5
2020.04.10
4.5
0.5
2020.04.11
8
2020.04.12
4
32
mvar(m,1w)
label
col1
col2
2020.04.07
2020.04.08
2020.04.09
4.5
2020.04.10
4.5
0.5
2020.04.11
12.3333
0.5
2020.04.12
8.9167
19
FILE:references/doc_539.md
# shell
**URL**: https://docs.dolphindb.cn/zh/funcs/s/shell.html
**来源**: DolphinDB 官方文档
---
shell
语法
shell(cmd)
详情
执行操作系统命令。该函数只能在配置参数 enableShellFunction 设置为 true 时,由 DolphinDB
系统管理员执行。
参数
cmd
是字符串,表示操作系统命令。
返回值
若
cmd
成功被执行,系统会返回 0。其它返回值请参阅相应操作系统的
system()
函数返回值。
例子
cmd="rm -rf /home/user1/test.txt"
shell(cmd);
FILE:references/doc_5390.md
# stopHeapSample
**URL**: https://docs.dolphindb.cn/zh/funcs/s/stopheapsample.html
**来源**: DolphinDB 官方文档
---
stopHeapSample
语法
stopHeapSample()
详情
动态关闭堆内存采样。仅管理员可执行该函数。
参数
无
例子
对内存使用情况进行分析的流程如下:
启用堆内存采样:可在启动 DolphinDB 前,设置环境变量 TCMALLOC_SAMPLE_PARAMETER 为1-524288之间的值(建议值
524288);或通过函数
startHeapSample
动态开启。
在可能发生内存泄漏的操作前、后分别执行
dumpHeapSample
,保存两个不同的文件。通过对比两个文件,确认操作涉及到的内存分配和使用情况。
关闭堆内存采样。
startHeapSample(524288)
dumpHeapSample("/DolphinDB/Data/heap1")
dumpHeapSample("/DolphinDB/Data/heap2")
stopHeapSample()
相关函数:
dumpHeapSample
,
startHeapSample
FILE:references/doc_5399.md
# getTSDBCompactionTaskStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getTSDBCompactionTaskStatus.html
**来源**: DolphinDB 官方文档
---
getTSDBCompactionTaskStatus
语法
getTSDBCompactionTaskStatus([count])
详情
查询 TSDB 引擎 level file 合并操作任务的状态。该函数只能在数据节点调用。
参数
count
非负整数。设置后,将返回最近的
count
条合并任务的记录。默认值为 0,返回每个
volume 中最新的 256 个已完成的合并任务以及所有未完成的合并任务。
返回值
返回一个表,包含以下几列:
列名
含义
volume
发生合并的文件所在的磁盘卷路径。由配置项
volumes
进行配置。
level
当前合并的 level file 层级。
chunkId
发生合并操作的 chunk 的 ID。
tableName
发生合并操作的数据表的物理表名。
files
参与当前合并任务的 level file。
force
是否由
triggerTSDBCompaction
强制触发。
receivedTime
当前合并任务进入任务队列的时间戳。
startTime
当前合并任务开始执行的时间戳。
endTime
当前合并任务执行结束的时间戳。
errorMessage
报错信息。如果失败,则显示失败的原因;否则显示空。
例子
getTSDBCompactionTaskStatus()
volume
level
chunkId
tableName
files
force
receivedTime
startTime
endTime
errorMessage
/home/DolphinDB/DolphinDB_Linux64_V2.00.9/server/clusterDemo/data/node1/storage
0
e0e00bc2-b81e-6eb9-4d01-7bb17fb39595
pt_2
0_00000006,0_00000011,
true
2023.06.22T12:47:32.009
2023.06.22T12:47:32.010
2023.06.22T12:47:32.182
/home/DolphinDB/DolphinDB_Linux64_V2.00.9/server/clusterDemo/data/node1/storage
1
a9dfccad-cec1-0786-480a-9ae809481a8b
pt_2
0_00000003,0_00000007,
true
2023.06.22T12:47:32.010
2023.06.22T12:47:32.182
2023.06.22T12:47:32.326
/home/DolphinDB/DolphinDB_Linux64_V2.00.9/server/clusterDemo/data/node1/storage
1
331324ce-b49f-94ac-4da8-a4bcf6c34e1c
pt_2
0_00000004,0_00000010,
true
2023.06.22T12:47:32.010
2023.06.22T12:47:32.326
2023.06.22T12:47:32.451
/home/DolphinDB/DolphinDB_Linux64_V2.00.9/server/clusterDemo/data/node1/storage
2
f3597e0f-6ad9-6eb6-45c8-d42adc5c50f7
pt_2
0_00000002,0_00000008,
true
2023.06.22T12:47:32.010
2023.06.22T12:47:32.451
2023.06.22T12:47:32.527
/home/DolphinDB/DolphinDB_Linux64_V2.00.9/server/clusterDemo/data/node1/storage
2
d36ac640-3428-069b-4382-0b9608b94d17
pt_2
0_00000005,0_00000009,
true
2023.06.22T12:47:32.010
2023.06.22T12:47:32.527
2023.06.22T12:47:32.616
/home/DolphinDB/DolphinDB_Linux64_V2.00.9/server/clusterDemo/data/node1/storage
2
e0e00bc2-b81e-6eb9-4d01-7bb17fb39595
pt_2
0_00000016,0_00000021,
true
2023.06.22T12:47:33.058
2023.06.22T12:47:33.058
2023.06.22T12:47:33.151
相关函数:
triggerTSDBCompaction
FILE:references/doc_5400.md
# cells
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cells.html
**来源**: DolphinDB 官方文档
---
cells
语法
cells(obj, row, col)
详情
返回一个由矩阵中
row
和
col
定位的元素组成的向量。
参数
obj
矩阵。
row
整型向量,表示行坐标。
col
与
row
等长的整型向量,表示列坐标。
返回值
一个向量,与
obj
中对应位置元素的数据类型保持一致。
例子
m=(1..15).reshape(3:5)
m;
col1
col2
col3
col4
col5
1
4
7
10
13
2
5
8
11
14
3
6
9
12
15
// 取矩阵中下标为 [0,1] 和 [0,2] 两个元素
cells(m, 0 0, 1 2)
// output
[4,7]
// 取矩阵对角线上的元素
index = 0..2
cells(m, index, index)
// output
[1, 5, 9]
FILE:references/doc_5411.md
# contextSum
**URL**: https://docs.dolphindb.cn/zh/funcs/c/contextSum.html
**来源**: DolphinDB 官方文档
---
contextSum
语法
contextSum(X, Y)
详情
找出
X
和
Y
中元素都不为 NULL 的位置,并计算
X
中这些位置对应的元素的和。
参数
X
和
Y
是向量、矩阵或表。
返回值
LONG/DOUBLE 类型标量/向量/表。
例子
contextSum(1 2 3 4 5, 2 3 4 5 6)
// output
15
contextSum(1..3, true false true)
// output
6
contextSum(1 2 NULL, 1 NULL 3)
// output
1
相关函数:
contextCount
,
contextSum2
FILE:references/doc_5427.md
# updateLicense
**URL**: https://docs.dolphindb.cn/zh/funcs/u/updateLicense.html
**来源**: DolphinDB 官方文档
---
updateLicense
语法
updateLicense()
详情
用于在线更新 license。先手动替换 license 文件,然后执行该函数在线更新 license,而无需重启节点。用户可通过
getLicenseExpiration
获得当前 license 的过期时间,以判断 license
是否生效。
该函数只在执行该函数的节点生效。因此在集群环境下,需要在所有节点上运行该函数。
注:
待升级 license 需满足以下条件才能成功升级(可通过
license
函数查看):
授权的客户名称(cilentName)和授权模式(authorization)必须与原来的 license
相同。
授权的节点个数(maxNodes),内存大小(maxMemoryPerNode),CPU
核数(maxCoresPerNode)不小于原 license 的授权。
若原 license 授权模式(authorization)为
site,则无法进行在线升级。
从 2.00.9 版本开始,支持将 DolphinDB 进程绑定到具体的 CPU 内核上。若待升级
license 中修改了绑定核信息,则升级 license 后须重启 DolphinDB 以使 CPU 内核绑定的设置生效。
参数
无
返回值
一个字典,表示许可证信息。
例子
updateLicense()
// output
authorization->commercial
licenseType->0
maxMemoryPerNode->32
maxCoresPerNode->8
clientName->test license
bindCPU->true
expiration->2022.03.01
maxNodes->8
version->
modules->-1
FILE:references/doc_5437.md
# checkBackup
**URL**: https://docs.dolphindb.cn/zh/funcs/c/checkBackup.html
**来源**: DolphinDB 官方文档
---
checkBackup
语法
checkBackup(backupDir, dbPath, [tableName],
[partition])
详情
检查备份文件的的完整性和准确性。若所有备份文件均完整且准确,则返回一个空表;否则返回异常的备份文件信息,此时可通过在
backup
函数设置
force
= true 开启强制备份以恢复受损的备份分区数据。
参数
backupDir
字符串,表示存放备份数据的目录。
dbPath
字符串,表示数据库路径。
tableName
字符串标量或向量,表示表名。若不指定,表示指定数据库下的所有表。
partition
表示分区。是字符串,表示备份分区的相对路径。分区路径可以包含通配符("%"和"?"),"?"表示单个字符,"%"表示0,1或多个字符。
若仅检查某个分区,输入分区的相对路径或者"%/"+”分区名称”。举例:要检查 "dfs://compoDB"
下的分区”20170810/50_100”,输入 "/compoDB/20170807/0_50" 或者 "%/20170807/0_50"。
若需要检查所有分区,直接输入"%"。
返回值
一个表。
例子
dbName = "dfs://compoDB2"
n=1000
ID=rand("a"+string(1..10), n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10, n)
t=table(ID, date, x)
db1 = database(, VALUE, 2017.08.07..2017.08.11)
db2 = database(, HASH,[INT, 20])
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db = database(dbName, COMPO,[ db1,db2])
// 创建2个表
pt1 = db.createPartitionedTable(t, `pt1, `date`x).append!(t)
pt2 = db.createPartitionedTable(t, `pt2, `date`x).append!(t)
// SQL 元代码方式备份 pt1
backup(backupDir=backupDir1, sqlObj=<select * from pt1>, parallel=true)
// 拷贝文件方式备份 pt2
backup(backupDir=backupDir2, dbPath=dbName, parallel=true, tableName=`pt2)
// pt2 备份文件都正常,pt1 中一个 chunk 文件出现问题
checkBackup(backupDir=backupDir2, dbPath=dbName, tableName="pt2") // 返回一个空表
checkBackup(backupDir=backupDir1, dbPath=dbName, tableName="pt1") // 返回出错的 chunk 信息
dbName
tableName
chunkPath
chunkID
partitionPath
dfs://compoDB2
pt1
/compoDB2/20170807/Key2/9
4ae71414-8bfe-4283-b04c-b2e48e90be08
/20170807/Key2
上例中,通过调用
checkBackup
函数,可以发现在 pt1 中存在损坏的 chunk 文件。此时,设置
force
= true
再次强制备份,以恢复受损文件。
backup(backupDir1, <select * from pt1>,force=true, parallel=true)
checkBackup(backupDir=backupDir1, dbPath=dbName, tableName="pt1") // 返回一个空表
FILE:references/doc_545.md
# log2
**URL**: https://docs.dolphindb.cn/zh/funcs/l/log2.html
**来源**: DolphinDB 官方文档
---
log2
语法
log2(X)
详情
求以2为底,
X
的对数。
参数
X
可以是标量、向量、数据对、矩阵或表。
返回值
返回数值类型的结果,形式和
X
一致。
例子
log2(4);
// output
2
log2(0 2 4 8 NULL);
// output
[,1,2,3,]
log2(1..4$2:2);
#0
#1
0
1.584963
1
2
FILE:references/doc_5452.md
# getMarketCalendar
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getMarketCalendar.html
**来源**: DolphinDB 官方文档
---
getMarketCalendar
语法
getMarketCalendar(marketName, [startDate], [endDate])
详情
DolphinDB 提供国内外超过50个交易所的交易日历信息(对应文件存放于
marketHolidayDir
中),通过该函数可以获取由
startDate
和
endDate
确定的时间范围内的交易日历。
参数
marketName
字符串标量,表示交易日历标识,例如:国外交易所的 ISO Code、国内交易所简称或自定义交易日历名称。必须是
marketHolidayDir
下存在的文件名,否则会报错。
startDate
DATE 类型标量。默认为空,表示起始日期为
marketName
同名文件中最小年份的1月1日。
endDate
DATE 类型标量。默认为空,表示结束日期为
marketName
同名文件中最大年份的12月31日。
返回值
DATE 类型向量。
例子
getMarketCalendar("CCFX",2022.01.01, 2022.01.10)
输出返回:[2022.01.04,2022.01.06,2022.01.07,2022.01.10]
FILE:references/doc_5459.md
# getSlaveReplicationStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getSlaveReplicationStatus.html
**来源**: DolphinDB 官方文档
---
getSlaveReplicationStatus
语法
getSlaveReplicationStatus([limit=-1])
详情
由管理员在从集群的控制节点调用,获取从集群的异步复制状态。若通过 slaveReplicationDBScope
指定了回放数据库的范围,则仅获取该范围内的异步复制情况。其中,已完成的任务排列在前面,未完成的任务排列在后面。
如果未指定
limit
,则返回的任务数量不受限制。
如果指定
limit
,则返回最多
limit
个任务列表。
其中,已完成的任务最多显示最近的1万条记录;而未完成的任务只显示从最早时间开始,直到满足指定条数的记录。
参数
limit
一个整数,表示结果中最多可返回的任务数量。
返回值
返回一个表,包含以下字段:
taskId:异步复制任务 id。
masterTid:该任务对应主集群中的事务 id。
groupId:异步复制任务所属的组。
executionSet:任务所属的执行集ID。
queueId:任务所属执行队列的编号。
operationType:任务类型,参照异步复制支持性表。
createTime:从集群从主集群获取任务的时间,类型为 NANOTIMESTAMP。
dbName:任务对应的数据库的路径。
tableName:任务对应的表名。
srcIP:存储写任务数据的数据节点 ip。
srcPort:存储写任务数据的数据节点 port。
finishTime:任务的完成时间,类型为 NANOTIMESTAMP。
executionNode:执行该任务的从集群的数据节点别名。
state:任务执行状态,包含四种类型:
WAITING(等待执行)、EXECUTING(正在执行)、FINISH(执行完成/任务skip)、FAILED(执行失败)。
details:补充说明。若 state = FAILED,则该列为执行失败的原因;若 state =
FINISH,该列用于对该任务进行补充说明。
例子
getSlaveReplicationStatus();
输出返回:
taskId
masterTid
groupId
queueId
operationType
createTime
dbName
tableName
srcIP
srcPort
finishTime
executionNode
state
details
1
1
1
0
CREATE_DOMAIN
2022.11.08T10:50:37.425056956
db://test_dropPartition_value
localhost
8002
2022.11.08T10:50:37.452792885
NODE2
FINISH
2
2
2
1
CREATE_PARTITIONED_TABLE
2022.11.08T10:50:37.425056988
db://test_dropPartition_value
pt
localhost
8002
2022.11.08T10:50:37.479906033
NODE3
FINISH
3
3
3
2
APPEND
2022.11.08T10:50:37.425057012
db://test_dropPartition_value
pt
localhost
8002
2022.11.08T10:50:37.638746819
NODE1
FINISH
4
4
4
3
DROP_PARTITION
2022.11.08T10:50:37.425057037
pt
localhost
8002
2022.11.08T10:50:37.869783336
NODE2
FINISH
相关函数:
getMasterReplicationStatus
,
getSlaveReplicationQueueStatus
FILE:references/doc_5469.md
# latestKeyedTable
**URL**: https://docs.dolphindb.cn/zh/funcs/l/latestKeyedTable.html
**来源**: DolphinDB 官方文档
---
latestKeyedTable
语法
latestKeyedTable(keyColumns, timeColumn, [X1], [X2], .....)
或
latestKeyedTable(keyColumns, timeColumn, capacity:size, colNames,
colTypes)
或
latestKeyedTable(keyColumns, timeColumn, table)
详情
该函数用于创建键值内存表,包含一个主键。主键可由一个或多个字段组成。其相较于
keyedTable,除主键外,还包含一个时间列,用于判断是否更新记录。
向表中添加新记录时,系统自动检查新记录的主键值。如果新记录的主键值与已有记录的主键值相同,且新记录的时间戳大于等于已有记录的时间戳,则更新表中对应的记录,否则不更新。因为在写入数据时会判断时间列,对相同主键的记录进行去重,所以
latestKeyedTable
写入性能较
keyedTable
差,但查询性能不受影响。
注:
不允许对主键进行修改(update, replaceColumn!)和删除(alter,
dropColumns!)操作。
优化查询 latestKeyedTable 的方法和相关案例请参照函数 keyedTable。
参数
在
keyedTable
的基础上,增加了
timeColumn
参数。
timeColumn
字符串,表示时间列,可以为整型或时间类型。
返回值
一张表。
例子
例1. 创建键值表
第一种写法:
sym=`A`B`C`D`E
id=5 4 3 2 1
val=52 64 25 48 71
timeCol = 2022.12.07T00:00:00.001+0..4
t=latestKeyedTable(`sym`id,`timeCol,sym,id,timeCol,val)
t;
输出返回:
sym
id
timeCol
val
A
5
2022.12.07T00:00:00.001
52
B
4
2022.12.07T00:00:00.002
64
C
3
2022.12.07T00:00:00.003
25
D
2
2022.12.07T00:00:00.004
48
E
1
2022.12.07T00:00:00.005
71
第二种写法:
t=latestKeyedTable(`sym`id,`timeCol, 1:0,`sym`id`timeCol`val,[SYMBOL,INT,TIMESTAMP, INT])
insert into t values(`A`B`C`D`E,5 4 3 2 1,2022.12.07T00:00:00.001+0..4,52 64 25 48 71);
第三种写法:
tmp=table(sym, id, timeCol, val)
t=latestKeyedTable(`sym`id, `timeCol, tmp);
例2. 更新键值表
插入新记录,并且新记录中的主键值与表中主键值重复,根据时间列来确定保留哪条记录:
insert into t values(`A`A`E,5 5 1, 2022.12.07T00:00:00.001 2022.12.07T00:00:00.007 2022.12.07T00:00:00.003, 44 66 28);
t;
输出返回:
sym
id
timeCol
val
A
5
2022.12.07T00:00:00.007
66
B
4
2022.12.07T00:00:00.002
64
C
3
2022.12.07T00:00:00.003
25
D
2
2022.12.07T00:00:00.004
48
E
1
2022.12.07T00:00:00.005
71
相关函数:
keyedTable
,
indexedTable
,
latestIndexedTable
FILE:references/doc_5473.md
# triggerTSDBCompaction
**URL**: https://docs.dolphindb.cn/zh/funcs/t/triggerTSDBCompaction.html
**来源**: DolphinDB 官方文档
---
triggerTSDBCompaction
语法
triggerTSDBCompaction(chunkId, [level=0])
详情
在 TSDB 存储引擎中,强制触发指定 chunk 内指定层级所有 Level File 的合并操作,以提升读取效率。
注
:只有在配置参数
allowTSDBLevel3Compaction
设置为 true 且表中指定
keepDuplicates
=FIRST/LAST 时,才会执行 Level 3 文件的合并。
参数
chunkId
是字符串标量,表示 chunk 的 ID。
level
可选参数,表示需要合并的层级。可以是 [-1,3] 的整数。
当
level
为 [0,3] 区间内的整数时,触发对应层级的 Level File 合并。默认值为 0。
当
level
=-1 时,所有 Level File 会合并为一个 Level File。
返回值
无。
例子
一个分区内包含两种文件类型,一种是记录数据库和数据表结构信息的文件(file chunk),另一种是数据文件(tablet chunk)。
因为只能对数据文件进行合并操作,在查询 chunk ID 时,需通过 type=1(代表数据文件)来进行过滤。
chunkIds = exec chunkId from getChunksMeta() where type=1
for (x in chunkIds) {
triggerTSDBCompaction(x)
}
FILE:references/doc_5479.md
# 基于 Docker 部署 DolphinDB
**URL**: https://docs.dolphindb.cn/zh/tutorials/docker_single_deployment.html
**来源**: DolphinDB 官方文档
---
基于 Docker 部署 DolphinDB
Docker 只是轻量化的资源隔离,DolphinDB 部署在 Docker 环境和非 Docker 环境下的运行性能差异不明显,可根据业务需求选择合适的运行环境。本文介绍如何使用 Docker 部署一个社区版/企业版 DolphinDB 单机服务。
环境准备
安装 Docker
Docker 可以方便地在 Linux /MAC/Windows 平台安装,安装方法请参考
Docker 官方文档
。
拉取 DolphinDB 的 Docker 镜像
最新 Docker 镜像可以通过
Docker 官方镜像仓库
获取,以 tag 为 v2.00.5 为例:
docker pull dolphindb/dolphindb:v2.00.5
注意:本文基于 v2.00.5 版本编写,文中涉及的版本号请根据实际使用的版本进行相应调整。
主机信息
主机名
IP
部署服务
数据盘挂载
host1
xxx.xxx.xx.xx
dolphindb
/ddbdocker
快速体验
Docker(X86 架构版)
登录机器执行以下脚本,创建一个 Docker 容器:
docker run -itd --name dolphindb \
--hostname host1 \
-p 8848:8848 \
-v /etc:/dolphindb/etc \
dolphindb/dolphindb:v2.00.5 \
sh
参数解释:
--hostname
: 容器的主机名称(用于采集指纹制作企业版 Licence)
可通过
hostname
shell 命令查看主机名称。
-p
:其中前一个 8848 端口为宿主机端口,后一个 8848 端口为映射到 DolphinDB 容器中的端口(DolphinDB 单机版默认端口)。启动后可通过本机 8848 端口访问 DolphinDB。
-v
:表示使用映射宿主机的
/etc
目录到容器中的 /dolphindb/etc 路径,用于采集指纹制作企业版 License。
--name
:为容器名。指定容器名以便对该容器进行相关操作,例如,通过容器名查看容器相关信息等。若不指定,Docker 会随机分配一个容器名。
dolphindb/dolphindb:v2.00.5
:必填参数,用于指定构建容器的镜像。镜像名称必须完整(包含dolphindb仓库及版本信息),例如:dolphindb/dolphindb:v2.00.5
检测容器是否成功构建
执行如下命令
docker ps|grep dolphindb
期望输出
347bfa54df86 dolphindb/dolphindb:v2.00.5 "sh -c 'cd /data/ddb…" 20 seconds ago Up 19 seconds 0.0.0.0:8848->8848/tcp, :::8848->8848/tcp dolphindb
客户端连接 DolphinDB 进行测试。
详细教程参考
使用客户端
Docker(ARM架构)
登录机器执行以下脚本,创建一个 Docker 容器:
docker run -itd --name dolphindb \
--hostname cnserver10 \
-p 8848:8848 \
-v /etc:/dolphindb/etc \
dolphindb/dolphindb-arm64:v2.00.7 \
sh
参数解释:
--hostname
:容器的主机名称(用于采集指纹制作企业版 License)
-p
:其中前一个 8848 端口为宿主机端口,后一个8848端口为映射到 DolphinDB容器中的端口(DolphinDB 单机版默认端口)。启动后可通过本机 8848 端口访问 DolphinDB。
-v
:表示使用映射宿主机的
/etc
目录到容器中的 /dolphindb/etc 路径,用于采集指纹制作企业版 License。
--name
:为容器名。指定容器名以便对该容器进行相关操作,例如,通过容器名查看容器相关信息等。若不指定,Docker 会随机分配一个容器名。
dolphindb/dolphindb-arm64:v2.00.7
:必填参数,用于指定构建容器的镜像。镜像名称必须完整(包含dolphindb仓库及版本信息),例如:dolphindb/dolphindb-arm64:v2.00.7
检测容器是否成功构建
执行如下命令
docker ps|grep dolphindb
期望输出
347bfa54df86 dolphindb/dolphindb-arm64:v2.00.7 "sh -c 'cd /data/ddb…" 20 seconds ago Up 19 seconds 0.0.0.0:8848->8848/tcp, :::8848->8848/tcp dolphindb
客户端连接 DolphinDB 进行测试。
详细教程参考
使用客户端
生产环境部署建议
以下内容以 X86 架构版为例。
在线部署
登录机器执行 shell 脚本,下载安装包并配置容器映射文件,以 v2.00.5 为例
git clone --depth=1 https://github.com/dolphindb/dolphindb-k8s && \
cd dolphindb_k8s/docker-single && \
sh map_dir.sh
注意
:由于新建的目录是
/ddbdocker
,可能遇到用户新建权限问题,需自行修改可以用户可以创建权限的文件夹 -->
执行下面命令:
tree /ddbdocker
期望输出:
├── ddbdocker
│ ├── data
│ ├── ddb_related
│ │ ├── dolphindb.cfg
│ │ └── dolphindb.lic
│ └── plugins
│ ├── hdf5
│ │ ├── libPluginHdf5.so
│ │ └── PluginHdf5.txt
│ ├── mysql
│ │ ├── libPluginMySQL.so
│ │ └── PluginMySQL.txt
│ ├── odbc
│ │ ├── libPluginODBC.so
│ │ └── PluginODBC.txt
│ └── parquet
│ ├── libPluginParquet.so
│ └── PluginParquet.tx
文件夹说明如下:
文件(夹)名
文件(夹)用途
宿主机映射路径
容器映射路径
dolphindb.cfg
单节点模式下的 DolphinDB 配置文件
/ddbdocker/ddb_related/dolphindb.cfg
/data/ddb/server/dolphindb.cfg
dolphindb.lic
DolphinDB 的证书文件(企业版的需要联系工程师)
/ddbdocker/ ddb_related/dolphindb.lic
/data/ddb/server/dolphindb.lic
plugins
存储 DolphinDB 插件
/ddbdocker/plugins
/data/ddb/server/plugins
data
用来存储 DolphinDB 数据节点相关文件(例如元数据,流数据,数据表等)
/ddbdocker/data
/data/ddb/server/data
执行下面命令启动容器:
docker run -itd --name dolphindb \
-p 8848:8848 \
--ulimit nofile=1000000:1000000 \
-v /etc:/dolphindb/etc \
-v /ddbdocker/ddb_related/dolphindb.cfg:/data/ddb/server/dolphindb.cfg \
-v /ddbdocker/ddb_related/dolphindb.lic:/data/ddb/server/dolphindb.lic \
-v /ddbdocker/plugins:/data/ddb/server/plugins \
-v /ddbdocker/data:/data/ddb/server/data \
dolphindb/dolphindb:v2.00.5 \
sh \
-stdoutLog 1
预期输出容器 id
3cdfbab788d0054a80c450e67d5273fb155e30b26a6ec6ef8821b832522474f5
。
使用 DolphinDB 客户端连接 DolphinDB 进行测试
详细教程参考
使用客户端
离线部署
在DolphinDB官网下载并安装对应版本的 DolphinDB server 安装镜像包。
在下载的 zip 压缩包的同目录添加 shell 脚本
map_dir.sh
,内容如下:
#!/bin/bash
set -e
clear
#创建用于存储相应文件(夹)的空白目录
dir1=/ddbdocker
dir2=/ddbdocker/ddb_related
if [ ! -e "$dir1" ];
then
mkdir $dir1
fi
if [ ! -e "$dir2" ];
then
mkdir $dir2
fi
#获取安装包
ddb_zip=$(ls ./DolphinDB_Linux64_V*.zip)
ddb_name=$(basename $ddb_zip .zip)
if [ -e $ddb_zip ];
then
echo -e "上传软件安装包成功" "\033[32m UpLoadSuccess\033[0m"
else
echo -e "无法找到安装包,请上传至该目录" "\033[31m UpLoadFailure\033[0m"
echo ""
sleep 1
exit
fi
#解压安装包
unzip "ddb_zip" -d "ddb_name"
if [ -d ./$ddb_name ];then
echo -e "解压软件安装包成功" "\033[32m UnzipSuccess\033[0m"
else
echo -e "解压安装包失败,请检查安装包是否下载完整" "\033[31m UnzipFailure\033[0m"
echo ""
sleep 1
exit
fi
#获取相应路径下的源和目标文件(夹)
source_f1=./ddb_name/server/dolphindb.cfg
source_f2=./ddb_name/server/dolphindb.lic
source_dir4=./ddb_name/server/plugins
f1=/ddbdocker/ddb_related/dolphindb.cfg
f2=/ddbdocker/ddb_related/dolphindb.lic
dir3=/ddbdocker/data
dir4=/ddbdocker/plugins
#编写函数对各目标路径进行遍历并通过设置条件语句来判断是否要对已有的文件进行覆盖
function isCovered() {
for i in $*;
do
if [ -e $i ];
then
#echo $i
read -p "The $i has already existed, would you want to recover or clean it and other similar ones?(y/n)" answer
if [ $answer=="y" ];
then
break
else
echo ""
sleep 1
exit
fi
fi
done
}
isCovered $f1 $f2 $dir3 $dir4
#进行相应文件(夹)的拷贝
cp -rpf $source_f1 $f1
cp -rpf $source_f2 $f2
if [ -e "$dir3" ];
then
rm -rf $dir3
fi
mkdir $dir3
cp -rpf $source_dir4 $dir4
#删除解压的安装包
rm -rf ./ddb_name
执行 shell 脚本,构建数据映射目录
sh map_dir.sh && tree /ddbdocker
期望输出:
├── ddbdocker
│ ├── data
│ ├── ddb_related
│ │ ├── dolphindb.cfg
│ │ └── dolphindb.lic
│ └── plugins
│ ├── hdf5
│ │ ├── libPluginHdf5.so
│ │ └── PluginHdf5.txt
│ ├── mysql
│ │ ├── libPluginMySQL.so
│ │ └── PluginMySQL.txt
│ ├── odbc
│ │ ├── libPluginODBC.so
│ │ └── PluginODBC.txt
│ └── parquet
│ ├── libPluginParquet.so
│ └── PluginParquet.tx
文件夹说明如下:
文件(夹)名
文件(夹)用途
宿主机映射路径
容器映射路径
dolphindb.cfg
单节点模式下的 DolphinDB 配置文件
/ddbdocker/ddb_related/dolphindb.cfg
/data/ddb/server/dolphindb.cfg
dolphindb.lic
DolphinDB 的证书文件(企业版的需要联系工程师)
/ddbdocker/ ddb_related/dolphindb.lic
/data/ddb/server/dolphindb.lic
plugins
存储 DolphinDB 插件
/ddbdocker/plugins
/data/ddb/server/plugins
data
用来存储 DolphinDB 数据节点相关文件(例如元数据,流数据,数据表等)
/ddbdocker/data
/data/ddb/server/data
执行下面命令启动容器:
docker run -itd --name dolphindb \
-p 8848:8848 \
--ulimit nofile=1000000:1000000 \
-v /etc:/dolphindb/etc \
-v /ddbdocker/ddb_related/dolphindb.cfg:/data/ddb/server/dolphindb.cfg \
-v /ddbdocker/ddb_related/dolphindb.lic:/data/ddb/server/dolphindb.lic \
-v /ddbdocker/plugins:/data/ddb/server/plugins \
-v /ddbdocker/data:/data/ddb/server/data \
dolphindb/dolphindb:v2.00.5 \
sh \
-stdoutLog 1
预期输出容器 id
3cdfbab788d0054a80c450e67d5273fb155e30b26a6ec6ef8821b832522474f5
。
使用 DolphinDB 客户端连接 DolphinDB 进行测试
详细教程参考
使用客户端
常见问题
如何自定义配置文件
在宿主机上找到映射的 DolphinDB 配置文件 dolphindb.cfg,此处的路径为/ddbdocker/ddb_related/dolphindb.cfg,其文件内容如下:
localSite=localhost:8848:local8848
mode=single
maxMemSize=32
maxConnections=512
workerNum=4
localExecutors=3
dataSync=1
chunkCacheEngineMemSize=2
newValuePartitionPolicy=add
maxPubConnections=64
subExecutors=4
subPort=8849
lanCluster=0
重要参数解释:
localSite
: 节点的局域网信息,格式为 host:port:alias。单实例中默认值为 localhost:8848:local8848。其中8848为 DolphinDB 运行的端口号,必须填写。
workerNum
: 常规作业的工作线程的数量,决定了节点最大并发前台作业数。默认值是 CPU 的内核数。
localExecutors
: 本地执行线程的数量,决定了节点最大并发子任务数。默认值是 CPU 的内核数-1。
maxMemSize
:分配给 DolphinDB 的最大内存空间(以 GB 为单位)。如果该参数设为0,表明 DolphinDB 的内存使用没有限制。建议设置为比机器内存容量低的一个值。
如何升级版本
执行如下命令拉取新版本的 DolphinDB 镜像,下例拉取的镜像为 2.00.6 版本:
docker pull dolphindb/dolphindb:v2.00.6
执行下列命令,进行升级:
docker run -itd --name dolphindb \
-p 8848:8848 \
--ulimit nofile=1000000:1000000 \
-v /etc:/dolphindb/etc \
-v /ddbdocker/ddb_related/dolphindb.cfg:/data/ddb/server/dolphindb.cfg \
-v /ddbdocker/ddb_related/dolphindb.lic:/data/ddb/server/dolphindb.lic \
-v /ddbdocker/plugins:/data/ddb/server/plugins \
-v /ddbdocker/data:/data/ddb/server/data \
dolphindb/dolphindb:v2.00.6 \
sh \
-stdoutLog 1
DolphinDB 升级只是替换二进制安装包,需要保留之前版本的
dolphindb.cfg
(DolphinDB 的配置),
dolphindb.lic
(DolphinDB 的证书文件),
plugins
(DolphinDB 内置的插件),
data
(DolphinDB 内置的数据文件等)目录,以保证配置不更改和数据不丢失。
注意
:
由于 Docker 容器名要求唯一,如果之前的容器依旧保留,则新容器名必须要和之前的容器名不同;
需要注意端口号不被占用。
通过 GUI 连接该节点,执行以下命令查看版本信息,检查升级是否成功。
version()
期望输出:
2.00.6
报错及解决方案
报错信息如下
Can't find time zone database. Please use parameter tzdb to set the root directory of time zone database.
解决方案:
若 Docker 镜像中不包含
tzdata
包,比如
ubuntu:latest
,会导致 DolphinDB 启动报如上错误,执行下述命令安装
tzdata
包:
apt-get install tzdata
报错信息如下
<ERROR> : Failed to retrieve machine fingerprint
解决方案:
由于正式 License 需要校验服务器硬件信息,而 Docker 没有权限获取此信息,启动时日志中会报告上述异常。需在
docker run
添加如下启动参数:
-v /etc:/dolphindb/etc
报错信息如下
docker: Error response from daemon: driver failed programming external connectivity on endpoint dolphindb (178a842284d64fbe128ff3f1188ead76ef4072c9149226f8bf62dc7795a58603): Error starting userland proxy: listen tcp4 0.0.0.0:8848: bind: address already in use.
解决方案:更换宿主机的端口号,或用如下命令查看端口号占用情况:
lsof -i:8848
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
dolphindb 17238 root 6u IPv4 231927135 0t0 TCP *:8848 (LISTEN)
FILE:references/doc_5480.md
# cdfF
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfF.html
**来源**: DolphinDB 官方文档
---
cdfF
语法
cdfF(numeratorDF, denominatorDF, X)
详情
返回 F 分布的累计密度函数的值。
参数
numeratorDF
和
denominatorDF
都是正数,表示 F 分布的自由度。
X
是数值型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfF(2.31, 0.627, [0.001, 0.5, 0.999]);
// output
[0.000444, 0.245679, 0.35098]
cdfF(2.31,0.627, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output
[0.07078, 0.176153, 0.245679, 0.295996, 0.334766]
FILE:references/doc_549.md
# grant
**URL**: https://docs.dolphindb.cn/zh/funcs/g/grant.html
**来源**: DolphinDB 官方文档
---
grant
语法
grant(userId|groupId, accessType, [objs])
详情
grant
函数用于授予某个用户或用户组指定权限,包括:
管理员可通过该命令授予用户或用户组所有权限(任意
accessType
)。
普通用户仅在拥有相关对象的 OWNER 权限时,才能授予以下权限:
TABLE_READ, TABLE_WRITE, TABLE_INSERT,
TABLE_UPDATE, TABLE_DELETE, DB_READ, DB_WRITE, DB_INSERT, DB_UPDATE,
DB_DELETE, DBOBJ_DELETE, DBOBJ_CREATE, VIEW_EXEC。
accessType
= DB_OWNER 支持通过
objs
指定一个或多个数据库名前缀,用于限制用户可创建和管理的数据库。多个前缀规则可通过向量传递。若用户已获得全局 DB_OWNER
权限,则该前缀规则无效。规则之间互不覆盖,除非某规则包含另一个。可通过
getUserAccess
函数查看用户已授权的前缀规则。
权限判定逻辑如下:
若用户全局权限被拒绝,则禁止创建和管理数据库操作;
否则,只要数据库名称匹配任一前缀规则,操作即被允许。
注意:
前缀规则仅支持通过
grant
和
revoke
进行授权和撤销,不能用
deny
拒绝;
DB_OWNER 权限仅在全局范围生效,前缀规则覆盖先前定义的规则。
查询内存限制权限
QUERY_RESULT_MEM_LIMIT:约束用户查询返回结果的内存上限;
TASK_GROUP_MEM_LIMIT:约束用户发送的批量子查询占用的内存上限。
这两项权限功能等同于
setMemLimitOfQueryResult
和
setMemLimitOfTaskGroupResult
,但仅针对指定用户生效,不支持用户组。
accessType
= CREATE_SHARED_VAR
该权限用于限制用户创建共享变量的能力,仅在系统参数
enableSharedVarCreationControl
= true
时生效。该权限为全局权限,不支持通过对象(
objs
)进行细分控制。
默认情况下:
admin 用户具备该权限;
guest 用户及新建用户普通用户不具备,需显式授权;新建的管理员用户也不具备,但可以为自己显式授权。
若配置项为 false,系统不启用权限校验,所有用户均可创建共享变量(即权限设置存在但不生效)。
参数
userId
|
groupId
是表示用户名或组名的字符串。
accessType
权限类型/内存限制。
objs
标量或向量,表示权限类型的应用对象/约束规则。也可以指定为 *,表示全局。
当
accessType
指定为 COMPUTE_GROUP_EXEC 时,
objs
必须为对应的计算组名。
注:
管理共享内存表、流数据表或流计算引擎的权限时,
objs
必须为 "tableName@nodeAlias"
或"nodeAlias:tableName"。
管理 IMOLTP 引擎库表权限时,
objs
必须为 "oltp://database/table@nodeAlias" 或
"oltp://database@nodeAlias"。
accessType
和
objs
的取值请参照
用户权限管理
权限类型表。
返回值
无。
例子
授予组 "research" 的所有成员读取所有数据库表的权限:
grant(`research, TABLE_READ, "*")
授予组 "research" 的所有成员读写表
dfs://db1/t1
的权限:
grant(`research, TABLE_WRITE, "dfs://db1/t1")
授予组 "research" 的所有成员在数据库
dfs://db1
和
dfs://db2
创建表的权限:
grant("research", DBOBJ_CREATE, ["dfs://db1","dfs://db2"])
授予用户 "AlexSmith" 删除数据库的权限:
grant("AlexSmith", DB_MANAGE)
授予用户"AlexSmith"执行脚本的权限:
grant("AlexSmith", SCRIPT_EXEC)
授予用户 "AlexSmith" 测试脚本的权限:
grant("AlexSmith", TEST_EXEC)
授予用户”AlexSmith”命名空间 test1下函数 f1 的执行权限:
grant("AlexSmith", VIEW_EXEC, "test1::f1")
授予用户”AlexSmith”命名空间 test2 下所有函数的执行权限:
grant("AlexSmith", VIEW_EXEC, "test2::*")
命名空间必须是模块级别。例如有一个模块
test.dos
,所在路径为
moduleDir/mod1/test.dos
,为用户授权执行模块中所有函数时,应通过以下脚本实现:
grant("AlexSmith", VIEW_EXEC, "mod1::test::*")
不支持写成:
grant("AlexSmith", VIEW_EXEC, "mod1::*")
如果授权了某个命名空间,后来命名空间中的函数视图被通过
dropFunctionView
删除,一旦命名空间中的最后一个函数视图被删除,对该命名空间的授权也将自动回收。同理,授权时如果发现该命名空间下没有函数视图,会抛出异常。
对于没有命名空间的函数视图,被认为是全局的。以下两种方式等价:
grant("AlexSmith", VIEW_EXEC, "::f")
grant("AlexSmith", VIEW_EXEC, f)
约束用户查询所占用的内存:
指定
accessType
为 QUERY_RESULT_MEM_LIMIT,此时
objs
表示限制的内存大小,单位为 GB。下述脚本限制用户 "AlexSmith" 查询时,查询结果所占用的内存大小不能超过 4 GB。
grant("AlexSmith", QUERY_RESULT_MEM_LIMIT, 4)
约束用户只能创建指定前缀的数据库:
假设管理员要求限制用户 "AlexSmith" 只能创建并管理以 ddb 作为库名前缀的数据库,可以通过以下脚本实现:
grant("AlexSmith", DB_OWNER, "dfs://ddb*")
当指定
grant
函数的
accessType
为 DB_OWNER 时,可以指定
objs
为一个规则,目前仅支持约束用户可以创建的库名前缀,便于不同用户管理不同范围的数据库。
当需要指定多个规则时,可以为 objs 传入一个向量,如下脚本所示:
grant("AlexSmith", DB_OWNER, ["dfs://ddb_prefix1*","dfs://ddb_prefix2*"])
授权时,如果当前已有全局授权,则对某一前缀规则的授权将无效。如果前缀规则之间存在包含关系,则这些规则不会相互覆盖。
当用户创建或管理数据库时,如有全局禁止,则禁止执行,否则,用户的权限为所有前缀规则的并集,即如果库名符合已授权的任一前缀规则,则允许执行。已授权的前缀规则可以通过函数
getUserAccess
查看。
注:
特定的前缀约束规则,只能通过
grant
指定、通过
revoke
移除,但不能通过
deny
禁止。当
accessType
为
DB_OWNER 时,
deny
只能对全局生效,且会覆盖之前已有的前缀约束规则。
FILE:references/doc_55.md
# isQuarterEnd
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isQuarterEnd.html
**来源**: DolphinDB 官方文档
---
isQuarterEnd
语法
isQuarterEnd(X)
详情
判断
X
是否为季度最后一天。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
返回值
布尔标量或向量。
例子
isQuarterEnd(2012.06.30);
// output: true
isQuarterEnd([2012.06.30,2012.07.01]);
// output: [true,false]
相关函数:
isQuarterStart
FILE:references/doc_550.md
# time
**URL**: https://docs.dolphindb.cn/zh/funcs/t/time.html
**来源**: DolphinDB 官方文档
---
time
语法
time(X)
详情
返回毫秒精度时间。
参数
X
是一个时间标量/向量。
返回值
TIME 类型标量或向量。
例子
time();
返回:null
time(1)
返回:00:00:00.001
time("12:32:56.356");
返回:12:32:56.356
time(now());
返回:16:03:36.529
FILE:references/doc_5501.md
# getMemLimitOfAllTempResults
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getmemlimitofalltempresults.html
**来源**: DolphinDB 官方文档
---
getMemLimitOfAllTempResults
语法
getMemLimitOfAllTempResults()
详情
获取分布式查询操作(例如表连接、GROUP BY、CONTEXT BY、PIVOT BY)产生的临时表可以占用的内存上限。
参数
无
返回值
DOUBLE 类型标量。
例子
getMemLimitOfAllTempResults()
// output: 3.0
相关函数:
setMemLimitOfAllTempResults
FILE:references/doc_5502.md
# refCount
**URL**: https://docs.dolphindb.cn/zh/funcs/r/refCount.html
**来源**: DolphinDB 官方文档
---
refCount
语法
refCount(varname)
详情
计算某个对象被引用的数量。
参数
varname
是一个字符串,表示变量名称。
返回值
INT 类型标量。
例子
db=database("",VALUE,1 2 3)
refCount(`db);
// output
1
db1=db
db2=db
refCount(`db);
// output
3
FILE:references/doc_5522.md
# clip
**URL**: https://docs.dolphindb.cn/zh/funcs/c/clip.html
**来源**: DolphinDB 官方文档
---
clip
语法
clip(X,Y,Z)
详情
返回一个与 X 数据形式和数据类型完全相同的 X'。
X' 的值满足以下规则(当 X 为字典时,下述"X'的元素"表示字典 X' 的 value):
当 Y 和 Z 为标量时,X' 的元素被限制在 [Y, Z] 区间内:
1.1 Y 或 Z 为 NULL 表示对区间下界或上界不做限制。
1.2 若 Y 大于 Z,则 X' 中所有元素设为 Z。
1.3 对于 X 中落在 [Y, Z] 范围内的元素,其在 X' 中保留原值;对于超出该范围的元素,X'
中相应位置的值将被替换为最近的边界值,即小于 Y 的元素被设为 Y,大于 Z 的元素被设为 Z。
当 Y 和 Z 为向量、矩阵或表时,对 X 中每个元素 x,根据相应位置的 [y, z] 组成的范围进行限制:
2.1 超出该范围的 x 依然按照上述规则进行处理。
2.2 若 Y 或 Z 某个位置元素为 NULL,则 X' 对应位置元素也为 NULL。
2.3 若 Y 或 Z 某个位置元素满足 y >z,则 X' 对应位置元素设为 z。
当 Y 或 Z 其中之一为标量,另一个为向量、矩阵或表时:
3.1 标量值代表区间下界或上界固定,向量、矩阵或表中的元素代表不同位置的限制区间的下界或上界。
3.2 标量值为 NULL 表示对下界或上界不做限制,向量、矩阵或表的某一元素为 NULL 代表将 X‘ 对应位置元素设置为空值。
3.3 某个位置元素满足 y >z,则 X' 对应位置元素设为 z。
参数
X
是一个数值型或时间类型的标量、向量、矩阵、表或 value 为数值型或时间类型的字典。
Y
是一个数值型或时间类型的标量、向量、矩阵或表。
Z
是一个数值型或时间类型的标量、向量、矩阵或表。
X
,
Y
,
Z
数据类型必须匹配:
若
X
为整型,
Y
、
Z
必须为整型。
若
X
为浮点型或 DECIMAL,
Y
、
Z
可以为整型、浮点型或 DECIMAL 类型。
若
X
为时间类型,
Y
、
Z
必须为同类型的时间类型。
X, Y, Z 的数据形式须满足以下要求:
当
X
是标量或字典时,
Y
和
Z
必须为标量。
当
X
是向量时,
Y
和
Z
可以是标量或与
X
维度相同的向量。
当
X
是矩阵时,
Y
和
Z
可以是标量或与
X
维度相同的矩阵。
当
X
是表时,
Y
和
Z
可以是标量或与
X
维度相同的表。
返回值
返回一个与输入
X
相同数据类型和形式的对象。
例子
Y 和 Z 是标量
Y = NULL ,Z = 5 ,根据规则1.1,表示不限制下界,上界为 5,此时仅将表中大于 5 的值置为
5。
X = table(1..10 as val1, 10..1 as val2)
Y = NULL
Z = 5
clip(X,Y,Z)
val1
val2
1
5
2
5
3
5
4
5
5
5
5
5
5
4
5
3
5
2
5
1
Y 大于 Z (6>3),根据规则1.2, X' 中所有元素被置为
3。
X = 1..10
Y = 6
Z = 3
clip(X,Y,Z)
// output:[3,3,3,3,3,3,3,3,3,3]
Y 和 Z 组成区间 [3,5],根据规则1.3,X’ 中 value
小于3的值(1和2)被置为3,大于5的值(6)被置为5,其他元素得到保留。
X = dict(`a`b`c`d`e`f,[1,2,3,4,5,6])
Y = 3
Z = 5
clip(X,Y,Z)
/*
output:
a->3
b->3
c->3
d->4
e->5
f->5
*/
Y 和 Z 是向量、矩阵或表
Y 和 Z 为与 X 维度相同的向量,用区间 [y[i], z[i]] 对 X[i] 进行限制:
X[0] 在 [Y[0],Z[0]] 区间内(1属于[0,3]),根据规则2.1,保留其值
X[3] 小于 Y[3](4<5),根据规则2.1,X'[3] 置为 5(Y[3])
X[9] 大于 Z[9](10>9),根据规则2.1,X'[9] 置为 9(Z[9])
Y[7] 和 Z[6] 为 NULL,根据规则2.2 ,X'[6] 和 X'[7] 为 NULL
Y[8] 大于 Z[8](7>5),根据规则2.3,X'[8] 置为 5(Z[8])
X = [1,2,3,4,5,6,7,8,9,10]
Y = [0,1,2,5,6,6,6,NULL,7,7]
Z = [3,4,5,6,7,8,NULL,5,5,9]
clip(X,Y,Z)
// output:[1,2,3,5,6,6,,,5,9]
Y 或 Z 其中之一为标量,另一个为向量、矩阵或表
下例中 Y 为 4,Z 为与 X 维度相同的矩阵,对 X 中元素 x[i,j],用区间 [4,Z[i,j]] 对其进行限制:
X[0,0] 小于 Y(1<4),根据规则3.1, X'[0,0] 置为 4
Z[0,2] 为 NULL,根据规则3.2,X'[0,2] 置为 NULL
Y 大于 Z[1,2](4>3),根据规则3.3, X'[1,2] 置为 3(Z[1,2])
X = 1..8$2:4
Y = 4
Z = [5,6,5,6,NULL,3,5,6]$2:4
clip(X,Y,Z)
// output:
#0 #1 #2 #3
-- -- -- --
4 4 5
4 4 3 6
FILE:references/doc_5523.md
# cdfNormal
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfNormal.html
**来源**: DolphinDB 官方文档
---
cdfNormal
语法
cdfNormal(mean, stdev, X)
详情
返回均值为
mean
,标准差为
stdev
的正态分布的累计密度函数的值。
参数
mean
是正态分布的均值。
stdev
是正态分布的标准差。
X
是数值型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfNormal(0,1,-2.33);
// output
0.009903
cdfNormal(10, 20, -30);
// output
0.02275
FILE:references/doc_5524.md
# 单节点部署与升级 (ARM)
**URL**: https://docs.dolphindb.cn/zh/tutorials/ARM_standalone_deploy.html
**来源**: DolphinDB 官方文档
---
单节点部署与升级 (ARM)
本教程用于嵌入式 ARM 版本的单节点部署、升级、过期 License 升级,并对常见问题做出解答,便于用户快速上手 DolphinDB 。包含以下主题:
系统要求
系统要求项
具体指标
操作系统
Linux(内核 3.10 及以上版本)
内存
2GB 及以上
Flash
8GB 及以上
支持的 ARM CPU
CORTEXA15/CORTEXA9/ARMV7/ARMV8/CORTEXA53/CORTEXA57/CORTEXA72/CORTEXA73/FALKOR/THUNDERX/THUNDERX2T99/TSV110
DolphinDB ARM 版使用的交叉编译器 32 位系统
arm-linux-gnueabihf4.9
DolphinDB ARM 版使用的交叉编译器 64 位系统
aarch64-linux-gnu_4.9.3
若用户在实际运行时出现问题,请反馈给我们:[email protected]。
部署 DolphinDB 单节点
第一步:下载
官方下载地址:https://dolphindb.cn/product#downloads
也可以通过 Shell 指令下载。下载方式如下:
wget https://www.dolphindb.cn/downloads/DolphinDB_ARM64_Vrelease.zip -O dolphindb.zip
其中,
release
代表版本。例如:下载 2.00.11.3 版本的 ARM64 server,使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_ARM64_V2.00.11.3.zip -O dolphindb.zip
以此类推。
执行以下 Shell 指令解压安装包至指定路径(
/path/to/directory
):
unzip dolphindb.zip -d </path/to/directory>
注意
: 安装路径的目录名中不能含有空格字符或中文字符,否则启动数据节点时会失败。
第二步:更新软件授权许可
如果用户拿到企业版试用授权许可,只需用其替换如下文件即可。
/DolphinDB/server/dolphindb.lic
如果用户没有申请企业版试用授权许可,可以直接使用程序包中的社区版试用授权许可。社区试用版指定 DolphinDB 单节点最大可用内存为 8GB,有效期为20年。
第三步:启动单节点
进入
/DolphinDB/server
目录,第一次启动时需要修改文件权限,执行以下 Shell 指令:
chmod +x dolphindb
由于嵌入式系统一般实际可使用内存较小,所以第一次启动时,建议根据实际环境修改与内存相关的配置参数。在
/DolphinDB/server
目录执行以下 Shell 指令编辑单节点配置文件:
vim dolphindb.cfg
系统默认端口号是8848。如果需要指定其它端口可以通过参数
localSite
设置,例如修改端口为8900:
localSite=localhost:8900:local8900
使用参数
maxMemSize
限制 DolphinDB 进程可用的最大内存,以 GB 为单位。建议根据实际内存大小设置,例如修改为 0.8GB:
maxMemSize=0.8
使用参数
regularArrayMemoryLimit
设置数组的内存限制,以 MB 为单位。该参数必须是2的指数幂,默认值512。建议根据实际内存大小设置,例如修改为 64MB:
regularArrayMemoryLimit=64
参数
maxLogSize
是指当日志文件达到指定大小时,系统会将日志文件存档,以 MB 为单位。默认值是1024,最小值是100。建议根据实际内存大小设置,例如修改为 100MB:
maxLogSize=100
前台运行
执行以下 Shell 指令:
./dolphindb
后台运行
执行以下 Shell 指令:
sh startSingle.sh
可以执行以下 Shell 指令,查看节点是否成功启动:
ps aux|grep dolphindb
返回如下信息说明后台启动成功:
第四步:Web 管理界面检查节点运行状态
在浏览器中输入部署服务器 IP 地址和部署端口号(默认是 8848)即可进入 Web 管理界面,教程中的部署服务器 IP 地址为10.0.0.82,部署端口为8848,所以访问地址为10.0.0.82:8848,打开后的 Web 管理界面如下:
注意
: 如果浏览器与 DolphinDB 不是部署在同一台服务器,需要关闭防火墙或者打开对应的部署端口,Web 管理界面才能正常打开。
单节点升级
第一步:正常关闭单节点
进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
./stopAllNode.sh
第二步:备份旧版本的元数据文件
单节点元数据的默认存储目录:
/DolphinDB/server/local8848/dfsMeta/
/DolphinDB/server/local8848/storage/CHUNK_METADATA/
可在
/DolphinDB/server
目录执行以下 Shell 指令备份单节点元数据:
mkdir backup
cp -r local8848/dfsMeta/ backup/dfsMeta
cp -r local8848/storage/CHUNK_METADATA/ backup/CHUNK_METADATA
注意
:元数据文件可能通过配置文件指定存储在其它目录,如果在默认路径没有找到上述文件,可以通过查询配置文件中的
dfsMetaDir
参数和
chunkMetaDir
参数
确认元数据文件的存储目录。若配置中未指定
dfsMetaDir
参数和
chunkMetaDir
参数,但是配置了
volumes
参数,
CHUNK_METADATA
目录在相应的
volumes
参数指定的目录下。
第三步:升级
注意
:当 server 升级到某个版本后,使用的插件也应升级到与此对应的版本。
下载所需升级版本的安装包,官方下载地址:
http://www.dolphindb.cn/downloads.html
。
将新版本
server
目录下除
dolphindb.cfg
以及
dolphindb.lic
外的所有文件覆盖替换旧版文件。
第四步:重新启动单节点
进入
/DolphinDB/server
目录执行以下 Shell 指令,后台运行 DolphinDB:
sh startSingle.sh
成功启动后,打开 Web 管理界面,在交互编程界面执行以下代码,查看 DolphinDB 当前版本:
version()
授权许可文件过期更新
第一步:替换授权许可文件
用新的授权许可文件
dolphindb.lic
替换旧的授权许可文件,授权许可文件位置如下:
/DolphinDB/server/dolphindb.lic
第二步:更新授权许可文件
在线更新
打开 Web 管理界面,在交互编程界面执行以下代码完成更新:
updateLicense()
注意
:在线更新有如下要求:
License 授权的客户名称必须与原来的 License 相同。
授权的节点个数,内存大小,CPU 核数不能比原来的小。
更新只在执行该函数的节点生效。因此在集群环境下,需要在所有控制节点、代理节点、计算节点和数据节点上运行该函数。
License 的类型必须是 commercial(付费)类型和 free 类型。
离线更新
关闭 DolphinDB,然后重新启动,即可完成更新。
常见问题解答(FAQ)
端口被其它程序占用导致启动失败怎么办?
DolphinDB 单节点默认启动端口是 8848,如果遇到无法启动 DolphinDB 的情况,建议打开
/DolphinDB/server
目录下的
dolphindb.log
日志文件,若出现如下错误:
<ERROR> :Failed to bind the socket on port 8848 with error code 98
说明选用的端口被其他程序占用,导致 DolphinDB 无法正常启动,修改配置文件中的端口为其它空闲端口后即可正常启动。
Web 管理界面无法访问怎么办?
DolphinDB 正常启动后,在浏览器输入正确的访问地址,但是 Web 管理界面无法正常打开,如下图所示:
出现上述问题的原因基本上都是因为浏览器与 DolphinDB 不是部署在同一台服务器,且部署 DolphinDB 的服务器开启了防火墙。可以通过关闭部署了 DolphinDB 的服务器的防火墙或者打开对应的部署端口,解决这个问题。
Linux 升级失败如何版本回退?
如果升级以后,不能正常开启单节点 DolphinDB ,可按以下方式回退到旧版本。
第一步:恢复旧版本元数据文件
在
/DolphinDB/server
目录执行以下 Shell 指令恢复已备份的单节点元数据:
cp -r backup/dfsMeta/ local8848/dfsMeta
cp -r backup/CHUNK_METADATA/ local8848/storage/CHUNK_METADATA
第二步:恢复旧版本程序文件
在官方下载旧版本程序包,把重新下载的旧版本
/DolphinDB/server
目录下除
dolphindb.cfg
以及
dolphindb.lic
外的所有文件覆盖替换升级失败的文件。
在线更新授权文件失败怎么办?
在线更新授权文件需要满足
更新授权许可文件
中在线更新的要求。如果不满足其中的要求,可以通过离线方式进行更新,或在 DolphinDB 官网申请企业版 License。
如何进行配置参数调优?
可以参考 DolphinDB 官方参数配置说明进行配置参数调优。
如果遇到性能问题,请添加微信号13306510479(仅用于添加微信)或扫描下面二维码,客服会邀您进群,我们的工程师会解答您的问题。
FILE:references/doc_5525.md
# dayOfWeek
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dayOfWeek.html
**来源**: DolphinDB 官方文档
---
dayOfWeek
语法
dayOfWeek(X)
详情
计算
X
是一个星期中的第几天。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
返回值
整数类型的标量或向量,范围为 0 到 6,0 表示星期一,1 表示星期二,...,6 表示星期日。
例子
dayOfWeek(2012.12.05);
// output
2
dayOfWeek 2013.05.23T12:00:00;
// output
3
dayOfWeek(2014.01.11T23:04:28.113);
// output
5
dayOfWeek(2012.12.05 2012.12.06 2013.01.05);
// output
[2,3,4]
FILE:references/doc_5528.md
# bitXor
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bitXor.html
**来源**: DolphinDB 官方文档
---
bitXor
语法
bitXor(X, Y)
或
X ^ Y
详情
返回位运算异或(
bitXOr
)的结果。
参数
X
和
Y
可以是数值型的标量,向量,矩阵,或数据表。
返回值
数值类型标量/向量/矩阵/表。
例子
x=1 0 1;
y= 0 1 1;
x^y;
// output
[1,1,0]
FILE:references/doc_5531.md
# rowPrev
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowPrev.html
**来源**: DolphinDB 官方文档
---
rowPrev
语法
rowPrev(X)
详情
逐行将
X
向右移动一个位置。
参数
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
。
返回值
返回一个数据类型和形式与
X
相同的对象。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL])
rowPrev(m)
返回:
col1
col2
col3
4.5
1.5
2.6
4.8
1.5
5.9
a=array(INT[], 0, 10).append!([1 2 3, 4 5, 6 7 8]);
rowPrev(a)
//output: [[00i,1,2],[00i,4],[00i,6,7]]
tp = [[1.3,2.5,2.3], [4.1,5.3,6.2]]
tp.setColumnarTuple!()
rowPrev(tp)
//output: [[00F,1.3,2.5],[00F,4.1,5.3]]
FILE:references/doc_5532.md
# toStdJson
**URL**: https://docs.dolphindb.cn/zh/funcs/t/toStdJson.html
**来源**: DolphinDB 官方文档
---
toStdJson
语法
toStdJson(obj)
详情
将 DolphinDB 对象转换为标准 JSON 类型。
转化 bool 值时,返回 true 或 false 值。
转换空值时,将除了 STRING 类型空值以外的其他所有类型空值都转换为null。
参数
obj
的数据形式不可为 matrix 或 pair;数据类型不可为
UUID, IPADDR, INT128, COMPRESSED 以及系统类型。
返回值
STRING 类型标量。
例子
x=1 2 3
toStdJson(x);
// output:
[1, 2, 3]
t=table(1 2 3 as id, 10 20 30 as val)
toStdJson(t);
// output:
[{"id": 1,"val": 10},{"id": 2,"val": 20},{"id": 3,"val": 30}]
b = set(2012.06.13T13:30:10 2017.07.10T14:10:12)
toStdJson(b);
// output:
["2017.07.10 14:10:12","2012.06.13 13:30:10"]
b = dict(INT,DATETIME)
b[0] = 2012.06.13 13:30:10
b[1] = 2017.07.10 14:10:12
toStdJson(b);
// output:
{"1": "2017.07.10 14:10:12","0": "2012.06.13 13:30:10"}
t1=table(`x`y`z as b, 2012.06.13 13:30:10 2012.06.13 13:30:10 2012.06.13 13:30:10 as c,10.8 7.6 3.5 as F)
toStdJson(t1);
// output:
[{"b": "x","c": "2012.06.13 13:30:10","F": 10.8},{"b": "y","c": "2012.06.13 13:30:10","F": 7.6},{"b": "z","c": "2012.06.13 13:30:10","F": 3.5}]
相关函数:
toJson
FILE:references/doc_5533.md
# eq
**URL**: https://docs.dolphindb.cn/zh/funcs/e/eq.html
**来源**: DolphinDB 官方文档
---
eq
语法
eq(X, Y)
或
X==Y
详情
如果
X
和
Y
都不是集合,返回逐个元素比较
X
==
Y
的结果。
如果
X
和
Y
都是集合,则检查
X
和
Y
是否是同一个集合。
参数
X
和
Y
可以是标量、数据对、向量、矩阵或集合。如果
X
或
Y
其中一个是数据对、向量或矩阵,另一个必须是标量,或具有相同长度或维度的数据对、向量或矩阵。
返回值
返回布尔类型,数据形式取决于
X
/
Y
。
例子
1 2 3 == 2;
// output
[0,1,0]
1 2 3==0 2 4;
// output
[0,1,0]
1:2==1:6;
// output
1 : 0
m1=1..6$2:3;
m1;
#0
#1
#2
1
3
5
2
4
6
m1 == 4;
#0
#1
#2
0
0
0
0
1
0
m2=6..1$2:3;
m2;
#0
#1
#2
6
4
2
5
3
1
m1==m2;
#0
#1
#2
0
0
0
0
0
0
集合操作:如果
X
==
Y
,则
X
和
Y
是同一个集合。
x=set(4 6)
y=set(4 6 8);
x==y;
// output
0
x==x;
// output
1
FILE:references/doc_5542.md
# truncate
**URL**: https://docs.dolphindb.cn/zh/funcs/t/truncate.html
**来源**: DolphinDB 官方文档
---
truncate
语法
truncate(dbUrl, tableName)
详情
删除分布式表的所有数据,但保留数据表结构。其性能较
delete
语句以及
dropPartition
命令均有数倍提升。
若仅需要删除表中所有的数据,但保留表结构,建议调用
truncate
实现。若无需保留表结构,建议调用
dropTable
命令。
参数
dbUrl
字符串,表示数据库的路径。
tableName
字符串,表示数据表的表名。
返回值
无。
例子
n=1000000
ID=rand(150, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x)
dbDate = database(, VALUE, 2017.08.07..2017.08.11)
dbID = database(, RANGE, 0 50 100 150)
dbName="dfs://compoDB"
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db = database(dbName, COMPO, [dbDate, dbID])
pt = db.createPartitionedTable(t, `pt, `date`ID)
pt.append!(t);
truncate(dbName, `pt)
FILE:references/doc_5546.md
# distinct
**URL**: https://docs.dolphindb.cn/zh/progr/sql/distinct.html
**来源**: DolphinDB 官方文档
---
distinct
添加在 select / exec 语句后,用于去除重复值并返回唯一值(distinct value)。支持在分布式查询中使用。
注:
distinct 关键字和 distinct 函数不同,后者不保证返回结果的顺序,且默认将结果列的列名重命名为
distinct_colName。
暂不支持 distinct 与 group by, context by 或 pivot by 配合使用。
语法
select distinct col1, col2, ...
from table
例子
t = table(`a`a`b`b`a`a`a`b as sym, 1 3 1 4 5 2 1 3 as id, 1..8 as value)
select distinct id from t
id
1
3
4
5
2
select distinct id, sym from t
id
sym
1
a
3
a
1
b
4
b
5
a
2
a
3
b
FILE:references/doc_5549.md
# rowMove
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowMove.html
**来源**: DolphinDB 官方文档
---
rowMove
语法
rowMove(X, steps)
详情
根据
steps
的设置,逐行移动元素。
参数
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
。
steps
是一个整数,表示移动多少位置。
如果
steps
为正数,
X
向右移动
steps
个位置;
如果
steps
为负数,
X
向左移动
steps
个位置;
如果
steps
为 0,不改变
X
的位置。
返回值
返回一个数据类型和形式与
X
相同的对象。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL])
rowMove(m, 2)
返回:
col1
col2
col3
4.5
2.6
1.5
rowMove(m, -2)
返回:
col1
col2
col3
4.9
2
a=array(INT[], 0, 10).append!([1 2 3, 4 5, 6 7 8]);
rowMove(a, 2)
//output: [[00i,00i,1],[00i,00i],[00i,00i,6]]
tp = [[1.3,2.5,2.3], [4.1,5.3,6.2]]
tp.setColumnarTuple!()
rowMove(tp, -2)
//output: [[2.3,00F,00F],[6.200000000000001,00F,00F]]
FILE:references/doc_556.md
# rpad
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rpad.html
**来源**: DolphinDB 官方文档
---
rpad
语法
rpad(str, length, [pattern])
详情
在字符串的右边填充特定字符串。
参数
str
是一个字符串或字符串向量。它表示目标字符串。
length
是一个不超过 65536 的非负整数。它表示返回字符串的长度。如果
length
小于
str
的长度,
rpad
会把
str
截断成长度为
length
的字符串。如果
length
大于 65536,则系统会自动调整为 65536。
pattern
是一个填充字符串。它是一个可选参数。如果没有指定,则在
str
的右边填充空格。
返回值
一个字符串或字符串向量。
例子
rpad("Hello",2);
// output
He
rpad(`Hello, 10);
// output
Hello
rpad(`Hello, 12, `0);
// output
Hello0000000
FILE:references/doc_5573.md
# rowBeta
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowBeta.html
**来源**: DolphinDB 官方文档
---
rowBeta
语法
rowBeta(Y, X)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行计算
Y
在
X
上的回归系数的最小二乘估计
返回值
返回一个长度与输入参数行数相同的向量。
例子
m1=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL])
m2=matrix(49.6 NULL 29.52, 50.32 51.29 26.23, NULL 74.97 23.75)
rowBeta(m1, m2)
// output
[-4.1667,-0.1182, -1.3374]
m3=matrix(8 NULL 10, 8 NULL 4, 14 NULL NULL)
rowBeta(m3, m2)
// output
[0, , 1.8237]
a= 110 112.3 44 98
b= 57.9 39 75 90
c= 55 64 37 78
x=array(DOUBLE[],0, 10).append!([a, b, c])
y=array(DOUBLE[],0, 10).append!([b, a, c])
rowBeta(x, y)
// output
[0.6783, 1 , -0.3202, 1]
相关函数:
beta
FILE:references/doc_5576.md
# 连接器 & API
**URL**: https://docs.dolphindb.cn/zh/api/connapi_intro.html
**来源**: DolphinDB 官方文档
---
连接器 & API
适用于130、200及更高版本系列的 Server。
DolphinDB 的 API 与连接器都有以下三个交互阶段:
连接
客户端发送报文
服务端返回报文
连接
连接阶段是客户端和服务端握手的阶段。客户端向服务器发送
connect
命令请求连接,服务端返回'OK',并且分配新的SessionID给客户端。
客户端发送连接请求
长度(Byte)
报文
说明
3
API
请求类型
1
空格
char(0x20)
1
0
SESSIONID
1
空格
char(0x20)
2
8
报文指令长度,固定字符串connect\n
1
换行符(LF)
char(0x10)
8
"connect\n"
固定字符串
服务端应答报文请求
长度(Byte)
报文
说明
不固定
例如'1195587396'
SESSIONID
1
空格
char(0x20)
1
0
返回对象数量
1
空格
char(0x20)
1
1
大小端,1-小端,0-大端
1
换行符(LF)
char(0x10)
不固定
执行结果
"OK"
指令交互
请求报文
| 请求类型 | 空格 | SESSIONID | 空格 | 报文指令长度 | 换行符(LF)
| 指令类型 | 换行符(LF)
| 指令参数 | 数据 |
应答报文
| SESSIONID | 空格 | 返回对象数量 | 空格 | 大小端 | 换行符(LF)
| 执行结果 | 换行符(LF)
会话
会话编号(session ID)代表终端与 DolphinDB 建立的一次 TCP 连接。终端通过
connect
连接成功后
DolphinDB 会返回一个新的 session ID,在此之后所有的报文交互都基于此 session ID进行,直到此连接被终端主动关闭。
如果请求报文的 session ID 为 0,或者服务器找不到指定的 session ID,服务器会创建并返回一个新的 session ID。
session ID 是一个随机的长整型。
请求类型
请求方式
说明
API
调用并返回结果,无进度信息返回。
API2
调用返回结果的同时,持续返回执行中脚本输出的信息。此方式仅支持 script 指令。
指令类型
DolphinDB database 支持以下三种指令类型:
script: 这种指令使用非常灵活,它以字符串形式发送脚本,服务器会返回脚本执行的结果。
function: 这种指令可以调用指定的函数,可以是内置函数或自定义函数。函数可以接受多个对象作为函数参数。
variable: 将客户端对象变量上传到服务器并指定其变量名。
Script
script 指令用来向 DolphinDB 发送脚本字符串,DolphinDB 执行脚本并返回执行结果。
表
1
.
请求报文格式
长度(Byte)
报文
说明
样本
3 或 4
请求类型
API,API2
API
1
空格
char(0x20)
不固定
SESSIONID
长度不固定,到空格为止
2247761467
1
空格
char(0x20)
2
报文指令长度
包含从“script"到脚本内容结束为止的长度,如"script\n1+1"
11
1
换行符
char(0x10)
7
指令
script
"script"
1
换行符
char(0x10)
不固定
脚本内容
长度到下一个换行符为止
select * from loadTable('dfs://db','tb1') 或 sum(1..100) +
avg(1..100)
表
2
.
响应报文格式
长度(Byte)
报文
说明
样本
不固定
MSG
如果请求类型为API2, 并且脚本中间有print等输出脚本,在返回报文包含MSG段
MSG"this is output message1"MSG"this is output
message2"
不固定
SESSIONID
长度不固定,到空格为止
2247761467
1
空格
char(0x20)
1
大小端
1-小端,0-大端
1
1
换行符(LF)
char(0x10)
1
执行成功否
返回文本OK表示执行成功
"OK"
1
换行符(LF)
char(0x10)
不固定
返回结果
数据格式参考第3节
function
function 指令用来向 DolphinDB 发送函数调用请求,DolphinDB 会执行指定函数并返回执行结果。
表
3
.
请求报文
长度(Byte)
报文
说明
样本
3
请求类型
API
API
1
空格
char(0x20)
不固定
SESSIONID
长度不固定,到空格为止
2247761467,638252939
1
空格
char(0x20)
2
报文指令长度
包含从“function"到大小端标志为止的长度,如"function\nsum\n1\n1"
16
1
换行符
char(0x10)
8
指令
function
"function"
1
换行符
char(0x10)
不固定
函数名称
长度到下一个换行符为止
sum
1
换行符
char(0x10)
1
参数数量
传递到函数的参数个数
1
1
换行符
char(0x10)
1
大小端标志
1-小端,0-大端
1
不固定
参数数据
数据格式参考第3节
表
4
.
响应报文格式
长度(Byte)
报文
说明
样本
3
SESSIONID
长度不固定,到空格为止
API
1
空格
char(0x20)
1
大小端
1-小端,0-大端
1
1
换行符(LF)
char(0x10)
1
执行成功否
返回文本OK表示执行成功
"OK"
1
换行符(LF)
char(0x10)
不固定
返回结果
数据格式参考第3节
variable
variable 指令用来向 DolphinDB 发送本地数据,DolphinDB 会在 server 端生成指定变量。
长度(Byte)
报文
说明
样本
3
请求类型
API
API
1
空格
char(0x20)
不固定
SESSIONID
长度不固定,到空格为止
2247761467
1
空格
char(0x20)
2
报文指令长度
包含从“variable"到大小端标志为止的长度,如"variable\na,b\n2\n1"
16
1
换行符
char(0x10)
8
指令
variable
"variable"
1
换行符
char(0x10)
不固定
变量名
多个变量通过","号分隔,字符串
a,b
1
换行符
char(0x10)
1
变量数量
传递到函数的变量个数
2
1
换行符
char(0x10)
1
大小端标志
1-小端,0-大端
1
不固定
变量数据
数据格式参考第3节
表
5
.
响应报文格式
占位(Byte)
报文
说明
样本
3
SESSIONID
长度不定,到空格为止
API
1
空格
char(0x20)
1
大小端
1-小端,0-大端
1
1
换行符(LF)
char(0x10)
1
执行成功否
返回文本OK表示执行成功
"OK"
行为标识
在 提交 script,function 报文时,在 "报文指令长度"
之后,增加"行为标识"报文来指示Server按照指定的要求来执行脚本或函数。
行为标识以字符串方式传输。每一个标识用下划线_分隔,整个字符串的含义如下:
标识名
标识范围
说明
样本
flag
(0,1,2,4,8,16)任意数字组的和
一组开关量标识,按位取值, 参考flag表格
4
cancellable
0,1
任务是否可以取消
1
priority
0~8
指定本任务优先级
8
parallelism
0~64
指定本任务并行度
8
rootId
整数
根任务编号,内部使用,API中固定为空
12
fetchSize
指定分块返回的块大小
10000
offset
API中固定为空
一个标准的行为标识字符串用"/ "开头,以换行符结束。如:"/ 4_1_8_8__10000\n"。
flag 的含义如下:
数位(从低位开始)
标识名
说明
0
isUrgent
是否紧急任务。即使系统繁忙,isUrgent=1的任务会通过紧急通道得以执行。
1
isSecondaryJob
API提交的任务,isSecondaryJob必须为0
2
isAsync
是否异步任务
3
isPickle
让服务端以picle协议返回数据,固定为0
4
isClearSessionMemory
本次任务完成后,是否释放 session 中创建的变量
5
isAPIClient
内部使用,固定为0
数据报文
数据格式
表
6
.
标量(DF_SCALAR)
报文字段
长度(Byte)
说明
DataType
1
数据类型
DataForm
1
数据形式
Data
不固定
数据
表
7
.
向量(DF_VECTOR)
报文字段
长度(Byte)
说明
DataForm
1
数据形式
DataType
1
数据类型
Rows
4
行数
Columns
4
列数,向量的columns是1
Data
不固定
数据
表
8
.
数据对(DF_PAIR)
报文字段
长度(Byte)
说明
DataForm
1
固定为2
DataType
1
数据类型
Rows
4
行数,固定为2
Columns
4
列数,固定为1
values
不固定
数据, 参照
向量
格式
表
9
.
矩阵(DF_MATRIX)
报文字段
长度(Byte)
说明
HasRowLabel
1bit
Byte中第一个bit, 0000 0001
HasColumnLabel
1bit
Byte中第二个bit,0000 0010
DataForm
1
数据形式
DataType
1
数据类型
RowLabels
不固定
行名称
ColumnsLabels
1
列名称
Rows
4
行数
Columns
4
列数
Data
不固定
数据
表
10
.
集合(DF_SET)
报文字段
长度(Byte)
说明
DataForm
1
固定为4
DataType
1
数据类型
Rows
4
行数
Columns
4
列数,固定为1
values
不固定
数据, 参照
向量
格式
表
11
.
字典(DF_DICTIONARY)
报文字段
长度(Byte)
说明
DataForm
1
固定为5
DataType
1
数据类型
Keys
不固定
键, 参照
向量
格式
values
不固定
值, 参照
向量
格式
表
12
.
表(Table)
报文字段
长度(Byte)
说明
DataForm
1
固定为6
DataType
1
数据类型
Rows
4
行数
Columns
4
列数
TableName
不固定
行名称
ColumnNames1
不固定
列名称1
ColumnNamesn
不固定
列名称n
VectorData1
不固定
列1数据, 参照
向量
格式
VectorDatan
不固定
列n数据, 参照
向量
格式
数据类型
API 使用基本的数据类型包括 Byte,Short,Int,Long,Float,Double,String 这几种,所有的日期和时间类型在系统内部都是用
INT 或者 LONG 来存储和传输数据。
数据类型
长度
说明
样例
BOOL
1
1b, 0b
true, false
CHAR
1
-2
7+1 ~ 2
7-1
'a', 97c
SHORT
2
-2
15+1 ~ 2
15-1
122h
INT
4
-2
31+1 ~ 2
31-1
22
LONG
8
-2
63+1 ~ 2
63-1
22l
DATE
4
INT
2013.06.13
MONTH
4
INT
2012.06M
TIME
4
INT
13:30:10.008
MINUTE
4
INT
13:30m
SECOND
4
INT
13:30:10
DATETIME
4
INT
2012.06.13 13:30:10 or 2012.06.13T13:30:10
TIMESTAMP
8
LONG
2012.06.13 13:30:10.008 or 2012.06.13T13:30:10.008
NANOTIME
8
LONG
13:30:10.008007006
NANOTIMESTAMP
8
LONG
2012.06.13 13:30:10.008007006 or
2012.06.13T13:30:10.008007006
FLOAT
4
2.1f
DOUBLE
8
2.1
STRING
不固定
采用UTF8编码,每个字符串用0做终止符
"String Hello World0"
附录:数据报文编码
表
13
.
数据类型(DataType)
数据类型
报文值
DT_VOID
0
DT_BOOL
1
DT_BYTE
2
DT_SHORT
3
DT_INT
4
DT_LONG
5
DT_DATE
6
DT_MONTH
7
DT_TIME
8
DT_MINUTE
9
DT_SECOND
10
DT_DATETIME
11
DT_TIMESTAMP
12
DT_NANOTIME
13
DT_NANOTIMESTAMP
14
DT_FLOAT
15
DT_DOUBLE
16
DT_SYMBOL
17
DT_STRING
18
DT_UUID
19
DT_FUNCTIONDEF
20
DT_HANDLE
21
DT_CODE
22
DT_DATASOURCE
23
DT_RESOURCE
24
DT_ANY
25
DT_DICTIONARY
26
DT_OBJECT
27
表
14
.
数据形式(DataForm)
数据形式
报文值
DF_SCALAR
0
DF_VECTOR
1
DF_PAIR
2
DF_MATRIX
3
DF_SET
4
DF_DICTIONARY
5
DF_TABLE
6
DF_CHART
7
DF_CHUNK
8
FILE:references/doc_5582.md
# maxDrawdown
**URL**: https://docs.dolphindb.cn/zh/funcs/m/maxdrawdown.html
**来源**: DolphinDB 官方文档
---
maxDrawdown
语法
maxDrawdown(X, [ratio=true])
聚合函数,别名
mdd
。
详情
计算传入向量数据的最大回撤(Maximum Drawdown,简称 MDD)或最大回撤率(Maximum Drawdown Rate)。
参数
X
数值向量,表示用于计算最大回撤的输入数据,一般指累积的收益或收益率。注意:不可为空。
ratio
布尔标量,表示是否返回最大回撤率。默认值为 true。
若为 true,表示返回最大回撤率,即相对于峰值的最大下降百分比,计算公式为:
若为 false,表示返回基于下降金额绝对值的最大回撤,计算公式为:
注意:计算时将忽略空值。
返回值
一个 DOUBLE 类型标量,表示
X
的最大回撤或最大回撤率。
例子
假设有一个投资组合在一段时间内的累积收益变化如下(以天为单位):
日期
累积收益
2024-10-01
36
2024-10-02
96
2024-10-03
42
2024-10-04
100
2024-10-05
59
2024-10-06
86
2024-10-07
25
2024-10-08
72
使用
maxDrawdown
计算该数据的最大回撤率和最大回撤。
x = [36,96,42,100,59,86,25,64,72]
maxDrawdown(x)
// Output: 0.75
maxDrawdown(x, false)
// Output: 75
相关函数:
cummdd
FILE:references/doc_5585.md
# getMemoryStat
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getMemoryStat.html
**来源**: DolphinDB 官方文档
---
getMemoryStat
语法
getMemoryStat()
详情
获取当前节点已分配的内存和未使用的内存。
参数
无
返回值
返回一个字典,其 key 值的含义为:
freeBytes:当前节点未使用的内存,单位为字节。
allocatedBytes:当前节点已分配的内存,单位为字节。
例子
getMemoryStat();
// output
freeBytes->6430128
allocatedBytes->35463168
FILE:references/doc_5593.md
# ksTest
**URL**: https://docs.dolphindb.cn/zh/funcs/k/ksTest.html
**来源**: DolphinDB 官方文档
---
ksTest
语法
ksTest(X, Y)
详情
对
X
和
Y
进行 Kolmogorov-Smirnov 检验,检验它们是否符合同一个分布。
参数
X
是一个数值向量。
Y
是一个数值向量。
返回值
返回一个字典,包含以下 key:
ksValue:Kolmogorov-Smirnov 统计量
pValue:p 值
D:D 统计量
method:字符串 "Two-sample Kolmogorov-Smirnov test"
例子
x = norm(0.0, 1.0, 50)
y = norm(0.0, 1.0, 20)
ksTest(x, y);
// output
ksValue->0.739301
pValue->0.645199
D->0.19
method->Two-sample Kolmogorov-Smirnov test
FILE:references/doc_5598.md
# getUsersByGroupId
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getUsersByGroupId.html
**来源**: DolphinDB 官方文档
---
getUsersByGroupId
语法
getUsersByGroupId(groupId)
详情
返回属于指定组的用户。
注:
该函数只能由管理员在控制节点、数据节点和计算节点运行。
参数
groupId
是表示组名的字符串。
返回值
字符串向量。
FILE:references/doc_56.md
# getPersistenceMeta
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getPersistenceMeta.html
**来源**: DolphinDB 官方文档
---
getPersistenceMeta
语法
getPersistenceMeta(table)
详情
查询启用了持久化的共享流数据表的元数据。
参数
table
是一个表。
返回值
返回一个字典,包含以下 key:
lastLogSeqNum:最新的 Raft 日志的逻辑序列号
sizeInMemory:内存中保留的记录数
asynWrite:持久化是否采用异步的方式
totalSize:流数据表中的总记录数
raftGroup:高可用流数据表所属 Raft 组的 ID。对于普通的流数据表,该值为-1
compress:是否采用压缩存储
memoryOffset:当前内存中数据相对总记录数的偏移量,memoryOffset = totalSize - sizeInMemory
sizeOnDisk:已经持久化到磁盘的记录数
retentionMinutes:日志文件的保留时间,默认值是1440分钟,即一天
persistenceDir:持久化路径
hashValue:对本表做持久化的工作线程标识,当配置项
persistenceWorkerNum>1时,hashValue 可能不为0
diskOffset:当前磁盘上数据相对总记录数的偏移量
例子
colName=["time","x"]
colType=["timestamp","int"]
t = streamTable(100:0, colName, colType);
enableTableShareAndPersistence(table=t, tableName=`st, cacheSize=1200000)
go;
for(s in 0:200){
n=10000
time=2019.01.01T00:00:00.000+s*n+1..n
x=rand(10.0, n)
insert into st values(time, x)
}
getPersistenceMeta(st);
// output
astLogSeqNum->-1
sizeInMemory->800000
asynWrite->true
totalSize->2000000
raftGroup->-1
compress->true
memoryOffset->1200000
retentionMinutes->1440
sizeOnDisk->2000000
persistenceDir->/dolphindb/server/streamPersistDir/st
hashValue->0
diskOffset->0
FILE:references/doc_560.md
# getSnapshotMsgId
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getSnapshotMsgId.html
**来源**: DolphinDB 官方文档
---
getSnapshotMsgId
语法
getSnapshotMsgId(engine)
详情
用于订阅断开后重新订阅时,获取指定流数据引擎的最近一个快照(snapshot)的 msgId。启用 snapshot
后,重订阅时,
subscribeTable
函数的
offset
参数设置为
getSnapshotMsgId(engine)+1,引擎会加载 snapshot,并从 getSnapshotMsgId(engine)
之后一条消息开始重新订阅。
参数
engine
是流数据引擎,即
createReactiveStateEngine
等函数返回的抽象表对象。
返回值
整型标量。
FILE:references/doc_5604.md
# getInstrumentCreditRating
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentcreditrating.html
**来源**: DolphinDB 官方文档
---
getInstrumentCreditRating
语法
getInstrumentCreditRating(instrument)
详情
根据输入的金融工具,获取该工具的信用评级(Credit Rating)。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
STRING 类型标量或向量。
例子
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "ZeroCouponBond",
"version": 0,
"instrumentId": "0001",
"start": 1996.03.01,
"maturity": 2032.05.15,
"dayCountConvention": "ActualActualISDA",
"coupon": 0.0276,
"issuePrice": 100.0,
"frequency": "Semiannual",
"subType":"TREASURY_BOND",
"creditRating":"B",
"settlement": 2022.05.15
}
ins = parseInstrument(bond)
getInstrumentCreditRating(ins)
// output: B
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_561.md
# rshift
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rshift.html
**来源**: DolphinDB 官方文档
---
rshift
语法
rshift(X, a)
或
X>>a
详情
rshift
将参数按位右移。
参数
X
可以是标量、数据对、向量或矩阵
a
是移动的位数。
返回值
数据形式和类型与 X 相同的对象。
例子
rshift(2048, 2);
// output
512
1..10 >> 1;
// output
[0,1,1,2,2,3,3,4,4,5]
1:10>>1;
// output
0 : 5
相关函数:
lshift
FILE:references/doc_5611.md
# getUnresolvedTxn
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getUnresolvedTxn.html
**来源**: DolphinDB 官方文档
---
getUnresolvedTxn
语法
getUnresolvedTxn()
详情
获取两阶段提交协议中处于决议状态的节点及其事务。只能由管理员在控制节点执行。
参数
无
返回值
返回一个表,包含以下字段:
tid:事务 id。
cid:提交的版本号。
chunkId:chunk 的唯一标识。
initiatingNode:事务决议的发起节点。
firstResolutionAt:事务开始决议的时间。
lastResolutionAt:若事务发生多次决议,则会显示最后一次决议的时间。
FILE:references/doc_5614.md
# 函数分类
**URL**: https://docs.dolphindb.cn/zh/funcs/funcs_by_topics.html
**来源**: DolphinDB 官方文档
---
函数分类
DolphinDB 的函数按照功能可以分为以下类别:
数据操作
数据类型与转换:
array
,
arrayVector
,
bigarray
,
blob
,
bool
,
cast
,
ceil
,
char
,
complex
,
date
,
datehour
,
datetime
,
decimal32
,
decimal64
,
decimal128
,
decimalFormat
,
decimalMultiply
,
deg2rad
,
dict
,
double
,
duration
,
enlist
,
fixedLengthArrayVector
,
floor
,
form
,
format
,
fromJson
,
fromStdJson
,
hex
,
highDouble
,
highLong
,
indexedSeries
,
int
,
int128
,
ipaddr
,
isIndexedMatrix
,
isIndexedSeries
,
isOrderedDict
,
jsonExtract
,
long
,
lowDouble
,
lowLong
,
makeKey
,
makeSortedKey
,
matrix
,
minute
,
month
,
nanotime
,
nanotimestamp
,
pair
,
parseInt
,
parseInteger
,
parsejsonTable
,
point
,
rad2deg
,
reverse
,
round
,
second
,
seq
,
set
,
setIndexedMatrix!
,
setIndexedSeries!
,
short
,
string
,
subtuple
,
symbol
,
symbolCode
,
syncDict
,
temporalFormat
,
temporalParse
,
tensor
,
time
,
timestamp
,
toJson
,
toStdJson
,
transpose
/
flip
,
type
,
typestr
,
uuid
生成:
eye
,
panel
,
rollingPanel
,
seq
,
stretch
,
take
,
til
追加:
append!
/
push!
,
appendTuple!
,
memberModify!
删除、清理:
clear!
,
drop
,
dropna
,
erase!
,
pop!
,
removeHead!
,
removeTail!
查找:
at
,
binsrch
,
cell
,
cells
,
col
,
eachAt(@)
,
find
,
first
,
firstHit
,
firstNot
,
head
,
ifirstHit
,
ifirstNot
,
ilastNot
,
last
,
lastNot
,
loc
,
milastNot
,
row
,
searchK
,
slice
,
sliceByKey
,
subarray
,
tail
排序:
denseRank
,
isort
,
isort!
,
isortTop
,
isSorted
,
rank
,
sort
,
sort!
,
sortBy!
空值查找、填充:
bfill!
,
ffill
,
ffill!
,
fill!
,
hasNull
,
ifNull
,
ifValid
,
interpolate
,
isNanInf
,
isNothing
,
isNull
,
isValid
,
isVoid
,
lfill
,
lfill!
,
nanInfFill
,
nullFill
,
nullFill!
替换:
replace
,
replace!
移动:
lshift
,
move
,
next
,
nextState
,
prev
,
prevState
,
rshift
合并:
concatMatrix
,
join
,
join!
,
merge
,
union
,
unionAll
分割:
cut
过滤:
conditionalFilter
对齐:
align
展开、重组:
flatten
,
regroup
,
reshape
,
shuffle
,
shuffle!
,
ungroup
分组:
bar
,
bucket
,
cutPoints
,
dailyAlignedBar
,
digitize
,
groups
,
segment
,
volumeBar
加载:
loadNpy
,
loadNpz
,
loadRecord
,
loadTable
,
loadText
,
loadTextEx
,
ploadText
编码转换:
base64Decode
,
base64Encode
,
compress
,
decodeShortGenomeSeq
,
decompress
,
encodeShortGenomeSeq
,
genShortGenomeSeq
,
oneHot
,
pack
,
rdp
,
unpack
累积窗口:
cumavg
,
cumbeta
,
cumcorr
,
cumcount
,
cumcovar
,
cumfirstNot
,
cumlastNot
,
cummax
,
cummed
,
cummin
,
cumnunique
,
cumpercentile
,
cumPositiveStreak
,
cumprod
,
cumrank
,
cumstd
,
cumstdp
,
cumsum
,
cumsum2
,
cumsum3
,
cumsum4
,
cumvar
,
cumvarp
,
cumwavg
,
cumwsum
,
dynamicGroupCumsum
,
dynamicGroupCumcount
m 系列:
mavg
,
mbeta
,
mcorr
,
mcount
,
mcovar
,
mfirst
,
mfirstNot
,
mifirstNot
,
milastNot
,
mimax
,
mimin
,
mkurtosis
,
mlast
,
mlastNot
,
mLowRange
,
mmad
,
mmax
,
mmaxPositiveStreak
,
mmed
,
mmin
,
mmse
,
movingTopNIndex
,
movingWindowIndex
,
mpercentile
,
mprod
,
mrank
,
mskew
,
mslr
,
mstd
,
mstdp
,
msum
,
msum2
,
mTopRange
,
mvar
,
mvarp
,
mwavg
,
mwsum
tm 系列:
tmavg
,
tmbeta
,
tmcorr
,
tmcount
,
tmcovar
,
tmfirst
,
tmkurtosis
,
tmlast
,
tmLowRange
,
tmmax
,
tmmed
,
tmmin
,
tmpercentile
,
tmprod
,
tmrank
,
tmskew
,
tmstd
,
tmstdp
,
tmsum
,
tmsum2
,
tmTopRange
,
tmvar
,
tmvarp
,
tmwavg
,
tmwsum
mTopN:
mavgTopN
,
mbetaTopN
,
mcorrTopN
,
mcovarTopN
,
mpercentileTopN
,
mstdpTopN
,
mstdTopN
,
msumTopN
,
mvarpTopN
,
mvarTopN
,
mwsumTopN
,
row 系列:
rowAlign
,
rowAnd
,
rowAt
,
rowAvg
,
rowBeta
,
rowCorr
,
rowCount
,
rowCovar
,
rowDenseRank
,
rowDot
,
rowEuclidean
,
rowGmd5
,
rowImax
,
rowImin
,
rowKurtosis
,
rowMax
,
rowMin
,
rowMove
,
rowNext
,
rowOr
,
rowPrev
,
rowProd
,
rowRank
,
rowSize
,
rowSkew
,
rowStd
,
rowStdp
,
rowSum
,
rowSum2
,
rowTanimoto
,
rowVar
,
rowVarp
,
rowWavg
,
rowWsum
,
rowXor
TA-lib 系列:
dema
,
ema
,
gema
,
kama
,
linearTimeTrend
,
ma
,
sma
,
t3
,
tema
,
trima
,
wilder
,
wma
字符串:
charAt
,
concat
,
convertEncode
,
crc32
,
endsWith
,
fromUTF8
,
gmd5
,
ilike
,
initcap
,
isAlNum
,
isAlpha
,
isDigit
,
isLower
,
isNumeric
,
isSpace
,
isTitle
,
isUpper
,
left
,
like
,
lower
,
lpad
,
ltrim
,
md5
,
regexCount
,
regexFind
,
regexFindStr
,
regexReplace
,
repeat
,
right
,
rpad
,
rtrim
,
split
,
startsWith
,
stringFormat
,
strip
,
strlen
,
strlenu
,
strpos
,
strReplace
,
substr
,
substru
,
toCharArray
,
toUTF8
,
trim
,
upper
时间处理:
addMarketHoliday
,
asFreq
,
businessDay
,
businessMonthBegin
,
businessMonthEnd
,
businessQuarterBegin
,
businessQuarterEnd
,
businessYearBegin
,
businessYearEnd
,
concatDateTime
,
convertTZ
,
date
,
dayOfMonth
,
dayOfWeek
,
dayOfYear
,
daysInMonth
,
fy5253
,
fy5253Quarter
,
getMarketCalendar
,
gmtime
,
hour
,
hourOfDay
,
isLeapYear
,
isMonthEnd
,
isMonthStart
,
isQuarterEnd
,
isQuarterStart
,
isYearEnd
,
isYearStart
,
lastWeekOfMonth
,
listAllMarkets
,
localtime
,
microsecond
,
millisecond
,
minuteOfHour
,
month
,
monthBegin
,
monthEnd
,
monthOfYear
,
nanosecond
,
now
,
quarterBegin
,
quarterEnd
,
secondOfMinute
,
semiannualBegin
,
semiannualEnd
,
semiMonthBegin
,
semiMonthEnd
,
temporalAdd
,
temporalDeltas
,
temporalDiff
,
temporalSeq
,
today
,
transFreq
,
updateMarketHoliday
,
weekBegin
,
weekday
,
weekEnd
,
weekOfMonth
,
weekOfYear
,
year
,
yearBegin
,
yearEnd
数据库/数据表
库表操作:
addColumn
,
addFunctionView
,
addRangePartitions
,
addValuePartitions
,
backup
,
backupDB
,
backupTable
,
cacheDS!
,
cacheDSNow
,
cachedTable
,
checkBackup
,
clearAllTSDBSymbolBaseCache
,
clearDSCache!
,
clearDSCacheNow
,
columnNames
,
createDimensionTable
,
createDistributedInMemoryTable
,
createIPCInMemoryTable
,
createPartitionedTable
,
createTable
,
database
,
disableActivePartition
,
disableQueryMonitor
,
disableTSDBAsyncSorting
,
dropColumns!
,
dropDatabase
,
dropDistributedInMemoryTable
,
dropFunctionView
,
dropIPCInMemoryTable
,
dropPartition
,
dropTable
,
enableActivePartition
,
enableQueryMonitor
,
enableTSDBAsyncSorting
,
existsDatabase
,
existsPartition
,
existsTable
,
extractTextSchema
,
flushOLAPCache
,
flushTSDBCache
,
getAllDBGranularity
,
getAllDBs
,
getBackupList
,
getBackupMeta
,
getBackupStatus
,
getChunkPath
,
getChunksMeta
,
getClusterChunksStatus
,
getClusterDFSDatabases
,
getClusterDFSTables
,
getClusterVolumeUsage
,
getConfigure
/
getConfig
,
getDFSDatabases
,
getDFSDatabasesByOwner
,
getDFSTablesByDatabase
,
getFunctionViews
,
getLevelFileIndexCacheStatus
,
getLocalIOTDBStaticTable
,
getMemLimitOfQueryResult
,
getMemLimitOfTaskGroupResult
,
getOLAPCacheEngineSize
,
getOLAPCacheEngineStat
,
getOLAPCachedSymbolBaseMemSize
,
getPKEYCompactionTaskStatus
,
getPKEYMetaData
,
getRecoveryTaskStatus
,
getRecoveryWorkerNum
,
getRedoLogGCStat
,
getTables
,
getTablet
,
getTabletsMeta
,
getTransactionStatus
,
getTSDBCachedSymbolBaseMemSize
,
getTSDBCacheEngineSize
,
getTSDBCompactionTaskStatus
,
getTSDBMetaData
,
getUnresolvedTxn
,
imr
,
indexedTable
,
keyedTable
,
latestIndexedTable
,
latestKeyedStreamTable
,
latestKeyedTable
,
loadBackup
,
loadDistributedInMemoryTable
,
loadIPCInMemoryTable
,
loadMvccTable
,
loadTableBySQL
,
migrate
,
mr
,
multiTableRepartitionDS
,
mvccTable
,
purgeCacheEngine
,
rename!
,
renameTable
,
reorderColumns!
,
repartitionDS
,
replaceColumn!
,
replay
,
replayDS
,
resetRecoveryWorkerNum
,
restore
,
restoreDB
,
restoreTable
,
rowNames
,
rowNo
,
saveDatabase
,
saveDualPartition
,
savePartition
,
saveTable
,
schema
,
setAtomicLevel
,
setChunkLastUpdateTime
,
setColumnComment
,
setMaxBlockSizeForReservedMemory
,
setMaxConnections
,
setMaxMemSize
,
setMemLimitOfQueryResult
,
setMemLimitOfTaskGroupResult
,
setMemLimitOfTempResult
,
setOLAPCacheEngineSize
,
setReservedMemSize
,
setTableComment
,
setTSDBCacheEngineSize
,
sqlDS
,
table
,
tableInsert
,
tableUpsert
,
textChunkDS
,
transDS!
,
triggerTSDBCompaction
,
truncate
,
tupleSum
,
update!
,
upsert!
catalog相关操作:
createCatalog
,
createSchema
,
dropCatalog
,
dropSchema
,
existsCatalog
,
getAllCatalogs
,
getCurrentCatalog
,
getSchemaByCatalog
,
renameCatalog
,
renameSchema
,
setDefaultCatalog
集群操作:
addNode
,
addVolumes
,
cancelRecoveryTask
,
copyReplicas
,
deleteReplicas
,
getActiveMaster
,
getActiveMaster
,
getConnections
,
getDatabaseClusterReplicationStatus
,
getMasterReplicationStatus
,
getNodeAlias
,
getNodeHost
,
getNodePort
,
getNodeType
,
getRecentSlaveReplicationInfo
,
getSlaveReplicationStatus
,
getSlaveReplicationQueueStatus
,
isControllerInitialized
,
isDataNodeInitialized
,
moveChunksAcrossVolume
,
moveReplicas
,
pnodeRun
,
rebalanceChunksAmongDataNodes
,
rebalanceChunksWithinDataNode
,
remoteRun
,
remoteRunCompatible
,
remoteRunWithCompression
,
removeNode
,
resetDBDirMeta
,
restoreDislocatedTablet
,
resumeRecovery
,
rpc
,
setDatabaseForClusterReplication
,
setTimeoutTick
,
skipClusterReplicationTask
,
startClusterReplication
,
startDataNode
,
stopClusterReplication
,
stopDataNode
,
suspendRecovery
,
triggerNodeReport
,
xdb
多集群操作:
getAllClusters
,
getCatalogsByCluster
,
getClusterStatus
,
getDatabasesByCluster
,
getGroupAccessByCluster
,
getGroupListOfAllClusters
,
getSchemasByCluster
,
getTableAccessByCluster
,
getTablesByCluster
,
getTablesOfAllClusters
,
getTableSchemaByCluster
,
getUserAccessByCluster
,
getUserListOfAllClusters
,
listPluginsByCluster
计算组相关操作:
clearComputeNodeCache
,
clearComputeNodeDiskCache
,
flushComputeNodeMemCache
,
getComputeGroupChunksStatus
,
getComputeNodeCacheDetails
,
getComputeNodeCacheStat
,
getComputeNodeCacheWarmupJobStatus
,
getComputeNodeCachingDelay
,
getPrefetchComputeNodeData
,
setComputeNodeCachingDelay
,
setPrefetchComputeNodeData
,
warmupComputeNodeCache
SQL
关键字:
alter
,
any/all
,
between
,
case
,
cgroup by
,
coalesce
,
context by
,
create
,
delete
,
distinct
,
drop
,
exec
,
exists
,
group by
,
having
, [
HINT_EXPLAIN
],
in
,
insert into
,
interval
,
is null
,
like/LIKE
,
limit
,
map
,
notBetween/NOTBETWEEN
,
notIn/NOTIN
,
notLike/NOTLIKE
,
nullIf
,
order by
,
partition
,
pivot by
,
sample
,
select
,
SQL Trace
,
top
,
union/union all
,
unpivot
,
update
,
where
,
with
表连接:
aj
,
cj
,
ej
,
fj
(full join),
inner join
,
lj
(left join),
lsj
(left semi join),
pj
,
pwj
,
right join
,
sej
,
wj
状态查看:
getCompletedQueries
,
getQueryStatus
,
getRunningQueries
,
getTraces
,
setTraceMode
,
viewTraceInfo
数学和统计
数学:
abs
,
acos
,
acosh
,
add
,
asin
,
asinh
,
atan
,
atanh
,
cbrt
,
clip
,
clip!
,
cos
,
cosh
,
cholesky
,
derivative
,
diag
,
div
,
det
,
eig
,
exp
,
exp2
,
expm1
,
gram
,
gramSchmidt
,
integral
,
inverse
,
intersection
,
iterate
,
log
,
log1p
,
log2
,
log10
,
lu
,
mod
,
mul
,
neg
,
pow
,
ratio
,
reciprocal
,
repmat
,
sin
,
sinh
,
sqrt
,
square
,
sub
,
symmetricDifference
,
svd
,
tan
,
tanh
,
tril
,
triu
,
schur
,
signbit
,
signum
,
qr
统计:
atImax
,
atImin
,
avg
,
boxcox
,
contextSum
,
contextSum2
,
count
,
covar
,
covarMatrix
,
crossStat
,
cubicHermiteSplineFit
,
cumnunique
,
demean
,
dot
,
ewmCov
,
ewmMean
,
ewmStd
,
ewmVar
,
gaussianKde
,
gaussianKdePredict
,
imax
,
imin
,
kurtosis
,
mad
,
max
,
maxIgnoreNull
,
med
,
mean
,
min
,
minIgnoreNull
,
mode
,
mmed
,
nunique
,
percentChange
,
percentile
,
percentileRank
,
prod
,
quantile
,
quantileSeries
,
rms
,
sem
,
skew
,
std
,
stdp
,
summary
,
sum
,
sum2
,
sum3
,
sum4
,
stat
,
var
,
varp
,
wavg
,
wc
,
wcovar
,
wsum
,
histogram2d
,
kroghInterpolateFit
,
linearInterpolateFit
相关性:
acf
,
autocorr
,
corr
,
corrMatrix
,
distance
,
ewmCorr
,
euclidean
,
kendall
,
mutualInfo
,
rowEuclidean
,
rowTanimoto
,
spearmanr
,
tanimoto
序列分析:
isMonotonicIncreasing
/
isMonotonic
,
isMonotonicDecreasing
,
isPeak
,
isValley
,
zigzag
分布与假设检验:
adfuller
,
anova
,
cdfBeta
,
cdfBinomial
,
cdfChiSquare
,
cdfExp
,
cdfF
,
cdfGamma
,
cdfKolmogorov
,
cdfLogistic
,
cdfNormal
,
cdfPoisson
,
cdfStudent
,
cdfUniform
,
cdfWeibull
,
cdfZipf
,
chiSquareTest
,
coint
,
esd
,
fTest
,
invBeta
,
invBinomial
,
invChiSquare
,
invExp
,
invF
,
invGamma
,
invLogistic
,
invNormal
,
invStudent
,
invPoisson
,
invUniform
,
invWeibull
,
ksTest
,
mannWhitneyUTest
,
manova
,
norm
/
normal
,
rand
,
randBeta
,
randBinomial
,
randChiSquare
,
randDiscrete
,
randExp
,
randF
,
randGamma
,
randLogistic
,
randMultivariateNormal
,
randNormal
,
randPoisson
,
randStudent
,
randUniform
,
randWeibull
,
seasonalEsd
,
shapiroTest
,
tTest
,
zTest
数据处理:
all
,
any
,
asis
,
asof
,
bucketCount
,
coevent
,
cols
,
deepCopy
,
copy
,
contextCount
,
countNanInf
,
cumPositiveStreak
,
deltas
,
dictUpdate!
,
distinct
,
dynamicGroupCumcount
,
dynamicGroupCumsum
,
hashBucket
,
iif
,
imaxLast
,
iminLast
,
isDuplicated
,
keys
,
linearTimeTrend
,
lowerBound
,
lowRange
,
mask
,
maxPositiveStreak
,
mimaxLast
,
miminLast
,
mmaxPositiveStreak
,
pca
,
ratios
,
resample
,
rowImaxLast
,
rowIminLast
,
rows
,
sessionWindow
,
shape
,
size
,
stl
,
sumbars
,
talibNull
,
tmove
,
topRange
,
valueChanged
,
values
,
winsorize!
,
winsorize
,
zscore
,
differentialEvolution
插值:
cubicSpline
,
cubicSplinePredict
,
dividedDifference
,
kroghInterpolate
,
loess
,
neville
,
pchipInterpolateFit
,
spline
,
splrep
,
splev
优化:
brute
,
brentq
,
fmin
,
fminBFGS
,
fminLBFGSB
,
fminNCG
,
fminSLSQP
,
linprog
,
osqp
,
qclp
,
quadprog
,
scs
,
solve
,
socp
运算符
逻辑:
and
,
bitAnd
,
bitOr
,
bitXor
,
not
,
or
,
xor
关系:
between
,
eq
,
eqFloat
,
eqObj
,
eqPercent
,
ge
,
gt
,
in
,
le
,
lt
,
ne
流数据
流表操作:
appendForJoin
,
appendMsg
,
clearTablePersistence
,
disableTablePersistence
,
dropStreamTable
,
enableTableCachePurge
,
enableTablePersistence
,
enableTableShareAndCachePurge
,
enableTableShareAndPersistence
,
existsStreamTable
,
existsSubscriptionTopic
,
getStreamTables
,
haStreamTable
,
keyedStreamTable
,
removeTopicOffset
,
setStreamTableFilterColumn
,
setStreamTableTimestamp
,
share
,
subscribeTable
,
unsubscribeTable
,
streamTable
计算引擎:
createAnomalyDetectionEngine
,
createAsofJoinEngine
,
createCrossSectionalEngine
,
createDailyTimeSeriesEngine
,
createDualOwnershipReactiveStateEngine
,
createEquiJoinEngine
/
createEqualJoinEngine
,
createLeftSemiJoinEngine
,
createLookupJoinEngine
,
createNarrowReactiveStateEngine
,
createOrderBookSnapshotEngine
,
createReactiveStateEngine
,
createRuleEngine
,
createSessionWindowEngine
,
createSnapshotJoinEngine
,
createStreamDispatchEngine
,
createTimeBucketEngine
,
createTimeSeriesEngine
,
createWindowJoinEngine
,
streamEngineParser
,
createCryptoOrderBookEngine
工具函数:
addMetrics
,
addReactiveMetrics
,
conditionalIterate
,
dropStreamEngine
/
dropAggregator
,
getComputeNodeCacheWarmupJobStatus
,
forceTriggerOrderBookSnapshot
,
getLeftStream
/
getRightStream
,
getPersistenceMeta
,
getReactiveMetrics
,
getSnapshotMsgId
,
getStreamEngine
/
getAggregator
,
getStreamEngineList
,
getStreamEngineStat
/
getAggregatorStat
,
getRules
,
getStreamingLeader
,
getStreamingRaftGroups
,
getStreamingStat
,
getStreamTableCacheOffset
,
getStreamTableFilterColumn
,
getSubscriptionTopic
,
getTopicProcessedOffset
,
stateIterate
,
warmupComputeNodeCache
,
warmupStreamEngine
流式 SQL:
declareStreamingSQLTable
,
getStreamingSQLStatus
,
listStreamingSQLTables
,
registerStreamingSQL
,
revokeStreamingSQL
,
revokeStreamingSQLTable
,
subscribeStreamingSQL
,
unsubscribeStreamingSQL
元编程
binaryExpr
,
eval
,
expr
,
funcByName
,
makeCall
,
makeUnifiedCall
,
parseExpr
,
sql
,
sqlCol
,
sqlColAlias
,
sqlDelete
,
sqlUpdate
,
unifiedExpr
高阶函数
accumulate (:A)
,
aggrTopN
,
all
,
any
,
byColumn (:V)
,
byRow (:H)
,
call
,
compose
,
contextby (:X)
,
cross (:C)
/
pcross
,
each (:E)
,
eachLeft (:L)
,
eachPost (:O)
,
eachPre (:P)
,
eachRight (:R)
,
groupby (:G)
,
loop (:U)
/
ploop
,
moving
,
nullCompare
,
pcall
,
pivot
,
reduce (:T)
,
rolling
,
rowGroupby
,
segmentby
,
talib
,
tmoving
,
twindow
,
unifiedCall
,
window
,
withNullFill
金融分析
金融分析:
amortizingFixedRateBondDirtyPrice
,
arima
,
nss
,
ns
,
condValueAtRisk
,
convertibleFixedRateBondDirtyPrice
,
nssPredict
,
trueRange
,
valueAtRisk
,
irs
,
varma
,
bondCashflow
,
bondYield
,
floatingRateBondDirtyPrice
,
treasuryConversionFactor
,
crmwCBond
,
cds
,
vanillaOption
,
maxDrawdown
,
mdd
,
cummdd
FICC:
bondAccrInt
,
bondCalculator
,
bondInstrumentCalculator
,
bondConvexity
,
bondDirtyPrice
,
bondDuration
,
,
bondFuturesPricer
,
bondPricer
,
bondYieldCurveBuilder
,
curvePredict
,
fxEuropeanOptionPricer
,
fxForwardPricer
,
fxSwapPricer
,
fxVolatilitySurfaceBuilder
,
instrumentPricer
,
irCrossCurrencyCurveBuilder
,
irDepositPricer
,
irFixedFloatingSwapPricer
,
irSingleCurrencyCurveBuilder
,
optionVolPredict
,
portfolioPricer
FICC 工具:
extractInstrument
,
extractMktData
,
parseInstrument
,
parseMktData
,
getInstrumentCalendar
,
getInstrumentCoupon
,
getInstrumentCreditRating
,
getInstrumentCurrency
,
getInstrumentCurrencyPair
,
getInstrumentDayCountConvention
,
getInstrumentDelivery
,
getInstrumentDirection
,
getInstrumentExpiry
,
getInstrumentFarDelivery
,
getInstrumentFarExpiry
,
getInstrumentFarStrike
,
getInstrumentField
,
getInstrumentFixedDayCountConvention
,
getInstrumentFixedRate
,
getInstrumentFloatingDayCountConvention
,
getInstrumentFrequency
,
getInstrumentIborIndex
,
getInstrumentInstrumentId
,
getInstrumentIssuePrice
,
getInstrumentKeys
,
getInstrumentMaturity
,
getInstrumentNearDelivery
,
getInstrumentNearExpiry
,
getInstrumentNearStrike
,
getInstrumentNominal
,
getInstrumentNominalCouponRate
,
getInstrumentNotional
,
getInstrumentPayReceive
,
getInstrumentPayoffType
,
getInstrumentRate
,
getInstrumentSettlement
,
getInstrumentSpread
,
getInstrumentStart
,
getInstrumentStrike
,
getInstrumentSubType
,
getInstrumentUnderlying
机器学习
机器学习:
adaBoostClassifier
,
adaBoostRegressor
,
beta
,
bvls
,
elasticNet
,
elasticNetCV
,
gaussianNB
,
glm
,
gmm
,
kernelRidge
,
kmeans
,
knn
,
lasso
,
lassoBasic
,
lassoCV
,
logisticRegression
,
mmse
,
msl
,
multinomialNB
,
ols
,
olsEx
,
piecewiseLinFit
,
poly1d
,
polyPredict
,
polyFit
,
polynomial
,
predict
,
pwlfPredict
,
randomForestClassifier
,
randomForestRegressor
,
residual
,
ridge
,
ridgeBasic
,
vectorAR
,
wls
,
garch
文本处理:
loadVocab
,
tokenizeBert
,
unloadVocab
权限与安全
addAccessControl
,
addGroupMember
,
backupSettings
,
changePwd
,
createGroup
,
createUser
,
deleteGroup
,
deleteGroupMember
,
deleteUser
,
deny
,
getAuthenticatedUsers
,
getGroupAccess
,
getGroupList
,
getGroupsByUserId
,
getOauthClientSecret
,
getUserAccess
,
getUserList
,
getUsersByGroupId
,
grant
,
isLoggedIn
,
login
,
logout
,
resetPwd
,
restoreSettings
,
revoke
,
scramClientFinal
,
scramClientFirst
,
unlockUser
文件系统
cleanOutdateLogFiles
,
close
,
exists
,
fflush
,
file
,
files
,
loadModel
,
mkdir
,
read!
,
readBytes
,
readLine
,
readLines
,
readLines!
,
readObject
,
readRecord!
,
rm
,
rmdir
,
saveAsNpy
,
saveModel
,
saveText
,
saveTextFile
,
seek
,
write
,
writeBytes
,
writeLine
,
writeLines
,
writeLog
,
writeLogLevel
,
writeObject
,
writeRecord
系统管理
cancelConsoleJob
,
cancelJob
,
closeSessions
,
defined
,
defs
,
deleteScheduledJob
,
disableResourceTracking
,
dumpHeapSample
,
enableResourceTracking
,
evalTimer
,
getAclAuditlog
,
getAuditLog
,
getClusterPerf
,
getConsoleJobs
,
getCurrentSessionAndUser
,
getDatanodeRestartInterval
,
getDynamicConfig
,
getIPConnectionLimit
,
getJobMessage
,
getJobReturn
,
getJobStat
,
getJobStatus
,
getLicenseExpiration
,
getMachineFingerprint
,
getMemLimitOfAllTempResults
,
getPerf
,
getRecentJobs
,
getScheduledJobs
,
getSessionMemoryStat
,
getSupportBundle
,
getTSDBDataStat
,
getTSDBTableIndexCacheStatus
,
getUserHardwareUsage
,
getUserTableAccessRecords
,
imtForceGCRedolog
,
imtUpdateChunkVersionOnDataNode
,
installPlugin
,
license
,
listRemotePlugins
,
loadModule
,
loadModuleFromScript
,
loadPlugin
,
member
,
module
,
objByName
,
objs
,
partial
,
pipeline
,
refCount
,
saveModule
,
scheduleJob
,
setDatanodeRestartInterval
,
setDynamicConfig
,
,
setLogLevel
,
setMaxJobParallelism
,
setMaxJobPriority
,
setMemLimitOfAllTempResults
,
setRandomSeed
,
setRetentionPolicy
,
setSystem
,
startHeapSample
,
stopHeapSample
,
submitJob
,
submitJobEx
,
submitJobEx2
,
syntax
,
timer
,
undef
,
updateLicense
,
use
,
version
,
getLoadedPlugins
MCP
addMCPPrompt
,
addMCPTool
,
callMCPTool
,
dropMCPPrompt
,
dropMCPTool
,
getMCPPrompt
,
listMCPPrompts
,
listMCPTools
,
publishMCPPrompts
,
publishMCPTools
,
updateMCPPrompt
,
updateMCPTool
,
withdrawMCPPrompts
,
withdrawMCPTools
环境
clearAllCache
,
clearCachedModules
,
getDiskIOStat
,
getEnv
,
getHomeDir
,
getMemoryStat
,
getOS
,
getOSBit
,
getSystemCpuUsage
,
getSystemLoadAvg
,
mem
,
moveHotDataToColdVolume
,
shell
,
sleep
,
clearAllIOTDBStaticTableCache
,
clearAllIOTDBLatestKeyCache
其它
attributeNames
,
attributeValues
,
,
constantDesc
,
convertExcelFormula
,
hmac
,
genericStateIterate
,
genericTStateIterate
,
objectChecksum
,
plot
,
plotHist
,
snippet
FILE:references/doc_5621.md
# getInstrumentDirection
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentdirection.html
**来源**: DolphinDB 官方文档
---
getInstrumentDirection
语法
getInstrumentDirection(instrument)
详情
根据输入的金融工具,获取该工具的交易方向。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
STRING 类型标量或向量。
例子
forward = {
"productType": "Forward",
"forwardType": "FxForward",
"version": 0,
"expiry": 2025.09.24,
"delivery": 2025.09.26,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E8],
"strike": 7.2
}
ins = parseInstrument(forward)
getInstrumentDirection(ins)
// output: Buy
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_5622.md
# string
**URL**: https://docs.dolphindb.cn/zh/funcs/s/string.html
**来源**: DolphinDB 官方文档
---
string
语法
string(X)
详情
将输入转化为一个字符串。
参数
X
可以是任何数据类型。
返回值
STRING 类型标量。
例子
string()==""; // 创建一个新的字符串,默认值为""。
返回:true
string(10);
返回:10
typestr string(108.5);
返回:STRING
string(now());
返回:2024.02.22T15:09:40.931
注:
以 字符串形式返回当前系统时间。
FILE:references/doc_5636.md
# mmse
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mmse.html
**来源**: DolphinDB 官方文档
---
mmse
语法
mmse(Y, X, window, [minPeriods])
详情
在给定长度(以元素个数衡量)的滑动窗口内,将因变量
Y
与自变量
X
进行普通最小二乘回归的系数估计并计算均方误差。计算公式如下:
参数
Y
是一个向量,表示因变量。
X
是一个向量,表示自变量。
window
是一个正整数,表示滑动窗口的长度。
minPeriods
是一个正整数。如果一个滑动窗口中的非 NULL 值的数量小于
minPeriods
,那么该窗口的结果为NULL。
返回值
返回一个包含两个向量的元组,第一个向量是普通最小二乘回归的系数估计,第二个向量是均方误差。
例子
x=0.011 0.006 -0.008 0.012 -0.016 -0.023 0.018
y=0.016 0.009 -0.012 0.022 0.003 -0.056 0.002;
mmse(y, x, 5)[0];
//output: [,,,,0.818182,1.692379,1.188532]
mmse(y, x, 5)[1];
//output: [,,,,0.000055,0.000231,0.000332]
select y, x, mmse(y,x,5,3) as `mbeta`mmse from table(x,y);
返回:
y
x
mbeta
mmse
0.016
0.011
0.009
0.006
-0.012
-0.008
1.479381
2.806415E-8
0.022
0.012
1.594701
0.000003
0.003
-0.016
0.818182
0.000055
-0.056
-0.023
1.692379
0.000231
0.002
0.018
1.188532
0.000332
FILE:references/doc_5642.md
# WorldQuant 101 Alpha 因子指标库
**URL**: https://docs.dolphindb.cn/zh/modules/wq101alpha/wq101alpha.html
**来源**: DolphinDB 官方文档
---
WorldQuant 101 Alpha 因子指标库
挖掘和计算 alpha 因子在量化金融领域有着重要的意义。在著名论文
101 Formulaic Alphas
中,作者给出了世界顶级量化对冲基金 WorldQuant 所使用的 101 个因子公式。为方便用户在 DolphinDB 中计算因子,本文使用 DolphinDB 脚本实现了所有101个因子的函数,并封装在 DolphinDB 模块
wq101alpha
(
wq101alpha.dos
) 中。
该模块的实现具有三大优势:
性能优越:性能远优于传统的 Python 实现方式。DolphinDB的性能中位数为Python的15.5倍,其中,27.5%的因子超100倍。
批流一体:模块中定义的因子函数,既可以用于历史计算,又可以用于流式增量计算。
实现简单:直接使用论文中所列公式实现,无需用户自定义函数,便于用户后续自行修改以产生定制化因子。
注意
:本教程包含的所有代码兼容 DolphinDB 2.00.8,1.30.20 及以上版本。
1. 函数的命名与入参规范
wq101alpha 模块 中的所有函数命名规则为WQAlpha + 因子序号, 如WQAlpha1,WQAlpha2。
每一个因子的入参字段有所不同,具体参考
附录1-因子入参一览表
。所有需要用到的输入字段如下:
参数名称 / 标准字段名称
参数含义
是否为行业信息字段
tradetime
交易时间
×
securityid
股票代码
×
open
开盘价
×
close
收盘价
×
high
最高价
×
low
最低价
×
vol
交易量
×
vwap
成交量加权平均价格
×
cap
市值
√
indclass
行业类型
√
由于包含行业信息的因子计算步骤与不含行业信息的因子有所不同,wq101alpha 模块 中根据入参字段是否包括行业信息字段,将因子分为了两类:行业信息因子和非行业信息因子:
因子类型
输入数据类型
输出数据类型
因子序号
行业信息因子
表
表
48,56,58,59,63,67,69,70,76,79,80,82,87,89,90,91,93,97,100
非行业信息因子
矩阵
矩阵
其余所有因子
2. 使用范例
本章节将通过环境配置、数据准备、计算调用方法等方面具体介绍 wq101alpha.dos 模块的具体用法。
2.1. 环境配置
把附件的 wq101alpha.dos 放在 [home]/modules 目录下,[home] 目录由系统配置参数 home 决定,可以通过
getHomeDir()
函数查看。
有关模块使用的更多细节,请参见:
DolphinDB 教程:模块
。
2.2. 数据准备
如若没有数据,可参考
日频数据及分钟频数据建库建表
生成模拟的日频数据 ;对于行业信息表的模拟数据生成,可参考
行业信息数据建库建表
。
如若已有数据,需保证现有的数据表中的字段名与模块中字段名一致,并将日频信息和行业信息做一个表连接。为方便使用,本教程准备了一个辅助模块
prepare101.dos
来帮助统一字段名。若要使用辅助模块,请将 prepare101.dos 放在 wq101alpha 模块 同一目录下。辅助模块中的prepareData函数的作用是将数据与标准字段的名称对齐,其中,rawData为非行业信息表,infoData为行业信息表,startTime与endTime 为需要的数据的起始时间和结束时间,其余参数为现有字段名与标准字段的对应名称:
注意
:如若用户采用的数据字段名与
输入字段
中的标准字段名一致,无需调用准备函数 prepareData 。
载入模块和数据方法如下,data 即为准备好的数据:
use wq101alpha
use prepare101
login('admin', '123456')
rawData = loadTable("dfs://k_day_level", "k_day")
infoData = select * from loadTable("dfs://info", "info_data")
startTime = timestamp(2010.01.01)
endTime = timestamp(2010.01.31)
data = prepareData(rawData=rawData, startTime=startTime, endTime=endTime, securityidName="securityid", tradetimeName="tradetime", openName="open", closeName="close", highName="high", lowName="low", volumeName="vol", vwapName="vwap", capName="cap", indclassName="indclass", infoData=infoData, infoSecurityidName="securityid")
2.3. 矩阵入参计算的非行业因子
在 wq101alpha 模块中,大多数因子计算都涉及横向与纵向的计算。对于这样的因子,用户需先准备矩阵,再调用对应的 WQAlpha# 函数,返回的结果为矩阵。由于不同因子计算时用到的参数不同,用户需通过查询
附录1-因子入参一览表
来确定所需的参数。
计算方法如下:
use wq101alpha
input1 = exec close from data where tradetime between startTime : endTime pivot by tradetime, securityid
res1 = WQAlpha1(input1)
input2 = dict(`vol`close`open, panel(data.tradetime, data.securityid, [data.vol, data.close, data.open]))
res2 = WQAlpha2(input2.vol, input2.close, input2.open)
为了更加便于用户计算,省去查询参数这一步骤,
因子计算准备函数模块 prepare101.dos
提供了所需的矩阵准备函数 prepare# 和计算函数 calAlpha#,用户可将其作为模块导入。prepare#的作用是调用对应模块计算函数所需要的字段,calAlpha#的作用是将prepare#以及wqAlpha#封装。
以world quant alpha 第 1 号因子为例,辅助准备模块内的函数如下:
def prepare1(data, startTime, endTime){
p = exec close from data where tradetime between startTime : endTime pivot by tradetime, securityid
return p
}
def calAlpha1(data, startTime, endTime){
input = prepare1(data, startTime, endTime)
return WQAlpha1(input)
}
//调用方法如下:
use prepare101
res = calAlpha1(data, startTime, endTime)
注意
:非行业因子中的41、54、101号因子除了可以用矩阵入参之外,也可以向量入参用 SQL 调用,如101号因子也可以这样调用:
use wq101alpha
res = select tradetime, securityid, `alpha101 as factorname, WQAlpha101(close, open, high, low) as val from data where tradetime between startTime : endTime
用户可以按需灵活选取调用方法。
2.4. 表入参计算行业信息因子
少部分因子涉及到了股票的行业分类信息。对于这些因子,用户需以表入参,返回的结果也为数据表。以 world quant alpha 第48 号因子为例:
use wq101alpha
res = WQAlpha48(data)
亦可使用
辅助准备模块 prepare101.dos
中的计算函数。
def calAlpha48(data, startTime, endTime){
input = select * from data where tradetime between startTime : endTime
return WQAlpha48(input)
}
//调用方法如下:
use prepare101
res = calAlpha48(data, startTime, endTime)
注意
:论文中用了多种行业分类,如IndClass.subindustry,IndClass.industry, IndClass.sector等,为了简便起见,本模块统一只用IndClass这一个字段做行业中性化。
3. 因子的存储
因子的存储可以参考
因子最佳实践中的因子存储章节
。wq101alpha 模块计算的因子返回的数据格式有矩阵及表两种形式,本章节将以宽表形式存储因子为例,完整代码可参考
Alpha101计算存储全流程代码汇总
。
3.1. 矩阵格式的因子存储
存储面板数据,需要先将面板数据转换为表,而后进行存储。以第 1 号因子为例,计算并存储因子,示例代码如下:
// 计算alpha 1号因子,得到的矩阵存储在res中
res = calAlpha1(data, startTime, endTime)
// 将res转换成表并存储在因子宽表中
writePanelInWideTable(res, `alpha1)
其中
writePanelInWideTable
的实现可见
Alpha101计算存储全流程代码汇总
。
3.2. 表形式的因子存储
wq101alpha
模块中返回的表为纵表,可以直接存入单值模型(纵表)。若要将其存入宽表,可以用
pivot by
将纵表重新排列(
tradetime
,
factorname
为行,
securityid
为列)。以第 101 号因子为例,代码如下:
// 计算world quant alpha 101号因子,得到的纵表存储在res中
res = calAlpha101(data, startTime, endTime)
// 将res转换成表并存储在因子宽表中
writeLongInWideTable(res)
其中
writeLongInWideTable
的实现可见
Alpha101计算存储全流程代码汇总
。
4. 性能对比
本章节将用 DolphinDB 实现的
wq101alpha
模块与 python 中用 pandas, numpy 模块实现的 WorldQuant alpha 因子分别对比计算性能。
本小节测试显示,DolphinDB 的 wq101alpha 模块的性能显著优于使用 python 的 pandas 与 numpy 模块的实现。
测试设备
CPU:Intel(R) Xeon(R) Silver 4216 CPU @ 2.10GHz
操作系统: 64 位 CentOS Linux 7 (Core)
使用数据
本节测试使用一年模拟日频数据进行性能对比
4.1. DolphinDB 与 Python Pandas 性能对比
本节用
一年模拟日频数据
对比了
wq101alpha
模块和
101因子的Pandas实现
计算101个因子的性能。
用
wq101alpha
模块中的函数计算并计时,核心代码如下,完整的脚本可参考
wq101alpha 模块性能测试
:
times = array(INT, 0)
defs()
for (i in 1:102){
if (i in passList) times.append!(NULL)
else{
print(i)
alphaName = exec name from defs() where name = "wq101alpha::WQAlpha"+string(i)
alphaSyntax = exec syntax from defs() where name = "wq101alpha::WQAlpha"+string(i)
function = alphaName + alphaSyntax
t1 = time(now())
res = parseExpr(function[0]).eval()
t2 = time(now())
times.append!(t2 - t1)
}
}
用 Python 脚本计算并计时,核心代码如下,完整的脚本可参考
Python alpha 101 性能测试
:
times = []
nofunc = [
48
,
56
,
58
,
59
,
63
,
67
,
69
,
70
,
76
,
79
,
80
,
82
,
87
,
89
,
90
,
91
,
93
,
97
,
100
]
for
i
in
range(
1
,
102
):
if
i
in
nofunc:
times.append(
'no function'
)
continue
else
:
factor = getattr(Alphas,
"alpha{:03d}"
.format(i))
try
:
t1 = time.time()
res = factor(stock)
t2 = time.time()
times.append(t2 - t1)
except
Exception:
times.append(
'error'
)
通过两个性能测试脚本,可得到
wq101alpha
模块和 Python 脚本计算101个因子的运行耗时,完整结果可见
性能对比结果
。筛除 Python 脚本中未实现的因子和实现有误的因子后,可供比较的因子共 69 个。对比结果见下表,单位为毫秒 ms。
因子ID#
DolphinDB
Python
耗时比(py/ddb)
ddbWin
因子ID#
DolphinDB
Python
耗时比(py/ddb)
ddbWin
1
86
68,837
800.43
true
38
91
89,487
983.38
true
2
229
2,117
9.24
true
40
73
2,379
32.59
true
3
140
2,018
14.41
true
41
84
11
0.13
false
4
75
89,440
1,192.53
true
42
97
218
2.25
true
5
120
600
5.
true
43
91
165,954
1,823.67
true
6
21
1,765
84.05
true
44
82
1,918
23.39
true
7
148
72,001
486.49
true
45
170
4,853
28.55
true
8
112
1,513
13.51
true
46
35
57
1.62
true
9
50
714
14.27
true
47
252
1,156
4.59
true
10
128
808
6.31
true
49
33
37
1.13
true
11
145
898
6.2
true
50
235
2,475
10.53
true
12
15
10
0.69
false
51
36
38
1.05
true
13
213
1,784
8.38
true
52
131
91,360
697.4
true
14
113
1,987
17.59
true
53
29
28
0.97
false
15
147
2,572
17.49
true
54
175
178
1.02
true
16
208
1,776
8.54
true
55
216
2,997
13.88
true
17
177
174,055
983.36
true
60
154
72,081
468.06
true
18
104
2,417
23.24
true
61
147
2,614
17.78
true
19
72
440
6.11
true
62
354
3,204
9.05
true
20
262
439
1.68
true
64
191
2,956
15.48
true
21
78
2,296
29.43
true
65
181
2,968
16.4
true
22
97
2,358
24.31
true
68
247
81,582
330.29
true
24
64
686
10.72
true
74
380
4,761
12.53
true
25
96
500
5.21
true
75
279
4,461
15.99
true
26
61
182,340
2,989.18
true
78
384
5,204
13.55
true
27
226
2,573
11.38
true
81
519
61,954
119.37
true
28
45
2,155
47.9
true
83
209
1,107
5.3
true
29
406
89,515
220.48
true
84
152
80,908
532.29
true
30
82
832
10.15
true
85
303
184,645
609.39
true
32
53
2,146
40.5
true
86
123
75,681
615.3
true
33
88
148
1.68
true
94
169
221,036
1,307.91
true
34
254
1,382
5.44
true
95
287
67,899
236.58
true
35
131
249,748
1,906.47
true
99
203
4,758
23.44
true
36
388
92,303
237.89
true
101
9
20
2.2
true
37
148
1,953
13.2
true
从上表结果可以看出,使用 DolphinDB 实现的
wq101alpha
模块的计算效率远远高于 Python 的实现。DolphinDB 的性能中位数为 Python 的15.5倍,其中,27.5%的因子超100倍。
其中因子41的实现,DolphinDB 慢于 Python。原因是 pow 函数的实现有些许不同。DolphinDB 会在后续版本中提升这个内置函数的性能。
4.2. DolphinDB 与 Python numpy 的性能对比
考虑到用 python pandas Dataframe 实现因子的计算性能效率可能不及 numpy ,为公平起见,本节抽取了11个 pandas 实现耗时特别久的因子,重新用 numpy 实现,具体代码见
部分101因子的numpy实现
。 DolphinDB 与 numpy 在实现这些因子的性能比较如下:
因子ID#
ddb
pandas
numpy
耗时比(pandas/ddb)
耗时比(numpy/ddb)
1
86
68,837
418
800.4
4.9
4
75
89,440
54,417
1,192.5
725.6
5
120
600
218
5.0
1.8
7
148
72,001
39,472
486.5
266.7
8
112
1,513
265
13.5
2.4
9
50
714
152
14.3
3.0
17
177
174,055
93,704
983.4
529.4
29
406
89,515
47,100
220.5
116.0
38
91
89,487
46,257
983.4
508.3
52
131
91,360
46,715
697.4
356.6
83
209
1,107
464
5.3
2.2
从结果上来看, numpy 的实现确实比 pandas dataframe 实现快一些,但是由于窗口函数 numpy 中是用
numpy.lib.stride_tricks.sliding_window_view
实现的,对于窗口计算没有优化,故性能并没有显著提升。
综合来看,DolphinDB 在实现 WorldQuant 101 alpha 因子上有非常大的优势,性能卓越。
5. 正确性验证
目前 python 101个alpha因子不存在统一的实现方式。本文基于
101因子的Python实现
中的实现方式,对部分报错代码进行调整(详情见
python模块代码
),与 wq101alpha 模块进行对比,部分验证了 wq101alpha 模块的正确性。由于在验证过程中发现诸多问题,该小节中将分类验证并探讨该模块实现方式与 Python 实现方式的不同。
验证所用的数据为一年模拟日频数据中的前十支股票。用
DolphinDB 验证脚本
在 DolphinDB 及
Python 验证脚本
在 python 中跑完因子后,截取第一支股票的数据做对比。
最后的验证步骤可参考
正确性验证脚本
。
5.1. 非行业因子验证
结果显示50%的因子DolphinDB与pandas计算结果一致。其余因子通过研究,发现
wq101alpha
模块与 Python pandas 实现有以下差异:
空值处理:
wq101alpha
模块中,对一个滚动 / 累积窗口长度为 k 的函数,每组最初的 (k-1) 个位置的结果均为空;Python 实现中,某些因子会默认将空值取0,某些因子不作改动。
Rank实现差异:如 alpha 4 号因子,在 DolphinDB 中的结果与 python 中的结果相差1,其原因是Rank的实现在 DolphinDB 中是从0开始排序,而在 python 中是从1开始排序。
结果不一致:经人工检验,Python 实现中存在一定错误。例如 Python 脚本计算 alpha 27 号因子的结果全为1,经检验为 Python 实现有错误。
5.2. 行业因子验证
该类因子目前少见 Python 实现,且因该模块中考虑到实际使用的便利性,已调整论文中的实现方式,故不作比较。
6. 实时流计算实现
World Quant 101 alpha 因子中大多数因子的实现方式都较为复杂,在流计算中,需要创建多个引擎进行流水线处理来完成。DolphinDB 提供了一个解析引擎
streamEngineParser
来代替人工创建并串联多个引擎,大大提高效率。
此功能从 DolphinDB 1.30.20 和 2.00.8 开始支持。
使用 wq101alpha 模块进行流计算时,因子的定义无需修改,直接在流引擎
streamEngineParser
中调用即可。
完整World Quant 101 alpha流计算流程代码可查看
WQ101alpha流计算全流程
。这里以 WQAlpha 1 为例,演示如何调用 wq101alpha 模块,实现流计算:
首先定义输入输出的表结构:
inputSchema = table(1:0, ["SecurityID","TradeTime","close"], [SYMBOL,TIMESTAMP,DOUBLE])
resultStream = table(10000:0, ["TradeTime", "SecurityID","factor"], [TIMESTAMP, SYMBOL,DOUBLE])
调用 wq101alpha 模块,并在
streamEngineParser
中使用 WQAlpha1 函数:
metrics = <[SecurityID,WQAlpha1(close)]>
streamEngine = streamEngineParser(name="WQAlpha1Parser", metrics=metrics, dummyTable=inputSchema, outputTable=resultStream, keyColumn="SecurityID", timeColumn=`tradetime, triggeringPattern='keyCount', triggeringInterval=4000)
部分因子可能会创建多个引擎,可以调用
getStreamEngineStat()
查看总共串联了哪些引擎:
getStreamEngineStat()
// output
ReactiveStreamEngine->
name user status lastErrMsg numGroups ...
------------- ----------- ------ ---------- --------- ...
WQAlpha1Parser0 admin OK 0 0
WQAlpha1Parser2 admin OK 0 0
CrossSectionalEngine->
name user status lastErrMsg numRows ...
--------------- ----- ------ ---------- ------- ...
WQAlpha1Parser1 admin OK 0 2
将数据注入引擎,即可在 resultStream 输出表中查看结果:
streamEngine.append!(data)
//check the result
res = exec factor from resultStream pivot by TradeTime, SecurityID
7. 小结
本教程详细介绍了
wq101alpha
模块的实现原理和用法。该模块用 DolphinDB 内置函数实现了 WorldQuant 101 alpha 因子,具有简单准确、高效快速、批流一体的特点。
8. 附录
8.1. 附录1-因子入参一览表
非行业信息因子
因子序号
所需参数
因子序号
所需参数
因子序号
所需参数
1, 9, 10, 19, 24, 29, 34, 46, 49, 51
close
23
high
71
vwap, vol, open, close, low
2, 14
vol, open, close
25, 47, 74
vwap, vol, close, high
72, 77
vwap, vol, high, low
3, 6
vol, open
27, 50, 61, 81
vwap, vol
73
vwap, open, low
4
low
28, 35, 55, 60, 68, 85
vol, high, low, close
75, 78
vwap, vol, low
5
vwap, open, close
31, 52
vol, close, low
83
vwap, vol, close, high, low
7, 12, 13, 17, 21, 30, 39, 43, 45
vol, close
32, 42, 57, 84
vwap, close
88, 92, 94
vol, open, close, high, low
8, 18, 33, 37, 38
open, close
36, 86
vwap, vol, open, close
95
vol, open, high, low
11, 96
vwap, vol, close
41
vwap, high, low
65, 98
vwap, vol, open
15, 16, 26, 40, 44
vol, high
53
close, high, low
99
vol, high, low
20, 54, 101
open, close, high, low
62, 64
vwap, vol, open, high, low
22
vol, high, close
66
vwap, open, high, low
行业信息因子
因子序号
所需参数
因子序号
所需参数
48
close, indclass
76, 89
vwap, vol, low, indclass
56
close, cap
80
vol, open, high, indclass
58, 59
vwap, vol, indclass
82
vol, open, indclass
63, 79
vwap, vol, open, close, indclass
90
vol, close, indclass
67
vwap, vol, high, indclass
97
vwap, vol, low, indclass
69, 70, 87, 91, 93
vwap, vol, close, indclass
100
vol, close, high, low, indclass
8.2. 附录2
主模块:wqalpha101 module
101 Formulaic Alphas
DolphinDB 教程:模块
日频数据及分钟频数据建库建表
行业信息数据建库建表
Alpha101计算存储全流程代码汇总
因子计算准备函数模块
因子最佳实践中的因子存储章节
101因子的Python实现参考出处
本文用的101因子python模块代码
下载一年模拟日频数据
wq101alpha 模块性能测试脚本
Python alpha 101 性能测试脚本
完整性能对比结果
DolphinDB 正确性验证脚本
Python 正确性验证脚本
正确性对比脚本
WQ101alpha流计算全流程
FILE:references/doc_5643.md
# getSessionMemoryStat
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getSessionMemoryStat.html
**来源**: DolphinDB 官方文档
---
getSessionMemoryStat
语法
getSessionMemoryStat()
详情
获取当前节点所有连接会话的内存占用状态。
缓存类型说明:
缓存类型
含义
__DimensionalTable__
维度表缓存,单位为字节。
__SharedTable__
共享表缓存,单位为字节。
__OLAPTablet__
OLAP 引擎数据库表的缓存,单位为字节。
__OLAPCacheEngine __
OLAP 引擎 Cache Engine 的内存占用,单位为字节。
__OLAPCachedSymbolBase__
OLAP 引擎 SYMBOL 类型字典编码的缓存,单位为字节。
__DFSMetadata__
分布式存储的元数据内存占用情况,单位为字节。
__TSDBCacheEngine__
TSDB 引擎 Cache Engine 的内存占用,单位为字节。
__TSDBLevelFileIndex__
TSDB 引擎 level file 索引的缓存,单位为字节。
__TSDBCachedSymbolBase__
TSDB 引擎 SYMBOL 类型字典编码的缓存,单位为字节。
__StreamingPubQueue__
流数据发布队列里未处理的消息数。
__StreamingSubQueue__
流数据订阅队列里未处理的消息数。
__IOTDBStaticTableCache__
静态表缓存,单位为字节。
__IOTDBLatestKeyCache__
最新值表缓存,单位为字节。
注:
此函数无法统计到会话中正在执行的任务所占用的内存情况。
对于返回表中的 createTime 和 lastActiveTime,
2.00.9.4
之前版本的 DolphinDB,返回零时区时间;
2.00.9.4
及之后版本的 DolphinDB,返回当前时区的时间。
返回值
返回一张表包含以下字段:
userId:用户 ID 或缓存类型的标识符(形如:__xxx__)。
sessionId:会话 ID。
memSize:会话所占用的内存,单位为字节。
remoteIP:发起会话的客户端的 IP。
remotePort:发起会话的客户端的端口号。
createTime:会话创建的时间,为 TIMESTAMP 类型。
lastActiveTime:会话最近一次执行脚本的时间戳。
例子
t = getSessionMemoryStat();
t;
userId
sessionId
memSize
remoteIP
remotePort
createTime
lastActiveTime
__DimensionalTable__
0
0.0.0.0
__SharedTable__
0
0.0.0.0
__OLAPTablet__
0
0.0.0.0
__OLAPCacheEngine__
0
0.0.0.0
__OLAPCachedSymbolBa...
0
0.0.0.0
__DFSMetadata__
2769
0.0.0.0
__TSDBCacheEngine__
0
0.0.0.0
__TSDBLevelFileIndex__
0
0.0.0.0
__TSDBCachedSymbolBa...
0
0.0.0.0
__StreamingPubQueue__
0
0.0.0.0
__StreamingSubQueue__
0
0.0.0.0
admin
2882591513
1416
60.176.105.0
20861
2023.02.15T02:15:22.384
2023.02.15T02:24:16.307
FILE:references/doc_5651.md
# getUserTableAccessRecords
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getUserTableAccessRecords.html
**来源**: DolphinDB 官方文档
---
getUserTableAccessRecords
语法
getUserTableAccessRecords([from=0], [to])
详情
从已保存记录了分布式表查询信息的日志中,提取指定时间段内的查询日志。
参数
from
整型或时间类型,表示查询的起始时间点。默认值为0,表示查询从1970.01.01零点开始的记录。
to
整型或时间类型,表示查询的结束时间点。默认为空,表示查询到目前时间点为止的记录。
from
必须小于等于
to
。
返回值
返回一个表。含以下字段:
timestamp:NANOTIMESTAMP 类型的时间戳。如果 type 是 sql,则这里记录开始执行 SQL 的时间戳;如果 type 是
rowCount 或 memUsage,则这里记录的是读出数据的时间戳。
rootQueryId:SQL 查询任务的 ID,是分布式 SQL 查询任务的唯一标识符。一个分布式查询会按分区拆分为多个 SQL 子查询。该 ID
为分布式查询及其拆分出的子查询的根 ID。
userid:用户名。
database:数据库名。
table:表名。
type:记录的信息类型,包括3类:sql, rowCount, memUsage。
value:
当类型为 sql 时,为 SQL 查询任务的执行次数。该值总是为1。
当类型为 rowCount 时,为 SQL 执行时存储引擎返回的表的行数。
当类型为 memUsage 时,为查询结果占用的内存大小。单位是字节。
script:当类型为 sql 时,记录 SQL 脚本,其他类型则为空字符串。
该函数仅限管理员在数据节点上调用。
例子
getUserTableAccessRecords(2023.12.30T09:18:35.894150296,2023.12.30T09:18:35.894538439)
// output
timestamp rootQueryId userId database table type value script
2023.12.30T09:18:35.894150296 e892855b-7843-1492-0140-a85810662006 admin dfs://rangedb pt sql 1 select count(x) as count_x from pt
2023.12.30T09:18:35.894497304 e892855b-7843-1492-0140-a85810662006 admin dfs://rangedb pt rowCount 43
2023.12.30T09:18:35.894501600 e892855b-7843-1492-0140-a85810662006 admin dfs://rangedb pt memUsage 516
FILE:references/doc_5656.md
# sub
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sub.html
**来源**: DolphinDB 官方文档
---
sub
语法
sub(X, Y)
或
X-Y
详情
逐元素地返回
X
和
Y
的差。如果
X
和
Y
是集合,
sub
返回一个集合,它是从
X
中减去
X
和
Y
相同元素后的集合。
参数
X
和
Y
可以是标量、数据对、向量、矩阵或集合。如果
X
或
Y
的其中一个是数据对、向量或矩阵,另一个参数可以是标量或具有相同长度或维度的数据对、向量或矩阵。
返回值
一个标量、数据对、向量、矩阵或集合。
例子
4:5-2;
// output
2 : 3
4:5-1:2;
// output
3 : 3
x=1 2 3;
x-1;
// output
[0,1,2]
1 sub x;
// output
[0,-1,-2]
y=4 5 6;
sub(x,y);
// output
[-3,-3,-3]
m1=1..6$2:3;
m1;
#0
#1
#2
1
3
5
2
4
6
m-2;
#0
#1
#2
-1
1
3
0
2
4
m2=6..1$2:3;
m2;
#0
#1
#2
6
4
2
5
3
1
m1-m2;
#0
#1
#2
-5
-1
3
-3
1
5
x=set([5,3,4]);
y=set(8 9 4 6);
x-y;
// output
set(3,5)
y-x;
// output
set(6,9,8)
FILE:references/doc_5659.md
# tmprod
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmprod.html
**来源**: DolphinDB 官方文档
---
tmprod
语法
tmprod(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
元素的乘积。
返回值
与
X
长度相同的 DOUBLE 类型向量。
例子
T = 1 1 3 5 8 15 15 20
X = 5 2 4 1 2 8 9 10
m=table(T as t, X as x)
select *, tmprod(t, x, 3) from m
t
x
tmprod_t
1
5
5
1
2
10
3
4
40
5
1
4
8
2
2
15
8
8
15
9
72
20
10
10
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = NULL 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmprod(t, x, 3d) from m
t
x
tmprod_t
2021.01.02
2021.01.02
4
4
2021.01.04
4
2021.01.05
-1
-1
2021.01.07
2
-2
2021.01.08
4
8
select *, tmprod(t, x, 1w) from m
t
x
tmprod_t
2021.01.02
2021.01.02
4
4
2021.01.04
4
2021.01.05
-1
-1
2021.01.07
2
-2
2021.01.08
4
8
相关函数:
mprod
,
prod
FILE:references/doc_5672.md
# restoreTable
**URL**: https://docs.dolphindb.cn/zh/funcs/r/restoreTable.html
**来源**: DolphinDB 官方文档
---
restoreTable
语法
restoreTable(backupDir, dbPath, tableName, [newDBPath], [newTableName],
[keyPath])
详情
恢复备份的表到数据库。调用该函数可以简化代码,方便用户一次性恢复数据库的一张表。
该函数与
migrate
类似,都可恢复整个数据库下的整个表,区别见表相关内容。
注意事项:
该函数仅支持恢复以拷贝文件方式(即
backup
时指定
dbPath
参数)进行的备份。
恢复时需要确保备份数据与待恢复数据库的引擎类型(engine)一致,且
partitionScheme
(VALUE
除外)也保持一致。 当采用 VALUE 分区时,须保证备份数据中的分区方案是待恢复数据库的分区方案的子集。例如:备份文件的分区方案是
database("dfs://xxx", VALUE, 2017.08.07..2017.08.11), 则待恢复数据库的 VALUE 分区范围必须不小于
2017.08.07..2017.08.11。
参数
backupDir
字符串,表示存放备份数据的目录。
dbPath
字符串,表示已备份的分布式数据库的路径。
tableName
字符串,表示表名。
newDBPath
字符串,表示新数据库的名称。如果没有指定,默认值为
dbPath
。
newTableName
字符串,表示新表的名称。如果没有指定,默认值为
tableName
。
keyPath
字符串标量,指定恢复加密表备份的密钥路径。仅 Linux
系统支持该参数。恢复数据使用的密钥必须与备份时指定的密钥版本一致。注意恢复加密表时,备份表与目标表必须指定相同的加密方式(即建表时指定相同的
encryptMode
参数)。
返回值
返回一个表,包含数据库名称和表名称。
例子
dbName = "dfs://compoDB2"
n=1000
ID=rand("a"+string(1..10), n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10, n)
t=table(ID, date, x)
db1 = database(, VALUE, 2017.08.07..2017.08.11)
db2 = database(, HASH,[INT, 20])
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db = database(dbName, COMPO,[ db1,db2])
// 创建2个表
pt1 = db.createPartitionedTable(t, `pt1, `date`x).append!(t)
pt2 = db.createPartitionedTable(t, `pt2, `date`x).append!(t)
backupDB(backupDir, dbName)
restoreTable(backupDir,"dfs://compoDB2",`pt1)
输出返回:
dbName
tableName
dfs://compoDB2
pt1
相关函数:
restore
,
restoreDB
,
migrate
,
backup
,
backupDB
,
backupTable
FILE:references/doc_5694.md
# createSchema
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createSchema.html
**来源**: DolphinDB 官方文档
---
createSchema
语法
createSchema(catalog, dbUrl, schema)
详情
把指定数据库添加到指定的 catalog 中。
由于数据库的 dbUrl 是全局唯一的,但不同 catalog 中的 schema 可以重名。因此需要先将数据库和 dbUrl 进行解耦。然后在将指定数据库添加到指定
catalog 时,需要为该数据库指定一个 schema 名称(类似该数据库的别名)。在后续 catalog 的相关操作中,都将使用该数据库的 schema 名称而非
dbUrl。
注意:不支持将数据库同时加到两个 catalog 中。
参数
catalog
字符串标量,表示 catalog 的名称。
dbUrl
字符串标量,表示数据库的路径。
schema
字符串标量,表示数据库对应的 schema 名称。
返回值
无。
例子
createSchema("catalog1", "dfs://db1", "schema1")
FILE:references/doc_5698.md
# bondInstrumentCalculator
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bondinstrumentcalculator.html
**来源**: DolphinDB 官方文档
---
bondInstrumentCalculator
语法
bondInstrumentCalculator(bond, settlement, price, priceType,
[calcRisk=false], [benchmark='Qeubee'])
详情
债券计算器,实现债券价格 (ytm / cleanPrice / dirtyPrice) 三者互算,同时计算久期、凸度等风险指标。
参数
bond
INSTRUMENT 类型标量或向量,表示债券金融工具。
settlement
DATE 类型标量或向量,表示债券的结算日,即购买日期。
price
数值型标量或向量,具体含义取决于 priceType 的取值:
当
priceType
为 "YTM" 时,
price
表示债券的到期收益率;
当
priceType
为 "CleanPrice" 时,
price
表示债券的净价;
当
priceType
为 "DirtyPrice" 时,
price
表示债券的全价。
priceType
STRING 类型的标量或向量,用于指定债券价格类型,可选值为:
"YTM":到期收益率
"CleanPrice":净价
"DirtyPrice":全价
calcRisk
可选参数,布尔值,默认为 false,只计算输出全价、净价、应计利息和收益率。若设置为
true,除上述4项外,还会计算并输出麦考利久期、修正久期、凸度、基点价值。
benchmark
可选参数,STRING 类型标量,表示算法参考基准。目前仅支持 “Qeubee”(国内债券算法)。
返回值
一个字典或元组。
例子
例1. 计算固定利率债券的价格、到期收益率、应计利息和风险指标。
fixedRateBondDict = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"start": 2022.07.15,
"maturity": 2072.07.15,
"issuePrice": 100.0,
"coupon": 0.034,
"dayCountConvention": "ActualActualISMA",
"calendar": "CFET",
"frequency": "Semiannual"
}
fixedRateBond = parseInstrument(fixedRateBondDict);
bondInstrumentCalculator(fixedRateBond, settlement=2025.04.10, price=0.02, priceType="YTM", calcRisk=true);
/* Output:
dirtyPrice->143.4689
cleanPrice->142.6705
ytm->0.02
accruedInterest->0.7983
macaulayDuration->27.4761
modifiedDuration->27.2041
convexity->1025.4003
pvbp->0.3902
*/
bondInstrumentCalculator(fixedRateBond, settlement=2072.04.18, price=100.2143, priceType="CleanPrice", calcRisk=false);
/* Output:
dirtyPrice: 101.0923
cleanPrice: 100.2143
ytm: 0.0250
accruedInterest: 0.8780
*/
例2. 计算零息债券的价格、到期收益率、应计利息和风险指标。
zeroCouponBondDict = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "ZeroCouponBond",
"coupon": 0.0119,
"start": 2025.01.09,
"maturity": 2026.02.05,
"issuePrice": 100.0,
"dayCountConvention": "ActualActualISMA",
"calendar": "CFET"
}
zeroCouponBond = parseInstrument(zeroCouponBondDict);
bondInstrumentCalculator(zeroCouponBond, settlement=2025.04.10, price=0.025, priceType="YTM", calcRisk=true);
/* Output:
dirtyPrice->99.2322
cleanPrice->98.9355
ytm->0.025
accruedInterest->0.2966
macaulayDuration->0.8246
modifiedDuration->0.8079
convexity->1.3057
pvbp->0.0080
*/
例3. 计算贴现债券的价格、到期收益率、应计利息和风险指标。
discountBondDict = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "Discount",
"start": 2025.02.13,
"maturity": 2025.05.15,
"issuePrice": 99.663,
"dayCountConvention": "ActualActualISMA",
"calendar": "CFET"
}
discountBond = parseInstrument(discountBondDict);
bondInstrumentCalculator(discountBond, settlement=2025.04.10, price=0.02, priceType="YTM", calcRisk=true);
/* Output:
dirtyPrice->99.8085
cleanPrice->99.6012
ytm->0.02
accruedInterest->0.2073
macaulayDuration->0.0958
modifiedDuration->0.0957
convexity->0.0183
pvbp->0.0009
*/
例4. 同时计算多种债券的价格、到期收益率、应计利息和风险指标。
result = bondInstrumentCalculator([discountBond, zeroCouponBond, fixedRateBond], settlement=[2025.04.10, 2025.04.10, 2072.04.18], price=[0.02, 0.025, 100.2143], priceType=["YTM", "YTM", "CleanPrice"], calcRisk=true);
print result
/* Output:
(dirtyPrice->99.808599999999998
cleanPrice->99.601200000000005
ytm->0.02
accruedInterest->0.2074
macaulayDuration->0.0959
modifiedDuration->0.0957
convexity->0.0183
pvbp->0.001
,dirtyPrice->99.232200000000005
cleanPrice->98.935500000000004
ytm->0.025
accruedInterest->0.2967
macaulayDuration->0.8247
modifiedDuration->0.808
convexity->1.3057
pvbp->0.008
,dirtyPrice->101.092299999999994
cleanPrice->100.214299999999994
ytm->0.025
accruedInterest->0.878
macaulayDuration->0.2404
modifiedDuration->0.239
convexity->0.1142
pvbp->0.0024
*/
相关函数:
bondCalculator
FILE:references/doc_5716.md
# imr
**URL**: https://docs.dolphindb.cn/zh/funcs/i/imr.html
**来源**: DolphinDB 官方文档
---
imr
语法
imr(ds, initValue, mapFunc, [reduceFunc], [finalFunc], terminateFunc,
[carryover=false])
详情
DolphinDB 提供了基于 map-reduce 方法的迭代计算函数
imr
。每次迭代使用上一次迭代的结果和输入数据集。每次迭代的输入数据集不变,因此可以被缓存。迭代计算需要模型参数的初始值和终止标准。
参数
ds
数据源列表。它必须是每个元素作为数据源对象的元组。即使只有一个数据源,我们仍然需要一个元组来包装数据源。在迭代计算中,数据源自动缓存,缓存将在最后一次迭代后被清除。
initValue
模型参数估计的初始值。初始值的格式必须与最终函数的输出相同。
mapFunc
map函数。它有两个参数。第一个参数是由相应数据源表示的数据实体。第二个参数是前一次迭代中最终函数的输出,这是对模型参数的更新估算。对于第一次迭代,它是用户给出的初始值。
reduceFunc
二元 reduce 函数组合了两个 map 函数调用结果。如果有 M 个 map
调用,reduce 函数将被调用 M-1 次。在大多数情况下,reduce 功能是不重要的。一个例子是加法函数。reduce 函数是可选的。
finalFunc
每次迭代的最终函数。它接受两个参数。第一个参数是前一次迭代中最终函数的输出。对于第一次迭代,它是用户给出的初始值。第二个参数是 reduce
函数调用的输出。如果没有指定 reduce 函数,则各个 map 调用结果的集合的元组将是第二个参数。
terminateFunc
这是一个确定计算是否继续的函数,或是指定次数的迭代。终止函数接受两个参数。第一个是前一次迭代中 reduce 函数的输出,第二个是当前迭代中 reduce
函数的输出。如果函数返回 true,迭代将结束。
carryover
布尔值,表示 map 函数调用是否生成一个传递给下一次 map 函数调用的对象。默认值为
false。如果
carryover
为 true,那么 map 函数有3个参数并且最后一个参数为携带的对象,同时 map
函数的输出结果是一个元组,最后一个元素为携带的对象。在第一次迭代中,携带的对象为 NULL。
例子
现在我们使用分布式中位数计算的例子来说明函数
imr
。假设数据分散在多个节点上,我们想计算所有节点之间的变量的中位数。首先,对于每个数据源,将数据放入桶中,并使用 map
函数对每个数据桶中的数据点数进行计数。然后使用 reduce
函数来合并来自多个数据源的计数。找到包含中位数的桶。在下一次迭代中,所选择的桶分为更小的桶。当所选择的桶的长度不超过指定的数量时,迭代就完成了。
def medMap(data, range, colName){
return bucketCount(data[colName], double(range), 1024, true)
}
def medFinal(range, result){
x= result.cumsum()
index = x.asof(x[1025]/2.0)
ranges = range[1] - range[0]
if(index == -1)
return (range[0] - ranges*32):range[1]
else if(index == 1024)
return range[0]:(range[1] + ranges*32)
else{
interval = ranges / 1024.0
startValue = range[0] + (index - 1) * interval
return startValue : (startValue + interval)
}
}
def medEx(ds, colName, range, precision){
termFunc = def(prev, cur): cur[1] - cur[0] <= precision
return imr(ds, range, medMap{,,colName}, +, medFinal, termFunc).avg()
}
FILE:references/doc_5721.md
# erase!
**URL**: https://docs.dolphindb.cn/zh/funcs/e/erase_.html
**来源**: DolphinDB 官方文档
---
erase!
语法
erase!(obj, key|filter)
详情
删除集合中的某些元素或字典中的键值或表中的某些行。
参数
obj
可以是集合、字典或表。
对于集合,
key|filter
表示要删除的元素;对于字典,
key|filter
表示要删除的键值;对于表,
key|filter
表示过滤条件的元代码。
返回值
返回修改后的集合、字典或表,数据类型同
obj
。
例子
对于集合:
y=set(8 9 4 6);
y;
// output
set(6,4,9,8)
y.erase!(6);
// output
set(4,9,8)
erase!(y, 9 8);
// output
set(4)
对于字典:
x=1..6;
y=11..16;
z=dict(x,y);
z;
// output
6->16
5->15
4->14
3->13
2->12
1->11
erase!(z, 1..4);
// output
6->16
5->15
对于表:
x=1..10;
y=11..20;
t=table(x,y);
// output
erase!(t, <x<=3>);
x
y
4
14
5
15
6
16
7
17
8
18
9
19
10
20
erase!(t, <x<=9 and y>=15>);
x
y
4
14
10
20
FILE:references/doc_5727.md
# cleanOutdateLogFiles
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cleanOutdateLogFiles.html
**来源**: DolphinDB 官方文档
---
cleanOutdateLogFiles
语法
cleanOutdateLogFiles([retentionTime=30])
详情
手动触发超过
retentionTime
时间的系统日志的清理。
参数
retentionTime
系统日志的保留时间,默认是 30(单位:天)。
返回值
无。
FILE:references/doc_5733.md
# kroghInterpolate
**URL**: https://docs.dolphindb.cn/zh/funcs/k/kroghinterpolate.html
**来源**: DolphinDB 官方文档
---
kroghInterpolate
语法
kroghInterpolate(X, Y, newX, [der=0])
详情
对一组点集进行多项式插值,该多项式通过点集中所有的数据点对 (x, y)。返回在 X 点处指定导数阶数的多项式估值。
可以额外指定在每个点 x 处的多个导数值:用户通过重复 xi 值并将导数值指定为连续的 yi 值来实现。
当 x 是唯一值时,y 为多项式 f(x) 的值。
当 x 出现相同值时,则第一个 y 是 f(x) 的值,第二个为对应的 x 的一阶导数值,第三个为对应的 x 的二阶导数值,依此类推。比如对于输入X =
[0,0,1,1],Yi= [1,0,2,3],有 Y[0]=f(0),Y[1]=f'(0),Y[2]=f(1),Y[3]=f'(1)。
参数
X
数值向量,表示用于插值的点的 x 坐标。必须是递增序列,不能包含 NULL 值。
Y
数值向量,与
Xi
等长,表示用于插值的点的 y 坐标。不能包含 NULL 值。
newX
数值向量,表示需要求值的点的 x 坐标。不能包含 NULL 值。
der
可选参数,非负整数,表示返回值的导数阶数。默认值为 0,表示计算多项式函数本身的值。
返回值
DOUBLE 类型向量。
例子
以正弦函数为例进行多项式插值,分别计算 xx 点处的多项式估值和其一阶导数值。
def linspace(start, end, num, endpoint=true){
if(endpoint) return end$DOUBLE\(num-1), start + end$DOUBLE\(num-1)*0..(num-1)
else return start + end$DOUBLE\(num-1)*0..(num-1)
}
x = 0 1 2 3 4 5
y = sin(x)
xx = linspace(0.0, 5.0, 10)[1]
yy=kroghInterpolate(x,y,xx)
yy;
yy1=kroghInterpolate(x,y,xx,1)
yy1;
yy 返回值:
[0,0.515119011157387,0.898231239576709,0.998548648650381,0.793484053410063,0.354287125066207,-0.188319604452395,-0.678504737959061,-0.969692008469677,-0.958924274663139]
yy1 返回值:
[0.885486080979582,0.875967413938641,0.459031117252456,-0.103633680213926,-0.612193041424271,-0.92866822117116,-0.976935666075988,-0.742727014588963,-0.273629096989106,0.320916064615744]
FILE:references/doc_5738.md
# randPoisson
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randPoisson.html
**来源**: DolphinDB 官方文档
---
randPoisson
语法
randPoisson(mean, count)
详情
生成指定个数的泊松分布随机数。
参数
mean
是泊松分布的均值。
count
是正整数,表示生成的随机数个数。
返回值
长度为
count
的 DOUBLE 类型向量。
例子
randPoisson(2.31, 2);
// output
[7, 2]
FILE:references/doc_5756.md
# log
**URL**: https://docs.dolphindb.cn/zh/funcs/l/log.html
**来源**: DolphinDB 官方文档
---
log
语法
log(X, [Y])
详情
若未指定
Y
,返回
X
的自然对数(以常数 e 为底);若指定了
Y
,则返回以
Y
为底的
X
的对数。
参数
X
可以是标量、向量、数据对、矩阵或表。
Y
可选参数。是一个正数,表示对数的底。
返回值
返回数值类型的结果,形式与
X
一致。
例子
log(2.718283);
输出返回:1
log(0 1 2 3);
输出返回:[,0,0.693147,1.098612]
log(100, 10)
输出返回:2
FILE:references/doc_5757.md
# extractMktData
**URL**: https://docs.dolphindb.cn/zh/funcs/e/extractMktData.html
**来源**: DolphinDB 官方文档
---
extractMktData
语法
extractMktData(mktData)
详情
提取 MKTDATA 类型对象内部的数据。
参数
mktData
MKTDATA 类型标量,或由多个 MKTDATA 组成的元组。
返回值
mktData
是标量时,返回一个字典。
mktData
是元组时,返回一个由字典组成的元组。
例子
curve = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": 2025.07.01,
"currency": "CNY",
"curveName": "CNY_FR_007",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"dates":[2025.07.07,2025.07.10,2025.07.17,2025.07.24,2025.08.04,2025.09.03,2025.10.09,2026.01.05,
2026.04.03,2026.07.03,2027.01.04,2027.07.05,2028.07.03],
"values":[0.015785,0.015931,0.016183,0.016381,0.016493,0.016503,0.016478,0.016234,0.016321,
0.016378,0.015508,0.015185,0.014901],
"settlement": 2025.07.01
}
mktData = parseMktData(curve)
//打印mktData数据类型
print(typestr(mktData)) //MKTDATA
//提取mktData里面的信息
d = extractMktData(mktData)
print(d)
/*
mktDataType->Curve
version->1
curveType->IrYieldCurve
referenceDate->2025.07.01
dayCountConvention->Actual365
curveName->CNY_FR_007
dates->[2025.07.07,2025.07.10,2025.07.17,2025.07.24,2025.08.04,2025.09.03,2025.10.09,2026.01.05,2026.04.03,2026.07.03,2027.01.04,2027.07.05,2028.07.03]
years->[0.016438356164384,0.024657534246575,0.043835616438356,0.063013698630137,0.093150684931507,0.175342465753425,0.273972602739726,0.515068493150685,0.756164383561644,1.005479452054794,1.512328767123288,2.010958904109589,3.008219178082192]
values->[0.015785,0.015931,0.016183,0.016381,0.016493,0.016503,0.016478,0.016234,0.016321,0.016378,0.015508,0.015185,0.014901]
interpMethod->Linear
extrapMethod->Flat
currency->CNY
compounding->Continuous
curveModel->Bootstrap
settlement->2025.07.01
frequency->Annual
*/
相关函数:
parseMktData
FILE:references/doc_5767.md
# createEqualJoinEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createEqualJoinEngine.html
**来源**: DolphinDB 官方文档
---
createEqualJoinEngine
是
createEquiJoinEngine
的别名。
FILE:references/doc_577.md
# randDiscrete
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randDiscrete.html
**来源**: DolphinDB 官方文档
---
randDiscrete
语法
randDiscrete(v, p, count)
详情
根据给定的分布概率
p
,生成向量
v
的随机样本。生成样本的长度由
count
指定。
参数
v
向量或元组,表示样本数据。
p
与
v
等长的浮点型向量,其每个元素必须是正数,对应
v
中采样元素的概率分布。系统会自动将
p
的元素归一化。
count
正整数,表示输出的随机向量的长度。
返回值
长度为
count
的 DOUBLE 类型向量。
例子
randDiscrete(1..5, [0.1, 0.1, 0.2, 0.2, 0.4], 10)
// output
[2,3,5,2,5,5,2,1,1,2]
// 若概率和不为1,系统会自动归一化
randDiscrete(1..5, [0.1, 0.2, 0.3, 0.4, 0.5], 5)
// output
[5,1,2,3,5]
randDiscrete(`A`B`C`E`F, [0.1, 0.2, 0.3, 0.4, 0.5], 5)
// output
["C","E","B","C","F"]
// 输入元组,对元组中的每个元素进行采样
randDiscrete([[1,2], [2,3,4], 'S', 'abc'], [0.3, 0.3, 0.2, 0.1], 10)
// output
('S',[2,3,4],[1,2],[2,3,4],[1,2],'S','S',[2,3,4],[2,3,4],[2,3,4])
// 输入数组向量,对其中的每个向量进行采样
a = array(INT[], 0, 10).append!([1 2 3, 4 5,6 7 8, 9 NULL])
randDiscrete(a, [0.1, 0.2, 0.3, 0.4], 10)
// output
[[9,00i],[9,00i],[9,00i],[4,5],[9,00i],[1,2,3],[9,00i],[6,7,8],[9,00i],[9,00i]]
FILE:references/doc_5776.md
# lfill
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lfill.html
**来源**: DolphinDB 官方文档
---
lfill
语法
lfill(obj)
详情
如果
obj
是向量,线性填充两个非空元素之间的 NULL值。
如果
obj
是表,对于表中的每一列,线性填充两个非空元素之间的 NULL 值。
lfill
不会改变向量的值,
lfill!
会改变向量的值。
参数
obj
是数值型向量或只包含数值类型的表。
返回值
返回值的类型和形式与
obj
保持一致。
例子
a= NULL 1.5 NULL NULL 4.5
a.lfill();
// output
[NULL,1.5,2.5,3.5,4.5]
b=1 NULL NULL 6
b.lfill();
// output
[1,3,4,6]
t=table(1 NULL NULL 4 5 6 as id,2.1 2.2 NULL NULL 2.4 2.6 as val);
select * from lfill(t);
id
val
1
2.1
2
2.2
3
2.266667
4
2.333333
5
2.4
6
2.6
相关函数:
bfill
,
bfill!
,
lfill!
FILE:references/doc_5783.md
# getComputeNodeCacheStat
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getcomputenodecachestat.html
**来源**: DolphinDB 官方文档
---
getComputeNodeCacheStat
语法
getComputeNodeCacheStat()
详情
应用于计算组中的计算节点上,返回该节点的二级缓存信息。
参数
无
返回值
返回一个表,包含以下列:
memCacheUsage:内存缓存的使用量,单位为 MB。
memCacheSize:内存缓存的最大容量,单位为 MB。
diskCacheUsage:磁盘缓存的使用量,单位为 MB。
diskCacheSize:磁盘缓存的最大容量,单位为 MB。
例子
getComputeNodeCacheStat()
memCacheUsage
memCacheSize
diskCacheUsage
diskCacheSize
114.51725769042969
1,024
0
65,536
FILE:references/doc_5792.md
# saveDualPartition
**URL**: https://docs.dolphindb.cn/zh/funcs/s/saveDualPartition.html
**来源**: DolphinDB 官方文档
---
saveDualPartition
语法
saveDualPartition(dbHandle1, dbHandle2, table, tableName, partitionColumn1,
partitionColumn2, [compression=false])
详情
在共享表前,将一张表保存为组合分区。该命令必须要用户登录后才能执行。
它通常与
share
一起使用。如果分区和表已经存在,该函数会把新数据追加到已有表格。
参数
dbHandle1
是第一级分区的数据库句柄。
dbHandle2
是第二级分区的数据库句柄。
table
是要保存的内存中的表。
tableName
是表示保存的分区表的名称的字符串。
partitionColumn1
是表示第一级分区的分区列的字符串。
partitionColumn2
是表示第二级分区的分区列的字符串。
compression
是一个布尔变量。它表示是否压缩表。当它设置为 true 时,表将被压缩保存到磁盘。默认设置为 false(不压缩)。
例子
n=1000000
ID=rand(10, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(1.0, n)
t=table(ID, date, x);
hdb = database("C:/DolphinDB/Data/dualDB", RANGE, 0 5 10)
vdb = database(, VALUE, dates)
saveDualPartition(hdb, vdb, t, `tDualPartition, `ID, `date)
FILE:references/doc_5793.md
# med
**URL**: https://docs.dolphindb.cn/zh/funcs/m/med.html
**来源**: DolphinDB 官方文档
---
med
语法
med(X)
详情
如果
X
是向量,返回
X
中所有元素的中值。
若
X
为矩阵,计算每列的中值,返回一个向量。
与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
可以是标量、向量或矩阵。
返回值
DOUBLE 类型标量或向量。
例子
x=3 6 1 5 9;
med x;
// output: 5
m=matrix(1 2 10, 4 5 NULL);
m;
#0
#1
1
4
2
5
10
med m;
// output: [2,4.5]
相关的中心趋势函数:
mean
和
mode
FILE:references/doc_5805.md
# ltrim
**URL**: https://docs.dolphindb.cn/zh/funcs/l/ltrim.html
**来源**: DolphinDB 官方文档
---
ltrim
语法
ltrim(X)
详情
删除字符串或字符串向量的每个元素左边的空格。
当
X
是表时,函数仅作用于其中字符串列,其他类型的列将被忽略。
参数
X
是字符串类型的标量、向量、或表。
返回值
返回与
X
形式一致的字符串类型。
例子
ltrim(" I love this game!");
// output
I love this game!
FILE:references/doc_5818.md
# tmvarp
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmvarp.html
**来源**: DolphinDB 官方文档
---
tmvarp
语法
tmvarp(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
的总体方差。
返回值
DOUBLE 类型向量。
例子
T = 1 1 3 5 8 15 15 20
X = 5 2 4 1 2 8 9 10
m=table(T as t, X as x)
select *, tmvarp(t, x, 3) from m
t
x
tmvarp_t
1
5
0
1
2
2.25
3
4
1.5556
5
1
2.25
8
2
0
15
8
0
15
9
0.25
20
10
0
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = NULL 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmvarp(t, x, 3d) from m
t
x
tmvarp_t
2021.01.02
2021.01.02
4
0
2021.01.04
0
2021.01.05
-1
0
2021.01.07
2
2.25
2021.01.08
4
1
select *, tmvarp(t, x, 1w) from m
t
x
tmvarp_t
2021.01.02
2021.01.02
4
0
2021.01.04
0
2021.01.05
-1
6.25
2021.01.07
2
4.2222
2021.01.08
4
4.1875
相关函数:
mvarp
,
varp
FILE:references/doc_5822.md
# any/all
**URL**: https://docs.dolphindb.cn/zh/progr/sql/any.html
**来源**: DolphinDB 官方文档
---
any/all
用法
any 和 all 关键字用于 where 或 having 子句。
where/having col optr any(sub_query)
where/having col optr all(sub_query)
其中 optr 是比较运算符,sub_query 是一个 SQL 查询或者向量。
any/all 关键字将比较运算符前的操作数(通常是某列的值)与子查询结果集或向量中的值一一比较:
any:若存在满足条件的子查询结果或向量值,则返回 true,否则为 false。
all:若所有子查询结果或向量值都满足比较条件,则返回 true,否则返回 false。
注:
“= any“ 等价于 “in”;”= all” 等价于 “!= any”;
SQL 的 any / all 谓词和内置函数 any / all
功能类似但不同。前者用于值比较,后者用于判断布尔值。
下面以两个语句来说明区别:
SQL 中的 any 谓词:
x > any([n1,n2,n3])
内置 any 函数:
any([x>n1, x>n2, x>n3])
例子
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t1 = table(timestamp, sym, qty, price);
t2 = table(`C`MS`IBM as sym, 1 0 1 as flag)
select * from t1 where sym = any(select sym from t2 where flag=1)
timestamp
sym
qty
price
09:34:07
C
2,200
49.6
09:32:47
IBM
6,800
174.97
09:35:26
IBM
5,400
175.23
09:34:16
C
1,300
50.76
09:34:26
C
2,500
50.32
09:38:12
C
8,800
51.29
select * from t1 where sym != all(select sym from t2 where flag = 1)
timestamp
sym
qty
price
09:36:42
MS
1,900
29.46
09:36:51
MS
2,100
29.52
09:36:59
MS
3,200
30.02
t3 = select wavg(price, qty) as wavg from t1 group by sym
select * from t1 where price >= all(select wavg from t3)
timestamp
sym
qty
price
09:35:26
IBM
5,400
175.23
select * from t1 where price >= any(select wavg from t3)
timestamp
sym
qty
price
09:34:07
C
2,200
49.6
09:36:59
MS
3,200
30.02
09:32:47
IBM
6,800
174.97
09:35:26
IBM
5,400
175.23
09:34:16
C
1,300
50.76
09:34:26
C
2,500
50.32
09:38:12
C
8,800
51.29
FILE:references/doc_5823.md
# upsert!
**URL**: https://docs.dolphindb.cn/zh/funcs/u/upsert_.html
**来源**: DolphinDB 官方文档
---
upsert!
语法
upsert!(obj, newData, [ignoreNull=false], [keyColNames],
[sortColumns])
详情
将新数据写入索引内存表、键值内存表,或者 DFS 表。若新数据的主键值已存在,更新该主键值的数据;否则添加数据。
注:
调用该函数时,需要保证
newData
和
obj
两表各列的顺序一致,否则可能产生错误结果或报错。
若
keyColNames
指定的列存在重复值,对重复值进行
upsert!
操作,仅会更新第一个值所在行,其余值所在行不会更新。
函数行为会受到配置参数
enableNullSafeJoin
的影响:
当
enableNullSafeJoin
=true 时,连接列中的 NULL 值可以匹配成功,upsert!
可能会更新包含 NULL 的记录;
当
enableNullSafeJoin
=false 时,连接列中的 NULL 值无法匹配,upsert!
不会更新此类记录。
参数
obj
是一个索引内存表、键值内存表,或者 DFS 表(分布式表或维度表)。
newData
是一个内存表,且与
obj
的结构一样。
ignoreNull
是一个布尔值,表示若
newData
中某元素为 NULL
值,是否忽略对目标表中的相应数据进行更新。默认值为 false。
keyColNames
是一个字符串标量或向量。由于 DFS 表没有键值列,对 DFS
表进行更新时,将该参数指定的列和分区列一起视为键值列。
sortColumns
是一个字符串标量或向量。设置该参数,更新的分区内的所有数据会根据指定的列进行排序。排序在每个分区内部进行,不会跨分区排序。
注:
仅 OLAP 引擎下使用
upsert!
时,才支持设置
sortColumns
。
要设置
sortColumns
,
obj
必须为分布式表。
仅对同一个分区内的数据 按照
sortColumns
进行排序,不同分区之间的数据不会进行排序。
obj
为一个空表时,设置
sortColumns
无效,即更新后不对新插入的数据进行排序。
在 PKEY 引擎下不支持设置
ignoreNull
,
keyColNames
,
sortColumns
。
返回值
一个表。
例子
对键值内存表使用
upsert!
sym=`A`B`C
date=take(2021.01.06, 3)
x=1 2 3
y=5 6 7
t=keyedTable(`sym`date, sym, date, x, y)
t;
sym
date
x
y
A
2021.01.06
1
5
B
2021.01.06
2
6
C
2021.01.06
3
7
如果对应列的数据类型一致,就会输出结果。
newData = table(`A`B`C`D as sym1, take(2021.01.06, 4) as date1, NULL NULL 300 400 as x1, NULL 600 700 800 as y1);
newData;
sym
date
x1
y1
A
2021.01.06
B
2021.01.06
600
C
2021.01.06
300
700
D
2021.01.06
400
800
upsert!(t, newData, ignoreNull=true)
t;
sym
date
x
y
A
2021.01.06
1
5
B
2021.01.06
2
600
C
2021.01.06
300
700
D
2021.01.06
400
800
以上为将
ignoreNull
设为 true 时的情况。此时,若新数据中有元素值为 NULL,不对目标数据表的相应的元素进行更新操作。
以下为将
ignoreNull
设为 false(默认值)时的情况,不管新数据中值是否为 NULL,均进行更新操作。
sym=`A`B`C
date=take(2021.01.06, 3)
x=1 2 3
y=5 6 7
t=keyedTable(`sym`date, sym, date, x, y)
upsert!(t, newData)
t;
sym
date
x
y
A
2021.01.06
B
2021.01.06
600
C
2021.01.06
300
700
D
2021.01.06
400
800
对 DFS 表使用
upsert!
:
ID=0 1 2 2
x=0.1*0..3
t=table(ID, x)
db=database("dfs://rangedb128", VALUE, 0..10)
pt=db.createPartitionedTable(t, `pt, `ID)
pt.append!(t)
select * from pt;
ID
x
0
0
1
0.1
2
0.2
2
0.3
t1=table(1 as ID, 111 as x)
upsert!(pt, t1, keyColNames=`ID)
select * from pt;
ID
x
0
0
1
111
2
0.2
2
0.3
t1=table(2 as ID, 222 as x)
upsert!(pt, t1, keyColNames=`ID)
select * from pt;
ID
x
0
0
1
111
2
222
2
0.3
对 DFS 表使用
upsert!
更新数据,设置
ignoreNull
= true,当新数据中有数据值为 NULL,
则不对目标数据表的相应的元素进行更新操作。
if(existsDatabase("dfs://valuedemo")) {
dropDatabase("dfs://valuedemo")
}
db = database("dfs://valuedemo", VALUE, 1..10)
t = table(take(1..10, 100) as id, 1..100 as id2, 100..1 as value)
pt = db.createPartitionedTable(t, "pt", `id).append!(t)
t2 = table( 1 2 as id, 1 2 as id2, 1 NULL as value)
upsert!(pt, t2, true, "id2")
if(existsDatabase("dfs://upsert")) {
dropDatabase("dfs://upsert")
}
sym=`A`B`C`A`D`B`A
date=take(2021.12.10,3) join take(2021.12.09, 3) join 2021.12.10
price=8.3 7.2 3.7 4.5 6.3 8.4 7.6
val=10 19 13 9 19 16 10
t=table(sym, date, price, val)
db=database("dfs://upsert", VALUE, `A`B`C)
pt=db.createPartitionedTable(t, `pt, `sym)
pt.append!(t)
t1=table(`A`B`E as sym, take(2021.12.09, 3) as date, 11.1 10.5 6.9 as price, 12 9 11 as val)
upsert!(pt, t1, keyColNames=`sym, sortColumns=`date`val)
select * from pt
sym
date
price
val
A
2021.12.09
4.5
9
A
2021.12.09
11.1
12
A
2021.12.10
7.6
10
B
2021.12.09
10.5
9
B
2021.12.09
8.4
16
C
2021.12.10
3.7
13
D
2021.12.09
6.3
19
E
2021.12.09
6.9
11
FILE:references/doc_5824.md
# resumeRecovery
**URL**: https://docs.dolphindb.cn/zh/funcs/r/resumeRecovery.html
**来源**: DolphinDB 官方文档
---
resumeRecovery
语法
resumeRecovery()
详情
用于重启节点恢复的进程。调用该命令后,会继续恢复 "Waiting" 状态的数据。该函数只能由管理员在控制节点上调用。
注:
启用高可用集群时,需要在 raft 组内每个节点执行该命令。
相关命令:
suspendRecovery
参数
无
FILE:references/doc_5829.md
# movingTopNIndex
**URL**: https://docs.dolphindb.cn/zh/funcs/m/movingTopNIndex.html
**来源**: DolphinDB 官方文档
---
movingTopNIndex
语法
movingTopNIndex(X, window, top, [ascending=true], [fixed=false],
[tiesMethod='oldest'])
详情
在滑动窗口内对数据进行排序,并返回排序后前 N 个元素的索引位置。
参数
X
是一个数值型/时间类型的向量。注意:从 2.00.10 版本开始,
X
中的空值不参与排序。
window
必须是不小于2的正整数,表示窗口长度。
top
是一个大于1,小于等于
window
的整数。
ascending
是一个布尔值,表示窗口内值的排序方式。true 表示升序,false 表示降序。
fixed
是一个布尔值。表示输出的数组向量每行的长度是否固定为
top
。默认值为 false。设置为 true 时所有窗口的长度相同,前(
top
- 1)个窗口内缺少的索引用 NULL 填充。
tiesMethod
字符串。在滑动窗口内对 X 进行排序后,如果有多个具有相同值的元素无法全部进入前
top
,可以通过该参数来指定选择元素的方式。可选值为:
'oldest':从最早进入窗口的元素开始选取,直至达到
top
个。
'latest':从最晚进入窗口的元素开始向前选取,直至达到
top
个。
返回值
返回一个数组向量,表示
X
在每一个滑动窗口内按照指定顺序排序后的前
top
个元素所对应的索引。
例子
S = 2 5 6 1 2 4 5 6 9 0
m1 = movingTopNIndex(X=S, window=4, top=2, ascending=true, fixed=true)
m1;
// output
[[,0],[0,1],[0,1],[3,0],[3,4],[3,4],[3,4],[4,5],[5,6],[9,6]]
m2 = movingTopNIndex(X=S, window=4, top=2, ascending=false, fixed=true)
m2;
// output
[[,0],[1,0],[2,1],[2,1],[2,1],[2,5],[6,5],[7,6],[8,7],[8,7]]
m3 = movingTopNIndex(X=S, window=4, top=2, ascending=true, fixed=false)
print m3;
// output
[[0],[0,1],[0,1],[3,0],[3,4],[3,4],[3,4],[4,5],[5,6],[9,6]]
S[m1[0]]
// output
[,2,2,1,1,1,1,2,4,0]
S[m3[0]]
// output
[2,2,2,1,1,1,1,2,4,0]
X = [5, 8, 1, 9, 7, 3, 1, NULL, 0, 8, 7, 7]
movingTopNIndex(X=X, window=4, top=2, ascending=true, fixed=true)
// 2.00.10 之前的版本,X 中的空值也参与排序,结果是:
[[00i,0],[0,1],[2,0],[2,0],[2,4],[2,5],[6,5],[7,6],[7,8],[7,8],[7,8],[8,10]]
// 2.00.10 及之后版本,X 中的空值会被忽略,结果是:
[[00i,0],[0,1],[2,0],[2,0],[2,4],[2,5],[6,5],[6,5],[8,6],[8,6],[8,10],[8,10]]
X = [2, 1, 4, 3, 4, 3, 4]
// 第6个滑动窗口中,X 排序后是 1 2 3 3 4 4,只取前3个排名,根据 tiesMethod 的设置值来选取哪个3被选取
// tiesMethod 未指定,则取默认值 'oldest',即选取第一次出现的3,其对应 X 中的索引是3
movingTopNIndex(X,6,3)
// output
[[0],[1,0],[1,0,2],[1,0,3],[1,0,3],[1,0,3],[1,3,5]]]
// tiesMethod = 'latest',即选最后一次出现的3,其对应 X 中的索引是5
movingTopNIndex(X,6,3,tiesMethod="latest")
// output
[[0],[1,0],[1,0,2],[1,0,3],[1,0,3],[1,0,5],[1,3,5]]
FILE:references/doc_5832.md
# randChiSquare
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randChiSquare.html
**来源**: DolphinDB 官方文档
---
randChiSquare
语法
randChiSquare(df, count)
详情
生成指定个数的卡方分布随机数。
参数
df
是正数,表示卡方分布的自由度。
count
是正整数,表示生成的随机数个数。
返回值
长度为
count
的 DOUBLE 类型向量。
例子
randChiSquare(2.31, 2);
// output
[2.78303, 2.868523]
FILE:references/doc_5841.md
# notBetween/NOTBETWEEN
**URL**: https://docs.dolphindb.cn/zh/progr/sql/notbetween.html
**来源**: DolphinDB 官方文档
---
notBetween/NOTBETWEEN
notBetween...and 是与 between…and 相反的操作,用于匹配指定范围(包括起始值和终止值)之外的所有值,其功能等同于
notBetween
函数、not between 语句。notBetween 支持内存表和分布式表。
语法
select col(s)
from table
where col notBetween value1 and value2
参数
col(s)
要选择的字段名称。一个或多个字段名称或 *(表示所有列)。
table
要查询的表名称。
col
要查询的字段名称。
value1, value2
任何有效的表达式。
value1
表示起始值,
value2
表示终止值。
value1
,
value2
和
col
的数据类型必须相同。
例子
查询 id 列值不在 2 和 4 之间的记录。
timeCols = 2024.11.14+1..6
symCols = `APPL`AMZN`IBM`IBM`AAPL`AMZN
priceCols = 1.8 2.3 3.7 3.1 4.2 2.8
t = table(timeCols as time, symCols as sym, priceCols as price);
select * from t where price notBetween 2 and 4
// 等价于 select * from t where price notBetween 2:4
// 亦等价于 select * from t where price not between 2 and 4
time
sym
price
2024.11.15
APPL
1.8
2024.11.19
AAPL
4.2
查询 time 列日期不在 2024.11.16 和 2024.11.18 之间的所有记录
select * from t where time notBetween 2024.11.16 and 2024.11.18
time
sym
price
2024.11.15
APPL
1.8
2024.11.19
AAPL
4.2
2024.11.20
AMZN
2.8
FILE:references/doc_5847.md
# gaussianNB
**URL**: https://docs.dolphindb.cn/zh/funcs/g/gaussianNB.html
**来源**: DolphinDB 官方文档
---
gaussianNB
语法
gaussianNB(Y, X, [varSmoothing=1e-9])
详情
使用高斯朴素贝叶斯(Gaussian Naive Bayes)算法对数据进行分类训练。
参数
Y
是一个长度与
X
的行数相等的向量,表示
X
中每个样本对应的标签。
X
是一个表,表示训练集。表中的每一行表示一个样本,每一列表示一个特征。
varSmoothing
是一个浮点类型的正数,表示平滑系数。默认值是 1e-9。
返回值
一个字典,包含以下 key:
modelName:模型名称,为字符串 "GaussianNB"
model:gaussianNB 的内部模型
varSmoothing:训练时的平滑系数
例子
本例所用数据集 iris.data 可从
https://archive.ics.uci.edu/ml/datasets/iris
下载。
DATA_DIR = "C:/DolphinDB/Data"
t = loadText(DATA_DIR+"/iris.data")
t.rename!(`col0`col1`col2`col3`col4, `sepalLength`sepalWidth`petalLength`petalWidth`class)
t[`classType] = take(0, t.size())
update t set classType = 1 where class = "Iris-versicolor"
update t set classType = 2 where class = "Iris-virginica"
training = select sepalLength, sepalWidth, petalLength, petalWidth from t
labels = t.classType
model = gaussianNB(labels, training);
predict(model, training);
FILE:references/doc_585.md
# getAllCatalogs
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getAllCatalogs.html
**来源**: DolphinDB 官方文档
---
getAllCatalogs
语法
getAllCatalogs()
详情
检索当前所有可用的 catalog。
参数
无
返回值
检返回一个包含 catalog name 的字符串向量。
例子
getAllCatalogs()
//Output:["catalog1", "catalog2", "catalog3"]
FILE:references/doc_5850.md
# not
**URL**: https://docs.dolphindb.cn/zh/funcs/n/not.html
**来源**: DolphinDB 官方文档
---
not
语法
not(X)
或
!(X)
详情
返回对
X
应用 NOT 的值。返回值是 0, 1 或 NULL。 0 的 NOT 值是 1;NULL 的 NOT
值仍是 NULL;所有其他值的 NOT 值是 0。
not 函数和运算符 ! 在大部分场景下可以相互替代,但仍然存在一些区别:
not 与括号结合时,被当作函数处理,具有最高优先级;
not 不与括号结合时,则优先级较低,会先运算 not 右边的表达式,再运算 not。例如:not false and false 等价于 not(false
and false),结果为 true。
运算符 "!" 则总是按照运算符优先级执行。例如:!false and false 等价于 (!false) and false,结果为 false。
参数
X
可以是标量、数据对、向量或矩阵。
返回值
布尔类型,其数据形式同
X
。
例子
!1.5;
// output
0
not 0;
// output
1
x=1 0 2;
not x;
// output
[0,1,0]
m=1 1 1 1 1 0 0 0 0 0$2:5;
m;
#0
#1
#2
#3
#4
1
1
1
0
0
1
1
0
0
0
not m;
#0
#1
#2
#3
#4
0
0
0
1
1
0
0
1
1
1
(1).not();
// output
0
(!NULL)==NULL;
// output
1
FILE:references/doc_5852.md
# millisecond
**URL**: https://docs.dolphindb.cn/zh/funcs/m/millisecond.html
**来源**: DolphinDB 官方文档
---
millisecond
语法
millisecond(X)
详情
返回
X
中的毫秒数。
参数
X
可以是 TIME, TIMESTAMP, NANOTIME 或 NANOTIMESTAMP
类型的标量或向量。
返回值
整型标量或向量。
例子
millisecond(13:30:10.008);
// output: 8
millisecond([2012.12.03 01:22:01.456120300, 2012.12.03 01:25:08.000234000]);
// output: [456,0]
相关函数:
dayOfYear
,
dayOfMonth
,
quarterOfYear
,
monthOfYear
,
weekOfYear
,
hourOfDay
,
minuteOfHour
,
secondOfMinute
,
microsecond
,
nanosecond
FILE:references/doc_5856.md
# sqlUpdate
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sqlUpdate.html
**来源**: DolphinDB 官方文档
---
sqlUpdate
语法
sqlUpdate(table, updates, [from], [where], [contextBy], [csort], [ascSort],
[having])
详情
动态生成 SQL update 语句的元代码。若需执行生成的元代码,请配合使用
eval
函数。
参数
各参数对应 SQL update
语句中相应部分:
update
table_name
set col1=X1, [col2=X2,…]
[from table_joiner(table_names)]
[where condition(s)]
[context by col_name(s)]
table
可以是内存表,亦可为分布式表。
updates
是元代码或元代码组成的元组,表示更新的操作。
from
是元代码,表示表连接操作。
where
是元代码,表示 where 条件。
contextBy
是元代码,表示 context by 子句。
csort
是 csort 后面的关键字(列名)。仅在使用 context by 子句时,才能指定该参数。如果有多个 csort
关键字,使用元组来表示,每个元素对应一个列名的元代码。
ascSort
是 csort 关键字按升序或降序排列的整型标量或向量。仅在使用 context by 子句时,才能指定该参数。1 表示升序,0
表示降序。默认值为 1。
having
是 having 条件。仅在使用 context by 子句时,才能指定该参数。如果有多个 having 条件,使用 ANY
向量来表示,每个元素对应一个条件的元代码。
返回值
CODE 类型标量。
例子
例1. 更新内存表记录
t1=table(`A`A`B`B as symbol, 2021.04.15 2021.04.16 2021.04.15 2021.04.16 as date, 12 13 21 22 as price)
t2=table(`A`A`B`B as symbol, 2021.04.15 2021.04.16 2021.04.15 2021.04.16 as date, 10 20 30 40 as volume);
sqlUpdate(t1, <price*2 as updatedPrice>).eval()
t1;
symbol
date
price
updatedPrice
A
2021.04.15
12
24
A
2021.04.16
13
26
B
2021.04.15
21
42
B
2021.04.16
22
44
sqlUpdate(table=t1, updates=[<price*10 as updatedPrice>,<price*20 as updatedPrice2>]).eval()
t1;
symbol
date
price
updatedPrice
updatedPrice2
A
2021.04.15
12
120
240
A
2021.04.16
13
130
260
B
2021.04.15
21
210
420
B
2021.04.16
22
220
440
sqlUpdate(table=t2, updates=<cumsum(volume) as cumVolume>, contextby=<symbol>).eval()
t2;
symbol
date
volume
cumVolume
A
2021.04.15
10
10
A
2021.04.16
20
30
B
2021.04.15
30
30
B
2021.04.16
40
70
sqlUpdate(table=t1, updates=<updatedPrice*volume as dollarVolume>, from=<lj(t1, t2, `symbol`date)>).eval()
t1;
symbol
date
price
updatedPrice
dollarVolume
A
2021.04.15
12
120
1200
A
2021.04.16
13
130
2600
B
2021.04.15
21
42
1260
B
2021.04.16
22
44
1760
sqlUpdate(table=t2,updates=<cumsum(volume) as cumVolume>,contextBy=<symbol>,csort=<volume>,ascSort=0).eval()
t2;
symbol
date
volume
cumVolume
A
2021.04.15
10
30
A
2021.04.16
20
20
B
2021.04.15
30
70
B
2021.04.16
40
40
例2. 更新分区表记录
if(existsDatabase("dfs://db1")){
dropDatabase("dfs://db1")
}
n=1000000
t=table(take(`A`B`C`D,n) as symbol, rand(10.0, n) as value)
db = database("dfs://db1", VALUE, `A`B`C`D)
Trades = db.createPartitionedTable(t, "Trades", "symbol")
Trades.append!(t)
x=exec sum(value) from Trades;
Trades=loadTable("dfs://db1", "Trades")
sqlUpdate(table=Trades, updates=<value+1 as value>, where=<symbol=`A>).eval()
y=exec sum(value) from Trades;
y-x;
// output
250000
FILE:references/doc_5857.md
# getConsoleJobs
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getConsoleJobs.html
**来源**: DolphinDB 官方文档
---
getConsoleJobs
语法
getConsoleJobs()
详情
查询本地节点上正在执行的交互式任务的描述信息。
参数
无
返回值
返回一个表,包含以下字段:
参数
含义
node
本地节点的别名。
userID
用户 ID。
rootJobId
系统中作业的唯一标识。
jobType
作业类型。
desc
作业描述。
priority
作业的优先级,为 0-9 之间的整数。
parallelism
作业的并行度,即分配给该作业的线程数上限。
receiveTime
作业被节点接收的时间。
sessionId
发起作业的会话 ID。
remoteIP
发起作业的客户端 IP。
remotePort
发起作业的客户端的端口号。
totalTasks
作业分解出的总任务数。
finishedTasks
作业分解出的任务中已经完成的任务数。
runningTask
作业分解出的任务中正在执行的任务数。
firstTaskStartTime
第一个任务的开始时间。
latestTaskStartTime
最近一个任务的开始时间。
queue
任务队列类型: normal queue(0级 worker 队列),web queue(web 端
worker 队列),local task queue(1~5级 worker 队列),batchJob
queue(批作业队列)。
例子
getConsoleJobs()
node
userID
rootJobId
jobType
desc
priority
parallelism
receiveTime
sessionId
remoteIP
remotePort
totalTasks
finishedTasks
runningTask
firstTaskStartTime
latestTaskStartTime
queue
P2-node1
admin
26681f9c-f914-81ae-47dd-8b8e6e106c48
script
getConsoleJobs()
4
2
2022.01.05T11:05:06.778
1823289176
127.0.0.1
50595
1
0
1
2022.01.05T11:05:06.778
2022.01.05T11:05:06.778
normal queue
FILE:references/doc_5868.md
# 编程语言
**URL**: https://docs.dolphindb.cn/zh/progr/progr_intro.html
**来源**: DolphinDB 官方文档
---
编程语言
本章节包含以下内容:
DolphinDB 脚本编程语言。包含了 DolphinDB 编程所需要了解的概念和方法,例如数据类型与数据形式、不同类型的对象、运算符及运算规则、具有
DolphinDB 特色的编程语句、函数化编程等。DolphinDB 脚本语言大小写敏感,所有标识符(如变量、函数名、类名)及保留字(关键字)严格区分大小写。
SQL 语句。DolphinDB 充分地兼容 ANSI-92 SQL 语言标准和多个主流 SQL 方言。了解 SQL 关键字在 DolphinDB
中的具体使用方法能够帮助 SQL 使用者更流畅地体验 DolphinDB。
FILE:references/doc_5870.md
# cumcovar
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumcovar.html
**来源**: DolphinDB 官方文档
---
cumcovar
语法
cumcovar(X,Y)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
累积计算
X
和
Y
的协方(covariance)。
返回值
DOUBLE 类型,其数据形式取决于
X
(
Y
)。
例子
x = 7 4 5 8 9
y = 1 7 8 9 0
cumcovar(x, y);
// output
[,-9,-5.166667,-1,-4.5]
相关函数:
covar
FILE:references/doc_5873.md
# gt
**URL**: https://docs.dolphindb.cn/zh/funcs/g/gt.html
**来源**: DolphinDB 官方文档
---
gt
语法
gt(X, Y)
或
X>Y
详情
如果
X
和
Y
都不是集合,返回逐个元素比较
X
>
Y
的结果。
如果
X
和
Y
都是集合,则检查
Y
是否为
X
的真子集。
参数
X
和
Y
可以是标量、数据对、向量、矩阵或集合。如果
X
或
Y
的其中一个是数据对、向量或矩阵,另一个必须是一个标量,或具有相同长度或维度的数据对、向量或矩阵。
返回值
布尔类型,数据形式由输入参数决定。
例子
1 2 3 > 2;
// output: [false,false,true]
1 2 3>0 2 4;
// output: [true,false,false]
2:3>1:6;
// output
true : false
m1=1..6$2:3;
m1;
#0
#1
#2
1
3
5
2
4
6
m1 gt 4;
#0
#1
#2
false
false
true
false
false
true
m2=6..1$2:3;
m2;
#0
#1
#2
6
4
2
5
3
1
m1>m2;
#0
#1
#2
false
false
true
false
true
true
集合操作:如果
X
>
Y
,则
Y
是
X
的真子集。
x=set(4 6);
x;
set(6,4)
y=set(8 9 4 6);
y;
set(6,4,9,8)
y>x;
// output
true
x>y;
// output: false
x>x;
// output: false
// x 不是 x 的真子集
FILE:references/doc_5890.md
# pivot
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/pivot.html
**来源**: DolphinDB 官方文档
---
pivot
语法
pivot(func, funcArgs, rowAlignCol, colAlignCol)
详情
在指定的二维维度上重组数据,结果为一个矩阵。
假设
rowAlignCol
有 n 个不同元素,
colAlignCol
有 m
个不同元素。该高阶函数将会返回 n 行 m 列的矩阵,
colAlignCol
的唯一值作为行标签,
rowAlignCol
的唯一值作为列标签。对于矩阵的每一个元素,将指定函数应用到
rowAlignCol
和
colAlignCol
所指定的矩阵单元格的元素上。
参数
func
函数。
funcArgs
func 的参数。如果 func 有多个参数,那么它是一个元组。
rowAlignCol
行的分组变量。
colAlignCol
列的分组变量。
rowAlignCol
,
colAlignCol
和
funcArgs
中的每个参数都是相同长度的向量。
返回值
一个矩阵。
例子
本例计算多只股票收益率的两两相关性。
原始数据表有 4 列:sym, price, volume 和 time。
syms=`600300`600400`600500$SYMBOL
sym=syms[0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 2]
time=09:40:00+1 30 65 90 130 185 195 10 40 90 140 160 190 200 5 45 80 140 170 190 210
price=172.12 170.32 172.25 172.55 175.1 174.85 174.5 36.45 36.15 36.3 35.9 36.5 37.15 36.9 40.1 40.2 40.25 40.15 40.1 40.05 39.95
volume=100 * 10 3 7 8 25 6 10 4 5 1 2 8 6 10 2 2 5 5 4 4 3
t1=table(sym, time, price, volume);
t1;
sym
time
price
volume
600300
09:40:01
172.12
1000
600300
09:40:30
170.32
300
600300
09:41:05
172.25
700
600300
09:41:30
172.55
800
600300
09:42:10
175.1
2500
600300
09:43:05
174.85
600
600300
09:43:15
174.5
1000
600400
09:40:10
36.45
400
600400
09:40:40
36.15
500
600400
09:41:30
36.3
100
600400
09:42:20
35.9
200
600400
09:42:40
36.5
800
600400
09:43:10
37.15
600
600400
09:43:20
36.9
1000
600500
09:40:05
40.1
200
600500
09:40:45
40.2
200
600500
09:41:20
40.25
500
600500
09:42:20
40.15
500
600500
09:42:50
40.1
400
600500
09:43:10
40.05
400
600500
09:43:30
39.95
300
将数据依据 time 和 sym 维度对齐,并且计算每分钟内股价以交易量为权重的加权平均值。结果为一个矩阵。
stockprice=pivot(wavg, [t1.price, t1.volume], minute(t1.time), t1.sym)
stockprice.round(2);
label
600300
600400
600500
09:40m
171.7
36.28
40.15
09:41m
172.41
36.3
40.25
09:42m
175.1
36.38
40.13
09:43m
174.63
36.99
40.01
计算每分钟的股票收益率:
stockreturn = each(ratios, stockprice)-1
stockreturn;
label
600300
600400
600500
09:40m
09:41m
0.004108
0.000459
0.002491
09:42m
0.015602
0.002204
-0.003037
09:43m
-0.002677
0.016871
-0.003006
计算股票收益率的两两相关性:
cross(corr, stockreturn, stockreturn);
label
600300
600400
600500
600300
1
-0.719182
-0.151824
600400
-0.719182
1
-0.577578
600500
-0.151824
-0.577578
1
统计每个股票每分钟内的记录数量:
pivot(count, price, minute(time), sym);
label
600300
600400
600500
09:40m
2
2
2
09:41m
2
1
1
09:42m
1
2
2
09:43m
2
2
2
每个股票每分钟里的最后一条记录:
pivot(last, price, minute(time), sym);
label
600300
600400
600500
09:40m
170.32
36.15
40.2
09:41m
172.55
36.3
40.25
09:42m
175.1
36.5
40.1
09:43m
174.5
36.9
39.95
FILE:references/doc_5899.md
# 分级存储
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db/tiered_storage.html
**来源**: DolphinDB 官方文档
---
分级存储
在数据库领域,分级存储是一种常见的需求。较旧的数据(冷数据)通常不会被用户频繁查询或计算,但是存储在本地会占用大量磁盘资源。DolphinDB
集群模式支持对数据进行分级存储,即将一部分较旧的数据从高速磁盘(如 SSD)转存至较低速的磁盘(如 HDD)或云端(如 S3),从而有效节约资源。
整体逻辑流程可概括为:
热数据(volumes)→ 冷数据(coldVolumes)→ 过期数据(删除)。
DolphinDB 支持通过函数设置数据保留策略和分级存储策略,通过自动或手动的方式触发迁移流程,通过配置项指定冷盘存储目录。
DolphinDB 的数据保留策略
数据的存活时间(TTL, Time to Live)通常用于定义数据记录的有效期限。一旦数据的存活时间超过 TTL,数据库系统将认定此记录过期,并将其删除。
数据保留策略以数据库的分区为单位,即数据库下所有表都遵循相同的数据保留策略,且要求分区方案必须包含 DATE 类型或 DATEHOUR 类型。
DolphinDB 通过
setRetentionPolicy
函数设置数据的保留时间。系统会根据当前的机器时间,保留时间戳在最近保留时间范围内的数据,并删除超过保留期限
10 天之内的数据。
注:
数据保留策略比较的是系统的机器时间与数据分区字段的时间,而非数据写入的时间。
DolphinDB 的分级存储策略
DolphinDB 的分级存储策略以数据库的分区为单位,即数据库下所有表都遵循相同的分级存储策略。
DolphinDB 通过
setRetentionPolicy
函数设置热数据的保留时间。系统会根据当前的机器时间,保留规定的保留时间范围内的热数据。超过该保留时间 10
天内的热数据,系统会将其作为冷数据转移存储。
注:
分级存储策略比较的是系统的机器时间与数据分区字段的时间,而非数据写入的时间。
数据迁移机制
分级存储以分区为单位,将每个节点的分区副本迁移到低速磁盘或者 S3 对象存储中。数据迁移内部的大致流程:
用户使用
setRetentionPolicy
函数设置
hoursToColdVolume
来配置热数据的保留时间。
DolphinDB 后台线程根据时间分区检查需要被迁移的数据,创建数据迁移任务。
执行迁移任务,拷贝对应的数据文件到本地路径,或使用 AWS S3 插件多线程上传数据到 S3 路径。在迁移时,分区会暂时不可用。
修改已迁移分区的元数据,更新分区路径,修改分区权限为
READ_ONLY
,即可以使用
select
语句进行查询,但是不能使用
update
,
delete
,
append!
等语句进行更新、删除或写入。
自动数据迁移触发机制
使用
setRetentionPolicy
函数设置好
hoursToColdVolume
后,DolphinDB 会使用后台工作线程,每隔1小时以分区为单位检查部分数据库在
[当前时间 - hoursToColdVolume - 10天,当前时间 -
hoursToColdVolume)
范围内是否存在需要被迁移的数据,如果存在,则触发数据迁移,生成对应的数据迁移任务。由于每次只检查并触发部分数据库的数据迁移,可以有效减少迁移的压力,提高可用性。
举例来说,假设有两个按时间分区的数据库
dfs://db1
和
dfs://db2
,包含
[2023.02.05, 2023.02.15) 的数据。
hoursToColdVolume
设置为 120h,即保留 5 天内的数据:
在 2023.02.20 某个时间(例如17:00),工作线程可能会将 db1 下 [2023.02.05, 2023.02.15)
分区进行迁移。
在 2023.02.20 某个时间(例如18:00),工作线程可能会将 db2 下 [2023.02.05, 2023.02.15)
分区进行迁移。
手动触发数据迁移
使用
moveHotDataToColdVolume
函数,强制触发将指定范围的数据迁移。
自动触发和手动触发的区别
自动触发和手动触发的区别如下表所示:
区分点
setRetentionPolicy
moveHotDataToColdVolume
触发方式
系统为每个数据库分配固定的检查时间点。当到达每个数据库的检查时间点时,系统会检查库中是否存在需要迁移的数据,若存在,则进行迁移。每天每个数据库仅被检查一次。
强制在当前数据节点触发一次数据迁移。
迁移数据的时间范围
只迁移 10 天的数据,范围为
[当前时间 - hoursToColdVolumes - 10 天,
当前时间 - hoursToColdVolumes)
迁移数据的范围由参数
checkRange
指定,为
[当前时间 -
hoursToColdVolumes - checkRange, 当前时间 -
hoursToColdVolumes)
在实际场景应用分级存储策略时,建议用户在第一次转存大量历史数据时,先通过
setRetentionPolicy
配置合理的自动转存策略,再通过
moveHotDataToColdVolume
进行批量迁移,最后由系统自动迁移冷数据。
可以通过
getRecoveryTaskStatus
函数来查看数据迁移任务的执行状态:
rpc(getControllerAlias(), getRecoveryTaskStatus)
配置项
分级存储的配置项根据存储的数据可分为热数据磁盘卷配置项和冷数据磁盘卷配置项。
热数据磁盘卷配置项包括 volumes,allowVolumeCreation,volumeUsageThreshold
冷数据磁盘卷配置项为 coldVolumes
在使用分级存储前,需要先配置相应的参数:
冷数据磁盘卷配置项 coldVolumes
coldVolumes=file:/{your_local_path},s3://{your_bucket_name}/{s3_path_prefix}
我们使用
coldVolumes
配置项来指定存储冷数据的文件目录。该参数支持配置为本地路径(以”file:/“开头)或者 s3
路径(以”s3://“开头)。也可指定多个路径,路径间用逗号隔开。
例如:
coldVolumes=file://home/mypath/hdd/<ALIAS>,s3://bucket1/data/<ALIAS>
注:
不同数据节点需要配置不同的 coldVolumes
路径,否则可能会造成不同datanode间数据的相互覆盖。这里通过”<ALIAS>”宏定义,让每个datanode将数据放到/home/mypath/hdd/目录下按照节点别名命名的目录中。
如果您配置了S3路径,那么还需要配置 AWS S3 插件,以及S3的AccessKeyId,SecretAccessKey,Region等信息。
pluginDir=plugins //指定节点的插件目录,需要将AWS S3插件放到plugins目录下
preloadModules=plugins::awss3 //系统启动后自动加载AWS S3插件
s3AccessKeyId={your_access_key_id}
s3SecretAccessKey={your_access_screet_key}
s3Region={your_s3_region}
关于配置项的更多细节请参考
功能配置
。
使用示例
配置分级存储策略
假设在上文中,我们已经配置了
coldVolumes
:
coldVolumes=file://home/dolphindb/tiered_store/<ALIAS>
DolphinDB 通过数据的时间列来确定需要迁移的数据,所以需要对应的数据库设置按照时间分区的分区方案。首先,我们先创建一个时间列
VALUE
分区的数据库,并写入最近十五天的数据:
//创建一个按照时间列VALUE分区的数据库
db = database(directory="dfs://db1", partitionType=VALUE, partitionScheme=(date(now()) - 14)..date(now()))
//创建一个table,时间列为最近15天
data = table((date(now()) - 14)..date(now()) as cdate, 1..15 as val)
tbl = db.createPartitionedTable(data, "table1", `cdate)
tbl.append!(data)
接下来,我们使用
setRetentionPolicy
函数做如下配置:
超过五天(120h)的数据将会被迁移至冷数据层,超过三十天(720h)的数据将会删除。因为
database
只有一层
VALUE
分区,所以时间列分区维度为 0。
setRetentionPolicy(dbHandle=db, retentionHours=720, retentionDimension=0, hoursToColdVolume=120)
触发数据迁移
设置之后,DolphinDB 会在后台每隔 1 小时检查并迁移范围内的数据。这里为了演示方便,我们使用
moveHotDataToColdVolume
函数来手动触发迁移。
//在每个datanode上执行函数,手动触发迁移
pnodeRun(moveHotDataToColdVolume)
之后,DolphinDB 会发起最近 15 天到最近 7 天的分区的数据迁移任务。DolphinDB 使用原有的 Recovery 机制实现数据的迁移,可以通过
getRecoveryTaskStatus
函数来查看迁移任务的执行状态:
//可以看到创建了最近15天到最近7天的数据迁移任务
rpc(getControllerAlias(), getRecoveryTaskStatus)
可能的结果样式(省略某些列):
TaskId
TaskType
ChunkPath
Source
Dest
Status
2059a13f-00d7-1c9e-a644-7a23ca7bbdc2
LoadRebalance
/db1/20230209/4
NODE0
NODE0
Finish
...
...
...
...
...
...
注意:
如果配置了多个
coldVolumes
,会随机将分区迁往不同的
coldVolumes
。
如果
coldVolumes
是 S3 路径,迁移速度相对于本地路径可能较慢。
在迁移时,分区会暂时不可用。
当迁移任务结束之后,已经被迁移的分区权限变为
READ_ONLY
,我们可以使用
select
语句进行查询,但是不能使用
update
,
delete
,
append!
等语句进行更新、删除或写入。
//查询迁移后的数据
select * from tbl where cdate = date(now()) - 10
//更新迁移后的数据,会报错 "Writing to chunk {ChunkID} is not allowed."
update tbl set val = 0 where cdate = date(now()) - 10
特殊地,我们使用
dropTable
,
dropParititon
,
dropDatabase
等 drop DDL 操作来进行数据的整体删除时,对象存储上对应的分区数据也会被删除。这里不再赘述。
您可以使用
getClusterChunksStatus
函数查看对应分区的权限:
rpc(getControllerAlias(), getClusterChunksStatus)
可能的结果样式(省略某些列):
ChunkId
file
permission
ef23ce84-f455-06b7-6842-c85e46acdaac
/db1/20230216/4
READ_ONLY(已经被迁移的分区)
260ab856-f796-4a87-3d4b-993632fb09d9
/db1/20230223/4
EAD_WRITE(没有被迁移的分区)
FILE:references/doc_5910.md
# getGroupListOfAllClusters
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getGroupListOfAllClusters.html
**来源**: DolphinDB 官方文档
---
getGroupListOfAllClusters
语法
getGroupListOfAllClusters()
详情
查询多集群系统中所有集群的用户组信息。只能由管理员在 MoM(Master of Master,管理集群)上执行该函数。
参数
无
返回值
返回一个字典,其中:
key:集群名称。
value:用户组名称列表。
例子
getGroupListOfAllClusters()
/* Output:
masterOfMaster->["group1"]
MoMSender->["group2"]
*/
FILE:references/doc_5915.md
# getClusterChunksStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getClusterChunksStatus.html
**来源**: DolphinDB 官方文档
---
getClusterChunksStatus
语法
getClusterChunksStatus()
详情
应用在控制节点上,返回集群中所有 chunk(包括 file chunk 和 tablet chunk)的元数据信息。可以查看
chunk 在集群中数据节点上的分布。
返回值
返回一个表,包含以下列
chunkId:chunk 的唯一标识
file:分区路径
size:file chunk 占用磁盘空间,单位为 byte。对于 tablet chunk,返回 0,需要使用 getTabletsMeta
来查看它们实际占用的磁盘空间
version:版本号
vcLength:版本链长度
versionChain:版本链
state:chunk 状态。CONSTRUCTING:正在事务中; RECOVERING:正在 recovery
中;COMPLETE:已经处于事务终止状态
replicas:副本的分布信息,每个副本的格式为
nodeAlias:replicaVersion:corrupted:inResolution:timestamp:volumeID
,多个副本之间使用逗号分隔。
replicaCount:副本数
lastUpdated:上一次更新的时间戳。请注意,server 从 2.00.1 版本才开始支持该字段,因此获取已经存在的由 2.00.1 之前的
server 创建的 chunk 元数据信息时,该字段将返回空值。
permission:CHUNK 的权限。CHUNK 的权限分为 READ_ONLY 以及
READ_WRITE(默认权限)两类。正在进行迁移的分区,或存储在 s3 的分区权限均为 READ_ONLY
对于 READ_ONLY 权限的分区:
(1) 不能追加或更新数据,并只能通过调用
drop
类函数进行删除,且遵从事务的原则。(注意:存储在 s3
的分区不支持事务)。
(2) 不能对其进行 recovery, rebalance
以及 TSDB 引擎的 level file
合并操作
。
例子
rpc(getControllerAlias(), getClusterChunksStatus);
chunkId
file
size
version
vcLength
versionChain
state
replicas
replicaCount
lastUpdated
permission
092d5e12-e595-6f...
/testDB/pt2.tbl
49
1
1
2052:49:1 ->
COMPLETE
P1-node1:1:0,P2-...
2
2022.03.31T18:09:41.138
READ_WRITE
42936e31-8be0-fa...
/testDB/9/i
0
2
2
2053:0:2 -> 2051...
COMPLETE
P3-node1:2:0,P1-...
2
2022.03.31T18:09:41.138
READ_WRITE
d31e6b47-18f0-37...
/testDB/7/i
0
2
2
2053:0:2 -> 2051...
COMPLETE
P1-node1:2:0,P2-...
2
2022.03.31T18:09:41.138
READ_WRITE
647a5fd6-cd85-3b...
/testDB/6/i
0
2
2
2053:0:2 -> 2051...
COMPLETE
P1-node1:2:0,P3-...
2
2022.03.31T18:09:41.138
READ_WRITE
8bec6445-bc6d-36...
/testDB/5/i
0
2
2
2053:0:2 -> 2051...
COMPLETE
P2-node1:2:0,P3-...
2
2022.03.31T18:09:41.138
READ_WRITE
ca690ba5-be73-a6...
/testDB/4/i
0
2
2
2053:0:2 -> 2051...
COMPLETE
P3-node1:2:0,P1-...
2
2022.03.31T18:09:41.138
READ_WRITE
FILE:references/doc_5921.md
# businessQuarterBegin
**URL**: https://docs.dolphindb.cn/zh/funcs/b/businessQuarterBegin.html
**来源**: DolphinDB 官方文档
---
businessQuarterBegin
语法
businessQuarterBegin(X, [startingMonth=1], [offset],
[n=1])
详情
返回
X
所在季度的第一个工作日(周一到周五)。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
个季度更新一次。注意,
offset
和
n
须同时指定,且只有当
n
>1 时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
startingMonth
是1到12之间的整数,表示一年的起始月份。默认值是1。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
businessQuarterBegin(2012.06.12);
// output
2012.04.02
businessQuarterBegin(2012.06.12, 3);
// output
2012.06.01
businessQuarterBegin(2012.06.12, 8, 2011.08.01, 3);
// output
2012.05.01
date=2011.04.25+(1..10)*90
time = take(09:30:00, 10)
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
t1;
date
time
sym
qty
price
2011.07.24
09:30:00
MSFT
2200
49.6
2011.10.22
09:30:00
MSFT
1900
29.46
2012.01.20
09:30:00
MSFT
2100
29.52
2012.04.19
09:30:00
MSFT
3200
30.02
2012.07.18
09:30:00
MSFT
6800
174.97
2012.10.16
09:30:00
MSFT
5400
175.23
2013.01.14
09:30:00
MSFT
1300
50.76
2013.04.14
09:30:00
MSFT
2500
50.32
2013.07.13
09:30:00
MSFT
8800
51.29
2013.10.11
09:30:00
MSFT
4500
52.38
select avg(price),sum(qty) from t1 group by businessQuarterBegin(date, 10, 2010.10.01, 2);
businessQuarterBegin_date
avg_price
sum_qty
2011.04.01
49.6
2200
2011.10.03
29.49
4000
2012.04.02
102.495
10000
2012.10.01
112.995
6700
2013.04.01
50.805
11300
2013.10.01
52.38
4500
相关函数:
businessQuarterEnd
,
quarterBegin
,
quarterEnd
FILE:references/doc_5922.md
# 模块
**URL**: https://docs.dolphindb.cn/zh/tutorials/tu_modules.html
**来源**: DolphinDB 官方文档
---
模块
在使用 DolphinDB
的脚本进行开发时,可以创建可复用模块,以封装自定义函数。模块可以将大量函数按目录树结构组织在不同模块中。既可以在系统初始化时预加载模块,也可以在需要使用的时候引入模块。
1. Module(模块)介绍
在 DolphinDB 中,模块是只包含函数定义的脚本文件。它具有以下特点:
模块文件默认保存在 [home]/modules 目录下。
模块文件名的后缀为 .dos("DolphinScript"的缩写)或 .dom("DolphinModule"的缩写)。
模块文件第一行只能使用 module 后接模块名以声明模块,即 module module_name。
模块文件除第一行外,仅可包含模块导入语句与函数定义。
2. 定义模块
2.1. 创建模块目录
所有的模块定义默认存放在 [home]/modules 目录下:
[home] 目录由系统配置参数
home
决定,可以通过
getHomeDir
函数查看。
节点的模块目录由配置参数
moduleDir
来指定,其默认值是相对路径 modules。系统会首先到节点的 home
目录寻找该目录,如果没有找到,会依次在节点的工作目录与可执行文件所在目录寻找。请注意,单节点模式下,这三个目录默认相同。
2.2. 创建模块文件
在 modules 目录下创建以 .dos 为后缀的模块文件,例如 fileLog.dos。模块文件的第一行必须是模块声明语句。例如在 fileLog.dos
中声明模块:
module fileLog
其中 fileLog 是模块名,必须与模块文件(fileLog.dos)的名称一致。
模块文件除第一行外的内容仅可包含函数定义或模块导入语句(如需引用其它模块)。例如,fileLog 模块仅包括向指定日志文件写入日志的函数
appendLog
:
module fileLog
def appendLog(filePath, logText){
f = file(filePath,"a+")
f.writeLine(string(now()) + " : " + logText)
f.close()
}
在模块文件中,
除函数定义、模块声明语句和模块导入语句外,其它代码将被忽略
。
如果需要对模块进行分类,可在 modules 目录下设置多个子目录,以作为不同模块类别的命名空间。例如,现有两个模块 fileUtil 和
dateUtil,它们分别存放于 modules/system/file/fileUtil.dos 与
modules/system/temporal/dateUtil.dos,那么声明语句分别为
module
system::file::fileUtil
与
module
system::temporal::dateUtil
。
2.3. 序列化模块文件
使用 saveModule 函数可以将模块序列化成扩展名为 dom 的二进制文件。将模块序列化为 dom 文件能够增强代码的保密性和安全性。例如,序列化上一节中的
module fileLog:
saveModule("fileLog")
dom 文件会保存至 dos 文件所在的目录。
注意:
如果 dos 文件的内容发生改变,需要重新执行
saveModule
函数来生成新的 dom 文件。可将
saveModule
函数的 overwrite 参数设置为 true 来覆盖已有的 dom
文件。例如:
saveModule("fileLog" , , true)
如果当前模块引用了另一个模块的函数,则在序列化该模块中只会对其依赖模块的名称进行序列化,不会序列化依赖函数的定义。因此,在加载或移动 .dom
文件时,需同时加载或移动其依赖的模块文件。
3. 导入模块
3.1. 使用 use 关键字
使用
use
关键字来导入一个模块。如果导入的模块依赖了其他模块,系统会自动加载其他模块。
注意:
use
关键字导入的模块是会话隔离的,仅对当前会话有效。
自 2.00.12 版本起,use 关键字支持导入后缀为 .dos 的模块文件或 .dom 的二进制文件。
导入模块后,可以通过以下两种方式来使用模块内的自定义函数:
(1) 直接使用模块中的函数:
use fileLog
appendLog("mylog.txt", "test my log")
(2) 指定模块中的函数的命名空间(即在 modules 目录下的完整路径):
use fileLog
fileLog::appendLog("mylog.txt", "test my log")
若导入的不同模块中含有相同名称的函数,则必须通过此种方式调用此类函数。
3.2. 将模块内函数加载为系统内置函数
注意
:该功能在1.20.1及以上版本支持。
3.1节提到,
use
关键字导入的模块是会话隔离的,这在实际使用中会带来一些不便。为了解决这一问题,DolphinDB 支持通过
loadModule
函数或者配置参数
preloadModules
将模块定义的函数加载为系统的内置函数,这样模块对所有会话都是可见的。
模块定义的函数成为内置函数之后,具有以下特点:
用户无法覆盖函数的定义。
如果在
remoteRun
或
rpc
中使用了该函数,系统不会序列化该函数的定义到远程节点。因此远程节点也必须加载该模块,否则系统会抛出无法找到函数的异常。
该函数在系统内存中只有一份,且对所有会话可见。不仅节约了内存,还减少了每个会话加载模块的时间。另外,无需使用
use
关键字导入模块,使得调用模块的代码更加简洁,API 调用模块函数更加方便。
可以通过 .dos 文件或 .dom 文件加载模块。系统会自动到 modules 目录寻找模块文件。如果目录中包含同名的 .dos 文件和 .dom
文件,系统优先加载 .dos 文件。如果加载的是 .dom 文件,则用户无法查看模块内函数的定义。
如果加载的模块中引用了其他模块:
如果加载的是 .dos 文件,则系统在加载时会自动加载其依赖的模块。
如果加载的是 .dom 文件,则必须先加载该模块中所依赖的模块文件。
3.2.1. 通过 loadModule 函数加载
该函数只能在系统的初始化脚本(默认是dolphindb.dos)中使用,不能在命令行或者 GUI 中执行。例如,加载上文“创建模块文件”节中的模块
fileLog,在 dolphindb.dos 文件末尾加上:
loadModule("fileLog")
通过此方法加载模块后,在调用模块函数时必须指定函数的命名空间(即在 modules 目录下的完整路径):
fileLog::appendLog("mylog.txt", "test my log")
3.2.2. 通过配置参数 preloadModules 加载
对单机版,该参数在 dolphindb.cfg 中配置。对集群版,需要为 controller 和 datanode 加载相同的模块。最简单的方法在
controller.cfg 和 cluster.cfg 中配置
preloadModules
参数。
例如:
preloadModules=fileLog
如果需要加载多个模块,使用逗号分隔。
3.2.3. 与函数视图(function view)的区别
通过
loadModule
或
preloadModules
生成的内置函数与 function view
对比,有以下区别:
dom 模块中的函数定义对所有人均不可见,包括系统管理员和 owner,保密性更高。function view 的定义对 admin 和
owner 以及授权用户可见。
序列化一个模块时,不会序列化依赖的函数,只会序列化依赖的模块名称。而 function view
序列化时,会序列化所有的依赖,以及依赖的依赖,实现 self-contained。
function view 和模块的应用场景有所不同。function view
一般用于跟数据库相关的数据访问。模块中的函数一般是通用的处理逻辑或算法。function view 可能会调用模块中的函数,但是模块中的函数一般不调用
function view。
4. 模块分类
4.1. 声明模块类别命名空间
如果需要对模块进行分类,可在 modules 目录下设置多个子目录,以作为不同模块类别的命名空间。例如,现有两个模块 fileLog 和
dateUtil,它们分别存放于 modules/system/log/fileLog.dos 与
modules/system/temperal/dateUtil.dos。这两个模块相应的声明语句分别为
module
system::log::fileLog
与
module
system::temporal::dateUtil
。
4.2. 调用命名空间模块
在对模块进行序列化(saveModule)、通过
use
语句导入、以及通过
loadModule
函数或
preloadModules
配置参数加载时,均需指定完整路径。例如,导入上一节中的 fileLog 模块:
use system::log::fileLog
可以通过以下两种方法调用模块函数:
直接调用其中函数:
appendLog("mylog.txt", "test my log")
使用全路径调用其中函数:
system::log::fileLog::appendLog("mylog.txt", "test my log")
5. GUI中远程调试模块
当 GUI 所在机器与 DolphinDB 服务器不是同一台机器时,在 GUI 中编辑的模块代码,需要先上传到远程服务器的 [home]/modules 目录,才能通过
use
语句调用模块。其中[home]表示DolphinDB 的主目录,通过配置项 home 指定。
DolphinDB GUI 从0.99.2版本开始提供了远程同步模块的功能,具体用法如下:
指定远程服务器路径:
添加远程服务器(Server->Add Server)时,指定
Remote Directory
目录:
若上步中未指定
Remote Directory
,可通过 Server->Edit Server
进行添加:
点击下图
Synchronize to server
将 modules 目录下的所有文件和子目录同步到步骤1设置的
Remote Directory
下。
假设
Remote Directory
设置为'[home]/modules',本地需要同步的文件名是
"C:/users/usr1/Project/scripts/test.dos"。同步的时候,系统会在远端自动创建目录和相应文件
'[home]/modules/Project/scripts/test.dos'。
同步完成后,就可以在远程服务器上执行
use
语句导入模块。需要注意的是,在使用模块前,需要参考
上文“创建模块目录”
设置模块路径。
6. 注意事项
6.1. 同名函数定义规则
不同模块中可以定义相同名字的函数。如果使用全路径调用函数,可以通过模块命名空间来区分函数。
如果直接调用函数:
若只有一个已导入模块包含该函数,DolphinDB 会调用该模块的函数。
若多个已导入模块包含该函数,会抛出异常:
Modules [Module1] and [Module2] contain function [functionName].
Please use module name to qualify the function.
若所有已导入的模块中均不包含该函数,DolphinDB 会在系统内置函数中搜索该函数。如果内置函数中也没有该函数,将抛出函数未定义的异常。
若已导入模块中某函数与某自定义函数重名,调用时需要通过命名空间来区分函数。自定义函数和内置函数的默认命名空间为根目录,用两个冒号表示。
下例中,首先创建自定义函数
myfunc
:
login("admin","123456")
def myfunc(){
return 1
}
addFunctionView(myfunc)
然后定义模块sys,其中含有函数
myfunc
。
module sys
def myfunc(){
return 3
}
若要调用模块sys中的函数
myfunc
,可在使用
use sys
之后,使用:
sys::myfunc()
或:
myfunc()
若要使用模块外的自定义函数,可使用:
::myfunc()
6.2. 刷新模块定义
通过
use
导入模块时,模块函数被加载到缓存中,后续调用函数时,都将从缓存中进行调用。若需要在测试过程中快速反复修改模块代码并刷新定义,可采用以下方法:
在模块文件修改后执行全部的模块代码。这种方法仅对当前会话有效。
调用命令 clearCachedModules,强制清除缓存的模块。当缓存清除后,执行 use 语句时,会重新从文件加载模块,无需重启节点。只有
admin 才有权限执行这个命令。
6.3. 模块间互相调用
模块之间可以单向引用,例如允许模块a引用b,b引用c。
模块之间不支持交叉引用,例如不允许模块a引用b,模块b又引用a。
FILE:references/doc_5928.md
# mTopRange
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mtoprange.html
**来源**: DolphinDB 官方文档
---
mTopRange
语法
mTopRange(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内,统计每个元素 Xi 左侧相邻且连续小于它的元素个数。NULL 被视为最小值。
若
X
是矩阵,在每列内进行上述计算。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
x = [NULL, 3.1, NULL, 3.0, 2.9, 2.8, 3.1, NULL, 3.2]
mTopRange(x, window=3)
// output: [,,0,1,0,0,2,0,2]
mTopRange(x, window=3, minPeriods=1)
// output: [,1,0,1,0,0,2,0,2]
x = [NULL, NULL, NULL, NULL, NULL, 2, NULL, NULL, 3.2]
date = [0, 1, 2, 3, 7, 8, 9, 10, 11] + 2020.01.01
X = indexedSeries(date, x)
mTopRange(X, 3d)
#0
2020.01.01
2020.01.02
2020.01.03
2020.01.04
2020.01.08
2020.01.09
1
2020.01.10
0
2020.01.11
0
2020.01.12
2
m = matrix(1 2 3 NULL, 1 2 NULL 3, 1 3 NULL NULL, 1 2 3 4)
mTopRange(m, 2)
#0
#1
#2
#3
1
1
1
1
1
0
0
1
0
1
1
FILE:references/doc_5936.md
# copyReplicas
**URL**: https://docs.dolphindb.cn/zh/funcs/c/copyReplicas.html
**来源**: DolphinDB 官方文档
---
copyReplicas
语法
copyReplicas(srcNode, destNode, chunkId)
详情
把源节点上的一个或多个 chunk 的副本复制到目标节点。如果目标节点上已经存在该 chunk,那么系统将忽略本次操作。该命令只能由管理员在控制节点上执行。
通过
getRecoveryTaskStatus
函数可以查看任务状态。
参数
srcNode
是一个字符串,表示源节点的别名。
destNode
是一个字符串,表示目标节点的别名。
chunkId
是字符串标量或向量,表示 chunk 的 ID。
返回值
无。
例子
把 "node1" 上所有 chunk 的副本复制到 "node2"。
chunkIds=exec chunkId from pnodeRun(getChunksMeta) where node="node1"
copyReplicas("node1", "node2", string(chunkIds));
FILE:references/doc_5938.md
# rowSum
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowSum.html
**来源**: DolphinDB 官方文档
---
rowSum
语法
rowSum(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行元素求和操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL])
rowSum(m);
// output
[10.9,9.4,7.4]
t1=table(1..5 as x, 6..10 as y)
t2=table(5..1 as a, 10..6 as b);
rowSum(t1);
// output
[7,9,11,13,15]
rowSum(t1[`x], t2, 1 1 2 2 2);
// output
[17,16,16,15,14]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2)
select sym,rowSum(price1,price2) as priceSum from t;
sym
priceSum
AAPL
224.83
MS
80.22
IBM
79.84
IBM
81.31
C
201.2
相关函数:
sum
FILE:references/doc_5941.md
# getRunningQueries
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getRunningQueries.html
**来源**: DolphinDB 官方文档
---
getRunningQueries
语法
getRunningQueries()
详情
获取本地节点上正在执行的查询任务的描述信息。
使用该函数之前,必须设定参数
perfMonitoring
= 1 来启用性能监控。
参数
无
返回值
返回一张表,包含以下字段:
参数
含义
userID
用户 ID 。
sessionID
发起查询的会话 ID。
jobID
系统中查询任务的唯一标识。
rootID
当前任务所属根任务的 jobID。
level
任务的级别。根任务的 level 为 0,其分解的子任务 level 为 1,该子任务分解的子任务
level 为 2,以此类推。
startTime
查询任务开始时间,为 NANOTIMESTAMP 类型。
endTime
查询任务结束时间,为 NANOTIMESTAMP 类型。
jobDesc
查询语句描述。
errorMsg
报错信息。
remoteIP
发起查询的客户端 IP。
例子
getRunningQueries();
userID
sessionID
jobID
rootID
level
startTime
endTime
jobDesc
errorMsg
remoteIP
admin
738481026
88e738a8-a749-4dcb-9cfe-740df2d9ce7d
88e738a8-a749-4dcb-9cfe-740df2d9ce7d
0
2019.02.07T19:02:26.809905612
select count(*) as count from pt
192.168.1.106
FILE:references/doc_595.md
# mwsumTopN
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mwsumTopN.html
**来源**: DolphinDB 官方文档
---
mwsumTopN
语法
mwsumTopN(X, Y, S, window, top, [ascending=true],
[tiesMethod='oldest'])
参数说明和窗口计算规则请参考:
mTopN
详情
在给定长度(以元素个数衡量)的滑动窗口内,根据
ascending
指定的排序方式将
X
和
Y
按照
S
进行稳定排序后,取前
top
个元素,然后计算
Y
和
X
的内积。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
x = NULL 3 8 4 0 7 4
y = 2 3 1 7 3 6 1
s = 5 NULL 8 9 9 4 4
mwsumTopN(x, y, s, 4, 3)
// output: [,,8,36,36,78,74]
s2=2021.01.01 2021.02.03 2021.01.23 2021.04.06 2021.12.29 2021.04.16 2021.10.29
mwsumTopN(x, y, s2, 3, 2)
// output: [ , 9, 8, 17, 36, 70, 46]
x1 = matrix(x, 4 3 6 2 3 1 3)
y1=matrix(3 7 9 3 2 4 6, y)
s1=matrix(2 3 1 7 3 NULL 1, s)
mwsumTopN(x1,y1,s1,4,3)
#1
#2
8
21
8
93
14
93
28
93
29
84
26
36
23
mwsumTopN(x1, y1, s, 4, 3)
#1
#2
8
8
72
14
84
28
84
29
112
26
64
23
n = 3000
ids = 1..3000
dates = take(2021.01.01..2021.10.01,n)
prices = rand(1000,n)
vals = rand(1000,n)
t = table(ids as id,dates as date,prices as price,vals as val)
dbName = "dfs://test_mwsumTopN_2"
if(existsDatabase(dbName))dropDB(dbName)
db = database(dbName,VALUE,1..5000)
pt = db.createPartitionedTable(t,"pt",`id).append!(t)
select mwsumTopN(price, val, id, 10, 5, true) from pt where date>2021.05.01
相关函数:
mwsum
FILE:references/doc_5955.md
# poly1d
**URL**: https://docs.dolphindb.cn/zh/funcs/p/poly1d.html
**来源**: DolphinDB 官方文档
---
poly1d
是
polyPredict
的别名。
FILE:references/doc_5956.md
# getClusterDFSTables
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getClusterDFSTables.html
**来源**: DolphinDB 官方文档
---
getClusterDFSTables
语法
getClusterDFSTables()
详情
返回集群中的分布式表。
2.00.9
版本起,
管理员可以返回当前集群中任一分布式表;
其他用户执行时仅返回:
(1)拥有 DB_OWNER, DB_MANAGE, DB_READ, DB_WRITE, DB_INSERT, DB_UPDATE, DB_DELETE
权限的数据库所对应的分布式表;
(2)拥有 TABLE_READ, TABLE_WRITE, TABLE_INSERT, TABLE_UPDATE, TABLE_DELETE
权限的分布式表。
2.00.10.2 版本起,该函数由拥有 DBOBJ_CREATE 权限的用户执行时,还会返回其创建的分布式表。
参数
无
返回值
字符串向量。
例子
getClusterDFSTables()
返回:["dfs://demohash/pt","dfs://myDataYesDB/tick","dfs://testDB/pt1","dfs://testDB/pt2"]
FILE:references/doc_5961.md
# getCompletedQueries
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getCompletedQueries.html
**来源**: DolphinDB 官方文档
---
getCompletedQueries
语法
getCompletedQueries([top])
详情
查询本地节点上最近完成的
top
条查询分布式数据库的 SQL 语句的描述信息。
本函数只可由系统管理员执行。在使用该函数之前,必须设定配置参数
perfMonitoring
= 1 以启动性能监控。
参数
top
是一个正整数。可选参数,默认值为 10。
返回值
返回一个表,包含以下字段:
参数
含义
userID
用户 ID 。
sessionID
发起查询的会话 ID。
jobID
系统中查询任务的唯一标识。
rootID
当前任务所属根任务的 jobID。
level
任务的级别。根任务的 level 为 0,其分解的子任务 level 为 1,该子任务分解的子任务
level 为 2,以此类推。
startTime
查询任务开始时间,为 NANOTIMESTAMP 类型。
endTime
查询任务结束时间,为 NANOTIMESTAMP 类型。
jobDesc
查询语句描述。
errorMsg
报错信息。
remoteIP
发起查询的客户端 IP。
例子
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x)
db=database("dfs://rangedb16", RANGE, 0 5 10)
pt = db.createPartitionedTable(t, `pt, `ID)
pt.append!(t)
t1 = select count(x) from pt;
t2 = select * from pt where ID=1;
t3 = select * from pt where ID=5;
getCompletedQueries()
userID
sessionID
jobID
rootID
level
startTime
endTime
jobDesc
errorMsg
remoteIP
admin
1166953221
4be0f403-a62d-7bae-4ded-43938cc2b4e9
4be0f403-a62d-7bae-4ded-43938cc2b4e9
0
2021.06.28T18:05:34.366483000
2021.06.28T18:05:34.372467000
select ID,x from pt where ID == 1
127.0.0.1
admin
1166953221
9e9132c5-60c2-b3ab-41da-039ad2dcb6ff
4be0f403-a62d-7bae-4ded-43938cc2b4e9
0
2021.06.28T18:05:34.366483000
2021.06.28T18:05:34.372467000
select ID,x from pt where ID == 5
127.0.0.1
admin
1166953221
98275891-9c9b-948e-425c-6c3083713d84
98275891-9c9b-948e-425c-6c3083713d84
0
2021.06.28T18:05:34.344272000
2021.06.28T18:05:34.359201000
select count(x) as count_x from pt
127.0.0.1
getCompletedQueries().keys()
返回:["userID","sessionID","jobID","rootID","level","startTime","endTime","jobDesc","errorMsg","remoteIP"]
getCompletedQueries().ErrorMsg
返回:[,,]
getCompletedQueries().jobDesc
返回:["select ID,x from pt where ID == 5","select ID,x from pt where ID == 1","select
count(x) as count_x from pt"]
FILE:references/doc_5965.md
# tan
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tan.html
**来源**: DolphinDB 官方文档
---
tan
语法
tan(X)
详情
返回
X
的正切。
参数
X
可以是标量、向量或矩阵。
返回值
DOUBLE 类型,数据形式同
X
。
例子
tan(0 1 2);
// output
[0,1.557408,-2.185040]
相关函数:
asin
,
acos
,
atan
,
sin
,
cos
,
asinh
,
acosh
,
atanh
,
sinh
,
cosh
,
tanh
FILE:references/doc_5975.md
# rdp
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rdp.html
**来源**: DolphinDB 官方文档
---
rdp
语法
rdp(pointList, epsilon)
详情
使用 RDP(Ramer-Douglas-Peucker) 矢量压缩算法对 POINT 类型向量进行压缩。
参数
pointList
是一个 POINT 类型向量,且不能包含空元素。
epsilon
是一个非负的 DOUBLE 类型的标量,表示压缩阈值。
返回值
POINT 类型向量。
例子
pt = point(1 2 3 4, 1 2 3 4)
rdp(pt, 0.1)
// output
[(1.0, 1.0), (4.0, 4.0)]
pt = point(1 2 3 4, 1 3 3 4)
rdp(pt, 0.1)
// output
[(1.0, 1.0), (2.0, 3.0), (3.0, 3.0), (4.0, 4.0)]
temp = array(POINT,0)
n=90000
x_data = rand(10.0,n)
y_data = rand(10.0,n)
index=0
do{
temp.append!(point(x_data[index], y_data[index]))
index += 1
}while(index<n)
s=rdp(temp, 0.8)
print(s.size())
// output
82002
print(temp.size())
// output
90000
FILE:references/doc_5990.md
# t3
**URL**: https://docs.dolphindb.cn/zh/funcs/t/t3.html
**来源**: DolphinDB 官方文档
---
t3
语法
t3(X, window, [vfactor=1.0])
TA-lib 系列函数参数说明和窗口计算规则请参考:
TAlib
详情
在给定长度(以元素个数衡量)的滑动窗口内,计算
X
的三重指数移动平均(Triple Exponential
Moving Average)。
其计算公式为:
参数
vfactor
是一个0-1之间的浮点数。 默认值是1.0。
返回值
DOUBLE 类型,数据形式同
X
。
例子
x=12.1 12.2 12.6 12.8 11.9 11.6 11.2 16.9 55.6 5.6 3.3 66 6 57
t3(x, 3, 0.5);
// output
[,,,,,,,,,,,,26.8447,33.209]
x=matrix(12.1 12.2 12.6 12.8 11.9 11.6 11.2 15.7 18.6 13.2 19.6 20.3 22.4 11, 14 15 18 19 21 12 10 6 5.5 7 11 16 15 9.9)
t3(x, 3, 0.8);
col1
col2
20.7584
13.4706
18.242
13.2408
相关函数:
tema
FILE:references/doc_5991.md
# enlist
**URL**: https://docs.dolphindb.cn/zh/funcs/e/enlist.html
**来源**: DolphinDB 官方文档
---
enlist
语法
enlist(X)
详情
X
是标量时,返回一个向量。
X
是字典时,
若键为字符串,返回一个单行的表。
若键为非字符串,返回一个元组。
X
是向量、元组等其他数据形式时,返回一个元组。
参数
X
任意数据形式。
例子
enlist(1)
// output
[1]
enlist(`aaa)
// output
["aaa"]
enlist([2022.01.01,2022.01.02,2022.01.03])
// output
([2022.01.01,2022.01.02,2022.01.03])
enlist(["a",2,3])
// output
(("a",2,3))
a = array(INT[], 0, 10).append!([1 2 3, 4 5,6 7 8, 9 NULL])
enlist(a)
// output
([[1,2,3],[4,5],[6,7,8],[9,00i]])
d1=dict(`a`b`c, (1, 2 3, 4))
enlist(d1)
c
b
a
4
[2, 3]
1
value =(-2 2 3, 0 1, 2.2 -3 1)
d2 = dict(1 2 3, value, true)
print enlist(d2)
/* output;
(1->[-2,2,3]
2->[0,1]
3->[2.2,-3,1]
)
*/
FILE:references/doc_5996.md
# adaBoostRegressor
**URL**: https://docs.dolphindb.cn/zh/funcs/a/adaBoostRegressor.html
**来源**: DolphinDB 官方文档
---
adaBoostRegressor
语法
adaBoostRegressor(ds, yColName, xColNames,
[maxFeatures=0], [numTrees=10], [numBins=32], [maxDepth=10],
[minImpurityDecrease=0.0], [learningRate=0.1], [loss='linear'],
[randomSeed])
详情
进行 AdaBoost 回归。
生成的模型可以作为
predict
函数的输入
参数
ds
是数据源,通常用
sqlDS
函数生成。
yColName
是字符串,表示数据源中作为因变量(所属分类)的列名。
xColNames
是字符串标量或向量,表示数据源中作为自变量的列名。
numClasses
是正整数,表示分类数目。y列的取值必须是[0, numClasses)之间的整数。
maxFeatures
是一个整数或浮点数,表示一次分裂节点选取的特征个数或比例。默认值是0。
如果
maxFeatures
为正整数,则在一次分裂时选取
maxFeatures
个特征。
如果
maxFeatures
=0 ,则在一次分裂时选取全部特征。
如果
maxFeatures
是一个0和1之间的浮点数,则在一次分裂时选取
int(特征列数量*maxFeatures)个特征。
numTrees
是正整数,表示产生树的最大个数,即停止提升时的最大迭代次数。如果能够完美训练,学习会提前中止。默认值为10。
numBins
是正整数,表示离散化连续特征时的桶数。默认值为32。增加
numBins
会使算法考虑更多的分裂节点的决策值,产生更好的分裂结果,但也会提高计算量和通讯量。
maxDepth
是正整数,表示树的最大深度。默认值为10。
minImpurityDecrease
是浮点数,如果分裂产生的基尼指数纯度减少值大于或等于这个值,节点会继续分裂。
learningRate
是正浮点数,表示迭代过程中的每个分类器对下一个分类器的样本权重的影响。
algorithm
是一个字符串,表示所使用的算法,可以取值 "SAMME.R" 或 "SAMME"。默认值为 "SAMME.R"。
loss
是一个字符串,表示在提升迭代时,更新样本权重时所用的损失函数,可以取值 "linear", "square" 或
"exponential"。默认值为 "linear"。
randomSeed
是随机数生成器使用的种子。
返回值
返回结果是字典,包含以下 key:predict, minImpurityDecrease, maxDepth, numBins, numTrees, maxFeatures, model, modelName, xColNames, learningRate,loss. 其中 model 是一个元组,保存了训练生成的树;modelName 为 "AdaBoost Regressor"。
例子
用模拟数据训练一个 AdaBoost 分类模型
n=10
x1 = rand(1.0, n)
x2 = rand(1.0, n)
b0 = 1
b1 = 1
b2 = -2
err = norm(0, 0.2, n)
y = b0 + b1 * x1 + b2 * x2 + err
t = table(y, x1, x2)
model = adaBoostRegressor(sqlDS(<select * from t>), `y, `x1`x2);
把模型用于预测
t1 = table(0 0.4 0.7 1 as x1, 0.9 0.2 0.1 0 as x2)
predict(model, t1);
保存模型到磁盘及加载保存的模型
saveModel(model, "C:/DolphinDB/data/regressionModel.bin")
loadModel("C:/DolphinDB/data/regressionModel.bin");
相关函数:
adaBoostClassifier
,
randomForestClassifier
,
randomForestRegressor
FILE:references/doc_6000.md
# prod
**URL**: https://docs.dolphindb.cn/zh/funcs/p/prod.html
**来源**: DolphinDB 官方文档
---
prod
语法
prod(X)
详情
若
X
为向量,返回
X
中所有元素的乘积。
若
X
为矩阵,计算每列中所有元素的乘积,返回一个向量。
若
X
为表,计算每列中所有元素的乘积,返回一个表。
与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
可以是标量、向量、矩阵或表。
返回值
数值型标量、向量、矩阵或表。
例子
prod(1 2 NULL 3);
// output
6
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
prod(m);
// output
[6,120]
FILE:references/doc_6013.md
# prevState
**URL**: https://docs.dolphindb.cn/zh/funcs/p/prevState.html
**来源**: DolphinDB 官方文档
---
prevState
语法
prevState(X)
详情
X
中连续且相同的元素标记为同一状态,空值无状态。每个元素的状态等于其元素值。对于
X
中的每一个元素,返回当前状态的上一个状态。若当前元素为空,则返回上一个邻近状态。
X
是矩阵时,则在矩阵每一列进行上述计算。
参数
X
时间类型,布尔类型或者数值型的向量/矩阵。
返回值
一个向量或矩阵,数据类型同
X
。
例子
X = [1, 2.2, NULL, 2.2, 2.3, 1, 1.2]
prev(X)
// output
[,1,2.2,,2.2,2.3,1]
prevState(X)
// output
[,1,2.2,2.2,2.2,2.3,1]
X = matrix([1.0, 1.1, 1.0, 0.9], [NULL, 1.3, 2.5, 5.5], [5.5, 4.2, 1.6, 1.8])
prevState(X)
#0
#1
#2
1
5.5
1.1
1.3
4.2
1
2.5
1.6
相关函数:
nextState
FILE:references/doc_6023.md
# lowerBound
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lowerbound.html
**来源**: DolphinDB 官方文档
---
lowerBound
语法
lowerBound(X,Y)
详情
对于
Y
中的每个元素 y,该函数返回
X
中第一个不小于 y 的元素下标。如果没有找到,则返回
X
的长度。
参数
X
递增的向量、索引序列、索引矩阵
Y
标量、向量、数组向量、元组、矩阵、字典、表
返回值
返回数值类型的结果,形式与
Y
一致。
例子
在以下例子中,X 中的部分元素大于或等于 Y 中的部分元素:
X = [1,3,5];
Y = [5,6,7];
Z = lowerBound(X,Y);
Z
// output: [2,3,3]
index = [2023.05.04, 2023.05.06, 2023.05.07, 2023.05.10]
s = indexedSeries(index, 1..4)
y=[2023.05.04, 2023.05.06, 2023.05.09]
lowerBound(s,y)
label
#0
2023.05.04
1
2023.05.06
2
2023.05.09
4
FILE:references/doc_6029.md
# randBinomial
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randBinomial.html
**来源**: DolphinDB 官方文档
---
randBinomial
语法
randBinomial(trials, p, count)
详情
生成指定个数的二项分布随机数。
参数
trials
是正整数。
p
是0到1之间的浮点数。
trials
和
p
是形状参数。
count
是正整数,表示生成的随机数个数。
返回值
长度为
count
的 DOUBLE 类型向量。
例子
randBinomial(2, 0.627, 2);
// output
[1, 1]
FILE:references/doc_603.md
# createTimeSeriesEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createTimeSeriesEngine.html
**来源**: DolphinDB 官方文档
---
createTimeSeriesEngine
语法
createTimeSeriesEngine(name, windowSize, step, metrics,
dummyTable, outputTable, [timeColumn], [useSystemTime=false], [keyColumn],
[garbageSize], [updateTime], [useWindowStartTime], [roundTime=true],
[snapshotDir], [snapshotIntervalInMsgCount], [fill='none'], [forceTriggerTime],
[raftGroup], [keyPurgeFreqInSec=-1], [closed='left'],
[outputElapsedMicroseconds=false], [subWindow], [parallelism=1],
[acceptedDelay=0], [outputHandler], [msgAsTable=false])
别名:
createTimeSeriesAggregator
详情
创建流数据时间序列引擎,以实现基于时间的滑动窗口或滚动窗口进行实时计算。
时序引擎的聚合计算的算子分为增量计算和全量计算两种。增量计算算子不会保留历史数据,每次有数据进来就会进行增量计算;而全量计算算子(例如自定义的聚合函数,或未经优化的内置聚合函数,亦或是嵌套了状态函数的函数)会保留窗口内完整的数据,待触发输出时进行全量计算。
时序引擎对以下聚合计算算子进行了优化,实现了增量计算,显著提升了性能:corr, covar, first, last, max,
med, min, percentile, quantile, std, var, sum, sum2, sum3, sum4, wavg, wsum, count,
firstNot, ifirstNot, lastNot, ilastNot, imax, imin, nunique, prod, sem, mode,
searchK, beta, avg。
更多流数据引擎的应用场景说明可以参考
流计算引擎
。
窗口
窗口边界规整:对起始窗口左边界进行规整。(详情请参考
step
和
roundTime
的参数说明以及
规整规则表
)
窗口确定:
windowSize
确定窗口长度。
closed
确定窗口左闭右开或左开右闭。
step
确定滑动的步长。
其中,
windowSize
与
step
的单位取决于
useSystemTime
参数。若
useSystemTime
= true,
windowSize
与
step
的单位是毫秒。若
useSystemTime
=
false,
windowSize
与
step
的单位同
timeColumn
列的精度一致。
窗口截取:
useSystemTime
参数决定了如何截取窗口,可以基于数据的时间列,亦可以基于数据注入系统的时间进行截取。
计算
乱序数据处理规则:
若指定了
timeColumn
,则
timeColumn
的时间必须递增;若同时指定了
keyColumn
,则按照分组分别进行滑动窗口计算,
timeColumn
在每组内的时间必须递增。否则,时间乱序的数据在计算中会被直接丢弃。
若希望接收指定范围内的乱序数据,可以设置
acceptedDelay
,详见
acceptedDelay
参数说明。
触发规则:若指定了
timeColumn
,当前窗口的计算将由该窗口结束后收到的第一条数据触发;若设置
useSystemTime
=
true,窗口结束后会自动触发计算。
强制触发规则:对长时间未触发计算的窗口数据,可以通过设置
updateTime
或
forceTriggerTime
强制触发计算。具体规则请参考参数说明。
窗口填充规则:未指定
fill
或指定
fill
= "none"
时,只会输出计算结果不为空的窗口;若指定了
fill
,则会输出所有窗口,且根据
fill
规则对结果为空的窗口进行填充。
其它功能
支持数据/状态清理:清理引擎中堆积的数据和不再需要的状态信息。(详情请参考
garbageSize
和
keyPurgeFreqInSec
的参数说明)
快照机制:启用快照机制之后,系统若出现异常,可及时将流数据引擎恢复到最新的快照状态。(详情请参考
snapshotDir
和
snapshotIntervalInMsgCount
的参数说明)
流数据引擎高可用:若要启用引擎高可用,需在订阅端 raft 组的 leader 节点创建引擎并通过
raftGroup
参数开启高可用。开启高可用后,当 leader 节点宕机时,会自动切换新 leader
节点重新订阅流数据表。(详情请参考
raftGroup
的参数说明)
参数
name
字符串标量,表示时间序列引擎的名称,作为其在一个数据节点/计算节点上的唯一标识。可包含字母,数字和下划线,但必须以字母开头。
windowSize
正整数标量或向量,表示滑动窗口的长度。
step
正整数标量,表示滑动窗口移动的步长。
windowSize
必须是
step
的整数倍,否则会抛出异常。
windowSize
和
step
的单位与
useSystemTime
有关:
若
useSystemTime
为 true,则
windowSize
和
step
的单位为毫秒。
若
useSystemTime
为 false,则
windowSize
和
step
的单位与
timeColumn
的时间精度一致。
metrics
以元代码的格式表示计算指标,支持输入元组。有关元代码的更多信息可参考
元编程
。
计算指标可以是一个或多个系统内置或用户自定义的聚合函数(使用 defg 关键字定义),如
<[sum(volume), avg(price)]>;可以对聚合结果使用表达式,如
<[avg(price1)-avg(price2)]>;也可对列与列的计算结果进行聚合计算,如
<[std(price1-price2)]>。
metrics
内支持调用具有多个返回值的函数,例如 <func(price) as
`col1`col2>(可不指定列名)。
支持指定为一个常量标量或向量,例如 <1>,<[1, 2, 3]> 。当指定为常量向量时,对应的输出列必须设置为数组向量类型。
若
windowSize
为向量,
windowSize
每个值可对应
metrics
中多个计算指标。例如,
windowSize
为[10,20]时,metrics可为
(<[min(volume), max(volume)]>, <sum(volume)>)。
metrics
也可以嵌套输入元组向量。例如:[[<[min(volume), max(volume)]>,
<sum(volume)>], [<avg(volume)>]]
注:
metrics
中使用的列名大小写不敏感,不需要与输入表的列名大小写保持一致。
metrics
中不可使用嵌套聚合函数。
dummyTable
一个表对象,和输入的流数据表的 schema 一致,可以含有数据,亦可为空表。
outputTable
计算结果的输出表,可以是内存表或者分布式表。在使用
createTimeSeriesEngine
函数之前,需要将输出表预先设立为一个空表,并指定各列列名以及数据类型。时间序列引擎会将计算结果插入该表。
输出表的列顺序如下:
时间列。其中:
若
useSystemTime
= true,为 TIMESTAMP 类型;反之,该列数据类型与
timeColumn
列一致。
若
useWindowStartTime
=
true,显示时间为数据窗口起始时间;反之,显示时间为数据窗口终止时间。
分组列。如果
keyColumn
不为空,则其后几列和
keyColumn
设置的列及其顺序保持一致。
耗时列。如果指定
outputElapsedMicroseconds
= true,则指定一个 LONG
类型的列用于存储耗时(单位:微秒)。
计算结果列。可为多列。
注:
自 2.00.10 版本开始,引擎支持通过自定义聚合函数,将多个计算结果以 array
vector 的形式输出,此时必须在
outputTable
中指定对应列类型为 array
vector,详见例2。
timeColumn
可选参数,字符串标量或向量。当
useSystemTime
= false
时,必须指定该参数。 该参数用于指定订阅的流数据表中时间列的名称。
注:
字符串向量必须是 date 和 time
组成的向量,date 类型为 DATE,time 类型为 TIME, SECOND 或 NANOTIME。此时,输出表第一列的时间类型必须与
concatDateTime(date, time)
的类型一致。
useSystemTime
可选参数,布尔值,表示是否使用数据注入引擎时的系统时间作为时间列进行计算。
当
useSystemTime
=
true时,时间序列引擎会按照数据注入时间序列引擎的时刻(毫秒精度的本地系统时间,与数据中的时间列无关),每隔固定时间截取固定长度窗口的流数据进行计算。只要一个数据窗口中含有数据,数据窗口结束后就会自动进行计算。结果中的第一列为计算发生的时间戳,与数据中的时间无关。
当
useSystemTime
= false(缺省值)时,时间序列引擎根据流数据中的
timeColumn
列来截取数据窗口。一个数据窗口结束后的第一条新数据才会触发该数据窗口的计算。请注意,触发计算的数据并不会参与该次计算。
例如,一个数据窗口从 10:10:10 到 10:10:19。若
useSystemTime
= true,则只要该窗口中至少有一条数据,该窗口的计算会在窗口结束后的 10:10:20 触发。若
useSystemTime
= false,且 10:10:19 后的第一条数据为 10:10:25,则该窗口的计算会在 10:10:25 触发。
keyColumn
可选参数,字符串标量或向量,表示分组列名。若设置,则分组进行聚合计算,例如以每支股票为一组进行聚合计算。
garbageSize
可选参数,正整数,默认值是
50,000(单位为行)。随着订阅的流数据不断积累,注入时间序列引擎,存放在内存中的数据会越来越多,这时需要清理不再需要的历史数据。当内存中历史数据行数超过
garbageSize
值时,系统会清理本次计算不需要的历史数据。如果指定了
keyColumn
,内存清理是各组内独立进行的。当一个组在内存中的历史数据记录数超出
garbageSize
时,会清理该组中本次计算中不需要的历史数据。
注:
对于增量计算算子,系统会自动清理不再需要的历史数据。而对于全量计算算子,需要指定该参数来触发清理历史数据。
updateTime
可选参数,非负整数,单位与 timeColumn 的时间精度一致。用于指定比
step
更短的计算时间间隔。
step
必须是
updateTime
的整数倍。要设置
updateTime
,
useSystemTime
必须设为 false。
如果没有指定
updateTime
,一个数据窗口结束前,不会发生对该数据窗口数据的计算。若一个窗口长时间未触发计算,可以指定
updateTime,分多次触发当前窗口数据的计算。计算触发的规则为:
updateTime 指定为正整数值时:
从当前窗口的左边界开始,每隔
updateTime
时间,若有新的数据到来,则对当前窗口内该数据之前的所有数据进行计算。
如果系统经过 2 *
updateTime
(至少2秒)后仍有未被处理的数据,则触发对当前窗口内所有数据的计算。
若分组计算,则每组内进行上述操作。
updateTime 指定为 0 时:在新的数据到来后,立即对当前窗口的最新数据计算并输出。
指定
updateTime
后,建议使用键值内存表作为输出表。因为每次计算均会增加一条记录,输出表若使用普通内存表或流数据表,则会产生大量带有相同时间戳的结果。因为键值流数据表不可更新记录,输出表亦不推荐使用键值流数据表。
useWindowStartTime
可选参数,布尔值,表示输出表中的时间是否为数据窗口起始时间。默认值为
false,表示输出表中的时间为数据窗口起始时间 +
windowSize
。若
windowSize
是向量,
useWindowStartTime
必须为 false。
roundTime
可选参数,布尔值,表示若数据时间精度为毫秒或者秒且
step
>
一分钟,如何对窗口边界值进行规整处理。默认值为 true,表示按照既定的多分钟规则进行规整。若为 false,则按一分钟规则进行窗口规整。
若要开启快照机制(snapshot),必须指定
snapshotDir
与
snapshotIntervalInMsgCount
。
snapshotDir
可选参数,字符串,表示保存引擎快照的文件目录。
指定的目录必须存在,否则系统会提示异常。
创建流数据引擎时,如果指定了
snapshotDir
,会检查该目录下是否存在快照。如果存在,会加载该快照,恢复引擎的状态。
多个引擎可以指定同一个目录存储快照,用引擎的名称来区分快照文件。
一个引擎的快照可能会使用三个文件名:
临时存储快照信息:文件名为 <engineName>.tmp;
快照生成并刷到磁盘:文件保存为 <engineName>.snapshot;
存在同名快照:旧快照自动重命名为 <engineName>.old。
snapshotIntervalInMsgCount
可选参数,为整数类型,表示每隔多少条数据保存一次流数据引擎快照。
fill
可选参数,一个标量或向量,指定某个分组的某个窗口无数据时的处理方法。可取以下值:
'none': 不输出结果。
'null': 输出结果为 NULL。
'ffill': 输出上一个有数据的窗口的结果。
'具体数值':该值的数据类型需要和对应的
metrics
计算结果的类型保持一致。
fill
可以输入向量,长度与
metrics
元素个数保持一致,表示为每个
metrics
指定不同的
fill
方式。若为向量,向量中各项只能是 'null', 'ffill' 或一个数值,不能是 'none'。
forceTriggerTime
可选参数,是非负整数,单位与
timeColumn
的时间精度一致。用于强制触发各个分组未计算的窗口进行计算。要设置
forceTriggerTime
,
useSystemTime
必须设置为
false,且不能指定
updateTime
。强制触发计算及输出规则如下:
未被触发计算的窗口结束后(窗口结束时刻为 t),若收到了其他分组的数据(时间戳为 t1),且满足 t1-t
≥
forceTriggerTime
,则该窗口将被触发计算。
如果某个分组在最后一个窗口被强制触发计算后,没有再收到新的数据,但其他分组仍然收到了新的数据,那么通过
fill
来填充该分组的所有缺失窗口,可以确保在最新时间截面上仍然输出该分组的窗口。如果不指定
fill
,则最后一个窗口被触发计算后,该分组不会产生新的窗口。
设置
forceTriggerTime
或
updateTime
时需注意以下几点:
设置
updateTime
,计算发生后仍有属于当前窗口的数据到达时,当前窗口计算结果会再次更新;
设置
forceTriggerTime
,则触发计算之后收到的数据会被丢弃,建议不要设置太小的
forceTriggerTime
。
raftGroup
可选参数,表示流数据高可用订阅端 raft 组的 ID (大于1的整数,由流数据高可用相关的配置项
streamingRaftGroups
指定)。设置该参数表示开启计算引擎高可用。在 leader 节点创建流数据引擎后,会同步在
follower 节点创建该引擎。每次保存的 snapshot 也会同步到 follower。当 raft 组的 leader 节点宕机时,会自动切换新 leader
节点重新订阅流数据表。请注意,若要指定
raftGroup
,必须同时指定
snapshotDir
。
keyPurgeFreqInSec
正整数,表示清理窗口数据为空的分组的时间间隔,单位为秒。指定该参数后,若当前数据注入时间与上一次清理时间的间隔大于等于
keyPurgeFreqInSec
,则触发对当前窗口数据为空的分组信息的清理。
注:
若需指定该参数,必须指定
forceTriggerTime
,且不能指定
fill
。
可以通过调用
getStreamEngineStat
函数查看 TimeSeriesEngine 引擎状态的
numGroups 列,来对比响应式状态引擎清理前后分组数的变化。
closed
字符串,用于确定滑动窗口边界的开闭情况。可选值为 'left' 或 'right',默认值为
'left'。
closed = 'left': 窗口左闭右开。
closed = 'right': 窗口左开右闭。
outputElapsedMicroseconds
布尔值,表示是否输出每个窗口从触发计算到计算完成输出结果的耗时(若指定了
keyColumn
则包含数据分组的耗时),默认为 false。指定参数
outputElapsedMicroseconds
后,在定义
outputTable
时需要在时间列和分组列后增加一个 LONG
类型的列,详见
outputTable
参数说明。
subWindow
整型或者 DURATION
数据对。在滑动窗口内指定子窗口,仅计算子窗口内的数据。子窗口边界的开闭情况由参数
closed
决定。子窗口结束后收到第一条数据触发对子窗口内数据的计算(参考例4)。当
subWindow
为整型数据对时,其单位与
timeColumn
的时间精度一致。若指定
subWindow
,则:
windowSize
和
step
必须相等。
不可设置
updateTime
>0和
useSystemTime
=true。
parallelism
为不超过 63 的正整数,可选参数,表示并行计算的工作线程数,默认值为
1。在计算量较大时,合理地调整该参数能够有效利用计算资源,降低计算耗时。建议小于机器核数,推荐值为 4 到 8 。
acceptedDelay
正整数,可选参数。指定每个窗口接收数据的最大延迟,默认值为 0。若设置该参数,则不能设置
forceTriggerTime
或
updateTime
。
当 useSystemTime= true 时,
acceptedDelay
必须小于等于
windowSize
。在窗口结束后的
acceptedDelay
时间内接收到的数据,仍然属于此窗口并参与计算,而不会参与下一个窗口的计算。
当 useSystemTime= false 时,该参数用于处理乱序数据。假设当前窗口结束的时间戳为 t ,若收到一条时间戳大于等于
t+
acceptedDelay
的数据,则触发在此之前收到的所有属于当前窗口的数据进行计算输出,并关闭该窗口。
outputHandler
一元函数。设置此参数时,引擎计算结束后,不再将计算结果写到输出表,而是会调用此函数处理计算结果。
msgAsTable
布尔标量,表示在设置了参数 outputHandler
时,将引擎的计算结果以表的结构调用函数。默认值为 false,此时将计算结果的每一列作为元素组成元组。
规整规则
为了便于观察和对比计算结果,系统会对第一个数据窗口的起始时间进行规整,根据
step
参数、数据的时间精度,以及
roundTime
参数来确定整数类型的规整尺度
alignmentSize。当时间序列引擎使用分组计算时,所有分组的窗口均进行统一的规整。相同时刻的数据窗口在各组均有相同的边界。
当数据时间类型为MONTH时,会以第一条数据对应年份的1月作为窗口的上边界。
当数据的时间类型为DATE时,不对第一个数据窗口的边界值进行规整。
若数据的时间精度为分钟,如 MINUTE(HH:mm) 类型,alignmentSize 取值如下:
若 roundTime = false
:
step
alignmentSize
0~2
2
3
3
4~5
5
6~10
10
11~15
15
16~20
20
21~30
30
>30
60 (1小时)
若 roundTime = true
:
当 step <= 30 时,alignmentSize 取值同上表。当 step > 30
时,alignmentSize 取值见下表:
step
alignmentSize
31~60
60 (1小时)
61~120
120 (2小时)
121~180
180 (3小时)
181~300
300 (5小时)
301~600
600 (10小时)
601~900
900 (15小时)
901~1200
1200 (20小时)
1201~1800
1800 (30小时)
>1800
3600 (60小时)
若数据的时间精度为秒,如 DATETIME(yyyy-MM-dd HH:mm:ss) 与
SECOND(HH:mm:ss) 类型,alignmentSize 的 取值如下:
若
roundTime = false
:
step
alignmentSize
0~2
2
3
3
4~5
5
6~10
10
11~15
15
16~20
20
21~30
30
>30
60 (1分钟)
若 roundTime = true
:
当 step <= 30
时,alignmentSize 取值同上表。当 step > 30 时,alignmentSize 取值见下表:
step
alignmentSize
31~60
60 (1分钟)
61~120
120 (2分钟)
121~180
180 (3分钟)
181~300
300 (5分钟)
301~600
600 (10分钟)
601~900
900 (15分钟)
901~1200
1200 (20分钟)
1201~1800
1800 (30分钟)
>1800
3600 (1小时)
若数据的时间精度为毫秒,如 TIMESTAMP(yyyy-MM-dd HH:mm:ss.mmm) 与
TIME(HH:mm:ss.mmm) 类型,alignmentSize 的取值如下:
若 roundTime = false
:
step
alignmentSize
0~2
2
3~5
5
6~10
10
11~20
20
21~25
25
26~50
50
51~100
100
101~200
200
201~250
250
251~500
500
501~1000
1000(1秒)
1001~2000
2000(2秒)
2001~3000
3000(3秒)
3001~5000
5000(5秒)
5001~10000
10000(10秒)
10001~15000
15000(15秒)
15001~20000
20000(20秒)
20001~30000
30000(30秒)
>30000
60000(1分钟)
若 roundTime = true
:
若
step
<= 30000,alignmentSize 取值同上表;若
step
> 30000,alignmentSize 取值见下表:
step
alignmentSize
30001~60000
60000(1分钟)
60001~120000
120000(2分钟)
120001~300000
300000(5分钟)
300001~600000
600000(10分钟)
600001~900000
900000(15分钟)
900001~1200000
1200000(20分钟)
1200001~1800000
1800000(30分钟)
>1800000
3600000(1小时)
若数据的时间精度为纳秒,如 NANOTIMESTAMP(yyyy-MM-dd
HH:mm:ss.nnnnnnnnn) 与 NANOTIME(HH:mm:ss.nnnnnnnnn) 类型,alignmentSize
的取值如下:
若 roundTime = false
:
step
alignmentSize
0~2ns
2ns
3ns~5ns
5ns
6ns~10ns
10ns
11ns~20ns
20ns
21ns~25ns
25ns
26ns~50ns
50ns
51ns~100ns
100ns
101ns~200ns
200ns
201ns~250ns
250ns
251ns~500ns
500ns
>500ns
1000ns
若 roundTime = true
:
step
alignmentSize
1000ns~1ms
1ms
1ms~10ms
10ms
10ms~100ms
100ms
100ms~1s
1s
1s~2s
2s
2s~3s
3s
3s~5s
5s
5s~10s
10s
10s~15s
15s
15s~20s
20s
20s~30s
30s
>30s
1min
假设第一条数据的时间为 x,
那么根据其类型,第一个数据窗口的左边界的计算规则为:
timeType_cast(x/alignmentSize*alignmentSize+step-windowSize)
。其中,timeType_cast
表示依据时间精度,需要强制转换的时间类型;'/' 表示整除。例如,第一条数据的时间为 2018.10.08T01:01:01.365,windowSize 为
120000,step 为 60000,那么 alignmentSize 为 60000,第一个数据窗口的左边界为
timestamp(2018.10.08T01:01:01.365/60000*60000+60000-120000)
,即
2018.10.08T01:00:00.000。
返回值
一个表对象,通过向该表对象写入,将数据注入时间序列引擎进行计算。
例子
注:
以下例子使用了相同的变量和表名便于比较。每个例子执行结束后,请使用以下命令清除环境中的临时数据:
getStreamingStat
:用于查看当前的流数据表订阅者。例如:
getStreamingStat().pubTables
unsubscribeTable
:用于取消订阅流数据表。例如,在例子 1 代码运行后取消对
trades
的订阅:
unsubscribeTable(tableName="trades", actionName="engine1")
dropStreamTable
:用于删除流数据表。例如,删除例子 1 中的流数据表
trades:
dropStreamTable(tableName="trades")
dropStreamEngine
:用于流数据引擎。例如,删除例子 1 中的流数据引擎
engine1:
dropStreamEngine("engine1")
例1. 时间序列引擎 engine1 订阅流数据表 trades,实时计算表 trades
中过去1分钟内每只股票交易量之和。
share streamTable(1000:0, ["time","sym","volume"], [TIMESTAMP, SYMBOL, INT]) as trades
share table(10000:0, ["time","sym","sumVolume"], [TIMESTAMP, SYMBOL, INT]) as output1
engine1 = createTimeSeriesEngine(name="engine1", windowSize=60000, step=60000, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output1, timeColumn="time", useSystemTime=false, keyColumn="sym", garbageSize=50, useWindowStartTime=false)
subscribeTable(tableName="trades", actionName="engine1", offset=0, handler=append!{engine1}, msgAsTable=true);
insert into trades values(2018.10.08T01:01:01.785,`A,10)
insert into trades values(2018.10.08T01:01:02.125,`B,26)
insert into trades values(2018.10.08T01:01:10.263,`B,14)
insert into trades values(2018.10.08T01:01:12.457,`A,28)
insert into trades values(2018.10.08T01:02:10.789,`A,15)
insert into trades values(2018.10.08T01:02:12.005,`B,9)
insert into trades values(2018.10.08T01:02:30.021,`A,10)
insert into trades values(2018.10.08T01:04:02.236,`A,29)
insert into trades values(2018.10.08T01:04:04.412,`B,32)
insert into trades values(2018.10.08T01:04:05.152,`B,23)
sleep(10)
select * from output1;
time
sym
sumVolume
2018.10.08T01:02:00.000
A
38
2018.10.08T01:02:00.000
B
40
2018.10.08T01:03:00.000
A
25
2018.10.08T01:03:00.000
B
9
下面详细解释时间序列引擎的计算过程。为简便起见,以下提到时间时,省略相同的日期部分,只列出(小时:分钟:秒.毫秒)部分。
首先,时间序列引擎对第一个数据窗口的起始时间进行规整。第一个数据窗口的时间范围是 01:01:00.000 到
01:02:00.000,只包含左边界,不包含右边界。当(01:02:10.789,
A,15)到达时,触发第一个窗口 A
组计算;当(01:02:12.005,
B,9)到达时,触发第一个窗口 B 组计算。
第二个数据窗口的时间范围是 01:02:00.000 到
01:03:00.000。当(01:04:02.236,
A,29)到达时,触发第二个窗口 A
组计算;当(01:04:04.412,
B,32)到达时,触发第二个窗口 B 组计算。
由于 01:05:00.000 及之后没有数据,因此没有对 01:04:00.000 到 01:05:00.000
之间的数据进行计算。
输出表 output1 保存了时间序列引擎的计算结果。由于
useWindowStartTime
为
false,因此输出表 output1 中的时间为窗口的结束时间。若将
useWindowStartTime
设为
true,则输出表中的时间为窗口的起始时间。例如:
output2 = table(10000:0, ["time","sym","sumVolume"], [TIMESTAMP, SYMBOL, INT])
engine2 = createTimeSeriesEngine(name="engine2", windowSize=60000, step=60000, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output2, timeColumn="time", useSystemTime=false, keyColumn="sym", garbageSize=50, useWindowStartTime=true)
subscribeTable(tableName="trades", actionName="engine2", offset=0, handler=append!{engine2}, msgAsTable=true)
sleep(10)
select * from output2;
time
sym
sumVolume
2018.10.08T01:01:00.000
A
38
2018.10.08T01:01:00.000
B
40
2018.10.08T01:02:00.000
A
25
2018.10.08T01:02:00.000
B
9
下例中指定
updateTime
为 1000(毫秒):
share keyedTable(["time","sym"],10000:0, ["time","sym","sumVolume"], [TIMESTAMP, SYMBOL, INT]) as output3
engine3 = createTimeSeriesEngine(name="engine3", windowSize=60000, step=60000, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output3, timeColumn="time", useSystemTime=false, keyColumn="sym", garbageSize=50, updateTime=1000, useWindowStartTime=false)
subscribeTable(tableName="trades", actionName="engine3", offset=0, handler=append!{engine3}, msgAsTable=true)
sleep(2001)
select * from output3;
time
sym
sumVolume
2018.10.08T01:02:00.000
A
38
2018.10.08T01:02:00.000
B
40
2018.10.08T01:03:00.000
A
25
2018.10.08T01:03:00.000
B
9
2018.10.08T01:05:00.000
B
55
2018.10.08T01:05:00.000
A
29
例2. 下例中指定
updateTime
为 0(毫秒):
share streamTable(1000:0, ["time","sym","volume"], [TIMESTAMP, SYMBOL, INT]) as trades
share table(1000:0, ["time","sym","sumVolume"], [TIMESTAMP, SYMBOL, INT]) as output4
engine4 = createTimeSeriesEngine(name="engine4", windowSize=60000, step=60000, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output4, timeColumn="time", useSystemTime=false, keyColumn="sym", garbageSize=50, updateTime=0, useWindowStartTime=false)
subscribeTable(tableName="trades", actionName="engine4", offset=0, handler=append!{engine4}, msgAsTable=true);
insert into trades values(2018.10.08T01:01:01.785,`A,10)
insert into trades values(2018.10.08T01:01:02.125,`B,26)
insert into trades values(2018.10.08T01:01:10.263,`B,14)
insert into trades values(2018.10.08T01:01:12.457,`A,28)
sleep(100)
insert into trades values(2018.10.08T01:01:12.557,`B,21)
insert into trades values(2018.10.08T01:01:12.557,`A,28)
select * from output4;
updateTime
=0 时,每收到一批数据就触发一次计算输出:
01:01:12.457 时,触发了第一批数据中 A、B 两组数据的计算输出。
01:01:12.557 时,再次触发第二批数据中 A、B 两组数据的计算输出。
最终得到:
time
sym
sumVolume
2018.10.08 01:02:00.000
A
38
2018.10.08 01:02:00.000
B
40
2018.10.08 01:02:00.000
B
61
2018.10.08 01:02:00.000
A
66
下面以最后一个数据窗口为例,介绍时间序列引擎指定
updateTime
时如何进行计算。假设 time
列时间亦为数据进入时间序列引擎的时刻。
在 01:04:04.236 时,A 分组的第一条记录到达后已经过 2000 毫秒,触发一次 A
组计算,输出表增加一条记录(01:05:00.000, `A, 29)。
在 01:04:05.152 时的 B 组记录为 01:04:04.412 所在小窗口[01:04:04.000,
01:04:05.000)之后第一条记录,触发一次 B 组计算,输出表增加一条记录(01:05:00,"B",32)。
2 秒(2*updateTime个时间单位)后,在 01:04:07.152 时,由于 01:04:05.152
时的 B 组记录仍未参与计算,触发一次B组计算,输出一条记录(01:05:00,"B",55)。由于输出表的主键为 time 和
sym,并且输出表中已有(01:05:00,"B",32)这条记录,因此将该记录更新为(01:05:00,"B",55)。
下例中,共享流数据表 "pubT" 包含两个时间列,类型分别时 DATE 和 SECOND,创建时间序列引擎时,通过设置
timeColumn
来将原来流数据表的两个时间列整合为输出表 streamMinuteBar_1min 中的一个类型为 DATETIME
的时间列。
colNames=["symbol","date","minute","price","type","volume"]
colTypes=[SYMBOL, DATE, SECOND, DOUBLE, STRING, INT]
pubTable = streamTable(10000:0,colNames,colTypes)
share pubTable as pubT
colNames = ["time","symbol","open","max","min","close","volume","amount","ret","vwap"]
colTypes = [DATETIME, SYMBOL, DOUBLE, DOUBLE, DOUBLE, DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE]
share streamTable(10000:0,colNames, colTypes) as streamMinuteBar_1min
tsAggrOHLC = createTimeSeriesEngine(name="subT", windowSize=60, step=60, metrics=<[first(price) as open ,max(price) as max,min(price) as min ,last(price) as close ,sum(volume) as volume ,wsum(volume, price) as amount ,(last(price)-first(price))/first(price) as ret, (wsum(volume, price)/sum(volume)) as vwap]>, dummyTable=pubTable, outputTable=streamMinuteBar_1min, timeColumn=["date","minute"], useSystemTime=false, keyColumn="symbol", fill="none")
subscribeTable(tableName="pubT", actionName="subT", offset=-1, handler=append!{tsAggrOHLC}, msgAsTable=true)
insert into pubT values("000001", 2021.04.05, 09:25:01, 1, 'B', 1)
insert into pubT values("000001", 2021.04.05, 09:30:05, 2, 'B', 1)
insert into pubT values("000001", 2021.04.05, 09:31:06, 3, 'B', 1)
insert into pubT values("000001", 2021.04.05, 09:35:05, 4, 'S', 4)
insert into pubT values("000001", 2021.04.05, 09:40:05, 5, 'S', 5)
insert into pubT values("000001", 2021.04.06, 09:25:05, 6, 'S', 6)
pubT
symbol
date
minute
price
type
volume
000001
2021.04.05
09:25:01
1
B
1
000001
2021.04.05
09:30:05
2
B
1
000001
2021.04.05
09:31:06
3
B
1
000001
2021.04.05
09:35:05
4
S
4
000001
2021.04.05
09:40:05
5
S
5
000001
2021.04.06
09:25:05
6
S
6
select * from streamMinuteBar_1min
time
symbol
open
max
min
close
volume
amount
ret
vwap
2021.04.05T09:26:00
000001
1
1
1
1
1
1
0
1
2021.04.05T09:31:00
000001
2
2
2
2
1
2
1
2
2021.04.05T09:32:00
000001
3
3
3
3
1
3
2
3
2021.04.05T09:36:00
000001
4
4
4
4
4
16
3
4
2021.04.05T09:41:00
000001
5
5
5
5
5
25
4
5
share streamTable(1000:0, ["time","sym","qty"], [DATETIME, SYMBOL, INT]) as trades
share table(10000:0, ["time","sym","sumQty"], [DATETIME, SYMBOL, INT]) as output5
engine = createTimeSeriesEngine(name="engine", windowSize=6, step=6, metrics=<sum(qty)>, dummyTable=trades, outputTable=output5, timeColumn="time",keyColumn="sym", forceTriggerTime=7,fill=1000)
subscribeTable(tableName="trades", actionName="engine", offset=0, handler=append!{engine}, msgAsTable=true)
sleep(1000)
insert into engine values(2018.08.01T14:05:43,`A,1)
insert into engine values(2018.08.01T14:05:43,`C,3)
sleep(10)
insert into engine values(2018.08.01T14:05:44,`B,1)
sleep(80)
insert into engine values(2018.08.01T14:05:52,`B,3)
sleep(20)
insert into engine values(2018.08.01T14:05:54,`A,3)
sleep(10)
insert into engine values(2018.08.01T14:05:55,`A,5)
sleep(20)
insert into engine values(2018.08.01T14:05:57,`B,5)
sleep(50)
insert into engine values(2018.08.01T14:06:12,`A,1)
sleep(50)
select * from output5 order by sym
time
sum
Qty
2018.08.01T14:05:46
A
1
2018.08.01T14:05:52
A
1,000
2018.08.01T14:05:58
A
8
2018.08.01T14:06:04
A
1,000
2018.08.01T14:06:10
A
1,000
2018.08.01T14:05:46
B
1
2018.08.01T14:05:52
B
1,000
2018.08.01T14:05:58
B
8
2018.08.01T14:05:46
C
3
2018.08.01T14:05:52
C
1,000
例3. 下例计算每个分组窗口的第一个和最后一个 volume,组合后输出为一个数组向量。
//通过 defg 自定义一个函数,引擎在调用该函数时会将返回值转换为数组向量
defg toVector(x){
return x
}
share streamTable(1000:0, ["time","sym","volume","price"], [TIMESTAMP, SYMBOL, DOUBLE,DOUBLE]) as trades
//定义输出表,对应 toVector 指标输出的列需要定义为数组向量类型,此例中将其定义为 DOUBLE[]
share table(10000:0, ["time","sym","sumVolume","avg"], [TIMESTAMP,STRING,DOUBLE[],DOUBLE]) as output6
//metrics 中调用了 toVector 函数,将1分钟窗口内的第一个 volume 和最后一个 volume 组合到一个向量中。
engine1 = createTimeSeriesEngine(name="engine1", windowSize=60000, step=60000, metrics=<[toVector([first(volume),last(volume)]),avg(volume+price)]>, dummyTable=trades, outputTable=output6, timeColumn="time", keyColumn="sym" , useSystemTime=false, garbageSize=50, useWindowStartTime=false)
times = sort(2023.10.08T00:00:00.000 + rand(1..(1+3000*200), 30))
syms = rand("A"+string(1..10), 30)
volumes = rand(rand(100.0, 10) join 2.3 NULL NULL NULL NULL, 30)
prices = rand(rand(100.0, 10) join 2.3 NULL NULL NULL NULL, 30)
t=table(times as time, syms as sym, volumes as volume,prices as price)
engine1.append!(t)
select * from output6 where time between 2023.10.08T00:01:00.000 and 2023.10.08T00:05:00.000 order by time,sym
time
sym
sumVolume
avg
2023.10.08T00:01:00.000
A1
[57.66,]
80.428
2023.10.08T00:01:00.000
A2
[,]
2023.10.08T00:02:00.000
A7
[,]
2023.10.08T00:02:00.000
A8
[,]
2023.10.08T00:03:00.000
A2
[,41.25]
101.7832
2023.10.08T00:03:00.000
A3
[41.25,41.25]
68.4897
2023.10.08T00:03:00.000
A6
[,]
2023.10.08T00:03:00.000
A8
[19.17,19.17]
93.9934
2023.10.08T00:04:00.000
A7
[,]
2023.10.08T00:05:00.000
A3
[2.05,2.05]
95.433
2023.10.08T00:05:00.000
A5
[55.93,55.93]
116.4669
2023.10.08T00:05:00.000
A9
[42.66,42.66]
例4.
本例将说明
subWindow
参数的作用。
share streamTable(
1000
:
0
, [
"time"
,
"sym"
,
"volume"
], [TIMESTAMP, SYMBOL, INT])
as
trades
share table(
10000
:
0
, [
"time"
,
"sym"
,
"sumVolume"
], [TIMESTAMP, SYMBOL, INT])
as
output7
//在长度为
1
分钟的窗口内指定一个子窗口,未指定 closed 时,子窗口左闭右开。这里子窗口为每分钟的[
0
s,
10
s)
engine4 = createTimeSeriesEngine(name=
"engine4"
, windowSize=
60000
, step=
60000
, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output7, timeColumn=
"time"
, useSystemTime=false, keyColumn=
"sym"
, garbageSize=
50
, useWindowStartTime=true, subWindow=
0
s:
10
s)
subscribeTable(tableName=
"trades"
, actionName=
"engine4"
, offset=
0
, handler=append!{engine4}, msgAsTable=true);
insert into trades values(
2018.10
.
08
T01:
01
:
01.785
,`A,
10
)
insert into trades values(
2018.10
.
08
T01:
01
:
02.125
,`B,
26
)
insert into trades values(
2018.10
.
08
T01:
01
:
10.000
,`A,
14
)
insert into trades values(
2018.10
.
08
T01:
01
:
12.457
,`A,
28
)
sleep(
10
)
select *
from
output7;
2018.10.08T01:01:10.000 时刻的数据触发 [2018.10.08T01:01:00.000, 2018.10.08T01:01:10.000)
区间内 A 组数据对应的 volume 的总和。在子窗口结束后没有再收到 B 组的数据,因此 B 组子窗口内数据未被触发计算。
time
sym
sumVolume
2018.10.08T01:01:10.000
A
10
FILE:references/doc_6031.md
# datehour
**URL**: https://docs.dolphindb.cn/zh/funcs/d/datehour.html
**来源**: DolphinDB 官方文档
---
datehour
语法
datehour(X)
详情
把时间类型的标量或向量转换为 DATEHOUR 类型。返回日期和精确到小时的时间值。
注:
自 2.00.12 版本起,支持转换 MONTH 类型的数据。
参数
X
是一个包含日期和小时信息的时间类型标量或向量。如果参数
X
中未包含前述时间类型标量或向量,则返回值是 1970.01.01 +
X
小时的日期与小时的时间表达。
返回值
返回一个 DATEHOUR 类型标量或向量。
例子
datehour(1)
返回:1970.01.01T01
datehour(2012.06.13 13:30:10);
返回:2012.06.13T13
datehour([2012.06.15 15:32:10.158,2012.06.15 17:30:10.008]);
返回:[2012.06.15T15,2012.06.15T17]
datehour(2012.01M)
返回:2012.01.01T00
FILE:references/doc_6037.md
# addVolumes
**URL**: https://docs.dolphindb.cn/zh/funcs/a/addVolumes.html
**来源**: DolphinDB 官方文档
---
addVolumes
语法
addVolumes(volumes)
详情
动态增加磁盘卷,使新增磁盘卷马上可以使用而无需重启集群。
注:
此命令并不会改变集群配置文件。使用该命令后请更改配置文件,否则集群重启后将不能写入新增的磁盘卷。
参数
volumes
是字符串标量或向量,表示磁盘卷的路径。
例子
addVolumes("/home/dolphindb/data")
FILE:references/doc_6055.md
# saveTextFile
**URL**: https://docs.dolphindb.cn/zh/funcs/s/saveTextFile.html
**来源**: DolphinDB 官方文档
---
saveTextFile
语法
saveTextFile(content, filename, [append=false],
[lastModified])
详情
通过追加或覆盖将字符串保存到文件中。该函数必须要用户登录后才能执行。
参数
content
是要写入文件的内容。
filename
是要保存的文件名。仅支持 CSV 格式的文件。若传入其他格式文件,则无法保证数据准确性。
append
是一个布尔值。True 表示追加,False表示覆盖。
lastModified
是最后修改的时间,显示的是1970年1月1日零时开始的秒数。
例子
saveTextFile("1234567890\n0987654321\nabcdefghijk\n", "/home/test/abc.txt", false, 1495762562671l);
// output
[content of file "/home/test/abc.txt"]
1234567890
0987654321
abcdefghijk
FILE:references/doc_6057.md
# eqObj
**URL**: https://docs.dolphindb.cn/zh/funcs/e/eqObj.html
**来源**: DolphinDB 官方文档
---
eqObj
语法
eqObj(obj1, obj2, [precision])
详情
检验两个对象的类型和值是否相同。只有当类型和值都相同时,此函数才会返回 true。 如果值相同但类型不同,则此函数仍返回
false,这与函数
eq
不同。
注:
使用
eqObj
比较浮点数时,根据 abs(obj1-obj2)<=pow(10,-precision)
的结果来判断 obj1 和 obj2 的值是否相等。
参数
obj1
和
obj2
可以是标量、数据对、向量或矩阵。
precision
是一个非负整数,表示对 FLOAT 或 DOUBLE 类型,比较精度为小数点后几位。
返回值
布尔类型标量。
例子
eqObj(2, 2.0);
// output: false
eq(2, 2.0);
// output: true
eqObj(1.1, 1.2, 0);
// output: true
eqObj(1.1, 1.2, 1);
// output: true
eqObj(1 2 3, 1 2 3);
// output: true
eq(1 2 3, 1 2 3);
// output: [true,true,true]
eqObj
不能直接用于比较两个表是否相同。但是,可以使用高阶函数
each
来逐列对比两个表的值。
t1=table(1 2 3 as x, 4 5 6 as y);
t2=table(1 2 3 as x, 4 5 6 as y);
t1.values();
// output: ([1,2,3],[4,5,6])
each(eqObj, t1.values(), t2.values());
// output: [true,true]
FILE:references/doc_6058.md
# addGroupMember
**URL**: https://docs.dolphindb.cn/zh/funcs/a/addGroupMember.html
**来源**: DolphinDB 官方文档
---
addGroupMember
语法
addGroupMember(userIds, groupIds)
详情
把用户添加到群组:
添加一个用户到一个群组
添加多个用户到一个群组
添加一个用户到多个群组
该操作可能会因为组所具有的权限而使入组用户的权限发生改变。
注:
该函数只能由管理员在控制节点、数据节点和计算节点运行。
参数
userIds
是一个表示用户名称的字符串。
groupIds
是一个表示群组名称的字符串。
userIds
和
groupIds
不能同时为向量。
例子
添加一个用户(Even)到一个群组(adm 组):
addGroupMember("Even", "adm");
添加多个用户(Alice 和 CardiB)到一个群组(adm 组):
addGroupMember(["Alice","CardiB"], "adm");
添加一个用户(Carlos)到多个群组(adm 组和 prof 组):
addGroupMember("Carlos", ["adm","prof"]);
FILE:references/doc_6065.md
# rowVar
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowVar.html
**来源**: DolphinDB 官方文档
---
rowVar
语法
rowVar(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行元素求样本方差操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL]);
rowVar(m);
// output
[3.453333,2.173333,9.68]
t1=table(1..5 as x, 10..6 as y, take(3, 5) as z);
t2=table(5..1 as a, 6..10 as b, take(8, 5) as c);
rowVar(t1);
// output
[22.333333,14.333333,8.333333,4.333333,2.333333]
rowVar(t1[`x], t2, 1 1 2 2 2);
// output
[9.7,9.3,8.7,11,14.7]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2);
select sym,rowVar(price1,price2) as var from t;
sym
var
AAPL
7891.44845
MS
226.845
IBM
216.32
IBM
226.20645
C
11061.7938
相关函数:
rowVarp
,
varp
FILE:references/doc_6069.md
# dropDistributedInMemoryTable
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropDistributedInMemoryTable.html
**来源**: DolphinDB 官方文档
---
dropDistributedInMemoryTable
语法
dropDistributedInMemoryTable(tableName)
详情
删除指定的表。该命令只能在数据节点/计算节点上执行。
参数
tableName
字符串标量,表示分布式共享内存表的名称。
返回值
无。
例子
pt = createDistributedInMemoryTable(`dt, `time`id`value, `DATETIME`INT`LONG, HASH, [INT, 2],`id)
time = take(2021.08.20 00:00:00..2021.08.30 00:00:00, 40);
id = 0..39;
value = rand(100, 40);
tmp = table(time, id, value);
pt = loadDistributedInMemoryTable(`dt)
pt.append!(tmp);
dropDistributedInMemoryTable(`dt)
相关函数:
loadDistributedInMemoryTable
,
createDistributedInMemoryTable
FILE:references/doc_6071.md
# invGamma
**URL**: https://docs.dolphindb.cn/zh/funcs/i/invGamma.html
**来源**: DolphinDB 官方文档
---
invGamma
语法
invGamma(shape, scale, X)
详情
返回Gamma分布的累计密度函数的逆函数值。
参数
shape
为形状参数,是正数。
scale
为尺度参数,是正数。
X
是0到1之间的浮点型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
invGamma(2.31, 0.627, [0.001, 0.5, 0.999]);
// output: [0.049713, 1.245583, 6.191955]
invGamma(2.31,0.627, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output: [0.437696, 0.843572, 1.245583, 1.760732, 2.724121]
FILE:references/doc_6079.md
# weekEnd
**URL**: https://docs.dolphindb.cn/zh/funcs/w/weekEnd.html
**来源**: DolphinDB 官方文档
---
weekEnd
语法
weekEnd(X, [weekday=6], [offset], [n=1])
别名:
week
详情
返回
X
所在星期或下一个星期中
weekday
对应的日期。
如果参数
weekday
>=
weekday
(
X
,
false
),返回
X
所在星期中
weekday
对应的日期。
如果参数
weekday
<
weekday
(
X
,
false
),返回
X
所在星期的下一个星期中
weekday
对应的日期。
如果指定了
offset
,表示从
offset
开始,结果每隔n个星期更新一次。注意,
offset
和
n
须同时指定,且只有当
n
>1
时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
weekday
是0到6之间的整数,0表示星期一,1表示星期二,... ,6表示星期日。默认值为6。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
一个 DATE 类型的标量或向量。
例子
例1:
t = table(2017.12.01..2017.12.14 as date)
update t set weekday=weekday(date, false), weekEnd=weekEnd(date), weekEnd4=weekEnd(date,4)
t;
得到:
date
weekday
weekEnd
weekEnd4
2017.12.01
4
2017.12.04
2017.12.01
2017.12.02
5
2017.12.04
2017.12.08
2017.12.03
6
2017.12.04
2017.12.08
2017.12.04
0
2017.12.04
2017.12.08
2017.12.05
1
2017.12.11
2017.12.08
2017.12.06
2
2017.12.11
2017.12.08
2017.12.07
3
2017.12.11
2017.12.08
2017.12.08
4
2017.12.11
2017.12.08
2017.12.09
5
2017.12.11
2017.12.15
2017.12.10
6
2017.12.11
2017.12.15
2017.12.11
0
2017.12.11
2017.12.15
2017.12.12
1
2017.12.18
2017.12.15
2017.12.13
2
2017.12.18
2017.12.15
2017.12.14
3
2017.12.18
2017.12.15
例2:
t = table(2018.01.03+0..10*3 as date, 0..10 as x)
update t set weekday=weekday(date, false), weekEnd2=weekEnd(date,,2018.01.02,2)
t;
得到:
date
x
weekday
weekEnd2
2018.01.03
0
2
2018.01.08
2018.01.06
1
5
2018.01.08
2018.01.09
2
1
2018.01.22
2018.01.12
3
4
2018.01.22
2018.01.15
4
0
2018.01.22
2018.01.18
5
3
2018.01.22
2018.01.21
6
6
2018.01.22
2018.01.24
7
2
2018.02.05
2018.01.27
8
5
2018.02.05
2018.01.30
9
1
2018.02.05
2018.02.02
10
4
2018.02.05
例3:
date=2012.10.02 2012.10.03 2012.10.07 2012.10.08 2012.10.12 2012.10.16 2012.10.18 2012.10.20 2012.10.25 2012.10.28
time=[09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12,09:38:13]
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
t1;
得到:
date
time
sym
qty
price
2012.10.02
09:34:07
MSFT
2200
49.6
2012.10.03
09:36:42
MSFT
1900
29.46
2012.10.07
09:36:51
MSFT
2100
29.52
2012.10.08
09:36:59
MSFT
3200
30.02
2012.10.12
09:32:47
MSFT
6800
174.97
2012.10.16
09:35:26
MSFT
5400
175.23
2012.10.18
09:34:16
MSFT
1300
50.76
2012.10.20
09:34:26
MSFT
2500
50.32
2012.10.25
09:38:12
MSFT
8800
51.29
2012.10.28
09:38:13
MSFT
4500
52.38
select avg(price),sum(qty) from t1 group by weekEnd(date, 4, 2012.10.01, 2);
得到:
weekEnd_date
avg_price
sum_qty
2012.10.05
39.53
4100
2012.10.19
92.1
18800
2012.11.02
51.33
15800
FILE:references/doc_6087.md
# wma
**URL**: https://docs.dolphindb.cn/zh/funcs/w/wma.html
**来源**: DolphinDB 官方文档
---
wma
语法
wma(X, window)
TA-lib 系列函数参数说明和窗口计算规则请参考:
TAlib
详情
在给定长度(以元素个数衡量)的滑动窗口内,计算
X
的加权移动平均(Weighted Moving
Average)。
其计算公式为:
返回值
返回数值类型的结果,形式与
X
一致。
例子
x=12.1 12.2 12.6 12.8 11.9 11.6 11.2
wma(x,3);
// output
[,,12.383333333333332,12.633333333333334,12.316666666666668,11.9,11.450000000000001]
x=matrix(12.1 12.2 12.6 12.8 11.9 11.6 11.2, 14 15 18 19 21 12 10)
wma(x,3);
col1
col2
12.3833
16.3333
12.6333
18
12.3167
19.8333
11.9
16.1667
11.45
12.5
相关函数:
sma
,
trima
FILE:references/doc_6097.md
# wilder
**URL**: https://docs.dolphindb.cn/zh/funcs/w/wilder.html
**来源**: DolphinDB 官方文档
---
wilder
语法
wilder(X, window)
TA-lib 系列函数参数说明和窗口计算规则请参考:
TAlib
详情
在给定长度(以元素个数衡量)的滑动窗口内,计算
X
的指数移动平均(Exponential Moving
Average),该函数是
ema
的扩展。
与
ema
的区别在于,该函数使用 Welles Wilder
指数平滑率,其计算公式为:
其中:
为第 k
个指数移动平均值,n 为移动窗口长度,
为向量
中第 k 个元素。
返回值
若
X
是向量,返回一个与
X
长度相同的向量;若
X
是矩阵,在每列内进行计算,返回一个与
X
维度相同的矩阵。
例子
x=12.1 12.2 12.6 12.8 11.9 11.6 11.2
wilder(x,3);
// output
[,,12.299999999999998,12.466666666666668,12.27777777777778,12.051851851851854,11.767901234567903]
x=matrix(12.1 12.2 12.6 12.8 11.9 11.6 11.2, 14 15 18 19 21 12 10)
wilder(x,3);
col1
col2
12.3
15.6667
12.4667
16.7778
12.2778
18.1852
12.0519
16.1235
11.7679
14.0823
相关函数:
ema
,
gema
,
tema
FILE:references/doc_6102.md
# iif
**URL**: https://docs.dolphindb.cn/zh/funcs/i/iif.html
**来源**: DolphinDB 官方文档
---
iif
语法
iif(cond, trueResult, falseResult)
详情
iif
是元素级的条件运算符。它逐元素判断给定的条件,并根据每个元素的条件结果从
trueResult
或
falseResult
中返回相应位置的元素。具体来说,如果 cond[i] 为 true,它返回
trueResult
的第 i 个元素;否则返回
falseResult
的第 i 个元素。 当 cond[i]
为空值时,则返回空值。
注:
此函数会首先执行其中的三个参数,然后根据
cond
的结果决定返回
trueResult
或
falseResult
。
参数
cond
是布尔标量、向量或矩阵。可为产生布尔标量、向量或矩阵的表达式。
trueResult
和
falseResult
可以是标量、与
cond
等长的向量/元组、或元素个数与
cond
相同的矩阵。二者的数据类型必须相同。
返回值
返回值的数据类型与
trueResult
和
falseResult
的数据类型相同。
当输入参数为标量时,返回标量。
当输入参数为向量时,返回向量,与输入向量长度相同。
当输入参数为矩阵时,返回矩阵,与输入矩阵维度相同。
例子
iif(true true true false false false, 1..6, 6..1);
// output: [1,2,3,3,2,1]
iif(1..6==3, 1, 2);
// output: [2,2,1,2,2,2]
x=9 6 8;
iif(x<=8, 10*x, 20*x-80);
// output: [100,60,80]
a = 1..10
iif(isNull(a.prev()), a.cut(1), a.prev().cut(1))
// output: (1,1,2,3,4,5,6,7,8,9)
t=table(1..5 as id, 11..15 as x);
t1=table(take(12,5) as a, take(14,5) as b);
t;
id
x
1
11
2
12
3
13
4
14
5
15
t1;
a
b
12
14
12
14
12
14
12
14
12
14
update t set x=iif(x<t1.a, t1.a, iif(x>t1.b,t1.b, x));
t;
id
x
1
12
2
12
3
13
4
14
5
14
当配置了
nullAsMinValueForComparison
=true时,在比较运算中,NULL
元素取相应数据类型的最小值。使用
nullCompare
可以保持
iif
条件语句里的 NULL 值。
a = NULL 1 -3 5
iif(a > 0, a, 0)
// output: [0, 1, 0, 5]
iif(nullCompare(>,a,0), a, 0)
// output: [ , 1, 0, 5]
m1=1..6$3:2
m2=6..1$3:2
iif(m1>m2, m1, m2);
col1
col2
6
4
5
5
4
6
FILE:references/doc_6104.md
# createRuleEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createRuleEngine.html
**来源**: DolphinDB 官方文档
---
createRuleEngine
语法
createRuleEngine(name, ruleSets, dummyTable, outputColumns, outputTable,
[policy], [ruleSetColumn], [callback]
, [snapshotDir],
[snapshotIntervalInMsgCount]
)
详情
createRuleEngine
用于创建一个规则引擎。
注:
不支持乱序处理机制,用户需要自行保证输入的数据有序。
工作流程
规则引擎能够根据预先定义的规则集,在数据流进入引擎时选择匹配的规则来检查数据,并输出检查结果。规则匹配和检查逻辑如下:
规则集(
ruleSets
)是一个字典,其中每一个 key 对应一组规则。key 为 NULL 时代表此规则为默认规则。
数据流进入引擎时,数据的关键字段(由
ruleSetColumn
指定)与规则集的 key 进行匹配。字段值等于 key
时,代表数据命中规则,将采用此规则检查数据。如果未指定
ruleSetColumn
,或数据未命中任何规则,将采用默认规则检查数据。
检查结果由具体的规则和检查策略(
policy
)决定。有关
policy
的解释请阅读
参数
章节。
如果定义了回调函数,将调用此函数进一步处理数据。
应用场景
规则引擎支持毫秒级实时响应、精准处理大规模时序数据以及动态规则调整,可应用于如下场景:
物联网:设备监测,例如监测设备的温度、湿度;电力监控,例如监控电压、用电量。
金融:风控场景,例如过滤订单、监控股票成交量、设置超量预警信号等。
参数
name
是一个字符串,表示引擎名。
ruleSets
是一个字典,表示规则集。字典的 key 是 STRING 或 INT 类型,value
是一个包含元代码的元组。如果 key 为NULL,表示此条为默认规则。如果未指定
ruleSetColumn
,或数据未命中任何规则,将采用默认规则检查数据。一个规则集必须包含默认规则。
dummyTable
一个表对象,和输入的流数据表的 schema 一致,可以含有数据,亦可为空表。
outputColumns
一个 STRING 类型向量,表示输入表中需要保留到输出表的列。
outputTable
是一个表对象,表示输出表,可以是内存表或者分布式表,包含
outputColumns
指示的列,以及一列规则检查的结果列。当参数
policy
设置为 "shortcut" 时,最后一列为 INT 类型的标量;否则,为 BOOL
类型的向量。
policy
是一个字符串标量,表示规则检查策略。可取以下值:
"shortcut" 是默认值,代表短路逻辑。当检查到任一规则不符合(计算结果为 false)时,规则引擎立即停止检查并返回该规则的
index(从 0 开始);如果所有规则都符合,则返回 NULL。比如数据匹配到如下规则,当 age 字段的值小于 18 时,计算结果为
false,规则引擎停止检查并返回 0 (规则的 index)到输出表中。
(< age > 18 >,< income > 5000 >,< debtRatio < 0.5 >)
"all" 代表检查全部规则,返回规则集的检查结果,布尔类型。比如数据匹配到如下规则,当
voltage=220
、
current=37.11
、
temperature=39
,检查结果为
[false, false, false]
。
(< voltage > 221.86 >,< current > 39.96 >,< temperature > 44.43 >)
ruleSetColumn
是一个 STRING
类型标量,为输入表的某一列名,如果没有定义或者输入数据中的该列数据没有命中任何一个规则集,则使用默认规则,即规则集中 key 为 NULL 时所指示的规则。
callback
是一个函数,其参数为一个元组,是引擎输出的一行。若设置此参数,引擎每处理一行,在将引擎处理结果输出到输出表的同时,会将该结果作为入参调用此函数。
snapshotDir
与
snapshotIntervalInMsgCount
可选参数,无需配置,实际不生效,仅用于兼容 ORCA 框架。
返回值
返回一个表对象。
例子
实现步骤
创建分布式表,存放回调函数输出的数据。
定义规则集,用于检查输入的数据。
定义回调函数,根据检查结果进一步处理数据。
创建规则引擎。
向规则引擎输入数据。
示例代码
创建分布式表
// 创建分布式表,存放回调函数输出的数据
db = database("dfs://temp", VALUE, 1..3)
t1 = table(1:0, `sym`value`price, [INT,DOUBLE,DOUBLE])
pt = db.createPartitionedTable(t1,`pt,`sym)
定义规则集
如下规则集包含三组规则,规则的 key 分别为 1、2、NULL,其中 NULL 代表默认规则。
x = [1, 2, NULL]
y = [ [ < value > 1 > ], [ < price < 2 >, < price > 6 > ], [ < value*price > 10 > ] ]
ruleSets = dict(x, y)
/* 输出:
->(< (value * price) > 10 >)
2->(< price < 2 >,< price > 6 >)
1->(< value > 1 >)
*/
定义回调函数
如下回调函数用于判断引擎每一行的检查结果中首个值是否为
false
,如是,则将对应数据插入分布式表。
def writeBack(result){
if(result.rule[0]==false){
temp = select sym,value,price from result
loadTable("dfs://temp",`pt).append!(temp)
}
}
创建规则引擎
names = `sym`value`price`quantity
types = [INT, DOUBLE, DOUBLE, DOUBLE]
dummy = table(1:0, names, types)
outputNames = `sym`value`price`rule
outputTypes = [INT, DOUBLE, DOUBLE, BOOL[]]
outputTable = table(10:0, outputNames, outputTypes)
test = createRuleEngine(
name="ruleEngineTest",
ruleSets=ruleSets,
dummyTable=dummy,
outputColumns=["sym","value","price"],
outputTable=outputTable,
policy="all",
ruleSetColumn="sym",
callback=writeBack)
向规则引擎输入数据
插入两条
sym=1
的数据,此时会根据规则集
ruleSets
中
key=1
对应的规则,即
value >1
来检查这两条数据。
test.append!(table(1 as sym, 0 as value, 2 as price, 3 as quantity))
test.append!(table(1 as sym, 2 as value, 2 as price, 3 as quantity))
插入三条
sym=2
的数据,此时会根据规则集
ruleSets
中
key=2
对应的规则,即
price < 2
和
price > 6
来检查这三条数据。
test.append!(table(2 as sym, 2 as value, 0 as price, 3 as quantity))
test.append!(table(2 as sym, 2 as value, 4 as price, 3 as quantity))
test.append!(table(2 as sym, 2 as value, 8 as price, 3 as quantity))
插入两条
sym=3
的数据,由于规则集
ruleSets
只设置了键值为 1 和 2 的规则,此时会根据规则集中
key=NULL
对应的规则,即
value*price > 10
来检查这两条数据。
test.append!(table(3 as sym, 2 as value, 3 as price, 3 as quantity))
test.append!(table(3 as sym, 2 as value, 6 as price, 3 as quantity))
查看输出表 outputTable 的内容。
select * from outputTable
sym
value
price
rule
1
0
2
[false]
1
2
2
[true]
2
2
0
[true,false]
2
2
4
[false,false]
2
2
8
[false,true]
3
2
3
[false]
3
2
6
[true]
回调函数处理后,所有检查结果中首个值为
false
的行均被写入了分布式表 dfs://temp/pt。
select * from loadTable("dfs://temp","pt")
sym
value
price
1
0
2
2
2
4
2
2
8
3
2
3
相关函数:
updateRule
、
deleteRule
、
getRules
FILE:references/doc_6110.md
# add
**URL**: https://docs.dolphindb.cn/zh/funcs/a/add.html
**来源**: DolphinDB 官方文档
---
add
语法
add(X, Y)
详情
对
X
和
Y
内的元素逐个求和并返回。
参数
X
和
Y
可以是标量、数据对、向量或矩阵。如果
X
和
Y
中其中一个是数据对、向量或矩阵,另一个参数的长度或维度必须相同。
返回值
若
X
和
Y
至少一个是矩阵,则返回矩阵;否则,若至少一个是数据对,则返回数据对;否则,若至少有一个是向量,则返回向量;若
X
和
Y
均为标量,则返回标量。
例子
add(3,2)
// output
5
1:2+6
// output
7:8
1:2+3:4
// output
4 : 6
3+1..3
// output
[4,5,6]
add(1..3, 4..6)
// output
[5,7,9]
(1..3).add(4..6)
// output
[5,7,9]
x=reshape(1..6, 3:2)
x
0
1
1
4
2
5
3
6
x+1.5
0
1
2.5
5.5
3.5
6.5
4.5
7.5
y=reshape(5..10, 3:2)
y
0
1
5
8
6
9
7
10
x+y
0
1
6
12
8
14
10
16
参见
"+" 运算符
相关函数:
sub
FILE:references/doc_6113.md
# cross
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/cross.html
**来源**: DolphinDB 官方文档
---
cross
语法
cross(func, X, [Y])
或
X <operator>:C Y
或
func:C(X, [Y])
详情
将 X 和 Y 中元素的两两组合作为参数来调用函数。如果 X 或 Y 是矩阵,以列为单位遍历。以下是
cross
高阶函数的伪代码:
for(i:0~(size(X)-1)){
for(j:0~(size(Y)-1)){
result[i,j]=<function>(X[i], Y[j]);
}
}
return result;
pcross
是并行计算版本的
cross
高阶函数。
参数
func
是一个二元函数。
X
和
Y
可以是数据对、向量或矩阵。X 和 Y 可以有不同的数据形式和长度或维度。
Y
是一个可选参数。如果Y没有指定,将会执行cross(func, X,
X),其中func必须是对称二元函数,如
corr
函数。
返回值
假设 X 有 m 个元素或 m 列,Y 有 n 个元素或 n 列,如果 func(X[i], Y[j]) 是标量,将返回一个 m×n
矩阵,如果 func(X[i], Y[j]) 是向量,将返回一个长度为 m 的元组,每个元素是一个长度为 n 的元组。
例子
基于以下的 x 和 y 值,两个向量执行
cross
:
x=1 2;
y=3 5 7;
x+:C y;
返回:
lable
3
5
7
1
4
6
8
2
5
7
9
cross(mul, x, y);
得到:
lable
3
5
7
1
3
5
7
2
6
10
14
cross(pow, x, y);
得到:
lable
3
5
7
1
1
1
1
2
8
32
128
矩阵 m:
m = 1..6$2:3;
m;
clo1
col2
col3
1
3
5
2
4
6
矩阵 n:
n=1..4$2:2;
n;
clo1
col2
1
3
2
4
对矩阵 m 和 n 执行
cross
:
cross(**, m, n);
得到:
clo1
col2
5
11
11
25
17
39
一个向量和一个矩阵执行
cross
,返回一个矩阵:
def topsum(x,n){return sum x[0:n]};
a=1..18$6:3;
a;
得到:
clo1
col2
col3
1
7
13
2
8
14
3
9
15
4
10
16
5
11
17
6
12
18
b=2 4;
a topsum :C b;
2
4
3
10
15
34
27
58
一个向量和一个矩阵执行
cross
,返回一个元组:
x=1 2
y=1..6$2:3
cross(add, x, y);
返回:(([2,3],[4,5],[6,7]),([3,4],[5,6],[7,8]))
x=1 2
y=1..6$3:2
cross(add, x, y);
返回:(([2,3,4],[5,6,7]),([3,4,5],[6,7,8]))
FILE:references/doc_6120.md
# highDouble
**URL**: https://docs.dolphindb.cn/zh/funcs/h/highDouble.html
**来源**: DolphinDB 官方文档
---
highDouble
语法
highDouble(X)
详情
返回
X
的高位 8 字节的数据,为 DOUBLE 类型。
参数
X
是一个标量或向量,必须是 16 字节的数据类型。
例子
x=1 2 3 4
y=4 3 2 1
points = point(x, y)
x1 = highDouble(points)
// output
[4,3,2,1]
获取一个复数的虚部(虚数)
a=complex(2, 5)
highDouble(a)
// output
5
FILE:references/doc_614.md
# rowAlign
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowAlign.html
**来源**: DolphinDB 官方文档
---
rowAlign
语法
rowAlign(left, right,
how)
详情
对
left
和
right
中的每一行向量,根据其元素值进行对齐。
该函数主要应用于金融场景下对多档买卖报价进行价格对齐,
left
是某个时刻的买价/卖价,而
right
则是上一时刻的买价/卖价。通常结合
rowAt
函数,按行取出索引对应的元素。
注意:若
left/right
是列式元组,则返回的元组内的元素也是列式元组。
下图演示某行的
left
和
right
对齐的过程。图中标注出对齐方式为 “bid“ 和 “allBid“ ,”ask” 和
“allAsk“ 时的区别( 蓝色背景是以 “bid“ 或 “ask“ 对齐时,超出有效档位的数据)。
通过
rowAt
函数可以按行取出对应索引的元素。
how
= "bid" 或 "allBid" 时,bid 中某行数据的对齐过程如下图所示:
how
= "ask" 或 "allAsk" 时,ask 中某行数据的对齐过程如下图所示:
参数
left/right
是数组向量或列式元组。
注:
left
和
right
的长度和类型必须相同,但它们对应的每行向量的个数可以相同或不同。例如:
left
的长度是3,其第一行向量的长度是5,则
right
的长度必须是3,其每一行向量的长度可以是5或者其它值。
必须保证
left
/
right
中每行向量的数据严格有序排列。
how
字符串,用于指定数据对齐的方式。设置值不同,会影响
left
和
right
对齐的数据范围。可选值为:
how(不区分大小写)
含义
对齐后的最大值
对齐后的最小值
"bid"
表示 left/right 为多档买方报价数据,其数据严格降序排列。此时,仅将有效档位内的数据进行对齐。
max(max(left), max(right))
max(min(left), min(right))
"allBid"
表示 left/right 为多档买方报价数据,其数据严格降序排列。此时,将 left 和 right
所有数据进行对齐。
max(max(left), max(right))
min(min(left), min(right)
"ask"
表示 left/right 为多档卖方报价数据,其数据严格升序排列。此时,仅将有效档位内的数据进行对齐。
min(max(left), max(right))
min(min(left), min(right))
”allAsk“
表示 left/right 为多档卖方报价数据,其数据严格升序排列。此时,将 left 和 right
所有数据进行对齐。
max(max(left), max(right))
min(min(left), min(right)
返回值
返回一个长度为 2 的元组,分别表示对齐后的数据在原向量中的索引。若
left/right
中不存在数据与
right/left
的元素值相等,则返回 -1。
例子
left = array(DOUBLE[], 0, 5).append!([9.01 9.00 8.99 8.98 8.97, 9.00 8.98 8.97 8.96 8.95, 8.99 8.97 8.95 8.93 8.91])
right = array(DOUBLE[], 0, 5).append!([9.02 9.01 9.00 8.99 8.98, 9.01 9.00 8.99 8.98 8.97, 9.00 8.98 8.97 8.96 8.95])
leftIndex, rightIndex = rowAlign(left, right, "bid")
leftIndex
//output:[[-1,0,1,2,3],[-1,0,-1,1,2],[-1,0,-1,1,-1,2]]
left.rowAt(leftIndex)
//output:[[,9.01,9.00,8.99,8.98],[,9,,8.98,8.97],[,8.99,,8.97,,8.95]]
rightIndex
//output:[[0,1,2,3,4],[0,1,2,3,4],[0,-1,1,2,3,4]]
right.rowAt(rightIndex)
//output:[[9.02,9.01,9.00,8.99,8.98],[9.01,9.00,8.99,8.98,8.97],[9.00,,8.98,8.97,8.96,8.95]]
// 输出 left 与 right 数据对齐后的买方报价
left.rowAt(leftIndex).nullFill(right.rowAt(rightIndex))
//output:[[9.02,9.01,9,8.99,8.98],[9.01,9.00,8.99,8.98,8.97],[9.00,8.99,8.98,8.97,8.96,8.95]]
// 假定 bid 对应的 qty 如下
leftBidQty = array(INT[], 0, 5).append!([10 5 15 20 13, 12 15 20 21 18, 7 8 9 9 10])
rightBidQty = array(INT[], 0, 5).append!([8 12 10 12 8, 10 5 15 18 13, 12 15 20 21 19])
// 计算 left 和 right 五档报价对应委托量的变化
leftBidQty.rowAt(leftIndex).nullFill(0) - rightBidQty.rowAt(rightIndex).nullFill(0)
//output:[[-8,-2,-5,3,12],[-10,7,-15,-3,7],[-12,7,-15,-12,-21,-10]]
leftIndex, rightIndex = rowAlign(left, right, "allBid")
leftIndex
//output:[[-1,0,1,2],[-1,-1,0,1,2],[-1,0,-1,1,2]]
rightIndex
//output:[[0,1,2,-1],[0,1,2,-1,-1],[0,-1,1,2,-1]]
left = array(DOUBLE[], 0, 3).append!([8.99 9.00 9.01, 8.97 8.99 9.00, 8.95 8.97 8.99])
right = array(DOUBLE[], 0, 3).append!([9.00 9.01 9.02, 8.99 9.00 9.01, 8.97 8.98 9.00])
leftIndex, rightIndex = rowAlign(left, right, "ask")
leftIndex
//output:[[0,1,2],[0,1,2],[0,1,-1,2]]
rightIndex
//output:[[-1,0,1],[-1,0,1],[-1,0,1,-1]]
leftIndex, rightIndex = rowAlign(left, right, "allAsk")
leftIndex
//output:[[0,1,2,-1],[0,1,2,-1],[0,1,-1,2,-1]]
rightIndex
//output:[[-1,0,1,2],[-1,0,1,2],[-1,0,1,-1,2]]
sym = `st1`st2`st3
left = [[3.1,2.5,2.8], [3.1,3.3], [3.2,2.9,3.3]]
left.setColumnarTuple!()
right = [[3.1,2.5,2.8], [3.1,3.3], [3.2,2.9,3.3]]
right.setColumnarTuple!()
rowAlign(left, right, "bid")
//output:[([0,1,2],[0,1],[0,1,2]), ([0,1,2],[0,1],[0,1,2])]
FILE:references/doc_6143.md
# mean
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mean.html
**来源**: DolphinDB 官方文档
---
mean
语法
mean(X)
详情
若
X
为向量,计算
X
的平均值。
若
X
为矩阵,计算每列的平均值。
若
X
为表,计算每列的平均值。
该函数与
avg
函数完全相同。
与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
可以是标量、数据对、向量、矩阵或表。
返回值
若
X
为向量,返回一个 DOUBLE 标量。
若
X
为矩阵,返回一个 DOUBLE 向量。
若
X
为表,返回一个表。
例子
x=1 5 9;
mean(x);
// output: 5
x=1 5 9 NULL;
mean(x);
// output
5
avg(x);
// output
5
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
mean(m);
// output
[2,5]
相关的中心趋势函数:
mode
,
med
FILE:references/doc_6147.md
# decimal32
**URL**: https://docs.dolphindb.cn/zh/funcs/d/decimal32.html
**来源**: DolphinDB 官方文档
---
decimal32
语法
decimal32(X, scale)
详情
将输入的数据类型转换为 DECIMAL32 类型。
参数
X
整型/浮点型/字符串类型标量或向量。
scale
整型标量,表示保留的小数位数。
返回值
DECIMAL32 类型的标量或向量。
例子
a=decimal32(142, 2)
a
返回:142.00
b=decimal32(1\7, 6)
b
返回:0.142857
a+b
返回:142.142857
a*b
返回:20.28569400
decimal32("3.1415926535", 4)
返回:3.1415
一个 DECIMAL 类型向量里的所有元素的类型和 scale 必须相同,例如:
d1=[1.23$DECIMAL32(4), 3$DECIMAL32(4), 3.14$DECIMAL32(4)];
返回:[1.2300,3.0000,3.1400]
typestr(d1);
返回:FAST DECIMAL32 VECTOR
d2=[1.23$DECIMAL32(4), 3$DECIMAL32(4), 3.14$DECIMAL32(3)];
返回:(1.2300,3.0000,3.140)
typestr(d2);
返回:ANY VECTOR
将 STRING 或 SYMBOL 类型转换为 DECIMAL 类型时,不同版本服务器的处理方式存在差别。2.00.10
之前版本会将超出
scale
的小数部分直接舍去。而 2.00.10 及之后的版本,会将超出
scale
的小数部分进行四舍五入。例如,对于以下的转换:
symbol(["1.341", "4.5677"])$DECIMAL32(2)
2.00.10 之前的版本,结果为:[1.34,4.56]
2.00.10 及之后的版本,结果为:[1.34,4.57]
FILE:references/doc_6151.md
# autocorr
**URL**: https://docs.dolphindb.cn/zh/funcs/a/autocorr.html
**来源**: DolphinDB 官方文档
---
autocorr
语法
autocorr(X, lag)
详情
计算
X
的
lag
阶自相关系数。请注意,计算时两个时间序列所用的均值均为
X
的均值,而非两个时间序列各自的均值。
参数
X
是一个向量。
lag
是一个正整数。
返回值
DOUBLE 类型标量。
例子
n=10000
x=array(DOUBLE, n, n, NULL)
x[0]=1
r=rand(0.05, n)-0.025
for(i in 0:(n-1)){
x[i+1]=-0.8*x[i]+r[i]
}
autocorr(x, 1)
// output
-0.808343
autocorr(x, 2)
// output
0.661018
相关函数:
acf
FILE:references/doc_6156.md
# enableTableShareAndCachePurge
**URL**: https://docs.dolphindb.cn/zh/funcs/e/enabletableshareandcachepurge.html
**来源**: DolphinDB 官方文档
---
enableTableShareAndCachePurge
语法
enableTableShareAndCachePurge(table, tableName,
[cacheSize],[cachePurgeTimeColumn],[cachePurgeInterval],[cacheRetentionTime])
详情
将非持久化的流数据表共享,并设置定时清理。
通过以下两种方式之一来清理内存中的数据:
配置
cacheSize
参数时,如果插入的数据使内存中流数据表的行数达到阈值,系统将清理内存中较旧的已发布记录。阈值确定方法如下:
每次 append 的数据都不超过
cacheSize
时,阈值为
cacheSize
的 2.5
倍。
当 append 的数据超过
cacheSize
时,阈值为追加行数和 cacheSize 之和的 1.2 倍。
同时配置
cachePurgeTimeColumn
,
cachePurgeInterval
和
cacheRetentionTime
,系统将根据时间列清理数据。每次插入新数据时,系统会计算新数据与内存中第一条数据的时间戳差值,当差值大于等于
cachePurgeInterval
时,系统仅保留时间戳与新数据时间戳差值小于等于
cacheRetentionTime
的数据,清理其它数据。
参数
table
是一个空的流数据表。
tableName
是一个字符串,表示 table 共享后的名称。
cacheSize
是一个正整数,可选参数,表示流数据表在内存中最多保留的记录数。
cachePurgeTimeColumn
字符串标量,可选参数。需要指定为持久化流表中的时间列名称。
cachePurgeInterval
DURATION 类型标量,表示触发清理内存中数据的时间间隔。
cacheRetentionTime
DURATION 类型标量,表示内存中数据的最长保留期限。
返回值
无。
例子
例1. 配置 cacheSize 参数,根据内存中的数据量进行清理。
t = streamTable(1000:0, `time`sym`volume, [DATETIME, SYMBOL, INT])
enableTableShareAndCachePurge(table=t, tableName=`st, cacheSize=1000)
time = datetime(2024.01.01T09:00:00) +1..1000*2
sym=take(`a`b`c, 1000)
volume = rand(10,1000)
insert into t values([time, sym, volume])
getStreamTableCacheOffset(t)
//0
time = datetime(2024.01.01T09:35:00) +1..1000*2
sym=take(`a`b`c, 1000)
volume = rand(10,1000)
insert into t values([time, sym, volume])
getStreamTableCacheOffset(t)
//500
例2. 配置
cachePurgeTimeColumn
,
cachePurgeInterval
和
cacheRetentionTime,
根据时间列清理数据。
t = streamTable(1000:0, `time`sym`volume, [DATETIME, SYMBOL, INT])
enableTableShareAndCachePurge(table=t, tableName=`st, cachePurgeTimeColumn=`time,
cachePurgeInterval=30m, cacheRetentionTime=20m)
time = datetime(2024.01.01T09:00:00) +1..1000*2
sym=take(`a`b`c, 1000)
volume = rand(10,1000)
insert into t values([time, sym, volume])
getStreamTableCacheOffset(t)
//0
time = datetime(2024.01.01T09:35:00) +1..1000*2
sym=take(`a`b`c, 1000)
volume = rand(10,1000)
insert into t values([time, sym, volume])
getStreamTableCacheOffset(t)
//999
FILE:references/doc_6157.md
# getSchemaByCatalog
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getSchemaByCatalog.html
**来源**: DolphinDB 官方文档
---
getSchemaByCatalog
语法
getSchemaByCatalog(catalog)
详情
检索指定 catalog 中的所有 schema。
参数
catalog
字符串标量,表示 catalog 的名称。
返回值
一个 Table,包含 schema 的名称(schema)和对应路径(dbUrl)。
例子
getSchemaByCatalog("catalog1")
返回:
schema
dbUrl
schema1
dfs://db1
schema2
dfs://db2
FILE:references/doc_6176.md
# setDefaultCatalog
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setDefaultCatalog.html
**来源**: DolphinDB 官方文档
---
setDefaultCatalog
语法
setDefaultCatalog(catalog)
详情
为当前 session 设置默认的 catalog。
参数
catalog
字符串标量,表示 catalog 的名称。若为空,则表示重置当前 catalog 空间为初始状态,即无默认 catalog。
例子
getCurrentCatalog()
// 返回为空
createCatalog("cat1")
setDefaultCatalog("cat1")
getCurrentCatalog()
// Output: cat1
setDefaultCatalog("")
getCurrentCatalog()
// 返回为空
FILE:references/doc_6182.md
# createLookupJoinEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createLookupJoinEngine.html
**来源**: DolphinDB 官方文档
---
createLookupJoinEngine
语法
createLookupJoinEngine(name, leftTable, rightTable,
outputTable, metrics, matchingColumn, [rightTimeColumn], [checkTimes],
[outputElapsedMicroseconds=false], [keepDuplicates=false], [isInnerJoin]
, [snapshotDir],
[snapshotIntervalInMsgCount]
)
详情
创建流数据表的 lookup join 引擎,该引擎以
matchingColumn
作为连接列,将左表(必须为流数据表)与右表进行左连接或内连接。lookup join
引擎常用于右表更新不频繁的场景(如保存了日频指标的维度表)。若右表为非流数据表,则需设置定时刷新该表数据。
工作机制
仅当左表有新数据流入时才会触发计算。
当
keepDuplicates
= false 时,引擎仅保留右表在基于
matchingColumn
分组后每组的最新一条数据。此时:
默认连接方式为左连接,即
isInnerJoin
=
false。每次数据注入左表时,无论右表中是否有匹配的记录,都会计算指标并输出(如果右表没有匹配记录,则输出空值)。
用户可以通过将
isInnerJoin
设置为 true 来将连接方式改为内连接。
当
keepDuplicates
= true 时,引擎保留右表在基于
matchingColumn
分组后每组的所有数据。此时,连接方式只能是内连接,即每次数据注入左表时,系统会在右表中查找与连接列匹配的记录,只有匹配成功才会计算指标并输出,否则不进行计算和输出。
当右表是订阅的流数据表时,数据流入右表的同时会更新数据; 若右表为内存表、维度表或元代码,系统会根据
checkTimes
定时刷新右表数据。
lookup join 引擎与 asof join, semi lookup join, snapshot join 引擎的比较:
asof join 引擎
lookup join 引擎输出表的第一列可以不是时间列,而 asof join
引擎输出表第一列必须是时间列。
lookup join 引擎当左表有新数据流入便会触发连接计算,因此无需考虑数据延迟,也无需缓存左表数据。而
asof join 引擎,当指定
timeColumn
时,需要考虑左右表的数据延时。
left semi join 引擎
lookup join 引擎和 left semi join
引擎都由左表的新记录触发连接计算,当引擎根据连接列匹配上右表中的记录时,引擎将输出结果。
lookup join 引擎对于左表中未在右表中成功匹配的记录,根据参数设置或直接输出、或不输出结果;left semi
join 引擎对于左表中未成功匹配的记录将进行缓存,等待与右表中更新的记录匹配后输出。
left semi join
引擎在缓存右表的记录时,对于相同连接列的数据总是只保留第一条或者最新一条,因此对于左表的每一条记录至多只会匹配一条右表记录并输出一条记录。在lookup
join
engine中,对于相同连接列的数据用户可选择保留全部记录,因此存在左表的每一条记录匹配到右表多条记录、输出多条记录的情况。
snapshot join 引擎
lookup join 引擎只能由左表的新记录触发连接;而 snapshot join 引擎可以由左表或右表的新记录触发连接。
更多流数据引擎的应用场景说明可以参考
流计算引擎
。
参数
name
必选参数,表示流数据 lookup join
引擎的名称,作为其在一个数据节点/计算节点上的唯一标识。可包含字母,数字和下划线,但必须以字母开头。
leftTable
可选参数,表对象。可以不包含数据,但结构必须与输入的流数据表相同。
rightTable
可选参数,表对象,可以是内存表、流数据表、维度表或 SQL 查询元代码(查询语句必须返回表 )。请注意,如果
rightTable
没有被订阅,但
rightTable
会定期更新,则必须设置
checkTimes
来定时刷新右表数据。
outputTable
必选参数,为计算结果的输出表。在使用
createLookupJoinEngine
函数之前,需要将输出表预先设立为一个空表,并指定各列列名以及数据类型。
输出表的各列的顺序如下:
连接列。与
matchingColumn
中的列以及其顺序一致,可为多列。
计算结果列。可为多列。
耗时列。如果指定
outputElapsedMicroseconds
= true,则指定一个 LONG
类型的列用于记录单次响应计算耗时(单位:微秒)。
batchSize 列。如果指定
outputElapsedMicroseconds
= true,
则指定一个INT类型的列,记录单次响应的数据条数。
metrics
可选参数,以元代码的格式表示计算指标,支持输入元组。有关元代码的更多信息可参考
Metaprogramming
。
计算指标可以是一个或多个表达式、系统内置或用户自定义函数、一个常量标量/向量,但不能是聚合函数。当指定为常量向量时,对应的输出列必须设置为数组向量类型,例子参见
createReactiveStateEngine
中的例4。
metrics
内支持调用具有多个返回值的函数,且必须指定列名,例如 <func(price) as
`col1`col2>。
若在
metrics
指定了
leftTable
和
rightTable
中具有相同名称的列,默认取左表的列,可以通过 "tableName.colName" 指定该列来自哪个表。
注:
metrics
中使用的列名大小写不敏感,不需要与输入表的列名大小写保持一致。
matchingColumn
可选参数,表示连接列的字符串标量/向量或字符串向量组成的 tuple,支持
Integral, Temporal 或 Literal(UUID 除外)类型。
matchingColumn
指定规则:
只有一个连接列。当左表和右表的连接列名相同时,
matchingColumn
是一个字符串标量,否则是一个长度为 2 的
tuple。例如:左表连接列名为 sym,右表连接列名为 sym1,则
matchingColumn
=
[[`sym],[`sym1]]。
有多个连接列。当左表和右表的连接列名相同时,
matchingColumn
是一个字符串向量,否则是一个长度为 2 的
tuple。例如:左表连接列名为 timestamp, sym,右表连接列名为 timestamp, sym1,则
matchingColumn
= [[`timestamp, `sym], [`timestamp,`sym1]]。
rightTimeColumn
可选参数,是字符串标量,表示右表的时间列名称。若设置该参数,右表会根据指定的时间列的时间戳保留最新的数据(若有多行,则取其中最后一行)。若不指定该参数,则根据数据注入系统的时间保留最新数据。
checkTimes
可选参数,是一个时间类型向量或 DURATION 的标量。设置后,系统会定时更新
rightTable
的数据(只保留
rightTable
的最新数据),并将更新后的数据追加到引擎中。当无需更新
rightTable
时,则不用设置该参数,但需要在引擎创建后,手动将
rightTable
注入到引擎中。
checkTimes
是时间类型向量时,只能为SECOND、TIME 或 NANOTIME 类型。 lookup join
引擎每天根据向量内各元素指定的时间定时更新右表。
checkTimes
是 DURATION 标量时,表示更新右表的时间间隔。
outputElapsedMicroseconds
可选参数,布尔值,表示是否输出单次响应计算的耗时(从触发计算的数据注入引擎到计算完成的耗时),默认为
false。指定参数
outputElapsedMicroseconds
后,在定义 outputTable 时需要在计算结果列后增加一个 LONG
类型的列和 INT 类型的列,详见
outputTable
参数说明。
keepDuplicates
可选参数,布尔值,表示是否保留右表各分组内的所有数据。默认值为
false,即在关联时只取右表各分组内的最新一条数据。当设置为 true
时,在关联时则使用右表各分组内的所有数据,此时的连接类型为内连接,即只有左右两表匹配的记录被计算输出。
isInnerJoin
布尔值,可选参数,表示是否进行内连接。该参数只在
keepDuplicates
为 false
时可进行配置。该参数默认值为 false,即进行左连接,无论在右表中是否找到匹配的记录,都会输出结果(右表未匹配的记录输出空值)。设置为 true
时左右两表进行内连接。
若要开启快照机制 (snapshot),必须指定
snapshotDir
与
snapshotIntervalInMsgCount
。
snapshotDir
可选参数,字符串,表示保存引擎快照的文件目录。
指定的目录必须存在,否则系统会提示异常。
创建流数据引擎时,如果指定了
snapshotDir
,会检查该目录下是否存在快照。如果存在,会加载该快照,恢复引擎的状态。
多个引擎可以指定同一个目录存储快照,用引擎的名称来区分快照文件。
一个引擎的快照可能会使用三个文件名:
临时存储快照信息:文件名为 <engineName>.tmp;
快照生成并刷到磁盘:文件保存为 <engineName>.snapshot;
存在同名快照:旧快照自动重命名为 <engineName>.old。
snapshotIntervalInMsgCount
可选参数,为整数类型,表示每隔多少条数据保存一次流数据引擎快照。
返回值
返回一个表对象。
例子
例1.
login(`admin, `123456)
share streamTable(1000:0, `timestamps`sym`price, [TIMESTAMP, SYMBOL, DOUBLE]) as trades
share streamTable(1000:0, `timestamps`sym`val`id, [TIMESTAMP, SYMBOL, DOUBLE, INT]) as prices
share table(100:0, `sym`factor1`factor2`factor3, [SYMBOL, DOUBLE, DOUBLE, DOUBLE]) as output
LjEngine = createLookupJoinEngine(name="test1", leftTable=trades, rightTable=prices, outputTable=output, metrics=<[price,val,price*val]>, matchingColumn=`sym)
subscribeTable(tableName="trades", actionName="append_leftTable", offset=0, handler=appendForJoin{LjEngine, true}, msgAsTable=true)
subscribeTable(tableName="prices", actionName="append_rightTable", offset=0, handler=appendForJoin{LjEngine, false}, msgAsTable=true)
n = 15
tem1 = table( (2018.10.08T01:01:01.001 + 1..12) join (2018.10.08T01:01:01.001 + 1..3)as timestamps,take(`A`B`C, n) as sym,take(1..15,n) as val,1..15 as id)
prices.append!(tem1)
sleep(2000)
n = 10
tem2 = table( 2019.10.08T01:01:01.001 + 1..n as timestamps,take(`A`B`C, n) as sym,take(0.1+10..20,n) as price)
trades.append!(tem2)
sleep(100)
select * from output
sym
factor1
factor2
factor3
A
10.1
13
131.3
B
11.1
14
155.4
C
12.1
15
181.5
A
13.1
13
170.3
B
14.1
14
197.4
C
15.1
15
226.5
A
16.1
13
209.3
B
17.1
14
239.4
C
8.1
15
271.5
A
19.1
13
248.3
例2.
share streamTable(1000:0, `timestamps`sym`price, [TIMESTAMP, SYMBOL, DOUBLE]) as trades
share streamTable(1000:0, `timestamps`sym`val`id, [TIMESTAMP, SYMBOL, DOUBLE, INT]) as prices
share table(100:0, `sym`factor1`factor2`factor3, [SYMBOL, DOUBLE, DOUBLE, DOUBLE]) as output
LjEngine = createLookupJoinEngine(name="test1", leftTable=trades, rightTable=prices, outputTable=output, metrics=<[price,val,price*val]>, matchingColumn=`sym, rightTimeColumn=`timestamps)
subscribeTable(tableName="trades", actionName="append_leftTable", offset=0, handler=appendForJoin{LjEngine, true}, msgAsTable=true)
subscribeTable(tableName="prices", actionName="append_rightTable", offset=0, handler=appendForJoin{LjEngine, false}, msgAsTable=true)
n = 15
tem1 = table( (2018.10.08T01:01:01.001 + 1..12) join (2018.10.08T01:01:01.001 + 1..3)as timestamps,take(`A`B`C, n) as sym,take(1..15,n) as val,1..15 as id)
prices.append!(tem1)
sleep(2000)
n = 10
tem2 = table( 2019.10.08T01:01:01.001 + 1..n as timestamps,take(`A`B`C, n) as sym,take(0.1+10..20,n) as price)
trades.append!(tem2)
sleep(100)
select * from output
sym
factor1
factor2
factor3
A
10.1
10
101
B
11.1
11
122.1
C
12.1
12
145.2
A
13.1
10
131
B
14.1
11
155.1
C
15.1
12
181.2
A
16.1
10
161
B
17.1
11
188.1
C
18.1
12
217.2
A
19.1
10
191
例3. 右表是内存表,需设置
checkTimes
share streamTable(1000:0, `timestamps`sym`price, [TIMESTAMP, SYMBOL, DOUBLE]) as trades
share table(100:0, `sym`factor1`factor2`factor3, [SYMBOL, DOUBLE, DOUBLE, DOUBLE]) as output
share table(1000:0, `timestamps`sym`val`id, [TIMESTAMP, SYMBOL, DOUBLE, INT]) as prices
LjEngine = createLookupJoinEngine(name="test1", leftTable=trades, rightTable=prices, outputTable=output, metrics=<[price,val,price*val]>, matchingColumn=`sym, rightTimeColumn=`timestamps, checkTimes=1s)
subscribeTable(tableName="trades", actionName="append_leftTable", offset=0, handler=appendForJoin{LjEngine, true}, msgAsTable=true)
n = 15
tem1 = table( (2018.10.08T01:01:01.001 + 1..12) join (2018.10.08T01:01:01.001 + 1..3)as timestamps,take(`A`B`C, n) as sym,take(1..15,n) as val,1..15 as id)
prices.append!(tem1)
sleep(2000)
n = 10
tem2 = table( 2019.10.08T01:01:01.001 + 1..n as timestamps,take(`A`B`C, n) as sym,take(0.1+10..20,n) as price)
trades.append!(tem2)
sleep(100)
select * from output
sym
factor1
factor2
factor3
A
10.1
10
101
B
11.1
11
122.1
C
12.1
12
145.2
A
13.1
10
131
B
14.1
11
155.1
C
15.1
12
181.2
A
16.1
10
161
B
17.1
11
188.1
C
18.1
12
217.2
A
19.1
10
191
例4. 左表为一个实时的交易表与右表(相对稳定的维度表)做连接。
share streamTable(1000:0, `time`volume`id, [TIMESTAMP, INT,INT]) as trades
dbPath="dfs://testlj"
if(existsDatabase(dbPath)){
dropDatabase(dbPath)
}
rt=table(1000:0, `time`price`id, [TIMESTAMP, DOUBLE, INT])
db=database(dbPath, VALUE, `A`B`C)
prices=db.createTable(rt,`rightTable)
share table(10000:0, `id`volume`price`prod, [INT,INT,DOUBLE,DOUBLE]) as outputTable
tradesLookupJoin = createLookupJoinEngine(name="streamLookup1", leftTable=trades, rightTable=prices, outputTable=outputTable, metrics=<[volume,price,volume*price]>, matchingColumn=`id, rightTimeColumn=`time,checkTimes=1s)
subscribeTable(tableName="trades", actionName="append_trades", offset=0, handler=appendForJoin{tradesLookupJoin, true}, msgAsTable=true)
def writeData(t,n){
timev = 2021.10.08T01:01:01.001 + timestamp(1..n)
volumev = take(1..n, n)
id = take(1 2 3, n)
insert into t values(timev, volumev, id)
}
writeData(rt, 10)
prices.append!(rt)
sleep(2000)
writeData(trades, 6)
sleep(2)
select * from outputTable
id
volume
price
prod
1
1
10
10
2
2
8
16
3
3
9
27
1
4
10
40
2
5
8
40
3
6
9
54
例5. 通过
rightTable
可以对分布式分区表中的字段进行关联,此时
rightTable
是一个 SQL 查询元代码:
share streamTable(1000:0, `time`volume`id, [TIMESTAMP, INT,INT]) as trades
dbPath="dfs://lookupjoinDB"
if(existsDatabase(dbPath)){
dropDatabase(dbPath)
}
rt=table(1000:0, `time`price`id, [TIMESTAMP, DOUBLE, INT])
db=database(dbPath, HASH, [INT,5])
prices=db.createPartitionedTable(rt,`rightTable, `id)
share table(10000:0, `id`volume`price`prod, [INT,INT,DOUBLE,DOUBLE]) as outputTable
tradesLookupJoin = createLookupJoinEngine(name="streamLookup1", leftTable=trades, rightTable=<select * from loadTable(dbPath, `rightTable)>, outputTable=outputTable, metrics=<[volume,price,volume*price]>, matchingColumn=`id, rightTimeColumn=`time,checkTimes=1s)
subscribeTable(tableName="trades", actionName="append_trades", offset=0, handler=appendForJoin{tradesLookupJoin, true}, msgAsTable=true)
def writeData(t,n){
timev = 2021.10.08T01:01:01.001 + timestamp(1..n)
volumev = take(1..n, n)
id = take(1 2 3, n)
insert into t values(timev, volumev, id)
}
writeData(rt, 10)
prices.append!(rt)
sleep(2000)
writeData(trades, 6)
sleep(2)
select * from outputTable
id
volume
price
prod
1
1
10
10
2
2
8
16
3
3
9
27
1
4
10
40
2
5
8
40
3
6
9
54
例6. 设置
isInnerJoin
为 true,当在右表中没有匹配的记录时不输出结果。
login(`admin, `123456)
share streamTable(1000:0, `timestamps`sym`price, [TIMESTAMP, SYMBOL, DOUBLE]) as trades
share streamTable(1000:0, `timestamps`sym`val`id, [TIMESTAMP, SYMBOL, DOUBLE, INT]) as prices
share table(100:0, `sym`factor1`factor2`factor3, [SYMBOL, DOUBLE, DOUBLE, DOUBLE]) as output
LjEngine = createLookupJoinEngine(name="test1", leftTable=trades, rightTable=prices, outputTable=output, metrics=<[price,val,price*val]>, matchingColumn=`sym, isInnerJoin=true)
n = 15
tem1 = table( (2018.10.08T01:01:01.001 + 1..12) join (2018.10.08T01:01:01.001 + 1..3)as timestamps,take(`A`B`C, n) as sym,take(1..15,n) as val,1..15 as id)
appendForJoin(LjEngine, false,tem1)
sleep(2000)
// 左表中存在 2 条右表中无匹配的记录
n = 10
tem2 = table( 2019.10.08T01:01:01.001 + 1..n as timestamps,take(`A`B`C`d, n) as sym,take(0.1+10..20,n) as price)
appendForJoin(LjEngine, true,tem2)
sleep(100)
select count(*) from output // 8
sym
factor1
factor2
factor3
A
10.1
13
131.3
B
11.1
14
155.4
C
12.1
15
181.5
A
14.1
13
183.3
B
15.1
14
211.4
C
16.1
15
241.5
A
18.1
13
235.3
B
19.1
14
267.4
FILE:references/doc_6183.md
# neg
**URL**: https://docs.dolphindb.cn/zh/funcs/n/neg.html
**来源**: DolphinDB 官方文档
---
neg
语法
neg(X)
或
neg X
详情
返回
X
的相反数。
neg 函数和运算符 - 在大部分场景下可以相互替代,但仍然存在一些区别:
neg 与括号结合时,被当作函数处理,具有最高优先级;
neg 不与括号结合时,则优先级较低,会先运算 neg 右边的表达式,再运算 neg。例如:neg 3 + 5,结果为 -8。
运算符 "-" 则总是按照运算符优先级执行。例如:-3 + 5,结果为 2。
参数
X
可以是标量、数据对、向量或矩阵。
返回值
返回一个与输入
X
相同数据类型和形式的对象。
例子
x=1:2;
-x;
// output
-1 : -2
x=1 0 1;
-x;
// output
[-1,0,-1]
m=1 1 1 0 0 0 $ 2:3;
m;
#0
#1
#2
1
1
0
1
0
0
-m
#0
#1
#2
-1
-1
0
-1
0
0
FILE:references/doc_620.md
# getNodeAlias
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getNodeAlias.html
**来源**: DolphinDB 官方文档
---
getNodeAlias
语法
getNodeAlias()
详情
获取本地节点的别名。该别名为配置参数
localSite
中定义的 alias。
参数
无
返回值
字符串标量。
例子
getNodeAlias();
// output: controller2
相关函数:
getControllerAlias
FILE:references/doc_6216.md
# getDFSDatabases
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getDFSDatabases.html
**来源**: DolphinDB 官方文档
---
getDFSDatabases
语法
getDFSDatabases()
详情
查询当前节点上的分布式数据库。
2.00.9
版本起,
当该函数由管理员或拥有 DB_MANAGE 权限的用户执行时,返回当前节点上所有分布式数据库;
否则,仅返回该用户有 DB_OWNER 权限的数据库。
参数
无
返回值
字符串向量。
例子
getDFSDatabases()
FILE:references/doc_6220.md
# 历史数据回放
**URL**: https://docs.dolphindb.cn/zh/stream/str_replay.html
**来源**: DolphinDB 官方文档
---
历史数据回放
一个量化策略在用于实际交易时,处理实时数据的程序通常为事件驱动。而研发量化策略时,需要使用历史数据进行回测,这时的程序通常不是事件驱动。因此同一个策略需要编写两套代码,不仅耗时而且容易出错。在
DolphinDB 中,用户可将历史数据按照时间顺序以”实时数据”的方式导入流数据表中,这样就可以使用同一套代码进行回测和实盘交易。
DolphinDB 的流数据处理框架采用发布-订阅-消费的模式,数据持续地以流的形式发布给数据订阅者。订阅者收到消息以后,可使用自定义函数或者 DolphinDB
内置流处理引擎对接收的消息完成复杂处理。DolphinDB 流数据接口支持多种语言的 API,包括 C++, C#, Java 和 Python 等。用户可以使用这些 API
来编写更加复杂的处理逻辑,更好地与实际生产环境相结合。
根据输入表到输出表的映射,回放支持 1 对 1,N 对 N,N 对 1 三种回放形式。
FILE:references/doc_6228.md
# parseExpr
**URL**: https://docs.dolphindb.cn/zh/funcs/p/parseExpr.html
**来源**: DolphinDB 官方文档
---
parseExpr
语法
parseExpr(X, [varDict], [modules], [overloadedOperators])
详情
把字符串转换为元代码。使用
eval
函数可以执行
parseExpr
函数生成的元代码。
参数
X
是一个字符串标量或向量。
varDict
为可选参数,是一个字典。如果指定了该参数,使用
eval
函数解析时,表达式中的变量会被解析成字典的 key,其值即为字典中该 key 所对应的 value。
modules
为可选参数,是字符串或字符串数组,表示需要加载的模块名称。
overloadedOperators
为可选参数,是一个字典。将运算符号映射为一个函数。key 必须是一个字符串标量,value
必须是一个二元函数。
返回值
当
X
是标量时,返回 CODE 类型标量;当
X
是向量时,返回由 CODE 组成的向量。
例子
a=parseExpr("1+2")
a;
// output
< 1 + 2 >
typestr(a);
// output
CODE
a.eval();
// output
3
将 JSON
字符串解析为字典
json1 = '{"f2":10.71,"f12":"000001"},{"f2":7.24,"f12":"000002"}'
parseExpr(json1).eval()
/*
output:
f2->10.71
f12->000001
*/
t=table(1 2 3 4 as id, 5 6 7 8 as value, `IBM`MSFT`IBM`GOOG as name);
parseExpr("select * from t where name='IBM'").eval();
id
value
name
1
3
IBM
3
7
IBM
parseExpr
函数解析变量时,首先搜索会话中的局部变量,再搜索共享变量,但不会搜索函数体内定义的局部变量。
如下例所示,用户自定义函数 myfunc 后欲取得数据表 t3 中 ID 列1到5对应的行:
def myfunc(){
t3 = table(1..100 as id)
return parseExpr("select * from t3 where id in 1..5").eval()
}
myfunc()
产生如下错误信息:
myfunc() => myfunc: return ::evaluate(parseExpr("select * from t3 where id in 1..5")) => Can't find the object with name t3
解决此问题可以使用
sql
函数动态生成 SQL
语句,如下所示:
def myfunc(){
t3 = table(1..100 as id)
return sql(sqlCol("*"), t3, <id in 1..5>).eval()
}
myfunc();
id
1
2
3
4
5
表达式中的变量和值通过字典形式传入,为 dict 的 key 赋值等价于为变量赋值。
d = dict(`a`b`c, (1, 2, 3))
parseExpr("a + b*c", d).eval()
// output
7
d[`a] = 5;
parseExpr("a + b*c", d).eval()
// output
11
下例解释表达式中使用函数的处理方式,因 dict 中未存储变量 first,first 解析时直接当作函数来处理。
index = [2000.01.01, 2000.01.31, 2000.02.15, 2000.02.20, 2000.03.12, 2000.04.16, 2000.05.06, 2000.08.30]
s = indexedSeries(index, 1..8)
d1 = dict(STRING, ANY)
d1["S"] = s
parseExpr("resample(S, `M, first)", d1).eval()
在 modules 目录下的 test 模块内定义了一个 add 函数,调用模块中的函数,同时通过
overloadedOperators 参数,将二元运算符”+”映射为一个新的函数。代码执行时,运算符”+”将按照新函数进行计算。
parseExpr("test::add(1,2)+2", modules="test", overloadedOperators={"+": def(a, b){return a - b}}).eval()
// output
1
相关函数:
expr
,
eval
FILE:references/doc_6240.md
# TSDB 存储引擎
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db/tsdb.html
**来源**: DolphinDB 官方文档
---
TSDB 存储引擎
随着传感器数据、金融市场数据和网络日志等时序数据的迅速增长,通用数据库在高效存储和分析方面面临挑战。针对时序数据的特点,专用的时序数据库(TSDB)能够针对数据特点进行优化,显著提升数据处理效率和查询性能。DolphinDB
在 2.0 版本中推出的 TSDB 引擎,旨在更好地支持时序数据的分析与存储,满足用户对时序数据处理的需求。
TSDB 引擎设计采用经典的 LSM-Tree(Log Structured Merge
Tree)模型并引入辅助索引的排序列,进一步优化了性能。
LSM-Tree
LSM-Tree
是一种将数据存储在高效的数据结构中的技术,它将数据按照时间顺序组织并存储,以便于快速访问和查询。这种数据结构可以有效地处理大量的时间序列数据,并提供高性能的读写操作。TSDB
基于 LSM-Tree 设计,并进行了以下优化:
写入:
与 LSM-Tree 直接写入一个有序的数据结构不同,DolphinDB TSDB
引擎在写入数据到内存时,会先按写入顺序存储在一个写缓冲区域(unsorted write Buffer),当数据量累积到一定程度,再进行排序转化为一个
sorted buffer。
查询:
DolphinDB TSDB 引擎会预先遍历 Level File (对应 LSM-Tree 的 SSTable
文件),读取查询涉及的分区下所有 Level File
尾部的索引信息到内存的索引区域(一次性读,常驻内存)。后续查询时,系统会先查询内存中的索引,若命中,则可以快速定位到对应 Level File
的数据块,无需再遍历磁盘上的文件。
排序列
排序列是 TSDB 引擎特有的结构,它在 TSDB 引擎的存储和读取流程中发挥着重要作用。在深入讨论 TSDB 引擎之前,我们首先了解一下排序列的概念。在创建表时通过参数
sortColumns 来定义排序列,其中 sortColumns 的最后一列必须是时间类型或整型,而除了最后一列之外的其他列被称为 sortKey,每个
sortKey 值对应的数据按列存储在一起。sortKey
字段的组合值作为索引键(sortKeyEntry),为数据查询提供了入口,能够迅速定位数据块的位置,从而降低查询时间。在写入过程中,每个事务中的数据会根据
sortColumns 进行排序和去重。
sortColumns 参数在 TSDB 引擎中起到三个作用:确定索引键值、数据排序、数据去重。
确定索引键值
TSDB 的索引机制可以提升查询性能。写入数据时,在 Cache Engine 中,数据会根据 sortColumns 指定的列进行排序,TSDB
引擎的索引列就是基于排序列建立的。sortColumns 由两部分组成: sortKey(可以是多列,其组合值作为数据的索引键),最后一列。若 sortColumns
只有一列,则该列将作为 sortKey。
假设 sortColumns 指定了 n 个字段,则系统取前 n-1 个字段的组合值,作为索引键 sortKey,每个 sortKey
值对应的数据按列存储在一起(如下图,假设 sortColumns 为 deviceId 和 timestamp)。
每个 sortKey 内部的数据仍然是按列存储的,其中每个列的数据又按记录数划分为多个 block(按固定行数划分,参见 Level File 层级示意图)。block
是内部最小的查询单元,也是数据压缩的单元,其内部数据按照 sortColumns 最后一列的顺序排序。
sortKey 需要合理设置,每个分区的 sortKey 值不宜过多。因为同等数据量下,sortKey 值越多,意味着每个 sortKey
对应的数据量越少,不仅会增加命中索引的开销,而且会增大读取每个 sortKey 元数据的开销,进而降低查询效率。
查询时,若查询条件包含 sortColumns 指定的字段,系统会先定位到对应的 sortKey 的数据所在的位置,然后根据 block 内部数据的有序性以及列之间
block 的对齐性,通过最后一列快速定位到对应的 block,将相关列的 block 读取到内存中。
注:
block 数据的有序性:block 内部数据是按照 sortColumns 最后一列排好序的,此外每个 sortKey
的元数据都记录了对应每个 block 的第一条数据,因此根据和每个 block 的第一条数据比较,可以快速过滤掉一些不必要的 block
的查询,从而提升查询性能。
block 的对齐性:由于 block 的数据量都是固定的,因此根据最后一列快速定位到时间列所在的 block,就能根据该 block 的
offset 快速定位到其他列的 block。
数据排序
在 TSDB Cache Engine 中,每批刷盘的数据会根据 sortColumns 进行排序,然后再写入磁盘,可以推断:
每个写入事务的数据一定是有序的。
单个 Level File 文件内的数据一定是有序的。
Level File 之间数据的顺序无法保证。
每个分区的数据的有序性无法保证。
sortColumns 的数据排序功能,不保证数据整体的有序性,而只是保证 Level File 内数据按 sortKey 有序排列,以及每个 sortKey 中
block 内数据的有序性,这有助于:
查询条件包含 sortKey 字段的范围查询或第一个 sortKey 字段的等值查询时,加速内存查找索引的效率。
命中 sortKey 索引时,可以根据 sortKey 的元数据信息,加速 block 的定位。
数据去重
TSDB 的去重机制主要用于同一个时间点产生多条数据,需要去重的场景。
去重是基于 sortColumns 进行的,发生在写入时数据排序阶段以及 Level File 的合并阶段。其对应的配置参数为
keepDuplicates(在建表时设置),有三个可选项:ALL(保留所有数据,即不去重,为默认值),
LAST(仅保留最新数据),FIRST(仅保留第一条数据)。
不同去重机制可能会对更新操作产生影响(具体参见 2.2.3 数据更新流程):若
keepDuplicates=ALL/FIRST,那么每次更新,都需要将分区数据读取到内存更新后再写回磁盘;若
keepDuplicates=LAST,则更新数据将以追加的方式写入,真正的更新操作将会在 Level File 合并阶段进行。
注:
去重策略不能保证磁盘上存储数据不存在冗余,只能保证查询时不会返回冗余结果。查询数据时,会将对应 sortKey 所在各个 Level File
中的数据块读出,然后在内存中进行去重,再返回查询结果。
DolphinDB 不支持约束。现实场景下,很多用户会利用 sortColumns 的去重机制,将数据中的主键或唯一约束设置为
sortColumns,造成一个 sortKey 键值对应的数据量很少,从而导致 TSDB 数据库数据膨胀。
存储结构
在 TSDB 中会存储业务数据和日志文件。其中:
业务数据分为两个部分:基线数据和增量数据。基线数据是已经被写入和存储在 LSM-Tree 中的主要数据,它们是持久的、可读取的数据,被称作 Level
File。增量数据是新写入的还在 Cache Engine
中的数据,它们在一段时间后会被合并到基线数据中。这两种数据都采用列式存储,即同一列的数据连续存储在一起,不同列的数据则分开存储。数据首先按分区分组后写入
Cache Engine,Cache Engine 中的数据未被压缩,当缓存的数据量达到刷盘条件时,存储到 Level File
文件中,在转储的过程中对数据进行压缩,因此 Level File 存储的是压缩后的数据。
日志文件包括预写日志(redo log)和元数据(meta)则存储在磁盘上。
cache engine
写入 TSDB 引擎的数据首先被写入 redo log 和 cache engine,其中写入 cache engine
的数据被追加到写缓冲区的一个可变内存表(MemTable)中。MemTable 中的数据是未排序的,当它的数据量累积到一定大小(由
TSDBCacheTableBufferThreshold
配置阈值)时,数据会按照
sortColumns
指定的列进行排序,并转化不可变内存表(Immutable MemTable)中。
日志文件
redo log 是一种用于记录数据库事务的日志文件,记录了对数据库所做的所有更改。它主要用于保证事务的原子性和持久性。写入 TSDB 引擎的数据首先会写入
redo log 中。每个事务的数据会被存储为一个独立的 redo log。
元数据是关于数据的数据,包含了数据库的结构、表的定义、索引、约束等信息。元数据本身不直接记录事务,但它通常也会被存储在 meta.log
中,以确保在恢复过程中可以重建数据库的结构。
Level File 文件
Level File 结构
TSDB 引擎存储的数据文件在 DolphinDB 中被称为 Level File,即 LSMTree 架构中各层级的文件。Level File
内部采用了行列混存(Partition Attributes Across,简称 PAX),即数据先按照 sortKey 的属性切分数据,每个 sortKey
对应的数据仍然按列存储,其中每列的数据按照固定行数划分为多个 block,并在 Level File 的尾部记录这些 block 的地址及其对应的
sortKey 信息。block 是最小的查询单元,也是数据压缩的单元,其内部数据按照时间列的顺序排序。Level File 文件的结构如下:
其中:
header:记录了一些保留字段、表结构以及事务相关的信息。
sorted col data:按 sortKey 顺序排列,每个 sortKey 依次存储了每列的 block 数据块。
zonemap:存储了数据的预聚合信息(每列每个 sortKey 对应数据的 min,max,sum,notnullcount)。
indexes:sorted col data 的索引信息,记录了sortKey 个数,每个 sortKey 的记录数、每列 block
数据块在文件中的偏移量信息,checksum 等。
footer:存储 zonemap 的起始位置,用来定位预聚合和索引区域。
Level File 的 zonemap 和 indexes 部分在查询时会加载到内存中,用于索引。
Level File 层级组织
Level File 各层级间的组织形式如下:
磁盘的 Level File 共分为 4 个层级, 即 Level 0, 1, 2, 3层。层级越高,Level File 文件大小越大,每个 Level
File 中数据划分的 block 大小也越大。
自 3.00.1 版本起,TSDB 提供配置项
allowTSDBLevel3Compaction
允许用户开启 Level 3 层文件合并功能。同时,函数
triggerTSDBCompaction
,支持触发 Level 3
层文件的合并。需要注意的是,仅当建表时设置
keepDuplicates
为 FIRST 和 LAST 时,才支持 Level 3
层文件合并。
Level File 合并及数据去重
多次写入后,相同的 sortKey 的数据可能分散在不同的 Level File 里。为减少无效文件数量,TSDB
引擎设计了文件合并的机制,通过合并操作(compaction)可以提高磁盘空间利用率(压缩率提升)以及提升查询性能。
合并机制
当较低层级的 Level File 的数量超过10个或该层所有 Level File 的大小超过更高一层单个
Level File 文件的大小时,系统会将这些 Level File 合并为更高一层的 Level File。每层 Level
File 单个文件的大小参考上文的 Level File 分层组织。
默认情况下,TSDB Level File
文件满足合并要求时,由系统自动触发合并,对用户透明。在某些特殊情况,可能出现文件过多,却没有合并,DolphinDB
也提供了函数实现手动触发合并。
数据去重
TSDB 根据 sortColumns
进行去重,建表时通过参数指定去重模式。包含三种去重模式:保留所有数据,仅保留最新数据,仅保留第一条数据。去重发生在写入时数据排序阶段以及
Level File
合并阶段。不同去重机制会对更新操作产生影响:若采用保留所有数据或仅保留第一条数据,则每次更新时都需要将分区数据读取到内存更新后再写回磁盘;若采用仅保留最新数据,则更新数据将以追加的方式写入,真正的更新操作将会在
Level File 合并阶段进行。请注意:
TSDB 去重策略无法确保磁盘上无冗余,只保证查询时无冗余结果。查询时,读取各 Level File 中 sortKey
对应的数据块,在内存中去重后返回结果。
DolphinDB 不支持约束。不建议将数据中的主键或唯一约束设置为 sortColumns。
数据压缩
对数据进行压缩,可以在通讯场景下传输更多的数据,显著地提升数据传输吞吐量。TSDB 引擎中的数据首先按分区分组后写入 Cache Engine,Cache Engine
中的数据未被压缩,当缓存的数据量达到刷盘条件时,存储到 Level File 文件中,在转储的过程中对数据进行压缩,因此 Level File
存储的是压缩后的数据。
TSDB 支持无损压缩,其按照 block 的方式去组装构建索引和压缩数据,在数据从 Cache Engine 写入磁盘时进行压缩。可选压缩算法:
默认采用 LZ4 压缩算法,适用于一般情况。LZ4主要针对重复字符进行压缩,压缩率与数据重复频率相关。如果同一列中有较多重复项,LZ4
算法可以获得较高的压缩速度。但相对于 Delta(delta-of-delta encoding) 压缩算法,压缩率提升可能不太明显。
zstd 压缩算法:zstd 适用于几乎所有数据类型,其压缩比高于 LZ4,但解压缩速度较 LZ4 慢约1倍。
对于时间类型或者变化较小的整型数据,建议采用 Delta(delta-of-delta encoding) 压缩算法。Delta
是专门针对时间戳等连续且等间隔的数据提出的算法,能够极大降低时间戳的存储空间,因此特别适合时间列的压缩。
chimp 压缩算法:在处理小数部分长度不超过三位的 DOUBLE 类型数据时,chimp 具有很高的压缩率及优越的压缩和解压效率。
对于重复较高的字符串,可采用 SYMBOL 类型存储。系统对 SYMBOL 类型数据会使用字典编码,将字符串转化为整型,减少字符串的存储空间。
在现实场景下,金融数据存盘的压缩率一般可达到 20% 到 30% 左右。
数据写入
TSDB 引擎写入整体上和 OLAP 一致,都是通过两阶段协议进行提交。写入时,先写 Redo Log(每个写事务都会产生一个 Redo Log),并写入 Cache
Engine 缓存,最后 由后台线程异步批量写入磁盘。需要注意的是,TSDB 引擎和 OLAP 引擎各自单独维护 Redo 以及 Cache
Engine,用户需要通过不同的配置项去设置两个引擎的 Cache Engine 大小,分别为 OLAPCacheEngineSize 和
TSDBCacheEngineSize。
写入流程如下:
写 Redo:
先将数据写入 TSDB Redo Log。
写 Cache Engine:
写 Redo Log 的同时,将数据写入 TSDB Cache Engine 的 CacheTable,并在
CacheTable 内部完成数据的排序过程。
CacheTable 分为两个部分:首先是 write buffer,数据刚写入时会追加到 write buffer 的尾部,该 buffer
的数据是未排序的。当 write buffer 超过
TSDBCacheTableBufferThreshold
的配置值(默认
16384 行),则按照 sortColumns 指定的列排序,转成一个 sorted buffer (该内存是 read only 的),同时清空
write buffer。
写磁盘:
若某写事务到来时,Cache Engine 中的数据累计超过了
TSDBCacheEngineSize
的一半,或经过一定时间,系统将进行一次刷盘操作。
刷盘前,系统会将 CacheTable 的所有数据按照 sortColumns 进行归并排序,再按分区写入磁盘 Level 0 层的 Level
File 文件中(大小为 32M)。
刷盘时,若单个分区的数据量很大,按 32 M 拆分可能产生多个 Level File 文件(见下注1);若单个分区写入数据量不足 32
M或拆分后最后一部分数据不足 32 M,也会写为一个 Level File。由于 Level File
一旦写入就是不可变的,下次写入不会向磁盘的 Level File 文件追加数据 。
注:
同属于一个 sortKey 值的数据不会被拆分到不同的 Level File 文件。因此实际场景我们会发现一个
Level File 的文件可能会大于 32 M,若一个 sortKey
值对应的数据量特别巨大,甚至可能达到更高!
可以通过设置刷盘的工作线程数配置项
TSDBCacheFlushWorkNum
来提高刷盘效率。
根据步骤 2,3,可以发现刷盘前数据先局部排序(sorted
buffer),再整体排序,共执行了两次排序操作。实际就是通过分治的思想,提升了排序的效率。
数据查询
相较于 OLAP 引擎,TSDB 引擎增加了索引的机制,因此更适用于点查场景,因此在配置 TSDB 引擎的 sortKey
字段时,可以优先考虑从频繁查询的字段中进行选取(如需了解更多 sortColumns 的设置原则,参考:
合理设置排序字段
)。
查询流程如下:
分区剪枝:
根据查询语句进行分区剪枝,缩窄查询范围。
加载索引:
遍历涉及到的分区下的所有 Level
File,将其尾部的索引信息加载到内存中(索引信息采用惰性缓存策略,即不会在节点启动时被立即加载进内存,而是在第一次查询命中该分区时才被加载进内存)。查询命中的分区的索引信息一旦被加载到内存后,会一直缓存在内存中(除非因内存不够被置换),后续查询若涉及该分区则不会重复此步骤,而是直接从内存中读取索引信息。
注:
内存中存放索引的区域大小由配置项
TSDBLevelFileIndexCacheSize
决定,用户可以通过函数
getLevelFileIndexCacheStats
在线查询内存中的索引占用。若加载的索引大小超过了该值,内部会通过一些缓存淘汰算法进行置换,用户可配置
TSDBLevelFileIndexCacheInvalidPercent
来调整缓存淘汰算法的阈值。
查找内存中的数据:
先搜索 TSDB Cache Engine中的数据。若数据在 write buffer 中,则采用顺序扫描的方式查找;若在
sorted buffer 中,则利用其有序性,采用二分查找。
查找磁盘上的数据:
根据索引查找磁盘 Level File 中各查询字段的数据块,解压到内存。若查询的过滤条件包含 sortKey
字段,即可根据索引加速查询。
返回查询结果:
合并上述两步的结果并返回。
其中,索引流程为:
内存索引包含两个部分:sortKey 维护的 block 的偏移量信息(对应 Level File indexes 部分),zonemap 信息(对应 Level
File zonemap 部分)。
查询 indexes 定位 sortKey:
indexes 中记录了每个 Level File 中每个 sortKey 值下每个字段的
block 的地址偏移量。若查询条件包含 sortKey 字段,则可以根据索引剪枝,缩窄查询范围。命中 sortKey 索引后,即可获取到对应
sortKey 下所有 block 的地址偏移量信息。
例如,上图 sortColumns=`deviceId`location`time,查询条件 deviceId = 0,则可以快速定位到所有 Level
File 中 deviceId= 0 的 sortKey 及其对应所有字段的 block 数据。
根据 zonemap 定位 block:
由 1 定位到 sortKey 后,系统会查询对应 sortKey 在 zonemap
里的最值信息(min,max)。如果查询条件提供了 sortKey 以外的字段范围,则可以进一步过滤掉一些不在查询范围内的 block 数据。
例如,上图 sortColumns="deviceId""location""time",查询条件 time between 13:30 and
15:00, 则可以根据 time 列的 zonemap 信息,快速定位到查询数据所在的 block 为 “block2”。系统根据该信息再去
indexes 找到 block2 的地址偏移量信息,然后根据索引到的所有 Level File 的 block2 的地址,把 block
数据从磁盘中读取出来,再根据去重策略过滤结果后返回给用户端。
数据更新
TSDB 引擎的更新效率取决于 keepDuplicates 参数配置的去重机制。
keepDuplicates=ALL/FIRST 时的更新流程:
分区剪枝:
根据查询语句进行分区剪枝,缩窄查询范围。
查到内存更新:
取出对应分区所有数据到内存后,更新数据。
写回更新后的分区数据到新目录:
将更新后的数据重新写入数据库,系统会使用一个新的版本目录(默认是
“物理表名_cid”)来保存更新后的分区数据,旧版本的分区数据文件将被定时回收(默认 30 min)。
keepDuplicates=LAST 时的更新流程:
分区剪枝:
根据查询语句进行分区剪枝,缩窄查询范围。
查到内存更新:
根据查询条件,查询出需要更新的数据。(查询步骤见
TSDB
数据查询
)
直接以写数据的方式追加写入:
更新后,直接追加写入数据库。
更新后的数据和旧的数据可能同时存储在磁盘上,但查询时,由于会按照 LAST 机制进行去重,因此可以保证不会查询出旧的数据。旧数据会在 Level File
合并操作时进行删除。
针对不同的数据更新需求,DolphinDB 提供 3 种更新表的方法:
update
:标准 SQL 的update语法
sqlUpdate
:动态生成 SQL update
语句的元代码。
upsert!
:用于更新键值内存表、索引内存表或分布式表。进行更新时,若新数据的主键值已存在,则更新该主键值的数据;否则添加数据。
注:
更新操作(
keepDuplicates
=LAST)按照直接追加的方式增量修改,更新效率更高,若业务场景需要高频更新,可以配置此策略。
更新操作(
keepDuplicates
=ALL /
FIRST)按分区全量修改,因此需要确保每次更新操作涉及分区总大小不会超过系统的可用内存大小,否则会造成内存溢出。
数据删除
TSDB 引擎的删除流程和 keepDuplicates=ALL/FIRST 时的更新流程基本一致,即按分区取数,删除后写入一个新版本的目录。
具体流程:
分区剪枝:
根据查询语句进行分区剪枝,缩窄查询范围。
查到内存删除:
取出对应分区所有数据到内存后,根据条件删除数据。
写回删除后的分区数据到新目录:
将删除后的数据重新写入数据库,系统会使用一个新的 CHUNK 目录(默认是
“物理表名_cid”)来保存写入的数据,旧的文件将被定时回收(默认 30 min)。
当采用保留最新数据(
keepDuplicates
=LAST)的机制时,可通过参数设置数据删除的方式:
建表时设置参数
softDelete
=true,则数据删除采用软删除方式,即将待删除的数据读取到内存中,打上删除标记后,以追加的方式写入一个新的
Level File 文件,不会删除旧数据,也不会产生新的版本目录。待删除的数据会在 Level File 文件进行合并时才会删除。
建表时设置参数
softDelete
=false,则数据删除流程同保留所有数据或仅保留第一条数据时的流程相同。
软删除方式因不需要读取整个分区数据,且不会产生新版本目录,可以显著提升删除性能,因此在需要频繁删除数据的场景下,建议开启软删除。
针对不同的数据删除需求,DolphinDB 提供以下方法删除数据:
dropPartition:删除整个分区的数据,不保留分区结构。
delete:删除分区的数据,保留分区结构。
sqlDelete:动态生成 SQL delete 语句。
dropTable:删除整个表的数据,不保留表结构。
truncate:删除整个表的数据,保留表结构。
TSDB引擎特点
过滤条件使用分区列以及分区内排序字段的点查询非常高效。
可以在写入时对数据进行排序和去重。
适合存储几百几千列的宽表,也适合存储 array
vector 和 BLOB 类型的数据。
若指定去重时保留最后一条记录(设置 keepDuplicates=LAST),则修改数据时重写数据所在 Level
File 即可,不需要重写整个分区。
写入吞吐量低。TSDB 引擎中,数据需在 Cache Engine 中进行排序;Level File
会进行合并与压缩。
读取整个分区数据或整个分区的某几列数据时,效率低于 OLAP。
TSDB 引擎使用示例
创建数据库
下述脚本以创建一个组合分区的数据库为例,和 OLAP 引擎创库时的区别仅在于 engine 设置不同:
方式一:通过 SQL 语句创建数据库。
create database "dfs://test_tsdb"
partitioned by VALUE(2020.01.01..2021.01.01),HASH([SYMBOL, 100]), engine='TSDB'
方式二:通过
database
函数创建数据库。
dbName="dfs://test_tsdb"
db1 = database(, VALUE, 2020.01.01..2021.01.01)
db2 = database(, HASH, [SYMBOL, 100])
db = database(directory=dbName, partitionType=COMPO, partitionScheme=[db1, db2], engine="TSDB")
创建数据表
创建分布式表/维度表时,与 OLAP 引擎不同, TSDB 需要额外设置 sortColumns 这个必选参数,以及 keepDuplicates,
sortKeyMappingFunction 这两个可选参数。
方式一:通过 SQL 语句创建分布式分区表。
// 通过标准 SQL 创建
create table dbPath.tableName (
schema[columnDescription]
)
[partitioned by partitionColumns],
[sortColumns], [keepDuplicates=ALL],
[sortKeyMappingFunction]
方式二:通过
createPartitionedTable
函数创建分布式分区表。
// 通过函数创建
createPartitionedTable(dbHandle, table, tableName, [partitionColumns], [compressMethods],
[sortColumns], [keepDuplicates=ALL], [sortKeyMappingFunction])
特别地,自 3.00.1 版本起,DolphinDB
支持用户通过自定义规则设计数据分区的方案,即在创建分区表的时候将分区列设置为一个函数调用,写入的数据将按函数调用的结果进行分区。参见下例创建一个自定义分区规则的分区表。
例如分区列 id_date 的数据形如 ax1ve_20240101_e37f6,
91f86_20240102_b781d,我们期望根据其中的日期(例如 20240101)进行分区,可以通过以下方式建表:
//首先定义处理分区列数据的函数
def myPartitionFunc(str) {
return temporalParse(substr(str, 6, 8),"yyyyMMdd")
}
通过 SQL 语句建表。
create database "dfs://partitionFunc"
partitioned by VALUE(2024.02.01..2024.02.02)
create table "dfs://partitionFunc"."pt"(
id_date STRING,
ts TIMESTAMP,
value DOUBLE
)
partitioned by myPartitionFunc(id_date)
通过
createPartitionedTable
函数建表。
db = database("dfs://partitionFunc", VALUE, 2024.02.01..2024.02.02)
tb=table(100:0,["id_date", "ts", "value"],[STRING,TIMESTAMP, DOUBLE])
db.createPartitionedTable(table=tb, tableName=`pt,
partitionColumns=["myPartitionFunc(id_date)"])
上述示例简单展示了如何在 TSDB
引擎下创建数据库表。在实际使用中,需要根据业务特点,合理设置数据库和表的参数。以下是关于建库和建表的一些关键参数设置建议。
建库参数说明
是否允许并发写入同一分区(
atomic)
:
默认为 ‘TRANS',即不允许并发写入同一个分区;
设置为 ‘CHUNK',则允许多线程并发写入同一分区。注意:需谨慎设置为 'CHUNK'
模式,因为该模式不能保证事务的原子性。
分区设计(
partitionType
和
partitionScheme
):
TSDB 引擎单个分区推荐大小
:400MB - 1GB(压缩前)
分布式查询按照分区加载数据进行并行计算(包括查询、删除、修改等操作),若分区粒度过大,可能会造成内存不足、查询并行度降低以及更新删除效率降低等问题;若分区粒度过小,可能会产生大量子任务,增加节点负荷,同时大量小文件的独立写入会增加系统负荷,并可能导致控制节点的的元数据膨胀。
分区设计步骤:
以推荐大小作为参照,先根据表中的记录数和每个字段的大小估算数据量,再根据分区方案计算的分区数(如天+股票HASH10
的组合分区,可以按天数 * 10),通过数据量/分区数计算得到每个分区的大小。
若分区粒度不合理,调整分区粒度可以参考以下方案:
粒度过小:若采用了值分区可以考虑改成范围分区,例如按天改成按月;若采用了 HASH
分区,可以考虑改小 HASH 分区数。
粒度过大:若采用了范围分区可以考虑改成值分区,例如按年改成按月;若采用了 HASH
分区,可以考虑改大 HASH 分区数;若是一级分区,可以考虑用组合分区,此时新增一级通常是 HASH
分区,例按天单分区,粒度过大,考虑二级按股票代码 HASH 分区。
合理设置分区至关重要,如需了解详细的分区机制和如何设计合理的分区,可参见数据库分区。
建表参数说明
建表参数说明
根据字段选择恰当的压缩算法(
compressMethods
):
对重复较高的字符串,使用 SYMBOL 类型存储。需要注意单个分区下 SYMBOL 字段的唯一值数不能超过
2
21
(2097152) 个,否则会抛异常,见
S00003
。
对时序数据或顺序数据(整型)可以使用 delta (即 delta-of-delta
encoding)算法存储。压缩性能测试参考
物联网应用范例
。
其余类型的数据采用 lz4 压缩算法
。
合理设置排序字段(
sortColumns
):
sortColumns
指定的列数不超过 4 个,同时确保一个分区的 sortKey 的组合数小于
2000。
通常金融场景下会以 SecurityID+时间戳的组合、物联网场景下会以 deviceID+时间戳的组合来作为
sortColumns。
在
Level File 文件
中提及,Level File
的每个 sortKey 都对应存储了许多索引信息,因此在数据量固定的情况下,如果 sortKey
的数量过多,元数据也会变多。极端场景下,数据库可能会膨胀 50 倍!因此不推荐把主键或唯一约束设置为
sortColumns
。
建议把查询频率高的字段作为
sortColumns
中的前置列。
索引键值是 sortKey 的组合值,查询时,如果过滤条件中包含 sortKey
字段,即可以快速定位索引,从而快速定位到数据块 block 加速查询。
由于索引键在内存中是按照其组合值排序的,因此如果将频繁查询的字段前置,查询语句中包含这些字段时,系统可以通过二分查找快速定位索引;否则系统将需要遍历内存中的索引。
如果
sortColumns
只有一列,该列将作为 sortKey,此时块内数据是无序的。因此需要遍历每个
block 的所有数据;如果
sortColumns
有多列,则最后一列必须是时间列或整型列。除最后一列外的作为索引列 sortKey ,block
内部按时间列或整型列排序。如果查询条件中指定了时间列或整型列,则无需遍历对每个 sortKey 下的
block。
类型限制:
sortColumns
只支持 INTEGER, TEMPORAL, STRING 或
SYMBOL 类型;sortKey 不能为 TIME, TIMESTAMP, NANOTIME,
NANOTIMESTAMP 类型。
索引降维(
sortKeyMappingFunction
):
如果依靠合理配置
sortColumns
仍然不能降低每个分区的 sortKey 数量,则可以通过
sortKeyMappingFunction
参数对索引列进行降维。
例如:5000 只股票,按照日期分区,设置股票代码和时间戳为
sortColumns
,每个分区 sortKey 组合数约为
5000,不满足每个分区 sortKey 组合数不超过 1000 的原则,则可以通过指定
sortKeyMappingFunction
=[hashBucket{, 500}] 进行降维,使每个分区的
sortKey 组合数降为 500。
降维是对每个 sortKey 的字段进行的,因此有几个 sortKey 字段就需要指定几个降维函数。
常用的降维函数是 hashBucket,即进行哈希映射。
降维后可以通过
getTSDBSortKeyEntry
查询每个分区的 sortKey 信息。
数据去重(
keepDuplicates
):
对同一个时间点产生多条数据,可以根据业务需求进行去重设置,此时可以设置
keepDuplicates
=FIRST/LAST。
若对去重策略没有要求,则可以根据以下需求进行评估,以设置去重策略:
高频更新:建议指定
keepDuplicates
=LAST,因为 LAST
采用追加更新的方式效率更高,见
数据更新
。
高性能查询:较推荐使用
keepDuplicates
=ALL,因为其他去重策略在查询时存在额外的去重开销。
atomic
=”CHUNK”:推荐使用
keepDuplicates
=FIRST/LAST。此时,若并发写入失败,则直接重复写入,无需删除数据再写。
性能调优
分区、索引等因素会显著影响引擎的写入和查询性能,因此在创建数据库和数据表时,需要先了解相关参数配置。本节主要介绍如何通过参数设置,提升 TSDB
的写入或查询性能。
TSDBRedoLogDir:为了提高写入效率,建议将 TSDB redo log 配置在 SSD 盘。
TSDBCacheEngineSize:默认是 1G,写入压力较大的场景可以适当调大该值。
若设置过小,可能导致 cache engine 频繁刷盘,影响系统性能;
若设置过大,由于 cache engine 内缓存的数据量很大,但由于未达到 cache engine 的大小的
50%(且未达到十分钟),因此数据尚未刷盘,此时若发生了机器断电或关机,重启后就需要回放大量事务,导致系统启动过慢。
TSDBLevelFileIndexCacheSize:默认是 5% * maxMemSize,该配置项确定了索引数据(Level File
indexes 和 zonemap)的上限,若配置过小,会造成索引频繁置换。在索引部分,较占内存空间的是 zonemap 部分,用户可以根据 “分区数量
× sortKey 数量 × (4 × 各字段字节数的和)” 估算 zonemap 所占内存大小。其中, 4 表示 4 种预聚合指标
min,max,sum,notnullcount)。
TSDBAsyncSortingWorkerNum:非负整数,默认值为1,用于指定 TSDB cache engine 异步排序的工作线程数。在 CPU
资源充足的情况下,可以适当增大该值,以提高写入性能。
TSDBCacheFlushWorkNum:TSDB cache engine 刷盘的工作线程数,默认值是 volumes
指定的磁盘卷数。若配置值小于磁盘卷数,则仍取默认值。通常无需修改此配置。
FILE:references/doc_6241.md
# substr
**URL**: https://docs.dolphindb.cn/zh/funcs/s/substr.html
**来源**: DolphinDB 官方文档
---
substr
语法
substr(X, offset, [length])
详情
从
X
的指定位置开始截取指定长度的字符串。
X
的第一个字符的位置为0。如果
length
超过了
X
的长度,则到
X
的尾部结束。
参数
X
是一个字符串。它可以是标量或向量。
offset
是一个非负整数。
length
是一个正整数。
返回值
STRING 类型标量或向量。
例子
substr("This is a test", 0, 4);
// output
This
substr("This is a test", 5, 2);
// output
is
substr("This is a test", 5);
// output
is a test
substr("This is a test", 8, 100);
// output
a test
FILE:references/doc_6249.md
# clearCachedModules
**URL**: https://docs.dolphindb.cn/zh/funcs/c/clearCachedModules.html
**来源**: DolphinDB 官方文档
---
clearCachedModules
语法
clearCachedModules()
详情
清除缓存的 module。更新 module 文件后,通过该命令清除 module 缓存,执行 use 语句时,会重新从文件加载 module,无需重启节点。
注:
只有管理员(admin)才能执行该命令。
参数
无
返回值
无。
例子
定义并导入一个 module
module printLog
def printLog(){
print "hello"
}
加载模块
use printLog
printLog()
// output
hello
修改 module
module printLog
def printLog(){
print "hello new"
}
再次加载模块前,需要调用
clearCachedModules
以清除之前缓存的
module。
login("admin", "123456")
clearCachedModules();
use printLog
printLog()
// output
hello new
FILE:references/doc_6250.md
# getInstrumentFloatingDayCountConvention
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentfloatingdaycountconvention.html
**来源**: DolphinDB 官方文档
---
getInstrumentFloatingDayCountConvention
语法
getInstrumentFloatingDayCountConvention(instrument)
详情
根据输入的金融工具,获取该工具的浮动端日期计数惯例。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
STRING 类型标量或向量。
例子
swap = {
"productType": "Swap",
"swapType": "IrSwap",
"irSwapType": "IrFixedFloatingSwap",
"version": 0,
"start": 2021.05.15,
"maturity": 2023.05.15,
"frequency": "Quarterly",
"fixedRate": 0.02,
"calendar": "CFET",
"fixedDayCountConvention": "Actual365",
"floatingDayCountConvention": "Actual360",
"payReceive": "Pay",
"iborIndex": "SHIBOR_3M",
"spread": 0.0005,
"notional":["CNY", 1E8]
}
instrument = parseInstrument(swap)
getInstrumentFloatingDayCountConvention(instrument)
// output: Actual360
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_6257.md
# rowKurtosis
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowKurtosis.html
**来源**: DolphinDB 官方文档
---
rowKurtosis
语法
rowKurtosis(X, [biased=true])
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行计算
X
的峰度。
DolphinDB 使用以下公式计算峰度(当
biased
=true 时):
参数
biased
是一个布尔值,表示是否为有偏估计。默认值为 true,表示为有偏估计。
返回值
一个向量。
例子
m = [4.5 2.6 1.5 1.5 4.8, 5.9 4.9 2.0 4.0 6.3, 2 2 2 2 2, 2.1 3.4 4.2 5.5 2.3]
rowKurtosis(m);
// output
[1.336589711715856,1.839333299961742,2.248755164221374,1.437834622248661,1.341044189891083]
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL, 4.3 NULL 3.5]);
rowKurtosis(m);
// output
[2.270290894661423,1.499999999999941,1.499999999999972]
t1=table(1..5 as x, 10..6 as y, 15..19 as z, take(3,5) as t);
rowKurtosis(t1);
// output
[1.417974225003112,1.676864,1.951167883478534,2.158698670898631,2.262015004030008]
相关函数:
kurtosis
FILE:references/doc_6261.md
# cumvar
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumvar.html
**来源**: DolphinDB 官方文档
---
cumvar
语法
cumvar(X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累计方差。
返回值
DOUBLE 类型,其数据形式同
X
。
例子
x=[2,3,4];
cumvar(x);
// output
[,0.5,1]
m=matrix(0.15 0.08 0.03 -0.14 -0.09, 0.2 -0.12 -0.16 0.08 0.16);
m;
#0
#1
0.15
0.2
0.08
-0.12
0.03
-0.16
-0.14
0.08
-0.09
0.16
cumvar(m);
#0
#1
0.0024
0.0512
0.0036
0.0389
0.0152
0.0288
0.0143
0.0267
相关函数:
cummax
,
cummin
,
cumprod
,
cumPositiveStreak
,
cumsum
,
cumavg
,
cumstd
FILE:references/doc_6263.md
# differentialEvolution
**URL**: https://docs.dolphindb.cn/zh/funcs/d/differentialevolution.html
**来源**: DolphinDB 官方文档
---
differentialEvolution
语法
differentialEvolution(func, bounds, [X0], [maxIter=1000], [popSize=15],
[mutation], [recombination=0.7], [tol=0.01], [atol=0], [polish=true],
[seed])
详情
使用差分进化算法(Differential Evolution)求解多元函数的全局最小值。返回一个字典,表示求解结果,详细说明请参见“返回值”小节。
参数
func
函数名,表示需要最小化的目标函数。注意:其返回值应为标量数值。
bounds
数值类型矩阵,形状为(N,2),其中 N 为需要优化的参数数量。
X0
可选参数,数值向量,表示使目标函数最小化的参数的初始猜测。
注意:
参数
bounds
中每一行的两个值(min, max),分别定义了
X0
中对应参数的下、上边界。即参数
X0
的每个元素值均在
bounds
的范围内。
参数
X0
应与
bounds
保持相同长度,即 N=size(
X0
)。
maxIter
可选参数,非负整数标量,表示执行的最大迭代次数,默认值为 1000。
popSize
可选参数,正整数标量,用于设置种群大小的乘数。种群包含 popSize*(N - N_equal) 个个体,其中,N_equal 表示
bounds
中上下限相等的参数个数。默认值为 15。
mutation
可选参数,输入形式为数值数据对 pair(min, max),表示变异常数的范围。应满足 0<= min <=max
<2。默认值为(0.5, 1)。
recombination
可选参数,数值标量,表示重组常数,又称为交叉概率。取值范围为[0, 1]。
tol
可选参数,非负浮点数标量,表示收敛的相对容忍度。默认值为 0.01。
atol
可选参数,非负浮点数标量,表示收敛的绝对容忍度。默认值为 0。当满足条件 stdev(population_energies) <=
atol
+
tol
* abs(mean(population_energies)) 时,停止算法迭代,其中
population_energies 表示种群中每个个体求得的目标函数值构成的向量。
polish
可选参数,布尔标量,表示是否在差分进化算法结束后进一步使用 L-BFGS-B 算法优化参数。默认值为 true,表示使用。
seed
可选参数,整数标量,表示差分进化算法中使用的随机数种子。如果不设置,则使用非确定性的随机数生成器。该参数的作用在于让用户可以复现运行结果。默认不设置。
返回值
返回一个字典,包含以下成员:
xopt:浮点数向量,使目标函数最小化的参数值。
fopt:浮点数标量,目标函数最小值,fopt=f(xopt)。
iterations:整数标量,优化过程中执行的总迭代数。
fcalls:整数标量,优化过程中的目标函数调用次数。
converged:布尔值标量,表示优化过程的收敛状态。
true:表示优化结果已收敛至满足预定条件,算法停止执行。
false:表示已达最大迭代次数,算法未收敛而停止执行。
例子
自定义函数
rosen
,在上下界
bounds
约束下使用
differentialEvolution
求解
rosen
函数的全局最小值。
def rosen(x) {
N = size(x);
return sum(100.0*power(x[1:]-power(x[:N-1], 2.0), 2.0)+power(1-x[:N-1], 2.0));
}
bounds = matrix([0 0 0 0 0, 2 2 2 2 2])
differentialEvolution(rosen, bounds)
/* Ouput:
fcalls->43656
xopt->[1.000000000000,1.000000000000,1.000000000000,1.000000000000,1.000000000000]
fopt->0.0
iterations->581
converged->true
*/
FILE:references/doc_6267.md
# getInstrumentCoupon
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getInstrumentCoupon.html
**来源**: DolphinDB 官方文档
---
getInstrumentCoupon
语法
getInstrumentCoupon(instrument)
详情
根据输入的金融工具,获取该工具的票面利率(Coupon Rate)。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DOUBLE 类型标量或向量。
例子
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"nominal": 100,
"instrumentId": "0001",
"start": 2022.05.15,
"maturity": 2032.05.15,
"dayCountConvention": "ActualActualISDA",
"coupon": 0.0276,
"issuePrice": 100.0,
"frequency": "Semiannual"
}
ins = parseInstrument(bond)
getInstrumentCoupon(ins)
// output: 0.0276
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_6286.md
# loadModel
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadModel.html
**来源**: DolphinDB 官方文档
---
loadModel
语法
loadModel(file)
详情
把模型加载到内存中,以字典的形式返回模型。
参数
file
是模型所在的本地文件的路径。
返回值
一个字典,表示加载到内存中的模型。
例子
x1 = rand(100.0, 100)
x2 = rand(100.0, 100)
b0 = 6
b1 = 1
b2 = -2
err = norm(0, 10, 100)
y = b0 + b1 * x1 + b2 * x2 + err
t = table(x1, x2, y)
model = randomForestRegressor(sqlDS(<select * from t>), `y, `x1`x2)
saveModel(model, "/home/DolphinDB/Data/regressionModel.txt");
model = loadModel("/home/DolphinDB/Data/regressionModel.txt")
yhat = predict(model, t);
FILE:references/doc_63.md
# MCP
**URL**: https://docs.dolphindb.cn/zh/mcp/mcp_introduction.html
**来源**: DolphinDB 官方文档
---
MCP
MCP(Model Context Protocol)是一种标准协议,用于将
大模型调用工具
的能力从原本紧耦合的 Function Call
模式中解耦。在传统模式下,AI 工具调用是绑定在特定系统内,例如 ChatGPT 的函数调用只能使用它自己的插件。而 MCP
的作用是
将“会话端”和“工具端”分离
:会话端只需实现 MCP 调用功能,具体的 MCP 工具可以在不同后端独立开发和维护。
在 DolphinDB 3.00.4 版本中,原生实现了 MCP server,支持一键将用户自定义函数转化成 MCP Tool,从而为 Agent 提供数据分析能力。
工具定义统一存储在支持 MCP Server 的 DolphinDB 控制节点上,执行时根据所连接的数据节点或计算节点执行函数逻辑。
会话界面(Agent 前端)可以是任何支持 MCP 协议的客户端,例如:VS Code Copilot, Claude, Cherry Studio,
DolphinDB 因子平台 AI 助手等。
大模型作为客户端的调度大脑,在会话过程中根据上下文决定用哪个工具以及填入哪些参数。
注意:
当前版本仅支持 MCP Tools 和 MCP Prompts。
FILE:references/doc_6301.md
# hour
**URL**: https://docs.dolphindb.cn/zh/funcs/h/hour.html
**来源**: DolphinDB 官方文档
---
hour
语法
hour(X)
详情
返回对应的小时数。结果的数据类型是 INTEGER。
参数
X
是一个时间标量/向量。
例子
hour(2012.12.03 01:22:01);
返回:1
FILE:references/doc_6305.md
# weekday
**URL**: https://docs.dolphindb.cn/zh/funcs/w/weekday.html
**来源**: DolphinDB 官方文档
---
weekday
语法
weekday(X, [startFromSunday=true])
详情
返回一个表示与
X
对应的一周中日期编号。
如果
startFromSunday
=true,那么0表示星期日,1表示星期一,...,6表示星期六。如果
startFromSunday
=false,那么0表示星期一,1表示星期二,...,6表示星期日。
参数
X
是一个时间标量或向量。
startFromSunday
是一个布尔值,表示一周是否从星期日开始。默认值为 true。
返回值
一个 INT 类型的标量或向量。
例子
weekday 2012.12.05;
// output
3
weekday(2012.12.05, false);
// output
2
weekday 2013.05.23T12:00:00;
// output
4
weekday(2014.01.11T23:04:28.113);
// output
6
weekday 2012.12.05 2012.12.06 2013.01.05;
// output
[3,4,6]
FILE:references/doc_6315.md
# ceil
**URL**: https://docs.dolphindb.cn/zh/funcs/c/ceil.html
**来源**: DolphinDB 官方文档
---
ceil
语法
ceil(X)
详情
函数
floor
和
ceil
分别把一个实数映射到小于等于它的最大整数,和大于等于它的最小整数。函数
round
根据四舍五入规则把一个实数映射到最接近的整数。
参数
X
可以是标量、向量或矩阵。
返回值
INT 类型标量、向量或矩阵。
例子
ceil(2.1);
// output
3
ceil(2.9);
// output
3
ceil(-2.1);
// output
-2
floor(2.1);
// output
2
floor(2.9);
// output
2
floor(-2.1);
// output
-3
round(2.1);
// output
2
round(2.9);
// output
3
round(-2.1);
// output
-2
m = 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10$2:5;
m;
0
1
2
3
4
1.1
3.3
5.5
7.7
9.9
2.2
4.4
6.6
8.8
10
ceil(m);
0
1
2
3
4
2
4
6
8
10
3
5
7
9
10
FILE:references/doc_632.md
# mmad
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mmad.html
**来源**: DolphinDB 官方文档
---
mmad
语法
mmad(X, window, [useMedian=false], [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数衡量)的滑动窗口内,计算
X
的平均绝对离差或绝对中位差。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
useMedian
是一个布尔值,默认值是 false,表示计算平均绝对离差(mean absolute deviation)。若为 true
则计算绝对中位差(median absolute deviation)。
平均绝对离差:mean(abs(X - mean(X)))
绝对中位差:med(abs(X - med(X)))
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
x = 7 4 6 0 -5 32;
mmad(x, window=3);
// output: [,,1.111111111111111,2.222222222222222,3.777777777777777,15.333333333333333]
mmad(x, window=3, useMedian=true)
// output: [,,1,2,5,5]
y = NULL NULL 2 5 1 7 -3 0
mmad(y, window=3, minPeriods=2);
// output: [,,,1.5,1.555555555555555,2.222222222222222,3.555555555555556,3.777777777777778]
m=matrix(85 90 95, 185 190 195);
m;
#0
#1
85
185
90
190
95
195
mmad(x, 2)
#0
#1
2.5
2.5
2.5
2.5
相关函数:
mad
FILE:references/doc_6322.md
# setTimeoutTick
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setTimeoutTick.html
**来源**: DolphinDB 官方文档
---
setTimeoutTick
语法
setTimeoutTick(tick)
别名:
setDfsChunkNodeHeartBeatTimeoutTick
详情
动态设置控制节点判断数据节点是否在线的超时时间。该命令只能由管理员在控制节点上执行。若为高可用集群,则需要在 raft
组的每个控制节点上执行该命令。
注:
此命令修改的配置值在集群重启后将失效。若需要配置值永久生效,请更改配置文件中的
dfsChunkNodeHeartBeatTimeout
。
参数
tick
一个正整数,表示超时时间,单位为秒。
FILE:references/doc_6323.md
# stretch
**URL**: https://docs.dolphindb.cn/zh/funcs/s/stretch.html
**来源**: DolphinDB 官方文档
---
stretch
语法
stretch(X, n)
详情
X
是向量/元组时,将
X
均匀拉伸为长度为
n
的向量/元组。
X
是矩阵/表时,将
X
均匀拉伸为行数为
n
的矩阵/表。
该函数与
take
的区别为:
take
是对向量整体进行循环拼接,而
stretch
则是对向量的每一个元素进行复制达到拉伸的效果。
参数
X
向量/元组/矩阵/表。
n
非负整数。
返回值
与
X
形式相同的对象。
例子
X = 1 NULL 2 3
print stretch(X, 11)
返回:[1,1,1,,,,2,2,2,3,3]
print stretch(X, 12)
返回:[1,1,1,,,,2,2,2,3,3,3]
以下用
take
做比较:
print take(X, 10)
返回:[1,,2,3,1,,2,3,1,]
另一个例子:
Y=array(INT[], 0, 10).append!([1 NULL 3, 4 5, 6 NULL 8, 9 10]);
print stretch(Y,7)
返回:[[1,00i,3],[1,00i,3],[4,5],[4,5],[6,00i,8],[6,00i,8],[9,10]]
s=[1 2 3, 4 5 6]
stretch(s, 5)
返回:
0
1
2
3
4
0
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]
[4, 5, 6]
[4, 5, 6]
m=matrix(1 2 3, 4 5 6)
stretch(m,5)
返回:
col1
col2
1
4
1
4
2
5
2
5
3
6
t=table(1 2 3 as a, 4 5 6 as b)
stretch(t,5)
返回:
a
b
1
4
1
4
2
5
2
5
3
6
FILE:references/doc_6330.md
# listStreamingSQLTables
**URL**: https://docs.dolphindb.cn/zh/funcs/l/listStreamingSQLTables.html
**来源**: DolphinDB 官方文档
---
listStreamingSQLTables
语法
listStreamingSQLTables()
详情
列出当前用户已通过
declareStreamingSQLTable
声明的所有流式 SQL 表。
如果调用者是管理员(admin),则会返回系统中所有用户声明的流式 SQL 表。
返回值
一张表,包含如下字段:表名(tableName)、是否共享(shared)、声明用户(users)。
例子
t=table(1..10 as id,rand(100,10) as val)
share t as st
declareStreamingSQLTable(st)
listStreamingSQLTables()
tableName
shared
users
st
true
admin
相关函数:
declareStreamingSQLTable
FILE:references/doc_6332.md
# 功能简介
**URL**: https://docs.dolphindb.cn/zh/stream/str_funcs.html
**来源**: DolphinDB 官方文档
---
功能简介
本节总体介绍 DolphinDB 流数据功能,主要包括:DolphinDB 流数据功能架构 、流数据表、订阅与发布 、流式处理中的状态、流处理中的时间概念
。在介绍功能之前,我们先了解下相关概念。
流数据表
流数据表是 DolphinDB
的一种特殊的内存表,用于存储和发布流数据。被订阅后,它会在收到数据时及时把增量数据推送给订阅者。向流数据表插入一条记录等价于数据源发布一条消息。
流数据表的查询接口与普通内存表相同,支持使用 SQL 语句进行查询和分析。此外,流数据表支持并发读写,但与普通内存表不同,流数据表不支持修改或删除记录。
发布与订阅
DolphinDB 采用经典的发布订阅(Pub-Sub)模式。每当有新的流数据注入负责发布消息的流数据表时,会通知所有的订阅方处理新的流数据。
流计算引擎
流数据计算引擎是专门用于处理特定计算场景的内置计算函数,如实时合成 K
线、实时多源关联、实时计算状态指标等。流计算引擎使用上比较灵活,不仅可以单独使用,还可以多个引擎级联使用。
流数据处理架构
DolphinDB 流数据处理模块采用发布-订阅-消费的模式。流数据首先注入流数据表中,通过流数据表来发布数据,数据节点或者第三方的应用可以通过 DolphinDB
脚本或 API 来订阅及消费流数据。
上图展示了 DolphinDB
的流数据处理框架。外部实时数据注入到发布节点的流数据表后,数据被发布到流数据表的订阅者。一个流数据表可同时将数据发布给多个订阅者,供它们并行消费:
流数据表可由数据仓库订阅并保存,作为分析系统与报表系统的数据源。
流数据表可由流数据计算引擎订阅,进行计算,并将结果输出到流数据表。计算结果既可以由 Grafana
等平台进行实时展示,也可以作为数据源再次发布,供二次订阅做事件处理。
流数据表可通过 API 进行订阅,并提供给第三方应用程序,例如第三方的 Java 应用程序可以通过 Java API 订阅流数据以进行操作。
FILE:references/doc_6341.md
# cdfChiSquare
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfChiSquare.html
**来源**: DolphinDB 官方文档
---
cdfChiSquare
语法
cdfChiSquare(df, X)
详情
返回卡方分布的累计密度函数的值。
参数
df
是正数,表示卡方分布的自由度。
X
是数值型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfChiSquare(1, [-1, 0, 0.5, 1, 2]);
// output
[0, 0, 0.5205, 0.682689, 0.842701]
cdfChiSquare(1, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output
[0.24817, 0.416118, 0.5205, 0.597216, 0.657218]
FILE:references/doc_6354.md
# like
**URL**: https://docs.dolphindb.cn/zh/funcs/l/like.html
**来源**: DolphinDB 官方文档
---
like
语法
like(X, pattern)
详情
确定
X
是否与
Pattern
指定的模式相匹配。比较操作是区分大小写的。
参数
X
可以是字符串类型的标量/向量。
pattern
是一个字符串,通常包含通配符(例如 "%")。
返回值
一个布尔值标量或向量。
例子
like(`ABCDEFG, `DE);
// output
false
like(`ABCDEFG, "%DE%");
// output
true
a=`IBM`ibm`MSFT`Goog`YHOO`ORCL;
like(a, "%OO%");
// output
[false,false,false,false,true,false]
a[like(a, "%OO%")];
// output
["YHOO"]
like
可以搭配
select
使用,用于筛选字符串类型的列的范围:
t = table(`abb`aac`aaa as sym, 1.8 2.3 3.7 as price);
select * from t where sym like "%aa%";
sym
price
aac
2.3
aaa
3.7
相关函数:
ilike
FILE:references/doc_6361.md
# getPKEYMetaData
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getpkeymetadata.html
**来源**: DolphinDB 官方文档
---
getPKEYMetaData
语法
getPKEYMetaData()
详情
获取 PKEY 引擎下所有 chunk 的元数据。该函数只能在数据节点上执行。
参数
无
返回值
返回一个表,包含以下列:
chunkId:chunk 的唯一标识
chunkPath:分区的物理路径
level:数据文件所在的 level 级别
table:数据表名称
files:数据文件名称,即 level file 名称
例子
getPKEYMetaData()
chunkId
chunkPath
level
table
files
a0a7b031-15b8-32be-664b-21b156dc94c0
/home/dolphindb/server/local8848/storage/CHUNKS/test_pkey/20200102/Key94/1B8
0
pt1_2
0-000000006-000
b3307046-77cb-bbb4-2244-dc4dcdd4c4e2
/home/dolphindb/server/local8848/storage/CHUNKS/test_pkey/20200104/Key39/1B8
0
pt1_2
0-000000009-000
1b47193f-39a4-8b93-3f44-d1b32b892126
/home/dolphindb/server/local8848/storage/CHUNKS/test_pkey/20200105/Key94/1B8
0
pt1_2
0-000000007-000
65ac20af-e1ea-21a6-254a-0c7a1f4a1bcf
/home/dolphindb/server/local8848/storage/CHUNKS/test_pkey/20200102/Key39/1B8
0
pt1_2
0-000000003-000
600e024e-e280-62bb-084d-b440f7ccc349
/home/dolphindb/server/local8848/storage/CHUNKS/test_pkey/20200101/Key94/1B8
0
pt1_2
0-000000002-000
4f33838b-1b90-3f84-6943-e0da5fda3e10
/home/dolphindb/server/local8848/storage/CHUNKS/test_pkey/20200104/Key94/1B8
0
pt1_2
0-000000005-000
e625607d-03ce-00bc-ab47-a419ae5af3f3
/home/dolphindb/server/local8848/storage/CHUNKS/test_pkey/20200103/Key94/1B8
0
pt1_2
0-000000004-000
9e0004ea-33b5-b2b4-d947-065c9333709f
/home/dolphindb/server/local8848/storage/CHUNKS/test_pkey/20200101/Key39/1B8
0
pt1_2
0-000000001-000
595d1703-88b4-4397-4b46-281eb8014251
/home/dolphindb/server/local8848/storage/CHUNKS/test_pkey/20200103/Key39/1B8
0
pt1_2
0-000000008-000
280b3b44-8006-52a8-694e-1133e8740c07
/home/dolphindb/server/local8848/storage/CHUNKS/test_pkey/20200105/Key39/1B8
0
pt1_2
0-000000010-000
FILE:references/doc_6363.md
# getLicenseExpiration
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getLicenseExpiration.html
**来源**: DolphinDB 官方文档
---
getLicenseExpiration
语法
getLicenseExpiration()
详情
查看当前节点的 license 过期时间。可用于更新 license 之后,验证新的 license 是否生效。
参数
无
返回值
DATE 类型标量。
例子
getLicenseExpiration()
输出返回:2021.09.30
FILE:references/doc_6367.md
# eachPre
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/eachPre.html
**来源**: DolphinDB 官方文档
---
eachPre
语法
eachPre(func, X, [pre], [assembleRule|consistent=false])
func:P([pre], X)
或
[pre] <operator>:P X
表示不指定
assembleRule
,使用默认值
func:PC([pre], X)
或
[pre] <operator>:PC X
表示指定
assembleRule,
此例中指定为 C(Consistent)
详情
将给定函数/运算符应用于X中所有相邻的数据对。
eachPre
高阶函数等同于: F(X[0], pre), F(X[1], X[0]), ..., F(X[n],
X[n-1])。
内置函数
ratios
和
deltas
也是通过用
eachPre
高阶函数实现。定义如下:
function deltas(a){return a[0] -:P a}
function ratios(a){return a[0] :P a}
参数
func
是一个二元函数。
X
可以是向量、矩阵或表。当X是向量时,pre必须是标量;当X是矩阵时,pre必须是标量或向量;当X是表时,pre必须是标量或表;当pre未指定时,结果的第一个元素为NULL。
pre
可选参数,用于为计算提供初始的前序值,其数据形式要求取决于
X
的数据形式。
assembleRule
可选参数,表示如何将子任务的结果合并为函数最终结果。接受一个整数或字符串作为输入,可选值如下:
0 (或 "D"):默认值,表示 DolphinDB
规则,即根据所有子任务的结果来决定最终输出的数据类型和形式。当所有子结果具有相同的数据类型和形式时,多个标量合并为一个向量、多个向量合并为一个矩阵、多个矩阵合并为一个元组、多个字典合并为一张表;否则将所有子结果合并为一个元组输出。
1(或 "C"):表示 Consistent
规则,即认为所有子结果的数据类型和形式都与第一个子结果相同,根据第一个子结果来选择最终结果的数据类型和形式。如果后续子任务返回的结果与第一个子任务的结果类型不一致,系统会尝试对后续结果进行类型转换。如果转换失败则抛出异常。因此,此规则只可在已知子结果的数据类型及形式一致时指定。此规则可使系统免于逐一缓存并检查每个子任务的计算结果,从而提升性能。
2(或 "U"):表示 Tuple 规则,系统不再对各子结果的类型和形式一致性进行检查,而是直接将子结果组装成一个元组输出。
3(或 "K"):表示 kdb+ 规则。与 DolphinDB 规则类似,都会根据所有子结果来决定最终结果形式。主要区别在于,kdb+
规则下,只要有任一子任务返回向量,则最终结果必为一个元组;而在 DolphinDB
规则下,子任务结果若均为长度相同的向量,则最终结果为一个矩阵。其他情况下,kdb+ 规则的输出与 DolphinDB 规则相同。
注:
自 2.00.15
/3.00.3
版本起,新增了
assembleRule
参数。该参数不仅实现了原
consistent
参数的功能,还提供了更多的结果合并选项。
consistent
是一个布尔值,默认值为 false,相当于
assembleRule
="D";若为 true,则相当于
assembleRule
="C"。为保持兼容性,用户仍可使用
consistent
参数。如果同时指定
assemble
和
consistent
,将以
consistent
的值为准。
assembleRule
也可在高阶函数对应的函数模式符号后指定,通过字符 D/C/U/K 表示。以
eachPre (:P)
为例,形如
sub:PU(X)
。不指定则使用默认值 D。
返回值
取决于
assembleRule
的值。
例子
x=1..10;
eachPre(sub, x);
返回:[,1,1,1,1,1,1,1,1,1]。该用法等同于 [NULL, 2-1, ..., 10-9]
eachPre(sub, x,,assembleRule="U");
返回:(,1,1,1,1,1,1,1,1,1)
-:P x;
返回:[,1,1,1,1,1,1,1,1,1]。该用法等同于 [NULL, 2-1, ..., 10-9]
eachPre(+, x);
返回:[,3,5,7,9,11,13,15,17,19]。该用法等同于 [NULL, 2+1, ..., ]。
0 +:P x;
返回:[1,3,5,7,9,11,13,15,17,19]。该用法等同于 [1+0, 2+1, ..., ]。
x=1..12$3:4;
x;
返回:
col1
col2
col3
col4
1
4
7
10
2
5
8
11
3
6
9
12
- :P x;
返回:
col1
col2
col3
col4
3
3
3
3
3
3
3
3
3
eachPre(\, x, x[0]);
返回:
col1
col2
col3
col4
1
4
1.75
1.428571
1
2.5
1.6
1.375
1
2
1.5
1.333333
def f1(a,b){
return (a[`x])+(a[`y])+(b[`x])+(b[`y])
}
t = table(1 2 3 as x,2 3 4 as y)
t1 = table(1 as x,2 as y)
eachPre(f1,t,t1)
返回:([6],8,12)
对比不同的结果组装方式。
tab = table(til(5) as a,`a`a`b`b`c as b)
select *, contextby({x,y->isNull(y) ? [x] : [y,x]}:P,a,b) as c from tab
//使用默认(DolphinDB)规则组装结果
a b c
- - -----
0 a [0]
1 a [0,1]
2 b [2]
3 b [2,3]
4 c 4
select *, contextby({x,y->isNull(y) ? [x] : [y,x]}:PU,a,b) as c from tab
//使用 Tuple 规则组装结果,可以发现最后一行记录的 c 列也输出一个向量
a b c
- - -----
0 a [0]
1 a [0,1]
2 b [2]
3 b [2,3]
4 c [4]
FILE:references/doc_6393.md
# cumwavg
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumwavg.html
**来源**: DolphinDB 官方文档
---
cumwavg
语法
cumwavg(X, Y)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
以
Y
为权重,计算
X
的累计加权平均。
返回值
DOUBLE 类型,其数据形式同
X
(
Y
)。
例子
cumwavg(2.2 1.1 3.3, 4 5 6);
// output
[2.2,1.588889,2.273333]
cumwavg(1 NULL 1, 1 1 1);
// output
[1,1,1]
相关函数:
wavg
FILE:references/doc_6398.md
# randMultivariateNormal
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randMultivariateNormal.html
**来源**: DolphinDB 官方文档
---
randMultivariateNormal
语法
randMultivariateNormal(mean, covar, count, [sampleAsRow=true])
别名:
multivariateNormal
详情
生成服从多元正态分布的随机数。
参数
mean
是一个数组,表示多元正太分布的均值。
covar
是一个正定矩阵,表示多元正太分布的协方差。
count
是一个正整数,表示样本长度。
sampleAsRow
是一个布尔值。默认值为 true,表示输出矩阵的一行是一个样本。如果
sampleAsRow
为
false,表示输出矩阵的一列是一个样本。
返回值
返回一个矩阵。
例子
multivariateNormal([2, 3], [1.0, 1.5, 1.5, 3.0]$2:2, 5);
输出返回:
#0
#1
-0.02395
-0.844505
-0.630637
0.098955
3.001908
4.831809
0.791095
2.01402
1.708191
2.41748
multivariateNormal([2, 3], [1.0, 1.5, 1.5, 3.0]$2:2, 5, false);
输出返回:
#0
#1
#2
#3
#4
0.435419
0.138209
-0.046187
-1.201421
0.069719
0.40163
0.034553
-0.337324
-1.008628
0.822161
FILE:references/doc_6405.md
# replayDS
**URL**: https://docs.dolphindb.cn/zh/funcs/r/replayDS.html
**来源**: DolphinDB 官方文档
---
replayDS
语法
replayDS(sqlObj, [dateColumn], [timeColumn],
[timeRepartitionSchema])
详情
将一个 SQL 表达式,根据时间维度划分为多个数据源,作为
replay
函数的输入,逐一进行回放。时间维度既可以为 DFS 表的时间列的分区粒度,也可以是基于该分区粒度的进一步的划分(由参数
timeColumn
与
timeRepartitionSchema
决定)。
若要回放 DFS 表中的数据,只能使用
replayDS
函数配合
replay
函数进行。
参数
sqlObj
表示 SQL 查询的元代码。SQL 查询的表对象是 DFS 表,且至少有一个分区列为时间类型。
dateColumn
列必须为 SQL 查询的表对象的时间类型列,一般为 DATE 类型,亦可为 MONTH
类型或其它时间类型。作为数据的排序依据。
dateColumn
列必须为表的分区列之一,系统将根据
dateColumn
列的分区粒度划分数据源,如 dateColumn 列按天进行分区,则数据源也按天进行划分。
timeColumn
列必须为 SQL 查询的表对象的时间列,作为数据的排序依据。若
dateColumn
为 DATE 类型时,可以指定
timeColumn
为 SECOND, TIME 或 NANOTIME
类型的列作为第二排序列。此外,配合
timeRepartitionSchema
参数,
timeColumn
列也可以作为数据源划分依据。
注:
dateColumn
和
timeColumn
暂不支持 DATEHOUR 类型的时间列。
如果没有指定
dateColumn
,原数据表的第一列将会作为
dateColumn
。
timeRepartitionSchema
时间类型的向量。如果指定了
timeColumn
,
timeRepartitionSchema
可用于划分更小粒度的数据源。如果
timeRepartitionSchema
为 [t1, t2, t3],均为 TIME 类型,则会将每天的数据进一步划分为 4
个数据源:[00:00:00.000,t1), [t1,t2), [t2,t3) 和 [t3,23:59:59.999)。
返回值
返回一个数据源列表,类型为 ANY VECTOR。
例子
在以下例子中:
创建变量 n。
创建一个包含
IBM
和
GS
的 join 表 sym,并重复该表内容。
创建一个包含 2021.01.04 到 2021.01.06 的日期序列 date,并对其排序,用于模拟交易日。
创建一个包含 09:30:00 到 15:59:59 的时间序列 time 用于模拟交易时间。
创建一个包含随机数(范围在 0 到 100 之间)的交易量序列 volume。
创建一个名为 t 的表,包含符号、日期、时间和交易量这四个字段。
如果名为 "dfs://test_stock" 的数据库存在,则删除该数据库。
创建两个不同类型的数据库 db1 和 db2,分别为 RANGE 类型和 VALUE 类型,并将它们组合到 "dfs://test_stock" 中。
在数据库中创建一个分区表 trades,按 date 和 sym 分区。
向 trades 表追加 t 表的内容。
创建一个 replayDS 对象,从 trades 表中加载数据,并按日期维度和时间维度划分这些数据形成数据源列表 ds。
输出 ds 的大小。
n=int(60*60*6.5)
sym = take(take(`IBM,n).join(take(`GS,n)), n*2*3)
date=take(2021.01.04..2021.01.06, n*2*3).sort!()
time=take(09:30:00..15:59:59,n*2*3)
volume = rand(100, n*2*3)
t=table(sym,date,time,volume)
if(existsDatabase("dfs://test_stock")){
dropDatabase("dfs://test_stock")
}
db1=database("",RANGE, 2021.01.04..2021.01.07)
db2=database("",VALUE,`IBM`GS)
db=database("dfs://test_stock",COMPO,[db1, db2])
trades=db.createPartitionedTable(t,`trades,`date`sym)
trades.append!(t);
ds = replayDS(sqlObj=<select * from loadTable(db, `trades)>, dateColumn=`date, timeColumn=`time)
ds.size();
返回:3。
接着,从数据库中加载名为 trades 表的所有数据,指定
timeRepartitionSchema
为
[11:30:00,
14:00:00]
,按照指定的时间范围对每日数据进行重分区,重新计算数据源列表的大小:
ds = replayDS(sqlObj=<select * from loadTable(db, `trades)>, dateColumn=`date, timeColumn=`time, timeRepartitionSchema=[11:30:00, 14:00:00])
ds.size();
指定时间区间
[11:30:00, 14:00:00]
后,每天的数据被划分为三个更小的部分 [09:30:00,
11:30:00)、[11:30:00, 14:00:00] 和 [14:00, 15:59:59]。
因此,返回:9。
FILE:references/doc_6412.md
# unsubscribeStreamingSQL
**URL**: https://docs.dolphindb.cn/zh/funcs/u/unsubscribeStreamingSQL.html
**来源**: DolphinDB 官方文档
---
unsubscribeStreamingSQL
语法
unsubscribeStreamingSQL([server], queryId)
详情
取消订阅指定的流式 SQL 查询结果。取消订阅后,订阅端的实时结果表将停止更新。
参数
server
可选参数,字符串标量,表示运行流式 SQL 查询的节点(即注册该查询的服务器)的别名或远程连接句柄。如果未指定或者为空字符串,表示流式 SQL
查询所在的服务器是本地实例。
queryId
字符串标量,表示要取消订阅的流式 SQL 查询 ID。
返回值
无。
例子
t=table(1..10 as id,rand(100,10) as val)
share t as st
declareStreamingSQLTable(st)
registerStreamingSQL("select avg(val) from st","sql_avg")
subscribeStreamingSQL(queryId="sql_avg")
// output: 52.1
unsubscribeStreamingSQL(queryId="sql_avg")
相关函数:
declareStreamingSQLTable
,
registerStreamingSQL
,
subscribeStreamingSQL
FILE:references/doc_6414.md
# OLTP 内存存储引擎(非嵌入式版)使用教程
**URL**: https://docs.dolphindb.cn/zh/tutorials/oltp_in-memory_storage_engine_non-embedded_version_tutorials.html
**来源**: DolphinDB 官方文档
---
OLTP 内存存储引擎(非嵌入式版)使用教程
1. 背景
在一些数据库应用场景中,例如金融行业的交易系统,其主要工作负载来源于对关系表的高频度、高并发的更新和查询操作。这样的应用场景要求数据的读写和计算能够具有低延迟、高并发的特征,同时保证极高的数据一致性,并提供 ACID 事务的支持,是典型的在线事务处理(OLTP)场景。传统的存储引擎由于其架构的设计出发点是将数据存储在磁盘上,在面对上述场景要求时,软硬件层面面临巨大挑战,无法很好地满足上述苛刻的性能要求。而在这些场景中,往往需要维护的数据量实际上没有那么大,那么,能否把所有的数据都维护在内存里呢?这样就可以减少读写磁盘的带宽,能够大大降低数据库的延迟和提升数据库的并发度。
基于这个想法,DolphinDB 设计并实现了一款纯自研的内存 OLTP 数据库,它有以下特点:
将所有数据都存储在内存中,省去磁盘 I/O 的开销;
以行存的形式来组织数据,主要适用于 OLTP 的场景;
支持创建 B+ 树索引 (主键索引和二级索引) 来应对高频度、高并发的更新和查询操作;
支持事务,默认为 snapshot isolation;
实现 Write-Ahead-Logging 和 checkpoint 机制以保证数据的持久化和恢复;
为加速重启时的恢复过程,实现了并行恢复机制。
下文将介绍 OLTP 的使用方式。
注:
需要在配置文件里加上
enableIMOLTPEngine=true
来开启 OLTP 引擎。
2. DDL
2.1 建库
使用
database
函数来创建 OLTP 数据库,语法与创建 OLAP/TSDB 数据库一样,但是有以下注意事项:
directory
必须以
oltp://
开头。
engine
必须为
IMOLTP
。
OLTP 目前只支持单机版本,分区方式可以任意填写。
dbName = "oltp://test_imoltp"
db = database(dbName, VALUE, 1..100, , "IMOLTP")
2.2 建表
使用
createIMOLTPTable
函数来创建 OLTP 表,语法如下:
createIMOLTPTable(dbHandle, table, tableName, primaryKey, [secondaryKey], [uniqueFlag])
primaryKey
用来指定主键索引的键。主键索引有且只有一个,每个 OLTP 表都必须指定。主键索引是 unique 的,插入数据时会检查是否满足唯一性约束(即不能插入重复元素),若违反则报错。主键可以包含多个字段(字段即为列名)。
secondaryKey
用来指定二级索引的键。二级索引可选,并且每个 OLTP 表可以创建多个二级索引。二级索引有 unique 和 non-unique 两种,两者的区别在于 unique 索引需要满足唯一性约束,而 non-unique 索引没有这个限制。由
uniqueFlag
来指定二级索引是否是 unique 的。二级索引的键同样可以包含多个字段。
// pt1 以 id 为主键,没有二级索引
pt1 = db.createIMOLTPTable(
table(1:0, ["id", "val1", "val2", "sym"], [LONG, INT, LONG, STRING]),
"test_table_1",
primaryKey=`id
)
// pt2 以 id,sym 为主键,有一个 unique 二级索引:以 val2,sym 为键
pt2 = db.createIMOLTPTable(
table(1:0, ["id", "val1", "val2", "sym"], [LONG, INT, LONG, STRING]),
"test_table_2",
primaryKey=`id`sym,
secondaryKey=`val2`sym,
uniqueFlag=true
)
// pt3 以 id 为主键,有一个非 unique 二级索引:以 val1 为键;一个 unique 二级索引:以 sym 为键
pt3 = db.createIMOLTPTable(
table(1:0, ["id", "val1", "val2", "sym"], [LONG, INT, LONG, STRING]),
"test_table_3",
primaryKey=`id,
secondaryKey=[`val1, `sym],
uniqueFlag=[false, true]
)
通常来说,对于查询效率:主键索引优于二级索引优于非索引,如果查询时不能利用任何索引,则只能进行全表扫描。合理地创建二级索引可以提升查询的效率,但是相应地会降低写入的效率,因为写入时 (insert/delete/update) 需要修改相应的索引。
2.3 删库/删表
使用
dropTable
和
dropDatabase
来删表删库,使用方式与 OLAP/TSDB 没有区别。
db.dropTable("test_table_1")
if (existsDatabase(dbName)) {
dropDatabase(dbName)
}
3. DML
后文的例子假设已经执行过下面的脚本来建库建表:
dbName = "oltp://test_imoltp"
tableName = "test_table"
if (existsDatabase(dbName)) {
dropDatabase(dbName)
}
db = database(dbName, VALUE, 1..100, , "IMOLTP")
// pt 以 id 为主键,没有二级索引
pt = db.createIMOLTPTable(
table(1:0, ["id", "val1", "val2", "sym"], [LONG, INT, LONG, STRING]),
tableName,
primaryKey=`id
)
3.1 写入数据
写入数据可以用
append!
和
insert into
,使用方式与 OLAP/TSDB 一样。
pt = loadTable("oltp://test_imoltp", "test_table")
id = 1..100
val1 = id * 10
val2 = rand(10000, size(id))
sym = take(`aaa`bbb`ccc`ddd`eee, size(id))
pt.append!(table(id, val1, val2, sym))
insert into pt values(200, 2000, 1111, `xxx)
insert into pt values(201, 2010, 2222, `yyy)
insert into pt values(211..220, (211..220)*10, take(9527, 10), take(`xxx`yyy`zzz, 10))
insert into pt(id, sym) values(1000, `aaa)
insert into pt(id, sym, val1) values(1001, `bbb, 10010)
3.2 查询数据
使用 SQL 来查询数据。where 条件非常重要,如果一次查询无法利用索引,那么性能会大幅降低。
pt = loadTable("oltp://test_imoltp", "test_table")
select * from pt where id = 10 // 点查,用主键索引
select * from pt where id > 100, id < 200 // 范围查询,用主键索引
select * from pt where val1 = 1000 // 全表扫描,无法利用索引
3.3 更新数据
使用 SQL 来更新数据。
pt = loadTable("oltp://test_imoltp", "test_table")
update pt set val1 = 100 where id = 1
update pt set val1 = id + val1 where id < 10
3.4 删除数据
使用 SQL 来删除数据。
pt = loadTable("oltp://test_imoltp", "test_table")
delete from pt where id = 1
delete from pt where id >= 100, id <= 110
4. 事务
使用
transaction
语句块可以在一个事务内执行多条 DML 语句,在一个事务范围内,所有的 DML 操作都会一起成功或一起失败。若一个事务执行的时候有异常抛出,会自动撤销本次事务的所有更改。
pt = loadTable("oltp://test_imoltp", "test_table")
delete from pt
transaction {
insert into pt values(0, 0, 0, `aaa)
insert into pt values(1, 1, 1, `bbb)
insert into pt values(2, 2, 2, `ccc)
commit // 提交事务(可以省略)
}
assert (exec id from pt order by id) == [0,1,2]
transaction {
insert into pt values(3, 3, 3, `ddd)
insert into pt values(4, 4, 4, `eee)
delete from pt where id = 1
update pt set id = 10 where id = 0
assert (exec id from pt order by id) == [2,3,4,10]
rollback // 强制回滚事务,撤销所有修改
}
assert (exec id from pt order by id) == [0,1,2]
commit
表示提交本次事务的所有更改,
rollback
表示撤销本次事务的所有更改。不需要显式地写
commit
,出了 transaction 语句块的作用域时会自动 commit。
注:
若不显式地使用 `transaction` 语句块,则每一句 SQL 都是一个事务。
重要:
DDL 语句(即建表,删表等)不能放在 `transaction` 语句块里面,因为 DDL 目前不支持事务。
5. 配置参数
目前 OLTP 有以下配置参数可以设置:
enableIMOLTPEngine
,bool 类型。表示是否开启 OLTP 引擎。默认为 false。
enableIMOLTPRedo
,bool 类型。表示是否开启 WAL(Write-Ahead-Log),开启之后才能保证数据不会丢失。默认为 true。
IMOLTPRedoFilePath
,string 类型。表示 redo 文件(即 WAL 文件)的路径(注意不是目录),可以为绝对路径或者相对路径。当为相对路径时,相对于 home 目录下的
IMOLTP
目录。默认为 home 目录下的
IMOLTP/im_oltp.redo
。
IMOLTPSyncOnTxnCommit
,bool 类型。只在
enableIMOLTPRedo
为 true 时(即开启了 WAL)有意义。默认为 false。详细解释见下文。
enableIMOLTPCheckpoint
,bool 类型。表示是否开启 checkpoint。默认为 true。
IMOLTPCheckpointFilePath
,string 类型。表示 checkpoint 文件的路径(注意不是目录),可以为绝对路径或者相对路径。当为相对路径时,相对于 home 目录下的
IMOLTP
目录。默认为 home 目录下的
IMOLTP/im_oltp.ckp
。
IMOLTPCheckpointThreshold
,long 类型,单位为 MiB。 表示:如果 redo 文件里面的 log 大小达到该阈值后,会触发一次 checkpoint。默认为 100 MiB。
IMOLTPCheckpointInterval
,long 类型,单位为秒。表示每隔 # 秒之后强制做一次 checkpoint。默认为 60 秒。
注:
关于
IMOLTPSyncOnTxnCommit
的含义:
在开启 WAL 后,事务对数据进行修改之前,会先写日志到持久化存储。系统重启时会回放 redo 文件里的日志,恢复到重启之前的状态。
如果
IMOLTPSyncOnTxnCommit
为 false,事务 commit 成功之后,保证日志写到了操作系统的缓存里,但是不保证日志已经写到了持久化存储上。因此,如果进程崩溃, 数据不会丢失, 但是当操作系统崩溃(机器掉电), 可能会有数据丢失。
如果
IMOLTPSyncOnTxnCommit
为 true,在事务 commit 成功之后,保证日志已经写到了持久化存储上,即使操作系统崩溃,数据也不会丢失。(但是如果存储设备故障, 还是可能有数据丢失)。
如果需要持久化数据,并且对数据的一致性要求较高,绝对无法忍受数据丢失,推荐把
enableIMOLTPRedo
和
IMOLTPSyncOnTxnCommit
都设置为 true。这种模式下,(写入)性能较差。
如果需要持久化数据,并且可以容忍操作系统崩溃(比如机器掉电等小概率事件)导致的数据丢失,推荐把
enableIMOLTPRedo
设置为 true, 把
IMOLTPSyncOnTxnCommit
设置为 false。这种模式下,(写入)性能较好。默认为这种配置。
6. 内置函数
triggerCheckpointForIMOLTP
当开启了 checkpoint 时(即
enableIMOLTPCheckpoint
配置为 true ),系统会在达到以下两个条件之一时自动触发 checkpoint:
redo 文件里面的 log 大小达到阈值(
IMOLTPCheckpointThreshold
MiB);
或者,距离上一次 checkpoint 过去了
IMOLTPCheckpointInterval
秒。
用户也可以手动调用
triggerCheckpointForIMOLTP
函数来触发 checkpoint。函数语法如下:
triggerCheckpointForIMOLTP([force=false], [sync=false])
参数:
force
,bool 类型,可选。表示是否强制做 checkpoint。如果为 false,并且当前并没有达到做 checkpoint 的条件(即 redo 文件里的 log 大小没有达到
IMOLTPCheckpointThreshold
),则忽略这次请求。默认为 false。
sync
,bool 类型,可选。表示是否异步。如果为 false,则该函数请求一次异步的 checkpoint,并不会等到请求完成再返回;否则该函数会等到请求完成(注意不一定做了 checkpoint)再返回。默认为 false。
7. 总结
DolphinDB 推出的OLTP 内存数据库适用于高并发、低延迟的在线事务处理场景。该数据库将数据存储在内存中,支持 B+ 树索引、事务、Write-Ahead-Logging 和 checkpoint 机制。事务通过 transaction 语句块实现,保证了操作的原子性。
用户还可以通过配置参数的配置以及内置函数
triggerCheckpointForIMOLTP
的使用,手动触发 checkpoint。
总体而言,DolphinDB 的 OLTP 引擎适用于对数据一致性和性能要求较高的场景。
FILE:references/doc_6425.md
# getAggregator
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getAggregator.html
**来源**: DolphinDB 官方文档
---
getAggregator
是
getStreamEngine
的别名。
FILE:references/doc_6426.md
# multinomialNB
**URL**: https://docs.dolphindb.cn/zh/funcs/m/multinomialNB.html
**来源**: DolphinDB 官方文档
---
multinomialNB
语法
multinomialNB(Y, X, [varSmoothing=1.0])
详情
使用多项式朴素贝叶斯(Multinomial Naive Bayes)算法对数据进行分类训练。
参数
Y
是一个长度与
X
的行数相等的向量,表示
X
中每个样本对应的标签。
X
是一个表,表示训练集。表中每一行表示一个样本,每一列表示一个特征。
varSmoothing
是0到1之间的浮点数,表示平滑系数。
返回值
返回一个字典,包含以下key:
modelName:模型名称,为字符串 "MultinomialNB"。
model:multinomialNB 的内部模型。
varSmoothing:训练时使用的平滑系数。
例子
本例所用数据集 iris.data 可从
https://archive.ics.uci.edu/ml/datasets/iris
下载。
DATA_DIR = "C:/DolphinDB/Data"
t = loadText(DATA_DIR+"/iris.data")
t.rename!(`col0`col1`col2`col3`col4, `sepalLength`sepalWidth`petalLength`petalWidth`class)
t[`classType] = take(0, t.size())
update t set classType = 1 where class = "Iris-versicolor"
update t set classType = 2 where class = "Iris-virginica"
training = select sepalLength, sepalWidth, petalLength, petalWidth from t
labels = t.classType
model = multinomialNB(labels, training);
predict(model, training);
FILE:references/doc_6428.md
# iminLast
**URL**: https://docs.dolphindb.cn/zh/funcs/i/iminlast.html
**来源**: DolphinDB 官方文档
---
iminLast
语法
iminLast(X)
详情
若
X
是向量,返回最小元素的位置。如果有多个相同的最小值,返回右起第一个最小值的位置。与所有其它聚合函数一致,计算时忽略 NULL 值。
若
X
为矩阵,计算在每列内部进行,返回一个向量。
若
X
为表,计算在每列内部进行,返回一个表。
参数
X
可以是标量、向量、矩阵或表。
例子
x = 1.2 2 NULL -1 6 -1
iminLast(x);
// output: 5
m=matrix(3 2 2 4 2, 1 4 2 1 3);
iminLast(m)
// output: [4,3]
t=table(3 2 2 as c1, 1 1 4 as c2)
iminLast(t)
/* output:
c1 c2
2 1
*/
相关函数:
imin
FILE:references/doc_6436.md
# 异步复制
**URL**: https://docs.dolphindb.cn/zh/sys_man/cluster_async_replc.html
**来源**: DolphinDB 官方文档
---
异步复制
集群间的异步复制指通过异步方式,将主集群复制到从集群,使主从集群数据一致。集群间的异步复制是集群异地容灾的一个解决方案,通常主集群用于实时的业务查询,而从集群则是作为主集群的一个备份。
与传统集群间的异步复制解决方案相比,DolphinDB 具有以下优势:
容错性强。节点宕机不会造成数据丢失,主从集群数据最终会保持一致。
运维便捷。提供在线监控函数以及错误修复函数。
支持情况
仅支持分布式表,暂不支持内存表和本地磁盘表。
对 DDL(Data Definition Language)/DML(Data Manipulation
Language) 操作的支持情况请参见下表。
不支持权限管理、分级存储以及存储引擎配置修改等非 DDL/DML 操作。
支持
对应操作类型(operationType)
append / tableInsert
APPEND、APPEND_CHUNK_GRANULARITY(APPEND Best Effort)
delete
SQL_DELETE
update
SQL_UPDATE
upsert!
UPSERT
dropTable
DROP_TABLE
dropPartition
DROP_PARTITION
dropDatabase
DROP_DB
addRangePartitions
ADD_RANGE_PARTITION
addValuePartitions
ADD_VALUE_PARTITION
database
CREATE_DOMAIN
create, createPartitionedTable, createTable
CREATE_TABLE, CREATE_PARTITIONED_TABLE
addColumn
ADD_COLUMN
dropColumns
DROP_COLUMN
renameTable
RENAME_TABLE
truncate
TRUNCATE_TABLE
replaceColumn
REPLACE_COLUMN
setColumnComment
SET_COLUMN_COMMENT
rename!
RENAME_COLUMN
异步复制流程
(1)启用集群间的异步复制,在配置文件指定相关配置参数。
(2)配置完成后,启动服务器。在主集群数据节点调用
setDatabaseForClusterReplication("dfs://xxx", true)
,开启某个数据库集群间的异步复制(一次调用只启动一个数据库的异步复制)。
(3)主集群开启异步复制后,从集群自动到主集群拉取异步复制任务,然后逐一执行。
(4)若从集群某个数据库的异步复制任务多次失败导致整个异步复制中断,用户可以尝试以下方案解决:
在从集群控制节点调用
startClusterReplication
函数尝试重启异步复制。
在从集群控制节点调用
getSlaveReplicationStatus
函数,查看从集群异步复制任务的失败原因,解决后再调用
startClusterReplication
函数重启。
若无法解决失败任务,可以在从集群控制节点调用
skipClusterReplicationTask
函数跳过该任务,再调用
startClusterReplication
函数重启。
(5)若需要停止所有数据库的异步复制,可以在主集群和从集群的控制节点分别调用
stopClusterReplication
函数。调用后,正在执行的任务会继续进行,但主集群不再将异步复制任务放进发送队列,从集群不再从主集群拉取异步复制任务。
(6)若要停止某个数据库的异步复制,可以调用
setDatabaseForClusterReplication("dfs://xxx", false)
。调用后,正在执行的任务会继续进行,但该数据库不再产生异步复制任务。
异步复制机制
主集群:
(1)事务完成后,根据两阶段提交协议,协调节点发送 “commit”
信号给控制节点,同时将事务的元数据发送给控制节点。若为写事务,则协调节点将该事务的数据持久化到本地。
(2)控制节点收到事务元数据后,将其持久化到 DFS 元数据文件
(3)协调节点发送事务 “complete” 信号给控制节点。
(4)控制节点将已经完成的事务的元数据放入发送队列。并根据入列先后标记任务的 taskID。
(5)对发送队列内的任务进行冲突检测。若两个任务写入或修改的 chunk 存在交集,则被认为是冲突的。
(6)根据事务的执行顺序和是否冲突,为其标记组号 groupID,系统保证同一组的任务是可以并行执行的。
从集群(
记录一个偏移量标记从主集群拉取任务的 taskID
):
(1)控制节点根据偏移量从主集群发送队列获取任务以及执行集信息。
(2)根据任务的执行集信息,将获取的任务分为两个执行集。
(3)根据目标数据库的不同,将每个执行集中的任务分配到对应的执行队列。
(4)将执行队列中的任务根据组号 groupID 排序。
(5)根据哈希算法将执行队列映射到从集群的数据节点。每个队列依次将自己的事务发送给对应节点。
(6)若数据节点检测到该任务为写操作,则根据元数据中主集群节点的 ip:port,将任务的数据从主集群拉取到本地。
(7)根据任务对应的执行语句,在当前节点发起事务。多个数据节点间可以并发执行同一任务组的任务(即不冲突的任务可以并发执行)。若同一组任务中,有任务执行失败,则不再执行下一组任务。
(8)事务完成后,根据两阶段提交协议,数据节点发送 “commit” 信号给控制节点。
(9)控制节点将已经提交的任务的 taskID 写入 EditLog。
(10)数据节点发送 “complete” 信号给控制节点。控制节点收到后,标记该任务为完成状态。并继续执行步骤(5)到(10)。
(11)控制节点将标记为完成状态的 taskID 发送给主集群,主集群发送队列根据该信息进行垃圾回收。
注:
步骤(11)和步骤(1)同时进行。
若从集群增加了节点,步骤(5)的哈希算法仍基于原节点数进行映射,因此异步复制任务不会被分配到新增加的节点上。
FILE:references/doc_6445.md
# moveHotDataToColdVolume
**URL**: https://docs.dolphindb.cn/zh/funcs/m/moveHotDataToColdVolume.html
**来源**: DolphinDB 官方文档
---
moveHotDataToColdVolume
语法
moveHotDataToColdVolume([checkRange=240])
详情
强制触发将用户指定范围的数据转存至
coldVolumes
。
注:
该命令仅对当前节点有效。集群环境中,可通过
pnodeRun
调用该函数,使其在其它节点生效。
该命令设置的转存策略与
setRetentionPolicy
设置的转存策略的有区别,详情请参考
TieredStorage
。
参数
checkRange
整数,单位为小时,默认值为 10 天,即 240 小时。用于设置需迁移至
coldVolumes
的数据的时间范围。设置后,时间范围在 [当前时间 -
hoursToColdVolumes
-
checkRange
, 当前时间 -
hoursToColdVolumes
) 内的数据将会被迁移至
coldVolumes
。
FILE:references/doc_6447.md
# moving
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/moving.html
**来源**: DolphinDB 官方文档
---
moving
语法
moving(func, funcArgs, window, [minPeriods])
详情
应用函数/运算符到给定对象的一个滚动窗口上。
当第一个滑动窗口出现时高阶函数开始计算,每计算一次,滑动窗口向右移动一个元素。
内置函数
msum
,
mcount
和
mavg
为各自的计算场景进行了优化,因此比
moving
高阶函数有更好的性能。
参数
func
是一个
聚合
函数。
注:
使用该参数时,用于定义相应聚合函数的关键词为
defg
。有关
defg
的详细用法,参考:
自定义聚合函数
。
funcArgs
是函数 func
的参数。可为向量、字典或矩阵。如果有多个参数,则用元组表示,并且每个参数的长度(向量/字典的元素个数)必须相同。
window
是正整型 或 DURATION 标量。
当
window
是整型时,表示以窗口内元素个数衡量的滑动窗口的长度。
当
window
是 DURATION
时,表示以时间衡量的滑动窗口的长度。此时,
X
必须是带有时间类型行索引的索引矩阵或者索引序列。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。如果滑动窗口中的观测值小于
minPeriods
,那么该窗口的结果为 NULL 值。默认值与
window
相等。 如果
window
是 DURATION,且需要设置
minPeriods
时,
minPeriods
必须是
1。
有关其他 m 系列函数的参数说明和窗口计算规则,参考:
滑动窗口系列(m 系列)
返回值
一个向量,长度与输入参数的长度相同。
例子
计算 APPL 相对于市场(SPY) 的 moving beta,移动窗口长度为 10。
date=2016.08.01..2016.08.31
date=date[1<=weekday(date)<=5]
aaplRet=0.0177 -0.0148 0.0125 0.0008 0.0152 0.0083 0.0041 -0.0074 -0.0006 0.0023 0.0120 -0.0009 -0.0015 -0.0013 0.0026 -0.0078 0.0031 -0.0075 -0.0043 -0.0059 -0.0011 -0.0077 0.0009
spyRet=-0.0008 -0.0064 0.0029 0.0011 0.0082 -0.0006 0.0006 -0.0025 0.0046 -0.0009 0.0029 -0.0052 0.0019 0.0022 -0.0015 0.0000 0.0020 -0.0051 -0.0007 -0.0019 0.0049 -0.0016 -0.0028
t=table(date, aaplRet, spyRet);
t;
输出返回:
date
aaplRet
spyRet
2016.08.01
0.0177
-0.0008
2016.08.02
-0.0148
-0.0064
2016.08.03
0.0125
0.0029
2016.08.04
0.0008
0.0011
2016.08.05
0.0152
0.0082
2016.08.08
0.0083
-0.0006
2016.08.09
0.0041
0.0006
2016.08.10
-0.0074
-0.0025
2016.08.11
-0.0006
0.0046
2016.08.12
0.0023
-0.0009
2016.08.15
0.012
0.0029
2016.08.16
-0.0009
-0.0052
2016.08.17
-0.0015
0.0019
2016.08.18
-0.0013
0.0022
2016.08.19
0.0026
-0.0015
2016.08.22
-0.0078
0
2016.08.23
0.0031
0.002
2016.08.24
-0.0075
-0.0051
2016.08.25
-0.0043
-0.0007
2016.08.26
-0.0059
-0.0019
2016.08.29
-0.0011
0.0049
2016.08.30
-0.0077
-0.0016
2016.08.31
0.0009
-0.0028
通过以下语句计算移动 beta:
update t set beta_value=moving(beta, [aaplRet, spyRet],10);
t;
输出返回:
date
aaplRet
spyRet
beta_value
2016.08.01
0.0177
-0.0008
2016.08.02
-0.0148
-0.0064
2016.08.03
0.0125
0.0029
2016.08.04
0.0008
0.0011
2016.08.05
0.0152
0.0082
2016.08.08
0.0083
-0.0006
2016.08.09
0.0041
0.0006
2016.08.10
-0.0074
-0.0025
2016.08.11
-0.0006
0.0046
2016.08.12
0.0023
-0.0009
1.601173
2016.08.15
0.012
0.0029
1.859846
2016.08.16
-0.0009
-0.0052
1.248804
2016.08.17
-0.0015
0.0019
1.114282
2016.08.18
-0.0013
0.0022
1.064296
2016.08.19
0.0026
-0.0015
0.512656
2016.08.22
-0.0078
0
0.614963
2016.08.23
0.0031
0.002
0.642491
2016.08.24
-0.0075
-0.0051
0.70836
2016.08.25
-0.0043
-0.0007
0.977279
2016.08.26
-0.0059
-0.0019
1.064465
2016.08.29
-0.0011
0.0049
0.422221
2016.08.30
-0.0077
-0.0016
0.793236
2016.08.31
0.0009
-0.0028
0.588027
minPeriods
的作用:
moving(avg, 1..4, 3);
输出返回:[,,2,3]
moving(avg, 1..4, 3, 1);
输出返回:[1,1.5,2,3]
v1=indexedSeries(2020.08.01..2020.08.04,1..4)
moving(avg, v1, 3d, 1);
输出返回:
label
col1
2020.08.01
1
2020.08.02
1.5
2020.08.03
2
2020.08.04
3
moving
高阶函数的参数
func
的所有参数必须要有相同的长度。如果
func
的参数长度不等,例如
percentile
函数,可以使用
部分应用
产生一个新的函数以满足此要求。请见下例:
moving(percentile{,50},1..20, 10);
输出返回:[,,,,,,,,,5.5,6.5,7.5,8.5,9.5,10.5,11.5,12.5,13.5,14.5,15.5]
性能提示
计算移动均值时,应该使用内置函数
mavg
而不是
moving
高阶函数,这是因为内置版本是经过优化的版本,运行速度比高阶函数更快。
n=1000000
x=norm(0,1, n);
timer mavg(x, 10);
输出返回:Time elapsed: 3.501ms
timer moving(avg, x, 10);
输出返回:Time elapsed: 976.03ms
FILE:references/doc_6452.md
# shuffle!
**URL**: https://docs.dolphindb.cn/zh/funcs/s/shuffle_.html
**来源**: DolphinDB 官方文档
---
shuffle!
shuffle!
是
shuffle
的原地计算的版本。
FILE:references/doc_6462.md
# invExp
**URL**: https://docs.dolphindb.cn/zh/funcs/i/invExp.html
**来源**: DolphinDB 官方文档
---
invExp
语法
invExp(mean, X)
详情
返回指数分布的累计密度函数的逆函数值。
参数
mean
是指数分布的均值。
X
是0到1之间的浮点型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
invExp(1, [0.05, 0.15, 0.25, 0.35]);
// output: [0.051293, 0.162519, 0.287682, 0.430783]
invExp(1, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output: [0.105361, 0.356675, 0.693147, 1.203973, 2.302585]
FILE:references/doc_6470.md
# nanosecond
**URL**: https://docs.dolphindb.cn/zh/funcs/n/nanosecond.html
**来源**: DolphinDB 官方文档
---
nanosecond
语法
nanosecond(X)
详情
返回
X
中的纳秒数。
参数
X
可以是 TIME, TIMESTAMP, NANOTIME 或 NANOTIMESTAMP
类型的标量或向量。
返回值
INT 类型标量或向量。
例子
nanosecond(13:30:10.008);
// output
8000000
nanosecond([2012.12.03 01:22:01.999999999, 2012.12.03 01:25:08.000000234]);
// output
[999999999,234]
相关函数:
dayOfYear
,
dayOfMonth
,
quarterOfYear
,
monthOfYear
,
weekOfYear
,
hourOfDay
,
minuteOfHour
,
secondOfMinute
,
millisecond
,
microsecond
FILE:references/doc_648.md
# quantile
**URL**: https://docs.dolphindb.cn/zh/funcs/q/quantile.html
**来源**: DolphinDB 官方文档
---
quantile
语法
quantile(X, q, [interpolation='linear'])
详情
计算
X
的分位数。
参数
X
是一个数值型向量、矩阵或表。
q
是0到1之间的浮点数。
interpolation
是一个字符串,表示当选中的分位点位于 i 和 j 之间时,采用的插值方法。它具有以下取值:
'linear': i+(j-1)*fraction, fraction 是 size(X)*q
的小数部分
'lower':i
'higher': j
'nearest': i 和 j 之中最接近分位点的数据
'midpoint': (i+j)/2
如果没有指定
interpolation
,默认采用 'linear'。
返回值
DOUBLE 类型标量或向量。
例子
a=[6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36];
quantile(a,0.25);
// output
25.5
quantile(a,0.5);
// output
40
quantile(a,0.75);
// output
42.5
quantile(a,0.75, 'lower');
// output
42
相关函数:
quantileSeries
,
percentile
FILE:references/doc_6480.md
# trueRange
**URL**: https://docs.dolphindb.cn/zh/funcs/t/trueRange.html
**来源**: DolphinDB 官方文档
---
trueRange
语法
trueRange(high, low, close)
详情
计算真实波幅,即 | 最高价-最低价 | 和 | 最高价-昨收 | 和 | 昨收-最低价 | 的最大值。
参数
high
,
low
和
close
是等长的数值型向量。
返回值
DOUBLE 类型向量。
例子
sym=take(`A`B,10)
date=2020.01.01 2020.01.01 2020.01.02 2020.01.02 2020.01.03 2020.01.03 2020.01.04 2020.01.04 2020.01.05 2020.01.05
high=[11.48,10.23,12.26,10.7,12.24,10.45,12.3,10.51,12.24,10.49]
low=[10.91,9.41,11.18,10,11.71,9.83,11.62,9.91,11.1,9.6]
close=[11.38,10.22,12.1,10.31,11.89,10.21,12.13,10.47,11.35,9.81]
t=table(sym,date,high,low,close)
select sym,trueRange(high,low,close) as trange from t context by sym;
sym
trange
A
A
1.08
A
0.53
A
0.68
A
1.14
B
B
0.7
B
0.62
B
0.6
B
0.89
FILE:references/doc_6487.md
# oneHot
**URL**: https://docs.dolphindb.cn/zh/funcs/o/oneHot.html
**来源**: DolphinDB 官方文档
---
oneHot
语法
oneHot(obj, encodingColumns)
详情
对指定的列进行独热编码(one-hot),返回编码后的表,列的顺序为编码列,非编码列。其中,编码列的列名格式为:原字段名_值。
参数
obj
是一个内存表。
encodingColumns
是一个字符串或者字符串向量,指定用于编码的列名。
返回值
一个表。
例子
t = table( take(`Tom`Lily`Jim, 10) as name, take(true false, 10) as gender, take(21..23,10) as age);
oneHot(t, `name`gender);
输出返回:
name_Tom
name_Lily
name_Jim
gender_1
gender_0
age
1
0
0
1
0
21
0
1
0
0
1
22
0
0
1
1
0
23
1
0
0
0
1
21
0
1
0
1
0
22
0
0
1
0
1
23
1
0
0
1
0
21
0
1
0
0
1
22
0
0
1
1
0
23
1
0
0
0
1
21
FILE:references/doc_6492.md
# loadIPCInMemoryTable
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadIPCInMemoryTable.html
**来源**: DolphinDB 官方文档
---
loadIPCInMemoryTable
语法
loadIPCInMemoryTable(tableName)
详情
加载跨进程共享内存表,并返回该表的句柄。
注意:此函数仅适用于 Linux 系统。
参数
tableName
字符串,表示跨进程共享内存表的名称。
返回值
一个共享内存表句柄。
例子
加载函数
createIPCInMemoryTable
例子中创建的表 ipc_table。
ipc_t = loadIPCInMemoryTable("ipc_table")
ipc_t
// output
timestamp temperature
FILE:references/doc_6493.md
# sqrt
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sqrt.html
**来源**: DolphinDB 官方文档
---
sqrt
语法
sqrt(X)
详情
计算
X
中每个元素的平方根。
参数
X
可以是标量、向量或矩阵。
返回值
DOUBLE 类型的标量、向量或矩阵。
例子
sqrt(4 16 -4 NULL);
// output
[2,4, , ]
typestr(sqrt(4));
// output
DOUBLE
FILE:references/doc_6496.md
# decimalFormat
**URL**: https://docs.dolphindb.cn/zh/funcs/d/decimalFormat.html
**来源**: DolphinDB 官方文档
---
decimalFormat
语法
decimalFormat(X, format)
参数
X
可以是整型或浮点型的标量或向量。
format
是表示格式的字符串。
详情
把数字转换成指定格式的字符串。
标志
含义
备注
0
强制数字位数
备注1
#
可选数字位数
备注2
.
小数点
%
百分号
备注3
E
科学计数法的符号
备注4
,
分隔符
备注5
;
表示正数和负数的符号
备注6
备注1:小数点之前0的个数表示整数部分的位数。与之对比,小数点之后0的个数表示小数部分的位数。
decimalFormat(123,"0");
// output: 123
decimalFormat(123,"00000");
// output: 00123
decimalFormat(123.45,"0");
// output: 123
decimalFormat(123.45,"0.0");
// output: 123.5
decimalFormat(123.45,"0.000");
// output: 123.450
decimalFormat(123.45, ".0");
// output: 123.5
decimalFormat(0.45, ".0");
// output: .5
备注2:如果0与#同时在小数点后使用,0必须在#前面。
decimalFormat(123.45,"0.#");
// output: 123.5
decimalFormat(123.45,"0.###");
// output: 123.45
decimalFormat(123.456,"0.000###");
// output: 123.456
decimalFormat(123.456789110,"0.000###");
// output: 123.456789
decimalFormat(0.345, ".##");
// output: .35
备注3:%用于格式字符串的结尾。%和 E 在一个格式字符串中不能同时出现。
decimalFormat(0.125,"0.00%");
// output: 12.50%
decimalFormat(0.125, "#.##%");
// output: 12.5%
decimalFormat(0.12567,"#.##%");
// output: 12.57%
备注4:E 后面只能紧跟0,并且至少紧跟一个0。
decimalFormat(1234567.89,"0.##E00");
// output: 1.23E06
decimalFormat(0.0000000000123456789,"0.000E0");
// output: 1.235E-11
备注5:分隔符在一个格式字符串中只能出现一次。分隔符与小数点之间的位数或分隔符到结尾的位数即为分隔的间距。
decimalFormat(123456789,"#,###");
// output: 123,456,789
decimalFormat(123456789.166,"#,###.##");
// output: 123,456,789.17
decimalFormat(123456789.166,"0,000.00");
// output: 123,456,789.17
备注6:我们可以使用";"来选择数字对象的正负。
decimalFormat(123.456,"0.00#E00;(0.00#E00)");
// output: 1.235E02
decimalFormat(-123.456,"0.00#E00;(0.00#E00)");
// output: (1.235E02)
FILE:references/doc_6502.md
# objectChecksum
**URL**: https://docs.dolphindb.cn/zh/funcs/o/objectChecksum.html
**来源**: DolphinDB 官方文档
---
objectChecksum
语法
objectChecksum(vector, [prev])
详情
计算向量的校验和,返回一个整数。通常用于校验数据的完整性。
参数
vector
向量。用于进行校验和(checksum)计算。
prev
整数。当
vector
过长时,可以通过指定
prev
分段迭代求完整的校验和,
prev
表示迭代时前一段数据的校验和。
返回值
一个整数。
例子
print objectChecksum(take(`A`B`C, 10))
// output
-268298654
print objectChecksum(2.3 6.5 7.8)
// output
-430996932
// 分段计算校验和
print objectChecksum(1..15)
// output
-1877567753
t0 = objectChecksum(1..5)
t1 = objectChecksum(6..10, t0)
t2 = objectChecksum(11..15, t1)
print t2
// output
-1877567753
FILE:references/doc_6511.md
# loadText
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadText.html
**来源**: DolphinDB 官方文档
---
loadText
语法
loadText(filename, [delimiter], [schema], [skipRows=0]
, [arrayDelimiter], [containHeader],
[arrayMarker]
)
详情
将数据文件加载到 DolphinDB 的内存表中。
loadText
使用单个线程加载数据,如果需要使用多个线程并行加载数据,请使用
ploadText
函数。
解析列名:
不指定
containHeader
时,
导入文本文件时将以字符串格式读取第一行数据,并根据该数据解析列名。但需要注意,系统内部对第一行数据设置了读取上限,即不能超过
256
KB。解析时,如果文件中第一行的内容不包含以数字开头的数据,那么加载文件时系统会将第一行作为列名。如果文件第一行记录中某列记录以数字开头,那么加载文件时系统可能会使用col0,
col1, ...等作为列名。
指定
containHeader
= true
时,则系统将第一行数据视为标题行,并解析出列名。
指定
containHeader
= false 时,则系统将添加列名 col0,
col1, ... 。
解析类型:
当 DolphinDB
加载数据文件时,会进行随机抽样,并基于样本决定每列的数据类型。这个方法不一定每次都能准确决定各列的数据类型。因此我们建议,在加载数据前,使用
extractTextSchema
函数查看 DolphinDB 识别每列的数据类型。
当加载的数据文件中包含了表达时间、日期的数据时,满足分隔符要求的这部分数据(日期数据分隔符包含"-"、"/"和".",时间数据分隔符为":")会解析为相应的类型。例如,"12:34:56"解析为SECOND类型;"23.04.10"解析为DATE类型。对于不包含分隔符的数据,形如"yyMMdd"的数据同时满足0<=yy<=99,0<=MM<=12,1<=dd<=31,会被优先解析成DATE;形如"yyyyMMdd"的数据同时满足1900<=yyyy<=2100,0<=MM<=12,1<=dd<=31会被优先解析成DATE。
如果 DolphinDB 识别的数据类型不符合预期,可以在 schema 的 type 列中指定数据类型。对于日期列或时间列,如果
DolphinDB 识别的数据类型不符合预期,不仅需要在 schema 的 type 列指定时间类型,还需要在 format
列中指定数据文件中日期或时间的格式(用字符串表示),如 "MM/dd/yyyy"。如何表示日期和时间格式请参考
ParsingandFormatofTemporalVariables
。
如果只需加载数据文件中的部分列,需要在 schema 的 col 列中指定要加载的列的下标。
由于 DolphinDB 的字符串采用 UTF-8 编码,加载的文件必须是 UTF-8 编码。
由于 DolphinDB 中列名仅可使用中文或英文字母、数字或下划线
(_),且必须以中文或英文字母开头,若数据文件中的列名不符合要求,系统会依据以下规则自动调整列名:
若数据中列名存在中文或英文字母、数字或下划线之外的字符,将其转换为下划线。
若数据中列名第一个字符不是中文或英文字母,添加 "c" 作为该列名首字符。
以下是数据文件中不合规列名以及自动转换的列名的例子:
数据文件中列名
自动转换的列名
1_test
c1_test
test-a!
test_a_
[test]
c_test_
注:
从 2.00.10
版本开始,
loadText
支持加载一条记录中包含多个换行符的数据文件。
参数
filename
字符串,表示数据文件的路径。仅支持 CSV 格式的文件。若传入其他格式文件,则无法保证数据准确性。
delimiter
字符串标量,表示数据文件中各列的分隔符。分隔符可以是一个或多个字符,默认是逗号(",")。
schema
表对象,用于指定各字段的数据类型。它可以包含以下四列(其中,name 和 type 这两列是必需的)
列名
含义
name
字符串,表示列名
type
字符串,表示各列的数据类型。暂不支持 BLOB, COMPLEX, POINT, DURATION
类型。
format
字符串,表示数据文件中日期或时间列的格式
col
整型,表示要加载的列的下标。该列的值必须是升序。
注:
若 type 为时间类型,则源数据的时间类型格式需要和 DolphinDB 时间类型数据格式一致。若原始数据的时间戳和
DolphinDB 时间类型不兼容,建议导入时先指定为字符串类型,再通过
temporalParse
函数进行转换。
skipRows
0 到 1024 之间的整数,表示从文件头开始忽略的行数。它是一个可选参数。默认值为 0。
arrayDelimiter
数据文件中数组向量列的分隔符。默认是逗号。由于不支持自动识别数组向量,必须同步修改
schema
的 type 列修为数组向量类型。
containHeader
布尔值,表示数据文件是否包含标题行,默认为空。若不设置,则系统将会分析第一行数据并确定其是否为标题行。不同设置下,列名解析规则见详情描述。
arrayMarker
包含两个字符的字符串或或 CHAR
类型数据对,两个字符分别表示数组向量左右边界的标识符。默认标识符为双引号(")。
不能包含空格、Tab(
\t
)
和换行符(
\t
和
\n
)。
不能包含数字或字母。
如果其中一个为双引号("),另一个也必须为双引号。
如果标识符为
'
,
"
或
\
,需视情况添加转义符。例如
arrayMarker="\"\""
。
如果
delimiter
是单个字符,则
arrayMarker
不能包含与其相同的字符。
如果
delimiter
是多个字符,则
arrayMarker
左边界不能与
delimiter
的首个字符相同。
返回值
一张表。
例子
首先,使用以下脚本生成模拟的数据文件:
n=10
sym=rand(`AAPL`ORCL`MS`SUN,n)
permno=take(10001,n)
date=rand(2019.06.01..2019.06.10,n)
open=rand(100.0,n)
high=rand(200.0,n)
close=rand(200.0,n)
pre_close=rand(200.0,n)
change=rand(100.0,n)
vol=rand(10000,n)
amount=rand(100000.0,n)
t=table(sym,permno,date,open,high,close,pre_close,change,vol,amount)
saveText(t,"/home/DolphinDB/Data/stock.csv");
例 1. 直接加载数据文件
tt=loadText("/home/DolphinDB/Data/stock.csv");
// output
tt;
sym
permno
date
open
high
close
pre_close
change
vol
amount
MS
10001
2019.06.06
90.346594
80.530542
96.474428
146.305659
0.720236
1045
90494.568297
AAPL
10001
2019.06.07
91.165315
8.482074
85.514922
16.259077
76.797829
7646
91623.485996
AAPL
10001
2019.06.03
45.361885
14.077451
149.848419
89.110375
45.499145
9555
98171.601654
MS
10001
2019.06.04
8.98688
0.591778
155.54643
132.423187
69.95799
1202
3512.927634
MS
10001
2019.06.07
62.866173
33.465237
174.20712
102.695818
74.580523
3524
61943.64517
MS
10001
2019.06.09
32.819915
13.319577
136.729618
63.980405
60.66375
7078
85138.216568
MS
10001
2019.06.07
90.210866
22.728777
150.212291
59.454705
73.916303
5306
19883.845607
AAPL
10001
2019.06.06
83.752686
71.3501
98.211979
145.60098
94.428343
8852
9236.020781
ORCL
10001
2019.06.01
81.64719
129.702202
182.784373
117.575967
74.84595
2942
43394.871242
AAPL
10001
2019.06.02
10.068382
80.875383
181.674585
138.783821
25.298267
1088
82981.043775
schema(tt).colDefs;
name
typeString
typeInt
comment
sym
SYMBOL
17
permno
INT
4
date
DATE
6
open
DOUBLE
16
high
DOUBLE
16
close
DOUBLE
16
pre_close
DOUBLE
16
change
DOUBLE
16
vol
INT
4
amount
DOUBLE
16
例 2. 指定某列的数据类型来加载数据文件
例如,我们想要把 permno 列的数据类型转换成 SYMBOL,可以用
extractTextSchema
函数获取输入文件的结构,在导入数据前修改该列的数据类型,并指定
loadText
函数的
schema
参数。
schema=extractTextSchema("/home/DolphinDB/Data/stock.csv");
update schema set type=`SYMBOL where name=`permno;
tt=loadText("/home/DolphinDB/Data/stock.csv",,schema);
schema(tt).colDefs;
name
typeString
typeInt
comment
sym
SYMBOL
17
permno
SYMBOL
17
date
DATE
6
open
DOUBLE
16
high
DOUBLE
16
close
DOUBLE
16
pre_close
DOUBLE
16
change
DOUBLE
16
vol
INT
4
amount
DOUBLE
16
用户也可以指定所有数据类型:
schematable=table(`sym`permno`date`open`high`close`pre_close`change`vol`amount as name,`SYMBOL`SYMBOL`DATE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`INT`DOUBLE as type)
tt=loadText("/home/DolphinDB/Data/stock.csv",,schematable)
schema(tt).colDefs;
name
typeString
typeInt
comment
sym
SYMBOL
17
permno
SYMBOL
17
date
DATE
6
open
DOUBLE
16
high
DOUBLE
16
close
DOUBLE
16
pre_close
DOUBLE
16
change
DOUBLE
16
vol
INT
4
amount
DOUBLE
16
例 3. 只加载部分列
例如,只需加载 sym, date, open, high, close, vol, amount 这 7
列。注意,加载数据时,不能改变各列的先后顺序。如果需要调整列的顺序,可以将数据文件加载后,再使用
reorderColumns!
函数。
schema=extractTextSchema("/home/DolphinDB/Data/stock.csv");
schema=select * from schema where name in `sym`date`open`high`close`vol`amount
schema[`col]=[0,2,3,4,5,8,9]
tt=loadText("/home/DolphinDB/Data/stock.csv",,schema);
tt;
sym
date
open
high
close
vol
amount
SUN
2019.06.10
18.675316
72.754005
136.463909
1376
31371.319038
AAPL
2019.06.05
42.098717
196.873587
41.513899
3632
9950.864129
ORCL
2019.06.05
62.223474
197.099027
123.785675
3069
38035.800937
SUN
2019.06.03
0.18163
50.669866
4.652098
6213
1842.198893
SUN
2019.06.06
32.54134
67.012502
130.312294
4891
55744.156823
SUN
2019.06.07
56.899091
81.709825
61.786176
1133
69057.849515
AAPL
2019.06.08
77.026838
38.504431
22.68496
3672
34420.187073
ORCL
2019.06.07
62.752656
39.33621
48.483091
4382
41601.601639
AAPL
2019.06.02
8.5487
17.623418
141.88325
8092
15449.159988
AAPL
2019.06.02
26.178685
197.320455
110.52407
5541
14616.820449
例 4. 加载文件时,忽略数据文件的前 2 行。
示例文件的第一行为列名,因此忽略前 2 行后,总的数据条数为 9。
re=loadText(filename="/home/DolphinDB/Data/stock.csv",skipRows=2)
select count(*) from re;
count
9
例 5. 指定时间类型的格式来加载数据文件
生成本例所需的数据文件:
time=["20190623145457","20190623155423","20190623163025"]
sym=`AAPL`MS`IBM
qty=2200 5400 8670
price=54.78 59.64 65.23
t=table(time,sym,qty,price)
saveText(t,"/home/DolphinDB/Data/t2.csv");
加载数据前,使用
extractTextSchema
函数获取该数据文件的结构:
extractTextSchema("/home/DolphinDB/Data/t2.csv");
name
type
time
LONG
sym
SYMBOL
qty
INT
price
DOUBLE
由于 time 列的时间格式与 DolphinDB 中的时间格式不同,如果直接加载该文件,time 列的数据将会被识别为长整型。为了能够正确加载该文件 time
列的数据,需要指定 time 列的数据类型为 DATETIME,并且指定该列的格式为 "yyyyMMddHHmmss"。
schema=extractTextSchema("/home/DolphinDB/Data/t2.csv")
update schema set type = "DATETIME" where name = "time"
schema[`format]=["yyyyMMddHHmmss",,,];
loadText("/home/DolphinDB/Data/t2.csv",,schema);
time
sym
qty
price
2019.06.23T14:54:57
AAPL
2200
54.78
2019.06.23T15:54:23
MS
5400
59.64
2019.06.23T16:30:25
IBM
8670
65.23
例 6. 加载包含数组向量列的数据
使用以下脚本模拟生成一个 csv 文本文件:
bid = array(DOUBLE[], 0, 20).append!([1.4799 1.479 1.4787, 1.4796 1.479 1.4784, 1.4791 1.479 1.4784])
ask = array(DOUBLE[], 0, 20).append!([1.4821 1.4825 1.4828, 1.4818 1.482 1.4821, 1.4814 1.4818 1.482])
TradeDate = 2022.01.01 + 1..3
SecurityID = rand(`APPL`AMZN`IBM, 3)
t = table(SecurityID as `sid, TradeDate as `date, bid as `bid, ask as `ask)
t;
saveText(t,filename="/home/DolphinDB/Data/t.csv",delimiter=',',append=true)
saveText在保存数组向量到 csv 文件时,把原数据中的
[ ]
替换为了
"
"
,文件内容如下:
sid,date,bid,ask
APPL,2022.01.02,"1.4799,1.479,1.4787","1.4821,1.4825,1.4828"
IBM,2022.01.03,"1.4796,1.479,1.4784","1.4818,1.482,1.4821"
APPL,2022.01.04,"1.4791,1.479,1.4784","1.4814,1.4818,1.482"
然后调用 loadText 导入该文件:
path = "/home/DolphinDB/Data/t.csv"
schema=extractTextSchema(path);
update schema set type = "DOUBLE[]" where name="bid" or name ="ask"
t = loadText(path, schema=schema, arrayDelimiter=",")
t;
sid
date
bid
ask
AMZN
2022.01.02
[1.4799,1.479,1.4787]
[1.4821,1.4825,1.4828]
AMZN
2022.01.03
[1.4796,1.479,1.4784]
[1.4818,1.482,1.4821]
IBM
2022.01.04
[1.4791,1.479,1.4784]
[1.4814,1.4818,1.482]
通过 saveText 导出 csv 文件时,数组向量的边界标识默认为双引号(”),本例中 t.csv 的内容如下
当数组向量的边界标识不为双引号时,可以通过设置参数 arrayMarker 导入,例如当 t.csv 的内容如下时
sid,date,bid,ask
APPL,2022.01.02,[1.4799,1.479,1.4787],[1.4821,1.4825,1.4828]
IBM,2022.01.03,[1.4796,1.479,1.4784],[1.4818,1.482,1.4821]
APPL,2022.01.04,[1.4791,1.479,1.4784],[1.4814,1.4818,1.482]
通过以下脚本导入
path = "/home/DolphinDB/Data/t.csv"
schema=extractTextSchema(path);
update schema set type = "DOUBLE[]" where name="bid" or name ="ask"
t = loadText(path, schema=schema, arrayDelimiter=",",arrayMarker="[]")
t;
例 7. 批量导入小文件
在现实场景中,数据供应商会将一只股票数据保存到一个文件中,这种场景的特点是文件数量比较多,但单个文件比较小。如果将文件一个个导入,则效率会比较低。为提高导入效率,可以考虑将多个小文件批量合并后再导入。
数据文件:
smallDataset.zip
db = database("dfs://k_day_level")
colName = `securityid`tradetime`open`close`high`low`vol`val`vwap
colType = [SYMBOL,TIMESTAMP,DOUBLE,DOUBLE,DOUBLE,DOUBLE,INT,DOUBLE,DOUBLE]
tbSchema = table(1:0, colName, colType)
if(existsDatabase("dfs://k_day_level")){
dropDatabase("dfs://k_day_level")
}
database(directory = 'dfs://k_day_level', partitionType = RANGE, partitionScheme =[2000.01M,2001.01M,2002.01M,2003.01M,2004.01M,2005.01M,2006.01M,2007.01M,2008.01M,2009.01M,2010.01M,2011.01M,2012.01M,2013.01M,2014.01M,2015.01M,2016.01M,2017.01M,2018.01M,2019.01M,2020.01M,2021.01M,2022.01M,2023.01M,2024.01M]$7, engine= `OLAP, atomic = `TRANS)
db.createPartitionedTable(table=tbSchema,tableName=`k_day,partitionColumns=`tradetime)
//2. 导入数据文件
batchNum=1000
dir = "/home/data/smallDataset/"
allFiles = files(dir).filename
i = 0
s = allFiles.size()
do{
files =allFiles[i:min(i+batchNum, s)]
data = each(loadText, dir + files).unionAll(false)
loadTable("dfs://k_day_level","k_day").append!(data)
i = i + batchNum
}while(i < s)
select top 10* from loadTable("dfs://k_day_level","k_day")
securityid
tradetime
open
close
high
low
vol
val
vwap
sz000001
2010.01.01T00:00:00.000
35.9484
35.4385
36.3261
35.9569
10,732
380,325.7701
35.4385
sz000002
2010.01.01T00:00:00.000
5.4374
7.2864
5.4665
3.8142
45,577
332,092.5668
7.2864
sz000003
2010.01.01T00:00:00.000
8.4177
10.5074
8.7004
7.577
96,865
1,017,794.5994
10.5074
sz000004
2010.01.01T00:00:00.000
78.7732
76.4809
79.1491
78.4188
67,520
5,163,993.091
76.4809
sz000005
2010.01.01T00:00:00.000
23.5196
25.8487
23.9986
23.9379
1,156
29,881.1144
25.8487
sz000006
2010.01.01T00:00:00.000
75.3909
73.9721
75.5661
74.8373
70,337
5,202,974.0605
73.9721
sz000007
2010.01.01T00:00:00.000
21.9932
22.7951
22.5291
21.218
76,912
1,753,219.9525
22.7951
sz000008
2010.01.01T00:00:00.000
21.0682
21.5055
21.6914
20.733
9,320
200,431.077
21.5055
sz000009
2010.01.01T00:00:00.000
77.2482
75.6649
78.2001
76.9927
13,538
1,024,351.3968
75.6649
sz000010
2010.01.01T00:00:00.000
54.2793
55.6466
54.3281
53.6054
31,924
1,776,461.4488
55.6466
FILE:references/doc_6525.md
# mkurtosis
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mkurtosis.html
**来源**: DolphinDB 官方文档
---
mkurtosis
语法
mkurtosis(X, window, [biased=true], [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
的峰度。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
biased
是一个布尔值,表示是否是有偏估计。默认值为 true,表示有偏估计。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算峰度。
输入为表时,返回一个与输入表结构相同的表,每列分别计算峰度。
输入为元组时,返回对应的元组结构。
例子
m=matrix(1 9 3 100 3 2 1 -100 9 10000, 1 2 3 4 5 6 7 8 9 100);
m.mkurtosis(8);
#0
#1
3.989653641279048
1.761904761904762
3.989840910744778
1.761904761904762
6.140237905908072
6.101712240467206
m.rename!(date(2020.04.06)+1..10, `col1`col2)
m.setIndexedMatrix!()
mkurtosis(m, 8d)
label
col1
col2
2020.04.07
2020.04.08
2020.04.09
1.5
1.5
2020.04.10
2.3195
1.64
2020.04.11
3.2251
1.7
2020.04.12
4.163
1.7314
2020.04.13
5.1141
1.75
2020.04.14
3.9897
1.7619
2020.04.15
3.9898
1.7619
2020.04.16
6.1402
6.1017
mkurtosis(m, 1w)
label
col1
col2
2020.04.07
2020.04.08
2020.04.09
1.5
1.5
2020.04.10
2.3195
1.64
2020.04.11
3.2251
1.7
2020.04.12
4.163
1.7314
2020.04.13
5.1141
1.75
2020.04.14
3.4937
1.75
2020.04.15
3.4937
1.75
2020.04.16
5.1645
5.145
DolphinDB 的
kurtosis
默认情况(当
biased
=true
时)存在偏差,而 pandas 的 kurt 默认为无偏估计,且减去正态分布的峰值3。下面例子示意了使用滑动窗口时,两者的等价转换关系:
python
m = [[1111,2], [323,9], [43,12], [51,32], [6,400]]
df = pandas.DataFrame(m)
y = df.rolling(4).kurt()
dolphindb
m=matrix(1111 323 43 51 6, 2 9 12 32 400)
m.mkurtosis(4, false)-3
#0
#1
2.504252
2.366838
3.675552
3.941262
相关函数:
kurtosis
FILE:references/doc_653.md
# convertibleFixedRateBondDirtyPrice
**URL**: https://docs.dolphindb.cn/zh/funcs/c/convertiblefixedratebonddirtyprice.html
**来源**: DolphinDB 官方文档
---
convertibleFixedRateBondDirtyPrice
语法
convertibleFixedRateBondDirtyPrice(settlement, issue,
maturity, redemption, coupon, spread, riskFree, volatility, spot,
conversionPrice, divYield, divDates, callDates, callPrices, putDates, putPrices,
style, calendar, frequency, [basis=1], [convention='Following'],
[method='binomial'], [kwargs])
详情
计算固息可转债每 100 面值的含息价格。
可转换债券(Convertible
Bond),简称可转债,是一种混合债券及期权的产品,可按一定规则转换为债券发行公司的股票;其转换价格会在发行前确定。可转债中往往会嵌入债券赎回或者回售的权利。
参数
注意
:如果输入参数中,部分为标量,其余为向量时,则会将标量当作与向量长度相同,所有元素值等于该标量的向量。所有向量的长度必须一致。若输入参数为数组向量,则其行数必须与其他向量参数的长度相同。
settlement
DATE 类型标量或向量,表示债券的结算日。
issue
DATE 类型标量或向量,表示债券的发行日。
maturity
DATE 类型标量或向量,表示债券的到期日。
redemption
数值型标量或向量,表示债券的赎回价格。
coupon
数值型标量或向量,表示债券的年息票利率。
spread
数值型标量或向量,表示息差。
riskFree
数值标量或向量,表示无风险利率。
volatility
数值标量或向量,表示波动率。
spot
数值标量或向量,表示债券发行公司的股票现价。
conversionPrice
数值型标量或向量,表示转股价格,即债券转换为普通股时每股所需支付的价格。该参数决定了每张可转债能换取的股票数量。
divYield
数值标量或向量,表示分红利率。
divDates
DATE 类型向量或数组向量,表示分红日期。
callDates
DATE 类型向量或数组向量,表示嵌入赎回权利时,约定的提前赎回债券的日期。
callPrices
数值型向量或数组向量,表示嵌入赎回权利时,约定的提前赎回债券的价格。必须与callDates一一对应。
putDates
DATE 类型向量或数组向量,表示嵌入回售权利时,约定的提前回售债券的日期。
putPrices
数值型向量或数组向量,表示嵌入回售权利时,约定的提前回售债券的价格。必须与putDates一一对应。
style
字符串类型标量或向量,表示可行权时间的类型,有两个可选值:
‘european’:表示欧式期权。
‘american’:表示美式期权。
calendar
字符串类型标量或向量,表示使用的市场日历类型,请参阅
交易日历
。
frequency
支持以下两种输入类型:
整型标量或向量:表示每年的付息次数,如 1 表示每年付息 1 次;
DURATION 标量或向量:表示间隔多长时间进行一次付息,如 3M,表示每 3 个月付息一次。
可选值
含义
1 / 1y
表示每年付息1次
2 / 6M
表示每年付息2次 / 每6个月付息1次
3 / 4M
表示每年付息3次 / 每4个月付息1次
4 / 3M
表示每年付息4次 / 每3个月付息1次
6 / 2M
表示每年付息6次 / 每2个月付息1次
12 / 1M
表示每年付息12次 / 每月付息1次
13 / 4w
表示每年付息13次 / 每4周付息1次
26 / 2w
表示每年付息26次 / 每2周付息1次
52 / 1w
表示每年付息52次 / 每周付息1次
365 / 1d
表示每年付息365次 / 每天付息1次
basis
可选参数,整型或字符串类型的标量或向量,表示要使用的日计数基准类型。可选值为:
Basis
日计数基准
0 / "Thirty360US"
US (NASD) 30/360
1 / "ActualActual" (默认值)
实际/实际
2 / "Actual360"
实际/360
3 / "Actual365"
实际/365
4 / "Thirty360EU"
欧洲 30/360
convention
可选参数,字符串标量或向量,用于指定如何调整落在非工作日的现金流支付日期。可选值为:
'Following'(默认值):选择给定假日后的第一个工作日;
'ModifiedFollowing':选择给定假日后的第一个工作日。如果该工作日属于不同的月份,则选择假日前的第一个工作日;
'Preceding':选择给定假日前的第一个工作日;
'ModifiedPreceding':选择给定假日前的第一个工作日。如果该工作日属于不同的月份,则选择假日后的第一个工作日;
'Unadjusted':不作调整;
'HalfMonthModifiedFollowing':选择给定假日后的第一个工作日。如果该工作日跨越了月中(15日)或月末,则选择假日前的第一个工作日;
'Nearest':选择离给定假日最近的工作日。如果前后工作日距离相同,则默认选择后一个工作日。
method
可选参数,字符串标量,表示使用的估值方法,目前只支持“binomial”, 即使用二叉树模型(Binomial tree
model)进行估值。
kwargs
可选参数,字典标量,表示估值方法对应的其他参数。
method
= 'binomial' 时,
kwargs
应包含成员:
‘type’:STRING 类型标量或向量,指定二叉树模型的类型,可选值为:
'crr'(默认值): Cox-Ross-Rubinstein 模型
'jr':Jarrow-Rudd 模型。
‘timeSteps’:INT 类型标量或向量,表示二叉树模型的时间间隔数,默认值为 100。
返回值
DOUBLE 类型的标量或向量。
例子
现有五年期可转换债券A:发行日为 2023 年 8 月 28 日,到期日为 2028 年 8 月 28 日,交易日为 2024 年 8 月 28 日。其赎回价格为
100,年息票利率为 0.05,付息频率为每年一次,息差 0.005。合约转股价格为 26,股票现价为 36,分红利率为 0.02,从 2024 年 10 月 28
日起每隔 6 个月分红一次,共分红 6 次。
债券可在 2025 年 8月 28 日和 2027 年 8 月 3 0日分别按 101.5 和 100.85 价格赎回,或者在 2026 年 8 月 28 日按 105
价格回售。市场无风险利率为 0.06,波动率为 0.2。日计数基准为 Actual365,把非工作日调整到工作日的方法为
ModifiedFollowing。交易日历为上海证交所(XSHG)。
分别计算欧式和美式两种可行权时间类型下,该债券的含息价格。
spot = 36.0
conversionPrice = 26.0
redemption = 100
spread = 0.005
divYield = 0.02
riskFree = 0.06
volatility = 0.20
issue = 2023.08.28
settlement = 2024.08.28
maturity = 2028.08.28
convention = `ModifiedFollowing
calendar = `XSHG
style = [`european, `american]
frequency = 1
coupon = 0.05
basis = 3
divFreq = 6M
nextDivDate = 2024.10.28
divDates = []
for (i in 0..5) {
divDates.append!(nextDivDate)
nextDivDate = temporalAdd(nextDivDate, divFreq)
}
divDates = divDates$DATE
callDates = [2025.08.28, 2027.08.30]
callPrices = [101.5, 100.85]
putDates = [2026.08.28]
putPrices = [105.0]
convertibleFixedRateBondDirtyPrice(settlement, issue, maturity, redemption, coupon, spread, riskFree, volatility, spot, conversionPrice, divYield, divDates, callDates, callPrices, putDates, putPrices, style, calendar, frequency, basis, convention)
// [100.14675326378128,138.45755887077215]
FILE:references/doc_6532.md
# genericStateIterate
**URL**: https://docs.dolphindb.cn/zh/funcs/g/genericStateIterate.html
**来源**: DolphinDB 官方文档
---
genericStateIterate
语法
genericStateIterate(X, initial, window, func)
详情
该函数是响应式状态引擎中的函数,基于以元素个数衡量的窗口进行迭代计算。
假设
X
指定为 [X1, X2, ..., Xn],该函数计算结果对应输出表中的列为 factor,初始化字段为
initial,
window
为 w,迭代函数为 func。
对于输入的第 k 条记录(k = 1, 2 …),其计算逻辑为:
当 w = 0 时:
k = 1 时:factor[0] = func(initial[0],, X1[0],
X2[0], … , Xn[0])
k > 1 时:factor[k-1] = func(factor[(k-2)],
X1[k-1], X2[k-1], … , Xn[k-1])
当 w >0 时:
k <= w 时:factor[k-1] = initial[k-1]
k > w 时:factor[k-1] = func(factor[(k-1-w):k-1], X1[k-1], X2[k-1],
… , Xn[k-1])
注意:数据对用于索引时,不包含右边界的值,即 (k-1-w):k-1 的范围是 [k-1-w, k-1)。
参数
X
表中的字段或对表字段其应用向量函数的计算结果。通过元组方式传入多个列字段。传入 [] 表示不指定该参数。
initial
表中的字段或对表字段应用向量函数的计算结果。其作用是对输出表的第1~
window
个计算结果进行填充。
window
非负整数
,表示窗口的长度(以元素个数衡量)。
func
用户自定义的无状态函数,其返回值必须是标量,以部分应用的方式接收参数。
当
window
> 0 时,
其第一个参数为当前记录向前取
window
个计算结果组成的向量
;当
window
= 0 时,其第一个参数为当前记录向前取1个计算结果
。其后参数依次为
X
指定的列。
例子
// define a function
def myfunc(x, w){
re = sum(x*w)
return re
}
dateTime = 2021.09.09T09:30:00.000 2021.09.09T09:31:00.000 2021.09.09T09:32:00.000 2021.09.09T09:33:00.000 2021.09.09T09:34:00.000
securityID = `600021`600021`600021`600021`600021
volume = 310 280 300 290 240
price = 1.5 1.6 1.7 1.6 1.5
t = table(1:0, `dateTime`securityID`volume`price, [TIMESTAMP, SYMBOL, INT, DOUBLE])
tableInsert(t, dateTime, securityID, volume, price)
output = table(100:0, `securityID`dateTime`factor1, [SYMBOL, TIMESTAMP, DOUBLE])
engine = createReactiveStateEngine(name="test", metrics=[<dateTime>, <genericStateIterate(volume,price,3,myfunc{,})>], dummyTable=t, outputTable=output, keyColumn=`SecurityID, keepOrder=true)
engine.append!(t)
dropAggregator(`test)
securityID
dateTime
factor1
600021
2021.09.09T09:30:00.000
1.5
600021
2021.09.09T09:31:00.000
1.6
600021
2021.09.09T09:32:00.000
1.7
600021
2021.09.09T09:33:00.000
1,392
600021
2021.09.09T09:34:00.000
334,872
上例计算过程如下:
由于窗口为 3,因此对于前 3 条数据,以 price 的值作为 factor1 的输出;
第 4 条数据到来时,历史窗口的数据为 [1.5, 1.6, 1.7],当前 volume 的值为 290,因此调用自定义函数 myfunc([1.5,
1.6, 1.7], 290) = 1392;
第 5 条数据到来时,历史窗口的数据为 [1.6, 1.7, 1392],当前 volume 的值为 240,因此调用自定义函数 myfunc([1.6,
1.7, 1392], 240) = 334872;
若之后继续有数据注入,其计算过程以此类推。
相关函数:
genericTStateIterate
FILE:references/doc_6538.md
# mstdTopN
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mstdTopN.html
**来源**: DolphinDB 官方文档
---
mstdTopN
语法
mstdTopN(X, S, window, top, [ascending=true],
[tiesMethod='oldest'])
参数说明和窗口计算规则请参考:
mTopN
详情
在给定长度(以元素个数衡量)的滑动窗口内,根据
ascending
指定的排序方式将
X
按照
S
进行稳定排序后,取前
top
个元素计算样本标准差。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
X = 1..7
S = 0.3 0.5 0.1 0.1 0.5 0.2 0.4
mstdTopN(X, S, 4, 2)
// output:
[,0.707106781186548,1.414213562373095,0.707106781186548,0.707106781186548,0.707106781186548,1.414213562373095]
X = NULL 1 2 3 4 NULL 5
S = 3 5 1 1 5 2 4
mstdTopN(X, S, 4, 2)
// output: [,,,0.707106781186548,0.707106781186548,0.707106781186548,]
X = matrix(1..5, 6..10)
S = 2022.01.01 2022.02.03 2022.01.23 2022.04.06 2021.12.29
mstdTopN(X, S, 3, 2)
#0
#1
0.707106781186548
0.707106781186548
1.414213562373095
1.414213562373095
0.707106781186548
0.707106781186548
1.414213562373095
1.414213562373095
X = matrix(1..5, 6..10)
S = matrix(2022.01.01 2022.02.03 2022.01.23 NULL 2021.12.29,NULL 2022.02.03 2022.01.23 2022.04.06 NULL)
mstdTopN(X, S, 3, 2)
#0
#1
0.7071
1.4142
0.7071
0.7071
0.7071
1.4142
0.7071
相关函数:
mstd
FILE:references/doc_6554.md
# getOLAPCachedSymbolBaseMemSize
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getOLAPCachedSymbolBaseMemSize.html
**来源**: DolphinDB 官方文档
---
getOLAPCachedSymbolBaseMemSize
语法
getOLAPCachedSymbolBaseMemSize()
详情
获取 OLAP 引擎中 SYMBOL 类型的字典编码的缓存大小,单位是字节。
参数
无
返回值
LONG 类型标量。
FILE:references/doc_6564.md
# [HINT_EXPLAIN]
**URL**: https://docs.dolphindb.cn/zh/progr/sql/hint_explain.html
**来源**: DolphinDB 官方文档
---
[HINT_EXPLAIN]
通过在 select / exec 关键字后添加
[HINT_EXPLAIN]
来显示 SQL 语句的执行过程,便于 SQL 查询中实时监测查询的速度和执行的顺序。形式如下:
select [HINT_EXPLAIN] * from tb where id > 20
注:
添加
[HINT_EXPLAIN]
后的查询语句仅返回一个 JSON 字符串显示了 SQL
的执行过程,不返回查询结果;对于 UPDATE 或者 DELETE 语句,目前还不支持查看执行计划。
[HINT_EXPLAIN]
支持分区表查询和非分区表查询,对于分区表查询,执行计划会体现
map-reduce
的过程。下面以一个分布式查询为例,来说明 JSON 字符串内各标签的组成和含义。
返回的 JSON 字符串的最外层包含
measurement
和
explain
两个标签。
measurement
"measurement":"microsecond"
表示 SQL 查询执行计划的开销时间的单位为微秒。内部所有
cost
标签表示的耗时,均以微秒为单位。
explain
explain
内包含的标签从上往下的顺序代表该
explain
对应的 SQL 语句的执行顺序。若 SQL
查询包含嵌套子句,
explain
可能会嵌套在其它子标签中。
explain
的构成如下:
rows
:查询返回的记录数。
cost
:查询耗时。
{
"measurement":"microsecond",
"explain": {
/* 可能包含的其他子标签模块 */
"rows": 20000,
"cost": 100
}
}
分布式查询包含三个阶段 map → merge → reduce,通常这三个标签均包含在根标签 explain 中, 例如:
{
"measurement":"microsecond",
"explain":{
"from":{...},
"map":{...},
"merge":{...},
"reduce":{...},
"rows":10,
"cost":23530
}
}
通常,系统会对某些查询条件进行优化。单机模式创建一个以
date
列为分区的分区表,查询该表的
date
列在单个分区的全部数据。
select [HINT_EXPLAIN] * from t1 where date = 2022.01.01
此时,该查询语句会被优化,返回如下的结果:
{
"measurement":"microsecond",
"explain":{
"from":{ ... },
"optimize":{ ... },
"rows":185,
"cost":987
}
}
from
from
标签说明了 SQL 语句中
from
子句解析后的执行过程。
根据
from
子句的不同,
from
标签模块下可能包含着不同的子模块。以下列举了几种可能的场景:
from
后接一个表对象,例如
select xref [HINT_EXPLAIN] * from pt
。
"from": {
"cost": 3 // from 子句的耗时
}
from
子句嵌套 SQL 语句,例如
select [HINT_EXPLAIN]
* from (select max(x) as maxx from loadTable(“dfs://valuedb”,’pt’) group by month)
where maxx <
0.9994
。
"from": {
"cost": 33571, // from 子句的耗时
"detail": {
"sql": "select [98304] max(x) as maxx from loadTable("dfs://valuedb", "pt") group by month", // 嵌套的SQL语句
"explain": { ... } // 嵌套的SQL语句的explain
}
}
可以看到由于包含嵌套的子句,
explain
标签嵌套在了
from
标签中。
from 跟表连接相关的子句,例如
select [HINT_EXPLAIN] * from lsj(pt1,
pt2, “date”)
。若使用 2.00.12 之前的版本,此处的
from
子句为
lsj(pt1,
pt2, "date")
,
cost
耗时只是获取待连接的表 pt1, pt2 数据源的耗时,两表未发生
join。
"from": {
"cost": 3, // from 子句的耗时
"detail": "materialize for JOIN" // 表示子句中包含 join 操作
}
若使用 2.00.12/3.00.0 及之后的版本,“from“ 字段更改为 “materialization“ 字段,且 “detail“
字段被替换为左表和右表数据源的 script。
"materialization":{
"cost": 37, // 准备左右表数据源的总耗时
"left": "pt1", // join 函数第一个参数的 script
"right": "select * from pt2" // join 函数第二个参数的 script
}
vectorindex
向量索引的处理过程信息将记录在此标签模块。仅当 from 后为一指定了向量索引的分布式表时,才会出现此标签。
useIndex:本次查询是否满足使用向量索引的条件,true 代表满足。当为 false 时,不会包含其他子标签。
cost:在向量索引的处理过程中花费的时间。
inputRows:通过 where 条件输入给向量索引的行数。
outputRows:经过向量索引处理完后输出的行数。
"vectorindex": {
"useIndex": true,
"cost": 457470,
"inputRows": 200000,
"outputRows": 3000
},
where
TSDBIndexPrefiltering
:在 TSDB 引擎中,通过 where 条件从 Level File
文件索引筛选所需数据信息。
blocksToBeScanned:待扫描的 TSDB 引擎 Level File 文件的 Blocks 数量。
matchedWhereConditions:where 子句中针对 sort key
的匹配条件数量,包括等值、非等值(不含链式比较)、in、between、like 等条件。
rows:满足 where 过滤条件的行数。
cost:where 子句的查询耗时。
"where": {
"TSDBIndexPrefiltering": {
"blocksToBeScanned": 0,
"matchedWhereConditions": 1
},
"rows": 0,
"cost": 416
}
map
map
阶段会统计 SQL 查询涉及到的所有分区(包括本地节点 local 和远程节点 remote
的分区),然后生成相应的子查询,并把子查询分发到涉及到的所有分区,进行并行查询。
下面是一个
map
标签模块中可能包含的子模块:
generate_reshuffle_query
:是分布式 join 独有的标签,包含进行
generate_reshuffle_query 过程的信息。generate_reshuffle_query 是进行分布式 join 前将数据按照 join
列连续存储在内存区的一个操作。如果 join 列是分区列,则不会进行该操作。(仅 2.00 及以上版本支持分布式 join)
partitions
: 本次查询的分区信息,其子标签 local 和 remote
分别表示查询的分区位于本地节点的数量和查询的分区位于远程节点的数量。
cost
:map 阶段完成所有过程所消耗的总时间(此时所有子查询都执行完成)。
partitionRoute
:集群中各个节点执行的子查询数量。
detail
:map 阶段查询子句的执行细节。
most:耗时最多的子查询的信息。
least:耗时最少的子查询的信息。
"map": {
"generate_reshuffle_query": {
"cost": 2
},
"partitions": {
"local": 0,
"remote": 50
},
"cost": 9723,
"partitionRoute": {
"node3": 15,
"node1": 19,
"node2": 16
},
"detail": {
"most": {
"sql": "select [254215] cumsum(price) as cumsum_price from pt where sym == \"a\" map [partition = /test_explain_olap/53/b]",
"explain": {
"from": {
"cost": 39
},
"where": {
"rows": 100,
"cost": 246
},
"rows": 100,
"cost": 1222
}
},
"least": {
"sql": "select [254223] cumsum(price) as cumsum_price from pt where sym == \"a\" map [partition = /test_explain_olap/92/b]",
"explain": {
"where": {
"rows": 0,
"cost": 154
},
"rows": 0,
"cost": 245
}
}
}
}
optimize
查询优化会显示在
optimize
标签模块中。
optimize
:查询优化的细节。组成如下所示:
field
:可以是被优化的字段,如:"where", "join", "group";也可以是优化的场景说明,如 "single partition
query"。
"optimize": {
"cost": 3,
"field": ["where", "join", "group"],
"sql": "..." // 优化之后的SQL语句
}
以下列举了几种可能优化的场景:
只查询单个分区数据,其
map
阶段的执行过程如下:
"map": {
"partitions": {
"local": 1, // 或者0
"remote": 0, // 或者1
},
"cost": 100,
"optimize": {
"field": "single partition query",
"sql": "...",
"explain": { ... }
}
}
单分区情况下,查询任务只涉及到对应分区的单个节点,因此不需要进行
merge
。
context by + csort + limit。对于 context by 和 csort 以及 limit 配合使用的 SQL
查询,系统内部进行了查询优化:
select * from pt where device in ["a", "b"] context by device csort time limit n
其中
pt 可以是单分区表或者组合分区的分区表。优化需满足以下几个条件:
context by 指定的列在 where 子句中进行了条件过滤。 比如上例中的 device, where 子句中筛选了
device in ["a", "b"]
的数据。
csort 指定的列(如例中的 time)是分区列, 且分区方式是 VALUE 或 RANGE。
csort, context by 只能指定单列。
context by 指定的列也需要一起输出(通过 select 语句指定该列)。
此时返回的结果中,
map
标签模块的组成如下所示:
"map":{
"optimize":{
"cost":4, // 完成优化耗费的时间
"field":"optimize for CONTEXT BY + CSORT + LIMIT: partial parallel execution."
},
"cost":1082 // 完成 map 阶段耗费的时间
}
如果进行了查询优化,返回结果可能不包含
merge
和
reduce
阶段。
merge
merge
阶段会将
map
阶段分配到各个节点的子查询的结果进行合并。
下面是一个
merge
标签模块中可能包含的子模块:
row
:
merge
后的结果的总行数。
cost
:
merge
阶段消耗的时间。
detail
:
merge
阶段查询子句的执行细节。
most:返回行数最多的子查询的信息。
least:返回行数最少的子查询的信息。
"merge": {
"row": 10000,
"cost": 50,
"detail": {
"most": { // 返回行数最多的SubQuery
"sql": "select time,id,value from pt [partition = /iot/6]",
"explain": { ...}
},
"least": {
"sql": "select time,id,value from pt [partition = /iot/9]",
"explain": { ...}
}
}
}
reduce
reduce 阶段通常是对子查询返回的结果做收尾处理,通常是对 merge 的结果表做最后一次查询。执行计划是否包含 reduce 阶段视具体情况而定。
下面介绍一个
reduce
标签模块中可能包含的子模块:
"reduce": {
"sql": "...", // Final Query
"explain": { ... }
}
除了上述在分布式查询各个阶段说明的标签模块以外,实际运行的结果中还可能包含一部分其他 SQL 相关的子标签模块。显示如下:
join, csort, sort以及pivotBy标签模块,只包含 cost 指标:
"join": {
"cost": 10
}
groupBy
sortKey
:是否利用了表的
sortColumn
来进行 groupBy。如果该值为true, 则没有
algo
标签。
algo
:分组算法, 可以为: "hash", "vectorize", "sort"。当分组算法为
“sort” 时,将显示以下两个字段:
inplaceOptimization
是否进行了 inplace
Optimization,即预先分配所需的内存来存储所有分组的查询结果,而不是每计算一组结果就进行小规模的内存分配,避免了频繁的小内存分配带来的开销,且节省了中间内存的使用。
optimizedColumns
若
inplaceOptimization
为 true,则该字段将显示进行了 inplace Optimization
的列名。
fill
:
interval
插值填充过程的标签。
"groupBy":{
"sortKey":false,
"algo":"hash",
"cost":8
}
// group by 搭配 interval 使用
"groupBy": {
"sortKey": false,
"algo": "hash",
"fill": {
"cost": 23
},
"cost": 248
}
// 进行 inplace Optimization
"groupBy": {
"sortKey": false,
"algo": "sort",
"inplaceOptimization": true,
"optimizedColumns": [
"std_price0"
],
"cost": 16422
},
contextBy
sortKey
:是否利用了表的
sortColumn
来做 contextBy。
"contextBy":{
"sortKey":false,
"cost":1994
}
表连接
自 2.00.12/3.00.0 版本起,
HINT_EXPLAIN
支持显示如下表连接操作:
cross join
inner join
left join
left semi join
right join
full join
注:
如果表连接操作中存在分区内存表,则不遵循本节说明。
标准 SQL 写法的表连接查询
SQL 示例如下:
select [HINT_EXPLAIN] * from pt1 left join t2 on pt1.p1=t2.p2 where p1+p2>4 and p2 < 6
使用标准 SQL 写法的表连接查询的显示输出由如下模块依情况进行组合,且一个模块的输出中也可能包含其他模块的输出:
SQL 引擎
多表 Join 框架
Pipelined Join 执行过程
串行 Join 执行过程
取数据过程
SQL 引擎
与其他模块的数据构成相同。
{
"measurement": "microsecond",
"explain": {
// <UniversalTableJoinImp explain 结果>
"rows": 10, //查询返回的记录数
"cost": 237 //查询耗时
},
}
多表 Join 框架
numPipelinedStages
:能用 pipeline 的 join 数量。
numSerialStages
:不能用 pipeline 的 join 数量。
pipelinedStages
:包含 Pipelined Join 执行过程的 explain 结果。下节将详细介绍。
serialStages
:包含串行 Join 执行过程的 explain 结果。后文将详细介绍。
"numPipelinedStages": 2,
"numSerialStages": 3,
"pipelinedStages": {
// <Pipelined Join 执行过程的 explain 结果>
},
"serialStages": {
// <串行 Join 执行过程的 explain 结果>
}
Pipelined Join 执行过程如下:
rows
:pipeline 阶段产生结果的行数。
cost
:pipeline 阶段总耗时。
numTasks
:pipeline 任务数。
most
:耗时最长的任务。
cost
:此 pipeline 运行耗时。
segments
:此 pipeline 每张表的分区 path,如果是内存表则为"",如果是分区表但被剪枝则为"<Empty
Segment>"。
explain
:
left
:取数据过程的 explain 结果,如果是分区表但被剪枝则为 "sql":"<Empty
Segment>"。
right
:取数据过程的 explain 结果。
join
:
script
:join 操作的脚本。
predicates
:下推到此次 join 的谓词。
rows
:此次 join 的结果行数。
cost
:join 运行耗时。
least
:耗时最短的任务,格式与
most
相同。
resultPartitionInfo
:join 结果的分区信息。
isPartitioned
:join 结果是否分区,如果为 true 则有下面的字段。
estimatedRows
:估计的总行数。
domainType
:结果复用的 database 的分区方式,如果没有复用,值为 NULL。
domainScheme
:如果 "domainType" 不为 NULL,其分区 scheme。
partitionColumns
:结果分区列。
useSeqPartition
:结果是否用 SEQ 方式分区。
totalExecutionCost
:执行 pipeline 任务的总耗时(不包含生成分区表的耗时)。
totalAppendCost
:结果生成分区表的总耗时。
final
:最终查询结果。如果 pipeline 覆盖所有 join,会有一次最终查询,下面是对应的 explain 结果、
sql
:最终查询 SQL。
rows
:最终查询的结果行数 。
cost
:最终查询耗时。
explain
:最终查询的 explain 结果。
"pipelinedStages": {
"rows": 10,
"cost": 35,
"numTasks": 10,
"most": {
"cost": 20,
"segments": [
"20210101/Key1",
""
],
"explain": {
"stage1": {
"left": {
// <取数据过程的 explain 结果>
},
"right": {
// <取数据过程的 explain 结果>
},
"join": {
"script": "ej(t1, t2, `id, `id)",
"predicates": [
"t1.id > 3",
"t2.id < 5"
],
"rows": 10,
"cost": 152
}
},
"stage2": {
"right": {
// <取数据过程的 explain 结果>
},
"join": {
// 与上面 "join" 格式相同
}
},
...
}
},
"least": {
// 与 "most" 格式相同
},
"resultPartitionInfo": {
"isPartitioned": true,
"estimatedRows": 50000,
"domainType": "NULL/VALUE/HASH/...",
"domainScheme": [1, 2, 3],
"partitionColumns": ["col1", "col2"],
"useSeqPartition": false
"totalExecutionCost": 20,
"totalAppendCost": 30,
"final": {
"sql": "...",
"rows": 10,
"cost": 237,
"explain": {
// <最终查询的 explain 结果>
}
}
},
串行 Join 执行过程
rows
:串行阶段产生结果的行数。
cost
:串行阶段总耗时。
stage
:编号从 pipeline 后一个编号开始。如果完全没有 pipeline 阶段,第一次 join 会有
"left",即取左表数据的 explain 结果。
left
:取数据过程的 explain 结果。
right
:取数据过程的 explain 结果。
resultPartitionInfo
:join 结果的分区信息。
partitionParamsSet
:此次 join
结果是否尝试分区。对除了最后一次以外的join,"partitionParamsSet" 为 true,且有其他字段。
forcePartition
:是否强制生成分区结果。
domainType
:结果复用的 database 的分区方式,如果没有复用,值为 NULL。
domainScheme
:如果 "domainType" 不为 NULL,其分区 scheme。
partitionColumns
:结果分区列。
useSeqPartition
:结果是否用 SEQ 方式分区。
numForcedPartitions
:在 "domainType" 为 NULL 且 "useSeqPartition" 为
false 时默认 HASH 分区的强制分区数量,-1 为未设置。
"serialStages": {
"rows": 10,
"cost": 30,
"stage3": {
"left": {
// <取数据过程的 explain 结果>
},
"right": {
// <取数据过程的 explain 结果>
},
"join": {
"sql": "...",
"rows": 10,
"cost": 237,
"resultPartitionInfo": {
"partitionParamsSet": true,
"forcePartition": true,
"domainType": "NULL/VALUE/HASH/...",
"domainScheme": [1, 2, 3],
"partitionColumns": ["col1", "col2"],
"useSeqPartition": false
"numForcedPartitions": -1,
},
"explain": {
// <本次 join 查询的 explain 结果>
}
}
},
"stage4": {
"right": {
// <取数据过程的 explain 结果>
},
"join": {
// 与上面的 "join" 格式相同
}
},
...
},
取数据过程
sql
:取数据的 SQL。
rows
:取到的数据条数。
cost
:取数据 SQL 运行耗时。
resultPartitionInfo
:join 结果的分区信息。
partitionParamsSet
:取数据结果是否尝试分区;若为 true,且有其他字段。
forcePartition
:是否强制生成分区结果。
domainType
:结果复用的 database 的分区方式,如果没有复用,值为 NULL。
domainScheme
:如果 "domainType" 不为 NULL,其分区 scheme。
partitionColumns
:结果分区列
useSeqPartition
:结果是否用 SEQ 方式分区。
numForcedPartitions
:在 "domainType" 为 NULL 且 "useSeqPartition" 为
false 时默认 HASH 分区的强制分区数量,-1 为未设置。
"sql": "...",
"rows": 10,
"cost": 237,
"resultPartitionInfo": {
"partitionParamsSet": true,
"forcePartition": true,
"domainType": "NULL/VALUE/HASH/...",
"domainScheme": [1, 2, 3],
"partitionColumns": ["col1", "col2"],
"useSeqPartition": false
"numForcedPartitions": -1,
},
"explain": {
// <取当前表数据的查询的 explain 结果>
}
使用函数写法的 Join 查询
由于分区全部覆盖,使用函数写法的 Join 查询的 explain 的结果维持原先格式。SQL 语句示例:
select [HINT_EXPLAIN] * from ej(pt1,pt2,`p1,`p2)
使用 cj 的特殊情况说明:
在满足以下所有条件时,连续
cj
的输出结果遵循前文所述的标准 SQL 输出结构:
查询的 from 是不涉及分区内存表的连续多表
cj
,不涉及其他 join 类型。
嵌套的任何一次
cj
只能出现在外层
cj
的左表。
这是一个符合条件的例子:
cj(cj(cj(t1, t2), t3), t4)
这是一个不符合条件的例子:
cj(t1, cj(t2, t3))
cj 以及 表 的外面可以嵌套任意个子查询,但不能是 pivot by
查询。例子:
select * from cj(select * from cj(select * from cj(t1, t2), t3), select * from
t4)
通过打印 SQL 执行过程,分析 SQL 语句执行中每一部分的耗时,可以帮助我们优化 SQL 语句,提升执行效率。具体的优化场景可以参考
DolphinDB SQL执行计划教程
FILE:references/doc_6570.md
# getInstrumentFrequency
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentfrequency.html
**来源**: DolphinDB 官方文档
---
getInstrumentFrequency
语法
getInstrumentFrequency(instrument)
详情
根据输入的金融工具,获取该工具的付息频率(Coupon Frequency)。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
STRING 类型标量或向量。
例子
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"nominal": 100,
"instrumentId": "0001",
"start": 2022.05.15,
"maturity": 2032.05.15,
"dayCountConvention": "ActualActualISDA",
"coupon": 0.0276,
"issuePrice": 100.0,
"frequency": "Semiannual"
}
ins = parseInstrument(bond)
getInstrumentFrequency(ins)
// output: Semiannual
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_6586.md
# setTableComment
**URL**: https://docs.dolphindb.cn/zh/funcs/s/settablecomment.html
**来源**: DolphinDB 官方文档
---
setTableComment
语法
setTableComment(table, comment)
详情
给分布式表添加注释,表注释可通过函数
schema
查看。
参数
table
是一个分布式表。
comment
字符串标量,表示表注释。长度不可超过 4096 字节。
例子
// 创建分布式表
db = database(directory="dfs://testDB", partitionType=VALUE, partitionScheme=1..5)
schemaTB = table(1..5 as id, take(`A`B`C,5) as sym, rand(10.0,5) as price)
pt = db.createPartitionedTable(table=schemaTB, tableName="pt", partitionColumns="id")
// 设置表的注释
setTableComment(table=pt, comment="my first pt")
// 通过 schema 查看
schema(pt)["tableComment"]
// output:'my first pt'
FILE:references/doc_6595.md
# getTablesOfAllClusters
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getTablesOfAllClusters.html
**来源**: DolphinDB 官方文档
---
getTablesOfAllClusters
语法
getTablesOfAllClusters()
详情
与
getClusterDFSTables
函数类似,但此函数能够获取当前用户在多个集群中拥有访问权限的所有表。
参数
无
返回值
字符串向量。
例子
getTablesOfAllClusters()
// Output: ["dfs://testDB/pt1", "trading.schema.pt@cluster3"]
FILE:references/doc_6601.md
# rowMin
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowMin.html
**来源**: DolphinDB 官方文档
---
rowMin
语法
rowMin(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行取最小值的操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL])
rowMin(m);
// output
[1.5,2,1.5]
t1=table(1..5 as x, 6..10 as y)
t2=table(5..1 as a, 10..6 as b);
rowMin(t1);
// output
[1,2,3,4,5]
rowMin(t1[`x], t2, take(2, 5));
// output
[1,2,2,2,1]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2);
select sym,rowMin(price1,price2) as min from t;
sym
min
AAPL
49.6
MS
29.46
IBM
29.52
IBM
30.02
C
26.23
相关函数:
min
FILE:references/doc_6602.md
# symmetricDifference
**URL**: https://docs.dolphindb.cn/zh/funcs/s/symmetricDifference.html
**来源**: DolphinDB 官方文档
---
symmetricDifference
语法
symmetricDifference(X, Y)
或
X^Y
详情
返回两个集合的并集减去两个集合的交集。
参数
X
和
Y
是集合。
返回值
一个集合。
例子
x=set([5,3,4])
y=set(8 9 4 6);
y^x;
// output
set(5,8,3,9,6)
x^y;
// output
set(8,5,3,6,9)
FILE:references/doc_6610.md
# rowImaxLast
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowimaxlast.html
**来源**: DolphinDB 官方文档
---
rowImaxLast
语法
rowImaxLast(args…)
详情
返回每行元素中最大元素的索引。如果有多个相同的最大值,返回右起第一个最大值的索引。
参数
row 系列函数通用参数说明和计算规则请参考:
行计算系列(row
系列)
返回值
结果为一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5 3.2, 1.5 4.8 5.9 1.7, 4.9 2.0 NULL 5.5])
rowImaxLast(m)
// output
[2,1,1,2]
trades = table(10:0,`time`sym`p1`p2`p3`p4`p5`vol1`vol2`vol3`vol4`vol5,[TIMESTAMP,SYMBOL,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,INT,INT,INT,INT,INT])
insert into trades values(2022.01.01T09:00:00, `A, 33.2, 33.8, 33.6, 33.3, 33.1, 200, 180, 180, 220, 200)
insert into trades values(2022.01.01T09:00:00, `A, 33.1, 32.8, 33.2, 34.3, 32.3, 150, 280, 190, 100, 220)
insert into trades values(2022.01.01T09:00:00, `A, 31.2, 32.6, 33.6, 35.3, 34.5, 220, 160, 130, 100, 110)
insert into trades values(2022.01.01T09:00:00, `A, 30.2, 32.5, 33.6, 35.3, 34.1, 200, 180, 150, 140, 120)
insert into trades values(2022.01.01T09:00:00, `A, 33.2, 33.8, 33.6, 33.3, 33.1, 180, 160, 160, 180, 200)
select rowAt(matrix(p1, p2, p3, p4, p5), rowImaxLast(vol1, vol2, vol3, vol4, vol5)) as price from trades
// output
price
33.3
32.8
31.2
30.2
33.1
相关函数:
rowImax
FILE:references/doc_6619.md
# form
**URL**: https://docs.dolphindb.cn/zh/funcs/f/form.html
**来源**: DolphinDB 官方文档
---
form
语法
form(X)
详情
生成变量或常数的数据形式标识符(data form ID)。数据形式标识符和对应的数据形式为:0: 标量; 1: 向量; 2:
数据对; 3: 矩阵; 4: 集合; 5: 字典; 6: 表
; 10: tensor
。
参数
X
是一个任意的变量或常数。
返回值
一个整型标量,表示数据形式标识符。
例子
form(false);
// output
0
form(`TEST);
// output
0
form(`t1`t2`t3);
// output
1
form(1 2 3);
// output
1
x= 1 2 3
if(form(x) == VECTOR){y=1}
y;
// output
1
form(1..6$2:3);
// output
3
FILE:references/doc_6622.md
# talib
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/talib.html
**来源**: DolphinDB 官方文档
---
talib
语法
talib(func, args...)
详情
当 args 的前几个元素为 NULL 时,DolphinDB 内置滑动窗口函数与 python TA-lib
的处理方式不同:
DolphinDB 滑动窗口函数:窗口从第一个元素开始进行滑动窗口计算;
python TA-lib: 保留开始的所有前置 NULL 值,然后从第一个非空元素开始进行滑动窗口计算。
若需要与 python TA-lib 保持一致的处理方式,可以使用 talib 函数。
参数
func
是一个函数名。
args
是函数 func 的参数。
其他相关的 talib 系列函数的参数说明和窗口计算规则请参考:
TA-lib 系列
返回值
一个向量,数据类型为 VOID、LONG 或 DOUBLE。
例子
以下例子通过对比说明了
talib
函数和 DolphinDB 函数处理 NULL 值的区别。
msum(NULL 1 2 3 4 5 6 7 8 9, 3)
输出返回:[,,3,6,9,12,15,18,21,24]
talib(msum, NULL 1 2 3 4 5 6 7 8 9, 3)
输出返回:[,,,6,9,12,15,18,21,24]
FILE:references/doc_6624.md
# getMemLimitOfQueryResult
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getMemLimitOfQueryResult.html
**来源**: DolphinDB 官方文档
---
getMemLimitOfQueryResult
语法
getMemLimitOfQueryResult()
详情
获取单次查询结果占用的内存上限(单位为字节)。
参数
无
返回值
DOUBLE 类型标量。
例子
setMemLimitOfQueryResult(0.2)
getMemLimitOfQueryResult() / 1024 / 1024 / 1024
// output: 0.2
相关函数:
setMemLimitOfQueryResult
FILE:references/doc_6627.md
# wls
**URL**: https://docs.dolphindb.cn/zh/funcs/w/wls.html
**来源**: DolphinDB 官方文档
---
wls
语法
wls(Y, X, W, [intercept=true], [mode=0])
详情
返回对
X
和
Y
计算加权最小二乘回归的结果。
参数
Y
是因变量;
X
是自变量。
Y
是一个向量;
X
是一个矩阵、表或元组。当
X
是矩阵时,如果行数等于
Y
的长度,
X
的每一列都是一个因子;如果行数不等于
Y
的长度,并且如果列数等于
Y
的长度,
X
的每一行都是一个因子。
W
是一个向量,表示权重,各元素为一个非负数。
intercept
是一个布尔变量,表示是否包含回归中的截距。默认值是 true。当它为 true 时,系统自动给
X
添加一列 "1"
以生成截距。
mode
是一个整数,默认值为 0,可取以下 3 个值
0:输出一个系数估计向量
1:输出一个具有系数估计,标准差,t 统计量和 p 值的表
2:输出一个具有 ANOVA(方差分析)、RegressionStat(回归统计)、Cofficient(系数)和
Residual(残差)的字典,具体含义见下表:
键 ANOVA 对应值:
Source of Variance
自由度(Degree of freedom)
平方和(Sum of Square)
均方差(Mean of square)
F统计量
Significance
Regression(回归)
变量个数(p)
回归平方和(SSR)
回归均方差(MSR=SSR/R)
MSR 对 MSE 的比值
显著性,即统计出的P值
Residual(残差)
残差自由度(n-p-1)
残差平方和(SSE)
残差均方差(MSE=MSE/E)
Total
样本自由度, 不包括常数项(n-1)
总离差平方和(SST)
键 RegressionStat 对应值:
item
统计值
R2
R 决定系数,描述回归曲线对真实数据点拟合程度的统计量。范围在[0,1]之间,越接近1
,说明对y的解释能力越强,拟合越好。
AdjustedR2
经自由度修正后的决定系数,通过样本数量与模型数量对 R-squared 进行修正。
StdError
回归残差标准误差,残差经自由度修正后的标准差。
Observations
观察样本个数。
键 Coefficient 对应值:
元素
说明
factor
自变量名称。
beta
回归系数估计值。
stdError
回归系数标准误差。标准差越大,回归系数的估计值越不靠谱。
tstat
T 统计值,衡量系数的统计显著性。
键 Residual 对应每一个预测值和实际值之间的残差。
返回值
取决于
mode
参数值。
例子
x1=1 3 5 7 11 16 23
x2=2 8 11 34 56 54 100
y=0.1 4.2 5.6 8.8 22.1 35.6 77.2;
w=rand(10,7)
wls(y, x1, w)
// output
[-17.6177 4.0016]
wls(y, (x1,x2), w);
// output
[-17.4168 3.0481 0.2214]
wls(y, (x1,x2), w, 1, 1);
factor
beta
stdError
tstat
pvalue
Intercept
-17.4168
4.8271
-3.6081
0.0226
x1
3.0481
1.6232
1.8779
0.1336
x2
0.2214
0.3699
0.5986
0.5817
wls(y, (x1,x2), w,1, 2);
// output
Coefficient->
factor beta stdError tstat pvalue
--------- --------- -------- --------- --------
intercept -10.11392 4.866583 -2.078239 0.106234
x1 3.938138 2.061191 1.910613 0.128655
x2 -0.088542 0.446667 -0.198227 0.852534
Residual->[6.452866,3.207839,-3.002812,-5.642629,-6.147264,-12.515038,5.590914]
RegressionStat->
item statistics
------------ ----------
R2 0.957998
AdjustedR2 0.936997
StdError 17.172833
Observations 7
ANOVA->
Breakdown DF SS MS F Significance
---------- -- ------------ ------------ --------- ------------
Regression 2 26905.306594 13452.653297 45.616718 0.001764
Residual 4 1179.624835 294.906209
Total 6 28084.931429
x=matrix(1 4 8 2 3, 1 4 2 3 8, 1 5 1 1 5);
w=rand(8,5)
wls(1..5, x,w,0,1);
factor
beta
stdError
tstat
pvalue
beta0
0.0026
1.4356
0.0018
0.9988
beta1
-1
1.2105
-0.8261
0.5605
beta2
0.4511
0.5949
0.7582
0.587
beta3
1.687
1.7389
0.9701
0.5097
FILE:references/doc_6642.md
# seek
**URL**: https://docs.dolphindb.cn/zh/funcs/s/seek.html
**来源**: DolphinDB 官方文档
---
seek
语法
seek(handle, offset, [mode])
详情
如果没有抛出异常,
seek
函数将返回文件内部游标经计算后的位置。
当系统从一个文件中读取数据,或把数据写入一个文件中时,内部的游标将前进。用户可以通过
seek
函数手动操纵游标。
参数
handle
必须是一个文件句柄。
offset
是一个整数。
mode
是 HEAD, CURRENT, TAIL 之一。默认的
mode
是 CURRENT。
返回值
INT 类型标量。
例子
// 编写一个返回文件长度的函数
def fileLength(f): file(f).seek(0, TAIL)
fileLength("test.txt");
// output
14
// 把内部游标移动到文件头部。
fin=file("test.txt")
fin.readLine();
// output
Hello World!
fin.seek(0, HEAD);
// output
0
fin.readLine();
// output
Hello World!
FILE:references/doc_6643.md
# addMetrics
**URL**: https://docs.dolphindb.cn/zh/funcs/a/addMetrics.html
**来源**: DolphinDB 官方文档
---
addMetrics
语法
addMetrics(engine, newMetrics, newMetricsSchema,
[windowSize], [fill])
别名:
extendMetrics
详情
动态增加流数据引擎的计算指标。
参数
engine
是流数据引擎,即
createTimeSeriesEngine
等函数返回的抽象表对象。请注意,暂不支持
createAnomalyDetectionEngine
和
createReactiveStateEngine
引擎。
newMetrics
是元代码,表示流数据引擎增加的计算指标。可以是一个或多个表达式、系统内置或用户自定义函数,也可以是一个常量标量/向量。当指定为常量向量时,对应的输出列应该设置为数组向量类型。
newMetricsSchema
是表对象,指定新增的计算指标在输出表中的列名和数据类型。
windowSize
是一个正整数,表示新增指标的计算窗口长度。仅适用于时间序列引擎,且必须为已指定的窗口长度之一。若未指定,默认值为第一个已指定的窗口长度。
fill
可选参数,一个标量或向量,指定某个分组的某个窗口无数据时的处理方法。可取以下值:
'none': 不输出结果。
'null': 输出结果为 NULL。
'ffill': 输出上一个有数据的窗口的结果。
'具体数值':该值的数据类型需要和对应的
metrics
计算结果的类型保持一致。
fill
可以输入向量,长度与
metrics
元素个数保持一致,表示为每个
metrics
指定不同的
fill
方式。若为向量,向量中各项只能是 'null', 'ffill' 或一个数值,不能是 'none'。
例子
使用流数据时间序列引擎计算 sum(x) 指标。
share streamTable(10000:0,`time`id`x, [TIMESTAMP,SYMBOL,INT]) as t
output1 = table(10000:0, `time`sum_x, [TIMESTAMP,INT])
agg1 = createTimeSeriesEngine(name=`agg1, windowSize=100, step=50, metrics=<sum(x)>, dummyTable=t, outputTable=output1, timeColumn=`time)
subscribeTable(tableName="t", actionName="agg1", offset=0, handler=append!{agg1}, msgAsTable=true)
n=500
time=2019.01.01T00:00:00.000+(1..n)
id=take(`ABC`DEF, n)
x=1..n
insert into t values(time, id, x);
select * from output1;
time
sum_x
2019.01.01T00:00:00.050
1,225
2019.01.01T00:00:00.100
4,950
2019.01.01T00:00:00.150
9,950
2019.01.01T00:00:00.200
14,950
2019.01.01T00:00:00.300
24,950
2019.01.01T00:00:00.350
29,950
2019.01.01T00:00:00.400
34,950
2019.01.01T00:00:00.450
39,950
2019.01.01T00:00:00.500
44,950
给时间序列引擎增加 avg(x) 指标,该指标在输出表中的名称为 avg_x,数据类型为 DOUBLE。
newMetricsSchema= table(1:0, [`avg_x], [DOUBLE])
addMetrics(agg1, <avg(x)>, newMetricsSchema);
n=300
time=2019.01.01T00:00:00.500+(1..n)
id=take(`ABC`DEF, n)
x=500+1..n
insert into t values(time, id, x);
select * from output1;
time
sum_x
avg_x
2019.01.01T00:00:00.050
1,225
2019.01.01T00:00:00.100
4,950
2019.01.01T00:00:00.150
9,950
2019.01.01T00:00:00.200
14,950
2019.01.01T00:00:00.250
19,950
2019.01.01T00:00:00.300
24,950
2019.01.01T00:00:00.350
29,950
2019.01.01T00:00:00.400
34,950
2019.01.01T00:00:00.450
39,950
2019.01.01T00:00:00.500
44,950
2019.01.01T00:00:00.550
49,950
525
2019.01.01T00:00:00.600
54,950
550
2019.01.01T00:00:00.650
59,950
599.5
2019.01.01T00:00:00.700
64,950
649.5
2019.01.01T00:00:00.750
69,950
699.5
2019.01.01T00:00:00.800
74,950
749.5
FILE:references/doc_6657.md
# mavgTopN
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mavgTopN.html
**来源**: DolphinDB 官方文档
---
mavgTopN
语法
mavgTopN(X, S, window, top, [ascending=true],
[tiesMethod='oldest'])
参数说明和窗口计算规则请参考:
mTopN
详情
在给定长度(以元素个数衡量)的滑动窗口内,根据
ascending
指定的排序方式将
X
按照
S
进行稳定排序后,取前
top
个元素计算平均值。
返回值
当
X
为向量时:返回与
X
长度相同的向量。
若
X
为矩阵/表,返回与输入具有相同维度的矩阵或表。
例子
X = 1..7
S = 0.3 0.5 0.1 0.1 0.5 0.2 0.4
mavgTopN(X, S, 4, 2)
// output: [1,1.5,2,3.5,3.5,3.5,5]
X = NULL 1 2 3 4 NULL 5
S = 3 5 1 1 5 2 4
mavgTopN(X, S, 4, 2)
// output: [,1,2,2.5,2.5,2.5,3]
X = matrix(1..5, 6..10)
S = 2022.01.01 2022.02.03 2022.01.23 2022.04.06 2021.12.29
mavgTopN(X, S, 3, 2)
#0
#1
1
6
1.5
6.5
2
7
2.5
7.5
4
9
X = matrix(1..5, 6..10)
S = matrix(2022.01.01 2022.02.03 2022.01.23 NULL 2021.12.29,NULL 2022.02.03 2022.01.23 2022.04.06 NULL)
mavgTopN(X, S, 3, 2)
#0
#1
1
1.5
7
2
7.5
2.5
7.5
4
8.5
某行情数据的数据表,包含四列:股票代码 code,交易日期 date,收盘价 close 和交易量 volume。
t = table(take(`IBM`APPL, 20) as code, 2020.01.01 + 1..20 as date, rand(100,20) + 20 as volume, rand(10,20) + 100.0 as close)
code
date
volume
close
IBM
2020.01.02
114
107
APPL
2020.01.03
66
106
IBM
2020.01.04
36
106
APPL
2020.01.05
52
101
IBM
2020.01.06
28
100
APPL
2020.01.07
55
108
IBM
2020.01.08
54
106
APPL
2020.01.09
103
106
IBM
2020.01.10
94
104
APPL
2020.01.11
82
102
IBM
2020.01.12
98
103
APPL
2020.01.13
118
101
IBM
2020.01.14
61
105
APPL
2020.01.15
43
105
IBM
2020.01.16
41
104
APPL
2020.01.17
111
106
IBM
2020.01.18
119
103
APPL
2020.01.19
24
107
IBM
2020.01.20
22
109
APPL
2020.01.21
26
103
计算每只股票窗口期内交易量最大的3条记录的的平均收盘价。
select code, date, mavgTopN(close, volume, 5, 3, false) from t context by code
code
date
mavgTopN_close
APPL
2020.01.03
106
APPL
2020.01.05
103.5
APPL
2020.01.07
105
APPL
2020.01.09
106.6667
APPL
2020.01.11
104.6667
APPL
2020.01.13
103
APPL
2020.01.15
103
APPL
2020.01.17
104.3333
APPL
2020.01.19
103
APPL
2020.01.21
104
IBM
2020.01.02
107
IBM
2020.01.04
106.5
IBM
2020.01.06
104.3333
IBM
2020.01.08
106.3333
IBM
2020.01.10
105.6667
IBM
2020.01.12
104.3333
IBM
2020.01.14
104
IBM
2020.01.16
104
IBM
2020.01.18
103.3333
IBM
2020.01.20
103.6667
相关函数:
mavg
FILE:references/doc_6663.md
# curvePredict
**URL**: https://docs.dolphindb.cn/zh/funcs/c/curvePredict.html
**来源**: DolphinDB 官方文档
---
curvePredict
语法
curvePredict(curve, dt)
详情
在给定的曲线上,预测指定点位(由
dt
确定)的曲线值。目前仅支持零息利率曲线。
参数
curve
MKTDATA 类型对象(IrYieldCurve)。
dt
DOUBLE 类型标量/向量,或 DATE 类型标量/向量。
当类型为 DOUBLE 时,表示以“年”为单位的时间。
当类型为 DATE 时,表示具体的日期。
返回值
DOUBLE 类型标量或向量。
例子
curveDict = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": 2025.08.18,
"currency": "CNY",
"dayCountConvention": "ActualActualISDA",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": [2025.08.21,
2025.08.27,
2025.09.03,
2025.09.10,
2025.09.22,
2025.10.20,
2025.11.20,
2026.02.24,
2026.05.20,
2026.08.20,
2027.02.22,
2027.08.20,
2028.08.21],
"values":[1.5113,
1.5402,
1.5660,
1.5574,
1.5556,
1.5655,
1.5703,
1.5934,
1.6040,
1.6020,
1.5928,
1.5842,
1.6068]/100
}
curve = parseMktData(curveDict)
curvePredict(curve, 2025.10.18)
// output: 0.0156
curvePredict(curve, 1.0)
// output: 0.0160
print curvePredict(curve, [2025.10.18, 2026.10.18])
// output: [0.0156,0.0159]
print curvePredict(curve, [1.0, 2.0])
// output: [0.0160,0.0158]
相关函数:
parseMktData
FILE:references/doc_667.md
# mannWhitneyUTest
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mannWhitneyUTest.html
**来源**: DolphinDB 官方文档
---
mannWhitneyUTest
语法
mannWhitneyUTest(X, Y, [correct=true])
详情
对
X
和
Y
进行 Mann-Whitney U 检验。
参数
X
是一个数值向量。
Y
是一个数值向量。
correct
是一个布尔值,表示在求 p 值时是否考虑连续性校正。默认值为 true。
返回值
返回一个字典,包含以下 key:
stat:一张表,包含三种不同备择假设下的 p 值
correct:求 p 值时是否考虑连续性校正
method:字符串 "Mann-Whitney U test"
U:U 统计量
例子
mannWhitneyUTest(5 1 4 3 5, 2 4 7 -1 0 4);
// output
stat->
alternativeHypothesis pValue
------------------------------------- --------
true location shift is not equal to 0 0.518023
true location shift is less than 0 0.259011
true location shift is greater than 0 0.797036
correct->true
method->Mann-Whitney U test
U->11
FILE:references/doc_6673.md
# createReactiveStateEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createReactiveStateEngine.html
**来源**: DolphinDB 官方文档
---
createReactiveStateEngine
语法
createReactiveStateEngine(name, metrics, dummyTable, outputTable, [keyColumn], [filter],
[snapshotDir], [snapshotIntervalInMsgCount], [keepOrder], [keyPurgeFilter],
[keyPurgeFreqInSecond=0], [raftGroup], [outputElapsedMicroseconds=false],
[keyCapacity=1024], [parallelism=1], [outputHandler], [msgAsTable=false])
详情
创建响应式状态引擎。返回一个表对象,向该表写入数据意味着这些数据进入响应式状态引擎进行计算。
注:
不支持乱序处理机制,用户需要自行保证输入的数据有序。
下列状态函数在 DolphinDB
的响应式状态引擎中的实现均得到了优化。需要注意的是,状态引擎不允许使用未经优化的内置状态函数,且需避免使用聚合函数。
累计窗口函数:
cumavg
,
cumsum
,
cumprod
,
cumcount
,
cummin
,
cummax
,
cumvar
,
cumvarp
,
cumstd
,
cumstdp
,
cumcorr
,
cumcovar
,
cumbeta
,
cumwsum
,
cumwavg
,
cumfirstNot
,
cumlastNot
,
cummed
,
cumpercentile
,
cumnunique
,
cumPositiveStreak
,
cummdd
滑动窗口函数:
ema
,
mavg
,
msum
,
mcount
,
mprod
,
mvar
,
mvarp
,
mstd
,
mstdp
,
mskew
,
mkurtosis
,
mmin
,
mmax
,
mimin
,
mimax
,
mmed
,
mpercentile
,
mrank
,
mcorr
,
mcovar
,
mbeta
,
mwsum
,
mwavg
,
mmad
,
mfirst
,
mlast
,
mslr
,
tmove
,
tmfirst
,
tmlast
,
tmsum
,
tmsum2
,
tmavg
,
tmcount
,
tmvar
,
tmvarp
,
tmstd
,
tmstdp
,
tmprod
,
tmskew
,
tmkurtosis
,
tmmin
,
tmmax
,
tmmed
,
tmpercentile
,
tmrank
,
tmcovar
,
tmbeta
,
tmcorr
,
tmwavg
,
tmwsum
,
tmoving
,
moving
,
sma
,
wma
,
dema
,
tema
,
trima
,
linearTimeTrend
,
talib
,
t3
,
ma
,
gema
,
wilder
,
mmaxPositiveStreak
,
movingWindowData
,
tmovingWindowData
序列相关函数:
deltas
,
ratios
,
ffill
,
move
,
prev
,
iterate
,
ewmMean
,
ewmVar
,
ewmStd
,
ewmCov
,
ewmCorr
,
prevState
,
percentChange
topN相关函数:
msumTopN
,
mavgTopN
,
mstdpTopN
,
mstdTopN
,
mvarpTopN
,
mvarTopN
,
mcorrTopN
,
mbetaTopN
,
mcovarTopN
,
mwsumTopN
,
cumsumTopN
,
cumwsumTopN
,
cumvarTopN
,
cumvarpTopN
,
cumstdTopN
,
cumstdpTopN
,
cumcorrTopN
,
cumbetaTopN
,
cumavgTopN
,
cumskewTopN
,
cumkurtosisTopN
,
mskewTopN
,
mkurtosisTopN
,
tmsumTopN
,
tmavgTopN
,
tmstdTopN
,
tmstdpTopN
,
tmvarTopN
,
tmvarpTopN
,
tmskewTopN
,
tmkurtosisTopN
,
tmbetaTopN
,
tmcorrTopN
,
tmcovarTopN
,
tmwsumTopN
高阶函数:
segmentby
(参数
func
暂支持 cumsum, cummax, cummin, cumcount,
cumavg, cumstd, cumvar, cumstdp, cumvarp),
moving
,
byColumn
,
accumulate
,
window
其他函数:
talibNull
,
dynamicGroupCumsum
,
dynamicGroupCumcount
,
topRange
,
lowRange
,
trueRange
,
sumbars
特殊函数(仅支持在引擎内使用):
stateIterate
,
conditionalIterate
,
genericStateIterate
,
genericTStateIterate
注:
talib
作为状态函数时,第一个参数
func
只能是响应式状态引擎支持的状态函数。
有关更多流数据引擎的应用场景说明,参考:
流计算引擎
。
计算规则
每注入一条数据都会计算并产生一条结果。用户可以通过设置参数
filter
过滤计算结果后输出。 若指定了
keyColumn
进行分组,则计算将在组内进行。
注:
状态引擎的输出结果可能和输入顺序不一致,建议配置参数
keepOrder
=
true,保持输出结果的有序性。
引擎的其它功能
支持数据/状态清理:状态引擎内部的状态数据是按分组保存的,为避免分组过多,导致引擎内部内存开销过大,可以将历史分组数据进行清理。用户可以通过配置参数
keyPurgeFilter
设置清理条件,配置
keyPurgeFreqInSecond
设置清理时间间隔。
快照机制:启用快照机制之后,系统若出现异常,可及时将流数据引擎恢复到最新的快照状态。(详情请参考
snapshotDir
和
snapshotIntervalInMsgCount
的参数说明)
流数据引擎高可用:若要启用引擎高可用,需在订阅端 raft 组的 leader 节点创建引擎并通过
raftGroup
参数开启高可用。开启高可用后,当 leader 节点宕机时,会自动切换新 leader
节点重新订阅流数据表。
参数
name
字符串标量,表示响应式状态引擎的名称,作为其在一个数据节点/计算节点上的唯一标识。可包含字母,数字和下划线,但必须以字母开头。
metrics
以元代码的形式表示计算公式,可以是一个或多个表达式、系统内置或用户自定义函数、一个常量标量/向量。当指定为常量向量时,对应的输出列应该设置为数组向量类型。有关元代码的详情可参考
Metaprogramming
。若需使用用户自定义函数,请注意以下事项:
需在定义前添加声明 "@state"。状态函数只能包含赋值语句和 return 语句。
自
2.00.9
版本起,支持使用 if-else
条件语句,且条件只能是标量。
自
2.00.11
版本起,支持使用 for 循环(包含 break, continue
语句),请注意不支持嵌套 for 循环,且循环次数须小于 100 次。
状态引擎中可以使用无状态函数或者状态函数。但不允许在无状态函数中嵌套使用状态函数。
若赋值语句的右值是一个多返回值的函数(内置函数或自定义函数),则需要将多个返回值同时赋予多个变量。例如:两个返回值的函数 linearTimeTrend
应用于自定义状态函数中,正确写法为:
@state
def forcast2(S, N){
linearregIntercept, linearregSlope = linearTimeTrend(S, N)
return (N - 1) * linearregSlope + linearregIntercept
}
dummyTable
一个表对象,和输入的流数据表的 schema 一致,可以含有数据,亦可为空表。
outputTable
计算结果的输出表,可以是内存表或分布式表。使用
createReactiveStateEngine
函数之前,需要将输出表预先设立为一个空表,并指定各列列名以及数据类型。响应式状态引擎会将计算结果注入该表。输出表的各列的顺序如下:
分组列。若指定
keyColumn
,则根据
keyColumn
的设置,输出表的前几列必须和
keyColumn
设置的列及其顺序保持一致。
耗时列和记录数。若指定
outputElapsedMicroseconds
= true,则需要指定一个 LONG 类型和一个 INT
类型的列,分别用于存储引擎内部每个 batch 的数据耗时(单位:微秒)和记录数。
计算结果列。可为多列。
keyColumn
可选参数,字符串标量或向量表示分组列名。若指定该参数,计算将在各分组进行。
filter
可选参数,以元代码的形式表示过滤条件。过滤条件只能是一个表达式,并且只能包含
dummyTable
中的列。设置多个条件时,用逻辑运算符(and, or)连接。引擎会先计算指标,然后根据
filter
指定的过滤条件,输出满足条件的输入数据对应的计算结果。
若要开启快照机制(snapshot),必须指定
snapshotDir
与
snapshotIntervalInMsgCount
。
snapshotDir
可选参数,字符串,表示保存引擎快照的文件目录。
指定的目录必须存在,否则系统会提示异常。
创建流数据引擎时,如果指定了
snapshotDir
,会检查该目录下是否存在快照。如果存在,会加载该快照,恢复引擎的状态。
多个引擎可以指定同一个目录存储快照,用引擎的名称来区分快照文件。
一个引擎的快照可能会使用三个文件名:
临时存储快照信息:文件名为
<engineName>.tmp
;
快照生成并刷到磁盘:文件保存为
<engineName>.snapshot
;
存在同名快照:旧快照自动重命名为
<engineName>.old
。
snapshotIntervalInMsgCount
可选参数,为整数类型,表示每隔多少条数据保存一次流数据引擎快照。
keepOrder
可选参数,表示输出表数据是否按照输入时的顺序排序。设置
keepOrder
=
true,表示输出表按照输入时的顺序排序。当
keyColumn
包含有时间列时,
keepOrder
默认值为 true,否则默认值为
false。
keyPurgeFilter
可选参数,是一个由布尔表达式组成的元代码,表示清理条件。各表达式只能引用
outputTable
中的字段。必须指定
keyColumn
才能使用该参数。
keyPurgeFreqInSecond
正整数,表示触发数据清理需要满足的时间间隔(以秒为单位)。必须指定
keyColumn
才能使用该参数。
响应式状态引擎提供了
keyPurgeFilter
,
keyPurgeFreqInSecond
两个参数,用来清理不再需要的分组数据。每次数据注入时,系统会依次根据以下条件决定是否触发数据清理:
检测本次数据注入与上一次数据注入的时间间隔是否大于等于
keyPurgeFreqInSecond
(第一次数据注入时,检测注入时间和引擎创建时间的间隔);
若满足上述条件,系统将根据
keyPurgeFilter
指定的条件,过滤出待清理的数据;
若待清理的数据所属的分组数大于等于所有分组数的 10%,则触发清理。
若需要查看清理前后的状态,可以通过调用
getStreamEngineStat
函数查看 ReactiveStreamEngine 引擎状态的 numGroups
列,来对比响应式状态引擎清理前后分组数的变化。
raftGroup
是流数据高可用订阅端 raft 组的 ID (大于1的整数,由流数据高可用相关的配置项
streamingRaftGroups
*指定)。设置该参数表示开启计算引擎高可用。在 leader 节点创建流数据引擎后,会同步在
follower 节点创建该引擎。每次保存的 snapshot 也会同步到 follower。当 raft 组的 leader 节点宕机时,会自动切换新 leader
节点重新订阅流数据表。请注意,若要指定
raftGroup
,必须同时指定
snapshotDir
。
若同时有一批数据注入响应式状态引擎,则引擎内部数据是分批进行计算的,每个批次的数据称为一个 batch,每个 batch 包含记录数由系统决定。
outputElapsedMicroseconds
布尔值,可选参数,表示是否输出每个 batch 中数据从注入引擎到计算输出的总耗时,以及每个 batch
包含的总记录数,默认为 false。指定参数
outputElapsedMicroseconds
后,在定义
outputTable
时需要指定耗时列和记录数两列,详见
outputTable
参数说明。
keyCapacity
正整数,可选参数,表示建表时系统为该表预分配的 key 分组数量,用于调整状态表中 key
的函数。通过该参数的合理设置,能够降低在 key 分组较多时可能出现的延迟。
parallelism
不超过63的正整数,可选参数,表示并行计算的工作线程数,默认值为
1。在计算量较大时,合理地调整该参数能够有效利用计算资源,降低计算耗时。
注:
parallelism
不能超过 min(许可核数, 逻辑核数)-1。
outputHandler
一元函数。设置此参数时,引擎计算结束后,不再将计算结果写到输出表,而是会调用此函数处理计算结果。
msgAsTable
布尔标量,表示在设置了参数 outputHandler 时,将引擎的计算结果以表的结构调用函数。默认值为
false,此时将计算结果的每一列作为元素组成元组。
返回值
返回一个表对象。
例子
例1.
def sum_diff(x, y){
return (x-y)/(x+y)
}
factor1 = <ema(1000 * sum_diff(ema(price, 20), ema(price, 40)),10) - ema(1000 * sum_diff(ema(price, 20), ema(price, 40)), 20)>
share streamTable(1:0, `sym`time`price, [STRING,DATETIME,DOUBLE]) as tickStream
share table(1000:0, `sym`time`factor1, [STRING,DATETIME,DOUBLE]) as result
rse = createReactiveStateEngine(name="reactiveDemo", metrics =[<time>, factor1], dummyTable=tickStream, outputTable=result, keyColumn="sym", filter=<sym in ["000001.SH", "000002.SH"]>)
subscribeTable(tableName=`tickStream, actionName="factors", handler=tableInsert{rse})
data1 = table(take("000001.SH", 100) as sym, 2021.02.08T09:30:00 + 1..100 *3 as time, 10+cumsum(rand(0.1, 100)-0.05) as price)
data2 = table(take("000002.SH", 100) as sym, 2021.02.08T09:30:00 + 1..100 *3 as time, 20+cumsum(rand(0.2, 100)-0.1) as price)
data3 = table(take("000003.SH", 100) as sym, 2021.02.08T09:30:00 + 1..100 *3 as time, 30+cumsum(rand(0.3, 100)-0.15) as price)
data = data1.unionAll(data2).unionAll(data3).sortBy!(`time)
replay(inputTables=data, outputTables=tickStream, timeColumn=`time)
查看结果表
result
,可见只有过滤条件中的 "000001.SH" 与 "000002.SH"
这两只股票的计算结果被输出。
若要重复调试以上代码,需要先执行以下代码。
unsubscribeTable(tableName=`tickStream, actionName="factors")
dropStreamEngine(`reactiveDemo)
undef(`tickStream, SHARED)
例2.
keyColumn
设置以股票和日期进行分组计算,并设置输出时间在 "2012.01.01"
和"2012.01.03" 之间的计算结果。
share streamTable(1:0, `date`time`sym`market`price`qty, [DATE, TIME, SYMBOL, CHAR, DOUBLE, INT]) as trades
share table(100:0, `date`sym`factor1, [DATE, STRING, DOUBLE]) as outputTable
engine = createReactiveStateEngine(name="test", metrics=<mavg(price, 3)>, dummyTable=trades, outputTable=outputTable, keyColumn=["date","sym"], filter=<date between 2012.01.01 : 2012.01.03>, keepOrder=true)
subscribeTable(tableName=`trades, actionName="test", msgAsTable=true, handler=tableInsert{engine})
n=100
tmp = table(rand(2012.01.01..2012.01.10, n) as date, rand(09:00:00.000..15:59:59.999, n) as time, rand("A"+string(1..10), n) as sym, rand(['B', 'S'], n) as market, rand(100.0, n) as price, rand(1000..2000, n) as qty)
trades.append!(tmp)
select * from outputTable
//若要重复调试以上代码,需要先执行以下代码
unsubscribeTable(tableName=`trades, actionName="test")
dropStreamEngine(`test)
undef(`trades, SHARED)
例3. 2.00.9 版本后,支持在响应式状态引擎中调用
moving
高阶函数计算 array
vector。
defg myFactor(x){
return avg(var(x));
}
share streamTable(1:0, `DateTime`SecurityID`Trade, [TIMESTAMP, SYMBOL, DOUBLE[]]) as tickStream
share table(1000:0, `SecurityID`DateTime`result, [SYMBOL, DATETIME, DOUBLE]) as result
rse = createReactiveStateEngine(name="reactiveDemo", metrics =<[DateTime, moving(myFactor, Trade, 3, 1)]>, dummyTable=tickStream, outputTable=result, keyColumn="SecurityID")
DateTime = 2022.09.15T09:00:00.000+1..12
SecurityID = take(`600021, 12)
Trade = [[10.06, 10.06], [10.04], [10.05, 10.06, 10.05, 10.08],[10.02,10.01], [10.06, 10.06, 10.05, 10.05], [10.04], [10.05,10.08, 10.09],[10.02,10.01],[10.06, 10.06, 10.05], [10.04, 10.03], [10.05, 10.06, 10.05, 10.08, 10.09],[10.02]]
t = table(1:0, `DateTime`SecurityID`Trade, [TIMESTAMP, SYMBOL, DOUBLE[]])
tableInsert(t, DateTime, SecurityID, Trade)
rse.append!(t)
select * from result
dropStreamEngine("reactiveDemo")
例4. 本例对例3进行改造,在指标中指定一个常数,表示因子名称。此时,输出表中会包含一个因子名称列。
defg myFactor(x){
return avg(var(x));
}
share streamTable(1:0, `DateTime`SecurityID`Trade, [TIMESTAMP, SYMBOL, DOUBLE[]]) as tickStream
share table(1000:0, `SecurityID`DateTime`factorName`result, [SYMBOL, DATETIME, STRING, DOUBLE]) as result
rse = createReactiveStateEngine(name="reactiveDemo", metrics =<[DateTime,"factor1", moving(myFactor, Trade, 3, 1)]>, dummyTable=tickStream, outputTable=result, keyColumn="SecurityID")
DateTime = 2022.09.15T09:00:00.000+1..12
SecurityID = take(`600021, 12)
Trade = [[10.06, 10.06], [10.04], [10.05, 10.06, 10.05, 10.08],[10.02,10.01], [10.06, 10.06, 10.05, 10.05], [10.04], [10.05,10.08, 10.09],[10.02,10.01],[10.06, 10.06, 10.05], [10.04, 10.03], [10.05, 10.06, 10.05, 10.08, 10.09],[10.02]]
t = table(1:0, `DateTime`SecurityID`Trade, [TIMESTAMP, SYMBOL, DOUBLE[]])
tableInsert(t, DateTime, SecurityID, Trade)
rse.append!(t)
select * from result
SecurityID
DateTime
factorName
result
600021
2022.09.15 09:00:00
factor1
0
600021
2022.09.15 09:00:00
factor1
0.0001
600021
2022.09.15 09:00:00
factor1
0.0002
600021
2022.09.15 09:00:00
factor1
0.0006
600021
2022.09.15 09:00:00
factor1
0.0004
600021
2022.09.15 09:00:00
factor1
0.0004
600021
2022.09.15 09:00:00
factor1
0.0003
600021
2022.09.15 09:00:00
factor1
0.001
600021
2022.09.15 09:00:00
factor1
0.0007
600021
2022.09.15 09:00:00
factor1
0.0004
FILE:references/doc_6682.md
# invPoisson
**URL**: https://docs.dolphindb.cn/zh/funcs/i/invPoisson.html
**来源**: DolphinDB 官方文档
---
invPoisson
语法
invPoisson(mean, X)
详情
返回泊松分布的累计分布函数的逆函数值。
参数
mean
是泊松分布的均值。
X
是0到1之间的浮点型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
invPoisson(1, [0.91, 0.92, 0.93]);
// output: [2, 3, 3]
invPoisson(3, [0.81, 0.83, 0.95, 0.97, 0.99]);
// output: [4, 5, 6, 7, 8]
FILE:references/doc_6683.md
# createDailyTimeSeriesEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createDailyTimeSeriesEngine.html
**来源**: DolphinDB 官方文档
---
createDailyTimeSeriesEngine
语法
createDailyTimeSeriesEngine(name, windowSize, step,
metrics, dummyTable, outputTable, [timeColumn], [useSystemTime=false],
[keyColumn], [garbageSize], [updateTime], [useWindowStartTime],
[roundTime=true], [snapshotDir], [snapshotIntervalInMsgCount], [fill='none'],
[sessionBegin], [sessionEnd], [mergeSessionEnd=false], [forceTriggerTime],
[raftGroup], [forceTriggerSessionEndTime], [keyPurgeFreqInSec], [closed='left'],
[outputElapsedMicroseconds=false], [subWindow]
,
[parallelism=1],[acceptedDelay=0]
, [outputHandler],
[msgAsTable=false], [keyPurgeDaily=true], [mergeLastWindow=false],
[mergeSession]
)
详情
创建流数据日级时间序列引擎。日级时间序列引擎和时间序列引擎窗口划分和计算规则基本一致,但在此基础上做了如下拓展:
该引擎只能在一个自然日的指定时间段内(以下统称为 session)进行窗口的聚合计算。一个自然日内,可以指定多个 session, 如
9:00-12:00,13:00-15:00 等。默认情况下,系统会对 session 的起始时间(
sessionBegin
和
sessionEnd
)进行规整,除非特别指定(详见
mergeLastWindow
)。
出现在一个 session 开始之前的数据,日级时序引擎规定将该部分数据合入该 session 的第一个窗口进行计算。
当日最后一个 session 后到来的数据将被丢弃,不会计入第二天的第一个窗口中。
若指定了
keyColumn
进行分组,则上述计算将在各分组内独立进行。有关乱序数据的处理规则,请参考
createTimeSeriesEngine
函数中的
计算
章节。
更多流数据引擎的应用场景说明可以参考
流计算引擎
。
参数
该引擎是基于时间序列引擎进行的扩展,继承了
createTimeSeriesEngine
所有的参数,请参照
createTimeSeriesEngine
中参数介绍。这里仅介绍与时间序列引擎不同的参数:
sessionBegin
为可选参数,可以是与时间列的数据类型对应的 SECOND、TIME 或 NANOTIME
类型的标量或向量,表示每个时间段的起始时刻。如果
sessionBegin
是一个向量,它必须是递增的。
sessionEnd
为可选参数,可以是与时间列的数据类型对应的 SECOND、TIME 或 NANOTIME
类型的标量或向量,表示每个时间段的结束时刻。可在
sessionEnd
中指定 00:00:00 表示的次日的零点(即当日的 24:00:00)。
注:
session 由 sessionBegin[i] 和 sessionEnd[i] 确定。
若 sessionBegin[i] > sessionEnd[i],则 sessionEnd[i] 视为下一个自然日的时间,此后 session
均为下一个自然日。例如 sessionBegin=[21:00:00, 23:30:00, 09:00:00, 13:00:00],
sessionEnd=[22:00:00, 02:00:00,11:30:00, 15:00:00],此时 session 分别为
21:00:00-22:00:00,23:30:00-次日02:00:00, 次日09:00:00-11:30:00,
次日13:00:00-15:00:00。 21:00:00-22:00:00为第一个session,keyPurgeDaily
在21:00:00之前生效,15:00:00-21:00:00之间的数据都会被丢弃。
若 i = 0 ,则该 session 视为该交易日的第一个 session。例如
sessionBegin=[21:00:00,09:00:00, 13:00:00],sessionEnd=[01:00:00,
11:30:00, 15:00:00],此时 session 分别为 21:00:00-次日01:00:00,次日
09:00:00- 11:30:00, 次日13:00:00- 15:00:00。21:00:00-次日01:00:00
为第一个 session,
keyPurgeDaily
在21:00:00之前生效,15:00:00-21:00:00之间的数据都会被丢弃。
若 i = size(sessionBegin)-1,则该 session 视为该交易日的最后一个 session。例如
sessionBegin=[09:00:00, 13:00:00,
21:00:00],sessionEnd=[11:30:00, 15:00:00, 01:00:00],此时 session
分别为09:00:00-11:30:00,13:00:00-15:00:00,21:00:00-次日01:00:00。09:00:00-11:30:00
为第一个session, keyPurgeDaily
在09:00:00之前生效,01:00:00-09:00:00之间的数据会被丢弃。
若 sessionBegin[i] < sessionEnd[i-1],则 sessionBegin[i] 视为下一个自然日的时间,此后
session 均为下一个自然日。例如 sessionBegin=[21:00:00,09:00:00,
13:00:00],sessionEnd=[23:00:00, 11:30:00, 15:00:00],此时 session 分别为
21:00:00-23:00:00,次日09:00:00-11:30:00,
次日13:00:00-15:00:00。21:00:00-23:00:00为第一个session, keyPurgeDaily
在21:00:00之前生效,15:00:00-21:00:00之间的数据都会被丢弃。
其他示例:
sessionBegin=[00:00:00, 09:00:00, 13:00:00,
21:00:00],sessionEnd=[01:00:00, 11:30:00, 15:00:00, 00:00:00],此时 session
分别为 21:00:00-次日01:00:00,09:00:00-11:30:00, 13:00:00-15:00:00。
21:00:00-次日01:00:00为第一个session, keyPurgeDaily 在21:00:00之前生效(2.00.14.4
前不会生效),15:00:00-21:00:00之间的数据都会被丢弃(2.00.14.4 前会并入21:00:00的第一个窗口)。
sessionBegin=[09:00:00, 13:00:00],sessionEnd=[11:30:00, 15:00:00],此时
session 分别为 09:00:00-11:30:00,13:00:00-15:00:00。keyPurgeDaily
在15:00:00之后生效,15:00:00-24:00:00之间的数据都会被丢弃,00:00:00-09:00:00
的数据会被并入第一个窗口。
mergeSessionEnd
为可选参数,是一个布尔值。当
closed
= 'left'
时,表示每个 session 结束时刻的数据是否合入最后一个窗口。默认值为 false,此时该条数据不会合入当前 session
的最后一个窗口,但可以触发最后一个窗口的计算;如果当前 session 不是该自然日内最后一个 session,则该数据会合入下个 session
的第一个窗口。
forceTriggerSessionEndTime
为可选参数,正整数,单位与
timeColumn
的时间精度一致。若
sessionEnd
时刻对应的窗口数据长时间未发生计算,通过该参数可以设置系统经过多少时间后触发计算并输出。若不指定
fill
,未包含在该窗口内的分组不会输出结果;若指定了
fill
,未包含在该窗口内的分组会按照
fill
指定的方式输出结果。
keyPurgeDaily
为可选参数,是一个布尔值。默认值为
true,表示引擎在收到第一批包含新日期的数据时,先清空之前保存的所有分组,再对这批新数据进行处理。若设置为 false,则引擎不会清理前一天的分组。
mergeLastWindow
为可选参数,是一个布尔值,默认值为 false,可用于处理无法被等长窗口(由
windowSize
指定)均分的不规则 session 时段。当设置为
true
时,系统将最后一个不完整窗口(即小于
windowSize
的窗口)的数据与前一个窗口合并进行计算。该参数不支持和
subWindow
同时指定。
mergeSession
为 BOOL 类型向量,其长度为 session 的数量减
1。mergeSession[i] 为 true 表示 session[i] 和 session[i+1] 合并,false 表示不合并。若两个 session
合并,则
mergeSessionEnd
、
forceTriggerSessionEndTime
和
mergeLastWindow
在前一个 session 的
sessionEnd
处不生效。
返回值
一个表对象。
例子
例1. 设置
mergeSessionEnd
,将每个 session 结束时刻的数据合入最后一个窗口。
share streamTable(1000:0, `date`second`sym`volume, [DATE, SECOND, SYMBOL, INT]) as trades
share keyedTable(`time`sym, 10000:0, `time`sym`sumVolume, [DATETIME, SYMBOL, INT]) as output1
engine1 = createDailyTimeSeriesEngine(name="engine1", windowSize=60, step=60, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output1, timeColumn=`date`second, useSystemTime=false, keyColumn=`sym, garbageSize=50, updateTime=2, useWindowStartTime=false, sessionBegin=09:30:00 13:00:00, sessionEnd=11:30:00 15:00:00,mergeSessionEnd=true)
subscribeTable(tableName="trades", actionName="engine1", offset=0, handler=append!{engine1}, msgAsTable=true);
insert into trades values(2018.10.08,09:25:31,`A,8)
insert into trades values(2018.10.08,09:26:01,`B,10)
insert into trades values(2018.10.08,09:30:02,`A,26)
insert into trades values(2018.10.08,09:30:10,`B,14)
insert into trades values(2018.10.08,11:29:46,`A,30)
insert into trades values(2018.10.08,11:29:50,`B,11)
insert into trades values(2018.10.08,11:30:00,`A,14)
insert into trades values(2018.10.08,11:30:00,`B,4)
insert into trades values(2018.10.08,13:00:10,`A,16)
insert into trades values(2018.10.08,13:00:12,`B,9)
insert into trades values(2018.10.08,14:59:56,`A,20)
insert into trades values(2018.10.08,14:59:58,`B,20)
insert into trades values(2018.10.08,15:00:00,`A,10)
insert into trades values(2018.10.08,15:00:00,`B,29)
sleep(1000)
select * from output1
time
sym
sumVolume
2018.10.08T09:31:00
A
34
2018.10.08T09:31:00
B
24
2018.10.08T11:30:00
A
44
2018.10.08T11:30:00
B
15
2018.10.08T13:01:00
A
16
2018.10.08T13:01:00
B
9
2018.10.08T15:00:00
A
30
2018.10.08T15:00:00
B
49
例2. 设置
forceTriggerSessionEndTime
,达到系统时间,强制触发计算。
share streamTable(1000:0, `date`second`sym`volume, [DATE, SECOND, SYMBOL, INT]) as trades
share keyedTable(`time`sym, 10000:0, `time`sym`sumVolume, [DATETIME, SYMBOL, INT]) as output1
engine1 = createDailyTimeSeriesEngine(name="engine1", windowSize=60, step=60, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output1, timeColumn=`date`second, useSystemTime=false, keyColumn=`sym, garbageSize=50, useWindowStartTime=false, sessionBegin=09:30:00 13:00:00, sessionEnd=11:30:00 15:00:00,mergeSessionEnd=true,forceTriggerSessionEndTime=10)
subscribeTable(tableName="trades", actionName="engine1", offset=0, handler=append!{engine1}, msgAsTable=true);
insert into trades values(date(now()),09:25:31,`A,8)
insert into trades values(date(now()),09:26:01,`B,10)
insert into trades values(date(now()),09:30:02,`A,26)
insert into trades values(date(now()),09:30:10,`B,14)
insert into trades values(date(now()),11:29:46,`A,30)
insert into trades values(date(now()),11:29:50,`B,11)
insert into trades values(date(now()),11:30:00,`B,14)
insert into trades values(date(now()),11:30:01,`A,4)
select * from output1
time
sym
sumVolume
2022.03.24T09:31:00
A
34
2022.03.24T09:31:00
B
24
2022.03.24T11:30:00
A
30
设置
forceTriggerSessionEndTime
= 10,则系统到达 11:30:00 后,再经过 10s
就会触发右边界为11:30:00的窗口内数据的计算。
sleep(10000)
select * from output1
time
sym
sumVolume
2022.03.24T09:31:00
A
34
2022.03.24T09:31:00
B
24
2022.03.24T11:30:00
A
30
2022.03.24T11:30:00
B
25
例3. 如果
sessionEnd
-
sessionBegin
不能整除
step,则会话的最后一个窗口由于长度不足而无法输出。若希望输出该窗口的数据,需要设置
roundTime
=
false,将窗口按一分钟规则规整后输出。
// 清理变量
dropStreamEngine("engine1")
unsubscribeTable(tableName="trades", actionName="engine1")
undef(`trades, SHARED)
undef(`output1,SHARED)
share streamTable(1000:0, `date`time`sym`volume, [DATE, TIME, SYMBOL, INT]) as trades
share keyedTable(`timestamp`sym, 10000:0, `timestamp`sym`sumVolume, [TIMESTAMP, SYMBOL, INT]) as output1
//创建引擎,指定窗口长度为 10 分钟。最后一个 sessionEnd 是 14:57:00
engine1 = createDailyTimeSeriesEngine(name="engine1", windowSize=600000, step=600000,
metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output1, timeColumn=`date`time, garbageSize=50, updateTime=2,
useSystemTime=false, keyColumn=`sym, useWindowStartTime=false, mergeSessionEnd=true,
sessionBegin=09:30:00.000 13:00:00.000, sessionEnd=11:30:00.000 14:57:00.000, roundTime=false)
subscribeTable(tableName="trades", actionName="engine1", offset=0,
handler=append!{engine1}, msgAsTable=true);
// 模拟数据插入流表。
// 最后一条数据时间是 14:56:00,按照一分钟规则进行规整,则该条数据将输出到 14:57:00 的窗口中
insert into trades values(2024.09.10,14:00:10.988,`A,16)
insert into trades values(2024.09.10,14:00:12.458,`B,9)
insert into trades values(2024.09.10,14:21:10.772,`A,13)
insert into trades values(2024.09.10,14:22:12.090,`B,15)
insert into trades values(2024.09.10,14:29:56.953,`A,20)
insert into trades values(2024.09.10,14:29:58.537,`B,20)
insert into trades values(2024.09.10,14:31:00.612,`A,10)
insert into trades values(2024.09.10,14:56:00.000,`B,29)
sleep(1000)
select * from output1
timestamp
sym
sumVolume
2024.09.10T14:10:00.000
A
16
2024.09.10T14:10:00.000
B
9
2024.09.10T14:30:00.000
A
33
2024.09.10T14:30:00.000
B
35
2024.09.10T14:40:00.000
A
10
2024.09.10T14:57:00.000
B
29
例4.
设置
keyPurgeDaily
=false, 则在收到第一批日期是 2024.09.11 的数据时,引擎不会清空日期是 2024.09.10
的分组数据。
share streamTable(1000:0, `date`second`sym`volume, [DATE, SECOND, SYMBOL, INT]) as trades
share table(10000:0, `time`sym`sumVolume, [DATETIME, SYMBOL, INT]) as output1
engine1 = createDailyTimeSeriesEngine(name="engine1", windowSize=30*60, step=30*60, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output1, timeColumn=`date`second, useSystemTime=false, keyColumn=`sym, garbageSize=50, useWindowStartTime=false, sessionBegin=09:30:00 13:00:00, sessionEnd=11:30:00 15:00:00,mergeSessionEnd=true, keyPurgeDaily=false, fill="null", forceTriggerTime=60)
insert into engine1 values(2024.09.10,13:00:10,`A,16)
insert into engine1 values(2024.09.10,13:00:12,`B,9)
insert into engine1 values(2024.09.10,13:00:12,`C,9)
insert into engine1 values(2024.09.10,14:59:56,`A,20)
insert into engine1 values(2024.09.10,14:59:58,`B,20)
insert into engine1 values(2024.09.10,15:00:00,`A,10)
insert into engine1 values(2024.09.10,15:00:00,`B,29)
insert into engine1 values(2024.09.11,09:30:02,`A,26)
insert into engine1 values(2024.09.11,09:30:10,`B,14)
insert into engine1 values(2024.09.11,10:30:46,`A,30)
insert into engine1 values(2024.09.11,10:30:50,`B,11)
select * from output1
time
sym
sumVolume
2024.09.10T13:30:00
A
16
2024.09.10T13:30:00
B
9
2024.09.10T13:30:00
C
9
2024.09.10T14:00:00
A
11
2024.09.10T14:00:00
B
30
2024.09.10T14:00:00
C
13
2024.09.10T14:30:00
A
20
2024.09.10T14:30:00
B
20
2024.09.10T14:30:00
C
10
2024.09.10T15:00:00
A
30
2024.09.10T15:00:00
B
49
2024.09.10T15:00:00
C
2024.09.11T10:00:00
A
26
2024.09.11T10:00:00
B
14
2024.09.11T10:00:00
C
2024.09.11T10:30:00
A
从上表的结果可以看出,2024.09.11 的数据中未包含 C 分组,但由于引擎未删除 2024.09.10 中的 C 分组,因此填充结果中仍然出现了 C 分组。
例5. 将第二个 session 的时间调整为 13:00:00~15:00:30,并设置
mergeLastWindow
为 true。session
的起止时间将不进行规整,最后一个不完整的窗口 [15:00:00, 15:00:30) 的数据与前一个窗口 [14:59:00, 15:00:00)一同计算,合并为一个
[14:59:00,15:00:30)
窗口输出。
dropStreamEngine("engine1")
unsubscribeTable(tableName="trades", actionName="engine1")
undef(`trades, SHARED)
undef(`output1,SHARED)
share streamTable(1000:0, `date`second`sym`volume, [DATE, SECOND, SYMBOL, INT]) as trades
share keyedTable(`time`sym, 10000:0, `time`sym`sumVolume, [DATETIME, SYMBOL, INT]) as output1
engine1 = createDailyTimeSeriesEngine(name="engine1", windowSize=60, step=60, timeColumn=`date`second,
metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output1,
useSystemTime=false, keyColumn=`sym, garbageSize=50,
useWindowStartTime=false, sessionBegin=09:00:00 13:00:00,
sessionEnd=11:30:00 15:00:30, roundTime=false, mergeLastWindow=true)
subscribeTable(tableName="trades", actionName="engine1", offset=0,
handler=append!{engine1}, msgAsTable=true);
insert into trades values(2018.10.08,13:00:10,`A,16)
insert into trades values(2018.10.08,13:00:12,`B,9)
insert into trades values(2018.10.08,14:29:56,`A,20)
insert into trades values(2018.10.08,14:29:58,`B,20)
insert into trades values(2018.10.08,14:31:00,`A,10)
insert into trades values(2018.10.08,14:55:00,`B,29)
insert into trades values(2018.10.08,14:56:00,`B,29)
insert into trades values(2018.10.08,14:57:01,`A,29)
insert into trades values(2018.10.08,14:57:01,`B,29)
insert into trades values(2018.10.08,14:59:01,`B,29)
insert into trades values(2018.10.08,14:59:01,`A,29)
insert into trades values(2018.10.08,15:00:01,`B,29)
insert into trades values(2018.10.08,15:00:01,`A,29)
insert into trades values(2018.10.08,15:00:31,`B,29)
insert into trades values(2018.10.08,15:00:31,`A,29)
sleep(2000)
select * from output1
Time
Symbol
Sum Volume
2018.10.08T13:01:00
A
16
2018.10.08T13:01:00
B
9
2018.10.08T14:30:00
A
20
2018.10.08T14:30:00
B
20
2018.10.08T14:56:00
B
29
2018.10.08T14:32:00
A
10
2018.10.08T14:57:00
B
29
2018.10.08T14:58:00
A
29
2018.10.08T14:58:00
B
29
2018.10.08T15:00:30
A
58
2018.10.08T15:00:30
B
58
FILE:references/doc_6687.md
# dropFunctionView
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropFunctionView.html
**来源**: DolphinDB 官方文档
---
dropFunctionView
语法
dropFunctionView(name
,
[isNamespace=false]
)
详情
删除一个视图
或一个命名空间下的所有函数
。
dropFunctionView
只能由管理员或拥有 VIEW_OWNER
权限的普通用户执行。
参数
name
是一个字符串标量,表示用户自定义函数名称
或一个命名空间。
isNamespace
是一个布尔标量,指示 name 是否是一个命名空间。
返回值
无。
例子
getFunctionViews()
name body
--------- ------------------
f1
def
f1(){
return
1
}
test::f1
def
f1(){
return
2
}
test::f2
def
f2(){
return
3
}
// 删除 f1
dropFunctionView(`f1)
// 删除 test::f1
dropFunctionView(
"test::f1"
)
// 删除命名空间 test 下所有函数
dropFunctionView(
"test"
,true)
FILE:references/doc_670.md
# declareStreamingSQLTable
**URL**: https://docs.dolphindb.cn/zh/funcs/d/declareStreamingSQLTable.html
**来源**: DolphinDB 官方文档
---
declareStreamingSQLTable
语法
declareStreamingSQLTable(table)
详情
将指定表声明为流式 SQL 的输入表。仅被声明的表才能通过
registerStreamingSQL
注册流式 SQL
查询。该声明操作不会影响该表在普通 SQL 查询或其他功能中的使用。
参数
table
表对象,目前仅支持共享内存表,包括通过
share
共享的普通内存表、键值内存表、索引内存表。
返回值
无
例子
t=table(1..10 as id,rand(100,10) as val)
share t as st
declareStreamingSQLTable(st)
registerStreamingSQL("select avg(val) from st")
相关函数:
listStreamingSQLTables
,
registerStreamingSQL
,
revokeStreamingSQLTable
FILE:references/doc_671.md
# isControllerInitialized
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isControllerInitialized.html
**来源**: DolphinDB 官方文档
---
isControllerInitialized
语法
isControllerInitialized()
详情
查看控制节点是否启动完成。若启动完成返回 true,否则返回 false。普通集群环境下,仅在控制节点调用;高可用集群环境下,仅在
leader 节点调用。
返回值
布尔标量。
例子
isControllerInitialized()
// output: true
相关函数:
isDataNodeInitialized
FILE:references/doc_6711.md
# randomForestRegressor
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randomForestRegressor.html
**来源**: DolphinDB 官方文档
---
randomForestRegressor
语法
randomForestRegressor(ds, yColName, xColNames,
[maxFeatures=0], [numTrees=10], [numBins=32], [maxDepth=32],
[minImpurityDecrease=0.0], [numJobs=-1], [randomSeed])
详情
计算指定数据源中
yColName
和
xColNames
随机森林回归。
生成的模型可以作为
predict
函数的输入。
参数
ds
是数据源,通常用
sqlDS
函数生成。
yColName
是字符串,表示数据源中作为因变量的列名
xColNames
是字符串标量或向量,表示数据源中作为自变量的列名。
maxFeatures
是一个整数或浮点数,表示一次分裂节点选取的特征个数或比例。默认值是0。
如果
maxFeatures
为正整数,则在一次分裂时选取
maxFeatures
个特征。
如果
maxFeatures
=0,则在一次分裂时选取 sqrt(特征列数量)
个特征。
如果
maxFeatures
是一个0和1之间的浮点数,则在一次分裂时选取
int(特征列数量*maxFeatures) 个特征
numTrees
是正整数,表示森林中树的个数。默认值为10。
numBins
是正整数,表示离散化连续特征时的桶数。默认值为32。增加
numBins
会使算法考虑更多的分裂结点的决策值,产生更好的分裂结果,但也会提高计算量和通讯量。
maxDepth
是正整数,表示树的最大深度。默认值为32。
minImpurityDecrease
是浮点数,如果分裂产生的纯度减少值大于或等于这个值,结点会继续分裂。纯度用方差来计算。默认值是0。
numJobs
是一个整数,表示训练时使用的任务数。它是可选参数,默认值为-1,表示训练时使用所有的线程。如果
numJobs
小于-1,假如设置的 localExecutor 参数为 n,产生的任务数为
(n+2+numJobs)。实际执行过程中,最多会产生 min(numTrees, n+1) 个任务。如果
ds
中有数据源位于远程节点,该参数不起作用,只产生一个任务。
randomSeed
是随机数生成器使用的种子。
返回值
返回结果是字典,包含以下 key:minImpurityDecrease, maxDepth, numBins, numTress, maxFeatures,
model, modelName, xColNames。其中 model 是一个元组,保存了训练生成的树;modelName 为 “Random Forest
Regressor”。
例子
用模拟数据训练一个随机森林回归模型
x1 = rand(100.0, 100)
x2 = rand(100.0, 100)
b0 = 6
b1 = 1
b2 = -2
err = norm(0, 10, 100)
y = b0 + b1 * x1 + b2 * x2 + err
t = table(x1, x2, y)
model = randomForestRegressor(sqlDS(<select * from t>), `y, `x1`x2)
yhat=predict(model, t);
plot(y, yhat, ,SCATTER);
保存模型到磁盘
saveModel(model, "C:/DolphinDB/Data/regressionModel.bin")
加载一个保存的模型
loadModel("C:/DolphinDB/Data/regressionModel.bin")
相关函数:
adaBoostClassifier
,
randomForestClassifier
FILE:references/doc_6718.md
# disableResourceTracking
**URL**: https://docs.dolphindb.cn/zh/funcs/d/disableresourcetracking.html
**来源**: DolphinDB 官方文档
---
disableResourceTracking
语法
disableResourceTracking()
详情
在线关闭资源跟踪。仅当 resourceSamplingInterval 设置为正整数时才能调用该函数。该函数仅限管理员在数据节点上调用。
注:
资源跟踪开启和关闭不会影响日志回收。
参数
无。
返回值
无。
相关函数
:
enableResourceTracking
FILE:references/doc_6727.md
# date
**URL**: https://docs.dolphindb.cn/zh/funcs/d/date.html
**来源**: DolphinDB 官方文档
---
date
语法
date(X)
详情
返回对应的日期。返回值的类型是 DATE,一个时间值。如果参数
X
不是日期,则返回值是 1970.01.01 +
X
天的日期。
参数
X
可以是时间标量、向量或整数。
例子
date();
返回:null
date(1)
返回:1970.01.02
date(`2011.10.12);
返回:2011.10.12
date(now());
返回:2024.02.22
date 2012.12.03 01:22:01;
返回:2012.12.03
date(2016.03M);
返回:2016.03.01
FILE:references/doc_6735.md
# temporalDiff
**URL**: https://docs.dolphindb.cn/zh/funcs/t/temporalDiff.html
**来源**: DolphinDB 官方文档
---
temporalDiff
别名:datetimeDiff
语法
temporalDiff(X, Y, [unit])
详情
temporalDiff
函数计算
X
和
Y
之间的时间差。
当提供
unit
参数时,时间差的计算将基于指定的时间单位(天、工作日或特定交易所的交易日)。
参数
X
是一个时间类型的标量、向量、矩阵,或包含时间类型列的表。
Y
是一个标量,或和
X
相同长度的向量、维度相同的矩阵或表。其类型必须与
X
严格相同。
unit
可选参数,是一个字符串标量,指定时间单位。取值可以是:
"d" 表示自然日
"B" 表示工作日
一个交易日历标识,例如 "XNYS",对应的交易日历文件必须保存在
marketHolidayDir
配置项指定的目录中。
注:
若指定
unit
,
X
和
Y
必须是 DATE 类型。
返回值
返回与
X
形状相同的标量/向量/矩阵/表。
例子
timestamps = [13:30:49,13:30:39,13:30:50,13:30:57,13:30:35]
temporalDiff(timestamps, 13:30:00)
// Output: [49,39,50,57,35]
若指定
unit
参数,
X
和
Y
必须为日期(DATE)类型:
dates = [2019.12.31, 2020.01.03, 2020.01.10, 2020.01.15, 2020.01.17]
temporalDiff(dates, 2019.12.30, "d") // Output: [1,4,11,16,18]
temporalDiff(dates, 2019.12.30, "B") // Output: [1,4,9,12,14]
temporalDiff(dates, 2019.12.30, "XNYS") // Output: [1,3,8,11,13]
FILE:references/doc_6738.md
# intersection
**URL**: https://docs.dolphindb.cn/zh/funcs/i/intersection.html
**来源**: DolphinDB 官方文档
---
intersection
语法
intersection(X, Y)
或
X&Y
详情
若
X
和
Y
均为集合,返回其交集。
若
X
和
Y
是相同长度的整形向量或标量,返回位运算
AND
的结果。
参数
X
和
Y
均为集合,或是相同长度的整型向量或标量。
返回值
集合、整型向量或标量。
例子
x=set([5,5,3,4,6])
y=set(8 9 4 4 6)
x & y;
// output: set(4,6)
6 7 8 & 4 5 6;
// output
[4,5,0]
FILE:references/doc_6744.md
# replace!
**URL**: https://docs.dolphindb.cn/zh/funcs/r/replace_.html
**来源**: DolphinDB 官方文档
---
replace!
是
replace
的别名。
FILE:references/doc_6754.md
# mod
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mod.html
**来源**: DolphinDB 官方文档
---
mod
语法
mod(X, Y)
详情
mod
表示取模运算。它返回
X
和
Y
逐个元素相除得到的余数。
当
Y
是正整数时,结果总是非负的,例如,-10%3 的结果是 2;
当
Y
是负整数时,结果总是非正的,例如,-10%-3 的结果是 -1。
mod
函数常用于数据分组。比如,[5,4,3,3,5,6]%3 是 [2,1,0,0,2,0],于是数据被分成了三组。
参数
X
和
Y
可以是标量、数据对、向量或矩阵。如果
X
或
Y
的其中一个是数据对、向量或矩阵,另一个必须是具有相同长度或维度的数据对、向量或矩阵。
返回值
当
X
和
Y
都是标量时,返回一个整型标量。
当
X
或
Y
是向量时,返回一个整型向量。
当输入是矩阵时,返回一个整型矩阵。
例子
x=1 2 3;
x % 2;
// output: [1,0,1]
2 % x;
// output: [0,0,2]
y=4 5 6;
x mod y;
// output: [1,2,3]
mod(y, x);
// output: [0,1,0]
m=1..6$2:3;
m;
#0
#1
#2
1
3
5
2
4
6
m mod 3;
#0
#1
#2
1
0
2
2
1
0
x=-1 2 3;
x%-5;
// output: [-1,-3,-2]
-1%5;
// output: 4
FILE:references/doc_6760.md
# interval
**URL**: https://docs.dolphindb.cn/zh/progr/sql/interval.html
**来源**: DolphinDB 官方文档
---
interval
语法
interval(X, duration, fill, [step], [explicitOffset=false], [closed],
[label], [origin])
详情
在 SQL 语句中,构建涵盖
X
所有数据的连续窗口以进行计算,其中每个窗口长度为
duration
。对无数据的组,根据
fill
参数指定的方式填充缺失的计算结果。该函数只能在 SQL 的 group by 子句中使用,以实现插值查询,不能单独使用。
注:
若SQL语句中指定where子句,条件中的时间类型支持自动转换。
参数
X
是一个向量,必须是整数或者时间类型。
duration
是一个整数或者 DURATION 类型。
duration
支持的时间单位(区分大小写):w, d, H, m, s, ms, us, ns 和由四个大写英文字母构成的交易日历标识(对应的文件必须保存在
marketHolidayDir
中)。
对
X
以年进行分组时,需要调用
year
对
X
进行转换。
fill
是计算结果缺失值的填充方式,可取值为:'prev', 'post', 'linear', 'null', 'none'
和一个数字。
'prev':使用前一个值填充。
'post':使用后一个值填充。
'linear':使用线性插值填充。对于非数值列,无法使用线性插值填充,这种情况下会使用 "prev" 的方式填充。
'null':使用 null 值填充。
'none':表示不进行插值。
一个数字:以该值填充。
step
是可选参数,是一个整数或者 DURATION 类型,表示计算窗口每次向前滑动的步长,必须为一个可以整除
duration
的数。 通过
step
可以指定一个比
duration
更小的滑动步长。默认与
duration
设置值相同,即计算窗口以
duration
的步长滑动。
注意
:
指定
step
后,不支持以下聚合计算:atImax, atImin, difference, imax, imin,
lastNot, mode, percentile。
当
step
与
duration
的值不同时,在查询分区表时,不支持对查询列应用自定义聚合函数。
explicitOffset
是可选参数,是一个布尔值,表示第一个插值窗口起点是否为 where 条件指定的起始值。
closed
字符串,表示分组区间哪一个边界是闭合的。可取值为 'left' 或 'right'。
label
字符串,表示将分组区间的哪一个边界作为 label 输出。可取值为 'left' 或 'right'。
origin
字符串或与 X 具有相同时间类型的标量,表示基于时间戳调整分组。origin 为字符串时,可取以下值:
'epoch':分组起始点为1970-01-01。
'start':分组起始点为时间序列的第一个值。
'start_day':分组起始点是时间序列的第一个值对应日期的午夜零点。
'end':分组起始点是时间序列的最后一个时间戳。
'end_day':分组起始点是时间序列的最后一个时间戳对应日期的午夜24点(即下一日的零点)。
注:
若设置 explicitOffset = true,则不能设置 origin。
注:从 2.00.2 版本开始,取消了
range
参数。
下图以
duration
= 2 *
step
为例,进一步解释插值窗口如何进行滑动计算(结果为 NULL 的窗口需要根据
fill
参数指定的方式进行填充):
下图解释了
explicitOffset
不同设置下,插值起始窗口如何确定。图中 where 条件指定起始值为 t1,t1 前最近的一个能被
step
整除的值为 t0,当
explicitOffset
设置为 true 时,插值起始窗口以 t1 开始,当
explicitOffset
设置为 false 时,插值起始窗口以 t0 开始。
例子
使用前一个值填充:
timestampv = temporalAdd(2012.01.01T00:00:00.000, 0..11 join 15..20 , "s")
a1v = [3,2.5,1.7,1.1,1.8,2.1,1.1,1.4,1.9,2.4,2.9,2.6,1.1,2.7,1.1,2.9,1.9,1.7]
t = table(timestampv as timestamp, a1v as a1)
select max(a1) from t group by interval(timestamp, 3s, "prev")
interval_timestamp
max_a1
2012.01.01T00:00:00.000
3
2012.01.01T00:00:03.000
2.1
2012.01.01T00:00:06.000
1.9
2012.01.01T00:00:09.000
2.9
2012.01.01T00:00:12.000
2.9
2012.01.01T00:00:15.000
2.7
2012.01.01T00:00:18.000
2.9
使用指定数字填充:
select max(a1) from t group by interval(timestamp, 3s, 100)
interval_timestamp
max_a1
2012.01.01T00:00:00.000
3
2012.01.01T00:00:03.000
2.1
2012.01.01T00:00:06.000
1.9
2012.01.01T00:00:09.000
2.9
2012.01.01T00:00:12.000
100
2012.01.01T00:00:15.000
2.7
2012.01.01T00:00:18.000
2.9
下例中,以 2 年进行分组,需要将
X
的单位进行转换:
t=table([2016.10.12T00:00:00.500,2017.10.12T00:00:03.000,2018.10.12T00:00:03.000,2019.10.12T00:00:08.000,2020.10.12T00:00:08.000,2021.10.12T00:00:08.000] as time, [7,9,NULL,NULL,8,6] as price)
select max(price) from t group by interval(X=year(time), duration=2, fill="prev")
interval
max_price
2016
9
2018
9
2020
8
下例说明
explicitOffset
不同设置下,第一个窗口起始时间的显示值。
symbol = `A`A`A`A`A`A`A`A`B`B`B`B
price= [29.55,29.74,29.51,29.54,29.79,29.81,29.50,29.56,29.41,29.49,29.83,29.76]
volume = [2200,1900,2100,3200,8800,5800,4300,9300,7900,9100,7300,6500]
tradeTime = [09:33:56,09:33:59,09:34:08,09:34:16,09:34:51,09:34:59,09:35:47,09:35:26,09:35:36,09:36:26,09:37:12,10:00:00]
t = table(tradeTime, symbol, volume, price)
//explicitOffset设置为true时,起始窗口以where指定的起始值09:33:50开始。
select max(price) as max_price, min(price) as min_price from t where tradeTime between 09:33:50:09:35:00 group by symbol, interval(X=tradeTime, duration=30, fill="post", explicitOffset=true) as tradeTime
symbol
tradeTime
max_price
min_price
A
09:33:50
29.74
29.51
A
09:34:20
29.81
29.79
A
09:34:50
29.81
29.79
explicitOffset
设置为 false,第一个窗口的起始时间为 09:33:30,即 where
指定的起始时间(09:33:50)前第一个可以被
step
整除的时间点。本例中没有设置
step
,它的取值与
duration
一样,第一个窗口起始时间计算方式为:second(09:33:50/30*30)。
select max(price) as max_price, min(price) as min_price from t where tradeTime between 09:33:50:09:35:00 group by symbol, interval(X=tradeTime, duration=30,fill="prev",explicitOffset=false) as tradeTime
symbol
tradeTime
max_price
min_price
A
09:33:30
29.74
29.55
A
09:34:00
29.54
29.51
A
09:34:30
29.81
29.79
A
09:35:00
29.81
29.79
下例指定
step
为 20s,计算窗口长度为 60s,每 20s 向前滑动一次,进行计算。
select max(price) as max_price, min(price) as min_price from t where tradeTime between 09:33:50:09:35:00 group by symbol, interval(X=tradeTime, duration=60, fill=0, step=20, explicitOffset=false) as tradeTime
symbol
tradeTime
max_price
min_price
A
09:33:40
29.74
29.51
A
09:34:00
29.81
29.51
A
09:34:20
29.81
29.79
A
09:34:40
29.81
29.79
A
09:35:00
0.00
0.00
下例以自定义交易日历 ADDA 的 2 个交易日进行分组
// 自定义交易日历 ADDA,其假期为 2024.01.02 和 2024.01.03
holiday = [2024.01.02, 2024.01.03]
addMarketHoliday("ADDA", holiday)
// 创建待查询表
n = 6
dates=[2023.12.30, 2024.01.02, 2024.01.03, 2024.01.05, 2024.01.07, 2024.01.09]
name = take(`A`B`S`C`F, n)
a1 = take(double(1..3),n)
t=table(dates as date, name as name, a1 as a1)
//计算 ADDA 每两个交易日中 “a1” 的最大值。
select max(a1) from t group by interval(X=date, duration=2ADDA, fill="null", label="right", origin="start")
FILE:references/doc_6762.md
# md5
**URL**: https://docs.dolphindb.cn/zh/funcs/m/md5.html
**来源**: DolphinDB 官方文档
---
md5
语法
md5(X)
详情
根据 MD5 算法,对字符串进行哈希,生成 INT128 类型的数据。
参数
X
是一个字符串标量或向量。
返回值
INT128 类型标量或向量。
例子
a=md5(`e`f);
a;
// output: [e1671797c52e15f763380b45e841ec32,8fa14cdd754f91cc6554c9e71929cce7]
typestr(a);
// output: INT128
FILE:references/doc_6767.md
# create
**URL**: https://docs.dolphindb.cn/zh/progr/sql/create.html
**来源**: DolphinDB 官方文档
---
create
create 语句用于创建数据库或者数据表。其语法如下:
自 3.00.0 版本起,支持创建 catalog 中的数据库或者数据表。
创建分布式数据库
该语句只支持创建分布式数据库。
create database directory partitioned by partitionType(partitionScheme),[partitionType(partitionScheme),partitionType(partitionScheme)],
[engine='OLAP'], [atomic='TRANS'], [chunkGranularity='TABLE']
在 create database 语句中,'partitionType' 的个数表示分区的层级,最少1个,最多3个。当指定多个
'partitionType' 时,表示组合分区。其它参数详情请参考函数
database
。
自 3.00.0 版本起,支持创建
catalog
中的数据库。使用
catalog.schema
代替上述语句中的
directory
。
createCatalog("catalog")
go
create database catalog.schema partitioned by partitionType(partitionScheme),[partitionType(partitionScheme),partitionType(partitionScheme)],
[engine='OLAP'], [atomic='TRANS'], [chunkGranularity='TABLE']
若已设置当前的默认 catalog,则可忽略 catalog 前缀,直接传入
schema。
use catalog catalog1 //如设置当前默认catalog为catalog1
create database test partitioned by partitionType(partitionScheme),[partitionType(partitionScheme),partitionType(partitionScheme)],
[engine='OLAP'], [atomic='TRANS'], [chunkGranularity='TABLE']
创建数据表
该语句只支持创建普通内存表和分布式表。
语法
create table dbPath.tableName (
schema[columnDescription]
)
[partitioned by partitionColumns]
,
[sortColumns],
[keepDuplicates=ALL],
[sortKeyMappingFunction]
[softDelete=false]
[comment],
[encryptMode='plaintext']
参数
dbPath
字符串,表示数据库的路径。创建内存表时,可以不指定该参数。
tableName
可以为表示表名的字符串,或者表示表对象的变量。
schema
表结构,包含两列:
columnName
和
columnType
。
columnDescription
为列字段添加描述,以 keywords
方式进行添加。可包含以下两项:
comment
为列字段添加注释;
compress
指定压缩方式,包含以下4种方式:
"lz4"
"delta"
"zstd"
"chimp"
partitionColumns
分区列或应用于分区列的函数调用(例如:partitionFunc(id))。对于组合分区,
partitionColumns
依次指定多个分区列。
softDelete
用于启用或禁用软删除功能。默认为
false,即禁用。该参数适于在行数多但删除量小的场景下使用。使用该参数需要同时满足以下条件:
由TSDB 存储引擎创建的数据库内的表。
keepDuplicates
已设置为 LAST。
comment
字符串标量,用于设置表注释。
TSDB 引擎参数:
sortColumns
TSDB
引擎必选参数,字符串标量或向量,用于指定每一分区内的排序列。
keepDuplicates
指定在每个分区内如何处理所有
sortColumns
之值皆相同的数据,默认值为 ALL。提供以下选项:
ALL:保留所有数据
LAST:仅保留最新数据
FIRST:仅保留第一条数据
sortKeyMappingFunction
由一元函数对象组成的向量,其长度与索引列一致,即
sortColumns
的长度 - 1,若只指定一个映射函数 mapfunc,必须写为
sortKeyMappingFunction
=[mapfunc]。用于指定应用在索引列中各列的映射函数,以减少 sort key
的组合数,该过程称为 sort key 降维。
索引列中的各列被对应的映射函数降维后,原本的多个 sort key 组合值会被重新映射到一个新的
sort key 组合值上。而每个新 sort key 组合值对应的数据仍将根据
sortColumns
的最后一列进行排序。降维在写入磁盘时进行,因此指定该参数一定程度上将影响写入性能。
注:
创建维度表时,不可指定该参数。
sortKeyMappingFunction
指定的函数对象与索引列中的各列一一对应,若其中某列无需降维,则函数对象置为空。
当
sortKeyMappingFunction
中的函数对象为 hashBucket,且需要对采用 Hash
分区的分区字段进行降维时,应确保 Hash 分区的数量和 hashBucket 中的 buckets
之间不存在整除关系,否则会导致同一分区内的所有 Hash 值得到的 key 都相同。
indexes
为一个字典,用于为表中的列指定索引。仅当
dbHandle
指示的数据库采用 “TSDB”
或 “PKEY” 引擎
(engine=”TSDB”
或 engine=”PKEY”
)时,本参数才生效。
当引擎为 TSDB 时,用于为某一列设置向量索引,以便在查询时对该列进行高效的欧氏距离计算。目前,每个表仅支持为单个列设置向量索引。字典的键为 STRING
类型,表示列名,且该列的类型必须为 FLOAT[];字典的 value 为 STRING 类型,其形式为
"vectorindex(type=flat, dim=128)"
,其中:
type 可选值为 Flat, PQ, IVF, IVFPQ, HNSW:
Flat 适用于数据规模在数百至数万级别的向量数据,或需要最高精度的场景。
PQ 适用于数据规模在数十万至数千万级别的向量数据,且对搜索精度要求不高的场景。常见应用场景如大型数据库、视频库等。
IVF 适用于数据规模在数万至数百万级别的向量数据,常见应用场景如图片检索、文本检索等。
IVFPQ
适用于数据规模在数百万至数千万级别的向量数据,需要在检索速度和精度之间找到最佳平衡的场景。常见应用场景如大型推荐系统、社交网络中的用户匹配。
HNSW
适用于数据规模在数亿至数十亿级别的向量数据,并对检索速度,精度和动态更新有高要求的场景,常见应用场景如实时推荐系统、在线搜索、RAG等。
encryptMode
字符串标量,指定表的加密方式,默认为不加密(明文模式)。目前支持以下可选值(大小写不区分):plaintext,
aes_128_ctr, aes_128_cbc, aes_128_ecb, aes_192_ctr, aes_192_cbc, aes_192_ecb,
aes_256_ctr, aes_256_cbc, aes_256_ecb, sm4_128_cbc, sm4_128_ecb
dim 为属于 [1,n] 的整数,表示向量的维度。后续插入的向量维度必须为 d,否则会插入失败。若
type
指定为 PQ 或 IVFPQ,则要求
dim 为 4 的倍数。
如果已为某一列设置了向量索引,在查询语句中,若同时满足以下条件:不包含 join 语句,where 子句中不包含 sort key, 包含 order by
子句且其中只包含对该列应用 rowEuclidean 函数并按升序排序,包含 limit 子句,则会应用向量索引提升查询性能。
create table 语句内的参数和详情说明请参考相关函数
createPartitionedTable
/
createDimensionTable
。
创建catalog 中的数据表
自 3.00.0 版本起,支持创建 catalog 中的数据表。使用
catalog.schema
代替上述语句中的
dbPath
。
create table catalog.schema.tableName(
schema[columnDescription]
)
[partitioned by partitionColumns],
[sortColumns],
[keepDuplicates=ALL],
[sortKeyMappingFunction]
若已设置当前的默认 catalog,则可忽略 catalog 前缀,直接传入
schema
。
use catalog catalog1 //如设置当前默认catalog为catalog1
create table schema.tableName(
schema[columnDescription]
)
[partitioned by partitionColumns],
[sortColumns],
[keepDuplicates=ALL],
[sortKeyMappingFunction]
创建临时内存表
通过在
create
后添加关键字 local temporary
(不区分大小写)以声明创建一张本地临时内存表。语法如下:
create local temporary table tableName(
schema
) [on commit preserve rows]
其中:
tableName
表示表名的字符串,或者表示表对象的变量。
schema
表结构声明,包含两列:
columnName
和
columnType
。
on commit preserve rows
为可选关键字,不区分大小写,用于声明该表为会话级临时表。
注:
DolphinDB
create table
语句创建的内存表即为本地临时表且仅对当前会话有效,因此该语句和
create table
语句等价。
系统暂不支持创建全局临时内存表及
on commit delete
rows
关键字。
创建点位管理表
点位管理表的相关概念请参阅
物联网点位管理引擎
。在使用 create
语句创建点位管理表时,通过创建一个 IOTANY 类型的列或开启最新值缓存功能(
latestKeyCache
)以建立点位管理表。使用前须保证库表已指定
IOTDB 引擎。
相关参数:
latestKeyCache
可选参数,布尔标量,用于设置是否开启最新值缓存功能。默认值为 false,即关闭。支持分区表、流数据表和共享内存表。
compressHashSortKey
可选参数,布尔标量,用于设置是否开启 sortColumns 列压缩功能。当 engine 为 IOTDB
时,默认值为 true。注意:只支持分区表。
注意:
当创建点位管理表时,数据库的 engine 必须为 IOTDB。
当 engine 为 IOTDB 的数据库中只能包含点位管理表,不能有非点位管理表,如正常的分区表,维度表等。
最多可以创建一个 IOTANY 列。不能单独建一个该类型的向量或表。
物联网点位管理引擎规定
将唯一标识一组点位的多个列(一般为 ID 列+各种 tag 列)+时间列
设置为sortColumns。当设置
latestKeyCache=true 时,sortColumns 里至少需要两列。
IOTANY 列是可选操作。即支持仅开启最新值缓存功能,但表中无 IOTANY 列。但若表中包含 IOTANY 列则必须指定
latestKeyCache=true。
建立点位管理表时,数据库分区方案必须为复合分区、必须存在一个时间分区,且时间分区位于最后一个维度。
当使用点位管理表、开启 sortColumns 列压缩功能,且 sortColumns 大于 2 列时,支持开启对 sortKey 列使用静态表 ID
压缩。这样在 sortColumns 列特别多的情况下能节约磁盘空间占用,但会使查询性能下降
。该参数
compressHashSortKey
当 engine 为 IOTDB 时,默认值为
true。
例子
例1. 创建内存表
create table tb(
id SYMBOL,
val DOUBLE
)
go; //必须使用 go 语句使上面的代码先解析执行,否则会报不识别变量 tb 的错误
tb.schema()
partitionColumnIndex->-1
chunkPath->
colDefs->
name typeString typeInt comment
---- ---------- ------- -------
id SYMBOL 17
val DOUBLE 16
例2. 创建 TSDB 引擎下的分布式数据库
if(existsDatabase("dfs://test")) dropDatabase("dfs://test")
create database "dfs://test" partitioned by VALUE(1..10), HASH([SYMBOL, 40]), engine='TSDB'
TSDB 引擎下的分布式表
create table "dfs://test"."pt"(
id INT,
deviceId SYMBOL,
date DATE[comment="time_col", compress="delta"],
value DOUBLE,
isFin BOOL
)
partitioned by ID, deviceID,
sortColumns=[`deviceId, `date],
keepDuplicates=ALL
pt = loadTable("dfs://test","pt")
pt.schema()
// output
engineType->TSDB
keepDuplicates->ALL
partitionColumnIndex->[0,1]
colDefs->
name typeString typeInt extra comment
-------- ---------- ------- ----- --------
id INT 4
deviceId SYMBOL 17
date DATE 6 time_col
value DOUBLE 16
isFin BOOL 1
partitionType->[1,5]
partitionColumnName->[id,deviceId]
partitionSchema->([1,2,3,4,5,6,7,8,9,10],40)
partitionSites->
partitionColumnType->[4,17]
partitionTypeName->[VALUE,HASH]
sortColumns->[deviceId,date]
softDelete->false
tableOwner->admin
chunkGranularity->TABLE
chunkPath->
TSDB 引擎下的维度表
create table "dfs://test"."pt1"(
id INT,
deviceId SYMBOL,
date DATE[comment="time_col", compress="delta"],
value DOUBLE,
isFin BOOL
)
sortColumns=[`deviceId, `date]
pt1 = loadTable("dfs://test","pt1")
pt1.schema()
// output
sortColumns->[deviceId,date]
softDelete->false
tableOwner->admin
engineType->TSDB
keepDuplicates->ALL
chunkGranularity->TABLE
chunkPath->
partitionColumnIndex->-1
colDefs->
name typeString typeInt extra comment
-------- ---------- ------- ----- --------
id INT 4
deviceId SYMBOL 17
date DATE 6 time_col
value DOUBLE 16
isFin BOOL 1
例3. 创建 PKEY 引擎下的分布式数据库
if(existsDatabase("dfs://test")) dropDatabase("dfs://test")
create database "dfs://test" partitioned by VALUE(1..10), engine="PKEY"
PKEY 引擎下的分布式表
create table "dfs://test"."pt"(
id INT,
deviceId SYMBOL [indexes="bloomfilter"],
date DATE [comment="time_col", compress="delta"],
value DOUBLE,
isFin BOOL
)
partitioned by ID,
primaryKey=`ID`deviceID
PKEY
引擎下的维度表
create table "dfs://test"."dt"(
id INT,
deviceId SYMBOL [indexes="bloomfilter"],
date DATE [comment="time_col", compress="delta"],
value DOUBLE,
isFin BOOL
)
primaryKey=`ID`deviceID
例4. 创建临时内存表
create local temporary table "tb" (
id SYMBOL,
val DOUBLE
) on commit preserve rows
tb.schema()
partitionColumnIndex->-1
chunkPath->
colDefs->
name typeString typeInt extra comment
---- ---------- ------- ----- -------
id SYMBOL 17
val DOUBLE 16
例5. 创建catalog 中的数据库和数据表
//建catalog
createCatalog("trading")
use catalog trading;
//建库
create database stock partitioned by VALUE(1..10), engine='OLAP'
//建表
create table stock.quote (
id INT,
date DATE[comment="time_col", compress="delta"],
value DOUBLE,
)
partitioned by id
例6. 为分区列指定函数
本例中分区列的数据比较特殊,格式形如 "id_date_id"。在写入数据库时需要调用函数从原始数据中提取日期,并按照日期进行分区。
login(`admin, `123456)
// 首先定义处理分区列数据(形如如"id_date_id")的函数
def myPartitionFunc(str,a,b) {
return temporalParse(substr(str, a, b),"yyyyMMdd")
}
// 分区列数据
data = ["ax1ve_20240101_e37f6", "475b4_20240101_6d9b2", "91f86_20240102_b781d"]
tb = table(data as id_date, 1..3 as value, `a`b`c as sym)
dbName = "dfs://partitonFunc"
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
create database "dfs://partitonFunc" partitioned by VALUE(2024.02.01..2024.02.02), HASH([SYMBOL, 5]), engine='TSDB'
create table "dfs://partitonFunc"."pt"(
date STRING,
value INT,
sym SYMBOL
)
// 采用组合分区方式,partitionColumns 中指定 myPartitionFunc 函数对第一个分区列的数据进行处理
partitioned by myPartitionFunc(date, 6, 8), sym,
sortColumns="sym"
pt = loadTable(dbName,"pt")
pt.append!(tb)
flushTSDBCache()
// 查询数据
select * from pt
date
value
sym
475b4_20240101_6d9b2
2
b
ax1ve_20240101_e37f6
1
a
91f86_20240102_b781d
3
c
例7. 创建点位管理表
本例中,我们通过复合分区方案按 id 和 ts 分区,创建了一个名为 pt 的点位管理表。该表使用 ticket 和 id2
作为唯一识别一个点位的两列;启用最新值缓存,且 value 为 IOTANY 类型,可存储不同类型的测点数据;启用了 hashSortKey
压缩。
dbName = "dfs://db"
if (existsDatabase(dbName)) {
dropDatabase(dbName)
}
// 创建数据库,存储引擎为IOTDB
create database "dfs://db" partitioned by HASH([INT, 20]),VALUE(2017.08.07..2017.08.11), engine='IOTDB'
// 创建点位表,其中 firstSortKey 为 deviceId 和 location,lastSortKey(时间戳列)为 timestamp
create table "dfs://db"."pt" (
deviceId INT,
location SYMBOL,
timestamp TIMESTAMP,
value IOTANY
)
partitioned by deviceId, timestamp,
sortColumns = [`deviceId, `location, `timestamp],
sortKeyMappingFunction = [hashBucket{, 50}, hashBucket{, 50}],
latestKeyCache = true
compressHashSortKey = true
FILE:references/doc_6774.md
# mutualInfo
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mutualInfo.html
**来源**: DolphinDB 官方文档
---
mutualInfo
语法
mutualInfo(X, Y)
别名:
infoGain
详情
计算
X
和
Y
的互信息。
DolphinDB 使用以下公式计算互信息:
若
X
或
Y
是矩阵,计算每列的互信息,返回一个向量。
注:
该公式计算时使用自然对数,若需要
base
为2或者10,直接以结果除以 log 2 或 log
10 即可。
参数
X
是一个标量、向量或矩阵。
Y
是一个标量、向量或矩阵。
X
和
Y
支持 Integral 和 symbol 类型。
返回值
DOUBLE 类型标量或向量。
例子
a = [NULL,4,NULL,NULL,-82,97,NULL,56,5,-92]
b = [NULL,53,NULL,18,97,-4,-73,NULL,NULL,24]
mutualInfo(a, b)
// output: 2.302585
// 计算表中两列数据的互信息
t=table(take(1..10,10000000) as id, rand(10,10000000) as x, rand(10,10000000) as y);
mutualInfo(t.x, t.y)
// output: 0.000004
m1 = 1..12$3:4
m2 = 1..3
mutualInfo(m1, m2)
// output: [1.0986,1.0986,1.0986,1.0986]
如果
X
是矩阵,
Y
可以是标量、向量或者是与
X
行数相同的矩阵。返回结果是与
X
列数相同的向量。
m1 = 1..12$3:4
m2 = 1..3
mutualInfo(m1, m2)
// output: [1.0986,1.0986,1.0986,1.0986]
FILE:references/doc_6784.md
# mstdp
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mstdp.html
**来源**: DolphinDB 官方文档
---
mstdp
语法
mstdp(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
的总体标准差。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
mstdp(1 2 5 4 3, 3);
// output: [,,1.699673171197595,1.247219128924647,0.816496580927726]
mstdp(1 2 5 4 3, 3, 2);
// output: [,0.5,1.699673171197595,1.247219128924647,0.816496580927726]
m=matrix(1 6 2 9 4 5, 11 12 18 23 21 10);
m;
#0
#1
1
11
6
12
2
18
9
23
4
21
5
10
mstdp(m,3);
#0
#1
2.160246899469287
3.091206165165233
2.867441755680875
4.496912521077346
2.943920288775949
2.054804667656331
2.160246899469287
5.715476066494082
m=matrix(1 NULL 4 NULL 8 6 , 9 NULL NULL 10 NULL 2)
m.rename!(date(2020.04.06)+1..6, `col1`col2)
m.setIndexedMatrix!()
mstdp(m,4d)
label
col1
col2
2020.04.07
0
0
2020.04.08
0
0
2020.04.09
1.5
0
2020.04.10
1.5
0.5
2020.04.11
2
0
2020.04.12
1.633
4
mstdp(m,1w)
label
col1
col2
2020.04.07
0
0
2020.04.08
0
0
2020.04.09
1.5
0
2020.04.10
1.5
0.5
2020.04.11
2.8674
0.5
2020.04.12
2.586
3.559
相关函数:
mstd
FILE:references/doc_680.md
# backup
**URL**: https://docs.dolphindb.cn/zh/funcs/b/backup.html
**来源**: DolphinDB 官方文档
---
backup
语法
backup(backupDir, dbPath|sqlObj, [force=false], [parallel=false],
[snapshot=true], [tableName], [partition], [keyPath])
详情
以分区为单位,备份分布式表的数据。返回一个整数,表示备份成功的分区数量。该函数必须要用户登录后才能执行。
注:
若
database
创建数据库时,指定
chunkGranularity
= 'DATABASE',则只能通过 SQL 语句备份数据。
若
backupDir
目录已存在备份文件,则再次向该目录备份数据时,需保证备份方式(
dbPath
或
sqlObj
)一致,否则将备份失败。
若
backupDir
指定为 AWS S3 存储路径,则只能以分区方式备份,即只支持
dbPath
,不支持
sqlObj
。
若
backupDir
指定为 AWS S3 存储路径,需要在数据节点的配置中添加配置项
preloadModules=plugins::awss3
,同时设置
s3AccessKeyId
、
s3SecretAccessKey
和
s3Region
。
参数
backupDir
字符串,表示存放备份数据的目录。如需备份到 AWS S3 存储路径,此参数的值应以
s3://
开头。
dbPath
字符串,表示数据库路径。若指定该参数,以分区为单位拷贝文件进行备份。
sqlObj
SQL 元代码,表示备份的数据。若指定该参数,则仅对 SQL 语句过滤出的数据进行备份。
force
布尔值,表示是否进行全量备份。进行非首次备份时,若
force
=
true,系统将待备份数据全部进行备份;否则仅备份有修改或新增的分区数据。
parallel
布尔值,表示是否对一个数据表下不同分区进行并行备份。默认值为 false。
以下参数仅在指定
dbPath
时有效:
snapshot
布尔值,仅在参数
partition
为空时有效。表示进行非首次备份时,源数据库中若存在被删除的表/分区,是否同步将备份中对应的表/分区删除。 若设置为
true,则备份文件中存在已经被删除的分区或表,会同步进行删除;否则不会删除。
tableName
字符串标量或向量,表示表名。若不指定,表示数据库下的所有表。
partition
表示分区,若不指定,则表示所有分区。有两种指定模式:
指定路径:以 "/" 开头的字符串标量或向量,表示数据库目录下单个或多个分区的路径。请注意对组合分区,路径必须包括所有层次分区。
指定条件:以分区列的一个或多个值作为过滤条件。对于组合分区,
partition
是一个元组,每个元素代表一层分区的过滤条件,如果某层分区不需要过滤,那么相应的过滤条件需置为空。需要注意的是,对于范围分区,需要指定为分区内的一个值。
假如一个组合分区数据库 "dfs://compoDB",一级分区采用值分区:2017.08.07;二级分区采用哈希分区:Key0 和
Key1。分区数据的路径分别为:<HomeDir>/storage/CHUNKS/compoDB/20170807/Key0 和
<HomeDir>/storage/CHUNKS/compoDB/20170807/Key1。若要备份单个分区
20170807/Key0,指定路径时需要设置
partition
= "/20170807/Key0";指定条件时需要设置
partition
= [2017.08.07, 0]。若要备份两个分区 20170807/Key0 和
20170807/Key1,则
partition
指定为 ["/20170807/Key0",
"/20170807/Key1"];指定条件时需要设置
partition
=
[2017.08.07,[0,1]]。
keyPath
字符串标量,指定备份时使用的密钥文件路径。仅 Linux 系统支持该参数。该密钥用于对备份数据进行加密。设置为空即不加密。
返回值
INT 类型标量。
补充说明
备份时指定
dbPath
和
sqlObj
的功能列表:
功能
dbPath
sqlObj
一键备份整库
支持
不支持
数据一致性
保证数据一致性
不完全保证
增量备份
支持同步已修改、新增及删除的分区数据
只支持同步已修改或新增的分区数据,不支持同步已删除的分区数据
断点续传
支持
不支持
灵活语法
不支持
SQL 语句,具有灵活语法,支持备份整张表或仅备份满足查询条件的数据
性能
拷贝文件方式,内存消耗小,速度快
序列化方式,内存消耗大,速度慢
例子
创建一个组合分区的数据库 dfs://compoDB。
n=1000000
ID=rand(100, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x)
dbDate = database(, VALUE, 2017.08.07..2017.08.11)
dbID=database(, RANGE, 0 50 100);
db = database("dfs://compoDB", COMPO, [dbDate, dbID])
pt = db.createPartitionedTable(t, `pt, `date`ID)
pt.append!(t)
例1. 备份表 pt 的所有数据。
backup("/home/DolphinDB/backup",<select * from loadTable("dfs://compoDB","pt")>,true);
// output
10
例2. 备份表 pt 中日期超过2017.08.10的数据。
backup("/home/DolphinDB/backup",<select * from loadTable("dfs://compoDB","pt") where date>2017.08.10>,true);
// output
2
例3. 备份数据库中表数据。
(1) 备份指定表或所有表
// dfs://compoDB 数据库下创建第2张表
pt1 = db.createPartitionedTable(t, `pt1, `date`ID)
pt1.append!(t)
// 同时备份数据库中的两张表
backup(backupDir="/home/DolphinDB/backup",dbPath="dfs://compoDB",force=true);
// output
20
(2) partition 指定分区范围
// 备份数据库中表 pt 的指定的5个分区
partitions=["/20170807/0_50","/20170808/0_50","/20170809/0_50","/20170810/0_50","/20170811/0_50"]
backup(backupDir="/home/DolphinDB/backup",dbPath="dfs://compoDB",force=true,tableName=`pt,partition=partitions);
// output
5
(3) partition 指定过滤条件。请注意,对于范围分区,指定分区范围内的一个值,表示整个分区。
// 备份数据库中表 pt 的一级分区 20170807 内的 50_100 的分区
partitions=[2017.08.07,50]
backup(backupDir="/home/DolphinDB/backup",dbPath="dfs://compoDB",force=true,tableName=`pt,partition=partitions);
// output
1
// 备份数据库中表 pt 的所有一级分区内的 0_50 的分区
partitions=[,[0]]
backup(backupDir="/home/DolphinDB/backup",dbPath="dfs://compoDB",force=true,tableName=`pt,partition=partitions);
// output
5
例4. 通过下例说明
snapshot
参数的作用
// 删除表 pt 中分区"/20170811/0_50"
db.dropPartition("/20170811/0_50",`pt)
//再次备份,指定snapshot=false
backup(backupDir="/home/DolphinDB/backup1",dbPath="dfs://compoDB",force=true,snapshot=false,tableName=`pt);
// output
9
// 从备份中恢复的分区仍包含 /20170811/0_50 这个分区,说明备份文件中并没有删除/20170811/0_50 这个分区
restore(backupDir="/home/DolphinDB/backup1",dbPath="dfs://compoDB",tableName=`pt,partition="%",force=true)
// output
["dfs://compoDB/20170807/0_50/9m9","dfs://compoDB/20170807/50_100/9m9","dfs://compoDB/20170808/0_50/9m9",
"dfs://compoDB/20170808/50_100/9m9","dfs://compoDB/20170809/0_50/9m9","dfs://compoDB/20170809/50_100/9m9",
"dfs://compoDB/20170810/0_50/9m9","dfs://compoDB/20170810/50_100/9m9","dfs://compoDB/20170811/0_50/9m9",
"dfs://compoDB/20170811/50_100/9m9"]
// 再次删除表pt中分区"/20170811/0_50"
db.dropPartition("/20170811/0_50",`pt)
// 再次备份,指定snapshot=true
backup(backupDir="/home/DolphinDB/backup",dbPath="dfs://compoDB",force=true,snapshot=true,tableName=`pt);
// output
9
// 从备份中恢复的分区不包含 /20170811/0_50 这个分区,说明备份文件中删除了/20170811/0_50 这个分区
restore(backupDir="/home/DolphinDB/backup",dbPath="dfs://compoDB",tableName=`pt,partition="%",force=true)
// output
["dfs://compoDB/20170807/0_50/9m9","dfs://compoDB/20170807/50_100/9m9","dfs://compoDB/20170808/0_50/9m9",
"dfs://compoDB/20170808/50_100/9m9","dfs://compoDB/20170809/0_50/9m9","dfs://compoDB/20170809/50_100/9m9",
"dfs://compoDB/20170810/0_50/9m9","dfs://compoDB/20170810/50_100/9m9","dfs://compoDB/20170811/50_100/9m9"]
相关函数:
backupDB
,
backupTable
,
restore
,
migrate
FILE:references/doc_6805.md
# union/union all
**URL**: https://docs.dolphindb.cn/zh/progr/sql/union.html
**来源**: DolphinDB 官方文档
---
union/union all
用于合并两个或多个 select / exec 查询的结果集。union 会将重复的记录删去,union all 保留所有记录。支持在分布式查询中使用。
注意
:
union / union all 连接的 select / exec 语句必须查询相同数量的列,且对应列的类型必须能够相互转换;
第一个查询的列名和类型决定了结果集的列名和列类型。
例子
t1= table(1 2 3 3 as id, 7.8 4.6 5.1 0.1 as v1)
t2 = table(5 3 3 as id, 3.2 5.1 0.1 as v2);
select * from t1 union select * from t2
id
v1
1
7.8
2
4.6
3
5.1
3
0.1
5
3.2
select * from t1 union all select * from t2
id
v1
1
7.8
2
4.6
3
5.1
3
0.1
5
3.2
3
5.1
3
0.1
t3 = table(3 3 4 as id, 5.1 0.2 1.1 as v3);
(select * from t1 where id=3) union all (select * from t2 where id=3) union (select * from t3 where id=3)
id
v1
3
5.1
3
0.1
3
0.2
FILE:references/doc_6811.md
# imaxLast
**URL**: https://docs.dolphindb.cn/zh/funcs/i/imaxlast.html
**来源**: DolphinDB 官方文档
---
imaxLast
语法
imaxLast(X)
详情
若
X
是向量,返回最大值的位置。如果有多个相同的最大值,返回右起第一个最大值的位置。
若
X
为矩阵,计算在每列内部进行,返回一个向量。
若
X
为表,计算在每列内部进行,返回一个表。
参数
X
可以是标量、向量、矩阵或表。
例子
x = 1.2 2 NULL -1 6 -1
imaxLast(x);
// output: 4
m=matrix(3 2 4 4 2, 1 4 2 4 3);
imaxLast(m)
// output: [3,3]
t=table(3 3 2 as c1, 1 4 4 as c2)
imaxLast(t)
/* output:
c1 c2
0 2
*/
相关函数:
imax
FILE:references/doc_6812.md
# tupleSum
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tupleSum.html
**来源**: DolphinDB 官方文档
---
tupleSum
语法
tupleSum(X)
详情
tupleSum
用于从多个
map
调用中总结单个结果。如果每个
map
调用返回了一个包含 N 个非元组对象的元祖,那么
tupleSum
函数的输入将是一个包含 N 个元组对象的元组。每一个子元组包含 m 个拥有相同数据形式和数据类型的对象,m
是
map
函数调用的次数。如果有一个单独的
map
调用,
tupleSum
以
map
调用的结果作为输入,将输入直接返回作为输出。
tupleSum
的函数调用结果和
map
调用的结果总是有相同的格式。如果
map
调用返回一个包含至少 2
个非元组对象的元祖,
tupleSum
将返回一个包含了具有相同个数的非元组对象的元组。
参数
X
是一个元组。
返回值
取决于
map
调用结果。
例子
x = [(1 2, 3 4, 5 6), (0.5, 0.6, 0.7)];
tupleSum(x);
// output
([9,12],1.8)
如果
map
调用返回单个非元组的对象,
tupleSum
也会返回单个非元组对象。
x = [(1 2, 3 4, 5 6)];
tupleSum(x);
// output
[9,12]
FILE:references/doc_684.md
# restore
**URL**: https://docs.dolphindb.cn/zh/funcs/r/restore.html
**来源**: DolphinDB 官方文档
---
restore
语法
restore(backupDir, dbPath, tableName, partition, [force=false],
[outputTable], [parallel=false], [snapshot=false], [keyPath])
详情
恢复指定分区的数据。该函数必须要用户登录后才能执行。
参数
backupDir
字符串,表示存放备份数据的目录。
dbPath
字符串,表示已备份的分布式数据库的路径。
tableName
字符串,表示已备份的表的名称。
partition
字符串,表示要恢复的分区的相对路径。分区路径可以包含通配符("%"和"?"), "?"表示单个字符,"%"表示0,1或多个字符。
若仅恢复某个分区,输入分区的相对路径或者"%/"+”分区名称”。举例:要恢复 "dfs://compoDB"
下的分区 ”20170810/50_100”,输入 "/compoDB/20170807/0_50" 或者 "%/20170807/0_50"。
请注意:若使用 2.00.4 ~ 2.00.6 版本 server,对表级分区数据进行备份和恢复时,该参数必须指定路径到物理索引(可通过函数
listTables
获取),例如分区
"/compoDB/20170807/0_50" 下表的物理索引为8,则
partition
需指定为
"/compoDB/20170807/0_50/8"。
若需要恢复所有分区,直接输入"%"。但需注意,采用此方法可能会导致当前数据表的数据丢失。举例说明:若当前表有10个分区,备份只包含2个分区,若使用%恢复数据,则可能导致表中其他8个分区的数据丢失。
force
布尔值,表示是否强制恢复。默认值为 false,表示只有元数据与备份数据元数据不一致的分区,才会恢复。
outputTable
分布式表句柄,该表的结构必须与要恢复的表结构一致。如果没有指定
outputTable
,恢复后的数据会存放到原表;如果指定了
outputTable
,恢复后的数据会存放到该表中,而原数据表保持不变。
parallel
布尔值,表示是否对一个数据表下不同分区进行并行恢复。默认值为 false。
snapshot
仅在参数
partition
= "%"
时有效。表示进行非首次恢复时,对于待恢复的数据库,若某些表或分区不在备份数据中,是否同步将数据库中对应的表/分区删除。 若设置为
true,则数据库将同步删除多余的表/分区;若设置为 false(默认值),则数据库不会删除多余的表/分区。
请注意:若 server 版本号低于
3.00.1
,则
snapshot
的默认值是 true,用户需要根据需求合理设置
snapshot
参数。
keyPath
字符串标量,指定恢复加密表备份的密钥路径。仅 Linux
系统支持该参数。恢复数据使用的密钥必须与备份时指定的密钥版本一致。注意恢复加密表时,备份表与目标表必须指定相同的加密方式(即建表时指定相同的
encryptMode
参数)。
返回值
返回一个字符串向量,包含恢复的分区的路径。该函数必须要用户登录后才能执行。
例子
创建一个组合分区的数据库 dfs://compoDB:
n=1000000
ID=rand(100, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x);
dbDate = database(, VALUE, 2017.08.07..2017.08.11)
dbID=database(, RANGE, 0 50 100);
db = database("dfs://compoDB", COMPO, [dbDate, dbID]);
pt = db.createPartitionedTable(t, `pt, `date`ID)
pt.append!(t);
备份表 pt 的所有数据:
backup("/home/DolphinDB/backup",<select * from loadTable("dfs://compoDB","pt")>,true);
// output
10
例1. 恢复所有数据到原表。
restore("/home/DolphinDB/backup","dfs://compoDB","pt","%",true);
// output
["dfs://compoDB/20170807/0_50/6F","dfs://compoDB/20170807/50_100/6F","dfs://compoDB/20170808/0_50/6F","dfs://compoDB/20170808/50_100/6F","dfs://compoDB/20170809/0_50/6F","dfs://compoDB/20170809/50_100/6F","dfs://compoDB/20170810/0_50/6F","dfs://compoDB/20170810/50_100/6F","dfs://compoDB/20170811/0_50/6F","dfs://compoDB/20170811/50_100/6F"]
例2. 恢复日期为2017.08.10的数据。
restore("/home/DolphinDB/backup","dfs://compoDB","pt","%20170810%",true)
// output
["dfs://compoDB/20170810/0_50/6F","dfs://compoDB/20170810/50_100/6F"]
例3. 在数据库 dfs://compoDB 中创建一个与表 pt 结构相同的表 temp,把 pt 的数据恢复到表
temp。请注意,采用此方法可能导致表中数据丢失。
temp=db.createPartitionedTable(t, `pt, `date`ID);
restore("/home/DolphinDB/backup","dfs://compoDB","pt","%",true,temp);
// output
["dfs://compoDB/20170807/0_50/6F","dfs://compoDB/20170807/50_100/6F","dfs://compoDB/20170808/0_50/6F","dfs://compoDB/20170808/50_100/6F","dfs://compoDB/20170809/0_50/6F","dfs://compoDB/20170809/50_100/6F","dfs://compoDB/20170810/0_50/6F","dfs://compoDB/20170810/50_100/6F","dfs://compoDB/20170811/0_50/6F","dfs://compoDB/20170811/50_100/6F"]
select count(*) from temp;
count
1000000
相关函数:
restoreDB
,
restoreTable
,
migrate
,
backup
注意事项
恢复通过 SQL 元代码(即
backup
指定
sqlObj
参数)备份的文件时,不能指定
snapshot
,否则会报错。
指定
outputTable
时,恢复通过 SQL 元代码备份的文件,系统会在
outputTable
中直接追加(append)备份数据;而恢复通过拷贝方式(即
backup
指定
dbPath
参数)备份的文件时,系统只覆盖
outputTable
中数据不一致的分区。若不指定
outputTable
,则数据恢复至原表,恢复方式相同。
恢复时需要确保备份数据与待恢复数据库的引擎类型(engine)一致,且
partitionScheme
(VALUE 除外)也保持一致。当采用 VALUE
分区时,须保证备份数据中的分区方案是待恢复数据库的分区方案的子集。例如:备份文件的分区方案是 database("dfs://xxx", VALUE,
2017.08.07..2017.08.11), 则待恢复数据库的 VALUE 分区范围必须不小于
2017.08.07..2017.08.11。
FILE:references/doc_6841.md
# stat
**URL**: https://docs.dolphindb.cn/zh/funcs/s/stat.html
**来源**: DolphinDB 官方文档
---
stat
语法
stat(X)
详情
获取
X
的统计信息。
参数
X
可以是向量或矩阵。
返回值
返回一个字典,它包含了 X 的统计信息,有平均值、最大值、最小值、计数、中位数和标准差。
例子
x=5 7 4 3 2 1 7 8 9 NULL;
stat(x);
// output
Median->5
Avg->5.111111
Min->1
Stdev->2.803767
Count->9
Size->10
Name->x
Max->9
stats = stat(x);
stats[`Avg];
// output
5.111111
FILE:references/doc_6844.md
# getOauthClientSecret
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getOauthClientSecret.html
**来源**: DolphinDB 官方文档
---
getOauthClientSecret
语法
getOauthClientSecret()
详情
获取单点登录(SSO)所使用的
oauthClientSecret
配置项的值。仅 admin
用户可调用。当启用配置访问控制(
enableConfigAccessControl=true
)时,由于
oauthClientSecret
属于敏感配置项,无法通过
getConfig
直接读取,管理员可调用此函数安全地获取该配置。
返回值
返回字符串,表示当前系统配置的
oauthClientSecret
值。
FILE:references/doc_6846.md
# getStreamingStat
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getStreamingStat.html
**来源**: DolphinDB 官方文档
---
getStreamingStat
语法
getStreamingStat([stat])
详情
监控流计算任务的运行状态。
参数
stat
可选参数,字符串标量或向量,用于指定需要返回的状态表名。可选值包括:pubConns, subConns,
pubTables, persistWorkers, subWorkers
,
udpPubTables
。
返回值
如果
stat
指定了单个表名,则返回对应的状态表。
如果
stat
指定了多个表名,或未指定
stat
,返回包含状态表的字典。
状态表包括:
表 pubConns
监控本地发布节点和它的所有订阅节点之间的连接状态。每一行表示一个订阅节点。它包含以下列:
列名
含义
client
订阅节点的 IP 地址和端口号
queueDepthLimit
发布节点上的消息队列深度的上限
queueDepth
发布节点上的当前消息队列深度
tables
发布节点上所有的共享流数据表
表 subConns 监控本地订阅节点和发布节点之间的连接状态。每一行表示一个发布节点。它包含以下列:
列名
含义
publisher
发布节点的别名
cumMsgCount
已经接收到的消息数量
cumMsgLatency
所有已接收的消息的平均延迟
LastMsgLatency
最后接收到的消息的延迟
lastUpdate
最后接收到消息的时间
表 pubTables 监控流数据表状态。每一行表示一个流数据表的信息。它包含以下列:
列名
含义
tableName
发布的流数据表名
subscriber
订阅端的 ip 和端口信息
msgOffset
已经发布的最后一条数据在总数据中的偏移量
actions
订阅任务的名称
上表中的延迟表示从消息到达发布节点的消息队列开始,到消息到达订阅节点的消息队列所耗费的时间。
表 persistWorkers 监控负责持久化流数据表的工作线程的状态。它包含以下列:
列名
含义
workerId
线程 ID
queueDepthLimit
持久化的消息队列深度的上限
queueDepth
持久化的当前消息队列深度
tables
已经持久化的流数据表
表 subWorkers 监控订阅节点的工作线程的状态。工作线程状态信息会按照 topic
来展示。它包含以下列:
列名
含义
workerId
线程 ID。若此列为空,代表该订阅尚未收到数据。
topic
订阅主题
type
当前订阅节点的订阅方式:UDP 组播订阅(udp)或 TCP 订阅(tcp)
queueDepthLimit
订阅节点上的消息队列深度的上限
queueDepth
订阅节点上的当前消息队列深度
processedMsgCount
已经处理的消息数
lastMsgId
最后一条消息的 ID
failedMsgCount
处理失败的消息数
lastFailedMsgId
最后一条错误消息的 ID
lastFailedTimestamp
最后一条错误消息发生的时间
lastErrMsg
最后一条错误消息的信息
msgAsTable
布尔值,表示订阅的数据是否为表。true 表示订阅的数据为表;false
表示订阅的数据是由列组成的元组。
batchSize
handler 批量处理的消息数
throttle
数值类型,单位为毫秒。表示继上次 handler 处理消息之后,若 batchSize
条件一直未达到,多久后再次处理消息
hash
非负整数,指定某个订阅线程处理进来的消息
filter
流数据表指定的过滤列
persistOffset
布尔值,表示是否持久化保存最新一条已经处理的订阅数据的偏移量
timeTrigger
布尔值,若为 true,表示即使没有新的消息进入,handler 也会在 throttle
参数所设定的时间间隔被触发
handlerNeedMsgId
布尔值,默认值为 false。若为 true,handler
必须支持两个参数:msgBody,msgId
raftGroup
高可用下 Raft 组的 ID
表 udpPubTables 用于监控流数据表进行 UDP 组播发布的状态。它包含以下列:
列名
含义
tableName
发布的流数据表名
channel
发布的 UDP 组播地址
msgOffset
已经发布的最后一条数据在总数据中的偏移量
actions
订阅该发布表的所有订阅任务名称
subNum
订阅该发布表的所有订阅数量
表 CEPEngine 用于监控 CEP 引擎的状态。它包含以下列:
列名
含义
name
CEP 引擎名称
user
创建 CEP 引擎的用户名
status
CEP 引擎状态
lastErrorMessage
最后一条错误信息
lastErrorTimestamp
最后一次错误信息的时间戳
useSystemTime
是否使用系统时间
numOfSubEngine
当前子引擎数量
queueDepth
队列深度
eventsReceived
从外部收到的事件数量
eventsEmitted
向外发送的事件数量
eventsOnOutputQueue
向外发送的事件队列中的事件数量
例子
getStreamingStat().pubConns;
getStreamingStat().subConns;
getStreamingStat().pubTables;
getStreamingStat().persistWorkers;
getStreamingStat().subWorkers;
getStreamingStat().udpPubTables
FILE:references/doc_6852.md
# unpack
**URL**: https://docs.dolphindb.cn/zh/funcs/u/unpack.html
**来源**: DolphinDB 官方文档
---
unpack
语法
unpack(format, buf)
详情
根据
format
指定的格式,将
buf
解包成 DolphinDB
中的数据。返回一个元组,其元素为解包后的数据。
参数
format
格式字符串,用于指定数据格式。指定方式参见附录。关于格式字符串的说明:
格式字符之前可以带有整数表示重复计数。 例如,格式字符串 '4h' 的含义与 'hhhh' 完全相同。
格式之间的空白字符会被忽略;但是计数及其格式字符中不可有空白字符。
对于 's' 格式字符,计数会被解析为字节的长度,而不是像其他格式字符那样的重复计数;例如,'10s' 表示一个 10 字节的字节串,而
'10c' 表示 10 个字符。 若未给出计数,则默认值为1。返回结果的字节对象长度必须恰好等于指定的字节数量。 作为特殊情况,'0c' 表示
0 个字符。
buf
二进制字节流,可以是 STRING 或 BLOB 类型。
buf
中各元素的字节大小和类型必须匹配
format
所要求的大小和类型。
返回值
一个元组,其元素为解包后的数据。
例子
res = pack("N",1);
res1 = unpack("N", res);
print(res1)
// output: (1)
res = pack("3s i", `123, 3)
res1 = unpack("3s i", res);
print(res1)
// output: ("123",3)
附录
格式和类型的对应关系见前述格式字符与类型相关内容。
默认情况下,C 类型以本机格式和字节顺序表示,在必要时通过跳过填充字节进行正确对齐(根据 C 编译器使用的规则)。
格式字符串的第一个字符可用于指示打包数据的字节顺序,大小和对齐方式。 如果第一个字符不是其中之一,则按 '@' 处理。
相关函数:
pack
FILE:references/doc_6856.md
# conditionalFilter
**URL**: https://docs.dolphindb.cn/zh/funcs/c/conditionalFilter.html
**来源**: DolphinDB 官方文档
---
conditionalFilter
语法
conditionalFilter(X, condition, filterMap)
详情
根据给定的字典参数
filterMap
,若向量
condition
中某元素为该字典的 key,而且向量
X
中相应位置元素为字典中该 key 值对应的 value 表示的向量中一个元素,或在该 value 表示的数据对的范围中时,返回 true,否则返回 false。
如果
X
和
condition
都是向量,返回的结果是与它们等长的向量。
参数
X
是标量或者向量。
condition
是标量,或与
X
等长的向量。
filterMap
是字典,表示过滤条件。
返回值
BOOL 类型标量或向量。
例子
例1:
conditionalFilter(1 2 3,`a`b`c, dict(`a`b,1 2));
// output
[1,1,0]
conditionalFilter(1 2 3,`a`b`b, dict(`a`b,[1 2,3 4]))
// output
[1,0,1]
例2:
从数据表 t 中,提取如下天内指定股票的数据:
2012.06.01: C, MS 2012.06.02: IBM, MS 2012.06.03: MS 2012.06.04: IBM
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
date = 2012.06.01 2012.06.01 2012.06.02 2012.06.03 2012.06.01 2012.06.02 2012.06.02 2012.06.03 2012.06.04
price = 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
t = table(sym, date, price, qty)
t;
sym
date
price
qty
C
2012.06.01
49.60
2200
MS
2012.06.01
29.46
1900
MS
2012.06.02
29.52
2100
MS
2012.06.03
30.02
3200
IBM
2012.06.01
174.97
6800
IBM
2012.06.02
175.23
5400
C
2012.06.02
50.76
1300
C
2012.06.03
50.32
2500
C
2012.06.04
51.29
8800
filter = dict(2012.06.01..2012.06.04, [`C`MS, `IBM`MS, `MS, `IBM])
select * from t where conditionalFilter(sym, date, filter) order by date, sym;
sym
date
price
qty
C
2012.06.01
49.6
2200
MS
2012.06.01
29.46
1900
IBM
2012.06.02
175.23
5400
MS
2012.06.02
29.52
2100
MS
2012.06.03
30.02
3200
例3:
filterMap
的 value 亦可采用数据对的形式。
t=table(`aaa`aaa`bbb`bbb as id, 2020.09.03 2020.09.10 2020.09.06 2020.09.09 as date)
t
id
date
aaa
2020.09.03
aaa
2020.09.10
bbb
2020.09.06
bbb
2020.09.09
mydict = dict(`aaa`bbb, [2020.09.01 : 2020.09.09, 2020.09.05 : 2020.09.09])
select * from t where conditionalFilter(date, id, mydict);
id
date
aaa
2020.09.03
bbb
2020.09.06
bbb
2020.09.09
FILE:references/doc_6858.md
# indexedSeries
**URL**: https://docs.dolphindb.cn/zh/funcs/i/indexedSeries.html
**来源**: DolphinDB 官方文档
---
indexedSeries
语法
indexedSeries(index, value)
详情
创建一个有索引的序列。
索引序列支持面板数据对齐运算。普通矩阵或向量进行二元运算时,按照对应元素分别进行计算,需要保持维度(shape)一致。而索引序列之间,索引序列与索引矩阵之间,进行二元运算时,根据行列标签(index)自动对齐,对维度没有硬性要求。
支持的二元操作包括:
(1) 算术运算符和函数:+, -, *, /(整除), (ratio), %(mod), pow
(2) 逻辑运算符和函数:<, <=, >, >=, ==, !=, <>, &&, ||, &, |,
^
(3) 滑动窗口函数:mwavg, mwsum, mbeta, mcorr, mcovar
(4) 累计窗口函数:cumwavg, cumwsum, cumbeta, cumcorr, cumcovar
(5) 聚合函数:wavg, wsum, beta, corr, covar
参数
index
与
value
为等长向量。
index
须严格递增,无重复项。
返回值
数值型矩阵,表示索引序列。
例子
例1. 索引序列之间的运算,长度可以相等或者不等,根据索引对齐。
s1 = indexedSeries(2012.01.01..2012.01.04, [10, 20, 30, 40])
s2 = indexedSeries(2011.12.30..2012.01.01, [50, 60, 70])
res = s1 + s2
col1
2011.12.30
2011.12.31
2012.01.01
80
2012.01.02
2012.01.03
2012.01.04
例2. 索引序列和向量之间运算,长度必须相等。
s1 = indexedSeries(2012.01.01..2012.01.04, [10, 20, 30, 40])
v = [1,2,3,4]
res = s1+v
col1
2012.01.01
11
2012.01.02
22
2012.01.03
33
2012.01.04
44
例3. 索引序列和索引矩阵进行运算时,根据索引对齐。
s1 = indexedSeries(2012.01.01 2012.01.03 2012.01.04 2012.01.06, [10, 20, 30, 40])
m = matrix(1..6, 11..16).rename!(2012.01.01..2012.01.06,`x`y).setIndexedMatrix!()
s1 + m
IBM
MSFT
2012.01.01
11
21
2012.01.02
2012.01.03
23
33
2012.01.04
34
44
2012.01.05
2012.01.06
46
56
例4. 索引序列与没有设置索引的矩阵进行运算,长度必须相等。
s1 = indexedSeries(2012.01.01..2012.01.04, [10, 20, 30, 40])
m = matrix([1,1,1,1], [2,2,2,2])
res = s1 pow m
col1
col2
10
100
20
400
30
900
40
1,600
FILE:references/doc_6888.md
# createCryptoOrderBookEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createcryptoorderbookengine.html
**来源**: DolphinDB 官方文档
---
createCryptoOrderBookEngine
语法
createCryptoOrderBookEngine(name, dummyTable, inputColMap,
[outputTable], depth, [updateRule='direct'], [errorHandler=NULL],
[cachingInterval=5000], [timeout=-1], [outputHandler], [msgAsTable=false],
[cachedDepth]
, [snapshotDir],
[snapshotIntervalInMsgCount]
)
注:
社区版 License 暂不支持该引擎,如需使用此功能,请联系技术支持。
详情
根据数字货币全量深度快照和增量深度信息,实时更新订单簿。
参数
name
字符串标量,表示 CryptoOrderBook 引擎的名称,可包含字母,数字和下划线,但必须以字母开头。
dummyTable
一个表对象,表示输入表。
dummyTable
需要通过
inputColMap
映射为如下列:
必需列1:
列名
类型
含义
symbol
SYMBOL
数字货币代码。
isIncremental
BOOL
是否为增量数据。true 表示增量数据,false 表示全量数据。
eventTime
TIMESTAMP
/ NANOTIMESTAMP
事件时间。
askQty
DECIMAL[] / DOUBLE[]
卖出数量的列表。
askPrice
DECIMAL[] / DOUBLE[]
卖出价格的列表。
bidQty
DECIMAL[] / DOUBLE[]
买入数量的列表。
bidPrice
DECIMAL[] / DOUBLE[]
买入价格的列表。
必需列2:根据 updateRule 的取值进行调整。
当
updateRule
="direct" 时,不需要指定必需列2。
当
updateRule
="general" 时,指定以下列:
列名
类型
含义
prevUpdateId
LONG
上一条数据的 ID。
updateId
LONG
当前收到数据的 ID。
当
updateRule
="Binance-spot" 时,指定以下列:
列名
类型
含义
lastUpdateId
LONG
从上次推送至今新增的最后一个 update Id。
firstUpdateId
LONG
从上次推送至今新增的第一个 update Id。
当
updateRule
="Binance-futures" 时,指定以下列:
列名
类型
含义
lastUpdateId
LONG
从上次推送至今新增的最后一个 update Id。
firstUpdateId
LONG
从上次推送至今新增的第一个 update Id。
prevLastUpdateId
LONG
上次推送的最后一个 update Id (即上条消息的 lastUpdateId)。
其它列:除上述必需列外的列。引擎会将这些列简单拷贝到
outputTable
的对应列中。
inputColMap
字典,将
dummyTable
中列字段的名称映射为引擎计算所需要的列。
outputTable
可选参数,一个表对象,用于输出最新的订单簿。其结构必须与
dummyTable
相同。
outputTable
和
outputHandler
只需指定其一。
depth
正整数或字典,用于指定订单簿的深度。
正整数:所有数字货币的订单簿深度都为该设置值。
字典:键是字符串标量或向量,表示数字货币代码;值是整型,表示订单簿深度。对于指定的数字货币,将按照设定的深度输出订单簿。未被指定的数字货币将不输出订单簿结果。
updateRule
可选参数,字符串标量,表示订单簿更新规则。可选值为:
"direct":默认值,表示直接更新,系统将不进行数据丢失判断,仅根据 isIncremental 字段的值绝对是更新(isIncremental
为 true)还是覆盖(isIncremental 为 false)订单簿结果。
"general":表示通用的更新规则。要求按顺序插入增量数据,并确保数据中 updateId 单调递增。
"Binance-spot":表示适用于币安交易所现货的更新规则。
"Binance-futures":表示适用于币安交易所期货的更新规则。
errorHandler
可选参数,自定义函数。当增量数据出现缺失时,可通过该函数进行错误处理。包含 2 个参数:
第一个是字符串标量,表示数字货币代码。
第二个是整型标量,表示错误码,包括以下情况:
1:接收到历史数据。
2:接收到应在未来时间点到达的乱序数据。
3:超时错误,指定时间间隔内没有新的订单簿合成。
4:买卖价格交叉错误。判断交叉的条件为最高买价大于等于最低卖价。
cachingInterval
可选参数,整型标量,表示缓存增量深度数据的时间间隔。默认值为
5000,单位为毫秒。对于每个数字货币,当缓存中的数据时间与当前最新一条数据时间的差值小于等于
cachingInterval
时,该数据才会被保留在缓存中。
timeout
可选参数,整型标量,表示超时时间。单位为毫秒,默认值为 -1,表示不设置超时时间。在
timeout
指定的时间内未合成新的订单簿时,将触发超时错误,此时会通过
errorHandler
进行错误处理。
outputHandler
可选参数,一元函数。设置此参数时,引擎计算结束后,不再将计算结果写到输出表,而是会调用此函数处理计算结果。
msgAsTable
可选参数,布尔标量,表示在设置了参数
outputHandler
时,将引擎的计算结果以表的结构调用函数。默认值为
false,此时将计算结果的每一列作为元素组成元组。
cachedDepth
可选参数,正整数或字典,用于指定缓存中价格和数量(包括 askQty, askPrice,
bidQty, bidPrice)的深度。
正整数:缓存中所有数字货币的价格和数量将按照该值的深度进行缓存。
字典:键是字符串标量或向量,表示数字货币代码;值是整型,表示对应的深度。对于指定的数字货币,将按照设定的深度缓存价格和数量。未被指定的数字货币将保留实际收到的所有价格和数量信息。
若要开启快照机制 (snapshot),必须指定
snapshotDir
与
snapshotIntervalInMsgCount
。
snapshotDir
可选参数,字符串,表示保存引擎快照的文件目录。
指定的目录必须存在,否则系统会提示异常。
创建流数据引擎时,如果指定了
snapshotDir
,会检查该目录下是否存在快照。如果存在,会加载该快照,恢复引擎的状态。
多个引擎可以指定同一个目录存储快照,用引擎的名称来区分快照文件。
一个引擎的快照可能会使用三个文件名:
临时存储快照信息:文件名为
<engineName>.tmp
;
快照生成并刷到磁盘:文件保存为
<engineName>.snapshot
;
存在同名快照:旧快照自动重命名为
<engineName>.old
。
snapshotIntervalInMsgCount
可选参数,为整数类型,表示每隔多少条数据保存一次流数据引擎快照。
返回值
一个表。
例子
运行代码前,先下载
../data/CryptoOrderBookInput.zip
文件。
例1. 创建一个加密货币订单簿引擎,使用 "Binance-futures" 规则处理来自 Binance 交易所 U 本位合约的深度数据。根据 Binance
交易所数据发送规则,示例数据中首先为增量深度数据,在 68 行插入 1000 档全量快照数据后,引擎开始输出订单簿。
// 定义输入输出表结构
colNames = `isIncremental`exchange`eventTime`transactionTime`symbol`firstUpdateId`lastUpdateId`prevLastUpdateId`bidPrice`bidQty`askPrice`askQty
colTypes = [BOOL, SYMBOL, TIMESTAMP, TIMESTAMP, SYMBOL, LONG, LONG, LONG, DECIMAL128(18)[], DECIMAL128(8)[], DECIMAL128(18)[], DECIMAL128(8)[]]
// 创建输入输入输出表
share table(1:0, colNames, colTypes) as outputTable
share table(1:0, colNames, colTypes) as inputTable
inputTarget = ["symbol", "eventTime", "isIncremental", "bidPrice", "bidQty", "askPrice", "askQty", "lastUpdateId", "firstUpdateId", "prevLastUpdateId"]
inputSource = ["symbol", "eventTime", 'isIncremental', 'bidPrice', 'bidQty', 'askPrice', 'askQty', 'lastUpdateId', 'firstUpdateId', 'prevLastUpdateId']
inputColMap = dict(inputTarget, inputSource)
depth = dict(["BTCUSDT"], [1000])
cachedDepth = dict(["BTCUSDT"], [1500])
def errorHandler(instrument, code) {
if (code == 1) {
writeLog("handle hisotorical msg...")
} else if (code == 2) {
writeLog("handle unordered msg...")
} else if (code == 3) {
writeLog("handle timeout...")
} else if (code == 4) {
writeLog("handle corssed price...")
} else {
writeLog("unknown error!")
}
}
// 创建引擎
engine = createCryptoOrderBookEngine(name="binanceFutures", dummyTable=inputTable, inputColMap=inputColMap, outputTable=outputTable,
depth=depth, updateRule="Binance-futures", errorHandler=errorHandler, cachingInterval=5000,
timeout=6000, msgAsTable=true, cachedDepth=cachedDepth)
// 加载示例数据
fin=file("binanceFuturesTestData.bin")
binanceFuturesTestData = fin.readObject()
fin.close();
// 数据插入引擎进行合成
getStreamEngine("binanceFutures").append!(binanceFuturesTestData)
// 清除环境
undef("inputTable", SHARED)
undef("outputTable", SHARED)
dropStreamEngine("binanceFutures")
例2. 创建一个加密货币订单簿引擎,使用 "general" 规则处理来自 OKX 交易所永续合约的深度数据。根据 OKX 交易所数据发送规则,示例数据中首行为 400
档快照数据,之后为增量快照数据。
// 定义输入输出表结构
colNames=['isIncremental', 'symbol', 'askPrice', 'askVolume', 'askNum', 'bidPrice', 'bidVolume', 'bidNum', 'checksum', 'prevSeqId', 'seqId', 'updateTime'];
colTypes=[BOOL, SYMBOL, DECIMAL128(18)[], DECIMAL128(8)[], INT[], DECIMAL128(18)[], DECIMAL128(8)[], INT[], LONG, LONG, LONG, TIMESTAMP];
// 创建输入输入输出表
share table(1:0, colNames, colTypes) as inputTable
share table(1:0, colNames, colTypes) as outputTable
inputTarget = ["symbol", "eventTime", "isIncremental", "bidPrice", "bidQty", "askPrice", "askQty", "prevUpdateId", "updateId"];
inputSource = ["symbol", "updateTime", 'isIncremental', 'bidPrice', 'bidVolume', 'askPrice', 'askVolume', 'prevSeqId', 'seqId'];
inputColMap = dict(inputTarget, inputSource)
depth = dict(["BTC-USD-SWAP"], [400])
cachedDepth = dict(["BTC-USD-SWAP"], [800])
def errorHandler(instrument, code) {
if (code == 1) {
writeLog("handle hisotorical msg...")
} else if (code == 2) {
writeLog("handle unordered msg...")
} else if (code == 3) {
writeLog("handle timeout...")
} else if (code == 4) {
writeLog("handle corssed price...")
} else {
writeLog("unknown error!")
}
}
// 创建引擎
engine = createCryptoOrderBookEngine(name="okxSwap", dummyTable=inputTable, inputColMap=inputColMap, outputTable=outputTable,
depth=depth, updateRule="general", errorHandler=errorHandler, cachingInterval=5000,
timeout=6000, msgAsTable=true, cachedDepth=cachedDepth)
// 加载示例数据
fin=file("okxTestData.bin")
okxTestData = fin.readObject()
fin.close();
// 数据插入引擎进行合成
getStreamEngine("okxSwap").append!(okxTestData)
// 清除环境
undef("inputTable", SHARED)
undef("outputTable", SHARED)
dropStreamEngine("okxSwap")
FILE:references/doc_6890.md
# remoteRunCompatible
**URL**: https://docs.dolphindb.cn/zh/funcs/r/remoteruncompatible.html
**来源**: DolphinDB 官方文档
---
remoteRunCompatible
语法
remoteRunCompatible(conn, script, args)
详情
将脚本或函数传输到远程数据库执行。
remoteRunCompatible 与 remoteRun 的区别在于:
remoteRunCompatible 对本地和远程数据库的版本没有限制。
remoteRun 在本地数据库为 3.00 版本时,不支持远程数据库的版本低于3.00。
参数
conn
是远程数据库的连接句柄。
script
是要执行的脚本或函数名。
args
可选的可变长度参数。如果
script
是函数名,
args
是函数的参数。
返回值
script
的执行结果。
例子
第一种用法:
script
是脚本,则表示在远程节点上执行脚本。
conn =
xdb(host="localhost",port=8848,userId="admin",password=123456);
remoteRunCompatible(conn, "avg(1..100)");
结果为
50.5。
第二种用法:
script
是函数名
如果 script 加了单引号,双引号或者反引号,那么表示在远程节点上调用函数。函数是定义在远程节点上,但是参数由本地节点传过去。
在远程节点增加函数视图 myAvg
def myAvg(x){ return avg(x)+2 }
addFunctionView(myAvg)
连接远程节点调用视图
conn = xdb("localhost",8848,`admin,`123456);
remoteRunCompatible(conn, "myAvg", 1..100);
结果为
52.5。
如果 script 不加单引号,双引号或者反引号,那么表示调用的函数定义在本地节点上。参数也是由本地节点传过去。
在本地节点定义同名函数 myAvg
def myAvg(x){ return avg(x)+1
}
在远程节点执行此函数
conn = xdb("localhost",8848,`admin,`123456);
remoteRunCompatible(conn, myAvg, 1..100);
结果为
51.5。
相关函数:
remoteRun
FILE:references/doc_6891.md
# setDatabaseForClusterReplication
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setDatabaseForClusterReplication.html
**来源**: DolphinDB 官方文档
---
setDatabaseForClusterReplication
语法
setDatabaseForClusterReplication(dbHandle, option)
详情
开启/关闭分布式数据库的集群间的异步复制。该函数只能由管理员在主集群的数据节点调用。
相关函数:
getDatabaseClusterReplicationStatus
参数
dbHandle
:一个分布式数据库句柄。
option
:布尔值,表示开启(true)/关闭(false)指定数据库的异步复制,默认为 false。
FILE:references/doc_6905.md
# push!
**URL**: https://docs.dolphindb.cn/zh/funcs/p/push_.html
**来源**: DolphinDB 官方文档
---
push!
是
append!
的别名。
FILE:references/doc_6914.md
# 滑动窗口系列(m 系列)
**URL**: https://docs.dolphindb.cn/zh/funcs/themes/mFunctions.html
**来源**: DolphinDB 官方文档
---
滑动窗口系列(m 系列)
对窗口内聚合计算,DolphinDB引入了 m 系列函数。m
系列函数对数据内的每个元素进行一次窗口计算,返回一个和原数据等长的结果。
m 系列函数介绍
m 系列函数对应的高阶函数
moving
:
moving(func, funcArgs, window, [minPeriods])
注:
m 系列函数为各自的计算场景进行了优化,因此比
moving
高阶函数有更好的性能。
内置的 m
系列函数的通用参数模板如下:
mfunc(X, window, [minPeriods])
mfunc(X, Y, window, [minPeriods])
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
Y
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
函数列表
根据
window
的取值,可以分为两类:
window
是正整数或 DURATION 类型
单目:
msum
msum2
mavg
mprod
mmax
mmin
mmed
mfirst
mlast
mrank
mcount
mpercentile
mstd
mstdp
mvar
mvarp
mkurtosis
mskew
mimax
mimin
mfirstNot
mlastNot
mifirstNot
milastNot
miminLast
mimaxLast
mLowRange
mTopRange
双目:
mwavg
mwsum
mcorr
mcovar
mbeta
window
是正整数时
mmad
mmaxPositiveStreak
mmse
mslr
窗口确定规则
m
系列函数,支持一个向前的窗口,即基于数据中的每个元素,向前选取
window
指定范围的窗口。
X
是普通向量/矩阵/表时
此时
window
表示以窗口内元素个数衡量的滑动窗口的长度。
注:
对于表,只有布尔类型和数值型的列参与计算。
m 系列函数(mrank, mcount 除外)提供了
minPeriods
参数,用于约束窗口的观测值。对于计算结果:
注:
如果没有指定
minPeriods
,前(
window
- 1)个元素为 NULL;
如果指定了
minPeriods
,前(
minPeriods
- 1)个元素为 NULL。
上图的对应代码,这里以
msum
为例:
X = 2 1 3 7 6 5 4 9 8 10
msum(X, 3);
//output: [ , , 6, 11, 16, 18, 15, 18, 21, 27]
X
是索引序列或索引矩阵时
此时
window
表示以时间衡量的滑动窗口的长度。若此时
window
是一个正整数,则默认将其视作和 X 中索引单位一致的量。
其滑动规则如下图:
上图的对应代码,这里以
msum
为例:
T = [2022.01.01, 2022.01.02, 2022.01.03, 2022.01.06, 2022.01.07, 2022.01.08, 2022.01.10, 2022.01.11]
X = 1..8
X1 = indexedSeries(T, X)
msum(X1, window=3d);
返回:
label
col0
2022.01.01
1
2022.01.02
3
2022.01.03
6
2022.01.06
4
2022.01.07
9
2022.01.08
15
2022.01.10
13
2022.01.11
15
FILE:references/doc_6917.md
# setTSDBCacheEngineSize
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setTSDBCacheEngineSize.html
**来源**: DolphinDB 官方文档
---
setTSDBCacheEngineSize
语法
setTSDBCacheEngineSize(memSize)
详情
用于在线修改 TSDB 引擎的 Cache Engine
容量。集群环境下,该命令只能由管理员在数据节点/计算节点上执行。执行前需要确保开启了 Cache Enigne (配置参数
TSDBCacheEngineSize
)。可以通过
getTSDBCacheEngineSize
查看设置是否生效。
注:
此命令修改的配置值在集群重启后将失效。若需要配置值永久生效,请更改配置文件中的
TSDBCacheEngineSize
。
自 2.00.16/
3.00.3
起,当 Cache Engine 内存占用达到
TSDBCacheEngineSize
设定值时,系统将阻塞写入线程。此前版本中,内存占用允许升至设定值的两倍后才会触发阻塞。详情请见
配置项
TSDBCacheEngineSize
说明
。
相关函数:
getTSDBCacheEngineSize
参数
memSize
一个数值型标量(单位为GB),必须大于0且小于
maxMemSize
* 0.75。
FILE:references/doc_6927.md
# invUniform
**URL**: https://docs.dolphindb.cn/zh/funcs/i/invUniform.html
**来源**: DolphinDB 官方文档
---
invUniform
语法
invUniform(lower, upper, X)
详情
返回均匀分布的累计密度函数的逆函数值。
参数
lower
和
upper
是数值型标量,表示连续均匀分布的下限和上限。
X
是0到1之间的浮点型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
invUniform(0.627, 2.31, [0.001, 0.5, 0.999]);
// output: [0.628683, 1.4685, 2.308317]
invUniform(0.627, 2.31, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output: [0.7953, 1.1319, 1.4685, 1.8051, 2.1417]
FILE:references/doc_6935.md
# getOLAPCacheEngineSize
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getOLAPCacheEngineSize.html
**来源**: DolphinDB 官方文档
---
getOLAPCacheEngineSize
语法
getOLAPCacheEngineSize()
别名:
getCacheEngineMemSize
详情
查看当前节点下 OLAP 引擎的 Cache Engine 的内存情况,单位为字节。
参数
无
返回值
返回一个 ANY VECTOR:
第1个元素表示 Cache Engine 正在使用的内存量;
第2个元素表示 Cache Engine 保存的列文件占用的内存;
第3个元素表示指向列文件的指针所占用的内存;
第4个元素表示 Cache Engine 允许使用的内存上限。
例子
setOLAPCacheEngineSize(0.4)
getOLAPCacheEngineSize()
// output
(0,0,0,429496729)
相关函数:
setOLAPCacheEngineSize
FILE:references/doc_6952.md
# firstNot
**URL**: https://docs.dolphindb.cn/zh/funcs/f/firstNot.html
**来源**: DolphinDB 官方文档
---
firstNot
语法
firstNot(X, [k])
详情
若
X
是向量:
如果没有指定
k
,返回
X
中第一个不为 NULL 的元素。
如果指定
k
,返回
X
中第一个不为
k
或 NULL 的元素。
若
X
是矩阵或表,在每列内进行上述计算,返回一个向量。
firstNot
函数也支持查询分布式表和分区表。
参数
X
可以是标量、数据对、向量、矩阵或表。
k
是一个标量,它是可选参数。
返回值
当
X
是向量时,返回标量,数据类型与
X
相同
当
X
是矩阵或表时,返回向量,每个元素对应每列的计算结果,数据类型与原列元素类型相同。
例子
X
是向量:
firstNot(0 0 0 6 1, 0);
// output
6
firstNot(NULL 0 3 2 1, 0);
// output
3
firstNot(NULL 0 1 6);
// output
0
t=table(1 1 1 1 1 2 2 2 2 2 as id, 0 0 0 2 1 NULL NULL 0 0 3 as x);
t;
id
x
1
0
1
0
1
0
1
2
1
1
2
2
2
0
2
0
2
3
select firstNot(x, 0) from t group by id;
id
firstNot_x
1
2
2
3
m=matrix(0 NULL 1 2 3, NULL 2 NULL 0 3);
m;
#0
#1
0
2
1
2
0
3
3
firstNot(m, 0);
// output
[1,2]
FILE:references/doc_6957.md
# clearDSCacheNow
**URL**: https://docs.dolphindb.cn/zh/funcs/c/clearDSCacheNow.html
**来源**: DolphinDB 官方文档
---
clearDSCacheNow
语法
clearDSCacheNow(ds)
详情
函数
clearDSCacheNow
立即清除数据源和缓存。
参数
ds
是数据源或数据源列表。
返回值
无。
例子
PTNDB_DIR = "/home/db_testing"
dbName = database(PTNDB_DIR + "/NYSETAQByName")
Trades = dbName.loadTable(`Trades)
ds=sqlDS(<select Time,Exchange,Symbol,Trade_Volume as Vol, Trade_Price as Price from Trades>)
ds.cacheDSNow() // cache the data immediately
ds.clearDSCacheNow() // clear the cache immediately
FILE:references/doc_6964.md
# groups
**URL**: https://docs.dolphindb.cn/zh/funcs/g/groups.html
**来源**: DolphinDB 官方文档
---
groups
语法
groups(X
, [mode='dict']
)
详情
对
X
中每一个独特值,列出其在
X
中的所有对应数据的下标。
参数
X
是一个向量。
mode
可选参数,用于指定
groups
返回值的数据形式,默认为
"dict"。可指定为以下值:
"dict":返回一个字典。字典的 key 存储
X
中的独特值(unique
value);字典的 value 为一个向量,存储该值在
X
中对应的下标。
"table":返回一个包含两列的表。字段为 "key" 和 "index",分别存储
X
中的独特值和其在
X
中对应的下标。
"vector":返回一个 array vector,按照
X
中独特值升序排列,存储每个独特值在
X
中对应的下标。
"tuple":返回一个 tuple,其存储方式同
mode
="vector"。
返回值
若
mode
= 'dict',返回一个字典;若
mode
=
'table',返回一个数据表,其中 index 列表示下标,为数组向量类型。
例子
x=NULL NULL 12 15 12 16 15 14 NULL NULL
groups(x);
// output
16->[5]
->[0,1,8,9]
12->[2,4]
14->[7]
15->[3,6]
groups(x, "vector")
// output
[[0,1,8,9],[2,4],[7],[3,6],[5]]
groups(x, "tuple")
// output
([0,1,8,9],[2,4],[7],[3,6],[5])
groups(x, "table")
key
index
[0,1,8,9]
2
[2,4]
4
[7]
5
[3,6]
6
[5]
FILE:references/doc_6970.md
# alter
**URL**: https://docs.dolphindb.cn/zh/progr/sql/alter.html
**来源**: DolphinDB 官方文档
---
alter
语法
alter table tableObj add [column] columnName columnType;
alter table tableObj drop [column] columnName;
alter table tableObj rename [column] columnName to newColumnName;
详情
alter 语句用于向已有的表中添加
、删除或重命名
列。其中
[column] 为可选的关键字,用于明确表示操作的是列。
需要注意的是,TSDB 引擎仅支持 add
操作。
参数
tableObj
可为任何形式的数据表,包括内存表、流数据表、分布式表。
columnName
字符串标量,表示要添加的列的名称。
newColumnName
字符串标量,表示要修改的列的新名称。
columnType
表示数据类型的标量。
例子
if(existsDatabase("dfs://test")) dropDatabase("dfs://test")
create database "dfs://test" partitioned by VALUE(1..10), HASH([SYMBOL, 40]), engine='OLAP', atomic='TRANS', chunkGranularity='TABLE'
create table "dfs://test"."pt"(
id INT,
deviceId SYMBOL,
date DATE[comment="time_col", compress="delta"],
value DOUBLE,
isFin BOOL
)
partitioned by ID, deviceID
pt = loadTable("dfs://test", `pt)
alter table pt add location SYMBOL;
pt = loadTable("dfs://test", `pt)
pt.schema().colDefs
name
typeString
typeInt
extra
comment
id
INT
4
deviceId
SYMBOL
17
date
DATE
6
time_col
value
DOUBLE
16
isFin
BOOL
1
location
SYMBOL
17
alter table pt rename location to loc
pt = loadTable("dfs://test", `pt)
pt.schema().colDefs
name
typeString
typeInt
extra
comment
id
INT
4
deviceId
SYMBOL
17
date
DATE
6
time_col
value
DOUBLE
16
isFin
BOOL
1
loc
SYMBOL
17
alter table pt drop value
pt = loadTable("dfs://test", `pt)
pt.schema().colDefs
name
typeString
typeInt
extra
comment
id
INT
4
deviceId
SYMBOL
17
date
DATE
6
time_col
isFin
BOOL
1
loc
SYMBOL
17
FILE:references/doc_6976.md
# cds
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cds.html
**来源**: DolphinDB 官方文档
---
cds
语法
cds(settlement, maturity, evalDate, notional, spread, riskFree, recovery,
isSeller, frequency, calendar, [convention='Following'],
[termDateConvention='Following'], [rule='CDS'], [basis=1])
详情
本函数对信用违约互换(Credit Default Swap,CDS)进行估值计算。成功执行后将返回 CDS 的估值。
参数
settlement
DATE 类型标量或向量,表示 CDS 合约的生效日。
maturity
DATE 类型标量或向量,表示 CDS 合约的到期日。
注意:
settlement
应早于对应的
maturity
。
evalDate
DATE 类型标量或向量,表示估值日。
注意:
evalDate
不应晚于对应的
settlement
。
notional
数值类型标量或向量,非负数,表示 CDS 合约的名义本金。
spread
数值类型标量或向量,表示 CDS 利差,是 CDS 买方每期需支付给 CDS 卖方的金额,以 CDS
的名义本金的百分比形式报价,以基点(bps)表示。
riskFree
数值类型标量或向量,非负数,表示无风险利率。
recovery
数值类型标量或向量,表示回收率,有效范围是(0,1),指的是在发生信用事件(如违约)后,债券持有人预计能够收回的金额占违约债券面值的百分比。
isSeller
布尔类型标量或向量,表示交易方为买方还是卖方,有两个可选值:
true:表示交易方为卖方。
false:表示交易方为卖方。
frequency
表示买方向卖方支付金额的频率,支持两种输入类型:
整数标量或向量:表示买方每年向卖方支付金额的次数;比如输入 1,表示每年付息 1 次,即按年支付;输入 2,表示每年付息 2 次,即按半年期支付。
DURATION 标量或向量:表示买方每隔多久向卖方进行一次支付。比如输入 duration(`3M),表示每隔 3 个月支付一次,即按季度支付。
可选值
含义
1 / 1y
表示每年付息1次
2 / 6M
表示每年付息2次 / 每6个月付息1次
3 / 4M
表示每年付息3次 / 每4个月付息1次
4 / 3M
表示每年付息4次 / 每3个月付息1次
6 / 2M
表示每年付息6次 / 每2个月付息1次
12 / 1M
表示每年付息12次 / 每月付息1次
13 / 4w
表示每年付息13次 / 每4周付息1次
26 / 2w
表示每年付息26次 / 每2周付息1次
52 / 1w
表示每年付息52次 / 每周付息1次
365 / 1d
表示每年付息365次 / 每天付息1次
calendar
字符串类型标量或向量,表示使用的市场日历类型,请参阅
交易日历
。
convention
可选参数,字符串标量或向量,表示把非工作日调整到工作日的方法,可选值为:
'Following':表示选择给定假日后的第一个工作日,默认值。
'ModifiedFollowing':表示选择给定假日后的第一个工作日,除非该工作日属于不同的月份,此时应选择假日前的第一个工作日。
'Preceding':表示选择给定假日前的第一个工作日。
'ModifiedPreceding':表示选择给定假日前的第一个工作日,除非该工作日属于不同的月份,此时应选择假日后的第一个工作日。
'Unadjusted':表示不做调整。
'HalfMonthModifiedFollowing':表示选择给定假日后的第一个工作日,除非该工作日跨越了月中(15
日)或月末,此时应选择假日前的第一个工作日。
'Nearest':表示选择离给定假日最近的工作日。如果前一个和后一个工作日距离给定假日同样远,则默认选择后一个工作日。
termDateConvention
可选参数,字符串标量或向量,表示如果最后一个日期是非工作日,将其调整到工作日的方法,可选值同
convention。默认值为'Following'。
rule
可选参数,字符串标量或向量,表示日期列表的生成规则,可选值为:
'Backward':表示从终止日期向生效日期倒向生成。
'Forward':表示从生效日期向终止日期正向生成。
'Zero':表示在生效日期和终止日期之间不生成中间日期。
'ThirdWednesday':表示除了生效日期和终止日期,其他日期落在当月的第三个星期三(正向生成)。
'ThirdWednesdayInclusive':表示所有日期,包括生效日期和终止日期,均落在当月的第三个星期三(正向生成)。
'Twentieth':表示除生效日期外,所有日期均落在当月 20 日(用于新兴市场 CDS 时间表)。终止日期也相应调整。
'TwentiethIMM':表示除生效日期外,所有日期均落在 IMM(International Money Market)月份的 20 日(用于
CDS 时间表)。终止日期也相应调整。
'OldCDS':表示除生效日期外,所有日期均落在 IMM(International Money Market)月份的 20
日(用于CDS时间表)。终止日期也相应调整。但日期端点不受限制,并允许短尾或长尾票息期(旧 CDS 惯例)。
'CDS':表示使用
自 2009
年“大爆炸”改革以来的信用衍生品标准规则
。默认值。
'CDS2015':表示
使用自 2015 年 12 月 20
日以来的信用衍生品标准规则
。
basis
可选参数,整型或 STRING 类型的标量或向量,表示要使用的日计数基准类型。可选值为:
Basis
日计数基准
0 / "Thirty360US"
US (NASD) 30/360
1 / "ActualActual" (默认值)
实际/实际
2 / "Actual360"
实际/360
3 / "Actual365"
实际/365
4 / "Thirty360EU"
欧洲 30/360
注意:如果输入参数中,部分为标量,其余为向量时,则会将标量当作与向量长度相同、所有元素值等于该标量的向量;且所有向量的长度必须一致。
返回值
DOUBLE 类型标量或向量。
例子
自定义参数,计算 CDS 的估值。
valDate = 2007.05.15
settlement = 2007.05.16
maturity = 2007.08.16
notional = 1000000.0
spread = 0.0150
riskFreeRate = 0.01
recoveryRate = 0.5
isSeller = true
frequency = 4
convention = 'Following'
termDateConvention = 'Unadjusted'
rule = 'TwentiethIMM'
basis = 3
cds(settlement, maturity, valDate, notional, spread, riskFreeRate, recoveryRate, isSeller, frequency, 'CCFX', convention, termDateConvention, rule, basis)
// Output: -5.448913728297157
FILE:references/doc_6988.md
# summary
**URL**: https://docs.dolphindb.cn/zh/funcs/s/summary.html
**来源**: DolphinDB 官方文档
---
summary
语法
summary(X,[interpolation],[characteristic],[percentile],[precision],[partitionSampling])
详情
生成数据的汇总统计信息。
注:
若
X
是表,则
summary
只统计表中数值类型的列,忽略非数值类型的列。
若
X
是数据源,则数据源只能包含数值类型的列,否则在进行
summary
统计时会报错。
参数
X
可以是内存表、DFS 表或由
sqlDS
函数生成的数据源。注意:暂不支持由
sqlDS
生成的包含表连接的数据源。
interpolation
字符串,表示计算百分位采用的插值方法,可以是 'linear'(默认值), 'nearest', 'lower',
'higher', 'midpoint'。
characteristic
字符串标量或向量,表示需要输出的统计特征。可选值为 'avg', 'std'。若不指定该参数,则默认同时输出 'avg' 和
'std'。
percentile
DOUBLE 类型向量,范围是[0,100]。默认值为 [25, 50, 75],表示返回第25, 50和75百分位数。
precision
大于0的 DOUBLE 类型标量,表示插值计算百分位时的迭代精度。默认值为
1e-3。当前计算结果与上一次迭代计算结果的差值小于等于该值时,将退出迭代。建议取值范围为[1.000e-3,
1.000e-9],若值较小,则可能因迭代次数过多而导致性能下降;若值较大,则可能导致计算的结果不精确。
partitionSampling
正整数或(0,1]之间的浮点数。正整数表示随机选取的分区个数;浮点数表示随机选取相应比例的分区。若不指定,则表示选取所有分区。指定该参数时需要注意以下事项:
对于分区表:
至少会选择1个分区,即当
partitionSampling
是浮点数,且
partitionSampling * 分区总个数小于1时,会选取1个分区;当
partitionSampling
* 分区总个数是大于1,但不是一个整数时,则向下取整。比如
partitionSampling
=0.26,分区总个数为10,则会随机选取2个分区。
若指定的分区个数大于实际分区数量,则会选择所有分区。
对于非分区表,指定该参数不会生效;
返回值
返回一个内存表,包含最小值、最大值、计数、均值、标准差和指定的百分位数(以升序输出)。
例子
n=2022
data=1..n
value=take(1..3,n)
name=take(`APPLE`IBM`INTEL,n)
t=table(data,value,name);
summary(t, precision=0.001);
// name 非数值类型,不会输出到表中
输出返回:
name
min
max
nonNullCount
count
avg
std
percentile
data
1
2,022
2,022
2,022
1,011.5
583.8454
[506.24,1011.50,1516.75]
value
1
3
2,022
2,022
2
0.8167
[1.00,1.99,2.99]
n = 5000
data1 = take(1..5000000, n)
data2 = rand(10000000, n)
data3 = take("A" + string(0..10), n)
t = table(data1, data2, data3)
dbname = "dfs://summary"
if(existsDatabase(dbname)) {
dropDatabase(dbname)
}
db = database(dbname, HASH, [INT, 10])
pt = createPartitionedTable(db, t, `pt, `data1)
pt.append!(t)
ds = sqlDS(<select data1,data2 from loadTable(db, `pt)>)
query_percentile = [25,50,75,90]
ds_re1 = summary(ds);
// 返回第25, 50, 75, 90 百分位值
ds_re2 = summary(ds, percentile=query_percentile, precision=0.0001);
// 分区占比为 0.6,即统计6个分区数据的信息
ds_re3 = summary(loadTable(db, `pt), percentile=query_percentile, precision=0.0001, partitionSampling=0.6);
FILE:references/doc_6990.md
# slice
**URL**: https://docs.dolphindb.cn/zh/funcs/s/slice.html
**来源**: DolphinDB 官方文档
---
slice
语法
slice(obj, index)
或
slice(obj, rowIndex, [colIndex])
相当于
obj[index]
或
obj[rowIndex, colIndex]
详情
对于第一种用法:
如果
obj
是一个数组向量,
index
是标量,返回指定的列,用向量表示。
index
是向量,返回指定行组成的数组向量。
index
是数据对,返回指定列组成的数组向量。
如果
obj
是一个矩阵,
index
是标量,返回指定的列,用向量表示。
index
是向量或数据对,返回指定列组成的子矩阵。
如果
obj
是一个表,
index
是标量,返回指定的行,用字典表示。
index
是向量或数据对,返回指定行组成的子表。
对于第二种用法:
如果
obj
是一个数组向量,
rowIndex
和
colIndex
都是标量,返回指向行列的值,用向量表示。
rowIndex
是标量,
colIndex
是数据对,返回由指定行列组成的数组向量。
rowIndex
是数据对,
colIndex
是标量,返回由指定行列组成的向量。
rowIndex
和
colIndex
都是数据对,返回由指定行列组成的数组向量。
如果
obj
是一个矩阵,
rowIndex
和
colIndex
都是标量,返回指定行列的值,用标量表示。
rowIndex
和
colIndex
中一个是标量,另一个是数据对,返回由指定行列组成的子矩阵。
rowIndex
和
colIndex
都是向量或数据对,返回指定行列组成的子矩阵。
如果
obj
是一个表,
rowIndex
和
colIndex
都是标量,返回指定行列的值,用标量表示。
rowIndex
和
colIndex
中一个是标量,另一个是数据对,返回指定行列组成的子表。
rowIndex
和
colIndex
都是向量或数据对,返回指定行列组成的子表。
注:
index
,
rowIndex
,
collIndex
作为
数组向量或
矩阵的索引值或索引范围时,若其值不在 [0, size(X)-1] 内,则超出 [0, size(X)-1]
的值所对应的位置返回空值。
参数
obj
可以是
数组向量、
矩阵或表。
index
,
rowIndex
和
colIndex
可以是标量、向量或数据对,表示行或列的下标。如果
index
,
rowIndex
或
colIndex
为数据对,那么它表示下标的范围,上边界不包含在内。
返回值
返回向量、数组向量、矩阵或表。
例子
例1. 矩阵
m=1..9$3:3
m.slice(0);
[1,2,3]
m.slice([0]);
#0
1
2
3
m.slice(0:2);
#0
#1
1
4
2
5
3
6
m.slice(0 2);
#0
#1
1
7
2
8
3
9
m.slice(0,1);
// output
4
m.slice(0 1,0 1);
#0
#1
1
4
2
5
m.slice(1:2,1:2);
#0
5
例2. 表
t=table(`A`B`C as sym,2018.01.01..2018.01.03 as date,10 48 5 as val)
t.slice(0);
// output
val->10
date->2018.01.01
sym->A
t.slice([0]);
sym
date
val
A
2018.01.01
10
t.slice(0 1);
sym
date
val
A
2018.01.01
10
B
2018.01.02
48
t.slice(0:1);
sym
date
val
A
2018.01.01
10
t.slice(0,1);
// output
2018.01.01
t.slice(0 1,0 1);
sym
date
A
2018.01.01
B
2018.01.02
t.slice(1:2,1:2);
date
2018.01.02
例3. 数组向量
av =array(DOUBLE[], 0, 10).append!([1.0, 2.1 4.1 6.8, 0.5 2.2 2]);
av[1]
// output
[,4.1,2.2]
av[1,1]
// output
[4.1]
av[1:3,1:3]
// output
[[4.1,6.8],[2.2,2]]
FILE:references/doc_6992.md
# renameSchema
**URL**: https://docs.dolphindb.cn/zh/funcs/r/renameSchema.html
**来源**: DolphinDB 官方文档
---
renameSchema
语法
renameSchema(catalog, oldSchema, newSchema)
详情
重命名 schema。
参数
catalog
字符串标量,表示 catalog 的名称。
oldSchema
字符串标量,表示要修改的 schema 的原名称。
newSchema
字符串标量,表示要修改的 schema 的新名称。
例子
renameSchema("catalog1", "schema1", "schema2")
FILE:references/doc_6994.md
# linearInterpolateFit
**URL**: https://docs.dolphindb.cn/zh/funcs/l/linearinterpolatefit.html
**来源**: DolphinDB 官方文档
---
linearInterpolateFit
语法
linearInterpolateFit(X, Y, [fillValue], [sorted=false])
详情
为一组点集进行线性插值,支持内插(interpolate)和外插(extrapolate)两种模式。内插用于估计已知数据点之间的未知值,而外插则用于估计已知数据点范围之外的未知值。
参数
X
数值向量,表示用于插值的点的 x 坐标。注意:
X 的长度至少为 2,即至少需要两个已知数据点才能进行插值。
X中的值必须是唯一的且不可包含 NULL 值。
Y
数值向量,表示用于插值的点的 y 坐标。注意:
Y
和
X
的长度必须一致,且不包含 NULL 值。
fillValue
可选参数,表示位于已知数据点范围之外的预测数据的赋值方式。支持以下两种方式:
形如
(below, above)
的数值类型数据对,below 和 above 分别表示当预测数据小于 X
的最小值或大于 X 的最大值时的赋值。具体含义如下,X
min
和 X
max
分别表示输入参数
X
向量中的最小值和最大值。
当预测数据 X
new
< X
min
,将其赋值为 below;
当预测数据 X
new
> X
max
,将其赋值为 above。
字符串 “extrapolate”,表示进行外插赋值,为默认值。
sorted
可选参数,布尔值标量,表示输入参数 X 是否有序递增。
如果为 true,则
X
必须是递增序列。
如果为 false,函数内部会对
X
进行排序,并相应调整
Y
的顺序。默认为 false。
返回值
一个字典,包含以下 key:
modelName:字符串类型,表示模型名称,值为 “linearInterpolate”。
sortedX:Double 类型向量,表示对输入
X
进行升序排序后的向量。
sortedY:Double 类型向量,表示与
sortedX
所对应的 y 值。
fillValue:表示外插方式,即输入的
fillValue
参数值。
predict:模型的预测函数,
predict
函数将返回在新 X 点处的线性插值结果。可通过
model.predict(X)
或
predict(model, X)
进行调用。其中:
model:字典类型,即
linearInterpolateFit
的输出。
X: 数值向量,表示需要求值的点的 x 坐标。
例子
通过自定义函数 linspace 创建一组点集,对其进行线性插值。
def linspace(start, end, num, endpoint=true){
if(endpoint) return end$DOUBLE\(num-1), start + end$DOUBLE\(num-1)*0..(num-1)
else return start + (end-start)$DOUBLE\(num)*0..(num-1)
}
x = 0..9
y = exp(-x/3.0)
model = linearInterpolateFit(x, y, sorted=true)
/*Output
sortedX->[0.0,1.000000000000,2.000000000000,3.000000000000,4.000000000000,5.000000000000,6.000000000000,7.000000000000,8.000000000000,9.000000000000]
modelName->linearInterpolate
predict->linearInterpolatePredict
fillValue->extrapolate
sortedY->[1.000000000000,0.716531310573,0.513417119032,0.367879441171,0.263597138115,0.188875602837,0.135335283236,0.096971967864,0.069483451222,0.049787068367]
*/
// 使用新 X 值进行预测
xnew = linspace(0,9,15,false)
model.predict(xnew)
//Output:[1,0.829918786344274,0.67590847226555,0.554039957340832,0.455202047888132,0.367879441171442,0.305310059338013,0.248652831060094,0.203819909893195,0.167459474997182,0.135335283236613,0.112317294013288,0.091474264536084,0.074981154551122,0.061604898080826]
FILE:references/doc_7001.md
# mcovar
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mcovar.html
**来源**: DolphinDB 官方文档
---
mcovar
语法
mcovar(X, Y, window, [minPeriods])
参数说明和窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内,计算
X
和
Y
元素的协方差。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
Y
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
计算结果为 DOUBLE 类型,形式同输入参数。
例子
x=1..10;
y=9 5 3 4 5 4 7 1 3 4;
mcovar(x,y,5);
// output: [,,,,-2.25,0,2,-1,-1.75,-1]
mcovar(x, y, 5, 3);
// output: [,,-3,-2.833333,-2.25,0,2,-1,-1.75,-1]
x1 = indexedSeries(date(2020.06.05)+1..10, x)
y1 = indexedSeries(date(2020.06.05)+1..10, y)
mcovar(x1,y1,5d)
label
col1
2020.06.06
2020.06.07
-2
2020.06.08
-3
2020.06.09
-2.8333
2020.06.10
-2.25
2020.06.11
0
2020.06.12
2
2020.06.13
-1
2020.06.14
-1.75
2020.06.15
-1
mcovar(x1,y1,1w)
label
col1
2020.06.06
2020.06.07
-2
2020.06.08
-3
2020.06.09
-2.8333
2020.06.10
-2.25
2020.06.11
-2.4
2020.06.12
-1
2020.06.13
-0.6667
2020.06.14
-0.6667
2020.06.15
-1.6667
相关函数:
covar
FILE:references/doc_7002.md
# rand
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rand.html
**来源**: DolphinDB 官方文档
---
rand
语法
rand(X, [count])
详情
返回一个与
X
类型相同的随机标量/向量/矩阵。
如果
X
是标量,
X
必须为大于 0 且为数值类型,生成的随机数服从 [0, X) 下的均匀分布。
如果
X
是向量,返回从
X
中随机选取的元素。
参数
X
标量或向量。
count
可选参数,INT 型标量或数据对。
若不指定
count
,返回一个标量。
若为标量,表示输出向量的长度。
若为数据对,表示输出矩阵的维度。
返回值
返回一个与
X
类型相同的随机标量/向量/矩阵。
例子
// 不指定count,生成一个随机标量
rand(2)
// output: 0
rand(1 2 5)
// output: 1
// 生成 20 个小于 10 的随机非负整数
rand(10, 20);
// output:[9,9,8,1,1,0,8,3,2,6,4,6,9,6,8,9,3,2,1,5]
// 生成 10 个 小于 9.8 的随机非负浮点数
rand(9.8, 10);
// output:[3.653754,1.750518,0.055747,5.219222,2.473778,6.337576,7.797493,1.392241,0.149499,5.697612]
// 生成 3 个随机从向量 x 中选取的值
x=3 5 4 6 9;
rand(x, 3);
// output:[9,3,6]
// 生成一个小于10的 2*2 的随机矩阵
rand(10.0, 2:2)
col1
col2
0.8233
1.0052
7.1127
9.7578
12:35:06 + rand(100, 10);
//output:[12:35:44,12:35:16,12:35:50,12:35:44,12:35:46,12:35:09,12:35:50,12:36:35,12:35:09,12:36:44]
x=`IBM`C`AAPL`BABA;
rand(x, 10);
// output:["IBM","BABA","C","AAPL","IBM","C","BABA","AAPL","BABA","BABA"]
rand(x,2:3)
#0
#1
#2
BABA
AAPL
BABA
C
AAPL
AAPL
FILE:references/doc_7012.md
# subscribeStreamingSQL
**URL**: https://docs.dolphindb.cn/zh/funcs/s/subscribeStreamingSQL.html
**来源**: DolphinDB 官方文档
---
subscribeStreamingSQL
语法
subscribeStreamingSQL([server],
queryId,[batchSize=0],[throttle=1],[hash=-1])
详情
订阅指定的流式 SQL 查询结果。订阅端会接收增量日志,并基于这些日志维护一个实时更新的共享结果表,保证查询结果随数据变更持续刷新。
参数
server
可选参数,字符串标量,表示运行流式 SQL 查询的节点(即注册该查询的服务器)的别名或远程连接句柄。如果未指定或者为空字符串,表示流式 SQL
查询所在的服务器是本地实例。
queryId
字符串标量,表示要订阅的流式 SQL 查询 ID。
batchSize
可选参数,整数标量,默认值为0。
正数:累计未处理日志数达到
batchSize
时才处理。
非正数或未指定:每批日志到达即处理。
throttle
可选参数,浮点数,单位为秒,默认值为1。表示继上次处理日志消息之后,若
batchSize
条件一直未达到,多久后再次处理消息。
如果没有指定
batchSize
,
throttle
即使指定,也不起作用。
若
throttle
需要设置小于1秒,则需要先修改配置项
subThrottle
。
hash
可选参数,非负整数,指定由某个订阅线程处理进入的日志消息。如果没有指定该参数,系统会自动分配一个线程。如果需要使用同一个线程来处理多个订阅任务的消息,可把这些订阅任务的
hash 设置为相同的值。
返回值
一个表,包含流式 SQL 查询结果列。
例子
t=table(1..10 as id,rand(100,10) as val)
share t as st
declareStreamingSQLTable(st)
registerStreamingSQL("select avg(val) from st","sql_avg")
subscribeStreamingSQL(queryId="sql_avg")
avg_val
64.3
相关函数:
declareStreamingSQLTable
,
registerStreamingSQL
,
unsubscribeStreamingSQL
FILE:references/doc_7013.md
# loadMvccTable
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadMvccTable.html
**来源**: DolphinDB 官方文档
---
loadMvccTable
语法
loadMvccTable(path, tableName)
详情
把磁盘上可并发读写的表加载到内存中。
参数
path
是一个字符串,表示绝对路径或相对路径。
tableName
是一个字符串,表示表名。
返回值
一张表。
例子
n=5
syms=`IBM`C`MS`MSFT`JPM`ORCL`FB`GE
timestamp=09:30:00+rand(18000,n)
sym=rand(syms,n)
qty=100*(1+rand(100,n))
price=5.0+rand(100.0,n)
temp=table(timestamp,sym,qty,price)
t1= mvccTable(1:0,`timestamp`sym`qty`price,[TIMESTAMP,SYMBOL,INT,DOUBLE],"/home/DolphinDB/Data","t1")
t1.append!(temp);
loadMvccTable("/home/DolphinDB/Data","t1");
timestamp
sym
qty
price
1970.01.01T00:00:39.091
MSFT
4500
99.808702
1970.01.01T00:00:35.293
FB
3600
26.644715
1970.01.01T00:00:36.334
MSFT
3800
66.754334
1970.01.01T00:00:40.362
ORCL
4800
15.480288
1970.01.01T00:00:35.565
MSFT
1700
23.107408
FILE:references/doc_7022.md
# mode
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mode.html
**来源**: DolphinDB 官方文档
---
mode
语法
mode(X)
详情
若
X
为向量,计算
X
中出现次数最多的值。
若
X
为矩阵/表,计算其每列中出现次数最多的值,返回一个向量/表。
该函数通过 hash table 统计
X
中唯一值(key)出现的次数,当有多个次数最多的 key 时,返回
hash table 中的第一个 key。与所有其它聚合函数一致,该函数在计算时忽略 NULL 值。
注:
对于不同数据类型,该函数采用的 hash 算法不相同,因此输出结果可能不同。
参数
X
可以是标量、向量、矩阵或表。
返回值
当
X
是标量或向量时,返回一个整型标量。
当
X
是矩阵时,返回一个整型向量。
当
X
是表时,返回一个表。
例子
mode 2;
// output: 2
mode 1 3 3 3 4 5 5;
// output: 3
mode `test;
// output: test
m=matrix(1 1 2 2 2 3, 4 4 5 6 6 6);
m;
#0
#1
1
4
1
4
2
5
2
6
2
6
3
6
mode m;
// output: [2,6]
相关的中心趋势函数:
mean
和
med
FILE:references/doc_7031.md
# warmupComputeNodeCache
**URL**: https://docs.dolphindb.cn/zh/funcs/w/warmupcomputenodecache.html
**来源**: DolphinDB 官方文档
---
warmupComputeNodeCache
语法
warmupComputeNodeCache(sqlObj, [parallelism])
详情
创建数据预热任务,将指定数据缓存至计算组。
参数
sqlObj
SQL 元代码,表示预热的数据。
parallelism
可选参数,正整数,表示分配给该任务的线程数上限。
返回值
任务的 jobId。
例子
warmupComputeNodeCache(sqlObj=<select * from loadTable("dfs://test","pt") where date>=2025.04.01>, parallelism=3)
FILE:references/doc_7033.md
# vectorAR
**URL**: https://docs.dolphindb.cn/zh/funcs/v/vectorar.html
**来源**: DolphinDB 官方文档
---
vectorAR
语法
vectorAR(ds, endogColNames, [exog], [trend='c'], [maxLag],
[ic])
详情
使用向量自回归模型(Vector Autoregression model,简称 VAR 模型)来分析多变量时间序列。
参数
ds
一张内存表、或者一个 DataSource 类型构成的向量,包含需要分析的多变量时间序列。注意:不可为空。
endogColNames
字符串向量,表示需要分析的内生变量(endogenous variable)在
ds
中所对应的列名。通过
endogColNames
从
ds
中取出的列组成的矩阵,即为需要分析的多变量时间序列数据。
exog
可选参数,数值矩阵,表示时间序列数据之外的外生变量。矩阵每一列表示一个外生变量的时间序列数据,矩阵行数为时间序列样本数,须与
ds
的行数相等。
trend
可选参数,表示在回归中使用的常数和趋势阶数。可选值为:
'c':只使用常数,默认值。
'ct':使用常数和趋势。
'ctt':使用常数、线性趋势和二次趋势。
'n':不适用常数和趋势。
maxLag
可选参数,非负整数标量,表示在选择阶数时使用的最大滞后期。传入空值或不填时使用默认值:
,nobs 表示样本数量。
ic
可选参数,字符串标量,表示在选择阶数时使用的信息准则类型,默认值为空值。可选值为:
'aic':Akaike 信息准则。
'bic':Bayesian 信息准则。
'fpe':Final prediction error,最终预测误差准则。
'hqic':Hannan-Quinn 信息准则。
返回值
返回一个字典,表示向量自回归模型的分析结果,字典有以下成员:
params:浮点数矩阵,表示向量自回归模型拟合得到的参数。
kAr:整数标量,表示向量自回归过程的阶数。
kTrend:整数标量,表示向量自回归过程的趋势数。
nobs:整数标量,表示向量自回归模型分析过程中的观测数量。
sigmaU:浮点数矩阵,表示白噪声过程方差的估计值。
sigmaUMle:浮点数矩阵,表示噪声过程协方差的有偏最大似然估计值。
aic:浮点数标量,表示 Akaike 信息准则。
bic:浮点数标量,表示 Bayesian 信息准则。
hqic:浮点数标量,表示 Hannan-Quinn 信息准则。
fpe:浮点数标量,表示最终预测误差信息准则。
llf:浮点数标量,表示向量自回归模型的对数似然值。
例子
本例提供一个
macrodata.csv
文件。取该文件中
realgdp, realcons, realinv 三列作为内生变量,并设置最大滞后期
maxlag
为 2,使用 VAR
模型来分析其多变量时间序列。
data = loadText("macrodata.csv")//该文件需要另外下载,请点击上方文本内的链接
vectorAR(data, [`realgdp, `realcons, `realinv],,,2)
/*
output:
nobs->200
hqic->-27.789187688321
llf->1962.570824044325
kTrend->1
aic->-27.929339439671
fpe->0E-12
params->
#0 #1 #2
0.001526972352 0.005459603048 -0.023902520885
-0.279434735873 -0.100467978082 -1.970973673795
0.675015751748 0.268639552522 4.414162326990
0.033219450793 0.025738726522 0.225478953223
0.008221084912 -0.123173927706 0.380785849237
0.290457628129 0.232499435917 0.800280917529
-0.007320907532 0.023503761040 -0.124079061576
sigmaU->
#0 #1 #2
0.000057113648 0.000029839495 0.000224637467
0.000029839495 0.000042830532 0.000034191732
0.000224637467 0.000034191732 0.001567709895
sigmaUMle->
#0 #1 #2
0.000055114670 0.000028795112 0.000216775156
0.000028795112 0.000041331464 0.000032995021
0.000216775156 0.000032995021 0.001512840049
kAr->2
bic->-27.583016116183
*/
FILE:references/doc_7039.md
# hasNull
**URL**: https://docs.dolphindb.cn/zh/funcs/h/hasNull.html
**来源**: DolphinDB 官方文档
---
hasNull
语法
hasNull(X)
详情
判断
X
中是否包含 NULL 值。
如果
X
是标量,当
X
为 NULL 值时,该函数返回 true。
如果
X
是向量,当
X
中至少有一个元素为 NULL 时,该函数返回
true。
如果
X
是矩阵或表,当
X
中至少有一列包含 NULL 值时,该函数返回
true。
参数
X
可以是标量、向量、矩阵或表。
返回值
一个布尔值。
例子
hasNull NULL;
// output
true
x=00f;
hasNull x;
// output
true
hasNull 5;
// output
false
hasNull(1 2 NULL 4 NULL 6);
// output
true
x=((NULL,1),2);
hasNull x;
// output
false
m=(1 NULL 3 4 5 6)$2:3;
hasNull m;
// output
true
t=table(`AAPL`IBM`MSFT as sym, 2200 NULL 4500 as qty);
hasNull(t);
// output
true
相关函数:
isNull
,
nullFill
FILE:references/doc_7042.md
# isNull
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isNull.html
**来源**: DolphinDB 官方文档
---
isNull
语法
isNull(X)
详情
用于检查是否是 NULL 值。如果元素是 NULL,返回 true。
注:
自 2.00.5 版本开始,当
X
是字典、元组、数据向量或表时,该函数将检查每一行中的元素是否是
NULL 值,返回一个具有相同维度的字典、元组或表。
参数
X
可以是标量、数据对、向量、字典、矩阵或内存表。
返回值
返回布尔类型,数据形式同 X。
例子
isNull(00i);
// output: true
isNull(1 NULL NULL 6 NULL 7);
[0,1,1,0,1,0]
isNull(1/0);
// output: true
x=1 NULL 5 NULL 4 6$2:3;
x;
#0
#1
#2
1
5
4
6
isNull(x);
#0
#1
#2
false
false
false
true
true
false
t=table(1 2 3 as id, `a`b`c as name, 10 NULL 7 as vol)
isNull(t)
id
name
vol
false
false
false
false
false
true
false
false
false
相关函数:
hasNull
,
nullFill
FILE:references/doc_7043.md
# isTitle
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isTitle.html
**来源**: DolphinDB 官方文档
---
isTitle
语法
isTitle(X)
详情
判断字符串中每个单词的第一个字母是否为大写,其他字母都为小写。对于不包含字母的字符串和空字符串,该函数返回 false。
参数
X
可以是字符串标量或向量。
返回值
布尔标量或向量。
例子
isTitle("Hello World");
// output: true
isTitle("Hello world");
// output: false
isTitle(["Hello","468"," "]);
// output: [true,false,false]
isTitle("1And1");
// output: true
相关函数:
isLower
,
isUpper
FILE:references/doc_7044.md
# getTablesByCluster
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getTablesByCluster.html
**来源**: DolphinDB 官方文档
---
getTablesByCluster
语法
getTablesByCluster(clusterName, dbUrl)
详情
获取集群指定数据库下的所有表。只能由管理员在 MoM(Master of Master,管理集群)上执行该函数。
参数
clusterName
字符串标量,表示要查询的集群名称。
dbUrl
字符串标量,表示要查询的数据库路径。
返回值
字符串向量。
例子
// MoMSender 集群数据节点:
db = database(directory="dfs://db1", partitionType=RANGE, partitionScheme=0 5 10)
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
sym = `C`MS`MS`MS`IBM`IBM`C`C`C
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
t = table(timestamp, sym, qty, price);
dt=db.createDimensionTable(t,`dt).append!(t);
// MoM 集群:
getTablesByCluster("MoMSender", "dfs://db1")
// Output: ["dt"]
FILE:references/doc_7051.md
# asis
**URL**: https://docs.dolphindb.cn/zh/funcs/a/asIs.html
**来源**: DolphinDB 官方文档
---
asis
语法
asis(obj)
详情
返回
obj
的引用。
参数
obj
可以是任意数据类型。
返回值
数据类型与数据形式与
obj
相同。
例子
a = 1 2 3
b = asis(a)
a[0] = 0
b
// output
[0, 2, 3]
b[1] = 4
// output
a;
[0, 4, 3]
相关函数:
copy
,
deepCopy
FILE:references/doc_7054.md
# getPrefetchComputeNodeData
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getprefetchcomputenodedata.html
**来源**: DolphinDB 官方文档
---
getPrefetchComputeNodeData
语法
getPrefetchComputeNodeData()
详情
当前节点下配置项
enableComputeNodePrefetchData
的生效值。
参数
无
返回值
布尔标量。
例子
getPrefetchComputeNodeData()
// output: false
相关函数:
setPrefetchComputeNodeData
FILE:references/doc_7063.md
# nunique
**URL**: https://docs.dolphindb.cn/zh/funcs/n/nunique.html
**来源**: DolphinDB 官方文档
---
nunique
语法
nunique(X, [ignoreNull=false])
详情
X
是向量/数组向量时,计算
X
中唯一值的数量。
X
是元组时,其内每个向量位于相同位置的元素组成一个 key,计算唯一 key 的数量。
参数
X
是一个向量/数组向量,或包含多个等长向量的元组。
ignoreNull
是一个布尔值,表示是否忽略
X
中 NULL 值。若指定
ignoreNull
=true,则统计唯一值时将不考虑 NULL 值;否则将会统计 NULL 值。默认值为 false。请注意,当
X
是元组或数组向量时,不可指定
ignoreNull
=true。
返回值
INT 类型标量。
例子
v = [1,3,1,-6,NULL,2,NULL,1];
nunique(v);
// output: 5
//指定 ignorNull = true,统计唯一值时将不考虑 NULL 值
nunique(v,true);
// output: 4
a = array(INT[], 0, 10).append!([1 2 3, 3 5, 6 8 8, 9 10])
nunique(a)
// output: 8
t=table(1 2 4 8 4 2 7 1 as id, 10 20 40 80 40 20 70 10 as val);
select nunique([id,val]) from t;
nunique
5
dbName = "dfs://testdb"
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db=database("dfs://testdb", VALUE, 2012.01.11..2012.01.29)
n=100
t=table(take(2012.01.11..2012.01.29, n) as date, symbol(take("A"+string(21..60), n)) as sym, take(100, n) as val)
pt=db.createPartitionedTable(t, `pt, `date).append!(t)
select nunique(date) from pt group by sym
FILE:references/doc_7065.md
# brentq
**URL**: https://docs.dolphindb.cn/zh/funcs/b/brentq.html
**来源**: DolphinDB 官方文档
---
brentq
语法
brentq(f, a, b, [xtol], [rtol], [maxIter],
[funcDataParam])
详情
使用 Brent 方法在一个给定区间 [a, b] 内求出函数 f(x) 的一个根 x0,使得 f(x0)=0 ,求解精度满足
|x-x0| <=
(xtol + rtol* |x0| )
,其中 x 是精确根,x0 为计算结果。
参数
f
是一个返回值为一个数值的函数。函数在 [a, b] 内连续且 f(a) 与 f(b) 的正负号需要相反。
a
是一个数值标量,指定区间的左边界。
b
是一个数值标量,指定区间的右边界。
xtol
是一个数值标量,用于指定求解结果的精度,默认值为 2e-12。
rtol
是一个数值标量,用于指定求解结果的精度,默认值为 4 倍的 DOUBLE 类型的机器精度。
maxIter
是一个整形标量,指定 Brent 的最大迭代次数,默认值为 100 。
funcDataParam
是一个向量,指定函数 f 的其他参数。
返回值
返回值为长度为2的向量 res:
res[0] 是一个字符串标量,表示求解状态。共有三种求解状态:
CONVERGED, 表示得到符合预期的解;
SIGNERR,表示 f(a) 与 f(b) 同号,不满足正负号相反的要求;
CONVERR,表示达到最大迭代次数
res[1] 是一个数值标量,表示求得的根。
例子
求解 f(x) = x^2 - 1 在 [-2,0], [0,2] 的根
def f(x) {
return (pow(x, 2) - 1)
}
root1 = brentq(f, -2, 0)
root2 = brentq(f, 0, 2)
print("root1 : ", root1)
print("root2 : ", root2)
返回如下:
root1 :
("CONVERGED",-1)
root2 :
("CONVERGED",1)
求解带有额外参数的函数 f(x,b) 在 [0,2] 的根:
def f(x, b) {
return (pow(x, 2) - b)
}
root = brentq(f, 0, 2, 2e-12, 1e-9, 100, [2])
print("root : ", root)
返回如下:
root :
("CONVERGED",1.414213562373136)
FILE:references/doc_7067.md
# setColumnComment
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setColumnComment.html
**来源**: DolphinDB 官方文档
---
setColumnComment
语法
setColumnComment(table, columnComments)
详情
给分布式表
或 mvcc 表
的列添加注释。通过
schema
函数可以查看各列的注释。
参数
table
是一个分布式表
或 mvcc 表
。
columnComments
是一个字典,其中 key 表示表中的列,value 表示各列的注释。
例子
n=1000000
sym=rand(`A`B`C`D`E`F,n)
date=rand(2019.06.01..2019.06.10,n)
open=rand(100.0,n)
high=rand(200.0,n)
close=rand(200.0,n)
pre_close=rand(200.0,n)
change=rand(100.0,n)
vol=rand(10000,n)
amount=rand(100000.0,n)
t=table(sym,date,open,high,close,pre_close,change,vol,amount);
db1=database("",VALUE,2019.06.01..2019.06.10)
db2=database("",VALUE,`A`B`C`D`E`F)
db=database("dfs://db1",COMPO,[db1,db2])
pt=db.createPartitionedTable(t,`pt,`date`sym).append!(t);
setColumnComment(pt,{sym:"股票代码",date:"交易日期",open:"开盘价",high:"最高价",close:"收盘价",pre_close:"昨收价",change:"涨跌额",vol:"成交量(手)",amount:"成交额(千元)"})
schema(pt).colDefs;
name
typeString
typeInt
comment
sym
SYMBOL
17
股票代码
date
DATE
6
交易日期
open
DOUBLE
16
开盘价
high
DOUBLE
16
最高价
close
DOUBLE
16
收盘价
pre_close
DOUBLE
16
昨收价
change
DOUBLE
16
涨跌额
vol
INT
4
成交量(手)
amount
DOUBLE
16
成交额(千元)
id=`XOM`GS`AAPL
x=102.1 33.4 73.6
mt = mvccTable(id, x);
setColumnComment(mt, {id:"标识符"})
schema(mt).colDefs
name
typeString
typeInt
extra
comment
id
STRING
18
标识符
x
DOUBLE
16
FILE:references/doc_7074.md
# tableUpsert
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tableUpsert.html
**来源**: DolphinDB 官方文档
---
tableUpsert
语法
tableUpsert(obj, newData, [ignoreNull=false], [keyColNames],
[sortColumns])
详情
将新数据写入索引内存表、键值内存表,或者 DFS 表。若新数据的主键值已存在,更新该主键值的数据;否则添加数据。
tableUpsert
与
upsert!
的用法一致,区别在于
tableUpsert
会返回操作行数,而
upsert!
进行了就地修改,用于链式操作。
注:
调用该函数时,需要保证
newData
和
obj
两表各列的顺序一致,否则可能产生错误结果或报错。
若
keyColNames
指定的列存在重复值,对重复值进行
tableUpsert
操作,仅会更新第一个值所在行,其余值所在行不会更新。
函数行为会受到配置参数
enableNullSafeJoin
的影响:
当
enableNullSafeJoin
=true 时,连接列中的 NULL
值可以匹配成功,
tableUpsert
可能会更新包含 NULL
的记录;
当
enableNullSafeJoin
=false 时,连接列中的 NULL
值无法匹配,
tableUpsert
不会更新此类记录。
参数
obj
是一个索引内存表、键值内存表,或者 DFS 表(分布式表或维度表)。
newData
是一个内存表,且与
obj
的结构一样。
ignoreNull
是一个布尔值,表示若
newData
中某元素为 NULL
值,是否忽略对目标表中的相应数据进行更新。默认值为 false。
keyColNames
是一个字符串标量或向量。由于 DFS 表没有键值列,对 DFS
表进行更新时,将该参数指定的列和分区列一起视为键值列。
sortColumns
是一个字符串标量或向量。设置该参数,更新的分区内的所有数据会根据指定的列进行排序。排序在每个分区内部进行,不会跨分区排序。
注:
仅 OLAP 引擎下使用
upsert!
时,才支持设置
sortColumns
。
要设置
sortColumns
,
obj
必须为分布式表。
仅对同一个分区内的数据 按照
sortColumns
进行排序,不同分区之间的数据不会进行排序。
obj
为一个空表时,设置
sortColumns
无效,即更新后不对新插入的数据进行排序。
在 PKEY 引擎下不支持设置
ignoreNull
,
keyColNames
,
sortColumns
。
返回值
LONG 类型数据对,第一个元素表示新插入的记录数,第二个元素表示更新的记录数。
例子
对键值内存表使用
tableUpsert
:
sym=`A`B`C
date=take(2021.01.06, 3)
x=1 2 3
y=5 6 7
t=keyedTable(`sym`date, sym, date, x, y)
newData = table(`A`B`C`D as sym1, take(2021.01.06, 4) as date1, NULL NULL 300 400 as x1, NULL 600 700 800 as y1);
tableUpsert(t, newData, ignoreNull=true)
// output
1:2
对索引内存表使用
tableUpsert
:
sym=`A`B`C
date=take(2021.01.06, 3)
x=1 2 3
y=5 6 7
t=indexedTable(`sym`date, sym, date, x, y)
newData = table(`A`B`C`D as sym1, take(2021.01.06, 4) as date1, NULL NULL 300 400 as x1, NULL 600 700 800 as y1);
tableUpsert(t, newData, ignoreNull=true)
// output
1:2
对 DFS 表使用
tableUpsert
:
ID=0 1 2 2
x=0.1*0..3
t=table(ID, x)
db=database("dfs://rangedb128", VALUE, 0..10)
pt=db.createPartitionedTable(t, `pt, `ID)
pt.append!(t)
t1=table(1 as ID, 111 as x)
tableUpsert(pt, t1, keyColNames=`ID)
// output
0:1
FILE:references/doc_7081.md
# talibNull
**URL**: https://docs.dolphindb.cn/zh/funcs/t/talibNull.html
**来源**: DolphinDB 官方文档
---
talibNull
语法
talibNull(args...)
详情
该函数对输入的每个 vector 处理后,返回一个由处理结果组成的 tuple。处理方式如下:
从0开始遍历每个 vector (v1, v2, …, vn) 的下标,若存在某个下标 i,满足 v1[i], v2[i],
..., vn[i] 均为非 NULL 值,则结果中下标对应 0 ~ i 的元素均取 NULL 值,下标 i 及之后的元素与原向量对应下标的元素保持一致。
参数
args...
是两个及以上的 vector,所有 vector 长度需保持一致。
返回值
返回一个元组,数据类型同输入的向量
args...
。
例子
下标为2时,所有向量对应元素满足全部非空,因此输出结果,在下标2之前的元素均被置为空。
talibNull(2 3 4 5 6, NULL 1 2 NULL 4, 7 NULL 9 10 11)
// output
([,,4,5,6],[,,2,,4],[,,9,10,11])
FILE:references/doc_7082.md
# makeKey
**URL**: https://docs.dolphindb.cn/zh/funcs/m/makeKey.html
**来源**: DolphinDB 官方文档
---
makeKey
语法
makeKey(args...)
详情
对于输入的多个
args
,将它们的值组合为一个 BLOB 标量或向量。返回的结果可用作字典或集合的 key。相较于
makeSortedKey
,
makeKey
不会保存组合值的排序结果。
参数
args
是多个标量或长度相同的向量。
返回值
BLOB 标量或向量。
例子
makeKey(`a1,`b1,`c1)
// output: a1b1c1
set(makeKey(1 2, 4 5))
re=makeKey(`a1`a2, `_1`_2)
dict(re,100 200)
// output
a2_2->200
a1_1->100
相关函数:
makeSortedKey
FILE:references/doc_7083.md
# reduce
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/reduce.html
**来源**: DolphinDB 官方文档
---
reduce
语法
reduce(func, X, [init], [assembleRule|consistent=false])
reduce:T(X, [init])
或
[init] <operator>:T X
表示不指定
assembleRule
,使用默认值
reduce:TC(X, [init])
或
[init] <operator>:TC X
表示指定
assembleRule
,此例中指定为 C(Consistent)
详情
该函数与
accumulate
的功能相同,唯一区别是返回值不同。
reduce
返回最后一个结果,而
accumulate
输出所有中间结果。关于函数功能描述,参见
accumulate
。
reduce
等同于以下伪代码的执行过程:
result=<function>(init,X[0]);
for(i:1~size(X)){
result=<function>(result, X[i]);
}
return result;
参数
func
函数。
当
func
是一元函数时,
X
可以是非负整数、一元函数或空值。
init
表示
func
的参数,必须指定。
func
是二元函数时,
X
是向量、矩阵或表。
init
表示初始值。
func
是三元函数时,
X
必须是一个
Tuple,包含2个元素,分别表示
func
的后两个参数。
assembleRule
可选参数,表示如何将子任务的结果合并为函数最终结果。接受一个整数或字符串作为输入,可选值如下:
0 (或 "D"):默认值,表示 DolphinDB
规则,即根据所有子任务的结果来决定最终输出的数据类型和形式。当所有子结果具有相同的数据类型和形式时,多个标量合并为一个向量、多个向量合并为一个矩阵、多个矩阵合并为一个元组、多个字典合并为一张表;否则将所有子结果合并为一个元组输出。
1(或 "C"):表示 Consistent
规则,即认为所有子结果的数据类型和形式都与第一个子结果相同,根据第一个子结果来选择最终结果的数据类型和形式。如果后续子任务返回的结果与第一个子任务的结果类型不一致,系统会尝试对后续结果进行类型转换。如果转换失败则抛出异常。因此,此规则只可在已知子结果的数据类型及形式一致时指定。此规则可使系统免于逐一缓存并检查每个子任务的计算结果,从而提升性能。
2(或 "U"):表示 Tuple 规则,系统不再对各子结果的类型和形式一致性进行检查,而是直接将子结果组装成一个元组输出。
3(或 "K"):表示 kdb+ 规则。与 DolphinDB 规则类似,都会根据所有子结果来决定最终结果形式。主要区别在于,kdb+
规则下,只要有任一子任务返回向量,则最终结果必为一个元组;而在 DolphinDB
规则下,子任务结果若均为长度相同的向量,则最终结果为一个矩阵。其他情况下,kdb+ 规则的输出与 DolphinDB 规则相同。
注:
自 2.00.15
/3.00.3
版本起,新增了
assembleRule
参数。该参数不仅实现了原
consistent
参数的功能,还提供了更多的结果合并选项。
consistent
是一个布尔值,默认值为 false,相当于
assembleRule
="D";若为 true,则相当于
assembleRule
="C"。为保持兼容性,用户仍可使用
consistent
参数。如果同时指定
assemble
和
consistent
,将以
consistent
的值为准。
assembleRule
也可在高阶函数对应的函数模式符号后指定,通过字符 D/C/U/K 表示。以
eachPre (:P)
为例,形如
sub:PU(X)
。不指定则使用默认值 D。
返回值
取决于
assembleRule
参数的值。
例子
func
是一元函数时:
通过以下方式定义一个一元函数:
def func1(x){
if(x<5){
return x*3
}
else{
return x+3
}
}
当 X 为整数时,迭代 X 次,输出最后一个结果:
reduce(func1, 5, 1)
返回:18
当 X 为一元函数 condition 时,第3次迭代时因 condition 返回false,停止迭代2次后停止,并输出最后一个结果。
def condition(x){
return x<9
}
reduce(func1, condition, 1)
返回:9
当 X 为 NULL(或不指定)时,自定义函数 func2 作为进行迭代的函数。
def func2(x){
if(x<5){
return x*3
}
else{
return 6
}
}
//因第4次迭代结果和第3次相同,停止迭代并输出最后一个结果。
reduce(func2,NULL,1)
返回:6
func
是二元函数时,在一个向量上执行
reduce
:
reduce(mul, 1..10);
返回:3628800,即 10 的阶乘。上例如果由
accumulate
高阶函数实现,则是:
*:A 1..10;
返回:[1,2,6,24,120,720,5040,40320,362880,3628800]
2 *:T 1..10;
返回:7257600
def f1(a,b):a+log(b);
reduce(f1, 1..5, 0);
返回:4.787492
对一个矩阵执行
reduce
:
x=1..12$3:4;
x;
得到:
col1
col2
col3
col4
1
4
7
10
2
5
8
11
3
6
9
12
+ :T x;
返回:[22,26,30]
func
是三元函数时:
def fun3(x,y,z){
return x+y+z
}
reduce(fun3,[[1,2,3],[10,10,10]],5)
返回:41
FILE:references/doc_710.md
# 节点内部订阅
**URL**: https://docs.dolphindb.cn/zh/stream/local_sub.html
**来源**: DolphinDB 官方文档
---
节点内部订阅
本节介绍节点内部订阅流处理结果的交互方式。对于节点内部订阅,发布端与订阅端在一个节点内,因此在订阅时不需要指定发布端 server。
下面为以逐笔成交数据为例介绍订阅流数据结果订阅及写入数据库的流程。
发布端创建一个共享的流数据表
tglobal
。
name = `ChannelNo`ApplSeqNum`MDStreamID`BidApplSeqNum`OfferApplSeqNum`SecurityID`SecurityIDSource`TradePrice`TradeQty`ExecType`TradeTime`LocalTime`SeqNo`DataStatus`TradeMoney`TradeBSFlag`BizIndex`OrderKind`Market
type = [INT,LONG,SYMBOL,LONG,LONG,SYMBOL,SYMBOL,DOUBLE,INT,SYMBOL,TIMESTAMP,TIME,LONG,INT,DOUBLE,SYMBOL,LONG,SYMBOL,SYMBOL]
share streamTable(
100
:
0
, name, type)
as
tglobal
订阅端创建一个分布式数据表,用于存储订阅到的数据。
if
(existsDatabase(
"dfs://tradeDB"
))
dropDatabase(
"dfs://tradeDB"
)
db1 = database(, VALUE,
2020.01
.
01.
.2021
.
01.01
)
db2 = database(, HASH, [SYMBOL,
50
])
db = database(
"dfs://tradeDB"
, COMPO, [db1, db2], ,
"TSDB"
)
name = `ChannelNo`ApplSeqNum`MDStreamID`BidApplSeqNum`OfferApplSeqNum`SecurityID`SecurityIDSource`TradePrice`TradeQty`ExecType`TradeTime`LocalTime`SeqNo`DataStatus`TradeMoney`TradeBSFlag`BizIndex`OrderKind`Market
type = [INT,LONG,SYMBOL,LONG,LONG,SYMBOL,SYMBOL,DOUBLE,INT,SYMBOL,TIMESTAMP,TIME,LONG,INT,DOUBLE,SYMBOL,LONG,SYMBOL,SYMBOL]
t = db.createPartitionedTable(table=table(
1
:
0
, name, type), tableName=
"tradeTB"
, partitionColumns=`TradeTime`SecurityID, sortColumns=[`SecurityID, `TradeTime])
创建表
tglobal
的本地订阅。将
handler
设置为需要写入的表
trades
,
batchSize
和
throttle
应根据需求合理设置,具体参数含义见
subscribeTable
。
trade = loadTable(
"dfs://tradeDB"
,
"tradeTB"
)
subscribeTable(tableName=
"tglobal"
, actionName=
"insertDB"
, offset=-
1
, handler=trade, msgAsTable=true, batchSize=
100000
, throttle=
60
)
向发布端流数据表
tglobal
写入模拟数据。
for
(i
in
1.
.100
){
insertData = [rand(
100
,
1
),long(i),string(i),long(i),long(i),string(i),string(i),rand(
1.0
,
1
),rand(
100
,
1
),string(i),timestamp(
'2021.01.04T09:30:02.000'
),time(
'09:30:02.000'
),long(i),rand(
100
,
1
),rand(
1.0
,
1
),string(i),long(i),string(i),string(i)]
insert into tglobal values(insertData)
}
查看写入接收端库表的数据。
select *
from
loadTable(
"dfs://tradeDB"
,
"tradeTB"
) limit
5
// output
ChannelNo ApplSeqNum MDStreamID BidApplSeqNum OfferApplSeqNum SecurityID SecurityIDSource TradePrice TradeQty ExecType TradeTime LocalTime SeqNo DataStatus TradeMoney TradeBSFlag BizIndex OrderKind Market
60
43
43
43
43
43
43
0.7538
56
43
2021.01
.
04
T09:
30
:
02.000
09
:
30
:
02.000
43
92
0.6234
43
43
43
43
56
59
59
59
59
59
59
0.1549
48
59
2021.01
.
04
T09:
30
:
02.000
09
:
30
:
02.000
59
94
0.428
59
59
59
59
60
92
92
92
92
92
92
0.198
13
92
2021.01
.
04
T09:
30
:
02.000
09
:
30
:
02.000
92
87
0.2109
92
92
92
92
57
41
41
41
41
41
41
0.0822
30
41
2021.01
.
04
T09:
30
:
02.000
09
:
30
:
02.000
41
32
0.2611
41
41
41
41
7
61
61
61
61
61
61
0.7593
81
61
2021.01
.
04
T09:
30
:
02.000
09
:
30
:
02.000
61
15
0.7564
61
61
61
61
当流数据订阅结束时,可以取消订阅并取消对流数据表的定义,取消流数据表定义需在对该表的订阅全部取消后进行。
//取消订阅
unsubscribeTable(tableName=
"tglobal"
, actionName=
"insertDB"
)
//取消定义流数据表
undef(`tglobal, SHARED)
FILE:references/doc_7103.md
# logisticRegression
**URL**: https://docs.dolphindb.cn/zh/funcs/l/logisticRegression.html
**来源**: DolphinDB 官方文档
---
logisticRegression
语法
logisticRegression(ds, yColName, xColNames, [intercept=true], [initTheta],
[tolerance=1e-3], [maxIter=500], [regularizationCoeff=1.0])
详情
计算数据源中
xColNames
和
yColName
逻辑回归的结果。
生成的模型可以作为
predict
函数的输入。
参数
ds
是数据源,通常是由
sqlDS
生成。
yColName
是字符串,表示数据源中作为因变量(所属分类)的列名。
xColNames
是字符串标量或向量,表示数据源中作为自变量的列名。
intercept
是布尔值,表示是否包含回归中的截距。默认值为True,系统会自动给自变量添加一列,该列的值全为1,用于生成截距。
initTheta
是迭代的初始参数向量。默认是长度为
xColNames.size()+intercept
的零向量。
tolerance
是迭代中止的边界差值 。如果在两次相邻迭代中,参数的对数似然函数的梯度的绝对值最大分量的差小于
tolerance
,迭代中止。默认值是0.001。
maxIter
是正整数,表示最大的迭代次数。当迭代次数达到
maxIter
时,迭代中止。默认值是500.
regularizationCoeff
是正数,表示正则项系数。默认值是1.0。
返回值
一个字典,包含以下 key:
iterations
,
modelName
,
coefficients
,
tolerance
,
logLikelihood
,
xColNames
和
intercept
。其中,
iterations
是实际迭代的次数;
modelName
是 “Logistic
Regression”;
coefficients
是向量,表示模型参数的估计值;
logLikelihood
是最终的对数似然值。
例子
以下例子把两个不同中心的正态分布标记为两类,然后计算逻辑回归模型。
t = table(100:0, `y`x0`x1, [INT,DOUBLE,DOUBLE])
y = take(0, 50)
x0 = norm(-1.0, 1.0, 50)
x1 = norm(-1.0, 1.0, 50)
insert into t values (y, x0, x1)
y = take(1, 50)
x0 = norm(1.0, 1.0, 50)
x1 = norm(1.0, 1.0, 50)
insert into t values (y, x0, x1)
model = logisticRegression(sqlDS(<select * from t>), `y, `x0`x1);
// output
modelName->Logistic Regression
logLikelihood->-23.269132
intercept->true
coefficients->[1.377971,1.914001,-0.305114]
xColNames->[x0,x1]
iterations->7
tolerance->0.001
把模型用于预测:
predict(model, t);
保存模型到磁盘:
saveModel(model, "C:/DolphinDB/data/logisticModel.txt");
加载一个保存的模型:
loadModel("C:/DolphinDB/data/logisticModel.txt");
FILE:references/doc_713.md
# socp
**URL**: https://docs.dolphindb.cn/zh/funcs/s/socp.html
**来源**: DolphinDB 官方文档
---
socp
语法
socp(f, [G], [h], [l], [q], [A], [b])
详情
该函数用于求解二阶锥规划问题,计算目标函数在限定条件下的最小值。若其约束条件以标准形式给出,其形式如下:
则矩阵 G 为:
向量 h 为:
参数
二阶锥规划(Second-Order Cone Programming,SOCP)问题的约束条件形式如下:
其中 K 为锥,s 为松弛变量,其值在优化过程中会被确定。
f
是数值型向量,表示目标函数的系数向量。
G
是数值型矩阵,表示锥约束的系数矩阵。
h
是数值型向量,表示锥约束的右端向量。
l
是整数标量,表示非负象限约束的维度。
q
是正数向量,表示各个二阶锥约束的维度大小,形式为 [r0,r1,…,rN-1]。
A
是数值型矩阵,表示等式约束的系数矩阵。
b
是数值型向量,表示等式约束的右端向量。
返回值
例子
求解以下二阶锥规划问题:
f = [-6, -4, -5]
G = matrix([[16, 7, 24, -8, 8, -1, 0, -1, 0],
[-14, 2, 7, -13, -18, 3, 0, 0, -1],
[5, 0, -15, 12, -6, 17, 0, 0, 0]])
h = [-3, 5, 12, -2, -14, -13, 10, 0, 0]
l = 2
q = [4,3]
re = socp(f,G,h,l,q, ,)
print(re)
返回:("Optimal solution
found",[-9.902804882871327,-1.39084684264198,26.211851780740154],-66.079042235904907)
FILE:references/doc_7143.md
# ifirstNot
**URL**: https://docs.dolphindb.cn/zh/funcs/i/ifirstNot.html
**来源**: DolphinDB 官方文档
---
ifirstNot
语法
ifirstNot(X)
详情
查找第一个非空元素的下标位置。
参数
X
可以是一个向量,也可以是由多个等长向量组成的元组,亦可是一个矩阵或表。
返回值
如果
X
是一个向量,返回第一个非空元素的下标。如果
X
中的所有元素都为空,返回-1。
如果
X
是一个元组,返回第一个所有向量中均不为空的位置的下标。
如果
X
是一个矩阵,返回每列中第一个非空元素的下标。返回一个向量。
如果
X
是一个表,返回每列中第一个非空元素的下标。返回一个表。
例子
ifirstNot(NULL NULL 2 4 8 NULL 1);
// output: 2
ifirstNot(take(int(),5));
// output: -1
x=NULL NULL 4 7 8 NULL
y=1 NULL NULL 4 NULL NULL
ifirstNot([x,y]);
// output: 3
x=NULL NULL 4 7 8 NULL
y=1 2 NULL NULL NULL 6
ifirstNot([x,y]);
// output: -1
m=matrix(0 NULL 1 2 3, NULL 2 NULL 0 3);
m;
#0
#1
0
2
1
2
0
3
3
ifirstNot(m);
// output: [0,1]
相关函数:
ilastNot
,
firstNot
,
lastNot
FILE:references/doc_7145.md
# polynomial
**URL**: https://docs.dolphindb.cn/zh/funcs/p/polynomial.html
**来源**: DolphinDB 官方文档
---
polynomial
语法
polynomial(X, coeffs)
详情
对于每个
X
中的元素,用多项式系数计算一个值。
参数
X
可以是标量或向量。
coeffs
是表示多项式系数向量。
返回值
返回一个和
X
相同长度的向量。
例子
计算
,
X
的取值是 1..10。
polynomial(1..10, 1 2 3);
// output
[6,17,34,57,86,121,162,209,262,321]
FILE:references/doc_7151.md
# keyedStreamTable
**URL**: https://docs.dolphindb.cn/zh/funcs/k/keyedStreamTable.html
**来源**: DolphinDB 官方文档
---
keyedStreamTable
语法
keyedStreamTable(keyColumn, X, [X1], [X2], .....)
或
keyedStreamTable(keyColumn, capacity:size, colNames, colTypes)
详情
创建键值流数据表。该表的主键不允许包含重复值。主键支持一个或多个字段。
实际应用中,可能由于网络原因,会出现数据重复提交写入的情况;或者在上游采用了多路高可用的方式写入数据。面对上述场景,键值流数据表可以实现流数据的幂等性写入,即多次写入键值相同的数据,其结果与第一次写入的结果相同,从而避免数据重复写入。
需要注意的是,此处的键值唯一性并非全局唯一,而是指内存中数据的唯一性。为流数据表开启持久化,可以设置内存中保留的数据条数,一旦数据条数超过设定的上限,系统将一半旧的数据持久化至磁盘。这种方案确保了内存中数据键值的唯一性,而不是全局唯一性。尽管如此,已足以解决多路写入或网络延迟导致的重复提交写入的问题。
向表中添加新记录时,系统会自动检查新记录的主键值:
如果新记录的主键值与内存中已有记录的主键值重复时,已有的记录不会被更新。
一次性批量插入新记录时,若有多条记录具有相同的主键值,且该主键值与已有记录的主键值不同,只有第一条记录能成功插入。
参数
keyColumn
是一个字符串或向量,表示主键。主键的数据类型必须属于以下类别:INTEGRAL,
TEMPORAL, LITERAL 或 FLOATING。
第一种用法中,
X
,
X1
,
X2
...
可以是向量、数组向量、矩阵或元组。每个向量、元组、数组向量的长度,以及矩阵中每列长度都必须相同。
当 Xk 是元组时:
若 Xk 的元素是等长的向量,
元组的每个元素将作为表的一列。
元组的长度必须等于表的行数。
若 Xk 包含不同类型或不等长元素,
则将单独作为表的一列(列类型为 ANY),其每个元素将作为该列每行的元素值。
Xk
的长度仍然必须和表的行数保持一致。
第二种用法中:
capacity
是正整数,表示建表时系统为该表分配的内存(以记录数为单位)。当记录数超过
capacity
时,系统首先会分配
capacity
1.2~2倍的新的内存空间,然后复制数据到新的内存空间,最后释放原来的内存。对于规模较大的表,此类操作的内存占用会很高。因此,建议建表时预先分配一个合理的
capacity
。
size
是整数,表示该表新建时的行数。若
size
=0,创建一个空表。 若
size
>0,则建立一个只包含 size 条记录的表,记录初始值如下:
BOOL 类型默认值为 false;
数值类型、时间类型、IPADDR、COMPLEX、POINT 的默认值为 0;
Literal, INT128 类型的默认值为 NULL。
注:
如果
colTypes
指定为数组向量,
size
必须为0。
colNames
是一个向量,表示列名。
colTypes
是一个向量,表示每列的数据类型,允许主键外的其它列指定为数组向量类型或元组(ANY)类型。可使用表示数据类型的系统保留字或相应的字符串。
返回值
一个表。
例子
第一种用法:
id=`A`B`C`D`E
x=1 2 3 4 5
t1=keyedStreamTable(`id, id, x)
t1;
id
x
A
1
B
2
C
3
D
4
E
5
第二种用法:
t2=keyedStreamTable(`id,100:0,`id`x, [INT,INT])
insert into t2 values(1 2 3,10 20 30);
t2;
id
x
1
10
2
20
3
30
往表 t2 中插入重复主键值的数据:
insert into t2 values(3 4 5,35 45 55)
t2;
id
x
1
10
2
20
3
30
4
45
5
55
可以看到,id=3 的记录并没有被覆盖。
主键为多个字段:
t=keyedStreamTable(`sym`id,1:0,`sym`id`val,[SYMBOL,INT,DOUBLE])
insert into t values(`A`B`C`D`E,5 4 3 2 1,52.1 64.2 25.5 48.8 71.9);
insert into t values(`A`B`R`T`Y,5 8 3 2 1,152.3 164.6 125.5 148.8 171.6);
t;
sym
id
val
A
5
52.1
B
4
64.2
C
3
25.5
D
2
48.8
E
1
71.9
B
8
164.6
R
3
125.5
T
2
148.8
Y
1
171.6
FILE:references/doc_7159.md
# backupSettings
**URL**: https://docs.dolphindb.cn/zh/funcs/b/backupsettings.html
**来源**: DolphinDB 官方文档
---
backupSettings
语法
backupSettings(fileName, [userPermission=true],
[functionView=true])
详情
此函数只能由管理员在控制节点执行,备份当前数据库系统中的所有用户、用户权限信息和函数视图,并将备份文件保存到指定路径。
函数返回一个向量,依次列出已成功备份的用户名和函数视图名称。
与函数
restoreSettings
搭配使用,可以在数据库迁移时实现用户、用户权限及函数视图的迁移。
参数
fileName
STRING 类型标量,指定备份文件的存储路径,可以为绝对路径或相对于 <HomeDir> 的相对路径。
userPermission
BOOL 类型标量,表示是否备份用户权限。默认值为 true,表示备份用户权限。
functionView
BOOL 类型标量,表示是否备份函数视图。默认值为 true,表示备份函数视图。
返回值
一个字典,包含以下 key:
users:备份的用户信息。
groups:备份的权限信息。
functionViews:备份的函数视图信息。
例子
// 备份用户、权限信息、函数视图
backupSettings(fileName="/home/ddb/backup/permission.back", userPermission=true, functionView=true)
// 备份用户、权限信息,不备份函数视图
backupSettings(fileName="/home/ddb/backup/permission.back", userPermission=true, functionView=false)
// 备份用户、函数视图,不备份权限信息
backupSettings(fileName="/home/ddb/backup/permission.back", userPermission=false, functionView=true)
// 备份用户,不备份权限信息和函数视图
backupSettings(fileName="/home/ddb/backup/permission.back", userPermission=false, functionView=false)
相关函数:
restoreSettings
FILE:references/doc_7170.md
# fromUTF8
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fromUTF8.html
**来源**: DolphinDB 官方文档
---
fromUTF8
语法
fromUTF8(str, encode)
详情
把 UTF8 编码的字符串转换为其他编码。DolphinDB 对编码名称的大小写敏感,所有编码名称必须用小写表示。
因为 Windows 版本目前仅支持 gbk 和 utf-8 两种编码的相互转换,因此在 Windows
中,
fromUTF8
的第二个参数只能是 "gbk"。Linux 版本支持任意两种编码之间的转换。
参数
str
是一个字符串标量或向量。
encode
是一个字符串,表示
str
的目标编码名称。
返回值
字符串类型标量或向量。
例子
fromUTF8("DolphinDB","gbk");
输出返回:DolphinDB
fromUTF8(["hello","world"],"euc-cn");
输出返回:["hello","world"]
相关函数:
convertEncode
,
toUTF8
FILE:references/doc_7175.md
# row
**URL**: https://docs.dolphindb.cn/zh/funcs/r/row.html
**来源**: DolphinDB 官方文档
---
row
语法
row(obj,index)
详情
获取向量、矩阵或表的一行或多行。参见相关函数:
col
。
参数
obj
可以是向量、矩阵或表
index
是一个整数标量或数据对。
返回值
返回向量、矩阵或表的一行或多行。
例子
x=matrix(1 2 3, 4 5 6);
x;
#0
#1
1
4
2
5
3
6
row(x,1);
// output
[2,5]
row(x,0);
// output
[1,4]
x.row(2);
// output
[3,6]
a=table(1..3 as x,`IBM`C`AAPL as y);
a
x
y
1
IBM
2
C
3
AAPL
row(a,1);
// output
y->C
x->2
row(a,1:3)
x
y
2
C
3
AAPL
FILE:references/doc_7186.md
# unsubscribeTable
**URL**: https://docs.dolphindb.cn/zh/funcs/u/unsubscribeTable.html
**来源**: DolphinDB 官方文档
---
unsubscribeTable
语法
unsubscribeTable([server], tableName, [actionName], [removeOffset=true],
[raftGroup])
详情
在信息订阅端的节点执行,以停止向信息发布者订阅数据。在调用该命令时,会删除流计算执行线程的队列中未处理的消息。
参数
server
是表示服务器的别名或与流数据表所在服务器创建的 xdb 连接的字符串。
tableName
是表示取消订阅的流数据表名称的字符串。
取消跨集群订阅 Orca
流表时,格式为
fqn@cluster_identifier
,例如
demo.orca_table.trades@cluster_BeiJing
。
actionName
是表示句柄名称的字符串。它可以包含字母、数字和下划线。如果创建订阅时指定了
actionName
,取消订阅时必须指定
actionName
。
removeOffset
是一个布尔值,表示是否删除持久化保存的最新一条已经处理订阅数据的偏移量(在
subscribeTable
函数中通过指定
persistOffset
参数为 true 获得)。
raftGroup
是在
subscribeTable
中设定的 raft 组的 ID,用于取消相应的订阅高端可用。不设置该参数,则订阅信息仍然保留在 raft
中,再次切换 leader 会重新订阅。
注:
unsubscribeTable
函数如果指定了
raftGroup
,则只能在 leader 上执行。
例子
在发布节点发布一张表 trades。
t=streamTable(100:0,`date`time`sym`qty`price`exch,[DATE,TIME,SYMBOL,INT,DOUBLE,SYMBOL])
share t as trades
t=NULL
在订阅节点上创建表 trades2 来保存发布节点中的表 trades 的数据。
t=streamTable(100:0,`date`time`sym`qty`price`exch,[DATE,TIME,SYMBOL,INT,DOUBLE,SYMBOL])
share t as trades2
t=NULL
h=xdb("localhost",8902)
subscribeTable(server=h, tableName="trades", actionName="sub1", handler=trades2);
// output: localhost:8902:node1/trades/sub1
取消订阅表 trades 的数据:
unsubscribeTable(h, "trades","sub1");
FILE:references/doc_7191.md
# 数据导入最容易忽略的十个细节
**URL**: https://docs.dolphindb.cn/zh/tutorials/data_import_details.html
**来源**: DolphinDB 官方文档
---
数据导入最容易忽略的十个细节
数据导入是使用 DolphinDB 的重要一环。无论是从磁盘文件(如 csv 文件、txt 文件等)导入数据,还是使用插件从其他来源导入,如果忽略了一些操作细节,会导致导入失败或导入结果不符合预期。
本文将介绍使用 DolphinDB 进行数据导入时,最容易忽略的 10 个细节,涉及了数据格式、数据类型、导入速率、数据预处理、连接失败、分区冲突等方面,并给出了正确的解决方案,一起来看看吧。
1. 表头包含数字时的文件导入技巧
loadText
和
ploadText
是使用 DolphinDB 导入文本文件时最常使用的函数。但由于 DolphinDB 中列名必须以中文或英文字母开头,对于以数字开头的表头,
loadText
和
ploadText
函数的处理规则如下:
不指定
containHeader
时,导入文本文件时将以字符串格式读取第一行数据,并根据该数据解析列名。但如果文件第一行记录中某列记录以数字开头,那么加载文件时系统会使用
col0
,
col1
, … 等作为列名。
指定
containHeader
= true 时,系统将第一行数据视为标题行,并解析出列名。如果文件第一行记录中某列记录以数字开头,那么加载文件时系统会使用 “c” 加列名作为列名。
如果忽略该细节,可能导致导入结果的列名不符合预期。
如导入下面的
colName.csv
,有列名以数字开头,原始结构如下:
id
name
totalSale
2023Q1
2023Q2
2023Q3
1
shirt
8000
2000
3000
3000
2
skirt
10000
2000
5000
3000
3
hat
2000
1000
300
700
1.1. 错误操作
不指定
containHeader
时,系统将会使用
col0
,
col1
, … 等作为列名。
执行
loadText("/xxx/colName.csv")
,导入结果如下:
需要注意的是,由于
col0
和
col1
可以被视作一组具有离散值的变量,符合枚举类型的特征,被默认解析为 SYMBOL 类型;而
col2
-
col5
这几列数据都是整数形式,被默认解析为 INT 类型,因此
col2
原本的列名
totalSale
无法写入该列,为空;
col3
-
col5
原本的列名只保留了开头可以解析为数字的 2023 部分。
1.2. 正确操作
指定
containHeader
= true 时,系统会使用 “c” 加列名作为数字开头列的列名。
执行
loadText("/xxx/colName.csv", containHeader = true)
,导入结果如下:
对于数字开头的列名,指定
containHeader
= true,可以保证数据完整性,仅在列名前添加字符 “c”,是目前最佳的解决方案。因此,当使用
loadText
函数导入的文本文件表头有列名以数字开头时,应该指定
containHeader
= true。
2. 自动解析数据类型的导入技巧
loadText
、
ploadText
和
loadTextEx
函数都提供了
schema
参数,用于传入一个表对象,以指定各字段的数据类型,并照此类型来加载数据。使用
loadText
、
ploadText
和
loadTextEx
函数时,如果用户不指定
schema
参数,会对数据文件进行随机抽样,并基于样本决定每列的数据类型。
由于自动解析数据类型的方法是对数据文件进行随机抽样,因此不一定每次都能准确决定各列的数据类型。为此,DolphinDB 提供了
extractTextSchema
函数,能够查看 DolphinDB 对数据文件进行自动解析数据类型的结果。在导入数据前,建议使用
extractTextSchema
确认对数据类型的自动解析结果;如果自动解析结果不符合预期,可以修改对应类型,并将修改后的表作为
loadText
、
ploadText
和
loadTextEx
的
schema
参数,再进行数据导入。
如导入下面的
type.csv
,原始结构如下:
id
ticker
price
1
300001
25.80
2
300002
6.85
3
300003
7.19
2.1. 错误操作
执行
loadText("/xxx/type.csv")
,导入结果如下:
执行
extractTextSchema("/xxx/type.csv")
,可以看到,
ticker
列被默认解析为 INT 类型,不符合预期:
2.2. 正确操作
可以使用
extractTextSchema
函数先得到自动解析结果,再将
ticker
列的类型指定为 SYMBOL 类型,并用修改后的结果作为
loadText
函数的
schema
参数值进行导入,即可得到预期结果:
schema = extractTextSchema("/xxx/type.csv")
update schema set type =`SYMBOL where name = "ticker"
loadText("/xxx/type.csv", schema=schema)
3. 日期与时间格式数据的手动导入方法
使用
loadText
函数导入符合日期、时间格式的数据时,如果用户不指定
schema
参数,会将符合日期、时间格式的数据优先解析为对应类型。规则如下:
当加载的数据文件中包含了表达日期、时间的数据时,满足分隔符要求的这部分数据(日期数据分隔符包含 ”-”、”/” 和 ”.”,时间数据分隔符为 ”:”)会解析为相应的类型。例如,”12:34:56” 解析为 SECOND 类型;”23.04.10” 解析为 DATE 类型。
对于不包含分隔符的数据,形如 ”yyMMdd” 的数据同时满足 0<=yy<=99,0<=MM<=12,1<=dd<=31 的条件时,会被优先解析成 DATE 类型;形如 ”yyyyMMdd” 的数据同时满足 1900<=yyyy<=2100,0<=MM<=12,1<=dd<=31 的条件时,会被优先解析成 DATE 类型。
如导入下面的
notdate.csv
,原始结构如下:
id
ticker
price
1
111011
133.950
2
111012
125.145
3
111013
113.240
3.1. 错误操作
直接使用
loadText
函数导入 DolphinDB,由于
ticker
列是形如 "yyMMdd" 的数据,且同时满足 0<=yy<=99,0<=MM<=12,1<=dd<=31 的条件,会被优先解析成 DATE 类型。
执行
loadText("/xxx/notdate.csv")
,导入结果如下:
3.2. 正确操作
导入此类符合日期、时间格式的数据时,无需使用
extractTextSchema
函数查看自动解析结果,可提前在
schema
参数中将
ticker
列指定解析为 SYMBOL 类型,再进行导入,即可得到预期结果。
执行如下代码:
schema = table(`id`ticker`price as name, `INT`SYMBOL`DOUBLE as type)
loadText("/xxx/notdate.csv", schema = schema)
4. 提升数据导入效率的
loadTextEx
函数使用建议
在一些实际应用场景中,用户导入数据文件的下一步,都是将其写入分布式数据库进行存储,而不需要在内存中进行额外操作。DolphinDB 为此提供了
loadTextEx
函数,能够直接把数据文件入库,不需要把数据加载到内存表,既简化了步骤,又节省了时间。
如导入下面的
data.csv
,原始结构如下:
ID
date
vol
23
2023.08.08
34.461863990873098
27
2023.08.08
4.043174418620766
36
2023.08.08
5.356599518563599
98
2023.08.09
5.630887264851481
…
…
…
4.1. 初级操作
如果先使用
loadText
函数把该文件加载到内存,再写入数据库,耗时 771.618ms。
timer{
t = loadText("/xxx/data.csv")
loadTable("dfs://test_load","data").append!(t)
}
>> Time elapsed: 771.618ms
4.2. 进阶操作
直接使用
loadTextEx
函数将该文件入库,耗时 384.097ms。
timer{
loadTextEx(database("dfs://test_load"), "data", "date", "/xxx/data.csv", sortColumns=`id)
}
>> Time elapsed: 384.097ms
数据量越大,两种方式的耗时差异越明显。
5. 在
loadTextEx
中使用
transform
参数预处理数据
在一些实际应用场景中,用户既希望能够使用
loadTextEx
函数直接把数据入库,又希望能够对数据做一些简单处理。针对这种需求,可以在
loadTextEx
中使用
transform
参数,对数据进行处理后再入库。这种做法无需把数据加载到内存来处理,简化了操作步骤。
例如,导入下面的
dataWithNULL.csv
时,
vol
列有空值,需要先将
vol
列的空值填充为 0,再入库:
ID
date
vol
52
2023.08.08
5.08143
77
2023.08.09
35
2023.08.08
0.22431
99
2023.08.09
…
…
…
5.1. 初级操作
如果先使用
loadText
函数把该文件加载到内存,使用
nullFill!
去除空值,再写入数据库,耗时 802.23ms。
timer{
t = loadText("/xxx/dataWithNULL.csv")
t.nullFill!(0.0)
loadTable("dfs://test_load","data").append!(t)
}
>> Time elapsed: 802.23ms
5.2. 进阶操作
使用
loadTextEx
函数配合
transform
参数将该文件入库,耗时 385.086ms。
timer{
loadTextEx(database("dfs://test_load"), "data", "date", "/xxx/dataWithNULL.csv", transform = nullFill!{, 0.0}, sortColumns=`id)
}
>> Time elapsed: 385.086 ms
可以看到,
transform
参数使数据预处理变得非常便捷,无需在内存中额外处理数据,可以一步入库。
6. 避免将长整型时间戳数据以 TIMESTAMP 类型导入
在许多数据中,常常用长整型(LONG 类型)来表示 Unix 毫秒时间戳,即从 1970 年 1 月 1 日(UTC/GMT 的午夜)开始所经过的毫秒数。在导入这样的数据时,如果不预先指定导入类型,将会把这种形式的时间戳直接作为长整型导入,显示的是长整型数据;而如果指定这种形式的时间戳为 TIMESTAMP 类型,将其导入后并不会自动转换为对应的 TIMESTAMP,而会返回空值。因此,这两种做法的结果都不符合预期。
正确的做法是,先把原始数据以 LONG 类型导入,再使用
timestamp
函数手动转换为对应的 TIMESTAMP。
如导入下面的
time.csv
,原始结构如下:
timestamp
ticker
price
1701199585108
SH2575
9.05991137959063
1701101960267
SH1869
9.667245978489518
1701292328832
SH1228
19.817104414105415
1701186220641
SH2471
3.389011020772159
6.1. 错误操作
如果指定把
timestamp
列作为 TIMESTAMP 类型导入,该列导入结果将会全为空值:
schema = extractTextSchema("/xxx/time.csv")
update schema set type = "TIMESTAMP" where name = "timestamp"
loadText("/xxx/time.csv", schema=schema)
6.2. 正确操作
正确做法应该是把
timestamp
列以 LONG 类型直接导入,然后使用
replaceColumn!
和
timestamp
函数,将其手动转换为 TIMESTAMP 类型,即可得到预期结果:
t = loadText("/xxx/time.csv")
replaceColumn!(t, `timestamp, timestamp(exec timestamp from t))
t
7. 长整型转换为 TIMESTAMP 类型时的时区注意事项
有的数据库在存储时间数据时,会将其转换为全球统一的 Unix 时间戳,并单独存储时区信息(即 UTC 偏移量)。 而 DolphinDB 将时间转换为本地时间戳直接存储,不会单独存储时区信息,具体可参考:
时区处理
。
因此,如果原始数据文件中的长整型是带时区信息的长整型,即已经加减了 UTC 偏移量的数据,导入 DolphinDB 进行转换时会被视为零时区数据处理,可能导致结果与预期不符。
如导入下面的
localtime.csv
,原始结构如下:
timestamp
ticker
price
1701331200000
SH3149
8.676103590987622
1701331200000
SH0803
12.16052254475653
1701331200000
SH2533
12.076009283773601
1701331200000
SH3419
0.239130933769047
其中,
timestamp
列应为由北京时间 2023.11.30T16:00:00.000 转换的长整型:
7.1. 错误操作
直接把
timestamp
列以 LONG 类型直接导入,然后将其手动转换为 TIMESTAMP 类型后,得到的是零时区时间,和北京时间相差 8 个小时:
t = loadText("/xxx/localtime.csv")
replaceColumn!(t, `timestamp, timestamp(exec timestamp from t))
t
7.2. 正确操作
对于长整型转换为 TIMESTAMP 默认为零时区的现象,可以在转换类型时,利用 DolphinDB 内置的时区转换函数
localtime
,把零时区时间转换成本地时间(本文测试的本地时间为东八区时间):
t = loadText("/xxx/localtime.csv")
replaceColumn!(t, `timestamp, localtime(timestamp(exec timestamp from t)))
t
也可以利用 DolphinDB 内置时区转换函数
convertTZ
,完成两个指定时区之间的转换:
t = loadText("/xxx/localtime.csv")
replaceColumn!(t, `timestamp, convertTZ(timestamp(exec timestamp from t), "UTC", "Asia/Shanghai"))
t
8. 使用标准格式的连接字符串连接 ODBC
通过 ODBC 插件可以连接其它数据源,将其他数据源的数据导入到 DolphinDB。在连接其他数据源时,有可能遇到报错:
FATAL: password authentication failed for user "xxx"
,但用户名和密码均正确,导致排查问题来源时没有头绪。许多情况下,这是因为使用的 ODBC 连接字符串有问题。有关连接字符串的标准格式,请参阅
连接字符串参考
。
8.1. 错误操作
如下面的场景,使用 DSN 连接字符串连接 PostgreSQL,运行后出现报错:
odbcConfig = "DSN=PIE_PGSQL;Server="+ip+";port="+port+";DATABASE="+db+";Uid="+userName+";Password="+password+";"
conn = odbc::connect(odbcConfig)
>> FATAL: password authentication failed for user "pie_dev"
Linux 版本的 ODBC 插件基于 unixODBC 开发,isql 是 unixODBC 提供的基本工具,能够快速排查 ODBC 相关问题。使用相同的 DSN 连接字符串运行 isql,出现了相同的报错:
[28P01][unixODBC]FATAL: password authentication failed for user "pie_dev"
[ISQL]ERROR: Could not SQLDriverConnect
说明该问题与 DolphinDB 的 ODBC 插件无关,可能是连接字符串有问题。
8.2. 正确操作
查阅
连接字符串参考
,发现 PostgreSQL 的 ODBC 标准连接字符串如下:
按照标准连接字符串形式,参考如下方式修改连接字符串:
odbcConfig = "Driver={PostgreSQL};Server="+ip+";port="+port+";DATABASE="+db+";Uid="+userName+";Password="+password+";"
conn = odbc::connect(odbcConfig)
运行后,连接成功。
9. 同磁盘下数据解压和导入的并行处理注意事项
许多时候,用户的原始数据文件是压缩包形式的,需要先解压再进行导入。如果用户采取的是一边解压一边导入的方式,且原始数据所在磁盘与解压后存储 DolphinDB 数据库的磁盘是同一块时,会降低导入的速率。如果忽略这个细节,可能导致数据导入的耗时额外增加。
如导入下面的
mdl_6_28_0.csv
,大小为 4.3 GB:
9.1. 错误操作
在该 DolphinDB 数据存储的磁盘上进行一个 .zip 文件的解压任务,同时使用
loadTextEx
函数将另一个已解压的 csv 文件入库,耗时约 1m41s:
timer loadTextEx(database("dfs://test_load"), "data", "SecurityID", "/xxx/mdl_6_28_0.csv", sortColumns=`SecurityID`UpdateTime)
>> Time elapsed: 101156.78ms
在导入过程中,观察磁盘读写速率如下:
可以看到,当在同一块磁盘同时解压数据和导入数据时,数据导入的速率降低了许多。
9.2. 正确操作
磁盘空闲,没有解压任务在执行时,直接使用
loadTextEx
函数入库相同的文件,耗时约 46s:
timer loadTextEx(database("dfs://test_load"), "data", "SecurityID", "/xxx/mdl_6_28_0.csv", sortColumns=`SecurityID`UpdateTime)
>> Time elapsed: 46203.117ms
在导入过程中,观察 DolphinDB 磁盘读写速率如下:
10. 避免并行写入同一分区时的冲突解决方案
在导入数据并写入分布式数据库时,有可能会存在并行写入同一分区的情况。在这种场景下,根据创建数据库时设置的
atomic
参数的不同,可能出现以下不同的情况:
atomic
参数设置为 ’TRANS’,写入事务的原子性层级为事务,即一个事务写入多个分区时,若某个分区被其他写入事务锁定而出现写入冲突,则该事务的写入全部失败。因此,该设置下,不允许并发写入同一个分区。
atomic
参数设置为 ’CHUNK’,写入事务的原子性层级为分区。若一个事务写入多个分区时,某分区被其它写入事务锁定而出现冲突,系统会完成其他分区的写入,同时对之前发生冲突的分区不断尝试写入,尝试数分钟后仍冲突才放弃。此设置下,允许并发写入同一个分区,但由于不能完全保证事务的原子性,可能出现部分分区写入成功而部分分区写入失败的情况。同时由于采用了重试机制,写入速度可能较慢。
当发生分区冲突导致写入失败时,将会抛出错误代码 S00002,错误信息为:
<ChunkInTransaction>filepath has been owned by transaction
,表示某个分区已经被一个事务锁定,新的事务无法再次锁定相同分区。如果忽略此细节,可能导致数据导入任务失败。
下面的
dfs://test_month
数据库,按月分区,且
atomic
参数为 ’TRANS’:
10.1. 错误操作
并行导入下面的 csv 文件入库,他们入库的目标分区都为 2023.08M:
使用
submitJob
提交导入任务:
filePath = "/xxx/dailyData"
for (i in files(filePath).filename){
submitJob("loadCSVTest", "load daily files to monthly db", loadTextEx, database("dfs://test_month"), "data", "date", filePath+i)
}
查看任务完成情况,可以看到,只有一个任务导入成功,别的任务都因为分区冲突而失败,抛出错误代码 S00002:
10.2. 正确操作
对于这种情况,我们可以串行导入文本文件,避免并行写入同一分区时的冲突:
def loadDaily(filePath){
for (i in files(filePath).filename){
loadTextEx(database("dfs://test_month"), "data",`date,filePath+i,sortColumns=`ID)
}
}
path = "/xxx/dailyData/"
submitJob("loadCSVTest","load daily files to monthly db",loadDaily, path)
查看任务完成情况,可以看到,数据能够导入成功,没有报错:
11. 总结
本文介绍了使用 DolphinDB 进行数据导入时,最容易忽略的 10 个细节,涵盖了数据格式、数据类型、导入速率、数据预处理、连接失败、分区冲突等多个方面。忽略了这些细节,可能导致数据导入失败或导入结果不符合预期。用户了解了这些细节,并合理进行数据导入,可以极大提升数据导入的速度和质量。
FILE:references/doc_7193.md
# getPerf
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getPerf.html
**来源**: DolphinDB 官方文档
---
getPerf
语法
getPerf()
详情
查询本地节点上的多个性能监控度量值。
参数
无
返回值
返回一个字典,包含以下 key:
runningJobs:正在执行中的 Job 个数。
jobLoad:作业负载。
avgLoad:CPU 平均负载。
queuedJobs:队列中的 Job 个数。
lastMinuteNetworkSend:前一分钟网络发送字节数(单位:字节)。
lastMinuteNetworkRecv:前一分钟网络接收字节数 (单位:字节)。
lastMinuteReadVolume:前一分钟读磁盘容量(单位:字节)。
lastMinuteWriteVolume:前一分钟写磁盘容量(单位:字节)。
lastMsgLatency:前一批消息的延时(单位:纳秒)。
cumMsgLatency:所有消息的平均延时(单位:纳秒)。
maxLast10QueryTime:前 10 个完成的查询执行所耗费时间的最大值(单位:纳秒)。
maxLast100QueryTime:前100个完成的查询执行所耗费时间的最大值(单位:纳秒)。
medLast10QueryTime:前 10 个完成的查询执行所耗费时间的中间值(单位:纳秒)。
medLast100QueryTime:前 100 个完成的查询执行所耗费时间的中间值(单位:纳秒)。
maxRunningQueryTime:当前正在执行的查询的耗费时间的最大值(单位:纳秒)。
diskFreeSpaceRatio:磁盘可用空间占比。
diskReadRate:磁盘读速率(单位:字节/秒)。
diskWriteRate:磁盘写速率(单位:字节/秒)。
diskFreeSpace:磁盘剩余空间(单位:字节)。
diskCapacity:磁盘容量(单位:字节)。
cpuUsage:CPU 使用率。
memoryAlloc:系统已分配给当前节点的内存(单位:字节)。
memoryUsed:节点的内存占用量(单位:字节)。
networkSendRate:网络发送速率(单位:字节/秒)。
networkRecvRate:网络接收速率(单位:字节/秒)。
connectionNum:连接到本地节点的连接数。
例子
getPerf();
// output
cumMsgLatency->-9.223372036854776E18
lastMsgLatency->-9.223372036854776E18
lastMinuteNetworkRecv->2184101
maxLast10QueryTime->224829
lastMinuteNetworkSend->378283
diskWriteRate->144
networkSendRate->3924
medLast100QueryTime->131965
avgLoad->1.0228125
runningJobs->0
connectionNum->2
medLast10QueryTime->131965
cpuUsage->0
diskFreeSpaceRatio->0.041250206237365
jobLoad->0
memoryUsed->7970304
memoryAlloc->19513344
maxLast100QueryTime->224829
networkRecvRate->32238
maxRunningQueryTime->0
diskCapacity->1.859747577856E12
queuedJobs->0
diskFreeSpace->7.6714971136E10
diskReadRate->6538
lastMinuteWriteVolume->1515
lastMinuteReadVolume->392408
FILE:references/doc_7196.md
# logout
**URL**: https://docs.dolphindb.cn/zh/funcs/l/logout.html
**来源**: DolphinDB 官方文档
---
logout
语法
logout([userId], [sessionOnly=true])
详情
该函数可以在控制节点/数据节点/计算节点上执行。
如果没有指定
userId
,用户自己退出登录。
如果
sessionOnly
为true,用户只退出登录当前会话。
如果
sessionOnly
为false,用户会退出登录当前会话、所有的数据节点/计算节点以及控制节点。
管理员可以使其他用户退出登录。如果管理员使用户退出登录,用户会退出登录当前会话、所有的数据节点/计算节点以及控制节点。
参数
userId
是表示用户名的字符串。注:包含短横线(-)的用户名必须用双引号来包裹,不能用反引号`。
sessionOnly
是表示是否退出登录当前会话的布尔值。
返回值
无。
例子
logout();
logout(`TomFord);
logout(, false);
FILE:references/doc_7197.md
# byColumn
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/byColumn.html
**来源**: DolphinDB 官方文档
---
byColumn
语法
byColumn(func, X
, [Y]
)
或
func:V(X)
或
func:V(X, [Y])
详情
func
为单目函数时,
对
X
的每一列应用指定函数;
func
为双目函数时,对
X
和
Y
的每列执行 func(Xi, Yi)
。
同时指定 X 和 Y 时,则对 X 和 Y 的每列执行 func(Xi, Yi) 。
支持在响应式状态引擎中使用
byColumn
函数。
计算规则
:
如果
X/Y
是矩阵、表或元组,byColumn 对 X/Y 的每一列数据应用指定的函数。
如果 X/Y 是数组向量或列式元组:byColumn 首先将对象转置,然后对转置后的对象的每一行应用指定函数。
当
func
是向量函数时,byColumn 会把
func
的计算结果转置后输出。
当
func
是聚合函数时,输出结果是一个向量。特别地,当
func
是以下聚合函数时,由于 byColumn
不对 X/Y 进行转置,从而提高了计算性能:sum, sum2, avg, min, max, count, imax, imin,
imaxLast, iminLast, prod, std, stdp, var, varp, skew, kurtosis, any,
all, corr, covar, wavg, wsum, beta, euclidean, dot, tanimoto
参数
func
一个单目函数,支持以部分应用的形式传入。该函数可以是向量函数(输入与输出为等长的向量),亦可为聚合函数。
X
一个矩阵
、表、元组、数组向量、列式元组
。
Y
矩阵、表、元组、数组向量、列式元组。
返回值
当
func
是聚合函数时,
如果
X/Y
是矩阵、数组向量或列式元组,则输出结果是一个向量。向量的长度与
X/Y
的列数相同。
如果
X/Y
是元组,则输出结果是一个元组。
如果
X/Y
是表,则输出结果是一个表。
当
func
是向量函数时,输出结果的形式、维度和
X/Y
的形式、维度相同。
例子
对于不支持矩阵运算的单目向量函数,通过
byColumn
进行按列计算,等效于
each
。
def myvfunc(x): var(x).log()
m = matrix(1.1 2.3 2.1 3.5 4.2, 3.3 2.5 4.2 5.1 0, -1 3.3 2 1.7 2.3)
byColumn(myvfunc, m)
输出返回: [0.3974329364109,1.334211281249665,0.945072533299607]
传入多元函数时,需要把该函数的其他参数通过部分应用进行固定,然后传入
func
。
byColumn(autocorr{,2},m)
返回:[-0.05,-0.28,-0.06]
输出返回:
col1 col2 col3
3.1 5.3 1
4.3 4.5 5.3
4.1 6.2 4
5.5 7.1 3.7
6.2 2 4.3
byColumn(add{1 2 3 4 5}, m)
输出返回:
col1 col2 col3
2.1 4.3 0
4.3 4.5 5.3
5.1 7.2 5
7.5 9.1 5.7
9.2 5 7.3
func
是一个自定义函数。
def my_func(x){
return iif(x > 0, 1, -1)
}
m = matrix(3 -6 5 0, 2 -9 -4 5)
byColumn(my_func, m)
输出返回:
col1 col2
1 1
-1 -1
1 -1
-1 1
func
是一个嵌套函数。
m = matrix(1 5 3 , 7 5 2)
byColumn(accumulate{def (x, y):iif(x > 5, y-1, y+1), ,1}, m)
输出返回:
col1 col2
2 8
6 4
2 3
入参是矩阵:
m=matrix([1 3 4 2,1 2 2 1])
max:V(m)
[4,2]
cummax:V(m)
col1 col2
1 1
3 2
4 2
4 2
n=matrix([11 5 9 2,8 5 3 2])
corr:V(m,n)
[-0.09,-0.21]
入参是表:
qty1 = 2200 1900 2100 3200 6800 5400 1300 2500 8800
qty2 = 2100 1800 6800 5400 1300 2400 8500 4100 3200
t = table(qty1, qty2);
max:V(t)
qty1 qty2
8,800 8,500
cummax:V(t)
qty1 qty2
2,200 2,100
2,200 2,100
2,200 6,800
3,200 6,800
6,800 6,800
6,800 6,800
6,800 8,500
6,800 8,500
8,800 8,500
qty3 = 7800 5400 5300 2500 1800 2200 3900 3100 1200
qty4 = 3200 2800 6400 8300 2300 3800 2900 1600 2900
t1 = table(qty3, qty4);
corr:V(t,t1)
qty1 qty2
-0.7267 0.4088
入参是元组:
tp=[1 3 4 2,1 2 2 1]
sum:V(tp)
(10,6)
cummax:V(tp)
([1,3,4,4],[1,2,2,2])
tp1=[11 23 14 21,10 12 32 21]
corr:V(tp,tp1)
(0.25,0.37)
入参是数组向量:
a=array(INT[], 0, 10).append!([1 2 3, 4 5 4, 6 7 8, 1 9 10]);
sum:V(a)
[12,23,25]
cummax:V(a)
[[1,2,3],[4,5,4],[6,7,8],[6,9,10]]
b=array(DOUBLE[], 0, 10).append!([11.8 21.2 23.9, 83.3 90.2 78.2, 86.5 52 36.5, 10.1 12.4 16.8])
corr:V(a,b)
[0.95,-0.13,-0.46]
入参是列式元组:
ctp=[1 3 4 2,1 2 2 1]
ctp.setColumnarTuple!()
sum:V(ctp)
[2,5,6,3]
cummax:V(ctp)
([1,3,4,2],[1,3,4,2])
ctp1=[11 23 14 21,10 12 32 21]
ctp1.setColumnarTuple!()
corr:V(ctp,ctp1)
[,1,-1,]
FILE:references/doc_7213.md
# set
**URL**: https://docs.dolphindb.cn/zh/funcs/s/set.html
**来源**: DolphinDB 官方文档
---
set
语法
set(X)
详情
返回向量
X
对应的集合对象。
参数
X
是一个向量。
返回值
返回向量 X 对应的集合对象。
例子
set
函数返回一个集合。
x=set(4 5 5 2 3 11 6);
x;
// output
set(6,11,3,2,5,4)
x.intersection(set([2,5,9]));
// output
set(2,5)
与此不同,
distinct
函数返回一个向量。
distinct(4 5 5 2 3 11 6);
// output
[6,11,3,2,5,4]
FILE:references/doc_7217.md
# 横截面引擎
**URL**: https://docs.dolphindb.cn/zh/stream/cross_sectional_engine.html
**来源**: DolphinDB 官方文档
---
横截面引擎
横截面引擎适用于对截面数据(如每只股票代码最新时间戳下的数据)进行实时计算。如:金融场景下,使用某个指数的所有成分股的最新价格计算该指数的内在价值;工业物联网场景下,对某批设备最新温度求最值等等。
横截面引擎包含两个部分:
横截面数据表(键值表):保存所有分组的最新记录
计算引擎:包含一组聚合计算表达式以及触发器,系统会根据指定规则触发对横截面数据表的计算,计算结果将保存到指定的数据表中。
横截面引擎由
createCrossSectionalEngine
函数创建。语法如下:
createCrossSectionalEngine(name, [metrics], dummyTable,
[outputTable], keyColumn, [triggeringPattern='perBatch'],
[triggeringInterval=1000], [useSystemTime=true], [timeColumn],
[lastBatchOnly=false], [contextByColumn], [snapshotDir],
[snapshotIntervalInMsgCount], [raftGroup], [outputElapsedMicroseconds=false],
[roundTime=true], [keyFilter], [updatedContextGroupsOnly=false])
其参数的详细含义可以参考:
createCrossSectionalEngine
应用示例
触发横截面引擎的计算方式非常灵活,只需在创建引擎时指定相应参数即可。本节将重点介绍横截面引擎在不同触发模式下的示例。
注:
每次执行示例之前,建议先清理环境(取消订阅、取消横截面引擎,并删除数据表)。清理环境的代码示例如下:
unsubscribeTable(,`trades, "tradesCrossAggregator")
dropStreamEngine("CrossSectionalDemo")
undef(`trades, SHARED)
例1. 每行触发计算的方式
股市的交易数据会实时以流数据的形式写入数据表
trades
。该表通常具有这些列:股票代码(sym)、
时间(time)、成交价(price)、成交数(qty)。以下步骤将使用横截面引擎结合流数据订阅,实时计算如下指标:所有股票的最新成交量之最大值、最新成交金额之最大值,以及最新交易金额之和。
定义流数据表,以写入模拟交易数据。
share streamTable(
10
:
0
,`time`sym`price`qty,[TIMESTAMP,SYMBOL,DOUBLE,INT])
as
trades
定义结果表,以保存横截面引擎计算的结果。
outputTable = table(
10
:
0
, `time`maxQty`maxDollarVolume`sumDollarVolume, [TIMESTAMP,INT,DOUBLE,DOUBLE])
创建横截面引擎,指定表达式、输入表、结果表、分组列、计算频率。返回的对象 tradesCrossAggregator 为保存横截面数据的表。
tradesCrossAggregator=createCrossSectionalEngine(name=
"CrossSectionalDemo"
, metrics=<[max(qty), max(price*qty), sum(price*qty)]>, dummyTable=trades, outputTable=outputTable, keyColumn=`sym, triggeringPattern=`perRow, useSystemTime=false, timeColumn=`time)
订阅流数据表,将新写入的流数据追加到横截面引擎中。
subscribeTable(tableName=
"trades"
, actionName=
"tradesCrossAggregator"
, offset=-
1
, handler=append!{tradesCrossAggregator}, msgAsTable=true)
模拟生成实时交易流数据。
def
writeData(n){
timev =
2000.10
.
08
T01:
01
:
01.001
+ timestamp(
1.
.n)
symv = take(`A`B, n)
pricev = take(
102.1
33.4
73.6
223
,n)
qtyv = take(
60
74
82
59
, n)
insert into trades values(timev, symv, pricev, qtyv)
}
writeData(
4
)
查询流数据表,共有 A 与 B 两只股票的 4 笔交易数据:
select *
from
trades
time
sym
price
qty
2000.10.08T01:01:01.002
A
102.1
60
2000.10.08T01:01:01.003
B
33.4
74
2000.10.08T01:01:01.004
A
73.6
82
2000.10.08T01:01:01.005
B
223
59
截面数据表保存了 A 与 B 两只股票最新的交易数据:
select *
from
tradesCrossAggregator
time
sym
price
qty
2000.10.08T01:01:01.004
A
73.6
82
2000.10.08T01:01:01.005
B
223
59
横截面引擎采用了每行触发计算的方式(
triggeringPattern
="perRow"
),因此每向横截面表写入一行数据,横截面引擎都会进行一次计算,并向结果表插入一条结果数据:
select *
from
outputTable
time
maxQty
maxDollarVolume
sumDollarVolume
2000.10.08 01:01:01.002
60
6126
6126
2000.10.08 01:01:01.003
74
6126
8597.6
2000.10.08 01:01:01.004
82
6035.2
8506.8
2000.10.08 01:01:01.005
82
13157
19192.2
例2. 每写入一批数据触发一次计算
riggeringPattern
取值为 "perBatch" 时,表示每追加一批数据触发一次写入。本例在创建引擎时指定
triggeringPattern
="perBatch"。以下脚本共生成 6 条记录,分两批写入,预期产生 2 次输出:
share streamTable(
10
:
0
,`time`sym`price`qty,[TIMESTAMP,SYMBOL,DOUBLE,INT])
as
trades
outputTable = table(
1
:
0
, `time`maxQty`maxDollarVolume`sumDollarVolume, [TIMESTAMP,INT,DOUBLE,DOUBLE])
tradesCrossAggregator=createCrossSectionalEngine(
"CrossSectionalDemo"
, <[max(qty), max(price*qty), sum(price*qty)]>, trades, outputTable, `sym, `perBatch, useSystemTime=false, timeColumn=`time)
subscribeTable(,
"trades"
,
"tradesCrossAggregator"
,-
1
,append!{tradesCrossAggregator},true)
def
writeData1(){
timev =
2000.10
.
08
T01:
01
:
01.001
+ timestamp(
1.
.4
)
symv = take(`A`B,
4
)
pricev =
102.1
33.4
102.3
33.2
qtyv =
10
20
40
30
insert into trades values(timev, symv, pricev,qtyv)
}
def
writeData2(){
timev =
2000.10
.
08
T01:
01
:
01.005
+ timestamp(
1.
.2
)
symv = `A`B
pricev =
102.4
33.1
qtyv =
120
60
insert into trades values(timev, symv, pricev,qtyv)
}
//写入2批数据,预期会触发2次计算,输出2次聚合结果。
writeData1();
sleep(
100
)
writeData2();
dropStreamEngine(`CrossSectionalDemo)
unsubscribeTable(, `trades, `tradesCrossAggregator)
trades 表中共写入了 6 条记录:
select *
from
trades
time
sym
price
qty
2000.10.08T01:01:01.002
A
102.1
10
2000.10.08T01:01:01.003
B
33.4
20
2000.10.08T01:01:01.004
A
102.3
40
2000.10.08T01:01:01.005
B
33.2
30
2000.10.08T01:01:01.006
A
102.4
120
2000.10.08T01:01:01.007
B
33.1
60
横截面表包含每组最新记录:
select *
from
tradesCrossAggregator
time
sym
price
qty
2000.10.08T01:01:01.006
A
102.4
120
2000.10.08T01:01:01.007
B
33.1
60
由于分 2 次写入,在 perBatch 模式下,横截面引擎输出了 2 条记录:
select *
from
outputTable
time
maxQty
maxDollarVolume
sumDollarVolume
2019.04.08T04:52:50.255
40
4092
5088
2019.04.08T04:52:50.355
120
12288
14274
例3. 基于系统时间间隔触发计算
triggeringPattern
取值 "interval" 时,必须与
triggeringInterval
参数配合使用,表示每隔
triggeringInterval
毫秒基于系统时间触发一次计算。本例中,数据分 6 次写入,每 500 毫秒触发一次计算,每次写入 1
条数据,间隔为 500 或 1000 毫秒。
share streamTable(
10
:
0
,`time`sym`price`qty,[TIMESTAMP,SYMBOL,DOUBLE,INT])
as
trades
outputTable = table(
1
:
0
, `time`avgPrice`volume`dollarVolume`count, [TIMESTAMP,DOUBLE,INT,DOUBLE,INT])
tradesCrossAggregator=createCrossSectionalEngine(name=
"tradesCrossAggregator"
, metrics=<[avg(price), sum(qty), sum(price*qty), count(price)]>, dummyTable=trades, outputTable=outputTable, keyColumn=`sym, triggeringPattern=
"interval"
, triggeringInterval=
500
)
subscribeTable(tableName=
"trades"
, actionName=
"tradesStats"
, offset=-
1
, handler=append!{tradesCrossAggregator}, msgAsTable=true)
insert into trades values(
2020.08
.
12
T09:
30
:
00.000
, `A,
10
,
20
)
sleep(
500
)
insert into trades values(
2020.08
.
12
T09:
30
:
00.000
+
500
, `B,
20
,
10
)
sleep(
500
)
insert into trades values(
2020.08
.
12
T09:
30
:
00.000
+
1000
, `A,
10.1
,
20
)
sleep(
1000
)
insert into trades values(
2020.08
.
12
T09:
30
:
00.000
+
2000
, `B,
20.1
,
30
)
sleep(
500
)
insert into trades values(
2020.08
.
12
T09:
30
:
00.000
+
2500
, `B,
20.2
,
40
)
sleep(
500
)
insert into trades values(
2020.08
.
12
T09:
30
:
00.000
+
3000
, `A,
10.2
,
20
)
select *
from
outputTable;
time
avgPrice
volume
dollarVolume
count
2021.07.27T10:54:00.303
10
20
200
1
2021.07.27T10:54:00.818
15
30
400
2
2021.07.27T10:54:01.331
15.05
30
402
2
2021.07.27T10:54:02.358
15.1
50
805
2
2021.07.27T10:54:02.871
15.15
60
1010
2
2021.07.27T10:54:03.386
15.2
60
1012
2
例4. 保留并计算最新时间戳的截面数据。
设置
triggeringPattern
="keyCount",同时设置
lastBatchOnly
=
true,横截面引擎将仅保留最新时间戳上的数据并进行计算。这里设置
triggeringInterval
=4,所以只有收到的具有相同时间戳的记录数达到 4
条或者收到更新时间戳的数据时,才会触发截面数据进行计算输出。
// 定义输入表与输出表
share streamTable(10:0,`time`sym`price`qty,[TIMESTAMP,SYMBOL,DOUBLE,INT]) as tick
share table(1:0, `time`amount, [TIMESTAMP,INT]) as opt
// 创建引擎
csEngine=createCrossSectionalEngine(name="csEngineDemo", metrics=<[sum(qty)]>, dummyTable=tick, outputTable=opt, keyColumn=`sym, triggeringPattern="keyCount", triggeringInterval=4, timeColumn=`time, useSystemTime=false,lastBatchOnly=true)
subscribeTable(tableName=`tick, actionName="csEngineDemo", msgAsTable=true, handler=append!{csEngine})
def writeData1(){
time = array(timestamp)
time=take(2020.10.08T10:01:01.000,7)
sym=take("A"+string(1..7),7)
price=1..7
qty=1..7
insert into tick values(time, sym, price, qty)
}
// 第一次写入数据
writeData1();
def writeData2(){
time = array(timestamp)
time=take(2020.10.08T10:30:01.000,5)
sym=take("A"+string(1..5),5)
price=1..5
qty=1..5
insert into tick values(time, sym, price, qty)
}
// 第二次写入数据
writeData2();
select * from opt
time
amount
2020.10.08 10:01:01.000
28
2020.10.08 10:30:01.000
15
以上结果表中,第一行的结果由引擎收到的 2020.10.08T10:01:01.000 时刻的数据触发。此时横截面数据表中的
2020.10.08T10:01:01.000 时刻 A1~A7 每个分组中的最后一个记录进行求和,结果是28。第二行的结果由于收到的 2020.10.08
10:30:01.000 时刻的数据条数达到 4 条,触发计算输出。
由于设置了
lastBatchOnly
= true,横截面数据表将只保留最新时间戳的各分组数据。查看截面数据表:
select * from csEngine
time
sym
price
qty
2020.10.08 10:30:01.000
A1
1
1
2020.10.08 10:30:01.000
A2
2
2
2020.10.08 10:30:01.000
A3
3
3
2020.10.08 10:30:01.000
A4
4
4
2020.10.08 10:30:01.000
A5
5
5
横截面表作为最终结果
在以上的例子中,
createCrossSectionalEngine
的返回结果(以下称为横截面表)是为聚合计算提供的一个中间结果,但横截面表亦可为最终结果。例如若需要定时刷新某只股票的最新交易价格,按照常规思路是从实时交易表中按代码筛选股票并取出最后一条记录,而交易表的数据量是随着时间快速增长的,如果频繁做这样的查询,无论从系统的资源消耗还是从查询的效能来看都不是最优的做法。而横截面表永远只保存所有股票的最近一次交易数据,数据量是稳定的,对于这种定时轮询的场景非常合适。
要将横截面表作为最终结果,需要在创建横截面时,对
metrics
与
outputTable
这两个参数置空。
tradesCrossAggregator=createCrossSectionalEngine(
"CrossSectionalDemo"
, , trades, , `sym, `perRow)
FILE:references/doc_7220.md
# Altair 连接 DolphinDB 数据源
**URL**: https://docs.dolphindb.cn/zh/stream/str_altair.html
**来源**: DolphinDB 官方文档
---
Altair 连接 DolphinDB 数据源
在数据爆炸增长时代,不仅需要高效分析来洞察数据背后的规律,更要敏锐把握时机,才能更好地释放数据价值,实时反控商业决策。数据可视化是一种将数据转化成图形化表达的技术,通过图表、图形、地图的展现形式,海量复杂数据能够化繁为简,快速、清晰地传达关键趋势和规律信息。
实时数据可视化在全球金融市场业务中的交易、分析、监控等各个场景都有广泛应用价值。例如报表数据的实时计算,配合关键指标直观输出和展示,能帮助决策者更好地理解业务运作情况,为决策提供数据可视化支持。
为了用户能更方便地实现数据可视化,DolphinDB 已完成与 Altair® Panopticon™ 流数据分析平台的数据对接。
Panopticon 流数据分析平台
Panopticon 流数据分析平台由数据科学和人工智能领域领先企业 Altair
研发,包含了一套专门针对时序数据进行了优化的实时数据可视化系统。系统仪表盘交互便捷,具有丰富的过滤工具,用户只需简单点击,便可以自由调整时间线长度、聚焦重点数据以及排除无关变量,直观地理解复杂关系。
DolphinDB 流数据应用
DolphinDB
高吞吐、低延迟、高可用的流数据框架能帮助用户实现流数据的发布、订阅、预处理、实时内存计算、复杂指标的滚动窗口计算、实时关联、异常数据检测等各种功能,内置的 10+
流数据计算引擎能满足复杂业务场景下的数据处理需求。
应用场景示例
用 DolphinDB 和 Altair Panopticon 共同搭建的高性能时序数据分析平台包括了 SQL
查询和流数据表订阅两种数据接口,用户能够访问和分析实时流数据、日内累计数据和历史数据,并对接收到的数据实时地进行可视化展示。直观易懂的操作流程让用户可以快速地掌握使用方法,在几分钟内连接到数据源,设计一个自动刷新的可交互仪表盘并将其发布,以供交易、分析、监控等相关人员使用。
图
1
.
日频交易数据分析
例如,使用 DolphinDB 流计算引擎搭配 Panopticon 可视化应用搭建价格分析仪表盘,可以将 K
线、移动平均指数、交易量等信息组合在一张图中,快速查看市场整体趋势或关键指标。
DolphinDB 和 Panopticon 的流数据引擎支持实时流数据分析或历史数据回放,用户可以选择实时监控或回放任意频率、任意时间段的交易活动。
图
2
.
订单簿分析
图
3
.
期货行情分析
实时流数据分析流程
DolphinDB + Panopticon 实时流数据分析流程如下图所示:
图
4
.
流数据处理流程
DolphinDB 订阅源数据并进行数据预处理。
预处理后的数据接入流数据引擎进行计算分析,DolphinDB
针对不同场景提供了多种流计算引擎,用户可以根据需要选择引擎或组合使用多种引擎共同完成计算任务。
计算完成的流数据表会被发布供消费端进行订阅及消费。
通过 Panopticon 流数据订阅接口接收 DolphinDB
发送的数据,并按业务需求制作仪表盘,供交易、分析、监控等相关人员使用。Panopticon
内置的聚合引擎、计算引擎和警报引擎可以满足不类型的图表制作以及完整性校验需求。
迭代、扩展和部署流处理计算系统。
迭代、扩展和部署可视化分析仪表盘。
此次 DolphinDB 与 Altair Panopticon
携手成功地搭建了高性能时序数据可视化分析平台,帮助用户实现实时数据的可视化分析,通过将大量复杂数据转化为直观的图形表达,用户可以轻松地访问、分析和可视化展示各种数据、理解数据趋势和信息规律,从而更高效的实现数据价值。
使用方法
如需了解 Altair 连接 DolphinDB 数据源的方法,请联系 DolphinDB 技术支持。
FILE:references/doc_7228.md
# getTraces
**URL**: https://docs.dolphindb.cn/zh/progr/sql/getTraces.html
**来源**: DolphinDB 官方文档
---
getTraces
语法
getTraces()
参数
无
详情
获取跟踪信息,返回一张表,包含以下几列:
time:客户端将脚本发送给 server 的时间戳。
scripts:客户端发送给 server 端执行的脚本。部分脚本(如下例:objs11
等)是客户端调用的脚本,可以忽略。
traceId:记录 SQL Trace 信息的 id,配合
viewTraceInfo
函数可以展示该脚本完整的跟踪信息。
sessionId:发起 SQL Trace 的会话的 id。
例子
getTraces();
time
scripts
traceId
sessionId
2022.09.26T08:50:48.486114674
setTraceMode(false)
db80c71c-51e4-4fa5-524c-8230a9e14259
2,333,906,441
2022.09.26T08:50:45.202118926
[n,db,[0, 0]]
078cafbc-003c-6495-e248-58f111d973c4
2,333,906,441
2022.09.26T08:50:45.196684636
objs11
50e9d859-2d4d-368d-c641-71f239325926
2,333,906,441
2022.09.26T08:50:45.150871346
login("admin", "123456")
if(existsDatabase("dfs://tedb")){
dropDatabase("dfs://tedb")
}
n=30
ticker = rand(`MSFT`GOOG`FB`ORCL`IBM`PPT`AZHILM`ANZ,n);
id = rand(`A`B`C, n)
x=rand(1.0, n)
t=table(ticker, id, x)
select *, x>0.5 as x1 from t
db=database(directory="dfs://tedb", partitionType=HASH, partitionScheme=[STRING, 5])
pt = db.createPartitionedTable(t, `pt, `ticker)
pt.append!(t)
update t set x = 1 where id = `A
64ae3ac9-3963-6eab-c244-48bd1c0adc80
2,333,906,441
2022.09.26T08:50:37.921672908
objs11
a2c39b23-8260-1cb7-ab4b-205429c0c60d
2,333,906,441
FILE:references/doc_7233.md
# startHeapSample
**URL**: https://docs.dolphindb.cn/zh/funcs/s/startheapsample.html
**来源**: DolphinDB 官方文档
---
startHeapSample
语法
startHeapSample(sampleParameter)
详情
用于动态启用堆内存采样。调用后将动态设置环境变量 TCMALLOC_SAMPLE_PARAMETER
的值,从而使开发者能够监控和分析程序的内存使用情况。仅管理员可执行该函数。
参数
sampleParameter
长整型标量,表示采样阈值,单位为字节。在分配到指定字节的内存后会,将进行一次内存采样。取值范围是 [1,
524288],建议设置为 524288。
例子
对内存使用情况进行分析的流程如下:
启用堆内存采样。
在可能发生内存泄漏的操作前、后分别执行
dumpHeapSample
,保存两个不同的文件。通过对比两个文件,确认操作涉及到的内存分配和使用情况。
关闭堆内存采样。
startHeapSample(524288)
dumpHeapSample("/DolphinDB/Data/heap1")
dumpHeapSample("/DolphinDB/Data/heap2")
stopHeapSample()
相关函数:
dumpHeapSample
,
stopHeapSample
FILE:references/doc_7235.md
# setMemLimitOfTaskGroupResult
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setMemLimitOfTaskGroupResult.html
**来源**: DolphinDB 官方文档
---
setMemLimitOfTaskGroupResult
语法
setMemLimitOfTaskGroupResult(memLimit)
详情
在线修改当前节点发送的批量子查询占用的内存上限。该命令只能由管理员在数据节点/计算节点执行。
相关函数:
getMemLimitOfTaskGroupResult
参数
memLimit
数值类型标量,表示内存上限。单位为 GB。
FILE:references/doc_7239.md
# revokeStreamingSQLTable
**URL**: https://docs.dolphindb.cn/zh/funcs/r/revokeStreamingSQLTable.html
**来源**: DolphinDB 官方文档
---
revokeStreamingSQLTable
语法
revokeStreamingSQLTable(tableName)
详情
注销一个通过
declareStreamingSQLTable
声明的流式 SQL 表。
只能取消当前用户自己声明的表。
注销前,必须先取消在该表上已注册的所有流式 SQL 查询。
注销操作仅移除表的流式 SQL 功能,不会删除表本身或表中的数据。
参数
tableName
字符串标量,表示已声明的流式 SQL 表的名称。
例子
t=table(1..10 as id,rand(100,10) as val)
share t as st
declareStreamingSQLTable(st)
registerStreamingSQL("select avg(val) from st","sql_avg")
// 取消已注册的流式 SQL 查询
revokeStreamingSQL("sql_avg")
// 注销流式 SQL 表
revokeStreamingSQLTable(`st)
相关函数:
declareStreamingSQLTable
,
listStreamingSQLTables
,
registerStreamingSQL
,
revokeStreamingSQL
FILE:references/doc_7243.md
# isOrderedDict
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isOrderedDict.html
**来源**: DolphinDB 官方文档
---
isOrderedDict
语法
isOrderedDict(X)
参数
X
一个字典对象。
详情
判断
X
是否为一个有序字典:
如果是,返回
true
;
如果不是,
false
。
返回值
布尔标量。
例子
x=1 5 3
y=4.5 7.8 4.3
z=dict(x,y);
isOrderedDict(z)
// output: false
z1=dict(x,y,true);
isOrderedDict(z1)
// output: true
FILE:references/doc_7245.md
# prev
**URL**: https://docs.dolphindb.cn/zh/funcs/p/prev.html
**来源**: DolphinDB 官方文档
---
prev
语法
prev(X)
详情
将
X
向右移动一个位置。类似地:
next
将
X
向左移动一个位置;
move
可以将
X
向左或向右移动一个位置。
参数
X
可以是向量、矩阵或表。
返回值
一个向量、矩阵或表。
例子
x=3 9 5 1 4;
prev(x);
// output: [,3,9,5,1]
x = matrix(1 2 3 4 5);
prev(x)#0
#0
1
2
3
4
t=table(1 2 3 as a, `x`y`z as b, 10.8 7.6 3.5 as c);
prev(t)
a
b
c
1
x
10.8
2
y
7.6
FILE:references/doc_7248.md
# registerStreamingSQL
**URL**: https://docs.dolphindb.cn/zh/funcs/r/registerStreamingSQL.html
**来源**: DolphinDB 官方文档
---
registerStreamingSQL
语法
registerStreamingSQL(query, [queryId],
[logTableCacheSize])
详情
注册一条流式 SQL 查询,成功注册后返回一个唯一的
queryId
。系统会基于该查询生成一个与
queryId
同名的共享流表,用于写入结果变更日志。
注意:
仅被声明的表才能通过
registerStreamingSQL
注册流式 SQL 查询。
参数
query
字符串标量,表示要注册的流式 SQL 查询语句。
queryId
可选参数,字符串标量,表示
query
对应的 ID
名称。格式要求与变量名相同,只能包含字母、数字及下划线,且必须以字母开头。
若指定的
queryId
已存在,系统会自动在其后追加时间戳生成唯一 ID。
若不指定,系统自动生成唯一 ID。
logTableCacheSize
可选参数,正整数,表示结果变更日志在内存中的最大缓存条数,默认缓存全部。只要存在订阅,缓存中未发布的数据就会被保留,不会被清理。已发布数据清理规则如下:
若单次插入的日志条数不超过
logTableCacheSize
,当内存中数据总条数达到
logTableCacheSize
* 2
时,开始清理旧数据。
若单次插入的日志条数超过
logTableCacheSize
,当内存中数据总条数达到插入行数与
logTableCacheSize
之和的1.2倍,开始清理旧数据。
返回值
字符串标量。
例子
t=table(1..10 as id,rand(100,10) as val)
share t as st
declareStreamingSQLTable(st)
registerStreamingSQL("select avg(val) from st","sql_avg")
// 查看流式 SQL 查询的状态
getStreamingSQLStatus("sql_avg")
相关函数:
declareStreamingSQLTable
,
registerStreamingSQL
FILE:references/doc_725.md
# invWeibull
**URL**: https://docs.dolphindb.cn/zh/funcs/i/invWeibull.html
**来源**: DolphinDB 官方文档
---
invWeibull
语法
invWeibull(alpha, beta, X)
详情
返回Weibull分布的累计密度函数的逆函数值。
参数
alpha
和
beta
为形状参数,都是正数。
X
是0到1之间的浮点型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
invWeibull(2.31, 0.627, [0.001, 0.5, 0.999]);
// output: [0.031525, 0.535009, 1.447494]
invWeibull(2.31,0.627, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output: [0.236692, 0.401279, 0.535009, 0.679464, 0.899644]
FILE:references/doc_7258.md
# expr
**URL**: https://docs.dolphindb.cn/zh/funcs/e/expr.html
**来源**: DolphinDB 官方文档
---
expr
语法
expr(args...)
详情
函数
expr
从对象、运算符或其他元代码生成元代码。
参数
args
可以是对象、运算符或元代码。元代码是由"<"和">"包围的对象和/或表达式。参数的最小数量为2。
返回值
CODE 类型元代码。
例子
expr(6,<,8);
// output
< 6 < 8 >
expr(sum, 1 2 3);
// output
< sum [1,2,3] >
a=6;
expr(a,+,1);
// output
< 6 + 1 >
expr(<a>,+,1);
// output
< a + 1 >
expr(<a>,+,<b>);
// output
< a + b >
expr(a+7,*,8);
// output
< 13 * 8 >
expr(<a+7>,*,8);
// output
< (a + 7) * 8 >
expr(not, < a >);
// output
< ! a >
FILE:references/doc_7260.md
# eig
**URL**: https://docs.dolphindb.cn/zh/funcs/e/eig.html
**来源**: DolphinDB 官方文档
---
eig
语法
eig(A)
详情
返回一个字典,为矩阵 A 的特征值与特征向量。
该函数的计算结果与
numpy.linalg.eigh
函数的结果保持一致。
参数
A
是一个实对称矩阵或 Hermitian(共轭对称)矩阵。
例子
A = 1 1 2 7 9 3 5 7 0 $ 3:3;
eig(A);
// output
vectors->
#0 #1 #2
--------- -------- ---------
0.839752 0.169451 -0.515852
-0.301349 0.935753 -0.18318
0.45167 0.309277 0.836864
values->[1.716868,10.17262,-1.889488]
对应第一个特征值 1.716868 的特征向量为:
eig(A).vectors[0];
// output
[0.839752,-0.301349,0.45167]
FILE:references/doc_7284.md
# Python API 接入数据
**URL**: https://docs.dolphindb.cn/zh/stream/str_api_python.html
**来源**: DolphinDB 官方文档
---
Python API 接入数据
实时流数据接入是指将数据从数据源实时写入 DolphinDB 中,供后续进行清洗、计算等使用。本文档介绍如何使用 Python API 把数据写入 DolphinDB。
按照上游发布端数据产生频率大小推荐不同的写入接口:
当数据实时写入频率小于 100 条每秒时,推荐使用
tableInsert
同步写入接口,其写入延时相对其它接口是最低的。
当数据实时写入频率大于 100 条每秒时,推荐使用
MultithreadedTableWriter
异步写入接口,其吞吐量和写入延时综合效益最高。
下面将介绍两种场景下推荐函数的使用方法和基准性能。
如果本文档中遇到 DolphinDB Python API 使用相关问题,参考:
Python API
。
tableInsert 同步写入接口
当数据实时写入频率小于 100 条每秒时,推荐使用
tableInsert
同步接口写入数据。本文档提供 10
列数据的写入示例和基准性能。
step1:创建共享普通流数据表
import
dolphindb
as
ddb
import
numpy
as
np
import
pandas
as
pd
import
random
s = ddb.session()
s.connect(host=
"localhost"
, port=
8848
, userid=
"admin"
, password=
"123456"
)
script =
"""
name = `c1Time`c2Symbol`c3Int`c4Int`c5Long`c6Long`c7Float`c8Float`c9Double`c10ArrayInt
type = [TIMESTAMP, SYMBOL, INT, INT, LONG, LONG, FLOAT, FLOAT, DOUBLE, INT[]]
share(table=streamTable(20000:0, name, type), sharedName="sharedMinBar")
"""
s.run(script)
注意:生产环境推荐使用共享持久化流数据表。
step2:tableInsert 写入数据
def
createData():
c1Time = [pd.Timestamp.now()]
c2Symbol = [
'000001'
]
c3Int = [random.randint(
0
,
10
)]
c4Int = [random.randint(
0
,
10
)]
c5Long = [random.randint(
0
,
1000
)]
c6Long = [random.randint(
0
,
1000
)]
c7Float = [random.uniform(
0
,
1
)]
c8Float = [random.uniform(
0
,
1
)]
c9Double = [random.uniform(
0
,
1
)]
c10ArrayInt = [np.random.randint(
10
,size=
10
)]
return
[c1Time, c2Symbol, c3Int, c4Int, c5Long, c6Long, c7Float, c8Float, c9Double, c10ArrayInt]
if
__name__ ==
"__main__"
:
inertRows =
10000
for
i
in
range(inertRows):
insertData = createData()
s.run(
"tableInsert{sharedMinBar}"
,insertData)
step3:查询表中数据
pd = s.run(
"select * from sharedMinBar limit 10"
)
step4:删除流数据表并关闭当前会话
script =
"""
dropStreamTable(tableName="sharedMinBar")
"""
s.run(script)
s.close()
基准性能
tableInsert
同步写入接口基准性能测试代码请参考附录 B,测试结果如下:
指标
性能(毫秒)
最小单次插入耗时
0.31
最大单次插入耗时
1.24
平均单次插入耗时
0.69
单次插入耗时统计图如下:
基准性能测试结果显示,DolphinDB Python API 的
tableInsert
同步写入接口具有以下特点:
实时逐条写入共享流数据表的平均耗时是 0.69 毫秒。
稳定性较好,波动较小,平均单条数据写入的最大耗时小于 2 毫秒。
MultithreadedTableWriter 异步写入接口
当数据写入频率大于 100 条每秒时,推荐使用
MultithreadedTableWriter
(MTW) 函数写入数据。
如下图所示,
MultithreadedTableWriter
函数把 Python 端实时产生的数据先通过 insert 线程写入
MTW 消息队列,同时 append 线程会批量取出消息队列的数据,自动转换数据类型后把数据写入 DolphinDB。
下面为
MultithreadedTableWriter
使用示例。
逐笔成交表
import
numpy
as
np
import
pandas
as
pd
import
dolphindb
as
ddb
import
random
import
datetime
s = ddb.session()
s.connect(host=
"localhost"
, port=
8848
, userid=
"admin"
, password=
"123456"
)
writer = ddb.MultithreadedTableWriter(
"localhost"
,
8848
,
"admin"
,
"123456"
,
""
,
"tglobal"
,False,False,[],
10
,
0
,
2
,
"SecurityID"
)
start = datetime.datetime.now()
for
i
in
range(
100
):
res = writer.insert(random.randint(
1
,
100
),random.randint(
1
,
100
),str(i),random.randint(
1
,
100
),random.randint(
1
,
100
),str(i),str(i),random.random(),random.randint(
1
,
100
),str(i),np.datetime64(
'2021-01-04T09:30:02.000'
),
9
,random.randint(
1
,
100
),random.randint(
1
,
100
),random.random(),str(i),random.randint(
1
,
100
),str(i),str(i))
writer.waitForThreadCompletion()
print
(writer.getStatus())
// output
'''
errorCode : None
errorInfo :
isExiting : True
sentRows : 10000
unsentRows : 0
sendFailedRows: 0
threadStatus :
threadId sentRows unsentRows sendFailedRows
0 0 0 0
2474632960 4994 0 0
2483025664 5006 0 0
<dolphindb.session.MultithreadedTableWriterStatus object at 0x7f0ca9f0e8d0>
'''
arrayVector 类型快照表
writer = ddb.MultithreadedTableWriter(
"localhost"
,
8892
,
"admin"
,
"123456"
,
""
,
"tglobal"
,False,False,[],
10
,
0
,
2
,
"SecurityID"
)
for
i
in
range(
10000
):
res = writer.insert(str(i),np.datetime64(
'2021-01-04T09:30:02.000'
),random.random(),random.random(),random.random(),random.random(),random.random(),random.randint(
1
,
100
),random.random(),
"OCALL"
,np.random.rand(
10
),np.random.randint(
10
,size=
10
),np.random.randint(
10
,size=
10
),np.random.randint(
10
,size=
10
),np.random.rand(
10
),np.random.randint(
10
,size=
10
),np.random.randint(
10
,size=
10
),np.random.randint(
10
,size=
10
),random.randint(
1
,
100
),random.random(),random.randint(
1
,
100
),random.randint(
1
,
100
),random.random(),random.random(),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.random(),random.randint(
1
,
100
),random.randint(
1
,
100
),random.random(),random.randint(
1
,
100
),random.randint(
1
,
100
),random.random(),random.randint(
1
,
100
),random.randint(
1
,
100
),random.random())
writer.waitForThreadCompletion()
print
(writer.getStatus())
// output
'''
errorCode : None
errorInfo :
isExiting : True
sentRows : 10000
unsentRows : 0
sendFailedRows: 0
threadStatus :
threadId sentRows unsentRows sendFailedRows
0 0 0 0
2474632960 4994 0 0
2466240256 5006 0 0
<dolphindb.session.MultithreadedTableWriterStatus object at 0x7f0cb032e190>
'''
multicolumn 类型快照表
writer = ddb.MultithreadedTableWriter(
"localhost"
,
8892
,
"admin"
,
"123456"
,
""
,
"tglobal"
,False,False,[],
10
,
0
,
2
,
"SecurityID"
)
for
i
in
range(
10000
):
res = writer.insert(str(i),np.datetime64(
'2021-01-04T09:30:02.000'
),random.random(),random.random(),random.random(),random.random(),random.random(),random.randint(
1
,
100
),random.random(),str(i),random.random(),random.random(),random.random(),random.random(),random.random(),random.random(),random.random(),random.random(),random.random(),random.random(),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.random(),random.random(),random.random(),random.random(),random.random(),random.random(),random.random(),random.random(),random.random(),random.random(),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.random(),random.randint(
1
,
100
),random.randint(
1
,
100
),random.random(),random.random(),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.randint(
1
,
100
),random.random(),random.randint(
1
,
100
),random.randint(
1
,
100
),random.random(),random.randint(
1
,
100
),random.randint(
1
,
100
),random.random(),random.randint(
1
,
100
),random.randint(
1
,
100
),random.random())
writer.waitForThreadCompletion()
print
(writer.getStatus())
// output
'''
errorCode : None
errorInfo :
isExiting : True
sentRows : 10000
unsentRows : 0
sendFailedRows: 0
threadStatus :
threadId sentRows unsentRows sendFailedRows
0 0 0 0
2474632960 4994 0 0
2466240256 5006 0 0
<dolphindb.session.MultithreadedTableWriterStatus object at 0x7f0ca9b37fd0>
'''
附录 A-测试环境
表
1
.
硬件环境
硬件名称
配置信息
CPU
Intel(R) Xeon(R) Silver 4216 CPU @ 2.10GHz
内存
32 GB
磁盘
SSD 500 GB
表
2
.
软件环境
软件名称
版本信息
操作系统
CentOS Linux 7 (Core)
内存
3.10.0-1160.el7.x86_64
DolphinDB server
2.00.10.9 2023.12.09
DolphinDB Python API
1.30.22.6
Python
3.11.5
Numpy
1.24.4
Pandas
2.1.1
附录 B-tableInsert 同步写入接口基准性能测试代码
import
dolphindb
as
ddb
import
numpy
as
np
import
pandas
as
pd
import
random
#模拟数据
def
createData():
c1Time = [pd.Timestamp.now()]
c2Symbol = [
'000001'
]
c3Int = [random.randint(
0
,
10
)]
c4Int = [random.randint(
0
,
10
)]
c5Long = [random.randint(
0
,
1000
)]
c6Long = [random.randint(
0
,
1000
)]
c7Float = [random.uniform(
0
,
1
)]
c8Float = [random.uniform(
0
,
1
)]
c9Double = [random.uniform(
0
,
1
)]
c10ArrayInt = [np.random.randint(
10
,size=
10
)]
return
[c1Time, c2Symbol, c3Int, c4Int, c5Long, c6Long, c7Float, c8Float, c9Double, c10ArrayInt]
if
__name__ ==
"__main__"
:
#与DolphinDB建立会话
s = ddb.session()
s.connect(host=
"localhost"
, port=
8200
, userid=
"admin"
, password=
"123456"
)
#创建共享普通流数据表
script =
"""
name = `c1Time`c2Symbol`c3Int`c4Int`c5Long`c6Long`c7Float`c8Float`c9Double`c10ArrayInt
type = [TIMESTAMP, SYMBOL, INT, INT, LONG, LONG, FLOAT, FLOAT, DOUBLE, INT[]]
share(table=streamTable(20000:0, name, type), sharedName="sharedMinBar")
"""
s.run(script)
#测试写入数据行数
inertRows =
10000
#延时统计
minCostTime =
1000.0
maxCostTime =
0.0
totalCostTime =
0.0
count =
0
for
i
in
range(inertRows):
insertData = createData()
startTime = pd.Timestamp.now()
s.run(
"tableInsert{sharedMinBar}"
,insertData)
delta = (pd.Timestamp.now() - startTime) / np.timedelta64(
1
,
'ms'
)
if
(delta < minCostTime):
minCostTime = delta
if
(delta > maxCostTime):
maxCostTime = delta
totalCostTime += delta
count +=
1
#每隔一段时间打印写入性能测试结果
if
(count %
10000
==
0
):
print
(f
"min: {minCostTime} ms"
)
print
(f
"max: {maxCostTime} ms"
)
print
(
"count:"
, count)
print
(f
"totalCostTime: {totalCostTime} ms"
)
print
(f
"avg: {totalCostTime / count} ms"
)
#删除流数据表
script =
"""
dropStreamTable(tableName="sharedMinBar")
"""
s.run(script)
#关闭当前会话
s.close()
FILE:references/doc_7286.md
# file
**URL**: https://docs.dolphindb.cn/zh/funcs/f/file.html
**来源**: DolphinDB 官方文档
---
file
语法
file(name, [mode="r"], [isLittleEndian])
详情
file 函数通过给定的模式打开一个文件。该函数必须要用户登录后才能执行。
打开的模式可以是以下 6 种之一:"r", "r+", "w", "w+", "a" 和 "a+"。默认的模式是 "r"
(只读)。
close
函数用于关闭一个打开的文件。
"r": 只读模式。游标位于文件头。
"r+": 读写模式。游标位于文件头。
"w": 只写模式,把文件清空。游标位于文件头。
"w+": 读写模式。如果文件不存在将创建文件,否则把文件清空。游标位于文件头。
"a":
追加模式(只写)。如果文件不存在将创建文件。游标位于文件尾,从文件尾开始写。连续地写文件,每次写完后,游标都会位于文件尾。
"a+":
追加模式(读写)。如果文件不存在将创建文件。游标位于文件尾,从文件尾开始读写。连续地写文件,每次写完后,游标都会位于文件尾。
参数
name
字符串,表示文件名称。
mode
字符串,表示打开的模式。
isLittleEndian
布尔值,表示是否采用小端模式。默认情况下,采用的是操作系统的大小端模式。它是一个可选参数。
返回值
一个句柄(HANDLE)。
例子
fout=file("test.txt","w");
fout.writeLine("hello world!");
// output
1
fout.close();
fin = file("test.txt");
print fin.readLine();
// output
hello world!
fin.close();
FILE:references/doc_7287.md
# VS Code 插件
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/vscode.html
**来源**: DolphinDB 官方文档
---
VS Code 插件
VS Code
是微软开发的一款轻便又有极强扩展性的代码编辑器。它提供强大的插件框架,可通过插件支持不同编程语言,达到语法高亮、智能语法提示以及代码运行等效果。
DolphinDB 开发了针对 Dolphin Script 的 VS Code 插件。用户可以通过该插件编写并执行脚本来操作 DolphinDB
数据库,或查看数据库中的数据。该插件具备以下主要功能:
智能提示与编辑增强
代码高亮。
关键字、常量、内置函数的代码补全。
内置函数的文档提示、参数提示。
函数名、变量名提示。
其他模块中的函数名提示。
模块导入提示。
连接到数据库后,支持库表名称和字段名称提示。
代码导航与执行管理
函数定义跳转。
变量定义跳转。
终端可以展示代码执行结果以及
print
函数输出的消息。
在底栏中展示执行状态,点击后可取消作业。
数据管理与可视化
在底部面板中以表格的形式展示表格、向量、矩阵等数据结构。
在侧边面板中管理多个数据库连接,展示数据库表及会话变量。
在浏览器弹窗中显示表格、向量、矩阵等数据结构。
支持从 DolphinDB 导出表数据到磁盘(.csv 格式 文件)。
图
1
.
界面
使用方法
安装如下:
前往
下载页面
安装或升级
VS Code,插件版本:
3.0.210 以下:要求 VS Code v1.68.0 及以上;
3.0.210 及以上:要求 VS Code v1.82.0 及以上。
在 VS Code 插件面板中搜索 dolphindb, 点击 Install
安装插件。如因网络原因安装遇阻,可以前往
下载链接
手动下载后缀为
.vsix
的插件,下载后拖到 VS
Code 插件面板中。
点击 Version History 下载最新的版本到本地。安装插件后,退出 VS Code
所有窗口并重新打开 VS Code,否则可能无法在浏览器中查看变量(见后文)。
查看、编辑服务器连接配置方法
成功安装插件后,在 VS Code 编辑器的活动栏(Activity Bar)中会显示一个表示
DolphinDB 数据库管理面板的图标。点击该图标可以在左侧边栏中看到 DolphinDB 面板,包含连接、数据库、变量管理三个子面板。
图
2
.
连接管理
点击右上角的
settings
按钮。
在
settings.json
配置文件中编辑
dolphindb.connections
配置项。
name
和
url
属性是必填的(不同的连接对象必须有不同的
name
),默认自动登录 admin 账号("autologin":
true)。将光标移动到属性上可以查看对应属性的说明。
dolphindb.connections
配置项是一个对象数组,默认有四个连接配置,可按情况修改或增加连接对象。
打开或新建一个 DolphinDB 脚本文件
点击 VS Code 编辑器右下角状态栏的语言选择按钮,如下图
图
3
.
语言选择
在语言选择弹框中输入
dolphindb
,
按回车键将当前文件关联的语言切换为 DolphinDB 语言。
图
4
.
语言切换
注:
如果脚本文件名是
.dos
后缀(DolphinDB Script
的缩写),插件会自动识别为 DolphinDB 语言,自动启用语法高亮及代码补全、提示
如果脚本文件名不是
.dos
后缀, 比如
.txt
后缀,则需要手动关联 DolphinDB 语言,方法如下:
执行代码
在打开的 DolphinDB 脚本文件中,按快捷键
Ctrl + E
将代码发送到 DolphinDB
Server 执行。第一次执行代码时会自动连接到 DOLPHINDB 区域中选中的连接。
如果当前有选中的代码,会将选中的代码发送至 DolphinDB Server 执行
如果当前无选中的代码,会将当前光标所在的行发送至 DolphinDB Server 执行
执行代码后,VS Code
编辑器下方的终端内会有基于文本的输出,如果执行的代码最后一条语句返回了表格、数组、矩阵,则会自动切换到 VS Code 编辑器下方面板的 DolphinDB
区域中以表格的形式展示表格、向量、矩阵等数据结构。
提示:
将 DolphinDB 标签页的内容拖动到终端的右侧,如下图
图
5
.
代码执行
代码提示
DolphinDB 的 VS Code
插件为脚本编辑提供基于上下文和工作区的代码提示,帮助用户更便捷地使用自定义函数、跳转至函数或变量定义,并高效编写数据库查询语句。
定义跳转
VS Code 插件支持跳转到选定函数或变量的定义。对于函数,还可跨模块跳转至从其他模块引入的函数(前提是目标模块位于当前工作区内)。
函数定义跳转
将光标移动到目标函数上。按下 F12,或右键单击选择“转到定义”。
图
6
.
跳转到定义
编辑器将跳转到该函数的定义位置。
变量定义跳转
变量定义跳转的使用方式与函数定义跳转相同,但不支持跨模块跳转。
函数名与变量名提示
在编辑代码时,可自动补全已定义的函数名或变量名称,并提供相关描述。
在
函数或变量定义
上方添加注释时,代码提示将以描述的形式展示这些注释,便于理解其作用。
若使用规范格式编写函数注释,可自动生成函数文档,并在提示描述中显示。
跨模块函数名提示
处于
工作区
内的模块文件中的函数,在编辑代码时可被
自动补全
。例如,在
LanguageServer::ModuleExample
模块中定义了一个函数,在工作区的其他文件中输入其名称的一部分,系统会自动补全,并在描述中显示该函数所属的模块。
如果当前文件尚未引入该模块,插件会自动在文件顶部添加模块引入语句。
此外,在函数调用补全时,插件会补全完整的函数名称(包含模块名),避免命名冲突,确保代码的清晰度和可读性。
模块导入提示
在输入
use
时,自动提示当前工作区内的可用模块名称。
数据库对象提示
在编写数据库查询语句时自动提示数据库、表、字段等对象名称,需先通过插件连接到数据库。当输入
select from
时,自动提示 Catalog 和共享变量中的表名。
当输入
loadTable
时,自动提示分布式数据库的库名和表名。
库表名称确定后,在
order by
,
where
,
group
by
等语句中,可自动补全
字段名称
及
常用关键字
(如
asc
、
desc
)。
查看变量
切换执行代码所用的连接 (原有连接不会断开)
点击连接右侧的按钮手动断开连接
查看会话变量的值
非 scalar, pair 类型的变量右侧有两个图标
点击左边的图标,在编辑器下方面板的 DolphinDB 区域中查看变量
点击右边的图标,在浏览器弹窗中查看变量 (需要配置浏览器允许弹窗,
见后文)。弹窗功能需要浏览器中有一个打开的
DolphinDB Data Browser
标签页
(URL 可能是 http://localhost:8321/),如果缺少这个标签页,插件会先自动打开这个页面:
如下图所示:
图
7
.
数据浏览器
注:
请使用近两年的浏览器版本,例如 Chrome 100+ 或 Edge 100+ 或 Firefox
100+,并配置浏览器允许该网站弹窗显示。
图
8
.
弹窗显示设置
查看函数
在 VS Code 编辑器中输入 DolphinDB 内置函数时,点击函数右侧的箭头可以展开函数的文档:
图
9
.
查看函数说明
函数输入完成后,将鼠标悬浮于函数名称上,也可查看函数文档。
如果需要将函数名高亮显示,可在 VS Code 配置文件
settings.json
中加上下面的 textmate
规则:
"editor.tokenColorCustomizations"
: {
"textMateRules"
: [
// function: bold
{
"scope"
:
"entity.name.function"
,
"settings"
: {
"fontStyle"
:
"bold"
}},
{
"scope"
:
"support.function"
,
"settings"
: {
"fontStyle"
:
"bold"
}} ,
]
},
上传文件
用户可以通过 DolphinDB 的 VS Code 插件以下述两种方式上传文件:
在 VS Code 的资源管理器中选中需要上传的文件并右击,在右键菜单中选择
DolphinDB:
上传到服务
。
打开需要上传的文件后,在 VS Code 界面的右上角单击上传按钮。之后,需要用户输入上传到 server
的文件路径(不能为空)。回车后,等待提示
文件成功上传
即可。
此外,用户可以通过配置
dolphindb.connections
的
mappings
属性来自定义本地路径和 server 路径的映射关系,方便插件在后续文件上传过程根据
mappings 映射 server 路径。在 VS Code 设置界面,选中扩展下的 DolphinDB,打开
setting.json
文件,在需要配置的 connection 中添加或修改
mappings
中的键值对 ,左侧 "键" 为本地地址,右侧 "值"
为服务器地址。
图
10
.
配置项
添加完成后,插件会根据当前连接中用户配置的
mappings
对路径进行映射。
例如,用户当前连接中配置的
mappings
为:
{
"/path/to/local/": "/path/at/remote/",
"/path/to/local/dir1/": "/data/server/dir1/",
"D:/path/to/local/": "/data/server/",
"default": "/data/server/"
}
文件上传时路径映射的规则如下:
以自动的方式进行映射,
key
代表本地路径,
value
代表 server
路径,配置完成后,会选择最长匹配项作为上传路径。例如,用户上传的文件路径为
/path/to/local/dir1/file.dos
,此时,同时存在
/path/to/local/
和
/path/to/local/dir1/
均可匹配用户路径,但以最长匹配项
/path/to/local/dir1/
优先匹配。
可配置
default
字段作为默认匹配。如果当前路径没有匹配
dolphindb.mappings
中的其余项,则以
default
对应的 server 路径作为上传路径。例如,用户上传的文件路径为
/user/dosuments/file.dos
,此时匹配不到
mappings
的其余项,则以
default
字段映射的 server
路径作为上传路径,即
/data/server/file.dos
。
若
dolphindb.mappings
中没有匹配项,则以
getHomeDir()
+
/uploads/
+
文件名
作为上传路径。
导出文件
注意,该功能要求 server 版本不小于 2.00.11。导出步骤如下:
运行需要保存的表,使其展示在数据视图中。
点击数据视图右上角的“DolphinDB:导出表格”的图标。
选择保存路径,编辑文件的名称后,点击保存按钮,将表数据保存至指定路径。此时在右下角会显示“文件成功导出到 xxxx”。
调试脚本
DolphinDB 的 VS Code
插件可用于调试用户脚本,用户可以使用实时追踪运行脚本、显示中间变量的值以及展示函数调用栈信息等功能,从而写出更快更好的脚本。
注:
Python Parse 不支持调试功能。
使用调试功能之前,请确保 DolphinDB Server 版本不低于 2.00.10.1 或 1.30.22.1。
具体调试方法如下:
图
11
.
调试方法
其中,
Debug Server(DolphinDB Server):真正执行中断、挂起、数据查询操作的数据库进程
Debug Adapter:处理两侧的交互信息
DAP:Debug Adapter Protocol,由 Microsoft 提出的一种通用的 Debug
信息交互协议
Debug Client:VS Code 调试界面,主要负责与用户交互。下图是该界面的主要部件及功能概览:
图
12
.
调试界面
编写脚本的方法如下:
后续步骤介绍基于以下例子脚本。出于调试目的以及代码可读性,我们建议每行只写一条语句。
use ta
close = 1..20
bret = bBands(close)
print(bret)
close = randNormal(50, 1, 20)
rret = rsi(close)
print(rret)
设置断点的方法如下:
在选定行左侧空白处单击鼠标左键设置断点。
图
13
.
设置断点
为了接下来的调试演示,我们在第 4 行和第 8
行分别设置了断点,设置断点后,编辑器区的左侧空白区域处会出现红色的圆点,表示断点设置成功。
图
14
.
断点设置成功
启动调试的方法如下:
在左下角的连接管理面板中选择用于调试的服务器。
图
15
.
选择调试服务器
在底部状态栏中设置语言模式为
DolphinDB
。
图
16
.
设置语言模式
按
F5
或通过左侧边栏的运行和调试打开主边栏,点击
运行和调试
。
图
17
.
运行和调试
启动后的界面如下图所示,
图
18
.
启动后界面
其中,
调试界面的左侧是调试信息区,右侧是编辑器区,下方是调试控制台。
调试信息区展示变量的值、函数调用栈等信息。
编辑器区用黄色的背景标出了将要执行的行。
调试控制台用于显示输出信息和异常信息。
注:
调试过程如果无法启动,打开调试控制台,通过错误信息检查排查错误原因。可能的错误原因包括:
DolphinDB Server 版本太低会报错
Server sent no
subprotocol
,调试服务器连接失败,请确保 DolphinDB Server 版本不低于 2.00.10.1 或
1.30.22.1。
调试方法如下:
启动调试后,VS Code 的界面上方会出现如下图所示的调试工具栏:
图
19
.
调试工具栏
从左到右的名称及对应的键盘快捷键分别为:
继续(F5)
逐过程(F10)
单步调试(F11)
单步跳出(Shift + F11)
重启(Ctrl + Shift + F5)
停止(Shift + F5)
提示:
继续、逐过程和单步调试是调试中最常用的三个功能,推荐使用快捷键来操作。
用于调试的按钮功能和使用方法如下:
逐过程(F10):在上个调试界面中,黄色的背景标出了即将被 Server 执行的第 4 行代码所对应的语句。我们按下
F10,让 Server 程序执行完第 4 行代码。此时的调试界面如下图所示,黄色的背景变成了第 5 行代码所对应的语句。
图
20
.
逐过程
继续(F5):我们可以利用逐过程的方式一条语句一条语句地执行脚本,但是这样做的效率较低。着重关注断点所在的语句有助于提升执行调试效率。在这里,我们关心的是第
8 行代码所对应的语句,按下 F5 后,Server 程序会一直执行到第 8 行代码。此时的调试界面如下图所示,黄色的背景变成了第 8
行代码所对应的语句。
图
21
.
继续
查看变量:在调试界面的左侧,即调试主边栏中,我们可以在略上方的位置看到变量的值,如下图所示:
图
22
.
查看变量
在这里,
close
和
bret
这两个变量因为过长而导致显示不全,我们可以将光标悬浮在变量的值上方,即可看到完整的值。
图
23
.
变量完整值
右键点击变量,选择”查看变量“,在数据视图中会展示该变量的详细信息。
图
24
.
查看变量
单步调试(F11):单步调试用于进入函数内部,查看函数内部的执行情况。在上一步,我们运行到了第8行代码,即
rsi
函数的调用语句。按下 F11 后,Server程序会进入
rsi
内。此时对应的调试界面如下图所示,黄色的背景标示程序已经运行到该函数内部,且即将执行第一条语句。
图
25
.
单步调试
查看调用堆栈:我们将目光再次移动到调试主边栏中。在略下方的位置,可以看到当前的函数调用栈,如下图所示。
图
26
.
查看调用堆栈
单击调用栈的某一行,就能在上游函数和下游函数之间切换。此时,调试主边栏上方的变量部分也会显示该层函数所对应的变量的值。
动态更新断点:在脚本执行的过程中,我们可以动态地更新断点。例如,我们可以在 152 行和 153
行的位置新增两个断点,如下图所示,编辑器区的左侧空白区域处会出现两个红色的圆点,表示断点已经新增成功。
图
27
.
动态更新断点
当然,我们也可以取消断点。例如,我们单击 152 行左侧空白处来删除 152
行对应的断点。如下图所示,编辑器区左侧空白区域处 152 行对应的红色圆点消失,表示 152 行处的断点已经取消成功。
跳出函数:实际过程中,我们经常需要执行完这个函数并返回上层函数。例如,我们点击调试工具栏中的单步跳出按钮
,即可执行完当前函数体的所有内容并返回到上一层函数。此时,如下图所示,我们已经返回到
test.dos
中的第9行代码所对应的语句,代表执行完第8行对应的
rsi
函数。
图
28
.
跳出函数
重启以及停止:重启和停止按钮的功能与其名字相符。例如,我们点击调试工具栏中的重启按钮
,即可重启调试;相应地,点击停止按钮
,即可停止调试。
语法解析的方法如下:
调试开始时, DolphinDB 会对代码进行初步检测, 如果代码有语法错误, 不会进入调试状态,
并且调试控制台会输出错误信息。
图
29
.
语法解析
断点管理的方法如下:
如下图所示,在调试主边栏的下方,可以看到所有断点的信息,包括断点的状态、断点的文件名和文件路径以及行号。值得注意的是右上方有两个按钮,禁用所有断点
以及删除所有断点
。
点击禁用所有断点
可以暂时关闭所有断点,恢复正常程序的执行;再次点击此按钮或者手动添加新断点时,会自动开启所有断点。
点击删除所有断点
可以删除所有断点,包括已经禁用的断点。
图
30
.
断点管理
多目标调试的方法如下:
在启动一个调试会话的同时, 启动另一个调试会话,VS Code 即可自动切换到多目标模式:
各个会话现在在
调用堆栈
视图中显示为顶级元素。
图
31
.
调用堆栈
调试工具栏显示当前活动的会话(所有其他会话在下拉菜单中可用)。
图
32
.
会话列表
调试操作(例如, 调试工具栏中的所有操作)在活动会话上执行可以使用调试工具栏中的下拉菜单或在
调用堆栈
视图中选择其他元素来更改活动会话。
以下脚本语法存在使用上的局限性:
functionview
能够通过初步语法检查,
但使用此类语法在调试时会出错。
含有
include
语句的脚本调试会报错“Does not support
Debug mode when using include”。可以考虑用
use
替代。
submitJob
,
remoteRun
等远程调用类函数不能跟踪函数栈调用。
匿名函数、lambda 表达式、闭包的用法。
暂不支持以下调试方法
内联断点、条件断点、记录点、监视
查看长度较大的变量
图
33
.
长度较大变量
常见问题
如果按
Ctrl + E
快捷键无反应:
可能是由于未关联 DolphinDB 语言(此时语法高亮也未生效)
也可能由于快捷键与其他插件冲突,需要在 VS Code 的
文件
>
首选项
>
键盘快捷方式
(
File
>
Preferences
>
Keyboard Shortcuts
`) 中自定义快捷键,在搜索框中输入
CTRL+E
, 删除和
DolphinDB: 执行代码
(DolphinDB: Execute Code) 冲突的其他插件的快捷键。
如果出现执行代码后一直卡在执行中,打开 vscode 顶部的
帮助 (Help)
>
切换开发人员工具
(DevTools)
在弹出的窗口中切换到控制台标签页查看,如果存在如下内容:
Webview fatal
error: Error: Could not register service workers: InvalidStateError:
Failed to register a ServiceWorker: The document is in an invalid
state..
,则按下面的步骤操作:
先更新 VS Code 到最新版本。
如果还不能解决,尝试下面的方法结束所有的
Code.exe
进程,并删除 service worker
缓存:
linux:
pkill code && rm -rf .config/Code/Service\
Worker/{CacheStorage,ScriptCache}
windows:
退出 vscode 之后,打开任务管理器,结束所有残留的 vscode 僵尸进程
taskkill
/F /IM Code.exe
在文件管理器中打开
C:/Users/你的用户名/AppData/Roaming/Code/Service
Worker/
删除
CacheStorage
和
ScriptCache
两个文件夹
如果操作以上内容后仍存在问题,则重启电脑。参考
https://github.com/microsoft/vscode/issues/125993
如果出现执行代码并返回表格后,底部没有自动切换到 DolphinDB 视图的情况,需要重置 DolphinDB
视图的位置,如下图所示
图
34
.
如果出现 dataview (数据视图)
面板右键隐藏后无法再次显示,且执行脚本一直卡在执行中的情况,尝试以下方法解决:
执行
defs()
函数
按
CTRL + SHIFT + P
呼出命令面板,搜索
open
view
点击打开视图
搜索数据视图(英文名是 dataview)
点击后即可打开。
VS Code 有大约为
1 GB
的内存限制。建议使用
limit
限制返回记录数;或者将结果赋给某个变量,如
a = select *
from
,后续通过点击侧边栏变量旁边的按钮进行分页懒加载,按需取回单页数据。
为了在浏览器中展示表格等数据,每个 VS Code 窗口会启动一个本地 HTTP 服务器,其可用端口范围可以通过
dolphindb.ports
配置,默认为
8321-8420
,鼠标悬浮在
ports 上可查看详细解释。在浏览器中弹窗展示的功能,要求近两年的版本,如 Chrome 100+ 或 Edge 100+ 或 Firefox
100+
若连接数据库时出现报错无法连接的报错,可参考下图关闭代理:
图
35
.
关闭代理
FILE:references/doc_731.md
# businessMonthBegin
**URL**: https://docs.dolphindb.cn/zh/funcs/b/businessMonthBegin.html
**来源**: DolphinDB 官方文档
---
businessMonthBegin
语法
businessMonthBegin(X, [offset], [n=1])
详情
返回
X
所在月份的第一个工作日(周一到周五)。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
月更新一次。注意,
offset
和
n
须同时指定,且只有当
n
>1时,
offset
才会生效。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP 类型的标量或向量。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
businessMonthBegin(2018.09.12);
// output
2018.09.03
businessMonthBegin(2018.09.12, 2018.07.12, 3);
// output
2018.07.02
date=2016.04.12+(1..10)*30
time = take(09:30:00, 10)
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
t1;
date
time
sym
qty
price
2016.05.12
09:30:00
MSFT
2200
49.6
2016.06.11
09:30:00
MSFT
1900
29.46
2016.07.11
09:30:00
MSFT
2100
29.52
2016.08.10
09:30:00
MSFT
3200
30.02
2016.09.09
09:30:00
MSFT
6800
174.97
2016.10.09
09:30:00
MSFT
5400
175.23
2016.11.08
09:30:00
MSFT
1300
50.76
2016.12.08
09:30:00
MSFT
2500
50.32
2017.01.07
09:30:00
MSFT
8800
51.29
2017.02.06
09:30:00
MSFT
4500
52.38
select avg(price),sum(qty) from t1 group by businessMonthBegin(date,2016.01.01,2);
businessMonthBegin_date
avg_price
sum_qty
2016.05.02
39.53
4100
2016.07.01
29.77
5300
2016.09.01
175.1
12200
2016.11.01
50.54
3800
2017.01.02
51.835
13300
相关函数:
businessMonthEnd
,
monthBegin
,
monthEnd
,
semiMonthBegin
,
semiMonthEnd
FILE:references/doc_7316.md
# sum2
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sum2.html
**来源**: DolphinDB 官方文档
---
sum2
语法
sum2(X)
详情
若
X
为向量,返回
X
中所有元素的平方和。
若
X
为矩阵,计算每列元素的平方和,返回一个向量。
若
X
为表,计算每列元素的平方和,返回一个表。
与所有其它聚合函数一致,计算时忽略 NULL 值。
即使
X
的数据类型是 INT 或 LONG,
sum2
返回结果的数据类型总是 DOUBLE 类型。如果
X
中的所有元素为 NULL,
sum2
返回的结果为 NULL。
参数
X
可以是标量、向量、矩阵或表。
返回值
返回标量、向量或表。
例子
sum2(1 2 3);
// output
14
sum2(1 NULL NULL);
// output
1
sum2(1.5 4.6 7.8);
// output
84.25
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
sum2(m);
// output
[14,77]
FILE:references/doc_7318.md
# point
**URL**: https://docs.dolphindb.cn/zh/funcs/p/point.html
**来源**: DolphinDB 官方文档
---
point
语法
point(X, Y)
详情
生成一个 POINT 类型的数据,用来存储坐标系中点的位置。
POINT 类型数据长度为16字节,其中低8位的数据存储于
X
中,高8位的数据存储于
Y
中。
参数
X
和
Y
是数值型的标量、数据对、向量或矩阵,支持的数据类型为 INTEGRAL
类(COMPRESSED、INT128 除外)和 FLOATING 类。
返回值
POINT 类型标量、向量。
例子
point(117.60972, 24.118418)
// output:
(117.60972, 24.118418)
point(1..5,6..10)
// output:
[(1, 6),(2, 7),(3, 8),(4, 9),(5, 10)]
FILE:references/doc_7322.md
# isNumeric
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isNumeric.html
**来源**: DolphinDB 官方文档
---
isNumeric
语法
isNumeric(X)
详情
判断
X
是否只包含数字。如果
X
中的所有字符都是数字,该函数返回 true,反之返回
false。对于空字符串(STRING 类型的 NULL 值),该函数返回 false。
参数
X
是字符或字符串类型的标量、向量或表。
返回值
返回布尔类型,数据形式同 X。
例子
isNumeric("123456");
// output: true
isNumeric("1And1");
// output: false
isNumeric("10.05");
// output: false
isNumeric(string());
// output: false
FILE:references/doc_7328.md
# getLeftStream
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getLeftStream.html
**来源**: DolphinDB 官方文档
---
getLeftStream
语法
getLeftStream(joinEngine)
详情
返回连接引擎左表的表结构对象。向该对象注入的数据,会注入到
joinEngine
中。
通过该函数,可以将一个引擎的计算结果直接注入到连接引擎中,实现引擎间的级联。
参数
joinEngine
创建连接引擎返回的对象。目前 DolphinDB 支持的连接引擎有:
createAsofJoinEngine
createEquiJoinEngine
createLookupJoinEngine
createWindowJoinEngine
createLeftSemiJoinEngine
返回值
返回一个表。
例子
share streamTable(1000:0, `time`sym`price, [TIMESTAMP, SYMBOL, DOUBLE]) as trades
output=table(100:0, `timestamp`sym`price1`price2, [TIMESTAMP, SYMBOL, DOUBLE, DOUBLE])
leftTable=table(1:0, `sym`timestamp`price, [SYMBOL, TIMESTAMP, DOUBLE])
rightTable=table(1:0, `sym`timestamp`price, [SYMBOL, TIMESTAMP, DOUBLE])
ajEngine = createAsofJoinEngine("asofjoin_engine", leftTable, rightTable, output, <[leftTable.price, rightTable.price]>, `sym, `timestamp)
leftEngine = createReactiveStateEngine(name=`left_reactive_engine, metrics=<[time,msum(price,3)]>, dummyTable=trades, outputTable=getLeftStream(ajEngine), keyColumn="sym")
rightEngine = createReactiveStateEngine(name=`right_reactive_engine, metrics=<[time,mfirst(price,3)]>, dummyTable=trades, outputTable=getRightStream(ajEngine), keyColumn="sym")
subscribeTable(, "trades", "left_reactive_engine", 0, append!{leftEngine}, true)
subscribeTable(, "trades", "right_reactive_engine", 0, append!{rightEngine}, true)
t = table(2022.01.01 + 1..20 as time, take(`AMZN`IBM`APPL, 20) as sym, rand(100.0, 20) as price)
trades.append!(t)
select * from output order by timestamp,sym
timestamp
sym
price1
price2
2022.01.02T00:00:00.000
AMZN
2022.01.03T00:00:00.000
IBM
2022.01.04T00:00:00.000
APPL
2022.01.05T00:00:00.000
AMZN
2022.01.06T00:00:00.000
IBM
2022.01.07T00:00:00.000
APPL
2022.01.08T00:00:00.000
AMZN
102.192
26.2273
2022.01.09T00:00:00.000
IBM
152.2704
43.6296
2022.01.10T00:00:00.000
APPL
126.1056
74.929
2022.01.11T00:00:00.000
AMZN
137.4656
57.6015
2022.01.12T00:00:00.000
IBM
116.7775
54.2854
2022.01.13T00:00:00.000
APPL
58.8909
49.3149
2022.01.14T00:00:00.000
AMZN
148.5405
18.3633
2022.01.15T00:00:00.000
IBM
141.0848
54.3554
2022.01.16T00:00:00.000
APPL
93.9003
1.8618
2022.01.17T00:00:00.000
AMZN
210.4329
61.5008
2022.01.18T00:00:00.000
IBM
88.7772
8.1367
相关函数:
getRightStream
。
FILE:references/doc_7349.md
# startsWith
**URL**: https://docs.dolphindb.cn/zh/funcs/s/startsWith.html
**来源**: DolphinDB 官方文档
---
startsWith
语法
startsWith(X, str)
详情
检查
X
是否以
str
开头。如果是,返回 true; 否则返回 false。
参数
X
是在该字符串中搜索。它可以是标量或向量。
str
是被搜索的目标字符串。它必须是标量。
返回值
一个布尔值。
例子
str1="US product"
str2="UK product"
if (startsWith(str1, "US")) print "str1 is a US product."
else print "str1 is not a US product."
if (startsWith(str2, "US")) print "str2 is a US product."
else print "str2 is not a US product.";
// output
str1 is a US product.
str2 is not a US product.
FILE:references/doc_7353.md
# triu
**URL**: https://docs.dolphindb.cn/zh/funcs/t/triu.html
**来源**: DolphinDB 官方文档
---
triu
语法
triu(X, [k=0])
详情
若未指定
k
: 返回矩阵
X
的上三角部分,其余元素设为0。
若指定
k
: 返回矩阵
X
的第
k
条对角线上以及该对角线上方的元素,其余元素设为0。矩阵的主对角线为其第0条对角线。
参数
X
是一个矩阵。
k
是一个整数。
返回值
返回一个矩阵,其数据类型同
X
。
例子
m=matrix(1 2 3, 4 5 6, 7 8 9);
m;
col1
col2
col3
1
4
7
2
5
8
3
6
9
triu(m);
col1
col2
col3
1
4
7
0
5
8
0
0
9
triu(m,1);
col1
col2
col3
0
4
7
0
0
8
0
0
0
triu(m,-1);
col1
col2
col3
1
4
7
2
5
8
0
6
9
相关函数:
tril
FILE:references/doc_7354.md
# gmd5
**URL**: https://docs.dolphindb.cn/zh/funcs/g/gmd5.html
**来源**: DolphinDB 官方文档
---
gmd5
语法
gmd5(X)
详情
根据 MD5 算法,对 X 的所有元素进行哈希。当 X 是元组/数组向量/数据对/矩阵时,对其平铺后计算 MD5 哈希值。
参数
X
可以是标量、向量、元组、数组向量、数据对或矩阵。
返回值
INT128 类型标量。
例子
gmd5([1 2 3])
// output: 2a1dd1e1e59d0a384c26951e316cd7e6
gmd5([[1, 2], 3])
// 因为构建 MD5 的数据完全一致,所以输出也一致
// output: 2a1dd1e1e59d0a384c26951e316cd7e6
xs = array(INT[], 0, 10).append!([1 2 3, 4 5, 6 7 8, 9 10])
gmd5(xs)
// output: c457b6addd2869161f8a853c0f247aaf
ys = [1 2 3, 4 5, 6 7 8, 9 10]
gmd5(ys)
// output: c457b6addd2869161f8a853c0f247aaf
m=matrix(1 2 3, 8 7 0)
gmd5(m)
// output: 660a82bc074f9dccc5c9fbb806f44f5c
相关函数:
rowGmd5
FILE:references/doc_7368.md
# all
**URL**: https://docs.dolphindb.cn/zh/funcs/a/all.html
**来源**: DolphinDB 官方文档
---
all
语法
all(X)
详情
如果
X
中包含 false 或0,返回 false;反之返回 true。NULL 值不参与计算。
参数
X
可以是标量、数据对、向量或矩阵。
返回值
一个布尔值。
例子
all(1 2 3)
// output
1
all(0 1 2)
// output
0
all(true false)
// output
0
all(true true true)
// output
1
all(1..10$2:5)
// output
1
all(0..9$2:5);
// output
0
相关函数:
any
FILE:references/doc_7377.md
# StreamEngineParser 解析原理
**URL**: https://docs.dolphindb.cn/zh/stream/str_eng_parser.html
**来源**: DolphinDB 官方文档
---
StreamEngineParser 解析原理
流数据引擎解析器(StreamEngineParser)的主要功能是自动构建计算流水线,以及在流批一体计算场景中,将批计算因子翻译成流计算解决方案。以下内容将详细介绍
StreamEngineParser 的计算规则和解析原理。
StreamEngineParser 功能介绍
DolphinDB
针对不同场景提供了多种流计算引擎,例如用户可以使用响应式状态引擎(ReactiveStateEngine)访问历史状态数据,通过横截面引擎(CrossSectionalEngine)实时计算截面数据等。对于简单的业务场景,只需使用单一引擎即可解决,而对于一些复杂任务,需要将多种引擎串联成流水线,共同完成计算任务。
相较于手动串联各类引擎需要人工定义每一层引擎实例,并按照特定顺序进行级联,StreamEngineParser
可以帮助用户自动解析表达式,构建流水线,高效实现各类复杂计算业务。
有了这一功能,用户还可以轻松实现流批一体解决方案。以量化因子研发为例,用户通常需要先对证券历史数据进行批计算,验证因子有效性,然后使用流计算在实盘中做交易。传统的解决方案中,为了批计算的开发效率和维护便捷性,往往采用
Python 等语言,而实盘流计算为了性能,通常采用 C++
等编译型语言。这就要求用户进行从批到流的因子转写,转写过程不仅带来了冗余繁重的开发工作,还存在流批计算结果不一致的隐患。
StreamEngineParser
很好地解决了这一问题,用户只需实现因子的批计算,就可以自动构建对应的流计算方案,无需自己转写即可轻松实现流批一体,同时严格保证了流批计算结果的一致性。
流计算引擎计算规则
流计算引擎支持类型
除了上文中提到的响应式状态引擎(ReactiveStateEngine)和横截面引擎(CrossSectionalEngine), DolphinDB
还提供了时间序列引擎(TimeSeriesEngine)、会话窗口引擎(SessionWindowEngine)、流数据连接引擎(AsofJoinEngine、EqualJoinEngine、WindowJoinEngine、LookupJoinEngine、LeftSemiJoinEngine)
以及异常检测引擎(AnormalyDectionEngine)。其中,异常检测引擎通常用于对实时数据进行监控的场景,流数据连接引擎侧重于异构表的融合。
目前 StreamEngineParser 仅支持响应式状态引擎、横截面引擎和时间序列引擎。
StreamEngineParser 可以自动解析因子表达式,然后识别解析出的因子应该放在哪一类计算引擎中,从而实现自动构建流水线。例如,针对用于逐行计算的
row
系列函数,StreamEngineParser 会解析生成一个横截面引擎来计算,其特征是函数名以 “row”
为前缀;针对用于滑动窗口计算的
rolling
高阶函数,StreamEngineParser
会解析生成时间序列引擎。除此之外,其他函数调用都将解析成状态引擎的指标。
流计算引擎数据交换规则
流计算引擎定义类继承了 Table
类,即每一个流计算引擎实例是一个特殊的的数据表。流计算引擎有三个基础要素:输入数据表的表结构(dummyTable)、待计算的逻辑(metrics)和输出数据表的实例引用(outputTable),在创建引擎实例时这三个基础要素是已经确定的。
流计算引擎通过 append 接口将引擎和流数据表的订阅关联起来以接收实时流数据。当引擎的 append
被调用时,会触发计算逻辑,根据引擎的类型来计算指标,计算完成后调用输出表的 append 接口将数据写入。
由于流计算引擎也是一个数据表,所以一个引擎的实例可以作为另一个引擎的输入或输出,这就是 DolphinDB 流计算流水线构建的基础。
流计算指标类型
流计算引擎的指标依赖 DolphinDB 脚本的表达语义,在解析过程中包括函数、表达式、列引用和常量这几类。
函数
解析函数时,StreamEngineParser
可以自动识别函数名称、参数列表及类型和返回值类型。函数可以嵌套调用,即一个函数可以作为另外一个函数的参数,如:
mrank(rowRank(low, percent=true), true,
9
)
表达式
解析表达式时,StreamEngineParser
可以自动识别表达式的类型,表达式的左值、右值,以及运算符号等,表达式可以在任何引擎中直接使用。如:
sign((vol - mfirst(vol,
2
))) * (-
1
* (close - mfirst(close,
2
)))
列引用
列引用的计算规则是通过引用列名,将输入表中某一列的值直接拷贝到输出表中。在流计算流水线中,列引用对于从某个 stage 的引擎往后续 stage
传递计算结果至关重要。
常量
常量的引用不涉及指标的计算,也不涉及跨 stage 传递数据,可以在任意 stage 中直接使用。
StreamEngineParser 解析过程介绍
定义流水线 stage
定义流水线 stage 的数据结构,包含当前 stage 的 engine 类型,输入 Table 的 schema,计算的 metrics 列表,假设流水线
stage 的类名为 Process,则其定义为:
class
Process {
private:
EngineType engineType_;
TableSP inputDummy_;
vector<ObjectSP> metrics_;
TableSP outputTableDummy_;
}
enum EngineType {
REACTIVE_STATE_ENGINE,
CROSS_SECTIONAL_ENGINE,
TIME_SERIES_ENGINE,
NONE_ENGINE
}
前文中我们说明了 engine 实例和计算函数之间的对应关系:
以 “row” 开头的函数或者
byrow
函数会被解析成 CROSS_SECTIONAL_ENGINE
rolling
函数会被解析成 TIME_SERIES_ENGINE
其他函数会被解析成 REACTIVE_STATE_ENGINE
某一个 stage 仅有一个 engine 实例,仅能计算某一种类型的计算任务,解析过程中当出现某一层的计算指标和当前层的 engine 类型不一致时则需要在当前
engine 的上游新建一个 stage,并将计算的结果以列引用的方式传递给当前 stage。如下图所示:
假设当前解析了两层 stage,stage1 是一个 ReactiveStateEngine, stage2 是一个
crossSectionalEngine。在解析过程中识别出来应该在 stage2 的 engine 新增一个计算指标
rolling
(sum, qty, 6000, 6000, fill=0)
。新的指标是一个使用了
rolling
的高阶函数调用,前文中介绍这类调用需要在 TIME_SERIES_ENGINE 中计算,而当前 engine 的类型是
CrossSectionalEngine, 与需要的 engine 类型不匹配, 则需要新建一个时间序列 engine 用来计算新的指标,并在原有的
stage2 中新增一个列引用,引用该计算结果。如下图所示:
值得注意的是,新增的 stage 既可以放在流水线开头,也可以放在当前 stage 的上一层,如果放在流水线的第一层,则在当前层和新增的 stage
之间每一层都需要增加列的引用,否则当前层会拿不到这个指标的计算结果,导致结果错误。放在原有的 stage 的上一层仅需在新的 stage3 中增加对新的
stage2 中新增指标的列的引用即可。
另外,当我们新增了一个 stage2,则需要在这个 stage2 中针对 stage1 输出表的每一列新增一个列引用。因为现在的 stage3 的输入 table
是 stage1,可以直接访问 stage1 的输出表中的数据,当中间新增了 stage2 后,stage3 的输入 table 是 stage2,没法直接访问
stage1,需要通过 stage2 的列引用作为中间媒介间接访问。
递归解析
StreamEngineParser 的其中一个参数是指标列表,不同的指标对应的 engine 类型可能会不同,同一个指标因为存在嵌套函数调用可能需要多层
stage 才能完整计算。StreamEngineParser 使用递归完成所有指标的解析,先遍历 StreamEngineParser
的原始输入指标列表。
流水线 stage 的最后一层输出到最终输出表,每一个原始输入指标对应流水线最终输出表的一个列。
StreamEngineParser
针对每一个原始输入指标递归进行解析,如果是函数调用指标则依次解析函数名和函数参数列表,如果是表达式则依次解析表达式的左右值,直到某一个解析的指标是一个列引用或者是一个常量则退出递归。
这里我们以 alpha1 因子为例讲解递归解析的完整过程。
DolphinDB 实现的 alpha1 因子代码为:
def
alpha1(close){
ts = mimax(pow(iif(ratios(close) -
1
<
0
, mstd(ratios(close) -
1
,
20
), close),
2.0
),
5
)
return
rowRank(X=ts, percent=true) -
0.5
}
inputSchemaT = table(
1
:
0
, [
"SecurityID"
,
"TradeTime"
,
"close"
], [SYMBOL,TIMESTAMP,DOUBLE])
resultStream = table(
10000
:
0
, [
"TradeTime"
,
"SecurityID"
,
"factor"
], [TIMESTAMP,SYMBOL,DOUBLE])
metrics = <[SecurityID, alpha1(close)]>
streamEngine = streamEngineParser(name=
"alpha1ParserT"
, metrics=metrics, dummyTable=inputSchemaT, outputTable=resultStream, keyColumn=
"SecurityID"
, timeColumn=`tradetime, triggeringPattern=
'perBatch'
, triggeringInterval=
4000
)
在这个例子中,输入 Table 的 schema 为
inputSchemaT
, 其中有一个
close
输入列,该列被 alpha1 因子作为参数引用。streamEngineParser 的输入指标为
metrics
,
metrics
中仅有两个指标分别用于
SecurityID
列引用,和
alpha1(close)
因子计算。输出
table 的为
resultStream
,其中
factor
列的值是
alpha1(close)
因子计算后的结果。
alpha1因子有一个赋值表达式
ts = mimax(pow(iif(ratios(close) -
1
<
0
, mstd(ratios(close) -
1
,
20
), close),
2.0
),
5
)
返回的计算表达式
rowRank(X=ts, percent=true) - 0.5
中引用了
ts
。对该因子的递归解析过程如下:
第一步, 将引用的变量展开,则计算完整表达式为:
rowRank(X=mimax(pow(iif(ratios(close) -
1
<
0
, mstd(ratios(close) -
1
,
20
), close),
2.0
),
5
), percent=true) -
0.5
第二步,展开后的引用变量最外层是一个表达式,左值为
rowRank(X=mimax(pow(iif(ratios(close) - 1 <
0, mstd(ratios(close) - 1, 20), close), 2.0), 5), percent=true)
,
表达式计算符为:"-", 右值为 0.5。
表达式可以在任意类型的 engine 中计算,因为当前的 stage 中还没有 stage,则创建一个初始的 NONE_STAGE,这个 stage 是万能
stage,后续遇到第一个函数计算时可以将其 NoneEngine 类型转换成对应的 engine 类型。如下图:
第三步, 递归解析表达式的左值
rowRank(X=mimax(pow(iif(ratios(close) - 1 < 0,
mstd(ratios(close) - 1, 20), close), 2.0), 5), percent=true)
这个是一个以 "row" 为前缀的函数调用,按照前文中的解析规则会被解析成一个 CrossSectionalEngine, 因为当前的 engine 是一个
NoneEngine 类型,则直接将当前 stage 的 engineType 设置成
CROSS_SECTIONAL_ENGINE
, 如下图所示:
第四步,接下来解析
rowRank
的参数,
rowRank
的参数分别为
mimax(pow(iif(ratios(close) - 1 < 0, mstd(ratios(close) - 1, 20),
close), 2.0), 5)
和
percent=true
.
先解析
mimax(pow(iif(ratios(close) - 1 < 0, mstd(ratios(close) - 1, 20),
close), 2.0), 5)
,
mimax
函数既不是以 "row" 开头,也不是
byrow
高阶函数调用或
rolling
的高阶函数调用,则应该解析成
REACTIVE_STATE_ENGINE
, 因为当前层是 CROSS_SECTIONAL_ENGINE,无法计算
REACTIVE_STATE_ENGINE 类型的指标,需要新增一个 stage,并将当前 stage 设置成新增的 stage。如图:
第五步, 接下来依次解析
mimax(pow(iif(ratios(close) - 1 < 0, mstd(ratios(close) -
1, 20), close), 2.0), 5)
参数,其中
mimax
,
pow
,
iif
,
ratios
,
mstd
等函数均应该解析成
REACTIVE_STATE_ENGINE
类型,而当前 stage 即 stage1 也是
REACTIVE_STATE_ENGINE,与前述
mimax
等函数的解析类型相匹配,所以放在当前 stage
中计算。
第六步,回到第二步 表达式的右值是一个常量,不需要新增 Engine,所以 alpha1 最终解析的流水线为:
流水线仅有两个 stage, stage1 是一个 ReactiveStateEngine 计算
mimax(pow(iif(ratios(close) - 1 < 0, mstd(ratios(close) - 1, 20),
close), 2.0)
这个指标,输出到 table 中对应的列为 "col_0"。stage2 是一个
CrossSectionalEngine, 输入表为 stage1 的输出表, 原来的计算指标
rowRank(X=mimax(pow(iif(ratios(close) -
1
<
0
, mstd(ratios(close) -
1
,
20
), close),
2.0
),
5
), percent=true) -
0.5
经过流水线拆解后,转换成:
rowRank(X=col_0, percent=true) - 0.5
, 其中
col_0
是 stage1 中
mimax(pow(iif(ratios(close) - 1 < 0, mstd(ratios(close) -
1, 20), close), 2.0)
的结算结果。
需要注意的是:
ReactiveEngine 支持嵌套计算,所以当 ReactinveEngine 的函数指标的参数也是一个 reactiveEngine 时,则可以放到同一个
engine 中执行。
但 TimeSeriesEngine 和 CrossSectionalEngine 不支持嵌套计算,比如
rowRank(rowRank(close, percent=true), percent=true)
,
则需要解析成两个 CrossSectionalEngine。
优化
优化可以尽可能减少流水线的 stage 和避免重复计算。主要的优化方向有两个:尽可能将同类型的指标放在同一个 engine 中计算,并通过列引用传递给后续的
stage;检查某个指标是否已经计算过了,如果已经计算过了则直接引用结果即可。
在类型匹配的 stage 中计算新增指标或为指标匹配 engine
当检测到某个指标和当前 Engine 类型不匹配时,检测下上游所有 stage,是否存在匹配的 engine,若存在,则在匹配的 engine
中计算,并将结果通过列引用透传到当前层。如:
假设当前 stage 是 stage3,解析的一个指标是 ratios(close), 和当前 stage 的 engine 类型不匹配,需要新增一个
reactiveStateEngine 来计算这个指标,但我们检查到上游 stage 中已有了 ReactiveStateEngine
则可以将这个指标在 stage1 中计算,并将结果透传给 stage3. 如下图所示:
检查指标
如上例,当 stage3 中新增某一个指标,不论这个指标是否和当前层 engine 类型相匹配,检查下上游 stage
中是否已经计算过了,如果已经计算过了则直接通过列引用引用结果即可。
复检
复检的目的是在 stage 都解析完成后,因为解析顺序以及依赖关系的原因有可能仍然存在多余的相同类型的 engine
的情况,此时需要合并,如下图所示:
当存在上图中的情况时,我们可以检查 stage4 中的每一个指标,如果指标计算需要的参数在 stage1 中都可以满足,则可以将指标放入 stage1
中计算,如果stage4中的指标有依赖 stage3 的计算结果,则无法移动。完成检查后如果 stage4 中所有指标都是列引用则可以删除该
stage,如下图:
FILE:references/doc_7384.md
# sum
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sum.html
**来源**: DolphinDB 官方文档
---
sum
语法
sum(X)
详情
若
X
为向量,返回
X
中所有元素之和。
若
X
为矩阵,计算每列元素之和,返回一个向量。
若
X
为表,计算每列元素之和,返回一个表。
与所有其它聚合函数一致,计算时忽略 NULL 值。
如果
X
中的所有元素为 NULL,
sum
返回的结果为 NULL。
参数
X
可以是标量、向量、矩阵或表。
返回值
返回标量、向量或表。
例子
sum(1 2 3 NULL 4);
// output
10
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
sum(m);
// output
[6,15]
FILE:references/doc_7388.md
# 第三方工具
**URL**: https://docs.dolphindb.cn/zh/third_party.html
**来源**: DolphinDB 官方文档
---
第三方工具
DolphinDB 通过与各类第三方工具无缝集成,提高其数据管理和系统运维能力。本节将介绍 DolphinDB 支持的第三方工具以及它们的安装使用方法。
FILE:references/doc_7405.md
# createTimeBucketEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createtimebucketengine.html
**来源**: DolphinDB 官方文档
---
createTimeBucketEngine
语法
createTimeBucketEngine(name,timeCutPoints,metrics,dummyTable,outputTable,timeColumn,[keyColumn],[useWindowStartTime],[closed='left'],[fill='none'],[keyPurgeFreqInSec=-1],[outputElapsedMicroseconds=false],[parallelism=1],[outputHandler],[msgAsTable=false]
,[snapshotDir],[snapshotIntervalInMsgCount]
)
详情
创建一个自定义窗口长度(长度相同或不同)的时间序列聚合引擎。该引擎基于数据时间,按照指定的长度对输入数据进行窗口划分,并在窗口内执行增量聚合计算。通常和时序聚合引擎(createTimeSeriesEngine
)级联使用,接收其输出秒级或分钟级聚合结果(例如 K 线)进行进一步处理。
注:
不支持乱序处理机制,用户需要自行保证输入的数据有序。
窗口
窗口边界:窗口的左、右边界由
timeCutPoints
向量的任意两个相邻元素确定。
边界开闭:由
closed
确定边界是左闭右开或者左开右闭。
窗口关闭时机:窗口左开右闭时,收到的第一条时间戳大于等于右边界的数据触发窗口关闭;窗口左闭右开时,收到的第一条时间戳大于等于右边界时间戳减1的数据触发窗口关闭。例如,对于窗口
[09:00, 09:05),当收到数据的时间戳大于等于 09:04 时,窗口关闭。
窗口输出时间戳:窗口输出时间戳的精度同
timeColumn
。若
useWindowStartTime
=
true,显示为窗口起始时间;反之,显示时间为数据窗口终止时间。
计算
参与计算的数据时间范围:
timeCutPoints
向量中第一个元素和最后一个元素确定的时间范围内的数据会参与计算。该向量的时间精度决定了计算窗口的时间精度。例如,当
timeCutPoints =
[09:00m,
09:05m],且窗口左闭右开时,窗口的时间精度为分钟。此时,只有在大于等于 09:00m 且小于等于 09:04m 的数据会参与计算,而大于
09:04m 的数据(如 09:04:00.100)则不参与计算。
分组计算或全局计算:若指定了
keyColumn
,则按照分组分别进行窗口计算,否则进行全局计算。
计算结果填充:未指定
fill
或指定
fill
= "none" 时,只输出计算结果不为空的窗口;若指定了
fill
,则输出所有窗口,且根据
fill
规则对结果为空的窗口进行填充。
参数
name
字符串标量,表示时间序列分组引擎的名称,作为其在一个数据节点/计算节点上的唯一标识。可包含字母,数字和下划线,但必须以字母开头。
timeCutPoints
MINUTE 或 SECOND 类型向量,且不能包含空值。由
timeCutPoints
向量的任意两个相邻元素确定窗口的左、右边界。注意:
timeCutPoints
指定的时间精度必须不高于
timeColumn
列的精度。
timeCutPoints
指定的时间精度决定关闭窗口右边界的时间精度。如果
timeCutPoints
是
MINUTE 类型,则窗口右边界的时间精度是分;如果
timeCutPoints
是 SECOND
类型,则窗口右边界的时间精度是秒。
metrics
以元代码的格式表示计算指标,支持输入元组。有关元代码的更多信息可参考
元编程
。
计算指标可以是一个或多个系统内置或用户自定义的聚合函数(使用 defg 关键字定义),如
<[sum(volume), avg(price)]>;可以对聚合结果使用表达式,如
<[avg(price1)-avg(price2)]>;也可对列与列的计算结果进行聚合计算,如
<[std(price1-price2)]>。
metrics
内支持调用具有多个返回值的函数,例如 <func(price) as
`col1`col2>(可不指定列名)。
dummyTable
一个表对象,和输入的流数据表的 schema 一致,可以含有数据,亦可为空表。
outputTable
计算结果的输出表,可以是内存表或者分布式表。在使用 createTimeBucketEngine
函数之前,需要将输出表预先设立为一个空表,并指定各列列名以及数据类型。引擎会将计算结果插入该表。
输出表的列顺序如下:
时间列。当
timeColumn
为标量时,输出表中时间列的数据类型与
timeColumn
列
一致。否则输出表中时间列的数据类型与
timeColumn
中日期和时间列应用 concatDateTime 的结果一致。
分组列。如果
keyColumn
不为空,则其后几列和
keyColumn
设置的列及其顺序保持一致。
耗时列。如果指定
outputElapsedMicroseconds
= true,则指定一个 LONG
类型的列用于存储耗时(单位:微秒)。
计算结果列,数量和
metrics
中指定的算子个数相同。若
metrics
指定的某个算子返回多个计算结果,则它们将以数组向量的形式输出,因此,该算子对应的计算结果列必须的类型必须是数组向量。
timeColumn
字符串标量或长度为2的向量,用于输入表中时间列的名称。
注:若
timeColumn
指定为向量,则第一个元素(date)的类型为 DATE,第二个元素(time)的类型为 TIME, SECOND 或
NANOTIME。此时,输出表第一列的时间类型必须与 concatDateTime(date, time) 的类型一致。
keyColumn
可选参数,字符串标量或向量,表示分组列名。若设置,则分组进行聚合计算,例如以每支股票为一组进行聚合计算。
useWindowStartTime
可选参数。布尔值,表示输出表中的时间是否为数据窗口起始时间。默认值为
false,表示输出表中的时间为窗口结束时间。
closed
字符串,用于确定滑动窗口边界的开闭情况。可选值为 'left' 或 'right',默认值为
'left'。
closed = 'left': 窗口左闭右开。
closed = 'right': 窗口左开右闭。
fill
可选参数,一个标量或向量,指定某个分组的某个窗口无数据时的处理方法。可取以下值:
'none': 不输出结果。
'null': 输出结果为 NULL。
'ffill': 输出上一个有数据的窗口的结果。
'具体数值':该值的数据类型需要和对应的
metrics
计算结果的类型保持一致。
fill
可以输入向量,长度与
metrics
元素个数保持一致,表示为每个
metrics
指定不同的
fill
方式。若为向量,向量中各项只能是 'null', 'ffill' 或一个数值,不能是 'none'。
keyPurgeFreqInSec
正整数,表示清理窗口数据为空的分组的时间间隔,单位为秒。指定该参数后,若当前数据注入时间与上一次清理时间的间隔大于等于
keyPurgeFreqInSec
,则触发对当前窗口数据为空的分组信息的清理。若指定该参数,则必须指定
keyColumn
,且不能指定
fill。
outputElapsedMicroseconds
布尔值,表示是否输出每个窗口从触发计算到计算完成输出结果的耗时(若指定了
keyColumn
则包含数据分组的耗时),默认为 false。指定参数
outputElapsedMicroseconds
后,在定义
outputTable
时需要在时间列和分组列后增加一个 LONG
类型的列,详见
outputTable
参数说明。
parallelism
为不超过 63 的正整数,可选参数,表示并行计算的工作线程数,默认值为
1。在计算量较大时,合理地调整该参数能够有效利用计算资源,降低计算耗时。建议小于机器核数,推荐值为 4 到 8 。
outputHandler
一元函数。设置此参数时,引擎计算结束后,不再将计算结果写到输出表,而是会调用此函数处理计算结果。
msgAsTable
布尔标量,表示在设置了参数 outputHandler
时,将引擎的计算结果以表的结构调用函数。默认值为 false,此时将计算结果的每一列作为元素组成元组。
若要开启快照机制 (snapshot),必须指定
snapshotDir
与
snapshotIntervalInMsgCount
。
snapshotDir
可选参数,字符串,表示保存引擎快照的文件目录。
指定的目录必须存在,否则系统会提示异常。
创建流数据引擎时,如果指定了
snapshotDir
,会检查该目录下是否存在快照。如果存在,会加载该快照,恢复引擎的状态。
多个引擎可以指定同一个目录存储快照,用引擎的名称来区分快照文件。
一个引擎的快照可能会使用三个文件名:
临时存储快照信息:文件名为
<engineName>.tmp
;
快照生成并刷到磁盘:文件保存为
<engineName>.snapshot
;
存在同名快照:旧快照自动重命名为
<engineName>.old
。
snapshotIntervalInMsgCount
可选参数,为整数类型,表示每隔多少条数据保存一次流数据引擎快照。
返回值
返回一个表对象,通过向该表对象写入,将数据注入引擎进行计算。
例子
通过时序聚合引擎计算1分钟 K 线,然后通过 createTimeBucketEngine 将 1 分钟 K 线聚合为 5
分钟。在窗口左闭右开的情况下,可以提前一分钟结束窗口并计算输出,从而比使用 createTimeSeriesEngine 减少延时。
share streamTable(1000:0, `time`sym`price`volume, [TIMESTAMP, SYMBOL, DOUBLE, INT]) as trades
share streamTable(10000:0, `time`sym`firstPrice`maxPrice`minPrice`lastPrice`sumVolume, [TIMESTAMP, SYMBOL, DOUBLE, DOUBLE, DOUBLE, DOUBLE, INT]) as output1
timeSeries1 = createTimeSeriesEngine(name="timeSeries1", windowSize=60000, step=60000, metrics=<[first(price), max(price), min(price), last(price), sum(volume)]>, dummyTable=trades, outputTable=output1, timeColumn=`time, useSystemTime=false, keyColumn=`sym, useWindowStartTime=false)
subscribeTable(tableName="trades", actionName="timeSeries1", offset=0, handler=append!{timeSeries1}, msgAsTable=true);
// 定义 createTimeBucketEngine 的输出表和窗口区间
share streamTable(10000:0, `time`sym`firstPrice`maxPrice`minPrice`lastPrice`sumVolume, [TIMESTAMP, SYMBOL, DOUBLE, DOUBLE, DOUBLE, DOUBLE, INT]) as output2
timeCutPoints=[10:00m, 10:05m, 10:10m, 10:15m]
timeBucket1 = createTimeBucketEngine(name="timeBucket1", timeCutPoints=timeCutPoints, metrics=<[first(firstPrice), max(maxPrice), min(minPrice), last(lastPrice), sum(sumVolume)]>, dummyTable=output1, outputTable=output2, timeColumn=`time, keyColumn=`sym)
subscribeTable(tableName="output1", actionName="timeBucket1", offset=0, handler=append!{timeBucket1}, msgAsTable=true);
insert into trades values(2024.10.08T10:01:01.785,`A, 10.83, 2110)
insert into trades values(2024.10.08T10:01:02.125,`B,21.73, 1600)
insert into trades values(2024.10.08T10:01:12.457,`A,10.79, 2850)
insert into trades values(2024.10.08T10:03:10.789,`A,11.81, 2250)
insert into trades values(2024.10.08T10:03:12.005,`B, 22.96, 1980)
insert into trades values(2024.10.08T10:08:02.236,`A, 11.25, 2400)
insert into trades values(2024.10.08T10:08:04.412,`B, 23.03, 2130)
insert into trades values(2024.10.08T10:08:05.152,`B, 23.18, 1900)
insert into trades values(2024.10.08T10:08:30.021,`A, 11.04, 2300)
insert into trades values(2024.10.08T10:10:20.123,`A, 11.85, 2200)
insert into trades values(2024.10.08T10:11:02.236,`A, 11.06, 2200)
insert into trades values(2024.10.08T10:13:04.412,`B, 23.15, 1880)
insert into trades values(2024.10.08T10:15:12.005,`B, 22.06, 2100)
sleep(10)
// 查看时序引擎输出的 1 分钟 K 线结果
select * from output1;
time
sym
firstPrice
maxPrice
minPrice
lastPrice
sumVolume
2024.10.08T10:02:00.000
A
10.83
10.83
10.79
10.79
4,960
2024.10.08T10:02:00.000
B
21.73
21.73
21.73
21.73
1,600
2024.10.08T10:04:00.000
A
11.81
11.81
11.81
11.81
2,250
2024.10.08T10:04:00.000
B
22.96
22.96
22.96
22.96
1,980
2024.10.08T10:09:00.000
A
11.25
11.25
11.04
11.04
4,700
2024.10.08T10:09:00.000
B
23.03
23.18
23.03
23.18
4,030
2024.10.08T10:11:00.000
A
11.85
11.85
11.85
11.85
2,200
2024.10.08T10:14:00.000
B
23.15
23.15
23.15
23.15
1,880
查看 5 分钟 K 线结果:
select * from output2;
time
sym
firstPrice
maxPrice
minPrice
lastPrice
sumVolume
2024.10.08T10:05:00.000
A
10.83
11.81
10.79
11.81
7,210
2024.10.08T10:05:00.000
B
21.73
22.96
21.73
22.96
3,580
2024.10.08T10:10:00.000
A
11.25
11.25
11.04
11.04
4,700
2024.10.08T10:10:00.000
B
23.03
23.18
23.03
23.18
4,030
2024.10.08T10:15:00.000
B
23.15
23.15
23.15
23.15
1,880
FILE:references/doc_7416.md
# rm
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rm.html
**来源**: DolphinDB 官方文档
---
rm
语法
rm(filename)
详情
删除一个文件。该命令必须要用户登录后才能执行。
参数
filename
是要删除的文件的名称。
例子
files("/home/test");
filename
isDir
fileSize
lastAccessed
lastModified
abc.txt
0
15
1496650187443
1496647459999
dir1
1
0
1496650004836
1496650004836
dir2
1
0
1496650002210
1496650002210
dir3
1
0
1496649999597
1496649999597
rm("/home/test/abc.txt"); // delete file abc.txt
files("/home/test");
filename
isDir
fileSize
lastAccessed
lastModified
dir1
1
0
1496650004836
1496650004836
dir2
1
0
1496650002210
1496650002210
dir3
1
0
1496649999597
1496649999597
FILE:references/doc_7418.md
# sessionWindow
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sessionWindow.html
**来源**: DolphinDB 官方文档
---
sessionWindow
语法
sessionWindow(X, sessionGap)
详情
从
X
的第一个非空元素开始一个会话窗口,依次判断
X
中每个元素与前一个相邻元素的差值是否小于
sessionGap
。若差值小于
sessionGap
,则会话窗口继续打开;否则,会话窗口关闭,且由当前元素开始一个新的会话窗口。以各个会话窗口的第一个元素值作为它的编号。该函数返回
X
中每个元素所属的会话窗口的编号。
注:
对于
X
中的空值(不参与比较):若空值位于
X
的开头,则返回空;否则,返回其前一个非空元素所属会话窗口的编号。
乱序数据不会参与比较,直接返回当前会话窗口的编号。
参数
X
整型或时间类型向量。
SessionGap
正整数,表示两个会话之间的间隔。其单位同
X
一致。
返回值
数据类型与长度均与
X
一致的向量。
例子
x = 1 5 6 12 13 13 15
sessionWindow(x, 5)
// output
[1,1,1,12,12,12,12]
y = 2012.06.13 2012.06.15 2012.06.19 2012.06.26 2012.06.28
sessionWindow(y, 5)
// output
[2012.06.13,2012.06.13,2012.06.13,2012.06.26,2012.06.26]
在下例中,第二个会话窗口(编号为12)之后出现的乱序数据3和7不参与判断,直接返回编号12。其后的元素15属于会话窗口12(因为15-12<4)。
x = [, , 1, 12, 3, 7, 15, 19]
sessionWindow(x, 4)
// output
[,,1,12,12,12,12,19]
colTime = 2023.06.01T10:00:00.000 + 1 2 3 4 5 6 7 8 9 21 22 23 28 29 30
colSym = take(`A`B`C,15)
colVolume = [2,1,5,5,2,3,2,3,2,2,5,5,2,7,2]
t = table(colTime as time, colSym as sym, colVolume as volume)
t
time
sym
volume
2023.06.01 10:00:00.001
A
2
2023.06.01 10:00:00.002
B
1
2023.06.01 10:00:00.003
C
5
2023.06.01 10:00:00.004
A
5
2023.06.01 10:00:00.005
B
2
2023.06.01 10:00:00.006
C
3
2023.06.01 10:00:00.007
A
2
2023.06.01 10:00:00.008
B
3
2023.06.01 10:00:00.009
C
2
2023.06.01 10:00:00.021
A
2
2023.06.01 10:00:00.022
B
5
2023.06.01 10:00:00.023
C
5
2023.06.01 10:00:00.028
A
2
2023.06.01 10:00:00.029
B
7
2023.06.01 10:00:00.030
C
2
在下面的代码中,我们使用了高阶函数
contextby
,根据股票代码 sym
对数据进行分组,并在每个分组内使用
sessionWindow
划分会话窗口,然后计算每个窗口中的交易量总和。其中,
sessionWinodow
使用了部分应用,其第一个参数固定为时间列
time。
select sum(volume) from t group by contextby(sessionWindow{, 5}, time, sym) as time,sym
time
sym
sum_volume
2023.06.01 10:00:00.001
A
9
2023.06.01 10:00:00.002
B
6
2023.06.01 10:00:00.003
C
10
2023.06.01 10:00:00.021
A
2
2023.06.01 10:00:00.022
B
5
2023.06.01 10:00:00.023
C
5
2023.06.01 10:00:00.028
A
2
2023.06.01 10:00:00.029
B
7
2023.06.01 10:00:00.030
C
2
FILE:references/doc_742.md
# 复杂事件处理(CEP)引擎
**URL**: https://docs.dolphindb.cn/zh/stream/cep.html
**来源**: DolphinDB 官方文档
---
复杂事件处理(CEP)引擎
概述
复杂事件处理(Complex Event Processing,简称 CEP
)引擎是一款用于实时处理和分析事件流中复杂事件的引擎。其主要功能包括接收实时数据流,定义事件并从事件流中检测特定事件,进而对满足指定规则的事件执行预设的操作。详细功能介绍如下:
事件捕捉和过滤: 从大量实时数据流中找到特定事件。
事件模式:识别指定的事件模式,这些模式可以涉及多个事件的组合,形成具有特定含义的事件序列。
复杂事件处理:执行复杂的事件处理逻辑,包括筛选、聚合、转换等操作,以识别关键信息或发现特定的业务模式。
表
1
.
CEP 与其它流数据处理引擎的区别
CEP
普通流处理引擎
数据结构
CEP
引擎专门处理复杂事件。同一个数据源中的数据可以被定义为多种不同的事件。多个简单的事件组合成复杂事件。它具备识别事件间特定模式和关系的能力,并根据不同的事件执行相应的处理逻辑。
普通流计算引擎中没有事件的概念。同一个数据源中的数据具有相同的数据结构,使用相同的处理逻辑。一个普通流计算引擎中不能处理具有不同结构的数据流,更不能识别数据流之间的关系。
处理方式
采用事件驱动的方式进行处理,主要通过识别和匹配复杂事件模式、窗口操作和时序分析来提取有用的信息。它通常需要定义和管理一组模式,以筛选和处理数据流中的事件。
普通流计算引擎应用同样的计算逻辑来处理所有接收到的数据。
目标
从实时数据流中提取指定的事件和模式,以便进行实时的分析、决策支持和响应。它强调在大规模、高速和复杂的数据流中发现和识别重要的事件和关联关系。
一般对数据进行高效的聚合、计算等,以满足具体的业务需求。
CEP 架构
CEP 引擎架构图如下:
从上图可以看出,一个完整的 CEP 应用包括以下几个部分:事件流序列化器、事件流反序列化器、事件分发器、CEP 子引擎。事件是贯穿这些部分的基本元素,在详细介绍 CEP
架构中各个部分的功能和内部接口之前,我们先了解 CEP 引擎中的基本概念。
FILE:references/doc_7420.md
# strlenu
**URL**: https://docs.dolphindb.cn/zh/funcs/s/strlenu.html
**来源**: DolphinDB 官方文档
---
strlenu
语法
strlenu(X)
详情
用于获取 Unicode 编码的目标字符串的长度。
参数
X
是一个字符串标量或向量。
返回值
INT 类型标量或向量。
例子
strlenu("高性能分布式时序数据库")
// output
11
strlenu(["高性能分布式时序数据库","DolphinDB"])
// output
[11,9]
FILE:references/doc_7421.md
# loadRecord
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadRecord.html
**来源**: DolphinDB 官方文档
---
loadRecord
语法
loadRecord(filename, schema, [skipBytes=0], [count])
详情
将每个字段长度固定的行式二进制文件加载到内存中。
参数
filename
是一个字符串,表示文件路径。
schema
是一个元组。元组中的每个向量表示一个列的名称、数据类型。如果该列是字符串,还需指定字符串长度。如果长度不足,需在最后补0达到指定长度。
skipBytes
是一个非负整数,表示从文件头开始忽略的字节数。它是一个可选参数,默认值为0。
count
是一个正整数,表示要加载的记录数。如果没有指定,表示加载所有记录。
返回值
一张表。
例子
一个二进制文件 sample.bin,包含46个字段,内容如下:
0000000 3036 3131 3737 532e 0048 0000 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
0000020 16b6 0134 d160 0578 0000 0000 0000 0000
0000030 0000 0000 3333 4137 0000 0000 0000 0000
0000040 0000 0000 0000 0000 0000 0000 0000 0000
0000050 0000 0000 0000 0000 0000 0000 00c8 0000
0000060 0000 0000 0000 0000 0000 0000 0000 0000
*
0000080 0000 0000 3333 4137 0000 0000 0000 0000
0000090 0000 0000 0000 0000 0000 0000 0000 0000
00000a0 0000 0000 0000 0000 0000 0000 00c8 0000
00000b0 0384 0000 0000 0000 0000 0000 0000 0000
00000c0 0000 0000 0000 0000 0000 0000 0000 0000
00000d0 0000 0000 3036 3131 3737 532e 0048 0000
00000e0 0000 0000 0000 0000 0000 0000 0000 0000
00000f0 0000 0000 16b6 0134 ea58 057b 0000 0000
0000100 0000 0000 0000 0000 3333 4137 0000 0000
0000110 0000 0000 0000 0000 0000 0000 0000 0000
*
0000130 00c8 0000 0000 0000 0000 0000 0000 0000
0000140 0000 0000 0000 0000 0000 0000 0000 0000
0000150 0000 0000 0000 0000 3333 4137 0000 0000
0000160 0000 0000 0000 0000 0000 0000 0000 0000
*
0000180 00c8 0000 0b54 0000 0000 0000 0000 0000
0000190 0000 0000 0000 0000 0000 0000 0000 0000
00001a0 0000 0000 0000 0000 3036 3131 3737 532e
00001b0 0048 0000 0000 0000 0000 0000 0000 0000
00001c0 0000 0000 0000 0000 16b6 0134 82b0 057c
00001d0 0000 0000 0000 0000 0000 0000 3333 4137
00001e0 0000 0000 0000 0000 0000 0000 0000 0000
*
0000200
现将该文件导入到 DolphinDB。其中 code 列是字符串,在二进制文件中的长度是固定的,为32。
schema = [("code", SYMBOL, 32),("date", INT),("time", INT),("last", FLOAT),("volume", INT),("value", FLOAT),("ask1", FLOAT),("ask2", FLOAT),("ask3", FLOAT),("ask4", FLOAT),("ask5", FLOAT),("ask6", FLOAT),("ask7", FLOAT),("ask8", FLOAT),("ask9", FLOAT),("ask10", FLOAT),("ask_size1", INT),("ask_size2", INT),("ask_size3", INT),("ask_size4", INT),("ask_size5", INT),("ask_size6", INT),("ask_size7", INT),("ask_size8", INT),("ask_size9", INT),("ask_size10", INT),("bid1", FLOAT),("bid2", FLOAT),("bid3", FLOAT),("bid4", FLOAT),("bid5", FLOAT),("bid6", FLOAT),("bid7", FLOAT),("bid8", FLOAT),("bid9", FLOAT),("bid10", FLOAT),("bid_size1", INT),("bid_size2", INT),("bid_size3", INT),("bid_size4", INT),("bid_size5", INT),("bid_size6", INT),("bid_size7", INT),("bid_size8", INT),("bid_size9", INT),("bid_size10", INT)];
t=loadRecord("/home/DolphinDB/sample.bin",schema);
select code, date,time,last,volume,value,ask1,ask_size1,bid1,bid_size1 from t;
code
date
time
last
volume
value
ask1
ask_size1
bid1
bid_size1
601177.SH
20190902
91804000
0
0
0
11.45
200
11.45
200
601177.SH
20190902
92007000
0
0
0
11.45
200
11.45
200
FILE:references/doc_7423.md
# 流计算状态监控
**URL**: https://docs.dolphindb.cn/zh/stream/str_monitor.html
**来源**: DolphinDB 官方文档
---
流计算状态监控
在 DolphinDB 中提交订阅后,流数据注入实时处理时所有的计算都在后台进行。用户无法直观地看到运行的情况,因此需要通过特定方式监控发布订阅以及消息处理的状态。与此同时,流计算引擎为系统嵌套的计算模块,引擎内部缓存了分组以及对应的状态等信息,用户需要通过特定的接口来查询流计算引擎的运行状态。流计算状态监控可以帮助用户及时地发现计算中出现的问题并进行修正。本文首先简单介绍 DolphinDB 提供的两种流计算监控方式,之后介绍流计算运行过程中需要重点关注的监控指标。
1. 流计算监控方式
DolphinDB 主要提供两种监控流计算状态的方法:Web 面板和函数查询。通过这两种方式,可以查询流计算中订阅节点的工作线程状态、本地发布节点和订阅节点连接状态等,以监控计算过程。
1.1 Web 面板(推荐)
首先打开浏览器,在浏览器地址栏中输入 <ip>:<port>,即 DolphinDB 所在服务器的 IP 和 DolphinDB server 的端口号。登陆客户端后点击 Web 界面左侧功能面板里的“流计算监控”进入监控页面,可以查看以下状态:
流计算发布订阅状态
:显示流计算订阅节点的工作线程的状态、本地发布节点和它的所有订阅节点之间的连接状态。表中各字段说明可分别查看
getStreamingStat().subWorkers
和
getStreamingStat().pubConns
的官方文档。
流计算引擎状态
:显示各类流计算引擎的状态,表中各字段说明可查看
getStreamEngineStat
。
流数据表状态
:显示非持久化共享流数据表和持久化共享流数据表的状态,表中各字段说明可查看
getStreamTables
函数。
CEP 流计算引擎
:显示节点上全部 CEP 引擎的内部状态以及 CEP 引擎中创建的数据视图(Data View),同时提供与 CEP 引擎进行交互的接口。此页面的更多介绍见 CEP 流计算引擎状态]。
此页面上常用的操作如下:
点击右上角的刷新按钮
:刷新按钮可对当前标签页的内容进行即时刷新。若不点击刷新按钮,页面不会自动刷新。查询状态数据结果均为瞬时数据,因此建议多次刷新以观察短时间内状态的变化趋势。
点击页面上方不同的标签
(流计算发布订阅状态、流计算引擎状态、流数据表状态):通过页面顶部的标签可以切换并查看所需内容,切换时会自动获取该页面对应的最新状态。
点击带三角形图表的字段
(如队列深度、最近处理失败的错误信息):通过点击字段名可以进行降序或升序排序。可以将队列深度最大的订阅线程排在列表的最前面,或者将有错误信息的订阅线程排在列表的最前面。
点击方框勾选订阅线程后点击批量取消订阅
:通过此操作可以取消多个订阅,对选中的订阅后台执行了
unsubscribeTable
函数以释放订阅。同理,在流计算引擎状态标签页可以批量删除引擎,后台将执行
dropStreamEngine
函数来释放引擎。在流数据表状态标签页可以批量删除流数据表,后台将执行
dropStreamTable
函数删除流数据表。
鼠标悬浮在表名或者字段名上方:
通过悬浮在表名上方可以查看各个表对应的系统状态函数,如订阅线程状态表对应
getStreamingStat().subWorkers
。通过悬浮在字段名上方可以查看该指标对应的英文名,通过查看状态函数的用户手册可以了解各个字段详细说明,如线程 ID 对应 workerId,在
getStreamingStat
函数的用户手册中可以找到其具体解释为:线程 ID。若此列为空,代表该订阅尚未收到数据。
流计算监控页面的更多介绍见
流计算监控
。
1.2 函数查询
除了通过 Web 界面监控流计算状态的方法,其他终端的客户也可以通过函数直接查询流计算状态。
流计算监控函数
getStreamingStat
getStreamingStat
函数返回一个字典,包含以下几个不同的表:
表 pubConns 监控本地发布节点和它的所有订阅节点之间的连接状态,每一行表示一个订阅节点。
表 subConns 监控本地订阅节点和发布节点之间的连接状态,每一行表示一个发布节点。
表 pubTables 监控流数据表状态,每一行表示一个流数据表的信息。
表 persistWorkers 监控负责持久化流数据表的工作线程的状态。
表 subWorkers 监控订阅节点的工作线程的状态,工作线程状态信息会按照 topic 来展示。
表 udpPubTables 用于监控流数据表进行 UDP 组播发布的状态。
以上各表包含的列字段见
getStreamingStat
。Web 页面上仅展示了最常用的两个表 subWorkers 和 pubTables 的信息。注意,执行
getStreamingStat
函数返回的也是瞬时数据,因此通常需要多次执行以观察流计算状态的变化趋势。
流计算引擎监控函数
getStreamEngineStat
该函数可以查看系统中定义的全部流计算引擎、各个引擎的内存占用等状态,每一类引擎对应一张表。调用该函数会返回一个 key 为引擎类型名称、value 为表的字典。详细说明见
getStreamEngineStat
,调用该函数返回结果如下。
在上图例子中,系统中有两个流计算引擎,分别为 ReactiveStreamEngine 和 CrossSectionEngine 类型的引擎。表格中记录了它们的引擎名称、已处理的数据行数、占用的内存等状态信息。
流数据表状态函数
getStreamTables
getStreamTables
函数查询非持久化共享流数据表和持久化共享流数据表的状态,调用该函数返回结果如下。
在上图例子中,系统中有一张名为 snapshotStreamTable 的非持久化共享流数据表,共 42 列 8046454 行。
2. 需重点关注的监控指标
上文介绍了通过 Web 监控面板和函数可以查看的状态信息。本章介绍需要重点关注的监控指标、其指标变化反应的问题以及建议的解决方法。
2.1 流计算发布订阅——队列深度
当整个节点上创建了多个不同 topic 的订阅时,定位具体流数据处理延迟阻塞问题时可优先关注队列深度。当数据流量极大而系统来不及处理时,此时系统会按照订阅端队列 → 发布端队列 → 数据注入端逐级反馈数据压力。当订阅端队列深度达到上限时开始阻止发布端数据进入,此时发布端的队列开始堆积。当发布端的队列深度达到上限时,系统会阻塞写入流数据表。
Web 监控面板中可以查看流计算发布订阅的队列深度情况,在不断刷新查看状态时,若队列深度呈现持续上升趋势,意味着订阅端处理速率小于上游输入的速率,队列堆积会导致计算时延增大。下图中订阅端队列发生了堆积,但是还没有达到其上限,因此发布端队列暂时还没有发生堆积。
当数据流消费出现阻塞时,可能有以下原因:
流计算引擎中 metrics 参数设置过于复杂
多个计算任务分配在了同一个线程上执行
进行历史数据回放时 replay 函数速度设置过快导致数据流量过大
……
建议使用各种优化手段提高消息处理的效率,以保证队列深度不会出现持续的增长。解决方法可以考虑并行计算、微批处理、增量计算等,详细的性能调优方见
流计算时延统计与性能优化
。
2.2 流计算发布订阅——线程ID
线程 ID 对应
subscribeTable
函数中设置的 hash 参数,对应关系为线程 ID = hash%subExecutor + 1,即 hash 参数按系统 subExecutor 值取模后再加 1 为线程 ID。线程 ID 的最大值是系统参数 subExecutor 的值,例如当 subExecutor 为 4 时,表示最多只有 4 个后台线程用于处理 subscribeTable 函数提交的后台作业。建议将流计算任务合理分配在不同的线程上执行,避免流计算任务都在同一个线程上执行而不能合理利用资源。
2.3 流计算发布订阅、流计算引擎——最近处理失败的错误信息
若订阅线程产生了错误,点击最近处理失败的错误信息的“详细”,查看发生时间最近的报错细节。该列支持倒序排名,即有错误信息的线程排列靠前展示。
假设订阅流数据表写入流计算引擎,若流计算引擎设置的 dummyTable 与实际订阅的流数据表的列数不同,发生错误情况如下图所示。解决方法为首先取消订阅,修改
handler
参数后再重新提交订阅。
此外,还需要关注流计算引擎状态中的最近错误消息。
2.4 流计算引擎状态——内存
随着订阅的流数据不断注入引擎,引擎内部缓存的数据越来越多,引擎占用的内存会逐渐增大。在创建引擎时可以通过参数 garbageSize 控制清理历史数据的频率以控制引擎中的内存占用。对于不再使用的引擎可以通过
dropStreamEngine
函数释放引擎,即可释放掉对应的内存。若流数据引擎的句柄仍在内存中,也需要释放,方式为:创建引擎时返回的句柄变量 = NULL。
相关信息
dropStreamEngine
getStreamingStat
unsubscribeTable
FILE:references/doc_7451.md
# readLine
**URL**: https://docs.dolphindb.cn/zh/funcs/r/readLine.html
**来源**: DolphinDB 官方文档
---
readLine
语法
readLine(handle)
详情
从给定的文件中读取一行。
参数
handle
是文件句柄。
返回值
返回的行不包括换行符。如果文件结束,函数会返回一个 NULL 对象,可以用
isVoid
函数测试。
例子
x=`IBM`MSFT`GOOG`YHOO`ORCL;
eachRight(writeLine, file("test.txt","w"), x);
// output
[1,1,1,1,1]
fin = file("test.txt")
do{
x=fin.readLine()
if(x.isVoid()) break
print x
}while(true);
// output
IBM
MSFT
GOOG
YHOO
ORCL
FILE:references/doc_746.md
# align
**URL**: https://docs.dolphindb.cn/zh/funcs/a/align.html
**来源**: DolphinDB 官方文档
---
align
语法
align(left, right, [how='outer'], [byRow], [view=true])
详情
按照
how
指定的方法,将
left
和
right
根据
byRow
指定的行/列标签进行对齐。
注:
返回矩阵不保留输入矩阵的属性,如:输入索引矩阵,返回非索引矩阵。
通过函数
rename!
设置普通矩阵的标签;通过 exec +
pivot by 也会生成以 pivot by 指定列为标签的矩阵。
参数
left/right
包含标签的矩阵/索引矩阵/索引序列。
how
矩阵的对齐方法。通过将矩阵的行列标签进行 join 操作,来实现标签对齐。可选值为:'outer' (or 'fj'), 'inner' (or
'ej'), 'left' (or 'lj'), or 'asof ('aj')',表示不同的连接方式。默认值是 'outer',即外连接。
byRow
布尔值或空值。若为 true,表示按行标签对齐;若为
false,表示按列标签对齐。默认为空值,表示同时按照行列标签对齐。此时,若行、列的连接方式相同,
how
需指定一个连接方式;否则,
how
需指定两个连接方式,格式为"行对齐方式,列对齐方式",例如
how
="outer,inner",逗号前后不能有空格或其他符号。
注:
left
和
right
指定的矩阵必须包含
byRow
指定的对齐标签,且标签的数据类型需要兼容。目前支持以下类型的标签:整型、浮点型、时间类型、STRING 类型、SYMBOL 类型。其中 INT,
SHORT, LONG, CHAR 互相兼容, FLOAT 和 DOUBLE 类型互相兼容,STRING 和 SYMBOL 类型也互相兼容。
view
布尔值,默认值是 true,表示生成原矩阵的一个视图(浅拷贝),若原数据发生改变,视图的数据也会相应变化。若为
false,则生成一个新的矩阵(深拷贝)。
返回值
返回一个长度为2的元组,其元素分别为两个矩阵按标签对齐后的对象。
例子
// 对齐包含重复标签的矩阵
x1 = [09:00:00, 09:00:01, 09:00:03]
x2 = [09:00:00, 09:00:03, 09:00:03, 09:00:04]
m1 = matrix(1 2 3, 2 3 4, 3 4 5).rename!(x1)
m2 = matrix(11 12 13, 12 13 14, 13 14 15, 14 15 16).rename!(x2)
a, b = align(m1, m2, 'fj', false);
a;
09:00:00
09:00:01
09:00:03
09:00:03
09:00:04
1
2
3
3
2
3
4
4
3
4
5
5
b;
09:00:00
09:00:01
09:00:03
09:00:03
09:00:04
11
12
13
14
12
13
14
15
13
14
15
16
a+b;
09:00:00
09:00:01
09:00:03
09:00:03
09:00:04
12
15
16
14
17
18
16
19
20
m = align(m1, m2, 'aj', false);
m[0];
09:00:00
09:00:01
09:00:03
1
2
3
2
3
4
3
4
5
m[1];
09:00:00
09:00:01
09:00:03
11
11
13
12
12
14
13
13
15
// 定义一个价格表 pt, 一个交易量的表 vt
timestamp = [09:00:00, 09:00:02, 09:00:03, 09:00:06, 09:00:08]
id= ['st1', 'st2', 'st1', 'st1', 'st2']
price = [197.8, 197.5, 198.4, 198.6, 198.6]
pt = table(timestamp, id, price)
timestamp = [09:00:00, 09:00:01, 09:00:02, 09:00:05, 09:00:08]
id = ['st1', 'st2', 'st2', 'st3', 'st2']
vol = [200, 300, 150, 200, 180]
vt = table(timestamp, id, vol)
// 利用 pivot by 获取价格矩阵和交易量矩阵,pivot by 指定的列将作为矩阵的标签
m1 = exec vol from vt pivot by timestamp, id
m2 = exec price from pt pivot by timestamp, id
// 使用 full join 对齐两个矩阵
m = align(m1, m2, how='aj,fj')
// 计算得到交易金额的矩阵
re = m[0] * m[1]
re;
label
st1
st2
st3
09:00:00
39560
09:00:01
09:00:02
29625
09:00:03
09:00:05
09:00:08
35748
FILE:references/doc_7463.md
# in
**URL**: https://docs.dolphindb.cn/zh/funcs/i/in.html
**来源**: DolphinDB 官方文档
---
in
语法
in(X, Y)
详情
若
Y
是非时间类型的标量,检查
X
和
Y
是否相等;若
Y
是时间类型的标量,则会检查
X
中的每个元素是否在
Y
中。当
Y
是 NULL 值时,无论
X
为何值都返回
false。
若
Y
是向量,检查
X
中的每一个元素是否在
Y
中。
若
Y
是字典,检查
X
中的每一个元素是否是
Y
中的键。
若
Y
是单列内存表,检查
X
中的每一个元素是否是
Y
唯一列中的值。
注:
表中单列的类型不能是数组向量。
若
Y
是键值表或索引内存表,检查
X
中的每一个元素是否为
Y
中的主键。
X
中元素的个数必须与
Y
中主键列的个数一致。
注:
X
和
Y
的数据类型需保持一致。若类型不一致,但属于同一分类,系统会将
X
强制转换为与
Y
一致的类型。
参数
X
可以是标量、向量、元组、矩阵、
数组向量、
字典、表。
Y
可以是标量、向量、字典、单列内存表、键值内存表或索引内存表。
返回值
布尔标量或向量。
例子
in(3 3 5 2, 2 3);
// output: [true,true,false,true]
x=dict(INT,DOUBLE);
x[1, 2, 3]=[4.5, 6.6, 3.2];
x;
// output
3->3.2
1->4.5
2->6.6
in(1..6, x);
// output: [true,true,true,false,false,false]
t = table(1 3 5 7 9 as id)
2 3 in t
// output: [false,true]
kt = keyedTable(`name`id,1000:0,`name`id`age`department,[STRING,INT,INT,STRING])
insert into kt values(`Tom`Sam`Cindy`Emma`Nick, 1 2 3 4 5, 30 35 32 25 30, `IT`Finance`HR`HR`IT)
in((`Tom`Cindy, 1 3), kt);
// output: [true,true]
t1 = indexedTable(`sym`side, 10000:0, `sym`side`price`qty, [SYMBOL,CHAR,DOUBLE,INT])
insert into t1 values(`IBM`MSFT`GOOG, ['B','S','B'], 10.01 10.02 10.03, 10 10 20)
in((`IBM`MSFT, ['S','S']), t1);
// output: [false,true]
X
为浮点型,
Y
为整型,数据类型不一致,会将
X
转换为与
Y
一致的类型进行比较。
in(10, NULL)
// output: false
in('a', 97)
// output: true
in(1, 1.1 1.2 1.3)
// output: false
in(float(1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8), 1..9)
// output: [true,true,true,true,true,true,true,true]
in
可以搭配
select
使用,用于限定条件的筛选的范围:
select * from kt where name in [`Tom, `Cindy];
name
id
age
department
Tom
1
30
IT
Cindy
3
32
HR
相关函数:
find
,
binsrch
。
FILE:references/doc_7469.md
# segmentby
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/segmentby.html
**来源**: DolphinDB 官方文档
---
segmentby
语法
segmentby(func, funcArgs, segment)
详情
根据
segment
参数确定分组方案,把
funcArgs
分组,并把函数
func
应用到每个分组中。返回的结果与
segment
参数的长度相同。
参数
func
是一个函数。
funcArgs
是函数的参数。
segment
是分组向量。segment参数中连续相同的元素为一组。segment的长度必须和funcArgs相同。
返回值
一个与
segment
参数长度相同的向量。
例子
下面的例子中,y确定了3个分组:1 1 1、-1 -1 -1和1 1
1。第一个分组的index是0-2,第二个分组的index是3-5,第三个分组的index是6-9。按照这个规则把x分成3组,1 2 3、0 3 2和1 4 5,并把
cumsum
函数应用到x的每个分组,计算每个分组的累计和。
x=1 2 3 0 3 2 1 4 5
y=1 1 1 -1 -1 -1 1 1 1
segmentby(cumsum,x,y);
// output
[1,3,6,0,3,5,1,5,10]
segmentby
可用于止损回测。下面的例子把回报率ret分为两组,分别判断position=1和position=-1这两种情况下,是否需要止损。
def stoploss(ret, threshold){
cumret = cumprod(1+ret)
drawDown = cumret.cummax() / cumret - 1
firstCutIndex = at(drawDown >= threshold).first() + 1
indicator = take(false, ret.size())
if(isValid(firstCutIndex) and firstCutIndex < ret.size())
indicator[firstCutIndex:] = true
return indicator
}
position = 1 1 1 1 1 -1 -1 -1 -1
ret = 0.01 0.02 -0.04 -0.02 -0.01 -0.005 -0.015 0.005 0.025
segmentby(stoploss{,0.05}, ret, position);
// output
[false,false,false,false,true,false,false,false,false]
FILE:references/doc_7470.md
# appendTuple!
**URL**: https://docs.dolphindb.cn/zh/funcs/a/appendTupel_.html
**来源**: DolphinDB 官方文档
---
appendTuple!
语法
appendTuple!(X, Y, [wholistic=false])
详情
将
Y
中的数据追加到
X
中。
当
wholistic
为 true 时,将
Y
整体作为一个元素追加到
X
中
当
wholistic
为 false 时,将
Y
中的每一个元素依次追加到
X
中
当
X
是列式元组时,
Y
中元素必须与
X
中元素类型一致,且
wholistic
只能为
false
参数
X
是一个元组。
Y
是一个元组。
wholistic
是一个 bool 标量,默认值为 false。
返回值
数据类型和数据形式与
obj
一致。
例子
x = (1,"X")
y = ([2,3],"Y")
x.appendTuple!(y,true)
print(x)
// output
(1,"X",([2,3],"Y"))
x.appendTuple!(y,false)
print(x)
// output
(1,"X",([2,3],"Y"),[2,3],"Y")
x = [[1,2,3],4]
x.setColumnarTuple!()
x.appendTuple!((5,6),false)
print(x)
([1,2,3],4,5,6)
FILE:references/doc_7471.md
# repeat
**URL**: https://docs.dolphindb.cn/zh/funcs/r/repeat.html
**来源**: DolphinDB 官方文档
---
repeat
语法
repeat(X, n)
详情
将
X
重复
n
次。
参数
X
是一个字符串或字符串向量。
n
是一个非负整数,表示重复的次数。
返回值
返回一个字符串或字符串向量。
例子
repeat(`FB, 3);
// output
FBFBFB
repeat(`AB`CD,2);
// output
["ABAB","CDCD"]
FILE:references/doc_7485.md
# concatDateTime
**URL**: https://docs.dolphindb.cn/zh/funcs/c/concatDateTime.html
**来源**: DolphinDB 官方文档
---
concatDateTime
语法
concatDateTime(date, time)
别名:
concatDT
详情
合并日期和时间。
参数
date
可以是 DATE 类型的标量或向量。
time
可以是 SECOND、TIME 或 NANOTIME 类型的标量或向量。
如果
date
和
time
都是向量,它们的长度必须相同。
返回值
一个标量或向量:
如果
time
是 SECOND 类型,返回的结果是 DATETIME 类型;
如果
time
是 TIME 类型,返回的结果是 TIMESTAMP 类型;
如果
time
是 NANOTIME,返回的结果是 NANOTIMESTAMP 类型。
例子
concatDateTime(2019.06.15,13:25:10);
// output
2019.06.15T13:25:10
concatDateTime(2019.06.15,[13:25:10, 13:25:12, 13:25:13]);
// output
[2019.06.15T13:25:10,2019.06.15T13:25:12,2019.06.15T13:25:13]
date=[2019.06.18, 2019.06.20, 2019.06.21, 2019.06.19, 2019.06.18, 2019.06.20]
time = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26]
sym = `C`MS`MS`MS`IBM`IBM$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23
qty = 2200 1900 2100 3200 6800 5400
t = table(date, time, sym, qty, price);
select concatDateTime(date,time) as datetime, sym, qty, price from t;
datetime
sym
qty
price
2019.06.18T09:34:07
C
2200
49.6
2019.06.20T09:36:42
MS
1900
29.46
2019.06.21T09:36:51
MS
2100
29.52
2019.06.19T09:36:59
MS
3200
30.02
2019.06.18T09:32:47
IBM
6800
174.97
2019.06.20T09:35:26
IBM
5400
175.23
FILE:references/doc_7490.md
# getMCPPrompt
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getMCPPrompt.html
**来源**: DolphinDB 官方文档
---
getMCPPrompt
语法
getMCPPrompt(name, [args], [published])
详情
调用指定的 MCP Prompt 模板。
参数
name
STRING 类型标量,表示 prompt 模板的名称。
args
可选参数,一个字典,键是 STRING 类型,值是 ANY 或 STRING 类型,表示传入 prompt 模板的参数。
published
可选参数,布尔值,表示是否调用已发布的版本。默认为 false,表示调用尚未发布的版本。
返回值
一个字符串,内容是根据模板和传入参数生成的 prompt 文本。
例子
// 定义 prompt 模板并发布
addMCPPrompt(
name = "stock_summary",
message = "请用一句话总结 stock 从 startDate 到 endDate 的走势。",
description = "生成某个股票在一段时间内的自然语言概述",
extraInfo = {title : "股票走势总结"}
)
publishMCPPrompts("stock_summary")
// 更新模板,不发布
updateMCPPrompt(
name = "stock_summary",
message = "请找出 stock 在 startDate 至 endDate 的最高价和最低价。",
description = "更新后的 Prompt 描述"
)
// 调用发布的 stock_summary
getMCPPrompt(name="stock_summary", args={"stock":"000111", "startDate":2025.01.01, "endDate":2025.08.01}, published=true)
// output: 请用一句话总结 000111 从 2025.01.01 到 2025.08.01 的走势。
// 调用更新后未发布的 stock_summary
getMCPPrompt(name="stock_summary", args={"stock":"000111", "startDate":2025.01.01, "endDate":2025.08.01}, published=false)
// output:请找出 000111 在 2025.01.01 至 2025.08.01 的最高价和最低价。
FILE:references/doc_7491.md
# cdfZipf
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfZipf.html
**来源**: DolphinDB 官方文档
---
cdfZipf
语法
cdfZipf(num, exponent, X)
详情
返回 Zipf 分布的累计密度函数的值。
参数
num
是正整数。
exponent
是非负数。
X
是数值型向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfZipf(10, 0.5, [1, 3, 5, 7, 9]);
// output
[0.199164, 0.454981, 0.643631, 0.800216, 0.937019]
FILE:references/doc_7492.md
# crc32
**URL**: https://docs.dolphindb.cn/zh/funcs/c/crc32.html
**来源**: DolphinDB 官方文档
---
crc32
语法
crc32(str, [cksum=0])
详情
根据 CRC32 算法,对字符串进行哈希,生成 INT 类型数据。
参数
str
是一个字符串标量、向量或表。
cksum
是整型标量或向量。
返回值
INT 类型标量/向量/表。
例子
a=crc32(`aa`cc,1);
a;
// output
[512829590,-1029100744]
typestr(a);
// output
FAST INT VECTOR
FILE:references/doc_7493.md
# covarMatrix
**URL**: https://docs.dolphindb.cn/zh/funcs/c/covarMatrix.html
**来源**: DolphinDB 官方文档
---
covarMatrix
语法
covarMatrix(X)
详情
设矩阵
X
有 n 列,将其每一列作为一维向量,求 n 维随机变量的协方差矩阵(covariance matrix)。
注:
如果矩阵中含有空值,会默认将空值转化为0,然后进行计算。而由于
covar
函数计算时忽略 NULL 值,因此调用
cross/pcross(covar, X)
函数计算相关矩阵时也会忽略 NULL 值。
在不含 NULL 值的情况下,虽然该函数计算结果等价于
cross(covar,
X)
,但该函数内部进行了优化,其性能较
cross/pcross
函数有大幅提升。
参数
X
是一个矩阵。
返回值
DOUBLE 类型矩阵。
例子
m = rand(10.0, 30)$10:3
covarMatrix(m)
#0
#1
#2
6.116181845352529
1.107026927999891
1.306707566911273
1.107026927999891
7.162534080771522
-0.758517799304199
1.306707566911273
-0.758517799304199
5.516744365930221
a = rand(1.0, 30000000).reshape(10000:3000)
a.rename!("s" + string(1..3000))
timer covarMatrix(a)
// output
Time elapsed: 2927.264 ms
timer pcross(covar, a)
// output
Time elapsed: 29484.85 ms
相关函数:
corrMatrix
FILE:references/doc_7504.md
# replay
**URL**: https://docs.dolphindb.cn/zh/funcs/r/replay.html
**来源**: DolphinDB 官方文档
---
replay
语法
replay(inputTables, outputTables, [dateColumn], [timeColumn], [replayRate],
[absoluteRate=true], [parallelLevel=1], [sortColumns],
[preciseRate=false])
详情
根据指定的回放模式,按时间顺序将一个或多个数据表或数据源列表(由
replayDS
函数的返回值)的数据回放到数据表,以模拟实时数据写入,通常用于高频策略回测场景。
注:
不支持乱序处理机制,用户需要自行保证输入的数据有序。
回放形式
根据输入表到输出表的映射(mapping),
replay
支持 1 对 1,N 对 N,N
对 1 三种回放形式。
相比于N对N回放,N个1对1的各个回放相互独立。当
inputTables
指定为数据源列表时,N对N
回放形式可以确保所有回放的第一个数据源回放完,再开始回放第二个数据源。
相比于N对N回放无法保证所有表的数据在全局上的时间顺序,N对1回放形式可以确保不同表的数据写入目标表的顺序与时间字段的先后顺序严格一致。
回放模式
根据回放速度的不同设定,
replay
提供以下四种回放模式:
指定每秒回放记录数:如果
replayRate
为正整数,且
absoluteRate
为 true,则回放的速率基于记录数计算,系统按照每秒
replayRate
条记录进行回放。
指定时间跨度回放加速倍数:如果
replayRate
为正整数,并且
absoluteRate
为 false,则根据输入表数据的时间跨度加速
replayRate
倍回放。注意,每秒回放的记录数是相同的。
全速回放:如果
replayRate
未指定或者为负,无论
absoluteRate
为 false 还是 true,系统都将以最快的速率进行回放。
精确速度回放:如果
replayRate
为正整数,且
preciseRate
为
true,则数据完全按照事件时间进行倍速回放。系统根据两条相邻数据的时间间隔加速
replayRate
倍依次回放每条数据。例如,
replayRate
为 2 时,原本时间戳相差 t 毫秒 的相邻两条数据,会尽量以 t/2
毫秒的时间间隔依次回放。
回放过程
数据加载(仅当输入表是数据源列表时)。
从磁盘加载数据源到内存时,用户可以指定
parallelLevel
参数并行加载数据,以提升性能。数据加载和数据回放异步进行。
分批回放。
每批回放的记录数和回放耗时受回放模式和系统性能影响。
回放模式
每批数据包含的记录数
取数据的方式
回放耗时
按指定记录数回放(数据总数为 s)
replayRate
条数据请注意:此模式下每秒回放一批数据。若输入表是数据源列表(即从磁盘加载)时,回放速度亦受磁盘IO性能制约。若一秒内加载的数据量小于
replayRate
,则将已加载的数据作为一个批次进行回放。
1 对 1:从单表取一批数据。N 对 1 / N 对 N:根据数据的时间戳顺序,从 N
张表中取一批数据。
约为 s/replayRate 秒
按时间跨度加速回放(数据时间跨度为 n 秒,数据总数为 s)
replayRate*s/n 条数据(若不足 1 条,则取 1
条)请注意:此模式下每秒回放一批数据。若输入表是数据源列表(即从磁盘加载)时,回放速度亦受磁盘IO性能制约。若一秒内加载的数据量小于
replayRate*s/n,则将已加载的数据作为一个批次进行回放。
1 对 1:从单表取一批数据。N 对 1 / N 对 N:根据数据的时间戳顺序,从 N
张表中取一批数据。
约为 n/replayRate 秒
全速回放
每次回放时系统已加载的所有数据
1 对 1:同上。N 对 1:同上。N 对 N:逐一回放各输入表,每次从单表取一批数据。
取决于系统性能
注:
上表的回放耗时计算方法适用于评估同构回放的耗时,异构回放的耗时会略高于同构回放。
回放过程中,系统会先从内存按批取出数据并回放。
replay
只保证同一批次数据的回放结果是有序的。因此,在调用
replay
函数前,请将输入表按照指定的时间列(由参数
dateColumn
和
timeColumn
决定)排序。
数据写入。
注:
目前系统仅支持单线程写入输出表。
终止回放:可使用
cancelJob
和
cancelConsoleJob
命令。
注:
2.00.5 版本前,N 对 1 回放要求输入表结构必须相同,称为同构回放。自
2.00.5 版本起,N 对 1
回放开始支持输入结构不同的表,称为异构回放。由于异构回放到输出表的记录均被序列化存储,无法直接读取,需要通过
streamFilter
进行数据过滤和分发,详情请参考
streamFilter
。
2.00.9 版本后,若 N 对 1
回放的输入表为多个数据源列表,会自动按照时间戳排序后回放。在该版本前,系统每次仅加载多个列表相同索引位置的数据源排序后回放,不保证全局的有序性。
参数
根据回放形式的不同,
inputTables
的数据形式也有所不同:
1 对 1 回放时,
inputTables
是一个未分区的表或数据源列表。
N 对 1 同构回放或 N 对 N 回放时,
inputTables
是多个未分区的表或数据源列表构成的元组。
N 对 1 异构回放时,
inputTables
是一个字典。字典的 key
可以是任意数据类型,表示输入表或数据源列表的唯一标识,value 是一个表对象或数据源列表。
根据回放形式的不同,
outputTables
的数据形式也有所不同:
1 对 1 回放或 N 对 1
同构回放时,
outputTables
_是一个表对象(未分区的内存表/流数据表)或表示共享表名的字符串,必须与输入表的 schema
相同。
N 对 N 回放,
outputTables
是多个表对象(未分区的内存表/流数据表)或表示共享表名的字符串构成的元组,且它的长度必须与
inputTables
相同。输出表和输入表一一对应,且 schema 必须相同。
N 对 1 异构回放时
outputTables
是
一个表对象(未分区的内存表/流数据表),至少包含三列:
其中:
第一列为
dateColumn
和
timeColumn
指定的回放时间的时间戳;
第二列为 SYMBOL 或 STRING 类型,对应
inputTables
字典的 key;
第三列为 BLOB 类型,用于存储被回放的每条记录序列化后的结果。
此外,可输出各输入表的公共列(列名和类型一致的列)。
dateColumn
和
timeColumn
为时间列的列名,至少指定其中一个参数。根据回放形式的不同,
dateColumn
和
timeColumn
的取值有所区别:
1 对 1 回放或 N 对 1 同构回放: 输入表与输出表的时间列列名必须相同,指定为字符串标量;
N 对 N 回放:输入表时间列的列名相同,指定为字符串标量;输入表时间列的列名不同,指定为字符串向量;
N 对 1 异构回放:输入表时间列的列名相同,指定为字符串标量;输入表时间列的列名不同,指定为字典,其中 key 为输入表的唯一标识符,value
是对应表时间列的列名。
只指定
dateColumn
或
timeColumn
中的一个参数,或者
dateColumn
和
timeColumn
指定为同一列时,对指定的时间列的类型没有限制。
若指定
dateColumn
和
timeColumn
为不同列,
dateColumn
必须是 DATE
类型,
timeColumn
只能是 SECOND, TIME 或 NANOTIME 类型。
replayRate
整数,和参数
absoluteRate
共同决定了回放的速率。
absoluteRate
布尔值。默认值为 true,表示系统每秒按
replayRate
指定的记录数回放。若为 false,表示依照数据的时间跨度加速
replayRate
倍回放。
parallelLevel
正整数,表示从数据源加载数据到内存的工作线程数量,默认值为 1。如果
inputTables
不是数据源,无需指定该参数。
sortColumns
字符串标量或者长度为2的向量。相同回放时间戳的数据将根据该参数指定的字段进行排序。仅异构回放支持该参数。
注:
该参数可以指定
inputTables
的非公共列。若某个输入表不存在指定的非公共列,则填充空值且将其前置。
preciseRate
布尔值。默认值为 false,表示不开启精确速度回放。若指定为 true,则系统根据相邻记录的时间戳,以
replayRate
指定的倍数精确回放。
例子
一对一回放
以下为按不同回放模式进行一对一回放的例子
n=1000
sym = take(`IBM,n)
timestamp= take(temporalAdd(2012.12.06T09:30:12.000,1..500,'s'),n)
volume = rand(100,n)
trades=table(sym,timestamp,volume)
trades.sortBy!(`timestamp)
share streamTable(100:0,`sym`timestamp`volume,[SYMBOL,TIMESTAMP,INT]) as st
每秒回放100条数据:
timer replay(inputTables=trades, outputTables=st, dateColumn=`timestamp,
timeColumn=`timestamp,replayRate=100, absoluteRate=true);
Time elapsed: 10001.195 ms
表 trades 中一共有1000条数据,每秒回放100条耗时大约10秒。
加速100倍时间回放:
timer replay(inputTables=trades,outputTables=st,dateColumn=`timestamp,
timeColumn=`timestamp,replayRate=100,absoluteRate=false);
Time elapsed: 5001.909 ms
表 trades 中的最大时间与最小时间相差500秒,加速 100 倍时间回放耗时大约5秒。
以最快的速率回放:
timer replay(inputTables=trades,outputTables=st,dateColumn=`timestamp,
timeColumn=`timestamp);
Time elapsed: 0.974 ms
精确速度回放:
timer replay(inputTables=trades,outputTables=st,dateColumn=`timestamp,
timeColumn=`timestamp,replayRate=100,absoluteRate=false, preciseRate=true);
Time elapsed: 4991.177 ms
表 trades 中,以相邻两条记录时间戳的 100 倍速度回放,回放时间大约 4.99 秒。
N 对 N 回放
以下为将多个数据源列表回放到多个输出表中的例子。
以下脚本将两个数据源回放到连接引擎,进行 asof join 计算。
n=50000
sym = rand(symbol(`IBM`APPL`MSFT`GOOG`GS),n)
date=take(2012.06.12..2012.06.16,n)
time=rand(13:00:00.000..16:59:59.999,n)
volume = rand(100,n)
t1=table(sym,date,time,volume).sortBy!([`date, `time])
sym = rand(symbol(`IBM`APPL`MSFT`GOOG`GS),n)
date=take(2012.06.12..2012.06.16,n)
time=rand(13:00:00.000..16:59:59.999,n)
price = 100 + rand(10.0,n)
t2=table(sym,date,time,price).sortBy!([`date, `time])
if(existsDatabase("dfs://test_stock")){
dropDatabase("dfs://test_stock")
}
db=database("dfs://test_stock",VALUE,2012.06.12..2012.06.16)
pt1=db.createPartitionedTable(t1,`pt1,`date).append!(t1)
pt2=db.createPartitionedTable(t2,`pt2,`date).append!(t2)
left = table(100:0,`sym`dt`volume,[SYMBOL,TIMESTAMP,INT])
right = table(100:0,`sym`dt`price,[SYMBOL,TIMESTAMP,DOUBLE])
opt=table(100:0, `dt`sym`volume`price`total, [TIMESTAMP, SYMBOL, INT, DOUBLE, DOUBLE])
ajEngine=createAsofJoinEngine(name="ajEngine", leftTable=left, rightTable=right,
outputTable=opt, metrics=<[volume, price, volume*price]>,
matchingColumn=`sym, timeColumn=`dt, useSystemTime=false, delayedTime=1)
ds1=replayDS(sqlObj=<select sym, concatDateTime(date, time) as dt, volume from pt1>,
dateColumn=`date, timeColumn=`time,
timeRepartitionSchema=[13:00:00.000, 14:00:00.000, 15:00:00.000, 16:00:00.000, 17:00:00.000])
ds2=replayDS(sqlObj=<select sym, concatDateTime(date, time) as dt, price from pt2>,
dateColumn=`date, timeColumn=`time,
timeRepartitionSchema=[13:00:00.000, 14:00:00.000, 15:00:00.000, 16:00:00.000, 17:00:00.000])
replay(inputTables=[ds1,ds2], outputTables=[getLeftStream(ajEngine),
getRightStream(ajEngine)], dateColumn=`dt);
select count(*) from opt
返回:50000
异构回放
异构回放中,回放的输出表通常注入 streamFilter 引擎,进一步过滤分发处理。
n=1000
sym = take(`IBM`GS,n)
myDate=take(2021.01.02..2021.01.06, n).sort!()
myTime=take(09:30:00..15:59:59,n)
vol = array(INT[], 0, 10)
for(i in 0:n){vol.append!([rand(100,3)])}
t=table(sym,myDate,myTime,vol)
sym = take(`IBM`GS,n)
date=take(2021.01.02..2021.01.06, n).sort!()
time=take(09:30:00..15:59:59,n)
vol = array(INT[], 0, 10)
for(i in 0:n){vol.append!([rand(100,3)])}
price = array(DOUBLE[], 0, 10)
for(i in 0:n){price.append!([rand(10.0,3)])}
t1=table(sym, date,time,vol,price)
if(existsDatabase("dfs://test_stock1")){
dropDatabase("dfs://test_stock1")
}
db1=database("",RANGE, 2021.01.02..2021.01.07)
db2=database("",VALUE,`IBM`GS)
db=database("dfs://test_stock1",COMPO,[db1, db2], engine="TSDB")
orders=db.createPartitionedTable(t,`orders,`myDate`sym, sortColumns=`sym`myDate`myTime)
orders.append!(t);
trades=db.createPartitionedTable(t1,`trades,`date`sym, sortColumns=`sym`date`time)
trades.append!(t1);
// 获取数据源
ds = replayDS(sqlObj=<select * from loadTable(db, `orders)>, dateColumn=`myDate, timeColumn=`myTime)
ds.size();
ds1 = replayDS(sqlObj=<select * from loadTable(db, `trades)>, dateColumn=`date, timeColumn=`time)
ds1.size();
input_dict = dict(["msg1", "msg2"], [ds, ds1])
date_dict = dict(["msg1", "msg2"], [`myDate, `date])
time_dict = dict(["msg1", "msg2"], [`myTime, `time])
// replay 的输出表,被订阅输入 streamFilter
share streamTable(100:0,`timestamp`sym`blob`vol, [DATETIME,SYMBOL, BLOB, INT[]]) as opt
filterOrder=table(100:0, `sym`date`time`volume, [SYMBOL, DATE, SECOND, INT[]])
filterTrades=table(100:0, `sym`date`time`volume`price, [SYMBOL, DATE, SECOND, INT[], DOUBLE[]])
// 定义 streamFilter 输入表
share streamTable(100:0,`timestamp`sym`blob`vol, [DATETIME,SYMBOL, BLOB, INT[]]) as streamFilter_input
// streamFilter 对接收的数据进行处理,分别分发到表 filterOrder 和 filterTrades
filter1=dict(STRING,ANY)
filter1['condition']=`msg1
filter1['handler']=filterOrder
filter2=dict(STRING,ANY)
filter2['condition']=`msg2
filter2['handler']=filterTrades
schema=dict(["msg1","msg2"], [filterOrder, filterTrades])
stEngine=streamFilter(name=`streamFilter, dummyTable=streamFilter_input,
filter=[filter1,filter2], msgSchema=schema)
subscribeTable(tableName="opt", actionName="sub1", offset=0, handler=stEngine, msgAsTable=true)
replay(inputTables=input_dict, outputTables=opt, dateColumn = date_dict,
timeColumn=time_dict, replayRate=100, absoluteRate=false);
select count(*) from filterOrder
返回:1000
select count(*) from filterTrades
返回:1000
自动记录回放数据的写入时间戳
在数据回放前,对目标输出流表调用
setStreamTableTimestamp
函数,可为输出表指定时间戳列。回放过程中,系统将自动把数据写入时的系统时间记录到该列。
下例展示了通过
setStreamTableTimestamp
设置为输出表设置时间戳列,再执行数据回放操作。
// 输入表
n=50000
sym = rand(symbol(`IBM`APPL`MSFT`GOOG`GS),n)
date = take(2012.06.12..2012.06.16,n)
time = take(13:00:00.000..16:59:59.999,n)
volume = rand(100,n)
input1 = table(sym,date,time,volume).sortBy!([`date, `time])
sym = rand(symbol(`IBM`APPL`MSFT`GOOG`GS),n)
date = take(2012.06.12..2012.06.16,n)
time = take(13:00:00.000..16:59:59.999,n)
price = 100 + rand(10.0,n)
input2 = table(sym,date,time,price).sortBy!([`date, `time])
// 输出表
share streamTable(100:0,`sym`date`time`volume`replaytime,[SYMBOL,DATE,TIME,INT,TIMESTAMP]) as output1
share streamTable(100:0,`sym`date`time`price`replaytime,[SYMBOL,DATE,TIME,DOUBLE,TIMESTAMP]) as output2
setStreamTableTimestamp(output1, `replaytime)
setStreamTableTimestamp(output2, `replaytime)
// 回放数据
replay(inputTables=[input1, input2], outputTables=[output1, output2], dateColumn=`date, timeColumn=`time)
输出表 output1:
sym
date
time
volume
replaytime
GOOG
2012.06.12
13:00:00.000
12
2025.08.05 10:14:55.475
GOOG
2012.06.12
13:00:00.005
78
2025.08.05 10:14:55.475
GOOG
2012.06.12
13:00:00.010
43
2025.08.05 10:14:55.475
GS
2012.06.12
13:00:00.015
19
2025.08.05 10:14:55.475
MSFT
2012.06.12
13:00:00.020
99
2025.08.05 10:14:55.475
…
输出表 output2:
sym
date
time
price
replaytime
APPL
2012.06.12
13:00:00.000
104.28991972325885
2025.08.05 10:14:55.476
MSFT
2012.06.12
13:00:00.005
105.34384201248842
2025.08.05 10:14:55.476
APPL
2012.06.12
13:00:00.010
102.77994729862654
2025.08.05 10:14:55.476
APPL
2012.06.12
13:00:00.015
105.42814567712317
2025.08.05 10:14:55.476
APPL
2012.06.12
13:00:00.020
108.74385016313717
2025.08.05 10:14:55.476
FILE:references/doc_7506.md
# tmLowRange
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmlowrange.html
**来源**: DolphinDB 官方文档
---
tmLowRange
语法
tmLowRange(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内,统计每个元素 Xi 左侧相邻且连续大于它的元素个数。NULL 被视为最小值。
返回值
长度与
X
相同的 INT 类型向量。
例子
t = [0, 1, 2, 3, 7, 8, 9, 10, 11]
x = [NULL, 3.1, NULL, 3.0, 2.9, 2.8, 3.1, NULL, 3.2]
tmLowRange(t, x, window=3)
// output: [,0,1,0,0,1,0,2,0]
tmLowRange(t, x, window=4)
// output: [,0,1,0,0,1,0,3,0]
index = take(datehour(2019.06.13 13:30:10),4) join (datehour(2019.06.13 13:30:10)+1..6)
data = 1 NULL 3 4 5 NULL 3 NULL 5 3
tmLowRange(index, data, 4h)
// output: [0,1,0,0,0,3,0,1,0,1]
FILE:references/doc_7509.md
# right
**URL**: https://docs.dolphindb.cn/zh/funcs/r/right.html
**来源**: DolphinDB 官方文档
---
right
语法
right(X, n)
详情
返回
X
右边
n
个字符。
参数
X
是一个字符串或字符串向量。
n
必须是一个非负整数。
返回值
返回一个字符串或字符串向量。
例子
right("I love this game!", 6);
输出返回:game!
FILE:references/doc_7520.md
# 交易日历
**URL**: https://docs.dolphindb.cn/zh/modules/MarketHoliday/mkt_calendar.html
**来源**: DolphinDB 官方文档
---
交易日历
交易日历是数据分析经常用到的工具,可以帮助快速获取对应交易所的交易日及进行相应的日期计算。DolphinDB 自 2.00.9/1.30.21 版本开始,提供交易日历功能,并内置世界五十多个交易所的交易日历。用户既可以直接使用内置的交易日历,也可以自定义交易日历,基于场景进行个性化定制。
我们会定期更新交易日历,更新详情可查看
交易日历更新说明
。最新交易日历可通过以下方式获取:
github
、
gitee
。
本教程将会从交易日历的查询和应用、如何自定义交易日历、以及交易日历的来源等三个方面介绍如何使用 DolphinDB 的交易日历。
1. 交易日历的查询和应用
DolphinDB 内置的交易日历可以支持多个场景的应用:
搭配
getMarketCalendar
函数查询指定范围内的交易日;
搭配
temporalAdd
,
transFreq
,
asFreq
,
resample
等内置函数,基于交易日进行计算。
duration 类型支持交易日历,可以用正负数字 + 4个大写字母,表示交易所交易日历时间。
1.1 查询交易日历-getMarketCalendar
可使用函数
getMarketCalendar(marketName, [startDate], [endDate])
获取对应交易所在 startDate 和 endDate 确定的时间范围内的的交易日历。以纽交所(XNYS)为例,获取2022年1月1日至2022年1月10日间的交易日历的脚本如下:
getMarketCalendar("XNYS",2022.01.01, 2022.01.10)
// output
[2022.01.03,2022.01.04,2022.01.05,2022.01.06,2022.01.07,2022.01.10]
1.2 基于交易日历的日期偏移计算 - temporalAdd
如需对交易日历做时间偏移,可以使用
temporalAdd(date, duration, exchangeId)
函数,获取给定时间的偏移的交易日。以纽交所(XNYS)为例,获取2023年1月1日至2023年1月6日增加2个交易日的日期的脚本如下:
dates=[2023.01.01, 2023.01.02, 2023.01.03, 2023.01.04, 2023.01.05, 2023.01.06]
temporalAdd(dates,2,"XNYS")
// output
[2023.01.04,2023.01.04,2023.01.05,2023.01.06,2023.01.09,2023.01.10]
自 2.00.11.1 版本起,还可以直接用正负数字 + 4个大写字母,表示交易所交易日历时间。上面的脚本可改写为:
dates=[2023.01.01, 2023.01.02, 2023.01.03, 2023.01.04, 2023.01.05, 2023.01.06]
temporalAdd(dates, 2XNYS)
// output
[2023.01.04,2023.01.04,2023.01.05,2023.01.06,2023.01.09,2023.01.10]
1.3 基于交易日历取最近的交易日 - transFreq
getMarketCalendar
函数可以获取相应时间范围内的交易日。但是如若某天不是交易日,又想获得该日期前最近的一个交易日,可以使用
transFreq(X,rule)
函数。指定
rule
参数为对应交易所编码,可获取对应日期的最近的交易日。以纽交所 (XNYS) 为例,获取2023年1月1日至1月6日最近的交易日历的脚本如下:
dates=[2023.01.01, 2023.01.02, 2023.01.03, 2023.01.04, 2023.01.05, 2023.01.06]
dates.transFreq("XNYS")
// output
[2022.12.30,2022.12.30,2023.01.03,2023.01.04,2023.01.05,2023.01.06]
2.00.11/1.30.23 版本后,transFreq支持多个交易日作为“rule”参数的输入。例如:
dates.transFreq("2XNYS")
// output
[2022.12.30,2022.12.30,2022.12.30,2023.01.04,2023.01.04,2023.01.06]
注意
:2.00.11/1.30.23 版本之后,交易日历的名字必须为4个大写英文字母。
1.4 基于交易日的数据采样 - asFreq/resample
基于交易日的数据采样,可使用函数
asFreq(X,rule)
或者函数
resample(X,rule,func)
,两者的区别在于是否对数据做聚合操作,resample 可以配合聚合函数使用,而 asFreq 函数是纯粹的取值。
函数
asFreq(X,rule)
会将数据按交易日(维度为天)展开,如果某一天的交易日数据有多个,只取第一个值。如若数据中没有交易日序列中的数据,会以 NULL 填充。以纽交所 (XNYS) 某支股票数据为例,获取2022年12月30日至2023年01月06日的交易日数据的脚本如下:
timestampv = [2022.12.30T23:00:00.000,2023.01.01T00:00:00.000,2023.01.03T00:10:00.000,2023.01.03T00:20:00.000,2023.01.04T00:20:00.000,2023.01.04T00:30:00.000,2023.01.06T00:40:00.000]
close = [100.10, 100.10, 100.10, 78.89, 88.99, 88.67, 78.78]
s=indexedSeries(timestampv, close)
s.asFreq("XNYS")
// output
#0
------
2022.12.30|100.10
2023.01.03|100.10
2023.01.04|88.99
2023.01.05|
2023.01.06|78.78
函数
resample(X,rule,func)
可以在采样的基础上,搭配聚合函数获取想要的交易日数据。以纽交所 (XNYS) 某支股票收盘价数据为例,查询每日收盘价的脚本如下:
timestampv = [2022.12.30T23:00:00.000,2023.01.01T00:00:00.000,2023.01.03T00:10:00.000,2023.01.03T00:20:00.000,2023.01.04T00:20:00.000,2023.01.04T00:30:00.000,2023.01.06T00:40:00.000]
close = [100.10, 100.10, 100.10, 78.89, 88.99, 88.67, 78.78]
s=indexedSeries(timestampv, close)
s.resample("XNYS", last)
// output
#0
------
2022.12.30|100.10
2023.01.03|78.89
2023.01.04|88.67
2023.01.05|
2023.01.06|78.78
2.00.11/1.30.23 版本后,
asFreq/resample
函数均支持多个交易日作为 "rule" 参数的输入。例如:
s.asFreq("2XNYS")
s.resample("2XNYS", last)
注意
:2.00.11/1.30.23 版本之后,交易日历的名字必须为4个大写英文字母。
1.5 duration 类型支持交易日历
自 2.00.11.1 版本起,duration 类型支持交易日历,即可以用正负数字 + 4个大写字母,表示交易所交易日历时间。例如 3XNYS 代表纽交所的3个交易日。
1.5.1 duration 函数支持交易日历
如需将字符串标量转换成DURATION类型,可使用
duration(X)
函数。以纽交所(XNYS)为例,将字符串"2XNYS"转换为DURATION类型,并查询每两个交易日(2XNYS)内平均收盘价格的脚本如下:
y = duration("2XNYS")
date = [2022.12.30, 2023.01.03, 2023.01.04, 2023.01.05, 2023.01.06]
close = [100.10, 78.89, 88.99, 88.67, 78.78]
t = table(date, close)
select avg(close) from t group by interval(date, y, "prev")
// output
| interval_date | avg_close
---|---------------|-----------
0 | 2022.12.30 | 89.495
1 | 2023.01.04 | 88.83
2 | 2023.01.06 | 78.78
1.5.2 基于交易日历 duration 的窗口连接 - window join
如需对数据表做基于交易日历的窗口连接,可使用
wj(leftTable, rightTable, window, aggs, matchingCols, [rightMatchingCols])
函数,并将交易日作为窗口区间单位。以下为以纽交所(XNYS)交易日作为窗口单位进行窗口连接的一个例子:
t1 = table(2023.01.03 2023.01.06 as date)
date = [2022.12.30, 2023.01.03, 2023.01.04, 2023.01.05, 2023.01.06]
close = [100.10, 78.89, 88.99, 88.67, 78.78]
t2 = table(date, close)
wj(t1, t2, -2XNYS:0XNYS, <avg(close)>, `date);
// output
| date | avg_close
---|------------|-------------------
0 | 2023.01.03 | 89.495
1 | 2023.01.06 | 85.48
1.5.3 基于交易日历 duration 的滑动窗口计算 - m系列/tm系列/twindow/tmovingWindowData
DolphinDB 引入了一系列函数以支持滑动窗口计算,以下针对交易日历场景对这些函数做具体说明。
m 系列函数对窗口内数据进行聚合计算。以
msum(X, window, [minPeriods])
函数为例,计算纽交所 (XNYS) 某只股票每两个交易日(2XNYS)的收盘价之和的脚本如下:
date = [2022.12.30, 2023.01.03, 2023.01.04, 2023.01.05, 2023.01.06]
close = [100.10, 78.89, 88.99, 88.67, 78.78]
X1 = indexedSeries(date, close)
msum(X1, window=2XNYS)
// output
#0
------
2022.12.30|100.1
2023.01.03|178.99
2023.01.04|167.88
2023.01.05|177.66
2023.01.06|167.45
tm 系列函数可以根据交易日历进行时序滑动窗口计算,以
tmavg(T, X, window)
函数为例,计算纽交所 (XNYS) 某只股票每两个交易日(2XNYS)的平均收盘价的脚本如下:
date = [2022.12.30, 2023.01.03, 2023.01.04, 2023.01.05, 2023.01.06]
close = [100.10, 78.89, 88.99, 88.67, 78.78]
t = table(date, close)
select tmavg(date, close, 2XNYS) from t
// output
| tmavg_date
---|------------
0 | 100.1
1 | 89.495
2 | 83.94
3 | 88.83
4 | 83.725
twindow(func, funcArgs, T, range, [prevailing=false])
函数可以将函数/运算符应用到滑动窗口的数据当中。以纽交所 (XNYS) 某只股票为例,针对T中的每个日期Ti,计算区间 [Ti-1个交易日(-1XNYS),Ti+2个交易日(+2XNYS)] 内平均收盘价的脚本如下:
date = [2022.12.30, 2023.01.03, 2023.01.04, 2023.01.05, 2023.01.06]
close = [100.10, 78.89, 88.99, 88.67, 78.78]
t = table(date, close)
select twindow(avg, close, date, -1XNYS:2XNYS) from t
// output
| twindow_avg
---|-------------------
0 | 89.32666666666667
1 | 89.1625
2 | 83.8325
3 | 85.48
4 | 83.725
tmovingWindowData(T, X, window, [leftClosed = false])
函数可以基于交易日返回每个滑动窗口中包含的元素。以纽交所 (XNYS) 某只股票为例,以2个交易日(2XNYS)为窗口长度,返回每个滑动窗口包含的元素的脚本如下:
date = [2022.12.30, 2023.01.03, 2023.01.04, 2023.01.05, 2023.01.06]
close = [100.10, 78.89, 88.99, 88.67, 78.78]
tmovingWindowData(date, close, 2XNYS)
// output
[[100.1],[100.1, 78.89],[78.89, 88.99],[88.99, 88.67],[88.67, 78.78]]
1.5.4 基于交易日历 duration 的偏移计算 - move/tmove
如需根据交易日历,对数据做偏移计算,可使用
move(X, steps)
或
tmove(T, X, window)
函数。
move(X, steps)
函数可根据交易日历对数据进行移动操作。以纽交所(XNYS)为例,将2022.12.30至2023年1月6日中的交易日对应的收盘价格向后移动两个交易日脚本如下:
date = [2022.12.30, 2023.01.03, 2023.01.04, 2023.01.05, 2023.01.06]
close = [100.10, 78.89, 88.99, 88.67, 78.78]
X1 = indexedSeries(date, close)
move(X1, 2XNYS)
// output
#0
------
2022.12.30|
2023.01.03|
2023.01.04|100.1
2023.01.05|78.89
2023.01.06|88.99
tmove(T, X, window)
函数可根据交易日历返回 T 中每个日期向前移动 window 个交易日所对应的 X 中的元素。以纽交所(XNYS)为例,返回将2022.12.30至2023年1月6日中的交易日向前移动两个交易日所对应的收盘价格的脚本如下:
date = [2022.12.30, 2023.01.03, 2023.01.04, 2023.01.05, 2023.01.06]
close = [100.10, 78.89, 88.99, 88.67, 78.78]
t = table(date, close)
select *, tmove(date, close, 2XNYS) from t
// output
| date | close | tmove_date
------|------------|-------|-----------
0 | 2022.12.30 | 100.1 |
1 | 2023.01.03 | 78.89 |
2 | 2023.01.04 | 88.99 | 100.1
3 | 2023.01.05 | 88.67 | 78.89
4 | 2023.01.06 | 78.78 | 88.99
2. 自定义及更新内置交易日历
DolphinDB 自 1.30.21/2.00.9 版本开始提供交易日历功能。内置的世界上五十多个交易所的节假日的 csv 文件存放于
marketHolidayDir
配置项对应的文件夹下(默认为
marketHoliday
文件夹),并以交易所的编码命名该文件,例如:“XNYS”(纽交所)。
DolphinDB 启动时会解析
marketHolidayDir
下所有的 csv 文件,启动后便可在
resample
,
asfreq
,
transFreq
,
temporalAdd
等函数内使用该交易所的编码。
DolphinDB 也支持管理员用户自定义交易日历,或者对现有交易日历修改和更新。管理员用户可通过 DolphinDB 内置函数更新交易日历:
使用
addMarketHoliday
新建交易日历
使用
updateMarketHoliday
更新交易日历
本章节将介绍如何通过上述两个函数自定义及更新内置交易日历。
2.1 新增交易日历
在 DolphinDB 中,可以通过函数
addMarketHoliday
新增交易日历。从 DolphinDB 2.00.12/3.00.0 版本起,该函数提供参数
dateType
,用于指定交易日历中的数据类型:
dateType
=="holidayDate";数据类型为休息日。在添加或更新交易日历时,仅需要将非周末的休盘日期。
dateType
="tradingDate":表示数据类型为交易日。在添加或更新交易日历时,需要将填入交易日。
注意
:每个交易日历中只能包含以上两种数据类型中的一种。
通过添加非周末的节假日日期创建交易日历
假设需要新增交易所 “XDDB” 的交易日历,可以通过
addMarketHoliday
函数,添加 “XDDB” 的交易日历。
addMarketHoliday
函数会在
/marketHoliday/
目录下添加新的
XDDB.csv
文件。
DolphinDB 在处理 holiday 文件时会自动过滤周末(周六、周日),因此在提交 holiday 文件时,不需要添加周末日期,只添加非周末的节假日信息即可。
新增交易日历后,可直接调用
getMarketCalendar
等函数对新的交易日历进行操作:
注意
:2.00.11/1.30.23 版本之后,交易日历的名字必须为4个大写英文字母。
//将 2023.01.03 2023.01.04(周二, 周三) 设置为节假日
holiday = 2023.01.03 2023.01.04
//用户登录
login(`admin,`123456)
//添加交易日历
addMarketHoliday("XDDB",holiday)
//获取指定日期区间的交易日历
getMarketCalendar("XDDB",2023.01.01, 2023.01.10)
// output
[2023.01.02,2023.01.05,2023.01.06,2023.01.09,2023.01.10]
temporalAdd(2023.01.01,2,"XDDB")
// output
2023.01.05
通过添加交易日期创建交易日历
自 DolphinDB 2.00.12/3.00.0 版本起,DolphinDB 支持自定义添加周末为交易日的交易日期。与之前默认周末为休市日,且只能添加休息日的方式相比,现在可以传入所有自定义交易日,从而避免遗漏周末为开盘日的问题。
通过指定
dateType
="tradingDate" 来自定义这类交易日历。
例如,2025 年 2 月 8 日是周六,如果因调休而开盘,可以通过设置
dateType
='tradingDate' 来通过交易日数据创建一个交易日日历。此时,
holiday
需要包含所有交易日:
tradingDates=[2025.02.08, 2025.02.10, 2025.02.11, 2025.02.12, 2025.02.13]
addMarketHoliday(marketName="AAAA", holiday=tradingDates, dateType='tradingDate')
getMarketCalendar(marketName="AAAA")
// output
2025.02.08 2025.02.10 2025.02.11 2025.02.12 2025.02.13
如需查看不同交易日历的数据(dateType)属性,可以使用
getTradingCalendarType
函数:
getTradingCalendarType("AAAA")
// output
"tradingDate"
2.2 替换交易日历
假设需要更新已建好的 “XDDB” 交易所的交易日历,可以使用函数
updateMarketHoliday(marketName, holiday)
重新设置该文件的节假日信息,进而更新该交易所的交易日历。
注意
:该函数设置的节假日信息将覆盖旧的交易日历文件,不可单独对该文件更新或新增节假日信息。
以下做法可以将已有的 “XDDB” 交易所重新指定 2023.03.07、2023.03.08 为交易所节假日,且不保留之前的 holiday 日期。通过
temporalAdd
查询 2022.01.01 的下一个交易日的脚本如下:
//将 2023.03.07 2023.03.08(周二, 周三) 重新设置为节假日
updateMarketHoliday("XDDB",2023.03.07 2023.03.08)
//2023.01.03 2023.01.04(周二, 周三) 不再是节假日
getMarketCalendar("XDDB",2023.01.01, 2023.01.10)
// output
[2023.01.02,2023.01.03,2023.01.04,2023.01.05,2023.01.06,2023.01.09,2023.01.10]
//2023.03.07, 2023.03.08(周二, 周三) 作为节假日,不会出现在交易日历中
getMarketCalendar("XDDB",2023.03.01, 2023.03.10)
// output
[2023.03.01,2023.03.02,2023.03.03,2023.03.06,2023.03.09,2023.03.10]
通常,各交易所会定期审查和更新交易日历。我们也会相应地对交易日历进行更新。一般情况下,在每年的12月底,我们会将所有已支持的交易日历更新至最新年份。本节将指导用户如何获取并更新交易日历。更新方式包括离线和在线两种。
离线更新
首先,下载
marketHoliday
文件夹。
然后,使用该文件夹替换 <dolphindb>/server 路径下的 marketHoliday 文件夹。注意:若为集群环境,需要替换每台机器下的对应文件夹。替换完成后,重启集群完成更新。
在线更新
首先,下载
marketHoliday
文件夹。
然后,将该文件夹存放至和 dolphindb 同一服务器的任意位置。注意:若为集群环境,每台机器都需要放置该文件夹。同时,为了验证是否更新成功,请不要保留原本 <dolphindb>/server 路径下的 marketHoliday 文件夹。替换完成后,参照以下代码实现在线更新(以更新 2026 年交易日历为例):
def update_2026_holiday(market_code, old_holiday_dir, new_holiday_dir){
old_holiday_files = exec filename.strReplace(".csv","") from files(old_holiday_dir)
new_holiday_files = exec filename.strReplace(".csv","") from files(new_holiday_dir)
if (!(market_code in new_holiday_files)){
return "There is no market holiday file of the exchange."
}
this_holiday = loadText(new_holiday_dir+'/'+market_code+".csv")
if (market_code in old_holiday_files){
updateMarketHoliday(market_code,this_holiday.col(0))
}
else{
getMarketType = extractTextSchema(new_holiday_dir+'/'+market_code+".csv").name[0]
addMarketHoliday(market_code, this_holiday.col(0),getMarketType)
}
}
market_code = "CZCE" //需要更新的交易所标识码
old_holiday_dir = "<dolphindb>/server/marketHoliday" //原 marketHoliday 文件夹路径
new_holiday_dir = "<dolphindb>/server/newMarketHoliday" //新 marketHoliday 文件夹路径
update_2026_holiday(market_code, old_holiday_dir, new_holiday_dir)
其中,
update_2026_holiday
函数仅在当前节点有效。在集群环境中,可通过
pnodeRun
调用该函数,使更新操作在其它节点生效。
需要注意的是,在线更新方式没有读写锁等一致性机制。因此,为了确保用户访问到更新后的交易日历,我们建议使用离线方式进行更新。
验证更新结果
完成更新后,可以执行以下代码验证更新结果:
2025.01.01 in getMarketCalendar("CZCE",2025.01.01, 2025.12.31)
未更新前,该代码将会返回 true;更新完成后,该代码将会返回 false。
3. 交易日历出处
本章里列举了
marketHoliday
目录下的所有交易所的信息。为了方便国内用户使用,除了用交易所的 ISO Code 标识交易所名(
交易所 ISO CODE 列表
)之外,增加了对国内六大交易所(上交所、深交所、中金所、上期所、郑商所、大商所、上能源)采用国内交易所简称作为标识名(
中国交易所简称列表
)。
3.1 国际交易所 ISO CODE 列表
针对世界各国知名交易所(含上交所和深交所),统一采用 ISO Code 作为交易所的标识码。交易日历数据来源于各交易所官网公布的交易所节假日以及各地政府公布的法定节假日公告。
标识码(ISO Code)
交易所
国家
交易所节假日的公布网站
交易日历备注
CSV 文件路径
开始年份
AIXK
Astana International Exchange
Kazakhstan
https://aix.kz/trading/trading-calendar/
添加了 2022.12.01
marketHoliday/AIXK.csv
2017
ASEX
Athens Stock Exchange
Greece
https://www.athexgroup.gr/market-alternative-holidays
删除了 2022.06.13、2022.05.02、2022.04.22、2022.03.07、2023.02.27、2023.04.17、2023.04.14、2023.06.05
marketHoliday/ASEX.csv
2004
BVMF
BMF Bovespa
Brazil
https://www.b3.com.br/en_us/solutions/platforms/puma-trading-system/for-members-and-traders/trading-calendar/holidays/
添加了 2022.12.01
marketHoliday/BVMF.csv
2004
CMES
Chicago Mercantile Exchange
USA
https://www.cmegroup.com/tools-information/holiday-calendar.html#cmeGlobex
marketHoliday/CMES.csv
2004
IEPA
ICE US
US
https://www.theice.com/holiday-hours?utm_source=website&utm_medium=search&utm_campaign=spotlight
添加了 2023.04.07
marketHoliday/IEPA.csv
2004
XAMS
Euronext Amsterdam
Netherlands
https://www.euronext.com/en/trade/trading-hours-holidays
marketHoliday/XAMS.csv
2004
XASX
Austrialian Securities Exchange
Australia
https://www2.asx.com.au/markets/market-resources/asx-24-trading-calendar
marketHoliday/XASX.csv
2004
XBKK
Stock Exchange of Thailand
Thailand
https://www.set.or.th/en/about/event-calendar/holiday?year=2023
添加了 2023.01.03、2022.01.03、2022.05.02、2022.12.12, 删除了 2022.12.11、2022.10.14、2022.07.29、2022.07.13、2022.06.05、2022.05.05、2022.05.01、2022.02.16、2022.01.02、2023.03.06、2023.05.05、2023.08.01
marketHoliday/XBKK.csv
2004
XBOG
Colombia Securities Exchange
Colombia
https://www.bvc.com.co/non-business-market-days
添加了 2023.12.29
marketHoliday/XBOG.csv
2004
XBOM
Bombay Stock Exchange
India
https://www.bseindia.com/static/markets/marketinfo/listholi.aspx
删除了 2023holidays
marketHoliday/XBOM.csv
2004
XBRU
Euronext Brussels
Belgium
https://www.euronext.com/en/trade/trading-hours-holidays#:~:text=Calendar%20of%20business%20days%202023%20%20%20Euronext:%20%20Closed%20%2012%20more%20rows%20
marketHoliday/XBRU.csv
2004
XBSE
Bucharest Stock Exchange
Romania
https://www.bvb.ro/TradingAndStatistics/TradingSessionSchedule
删除了 2022.04.25、2022.04.22、2022.06.13、2023.04.17、2023.04.14、2023.06.05
marketHoliday/XBSE.csv
2004
XBUD
Budapest Stock Exchange
Hungary
https://www.bse.hu/Products-and-Services/Trading-information/trading-calendar-2023
marketHoliday/XBUD.csv
2004
XBUE
Buenos Aires Stock Exchange
Argentina
删除了 2022.12.09、2023.06.19、2023.05.26、2023.10.13、2023.11.08、2023.10.20
marketHoliday/XBUE.csv
2004
XCBF
CBOE Futures
USA
https://www.cboe.com/about/hours/us-futures/
marketHoliday/XCBF.csv
2004
XCSE
Copenhagen Stock Exchange
Denmark
https://www.nasdaqomxnordic.com/tradinghours/
marketHoliday/XCSE.csv
2004
XDUB
Irish Stock Exchange
Ireland
https://www.euronext.com/en/trade/trading-hours-holidays
marketHoliday/XDUB.csv
2004
XETR
Xetra
Germany
https://www.xetra.com/xetra-en/newsroom/trading-calendar
marketHoliday/XETR.csv
2004
XFRA
Frankfurt Stock Exchange
Germany
https://www.boerse-frankfurt.de/en/know-how/trading-calendar
marketHoliday/XFRA.csv
2004
XHEL
Helsinki Stock Exchange
Finland
https://www.nasdaqomxnordic.com/tradinghours/XHEL
marketHoliday/XHEL.csv
2004
XHKG
Hong Kong Exchanges
Hong Kong, China
https://www.hkex.com.hk/News/HKEX-Calendar?sc_lang=zh-HK&defaultdate=2023-02-01
marketHoliday/XHKG.csv
2004
XICE
Iceland Stock Exchange
Iceland
https://www.nasdaqomxnordic.com/tradinghours/
marketHoliday/XICE.csv
2004
XIDX
Indonesia Stock Exchange
Indonesia
https://idx.co.id/en/about-idx/trading-holiday/
删除了 2023.12.26、2023.09.28、2023.07.19、2023.06.29、2023.06.02、2023.04.26、2023.04.25、2023.04.24、2023.04.21、2023.03.23、2023.03.22、2023.01.23、2022.03.03、2022.02.28、2023.05.02、2023.05.03、2023.05.16
marketHoliday/XIDX.csv
2004
XIST
Istanbul Stock Exchange
Turkey
https://borsaistanbul.com/en/sayfa/3631/official-holidays
marketHoliday/XIST.csv
2004
XJSE
Johannesburg Stock Exchange
South Africa
https://www.jse.co.za/
marketHoliday/XJSE.csv
2004
XKAR
Pakistan Stock Exchange
https://www.psx.com.pk/psx/exchange/general/calendar-holidays
删除了 2023.04.21、2023.11.09、2022.12.26
marketHoliday/XKAR.csv
2004
XKLS
Malaysia Stock Exchange
Malaysia
https://www.bursamalaysia.com/about_bursa/about_us/calendar
添加了 2023.04.21、2023.06.28、2023.09.27, 删除了 2022.02.06、2023.06.29、2023.09.28、2023.11.13
marketHoliday/XKLS.csv
2004
XKRX
Korea Exchange
Republic of Korea
http://global.krx.co.kr/contents/GLB/05/0501/0501110000/GLB0501110000.jsp
marketHoliday/XKRX.csv
2004
XLIM
Lima Stock Exchange
Peru
marketHoliday/XLIM.csv
2004
XLIS
Euronext Lisbon
Portugal
https://www.euronext.com/en/trade/trading-hours-holidays
marketHoliday/XLIS.csv
2004
XLON
London Stock Exchange
England
https://www.londonstockexchange.com/securities-trading/trading-access/business-days
删除了 2023.05.08
marketHoliday/XLON.csv
2004
XMAD
Euronext Lisbon
Portugal
https://www.euronext.com/en/trade/trading-hours-holidays
marketHoliday/XMAD.csv
2004
XMEX
Mexican Stock Exchange
Mexico
https://www.bmv.com.mx/en/bmv-group/holiday-schedule
marketHoliday/XMEX.csv
2004
XMIL
Borsa Italiana
Italy
https://www.borsaitaliana.it/borsaitaliana/calendario-e-orari-di-negoziazione/calendario-borsa-orari-di-negoziazione.en.htm
marketHoliday/XMIL.csv
2004
XMOS
Moscow Exchange
Russia
https://www.moex.com/en/tradingcalendar/
添加了 2023.01.09、2023.11.06、2022.01.03、2022.06.13
marketHoliday/XMOS.csv
2004
XNYS
New York Stock Exchange
USA
https://www.nyse.com/markets/hours-calendars
marketHoliday/XNYS.csv
2004
XNZE
New Zealand Exchangen
New Zealand
https://www.nzx.com/services/nzx-trading/hours-boards
marketHoliday/XNZE.csv
2004
XOSL
Oslo Stock Exchange
Norway
https://www.euronext.com/en/trade/trading-hours-holidays
marketHoliday/XOSL.csv
2004
XPAR
Euronext Paris
France
https://www.euronext.com/en/trade/trading-hours-holidays
marketHoliday/XPAR.csv
2004
XPHS
Philippine Stock Exchange
Philippines
https://www.pse.com.ph/investing-at-pse/#investing2
删除了 2022.12.08、2023.01.02、2023.04.10、2023.11.02、2023.11.27、2023.12.08
marketHoliday/XPHS.csv
2004
XPRA
Prague Stock Exchange
Czech Republic
https://www.pse.cz/en/trading/trading-information/trading-calendar
marketHoliday/XPRA.csv
2004
XSES
Singapore Exchange
Singapore
https://www.mom.gov.sg/employment-practices/public-holidays
删除了 2023.12.25、2023.11.13、2023.08.09、2023.06.29、2023.06.02、2023.05.01、2023.04.07、2023.01.24、2023.01.23
marketHoliday/XSES.csv
2004
XSGO
Santiago Stock Exchange
Chile
https://www.euronext.com/en/trade/trading-hours-holidays
marketHoliday/XSGO.csv
2004
XSHE
Shenzhen Stocak Exchange
China
http://www.szse.cn/disclosure/index.html
marketHoliday/XSHE.csv
1991
XSHG
Shanghai Stock Exchange
China
http://www.sse.com.cn/market/view/
marketHoliday/XSHG.csv
1991
XSTO
Stockholm Stock Exchange
Sweden
https://www.nasdaqomxnordic.com/tradinghours/
marketHoliday/XSTO.csv
2004
XSWX
SIX Swiss Exchange
Switzerland
https://www.six-group.com/en/products-services/the-swiss-stock-exchange/market-data/news-tools/trading-currency-holiday-calendar.html#/
marketHoliday/XSWX.csv
2004
XTAI
Taiwan Stock Exchange Corp
Taiwan, China
https://www.twse.com.tw/en/holidaySchedule/holidaySchedule
marketHoliday/XTAI.csv
2004
XTKS
Tokyo Stock Exchange
Japan
https://www.jpx.co.jp/english/corporate/about-jpx/calendar/
删除了 2023.03.21
marketHoliday/XTKS.csv
2004
XTSE
Toronto Stock Exchange
Canada
https://www.tsx.com/trading/calendars-and-trading-hours/calendar
marketHoliday/XTSE.csv
2004
XWAR
Poland Stock Exchange
Poland
marketHoliday/XWAR.csv
2004
XWBO
Wiener Borse
Austria
https://www.wienerborse.at/en/trading/trading-information/trading-calendar/
添加了 2023.05.29
marketHoliday/XWBO.csv
2004
3.2 中国大陆交易所简称列表
为方便中国大陆用户使用,DolphinDB 也提供了中国大陆六大交易所(上交所、深交所、中金所、上期所、郑商所、大商所、上能源)的简称作为标识码。
标识码 (ISO Code)
交易所
国家
交易所节假日的公布网站
交易日历备注
CSV 文件路径
开始年份
XSHG
Shanghai Stock Exchange
China
http://www.sse.com.cn/market/view/
删除了 2023.05.03、2023.05.02、2023.06.23、2023.10.06
marketHoliday/XSHG.csv
1991
SZSE
Shenzhen Stocak Exchange
China
http://www.szse.cn/disclosure/index.html
删除了 2023.05.03、2023.05.02、2023.06.23、2023.10.06
marketHoliday/SZSE.csv
1991
CCFX
China Finacial Futures Exchange
China
http://www.cffex.com.cn/jyrl/
删除了 2023.05.03、2023.05.02、2023.06.23、2023.10.06
marketHoliday/CFFEX.csv
2006
SHFE
Shanghai Futures Exchange
China
https://www.shfe.com.cn/bourseService/businessdata/calendar/
删除了 2023.05.03、2023.05.02、2023.06.23、2023.10.06
marketHoliday/SHFE.csv
1992
CZCE
Zhengzhou Commodity Exchange
China
http://www.czce.com.cn/cn/jysj/jyyl/H770313index_1.htm
删除了 2023.05.03、2023.05.02、2023.06.23、2023.10.06
marketHoliday/CZCE.csv
1991
XDCE
Dalian Commodity Exchange
China
http://big5.dce.com.cn:1980/SuniT/www.dce.com.cn/DCE/TradingClearing/Exchange%20Notice/1516085/index.html
删除了 2023.05.03、2023.05.02、2023.06.23、2023.10.06
marketHoliday/XDCE.csv
1994
XINE
Shanghai International Energey Exchange
China
https://www.ine.cn/en/news/notice/6598.html
删除了 2023.05.03、2023.05.02、2023.06.23、2023.10.06
marketHoliday/XINE.csv
2017
CFET
China Foreign Exchange Trade System
China
https://www.chinamoney.com.cn/chinese/mgbbjjr/
本交易日历主要服务于 FICC 业务函数,用于确定现金流的发生日期。由于 CFET 市场的交易规则不同于股票和期货交易所,其交易日历中周末也可能存在交易日。因此,与以往记录休市日期的交易日历文件不同,本文件中的数据表示交易日期(tradingDate)。
marketHoliday/CFET.csv
1990
附录
交易日历更新说明
FILE:references/doc_7529.md
# cut
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cut.html
**来源**: DolphinDB 官方文档
---
cut
语法
cut(X, size|cutPositions)
详情
将
X
分为一系列标量、向量、矩阵(按列)或表(按行)。
当
X
是标量时:第二个参数只能是
size
,且
size
值只能为1,cut 函数返回由
X
组成的元组。
当
X
是向量时:
若第二个参数为
size
:cut 函数把
X
分成一系列长度为
size
的标量(
size
=1时)或向量(
size
>1时)。
若第二个参数为
cutPositions
,cut 函数先根据
cutPositions
将
X
分段,然后返回每段子向量组成的元组。
当
X
是矩阵(表)时:
若第二个参数为
size
:cut 函数把
X
分成一系列列数(行数)为
size
的矩阵(表)。
若第二个参数为
cutPositions
,cut 函数先根据
cutPositions
将
X
分段,然后返回每个子矩阵(子表)组成的元组。
关于该函数的逆操作,参见
flatten
函数。
参数
X
是标量/向量。
size
是整型标量,必须满足 0<
size
<=
size
(
X
) 条件。
cutPositions
是单增的整型向量,用于指定切分段开始的索引。
例子
a=1..10;
cut(a,2);
// output
([1,2],[3,4],[5,6],[7,8],[9,10])
cut(a,3);
// output
([1,2,3],[4,5,6],[7,8,9],[10])
cut(a,9);
// output
([1,2,3,4,5,6,7,8,9],[10])
b = cut(a,2);
b;
// output
([1,2],[3,4],[5,6],[7,8],[9,10])
flatten b;
// output
(1,2,3,4,5,6,7,8,9,10)
cut(a, 0 2 7);
// output
([1,2],[3,4,5,6,7],[8,9,10])
cut(a, 2 7);
// output
([3,4,5,6,7],[8,9,10])
m=matrix(1 5 9, 12 20 23, 25 29 32)
cut(m,2)
// output
(#0 #1
-- --
1 12
5 20
9 23
,#0
--
25
29
32
)
cut(m, 1 2)
// output
(#0
--
12
20
23
,#0
--
25
29
32
)
cut
函数在时间数据分析中是一个方便的工具。在下面的例子中,我们用
cut
函数计算两个事件发生期间的收入和。
incomes=table(2016.07.31 - 10..1 as date, rand(100,10) as income);
incomes;
date
income
2016.07.21
78
2016.07.22
61
2016.07.23
79
2016.07.24
15
2016.07.25
78
2016.07.26
22
2016.07.27
30
2016.07.28
81
2016.07.29
17
2016.07.30
52
eventdates = [2016.07.22, 2016.07.25, 2016.07.29];
x = incomes.date.binsrch(eventdates);
x;
// output
[1,4,8]
incomes.date.cut(x);
// output
([2016.07.22,2016.07.23,2016.07.24],[2016.07.25,2016.07.26,2016.07.27,2016.07.28],[2016.07.29,2016.07.30])
table(eventdates as startDate, each(last,incomes.date.cut(x)) as endDate, each(sum,incomes.income.cut(x)) as incomeSum);
startDate
endDate
incomeSum
2016.07.22
2016.07.24
155
2016.07.25
2016.07.28
211
2016.07.29
2016.07.30
69
FILE:references/doc_7533.md
# enableTableCachePurge
**URL**: https://docs.dolphindb.cn/zh/funcs/e/enabletablecachepurge.html
**来源**: DolphinDB 官方文档
---
enableTableCachePurge
语法
enableTableCachePurge(table,
[cacheSize],[cachePurgeTimeColumn],[cachePurgeInterval],[cacheRetentionTime])
详情
为非持久化流表开启自动清理缓存。
通过以下两种方式之一来清理内存中的数据:
配置
cacheSize
参数时,如果插入的数据使内存中流数据表的行数达到阈值,系统将清理内存中较旧的已发布记录。阈值确定方法如下:
每次 append 的数据都不超过
cacheSize
时,阈值为
cacheSize
的 2.5
倍。
当 append 的数据超过
cacheSize
时,阈值为追加行数和 cacheSize 之和的 1.2 倍。
同时配置
cachePurgeTimeColumn
,
cachePurgeInterval
和
cacheRetentionTime
,系统将根据时间列清理数据。每次插入新数据时,系统会计算新数据与内存中第一条数据的时间戳差值,当差值大于等于
cachePurgeInterval
时,系统仅保留时间戳与新数据时间戳差值小于等于
cacheRetentionTime
的数据,清理其它数据。
参数
table
是一个空的流数据表。
cacheSize
是一个正整数,可选参数,表示流数据表在内存中最多保留的记录数。
cachePurgeTimeColumn
字符串标量,需要指定为非持久化流表中的时间列名称。
cachePurgeInterval
DURATION 类型标量,表示触发清理内存中数据的时间间隔。
cacheRetentionTime
DURATION 类型标量,表示内存中数据的最长保留期限。
返回值
无。
例子
例1. 配置 cacheSize 参数,根据内存中的数据量进行清理。
t = streamTable(1000:0, `time`sym`volume, [DATETIME, SYMBOL, INT])
enableTableCachePurge(table=t, cacheSize=1000)
time = datetime(2024.01.01T09:00:00) +1..1000*2
sym=take(`a`b`c, 1000)
volume = rand(10,1000)
insert into t values([time, sym, volume])
getStreamTableCacheOffset(t)
//0
time = datetime(2024.01.01T09:35:00) +1..1000*2
sym=take(`a`b`c, 1000)
volume = rand(10,1000)
insert into t values([time, sym, volume])
getStreamTableCacheOffset(t)
//500
例2. 配置
cachePurgeTimeColumn
,
cachePurgeInterval
和
cacheRetentionTime,
根据时间列清理数据。
t = streamTable(1000:0, `time`sym`volume, [DATETIME, SYMBOL, INT])
enableTableCachePurge(table=t, cachePurgeTimeColumn=`time,
cachePurgeInterval=30m, cacheRetentionTime=20m)
time = datetime(2024.01.01T09:00:00) +1..1000*2
sym=take(`a`b`c, 1000)
volume = rand(10,1000)
insert into t values([time, sym, volume])
getStreamTableCacheOffset(t)
//0
time = datetime(2024.01.01T09:35:00) +1..1000*2
sym=take(`a`b`c, 1000)
volume = rand(10,1000)
insert into t values([time, sym, volume])
getStreamTableCacheOffset(t)
//999
FILE:references/doc_7536.md
# tmvar
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmvar.html
**来源**: DolphinDB 官方文档
---
tmvar
语法
tmvar(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
的样本方差。
返回值
DOUBLE 类型向量。
例子
T = 1 1 3 5 8 15 15 20
X = 5 2 4 1 2 8 9 10
m=table(T as t, X as x)
select *, tmvar(t, x, 3) from m
t
x
tmvar_t
1
5
1
2
4.5
3
4
2.3333
5
1
4.5
8
2
15
8
15
9
0.5
20
10
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = NULL 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmvar(t, x, 3d) from m
t
x
tmvar_t
2021.01.02
2021.01.02
4
2021.01.04
2021.01.05
-1
2021.01.07
2
4.5
2021.01.08
4
2
select *, tmvar(t, x, 1w) from m
t
x
tmvar_t
2021.01.02
2021.01.02
4
2021.01.04
2021.01.05
-1
12.5
2021.01.07
2
6.333
2021.01.08
4
5.5833
相关函数:
mvar
,
var
FILE:references/doc_7538.md
# rowNo
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowNo.html
**来源**: DolphinDB 官方文档
---
rowNo
语法
rowNo(X)
详情
rowNo
通常用于在表中产生行号。行号从 0 开始。
参数
X
是向量。
返回值
返回一个向量。
例子
team=1 1 1 1 1 2 2 2 2 2
id=1..5 join 2..6
x=11..20\2
t=table(team, id, x)
t;
team
id
x
1
1
5.5
1
2
6
1
3
6.5
1
4
7
1
5
7.5
2
2
8
2
3
8.5
2
4
9
2
5
9.5
2
6
10
select * from t where rowNo(id)%3=0;
team
id
x
1
1
5.5
1
4
7
2
3
8.5
2
6
10
update t set teamFirst=(rowNo(id)==0) context by team;
t;
team
id
x
teamFirst
1
1
5.5
1
1
2
6
0
1
3
6.5
0
1
4
7
0
1
5
7.5
0
2
2
8
1
2
3
8.5
0
2
4
9
0
2
5
9.5
0
2
6
10
0
FILE:references/doc_7550.md
# syntax
**URL**: https://docs.dolphindb.cn/zh/funcs/s/syntax.html
**来源**: DolphinDB 官方文档
---
syntax
语法
syntax(X)
详情
返回
X
表示的函数或命令的语法。
参数
X
是 DolphinDB 函数或命令。
返回值
STRING 类型标量。
例子
syntax(createPartitionedTable);
// output
createPartitionedTable(dbHandle, table, tableName, [partitionColumns], [compressMethods])
FILE:references/doc_7551.md
# changePwd
**URL**: https://docs.dolphindb.cn/zh/funcs/c/changePwd.html
**来源**: DolphinDB 官方文档
---
changePwd
语法
changePwd(oldPwd, newPwd)
详情
修改用户密码。
参数
oldPwd
表示用户旧密码的字符串。
newPwd
表示用户新密码的字符串。它不能包含空格或控制字符。
从 2.00.10.10 开始,用户可以通过配置项
enhancedSecurityVerification
控制是否对 newPwd 进行复杂性校验。若不设置
enhancedSecurityVerification
,则不校验;若设置
enhancedSecurityVerification
=true,则要求新密码必须满足以下条件:
字符个数为8~20
至少包含一个大写字母
至少包含以下字符之一:!"#$%&'()*+,-./:;<=>?@[]^_`{|}~。
注:
该函数只能在控制节点、数据节点和计算节点运行。
返回值
无。
例子
changePwd("LTmp4389.", "T5139pm.");
FILE:references/doc_7574.md
# skipClusterReplicationTask
**URL**: https://docs.dolphindb.cn/zh/funcs/s/skipClusterReplicationTask.html
**来源**: DolphinDB 官方文档
---
skipClusterReplicationTask
语法
skipClusterReplicationTask(taskIds)
详情
用于跳过异步复制任务(通常是由于执行异常导致异步复制停止的任务)。该命令只能由管理员在从集群的控制节点调用。
调用该命令前,需先将集群的异步复制流程暂停(调用
stopClusterReplication
函数)。执行完该命令后,再重启异步复制(调用
startClusterReplication
命令)。跳过的任务会被标记为完成状态。
参数
taskIds
标量或向量,表示待跳过的异步复制任务的 id(通过函数
getMasterReplicationStatus
获取)。
例子
skipClusterReplicationTask(1);
相关函数:
startClusterReplication
,
stopClusterReplication
FILE:references/doc_7577.md
# getDFSDatabasesByOwner
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getdfsdatabasebyowner.html
**来源**: DolphinDB 官方文档
---
getDFSDatabasesByOwner
语法
getDFSDatabasesByOwner(user)
详情
该函数仅限管理员用户执行,查询当前集群中所有由用户
user
创建的数据库。
参数
user
STRING 类型标量,表示用户名。
返回值
字符串向量。
例子
getDFSDatabasesByOwner(user="user1")
// output:["dfs://tsdb1","dfs://tsdb2"]
FILE:references/doc_7585.md
# isMonotonicDecreasing
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isMonotonicDecreasing.html
**来源**: DolphinDB 官方文档
---
isMonotonicDecreasing
语法
isMonotonicDecreasing(X)
详情
判断
X
是否为单调递减。
参数
X
可以是标量或向量。
返回值
布尔型标量或向量。
例子
a=[10,7,5,2,int()];
isMonotonicDecreasing(a);
// output: true
a=[10.5,8.7,int(),5.3,1.0];
isMonotonicDecreasing(a);
// output: false
a=[5,10,14,20,int()];
isMonotonicDecreasing(a);
// output: false
相关函数:
isMonotonicIncreasing
,
isMonotonic
FILE:references/doc_7591.md
# tmkurtosis
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmkurtosis.html
**来源**: DolphinDB 官方文档
---
tmkurtosis
语法
tmkurtosis(T, X, window, [biased=true])
部分通用参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
的峰度。
参数
biased
是一个布尔值,表示是否是有偏估计。默认值为 true,表示有偏估计。
返回值
DOUBLE 类型向量。
例子
T = 1 1 1 2 5 6
X = 1 4 NULL -1 NULL 4
m = table(T as t, X as x)
select *, tmkurtosis(t, x, 3) from m
t
x
tmkurtosis_t
1
1
1
4
1
2
-1
1.5
5
6
4
T = take(datehour(2019.06.13 13:30:10),4) join (datehour(2019.06.13 13:30:10)+1..6)
X = 1 NULL 3 4 5 NULL 3 NULL 5 3
m = table(T as t,X as x)
select *, tmkurtosis(t, x, 3d) from m
t
x
tmkurtosis_t
2019.06.13T13
1
2019.06.13T13
2019.06.13T13
3
2019.06.13T13
4
1.5
2019.06.13T14
5
1.8457
2019.06.13T15
1.8457
2019.06.13T16
3
2.2169
2019.06.13T17
2.2169
2019.06.13T18
5
2.2401
2019.06.13T19
3
2.4072
select *, tmkurtosis(t, x, 1w) from m
t
x
tmkurtosis_t
2019.06.13T13
1
2019.06.13T13
2019.06.13T13
3
2019.06.13T13
4
1.5
2019.06.13T14
5
1.8457
2019.06.13T15
1.8457
2019.06.13T16
3
2.2169
2019.06.13T17
2.2169
2019.06.13T18
5
2.2401
2019.06.13T19
3
2.4072
相关函数:
mkurtosis
,
kurtosis
FILE:references/doc_7592.md
# fminLBFGSB
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fminlbfgsb.html
**来源**: DolphinDB 官方文档
---
fminLBFGSB
语法
fminLBFGSB(func, X0, [fprime], [bounds], [m=10],
[factr=1e7], [pgtol=1e-5], [epsilon=1e-8], [maxIter=15000], [maxFun=15000],
[maxLS=20])
详情
使用 L-BFGS-B 算法找到目标函数的最小值。
参数
func
函数名,表示需要最小化的目标函数。注意:该函数的返回值须是数值标量类型。
X0
数值类型的标量或向量,表示使目标函数最小化的参数的初始猜测。
fprime
可选参数,函数名,表示计算
func
梯度的函数。如果为空,则使用数值微分方法来获取函数梯度。
bounds
可选参数,数值类型矩阵,形状为(N,2),其中 N 为需要优化的参数数量,即 N=size(X0)。每一行的两个值(min, max),定义了
X0 中对应参数的边界。可以用
float("inf")
来表示不设边界。
m
可选参数,正整数标量,表示有限内存矩阵的最大可变度量修正数。默认值为 10。
factr
可选参数,数值标量,正数,用于衡量迭代是否结束的指标值。当满足条件
时,算法将停止迭代,其中 eps 是机器精度。
factr
的典型值有:1e12 代表低精度;1e7
代表中等精度;10.0 代表极高的精度。默认值为 1e7。
pgtol
可选参数,数值标量,正数,用于衡量迭代是否结束的指标值。当满足条件
时,算法将停止迭代,其中
是投影梯度的第 i 个分量。默认值为 1e-5。
epsilon
可选参数,数值标量,正数,表示当使用数值近似方法来求解函数梯度时使用的步长。默认值为 1e-8。
maxIter
可选参数,非负整数标量,表示执行的最大迭代次数,默认值为 15000。
maxFun
可选参数,非负整数标量,表示最大目标函数调用次数,默认值为 15000。
maxLS
可选参数,非负整数标量,表示每轮迭代的最大线搜索步数,默认值为 20。
返回值
返回一个字典,字典有以下成员:
xopt:浮点数向量,使目标函数最小化的参数值。
fopt:浮点数标量,目标函数最小值。fopt=func(xopt)。
gopt:浮点数向量,目标函数最小值点处的函数梯度。gopt=func'(xopt)。
iterations:整数标量,优化过程中执行的总迭代数。
fcalls:整数标量,优化过程中的目标函数调用次数。
warnFlag:整数标量,有三个可能值:
0:表示成功执行算法全过程。
1:表示已达最大目标函数调用次数或已达最大迭代次数,算法停止执行。
2:表示由于其他原因算法停止执行。
例子
本例自定义约束条件,传入参数
func
,
X0
,使用 L-BFGS-B 算法找到目标函数
fun
的最小值。
X = double(0..9)
M = 2
B = 3
Y = double(M * X + B)
def fun(params, x, y) {
m = params[0]
b = params[1]
y_model = m*x + b
error = sum(square(y - y_model))
return error
}
initial_values = [0.0, 1.0]
fminLBFGSB(fun{,X,Y}, initial_values)
/* Ouput:
fcalls->27
warnFlag->0
xopt->[1.999999985435,3.000000060585]
gopt->[8.05E-10,8.84E-10]
fopt->0E-12
iterations->6
*/
相关函数:
fminBFGS
FILE:references/doc_7605.md
# 量化金融范例
**URL**: https://docs.dolphindb.cn/zh/tutorials/quant_finance_examples.html
**来源**: DolphinDB 官方文档
---
量化金融范例
建议使用DolphinDB GUI编写DolphinDB脚本。请在DolphinDB官网下载
DolphinDB GUI
。关于如何使用DolphinDB GUI,请参考
DolphinDB GUI 客户端
。
创建或访问分布式数据库和表需要用户权限。本教程使用默认用户名"admin"登录(默认密码是"123456"),后续例子中不再显示登录相关代码。与其他数据库不同,DolphinDB将数据库、编程语言与分布式计算三者融为一体。这种设计使得DolphinDB可以一站式轻量化的解决大数据问题。但是,在引用数据库和表时,不能直接使用数据库或表名称(因为与脚本中的变量名可能会冲突),必须使用
loadTable
函数加载数据表。下面的例子中,我们首先登录。然后加载数据库
dfs://futures 的一个表 quotes,并把这个表对象赋值给变量 quotes,之后就可以用变量 quotes 来访问这个数据表。
login("admin", "123456")
quotes = loadTable("dfs://futures", "quotes")
select count(*) from quotes
1. DolphinDB的存储机制
DolphinDB利用分布式文件系统实现数据库的存储和基本事务机制。数据库以分区(chunk)为单位进行管理。分区的元数据(元数据指数据库的分区信息,每个分区的版本链,大小,存储位置等)存储在控制节点,副本数据存储在各数据节点,统一由分布式文件系统进行管理。一个数据库的数据可能存储在多个服务器上,系统内部通过事务机制和二阶段提交协议保证数据的强一致性和完整性,对于外部用户来说,这些机制是完全透明的。每个分区副本的数据采用列式增量压缩存储。压缩算法采用了LZ4方法,对金融数据平均能达到20%-25%的无损压缩比。
为尽可能保证每个分区的大小平衡,DolphinDB提供了值(VALUE)分区,范围(RANGE)分区,哈希(HASH)分区,列表(LIST)分区和复合(COMPO)分区等多种分区方式,用户可以灵活使用,合理规划分区。复合(COMPO)分区最多可以支持三个维度的分区,支持百万甚至千万级的分区数。在查询时,加载数据的最小单位是一个分区的一个列。DolphinDB不提供行级的索引,而是将分区作为数据库的物理索引。一个分区字段相当于数据表的一个物理索引。如果查询时用到了该分区字段做数据过滤,SQL引擎就能快速定位需要的数据块,而无需对整表进行扫描。在量化金融领域,查询分析大多基于某一个时间段、某个产品标识进行,因此时间和产品标识是量化金融领域最常用的分区维度。
下面展示一个期货tick实时行情数据库的存储目录和文件,其中数据库按照两个维度分区,第一个维度按天(tradingday列)进行值分区,第二个维度按照期货品种(instrument列)分为3个HASH分区,建库建表代码如下所示:
db1 = database("", VALUE, 2020.01.01..2020.12.31)
db2 = database("", HASH,[SYMBOL,3])
db = database("dfs://futures",COMPO, [db1,db2])
colNames=`instrument`tradingday`calendarday`time`lastp`volume`openinterest`turnover`ask1`asksz1`bid1`bidsz1
colTypes=[SYMBOL,DATE,DATE,TIME,DOUBLE,INT,DOUBLE,DOUBLE,DOUBLE,INT,DOUBLE,INT]
t=table(1:0,colNames,colTypes)
db.createPartitionedTable(t,`tick,`tradingday`instrument)
写入数据后,存储目录和数据文件如下所示,
[dolphindb@localhost futures]$ tree
.
├── 20200101
│ ├── Key0
│ │ ├── chunk.dict
│ │ └── tick
│ │ ├── ask1.col
│ │ ├── asksz1.col
│ │ ├── bid1.col
│ │ ├── bidsz1.col
│ │ ├── calendarday.col
│ │ ├── instrument.col
│ │ ├── lastp.col
│ │ ├── openinterest.col
│ │ ├── time.col
│ │ ├── tradingday.col
│ │ ├── turnover.col
│ │ └── volume.col
│ ├── Key1
│ │ ├── chunk.dict
│ │ └── tick
│ │ ├── ask1.col
│ │ ├── asksz1.col
│ │ ├── bid1.col
│ │ ├── bidsz1.col
│ │ ├── calendarday.col
│ │ ├── instrument.col
│ │ ├── lastp.col
│ │ ├── openinterest.col
│ │ ├── time.col
│ │ ├── tradingday.col
│ │ ├── turnover.col
│ │ └── volume.col
│ └── Key2
│ ├── chunk.dict
│ └── tick
│ ├── ask1.col
│ ├── asksz1.col
│ ├── bid1.col
│ ├── bidsz1.col
│ ├── calendarday.col
│ ├── instrument.col
│ ├── lastp.col
│ ├── openinterest.col
│ ├── time.col
│ ├── tradingday.col
│ ├── turnover.col
│ └── volume.col
├── 20200102
│ ├── Key0
...
├── dolphindb.lock
├── domain
└── tick.tbl
从中可以看到,一个分区维度对应一层子目录,譬如按天分区的子目录名是20200101,20200102等,按期货品种HASH分区的子目录名是Key0,Key1等,表中每一列保存为一个后缀名为col的文件,如ask1.col,bid1.col等。
2. 行情数据和K线数据的数据库设计
行情数据是量化金融中量级最大的数据类别。在中国证券市场,每日新增的数据在20-40G左右,累积的历史数据在20-40T左右。传统的关系型数据库处理这样的数据量级的性能非常低下。即使分库分表,效果也不理想。DolphinDB的分区机制可以轻松应对几百TB甚至PB级别的数据量。
为保证最佳性能,尽量将数据均匀分区,且将每个表的每个分区的数据量控制在压缩前100M左右。这是因为DolphinDB并不提供行级的索引,而是将分区作为数据库的物理索引,因此每个分区的数据量不宜过大。
行情数据通常可用时间和产品标识两个维度来进行分区:
(1)
时间维度大部分情况下可以选择按天进行值分区。如果时间跨度不是很长,而每天的数据量又非常大,也可以考虑按照小时进行分区,为此DolphinDB提供了DATEHOUR这种数据类型。设计分区机制时要考虑常用的应用场景。譬如说每次的请求都是对单一股票进行查询或聚合计算,而且跨越的时间比较长,可能几个月甚至一年,那么时间维度上按月分区不失为一种好的做法。
(2)
产品标识维度的分区可采用哈希、范围、值、列表等多种方法。如果每个产品在固定时间内的数据量比较均匀,可采用哈希或范围分区。例如中国的期货与股票市场以固定频率发布报价和交易的快照,因此每个市场内不同产品的数据量基本一致。美国金融市场的行情数据分布则完全不同,不同股票的tick级别数据量差异非常大。这种情境下,可选择范围分区,以一天或多天的数据为样本,将产品标识划分成多个范围,使得每一个范围内的产品的数据总量比较均衡。如果产品个数比较少,譬如期货的品种比较少,也可以考虑用值分区。
行情数据包括每日数据(end of day data)、Level 1、Level 2、Level
3等不同级别的数据。不同级别的数据,数据量差异比较大。所以建议采用不同分区机制的数据库来存储这些数据。
DolphinDB中的多个分区维度并不是层级关系,而是平级的组合关系。如果时间维度有n个分区,产品维度有m个分区,最多可能有n x m个分区。
K线数据或相关的signal数据都是基于高精度的行情数据降低时间精度产生的数据。通常,我们会生成不同频率的K线,譬如1分钟、5分钟、30分钟等等。这些不同频率的K线数据,因为数据量不是太大,建议存储在同一个分区表中,可以增加一个字段frequency来区分不同的时间窗口。K线表通常也按照日期和产品标识两个维度来分区,分区的粒度由数据量决定。以中国股票市场的分钟级K线为例,3000个股票每天产生约240个数据点,总共约72万个数据点。建议时间维度按月进行分区,产品的维度按范围或哈希分成15个分区。这样每个分区的数据量在100万行左右。这样的分区方法,既可在较长时间范围内(1个月或1年)快速查找某一个股票的数据,也可应对查找一天内全部股票的数据这样的任务。
3. 导入历史数据
3.1. 从文本文件导入
中国股票市场每3秒更新一条 level 2
的行情数据,一般包括股票代码、日期、时间、交易量、交易价格、交易次数、买方与卖方的10档报价与量等常用信息,以及其它信息等数据。本例中所用数据为上海证券交易所A股股票2020年6月的
level 2
数据,每天的数据是一个约2.5GB的CSV文件,共68列数据。所有数据文件均存于同一个文件夹下。若其中一半的列为常用数据,遵循每个表每个分区中的常用数据压缩前为100MB左右的原则,可将数据库设计为复合分区。按天(date列)进行值分区,并按照股票代码(symbol列)分为10个HASH分区。
建库以及导入数据的脚本如下。使用
loadTextEx
导入分布式数据库,其详情请参阅
文本数据加载教程
。若您尚无高频数据,可下载
20200601.csv
。若已有高频数据,请注意数据中列名与本例中列名一致。
dbDate = database("", VALUE, 2020.01.01..2020.12.31)
dbSymbol=database("", HASH, [SYMBOL, 10])
db = database("dfs://level2", COMPO, [dbDate, dbSymbol])
//请注意更换目录dataDir
dataDir="/hdd/hdd1/data/Level2TextFiles/"
def importTxtFiles(dataDir, db){
dataFiles = exec filename from files(dataDir) where isDir=false
for(f in dataFiles){
loadTextEx(db, `quotes, `date`symbol, dataDir + f)
}
}
importTxtFiles(dataDir, db);
选择合适的数据库分区机制,对确保数据库最优性能非常重要。具体细节请参阅
分区数据库教程
。
3.2. 从二进制文件导入
本例中导入的数据是上海证券交易所A股股票2020年6月1日的 level 2 数据。请下载二进制文件:
20200601.bin
。与 csv 导入时能自动生成分布式表的 shema
不同,二进制导入前需要显式定义分布式表,具体建库建表的脚本如下:
login("admin", "123456")
dbDate = database("", VALUE, 2020.01.01..2020.12.31)
dbSymbol=database("", HASH, [SYMBOL, 10])
db = database("dfs://level2", COMPO, [dbDate, dbSymbol])
schemaTable=table(
array(SYMBOL,0) as symbol,
array(SYMBOL,0) as market,
array(DATE,0) as date,
array(TIME,0) as time,
array(DOUBLE,0) as preClose,
array(DOUBLE,0) as open,
array(DOUBLE,0) as high,
array(DOUBLE,0) as low,
array(DOUBLE,0) as last,
array(INT,0) as numTrades,
array(INT,0) as curNumTrades,
array(INT,0) as volume,
array(INT,0) as curVol,
array(DOUBLE,0) as turnover,
array(INT,0) as curTurnover,
array(INT,0) as peratio1,
array(INT,0) as peratio2,
array(INT,0) as totalAskVolume,
array(DOUBLE,0) as wavgAskPrice,
array(INT,0) as askLevel,
array(INT,0) as totalBidVolume,
array(DOUBLE,0) as wavgBidPrice,
array(INT,0) as bidLevel,
array(DOUBLE,0) as iopv,
array(INT,0) as ytm,
array(DOUBLE,0) as askPrice1,
array(DOUBLE,0) as askPrice2,
array(DOUBLE,0) as askPrice3,
array(DOUBLE,0) as askPrice4,
array(DOUBLE,0) as askPrice5,
array(DOUBLE,0) as askPrice6,
array(DOUBLE,0) as askPrice7,
array(DOUBLE,0) as askPrice8,
array(DOUBLE,0) as askPrice9,
array(DOUBLE,0) as askPrice10,
array(DOUBLE,0) as bidPrice1,
array(DOUBLE,0) as bidPrice2,
array(DOUBLE,0) as bidPrice3,
array(DOUBLE,0) as bidPrice4,
array(DOUBLE,0) as bidPrice5,
array(DOUBLE,0) as bidPrice6,
array(DOUBLE,0) as bidPrice7,
array(DOUBLE,0) as bidPrice8,
array(DOUBLE,0) as bidPrice9,
array(DOUBLE,0) as bidPrice10,
array(INT,0) as askVolume1,
array(INT,0) as askVolume2,
array(INT,0) as askVolume3,
array(INT,0) as askVolume4,
array(INT,0) as askVolume5,
array(INT,0) as askVolume6,
array(INT,0) as askVolume7,
array(INT,0) as askVolume8,
array(INT,0) as askVolume9,
array(INT,0) as askVolme10,
array(INT,0) as bidVolume1,
array(INT,0) as bidVolume2,
array(INT,0) as bidVolume3,
array(INT,0) as bidVolume4,
array(INT,0) as bidVolume5,
array(INT,0) as bidVolume6,
array(INT,0) as bidVolume7,
array(INT,0) as bidVolume8,
array(INT,0) as bidVolume9,
array(INT,0) as bidVolume10,
array(LONG,0) as unixTime,
array(DOUBLE,0) as upperLimit,
array(DOUBLE,0) as lowerLimit
)
db.createPartitionedTable(schemaTable,`quotes,`date`symbol)
对于二进制格式的文件,DolphinDB提供了2个函数用于导入:
readRecord!
函数和
loadRecord
函数。二者的区别是,前者不支持导入字符串类型的数据,后者支持。在二进制文件中,date列和time列的数据以数值形式存储,可以使用
temporalParse
函数进行日期和时间类型数据的格式转换。再使用
replaceColumn!
函数替换表中原有的列。symbol和market列在二进制文件中也是数值形式存储,处理的方式类似。具体代码如下所示:
schema = [
("symbol", INT), ("market", INT), ("date", INT), ("time", INT), ("preClose", DOUBLE),
("open", DOUBLE), ("high", DOUBLE), ("low", DOUBLE), ("last", DOUBLE), ("numTrades", INT),
("curNumTrades", INT), ("volume", INT), ("curVol", INT), ("turnover", DOUBLE), ("curTurnover", INT),
("peratio1", INT), ("peratio2", INT), ("totalAskVolume", INT), ("wavgAskPrice", DOUBLE), ("askLevel", INT),
("totalBidVolume", INT), ("wavgBidPrice", DOUBLE), ("bidLevel", INT), ("iopv", DOUBLE), ("ytm", INT),
("askPrice1", DOUBLE), ("askPrice2", DOUBLE), ("askPrice3", DOUBLE), ("askPrice4", DOUBLE), ("askPrice5", DOUBLE),
("askPrice6", DOUBLE), ("askPrice7", DOUBLE), ("askPrice8", DOUBLE), ("askPrice9", DOUBLE), ("askPrice10", DOUBLE),
("bidPrice1", DOUBLE), ("bidPrice2", DOUBLE), ("bidPrice3", DOUBLE), ("bidPrice4", DOUBLE), ("bidPrice5", DOUBLE),
("bidPrice6", DOUBLE), ("bidPrice7", DOUBLE), ("bidPrice8", DOUBLE), ("bidPrice9", DOUBLE), ("bidPrice10", DOUBLE),
("askVolume1", INT), ("askVolume2", INT), ("askVolume3", INT), ("askVolume4", INT), ("askVolume5", INT),
("askVolume6", INT), ("askVolume7", INT), ("askVolume8", INT), ("askVolume9", INT), ("askVolme10", INT),
("bidVolume1", INT), ("bidVolume2", INT), ("bidVolume3", INT), ("bidVolume4", INT), ("bidVolume5", INT),
("bidVolume6", INT), ("bidVolume7", INT), ("bidVolume8", INT), ("bidVolume9", INT),("bidVolume10", INT),
("unixTime", LONG), ("upperLimit", DOUBLE), ("lowerLimit", DOUBLE) ]
dataDir="/hdd/hdd1/data/Level2BinFiles/"
def importBinFiles(dataDir, schema){
tick1 = loadTable("dfs://level2","quotes")
dataFiles = exec filename from files(dataDir)
for(f in dataFiles){
t=loadRecord(dataDir + f, schema)
t.replaceColumn!(`date, t.date.string().datetimeParse("yyyyMMdd"))
t.replaceColumn!(`time, t.time.format("000000000").datetimeParse("HHmmssSSS"))
t.replaceColumn!(`symbol, t.symbol.format("000000"))
t.replaceColumn!(`market, iif(t.market==0,"SH","SZ"))
tick1.append!(t)
}
}
importBinFiles(dataDir, schema);
3.3. 生成模拟数据
下列代码通过
sqlDS
函数将之前导入的2020.06.01这一天的数据,按分布式表一个分区生成一个数据源的方式,共分成10个数据源,然后通过
mr
函数将这10份数据先取到内存更新日期,再写入数据库。
mr
函数的parallel参数可设为true,即采用并行执行,以加块生成模拟数据的速度。若服务器内存不足容纳一天的数据,则需要设为false,即采用串行执行以尽量少占用内存。
def writeData(mutable t,dbName,tableName, days){
pt = loadTable(dbName,tableName)
for(day in days){
update t set date = day
pt.append!(t)
}
}
def main(dbName,tableName,days){
rds = sqlDS(<select * from loadTable(dbName,tableName) where date=2020.06.01>)
mr(ds=rds, mapFunc=writeData{,dbName,tableName,days}, parallel=true)
}
login(`admin,`123456)
days=2020.06.01..2020.06.30
days=days[weekday(days) between 1:5]
main("dfs://level2","quotes",days)
4. 基于历史数据库的量化计算
本章节所用数据均为第3章中所建之quotes表。
4.1. 常用的SQL处理
将quotes表元数据载入内存:
db = database("dfs://level2")
quotes = loadTable(db, `quotes);
计算某只股票某天中,每分钟内的平均价差(bid-ask spread),并将结果在GUI以图形展示:
avgSpread = select max((askPrice1-bidPrice1)/(askPrice1+bidPrice1)*2) as avgSpread from quotes where date=2020.06.01, symbol=`600600, time between 09:30:00.000 : 15:00:00.000, askPrice1>=bidPrice1 group by minute(time) as minute
plot(avgSpread.avgSpread, avgSpread.minute, "Average bid-ask spread per minute")
4.2. 使用context by子句处理面板数据(panel data)
context by是DolphinDB独有的功能,是对标准SQL语句的拓展。使用context by子句可以简化对面板数据的操作。
context by与group by类似,都对数据进行分组。但是,用group by时,每一组返回一个标量值,而用context
by时,每一组返回一个和组内元素数量相同的向量。group by只能配合聚合函数使用,而context
by既可以配合聚合函数使用,也可以与移动窗口函数或累积函数等其它函数结合使用。
计算每只股票在2020.06.01中截止到当前时刻的每次数据更新(绝大部分情况下为3秒)中最大交易量:
t = select symbol, date, time, cummax(curVol) as volume_cummax from quotes where date=2020.06.01 context by symbol, date
context by子句亦可结合滑动窗口函数使用。下例计算每只股票在2020.06.01中过去20次数据更新中的平均价格(约为过去一分钟的平均价格):
t = select symbol, date, time, mavg(last, 20) as price_mavg1min from quotes where date=2020.06.01 context by symbol, date
context by子句还可结合聚合函数使用,将聚合函数的分组计算结果赋予组内每一行:
t = select symbol, date, time, max(curVol) as volume_dailyMax from quotes where date=2020.06.01 context by symbol, date
使用某天数据,计算高频因子:
t=select symbol, date, time, (2*bidVolume1+bidVolume2-2*askVolume1-askVolume2)\(2*bidVolume1+bidVolume2+2*askVolume1+askVolume2) as factor1, (2*bidVolume1+bidVolume2-2*askVolume1-askVolume2)\mavg((2*bidVolume1+bidVolume2+2*askVolume1+askVolume2),100) as factor2 from quotes where date=2020.06.01, symbol>=`600000, time between 09:30:00.000 : 15:00:00.000 context by symbol order by symbol, date, time
移动窗口函数可嵌套使用。下例中,首先分别计算第一档买量与卖量100次数据更新(约为5分钟)的移动平均,再计算两者60次数据更新(约为3分钟)的移动相关性。仅用一行代码即可完成。
t=select symbol, date, time, mcorr(mavg(bidVolume1,100), mavg(askVolume1,100), 60) from quotes where date=2020.06.01, symbol>=`600000, time between 09:30:00.000 : 15:00:00.000 context by symbol order by symbol, date, time
4.3. pivot子句的应用
pivot by是DolphinDB的独有功能,是对标准SQL语句的拓展。它将表中某列的内容按照两个维度重新排列,亦可配合数据转换函数使用。
下例中的投资组合的股票代码为向量syms,其中各股票的持仓数量分别为100, 200, 400, 800, 600, 400,
300。本例的目标是计算某天中每个时刻的投资组合价值。请注意,两行DolphinDB代码即可实现目标,但为了读者理解方便,这里分为三步逐步介绍如何实现。
首先对数据使用pivot by子句进行重新排列:
db = database("dfs://level2")
quotes = loadTable(db, `quotes)
syms = `600000`600300`600400`600500`600600`600800`600900
pv = select last from quotes where date=2020.06.01, symbol in syms, time between 09:30:00.000 : 15:00:00.000 pivot by time, symbol
select top 10 * from pv;
注意,从 2.00.2 版本开始,由 pivot by 操作产生的列支持以数字作为列名。而在 2.00.2 以前的版本中,不支持以数字作为列名,会在数字前加上
C。因此,这里结果表中列字段的名称可能会因为版本而有所不同。以下展示 2.00.2 以上版本返回的结果:
time 600000 600300 600400 600500 600600 600800 600900
------------ ------- ------- ------- ------- ------- ------- -------
09:30:00.000 10.63 3.09 3.28 5.03 63.5 4.68 17.43
09:30:03.000 10.62 3.08 3.28 5.03 63.5 4.68 17.4
09:30:05.000 10.61 4.68 17.41
09:30:06.000 3.08 3.28 5.02 63.51
09:30:08.000 10.62 4.68 17.41
09:30:09.000 3.07 3.28 5.03 63.74
09:30:11.000 10.63 4.68 17.42
09:30:12.000 3.07 3.27 5.03 63.95
09:30:14.000 10.64 4.68 17.43
09:30:15.000 3.06 5.03 63.95
可见并不是所有股票均在同一时刻更新数据。若要计算每个时刻的投资组合价值,首先应在以上结果中使用
ffill
函数向前填充last列的空值:
tmp = select ffill(last) from quotes where date=2020.06.01, symbol in syms, time between 09:30:00.000 : 15:00:00.000 pivot by time, symbol
select top 10 * from tmp;
结果为:
time C600000 C600300 C600400 C600500 C600600 C600800 C600900
------------ ------- ------- ------- ------- ------- ------- -------
09:30:00.000 10.63 3.09 3.28 5.03 63.5 4.68 17.43
09:30:03.000 10.62 3.08 3.28 5.03 63.5 4.68 17.4
09:30:05.000 10.61 3.08 3.28 5.03 63.5 4.68 17.41
09:30:06.000 10.61 3.08 3.28 5.02 63.51 4.68 17.41
09:30:08.000 10.62 3.08 3.28 5.02 63.51 4.68 17.41
09:30:09.000 10.62 3.07 3.28 5.03 63.74 4.68 17.41
09:30:11.000 10.63 3.07 3.28 5.03 63.74 4.68 17.42
09:30:12.000 10.63 3.07 3.27 5.03 63.95 4.68 17.42
09:30:14.000 10.64 3.07 3.27 5.03 63.95 4.68 17.43
09:30:15.000 10.64 3.06 3.27 5.03 63.95 4.68 17.43
最后计算每一时刻的投资组合价值:
select time, 100*C600000+200*C600300+400*C600400+800*C600500+600*C600600+400*C600800+300*C600900 from tmp;
4.4. 生成分钟级数据
计算某天分钟级K线:
minuteBar = select first(last) as open, max(last) as high, min(last) as low, last(last) as last, sum(curVol) as volume from quotes where date=2020.06.01, symbol>=`600000 group by symbol, date, minute(time) as minute;
以上为仅计算一天数据的K线。若需使用全部数据计算分钟级K线,并将结果存入数据库,由于全部数据有可能超过内存,同时为了充分利用系统硬件资源进行并行计算,可使用MapReduce函数
mr
。
model=select top 1 symbol,date, minute(time) as minute, open, high, low, last, curVol as volume from quotes where date=2020.06.01,symbol=`600000
if(existsTable("dfs://level2", "minuteBar"))
db.dropTable("minuteBar")
db.createPartitionedTable(model, "minuteBar", `date`symbol)
def saveMinuteBar(t){
minuteBar=select first(last) as open, max(last) as high, min(last) as low, last(last) as last, sum(curVol) as volume from t where symbol>=`600000, time between 09:30:00.000 : 15:00:00.000 group by symbol, date, minute(time) as minute
loadTable("dfs://level2", "minuteBar").append!(minuteBar)
return minuteBar.size()
}
ds = sqlDS(<select symbol, date, time, last, curVol from quotes>)
mr(ds,saveMinuteBar,+)
有关K线计算的更多场景及范例,例如指定K线窗口的起始时刻、重叠K线窗口、使用交易量划分K线窗口等等,请参考
K线计算教程
。
4.5. asof join 及 window join
DolphinDB提供性能极佳的非同时连接函数
aj
及
wj
。函数
aj
(asof
join)为左表中每条记录,在右表中获取符合指定条件的组中该时刻之前(包括该时刻)的最后一条记录;函数
wj
(window
join)为左表中每条记录,在右表中获取符合指定条件的组基于该时刻的指定时间范围的记录并进行计算。DolphinDB的asof
join比pandas中的asof join速度快约200倍。
Asof join 在国际证券市场的最典型应用场景为,报价与交易信息处于不同的数据表中,使用asof
join可以高效的寻找每一笔交易之前的最近一笔报价。在国内证券市场,asof join 亦有许多应用场景。
每天交易结束后,若要将交易价格与交易前的最新报价进行对比,可将交易记录与报价记录进行asof join。如下所示:
trades=table(`600000`600300`600800 as symbol, take(2020.06.01,3) as date, [14:35:18.000, 14:30:30.000, 14:31:09.000] as time, [10.63, 3.12, 4.72] as tradePrice)
quotesTmp=select symbol, date, time, bidPrice1, askPrice1 from quotes where symbol in `600000`600300`600800 and date=2020.06.01
select * from aj(trades, quotesTmp, `symbol`date`time)
结果为:
symbol date time tradePrice quotesTmp_time bidPrice1 askPrice1
------ ---------- ------------ ---------- -------------- --------- ---------
600000 2020.06.01 14:35:18.000 10.63 14:35:17.000 10.62 10.63
600300 2020.06.01 14:30:30.000 3.12 14:30:29.000 3.12 3.13
600800 2020.06.01 14:31:09.000 4.72 14:31:09.000 4.72 4.73
从4.3节中,可见不同的股票行情数据更新的时刻可能不同。若要为某只股票每一个数据更新的时刻,提供另外一只股票在此时刻的最新报价数据,可使用asof
join。
t1 = select symbol, date, time, askPrice1, bidPrice1 from quotes where date=2020.06.01, symbol=`600000, time between 09:30:00.000 : 15:00:00.000
C600300 = select date, time, askPrice1, bidPrice1 from quotes where date=2020.06.01, symbol=`600300, time between 09:30:00.000 : 15:00:00.000
t = aj(t1, C600300, `date`time)
若要对某天中所有记录,计算之前一分钟之内的总交易量,可使用window join。以下脚本中,假设只保留原表中的symbol, date, time,
curVol, askPrice1, bidPrice1这几列。
t=select symbol, date, time, curVol, askPrice1, bidPrice1 from quotes where date=2020.06.01, symbol>=`600000, time between 09:30:00.000 : 15:00:00.000 order by symbol, date, time
t1 = wj(t, t, -60000:-1, <sum(curVol) as sumVolumePrev1m>, `symbol`date`time)
若要对某天中所有记录,寻找一分钟之后第一笔第一档报价,可使用以下脚本。假设只保留原表中的symbol, date, time, askPrice1,
bidPrice1这几列。
t=select symbol, date, time, askPrice1, bidPrice1 from quotes where date=2020.06.01, symbol>=`600000, time between 09:30:00.000 : 15:00:00.000 order by symbol, date, time
t1 = wj(t, t, 60000:70000, <[first(askPrice1) as firstAskPrice1In1m, first(bidPrice1) as firstBidPrice1In1m]>, `symbol`date`time)
4.6. 高阶函数
高阶函数与其它函数的不同之处在于,高阶函数的变量之一为一个函数。输入的数据被分解成多个数据块(可能重叠),然后将函数应用于每个数据块,最后将所有的结果组合为一个对象返回。某些复杂的分析任务如果使用高阶函数,可大大减少代码量。
以下代码计算2020年6月1日交易量最大的100只股票的分钟级收益率的两两相关性。
minuteBar = select first(last) as open, max(last) as high, min(last) as low, last(last) as last, sum(curVol) as volume from quotes where date=2020.06.01, symbol>=`600000 group by symbol, date, minute(time) as minute;
syms = (exec sum(volume) from minuteBar group by symbol order by sum_volume desc).symbol[0:100]
priceMatrix = exec last from minuteBar where symbol in syms pivot by minute, symbol
retMatrix = each(def(x):ratios(x)-1, priceMatrix)
corrMatrix = pcross(corr, retMatrix);
首先计算分钟级K线,然后获取交易量最大的100只股票。将分钟级K线数据整理为每分钟价格矩阵(priceMatrix),其中每列为一只股票,每行为一分钟。然后对价格矩阵使用高阶函数
each
,对每列应用函数ratios(x)-1,将价格矩阵转化为收益率矩阵(retMatrix)。最后对收益率矩阵使用高阶函数
pcross
,对其每两列应用函数
corr
以计算其两两相关性。最终结果为100*100的相关性矩阵(corrMatrix)。
有关其它高阶函数以及更多细节,请参考第八章中的高阶函数部分内容。
4.7. 使用API读写数据
DolphinDB提供Python, C++, Java, C#, Go, JavaScript, Excel等常用系统的API。
Python是目前最流行的数据分析语言,pandas是Python在金融行业最常用的库。本小节讲述如何使用python API
写入分布式数据库以及从DolphinDB数据库中读取数据。
使用Python
API将数据写入分布式数据库
import
dolphindb
as
ddb
import
dolphindb.settings
as
keys
import
pandas
as
pd
import
numpy
as
np
dbPath =
"dfs://level2API"
tableName =
"quotes"
s = ddb.session()
s.connect(
"127.0.0.1"
,
8848
,
"admin"
,
"123456"
)
if
(s.existsDatabase(dbPath)):
s.dropDatabase(dbPath)
s.database(
'dbDate'
,partitionType=keys.VALUE,partitions=
"2020.01.01..2020.12.31"
)
s.database(
'dbSymbol'
,partitionType=keys.HASH,partitions=
"[SYMBOL,10]"
)
s.database(
'db'
, partitionType=keys.COMPO, partitions=
"[dbDate, dbSymbol]"
, dbPath=dbPath)
data=pd.DataFrame({
"symbol"
:[
'600007'
,
'600104'
],
"dt"
:[np.datetime64(
'2020-01-01T20:01:01'
),np.datetime64(
'2020-01-01T20:01:02'
)],
"last"
:[
100.36
,
99.3
],
"askPrice1"
:[
100.36
,
101.22
],
"bidPrice1"
:[
100.35
,
100.45
],
"askVolume1"
:[
4138
,
2
],
"bidVolume1"
:[
20
,
39
],
"volume"
:[
1
,
5
]})
s.run(
"db.createPartitionedTable(table(1:0, `symbol`datetime`last`askPrice1`bidPrice1`askVolume1`bidVolume1`volume, [SYMBOL,DATETIME,DOUBLE,DOUBLE,DOUBLE,INT,INT,INT]),`quotes, `datetime`symbol)"
)
s.upload({
"tmpdata"
:data})
s.run(
"data=select symbol, datetime(dt) as datetime, last, askPrice1, bidPrice1, askVolume1, bidVolume1, volume from tmpdata"
)
s.run(
"tableInsert(loadTable('{db}','{tb}'),data)"
.format(db=dbPath,tb=tableName))
使用Python
API将从分布式数据库中读取数据
import
dolphindb
as
ddb
import
pandas
as
pd
dbPath =
"dfs://level2API"
tableName =
"quotes"
s = ddb.session()
s.connect(
"127.0.0.1"
,
8848
,
"admin"
,
"123456"
)
t = s.run(
"select * from loadTable('{db}','{tb}') where symbol=`600007"
.format(db=dbPath,tb=tableName))
print
(t)
orca 是基于Python API的完全实现pandas接口的库,下面的例子展示在 orca
中如何查询数据:
import
dolphindb.orca
as
orca
orca.connect(
"127.0.0.1"
,
8848
,
"admin"
,
"123456"
)
odf = orca.read_table(
"dfs://level2API"
,
"quotes"
)
t = odf[(odf[
"bidVolume1"
]>
5
*odf[
"askVolume1"
]) & (odf[
"askVolume1"
]>
1000000
)].compute()
print
(t)
更多信息与范例,请参考
Python API 教程
与
orca教程
。
5. 实时行情处理
实时的行情处理过程,首先是在DolphinDB中建立一个流数据表(level2),从API接收实时行情数据,然后通过订阅(subscribeTable)流数据表,将实时数据应用于K线计算、因子计算、实时截面数据更新、分布式表存储等场景中。
5.1. 将数据写入流表
DolphinDB中建立流数据表。以下为DolphinDB脚本:
share streamTable(100:0, `symbol`datetime`last`askPrice1`bidPrice1`askVolume1`bidVolume1`volume, [SYMBOL,DATETIME,DOUBLE,DOUBLE,DOUBLE,INT,INT,INT]) as level2
使用API将实时数据写入DolphinDB流数据表
在实际使用环境中,通常是先通过程序从数据提供商订阅实时数据,然后通过API写入到DolphinDB。本例使用Python
API来展示这一过程,实际使用中用实时数据代替示例中的data变量。以下为Python代码。
import
dolphindb
as
ddb
import
pandas
as
pd
import
numpy
as
np
data = [[
'600007'
,
'600104'
],[np.datetime64(
'2019-01-01T20:01:01'
),np.datetime64(
'2019-01-01T20:01:02'
)],[
100.36
,
99.3
],[
100.36
,
101.22
], [
100.35
,
100.45
],[
4138
,
2
],[
20
,
39
],[
1
,
5
]]
s = ddb.session()
s.connect(
"127.0.0.1"
,
8848
,
"admin"
,
"123456"
)
s.run(
"tableInsert{level2}"
,data)
使用数据回放功能将历史数据以指定速率写入流表
使用
replay
函数,可将历史数据以一定的速率注入到流数据表中,实现数据回放。结合流数据处理引擎或自定义函数使用,可实现基于历史数据的高频策略回测。具体回放函数的使用可参考
数据回放教程
。
在本例中的后续示例中,会使用历史数据回放来代替实时数据。即使在未实现三方数据源接口的情况下,也可以快速体验DolphinDB实时数据处理的功能。
在使用回放功能之前,首先需要准备好供回放的历史数据,本例中利用3.1导入的历史数据来生成回放的分布式表。
dbDate = database("", VALUE, 2020.01.01..2020.12.31)
dbSymbol=database("", HASH, [SYMBOL, 10])
db = database("dfs://level2Replay", COMPO, [dbDate, dbSymbol])
modal = table(1:0, `symbol`datetime`last`askPrice1`bidPrice1`askVolume1`bidVolume1`volume, [SYMBOL,DATETIME,DOUBLE,DOUBLE,DOUBLE,INT,INT,INT])
db.createPartitionedTable(modal,`quotes, `datetime`symbol)
data = select symbol, datetime(datetime(date(date))+second(time)) as datetime, last, askPrice1, bidPrice1, askVolume1, bidVolume1, curVol as volume from loadTable("dfs://level2","quotes")
loadTable("dfs://level2Replay","quotes").append!(data)
使用以下脚本,可以以10倍的速率将已保存到分布式表的报价数据回放到level2流数据表中:
quotes = loadTable("dfs://level2Replay","quotes")
//设置每次提取到内存数据量=1小时
repartitionSchema = time(cutPoints(08:00:00..18:00:00,10))
inputDS = replayDS(<select * from quotes>, `datetime, `datetime, repartitionSchema)
submitJob("replay_quotes", "replay_quotes_stream", replay, [inputDS], [`level2], `datetime, `datetime, 10, false, 2)
当回放函数被提交后,它在后台运行,可以通过
getRecentJobs()
函数查看已经提交的回放任务情况,通过
cancelJob(jobid)
取消回放任务。
本示例脚本下载
5.2. 用流计算生成K线
本小节介绍如何使用流数据时序聚合引擎
createTimeSeriesAggregator
函数实时计算K线。
时间窗口不重合,可将
createTimeSeriesAggregator
函数的windowSize参数和step参数设置为相同值。时间窗口部分重合,可将windowSize参数设为大于step参数。请注意,windowSize必须是step的整数倍。
场景一:每隔5分钟计算过去5分钟的K线数据
modal = table(100:0, `symbol`datetime`last`askPrice1`bidPrice1`askVolume1`bidVolume1`volume, [SYMBOL,DATETIME,DOUBLE,DOUBLE,DOUBLE,INT,INT,INT])
share streamTable(100:0, `datetime`symbol`open`high`low`close`volume,[DATETIME,SYMBOL,DOUBLE,DOUBLE,DOUBLE,DOUBLE,LONG]) as OHLC1
tsAggr1 = createTimeSeriesAggregator(name="tsAggr1", windowSize=300, step=300, metrics=<[first(last),max(last),min(last),last(last),sum(volume)]>, dummyTable=modal, outputTable=OHLC1, timeColumn=`datetime, keyColumn=`symbol)
subscribeTable(tableName="level2", actionName="act_tsAggr1", offset=0, handler=append!{tsAggr1}, msgAsTable=true);
场景二:每隔1分钟计算过去5分钟的K线数据
modal = table(100:0, `symbol`datetime`last`askPrice1`bidPrice1`askVolume1`bidVolume1`volume, [SYMBOL,DATETIME,DOUBLE,DOUBLE,DOUBLE,INT,INT,INT])
share streamTable(100:0, `datetime`symbol`open`high`low`close`volume,[DATETIME,SYMBOL,DOUBLE,DOUBLE,DOUBLE,DOUBLE,LONG]) as OHLC2
tsAggr2 = createTimeSeriesAggregator(name="tsAggr2", windowSize=300, step=60, metrics=<[first(last),max(last),min(last),last(last),sum(volume)]>, dummyTable=modal, outputTable=OHLC2, timeColumn=`datetime, keyColumn=`symbol)
subscribeTable(tableName="level2", actionName="act_tsAggr2", offset=0, handler=append!{tsAggr2}, msgAsTable=true);
本示例脚本下载
5.3. 用流计算生成实时高频因子
除了流数据聚合引擎,用户亦可使用自定义函数进行更复杂的实时计算。下面的例子是将实时数据与历史数据结合来计算因子。
本例中计算的因子定义为:前100笔记录与前200笔记录的资金净流入(net_amount)之比。计算流程为:订阅level2实时数据,调用因子计算函数
factorHandler
计算每只股票的因子值。在算法设计中,为了优化历史数据的存取性能,设计了一个字典(d)来存储每个symbol的历史资金净流入值(net_amount)。类似如下格式:
//字典定义 {key:symbol, value: [net_amount]},
600000->[-85,-69,-32,-57,80,-54,71,87,43,45,...]
600300->[-33,49,16,21,-82,-30,68,-44,-58,-66,...]
600400->[13,35,-67,-30,49,44,85,-10,-42,96,...]
600500->[-15,78,18,17,13,-70,67,-31,-19,-78,...]
600600->[65,-64,-90,-75,85,-99,15,83,-85,60,...]
600800->[14,-78,96,93,-89,92,99,-96,21,93,...]
当实时数据到达后,通过
dictUpdate!
将最新计算得到的net_amount更新到每个symbol的数据向量中,得到一个包含当天历史和最新net_amount数据的字典。针对这个字典通过循环调用自定义函数
calcNetAmountRatio
来计算每只股票的因子值。
核心计算脚本如下
//定义函数calcNetAmountRatio,对一个向量求前n个与前2n个元素之和的比值:
defg calcNetAmountRatio(x,n){
size = x.size()
return x.subarray((size - n):size).sum()\x.subarray((size - 2*n):size).sum()
}
//因子计算函数
def factorHandler(mutable factorTable,mutable d, facName,msg){
codeList = msg.symbol.distinct()
symbolCount = codeList.size()
//资金净流入(net_amount)= volume * iif(bidPrice1>=askPrice1, 1, -1)
t2 = select symbol, volume * iif(bidPrice1>=askPrice1, 1, -1) as net_amount from msg
//将本次数据的计算net_amount追加更新字典
dictUpdate!(d,append!, t2.symbol, t2.net_amount)
//计算因子
factorValue = array(DOUBLE,symbolCount)
for(i in 0:symbolCount){
factorValue[i] = calcNetAmountRatio(d[codeList[i]],100)
}
//添加时间戳,写入因子结果表
factorTable.append!(table(take(now(),symbolCount) as timestamp, codeList as symbol,factorValue as value, take(facName,symbolCount) as factorName))
}
下列脚本完成数据的定义以及预处理
定义保存因子的结果表
share(streamTable(100:0, `timestamp`symbol`value`factorName,[TIMESTAMP,SYMBOL,DOUBLE,SYMBOL]),"FACTOR")
预先构造历史的net_amount数据字典,此处利用了3.1的历史数据表。
d = dict(STRING, ANY)
his = select symbol,volume * iif(bidPrice1>=askPrice1, 1, -1) as net_amount from loadTable("dfs://level2","quotes") context by symbol limit -200
for(id in his[`symbol].distinct())
d[id]= exec net_amount from his where symbol == id
设置level2数据的订阅,建立实时数据和因子处理函数的关系。
subscribeTable(tableName="level2", actionName="act_factor", offset=0, handler=factorHandler{FACTOR,d,"factor1"}, msgAsTable=true, batchSize=4000, throttle=1)
订阅函数的调用需要注意以下几点:
部分应用的使用。因为订阅的handler必须是一个一元函数,仅接受一个msg参数(msg即订阅到的实时数据),所以当因子处理函数需要多个参数时,需要将除msg之外的参数通过部分应用来固化,生成一个符合要求的一元函数。
batchSize和throttle参数的使用。若消息的数量达到batchSize或者距离上次计算的时间间隔达到throttle这两个条件任意一个符合,都会触发handler。
本示例脚本下载
5.4. 使用键值表缓存最新报价和交易价格
某些场景只需要每只股票最新的一条level 2数据。为了保证此类场景的最佳查询性能,可使用键值表订阅流数据表,并指定键值为股票代码。
newestLevel2 = keyedTable(`symbol, 100:0, `symbol`datetime`last`askPrice1`bidPrice1`askVolume1`bidVolume1`volume, [SYMBOL,DATETIME,DOUBLE,DOUBLE,DOUBLE,INT,INT,INT])
subscribeTable(tableName="level2", actionName="newestLevel2data", offset=0, handler=append!{newestLevel2}, msgAsTable=true)
键值表newestLevel2中,每只股票的数据仅为最新的一条level 2数据。
本示例脚本下载
FILE:references/doc_761.md
# 入门示例
**URL**: https://docs.dolphindb.cn/zh/stream/try_example1.html
**来源**: DolphinDB 官方文档
---
入门示例
本节将通过两个示例展示如何实时进行因子计算。
示例1:实时计算买卖价差
本例中我们将以行情快照数据作为输入,针对每一笔快照实时响应,计算并输出买卖价差这一高频因子。
因子计算逻辑
行情数据中包含了买卖双方多档量价信息,买卖价差的定义为卖1价与买1价之差与均价之比:
其中 offerPrice0 、 bidPrice0 分别表示卖1价与买1价。
输入数据示例
实现步骤
接下来,我们将逐步在 DolphinDB 上模拟行情快照数据流,并实时计算输出。完整脚本见附录。
创建作为输入的流数据表
首先创建一个共享流数据表 tick,用于存储和发布行情快照数据:
share(table=streamTable(
1
:
0
, `securityID`dateTime`bidPrice0`bidOrderQty0`offerPrice0`offerOrderQty0, [SYMBOL,TIMESTAMP,DOUBLE,LONG,DOUBLE,LONG]), sharedName=`tick)
执行上述语句后,DolphinDB 数据节点的内存中将创建一个名为 tick 的表,但目前尚未写入任何数据。
创建作为输出的流数据表
创建一个共享流数据表 resultTable,用于存储和发布因子计算结果:
share(table=streamTable(
10000
:
0
, [
"securityID"
,
"dateTime"
,
"factor"
], [SYMBOL, TIMESTAMP, DOUBLE]), sharedName=`resultTable)
执行以上语句后,DolphinDB 数据节点的内存中将创建一个名为 resultTable
的表,但目前尚未写入任何数据。我们希望将后续的计算结果实时写入该表中。
定义计算逻辑
def
factorCalFunc(msg){
tmp = select securityID, dateTime, (offerPrice0-bidPrice0)*
2
\(offerPrice0+bidPrice0)
as
factor
from
msg
objByName(
"resultTable"
).append!(tmp)
}
msg
可以看做一个与 tick 表结构相同的内存表。
objByName("resultTable").append!(tmp)
表示向结果表 resultTable
插入 tmp 表。
tmp 表通过 DolphinDB SQL
语句计算得出,(offerPrice0-bidPrice0)*2\(offerPrice0+bidPrice0) 表示买卖价差公式,对 msg
表中的每一行记录都会计算出对应的买卖价差因子。
订阅流数据表
subscribeTable(tableName=
"tick"
, actionName=
"factorCal"
, offset=-
1
, handler=factorCalFunc, msgAsTable=true, batchSize=
1
, throttle=
0.001
)
订阅流数据表 tick,并指定
factorCalFunc
作为数据处理方法,同时分配一个后台线程不断处理订阅到的新数据。每当表
tick 插入一批数据时,这些数据都会被发布到订阅端,后台线程会接收新增数据,并以此作为输入调用函数
factorCalFunc
。
tableName
="tick" 表示订阅流数据表 tick。
actionName
="factorCal" 表示订阅任务的名称,用户自定义。相同节点上,
tableName
和
actionName
的组合必须唯一。
offset
=-1 表示从订阅之后表 tick 中新增的第一条数据开始消费。
handler
=factorCalFunc 表示对订阅数据的处理方式。
msgAsTable
=true 表示待处理的订阅到的数据是表,即
factorCalFunc
函数的入参
msg
是表。
batchSize
=1 和
throttle
=0.001
共同指定了后台线程的处理频率。本例中任意有一条或多条待处理数据会触发一次
factorCalFunc
的调用。
模拟数据输入
执行上述所有脚本后,我们提交了对流数据表 tick 的订阅,并指定调用自定义函数
factorCalFunc
来处理收到的订阅数据。接下来,我们将向流数据表中注入一些数据,以观察订阅消费的结果。
insert into tick values(`
000001
,
2023.01
.
01
T09:
30
:
00.000
,
19.98
,
100
,
19.99
,
120
)
insert into tick values(`
000001
,
2023.01
.
01
T09:
30
:
03.000
,
19.96
,
130
,
19.99
,
120
)
insert into tick values(`
000001
,
2023.01
.
01
T09:
30
:
06.000
,
19.90
,
120
,
20.00
,
130
)
在向表 tick 插入若干条数据后,查看结果表
resultTable
:
至此,我们通过发布订阅框架和流计算引擎完成了一个流计算任务的开发。不断向流数据表 tick 中插入数据将持续触发计算,并将因子输出到结果表。
如有需要,可参考管理流计算任务,对该计算任务进行监控或环境清理。
示例2:实时计算过去 5 分钟主动成交量占比
在本例中,我们将使用逐笔成交数据作为输入,对每笔数据进行实时响应,计算并输出过去5分钟的主动成交量占比这一高频因子。
因子计算逻辑
主动成交占比即主动成交量占总成交量的比例,其计算公式如下:
其中:
actVolumes
t
表示 t-window 时刻到 t 时刻区间内的主动成交量;指示函数
I
buyNo>selNo
的含义如下:
totalVolume
t
表示 t-window 时刻到 t 时刻区间的总成交量。
输入数据示例
实现步骤
接下来,我们将逐步在 DolphinDB 上模拟逐笔成交数据流,并实时计算输出。完整脚本见附录。
创建作为输入的流数据表
首先创建一个共享流数据表 trade ,用于存储和发布逐笔成交数据:
share(table=streamTable(1:0, `securityID`tradeTime`tradePrice`tradeQty`tradeAmount`buyNo`sellNo, [SYMBOL,TIMESTAMP,DOUBLE,INT,DOUBLE,LONG,LONG]), sharedName=`trade)
执行以上语句后,DolphinDB 数据节点的内存中将创建一个名为 trade 的表,但目前尚未写入任何数据。
创建作为输出的流数据表
创建一个共享流数据表 resultTable,用于存储和发布因子计算结果:
share(table=streamTable(10000:0, ["securityID", "tradeTime", "factor"], [SYMBOL, TIMESTAMP, DOUBLE]), sharedName=`resultTable)
执行以上语句后,DolphinDB 数据节点的内存中将创建一个名为 resultTable
的表,但目前尚未写入任何数据。我们希望将后续的计算结果实时写入该表中。
定义计算逻辑
示例 1
中的因子计算不涉及状态,因此实现逻辑相对简单。而本示例的主动成交量因子计算依赖于历史记录,因此其计算逻辑需要考虑如何获取状态。本节将首先介绍一种错误的实现方式,以帮助用户理解带状态因子计算的处理方法,接着给出了正确的实现逻辑。
定义错误的计算函数
首先,我们定义一个 factorVolumeCalFunc 函数:
def factorVolumeCalFunc (msg){
tmp = select securityID, tradeTime, tmsum(tradeTime, iif(buyNo>sellNo, tradeQty, 0), 5m)\tmsum(tradeTime, tradeQty, 5m) as factor from msg context by securityID
objByName("resultTable").append!(tmp)
}
subscribeTable(tableName="trade", actionName="factorCal", offset=-1, handler=factorVolumeCalFunc , msgAsTable=true, batchSize=1, throttle=0.001)
msg
可以看做一个与 trade 表结构相同的内存表
objByName("resultTable").append!(tmp) 表示往结果表 resultTable 插入 tmp 表
tmp 表通过 DolphinDB SQL 语句计算得到:
SQL 语句中使用 context by 对表 msg 分组后,返回的结果表 tmp 的行数与 msg 一致。context by
和时间序列函数(如此处的 tmsum)一起使用,可实现在分组内( securityID
)按记录的顺序逐行进行滑动时间窗口聚合计算。
tmsum(tradeTime, tradeQty, 5m) 表示以 tradeTime 为时间列,对每一行划定过去 5
分钟的窗口,对窗口内所有记录的 tradeQty 求和,即过去五分钟的总成交量。
tmsum(tradeTime, iif(buyNo>sellNo, tradeQty, 0), 5m) 表示以
tradeTime 为时间列,对每一行划定过去 5 分钟窗口,对窗口内 buyNo>sellNo 的这部分记录的
tradeQty 求和,即过去五分钟的主动成交量。
当该函数被用于处理订阅数据时,每次仅基于 trade
表新增的记录进行计算,而未能缓存或获取主动成交量因子依赖的历史记录。这会导致错误结果错误。下面进一步展示函数计算的过程及结果。
首先构造一批数据调用一次 factorVolumeCalFunc 函数。
// 定义结果表
share(table=streamTable(10000:0, ["securityID", "tradeTime", "factor"], [SYMBOL, TIMESTAMP, DOUBLE]), sharedName=`resultTable)
// 构造输入数据
input1 = table(1:0, `securityID`tradeTime`tradePrice`tradeQty`tradeAmount`buyNo`sellNo, [SYMBOL,TIMESTAMP,DOUBLE,INT,DOUBLE,LONG,LONG])
insert into input1 values(`000155, 2020.01.01T09:30:00.000, 30.85, 100, 3085, 4951, 0)
insert into input1 values(`000155, 2020.01.01T09:31:00.000, 30.86, 100, 3086, 4952, 1)
insert into input1 values(`000155, 2020.01.01T09:32:00.000, 30.85, 200, 6170, 5001, 5100)
insert into input1 values(`000155, 2020.01.01T09:33:00.000, 30.83, 100, 3083, 5202, 5204)
insert into input1 values(`000155, 2020.01.01T09:34:00.000, 30.82, 300, 9246, 5506, 5300)
insert into input1 values(`000155, 2020.01.01T09:35:00.000, 30.82, 500, 15410, 5510, 5600)
// 调用一次 factorVolumeCalFunc 函数
factorVolumeCalFunc (msg=input1)
执行下述语句查询结果表:
select * from resultTable
返回结果如下,目前结果正确:
再构造1条数据,并调用一次 factorVolumeCalFunc 函数:
// 构造输入数据
input2 = table(1:0, `securityID`tradeTime`tradePrice`tradeQty`tradeAmount`buyNo`sellNo, [SYMBOL,TIMESTAMP,DOUBLE,INT,DOUBLE,LONG,LONG])
insert into input2 values(`000155, 2020.01.01T09:36:00.000, 30.87, 800, 24696, 5700, 5600)
// 再调用一次 factorVolumeCalFunc 函数
factorVolumeCalFunc (msg=input2)
结果表如下,最后一行对应新增的 input2 的结果,factor 值明显错误:
定义正确的计算函数
为了实现正确的计算逻辑,我们需要在上文的 factorVolumeCalFunc 函数基础上进行复杂的改写,以获取历史数据。然而,DolphinDB
提供了一种更简便的实现方式——DolphinDB
计算引擎。流计算引擎可以被视为一个封装的独立计算黑盒,其内部会缓存所需的历史数据或中间结果(即状态),通过向其写入数据触发计算,并将结果输出到目标表。有关流计算引擎的详细介绍,
内置流计算引擎
。
针对不同场景,DolphinDB 提供了多种流计算引擎。在本例中,由于需要逐条分组响应计算并输出,因此应选择响应式状态引擎。
createReactiveStateEngine(name="reactiveDemo", metrics=<[tradeTime, tmsum(tradeTime, iif(buyNo>sellNo, tradeQty, 0), 5m)\tmsum(tradeTime, tradeQty, 5m)]>, dummyTable=trade, outputTable=resultTable, keyColumn="securityID")
def factorVolumeCalFunc (msg){
getStreamEngine("reactiveDemo").append!(msg)
}
以上代码使用 createReactiveStateEngine 函数定义一个响应式状态引擎:
引擎需要一个在节点上唯一的名字,此处为 reactiveDemo。
dummyTable
=trade 表示引擎的输入表结构与表 trade 一致。
outputTable
=resultTable 表示计算结果输出到结果表 resultTable。
keyColumn
="securityID" 表示按 securityID 进行分组计算。分组列将作为引擎输出表的第一列。
metrics
定义了因子计算的逻辑。其中的 tradeTime 表示将输入的 tradeTime
列随计算结果一同输出,tmsum(tradeTime, iif(buyNo>sellNo, tradeQty, 0),
5m)\tmsum(tradeTime, tradeQty, 5m) 计算得到的主动成交量占比作为计算结果列输出。
在此定义的 factorVolumeCalFunc 函数中,tmsum 在响应式状态引擎中的含义与上文 SQL
语句中的业务含义一致,但其内部实现有所不同。在引擎中,tmsum 是基于上一条计算结果进行增量计算的,因此引擎会缓存必要的计算状态。例如,对于输入记录
09:36:00.000,其过去 5 分钟的总成交量计算公式为:该记录之前的最后一条记录过去 5 分钟总成交量 + 该记录的成交量 - 上一条记录的过去 5
分钟窗口内不属于当前记录时间窗口的记录对应的成交量。
订阅流数据表
subscribeTable(tableName="trade", actionName="factorCal", offset=-1, handler=factorVolumeCalFunc, msgAsTable=true, batchSize=1, throttle=0.001)
subscribeTable 函数的
handler
参数除了指定为一元函数外,还可以直接指定为数据表。getStreamEngine("reactiveDemo") 返回的流计算引擎句柄是一个数据表,因此可以将
handler
直接指定为引擎句柄,而无需额外定义 factorVolumeCalFunc 函数,从而简化上述脚本。
createReactiveStateEngine(name="reactiveDemo", metrics=<[tradeTime, tmsum(tradeTime, iif(buyNo>sellNo, tradeQty, 0), 5m)\tmsum(tradeTime, tradeQty, 5m)]>, dummyTable=trade, outputTable=resultTable, keyColumn="securityID")
subscribeTable(tableName="trade", actionName="factorCal", offset=-1, handler=getStreamEngine("reactiveDemo"), msgAsTable=true, batchSize=1, throttle=0.001)
模拟数据输入
insert into trade values(`000155, 2020.01.01T09:30:00.000, 30.85, 100, 3085, 4951, 0)
insert into trade values(`000155, 2020.01.01T09:31:00.000, 30.86, 100, 3086, 4952, 1)
insert into trade values(`000155, 2020.01.01T09:32:00.000, 30.85, 200, 6170, 5001, 5100)
insert into trade values(`000155, 2020.01.01T09:33:00.000, 30.83, 100, 3083, 5202, 5204)
insert into trade values(`000155, 2020.01.01T09:34:00.000, 30.82, 300, 9246, 5506, 5300)
insert into trade values(`000155, 2020.01.01T09:35:00.000, 30.82, 500, 15410, 5510, 5600)
插入若干条数据到表 trade 后,查看结果表 resultTable:
以上结果符合预期。我们再插入一条数据:
insert into trade values(`000155, 2020.01.01T09:36:00.000, 30.87, 800, 24696, 5700, 5600)
结果表对应地新增了一条记录,且对于09:36:00这条记录,计算得到了正确的 factor 值:
管理流计算任务
系统提供了运维函数,用于查看流计算的执行情况。除了通过函数查询外,在 2.00.11 及以上版本中,用户还可以在 Web 界面的流计算监控模块中直接查看。
查看流订阅消费的状态
调用
getStreamingStat
函数,可以查看订阅状态。
getStreamingStat().subWorkers
执行代码后,可以观察到节点上有一个订阅线程在工作。该订阅已经处理了 7 条消息,目前没有报错。订阅消费队列的最大深度为1000万,目前队列里没有待处理的数据。
查看流计算引擎状态
getStreamEngineStat().ReactiveStreamEngine
执行以上代码后可以看到,目前插入引擎的输入数据中,只有一个分组(即000155),共输入了 7 条数据,引擎内部维护的状态占用了1836字节。
清理流计算环境
当流计算任务运行一段时间后,或许我们需要下线计算任务、更改计算逻辑或者修改输入源的表结构,那么我们可能需要将订阅、引擎或者流数据表分别取消掉,可以使用以下系统函数。
取消订阅:
unsubscribeTable(tableName="trade", actionName="factorCal")
执行以上代码可以取消特定的订阅关系,之后表 trade 再发布数据,系统也不会计算主动成交量因子。
释放流计算引擎:
dropStreamEngine(`reactiveDemo)
执行以上脚本可以释放流计算引擎
reactiveDemo
,引擎占用的内存也会一起释放。
删除流数据表:
dropStreamTable(`trade)
附录
示例 1 完整脚本
// 创建作为输入的流数据表
share(table=streamTable(
1
:
0
, `securityID`dateTime`bidPrice0`bidOrderQty0`offerPrice0`offerOrderQty0, [SYMBOL,TIMESTAMP,DOUBLE,LONG,DOUBLE,LONG]), sharedName=`tick)
// 创建作为输出的流数据表
share(table=streamTable(
10000
:
0
, [
"securityID"
,
"dateTime"
,
"factor"
], [SYMBOL, TIMESTAMP, DOUBLE]), sharedName=`resultTable)
go
// 定义处理函数
def
factorCalFunc(msg){
tmp = select securityID, dateTime, (offerPrice0-bidPrice0)*
2
\(offerPrice0+bidPrice0)
as
factor
from
msg
objByName(
"resultTable"
).append!(tmp)
}
// 订阅流数据表
subscribeTable(tableName=
"tick"
, actionName=
"factorCal"
, offset=-
1
, handler=factorCalFunc, msgAsTable=true, batchSize=
1
, throttle=
0.001
)
go
// 模拟数据输入
insert into tick values(`
000001
,
2023.01
.
01
T09:
30
:
00.000
,
19.98
,
100
,
19.99
,
120
)
insert into tick values(`
000001
,
2023.01
.
01
T09:
30
:
03.000
,
19.96
,
130
,
19.99
,
120
)
insert into tick values(`
000001
,
2023.01
.
01
T09:
30
:
06.000
,
19.90
,
120
,
20.00
,
130
)
示例 2 完整脚本
// 创建作为输入的流数据表
share(table=streamTable(
1
:
0
, `securityID`tradeTime`tradePrice`tradeQty`tradeAmount`buyNo`sellNo, [SYMBOL,TIMESTAMP,DOUBLE,INT,DOUBLE,LONG,LONG]), sharedName=`trade)
// 创建作为输出的流数据表
share(table=streamTable(
10000
:
0
, [
"securityID"
,
"tradeTime"
,
"factor"
], [SYMBOL, TIMESTAMP, DOUBLE]), sharedName=`resultTable)
go
// 定义处理函数
createReactiveStateEngine(name=
"reactiveDemo"
, metrics=<[tradeTime, tmsum(tradeTime, iif(buyNo>sellNo, tradeQty,
0
),
5
m)\tmsum(tradeTime, tradeQty,
5
m)]>, dummyTable=trade, outputTable=resultTable, keyColumn=
"securityID"
)
// 订阅流数据表
subscribeTable(tableName=
"trade"
, actionName=
"factorCal"
, offset=-
1
, handler=getStreamEngine(
"reactiveDemo"
), msgAsTable=true, batchSize=
1
, throttle=
0.001
)
go
insert into trade values(`
000155
,
2020.01
.
01
T09:
30
:
00.000
,
30.85
,
100
,
3085
,
4951
,
0
)
insert into trade values(`
000155
,
2020.01
.
01
T09:
31
:
00.000
,
30.86
,
100
,
3086
,
4952
,
1
)
insert into trade values(`
000155
,
2020.01
.
01
T09:
32
:
00.000
,
30.85
,
200
,
6170
,
5001
,
5100
)
insert into trade values(`
000155
,
2020.01
.
01
T09:
33
:
00.000
,
30.83
,
100
,
3083
,
5202
,
5204
)
insert into trade values(`
000155
,
2020.01
.
01
T09:
34
:
00.000
,
30.82
,
300
,
9246
,
5506
,
5300
)
insert into trade values(`
000155
,
2020.01
.
01
T09:
35
:
00.000
,
30.82
,
500
,
15410
,
5510
,
5600
)
insert into trade values(`
000155
,
2020.01
.
01
T09:
36
:
00.000
,
30.87
,
800
,
24696
,
5700
,
5600
)
FILE:references/doc_7615.md
# migrate
**URL**: https://docs.dolphindb.cn/zh/funcs/m/migrate.html
**来源**: DolphinDB 官方文档
---
migrate
语法
migrate(backupDir, [backupDBPath], [backupTableName],
[newDBPath=backupDBPath], [newTableName=backupTableName],
[keyPath])
详情
恢复数据库中已备份的数据。该函数必须要用户登录后才能执行。
migrate 函数有以下三种用法
:
migrate(backupDir): 恢复该目录下所有数据库的备份数据。恢复后的数据库名称、表名称与原数据库、原表一致。
migrate(backupDir, backupDBPath):
恢复该目录下指定数据库的备份数据。恢复后的数据库名称、表名称与原数据库、原表一致。
migrate(backupDir, backupDBPath, backupTableName, [newDBPath],
[newTableName]): 恢复该目录下指定数据库指定表的备份数据。如果没有指定
newDBPath
和
newTableName
,恢复后的数据库名称、表名称与原数据库、原表一致。如果指定了
newDBPath
和
newTableName
,恢复后的数据库名称为
newDBPath
,表名为
newTableName
。
参数
backupDir
字符串,表示存放已备份数据的目录。
backupDBPath
字符串,表示已备份的数据库的名称。
backupTableName
字符串,表示已备份的表的名称。
newDBPath
字符串,表示新数据库的名称。如果没有指定,默认值为
backupDBPath
。
若指定该参数,则需要确保备份数据与
newDBPath
的引擎类型(engine)一致,且 partitionScheme(VALUE 除外)也保持一致。
当采用 VALUE 分区时,须保证备份数据中的分区方案是待恢复数据库的分区方案的子集。
newTableName
字符串,表示新表的名称。如果没有指定,默认值为
backupTableName
。
keyPath
字符串标量,指定恢复加密表备份的密钥路径。仅 Linux
系统支持该参数。恢复数据使用的密钥必须与备份时指定的密钥版本一致。注意恢复加密表时,备份表与目标表必须指定相同的加密方式(即建表时指定相同的
encryptMode
参数)。
返回值
返回的结果是一个表,包含了每个表恢复数据的结果。
例子
创建两个示例数据库,并将它们备份到相同的目录中:
backupDir="/home/DolphinDB/backup"
n = 1000000
t1 = table(rand(2012.12.01..2012.12.10, n) as date, rand(`AAPL`IBM`GOOG`MSFT, n) as sym, rand(1000.0,n) as price)
t2 = table(rand(2012.12.01..2012.12.10, n) as date, rand(`AAPL`IBM`GOOG`MSFT, n) as sym, rand(1000,n) as qty)
db1 = database("dfs://db1", VALUE, 2012.12.01..2012.12.10)
trades1 = db1.createPartitionedTable(t1, `trades1, `date).append!(t1)
trades2 = db1.createPartitionedTable(t2, `trades2, `date).append!(t2)
n = 1000000
t1 = table(rand(2012.12.01..2012.12.10, n) as date, rand(`AAPL`IBM`GOOG`MSFT, n) as sym, rand(1000.0,n) as price)
t2 = table(rand(2012.12.01..2012.12.10, n) as date, rand(`AAPL`IBM`GOOG`MSFT, n) as sym, rand(1000,n) as qty)
db1 = database("dfs://db2", VALUE, `AAPL`IBM`GOOG`MSFT)
quotes1 = db1.createPartitionedTable(t1, `quotes1, `sym).append!(t1)
quotes2 = db1.createPartitionedTable(t2, `quotes2, `sym).append!(t2)
backup(backupDir, <select * from trades1>, true)
backup(backupDir, <select * from trades2>, true)
backup(backupDir, <select * from quotes1>, true)
backup(backupDir, <select * from quotes2>, true)
删除原来的数据库:
dropDatabase("dfs://db1")
dropDatabase("dfs://db2")
例1. 恢复所有数据库的数据
migrate(backupDir);
dbName
tableName
success
errorMsg
dfs://db1
trades1
1
dfs://db1
trades2
1
dfs://db2
quotes2
1
dfs://db2
quotes1
1
例2. 恢复数据库
dfs://db1
中所有表的数据
migrate(backupDir, "dfs://db1");
dbName
tableName
success
errorMsg
dfs://db1
trades1
1
dfs://db1
trades2
1
例3. 恢复数据库
dfs://db1
中表 trades1 的数据
例3.1 不指定新数据库名称和表名称
migrate(backupDir, "dfs://db1", "trades1");
dbName
tableName
success
errorMsg
dfs://db1
trades1
1
例3.2 指定新数据库名称和表名称
migrate(backupDir, "dfs://db1", "trades1", "dfs://db3", "trades");
dbName
tableName
success
errorMsg
dfs://db1
trades1
1
exec count(*) from loadTable("dfs://db3", "trades")
// output
1000000
相关函数:
backup
,
backupDB
,
backupTable
,
restore
,
restoreDB
,
restoreTable
FILE:references/doc_7620.md
# addMCPPrompt
**URL**: https://docs.dolphindb.cn/zh/funcs/a/addMCPPrompt.html
**来源**: DolphinDB 官方文档
---
addMCPPrompt
语法
addMCPPrompt(name, message, [description], [extraInfo])
详情
定义一个 MCP prompt 模板。
参数
name
STRING 类型标量,表示 prompt 模板的名称。
message
STRING 类型标量,表示 prompt 模板内容,允许包含
{}
占位符。
description
可选参数,STRING 类型标量,表示 prompt 模板说明。
extraInfo
可选参数,一个字典,键是 STRING 类型,值是 ANY 或 STRING 类型,用于指定其他信息。目前键支持
"title"。
返回值
一个字符串,表示新增 MCP prompt 模板的名称。
例子
addMCPPrompt(
name = "stock_summary",
message = "请用一句话总结 stock 从 startDate 到 endDate 的走势。",
description = "生成某个股票在一段时间内的自然语言概述",
extraInfo = {title : "股票走势总结"}
)
//output:'stock_summary'
FILE:references/doc_7621.md
# mslr
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mslr.html
**来源**: DolphinDB 官方文档
---
mslr
语法
mslr(Y, X, window, [minPeriods])
详情
在长度为
window
的滑动窗口中,将因变量
Y
与自变量
X
进行普通最小二乘回归。返回一个元组,其中第一个元素为截距,第二个元素为斜率。
如果没有指定
minPeriods
,结果的前 (
window
- 1) 个元素为NULL;
如果指定了
minPeriods
,结果的前 (
minPeriods
- 1) 个元素为NULL。
参数
Y
是一个向量,表示因变量。
X
是一个向量,表示自变量。
window
是一个正整数,表示滑动窗口的长度。
minPeriods
是一个正整数。如果一个滑动窗口中的非 NULL 值的数量小于
minPeriods
,那么该窗口的结果为NULL。
返回值
返回一个元组,包含两个元素:
第一个元素表示截距,类型为 DOUBLE。
第二个元素表示斜率,类型为 DOUBLE。
例子
Y=1 4 3 9 5 4
X=12 31 29 88 67 76
mslr(Y,X,4);
//output: ([,,,0.177052,0.712557,0.15],[,,,0.101824,0.084418,0.078462])
FILE:references/doc_7622.md
# acf
**URL**: https://docs.dolphindb.cn/zh/funcs/a/acf.html
**来源**: DolphinDB 官方文档
---
acf
语法
acf(X, maxLag)
详情
计算
X
的1阶至
maxLag
阶的自相关系数。
参数
X
是一个向量。
返回值
长度为
maxLag
+ 1 的向量。
例子
n=10000
x=array(DOUBLE, n, n, NULL)
x[0]=1
r=rand(0.05, n)-0.025
for(i in 0:(n-1)){
x[i+1]=-0.8*x[i]+r[i]
}
acf = acf(x, 20)
plot(acf,chartType=BAR)
相关函数:
autocorr
FILE:references/doc_7628.md
# withdrawMCPTools
**URL**: https://docs.dolphindb.cn/zh/funcs/w/withdrawMCPTools.html
**来源**: DolphinDB 官方文档
---
withdrawMCPTools
语法
withdrawMCPTools([names])
详情
撤销已发布的 MCP tool。
参数
names
可选参数,STRING 类型标量或向量,表示 tool 的名称。
返回值
一个 STRING 类型向量,表示撤销成功的 tool。
例子
withdrawMCPTools("myTool")
FILE:references/doc_7630.md
# imtUpdateChunkVersionOnDataNode
**URL**: https://docs.dolphindb.cn/zh/funcs/i/imtUpdateChunkVersionOnDataNode.html
**来源**: DolphinDB 官方文档
---
imtUpdateChunkVersionOnDataNode
语法
imtUpdateChunkVersionOnDataNode(chunkId, version)
详情
修改数据节点上对应
chunkId
的版本号,以维护集群中多副本数据之间,或数据节点与控制节点之间的版本一致性。
该函数只能在数据节点执行。
参数
chunkId
字符串标量或向量,表示 chunk 的 ID。
version
整型数字,表示版本号。
返回值
无。
相关函数
控制节点可调用函数
getClusterChunksStatus
查询所有节点上 chunk 对应的版本号。
数据节点可调用函数
getChunksMeta
查询当前数据节点上 chunk 对应的版本号。
FILE:references/doc_7642.md
# getAclAuditLog
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getaclauditlog.html
**来源**: DolphinDB 官方文档
---
getAclAuditLog
语法
getAclAuditLog([userId],[startTime],[endTime],[opType])
详情
查询用户
userId
在
startTime
到
endTime
这段时间内完成的,类型为
opType
的
ACL 操作记录。
参数
userId
可选参数,字符串标量或向量,表示要查询的用户。默认为 NULL,表示查询所有用户的 ACL 操作日志。
startTime
可选参数,整型标量或者时间标量,表示查询的起始时间点。时间标量支持 DATE, MONTH, DATETIME, TIMESTAMP,
DATEHOUR, NANOTIMESTAMP 类型。默认值为 1970.01.01,表示 1970.01.01零点。
endTime
可选参数,整型标量或者时间标量,表示查询的结束时间点。时间标量支持DATE, MONTH, DATETIME, TIMESTAMP,
DATEHOUR, NANOTIMESTAMP 类型。默认值为空,表示结束时间为当前时间。
endTime
必须大于
startTime
。
opType
可选参数,字符串标量或向量,表示查询的操作类型。默认为 NULL,表示查询所有 ACL 操作类型。关于
opType
的详细描述参见详情。
返回值
一张表,包含以下字段:
userId:表示执行操作的用户名称。
time:表示操作发生时间。
opType:表示操作类型。
opDetail:操作细节说明。
remoteIp:提交该操作的客户端 IP。
remotePort:提交该操作的客户端端口。
opType
的所有取值及其对应的 opDetail 示例如下:
opType
opDetail
Description
login
login userId=xxx encrypted=true/false
用户登录
logout
logout userId=xxx sessionOnly=true/false
用户登出
createUser
userId=xxx groupId=xxx isAdmin=true/false
创建用户
createGroup
groupId=xxx userIds=[xxx,xxx,…]
创建用户组
resetPwd
userId=xxx
重置用户密码
changePwd
修改用户密码
deleteUser
userId=xxx
删除用户
deleteGroup
groupId=xxx
删除用户组
addGroupMember
userIds=[xxx,xxx,…] groupIds=[xxx,xxx,…]
把用户添加到群组
deleteGroupMember
userIds=[xxx,xxx,…] groupIds=[xxx,xxx,…]
删除用户组的成员
grant
userOrGroupId=xxx accessType=xxx objs=[xxx,xxx,…]
授予权限
deny
userOrGroupId=xxx accessType=xxx objs=[xxx,xxx,…]
拒绝权限
revokeByDFSOperation
oldObj=xxx newObjs=[xxx,xxx,…]
进行 dropDatabase, dropTable 或 dropColumn!
删除操作时,会自动清除所有用户中与被删除内容相关的权限。
replaceByDFSOperation
oldObj=xxx newObjs=[xxx,xxx,…]
进行 renameTable 和 replaceColumn! 等修改操作时,会同步更新与被修改内容相关的权限信息
revoke
userOrGroupId=xxx accessType=xxx objs=[xxx,xxx,…]
撤回权限
createCatalog
catalog=xxx
创建 catalog
dropCatalog
catalog=xxx
删除 catalog
renameCatalog
catalog=xxx new catalog=xxx
重命名 catalog
renameSchema
catalog=xxx schema=xxx new schema=xxx
重命名 schema
createSchema
catalog=xxx dbUrl=xxx schema=xxx
创建 schema
dropSchema
catalog=xxx schema=xxx
删除 schema
tryDropSchemaByDatabase
dbUrl=xxx
删除数据库时,从 catalog 里删掉 db 对应的 schema
setMaxJobPriority
maxJobPriority=xxx
指定提交作业的最高优先级
setMaxJobParallelism
maxJobParallelism=xxx
指定提交的作业最多可以同时并行执行的子任务数量
newConnection
收到新连接
closeConnection
关闭连接
saveClusterNodes
修改 nodes.cfg
saveClusterNodesConfigs
修改 cluster.cfg
saveControllerConfigs
修改 controller.cfg
loadClusterNodesConfigs
读取 nodes.cfg
loadControllerConfigs
读取 controller.cfg
例子
首先配置文件设置
enableAuditLog
=true。然后通过
getAclAuditLog
查询所有 ACL
操作。
login("admin","123456")
createUser("user1","abcdec")
grant("user1",TABLE_READ,"*")
logout()
login("admin","123456")
getAclAuditLog()
返回:
userId
time
opType
opDetail
remoteIp
remotePort
guest
2025.01.02 14:26:52.738224592
newConnection
192.168.0.130
55,428
guest
2025.01.02 14:26:53.049518446
login
login userId=admin encrypted=false
192.168.0.130
55,428
admin
2025.01.02 14:26:53.059963095
createUser
userId=user1 groupIds=[] isAdmin=false
192.168.0.130
55,428
admin
2025.01.02 14:26:53.060387348
grant
userOrGroupId=user1 accessType=TABLE_READ objs=[]
192.168.0.130
55,428
guest
2025.01.02 14:26:53.060426785
logout
logout userId=admin sessionOnly=true
192.168.0.130
55,428
guest
2025.01.02 14:26:53.060576365
login
login userId=admin encrypted=false
192.168.0.130
55,428
guest
2025.01.08 09:46:49.710254224
newConnection
192.168.0.130
41,746
guest
2025.01.08 09:46:52.124830142
login
login userId=admin encrypted=false
192.168.0.130
41,746
admin
2025.01.08 09:46:52.127153771
createUser
userId=user1 groupIds=[] isAdmin=false
192.168.0.130
41,746
admin
2025.01.08 09:46:52.127752666
grant
userOrGroupId=user1 accessType=TABLE_READ objs=[]
192.168.0.130
41,746
FILE:references/doc_7645.md
# predict
**URL**: https://docs.dolphindb.cn/zh/funcs/p/predict.html
**来源**: DolphinDB 官方文档
---
predict
语法
predict(model, X)
详情
用特定的模型对数据进行预测。
参数
model
是用于预测的模型,一般是字典,由
randomForestClassifier
,
randomForestRegressor
等机器学习函数生成。
X
是用于预测的表,表的结构必须和用于训练
model
的表相同。
返回值
DOUBLE 类型向量,其长度和
X
的行数相同,每个元素对应一行的预测值。
例子
以下例子是将
randomForestRegressor
生成的模型用于预测。
x1 = rand(100.0, 100)
x2 = rand(100.0, 100)
b0 = 6
b1 = 1
b2 = -2
err = norm(0, 10, 100)
y = b0 + b1 * x1 + b2 * x2 + err
t = table(x1, x2, y)
model = randomForestRegressor(sqlDS(<select * from t>), `y, `x1`x2)
yhat = predict(model, t);
// output
[-93.733842,2.213932,5.39619,-47.817339,-38.655786,-75.772237,-45.817417,43.412841,-87.333214,-51.275368,32.41792,-45.797275,-152.075001,-83.423919,-21.154954,-65.734012,58.088571,-30.00795,-149.71085,-18.699006,-82.023643,-140.455355,-43.629218,65.832865,-79.411508,-65.625276,-17.466925,-43.469005,44.639384,31.686378...]
plot(y, yhat, ,SCATTER);
FILE:references/doc_7650.md
# getCatalogsByCluster
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getCatalogsByCluster.html
**来源**: DolphinDB 官方文档
---
getCatalogsByCluster
语法
getCatalogsByCluster(clusterName)
详情
查询指定集群所有的数据目录(catalog)。只能由管理员在 MoM(Master of Master,管理集群)上执行该函数。
返回值:
字符串向量。
参数
clusterName
字符串标量或向量,表示集群名称。
返回值
字符串向量。
例子
// MoMSender 集群:
createCatalog("catalog1")
createCatalog("catalog2")
createCatalog("catalog3")
createCatalog("catalog4")
// MoM 集群:
getCatalogsByCluster("MoMSender")
// Output: ["catalog1","catalog2","catalog3","catalog4"]
FILE:references/doc_7652.md
# varma
**URL**: https://docs.dolphindb.cn/zh/funcs/v/varma.html
**来源**: DolphinDB 官方文档
---
varma
语法
varma(ds,endogColNames,order,[exog],[trend='c'],[errorCovType='unstructured'],[measurementError=false],[enforceStationarity=true],[enforceInvertibility=true],[trendOffset=1],
[maxIter=50])
详情
使用向量自回归移动平均模型(Vector Autoregressive Moving-Average Model,简称 VARMA
模型)来分析多变量时间序列。返回一个字典,表示 VARMA 模型的分析结果,详细说明请参见“返回值”小节。
参数
ds
内存表或数据源(DATASOURCE)向量,包含需要分析的多变量时间序列,不可为空。仅当分布式表数据源的第一列为时间列时,模型会自动根据时间列对数据排序。
endogColNames
字符串向量,表示
ds
中需要分析的多变量时间序列所对应的列名。
order
非负整数型向量,长度必须为 2,第一维表示自回归部分(AR)的阶数,第二维表示移动平均部分(MA)的阶数。
exog
可选参数,数值矩阵,表示时间序列数据之外的外生变量。矩阵每一列表示一个外生变量的时间序列数据,矩阵行数为时间序列样本数,与
ds
的行数相等。
trend
可选参数,字符串标量,表示在回归中使用的常数和趋势阶数。可取值:
"c" 表示只使用常量,默认值。
"ct" 表示使用常量和趋势。
"ctt" 表示使用常数,线性趋势和二次趋势。
"n" 表示不使用常量和趋势。
errorCovType
可选参数,字符串标量,表示误差项的协方差矩阵的结构。可取值:
"unstructured" 表示会保存协方差矩阵的下三角部分,默认值。
"diagonal" 表示只保存对角线部分。
measurementError
可选参数,布尔标量,表示输入的多变量时间序列是否存在误差。默认值是 false,表示不存在。
enforceStationarity
可选参数,布尔标量,表示是否转换 AR 参数以在模型的自回归分量中增强平稳性。默认值为 true,表示转换。
enforceInvertibility
可选参数,布尔标量,表示是否变换 MA 参数以增强模型的移动平均分量的可逆性。默认值为
true,表示转换。
trendOffset
可选参数,正整数标量,表示开始时间序列值的偏移量。默认值为 1。
maxIter
可选参数,正整数标量,表示拟合时最大的迭代次数,默认值为 50。
返回值
返回一个字典,表示向量自回归移动平均模型的分析结果,字典有以下成员:
params:浮点数矩阵,表示向量自回归移动平均模型拟合得到的参数。
kAr:整数标量,表示向量自回归过程的阶数。
kMa:整数标量,表示向量移动平均部分的阶数。
kTrend:整数标量,表示向量自回归移动平均模型中的趋势数。
nobs:整数标量,表示输入的多变量时间序列的信息观测数量。
aic:浮点数标量,表示 Akaike 信息准则。
bic:浮点数标量,表示 Bayesian 信息准则。
hqic:浮点数标量,表示 Hannan-Quinn 信息准则。
llf:浮点数标量,表示向量自回归移动平均模型的对数似然值。
例子
传入指定的
macrodata.csv
文件,自定义相关参数,计算其使用 VARMA
进行分析的结果。
data = loadText("macrodata.csv")
my_exog = matrix(DOUBLE, size(data), 1,,1)
result = varma(data, [`realgdp, `realcons, `realinv],[1,1],trend="c", exog=my_exog)
print(result)
/* Output:
params->[0.001792375138657,0.003160556421415,-0.007883363910928,-0.339419264165185,0.755250482937653,0.058642159539323,-0.133526968617148,0.32767138782651,0.042514529460363,-2.212343999390979,4.610354288385349,0.302449619489419,0.056726965953926,-0.069554043921028,-0.024169855056237,0.03072738358672,-0.056571376624308,-0.015977637956917,0.249792348549773,-0.171657812582861,-0.075503097693781,0.001792375138657,0.003160556421415,-0.007883363910928,0.007685902441147,0.003916408996852,0.005142039118261,0.030338334390003,-0.016066874864259,0.020322423082551]
llf->1974.199528289279214
kAr->1
kMa->1
kTrend->1
nobs->202
aic->-3888.399056578558429
bic->-3789.151025656522506
hqic->-3848.243123697545343
*/
FILE:references/doc_7657.md
# reverse
**URL**: https://docs.dolphindb.cn/zh/funcs/r/reverse.html
**来源**: DolphinDB 官方文档
---
reverse
语法
reverse(X)
详情
将 X 中的元素反序排列。
参数
X
可以是向量、矩阵、内存表、有序字典。
返回值
若
X
为向量或矩阵,返回一个新的向量或矩阵,它和原有向量或矩阵的元素顺序相反。
若
X
为内存表,返回一个内存表,其行序与原表相反。
若
X
为有序字典,返回一个有序字典,其键值对顺序与原字典相反。
例子
reverse `hello `world;
// output
[world,hello]
(1..6).reverse();
// output
[6,5,4,3,2,1]
x=1..6$2:3;
x
#0
#1
#2
1
3
5
2
4
6
reverse(x);
#0
#1
#2
6
4
2
5
3
1
t = table(1 2 3 as a, `x`y`z as b)
reverse(t)
a
b
3
z
2
y
1
x
d = dict(1 2 3, `x`y`z, true)
reverse(d)
/*
output:
3->z
2->y
1->x
*/
FILE:references/doc_7663.md
# mprod
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mprod.html
**来源**: DolphinDB 官方文档
---
mprod
语法
mprod(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
元素的乘积。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
X = 2 1 3 7 6 5 4
Y = 2 1 3 NULL 6 5 4
mprod(X, 3);
// output: [,,6,21,126,210,120]
mprod(Y, 3);
// output: [,,6,3,18,30,120]
mprod(Y, 3, minPeriods=1);
// output: [2,2,6,3,18,30,120]
m=matrix(1 NULL 4 NULL 8 6 , 9 NULL NULL 10 NULL 2)
m.rename!(date(2020.04.06)+1..6, `col1`col2)
m.setIndexedMatrix!()
mprod(m, 3d)
label
col1
col2
2020.04.07
1
9
2020.04.08
1
9
2020.04.09
4
9
2020.04.10
4
10
2020.04.11
32
10
2020.04.12
48
20
mprod(m, 1w)
label
col1
col2
2020.04.07
1
9
2020.04.08
1
9
2020.04.09
4
9
2020.04.10
4
90
2020.04.11
32
90
2020.04.12
192
180
相关函数:
prod
FILE:references/doc_7667.md
# genShortGenomeSeq
**URL**: https://docs.dolphindb.cn/zh/funcs/g/genShortGenomeSeq.html
**来源**: DolphinDB 官方文档
---
genShortGenomeSeq
语法
genShortGenomeSeq(X, window)
别名:
genSGS
详情
对给定长度(以字符个数衡量)的滑动窗口内的 DNA 序列进行编码,不忽略空值。
注:
该函数使用向后的窗口,即从当前元素开始向后选取元素。
若
window
大于
X
中所有字符的个数,则返回一个空的整型向量。
参数
X
STRING 类型标量或 CHAR 类型的向量。
window
正整数,范围为[2,28]。
返回值
返回一个整型向量,其长度与
X
包含的字符个数相同。具体如下:
window 范围
返回值类型
[2,4]
短整型向量(FAST SHORT VECTOR)
[5,12]
整型向量(FAST INT VECTOR)
[13,28]
返回长整型向量(FAST LONG VECTOR)
例子
genShortGenomeSeq("NNNNNNNNTCGGGGCAT",3)
// output
[,,,,,,,,795,815,831,831,830,824,801,,]
genShortGenomeSeq("TCGGGGCATNGCCCG",4)
// output
[1135,1215,1279,1278,1272,1249,,,,,1258,1195,,,]
genShortGenomeSeq("GCCCGATNNNNN",6)
// output
[396972,395953,,,,,,,,,,]
genShortGenomeSeq("TCGATCGTCGATCGTCGATCGTCGATCGG",5)
// output
[328113,328390,328475,327789,328118,328411,328556,328113,328390,328475,327789,328118,328411,328556,328113,328390,328475,327789,328118,328411,328556,328113,328390,328475,327791,,,,]
genShortGenomeSeq("ACTT",8)
// output
[,,,]
相关函数:
encodeShortGenomeSeq
,
decodeShortGenomeSeq
FILE:references/doc_767.md
# transFreq
**URL**: https://docs.dolphindb.cn/zh/funcs/t/transFreq.html
**来源**: DolphinDB 官方文档
---
transFreq
语法
transFreq(X, rule, [closed], [label],
[origin='start_day'])
详情
将给定日期或时间变量转换为给定的时间格式(或对应的交易日)。结果长度与
X
相同。
参数
X
是表示日期或时间类型的标量或向量。
rule
是一个字符串,可取以下值:
rule 参数取值
对应 DolphinDB 函数
"B"
businessDay
"W"
weekEnd
"WOM"
weekOfMonth
"LWOM"
lastWeekOfMonth
"M"
monthEnd
"MS"
monthBegin
"BM"
businessMonthEnd
"BMS"
businessMonthBegin
"SM"
semiMonthEnd
"SMS"
semiMonthBegin
"Q"
quarterEnd
"QS"
quarterBegin
"BQ"
businessQuarterEnd
"BQS"
businessQuarterBegin
"A"
yearEnd
"AS"
yearBegin
"BA"
businessYearEnd
"BAS"
businessYearBegin
"D"
date
"H"
hourOfDay
"min"
minuteOfHour
"S"
secondOfMinute
"L"
millisecond
"U"
microsecond
"N"
nanosecond
"SA"
semiannualEnd
"SAS"
semiannualBegin
上述字符串亦可配合使用数字(必须为正整数),例如 "2M" 表示频率为每两个月月末。此外,
rule
也可以是交易日历标识(国外交易所的 ISO
Code、国内交易所简称或自定义交易日历名称),以便基于交易日历进行计算。交易日历也可以配合使用数字,表示多个交易日,此时只能指定由4个大写字母组成的交易日历标识。例如:“2XSHG”,表示上海证券交易所每两个交易日。
closed
字符串,表示分组区间哪一个边界是闭合的。
rule
为 'M', 'A', 'Q', 'BM', 'BA', 'BQ' 和 'W'
时,
closed
的默认取值为 'right' ,否则,
closed
的默认取值为 'left'。
origin
取 'end' 或者 'end_day' 时,
closed
的默认值为 'right'。
label
字符串,表示将分组区间的哪一个边界作为
label
输出。
rule
为 'M', 'A', 'Q', 'BM', 'BA', 'BQ' 和 'W'
时,
label
的默认取值为 'right' ,否则,
label
的默认取值为 'left'。
origin
取 'end' 或者 'end_day' 时,
label
的默认值为 'right'。
origin
字符串或和
X
具有相同时间类型的标量,表示基于时间戳调整分组。取值为 'epoch',
start', 'start_day', 'end', 'end_day' 或自定义的时间对象,默认值为 'start_day'。
'epoch':分组起始点为1970-01-01。
'start':分组起始点为时间序列的第一个值。
'start_day':分组起始点是时间序列的第一个值对应日期的午夜零点。
'end':分组起始点是时间序列的最后一个时间戳。
'end_day':分组起始点是时间序列的最后一个时间戳对应日期的午夜24点(即下一日的零点)。
返回值
时间类型标量或向量,其数据类型与形式同
X
。
例子
transFreq(2020.11.08 2020.11.09 2020.11.18, "SM");
// output
[2020.10.31,2020.10.31,2020.11.15]
transFreq(2020.08.08 2020.11.18, "Q");
// output
[2020.09.30,2020.12.31]
transFreq(2020.08.08 2020.11.18, "2Q");
// output
[2020.09.30,2021.03.31]
s = temporalAdd(2022.01.01 00:00:00,1..8,`m);
s.transFreq(rule="3min");
// output
[2022.01.01T00:00:00,2022.01.01T00:00:00,2022.01.01T00:03:00,2022.01.01T00:03:00,2022.01.01T00:03:00,2022.01.01T00:06:00,2022.01.01T00:06:00,2022.01.01T00:06:00]
s.transFreq(rule=`3min,closed=`right);
// output
[2022.01.01T00:00:00,2022.01.01T00:00:00,2022.01.01T00:00:00,2022.01.01T00:03:00,2022.01.01T00:03:00,2022.01.01T00:03:00,2022.01.01T00:06:00,2022.01.01T00:06:00]
s.transFreq(rule=`3min,closed=`right,origin=`end);
// output
[2021.12.31T23:59:00,2021.12.31T23:59:00,2022.01.01T00:02:00,2022.01.01T00:02:00,2022.01.01T00:02:00,2022.01.01T00:05:00,2022.01.01T00:05:00,2022.01.01T00:05:00]
FILE:references/doc_7671.md
# rtrim
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rtrim.html
**来源**: DolphinDB 官方文档
---
rtrim
语法
rtrim(X)
详情
删除字符串或字符串向量的每个元素右边的空格。
参数
X
是一个字符串或字符串向量。
返回值
一个字符串或字符串向量。
例子
rtrim("I love ")+" "+ltrim(" this game!");
// output
I love this game!
FILE:references/doc_7675.md
# sumbars
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sumbars.html
**来源**: DolphinDB 官方文档
---
sumbars
语法
sumbars(X, Y)
详情
对
X
中每个元素,计算其向前累加直到不小于指定值
Y
时经过的周期数。若
X
向前的所有元素累加后的值仍不能大于等于
Y
,则返回0。
参数
X
向量/矩阵/元组/表。其元素必须为非负数。
Y
标量,表示累加和的阈值。
返回值
返回 INT 类型向量或矩阵。
例子
sumbars(1 2 3.3 2 5, 3)
// output
[0,2,1,2,1]
sumbars(matrix(5 3 6 2 3, 2 6 1 5 4), 5)
col1
col2
1
0
2
1
1
2
2
1
2
2
# 求完全换手到现在的周期数。
# calculate the turnover period
id = `A`A`B`A`C`B`A`C`A`B
time = 2022.01.01T09:00:00 + 0..9
volume = 100 150 80 120 220 200 180 90 100 125
t = table(id, time, volume)
capital = 300
re = select *, sumbars(volume, capital) as period from t
re;
id
time
volume
period
A
2022.01.01T09:00:00
100
0
A
2022.01.01T09:00:01
150
0
B
2022.01.01T09:00:02
80
3
A
2022.01.01T09:00:03
120
3
C
2022.01.01T09:00:04
220
2
B
2022.01.01T09:00:05
200
2
A
2022.01.01T09:00:06
180
2
C
2022.01.01T09:00:07
90
3
A
2022.01.01T09:00:08
100
3
B
2022.01.01T09:00:09
125
3
FILE:references/doc_7688.md
# dropMCPPrompt
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropMCPPrompt.html
**来源**: DolphinDB 官方文档
---
dropMCPPrompt
语法
dropMCPPrompt(name)
详情
删除一个 MCP prompt 模板。如果该模板已被发布,需要先调用
withdrawMCPPrompts
撤销发布后才能删除。
参数
name
STRING 类型标量,表示 prompt 模板的名称。
返回值
一个字符串,表示删除 MCP prompt 模板的名称。
例子
dropMCPPrompt("stock_summary")
// output:'stock_summary'
FILE:references/doc_7691.md
# secondOfMinute
**URL**: https://docs.dolphindb.cn/zh/funcs/s/secondOfMinute.html
**来源**: DolphinDB 官方文档
---
secondOfMinute
语法
secondOfMinute(X)
详情
返回
X
中的秒数。
参数
X
可以是 TIME、SECOND、DATETIME、TIMESTAMP、NANOTIME 或
NANOTIMESTAMP 类型的标量或向量。
返回值
INT 类型标量或向量。
例子
secondOfMinute(12:32:00);
// output
0
secondOfMinute([2012.06.12T12:30:00,2012.10.28T12:35:00,2013.01.06T12:36:47,2013.04.06T08:02:14]);
// output
[0,0,47,14]
相关函数:
dayOfYear
,
dayOfMonth
,
quarterOfYear
,
monthOfYear
,
weekOfYear
,
hourOfDay
,
minuteOfHour
,
millisecond
,
microsecond
,
nanosecond
FILE:references/doc_7703.md
# getInstrumentMaturity
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentmaturity.html
**来源**: DolphinDB 官方文档
---
getInstrumentMaturity
语法
getInstrumentMaturity(instrument)
详情
根据输入的金融工具,获取该工具的到期日(Maturity Date)。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DATE 类型标量或向量。
例子
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "ZeroCouponBond",
"version": 0,
"instrumentId": "0001",
"start": 1996.03.01,
"maturity": 2032.05.15,
"dayCountConvention": "ActualActualISDA",
"coupon": 0.0276,
"issuePrice": 100.0,
"frequency": "Semiannual",
"subType":"TREASURY_BOND",
"creditRating":"B",
"settlement": 2022.05.15
}
ins = parseInstrument(bond)
getInstrumentMaturity(ins)
// output: 2032.05.15
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_7711.md
# purgeCacheEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/p/purgeCacheEngine.html
**来源**: DolphinDB 官方文档
---
purgeCacheEngine
是
flushOLAPCache
的别名。
FILE:references/doc_7715.md
# segment
**URL**: https://docs.dolphindb.cn/zh/funcs/s/segment.html
**来源**: DolphinDB 官方文档
---
segment
语法
segment(X, [segmentOffset=true])
详情
将向量分组,连续的相同元素为一组。
如果
segmentOffset
为 true,返回的结果是每组第一个元素在
X
中的下标。
如果
segmentOffset
为 false,返回的结果表示每个元素位于第几组。组号从0开始编号。
参数
X
是一个向量。
segmentOffset
是一个布尔值。默认值为 true。
返回值
INT 类型,长度与 X 相等的向量。
例子
x = 1 1 2 4 4 5 2 5 NULL NULL
segment(x);
// output
[0,0,2,3,3,5,6,7,8,8]
segment(x, false);
// output
[0,0,1,2,2,3,4,5,6,6]
x = 1 2 1 2 1 2 1 2 1 2 1 2;
y = 0 0 1 1 1 2 2 1 1 3 3 2;
t = table(x,y);
select *, cumsum(x) from t context by segment(y);
y
x
cumsum_x
0
1
1
0
2
3
1
1
1
1
2
3
1
1
4
2
2
2
2
1
3
1
2
2
1
1
3
3
2
2
3
1
3
2
2
2
FILE:references/doc_7716.md
# stateIterate
**URL**: https://docs.dolphindb.cn/zh/funcs/s/stateIterate.html
**来源**: DolphinDB 官方文档
---
stateIterate
语法
stateIterate(X, initial, initialWindow, iterateFunc,
combineCoeff)
该函数只能用作响应式状态引擎
metrics
中的函数。
详情
通过线性迭代实现线性递归。
假设该函数计算结果对应输出表的列为 factor,且迭代仅基于前一个值,对于第 k 条记录(k = 0, 1, 2 …),其计算逻辑为:
k <
initialWindow
:factor[k] = initial[k]
k >=
initialWindow
:factor[k] = combineCoeff[0] *
X[k] + combineCoeff[1] * iterateFunc(factor)[k-1]。
注意:若
iterateFunc
为窗口函数,则会基于前多个 factor 值进行计算。
参数
X
输入表中的字段或其应用向量函数的计算结果。
initial
数据形式同
X
,作为
initialWindow
内数据的输出结果。
initialWindow
正整数,表示初始化窗口的长度。其确定的窗口范围为[0, initialWindow)。
iterateFunc
用于迭代计算的函数。必须是一个单目函数,其唯一参数是
stateIterate
对应输出表中的字段。目前只支持以下函数(非单目函数以部分应用形式给出其他参数):
滑动窗口函数:
tmove
,
tmavg
,
tmmax
,
tmmin
,
tmsum
,
mavg
,
mmax
,
mmin
,
mcount
,
msum
累计窗口函数:
cumlastNot
,
cumfirstNot
序列相关函数:
ffill
,
move
注:
由于迭代是基于历史数据进行的,因此当前记录的输出是基于输出表中的历史结果和
X
计算得到的。
tm 系列函数计算时,时间窗口由当前记录的时间戳确定。且计算窗口范围为 (T - window, T)。
combineCoeff
长度为 2 的向量,作为
iterateFunc
迭代结果和
X
的关联系数。
例子
trade = table(take("A", 6) join take("B", 6) as sym, 1..12 as val0, take(10, 12) as val1)
trade;
sym
val0
val1
A
1
10
A
2
10
A
3
10
A
4
10
A
5
10
A
6
10
B
7
10
B
8
10
B
9
10
B
10
10
B
11
10
B
12
10
定义一个响应式状态引擎,并按 sym 列分组进行计算。组内的计算逻辑如下:
前
initialWindow
行记录,计算公式为 factor[k]=initial[k],因此
factor[0], factor[1], factor[2] 均将 val1 列的值直接作为 factor 列的输出。
之后的记录,对应计算公式为 factor[k]=0.5*val0[k]+0.5*msum(factor,
3)[k-1]。以计算 sym=`A,val0=4 这条记录为例,此时 factor 列仅有前 3 条数据的输出,即 factor=[10, 10,
10],k=3,带入计算公式即 0.5*4+0.5*msum([10, 10, 10], 3)[2]=17。同理 sym=`A,val0=5
这条记录带入计算公式即 0.5*5+0.5*msum([10, 10, 10, 17], 3)[3]=21,以此类推。
inputTable = streamTable(1:0, `sym`val0`val1, [SYMBOL, INT, INT])
outputTable = table(100:0, `sym`factor, [STRING, DOUBLE])
engine = createReactiveStateEngine(name="rsTest", metrics=<[stateIterate(val0, val1, 3, msum{, 3}, [0.5, 0.5])]>, dummyTable=inputTable, outputTable=outputTable, keyColumn=["sym"], keepOrder=true)
engine.append!(trade)
select * from outputTable
sym
factor
A
10
A
10
A
10
A
17
A
21
A
27
B
10
B
10
B
10
B
20
B
25.5
B
33.75
相关函数:
conditionalIterate
FILE:references/doc_7720.md
# listPluginsByCluster
**URL**: https://docs.dolphindb.cn/zh/funcs/l/listPluginsByCluster.html
**来源**: DolphinDB 官方文档
---
listPluginsByCluster
语法
listPluginsByCluster(clusterName)
详情
获取集群中每个节点上插件的安装情况。
参数
clusterName
字符串标量,表示要查询的集群名称。只能由管理员在 MoM(Master of Master,管理集群)上执行该函数。
返回值
一张表,包含以下字段:
plugin:插件名称。
version:插件版本。
user:安装该插件的用户名称。
time:插件安装时间,单位为毫秒。
node:插件安装所在的节点名称。
例子
// MoMSender 集群节点:
installPlugin("mysql")
loadPlugin("mysql")
// MoM 集群:
listPluginsByCluster("MoMSender")
plugin
version
user
time
node
mysql
3.00.3
admin
2025.05.24T17:10:42.300
dnode1
zip
3.00.3
admin
2025.05.24T17:10:42.285
dnode1
mysql
3.00.1.3
admin
2025.05.24T17:10:49.135
controller8899
zip
3.00.3
admin
2025.05.24T17:10:49.120
controller8899
FILE:references/doc_7723.md
# and
**URL**: https://docs.dolphindb.cn/zh/funcs/a/and.html
**来源**: DolphinDB 官方文档
---
and
语法
and(X, Y)
或
X && Y
详情
对
X
和
Y
内的元素逐个进行逻辑与(logical AND)的运算并返回结果。
参数
X
和
Y
可以是标量、数据对、向量或矩阵。
返回值
数据类型为布尔类型。
若
X
和
Y
至少一个是矩阵,则返回矩阵;否则,若至少一个是数据对,则返回数据对;否则,若至少有一个是向量,则返回向量;若
X
和
Y
均为标量,则返回标量。
例子
1 && 3;
// output
1
x=1 2 3
x && 0
// output
[0,0,0]
x=1 2 3
y=0 1 0
x && y
// output
[0,1,0]
t=table(1 2 2 3 as id, 4 5 6 5 as value)
t
id
value
1
4
2
5
2
6
3
5
select id, value from t where id=2 and value=5; // SQL query
id
value
2
5
相关函数:
or
,
not
FILE:references/doc_7739.md
# 数据迁移方法
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db_oper/import_data.html
**来源**: DolphinDB 官方文档
---
数据迁移方法
从外部数据源向向 DolphinDB 迁移时,可采取如下方法:
通过文本文件导入
通过 HDF5 插件导入
通过 ODBC 插件导入
通过 MySQL 插件导入
其中,HDF5, ODBC 与 MySQL 插件均可从 DolphinDB 官网下载。以下简介这四种导入方法:
文本文件
通过文本文件进行数据中转是较为通用的一种数据迁移方式。DolphinDB 提供了以下三个函数来加载文本文件:
loadText
:把文本文件加载到内存中
ploadText
:以并行的方式把文本文件加载到内存中,它的速度比
loadText
要快
loadTextEx
:把文本文件导入到 DolphinDB 数据库中
导入内存
使用
loadText
或
ploadText
函数时,需要先把数据加载到内存,然后再落盘到数据库。如果文本文件过大,可能会出现内存不足。因此这两个函数不能用于导入大于本地机器内存的文本文件。
若要把数据导入到数据库中,
loadText
和
ploadText
需要与
append!
和
tableInsert
函数一起使用。
t = ploadText("/stockData/trades.csv")
db=database("dfs://stock",VALUE,2019.08.01..2019.08.10)
pt=db.createPartitionedTable(t,`pt,`timestamp)
pt.append!(t)
在下例中,原始数据是 2018 年 5 月至今的股票报价数据,每天一个
CSV 文件,保存在文件夹
/stockData
下。按照下面的步骤,创建一个数据库并把数据导入。
创建组合分区类型(COMPO)的分布式数据库
dfs://stockDB
,根据日期进行值分区,根据股票代码进行范围分区。由于后续的数据都会导入到数据库,所以在创建数据库时我们扩大了日期的分区方案。
t = ploadText("/stockData/TAQ20180501.csv")
tmp = select count(*) as count from t group by sym order by sym;
buckets = cutPoints(tmp.sym, 128, tmp.count)
dateDomain = database("", VALUE, 2018.05.01..2030.07.01)
symDomain = database("", RANGE, buckets)
stockDB = database("dfs://stockDB", COMPO, [dateDomain, symDomain])
stockDB.createPartitionedTable(t, "quotes", `date`sym)
导入数据库
loadTextEx
可以避免文本文件过大时可能出现内存不足的问题。该函数将文本文件分为许多批次逐步载入内存并落盘到数据库,因可以导入超出本地机器内存的文本文件。
例如:
直接使用:
db=database("dfs://stock",VALUE,2019.08.01..2019.08.10)
loadTextEx(db,`pt,`timestamp,"/stockData/trades.csv")
利用
loadTextEx
函数,编写用户自定义函数 loadCsv
把文件文件加载到数据库:
def loadCsv(){
fileDir='/stockData'
filenames = exec filename from files(fileDir)
db = database("dfs://stockDB")
for(fname in filenames){
jobId = fname.strReplace(".csv", "")
submitJob(jobId, , loadTextEx{db, "quotes", `date`sym, fileDir+'/'+fname})
}
}
loadCsv()
HDF5 插件
HDF5 是一种在数据分析领域广泛使用的二进制数据文件格式。用户可通过 DolphinDB HDF5 插件提供的以下方法导入
HDF5 格式数据文件:
hdf5::ls:列出HDF5文件中所有 group 和 dataset 对象
hdf5::lsTable:列出HDF5文件中所有 dataset 对象
hdf5::HDF5DS:返回HDF5文件中 dataset 的元数据
hdf5::loadHDF5:将HDF5文件导入内存表
hdf5::loadHDF5Ex:将HDF5文件导入分区表
hdf5::extractHDF5Schema:从HDF5文件中提取表结构
用法如下:
下载HDF5 插件,再将插件部署到
/server/plugins
目录下。使用以下脚本加载插件:
loadPlugin("plugins/hdf5/PluginHdf5.txt")
调用插件方法时需要在方法前面提供namespace,比如调用loadHdf5可以使用hdf5::loadHDF5。另一种写法是:
use hdf5
loadHdf5(filePath,tableName)
若要导入包含一个Dataset candle_201801的文件candle_201801.h5,可使用以下脚本:
dataFilePath = "/home/data/candle_201801.h5"
datasetName = "candle_201801"
tmpTB = hdf5::loadHDF5(dataFilePath,datasetName)
如果需要指定数据类型导入可以使用hdf5::extractHDF5Schema,脚本如下:
dataFilePath = "/home/data/candle_201801.h5"
datasetName = "candle_201801"
schema=hdf5::extractHDF5Schema(dataFilePath,datasetName)
update schema set type=`LONG where name=`volume
tt=hdf5::loadHDF5(dataFilePath,datasetName,schema)
如果HDF5文件超过服务器内存,可以使用hdf5::loadHDF5Ex载入数据。
dataFilePath = "/home/data/candle_201801.h5"
datasetName = "candle_201801"
dfsPath = "dfs://dataImportHDF5DB"
db=database(dfsPath,VALUE,2018.01.01..2018.01.31)
hdf5::loadHDF5Ex(db, "cycle", "tradingDay", dataFilePath,datasetName)
更多关于 HDF5 插件的内容,参考:
HDF5 插件
。
ODBC 插件
用户可通过 ODBC 插件提供的接口连接第三方数据库后迁移数据至 DolphinDB。
ODBC 插件提供了以下四个方法用于操作第三方数据源数据:
odbc::connect:创建连接。
odbc::close: 关闭连接。
odbc::query:根据给定的SQL语句查询数据并将结果返回到DolphinDB的内存表。
odbc::execute:在第三方数据库内执行给定的SQL语句,不返回结果。
在使用ODBC 插件之前,需要安装ODBC驱动程序。
下面的例子使用ODBC 插件连接以下SQL Server:
IP地址:172.18.0.15
连接用户名:sa
密码:123456
数据库名称: SZ_TAQ
下载插件解压并拷贝 plugins/odbc 目录下所有文件到 DolphinDB server/plugins/odbc
目录下,通过下面的脚本完成插件初始化:
loadPlugin("plugins/odbc/odbc.cfg")
conn=odbc::connect("Driver=ODBC Driver 17 for SQL Server;Server=172.18.0.15;Database=SZ_TAQ;Uid=sa;Pwd=123456;")
创建 DolphinDB 分布式数据库dfs://dataImportODBC。使用SQL
Server中的数据表结构作为DolphinDB数据表的模板,在dfs://dataImportODBC中创建数据库cycle。
tb = odbc::query(conn,"select top 1 * from candle_201801")
db=database("dfs://dataImportODBC",VALUE,2018.01.01..2018.01.31)
db.createPartitionedTable(tb, "cycle", "tradingDay")
从SQL Server中导入数据并保存入cycle表中:
tb = database("dfs://dataImportODBC").loadTable("cycle")
data = odbc::query(conn,"select * from candle_201801")
tb.append!(data);
更多关于 ODBC 插件的内容,参考:
ODBC 插件
。
MySQL 插件
MySQL 插件导入数据的速度比ODBC接口要快,并且不需要配置数据源,使用更加便捷。
MySQL插件提供了以下接口函数:
mysql::connect:创建连接
mysql::showTables:列出MySQL数据库中的所有表
mysql::extractSchema:获取MySQL数据表的结构
mysql::load:把MySQL数据加载到DolphinDB的内存表
mysql::loadEx:把MySQL中的数据加载到DolphinDB的分区表
下载插件解压并拷贝 plugins\mysql 目录下所有文件到DolphinDB server的 plugins/mysql
目录下,通过下面的脚本完成插件初始化:
loadPlugin("plugins/PluginMySQL.txt")
连接本地MySQL服务器中的employees数据库:
conn=connect("127.0.0.1",3306,"root","123456","employees")
确定分区类型和分区方案,创建数据库,用于保存MySQL数据:
db=database("dfs://mysql",VALUE,`F`M)
导入数据:
pt=loadEx(conn,db,"pt","gender","employees")
更多关于 MySQL 插件的内容,参考:
MySQL
插件
。
FILE:references/doc_7760.md
# cummin
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cummin.html
**来源**: DolphinDB 官方文档
---
cummin
语法
cummin(X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累计最小值。
返回值
返回一个与输入
X
相同数据类型和形式的对象。
例子
x = [7,4,5,NULL,9]
cummin(x);
// output
[7,4,4,4,4]
m = matrix(6 5 7 8 1, 3 9 4 2 10);
m;
#0
#1
6
3
5
9
7
4
8
2
1
10
cummin(m);
#0
#1
6
3
5
3
5
3
5
2
1
2
相关函数:
cummax
,
min
FILE:references/doc_7768.md
# contextCount
**URL**: https://docs.dolphindb.cn/zh/funcs/c/contextCount.html
**来源**: DolphinDB 官方文档
---
contextCount
语法
contextCount(X, Y)
详情
计算
X
和
Y
中相同位置都不为 NULL 的元素个数。
参数
X
和
Y
必须是相同长度的向量。
返回值
INT 类型标量。
例子
contextCount(1 2 3, 1 NULL 3)
// output
2
contextCount(1..3,true false true)
// output
3
contextCount(1 2 NULL, 1 NULL 3)
// output
1
相关函数:
contextSum
,
contextSum2
FILE:references/doc_7769.md
# mmin
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mmin.html
**来源**: DolphinDB 官方文档
---
mmin
语法
mmin(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
输入为向量时,返回一个与输入等长的向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
元素的最小值。
例子
X = 2 1 3 7 6 5 4
Y = 2 1 3 NULL 6 5 4
mmin(X, 3);
// output
[,,1,1,3,5,4]
mmin(Y, 3);
// output
[,,1,1,3,5,4]
mmin(Y, 3, minPeriods=1);
// output
[2,1,1,1,3,5,4]
m = matrix(1 5 9 0 2 8 -1 5, 9 10 2 NULL -1 10 2 3)
m.rename!(date(2020.09.10)+1..8, `A`B)
m.setIndexedMatrix!()
m.mmin(3d)
label
col1
col2
2020.09.11
1
9
2020.09.12
1
9
2020.09.13
1
2
2020.09.14
0
2
2020.09.15
0
(1)
2020.09.16
0
(1)
2020.09.17
(1)
(1)
2020.09.18
(1)
2
m.mmin(1w)
label
col1
col2
2020.09.11
1
9
2020.09.12
1
9
2020.09.13
1
2
2020.09.14
0
2
2020.09.15
0
(1)
2020.09.16
0
(1)
2020.09.17
(1)
(1)
2020.09.18
(1)
(1)
相关函数:
min
FILE:references/doc_7777.md
# getComputeNodeCacheDetails
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getComputeNodeCacheDetails.html
**来源**: DolphinDB 官方文档
---
getComputeNodeCacheDetails
语法
getComputeNodeCacheDetails(granularity)
详情
在存算分离架构中,在计算组中的计算节点上执行该函数,可返回该节点上的具体缓存信息。
区别于
getComputeNodeCacheStat
用于查询当前节点的缓存总使用量和缓存上限;
getComputeNodeCacheDetails
可查询缓存的具体构成。
用户指定以表或分区为单位,查询对应数据在该节点上的缓存类型、缓存大小等。
关于存算分离架构的详细介绍与相关配置,请参见
存算分离
主题页。
参数
granularity
字符串标量,表示查询的粒度:
"CHUNK": 以分区为单位查询缓存信息。
"TABLE":以表为单位查询信息。若存在大量分区,可选择该项以控制返回表行数。
返回值
当以分区为单位(
granularity
="CHUNK")查询时,返回一张包含以下字段的表:
dbName - 库名
tableName - 表名
dfsPath - 分区的 DFS 路径
cid - 当前缓存对应的的版本标识
cacheType - 缓存类型,"MEM" 表示位于内存,"DISK" 表示位于磁盘。若存在于两处,则会显示两行
size - 以字节为单位的缓存大小,与缓存类型对应
当以表为单位(
granularity
="TABLE")查询时,每个分区表对应一条记录,包括
dbName、tableName、partitionCount、cacheType 和 size 字段。其中 partitionCount
表示该表中被缓存的分区数。
例子
getComputeNodeCacheDetails("CHUNK");
dbName
tableName
dfsPath
cid
cacheType
size
dfs://demo
pt1
/demo/43/G6
509
MEM
222
dfs://demo
pt1
/demo/15/G6
509
MEM
184
dfs://test01
pt01
/test01/1/8c
515
MEM
280
…
getComputeNodeCacheDetails("TABLE");
dbName
tableName
partitionCount
cacheType
size
dfs://demo
pt1
27
MEM
5804
相关函数:
clearComputeNodeCache
,
clearComputeNodeDiskCache
,
getComputeNodeCacheStat
FILE:references/doc_7780.md
# coalesce
**URL**: https://docs.dolphindb.cn/zh/progr/sql/coalesce.html
**来源**: DolphinDB 官方文档
---
coalesce
语法
coalesce(X1, X2, args...)
参数
X1
标量或向量。
X2
与
X1
类型相同的标量/向量。若
X1
为标量,
X2
只能为标量;若
X1
为向量,
X2
可以为非空的标量,也可以为与
X1
等长的向量。
args
可选参数,参数说明同
X2
。
详情
根据给定的数据,填充原始数据中的空值,返回一个和原始数据等长的标量/向量。
注:
支持在分布式查询中使用。
逐一检查 X1 中的元素:
若非空,则直接返回。
若为空,则检查 X2 中相同位置的元素是否为空;若为空,则按照相同的规则检查后续 args
中相同位置的元素是否为空,直到找到第一个非空值并返回,若找不到则返回空。
使用场景
将表的多列合并为一列。
替代复杂的
case
表达式:
select
coalesce (expr1, expr2, 1) from t
等效于
select case
when vol1 is not null then vol1 when vol2 is not null then vol2 else
1 end from t
例子
coalesce(int(NULL), int(NULL), 1, 3)
1
coalesce(-1 NULL 4 3, NULL 2 NULL 1, 1 4 5 2)
[-1,2,4,3]
vol1 = [3.3, 2.2, 2.1, NULL, 1.2]
vol2 = [NULL, 1.8, 1.9, 2.3, 3.2]
sym = `a`a`b`a`c
t = table(sym, vol1, vol2)
select sym, coalesce(vol1, vol2) as vol from t
sym
vol
a
3.3
a
2.2
b
2.1
a
2.3
c
1.2
FILE:references/doc_7782.md
# contextSum2
**URL**: https://docs.dolphindb.cn/zh/funcs/c/contextSum2.html
**来源**: DolphinDB 官方文档
---
contextSum2
语法
contextSum2(X, Y)
详情
找出
X
和
Y
中元素都不为 NULL 的位置,并计算
X
中这些位置对应的元素的平方和。
即使
X
的数据类型是 INT 或 LONG,返回结果的数据类型总是 DOUBLE 类型。
参数
X
和
Y
是向量、矩阵或表。
返回值
DOUBLE 类型标量/向量/表。
例子
contextSum2(1 2 3, 10 NULL 30);
// output
10
contextSum2(1 2 3, true false true);
// output
14
相关函数:
contextCount
,
contextSum
FILE:references/doc_7784.md
# isAlNum
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isAlNum.html
**来源**: DolphinDB 官方文档
---
isAlNum
语法
isAlNum(X)
详情
判断
X
是否只包含字母或数字。如果
X
中的所有字符都是字母和数字,该函数返回 true,反之返回
false。对于空字符串(STRING类型的NULL值),该函数返回 false。
当
X
是表时,函数仅作用于其中 CHAR、STRING、SYMBOL 列,其他类型的列将被忽略。
参数
X
是字符/字符串/SYMBOL 类型的标量、向量,或表。
返回值
当
X
是标量时,返回布尔标量。
当
X
是向量时,返回布尔向量。
当
X
是表时,返回一个表。
例子
isAlNum("123456");
// output: true
isAlNum("1And1");
// output: true
isAlNum("10.05");
// output: false
isAlNum(string());
// output: false
FILE:references/doc_7787.md
# getInstrumentStart
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentstart.html
**来源**: DolphinDB 官方文档
---
getInstrumentStart
语法
getInstrumentStart(instrument)
详情
根据输入的金融工具,获取该工具的起始日(Start Date)。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DATE 类型标量或向量。
例子
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "ZeroCouponBond",
"version": 0,
"instrumentId": "0001",
"start": 1996.03.01,
"maturity": 2032.05.15,
"dayCountConvention": "ActualActualISDA",
"coupon": 0.0276,
"issuePrice": 100.0,
"frequency": "Semiannual",
"subType":"TREASURY_BOND",
"creditRating":"B",
"settlement": 2022.05.15
}
ins = parseInstrument(bond)
getInstrumentStart(ins)
// output: 1996.03.01
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_7793.md
# loadBackup
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadBackup.html
**来源**: DolphinDB 官方文档
---
loadBackup
语法
loadBackup(backupDir, dbPath, partition, tableName)
详情
加载指定分布式表中某个分区的备份数据。该函数必须要用户登录后才能执行。
请注意,目前该函数只支持加载 SQL 元代码(即
backup
时指定
sqlObj
参数)备份的数据。
参数
backupDir
是字符串,表示存放备份数据的目录。
dbPath
是字符串,表示 DFS 数据库的路径,例如
"dfs://demo"
。
partition
是字符串,表示分区在数据库内的路径,例如
"/20190101/GOOG"
。
注:
若使用 2.00.4 到 2.00.6 版本
server,对表级分区数据进行备份和恢复时,该参数必须指定路径到物理索引(可通过函数
listTables
获取),例如分区
"/compoDB/20170807/0_50"
下表的物理索引为8,则
partition
需指定为
"/compoDB/20170807/0_50/8"
。
tableName
是字符串,表示分布式表的名称。
返回值
一张表。
例子
loadBackup("/home/DolphinDB/backup","dfs://valuedb", "/200001M","pt");
输出返回:
month
x
2000.01M
1
2000.01M
205
2000.01M
409
2000.01M
613
2000.01M
817
FILE:references/doc_7794.md
# streamEngineParser
**URL**: https://docs.dolphindb.cn/zh/funcs/s/streamEngineParser.html
**来源**: DolphinDB 官方文档
---
streamEngineParser
语法
streamEngineParser(name, metrics, dummyTable, outputTable, keyColumn,
[timeColumn], [useSystemTime=false], [snapshotDir],
[snapshotIntervalInMsgCount], [raftGroup], [filter], [keepOrder],
[keyPurgeFilter], [keyPurgeFreqInSecond], [triggeringPattern='perBatch'],
[triggeringInterval=1000], [lastBatchOnly=false], [contextByColumn],
[updateTime], [useWindowStartTime=false], [roundTime=true], [forceTriggerTime],
[sessionBegin], [sessionEnd], [mergeSessionEnd=false], [closed='left'],
[fill='none'], [garbageSize], [forceTriggerSessionEndTime],
[keyPurgeFreqInSec=-1])
详情
在实际场景下,用户的因子可能嵌套横截面、历史状态、时序窗口、表连接等多种复杂逻辑,需要多个计算引擎的级联才能实现。
streamEngineParser
为只涉及横截面、历史状态、时序窗口三种逻辑嵌套的复杂因子,提供了一个统一的计算入口。用户无需编写复杂的级联代码,只需将嵌套因子按规则改写后传入
streamEngineParser
,系统将自动解析各层嵌套涉及的计算逻辑,形成流计算引擎流水线,自动分发给对应的引擎进行计算。
为满足各逻辑对应引擎的功能,该函数集合了(日级)时序引擎、响应式状态引擎和横截面引擎的参数。需要注意的是,由于部分为公共参数(如
keyColumn
),若公共参数在不同计算逻辑下需要指定的值不同(如时序窗口按天分组,状态逻辑要求按股票代码分组,则需要配置不同的
keyColumn
),不能使用该函数,只能通过级联实现。
根据上文,若要使用
streamEngineParser
,必须根据业务场景提供的指标,分析业务中涉及的流计算引擎,将指标改写成
streamEngineParser
能够识别分解的
metrics
。若
metrics
中包含了用户自定义函数,引擎对函数体内部的嵌套逻辑进一步进行解析。
改写规则如下:
引擎分解标识
若指标中的某一层嵌套逻辑要求计算截面数据,需将对应的计算函数改成以 “row开头”
的函数作为标识,若不添加 row 则该操作默认在响应式状态引擎处理。如:需要在截面计算排名,则需要将该层嵌套改写为
rowRank
。
目前支持的标识函数如下:
"byRow", "rowAvg", "rowCount", "count", "rowDenseRank", "rowMax", "rowMin", "rowProd", "rowRank",
"rowSize", "rowSkew", "rowStd", "rowStdp", "rowSum", "rowSum2", "rowVar", "rowVarp",
"rowAnd", "rowOr", "rowXor", "rowKurtosis", "rowCorr", "rowCovar", "rowBeta", "rowWsum", "rowWavg"
用户自定义函数或者 row 系列函数不支持的逻辑可以通过
byRow
高阶函数实现。
若指标中的某一层嵌套逻辑涉及到时序聚合窗口的计算,必须在指标中以
rolling
作为标识进行改写。如:窗口为 3,
步长为 3,窗口内进行求和计算,计算列为 price,空值以前值填充,则可以写为 rolling(sum, price, 3, 3,
'ffill')。形式如下:
rolling(func, funcArgs, window, [step=1], [fill='none'])
分解时,不包含上述标识的内置函数均在响应式状态引擎中处理。
中间引擎输入表结构
在
streamEngineParser
中,用户只能通过参数
dummyTable
指定第一个引擎输入表的 schema ,中间引擎的
dummyTable
对用户而言是透明的, 为了能在
metrics
和部分参数中指定中间表的列名,
streamEngineParser
提供了一套中间引擎
dummyTable
的命名规范:
第一列为时间列。
之后几列对应指定的
keyColumn
。
后续列为
metrics
对应的计算结果列,列名为:“col_0_, col_1_,
col_2_...”。
注:
由于响应式状态引擎的输出表没有时间列,而时间序列聚合引擎以及横截面引擎的输出表需包含时间列,因此当流水线中涉及到响应式状态引擎相关操作时,其
metrics
会自动增加时间列作为下一个引擎的
dummyTable
的一列。若此时
useSystemTime
= true,则其中间表的时间列的列名为 "datatime"。
以下引擎的部分参数需要指定列名,如:
横截面引擎:
contextByColumn
响应式状态引擎:
filter
,
keyPurgeFilter
若这些参数需要指定中间引擎的
dummyTable
的列名,则可以根据如上的命名规则给出的列名进行指定,如
"
contextByColumn
= col_0_"。若指定的列为
timeColumn
和
keyColumn
,则也可以指定参数对应的列名。
必选参数
name
是一个字符串,表示指定流水线内引擎名称的前缀,可包含字母,数字和下划线,但必须以字母开头。比如指定
name
=
"test",则流水线内部对应的引擎名称为 "test0", "test1", "test2"... 其中,数字代表
metrics
分解出的流数据引擎的级联顺序。
metrics
以元代码的形式表示计算指标,支持输入元组。有关元代码的更多信息可参考
Metaprogramming
。
metrics 可以是系统内置或用户自定义的函数,如 <[sum(qty),
avg(price)]>;可以对计算结果使用表达式,如
<[avg(price1)-avg(price2)]>;也可以对多列进行运算,如
<[std(price1-price2)]>。
metrics 内支持具有多个返回值的函数,例如 <func(price) as
col1
col2>(可不指定列名)。
在
streamEngineParser
中,计算指标通常是一个嵌套的因子,每层嵌套逻辑都被解析后放入特定的引擎进行计算。更多说明见详情。
dummyTable
一个表对象,和输入的流数据表的 schema 一致,可以含有数据,亦可为空表。
outputTable
计算结果的输出表,可以是内存表或者分布式表。调用
streamEngineParser
之前,需要将输出表预先设立为一个空表,并指定各列列名以及数据类型。各引擎会将计算结果插入该表。 若
metrics
分解的流水线上的最后一个操作对应:
时序聚合引擎
输出表的各列的顺序为:时间列,分组列,计算结果列。
其中:
第一列必须是时间类型。
若
useSystemTime
= true,为 TIMESTAMP 类型。
若
useSystemTime
= false,数据类型与
timeColumn
列一致。
若
useWindowStartTime
= true,显示时间为数据窗口起始时间。
若
useWindowStartTime
= false,显示时间为数据窗口终止时间。
如果
keyColumn
不为空,则其后几列和
keyColumn
设置的列及其顺序保持一致。
最后为计算结果列,可为多列。
最终的 schema
为“时间列,分组列(可选),计算结果列1,计算结果列2...”这样的格式。
响应式状态引擎
输出表的各列的顺序为:分组列,计算结果列。
其中:
根据
keyColumn
的设置,输出表的前几列必须和
keyColumn
设置的列及其顺序保持一致。
其后为计算结果列,可为多列。
横截面引擎
输出表的 schema 需要遵循以下规范:
如果没有指定
contextByColumn
, 输出表的列数为
metrics
数量+1,第一列为
TIMESTAMP 类型,用于存放发生计算的时间戳(如果指定了
timeColumn
则是对应记录的时间戳),其他列为
metrics
计算结果对应的列,其数据类型必须与
metrics
返回结果的数据类型一致。
如果指定
contextByColumn
, 输出表的列数为
metrics
数量+2。第一列为
TIMESTAMP 类型,用于存放发生计算的时间戳(如果指定了
timeColumn
则是对应记录的时间戳);第二列为
contextByColumn
指定的列;最后几列为
metrics
计算结果对应的列,其数据类型必须与
metrics
返回结果的数据类型一致。
keyColumn
是一个字符串标量或向量。
时序聚合引擎/响应式状态引擎:表示分组列名。若设置,计算按分组进行,例如以每支股票为一组进行聚合计算。
横截面引擎:表示将某列值作为横截面引擎的 key,横截面引擎的每次计算,只使用每个 key
对应的最新一条记录。
可选参数
timeColumn
指定输入的流数据表中时间列的名称。当
useSystemTime
= false 时,必须指定该参数。
时序聚合引擎/响应式状态引擎:是一个字符串标量或向量。请注意,若为字符串向量,必须是 date 和 time
组成的向量,date 类型为 DATE,time 类型为 TIME, SECOND 或 NANOTIME。此时,输出表第一列的时间类型必须与
concatDateTime(date,
time)
的类型一致。
横截面引擎:是一个字符串,仅支持 TIMESTAMP 类型。
useSystemTime
表示是否使用系统时间作为时间戳。
横截面引擎:可选参数。表示
outputTable
中第一列(时间列)为系统当前时间(
useSystemTime
= true)或数据中时间列(
useSystemTime
=
false)。
时间序列聚合引擎:可选参数,表示时间序列引擎计算的触发方式。若指定该参数为 true,不能指定
timeColumn
。
a. 当
useSystemTime
= true
时,时间序列引擎会按照数据进入时间序列引擎的时刻(毫秒精度的本地系统时间,与数据中的时间列无关),每隔固定时间截取固定长度窗口的流数据进行计算。只要一个数据窗口中含有数据,数据窗口结束后就会自动进行计算。结果中的第一列为计算发生的时间戳,与数据中的时间无关。
b. 当
useSystemTime
= false(缺省值)时,时间序列引擎根据流数据中的 timeColumn
列来截取数据窗口。一个数据窗口结束后的第一条新数据才会触发该数据窗口的计算。请注意,触发计算的数据并不会参与该次计算。
若要开启快照机制 (snapshot),必须指定
snapshotDir
与
snapshotIntervalInMsgCount
。启用快照机制之后,系统若出现异常,可及时将流数据引擎恢复到最新的快照状态。
snapshotDir
可选参数,字符串,表示保存引擎快照的文件目录。
指定的目录必须存在,否则系统会提示异常。
创建流数据引擎时,如果指定了
snapshotDir
,会检查该目录下是否存在快照。如果存在,会加载该快照,恢复引擎的状态。
多个引擎可以指定同一个目录存储快照,用引擎的名称来区分快照文件。
一个引擎的快照可能会使用三个文件名:
临时存储快照信息:文件名为 <engineName>.tmp;
快照生成并刷到磁盘:文件保存为 <engineName>.snapshot;
存在同名快照:旧快照自动重命名为 <engineName>.old。
snapshotIntervalInMsgCount
可选参数,为整数类型,表示每隔多少条数据保存一次流数据引擎快照。
raftGroup
是流数据高可用订阅端 raft 组的 ID (大于1的整数,由流数据高可用相关的配置项
streamingRaftGroups
指定)。设置该参数表示开启计算引擎高可用。在 leader 节点创建流数据引擎后,会同步在
follower 节点创建该引擎。每次保存的 snapshot 也会同步到 follower。当 raft 组的 leader 节点宕机时,会自动切换新 leader
节点重新订阅流数据表。请注意,若要指定
raftGroup
,必须同时指定
snapshotDir
。
该流水线引擎只能在 raft 组的 leader 节点创建。
各引擎特有的参数如下:
响应式状态引擎
createReactiveStateEngine
:
filter
,
keepOrder
,
keyPurgeFilter
,
keyPurgeFreqInSecond
横截面引擎参数
createCrossSectionalEngine
:
triggeringPattern
,
triggeringInterval
,
lastBatchOnly
,
contextByColumn
时间序列聚合引擎
createTimeSeriesEngine
:
updateTime
,
useWindowStartTime
,
roundTime
,
forceTriggerTime
,
closed, fill, garbageSize, keyPurgeFreqInSec
日级时间序列聚合引擎
createDailyTimeSeriesEngine
:
sessionBegin
,
sessionEnd
,
mergeSessionEnd
, closed, fill, garbageSize,
forceTriggerSessionEndTime, keyPurgeFreqInSec
注:
如果
triggeringPattern
='keyCount',则
keepOrder
的默认值为 true,且不可设置为 false。
返回值
返回一个表对象,为解析后流水线上第一个流计算引擎返回的表,向该表写入数据意味着这些数据进入流水线进行计算。删除时,需要根据 streamEngineParser 解析出的引擎对应的名称(详见 name)单独进行删除。暂不支持通过一个函数删除全部引擎。
例子
下面的例子是 World Quant 101 个 Alpha
因子中的1号因子公式的流数据实现。
rank
函数是一个横截面操作。
rank
的参数部分用响应式状态引擎实现。
rank
函数本身用横截面引擎实现。横截面引擎作为状态引擎的输出。
n = 100
sym = rand(`aaa`bbb`ccc, n)
time = 2021.01.01T13:30:10.008 + 1..n
maxIndex=rand(100.0, n)
data = table(sym as sym, time as time, maxIndex as maxIndex)
rank(Ts_ArgMax(SignedPower((returns<0?stddev(returns,20):close), 2), 5))-0.5
// 创建横截面引擎,计算每个股票的rank
dummy = table(1:0, `sym`time`maxIndex, [SYMBOL, TIMESTAMP, DOUBLE])
resultTable = streamTable(10000:0, `time`sym`factor1, [TIMESTAMP, SYMBOL, DOUBLE])
ccsRank = createCrossSectionalAggregator(name="alpha1CCS", metrics=<[sym, rank(maxIndex, percent=true) - 0.5]>, dummyTable=dummy, outputTable=resultTable, keyColumn=`sym, triggeringPattern='keyCount', triggeringInterval=3000, timeColumn=`time, useSystemTime=false)
@state
def wqAlpha1TS(close){
ret = ratios(close) - 1
v = iif(ret < 0, mstd(ret, 20), close)
return mimax(signum(v)*v*v, 5)
}
// 创建响应式状态引擎,输出到前面的横截面引擎ccsRank
input = table(1:0, `sym`time`close, [SYMBOL, TIMESTAMP, DOUBLE])
rse = createReactiveStateEngine(name="alpha1", metrics=<[time, wqAlpha1TS(close)]>, dummyTable=input, outputTable=ccsRank, keyColumn="sym")
rse.append!(data)
dropStreamEngine("alpha1CCS")
dropStreamEngine("alpha1")
上述操作可以通过直接构建流水线引擎进行替代:
input = table(1:0, `sym`time`close, [SYMBOL, TIMESTAMP, DOUBLE])
resultTable = streamTable(10000:0, `time`sym`factor1, [TIMESTAMP, SYMBOL, DOUBLE])
// 构建计算因子
metrics=<[sym, rowRank(wqAlpha1TS(close), percent=true)- 0.5]>
streamEngine=streamEngineParser(name=`alpha1_parser, metrics=metrics, dummyTable=input, outputTable=resultTable, keyColumn=`sym, timeColumn=`time, triggeringPattern='keyCount', triggeringInterval=3000)
streamEngine.append!(data)
dropStreamEngine("alpha1_parser0")
dropStreamEngine("alpha1_parser1")
FILE:references/doc_7795.md
# values
**URL**: https://docs.dolphindb.cn/zh/funcs/v/values.html
**来源**: DolphinDB 官方文档
---
values
语法
values(X)
详情
返回字典
X
中的所有值,或者以元组形式返回表
X
中的所有列。
参数
X
是一个字典或表。
返回值
向量或元组,数据类型取决于字典的值或表的所有列。
例子
z=dict(INT,DOUBLE)
z[5]=7.9
z[3]=6
z.values();
// output
[6,7.9]
t = table(1 2 3 as id, 4 5 6 as x, `IBM`MSFT`GOOG as name);
values(t);
// output
([1,2,3],[4,5,6],["IBM","MSFT","GOOG"])
相关函数:
keys
FILE:references/doc_7819.md
# existsTable
**URL**: https://docs.dolphindb.cn/zh/funcs/e/existsTable.html
**来源**: DolphinDB 官方文档
---
existsTable
语法
existsTable(dbUrl, tableName)
详情
检查指定表是否存在于指定数据库中。
参数
dbUrl
是一个字符串,表示数据库的路径。
tableName
是表的名称。它需要用反引号(`)或双引号。
返回值
布尔类型标量。 false 和 true 分别表示指定表不存在、存在。
例子
检查分区是否在分布式文件系统中(以下脚本需要在集群的数据节点/计算节点中执行):
n=1000000
ID=rand(10, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x)
db = database("dfs://valueDB", VALUE, 2017.08.07..2017.08.11)
pt = db.createPartitionedTable(t, `pt, `date);
pt.append!(t);
existsTable("dfs://valueDB", `pt);
// output
true
existsTable("dfs://valueDB/20170807", `pt);
// output
true
FILE:references/doc_7820.md
# installPlugin
**URL**: https://docs.dolphindb.cn/zh/funcs/i/installPlugin.html
**来源**: DolphinDB 官方文档
---
installPlugin
语法
installPlugin(pluginName, [pluginVersion],
[pluginServerAddr])
详情
下载并解压指定名称的插件的二进制文件(Windows 版本 server 使用 .dll,Linux 版本 server 使用
.so)和插件描述文件(.txt)到 DolphinDB
的插件目录(
/server/plugins/
)下。返回插件描述文件的完整路径。后续可通过该路径加载插件。
可通过
listRemotePlugins
函数查看所支持的插件名称及版本信息。
参数
pluginName
STRING 类型,用于指定插件名称。
pluginVersion
可选,STRING 类型,用于指定插件版本。如果不指定该参数,则使用插件的最新版本。
pluginServerAddr
可选,STRING 类型,用于指定插件仓库的 HTTP 地址。如果不配置该参数,使用默认的 HTTP
地址:"http://plugins.dolphindb.cn/plugins"。如果 DolphinDB 服务位于国外,建议填写
"http://plugins.dolphindb.com/plugins" 以提高查询速度。
返回值
字符串标量,表示插件描述文件的完整路径。
例子
在 Linux 中下载指定的插件:
installPlugin("mysql")
返回:
/home/DolphinDB_Linux64_V2.00.10/server/plugins/mysql/PluginMySQL.txt
通过
loadPlugin
加载插件:
loadPlugin("mysql")
FILE:references/doc_7821.md
# winsorize!
**URL**: https://docs.dolphindb.cn/zh/funcs/w/winsorize_.html
**来源**: DolphinDB 官方文档
---
winsorize!
语法
winsorize!(X, limit, [inclusive=true], [nanPolicy='omit'])
详情
winsorize!
是
winsorize
函数原地修改版本,它会改变输入对象
X
的值。参考
winsorize
FILE:references/doc_7830.md
# renameTable
**URL**: https://docs.dolphindb.cn/zh/funcs/r/renameTable.html
**来源**: DolphinDB 官方文档
---
renameTable
语法
renameTable(dbHandle, tableName, newTableName)
详情
将给定分布式数据库内数据表改名。
参数
dbHandle
是一个DFS数据库句柄。
tableName
是一个字符串,表示要改名的数据表名称。该表既可为分布式表,亦可为维度表。
newTableName
是一个字符串,表示要改名后的数据表名称。
返回值
返回包含元数据的表对象。
例子
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x)
db=database("dfs://hashdb101", HASH, [INT, 2]);
pt = db.createPartitionedTable(t, `pt, `ID)
pt.append!(t)
renameTable(db, `pt, `pt1)
select count(x) from loadTable(db, `pt1);
输出返回: 1000000
FILE:references/doc_7833.md
# getUserAccess
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getUserAccess.html
**来源**: DolphinDB 官方文档
---
getUserAccess
语法
getUserAccess([userIds], [finalAccess=false])
详情
指定
userId
时:
若
finalAccess
= false,则返回指定用户所单独被赋予的权限,不包括用户所属组的权限。
若
finalAccess
= true,则返回指定用户及其所属组的权限组合后的最终生效权限。
当没有指定
userId
时,返回当前登录用户的权限。
注:
该函数只能由管理员在控制节点、数据节点和计算节点运行。
参数
userId
是表示一个或多个用户的字符串标量或向量。
finalAccess
为布尔值,表示是否获取用户及其所属组权限叠加的结果。默认值为 false。
返回值
返回一个表,以下分别介绍返回表的各参数的详情:
参数
详情
userId
用户名
groups
组名
isAdmin
是否是管理员。
MAX_JOB_PRIORITY
该用户对应的作业最高优先级,范围是0-8,可以通过
setMaxJobPriority
指定。
MAX_PARALLELISM
该用户提交的作业最多可以有多少个子任务同时并行执行,可以通过
setMaxJobParallelism
指定。
QUERY_RESULT_MEM_LIMIT
该用户单次查询结果的占用内存上限,浮点类型,单位为 GB。可以通过
grant
指定,
revoke
撤销。
TASK_GROUP_MEM_LIMIT
该用户发送的批量子查询占用的内存上限,浮点类型,单位为 GB。可以通过
grant
指定,
revoke
撤销。
MAX_PARTITION_NUM_PER_QUERY
该用户单次查询的最大分区数。整型标量,-1 表示没有设置该权限。可以通过
grant
指定,
revoke
撤销。
以下字段对应权限,其值为 “allow" / "none" / "deny" :
权限
ACCESS_READ
ACCESS_INSERT
ACCESS_UPDATE
ACCESS_DELETE
VIEW_EXEC
SCRIPT_EXEC
TEST_EXEC
DBOBJ_CREATE
DBOBJ_DELETE
DB_MANAGE
DB_OWNER
VIEW_OWNER
COMPUTE_GROUP_EXEC
TABLE_SENSITIVE_VIEW
DB_SENSITIVE_VIEW
CREATE_SHARED_VARS
MCP_MANAGE
MCP_DEVELOP
MCP_EXEC
注意
:
自 3.00.2 版本起,支持获取访问计算节点组的权限。
自 3.00.0.0 版本起,支持获取访问 catalog 的相关权限。
自
2.00.9
版本开始,新增了表和数据库的插入更新和删除权限(即对写权限进行拓展),因此旧版本的 TABLE_WRITE 字段由
TABLE_INSERT,TABLE_UPDATE,TALBE_DELETE 字段替代。
因为具有 DB_READ / DB_INSERT / DB_UPDATE / DB_DELETE
权限的用户,可以在该数据库范围内对其下的所有表执行相应的操作,所以在 getUserAccess 函数中,用户对数据库和表的权限会被统一为
ACCESS_READ / ACCESS_INSERT / ACCESS_UPDATE /
ACCESS_DELETE。可以通过下表来区分上述权限的具体应用对象。
以下几个字段表示权限应用的具体对象:
对象
TABLE_READ_allowed
TABLE_READ_denied
TABLE_INSERT_allowed
TABLE_INSERT_denied
TABLE_UPDATE_allowed
TABLE_UPDATE_denied
TABLE_DELETE_allowed
TABLE_DELETE_denied
DB_READ_allowed
DB_READ_denied
DB_INSERT_allowed
DB_INSERT_denied
DB_UPDATE_allowed
DB_UPDATE_denied
DB_DELETE_allowed
DB_DELETE_denied
VIEW_EXEC_allowed
VIEW_EXEC_denied
DBOBJ_CREATE_allowed
DBOBJ_CREATE_denied
DBOBJ_DELETE_allowed
DBOBJ_DELETE_denied
DB_OWNER_allowed
DB_MANAGE_allowed
DB_MANAGE_denied
CATALOG_READ_allowed
CATALOG_READ_denied
CATALOG_INSERT_allowed
CATALOG_INSERT_denied
CATALOG_UPDATE_allowed
CATALOG_UPDATE_denied
CATALOG_DELETE_allowed
CATALOG_DELETE_denied
COMPUTE_GROUP_EXEC_allowed
COMPUTE_GROUP_EXEC_denied
TABLE_SENSITIVE_VIEW_allowed
TABLE_SENSITIVE_VIEW_denied
DB_SENSITIVE_VIEW_allowed
DB_SENSITIVE_VIEW_denied
MCP_EXEC_allowed
MCP_EXEC_denied
FILE:references/doc_7837.md
# OLAP 存储引擎
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db/olap.html
**来源**: DolphinDB 官方文档
---
OLAP 存储引擎
在 OLAP 场景中,通常需要执行大规模的聚合和分析操作。为了应对这种需求,DolphinDB OLAP
引擎采用了数据分区技术,按照指定规则将大规模数据集水平分割成多个分区,并在每个分区内采用列式存储的方式来存储数据。这种分区式存储策略允许我们只读取所需的列数据,从而减少不必要的
I/O 操作,显著提高了查询速度。
存储结构
OLAP 存储如下图所示,同一列的数据按表中的顺序连续地存放在一起,表的每列构成一个长数组。
OLAP
引擎将数据表中的每个分区中的每列都存储在一个单独的数据文件中。数据以追加的方式存储到相应的列文件中,因此,数据写入的顺序决定了它们的存储顺序。这种存储方式使得对于每个分区中的每一列数据的查询和分析都可以快速高效地进行。同时,由于每个分区都有其独立的存储空间,因此在进行数据操作时可以充分利用系统的并行处理能力,进一步提高数据处理速度。
数据压缩
OLAP 支持无损压缩,提供了如下可选的压缩算法(通过建表的选项
compressMethods
配置):
若不指定,默认采用 LZ4 压缩算法,适用于一般情况。LZ4 主要针对重复字符进行压缩,压缩率与数据重复频率相关。如果同一列中有较多重复项,LZ4
算法可以获得较高的压缩速度。但相对于 Delta(delta-of-delta encoding) 压缩算法,压缩率提升可能不太明显。
zstd 压缩算法:zstd 适用于几乎所有数据类型,其压缩比高于 LZ4,但解压缩速度较 LZ4 慢约1倍。
对于时间类型或者变化较小的整型数据,建议采用 Delta(delta-of-delta encoding) 压缩算法。Delta
是专门针对时间戳等连续且等间隔的数据提出的算法,能够极大降低时间戳的存储空间,因此特别适合时间列的压缩。
chimp 压缩算法:在处理小数部分长度不超过三位的 DOUBLE 类型数据时,chimp 具有很高的压缩率及优越的压缩和解压效率。
对于重复较高的字符串,可采用 SYMBOL 类型存储。系统对 SYMBOL 类型数据会使用字典编码,将字符串转化为整型,减少字符串的存储空间。
在现实场景下,金融数据存盘的压缩率一般可达到 20% 到 30% 左右。OLAP
采用增量压缩策略,每次只对新增数据进行压缩,因此批量写入有助于提升压缩效果。若每次仅写入一行记录,且 Cache Engine
未开启,则存于磁盘的数据不会进行压缩。
数据写入
通用场景下,数据写入后会直接刷盘,若每次进行小批量写入会极大影响磁盘 I/O 性能以及压缩效果。为此,OLAP 维护了一个 Cache
Engine,以实现数据缓存后批量写入的功能。Cache Engine 是 DolphinDB
中的一种数据写入缓存机制,对一个文件进行写入时,写入1行数据和写入1000行数据的时间基本相等,大部分时间都花在打开和关闭文件上;因此,如果把多次少量的写入缓存起来,在一次文件
IO 中批量写入,那么就可以节省许多对文件进行打开和关闭带来的时间开销,从而在整体上提升系统的写入性能。
OLAP 引擎可以通过配置参数 OLAPCacheEngineSize 开启或关闭 Cache Engine。写入缓存功能必须与 Redo Log 配合使用,即开启
Cache Engine 时必须指定 dataSync=1。 当缓存中的数据量达到阈值(OLAPCacheEngineSize
的30%)时,系统才会将数据写入磁盘,这样避免了频繁的磁盘操作。
OLAP 引擎写入操作支持事务,具备事务 ACID 特性,且通过 MVCC 实现快照隔离级别。
写入流程如下:
写 Redo:
先将数据写入 OLAP Redo Log。
写 Cache Engine:
写 Redo Log 的同时,将数据写入 OLAP Cache Engine。
写磁盘:
若某写事务到来时,Cache Engine 中的数据累计达到了
OLAPCacheEngineSize
* 30%
时,系统将进行一次刷盘操作,把数据以追加的方式写入分区中的列文件。
数据查询
OLAP 引擎将每列数据存储为一个列文件,所以读取数据时,需要从磁盘读取该列所在的分区,解压后加载到内存。
具体流程如下:
根据查询语句进行分区剪枝,缩窄查询范围。
将 where 语句过滤条件中包含的列的数据文件读到内存,并进行过滤。
根据过滤出的列数据,读出其对应的其他列的数据。
这种数据读取方式使得 OLAP 引擎在高吞吐量查询情况下拥有较好的性能。 但若需要更新或删除某条数据,OLAP
会将整个分区数据加载到内存中,再对这条数据进行更新或删除,因此性能开销大。
数据更新
OLAP 引擎更新操作支持事务,具备事务 ACID 特性,且通过 MVCC
实现快照隔离级别。每次更新,系统都会读出对应分区中相关的列文件,在内存中进行更新,同时创建一个新的版本以存储新的数据。整个过程通过事务来确保数据一致性,并通过 MVCC
保证读取的一致性,对于未变化的列,采用创建硬链接的方式,以提升性能并降低不必要的数据读写。在提交事务之前,其他 SQL
语句仍然访问旧版本的数据,直到更新事务完成。若更新操作涉及多个分区,只要其中某一个分区更新失败,系统会回滚所有分区的修改。
针对不同的数据更新需求,DolphinDB 提供3种更新表的方法:
update:ANSI SQL 92 的update语法
sqlUpdate:动态生成 SQL update 语句的元代码。
upsert!:用于更新键值内存表、索引内存表或分布式表。进行更新时,若新数据的主键值已存在,则更新该主键值的数据;否则添加数据。
数据删除
对于 OLAP 引擎的数据删除操作,其流程与更新操作一致,即按分区读取所有数据,执行删除操作后写入一个新版本的目录。整个过程同样通过事务保证数据一致性,并通过 MVCC
保证读取一致性。若删除操作涉及多个分区,只要其中某一个分区删除失败,系统会回滚所有分区的修改。
针对不同的数据删除需求,DolphinDB 提供以下方法删除数据:
dropPartition:删除整个分区的数据,默认保留分区结构,也可通过参数设置不保留分区结构。
delete:删除数据,保留分区结构。
sqlDelete:动态生成 SQL delete 语句。
dropTable:删除整个表的数据,不保留表结构。
truncate:删除整个表的数据,保留表结构。
OLAP引擎特点
数据在表中的存储顺序与数据写入的顺序一致,数据写入非常高效。
OLAP 的存储结构决定了它很适合读取整个分区数据或分区的某几列数据的场景。
适合扫描分析大量数据、全表扫描等场景,如:查询所有股票在某个时间段内的交易量等。
写入过程设计简单,不支持去重。
不适合几百几千列的宽表存储。
FILE:references/doc_7840.md
# inner join
**URL**: https://docs.dolphindb.cn/zh/progr/sql/innerjoin.html
**来源**: DolphinDB 官方文档
---
inner join
语法
等值连接,又称内连接。
select column_name(s) from leftTable inner join rightTable on leftTable.matchingCol=rightTable.rightMatchingCol
或
select column_name(s)
from table1 inner join table2
on table1.column_name=table2.column_name and [filter]
参数
filter
为条件表达式,作为连接时的过滤条件。暂时只支持通过 and 连接多个过滤条件,不支持 or。
详情
返回与连接列匹配的行。该函数返回结果与
equijoin
相同。
注意
:
如果有多个连接列,必须使用 and 连接。
不能和 update 关键字一起使用。
例子
例1. 两个表等值连接,除了连接列外没有其他名称相同的列
t1= table(1 2 3 3 as id, 7.8 4.6 5.1 0.1 as value)
t2 = table(5 3 1 as id, 300 500 800 as qty);
select id, value, qty from t1 inner join t2 on t1.id=t2.id
id
value
qty
1
7.8
800
3
5.1
500
3
0.1
500
select id, value, qty from t1 inner join t2 on t1.id=t2.id where id=3
id
value
qty
3
5.1
500
3
0.1
500
例2. 等值连接两张表,它们含有相同名字的列,但是不以它作为连接列:
t3 = table(1 2 3 3 as id, 7.8 4.6 5.1 0.1 as value, 64 73 52 66 as x);
t4 = table(5 3 1 as id, 300 500 800 as qty, 44 66 88 as x) ;
select id, value, qty, x from t3 inner join t4 on t3.id=t4.id
id
value
qty
x
1
7.8
800
64
3
5.1
500
52
3
0.1
500
66
若不指定value与qty来自何表,系统首先会在左表中定位这两个列,如果左表没有这两个列,系统会在右表定位。
select id, value, qty, t4.x from t3 inner join t4 on t3.id=t4.id
id
value
qty
x
1
7.8
800
88
3
5.1
500
52
3
0.1
500
66
例3. 多个连接列:
select id, value, qty, x from t3 inner join t4 on t3.id=t4.id and t3.x=t4.x
id
value
qty
x
3
0.1
500
66
例4. 分布式表连接:
dbName1="dfs://sql_inner_join"
if(existsDatabase(dbName1)){
dropDatabase(dbName1)
}
db1=database(dbName1, RANGE, 1 30 70 101)
t1=table("A"+string(1..100) as sym, 1..100 as val)
pt1=db1.createPartitionedTable(t1, `pt1, `val).append!(t1)
t2=table("A"+string(1..20) as sym, 1..20 as val)
pt2=db1.createPartitionedTable(t2, `pt2, `val).append!(t2)
select * from pt1 inner join pt2 on pt1.val=pt2.val
sym
val
pt2_sym
A1
1
A1
A2
2
A2
A3
3
A3
A4
4
A4
A5
5
A5
A6
6
A6
A7
7
A7
A8
8
A8
A9
9
A9
A10
10
A10
A11
11
A11
A12
12
A12
A13
13
A13
A14
14
A14
A15
15
A15
A16
16
A16
A17
17
A17
A18
18
A18
A19
19
A19
A20
20
A20
例5. 指定
filter
t1= table(1 2 3 3 6 8 as id, 7.8 4.6 5.1 0.1 0.5 1.2 as value)
t2 = table(5 3 1 2 6 8 as id, 300 500 800 400 600 700 as qty);
select * from t1 inner join t2 on t1.id=t2.id and t1.id>=3
id
value
qty
3
5.1
500
3
0.1
500
6
0.5
600
8
1.2
700
FILE:references/doc_7848.md
# take
**URL**: https://docs.dolphindb.cn/zh/funcs/t/take.html
**来源**: DolphinDB 官方文档
---
take
语法
take(X, n)
详情
如果
X
是标量,则
n
必须是标量,返回由
n
个
X
组成的向量。
如果
X
是向量/元组:
n
标量:从
X
中循环地依次取值,共取
n
个值。结果是一个向量。
n
是正数时,从左到右取数,
n
是负数时,从右到左取数。
n
是向量:
n
的长度必须和
X
相同。从
X
中依次取出
n[i] 个 X[i]。当 n[i] <=0 时,不会取 X[i]。结果是一个向量。
如果
X
是矩阵/表:
n
标量:从
X
中循环地依次逐行取值,共取
n
行。结果是一个矩阵/表。
n
是正数时,从上到下取数,
n
是负数时,则从下到上取数。
n
是向量:
n
的长度必须和
X
的行数相同。从
X
中依次取出 n[i] 个第 i 行的元素。当 n[i] <=0 时,不会取第 i 行元素。结果是一个矩阵/表。
参数
X
可以是标量、向量、元组、矩阵或表。
n
是一个整数标量或向量。
返回值
数据类型同
X
,数据形式见
详情
。
例子
take(10,5);
// output
[10,10,10,10,10]
x=`IBM`C`AAPL`BABA;
take(x,10);
// output
["IBM","C","AAPL","BABA","IBM","C","AAPL","BABA","IBM","C"]
# sequentially and iteratively take 10 elements from vector x
x=3 5 4 6 9;
take(x,3);
// output
[3,5,4]
x=1..3;
x.take(10);
// output
[1,2,3,1,2,3,1,2,3,1]
take(1 2 3, 10);
// output
[1,2,3,1,2,3,1,2,3,1]
take(1,10);
// output
[1,1,1,1,1,1,1,1,1,1]
# an efficient way to generate a vector with default values.
x=take(1,0);
# return an empty INT VECTOR
x;
// output
[]
typestr x;
// output
FAST INT VECTOR
x=1..12$3:4;
take(x,2);
col1
col2
col3
col4
1
4
7
10
2
5
8
11
take(x,-2);
col1
col2
col3
col4
2
5
8
11
3
6
9
12
take(1..3,2 0 2)
// output
[1,1,3,3]
m=matrix(1 2 3, 4 5 6)
take(m,5)
col1
col2
1
4
2
5
3
6
1
4
2
5
take(m, 0 2 1)
col1
col2
2
5
2
5
3
6
t=table(1 2 3 as a, 4 5 6 as b)
take(t,-4)
a
b
3
6
1
4
2
5
3
6
take(t, -2 2 1)
a
b
2
5
2
5
3
6
FILE:references/doc_7854.md
# getHomeDir
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getHomeDir.html
**来源**: DolphinDB 官方文档
---
getHomeDir
语法
getHomeDir()
详情
查询本地节点的主目录。主目录是由配置文件 dolphindb.cfg 定义的。
参数
无
返回值
字符串标量。
例子
getHomeDir()
// output: /data/ddb/server
FILE:references/doc_7856.md
# getRules
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getrules.html
**来源**: DolphinDB 官方文档
---
getRules
语法
getRules([engineName])
详情
查询规则引擎的规则信息,包括规则集、规则检查策略和回调函数等。
参数
engineName
字符串向量,代表要查询的规则引擎的名称。该参数省略时,返回当前节点所有规则引擎的规则信息。
返回值
返回一个字典,key 为引擎的名称, value 为字典,包含以下信息:
ruleSets:该引擎的规则集。类型为一个字典,key 和 value 定义如下:
key:规则集的键值。key 为 “Default” 指默认规则。
value:规则集中该键值对应的规则。
policy:指定引擎的规则检查策略。
callback:指定引擎的回调函数的名称,未配置回调函数时为空字符串。
例子
// 设置规则集
x = [1, 2, NULL]
y = [ [ < value > 1 > ], [ < price < 2 >, < price > 6 > ], [ < value*price > 10 > ] ]
ruleSets = dict(x, y)
// 创建规则引擎
names = `sym`value`price`quantity
types = [INT, DOUBLE, DOUBLE, DOUBLE]
dummy = table(1:0, names, types)
outputNames = `sym`value`price`rule
outputTypes = [INT, DOUBLE, DOUBLE, BOOL[]]
outputTable = table(10:0, outputNames, outputTypes)
test = createRuleEngine(name="ruleEngineTest", ruleSets=ruleSets, dummyTable=dummy, outputColumns=["sym","value","price"], outputTable=outputTable, policy="all", ruleSetColumn="sym")
test2 = createRuleEngine(name="ruleEngineTest2", ruleSets=ruleSets, dummyTable=dummy, outputColumns=["sym","value","price"], outputTable=outputTable, policy="all", ruleSetColumn="sym")
// 查询规则
getRules(["ruleEngineTest"])
/*
ruleEngineTest->
ruleSets->
Default->(value * price > 10)
1->(value > 1)
2->(price < 2, price > 6)
policy->all
callback->
*/
// 更新规则
updateRule("ruleEngineTest", 1, [<value > 2>])
// 再次查询
getRules()
/*
ruleEngineTest->
ruleSets->
Default->(value * price > 10)
1->(value > 2)
2->(price < 2, price > 6)
policy->all
callback->
*/
相关函数:
createRuleEngine
,
updateRule
,
deleteRule
FILE:references/doc_7860.md
# base64Encode
**URL**: https://docs.dolphindb.cn/zh/funcs/b/base64Encode.html
**来源**: DolphinDB 官方文档
---
base64Encode
语法
base64Encode(X)
详情
将
X
转换为 Base64 编码格式。
参数
X
字符串标量或向量。
返回值
字符串标量或向量。
例子
base64Encode(`hello)
// output
aGVsbG8=
base64Encode(`hello`world)
// output
["aGVsbG8=","d29ybGQ="]
base64Encode("")
// output
""
相关函数:
base64Decode
FILE:references/doc_7864.md
# existsDatabase
**URL**: https://docs.dolphindb.cn/zh/funcs/e/existsDatabase.html
**来源**: DolphinDB 官方文档
---
existsDatabase
语法
existsDatabase(dbUrl)
详情
检查指定数据库是否存在。
参数
dbUrl
是一个字符串,表示数据库的路径。
返回值
布尔类型标量。 false 和 true 分别表示指定的数据库不存在、存在。
例子
检查分布式数据库是否存在:
n=1000000
ID=rand(10, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x)
db = database("dfs://valueDB", VALUE, 2017.08.07..2017.08.11)
pt = db.createPartitionedTable(t, `pt, `date);
pt.append!(t);
existsDatabase("dfs://valueDB");
输出返回:true
existsDatabase("dfs://valueDB/20170807");
输出返回:false
FILE:references/doc_7878.md
# share
**URL**: https://docs.dolphindb.cn/zh/progr/statements/share.html
**来源**: DolphinDB 官方文档
---
share
语法
share <table> as <shared name>
或
share <engine> as <engine name>
详情
第一种用法:节点内的会话共享
将一个表共享到当前节点的所有会话中。包括表在内的局部对象在其他会话中是不可见的,需要通过共享才能在其他会话中可见。
共享表名必须与所有其他会话中的普通表名不同。DolphinDB 服务器可以最多定义 65535 张共享表。
第二种用法:为引擎添加写入锁
通过 share
语句,可以为引擎添加写入锁,从而允许当前节点的所有会话并发地向引擎写入数据(要求引擎共享后的名称和引擎名称相同)。注意:在其它会话中,需要通过函数
getStreamEngine
来获取引擎的句柄。
例子
第一种用法
t1= table(1 2 3 as id, 4 5 6 as value);
share t1 as table1;
第二种用法
在一个会话中定义一个引擎,且通过 share 语句进行共享。
trades = streamTable(1:0, `time`sym`price, [TIMESTAMP, SYMBOL, DOUBLE])
share table(100:0, `sym`time`factor1, [SYMBOL, TIMESTAMP, DOUBLE]) as outputTable
engine = createReactiveStateEngine(name="test", metrics=[<time>, <mavg(price, 3)>], dummyTable=trades, outputTable=outputTable, keyColumn=`sym)
//通过 share 语句,将引擎 test 共享后,便可以对引擎进行并发写入
share engine as "test"
当前节点所连接的任意一个会话中执行以下脚本:
//第一个自定义函数,向 engine 写入数据
def write1(mutable engine) {
N = 10
for (i in 1..500) {
data = table(take(now(), N) as time, take(`A`B, N) as sym, rand(10.0, N) as price)
getStreamEngine(engine).append!(data)
}
}
//第二个自定义函数,向 engine 写入数据
def write2(mutable engine) {
N = 10
for (i in 1..500) {
data = table(take(now(), N) as time, take(`C`D, N) as sym, rand(10.0, N) as price)
getStreamEngine(engine).append!(data)
}
}
//提交作业,使 write1 和 write2 同时向引擎写入数据
submitJob("j1", "j1", write1, "test")
submitJob("j2", "j2", write2, "test")
查看输出表中数据行数为 10000,正好是 write1 和 write2 写入的数据量之和。
select count(*) from outputTable
//output
10000
相关文档:
取消变量
,
undef
FILE:references/doc_7882.md
# randLogistic
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randLogistic.html
**来源**: DolphinDB 官方文档
---
randLogistic
语法
randLogistic(mean, s, count)
详情
生成指定个数的 Logistic 分布随机数。
参数
mean
Logistic 分布的均值。
s
是Logistic 分布的尺度参数。
count
是正整数,表示生成的随机数个数。
返回值
长度为
count
的 DOUBLE 类型向量。
例子
randLogistic(2.31, 0.671, 2);
// output
[2.465462, 2.577171]
FILE:references/doc_7885.md
# 时序聚合引擎
**URL**: https://docs.dolphindb.cn/zh/stream/time_series_engine.html
**来源**: DolphinDB 官方文档
---
时序聚合引擎
时间聚合引擎将数据基于时间进行窗口划分,并在窗口内进行聚合计算。DolphinDB 提供了三种时间序列引擎,分别为:
时间序列引擎(createTimeSeriesEngine),按照指定频率对时序数据进行滑动聚合计算,如计算 K
线等。适用于物联网、数字货币、外汇等无固定交易时段的场景。
日级时间序列引擎(createDailyTimeSeriesEngine),是在时间序列引擎的基础上的进一步扩展。除了可以实现时序引擎的全部功能外,它还可以指定交易时间段,将一个自然日之内各个交易时段开始之前的所有未参与计算的数据,并入该交易时段的第一个窗口进行计算。适用于在股票、期货市场等有固定交易时段的场景。
会话窗口引擎(createSessionWindowEngine)。与时间序列引擎极为相似,它们计算规则和触发计算的方式相同。不同之处在于时间序列引擎具有固定的窗口长度和滑动步长,但会话窗口引擎的窗口不是按照固定的频率产生的,其窗口长度也不是固定的。适用于需要根据事件活跃度划分窗口的场景。
本节以时间序列引擎为例,介绍时序引擎在流计算中的应用。
应用示例
示例1. 窗口边界规整
下例说明数据窗口如何规整以及流数据时序引擎如何进行计算。以下代码建立流数据表
trades
,包含 time 和 volume 两列。创建时序引擎
streamAggr1,每 3 毫秒对过去 6 毫秒的数据计算 sum(volume)。time
列的精度为毫秒,模拟插入的数据流频率也设为每毫秒一条数据。
share streamTable(
1000
:
0
, `time`volume, [TIMESTAMP, INT])
as
trades
outputTable = table(
10000
:
0
, `time`sumVolume, [TIMESTAMP, INT])
tradesAggregator = createTimeSeriesEngine(name=
"streamAggr1"
, windowSize=
6
, step=
3
, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=outputTable, timeColumn=`time)
subscribeTable(tableName=
"trades"
, actionName=
"append_tradesAggregator"
, offset=
0
, handler=append!{tradesAggregator}, msgAsTable=true)
向流数据表
trades
中写入 10 条数据,并查看流数据表
trades
内容:
def
writeData(t, n){
timev =
2018.10
.
08
T01:
01
:
01.001
+ timestamp(
1.
.n)
volumev = take(
1
, n)
insert into t values(timev, volumev)
}
writeData(trades,
10
)
select *
from
trades;
time
volume
2018.10.08T01:01:01.002
1
2018.10.08T01:01:01.003
1
2018.10.08T01:01:01.004
1
2018.10.08T01:01:01.005
1
2018.10.08T01:01:01.006
1
2018.10.08T01:01:01.007
1
2018.10.08T01:01:01.008
1
2018.10.08T01:01:01.009
1
2018.10.08T01:01:01.010
1
2018.10.08T01:01:01.011
1
再查看结果表
outputTable
:
select *
from
outputTable;
time
sumVolume
2018.10.08T01:01:01.003
1
2018.10.08T01:01:01.006
4
2018.10.08T01:01:01.009
6
时序引擎根据收到的第一条数据时刻规整第一个窗口的起始时间后,窗口以
step
为步长移动。下面详细解释时序引擎的计算过程。为简便起见,以下提到时间时,省略相同的 2018.10.08T01:01:01
部分,只列出毫秒部分。基于第一行数据的时间 002,第一个窗口的起始时间规整为 000,到 002 结束,只包含 002 一条记录,计算被 003
记录触发,sum(volume) 的结果是 1;第二个窗口从 000 到 005,包含了 4 条数据,计算被 006 记录触发,计算结果为 4;第三个窗口从
003 到 008,包含 6 条数据,计算被 009 记录触发,计算结果为 6。虽然第四个窗口从 006 到 011 且含有 6
条数据,但是由于该窗口结束之后没有数据,所以该窗口的计算没有被触发。
若需要重复执行以上程序,应首先解除订阅,并将流数据表
trades
与时序引擎 streamAggr1 二者删除:
unsubscribeTable(tableName=
"trades"
, actionName=
"append_tradesAggregator"
)
undef(`trades, SHARED)
dropStreamEngine(
"streamAggr1"
)
示例2. 设置多个窗口
DolphinDB 时序聚合引擎支持多个窗口,可以为每个窗口设置相同或不同的算子。
下例说如何对相同的
metrics
按不同的
windowSize
聚合。以下代码建立流数据表
trades
,包含
time 和 volume 两列。创建时序引擎 streamAggr1,每 3 毫秒对过去 6 毫秒和过去 12 毫秒的数据计算
sum(volume)
。
share streamTable(
1000
:
0
, `time`volume, [TIMESTAMP, INT])
as
trades
outputTable = table(
10000
:
0
, `time`sumVolume1`sumVolume2, [TIMESTAMP, INT,INT])
tradesAggregator = createTimeSeriesEngine(name=
"streamAggr1"
, windowSize=[
6
,
12
], step=
3
, metrics=[<sum(volume)>,<sum(volume)>], dummyTable=trades, outputTable=outputTable, timeColumn=`time)
subscribeTable(tableName=
"trades"
, actionName=
"append_tradesAggregator"
, offset=
0
, handler=append!{tradesAggregator}, msgAsTable=true)
def
writeData(t, n){
timev =
2018.10
.
08
T01:
01
:
01.001
+ timestamp(
1.
.n)
volumev = take(
1
, n)
insert into t values(timev, volumev)
}
writeData(trades,
20
)
select *
from
trades;
再查看结果表
outputTable
:
select *
from
outputTable;
time
sumVolume1
sumVolume2
2018.10.08T01:01:01.003
1
1
2018.10.08T01:01:01.006
4
4
2018.10.08T01:01:01.009
6
7
2018.10.08T01:01:01.012
6
10
2018.10.08T01:01:01.015
6
12
2018.10.08T01:01:01.018
6
12
2018.10.08T01:01:01.021
6
12
示例3.
metrics
指定多种表达式
DolphinDB 时序聚合引擎支持使用多种表达式进行实时计算。
一个或多个聚合函数
tsAggregator = createTimeSeriesEngine(name=
"streamAggr1"
, windowSize=
6
, step=
3
, metrics=<sum(ask)>, dummyTable=quotes, outputTable=outputTable, timeColumn=`time)
使用聚合结果进行计算
tsAggregator = createTimeSeriesEngine(name=
"streamAggr1"
, windowSize=
6
, step=
3
, metrics=<max(ask)-min(ask)>, dummyTable=quotes, outputTable=outputTable, timeColumn=`time)
对列与列的操作结果进行聚合计算
tsAggregator = createTimeSeriesEngine(name=
"streamAggr1"
, windowSize=
6
, step=
3
, metrics=<max(ask-bid)>, dummyTable=quotes, outputTable=outputTable, timeColumn=`time)
输出多个聚合结果
tsAggregator = createTimeSeriesEngine(name=
"streamAggr1"
, windowSize=
6
, step=
3
, metrics=<[max((ask-bid)/(ask+bid)*
2
), min((ask-bid)/(ask+bid)*
2
)]>, dummyTable=quotes, outputTable=outputTable, timeColumn=`time)
使用多参数聚合函数
tsAggregator = createTimeSeriesEngine(name=
"streamAggr1"
, windowSize=
6
, step=
3
, metrics=<corr(ask,bid)>, dummyTable=quotes, outputTable=outputTable, timeColumn=`time)
tsAggregator = createTimeSeriesEngine(name=
"streamAggr1"
, windowSize=
6
, step=
3
, metrics=<percentile(ask-bid,
99
)/sum(ask)>, dummyTable=quotes, outputTable=outputTable, timeColumn=`time)
使用自定义函数
defg diff(x,y){
return
sum(x)-sum(y)
}
tsAggregator = createTimeSeriesEngine(name=
"streamAggr1"
, windowSize=
6
, step=
3
, metrics=<diff(ask, bid)>, dummyTable=quotes, outputTable=outputTable, timeColumn=`time)
使用多个返回结果的函数
defg sums(x){
return
[sum(x),sum2(x)]
}
tsAggregator = createTimeSeriesEngine(name=
"streamAggr1"
, windowSize=
6
, step=
3
, metrics=<sums(ask)
as
`sumAsk`sum2Ask>, dummyTable=quotes, outputTable=outputTable, timeColumn=`time)
注:
不支持聚合函数嵌套调用,例如
sum(spread(ask,bid))
。
示例4. 指定输出表的类型
计算结果可以输出到内存表或流数据表。输出到流数据表的数据无法更新或删除,但是可以通过流数据表将结果作为另一个引擎的数据源再次发布。
下例中,时序引擎 electricityAggregator1 订阅流数据表
electricity
,进行移动均值计算,并将结果输出到流数据表
outputTable1
。时序引擎 electricityAggregator2 订阅
outputTable1
表,并对移动均值计算结果求移动峰值。
share streamTable(
1000
:
0
,`time`voltage`current,[TIMESTAMP,DOUBLE,DOUBLE])
as
electricity
//将第一个时序引擎的输出表定义为流数据表,可以再次订阅
share streamTable(
10000
:
0
,`time`avgVoltage`avgCurrent,[TIMESTAMP,DOUBLE,DOUBLE])
as
outputTable1
electricityAggregator1 = createTimeSeriesEngine(name=
"electricityAggregator1"
, windowSize=
10
, step=
10
, metrics=<[avg(voltage), avg(current)]>, dummyTable=electricity, outputTable=outputTable1, timeColumn=`time, garbageSize=
2000
)
subscribeTable(tableName=
"electricity"
, actionName=
"avgElectricity"
, offset=
0
, handler=append!{electricityAggregator1}, msgAsTable=true)
//订阅计算结果,再次进行聚合计算
outputTable2 =table(
10000
:
0
, `time`maxVoltage`maxCurrent, [TIMESTAMP,DOUBLE,DOUBLE])
electricityAggregator2 = createTimeSeriesEngine(name=
"electricityAggregator2"
, windowSize=
100
, step=
100
, metrics=<[max(avgVoltage), max(avgCurrent)]>, dummyTable=outputTable1, outputTable=outputTable2, timeColumn=`time, garbageSize=
2000
)
subscribeTable(tableName=
"outputTable1"
, actionName=
"maxElectricity"
, offset=
0
, handler=append!{electricityAggregator2}, msgAsTable=true);
//向electricity表中插入500条数据
def
writeData(t, n){
timev =
2018.10
.
08
T01:
01
:
01.000
+ timestamp(
1.
.n)
voltage =
1.
.n *
0.1
current =
1.
.n *
0.05
insert into t values(timev, voltage, current)
}
writeData(electricity,
500
);
聚合计算结果:
select *
from
outputTable2;
time
maxVoltage
maxCurrent
2018.10.08T01:01:01.100
8.45
4.225
2018.10.08T01:01:01.200
18.45
9.225
2018.10.08T01:01:01.300
28.45
14.225
2018.10.08T01:01:01.400
38.45
19.225
2018.10.08T01:01:01.500
48.45
24.225
若要对上述脚本进行重复使用,需先执行以下脚本以清除共享表、订阅以及流数据引擎:
unsubscribeTable(tableName=
"electricity"
, actionName=
"avgElectricity"
)
undef(`electricity, SHARED)
unsubscribeTable(tableName=
"outputTable1"
, actionName=
"maxElectricity"
)
undef(`outputTable1, SHARED)
dropStreamEngine(
"electricityAggregator1"
)
dropStreamEngine(
"electricityAggregator2"
)
示例5. 分组计算
下例中设定
keyColumn
参数为 sym,时序引擎将基于 sym 列对数据进行分组,然后在分组内进行窗口计算。
share streamTable(
1000
:
0
, `time`sym`volume, [TIMESTAMP, SYMBOL, INT])
as
trades
outputTable = table(
10000
:
0
, `time`sym`sumVolume, [TIMESTAMP, SYMBOL, INT])
tradesAggregator = createTimeSeriesEngine(name=
"streamAggr1"
, windowSize=
3
, step=
3
, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=outputTable, timeColumn=`time, useSystemTime=false, keyColumn=`sym, garbageSize=
50
)
subscribeTable(tableName=
"trades"
, actionName=
"append_tradesAggregator"
, offset=
0
, handler=append!{tradesAggregator}, msgAsTable=true)
def
writeData(t, n){
timev =
2018.10
.
08
T01:
01
:
01.001
+ timestamp(
1.
.n)
symv =take(`A`B, n)
volumev = take(
1
, n)
insert into t values(timev, symv, volumev)
}
writeData(trades,
6
)
为了方便观察,对
trades
表的 sym 列排序输出:
select *
from
trades order by sym
time
sym
volume
2018.10.08T01:01:01.002
A
1
2018.10.08T01:01:01.004
A
1
2018.10.08T01:01:01.006
A
1
2018.10.08T01:01:01.003
B
1
2018.10.08T01:01:01.005
B
1
2018.10.08T01:01:01.007
B
1
分组计算结果:
select *
from
outputTable
time
sym
sumVolume
2018.10.08T01:01:01.003
A
1
2018.10.08T01:01:01.006
A
1
2018.10.08T01:01:01.006
B
2
各组窗口规整后统一从 000 时间点开始,根据
windowSize
=3 以及
step
=3,每个组的窗口会按照
000-003-006 划分。
(1) 在 003,B组有一条数据,但是由于B组在第一个窗口没有任何数据,不会进行计算,所以B组第一个窗口没有结果输出。
(2) 004 的A组数据触发A组第一个窗口的计算。
(3) 006 的A组数据触发A组第二个窗口的计算。
(4) 007 的B组数据触发B组第二个窗口的计算。
如果进行分组聚合计算,流数据源中的每个分组中的 'timeColumn' 必须是递增的,但是整个数据源的 'timeColumn'
可以不是递增的;如果没有进行分组聚合,那么整个数据源的 'timeColumn' 必须是递增的,否则时序引擎的输出结果会与预期不符。
示例6. 设置
updateTime
参数,在窗口未结束前强制触发计算
时序聚合引擎如果没有指定
updateTime
,一个数据窗口结束前,不会发生对该数据窗口数据的计算。若一个窗口长时间未触发计算,可以指定
updateTime
,分多次触发当前窗口数据的计算。以下通过两个例子,帮助用户理解
updateTime
的作用。
首先创建流数据表并写入数据:
share streamTable(
1000
:
0
, `time`sym`volume, [TIMESTAMP, SYMBOL, INT])
as
trades
insert into trades values(
2018.10
.
08
T01:
01
:
01.785
,`A,
10
)
insert into trades values(
2018.10
.
08
T01:
01
:
02.125
,`B,
26
)
insert into trades values(
2018.10
.
08
T01:
01
:
10.263
,`B,
14
)
insert into trades values(
2018.10
.
08
T01:
01
:
12.457
,`A,
28
)
insert into trades values(
2018.10
.
08
T01:
02
:
10.789
,`A,
15
)
insert into trades values(
2018.10
.
08
T01:
02
:
12.005
,`B,
9
)
insert into trades values(
2018.10
.
08
T01:
02
:
30.021
,`A,
10
)
insert into trades values(
2018.10
.
08
T01:
04
:
02.236
,`A,
29
)
insert into trades values(
2018.10
.
08
T01:
04
:
04.412
,`B,
32
)
insert into trades values(
2018.10
.
08
T01:
04
:
05.152
,`B,
23
);
不指定
updateTime
:
output1 = table(
10000
:
0
, `time`sym`sumVolume, [TIMESTAMP, SYMBOL, INT])
agg1 = createTimeSeriesEngine(name=
"agg1"
, windowSize=
60000
, step=
60000
, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output1, timeColumn=`time, useSystemTime=false, keyColumn=`sym, garbageSize=
50
, useWindowStartTime=false)
subscribeTable(tableName=
"trades"
, actionName=
"agg1"
, offset=
0
, handler=append!{agg1}, msgAsTable=true)
sleep(
10
)
select *
from
output1;
time
sym
sumVolume
2018.10.08T01:02:00.000
A
38
2018.10.08T01:03:00.000
A
25
2018.10.08T01:02:00.000
B
40
2018.10.08T01:03:00.000
B
9
将
updateTime
设为 1000:
output2 = keyedTable(`time`sym,
10000
:
0
, `time`sym`sumVolume, [TIMESTAMP, SYMBOL, INT])
agg2 = createTimeSeriesEngine(name=
"agg2"
, windowSize=
60000
, step=
60000
, metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output2, timeColumn=`time, useSystemTime=false, keyColumn=`sym, garbageSize=
50
, updateTime=
1000
, useWindowStartTime=false)
subscribeTable(tableName=
"trades"
, actionName=
"agg2"
, offset=
0
, handler=append!{agg2}, msgAsTable=true)
sleep(
2010
)
select *
from
output2;
time
sym
sumVolume
2018.10.08T01:02:00.000
A
38
2018.10.08T01:03:00.000
A
25
2018.10.08T01:02:00.000
B
40
2018.10.08T01:03:00.000
B
9
2018.10.08T01:05:00.000
B
55
2018.10.08T01:05:00.000
A
29
下面我们介绍以上两个例子在处理最后一个数据窗口(01:04:00.000 到
01:05:00.000)的区别。为简便起见,我们省略日期部分,只列出(小时:分钟:秒.毫秒)部分。假设 time 列时间亦为数据进入时序引擎的时刻。
(注:(1) (3) 中的 2000 毫秒是系统在经过 2 倍 updateTime 后,仍有未处理数据时触发计算的时间间隔。)
(1) 在 01:04:02.236 时,A 分组的第一条记录到达后已经过 2000 毫秒,触发一次 A 组计算,输出表增加一条记录(01:05:00.000,
`A, 29)。
(2) 在 01:04:04.412 时,B 分组的记录到达,距离窗口左边界 01:04:00.000 已经过了 4412 毫秒(超过了
updateTime),因此触发一次 B 组计算,输出表增加一条记录 (01:05:00.000, "B", 32)。
(3) 在 01:04:07.152 时,系统发现 B 组的记录 01:04:05.152 已过了 2000 毫秒仍未参与计算,触发一次 B 组计算,因此输出表将
(01:05:00.000,"B",32) 记录更新为 (01:05:00.000, "B", 55)。
示例7. 为引擎开启快照
为引擎开启快照机制后,若引擎出现异常,可及时将它的状态恢复到最新的快照状态。以下例子,将帮助用户理解
snapshotDir
和
snapshotIntervalInMsgCount
的作用。如果启用
snapshot
,引擎订阅流表时(subscribeTable),
handler
必须是 appendMsg
函数,且必须指定
handlerNeedMsgId
=true,用来记录快照的消息位置。
share streamTable(
10000
:
0
,`time`sym`price`id, [TIMESTAMP,SYMBOL,INT,INT])
as
trades
output1 =table(
10000
:
0
, `time`sumprice, [TIMESTAMP,INT]);
Agg1 = createTimeSeriesEngine(name=`Agg1, windowSize=
100
, step=
50
, metrics=<sum(price)>, dummyTable=trades, outputTable=output1, timeColumn=`time, snapshotDir=
"/home/server1/snapshotDir"
, snapshotIntervalInMsgCount=
100
)
subscribeTable(server=
""
, tableName=
"trades"
, actionName=
"Agg1"
,offset=
0
, handler=appendMsg{Agg1}, msgAsTable=true, handlerNeedMsgId=true)
n=
500
timev=timestamp(
1.
.n) +
2021.03
.
12
T15:
00
:
00.000
symv = take(`abc`
def
, n)
pricev = int(
1.
.n)
id = take(-
1
, n)
insert into trades values(timev, symv, pricev, id)
select *
from
output1
time
sumprice
2021.03.12T15:00:00.050
1225
2021.03.12T15:00:00.100
4950
2021.03.12T15:00:00.150
9950
2021.03.12T15:00:00.200
14950
2021.03.12T15:00:00.250
19950
2021.03.12T15:00:00.300
24950
2021.03.12T15:00:00.350
29950
2021.03.12T15:00:00.400
34950
2021.03.12T15:00:00.450
39950
2021.03.12T15:00:00.500
44950
getSnapshotMsgId(Agg1)
>
499
取消订阅并删除引擎来模拟系统异常
unsubscribeTable(,
"trades"
,
"Agg1"
)
dropStreamEngine(
"Agg1"
)
Agg1=NULL
此时发布端仍在写入数据
n=
500
timev=timestamp(
501.
.1000
) +
2021.03
.
12
T15:
00
:
00.000
symv = take(`abc`
def
, n)
pricev = int(
1.
.n)
id = take(-
1
, n)
insert into trades values(timev, symv, pricev, id)
再次创建 Agg1, 加载 snapshot,从上次处理最后一条消息开始重新订阅
Agg1 = createTimeSeriesEngine(name=`Agg1, windowSize=
100
, step=
50
, metrics=<sum(price)>, dummyTable=trades, outputTable=output1, timeColumn=`time, snapshotDir=
"/home/server1/snapshotDir"
, snapshotIntervalInMsgCount=
100
)
ofst=getSnapshotMsgId(Agg1)
print
(ofst)
>
499
subscribeTable(server=
""
, tableName=
"trades"
, actionName=
"Agg1"
,offset=ofst+
1
, handler=appendMsg{Agg1}, msgAsTable=true, handlerNeedMsgId=true)
select *
from
output1
time
sumprice
2021.03.12T15:00:00.050
1225
2021.03.12T15:00:00.100
4950
2021.03.12T15:00:00.150
9950
2021.03.12T15:00:00.200
14950
2021.03.12T15:00:00.250
19950
2021.03.12T15:00:00.300
24950
2021.03.12T15:00:00.350
29950
2021.03.12T15:00:00.400
34950
2021.03.12T15:00:00.450
39950
2021.03.12T15:00:00.500
44950
2021.03.12T15:00:00.550
25450
2021.03.12T15:00:00.600
5450
2021.03.12T15:00:00.650
9950
2021.03.12T15:00:00.700
14950
2021.03.12T15:00:00.750
19950
2021.03.12T15:00:00.800
24950
2021.03.12T15:00:00.850
29950
2021.03.12T15:00:00.900
34950
2021.03.12T15:00:00.950
39950
2021.03.12T15:00:01.000
44950
结果和订阅不中断一样。
share streamTable(
10000
:
0
,`time`sym`price`id, [TIMESTAMP,SYMBOL,INT,INT])
as
trades
output1 =table(
10000
:
0
, `time`sumprice, [TIMESTAMP,INT]);
Agg1 = createTimeSeriesEngine(name=`Agg1, windowSize=
100
, step=
50
, metrics=<sum(price)>, dummyTable=trades, outputTable=output1, timeColumn=`time)
subscribeTable(server=
""
, tableName=
"trades"
, actionName=
"Agg1"
,offset=
0
, handler=append!{Agg1}, msgAsTable=true)
n=
500
timev=timestamp(
1.
.n) +
2021.03
.
12
T15:
00
:
00.000
symv = take(`abc`
def
, n)
pricev = int(
1.
.n)
id = take(-
1
, n)
insert into trades values(timev, symv, pricev, id)
n=
500
timev=timestamp(
501.
.1000
) +
2021.03
.
12
T15:
00
:
00.000
symv = take(`abc`
def
, n)
pricev = int(
1.
.n)
id = take(-
1
, n)
insert into trades values(timev, symv, pricev, id)
select *
from
output1
time
sumprice
2021.03.12T15:00:00.050
1225
2021.03.12T15:00:00.100
4950
2021.03.12T15:00:00.150
9950
2021.03.12T15:00:00.200
14950
2021.03.12T15:00:00.250
19950
2021.03.12T15:00:00.300
24950
2021.03.12T15:00:00.350
29950
2021.03.12T15:00:00.400
34950
2021.03.12T15:00:00.450
39950
2021.03.12T15:00:00.500
44950
2021.03.12T15:00:00.550
25450
2021.03.12T15:00:00.600
5450
2021.03.12T15:00:00.650
9950
2021.03.12T15:00:00.700
14950
2021.03.12T15:00:00.750
19950
2021.03.12T15:00:00.800
24950
2021.03.12T15:00:00.850
29950
2021.03.12T15:00:00.900
34950
2021.03.12T15:00:00.950
39950
2021.03.12T15:00:01.000
44950
如果不开启 snapshot,即使从上次中断的地方开始订阅,得到的结果也与订阅不中断不一样。
share streamTable(
10000
:
0
,`time`sym`price`id, [TIMESTAMP,SYMBOL,INT,INT])
as
trades
output1 =table(
10000
:
0
, `time`sumprice, [TIMESTAMP,INT]);
Agg1 = createTimeSeriesEngine(name=`Agg1, windowSize=
100
, step=
50
, metrics=<sum(price)>, dummyTable=trades, outputTable=output1, timeColumn=`time)
subscribeTable(server=
""
, tableName=
"trades"
, actionName=
"Agg1"
,offset=
0
, handler=append!{Agg1}, msgAsTable=true)
n=
500
timev=timestamp(
1.
.n) +
2021.03
.
12
T15:
00
:
00.000
symv = take(`abc`
def
, n)
pricev = int(
1.
.n)
id = take(-
1
, n)
insert into trades values(timev, symv, pricev, id)
unsubscribeTable(,
"trades"
,
"Agg1"
)
dropStreamEngine(
"Agg1"
)
Agg1=NULL
n=
500
timev=timestamp(
501.
.1000
) +
2021.03
.
12
T15:
00
:
00.000
symv = take(`abc`
def
, n)
pricev = int(
1.
.n)
id = take(-
1
, n)
insert into trades values(timev, symv, pricev, id)
Agg1 = createTimeSeriesEngine(name=`Agg1, windowSize=
100
, step=
50
, metrics=<sum(price)>, dummyTable=trades, outputTable=output1, timeColumn=`time)
subscribeTable(server=
""
, tableName=
"trades"
, actionName=
"Agg1"
,offset=
500
, handler=append!{Agg1}, msgAsTable=true)
select *
from
output1
time
sumprice
2021.03.12T15:00:00.050
1225
2021.03.12T15:00:00.100
4950
2021.03.12T15:00:00.150
9950
2021.03.12T15:00:00.200
14950
2021.03.12T15:00:00.250
19950
2021.03.12T15:00:00.300
24950
2021.03.12T15:00:00.350
29950
2021.03.12T15:00:00.400
34950
2021.03.12T15:00:00.450
39950
2021.03.12T15:00:00.500
44950
2021.03.12T15:00:00.550
1225
2021.03.12T15:00:00.600
4950
2021.03.12T15:00:00.650
9950
2021.03.12T15:00:00.700
14950
2021.03.12T15:00:00.750
19950
2021.03.12T15:00:00.800
24950
2021.03.12T15:00:00.850
29950
2021.03.12T15:00:00.900
34950
2021.03.12T15:00:00.950
39950
2021.03.12T15:00:01.000
44950
示例8. 过滤订阅数据
使用
subscribeTable
函数时,可利用
handler
参数过滤订阅的流数据。
在下例中,传感器采集电压和电流数据并实时上传作为流数据源,其中电压 voltage<=122 或电流 current=NULL
的数据需要在进入时序引擎之前过滤掉。下例中,通过
部分应用
将函数
append_after_filtering 的参数
inputTable
固定为 electricityAggregator,得到的一元函数
append_after_filtering{electricityAggregator}
仅接受参数
msg
。订阅收到的数据将作为
msg
传入
append_after_filtering{electricityAggregator}
进行处理。
share streamTable(
1000
:
0
, `time`voltage`current, [TIMESTAMP, DOUBLE, DOUBLE])
as
electricity
outputTable = table(
10000
:
0
, `time`avgVoltage`avgCurrent, [TIMESTAMP, DOUBLE, DOUBLE])
//自定义数据处理过程,过滤 voltage<=
122
或 current=NULL的无效数据。
def
append_after_filtering(inputTable, msg){
t = select *
from
msg where voltage>
122
, isValid(current)
if
(size(t)>
0
){
insert into inputTable values(t.time,t.voltage,t.current)
}
}
electricityAggregator = createTimeSeriesEngine(name=
"electricityAggregator"
, windowSize=
6
, step=
3
, metrics=<[avg(voltage), avg(current)]>, dummyTable=electricity, outputTable=outputTable, timeColumn=`time, garbageSize=
2000
)
subscribeTable(tableName=
"electricity"
, actionName=
"avgElectricity"
, offset=
0
, handler=append_after_filtering{electricityAggregator}, msgAsTable=true)
//模拟产生数据
def
writeData(t, n){
timev =
2018.10
.
08
T01:
01
:
01.001
+ timestamp(
1.
.n)
voltage =
120
+
1.
.n *
1.0
current = take([
1
,NULL,
2
]*
0.1
, n)
insert into t values(timev, voltage, current);
}
writeData(electricity,
10
)
流数据表:
select *
from
electricity
time
voltage
current
2018.10.08T01:01:01.002
121
0.1
2018.10.08T01:01:01.003
122
2018.10.08T01:01:01.004
123
0.2
2018.10.08T01:01:01.005
124
0.1
2018.10.08T01:01:01.006
125
2018.10.08T01:01:01.007
126
0.2
2018.10.08T01:01:01.008
127
0.1
2018.10.08T01:01:01.009
128
2018.10.08T01:01:01.010
129
0.2
2018.10.08T01:01:01.011
130
0.1
聚合计算结果:
select *
from
outputTable
time
avgVoltage
avgCurrent
2018.10.08T01:01:01.006
123.5
0.15
2018.10.08T01:01:01.009
125
0.15
由于 voltage<=122 或 current=NULL 的数据已经在进入时序引擎时被过滤了,所以第一个窗口 [000,003)
里没有数据,也就没有发生计算。
FILE:references/doc_7893.md
# where
**URL**: https://docs.dolphindb.cn/zh/progr/sql/where.html
**来源**: DolphinDB 官方文档
---
where
where 子句用于在查询语句中指定选择条件。
详情
若 SQL 语句中包含 where 子句,则查询数据的逻辑如下:
先读取 where 语句指定的列数据,然后按条件对其过滤;
再读取的结果所对应的其他列数据。
因此,为提高查询效率,当 where 子句过滤出的数据占总数据的比例较大时,可以通过指定 [HINT_PRELOAD] 预先加载所有数据到内存再进行过滤。
例子
在下例中,脚本创建一个包含证券交易信息的表,并显示该表的内容。
其中定义了四个变量:
sym: 代表证券代码,包括多个证券的代码。
price: 代表证券的价格,包括每个证券对应的价格。
qty: 代表证券的数量,包括每个证券对应的数量。
timestamp: 代表时间戳,包括了每个交易的时间。
接下来,脚本创建了一个名为 t1 的表,该表包含了 timestamp、sym、qty 和 price 列。最后,脚本输出了 t1 表的内容。
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t1 = table(timestamp, sym, qty, price);
t1;
得到:
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
where 子句包含一个条件时
执行以下查询语句:
select * from t1 where sym=`IBM;
得到:
timestamp
sym
qty
price
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
select * from t1 where timestamp.minute()>=09:36m;
得到:
timestamp
sym
qty
price
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:38:12
C
8800
51.29
注:
在 where 子句中,"==" 等于
"="。例如:
select * from t1 where sym==`IBM;
得到:
timestamp
sym
qty
price
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
where 子句包含多个条件时
执行以下查询语句:
select * from t1 where sym=`IBM and qty>=2000 or timestamp>09:37:00;
得到:
timestamp
sym
qty
price
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:38:12
C
8800
51.29
若多条件必须同时满足才能成立,则用 "and", "&&" 或 "," 连接;若只满足一个条件即可,则用
“or” 或 “||” 连接。
select * from t1 where qty>=2000, timestamp.minute()>=09:36m;
得到:
timestamp
sym
qty
price
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:38:12
C
8800
51.29
select * from t1 where qty>=2000 and timestamp.minute()>=09:36m;
得到:
timestamp
sym
qty
price
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:38:12
C
8800
51.29
select * from t1 where qty>=2000 && timestamp.minute()>=09:36m;
得到:
timestamp
sym
qty
price
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:38:12
C
8800
51.29
where 条件中包含函数时
下面的例子中,我们将价格高于平均价格的记录选择出来。这里对表中所有记录使用了函数avg。
select * from t1 where price>avg(price);
得到:
timestamp
sym
qty
price
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
要计算每个股票的平均价格,可以使用
c/contextby
。下面的例子查询每个股票的价格大于平均价格的记录。
select * from t1 where price>contextby(avg, price, sym) order by sym, price;
timestamp
sym
qty
price
09:34:16
C
1300
50.76
09:38:12
C
8800
51.29
09:35:26
IBM
5400
175.23
09:36:59
MS
3200
30.02
要随机抽取分区作为样本,只需在where子句中使用
sample
函数即可。
n=1000000
ID=rand(50, n)
x=rand(1.0, n)
t=table(ID, x)
db=database("dfs://rangedb1", RANGE, 0 10 20 30 40 50)
pt = db.createPartitionedTable(t, `pt, `ID)
pt.append!(t)
pt=loadTable(db,`pt);
pt 有 5 个分区,随机抽取两个分区的数据作为样本,可以使用下面的语句:
x = select * from pt where sample(ID, 0.4);
x = select * from pt where sample(ID, 2);
where 条件中包含 SQL 子句时
运行以下脚本:
t1 = table(`APPL`AMZN`IBM`IBM`AAPL`AMZN as sym, 2022.01.01 + 1..6 as date);
t2 = table(`APPL`AMZN`IBM`IBM`AAPL`AMZN as sym, 1.8 2.3 3.7 3.1 4.2 2.8 as price)
select count(*) from t1 where sym in select sym from t2 where price > 3
得到:3
运行以下脚本:
t3 = table(`APPL`AMZN`IBM`IBM`AAPL`AMZN as sym, 1.9 2.1 2.5 2.6 2.7 3.2 as price)
select * from t2 where price > select avg(price) from t3
得到:
sym
price
IBM
3.7
IBM
3.1
AAPL
4.2
AMZN
2.8
FILE:references/doc_7910.md
# semiannualBegin
**URL**: https://docs.dolphindb.cn/zh/funcs/s/semiannualBegin.html
**来源**: DolphinDB 官方文档
---
semiannualBegin
语法
semiannualBegin(X, [startingMonth=1], [offset],
[n=1])
详情
返回
X
所在半年期的第一天。每半年包含的月份由参数
startingMonth
决定。
如果指定了
offset
,表示从
offset
开始,结果每隔 n 个半年期更新一次。注意,
offset
和
n
须同时指定,且只有当
n
> 1 时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP 类型的标量或向量。
startingMonth
(可选参数)是 1 到 12 之间的整数,表示一年的起始月份。默认值是 1。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为 1。
返回值
DATE 类型标量或向量。
例子
semiannualBegin(2025.08.10);
// output: 2025.07.01
semiannualBegin(2025.10.10 10:10:10.008, 3);
// output: 2025.09.01
date=[2024.04.20,2024.05.31,2024.07.07,2024.10.24,2024.12.20,2025.01.19,2025.04.24,2025.04.28,2025.10.06,2026.01.06]
sym = take(`AAA,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, sym, qty, price)
select avg(price),sum(qty) from t1 group by semiannualBegin(date, 1, 2024.01.01, 2)
semiannualBegin_date
avg_price
sum_qty
2024.01.01
62.714
16,200
2025.01.01
81.9
18,000
2026.01.01
52.38
4,500
FILE:references/doc_7911.md
# prefix join
**URL**: https://docs.dolphindb.cn/zh/progr/sql/prefixjoin.html
**来源**: DolphinDB 官方文档
---
prefix join
语法
pj(leftTable, rightTable, matchingCols, [rightMatchingCols])
参数
leftTable
和
rightTable
是连接的表。
matchingCols
是一个字符串,表示连接列的名称。
rightMatchingCols
是一个字符串,表示右表连接列的名称。当
leftTable
和
rightTable
的连接列不同时,必须指定
rightMatchingCols
。返回结果中的连接列与左表的连接列名称相同。
详情
将左表连接列中以右表连接列内容开头的记录与相应的右表记录连接。如果左表中有多条匹配记录,pj会取所有匹配的记录。因此,pj返回结果的行数可能比右表的行数多。
注:
当左右表均为分布式表时,
pj
仅在分布式表的分区内部匹配数据。
pj和ej类似,它们的区别如下:
pj只能有一个连接列,且连接列必须是STRING或SYMBOL类型。
pj返回左表连接列中以右表连接列内容开头的记录。
例子
例1:两个表的连接列名称相同。
t1=table(["DT_1","DT2","BC.1","GB7T","AC/8","ACA9","DEF"] as id, 20.5 12.3 26.8 15.2 24.7 56.8 33.6 as price)
t2=table(["DT","BC","GB","AC", "TD"] as id,12 45 78 26 89 as qty);
t1;
id
price
DT_1
20.5
DT2
12.3
BC.1
26.8
GB7T
15.2
AC/8
24.7
ACA9
56.8
DEF
33.6
t2;
id
qty
DT
12
BC
45
GB
78
AC
26
TD
89
select * from pj(t1,t2,`id);
id
price
t2_id
qty
DT_1
20.5
DT
12
DT2
12.3
DT
12
BC.1
26.8
BC
45
GB7T
15.2
GB
78
AC/8
24.7
AC
26
ACA9
56.8
AC
26
例2:两个表的连接列名称不同。
t1=table(["DT_1","DT2","BC.1","GB7T","AC/8","ACA9","DEF"] as id, 20.5 12.3 26.8 15.2 24.7 56.8 33.6 as price)
t2=table(["DT","BC","GB","AC", "TD"] as prefix,12 45 78 26 89 as qty);
select * from pj(t1,t2,`id,`prefix);
id
price
prefix
qty
DT_1
20.5
DT
12
DT2
12.3
DT
12
BC.1
26.8
BC
45
GB7T
15.2
GB
78
AC/8
24.7
AC
26
ACA9
56.8
AC
26
FILE:references/doc_7913.md
# fmin
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fmin.html
**来源**: DolphinDB 官方文档
---
fmin
语法
fmin(func, X0, [xtol=0.0001],
[ftol=0.0001], [maxIter], [maxFun])
详情
使用 Nelder-Mead 单纯形算法找到目标函数的最小值。
注意:该算法只使用函数值,不使用一阶导数或二阶导数。
参数
func
函数名,表示需要最小化的目标函数。注意:函数返回值须是数值标量类型。
X0
数值类型的标量或向量,表示使目标函数最小化的参数的初始猜测。
xtol
可选参数,正数值标量,表示在迭代过程中
xopt
之间可接受的收敛的绝对误差。默认值为 0.0001。
ftol
可选参数,正数值标量,表示在迭代过程中
func(xopt)
的绝对误差可接受的收敛标准。默认值为
0.0001。
maxIter
可选参数,非负整数标量,表示执行的最大迭代次数。
maxFun
可选参数,非负整数标量,表示最大目标函数调用次数。
返回值
返回一个字典,包含以下成员:
xopt:浮点数向量,使目标函数最小化的参数值。
fopt:浮点数标量,目标函数最小值。fopt=func(xopt)。
iterations:整数标量,优化过程中执行的总迭代数。
fcalls:整数标量,优化过程中目标函数的调用次数。
warnFlag:整数标量,有三个可能值:
0:表示成功执行算法全过程。
1:表示已达最大目标函数调用次数,算法停止执行。
2:表示已达最大迭代次数,算法停止执行。
例子
下例中自定义一个 f(x) 函数,使用 Nelder-Mead 单纯形算法找到其最小值。
def f(x) {return x*x}
fmin(f, 1)
/* Ouput:
xopt->[-8.881784197001252E-16]
fopt->7.888609052210119E-31
iterations->17
fcalls->34
warnFlag->0
*/
FILE:references/doc_7930.md
# vanillaOption
**URL**: https://docs.dolphindb.cn/zh/funcs/v/vanillaoption.html
**来源**: DolphinDB 官方文档
---
vanillaOption
语法
vanillaOption(settlement, maturity, evalDate, spot, strike, riskFree,
divYield, volatility, isCall, style, basis, calendar, [method="BS"], [kwargs],
[mode=0])
详情
对香草期权(Vanilla Option)进行估值计算。
参数
settlement
DATE 类型标量或向量,表示期权交易日。
maturity
DATE 类型标量或向量,表示期权到期日。
evalDate
DATE 类型标量或向量,表示估值日。
spot
数值标量或向量,表示标的资产的当前价格。
strike
数值标量或向量,表示标的资产的行权价格。
riskFree
数值标量或向量,表示无风险利率。
divYield
数值标量或向量,表示分红利率。
volatility
数值标量或向量,表示波动率。
isCall
BOOL 标量或向量,表示是看涨期权还是看跌期权:
true:表示看涨期权(call option)。
false:表示看跌期权(put option)。
style
字符串标量或向量,表示可行权时间的类型,有两个可选值:
‘european’:表示欧式期权。
‘american’:表示美式期权。
basis
整型或 STRING 类型的标量或向量,表示要使用的日计数基准类型。可选值为:
Basis
日计数基准
0 / "Thirty360US"
US (NASD) 30/360
1 / "ActualActual" (默认值)
实际/实际
2 / "Actual360"
实际/360
3 / "Actual365"
实际/365
4 / "Thirty360EU"
欧洲 30/360
calendar
字符串类型标量或向量,表示使用的市场日历类型,请参阅
交易日历
。
method
可选参数,字符串标量,表示使用的期权估值方法,可选值有:
‘BS’:表示 Black-Scholes 方法,默认值,只能用于欧式期权估值。
'FDBS':表示结合有限差分法(Finite Difference Method, FDM)和 Black-Scholes 方法的数值求解方法。
'heston':表示 Heston 模型方法,只能用于欧式期权估值。
'FDHeston':表示结合有限差分法(Finite Difference Method, FDM)和 Heston 模型方法的数值求解方法。
'PTDHeston':表示分段时间依赖的 Heston 模型方法。分段时间依赖:Piecewise Time
Dependent,PTD。该方法只能用于欧式期权估值。
kwargs
可选参数,字典标量,表示期权估值的其他参数,不同的估值方法有不同的参数要求。当 method =
'BS'时无需填写该参数,其他方法的具体参数要求如下:
method = 'FDBS',kwargs应包含以下成员:
'xGrid':整数标量或向量,表示有限差分法在进行离散化时使用的空间网格数;xGrid 应大于 1。
'tGrid':整数标量或向量,表示有限差分法在进行离散化时使用的时间网格数。tGrid 应大于 0。
'dampingSteps':整数标量或向量,表示有限差分求解过程中应用的阻尼步骤数。dampingSteps 应大于等于 0。
method = 'heston',kwargs应包含以下成员:
'theta':数值标量或向量,表示波动率平方的长期均值。
'kappa':数值标量或向量,表示波动率平方的均值回归速度。
'rho':数值标量或向量,表示资产价格和波动率的相关系数。
'sigma':数值标量或向量,表示波动率的波动率。
method = 'FDHeston',kwargs 应包含以下成员:
'theta':数值标量或向量,表示波动率平方的长期均值。
'kappa':数值标量或向量,表示波动率平方的均值回归速度。
'rho':数值标量或向量,表示资产价格和波动率的相关系数。
'sigma':数值标量或向量,表示波动率的波动率。
'xGrid':整数标量或向量,表示有限差分法在进行离散化时使用的空间网格数;xGrid 应大于 1。
'vGrid':整数标量或向量,表示有限差分法在进行离散化时使用的波动率网格数;vGrid 应大于 1。
'tGrid':整数标量或向量,表示有限差分法在进行离散化时使用的时间网格数;tGrid 应大于等于 0。
'dampingSteps':整数标量或向量,表示有限差分求解过程中应用的阻尼步骤数。dampingSteps 应大于等于 0。
method = 'PTDHeston',kwargs 应包含以下成员:
'times':数值向量或数组向量,表示条件发生变化的时间点。
'theta':数值向量或数组向量,表示各时间点对应的波动率平方的长期均值。
'kappa':数值向量或数组向量,表示各时间点对应的波动率平方的均值回归速度。
'rho':数值向量或数组向量,表示各时间点对应的资产价格和波动率的相关系数。
'sigma':数值向量或数组向量,表示各时间点对应的波动率的波动率。
注意:所有成员长度应保持一致。
mode
选参数,整型标量或向量,表示输出的模式,可选值为:
0:只输出期权净现值(npv only),默认值。
1:输出期权的净现值和希腊字母,用元组存储,每个元组中依次存放 npv, delta, gamma, theta, vega 和 rho。
2:输出期权的净现值和希腊字母,用有序字典存储。
注意:如果输入参数中,部分为标量,其余为向量时,则会将标量当作与向量长度相同,所有元素值等于该标量的向量。所有向量的长度必须一致。
返回值
当 mode=0,返回一个浮点数标量或向量,表示期权的净现值。
当 mode=1,返回一个浮点数tuple或浮点数tuple构成的向量,表示期权定价结果,包含期权的净现值和希腊字母,顺序是 npv,
delta, gamma, theta, vega 和 rho。
当 mode=2,返回一个字典标量,表示期权定价结果,包含期权的净现值和希腊字母。
'npv':DOUBLE 类型标量或向量,表示期权的净现值。
'delta':DOUBLE 类型标量或向量,希腊字母 Delta 衡量期权价格对标的资产价格小幅变化的敏感度。
'gamma':DOUBLE 类型标量或向量,希腊字母 Gamma 衡量 Delta 随标的资产价格变化的速率。
'theta':DOUBLE 类型标量或向量,希腊字母 Theta 衡量期权价格随时间流逝(时间衰减)的敏感度。
'vega':DOUBLE 类型标量或向量,希腊字母 Vega 衡量期权价格对标的资产隐含波动率小幅变化的敏感度。
'rho':DOUBLE 类型标量或向量,希腊字母 Rho 衡量期权价格对无风险利率小幅变化的敏感度。
例子
例1 使用 BS 方法进行估值
本例对 1998 年 5 月 17 日至 1999 年 5 月 17 日的期权交易,估值日在 1998 年 5 月 15 日;标的资产的当前价格为 36,行权价格为
40;无风险利率为 6%,无分红,波动率为 2%;可行权时间的类型为欧式看跌期权;使用实际/365 的日计数基准类型,中金所交易日历;使用 Black-Scholes
方法,输出期权的净现值和希腊字母的设定下,对其进行估值计算。
settlement = 1998.05.17
maturity = 1999.05.17
valDay = 1998.05.15
spot = 36
strike = 40
riskFree = 0.06
dividend = 0
volatility = 0.2
isCall = false
style = 'european'
basis = 3
calendar = 'CCFX'
vanillaOption(settlement, maturity, valDay, spot, strike, riskFree, dividend, volatility, isCall, style, basis, calendar, mode=2)
/* Output:
npv->[2.080759333948596,2.080759333948596]
delta->[-0.727790750119184,-0.727790750119184]
gamma->[0.130419967911091,0.130419967911091]
theta->[1.274320988976569,1.274320988976569]
vega->[11.951706726567239,11.951706726567239]
rho->[-28.281226338239189,-28.281226338239189]
*/
例2 使用 PTDHeston 方法进行估值
本例对 1998 年 5 月 17 日至 1999 年 5 月 17 日的期权交易,估值日在 1998 年 5 月 15 日;标的资产的当前价格为 36,行权价格为
40;无风险利率为 6%,无分红,波动率为 2%;可行权时间的类型为欧式看跌期权;使用实际/365 的日计数基准类型,中金所、上交所交易日历;使用 PTDHeston
方法并传入相关参数,只输出期权净现值的设定下,对其进行估值计算。
settlement = 1998.05.17
maturity = 1999.05.17
valDay = 1998.05.15
spot = 36
strike = 40
riskFree = 0.06
dividend = 0
isCall = false
times = array(DOUBLE[], 0).append!( [1.0 2.0 3.0, 1.0 2.0 3.0])
volatility = 0.07071
style = 'european'
basis = 3
theta = [0.010, 0.015, 0.02]
kappa = [0.600, 0.500, 0.400]
sigma = [0.400, 0.350, 0.300]
rho = [-0.15, -0.10, -0.00]
calendar = 'CCFX' 'XSHG'
kwargs = dict(STRING,ANY)
kwargs[`times] = times
kwargs[`theta] = theta
kwargs[`kappa] = kappa
kwargs[`sigma] = sigma
kwargs[`rho] = rho
method = 'PTDHeston'
vanillaOption(settlement, maturity, valDay, spot, strike, riskFree, dividend, volatility, isCall, style, basis, calendar, method, kwargs)
// Output: [1.99693345461036,1.99693345461036]
FILE:references/doc_7941.md
# resample
**URL**: https://docs.dolphindb.cn/zh/funcs/r/resample.html
**来源**: DolphinDB 官方文档
---
resample
语法
resample(X, rule, func, [closed], [label],
[origin='start_day'])
详情
依照指定时间频率(或交易日历),对给定数据使用给定函数。注意,
rule
指定为交易日历标识时,对于非交易日的数据,将并入上一个交易日计算。
参数
X
是一个带有行标签的矩阵或序列(indexed series)。行标签要求为时间类型,不得含有空值,且必须保持递增。
rule
是一个字符串,可取以下值:
rule 参数取值
对应 DolphinDB 函数
"B"
businessDay
"W"
weekEnd
"WOM"
weekOfMonth
"LWOM"
lastWeekOfMonth
"M"
monthEnd
"MS"
monthBegin
"BM"
businessMonthEnd
"BMS"
businessMonthBegin
"SM"
semiMonthEnd
"SMS"
semiMonthBegin
"Q"
quarterEnd
"QS"
quarterBegin
"BQ"
businessQuarterEnd
"BQS"
businessQuarterBegin
"REQ"
fy5253Quarter
"A"
yearEnd
"AS"
yearBegin
"BA"
businessYearEnd
"BAS"
businessYearBegin
"RE"
fy5253
"D"
date
"H"
hourOfDay
"U"
microsecond
"L"
millisecond
"min"
minuteOfHour
"N"
nanosecond
"S"
secondOfMinute
"SA"
semiannualEnd
"SAS"
semiannualBegin
上述字符串亦可配合使用数字(必须为正整数),例如 "2M" 表示频率为每两个月月末。此外,
rule
也可以是交易日历标识(国外交易所的 ISO
Code、国内交易所简称或自定义交易日历名称),以便基于交易日历进行计算。交易日历也可以配合使用数字,表示多个交易日,此时只能指定由4个大写字母组成的交易日历标识。例如:“2XSHG”,表示上海证券交易所每两个交易日。
func
一个聚合函数。
closed
字符串,表示分组区间哪一个边界是闭合的。
rule
为 'M', 'A', 'Q', 'BM', 'BA', 'BQ' 和 'W'
时,
closed
的默认取值为 'right' ,否则,
closed
的默认取值为 'left'。
origin
取 'end' 或者 'end_day' 时,
closed
的默认值为 'right'。
label
字符串,表示将分组区间的哪一个边界作为
label
输出。
rule
为 'M', 'A', 'Q', 'BM', 'BA', 'BQ' 和 'W'
时,
label
的默认取值为 'right' ,否则,
label
的默认取值为 'left'。
origin
取 'end' 或者 'end_day' 时,
label
的默认值为 'right'。
origin
字符串或与
X
具有相同时间类型的标量,表示基于时间戳调整分组。
origin
的取值为 'epoch', start', 'start_day', 'end', 'end_day' 或自定义的时间对象,默认值为 'start_day'。
'epoch':分组起始点为1970-01-01。
'start':分组起始点为时间序列的第一个值。
'start_day':分组起始点是时间序列的第一个值对应日期的午夜零点。
'end':分组起始点是时间序列的最后一个时间戳。
'end_day':分组起始点是时间序列的最后一个时间戳对应日期的午夜24点(即下一日的零点)。
返回值
返回一个行标签的矩阵或序列。
例子
index = [2000.01.01, 2000.01.31, 2000.02.15, 2000.02.20, 2000.03.12, 2000.04.16, 2000.05.06, 2000.08.30]
s = indexedSeries(index, 1..8)
s.resample("M", sum);
col1
2000.01.31
3
2000.02.29
7
2000.03.31
5
2000.04.30
6
2000.05.31
7
2000.06.30
2000.07.31
2000.08.31
8
s.resample("2M", last);
col1
2000.01.31
2
2000.03.31
5
2000.05.31
7
2000.07.31
2000.09.30
8
index = temporalAdd(2022.01.01 00:00:00,1..8,`m)
s = indexedSeries(index, 1..8)
s.resample(rule=`3min, func=sum);
label
col1
2022.01.01T00:00:00
3
2022.01.01T00:03:00
12
2022.01.01T00:06:00
21
s.resample(rule=`3min, func=sum, closed=`right);
label
col1
2022.01.01T00:00:00
6
2022.01.01T00:03:00
15
2022.01.01T00:06:00
15
s.resample(rule=`3min, func=sum, closed=`left,origin=`end);
label
col1
2022.01.01T00:02:00
1
2022.01.01T00:05:00
9
2022.01.01T00:08:00
18
2022.01.01T00:11:00
8
s.resample(rule=`3min, func=sum,origin=2022.10.01 00:00:10)
label
col1
2022.01.01T00:00:10
6
2022.01.01T00:03:10
15
2022.01.01T00:06:10
15
m = matrix(1..5, 1..5)
index = temporalAdd(2000.01.01, [1, 1, 2, 2, 3], "d")
m.rename!(index, `A`B);
m.resample(rule=`D, func=sum);
label
A
B
2000.01.02
3
3
2000.01.03
7
7
2000.01.04
5
5
FILE:references/doc_7967.md
# crmwCBond
**URL**: https://docs.dolphindb.cn/zh/funcs/c/crmwcbond.html
**来源**: DolphinDB 官方文档
---
crmwCBond
语法
crmwCBond(settlement, maturity, fv, ys, yd)
详情
本函数使用
中债估值方法
,对标的债务为到期一次还本付息的短期债券的信用风险缓释凭证(Credit
Risk Mitigation Warrant, CRMW)进行估值。
参数
settlement
DATE 类型标量或向量,表示 CRMW 的估值日。
maturity
DATE 类型标量或向量,表示标的债券的到期日。
注意:
settlement
应早于对应的
maturity
。
fv
数值型标量或向量,非负数,表示标的债券到期时还本付息总金额。
ys
数值型标量或向量,非负数,表示 CRMW 创设机构估价收益率。
yd
数值型标量或向量,非负数,表示标的债券的估价收益率。
注意:如果输入参数中,部分为标量,其余为向量时,则会将标量当作与向量长度相同、所有元素值等于该标量的向量;且所有向量的长度必须一致。
返回值
成功执行后将返回 CRMW 的估值价格,是一个 DOUBLE 类型的标量或向量。
例子
假设 CRMW 的标的债券到期日为 2024 年 9 月 1 日,到期时还本付息总金额为 105,CRMW 创设机构估价收益率为 5.3%,标的债券的估价收益率
5.8%。估值日为 2024 年 3 月 1
日。
crmwCBond(settlement=2024.03.01, maturity=2024.09.01, fv=105, ys=0.053, yd=0.058)
// Output: 0.249800655
FILE:references/doc_7968.md
# isSorted
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isSorted.html
**来源**: DolphinDB 官方文档
---
isSorted
语法
isSorted(X, [ascending=true])
详情
检查
X
是否有序。
参数
X
是一个向量。
ascending
是布尔值,表示
X
按升序排序(true)或降序排序(false)。默认值为 true。
返回值
布尔标量。
例子
x=NULL 1 2 3
isSorted(x);
// output: true
t=table(9 7 5 3 as x, 1 5 2 4 as y)
t.x.isSorted(false);
// output: true
t.y.isSorted();
// output: false
FILE:references/doc_7984.md
# 单服务器集群部署与升级
**URL**: https://docs.dolphindb.cn/zh/tutorials/single_machine_cluster_deploy.html
**来源**: DolphinDB 官方文档
---
单服务器集群部署与升级
DolphinDB 集群包括四种类型节点:控制节点(controller),代理节点(agent),数据节点(datanode)和计算节点(compute node)。
控制节点
:控制节点是 DolphinDB 集群的核心部分,负责收集代理节点和数据节点的心跳,监控每个节点的工作状态,管理分布式文件系统的元数据和事务日志。单服务器集群中只有一个控制节点。
代理节点
:代理节点负责执行控制节点发出的启动和关闭数据节点或计算节点的命令。在一个集群中,每台物理服务器有且仅有一个代理节点。
数据节点
:数据节点既可以存储数据,也可以用于数据的查询和计算。每台物理服务器可以配置多个数据节点。
计算节点
:计算节点承担数据节点查询和计算的相关职能,负责响应客户端的请求并返回结果,与数据节点共同实现存储资源和计算资源有效隔离。每台物理服务器可以配置零到多个计算节点。
本教程用于单服务器集群的部署、升级、过期 License 升级,并对常见问题做出解答,便于用户快速上手 DolphinDB。包含以下主题:
在 Linux 操作系统部署 DolphinDB 单服务器集群
使用 DolphinDB 安装包默认集群配置文件,部署一个最简单的单服务器集群:1 个控制节点,1 个代理节点,1 个数据节点,1 个计算节点。
第一步:下载
官方下载地址:https://dolphindb.cn/product#downloads
也可以通过 Shell 指令下载。下载方式如下:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_Vrelease.zip -O dolphindb.zip
其中,
release
代表版本。例如:下载 2.00.11.3 版本的 Linux64 server,使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_V2.00.11.3.zip -O dolphindb.zip
如需下载 ABI 或 JIT 版本 server,则需要在版本号后以下划线连接 ABI 或 JIT。例如:下载 2.00.11.3 版本的 Linux64 ABI server, 使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_V2.00.11.3_ABI.zip -O dolphindb.zip
下载 2.00.11.3 版本的 Linux64 JIT 版本 server,使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_V2.00.11.3_JIT.zip -O dolphindb.zip
以此类推。
执行以下 Shell 指令解压安装包至指定路径(
/path/to/directory
):
unzip dolphindb.zip -d </path/to/directory>
注意
:安装路径的目录名中不能含有空格字符或中文字符,否则启动数据节点时会失败。
第二步:更新软件授权许可
如果用户拿到企业版试用授权许可,只需用其替换如下文件即可。
/DolphinDB/server/dolphindb.lic
如果用户没有申请企业版试用授权许可,可以直接使用程序包中的社区版试用授权许可。社区试用版指定 DolphinDB 单节点最大可用内存为 8 GB ,有效期为 20 年。
第三步:启动集群
进入
/DolphinDB/server
目录,第一次启动时需要修改文件权限,执行以下 Shell 指令:
chmod +x dolphindb
进入
/DolphinDB/server/clusterDemo
目录,启动控制节点和代理节点,启动顺序无要求。
启动控制节点
执行以下 Shell 指令启动控制节点:
sh startController.sh
启动代理节点
运行以下 Shell 指令启动代理节点:
sh startAgent.sh
可以执行以下 Shell 指令,查看节点是否成功启动:
ps aux|grep dolphindb
返回如下信息说明控制节点和代理节点启动成功:
启动数据节点和计算节点
可以在 Web 管理界面启动或关闭数据节点和计算节点,以及修改集群的配置。在浏览器中输入部署服务器 IP 地址和控制节点部署端口号即可进入 Web 管理界面,教程中的部署服务器 IP 地址为 10.0.0.80,控制节点默认部署端口为 8900,所以访问地址为 10.0.0.80:8900 ,打开后的 Web 管理界面如下。以管理员身份(默认账号:admin ,默认密码:123456)登录 Web 管理界面后,用户可以通过勾选想要启动的数据节点和计算节点,再点击启动(关闭)按键即可启动(关闭)相应的数据节点和计算节点:
刷新页面后可看到对应的数据节点和计算节点已启动,如下图所示:
注意
:如果浏览器与 DolphinDB 不是部署在同一台服务器,应事先关闭防火墙或者打开对应的部署端口,Web 管理界面才能正常打开。
第四步:连接数据节点创建数据库和分区表
数据节点既可以存储数据,也可以用于数据的查询和计算。接下来通过一个例子介绍如何在 DolphinDB 集群数据节点创建数据库并写入数据。首先,打开控制节点的 Web 管理界面,点击对应的数据节点打开其 Web 交互编程界面,如下图所示:
也可以在浏览器直接输入数据节点的 IP 地址和端口号进入数据节点的 Web 交互编程界面。
在数据节点的 Web 交互编程界面执行以下语句创建数据库和分区表:
// 创建存储的数据库和分区表
login("admin", "123456")
dbName = "dfs://testDB"
tbName = "testTB"
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db = database(dbName, VALUE, 2021.01.01..2021.12.31)
colNames = `SecurityID`DateTime`PreClosePx`OpenPx`HighPx`LowPx`LastPx`Volume`Amount
colTypes = [SYMBOL, DATETIME, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, INT, DOUBLE]
schemaTable = table(1:0, colNames, colTypes)
db.createPartitionedTable(table=schemaTable, tableName=tbName, partitionColumns=`DateTime)
然后,执行以下语句模拟生成 5000 个股票 1 天的 1 分钟 K 线数据并写入上面创建的分区表:
// 模拟数据并写入分区表
n = 1210000
randPrice = round(10+rand(1.0, 100), 2)
randVolume = 100+rand(100, 100)
SecurityID = lpad(string(take(0..4999, 5000)), 6, `0)
DateTime = (2023.01.08T09:30:00 + take(0..120, 121)*60).join(2023.01.08T13:00:00 + take(0..120, 121)*60)
PreClosePx = rand(randPrice, n)
OpenPx = rand(randPrice, n)
HighPx = rand(randPrice, n)
LowPx = rand(randPrice, n)
LastPx = rand(randPrice, n)
Volume = int(rand(randVolume, n))
Amount = round(LastPx*Volume, 2)
tmp = cj(table(SecurityID), table(DateTime))
t = tmp.join!(table(PreClosePx, OpenPx, HighPx, LowPx, LastPx, Volume, Amount))
dbName = "dfs://testDB"
tbName = "testTB"
loadTable(dbName, tbName).append!(t)
可以在交互编程界面选中函数语句跳转至弹出的网页查看函数说明。
语句执行成功后可在交互编程界面的左边,
数据库
一栏查看已创建的库表及字段信息。
也可在
本地变量
一栏查看已创建的变量和表,展示了变量名、变量类型、变量维度大小、占用内存大小等信息,并且可以直接点击变量名进行变量预览。
第五步:连接计算节点进行查询和计算
计算节点主要用于数据的查询和计算。接下来通过一个例子介绍如何在计算节点对数据库内的分区表执行查询和计算。首先,打开控制节点的 Web 管理界面,点击对应的计算节点打开其 Web 交互编程界面,如下图所示:
也可以在浏览器直接输入计算节点的 IP 地址和端口号进入计算节点的 Web 交互编程界面。
在计算节点的 Web 交互编程界面执行以下语句加载分区表对象,此时只加载了分区表的元数据,并未加载分区表全量数据,所以响应时间非常快:
// 加载分区表对象
pt = loadTable("dfs://testDB", "testTB")
然后,执行以下语句查询股票表中每天包含的数据条数:
// SQL 返回数据量少的时候,可以直接取回客户端展示
select count(*) from pt group by date(DateTime) as Date
语句执行成功后,查询结果会在 Web 界面下方展示:
执行以下语句计算每支股票每天的 OHLC 值:
// SQL 返回数据量较大时,可以赋值给变量,占用 server 端内存,客户端分页取回展示
result = select first(LastPx) as Open, max(LastPx) as High, min(LastPx) as Low, last(LastPx) as Close from pt group by date(DateTime) as Date, SecurityID
在这里,把计算结果赋值给了
result
变量,这样就不会直接在客户端界面直接展示,减少客户端内存占用,用户可以通过点击
本地变量
栏目下的
result
变量进行分页展示查看:
在 Windows 操作系统部署 DolphinDB 单服务器集群
使用 DolphinDB 安装包默认集群配置文件,部署一个最简单的单服务器集群:1 个控制节点,1 个代理节点,1 个数据节点,1 个计算节点。
第一步:下载
官方下载地址:
http://www.dolphindb.cn/downloads.html
解压安装包,例如解压到如下目录:
C:\DolphinDB
注意
:安装路径的目录名中不能含有空格字符或中文字符,否则启动数据节点时会失败。例如不要装到 Windows 系统的
Program Files
目录下。
第二步:更新软件授权许可
如果用户拿到企业版试用授权许可,只需用其替换如下文件即可。
C:\DolphinDB\server\dolphindb.lic
如果用户没有申请企业版试用授权许可,可以直接使用程序包中的社区版试用授权许可。社区试用版指定 DolphinDB 单节点最大可用内存为 8 GB,有效期为 20 年。
第三步:启动集群
前台启动控制节点和代理节点
进入
C:\DolphinDB\server\clusterDemo
目录,双击
startController.bat
启动控制节点,双击
startAgent.bat
启动代理节点。
后台启动控制节点和代理节点
进入
C:\DolphinDB\server\clusterDemo
目录,双击
backgroundStartController.vbs
启动控制节点,双击
backgroundStartAgent.vbs
启动代理节点。
启动数据节点和计算节点
可以在 Web 管理界面启动或关闭数据节点和计算节点,以及修改集群的配置。在浏览器中输入部署服务器 IP 地址和控制节点部署端口号即可进入 Web 管理界面,教程中的部署服务器 IP 地址为 10.0.0.80,控制节点默认部署端口为 8900,所以访问地址为 10.0.0.80:8900,打开后的 Web 管理界面如下。以管理员身份(默认账号:admin ,默认密码:123456)登录 Web 管理界面后,用户可以通过勾选想要启动的数据节点和计算节点,再点击启动(关闭)按键即可启动(关闭)相应的数据节点和计算节点:
刷新页面后可看到对应的数据节点和计算节点已启动,如下图所示:
注意
:如果浏览器与 DolphinDB 不是部署在同一台服务器,应事先关闭防火墙或者打开对应的部署端口,Web 管理界面才能正常打开。
第四步:连接数据节点创建数据库和分区表
数据节点既可以存储数据,也可以用于数据的查询和计算。接下来通过一个例子介绍如何在 DolphinDB 集群数据节点创建数据库并写入数据。首先,打开控制节点的 Web 管理界面,点击对应的数据节点打开其 Web
交互编程
界面,如下图所示:
也可以在浏览器直接输入数据节点的 IP 地址和端口号进入数据节点的 Web 交互编程界面。
在数据节点的 Web 交互编程界面执行以下语句创建数据库和分区表:
// 创建存储的数据库和分区表
login("admin", "123456")
dbName = "dfs://testDB"
tbName = "testTB"
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db = database(dbName, VALUE, 2021.01.01..2021.12.31)
colNames = `SecurityID`DateTime`PreClosePx`OpenPx`HighPx`LowPx`LastPx`Volume`Amount
colTypes = [SYMBOL, DATETIME, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, INT, DOUBLE]
schemaTable = table(1:0, colNames, colTypes)
db.createPartitionedTable(table=schemaTable, tableName=tbName, partitionColumns=`DateTime)
然后,执行以下语句模拟生成 5000 个股票 1天的 1 分钟 K 线数据并写入上面创建的分区表:
// 模拟数据并写入分区表
n = 1210000
randPrice = round(10+rand(1.0, 100), 2)
randVolume = 100+rand(100, 100)
SecurityID = lpad(string(take(0..4999, 5000)), 6, `0)
DateTime = (2023.01.08T09:30:00 + take(0..120, 121)*60).join(2023.01.08T13:00:00 + take(0..120, 121)*60)
PreClosePx = rand(randPrice, n)
OpenPx = rand(randPrice, n)
HighPx = rand(randPrice, n)
LowPx = rand(randPrice, n)
LastPx = rand(randPrice, n)
Volume = int(rand(randVolume, n))
Amount = round(LastPx*Volume, 2)
tmp = cj(table(SecurityID), table(DateTime))
t = tmp.join!(table(PreClosePx, OpenPx, HighPx, LowPx, LastPx, Volume, Amount))
dbName = "dfs://testDB"
tbName = "testTB"
loadTable(dbName, tbName).append!(t)
可以在交互编程界面选中函数语句跳转至弹出的网页查看函数说明。
语句执行成功后可在交互编程界面的左边,
数据库
一栏查看已创建的库表及字段信息。
也可在
本地变量
一栏查看已创建的变量和表,展示了变量名、变量类型、变量维度大小、占用内存大小等信息,并且可以直接点击变量名进行变量预览。
第五步:连接计算节点查询和计算
计算节点主要用于数据的查询和计算。接下来通过一个例子介绍如何在计算节点对数据库内的分区表执行查询和计算。首先,打开控制节点的 Web 管理界面,点击对应的计算节点打开其 Web
交互编程
界面,如下图所示:
也可以在浏览器直接输入计算节点的 IP 地址和端口号进入计算节点的 Web 交互编程界面。
在计算节点的 Web 交互编程界面执行以下语句加载分区表对象,此时只加载了分区表的元数据,并未加载分区表全量数据,所以响应时间非常快:
// 加载分区表对象
pt = loadTable("dfs://testDB", "testTB")
然后,执行以下语句查询股票表中每天包含的数据条数:
// SQL 返回数据量少的时候,可以直接取回客户端展示
select count(*) from pt group by date(DateTime) as Date
语句执行成功后,查询结果会在 Web 界面下方展示:
执行以下语句计算每支股票每天的 OHLC 值:
// SQL 返回数据量较大时,可以赋值给变量,占用 server 端内存,客户端分页取回展示
result = select first(LastPx) as Open, max(LastPx) as High, min(LastPx) as Low, last(LastPx) as Close from pt group by date(DateTime) as Date, SecurityID
在这里,将计算结果赋值给了
result
变量,这样就不会直接在客户端界面直接展示,减少客户端内存占用,用户可以通过点击
本地变量
栏目下的
result
变量进行分页展示查看:
集群升级
Linux 集群升级
第一步:正常关闭集群所有节点
进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
./stopAllNode.sh
第二步:备份旧版本的元数据文件
单服务器集群只有写入过数据才会创建相应的元数据文件,如果集群没有数据写入行为则可直接跳过此步骤进行升级。
备份控制节点元数据
控制节点元数据默认存储在服务器的
/DolphinDB/server/clusterDemo/data
目录下的
DFSMetaLog.0
文件,如果数据量超过一定的大小则还会生成
DFSMasterMetaCheckpoint.0
文件。本教程示例集群的控制节点元数据的默认存储目录:
/DolphinDB/server/clusterDemo/data
可进入
/DolphinDB/server/clusterDemo/data
目录执行以下 Shell 指令进行备份:
mkdir backup
cp -r DFSMetaLog.0 backup
cp -r DFSMasterMetaCheckpoint.0 backup
备份数据节点元数据
数据节点的元数据默认存储在控制节点服务器的
/DolphinDB/server/clusterDemo/data/数据节点别名/storage/CHUNK_METADATA
目录下,本教程示例集群的数据节点元数据的默认存储目录:
/DolphinDB/server/clusterDemo/data/dnode1/storage/CHUNK_METADATA
可进入上述目录执行以下 Shell 指令备份到上面创建的
backup
文件夹:
cp -r CHUNK_METADATA ../../backup
注意
:元数据文件可能通过配置文件指定存储在其它目录,如果在默认路径没有找到上述文件,可以通过查询配置文件中的
dfsMetaDir
参数和
chunkMetaDir
参数确认元数据文件的存储目录。若配置中未指定
dfsMetaDir
参数和
chunkMetaDir
参数,但是配置了
volumes
参数,
CHUNK_METADATA
目录在相应的
volumes
参数指定的目录下。
第三步:升级
当 server 在线升级到某个版本后,使用的插件也应升级到与此对应的版本。
在线升级
进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
./upgrade.sh
运行后将会出现如下提示:
输入 y 并点击回车后会出现如下提示:
输入 1 选择在线更新,并点击回车后会出现如下提示:
输入所需更新的版本号再点击回车即可,以更新至 2.00.9.1 版本为例,输入 2.00.9.1 后点击回车,出现如下界面则表示升级成功:
离线升级
下载升级所需版本的安装包,官方下载地址:
http://www.dolphindb.cn/downloads.html
将下载好的安装包上传至
/DolphinDB/server/clusterDemo
目录下,以更新至 2.00.9.1 版本为例:
进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
./upgrade.sh
运行后将会出现如下提示:
输入 y 并点击回车后会出现如下提示:
输入 2 选择离线更新,并点击回车后会出现如下提示:
输入所需更新的版本号再点击回车即可,以更新至 2.00.9.1 版本为例,输入 2.00.9.1 后点击回车,出现如下界面则表示升级成功:
如所需更新的版本是 JIT 或 ABI 版本,则版本号应与安装包保持一致。例如,安装包名称是"DolphinDB_Linux64_V2.00.9.1_JIT.zip"时,需要输入的版本号是"2.00.9.1_JIT"。
第四步:重新启动集群
进入
/DolphinDB/server/clusterDemo
目录,启动控制节点和代理节点,启动顺序无要求。
启动控制节点
执行以下 Shell 指令启动控制节点:
sh startController.sh
启动代理节点
运行以下 Shell 指令启动代理节点:
sh startAgent.sh
成功启动后,打开控制节点 Web 管理界面,在交互编程界面执行以下代码,查看 DolphinDB 当前版本:
version()
Windows 集群升级
第一步:正常关闭集群所有节点
如果是前台运行,关闭前台程序窗口
如果是后台运行,打开 Windows 任务管理器,找到 DolphinDB 的后台进程并关闭
第二步:备份旧版本的元数据文件
单服务器集群只有写入过数据才会创建相应的元数据文件,如果集群没有数据写入行为则可直接跳过此步骤进行升级。
备份控制节点元数据
控制节点元数据默认存储在服务器的
C:\DolphinDB\server\clusterDemo\data
目录下的
DFSMetaLog.0
文件,如果数据量超过一定的大小则还会生成
DFSMasterMetaCheckpoint.0
文件。本教程示例集群的控制节点元数据的默认存储目录:
C:\DolphinDB\server\clusterDemo\data
在该目录下创建文件夹
backup
,然后把
C:\DolphinDB\server\clusterDemo\data
文件夹下的
DFSMetaLog.0
文件及
DFSMasterMetaCheckpoint.0
文件复制到上面创建的
backup
文件夹下,如下图所示:
备份数据节点元数据
数据节点的元数据默认存储在服务器的
C:\DolphinDB\server\clusterDemo\data\数据节点别名\storage\CHUNK_METADATA
目录下,本教程示例集群的数据节点元数据的默认存储目录:
C:\DolphinDB\server\clusterDemo\data\dnode1\storage\CHUNK_METADATA
把
C:\DolphinDB\server\clusterDemo\data\dnode1\storage
文件夹下的
CHUNK_METADATA
文件夹复制到上面创建的
backup
文件夹下,如下图所示:
注意
:元数据文件可能通过配置文件指定存储在其它目录,如果在默认路径没有找到上述文件,可以通过查询配置文件中的
dfsMetaDir
参数和
chunkMetaDir
参数确认元数据文件的存储目录。若配置中未指定
dfsMetaDir
参数和
chunkMetaDir
参数,但是配置了
volumes
参数,
CHUNK_METADATA
目录在相应的
volumes
参数指定的目录下。
第三步:升级
下载所需升级版本的安装包,官方下载地址:
http://www.dolphindb.cn/downloads.html
将新版本
server
目录下除
dolphindb.cfg
,
clusterDemo
以及
dolphindb.lic
外的所有文件覆盖替换旧版文件
注意
:当 server 升级到某个版本后,使用的插件也应升级到与此对应的版本。
第四步:重新启动集群
前台启动控制节点和代理节点
进入
C:\DolphinDB\server\clusterDemo
目录,双击
startController.bat
启动控制节点,双击
startAgent.bat
启动代理节点。
后台启动控制节点和代理节点
进入
C:\DolphinDB\server\clusterDemo
目录,双击
backgroundStartController.vbs
启动控制节点,双击
backgroundStartAgent.vbs
启动代理节点。
成功启动后,打开控制节点 Web 管理界面,在交互编程界面执行以下代码,查看 DolphinDB 当前版本:
version()
授权许可文件过期更新
在更新授权许可文件前,可以打开控制节点 Web 管理界面,在交互编程界面执行以下代码查看当前授权许可文件的到期时间:
use ops
getAllLicenses()
在更新授权许可文件后,可通过对比更新前后授权许可文件的到期时间确认是否更新成功。
第一步:替换授权许可文件
用新的授权许可文件
dolphindb.lic
替换老的授权许可文件。
Linux 环境授权许可文件位置:
/DolphinDB/server/dolphindb.lic
Windows 环境授权许可文件位置:
C:\DolphinDB\server\dolphindb.lic
第二步:更新授权许可文件
在线更新
打开控制节点 Web 管理界面,在交互编程界面执行以下代码完成更新,代码成功运行会返回新授权许可证的到期时间:
use ops
updateAllLicenses()
注意
:在线更新有如下要求:
License 授权的客户名称必须与原来的 License 相同。
授权的节点个数,内存大小,CPU 核个数不能比原来的小。
该函数只在执行该函数的节点生效。因此在集群环境下,需要在所有控制节点,代理节点、计算节点和数据节点上运行该函数。
License 的类型必须是 commercial(付费)类型和 free 类型,如果是 trial(试用)类型不支持在线更新。
离线更新
关闭 DolphinDB 集群的所有节点,然后重新启动集群,即可完成更新。
单服务器集群配置文件介绍
为了方便用户部署集群,DolphinDB 安装包内置了集群配置文件,默认配置可以启动一个最简单的单服务器集群: 1 个控制节点, 1 个代理节点, 1 个数据节点, 1 个计算节点。
Linux 环境集群配置文件位于
/DolphinDB/server/clusterDemo/config
目录,Windows 环境集群配置文件位于
C:\DolphinDB\server\clusterDemo\config
目录。性能调优时往往需要手动修改集群配置文件,进行集群配置参数优化,单服务器集群配置文件主要包含:
controller.cfg
配置文件、
agent.cfg
配置文件、
cluster.nodes
配置文件和
cluster.cfg
配置文件。
配置控制节点参数文件
执行以下 Shell 指令修改
controller.cfg
配置文件:
vim ./controller.cfg
mode=controller
localSite=localhost:
8900
:controller8900
dfsReplicationFactor=
1
dfsReplicaReliabilityLevel=
2
dataSync=
1
workerNum=
4
maxConnections=
512
maxMemSize=
8
lanCluster=
0
默认控制节点启动端口是 8900,可以通过修改
localSite
参数指定控制节点的 IP 地址、端口号和别名。
例如,IP 地址为 10.0.0.80,端口号为 8900,别名为 controller8900,则可配置为:
localSite=10.0.0.80:8900:controller8900
其余参数用户应结合自身服务器硬件配置进行合理参数调优。
配置代理节点参数文件
执行以下 Shell 指令修改
agent.cfg
配置文件:
vim ./agent.cfg
mode=agent
localSite=localhost:
8901
:agent1
controllerSite=localhost:
8900
:controller8900
workerNum=
4
maxMemSize=
4
lanCluster=
0
agent.cfg
的
controllerSite
必须与
controller.cfg
中的
localSite
保持一致,因为代理节点使用
agent.cfg
中的
controllerSite
来寻找集群中的控制节点。若
controller.cfg
中的参数
localSite
有变化,即使只是控制节点别名有改变,
agent.cfg
中的
controllerSite
都必须做相应的改变。默认代理节点启动端口是 8901,可以通过修改
localSite
参数指定代理节点的 IP 地址、端口号和别名。agent.cfg 中的 sites 配置当前代理节点和集群控制节点的信息,需要依次填写当前代理节点和控制节点的 IP 地址、端口号和别名,例如
sites=10.0.0.80:8901:agent1:agent,10.0.0.80:8900:controller8900:controller
。只有设置了配置项 sites,才允许在代理节点登录。
例如, IP 地址为 10.0.0.80 ,端口号为 8901 ,别名为 agent1,则可配置为:
localSite=10.0.0.80:8901:agent1
其余参数用户应结合自身服务器硬件配置进行合理参数调优。
配置集群成员参数文件
执行以下 Shell 指令修改
cluster.nodes
配置文件:
vim ./cluster.nodes
localSite,mode
localhost:
8901
:agent1,agent
localhost:
8902
:dnode1,datanode
localhost:
8903
:cnode1,computenode
cluster.nodes
用于存放集群代理节点、数据节点和计算节点的信息。默认集群配置文件使用 1 个代理节点,1 个数据节点和1个计算节点,用户可以根据实际要求配置节点个数。该配置文件分为两列,第一列存放节点 IP 地址、端口号和节点别名,这三个信息由冒号分隔;第二列是说明节点类型,比如代理节点类型为
agent
,数据节点类型为
datanode
,计算节点类型为
computenode
。
注意
:节点别名是大小写敏感的,而且在集群内必须是唯一的。
配置数据节点和计算节点参数文件
执行以下 Shell 指令修改
cluster.cfg
配置文件:
vim ./cluster.cfg
maxMemSize=
32
maxConnections=
512
workerNum=
4
maxBatchJobWorker=
4
OLAPCacheEngineSize=
2
TSDBCacheEngineSize=
1
newValuePartitionPolicy=add
maxPubConnections=
64
subExecutors=
4
lanCluster=
0
enableChunkGranularityConfig=true
cluster.cfg
的配置适用于集群中所有数据节点,用户应结合自身服务器硬件配置进行合理参数调优。
常见问题解答(FAQ)
端口被其它程序占用导致节点启动失败怎么办?
如果遇到无法启动 DolphinDB 节点的情况,建议打开
/DolphinDB/server/clusterDemo/log
目录下对应节点的日志文件,若出现如下错误:
<ERROR> :Failed to bind the socket on port 8900 with error code 98
说明选用的端口被其他程序占用,导致 DolphinDB 节点无法正常启动,修改配置文件中的端口为其它空闲端口后即可正常启动。
Web 管理界面无法访问怎么办?
DolphinDB 正常启动后,在浏览器输入正确的访问地址,但是 Web 管理界面无法正常打开,如下图所示:
出现上述问题的原因基本上都是因为浏览器与 DolphinDB 不是部署在同一台服务器,且部署 DolphinDB 的服务器开启了防火墙。可以通过关闭部署了 DolphinDB 的服务器的防火墙或者打开对应的部署端口,解决这个问题。
Linux 升级失败如何版本回退?
如果升级以后,不能正常开启 DolphinDB 单服务器集群,可按以下方式回退到旧版本。
第一步:恢复旧版本元数据文件
在
/DolphinDB/server/clusterDemo/data
目录执行以下 shell 指令恢复已备份的控制节点和数据节点元数据:
cp -r backup/DFSMetaLog.0 ./
cp -r backup/DFSMasterMetaCheckpoint.0 ./
cp -r backup/CHUNK_METADATA ./dnode1/storage
第二步:恢复旧版本程序文件
在官方下载旧版本程序包,把重新下载的旧版本
server
目录下除
dolphindb.cfg
、
clusterDemo
以及
dolphindb.lic
外的所有文件覆盖替换升级失败的文件。
Windows 升级失败如何版本回退?
如果升级以后,不能正常开启 DolphinDB 单服务器集群,可按以下方式回退到旧版本。
第一步:恢复旧版本元数据文件
把升级前备份在
C:\DolphinDB\server\clusterDemo\data\backup
目录下的
DFSMetaLog.0
和
DFSMasterMetaCheckpoint.0
(若存在)文件复制替换
C:\DolphinDB\server\clusterDemo\data
目录下的
DFSMetaLog.0 和 DFSMasterMetaCheckpoint.0
文件。
把升级前备份在
C:\DolphinDB\server\clusterDemo\data\backup
目录下的
CHUNK_METADATA
文件复制替换
C:\DolphinDB\server\clusterDemo\data\dnode1\storage
目录下的
CHUNK_METADATA
文件。
第二步:恢复旧版本程序文件
在官方下载旧版本程序包,把重新下载的旧版本
server
目录下除
dolphindb.cfg
、
clusterDemo
以及
dolphindb.lic
外的所有文件覆盖替换升级失败的文件。
在线更新授权文件失败怎么办?
在线更新授权文件需要满足
更新授权许可文件
中在线更新的要求。如果不满足其中的要求,可以通过离线方式进行更新,或前往DolphinDB官网申请企业版 License。
如何进行配置参数调优?
可以参考 DolphinDB 官方参数配置说明进行配置参数调优。
如果遇到性能问题,请添加微信号13306510479 或扫描下面二维码,客服会邀您进群,由 DolphinDB 技术支持工程师会解答您的问题。
FILE:references/doc_7986.md
# submitJobEx
**URL**: https://docs.dolphindb.cn/zh/funcs/s/submitJobEx.html
**来源**: DolphinDB 官方文档
---
submitJobEx
语法
submitJobEx(jobId, jobDesc, priority, parallelism, jobDef,
args...)
详情
把批处理作业提交到本地节点并且返回作业的ID。
submitJobEx
与
submitJob
的唯一区别在于
submitJobEx
中可以指定参数
priority
与
parallelism
。
参数
jobId
是作业的 ID,是字符串类型。
jobDesc
是字符串,用于描述作业。
priority
是0到9之间的整数,表示作业的优先级。9表示优先级最高。
parallelism
是正整数,表示分配给该作业的线程数上限。
jobDef
是用于定义作业的本地函数。请注意,该参数是一个函数对象,而不是表示函数名的字符串,因此不可使用引号。
args...
是函数的参数。如果函数没有参数,它可以不指定。
返回值
STRING 类型标量,表示作业的 ID。
例子
def jobDemo(n){
s = 0
for (x in 1 : n) {
s += sum(sin rand(1.0, 100000000)-0.5)
print("iteration " + x + " " + s)
}
return s
};
submitJobEx("jobDemo1","job demo", 8, 12, jobDemo, 100);
FILE:references/doc_7988.md
# timer
**URL**: https://docs.dolphindb.cn/zh/progr/statements/timer.html
**来源**: DolphinDB 官方文档
---
timer
timer
语句用于计算一条命令的执行时间。
语法
用法
语法
1
timer{
<statement block>
}
2
timer (X){
<statement block>
}
参数
对于第二种用法,
X
是正整数,表示连续(非并行)执行指定代码块的次数。
详情
计算执行指定代码的耗费的时间。
注:
timer
获取的耗时仅为脚本在服务器运行的时间(若为集群环境,包含集群内节点间的网络开销),不包括客户端和服务器之间的网络传输耗时。
例子
x=rand(10.0, 1000000);
timer x*2;
// output
Time elapsed: 3 ms
timer(10){x*2};
// output
Time elapsed: 35.004 ms
FILE:references/doc_7990.md
# listMCPTools
**URL**: https://docs.dolphindb.cn/zh/funcs/l/listMCPTools.html
**来源**: DolphinDB 官方文档
---
listMCPTools
语法
listMCPTools()
详情
查看所有已定义的 MCP Tools。
返回值
一张表,包含以下字段:
name:STRING 类型,tool 的名称。
title:STRING 类型,tool 的 title。
description:STRING 类型,tool 的描述。
args:STRING 类型,参数列表,格式为
argName1: argType1, argName2: argType2,
...
。
lastModifyTime:TIMESTAMP 类型,最后一次修改时间。
publishTime:TIMESTAMP 类型,发布时间。
function:BLOB 类型,函数定义。
例子
listMCPTools()
返回结果
name
title
description
args
lastModifyTime
publishTime
function
myTool
DolphinDB Tools
This is a tool
a:number
2025.08.13 09:51:56.550
2025.08.13 15:14:14.255
def myTool(x){ return (x * 2) + 1 }
FILE:references/doc_8.md
# mvarTopN
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mvarTopN.html
**来源**: DolphinDB 官方文档
---
mvarTopN
语法
mvarTopN(X, S, window, top, [ascending=true],
[tiesMethod='oldest'])
参数说明和窗口计算规则请参考:
mTopN
详情
在给定长度(以元素个数衡量)的滑动窗口内,根据
ascending
指定的排序方式将
X
按照
S
进行稳定排序后,取前
top
个元素计算样本方差。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
X = 1..7
S = 0.3 0.5 0.1 0.1 0.5 0.2 0.4
mvarTopN(X, S, 4, 2)
// output: [,0.5,2,0.5,0.5,0.5,2]
X = NULL 1 2 3 4 NULL 5
S = 3 5 1 1 5 2 4
mvarTopN(X, S, 4, 2)
// output: [,,,0.5,0.5,0.5,]
X = matrix(1..5, 6..10)
S = 2022.01.01 2022.02.03 2022.01.23 2022.04.06 2021.12.29
mvarTopN(X, S, 3, 2)
#0
#1
0.5
0.5
2
2
0.5
0.5
2
2
X = matrix(1..5, 6..10)
S = matrix(2022.01.01 2022.02.03 2022.01.23 NULL 2021.12.29,NULL 2022.02.03 2022.01.23 2022.04.06 NULL)
mvarTopN(X, S, 3, 2)
#0
#1
0.5
0.5
2
2
0.5
0.5
2
2
相关函数:
mvar
FILE:references/doc_800.md
# rename!
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rename_.html
**来源**: DolphinDB 官方文档
---
rename!
语法
rename!(X, Y, [Z])
详情
对于向量,赋予其一个新标签。
对于矩阵、索引矩阵,给列(和行)添加标签。
对于表,替换表的列名。
参数
X
可以是向量、矩阵、索引矩阵、非共享内存表
或分布式表(仅支持
OLAP 引擎)
。
当
X
是向量时,
Y
是表示标签的字符串。
当
X
是矩阵、索引矩阵时,如果
Z
没有指定,则
Y
是列标签;如果
Z
指定了,
Y
是行标签,而
Z
是列标签。列标签和行标签的长度分别需要等于
X
的列数和行数。
Y
和
Z
可以是任意数据类型。
当
X
是非共享内存表时,
Y
和
Z
是字符串标量或向量。如果
Z
没有指定,则
Y
从左到右是新的列名,用户应该确保新的列名的数量小于或等于表中列的总数;如果
Z
指定了,则
Y
是旧的列名,
Z
是对应的新的列名。
当
X
是分布式表时,必须指定
Y
和
Z
且只能是字符串标量。其中
Y
表示指定的旧列名,
Z
是对应的新列名。分布式表不支持批量修改列名。
返回值
返回一个数据类型和形式与
X
相同的对象。
例子
k = 3 6 9;
k.rename!(`rk);
// output
[3, 6, 9]
// 用函数 stat 获取统计信息是一种查看名字的方法
stat k;
// output
Median->6
Avg->6
Min->3
Stdev->3
Count->3
Size->3
Name->rk // k 的新标签
Max->9
m1 = 1..9$3:3;
m1
#0
#1
#2
1
4
7
2
5
8
3
6
9
m1.rename!(`col1`col2`col3);
col1
col2
col3
1
4
7
2
5
8
3
6
9
m1.rename!(1 2 3, `c1`c2`c3);
c1
c2
c3
1
1
4
7
2
2
5
8
3
3
6
9
m1 join k;
// 注意新的矩阵使用 k 的标签作为它的列标签。
c1
c2
c3
rk
1
1
4
7
3
2
2
5
8
6
3
3
6
9
9
t1=table(1..3 as x, 4..6 as y, 7..9 as z);
t1
x
y
z
1
4
7
2
5
8
3
6
9
t1.rename!(`a`b);
注:
若要重命名的列数超过原表的实际列数,则会报错。
a
b
z
1
4
7
2
5
8
3
6
9
t1.rename!(`aa`bb`cc);
aa
bb
cc
1
4
7
2
5
8
3
6
9
t1.rename!(`bb`cc, `y`z);
aa
y
z
1
4
7
2
5
8
3
6
9
t1=table(1..3 as x, 4..6 as y, 7..9 as z, k);
t1
// 注意表使用了 k 的标签作为它的列名
x
y
z
rk
1
4
7
3
2
5
8
6
3
6
9
9
创建一个索引矩阵。
m = matrix(1..5, 11..15)
m.rename!(2020.01.01..2020.01.05, `A`B)
m1 = m.setIndexedMatrix!();
A
B
2020.01.01
1
11
2020.01.02
2
12
2020.01.03
3
13
2020.01.04
4
14
2020.01.05
5
15
修改其行、列标签。
m1.rename!( "a" + string(1..5), `A1`A2)
若向量不遵循严格递增或包含重复值,则会报错。
m1.rename!( "a" + string(4 6 2 1 3), `A1`A2)
m1.rename!( "a""a""a""a""a", `A1`A2)
//Error: The label of an indexed matrix or series must be in strict ascending order.
FILE:references/doc_8004.md
# 流数据
**URL**: https://docs.dolphindb.cn/zh/stream/str_intro.html
**来源**: DolphinDB 官方文档
---
流数据
DolphinDB 流数据简介
DolphinDB 流数据(DolphinDB Stream)是基于 C++ 自主研发的高性能流处理引擎,支持实时
ETL、实时低延时复杂计算、实时多源数据关联等流数据处理任务,具备数据库融合、丰富的算子和流计算引擎、金融级高可用、流批一体和分布式等特性。
DolphinDB
的流数据功能非常适合
吞吐量大
、
时延要求高
、
复杂实时分析
等业务场景,其在以下两大领域已被广泛应用(不限于这些场景):
金融领域:
搭建实时行情中心
量化交易中的实时多因子计算和交易信号构建
AI 算法交易中的实时特征工程构建和模型在线推断
量化交易订单实时监控
做市业务实盘监控
行情数据的实时衍生指标计算和分发
物联网领域:
大型电厂百万测点监控数据实时接入和计算分析
海量地震数据的实时特征工程构建和预测模型在线推断
数字化智慧工厂生产流水线运行状态的实时监控和自动化反向操控
DolphinDB 流数据核心特性
数据库融合
流数据与时序数据库无缝集成在 DolphinDB 中,因此 DolphinDB
不仅可以解决海量历史数据的存储和批计算问题,还广泛支持了流数据的实时计算和实时存储。
算子丰富
DolphinDB 内置了丰富的计算函数,使用户能够通过低代码方式轻松实现复杂的数据分析和金融量化因子计算。内置计算函数包括但不限于以下大类:
时序处理函数
窗口函数
聚合函数
排序/查找/分类函数
统计函数
分布函数
机器学习
三角函数
逻辑函数
傅里叶变换函数
内置流数据引擎丰富
DolphinDB 内置了超过 10 个流计算引擎, 提供了灵活的计算方式和丰富的功能,适用于多样化的实时数据处理需求。
金融级高可用
基于 Raft 协议提供高可用功能,确保流数据处理级别可以保证 Exactly-Once。
流批一体
分布式订阅与发布
FILE:references/doc_8009.md
# 数据导入方法
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db_oper/data_import_method.html
**来源**: DolphinDB 官方文档
---
数据导入方法
DolphinDB 针对各种类型的数据文件和数据源提供了便捷的导入导出工具,利用这些工具,可以完成即时或定时的数据加载、清洗和导入导出任务。
内置函数
DolphinDB 提供了多种内置函数进行文本文件、二进制、JSON
文件的数据导入与导出。在数据导入的过程中,用户通过对相关的参数进行设置,可进行数据类型匹配等预处理。
文本文件导入
函数
说明
loadText
将文本文件导入为内存表。
ploadText
将文本文件并行导入为分区内存表,与
loadText
函数相比速度更快。
ploadText
充分利用了多核 CPU
来并行载入文件,可快速载入 16MB 或以上的较大文件。
loadTextEx
将文本文件导入数据库中,包括分布式数据库或内存数据库。该函数将文本文件分为许多批次逐步载入内存并落盘到数据库,避免文本文件过大时可能出现内存不足的问题。支持通过传入自定义函数,在入库前对数据进行预处理。
textChunkDS
将文本文件划分为多个小数据源,并将划分后的数据通过分布式计算框架下的 map-reduce
函数导入数据库。
二进制、JSON 文件导入
导入类型
函数
说明
二进制文件
readRecord!
将二进制文件转换为 DolphinDB 数据对象。
loadRecord
将二进制文件转换为 DolphinDB 数据对象,并支持处理字符串类型的数据。
JSON 文件
fromJson
,
fromStdJson
将 JSON 格式的字符串转换为 DolphinDB 对象。
数据导出
导出类型
函数
说明
文本文件
saveText
可以将任意变量或表对象保存为文本文件。
saveTextFile
通过追加或覆盖将字符串保存到文本文件中。
二进制文件
writeRecord
将 DolphinDB
对象(例如表或元组)转换为二进制文件并返回向文件写入的行数。
saveAsNpy
将 DolphinDB 向量或矩阵保存为 NumPy 支持的
.npy
二进制文件。
JSON 文件
toJson
,
toStdJson
将 DolphinDB 对象转换为 JSON 字符串。
插件及工具
DolphinDB 还提供了一系列用于数据导入/迁移的插件。
数据库插件
使用数据库迁移插件的主要优点在于可以直接调用现成的接口,脚本简单易上手。DolphinDB 提供了一系列专门针对第三方数据库的数据迁移插件,如对
MySQL,kdb+,MongoDB 有专门的插件, SQL Server,Oracle,ClickHouse,SQLite 等可通过 ODBC
插件进行连接和导入。
插件名
功能描述
odbc
通过 ODBC 读取其他数据源的数据,包括来自 MySQL, Oracle, SQL
Server 等大多数数据库的数据
mysql
连接 MySQL 并读取数据
HBase
通过 Thrift 连接 HBase,读取数据
kdb
通过连接 kdb+ 数据库或直接读取磁盘上的 kdb+ 数据文件以导入数据
mongodb
连接 MongoDB,读取数据
数据文件读取插件
通过插件从数据文件中导入数据的优点在于操作简单、稳定,适合大量数据迁移。
插件名
功能描述
Arrow
序列化支持 Apache Arrow 格式
aws
读取和写入 AWS S3 的网络文件
feather
读取、写入 Apache Feather 文件
hdfs
读取和写入 Hadoop 的 HDFS 文件
hdf5
读取和写入 HDF5 文件
mat
读取、写入 MATLAB 文件
mseed
读取和写入 miniSEED 文件
orc
读取、写入 ORC 文件
parquet
读取和写入 Apache Parquet 文件
zip
解压 ZIP 文件
zlib
压缩、解压 gz 文件
消息中间件、行情插件
通过对接消息中间件及行情服务的插件,可以将实时数据写入 DolphinDB。
插件
类别
功能描述
zmq
消息发布和订阅
发送、接收 ZeroMQ 消息
mqtt
发布和订阅 MQTT 消息
kafka
发布或订阅 Kafka 流服务
insight
行情接收
接收华泰 Insight 实时行情
AmdQuote
接收华锐 Amd 实时行情数据
nsq
读取恒生 NSQ 实时行情数据
其他导入工具
DolphinDB 也提供了基于离线数据同步工具 DataX 的 dolphindbwriter 插件,可满足从不同数据源向 DolphinDB
导入数据、同步增量数据的功能,具有可拓展、通用性强的优势。
此外,用户也可通过 DolphinDB C++ API,Python API,Java API 等 API 所提供的接口导入数据,详情请见相关 API
文档。
FILE:references/doc_8011.md
# 基于 DataX 的 DolphinDB 数据导入工具
**URL**: https://docs.dolphindb.cn/zh/plugins/dataxwriter/README_CN.html
**来源**: DolphinDB 官方文档
---
基于 DataX 的 DolphinDB 数据导入工具
DataX-dolphindbwriter 是为解决用户将不同数据来源的数据同步到 DolphinDB 而开发的插件。这类数据的特征是改动很少,并且数据分散在不同的数据库系统中。
1. DataX 离线数据同步
DataX 是在阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL, Oracle, SqlServer, Postgre, HDFS, Hive, ADS, HBase, TableStore(OTS), MaxCompute(ODPS), DRDS 等各种异构数据源之间高效的数据同步功能,详情可查看
DataX 已支持的数据源
。
DataX 是可扩展的数据同步框架,将不同数据源的同步抽象为从源头数据源读取数据的 Reader 插件,以及向目标端写入数据的 Writer 插件。理论上 DataX 框架可以支持任意数据源类型的数据同步工作。每接入一套新数据源该新加入的数据源即可实现和现有的数据源互通。
DataX 插件:dolphindbwriter
基于 DataX 的扩展功能,dolphindbwriter 插件实现了向 DolphinDB 写入数据。使用 DataX 的现有 reader 插件结合 DolphinDBWriter 插件,即可满足从不同数据源向 DolphinDB 同步数据。
DolphinDBWriter 底层依赖 DolphinDB Java API,采用批量写入的方式将数据写入分布式数据库。
本插件通常用于以下两个场景:
定期从数据源向 DolphinDB 追加新增数据。
定期获取更新的数据,定位 DolphinDB 中的相同数据并进行更新。此种模式下,由于需要将历史数据读取出来并在内存中进行匹配,会需要大量的内存,因此这种场景适用于在 DolphinDB 中容量较小的表,通常建议使用数据量在 200 万以下的表。
当前使用的更新数据的模式是通过全表数据提取、更新后删除分区重写的方式来实现。
注意,目前版本还无法保障上述整体操作的原子性,后续版本会针对此种方式的事务处理方面进行优化和改进。
2. 使用方法
详细信息请参阅
DataX 指南
,以下仅列出必要步骤。
2.1 下载部署 DataX
DataX 指南
提供了两种部署方式,建议选择方式一,即直接下载 DataX 工具包进行部署。
2.2 部署 DataX-DolphinDBWriter 插件
将源码的
./dist/dolphindbwriter
目录下所有内容拷贝到
datax/plugin/writer
目录下,即可使用。
2.3 执行 DataX 任务
进入
datax/bin
目录下,用 Python 执行
datax.py
脚本,并指定配置文件地址,示例如下:
cd /root/datax/bin/python datax.py /root/datax/myconf/BASECODE.json
2.4 导入实例
使用 DataX 的绝大部分工作都是通过配置来完成,包括双边的数据库连接信息和需要同步的数据表结构信息等。
2.4.1 全量导入
下面以从 Oracle 向 DolphinDB 导入一张表 BASECODE 进行示例。
首先在导入前,需要在 DolphinDB 中预先创建好目标数据库和表;然后使用 oraclereader 从 Oracle 读取 BASECODE 表读取全量数据;再使用 dolphindbwriter 将读取到的 BASECODE 数据写入 DolphinDB 中。
编写配置文件
BASECODE.json
,并存放到指定目录,比如
/root/datax/myconf
目录下,配置文件说明参考本文附录。
注意:在做全量导入时,
saveFunctionName
和
saveFunctionDef
这两项无需配置,删除即可。
配置完成后,在
datax/bin
目录下执行如下脚本即可启动同步任务:
cd /root/datax/bin/
python datax.py /root/datax/myconf/BASECODE.json
2.4.2 增量数据导入
增量数据分两种类型,一种是新增数据,另一种是已有数据的更新,即更新了数据内容以及时间戳。对于这两种类型的数据要用不同的数据导入方式。
新增数据增量同步
新增数据的增量同步与全量导入相比,唯一的不同点在于 reader 对数据源中已导入数据的过滤。通常需要处理增量数据的表,都会有一个时间戳的列来标记入库时间,在 oralcereader 插件中,只需要配置 where 条件,增加时间戳过滤即可,其对于 dolphindbwriter 的配置与全量导入完全相同。比如时间戳字段为 OPDATE, 要增量导入 2020.03.01 之后的增量数据,则配置
"where": "OPDATE > to_date('2020-03-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
。
变更数据增量同步
变更数据在数据源有不同的记录方法,比较规范的方法是通过一个变更标志和时间戳来记录,比如用 OPTYPE、 OPDATE 来记录变更的类型和时间戳,这样可以通过类似
"where": "OPTYPE=1 and OPDATE > to_date('2020-03-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
条件过滤出增量数据。
对于 writer 的配置项,需要增加如下两处配置:
isKeyField
因为变更数据的更新需要目标表中有唯一列,所以 writer 的配置中,需要对 table 配置项中唯一键列增加
isKeyField=true
这一配置项。
saveFunctionName
DolphinDB 有多种数据存储的方式,比较常用的两种是分布式表和维度表。dolphindbwriter 中内置了更新这两种表的脚本模板,当从数据源中过滤出变更数据之后,在 writer 配置中增加
saveFunctionName
和
saveFunctionDef
两个配置(具体用法请参考附录),writer 会根据这两个配置项,采用对应的方式将数据更新到 DolphinDB 中。
在 1.30.21.4 版本中,用户可通过
saveFunctionName
和
saveFunctionDef
引入 DolphinDB 的
upsert!
功能以保证导入后的数据唯一性。具体配置示例参考附录。
当有些数据源中不包含 OPTYPE 这一标识列,无法分辨出新数据是更新或是新增的时候,可以作为新增数据入库,以函数视图输出的方式:
数据作为新增数据处理。这种方式处理后,数据表中存在重复键值。
定义 functionView 作为数据访问接口,在 functionView 中对有重复键值的数据仅输出时间戳最新的一条。
用户不能直接访问表(可以取消非管理员用户访问表的权限),统一通过 functionView 访问数据。
定时同步
利用 shell 脚本实现 DataX 定时增量数据同步:
DataX 从设计上用于离线数据的一次性同步场景,我们可以通过 shell 或 Python 脚本等工程方式实现定时增量同步。由于 DataX 支持非常灵活的配置, 一种相对简单并且可靠的思路就是根据时间戳动态修改配置文件:
利用 DataX 的 reader 去目标数据库读取数据,并记录最新时间戳;
将这个最新时间戳写入到一个 json 文本文件(op_table.json)。
再次执行同步时用脚本来读取 json 文本文件, 并动态修改同步的配置文件。
执行修改后的配置文件(run_job.json),进行增量同步。
本脚本默认约定,每一个数据表中都有 OPDATE 和 OPMODE 两个字段,用于标记操作时间和操作方式。
OPMODE=0
为新增数据,
OPMODE=1,2
为更新和删除数据。在运行时,根据保存的时间戳动态为 oraclereader 增加一个 where 配置项:
OPMODE = 0 AND OPDATE > to_date('[最新时间戳]', 'YYYY-MM-DD HH24:MI:SS') //新增数据
OPMODE > 0 AND OPDATE > to_date('[最新时间戳]', 'YYYY-MM-DD HH24:MI:SS') //更新数据
定时同步是通过 Python 脚本实现,被包含在 datax 的发布包中。
增量同步脚本在根目录
ddb_script
下,下载后被保存在本地磁盘比如
/root/ddb_script/
。假设 datax 根目录为
/root/datax
, 配置文件放在
/root/datax/myconf/
目录下,则增量同步的使用方法为:
cd /root/ddb_script/
python main.py /root/datax/bin/datax.py /root/datax/myconf/BASECODE.json [run_type]
run_type
参数为选项值,当前支持 [test|prod],具体说明如下:
设置为 test 时,脚本实时打印 datax 输出的内容,此设置下不会向
op_table.json
文件更新时间戳,可供重复调试配置文件使用。
设置为 prod 时,执行后会更新
op_table.json
中的时间戳,用于真实生产环境。
调试好配置文件之后,将此脚本通过 cron 加入到定时任务中,即可实现每日定期增量备份的功能。
2.4.3 数据导入预处理
在数据进入 DolphinDB 分布式库之前,某些场景下需要对数据做一些预处理,比如数据格式转换,参照值转换等。这一功能可以通过自定义
saveFunctionDef
来实现,在数据上传到 DolphinDB 内存中,若
saveFunctionDef
有定义,插件会用此函数来替换
tableInsert
函数,将数据处理逻辑插入数据写入之前即可实现上述的功能(具体用法请参考附录)。
此函数定义必须有三个参数:
dbName
,
tbName
,
data
,分别对应数据库路径(如
dfs://db1
)、数据表名称、待写入的数据。
附录
DolphinDB 写插件配置项
配置项
是否必须
数据类型
默认值
描述
host
是
STRING
无
Server Host
port
是
INT
无
Server Port
userId
是
STRING
无
DolphinDB 用户名导入分布式库时,必须是要有权限的用户才能操作
pwd
是
STRING
无
DolphinDB 用户密码
dbPath
是
STRING
无
需要写入的目标分布式库名称,比如"dfs://MYDB"。
preSql
否
STRING
无
写入数据到目的表前,会先执行这里的 DolphinDB 脚本。
postSql
否
STRING
无
写入数据到目的表后,会执行这里的 DolphinDB 脚本。
column
否
STRING
无
目的表需要写入数据的字段。注意:不能与 table 字段同时使用。使用时请阅读本表下方的注意事项。
tableName
是
STRING
无
目标数据表名称
batchSize
否
INT
10000000
datax 每次写入 DolphinDB 的批次记录数。
table
是
写入表的字段集合,具体参考后续table 项配置详解。
saveFunctionName
否
STRING
无
自定义数据处理函数。若未指定此配置,插件在接收到 reader 的数据后,会将数据提交到 DolphinDB 并通过
tableInsert
函数写入指定库表;如果定义此参数,则会用指定函数替换
tableInsert
函数。
saveFunctionDef
否
STRING
无
数据入库自定义函数。此函数指用DolphinDB 脚本来实现的数据入库过程。 此函数必须接受三个参数:dbName(分布式库路径), tbName(数据表名), data(从 datax 导入的数据,table 格式)。
writeTimeout
否
INT
无
每次写入的执行超时时间,单位为毫秒(ms)。如果未设置,则将一直等待写入完成。
在使用 column 时,请注意:
字段之间用英文逗号分隔,例如: "column": ["id","name","age"]。
如果要依次写入全部列,使用表示,例如: "column": ["*"]。
不可以为空 “column": [],或者”column": [““]。
导入数据是按照原表的字段顺序,无法通过识别新表的字段名称而改变数据顺序。
table 配置详解
table 用于配置写入表的字段集合。内部结构为:
{"name": "columnName", "type": "DT_STRING", "isKeyField":true}
请注意此处列定义的顺序,需要与原表提取的列顺序完全一致。
name:字段名称。
isKeyField:是否唯一键值,可以允许组合唯一键。本属性用于数据更新场景,用于确认更新数据的主键,若无更新数据的场景,无需设置。
type:枚举值以及对应 DolphinDB 数据类型如下。
DolphinDB 类型
配置值
DOUBLE
DT_DOUBLE
FLOAT
DT_FLOAT
BOOL
DT_BOOL
DATE
DT_DATE
MONTH
DT_MONTH
DATETIME
DT_DATETIME
TIME
DT_TIME
SECOND
DT_SECOND
TIMESTAMP
DT_TIMESTAMP
NANOTIME
DT_NANOTIME
NANOTIMETAMP
DT_NANOTIMETAMP
INT
DT_INT
LONG
DT_LONG
UUID
DT_UUID
SHORT
DT_SHORT
STRING
DT_STRING
SYMBOL
DT_SYMBOL
更新分区表和维度表脚本模板代码(供参考)
savePartitionedData
def rowUpdate(dbName, tbName, data, t){
updateRowCount = exec count(*) from ej(t,data,['OBJECT_ID'])
if(updateRowCount<=0) return
dfsPath = "dfs://" + dbName
temp = select * from t
cp = t.schema().chunkPath.substr(strlen("/" + dbName))
update temp set EVENT_ID = data.EVENT_ID,S_INFO_WINDCODE = data.S_INFO_WINDCODE, S_ACTIVITIESTYPE=data.S_ACTIVITIESTYPE, S_SURVEYDATE=data.S_SURVEYDATE, S_SURVEYTIME=data.S_SURVEYTIME, ANN_DT = data.ANN_DT,OPDATE=data.OPDATE,OPMODE=data.OPMODE where OBJECT_ID in data.OBJECT_ID
dropPartition(database(dfsPath), cp, tbName)
loadTable(dfsPath, tbName).append!(temp)
}
def savePartitionedData(dbName, tbName, data){
dfsPath = "dfs://" + dbName
login("admin","123456")
t = loadTable(dfsPath, tbName)
ds1 = sqlDS(<select * from t>)
mr(ds1, rowUpdate{dbName, tbName, data})
}
saveDimensionData
def saveDimensionData(dbName, tbName, data){
login('admin','123456')
dfsPath = 'dfs://' + dbName
temp = select * from loadTable(dbPath, tbName)
update temp set EVENT_ID = data.EVENT_ID,S_INFO_WINDCODE = data.S_INFO_WINDCODE, S_ACTIVITIESTYPE=data.S_ACTIVITIESTYPE, S_SURVEYDATE=data.S_SURVEYDATE, S_SURVEYTIME=data.S_SURVEYTIME, ANN_DT = data.ANN_DT,OPDATE=data.OPDATE,OPMODE=data.OPMODE where OBJECT_ID in data.OBJECT_ID
db = database(dbPath)
db.dropTable(tbName)
dt = db.createTable(temp, tbName)
dt.append!(temp)}
配置文件示例
BASECODE.json
{
"job": {
"setting": {
"speed": {
"channel": 1
}
},
"content": [
{
"reader": {
"name": "oraclereader",
"parameter": {
"username": "root",
"password": "password",
"column": [
"*"
],
"connection": [
{
"table": [
"BASECODE"
],
"jdbcUrl": [
"jdbc:oracle:thin:@127.0.0.1:1521:helowin"
]
}
],
"where":"OPDATE > to_date('2020-03-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')"
}
},
"writer": {
"name": "dolphindbwriter",
"parameter": {
"userId": "user",
"pwd": "pass",
"host": "127.0.0.1",
"port": 8848,
"dbPath": "dfs://TESTDB",
"tableName": "BASECODE",
"batchSize": 100000,
"table": [
{
"type": "DT_DOUBLE",
"name": "S_INFO_MIN_PRICE_CHG_UNIT"
},
{
"type": "DT_DOUBLE",
"name": "S_INFO_LOT_SIZE"
},
{
"type": "DT_STRING",
"name": "S_INFO_ENAME"
},
{
"type": "DT_TIMESTAMP",
"name": "OPDATE"
},
{
"type": "DT_STRING",
"name": "OPMODE"
},
{
"type": "DT_STRING",
"name": "OBJECT_ID",
"isKeyField" :true
},
{
"type": "DT_STRING",
"name": "S_INFO_WINDCODE"
},
{
"type": "DT_STRING",
"name": "S_INFO_ASHARECODE"
},
{
"type": "DT_STRING",
"name": "S_INFO_COMPCODE"
},
{
"type": "DT_STRING",
"name": "S_INFO_SECURITIESTYPES"
},
{
"type": "DT_STRING",
"name": "S_INFO_SECTYPENAME"
}
]
}
}
}
]
}
}
特殊情况 - 时间精度丢失
reader 读取的上游数据库是用字符串的形式存储的时间字段,且该时间字段的需要保留毫秒及以上的精度,那么如果 dolphindbwriter 对应字段的 type 配置成 DT_TIME, DT_TIMESTAMP 等,会导致时间存入 DolphinDB 分布式表后丢失毫秒及以上的精度。
例如:从 Oracle 向 DolphinDB 导入数据, Oracle 用 varchar 类型存储时间:09:00:01.123 , DolphinDB 的分布式表用 TIME 类型存储该时间, 在 dolphindbwriter 的配置中设置对应字段的 type 为 DT_TIME,,入库之后的结果为 09:00:01.000。
解决方案:
将 dolphindbwriter 对应字段的 type 配置为 STRING, 再通过写自定义处理函数,将 STRING 转换成 DolphinDB 的时间类型。
"writer": {
"name": "dolphindbwriter",
"parameter": {
"userId": "user",
"pwd": "pass",
"host": "127.0.0.1",
"port": 8848,
"dbPath": "dfs://TESTDB",
"tableName": "BASECODE1",
"batchSize": 100000,
"saveFunctionName":"updateData",
"saveFunctionDef":"def updateData(dbName, tbName, mutable data){login('admin', '123456');data.replaceColumn!(`Dtime, temporalParse(data.Dtime, 'HH:mm:ss.SSS'));loadTable(dbName, tbName).append!(data)} "
"table": [
{
"type": "DT_STRING",
"name": "Dtime"
}
]
}
}
FILE:references/doc_8018.md
# condValueAtRisk
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cvar.html
**来源**: DolphinDB 官方文档
---
condValueAtRisk
语法
condValueAtRisk(returns, method,
[confidenceLevel=0.95])
详情
条件风险指标(Conditional Value at Risk;也可称 Expected
Shortfall),用于计算超过风控指标的损失的平均值。该函数将返回其绝对值,为 DOUBLE 类型。如果没有收益率低于 VaR 的值,则返回 VaR 的值。
参数
returns
数值型向量,表示收益率序列。注意,表示收益率的每个元素都应大于 -1 且不能为空。
method
字符串类型,表示计算 VaR 的方法,可选值为:
'normal' 正态参数法。
'logNormal' 对数正态参数法。
'historical' 历史模拟法。
'monteCarlo' 蒙特卡洛模拟法,使用正态分布进行模拟。
confidenceLevel
数值型标量,表示置信水平,合法值域为(0,1),默认值为 0.95。
返回值
DOUBLE 类型标量。
例子
本例中给定一个假设的收益率序列,通过历史模拟法,计算置信水平为 0.9 的条件风险指标。
returns = [0.0, -0.0023816107391389394, -0.0028351258634076834, 0.00789570628538656, 0.0022056267475062397, -0.004515475812603498, 0.0031189325339843646, 0.010774648811452205, 0.0030816164453268957, 0.02172541561228001, 0.011106185767699728, -0.005369098699244845, -0.0096490689793588, 0.0025152212699484314, 0.017822140037111668, -0.02837536728283525, 0.018373545076599204, -0.0026401111537113003, 0.019524374522517898, -0.010800546314337627, 0.014073362622486131, -0.00398277532382243, 0.008398647051501285, 0.0024056749358184904, 0.007093080335863512, -0.005332549248384733, -0.008471915938733665, -0.0038788486165083342, -0.01308504169086584, 0.00350496242864784, 0.009036118926745962, 0.0013358223875250545, 0.0036426642608267563, 0.003974568474545581, -0.003944066366522669, -0.011969668605022311, 0.015116930499066374, 0.006931427295653037, -0.0032650627551519267, 0.003407880132851648]
condValueAtRisk(returns, 'historical', 0.9);
//output:0.016057655973
相关函数
:
valueAtRisk
FILE:references/doc_8020.md
# quarterBegin
**URL**: https://docs.dolphindb.cn/zh/funcs/q/quarterBegin.html
**来源**: DolphinDB 官方文档
---
quarterBegin
语法
quarterBegin(X, [startingMonth=1], [offset],
[n=1])
详情
返回
X
所在季度的第一天。每季度包含的月份由参数
startingMonth
决定。
如果指定了
offset
,表示从
offset
开始,结果每隔n个季度更新一次。注意,
offset
和
n
须同时指定,且只有当
n
>1时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
startingMonth
是1到12之间的整数,表示一年的起始月份。默认值是1。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
quarterBegin(2012.06.12);
// output
2012.04.01
quarterBegin(2012.06.13 10:10:10.008,5);
// output
2012.05.01
date=2016.01.12 2016.02.25 2016.05.12 2016.06.28 2016.07.10 2016.08.18 2016.09.02 2016.10.16 2016.11.26 2016.12.30
time = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12,09:38:13]
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
select avg(price),sum(qty) from t1 group by quarterBegin(date,1,2016.01.01,2)
quarterBegin_date
avg_price
sum_qty
2016.01.01
34.65
9400
2016.07.01
92.491667
29300
相关函数:
quarterEnd
,
businessQuarterBegin
,
businessQuarterEnd
FILE:references/doc_8025.md
# rad2deg
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rad2deg.html
**来源**: DolphinDB 官方文档
---
rad2deg
语法
rad2deg(X)
详情
将
X
的角单位从弧度转换为度。
参数
X
可以是标量、向量、矩阵或表。
返回值
数据类型是 DOUBLE,数据形式与
X
相同。
例子
rad2deg(pi);
// output
180
相关函数:
deg2rad
FILE:references/doc_8027.md
# cumsum
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumsum.html
**来源**: DolphinDB 官方文档
---
cumsum
语法
cumsum(X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累计和。
返回值
LONG/DOUBLE 类型,其数据形式同
X
。
例子
x=[2,3,4];
cumsum(x);
// output
[2,5,9]
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
cumsum(m);
#0
#1
1
4
3
9
6
15
相关函数:
sum
FILE:references/doc_8033.md
# cubicHermiteSplineFit
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cubichermitesplinefit.html
**来源**: DolphinDB 官方文档
---
cubicHermiteSplineFit
语法
cubicHermiteSplineFit(X, Y, derivative,
[extrapolate=true])
详情
对一组数值向量
X
和
Y
进行三次埃尔米特(Hermite)插值。
参数
X
数值型向量,表示用于插值的点的 x 坐标(自变量)。
X
必须严格递增,且至少包含两个元素。
Y
与
X
等长的数值型向量,表示用于插值的点的 y 坐标(因变量)。
derivative
与
X
等长的数值型向量,表示
Y
对
X
的一阶导数。
extrapolate
可选参数,布尔标量,表示当预测点超出已知数据范围时是否进行外插。默认为 true。
返回值
一个字典,包含以下键值对:
modelName:字符串“CubicHermiteSpline”,表示模型名称。
X:DOUBLE 类型向量,即输入
X
。
extrapolate:布尔标量,即输入
extrapolate
。
coeffs:数值型向量,表示根据输入数据点拟合得到的多项式系数。
predict:模型的预测函数。可通过
model.predict(X)
或
predict(model,
X)
调用。其中:
model:
cubicHermiteSplineFit
函数返回的字典。
X:数值型向量,表示需要求值的点的 x 坐标,
predict
函数将返回在
X
点处的插值结果。
例子
对 x 和 y 进行三次埃尔米特(Hermite)插值。
x = [0.0000,0.0800,0.1000,0.1700,0.2000,0.2500,0.3000,0.4000,0.5000,0.6000,0.7000,0.7500,0.8000,0.9000,1.0000]
y = [1.2157,1.4000,1.4000,1.4000,1.4055,1.4323,1.4585,1.5096,1.5291,1.4985,1.4562,1.4440,1.4427,1.4461,1.4504]
N = shape(x)[0]
derv = take([0.0], N)
derv[0] = (y[1] - y[0]) \ (x[1] - x[0])
derv[N-1] = (y[N-1] - y[N-2]) \ (x[N-1] - x[N-2])
for (i in 1..(N-2)) {
derv[i] = (y[i+1] - y[i-1]) \ (x[i+1] - x[i-1])
}
model = cubicHermiteSplineFit(x, y, derv)
model;
/* output:
modelName->CubicHermiteSpline
X->[0,0.08,0.1,0.17,0.2,0.25,0.3,0.4,0.5,0.6,0.7,0.75,0.8,0.9,1]
coeffs->#0 #1 #2 #3
-------------------- -------------------- ------------------ ------
-71.992187499999985 5.759375 2.303749999999999 1.2157
4607.499999999995452 -184.299999999999869 1.842999999999999 1.4
11.224489795918488 -0.785714285714294 0 1.4
102.314814814811015 1.208333333333494 0.055000000000001 1.4
-55.2999999999993 5.409999999999942 0.40375 1.4055
-1.066666666666638 -0.066666666666655 0.53 1.4323
-15.366666666666818 1.493333333333353 0.515333333333334 1.4585
-9.249999999999774 -0.655000000000037 0.353 1.5096
19.199999999999896 -4.424999999999982 -0.055500000000001 1.5291
11.816666666666725 -1.766666666666675 -0.3645 1.4985
-4.133333333332982 2.593333333333321 -0.363333333333333 1.4562
-27.600000000001628 3.560000000000105 -0.134999999999998 1.444
-1.549999999999794 0.354999999999965 0.014 1.4427
-0.450000000000062 0.090000000000012 0.038499999999999 1.4461
extrapolate->1
predict->cubicHermiteSplinePredict
*/
通过
predict
函数对 x 进行插值预测。
preds = predict(model, x)
preds;
// output: [1.2157,1.4,1.4,1.4,1.4055,1.4323,1.4585,1.5096,1.5291,1.4985,1.4562,1.444,1.4427,1.4461,1.4504]
FILE:references/doc_8050.md
# createDimensionTable
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createdimensiontable.html
**来源**: DolphinDB 官方文档
---
createDimensionTable
语法
createDimensionTable(dbHandle, table, tableName, [compressMethods],
[sortColumns
|primaryKey
],
[keepDuplicates=ALL]
, [softDelete=false]
,
[indexes]
, [encryptMode='plaintext'])
别名:createTable
详情
在分布式数据库中创建一个维度表。维度表是分布式数据库中没有进行分区的表,查询时会将表中所有数据加载到内存,适用于存储不频繁更新的小数据集。
系统会定期检查内存的使用情况,当内存使用超过系统配置参数
warningMemSize
设定的阈值时,系统会尝试释放部分缓存。维度表如果长时间未被使用,其占用的内存根据 LRU(Least Recently Used)策略将被释放。用户也可以调用
clearCachedDatabase
手动释放维度表的缓存。
维度表与分区表都是根据设置参数
dfsReplicationFactor
决定副本的数量。维度表的读写操作也支持事务。
通过在配置项配置
enableConcurrentDimensionalTableWrite
=
true,可以支持对维度表进行并发的写入、修改或删除操作。
参数
dbHandle
是
database
函数返回的分布式数据库句柄。
table
是一个表,系统将根据该表的结构在数据库中创建一个空的维度表。
tableName
是一个字符串,表示维度表的名称。
compressMethods
一个字典,指定某些列使用 lz4, delta, zstd 或 chimp
压缩算法存储。key 为字段名,value 为压缩算法("lz4", "delta", "zstd" 或 "chimp")。若未指定,默认采用 lz4 压缩算法。有关
Delta 压缩算法,亦称为 delta-of-delta encoding,参考:
Delta Compression Techniques
。
对于
DECIMAL,
SHORT, INT, LONG 与时间或日期类型数据,建议采用 Delta 算法压缩。
将字符串存储为 SYMBOL 类型数据,实现对字符串类型的压缩。
对于小数部分长度在三位以内的 DOUBLE 类型的数据,可以考虑使用 chimp 算法压缩。
sortColumns
字符串标量或向量,用于指定每一分区内的排序列,
每次
写入
磁盘
的数据在每一分区内将按
sortColumns
进行排序。系统默认
sortColumns
(指定多列时) 除最后一列外的列字段作为排序的索引列,称作 sort key。每一分区内,同一个 sort
key 组合值对应的数据将按最后一列的值顺序连续存放在一起。查询时,若查询条件包含索引列,可以快速定位数据所在的数据块位置,提高查询性能。
仅当 dbHandle 指示的数据库采用 "TSDB" 引擎(engine="TSDB")时,本参数才生效。
sortColumns
只能是 INTEGER, TEMPORAL, LITERAL 类别(除 BLOB) 或 DECIMAL 类型。
若
sortColumns
指定为多列,则
sortColumns
的最后一列必须为时间类型或整型,其余列为索引列,且索引列不能为为 TIME, TIMESTAMP, NANOTIME,
NANOTIMESTAMP 类型。
若
sortColumns
仅指定一列,则该列作为 sort key,其类型可以是除 TIME, TIMESTAMP,
NANOTIME, NANOTIMESTAMP 之外的任意类型。若
sortColumns
为时间类型 (非分区列),且同时指定了
sortKeyMappingFunction
,则查询的过滤条件中
sortColumns
只能与相同时间类型的值进行比较。
频繁查询的字段适合设置为
sortColumns
(建议不超过 4 列),且建议优先把查询频率高的字段作为
sortColumns
中位置靠前的列。
为保证性能最优,建议每个分区内索引列的组合数(sort key)不超过 2000 个。
sortColumns
是每个分区内部 level file 内数据的排序依据,与其是否为分区字段无关。
primaryKey
字符串标量或向量,用于指定主键列。在数据写入操作中,如果主键相同,新的数据覆盖现有数据。
仅当
dbHandle
指示的数据库采用 “PKEY” 引擎(engine=”PKEY”)时,本参数才生效。
主键列必须包含所有的分区列。
主键列支持的类型包括:BOOL, CHAR, SHORT, INT, LONG, INT128, STRING, TIME, SECOND,
MINUTE, DATE, MONTH, DATEHOUR, DATETIME, SYMBOL, TIMESTAMP, NANOTIME,
NANOTIMESTAMP, UUID, COMPLEX, POINT, IPADDR, DECIMAL32, DECIMAL64,
DECIMAL128。
keepDuplicates
指定在每个分区内如何处理所有
sortColumns
之值皆相同的数据。提供以下选项:
ALL:保留所有数据,为默认值。
LAST:仅保留最新数据
FIRST:仅保留第一条数据
softDelete
用于启用或禁用软删除功能。默认为
false,即禁用。该参数适于在行数多但删除量小的场景下使用。使用该参数需要同时满足以下条件:
由TSDB 存储引擎创建的数据库内的表
keepDuplicates
已设置为 LAST
注:
参数
sortColumns
,
keepDuplicates
仅在
database
的
engine
参数指定为 TSDB
时才有效。
indexes
为一个字典。当引擎为 PKEY 时,用于为表中的列指定索引。字典的键是 STRING
类型标量,表示列名;值是 STRING 类型标量,表示为该列指定的索引类型。目前支持设置 “bloomfilter”
索引类型:适用于对大基数列进行点查,且基数越大,索引效果越好,如身份证 ID、订单号、从业务上游同步的外键等数据列。目前支持的类型包括 BOOL, CHAR,
SHORT, INT, LONG, BLOB, STRING, DECIMAL32, DECIMAL64, DECIMAL128。
注:
引擎会将所有主键列合并为组合主键,并为组合主键设置 bloomfilter
类型索引。
encryptMode
可选参数,字符串标量,指定表的加密方式,默认为不加密(明文模式)。仅 Linux
系统支持该参数。目前支持以下可选值(大小写不区分):plaintext, aes_128_ctr, aes_128_cbc, aes_128_ecb,
aes_192_ctr, aes_192_cbc, aes_192_ecb, aes_256_ctr, aes_256_cbc, aes_256_ecb,
sm4_128_cbc, sm4_128_ecb。
返回值
一个表。
例子
例1
db=database("dfs://db1",VALUE,1 2 3)
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
sym = `C`MS`MS`MS`IBM`IBM`C`C`C
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
t = table(timestamp, sym, qty, price);
dt=db.createDimensionTable(t,`dt).append!(t);
select * from dt;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
例2
db = database("dfs://demodb", VALUE, 1..10)
t=table(take(1, 86400) as id, 2020.01.01T00:00:00 + 0..86399 as timestamp, rand(1..100, 86400) as val)
dt = db.createDimensionTable(t, "dt", {timestamp:"delta", val:"delta"})
dt.append!(t)
例3. TSDB 存储引擎下创建维度表
if(existsDatabase("dfs://dbctable_createDimensionTable")){
dropDatabase("dfs://dbctable_createDimensionTable")
}
db = database("dfs://dbctable_createDimensionTable", VALUE, 1..100, , "TSDB")
t1 = table(1 100 100 300 300 400 500 as id, 1..7 as v)
db.createDimensionTable(t1, "dt", , "id").append!(t1)
dt=loadTable("dfs://dbctable_createDimensionTable","dt")
例4. PKEY 存储引擎下创建维度表
db = database(directory="dfs://PKDB", partitionType=VALUE, partitionScheme=1..10, engine="PKEY")
schematb = table(1:0,`id1`id2`val1`val2`date1`time1,[INT,INT,INT,DECIMAL32(2),DATE,TIME])
pkt = createDimensionTable(dbHandle=db, table=schematb, tableName="pkt", primaryKey=`id1`id2, indexes={"val1": "bloomfilter", "val2": "bloomfilter"})
FILE:references/doc_8055.md
# between
**URL**: https://docs.dolphindb.cn/zh/progr/sql/between.html
**来源**: DolphinDB 官方文档
---
between
between...and 用于匹配指定范围内的所有值,包括起始值和终止值,其功能等同于 between 函数。
语法
select col(s)
from table
where col [not] between value1 and value2
例子
t = table(`APPL`AMZN`IBM`IBM`AAPL`AMZN as sym, 1.8 2.3 3.7 3.1 4.2 2.8 as price);
select * from t where price between 2 and 4
// 等价于 select * from t where price between 2:4
sym
price
AMZN
2.3
IBM
3.7
IBM
3.1
AMZN
2.8
select * from t where sym between `A and `H
sym
price
APPL
1.8
AMZN
2.3
APPL
4.2
AMZN
2.8
FILE:references/doc_807.md
# existsPartition
**URL**: https://docs.dolphindb.cn/zh/funcs/e/existsPartition.html
**来源**: DolphinDB 官方文档
---
existsPartition
语法
existsPartition(partitionUrl, [tableName])
详情
检查指定分区是否存在。
参数
partitionUrl
字符串,表示分区文件夹的路径。
tableName
字符串,表示表名。
若分区粒度为数据库级(
database
:
chunkGranularity
= 'DATABASE'),可以不指定该参数。
若分区粒度为表级(
database
:
chunkGranularity
= 'TABLE')
若
path
指定的路径包含了物理索引(通过函数
listTables
获取),可以不指定该参数。
否则,必须指定该参数。
返回值
布尔类型标量。 false 和 true 分别表示指定的分区不存在、存在。
例子
检查分区是否在分布式文件系统中(以下脚本需要在集群的数据节点/计算节点中执行):
n=1000000
ID=rand(10, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x)
db = database("dfs://valueDB", VALUE, 2017.08.07..2017.08.11)
pt = db.createPartitionedTable(t, `pt, `date);
pt.append!(t);
listTables("dfs://valueDB")
tableName
physicalIndex
pt
s
existsPartition("dfs://valueDB/20170807/s");
// output
true
//表级分区时,path 不包含物理索引,检查分区时需指定表名,否则查找不到分区信息
existsPartition("dfs://valueDB/20170807", `pt)
// output
true
existsPartition("dfs://valueDB/20170807");
// output
false
existsPartition("dfs://valueDB");
// output
false
existsPartition("dfs://valueDB/20170807/s/pt");
// output
false
FILE:references/doc_8101.md
# context by
**URL**: https://docs.dolphindb.cn/zh/progr/sql/contextBy.html
**来源**: DolphinDB 官方文档
---
context by
context by 是 DolphinDB 的独有功能,是对标准 SQL 语句的拓展。使用 context by 子句可以简化对时间序列数据的操作。
传统的关系型数据库不支持时间序列数据处理。在关系型数据库管理系统 (RDBMS) 中,一张表由行的集合组成,行之间没有顺序。尽管可以使用如 min, max, avg
等聚合函数来对行进行分组,但是不能在分组内的行使用顺序敏感的聚合函数,比如 first, last 等,或者对顺序敏感的向量函数,如 cumsum, cummax,
ratios, deltas 等。
DolphinDB 支持时间序列数据处理。context by 子句使组内处理时间序列数据更加方便。
context by 与 group by 类似,都对数据进行分组。但是,用 group by 时,每一组返回一个标量值,而用 context by
时,每一组返回一个和组内元素数量相同的向量。group by 只能配合聚合函数使用,而 context by
既可以配合聚合函数使用,也可以与移动窗口函数或累积函数等其它函数结合使用。context by 常用于基于组更新的场景,请参考
update
语句的例子。context by 还可以和 having 子句一起使用,详情参考
having
。
context by 通常与
cumsum
,
mavg
等时间序列函数一起使用,每个分组中记录的顺序对结果有直接影响。可在
context by 语句后使用 csort 关键字排序。使用 context by 分组后,csort 在 select
从句的表达式执行之前,对每个组内的数据进行排序。可对多个列(包括计算列)使用 csort 关键字,在组内进行升序(asc)或降序(desc)排序,若 csort
后不指定排序关键字,则默认是升序。csort 关键字还可以和 top 关键字一起使用,用于获取每个分组中的最新记录。
下例展示了 group by 和 context by 的不同之处。
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t1 = table(timestamp, sym, qty, price);
t1;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
select wavg(price,qty) as wvap, sum(qty) as totalqty from t1 group by sym;
sym
wvap
totalqty
C
50.828378
14800
IBM
175.085082
12200
MS
29.726389
7200
select sym, price, qty, wavg(price,qty) as wvap, sum(qty) as totalqty from t1 context by sym;
sym
price
qty
wvap
totalqty
C
49.6
2200
50.828378
14800
C
50.76
1300
50.828378
14800
C
50.32
2500
50.828378
14800
C
51.29
8800
50.828378
14800
IBM
174.97
6800
175.085082
12200
IBM
175.23
5400
175.085082
12200
MS
29.46
1900
29.726389
7200
MS
29.52
2100
29.726389
7200
MS
30.02
3200
29.726389
7200
计算每家公司的股票收益,我们不能使用 group by,但是可以使用 context by 和
ratio
函数。在使用 context by
之前,需要确保记录在每一组内已按时间排好序。
select sym, timestamp, price, eachPre(\,price)-1.0 as ret from t1 context by sym;
sym
timestamp
price
ret
C
09:34:07
49.6
C
09:34:16
50.76
0.023387
C
09:34:26
50.32
-0.008668
C
09:38:12
51.29
0.019277
IBM
09:32:47
174.97
IBM
09:35:26
175.23
0.001486
MS
09:36:42
29.46
MS
09:36:51
29.52
0.002037
MS
09:36:59
30.02
0.016938
可以使用
contextby
高阶函数来达到同样的效果,但是结果是一个向量而不是表。
contextby(eachPre{ratio}, t1.price, t1.sym);
// output
[,,1.002037,1.016938,,1.001486,1.023387,0.991332,1.019277]
这里用了一个部分应用
eachPre{ratio}
。详情参考
PartialApplication
。
对每个股票,计算每分钟累计交易量:
select *, cumsum(qty) from t1 context by sym, timestamp.minute();
timestamp
sym
qty
price
cumsum_qty
09:34:07
C
2200
49.6
2200
09:34:16
C
1300
50.76
3500
09:34:26
C
2500
50.32
6000
09:38:12
C
8800
51.29
8800
09:32:47
IBM
6800
174.97
6800
09:35:26
IBM
5400
175.23
5400
09:36:42
MS
1900
29.46
1900
09:36:51
MS
2100
29.52
4000
09:36:59
MS
3200
30.02
7200
和 top 子句一起使用:
select top 2 * from t1 context by sym;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:34:16
C
1300
50.76
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
和 top 子句一起使用时,不允许在 top 子句中指定一个范围:
select top 2:3 * from t1 context by sym;
// output
Syntax Error: [line #2] When top clause uses together with context clause in SQL query, can't specify a range in top clause
context by 与 csort、top 子句一起使用,获取每只股票时间最近两条记录:
select top 2 * from t1 context by sym csort timestamp desc;
timestamp
sym
qty
price
09:38:12
C
8800
51.29
09:34:26
C
2500
50.32
09:35:26
IBM
5400
175.23
09:32:47
IBM
6800
174.97
09:36:59
MS
3200
30.02
09:36:51
MS
2100
29.52
context by 与 limit 一起使用能够获取表中每个分组前 n 条记录或最后 n 条记录。如果 limit 后面为正数,表示取前 n 条记录;如果 limit
后面为负数,表示取最后 n 条记录。例如,获取每只股票的前 2 条记录:
select * from t1 context by sym limit 2;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
获取每只股票最后两条记录:
select * from t1 context by sym limit -2;
timestamp
sym
qty
price
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
context by 与 csort, limit 一起使用能够获取表中每个分组排序后的前 n 条记录或最后 n 条记录:
select * from t1 context by sym csort qty limit -2;
timestamp
sym
qty
price
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
09:35:26
IBM
5400
175.23
09:32:47
IBM
6800
174.97
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
从每个股票价格对数量的回归模型,计算价格的拟合值。
select *, ols(price, qty)[0]+ols(price, qty)[1]*qty as fittedPrice from t1 context by sym;
timestamp
sym
qty
price
fittedPrice
09:34:07
C
2200
49.6
50.282221
09:34:16
C
1300
50.76
50.156053
09:34:26
C
2500
50.32
50.324277
09:38:12
C
8800
51.29
51.207449
09:32:47
IBM
6800
174.97
174.97
09:35:26
IBM
5400
175.23
175.23
09:36:42
MS
1900
29.46
29.447279
09:36:51
MS
2100
29.52
29.535034
09:36:59
MS
3200
30.02
30.017687
context by 和 order by 配合使用。order by 的字段必须是 context by 结果表中的字段。
select *, ols(price, qty)[0]+ols(price, qty)[1]*qty as fittedPrice from t1 context by sym order by timestamp;
timestamp
sym
qty
price
fittedPrice
09:32:47
IBM
6800
174.97
174.97
09:34:07
C
2200
49.6
50.075318
09:34:16
C
1300
50.76
49.911222
09:34:26
C
2500
50.32
50.130017
09:35:26
IBM
5400
175.23
175.23
09:36:42
MS
1900
29.46
29.447279
09:36:51
MS
2100
29.52
29.535034
09:36:59
MS
3200
30.02
30.017687
09:38:12
C
8800
51.29
51.278686
请注意,以上例子仅用于展示,股票价格对交易量的回归没有经济意义。
context by 与 contextby 函数的区别主要有以下三个方面:
contextby 生成一个向量,而 context by 在 select 语句中使用中,结果为数据表。
contextby 只能使用一个列进行分组,而 context by 子句可以使用多个列进行分组。
contextby 每次调用都只对一个列进行计算,因此如果要对多列进行计算,contextby 效率不高。使用 context by
可以一次性完成分组,再同时对多列进行计算。
提高性能的技巧
在使用 context by 之前,若对数据按照 context by 的列进行排序,可加快 context by 的运行速度。
n=1000000
ID=rand(100, n)
x=rand(10.0, n)
ta=table(ID, x)
tb=select * from ta order by ID;
timer select (NULL \:P x)-1 as ret from ta context by ID;
// output
Time elapsed: 4.018 ms
timer select (NULL \:P x)-1 as ret from tb context by ID;
// output
Time elapsed: 2.991 ms
在特定条件下使用 context by 子句时,系统内部进行了查询优化:
若要查询分区表中某些组的最新数据,可使用 context by 配合 csort,limit。在满足以下条件时,对 context by + csort + limit
场景,系统对查询语句的性能进行了优化:
在 where 子句中对 context by 列进行了条件过滤。
csort 指定的列必须是分区列,且该列的分区方式是 VALUE 或 RANGE。
context by 与 csort 只能指定单列。
context by 指定的列也需要一起输出(通过 select 语句指定该列)。
可以通过添加
hint_explain
关键字查询执行计划来判断是否进行了优化。
FILE:references/doc_8102.md
# irCrossCurrencyCurveBuilder
**URL**: https://docs.dolphindb.cn/zh/funcs/i/irCrossCurrencyCurveBuilder.html
**来源**: DolphinDB 官方文档
---
irCrossCurrencyCurveBuilder
语法
irCrossCurrencyCurveBuilder(referenceDate, currency,
instNames, instTypes, terms, quotes, currencyPair, spot, dayCountConvention,
discountCurve, [compounding='Continuous'], [frequency='Annual'],
[curveName])
详情
构建跨币种利率互换收益率曲线。
参数
referenceDate
DATE 类型标量,指定收益率曲线的参考日期。
currency
STRING 类型标量,表示曲线定义的货币,可选值为:
"CNY":人民币
"USD":美元
"EUR":欧元
"GBP":英镑
"JPY":日元
"HKD":港币
instNames
STRING 类型向量,表示金融工具名称。
instTypes
STRING 类型向量,表示金融工具类型。
目前
instTypes
仅支持 "FxSwap",此时
instNames
必须为货币对,例如 "USDCNY"。
terms
STRING 或 DURATION 类型向量,表示合约剩余期限,例如 "1M"。
quotes
数值类型向量,表示构建曲线所需的市场报价。
currencyPair
STRING 类型标量,表示货币对,形式为 "EURUSD","EUR.USD" 或
"EUR/USD"。支持的货币对包括:
EURUSD:欧元兑美元
USDCNY:美元兑人民币
EURCNY:欧元兑人民币
GBPCNY:英镑兑人民币
JPYCNY:日元兑人民币
HKDCNY:港币兑人民币
spot
DOUBLE 类型标量,表示参考日期的即期汇率。
dayCountConvention
STRING 类型,表示计息日数规则,可选值为:
"Actual360": 实际/360
"Actual365": 实际/365
"ActualActualISMA": 实际/实际,遵循 ISMA(International Securities Market
Association,国际证券市场协会)规则
"ActualActualISDA":实际/实际,遵循 ISDA(International Swaps and Derivatives
Association,国际掉期及衍生工具协会)规则。
"Thirty360EU": 欧洲 30/360
"Thirty360US": 美国 (NASD) 30/360
discountCurve
MKTDATA 类型对象(IrYieldCurve),表示货币对中另一方的贴现曲线,必须由 bootstrap
方法构建。曲线所需包含的关键字段见
曲线字段要求
。
compounding
可选参数,STRING 类型标量,表示利率复利方式。可选值为:
"Compounded":离散复利。
"Simple":简单复利。
"Continuous":默认值,连续复利。
frequency
可选参数,STRING 类型标量,表示计算计息频率。可选值为:
"NoFrequency":无计息频率
"Annual":每年付息一次
"Semiannual":每半年付息一次
"EveryFourthMonth":每四个月付息一次
"Quarterly":每季度付息一次
"BiMonthly":每两月付息一次
"Monthly":每月付息一次
"EveryFourthWeek":每四周付息一次
"BiWeekly":每两周付息一次
"Weekly":每周付息一次
"Daily":每日付息一次
"Other":其他计息频率
curveName
可选参数,STRING 类型标量,表示生成的曲线名称,默认为空。
返回值
MKTDATA 类型对象。
例子
// 以2025年8月18日的USDCNY美元隐含收益率曲线构建为例
refDate = 2025.08.18
spotDate1 = temporalAdd(refDate, 2, "XNYS") //美元的即期日
spotDate2 = temporalAdd(refDate, 2, "CFET") //人民币的即期日
spotDate = max(spotDate1, spotDate2)
instNames = take("USDCNY", 13)
instTypes = take("FxSwap", 13)
terms = ["1d", "1w", "2w", "3w", "1M", "2M", "3M", "6M", "9M", "1y", "18M", "2y", "3y"]
curveDates = array(DATE)
for(term in terms){
dur = duration(term)
days1 = transFreq(temporalAdd(spotDate, dur), "XNYS", "right", "right")
days2 = transFreq(temporalAdd(spotDate, dur), "CFET", "right", "right")
curveDates.append!(max(transFreq(temporalAdd(spotDate, dur), "XNYS", "right", "right"), transFreq(temporalAdd(spotDate, dur), "CFET", "right", "right")))
}
quotes = [-5.54,
-39.00,
-75.40,
-113.20,
-177.00,
-317.00,
-466.00,
-898.50,
-1284.99,
-1676.00,
-2320.00,
-2870.00,
-3962.50] \ 10000 // fx swap points
cnyShibor3m = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"version": 0,
"referenceDate": refDate,
"currency": "CNY",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"dates": curveDates,
"values": [1.5113,
1.5402,
1.5660,
1.5574,
1.5556,
1.5655,
1.5703,
1.5934,
1.6040,
1.6020,
1.5928,
1.5842,
1.6068] \ 100,
"settlement": spotDate
}
cnyShibor3m = parseMktData(cnyShibor3m)
spot = 7.1627
curve = irCrossCurrencyCurveBuilder(refDate, "USD", instNames, instTypes, terms, quotes, "USDCNY", spot, "Actual365", cnyShibor3m, "Continuous")
curveDict = extractMktData(curve)
for(i in 0..(size(quotes)-1) ){
print(curveDict["values"][i]*100)
}
相关函数:
bondYieldCurveBuilder
,
irSingleCurrencyCurveBuilder
,
parseMktData
曲线字段要求
字段名
类型
描述
是否必填
mktDataType
STRING
固定填 "Curve"
是
referenceDate
DATE
参考日期
是
version
INT
版本号,默认值 0
否
curveType
STRING
固定填 "IrYieldCurve"
是
dayCountConvention
STRING
曲线的日期计数惯例,可选值为:
"Actual360":实际天数除以360
"Actual365":实际天数除以365(不区分闰年)
"ActualActualISMA":实际天数/实际天数(ISMA规则)
"ActualActualISDA":实际天数/实际天数(ISDA规则)
是
interpMethod
STRING
内插方法,可选值为:
"Linear":线性插值
"CubicSpline":三次样条插值
"CubicHermiteSpline":三次埃尔米特样条插值
是
extrapMethod
STRING
外插方法,可选值为:
"Flat":平插
"Linear":线性插值
是
dates
DATE 向量
数据点的日期
是
values
DOUBLE 向量
数据点的值,与
dates
中的元素一一对应
是
curveName
STRING
曲线名称
否
currency
STRING
货币,可选值为"CNY", "USD", "EUR", "GBP", "JPY", "HKD"
是
compounding
STRING
复利类型,可选值为:
"Simple":单利
"Compounded":离散复利
"Continuous":连续复利
是
settlement
DATE
结算日,如果指定了结算日,则后续期限间隔的计算都将从
settlement
开始,而不是
referenceDate
否
frequency
INTEGRAL或 STRING
计息频率,可选值为:
-1 或 "NoFrequency":无效计息频率
0 或 "Once":到期一次还本付息
1 或 "Annual":每年付息一次
2 或 "Semiannual":每半年付息一次
3 或 "EveryFourthMonth":每四个月付息一次
4 或 "Quarterly":每季度付息一次
6 或 "BiMonthly":每两月付息一次
12 或 "Monthly":每月付息一次
13 或 "EveryFourthWeek":每四周付息一次
26 或 "BiWeekly":每两周付息一次
52 或 "Weekly":每周付息一次
365 或 "Daily":每日付息一次
999 或 "Other":其他计息频率
否
curveModel
STRING
曲线构建模型,目前仅支持 "Bootstrap"。
否
curveParams
DICT
模型的参数。
否
FILE:references/doc_8103.md
# update
**URL**: https://docs.dolphindb.cn/zh/progr/sql/update.html
**来源**: DolphinDB 官方文档
---
update
update 语句用于更新数据表中的记录。
详情
update 语句不仅支持更新内存表,也支持更新没有正在写入数据的 DFS
表(分布式表与维度表)。当更新分布式表时,系统把要更新记录所在的分区整体更新;更新维度表时,系统将该表整体更新。因此更新分布式表仅适用于低频更新任务,例如分钟级更新任务;不适用于高频更新任务,例如毫秒级更新任务。自
2.00.10 版本开始,支持对
OLAP 和 TSDB 引擎(设置 keepDuplicates=ALL
时)下
分布式表的分区列进行更新。
更新采取了多版本的方式,并且支持事务。系统会创建一个新的版本以存储新的数据。提交事务之前,其他 SQL
语句仍然访问旧版本的数据。若更新涉及多个分区,只要其中某一个分区更新失败,系统会回滚所有分区的修改。
通过查看
分布式表数据更新原理和性能
中“数据更新原理”章节的内容来了解分布式表的更新原理。
通过 update 语句,可以使用向量或数组向量更新数组向量列,详情参考例4,例5。0
注:
暂不支持更新内存分区表的数组向量列。
暂不支持通过表连接更新内存表的数组向量列。
注:
自 3.00.0 版本起,支持 catalog 结构。
自 2.00.12 版本起,update 语句支持在 context by 子句中使用 csort 指定顺序;支持使用 having
指定只对满足聚合函数条件的分组进行更新;支持通过 having 使用非聚合函数、或者混用非聚合函数与聚合函数对满足条件的分组进行更新。可参考例3。
注:
update 语句无法改变列的数据类型。
根据分布式表的更新原理,update 操作首先获取数据所在的分区,然后在每个分区内进行数据更新,最后将更新后的分区写回磁盘。因此,DolphinDB
限制了对跨分区数据进行更新操作。当 update 语句的 set 部分使用聚合函数、序列函数或自定义函数,这些操作不能跨分区执行。然而,当 update
与 context by 结合使用,且 context by 指定了所有分区列时,set 部分可以使用聚合函数、序列函数或自定义函数。这里
context by 指定分区列两种情况:一是直接使用原始分区列,二是对分区列使用时间转换函数,此时,分区类型必须是 VALUE 或
RANGE,且转换后的时间精度必须和分区方案中指定的时间列类型相同。可参考下面例2。
语法
update
table_name
set col1=X1, [col2=X2,...]
[from table_joiner(table_names)]
[where condition(s)]
[context by col_name(s)]
例子
例 1:更新内存表
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t1 = table(timestamp, sym, qty, price);
t1;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
使用 update 语句创建新的列,该列的值为空。
update t1 set vol=long();
t1;
timestamp
sym
qty
price
vol
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
t1.drop!(`vol);
// 将 t1 还原到初始状态
更新 t1 表,将股票符号为 C 的记录的 price 列加 $0.5 以及 qty 列减 50。
update t1 set price=price+0.5, qty=qty-50 where sym=`C;
t1;
timestamp
sym
qty
price
09:34:07
C
2150
50.1
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1250
51.26
09:34:26
C
2450
50.82
09:38:12
C
8750
51.79
update t1 set price=price-0.5, qty=qty+50 where sym=`C;
// 将 t1 还原到初始状态
使用
contextBy
更新一张表。context by
可以用来做分组调整,而 contextby 不可。下例首先使用 context by 计算每只股票的平均价格,然后将每个记录的原始价格减去平均价格。
update t1 set price=price-avg(price) context by sym;
t1;
timestamp
sym
qty
price
09:34:07
C
2150
-0.8925
09:36:42
MS
1900
-0.206667
09:36:51
MS
2100
-0.146667
09:36:59
MS
3200
0.353333
09:32:47
IBM
6800
-0.13
09:35:26
IBM
5400
0.13
09:34:16
C
1250
0.2675
09:34:26
C
2450
-0.1725
09:38:12
C
8750
0.7975
使用表连接来更新表。
item = table(1..10 as id, 10+rand(100,10) as qty, 1.0+rand(10.0,10) as price)
promotion = table(1..10 as id, rand(0b 1b, 10) as flag, 0.5+rand(0.4,10) as discount);
item;
id
qty
price
1
23
7.839664
2
44
7.635988
3
76
5.378054
4
91
8.078173
5
11
10.316152
6
58
9.510634
7
90
1.643082
8
68
5.787797
9
52
7.53352
10
62
6.222249
promotion;
id
flag
discount
1
0
0.650346
2
0
0.697081
3
0
0.774207
4
1
0.819562
5
0
0.710393
6
0
0.728223
7
1
0.602512
8
0
0.71226
9
1
0.606631
10
0
0.765697
update item set price = price*discount from ej(item, promotion, `id) where flag=1;
item;
id
qty
price
1
23
7.839664
2
44
7.635988
3
76
5.378054
4
91
6.620566
5
11
10.316152
6
58
9.510634
7
90
0.989976
8
68
5.787797
9
52
4.570069
10
62
6.222249
例 2. 更新分布式表
login(`admin, `123456)
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x)
db=database("dfs://rangedb123", RANGE, 0 5 10)
pt=db.createPartitionedTable(t, `pt, `ID)
pt.append!(t)
pt=loadTable("dfs://rangedb123", `pt)
select avg(x) from pt;
// output: 0.4999
update pt set x=x+1;
pt=loadTable("dfs://rangedb123", `pt)
select avg(x) from pt;
// output: 1.4999
//不允许使用序列函数对跨分区数据进行更新,因此会报错。
update pt set x=prev(x)
// update pt set x = prev(x) => Aggregate or order-sensitive functions are not allowed without context by clause when updating a partitioned table.
update pt set x=prev(x) context by ID
//搭配 context by 将数据更新限制在分区内时,可以正确执行。
select TOP 10* from pt order by ID
/*
ID x
0
0 1.4483
0 1.6277
0 1.7735
0 1.4349
*/
例3 在 context by 子句中使用 csort, having 进行更新
login("admin", "123456")
dbName = "dfs://time_comparison"
if(existsDatabase(dbName))
dropDatabase(dbName)
db = database(dbName, VALUE, [2019.12M,2020.01M,2020.02M,2020.03M,2021.01M,2021.02M,2021.03M,2021.12M,2022.01M],engine="TSDB")
n = 100
t = table(n:n,[`time,`id,`value],[MONTH,INT,DOUBLE])
t[`time] = take([2019.12M,2020.01M,2020.02M,2020.03M,2021.01M,2021.02M,2021.03M,2021.12M,2022.01M],n)
t[`id] = take(1..10,n)
t[`value] = rand(100.0,n)
pt = db.createPartitionedTable(t, `pt, `time, sortColumns=`time).append!(t)
pnodeRun(flushIotCache)
update pt set value = 1
select * from pt where time = 2019.12M order by time, id
此时返回初始 pt:
time
id
value
2019.12M
1
1
2019.12M
1
1
2019.12M
2
1
2019.12M
3
1
2019.12M
4
1
2019.12M
5
1
2019.12M
6
1
2019.12M
7
1
2019.12M
8
1
2019.12M
9
1
2019.12M
10
1
2019.12M
10
1
不使用 csort 进行更新:
update pt set value = cumsum(value) context by time;
select * from pt where time = 2019.12M order by time, id
返回:
time
id
value
2019.12M
1
1
2019.12M
1
11
2019.12M
2
10
2019.12M
3
9
2019.12M
4
8
2019.12M
5
7
2019.12M
6
6
2019.12M
7
5
2019.12M
8
4
2019.12M
9
3
2019.12M
10
2
2019.12M
10
12
将 pt 恢复至初始,使用 csort 进行更新:
update pt set value = 1
update pt set value = cumsum(value) context by time csort id;
select * from pt where time = 2019.12M order by time, id
返回:
time
id
value
2019.12M
1
1
2019.12M
1
2
2019.12M
2
3
2019.12M
3
4
2019.12M
4
5
2019.12M
5
6
2019.12M
6
7
2019.12M
7
8
2019.12M
8
9
2019.12M
9
10
2019.12M
10
11
2019.12M
10
12
csort 支持升序(asc)或降序(desc)语法。以下将 pt 恢复至初始进行示例:
update pt set value = 1
update pt set value = cumsum(value) context by time csort id desc, value asc;
select * from pt where time = 2019.12M order by time, id
返回:
time
id
value
2019.12M
1
11
2019.12M
1
12
2019.12M
2
10
2019.12M
3
9
2019.12M
4
8
2019.12M
5
7
2019.12M
6
6
2019.12M
7
5
2019.12M
8
4
2019.12M
9
3
2019.12M
10
1
2019.12M
10
2
将 pt 恢复至初始,使用 having 指定部分更新,若满足 having 条件则进行更新:
update pt set value = 1
update pt set value = cumsum(value) context by time having sum(id) > 60
select * from pt where time = 2019.12M order by time, id
返回:
time
id
value
2019.12M
1
1
2019.12M
1
11
2019.12M
2
10
2019.12M
3
9
2019.12M
4
8
2019.12M
5
7
2019.12M
6
6
2019.12M
7
5
2019.12M
8
4
2019.12M
9
3
2019.12M
10
2
2019.12M
10
12
将 pt 恢复至初始,同时使用 csort 和 having 进行更新:
update pt set value = 1
update pt set value = cumsum(value) context by time csort id having sum(id) > 60;
select * from pt where time = 2019.12M order by time, id
返回:
time
id
value
2019.12M
1
1
2019.12M
1
2
2019.12M
2
3
2019.12M
3
4
2019.12M
4
5
2019.12M
5
6
2019.12M
6
7
2019.12M
7
8
2019.12M
8
9
2019.12M
9
10
2019.12M
10
11
2019.12M
10
12
having 支持使用非聚合函数,也支持混用非聚合函数与聚合函数。
以下将 pt 恢复至初始,having 使用非聚合函数:
update pt set value = 1
update pt set value = cumsum(value) context by time csort id having denseRank(id) > 3
select * from pt where time = 2019.12M order by time, id
返回:
time
id
value
2019.12M
1
1
2019.12M
1
1
2019.12M
2
1
2019.12M
3
1
2019.12M
4
1
2019.12M
5
6
2019.12M
6
7
2019.12M
7
8
2019.12M
8
9
2019.12M
9
10
2019.12M
10
11
2019.12M
10
12
以下将 pt 恢复至初始,having 混用非聚合函数与聚合函数:
update pt set value = 1
update pt set value = cumsum(value) context by time csort id having denseRank(id) > 3 and sum(id) > 10000
select * from pt where time = 2019.12M order by time, id
返回:
time
id
value
2019.12M
1
1
2019.12M
1
1
2019.12M
2
1
2019.12M
3
1
2019.12M
4
1
2019.12M
5
1
2019.12M
6
1
2019.12M
7
1
2019.12M
8
1
2019.12M
9
1
2019.12M
10
1
2019.12M
10
1
例 4. 使用向量更新 DFS 表的数组向量列
通过以下脚本创建一个某一列为数组向量的分布式分区表
dbName = "dfs://updateArrayVector"
db = database(dbName,VALUE,2024.01.01..2024.01.03, engine='TSDB')
a = arrayVector(2 4 6 8 10 12, [1, 1, 1, 2, 1, 3, 1, 1, 1, 2, 1, 3])
date = take(2024.01.03 2024.01.02 2024.01.01, 6)
sym = take(`a`b`c, 6)
t = table(a as a, sym as sym, date as date)
pt=createPartitionedTable(db,t,`pt,partitionColumns=`date, sortColumns=`date)
pt.append!(t)
select * from pt
a
sym
date
[1, 3]
c
2024.01.01
[1, 3]
c
2024.01.01
[1, 2]
b
2024.01.02
[1, 2]
b
2024.01.02
[1, 1]
a
2024.01.03
[1, 1]
a
2024.01.03
更新数据
update pt set a = [2,2,3] where date = 2024.01.01
select * from pt where date = 2024.01.01
a
sym
date
[2, 2, 3]
c
2024.01.01
[2, 2, 3]
c
2024.01.01
例 5. 使用数组向量更新 DFS 表的数组向量列
更新 例4 的分布式表,此时应确保数组向量的长度与满足条件的行数相等:
update pt set a=array(INT[], 0).append!([1 2 3, 4 5]) where date = 2024.01.02
select * from pt where date = 2024.01.02
a
sym
date
[1, 2, 3]
b
2024.01.02
[4, 5]
b
2024.01.02
例 6. 自 2.00.15 版本起,支持通过 update 语句向内存表中添加 ANY 类型的列。本例向例 1 中的表 t1 添加一个 ANY 类型的列
info。
update t1 set info = [1, 2 2, 2 2, 2 2, 3 3, 3 3, 1, 1, 1]
select * from t1
timestamp
sym
qty
price
info
09:34:07
C
2,200
49.6
1
09:36:42
MS
1,900
29.46
[2,2]
09:36:51
MS
2,100
29.52
[2,2]
09:36:59
MS
3,200
30.02
[2,2]
09:32:47
IBM
6,800
174.97
[3,3]
09:35:26
IBM
5,400
175.23
[4,4]
09:34:16
C
1,300
50.76
1
09:34:26
C
2,500
50.32
1
09:38:12
C
8,800
51.29
1
FILE:references/doc_8110.md
# clip!
**URL**: https://docs.dolphindb.cn/zh/funcs/c/clip_.html
**来源**: DolphinDB 官方文档
---
clip!
语法
clip!(X, Y, Z)
详情
函数
clip
的原地修改版本,它会修改输入对象 X 的值,修改规则参考
clip
。
返回值
无。
FILE:references/doc_8119.md
# shapiroTest
**URL**: https://docs.dolphindb.cn/zh/funcs/s/shapiroTest.html
**来源**: DolphinDB 官方文档
---
shapiroTest
语法
shapiroTest(X)
详情
对样本数据进行 Shapiro-Wilk 检验。
参数
X
是一个数值向量,表示样本。
返回值
一个字典,包含以下 key:
method :字符串 "Shapiro-Wilk normality test"
pValue :p 值
W :W 统计量
例子
x = norm(0.0, 1.0, 50)
shapiroTest(x);
// output
method->Shapiro-Wilk normality test
pValue->0.621668
W->0.981612
FILE:references/doc_8128.md
# avg
**URL**: https://docs.dolphindb.cn/zh/funcs/a/avg.html
**来源**: DolphinDB 官方文档
---
avg
返回值
若
X
为向量,返回一个 DOUBLE 标量。
若
X
为矩阵,返回一个 DOUBLE 向量。
若
X
为表,返回一个表。
语法
avg(X)
详情
若
X
为向量,计算
X
的平均值。
若
X
为矩阵,计算每列的平均值。
若
X
为表,计算每列的平均值。
该函数与
mean
函数完全相同。
与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
可以是标量、数据对、向量、矩阵或表。
返回值
根据输入形式返回不同的结果:若输入为向量,返回 DOUBLE 类型标量;若输入为矩阵,返回 DOUBLE 类型向量(对每列聚合);若输入为表,返回表。
例子
avg(1 2 3 NULL)
// output
2
m=matrix(1 2 3, 4 5 6)
m
0
1
1
4
2
5
3
6
avg(m)
// output
[2,5]
FILE:references/doc_8136.md
# unifiedCall
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/unifiedCall.html
**来源**: DolphinDB 官方文档
---
unifiedCall
语法
unifiedCall(func, args)
详情
用指定的参数调用一个函数。同
call
类似,可以用在
each/peach
或
loop
/
ploop
函数中,来调用一批函数。区别在于,
call
函数的args参数个数不确定,由func传入的函数决定。 而
unifiedCall
的args只有一个,通过tuple来给func函数传入多个参数。
参数
func
是一个函数。
args
是一个tuple, tuple的每一个元素作为函数的参数。
返回值
取决于
func
的返回值。
例子
unifiedCall(sum, [1..10])
返回:55
unifiedCall(add, ([1,2,3,4,5,6,7,8,9,10],2))
返回:[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
each(unifiedCall, [std, max], [[matrix(1 3 5 7 9, 1 4 7 10 13)], [0..100]]);
得到:
col1
col2
3.1623
100
4.7434
100
下面这个例子,自定义一个函数,再通过unifiedCall传入参数,进行调用。
def f(a,b){return (a+2)*b}
unifiedCall(f, (5,10))
返回:70
FILE:references/doc_8137.md
# rowCovar
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowCovar.html
**来源**: DolphinDB 官方文档
---
rowCovar
语法
rowCovar(X, Y)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行计算
X
和
Y
之间的协方差
返回值
返回一个长度与输入参数行数相同的向量。
例子
m1=matrix(2 8 9 12, 9 14 11 8,-3 NULL NULL 9)
m2=matrix(11.2 3 5 9, 7 -10 8 5,17 12 18 9)
rowCovar(m1, m2)
// output
[-29.7333, -39, 3, 3.3333]
a= 110 112.3 44 98
b= 57.9 39 75 90
c= 55 64 37 78
x=array(DOUBLE[],0, 10).append!([a, b, c])
y=array(DOUBLE[],0, 10).append!([b, a, c])
rowCovar(x, y)
// output
[-327.9475, -327.9475, 295]
// 定义一个随机数据集x
x = rand(1.0, 1000000)
// 自定义了一个聚合函数,窗口长度为5,滑动计算窗口内 x 和它排序后数据的协方差
timer moving(defg(x):covar(x, sort(x)), x, 5)
// output
1928.888 ms
// movingWindowIndex 滑动选取 x 的5个元素的索引,movingTopNIndex 滑动选取 x 的5个元素排序后的索引。通过 rowCovar 函数计算
timer rowCovar(x[movingWindowIndex(x, 5)], x[movingTopNIndex(x, 5, 5)])
// output
232.407 ms
相关函数:
covar
FILE:references/doc_8146.md
# getComputeNodeCacheWarmupJobStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getcomputenodecachewarmupjobstatus.html
**来源**: DolphinDB 官方文档
---
getComputeNodeCacheWarmupJobStatus
语法
getComputeNodeCacheWarmupJobStatus([jobId])
详情
查询指定
jobId
的数据预热任务状态。省略
jobId
时返回所有预热任务的状态。
参数
jobId
可选参数,字符串标量或向量,表示预热任务的 jobId。
返回值
返回一个表,包括以下字段:
jobId:数据预热任务的 jobId。
tableName:任务对应的库表信息。
jobStatus:任务状态,包括 Pending(待执行),Running(正在执行),Finished(已完成),Error(发生错误)。
parallelism:并行度,其中 -1 代表该任务没有并行度限制。
elapsed:任务的执行时长,单位为 ms。
errMsg:错误信息。
例子
getComputeNodeCacheWarmupJobStatus()
FILE:references/doc_8156.md
# fminSLSQP
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fminslsqp.html
**来源**: DolphinDB 官方文档
---
fminSLSQP
语法
fminSLSQP(func, X0, [fprime], [constraints], [bounds],
[ftol=1e-6], [epsilon], [maxIter=100])
详情
使用顺序最小二乘编程方法(Sequential Least Squares Programming, SLSQP)找到目标函数的最小值。
参数
func
函数名,表示需要最小化的目标函数。注意:函数返回值须是数值标量类型。
X0
数值类型的标量或向量,表示使目标函数最小化的参数的初始猜测。
fprime
可选参数,函数名,表示计算
func
梯度的函数。如果为空,则使用数值微分方法来获取函数梯度。
constraints
可选参数,字典向量,表示待优化参数需满足的约束条件,每个字典应包含下列成员:
type:字符串标量,表示约束类型。有两个可选值:'eq'表示等式约束,'ineq'表示不等式约束。
fun:函数名,表示约束函数。
注意:函数返回值须是一个数值标量或向量。
jac:函数名,表示约束函数 fun 的梯度函数。
注意:函数返回值须是一个数值向量或矩阵。
注意:
假设 fun 返回值的大小为 m,待优化参数的 size 为 n,则 jac 的返回值的形状必须是(n, m)。
constraints
中的等式约束(Equality
Constraint)的数量不能超过待优化参数的大小。假设待优化参数的大小为 n,
constraints
中共有 k
个等式约束函数,
constraints
中第 i 个等式约束的约束函数 fun 的返回值大小为
len
i
,则应满足:
bounds
可选参数,数值矩阵,形状为(N,2),其中 N 为需要优化的参数数量,即 N=size(X0)。每一行的两个值(min,
max),定义了对应参数的边界。
ftol
可选参数,数值标量,正数,表示算法停止时对目标函数值的精度要求,默认值为 1e-6。
epsilon
可选参数,数值标量,正数,表示当使用数值近似方法来求解函数梯度时使用的步长。默认值为 1.4901161193847656e-08。
maxIter
可选参数,非负整数标量,表示最大迭代次数,默认值为 100。
返回值
返回一个字典,字典有以下成员:
xopt:浮点数向量,使目标函数最小化的参数值。
fopt:浮点数标量,目标函数最小值。fopt=func(xopt)。
iterations:整数标量,优化过程中执行的总迭代数。
mode:整数标量,表示算法退出时的状态。mode=0 时表示成功进行优化,取其他值表示算法异常退出
,详细说明可参考文档
jacobwilliams -
slsqp
。
例子
本例自定义条件,传入参数
f
,
X0
,
fargs
,
fprime
,
constraints
,
bounds
,使用 SLSQP 算法找到目标函数
rosen
的最小值。
def rosen(x) {
N = size(x);
return sum(100.0*power(x[1:N]-power(x[0:(N-1)], 2.0), 2.0)+power(1-x[0:(N-1)], 2.0));
}
def rosen_der(x) {
N = size(x);
xm = x[1:(N-1)]
xm_m1 = x[0:(N-2)]
xm_p1 = x[2:N]
der = array(double, N)
der[1:(N-1)] = (200 * (xm - xm_m1*xm_m1) - 400 * (xm_p1 - xm*xm) * xm - 2 * (1 - xm))
der[0] = -400 * x[0] * (x[1] - x[0]*x[0]) - 2 * (1 - x[0])
der[N-1] = 200 * (x[N-1] - x[N-2]*x[N-2])
return der
}
def eq_fun(x) {
return 2*x[0] + x[1] - 1
}
def eq_jac(x) {
return [2.0, 1.0]
}
def ieq_fun(x) {
return [1 - x[0] - 2*x[1], 1 - x[0]*x[0] - x[1], 1 - x[0]*x[0] + x[1]]
}
def ieq_jac(x) {
ret = matrix(DOUBLE, 2, 3)
ret[0,:] = [-1.0, -2*x[0], -2*x[0]]
ret[1,:] = [-2.0, -1.0, 1.0]
return ret
}
eqCons=dict(STRING, ANY)
eqCons[`type]=`eq
eqCons[`fun]=eq_fun
eqCons[`jac]=eq_jac
ineqCons=dict(STRING, ANY)
ineqCons[`type]=`ineq
ineqCons[`fun]=ieq_fun
ineqCons[`jac]=ieq_jac
cons = [eqCons, ineqCons]
X0 = [0.5, 0]
bounds = matrix([0 -0.5, 1.0 2.0])
res = fminSLSQP(rosen, X0, rosen_der, cons, bounds, 1e-9)
res;
/* Ouput:
mode->0
xopt->[0.414944749170,0.170110501659]
fopt->0.342717574994
iterations->4
*/
FILE:references/doc_8158.md
# 教程
**URL**: https://docs.dolphindb.cn/zh/tutorials/about_tutorials.html
**来源**: DolphinDB 官方文档
---
教程
DolphinDB 是一种高性能的分布式数据库和分析计算平台,它支持海量数据的存储、管理和分析。DolphinDB
提供了灵活的查询语言和丰富的内置函数,能够进行复杂的数据处理和分析。通过
DolphinDB,用户可以轻松地进行数据清洗、统计分析、机器学习等不同场景的数据操作。DolphinDB
还具有良好的扩展性和并行计算能力,适用于金融、物联网等多个领域的数据处理需求。
通过 DolphinDB
教程,用户可以学习如何利用这个强大的工具来处理和分析各种类型的数据,从而提高工作效率和实现数据处理目标。请根据本章节的子目录选择浏览您感兴趣的教程。
FILE:references/doc_8159.md
# getQueryStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getQueryStatus.html
**来源**: DolphinDB 官方文档
---
getQueryStatus
语法
getQueryStatus()
详情
获取由当前节点发起且正在执行的查询任务状态。
参数
无
返回值
返回一个表,包含以下几列:
id:表示到该查询任务为止,系统已执行的查询任务总数。
sessionId:任务发起会话的 id。请注意,无法获取通过
submitJob
提交的查询任务的 sessionId。
userId:任务发起会话的用户名。
query:原始查询语句中主要的查询信息。
startTime:查询任务开始的时间戳。
elapsedTimeInMs:查询任务已经经过的时间,单位为毫秒。
memoryUsage:查询过程中变量和结果所占用的内存空间,单位为字节。
totalTaskCount:查询子任务总数。
completedTaskCount:已完成的查询子任务数。
percentComplete:已完成的查询子任务占比。
该函数只能在任务发起节点上调用。
例子
getQueryStatus();
id
sessionId
userId
query
startTime
elapsedTimeInMs
memoryUsage
totalTaskCount
completedTaskCount
percentComplete
2
1166953221
admin
select ticker, id, x from pt
2022.06.14 08:15:00.606
1052
184550000
4
1
0.25
FILE:references/doc_8161.md
# dropColumns!
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropColumns_.html
**来源**: DolphinDB 官方文档
---
dropColumns!
语法
dropColumns!(table, colNames)
别名:
drop!
详情
从表中删除指定的列。请注意,对于分布式表,不支持删除分区列。
参数
table
一个内存表或分布式表(仅支持 OLAP 引擎)。
colNames
表示列名的标量或向量。若
table
是分布式表,则
colNames
只能是标量。
返回值
无。
例子
t=table(1 2 3 as x, 4 5 6 as y, 7..9 as z, 10..12 as a, 13..15 as b, 16..18 as c);
t;
x
y
z
a
b
c
1
4
7
10
13
16
2
5
8
11
14
17
3
6
9
12
15
18
t.dropColumns!(`x);
y
z
a
b
c
4
7
10
13
16
5
8
11
14
17
6
9
12
15
18
dropColumns!(t, `a`b);
y
z
c
4
7
16
5
8
17
6
9
18
FILE:references/doc_8179.md
# skew
**URL**: https://docs.dolphindb.cn/zh/funcs/s/skew.html
**来源**: DolphinDB 官方文档
---
skew
语法
skew(X, [biased=true])
详情
计算
X
的倾斜度。
skew
函数在计算时会忽略 NULL 值。
DolphinDB 使用以下公式计算倾斜度:
当
biased
=true 时,
当
biased
= false 时
若
X
为矩阵,计算每列的倾斜度,返回一个向量。
若
X
为表,计算每列的倾斜度,返回一个表。
skew
函数也支持校正偏差查询分区表和分布式表。
参数
X
是一个向量、矩阵或表。
biased
是一个布尔值,表示是否为有偏估计。默认值为 true,表示为有偏估计。
biased
值为 false ,表示无偏估计。
返回值
DOUBLE 类型的标量、向量或表。
例子
下面的例子使用了
norm
函数生成数据,每次生成的数据都会有细微差别,因此每次计算的结果会有所偏差。
x=norm(0, 1, 1000000);
skew(x);
返回:-0.00124
x[0]=100;
skew(x);
返回:0.983656
m=matrix(1..10, 1 2 3 4 5 6 7 8 9 100);
m;
返回:
#0
#1
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
100
skew(m);
返回:[0,2.630083823883674]
FILE:references/doc_8181.md
# getRecoveryWorkerNum
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getRecoveryWorkerNum.html
**来源**: DolphinDB 官方文档
---
getRecoveryWorkerNum
语法
getRecoveryWorkerNum()
详情
获取当前节点用于 chunk 恢复的工作线程数。
参数
无
返回值
整型标量。
例子
resetRecoveryWorkerNum(2)
getRecoveryWorkerNum()
// output: 2
相关函数:
resetRecoveryWorkerNum
FILE:references/doc_8182.md
# extractTextSchema
**URL**: https://docs.dolphindb.cn/zh/funcs/e/extractTextSchema.html
**来源**: DolphinDB 官方文档
---
extractTextSchema
语法
extractTextSchema(filename, [delimiter], [skipRows=0])
详情
生成输入数据文件的表的结构。表的结构有两列:列名和数据类型。
数据文件中包含了表达时间、日期的数据时:
满足分隔符要求的这部分数据(日期数据分隔符包含"-"、"/"和".",时间数据分隔符为":")会转换为相应的类型。例如,"12:34:56"转换为SECOND类型;"23.04.10"转换为DATE类型。
对于不包含分隔符的数据,形如"yyMMdd"的数据同时满足0<=yy<=99,0<=MM<=12,1<=dd<=31,会被优先解析成DATE;形如"yyyyMMdd"的数据同时满足1900<=yyyy<=2100,0<=MM<=12,1<=dd<=31会被优先解析成DATE。
注:
从
2.00.10
版本开始,
loadText
支持加载一条记录中包含多个换行符的数据文件。
参数
filename
字符串,表示输入数据的绝对路径或相对路径。仅支持 CSV 格式的文件。若传入其他格式文件,则无法保证数据准确性。
delimiter
字符串标量,表示数据文件中各列的分隔符。分隔符可以是一个或多个字符,默认是逗号(",")。
skipRows
是0到1024之间的整数,表示从文件头开始忽略的行数。它是一个可选参数。默认值为0。
返回值
返回一个表,包含两列:
name:字符串,表示列名。
type:字符串,表示数据类型。
例子
n=1000000
timestamp=09:30:00+rand(18000,n)
ID=rand(100,n)
qty=100*(1+rand(100,n))
price=5.0+rand(100.0,n)
t1 = table(timestamp,ID,qty,price)
saveText(t1, "/home/DolphinDB/Data/t1.txt")
schema=extractTextSchema("/home/DolphinDB/Data/t1.txt");
schema;
name
type
timestamp
SECOND
ID
INT
qty
INT
price
DOUBLE
FILE:references/doc_8189.md
# mrank
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mrank.html
**来源**: DolphinDB 官方文档
---
mrank
语法
mrank(X, ascending, window, [ignoreNA=true], [tiesMethod='min'],
[percent=false], [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
元素在其对应窗口内的排名。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
ascending
是一个布尔值,表示是否按升序排序。默认值是 true。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
ignoreNA
是一个布尔值,表示是否忽略 NULL 值。true 表示忽略 NULL 值(默认值),false 表示 NULL 值参与排名,此时
NULL 值为最小值。
tiesMethod
是一个字符串,表示窗口内若存在重复值时,排名如何选取。'min' 表示取最小排名,'max' 表示取最大排名,'average'
表示取排名的均值。
percent
是一个布尔值,表示是否以百分比形式显示返回的排名,默认值为 false。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
返回一个向量、矩阵或表,具体取决于输入参数
X
的形式。
当
percent=false
时,返回整数类型,表示元素在窗口内的排名位置(从0开始)。
当
percent=true
时,返回浮点数类型的百分比值,范围在0到1之间。
例子
X = 3 2 4 4 4 NULL 1
mrank(X, ascending=false, window=3, ignoreNA=true);
// output: [,,0,0,0,,1]
mrank(X, ascending=false, window=3, ignoreNA=true, minPeriods=2);
// output: [,1,0,0,0,,1]
mrank(X, ascending=false, window=3, ignoreNA=false, tiesMethod='max');
// output: [,,0,1,2,2,1]
mrank(X, ascending=false, window=3, ignoreNA=false, tiesMethod='max', minPeriods=2);
// output: [,1,0,1,2,2,1]
mrank(X, ascending=false, window=3, ignoreNA=false, tiesMethod='min');
// output: [,,0,0,0,2,1]
mrank(X, ascending=false, window=3, ignoreNA=false, tiesMethod='min', minPeriods=3);
// output: [,,0,0,0,,]
mrank(X, ascending=false, window=3, ignoreNA=false, tiesMethod='average');
// output: [,,0,0.5,1,2,1]
mrank(X, ascending=false, window=3, ignoreNA=false, tiesMethod='average', minPeriods=2);
// output: [,1,0,0.5,1,2,1]
m=matrix(1 2 5 3 4, 5 4 1 2 3);
m;
#0
#1
1
5
2
4
5
1
3
2
4
3
mrank(m, true, 3);
#0
#1
2
0
1
1
1
2
mrank(m, true, 3, percent=true);
col1
col2
1
0.3333
0.6667
0.6667
0.6667
1
m=matrix([1 4 2 4 5 7 4 3 2 5])
m.rename!(2020.01.01..2020.01.10, [`A])
m.setIndexedMatrix!()
mrank(m,window=3d,percent = 1)
label
A
2020.01.01
1
2020.01.02
1
2020.01.03
0.6667
2020.01.04
0.6667
2020.01.05
1
2020.01.06
1
2020.01.07
0.3333
2020.01.08
0.3333
2020.01.09
0.3333
2020.01.10
1
mrank(m, window=1w, percent = 1)
label
A
2020.01.01
1
2020.01.02
1
2020.01.03
0.6667
2020.01.04
0.75
2020.01.05
1
2020.01.06
1
2020.01.07
0.4286
2020.01.08
0.2857
2020.01.09
0.1429
2020.01.10
0.7143
相关函数:
rank
FILE:references/doc_8197.md
# valueChanged
**URL**: https://docs.dolphindb.cn/zh/funcs/v/valueChanged.html
**来源**: DolphinDB 官方文档
---
valueChanged
语法
valueChanged(X, [mode="prev"])
详情
X
中每个元素较
mode
是否发生变化,若当前元素值发生变化,则返回 true,否则返回 false。若比较对象不存在,则返回
false。例如:valueChanged(X, [mode="prev"]) 的第一个元素返回 false;valueChanged(X,
[mode="next"]) 的最后一个元素返回 false。
若
X
为矩阵/表,在每列内进行上述操作,返回一个矩阵/表。
参数
X
字符串、布尔、时间或数值类型的向量/矩阵/表/元组。
mode
字符串,可选值为:"prev", "next", "either" 和 "both",默认值为 "prev"。
"prev":前一个元素。
"next":后一个元素。
"either":前一个元素或后一个元素。
"both":前一个元素和后一个元素值。
返回值
布尔类型,数据形式同
X
。
例子
x= 1 2 2 2 2 3 NULL 3 4 8
valueChanged(x)
// output
[false,true,false,false,false,true,true,true,true,true]
valueChanged(x,"next")
// output
[true,false,false,false,true,true,true,true,true,false]
valueChanged(x,"either")
// output
[true,true,false,false,true,true,true,true,true,true]
valueChanged(x,"both")
// output
[false,false,false,false,false,true,true,true,true,false]
tup=(1 2 3, `A`A`B, 2021.10.12+1 2 2)
valueChanged(tup)
// output
([false,true,true],[false,false,true],[false,true,false])
m=matrix(1 2 3, 1 2 3, 1 3 3)
valueChanged(m)
col1
col2
col3
false
false
false
true
true
true
true
true
false
id= 1 2 2 2 2 3 3 4 8
sym=`A + string(1 2 2 2 2 3 3 4 8)
val=83.8 92.8 8.1 61.4 40.7 67.2 15.2 20.6 96.5
t=table(id, sym, val)
valueChanged(t)
id
sym
val
false
false
false
true
true
true
false
false
true
false
false
true
false
false
true
true
true
true
false
false
true
true
true
true
true
true
true
相关函数:
keys
FILE:references/doc_8205.md
# rowSum2
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowSum2.html
**来源**: DolphinDB 官方文档
---
rowSum2
语法
rowSum2(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行元素求平方和操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL]);
rowSum2(m);
// output
[46.51,33.8,37.06]
t1=table(1..5 as x, 6..10 as y);
t2=table(5..1 as a, 10..6 as b);
rowSum2(t1);
// output
[37,53,73,97,125]
rowSum2(t1[`x], t2, 1 1 2 2 2);
// output
[127,102,86,73,66]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2);
select sym,rowSum2(price1,price2) as price2Sum from t;
sym
priceSum
AAPL
224.83
MS
80.22
IBM
79.84
IBM
81.31
C
201.2
相关函数:
sum2
FILE:references/doc_821.md
# moveReplicas
**URL**: https://docs.dolphindb.cn/zh/funcs/m/moveReplicas.html
**来源**: DolphinDB 官方文档
---
moveReplicas
语法
moveReplicas(srcNode, destNode, chunkId,
[destVolumes])
详情
通过该函数将源节点上的一个或多个 chunk 的副本移动到目标节点。如果目标节点上已经存在该
chunk,那么系统将放弃本次操作。
该命令只能由管理员在控制节点上执行。
通过
getRecoveryTaskStatus
函数可以查看任务状态。
参数
srcNode
字符串,表示源节点的别名。
destNode
字符串,表示目标节点的别名。
chunkId
字符串/UUID 标量或向量,表示 chunk 的 ID。
destVolumes
字符串标量或向量,表示移动到目的节点的具体目录,此目录必须来自配置文件中 volumes
指定的目录。如果为向量,则优先移动到向量中位次靠前的目录下。
例子
把 "node1" 上所有 chunk 的副本移动到 "node2"的指定目录。
chunkIds=exec chunkId from pnodeRun(getChunksMeta) where node="node1"
moveReplicas("node1","node2",chunkIds,"/ddb/server/clusterDemo/data/node2/storage");
FILE:references/doc_8215.md
# getInstrumentCurrency
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentcurrency.html
**来源**: DolphinDB 官方文档
---
getInstrumentCurrency
语法
getInstrumentCurrency(instrument)
详情
根据输入的金融工具,获取该工具的货币类型。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
STRING 类型标量或向量。
例子
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"nominal": 100,
"instrumentId": "0001",
"start": 2022.05.15,
"maturity": 2032.05.15,
"dayCountConvention": "ActualActualISDA",
"coupon": 0.0276,
"issuePrice": 100.0,
"frequency": "Semiannual",
"currency": "USD"
}
ins = parseInstrument(bond)
getInstrumentCurrency(ins)
// output: USD
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_8238.md
# remoteRunWithCompression
**URL**: https://docs.dolphindb.cn/zh/funcs/r/remoteRunWithCompression.html
**来源**: DolphinDB 官方文档
---
remoteRunWithCompression
语法
remoteRunWithCompression(conn, script, args)
详情
和
remoteRun
功能和用法基本一致,唯一不同的是
remoteRunWithCompression
在传输时对脚本中大于 1024 行的表数据进行了压缩。
参数
conn
是远程数据库的连接句柄。
script
是要执行的脚本或函数名。
args
可选参数,如果
script
是函数名,
args
是函数的参数。
返回值
script
的执行结果。
FILE:references/doc_8239.md
# dropDatabase
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropDatabase.html
**来源**: DolphinDB 官方文档
---
dropDatabase
语法
dropDatabase(dbDir)
详情
删除指定数据库的所有物理文件。
自 3.00.0 版本起,支持删除 catalog 中的数据库,其引用关系也会同时被删掉。
参数
dbDir
是数据库所在的目录。对于分布式文件系统中的数据库,目录要以
"dfs://"
开始。
返回值
无。
例子
删除分布式数据库:
n=1000000
ID=rand(10, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x);
saveText(t, "C:/DolphinDB/Data/t.txt");
db = database("dfs://valueDB", VALUE, 2017.08.07..2017.08.11)
pt = loadTextEx(db, `pt1, `date, "C:/DolphinDB/Data/t.txt");
dropDatabase("dfs://valueDB")
删除本地磁盘数据库:
n=1000000
ID=rand(10, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x)
saveText(t, "C:/DolphinDB/Data/t.txt");
db = database("C:/DolphinDB/Data/rangedb", RANGE, 0 5 10)
pt = loadTextEx(db, `pt, `ID, "C:/DolphinDB/Data/t.txt");
dropDatabase("C:/DolphinDB/Data/rangedb");
FILE:references/doc_824.md
# rowImax
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowImax.html
**来源**: DolphinDB 官方文档
---
rowImax
语法
rowImax(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
返回每行元素中最大元素的索引。如果有多个相同的最大值,返回左起第一个最大值的索引。
返回值
结果为一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5 3.2, 1.5 4.8 5.9 1.7, 4.9 2.0 NULL 5.5])
print rowImax(m)
返回:[2,1,1,2]
trades = table(10:0,`time`sym`p1`p2`p3`p4`p5`vol1`vol2`vol3`vol4`vol5,[TIMESTAMP,SYMBOL,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,INT,INT,INT,INT,INT])
insert into trades values(2022.01.01T09:00:00, `A, 33.2, 33.8, 33.6, 33.3, 33.1, 200, 180, 180, 220, 200)
insert into trades values(2022.01.01T09:00:00, `A, 33.1, 32.8, 33.2, 34.3, 32.3, 150, 280, 190, 100, 220)
insert into trades values(2022.01.01T09:00:00, `A, 31.2, 32.6, 33.6, 35.3, 34.5, 220, 160, 130, 100, 110)
insert into trades values(2022.01.01T09:00:00, `A, 30.2, 32.5, 33.6, 35.3, 34.1, 200, 180, 150, 140, 120)
insert into trades values(2022.01.01T09:00:00, `A, 33.2, 33.8, 33.6, 33.3, 33.1, 180, 160, 160, 180, 200)
select rowAt(matrix(p1, p2, p3, p4, p5), rowImax(vol1, vol2, vol3, vol4, vol5)) as price from trades
返回:
price
33.3
32.8
31.2
30.2
33.1
当 args 是数组向量时,返回每行元素中的最大元素的索引,结果为一个向量:
a = 1 8 3 8 1
b = 5 8 1 3 6
c = 9 5 4 7 6
x = fixedLengthArrayVector(a, b, c)
rowImax(x)
返回:[2,0,2,0,1]
FILE:references/doc_8250.md
# 高可用集群部署与升级
**URL**: https://docs.dolphindb.cn/zh/tutorials/ha_cluster_deployment.html
**来源**: DolphinDB 官方文档
---
高可用集群部署与升级
DolphinDB 集群包括四种类型节点:控制节点(controller)、代理节点(agent)、数据节点(datanode)和计算节点(compute node)。
控制节点
:控制节点是 DolphinDB 集群的核心部分,负责收集代理节点和数据节点的心跳,监控每个节点的工作状态,管理分布式文件系统的元数据和事务日志。高可用集群中会有多个控制节点并组成一个 Raft 组,通过 Raft 协议保证多个控制节点上元数据的强一致性。
代理节点
:代理节点负责执行控制节点发出的启动和关闭数据节点或计算节点的命令。在一个集群中,每台物理服务器有且仅有一个代理节点。
数据节点
:数据节点既可以存储数据,也可以用于数据的查询和计算。每台物理服务器可以配置多个数据节点。
计算节点
:计算节点承担数据节点查询和计算的相关职能,负责响应客户端的请求并返回结果,与数据节点共同实现存储资源和计算资源有效隔离。每台物理服务器可以配置零到多个计算节点。
本教程用于在 Linux 操作系统上进行高可用集群的部署、升级、过期 License 升级,并对常见问题做出解答,便于用户快速上手 DolphinDB 。包含以下主题:
部署 DolphinDB 高可用集群
本教程示例集群的部署架构图如下:
三台部署服务器(P1, P2, P3)对应的内网 IP 地址为:
P1:10.0.0.80
P2:10.0.0.81
P3:10.0.0.82
部署本教程示例高可用集群前的要求和准备:
本教程示例集群超过了社区版试用授权许可节点数的限制,所以必须前往DolphinDB官网申请企业版 License并按第一章第二步的方法进行更新。
建议节点的 IP 地址使用内网 IP,网络使用万兆以太网。如果使用外网地址,则不能保证节点间网络传输性能。
部署数据节点或者计算节点的服务器必须部署一个代理节点,用于启动和关闭该服务器上的数据节点或计算节点。
第一步:下载
在每台服务器上下载 DolphinDB 安装包并解压。
官方下载地址:https://dolphindb.cn/product#downloads
也可以通过 Shell 指令下载。下载方式如下:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_Vrelease.zip -O dolphindb.zip
其中,
release
代表版本。例如:下载 2.00.11.3 版本的 Linux64 server,使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_V2.00.11.3.zip -O dolphindb.zip
如需下载 ABI 或 JIT 版本 server,则需要在版本号后以下划线连接 ABI 或 JIT。例如:下载 2.00.11.3 版本的 Linux64 ABI server, 使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_V2.00.11.3_ABI.zip -O dolphindb.zip
下载 2.00.11.3 版本的 Linux64 JIT 版本 server,使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_V2.00.11.3_JIT.zip -O dolphindb.zip
以此类推。
执行以下 Shell 指令解压安装包至指定路径(
/path/to/directory
):
unzip dolphindb.zip -d </path/to/directory>
注意
:安装路径的目录名中不能含有空格字符或中文字符,否则启动数据节点时会失败。
第二步:更新软件授权许可
与社区版试用授权许可相比,企业版试用授权许可支持更多的节点、CPU 核数和内存。用户拿到企业版试用授权许可,只需用其替换如下文件即可。请注意:每台服务器上的授权许可文件都需要替换。
/DolphinDB/server/dolphindb.lic
本教程示例集群超过了社区版 License 节点数的限制,可以前往DolphinDB官网申请企业版试用授权许可。
第三步:集群配置
(1)P1 需要配置的文件
登录
P1
服务器,进入
/DolphinDB/server/clusterDemo/config
目录
配置控制节点参数文件
执行以下 Shell 指令修改
controller.cfg
配置文件:
vim ./controller.cfg
mode=controller
localSite=10.0.0.80:8800:controller1
dfsReplicationFactor=2
dfsReplicaReliabilityLevel=1
dataSync=1
workerNum=4
maxConnections=512
maxMemSize=8
dfsHAMode=Raft
lanCluster=0
在这里必须修改的是
localSite
,用户需要根据实际环境指定控制节点的 IP 地址、端口号和别名。
dfsHAMode=Raft
表示配置高可用集群,集群中所有的控制节点组成一个 Raft 组。
dfsReplicationFactor
必须大于1。其余参数用户应结合自身服务器硬件配置进行合理参数调优。
如果需要配置集群 Web 管理界面外网访问,必须配置
publicName
参数,例如配置
P1
外网访问地址为 19.56.128.21 ,则需要添加配置参数:
publicName=19.56.128.21
配置集群成员参数文件
cluster.nodes
用于存放高可用集群控制节点、代理节点、数据节点和计算节点的信息。本教程配置 3 个控制节点、 3 个代理节点、3 个数据节点和 3 个计算节点,用户可以根据实际要求配置节点个数。该配置文件分为两列,第一例存放节点 IP 地址、端口号和节点别名。这三个信息由冒号分隔;第二列是说明节点类型,比如控制节点类型为
controller
,代理节点类型为
agent
,数据节点类型为
datanode
,计算节点为
computenode
。
注意:节点别名是大小写敏感的,而且在集群内必须是唯一的。
本例中集群的节点配置信息需要包含位于
P1, P2, P3
的控制节点、代理节点、数据节点和计算节点信息。执行以下 Shell 指令修改
cluster.nodes
配置文件:
vim ./cluster.nodes
localSite,mode
10.0.0.80:8800:controller1,controller
10.0.0.81:8800:controller2,controller
10.0.0.82:8800:controller3,controller
10.0.0.80:8801:agent1,agent
10.0.0.80:8802:datanode1,datanode
10.0.0.80:8803:computenode1,computenode
10.0.0.81:8801:agent2,agent
10.0.0.81:8802:datanode2,datanode
10.0.0.81:8803:computenode2,computenode
10.0.0.82:8801:agent3,agent
10.0.0.82:8802:datanode3,datanode
10.0.0.82:8803:computenode3,computenode
注意:服务器 P1, P2 和 P3 的
cluster.nodes
配置必须完全相同。
配置数据节点和计算节点参数文件
执行以下 Shell 指令修改
cluster.cfg
配置文件:
vim ./cluster.cfg
maxMemSize=32
maxConnections=512
workerNum=4
maxBatchJobWorker=4
OLAPCacheEngineSize=2
TSDBCacheEngineSize=2
newValuePartitionPolicy=add
maxPubConnections=64
subExecutors=4
lanCluster=0
enableChunkGranularityConfig=true
cluster.cfg
的配置适用于集群中所有数据节点和计算节点,用户应结合自身服务器硬件配置进行合理参数调优:
maxMemSize
推荐设置为min(服务器可用内存/节点数,license限制最大内存)*0.85,
workerNum
推荐设置为min(服务器逻辑核心数,license限制逻辑核心数),
volumes
推荐设置为ssd,且设置多块盘
如果需要配置数据节点和计算节点的 Web 交互编程界面外网访问,必须配置
publicName
参数,例如配置
P1
外网访问地址为 19.56.128.21,
P2
外网访问地址为 19.56.128.22,
P3
外网访问地址为 19.56.128.23,则需要添加配置参数:
datanode1.publicName=19.56.128.21
computenode1.publicName=19.56.128.21
datanode2.publicName=19.56.128.22
computenode2.publicName=19.56.128.22
datanode3.publicName=19.56.128.23
computenode3.publicName=19.56.128.23
注意:服务器 P1, P2 和 P3 的
cluster.cfg
配置必须完全相同
配置代理节点参数文件
执行以下 Shell 指令修改
agent.cfg
配置文件:
vim ./agent.cfg
mode=agent
localSite=10.0.0.80:8801:agent1
controllerSite=10.0.0.80:8800:controller1
sites=10.0.0.80:8801:agent1:agent,10.0.0.80:8800:controller1:controller,10.0.0.81:8800:controller2:controller,10.0.0.82:8800:controller3:controller
workerNum=4
maxMemSize=4
lanCluster=0
在这里必须修改的是
localSite, controllerSite
和
sites
。
localSite
配置代理节点信息,用户需要根据实际环境指定代理节点的 IP 地址、端口号和别名。
controllerSite
配置代理节点第一次与集群中通信的控制节点的信息,与 P1 的
controller.cfg
中的
localSite
保持一致。
sites
配置当前代理节点和集群中所有控制节点的信息,需要依次填写该代理节点和所有控制节点的 IP 地址、端口号和别名。若控制节点
controller.cfg
中的参数
localSite
有变化,即使只是节点别名有改变,所有代理节点的配置文件
agent.cfg
中的参数
controllerSite
和
sites
都应当做相应的改变。其余参数用户可根据实际情况进行调整。
(2)P2 需要配置的文件
登录
P2
服务器,进入
/DolphinDB/server/clusterDemo/config
目录
配置控制节点参数文件
执行以下 Shell 指令修改
controller.cfg
配置文件:
vim ./controller.cfg
mode=controller
localSite=10.0.0.81:8800:controller2
dfsReplicationFactor=2
dfsReplicaReliabilityLevel=1
dataSync=1
workerNum=4
maxConnections=512
maxMemSize=8
dfsHAMode=Raft
lanCluster=0
在这里必须修改的是
localSite
,用户需要根据实际环境指定控制节点的 IP 地址、端口号和别名。
dfsHAMode=Raft
表示配置高可用集群,集群中所有的控制节点组成一个 Raft 组。
dfsReplicationFactor
必须大于1。其余参数用户应结合自身服务器硬件配置进行合理参数调优。
如果需要配置集群 Web 管理界面外网访问,必须配置
publicName
参数,例如配置
P2
外网访问地址为 19.56.128.22 ,则需要添加配置参数:
publicName=19.56.128.22
配置集群成员参数文件
cluster.nodes
用于存放高可用集群控制节点、代理节点、数据节点和计算节点的信息。本教程配置 3 个控制节点、 3 个代理节点、3 个数据节点和 3 个计算节点,用户可以根据实际要求配置节点个数。该配置文件分为两列,第一例存放节点 IP 地址、端口号和节点别名。这三个信息由冒号分隔;第二列是说明节点类型,比如控制节点类型为
controller
,代理节点类型为
agent
,数据节点类型为
datanode
,计算节点为
computenode
。
注意:节点别名是大小写敏感的,而且在集群内必须是唯一的。
本例中集群的节点配置信息需要包含位于
P1, P2, P3
的控制节点、代理节点、数据节点和计算节点信息。执行以下 Shell 指令修改
cluster.nodes
配置文件:
vim ./cluster.nodes
localSite,mode
10.0.0.80:8800:controller1,controller
10.0.0.81:8800:controller2,controller
10.0.0.82:8800:controller3,controller
10.0.0.80:8801:agent1,agent
10.0.0.80:8802:datanode1,datanode
10.0.0.80:8803:computenode1,computenode
10.0.0.81:8801:agent2,agent
10.0.0.81:8802:datanode2,datanode
10.0.0.81:8803:computenode2,computenode
10.0.0.82:8801:agent3,agent
10.0.0.82:8802:datanode3,datanode
10.0.0.82:8803:computenode3,computenode
注意:服务器 P1, P2 和 P3 的
cluster.nodes
配置必须完全相同。
配置数据节点和计算节点参数文件
执行以下 Shell 指令修改
cluster.cfg
配置文件:
vim ./cluster.cfg
maxMemSize=32
maxConnections=512
workerNum=4
maxBatchJobWorker=4
OLAPCacheEngineSize=2
TSDBCacheEngineSize=2
newValuePartitionPolicy=add
maxPubConnections=64
subExecutors=4
lanCluster=0
enableChunkGranularityConfig=true
cluster.cfg
的配置适用于集群中所有数据节点和计算节点,用户应结合自身服务器硬件配置进行合理参数调优。
如果需要配置数据节点和计算节点的 Web 交互编程界面外网访问,必须配置
publicName
参数,例如配置
P1
外网访问地址为 19.56.128.21,
P2
外网访问地址为 19.56.128.22,
P3
外网访问地址为 19.56.128.23,则需要添加配置参数:
datanode1.publicName=19.56.128.21
computenode1.publicName=19.56.128.21
datanode2.publicName=19.56.128.22
computenode2.publicName=19.56.128.22
datanode3.publicName=19.56.128.23
computenode3.publicName=19.56.128.23
注意:服务器 P1, P2 和 P3 的
cluster.cfg
配置必须完全相同
配置代理节点参数文件
执行以下 Shell 指令修改
agent.cfg
配置文件:
vim ./agent.cfg
mode=agent
localSite=10.0.0.81:8801:agent2
controllerSite=10.0.0.80:8800:controller1
sites=10.0.0.81:8801:agent2:agent,10.0.0.80:8800:controller1:controller,10.0.0.81:8800:controller2:controller,10.0.0.82:8800:controller3:controller
workerNum=4
maxMemSize=4
lanCluster=0
在这里必须修改的是
localSite, controllerSite
和
sites
。
localSite
配置代理节点信息,用户需要根据实际环境指定代理节点的 IP 地址、端口号和别名。
controllerSite
配置代理节点第一次与集群中通信的控制节点的信息,与 P1 的
controller.cfg
中的
localSite
保持一致。
sites
配置当前代理节点和集群中所有控制节点的信息,需要依次填写该代理节点和所有控制节点的 IP 地址、端口号和别名。若控制节点
controller.cfg
中的参数
localSite
有变化,即使只是节点别名有改变,所有代理节点的配置文件
agent.cfg
中的参数
controllerSite
和
sites
都应当做相应的改变。其余参数用户可根据实际情况进行调整。
(3)P3 需要配置的文件
登录
P3
服务器,进入
/DolphinDB/server/clusterDemo/config
目录
配置控制节点参数文件
执行以下 Shell 指令修改
controller.cfg
配置文件:
vim ./controller.cfg
mode=controller
localSite=10.0.0.82:8800:controller3
dfsReplicationFactor=2
dfsReplicaReliabilityLevel=1
dataSync=1
workerNum=4
maxConnections=512
maxMemSize=8
dfsHAMode=Raft
lanCluster=0
在这里必须修改的是
localSite
,用户需要根据实际环境指定控制节点的 IP 地址、端口号和别名。
dfsHAMode=Raft
表示配置高可用集群,集群中所有的控制节点组成一个 Raft 组。
dfsReplicationFactor
必须大于1。其余参数用户应结合自身服务器硬件配置进行合理参数调优。
如果需要配置集群 Web 管理界面外网访问,必须配置
publicName
参数,例如配置
P3
外网访问地址为 19.56.128.23,则需要添加配置参数:
publicName=19.56.128.23
配置集群成员参数文件
cluster.nodes
用于存放高可用集群控制节点、代理节点、数据节点和计算节点的信息。本教程配置 3 个控制节点、 3 个代理节点、3 个数据节点和 3 个计算节点,用户可以根据实际要求配置节点个数。该配置文件分为两列,第一例存放节点 IP 地址、端口号和节点别名。这三个信息由冒号分隔;第二列是说明节点类型,比如控制节点类型为
controller
,代理节点类型为
agent
,数据节点类型为
datanode
,计算节点为
computenode
。
注意:节点别名是大小写敏感的,而且在集群内必须是唯一的。
本例中集群的节点配置信息需要包含位于
P1, P2,
P3
的控制节点、代理节点、数据节点和计算节点信息。执行以下 Shell 指令修改
cluster.nodes
配置文件:
vim ./cluster.nodes
localSite,mode
10.0.0.80:8800:controller1,controller
10.0.0.81:8800:controller2,controller
10.0.0.82:8800:controller3,controller
10.0.0.80:8801:agent1,agent
10.0.0.80:8802:datanode1,datanode
10.0.0.80:8803:computenode1,computenode
10.0.0.81:8801:agent2,agent
10.0.0.81:8802:datanode2,datanode
10.0.0.81:8803:computenode2,computenode
10.0.0.82:8801:agent3,agent
10.0.0.82:8802:datanode3,datanode
10.0.0.82:8803:computenode3,computenode
注意:服务器 P1, P2 和 P3 的
cluster.nodes
配置必须完全相同。
配置数据节点和计算节点参数文件
执行以下 Shell 指令修改
cluster.cfg
配置文件:
vim ./cluster.cfg
maxMemSize=32
maxConnections=512
workerNum=4
maxBatchJobWorker=4
OLAPCacheEngineSize=2
TSDBCacheEngineSize=2
newValuePartitionPolicy=add
maxPubConnections=64
subExecutors=4
lanCluster=0
enableChunkGranularityConfig=true
cluster.cfg
的配置适用于集群中所有数据节点和计算节点,用户应结合自身服务器硬件配置进行合理参数调优。
如果需要配置数据节点和计算节点的 Web 交互编程界面外网访问,必须配置
publicName
参数,例如配置
P1
外网访问地址为 19.56.128.21,
P2
外网访问地址为 19.56.128.22,
P3
外网访问地址为 19.56.128.23,则需要添加配置参数:
datanode1.publicName=19.56.128.21
computenode1.publicName=19.56.128.21
datanode2.publicName=19.56.128.22
computenode2.publicName=19.56.128.22
datanode3.publicName=19.56.128.23
computenode3.publicName=19.56.128.23
注意:服务器 P1, P2 和 P3 的
cluster.cfg
配置必须完全相同
配置代理节点参数文件
执行以下 Shell 指令修改
agent.cfg
配置文件:
vim ./agent.cfg
mode=agent
localSite=10.0.0.82:8801:agent3
controllerSite=10.0.0.80:8800:controller1
sites=10.0.0.82:8801:agent3:agent,10.0.0.80:8800:controller1:controller,10.0.0.81:8800:controller2:controller,10.0.0.82:8800:controller3:controller
workerNum=4
maxMemSize=4
lanCluster=0
在这里必须修改的是
localSite, controllerSite
和
sites
。
localSite
配置代理节点信息,用户需要根据实际环境指定代理节点的 IP 地址、端口号和别名。
controllerSite
配置代理节点第一次与集群中通信的控制节点的信息,与 P1 的
controller.cfg
中的
localSite
保持一致。
sites
配置当前代理节点和集群中所有控制节点的信息,需要依次填写该代理节点和所有控制节点的 IP 地址、端口号和别名。若控制节点
controller.cfg
中的参数
localSite
有变化,即使只是节点别名有改变,所有代理节点的配置文件
agent.cfg
中的参数
controllerSite
和
sites
都应当做相应的改变。其余参数用户可根据实际情况进行调整。
第四步:启动集群
登录服务器
P1, P2 和 P3
,进入
/DolphinDB/server
目录,第一次启动时需要修改文件权限,执行以下 Shell 指令:
chmod +x dolphindb
启动控制节点
在服务器
P1, P2 和 P3
的
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令启动控制节点:
sh startController.sh
注意:本教程示例集群在每台服务器部署了控制节点,所以需要在三台服务器上分别启动控制节点。
可以执行以下 Shell 指令,查看节点是否成功启动:
ps aux|grep dolphindb
返回如下信息说明控制节点启动成功:
启动代理节点
在服务器
P1, P2 和 P3
的
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令启动代理节点:
sh startAgent.sh
注意
:本教程示例集群在每台服务器部署了代理节点,所以需要在三台服务器上分别启动代理节点。
可以执行以下 Shell 指令,查看节点是否成功启动:
ps aux|grep dolphindb
返回如下信息说明代理节点启动成功:
启动数据节点和计算节点
可以在 Web 管理界面启动或关闭数据节点和计算节点,以及修改集群的配置。在浏览器中输入任一控制节点的 IP 地址和端口号即可进入 Web 管理界面,例如,
P2
上控制节点的 IP 为 10.0.0.81,端口号为 8800,所以访问地址为 10.0.0.81:8800,访问后可能出现如下提示,表明当前控制节点不是 leader 节点,点击确定即可自动跳转到 leader 节点:
打开后的 Web 管理界面如下。以管理用身份(默认账号:admin,默认密码:123456)登录 Web 管理界面后,用户可以通过勾选想要启动的数据节点和计算节点,再点击启动(关闭)按键即可启动(关闭)相应的数据节点和计算节点:
刷新页面后可看到对应的数据节点和计算节点已启动,如下图所示:
第五步:连接数据节点创建数据库和分区表
数据节点既可以存储数据,也可以用于数据的查询和计算。接下来通过一个例子介绍如何在 DolphinDB 集群数据节点创建数据库并写入数据。首先,打开控制节点的 Web 管理界面,点击对应的数据节点打开其 Web 交互编程界面,如下图所示(以 datanode1 为例):
也可以在浏览器直接输入数据节点的 IP 地址和端口号进入数据节点的 Web 交互编程界面。
在数据节点的 Web 交互编程界面执行以下语句创建数据库和分区表:
// 创建存储的数据库和分区表
login("admin", "123456")
dbName = "dfs://testDB"
tbName = "testTB"
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db = database(dbName, VALUE, 2021.01.01..2021.12.31)
colNames = `SecurityID`DateTime`PreClosePx`OpenPx`HighPx`LowPx`LastPx`Volume`Amount
colTypes = [SYMBOL, DATETIME, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, INT, DOUBLE]
schemaTable = table(1:0, colNames, colTypes)
db.createPartitionedTable(table=schemaTable, tableName=tbName, partitionColumns=`DateTime)
然后,执行以下语句模拟生成 5000 个股票 1天的 1 分钟 K 线数据并写入上面创建的分区表:
// 模拟数据并写入分区表
n = 1210000
randPrice = round(10+rand(1.0, 100), 2)
randVolume = 100+rand(100, 100)
SecurityID = lpad(string(take(0..4999, 5000)), 6, `0)
DateTime = (2023.01.08T09:30:00 + take(0..120, 121)*60).join(2023.01.08T13:00:00 + take(0..120, 121)*60)
PreClosePx = rand(randPrice, n)
OpenPx = rand(randPrice, n)
HighPx = rand(randPrice, n)
LowPx = rand(randPrice, n)
LastPx = rand(randPrice, n)
Volume = int(rand(randVolume, n))
Amount = round(LastPx*Volume, 2)
tmp = cj(table(SecurityID), table(DateTime))
t = tmp.join!(table(PreClosePx, OpenPx, HighPx, LowPx, LastPx, Volume, Amount))
dbName = "dfs://testDB"
tbName = "testTB"
loadTable(dbName, tbName).append!(t)
可以在交互编程界面选中函数语句跳转至弹出的网页查看函数说明。
语句执行成功后可在
交互编程
界面的左边,
数据库
一栏查看已创建的库表及字段信息。
也可在
本地变量
一栏查看已创建的变量和表,展示了变量名、变量类型、变量维度大小、占用内存大小等信息,并且可以直接点击变量名进行变量预览。
第六步:连接计算节点查询和计算
计算节点主要用于数据的查询和计算。接下来通过一个例子介绍如何在计算节点对数据库内的分区表执行查询和计算。首先,打开控制节点的 Web 管理界面,点击对应的计算节点打开其 Web 交互编程界面,如下图所示(以 computenode1 为例):
也可以在浏览器直接输入计算节点的 IP 地址和端口号进入计算节点的 Web 交互编程界面。
在计算节点的 Web 交互编程界面执行以下语句加载分区表对象,此时只加载了分区表的元数据,并未加载分区表全量数据,所以响应速度非常快:
// 加载分区表对象
pt = loadTable("dfs://testDB", "testTB")
然后,执行以下语句查询股票表中每天包含的数据条数:
// SQL 返回数据量少的时候,可以直接取回客户端展示
select count(*) from pt group by date(DateTime) as Date
语句执行成功后,查询结果会在 Web 界面下方展示:
执行以下语句计算每支股票每天的 OHLC 值:
// SQL 返回数据量较大时,可以赋值给变量,占用 server 端内存,客户端分页取回展示
result = select first(LastPx) as Open, max(LastPx) as High, min(LastPx) as Low, last(LastPx) as Close from pt group by date(DateTime) as Date, SecurityID
在这里,将计算结果赋值给了
result
变量,这样就不会直接在客户端界面直接展示,减少客户端内存占用,用户可以通过点击
本地变量
栏目下的
result
变量进行分页展示查看:
基于 Web 的集群管理
完成部署后,我们可以通过控制节点的 Web 管理界面更改集群配置。
注意
:由于高可用集群的所有配置信息由 Raft 组统一管理,高可用集群修改集群配置时,必须通过 Web 界面修改配置参数,重启后生效。Web 端会自动同步到集群中的所有配置文件。
控制节点参数配置
点击
Controller Config
按钮,可进行所在控制节点的参数配置。以下参数是在第一章中
controller.cfg
里配置的,用户可以根据实际应用在这里添加、删除、修改配置参数。这些配置信息都可以在这个界面上进行更改,修改的配置会在重启控制节点之后生效。
数据节点和计算节点参数配置
点击
Nodes Config
按钮,可进行数据节点和计算节点的参数配置。以下参数是在第一章中
cluster.cfg
里配置的,用户可以根据实际应用在这里添加、删除、修改配置参数。修改的配置会在重启数据节点和计算节点之后生效。
集群升级
第一步:正常关闭集群所有节点
登录服务器
P1, P2 和 P3
,进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
sh stopAllNode.sh
第二步:备份旧版本的元数据文件
备份控制节点元数据
高可用集群控制节点 Raft 组元数据默认存储在每个控制节点服务器的
/DolphinDB/server/clusterDemo/data/<控制节点别名>/raft
目录下。以
P1
为例,控制节点 Raft 组元数据的默认存储目录:
/DolphinDB/server/clusterDemo/data/controller1/raft
登录服务器 P1, P2 和 P3,可进入
/DolphinDB/server/clusterDemo/data/<控制节点别名>
目录执行以下 Shell 指令进行备份:
mkdir controllerBackup
cp -r raft controllerBackup
如果写入数据量超过一定的大小则还会在
/DolphinDB/server/clusterDemo/dfsMeta
目录下生成
DFSMasterMetaCheckpoint.0
文件。可进入
/DolphinDB/server/clusterDemo/dfsMeta
目录执行以下 Shell 指令备份到
controllerBackup
文件夹:
cp -r dfsMeta controllerBackup
备份数据节点元数据
数据节点的元数据默认存储在控制节点服务器的
/DolphinDB/server/clusterDemo/data/<控制节点别名>/stroage/CHUNK_METADATA
目录下,以
P1
为例,数据节点元数据的默认存储目录:
/DolphinDB/server/clusterDemo/data/datanode1/stroage/CHUNK_METADATA
登录服务器 P1, P2 和 P3,可进入
/DolphinDB/server/clusterDemo/data/<控制节点别名>/storage
目录执行以下 Shell 指令进行备份:
mkdir dataBackup
cp -r CHUNK_METADATA dataBackup
注意
:元数据文件可能通过配置文件指定存储在其它目录,如果在默认路径没有找到上述文件,可以通过查询配置文件中的
dfsMetaDir
参数和
chunkMetaDir
参数确认元数据文件的存储目录。若配置中未指定
dfsMetaDir
参数和
chunkMetaDir
参数,但是配置了
volumes
参数,
CHUNK_METADATA
目录在相应的
volumes
参数指定的目录下。
第三步:升级
注意
:当 server 在线升级到某个版本后,使用的插件也应升级到与此对应的版本。
登录服务器
P1, P2 和 P3
,进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
bash upgrade.sh
运行后将会出现如下提示:
输入 y 并点击回车后会出现如下提示:
输入 1 选择在线更新,并点击回车后会出现如下提示:
输入所需更新的版本号再点击回车即可,以更新至 2.00.9.1 版本为例,输入 2.00.9.1 后点击回车,出现如下界面则表示升级成功:
离线升级
下载升级所需版本的安装包,官方下载地址:
http://www.dolphindb.cn/downloads.html
将下载好的安装包上传至
P1,
P2
和
P3
的
/DolphinDB/server/clusterDemo
目录下,以更新至 2.00.9.1 版本为例:
登录
P1,
P2
和
P3
,进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
bash upgrade.sh
运行后将会出现如下提示:
输入 y 并点击回车后会出现如下提示:
输入 2 选择离线更新,并点击回车后会出现如下提示:
输入所需更新的版本号再点击回车即可,以更新至 2.00.9.1 版本为例,输入 2.00.9.1 后点击回车,出现如下界面则表示升级成功:
如所需更新的版本是 JIT 或 ABI 版本,则版本号应与安装包保持一致。例如,安装包名称是"DolphinDB_Linux64_V2.00.9.1_JIT.zip"时,需要输入的版本号是"2.00.9.1_JIT"。
第四步:重新启动集群
启动控制节点
在服务器
P1, P2 和 P3
的
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令启动控制节点:
sh startController.sh
启动代理节点
在服务器
P1, P2 和 P3
的
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令启动代理节点:
sh startAgent.sh
启动数据节点和计算节点
可以在 Web 管理界面启动或关闭数据节点和计算节点,以及修改集群的配置。在浏览器中输入任一控制节点的 IP 地址和端口号即可进入 Web 管理界面,例如,
P2
上控制节点的 IP 为 10.0.0.81,端口号为 8800,所以访问地址为 10.0.0.81:8800,访问后可能出现如下提示,表明当前控制节点不是 leader 节点(详细说明见5.1),点击确定即可自动跳转到 leader 节点:
打开后的 Web 管理界面如下。以管理用身份(默认账号:admin,默认密码:123456)登录 Web 管理界面后,用户可以通过勾选想要启动的数据节点和计算节点,再点击启动(关闭)按键即可启动(关闭)相应的数据节点和计算节点:
刷新页面后可看到对应的数据节点和计算节点已启动,如下图所示:
成功启动后,打开 Web 管理界面,在交互编程界面执行以下代码,查看 DolphinDB 当前版本:
version()
授权许可文件过期更新
在更新授权许可文件前,可以打开 Web 管理界面,在任一节点交互编程界面执行以下代码查看当前授权许可文件的到期时间:
use ops
getAllLicenses()
在更新授权许可文件后,可通过对比更新前后授权许可文件的到期时间确认是否更新成功
第一步:替换授权许可文件
登录服务器
P1, P2 和 P3
,用新的授权许可文件
dolphindb.lic
替换老的授权许可文件。
Linux 环境授权许可文件位置:
/DolphinDB/server/dolphindb.lic
第二步:更新授权许可文件
在线更新
打开 Web 管理界面,在任一节点交互编程界面执行以下代码完成更新,代码成功运行会返回新授权许可证的到期时间:
use ops
updateAllLicenses()
注意
:在线更新有如下要求:
License 授权的客户名称必须与原来的 License 相同。
授权的节点个数,内存大小,CPU 核个数不能比原来的小。
该函数只在执行该函数的节点生效。因此在集群环境下,需要在所有控制节点,代理节点、计算节点和数据节点上运行该函数。
License 的类型必须是 commercial(付费)类型和 free 类型,如果是 trial(试用)类型不支持在线更新。
离线更新
关闭每台服务器上的 DolphinDB 节点,然后重新启动,即可完成更新。
高可用集群的高可用功能
DolphinDB 高可用集群提供元数据高可用、数据高可用和客户端高可用的功能,可以容忍单机故障,在任一节点发生故障时,数据库依然可以正常运作,保证业务不会中断。
元数据存储在控制节点(conroller)上。为了保证元数据的高可用,DolphinDB 采用 Raft 协议,通过部署多个控制节点来组成一个 Raft 组,只要宕机的控制节点少于半数,集群仍然可提供服务。
DolphinDB 采用多副本机制,相同数据块的多个副本存储在不同的数据节点(datanode)上。即使集群中某个或多个数据节点宕机,只要集群中还有至少 1 个副本可用,那么数据库就可以提供服务。多副本的数据一致性通过二阶段提交协议来实现。
DolphinDB API 提供了自动重连和切换机制,如果当前连接的数据节点宕机,API 会尝试重连,若重连失败就会自动切换连接到其他数据节点或计算节点执行任务。节点切换对用户是透明的,用户不会感知到当前连接的节点已经切换。
DolphinDB 的高可用架构图如下:
元数据高可用
数据存储时会产生元数据,例如每个数据块存储在哪些数据节点上的哪个位置等信息。如果元数据不能使用,即使数据块完整,系统也无法正常访问数据。元数据存放在控制节点。高可用集群中会部署多个控制节点,通过元数据冗余来保证元数据服务不中断。高可用集群中的所有控制节点组成一个 Raft 组,Raft 组中只有一个 Leader,其他都是 Follower,Leader 和 Follower 上的元数据保持强一致性。数据节点和计算节点只能和 Leader 进行交互。如果当前 Leader 不可用,系统会立即选举出新的 Leader 来提供元数据服务。Raft 组能够容忍小于半数的控制节点宕机,例如包含三个控制节点的集群,可以容忍一个控制节点出现故障;包含五个控制节点的集群,可以容忍两个控制节点出现故障。要设置元数据高可用,控制节点的数量至少为 3 个,同时需要设置数据高可用,即副本数必须大于 1。对应配置文件为
controller.cfg
,对应配置参数如下:
dfsHAMode=Raft
dfsReplicationFactor=2
dfsReplicaReliabilityLevel=1
数据高可用
为了保证数据的安全和高可用,DolphinDB 支持在不同的服务器上存储多个数据副本,并且采用二阶段提交协议实现数据副本之间以及数据和元数据之间的强一致性。即使一台机器上的数据损坏,也可以通过访问其他机器上的副本数据来保证数据服务不中断。DolphinDB 之所以采用二阶段提交协议实现副本之间的一致性,主要基于三个因素的考量:(1)DolphinDB 集群是为海量数据设计的,单个集群可以支持千万级以上分区数,使用 Raft 和 Paxos 等算法创建千万级的协议组,成本太高;(2)使用 Raft 和 Paxos 等算法,查询数据时只有一个副本可用,对于 OLAP 应用场景来说过于浪费资源;(3)写入的数据如果跨分区,即使采用了 Raft 和 Paxos 等算法,仍然需要二阶段提交协议保证事务的 ACID。
副本的个数可以在配置文件
controller.cfg
中的
dfsReplicationFactor
参数来设定。高可用集群建议设置副本数为 2:
dfsReplicationFactor=2
默认情况下,DolphinDB 允许相同数据块的副本分布在同一台机器上。为了保证数据高可用,需要把相同数据块的副本分布在不同的机器上。建议在配置文件
controller.cfg
添加以下配置项:
dfsReplicaReliabilityLevel=1
客户端高可用
使用 API 与 DolphinDB server 的数据节点和计算节点进行交互时,如果连接的节点宕机,API 会尝试重连,若重连失败会自动切换到其他可用的数据节点或计算节点。这个过程对用户是透明的。目前 Java, C#, C++ 和 Python API 支持高可用。
API 的 connect 方法如下:
connect(host,port,username,password,startup,highAvailability)
使用 connect 方法连接数据节点时,只需要指定
highAvailability
参数为
true
。
以下例子设置 Java API 高可用:
import com.xxdb;
DBConnection conn = new DBConnection();
String[] sites = {"10.0.0.80:8902","10.0.0.81:8902","10.0.0.82:8902"};
boolean success = conn.connect("10.0.0.80", 8902,"admin","123456","",true, sites);
如果数据节点 10.0.0.80:8902 发生故障后不可用,API 会自动连接到
sites
中配置的其他可用的数据节点或计算节点。
常见问题解答(FAQ)
节点启动失败的可能原因
端口号被占用
如果遇到无法启动 DolphinDB 节点的情况,建议打开
/DolphinDB/server/clusterDemo/log
目录下相应节点的日志文件,若出现如下错误:
<ERROR> :Failed to bind the socket on port 8800 with error code 98
说明该节点选用的端口被其他程序占用,导致 DolphinDB 无法正常启动,修改配置文件中对应节点的端口为其它空闲端口后即可正常启动。
集群成员配置文件
cluster.nodes
第一行为空行
如果遇到无法启动 DolphinDB 节点的情况,建议打开
/DolphinDB/server/clusterDemo/log
目录下相应节点的日志文件,若出现如下错误:
<ERROR> :Failed to load the nodes file [/home/DolphinDB/server/clusterDemo/config/cluster.nodes] with error: The input file is empty.
说明服务器
P1,
P2
和
P3
的配置文件
cluster.nodes
的第一行为空行,这种情况下只需将文件中的空行删除,再重新启动节点即可。
如何通过 systemd 命令启动 DolphinDB 集群?
首先在每台服务器的
DolphinDB/server/clusterDemo
目录中创建脚本文件
controller.sh
以及
agent.sh
,其 Shell 创建命令及写入内容如下 :
vim ./controller.sh
#!/bin/bash
#controller.sh
workDir=$PWD
start(){
cd workDir && export LD_LIBRARY_PATH=$(dirname "$workDir"):$LD_LIBRARY_PATH
nohup ./../dolphindb -console 0 -mode controller -home data -script dolphindb.dos -config config/controller.cfg -logFile log/controller.log -nodesFile config/cluster.nodes -clusterConfig config/cluster.cfg > controller.nohup 2>&1 &
}
stop(){
ps -o ruser=userForLongName -e -o pid,ppid,c,time,cmd |grep dolphindb|grep -v grep|grep $USER|grep "mode controller"| awk '{print $2}'| xargs kill -TERM
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
esac
vim ./agent.sh
#!/bin/bash
#agent.sh
workDir=$PWD
start(){
cd workDir && export LD_LIBRARY_PATH=$(dirname "$workDir"):$LD_LIBRARY_PATH
nohup ./../dolphindb -console 0 -mode agent -home data -script dolphindb.dos -config config/agent.cfg -logFile log/agent.log > agent.nohup 2>&1 &
}
stop(){
ps -o ruser=userForLongName -e -o pid,ppid,c,time,cmd |grep dolphindb|grep -v grep|grep $USER|grep "mode agent"| awk '{print $2}'| xargs kill -TERM
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
esac
然后,执行以下 Shell 命令配置 controller 的守护进程:
vi /usr/lib/systemd/system/ddbcontroller.service
配置如下内容:
[Unit]
Description=ddbcontroller
Documentation=https://www.dolphindb.com/
[Service]
Type=forking
WorkingDirectory=/home/DolphinDB/server/clusterDemo
ExecStart=/bin/sh controller.sh start
ExecStop=/bin/sh controller.sh stop
ExecReload=/bin/sh controller.sh restart
Restart=always
RestartSec=10s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
注意:配置中
WorkingDirectory
需要修改为
/DolphinDB/server/clusterDemo
执行以下 Shell 命令配置 agent 的守护进程:
vi /usr/lib/systemd/system/ddbagent.service
配置如下内容:
[Unit]
Description=ddbagent
Documentation=https://www.dolphindb.com/
[Service]
Type=forking
WorkingDirectory=/home/DolphinDB/server/clusterDemo
ExecStart=/bin/sh agent.sh start
ExecStop=/bin/sh agent.sh stop
ExecReload=/bin/sh agent.sh restart
Restart=always
RestartSec=10s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
KillMode=process
[Install]
WantedBy=multi-user.target
注意
:配置中
WorkingDirectory
需要修改为
/DolphinDB/server/clusterDemo
最后,执行以下 Shell 命令启动 controller :
systemctl enable ddbcontroller.service #配置自启
systemctl start ddbcontroller.service #启动
systemctl stop ddbcontroller.service #停止服务
systemctl status ddbcontroller.service #检测状态
执行以下 Shell 命令启动 agent :
systemctl enable ddbagent.service #配置自启
systemctl start ddbagent.service #启动
systemctl stop ddbagent.service #停止服务
systemctl status ddbagent.service #检测状态
Web 管理界面无法访问怎么办?
DolphinDB 正常启动后,在浏览器输入控制节点正确的访问地址,但 Web 管理界面无法正常打开,如下图所示:
出现上述问题的原因通常是由于浏览器与 DolphinDB 不是部署在同一台服务器,且部署 DolphinDB 的服务器开启了防火墙。可以通过关闭部署了 DolphinDB 的服务器的防火墙或者打开对应的部署端口,解决这个问题。
Linux 升级失败如何版本回退?
如果升级以后,不能正常开启 DolphinDB 集群,可按以下方式回退到旧版本。
注意:版本回退必须满足升级以后未写入过新的数据。
第一步:恢复旧版本元数据文件
恢复控制节点元数据
登录控制节点的服务器(以
P1
为例),在
/DolphinDB/server/clusterDemo/data/controller1
目录执行以下 Shell 指令恢复已备份的控制节点元数据:
cp -r backup/raft ./
并在
/DolphinDB/server/clusterDemo/dfsMeta
目录执行以下 Shell 指令恢复已备份的控制节点元数据:
cp -r backup/dfsMeta ./
恢复数据节点元数据
登录数据节点的服务器(以
P1
为例),在
/DolphinDB/server/clusterDemo/data/datanode1/storage
目录执行以下 Shell 指令恢复已备份的数据节点元数据:
cp -r dataBackup/CHUNK_METADATA ./
第二步:恢复旧版本程序文件
在官方下载旧版本程序包,把重新下载的旧版本
server
目录下除
dolphindb.cfg
,
clusterDemo
以及
dolphindb.lic
外的所有文件覆盖替换升级失败的文件。
为什么在线更新授权许可文件失败?
在线更新授权文件需要满足
更新授权许可文件
中在线更新的要求。如果不满足其中的要求,可以通过离线方式进行更新,或前往 DolphinDB 官网申请企业版 License。
为什么云部署节点无法启动?
DolphinDB 集群既可以部署在局域网内,也可以部署在私有云或公有云上。DolphinDB 默认集群的所有节点在一个局域网内(
lanCluster
=1)并通过 UDP 广播来监测节点心跳。但是在云平台上,所有节点不一定位于一个局域网,也有可能不支持 UDP。所以,在云平台上,需要在
controller.cfg
和
agent.cfg
填入 lanCluster=0 来实现非 UDP 模式的节点之间的通讯。否则,由于可能无法正常检测到节点的心跳,集群可能无法正常工作。
如何进行配置参数调优?
可以参考 DolphinDB 官方参数配置说明进行配置参数调优。
如果遇到性能问题,请添加微信号13306510479 或扫描下面二维码,客服会邀您进群,由 DolphinDB 技术支持工程师会解答您的问题。
如何设置数据卷?
数据卷是位于数据节点上的文件夹,用来保存分布式文件系统的数据。一个数据节点可以有多个数据卷。要确保最优性能,每个数据卷应当对应不同的物理设备。如果多个数据卷对应同一个物理设备,会影响性能。
可在
cluster.cfg
中设置数据卷的路径。如果用户不设置数据卷的路径,系统会默认按数据节点别名来设置数据卷的路径。若节点别名为 P1-datanode,系统会自动在该节点的
/DophinDB/server/clusterDemo/data
目录下创建一个名为
P1-datanode
的子目录来存储数据。注意:数据卷只支持绝对路径,不支持相对路径。
注意
:在 linux 环境部署时,
volumes
配置目录建议不要指定用 NAS 挂载服务器路径的远程磁盘,如果这样配置,数据库性能会因为磁盘 IO 瓶颈变差。 如果非要这样配置,如果您的分区挂载用的是 NFS 协议,则该 datanode (数据节点)进程必须以 root 身份启动。因为普通用户启动的数据库进程无权限在 NAS 读写磁盘,如果用 sudo 用户启动,会造成文件夹权限混乱。
三种设置数据卷路径的方法:
对每个数据节点分别指定数据卷路径
P1-datanode.volumes=/DFS/P1-datanode
P2-datanode.volumes=/DFS/P2-datanode
通过 % 和 ? 通配符
?
代表单个字符;
%
表示 0 ,1 或多个字符。
将所有以 "-datanode" 为结尾的节点的数据存放到
/VOL1
:
%-datanode.volumes=/VOL1
等同于:
P1-datanode.volumes=/VOL1
P2-datanode.volumes=/VOL1
通过 ALIAS 通配符
若所有数据节点的数据卷路径都含有节点别名,可使用 来配置数据卷路径。可用以下代码为每台服务器配置两个物理卷
/VOL1
和
/VOL2
:
volumes=/VOL1/<ALIAS>,/VOL2/<ALIAS>
等同于:
P1-datanode.volumes=/VOL1/P1-datanode,/VOL2/P1-datanode
P2-datanode.volumes=/VOL1/P2-datanode,/VOL2/P2-datanode
附录
示例集群的配置文件
:
ha_cluster_deployment
FILE:references/doc_8252.md
# kroghInterpolateFit
**URL**: https://docs.dolphindb.cn/zh/funcs/k/kroghinterpolatefit.html
**来源**: DolphinDB 官方文档
---
kroghInterpolateFit
语法
kroghInterpolateFit(X, Y, [der=0])
详情
对一组点集进行多项式插值,该多项式通过点集中所有的点对 (X, Y)。并且可以额外指定在每个点 X 处的多个导数值:用户通过重复 X 值并将导数值指定为连续的 Y
值来实现:
当 X 只出现一次时,Y 为多项式 f(x) 的值。
当 X 出现多次时,则第一个 Y 是 f(X) 的值,第二个为对应的 X 的一阶导数值,第三个为对应的 X 的二阶导数值,依此类推。比如对于输入 X =
[0,0,1,1], Y= [1,0,2,3], 有 Y[0]=f(0),Y[1]=f'(0),Y[2]=f(1),Y[3]=f'(1)。
另外,本函数可结合
predict
函数先后使用,针对生成的模型进行预测。
参数
X
数值向量,表示用于插值的点的 x 坐标,必须是递增序列。注意:X 中不可包含 NULL 值。
Y
数值向量,表示用于插值的点的 y 坐标。注意:Y 和 X 的长度必须一致,且 Y 中不可包含 NULL 值。
der
可选参数,非负整数,表示要求的导数阶数。
der
=0 时计算多项式函数本身的值。其默认值为 0。
返回值
返回一个字典,字典有以下成员:
modelName:字符串类型,表示模型名称,值为“kroghInterpolate”。
X:数值向量,表示用于插值的点的x坐标,即输入 X。
der:非负整数,即输入 der。
coeffs:数值向量,表示根据输入数据点拟合得到的多项式系数。
predict:模型的预测函数。其使用方法为
model.predict(X)
,或者通过
predict
函数进行调用:
predict(model,
X)
。其参数为:
model:字典类型,即 kroghInterpolateFit 的输出。
X: 数值向量,表示需要求值的点的 x 坐标,
predict
函数将返回在 X
点处的多项式估值。
例子
以正弦函数为例进行多项式插值,计算 x
点处的多项式估值。
x = 0 1 2 3 4 5
y = sin(x)
model = kroghInterpolateFit(x,y)
model
/*
output:
X->[0,1,2,3,4,5]
der->0
predict->kroghInterpolateFitPredict
modelName->kroghInterpolate
coeffs->[0.0,0.841470984807,-0.386822271395,-0.010393219665,0.032025753923,-0.005411092181,0.0]
*/
根据生成的模型,自定义函数
linspace
,并传入相关参数,进一步预测模型。
def linspace(start, end, num, endpoint=true){
if(endpoint) return end$DOUBLE\(num-1), start + end$DOUBLE\(num-1)*0..(num-1)
else return start + end$DOUBLE\(num-1)*0..(num-1)
}
xx = linspace(0.0, 5.0, 10)[1]
model.predict(xx)
/*
output:
[0,0.515119011157387,0.898231239576709,0.998548648650381,0.793484053410063,0.354287125066207,-0.188319604452395,-0.678504737959061,-0.969692008469677,-0.958924274663139]
*/
相关函数:
predict,
kroghinterpolate
FILE:references/doc_8253.md
# mimax
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mimax.html
**来源**: DolphinDB 官方文档
---
mimax
语法
mimax(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
中最大元素的位置。如果窗口内存在多个相同的最大值,则返回左起第一个最大值的位置。与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
当
X
是向量时,返回一个整型向量,长度与输入向量相同。
当
X
是矩阵时,返回一个整型矩阵,形状与输入矩阵相同。
当
X
是表时,对表的每列进行计算,返回相应的结果。
当
X
是元组时,对元组中的每个向量分别计算,返回相应的结果。
例子
x = 1.2 2 NULL 6 -1 6
mimax(x, 3);
//output: [,,1,2,1,0]
mimax(x, 3, 1);
//output: [0,1,1,2,1,0]
m=matrix(1 6 2 9 10 3, 9 10 2 6 6 6);
m;
返回:
#0
#1
1
9
6
10
2
2
9
6
10
6
3
6
mimax(m,3);
#0
#1
1
1
2
0
2
1
1
0
T = [2022.01.01, 2022.01.02, 2022.01.03, 2022.01.06, 2022.01.07, 2022.01.08, 2022.01.10, 2022.01.11]
X = 1..8
X1 = indexedSeries(T, X)
mimax(X1,3)
#0
2022.01.01
0
2022.01.02
1
2022.01.03
2
2022.01.06
0
2022.01.07
1
2022.01.08
2
2022.01.10
1
2022.01.11
1
t= 2021.01.02 2021.01.05 2021.01.06 2021.01.09 2021.01.10 2021.01.12
m=matrix(5 4 NULL -1 2 4, 3 2 8 1 0 5)
m1=m.rename!(t, `a`b).setIndexedMatrix!()
mimax(m1,3)
返回结果:
a
b
2021.01.02
0
0
2021.01.05
0
0
2021.01.06
0
1
2021.01.09
0
0
2021.01.10
1
0
2021.01.12
1
1
FILE:references/doc_8265.md
# rowEuclidean
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowEuclidean.html
**来源**: DolphinDB 官方文档
---
rowEuclidean
语法
rowEuclidean(X, Y)
详情
若
X
和
Y
同时为向量/矩阵,按行计算
X
和
Y
之间的欧式距离。若
X
和
Y
同时为索引矩阵,会对齐标签,对标签相同的行进行计算,标签不同的行直接返回 NULL。
若
X
和
Y
一个为向量,一个为矩阵,则向量的长度必须与矩阵的列数相同,计算向量与矩阵每一行的欧式距离。
若
X
和
Y
是数组向量,计算
X
和
Y
对应位置的向量之间的欧式距离,即 euclidean(X.row(i),Y.row(i))。
若
X
和
Y
一个为向量,一个为数组向量,计算向量与数组向量内每个向量的欧式距离。两个向量的长度相同时返回计算结果,长度不相同时返回 NULL。
与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
和
Y
是长度相同的数值型向量或数组向量,或维度相同的矩阵。若
X
和
Y
为数组向量,它们对应位置的向量必须具有相同长度。
返回值
一个向量。
例子
rowEuclidean(3.6 5.2 6.3, 8.6 4.8 5.5)
// output
[5,0.4,0.8]
m=matrix(23 56 47, 112 94 59)
m1=matrix(11 15 89, 52 41 63)
rowEuclidean(m,m1)
// output
[61.1882,67.0075,42.19]
m.rename!(2020.01.01..2020.01.03, `A`B)
m.setIndexedMatrix!()
m1.rename!(2020.01.01 2020.01.03 2020.01.04, `A`B)
m1.setIndexedMatrix!()
rowEuclidean(m,m1)
// output
[61.1882,NULL,36.7151,NULL]
a=array(INT[],0,10)
a.append!([[1, 8, 9],[15, NULL], [25, 22, 13, 15]])
b=array(INT[],0,10)
b.append!([[11, 18, 6],[5, 9], [5, 2, 3, 1]])
rowEuclidean(a,b)
// output
[14.4568,10,33.1059]
相关函数:
euclidean
FILE:references/doc_8267.md
# getRedoLogGCStat
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getRedoLogGCStat.html
**来源**: DolphinDB 官方文档
---
getRedoLogGCStat
语法
getRedoLogGCStat()
详情
获取 redo log 垃圾回收的状态。
参数
无
返回值
返回一个表对象,包含以下几列:
physicalName:物理表名,格式为 "/数据库名/物理表名"
txnCount:redo log 尚未回收的事务数
numOfTxnPendingGC:等待回收的事务数
minTidPendingGC:等待回收的事务的最小 tid
numOfTxnPendingFlush:等待刷盘的事务数
minTidPendingFlush:等待刷盘的事务的最小 tid
例子
getRedoLogGCStat();
physicalName
txnCount
numOfTxnPendingGC
minTidPendingGC
numOfTxnPendingFlush
minTidPendingFlush
/test/pt_2
2
0
2
1031
/listdb/pt_2
1
1
1033
0
FILE:references/doc_827.md
# histogram2d
**URL**: https://docs.dolphindb.cn/zh/funcs/h/histogram2d.html
**来源**: DolphinDB 官方文档
---
histogram2d
语法
histogram2d(x, y, [bins=10], [range], [density=false],
[weights])
详情
计算两组数据样本的二维直方图。
参数
X
,
Y
两个等长的数值向量,分别作为构造二维直方图的 x 和 y 坐标值。注意:不可包含空值。
bins
可选参数,数值标量,严格递增的、长度至少为 2 的数值向量,或者由前两者组成的元组(第一个元素表示 x 维度上的特性,第二个元素表示 y
维度的特性)。默认值为 10。注意:不能包含空值。以下为传入不同形式数据的含义说明:
标量:x 和 y 两个维度箱的数目。
向量:x 和 y 两个维度分箱的边界。
标量组成的二维元组:x 和 y 两个维度分别分箱的数目。
向量组成的二维元组:x 和 y 两个维度分别分箱的边界。
标量和向量组成的二维元组:标量代表在对应维度上按照均等分箱时箱的数目;向量表示在对应维度上按给定的边界值分箱。
range
可选参数,二维向量,形状须为(2, 2),用来指定每个维度上统计图的最左边界和最右边界(如果
bins
参数未显式给出边界值时)。所有超出
range
的点将被视为异常点,不会被二维直方图统计。默认为空。
density
可选参数,布尔标量。以下为说明:
如果为 false(默认值),则表示直方图统计每个二维箱子的样本点个数。
如果为 true,则会返回每个箱子的概率密度函数。bin_count(当前箱子内的点个数)/sample_count(总样本点数)/
bin_area(每个箱子的面积)。
weights
可选参数,数值向量,长度须与
X
/
Y
相同,表示对应样本点(x_i,
y_i)的权重。默认为空。注意:传入向量时不可包含空数据。其中,
如果
density
为 true,则 weights 会被正则化到 1。
如果
density
为 false,则每个箱子在二维直方图中的值就是落入这些该箱子的所有点的权重值之和。
返回值
H:二维直方图的统计结果,形状为(nx, ny)。其中,每一个值代表落入该箱子的样本点的统计值,nx 和 ny 分别为 x 轴和 y
轴的分箱个数。
xedges:沿着 x 轴分箱时箱子的 x 轴边界,形状为(nx + 1, )。其中,nx 为 x 轴的分箱个数。
yedges:沿着 y 轴分箱时箱子的 y 轴边界,形状为(ny + 1, )。其中,ny 为 y 轴的分箱个数。
例子
例 1:传入两组数据样本,设置 x 和 y 两个维度分别分箱的边界、
density
为
false,计算其二维直方图的统计结果。
x = [0.1, 0.2, 0.5, 0.7, 0.9]
y = [0.2, 0.4, 0.6, 0.8, 1.0]
bins = [[0, 0.3, 0.6, 1.0], [0, 0.5, 1.0]]
density = false
result = histogram2d(x, y, bins, ,density)
/* Output:
H->#0 #1
-- --
2 0
0 1
0 2
xedges->[0,0.3,0.6,1]
yedges->[0,0.5,1]
*/
例 2:传入两组数据样本,设置 x 均等分箱时箱的数目、y 分箱的边界、权重、
density
为
true,计算其二维直方图的统计结果。
x = [0.2, 0.4, 0.6, 0.8, 1.0]
y = [0.3, 0.5, 0.7, 0.9, 1.1]
bins = [2, [0.3, 0.5, 1.1]]
weights = [1, 2, 3, 4, 5]
density = true
result = histogram2d(x, y, bins, ,density, weights)
/* Output:
H->#0 #1
-- --
1 5
0 9
xedges->[0.2,0.6,1]
yedges->[0.3,0.5,1.1]
*/
FILE:references/doc_8273.md
# getClusterVolumeUsage
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getClusterVolumeUsage.html
**来源**: DolphinDB 官方文档
---
getClusterVolumeUsage
语法
getClusterVolumeUsage()
详情
检查集群中各节点的磁盘使用情况。该函数只能由管理员调用。
参数
无
返回值
返回一个表,包含以下列:
node:节点名
volumePath:磁盘路径
volumeId:磁盘内部 ID
usage:当前磁盘占用量(单位字节)
capacity:磁盘总容量(单位字节)
例子
getClusterVolumeUsage()
node
volumePath
volumeId
usage
capacity
local8999
/home/server/local8999/storage
109,993,503
138,556,121,088
250,438,021,120
FILE:references/doc_829.md
# listRemotePlugins
**URL**: https://docs.dolphindb.cn/zh/funcs/l/listRemotePlugins.html
**来源**: DolphinDB 官方文档
---
listRemotePlugins
语法
listRemotePlugins([pluginName],
[pluginServerAddr])
详情
返回一个表,显示当前 DolphinDB 所支持的插件和其对应的版本信息。
注:
使用该命令获取的插件信息取决于:
DolphinDB server 版本
操作系统
如果不指定 pluginName,则返回所有插件;如果指定
pluginName,则返回指定插件;如果指定的插件不存在,则返回空。
参数
pluginName
可选,STRING 类型,用于指定插件名称。
pluginServerAddr
可选,STRING 类型,用于指定插件仓库的 HTTP 地址。如果不配置该参数,使用默认的 HTTP
地址:"http://plugins.dolphindb.cn/plugins"。如果 DolphinDB 服务位于国外,建议填写
"http://plugins.dolphindb.com/plugins" 以提高查询速度。
返回值
一张表,包含以下字段:
PluginName:插件名称。
PluginVersion:插件版本。
例子
列出插件仓库所有可用插件:
listRemotePlugins()
均会返回类似以下的插件列表:
PluginName
PluginVersion
hdf5
<PluginVersion>
matchEngine
<PluginVersion>
mongodb
<PluginVersion>
mqtt
<PluginVersion>
mseed
<PluginVersion>
mysql
<PluginVersion>
nsq
<PluginVersion>
odbc
<PluginVersion>
opc
<PluginVersion>
opcua
<PluginVersion>
zip
<PluginVersion>
其中
<PluginVersion>
为插件的版本信息,例如:
2.00.11
。
返回指定插件及其版本信息。例如,获取 MySQL 插件的版本信息:
listRemotePlugins("mysql")
返回:
PluginName
PluginVersion
mysql
2.00.11
FILE:references/doc_8320.md
# readBytes
**URL**: https://docs.dolphindb.cn/zh/funcs/r/readBytes.html
**来源**: DolphinDB 官方文档
---
readBytes
语法
readBytes(fileHandle, sizeInByte)
详情
从句柄中读取给定数目的字节。如果文件到达结尾,或发生了 IO 错误,将抛出一个
IOException;否则返回一个包含了给定数目字节的缓冲区。因此,必须在调用函数之前知道要读取的确切的字节数。
参数
fileHandle
是文件句柄。
sizeInByte
是整数,用于指定读取的字节数。
返回值
返回一个包含了给定数目字节的缓冲区。
例子
// 定义一个文件复制函数
def fileCopy(source, target){
s = file(source)
len = s.seek(0,TAIL)
s.seek(0,HEAD)
t = file(target,"w")
if(len==0) return
do{
buf = s.readBytes(min(len,1024))
t.writeBytes(buf)
len -= buf.size()
}while(len)
};
fileCopy("test.txt","testcopy.txt");
FILE:references/doc_8321.md
# deepCopy
**URL**: https://docs.dolphindb.cn/zh/funcs/d/deepCopy.html
**来源**: DolphinDB 官方文档
---
deepCopy
语法
deepCopy(obj)
详情
返回
obj
的深拷贝。即复制对象及其所有可变子对象,生成一个与原对象完全独立的新副本。
copy
(浅拷贝)和
deepCopy
(深拷贝)的区别主要体现在嵌套结构(如元组或 ANY
类型字典)中:
使用
copy
时,子对象的引用会被共享(即子对象的地址保持不变)。
使用
deepCopy
时,所有子对象都会被递归复制,引用也会完全分离。
参数
obj
可以是任意数据类型。
返回值
与
obj
相同类型对象。
例子
例1. 拷贝向量
x = 1 2 3
a = x.copy()
b = x.deepCopy();
print constantDesc(x[0]).address // 000000000dd3d640
print constantDesc(a[0]).address // 000000000cb5a4c0
print constantDesc(b[0]).address // 000000000de92c20
例2. 拷贝元组
x = ([[1, 2], [3, 4]], "a")
a = x.copy()
b = x.deepCopy();
print constantDesc(x[0]).address // 000000000c7ce880
print constantDesc(a[0]).address // 000000000c7ce880
print constantDesc(b[0]).address // 000000000c89be00
例3. 拷贝 ANY 字典
y = dict(`A`B`C, (1 2, 3 4, 5 6))
c = y.copy()
d = y.deepCopy();
print constantDesc(y[`A]).address // 000000000c88c450
print constantDesc(c[`A]).address // 000000000c88c450
print constantDesc(d[`A]).address // 000000000c7cde00
相关函数:
copy
,
asis
FILE:references/doc_8329.md
# gmtime
**URL**: https://docs.dolphindb.cn/zh/funcs/g/gmtime.html
**来源**: DolphinDB 官方文档
---
gmtime
语法
gmtime(X)
详情
把本地时间
X
转换成零时区时间,即格林尼治时间(GMT)。
参数
X
可以是 DATATIME, TIMESTAMP, NANOTIMESTAMP 类型的标量或向量。
返回值
DATETIME 类型标量或向量。
例子
以下例子在美国东部时区执行:
gmtime(2018.01.22 10:20:26);
// output: 2018.01.22T15:20:26
gmtime(2017.12.16T13:30:10.008);
// output: 2017.12.16T18:30:10.008
FILE:references/doc_8330.md
# col
**URL**: https://docs.dolphindb.cn/zh/funcs/c/col.html
**来源**: DolphinDB 官方文档
---
col
语法
col(obj, index)
或
column(obj,
index)
详情
返回向量、矩阵或表的一列或多列。参见相关函数:
row
。
参数
obj
可以是向量、矩阵或表。
index
是一个整数标量或数据对。
返回值
返回一个与输入
obj
相同数据类型和形式的对象。
例子
x=1..6$3:2;
x;
#0
#1
1
4
2
5
3
6
col(x,0);
// output
[1,2,3]
x.col(1);
// output
[4,5,6]
a=table(1..3 as x,`IBM`C`AAPL as y);
a;
x
y
1
IBM
2
C
3
AAPL
a col 1;
// output
["IBM","C","AAPL"]
col(a, 0:2)
x
y
1
IBM
2
C
3
AAPL
FILE:references/doc_834.md
# tableInsert
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tableInsert.html
**来源**: DolphinDB 官方文档
---
tableInsert
语法
tableInsert(table, args...)
详情
将
args...
插入到
table
中,并返回插入的行数。
如果
args...
是一个表,它的结构必须与
table
的结构相同。若
table
是分区表,
args...
只能是一个表。
如果
args...
是一个元组,那么它的元素个数必须与
table
的列数相同,并且每个元素的数据类型必须与
table
中与之对应的每列的数据类型相同。
如果
args...
是多个向量或元组,那么向量与元组的个数必须与
table
中列数一致,且每个向量或元组的数据类型必须与
table
中与之对应的每列的数据类型相同。
如果
args...
是一个字典,那么它的 keys 对应
table
的列名,values 对应
table
中每列的值,且 values 必须为元组。这种用法只适用于
table
为内存表的情况。
注:
若数据库为 VALUE 分区,且分区列为字符串类型,则追加的分区列数据不能包含空格,“/n”, “/r”,
“/t”。
参数
table
是表对象或表名。该表可为内存表或 DFS 表。在远程调用中,由于得不到远程表对象的引用,因此必须使用表名。
args...
可以是一个表、元组或字典,或多个向量或元组。
返回值
INT 类型标量。
例子
colName=["Name","Age"]
colType=["string","int"]
t1=table(100:0,colName, colType);
name=`Tom`Jerry`John
age=24 25 26
t2=table(name, age)
tableInsert(t1, t2);
// output
3
t1;
Name
Age
Tom
24
Jerry
25
John
26
tableInsert(t1, (`George, 29));
// output
1
t1;
Name
Age
Tom
24
Jerry
25
John
26
George
29
tableInsert(t1, (`Frank`Henry, 31 32));
// output
2
tableInsert(t1, `Nicole`Nancy, 28 29);
// output
2
t1.tableInsert(dict(`Name`Age, [`Patrick, 22]));
// output
1
使用
tableInsert
函数向分布式表中插入批量数据:
db=database("dfs://db1",RANGE,0 20 50 101)
n=100000
id=rand(100,n)
val=rand(100.0,n)
t=table(id,val)
pt=db.createPartitionedTable(t,`pt,`id).append!(t);
tmp=table(rand(100,10000) as id,take(200.0,10000) as val);
tableInsert(pt,tmp);
// output
10000
FILE:references/doc_8342.md
# getDynamicConfig
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getdynamicconfig.html
**来源**: DolphinDB 官方文档
---
getDynamicConfig
语法
getDynamicConfig()
详情
获取动态配置项的名称。
参数
无
返回值
返回一个向量,包含所有可以通过
setDynamicConfig
在线修改的配置项名。
例子
getDynamicConfig();
// output: ["TSDBVectorIndexCacheSize","TSDBCacheEngineSize","dfsChunkNodeHeartBeatTimeout","reservedMemSize","recoveryWorkers","OLAPCacheEngineSize","memLimitOfTempResult","maxMemSize","memLimitOfAllTempResults","maxPartitionNumPerQuery","memLimitOfTaskGroupResult","memLimitOfQueryResult","maxConnections","maxBlockSizeForReservedMemory","TSDBBlockCacheSize","logLevel","enableNullSafeJoin","enableMultiThreadMerge"]
FILE:references/doc_8345.md
# rowSkew
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowSkew.html
**来源**: DolphinDB 官方文档
---
rowSkew
语法
rowSkew(X, [biased=true])
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行计算
X
的斜度。
DolphinDB 使用以下公式计算倾斜度(当
biased
=true 时):
参数
biased
是一个布尔值,表示是否为有偏估计。默认值为 true,表示为有偏估计。
返回值
返回一个 DOUBLE 类型的向量。
例子
m = [4.5 2.6 1.5 1.5 4.8, 5.9 4.9 2.0 4.0 6.3, 2 2 2 2 2]
rowSkew(m);
// output
[-0.329206341655613,0.586870565935934,-0.707106781186563,0.595170064139497,-0.350377619697706]
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL, 4.3 NULL 3.5]);
rowSkew(m);
// output
[-1.064430070205901,0.577633692366209,0.110780117654846]
t1=table(1..5 as x, 10..6 as y, take(3, 5) as z);
rowSkew(t1);
// output
[0.567316577993729,0.652012117044047,0.707106781186548,0.528004979218188,-0.381801774160629]
相关函数:
skew
FILE:references/doc_836.md
# setDynamicConfig
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setdynamicconfig.html
**来源**: DolphinDB 官方文档
---
setDynamicConfig
语法
setDynamicConfig(configName, configValue)
详情
在线修改指定的配置项。无返回值。
注:
此命令修改的配置值在系统重启后将失效。若需永久生效,请更新对应的配置文件。
如下为支持修改的配置项(详情请参考文档
DolphinDB-功能配置
):
enableMultiThreadMerge
, enableNullSafeJoin,
logLevel
,
maxBlockSizeForReservedMemory
,
maxConnections
,
memLimitOfQueryResult
,
memLimitOfTaskGroupResult
,
maxMemSize
,
maxPartitionNumPerQuery
,
memLimitOfTempResult
,
OLAPCacheEngineSize
,
recoveryWorkers
,
reservedMemSize
,
dfsChunkNodeHeartBeatTimeout
,
TSDBCacheEngineSize
,
TSDBVectorIndexCacheSize
,
memLimitOfAllTempResults
.
参数
configName
字符串标量,表示待修改的配置项名。
configValue
标量,表示待修改的配置项的值。
例子
setDynamicConfig("maxMemSize", 8);
setDynamicConfig("maxConnections", 4096);
FILE:references/doc_8366.md
# 累计窗口系列(cum 系列)
**URL**: https://docs.dolphindb.cn/zh/funcs/themes/cumFunctions.html
**来源**: DolphinDB 官方文档
---
累计窗口系列(cum 系列)
累积窗口,即窗口的起始边界固定,结束边界逐步向右移动的窗口。针对累计窗口计算场景,DolphinDB 提供了 cum 系列函数。
cum 系列函数介绍
cum 系列函数对应的高阶函数
accumulate
:
accumulate(func, X, [init])
注:
如果指定了
init
,第一个窗口的结果为
init
+
X
[0]。
内置的 cum 系列函数的通用参数模板如下:
cumfunc(X)
cumfunc(X, Y)
参数
X
(
Y
) 是一个标量、向量、矩阵、表、元组(元素为标量或等长向量)、或字典。cum 系列函数如下:
单目:
cummax
cummin
cummed
cumfirstNot
cumlastNot
cumrank
cumcount
cumpercentile
cumstd
cumstdp
cumvar
cumvarp
cumsum
cumsum2
cumsum3
cumsum4
cumavg
cumprod
cumnunique
cumPositiveStreak
双目:
cumbeta
cumwsum
cumwavg
cumcovar
cumcorr
窗口确定规则
cum
系列函数可以视为一个累计的窗口计算,对数据中的每一个元素,都会进行一次累计计算,因此返回一个和元数据等长的向量(相同维度的矩阵)。
其计算规则如下图:
上图的对应代码,这里以
cumsum
为例:
X = 1 1 2 3 4 5 NULL 8 9 1 3
cumsum(X)
//output: [1, 2, 4, 7, 11, 16, 16, 24, 33, 34, 37]
FILE:references/doc_8367.md
# asof
**URL**: https://docs.dolphindb.cn/zh/funcs/a/asof.html
**来源**: DolphinDB 官方文档
---
asof
语法
asof(X, Y)
详情
对于每个
Y
中的元素 y,
asof
返回
X
中不大于 y
的元素的最大序号(从 0 开始编号)。如果没有找到,则返回-1。
参数
X
必须是一个递增的向量、索引序列、索引矩阵;
Y
可以是标量、向量、
数组向量、
元组、矩阵、字典、表。
返回值
数据类型为 INT,数据形式与
Y
相同。
例子
asof(1..100, 60 200 -10)
// output
[59,99,-1]
0 0 0 1 1 1 1 2 2 3 asof 1
// output
6
FILE:references/doc_8372.md
# isort!
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isort_.html
**来源**: DolphinDB 官方文档
---
isort!
语法
isort!(X, [ascending=true], indices)
详情
isort!(x, ascending, y) 相当于 y[isort(x, ascending)],结果会赋给 y。
参数
X
是一个向量或一个由多个等长向量组成的元组。
ascending
是布尔值,表示按升序排序还是按降序排序。默认值为 true(按升序排序)。
indices
是一个向量,它的长度与
X
中每个向量的长度相同。
返回值
一个排序后的向量,类型同
X
。
例子
x=3 1 NULL 2
y=5 7 8 3
isort!(x, false, y);
// output: [5, 3, 7, 8]
// 排序后的x为[3, 2, 1, NULL],第一个元素3与y中的5对应,第二个元素与2与y中的3对应,第三个元素1与y中的7对应,...以此类推。
x=2 2 1 1
y=2 1 1 2
isort!([x,y],[1,0],5 4 3 2);
// output: [2,3,5,4]
FILE:references/doc_8373.md
# iterate
**URL**: https://docs.dolphindb.cn/zh/funcs/i/iterate.html
**来源**: DolphinDB 官方文档
---
iterate
语法
iterate(init, coeffs, input)
详情
若
init
、
coeffs
与
input
均为标量,返回等比数列[
init
*
coeffs
,
init
*
coeffs
2,
init
*
coeffs
3, ...],其长度为
input
。
若
init
、
coeffs
为标量,
input
为向量,返回数列x,满足以下条件:x[0]=
init
*
coeffs
+
input
[0],x[n]=x[n-1]*
coeffs
+
input
[n]。数列x的长度为
input
的长度。
若
init
、
coeffs
为向量,
input
为标量,返回数列x,满足以下条件:x[n]=y(n)**
coeffs
,
y(n)=y(n-1)[1:].append!(x[n-1]), y(0)=
init
, x的长度为
input
。其中**表示点乘,返回两个向量的内积。
若
init
、
coeffs
与
input
均为向量,返回数列x,满足以下条件:x[n]=y(n)**
coeffs
+
input
[n],
y(n)=y(n-1)[1:].append!(x[n-1]), y(0)=
init
。其中**表示点乘,返回两个向量的内积。
参数
init
是初始值。
coeffs
是迭代系数。
init
和
coeffs
的长度必须相同。
input
是整型标量,或者是向量。如果
input
是整型标量,表示迭代的次数;如果
input
是向量,其长度表示迭代的次数,每个元素在每次迭代后都添加到结果中。
返回值
DOUBLE 类型向量。
例子
iterate(1, 0.8, 3);
// output: [0.8,0.64,0.512]
// 1*0.8=0.8, 0.8*0.8=0.64, 0.64*0.8=0.512
iterate(1, 0.8, 0.1 0.2 0.3);
// output: [0.9,0.92,1.036]
// 1*0.8+0.1=0.9, 0.9*0.8+0.2=0.92, 0.92*0.8+0.3=1.036
iterate(1 1, 1 1, 10);
// output: [2,3,5,8,13,21,34,55,89,144]
// 斐波那契数列: 1*1+1*1=2; 1*1+2*1=3; 2*1+3*1=5; 3*1+5*1=8; ... ; 55*1+89*1=144.
iterate(1 1, 1 1, 1 2 3 4 5);
// output: [3,6,12,22,39]
// 1*1+1*1+1=3; 1*1+3*1+2=6; 3*1+6*1+3=12; 6*1+12*1+4=22; 12*1+22*1+5=39.
FILE:references/doc_8376.md
# ifValid
**URL**: https://docs.dolphindb.cn/zh/funcs/i/ifValid.html
**来源**: DolphinDB 官方文档
---
ifValid
语法
ifValid(X,Y)
详情
判断
X
是否非空。
参数
X
可以是标量、数据对、向量或矩阵。
Y
可以是标量、数据对、向量或矩阵。
X
和
Y
必须具有相同的数据类型。
返回值
如果
X
为非 NULL,则返回
X
的值
如果
X
为 NULL,则返回
Y
的值
例子
x = take(1..5 join NULL 6,7)
y = 1..7
ifValid(x,y)
// output
[1,2,3,4,5,6,6]
x1 = int(take(1..5 join int(),6))$2:3
y1 = int(take(100,6))$2:3
ifValid(x1,y1)
col1
col2
col3
1
3
5
2
4
100
若
X
为向量,
Y
为 n 行 m 列的矩阵,则
X
的长度为 n*m
m=int(take(1..4 join NULL 8,6))
ifValid(m,y1)
// output
[1,2,3,4,100,8]
FILE:references/doc_8385.md
# rolling
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/rolling.html
**来源**: DolphinDB 官方文档
---
rolling
语法
rolling(func, funcArgs, window, [step=1])
详情
应用函数/运算符到给定对象的一个滑动窗口(
step
与
window
取相同值时为滚动窗口)上。
当第一个滑动窗口出现时,高阶函数开始计算,然后每经过
step
个元素就进行一次变量计算。
注:
当
func
指定为向量函数时,
window
必须等于
step
。
若窗口内的元素个数小于窗口长度,则该窗口不会计算输出。
和
moving
高阶函数类似,即对矩阵来说滑动窗口还是按行计算,而其他高阶函数通常是按列计算。
rolling
的
func
支持向量函数和聚合函数,而
moving
的
func
只支持聚合函数。
func
为聚合函数时,
rolling
与
moving
的区别是:
rolling
支持参数
step
,可以指定窗口滑动的步长;而
moving
的滑动步长只能是 1。
rolling
不输出前
window
- 1 个 NULL
值结果。
参数
func
聚合函数或向量函数。若
func
是向量函数,则
step
必须和
window
相等。
funcArgs
函数
func
的参数。可为向量或矩阵。如果有多个参数,则用元组表示,并且每个参数的长度(向量的元素个数或矩阵的行数)必须相同。
window
滑动窗口长度。
step
应用函数的频率。默认值为1。
返回值
向量或矩阵,取决于
func
的类型以及
funcArgs
的结构。
例子
func
为向量函数:
m = matrix(3 4 6 8 5 2 0 -2, 2 9 NULL 1 3 -4 2 1, NULL 8 9 8 0 1 9 -3)
rolling(cummax, m, 4, 4)
输出返回:
col1
col2
col3
3
2
4
9
8
6
9
9
8
9
9
5
3
0
5
3
1
5
3
9
5
3
9
rolling(cumsum, m, 3, 3)
输出返回:
col1
col2
col3
3
2
7
11
8
13
11
17
8
1
8
13
4
8
15
0
9
func
为聚合函数:
rolling(sum, m, 4)
输出返回:
col1
col2
col3
21
12
25
23
13
25
21
0
18
15
2
18
5
2
7
计算APPL相对于市场(SPY)的beta值,滑动窗口长度为10,频率为5。
date=2016.08.01..2016.08.31
date=date[1<=weekday(date)<=5]
aaplRet=0.0177 -0.0148 0.0125 0.0008 0.0152 0.0083 0.0041 -0.0074 -0.0006 0.0023 0.0120 -0.0009 -0.0015 -0.0013 0.0026 -0.0078 0.0031 -0.0075 -0.0043 -0.0059 -0.0011 -0.0077 0.0009
spyRet=-0.0008 -0.0064 0.0029 0.0011 0.0082 -0.0006 0.0006 -0.0025 0.0046 -0.0009 0.0029 -0.0052 0.0019 0.0022 -0.0015 0.0000 0.0020 -0.0051 -0.0007 -0.0019 0.0049 -0.0016 -0.0028
t=table(date, aaplRet, spyRet);
t;
输出返回:
date
aaplRet
spyRet
2016.08.01
0.0177
-0.0008
2016.08.02
-0.0148
-0.0064
2016.08.03
0.0125
0.0029
2016.08.04
0.0008
0.0011
2016.08.05
0.0152
0.0082
2016.08.08
0.0083
-0.0006
2016.08.09
0.0041
0.0006
2016.08.10
-0.0074
-0.0025
2016.08.11
-0.0006
0.0046
2016.08.12
0.0023
-0.0009
2016.08.15
0.012
0.0029
2016.08.16
-0.0009
-0.0052
2016.08.17
-0.0015
0.0019
2016.08.18
-0.0013
0.0022
2016.08.19
0.0026
-0.0015
2016.08.22
-0.0078
0
2016.08.23
0.0031
0.002
2016.08.24
-0.0075
-0.0051
2016.08.25
-0.0043
-0.0007
2016.08.26
-0.0059
-0.0019
2016.08.29
-0.0011
0.0049
2016.08.30
-0.0077
-0.0016
2016.08.31
0.0009
-0.0028
// 计算滚动beta
betas = rolling(beta, [aaplRet, spyRet], 10,5);
dates = rolling(last, date, 10,5);
table(dates, betas);
输出返回:
dates
betas
2016.08.12
1.601173
2016.08.19
0.512656
2016.08.26
1.064465
生成一个带有行标签的矩阵 m,将其作为参数
func
Args。
当传入参数
func
是一个聚合函数,输出带有行标签的结果矩阵。
minBar = 2024.03.08T10:00:00 + 0..9
aaplClose = [170.88,170.88,170.90,171.05,171.18,171.30,171.51,171.49,171.31,171.14]
ibmClose = [150.15,150.18,150.20,150.05,150.18,150.25,150.32,150.30,150.31,150.20]
m = matrix(aaplClose, ibmClose).rename!(minBar, `aapl`ibm)
// func 也支持传入自定义的聚合函数
rolling(func=avg, funcArgs=m, window=5, step=2)
输出结果:
label
aapl
ibm
2024.03.08T10:00:00
170.978
150.152
2024.03.08T10:00:02
171.188
150.2
2024.03.08T10:00:04
171.358
150.272
承接上例,当传入参数
func
是一个部分应用,也可输出带有行标签的结果矩阵。
defg f1(x,y){
return (last(x)-first(x))/size(x)+y
}
f2 = f1{,1}
rolling(func=f2, funcArgs=m, window=5, step=2)
输出结果:
label
aapl
ibm
2024.03.08T10:00:00
1.06
1.006
2024.03.08T10:00:02
1.122
1.024
2024.03.08T10:00:04
1.026
1.026
FILE:references/doc_8398.md
# getDatabasesByCluster
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getDatabasesByCluster.html
**来源**: DolphinDB 官方文档
---
getDatabasesByCluster
语法
getDatabasesByCluster(clusterName)
详情
获取集群下所有数据库。只能由管理员在 MoM(Master of Master,管理集群)上执行该函数。
参数
clusterName
字符串标量,表示要查询的集群名称。
返回值
字符串向量。
例子
getDatabasesByCluster("MoMSender")
// Output: ["dfs://db2","dfs://db1"]
FILE:references/doc_8402.md
# minuteOfHour
**URL**: https://docs.dolphindb.cn/zh/funcs/m/minuteOfHour.html
**来源**: DolphinDB 官方文档
---
minuteOfHour
语法
minuteOfHour(X)
详情
返回
X
中的分钟数。
参数
X
可以是 TIME, MINUTE, SECOND, DATETIME, TIMESTAMP, NANOTIME 或
NANOTIMESTAMP 类型的标量或向量。
返回值
整型标量或向量。
例子
minuteOfHour(12:32:00);
// output: 32
minuteOfHour([2012.06.12T12:30:00,2012.10.28T12:35:00,2013.01.06T12:36:47,2013.04.06T08:02:14]);
// output: [30,35,36,2]
相关函数:
dayOfYear
,
dayOfMonth
,
quarterOfYear
,
monthOfYear
,
weekOfYear
,
hourOfDay
,
secondOfMinute
,
millisecond
,
microsecond
,
nanosecond
FILE:references/doc_8425.md
# setMemLimitOfTempResult
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setMemLimitOfTempResult.html
**来源**: DolphinDB 官方文档
---
setMemLimitOfTempResult
语法
setMemLimitOfTempResult(X)
详情
在线修改表连接过程中产生的临时数据表(单个)的大小,单位为 GB。该命令只能由管理员在数据节点/计算节点上执行。
注:
此命令修改的配置值在系统重启后将失效。若需要配置值永久生效,请更改配置文件中的
memLimitOfTempResult
。
参数
X
一个数值型标量,必须大于0且不能大于
maxMemSize
的设置值。
FILE:references/doc_8438.md
# select
**URL**: https://docs.dolphindb.cn/zh/progr/sql/Select.html
**来源**: DolphinDB 官方文档
---
select
使用select语句访问表中数据。select语句总是返回一个表。
自 3.00.0 版本起,支持 catalog 结构。
用法
用法 1:读取表中的列数据。
select column1, column2, ... from t
select * from t //选取所有列
column1, column2, ... 为表 t 中的列字段名称。
用法 2:生成新列。
select expression [as colName] from t
expression 可以是包含表 t 中列字段的计算表达式,也可以是一个常量。若不指定 colName,当 expression
是表达式时,将表达式和其作用的列名组合生成新列名;当 expression 是常量时,将使用常量值作为新列名。
注意:当只 select 一个常量时,返回一个单行单列的表。
用法3:生成一个新列,其元素全为 NULL。
select NULL [as colName] from t
通过用法3生成的新列的类型为 VOID(无类型),不支持对该列进行计算操作,亦不支持追加、插入数据到 VOID 类型列和修改 VOID
类型列。其主要作用是占位。将包含空值列的表追加到其它表中(使用 append!, insert into, tableInsert
方法),则空值列的类型会自动转换为被追加列的类型,以方便后续操作。
注意:当只 select 一个 NULL 时,返回一个单行单列的空表。
以上3种用法可以结合使用,比如
select *, expression as newCol1, NULL as newCol2 from
t
。
在 SQL 查询中,select 查询返回的结果,若为:
单列表:将作为向量,可以与 in 关键字结合使用;
单行单列的表:将作为标量,可以和操作符,如:gt、ge、lt、le、eq、ne 等结合使用;
用法4:通过字段序列,选择具有”相同前缀”+“连续数字“的多列。例如:col1…col10 或 col10…col1。
select col1...colN [as name1 ... nameN] from t
上述语法中的 as
关键字可选,用于为列指定别名。该语法通常用于查询包含许多列且这些列具有相似属性的多列数据。使用时需要注意以下几点:查询表中的字段名必须满足以下正则表达式的要求:
[a-zA-Z\_]{1,}[0-9]+:以字母(大小写均可)或下划线开头,后面可以跟着任意数量的字母、下划线,最后必须至少包含一个数字。
字段序列中的数字必须连续,且满足最大和最小数字之间的差必须小于等于32768。可对数字进行格式化,例如固定位数:0001,0002,…,0010,0011,…,0100,0101,…。
数字前的文本作为前缀。前缀必须相同。
例子
创建表t1,含有列timestamp, qty, price和sym.
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t1 = table(timestamp, sym, qty, price);
t1;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
select * from t1;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
select语句中被选中的对象不仅限于表中的列,可以是变量或函数。系统会检查选中的列是否是表中的列,如果是,那么这个列将会被当作表列处理;否则将会被当作变量列或者函数处理。
recordNum=1..9;
select 1..9 as recordNum, sym from t1;
recordNum
sym
1
C
2
MS
3
MS
4
MS
5
IBM
6
IBM
7
C
8
C
9
C
// 使用一个标量值来表示含有相同值的列
select 3 as portfolio, sym from t1;
portfolio
sym
3
C
3
MS
3
MS
3
MS
3
IBM
3
IBM
3
C
3
C
3
C
在select语句中使用函数。
def f(a):a+100;
select f(qty) as newQty, sym from t1;
newQty
sym
2300
C
2000
MS
2200
MS
3300
MS
6900
IBM
5500
IBM
1400
C
2600
C
8900
C
select last price from t1 group by sym;
sym
last_price
C
51.29
MS
30.02
IBM
175.23
生成一列常量列:
t = table(1..5 as id, `a`a`a`b`b as val);
select *, 1 as cst from t
id
val
cst
1
a
1
2
a
1
3
a
1
4
b
1
5
b
1
select *, 1 from t
id
val
1
1
a
1
2
a
1
3
a
1
4
b
1
5
b
1
单列的查询结果和 in 关键字结合使用:
t = table(`APPL`IBM`AMZN`IBM`APPL`AMZN as sym, 10.1 11.2 11.3 12 10.6 10.8 as val)
t;
sym
val
APPL
10.1
IBM
11.2
AMZN
11.3
IBM
12
APPL
10.6
AMZN
10.8
stk = table(1 2 3 as id, `AAPL`IBM`FB as stock);
select count(*) from t where sym in select stock from stk;
// output: 2
下例生成一个包含空值列的表,且将该表追加到 t2 中
t1 = table(rand(10,3) as x)
tmp=select *, NULL from t1
typestr(tmp[`NULL])
// output: VOID VECTOR
将表 tmp 追加到 t2 中
t2 = table(1..6 as x1, 1..6 as y1)
t2.append!(tmp)
t2
x1
y1
1
1
2
2
3
3
3
4
6
字段序列支持直接用在 SQL 语句中作为查询的字段或者别名:
通过字段序列查询多列并重命名:
t= table(`a1`a2 as sym, 2.5 1.5 as price1, 3.0 2.0 as price2, 3.5 2.5 as price3, 4.0 3.0 as price4, 4.5 3.5 as price5,
110 200 as qty1, 120 210 as qty2, 130 230 as qty3, 140 240 as qty4, 150 260 as qty5)
select price1...price5 as p1...p5 from t
p1
p2
p3
p4
p5
2.5
3
3.5
4
4.5
1.5
2
2.5
3
3.5
对于具有多个相似功能的列,通常列名也类似,此时可通过 fixedLengthArrayVector
结合字段序列,简化生成数组向量:
select fixedLengthArrayVector(price1...price5) as priceArray, fixedLengthArrayVector(qty1...qty5) as qtyArray from t
priceArray
qtyArray
[2.5000,3.0000,3.5000,4.0000,4.5000]
[110,120,130,140,150]
[1.5000,2.0000,2.5000,3.0000,3.5000]
[200,210,230,240,260]
多个字段序列间进行计算,规则同向量间计算。如下例,将分别计算 price1*qty1 ,…, price5*qty5:
select (price1...price5) * (qty1...qty5) as amount1...amount5 from t
amount1
amount2
amount3
amount4
amount5
275
360
455
560
675
300
420
575
720
910
FILE:references/doc_8442.md
# square
**URL**: https://docs.dolphindb.cn/zh/funcs/s/square.html
**来源**: DolphinDB 官方文档
---
square
语法
square(X)
详情
返回
X
的平方。返回结果的数据类型为 DOUBLE 类型。
参数
X
可以是标量、数据对、向量或矩阵。
返回值
DOUBLE 类型的标量、数据对、向量或矩阵。
例子
square(3);
// output
9
square(2 4 NULL 6);
// output
[4,16,,36]
square(1..4$2:2);
#0
#1
1
9
4
16
FILE:references/doc_8445.md
# kendall
**URL**: https://docs.dolphindb.cn/zh/funcs/k/kendall.html
**来源**: DolphinDB 官方文档
---
kendall
语法
kendall(X, Y)
详情
计算
X
和
Y
的 Kendall 相关性系数。计算时忽略 NULL 值。
若
X
或
Y
是矩阵,对每一列执行上述计算,返回一个向量。
如果
X
或
Y
是内存表,则对表中的每个数值列执行上述计算,非数值列将返回空,结果为一个表。
参数
X
一个标量/向量/矩阵/内存表。
Y
一个标量/向量/矩阵/内存表。
返回值
DOUBLE 类型标量/向量/表。
例子
x = [33,21,46,-11,78,47,18,20,-5,66]
y = [1,NULL,10,6,10,3,NULL,NULL,5,3]
kendall(x, y)
//output
0.05
如果
X
是矩阵,
Y
可以长度是与
X
行数相同的向量,或者是与
X
维度相同的矩阵。返回结果是长度与
X
列数相同的向量。
m=1..20$10:2
kendall(m,x)
//output
[-0.0222,-0.0222]
n=rand(20,20)$10:2
kendall(m,n)
//output
[0.3865,-0.1591]
如果
X
是表,
Y
可以是长度与
X
行数相同的向量,或者是维度与
X
相同的表。返回结果是与
X
列数相同的表。
t=table(
2.
.11
as
id,
"a"
+string(
2.
.11
)
as
name)
kendall(t,x)
表
1
.
id
name
-0.0222
t1=table(x
as
col1, y
as
col2)
kendall(t,t1)
表
2
.
id
name
-0.0222
FILE:references/doc_8451.md
# digitize
**URL**: https://docs.dolphindb.cn/zh/funcs/d/digitize.html
**来源**: DolphinDB 官方文档
---
digitize
语法
digitize(x, bins, [right=false])
详情
返回
x
所属的
bins
的索引,返回值的数据形式与
x
一致。
right
bins 顺序
返回的索引满足
false
升序
bins
里第一个大于
x
的元素的索引
true
升序
bins
里第一个大于等于
x
的元素的索引
false
降序
bins
里第一个小于等于
x
的元素的索引
true
降序
bins
里第一个小于
x
的元素的索引
如果
x
中的值超出
bins
的左或右边界,则返回 0 或
bins
的长度。
该函数的功能和使用方法同 numpy.digitize。
参数
x
一个浮点型、整型或 DECIMAL 类型的标量或向量。
bins
一个单调递增或递减的浮点型、整型或 DECIMAL 类型向量。
right
一个布尔值,为可选参数,设置区间包含右边界还是左边界,默认为 false(包含左边界)。
例子
bins = [1,3,3,5,5]
// 返回 bins 里第一个大于 x 的元素的索引
digitize(3, bins=bins, right=false)
// output: 3
//返回 bins 里第一个大于 x 的元素的索引,由于 bins 里不存在这样的元素,返回 size(bins)
digitize(5, bins=bins, right=false)
//output: 5
// 返回 bins 里第一个大于等于 x 的元素的索引
digitize(5, bins=bins, right=true)
//output: 3
bins = reverse(bins)
digitize(5, bins=bins, right=false)
//output: 0
digitize(5, bins=bins, right=true)
//output: 2
x = [-1,0,1,2,3,4,5,6]
bins = [1,3,5]
digitize(x=x, bins=bins, right=false)
//output: [0,0,1,1,2,2,3,3]
digitize(x=x, bins=bins, right=true)
//output: [0,0,0,1,1,2,2,3]
bins = reverse(bins)
digitize(x=x, bins=bins, right=false)
//output: [3,3,2,2,1,1,0,0]
digitize(x=x, bins=bins, right=true)
//output: [3,3,3,2,2,1,1,0]
digitize
函数相较于
bucket
函数更灵活,可以自定义
bins
。以下为示例:
bucket(9 23 54 36 46 12, 12:53, 2) //报错:dataRange must be the mutltiplier of bucketNum.
因为 [12, 53) 中元素个数不能被2整除,所以不能使用
bucket
来分桶。
digitize(9 23 54 36 46 12 , 12 40 53)
// output: [0,1,3,1,2,1]
digitize
函数中,函数按照自定义的
bins
给数据分桶。
FILE:references/doc_8454.md
# database
**URL**: https://docs.dolphindb.cn/zh/funcs/d/database.html
**来源**: DolphinDB 官方文档
---
database
语法
database(directory, [partitionType], [partitionScheme], [locations],
[engine='OLAP'], [atomic='TRANS'])
2.00.4
版本以后,
若配置项
enableChunkGranularityConfig
= true:
database(directory, [partitionType], [partitionScheme], [locations],
[engine='OLAP'], [atomic='TRANS'], [chunkGranularity='TABLE'])
详情
创建一个数据库句柄。
我们需要指定
partitionType
和
partitionScheme
创建新的分布式数据库。当我们重新打开已有的分布式数据库,只需要指定
directory
。我们不能用不同的
partitionType
或
partitionScheme
覆盖已有的分布式数据库。
当
directory
为本地磁盘路径时,将创建本地磁盘数据库。磁盘数据库仅应用于备份数据和本地计算的场景,其相较于分布式表,在使用上具有一定局限,例如不能进行权限控制等。
参数
directory
是保存数据库的目录的路径。如果需要创建分布式文件系统中的数据库,
directory
应该以 "dfs://" 开头,如果需要创建内存在线事务处理数据库,应该以 "oltp://" 开头。
partitionType
有六种类型:顺序分区(SEQ),范围分区(RANGE),哈希分区(HASH),数值分区(VALUE),列表分区(LIST)和组合分区(COMPO)。
partitionScheme
描述了分区是如何创建的。它通常是一个向量,在序列域是一个整型标量。分区方案的说明决定了分区类型。
partitionScheme
支持以下数据类型:CHAR, SHORT, INT, DATE, MONTH, TIME, MINUTE, SECOND, DATETIME 和 SYMBOL。
分区类型
分区符号
分区方案
顺序分区
SEQ
整型标量。表示分区的数量。
范围分区
RANGE
向量。向量的任意两个相邻元素定义分区的范围。
哈希分区
HASH
元组。第一个元素是分区列的数据类型,第二个元素是分区的数量。
值分区
VALUE
向量。向量的每个元素定义了一个分区。
列表分区
LIST
向量。向量的每个元素定义了一个分区。
组合分区
COMPO
向量。向量的每个元素是一个数据库句柄。向量长度表示分区的层级,最小是2,最大是3。
locations
是元组,指定分区的位置。元组中元素的数量应该与
partitionType
和
partitionScheme
共同决定的分区数量相同。若要在多个节点上保存分区时, 可以使用分布式文件系统或使用
locations
参数指定每个分区在哪些节点。如果没有指定
locations
参数,所有分区属于当前节点。我们不能指定分层域的分区。
engine = 'OLAP'
设置数据库存储引擎
。取值为:'OLAP' , 'TSDB'
, 'IMOLTP', 'IOTDB',
或'PKEY'
,默认值为 'OLAP'。
关于存储引擎的介绍,请参见
数据库
。
注:
TSDB
和 PKEY
引擎只支持创建分布式数据库。
atomic
表示写入事务的原子性层级,决定了是否允许并发写入同一分区。可选值为 'TRANS' 和 'CHUNK',默认值为 'TRANS'。
设置为
'TRANS',写入事务的原子性层级为事务,即一个事务写入多个分区时,若某个分区被其他写入事务锁定而出现写入冲突,则该事务的写入全部失败。因此,该设置下,不允许并发写入同一个分区。
设置为
'CHUNK',写入事务的原子性层级为分区。若一个事务写入多个分区时,某分区被其它写入事务锁定而出现冲突,系统会完成其他分区的写入,同时对之前发生冲突的分区不断尝试写入,尝试数分钟后仍冲突才放弃。此设置下,允许并发写入同一个分区,但由于不能完全保证事务的原子性,可能出现部分分区写入成功而部分分区写入失败的情况。同时由于采用了重试机制,写入速度可能较慢。
chunkGranularity
是一个字符串,用于指定分区的粒度。可选值为:
'TABLE':表级分区,设置后支持同时写入同一分区的不同表。
'DATABASE':数据库级分区,设置后只支持同时写入不同分区。
该参数只有在配置
enableChunkGranularityConfig
= true 时启用。
例子
1.创建没有分区的磁盘数据库。
db=database(directory="C:/DolphinDB/Data/db1/");
t=table(take(1..10,10000000) as id, rand(10,10000000) as x, rand(10.0,10000000) as y);
saveTable(db, t, `t1);
2.对于分布式数据库,每种类型的分区都有一个例子。
顺序分区(SEQ):分区是基于输入数据文件中行的顺序。它只能在本地文件系统中使用,不能在分布式文件系统中使用。
n=1000000
ID=rand(100, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x);
saveText(t, "C:/DolphinDB/Data/t.txt");
db = database(directory="C:/DolphinDB/Data/seqdb", partitionType=SEQ, partitionScheme=8)
pt = loadTextEx(db, `pt, ,"C:/DolphinDB/Data/t.txt");
在
"C:/DolphinDB/data/seqdb"
文件夹中,有8个新建的子文件夹。每个对应输入数据文件中的分区。如果输入数据文件比计算机的可用内存大,我们可以把数据载入分区。
范围分区(RANGE):分区是由分区方案中的两个元素决定的。范围包含下限不包含上限。
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x);
db=database(directory="dfs://rangedb", partitionType=RANGE, partitionScheme=0 5 10)
pt = db.createPartitionedTable(t, `pt, `ID);
pt.append!(t);
pt=loadTable(db,`pt)
x=select * from pt
select count(x) from pt;
count_x
1000000
在上述例子中,数据库 db 有两个分区:[0,5)和[5,10)。表 t 在数据库 db 中保存为以 ID 为分区列的分区表 pt。
把数据文件输入为范围域的分布式数据库:
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x);
saveText(t, "C:/DolphinDB/Data/t.txt");
db=database(directory="dfs://rangedb", partitionType=RANGE, partitionScheme=0 5 10)
pt = loadTextEx(db, `pt, `ID, "C:/DolphinDB/Data/t.txt");
哈希分区(HASH):我们需要指定分区列的数据类型和分区数量。
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x)
db=database(directory="dfs://hashdb", partitionType=HASH, partitionScheme=[INT, 2])
pt = db.createPartitionedTable(t, `pt, `ID)
pt.append!(t);
select count(x) from pt;
count_x
1000000
上面的例子中,数据库 db 有两个分区。表 t 被保存为以 ID 为分区列的分区表 pt。
注意:如果导入哈希分区数据库的数据的分区列包含空值,则该条数据会被丢弃。
ID = NULL 3 6 NULL 9
x = rand(1.0, 5)
t1 = table(ID, x)
pt.append!(t1)
select count(x) from pt;
count_x
1000003
数值分区(VALUE):分区方案中的每个元素决定一个分区。
n=1000000
month=take(2000.01M..2016.12M, n);
x=rand(1.0, n);
t=table(month, x);
db=database(directory="dfs://valuedb", partitionType=VALUE, partitionScheme=2000.01M..2016.12M)
pt = db.createPartitionedTable(t, `pt, `month);
pt.append!(t);
pt=loadTable(db,`pt)
select count(x) from pt;
count_x
1000000
上述例子定义了一个具有204个分区的数据库。每个分区表示从2000年1月到2016年12月的月份。使用
createPartitionedTable
和
append!
函数,把表 t
保存为数据库 db 中以 month 作为分区列的分区表 pt。
列表分区(LIST):分区方案的每个元素决定分区。
n=1000000
ticker = rand(`MSFT`GOOG`FB`ORCL`IBM,n);
x=rand(1.0, n);
t=table(ticker, x);
db=database(directory="dfs://listdb", partitionType=LIST, partitionScheme=[`IBM`ORCL`MSFT, `GOOG`FB])
pt = db.createPartitionedTable(t, `pt, `ticker)
pt.append!(t);
pt=loadTable(db,`pt)
select count(x) from pt;
count_x
1000000
上述例子中的数据库有两个分区。第一个分区有3支股票,第二个分区有2支股票。
组合分区(COMPO):可以有2个或3个分区列。每个分区列可以是按范围分区、值分区、哈希分区或列表分区。分区列的顺序是无关的。
n=1000000
ID=rand(100, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x)
dbDate = database(, partitionType=VALUE, partitionScheme=2017.08.07..2017.08.11)
dbID = database(, partitionType=RANGE, partitionScheme=0 50 100)
db = database(directory="dfs://compoDB", partitionType=COMPO, partitionScheme=[dbDate, dbID])
pt = db.createPartitionedTable(t, `pt, `date`ID)
pt.append!(t)
pt=loadTable(db,`pt)
select count(x) from pt;
count_x
1000000
数值域根据天数分成5个分区:
范围域有2个分区:
请注意,虽然这里的数据库文件有两级文件夹,但是分层域只有一个层次的分区。与之对比,双重分区具有两个层次分区。
3.创建分布式数据库
我们可以根据上述例子的语法,在分布式文件系统中建立分布式数据库。唯一区别是,在
database
函数中,
directory
参数要以 "dfs://" 开头。
在执行下面例子之前,我们需要在 web 界面上启动 DFS 集群,并且提交数据节点的脚本。
在分布式文件系统中保存分层域的分区表:
n=1000000
ID=rand(100, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(ID, date, x);
dbDate = database(, partitionType=VALUE, partitionScheme=2017.08.07..2017.08.11)
dbID=database(, partitionType=RANGE, partitionScheme=0 50 100);
db = database(directory="dfs://compoDB", partitionType=COMPO, partitionScheme=[dbDate, dbID]);
pt = db.createPartitionedTable(t, `pt, `date`ID)
pt.append!(t);
我们可以在以下目录查看数据库文件:
DFS_NODE1 只有4个关于日期的文件夹;在 "20170807" 文件夹中只有一个 ID
文件夹。这是因为有4个数据节点和基于日期和 ID
的2*5=10个分区。默认情况下,每个分区在分布式文件系统中有3个备份。因此,总共有5*2*3=30个分区来保存4个数据节点。不是所有数据节点都有10个分区。
在分布式文件系统中把数据文件输入到范围域的分布式数据库中:
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x);
saveText(t, "C:/DolphinDB/Data/t.txt");
db=database(directory="dfs://rangedb", partitionType=RANGE, partitionScheme=0 5 10)
pt = loadTextEx(db, `pt, `ID, "C:/DolphinDB/Data/t.txt");
4.关于
locations
参数的例子:
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x);
db=database(directory="dfs://rangedb5", partitionType=RANGE, partitionScheme=0 5 10, locations=[`node1`node2, `node3])
pt = db.createPartitionedTable(t, `pt, `ID);
pt.append!(t);
上述例子定义了具有两个分区的数值域。第一个分区在 node1 和 node2 上,第二个分区在 node3 上。所有的位置必须在这些节点所在的计算机中的
dolphindb.cfg 文件的 sites 参数定义:
sites=111.222.3.4:8080:node1, 111.222.3.5:8080:node2, 111.222.3.6:8080:node3
sites 中的参数是用逗号分隔的。每个 site 包含3部分:主机名,端口号和别名。分区可以复制多个 sites。在这个例子中,每个节点位于不同的计算机。
我们也可以直接使用主机名和端口号表示位置。函数将会变成:
db=database(directory="dfs://rangedb6", partitionType=RANGE, partitionScheme=0 5 10, locations=[["111.222.3.4:8080", "111.222.3.5:8080"], "111.222.3.6:8080"])
5. 关于
atomic
参数的例子:
if(existsDatabase("dfs://test"))
dropDB("dfs://test")
db = database(directory="dfs://test", partitionType=VALUE, partitionScheme=1..20, atomic='CHUNK')
dummy = table(take(1..20, 100000) as id, rand(1.0, 100000) as value)
pt = db.createPartitionedTable(dummy, "pt", `id)
dummy1 = table(take(1..15, 1000000) as id, rand(1.0, 1000000) as value)
dummy2 = table(take(11..20, 1000000) as id, rand(1.0, 1000000) as value)
submitJob("write1", "writer1", append!{pt, dummy1})
submitJob("write2", "writer2", append!{pt, dummy2})
submitJob("write3", "writer3", append!{pt, dummy1})
submitJob("write4", "writer4", append!{pt, dummy2})
select count(*) from pt
// output
4,000,000
创建 IMOLTP 数据库
dbName = "oltp://test_imoltp"
db = database(directory=dbName, partitionType=VALUE, partitionScheme=1..100, engine="IMOLTP")
FILE:references/doc_8465.md
# saveModule
**URL**: https://docs.dolphindb.cn/zh/funcs/s/saveModule.html
**来源**: DolphinDB 官方文档
---
saveModule
语法
saveModule(name, [moduleDir],
[overwrite=false])
详情
将模块序列化成扩展名为 dom 的二进制文件,可以增加代码的保密性和安全性。该函数必须要用户登录后才能执行。
如果没有指定
moduleDir
,默认是相对目录 modules。系统搜寻相对目录 modules
的顺序如下:先到节点的 home 目录寻找,再到节点的工作目录寻找,最后到 DolphinDB
可执行文件所在目录寻找。请注意,单节点模式下,这三个目录默认为同一目录。
参数
name
是一个字符串,表示模块的名称。
moduleDir
是一个字符串,表示模块 dos 文件所在的目录。
overwrite
是一个布尔值,表示是否覆盖已有的模块 dom 文件。
例子
假设节点 home 目录下的 modules 目录中包含了 ta.dos 以及 system/log/fileLog.dos 模块文件,将它们序列化为二进制文件。
saveModule("ta");
saveModule("system::log::fileLog");
相关函数:
loadModule
FILE:references/doc_8468.md
# cumpercentile
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumpercentile.html
**来源**: DolphinDB 官方文档
---
cumpercentile
语法
cumpercentile(X, percent,
[interpolation='linear'])
部分通用参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累计百分位。
参数
percent
是 0 到 100 之间的整数或小数。
interpolation
是一个字符串,表示当选中的分位点位于在
X
的第 i 和第 i+1
个元素之间时,采用的插值方法。它具有以下取值:
'linear':
, 其中
'lower':
'higher':
'nearest':
和
之中最接近分位点的数据
'midpoint':
如果没有指定
interpolation
,默认采用 'linear'。
返回值
DOUBLE 类型,其数据形式同
X
。
例子
a=1..10;
cumpercentile(a,25);
[1,1.25,1.5,1.75,2,2.25,2.5,2.75,3,3.25]
cumpercentile(a,25,'lower');
[1,1,1,1,2,2,2,2,3,3]
cumpercentile(a,25,'higher');
[1,2,2,2,2,3,3,3,3,4]
cumpercentile(a,25,'midpoint');
[1,1.5,1.5,1.5,2,2.5,2.5,2.5,3,3.5]
cumpercentile(a,25,'nearest');
[1,1,1,2,2,2,2,3,3,3]
cumpercentile(a,50.5);
[1,1.505,2.01,2.515,3.02,3.525,4.03,4.535,5.04,5.545]
m=matrix(1..10, 11..20);
m;
#0
#1
1
11
2
12
3
13
4
14
5
15
6
16
7
17
8
18
9
19
10
20
cumpercentile(m,25);
#0
#1
1
11
1.25
11.25
1.5
11.5
1.75
11.75
2
12
2.25
12.25
2.5
12.5
2.75
12.75
3
13
3.25
13.25
相关函数:
percentile
FILE:references/doc_8493.md
# mstdpTopN
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mstdpTopN.html
**来源**: DolphinDB 官方文档
---
mstdpTopN
语法
mstdpTopN(X, S, window, top, [ascending=true],
[tiesMethod='oldest'])
参数说明和窗口计算规则请参考:
mTopN
详情
在给定长度(以元素个数衡量)的滑动窗口内,根据
ascending
指定的排序方式将
X
按照
S
进行稳定排序后,取前
top
个元素计算总体标准差。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
X = 1..7
S = 0.3 0.5 0.1 0.1 0.5 0.2 0.4
mstdpTopN(X, S, 4, 2)
// output: [0,0.5,1,0.5,0.5,0.5,1]
X = NULL 1 2 3 4 NULL 5
S = 3 5 1 1 5 2 4
mstdpTopN(X, S, 4, 2)
// output: [,0,0,0.5,0.5,0.5,0]
X = matrix(1..5, 6..10)
S = 2022.01.01 2022.02.03 2022.01.23 2022.04.06 2021.12.29
mstdpTopN(X, S, 3, 2)
#0
#1
0
0
0.5
0.5
1
1
0.5
0.5
1
1
X = matrix(1..5, 6..10)
S = matrix(2022.01.01 2022.02.03 2022.01.23 NULL 2021.12.29,NULL 2022.02.03 2022.01.23 2022.04.06 NULL)
mstdpTopN(X, S, 3, 2)
#0
#1
0
0.5
0
1
0.5
0.5
0.5
1
0.5
相关函数:
mstdp
FILE:references/doc_8499.md
# lowLong
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lowlong.html
**来源**: DolphinDB 官方文档
---
lowLong
语法
lowLong(X)
详情
返回值为
X
的低位8字节的数据,为 LONG 类型。
参数
X
是一个标量、向量、表、数据对或者字典,且必须为16字节的数据类型(支持 UUID、IPADDR、INT128、COMPLEX、POINT)。
例子
x =ipaddr("192.168.1.13")
x1 = lowLong(x)
print(x1)
//output: 3232235789
x=1 2 3 4
y=4 3 2 1
points = point(x, y)
x1 = lowLong(points)
//output: [4607182418800017408,4611686018427387904,4613937818241073152,4616189618054758400]
FILE:references/doc_85.md
# pnodeRun
**URL**: https://docs.dolphindb.cn/zh/funcs/p/pnodeRun.html
**来源**: DolphinDB 官方文档
---
pnodeRun
语法
pnodeRun(function, [nodes],
[addNodeAlias=true])
详情
在集群指定节点或所有数据节点/计算节点上并行调用本地函数,然后合并结果。
当指定
nodes
参数时,在指定的节点上调用本地函数。
当未指定
nodes
参数时:若在指定了计算组的计算节点上执行该函数时,仅会在同组内的所有计算节点上调用本地函数;否则,在集群中所有的数据节点、未指定计算组的计算节点上调用本地函数。
参数
function
调用的本地函数(不能使用引号)。它可以是一个没有定义参数的函数,或者是没有参数的封装了初始函数和参数的部分应用。它可以是内置函数或用户自定义函数。
nodes
可选参数,字符串标量或向量,表示节点的别名。
addNodeAlias
是否在结果中加入节点的别名,默认值是
true。如果返回的结果已经包含节点的别名,可设置为false。
返回值
若被调用函数返回标量、字典、表, 返回一个表。
若被调用函数返回向量, 返回一个矩阵。
若被调用函数返回字典, 返回一个表。
若被调用函数为命令(无返回值), 返回空值。
其他情况,返回一个字典。
例子
例1. 函数 getChunksMeta 不指定参数。
pnodeRun(getChunksMeta,,false);
site
chunkId
path
dfsPath
type
flag
size
version
state
versionList
local8848
bd13090e-7177-01a7-4ac4-840e1b977dcf
D:130DolphinDB_Win64_Vserverlocal8848storage/CHUNKS/compo/20190605/GOOG
/compo/20190605/GOOG
1
0
0
1
0
cid : 40,pt2=>40:6729; #
local8848
b4935730-6372-b2a1-4f24-6c323037e576
e:data/CHUNKS/compo/20190605/AAPL
/compo/20190605/AAPL
1
0
0
1
0
cid : 40,pt2=>40:6613; #
local8848
f8ee72c9-dad3-f49e-430e-5ddb3c61ae18
D:130DolphinDB_Win64_Vserverlocal8848storage/CHUNKS/compo/20190604/MSFT
/compo/20190604/MSFT
1
0
0
1
0
cid : 40,pt2=>40:6664; #
local8848
08e26b5a-dfac-799f-4979-0dd3902eae6e
D:130DolphinDB_Win64_Vserverlocal8848storage/CHUNKS/compo/20190604/GOOG
/compo/20190604/GOOG
1
0
0
1
0
cid : 40,pt2=>40:6635; #
local8848
f9e53a3d-af3e-018d-4bfa-a2b4980f3561
D:130DolphinDB_Win64_Vserverlocal8848storage/CHUNKS/compo/20190604/AAPL
/compo/20190604/AAPL
1
0
0
1
0
cid : 40,pt2=>40:6783; #
local8848
417e49e9-5c61-cf9e-4b21-4b35f8e57273
D:130DolphinDB_Win64_Vserverlocal8848storage/CHUNKS/compo/20190601/MSFT
/compo/20190601/MSFT
1
0
0
1
0
cid : 40,pt2=>40:6602; #
local8848
3ee64942-1d72-bea7-4bc1-f720132d9288
D:130DolphinDB_Win64_Vserverlocal8848storage/CHUNKS/compo/20190602/AAPL
/compo/20190602/AAPL
1
0
0
1
0
cid : 40,pt2=>40:6749; #
例2. 在下例中,函数 sum 和参数1..10被封装成了部分应用 sum{1..10}。
pnodeRun(sum{1..10}, `nodeA`nodeB);
Node
Value
DFS_NODE2
55
DFS_NODE3
55
例3.
pnodeRun
对于集群管理非常方便。例如,在一个集群中有4个节点:"DFS_NODE1", "DFS_NODE2", "DFS_NODE3" 和
"DFS_NODE4"。在每个节点上执行以下脚本:
def jobDemo(n){
s = 0
for (x in 1 : n) {
s += sum(sin rand(1.0, 100000000)-0.5)
print("iteration " + x + " " + s)
}
return s
};
submitJob("jobDemo1","job demo", jobDemo, 10);
submitJob("jobDemo2","job demo", jobDemo, 10);
submitJob("jobDemo3","job demo", jobDemo, 10);
查看集群中每个节点最近完成的两个批处理作业的状态:
pnodeRun(getRecentJobs{2});
Node
UserID
JobID
JobDesc
ReceivedTime
StartTime
EndTime
ErrorMsg
DFS_NODE1
root
jobDemo2
job demo
2017.11.16T13:04:38.841
2017.11.16T13:04:38.841
2017.11.16T13:04:51.660
DFS_NODE1
root
jobDemo3
job demo
2017.11.16T13:04:38.841
2017.11.16T13:04:38.843
2017.11.16T13:04:51.447
DFS_NODE2
root
jobDemo2
job demo
2017.11.16T13:04:56.431
2017.11.16T13:04:56.432
2017.11.16T13:05:11.992
DFS_NODE2
root
jobDemo3
job demo
2017.11.16T13:04:56.432
2017.11.16T13:04:56.434
2017.11.16T13:05:11.670
DFS_NODE3
root
jobDemo2
job demo
2017.11.16T13:05:08.418
2017.11.16T13:05:08.419
2017.11.16T13:05:29.176
DFS_NODE3
root
jobDemo3
job demo
2017.11.16T13:05:08.419
2017.11.16T13:05:08.421
2017.11.16T13:05:29.435
DFS_NODE4
root
jobDemo2
job demo
2017.11.16T13:05:16.324
2017.11.16T13:05:16.325
2017.11.16T13:05:34.729
DFS_NODE4
root
jobDemo3
job demo
2017.11.16T13:05:16.325
2017.11.16T13:05:16.328
2017.11.16T13:05:34.716
pnodeRun(getRecentJobs{2}, `DFS_NODE3`DFS_NODE4);
Node
UserID
JobID
JobDesc
ReceivedTime
StartTime
EndTime
ErrorMsg
DFS_NODE3
root
jobDemo2
job demo
2017.11.16T13:05:08.418
2017.11.16T13:05:08.419
2017.11.16T13:05:29.176
DFS_NODE3
root
jobDemo3
job demo
2017.11.16T13:05:08.419
2017.11.16T13:05:08.421
2017.11.16T13:05:29.435
DFS_NODE4
root
jobDemo2
job demo
2017.11.16T13:05:16.324
2017.11.16T13:05:16.325
2017.11.16T13:05:34.729
DFS_NODE4
root
jobDemo3
job demo
2017.11.16T13:05:16.325
2017.11.16T13:05:16.328
2017.11.16T13:05:34.716
pnodeRun
合并多个节点的结果时遵循以下规则:
(1) 如果 function 返回一个标量:
返回一个表,它具有两列:节点别名和函数结果。
紧接上面的例子:
pnodeRun(getJobReturn{`jobDemo1});
Node
Value
DFS_NODE3
2,123.5508
DFS_NODE2
(42,883.5404)
DFS_NODE1
3,337.4107
DFS_NODE4
(2,267.3681)
(2) 如果 function 返回一个向量:
返回一个矩阵。矩阵中的每一列是函数在节点上返回的结果。矩阵的列标签是节点。
(3) 如果 function 返回键-值形式的字典:
返回一个表,每行代表函数在一个节点上的结果。
(4) 如果 function 返回一个表:
返回一个表,它是多个节点上的表的合并。
(5) 如果 function 是一个命令(该命令不返回任何内容):
不返回任何内容。
(6) 对于其他情况:
返回一个字典。键是节点别名,值是函数的返回内容。
FILE:references/doc_8504.md
# ifirstHit
**URL**: https://docs.dolphindb.cn/zh/funcs/i/ifirstHit.html
**来源**: DolphinDB 官方文档
---
ifirstHit
语法
ifirstHit(func, X, target)
详情
返回
X
中第一个满足
X
func
target
(例如
X
>5) 条件的元素的下标。
若
X
中无元素满足条件,则返回-1。
通过
ifirstHit
查找时,NULL 值会被忽略:
如需查找第一个非 NULL 的下标, 可以通过函数
ifirstNot
;
如需查找第一个空值的下标,可以通过函数
find
。
参数
func
关系运算符 >, >=, <, <=, !=, <>, ==。
X
向量,矩阵或表。
target
和
X
类型相同的标量,表示与
X
比较的对象。
返回值
X
是向量,返回一个整数。
X
是矩阵,返回一个整型向量。
X
是表,返回一个表。
例子
X = NULL 3.2 4.5 1.2 NULL 7.8 0.6 9.1
ifirstHit(<, X, 2.5)
// output: 3
// 若无元素满足查找条件,返回 -1
ifirstHit(>, X, 10.0)
// output: -1
相关函数:
firstHit
FILE:references/doc_8508.md
# setMaxConnections
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setMaxConnections.html
**来源**: DolphinDB 官方文档
---
setMaxConnections
语法
setMaxConnections(newValue)
详情
在线修改当前节点的最大连接数。该命令只能由管理员执行。
可以在控制节点调用函数
getClusterPerf
返回的 maxConnections 字段查看是否成功修改。
注:
newValue
指定的值必须大于当前的最大连接数,否则无法生效。
此命令修改的配置值在系统重启后将失效。若需要配置值永久生效,请更改配置文件中的
maxConnections
。
getClusterPerf
函数获取节点信息存在延迟,获取的可能不是最新的连接数。
参数
newValue
一个小于 2^16(65536)的正整数。
FILE:references/doc_8518.md
# seq
**URL**: https://docs.dolphindb.cn/zh/funcs/s/seq.html
**来源**: DolphinDB 官方文档
---
seq
语法
seq(start, end)
或
start..end
详情
返回一个以
start
为起点,
end
为终点的向量,相邻元素之间的差为 1。
注意:若
start
和
end
都为整型或时间类型的 NULL 值,函数返回一个空向量。
参数
start
和
end
必须是整型或时间类型。
返回值
返回一个向量。
例子
x=0..3;
x;
// output
[0,1,2,3]
1..3+1;
// output
[2,3,4]
11..1;
// output
[11,10,9,8,7,6,5,4,3,2,1]
seq(3,1);
// output
[3,2,1]
2015.01M..2015.12M;
// output
[2015.01M,2015.02M,2015.03M,2015.04M,2015.05M,2015.06M,2015.07M,2015.08M,2015.09M,2015.10M,2015.11M,2015.12M]
2016.01.01..2016.01.07;
// output
[2016.01.01,2016.01.02,2016.01.03,2016.01.04,2016.01.05,2016.01.06,2016.01.07]
FILE:references/doc_8520.md
# viewTraceInfo
**URL**: https://docs.dolphindb.cn/zh/progr/sql/viewTraceInfo.html
**来源**: DolphinDB 官方文档
---
viewTraceInfo
语法
viewTraceInfo(traceId, [isTreeView=true])
参数
traceId
字符串,表示记录 SQL Trace 信息的 id。通过函数
getTraces
获取。
isTreeView
布尔值,表示是否以树状结构显示跟踪信息,默认为 true。
详情
展示 traceId 对应脚本的跟踪信息。返回一个表,包含以下几列:
tree (
isTreeView
= true):以树状结构显示执行流程,每个节点可视为一个操作的
span
。| name (
isTreeView
= false):直接显示每个
span 的操作名。
script:每个 span 所执行的由用户编写的脚本字符串。
startTime:脚本开始执行的时间戳,单位为纳秒。
timeElapsed:脚本执行总耗时,单位为微秒。
reference:该列显示了子 span 和父 span 的关系。有三种类型:
Root:根节点,为首次接收请求的阶段。
ChildOf:父 span 依赖于子 span 返回的结果。表示该 span 是被同步调用的。
FollowsFrom:父 span 并不依赖子 span 的的返回结果。表示是该 span
是被异步调用的(如:进入队列或网络请求等操作)。
node:该 span 所在执行节点的别名。
thread:该 span 对应的线程号。
name/tree 中各 span 的操作及其含义:
操作名
含义
Worker::run
服务器获取请求后将请求送入队列,由 worker 线程进行计算工作。
其中x是正整数,取值范围[0, 6]。
Tokenizer::tokenize
对请求内的脚本做词法分析,得到词素流便于后续语法解析。
Parser::parse
对请求内的脚本做语法解析,得到可执行的语句。
Statement::execute
执行语句,指代一行脚本。
SQLQueryImp::getReference
对 SQL 查询求值,即执行 SQL 查询。
SQLQueryImp::partitionedCall
进行一次分区查询,该查询任务会分解并发送给其他 datanode
来执行查询。常见于分布式查询。
SQLQueryImp::simpleCall
简单的查询语句,一般不包含 group by, context by, cgroup by
等操作。常见于内存表查询。
SQLQueryImp::basicCall
从存储引擎中读取数据。
StaticStageExecutor::execute[probing]
指分布式查询执行前的探测过程(probing)。系统会将客户端发起的查询任务拆分成多个子任务,部分在本地执行,部分发送到远端节点。当发送给远端的子任务过多时,系统会分批进行发送。[probing]阶段,系统会先发送一个子任务,根据其返回结果占用的内存大小估算所有子任务结果占用的内存大小,若超出
memLimitOfQueryResult,则抛出异常。若小于 memLimitOfQueryResult,则根据
memLimitOfTaskGroupResult
和单个子任务返回结果的大小计算每批包含的子任务数,再根据子任务总数算出拆分的批次。
StaticStageExecutor::execute[remote]
执行远程任务的过程,包括了网络调用和远端执行。
StaticStageExecutor::execute[local]
在本地工作线程执行任务的过程。
GOContainer::addRemoteTask
发送一个远程任务。注意这里只包含发送任务过程,不包括远端执行和响应过程。
TableJoiner::getReference
进行一次表连接。
GroupByEngine::getReference
对一次 group by 操作进行求值。
ContextByEngine::getReference
对一次 context by 操作进行求值。
PivotByEngine::getReference
对一次 pivot by 操作进行求值。
PartitionedPersistentTable::spillToDisk
对分区持久化表执行一次磁盘溢写
PipelinedJoinTask::getReference
执行一次 pipeline join任务
StaticStageExecutor::execute[batch]
批量执行任务
UniversalTableJoinImp::executeJoinPipeline
对多表查询执行一次 pipeline join
UniversalTableJoinImp::getReference
执行一次多表查询
例子
viewTraceInfo("c87ffe02-0c93-1db0-8e4f-b5416cce0207", true);
tree
script
startTime
timeElapsed
reference
node
thread
receiving request
2023.11.27 07:53:37.564128355
50
Root
local7270
41,472
└── Worker<0>::run
2023.11.27 07:53:37.565859643
109,969
FollowsFrom
local7270
41,457
├── Tokenizer::tokenize
2023.11.27 07:53:37.566078288
61
ChildOf
local7270
41,457
├── Parser::parse
2023.11.27 07:53:37.566161146
429
ChildOf
local7270
41,457
└── Statement::execute
t1 = select
ID,col1,col2,ratio1,ratio2,col1 * ratio1 as col1_mul,col2 *
ratio2 as col2_mul from ej(loadTable("dfs://TSDBdemo",
"data"),temp,"ID","securityId") where ID in "tag" + string(1 ..
19)
2023.11.27 07:53:37.566651394
109,110
ChildOf
local7270
41,457
└── SQLQueryImp::getReference
select ID,col1,col2,ratio1,ratio2,col1 *
ratio1 as col1_mul,col2 * ratio2 as col2_mul from
ej(loadTable("dfs://TSDBdemo", "data"),temp,"ID","securityId")
where ID in "tag" + string(1 .. 19)
2023.11.27 07:53:37.566691562
109,031
ChildOf
local7270
41,457
└── SQLQueryImp::getReference
select ID,col1,col2,ratio1,ratio2,col1 *
ratio1 as col1_mul,col2 * ratio2 as col2_mul from
ej(data,tempb035e530587f0000,"ID","securityId") where ID in
"tag" + string(1 .. 19)
2023.11.27 07:53:37.567047904
108,611
ChildOf
local7270
41,457
└── SQLQueryImp::partitionedCall
2023.11.27 07:53:37.568467496
107,166
ChildOf
local7270
41,457
└── SQLQueryImp::executeDistributedTasks
2023.11.27 07:53:37.569360522
105,751
ChildOf
local7270
41,457
├── StaticStageExecutor::execute
2023.11.27 07:53:37.569425993
103,402
ChildOf
local7270
41,457
│ ├── StaticStageExecutor::execute[probing]
2023.11.27 07:53:37.569446501
5
ChildOf
local7270
41,457
│ ├── StaticStageExecutor::execute[localWorker]
2023.11.27 07:53:37.569472069
16,530
ChildOf
local7270
41,457
│ ├── StaticStageExecutor::execute[remote]
2023.11.27 07:53:37.569491542
16,503
ChildOf
local7270
41,457
│ └── StaticStageExecutor::execute[local]
2023.11.27 07:53:37.569512416
102,990
ChildOf
local7270
41,457
│ ├── SQLQueryImp::getReference
select [147467]
ID,col1,col2,ratio1,ratio2,col1 * ratio1 as col1_mul,col2 *
ratio2 as col2_mul from
ej(data,tempb035e530587f0000,"ID","securityId") where ID in
"tag" + string(1 .. 19) [partition =
/TSDBdemo/20231112/Key0/x5]
2023.11.27 07:53:37.586062823
10,658
ChildOf
local7270
41,457
│ │ └── SQLQueryImp::basicCall
2023.11.27 07:53:37.586079488
10,611
ChildOf
local7270
41,457
│ │ └── TableJoiner::getReference
ej(data,tempb035e530587f0000,"ID","securityId")
2023.11.27 07:53:37.586099380
10,465
ChildOf
local7270
41,457
│ │ └── TableJoinerImp::getReference
ej(data,tempb035e530587f0000,"ID","securityId")
2023.11.27 07:53:37.586123907
10,374
ChildOf
local7270
41,457
│ ├── SQLQueryImp::getReference
2023.11.27 07:53:37.596826822
16,607
ChildOf
local7270
41,457
│ │ └── SQLQueryImp::basicCall
2023.11.27 07:53:37.596858895
16,529
ChildOf
local7270
41,457
│ │ └── TableJoiner::getReference
2023.11.27 07:53:37.596885332
16,342
ChildOf
local7270
41,457
│ │ └── TableJoinerImp::getReference
2023.11.27 07:53:37.596920858
14,428
ChildOf
local7270
41,457
│ ├── SQLQueryImp::getReference
2023.11.27 07:53:37.613520106
5,338
ChildOf
local7270
41,457
│ │ └── SQLQueryImp::basicCall
2023.11.27 07:53:37.613543452
5,251
ChildOf
local7270
41,457
│ │ └── TableJoiner::getReference
2023.11.27 07:53:37.613565397
5,127
ChildOf
local7270
41,457
│ │ └── TableJoinerImp::getReference
2023.11.27 07:53:37.613591427
5,067
ChildOf
local7270
41,457
│ ├── SQLQueryImp::getReference
2023.11.27 07:53:37.618933658
13,263
ChildOf
local7270
41,457
│ │ └── SQLQueryImp::basicCall
2023.11.27 07:53:37.618955493
13,198
ChildOf
local7270
41,457
│ │ └── TableJoiner::getReference
2023.11.27 07:53:37.618973938
10,390
ChildOf
local7270
41,457
│ │ └── TableJoinerImp::getReference
2023.11.27 07:53:37.618998447
10,167
ChildOf
local7270
41,457
│ ├── SQLQueryImp::getReference
2023.11.27 07:53:37.632284783
11,046
ChildOf
local7270
41,457
│ │ └── SQLQueryImp::basicCall
2023.11.27 07:53:37.632305236
11,022
ChildOf
local7270
41,457
│ │ └── TableJoiner::getReference
2023.11.27 07:53:37.632330014
10,864
ChildOf
local7270
41,457
│ │ └── TableJoinerImp::getReference
2023.11.27 07:53:37.632352650
7,955
ChildOf
local7270
41,457
│ ├── SQLQueryImp::getReference
2023.11.27 07:53:37.643674730
11,336
ChildOf
local7270
41,457
│ │ └── SQLQueryImp::basicCall
2023.11.27 07:53:37.643693926
11,313
ChildOf
local7270
41,457
│ │ └── TableJoiner::getReference
2023.11.27 07:53:37.643714493
11,168
ChildOf
local7270
41,457
│ │ └── TableJoinerImp::getReference
2023.11.27 07:53:37.643737539
8,961
ChildOf
local7270
41,457
│ ├── SQLQueryImp::getReference
select [147467]
ID,col1,col2,ratio1,ratio2,col1 * ratio1 as col1_mul,col2 *
ratio2 as col2_mul from
ej(data,tempb035e530587f0000,"ID","securityId") where ID in
"tag" + string(1 .. 19) [partition =
/TSDBdemo/20231120/Key0/x5]
2023.11.27 07:53:37.655067979
10,913
ChildOf
local7270
41,457
│ │ └── SQLQueryImp::basicCall
2023.11.27 07:53:37.655087126
10,874
ChildOf
local7270
41,457
│ │ └── TableJoiner::getReference
2023.11.27 07:53:37.655294579
10,551
ChildOf
local7270
41,457
│ │ └── TableJoinerImp::getReference
2023.11.27 07:53:37.655322871
10,413
ChildOf
local7270
41,457
│ └── SQLQueryImp::getReference
2023.11.27 07:53:37.666074996
6,352
ChildOf
local7270
41,457
│ └── SQLQueryImp::basicCall
2023.11.27 07:53:37.666094885
6,317
ChildOf
local7270
41,457
│ └── TableJoiner::getReference
2023.11.27 07:53:37.666112965
6,188
ChildOf
local7270
41,457
│ └── TableJoinerImp::getReference
2023.11.27 07:53:37.666133582
6,111
ChildOf
local7270
41,457
├──
SQLQueryImp::executeDistributedTasks[firstNonEmptyTask.getValue]
2023.11.27 07:53:37.672891073
102
ChildOf
local7270
41,457
├──
SQLQueryImp::executeDistributedTasks[collectFinalColumns]
2023.11.27 07:53:37.673014087
72
ChildOf
local7270
41,457
└──
SQLQueryImp::executeDistributedTasks[concatenateColumns]
2023.11.27 07:53:37.673112499
1,621
ChildOf
local7270
41,457
FILE:references/doc_853.md
# floor
**URL**: https://docs.dolphindb.cn/zh/funcs/f/floor.html
**来源**: DolphinDB 官方文档
---
floor
语法
floor(X)
详情
floor
和
ceil
函数分别把一个实数映射到小于等于它的最大整数,和大于等于它的最小整数。函数
round
根据四舍五入规则把一个实数映射到最接近的整数。
参数
X
可以是标量、向量或矩阵。
返回值
整型标量、向量或矩阵。
例子
floor(2.1);
// output
2
floor(2.9);
// output
2
floor(-2.1);
// output
-3
ceil(2.1);
// output
3
ceil(2.9);
// output
3
ceil(-2.1);
// output
-2
round(2.1);
// output
2
round(2.9);
// output
3
round(-2.1);
// output
-2
m = 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10$2:5;
m;
#0
#1
#2
#3
#4
1.1
3.3
5.5
7.7
9.9
2.2
4.4
6.6
8.8
10
floor(m);
#0
#1
#2
#3
#4
1
3
5
7
9
2
4
6
8
10
FILE:references/doc_8533.md
# getJobMessage
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getJobMessage.html
**来源**: DolphinDB 官方文档
---
getJobMessage
语法
getJobMessage(jobId)
详情
取得批处理任务的中间信息。详情请参考
BatchJobManagement
。
参数
jobId
是批处理作业的 ID,是一个字符串。
返回值
当返回值大小超过 65535 字节(即64 KB)时,返回类型为 BLOB(最大支持 64 MB);否则返回类型为
STRING(最大支持 64 KB)。
例子
def job1(n){
s = 0
for (x in 1 : n) {
s += sum(sin rand(1.0, 100000000)-0.5)
print("iteration " + x + " " + s)
}
return s
}
job1_ID=submitJob("job1_ID","", job1, 100);
批处理作业完成后,执行以下命令:
getJobMessage(job1_ID);
返回:
2025-05-26 14:44:58.090748 Start the job [job1_ID202505260000]: job1
2025-05-26 14:44:59.394245 iteration 1 -2067.639360414350903
2025-05-26 14:45:00.571536 iteration 2 -3394.027760215838497
2025-05-26 14:45:01.728218 iteration 3 -6658.143178910555434
2025-05-26 14:45:02.955152 iteration 4 -9995.435727637650415
2025-05-26 14:45:04.362283 iteration 5 -8653.510696739111153
2025-05-26 14:45:05.542019 iteration 6 -10801.809641761219609
2025-05-26 14:45:06.702139 iteration 7 -12924.020454809666262
2025-05-26 14:45:07.850191 iteration 8 -10882.168276451939163
2025-05-26 14:45:09.060107 iteration 9 -14318.061736551684589
2025-05-26 14:45:10.428853 iteration 10 -11516.30579954075074
2025-05-26 14:45:11.570470 iteration 11 -13945.02455184262908
2025-05-26 14:45:12.706159 iteration 12 -15082.415793091910018
2025-05-26 14:45:13.845771 iteration 13 -16508.837934508221223
2025-05-26 14:45:14.980443 iteration 14 -12171.185820641085228
2025-05-26 14:45:16.133074 iteration 15 -11497.140285110303011
2025-05-26 14:45:17.305225 iteration 16 -12546.300852946240411
2025-05-26 14:45:18.469218 iteration 17 -8682.138463782639519
2025-05-26 14:45:19.636227 iteration 18 -8287.05071118341948
2025-05-26 14:45:20.797512 iteration 19 -6045.8953755881721
2025-05-26 14:45:21.989929 iteration 20 -1587.853404830938416
2025-05-26 14:45:23.366825 iteration 21 -1061.898133246364068
2025-05-26 14:45:24.509909 iteration 22 -5604.016581881107413
2025-05-26 14:45:25.658594 iteration 23 -681.276543087000391
2025-05-26 14:45:26.814315 iteration 24 798.217304283653447
2025-05-26 14:45:27.967876 iteration 25 -2357.82192257714496
2025-05-26 14:45:29.122764 iteration 26 1474.997463642485854
2025-05-26 14:45:30.264584 iteration 27 2351.139591280943477
2025-05-26 14:45:31.408370 iteration 28 1037.512168873698328
2025-05-26 14:45:32.548303 iteration 29 3893.945455537286761
2025-05-26 14:45:33.699278 iteration 30 4148.650282345925006
2025-05-26 14:45:34.894419 iteration 31 4031.307766634015024
2025-05-26 14:45:36.285051 iteration 32 4107.605624560140313
2025-05-26 14:45:37.452961 iteration 33 5929.91120327810222
2025-05-26 14:45:38.623867 iteration 34 9425.642810558107157
2025-05-26 14:45:39.791290 iteration 35 13047.809822686220286
2025-05-26 14:45:40.965689 iteration 36 10245.933230357943102
2025-05-26 14:45:42.117447 iteration 37 5432.54276188393851
2025-05-26 14:45:43.253473 iteration 38 5227.81294757969772
2025-05-26 14:45:44.241254 iteration 39 1356.898505138993641
2025-05-26 14:45:44.860755 iteration 40 -1671.878041062590909
2025-05-26 14:45:45.484119 iteration 41 -1021.138518814122107
2025-05-26 14:45:46.108090 iteration 42 -2321.149447111632525
2025-05-26 14:45:46.720242 iteration 43 -5246.586195028939982
2025-05-26 14:45:47.339880 iteration 44 -8492.119388688672188
2025-05-26 14:45:47.994839 iteration 45 -8663.850570230377343
2025-05-26 14:45:48.798468 iteration 46 -10024.085162459703497
2025-05-26 14:45:49.416817 iteration 47 -7627.128519907962072
2025-05-26 14:45:50.050123 iteration 48 -8859.465736911144631
2025-05-26 14:45:50.696957 iteration 49 -11600.588771286853443
2025-05-26 14:45:51.332706 iteration 50 -12023.426188408715461
2025-05-26 14:45:51.958107 iteration 51 -13738.331148613655386
2025-05-26 14:45:52.574174 iteration 52 -14245.913822854639875
2025-05-26 14:45:53.228183 iteration 53 -15609.22655546905662
2025-05-26 14:45:53.840108 iteration 54 -14109.554485099233716
2025-05-26 14:45:54.455551 iteration 55 -15457.235974196633833
2025-05-26 14:45:55.109167 iteration 56 -14926.928231457419315
2025-05-26 14:45:55.901304 iteration 57 -13535.493685042154538
2025-05-26 14:45:56.512054 iteration 58 -11137.324502514182313
2025-05-26 14:45:57.126833 iteration 59 -8467.404657879153091
2025-05-26 14:45:57.742143 iteration 60 -1746.003070659520744
2025-05-26 14:45:58.353437 iteration 61 -3325.876159699668278
2025-05-26 14:45:58.966068 iteration 62 588.700051641846584
2025-05-26 14:45:59.574346 iteration 63 -5367.267372965314279
2025-05-26 14:46:00.185607 iteration 64 -5910.796992469990073
2025-05-26 14:46:00.828945 iteration 65 -3960.193144167483296
2025-05-26 14:46:01.458748 iteration 66 122.939722062535111
2025-05-26 14:46:02.128915 iteration 67 -704.828146272833123
2025-05-26 14:46:02.955747 iteration 68 3864.606686010478824
2025-05-26 14:46:03.584085 iteration 69 5186.69739255679724
2025-05-26 14:46:04.210760 iteration 70 5384.310290306410024
2025-05-26 14:46:04.832343 iteration 71 3535.338795232024494
2025-05-26 14:46:05.451344 iteration 72 7529.76101041288075
2025-05-26 14:46:06.070711 iteration 73 5539.502143333455023
2025-05-26 14:46:06.719013 iteration 74 7597.268444337500113
2025-05-26 14:46:07.342229 iteration 75 14728.821072668564738
2025-05-26 14:46:07.979907 iteration 76 18934.636409439837734
2025-05-26 14:46:08.596204 iteration 77 19498.750036070654459
2025-05-26 14:46:09.252392 iteration 78 19268.594342755670368
2025-05-26 14:46:10.059616 iteration 79 20036.702738540243444
2025-05-26 14:46:10.734090 iteration 80 24399.283123330875241
2025-05-26 14:46:11.401129 iteration 81 26353.387390017069265
2025-05-26 14:46:12.020258 iteration 82 25021.36744718257978
2025-05-26 14:46:12.640379 iteration 83 20515.896296028589858
2025-05-26 14:46:13.271550 iteration 84 18948.980154855420551
2025-05-26 14:46:13.888417 iteration 85 22251.157044437986769
2025-05-26 14:46:14.509057 iteration 86 21076.744112906457303
2025-05-26 14:46:15.129712 iteration 87 19794.661956942076358
2025-05-26 14:46:15.750538 iteration 88 20416.494072026296635
2025-05-26 14:46:16.401382 iteration 89 19871.931658841131138
2025-05-26 14:46:17.209955 iteration 90 18276.697674308263231
2025-05-26 14:46:17.828958 iteration 91 19967.525665167577244
2025-05-26 14:46:18.461022 iteration 92 22098.668749747052061
2025-05-26 14:46:19.079399 iteration 93 17969.401810196610313
2025-05-26 14:46:19.711974 iteration 94 18239.368392132648295
2025-05-26 14:46:20.358000 iteration 95 18944.493373054185212
2025-05-26 14:46:21.011468 iteration 96 14969.713016859974231
2025-05-26 14:46:21.648286 iteration 97 12863.562367756972889
2025-05-26 14:46:22.289103 iteration 98 12659.014405440735572
2025-05-26 14:46:22.917878 iteration 99 14069.1513439974442
2025-05-26 14:46:22.917878 The job is done.
FILE:references/doc_8536.md
# getInstrumentPayoffType
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentpayofftype.html
**来源**: DolphinDB 官方文档
---
getInstrumentPayoffType
语法
getInstrumentPayoffType(instrument)
详情
根据输入的金融工具,获取该工具的收益类型。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
STRING 类型标量或向量。
例子
option = {
"productType": "Option",
"optionType": "EuropeanOption",
"assetType": "FxEuropeanOption",
"version": 0,
"notional": ["EUR", 1000000.0],
"strike": 1.2,
"maturity": "2025.10.08",
"payoffType": "Call",
"dayCountConvention": "Actual365",
"underlying": "EURUSD"
}
ins = parseInstrument(option)
getInstrumentPayoffType(ins)
// output: Call
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_8543.md
# ridgeBasic
**URL**: https://docs.dolphindb.cn/zh/funcs/r/ridgeBasic.html
**来源**: DolphinDB 官方文档
---
ridgeBasic
语法
ridgeBasic(Y, X, [mode=0], [alpha=1.0], [intercept=true], [normalize=false],
[maxIter=1000], [tolerance=0.0001], [solver='svd'], [swColName])
详情
进行 ridge 回归估计。
最小化以下目标函数:
参数
Y
数值类型的向量,表示因变量。
X
数值类型的向量/元组/矩阵/表,表示自变量。
当
X
是向量/元组时,其长度必须等于 Y 的长度。
当
X
是矩阵/表时,其行数必须等于 Y 的长度。
mode
一个整数,可取以下 3 个值
0(默认值): 输出一个系数估计向量
1: 输出一个具有系数估计,标准差,t 统计量和 p 值的表
2: 输出一个具有 ANOVA(方差分析)、RegressionStat(回归统计)、Cofficient(系数) 和 Residual(残差)
的字典,具体含义见下表:
键 ANOVA 对应值:
Source of Variance
自由度(Degree of freedom)
平方和(Sum of Square)
均方差(Mean of square)
F统计量
Significance
Regression(回归)
变量个数(p)
回归平方和(SSR)
回归均方差(MSR=SSR/R)
MSR对MSE的比值
显著性,即统计出的P值
Residual(残差)
残差自由度(n-p-1)
残差平方和(SSE)
残差均方差(MSE=MSE/E)
Total
样本自由度, 不包括常数项(n-1)
总离差平方和(SST)
键 RegressionStat 对应值:
item
统计值
R2
R决定系数,描述回归曲线对真实数据点拟合程度的统计量。范围在 [0,1]之间,越接近1
,说明对y的解释能力越强,拟合越好。
AdjustedR2
经自由度修正后的决定系数,通过样本数量与模型数量对 R-squared 进行修正。
StdError
回归残差标准误差,残差经自由度修正后的标准差。
Observations
观察样本个数。
键 Coefficient 对应值:
元素
说明
factor
自变量名称
beta
回归系数估计值
stdError
回归系数标准误差。
tstat
T统计值,衡量系数的统计显著性。
键 Residual 对应每一个预测值和实际值之间的残差。
alpha
一个浮点数,表示乘以L1范数惩罚项的系数。默认值是1.0。
intercept
布尔值,表示是否包含回归中的截距。默认值为 true,此时系统自动给
X
添加一列 “1”
以生成截距。
normalize
布尔值,默认值为 false。若设为 true,则所有自变量均会进行如下标准化:减去平均值,然后除以L2范数。若
intercept 为 false,该参数会被忽略。
maxIter
一个正整数,表示最大迭代次数。默认值是1000。
tolerance
一个浮点数,表示迭代中止的边界差值。默认值是0.0001。
solve
字符串,表示回归算法模型。可取值 ‘svd’ 或 ‘cholesky’。若 ds 为多个数据源,则 solver 必须为
’cholesky’。
swColName
字符串,表示列名,必须为 X
中存在的列名。如果未指定该参数,则所有样本的权重都默认为1;如果指定该参数,则将指定的列作为自变量的权重。
返回值
返回一个向量、表或字典,取决于参数
mode
。
FILE:references/doc_8548.md
# kama
**URL**: https://docs.dolphindb.cn/zh/funcs/k/kama.html
**来源**: DolphinDB 官方文档
---
kama
语法
kama(X, window)
TA-lib 系列函数参数说明和窗口计算规则请参考:
TA-lib 系列
详情
在给定长度(以元素个数衡量)的滑动窗口内,计算
X
的考夫曼自适应移动平均值(Kaufman Adaptive
Moving Average)。
返回值
DOUBLE 类型,数据形式同
X
。
例子
x=[51.65, 81.18, 43.37, 11.26, 82.79, 13.4, 81.87, 63.53, 21.28, 94.23]
kama(x, 5);
// output
[,,,,,81.006144,81.009907,80.793626,80.344572,80.456788]
t=table(take(`A`B,10) as sym, rand(100.0,10) as close)
select sym, kama(close, 3) as kama from t context by sym;
输出返回:
sym
kama
A
A
A
A
66.342572
A
62.500023
B
B
B
B
17.376469
B
42.27882
FILE:references/doc_8552.md
# drop
**URL**: https://docs.dolphindb.cn/zh/progr/sql/drop.html
**来源**: DolphinDB 官方文档
---
drop
drop 语句用于删除数据库或者数据表。建库建表语句请参考
create
。
删除分布式数据库
语法
drop database [if exists] dbPath
参数
dbPath
数据库的路径。
例子
drop database if exists "dfs://test"
相关函数:
dropDatabase
,
existsDatabase
删除分布式表或维度表
语法
drop table [if exists] dbPath.tableName
参数
dbPath
字符串,表示数据库的路径。
tableName
字符串,分布式表和维度表的表名。
例子
drop table if exists "dfs://test"."pt"
相关函数:
dropTable
,
existsTable
删除 catalog 中的数据库
语法
drop database [if exists] catalog.schema
参数
catalog.schema
要删除数据库的结构为 catalog.schema 的字符串。若已设置当前的默认 catalog,则可忽略
catalog 前缀,直接传入
schema。
删除 catalog 中的数据表
语法
drop table [if exists] catalog.schema.tableName
参数
catalog.schema.tableName
要删除数据库的结构为“catalog.schema.tableName”的字符串。若已设置当前的默认 catalog,则可忽略 catalog
前缀,直接传入“
schema
.tableName”
。
删除内存表
语法
drop table [if exists] tableName
参数
tableName
与内存表对象同名的字符串。
例子
drop table if exists "t"
相关函数:
undef
,
objs
FILE:references/doc_8559.md
# writeRecord
**URL**: https://docs.dolphindb.cn/zh/funcs/w/writeRecord.html
**来源**: DolphinDB 官方文档
---
writeRecord
语法
writeRecord(handle, object, [offset=0], [length])
详情
writeRecord
函数把 DolphinDB 对象(例如表或元组)转换为二进制文件。
参数
handle
是二进制文件句柄。
object
是一个表或一个由多个等长向量组成的元组。
offset
表示写入的起始位置。
length
是向文件写入的行数。
返回值
整型标量,表示向文件写入的行数。
例子
t=table(1..10000 as id, 1..10000+100 as value);
f1=file("C:/DolphinDB/a.bin", "w"); // 创建一个用于写入记录的文件句柄
f1.writeRecord(t);
// output
10000
f2=file("C:/DolphinDB/b.bin", "w");
f2.writeRecord(t, 100, 1000);
// output
1000
f3=file("C:/DolphinDB/c.bin", "w");
f3.writeRecord(t, 100, 10000);
// output
The optional argument length is invalid.
FILE:references/doc_8570.md
# getGroupAccessByCluster
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getGroupAccessByCluster.html
**来源**: DolphinDB 官方文档
---
getGroupAccessByCluster
语法
getGroupAccessByCluster(groupIds, clusterName)
详情
查询指定用户组的权限。只能由管理员在 MoM(Master of Master,管理集群)上执行该函数。
参数
groupIds
字符串标量或向量,表示要查询的用户组名称。
clusterName
字符串标量,表示用户组所属的集群名称。
返回值
返回一个表, 字段与
getGroupAccess
函数的返回结果一致。
例子
getGroupAccessByCluster(["group2"], "MoMSender")
groupName
users
ACCESS_READ
ACCESS_INSERT
ACCESS_UPDATE
ACCESS_DELETE
VIEW_EXEC
SCRIPT_EXEC
TEST_EXEC
DBOBJ_CREATE
...
group2
user2
none
allow
none
none
none
none
none
none
...
相关函数:
getGroupAccess
FILE:references/doc_8585.md
# temporalDeltas
**URL**: https://docs.dolphindb.cn/zh/funcs/t/temporalDeltas.html
**来源**: DolphinDB 官方文档
---
temporalDeltas
别名:datetimeDeltas
语法
temporalDeltas(X, [unit])
详情
temporalDeltas
函数计算
X
中每个元素与前一个元素之间的时间差,NULL 值在计算中返回
NULL,且输出的第一个值总是 NULL。
若
X
是向量,返回一个包含
X
中两个元素之差的向量。
若
X
是矩阵,在每列内进行上述计算,返回一个与
X
维度相同的矩阵。
若
X
是表,在每个时间类型列内进行上述计算,返回一个与
X
行数与列数都相同的表。
当提供
unit
参数时,时间差的计算将基于指定的时间单位(天、工作日或特定交易所的交易日)。
参数
X
是一个时间类型的向量、矩阵,或包含时间类型列的表。
unit
可选参数,是一个字符串标量,指定时间单位。取值可以是:
"d" 表示自然日
"B" 表示工作日
一个交易日历标识,例如 "XNYS",对应的交易日历文件必须保存在
marketHolidayDir
配置项指定的目录中。
注:
若指定
unit
,
X
必须是 DATE 类型。
返回值
INT 类型,数据形式同
X
。
例子
timestamps = [2020.06.13T13:30:10.000, 2020.06.13T13:30:10.010, 2020.06.13T13:30:10.021, 2020.06.13T13:30:10.033, 2020.06.13T13:30:10.046]
temporalDeltas(timestamps)
// Output: [,10,11,12,13]
若指定
unit
参数,
X
必须为日期(DATE)类型:
times = [2019.12.31, 2020.01.03, 2020.01.10, 2020.01.15, 2020.01.17]
temporalDeltas(times, "d");
// Output: [NULL, 3, 7, 5, 2]
temporalDeltas(times, "B");
// Output: [NULL, 3, 5, 3, 2]
temporalDeltas(times, "XNYS");
// Output: [NULL, 2, 5, 3, 2]
sym = `A`B`C`D`E
num = 5 4 3 2 1
t = table(times, sym, num)
temporalDeltas(t);
/*
times sym num
----- --- ---
A 5
3 B 4
7 C 3
5 D 2
2 E 1
*/
FILE:references/doc_8589.md
# sma
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sma.html
**来源**: DolphinDB 官方文档
---
sma
语法
sma(X, window)
TA-lib 系列函数参数说明和窗口计算规则请参考:
TAlib
详情
在给定长度(以元素个数衡量)的滑动窗口内,计算
X
的简单移动平均(Simple Moving
Average)。
其计算公式为:
返回值
DOUBLE 类型向量。
例子
x=12.1 12.2 12.6 12.8 11.9 11.6 11.2
sma(x,3);
// output
[,,12.299999999999998,12.533333333333331,12.433333333333331,12.099999999999999,11.566666666666664]
x=matrix(12.1 12.2 12.6 12.8 11.9 11.6 11.2, 14 15 18 19 21 12 10)
sma(x,3);
col1
col2
12.3
15.6667
12.5333
17.3333
12.4333
19.3333
12.1
17.3333
11.5667
14.3333
相关函数:
wma
,
trima
FILE:references/doc_8598.md
# acos
**URL**: https://docs.dolphindb.cn/zh/funcs/a/acos.html
**来源**: DolphinDB 官方文档
---
acos
语法
acos(X)
详情
返回
X
的反余弦。
参数
X
可以是标量、向量、矩阵或表。
返回值
返回结果的数据形式与输入保持一致:若输入为标量,返回标量;若输入为向量、矩阵或表,返回相同维度的结果。
例子
acos(1.000000 0.540302 -0.416147);
// output: [0,1,2]
相关函数:
asin
,
atan
,
sin
,
cos
,
tan
,
asinh
,
acosh
,
atanh
,
sinh
,
cosh
,
tanh
FILE:references/doc_860.md
# mimin
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mimin.html
**来源**: DolphinDB 官方文档
---
mimin
语法
mimin(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
中最小元素的位置。如果窗口内存在多个相同的最小值,则返回左起第一个最小值的位置。与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
当
X
是向量时,返回一个整型向量,长度与输入向量相同。
当
X
是矩阵时,返回一个整型矩阵,形状与输入矩阵相同。
当
X
是表时,对表的每列进行计算,返回相应的结果。
当
X
是元组时,对元组中的每个向量分别计算,返回相应的结果。
例子
x = 1.2 2 NULL 6 -1 -1
mimin(x, 3);
//output: [,,0,0,2,1]
mimin(x, 3, 1);
//output: [0,0,0,0,2,1]
m=matrix(1 6 2 9 10 3, 9 10 2 6 6 6);
m;
#0
#1
1
9
6
10
2
2
9
6
10
6
3
6
mimin(m,3);
#0
#1
0
2
1
1
0
0
2
0
T = [2022.01.01, 2022.01.02, 2022.01.03, 2022.01.06, 2022.01.07, 2022.01.08, 2022.01.10, 2022.01.11]
X = 1..8
X1 = indexedSeries(T, X)
mimin(X1,3)
#0
2022.01.01
0
2022.01.02
0
2022.01.03
0
2022.01.06
0
2022.01.07
0
2022.01.08
0
2022.01.10
0
2022.01.11
0
t= 2021.01.02 2021.01.05 2021.01.06 2021.01.09 2021.01.10 2021.01.12
m=matrix(5 4 NULL -1 2 4, 3 2 8 1 0 5)
m1=m.rename!(t, `a`b).setIndexedMatrix!()
mimin(m1,3)
a
b
2021.01.02
0
0
2021.01.05
0
0
2021.01.06
0
0
2021.01.09
0
0
2021.01.10
0
1
2021.01.12
0
0
FILE:references/doc_8602.md
# isValley
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isValley.html
**来源**: DolphinDB 官方文档
---
isValley
语法
isValley(X, [strict=true])
详情
若
X
为向量,计算
X
中的每个元素是否为谷值点,若是则返回 true,否则返回 false。
若
X
为矩阵,在每列进行上述计算,返回值一个同 X 维度相同的矩阵。若
X
为表,则只对数值型的列进行上述计算。
参数
X
数值型向量/矩阵/表。
strict
布尔值,表示是否取严格的谷值点。默认值为 true。
若
strict
= true,相邻元素不为空且严格大于该元素
若
strict
= false,相邻元素不为空且大于等于该元素
返回值
当
X
是向量时,返回布尔向量。
当
X
是矩阵时,返回布尔矩阵。
当
X
是表时,返回一个表。
例子
v = [3.1, 2.2, 2.2, 2.2, 1.3, 2.1, 1.2]
isValley(v)
// output: [false,false,false,false,true,false,false]
v = [3.1, 2.2, 2.2, 2.2, 2.6, 1, 1.2]
isValley(v)
// output: [false,false,false,false,false,true,false]
isValley(v, false)
// output: [false,true,true,true,false,true,false]
// 矩阵在每列单独计算
m = matrix(5.3 5.8 5.6 NULL 5.7 1.2, 4.5 3.5 4.6 2.8 3.9 NULL)
isValley(m)
#0
#1
false
false
false
true
false
false
false
true
false
false
false
false
// 表只在数值列进行计算
t = table(`01`01`00`01`02`00 as id, 388.3 390.6 390.8 390.6 390.3 391.5 as price)
isValley(t)
id
price
01
false
01
false
00
false
01
false
02
true
00
false
相关函数:
isPeak
FILE:references/doc_8603.md
# getTablet
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getTablet.html
**来源**: DolphinDB 官方文档
---
getTablet
语法
getTablet(table, partition)
详情
查询内存分区表指定分区的子表。
参数
table
是一个内存分区表。
partition
是一个标量或向量,代表分区。若
partition
中某元素属于某个分区的分区列,此元素代表该分区。
返回值
如果
partition
是标量,返回一个表。
如果
partition
是向量,返回一个元组,其中每个元素是一个表。
例子
db=database(partitionType=RANGE, partitionScheme=2012.06.01 2012.06.10 2012.06.20 2012.07.01)
n=30
t=table(take(2012.06.01..2012.06.30, n) as date, n..1 as val)
pt=db.createPartitionedTable(table=t, tableName=`pt, partitionColumns=`date).append!(t);
getTablet(pt, 2012.06.05);
date
val
2012.06.01
30
2012.06.02
29
2012.06.03
28
2012.06.04
27
2012.06.05
26
2012.06.06
25
2012.06.07
24
2012.06.08
23
2012.06.09
22
result=getTablet(pt, 2012.06.22 2012.06.11);
result.size();
// output
2
result[0];
date
val
2012.06.20
11
2012.06.21
10
2012.06.22
9
2012.06.23
8
2012.06.24
7
2012.06.25
6
2012.06.26
5
2012.06.27
4
2012.06.28
3
2012.06.29
2
2012.06.30
1
FILE:references/doc_861.md
# wc
**URL**: https://docs.dolphindb.cn/zh/funcs/w/wc.html
**来源**: DolphinDB 官方文档
---
wc
语法
wc(X)
详情
计算
X
中包含的单词数量。
参数
X
是一个字符串。它可以是标量或向量。
返回值
一个 INT 类型的标量或向量。
例子
wc(`apple);
// output
1
wc("This is a 7th generation iphone!");
// output
6
wc("This is a 7th generation iphone!" "I wonder what the 8th generation looks like");
// output
[6,8]
FILE:references/doc_8623.md
# cumstdp
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumstdp.html
**来源**: DolphinDB 官方文档
---
cumstdp
语法
cumstdp(X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累计总体标准差。
返回值
DOUBLE 类型,其数据形式同
X
。
例子
x = [1,2,4,NULL,8];
cumstdp(x)
// output
[0, 0.5, 1.247219128924647, 1.247219128924647, 2.680951323690902]
m=matrix(0.15 0.08 0.03 -0.14 -0.09, 0.2 -0.12 -0.16 0.08 0.16);
m;
#0
#1
0.15
0.2
0.08
-0.12
0.03
-0.16
-0.14
0.08
-0.09
0.16
cumstdp(m);
col1
col2
0
0
0.035
0.16
0.0492
0.1611
0.107
0.147
0.1071
0.1462
FILE:references/doc_863.md
# lu
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lu.html
**来源**: DolphinDB 官方文档
---
lu
语法
lu(obj, [permute=false])
详情
实现矩阵的 LU 分解。
参数
obj
是一个不包含 NULL 值的矩阵。
permute
是一个布尔值。默认值为 false。
返回值
如果
permute
为 false,返回三个矩阵,依次是 L, U, P,满足条件
obj
= P' * L * U。P
是置换矩阵;L 是下三角矩阵,其对角线元素均为1;U 是上三角矩阵。
如果
permute
为 true,返回两个矩阵,依次是 L,U,满足条件
obj
= L * U。
例子
A = matrix([[2, 5, 8, 7], [5, 2, 2, 8], [7, 5, 6, 6], [5, 4, 4, 8]]);
P, L, U = lu(A);
P;
#0
#1
#2
#3
0
0
1
0
0
0
0
1
1
0
0
0
0
1
0
0
L;
#0
#1
#2
#3
1
0
0
0
0.875
1
0
0
0.25
0.72
1
0
0.625
0.12
0.233871
1
U;
#0
#1
#2
#3
8
2
6
4
0
6.25
0.75
4.5
0
0
4.96
0.76
0
0
0
0.782258
L, U = lu(A, true);
L;
#0
#1
#2
#3
0.25
0.72
1
0
0.625
0.12
0.233871
1
1
0
0
0
0.875
1
0
0
U;
#0
#1
#2
#3
8
2
6
4
0
6.25
0.75
4.5
0
0
4.96
0.76
0
0
0
0.782258
FILE:references/doc_8637.md
# randBeta
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randBeta.html
**来源**: DolphinDB 官方文档
---
randBeta
语法
randBeta(alpha, beta, count)
详情
生成指定个数的 Beta 分布随机数。
参数
形状参数
alpha
和
beta
都是正数。
count
是正整数,表示生成随机数的个数。
返回值
长度为
count
的 DOUBLE 类型向量。
例子
randBeta(2.31, 0.627, 2);
// output
[0.781246, 0.951372]
FILE:references/doc_8642.md
# 错误代码
**URL**: https://docs.dolphindb.cn/zh/error_codes/err_codes.html
**来源**: DolphinDB 官方文档
---
错误代码
DolphinDB 数据库错误代码列表用于解释 DolphinDB Server(以下简称 Server)的不同类型错误。每个错误代码对应特定的系统状态或不当操作。
错误代码由三部分构成:
S + <与模块相关的错误类别码> + <类别内编码>
以 S00004 为例:
S:Server
00:错误类别,此处指系统错误类别,见下表第一行
004:错误类别下的 004 错误
表
1
.
错误代码类别
模块
错误类别
说明
系统
00
网络错误、磁盘错误、文件操作错误、内存错误等通用系统错误
存储
01
DFS、OLAP、TSDB、事务、Raft 基础模块、Recovery、Redo
log、cacheEngine、backup/restore、异步复制等相关错误
SQL
02
SQL 相关错误
流数据
03
流计算、流计算引擎、流数据引擎解释器相关错误
管理
04
与数据库管理操作、权限管理、函数视图、集群管理相关错误
通用
05
难以归类的错误。例如:与基础数据结构相关的错误
DolphinDB 解释器
06
语法错误和语法解析相关错误
部分报错信息中包含类似 "with error 13" 的信息。这里的 13 是 DolphinDB 的报错码。下表列举了 DolphinDB
报错码对应的报错信息:
表
2
.
DolphinDB 报错码
报错码
说明
1
Socket is disconnected/closed or file is closed.
2
In non-blocking socket mode, there is no data ready for retrieval
yet.
3
Out of memory, no disk space, or no buffer for sending data in
non-blocking socket mode.
4
String size exceeds 64K or code size exceeds 1 MB during
serialization over network.
5
In non-blocking socket mode, a program is in pending connection
mode.
6
Invalid message format.
7
Reach the end of a file or a buffer.
8
File is readable but not writable.
9
File is writable but not readable.
10
A file doesn't exist or the socket destination is not
reachable.
11
The database file is corrupted.
12
Not the leader node of the RAFT protocol.
13
Unknown IO error.
FILE:references/doc_8643.md
# removeHead!
**URL**: https://docs.dolphindb.cn/zh/funcs/r/removeHead_.html
**来源**: DolphinDB 官方文档
---
removeHead!
语法
removeHead!(obj, n)
详情
删除向量
obj
的前
n
个元素。
参数
obj
是一个向量。
n
是一个正整数,表示要删除的位于向量头部的元素的个数。
返回值
与
obj
同类型的向量。
例子
x=11..20;
x.removeHead!(3);
// output
[14,15,16,17,18,19,20]
FILE:references/doc_8652.md
# cdfGamma
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cdfGamma.html
**来源**: DolphinDB 官方文档
---
cdfGamma
语法
cdfGamma(shape, scale, X)
详情
返回 Gamma 分布的累计密度函数的值。
参数
形状参数
shape
是正数。
尺度参数
scale
是正数。
X
是数值型标量或向量。
返回值
DOUBLE 类型标量或向量。
例子
cdfGamma(2.31, 0.627, [0.001, 0.5, 0.999]);
// output
[0, 0.127367, 0.38032]
cdfGamma(2.31,0.627, [0.1, 0.3, 0.5, 0.7, 0.9]);
// output
[0.004754, 0.048388, 0.127367, 0.225351, 0.329391]
FILE:references/doc_8655.md
# rowGmd5
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowgmd5.html
**来源**: DolphinDB 官方文档
---
rowGmd5
语法
rowGmd5(args...)
详情
逐行计算 gmd5。
参数
args
是数组向量或列式元组。
返回值
一个长度与
args
行数相同的 INT128 向量。
例子
xs = array(INT[], 0, 10).append!([1 2 3, 4 5, 6 7 8, 9 10])
rowGmd5(xs)
// output: [2a1dd1e1e59d0a384c26951e316cd7e6,678157bbe4fd35371e047b4cadf9c46a,ff93cd8c0033f2ab93726d48661d1221,10986ac9310ecb2f10c3a5524eb38999]
// 输出四行,每个元素对应array vector中的每行,如1 2 3对应2a1dd1e1e59d0a384c26951e316cd7e6
gmd5(1 2 3)
// output: 2a1dd1e1e59d0a384c26951e316cd7e6
rowGmd5(xs, xs)
// output: [50420aa84aa547ebc24dfa3ef8fffa57,de90d6c74c0b99f5656b95563a9a35b7,376579b27ec7c2f6eed7347ef0e5a15b,78bf6752e93cbca5fd1dcc3519fc6c55]
ys = [1 2 3, 4 5, 6 7 8, 9 10]
ys.setColumnarTuple!(true)
rowGmd5(xs, ys)
// output: [50420aa84aa547ebc24dfa3ef8fffa57,de90d6c74c0b99f5656b95563a9a35b7,376579b27ec7c2f6eed7347ef0e5a15b,78bf6752e93cbca5fd1dcc3519fc6c55]
相关函数:
gmd5
FILE:references/doc_8656.md
# topRange
**URL**: https://docs.dolphindb.cn/zh/funcs/t/topRange.html
**来源**: DolphinDB 官方文档
---
topRange
语法
topRange(X)
详情
对于
X
中的每个元素
Xi
,统计
Xi
左侧相邻且连续小于它的元素个数。
该函数常用于统计一个序列的当前值是前多少周期(日或分钟等)内的最大值。例如某只股票创几日新高等。
参数
X
向量/元组/矩阵/表。
返回值
INT 类型,数据形式同
X
。
例子
topRange([13.5, 13.6, 13.4, 13.3, 13.5, 13.9, 13.1, 20.1, 20.2, 20.3])
// output
[0,1,0,0,2,5,0,7,8,9]
m = matrix(1.5 2.6 3.2 1.4 2.5 2.2 3.7 2.0, 1.6 2.3 4.2 5.6 4.1 3.2 4.4 6.9)
topRange(m)
#0
#1
0
0
1
1
2
2
0
3
1
0
0
0
6
2
0
7
//模拟股票 A 8天的股价,使用 topRange 计算股票 A 当日股价创几日新高
trades = table(take(`A, 8) as sym, 2022.01.01 + 1..8 as date, 39.70 39.72 39.80 39.78 39.83 39.92 40.00 40.03 as price)
select *, topRange(price) from trades
id
date
price
topRange_price
A
2022.01.02
39.7
0
A
2022.01.03
39.72
1
A
2022.01.04
39.8
2
A
2022.01.05
39.78
0
A
2022.01.06
39.83
4
A
2022.01.07
39.92
5
A
2022.01.08
40
6
A
2022.01.09
40.03
7
相关函数:
lowRange
FILE:references/doc_867.md
# rowAvg
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowAvg.html
**来源**: DolphinDB 官方文档
---
rowAvg
语法
rowAvg(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行元素求平均操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL])
rowAvg(m);
// output
[3.633333,3.133333,3.7]
t1=table(1..5 as x, 6..10 as y)
t2=table(5..1 as a, 10..6 as b);
rowAvg(t1);
// output
[3.5,4.5,5.5,6.5,7.5]
rowAvg(t1[`x], t2, take(1, 5));
// output
[4.25,4,3.75,3.5,3.25]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2)
select sym,rowAvg(price1,price2) as avg from t;
sym
price1
AAPL
112.415
MS
40.11
IBM
39.92
IBM
40.655
C
100.6
相关函数:
avg
FILE:references/doc_8672.md
# mbeta
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mbeta.html
**来源**: DolphinDB 官方文档
---
mbeta
语法
mbeta(Y, X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的移动窗口中,计算
Y
在
X
上的回归系数的最小二乘估计。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
Y
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
计算结果为 DOUBLE 类型,形式同输入参数。
例子
x=0.011 0.006 -0.008 0.012 -0.016 -0.023 0.018
y=0.016 0.009 -0.012 0.022 0.003 -0.056 0.002
mbeta(y, x, 5);
// output: [,,,,0.818182,1.692379,1.188532]
mbeta(y, x, 5, 3);
// output: [,,1.479381,1.594701,0.818182,1.692379,1.188532]
x1 = indexedSeries(date(2020.06.05)+1..7, x)
y1 = indexedSeries(date(2020.06.05)+1..7, y)
mbeta(y1, x1, 5d);
label
col1
2020.06.06
2020.06.07
1.4
2020.06.08
1.4794
2020.06.09
1.5947
2020.06.10
0.8182
2020.06.11
1.6924
2020.06.12
1.1885
mbeta(y1, x1, 1w);
label
col1
2020.06.06
2020.06.07
1.4
2020.06.08
1.4794
2020.06.09
1.5947
2020.06.10
0.8182
2020.06.11
1.6924
2020.06.12
1.2659
相关函数:
beta
FILE:references/doc_8673.md
# regexFind
**URL**: https://docs.dolphindb.cn/zh/funcs/r/regexFind.html
**来源**: DolphinDB 官方文档
---
regexFind
语法
regexFind(str, pattern, [offset])
详情
从
str
的第
offset
个位置开始搜索与
pattern
匹配的字符串,如果在
str
中找到匹配字符串,则返回
str
中第一个匹配字符串的位置;如果没有找到,则返回-1。
参数
str
是一个字符串或字符串向量。
pattern
是一个字符串,表示搜索的模式字符串(
正则表达式
)。模式字符串可以包含字面量字符、元字符或两者的组合。
offset
是一个非负整数,默认值为0。它是一个可选参数,表示从
str
的第
offset
个位置开始搜索。
str
的第一个位置为0。
返回值
INT 类型标量。
例子
regexFind("1231hsdU777_ DW#122ddd", "[a-z]+");
// output
4
regexFind("1231hsdU777_ DW#122ddd", "[0-9]+");
// output
0
regexFind("1231hsdU777_ DW#122ddd", "[0-9]+", 4);
// output
8
相关函数:
regexFindStr
FILE:references/doc_8685.md
# getInstrumentNotional
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentnotional.html
**来源**: DolphinDB 官方文档
---
getInstrumentNotional
语法
getInstrumentNotional(instrument)
详情
根据输入的金融工具,获取该工具的名义本金。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
ANY 向量。
例子
deposit = {
"productType": "Cash",
"assetType": "Deposit",
"version": 0,
"start": 2025.05.15,
"maturity": 2025.08.15,
"rate": 0.02,
"dayCountConvention": "Actual360",
"notional":["CNY", 1E6],
"payReceive": "Receive"
}
instrument = parseInstrument(deposit)
getInstrumentNotional(instrument)
// output: ("CNY",1000000)
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_8687.md
# createStreamDispatchEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createStreamDispatchEngine.html
**来源**: DolphinDB 官方文档
---
createStreamDispatchEngine
语法
createStreamDispatchEngine(name, dummyTable, keyColumn,
outputTable, [dispatchType='hash'], [hashByBatch=false], [outputLock=true],
[queueDepth=4096], [outputElapsedTime=false], [mode='buffer'])
详情
创建流数据分发引擎,返回一个表对象。该引擎将输入的数据分发到不同的输出表,以实现负载均衡。其中输出表可以是内存表,分布式表或流数据引擎。
引擎特性:
支持多线程输入和多线程输出。
只提供数据分发功能,不提供指标计算功能。
场景应用:
将快照数据分发给一个或多个计算引擎进行因子计算,以提高计算性能。
参数
name
字符串,表示流数据分发引擎的名称,可包含字母,数字和下划线,但必须以字母开头。
dummyTable
表对象,和输入的流数据表的 schema 一致,可以含有数据,亦可为空表。
keyColumn
字符串。若设置,则会以
dispatchType
指定的方式,基于该列分发数据。
keyColumn
列中的每个唯一值被视为一个 key。
outputTable
表对象,若
outputElapsedTime
= false,则
outputTable
的表结构和
dummyTable
相同;否则
outputTable
比
dummyTable
在最后多了一个 LONG
类型和一个 INT 类型的列,分别表示每一个 batch 的输出耗时(单位是微秒)及其输出时的时间戳(精度为纳秒)。
可以指定1~100个输出表。引擎会为每个表创建一个线程来接收分发到该表的数据。以 tuple 或嵌套 tuple
的方式指定多张表,例如:outputTable=[table1, table2, table3,
table4],表示将注入的数据平均分发到4张表中,每张表的数据不同;outputTable=[[table1_1, table1_2], [table2_1,
table2_2]],则会将数据拆分并复制。两份副本分别分发到各个子元素中对应的表中。具体来说,副本1的数据分发到 table1_1
table1_2,副本2的数据分发到 table2_1 和 table2_2。此时 table1_1 和 table2_1
除耗时和时间列外,其它列的数据相同;table1_2 和 table2_2 除耗时和时间列外,其它列的数据相同。
dispatchType
可选参数,字符串,可选值为:
"hash"(默认值):对
keyColumn
列进行哈希计算,并根据计算结果,将数据分发到各个输出表。由于哈希计算得到的分布不一定均匀,因此可能会出现数据分配不均的情况。
"uniform":按照
keyColumn
列,将数据均匀分发到各个输出表。
"saltedHash":对
keyColumn
列进行加盐处理,然后进行哈希计算。通过
加盐处理
,可以确保即使输入相同,也能产生独特的哈希值,从而避免碰撞。该选项在需要进行多层哈希分发的场景(例如分发引擎嵌套分发引擎,且都采用哈希计算进行数据分发)中更为适用。
提示:
建议使用默认的分发方式,即 "hash"。如果因为哈希分配不均匀而影响性能,则可以尝试使用
"uniform" 方式。
hashByBatch
可选参数, 布尔类型。该参数决定了是否将一个 batch 中的所有数据输出到同一个表中。默认为 false,表示对一个 batch
中的所有 key 分组后,按照
dispatchType
指定的方式分发数据。 仅当
dispatchType
='hash' 时,才可设置
hashByBatch
=true,此时,引擎随机取 batch 中一个 key 进行哈希计算,根据计算结果,将该 batch
中的所有数据输出到某一个表。
注:
当
hashByBatch
=false 时,可以保证相同
key 的数据被输出到同一张表,但是这种分组操作会增加一些开销。
outputLock
可选参数,布尔类型,默认值为
true,表示是否对输出表进行加锁以避免并发访问的冲突。若设置为
false,则不对输出表进行加锁,此时需要保证其他线程不会对输出表进行并发操作。一般情况下,建议使用默认值(true)。
当除了分发引擎以外,还有其他线程(比如其他引擎、流订阅等等)写入到输出表时,输出表需要加锁(因为内存表不允许并发写入),但加锁会增加开销。但在某些场景下,例如在输出线程数量大于等于输入线程数量,且能保证多个输入线程不会同时向一个输出线程写入数据的场景下,如果用户能保证只有一个线程写入输出表,则可以设置该参数为
false,即不对输出表加锁,以提高数据分发的性能。
queueDepth
可选参数,正整数,默认为4096(单位为行)。
mode
= “buffer” 时,表示每个输出线程的缓存表大小。
mode
= “queue” 时,表示每个输出线程的队列深度。
建议根据输入数据的记录数大小,适当调节该参数。如果输入数据量较小但该参数设置过大,则会导致内存空间的浪费;相反,如果输入数据量较大但该参数设置过小,可能会导致数据输出阻塞。
outputElapsedTime
可选参数,布尔类型,表示是否输出每个 batch 从注入引擎到分发输出的总耗时。默认为
false,不输出总耗时。若设置为 true,则会在输出表最后两列中输出耗时(单位为微秒)和数据输出的时间戳(单位为纳秒)。
mode
可选参数,字符串,可选值为:
"buffer"(默认值):引擎会为每个输出线程创建一个内存缓存表,并将待分发的数据复制到缓存表中。对于数据写入引擎过程中,可能会并发读写输入表,或频繁
append 数据到引擎且每次 append 的数据量较小的场景,建议使用该配置。
"queue":引擎为每一个输出线程维护一个数据队列,只将输入表的引用加入到分发队列,不复制数据。此配置要求写入数据的过程中不能对输入表进行并发读写,适合不频繁
append 数据到引擎且每次 append 的数据量较大的场景。
返回值
返回一个表对象。
例子
通过分发引擎,将流数据表中的数据分发到3个状态引擎,以进行因子计算,最终将结果输出到同一个输出表中。
//定义状态引擎的输入和输出表
share streamTable(1:0, `sym`price, [STRING,DOUBLE]) as tickStream
share streamTable(1000:0, `sym`factor1, [STRING,DOUBLE]) as resultStream
//定义将要使用的输出表。这里定义3个状态引擎。
for(i in 0..2){
rse = createReactiveStateEngine(name="reactiveDemo"+string(i), metrics =<cumavg(price)>, dummyTable=tickStream, outputTable=resultStream, keyColumn="sym")
}
//定义分发引擎
dispatchEngine=createStreamDispatchEngine(name="dispatchDemo", dummyTable=tickStream, keyColumn=`sym, outputTable=[getStreamEngine("reactiveDemo0"),getStreamEngine("reactiveDemo1"),getStreamEngine("reactiveDemo2")])
//订阅流数据表tickStream
subscribeTable(tableName=`tickStream, actionName="sub", handler=tableInsert{dispatchEngine}, msgAsTable = true)
//订阅的数据注入引擎
n=100000
symbols=take(("A" + string(1..10)),n)
prices=100+rand(1.0,n)
t=table(symbols as sym, prices as price)
tickStream.append!(t)
select count(*) from resultStream
100,000
//查看状态引擎状态
getStreamEngineStat().ReactiveStreamEngine
name
user
status
lastErrMsg
numGroups
numRows
numMetrics
metrics
snapshotDir
snapshotInterval
snapshotMsgId
snapshotTimestamp
garbageSize
memoryUsed
dispatchDemo
admin
OK
0
100,000
0
0
-1
0
0
FILE:references/doc_8690.md
# ne
**URL**: https://docs.dolphindb.cn/zh/funcs/n/ne.html
**来源**: DolphinDB 官方文档
---
ne
语法
ne(X, Y)
或
X!=Y
详情
如果
X
和
Y
都不是集合,逐个元素地比较
X
和
Y
,如果不相等则返回1。
如果
X
和
Y
都是集合,检查
X
和
Y
是不是同一个集合。是则返回0,不是则返回1。
参数
X
和
Y
可以是标量、数据对、向量、矩阵或集合。如果
X
和
Y
的其中一个是数据对、向量或矩阵,另一个必须是标量或具有相同长度或维度的数据对、向量或矩阵。
返回值
BOOL 类型标量/数据对/向量/矩阵。
例子
1 2 3 != 2;
// output
[1,0,1]
1 2 3 ne 0 2 4;
// output
[1,0,1]
1:2 != 1:6;
// output
0 : 1
m1=1..6$2:3;
m1;
#0
#1
#2
1
3
5
2
4
6
m1 != 4
#0
#1
#2
1
1
1
1
0
1
m2=6..1$2:3;
m2;
#0
#1
#2
6
4
2
5
3
1
m1 ne m2;
#0
#1
#2
1
1
1
1
1
1
集合操作:如果 X!=Y 则 X 和 Y 不是同一个集合。
x=set(4 6);
y=set(4 6 8);
x!=y;
// output
1
x!=x;
// output
0
FILE:references/doc_8691.md
# fxVolatilitySurfaceBuilder
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fxVolatilitySurfaceBuilder.html
**来源**: DolphinDB 官方文档
---
fxVolatilitySurfaceBuilder
语法
fxVolatilitySurfaceBuilder(referenceDate, currencyPair,
quoteNames, quoteTerms, quotes, spot, domesticCurve, foreignCurve,
[model='SVI'])
详情
构建外汇波动率曲面。
参数
referenceDate
DATE 类型标量,表示曲面的参考日期。
currencyPair
STRING 类型标量,表示货币对,形式为 "EURUSD","EUR.USD" 或
"EUR/USD"。支持的货币对包括:
EURUSD:欧元兑美元
USDCNY:美元兑人民币
EURCNY:欧元兑人民币
GBPCNY:英镑兑人民币
JPYCNY:日元兑人民币
HKDCNY:港币兑人民币
quoteNames
STRING 类型向量,须为 ["ATM", "D25_RR", "D25_BF", "D10_RR", "D10_BF"]
的一组排列,表示报价名称,其中:
"ATM":平值波动率
"D25_RR":Delta = 0.25 的风险逆转
"D25_BF":Delta = 0.25 的蝶式
"D10_RR":Delta = 0.1 的风险逆转
"D10_BF":Delta = 0.1 的蝶式
quoteTerms
DURATION 或 STRING 类型向量,表示市场报价的对应期限。当为 STRING 类型标量时,除可以是能转换成
DURATION 的字符串外,还可以为以下可选值:
"ON":Overnight,近端起息日为 T,远端起息日为 T+1
"TN":Tomorrow-next,近端起息日为 T+1,远端起息日为 T+2
"SN":Spot-next,近端起息日为 T+2,远端起息日为 T+3
quotes
DOUBLE 类型矩阵,形状为
(size(quoteTerms), size(quoteNames))
。第
i 行第 j 列表示 quoteNames[j] 在 quoteTerms[i] 上的市场报价。
spot
DOUBLE 类型标量,表示即期汇率。
domesticCurve
MKTDATA 类型标量,一个 IrYieldCurve 对象,表示本币的折现曲线。本币折现曲线所需包含的关键字段见
曲线字段要求
。
foreignCurve
MKTDATA 类型标量,一个 IrYieldCurve 对象,表示外币的折现曲线。外币折现曲线所需包含的关键字段见
曲线字段要求
。
model
可选参数,STRING 类型标量,指定构建波动率曲面所用模型。支持以下选项:
“SVI”:默认值,Stochastic Volatility Inspired 模型
“SABR”:Stochastic Alpha Beta Rho 模型
“Linear”:线性模型
“CubicSpline”:三次样条模型
返回值
MKTDATA 类型标量,一个 FxVolatilitySurface 对象。
例子
refDate = 2025.08.18
ccyPair = "USDCNY"
quoteTerms = ['1d', '1w', '2w', '3w', '1M', '2M', '3M', '6M', '9M', '1y', '18M', '2y', '3y']
quoteNames = ["ATM", "D25_RR", "D25_BF", "D10_RR", "D10_BF"]
quotes = [0.030000, -0.007500, 0.003500, -0.010000, 0.005500,
0.020833, -0.004500, 0.002000, -0.006000, 0.003800,
0.022000, -0.003500, 0.002000, -0.004500, 0.004100,
0.022350, -0.003500, 0.002000, -0.004500, 0.004150,
0.024178, -0.003000, 0.002200, -0.004750, 0.005500,
0.027484, -0.002650, 0.002220, -0.004000, 0.005650,
0.030479, -0.002500, 0.002400, -0.003500, 0.005750,
0.035752, -0.000500, 0.002750, 0.000000, 0.006950,
0.038108, 0.001000, 0.002800, 0.003000, 0.007550,
0.039492, 0.002250, 0.002950, 0.005000, 0.007550,
0.040500, 0.004000, 0.003100, 0.007000, 0.007850,
0.041750, 0.005250, 0.003350, 0.008000, 0.008400,
0.044750, 0.006250, 0.003400, 0.009000, 0.008550]
quotes = reshape(quotes, size(quoteNames):size(quoteTerms)).transpose()
spot = 7.1627
curveDates = [2025.08.21,
2025.08.27,
2025.09.03,
2025.09.10,
2025.09.22,
2025.10.20,
2025.11.20,
2026.02.24,
2026.05.20,
2026.08.20,
2027.02.22,
2027.08.20,
2028.08.21]
domesticCurveInfo = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": refDate,
"currency": "CNY",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": curveDates,
"values":[1.5113,
1.5402,
1.5660,
1.5574,
1.5556,
1.5655,
1.5703,
1.5934,
1.6040,
1.6020,
1.5928,
1.5842,
1.6068]/100
}
foreignCurveInfo = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"referenceDate": refDate,
"currency": "USD",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"frequency": "Annual",
"dates": curveDates,
"values":[4.3345,
4.3801,
4.3119,
4.3065,
4.2922,
4.2196,
4.1599,
4.0443,
4.0244,
3.9698,
3.7740,
3.6289,
3.5003]/100
}
domesticCurve = parseMktData(domesticCurveInfo)
foreignCurve = parseMktData(foreignCurveInfo)
surf = fxVolatilitySurfaceBuilder(refDate, ccyPair, quoteNames, quoteTerms, quotes, spot, domesticCurve, foreignCurve)
surfDict = extractMktData(surf)
print(surfDict)
相关函数:
extractMktData
,
parseMktData
曲线字段要求
字段名
类型
描述
是否必填
mktDataType
STRING
固定填 "Curve"
是
referenceDate
DATE
参考日期
是
version
INT
版本号,默认值 0
否
curveType
STRING
固定填 "IrYieldCurve"
是
dayCountConvention
STRING
曲线的日期计数惯例,可选值为:
"Actual360":实际天数除以360
"Actual365":实际天数除以365(不区分闰年)
"ActualActualISMA":实际天数/实际天数(ISMA规则)
"ActualActualISDA":实际天数/实际天数(ISDA规则)
是
interpMethod
STRING
内插方法,可选值为:
"Linear":线性插值
"CubicSpline":三次样条插值
"CubicHermiteSpline":三次埃尔米特样条插值
是
extrapMethod
STRING
外插方法,可选值为:
"Flat":平插
"Linear":线性插值
是
dates
DATE 向量
数据点的日期
是
values
DOUBLE 向量
数据点的值,与
dates
中的元素一一对应
是
curveName
STRING
曲线名称
否
currency
STRING
货币,可选值为"CNY", "USD", "EUR", "GBP", "JPY", "HKD"
是
compounding
STRING
复利类型,可选值为:
"Simple":单利
"Compounded":离散复利
"Continuous":连续复利
是
settlement
DATE
结算日,如果指定了结算日,则后续期限间隔的计算都将从
settlement
开始,而不是
referenceDate
否
frequency
INTEGRAL或 STRING
计息频率,可选值为:
-1 或 "NoFrequency":无效计息频率
0 或 "Once":到期一次还本付息
1 或 "Annual":每年付息一次
2 或 "Semiannual":每半年付息一次
3 或 "EveryFourthMonth":每四个月付息一次
4 或 "Quarterly":每季度付息一次
6 或 "BiMonthly":每两月付息一次
12 或 "Monthly":每月付息一次
13 或 "EveryFourthWeek":每四周付息一次
26 或 "BiWeekly":每两周付息一次
52 或 "Weekly":每周付息一次
365 或 "Daily":每日付息一次
999 或 "Other":其他计息频率
否
curveModel
STRING
曲线构建模型,目前仅支持 "Bootstrap"。
否
curveParams
DICT
模型的参数。
否
FILE:references/doc_870.md
# wcovar
**URL**: https://docs.dolphindb.cn/zh/funcs/w/wcovar.html
**来源**: DolphinDB 官方文档
---
wcovar
语法
wcovar(X, Y, W)
详情
返回
X
和
Y
的加权协方差。
参数
X
,
Y
和
W
是相同长度的数值型向量。
W
表示权重。它不能包含 NULL 值。
返回值
一个数值型标量。
例子
x=7 4 5 8 9 3 3 5 2 6 12 1 0 -5 32
y=1.1 7 8 9 9 5 4 8.6 2 1 -9 -3 5 8 13
wt=iterate(1,0.9,x.size())
wcovar(x,y,wt);
// output
4.201899
FILE:references/doc_8702.md
# daysInMonth
**URL**: https://docs.dolphindb.cn/zh/funcs/d/daysInMonth.html
**来源**: DolphinDB 官方文档
---
daysInMonth
语法
daysInMonth(X)
详情
返回
X
所在月份的天数。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
返回值
整数类型的标量或向量。
例子
daysInMonth(2012.06.12T12:30:00);
// output
30
daysInMonth([2012.02.01,2013.12.05]);
// output
[29,31]
FILE:references/doc_8703.md
# getUserListOfAllClusters
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getUserListOfAllClusters.html
**来源**: DolphinDB 官方文档
---
getUserListOfAllClusters
语法
getUserListOfAllClusters()
详情
查询多集群管理系统中所有集群的用户信息。只能由管理员在 MoM(Master of Master,管理集群)上执行该函数。
参数
无
返回值
一个字典(dictionary),其中:
key:集群名称。
value:该集群下的用户名称列表。
例子
getUserListOfAllClusters()
/* Output:
masterOfMaster->["user1","user2","admin"]
MoMSender->["admin","user2"]
*/
FILE:references/doc_8706.md
# 参数配置
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/cfg/para_cfg.html
**来源**: DolphinDB 官方文档
---
参数配置
DolphinDB 提供了一系列配置参数,方便用户根据实际情况进行合理的配置,以充分利用机器的硬件资源。
用户可通过
getConfig
函数,查看配置项的值。
注:
大部分参数数据节点和计算节点均可配置。由于计算节点不存储数据,因此无需配置磁盘相关的参数。
FILE:references/doc_8719.md
# ns
**URL**: https://docs.dolphindb.cn/zh/funcs/n/ns.html
**来源**: DolphinDB 官方文档
---
ns
语法
ns(maturity, yield, [method='nm'], [maxIter], [bounds], [initialGuess],
[seed])
详情
使用 NS 模型和指定的优化方法,拟合债券的收益率曲线。
参数
initialGuess
可选参数,数值向量,表示使函数最优化的参数的初始猜测。长度为 4,每个值分别表示 β
0
,
β
1
, β
2
, λ 的初始猜测,默认值为 [0.01, 0.01, 0.01, 1.0]。
其余参数详见
nss
。
返回值
返回一个字典,详见
nss
。
例子
传入指定的模型名称与参数,使用 bfgs
优化方法,拟合债券的收益率曲线。
maturity = [1,2,3,4,5,8,10,15,20,25,30]
yield = [0.0039,0.0061,NULL,NULL,0.0166,NULL,0.0258,NULL,NULL,0.0332,NULL]
model = ns(maturity, yield, method='bfgs');
model;
/*Output
modelName->ns
params->[0.037907009765789,-0.032345632006991,-0.048221596538028,1.48711064869407]
fminResult->xopt->[0.037907009765789,-0.032345632006991,-0.048221596538028,1.48711064869407]
fopt->7.682740281926149E-8
gopt->[0.000007050477817,-0.000001557728067,8.217072418048589E-7,-7.435919702203364E-8]
iterations->29
Hinv->#0 #1 #2 #3
------------------- --------------------- -------------------- ---------------------
1.046957491287936 -2.422265785994416 4.016547235964936 174.575362711334378
-2.422265785994413 20.767722224747515 -55.516118469836506 -1160.911707217612729
4.016547235964929 -55.516118469836506 162.441840532431541 3127.297987855009978
174.575362711334378 -1160.911707217613638 3127.297987855011797 72743.950482441126951
warnFlag->0
fcalls->165
gcalls->33
predict->nssPredict
*/
若更换优化算法为
nm,返回值将发生变化。
model = ns(maturity, yield, method='nm');
model;
/*Output
modelName->ns
modelName->ns
params->[-0.017297505365068,0.016544815374471,0.142682692134247,14.720778706012911]
fminResult->xopt->[-0.017297505365068,0.016544815374471,0.142682692134247,14.720778706012911]
fopt->0.000001443427918
iterations->446
fcalls->740
warnFlag->0
predict->nssPredict
*/
相关函数
:
nss
FILE:references/doc_8731.md
# saveModel
**URL**: https://docs.dolphindb.cn/zh/funcs/s/saveModel.html
**来源**: DolphinDB 官方文档
---
saveModel
语法
saveModel(model, location)
详情
把模型保存到本地文件中。返回表示保存结果的布尔值。
参数
model
需要保存的模型,一般是字典,由
randomForestClassifier
,
randomForestRegressor
等机器学习函数生成。
location
字符串,表示服务器端输出文件的绝对路径或相对路径。
返回值
返回表示保存结果的布尔值。
例子
x1 = rand(100.0, 100)
x2 = rand(100.0, 100)
b0 = 6
b1 = 1
b2 = -2
err = norm(0, 10, 100)
y = b0 + b1 * x1 + b2 * x2 + err
t = table(x1, x2, y)
model = randomForestRegressor(sqlDS(<select * from t>), `y, `x1`x2)
saveModel(model, "/home/DolphinDB/Data/regressionModel.txt");
FILE:references/doc_8734.md
# ungroup
**URL**: https://docs.dolphindb.cn/zh/funcs/u/ungroup.html
**来源**: DolphinDB 官方文档
---
ungroup
语法
ungroup(X)
详情
若表
X
的某列中包含数组向量或列式元组,则将其展开后整体做为一列;同时保留原同行中其余列的数据,按照对应数组向量或列式元组的元素数量进行复制填充;
若
X
的行数为0或不包含数组向量或列式元组,则直接返回
X
。
参数
X
必须是一个表对象。
返回值
一个表。
例子
x = array(INT[], 0).append!([1 2 3, 4 5, 6 7 8, 9 10])
t = table(1 2 3 4 as id, x as vol)
ungroup(t)
// output
id vol
-- -------
1 1
1 2
1 3
2 4
2 5
3 6
3 7
3 8
4 9
4 10
//创建一个表,其中 price 列为列式元组。
sym = `st1`st2`st3
price = [[3.1,2.5,2.8], [3.1,3.3], [3.2,2.9,3.3]]
price.setColumnarTuple!()
t = table(sym, price)
ungroup(t)
sym
price
st1
[3.1000,2.5000,2.8000]
st2
[3.1000,3.3000]
st3
[3.2000,2.9000,3.3000]
ungroup(t)
sym
price
st1
3.1
st1
2.5
st1
2.8
st2
3.1
st2
3.3
st3
3.2
st3
2.9
st3
3.3
sym = `st1`st2`st2`st1`st3`st1`st3`st2`st3
volume = 106 115 121 90 130 150 145 123 155;
t = table(sym, volume);
t;
t1 = select toArray(volume) as volume_all from t group by sym;
t1;
sym
volume_all
st1
[106,90,150]
st2
[115,121,123]
st3
[130,145,155]
ungroup(t1)
sym
volume_all
st1
106
st1
90
st1
150
st2
115
st2
121
st2
123
st3
130
st3
145
st3
155
FILE:references/doc_8739.md
# setOLAPCacheEngineSize
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setOLAPCacheEngineSize.html
**来源**: DolphinDB 官方文档
---
setOLAPCacheEngineSize
语法
setOLAPCacheEngineSize(memSize)
别名:
setCacheEngineMemSize
详情
在线修改 Cache Engine 的容量。集群环境下,该命令只能由管理员在数据节点上执行。执行前需要确保开启了 Cache
Engine (配置参数
OLAPCacheEngineSize
)。仅 OLAP 引擎支持该命令。
注:
此命令修改的配置值在集群重启后将失效。若需要配置值永久生效,请更改配置文件中的
OLAPCacheEngineSize
。
参数
memSize
一个数值型标量,且必须大于0且小于
maxMemSize
* 0.75。单位:GB。
场景
Cache Engine 开启后,写入数据时,系统会先把数据写入缓存,当缓存中的数据量达到
OLAPCacheEngineSize
的30%时,才会写入磁盘。若该配置项设置过小,大批量数据写入时,Cache Engine 可能很快被占满,从而导致写入卡住。此时,通过该命令在线修改 Cache
Engine 的容量,来保证写入继续进行。
相关函数:
可以使用
getOLAPCacheEngineSize
获取 Cache Engine 的实时状态,确认 Cache Engine
是否在线修改成功。
FILE:references/doc_8740.md
# createCatalog
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createCatalog.html
**来源**: DolphinDB 官方文档
---
createCatalog
语法
createCatalog(catalog)
详情
创建一个 catalog。
参数
catalog
字符串标量,表示 catalog 的名称。
返回值
无。
例子
createCatalog("catalog1")
FILE:references/doc_8747.md
# eqFloat
**URL**: https://docs.dolphindb.cn/zh/funcs/e/eqFloat.html
**来源**: DolphinDB 官方文档
---
eqFloat
语法
eqFloat(X, Y, [precision=9])
详情
以给定(小数点后位数)精度,逐个元素比较
X
==
Y
。
参数
X
和
Y
可以是数值类型标量、向量或矩阵。如果
X
与
Y
其中一个是向量或矩阵,另一个必须是标量或具有相同长度或维度的向量或矩阵。
precision
是一个非负整数,表示对 FLOAT 或 DOUBLE 类型,比较精度为小数点后几位。
返回值
返回布尔类型,数据形式取决于
X
/
Y
。
例子
eqFloat(0.1234567891, 0.123456789);
// output
true
eqFloat(0.123456788, 0.123456789);
// output
false
eqFloat(0.123456788 0.123456789 0.1234567891, 0.123456789);
// output
[false,true,true]
FILE:references/doc_8753.md
# easyTLDataImport 通联历史数据自动化导入功能模块
**URL**: https://docs.dolphindb.cn/zh/modules/easyTLDataImport/easytl_data_import.html
**来源**: DolphinDB 官方文档
---
easyTLDataImport 通联历史数据自动化导入功能模块
在部署完 DolphinDB 后,需要将历史数据批量导入数据库,再进行数据查询、计算和分析等操作。为便于用户快速导入通联历史 Level-2 行情数据,DolphinDB 开发了 DolphinDBModules::easyTLDataImport 模块(简称 easyTLDataImport 模块),主要用于通联历史 Level-2 行情数据的自动化导入。
沪深 Level-2 快照行情
沪深逐笔委托
沪深逐笔成交
1. 模块版本说明
自 2.00.10 版本开始,DolphinDB 安装包的 server/modules 目录下已预装 easyTLDataImport 模块(模块版本 1.0)。
由于 1.0 版本的 easyTLDataImport 模块存在以下问题:
无法适配上交所从 2023.11.27 启用的逐笔合并数据文件(对应通联的 mdl_4_24_0.csv 文件)。
内存使用较高,至少需要 64 GB 以上内存才能执行导入任务。
对于导入任务的进度以及每天的任务执行结果无法监控。
模块结构不清晰,二次开发难度较大。
因此,开发了 2.0 版本的 easyTLDataImport 模块。对原来的模块结构进行了调整,对导入流程进行了优化。
自 2.00.15 和 3.00.3 版本开始,DolphinDB 安装包的 server/modules 目录下预装 easyTLDataImport 模块(模块版本 2.0)。
若需要安装 1.0 版本,也可以从 9.1 的附录章节下载对应的模块包。解压后,覆盖节点所在服务器上 [home]/modules 路径下的对应文件夹,从而对模块进行升级。([home] 目录可以通过 getHomeDir 函数查看。)
本文将对 easyTLDataImport 模块(模块版本 2.0)进行详细介绍。
2. 历史数据文件结构
在使用本教程功能模块时,用户需要自行解压通联数据,并确保在主目录下创建了以日期命名的文件夹("yyyyMMdd" 的日期格式)。每个日期目录下包含该日期的 .csv 文件。
例如,主目录是 level2,则文件结构可以设置如下:
|—— level2
| |—— 20211201
| | |—— xxx.csv
| | |—— …
| |—— 20211202
| | |—— xxx.csv
| | |—— …
| |—— …
数据也可以按年组织,则文件结构如下
|—— level2
| |—— 2021
| | |—— 20211201
| | | |—— xxx.csv
| | | |—— …
| | |—— …
| |—— 2022
| | |—— 20221201
| | | |—— xxx.csv
| | | |—— …
| | |—— …
| |—— …
数据也可以按年组织,则文件结构如下
|—— level2
| |—— 2021
| | |—— 20211201
| | | |—— xxx.csv
| | | |—— …
| | |—— …
| |—— 2022
| | |—— 20221201
| | | |—— xxx.csv
| | | |—— …
| | |—— …
| |—— …
注意
:日期这一层目录之前的文件结构和日期目录下的文件结构都没有要求。
3. 模块介绍
easyTLDataImportPro 模块主要包含主函数(loadTLData.dos)、数据表结构 (tbSchema)、分布式库表创建 (createDbAndTb) 和数据导入 (loadData) 四个部分。
3.1 主函数: autoLoadTongLianData
语法
autoLoadTongLianData(fileDir, dataSource,
dbName="dfs://TL_Level2", tableName=NULL, market="ALL",
startDate=NULL, endDate=NULL, parallel=1, initialDB=false, initialTB=false,
isDataDuplicated=true, isConcatTime=true, isNeedOrderQueue=true)
详情
将
fileDir
路径下从
startDate
到
endDate
日期的通联数据导入指定的分布式表里。
参数
fileDir
指定的存放通联 .csv 文件的文件目录。该目录下必须包含 “yyyyMMdd” 格式的日期文件夹。
dataSource
数据源。目前支持的参数值如下:
"TLAll": 目前支持的所有通联数据,包括快照行情、逐笔成交和逐笔委托。
"TLSnapshot": 通联的快照行情数据。
"TLEntrust": 通联的逐笔委托数据。
"TLTrade": 通联的逐笔成交数据。
"TLTradeEntrust": 通联的逐笔数据,包括逐笔成交和逐笔委托。
dbName
导入的数据库名。支持字符串和字典两种格式,默认值是 "dfs://TL_Level2"。
当参数是字典类型时,其 key 是一个字符串标量,表示数据源,目前支持 "TLSnapshot", "TLEntrust", "TLTrade";其 value 是一个字符串标量,表示数据源对应的导入库名。
当参数是字符串标量时,表示 "TLSnapshot", "TLEntrust", "TLTrade" 三种数据类型的数据都会写入同一个数据库。
tableName
导入的分布式表名。支持空值、字符串标量和字典三种格式,默认值是 NULL。
当参数值为 NULL 时,表示使用默认的分布式表名。"TLSnapshot" 数据对应的表名为 "snapshot";"TLEntrust" 数据对应的表名为 "entrust";"TLTrade" 数据对应的表名为 "trade"。
当参数是字典类型时,其 key 是一个字符串标量,表示数据源,目前支持 "TLSnapshot", "TLEntrust", "TLTrade";其 value 是一个字符串标量,表示数据源对应的分布式表名。
只有
dataSource
属于 "TLSnapshot", "TLEntrust", "TLTrade" 之一时,参数可以是字符串标量,表示对应数据源需要存入的分布式表名。
market
交易所。目前支持的参数值如下:
"ALL": 表示将沪深数据合并存储,会将所有数据全部导入一个分布式表,其表名为
tableName 。
"SZ": 表示将深交所数据单独存储,会将深交所数据单独导入一个分布式表,其表名为
tableName
+
market
(比如 "snapshotSZ")。
"SH": 表示将上交所数据单独存储,会将上交所数据单独导入一个分布式表,其表名为
tableName
+
market
(比如 "snapshotSH")。
startDate
空值或形如 "yyyyMMdd" 的字符串标量,表示导入数据的起始日期。
当参数值为 NULL 时,不会对起始日期做判断。
当参数是形如 "yyyyMMdd" 的字符串标量时,会导入大于等于该日期的通联数据。
endDate
空值或形如 "yyyyMMdd" 的字符串标量,表示导入数据的结束日期。
当参数值为 NULL 时,不会对结束日期做判断。
当参数是形如 "yyyyMMdd" 的字符串标量时,会导入小于等于该日期的通联数据。
parallel
后台任务的并行度。按日期拆分导入任务,
parallel
控制后台任务的个数。
initialDB
布尔值,表示是否需要初始化数据库。如果已经存在名为
dbName
的数据库,当
initialDB
=true 时,会删除原来的数据库并重新创建;否则会保留原来的数据库。
initialTB
布尔值,表示是否需要初始化分布式表。如果在 dbName 数据库下已经存在名为 tbName 的表,当
initialTB
=true 时,会删除原来的表并重新创建;否则会保留原来的分布式表。
isDataDuplicated
布尔值,表示是否需要对数据进行去重。
"TLSnapshot" 对应的快照数据的去重字段:"TradeDate", "TradeTime", "SecurityID", "ImageStatus" 。
"TLEntrust" 对应的逐笔委托数据的去重字段:"TradeDate", "SecurityID", "ChannelNo", "ApplSeqNum"。
"TLTrade" 对应的逐笔成交数据的去重字段:"TradeDate", "SecurityID", "ChannelNo", "ApplSeqNum"。
isConcatTime
布尔值,表示是否需要将日期列和时间列合并为一列。
当参数值为 true 时,会用类型为 TIMESTAMP 的时间列 TradeTime 来存储数据时间。
当参数值为 false 时,会用类型为 DATE 的日期列 TradeDate 和类型为 TIME 的时间列 TradeTime 存储数据时间。
isNeedOrderQueue
布尔值,表示导入快照数据时,是否需要合并最优报价 50 档委托队列的数据。
3.2 数据表结构
tbSchema 文件夹下定义了所有数据表的表结构。
csvSchema 文件夹下的文件用于指定 DolphinDB 读取 .csv 文件时的数据格式。
dfsSchema 文件夹下的文件用于指定 DolphinDB 数据存入数据库的数据格式。
用户可以通过指定
market
参数选择将沪深两个交易所的数据分开单独存储还是合并存储。当
market="ALL"
时,会将沪深数据存储到同一张表中,表中的字段是两个交易所数据字段的并集,并新增 Market 字段用于标识数据来自哪个交易所。
用户可以通过指定
isConcatTime
参数选择是否将数据的日期列和时间列合并为一列。
上交所和深交所两个交易所数据的结构不同,且不同时期同一个交易所的数据结构也不同。因此,我们根据《沪深 L2 高频行情文件说明》整理了两个交易所不同时期的数据结构,最终确定了存入数据库的表结构。具体表结构可以查看 9.3 章节。
3.3 分布式库表创建
createDbAndTb 文件夹下定义了分布式库表创建脚本。
createDB.dos 用于创建存储通联数据的数据库。
createTB.dos 用于创建存储通联数据的分布式表。
基于客户的实践经验,确定了如下的分区方案:
沪深是否分开存储
日期列和时间列是否合并
分区方案
分区列
排序列
market="SH" or market="SZ"
isConcatTime =true
时间维度按天 VALUE 分区 + 证券代码维度 HASH 25 分区
"TradeTime", "SecurityID"
"SecurityID", "TradeTime"
market="SH" or market="SZ"
isConcatTime =false
时间维度按天 VALUE 分区 + 证券代码维度 HASH 25 分区
"TradeDate", "SecurityID"
"SecurityID", "TradeTime"
market="ALL"
isConcatTime =true
时间维度按天 VALUE 分区 + 证券代码维度 HASH 50 分区
"TradeTime", "SecurityID"
"Market","SecurityID", "TradeTime"
market="ALL"
isConcatTime =false
时间维度按天 VALUE 分区 + 证券代码维度 HASH 50 分区
"TradeDate", "SecurityID"
"Market","SecurityID", "TradeTime"
3.4 数据导入
loadData 文件夹下定义了数据转换和导入的规则。
loadOneDayData 文件夹下的文件用于指定对一天的通联数据的处理和导入规则。
loadOneDaySnapshot.dos:指定通联提供的快照行情数据的处理和导入规则。
会用
textChunkDS
函数将文件划分为 512 MB 大小的数据源,再通过
mr
函数写入到数据库中。
当
isNeedOrderQueue=true
时,会读取对应的最优报价 50 档委托队列的数据文件,用左连接的方式将其关联到快照行情数据中(关联列:"SecurityID", "TradeTime", "ImageStatus");当 *isNeedOrderQueue=false *时,会直接将对应的列置空。
当
isDataDuplicated=true
时,会通过
upsert!
函数写入数据,写入时根据 "TradeDate", "TradeTime", "SecurityID", "ImageStatus" 字段进行去重;当
isDataDuplicated=false
时,会通过
append!
函数写入数据,此时不会进行去重操作。
loadOneDayEntrust.dos:指定通联提供的逐笔委托数据的处理和导入规则。
会用
textChunkDS
函数将文件划分为 512 MB 大小的数据源,再通过
mr
函数写入到数据库中。
当
isDataDuplicated=true
时,会通过
upsert!
函数写入数据,写入时根据 "TradeDate", "SecurityID", "ChannelNo", "ApplSeqNum" 字段进行去重;当
isDataDuplicated=false
时,会通过
append!
函数写入数据,此时不会进行去重操作。
loadOneDayTrade.dos:指定通联提供的逐笔成交数据的处理和导入规则。
会用
textChunkDS
函数将文件划分为 512 MB 大小的数据源,再通过
mr
函数写入到数据库中。
当
isDataDuplicated=true
时,会通过
upsert!
函数写入数据,写入时根据 "TradeDate", "SecurityID", "ChannelNo", "ApplSeqNum" 字段进行去重;当
isDataDuplicated=false
时,会通过
append!
函数写入数据,此时不会进行去重操作。
loadOneDayTradeEntrust.dos:指定通联提供的上交所逐笔数据的处理和导入规则。(仅针对 mdl_4_24_0.csv 文件)
会用
textChunkDS
函数将文件划分为 512 MB 大小的数据源,再通过
mr
函数写入到数据库中。
会将 mdl_4_24_0.csv 文件中 Type="T" 的数据写入逐笔成交的分布式库里。
会将 mdl_4_24_0.csv 文件中 Type!="T" 的数据写入逐笔委托的分布式库里。(包含 Type="A" 新增委托、Type="D" 删除委托、Type="S" 产品状态的数据)
当
isDataDuplicated=true
时,会通过
upsert!
函数写入数据,写入时根据 "TradeDate", "SecurityID", "ChannelNo", "ApplSeqNum" 字段进行去重;当
isDataDuplicated=false
时,会通过
append!
函数写入数据,此时不会进行去重操作。
loadOneDayData.dos:用于指定导入一天对应交易所数据的导入规则。
loadData.dos:用于指定导入若干天的通联数据的导入规则。
4. 使用示例
第一步
:用户按照第 2 章文件结构中的要求解压并准备好数据。
假设数据放在 /hdd/hdd1/data/TLData/ 目录下,文件结构如下图:
第二步
:将模块同步到 DolphinDB 的
server/modules
的目录下。
VS Code 插件
:连接对应的节点 ——> 右键 DolphinDBModules 文件夹 ——> 选择 DolphinDB: Upload Module
GUI 客户端
:连接对应的节点 ——> 右键 DolphinDBModules 文件夹 ——> 选择 Synchronize module to server
第三步
:载入模块和导入数据方法如下:
// 加载模块
use DolphinDBModules::easyTLDataImport::loadTLData
// 配置参数
fileDir = "/hdd/hdd1/data/TLData/"
dataSource = "TLAll"
dbName = {
"TLSnapshot": "dfs://Level2",
"TLEntrust": "dfs://Level2",
"TLTrade": "dfs://Level2"
}
tableName = {
"TLSnapshot": "snapshot",
"TLEntrust": "entrust",
"TLTrade": "trade"
}
isDataDuplicated = false
isConcatTime = false
isNeedOrderQueue = true
// 调用函数,导入通联数据
jobid = autoLoadTongLianData(fileDir=fileDir, dataSource=dataSource, dbName=dbName, tableName=tableName,
isDataDuplicated=isDataDuplicated, isConcatTime=isConcatTime, isNeedOrderQueue=isNeedOrderQueue)
5.任务状态监控
(1)使用以下代码可以查询后台任务状态:
getTLJobStatus(jobid) // 函数名发生变更,1.0 版本中为 getJobStatus(jobid)
jobid
为
autoLoadTongLianData
函数的返回值,对应
getRecentJobs()
结果里的 jobDesc 字段值。
通过函数里的参数
parallel
可以设置提交的后台任务的个数。
通过配置文件里的参数
maxBatchJobWorker
可以设置处理后台任务的最大工作线程数。
返回的结果表里,startTime 不是空值表示任务已经开始执行;endTime 不是空值表示任务已经结束执行。
(2)使用以下代码可以查询后台任务导入进度:
getTLJobDetails(jobid) // 函数名发生变更,1.0 版本中为 getJobDetails(jobid)
jobid
为
autoLoadTongLianData
函数的返回值,对应
getRecentJobs()
结果里的 jobDesc 字段值。
通过输出的信息,可以了解哪些日期的任务已经执行完毕,哪些日期的任务正在执行。
(3)使用以下代码可以查询导入子任务状态:
共享内存表 TLDataImportStatusTable 记录了查询导入子任务的状态。
select * from TLDataImportStatusTable
模块会自动生成一个共享表,记录每个导入子任务的状态。
脚本拆分的最小导入任务是:一天一个数据源的导入任务。
如果 TLDataImportStatusTable 没有对应的日期对应数据源的任务信息,表示该任务还没有结束。只有等一个最小导入任务执行结束,才会在共享表里写入任务状态。
每次执行
autoLoadTongLianData
函数都会重置任务状态的共享表 TLDataImportStatusTable。
会出现的报错信息详情可以查看 9.2 章节。
6. 参数设置注意事项
fileDir
模块中对数据文件查找的方法如下:
(1)从
fileDir
目录下递归查找所有由 8 位数字组成的文件夹路径,即 "yyyyMMdd" 格式的日期文件夹。
(2)再将找到的所有日期和
startDate、endDate
进行字符串比较,从而达到导入数据日期筛选的目的。
(3)最后在每个日期文件夹下,递归查找所有以 csv 结尾的文件,从而获取该日期下的所有 .csv 文件的绝对路径。
因为第一步是查找所有 8 位数字组成的文件夹,所以参数
fileDir
指定的文件路径下必须有一层目录是以 "yyyyMMdd" 格式的日期命名。
所以如果用户想要导入一天的数据,需要通过
startDate、endDate
参数控制导入日期,而不是通过
fileDir
参数。
以图 4-1中的文件结构为例,假设只想导入 2021.12.01 这一天的数据,不是配置参数
fileDir
为 "/hdd/hdd1/data/TLData/20211201",而是配置
startDate
和
endDate
为 "20211201"。
isNeedOrderQueue
参数
isNeedOrderQueue
为 true 时,对最优报价 50 档委托队列的数据处理逻辑如下:
(1)先读取对应的委托队列的 .csv 文件到内存中。
(2)对委托队列的内存表进行格式处理,生成 OfferOrders 和 BidOrders 列分别存储卖方和买方的委托队列。
(3)用
textChunkDS
函数将快照数据的文件划分为 512 MB 大小的数据源。
(4)通过
mr
函数对快照数据源和全量的委托队列数据进行左连接,连接列为 "TradeTime", "SecurityID", "ImageStatus"。并将关联后的结果写入对应的数据库。
因为需要将委托队列的数据全量读到内存并进行关联操作,所以这种方式会使用更多的内存。
可用内存小于 64 GB 的不推荐设置参数
isNeedOrderQueue
为 true。
isDataDuplicated
测试发现,2016 年左右的数据中,快照数据和 50 档委托数据里都会有大量的重复数据(以"TradeTime", "SecurityID", "ImageStatus"为键值的重复数据)。
如果直接做左连接,会让结果表的数据量大幅增加,导致内存使用暴增,经常出现 OOM。
因此导入 2016 年左右的快照数据且需要合并最优报价的 50 档委托数据(即参数
isNeedOrderQueue
为 true)时,推荐设置参数
isDataDuplicated
为 true。
导入近期的快照行情数据时,推荐设置参数
isDataDuplicated
为 false。
parallel
当
parallel
参数设置很大时,可能会出现后台导入任务部分处于等待状态并未执行的情况,这可能与配置文件里的
maxBatchJobWorker
参数有关。函数里的
parallel
参数只能设置提交的后台任务的个数。同时执行的后台任务个数需要通过配置文件里的
maxBatchJobWorker
参数进行设置。
parallel
越大使用的内存会越多。在资源有限的情况下,
parallel
参数不宜设置的过大。参数
parallel
对导入性能以及资源使用的影响可以参考 7.2 章节。
7. 性能测试
7.1 测试环境
测试环境的软硬件配置如下表:
软硬件项
信息
OS(操作系统)
CentOS Linux 7 (Core)
内核
3.10.0-1160.el7.x86_64
CPU
Intel(R) Xeon(R) Gold 5220R CPU @ 2.20GHz
CPU 逻辑核数
8(使用 license 限制节点使用的核数)
内存
使用 dolphindb.cfg 里的配置项限制节点使用的内存大小
maxMemSize:64 GB
OLAPCacheEngineSize:2 GB
TSDBCacheEngineSize:2 GB
TSDBLevelFileIndexCacheSize:2 GB
磁盘
1 块 SSD,3.84 TB 固态硬盘 SATA 读取密集型 6 Gbps 512 2.5 英寸 Flex Bay AG 硬盘 1 DWPD
server 版本
2.00.14.3
7.2 性能结果
测试数据集
:2023.02.06~2023.02.10 共 5 天的数据。
以下只测试了通联数据沪深合并存储时的导入性能:
isDataDuplicated=false
数据源
数据量
原始 csv 大小(GB)
磁盘占用大小(GB)
压缩比
并发数
耗时(min)
最大内存占用(GB)
RPS(W/s)
吞吐量(MB/s)
snapshot+order queue
118,551,389
111.87
12.08
9.26
1
37.67
41
52
51
snapshot
118,551,389
69.99
9.73
7.20
1
22.50
7
88
53
snapshot
118,551,389
69.99
9.73
7.20
5
10.89
18
181
110
entrust
660,586,205
52.70
15.86
3.32
1
18.11
7
608
50
entrust
660,586,205
52.70
15.86
3.32
5
8.63
18
1276
104
trade
503,367,925
45.95
12.70
3.62
1
15.97
8
525
49
trade
503,367,925
45.95
12.70
3.62
5
7.39
20
1135
106
isDataDuplicated=true
数据源
数据量
原始 csv 大小(GB)
磁盘占用大小(GB)
压缩比
并发数
耗时(min)
最大内存占用(GB)
RPS(W/s)
吞吐量(MB/s)
snapshot+order queue
118,518,576
111.87
12.09
9.25
1
47.37
43
42
40
snapshot
118,518,576
69.99
9.15
7.65
1
22.91
14
86
52
snapshot
118,518,576
69.99
9.15
7.65
5
12.04
21
164
99
entrust
660,586,205
52.70
15.96
3.30
1
24.03
16
458
37
entrust
660,586,205
52.70
15.96
3.30
5
10.02
20
1099
90
trade
503,367,925
45.95
12.67
3.63
1
21.35
16
393
37
trade
503,367,925
45.95
12.67
3.63
5
9.23
21
909
85
8. 模块开发
目前,easyTLDataImport 模块只支持导入快照行情、逐笔成交和逐笔委托。如果想要基于 easyTLDataImport 模块导入更多数据源的数据,用户可以按照以下流程对模块进行二次开发。
模块结构可以查看第 3 章节。下面将增加 dataSource="TLIndex" 的数据源,使模块能导入上交所指数数据(Index.csv)。
(1)在 DolphinDBModules/easyTLDataImport/tbSchema/csvSchema 文件夹下新增一个 indexCsvSchema.dos 文件,用于指定目标导入数据的结构。
module DolphinDBModules::easyTLDataImport::tbSchema::csvSchema::indexCsvSchema
def indexCsvSchema(){
name = ["UpdateTime", "DataStatus", "SecurityID", "PreCloseIndex", "OpenIndex", "Turnover", "HighIndex",
"LowIndex", "LastIndex", "TradTime", "TradVolume", "CloseIndex", "LocalTime", "SeqNo"]
typeString = ["TIME", "INT", "SYMBOL", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE",
"DOUBLE", "DOUBLE", "TIME", "DOUBLE", "DOUBLE", "TIME", "LONG"]
return table(name, typeString)
}
(2)在 DolphinDBModules/easyTLDataImport/tbSchema/dfsSchema 文件夹下新增一个 indexSchema.dos 文件,用于指定分布式表的表结构。
module DolphinDBModules::easyTLDataImport::tbSchema::dfsSchema::indexSchema
def indexSchemaTb(isConcatTime){
if(isConcatTime==true){
name = ["TradeTime", "DataStatus", "SecurityID", "PreCloseIndex", "OpenIndex", "Turnover", "HighIndex",
"LowIndex", "LastIndex", "TradTime", "TradVolume", "CloseIndex", "LocalTime", "SeqNo"]
typeString = ["TIMESTAMP", "INT", "SYMBOL", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE",
"DOUBLE", "DOUBLE", "TIME", "DOUBLE", "DOUBLE", "TIME", "LONG"]
}else{
name = ["TradeDate", "TradeTime", "DataStatus", "SecurityID", "PreCloseIndex", "OpenIndex", "Turnover", "HighIndex",
"LowIndex", "LastIndex", "TradTime", "TradVolume", "CloseIndex", "LocalTime", "SeqNo"]
typeString = ["DATE", "TIME", "INT", "SYMBOL", "DOUBLE", "DOUBLE", "DOUBLE", "DOUBLE",
"DOUBLE", "DOUBLE", "TIME", "DOUBLE", "DOUBLE", "TIME", "LONG"]
}
return table(1:0, name, typeString)
}
(3)在 DolphinDBModules/easyTLDataImport/createDbAndTb/createDB.dos 的
createDb
函数里增加创建数据库的语句。
def createDb(dbName, dataSource, merge){
if(dataSource in ["TLSnapshot", "TLTrade", "TLEntrust"]){
// ... ...
}else if(dataSource=="TLIndex"){ // 新增 TLIndex 的建库语句
db = database(dbName, VALUE, 2021.01.01..2021.01.03)
}
}
(4)在 DolphinDBModules/easyTLDataImport/createDbAndTb/createTB.dos 的
createTb
函数里增加创建分布式表的语句。
use DolphinDBModules::easyTLDataImport::tbSchema::dfsSchema::indexSchema // 新增
def createTb(dbName, tbName, dataSource, market, isConcatTime){
db = database(dbName)
// Handle different data types for the table
if(dataSource=="TLSnapshot"){
// ... ...
}else if(dataSource=="TLEntrust"){
// ... ...
}else if(dataSource=="TLTrade"){
// ... ...
}else if(dataSource=="TLIndex"){ // 新增 TLIndex 的建表语句
t = indexSchemaTb(isConcatTime)
partitionColumns=iif(isConcatTime, `TradeTime, `TradeDate)
db.createPartitionedTable(table=t, tableName=tbName, partitionColumns=partitionColumns)
}
}
(5)在 DolphinDBModules/easyTLDataImport/loadData/loadOneDayData 文件夹下新增一个 loadOneDayIndex.dos 文件,它是包含数据转化规则的导入脚本。
module DolphinDBModules::easyTLDataImport::loadData::loadOneDayData::loadOneDayIndex
use DolphinDBModules::easyTLDataImport::tbSchema::csvSchema::indexCsvSchema
def appendIndex(day, t, dbName, tbName, isConcatTime){
// 转换数据格式
tmpData = select day as TradeDate, UpdateTime as TradeTime, DataStatus as DataStatus, SecurityID as SecurityID,PreCloseIndex as PreCloseIndex,
OpenIndex as OpenIndex, Turnover as Turnover,HighIndex as HighIndex,LowIndex as LowIndex,LastIndex as LastIndex,
TradTime as TradTime,TradVolume as TradVolume,CloseIndex as CloseIndex,LocalTime as LocalTime,SeqNo as SeqNo
from t
if(isConcatTime==true){
tmpData.replaceColumn!(`TradeTime, concatDateTime(tmpData["TradeDate"], tmpData["TradeTime"]))
tmpData.dropColumns!(`TradeDate)
}
// 写入数据库
loadTable(dbName, tbName).append!(tmpData)
}
def loadOneDayIndexSH(csvFiles, day, dbName, tbName, isConcatTime){
csvNames = "Index.csv"
csvPath = csvFiles[endsWith(csvFiles, csvNames)][0]
schemaTB = indexCsvSchema()
try{
ds = textChunkDS(filename=csvPath, chunkSize=512, schema=schemaTB)
mr(ds, appendIndex{day, , dbName, tbName, isConcatTime}, parallel=false)
}catch(ex){
errorMessage = dict(`message`code, [string(ex[0])+":"+string(ex[1]), "error"])
return errorMessage
}
return true
}
(6)在 DolphinDBModules/easyTLDataImport/loadData/loadOneDayData.dos 的
loadOneDayDataSH
函数里增加指数数据的导入规则。
use DolphinDBModules::easyTLDataImport::loadData::loadOneDayData::loadOneDayIndex // 新增
def loadOneDayDataSH(csvFilesSH, day, dbNames, tbNames, merge, dtypes, isConcatTime, isDataDuplicated, isNeedOrderQueue) {
csvFiles = csvFilesSH
statTable = objByName(`TLDataImportStatusTable) // 状态监控表
// 定义数据源和导入函数的映射关系
if("mdl_4_24_0.csv" in each(last, csvFiles.split("/"))){
loadFuncs = ["TLSnapshot", "TLTradeEntrust", "TLIndex"] // 新增 TLIndex 数据源
loadTypes = ["TLSnapshot", ["TLTrade", "TLEntrust"], "TLIndex"] // 新增 TLIndex 数据源
}else{
loadFuncs = ["TLSnapshot", "TLEntrust", "TLTrade", "TLIndex"] // 新增 TLIndex 数据源
loadTypes = ["TLSnapshot", "TLEntrust", "TLTrade", "TLIndex"] // 新增 TLIndex 数据源
}
// 串行导入多天的数据
for(i in 0:size(loadFuncs)){ // i = 0
if(any(loadTypes[i] in dtypes)){
dtype = loadTypes[i]
loadFunc = loadFuncs[i]
if(loadFunc=="TLTradeEntrust"){
dbName = dbNames
tbName = tbNames
}else{
dbName = dbNames[dtypes==dtype][0]
tbName = tbNames[dtypes==dtype][0]
}
// 导入开始时间
start_time = now()
// 使用新增的自定义函数导入指数数据
if(loadFunc=="TLSnapshot"){
// ... ...
}else if(loadFunc=="TLEntrust"){
// ... ...
}else if(loadFunc=="TLTrade"){
// ... ...
}else if(loadFunc=="TLTradeEntrust"){
// ... ...
}else if(loadFunc=="TLIndex"){ // 新增 TLIndex 数据源
errorMessage = loadOneDayIndexSH(csvFiles, day, dbName, tbName, isConcatTime)
}
// 导入结束时间
end_time = now()
// 向子任务状态表记录任务情况
try{
if(typestr(errorMessage)=="BOOL") errorMsg = ""
else errorMsg = toStdJson(errorMessage)
insert into statTable values(concat(dtype, ""), "SH", day, start_time, end_time, errorMsg)
}catch(ex){print(ex)}
}
}
}
(7)在 DolphinDBModules/easyTLDataImport/loadTLData.dos 的主函数里增加新的数据源类型 "TLIndex"。
def autoLoadTongLianData(fileDir, dataSource,
dbName="dfs://TL_Level2", tableName=NULL, market="ALL",
startDate=NULL, endDate=NULL, parallel=1, initialDB=false, initialTB=false,
isDataDuplicated=true, isConcatTime=true, isNeedOrderQueue=true){
// ... ... (无需修改)
// 对 dataSource 做参数校验时,增加数据源 TLIndex
if(!(string(dataSource) in ["TLAll", "TLTradeEntrust", "TLSnapshot", "TLEntrust", "TLTrade", "TLIndex"])){
errorMessage = dict(`message`code, ["数据源 [" + string(dataSource) + "] 暂时不支持", "error"])
return printLog(errorMessage)
}
// 对数据类型做处理时,根据需求增加数据源 TLIndex
if(dataSource=="TLTradeEntrust") dtypes = ["TLTrade", "TLEntrust"]
else if(dataSource=="TLAll") dtypes = ["TLSnapshot", "TLTrade", "TLEntrust", "TLIndex"]
else dtypes = [dataSource]
// ... ... (无需修改)
}
(8)重新同步模块后,即可导入上交所指数数据。(模块同步步骤查看第 4 章节)
// 加载模块
use DolphinDBModules::easyTLDataImport::loadTLData
// 配置参数
fileDir = "/hdd/hdd1/data/TLData/"
dataSource = "TLIndex"
dbName = {"TLIndex": "dfs://Level2Index"}
tableName = {"TLIndex": "index"}
isDataDuplicated = false
isConcatTime = false
// 调用函数,导入通联数据
jobid = autoLoadTongLianData(fileDir=fileDir, dataSource=dataSource, dbName=dbName, tableName=tableName,
isDataDuplicated=isDataDuplicated, isConcatTime=isConcatTime)
9. 附录
9.1 模块代码
easyTLDataImport 模块(版本2.0):
DolphinDBModulesV2.0
easyTLDataImport 模块(版本1.0):
DolphinDBModulesV1.0
9.2 异常处理
对于导入过程中可能出现的问题,会在日志中输出对应的报错提示信息。
情况
输出信息
参数
market
不属于 "ALL", "SZ", "SH"
{"code": "error","message": "市场 [market] 暂时不支持"}
参数
dataSource
不属于 "TLAll", "TLSnapshot", "TLEntrust", "TLTrade" , "TLTradeEntrust"
{"code": "error","message": "数据源 [dataSource] 暂时不支持"}
参数
dbName
不是字符串或者字典
{"code": "error","message": "数据库名 [dbName] 参数类型有误"}
参数
tableName
不是空值、字符串或者字典
{"code": "error","message": "分布式表名 [tableName] 参数类型有误"}
参数* startDate* 不是空值或者 "yyyyMMdd" 格式的日期字符串
{"code": "error","message": "开始日期 [startDate] 格式有误"}
参数* endDate* 不是空值或者"yyyyMMdd" 格式的日期字符串
{"code": "error","message": "开始日期 [endDate] 格式有误"}
参数* fileDir* 指定的路径下没有
startDate
到
endDate
内的 "yyyyMMdd" 格式的日期文件夹
{"code": "warning","message": "[fileDir] 路径下没有找到指定日期的文件夹,请确认文件路径"}
参数
initialDB
为 false,但是参数 *dbName *指定的数据库已经存在
{"code": "info","message": "[dbName] 数据库已经存在"}
参数
initialTB
为 false,但是参数 *tableName *指定的分布式表已经存在
{"code": "info","message": "数据库 [dbName] 已经存在表 [tableName]"}
数据导入时,文件夹下没有对应的 csv 文件
{"code": "error","message": "深交所 [day] 日期的 [csvNames] 的 csv 文件不全或者不存在"}{"code": "error","message": "上交所 [day] 日期的 [csvNames] 的 csv 文件不全或者不存在"}
实际 csv 文件的数据列数和 csvSchema 模块里面预设的表结构的列数不一致
{"code": "error","message": "[csvPath] 的数据格式有误,列数不匹配"}
其他错误【通过 try{}catch(ex){} 捕获异常】
{"code": "error","message": 输出报错信息 ex}
9.3 行情数据存储表结构
因为 .csv 文件里的时间为 TIME 类型,没有日期字段,所以处理数据格式时,会将上层文件夹名里的日期作为最终的日期字段。
9.3.1 Level-2 快照数据
深交所数据(总共 37 列)
字段含义
入库字段名
入库数据类型
2010.05 - 2016.05.06(MarketData.csv)
2016.05.07 - 2019.06.04(mdl_6_28_0.csv)
2019.06.05 - 至今(mdl_6_28_0.csv)
数据生成时间
TradeTime
TIMESTAMP
DataTimeStamp
UpdateTime
UpdateTime
行情类别
MDStreamID
SYMBOL
MDStreamID
MDStreamID
证券代码
SecurityID
SYMBOL
SecurityID
SecurityID
SecurityID
证券代码源
SecurityIDSource
SYMBOL
SecurityIDSource
SecurityIDSource
交易阶段
TradingPhaseCode
SYMBOL
EndOfDayMaker
TradingPhaseCode
TradingPhaseCode
昨日收盘价
PreCloPrice
DOUBLE
PreClosePx
PreCloPrice
PreCloPrice
成交笔数
NumTrades
LONG
NumTrades
TurnNum
TurnNum
成交总量
TotalVolumeTrade
LONG
TotalVolumeTrade
Volume
Volume
成交总金额
TotalValueTrade
DOUBLE
TotalValueTrade
Turnover
Turnover
最近价
LastPrice
DOUBLE
LastPx
LastPrice
LastPrice
开盘价
OpenPrice
DOUBLE
OpenPx
OpenPrice
OpenPrice
最高价
HighPrice
DOUBLE
HighPx
HighPrice
HighPrice
最低价
LowPrice
DOUBLE
LowPx
LowPrice
LowPrice
升跌1(最新价-昨收价)
DifPrice1
DOUBLE
DifPrice1
DifPrice1
升跌2(最新价-上一最新价)
DifPrice2
DOUBLE
DifPrice2
DifPrice2
股票市盈率1
PE1
DOUBLE
PERatio1
PE1
PE1
股票市盈率2
PE2
DOUBLE
PERatio2
PE2
PE2
基金T-1净值
PreCloseIOPV
DOUBLE
PreCloseIOPV
PreCloseIOPV
基金实时参考净值
IOPV
DOUBLE
IOPV
IOPV
委托买入总量
TotalBidQty
LONG
TotalBidQty
TotalBidQty
TotalBidQty
加权平均买入价格
WeightedAvgBidPx
DOUBLE
WeightedAvgBidPx
WeightedAvgBidPx
WeightedAvgBidPx
委托卖出总量
TotalOfferQty
LONG
TotalOfferQty
TotalOfferQty
TotalOfferQty
加权平均卖出价格
WeightedAvgOfferPx
DOUBLE
WeightedAvgOfferPx
WeightedAvgOfferPx
WeightedAvgOfferPx
涨停价
UpLimitPx
DOUBLE
HighLimitPrice
HighLimitPrice
跌停价
DownLimitPx
DOUBLE
LowLimitPrice
LowLimitPrice
持仓量
OpenInt
LONG
TotalLongPosition
OpenInt
OpenInt
权证溢价率
OptPremiumRatio
DOUBLE
OptPremiumRatio
OptPremiumRatio
卖价10档
OfferPrice
DOUBLE[]
AskPrice1..AskPrice10
AskPrice1..AskPrice10
AskPrice1..AskPrice10
买价10档
BidPrice
DOUBLE[]
BidPrice1..BidPrice10
BidPrice1..BidPrice10
BidPrice1..BidPrice10
卖量10档
OfferOrderQty
LONG[]
AskVolume1..AskVolume10
AskVolume1..AskVolume10
AskVolume1..AskVolume10
买量10档
BidOrderQty
LONG[]
BidVolume1..BidVolume10
BidVolume1..BidVolume10
BidVolume1..BidVolume10
申买10档委托笔数
BidNumOrders
INT[]
NumOrdersB1..NumOrdersB10
申卖10档委托笔数
OfferNumOrders
INT[]
NumOrdersS1..NumOrdersS10
入库时间
LocalTime
TIME
LocalTime
LocalTime
LocalTime
消息序列号
SeqNo
LONG
SeqNo
SeqNo
SeqNo
委托卖量50档
OfferOrders
LONG[]
OrderQty1..OrderQty50 (OrderQueue.csv)
OrderQty1..OrderQty50 (mdl_6_28_1.csv)
OrderQty1..OrderQty50 (mdl_6_28_1.csv)
委托买量50档
BidOrders
LONG[]
OrderQty1..OrderQty50 (OrderQueue.csv)
OrderQty1..OrderQty50 (mdl_6_28_2.csv)
OrderQty1..OrderQty50 (mdl_6_28_2.csv)
上交所数据(总共 52 列)
字段含义
入库字段名
入库数据类型
2019.06.05 以前(MarketData.csv)
2019.06.06 - 至今(MarketData.csv)
数据生成时间
TradeTime
TIMESTAMP
UpdateTime
UpdateTime
证券代码
SecurityID
SYMBOL
SecurityID
SecurityID
快照类型(全量/更新)
ImageStatus
INT
ImageStatus
ImageStatus
昨日收盘价
PreCloPrice
DOUBLE
PreCloPrice
PreCloPrice
开盘价
OpenPrice
DOUBLE
OpenPrice
OpenPrice
最高价
HighPrice
DOUBLE
HighPrice
HighPrice
最低价
LowPrice
DOUBLE
LowPrice
LowPrice
最近价
LastPrice
DOUBLE
LastPrice
LastPrice
今收盘价
ClosePrice
DOUBLE
ClosePrice
ClosePrice
交易阶段
TradingPhaseCode
SYMBOL
InstruStatus
InstruStatus
成交笔数
NumTrades
LONG
TradNumber
TradNumber
成交总量
TotalVolumeTrade
LONG
TradVolume
TradVolume
成交总金额
TotalValueTrade
DOUBLE
Turnover
Turnover
委托买入总量
TotalBidQty
LONG
TotalBidVol
TotalBidVol
加权平均买入价格
WeightedAvgBidPx
DOUBLE
WAvgBidPri
WAvgBidPri
债券加权平均委买价格
AltWAvgBidPri
DOUBLE
AltWAvgBidPri
AltWAvgBidPri
委托卖出总量
TotalOfferQty
LONG
TotalAskVol
TotalAskVol
加权平均卖出价格
WeightedAvgOfferPx
DOUBLE
WAvgAskPri
WAvgAskPri
债券加权平均委卖价格
AltWAvgAskPri
DOUBLE
AltWAvgAskPri
AltWAvgAskPri
ETF申购笔数
ETFBuyNumber
INT
ETFBuyNumber
ETFBuyNumber
ETF申购数量
ETFBuyAmount
LONG
EtfBuyVolume
EtfBuyVolume
ETF申购金额
ETFBuyMoney
DOUBLE
ETFBuyMoney
ETFBuyMoney
ETF赎回笔数
ETFSellNumber
INT
ETFSellNumber
ETFSellNumber
ETF赎回数量
ETFSellAmount
LONG
ETFSellVolume
ETFSellVolume
ETF赎回金额
ETFSellMoney
DOUBLE
ETFSellMoney
ETFSellMoney
债券到期收益率
YieldToMatu
DOUBLE
YieldToMatu
YieldToMatu
权证执行的总数量
TotWarExNum
DOUBLE
TotWarExNum
TotWarExNum
涨停价
UpLimitPx
DOUBLE
WarUpperPri
WarUpperPri
跌停价
DownLimitPx
DOUBLE
WarLowerPri
WarLowerPri
买入撤单笔数
WithdrawBuyNumber
INT
WiDBuyNum
WiDBuyNum
买入撤单数量
WithdrawBuyAmount
LONG
WiDBuyVol
WiDBuyVol
买入撤单金额
WithdrawBuyMoney
DOUBLE
WiDBuyMon
WiDBuyMon
卖出撤单笔数
WithdrawSellNumber
INT
WiDSellNum
WiDSellNum
卖出撤单数量
WithdrawSellAmount
LONG
WiDSellVol
WiDSellVol
卖出撤单金额
WithdrawSellMoney
DOUBLE
WiDSellMon
WiDSellMon
买入总笔数
TotalBidNumber
INT
TotBidNum
TotBidNum
卖出总笔数
TotalOfferNumber
INT
TotSellNum
TotSellNum
买入委托成交最大等待时间
MaxBidDur
INT
MaxBidDur
MaxBidDur
卖出委托最大等待时间
MaxSellDur
INT
MaxSellDur
MaxSellDur
买方委托价位数
BidNum
INT
BidNum
BidNum
卖方委托价位数
SellNum
INT
SellNum
SellNum
基金实时参考净值
IOPV
DOUBLE
IOPV
IOPV
卖价10档
OfferPrice
DOUBLE[]
AskPrice1..AskPrice10
AskPrice1..AskPrice10
买价10档
BidPrice
DOUBLE[]
BidPrice1..BidPrice10
BidPrice1..BidPrice10
卖量10档
OfferOrderQty
LONG[]
AskVolume1..AskVolume10
AskVolume1..AskVolume10
买量10档
BidOrderQty
LONG[]
BidVolume1..BidVolume10
BidVolume1..BidVolume10
申买10档委托笔数
BidNumOrders
INT[]
NumOrdersB1..NumOrdersB10
申卖10档委托笔数
OfferNumOrders
INT[]
NumOrdersS1..NumOrdersS10
入库时间
LocalTime
TIME
LocalTime
LocalTime
消息序列号
SeqNo
LONG
SeqNo
SeqNo
委托卖量50档
OfferOrders
LONG[]
OrderQty1..OrderQty50 (OrderQueue.csv)
OrderQty1..OrderQty50 (OrderQueue.csv)
委托买量50档
BidOrders
LONG[]
OrderQty1..OrderQty50 (OrderQueue.csv)
OrderQty1..OrderQty50 (OrderQueue.csv)
沪深数据合并(总共 62 列)
字段含义
入库字段名
入库数据类型
深交所
上交所
2010.05 - 2016.05.06(MarketData.csv)
2016.05.07 - 2019.06.04(mdl_6_28_0.csv)
2019.06.05 - 至今(mdl_6_28_0.csv)
2019.06.05 以前(MarketData.csv)
2019.06.06 - 至今(MarketData.csv)
交易所名称
Market
SYMBOL
"SZ"
"SZ"
"SZ"
"SH"
"SH"
数据生成时间
TradeTime
TIMESTAMP
DataTimeStamp
UpdateTime
UpdateTime
UpdateTime
UpdateTime
行情类别
MDStreamID
SYMBOL
MDStreamID
MDStreamID
证券代码
SecurityID
SYMBOL
SecurityID
SecurityID
SecurityID
SecurityID
SecurityID
证券代码源
SecurityIDSource
SYMBOL
SecurityIDSource
SecurityIDSource
交易阶段
TradingPhaseCode
SYMBOL
EndOfDayMaker
TradingPhaseCode
TradingPhaseCode
InstruStatus
InstruStatus
快照类型(全量/更新)
ImageStatus
INT
ImageStatus
ImageStatus
昨日收盘价
PreCloPrice
DOUBLE
PreClosePx
PreCloPrice
PreCloPrice
PreCloPrice
PreCloPrice
成交笔数
NumTrades
LONG
NumTrades
TurnNum
TurnNum
TradNumber
TradNumber
成交总量
TotalVolumeTrade
LONG
TotalVolumeTrade
Volume
Volume
TradVolume
TradVolume
成交总金额
TotalValueTrade
DOUBLE
TotalValueTrade
Turnover
Turnover
Turnover
Turnover
最近价
LastPrice
DOUBLE
LastPx
LastPrice
LastPrice
LastPrice
LastPrice
开盘价
OpenPrice
DOUBLE
OpenPx
OpenPrice
OpenPrice
OpenPrice
OpenPrice
最高价
HighPrice
DOUBLE
HighPx
HighPrice
HighPrice
HighPrice
HighPrice
最低价
LowPrice
DOUBLE
LowPx
LowPrice
LowPrice
LowPrice
LowPrice
今收盘价
ClosePrice
DOUBLE
ClosePrice
ClosePrice
升跌1(最新价-昨收价)
DifPrice1
DOUBLE
DifPrice1
DifPrice1
升跌2(最新价-上一最新价)
DifPrice2
DOUBLE
DifPrice2
DifPrice2
股票市盈率1
PE1
DOUBLE
PERatio1
PE1
PE1
股票市盈率2
PE2
DOUBLE
PERatio2
PE2
PE2
基金T-1净值
PreCloseIOPV
DOUBLE
PreCloseIOPV
PreCloseIOPV
基金实时参考净值
IOPV
DOUBLE
IOPV
IOPV
IOPV
IOPV
委托买入总量
TotalBidQty
LONG
TotalBidQty
TotalBidQty
TotalBidQty
TotalBidVol
TotalBidVol
加权平均买入价格
WeightedAvgBidPx
DOUBLE
WeightedAvgBidPx
WeightedAvgBidPx
WeightedAvgBidPx
WAvgBidPri
WAvgBidPri
债券加权平均委买价格
AltWAvgBidPri
DOUBLE
AltWAvgBidPri
AltWAvgBidPri
委托卖出总量
TotalOfferQty
LONG
TotalOfferQty
TotalOfferQty
TotalOfferQty
TotalAskVol
TotalAskVol
加权平均卖出价格
WeightedAvgOfferPx
DOUBLE
WeightedAvgOfferPx
WeightedAvgOfferPx
WeightedAvgOfferPx
WAvgAskPri
WAvgAskPri
债券加权平均委卖价格
AltWAvgAskPri
DOUBLE
AltWAvgAskPri
AltWAvgAskPri
涨停价
UpLimitPx
DOUBLE
HighLimitPrice
HighLimitPrice
WarUpperPri
WarUpperPri
跌停价
DownLimitPx
DOUBLE
LowLimitPrice
LowLimitPrice
WarLowerPri
WarLowerPri
持仓量
OpenInt
LONG
TotalLongPosition
OpenInt
OpenInt
权证溢价率
OptPremiumRatio
DOUBLE
OptPremiumRatio
OptPremiumRatio
卖价10档
OfferPrice
DOUBLE[]
AskPrice1..AskPrice10
AskPrice1..AskPrice10
AskPrice1..AskPrice10
AskPrice1..AskPrice10
AskPrice1..AskPrice10
买价10档
BidPrice
DOUBLE[]
BidPrice1..BidPrice10
BidPrice1..BidPrice10
BidPrice1..BidPrice10
BidPrice1..BidPrice10
BidPrice1..BidPrice10
卖量10档
OfferOrderQty
LONG[]
AskVolume1..AskVolume10
AskVolume1..AskVolume10
AskVolume1..AskVolume10
AskVolume1..AskVolume10
AskVolume1..AskVolume10
买量10档
BidOrderQty
LONG[]
BidVolume1..BidVolume10
BidVolume1..BidVolume10
BidVolume1..BidVolume10
BidVolume1..BidVolume10
BidVolume1..BidVolume10
申买10档委托笔数
BidNumOrders
INT[]
NumOrdersB1..NumOrdersB10
NumOrdersB1..NumOrdersB10
申卖10档委托笔数
OfferNumOrders
INT[]
NumOrdersS1..NumOrdersS10
NumOrdersS1..NumOrdersS10
ETF申购笔数
ETFBuyNumber
INT
ETFBuyNumber
ETFBuyNumber
ETF申购数量
ETFBuyAmount
LONG
EtfBuyVolume
EtfBuyVolume
ETF申购金额
ETFBuyMoney
DOUBLE
ETFBuyMoney
ETFBuyMoney
ETF赎回笔数
ETFSellNumber
INT
ETFSellNumber
ETFSellNumber
ETF赎回数量
ETFSellAmount
LONG
ETFSellVolume
ETFSellVolume
ETF赎回金额
ETFSellMoney
DOUBLE
ETFSellMoney
ETFSellMoney
债券到期收益率
YieldToMatu
DOUBLE
YieldToMatu
YieldToMatu
权证执行的总数量
TotWarExNum
DOUBLE
TotWarExNum
TotWarExNum
买入撤单笔数
WithdrawBuyNumber
INT
WiDBuyNum
WiDBuyNum
买入撤单数量
WithdrawBuyAmount
LONG
WiDBuyVol
WiDBuyVol
买入撤单金额
WithdrawBuyMoney
DOUBLE
WiDBuyMon
WiDBuyMon
卖出撤单笔数
WithdrawSellNumber
INT
WiDSellNum
WiDSellNum
卖出撤单数量
WithdrawSellAmount
LONG
WiDSellVol
WiDSellVol
卖出撤单金额
WithdrawSellMoney
DOUBLE
WiDSellMon
WiDSellMon
买入总笔数
TotalBidNumber
INT
TotBidNum
TotBidNum
卖出总笔数
TotalOfferNumber
INT
TotSellNum
TotSellNum
买入委托成交最大等待时间
MaxBidDur
INT
MaxBidDur
MaxBidDur
卖出委托最大等待时间
MaxSellDur
INT
MaxSellDur
MaxSellDur
买方委托价位数
BidNum
INT
BidNum
BidNum
卖方委托价位数
SellNum
INT
SellNum
SellNum
入库时间
LocalTime
TIME
LocalTime
LocalTime
LocalTime
LocalTime
LocalTime
消息序列号
SeqNo
LONG
SeqNo
SeqNo
SeqNo
SeqNo
SeqNo
委托卖量50档
OfferOrders
LONG[]
OrderQty1..OrderQty50 (OrderQueue.csv)
OrderQty1..OrderQty50 (mdl_6_28_1.csv)
OrderQty1..OrderQty50 (mdl_6_28_1.csv)
OrderQty1..OrderQty50 (OrderQueue.csv)
OrderQty1..OrderQty50 (OrderQueue.csv)
委托买量50档
BidOrders
LONG[]
OrderQty1..OrderQty50 (OrderQueue.csv)
OrderQty1..OrderQty50 (mdl_6_28_2.csv)
OrderQty1..OrderQty50 (mdl_6_28_2.csv)
OrderQty1..OrderQty50 (OrderQueue.csv)
OrderQty1..OrderQty50 (OrderQueue.csv)
9.3.2 逐笔委托数据
深交所数据(总共 12 列)
字段含义
入库字段名
入库数据类型
2012.10 - 2016.05.06(Order.csv)
2016.05.07 - 至今(mdl_6_33_0.csv)
频道代码
ChannelNo
INT
SetNo
ChannelNo
委托索引
ApplSeqNum
LONG
RecNo
ApplSeqNum
行情类别
MDStreamID
SYMBOL
MDStreamID
证券代码
SecurityID
SYMBOL
SecurityID
SecurityID
证券代码源
SecurityIDSource
SYMBOL
SecurityIDSource
委托价格
Price
DOUBLE
Price
Price
委托数量
OrderQty
LONG
OrderQty
OrderQty
买卖方向
Side
SYMBOL
FunctionCode
Side
报价时间
TradeTime
TIMESTAMP
OrderEntryTime
TransactTime
委托类别
OrderType
SYMBOL
OrderKind
OrdType
入库时间
LocalTime
TIME
LocalTime
LocalTime
接收序列号
SeqNo
LONG
SeqNo
SeqNo
上交所数据(总共 13 列)
字段含义
入库字段名
入库数据类型
2021.06.07 - 2023.12.04(mdl_4_19_0.csv)
2023.12.04 - 至今(mdl_4_24_0.csv)
数据状态
DataStatus
INT
DataStatus
委托序号
ApplSeqNum
LONG
OrderIndex
BizIndex
频道代码
ChannelNo
INT
OrderChannel
Channel
证券代码
SecurityID
SYMBOL
SecurityID
SecurityID
委托时间
TradeTime
TIMESTAMP
OrderTime
TickTime
订单类型
OrderType
SYMBOL
OrderType
Type
原始订单号
OrderNO
INT
OrderNO
BuyOrderNO / SellOrderNO
委托价格
Price
DOUBLE
OrderPrice
Price
委托数量
OrderQty
LONG
Balance
Qty
委托标识
Side
SYMBOL
OrderBSFlag
TickBSFlag
业务序列号
BizIndex
LONG
BizIndex
BizIndex
入库时间
LocalTime
TIME
LocalTime
LocalTime
接收序列号
SeqNo
LONG
SeqNo
SeqNo
沪深数据合并(总共 16 列)
字段含义
入库字段名
入库数据类型
深交所
上交所
2012.10 - 2016.05.06(Order.csv)
2016.05.07 - 至今(mdl_6_33_0.csv)
2021.06.07 - 至今(mdl_4_19_0.csv)
2023.12.04 - 至今(mdl_4_24_0.csv)
频道代码
ChannelNo
INT
SetNo
ChannelNo
OrderChannel
Channel
委托索引
ApplSeqNum
LONG
RecNo
ApplSeqNum
OrderIndex
BizIndex
行情类别
MDStreamID
SYMBOL
MDStreamID
证券代码
SecurityID
SYMBOL
SecurityID
SecurityID
SecurityID
SecurityID
证券代码源
SecurityIDSource
SYMBOL
SecurityIDSource
委托价格
Price
DOUBLE
Price
Price
OrderPrice
Price
委托数量
OrderQty
LONG
OrderQty
OrderQty
Balance
Qty
买卖方向
Side
SYMBOL
FunctionCode
Side
OrderBSFlag
TickBSFlag
报价时间
TradeTime
TIMESTAMP
OrderEntryTime
TransactTime
OrderTime
TickTime
委托类别
OrderType
SYMBOL
OrderKind
OrdType
OrderType
Type
入库时间
LocalTime
TIME
LocalTime
LocalTime
LocalTime
LocalTime
接收序列号
SeqNo
LONG
SeqNo
SeqNo
SeqNo
SeqNo
委托订单号
OrderNO
LONG
OrderNO
BuyOrderNO / SellOrderNO
数据状态
DataStatus
INT
DataStatus
业务序列号
BizIndex
LONG
BizIndex
BizIndex
交易所名称
Market
SYMBOL
"SZ"
"SZ"
"SH"
“SH”
9.3.3 逐笔成交数据
深交所数据(总共 14 列)
字段含义
入库字段名
入库数据类型
2010.05 - 2016.05.06(Trade.csv)
2016.05.07 - 至今(mdl_6_36_0.csv)
频道代码
ChannelNo
INT
SetNo
ChannelNo
消息记录号
ApplSeqNum
LONG
RecNo
ApplSeqNum
行情类别
MDStreamID
SYMBOL
MDStreamID
买方委托索引
BidApplSeqNum
LONG
BuyOrderRecNo
BidApplSeqNum
卖方委托索引
OfferApplSeqNum
LONG
SellOrderRecNo
OfferApplSeqNum
证券代码
SecurityID
SYMBOL
SecurityID
SecurityID
证券代码源
SecurityIDSource
SYMBOL
SecurityIDSource
委托价格
TradPrice
DOUBLE
Price
LastPx
委托数量
TradeQty
LONG
TradeQty
LastQty
成交代码
ExecType
SYMBOL
FunctionCode
ExecType
成交时间
TradeTime
TIMESTAMP
TradeTime
TransactTime
接收时间戳
LocalTime
TIME
LocalTime
LocalTime
接收序列号
SeqNo
LONG
SeqNo
SeqNo
成交类别
OrderKind
SYMBOL
OrderKind
上交所数据(总共 14 列)
字段含义
入库字段名
入库数据类型
2021.04.25 以前(Transaction.csv)
2021.04.26 - 2023.12.04(Transaction.csv)
2023.12.04 - 至今(mdl_4_24_0.csv)
数据状态
DataStatus
INT
DataStatus
DataStatus
消息记录号
ApplSeqNum
LONG
TradeIndex
TradeIndex
BizIndex
频道代码
ChannelNo
INT
TradeChan
TradeChan
Channel
证券代码
SecurityID
SYMBOL
SecurityID
SecurityID
SecurityID
成交时间
TradeTime
TIMESTAMP
TradTime
TradTime
TickTime
委托价格
TradPrice
DOUBLE
TradPrice
TradPrice
Price
委托数量
TradeQty
LONG
TradVolume
TradVolume
Qty
成交金额
TradeMoney
DOUBLE
TradeMoney
TradeMoney
TradeMoney
买方委托索引
BidApplSeqNum
LONG
TradeBuyNo
TradeBuyNo
BuyOrderNO
卖方委托索引
OfferApplSeqNum
LONG
TradeSellNo
TradeSellNo
SellOrderNO
内外盘标志
TradeBSFlag
SYMBOL
TradeBSFlag
TradeBSFlag
TickBSFlag
业务序列号
BizIndex
LONG
BizIndex
BizIndex
接收时间戳
LocalTime
TIME
LocalTime
LocalTime
LocalTime
接收序列号
SeqNo
LONG
SeqNo
SeqNo
SeqNo
沪深数据合并(总共 19 列)
字段含义
入库字段名
入库数据类型
深交所
上交所
2010.05 - 2016.05.06(Trade.csv)
2016.05.07 - 至今(mdl_6_36_0.csv)
2021.04.25 以前(Transaction.csv)
2021.04.26 - 2023.12.04(Transaction.csv)
2023.12.04 - 至今(mdl_4_24_0.csv)
频道代码
ChannelNo
INT
SetNo
ChannelNo
TradeChan
TradeChan
Channel
消息记录号
ApplSeqNum
LONG
RecNo
ApplSeqNum
TradeIndex
TradeIndex
BizIndex
行情类别
MDStreamID
SYMBOL
MDStreamID
买方委托索引
BidApplSeqNum
LONG
BuyOrderRecNo
BidApplSeqNum
TradeBuyNo
TradeBuyNo
BuyOrderNO
卖方委托索引
OfferApplSeqNum
LONG
SellOrderRecNo
OfferApplSeqNum
TradeSellNo
TradeSellNo
SellOrderNO
证券代码
SecurityID
SYMBOL
SecurityID
SecurityID
SecurityID
SecurityID
SecurityID
证券代码源
SecurityIDSource
SYMBOL
SecurityIDSource
委托价格
TradPrice
DOUBLE
Price
LastPx
TradPrice
TradPrice
Price
委托数量
TradeQty
LONG
TradeQty
LastQty
TradVolume
TradVolume
Qty
成交代码
ExecType
SYMBOL
FunctionCode
ExecType
成交时间
TradeTime
TIMESTAMP
TradeTime
TransactTime
TradTime
TradTime
TickTime
接收时间戳
LocalTime
TIME
LocalTime
LocalTime
LocalTime
LocalTime
LocalTime
接收序列号
SeqNo
LONG
SeqNo
SeqNo
SeqNo
SeqNo
SeqNo
数据状态
DataStatus
INT
DataStatus
DataStatus
成交金额
TradeMoney
DOUBLE
TradeMoney
TradeMoney
TradeMoney
内外盘标志
TradeBSFlag
SYMBOL
TradeBSFlag
TradeBSFlag
TickBSFlag
业务序列号
BizIndex
LONG
BizIndex
BizIndex
成交类别
OrderKind
SYMBOL
OrderKind
交易所名称
Market
SYMBOL
"SZ"
"SZ"
"SH"
"SH"
"SH"
FILE:references/doc_8757.md
# businessDay
**URL**: https://docs.dolphindb.cn/zh/funcs/b/businessDay.html
**来源**: DolphinDB 官方文档
---
businessDay
语法
businessDay(X, [offset], [n=1])
详情
如果
X
所在的日期是工作日(周一到周五),返回
X
的日期,反之返回
X
最近的工作日。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
个工作日更新一次。注意,只有当
n
>1时,
offset
才会生效。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP 类型的标量或向量。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
businessDay(2019.01.06);
// output
2019.01.04
businessDay(2019.01.04);
// output
2019.01.04
date=2019.01.06 + 1..10
businessDay = businessDay(date)
businessDay2 = businessDay(date,min(date),2)
table(date, businessDay, businessDay2);
date
businessDay
businessDay2
2019.01.07
2019.01.07
2019.01.07
2019.01.08
2019.01.08
2019.01.07
2019.01.09
2019.01.09
2019.01.09
2019.01.10
2019.01.10
2019.01.09
2019.01.11
2019.01.11
2019.01.11
2019.01.12
2019.01.11
2019.01.11
2019.01.13
2019.01.11
2019.01.11
2019.01.14
2019.01.14
2019.01.11
2019.01.15
2019.01.15
2019.01.15
2019.01.16
2019.01.16
2019.01.15
FILE:references/doc_876.md
# like/LIKE
**URL**: https://docs.dolphindb.cn/zh/progr/sql/like.html
**来源**: DolphinDB 官方文档
---
like/LIKE
like/LIKE 用于测试列中的值是否与指定模式匹配。其功能与
like
函数相同。
语法
match_expression [NOT] LIKE pattern
参数
match_expression
是一个列名或包含列名的表达式。
pattern
是要在 match_expression
中搜索的字符串(区分大小写)。包含以下通配符:
% 匹配零个或多个字符的任何字符串。
? 匹配任何单个字符。
用法
如果 match_expression 与 pattern 匹配,则 like 返回 true;否则,like 返回
false。
如果指定了 not,则取和 like 相反的结果。like 通常和 where
子句搭配使用,根据指定的字段模式过滤数据。例如:使用 like 来查找以 “A“ 开头、以 “b“ 结尾、或包含 “Ca“ 的数据。
LIKE 支持内存表和分布式表。
例子
t= table(`a1`a2`a3`b1`b2`b3`c1`c2 as id, 7 4 NULL 1 8 NULL 12 NULL as val)
select * from t where id like "a%"
//等价于 select * from t where like(id, "a%")
输出返回:
id
val
a1
7
a2
4
a3
select * from t where id not like "a%"
输出返回:
id
val
b1
1
b2
8
b3
c1
12
c2
FILE:references/doc_8763.md
# double
**URL**: https://docs.dolphindb.cn/zh/funcs/d/double.html
**来源**: DolphinDB 官方文档
---
double
语法
double(X)
详情
将输入的数据类型转换为 DOUBLE。
参数
X
可以是任意数据类型。
返回值
DOUBLE 类型,数据形式同
X
。
例子
x=double(); // 创建一个 DOUBLE 类型的变量,默认值为0。
x;
返回:null
typestr x;
返回:DOUBLE
typestr double(`10);
返回:DOUBLE
double(`10.9);
返回:10.9
double(now());
返回:1,708,616,927,949
注:
该例子首先使用
now
函数获得当前系统时间 2024.02.22
15:50:15.528,
double
函数将该时间转换为 1,708,616,927,949。
FILE:references/doc_8767.md
# loadVocab
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadVocab.html
**来源**: DolphinDB 官方文档
---
loadVocab
语法
loadVocab(filePath, vocabName)
详情
将指定路径下的词库加载到内存中,用于文本向量化处理。
参数
filePath
字符串标量,词库文件的路径,可以是相对路径或绝对路径。
vocabName
字符串标量,用于指定加载后词库的名称。
返回值
无。
例子
loadVocab("/home/data/vocab.txt", "vocab1")
相关函数:
unloadVocab
,
tokenizeBert
FILE:references/doc_8784.md
# crossStat
**URL**: https://docs.dolphindb.cn/zh/funcs/c/crossStat.html
**来源**: DolphinDB 官方文档
---
crossStat
语法
crossStat(X, Y)
详情
返回的结果是一个元组,结果中的每个元素依次为 count(X), sum(X), sum(Y), sum2(X), sum2(Y), sum(X*Y)
的计算结果。
参数
X
和
Y
是长度相同的数值型向量。
例子
x=1 NULL 2 3
y=4 3 NULL 2
crossStat(x,y);
// output
(2,4,6,10,20,10)
FILE:references/doc_8786.md
# ewmVar
**URL**: https://docs.dolphindb.cn/zh/funcs/e/ewmVar.html
**来源**: DolphinDB 官方文档
---
ewmVar
语法
ewmVar(X, [com], [span], [halfLife], [alpha], [minPeriods=0], [adjust=true],
[ignoreNA=false], [bias=false])
详情
返回
X
的指数加权移动方差。该函数必须指定
com
,
span
,
halfLife
,
alpha
四个参数中的一个。
参数
X
是一个数值型向量、矩阵或表。若
X
是表,只对其内数值型和布尔型的列进行计算。
com
是一个大于等于0的数值型标量,表示质心。
span
是一个大于等于1的数值型标量,表示跨度。
halfLife
是一个大于0的数值型标量,表示半衰期。
alpha
是一个(0,1]之间的浮点数,表示平滑系数。
minPeriods
是一个整数,表示窗口中的最小观察数。默认值为0。
adjust
是一个布尔值,表示是否除以开始阶段的衰减调整因子。默认值为 true。
ignoreNA
是一个布尔值,表示计算权重时是否忽略 NULL 值。默认值为 false。
bias
是一个布尔值,表示是否校正系统偏差。默认值为 false。
返回值
DOUBLE 类型,数据形式同
X
。
例子
a=[0,1,2,int(),4]
ewmVar(X=a,com=0.5);
// output
[,0.5,0.846154,0.846154,2.960165]
ewmVar(X=a,com=0.5,ignoreNA=true);
// output
[,0.5,0.846154,0.846154,2.819231]
n = 20
colNames = `time`sym`qty`price
colTypes = [TIME,SYMBOL,INT,DOUBLE]
t1 = table(n:0, colNames, colTypes)
insert into t1 values(09:30:00.001,`AAPL,100,56.5)
insert into t1 values(09:30:00.001,`AAPL,200,30.5)
insert into t1 values(09:30:00.001,`DELL,150,35.5)
insert into t1 values(09:30:00.001,`DELL,170,60.5)
insert into t1 values(09:30:00.001,`DELL,130,40.5)
b=[2,4,3,6,5]
ewmVar(X=t1,com=0.5);
time
sym
qty
price
09:30:00.001
AAPL
09:30:00.001
AAPL
4999.9999
337.9999
09:30:00.001
DELL
1538.4615
85.5384
09:30:00.001
DELL
541.5384
297.2807
09:30:00.001
DELL
754.3801
161.1487
相关函数:
ewmCorr
,
ewmCov
,
ewmMean
,
ewmStd
FILE:references/doc_8788.md
# sort!
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sort_.html
**来源**: DolphinDB 官方文档
---
sort!
语法
sort!(X, [ascending=true])
详情
对向量/矩阵进行排序。该函数会改变
X
的值。
参数
X
是一个向量/向量。
ascending
是一个布尔值,表示按升序排序还是按降序排序。默认值为 true(按升序排序)。
返回值
返回排序后的向量/矩阵。
例子
x=9 1 5;
sort!(x);
x;
// output
[1 5 9]
x.sort!(0);
x;
// output
[9,5,1]
FILE:references/doc_8801.md
# listMCPPrompts
**URL**: https://docs.dolphindb.cn/zh/funcs/l/listMCPPrompts.html
**来源**: DolphinDB 官方文档
---
listMCPPrompts
语法
listMCPPrompts()
详情
查看所有已定义的 MCP prompt 模板。
返回值
一张表,包含以下字段:
name:STRING 类型,prompt 模板的名称。
description:STRING 类型,prompt 模板的描述。
title:STRING 类型,prompt 模板的 title。
lastModifyTime:TIMESTAMP 类型,最后一次修改时间。
publishTime:TIMESTAMP 类型,发布时间。
例子
listMCPTools()
返回结果
name
message
description
title
lastModifyTime
publishTime
stock_summary
请总结 stock 在 startDate 至 endDate 的表现。
更新后的 Prompt 描述
股票走势总结
2025.08.24 17:17:29.091
FILE:references/doc_8803.md
# savePartition
**URL**: https://docs.dolphindb.cn/zh/funcs/s/savePartition.html
**来源**: DolphinDB 官方文档
---
savePartition
语法
savePartition(dbHandle, table, tableName,
[compression=true])
详情
把一张表保存为分布式数据库中的分区表。该命令必须要用户登录后才能执行。
在用
savePartition
保存之前,要用
createPartitionedTable
先创建空的分区表。
参数
dbHandle
是一个 DolphinDB 数据库句柄。
table
是将要保存的内存中的表。
tableName
是表示保存的分区表名称的字符串。
compression
是否压缩数据。默认的设置是 true。
例子
n=1000000
ID=rand(10, n)
value=rand(1.0, n)
t=table(ID, value);
db=database("dfs://rangedb_Trades", RANGE, 0 5 10)
Trades = db.createPartitionedTable(t, "Trades", "ID");
savePartition(db, t, `Trades)
Trades=loadTable(db, `Trades)
select count(value) from Trades;
// output
1,000,000
在上述例子中,数据库 db 有两个分区:[0,5)和[5,10)。表t被保存为一个分区表 Trades,它包含数据库 db
中的分区列。
我们可以在表 Trades 中追加另一个表:
n=500000
ID=rand(10, n)
value=rand(1.0, n)
t1=table(ID, value);
savePartition(db, t1, `Trades)
Trades=loadTable(db, `Trades)
select count(value) from Trades;
// output
1,500,000
FILE:references/doc_8809.md
# MyTT 指标库
**URL**: https://docs.dolphindb.cn/zh/modules/mytt/mytt.html
**来源**: DolphinDB 官方文档
---
MyTT 指标库
MyTT(My麦语言 T通达信 T同花顺)是一个简单易用的Python库,它将通达信、同花顺、文华麦语言等指标公式最简化移植到了Python中,实现的常见指标包括MACD、RSI、BOLL、ATR、KDJ、CCI、PSY等。MyTT全部基于numpy和pandas的函数进行封装。
为了方便用户在DolphinDB中计算这些技术指标,我们使用DolphinDB脚本实现了MyTT中包含的指标函数,并封装在DolphinDB mytt module中。 相比于Python中的MyTT库,DolphinDB mytt module中的计算函数不仅在批处理中性能有大幅提升,而且支持DolphinDB的流式增量计算引擎,可以直接用于实时流计算场景。
因为DolphinDB mytt module是基于DolphinDB V1.30.18和DolphinDB V2.00.6开发的,所以建议用户使用DolphinDB V1.30.18和DolphinDB V2.00.6及以上版本运行mytt指标库中的函数。在DolphinDB V1.30.19和DolphinDB V2.00.7支持了
BARSLAST
,
BARSLASTCOUNT
,
TOPRANGE
,
LOWRANGE
函数在流式增量计算引擎中的使用。在DolphinDB V1.30.21和DolphinDB V2.00.9中
CROSS
函数与DolphinDB内置变量名冲突,函数名修改为
CROSS_
。
匹配不同DolphinDB版本的mytt module:
V1.30.18, V2.00.6:
mytt.dos
V1.30.19, V2.00.7:
mytt.dos
V1.30.21, V2.00.9:
mytt.dos
1. 函数及参数的命名与用法规范
Python MyTT库中所有函数名大写,所有参数名大写,为适应使用者的使用习惯,DolphinDB mytt module中的函数名、参数、参数默认值均与MyTT保持一致。
为得到有意义的计算结果,mytt中函数的参数表示时间跨度的参数均要求至少是2。
由于LAST函数与DolphinDB中内置关键字冲突,mytt中将此函数命名为LAST_。
2. 环境配置
把附件的mytt.dos放在节点的[home]/modules目录下,[home]目录由系统配置参数home决定,可以通过
getHomeDir()
函数查看。初次使用模块文件时,[home]目录没有modules目录,手动创建modules目录,然后把mytt.dos模块文件放入该目录即可。
3. 使用范例
3.1. 脚本中直接使用指标函数
对一个向量直接使用mytt模块中的
EMA
函数(指数平滑法)进行计算:
//如果未设置自动加载mytt module,新会话需要手动加载一次mytt module
use mytt
close = 7.2 6.97 7.08 6.74 6.49 5.9 6.26 5.9 5.35 5.63
x = EMA(close, 5)
3.2. 在SQL语句中分组使用
用户经常需要在数据表中对多组数据在每组内进行计算。在以下例子中,先构造了一个包含2个股票的数据表:
use mytt
close = 7.2 6.97 7.08 6.74 6.49 5.9 6.26 5.9 5.35 5.63 3.81 3.935 4.04 3.74 3.7 3.33 3.64 3.31 2.69 2.72
date = (2020.03.02 + 0..4 join 7..11).take(20)
symbol = take(`F,10) join take(`GPRO,10)
t = table(symbol, date, close)
对其中每只股票使用mytt模块中的
EMA
函数进行计算:
update t set EMA = EMA(close, 5) context by symbol
3.3. 返回多个列的结果
某些函数会返回多个列的结果,例如函数
BIAS
(乘离率指标)。
直接使用的例子:
use mytt
close = 7.2 6.97 7.08 6.74 6.49 5.9 6.26 5.9 5.35 5.63
bias1, bias2, bias3 = BIAS(close, L1 = 2, L2 = 4, L3 = 6)
在SQL语句中使用的例子:
use mytt
close = 7.2 6.97 7.08 6.74 6.49 5.9 6.26 5.9 5.35 5.63 3.81 3.935 4.04 3.74 3.7 3.33 3.64 3.31 2.69 2.72
date = (2020.03.02 + 0..4 join 7..11).take(20)
symbol = take(`F,10) join take(`GPRO,10)
t = table(symbol, date, close)
select *, BIAS(close, L1 = 2, L2 = 4, L3 = 6) as `bias1`bias2`bias3 from t context by symbol
symbol date close bias1 bias2 bias3
------ ---------- ----- -------- -------- --------
F 2020.03.02 7.2
F 2020.03.03 6.97 -1.623
F 2020.03.04 7.08 0.783
F 2020.03.05 6.74 -2.46 -3.68
F 2020.03.06 6.49 -1.89 -4.839
F 2020.03.09 5.9 -4.762 -9.958 -12.333
F 2020.03.10 6.26 2.961 -1.378 -4.767
F 2020.03.11 5.9 -2.961 -3.87 -7.74
F 2020.03.12 5.35 -4.889 -8.586 -12.391
F 2020.03.13 5.63 2.55 -2.679 -4.925
GPRO 2020.03.02 3.81
GPRO 2020.03.03 3.935 1.614
GPRO 2020.03.04 4.04 1.317
GPRO 2020.03.05 3.74 -3.856 -3.639
GPRO 2020.03.06 3.7 -0.538 -3.99
GPRO 2020.03.09 3.33 -5.263 -10.061 -11.417
GPRO 2020.03.10 3.64 4.448 1.041 -2.435
GPRO 2020.03.11 3.31 -4.748 -5.293 -8.732
GPRO 2020.03.12 2.69 -10.333 -17.039 -20.921
GPRO 2020.03.13 2.72 0.555 -11.974 -15.833
4. 函数计算性能
本节将以
AVEDEV
函数为例做直接使用的性能对比,同时使用真实股票日频数据对所有函数进行分组使用性能对比。
4.1. 直接使用性能对比
在DolphinDB中:
use mytt
close = 7.2 6.97 7.08 6.74 6.49 5.9 6.26 5.9 5.35 5.63
close = take(close, 100000)
timer x = mytt::AVEDEV(close, 100)
对一个长度为100000的向量直接使用mytt模块中的
AVEDEV
函数,耗时为25ms。
与之对应的Python代码如下:
import
numpy
as
np
from
MyTT
import
*
import
time
close = np.array([
7.2
,
6.97
,
7.08
,
6.74
,
6.49
,
5.9
,
6.26
,
5.9
,
5.35
,
5.63
])
close = np.tile(close,
10000
)
start_time = time.time()
x = AVEDEV(close,
100
)
print
(
"--- %s seconds ---"
% (time.time() - start_time))
Python MyTT库中的
AVEDEV
函数耗时为25000ms,是DolphinDB mytt module中的
AVEDEV
函数的1000倍。测试数据量越大,性能差异越显著。
4.2. 分组使用性能对比
测试数据为上海证券交易所2020年,全年2919个证券(筛选交易日大于120)日频交易数据,总记录数为686,104条。
计算逻辑为按照股票代码进行分组计算各指标。
为了测试函数计算性能,DolphinDB和Python测试代码都是单线程运行。
DolphinDB测试代码
Python测试代码
下载测试数据
Python MyTT库
测试结果如下表所示:
序号
函数
Python(ms)
DolphinDB(ms)
运行时间比
1
RD
296
16
18
2
RET
243
13
18
3
ABS
229
15
15
4
LN
253
25
10
5
POW
311
30
10
6
SQRT
248
19
13
7
MAX
390
34
11
8
MIN
373
29
12
9
IF
282
21
13
10
REF
740
17
43
11
DIFF
662
22
30
12
STD
1,263
24
98
13
SUM
1,297
22
58
14
CONST
258
22
11
15
HHV
1,207
30
40
16
LLV
1,218
31
39
17
HHVBARS
2,952
41
72
18
LLVBARS
2,878
38
75
19
MA
1,220
24
50
20
EMA
1,171
26
45
21
SMA
1,199
28
42
22
WMA
4,322
20
216
23
DMA
1,123
27
41
24
AVEDEV
176,652
32
5,520
25
SLOPE
53,703
29
1,851
26
FORCAST
60,321
38
1,587
27
LAST
4,132
38
108
28
COUNT
1,249
20
62
29
EVERY
1,267
28
45
30
EXIST
1,490
22
67
31
BARSLAST
559
18
31
32
BARSLASTCOUNT
607
17
35
33
CROSS_
2,088
80
26
34
LONGCROSS
6,019
94
64
35
VALUEWHEN
968
27
35
36
BETWEEN
489
42
11
37
TOPRANGE
3,647
37
99
38
LOWRANGE
3,703
36
103
39
MACD
3,060
86
35
40
KDJ
4,705
144
32
41
RSI
2,539
103
24
42
WR
5,632
166
33
43
BIAS
5,318
135
39
44
BOLL
3,067
90
34
45
PSY
2,596
82
31
46
CCI
163,681
76
2,153
47
ATR
2,281
101
22
48
BBI
3,667
66
55
49
DMI
6,181
250
24
50
TAQ
2,292
64
35
51
KTN
3,170
164
19
52
TRIX
4,329
97
44
53
VR
2,732
117
23
54
EMV
4,437
132
33
55
DPO
2,455
59
41
56
BRAR
4,909
156
31
57
DFMA
2,890
52
55
58
MTM
1,659
43
38
59
MASS
4,602
99
46
60
ROC
2,000
63
31
61
EXPMA
1,900
49
38
62
OBV
1,790
94
19
63
MFI
3,488
158
22
64
ASI
4,173
316
13
从测试结果分析可知:
DolphinDB mytt module 中的函数计算性能远远超过 Python MyTT 库,最大的性能差距达到 5520 倍,普遍性能差距在 30 倍左右。
Python pandas测试核心代码
data.groupby(
"symbol"
).apply(
lambda
x: RSI(np.array(x.close), N =
24
))
DolphinDB测试核心代码
RSI = select symbol, tradedate, mytt::RSI(close, N=24) as `RSI from data context by symbol
5. 正确性验证
基于分组使用性能对比中的测试数据和代码,验证 DolphinDB mytt module 中函数的计算结果是否和 Python MyTT 库一致。
5.1. 浮点数精度问题
结果有差异的函数
CROSS_, LONGCROSS
原因
浮点数精度问题
对于CROSS_和LONGCROSS函数,在浮点数比较上,DolphinDB mytt module中的处理比Python MyTT库更加严谨。DolphinDB mytt module中首先会对浮点数round保留小数点后6位,然后再进行大小判断,而MyTT中并没有类似处理,因此对于相同大小的浮点数,Python的判别可能会出错,如下图所示:
5.2. NULL 值的处理
结果有差异的函数
SUM, DMI, EMV, MASS, MFI, ASI
原因
:
若输入向量开始包含空值,则从第一个非空位置开始计算。DolphinDB mytt module与Python MyTT库的计算规则一致。
对一个滚动/累积窗口长度为k的函数,每组最初的(k-1)个位置的结果均为空。DolphinDB mytt module与Python MyTT库的计算规则一致。
对一个滚动/累积窗口长度为k的函数,若一组中第一个非空值之后再有空值,Python MyTT库会对包含nan的窗口计算结果都处理为nan。DolphinDB mytt module会对窗口内非NULL的元素按计算规则计算,得到一个非NULL的计算结果。
DolphinDB 代码与结果:
close = [99.9, NULL, 84.69, 31.38, 60.9, 83.3, 97.26, 98.67]
mytt::SUM(close, 5);
[,,,,276.87, 260.27, 357.53, 371.51]
Python 代码与结果:
close = np.array([99.9, np.nan, 84.69, 31.38, 60.9, 83.3, 97.26, 98.67])
MyTT.SUM(close,5)
array([nan, nan, nan, nan, nan, nan, 357.53, 371.51])
以滑动窗口求和为例,close向量的第2个元素为空值,DolphinDB mytt module在计算第5个元素(60.9)时,回看过去5个窗口内的数据
[99.9, NULL, 84.69, 31.38, 60.9]
,对非NULL的元素求和,所以结果向量的第5个元素为276.87。
Python MyTT库会对包含nan的窗口计算结果都处理为nan,所以结果向量的前6个元素都为nan。
除上述因为浮点数精度问题和NULL值的处理问题导致计算结果存在差异外,其余函数计算结果的百分比误差均小于1e-10。
5.3. TOPRANGE、LOWRANGE 计算结果差异问题
TOPRANGE函数是统计S序列的某个元素是近多少周期内的最大值,
TOPRANGE(High)
表示创多少日新高。
mytt模块中的TOPRANGE函数与MyTT中的TOPRANGE函数在头部数据的计算中有差异,如下图所示,High序列
16.95, 17.31, 17.34
其TOPRANGE分别为创
0日新高,1日新高,2日新高
。MyTT在数据先下降再上升之后才开始统计创多少日新高,而mytt模块则从数据头部就开始统计创多少日新高。从而造成数据头部的计算结果会有差异。
LOWRANGE函数与上述情况相同。
6. 实时流计算案例
在DolphinDB V1.30.3 中发布的响应式状态引擎(
createReactiveStateEngine
)是许多金融场景流批统一计算中的重要构件,DolphinDB mytt module在开发时就对其做了适配,使得mytt模块中的大部分函数可以在响应式状态引擎中实现增量计算。
无需支持在响应式状态引擎的中使用的函数:
RET, CONST
。
所有mytt中的
技术指标函数
均支持增量计算。
示例代码如下:
def cleanEnvironment(){
try{ unsubscribeTable(tableName="snapshotStream",actionName="aggr1min") } catch(ex){ print(ex) }
try{ dropStreamEngine("myttReactiveStateEngine") } catch(ex){ print(ex) }
try{ dropStreamEngine("aggr1min") } catch(ex){ print(ex) }
try{ dropStreamTable(`snapshotStream) } catch(ex){ print(ex) }
try{ dropStreamTable(`outputTable) } catch(ex){ print(ex) }
undef all
}
cleanEnvironment()
go
//load modules
use mytt
//define stream table
name = `tradetime`SecurityID`high`low`open`close`vol
type = `TIMESTAMP`SYMBOL`DOUBLE`DOUBLE`DOUBLE`DOUBLE`INT
share streamTable(100:0, name, type) as snapshotStream
name = `SecurityID`tradetime`K`D`J`DIF`DEA`MACD`UPPER`MID`LOWER`ROC`MAROC
type = `SYMBOL`TIMESTAMP`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE`DOUBLE
share streamTable(1000000:0, name, type) as outputTable
//register stream computing engine
reactiveStateMetrics=<[
tradetime,
mytt::KDJ(close, high, low, N=9, M1=3, M2=3) as `K`D`J,
mytt::MACD(close, SHORT_=12, LONG_=26, M=9) as `DIF`DEA`MACD,
mytt::KTN(close, high, low, N=20, M=10) as `UPPER`MID`LOWER,
mytt::ROC(close, N=12, M=6) as `ROC`MAROC
]>
createReactiveStateEngine("myttReactiveStateEngine", metrics=reactiveStateMetrics, dummyTable=snapshotStream, outputTable=outputTable, keyColumn=`SecurityID, keepOrder=true)
createTimeSeriesEngine(name="aggr1min", windowSize=60000, step=60000, metrics=<[first(open),max(high),min(low),last(close),sum(vol)]>, dummyTable=snapshotStream, outputTable=getStreamEngine("myttReactiveStateEngine"), timeColumn=`tradetime, useWindowStartTime=true, keyColumn=`SecurityID)
subscribeTable(tableName="snapshotStream", actionName="aggr1min", offset=-1, handler=getStreamEngine("aggr1min"), msgAsTable=true, batchSize=2000, throttle=1, hash=0, reconnect=true)
7. DolphinDB mytt 指标列表
7.1. 核心工具函数
函数
语法
解释
RD
RN(N, D = 3)
四舍五入取3位小数
RET
RET(S, N = 1)
返回序列
倒数第N个值
,默认返回最后一个
ABS
ABS(S)
返回序列或数值S的绝对值
LN
LN(S)
求序列S底是e的自然对数
POW
POW(S, N)
求序列S的N次方
SQRT
SQRT(S)
求序列S的平方根
MAX
MAX(S1, S2)
配对比较两个序列,给出比较以后大的序列
MIN
MIN(S1, S2)
配对比较两个序列,给出比较以后小的序列
IF
IF(S, A, B)
序列布尔判断,if S == True return A else B
REF
REF(S, N = 1)
对序列整体下移动N个单位,返回平移后的序列,会产生NAN
DIFF
DIFF(S, N = 1)
序列S的前一个值减后一个值,序列头部会产生NAN
STD
STD(S, N)
求序列S的滚动N日标准差,返回滚动标准差序列
SUM
SUM(S, N)
对序列S求滚动N日总和
CONST
CONST(S)
返回序列S最后一个值组成常量序列
HHV
HHV(S, N)
求序列S的滚动N日最大值,返回滚动最大值序列
LLV
LLV(S, N)
求序列S的滚动N日最小值,返回滚动最小值序列
HHVBARS
HHVBARS(S, N)
求序列S的滚动N期内最高值到当前的天数, 返回距离天数序列
LLVBARS
LLVBARS(S, N)
求序列S的滚动N期内最低值到当前的天数, 返回距离天数序列
MA
MA(S, N)
求序列S的N日简单移动平均值,返回移动平均序列
EMA
EMA(S, N)
求序列S的指数移动平均,为了精度,S>4*N,EMA至少需要120周期alpha = 2/(span+1)
SMA
SMA(S, N, M = 1)
中国式的SMA,至少需要120周期才精确 (雪球180周期),alpha = 1/(1+N)
WMA
WMA(S, N)
求S序列S的N日加权移动平均,
Yn = (1*X1+2*X2+3*X3+...+n*Xn)/(1+2+3+...+n)
DMA
DMA(S, A)
求S的动态移动平均,A作平滑因子,必须 0 < A < 1
AVEDEV
AVEDEV(S, N)
求序列S的滚动平均绝对偏差
SLOPE
SLOPE(S, N)
求序列S的滚动N周期内的线性回归模型的斜率
FORCAST
FORCAST(S, N)
求序列S的滚动N周期内的线性回归模型的预测值
LAST_
LAST_(S, A, B)
BOOL型判断,从前A日到前B日一直满足BOOL条件,要求A > B & A > 0 & B >= 0
7.2. 应用层函数(通过核心工具函数实现)
函数
语法
解释
COUNT
COUNT(S, N)
序列S是BOOL型,求最滚动N天内满足BOOL为True的天数
EVERY
EVERY(S, N)
序列S是BOOL型,求最滚动N天内
全部
满足BOOL为True的天数
EXIST
EXIST(S, N)
序列S是BOOL型,判断最滚动N天内
是否存在
满足BOOL为True
BARSLAST
BARSLAST(S)
序列S是BOOL型,统计上一次条件成立到当前的周期
BARSLASTCOUNT
BARSLASTCOUNT(S)
序列S是BOOL型,统计连续满足条件的周期数
BARSSINCEN
BARSSINCEN(S, N)
序列S是BOOL型,统计滚动周期N内第一次满足条件到当前的周期数
CROSS_
CROSS_(S1, S2)
判断两个序列是否交叉的函数,判断向上金叉穿越 CROSS_(MA(C,5),MA(C,10)) ,判断向下死叉穿越 CROSS_(MA(C,10),MA(C,5))
LONGCROSS
LONGCROSS(S1, S2, N)
判断两个序列是否在个持一定周期后再交叉的函数,判断两个序列是否再个持N周期后再交叉,N = 1时等同于CROSS_(S1, S2)
VALUEWHEN
VALUEWHEN(S, X)
解决当S条件成立时,取X的当前值,否则取S的上个成立时对应的X值
BETWEEN
BETWEEN(S, A, B)
判断S序列是否介于A和B之间的函数,当S处于A和B之间时为真,包括 A<S<B 或 A>S>B
TOPRANGE
TOPRANGE(S)
统计S序列的某个元素是近多少周期内的最大值
LOWRANGE
LOWRANGE(S)
统计S序列的某个元素是近多少周期内的最小值
7.3. 技术指标函数(全部通过核心工具和应用函数实现)
函数
语法
解释
MACD
MACD(CLOSE, SHORT = 12, LONG = 26, M = 9)
平滑异同平均线
KDJ
KDJ(CLOSE, HIGH, LOW, N = 9, M1 = 3, M2 = 3)
KDJ指标
RSI
RSI(CLOSE, N = 24)
RSI指标,和通达信小数点2位相同
WR
WR(CLOSE, HIGH, LOW, N = 10, N1 = 6)
W&R 威廉指标
BIAS
BIAS(CLOSE, L1 = 6, L2 = 12, L3 = 24)
BIAS乖离率
BOLL
BOLL(CLOSE, N = 20, P = 2)
BOLL指标,布林带
PSY
PSY(CLOSE, N = 12, M = 6)
PSY指标,心理线
CCI
CCI(CLOSE, HIGH, LOW, N = 14)
CCI指标,顺势线
ATR
ATR(CLOSE, HIGH, LOW, N = 20)
真实波动N日平均值
BBI
BBI(CLOSE, M1 = 3, M2 = 6, M3 = 12, M4 = 20)
BBI多空指标
DMI
DMI(CLOSE, HIGH, LOW, M1 = 14, M2 = 6)
DMI动向指标
TAQ
TAQ(HIGH, LOW, N)
唐安奇通道(海龟)交易指标
KTN
KTN(CLOSE, HIGH, LOW, N = 20, M = 10)
肯特纳交易通道
TRIX
TRIX(CLOSE, M1 = 12, M2 = 20)
三重指数平滑平均线
VR
VR(CLOSE, VOL, M1 = 26)
VR容量比率
EMV
EMV(HIGH, LOW, VOL, N = 14, M = 9)
EMV简易波动指标
DPO
DPO(CLOSE, M1 = 20, M2 = 10, M3 = 6)
区间震荡线
BRAR
BRAR(OPEN, CLOSE, HIGH, LOW, M1 = 26)
BRAR-ARBR 情绪指标
DFMA
DFMA(CLOSE, N1 = 10, N2 = 50, M = 10)
DFMA平行线差指标
MTM
MTM(CLOSE, N = 12, M = 6)
MTM动量指标
MASS
MASS(HIGH, LOW, N1 = 9, N2 = 25, M = 6)
梅斯线
ROC
ROC(CLOSE, N = 12, M = 6)
变动率指标
EXPMA
EXPMA(CLOSE, N1 = 12, N2 = 50)
指数平均数指标
OBV
OBV(CLOSE, VOL)
能量潮指标
MFI
MFI(CLOSE, HIGH, LOW, VOL, N = 14)
MFI资金流量
ASI
ASI(OPEN, CLOSE, HIGH, LOW, M1 = 26, M2 = 10)
振动升降指标
8. 路线图(Road Map)
长期保持对Python MyTT包的同步更新。
9. 附件
V1.30.18, V2.00.6:
mytt.dos
V1.30.19, V2.00.7:
mytt.dos
DolphinDB测试代码
Python测试代码
下载测试数据
Python MyTT库
计算性能测试环境
CPU类型:Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz 3.60 GHz
逻辑CPU总数:8
内存:32GB
OS:Windows 10
FILE:references/doc_8823.md
# in
**URL**: https://docs.dolphindb.cn/zh/progr/sql/in.html
**来源**: DolphinDB 官方文档
---
in
in 谓词用在 where 子句中,可以指定一个或多个值。通过 in 可以简写多个 or 条件。
语法
select col(s)
from table
where col [not] in (value1, value2, ...)
或
select col(s)
from table
where col [not] in (subquery)
参数
col(s)
要选择的字段名称。可以为多个字段名称或 *(表示所有列)。
table
要查询的表名称。
col
要查询的字段名称。
value1, value2, ...
要查询的值,可以为多个值。
例子
t = table(`APPL`AMZN`IBM`IBM`APPL`AMZN as sym, 1.8 2.3 3.7 3.1 4.2 2.8 as price);
select * from t where sym in (`APPL, `AMZN)
// select * from t where sym=`APPL or sym=`AMZN
sym
price
APPL
1.8
AMZN
2.3
APPL
4.2
AMZN
2.8
t1=table(`APPL`AMZN`IBM`IBM`APPL`AMZN as sym, 200 500 300 350 240 580 as vol);
select * from t where sym in (select sym from t1 where sym=`IBM)
sym
price
IBM
3.7
IBM
3.1
FILE:references/doc_8842.md
# denseRank
**URL**: https://docs.dolphindb.cn/zh/funcs/d/denseRank.html
**来源**: DolphinDB 官方文档
---
denseRank
语法
denseRank(X, [ascending=true],[ignoreNA=true], [percent=false])
详情
若
X
是向量:
基于
ascending
指定的排序顺序,返回
X
中每个元素连续的排名。
如果
ignoreNA
= true,则 NULL 值不参与排序,结果中 NULL 值的排名为空。
若
X
是矩阵,在每列内进行上述计算,返回一个与
X
维度相同的矩阵。
若
X
是字典,则按字典的值进行排序,并返回各元素的排名。
注:
denseRank
和
rank
的区别在于,多个元素相等时,前者采用密集排名方式,而后者采用跳跃排名方式。
参数
X
是一个向量、矩阵或字典。
ascending
是一个布尔值,表示是否按升序排序。默认值是 true。
ignoreNA
是一个布尔值,表示是否忽略 NULL 值,默认值为 true。true 表示忽略 NULL 值,false 表示 NULL
作为最小值参与排名。
percent
是一个布尔值,表示是否以百分比形式显示返回的排名,默认值为 false。
例子
x=1 5 5 6 8 8 9
print denseRank(x)
// output
[0,1,1,2,3,3,4]
y=time(4 1 1 2)
print denseRank(y, ascending=false)
// output
[0,2,2,1]
m = matrix(1 2 2 NULL, 0 0 0 1, 0 0 NULL 2)
denseRank(m, ignoreNA=false)
#0
#1
#2
1
0
1
2
0
1
2
0
0
0
1
2
t=table(`A`A`B`C`B`B`A`C`C as id,[4,1,NULL,1,2,4,5,0,-1] as val)
select id,val, denseRank(val) from t context by id
id
val
denseRank_val
A
4
1
A
1
0
A
5
2
B
B
2
0
B
4
1
C
1
2
C
0
1
C
-1
0
denseRank(dict(`a`b`c`d, [4, 1, 1,2],true))
// output: [2,0,0,1]
相关函数:
rowDenseRank
FILE:references/doc_8844.md
# rowStdp
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowStdp.html
**来源**: DolphinDB 官方文档
---
rowStdp
语法
rowStdp(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行元素求总体标准差操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL])
rowStdp(m);
// output
[1.517307556898806,1.203698005684518,2.2]
t1=table(1..5 as x, 10..6 as y, take(3, 5) as z)
t2=table(5..1 as a, 6..10 as b, take(8, 5) as c);
rowStdp(t1);
// output
[3.858612300930075,3.091206165165235,2.357022603955159,1.699673171197595,1.247219128924648]
rowStdp(t1[`x], t2, 1 1 2 2 2);
// output
[2.785677655436824,2.727636339397171,2.638181191654584,2.966479394838265,3.42928563989645]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2)
select sym,rowStdp(price1,price2) as stdp from t;
sym
stdp
AAPL
62.815
MS
10.65
IBM
10.4
IBM
10.635
C
74.37
相关函数:
rowStd
,
std
FILE:references/doc_8852.md
# cumsum2
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumsum2.html
**来源**: DolphinDB 官方文档
---
cumsum2
语法
cumsum2(X)
参数说明和窗口计算规则请参考:
累计窗口系列(cum 系列)
详情
计算
X
元素的累计平方和。
返回值
DOUBLE 类型,其数据形式同
X
。
例子
x=[2,3,4];
cumsum2 x;
// output
[4,13,29]
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
16
5
41
14
77
相关函数:
sum2
FILE:references/doc_8855.md
# treasuryConversionFactor
**URL**: https://docs.dolphindb.cn/zh/funcs/t/treasuryconversionfactor.html
**来源**: DolphinDB 官方文档
---
treasuryConversionFactor
语法
treasuryConversionFactor(contractCoupon, deliverableCoupon,
monthsToNextCoupon, remainingPayments, frequency)
详情
本函数基于
中金所国债转换因子和应计利息计算公式
对转换因子进行估值计算。成功执行后将返回转换因子的估值。
参数
contractCoupon
数值型类型标量或向量,非负数,表示国债合约票面利率。
deliverableCoupon
数值型标量或向量,非负数,表示可交割国债的票面利率。
monthsToNextCoupon
整数类型标量或向量,非负数,表示交割月到下一付息月的月份数。
remainingPayments
整数类型标量或向量,非负数,表示剩余付息次数。
frequency
表示可交割国债每年的付息频率,支持两种输入类型:
INT 类型标量或向量,正数,表示可交割国债每年的付息次数。例如,
frequency
= 1 表示每年付息 1
次,即按年支付;
frequency
= 2 表示每年付息 2 次,即按半年期支付。
DURATION 标量或向量:表示可交割国债每隔多久进行一次付息。例如,
frequency
= duration(`3M),表示每隔 3
个月付息一次,即按季度支付。
可选值
含义
1 / 1y
表示每年付息1次
2 / 6M
表示每年付息2次 / 每6个月付息1次
3 / 4M
表示每年付息3次 / 每4个月付息1次
4 / 3M
表示每年付息4次 / 每3个月付息1次
6 / 2M
表示每年付息6次 / 每2个月付息1次
12 / 1M
表示每年付息12次 / 每月付息1次
13 / 4w
表示每年付息13次 / 每4周付息1次
26 / 2w
表示每年付息26次 / 每2周付息1次
52 / 1w
表示每年付息52次 / 每周付息1次
365 / 1d
表示每年付息365次 / 每天付息1次
注意:在调用此函数时,必须保证所有提供的向量参数长度相同。若参数向量长度不一致,函数将会报错。
返回值
DOUBLE 类型标量或向量。
例子
假设 5 年期国债合约票面利率为 3%,交割月到下一付息月的月份数为 2,剩余付息次数为 1,可交割国债的票面利率为 3.2%,付息频率为
4,该种情况下对转换因子进行估值计算。
treasuryConversionFactor(contractCoupon=0.03, deliverableCoupon=0.032, monthsToNextCoupon=2, remainingPayments=1, frequency=4)
// Output:1.000324624767048
FILE:references/doc_8857.md
# getActiveMaster
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getActiveMaster.html
**来源**: DolphinDB 官方文档
---
getActiveMaster
语法
getActiveMaster()
详情
对于普通集群,
getActiveMaster
函数返回控制节点的别名。
对于包含多个控制节点的集群,
getActiveMaster
函数返回 Leader
控制节点的别名。
注:
该函数只能在控制节点上执行。
参数
无
返回值
字符串标量。
例子
getActiveMaster();
// output
controller1
FILE:references/doc_8859.md
# cumPositiveStreak
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cumPositiveStreak.html
**来源**: DolphinDB 官方文档
---
cumPositiveStreak
语法
cumPositiveStreak(X)
参数说明和窗口计算规则请参考:
cumFunctions
详情
累计计算
X
中连续的正数之和的。
返回值
LONG/DOUBLE 类型,其数据形式同
X
。
例子
x=1 0 -1 1 2 2 2 1 0 -1 0 2;
cumPositiveStreak x;
// output
[1,0,0,1,3,5,7,8,0,0,0,2]
m=matrix(1 0 -1 1 2 2 2 1 0 -1 0 2, -1 -2 -1 0 1 3 6 7 0 -1 -2 0);
m;
#0
#1
1
-1
0
-2
-1
-1
1
0
2
1
2
3
2
6
1
7
0
0
-1
-1
0
-2
2
0
cumPositiveStreak(m);
#0
#1
1
0
0
0
0
0
1
0
3
1
5
4
7
10
8
17
0
0
0
0
0
0
2
0
FILE:references/doc_8862.md
# addRangePartitions
**URL**: https://docs.dolphindb.cn/zh/funcs/a/addRangePartitions.html
**来源**: DolphinDB 官方文档
---
addRangePartitions
语法
addRangePartitions(dbHandle, newRanges, [level=0],
[locations])
详情
给数据库增加新的分区。目标数据库必须是 RANGE 分区类型或 COMPO 分区类型并且至少其中一层分区为 RANGE
类型。注意,只能在最后一个现有数据分区后面添加分区,不能在第一个现有数据分区前面添加分区。
参数
dbHandle
是数据库句柄。
newRanges
是向量,表示新的分区。它必须按升序排序,并且第一个元素必须与数据库的原分区方案的最后一个元素相同。
level
是整数。当分区类型为 COMPO,并且每层分区为 RANGE 时,需要使用
level
参数指定 RANGE 分区所在的层。它是可选参数。默认值为0。
locations
是字符串标量或向量。如果目标数据库创建时,指定了
locations
参数,增加新的分区时可以使用
locations
参数指定新增分区的位置。它是可选参数。
返回值
返回的结果是一个整数,表示新增的分区数量。
例子
下面的例子是给分区类型为 COMPO 的数据库新增[101, 150), [150,200)和[200,250)分区,但无法新增
[50,100) 分区。
n=1000000
ID=rand(100, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t=table(date, ID, x);
dbDate = database(, VALUE, 2017.08.07..2017.08.11)
dbID=database(, RANGE, 0 50 101);
db = database("dfs://compoDB", COMPO, [dbDate,dbID]);
pt = db.createPartitionedTable(t, `pt, `date`ID)
pt.append!(t);
addRangePartitions(db,101 150 200 250,1)
// output
3
添加新的分区后,需要重新加载数据库。
db=database("dfs://compoDB")
pt=loadTable(db,"pt")
t1=table(rand(2017.08.07..2017.08.11,n) as date, rand(101..249,n) as ID, rand(10.0,n) as x)
pt.append!(t1);
select count(*) from loadTable("dfs://compoDB","pt");
// output
2000000
FILE:references/doc_8864.md
# irSingleCurrencyCurveBuilder
**URL**: https://docs.dolphindb.cn/zh/funcs/i/irSingleCurrencyCurveBuilder.html
**来源**: DolphinDB 官方文档
---
irSingleCurrencyCurveBuilder
语法
irSingleCurrencyCurveBuilder(referenceDate, currency,
instNames, instTypes, terms, quotes, dayCountConvention, [discountCurve],
[compounding='Continuous'], [frequency='Annual'], [curveName])
详情
构建单货币利率互换收益率曲线。目前仅支持 CNY_FR_007 和 CNY_SHIBOR_3M 两条曲线构建。
参数
referenceDate
DATE 类型标量,收益率曲线的参考日期。
currency
STRING 类型标量,表示曲线定义的货币,目前仅支持 "CNY"。
instNames
STRING 类型向量,表示金融工具名称。
instTypes
STRING 类型向量,表示金融工具类型。暂时仅支持 "Deposit" 和 "IrVanillaSwap"。
terms
DURATION 类型向量,表示合约剩余期限,例如 "1M"。
quotes
数值向量,表示构建曲线所需的市场报价。
dayCountConvention
STRING 类型标量,表示计息日数规则,可选值为:
"Actual360": 实际/360
"Actual365": 实际/365
"ActualActualISMA": 实际/实际,遵循 ISMA(International Securities Market
Association,国际证券市场协会)规则
"ActualActualISDA":实际/实际,遵循 ISDA(International Swaps and Derivatives
Association,国际掉期及衍生工具协会)规则。
discountCurve
可选参数,MKTDATA
类型对象(IrYieldCurve),表示贴现曲线。当构建目标曲线的市场工具在自身定价时需要外部贴现曲线,则通过该参数指定。若不传入,则默认不使用外部贴现曲线。曲线所需包含的关键字段见
曲线字段要求
。
compounding
可选参数,STRING 类型标量,表示利率复利方式。可选值为:
"Compounded":离散复利。
"Simple":单利。
"Continuous":默认值,连续复利。
frequency
可选参数,STRING 类型标量,表示计算贴现因子的频率。可选值为:
"NoFrequency":无计息频率
"Annual":默认值,每年付息一次
"Semiannual":每半年付息一次
"EveryFourthMonth":每四个月付息一次
"Quarterly":每季度付息一次
"BiMonthly":每两月付息一次
"Monthly":每月付息一次
"EveryFourthWeek":每四周付息一次
"BiWeekly":每两周付息一次
"Weekly":每周付息一次
"Daily":每日付息一次
"Other":其他计息频率
curveName
可选参数,STRING 类型标量,表示生成的曲线名称,默认为空。
返回值
MKTDATA 类型对象。
例子
例1. 构建一条以人民币计价、参考 FR007 浮动利率的利率互换曲线。
referenceDate = 2021.05.26
currency = "CNY"
terms = [7d, 1M, 3M, 6M, 9M, 1y, 2y, 3y, 4y, 5y, 7y, 10y]
instNames = take("CNY_FR_007", size(terms))
instNames[0] = "FR_007"
instTypes = take("IrVanillaSwap", size(terms))
instTypes[0] = "Deposit"
quotes = [2.3500, 2.3396, 2.3125, 2.3613, 2.4075, 2.4513, 2.5750, 2.6763, 2.7650, 2.8463, 2.9841, 3.1350]\100
dayCountConvention = "Actual365"
curve = irSingleCurrencyCurveBuilder(referenceDate, currency, instNames, instTypes, terms, quotes, dayCountConvention, curveName="CNY_FR_007")
curveDict = extractMktData(curve)
print(curveDict)
例2. 根据短期存款和利率互换市场报价,构建人民币利率互换收益率曲线。
referenceDate = 2021.05.26
currency = "CNY"
terms = [1w, 2w, 1M, 3M, 6M, 9M, 1y, 2y, 3y, 4y, 5y, 7y, 10y]
instNames = take("CNY_SHIBOR_3M", size(terms))
instNames[0] = "SHIBOR_1W"
instNames[1] = "SHIBOR_2W"
instNames[2] = "SHIBOR_1M"
instNames[3] = "SHIBOR_3M"
instTypes = take("IrVanillaSwap", size(terms))
instTypes[0] = "Deposit"
instTypes[1] = "Deposit"
instTypes[2] = "Deposit"
instTypes[3] = "Deposit"
quotes = [2.269,
2.311,
2.405,
2.479,
2.6013,
2.7038,
2.7725,
2.9625,
3.11,
3.24,
3.3513,
3.5313,
3.7125]/100
dayCountConvention = "Actual365"
curve = irSingleCurrencyCurveBuilder(referenceDate, currency, instNames, instTypes, terms, quotes, dayCountConvention)
curveDict = extractMktData(curve)
print(curveDict)
例3. 构建一个双曲线利率互换收益率曲线(CNY_SHIBOR_3M)。
referenceDate = 2021.05.26
currency = "CNY"
curveName = "CNY_SHIBOR_3M"
discountCurve = {
"mktDataType": "Curve",
"curveType": "IrYieldCurve",
"curveName": "CNY_FR_007",
"referenceDate": referenceDate,
"currency": "CNY",
"dayCountConvention": "Actual365",
"compounding": "Continuous",
"interpMethod": "Linear",
"extrapMethod": "Flat",
"dates":[2021.06.02,2021.06.28,2021.08.27,2021.11.29,2022.02.28,2022.05.27,2023.05.29,2024.05.27,2025.05.27,2026.05.27,2028.05.29,2031.05.27],
"values": [2.3495, 2.3376, 2.3063, 2.3543, 2.4004, 2.4442, 2.5686, 2.6715, 2.7625, 2.8468, 2.9922, 3.1559] / 100.0
}
discountCurve = parseMktData(discountCurve)
terms = [1w, 2w, 1M, 3M, 6M, 9M, 1y, 2y, 3y, 4y, 5y, 7y, 10y]
instNames = take("CNY_SHIBOR_3M", size(terms))
instNames[0] = "SHIBOR_1W"
instNames[1] = "SHIBOR_2W"
instNames[2] = "SHIBOR_1M"
instNames[3] = "SHIBOR_3M"
instTypes = take("IrVanillaSwap", size(terms))
instTypes[0] = "Deposit"
instTypes[1] = "Deposit"
instTypes[2] = "Deposit"
instTypes[3] = "Deposit"
quotes = [2.269,
2.311,
2.405,
2.479,
2.6013,
2.7038,
2.7725,
2.9625,
3.11,
3.24,
3.3513,
3.5313,
3.7125]/100
dayCountConvention = "Actual365"
curve = irSingleCurrencyCurveBuilder(referenceDate, currency, instNames, instTypes, terms, quotes, dayCountConvention, discountCurve)
curveDict = extractMktData(curve)
print(curveDict)
相关函数:
bondYieldCurveBuilder
,
extractMktData
,
irCrossCurrencyCurveBuilder
,
parseMktData
曲线字段要求
字段名
类型
描述
是否必填
mktDataType
STRING
固定填 "Curve"
是
referenceDate
DATE
参考日期
是
version
INT
版本号,默认值 0
否
curveType
STRING
固定填 "IrYieldCurve"
是
dayCountConvention
STRING
曲线的日期计数惯例,可选值为:
"Actual360":实际天数除以360
"Actual365":实际天数除以365(不区分闰年)
"ActualActualISMA":实际天数/实际天数(ISMA规则)
"ActualActualISDA":实际天数/实际天数(ISDA规则)
是
interpMethod
STRING
内插方法,可选值为:
"Linear":线性插值
"CubicSpline":三次样条插值
"CubicHermiteSpline":三次埃尔米特样条插值
是
extrapMethod
STRING
外插方法,可选值为:
"Flat":平插
"Linear":线性插值
是
dates
DATE 向量
数据点的日期
是
values
DOUBLE 向量
数据点的值,与
dates
中的元素一一对应
是
curveName
STRING
曲线名称
否
currency
STRING
货币,可选值为"CNY", "USD", "EUR", "GBP", "JPY", "HKD"
是
compounding
STRING
复利类型,可选值为:
"Simple":单利
"Compounded":离散复利
"Continuous":连续复利
是
settlement
DATE
结算日,如果指定了结算日,则后续期限间隔的计算都将从
settlement
开始,而不是
referenceDate
否
frequency
INTEGRAL或 STRING
计息频率,可选值为:
-1 或 "NoFrequency":无效计息频率
0 或 "Once":到期一次还本付息
1 或 "Annual":每年付息一次
2 或 "Semiannual":每半年付息一次
3 或 "EveryFourthMonth":每四个月付息一次
4 或 "Quarterly":每季度付息一次
6 或 "BiMonthly":每两月付息一次
12 或 "Monthly":每月付息一次
13 或 "EveryFourthWeek":每四周付息一次
26 或 "BiWeekly":每两周付息一次
52 或 "Weekly":每周付息一次
365 或 "Daily":每日付息一次
999 或 "Other":其他计息频率
否
curveModel
STRING
曲线构建模型,目前仅支持 "Bootstrap"。
否
curveParams
DICT
模型的参数。
否
FILE:references/doc_8878.md
# rowTanimoto
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowTanimoto.html
**来源**: DolphinDB 官方文档
---
rowTanimoto
语法
rowTanimoto(X, Y)
详情
若
X
和
Y
同时为向量/矩阵,按行计算
X
和
Y
之间的谷本距离。若
X
和
Y
同时为索引矩阵,会对齐标签,对标签相同的行进行计算,标签不同的行直接返回 NULL。
若
X
和
Y
一个为向量,一个为矩阵,则向量的长度必须与矩阵的列数相同,计算向量与矩阵每一行的谷本距离。
若
X
和
Y
是数组向量,计算
X
和
Y
对应位置的向量之间的谷本距离,即 tanimoto(X.row(i),Y.row(i))。
若
X
和
Y
一个为向量,一个为数组向量,计算向量与数组向量内每个向量的谷本距离。两个向量的长度相同时返回计算结果,长度不相同时返回 NULL。
与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
和
Y
是长度相同的数值型向量或数组向量,或维度相同的矩阵。若
X
和
Y
为数组向量,它们对应位置的向量必须具有相同长度。
返回值
返回一个向量。
例子
rowTanimoto(3.6 5.2 6.3, 8.6 4.8 5.5)
// output
[0.4467,0.0064,0.0181]
a=array(INT[],0,10)
a.append!([[1, 8, 9],[15, NULL], [25, 22, 13, 15]])
b=array(INT[],0,10)
b.append!([[11, 18, 6],[5, 9], [5, 2, 3, 1]])
rowTanimoto(a,b)
// output
[0.5,0.5714,0.8309]
s1=indexedSeries(2020.01.01..2020.01.03, 10.4 11.2 9)
s2=indexedSeries(2020.01.01 2020.01.03 2020.01.04, 23.5 31.2 26)
rowTanimoto(s1,s2)
// output
[0.4125,0.5337,0.5526]
m=matrix(23 56 47, 112 94 59)
m1=matrix(11 15 89, 52 41 63)
rowTanimoto(m,m1)
// output
[0.3812,0.4889,0.1839]
m.rename!(2020.01.01..2020.01.03, `A`B)
m.setIndexedMatrix!()
m1.rename!(2020.01.01 2020.01.03 2020.01.04, `A`B)
m1.setIndexedMatrix!()
rowTanimoto(m,m1)
// output
[0.3812,NULL,0.3014,NULL]
相关函数:
tanimoto
FILE:references/doc_8883.md
# plot
**URL**: https://docs.dolphindb.cn/zh/funcs/p/plot.html
**来源**: DolphinDB 官方文档
---
plot
语法
plot(data, [labels], [title], [chartType=LINE],
[stacking=false], [extras])
详情
生成图表对象的系统函数。当我们在 IDE 中使用绘图功能时,GUI 将生成图表对象。
参数
data
可以是向量,元组,矩阵或表。
如果输入数据是一个向量,它会产生一个单一的系列图,而向量名称就是系列名称。
如果输入数据是元组,则元组的每个元素被视为一个系列。元组的元素必须都是相同长度的向量。向量的名称是系列名称。
如果输入数据是一个矩阵,则矩阵的每一列都是一个系列,矩阵的列标签是系列名称。如果矩阵具有行标签,则它们将被用作数据点标签。
如果输入数据是一个表,那么表的每一列都是一个系列,列名是系列名。
labels
是每个数据点的标签。所有系列的图表共享相同的数据标签。如果输入是矩阵,则可以将矩阵的行标签设置为数据点标签。否则,必须在此指定数据点标签。
title
可以是字符串标量或字符串向量。如果标题是标量,则是图表标题;
如果是矢量,矢量的第一个元素是图表标题,第二个是X轴标题,第三个是Y轴标题。
chartType
表示图表类型,默认值是线性图(LINE)。其他类型还有饼图(PIE),柱形图(COLUMN),条形图(BAR),面积图(AREA)和散点图(SCATTER)。
stacking
表示图表是否堆叠。当
chartType
设置为LINE、BAR 或 AREA
时,该参数才有效。
extras
为可选参数,用于扩展
plot
函数的属性。
extras
必须是字典,其 key 必须是字符串类型。
注:
目前仅支持 multiYAxes 属性:{multiYAxes: true}。设置为 true
表示支持多个 Y 轴,设置为 false 表示共享一个 Y 轴。若需要使用 extras
添加新的属性名称和类型,请联系我们进行报备。
chartType
=LINE 时,必须设置该参数的 multiYAxes
属性。
返回值
无。
例子
Example 1:表
x=0.1*(1..100)
y=0.1*(100..1)
t=table(x,y)
plot(t,extras={multiYAxes: true})
上面的图也可以用
plot(t[`x`y],extras={multiYAxes:true})
生成。
Example 2:矩阵
plot([sin,cos](x),x,"cos and sin curve",extras={multiYAxes: false})
请注意,把函数名作为系列名称,并且指定了数据标志和图的标题。
Example 3:向量
plot(cumsum(x) as cumsumX, 2012.10.01+1..100, "cumulative sum of x")
cumsumX 被用作系列名称。
Example 4:元组
plot([1..10 as x, 10..1 as y], 1..10, extras={multiYAxes: false})
x 和 y 被用作系列名称。
Example 5:条形图
plot(1..5 as value, `IBM`MSFT`GOOG`XOM`C, `rank, BAR)
Example 6:柱形图
plot(99 128 196 210 312 as sales, `IBM`MSFT`GOOG`XOM`C, `sales, COLUMN)
Example 7:饼状图
plot(99 128 196 210 312 as sales, `IBM`MSFT`GOOG`XOM`C, `sales, PIE)
Example 8:散点图
x=rand(1.0, 1000);
y=x+norm(0.0, 0.2, 1000);
plot(x, y, ,SCATTER)
Example 9:设置 {multiYAxes : true}, y1, y2 和 y3 分别对应不同的Y轴
t = table(1 2 3 4 5 as y1, 1200 1300 1400 1500 1600 as y2, 100 300 500 800 900 as y3, 10 20 30 40 50 as date)
plot([t.y1, t.y2,t.y3], t.date, , LINE, , {multiYAxes : true})
FILE:references/doc_889.md
# businessQuarterEnd
**URL**: https://docs.dolphindb.cn/zh/funcs/b/businessQuarterEnd.html
**来源**: DolphinDB 官方文档
---
businessQuarterEnd
语法
businessQuarterEnd(X, [endingMonth=12], [offset],
[n=1])
详情
返回
X
所在季度的最后一个工作日(周一到周五)。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
个季度更新一次。注意,
offset
和
n
须同时指定,且只有当
n
>1 时,offset 才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
endingMonth
是1到12之间的整数,表示一年的结束月份。默认值是12。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
businessQuarterEnd(2012.04.12);
// output
2012.06.30
businessQuarterEnd(2012.04.12, 2);
// output
2012.05.31
businessQuarterEnd(2012.04.12, 8, 2011.08.01, 3);
// output
2012.05.31
date=2011.04.25+(1..10)*90
time = take(09:30:00, 10)
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
t1;
date
time
sym
qty
price
2011.07.24
09:30:00
MSFT
2200
49.6
2011.10.22
09:30:00
MSFT
1900
29.46
2012.01.20
09:30:00
MSFT
2100
29.52
2012.04.19
09:30:00
MSFT
3200
30.02
2012.07.18
09:30:00
MSFT
6800
174.97
2012.10.16
09:30:00
MSFT
5400
175.23
2013.01.14
09:30:00
MSFT
1300
50.76
2013.04.14
09:30:00
MSFT
2500
50.32
2013.07.13
09:30:00
MSFT
8800
51.29
2013.10.11
09:30:00
MSFT
4500
52.38
select avg(price),sum(qty) from t1 group by businessQuarterEnd(date, , 2010.06.01, 2)
businessQuarterEnd_date
avg_price
sum_qty
2011.12.30
39.53
4100
2012.06.29
29.77
5300
2012.12.31
175.1
12200
2013.06.28
50.54
3800
2013.12.31
51.835
13300
相关函数:
businessQuarterBegin
,
quarterBegin
,
quarterEnd
FILE:references/doc_890.md
# getInstrumentFarDelivery
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentfardelivery.html
**来源**: DolphinDB 官方文档
---
getInstrumentFarDelivery
语法
getInstrumentFarDelivery(instrument)
详情
根据输入的金融工具,获取该工具的远端交割日期(far delivery date)。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DATE 类型标量或向量。
例子
swap = {
"productType": "Swap",
"swapType": "FxSwap",
"version": 0,
"currencyPair": "EURUSD",
"direction": "Buy",
"notional": ["EUR", 1E6],
"nearStrike": 1.1,
"nearExpiry": 2025.12.08,
"nearDelivery": 2025.12.10,
"farStrike": 1.2,
"farExpiry": 2026.06.08,
"farDelivery": 2026.06.10
}
ins = parseInstrument(swap)
getInstrumentFarDelivery(ins)
// output: 2026.06.10
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_8907.md
# multiTableRepartitionDS
**URL**: https://docs.dolphindb.cn/zh/funcs/m/multiTableRepartitionDS.html
**来源**: DolphinDB 官方文档
---
multiTableRepartitionDS
语法
multiTableRepartitionDS(query, [column], [partitionType], [partitionScheme],
[local=true])
详情
使用相同的分区类型和分区方案对多个表重新划分数据源。
如果没有指定
column
,
partitionType
和
partitionScheme
,该函数将根据各表原来的分区类型和分区方案划分数据源。相当于
query
中的每个元代码应用到
sqlDS
函数,再将结果合并。
参数
query
是一个元组,其中每个元素都是 SQL 查询的元代码,并且每个 SQL 查询表示的数据表结构(包括列名和各列的数据类型)必须完全相同。
column
是一个字符串,表示
query
中的一个列名。
repartitionDS
函数会根据该列划分数据源。
partitionType
表示分区类型,它的取值可以是 RANGE 或 VALUE。
partitionScheme
是一个向量,表示分区方案。
local
是一个布尔值,表示是否将数据源获取到当前节点进行计算。默认值为 true。
返回值
返回一个元组,包含一组数据源。
例子
n=100000
date=rand(2019.06.01..2019.06.05,n)
sym=rand(`AAPL`MSFT`GOOG,n)
price=rand(1000.0,n)
t1=table(date,sym,price)
db=database("dfs://value",VALUE,2019.06.01..2019.06.05)
db.createPartitionedTable(t1,`pt1,`date).append!(t1);
n=100000
date=rand(2019.06.01..2019.06.05,n)
sym=rand(`AAPL`MSFT`GOOG,n)
price=rand(1000.0,n)
qty=rand(500,n)
t2=table(date,sym,price,qty)
db1=database("",VALUE,2019.06.01..2019.06.05)
db2=database("",VALUE,`AAPL`MSFT`GOOG)
db=database("dfs://compo",COMPO,[db1,db2])
db.createPartitionedTable(t2,`pt2,`date`sym).append!(t2);
pt1=loadTable("dfs://value","pt1")
pt2=loadTable("dfs://compo","pt2");
例1. 根据原有的分区方案划分数据源,不指定
column
,
partitionType
和
partitionScheme
ds=multiTableRepartitionDS([<select * from pt1>,<select date,sym,price from pt2>]);
// output
(DataSource< select [7] * from pt1 [partition = /value/20190601] >,DataSource< select [7] * from pt1 [partition = /value/20190602] >, ...... ,DataSource< select [7] date,sym,price from pt2 [partition = /compo/20190605/GOOG] >,DataSource< select [7] date,sym,price from pt2 [partition = /compo/20190605/MSFT] >)
例2. 根据股票代码的值划分数据源
ds=multiTableRepartitionDS([<select * from pt1>,<select date,sym,price from pt2>],`sym,VALUE,`AAPL`MSFT`GOOG);
// output
(DataSource< select [4] * from pt1 where sym == "AAPL" >,DataSource< select [4] * from pt1 where sym == "MSFT" >,DataSource< select [4] * from pt1 where sym == "GOOG" >,DataSource< select [4] date,sym,price from pt2 where sym == "AAPL" >,DataSource< select [4] date,sym,price from pt2 where sym == "MSFT" >,DataSource< select [4] date,sym,price from pt2 where sym == "GOOG" >)
例3. 根据日期范围划分数据源
ds=multiTableRepartitionDS([<select * from pt1>,<select date,sym,price from pt2>],`date,RANGE,2019.06.01 2019.06.03 2019.06.05);
// output
(DataSource< select [4] * from pt1 where date >= 2019.06.01,date < 2019.06.03 >,DataSource< select [4] * from pt1 where date >= 2019.06.03,date < 2019.06.05 >,DataSource< select [4] date,sym,price from pt2 where date >= 2019.06.01,date < 2019.06.03 >,DataSource< select [4] date,sym,price from pt2 where date >= 2019.06.03,date < 2019.06.05 >)
相关函数:
repartitionDS
FILE:references/doc_8909.md
# semiMonthBegin
**URL**: https://docs.dolphindb.cn/zh/funcs/s/semiMonthBegin.html
**来源**: DolphinDB 官方文档
---
semiMonthBegin
语法
semiMonthBegin(X, [dayOfMonth=15], [offset], [n=1])
详情
返回
X
所在半月的第一天。假设
X
为当月的第 d 天:
如果 d<
dayOfMonth
,那么
semiMonthBegin
返回X所在月份的第一天。
如果 d>=
dayOfMonth
,那么
semiMonthBegin
返回X所在月份的第
dayOfMonth
天。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
个半月更新一次。注意,
offset
和
n
须同时指定,且只有当
n>1
时,
offset
才会生效。
参数
X
可以是 DATE, DATEHOUR, DATETIME, TIMESTAMP 或 NANOTIMESTAMP 类型的标量或向量。
dayOfMonth
是2到27之间的整数。它是一个可选参数,默认值为15。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量。
例子
semiMonthBegin(2012.06.12);
输出返回: 2012.06.01
semiMonthBegin(2012.06.24);
输出返回: 2012.06.15
semiMonthBegin(2012.06.15);
输出返回: 2012.06.15
semiMonthBegin(2012.06.16, 16);
输出返回: 2012.06.16
date=2016.04.07+(1..10)*7
time = take(09:30:00, 10);
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
t1;
输出返回:
date
time
sym
qty
price
2016.04.14
09:30:00
MSFT
2200
49.6
2016.04.21
09:30:00
MSFT
1900
29.46
2016.04.28
09:30:00
MSFT
2100
29.52
2016.05.05
09:30:00
MSFT
3200
30.02
2016.05.12
09:30:00
MSFT
6800
174.97
2016.05.19
09:30:00
MSFT
5400
175.23
2016.05.26
09:30:00
MSFT
1300
50.76
2016.06.02
09:30:00
MSFT
2500
50.32
2016.06.09
09:30:00
MSFT
8800
51.29
2016.06.16
09:30:00
MSFT
4500
52.38
select avg(price),sum(qty) from t1 group by semiMonthBegin(date);
输出返回:
semiMonthBegin_date
avg_price
sum_qty
2016.04.01
49.6
2200
2016.04.15
29.49
4000
2016.05.01
102.495
10000
2016.05.15
112.995
6700
2016.06.01
50.805
11300
2016.06.15
52.38
4500
相关函数:
monthBegin
,
monthEnd
,
semiMonthEnd
FILE:references/doc_8915.md
# isLoggedIn
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isLoggedIn.html
**来源**: DolphinDB 官方文档
---
isLoggedIn
语法
isLoggedIn(userId)
详情
检查用户是否已经登录。
参数
userId
是表示用户名的字符串。它只能包含字母、数字和下划线。它不能以数字开头,长度不能超过30个字符。
返回值
返回一个布尔值。
例子
isLoggedIn(`AlexSmith)
// output: false
FILE:references/doc_8916.md
# lowRange
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lowRange.html
**来源**: DolphinDB 官方文档
---
lowRange
语法
lowRange(X)
详情
对于
X
中的每个元素
Xi
,统计
Xi
左侧相邻且连续大于它的元素个数。
该函数常用于统计一个序列的当前值是前多少周期(日或分钟等)内的最小值。例如某只股票创几日新低等。
参数
X
向量/元组/矩阵/表。
返回值
返回 INT 类型的结果,形式与
X
一致。
例子
lowRange([13.5, 13.6, 13.4, 13.3, 13.5, 13.9, 13.1, 20.1, 20.2, 20.3])
// output
[0,0,2,3,0,0,6,0,0,0]
m = matrix(1.5 2.6 3.2 1.4 2.5 2.2 3.7 2.0, 1.6 2.3 4.2 5.6 4.1 3.2 4.4 6.9)
lowRange(m)
#0
#1
0
0
0
0
0
0
3
0
0
2
1
3
0
0
3
0
// 模拟股票 A 8天的股价,使用 lowRange 计算股票 A 当日股价创几日新低
trades = table(take(`A, 8) as sym, 2022.01.01 + 1..8 as date, 39.70 39.72 39.80 39.78 39.83 39.92 40.00 40.03 as price)
select *, lowRange(price) from trades
id
date
price
lowRange_price
A
2022.01.02
39.7
0
A
2022.01.03
39.72
0
A
2022.01.04
39.8
0
A
2022.01.05
39.78
1
A
2022.01.06
39.83
0
A
2022.01.07
39.92
0
A
2022.01.08
40
0
A
2022.01.09
40.03
0
FILE:references/doc_8923.md
# startClusterReplication
**URL**: https://docs.dolphindb.cn/zh/funcs/s/startClusterReplication.html
**来源**: DolphinDB 官方文档
---
startClusterReplication
语法
startClusterReplication()
详情
重启由多次任务失败而停止或调用
stopClusterReplication
主动停止的异步复制。该命令只能由管理员在主/从集群的控制节点调用。调用该命令前,必须先配置
replicationMode
参数。
参数
无
例子
startClusterReplication();
相关函数:
stopClusterReplication
,
skipClusterReplicationTask
FILE:references/doc_8927.md
# qclp
**URL**: https://docs.dolphindb.cn/zh/funcs/q/qclp.html
**来源**: DolphinDB 官方文档
---
qclp
语法
qclp(r, V, k, [A], [b], [Aeq], [beq], [x0], [c], [eps], [alpha])
详情
用一个线性目标函数和一组包含二次约束的约束条件求解下列优化问题。
结果是一个包含2个元素的元组。第一个元素是目标函数的最小值。第二个元素是目标函数值最小时的x值。
参数
V
,
A
和
Aeq
是列数相同的矩阵。
r
,
b
和
beq
是向量。
k
是一个正标量。
x0
向量绝对值不等式约束的系数向量。
c
一个非负数字,表示绝对值不等式约束的右侧常量系数。
eps
正浮点数,表示求解的精度。默认值为1e-6,范围为 [1e-4,
1e-9]。通过减小该参数值以获得更高精度的解。如果该参数设置值超过规定范围,则会自动调整为默认值。
alpha
正浮点数,表示松弛参数。默认值为1.5,范围为 (0, 2)。通过增加 alpha
的值来加快求解速度。如果该参数设置值超过规定范围,则会自动调整为默认值。
返回值
长度为2的元组。第一个元素是目标函数的最小值。第二个元素是使目标函数达到最小值的变量值。
例子
根据每只股票的预期收益与收益率协方差矩阵,以及如下限制 (1) 投资组合的收益率波动率不超过11% (2)
每只股票的权重在10%到50%之间,以决定最优投资组合。
r = 0.18 0.25 0.36
V= 0.0225 -0.003 -0.01125 -0.003 0.04 0.025 -0.01125 0.025 0.0625 $ 3:3
k = pow(0.11, 2)
A = (eye(3) join (-1*eye(3))).transpose()
b = 0.5 0.5 0.5 -0.1 -0.1 -0.1
Aeq = (1 1 1)$1:3
beq = [1]
x = qclp(-r, V, k, A, b, Aeq, beq);
x[1];
//Output: [0.5,0.1763,0.3237]
在上例的基础上,添加绝对值约束:| x1 - 0.35| + | x2 - 0.35 | + | x3 - 0.35 | ≤ 0.3:
x0 = [0.35, 0.35, 0.35];
c = 0.3;
y = qclp(-r, V, k, A, b, Aeq, beq, x0, c);
y[1]
//Output: [0.475,0.248,0.277]
FILE:references/doc_8935.md
# 部署
**URL**: https://docs.dolphindb.cn/zh/deploy/deploy_intro.html
**来源**: DolphinDB 官方文档
---
部署
DolphinDB 系统包括:服务器程序(dolphindb.exe)、Web 集群管理工具、图形界面客户端 DolphinDB GUI、DolphinDB VS
Code 插件、API 以及面向不同使用场景的插件。
安装系统
下载 Server 压缩包
前往:
https://www.dolphindb.cn/downloads.html
。
图
1
.
下载页面
点击
立即下载
即可下载 DolphinDB server 社区版压缩包。
解压 DolphinDB server 压缩包,其中含有 Web 集群管理工具、服务端程序以及 license
文件。解压完成后不需要进一步安装。
注:
如需企业试用版,点击
申请企业试用版
填写申请表单并提交。DolphinDB 技术支持人员与您联系后,您会收到企业试用版 license 文件。若 license 文件名不是
dolphindb.lic
,需要将其改名为
dolphindb.lic
并替换社区版中
/server/
路径下的同名文件,即可使用企业试用版。
选择编程交互客户端
图
2
.
客户端
DolphinDB 公司开发了支持 DolphinDB 数据库编程语言的 VS Code 插件,便于用户使用 VS Code 编写 DolphinDB
脚本,并在 DolphinDB 服务器上运行。VS Code
使用者无需安装其它软件,直接下载插件即可使用,学习成本低,上手快。因此,
推荐具有深度编程需求的用户选择使用 VS Code 插件(即 Visual
Studio Code extension for DolphinDB)
。
有关 VS Code 插件的安装和使用,参考:
DolphinDB VS
Code 插件
。
DolphinDB 也支持使用 DolphinDB GUI 客户端来连接 DolphinDB、编辑脚本。有关 DolphinDB GUI
的安装和使用,参考:
GUI 客户端
。
开发资源(可选)
为满足不同场景需求下的用户操作,DolphinDB 提供了 C++,Java, Python 和 C# 等开发接口,包含 JDBC,Grafana
在内的连接器以及数十个面向不同应用场景的插件作为可选的开发资源。
更多相关内容,查看:
开发资源
。
有关 DolphinDB 的连接器安装步骤及使用方法,参考:
连接器
& API
。
有关 DolphinDB 的插件使用说明,参考:
插件
。
配置
完成以上系统安装后,即可搭建单机集群或多机集群。
独立服务器(单节点模式)
作为一个独立的工作站或服务器使用,下载后即可使用,无需配置。详见:
单节点部署教程
。
DolphinDB 支持嵌入式 ARM 环境。详见:
ARM版本单节点部署教程
。
单节点模式拥有与集群模式相同的功能,区别在于单节点模式不支持扩展节点和高可用,而集群模式可以方便地扩展到多个服务器节点以及支持高可用。
单机集群搭建
控制节点(controller)、代理节点(agent)、数据节点(data node)、计算节点(compute
node)部署在同一个物理机器上。详见:
单服务器集群部署
。
多机集群搭建
在多个物理机器上部署 DolphinDB 集群。详见:
多服务器集群部署
。
DolphinDB 提供数据、元数据以及客户端的高可用方案,使得数据库节点发生故障时,数据库依然可以正常运作,保证业务不会中断。详见:
高可用集群部署
。
功能及应用场景
功能
单节点
单机集群
多服务器集群
多模存储引擎
√
√
√
支持事务
√
√
√
分布式计算
√
√
√
多范式编程
√
√
√
实时流数据
√
√
√
系统管理及接口
√
√
√
云上部署
√
√
√
扩展节点
x
√
√
数据高可用(多副本)
x
√
√
应用高可用
x
x
√
应用场景
单节点
单机集群
多服务器集群
开发
√
√
√
研究
√
√
√
小规模生产环境
√
√
√
可扩展
x
√
√
企业级生产环境
x
x
√
使用系统
使用 Web 集群管理工具可以启动关闭数据节点、查看集群各节点的性能指标、浏览分布式数据库整体数据分区情况及详细数据。详见:
Web 操作手册
。
GUI 客户端提供了方便开发 DolphinDB 脚本的图形界面。详见:
GUI 客户端
。
在 DolphinDB 中创建分区数据库和表。DolphinDB
支持范围、哈希、值、列表、以及组合分区,可灵活应对各类企业实际业务场景,详见:
建库建表
。
使用 DolphinDB 流数据引擎进行实时数据处理与分析。详见:
流数据
。
提示:
使用系统前建议先阅读:
量化金融范例
物联网范例
用户权限设置
DolphinDB 提供了完善、安全的权限管理机制,适用于企业级的不同应用场景,详见:
用户权限管理
。
常见错误原因
节点启动后立即退出,在 log 文件中显示错误原因为 "
The license has expired
"。
原因:license 过期。
解决方案:联系 DolphinDB 技术支持
[email protected]
,更新 license 文件
dolphindb.lic
。
集群管理器上启动节点后,节点仍然显示未启动状态。
原因:需要手动刷新集群节点状态。
解决方案:点击集群管理器上刷新按钮。
在使用过程中如果遇到各种问题,可以查看 log 文件获取问题信息。每个数据节点和控制节点都有独立的 log 文件,默认在
home
目录下(例如单节点部署是
server/dolphindb.log
,集群部署是
server/log/*.log
),里面有系统详细的运行日志;也可以联系
[email protected]
或致电 0571-82853925。
有关更多 DolphinDB server 使用中可能出现的错误码及说明,参考:
错误代码
。
FILE:references/doc_8936.md
# highLong
**URL**: https://docs.dolphindb.cn/zh/funcs/h/highlong.html
**来源**: DolphinDB 官方文档
---
highLong
语法
highLong(X)
详情
返回
X
的高位 8 字节的数据,为 LONG 类型。
参数
X
是一个标量、向量、表、数据对或者字典,且必须为16字节的数据类型(支持 UUID、IPADDR、INT128、COMPLEX、POINT)。
例子
x =ipaddr("192.168.1.13")
x1 = highLong(x)
print(x1)
//output: 0
x=1 2 3 4
y=4 3 2 1
points = point(x, y)
x1 = highLong(points)
//output:[4616189618054758400,4613937818241073152,4611686018427387904,4607182418800017408]
FILE:references/doc_8939.md
# shape
**URL**: https://docs.dolphindb.cn/zh/funcs/s/shape.html
**来源**: DolphinDB 官方文档
---
shape
语法
shape(X)
详情
以数据对的形式返回标量、向量或矩阵的维度。
参数
X
可以是标量、向量、矩阵或表。
返回值
INT PAIR 类型标量。
例子
标量的维度总是 1:1
shape 1;
// output
1:1
s;
向量的维度总是向量长度:1
shape 1 5 3 7 8;
// output
5:1
矩阵的维度
m=(5 3 1 4 9 10)$3:2;
m;
#0
#1
5
4
3
9
1
10
shape m;
// output
3 :2
表的维度
t=table(1 2 3 as x, 4 5 6 as y);
t;
x
y
1
4
2
5
3
6
shape t;
// output
3 :2
FILE:references/doc_8943.md
# mwsum
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mwsum.html
**来源**: DolphinDB 官方文档
---
mwsum
语法
mwsum(X, Y, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内,计算
X
和
Y
元素的内积。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
Y
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的 DOUBLE 类型向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
X = 2 1 3 7 6 5 4
X1 = 2 1 3 NULL 6 5 4
Y = 1 0.5 1 1 2 2.1 2
mwsum(X, Y, 3);
// output: [,,5.5,10.5,22,29.5,30.5]
mwsum(X1, Y, 3)
// output: [,,5.5,3.5,15,22.5,30.5]
mwsum(X1, Y, 3, minPeriods=1)
// output: [2,2.5,5.5,3.5,15,22.5,30.5]
X = 1..10;
Y = 9 5 3 4 5 4 7 1 3 4;
X1 = indexedSeries(date(2020.06.05)+1..10, X)
Y1 = indexedSeries(date(2020.06.05)+1..10, Y)
mwsum(X1, Y1, 5d)
label
col1
2020.06.06
9
2020.06.07
19
2020.06.08
28
2020.06.09
44
2020.06.10
69
2020.06.11
84
2020.06.12
123
2020.06.13
122
2020.06.14
133
2020.06.15
148
mwsum(X1, Y1, 1w)
label
col1
2020.06.06
9
2020.06.07
19
2020.06.08
28
2020.06.09
44
2020.06.10
69
2020.06.11
93
2020.06.12
142
2020.06.13
141
2020.06.14
158
2020.06.15
189
相关函数:
wsum
,
msum
FILE:references/doc_8948.md
# createOrderBookSnapshotEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createorderbooksnapshotengine.html
**来源**: DolphinDB 官方文档
---
createOrderBookSnapshotEngine
语法
createOrderBookSnapshotEngine(name, exchange,
orderbookDepth, intervalInMilli, date, startTime, prevClose, dummyTable,
outputTable, inputColMap, [outputColMap], [outputCodeMap], [snapshotDir],
[snapshotIntervalInMsgCount], [raftGroup], [outputIntervalOffsetMap],
[checkRestrict], [maxPrice], [minPrice], [userDefinedMetrics], [priceNullFill],
[triggerType], [forceTriggerTime], [precision], [orderBySeq],
[skipCrossedMarket=true], [orderBookDetailDepth=0],
[orderBookAsArray=false],[useSystemTime=false],[independentForceTriggerTime],[includeImmediateExecution=false],
[securitySubType='ConvertibleBond'], [priceScale=10000], [endTime])
注:
社区版 License 暂不支持该引擎,如需使用此功能,请联系技术支持。
详情
该函数基于一个包含了逐笔委托和逐笔交易数据表,实时合成指定频率(1秒,100ms,30ms
等)的全档位盘口信息、窗口内统计信息、全天累计统计信息等订单薄(或者叫快照)数据。也可通过历史逐笔数据来合成需要的订单薄数据。
目前支持合成深交所股票、深交所债券、深交所基金、上交所股票、上交所债券、上交所基金的订单薄数据。请注意,债券的规则遵循自2022年8月之后发布的新规定。
如果输入数据后,引擎一直没有输出或者输出的结果很少,请参考 Orderbook 引擎教程中常见问题的
7.5 小节
排查问题。
窗口规则
由参数
intervalInMilli
指定窗口的长度(以时间衡量),输出表中显示的时间为窗口的右边界。最后一个窗口区间为左开右开,且输出窗口显示为右边界的时间戳,其余窗口区间全部左开右闭。
最后一个窗口的右边界上限由参数
endTime
决定:
若指定
endTime
,则最后一个窗口的右边界上限为
endTime
。
若未指定
endTime
:
当
exchange
= “XSHGBOND” 时,最后一个窗口的右边界上限为 15:00:00.000。
当
exchange
是其它值时,最后一个窗口的右边界上限为 14:57:00.000。
触发规则
第一条输出记录由输入表中第一条时间戳大于 startTime + intervalInMilli 的记录触发,此时输出表的时间戳为 startTime +
intervalInMili。之后根据参数
triggerType
的配置值,决定新收到任意一条逐笔数据,当其时间戳大于窗口右边界时,触发输出单个或所有证券代码的快照。
注:
一个引擎至多只能输入某一天一个通道的全部股票数据。
必须保证注入引擎的数据表内的数据按照交易所的逐笔序号排序。
参数
注:
传参时必须指定参数名。
name
字符串标量,表示 orderbook 快照引擎的名称,可包含字母,数字和下划线,但必须以字母开头。
exchange
字符串标量,表示证券的类型。可选参数:
"XSHE" 或 "XSHESTOCK":深交所股票
"XSHEBOND":深交所债券
"XSHEFUND":深交所基金
"XSHG" 或 "XSHGSTOCK":上交所股票
"XSHGBOND":上交所债券
"XSHGFUND":上交所基金
orderbookDepth
正整数,表示 orderbook 中最多能够显示的买卖报价的档位。
intervalInMilli
正整数,表示触发输出数据的时间间隔,即合成快照的时间频率,单位为毫秒。
date
DATE 类型标量,表示交易日期。该参数和窗口右边界组合成输出表的 TIMESTAMP 列。
startTime
TIME
类型标量,表示触发输出数据的起始时刻。引擎只会输出该参数指定时刻(规整后)之后的数据。
prevClose
字典,其 key 为字符串标量或向量,表示股票代码;其 value
为数值类型,表示对应于股票代码的上一个交易日的收盘价格。注意:若 value 为浮点型,则认为是真实价格,引擎处理过程中会乘以
priceScale
,以匹配输入表中 priceColumn 字段的精度。若为整型,则视为已和 priceColumn
具备相同精度,不再进行缩放。
dummyTable
一个表对象,和输入的流数据表的 schema 一致,可以含有数据,亦可为空表。
outputTable
一个表对象。若指定
userDefinedMetrics
,
outputTable
根据
genOutputColumnsForOBSnapshotEngine
函数指定的
basic
、
depth
以及用户自定义的指标来确定表结构。否则,
outputTable
根据
outputColMap
的设置来确定表结构。
注:
tradeDetail(成交明细)中的
tradeBuyOrderTypeList 和 tradeSellOrderTypeList。如需要输出上述字段,请在
outputColMap
中手动添加。
inputColMap
字典,将输入表中列字段的名称映射为引擎计算所需要的列。其中:
key 为字符串类型,表示引擎所需要的固定的输入字段。具体字段名和含义见下表。注意,这些 key 区分大小写,必须全部指定,但顺序可以不固定。
value 为字符串类型,表示输入表中对应的列名称。
key
value 对应的字段类型
含义
"codeColumn"
SYMBOL
证券代码(如300010.SZ)
"timeColumn"
TIME
交易时间
"typeColumn"
INT
交易类型:
如果是逐笔委托单,则:1 表示市价;2 表示限价;3 表示本方最优;10 表示撤单(仅上交所);11
市场状态(仅上交所)
如果是逐笔成交单,则:0 表示成交;1 表示撤单(仅深交所)
"priceColumn"
LONG
价格,由
priceScale
决定,默认是真实价格*10000
"qtyColumn"
LONG
数量(股数)
"buyOrderColumn"
LONG
逐笔成交:对应其原始成交中的买方委托序号。
逐笔委托:
上交所:填充原始委托中的原始订单号,即上交所在新增、删除订单时用以标识订单的唯一编号(OrderNo
字段)
深交所:填充 0。此字段为深交所为了补全上交所数据格式而增加的冗余列
"sellOrderColumn"
LONG
逐笔成交:对应其原始成交中的卖方委托序号。
逐笔委托:
上交所:填充原始委托中的原始订单号,即上交所在新增、删除订单时用以标识订单的唯一编号(OrderNo
字段)
深交所:填充 0。此字段深交所为了补全上交所数据格式而增加的冗余列
"sideColumn"
INT
买卖方向:1 表示买单;2 表示卖单
说明:
委托单的 BSFlag,必填
撤单的 BSFlag 由原始委托单决定买卖方向,必填
成交单的 BSFlag,不影响结果,非必填
"msgTypeColumn"
INT
数据类型:
0 表示逐笔委托;
1 表示逐笔成交;
-1 表示产品状态。
"seqColumn"
LONG
一个通道内从 1 开始递增的逐笔数据序号。深交所为 appseqlnum 字段,若深交所数据中包含 index
字段,也可以使用 index;上交所为 bizIndex 字段。
"receiveTime"
NANOTIMESTAMP
逐笔数据的接收时间
注:
引擎规范了枚举类型中各枚举值的具体含义。输入表对应的枚举值必须遵守这个规范。比如枚举类型字段
sideColumn 所对应的输入表中的字段必须使用 1 代表买方向,2 代表卖方向。
outputColMap
可选参数,字符串向量,用于指定需要输出的字段名称,不区分大小写。为方便指定
outputColMap
,用户可通过
genOutputColumnsForOBSnapshotEngine
函数生成需要输出的字段名称,将返回值的第一个元素赋值给
outputColMap
即可。
注:
genOutputColumnsForOBSnapshotEngine
函数生成的字段列表中不包含以下字段:
tradeDetail(成交明细)中的 tradeBuyOrderTypeList 和
tradeSellOrderTypeList。
withdrawDetail(撤单明细)中的
withdrawBuyOrderNoList和withdrawSellOrderNoList。
residualDetail(剩余委托明细)中的 ResidualBidOrderNoList 和
ResidualAskOrderNoList。
如需要输出上述字段,请在
outputColMap
中手动添加。
outputCodeMap
可选参数,字符串向量,表示股票代码,例如:"000803.SZ"。指定该参数后,将只输出指定股票对应的数据。
outputIntervalOffsetMap
可选参数,向量或字典,用于指定输出表中股票被触发计算的时间偏移量。
当为向量时,向量中的元素表示不同的时间偏移量,单位为毫秒。引擎将根据输入的股票数量自动将这些股票均匀分配到这些偏移量上。例如,outputIntervalOffsetMap
= [400, 500],表示引擎将自动将输入的股票均匀分成两部分,经过intervalInMilli + 400(ms)
后触发其中一部分股票的数据输出;经过 intervalInMilli + 500(ms) 后触发另一部分股票的数据输出。
当为字典时,其 key 为字符串类型,表示股票代码;其 value
为整型,表示时间偏移量,单位为毫秒。例如:outputIntervalOffsetMap
=dict(["127053.sz","123082.SZ"],[400, 500]),表示经过 intervalInMilli + 400(ms)
后触发 127053.sz 股票的数据输出;经过 intervalInMilli + 500(ms) 后触发 123082.SZ
股票的数据输出。
checkRestrict
可选参数,布尔值,默认值为 true,表示开启价格笼子机制;若设置为
false,则关闭笼子机制,此时会取消对股票交易的限制,创业板合成出的快照可能不正确。
注:
深交所对创业板证券(证券代码以 3 开头)设定了价格笼子。在
checkRestrict
=true
时,引擎只会将证券代码的首字符是否为 3 作为是否执行价格笼子的判断标准。因此,在向引擎输入创业板数据时,证券代码必须以 3 开头。
maxPrice
可选参数,字典。其 key 为字符串类型,表示证券代码;其 value 为 DOUBLE 或 INT
类型,表示涨停价格。注意:若
maxPrice
为浮点型,则认为是真实价格,引擎处理过程中会乘以
priceScale
,以匹配输入表中
priceColumn 字段的精度。若为整型,则视为已和 priceColumn 具备相同精度,不再进行缩放。
minPrice
可选参数,字典。其 key 为字符串类型,表示证券代码;其 value 为 DOUBLE 或 INT
类型,表示跌停价格。注意:若
minPrice
为浮点型,则认为是真实价格,引擎处理过程中会乘以
priceScale
,以匹配输入表中
priceColumn 字段的精度。若为整型,则视为已和 priceColumn 具备相同精度,不再进行缩放。
userDefinedMetrics
可选参数,一元函数。
函数的入参是一个表,表的每一行是一个标的,每一列是标的对应的快照。若指定
outputColMap
,则表中数据为
outputColMap
设置的字段;否则表中数据为基础字段和报价/询价的价格和数量。
函数的返回值是一个元组,元组的每一个元素是一个常规向量,代表每个标的经对应指标计算后的结果。
priceNullFill
一个数字。该参数值用于填充输出表中多档买/卖价格中缺失档位的价格。例如涨停后卖单的价格都为
NULL,此时如有指定卖单价格为 0 的需求,可以设置 priceNullFill=0。
triggerType
可选参数,字符串标量,表示触发方式。可选值为:
"mutual"(默认值):新收到任意一条逐笔数据,当其时间戳大于窗口右边界时,就会触发所有股票未计算的快照合成输出。触发计算的数据并不会参与该次计算。
"independent":新收到任意一条逐笔数据,当其时间戳大于窗口右边界时,只触发该条数据对应股票未计算的快照合成输出。触发计算的数据并不会参与该次计算。
"perRow":每收到一行逐笔数据都会触发该条数据对应股票计算并输出,触发计算的数据并参与该次计算。
forceTriggerTime
可选参数,是非负整数,单位为毫秒。除了正常触发合成快照外,有时会出现一些数据因乱序不能触发合成快照,而是被缓存在引擎中。在这种情况下,可通过该参数设置强制触发引擎中长时间未处理的逐笔数据合成快照。触发规则为:
最新收到的逐笔数据的时间戳(t )减去最后一条已经处理的交易数据的时间戳(t0 )大于或等于
forceTriggerTime
,则触发未处理的数据中序号最小的那条数据合成快照,并更新已经处理的交易数据的时间戳(t1)。
重复上述操作,若判断 t-t1 >=
forceTriggerTime
,则触发未处理的数据中序号最小的那条数据合成快照,并更新已经处理的交易数据的时间戳(t2);直到两个时间戳的差值小于
forceTriggerTime
时,停止触发快照合成。
precision
可选参数,整数,表示小数位数,取值范围为[-1,4]。
当
precision
=-1 时,引擎输出的价格相关字段为整型。注意:输出表中相应的字段可以是整型或非整型。
当
pricision
取 [0, 4]
中的值时,表示小数位数。输出表中所有的价格将按照指定的位数进行四舍五入。否则,按照原始结果输出。
orderBySeq
可选参数,布尔值或元组。
指定该参数值为布尔值时,表示是否按照逐笔数据中的 seqColumn 列中值的大小顺序处理数据。当
exchange
="XSHG" 或
"XSHGFUND" 时,默认值为 true;在其他情况下,默认值为 false。
当
orderBySeq
=true
时,会根据逐笔数据的序号有序处理数据,并计算输出。例如引擎先后收到序号为1,3的数据,因为缺少序号为2的数据,引擎先将1和3的数据缓存,待收到序号2的数据时,再进行计算输出。此时也可以指定
forceTriggerTime
强制触发计算输出。
当
orderBySeq
=false 时,每接收到一条数据都会立即进行计算并输出,此时不可设置
forceTriggerTime
。
指定该参数值为元组时,以(BOOL, INTEGER, [STRING])的形式表示,其中:
第一个元素为布尔值,表示是否按照逐笔数据的序号有序输出结果的布尔值,作用同上。
第二个元素为正整数,表示记录缓存输入数据量的时间间隔,单位为毫秒(ms)。
第三个元素为指定输出日志级别的字符串标量,可选参数,其可用值为 DEBUG (默认值)和 INFO,分别对应 Debug 和 Info
级别的日志输出。
skipCrossedMarket
可选参数, 布尔值,表示是否输出买一卖一价交叉的计算结果。
当
skipCrossedMarket
=true(默认值)时,若设置
useSystemTime
=
false,若出现买一卖一价交叉,即卖一价<=买一价,则不输出该条结果;若设置
useSystemTime
=
true,则出现买一卖一交叉时,暂时不输出该条快照,若接下来收到的数据不再有交叉,则立即触发该条快照输出。
当
skipCrossedMarket
=false 时,若出现买一卖一价交叉,仍然输出该条结果。
orderBookDetailDepth
可选参数,整型标量,表示 orderbook
明细的深度。默认值为0,表示不输出。该参数必须和
outputColMap
中 orderBookDetailDepth 字段的值保持一致。
orderBookAsArray
可选参数,布尔值,表示是否以数组向量形式输出报价/询价的价格和数量。默认值为
false,价格和数量将以多列形式输出。
注意,若指定
userDefinedMetrics
,价格和数量的输出形式由
orderBookAsArray
确定。否则,价格和数量的输出形式由
outputColMap
确定,该参数失效。
useSystemTime
可选参数,布尔值,表示是否使用系统时间来触发快照输出。
当
useSystemTime
= true 时,
交易时段内,
引擎将基于当前的系统时间,按照
intervalInMilli
设置的时间间隔触发快照输出。此时,休盘时段((11:30:00.000,13:00:00.000])不输出数据,下午盘第一个输出窗口时间戳为
13:00:00.000+
intervalInMilli
。注意,若设置
useSystemTime
=
true,则不能指定
forceTriggerTime
;可以不指定
triggerType
,或者指定为
triggerType
="mutual"
当
useSystemTime
= false(缺省值)时,引擎根据事件时间来触发快照输出。
independentForceTriggerTime
可选参数,非负整数,单位为毫秒。该参数用于设置在长时间未触发快照输出的分组中,强制输出快照的时间间隔。仅当设置
triggerType
="independent" 时,该参数才会生效。
举例说明:假设在当前已处理的数据中,最新一条数据的时间为 t。各个分组内已处理的应被触发输出的快照时间为 ti。如果满足
t-ti>
independentForceTriggerTime
,则会触发输出相应分组的快照。
includeImmediateExecution
可选参数,布尔值,默认值为
false,表示是否将即时成交的信息统计到委托明细(orderDetail)中。此设置仅在合成上交所订单簿时有效
,且适用于股票和基金数据(
exchange
指定为 "XSHG", "XSHGSTOCK" 或 "XSHGFUND")
。
注:
注意:若该配置项设置为 true,则
inputColMap
必须保证输入数据中的 OrderNo
全局有序。同时,确保即时成交记录中的未被记录的 orderNo 大于等于当前最新记录的 OrderNo。
securitySubType
字符串标量(不区分大小写),用于指定生成订单簿的证券子类型,仅适用于
exchange
为 "XSHEBOND"
或 "XSHGBOND" 的情况。可选值为:
"ConvertibleBond"(默认):对于 "XSHEBOND" 订单簿仅包含代码前缀为 "123","127","128" 的债券;对于
“XSHGBOND” 订单簿仅包含代码前缀为 "110","111","113","118" 的债券。
"All":包含所有债券,无前缀限制。
priceScale
一个正整数,表示输入表中 priceColumn 列的缩放比例,默认值为 10000。引擎输出时会将计算结果除以
priceScale
。
endTime
可选参数,TIME
类型标量,指定快照输出的最后一个窗口的的右边界上限。即,仅当窗口右边界时间戳小于
endTime
时,才会输出该窗口对应的快照数据。
仅在
triggerType
= "mutual" 时支持设置该参数。若不设置,当
exchange
= “XSHGBOND”
时,
endTime
默认值为 15:00:00.000;当
exchange
是其它值时,
endTime
默认值为14:57:00.000。
若要开启快照机制 (snapshot),必须指定
snapshotDir
与
snapshotIntervalInMsgCount
。
snapshotDir
可选参数,字符串,表示保存引擎快照的文件目录。
指定的目录必须存在,否则系统会提示异常。
创建流数据引擎时,如果指定了
snapshotDir
,会检查该目录下是否存在快照。如果存在,会加载该快照,恢复引擎的状态。
多个引擎可以指定同一个目录存储快照,用引擎的名称来区分快照文件。
一个引擎的快照可能会使用三个文件名:
临时存储快照信息:文件名为
<engineName>.tmp
;
快照生成并刷到磁盘:文件保存为
<engineName>.snapshot
;
存在同名快照:旧快照自动重命名为
<engineName>.old
。
snapshotIntervalInMsgCount
可选参数,为整数类型,表示每隔多少条数据保存一次流数据引擎快照。
返回值
返回一个表。
例子
运行代码前,先下载
../data/orderbookDemoInput.zip
文件。
例1.
// 登录
login("admin", "123456")
// 释放已有的引擎
try { dropStreamEngine("demo") } catch(ex) { print(ex) }
// 创建引擎参数 outputTable,即指定输出表
suffix = string(1..10)
colNames = `SecurityID`timestamp`lastAppSeqNum`tradingPhaseCode`modified`turnover`volume`tradeNum`totalTurnover`totalVolume`totalTradeNum`lastPx`highPx`lowPx`ask`bid`askVol`bidVol`preClosePx`invalid join ("bids" + suffix) join ("bidVolumes" + suffix) join ("bidOrderNums" + suffix) join ("asks" + suffix) join ("askVolumes" + suffix) join ("askOrderNums" + suffix)
colTypes = [SYMBOL,TIMESTAMP,LONG,INT,BOOL,DOUBLE,LONG,INT,DOUBLE,LONG,INT,DOUBLE,DOUBLE,DOUBLE,DOUBLE,DOUBLE,LONG,LONG,DOUBLE,BOOL] join take(DOUBLE, 10) join take(LONG, 10) join take(INT, 10) join take(DOUBLE, 10) join take(LONG, 10) join take(INT, 10)
share table(10000000:0, colNames, colTypes) as outTable
// 创建引擎参数 dummyTable,即指定输入表的表结构
colNames = `SecurityID`Date`Time`SecurityIDSource`SecurityType`Index`SourceType`Type`Price`Qty`BSFlag`BuyNo`SellNo`ApplSeqNum`ChannelNo
colTypes = [SYMBOL, DATE, TIME, SYMBOL, SYMBOL, LONG, INT, INT, LONG, LONG, INT, LONG, LONG, LONG, INT]
dummyOrderStream = table(1:0, colNames, colTypes)
// 创建引擎参数 inputColMap,即指定输入表各字段的含义
inputColMap = dict(`codeColumn`timeColumn`typeColumn`priceColumn`qtyColumn`buyOrderColumn`sellOrderColumn`sideColumn`msgTypeColumn`seqColumn, `SecurityID`Time`Type`Price`Qty`BuyNo`SellNo`BSFlag`SourceType`ApplSeqNum)
// 创建引擎参数 prevClose,即昨日收盘价,prevClose 不影响最终的输出结果中除昨日收盘价以外的其他字段
prevClose = dict(`000587.SZ`002694.SZ`002822.SZ`000683.SZ`301063.SZ`300459.SZ`300057.SZ`300593.SZ`301035.SZ`300765.SZ, [1.66, 6.56, 6.10, 8.47, 38.10, 5.34, 9.14, 48.81, 60.04, 16.52])
// 定义引擎,每1s计算输出深交所股票10档买卖盘口
engine = createOrderBookSnapshotEngine(name="demo", exchange="XSHE", orderbookDepth=10, intervalInMilli = 1000, date=2022.01.10, startTime=09:15:00.000, prevClose=prevClose, dummyTable=dummyOrderStream, outputTable=outTable, inputColMap=inputColMap)
filePath = "./orderbookDemoInput.csv"
colNames = `SecurityID`Date`Time`SecurityIDSource`SecurityType`Index`SourceType`Type`Price`Qty`BSFlag`BuyNo`SellNo`ApplSeqNum`ChannelNo
colTypes = [SYMBOL, DATE, TIME, SYMBOL, SYMBOL, LONG, INT, INT, LONG, LONG, INT, LONG, LONG, LONG, INT]
orderTrade = table(1:0, colNames, colTypes)
orderTrade.append!(select * from loadText(filePath) order by Time)
// 10支股票的逐笔数据批量注入快照合成引擎
engine.append!(orderTrade)
select count(*) from outTable where SecurityID="300593.SZ", timestamp between 2022.01.10T13:15:01.000 and 2022.01.10T13:15:10.000
//output: 10
例2. 通过
outputColMap
指定需要输出的字段。
genOutputColumnsForOBSnapshotEngine
函数返回值的第一个元素即为
outputColMap
,返回值的第二个元素可以确定
outputTable
的
schema。
try { dropStreamEngine("demo") } catch(ex) { print(ex) }
filePath = "./orderbookDemoInput.csv"
// 创建引擎参数 dummyTable,即指定输入表的表结构
colNames = `SecurityID`Date`Time`SecurityIDSource`SecurityType`Index`SourceType`Type`Price`Qty`BSFlag`BuyNo`SellNo`ApplSeqNum`ChannelNo
colTypes = [SYMBOL, DATE, TIME, SYMBOL, SYMBOL, LONG, INT, INT, LONG, LONG, INT, LONG, LONG, LONG, INT]
share table(1:0, colNames, colTypes) as dummyOrderStream
// 创建引擎参数 inputColMap,即指定输入表各字段的含义
inputColMap = dict(`codeColumn`timeColumn`typeColumn`priceColumn`qtyColumn`buyOrderColumn`sellOrderColumn`sideColumn`msgTypeColumn`seqColumn, `SecurityID`Time`Type`Price`Qty`BuyNo`SellNo`BSFlag`SourceType`ApplSeqNum)
// 创建引擎参数 prevClose,即昨日收盘价,prevClose 不影响最终的输出结果中除昨日收盘价以外的其他字段
prevClose = dict(`000587.SZ`002694.SZ`002822.SZ`000683.SZ`301063.SZ`300459.SZ`300057.SZ`300593.SZ`301035.SZ`300765.SZ, [1.66, 6.56, 6.10, 8.47, 38.10, 5.34, 9.14, 48.81, 60.04, 16.52])
//创建使用 outputColMap 和 outputTableSch 接收 genOutputColumnsForOBSnapshotEngine 的返回值。它们分别用于确定 outputColMap 和 outputTable
outputColMap, outputTableSch = genOutputColumnsForOBSnapshotEngine(basic=true, time=false, depth=(10, true), tradeDetail=true, orderDetail=false, withdrawDetail=false, orderBookDetailDepth=0, prevDetail=false)
engine = createOrderBookSnapshotEngine(name="demo", exchange="XSHE", orderbookDepth=10, intervalInMilli = 1000, date=2022.01.10, startTime=09:15:00.000, prevClose=prevClose, dummyTable=dummyOrderStream, outputTable=outputTableSch, inputColMap=inputColMap, outputColMap=outputColMap, orderBookAsArray=true)
// 10支股票的逐笔数据批量注入快照合成引擎
engine.append!(select * from loadText(filePath) order by Time)
select top 10 * from outputTableSch where code="300593.SZ", timestamp between 2022.01.10T13:15:01.000 and 2022.01.10T13:15:10.000
部分结果展示如下:
可结合
genOutputColumnsForOBSnapshotEngine
,输出部分需要的字段。假如我们只需要输出示例中
tradeDetail
的部分字段(如排除最后 4 列),可对
genOutputColumnsForOBSnapshotEngine
的返回值进行如下处理:
outputColMap = outputColMap[0 : (size(outputColMap) - 4)]
outputTableSch = outputTableSch[, 0 : (outputTableSch.columns() - 4)]
engine = createOrderBookSnapshotEngine(name="demo", exchange="XSHE", orderbookDepth=10, intervalInMilli = 1000, date=2022.01.10, startTime=09:15:00.000, prevClose=prevClose, dummyTable=dummyOrderStream, outputTable=outputTableSch, inputColMap=inputColMap, outputColMap=outputColMap, orderBookAsArray=true)
例 3.
try { dropStreamEngine("demo") } catch(ex) { print(ex) }
filePath = "./orderbookDemoInput.csv"
// 创建引擎参数 dummyTable,即指定输入表的表结构
colNames = `SecurityID`Date`Time`SecurityIDSource`SecurityType`Index`SourceType`Type`Price`Qty`BSFlag`BuyNo`SellNo`ApplSeqNum`ChannelNo`ReceiveTime
colTypes = [SYMBOL, DATE, TIME, SYMBOL, SYMBOL, LONG, INT, INT, LONG, LONG, INT, LONG, LONG, LONG, INT, NANOTIMESTAMP]
share table(1:0, colNames, colTypes) as dummyOrderStream
// 创建引擎参数 inputColMap,即指定输入表各字段的含义
inputColMap = dict(`codeColumn`timeColumn`typeColumn`priceColumn`qtyColumn`buyOrderColumn`sellOrderColumn`sideColumn`msgTypeColumn`seqColumn`receiveTime, `SecurityID`Time`Type`Price`Qty`BuyNo`SellNo`BSFlag`SourceType`ApplSeqNum`ReceiveTime)
// 创建引擎参数 prevClose,即昨日收盘价,prevClose 不影响最终的输出结果中除昨日收盘价以外的其他字段
prevClose = dict(`000587.SZ`002694.SZ`002822.SZ`000683.SZ`301063.SZ`300459.SZ`300057.SZ`300593.SZ`301035.SZ`300765.SZ, [1.66, 6.56, 6.10, 8.47, 38.10, 5.34, 9.14, 48.81, 60.04, 16.52])
//此处只定义 outputColMap 接收 genOutputColumnsForOBSnapshotEngine 的第一个返回值。因 userDefinedMetrics 定义的指标中需要使用委托明细和回撤明细,因此 genOutputColumnsForOBSnapshotEngine 需要指定 orderDetail=false, withdrawDetail=true
outputColMap = genOutputColumnsForOBSnapshotEngine(basic=true, time=false, depth=(10, true), tradeDetail=true, orderDetail=false, withdrawDetail=true, orderBookDetailDepth=0, prevDetail=false)[0]
//// 定义用户自定义因子
def userDefinedFunc(t){
AvgBuyDuration = rowAvg(t.TradeMDTimeList-t.TradeOrderBuyNoTimeList).int()
AvgSellDuration = rowAvg(t.TradeMDTimeList-t.TradeOrderSellNoTimeList).int()
BuyWithdrawQty = rowSum(t.WithdrawBuyQtyList)
SellWithdrawQty = rowSum(t.WithdrawSellQtyList)
return (AvgBuyDuration, AvgSellDuration, BuyWithdrawQty, SellWithdrawQty)
}
// 定义 orderbook 引擎的输出表,需要包含基础字段(basic),报价/询价的多档价格和数量(depth),userDefinedMetrics 自定义指标的输出结果
outputTableSch = genOutputColumnsForOBSnapshotEngine(basic=true, time=false, depth=(10, true), tradeDetail=false, orderDetail=false, withdrawDetail=false, orderBookDetailDepth=0, prevDetail=false)[1]
colNames = outputTableSch.schema().colDefs.name join (`AvgBuyDuration`AvgSellDuration`BuyWithdrawQty`SellWithdrawQty)
colTypes = outputTableSch.schema().colDefs.typeString join (`INT`INT`INT`INT)
outputTable = table(1:0, colNames, colTypes)
// 创建引擎,每1s计算输出深交所股票10档 orderbook
engine = createOrderBookSnapshotEngine(name="demo", exchange="XSHE", orderbookDepth=10, intervalInMilli = 1000, date=2022.01.10, startTime=09:30:00.000, prevClose=prevClose, dummyTable=dummyOrderStream, outputTable=outputTable, inputColMap=inputColMap, outputColMap=outputColMap, orderBookAsArray=true, userDefinedMetrics=userDefinedFunc)
t = select * from loadText(filePath) order by Time
update t set ReceiveTime = now(true) // 构造接收时间列
getStreamEngine("demo").append!(t)
select top 10 * from outputTable where code="300593.SZ", timestamp between 2022.01.10T13:15:01.000 and 2022.01.10T13:15:10.000
部分结果展示如下:
相关函数:
genOutputColumnsForOBSnapshotEngine
相关教程:
基于逐笔数据合成高频 Orderbook:DolphinDB Orderbook 引擎
附录
basic(基础字段)
不指定
outputColMap
和
userDefinedMetrics
时,输出除 openPrice,maxPrice,minPrice
外的字段。
字段名
类型
说明
code
SYMBOL
证券代码
timestamp
TIMESTAMP
快照时间戳,如以1s间隔合成快照:2022.08.01T09:20:00.000,2022.08.01T09:20:01.000
lastSeq
LONG
最后一条逐笔数据的序号(lastAppSeqNum)
tradingPhaseCode
INT
交易阶段代码(tradingPhaseCode)。枚举值:0(开盘前,启动)、1(开盘集合竞价)、2(开盘集合竞价阶段结束至连续竞价阶段开始之前)、3(连续竞价)、4(中午午休)、5(收盘集合竞价)
modified
BOOL
各证券代码当前周期无输入数据,则对应输出表中的该字段显示为 false,否则显示为 true。
turnover
DOUBLE
当前周期内的成交金额
volume
LONG
当前周期内的成交量
tradeNum
INT
当前周期内的成交笔数
ttlTurnover
DOUBLE
(totalTurnover)开盘到现在的成交金额
ttlVolume
LONG
(totalVolume)开盘到现在的成交量
ttlTradeNum
INT
(totalTradeNum)开盘到现在的成交笔数
lastPrice
DOUBLE
(lastPx)最近成交价
highPrice
DOUBLE
(highPx)开盘到现在的最高价
lowPrice
DOUBLE
(lowPx)开盘到现在的最低价
openPrice
DOUBLE
(openPx)开盘价
avgAskPrice
DOUBLE
(ask)卖出加权平均价 = 卖单的每一档价格*量 / 卖单的总量
avgBidPrice
DOUBLE
(bid)买入加权平均价 = 买单的每一档价格*量 / 买单的总量
askQty
LONG
(askVol)当前卖盘加权挂单量
bidQty
LONG
(bidVol)当前买盘加权挂单量
preClosePrice
DOUBLE/INT
(preClosePx)昨收价。
引擎外部定义昨收价,并以字典的方式传入引擎。
abnormal
BOOL
(invalid)输入数据是否异常:
true 表示输入数据异常,或在设置了
forceTriggerTime
后对不连续的数据进行了强制合成得到的第一批订单簿快照数据及其后续数据;其中,数据异常是指收到了逐笔成交或者撤单,却找不到对应的委托单。
false 表示输入数据正常。
maxPrice
DOUBLE/INT
涨停价。
引擎外部定义涨停价,并以字典的方式传入引擎。
minPrice
DOUBLE/INT
跌停价。
引擎外部定义跌停价,并以字典的方式传入引擎。
time(时间字段)
字段名
类型
说明
mdTime
TIME
快照时间戳,如以1s间隔合成快照:09:20:00.000,09:20:01.000
mdDate
DATE
快照日期。
引擎外部定义快照日期,通过 date 参数传入引擎。
UpdateTime1
NANOTIMESTAMP
触发窗口关闭的那条输入数据的 receiveTime
UpdateTime2
NANOTIMESTAMP
触发窗口关闭后计算完成的系统时刻,即输出计算结果时的系统时间。
depth(报价/询价档位)
不指定
outputColMap
和
userDefinedMetrics
时,会输出 depth 中的所有字段。提供两种方式存储 depth
数据。两种方式只能选其一:
每个档位输出一列。比如 bidsPrice 有10个档位,则会输出10个 bidsPrice
字段:bidsPrice1、bidsPrice2、…、bidsPrice10。
字段名
类型
说明
bidsPrice
DOUBLE (多个)
(bids)多个字段,分别存放多档买入价格,档位由
depth
确定
bidsQty
LONG (多个)
(bidVolumes)多个字段,分别存放多档买入数量,档位由
depth
确定
bidsCount
INT (多个)
(bidOrderNums)多个字段,分别存放多档买入委托笔数,档位由
depth
确定
asksPrice
DOUBLE (多个)
(asks)多个字段,分别存放多档卖出价格,档位由
depth
确定
asksQty
LONG (多个)
(askVolumes)多个字段,分别存放多档卖出数量,档位由
depth
确定
asksCount
INT (多个)
(askOrderNums)多个字段,分别存放多档卖出委托笔数,档位由
depth
确定
多个档位输出到一个列字段,该列的类型为数组向量。比如 bidsPrice
有10个档位,则会将这10个档位以数组向量的形式输出到一个字段:bidsPriceList。
字段名
类型
说明
bidsPriceList
DOUBLE[]
数组向量,存放多档买入价格,档位由
depth
确定
bidsQtyList
LONG[]
数组向量,存放多档买入数量,档位由
depth
确定
bidsCountList
INT[]
数组向量,存放多档买入委托笔数,档位由
depth
确定
asksPriceList
DOUBLE[]
数组向量,存放多档卖出价格,档位由
depth
确定
asksQtyList
LONG[]
数组向量,存放多档卖出数量,档位由
depth
确定
asksCountList
INT[]
数组向量,存放多档卖出委托笔数,档位由
depth
确定
tradeDetail(成交明细)
注:
对于上交所订单簿,若指定参数
includeImmediateExecution
=
true,则委托明细中将会统计即时成交的订单。此时,系统将 trade 记录的成交时间作为 order 的下单时间,并在
tradeOrderBuyNoTimeList/tradeOrderSellNoTimeList 字段中显示。
在调用
genOutputColumnsForOBSnapshotEngine
函数时,当
tradeDetail
=true 时,默认不会输出 tradeBuyOrderTypeList 和
tradeSellOrderTypeList 两个字段。
基础衍生字段
类型
含义
buyQty
LONG
当前周期内的买入总量 = sum(BSFlag=1 的成交量)
sellQty
LONG
当前周期内的卖出总量 = sum(BSFlag=2 的成交量)
buyMoney
DOUBLE
当前周期内的买入总金额 = sum( BSFlag=1 的成交量*价格)
sellMoney
DOUBLE
当前周期内的卖出总金额 = sum( BSFlag=2 的成交量*价格)
tradePriceList
DOUBLE[]
当前周期内成交价格列表
tradeQtyList
LONG[]
当前周期内成交量列表
tradeTypeList
INT[]
当前周期内成交类型列表
tradeBSFlagList
INT[]
当前周期内成交方向列表
tradeMDTimeList
TIME[]
当前周期内成交时间列表
tradeBuyNoList
LONG[]
当前周期内买方委托序号列表
tradeSellNoList
LONG[]
当前周期内卖方委托序号列表
tradeOrderBuyNoTimeList
TIME[]
当前周期内的有效成交对应的委托的买单下单时间
tradeOrderSellNoTimeList
TIME[]
当前周期内的有效成交对应的委托的卖单下单时间
tradeBuyOrderTypeList
INT[]
当前周期内的有效成交对应的委托的买单类型
tradeSellOrderTypeList
INT[]
当前周期内的有效成交对应的委托的卖单类型
orderDetail (委托明细)
注意:对于上交所订单簿,若指定参数
includeImmediateExecution
= true,则委托明细中将会统计即时成交的订单。
基础衍生字段
类型
含义
orderPriceList
DOUBLE[]
当前周期内委托价格列表
orderQtyList
LONG[]
当前周期内委托量列表
orderTypeList
INT[]
当前周期内委托类型列表
orderBSFlagList
INT[]
当前周期内委托方向列表
orderMDTimeList
TIME[]
当前周期内委托时间列表
orderNoList
LONG[]
当前周期内委托序号列表
withdrawDetail(撤单明细)
注:
对于上交所订单簿,若指定参数
includeImmediateExecution
=
true,则委托明细中将会统计即时成交的订单。此时,withdrawBuyOrderQtyList/WithdrawSellOrderQtyList
字段中将包括即时成交的数量。
在调用
genOutputColumnsForOBSnapshotEngine
函数时,当
withdrawDetail
=true 时,默认不会输出 withdrawBuyOrderNoList 和
withdrawSellOrderNoList 两个字段。
基础衍生字段
类型
含义
withdrawBuyPriceList
DOUBLE[]
当前周期内买方撤单的委托价格
withdrawBuyQtyList
LONG[]
当前周期内买方撤单的委托量
withdrawBuyOrderTypeList
INT[]
当前周期内买方撤单的委托的订单类型
withdrawBuyMDTimeList
TIME[]
当前周期内买方撤单的订单时间
withdrawBuyOrderMDTimeList
TIME[]
当前周期内买方撤单对应的委托下单时间
WithdrawBuyOrderQtyList
LONG[]
当前周期内买方撤单对应的原始委托数据中的委托量
withdrawSellPriceList
DOUBLE[]
当前周期内卖方撤单的委托价格
withdrawSellQtyList
LONG[]
当前周期内卖方撤单的委托量
withdrawSellOrderTypeList
INT[]
当前周期内卖方撤单的委托的订单类型
withdrawSellMDTimeList
TIME[]
当前周期内卖方撤单的订单时间
withdrawSellOrderMDTimeList
TIME[]
当前周期内卖方撤单对应的委托下单时间
WithdrawSellOrderQtyList
LONG[]
当前周期内卖方撤单对应的原始委托数据中的委托量
withdrawBuyOrderNoList
LONG[]
当前周期内买方撤单对应的原始委托数据中的订单号
withdrawSellOrderNoList
LONG[]
当前周期内卖方撤单对应的原始委托数据中的订单号
prevDetail(上一笔交易明细)
注:
对于上交所订单簿,若指定参数
includeImmediateExecution
=
true,则委托明细中将会统计即时成交的订单。此时,当即时成交的价格和上一笔快照的价格(BuyPrice1/SellPrice1)相同,则
prevBuyAddQtyList1/prevSellAddQtyList1 字段中将包括即时成交的申购明细。
基础衍生字段
类型
含义
prevBuyPrice1
DOUBLE
上一笔快照的 BuyPrice1 价格
prevSellPrice1
DOUBLE
上一笔快照的 SellPrice1 价格
prevBuyAddQtyList1
LONG[]
价格为上一笔快照的 BuyPrice1,在当前周期内的申购明细
prevSellAddQtyList1
LONG[]
价格为上一笔快照的 SellPrice1,在当前周期内的申购明细
prevBuyWithdrawQtyList1
LONG[]
价格为上一笔快照的 BuyPrice1,在当前周期内的撤单明细
prevSellWithdrawQtyList1
LONG[]
价格为上一笔快照的 SellPrice1,在当前周期内的撤单明细
orderBookDetailDepth( orderbook 明细档位)
每个档位输出一列,该列的类型是数组向量。比如 buyQtyList 有20个档位,则会输出20个 buyQtyList
字段:buyQtyList1、buyQtyList2、…、buyQtyList20。buyValueList,sellQtyList 和 sellValueList
同理。
基础衍生字段
类型
含义
buyQtyList
LONG[](多个)
当前最新盘口各档位买入的每一笔委托的数量
buyValueList
DOUBLE[](多个)
当前最新盘口各档位买入的每一笔委托的金额
sellQtyList
LONG[](多个)
当前最新盘口各档位卖出的每一笔委托的数量
sellValueList
DOUBLE[](多个)
当前最新盘口各档位卖出的每一笔委托的金额
seqDetail(sequence 明细)
注:
对于上交所订单簿,若指定参数
includeImmediateExecution
= true,则委托明细中将会统计即时成交的订单。此时,orderSeqList
字段中将会包含即时成交的委托记录。
基础衍生字段
类型
含义
tradeSeqList
LONG[]
当前周期内的成交序号列表
orderSeqList
LONG[]
当前周期内的委托序号列表
withdrawBuySeqList
LONG[]
当前周期内的买方撤单序号列表
withdrawSellSeqList
LONG[]
当前周期内的卖方撤单序号列表
residualDetail(剩余委托明细)
注意:
卖方字段(ResidualAskPriceList, ResidualAskQtyList, ResidualAskTimeList,
ResidualAskApplSeqNumList)中每个档位的信息按照价格和交易时间升序排序。若价格和交易时间相同,则按数据进入引擎的时间升序排序。
买方字段(ResidualBidPriceList, ResidualBidQtyList, ResidualBidTimeList,
ResidualBidApplSeqNumList)中每个档位的信息按价格降序和交易时间升序排序,若价格和交易时间相同,则按数据进入引擎的时间升序排序。
在调用
genOutputColumnsForOBSnapshotEngine
函数时,当
residualDetail
=true 时,默认不会输出 ResidualBidOrderNoList 和
ResidualAskOrderNoList 两个字段。
字段名
类型
说明
ResidualAskPriceList
DOUBLE[]
卖方剩余委托价格列表
ResidualAskQtyList
LONG[]
卖方剩余委托量列表
ResidualAskTimeList
TIME[]
卖方剩余委托时间列表
ResidualAskApplSeqNumList
LONG[]
卖方剩余委托单 ApplSeqNum 列表
ResidualBidPriceList
DOUBLE[]
买方剩余委托价格列表
ResidualBidQtyList
LONG[]
买方剩余委托量列表
ResidualBidTimeList
TIME[]
买方剩余委托时间列表
ResidualBidApplSeqNumList
LONG[]
买方剩余委托单 ApplSeqNum 列表
ResidualBidOrderNoList
LONG[]
买方剩余委托的订单号
ResidualAskOrderNoList
LONG[]
卖方剩余委托的订单号
FILE:references/doc_8957.md
# getRecoveryTaskStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getRecoveryTaskStatus.html
**来源**: DolphinDB 官方文档
---
getRecoveryTaskStatus
语法
getRecoveryTaskStatus()
详情
查询副本恢复任务的状态。该函数只能在控制节点上执行。
参数
无
返回值
返回一个表,包含以下列:
TaskId:表示恢复副本任务的 ID。
TaskType:恢复任务的类型,包括 LoadRebalance 和 ChunkRecovery 。
ChunkId:分区的 ID。
ChunkPath:分区的 DFS 路径。
Source:恢复数据的源节点,即正常的数据节点。
Dest:需要进行数据恢复的节点(目的节点)。
Status:数据恢复的状态,包括 “Waiting”, “In-Progress”, “Finished”, “Aborted”。
AttemptCount:恢复任务尝试的次数。
DeleteSource:是否删除源节点的数据。当 TaskType 是 ChunkRecovery 时,只能返回 false;当 TaskType 是
LoadRebalance 时,可以返回 true 或 false。
StartTime:创建恢复任务的时间。
LastDequeueTime:任务最后一次从任务队列出队的时间。
LastStartTime:最后一次开始执行任务的时间。
FinishTime:任务结束的时间。
IsIncrementalRecovery:是否启用增量复制。
IsAsyncRecovery:是否启用异步复制。
ChangeFromIncrementalToFull:是否从增量恢复转为全量恢复。系统多次尝试增量恢复失败会自动转换成全量恢复。
ChangeToSyncTime:节点在线恢复时,从异步恢复阶段转为同步恢复阶段的时刻。
FailureReason:recovery 任务失败的原因。
例子
getRecoveryTaskStatus();
FILE:references/doc_8962.md
# lfill!
**URL**: https://docs.dolphindb.cn/zh/funcs/l/lfill_.html
**来源**: DolphinDB 官方文档
---
lfill!
语法
lfill!(obj)
详情
如果
obj
是向量,线性填充两个非空元素之间的 NULL 值。
如果
obj
是表,对于表中的每一列,线性填充两个非空元素之间的 NULL 值。
参数
obj
是数值型向量或只包含数值类型的表。
返回值
返回值的类型和形式与
obj
保持一致。
例子
a= NULL 1.5 NULL NULL 4.5
a.lfill!()
a;
// output
[NULL,1.5,2.5,3.5,4.5]
b=1 NULL NULL 6
b.lfill!()
b;
// output
[1,3,4,6]
t=table(1 NULL NULL 4 5 6 as id,2.1 2.2 NULL NULL 2.4 2.6 as val);
lfill!(t);
t;
id
val
1
2.1
2
2.2
3
2.266667
4
2.333333
5
2.4
6
2.6
相关函数:
bfill
,
bfill!
,
lfill
FILE:references/doc_8969.md
# 交互编程
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db_man/web/Shell.html
**来源**: DolphinDB 官方文档
---
交互编程
交互编程界面包含以下几个部分:编辑器、变量浏览器、日志浏览器、数据浏览器、数据库浏览器。进行数据库相关操作时,需要先登录。点击数据库浏览器页面的“去登录”按钮,进入登录页面,输入用户名和密码进行登录。也可以在代码编辑框中通过函数
login
登录。
在代码编辑框中通过函数
logout
登出,或者点击页面右上角的用户注销按钮进行注销。需要注意的是,函数
logout
仅清除当前连接的登录状态,刷新页面后会自动重新登录;而注销按钮则可以完全退出登录。
下文将介绍交互编程中各个界面的具体功能。
编辑器
在编辑器中,可通过左上角的 ▶ 按钮执行代码、或通过快捷键 "Ctrl"+"E" 执行代码。选中部分(或全部)代码,点击 ▶ 按钮,或按下 "Ctrl"+"E"
按键,便可执行它们。可通过光标定位到某行,按下 "Ctrl"+"E" 按键仅执行这一行代码。若不选中代码,点击 ▶ 按钮便可执行编辑器中的全部代码。
编辑器默认只显示一个标签栏,可根据需要,通过右侧的
+
增加代码编辑标签页。
注:
不能在此使用
print
打印字节数超过 65536 的字符串,如下例:
a = array(STRING,10).append!(string(concat(take(`abcd中文123,100005))));
print a
执行以上脚本后,会导致 Web 断连。需要刷新网页才会重新建立连接。
变量浏览器
Web 端的变量浏览器显示各个数据形式下变量的名称、数据类型、维度和占用空间。
Web 端的变量浏览器与 GUI 中的变量浏览器十分相似。它们唯一的区别是,在 Web 端不能右键单击变量来取消定义、查看表字段类型等。
通过点击变量浏览器的向量/矩阵/内存表,可在数据浏览器查看其数据。分布式表的数据请通过数据库浏览器查看。
数据浏览器
Web 端的数据浏览器显示了编辑器窗口中执行的脚本结果,其与 DolphinDB GUI 中的数据浏览器非常相似。它们的区别如下:
在 GUI 中,我们可以右键点击数据浏览器,在弹出菜单中执行复制,排序,输出等操作;在 Web
端中只能通过光标选中文本复制,不支持排序输出,但支持通过左下角的箭头图标实现小窗查看。
在 Web 端中,我们可以通过右上角用户图表左侧的设置按钮,设置显示的小数位数。
例子:查询
在编辑器中输入并执行以下脚本:
sym = `C`MS`BAC`BK`WFC
price= 75.67 53.24 29.48 54.42 60.92
qty = 2200 1900 2100 3200 1800
t = table(sym, qty, price)
select *, price*qty as volume from t
执行结果将会显示在数据浏览器中:
日志浏览器
日志浏览器显示每个执行的完成时间、耗时、标量形式的执行结果以及执行过程中的错误信息。
执行结果为标量的数据显示在日志浏览器中。结果为其他形式的数据则显示在数据浏览器中。
例如,我们在编辑器中运行 2 + 3,结果将显示在日志浏览器中。在编辑器中运行 2 + [1, 2, 3],结果将显示在数据浏览器中。见下图:
注:
暂不支持清理日志浏览器中的信息。
日志浏览器最多可输出 100,000 行日志。
数据库浏览器
数据库浏览器如下图所示,其提供以下功能:
创建数据库和数据表;
在数据表中添加列并给数据列添加注释;
分层展示已创建的数据库及其所属表的信息。
用户可以通过页面和脚本两种方式创建数据库和数据表:
通过页面创建数据库
点击
图标,打开创建数据库的界面,如下图:
点击“取消”,取消建库操作;点击“清空”,清空上图中所填写内容;点击“预览”,进入脚本预览窗口,可以看到具体的建库语句,如下图:
点击“取消”,取消建库操作;点击“上一步”,返回上一步的建库页面;点击“执行”,创建数据库。成功创建的数据库将显示在左侧的数据库浏览器中。若建库语句不正确,点击执行后会显示报错信息。
通过页面创建数据表
将鼠标悬浮在刚刚创建的数据库名称上,在右侧会显示出创建数据表的图标,见下图:
点击
图标,打开创建数据表的页面:
点击“下一步”,进入创建数据表的脚本预览窗口:
在此页面,点击右上角的
图标,可复制所有脚本;点击“上一步”,返回建表页面;点击“执行”,创建数据表。若成功创建数据表,则出现下图创建成功的提示:
若创建失败,则出现下图,并提示失败原因:
通过脚本创建数据库表
用户也可直接在编辑器中输入代码来创建数据库表。创建成功后,需要点击数据库浏览器左上角的 🔄
按钮,以便在数据库浏览器窗口中查看刚刚创建的数据库、表。
例子:在编辑器中输入并执行以下代码,创建分布式表 pt。
dbName="dfs://test_topic_partition"
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db=database(dbName,VALUE,2012.01.01..2012.01.10)
n=20
date=rand(2012.01.01..2012.01.10, n)
sym=rand("A"+string(1..30), n)
qty=rand(100, n)
t=table(date, sym, qty)
pt=db.createPartitionedTable(t, `pt, `date).append!(t)
如下图所示,在数据库浏览器中,分层展示了各数据库及其所属表。点击变量前的 ➕,可以展示数据表的结构、所包含的列,每列的名称及类型、分区。点击变量前的
➖,折叠展示的内容。
点击数据表变量 pt,在数据浏览器中会展示该表数据。
鼠标悬浮在“列”前,可显示添加列变量的图标,点击该图标进行添加列的操作。
鼠标悬浮在列变量前,可显示添加列注释的图标,点击该图标对该列添加注释。
点击 pt 的结构,会在数据浏览界面中展示它的表结构。点击下图的分区数据,会在数据浏览界面展示该分区所包含的数据。
点击流图数据表右侧按钮可在页面底部查看数据血缘。
注:
productKey
非 ORCA 时需管理员 admin 在
功能设置
页面启用该功能。
FILE:references/doc_8979.md
# setMemLimitOfQueryResult
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setMemLimitOfQueryResult.html
**来源**: DolphinDB 官方文档
---
setMemLimitOfQueryResult
语法
setMemLimitOfQueryResult(memLimit)
详情
在线修改单次查询结果占用的最大内存上限。该命令只能由管理员在数据节点/计算节点执行。
相关函数:
getMemLimitOfQueryResult
参数
memLimit
数值类型标量,表示内存上限,单位为 GB。该值必须小于 80% * maxMemSize。
FILE:references/doc_8982.md
# copy
**URL**: https://docs.dolphindb.cn/zh/funcs/c/copy.html
**来源**: DolphinDB 官方文档
---
copy
语法
copy(obj)
详情
返回
obj
的浅拷贝。即复制最外层结构,内部子对象仍与原对象共享引用。
copy
(浅拷贝)和
deepCopy
(深拷贝)的区别主要体现在嵌套结构(如元组或 ANY
类型字典)中:
使用
copy
时,子对象的引用会被共享(即子对象的地址保持不变)。
使用
deepCopy
时,所有子对象都会被递归复制,引用也会完全分离。
参数
obj
可以是任意数据类型。
返回值
返回
obj
的浅拷贝对象。
例子
例1. 拷贝向量
x = 1 2 3
a = x.copy()
b = x.deepCopy();
print constantDesc(x[0]).address // 000000000dd3d640
print constantDesc(a[0]).address // 000000000cb5a4c0
print constantDesc(b[0]).address // 000000000de92c20
例2. 拷贝元组
x = ([[1, 2], [3, 4]], "a")
a = x.copy()
b = x.deepCopy();
print constantDesc(x[0]).address // 000000000c7ce880
print constantDesc(a[0]).address // 000000000c7ce880
print constantDesc(b[0]).address // 000000000c89be00
例3. 拷贝 ANY 字典
y = dict(`A`B`C, (1 2, 3 4, 5 6))
c = y.copy()
d = y.deepCopy();
print constantDesc(y[`A]).address // 000000000c88c450
print constantDesc(c[`A]).address // 000000000c88c450
print constantDesc(d[`A]).address // 000000000c7cde00
相关函数:
asis
,
deepCopy
FILE:references/doc_8984.md
# attributeValues
**URL**: https://docs.dolphindb.cn/zh/funcs/a/attributevalues.html
**来源**: DolphinDB 官方文档
---
attributeValues
语法
attributeValues(obj)
详情
获取类实例的所有属性及其对应的属性值。
参数
obj
类实例。
返回值
一个字典,key 是属性名称,value 是属性值。
例子
class Person {
name :: STRING
age :: INT
def Person(name_, age_) {
name = name_
age = age_
}
}
p1 = Person("Sam", 12)
attributeValues(p1)
/* output:
name->Sam
age->12
*/
p2 = Person("Andy", 16)
attributeValues(p2)
/* output:
name->Andy
age->16
*/
FILE:references/doc_8989.md
# getInstrumentFixedDayCountConvention
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentfixeddaycountconvention.html
**来源**: DolphinDB 官方文档
---
getInstrumentFixedDayCountConvention
语法
getInstrumentFixedDayCountConvention(instrument)
详情
根据输入的金融工具,获取该工具的固定端日期计数惯例。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
STRING 类型标量或向量。
例子
swap = {
"productType": "Swap",
"swapType": "IrSwap",
"irSwapType": "IrFixedFloatingSwap",
"version": 0,
"start": 2021.05.15,
"maturity": 2023.05.15,
"frequency": "Quarterly",
"fixedRate": 0.02,
"calendar": "CFET",
"fixedDayCountConvention": "Actual365",
"floatingDayCountConvention": "Actual360",
"payReceive": "Pay",
"iborIndex": "SHIBOR_3M",
"spread": 0.0005,
"notional":["CNY", 1E8]
}
instrument = parseInstrument(swap)
getInstrumentFixedDayCountConvention(instrument)
// output: Actual365
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_8999.md
# repmat
**URL**: https://docs.dolphindb.cn/zh/funcs/r/repmat.html
**来源**: DolphinDB 官方文档
---
repmat
语法
repmat(X, rowRep, colRep)
详情
将矩阵
X
竖向重复
rowRep
次,横向重复
colRep
次,产生一个新的矩阵。
参数
X
是一个矩阵。
rowRep
与
colRep
均为正整数。
返回值
一个矩阵。
例子
x=matrix(1 2 3, 4 5 6);
输出返回:
#0
#1
1
4
2
5
3
6
repmat(x, 2, 3);
输出返回:
#0
#1
#2
#3
#4
#5
1
4
1
4
1
4
2
5
2
5
2
5
3
6
3
6
3
6
1
4
1
4
1
4
2
5
2
5
2
5
3
6
3
6
3
6
FILE:references/doc_90.md
# eye
**URL**: https://docs.dolphindb.cn/zh/funcs/e/eye.html
**来源**: DolphinDB 官方文档
---
eye
语法
eye(n)
详情
生成一个维度为
n
的单位矩阵。
参数
n
是一个正整数,表示维度。
返回值
一个 DOUBLE 类型矩阵。
例子
eye(3);
#0
#1
#2
1
0
0
0
1
0
0
0
1
FILE:references/doc_9005.md
# rpc
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rpc.html
**来源**: DolphinDB 官方文档
---
rpc
语法
rpc(nodeAlias, func, args, ...)
详情
在指定的远程节点上调用本地函数,并把结果返回到本地节点。这个函数可以是内置函数或调用节点上的用户自定义函数。函数的参数暂不支持值为函数定义的字典。
调用节点和远程节点必须在同一集群。否则,我们需要使用
remoteRun
函数。详情请参考
BatchJobManagement
。
参数
nodeAlias
是远程节点的别名。
func
是函数,它不能被引用。这个函数可以是内置函数或调用节点上的用户自定义函数。
args
是函数的参数。
返回值
func
执行的结果。
例子
远程调用用户定义函数
rpc("nodeA", def(x,y):x+y, 10, 15)
远程调用部分应用
rpc("nodeA", getRecentJobs{10})
远程调用引用了用户定义函数的内置函数
def jobDemo(n){
s = 0
for (x in 1 : n) {
s += sum(sin rand(1.0, 100000000)-0.5)
print("iteration " + x + " " + s)
}
return s
};
// the node "DFS_NODE2" is located in the same cluster as the local node.
rpc("DFS_NODE2", submitJob, "jobDemo3", "job demo", jobDemo, 10);
// output:
jobDemo3
rpc("DFS_NODE2", getJobReturn, "jobDemo3")
// output:
-3426.577521
FILE:references/doc_9018.md
# gram
**URL**: https://docs.dolphindb.cn/zh/funcs/g/gram.html
**来源**: DolphinDB 官方文档
---
gram
语法
gram(ds, [colNames], [subMean], [normalize])
详情
计算数据源中对应列的数据的格拉姆矩阵。假设数据对应的矩阵为 A,返回的结果为 A 的转置与其自身的点积,即 A.tranpose() dot A。
参数
ds
是一个或多个数据源,通常由
sqlDS
生成。
colNames
是字符串标量或向量,表示数据源中用于计算的列名。默认值是数据源中所有列的列名。
subMean
是一个布尔值,表示每列是否减去该列的均值。默认值为 true。
normalize
是一个布尔值,表示每列是否除以该列的标准差。默认值为 false。
返回值
一个矩阵。
例子
x = [7,1,1,0,5,2]
y = [0.7, 0.9, 0.01, 0.8, 0.09, 0.23]
t=table(x, y)
ds = sqlDS(<select * from t>);
gram(ds);
#0
#1
37.333333
-0.56
-0.56
0.75895
FILE:references/doc_9020.md
# businessYearEnd
**URL**: https://docs.dolphindb.cn/zh/funcs/b/businessYearEnd.html
**来源**: DolphinDB 官方文档
---
businessYearEnd
语法
businessYearEnd(X, [endingMonth=12], [offset],
[n=1])
详情
返回
X
所在年份的最后一个工作日(周一到周五)。
如果指定了
offset
,表示从
offset
开始,结果每隔
n
年更新一次。注意,
offset
和
n
须同时指定,且只有当
n
>1 时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
endingMonth
是1到12之间的整数,表示一年的结束月份。默认值是12。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
businessYearEnd(2012.06.12, 3);
// output
2013.03.29
businessYearEnd(2012.06.12, 9);
// output
2012.09.28
businessYearEnd(2012.06.12);
// output
2012.12.31
businessYearEnd(2012.06.12, 12, 2009.04.03, 2);
// output
2013.12.31
date=2011.04.25+(1..10)*365
time = take(09:30:00, 10)
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
t1;
date
time
sym
qty
price
2012.04.24
09:30:00
MSFT
2200
49.6
2013.04.24
09:30:00
MSFT
1900
29.46
2014.04.24
09:30:00
MSFT
2100
29.52
2015.04.24
09:30:00
MSFT
3200
30.02
2016.04.23
09:30:00
MSFT
6800
174.97
2017.04.23
09:30:00
MSFT
5400
175.23
2018.04.23
09:30:00
MSFT
1300
50.76
2019.04.23
09:30:00
MSFT
2500
50.32
2020.04.22
09:30:00
MSFT
8800
51.29
2021.04.22
09:30:00
MSFT
4500
52.38
select avg(price),sum(qty) from t1 group by businessYearEnd(date, 4, 2010.04.01, 2);
businessYearEnd_date
avg_price
sum_qty
2012.04.30
49.6
2200
2014.04.30
29.49
4000
2016.04.29
102.495
10000
2018.04.30
112.995
6700
2020.04.30
50.805
11300
2022.04.29
52.38
4500
相关函数:
businessYearBegin
,
yearBegin
,
yearEnd
FILE:references/doc_9034.md
# array
**URL**: https://docs.dolphindb.cn/zh/funcs/a/array.html
**来源**: DolphinDB 官方文档
---
array
语法
array(dataType|template, [initialSize], [capacity], [defaultValue])
详情
创建一个向量。
参数
dataType
是向量的数据类型。
template
是一个已有向量。这个已有向量的数据类型决定了新向量的数据类型。
initialSize
是正整数,表示向量的初始长度,即该向量新建时的元素数量。
capacity
是正整数,表示向量的容量,即该向量新建时系统为该向量分配的内存(以元素数为单位)。当元素数超过capacity时,系统会自动扩充容量。系统首先会分配当前容量1.2~2倍的内存,然后复制数据到新的内存空间,最后释放原来的内存。
defaultValue
是向量的默认值。若指定,则只能是标量。若不指定:对于多数数据类型,默认值是 0;对于字符串和符号(Symbol),默认值是
NULL。
返回值
一个向量。
例子
x=array(INT, 10, 100, 1)
// 初始长度是 10;容量是 100;默认值是 1。
x
// output
[1,1,1,1,1,1,1,1,1,1]
x=array(INT, 0)
// 初始化一个空向量
x
// output
[]
x.append!(1..10)
// output
[1,2,3,4,5,6,7,8,9,10]
y=array(x)
y
// output
[0,0,0,0,0,0,0,0,0,0]
syms=array(SYMBOL, 0, 100)
// 一个空的符号向量,容量是 100.
typestr syms
// output
FAST SYMBOL VECTOR
FILE:references/doc_9058.md
# randGamma
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randGamma.html
**来源**: DolphinDB 官方文档
---
randGamma
语法
randGamma(shape, scale, count)
详情
生成指定个数的 Gamma 分布随机数。
参数
形状参数
shape
是正数。
形状参数
scale
是正数。
count
是正整数,表示生成的随机数个数。
返回值
长度为
count
的 DOUBLE 类型向量。
例子
randGamma(2.31, 0.671, 2);
// output
[0.784424, 0.716934]
FILE:references/doc_9061.md
# gaussianKde
**URL**: https://docs.dolphindb.cn/zh/funcs/g/gaussiankde.html
**来源**: DolphinDB 官方文档
---
gaussianKde
语法
gaussianKde(X,[weights],[bwMethod="scott"])
详情
使用核密度估计方法中的高斯核来估计随机变量的概率密度。
生成的模型可以作为
gaussianKdePredict
函数的输入。
参数
X
数值向量、矩阵、元组或表类型,表示给定的数据集合。
X
的每一行表示一个数据点,元素数量至少为 2(即数据点的维度至少为
2),各数据点的维度保持一致,且
X
的行数须大于列数。暂时不支持分布式表。
weights
数值向量类型,可选参数,表示每一个数据点的权重,默认每个数据点的权重相同。向量中数值必须非负且不全为0;且向量大小须和
X
的行数相同。
bwMethod
数值标量,字符串标量或函数名类型,可选参数,表示带宽的生成方式。默认值为”scott”。
若传入数值标量,则表示带宽的大小。
若传入字符串标量类型,可选值为”scott”和”silverman”。
若传入函数,表示用于计算带宽的函数,其输入值为已传入的参数
X
,执行后得到带宽的值。注意:返回值须为数值标量。
返回值
返回一个字典,字典的内容有:
X:浮点型向量或矩阵,表示输入的数据集合
X
。
cov:浮点型矩阵,表示的是通过
weights
、
X
和带宽生成的协方差矩阵的 cholesky 分解矩阵。
weights:浮点型向量,表示对应的权重。
predict:函数指针,表示对应的预测函数。其使用方法为
model.gaussianKdePredict(model,X)
,详情见
gaussianKdePredict。
bandwidth:浮点型标量,表示的生成的带宽。
例子
下例传入指定的
trainset.txt
,使用高斯核估计来预测数据的概率密度。
trainData = loadText("trainset.txt"," ");
model = gaussianKde(trainData)
model
/* Output
X->
#0 #1
0.1460 -0.1659
-1.3717 -1.6650
-1.6957 -1.1680
-0.7976 0.6081
0.1088 2.5113
-0.0724 -0.8210
-1.7548 -0.3485
1.1202 0.9004
1.0234 0.7907
-0.4256 0.7169
predict->gaussianKdePredict
cov->
#0 #1
0.7040 0.0
0.4921 0.6700
weights->[0.1000,0.1000,0.1000,0.1000,0.1000,0.1000,0.1000,0.1000,0.1000,0.1000]
bandwidth->0.6812
*/
承接上例,传入
testset.txt
文件,
gaussianKde
可与
gaussianKdePredict
函数结合使用,生成其对应的预测结果。
testData = loadText("testset.txt"," ");
model.predict(testData)
/* Output
->[0.0623,0.0730,0.0336,0.0030,0.0001,0.0552....]
*/
相关函数:
gaussianKdePredict
FILE:references/doc_9068.md
# semiannualEnd
**URL**: https://docs.dolphindb.cn/zh/funcs/s/semiannualEnd.html
**来源**: DolphinDB 官方文档
---
semiannualEnd
语法
semiannualEnd(X, [endingMonth=12], [offset],
[n=1])
详情
返回
X
所在半年期的最后一天。每半年包含的月份由参数
endingMonth
决定。
如果指定了
offset
,表示从
offset
开始,结果每隔 n 个半年期更新一次。注意,offset 和 n 须同时指定,且只有当
n
> 1 时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP 类型的标量或向量。
endingMonth
是 1 到 12 之间的整数,表示一年的结束月份。默认值是 12。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为 1。
返回值
DATE 类型标量。
例子
semiannualEnd(2025.08.10);
// output: 2025.12.31
semiannualEnd(2025.10.10 10:10:10.008, 3);
// output: 2026.03.31
date=[2024.04.20,2024.05.31,2024.07.07,2024.10.24,2024.12.20,2025.01.19,2025.04.24,2025.04.28,2025.10.06,2026.01.06]
sym = take(`AAA,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, sym, qty, price);
select avg(price),sum(qty) from t1 group by semiannualEnd(date, 12, 2024.01.01, 2)
semiannualEnd_date
avg_price
sum_qty
2024.06.30
39.53
4,100
2025.06.30
85.13666666666667
21,300
2026.06.30
51.835
13,300
FILE:references/doc_9069.md
# mcovarTopN
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mcovarTopN.html
**来源**: DolphinDB 官方文档
---
mcovarTopN
语法
mcovarTopN(X, Y, S, window, top, [ascending=true],
[tiesMethod='oldest'])
参数说明和窗口计算规则请参考:
mTopN
详情
在给定长度(以元素个数衡量)的滑动窗口内,根据
ascending
指定的排序方式将
X
和
Y
按照
S
进行稳定排序后,取前
top
个元素,然后计算
Y
和
X
的协方差。
返回值
计算结果为 DOUBLE 类型,形式同输入参数。
例子
x = NULL 3 8 4 0
y = 2 3 1 7 3
s = 5 NULL 8 9 4
mcovarTopN(x, y, s, 3, 2)
// output: [ , , , -12, -8]
s2=2021.01.01 2021.02.03 2021.01.23 2021.04.06 2021.12.29
mcovarTopN(x, y, s2, 3, 2)
// output: [ , , , -5, -12]
x1 = matrix(x, 4 3 6 2 3)
y1=matrix(3 7 9 3 2, y)
s1=matrix(2 3 1 7 3, s)
mcovarTopN(x, y1, s1, 3, 2)
col1
col2
5
-5
28
-8
mcovarTopN(x1, y1, s, 3, 2)
col1
col2
-0.5
-0.5
5
-3
28
-3
mcovarTopN(x1, y1, s1, 3, 2)
col1
col2
-0.5
-0.5
5
-3
28
-3
n = 3000
ids = 1..3000
dates = take(2021.01.01..2021.10.01,n)
prices = rand(1000,n)
vals = rand(1000,n)
t = table(ids as id,dates as date,prices as price,vals as val)
dbName = "dfs://test_mcovarTopN_2"
if(existsDatabase(dbName))dropDB(dbName)
db = database(dbName,VALUE,1..5000)
pt = db.createPartitionedTable(t,"pt",`id).append!(t)
select mcovarTopN(price, val, id, 10, 5, true) from pt where date>2021.05.01
相关函数:
mcovar
FILE:references/doc_907.md
# cbrt
**URL**: https://docs.dolphindb.cn/zh/funcs/c/cbrt.html
**来源**: DolphinDB 官方文档
---
cbrt
语法
cbrt(X)
详情
返回
X
的立方根。
参数
X
可以是标量、数据对、向量、矩阵或表。
返回值
DOUBLE 类型,数据形式同
X
。
例子
cbrt(8);
// output
2
cbrt(8 12 16);
// output
[2,2.289428,2.519842]
cbrt(1..6$2:3);
0
1
2
1
1.44225
1.709976
1.259921
1.587401
1.817121
FILE:references/doc_9075.md
# toUTF8
**URL**: https://docs.dolphindb.cn/zh/funcs/t/toUTF8.html
**来源**: DolphinDB 官方文档
---
toUTF8
语法
toUTF8(str, encode)
详情
把字符串转换为 UTF8 编码。DolphinDB 对编码名称的大小写敏感,所有编码名称必须用小写表示。
因为 Windows 版本目前仅支持 gbk 和 utf-8 两种编码的相互转换,因此在 Windows
中,
toUTF8
的第二个参数只能是 "gbk"。Linux 版本支持任意两种编码之间的转换。
参数
str
是一个字符串标量或向量。
encode
是一个字符串,表示
str
原来的编码名称。
返回值
STRING 类型标量或向量。
例子
toUTF8("DolphinDB","gbk");
// output
DolphinDB
toUTF8(["hello","world"],"euc-cn");
// output
["hello","world"]
相关函数:
convertEncode
,
fromUTF8
FILE:references/doc_9086.md
# unloadVocab
**URL**: https://docs.dolphindb.cn/zh/funcs/u/unloadVocab.html
**来源**: DolphinDB 官方文档
---
unloadVocab
语法
unloadVocab([vocabName])
详情
从内存中删除已加载的词库。
参数
vocabName
可选参数,字符串标量,指定要删除的词库名称。若不指定,则删除所有词库。
返回值
无。
例子
unloadVocab("vocab1")
相关函数:
loadVocab
,
tokenizeBert
FILE:references/doc_909.md
# size
**URL**: https://docs.dolphindb.cn/zh/funcs/s/size.html
**来源**: DolphinDB 官方文档
---
size
语法
size(X)
详情
对于向量或矩阵,
size
返回元素的个数,而
count
返回的是非 NULL 元素个数。
对于内存表,
size
返回行数。
参数
X
可以是标量、向量、矩阵或表。
返回值
INT 类型标量。
例子
size(3 NULL 5 6);
// output
4
count(3 NULL 5 6);
// output
3
m=1 2 3 NULL 4 5$2:3;
m;
#0
#1
#2
1
3
4
2
5
size(m);
// output
6
count(m);
// output
5
t = table(1 NULL 3 as id, 3 NULL 9 as qty);
t;
id
qty
1
3
3
9
size(t);
// output
3
count(t);
// output
3
FILE:references/doc_9091.md
# maxPositiveStreak
**URL**: https://docs.dolphindb.cn/zh/funcs/m/maxPositiveStreak.html
**来源**: DolphinDB 官方文档
---
maxPositiveStreak
语法
maxPositiveStreak(X)
详情
如果
X
是向量,返回
X
中连续的正数之和的最大值。
如果
X
是矩阵,返回
X
中每列连续的正数之和的最大值。
maxPositiveStreak(X) = max(cumPositiveStreak(X))
参数
X
可以是标量、向量或矩阵。
X
中的元素必须是 INTEGRAL 或 LOGICAL 类型。
返回值
整型标量或向量。
例子
x=1 0 -1 1 2 2 2 1 0 -1 0 2;
cumPositiveStreak x;
// output: [1,0,0,1,3,5,7,8,0,0,0,2]
maxPositiveStreak x;
// output: 8
y=x$6:2;
y;
#0
#1
1
2
0
1
-1
0
1
-1
2
0
2
2
cumPositiveStreak(y);
#0
#1
1
2
0
3
0
0
1
0
3
0
5
2
maxPositiveStreak(y);
// output: [5,3]
相关函数:
cumPositiveStreak
FILE:references/doc_91.md
# setIndexedMatrix!
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setIndexedMatrix_.html
**来源**: DolphinDB 官方文档
---
setIndexedMatrix!
语法
setIndexedMatrix!(X, [on=true])
详情
将矩阵的行与列标签设为索引。
参数
X
是一个有行与列标签的矩阵。行与列标签均须严格递增,无重复项。
on
布尔值,表示普通矩阵和索引矩阵之间的转换。默认为 true,表示将普通矩阵转换成索引矩阵;若为 false,表示将索引矩阵转换为普通矩阵。
返回值
返回一个矩阵或索引矩阵。
例子
m=matrix(1..5, 11..15)
m.rename!(2020.01.01..2020.01.05, `A`B)
m.setIndexedMatrix!();
A
B
2020.01.01
1
11
2020.01.02
2
12
2020.01.03
3
13
2020.01.04
4
14
2020.01.05
5
15
FILE:references/doc_911.md
# writeBytes
**URL**: https://docs.dolphindb.cn/zh/funcs/w/writeBytes.html
**来源**: DolphinDB 官方文档
---
writeBytes
语法
writeBytes(handle, bytes)
详情
writeBytes
函数把整个缓冲区写入文件。缓冲区必须是一个字符标量或字符向量。如果操作成功,函数返回实际写入的字节数;否则,抛出一个 IOException。
返回值
整型标量。
例子
// 定义一个文件复制函数
def fileCopy(source, target){
s = file(source)
len = s.seek(0,TAIL)
s.seek(0,HEAD)
t = file(target,"w")
if(len==0) return
do{
buf = s.readBytes(min(len,1024))
t.writeBytes(buf)
len -= buf.size()
}while(len)
};
fileCopy("test.txt","testcopy.txt");
FILE:references/doc_9111.md
# loop
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/loop.html
**来源**: DolphinDB 官方文档
---
loop
语法
loop(func, args...)
或
func:U(args…)
或
func:U X
或
X func:U Y
详情
loop 高阶函数与 each 高阶函数很相似,区别在于函数返回值的格式和类型。ploop 是相应的并行版本。
each 高阶函数根据每个子任务计算结果的数据类型和形式,决定返回值的数据形式。若所有子任务的数据类型和形式都相同, 则返回
Vector 或 Matrix,否则返回 Tuple。而 loop 总是返回 Tuple。
参数
func
是一个函数。
args/X/Y
是
func
的参数。
返回值
一个元组。
例子
函数入参是矩阵时:
m=matrix([1 3 4 2,1 2 2 1])
max:U(m)
返回:(4,2)
n=matrix([11 5 9 2,8 5 3 2])
m add:U n
返回:([12,8,13,4],[9,7,5,3])
函数入参是数组向量时:
a=array(INT[], 0, 10).append!([1 2 3, 4 5 4, 6 7 8, 1 9 10]);
sum:U(a)
返回:(6,13,21,20)
下例中,通过 loop 函数将数组转换为元组。
a=[1,2,3,4,5]
asis:U(a)
返回:(1,2,3,4,5)
FILE:references/doc_9113.md
# fTest
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fTest.html
**来源**: DolphinDB 官方文档
---
fTest
语法
fTest(X, Y, [ratio=1.0], [confLevel=0.95])
详情
对
X
和
Y
进行 F 检验。
参数
X
是一个数值向量,表示用于F检验的样本。
Y
是一个数值向量,表示用于独立双样本F检验的另一个样本。它是可选参数。
ratio
是一个大于0的浮点数,表示X和Y方差的比例的假设值。默认值是1.0。
confLevel
是0到1之间的浮点数,表示置信区间的置信水平。
返回值
一个字典,包含以下 key:
numeratorDf:分子的自由度
stat:一张表,包含三种不同备择假设下的 p 值和置信区间
denominatorDf:分母的自由度
confLevel:置信水平
fValue:F 统计量
method:字符串 "F test to compare two variances"
例子
x = norm(10.0, 1.0, 20);
y = norm(1.0, 2.0, 10);
fTest(x, y, 0.5);
// output
numeratorDf->19
stat->
alternativeHypothesis pValue lowerBound upperBound
-------------------------------------- --------- ---------- ----------
ratio of variances is not equal to 0.5 0.002326 0.025844 0.274161
ratio of variances is less than 0.5 0.001163 0 0.230624
ratio of variances is greater than 0.5 0.998837 0.032295 Infinity
denominatorDf->9
confLevel->0.95
fValue->0.190386
method->F test to compare two variances
FILE:references/doc_9126.md
# quantileSeries
**URL**: https://docs.dolphindb.cn/zh/funcs/q/quantileSeries.html
**来源**: DolphinDB 官方文档
---
quantileSeries
语法
quantileSeries(X, q, [interpolation='linear'])
详情
计算
X
的分位数。
参数
X
是一个数值型向量。
q
是0到1之间的浮点型标量或向量。
interpolation
是一个字符串,表示当选中的分位点位于 i 和 j 之间时,采用的插值方法。它具有以下取值:
'linear': i+(j-1)*fraction, fraction 是 size(X)*q
的小数部分
'lower':i
'higher': j
'nearest': i 和 j 之中最接近分位点的数据
'midpoint': (i+j)/2
如果没有指定
interpolation
,默认采用 'linear'。
返回值
DOUBLE 类型向量,表示计算结果。
例子
a=[6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36];
quantileSeries(a,[0.25,0.5,0.75]);
// output
[25.5,40,42.5]
quantileSeries(a,[0.25,0.5,0.75], 'higher');
// output
[36,40,43]
相关函数:
quantile
FILE:references/doc_9130.md
# getEnv
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getEnv.html
**来源**: DolphinDB 官方文档
---
getEnv
语法
getEnv(name, [default])
详情
查询指定环境变量的值。如果环境变量不存在,则返回 default 参数。
参数
name
是字符串标量,表示环境变量名称。
default
是字符串标量,表示不存在对应的环境变量时返回的默认值。如果没有指定 default,默认值为空字符串。
返回值
字符串标量。
例子
getEnv("path")
返回:
C:\ProgramData\DockerDesktop\version-bin;C:\Program
Files\Docker\Docker\Resources\bin;
getEnv("JAVA_HOME");
返回:
C:\Program Files\Java\jdk1.8.0_191
getEnv("not_exist","not exist")
返回:
not exist
FILE:references/doc_9131.md
# order by
**URL**: https://docs.dolphindb.cn/zh/progr/sql/orderby.html
**来源**: DolphinDB 官方文档
---
order by
详情
根据order by指定的列,对结果排序。
用法
order by col [asc | desc] [nulls first | nulls last]
其中:
[asc | desc] 指定按升序或降序对数据进行排序。若不指定,则默认为升序。
[nulls first | nulls last] 指定空值放在排序查询结果的最前面或最后面。
在查询分布式表时,不支持对 col 使用序列函数和自定义函数。
注:
指定 nulls first/last 时,必须要指定 asc/desc。
例子
sym = `C`MS`MS`MS`IBM`IBM`C`C`C$SYMBOL
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
t1 = table(timestamp, sym, qty, price);
t1;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
select * from t1 order by sym, timestamp;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
可使用"
desc
"关键字进行降序排序。
select * from t1 where sym in `C`IBM order by sym, timestamp desc;
timestamp
sym
qty
price
09:38:12
C
8800
51.29
09:34:26
C
2500
50.32
09:34:16
C
1300
50.76
09:34:07
C
2200
49.6
09:35:26
IBM
5400
175.23
09:32:47
IBM
6800
174.97
t = table(5 3 NULL NULL 1 6 8 as id, 1 2 3 4 5 6 7 as val)
select * from t order by id asc nulls last
id
val
1
5
3
2
5
1
6
6
8
7
3
4
t = table(5 3 NULL NULL 1 6 8 as id, 1 2 3 4 5 6 7 as val)
select * from t order by id asc nulls first
id
val
3
4
1
5
3
2
5
1
6
6
8
7
FILE:references/doc_9132.md
# ifNull
**URL**: https://docs.dolphindb.cn/zh/funcs/i/ifNull.html
**来源**: DolphinDB 官方文档
---
ifNull
语法
ifNull(X, Y)
详情
判断
X
是否为空。
参数
X
可以是标量、数据对、向量或矩阵。
Y
可以是标量、数据对、向量或矩阵。
X
和
Y
必须具有相同的数据类型。
返回值
如果
X
为 NULL,则返回
Y
的值
如果
X
为非 NULL,则返回
X
的值
例子
x = take(1..5 join NULL 6,7)
y = 1..7
ifNull(x,y)
// output: [1,2,3,4,5,,7]
y1 = int(take(1..5 join int(),6))$2:3
x1 = int(take(100,6))$2:3
ifNull(x1,y1)
/* output:
#0 #1 #2
-- -- --
1 3 5
2 4
*/
若
X
为向量,
Y
为 n 行 m 列的矩阵,则
X
的长度为 n*m
m=int(take(1..4 join NULL 8,6))
ifNull(m,y1)
// output: [1,2,3,4,,]
FILE:references/doc_9138.md
# getNodeType
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getNodeType.html
**来源**: DolphinDB 官方文档
---
getNodeType
语法
getNodeType()
详情
查询节点的类型。0表示数据节点;1表示代理节点;2表示控制器节点;3表示单节点模式;4表示计算节点。
参数
无
返回值
INT 类型标量。
例子
getNodeType();
// output: 2
FILE:references/doc_914.md
# K 线计算
**URL**: https://docs.dolphindb.cn/zh/tutorials/OHLC.html
**来源**: DolphinDB 官方文档
---
K 线计算
DolphinDB 提供了功能强大的内存计算引擎,内置时间序列函数,分布式计算以及流数据处理引擎,在众多场景下均可高效的计算K线。本教程将介绍DolphinDB如何通过批量处理和流式处理计算K线。
计算历史数据 K 线:可以指定K线窗口的起始时间;一天中可以存在多个交易时段,包括隔夜时段;K线窗口可重叠;使用交易量作为划分K线窗口的维度。需要读取的数据量特别大并且需要将结果写入数据库时,可使用DolphinDB内置的Map-Reduce函数并行计算。
实时计算 K 线:使用API实时接收市场数据,并使用DolphinDB内置的流数据时序计算引擎(time-series aggregator)进行实时计算得到K线数据。
1. 历史数据 K 线计算
使用历史数据计算K线,可使用DolphinDB的内置函数
bar
,
dailyAlignedBar
或
wj
。
1.1. 不指定 K 线窗口的起始时刻
这种情况可使用
bar
函数。bar(X,Y)返回X减去X除以Y的余数(X-mod(X,Y)),一般用于将数据分组。如下例所示。
date = 09:32m 09:33m 09:45m 09:49m 09:56m 09:56m;
bar(date, 5);
返回结果:
[09:30m,09:30m,09:45m,09:45m,09:55m,09:55m]
例子1
:使用以下数据模拟美国股票市场:
n = 1000000
date = take(2019.11.07 2019.11.08, n)
time = (09:30:00.000 + rand(int(6.5*60*60*1000), n)).sort!()
timestamp = concatDateTime(date, time)
price = 100+cumsum(rand(0.02, n)-0.01)
volume = rand(1000, n)
symbol = rand(`AAPL`FB`AMZN`MSFT, n)
trade = table(symbol, date, time, timestamp, price, volume).sortBy!(`symbol`timestamp)
undef(`date`time`timestamp`price`volume`symbol)
计算5分钟K线:
barMinutes = 5
OHLC = select first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume from trade group by symbol, date, bar(time, barMinutes*60*1000) as barStart
请注意,以上数据中,time列的精度为毫秒。若time列精度不是毫秒,则应当将 barMinutes*60*1000 中的数字做相应调整。
1.2. 指定 K 线窗口的起始时刻
需要指定K线窗口的起始时刻,可使用
dailyAlignedBar
函数。该函数可处理每日多个交易时段,亦可处理隔夜时段。
请注意,使用
dailyAlignedBar
函数时,时间列必须含有日期信息,包括 DATETIME, TIMESTAMP 或 NANOTIMESTAMP 这三种类型的数据。指定每个交易时段起始时刻的参数 timeOffset 必须使用相应的去除日期信息之后的 SECOND,TIME 或 NANOTIME 类型的数据。
例子2
(每日一个交易时段):计算美国股票市场 7 分钟 K 线。数据沿用例子 1 中的 trade 表。
barMinutes = 7
OHLC = select first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume from trade group by symbol, dailyAlignedBar(timestamp, 09:30:00.000, barMinutes*60*1000) as barStart
例子3
(每日两个交易时段):中国股票市场每日有两个交易时段,上午时段为 9:30 至 11:30,下午时段为 13:00 至 15:00。
使用以下脚本产生模拟数据:
n = 1000000
date = take(2019.11.07 2019.11.08, n)
time = (09:30:00.000 + rand(2*60*60*1000, n/2)).sort!() join (13:00:00.000 + rand(2*60*60*1000, n/2)).sort!()
timestamp = concatDateTime(date, time)
price = 100+cumsum(rand(0.02, n)-0.01)
volume = rand(1000, n)
symbol = rand(`600519`000001`600000`601766, n)
trade = table(symbol, timestamp, price, volume).sortBy!(`symbol`timestamp)
undef(`date`time`timestamp`price`volume`symbol)
计算 7 分钟 K 线:
barMinutes = 7
sessionsStart=09:30:00.000 13:00:00.000
OHLC = select first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume from trade group by symbol, dailyAlignedBar(timestamp, sessionsStart, barMinutes*60*1000) as barStart
例子4
(每日两个交易时段,包含隔夜时段):某些期货每日有多个交易时段,且包括隔夜时段。本例中,第一个交易时段为上午 8:45 到下午 13:45,另一个时段为隔夜时段,从下午 15:00 到第二天上午 05:00。
使用以下脚本产生模拟数据:
daySession = 08:45:00.000 : 13:45:00.000
nightSession = 15:00:00.000 : 05:00:00.000
n = 1000000
timestamp = rand(concatDateTime(2019.11.06, daySession[0]) .. concatDateTime(2019.11.08, nightSession[1]), n).sort!()
price = 100+cumsum(rand(0.02, n)-0.01)
volume = rand(1000, n)
symbol = rand(`A120001`A120002`A120003`A120004, n)
trade = select * from table(symbol, timestamp, price, volume) where timestamp.time() between daySession or timestamp.time()>=nightSession[0] or timestamp.time()<nightSession[1] order by symbol, timestamp
undef(`timestamp`price`volume`symbol)
计算7分钟K线:
barMinutes = 7
sessionsStart = [daySession[0], nightSession[0]]
OHLC = select first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume from trade group by symbol, dailyAlignedBar(timestamp, sessionsStart, barMinutes*60*1000) as barStart
1.3. 重叠 K 线窗口
以上例子中,K 线窗口均不重叠。若要计算重叠K线窗口,可以使用
wj
函数对左表中的每一行,在右表中截取一段窗口,进行计算。
例子5
(每日两个交易时段,重叠的K线窗口):模拟中国股票市场数据,每5分钟计算30分钟K线。
n = 1000000
sampleDate = 2019.11.07
symbols = `600519`000001`600000`601766
trade = table(take(sampleDate, n) as date,
(09:30:00.000 + rand(7200000, n/2)).sort!() join (13:00:00.000 + rand(7200000, n/2)).sort!() as time,
rand(symbols, n) as symbol,
100+cumsum(rand(0.02, n)-0.01) as price,
rand(1000, n) as volume)
首先生成窗口,并且使用
cj
函数来生成股票和交易窗口的组合。
barWindows = table(symbols as symbol).cj(table((09:30:00.000 + 0..23 * 300000).join(13:00:00.000 + 0..23 * 300000) as time))
然后使用
wj
函数计算重叠窗口的K线数据:
OHLC = wj(barWindows, trade, 0:(30*60*1000),
<[first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume]>, `symbol`time)
1.4. 使用交易量划分K线窗口
上面的例子我们均使用时间作为划分K线窗口的维度。在实践中,也可以使用其他变量,譬如用累计的交易量作为划分K线窗口的依据。
例子6
(使用累计的交易量计算K线):交易量每增加1000000计算一次 K 线。
n = 1000000
sampleDate = 2019.11.07
symbols = `600519`000001`600000`601766
trade = table(take(sampleDate, n) as date,
(09:30:00.000 + rand(7200000, n/2)).sort!() join (13:00:00.000 + rand(7200000, n/2)).sort!() as time,
rand(symbols, n) as symbol,
100+cumsum(rand(0.02, n)-0.01) as price,
rand(1000, n) as volume)
volThreshold = 1000000
t = select first(time) as barStart, first(price) as open, max(price) as high, min(price) as low, last(price) as close, last(cumvol) as cumvol
from (select symbol, time, price, cumsum(volume) as cumvol from trade context by symbol)
group by symbol, bar(cumvol, volThreshold) as volBar
代码采用了嵌套查询的方法。子查询为每个股票生成累计的交易量cumvol,然后在主查询中根据累计的交易量用
bar
函数生成窗口。
1.5. 使用 MapReduce 函数加速
若需从数据库中提取较大量级的历史数据,计算K线,然后存入数据库,可使用DolphinDB内置的Map-Reduce函数
mr
进行数据的并行读取与计算。这种方法可以显著提高速度。
本例使用美国股票市场的交易数据。原始数据存于"dfs://TAQ"数据库的"trades"表中。"dfs://TAQ"数据库采用复合分区:基于交易日期Date的值分区与基于股票代码Symbol的范围分区。
(1) 将存于磁盘的原始数据表的元数据载入内存:
login(`admin, `123456)
db = database("dfs://TAQ")
trades = db.loadTable("trades")
(2) 在磁盘上创建一个空的数据表,以存放计算结果。以下代码建立一个模板表(model),并根据此模板表的schema在数据库"dfs://TAQ"中创建一个空的 OHLC 表以存放K线计算结果:
model=select top 1 Symbol, Date, Time.second() as bar, PRICE as open, PRICE as high, PRICE as low, PRICE as close, SIZE as volume from trades where Date=2007.08.01, Symbol=`EBAY
if(existsTable("dfs://TAQ", "OHLC"))
db.dropTable("OHLC")
db.createPartitionedTable(model, `OHLC, `Date`Symbol)
(3) 使用
mr
函数计算K线数据,并将结果写入 OHLC 表中:
def calcOHLC(inputTable){
tmp=select first(PRICE) as open, max(PRICE) as high, min(PRICE) as low, last(PRICE) as close, sum(SIZE) as volume from inputTable where Time.second() between 09:30:00 : 15:59:59 group by Symbol, Date, 09:30:00+bar(Time.second()-09:30:00, 5*60) as bar
loadTable("dfs://TAQ", `OHLC).append!(tmp)
return tmp.size()
}
ds = sqlDS(<select Symbol, Date, Time, PRICE, SIZE from trades where Date between 2007.08.01 : 2019.08.01>)
mr(ds, calcOHLC, +)
ds是函数
sqlDS
生成的一系列数据源,每个数据源代表从一个数据分区中提取的数据。
自定义函数
calcOHLC
为Map-Reduce算法中的map函数,对每个数据源计算K线数据,并将结果写入数据库,返回写入数据库的K线数据的行数。
"+"是Map-Reduce算法中的reduce函数,将所有map函数的结果,亦即写入数据库的K线数据的行数相加,返回写入数据库的K线数据总数。
2. 实时K线计算
DolphinDB 中计算实时 K 线的流程如下图所示:
实时数据供应商一般会提供基于Python、Java或其他常用语言的API的数据订阅服务。本例中使用Python来模拟接收市场数据,通过DolphinDB Python API写入流数据表中。DolphinDB的流数据时序聚合引擎可按照指定的频率与移动窗口实时计算K线。
本例使用的模拟实时数据源为文本文件
trades.csv
。该文件包含以下4列(附带一行样本数据):
Symbol
Datetime
Price
Volume
000001
2018.09.03T09:30:06
10.13
4500
以下三小节介绍实时K线计算的三个步骤:
2.1. 使用 Python 接收实时数据,并写入DolphinDB 流数据表
DolphinDB 中建立流数据表
share streamTable(100:0, `Symbol`Datetime`Price`Volume,[SYMBOL,DATETIME,DOUBLE,INT]) as Trade
将模拟数据写入DolphinDB流数据表
实时数据中Datetime的数据精度是秒,由于pandas DataFrame中仅能使用DateTime[64]即DolphinDB中的nanotimestamp类型,所以下列代码在写入前有一个数据类型转换的过程。
import
dolphindb
as
ddb
import
pandas
as
pd
import
numpy
as
np
csv_file =
"trades.csv"
csv_data = pd.read_csv(csv_file, dtype={
'Symbol'
:str} )
csv_df = pd.DataFrame(csv_data)
s = ddb.session();
s.connect(
"127.0.0.1"
,
8848
,
"admin"
,
"123456"
)
#上传DataFrame到DolphinDB,并对Datetime字段做类型转换
s.upload({
"tmpData"
:csv_df})
s.run(
"data = select Symbol, datetime(Datetime) as Datetime, Price, Volume from tmpData"
)
s.run(
"tableInsert(Trade,data)"
)
2.2. 实时计算K线
可使用移动窗口实时计算K线数据,一般分为以下2种情况:
仅在每次时间窗口结束时触发计算。
时间窗口完全不重合,例如每隔5分钟计算过去5分钟的K线数据。
时间窗口部分重合,例如每隔1分钟计算过去5分钟的K线数据。
在每个时间窗口结束时触发计算,同时在每个时间窗口内数据也会按照一定频率更新。
例如每隔1分钟计算过去1分钟的K线数据,但最近1分钟的K线不希望等到窗口结束后再计算。希望每隔1秒钟更新一次。
下面针对上述的几种情况分别介绍如何使用
createTimeSeriesAggregator
函数实时计算K线数据。请根据实际需要选择相应场景创建时间序列聚合引擎。
2.2.1. 仅在每次时间窗口结束时触发计算
时间窗口不重合,可将
createTimeSeriesAggregator
函数的windowSize参数和step参数设置为相同值。时间窗口部分重合,可将windowSize参数设为大于step参数。请注意,windowSize必须是step的整数倍。
场景一:每隔 5 分钟计算过去 5 分钟的 K 线数据。
share streamTable(100:0, `datetime`symbol`open`high`low`close`volume,[DATETIME,SYMBOL,DOUBLE,DOUBLE,DOUBLE,DOUBLE,LONG]) as OHLC1
tsAggr1 = createTimeSeriesAggregator(name="tsAggr1", windowSize=300, step=300, metrics=<[first(Price),max(Price),min(Price),last(Price),sum(volume)]>, dummyTable=Trade, outputTable=OHLC1, timeColumn=`Datetime, keyColumn=`Symbol)
subscribeTable(tableName="Trade", actionName="act_tsAggr1", offset=0, handler=append!{tsAggr1}, msgAsTable=true);
场景二:每隔 1 分钟计算过去 5 分钟的 K 线数据。
share streamTable(100:0, `datetime`symbol`open`high`low`close`volume,[DATETIME,SYMBOL,DOUBLE,DOUBLE,DOUBLE,DOUBLE,LONG]) as OHLC2
tsAggr2 = createTimeSeriesAggregator(name="tsAggr2", windowSize=300, step=60, metrics=<[first(Price),max(Price),min(Price),last(Price),sum(volume)]>, dummyTable=Trade, outputTable=OHLC2, timeColumn=`Datetime, keyColumn=`Symbol)
subscribeTable(tableName="Trade", actionName="act_tsAggr2", offset=0, handler=append!{tsAggr2}, msgAsTable=true);
2.2.2. 在每个窗口内进行多次计算
以每分钟计算 vwap 价格为例,当前窗口内即使发生了多次交易,窗口结束前都不会触发任何使用当前窗口数据的计算。某些用户希望在当前窗口结束前频繁使用已有数据计算K线,这时可指定
createTimeSeriesAggregator
函数的updateTime参数。指定updateTime参数后,当前窗口结束前可能会发生多次针对当前窗口的计算。这些计算触发的规则为:
(1) 将当前窗口分为 windowSize/updateTime 个小窗口,每个小窗口长度为 updateTime。一个小窗口结束后,若有一条新数据到达,且在此之前当前窗口内有未参加计算的的数据,会触发一次计算。请注意,该次计算不包括这条新数据。
(2) 一条数据到达聚合引擎之后经过2*updateTime(若2*updateTime不足2秒,则设置为2秒),若其仍未参与计算,会触发一次计算。该次计算包括当时当前窗口内的所有数据。
若进行分组计算,以上规则在每组之内应用。在使用updateTime参数时,step必须是updateTime的整数倍。必须使用键值表作为输出表。若未指定keyColumn参数,主键为timeColumn列;若指定了keyColumn参数,主键为timeColumn列和keyColumn列。有关updateTime参数更多细节,请参考
时序聚合引擎教程
例如,要计算1分钟窗口的K线,但当前1分钟的K线不希望等到窗口结束后再计算,而是希望新数据进入后最迟2秒钟就计算。可通过如下步骤实现。
首先,创建一个键值表作为输出表,并将时间列和股票代码列作为主键。
share keyedTable(`datetime`Symbol, 100:0, `datetime`Symbol`open`high`low`close`volume,[DATETIME,SYMBOL,DOUBLE,DOUBLE,DOUBLE,DOUBLE,LONG]) as OHLC
使用以下脚本定义时序聚合引擎。其中指定updateTime参数取值为1(秒)。useWindowStartTime参数设为true,表示输出表第一列为数据窗口的起始时间。
tsAggr = createTimeSeriesAggregator(name="tsAggr", windowSize=60, step=60, metrics=<[first(Price),max(Price),min(Price),last(Price),sum(volume)]>, dummyTable=Trade, outputTable=OHLC, timeColumn=`Datetime, keyColumn=`Symbol, updateTime=1, useWindowStartTime=true)
最后,订阅流数据:
subscribeTable(tableName="Trade", actionName="act_tsaggr", offset=0, handler=append!{tsAggr}, msgAsTable=true);
2.3. 在 Python 中展示 K 线数据
在本例中,聚合引擎的输出表也定义为流数据表,客户端可以通过 Python API 订阅输出表,并将计算结果展现到 Python 终端。
以下代码使用 Python API 订阅实时聚合计算的输出结果表 OHLC,并将结果通过
print
函数打印出来。
from
threading
import
Event
import
dolphindb
as
ddb
import
pandas
as
pd
import
numpy
as
np
s=ddb.session()
#设定本地端口20001用于订阅流数据
s.enableStreaming(
20001
)
def
handler(lst):
print
(lst)
# 订阅DolphinDB(本机8848端口)上的OHLC流数据表
s.subscribe(
"127.0.0.1"
,
8848
, handler,
"OHLC"
,
"python_api_subscribe"
,
0
)
Event().wait()
也可通过 Grafana 等可视化系统来连接 DolphinDB,对输出表进行查询并将结果以图表方式展现。
FILE:references/doc_9142.md
# linearTimeTrend
**URL**: https://docs.dolphindb.cn/zh/funcs/l/linearTimeTrend.html
**来源**: DolphinDB 官方文档
---
linearTimeTrend
语法
linearTimeTrend(X, window)
TA-lib 系列函数参数说明和窗口计算规则请参考:
TA-lib 系列
详情
计算滑动线性回归,返回一个 tuple 类,包含两列,分别是 alpha 和 beta,对应 talib 中的 linearreg_intercept(线性回归截距)和
linearreg_slope(线性回归斜率指标)。
返回值
一个元组。
例子
x = 3 3 5 7 8 9 10 11 15 13 12 11 10
print linearTimeTrend(x,3)
// output
([,,2.666666666666666,3,5.166666666666667,7,8,9,9.5,12,14.833333333333333,13,12],[,,1,2,1.5,1,1,1,2.5,1,-1.5,-1,-1])
n = 10
t = table(09:00:00 + 1..n as time, rand(`A`B, n) as sym, rand(100.0, n) as val1, rand(1000..2000, n) as val2)
select time, sym, linearTimeTrend(val1, 3) as `alpha`beta from t
time
sym
alpha
beta
09:00:01
B
09:00:02
A
09:00:03
A
85.0844
-30.0688
09:00:04
B
49.3461
7.3621
09:00:05
B
30.4248
28.3589
09:00:06
A
83.106
-7.7515
09:00:07
B
78.4412
-17.7575
09:00:08
A
56.8575
4.4732
09:00:09
A
53.8492
-6.0653
09:00:10
A
61.7888
-4.5586
FILE:references/doc_9146.md
# undef
**URL**: https://docs.dolphindb.cn/zh/funcs/u/undef.html
**来源**: DolphinDB 官方文档
---
undef
语法
undef(obj, [objType=VAR])
或
undef all
详情
从内存中释放变量和函数定义。VAR(本地变量)亦可通过 "= NULL" 释放变量。
参数
obj
需要取消定义的对象。如果想要取消所有变量、所有全局变量或所有用户自定义函数的定义,
obj
可以使用 "all"。
objType
需要取消定义的对象的类型。可以是以下取值之一:VAR(本地变量),SHARED(共享变量) 或 DEF(函数定义)。默认值是
VAR。
使用
undef all
删除系统中所有用户自定义的对象。
返回值
无。
例子
undef all;
x=1
undef(`x);
x=1
y=2
undef(`x`y);
share table(1..3 as x, 4..6 as y) as t
undef(`t, SHARED);
def f(a){return a+1}
undef(`f, DEF);
a=1
b=2
undef all, VAR;
// 取消所有变量的定义,但不包括函数定义。
FILE:references/doc_9147.md
# atImin
**URL**: https://docs.dolphindb.cn/zh/funcs/a/atImin.html
**来源**: DolphinDB 官方文档
---
atImin
语法
atImin(location, value)
详情
找出
location
中最小值所在的位置,然后返回
value
中该位置对应的值。如果
location
中有多个相同的最小值,则取第一个最小值所在的位置。
若
location
和
value
是矩阵,则
location
和
value
的每列一一对应,分别计算
atImin
。
atImin(location, value) 相当于 value[imin(location)]。
参数
location
和
value
是向量、矩阵或表。
返回值
根据输入形式返回不同的结果:若输入为向量,返回标量;若输入为矩阵,返回向量。
数据类型与 value 一致。
例子
atImin(3 5 1 2, 9 7 5 3)
// output
5
m1=matrix(9 2 1 5 6 9, 3 1 3 NULL 5 2, 2 8 1 2 3 4)
m2=matrix(1..6, 1..6, 1..6)
atImin(m1,m2)
// output
[3,2,3]
相关函数:
imin
,
atImax
FILE:references/doc_9159.md
# setTraceMode
**URL**: https://docs.dolphindb.cn/zh/progr/sql/setTraceMode.html
**来源**: DolphinDB 官方文档
---
setTraceMode
语法
setTraceMode(mode)
参数
mode
布尔值,用于开启或关闭 SQL Trace。
详情
该命令用于控制 SQL Trace 功能的开启或关闭。
注:
一次完整的跟踪流程必须以 setTraceMode(true) 作为开启标识,并以
setTraceMode(false) 作为结束标识。
DolphinDB
从开启跟踪功能后的接收到的第一次请求开始进行跟踪。因此该命令必须单独执行,而不能和待跟踪的语句放在一个脚本中一起执行。
FILE:references/doc_9164.md
# existsStreamTable
**URL**: https://docs.dolphindb.cn/zh/funcs/e/existsStreamTable.html
**来源**: DolphinDB 官方文档
---
existsStreamTable
语法
existsStreamTable(tableName)
详情
查询指定的流数据表是否存在。
参数
tableName
字符串,表示流数据表名称。可以是普通流表、共享流表、持久化流表或高可用流表。
返回值
布尔类型标量。true 表示该流数据表存在;false 表示该数据表不存在。
例子
id=`XOM`GS`AAPL
x=102.1 33.4 73.6
rt=streamTable(id, x);
existsStreamTable(`rt)
返回:true
existsStreamTable(`srt)
返回:false
share rt as srt
existsStreamTable(`srt)
返回:true
FILE:references/doc_9166.md
# getRecentJobs
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getRecentJobs.html
**来源**: DolphinDB 官方文档
---
getRecentJobs
语法
getRecentJobs([n])
详情
取得本地节点上最近
n
个批处理作业的状态。
参数
n
是一个可选参数,为正整数。 无参数时返回所有 Jobs。
返回值
返回一个表,包含以下字段:
参数
含义
node
本地节点的别名。
userID
提交作业任务的用户 ID。
jobId
在提交批作业时指定的作业名。
rootJobId
系统中作业的唯一标识。
jobDesc
用于描述作业的字符串。
priority
作业的优先级,为 0-9 之间的整数。
parallelism
作业的并行度,即分配给该作业的线程数上限。
clientIp
发起作业任务的客户端 IP。
clientPort
发起作业任务的客户端端口号。
receivedTime
作业接收的时间,为 TIMESTAMP 类型。
startTime
作业开始时间,为 TIMESTAMP 类型。
endTime
作业结束时间,为 TIMESTAMP 类型。
errorMsg
报错信息。
详情参考:
BatchJobManagement
。
例子
def jobDemo(n){
s = 0
for (x in 1 : n) {
s += sum(sin rand(1.0, 100000000)-0.5)
print("iteration " + x + " " + s)
}
return s
};
submitJob("jobDemo1","job demo", jobDemo, 100);
submitJob("jobDemo2",, jobDemo, 10);
getRecentJobs(10);
node
userID
jobId
rootJobId
jobDesc
priority
parallelism
clientIp
clientPort
receivedTime
startTime
endTime
errorMsg
local8848
admin
jobDemo1
859c3c53-c9ad-1abc-41f5-6dbaaf8003e9
job demo
0
1
127.0.0.1
61,436
2024.02.29 10:18:07.160
local8848
admin
jobDemo2
5515626b-0dd9-e7ac-466c-d8b4d1fff2d1
jobDemo
0
1
127.0.0.1
61,436
2024.02.29 10:18:07.164
FILE:references/doc_9177.md
# enableTSDBAsyncSorting
**URL**: https://docs.dolphindb.cn/zh/funcs/e/enableTSDBAsyncSorting.html
**来源**: DolphinDB 官方文档
---
enableTSDBAsyncSorting
语法
enableTSDBAsyncSorting()
详情
TSDB 写入 Cache Engine 中的数据会根据
sortColumns
排序。写入任务和排序任务可以同步或异步进行,该命令用于开启异步进行数据排序的功能。异步线程数量由配置参数
TSDBAsyncSortingWorkerNum
指定。 只能由管理员在数据节点上执行。请注意,执行该命令前请确认
TSDBAsyncSortingWorkerNum
配置值大于0。
因异步数据排序能提高数据写入性能,若 TSDB 引擎所在服务器 CPU 核数较多,建议在进行数据写入前,执行该命令开启异步数据排序功能。
参数
无
返回值
无。
相关函数:
disableTSDBAsyncSorting
FILE:references/doc_9184.md
# nss
**URL**: https://docs.dolphindb.cn/zh/funcs/n/nss.html
**来源**: DolphinDB 官方文档
---
nss
语法
nss(maturity, yield, [method='nm'], [maxIter], [bounds], [initialGuess],
[seed])
详情
使用 NSS 模型和指定的优化方法,拟合债券的收益率曲线。
参数
maturity
值大于等于 0 的数值型向量,表示历史债券的到期时间,单位是年。
yield
与
maturity
等长的数值型向量,表示历史债券的收益率。
method
可选参数,字符串类型,表示在拟合过程中使用的最优化算法,可选值为:
“nm“:表示使用 Nelder-Mead 单纯形算法,默认值;
“bfgs“:表示使用 bfgs 算法;
“lbfgs“ :表示使用 lbfgs 算法;
'slsqp':表示顺序最小二乘编程方法(SLSQP)算法;
'de':表示差分进化(Differential Evolution)算法。
maxIter
可选参数,整型标量或向量,表示拟合过程中优化算法的最大迭代次数。
bounds
可选参数,数值类型矩阵,形状为(N,2),其中 N 为需要优化的参数数量。每一行的两个值(min,
max)定义了对应参数的边界。注意:
bounds
参数只在
method
取值'lbfgs'、'slsqp'或者'de'时生效。
initialGuess
可选参数,数值向量,表示使函数最优化的参数的初始猜测。长度为 6,每个值分别表示 β
0
,
β
1
, β
2
, β
3
, λ
0
, λ
1
的初始猜测,默认值为 [0.01, 0.01, 0.01, 0.01, 1.0, 1.0]。
seed
可选参数,整数标量,表示差分进化算法中使用的随机数种子,仅在
method
='de' 时生效。若
method
='de' 且不指定
seed
,则采用非确定性的随机数生成器。
seed
参数用于确保结果的可复现性。
返回值
返回一个字典,包含以下键值对:
modelName:字符串类型,表示模型名称;
params:数值向量,表示拟合后的模型参数。对于NS模型来说,长度为4,包含;对于NSS模型来说,长度为6,包含 。
fminResult:字典类型,表示 method 对应的最优化算法的优化结果,对于不同的 method,有不同输出。
“nm“:详情见 fmin 文档。
“bfgs“:详情见 fminBFGS 文档。
“lbfgs“:详情见 fminLBFGSB 文档。
“slsqp“:详情见 fminSLSQP 文档。
“de“:详情见 differentialEvolution 文档。
predict:模型的预测函数。其使用方法为
model.predict(T)
,T
表示需要预测的以年为单位的到期时间。
例子
传入指定的模型名称与参数,使用 bfgs 优化方法,拟合债券的收益率曲线。
maturity = [1,2,3,4,5,8,10,15,20,25,30]
yield = [0.0039,0.0061,NULL,NULL,0.0166,NULL,0.0258,NULL,NULL,0.0332,NULL]
model = nss(maturity, yield, method='bfgs');
model;
/*Output
modelName->nss
params->[0.036140551464406,-0.017389058792285,-0.039552798745696,-0.039554933812457,1.001838685848857,1.000930288743548]
fminResult->xopt->[0.036140551464406,-0.017389058792285,-0.039552798745696,-0.039554933812457,1.001838685848857,1.000930288743548]
fopt->0.000003185056025
gopt->[4.415407204305666E-7,8.382398277717584E-7,-2.683916591195157E-7,-4.651950860079524E-7,-0.000008569511408,-0.000008564345961]
iterations->10
Hinv->#0 #1 #2 #3 #4 #5
------------------ ------------------ ------------------ ------------------ ------------------ ------------------
0.492426526437359 0.696702464055202 -1.643864246164442 -1.644086017367336 0.08871259052824 0.037055616913674
0.696702464055203 9.022078200827937 -9.027640937693616 -9.027654505585944 0.659730122918773 0.302144825834614
-1.643864246164441 -9.027640937693616 12.179963755936533 11.180865226841653 -0.737531568671335 -0.323934330889313
-1.644086017367337 -9.027654505585944 11.180865226841657 12.181767428775573 -0.737537584440894 -0.32392102429678
0.08871259052824 0.659730122918772 -0.737531568671335 -0.737537584440894 1.053013492023418 0.024560701245749
0.037055616913674 0.302144825834614 -0.323934330889313 -0.32392102429678 0.024560701245749 1.011692492570688
warnFlag->0
fcalls->84
gcalls->12
predict->nssPredict
*/
若更换优化算法为
nm,返回值将发生变化。
model = ns(maturity, yield, method='nm');
model;
/*Output
modelName->nss
params->[0.038184469794996,-0.048575389082029,-0.022287414169806,0.047523360012739,1.873046195772644,0.161159907274023]
fminResult->xopt->[0.038184469794996,-0.048575389082029,-0.022287414169806,0.047523360012739,1.873046195772644,0.161159907274023]
fopt->5.456415848001168E-9
iterations->541
fcalls->860
warnFlag->0
predict->nssPredict
*/
相关函数:
nsspredict
FILE:references/doc_9187.md
# all
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/all.html
**来源**: DolphinDB 官方文档
---
all
语法
all(func, args...)
详情
把函数应用到参数的每一个元素。只要函数调用返回false,
all
高阶函数就会停止执行,并返回false。如果所有的函数调用都返回true,
all
高阶函数将返回true。
如果args是一个矩阵,
all
高阶函数将会按列执行;如果args是一个表格,它将会按行执行。
参数
func
是一个函数名。
args
是函数func的参数。它们可以是向量、矩阵或表。它们的数据形式可以不尽相同,但是长度必须相同,即向量中元素的个数,或矩阵中列的数量,或表中行的数量需要相同。
返回值
一个布尔值标量。
例子
all
高阶函数用于向量。
x = 1 2 NULL 11 NULL 13 NULL 102 103;
y = x cut 3;
y;
// output
([1,2,],[11,,13],[,102,103])
all(hasNull, y);
// output
1
// 检查是否 [1,2,],[11,,13],[,102,103]都含有 NULL值
x = 1 25 7 15 11 197 16 18 23;
y = x cut 3;
y;
// output
([1,25,7],[15,11,197],[16,18,23])
all(in, 7 11 23, y);
// output
1
// 检查是否 7在[1, 25, 7] 中, 11在[15,11,197] 中以及 23在[16,18,23]中。
all(in, 7 8 23, y);
// output
0
// 由于8不在[15, 11, 197]中,返回false
all(lt, 1 2 3, 4 5 6);
// output
1
// 检查是否 1<4, 2<5 以及3<6
all(lt, 1 2 7, 4 5 6);
// output
0
//返回false,因为7>6
all
高阶函数作用在矩阵上,按列遍历。
x=1..6$2:3;
x;
#0
#1
#2
1
3
5
2
4
6
all(in, 1 4 5, x);
// output
1
all(in, 1 2 5, x);
// output
0
// 返回 false,因为2不在x的第二列中
all
高阶函数作用在表上,按行遍历。下例中,定义了一个名为
varscompare
的函数用于比较表中的两个变量。
x=table(1 2 3 as a, 4 5 6 as b);
x;
a
b
1
4
2
5
3
6
def varscompare(t):t.a<t.b;
all(varscompare, x);
// output
1
y=table(1 7 3 as a, 4 5 6 as b);
// output
y;
a
b
1
4
7
5
3
6
all(varscompare, y);
// output
0
// 返回 false,因为7>5
FILE:references/doc_9202.md
# rowGroupby
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/rowgroupby.html
**来源**: DolphinDB 官方文档
---
rowGroupby
语法
rowGroupby(func, funcArgs, groupingCol, [mode='tuple'],
[ascending=true])
详情
对
groupingCol
的每一行分组后,在每个分组中计算
func(funcArgs)
,每组的计算结果是一个标量。该函数将根据
mode
指定的形式输出结果。
参数
func
一个聚合函数。
funcArgs
是函数
func
的参数。如果有多个参数,则用元组表示,且每个元素的维度必须和
groupingCol
保持一致。
groupingCol
非空矩阵或数组向量,用于分组。
mode
可选参数,指定
rowGroupby
返回值的数据形式,默认为 "tuple"。可取值为:
"tuple":返回一个长度为2的 tuple,其第1个元素是一个数组向量,存储分组变量,第2个元素是一个数组向量,存储各分组中
funcArgs
应用
func
后的结果。
"dict":返回一个字典。包含两个元素:'key' 和 'value',分别存储分组变量和各分组中
funcArgs
应用
func
后的结果。
"table":返回一个包含两列的表。字段为 "key" 和 "value",分别存储分组变量及各分组中
funcArgs
应用
func
后的结果。
ascending
布尔值,表示输出结果按
groupingCol
升序还是降序排序。默认值为 true(升序)。
返回值
取决于参数
mode
的值。
例子
下例对表 t 中的 price 列按升序排序后分组,对每个分组内对应的 qty 进行求和。
sym=`A`B
price = array(DOUBLE[], 0).append!([12.5 12.6 12.5 12.5 12.6, 15.5 15.5 15.5 15.3 15.3])
qty = array(INT[], 0).append!([201 212 220 215 214, 210 213 223 219 211])
t=table(sym,price,qty)
//指定 mode='dict' 时,以字典形式输出结果,其中 key 存储 price 排序后分组的结果,value 存储对 qty 分组求和的结果
rowGroupby(func=sum,funcArgs=t.qty,groupingCol=t.price,mode='dict')
/* output:
value->[[636,426],[430,646]]
key->[[12.5,12.6],[15.3,15.5]]
*/
//指定 ascending=false,按照 price 降序输出结果。
rowGroupby(func=sum,funcArgs=t.qty,groupingCol=t.price,mode='dict', ascending=false)
/* output:
value->[[426,636],[646,430]]
key->[[12.6000,12.5000],[15.5000,15.3000]]
*/
//指定 mode='table' 时,以表的形式输出结果,其中 key 存储 price 排序后分组的结果,value 存储对 qty 分组求和的结果
rowGroupby(func=sum,funcArgs=t.qty,groupingCol=t.price,mode='table')
key
value
[12.5,12.6]
[636,426]
[15.3,15.5]
[430,646]
//指定 mode='tuple',输出结果为 tuple,将 tuple 的两个元素重命名后作为表的一列输出。
select rowGroupby(sum, qty, price, 'tuple') as `a`b from t
a
b
[12.5,12.6]
[636,426]
[15.3,15.5]
[430,646]
接下来通过一个例子来展示如何在矩阵上使用
rowGroupby
函数:
m=matrix([32.5 12.6 22.5 42.5 32.6, 17.5 25.5 35.5 17.3 19.3, 17 20.1 30 13 19])
g=matrix([1 2 2 5 4, 2 2 3 2 1, 1 3 2 3 5])
//对 g 的每行排序后分组,对 m 的每行在每个组内进行求和
rowGroupby(func=sum, funcArgs=m, groupingCol=g, mode='table')
key
value
[1,2]
[49.5,17.5]
[2,3]
[38.1,20.1]
[2,3]
[52.5,35.5]
[2,3,5]
[17.3,13,42.5]
[1,4,5]
[19.3,32.6,19]
FILE:references/doc_9206.md
# subarray
**URL**: https://docs.dolphindb.cn/zh/funcs/s/subarray.html
**来源**: DolphinDB 官方文档
---
subarray
语法
subarray(X, range)
详情
当使用某个向量的一部分元素进行计算时,例如若使用 close[10:].avg() 的语句,系统会从向量 close
中复制数据产生一个新的向量 close[10:] 再进行计算,不仅占用更多内存而且耗时。
subarray
函数返回输入向量的一个子向量。它是原向量的一个视图,只记录了原向量的指针以及子向量的开始和结束位置。由于并没有分配大块内存来存储新向量,所以没有发生数据复制。所有向量的只读操作都可直接应用于
subarray
。
参数
X
可以是向量或矩阵。
range
是表示范围的数据对,范围包括下限,不包括上限。若
range
不在 [0,
size(X)-1] 内,则超出 [0, size(X)-1] 的值所对应的位置返回空值。
返回值
一个向量。
例子
x=1..100
subarray(x, 10:20);
// output
[11,12,13,14,15,16,17,18,19,20]
subarray(x, 90:);
// output
[91,92,93,94,95,96,97,98,99,100]
subarray(x, :10);
// output
[1,2,3,4,5,6,7,8,9,10]
a=rand(1000.0,20000000);
timer a.subarray(0:1000000).avg();
// output
Time elapsed: 1.5 ms
timer a[0:1000000].avg();
// output
Time elapsed: 8 ms
// subarray is read-only:
b=a.subarray(0:1000000);
b[0]=1;
// output
b[0] = 1 => Immutable sub vector doesn't support method set
FILE:references/doc_9209.md
# arrayVector
**URL**: https://docs.dolphindb.cn/zh/funcs/a/arrayVector.html
**来源**: DolphinDB 官方文档
---
arrayVector
语法
arrayVector(index, value)
详情
根据
index
中的元素对
value
进行分割,将
value
转换为一个数组向量。
index
中元素的个数表示转换后数组向量的行数;
index
中的每个元素值,
代表数组向量中,每行向量的最后一个元素对应原本
value
中的位置(从1开始编号)。如下图所示:
图
1
.
Index
注:
index
中元素的最大值不能超过
value
的长度。
参数
index
是一个严格单调递增的正整型向量。
value
是一个向量。其元素类型必须是
arrayVector
支持的类型。
返回值
一个数组向量。
例子
arrayVector(2 3 4, [1,2,3,4])
[[1,2],[3],[4]]
arrayVector(1 4 7, [1.0,2.1,4.1,6.8,0.5,2.2,2])
[[1],[2.1,4.1,6.8],[0.5,2.2,2]]
value = 2022.01.01 + 0..20
index = 7 14 21
arrayVector(index, value)
[[2022.01.01,2022.01.02,2022.01.03,2022.01.04,2022.01.05,2022.01.06,2022.01.07],[2022.01.08,2022.01.09,2022.01.10,2022.01.11,2022.01.12,2022.01.13,2022.01.14],[2022.01.15,2022.01.16,2022.01.17,2022.01.18,2022.01.19,2022.01.20,2022.01.21]]
相关函数:
fixedLengthArrayVector
FILE:references/doc_9214.md
# readRecord!
**URL**: https://docs.dolphindb.cn/zh/funcs/r/readRecord_.html
**来源**: DolphinDB 官方文档
---
readRecord!
语法
readRecord!(handle, holder, [offset=0], [length])
详情
readRecord!
函数将二进制文件转换为 DolphinDB 数据对象。DolphinDB
也提供了
writeRecord
函数,用于将 DolphinDB
数据对象转换为二进制文件,以供其它程序使用。 二进制文件基于行,且每行包含的记录有相同的数据类型和固定的长度。例如,如果一个二进制文件包含了 5
个数据域,分别具有下述数据类型(长度):char(1), boolean(1), short(2), int(4), long(8), 和 double(8), 那么
readRecord!
函数将把每行视为 24 个字节。类似地,
writeRecord
函数把 DolphinDB 对象(例如表或元组)转换为具有上述格式的二进制文件。
参数
handle
是文件句柄。
holder
是用于保存读取的数据的变量。
offset
表示数据保存至
holder
的起始位置。
length
是从文件中读取的行数。
返回值
返回读取的行数。
例子
// 创建一个文件句柄,用于读取记录。二进制文件 a.bin 包含了 1000 条记录。
f=file("c:/DB/a.bin")
t=table(1000:0, `PERMNO`PRC`VOL`SHROUT, `int`double`int`double)
f.readRecord!(t);
// output
1000
// 类似地,我们可以将一个二进制文件读入一个 DolphinDB 元组对象
f=file("c:/DB/a.bin")
t=loop(array, [int, double, int, double], 0, 500)
// 创建具有 4 个数组元素的元组 t。每一个数组的长度是 500
f.readRecord!(t, 0, 500);
// 读取前 500 行
// output
500
FILE:references/doc_9220.md
# memberModify!
**URL**: https://docs.dolphindb.cn/zh/funcs/m/membermodify.html
**来源**: DolphinDB 官方文档
---
memberModify!
语法
memberModify!(obj, function, indices, parameters)
详情
修改元组或 ANY 字典的成员对象
,也可修改面向对象的编程(OOP)中的对象
。
参数
obj
一个元组或值为 ANY 类型的字典
,或者一个 OOP 对象
。
function
一个内置的系统函数,该函数的第一个参数是可修改的,例如 append!。
indices
标量、向量或元组,表示指向一个或多个成员对象的索引或键值。
若是一个元组,用于表示多维度索引。元组的长度表示索引的深度。
若是一个向量,表示对多个成员进行修改。
parameters
function
除第一个参数外的其它参数。
parameters
的维度必须与
indices
,
function
的参数个数匹配。
返回值
无
例子
例 1
创建元组 a,修改其中的一个元素,可见前后对比。
a = (1 2, 3 4 5)
memberModify!(a, append!, 0, 3 4)
a
//output: a = (1 2 3 4, 3 4 5)
创建字典
d,修改其中的两个元素,可见前后对比。
d = dict(`A`B`C, (1 2, 3 4, 5 6))
d
/*output:
A->[1,2]
B->[3,4]
C->[5,6]
*/
d.memberModify!(append!,`A`B, 3 4)
d
/*output:
A->[1,2,3]
B->[3,4,4]
C->[5,6]
*/
创建元组 c,其包含基于表 t,字典 d
和一个元组。
t = table(1 2 3 as val1, 4 5 6 as val2)
d = dict(`A`B`C, (1 2, 3 4, 5 6))
c = (t, d, [1 2 3, 4 5 6])
c
/*output:
(val1 val2
---- ----
1 4
2 5
3 6
,C->[5,6]
A->[1,2]
B->[3,4]
,([1,2,3],[4,5,6]))
*/
调用
memberModify!
对元组第 3 个元素
[1 2 3, 4 5 6]
的第 1
个元素 [1, 2, 3] 添加元素 4 和 5。要修改的对象需要用两个维度来指定,因此 indices 使用元组 (2, 0)
来表示。
c.memberModify!(append!, (2, 0), 4 5)
/*output:
(val1 val2
---- ----
1 4
2 5
3 6
,C->[5,6]
A->[1,2]
B->[3,4]
,([1,2,3,4,5],[4,5,6]))
*/
在该基础上,继续向元组的第 2 个元素(字典)的键值 B 指定的对象写入新数据 5 和 7。indices 仍然使用元组 (1,`B)
来表示。
c.memberModify!(append!, (1,`B), 5 7)
c
/*output:
(val1 val2
---- ----
1 4
2 5
3 6
,C->[5,6]
A->[1,2]
B->[3,4,5,7]
,([1,2,3,4,5],[4,5,6]))
*/
例 2
约定名为 A 的类并进行实例化,使用
memberModify!
进行写入操作,打印向量 a 的数据,可得预期结果。
class A {
a :: INT VECTOR
def A() {
a = []
}
}
v = A()
memberModify!(v, append!, "a", 1)
print v.a
//output: [1]
memberModify!(v, append!, "a", 11)
print v.a
//output: [1,11]
FILE:references/doc_9221.md
# clearDSCache!
**URL**: https://docs.dolphindb.cn/zh/funcs/c/clearDSCache_.html
**来源**: DolphinDB 官方文档
---
clearDSCache!
语法
clearDSCache!(ds)
详情
clearDSCache!
函数指示系统在下次执行数据源之后清除缓存。
参数
ds
是数据源或数据源列表。
返回值
无。
例子
PTNDB_DIR = "/home/db_testing"
dbName = database(PTNDB_DIR + "/NYSETAQByName")
Trades = dbName.loadTable(`Trades)
ds=sqlDS(<select Time,Exchange,Symbol,Trade_Volume as Vol, Trade_Price as Price from Trades>)
ds.cacheDS!() // cache the data
ds.clearDSCache!() // clear the cache
FILE:references/doc_9223.md
# hourOfDay
**URL**: https://docs.dolphindb.cn/zh/funcs/h/hourOfDay.html
**来源**: DolphinDB 官方文档
---
hourOfDay
语法
hourOfDay(X)
详情
返回
X
中的小时。
参数
X
可以是 TIME, MINUTE, SECOND, DATETIME, TIMESTAMP, NANOTIME,
NANOTIMESTAMP 类型的标量或向量。
返回值
INT 类型标量或向量。
例子
hourOfDay(00:46:12);
// output
0
hourOfDay([2012.06.12T12:30:00,2012.10.28T17:35:00,2013.01.06T02:36:47,2013.04.06T08:02:14]);
// output
[12,17,2,8]
相关函数:
dayOfYear
,
dayOfMonth
,
quarterOfYear
,
monthOfYear
,
weekOfYear
,
minuteOfHour
,
secondOfMinute
,
millisecond
,
microsecond
,
nanosecond
FILE:references/doc_9225.md
# files
**URL**: https://docs.dolphindb.cn/zh/funcs/f/files.html
**来源**: DolphinDB 官方文档
---
files
语法
files(directory, [pattern])
详情
该函数必须要用户登录后才能执行。
如果没有指定
pattern
,返回一个包含目录中的文件和子目录信息的表。
如果指定了
pattern
,返回一个包含文件名中包含了pattern 的文件和子目录的表。
参数
directory
是表示目录路径的字符串。
pattern
是表示在该目录下搜索的文件名的模式的字符串。
返回值
一个表。
例子
files("/home/06_DolphinDB/01_App/DolphinDB_Win_V0.2");
filename
isDir
fileSize
lastAccessed
lastModified
LICENSE_AND_AGREEMENT.txt
0
22558
1495508675000
1483773234998
README_WIN.txt
0
5104
1495508675000
1483866232680
server
1
0
1496624932437
1496624932437
THIRD_PARTY_SOFTWARE_LICENS...
0
8435
1495508675000
1483628426506
files("/home/06_DolphinDB/01_App/DolphinDB_Win_V0.2", "readme%");
filename
isDir
fileSize
lastAccessed
lastModified
README_WIN.txt
0
5104
1495508675000
1483866232680
select * from files("/home/06_DolphinDB/01_App/DolphinDB_Win_V0.2") where filename like "README%";
filename
isDir
fileSize
lastAccessed
lastModified
README_WIN.txt
0
5104
1495508675000
1483866232680
FILE:references/doc_9230.md
# gema
**URL**: https://docs.dolphindb.cn/zh/funcs/g/gema.html
**来源**: DolphinDB 官方文档
---
gema
语法
gema(X, window, alpha)
TA-lib 系列函数参数说明和窗口计算规则请参考:
TA-lib 系列
详情
在给定长度(以元素个数衡量)的滑动窗口内,计算
X
的指数移动平均(Exponential Moving Average),该函数是
ema
的扩展。
与
ema
相比,该函数引入了计算系数
alpha
,其计算公式为:
其中:
为第 k
个指数移动平均值,alpha 为计算系数,
为向量
中第 k 个元素。
参数
alpha
是一个0-1之间的浮点数(不包含0, 1),表示计算系数。
返回值
DOUBLE 类型,形式同
X
。
例子
x=12.1 12.2 12.6 12.8 11.9 11.6 11.2
gema(x,3,0.5);
// output
[,,12.299999999999998,12.55,12.225000000000001,11.912500000000001,11.55625]
x=matrix(12.1 12.2 12.6 12.8 11.9 11.6 11.2, 14 15 18 19 21 12 10)
gema(x,3,0.1);
col1
col2
12.3
15.6667
12.35
16
12.305
16.5
12.2345
16.05
12.131
15.445
相关函数:
ema
,
wilder
,
tema
FILE:references/doc_9235.md
# msum2
**URL**: https://docs.dolphindb.cn/zh/funcs/m/msum2.html
**来源**: DolphinDB 官方文档
---
msum2
语法
msum2(X, window, [minPeriods])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内计算
X
元素的平方和。请注意,该函数的返回值是 DOUBLE
类型。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
输入为向量时,返回一个与输入等长的向量。
输入为矩阵时,返回一个与输入矩阵同维度的矩阵,每列分别计算。
输入为表时,返回一个与输入表结构相同的表。
输入为元组时,返回对应的元组结构。
例子
X = 2 1 3 7 6 5 4
Y = 2 1 3 NULL 6 5 4
msum2(X, 3)
// output: [,,14,59,94,110,77]
msum2(Y, 3)
// output: [,,14,10,45,61,77]
msum2(Y, 3, minPeriods=1)
// output: [4,5,14,10,45,61,77]
m = matrix(1 NULL 4 NULL 8 6 , 9 NULL NULL 10 NULL 2)
m.rename!(date(2021.08.16)+1..6, `col1`col2)
m.setIndexedMatrix!()
msum2(m, 3d) // 等价于 msum2(m, 3)
label
col1
col2
2021.08.17
1
81
2021.08.18
1
81
2021.08.19
17
81
2021.08.20
16
100
2021.08.21
80
100
2021.08.22
100
104
相关函数:
sum2
FILE:references/doc_9250.md
# pcall
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/pcall.html
**来源**: DolphinDB 官方文档
---
pcall
语法
pcall(func, args...)
详情
将输入参数分成几个部分,并行计算,最后将结果合并。如果输入参数的长度小于100,000,
pcall
函数不会并行计算。
参数
func
是一个函数。该函数的输出结果可以是一个向量或表,并且它们的长度必须与输入参数args的长度相同。
args
是func的参数。它可以是表、向量或元组。输入参数中的所有向量或表列必须长度相同。
返回值
向量或表,取决于
func
的输出结果。
例子
x = rand(1.0, 10000000);
timer(10) sin(x);
输出返回:
Time elapsed: 739.561 ms
timer(10) pcall(sin, x);
输出返回:
Time elapsed: 404.56 ms
FILE:references/doc_9254.md
# nssPredict
**URL**: https://docs.dolphindb.cn/zh/funcs/n/nsspredict.html
**来源**: DolphinDB 官方文档
---
nssPredict
语法
nssPredict(model, T)
详情
根据指定的 NS 模型或 NSS 模型,预测债券的收益率。
参数
model
字典类型,表示 Nelson-Siegel(NS) 模型或 Nelson-Siegel-Svensson(NSS)模型。字典中应至少包含
modelName
和
params
两个成员:
modelName 字符串类型,必须为 “ns” 或 “nss” 。
params 数值型向量,表示模型的参数:
对于 NS 模型,向量长度为 4,依次为
β
0
,
β
1
,
β
2
,
λ
。
对于 NSS 模型,向量长度为 6,依次为
β
0
,
β
1
,
β
2
,
β
3
,
λ
0
,
λ
1
。
T
值大于 0 的数值型向量,表示历史债券的到期时间,单位是年。
返回值
DOUBLE 类型向量。
例子
model = dict(STRING, ANY)
model[`modelName] = `nss
model[`params] = [0.038184469794996,-0.048575389082029,-0.022287414169806,0.047523360012739,1.873046195772644,0.161159907274023]
T = [3,1]
nssPredict(model, T)
//output: [0.009904201306,0.003891991292041]
相关函数:
nss
FILE:references/doc_9257.md
# char
**URL**: https://docs.dolphindb.cn/zh/funcs/c/char.html
**来源**: DolphinDB 官方文档
---
char
语法
char(X)
详情
把输入转换为 CHAR 数据类型。
参数
X
可以是任意数据类型。
返回值
CHAR 类型标量。
例子
x=char();
x;
返回:null
typestr x;
返回:CHAR
a=char(99);
a;
返回:'c'
typestr a;
返回:CHAR
char(a+5);
返回:'h'
char("990");
返回:
Failed to convert the string to CHAR
注:
char
函数会把输入的字符串识别为 ASCII 码,超出 ASCII
码范围的输入字符无法转换。
FILE:references/doc_9262.md
# version
**URL**: https://docs.dolphindb.cn/zh/funcs/v/version.html
**来源**: DolphinDB 官方文档
---
version
语法
version()
详情
返回 DolphinDB 的版本、发布日期,和当前的操作系统版本、特定编译版本(非特定版本不显示)、 CPU
指令集。信息间使用空格隔开。
参数
无
返回值
STRING 类型标量。
例子
version();
//output: 3.00.0 2024.03.31 LINUX x86_64
FILE:references/doc_9272.md
# sleep
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sleep.html
**来源**: DolphinDB 官方文档
---
sleep
语法
sleep(X)
详情
暂停程序
X
毫秒。
参数
X
是一个非负数。
例子
for(s in 1:10){
sleep(1000)
print(s+" seconds passed.")
};
// output
1 seconds passed.
2 seconds passed.
3 seconds passed.
4 seconds passed.
5 seconds passed.
6 seconds passed.
7 seconds passed.
8 seconds passed.
9 seconds passed.
FILE:references/doc_9275.md
# nullFill
**URL**: https://docs.dolphindb.cn/zh/funcs/n/nullFill.html
**来源**: DolphinDB 官方文档
---
nullFill
语法
nullFill(X, Y)
详情
如果
X
是一个标量,
Y
只能是一个标量,使用
Y
填充
X
中的 NULL 值。
如果
X
是一个向量或矩阵:
如果
Y
是标量,使用
Y
填充
X
中的 NULL 值。
如果
Y
是一个与
X
等长的向量或矩阵,使用
Y
中与
X
的 NULL 值对应位置的元素替换
X
中的 NULL 值。
如果
X
是一个表,那么
Y
只能是一个标量,使用
Y
填充表中的 NULL
值。注意,填充 NULL 值时,系统会尝试将
Y
进行类型转换。如果
Y
不能转换为表中某列的类型,系统会抛出异常。
nullFill
不改变输入对象的值;
nullFill!
会改变输入对象的值。
参数
X
可以是标量、向量、矩阵或表。
Y
可以是一个标量,也可以是与
X
长度相同的向量或矩阵。
返回值
返回填充空值后的对象,其类型与形式同
X
。
例子
例1.向量
x=1 NULL NULL 6 NULL 7;
nullFill(x,0);
// output
[1,0,0,6,0,7]
y=1..6
nullFill(x,y);
// output
[1,2,3,6,5,7]
在 SQL 语句中对表中的一列使用
nullFill
函数:
ID=take(1,6) join take(2,6)
date=take(2018.01.01..2018.01.06, 12)
x=3.2 5.2 NULL 7.4 NULL NULL NULL NULL 8 NULL NULL 11
t=table(ID, date, x)
t;
ID
date
x
1
2018.01.01
3.2
1
2018.01.02
5.2
1
2018.01.03
1
2018.01.04
7.4
1
2018.01.05
1
2018.01.06
2
2018.01.01
2
2018.01.02
2
2018.01.03
8
2
2018.01.04
2
2018.01.05
2
2018.01.06
11
update t set x=x.nullFill(avg(x)) context by id;
t;
ID
date
x
1
2018.01.01
3.2
1
2018.01.02
5.2
1
2018.01.03
5.266667
1
2018.01.04
7.4
1
2018.01.05
5.266667
1
2018.01.06
5.266667
2
2018.01.01
9.5
2
2018.01.02
9.5
2
2018.01.03
8
2
2018.01.04
9.5
2
2018.01.05
9.5
2
2018.01.06
11
例2.矩阵
x=1 NULL 2 NULL 3 4 $ 3:2;
x;
#0
#1
1
3
2
4
x.nullFill(0);
#0
#1
1
0
0
3
2
4
例3.表
t=table(1..6 as id, 2.1 2.2 NULL NULL 2.4 2.6 as x, 4.3 NULL 3.6 6.7 8.8 NULL as y);
nullFill(t, -999999);
id
x
y
1
2.1
4.3
2
2.2
-999999
3
-999999
3.6
4
-999999
6.7
5
2.4
8.8
6
2.6
-999999
相关函数:
isNull
,
hasNull
,
bfill
,
ffill
,
lfill
FILE:references/doc_9279.md
# stdp
**URL**: https://docs.dolphindb.cn/zh/funcs/s/stdp.html
**来源**: DolphinDB 官方文档
---
stdp
语法
stdp(X)
详情
若
X
为向量,返回
X
的总体标准差。
若
X
为矩阵,计算每列的总体标准差,返回一个向量。
若
X
为表,计算每列的总体标准差,返回一个表。
与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
可以是向量、矩阵或表。
返回值
一个标量、向量或表。
例子
stdp(1 2 3);
// output
0.816497
m=matrix(1 3 5 7 9, 1 4 7 10 13);
m;
#0
#1
1
1
3
4
5
7
7
10
9
13
stdp(m);
// output
[2.8284,4.2426]
相关函数:
std
,
cumstdp
FILE:references/doc_9280.md
# mad
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mad.html
**来源**: DolphinDB 官方文档
---
mad
语法
mad(X, [useMedian=false])
详情
若
X
为向量,计算
X
的平均绝对离差或平均绝对中位差。
若
X
为矩阵,计算在每列内部进行,返回一个向量。
若
X
为表,计算在每列内部进行,返回一个表。
与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
是一个向量、矩阵或表。
useMedian
是一个布尔值,默认值是 false,表示计算平均绝对离差(mean absolute deviation)。若为 true
则计算绝对中位差(median absolute deviation)。
平均绝对离差:mean(abs(X - mean(X)))
绝对中位差:med(abs(X - med(X)))
返回值
X
是向量时,返回一个 DOUBLE 类型标量。
X
是矩阵时,返回一个 DOUBLE 类型向量。
X
是表时,返回一个表。
例子
mad([85, 90, 95, NULL]);
// output: 3.333333333333333
m=matrix(85 90 95, 185 190 195);
m;
#0
#1
85
185
90
190
95
195
mad m;
// output: [3.333333333333333, 3.333333333333333]
mad([0, 19.618568, 67.900707, 71.65218, 73.103952, 58.275308, 18.819054, 36.940571, 48.114366], false)
// output: 22.204817
相关函数:
mmad
FILE:references/doc_9288.md
# unifiedExpr
**URL**: https://docs.dolphindb.cn/zh/funcs/u/unifiedExpr.html
**来源**: DolphinDB 官方文档
---
unifiedExpr
语法
unifiedExpr(objs, optrs)
详情
使用
optrs
中的二元运算符,将
objs
中元素连接,生成一个多元运算表达式的元代码。使用
eval
函数可以执行
unifiedExpr
函数生成的元代码。
参数
objs
是长度在2到1024之间的元组。
optrs
是由二元运算符组成的向量,其数量为 size(
objs
)-1。
返回值
CODE 类型元代码。
例子
unifiedExpr((1, 2), add)
// output: <1 + 2>
t=table(1..3 as price1, 4..6 as price2, 5..7 as price3)
a=sqlColAlias(unifiedExpr((sqlCol("price1"), sqlCol("price2"), sqlCol("price3")), take(add, 2)))
sql(select=(sqlCol(`price1),sqlCol(`price2),sqlCol(`price3),a), from=t).eval()
price1
price2
price3
price1_add
1
4
5
10
2
5
6
13
3
6
7
16
相关函数:
binaryExpr
FILE:references/doc_9293.md
# clear!
**URL**: https://docs.dolphindb.cn/zh/funcs/c/clear_.html
**来源**: DolphinDB 官方文档
---
clear!
语法
clear!(X)
详情
函数
clear!
用来清除
X
中的所有内容。对
X
执行该函数后,
X
仍然存在,保持原有的数据类型,可以追加新的数据。
参数
X
可以是向量、矩阵、集合、字典、内存表。
返回值
返回一个与输入
X
相同数据类型和形式的对象。
例子
x=1 2 3;
clear!(x);
// output
[]
typestr x;
// output
FAST INT VECTOR
size x;
// output
0
x.append!(1..6);
// output
[1,2,3,4,5,6]
y=set(8 9 4 6);
y.clear!();
// output
set()
x=1..3;
y=4..6;
z=dict(x,y);
z;
// output
3->6
1->4
2->5
z.clear!();
t = table(1 2 3 as id, 1.0 2.0 3.0 as value)
t.clear!()
FILE:references/doc_9304.md
# move
**URL**: https://docs.dolphindb.cn/zh/funcs/m/move.html
**来源**: DolphinDB 官方文档
---
move
语法
move(X, steps)
详情
move
是
prev
和
next
的通用形式。
参数
X
可以是向量、矩阵或表;
steps
是一个整数或一个
duration
,表示移动多少位置或多少时间。
如果
steps
为正数,
X
向右移动
steps
个位置;
如果
steps
为负数,
X
向左移动
steps
个位置;
如果
steps
为 0,不改变
X
的位置;
如果
steps
为 DURATION,对应的
X
必须是行索引为时间类型的索引矩阵或者索引序列。
返回值
返回一个与输入
X
相同数据类型和形式的对象。
例子
x=3 9 5 1 4 9;
move(x,3);
// output: [,,,3,9,5]
move(x,-2);
// output: [5,1,4,9,,]
index = (second(08:20:00)+1..4) join 08:21:01 join 08:21:02
x = index.indexedSeries(x)
move(x,3s)
label
col1
08:20:01
08:20:02
08:20:03
08:20:04
3
08:21:01
1
08:21:02
1
move(x,1m)
label
col1
08:20:01
08:20:02
08:20:03
08:20:04
08:21:01
3
08:21:02
9
FILE:references/doc_9307.md
# count
**URL**: https://docs.dolphindb.cn/zh/funcs/c/count.html
**来源**: DolphinDB 官方文档
---
count
语法
count(X)
详情
size
和
count
不同。
size
返回向量/矩阵中元素的个数,而
count
返回向量/矩阵中非 NULL
的元素个数。
count
可以用在 SQL 查询中,而
size
不可以。对于表而言,
size
和
count
都返回行数。参见相关函数
size
。
count
用于 SQL 查询时,有如下三种常见用法:
select count(*) from pt
:返回 pt 表中的数据条数。
select count(1) from pt
:若 pt 为空表,则返回1;否则返回 pt
表中数据涉及到的分区数量。
select count(colName) from pt
:返回列 colName 中的非空数据的个数。
参数
X
可以是标量、向量、矩阵或表。
返回值
INT 类型标量。
例子
count(3 NULL 5 6);
// output
3
size(3 NULL 5 6);
// output
4
m=1 2 3 NULL 4 5$2:3;
m;
#0
#1
#2
1
3
4
2
5
count(m);
// output
5
size(m);
// output
6
t = table(1 NULL 3 as id, 3 NULL 9 as qty);
t;
id
qty
1
3
3
9
count(t);
// output
3
size(t);
// output
3
data = table(2023.10.01 + take(0..9,100) as date, take(['A','B','C','D'],100) as sym, 1..100 as val)
db = database("dfs://demo",VALUE,2023.10.01..2023.10.10)
pt = db.createPartitionedTable(data,`pt,`date)//创建一个分区表
pt.append!(data) //向表中插入数据
select count(*) from pt;//返回数据条数
count
100
select count(1) from pt;//返回分区数
count
10
FILE:references/doc_9323.md
# zscore
**URL**: https://docs.dolphindb.cn/zh/funcs/z/zscore.html
**来源**: DolphinDB 官方文档
---
zscore
语法
zscore(X)
详情
若
X
为向量,为
X
中的每个元素计算标准分数(z-score)。
若
X
为矩阵或表,上述计算对每列分别进行。
计算中使用了样本标准差,而不是总体标准差。
参数
X
是一个向量、矩阵或表。
返回值
若
X
为向量,返回一个与
X
长度相等的向量;若
X
为矩阵或表,返回一个与
X
行列数相同的矩阵或表。
例子
zscore(1 2 3 4 5);
// output
[-1.264911,-0.632456,0,0.632456,1.264911]
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
zscore(m);
#0
#1
-1
-1
0
0
1
1
FILE:references/doc_9333.md
# ploop
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/ploop.html
**来源**: DolphinDB 官方文档
---
ploop
语法
ploop(func, args...)
ploop 是
loop
的并行版本。
FILE:references/doc_9334.md
# next
**URL**: https://docs.dolphindb.cn/zh/funcs/n/next.html
**来源**: DolphinDB 官方文档
---
next
语法
next(X)
详情
将
X
向左移动一个位置。类似地:
prev
将
X
向右移动一个位置;
move
可以将
X
向左或向右移动一个位置。
参数
X
可以是向量、矩阵或表。
返回值
返回一个与输入
X
相同数据类型和形式的对象。
例子
x = 1..5;
next(x);
// output: [2,3,4,5,]
x = matrix(1 2 3 4 5);
next(x)
#0
2
3
4
5
t=table(1 2 3 as a, `x`y`z as b, 10.8 7.6 3.5 as c);
next(t)
a
b
c
2
y
7.6
3
z
3.5
FILE:references/doc_9336.md
# ipaddr
**URL**: https://docs.dolphindb.cn/zh/funcs/i/ipaddr.html
**来源**: DolphinDB 官方文档
---
ipaddr
语法
ipaddr(X)
详情
把字符串转换成用于表达 IPv4 或 IPv6 地址的 IPADDR 类型数据。
参数
X
是一个字符串标量或向量。
返回值
IPADDR 类型标量或向量。
例子
a=ipaddr("192.168.1.13");
a;
返回:192.168.1.13
typestr(a);
返回:IPADDR
FILE:references/doc_9338.md
# ops 运维函数库
**URL**: https://docs.dolphindb.cn/zh/modules/ops/ops.html
**来源**: DolphinDB 官方文档
---
ops 运维函数库
进行数据库运维时,存在一些常见需求,例如取消集群中未完成的作业、查看数据库磁盘占用情况、关闭不活跃会话等。V1.30.19/V2.00.7 之前版本的 server,用户需要自己开发脚本,来实现这些需求,这增加了维护的难度。为降低用户的开发成本,提升数据库易用性,DolphinDB 自 V1.30.19/V2.00.7 版本开始,增加了数据库运维模块 ops,其覆盖了部分常用的运维脚本,可以满足用户较频繁的运维需求。
注
:ops 模块兼容 DolpinDB server V1.30.19/V2.00.7 及以上版本。
1. 环境配置
自 1.30.19 和 2.00.7 版本开始,DolphinDB 安装包的 server/modules 目录下已预装 ops.dos,无需用户下载。若在 server/modules 下没找到 ops.dos,通过此处获得
ops.dos
文件,并放至节点的 [home]/modules 目录下。其中 [home] 目录由系统配置参数 home 决定,可以通过
getHomeDir()
函数查看。
更多 DolphinDB 模块的说明,请参阅
DolphinDB 教程:模块
。
2. 使用说明
通过 use 关键字导入模块。导入模块后,可以通过以下两种方式来使用模块内的自定义函数:
直接调用模块中的函数:
use ops
getAllLicenses()
通过模块中的函数的完整路径来调用:
use ops
ops::getAllLicenses()
若导入的不同模块中含有相同名称的函数,则必须通过第二种方式调用。
3. 函数说明
3.1. cancelJobEx
语法
cancelJobEx(id=NULL)
参数
id: 字符串,表示后台作业的ID,可通过
getRecentJobs()
获取。
详情
取消集群节点上的后台作业。若指定了参数 id,取消此 id 对应的后台作业,若未指定 id,则取消集群各节点上的所有后台作业。
例子
创建 3 个后台作业:
def testJob(n,id){
for(i in 0:n){
writeLog("demo"+id+"is working")
sleep(1000)
}
}
submitJob("demo1","just a test",testJob,300,1);
submitJob("demo2","just a test",testJob,300,2);
submitJob("demo3","just a test",testJob,300,3);
取消第 1 个作业后,查询作业情况, 发现第 1 个作业的 errorMsg 显示 The task was cancelled:
cancelJobEx("demo1")
pnodeRun(getRecentJobs)
返回:
node
userID
jobId
rootJobId
jobDesc
priority
parallelism
receivedTime
startTime
endTime
errorMsg
comnode1
admin
demo1
45c4eb71-6812-2b83-814e-ed6b22a99964
just a test
4
2
2022.08.29T17:20:47.061
2022.08.29T17:20:47.061
2022.08.29T17:22:15.081
testJob: sleep(1000) => The task was cancelled.
comnode1
admin
demo2
1c16dfec-7c5a-92b3-414d-0cfbdc83b451
just a test
4
2
2022.08.29T17:20:47.061
2022.08.29T17:20:47.062
comnode1
admin
demo3
e9dffcc1-3194-9181-8d47-30a325774697
just a test
4
2
2022.08.29T17:20:47.061
2022.08.29T17:20:47.062
取消所有作业,查看作业情况,发现第 2、3 个作业的 errorMsg 也显示 The task was cancelled:
cancelJobEx()
pnodeRun(getRecentJobs)
返回:
node
userID
jobId
rootJobId
jobDesc
priority
parallelism
receivedTime
startTime
endTime
errorMsg
comnode1
admin
demo1
45c4eb71-6812-2b83-814e-ed6b22a99964
just a test
4
2
2022.08.29T17:20:47.061
2022.08.29T17:20:47.061
2022.08.29T17:22:15.081
testJob: sleep(1000) => The task was cancelled.
comnode1
admin
demo2
1c16dfec-7c5a-92b3-414d-0cfbdc83b451
just a test
4
2
2022.08.29T17:20:47.061
2022.08.29T17:20:47.062
2022.08.29T17:23:15.111
testJob: sleep(1000) => The task was cancelled.
comnode1
admin
demo3
e9dffcc1-3194-9181-8d47-30a325774697
just a test
4
2
2022.08.29T17:20:47.061
2022.08.29T17:20:47.062
2022.08.29T17:23:15.111
testJob: sleep(1000) => The task was cancelled.
3.2. closeInactiveSessions
语法
closeInactiveSessions(hours=12)
参数
hours: 一个数值,用于判断 session 是否过期的时长。单位为小时,默认值为 12。
返回值
返回一个表,包含所有节点仍活跃 sessions 的信息。其表结构与
getSessionMemoryStat
返回的表结构一致。
详情
若 session 最后一次活跃时间与当前时间的差值大于 hours 指定值,则认为该 session 过期了。调用
closeInactiveSessions
会将所有过期会话关闭。通过
getSessionMemoryStat
方法查看 session 最后一次活跃时间。
例子
getSessionMemoryStat()
返回:
userId
sessionId
memSize
remoteIP
remotePort
createTime
lastActiveTime
admin
1195587396
16
125.119.128.134
20252
2022.09.01T08:42:16.980
2022.09.01T08:45:23.808
guest
2333906441
16
115.239.209.122
37284
2022.09.01T06:39:05.530
2022.09.01T08:42:17.127
closeInactiveSessions(0.05)
返回:
userId
sessionId
memSize
remoteIP
remotePort
createTime
lastActiveTime
node
admin
1195587396
16
125.119.128.134
20252
2022.09.01T08:42:16.980
2022.09.01T08:45:23.808
DFS_NODE1
3.3. getDDL
语法
getDDL(database, tableName)
参数
database: 字符串,表示数据库的路径,如 "dfs://demodb"。
tableName: 字符串,表示分布式表名。
返回值
返回数据库创建语句、分布式表中各字段名称及类型、以及创建分布式表的语句。
详情
输出指定分布式表的建表语句。
例子
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x)
db=database("dfs://rangedb", RANGE, 0 5 10)
pt=db.createPartitionedTable(t, `pt, `ID)
getDDL("dfs://rangedb", "pt")
返回:
db = database("dfs://rangedb")
colName = `ID`x
colType = [INT,DOUBLE]
tbSchema = table(1:0, colName, colType)
db.createPartitionedTable(table=tbSchema,tableName=`pt,partitionColumns=`ID)
3.4. getTableDiskUsage
语法
getTableDiskUsage(database, tableName, byNode=false)
参数
database: 字符串,表示数据库的路径,如 "dfs://demodb"。
tableName: 字符串,表示分布式表名。
byNode: 布尔值,表示是否按节点显示磁盘使用量。默认值是 false,表示显示所有节点的磁盘使用总量。
返回值
返回一张记录磁盘占用信息的表,包含字段:
node: 字符串,表示节点别名。仅在 byNode = true 时显示。
diskGB: DOUBLE 浮点数,表示指定分布式表占用的磁盘空间。
详情
获取指定分布式表占用的磁盘空间大小。
例子
getTableDiskUsage("dfs://rangedb", "pt", true)
返回:
node
diskGB
DFS_NODE1
0.008498
3.5. dropRecoveringPartitions
语法
dropRecoveringPartitions(dbPath , tableName="")
参数
dbPath: 字符串,表示数据库的路径,如 "dfs://demodb"。
tableName: 字符串,表示分布式表名,仅当指定分区粒度 chunkGranularity 为 TABLE 时指定。关于 chunkGranularity 的说明参见:
database
。
详情
强制删除指定数据库的正在恢复的分区。当表的分区粒度 chunkGranularity 为 TABLE 时必须指定 tableName 参数。
例子
首先,查看集群中所有 chunk 的元数据信息。
rpc(getControllerAlias(), getClusterChunksStatus)
chunkId
file
size
version
vcLength
versionChain
state
replicas
replicaCount
lastUpdated
permission
5c3bd88f-8a13-a382-2848-cb7c6e75d0fa
/olapDemo/20200905/61_71/53R
0
2
3
19752:0:2:7460 -> 19506:0:1:7214 -> 19506:0:0:7214 ->
RECOVERING
DFS_NODE1:2:0:false:7494976728710525
1
2022.08.23T04:20:03.100
READ_WRITE
620526c7-6cf1-3c89-5444-de04f46aaa93
/olapDemo/20200904/51_61/53R
0
2
3
19746:0:2:7454 -> 19495:0:1:7203 -> 19495:0:0:7203 ->
RECOVERING
DFS_NODE1:2:0:false:7494976704543705
1
2022.08.23T04:20:02.564
READ_WRITE
由结果表看出,此时数据库 olapDemo 的 2 个分区 /olapDemo/20200904/ 和 /olapDemo/20200905/ 均处于 RECOVERING 状态。
调用 dropRecoveringPartitions 强制删除所有正在恢复的分区:
dropRecoveringPartitions("dfs://olapDemo");
3.6. getAllLicenses
语法
getAllLicenses()
参数
无
返回值
返回一张表,显示各个节点的 license 过期时间,包含字段:
nodeAlias: 字符串,表示节点别名。
endDate: 日期值,表示节点 license 过期时间。
详情
获取集群中各个节点的 license 过期时间。
例子
getAllLicenses()
nodeAlias
endDate
DFS_NODE1
2042.01.01
ctl18920
2042.01.01
agent
2042.01.01
3.7. updateAllLicenses
语法
updateAllLicenses()
参数
无
返回值
同
getAllLicenses()
的返回值
详情
在线更新集群中各个节点的 license,并返回 license 过期信息。
注意,调用此函数前,需要先替换 license 文件。
例子
updateAllLicenses()
nodeAlias
endDate
DFS_NODE1
2042.01.01
ctl18920
2042.01.01
agent
2042.01.01
3.8. unsubscribeAll
语法
unsubscribeAll(tbName=NULL)
参数
tbName: 字符串标量,表示要取消订阅的表名。默认值NULL,即如若不填参数,表示取消所有表的订阅。
详情
取消某个表的订阅,参数为NULL,即如若不填参数时可以取消所有表的订阅。
例子
share streamTable(10:0, `id`val, [INT, INT]) as st
t = table(10:0, `id`val, [INT, INT])
subscribeTable(tableName=`st, actionName=`sub_st, handler=append!{t})
undef(st, SHARED)
#error
All subscriptions to the shared stream table [st] must be cancelled before it can be undefined.
unsubscribeAll()
undef(st, SHARED)
取消某个表的订阅:
share streamTable(
10
:
0
, `id`val, [INT, DOUBLE])
as
test_
1
res = table(
10
:
0
, `id`val, [INT, DOUBLE])
subscribeTable(tableName=`test_
1
,handler=append!{res},actionName=
"sub_test_1"
)
unsubscribeAll(
"test_1"
)
3.9. gatherClusterPerf
语法
gatherClusterPerf(monitoringPeriod=60, scrapeInterval=15, dir="/tmp")
参数
monitoringPeriod: 整数值,表示监控时间,单位为秒,默认为 60。
scrapeInterval: 整数值,表示抓取间隔,单位为秒,默认为 15。
dir: 字符串,表示保存路径,默认为 "/tmp"。
详情
根据指定的监控时间和抓取间隔获取集群中各个节点的性能监控信息,并将结果保存至指定目录的 statis.csv 文件。输出内容说明见
getClusterPerf
。
例子
gatherClusterPerf(30, 3, "/tmp")
// 30s 后查看 /tmp/statis.csv 里的结果
3.10. gatherStreamingStat
语法
gatherStreamingStat(subNode, monitoringPeriod=60, scrapeInterval=15, dir="/tmp")
参数
subNode: 字符串,表示订阅节点的别名。
monitoringPeriod: 整数值,表示监控时间,单位为秒,默认为 60。
scrapeInterval: 整数值,表示抓取间隔,单位为秒,默认为 15。
dir: 字符串,表示保存路径,默认为 "/tmp"。
详情
根据指定的监控时间和抓取间隔获取指定订阅节点的工作线程的状态信息,并将结果保存至指定目录的 sub_worker_statis.csv 文件。输出内容说明见
getStreamingStat
。
例子
gatherStreamingStat(30, 3, "/tmp")
// 30s 后查看 /tmp/sub_worker_statis.csv 里的结果
3.11. getDifferentData
语法
getDifferentData(t1, t2)
参数
t1: 内存表句柄。
t2: 内存表句柄。
返回值
若存在不同行,返回不同的行;否则打印 "Both tables are identical"。
详情
使用
eqObj
比较两张内存表的每一行是否相同。比较的两张表的长度必须相同。
例子
t1=table(1 2 3 as id, 4 5 6 as val)
t2=table(1 8 9 as id, 4 8 9 as val)
t3=table(1 2 3 as id, 4 5 6 as val)
for (row in getDifferentData(t1, t2))
print row
返回:
id val
-- ---
2 5
3 6
id val
-- ---
8 8
9 9
getDifferentData(t1, t3)
返回:
Both tables are identical
3.12. checkChunkReplicas
语法
checkChunkReplicas(dbName, tableName, targetChunkId)
参数
dbName: 字符串,表示数据库的路径,如 "dfs://demodb"。
tableName: 字符串,表示分布式表名。
targetChunkId: 字符串,表示要检查的 chunk 的 ID,可通过
getTabletsMeta()
查看。
返回值
布尔值,表示指定分区的副本数据是否一致。
详情
检查数据库表指定分区的两个副本的数据是否一致。仅当控制节点配置 dfsReplicationFactor 值为 2 时有效。
例子
n=1000000
ID=rand(10, n)
x=rand(1.0, n)
t=table(ID, x)
db=database("dfs://rangedb", RANGE, 0 5 10)
pt=db.createPartitionedTable(t, `pt, `ID)
pt.append!(t)
checkChunkReplicas("dfs://rangedb", "pt", "af8268f0-151e-c18b-a84c-a77560b721e6") // chunk ID 可通过 getTabletsMeta() 查看
返回:true
使用
kill -9 PID
杀死其中一个数据节点,执行如下脚本:
pt.append!(t)
checkChunkReplicas("dfs://rangedb", "pt", "af8268f0-151e-c18b-a84c-a77560b721e6") // chunk ID 可通过 getTabletsMeta() 查看
返回:
checkChunkReplicas: throw "colFiles on two replicas are not same" => colFiles on two replicas are not same
重新启动杀死的数据节点,待副本数据同步后,再次执行 checkChunkReplicas():
checkChunkReplicas("dfs://rangedb", "pt", "af8268f0-151e-c18b-a84c-a77560b721e6") // chunk ID 可通过 getTabletsMeta() 查看
返回:true
3.13. clearAllSubscriptions
语法
clearAllSubscriptions()
参数
该函数无参数
返回值
返回取消订阅的流数据表名称和句柄名称,并打印"All subscriptions have been cleared !"。
详情
取消当前节点所有的流数据表订阅。
例子
clearAllSubscriptions()
返回:
unsub: st, sub1
All subscriptions have been cleared !
3.14. dropAllEngines
语法
dropAllEngines()
参数
该函数无参数
返回值
返回:
All engines have been dropped !
详情
释放当前节点所有的流数据引擎的定义。
例子
dropAllEngines()
返回:
All engines have been dropped !
3.15. existsShareVariable
语法
existsShareVariable(names)
参数
names: 可以是字符串标量或向量,表示对象名。
返回值
返回一个标量/向量,表示names中的每个元素是否为共享变量。
详情
判断一个字符串标量或向量中的每个元素是否为共享变量。
例子
share streamTable(10000:0, `timestamp`sym`val, [TIMESTAMP, SYMBOL, INT]) as variable1
existsShareVariable("variable1")
返回:true
3.16. clearAllSharedTables
语法
clearAllSharedTables()
参数
该函数无参数
返回值
返回删除的共享表的表名,并打印"All shared table have been cleared !"。
详情
删除当前节点所有的共享表。
例子
clearAllSharedTables()
返回:
Drop Shared Table: st
All shared table have been cleared !
3.17. clearAllStreamEnv
语法
clearAllStreamEnv()
参数
该函数无参数
返回值
同clearAllSubscriptions()、dropAllEngines()、clearAllSharedTables()三个函数的返回值汇总。
详情
清除当前节点所有的流数据环境,包括流数据表订阅、流数据引擎和共享表。
例子
clearAllStreamEnv()
返回:
unsub: st, sub1
All subscriptions have been cleared !
All engines have been dropped !
Drop Stream Table: dummyTable1
All stream table have been cleared !
3.18. getPersistenceTableNames
语法
getPersistenceTableNames()
参数
该函数无参数
返回值
所有共享持久化流表的表名。
详情
获得所有共享持久化流表的表名。
例子
getPersistenceTableNames()
返回:[st1,st2]
3.19. getNonPersistenceTableNames
语法
getNonPersistenceTableNames()
参数
该函数无参数
返回值
所有非持久化共享流表名。
详情
获取所有非持久化共享流表名。
例子
getNonPersistenceTableNames()
返回:[st1,st2]
3.20. getPersistenceStat
语法
getPersistenceStat()
参数
该函数无参数
返回值
返回所有启用了持久化的共享流数据表的元数据。
详情
获取所有持久化共享流表的状态。
例子
getPersistenceStat()
返回:
lastLogSeqNum
sizeInMemory
asynWrite
compress
retentionMinutes
sizeOnDisk
persistenceDir
hashValue
diskOffset
totalSize
raftGroup
memoryOffset
tablename
-1
0
TRUE
TRUE
1440
0
C:/DolphinDB/Data/st2
1
0
0
-1
0
st2
3.21. getNonPersistenceTableStat
语法
getNonPersistenceTableStat()
参数
该函数无参数
返回值
返回所有非持久化的共享流数据表的元数据。
详情
获取所有非持久化共享流表状态。
例子
getNonPersistenceTableStat()
TableName
rows
columns
bytes
st3
0
3
20
3.22. clearAllPersistenceTables
语法
clearAllPersistenceTables()
参数
该函数无参数
返回值
该函数无返回值。
详情
删除所有持久化流表。
例子
clearAllPersistenceTables()
3.23. getDatabaseDDL
语法
getDatabaseDDL(dbName)
参数
dbName : 库名(字符串标量)
返回值
建库语句(字符串标量)
详情
获得目标库的建库语句。
例子
dbName = "dfs://testDatabaseRANGE"
db1 = database(dbName, RANGE, 1985.01.01 1990.01.01 1995.01.01 2000.01.01 2005.01.01 2010.01.01)
getDatabaseDDL(dbName)
返回:
database(directory = 'dfs://testDatabaseRANGE', partitionType = RANGE, partitionScheme =[1985.01.01,1990.01.01,1995.01.01,2000.01.01,2005.01.01,2010.01.01], engine= `OLAP, atomic = `TRANS)
3.24. getDBTableDDL
语法
getDBTableDDL(dbName,tbName)
参数
dbName : 库名(字符串标量)
tbName : 表名(字符串标量)
返回值
数据库中的建表语句(字符串标量)
详情
获得目标库内的表的建表语句。
例子
dbName = "dfs://test_OLAP_RANGE"
tbName1 = "partition1"
tbName2= "dimension1"
db1 = database(dbName, RANGE, 1985.01.01 1990.01.01 1995.01.01 2000.01.01 2005.01.01 2010.01.01)
tbSchema = table(1:0, `SecurityID`DateTime`Open`High`Low`Close, [SYMBOL, DATETIME, DOUBLE, DOUBLE, DOUBLE, DOUBLE])
db = database(dbName)
tb1 = createPartitionedTable(db, tbSchema, tbName1, ["DateTime"])
tb2 = createTable(db, tbSchema, tbName2)
getDBTableDDL(dbName,tbName1)
getDBTableDDL(dbName,tbName2)
返回:
createPartitionedTable(dbHandle = database('dfs://test_OLAP_RANGE'),table = table(1:0, ["SecurityID","DateTime","Open","High","Low","Close"],["SYMBOL","DATETIME","DOUBLE","DOUBLE","DOUBLE","DOUBLE"]),tableName = 'partition1',partitionColumns =["DateTime"],compressMethods = dict(["SecurityID","DateTime","Open","High","Low","Close"],["lz4","lz4","lz4","lz4","lz4","lz4"]))
createTable(dbHandle = database('dfs://test_OLAP_RANGE'),table = table(1:0, ["SecurityID","DateTime","Open","High","Low","Close"],["SYMBOL","DATETIME","DOUBLE","DOUBLE","DOUBLE","DOUBLE"]),tableName = 'dimension1',compressMethods = dict(["SecurityID","DateTime","Open","High","Low","Close"],["lz4","lz4","lz4","lz4","lz4","lz4"]))
FILE:references/doc_9355.md
# initcap
**URL**: https://docs.dolphindb.cn/zh/funcs/i/initcap.html
**来源**: DolphinDB 官方文档
---
initcap
语法
initcap(X)
详情
将
X
中由分隔符分隔的字符串中的第一个英文字符设置为大写,其余英文字符设置为小写。其中,分隔符是除英文字符和数字外的任意字符,例如:汉字,空格,@
等。
注:
该函数将数字也视为英文字符。
参数
X
STRING 类型的标量/向量,或 SYMBOL 类型的向量。
返回值
和
X
类型保持一致。
例子
initcap("hello world")
// output
Hello World
initcap("1aBBBBBB")
// output
1abbbbbb
initcap("nihao, hello@you")
// output
Nihao, Hello@You
initcap("你好hello" "hello You")
// output
["你好Hello","Hello You"]
initcap(symbol(["adhE","","1yI"]))
// output
["Adhe",,"1yi"]
FILE:references/doc_936.md
# isSpace
**URL**: https://docs.dolphindb.cn/zh/funcs/i/isSpace.html
**来源**: DolphinDB 官方文档
---
isSpace
语法
isSpace(X)
详情
判断
X
是否为空格类字符串。如果
X
中的字符都是空格、跳格符(\t)、回车符(\r)或换行符(\n),该函数返回 true,反之,返回 false。对于空字符串(STRING 类型的 NULL
值),该函数返回 false。
参数
X
是字符或字符串类型的标量、向量或表。
返回值
当
X
是标量时,返回布尔标量。
当
X
是向量时,返回布尔向量。
当
X
是表时,返回一个表。
例子
isSpace("hello world");
// output: false
isSpace(" \t ");
// output: true
isSpace(string());
// output: false
FILE:references/doc_9369.md
# mkdir
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mkdir.html
**来源**: DolphinDB 官方文档
---
mkdir
语法
mkdir(directory)
详情
创建一个目录。该函数必须要用户登录后才能执行。
参数
directory
为要创建的目录的名字。
返回值
返回一个内存表。
例子
files("/home/test");
filename
isDir
fileSize
lastAccessed
lastModified
dir3
1
0
1496649999597
1496649999597
mkdir("/home/test/dir1");
mkdir("/home/test/dir2");
mkdir("/home/test/dir3");
// output
The directory [/home/test/dir3] already exists.
files("/home/test");
filename
isDir
fileSize
lastAccessed
lastModified
dir1
1
0
1496651628372
1496651628372
dir2
1
0
1496651645598
1496651645598
dir3
1
0
1496649999597
1496649999597
FILE:references/doc_9374.md
# getGroupAccess
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getGroupAccess.html
**来源**: DolphinDB 官方文档
---
getGroupAccess
语法
getGroupAccess(groupIds)
详情
查询组的权限。只能由管理员执行该函数。
注:
自 3.00.2 版本起,支持获取访问计算节点组的权限。
自 3.00.0 版本起,支持获取访问 catalog 的相关权限。
参数
groupIds
表示组名的字符串标量或向量。
返回值
一个内存表,包含组权限信息。
例子
getGroupAccess("myGroup")
FILE:references/doc_9375.md
# getAllClusters
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getAllClusters.html
**来源**: DolphinDB 官方文档
---
getAllClusters
语法
getAllClusters()
详情
获取所有集群名称。只能由管理员在 MoM(Master of Master,管理集群)上执行该函数。
参数
无
返回值
一个表,包含以下字段:
clusterName:集群名称,字符串。
clusterType:集群类型,字符串。“momCluster” 代表多集群的管理集群;”memberCluster” 代表普通集群,即被 MoM
管理的集群。
status:集群存活状态,整型。 0 代表异常,1 代表存活。
例子
getAllClusters()
clusterName
clusterType
status
ShangHai_cluster2
memberCluster
1
Hangzhou_cluster1
momCluster
1
ShangHai_cluster1
memberCluster
1
FILE:references/doc_9376.md
# call
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/call.html
**来源**: DolphinDB 官方文档
---
call
语法
call(func, args...)
详情
用指定的参数调用一个函数。常常用在
each
/
peach
或
loop
/
ploop
中,用来调用一批函数。
参数
func
是一个函数名。
args
是函数func的参数。
返回值
取决于
func(args)
的返回值。
例子
call(sum, 1..10);
// output
55
// 等同于sum(1..10)
each(call, [avg, sum], [0..10, 0..100]);
// output
[5,5050]
each(call{, 1..3},(sin,log));
// 注意call{, 1..3}是一个部分应用
sin
log
0.841471
0
0.909297
0.693147
0.14112
1.098612
FILE:references/doc_9381.md
# SQL Trace
**URL**: https://docs.dolphindb.cn/zh/progr/sql/sql_trace.html
**来源**: DolphinDB 官方文档
---
SQL Trace
SQL Trace 是 DolphinDB 提供的一套函数工具,它能够通过跟踪 SQL 脚本的执行过程,分析复杂 SQL
查询的内部耗时,以达到定位问题并优化执行的目的。
setTraceMode
函数用于开启或关闭 SQL Trace。一次完整的跟踪流程必须以
setTraceMode(true)
作为开启标识,并以
setTraceMode(false)
作为结束标识。需要注意的是,DolphinDB 从开启跟踪功能后接收到的第一次请求开始跟踪。因此,
setTraceMode
命令必须单独执行,而不能和待跟踪的语句放在同一脚本中一起执行。
开启跟踪后,可以通过调用
getTraces()
函数来获取一张包含跟踪信息的表。这张表记录了客户端将脚本发送给服务器的时间戳、客户端发送给服务器端执行的脚本、记录SQL Trace信息的 id 和发起 SQL Trace
的会话的 id。
例如,下面的脚本展示了一次完整的 SQL Trace
跟踪流程。
setTraceMode(true)
go
select * from loadTable("dfs://S_SEC_INFO", "S_SEC_INFO")
setTraceMode(false)
使用
getTraces()
函数得到的跟踪信息如下图所示。
此外,使用
viewTraceInfo(traceId, [isTreeView = true])
还可以展示某个 traceId
对应脚本的跟踪信息。例如,要查看上面执行的 SQL 脚本的跟踪信息,可以使用以下命令。
viewTraceInfo("2eb58830-90cd-e3b3-4544-429237e80ad8")
下图以树状结构清晰地展示了 SQL 的执行流程,并详细列出了每个步骤的脚本执行耗时。
FILE:references/doc_9382.md
# scheduleJob
**URL**: https://docs.dolphindb.cn/zh/funcs/s/scheduleJob.html
**来源**: DolphinDB 官方文档
---
scheduleJob
语法
scheduleJob(jobId, jobDesc, jobFunc, scheduleTime, startDate, endDate,
frequency, [days], [onComplete], [priority], [parallelism])
详情
提交定时任务。我们可以使用
getRecentJobs
来查看最近完成的定时任务。
执行定时任务生成的信息保存在 jodId.msg 文件中;如果定时任务会返回值,它会保存在 jobId.object 文件中。
jobId.msg 和 jobId.object 保存在 batchIobs 文件夹中。我们可以分别使用
getJobMessage
和
getJobReturn
来查看这两个文件。
参数
jobId
是一个字符串。
jobDesc
是关于任务描述的字符串。
jobFunc
是一个没有参数的函数。它通常是一个部分应用。注意:若该函数是一个自定义函数,则它只能接收标量、数据对或常规数组作为默认参数。
scheduleTime
是一个 MINUTE 类型的标量/向量。任务之间的时间间隔最小为5分钟。
startDate
是一个日期标量。
endDate
是一个日期标量。
frequency
是一个字符。它可以是下列3个值之一:'D' 表示每日,'W' 表示每周,'M' 表示每月。
days
是一个整型标量/向量,表示执行定时任务的日期。如果
frequency
为 'W' 或 'M' 时,它是必需的。如果
frequency
为W,
days
可以取以下值:0(周日),1(周一),...,5(周五),6(周六)。
onComplete
是一个有4个参数的回调函数,细节请见以下最后一个例子。当定时作业执行完毕(包括有异常的情况)后,会执行该函数。可通过该函数向外部消息系统如邮件系统或微信与钉钉发送消息。
priority
属于 0 到 8 的整数,表示任务的优先级。默认值为 4。
parallelism
属于 0 到 8 的整数,表示任务的并行度。默认值为 2。
注:用户设置的优先级和并行度,还分别受到
setMaxJobPriority
的参数
maxPriority
和
setMaxJobParallelism
的参数
maxParallelism
限制。最终的优先级和并行度分别为 min(
priority
,
maxPriority
),
min(
parallelism
,
maxParallelism
)。
返回值
返回定时任务的任务 ID。如果
jobId
与已有的定时任务的 ID 不一致,系统返回
jobId
。否则在
jobId
后面添加当前日期,"000", "001" 等作为后缀,直到产生唯一的任务 ID。
例子
定时执行一个函数:
def f():1+2;
scheduleJob(jobId=`daily, jobDesc="Daily Job 1", jobFunc=f, scheduleTime=17:23m, startDate=2018.01.01, endDate=2018.12.31, frequency='D');
scheduleJob(jobId=`weekly, jobDesc="Weekly Job", jobFunc=f, scheduleTime=17:30m, startDate=2018.01.01, endDate=2018.12.31, frequency='W', days=2);
定时执行一个脚本:
scheduleJob(jobId=`monthly, jobDesc="Monthly Job 1", jobFunc=run{"monthlyJob.dos"}, scheduleTime=17:23m, startDate=2018.01.01, endDate=2018.12.31, frequency='M', days=1);
这里使用部分应用 run{<script>},因为
jobFunc
必须是没有参数的函数。
getJobMessage(`daily);
// output
018-02-08 17:23:27.166296 Start the job [daily]: Daily Job 1
018-02-08 17:23:27.167303 The job is done.
getJobReturn(`daily);
// output
3
可以在一天中多次定时执行相同的任务:
scheduleJob(jobId=`Trading, jobDesc="Generate Trading Tickets", jobFunc=run{"TradingTickets.dos"}, scheduleTime=[09:25m, 12:00m, 02:00m, 15:50m], startDate=2018.01.01, endDate=2018.12.31, frequency='D');
在这种情况下,每次执行定时任务时,任务 ID 是不一样的。
可以在每周的工作日中多次执行相同的定时任务:
scheduleJob(jobId=`PnL, jobDesc="Calculate Profit & Loss", jobFunc=run{"PnL.dos"}, scheduleTime=[12:00m, 02:00m, 14:50m], startDate=2018.01.01, endDate=2018.12.31, frequency='W', days=[1,2,3,4,5]);
定时任务执行结束后可发送邮件通知。以下脚本运行前需安装 HttpClient 插件。
def sendEmail(jobId, jobDesc, success, result){
desc = "jobId=" + jobId + " jobDesc=" + jobDesc
if(success){
desc += " successful " + result
res = httpClient::sendEmail('[email protected]','password','[email protected]','This is a subject',desc)
}
else{
desc += " with error: " + result
res = httpClient::sendEmail('[email protected]','password','[email protected]','This is a subject',desc)
}
}
scheduleJob(jobId=`PnL, jobDesc="Calculate Profit & Loss", jobFunc=run{"PnL.dos"}, scheduleTime=[12:00m, 02:00m, 14:50m], startDate=2018.01.01, endDate=2018.12.31, frequency='W', days=[1,2,3,4,5], onComplete=sendEmail);
FILE:references/doc_9389.md
# sem
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sem.html
**来源**: DolphinDB 官方文档
---
sem
语法
sem(X)
详情
返回
X
的平均值的标准误差。
若
X
为矩阵,计算每列的标准误差,返回一个向量。
若
X
为表,计算每列的标准误差,返回一个表。
参数
X
是数值型向量、矩阵或表。
返回值
返回 DOUBLE 类型的标量、向量或表。
例子
sem([85,90,95,NULL]);
// output
2.886751
FILE:references/doc_9396.md
# fromStdJson
**URL**: https://docs.dolphindb.cn/zh/funcs/f/fromStdJson.html
**来源**: DolphinDB 官方文档
---
fromStdJson
语法
fromStdJson(X)
详情
将标准 JSON 文本转化为符合 DolphinDB 规范的数据。
转换规则说明:
JSON 数据类型
对应 DolphinDB 数据类型/形式
对象
转换为字典,key 类型始终为 STRING;如果其 value 由多种类型组成,那么 value 的类型为
ANY。
数组
向量
字符串
优先解析为 TEMPORAL 类型;如果解析失败,则转换为 STRING。
数字
DOUBLE
布尔值
BOOL
null
NULL
注:
该函数会自动解析表示转义的特殊字符,如
\n
、
\r
等。
参数
X
符合标准 JSON 格式的字符串,或由这些字符串组成的向量。
返回值
返回值的数据形式和类型由输入 JSON 的数据类型决定,具体转换规则参见详情中的规则转换表。
例子
X = "\"\\u4e2d\\u6587\"";
fromStdJson(X);
//output: 中文
X = "\"\\u4e2d\\n\\u6587\"";
fromStdJson(X);
//output: 中
// 文
X = "[1, 2, 3]";
fromStdJson(X);
//output:[1,2,3]
X = "[1, null, false, \"2012.06.13 13:30:10\", [\"\\u5d4c\\u5957\\u6570\\u7ec4\"]]";
fromStdJson(X);
//output:(1,,false,2012.06.13T13:30:10,["嵌套数组"])
X = "{\"1\": \"2017.07.10 14:10:12\",\"0\": \"2012.06.13 13:30:10\"}";
fromStdJson(X);
//output:1->2017.07.10T14:10:12
// 0->2012.06.13T13:30:10
相关函数:
toStdJson
FILE:references/doc_940.md
# DolphinDB 终端
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/terminal.html
**来源**: DolphinDB 官方文档
---
DolphinDB 终端
DolphinDB 终端(DolphinDB Terminal)是一个命令行交互式工具,用于连接到远程的 DolphinDB
服务器执行命令。使用终端的优点是可以快速连接到远端数据库上执行一些交互命令和脚本。缺点是没有图形化界面,不适用于开发和执行大量复杂代码。
DolphinDB 终端和 DolphinDB 服务器用的是同一个程序,1.10.4及以上版本方可支持。当用户启动 DolphinDB
的时候,如果指定参数
remoteHost
和
remotePort
,当前进程将被启动为 DolphinDB
终端。如果服务器不允许guest用户登录,启动时可参数
uid
和
pwd
指定用户名和密码,也可以在启动后的终端中通过 login 命令登录。DolphinDB 的工作非常简单,接受用户的输入并发送到远程服务器执行,最后把执行结果在终端显示。因此
DolphinDB 终端不需要 license,也不需要系统初始化脚本 dolphindb.dos 以及其它配置文件。DolphinDB
的终端可以是跨操作系统的,例如Windows上的终端可以访问Linux的DolphinDB的服务器。
基本用法
注:
在第一次启动 DolphinDB 时,需要给执行文件
dolphindb
添加可执行权限。进入 server 目录,执行以下 Shell
指令:
chmod +x dolphindb
下面的命令是在
Linux 上启动 DolphinDB 终端的示例。由于默认 shell 不支持命令上下回滚,所以需要借助 rlwrap 命令来实现。
rlwrap -r ./dolphindb -remoteHost
127.0
.
0.1
-remotePort
8848
-uid admin -
pwd
123456
下面的命令是在 Windows 上启动 DolphinDB 终端的示例。
dolphindb.exe -remoteHost
127.0
.
0.1
-remotePort
8848
-uid admin -
pwd
123456
成功登入后,系统会显示 DolphinDB Termninal,如下:
DolphinDB Terminal
1.10
.
4
(Build:
2020.04
.
03
). Copyright (c)
2011
~
2019
DolphinDB, Inc.
如果启动终端时不指定登录信息,可以在连接后使用 login 命令。
>DolphinDB Terminal
1.10
.
4
(Build:
2020.04
.
03
). Copyright (c)
2011
~
2019
DolphinDB, Inc.
>login(
"admin"
,
"123456"
);
DolphinDB 终端支持单行或多行脚本。只要在代码末尾加上分号
;
或者
go
语句,系统就会将代码发送到远端执行。通过分号
;
单句提交示例如下:
1+2;
多句提交示例如下:
def myFunc(x,y){
return x+y
}
myFunc(1,2);
由于分号
;
会触发解析它们之前的代码,如果将其放在自定义函数中间,会造成函数定义无法完整传送到远端,从而造成解析错误,例如:
def myFunc(x,y){
return x+y;
}
myFunc(1,2);
//抛出语法接异常
Syntax Error: [line #2] } expected to end function definition
退出终端使用 quit 指令。
quit + Enter
为方便在任何工作目录下启动终端,可以将 DolphinDB 可执行文件目录(即包含 dolphindb 或者
dolphindb.exe 的目录),添加到系统的搜索路径中。Linux 上可以 export 到
PATH
export
PATH=/your/dolphindb/excutable/path:$PATH
在 Windows 上可以将可执行文件路径添加到系统环境变量
Path
中。格式为分号加全路径(注意分号必须是英文分号)。路径设置完成后,可以通过打开 dos 或者 PowerShell 窗口,在任意目录下,通过 dolphindb
命令启动终端。
本地执行脚本
通过终端交互式或批量执行脚本覆盖了大部分的应用场景。但是某些场景下,需要同时能够在本地和远端执行脚本。譬如,本地读取一个 csv
文件,然后追加到运行在远端 DolphinDB 数据库中。这种模式我们称之为
命令行本地脚本执行
。下面是在 Linux
上启动命令行本地脚本执行的示范:
./dolphindb -run /home/usr1/
test
.dos
Windows 上启动命令行本地脚本执行非常类似:
dolphindb.exe -run c:/users/usr1/
test
.dos
启动命令行本地脚本执行,只要通过启动参数 run 指定一个本地的脚本文件,同时不指定参数 remoteHost
即可。本质上是启动了一个 DolphinDB 的工作站(workstation) 来执行脚本,完成后退出。因此,命令行本地执行脚本文件的配置跟工作站的配置一样,需要
dolphindb.lic 和 dolphindb.dos。在 Windows 下,还需要 tzdb 目录。
那么在本地脚本执行过程中,如何连接到远端数据库进行操作呢?我们需要通过 xdb 函数创建一个到远程数据库的连接,然后使用
remoteRun 函数执行一个脚本或进行rpc调用。DolphinDB 对 rpc
调用进行了扩展,不仅可以调用远端服务器上定义的函数,也可以将本地的函数序列化到远端服务器执行。如果需要执行的脚本比较复杂,一般我们建议定义成一个本地的函数,然后通过
rpc 调用来完成。
下面的脚本文件
test.dos
,演示了如何将本地的一个 csv
文件,写入到远程的一个分布式数据库表中。
def appendData(dbPath, partitionTable, t1){
pt = loadTable(dbPath, partitionTable)
return tableInsert(pt, t1)
}
conn=xdb("127.0.0.1",8848,"admin","123456")
remoteRun(conn, appendData, "dfs://db1", "pt", loadText("c:/users/usr1/data.csv"))
我们首先定义一个函数
appendData
,将一个内存表写入到指定的数据库表中。然后创建一个远程连接 conn。最后通过
loadText
函数加载本地的 csv 文件,rpc 调用
appendData
函数。
远程执行脚本
DolphinDB 终端可以让用户方便地连接到远端 DolphinDB
服务器,并以交互的方式执行命令。但是如果所有需要执行的脚本已经写在一个脚本文件中,那么我们有更简单的办法在远端服务器上批处理执行这些脚本。只要在启动 DolphinDB
终端的命令中额外指定一个参数
run
,即可将
run
参数指定的本地脚本文件发送到远端服务器上执行。执行完成后终端马上退出。我们称这种模式为命令行远程脚本执行。使用示例如下。
注:
/home/usr1/test.dos
是本地而非远程服务器上的脚本文件。
./dolphindb -remoteHost
127.0
.
0.1
-remotePort
8848
-uid admin -
pwd
123456
-run /home/usr1/
test
.dos
命令行远程脚本执行是 DolphinDB
终端的一个特殊应用。相对于终端模式,优点是无需在终端中输入代码,可以执行更复杂的代码,以及用于重复执行特定任务。例如,定期连接到远端服务器数据库执行脚本中的代码,执行完即退出。缺点是,没有交互模式。
注:
通过
-run
使用远端服务器执行本地脚本文件时,如遇异常,返回非 0
值。
FILE:references/doc_9420.md
# restoreDislocatedTablet
**URL**: https://docs.dolphindb.cn/zh/funcs/r/restoreDislocatedTablet.html
**来源**: DolphinDB 官方文档
---
restoreDislocatedTablet
语法
restoreDislocatedTablet()
详情
当配置分区粒度为表级分区时(详见
StandaloneMode
enableChunkGranularityConfig
参数),同一个分区的所有表将分布在相同的节点下。当调用函数
rebalanceChunksAmongDataNodes
进行数据平衡时,若出现节点宕机或离线,可能出现同一个分区里部分表的数据转移成功,部分表的数据转移失败的情况,即同一个分区下的不同表会分布在不同的节点。该函数可以修复此问题,将同一个分区里的表转移到同一个节点下。
注:
该函数必须在控制节点下运行。
调用该函数后,可以在进行数据平衡的数据节点上执行
getRecoveryTaskStatus
查看任务执行的状态。
参数
无
返回值
返回一个表,包含以下列:
列名
含义
chunkId
chunk 的唯一标识
srcNode
源节点的别名
destNode
目标节点的别名
例子
restoreDislocatedTablet()
ChunkId
srcNode
destNode
99279094-ca12-3b87-48b6-520cbb986f39
node1
node2
45f612b8-42f5-aebd-4cef-e522b6ae1fc8
node1
node2
FILE:references/doc_9431.md
# withNullFill
**URL**: https://docs.dolphindb.cn/zh/funcs/ho_funcs/withNullFill.html
**来源**: DolphinDB 官方文档
---
withNullFill
语法
withNullFill(func, x, y, fillValue)
详情
如果 x 与 y 中相同位置的元素只有一个为NULL,使用 fillValue 替换 NULL 值参与计算。
如果 x 和 y 相同位置的元素均为 NULL,返回 NULL。
参数
func
是一个DolphinDB内置函数,须为双目运算符,例如+, -, *, /, , %, pow, and, or 等。
x
与
y
是向量或矩阵。
fillValue
是一个标量。
返回值
一个与
func(x, y)
结果结构和维度一致的向量或矩阵。
例子
x = 0 1 NULL NULL 2
y = 1 NULL 2 NULL 3;
add(x,y);
// output
[1,,,,5]
withNullFill(add, x, y, 0);
// output
[1,1,2,,5]
m=matrix(1..5, y);
m;
col1
col2
1
1
2
3
2
4
5
3
add(x, m);
col1
col2
1
1
3
7
5
withNullFill(add, x, m, 0);
col1
col2
1
1
3
1
3
2
4
7
5
FILE:references/doc_9445.md
# syncDict
**URL**: https://docs.dolphindb.cn/zh/funcs/s/syncDict.html
**来源**: DolphinDB 官方文档
---
syncDict
语法
syncDict(keyObj, valueObj, [sharedName], [ordered=false])
或
syncDict(keyType, valueType, [sharedName], [ordered=false])
详情
创建一个线程安全的同步字典。同步字典允许多个线程对其进行并发读写。
参数
第一种用法中,
keyObj
是表示键的标量或向量,
valueObj
是表示值的标量或向量。
第二种用法中,
keyType
是字典键的数据类型;
valueType
是字典值的数据类型。系统支持以下键的数据类型:Logical, Integral, Floating和Temporal。字典中的值不支持
COMPLEX, POINT 类别。
sharedName
为一个字符串。指定后此字典会被共享,共享的字典名为
sharedName
。
ordered
一个布尔值,默认为 false,表示创建一个无序字典。当
ordered
= true
时,创建一个有序字典。无序字典在输出或进行遍历时,其键值对不保留输入时的顺序;有序字典在输出或进行遍历时,键值对的顺序与输入顺序保持一致。
返回值
一个字典。
例子
例1:
x=
1
6
3
y=
4.5
7.8
4.3
z=syncDict(x,y);
// output
3
->
4.3
1
->
4.5
6
->
7.8
z=syncDict(INT,DOUBLE)
z[
5
]=
7.9
z;
// output
5
->
7.9
syncDict(INT,DOUBLE, `sn)
sn[
5
6
]=
10.99
2.33
sn[
5
];
// output
10.99
// y 为 DECIMAL32 类型的向量,将 y 作为 value 值创建有序字典 z
x=
1
3
2
y = decimal32(
1.23
3
3.14
,
3
)
z=dict(x,y,true);
z;
// output
1
->
1.230
3
->
3.000
2
->
3.140
下面的例子中,我们分别对普通字典 z1 和同步字典 z2 并发写入。
对普通字典 z1 进行多线程并发写入会造成节点崩溃:
def
task1(mutable d,n){
for
(i
in
0.
.n){
d[i]=i*
2
}
}
def
task2(mutable d,n){
for
(i
in
0.
.n){
d[i]=i+
1
}
}
n=
10000000
z1=dict(INT,INT)
jobId1=submitJob(
"task1"
,,task1,z1,n)
jobId2=submitJob(
"task2"
,,task2,z1,n);
同步字典 z2 允许多线程并发写入:
z2=syncDict(INT,INT)
jobId3=submitJob(
"task1"
,,task1,z2,n)
jobId4=submitJob(
"task2"
,,task2,z2,n)
getJobReturn(jobId3, true)
getJobReturn(jobId4, true)
z2;
相关函数:
array
,
matrix
,
dictUpdate!
,
dict
例 2:syncDict 与
go
配合使用:
syncDict(SYMBOL,RESOURCE,`resDict)
go
resDict[`a]=10
FILE:references/doc_9448.md
# interpolate
**URL**: https://docs.dolphindb.cn/zh/funcs/i/interpolate.html
**来源**: DolphinDB 官方文档
---
interpolate
语法
interpolate(X, [method='linear'], [limit], [inplace=false],
[limitDirection='forward'], [limitArea], [index])
详情
填充数值型向量中的缺失值。默认情况下,基于 X 中每个元素的下标索引(0, 1, 2, ...,
size(X)-1)进行插值计算。支持自定义横坐标的插值计算,详见参数
index
。
参数
X
是一个数值型向量。
method
可选参数,是一个字符串,表示插值的方式。它的可取值为:
'linear':线性插值
'pad':使用已有的值填充
'nearest':使用最接近 NULL 值的有效值填充
注:
若
method
= 'nearest' 且
limitDirection =
'both',当 NULL 值与两侧最近有效值的距离相同时,取
左侧
的有效值填充。
'krogh':使用 krogh 多项式插值
如果没有指定,默认值为 'linear'。
limit
可选参数,是一个正整数,表示最多要填充的连续 NULL 值的个数。
inplace
可选参数, 是一个布尔值,表示是否使用结果覆盖输入的
X
。默认值为
false,会返回一个新的向量。
limitDirection
可选参数, 是一个字符串,表示填充 NULL 的方向。它的可取值为:'forward',
'backward' 和 'both'。默认值为 'forward'。
limitArea
可选参数, 是一个字符串,表示填充的区域。它的可取值为:
空字符串: 填充的区域没有限制
'inside': 只填充有效值包围的 NULL 值
'outside': 只填充有效值之外的 NULL 值
index
可选参数,是一个时间类型或数值类型的索引向量,与 X 等长且不包含空值。当指定
index
时,函数将以该索引向量为横坐标,X
为纵坐标,对 X 中的缺失值进行插值。
返回值
返回填充后的数值型向量。
例子
a=[NULL,NULL,1,2,NULL,NULL,5,6,NULL,NULL];
interpolate(a);
// output: [,,1,2,3,4,5,6,6,6]
interpolate(X=a, method="pad");
// output: [,,1,2,2,2,5,6,6,6]
interpolate(X=a, limitDirection='both');
// output: [1,1,1,2,3,4,5,6,6,6]
interpolate(X=a, limit=1, limitDirection='both');
// output: [,1,1,2,3,4,5,6,6,]
interpolate(X=a, limitDirection='both', limitArea='outside');
// output: [1,1,1,2,,,5,6,6,6]
a;
// output: [,,1,2,,,5,6,,]
interpolate(X=a, limitDirection='backward', inplace=true);
// output: [1,1,1,2,3,4,5,6,,]
a;
// output: [1,1,1,2,3,4,5,6,,]
dates=[2023.10.01, 2023.10.03, 2023.10.08, 2023.10.13, 2023.10.31, 2023.11.02, 2023.11.07, 2023.11.08,2023.11.09,2023.11.14]
interpolate(X=a,index=dates)
// output
[,,1,2,4.160000000000001,4.400000000000001,5,6,6,6]
a=[10,NULL,30,NULL,50];
index=[0, 3, 4, 7, 8]
interpolate(X=a,method='linear',index=index)
// output
[10,25,30,45,50]
FILE:references/doc_9455.md
# getInstrumentExpiry
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentexpiry.html
**来源**: DolphinDB 官方文档
---
getInstrumentExpiry
语法
getInstrumentExpiry(instrument)
详情
根据输入的金融工具,获取该工具的到期日(Expiry Date)。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
DATE 类型标量或向量。
例子
forward = {
"productType": "Forward",
"forwardType": "FxForward",
"version": 0,
"expiry": 2025.09.24,
"delivery": 2025.09.26,
"currencyPair": "USDCNY",
"direction": "Buy",
"notional": ["USD", 1E8],
"strike": 7.2
}
ins = parseInstrument(forward)
getInstrumentExpiry(ins)
// Output: 2025.09.24
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_9461.md
# submitJob
**URL**: https://docs.dolphindb.cn/zh/funcs/s/submitJob.html
**来源**: DolphinDB 官方文档
---
submitJob
语法
submitJob(jobId, jobDesc, jobDef, args...)
详情
把批处理作业提交到本地节点并且返回作业的 ID。如果要把批处理作业提交到远程节点,需要结合使用
rpc
或
remoteRun
函数。详情请参考
BatchJobManagement
。
参数
jobId
是作业的 ID,是字符串类型。
jobDesc
是字符串,用于描述作业。
jobDef
是用于定义作业的本地函数。请注意,该参数是一个函数对象,而不是表示函数名的字符串,因此不可使用引号。
args...
是函数的参数。如果函数没有参数,可以不指定。
返回值
STRING 类型标量,表示作业的 ID。
例子
把作业提交到本地节点:
def jobDemo(n){
s = 0
for (x in 1 : n) {
s += sum(sin rand(1.0, 100000000)-0.5)
print("iteration " + x + " " + s)
}
return s
};
submitJob("jobDemo1","job demo", jobDemo, 100);
// output
jobDemo1
getJobStatus("jobDemo1");
node
userID
jobId
rootJobId
jobDesc
priority
parallelism
clientIp
clientPort
receivedTime
startTime
endTime
errorMsg
local8848
guest
jobDemo1
d1d76cad-d46f-338c-4179-21cface3ce7c
job demo
4
2
127.0.0.1
62016
2023.12.12T17:52:01.576
2023.12.12T17:52:01.585
在作业的状态中,endTime 为空,这意味着作业还在执行中。作业完成后,就能在状态中看到 endTime 的值。
getJobStatus("jobDemo1");
node
userID
jobId
rootJobId
jobDesc
priority
parallelism
clientIp
clientPort
receivedTime
startTime
endTime
errorMsg
local8848
guest
jobDemo1
d1d76cad-d46f-338c-4179-21cface3ce7c
job demo
4
2
127.0.0.1
62016
2023.12.12T17:52:01.576
2023.12.12T17:52:01.585
2023.12.12T17:53:23.204
getJobMessage("jobDemo1");
// output
2023-12-12 17:52:01.586399 Start the job [jobDemo1]: job demo
2023-12-12 17:52:02.550241 iteration 1 1094.345887943766229
2023-12-12 17:52:03.417464 iteration 2 3167.431462436133642
2023-12-12 17:52:04.463558 iteration 3 5265.929786668073575
...
2023-12-12 17:53:21.609843 iteration 97 25681.096442654183192
2023-12-12 17:53:22.401263 iteration 98 25609.952331757223873
2023-12-12 17:53:23.204495 iteration 99 23660.316042780508723
2023-12-12 17:53:23.204495 The job is done.
getJobReturn("jobDemo1");
// output
924.915703
submitJob("jobDemo2",, jobDemo, 10);
// output
jobDemo2
getRecentJobs();
node
userID
jobId
rootJobId
jobDesc
priority
parallelism
clientIp
clientPort
receivedTime
startTime
endTime
errorMsg
local8848
guest
jobDemo1
d1d76cad-d46f-338c-4179-21cface3ce7c
job demo
4
2
127.0.0.1
62016
2023.12.12T17:52:01.576
2023.12.12T17:52:01.585
2023.12.12T17:53:23.204
local8848
guest
jobDemo2
def84639-5b21-c6b0-47be-986b4563e192
jobDemo
4
2
127.0.0.1
62016
2023.12.12T17:57:42.325
2023.12.12T17:57:42.327
2023.12.12T17:57:49.995
把作业提交到远程节点:
使用
rpc
函数("DFS_NODE2" 与本地节点在同一集群):
def jobDemo(n){
s = 0
for (x in 1 : n) {
s += sum(sin rand(1.0, 100000000)-0.5)
print("iteration " + x + " " + s)
}
return s
}
rpc("DFS_NODE2", submitJob, "jobDemo3", "job demo", jobDemo, 10);
// output
Output: jobDemo3
rpc("DFS_NODE2", getJobReturn, "jobDemo3");
// output
Output: -3426.577521
使用
remoteRun
函数或
remoteRunWithCompression
函数,这里以
remoteRun
为例:
conn = xdb("DFS_NODE2")
conn.remoteRun(submitJob, "jobDemo4", "job demo", jobDemo, 10);
// output
Output: jobDemo4
conn.remoteRun(getJobReturn, "jobDemo4");
// output
Output: 4238.832005
FILE:references/doc_9469.md
# getOLAPCacheEngineStat
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getOLAPCacheEngineStat.html
**来源**: DolphinDB 官方文档
---
getOLAPCacheEngineStat
语法
getOLAPCacheEngineStat()
别名:
getCacheEngineStat
详情
获取当前节点下 OLAP 引擎 Cache Engine 的状态信息。该函数只能在数据节点调用。
参数
无
返回值
返回一个表,包含以下几列:
chunkId:chunk 的唯一标识。
physicalName:chunk 所属表的物理表名。
timeSinceLastWrite:距离最后一次写入经过的时间,单位为毫秒。
cachedRowsOfCompletedTxn:当前缓存的已完成事务的记录数。
cachedRowsOfUncompletedTxn:当前缓存的未完成事务的记录数。注意:每个 chunk
最多只有最后一个事务是未完成的。
cachedMemOfCompletedTxn:cachedRowsOfCompletedTxn
占用的内存,单位为字节。
cachedMemOfUncompletedTxn:cachedRowsOfUncompletedTxn
占用的内存,单位为字节。
cachedTids:当前缓存的事务 id 列表。
例子
getOLAPCacheEngineStat()
chunkId
physicalName
timeSinceLastWrite
cachedRowsOfCompletedTxn
cachedRowsOfUncompletedTxn
cachedMemOfCompletedTxn
cachedMemOfUncompletedTxn
cachedTids
e4558d3c-fa41-52b5-418b-94e26cb70a75
pt_2
1056
222,386
0
3,558,176
0
2052
FILE:references/doc_9470.md
# 向量存储引擎
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db/vectordb.html
**来源**: DolphinDB 官方文档
---
向量存储引擎
DolphinDB 在 3.00.1 版本中,基于 TSDB 存储引擎,开发并实现了支持向量检索的向量存储引擎(VectorDB)。VectorDB 针对 TSDB
中以数组向量(Array
Vector)形式存储的向量数据,引入了向量检索技术。它支持对向量数据创建索引,并实现了快速的近似最近邻搜索,满足现代应用场景下对海量数据高效检索和响应的需求。DolphinDB
VectorDB 具有以下特点:
支持向量索引的持久化存储,可以从磁盘读取预先构建好的向量索引,无需在每次查询时重复构建索引。
提供了高效的向量相似度检索能力,可以快速地对海量向量数据进行近似最近邻搜索。
支持混合搜索,可以结合关键词搜索和向量特征搜索,使得搜索更加全面和精准。
实现原理
VectorDB 的实现主要考虑以下三个方面:向量数据存储、向量索引构建和向量数据检索。
向量数据存储
在 DolphinDB 中,向量数据以数组向量的形式存储。DolphinDB 的 TSDB 引擎本身就支持数组向量的存储,因此 VectorDB
无需自行实现向量数据的存储,只需要基于 TSDB 引擎进行构建即可。关于 TSDB 数据存储原理介绍,请参考
TSDB 存储引擎
。
向量索引构建
DolphinDB 采用 Facebook 开源的向量检索库
Faiss
,为 VectorDB 的向量索引构建提供支持。
在创建分区表时,如果为表中的某列指定了索引信息,系统会为该列构建并存储向量索引。VectorDB 以 Level File
为单位进行向量索引的构建和存储。也就是说,VectorDB 不会在全局仅保存一个向量索引,而是在每个 Level File
文件存储一个独立的向量索引。每次生成新的 Level File 文件时,VectorDB 会根据指定的索引类型,为该 Level File
中的向量数据建立向量索引。
向量数据检索
相似度计算和检索方法是向量数据检索中的关键技术。VectorDB 利用欧式距离(L2, Euclidean distance)计算向量数据之间的相似度。L2
是最常用的距离度量,计算所得的值越小,越与搜索值相似。L2 在低维空间中表现良好,但是在高维空间中,由于维度灾难的影响,L2 的效果会逐渐变差。
如下代码展示了在 VectorDB 进行向量检索的查询语句。在查询时,VectorDB 会根据所使用的向量索引的类型来搜索并获取与查询向量最相似的 K
个向量。
SELECT {col1,...,colx}
FROM table [where]
ORDER BY rowEuclidean(<vectorCol>, queryVector)
LIMIT <TOPK>
普通向量检索
普通向量检索即在查询语句中没有指定 where 语句进行条件过滤。由于只有存储在磁盘 Level File 中的数据拥有向量索引,而 Cache Engine
中的数据并没有建立向量索引,因此普通向量检索的流程如下:
首先,遍历磁盘上所有 Level File,读取每个 Level File 中存储的向量索引。通过索引搜索得到 N * K
个初步查询结果。
其次,对 Cache Engine 中的数据(若有)进行穷举搜索,得到共(N + 1)* K 个查询结果。
最后,将这
(N + 1)* K
个查询结果根据与查询向量的 L2 距离从小到大进行归并排序,取出并返回与查询向量最相近的
K条数据。
混合检索
VectorDB 支持在查询语句中使用 where
条件过滤数据,以充分利用向量数据库的优势,提高检索的准确性和灵活性。这种检索方式适用于综合多个属性进行查询的场景。此时的向量检索流程为:
根据 where 条件对数据进行初步过滤。
将过滤后的数据按照 Level File 进行划分,确保同一 Level File 中的数据被划分在一起。
对每个 Level File 中的数据使用其对应的索引进行相似性搜索。
合并各 Level File 的搜索结果,并从中选出与查询向量最相近的 K 条数据作为最终返回结果。
索引类型
向量索引(Vector
Index)是一种针对向量数据构建的高效数据结构。它帮助在时间和空间上提供更高效的向量相似性查询能力。通过向量索引,可以快速地查询出与目标向量最相似的若干个向量。
当前 VectorDB 支持以下索引类型:Flat, PQ, IVF, IVFPQ, HNSW。
索引类型
索引说明
索引构建复杂度
Flat
Flat 索引提供精确的向量最近邻检索。它在构建索引时无需进行训练,而是直接对系统中存储的所有向量进行穷举搜索。在查询时,Flat
索引会计算查询向量与所有存储向量的相似度,从而找出与查询向量最相似的向量。
无需复杂的索引构建过程。
PQ
PQ(Product Quantization)索引通过对向量数据进行训练来构建向量索引。在训练过程中,PQ
会将每个向量划分为多个子向量,并对每个子向量进行乘积量化(Product
Quantization)处理。这样可以大幅压缩每个向量的存储空间。
构建 PQ 索引时需要训练乘积量化器。与除 Flat 索引之外的其他索引相比,PQ 索引在内存占用方面更小。
IVF
IVF(Inverted File Index)索引在构建时需要对向量数据进行训练。训练过程中,IVF 会采用
k-means
聚类算法将向量数据划分为多个簇(cluster)。然后为每个簇建立一个倒排索引,记录该簇中包含的所有向量数据。
在查询时,IVF
会先计算查询向量与各个簇的距离,找出与查询向量距离较近的几个簇。然后仅对这些相关簇中的向量进行相似度计算,而不需要计算全部向量,从而大幅降低了计算量,提高了搜索效率。
构建 IVF 索引需要对向量数据进行聚类训练,并为每个聚类簇建立倒排索引。相比其他索引方式,IVF
索引的构建过程较为复杂。
IVFPQ
IVFPQ(Inverted File Index with Product Quantization)是 IVF 和 PQ
两种索引技术的结合。在构建 IVFPQ 索引时,需要对向量数据进行训练。训练过程中,IVFPQ
会将向量数据划分为多个簇,并对每个簇的向量数据采用 PQ 的乘积量化方式进行压缩处理。
构建 IVFPQ 索引需要同时进行向量数据聚类训练和乘积量化器训练。因此,与单独使用 IVF 或 PQ 相比,IVFPQ
索引的构建和维护过程更为复杂。
HNSW
HNSW(Hierarchical Navigable Small
World)基于图算法为向量数据构建多层次的导航图结构,实现高精度和高速度的近似最近领搜索。在查询过程中HNSW会根据查询向量从导航图的顶层开始查找最近的向量,然后在更低的层次中进一步搜索,逐渐逼近目标向量。每一层的搜索都是局部的,从而大幅提高了搜索效率。
构建索引时不需要进行训练,但是需要在构建索引时动态地构建和维护多层次导航图,构建多层次的图结构复杂度高耗时长。且相比其他索引,HNSW对内存的占用最高。
选择索引类型
索引类型
使用场景
适用向量规模
检索速度
检索精度
Flat
需要最高精度的场景
10万以内
慢
高
PQ
对搜索精度要求不高的场景。例如:大型数据库、视频库等。
数十万至数千万级别
较 Flat 快
最低
IVF
图片检索、文本检索等。
数万至数百万级别
较 PQ 快
较 Flat 低
IVFPQ
在检索速度和精度之间找到最佳平衡的场景。例如:大型推荐系统、社交网络中的用户匹配等。
数百万至数千万级别
比单独使用 IVF 或 PQ 更快
比单独使用 PQ 高,但比单独使用 IVF 低
HNSW
对检索速度,精度和动态更新有高要求的场景,例如:实时推荐系统、在线搜索、RAG 等。
数亿至数十亿级别
最快
与 IVF 相近
创建 VectorDB 中的数据表
在 DolphinDB 中,创建分布式分区表有两种方式:一种是使用
createPartitionedTable
函数,另一种是使用
create
语句。这两个函数中的
indexes
参数用于指定需要建立向量索引的列、向量索引的类型以及向量数据的维度。在创建数据表时,必须指定该参数,才能创建
VectorDB 中分布式分区表。
关于数据表的创建方法,请参考函数页面。本文仅说明 VectorDB 的使用限制。
建库限制:
只能创建 TSDB 引擎下的数据库,因此在使用
database
函数创建数据库时,必须设置
engine
="TSDB"。
建表限制:
仅支持为分布式分区表设置向量索引,且建表时必须指定
keepDuplicate
s=ALL。
最多只能为一个 FLOAT[] 类型的列建立向量索引。该列中的每一行代表一个向量,且所有向量必须具有相同的维度。维度表示每个向量中的元素数量,由
indexes
参数中的 dim 指定。
插入向量索引列的数据维度必须与维度(dim)一致。
搜索限制:
只有在满足如下条件时,才会使用向量索引加速检索:
不能使用表连接查询。
查询语句中
order by
必须按升序排序,且仅支持使用
rowEuclidean
计算距离。
传入
rowEuclidean
的第一个参数必须是已指定了向量索引的列,即
rowEuclidean(<vectorCol>, queryVec)
。
必须指定
limit
子句。
若指定了
where
,则
where
条件中不能包含
sortColumns
中的任意列。
查询语句中不能指定
group by
,
having
等其他子句。
其它说明:
内存 Cache Engine 中的向量数据没有索引,无法对其通过向量索引加速检索。若需要检索这部分数据,可以通过
flushTSDBCache
强制将缓存中的数据写入磁盘后,再进行查询。
简单示例
// 创建 TSDB 引擎中的数据库
db = database(directory="dfs://indexesTest", partitionType=VALUE, partitionScheme=1..10, engine="TSDB")
// 创建表结构,其中 col3 列的类型是 FLOAT[]
schematb = table(1:0,`col0`col1`col2`col3,[INT,INT,TIMESTAMP,FLOAT[]])
// 通过 indexes 参数,为 col3 指定向量索引
pt = createPartitionedTable(dbHandle=db, table=schematb, tableName=`pt, partitionColumns=`col0, sortColumns=`col1`col2, indexes={"col3":"vectorindex(type=flat, dim=5)"})
tmp = cj(table(1..10 as col0),cj(table(1..10 as col1),table(now()+1..10 as col2))) join table(arrayVector(1..1000*5,1..5000) as col3)
//分区表中写入数据后,强制将数据写入磁盘
pt.tableInsert(tmp)
flushTSDBCache()
select * from pt where col2<now() order by rowEuclidean(col3,[1339,252,105,105,829]) limit 10
应用场景
向量检索技术在检索增强生成(RAG)系统中扮演着至关重要的角色,其能够有效地从知识库中找到与查询相关的信息,为生成模型提供丰富的上下文支持。将 VectorDB 与
RAG 结合,可以进一步扩展系统知识库,并利用向量检索提供的上下文信息提高生成结果的质量和准确性。VectorDB 还可以改进推荐系统、实现高效图像和视频搜索、提升
AI 生成模型的准确性以及多样性等。
FILE:references/doc_9483.md
# 多服务器集群部署与升级
**URL**: https://docs.dolphindb.cn/zh/tutorials/multi_machine_cluster_deployment.html
**来源**: DolphinDB 官方文档
---
多服务器集群部署与升级
DolphinDB 集群包括四种类型节点:控制节点(controller)、代理节点(agent)、数据节点(datanode)和计算节点(compute node)。
控制节点
:控制节点是 DolphinDB 集群的核心部分,负责收集代理节点和数据节点的心跳,监控每个节点的工作状态,管理分布式文件系统的元数据和事务日志。多服务器集群中只有一个控制节点。
代理节点
:代理节点负责执行控制节点发出的启动和关闭数据节点或计算节点的命令。在一个集群中,每台物理服务器有且仅有一个代理节点。
数据节点
:数据节点既可以存储数据,也可以用于数据的查询和计算。每台物理服务器可以配置多个数据节点。
计算节点
:计算节点承担数据节点查询和计算的相关职能,负责响应客户端的请求并返回结果,与数据节点共同实现存储资源和计算资源有效隔离。每台物理服务器可以配置零到多个计算节点。
本教程用于在 Linux 操作系统上进行多服务器集群的部署、升级、过期 License 升级,并对常见问题做出解答,便于用户快速上手 DolphinDB 。包含以下主题:
部署 DolphinDB 多服务器集群
本教程示例集群的部署架构图如下:
三台部署服务器(P1, P2, P3)对应的内网 IP 地址为:
P1:10.0.0.80
P2:10.0.0.81
P3:10.0.0.82
部署本教程示例多服务器集群前的要求和准备:
本教程示例集群超过了社区版试用授权许可节点数的限制,所以必须在DolphinDB官网申请企业版 License并按第一章第二步的方法进行更新。
建议节点的 IP 地址使用内网 IP,网络使用万兆以太网。如果使用外网地址,则不能保证节点间网络传输性能。
DolphinDB 多机集群(非高可用集群)有且仅有一个控制节点。
部署数据节点或者计算节点的服务器必须部署一个代理节点,用于启动和关闭该服务器上的数据节点或计算节点。
第一步:下载
在每台服务器上下载 DolphinDB 安装包并解压。
官方下载地址:https://dolphindb.cn/product#downloads
也可以通过 Shell 指令下载。下载方式如下:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_Vrelease.zip -O dolphindb.zip
其中,
release
代表版本。例如:下载 2.00.11.3 版本的 Linux64 server,使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_V2.00.11.3.zip -O dolphindb.zip
如需下载 ABI 或 JIT 版本 server,则需要在版本号后以下划线连接 ABI 或 JIT。例如:下载 2.00.11.3 版本的 Linux64 ABI server, 使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_V2.00.11.3_ABI.zip -O dolphindb.zip
下载 2.00.11.3 版本的 Linux64 JIT 版本 server,使用以下指令:
wget https://www.dolphindb.cn/downloads/DolphinDB_Linux64_V2.00.11.3_JIT.zip -O dolphindb.zip
以此类推。
执行以下 Shell 指令解压安装包至指定路径(
/path/to/directory
):
unzip dolphindb.zip -d </path/to/directory>
注意
:安装路径的目录名中不能含有空格字符或中文字符,否则启动数据节点时会失败。
第二步:更新软件授权许可
与社区版试用授权许可相比,企业版试用授权许可支持更多的节点、CPU 核数和内存。用户拿到企业版试用授权许可,只需用其替换如下文件即可。请注意:每台服务器上的授权许可文件都需要替换。
/DolphinDB/server/dolphindb.lic
本教程示例集群超过了社区版 License节点数的限制,可以前往DolphinDB官网申请企业版试用授权许可。
第三步:集群配置
(1)P1 需要配置的文件
登录
P1
服务器,进入
/DolphinDB/server/clusterDemo/config
目录
配置控制节点参数文件
执行以下 Shell 指令修改
controller.cfg
配置文件:
vim ./controller.cfg
mode=controller
localSite=10.0.0.80:8900:controller8900
dfsReplicationFactor=1
dfsReplicaReliabilityLevel=2
dataSync=1
workerNum=4
maxConnections=512
maxMemSize=8
lanCluster=0
在这里必须配置的是
localSite
,指定控制节点的 IP 地址、端口号和别名。其余参数用户应结合自身服务器硬件配置进行合理参数调优。
配置集群成员参数文件
cluster.nodes
用于存放集群代理节点、数据节点和计算节点的信息。本教程配置 3 个代理节点,2 个数据节点和 1 个计算节点,用户可以根据实际要求配置节点个数。该配置文件分为两列,第一例存放节点 IP 地址、端口号和节点别名。这三个信息由冒号分隔;第二列是说明节点类型,比如代理节点类型为 agent,数据节点类型为 datanode,计算节点为 computenode。
注意
:节点别名是大小写敏感的,而且在集群内必须是唯一的。
本例中集群的节点配置信息需要包含位于
P1
,
P2
,
P3
的代理节点、数据节点和计算节点信息。执行以下 Shell 指令修改
cluster.nodes
配置文件:
vim ./cluster.nodes
localSite,mode
10.0.0.80:8901:P1-agent,agent
10.0.0.80:8902:P1-datanode,datanode
10.0.0.81:8901:P2-agent,agent
10.0.0.81:8902:P2-datanode,datanode
10.0.0.82:8901:P3-agent,agent
10.0.0.82:8902:P3-computenode,computenode
配置数据节点和计算节点参数文件
执行以下 Shell 指令修改
cluster.cfg
配置文件:
vim ./cluster.cfg
maxMemSize=32
maxConnections=512
workerNum=4
maxBatchJobWorker=4
chunkCacheEngineMemSize=2
TSDBCacheEngineSize=1
newValuePartitionPolicy=add
maxPubConnections=64
subExecutors=4
lanCluster=0
enableChunkGranularityConfig=true
cluster.cfg
的配置适用于集群中所有数据节点和计算节点,
用户应结合自身服务器硬件配置进行合理参数调优:
maxMemSize
推荐设置为min(服务器可用内存/节点数,license限制最大内存)*0.85,
workerNum
推荐设置为min(服务器逻辑核心数,license限制逻辑核心数),
volumes
推荐设置为ssd,且设置多块磁盘
配置代理节点参数文件
执行以下 Shell 指令修改
agent.cfg
配置文件:
vim ./agent.cfg
mode=agent
localSite=10.0.0.80:8901:P1-agent
controllerSite=10.0.0.80:8900:controller8900
workerNum=4
maxMemSize=4
lanCluster=0
在这里,
controllerSite
需要与 P1 的
controller.cfg
中的
localSite
保持一致,因为代理节点使用
agent.cfg
中的参数
controllerSite
来寻找集群中的控制节点 。若
controller.cfg
中的参数
localSite
有变化,即使只是节点别名有改变,所有代理节点的配置文件
agent.cfg
中的参数
controllerSite
都应当做相应的改变。此外,还必须配置的是
localSite
,指定代理节点的 IP 地址、端口号和别名。其余参数用户可根据实际情况进行调整。agent.cfg 中的 sites 配置当前代理节点和集群控制节点的信息,需要依次填写当前代理节点和控制节点的 IP 地址、端口号和别名,例如
sites=10.0.0.80:8901:P1-agent:agent,10.0.0.80:8900:controller8900:controller
。只有设置了配置项 sites,才允许在代理节点登录。
(2)P2 需要配置的文件
登录
P2
服务器,进入
/DolphinDB/server/clusterDemo/config
目录
配置代理节点参数文件
执行以下 Shell 指令修改
agent.cfg
配置文件:
vim ./agent.cfg
mode=agent
localSite=10.0.0.81:8901:P2-agent
controllerSite=10.0.0.80:8900:controller8900
workerNum=4
maxMemSize=4
lanCluster=0
在这里,
controllerSite
需要与 P1 的
controller.cfg
中的
localSite
保持一致,因为代理节点使用
agent.cfg
中的参数
controllerSite
来寻找集群中的控制节点。若
controller.cfg
中的参数
localSite
有变化,即使只是节点别名有改变,所有代理节点的配置文件
agent.cfg
中的参数
controllerSite
都应当做相应的改变。此外,还必须配置的是
localSite
,指定代理节点的 IP 地址、端口号和别名。其余参数用户可根据实际情况进行调整。agent.cfg 中的 sites 配置当前代理节点和集群控制节点的信息,需要依次填写当前代理节点和控制节点的 IP 地址、端口号和别名,例如
sites=10.0.0.81:8901:P2-agent:agent,10.0.0.80:8900:controller8900:controller
。只有设置了配置项 sites,才允许在代理节点登录。
(3)P3 需要配置的文件
登录
P3
服务器,进入
/DolphinDB/server/clusterDemo/config
目录
配置代理节点参数文件
执行以下 Shell 指令修改
agent.cfg
配置文件:
vim ./agent.cfg
mode=agent
localSite=10.0.0.82:8901:P3-agent
controllerSite=10.0.0.80:8900:controller8900
workerNum=4
maxMemSize=4
lanCluster=0
在这里,
controllerSite
需要与 P1 的
controller.cfg
中的
localSite
保持一致,因为代理节点使用
agent.cfg
中的参数
controllerSite
来寻找集群中的控制节点。若
controller.cfg
中的参数
localSite
有变化,即使只是节点别名有改变,所有代理节点的配置文件
agent.cfg
中的参数
controllerSite
都应当做相应的改变。此外,还必须配置的是
localSite
,指定代理节点的 IP 地址、端口号和别名。其余参数用户可根据实际情况进行调整。agent.cfg 中的 sites 配置当前代理节点和集群控制节点的信息,需要依次填写当前代理节点和控制节点的 IP 地址、端口号和别名,例如
sites=10.0.0.82:8901:P3-agent:agent,10.0.0.80:8900:controller8900:controller
。只有设置了配置项 sites,才允许在代理节点登录。
第四步:启动集群
登录服务器
P1, P2 和 P3
,进入
/DolphinDB/server
目录,第一次启动时需要修改文件权限,执行以下 Shell 指令:
chmod +x dolphindb
启动控制节点
在服务器
P1
的
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令启动控制节点:
sh startController.sh
注意
:本教程示例集群的控制节点部署在服务器 P1,所以只需要在服务器 P1 启动控制节点。
可以执行以下 Shell 指令,查看节点是否成功启动:
ps aux|grep dolphindb
返回如下信息说明控制节点启动成功:
启动代理节点
在服务器
P1, P2 和 P3
的
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令启动代理节点:
sh startAgent.sh
可以执行以下 Shell 指令,查看节点是否成功启动:
ps aux|grep dolphindb
返回如下信息说明代理节点启动成功:
启动数据节点和计算节点
可以在 Web 管理界面启动或关闭数据节点和计算节点,以及修改集群的配置。在浏览器中输入控制节点的 IP 地址和端口号即可进入 Web 管理界面,教程中的部署控制节点的服务器 IP 地址为 10.0.0.80,部署端口为 8900,所以访问地址为 10.0.0.80:8900,打开后的 Web 管理界面如下。以管理用身份(默认账号:admin,默认密码:123456)登录 Web 管理界面后,用户可以通过勾选想要启动的数据节点和计算节点,再点击启动(关闭)按键即可启动(关闭)相应的数据节点和计算节点:
刷新页面后可看到对应的数据节点和计算节点已启动,如下图所示:
第五步:连接数据节点创建数据库和分区表
数据节点既可以存储数据,也可以用于数据的查询和计算。接下来通过一个例子介绍如何在 DolphinDB 集群数据节点创建数据库并写入数据。首先,打开控制节点的 Web 管理界面,点击对应的数据节点打开其 Web 交互编程界面,如下图所示(以 P1-datanode 为例):
也可以在浏览器直接输入数据节点的 IP 地址和端口号进入数据节点的 Web 交互编程界面。
在数据节点的 Web 交互编程界面执行以下语句创建数据库和分区表:
// 创建存储的数据库和分区表
login("admin", "123456")
dbName = "dfs://testDB"
tbName = "testTB"
if(existsDatabase(dbName)){
dropDatabase(dbName)
}
db = database(dbName, VALUE, 2021.01.01..2021.12.31)
colNames = `SecurityID`DateTime`PreClosePx`OpenPx`HighPx`LowPx`LastPx`Volume`Amount
colTypes = [SYMBOL, DATETIME, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, INT, DOUBLE]
schemaTable = table(1:0, colNames, colTypes)
db.createPartitionedTable(table=schemaTable, tableName=tbName, partitionColumns=`DateTime)
然后,执行以下语句创建 5000 个股票 1 分钟 K 线数据并写入上面创建的分区表:
// 模拟数据并写入分区表
n = 1210000
randPrice = round(10+rand(1.0, 100), 2)
randVolume = 100+rand(100, 100)
SecurityID = lpad(string(take(0..4999, 5000)), 6, `0)
DateTime = (2023.01.08T09:30:00 + take(0..120, 121)*60).join(2023.01.08T13:00:00 + take(0..120, 121)*60)
PreClosePx = rand(randPrice, n)
OpenPx = rand(randPrice, n)
HighPx = rand(randPrice, n)
LowPx = rand(randPrice, n)
LastPx = rand(randPrice, n)
Volume = int(rand(randVolume, n))
Amount = round(LastPx*Volume, 2)
tmp = cj(table(SecurityID), table(DateTime))
t = tmp.join!(table(PreClosePx, OpenPx, HighPx, LowPx, LastPx, Volume, Amount))
dbName = "dfs://testDB"
tbName = "testTB"
loadTable(dbName, tbName).append!(t)
语句执行成功后可在交互编程界面的左边,
数据库
一栏查看已创建的库表及字段信息。
也可在
本地变量
一栏查看已创建的变量和表,展示了变量名、变量类型、变量维度大小、占用内存大小等信息,并且可以直接点击变量名进行变量预览。
第六步:连接计算节点查询和计算
计算节点主要用于数据的查询和计算。接下来通过一个例子介绍如何在计算节点对数据库内的分区表执行查询和计算。首先,打开控制节点的 Web 管理界面,点击对应的计算节点打开其 Web 交互编程界面,如下图所示:
也可以在浏览器直接输入计算节点的 IP 地址和端口号进入计算节点的 Web 交互编程界面。
在计算节点的 Web 交互编程界面执行以下语句加载分区表对象,此时只加载了分区表的元数据,并未加载分区表全量数据,所以响应时间非常快:
// 加载分区表对象
pt = loadTable("dfs://testDB", "testTB")
然后,执行以下语句查询股票表中每天包含的数据条数:
// SQL 返回数据量少的时候,可以直接取回客户端展示
select count(*) from pt group by date(DateTime) as Date
语句执行成功后,查询结果会在 Web 界面下方展示:
执行以下语句计算每支股票每天的 OHLC 值:
// SQL 返回数据量较大时,可以赋值给变量,占用 server 端内存,客户端分页取回展示
result = select first(LastPx) as Open, max(LastPx) as High, min(LastPx) as Low, last(LastPx) as Close from pt group by date(DateTime) as Date, SecurityID
在这里,将计算结果赋值给了
result
变量,这样就不会直接在客户端界面直接展示,减少客户端内存占用,用户可以通过点击
本地变量
栏目下的
result
变量进行分页展示查看:
基于 Web 的集群管理
完成部署后,我们可以通过控制节点的 Web 管理界面更改集群配置。
控制节点参数配置
点击
Controller Config
按钮,可进行控制节点的参数配置。以下参数是在第一章中
controller.cfg
里配置的,用户可以根据实际应用在这里添加、删除、修改配置参数。这些配置信息都可以在这个界面上进行更改,修改的配置会在重启控制节点之后生效。
注意
:如果改变了控制节点的
localSite
参数值,一定要对所有
agent.cfg
中的
controllerSite
参数做相应修改,否则集群将无法正常运行。
数据节点和计算节点参数配置
点击
Nodes Config
按钮,可进行数据节点和计算节点的参数配置。以下参数是在第一章中
cluster.cfg
里配置的,用户可以根据实际应用在这里添加、删除、修改配置参数。修改的配置会在重启数据节点和计算节点之后生效。
设置集群管理器通过外网访问
通常,集群所有节点同属一个内网时,将
site
信息设置为内网地址,使节点间的网络通信更加高效。若同时需要通过外网地址访问集群管理器,需要在 controller 上配置
publicName
选项,用来指定外网访问的地址。
publicName
可以设置为域名或者 IP 地址,如果要启动 HTTPS,则必须是域名。举个例子,要设置服务器
P1, P2, P3
上所有节点的外网地址,需要在
cluster.cfg
中填入如下信息:
P1-%.publicName=19.56.128.21
P2-%.publicName=19.56.128.22
P3-%.publicName=19.56.128.23
%
是节点别名的通配符。另外
controller.cfg
也要加上相应的外网域名或 IP, 例如
publicName=19.56.128.21
集群升级
第一步:正常关闭集群所有节点
登录服务器
P1 , P2 和 P3
,进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
./stopAllNode.sh
第二步:备份旧版本的元数据文件
多服务器集群只有写入过数据才会创建相应的元数据文件,如果集群没有数据写入行为则可直接跳过此步骤进行升级。
备份控制节点元数据
控制节点元数据默认存储在控制节点服务器的
/DolphinDB/server/clusterDemo/dfsMeta
目录下的
DFSMetaLog.0
文件,如果数据量超过一定的大小则还会生成
DFSMasterMetaCheckpoint.0
文件。控制节点元数据的默认存储目录:
/DolphinDB/server/clusterDemo/dfsMeta
登录控制节点所在的服务器
P1
,可进入上述目录执行以下 Shell 指令进行备份:
mkdir backup
cp -r DFSMetaLog.0 backup
cp -r DFSMasterMetaCheckpoint.0 backup
备份数据节点元数据
数据节点的元数据默认存储在控制节点服务器的
/DolphinDB/server/clusterDemo/data/ 数据节点别名 /stroage/ CHUNK_METADATA
目录下,接下来以
P1
服务器为例演示如何备份数据节点元数据,数据节点元数据的默认存储目录:
/DolphinDB/server/clusterDemo/data/P1-datanode/stroage/CHUNK_METADATA
登录服务器
P1
,可进入上述目录执行以下 Shell 指令备份到上面创建的
backup
文件夹:
cp -r CHUNK_METADATA ../../backup
注意
:元数据文件可能通过配置文件指定存储在其它目录,如果在默认路径没有找到上述文件,可以通过查询配置文件中的
dfsMetaDir
参数和
chunkMetaDir
参数确认元数据文件的存储目录。若配置中未指定
dfsMetaDir
参数和
chunkMetaDir
参数,但是配置了
volumes
参数,
CHUNK_METADATA
目录在相应的
volumes
参数指定的目录下。
第三步:升级
注意
:
当 server 在线升级到某个版本后,使用的插件也应升级到与此对应的版本。
在线升级
登录服务器
P1 、P2 和 P3
,进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
./upgrade.sh
运行后将会出现如下提示:
输入 y 并点击回车后会出现如下提示:
输入 1 选择在线更新,并点击回车后会出现如下提示:
输入所需更新的版本号再点击回车即可,以更新至 2.00.9.1 版本为例,输入 2.00.9.1 后点击回车,出现如下界面则表示升级成功:
离线升级
下载升级所需版本的安装包,官方下载地址:
http://www.dolphindb.cn/downloads.html
将下载好的安装包上传至
P1
、
P2
和
P3
的
/DolphinDB/server/clusterDemo
目录下,以更新至 2.00.9.1 版本为例:
登录
P1
、
P2
和
P3
,进入
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令:
./upgrade.sh
运行后将会出现如下提示:
输入 y 并点击回车后会出现如下提示:
输入 2 选择离线更新,并点击回车后会出现如下提示:
输入所需更新的版本号再点击回车即可,以更新至 2.00.9.1 版本为例,输入 2.00.9.1 后点击回车,出现如下界面则表示升级成功:
如所需更新的版本是 JIT 或 ABI 版本,则版本号应与安装包保持一致。例如,安装包名称是"DolphinDB_Linux64_V2.00.9.1_JIT.zip"时,需要输入的版本号是"2.00.9.1_JIT"。
第四步:重新启动集群
启动控制节点
在服务器
P1
的
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令启动控制节点:
sh startController.sh
注意
:本教程示例集群的控制节点部署在服务器 P1,所以只需要在服务器 P1 启动控制节点。
启动代理节点
在服务器
P1, P2 和 P3
的
/DolphinDB/server/clusterDemo
目录执行以下 Shell 指令启动代理节点:
sh startAgent.sh
启动数据节点和计算节点
在浏览器中输入控制节点的 IP 地址和端口号即可进入 Web 管理界面,教程中的部署控制节点的服务器 IP 地址为 10.0.0.80,部署端口为 8900,所以访问地址为 10.0.0.80:8900,打开后的 Web 管理界面如下。以管理用身份(默认账号:admin,默认密码:123456)登录 Web 管理界面后,用户可以通过勾选想要启动的数据节点和计算节点,再点击启动(关闭)按键即可启动(关闭)相应的数据节点和计算节点:
刷新页面后可看到对应的数据节点和计算节点已启动,如下图所示:
成功启动后,打开 Web 管理界面,在交互编程界面执行以下代码,查看 DolphinDB 当前版本:
version()
授权许可文件过期更新
在更新授权许可文件前,可以打开 Web 管理界面,在任一节点交互编程界面执行以下代码查看当前授权许可文件的到期时间:
use ops
getAllLicenses()
在更新授权许可文件后,可通过对比更新前后授权许可文件的到期时间确认是否更新成功
第一步:替换授权许可文件
登录服务器
P1 、P2 和 P3
,用新的授权许可文件
dolphindb.lic
替换老的授权许可文件。
Linux 环境授权许可文件位置:
/DolphinDB/server/dolphindb.lic
第二步:更新授权许可文件
在线更新
打开 Web 管理界面,在任一节点交互编程界面执行以下代码完成更新,代码成功运行会返回新授权许可证的到期时间:
use ops
updateAllLicenses()
注意
:在线更新有如下要求:
License 授权的客户名称必须与原来的 License 相同。
授权的节点个数,内存大小,CPU 核个数不能比原来的小。
该函数只在执行该函数的节点生效。因此在集群环境下,需要在所有控制节点,代理节点、计算节点和数据节点上运行该函数。
License 的类型必须是 commercial(付费)类型和 free 类型,如果是 trial(试用)类型不支持在线更新。
离线更新
关闭每台服务器上的 DolphinDB 节点,然后重新启动,即可完成更新。
常见问题解答(FAQ)
节点启动失败的可能原因
端口号被占用
如果遇到无法启动 DolphinDB 节点的情况,建议打开
/DolphinDB/server/clusterDemo/log
目录下相应节点的日志文件,若出现如下错误:
<ERROR> :Failed to bind the socket on port 8900 with error code 98
说明该节点选用的端口被其他程序占用,导致 DolphinDB 无法正常启动,修改配置文件中对应节点的端口为其它空闲端口后即可正常启动。
集群成员配置文件
cluster.nodes
第一行为空行
如果遇到无法启动 DolphinDB 节点的情况,建议打开
/DolphinDB/server/clusterDemo/log
目录下相应节点的日志文件,若出现如下错误:
<ERROR> :Failed to load the nodes file [/DolphinDB/server/clusterDemo/config/cluster.nodes] with error: The input file is empty.
说明控制节点的
cluster.nodes
的第一行为空行,这种情况下只需将文件中的空行删除,再重新启动节点即可。
宏变量
<ALIAS>
在明确节点的情况下使用无效
查看控制节点下的配置文件 cluster.cfg,若在明确了节点的情况下使用宏变量
<ALIAS>
,如: P1-datanode.persistenceDir = /hdd/hdd1/streamCache/<ALIAS> :
P1-datanode.persistenceDir = /hdd/hdd1/streamCache/<ALIAS>
则会导致该节点无法正常启动。这种情况下只需要把
<ALIAS>
删除,替换成特定节点即可,如:
P1-datanode.persistenceDir = /hdd/hdd1/streamCache/P1-datanode
若想对所有节点使用宏变量,则做如下修改:
persistenceDir = /hdd/hdd1/streamCache/<ALIAS>
如何通过 systemd 命令启动 DolphinDB 集群?
首先在每台服务器的
DolphinDB/server/clusterDemo
目录中创建脚本文件
controller.sh
以及
agent.sh
,其Shell 创建命令及写入内容如下 :
vim ./controller.sh
#!/bin/bash
#controller.sh
workDir=$PWD
start(){
cd workDir && export LD_LIBRARY_PATH=$(dirname
"$workDir"
):$LD_LIBRARY_PATH
nohup ./../dolphindb -console
0
-mode controller -home data -script dolphindb.dos -config config/controller.cfg -logFile log/controller.log -nodesFile config/cluster.nodes -clusterConfig config/cluster.cfg > controller.nohup
2
>&
1
&
}
stop(){
ps -o ruser=userForLongName -e -o pid,ppid,c,time,cmd |grep dolphindb|grep -v grep|grep $USER|grep controller| awk
'{print $2}'
| xargs kill -TERM
}
case
$
1
in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
esac
vim ./agent.sh
#!/bin/bash
#agent.sh
workDir=$PWD
start(){
cd workDir && export LD_LIBRARY_PATH=$(dirname
"$workDir"
):$LD_LIBRARY_PATH
nohup ./../dolphindb -console
0
-mode agent -home data -script dolphindb.dos -config config/agent.cfg -logFile log/agent.log > agent.nohup
2
>&
1
&
}
stop(){
ps -o ruser=userForLongName -e -o pid,ppid,c,time,cmd |grep dolphindb|grep -v grep|grep $USER|grep agent| awk
'{print $2}'
| xargs kill -TERM
}
case
$
1
in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
esac
然后,执行以下 Shell 命令配置 controller 的守护进程:
vi /usr/lib/systemd/system/ddbcontroller.service
配置如下内容:
[Unit]
Description=ddbcontroller
Documentation=https:
//www.dolphindb.com/
[Service]
Type=forking
WorkingDirectory=/home/DolphinDB/server/clusterDemo
ExecStart=/bin/sh controller.sh start
ExecStop=/bin/sh controller.sh stop
ExecReload=/bin/sh controller.sh restart
Restart=always
RestartSec=
10
s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
注意
:配置中
WorkingDirectory
需要修改为
/DolphinDB/server/clusterDemo
执行以下 Shell 命令配置 agent 的守护进程:
vi /usr/lib/systemd/system/ddbagent.service
配置如下内容:
[Unit]
Description=ddbagent
Documentation=https:
//www.dolphindb.com/
[Service]
Type=forking
WorkingDirectory=/home/DolphinDB/server/clusterDemo
ExecStart=/bin/sh agent.sh start
ExecStop=/bin/sh agent.sh stop
ExecReload=/bin/sh agent.sh restart
Restart=always
RestartSec=
10
s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
注意
:配置中
WorkingDirectory
需要修改为
/DolphinDB/server/clusterDemo
最后,执行以下 Shell 命令启动 controller :
systemctl enable ddbcontroller.service #配置自启
systemctl start ddbcontroller.service #启动
systemctl stop ddbcontroller.service #停止服务
systemctl status ddbcontroller.service #检测状态
执行以下 Shell 命令启动 agent :
systemctl enable ddbagent.service #配置自启
systemctl start ddbagent.service #启动
systemctl stop ddbagent.service #停止服务
systemctl status ddbagent.service #检测状态
Web 管理界面无法访问怎么办?
DolphinDB 正常启动后,在浏览器输入控制节点正确的访问地址,但 Web 管理界面无法正常打开,如下图所示:
出现上述问题的原因通常是由于浏览器与 DolphinDB 不是部署在同一台服务器,且部署 DolphinDB 的服务器开启了防火墙。可以通过关闭部署了 DolphinDB 的服务器的防火墙或者打开对应的部署端口,解决这个问题。
Linux 升级失败如何版本回退?
如果升级以后不能正常开启 DolphinDB 集群,可按以下方式回退到旧版本。
第一步:恢复旧版本元数据文件
恢复控制节点元数据
登录控制节点的服务器,在
/DolphinDB/server/clusterDemo/dfsMeta
目录执行以下 Shell 指令恢复已备份的控制节点元数据:
cp -r backup/DFSMetaLog.0 ./
cp -r backup/DFSMasterMetaCheckpoint.0 ./
恢复数据节点元数据
登录数据节点的服务器(以
P1
为例),在
/DolphinDB/server/clusterDemo/data
目录执行以下 Shell 指令恢复已备份的数据节点元数据:
cp -r backup/CHUNK_METADATA ./P1-datanode/storage
第二步:恢复旧版本程序文件
在官方下载旧版本程序包,把重新下载的旧版本
server
目录下除
dolphindb.cfg
,
clusterDemo
以及
dolphindb.lic
外的所有文件覆盖替换升级失败的文件。
为什么在线更新授权许可文件失败?
在线更新授权文件需要满足
更新授权许可文件
中在线更新的要求。如果不满足其中的要求,可以通过离线方式进行更新,或申请企业版 License。
为什么云部署节点无法启动?
DolphinDB 集群既可以部署在局域网内,也可以部署在私有云或公有云上。DolphinDB 默认集群的所有节点在一个局域网内(
lanCluster
=1)并通过 UDP 广播来监测节点心跳。但是在云平台上,所有节点不一定位于一个局域网,也有可能不支持 UDP。所以,在云平台上,需要在
controller.cfg
和
agent.cfg
填入 lanCluster=0 来实现非 UDP 模式的节点之间的通讯。否则,由于可能无法正常检测到节点的心跳,集群可能无法正常工作。
如何进行配置参数调优?
如果遇到性能问题,请添加微信号13306510479 或扫描下面二维码,客服会邀您进群,由 DolphinDB 技术支持工程师会解答您的问题。
如何设置数据卷?
数据卷是位于数据节点上的文件夹,用来保存分布式文件系统的数据。一个数据节点可以有多个数据卷。要确保最优性能,每个数据卷应当对应不同的物理设备。如果多个数据卷对应同一个物理设备,会影响性能。
可在
cluster.cfg
中设置数据卷的路径。如果用户不设置数据卷的路径,系统会默认按数据节点别名来设置数据卷的路径。若节点别名为 P1-datanode,系统会自动在该节点的
/DophinDB/server/clusterDemo/data
目录下创建一个名为
P1-datanode
的子目录来存储数据。注意:数据卷只支持绝对路径,不支持相对路径。
注意
:在 linux 环境部署时,
volumes
配置目录建议不要指定用 NAS 挂载服务器路径的远程磁盘,如果这样配置,数据库性能会因为磁盘 IO 瓶颈变差。 如果非要这样配置,如果您的分区挂载用的是 NFS 协议,则该 datanode(数据节点)进程必须以 root 身份启动。因为普通用户启动的数据库进程无权限在 NAS 读写磁盘,如果用 sudo 用户启动,会造成文件夹权限混乱。
三种设置数据卷路径的方法:
对每个数据节点分别指定数据卷路径
P1-datanode.volumes=/DFS/P1-datanode
P2-datanode.volumes=/DFS/P2-datanode
通过 % 和 ? 通配符
?
代表单个字符;
%
表示 0 ,1 或多个字符。
将所有以 "-datanode" 为结尾的节点的数据存放到
/VOL1
:
%-datanode.volumes=/VOL1
等同于:
P1-datanode.volumes=/VOL1
P2-datanode.volumes=/VOL1
通过 ALIAS 通配符
若所有数据节点的数据卷路径都含有节点别名,可使用 来配置数据卷路径。可用以下代码为每台服务器配置两个物理卷
/VOL1
和
/VOL2
:
volumes=/VOL1/<ALIAS>,/VOL2/<ALIAS>
等同于:
P1-datanode.volumes=/VOL1/P1-datanode,/VOL2/P1-datanode
P2-datanode.volumes=/VOL1/P2-datanode,/VOL2/P2-datanode
FILE:references/doc_9485.md
# 数据分区
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db/db_partitioning.html
**来源**: DolphinDB 官方文档
---
数据分区
为什么对数据库进行分区
对数据库进行分区可以显著降低系统响应延迟,提高数据吞吐量。具体来说,分区有以下主要好处。
分区使得大型表更易于管理。对数据子集的维护操作也更加高效,因为这些操作只针对需要的数据而不是整个表。一个好的分区策略通过只读取查询所需的相关数据来减少要扫描的数据量。如果分区机制设计不合理,对数据库的查询、计算以及其它操作都可能受到磁盘访问I/O这个瓶颈的限制。
分区使得系统可以充分利用所有资源。选择一个良好的分区方案搭配并行计算,分布式计算可以充分利用所有节点来完成通常要在一个节点上完成的任务。若一个任务可以拆分成几个子任务,每个子任务访问不同的分区,可以显著提升效率。
分区类型
DolphinDB 在数据库层面支持多种分区类型: 范围分区、哈希分区、值分区、列表分区与复合分区。选择合适的分区类型,有助于用户根据业务特点对数据进行均匀分割。
范围分区对每个分区区间创建一个分区。
哈希分区利用哈希函数对分区列操作,方便建立指定数量的分区。
值分区每个值创建一个分区,例如股票交易日期、股票交易月等。
列表分区是根据用户枚举的列表来进行分区,比值分区更加灵活。
复合分区适用于数据量特别大而且SQL where 或 group by
语句经常涉及多列。可使用2个或3个分区列,每个分区选择都可以采用区间、值、哈希或列表分区。例如按股票交易日期进行值分区, 同时按股票代码进行范围分区。
创建一个新的分布式数据库时,需要在
database
函数中指定数据库路径 directory,分区类型 partitionType
以及分区模式 partitionScheme。重新打开已有的分布式数据库时,只需指定数据库路径。不允许用不同的分区类型或分区方案覆盖已有的分布式数据库。
聚合函数在分区表上利用分区列操作时,例如当 group by 列与分区列一致时,运行速度特别快。
为便于学习, 以下分区例子使用 Windows 本地目录,用户可以将数据库创建使用的路径改成 Linux 或 DFS 目录。
调用
database
函数前,用户必须先登录,只有具有 DB_OWNER
或 admin 管理员权限才能创建数据库。默认的 admin 管理员登录脚本为:
login(userId=`admin, password=`123456)
下文提供的所有创建数据库脚本,默认已经登录。
范围分区
在范围分区(RANGE)中,分区由区间决定,而区间由分区向量的任意两个相邻元素定义。区间包含起始值,但不包含结尾值。
在下面的例子中,数据库 db 有两个分区:[0,5) 和 [5,10)。使用 ID 作为分区列,并使用函数
append!
在数据库 db 中保存表 t 为分区表 pt。
n=
1000000
ID=rand(
10
, n)
x=rand(
1.0
, n)
t=table(ID, x)
db=database(
"dfs://rangedb"
, RANGE,
0
5
10
)
pt = db.createPartitionedTable(t, `pt, `ID)
pt.append!(t)
pt=loadTable(db,`pt)
select count(x)
from
pt;
目录结构如下:
范围分区创建后,可使用
addRangePartitions
函数来追加分区。细节参见
增加范围分区
。
哈希分区
哈希分区(HASH)对分区列使用哈希函数以产生分区。哈希分区是产生指定数量的分区的一个简便方法。但是要注意,哈希分区不能保证分区的大小一致,尤其当分区列的值的分布存在偏态的时候。此外,若要查找分区列中一个连续范围的数据时,哈希分区的效率比范围分区或值分区要低。
在下面的例子中,数据库 db 有两个分区。使用ID作为分区列,并使用函数
append!
在数据库 db 中保存表 t 为分区表
pt。
n=
1000000
ID=rand(
10
, n)
x=rand(
1.0
, n)
t=table(ID, x)
db=database(
"dfs://hashdb"
, HASH, [INT,
2
])
pt = db.createPartitionedTable(t, `pt, `ID)
pt.append!(t)
pt=loadTable(db,`pt)
select count(x)
from
pt;
目录结构如下:
值分区
在值域(VALUE)分区中,一个值代表一个分区。
n=
1000000
month=take(
2000.01
M.
.2016
.
12
M, n)
x=rand(
1.0
, n)
t=table(month, x)
db=database(
"dfs://valuedb"
, VALUE,
2000.01
M.
.2016
.
12
M)
pt = db.createPartitionedTable(t, `pt, `month)
pt.append!(t)
pt=loadTable(db,`pt)
select count(x)
from
pt;
上面的例子定义了一个具有 204 个分区的数据库 db。每个分区是 2000 年 1 月到 2016 年 12 月之间的一个月(如下图)。在数据库 db 中,表
t 被保存为分区表 pt,分区列为 month。
值分区创建后,可使用
addValuePartitions
函数来追加分区。细节参见
增加值分区
。
列表分区
在列表(LIST)分区中,我们用一个包含多个元素的列表代表一个分区。
n=
1000000
ticker = rand(`MSFT`GOOG`FB`ORCL`IBM,n)
x=rand(
1.0
, n)
t=table(ticker, x)
db=database(
"dfs://listdb"
, LIST, [`IBM`ORCL`MSFT, `GOOG`FB])
pt = db.createPartitionedTable(t, `pt, `ticker)
pt.append!(t)
pt=loadTable(db,`pt)
select count(x)
from
pt;
上面的数据库有 2 个分区。第一个分区包含 3 个股票代号,第二个分区包含 2 个股票代号。
组合分区
组合(COMPO)分区可以定义 2 或 3
个分区列。每列可以独立采用范围(RANGE)、值(VALUE)、哈希(HASH)或列表(LIST)分区。组合分区的多个列在逻辑上是并列的,不存在从属关系或优先级关系。
n=
1000000
ID=rand(
100
, n)
dates=
2017.08
.
07.
.2017
.
08.11
date=rand(dates, n)
x=rand(
10.0
, n)
t=table(ID, date, x)
dbDate = database(, VALUE,
2017.08
.
07.
.2017
.
08.11
)
dbID=database(, RANGE,
0
50
100
)
db = database(
"dfs://compoDB"
, COMPO, [dbDate, dbID])
pt = db.createPartitionedTable(t, `pt, `date`ID)
pt.append!(t)
pt=loadTable(db,`pt)
select count(x)
from
pt;
值域有 5 个分区,其中 20170807 分区有 2 个区间域(RANGE)分区:
若组合分区有一列为值分区,创建后可使用
addValuePartitions
函数来追加分区。
分区设计策略
合理的数据库分区能够提高数据管理效率、查询和计算的性能,实现低延时和高吞吐量。以下列出了设计和优化分区表的设计策略细则,以供参考。
选择恰当分区字段
在 DolphinDB 中,可以用于分区的数据类型包括整型(CHAR, SHORT, INT),日期类型(DATE, MONTH, TIME, MINUTE,
SECOND, DATETIME, DATEHOUR),以及 STRING 与 SYMBOL。此外,哈希分区还支持 LONG, UUID, IPADDR,
INT128 等类型。虽然 STRING 可作为分区列,为确保性能,建议将 STRING 转化为 SYMBOL 再用于分区列。
FLOAT 和 DOUBLE 数据类型不可作为分区字段。
db=database(
"dfs://rangedb1"
, RANGE,
0.0
5.0
10.0
)
会产生出错信息:DOUBLE 数据类型的字段不能作为分区字段
The data type DOUBLE can
't be used for a partition column
虽然 DolphinDB 支持对 TIME, SECOND, DATETIME
类型字段的分区,但是在实际使用中要尽量避免对这些数据类型采用值分区,以免分区粒度过细,将耗费大量时间创建或查询百万级以上的很小的分区。例如下面这个例子就会产生过多的分区。
序列:2012.06.01T09:30:00..2012.06.30T16:00:00 包含 2,529,001个元素。如果用这个序列进行值分区,将会在磁盘上产生
2,529,001 个分区,即 2,529,001 个文件目录和相关文件,使得分区表创建、写入、查询都非常缓慢。
分区字段应在业务中,特别是数据更新的任务中有重要相关性。譬如在证券交易领域,许多任务都与股票交易日期或股票代码相关,因此以这两个字段来分区比较合理。更新数据库时,DolphinDB
的事务机制不允许多个writer的事务在分区上有重叠。鉴于经常需要对某个交易日或某只股票的数据进行更新,若采用其它分区字段(例如交易时刻),有可能造成多个
writer 同时对同一分区进行写入而导致问题。
一个分区字段相当于数据表的一个物理索引。如果查询时用到了该字段做数据过滤,SQL
引擎就能快速定位需要的数据块,而无需对整表进行扫描,从而大幅度提高处理速度。因此,分区字段应当选用查询和计算时经常用到的过滤字段。
控制分区粒度
一个分区内的多个列以文件形式独立存储在磁盘上,通常数据是经过压缩的。使用的时候,系统从磁盘读取所需要的列,解压后加载到内存。若分区粒度过大,可能会造成多个工作线程并行时内存不足,或者导致系统频繁地在磁盘和工作内存之间切换,影响性能。一个经验公式是,若数据节点的可用内存是
S,工作线程(worker)的的数量是 W,建议每个分区解压后在内存中的大小不超过 S/8W。假设工作内存上限为 32GB,并有 8
个工作线程,建议单个分区解压后的大小不超过 512MB。
DolphinDB 的子任务以分区为单位。因此分区粒度过大会造成无法有效利用多节点多分区的优势,将本来可以并行计算的任务转化成了顺序计算任务。
综上各种因素,建议一个分区未压缩前的原始数据大小不超过
1GB。当然这个限制可结合实际情况调整。譬如在大数据应用中,经常有宽表设计,一个表有几百个字段,但是单个应用只会使用一部分字段。这种情况下,可以适当放大上限的范围。
降低分区粒度可采用以下几种方法:
采用组合分区
增加分区个数
将范围分区改为值分区
分区粒度不要过小
若分区粒度过小,一个查询和计算作业往往会生成大量的子任务,这会增加数据节点和控制节点,以及控制节点之间的通讯和调度成本。分区粒度过小,也会造成很多低效的磁盘访问(小文件读写),造成系统负荷过重。另外,所有的分区的元数据都会驻留在控制节点的内存中。分区粒度过小,分区数过多,可能会导致控制节点内存不足。
提示:
建议每个分区未压缩前的数据量不要小于 100M。
综合前述,推荐分区大小控制在 100MB 到 1GB 之间。
股票的高频交易数据若按交易日期和股票代码的值做组合分区,会导致许多极小的分区,因为许多交易不活跃的股票的交易数据量太少。如果将股票代码的维度按照范围分区的方法来切分数据,将多个交易不活跃的股票组合在一个分区内,则可以有效解决分区粒度过小的问题,提高系统的性能。
均匀分区
当各个分区的数据量差异很大时,会造成系统负荷不均衡,部分节点任务过重,而其它节点处于闲置等待状态。当一个任务有多个子任务时,只有最后一个子任务完成了,才会将结果返回给用户。由于一个子任务对应一个分区,如果数据分布不均匀,可能会增大作业延时,影响用户体验。
为了方便根据数据的分布进行分区,DolphinDB 提供了函数
cutPoints(X, N, [freq])
。其中,X
是一个数组,N 代表需要产生多少组, 而 freq 是 X 的等长数组,其中每个元素对应着 X 中元素出现的频率。函数返回具有(N + 1)个元素的数组,代表
N 个组,使得X中的数据均匀地分布在这 N 个组中。
下面的例子对股票报价数据按日期和股票代码分区数据。如果仅按股票名称首字母进行范围分区,极易造成数据分布不均,因为极少量的股票代码以 U, V, X,Y,Z
等字母开头。我们这里使用
cutPoints
函数将 2020 年 10 月 01 日到 2020 年 10 月 29
日的数据根据股票代码划为 5 个分区:
dates=
2020.10
.
01.
.2020
.
10.29
;
syms=
"A"
+string(
1.
.13
);
syms.append!(string(
'B'
..
'Z'
));
buckets=cutPoints(syms,
5
);//cutpoints
t1=table(take(syms,
10000
)
as
stock, rand(dates,
10000
)
as
date, rand(
10.0
,
10000
)
as
x);
dateDomain = database(
""
, VALUE, dates);
symDomain = database(
""
, RANGE, buckets);
stockDB = database(
"dfs://stockDBTest"
, COMPO, [dateDomain, symDomain]);
pt = stockDB.createPartitionedTable(t1, `pt, `date`stock).append!(t1);
除了使用范围分区的方法,列表分区也是解决数据分布不均匀的有效方法。
时序类型分区
时间是实际数据中最常见的一个维度。以时间类型字段作为分区字段时,在时间取值上可以预留分区以容纳未来数据。以下例子中,我们创建一个数据库,以天为单位,将
2000.01.01 到 2030.01.01 的日期分区。
注:
仅当实际数据写入数据库时,数据库才会真正创建需要的分区。
dateDB = database(
"dfs://testDate"
, VALUE,
2000.01
.
01
..
2030.01
.
01
)
DolphinDB
使用时间类型作为分区字段时,数据库定义的分区字段类型和数据表实际采用的时间类型可以不一致,只要保证定义的分区字段数据类型精度小于等于实际数据类型即可。例如,如果数据库是按月(month)分区,数据表的字段可以是
month, date, datetime, timestamp和 nanotimestamp。系统自动会作数据类型的转换。
共存储
在分布式数据库中,如果多个分区的数据表要连接(join)通常十分耗时,因为涉及到的分区可能在不同的节点上,需要在不同节点之间复制数据。
为解决这个问题,共存储位置(co-location)的分区机制能够确保同一个分布式数据库里所有表在相同分区的数据存储在相同的节点上。这保证了这些表在连接时非常高效。DolphinDB
对采用不同分区机制的多个分区表不提供连接功能。
dateDomain = database(
""
, VALUE,
2018.05
.
01.
.2018
.
07.01
)
symDomain = database(
""
, RANGE, string(
'A'
..
'Z'
) join `ZZZZZ)
stockDB = database(
"dfs://stockDB"
, COMPO, [dateDomain, symDomain])
quoteSchema = table(
10
:
0
, `sym`date`time`bid`bidSize`ask`askSize, [SYMBOL,DATE,TIME,DOUBLE,INT,DOUBLE,INT])
stockDB.createPartitionedTable(quoteSchema,
"quotes"
, `date`sym)
tradeSchema = table(
10
:
0
, `sym`date`time`price`vol, [SYMBOL,DATE,TIME,DOUBLE,INT])
stockDB.createPartitionedTable(tradeSchema,
"trades"
, `date`sym)
上面的例子中,quotes 和 trades 两个分区表采用同一个分区机制。
FILE:references/doc_9486.md
# int
**URL**: https://docs.dolphindb.cn/zh/funcs/i/int.html
**来源**: DolphinDB 官方文档
---
int
语法
int(X)
详情
将输入的数据转换为 INT 类型数据。
参数
X
可以是任意数据类型。
返回值
整型,数据形式同
X
。
例子
x=int();
x;
返回:null
typestr x;
返回:INT
int(`10.9);
返回:10
int(2147483647);
返回:2,147,483,647
注:
INT 数据类型的最大值为 2
31
-1 = 2,147,483,647。
int(2147483648);
由于2,147,483,648 超出了 INT 数据类型的最大值,因此返回:null
FILE:references/doc_9490.md
# pack
**URL**: https://docs.dolphindb.cn/zh/funcs/p/pack.html
**来源**: DolphinDB 官方文档
---
pack
语法
pack(format, args...)
详情
将数据按照
format
指定的格式打包成二进制字节流。
参数
format
格式字符串,用于指定数据格式。指定方式参见附录。关于格式字符串的说明:
格式字符之前可以带有整数表示重复计数。 例如,格式字符串 '4h' 的含义与 'hhhh' 完全相同。
格式之间的空白字符会被忽略;但是计数及其格式字符中不可有空白字符。
对于 's' 格式字符,计数会被解析为字节的长度,而不是重复计数;例如,'10s' 表示一个 10 字节的字节串,而 '10c' 表示 10 个字符。
若未给出计数,则默认值为1。字节串会被适当地截断或填充空字节以符合要求。
args...
表示需要进行打包的数据。参数个数与
format
的长度一致。每个参数的类型与对应位置的
format
类型一致。
返回值
一个 bytes 对象,包含
args
数据按照格式字符串
format
打包后的值。
例子
res = pack("N",1);
res1 = unpack("N", res);
print(res1)
// output
(1)
res = pack("iii", 1, 2, 3)
res1 = unpack("iii", res);
print(res1)
// output
(1,2,3)
res = pack("x",NULL)
res = unpack("x",pack("x",NULL))
typestr(res[0])
// output
VOID
res = pack("3si", `123, 3)
res1 = unpack("3si", res);
print(res1)
// output
("123",3)
附录
格式和类型的对应关系见格式字符与类型部分内容。
默认情况下,C 类型以本机格式和字节顺序表示,在必要时通过跳过填充字节进行正确对齐(根据 C 编译器使用的规则)。
格式字符串的第一个字符可用于指示打包数据的字节顺序,大小和对齐方式,见首字符字节顺序,大小和对齐方式部分内容。 如果第一个字符不是其中之一,则按 '@' 处理。
相关函数:
unpack
FILE:references/doc_9492.md
# flushComputeNodeMemCache
**URL**: https://docs.dolphindb.cn/zh/funcs/f/flushcomputenodememcache.html
**来源**: DolphinDB 官方文档
---
flushComputeNodeMemCache
语法
flushComputeNodeMemCache()
详情
应用于计算组中的计算节点上,将该节点的内存缓存的内容写入磁盘缓存。
适用场景:在计算节点升级并需要优雅重启时,首先使用该函数将内存缓存的内容写入磁盘,这样在计算节点重启后,可以避免从远程数据节点集群重新获取数据,从而提升性能。
参数
无
返回值
无
FILE:references/doc_9493.md
# dumpHeapSample
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dumpheapsample.html
**来源**: DolphinDB 官方文档
---
dumpHeapSample
语法
dumpHeapSample(filename)
详情
生成当前堆内存的快照。调用此函数后,系统会记录当前的内存使用情况,包括已分配的内存块、它们的大小和状态等信息。仅管理员可执行该函数。
参数
filename
字符串标量,表示堆内存快照的路径。
返回值
无。
例子
对内存使用情况进行分析的流程如下:
启用堆内存采样:可在启动 DolphinDB 前,设置环境变量 TCMALLOC_SAMPLE_PARAMETER 为1-524288之间的值(建议值
524288);或通过函数
startHeapSample
动态开启。
在可能发生内存泄漏的操作前、后分别执行
dumpHeapSample
,保存两个不同的文件。通过对比两个文件,确认操作涉及到的内存分配和使用情况。
关闭堆内存采样。
startHeapSample(524288)
dumpHeapSample("/DolphinDB/Data/heap1")
dumpHeapSample("/DolphinDB/Data/heap2")
stopHeapSample()
相关函数:
startHeapSample
,
stopHeapSample
FILE:references/doc_9502.md
# setStreamTableFilterColumn
**URL**: https://docs.dolphindb.cn/zh/funcs/s/setStreamTableFilterColumn.html
**来源**: DolphinDB 官方文档
---
setStreamTableFilterColumn
语法
setStreamTableFilterColumn(streamTable, columnName)
详情
指定流数据表的过滤列。该函数需要配合
subscribeTable
函数的
filter
参数一起使用。
filter
是一个向量,
streamTable
的
columnName
列在
filter
中的数据才会发布到订阅端,不在
filter
中的数据不会发布。一个流数据表只能指定一个过滤列。
参数
streamTable
是流数据表。
columnName
是一个字符串。
例子
下例中,指定了流数据表 trades 的 symbol 列为过滤列,同一节点上的表 trades_slave 订阅流数据表
trades 时把 filter 设置为 ["IBM", "GOOG"],即流数据表 trades 的 symbol 为 "IBM" 或 "GOOG"
时才会发布到订阅端。
share streamTable(10000:0,`time`symbol`price, [TIMESTAMP,SYMBOL,INT]) as trades
setStreamTableFilterColumn(trades, `symbol)
trades_1=table(10000:0,`time`symbol`price, [TIMESTAMP,SYMBOL,INT])
filter=symbol(`IBM`GOOG)
subscribeTable(tableName=`trades, actionName=`trades_1, handler=append!{trades_1}, msgAsTable=true, filter=filter);
FILE:references/doc_9504.md
# mdd
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mdd.html
**来源**: DolphinDB 官方文档
---
mdd
是
maxDrawdown
的别名。
FILE:references/doc_9509.md
# unpivot
**URL**: https://docs.dolphindb.cn/zh/funcs/u/unpivot.html
**来源**: DolphinDB 官方文档
---
unpivot
语法
unpivot(obj, keyColNames, valueColNames, [func])
详情
把多列的数据转换成一列。
参数
obj
是一个表。
keyColNames
是表示列名的标量或向量,用于指定要在输出表中保留的列。
valueColNames
是一个列名向量。
valueColNames
中的数据将转换成一列。 请注意
valueColNames
各列的数据类型应一致。
func
是一个函数。如果指定了
func
函数,该函数将会应用到
valueColNames
上,再将其合并。
返回值
返回一个表,列的顺序依次为
keyColNames
指定的各列,valueType 列和 value
列。其中,若未指定
func
参数,则 valueType 列存储
valueColNames
中的列名,否则 ,valueType 列存储
func
应用于
valueColNames
中各列的结果;value 列存储
valueColNames
中各列的值。
例子
t=table(1..3 as id, 2010.01.01 + 1..3 as time, 4..6 as col1, 7..9 as col2, 10..12 as col3, `aaa`bbb`ccc as col4, `ddd`eee`fff as col5, 'a' 'b' 'c' as col6);
t;
id
time
col1
col2
col3
col4
col5
col6
1
2010.01.02
4
7
10
aaa
ddd
'a'
2
2010.01.03
5
8
11
bbb
eee
'b'
3
2010.01.04
6
9
12
ccc
fff
'c'
保留表 t 中的 id 列,将 col1 列和 col2 列转换为一列:
t.unpivot(keyColNames=`id, valueColNames=`col1`col2);
id
valueType
value
1
col1
4
2
col1
5
3
col1
6
1
col2
7
2
col2
8
3
col2
9
保留表 t 中的 id 列,将 col1 列和 col2 列转换为一列,且将自定义函数应用于 col1 列和 col2 列:
f = def(x): x.split("col")[1];
t.unpivot(keyColNames=`id, valueColNames=`col1`col2, func=f);
id
valueType
value
1
1
4
2
1
5
3
1
6
1
2
7
2
2
8
3
2
9
不保留其它列,仅仅将 col1 列和 col2 列转换为一列:
t.unpivot(, valueColNames=`col1`col2);
valueType
value
col1
4
col1
5
col1
6
col2
7
col2
8
col2
9
保留表 t 中的 id 列,将 col1 列、col2 列 和 col3 列转换为一列,且将自定义函数应用于 col1 列、col2 列和 col3 列:
f = def(x): x.regexReplace("col", "var")
t.unpivot(keyColNames=`id, valueColNames=`col1`col2`col3, func=f);
id
valueType
value
1
var1
4
2
var1
5
3
var1
6
1
var2
7
2
var2
8
3
var2
9
1
var3
10
2
var3
11
3
var3
12
t.unpivot(keyColNames=`time, valueColNames=`col4`col5)
time
valueType
value
2010.01.02
col4
aaa
2010.01.03
col4
bbb
2010.01.04
col4
ccc
2010.01.02
col5
ddd
2010.01.03
col5
eee
2010.01.04
col5
fff
t = table(1..3 as id, 2010.01.01 + 1..3 as time, 8.1 9.2 11.3 as bid1, 12.4 11.1 10.5 as bid2, 10.1 10.2 10.3 as bid3, 10.1 10.2 10.3 as bid4, 10.1 11.2 9.3 as bid5, 7.7 8.2 10.5 as ask1, 11.4 10.1 9.5 as ask2, 9.6 9.2 11.3 as ask3, 12.1 7.2 8.3 as ask4, 10.1 12.5 8.9 as ask5);
t;
//保留 id 和 time 列,将 bid1~bid5 列转换到一个列
t1 = t.unpivot(`id`time, `bid1`bid2`bid3`bid4`bid5);
//不保留其它列,仅仅将 ask1~ask5 列转换到一个列
t2 = t.unpivot(, `ask1`ask2`ask3`ask4`ask5);
//分别将 t1 和 t2 的 valueType 和 value 列重命名后进行合并
re = rename!(t1, `valueType`value, `bid_type`bid_value) join rename!(t2, `valueType`value, `ask_type`ask_value)
re;
id
time
bid_type
bid_value
ask_type
ask_value
1
2010.01.02
bid1
8.1
ask1
8.1
2
2010.01.03
bid1
9.2
ask1
9.2
3
2010.01.04
bid1
11.3
ask1
11.3
1
2010.01.02
bid2
12.4
ask2
12.4
2
2010.01.03
bid2
11.1
ask2
11.1
3
2010.01.04
bid2
10.5
ask2
10.5
1
2010.01.02
bid3
10.1
ask3
10.1
2
2010.01.03
bid3
10.2
ask3
10.2
3
2010.01.04
bid3
10.3
ask3
10.3
1
2010.01.02
bid4
10.1
ask4
10.1
2
2010.01.03
bid4
10.2
ask4
10.2
3
2010.01.04
bid4
10.3
ask4
10.3
1
2010.01.02
bid5
10.1
ask5
10.1
2
2010.01.03
bid5
11.2
ask5
11.2
3
2010.01.04
bid5
9.3
ask5
9.3
FILE:references/doc_952.md
# write
**URL**: https://docs.dolphindb.cn/zh/funcs/w/write.html
**来源**: DolphinDB 官方文档
---
write
语法
write(handle, object, [offset=0], [length])
详情
write
函数把指定的缓冲区转换为字节流,并保存到文件中。缓冲区可以是各种数据类型的标量或向量。如果发生了错误,将抛出
IOException。否则,函数返回写入元素的个数(而不是字节数)。
read!
函数将给定数量的元素读取到缓冲区。例如,如果缓冲区是 INT 向量,该函数将把文件中的字节转换为 INT。
write
和
read
函数都涉及到流和字节之间的转换问题,和计算机科学中多字节的字的0端问题。大端的最重要位位于最低地址,而小端的最不重要位位于最低地址。
write
函数总是使用操作系统的大小端。如果文件的大小端和操作系统的大小端不同,
read!
函数将转换大小端。在使用
file
函数打开文件时,有可选的布尔参数用于表明文件采用的大小端。默认情况下,采用操作系统的大小端。
返回值
INT 类型标量。
例子
x=10h
y=0h
file("test.bin","w").write(x);
// output
1
file("test.bin","r",true).read!(y); // 假设文件格式是小端
// output
1
y;
// output
10
file("test.bin","r",false).read!(y); // 假设文件格式是大端
// output
1
y;
// output
2560
FILE:references/doc_9521.md
# suspendRecovery
**URL**: https://docs.dolphindb.cn/zh/funcs/s/suspendRecovery.html
**来源**: DolphinDB 官方文档
---
suspendRecovery
语法
suspendRecovery()
详情
用于暂停在线恢复节点的进程。恢复进程中,处于 "In-Progress" 状态的数据会继续恢复,"Waiting"
状态的数据会暂停恢复。暂停后,恢复进程的源节点可以继续写入数据。该函数只能由管理员在控制节点上调用。
注:
启用高可用集群时,需要在 raft 组内每个节点执行该命令。
相关命令:
resumeRecovery
FILE:references/doc_9525.md
# drop
**URL**: https://docs.dolphindb.cn/zh/funcs/d/drop.html
**来源**: DolphinDB 官方文档
---
drop
语法
drop(X, n)
详情
从向量中删除前
n
个或后
n
个(如果
n
为负数)个元素,或从矩阵中删除前/后
n
列,或从表中删除前/后
n
行。
参数
X
可以是向量、矩阵或表。
n
是一个整数。
返回值
被删除前/后
n
个元素/列/行的向量、矩阵或表,其数据类型同
X
。
例子
x=1..10;
x.drop(2);
// output
[3,4,5,6,7,8,9,10]
x.drop(-2);
// output
[1,2,3,4,5,6,7,8]
x=1..10$2:5;
x;
#0
#1
#2
#3
#4
1
3
5
7
9
2
4
6
8
10
drop(x,2);
#0
#1
#2
5
7
9
6
8
10
x drop -2;
#0
#1
#2
1
3
5
2
4
6
t=table(1 2 3 4 as x, 11..14 as y);
t;
x
y
1
11
2
12
3
13
4
14
t.drop(2);
x
y
3
13
4
14
FILE:references/doc_9530.md
# deg2rad
**URL**: https://docs.dolphindb.cn/zh/funcs/d/deg2rad.html
**来源**: DolphinDB 官方文档
---
deg2rad
语法
deg2rad(X)
详情
将角的单位从度转换成弧度。
参数
X
可以是标量、向量、矩阵或表。
返回值
返回值类型与
X
保持一致,表示对应弧度值。
例子
deg2rad 45 90 180 360;
// output
[0.785398,1.570796,3.141593,6.283185]
相关函数:
rad2deg
FILE:references/doc_9542.md
# residual
**URL**: https://docs.dolphindb.cn/zh/funcs/r/residual.html
**来源**: DolphinDB 官方文档
---
residual
语法
residual(Y,X,params,[intercept=true])
详情
返回对
X
和
Y
计算最小二乘回归结果的残差。
注:
对于内存表,
ols
和
wls
设置
mode
=2,即可获得残差。对于分布式表,只能通过此函数计算残差。
参数
Y
是因变量;
X
是自变量。
Y
是一个向量;
X
是一个矩阵、表或元组。当
X
是矩阵时,如果行数等于
Y
的长度,
X
的每一列都是一个因子;如果行数不等于
Y
的长度,并且如果列数等于
Y
的长度,
X
的每一行都是一个因子。
params
表示回归模型的系数。
intercept
是一个布尔变量,表示是否包含回归中的截距。默认值是 true。当它为 true 时,系统自动给
X
添加一列 "1"
以生成截距。
返回值
返回 DOUBLE 类型的向量。
例子
例1
x1=1 3 5 7 11 16 23
x2=2 8 11 34 56 54 100
y=0.1 4.2 5.6 8.8 22.1 35.6 77.2
params=ols(y, x1);
residual(y,x1,params)
// output
[6.634188034188036,3.976923076923078,-1.380341880341881,-4.937606837606838,-5.152136752136756,-8.545299145299146,9.404273504273504]
params1=ols(y, (x1,x2),false);
residual(y,(x1,x2),params1,false)
// output
[-1.941530853763632,-2.556479729553295,-4.923597852949359,-11.809587658969416,-11.098921251860737,-4.0152525111045,13.183836820351686]
x=matrix(1 4 8 2 3, 1 4 2 3 8, 1 5 1 1 5);
p1=ols(1..5, x);
residual(1..5, x,p1);
// output
[-0.474770642201834,0.268348623853214,-0.123853211009174,0.598623853211011,-0.268348623853205]
例2
x1 = 10 20 30 40 50
x2 = 5 15 25 35 45
x3 = 3 6 9 12 15
factor0 = 10.7 22.2 29.6 43.4 48.9
t = table(x1, x2, x3, factor0)
x = `x + string(1..3)
residual = makeCall(member, makeCall(ols, sqlCol(`factor0), makeUnifiedCall(matrix, sqlCol(x)), 1, 2), "Residual")
sql(residual, t).eval()
member
-0.74
1
-1.36
2.68
-1.58
FILE:references/doc_9546.md
# month
**URL**: https://docs.dolphindb.cn/zh/funcs/m/month.html
**来源**: DolphinDB 官方文档
---
month
语法
month(X)
详情
返回对应的月份。
参数
X
可以是时间标量或向量。
返回值
MONTH 类型标量或向量。
例子
month();
返回:null
month(`2012.12);
返回:2012.12M
month(2012.12.23); // 把一个 DATE 类型的数据转换成 MONTH 类型。
返回:2012.12M
month(now()); // 把一个 TIMESTAMP 类型的数据转换成 MONTH 类型。
返回:2024.02M
FILE:references/doc_9550.md
# matrix
**URL**: https://docs.dolphindb.cn/zh/funcs/m/matrix.html
**来源**: DolphinDB 官方文档
---
matrix
语法
matrix(X1, [X2], ...)
或
matrix(dataType, rows, cols, [columnsCapacity], [defaultValue])
或
matrix(X)
详情
返回一个矩阵。
参数
第一种情况中,
X1
,
X2
,
...
可以是混合类型,包括向量、矩阵、表(不能包含 SYMBOL 字段)、元组或它们的任意组合。
第二种情况中:
dataType
是矩阵的数据类型,支持除
INT128、UUID、IPADDR、POINT 和 DURATION 外的其他数据类型。
rows
是行数。
cols
是列数。
columnsCapacity
是正整数,表示矩阵的容量,即新建该矩阵时,系统为该矩阵分配的内存(以列数为单位)。当列数超过
capacity
时,系统会自动扩充容量。系统首先会分配当前容量1.2~2倍的内存,然后复制数据到新的内存空间,最后释放原来的内存。
defaultValue
是矩阵的默认值。不指定默认值,对于整数或浮点数类型,矩阵中所有的元素都是 0,对于符号类型,所有元素都是 NULL。
第三种情况下:
X
是一个数组向量(arrayVector),且数组向量每个元素的长度必须相等。
例子
x=matrix(INT,3,2, ,1);
x;
#0
#1
1
1
1
1
1
1
y = matrix(DECIMAL32(3),2,3)
y
#0
#1
#2
0.000
0.000
0.000
0.000
0.000
0.000
s=matrix(SYMBOL,2,2, ,`T);
s;
#0
#1
T
T
T
T
matrix(table(1 2 3 as id, 4 5 6 as value));
#0
#1
1
4
2
5
3
6
matrix([1 2 3, 4 5 6]);
#0
#1
1
4
2
5
3
6
matrix([1 2 3, 4 5 6], 7 8 9, table(0.5 0.6 0.7 as id), 1..9$3:3);
#0
#1
#2
#3
#4
#5
#6
1
4
7
0.5
1
4
7
2
5
8
0.6
2
5
8
3
6
9
0.7
3
6
9
matrix(`AA`BB`CC,`DD`EE`FF)
输出为:
#0
#1
AA
DD
BB
EE
CC
FF
当表中含有 SYMBOL 字段时,通过 matrix 进行转换时会出现报错,如下例:
t = table(symbol(["a", "b"]) as sym, [1, 2] as val)
matrix(t)
// output: matrix(t) => Failed to append a table object to a matrix.
将 SYMBOL 类型转换为 STRING 类型后,可以进行转换,见如下代码:
t = table(string(["a", "b"]) as sym, [1, 2] as val)
matrix(t)
#1
#2
a
1
b
2
FILE:references/doc_9558.md
# stopClusterReplication
**URL**: https://docs.dolphindb.cn/zh/funcs/s/stopClusterReplication.html
**来源**: DolphinDB 官方文档
---
stopClusterReplication
语法
stopClusterReplication()
详情
停止集群间的异步复制。该命令只能由管理员在主/从集群的控制节点调用。
主集群:调用后,停止将任务放入发送队列。
从集群:调用后,停止从主集群读取新任务,但执行中的任务不会停止。
调用该命令前,必须先配置
replicationMode
参数。
参数
无
例子
stopClusterReplication();
相关函数:
startClusterReplication
,
skipClusterReplicationTask
FILE:references/doc_956.md
# decimalMultiply
**URL**: https://docs.dolphindb.cn/zh/funcs/d/decimalMultiply.html
**来源**: DolphinDB 官方文档
---
decimalMultiply
语法
decimalMultiply(X, Y, scale)
详情
DECIMAL 类型的乘法运算,相较于
mul
函数或运算符 *,该函数可以指定计算结果保留的小数位数。
注:
在以下情况下,
scale
参数将会失效,返回值类型为 DECIMAL:
只有一个参数是 DECIMAL 类型(小数位数是 S),且指定的
scale
值不等于 S。
X 和 Y 都是 DECIMAL 类型(小数位数分别是 S1 和 S2),且指定的
scale
值小于
min(S1, S2) 或大于 S1+S2。
当其中一个参数是浮点数时,scale 参数将会失效,并且返回值类型为 DOUBLE。
当
scale
参数失效时,该函数的计算结果等同于 X * Y。
参数
X / Y
标量或向量,其中至少有一个必须为 DECIMAL 类型。
scale
非负整型标量,表示计算结果保留的小数位数。
返回值
DECIMAL 或 DOUBLE 类型。
例子
a = decimal32(`1.235, 3);
b = decimal32(`7.5689, 4);
c=decimalMultiply(a, b, 5)
// output
9.34759
typestr(c)
// output
DECIMAL32
decimalMultiply(a, b, 2) // scale 小于min(3,4),函数结果等于 a*b
// output
9.3475915
b=float(`7.5689)
c=decimalMultiply(a, b, 5) // b 是浮点数, 函数结果等于 a*b,且数据类型是 DOUBLE。
// output
9.3475916337
typestr(c)
// output
DOUBLE
乘法运算(*)和 decimalMultiply 的计算结果如果溢出,会自动转换为更高精度的类型。如果无法进行转换,则会抛出异常。
x = decimal32(1\7, 8)
y = decimal32(1\6, 8)
z = x * y
z
// output
0.0238095223809524
typestr z
// output
DECIMAL64
z = decimalMultiply(x, y, 8)
z
// output
0.02380952
typestr z
// output
DECIMAL64
x = decimal128(1\7, 35)
y = decimal128(1\6, 35)
x*y
// output
x * y => Scale out of bound (valid range: [0, 38], but get: 70)
decimalMultiply(x, y, 35)
// output
decimalMultiply(x, y, 35) => Decimal math overflow
X
和
Y
中至少有一个是向量。
x = [decimal32(3.213312, 3), decimal32(3.1435332, 3), decimal32(3.54321, 3)]
y = 2.1
decimalMultiply(x, y, 5)
// output
[6.7473,6.6003,7.440300000000001]
x = [decimal32(3.213312, 3), decimal32(3.1435332, 3), decimal32(3.54321, 3)]
y = [decimal64(4.312412, 3), decimal64(4.53231, 3), decimal64(4.31258, 3)]
decimalMultiply(x, y, 5)
// output
[13.85445,14.24407,15.27741]
FILE:references/doc_9561.md
# stl
**URL**: https://docs.dolphindb.cn/zh/funcs/s/stl.html
**来源**: DolphinDB 官方文档
---
stl
语法
stl(data, period, sWindow, [sDegree], [sJump], [tWindow], [tDegree],
[tJump], [lWindow], [lDegree], [lJump], [robust], [inner], [outer])
详情
使用 Loess 方法将一个时间序列分解为趋势性、季节性和随机性。
参数
data
是一个数值型向量,表示时间序列。
period
是一个大于1的整数,表示时间序列的周期。
sWindow
可以是一个字符串,它的取值只能是
"periodic",表示在提取时间序列中的周期性时,不采取平滑算法,直接用平均值代替;
sWindow
也可以是一个大于7的奇数,表示提取时间序列中的周期性时 Loess 窗口的长度。
sDegree
可以是0,1或2,表示提取时间序列中的周期性时,局部拟合的多项式次数。默认值为1。
sJump
是一个大于1的整数,表示提取时间序列的周期性时,每隔
sJump
个元素执行一次平滑计算。默认值为
ceil(
sWindow
/10)。
tWindow
是一个正奇数,表示提取时间序列中的趋势性时 Loess 窗口的长度。默认值为 1.5 *
period
/ (1 - (1.5
/
sWindow
)) 的下一个奇数。
tDegree
可以是0,1或2,表示提取时间序列中的趋势性时,局部拟合的多项式次数。默认值为1。
tJump
是一个大于1的整数,表示提取时间序列的趋势性时,每隔
tJump
个元素执行一次平滑计算。默认值为ceil(tWindow/10)。
lWindow
是一个正奇数,表示提取时间序列的周期性时,每一个子序列的低通滤波器的 Loess 窗口长度。默认值为
period
的下一个奇数。
lDegree
可以是0,1或2,表示子序列的低通滤波器中,局部拟合的多项式次数。默认值为1。
lJump
是一个大于1的整数,表示子序列的低通滤波器中,每隔
lJump
个元素执行一次平滑计算。默认值为
ceil(
lWindow
/10)。
robust
是一个布尔值,表示在 Loess 过程中是否采用稳健拟合。默认值为 false。
inner
是一个大于等于1的整数,表示内部迭代次数,一般较小的取值即可满足需求。如果
robust
为 true,
inner
的默认值为1,如果
robust
为 false,
inner
的默认值为2。
outer
是一个大于等于1的整数,表示外部迭代次数,用于增加稳健性。如果
robust
为 true,
outer
的默认值为15,如果
robust
为 false,
outer
的默认值为0。
返回值
一个包含以下 key 的字典:trend, seasonal 和 residual,每个 key 对应一个与 data 长度相同的向量。
例子
n = 100
trend = 6 * sin(1..n \ 200)
seasonal = sin(pi / 6 * 1..n)
residual = rand(1.0, n) - 0.5
data = trend + seasonal + residual
res = stl(data, 12, "periodic");
我们可以在 DolphinDB GUI 中画图检验分解结果。
plot([trend, res.trend]);
plot([seasonal, res.seasonal]);
FILE:references/doc_9573.md
# enableTableShareAndPersistence
**URL**: https://docs.dolphindb.cn/zh/funcs/e/enableTableShareAndPersistence.html
**来源**: DolphinDB 官方文档
---
enableTableShareAndPersistence
语法
enableTableShareAndPersistence(table, tableName, [asynWrite=true],
[compress=true], [cacheSize], [retentionMinutes=1440], [flushMode=0],
[preCache],[cachePurgeTimeColumn],[cachePurgeInterval],[cacheRetentionTime])
详情
该命令将流数据表共享,并把它持久化到磁盘上。
为了保证该命令能够正常执行,需要在配置文件中(单节点:
dolphindb.cfg
,集群:
cluster.cfg
)指定配置参数
persistenceDir
,配置参考:
功能配置
。流数据表在磁盘上的存储目录是
<PERSISTENCE_DIR>/<TABLE_NAME>
。目录包含两种类型的文件:数据文件(名称类型
data0.log, data1.log...
)和索引文件
index.log
。把这些数据保存到磁盘后,如果重启系统,再次执行该命令会把磁盘中的数据加载到内存中,加载的记录条数由参数
preCache
指定,但是实际加载的记录条数有可能会超过
preCache
。
参数
asynWrite
会告知系统是否以异步模式保存表。在异步模式中,追加的数据会被放进队列,之后用于保存的工作线程把数据写入磁盘。在同步模式中,表的追加数据操作直到追加数据被保存到磁盘中才完成。该参数的默认值是
true,即为异步模式。通常情况下,异步模式实现更高的吞吐量,但是如果服务器崩溃,可能会丢失最后追加的行。在异步模式中,保存表的工作是由单个工作线程完成,并且一个工作线程可能处理多个表。如果只保存一个表,增加工作线程的数量并不会提升性能。
默认情况下,流数据表将所有数据保存在内存中。如果流数据表太大,系统可能会出现内存不足的情况。为了避免内存不足的问题,可以通过以下两种方式之一来清理内存中的数据:
配置
cacheSize
参数时,如果插入的数据使内存中流数据表的行数达到阈值,系统将清理内存中较旧的已发布记录。阈值确定规则如下:
每次 append 的数据都不超过
cacheSize
时,内存中的记录数不会大于
cacheSize
的
2.5 倍。
否则,当 append 的数据超过
cacheSize
时,内存中的记录数不会超过追加行数和
cacheSize
之和的 1.2 倍。
同时配置
cachePurgeTimeColumn
,
cachePurgeInterval
和
cacheRetentionTime
,系统将根据时间列清理数据。每次插入新数据时,系统会计算新数据与内存中第一条数据的时间戳差值,当差值大于等于
cachePurgeInterval
时,系统仅保留时间戳与新数据时间戳差值小于等于
cacheRetentionTime
的数据,清理其它数据。
注:
如果手动重启 server,建议调用
fflush
函数先把缓存区的数据写入磁盘使用
kill -15
命令 进程。
如果设置 asynWrite=true,此时流数据写入速度最快,若 server 发生 crash
可能导致部分数据丢失。
如果设置 asynWrite=false,flushmode=0,此时流数据写入速度中等,server 发生
crash 不会丢失数据,但操作系统崩溃可能导致部分数据丢失。
如果设置 asynWrite=false,flushmode=1,此时流数据写入速度最慢,server 发生
crash 或操作系统崩溃都不会导致数据丢失。
不可以将同一个流数据表通过修改共享变量名称的方式共享 2 次及以上。
参数
table
是一个空的流数据表。
tableName
是一个字符串,表示 table 共享后的名称。
asynWrite
可选参数,是一个布尔值,表示是否异步持久化数据到磁盘。默认值为
true,流数据写入内存即为写入成功,持久化到磁盘的操作将会由另一个线程执行。
注:
持久化数据到磁盘包含两个步骤:
写内存数据到操作系统缓存
写缓存数据到磁盘(是否开启同步刷盘由参数
flushMode
决定)
compress
可选参数,是一个布尔值,表示是否以压缩模式模式保存至磁盘。默认值为 true。
cacheSize
可选参数,整数,表示流数据表在内存中最多保留多少行。如果未指定该参数,则所有记录行都会保存在内存中。如果
cacheSize
小于 1000,它会被自动调整为 1000。
retentionMinutes
可选参数,是一个整数,表示文件大小超过 1GB的 log
文件的保留时间(从文件的最后修改时间开始计算),单位是分钟。默认值是 1440,即一天。如果 log 文件未达 1GB,则会一直保留至大小达到 1GB。
flushMode
可选参数,是一个整数,表示是否开启同步刷盘,取值只能为 0 或 1。默认值是
0,表示异步刷盘,内存中的流数据写入操作系统缓存即为写入成功,并进行下一批数据的写入。 若为
1,则表示同步刷盘,当前批次的流数据必须落盘完成,才会进行下一批数据的写入。
preCache
可选参数,是一个整数,表示从磁盘加载到内存的记录条数。如果没有指定该参数,默认会把所有记录加载到内存中。
cachePurgeTimeColumn
可选参数,字符串标量,需要指定为持久化流表中的时间列名称。
cachePurgeInterval
可选参数,DURATION 类型标量,表示触发清理内存中数据的时间间隔。
cacheRetentionTime
可选参数,DURATION 类型标量,表示内存中数据的最长保留期限。
注:
自
3.00.2
版本起,该函数要求参数
cacheRetentionTime
必须小于
cachePurgeInterval
。
返回值
无。
例子
例1.
colName=["time","x"]
colType=["timestamp","int"]
t = streamTable(100:0, colName, colType);
enableTableShareAndPersistence(table=t, tableName=`st, cacheSize=1200000)
go;
for(s in 0:200){
n=10000
time=2019.01.01T00:00:00.000+s*n+1..n
x=rand(10.0, n)
insert into st values(time, x)
}
getPersistenceMeta(st);
/* output:
sizeInMemory->800000
asynWrite->true
totalSize->2000000
compress->true
memoryOffset->1200000
retentionMinutes->1440
sizeOnDisk->2000000
persistenceDir->/home/llin/hzy/server1/pst/st
hashValue->0
diskOffset->0
*/
例2. 本例将说明
cachePurgeTimeColumn
,
cachePurgeInterval
和
cacheRetentionTime
的使用方法。
colName=["time","x"]
colType=["timestamp","int"]
t1 = streamTable(100:0, colName, colType);
enableTableShareAndPersistence(table=t1,tableName=`st1, cachePurgeTimeColumn=`time, cachePurgeInterval=duration("7H"),cacheRetentionTime=duration("2H"))
go;
time=2019.01.01T00:00:00.000
for(s in 0:6000){
time = temporalAdd(time,1,"m");
x=rand(10.0, 1)
insert into st1 values(time, x)
}
getPersistenceMeta(st1);
/* output:
lastLogSeqNum->-1
sizeInMemory->300
totalSize->12000
asynWrite->true
compress->true
raftGroup->-1
memoryOffset->11700
retentionMinutes->1440
sizeOnDisk->11879
persistenceDir->/home/ffliu/jjxu/DolphinDB_Linux64_V3.0/server/persistence/st1
hashValue->0
diskOffset->0
*/
FILE:references/doc_9574.md
# createDualOwnershipReactiveStateEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createDualOwnershipReactiveStateEngine.html
**来源**: DolphinDB 官方文档
---
createDualOwnershipReactiveStateEngine
语法
createDualOwnershipReactiveStateEngine(name, metrics1,
metrics2, dummyTable, outputTable, keyColumn1, keyColumn2, [snapshotDir],
[snapshotIntervalInMsgCount], [keyPurgeFilter1], [keyPurgeFilter2],
[keyPurgeFreqInSecond=0], [raftGroup]
, [outputHandler],
[msgAsTable=false]
)
详情
Dual Ownership Reactive State Engine
是对响应式状态引擎的扩展,支持对同一张流数据表指定两种不同的分组方式分别应用不同的指标进行并行计算。与响应式状态级联实现相比,该函数能极大地提升计算性能。
注:
该引擎输出和输入顺序保持一致,即内部强制使
keepOrder
= True。
不支持乱序处理机制,用户需要自行保证输入的数据有序。
参数
createDualOwnershipReactiveStateEngine
与
createReactiveStateEngine
参数基本一致,这里仅介绍有区别的参数:
对
keyColumn1
分组后的数据按照
metrics1
进行计算,分组数据的清条件则由参数
keyPurgeFilter1
设置。
对
keyColumn2
分组后的数据按照
metrics2
进行计算,分组数据的清条件则由参数
keyPurgeFilter2
设置。
outputTable
结果的输出表,可以是内存表或者分布式表。使用
createDualOwnershipReactiveStateEngine
函数之前,需要将输出表预先设立为一个空表,并指定各列列名以及数据类型。
输出表各列的顺序如下:
分组列。输出表的前几列为
keyColumn1
和
keyColumn2
的公共列,然后依次为
keyColumn1
的非公共列和
keyColumn2
的非公共列。
计算结果列。包含
metrics1
的计算结果列,
metrics2
的计算结果列。
outputHandler
一元函数。设置此参数时,引擎计算结束后,不再将计算结果写到输出表,而是会调用此函数处理计算结果。
msgAsTable
布尔标量,表示在设置了参数 outputHandler 时,将引擎的计算结果以表的结构调用函数。默认值为
false,此时将计算结果的每一列作为元素组成元组。
返回值
一个表对象。
例子
share streamTable(1:0, `date`time`sym`market`price`qty, [DATE, TIME, SYMBOL, CHAR, DOUBLE, INT]) as trades
share table(100:0, `date`sym`market`factor1`factor2, [DATE, SYMBOL, CHAR, DOUBLE, DOUBLE]) as outputTable
dors = createDualOwnershipReactiveStateEngine(name="test", metrics1=<mfirst(price, 3)>, metrics2=<mmax(price, 3)>, dummyTable=trades, outputTable=outputTable, keyColumn1=`date`sym, keyColumn2=`date`market)
tmp = table(1:0, `date`time`sym`market`price`qty, [DATE, TIME, SYMBOL, CHAR, DOUBLE, INT])
subscribeTable(tableName=`trades, actionName="test",msgAsTable=true, handler=tableInsert{dors})
insert into tmp values(2012.01.01, 09:00:00.030, `a, 'B', 10.65, 1500)
insert into tmp values(2012.01.01, 09:00:00.030, `a, 'B', 10.59, 2500)
insert into tmp values(2012.01.01, 09:00:00.031, `b, 'A', 10.59, 2500)
insert into tmp values(2012.01.01, 09:00:00.031, `a, 'B', 10.65, 1500)
insert into tmp values(2012.01.01, 09:00:00.031, `a, 'A', 10.59, 2500)
insert into tmp values(2012.01.01, 09:00:00.033, `b, 'B', 10.59, 2500)
insert into tmp values(2012.01.01, 09:00:00.033, `a, 'A', 10.59, 2500)
insert into tmp values(2012.01.01, 09:00:00.034, `b, 'A', 10.59, 2500)
insert into tmp values(2012.01.01, 09:00:00.034, `b, 'A', 10.22, 1200)
insert into tmp values(2012.01.01, 09:00:00.035, `a, 'A', 11.0, 2500)
insert into tmp values(2012.01.02, 09:00:00.031, `b, 'A', 10.22, 1200)
insert into tmp values(2012.01.02, 09:00:00.032, `a, 'B', 11.0, 2500)
insert into tmp values(2012.01.02, 09:00:00.032, `b, 'B', 15.6, 1300)
insert into tmp values(2012.01.02, 09:00:00.040, `c, 'B', 13.2, 2000)
trades.append!(tmp)
select * from outputTable
date
sym
market
factor1
factor2
2012.01.01
a
'B'
2012.01.01
a
'B'
2012.01.01
b
'A'
2012.01.01
a
'B'
10.65
10.65
2012.01.01
a
'A'
10.59
2012.01.01
b
'B'
10.65
2012.01.01
a
'A'
10.65
10.59
2012.01.01
b
'A'
10.59
10.59
2012.01.01
b
'A'
10.59
10.59
2012.01.01
a
'A'
10.59
11
2012.01.02
b
'A'
2012.01.02
a
'B'
2012.01.02
b
'B'
2012.01.02
c
'B'
15.6
unsubscribeTable(tableName=`trades, actionName="test")
undef(`trades,SHARED)
dropStreamEngine("test")
FILE:references/doc_9575.md
# randWeibull
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randWeibull.html
**来源**: DolphinDB 官方文档
---
randWeibull
语法
randWeibull(alpha, beta, count)
详情
生成指定个数的 Weibull 分布随机数。
参数
形状参数
alpha
和
beta
都是正数。
count
是正整数,表示生成的随机数个数。
返回值
长度为
count
的 DOUBLE 类型向量。
例子
randWeibull(2.31,0.61, 2);
// output
[0.524197, 0.51402]
FILE:references/doc_9579.md
# createEquiJoinEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createEquiJoinEngine.html
**来源**: DolphinDB 官方文档
---
createEquiJoinEngine
语法
createEquiJoinEngine(name, leftTable, rightTable,
outputTable, metrics, matchingColumn, timeColumn, [garbageSize=5000],
[maxDelayedTime]
, [snapshotDir],
[snapshotIntervalInMsgCount]
)
别名:createEqualJoinEngine
详情
创建流数据等值连接引擎。返回一个左、右两表 equi join 后的表对象。注入等值连接引擎的左、右两表将以
matchingColumn
+
timeColumn
作为连接列,返回两表中连接字段相等的行。
流计算 equi join 引擎内部的左、右表基于连接列和时间列构建键值表,不保留全部历史记录,可能因匹配记录被清除而不输出结果,行为上不同于 SQL 的 equi
join。
更多流数据引擎的应用场景说明可以参考
内置多数据源流式关联引擎
。
计算规则
每次数据注入引擎左表时,会在右表中查找与连接列字段相匹配的记录,若找到,则将两表匹配的记录 join 后,根据
metrics
给出的因子进行计算并输出。
每次数据注入引擎右表时,亦会做同样操作。
参数
equi join 引擎的部分参数和 asof join 引擎相同,请参照
createAsofJoinEngine
中参数介绍。下面介绍不同的参数:
name
字符串标量,表示 equi join 引擎的名称,作为其在一个数据节点/计算节点上的唯一标识。可包含字母,数字和下划线,但必须以字母开头。
timeColumn
字符串标量或向量。用于指定
leftTable
和
rightTable
中时间列的名称。两表的时间列名称可以不同,但数据类型需保持一致。当
leftTable
和
rightTable
时间列名称相同时,
timeColumn
是字符串标量,否则,
timeColumn
是长度为2的字符串向量。
garbageSize
可选参数,正整数,默认值是 5,000(单位为行)。当内存中历史数据行数超过
garbageSize
时,会清理本次计算不需要的历史数据。
满足以下条件的数据才会被清理:
历史数据中已经 join 并输出的数据;
历史数据未发生 join 的数据,但其时间戳与
leftTable
或
rightTable
收到的最新数据的时间戳的差值大于
maxDelayedTime
。
maxDelayedTime
可选参数,正整数,单位同
timeColumn
精度一致,默认值为 3
秒。该参数仅在达到
garbageSize
清理条件时才会起效,表示引擎内能够保留最新多长时间的数据。详情参考上述清理条件 2。不建议设置
maxDelayedTime
值设置过小,否则可能导致一些需关联却没及时关联的数据被清理。
返回值
一个表对象。
例子
share streamTable(1:0, `time`sym`price, [SECOND, SYMBOL, DOUBLE]) as leftTable
share streamTable(1:0, `time`sym`val, [SECOND, SYMBOL, DOUBLE]) as rightTable
share table(100:0, `time`sym`price`val`total, [SECOND, SYMBOL, DOUBLE, DOUBLE, DOUBLE]) as output
ejEngine=createEquiJoinEngine("test1", leftTable, rightTable, output, [<price>, <val>, <price*val>], `sym, `time)
subscribeTable(tableName="leftTable", actionName="joinLeft", offset=0, handler=appendForJoin{ejEngine, true}, msgAsTable=true)
subscribeTable(tableName="rightTable", actionName="joinRight", offset=0, handler=appendForJoin{ejEngine, false}, msgAsTable=true)
tmp1=table(13:30:10+1..20 as time, take(`AAPL, 10) join take(`IBM, 10) as sym, double(1..20) as price)
leftTable.append!(tmp1)
tmp2=table(13:30:10+1..20 as time, take(`AAPL, 10) join take(`IBM, 10) as sym, double(50..31) as val)
rightTable.append!(tmp2)
下例中时间列类型为 TIMESTAMP,若不设置
maxDelayedTime
,取默认值3000ms(3s)。
share streamTable(5000000:0, `timestamp`sym`price, [TIMESTAMP, SYMBOL, DOUBLE]) as leftTable
share streamTable(5000000:0, `timestamp`sym`val, [TIMESTAMP, SYMBOL, DOUBLE]) as rightTable
share table(5000000:0, `timestamp`sym`price`val`total`diff`ratio, [TIMESTAMP, SYMBOL, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]) as output
ejEngine=createEquiJoinEngine("test1", leftTable, rightTable, output, <[price, val, price+val, price-val, price/val]>, `sym, `timestamp, 5000)
topic1=subscribeTable(tableName="leftTable", actionName="writeLeft", offset=0, handler=appendForJoin{ejEngine, true}, batchSize=10000, throttle=1)
topic2=subscribeTable(tableName="rightTable", actionName="writeRight", offset=0, handler=appendForJoin{ejEngine, false}, batchSize=10000, throttle=1)
def writeLeftTable(mutable tb){
batch = 1000
for(i in 1..300){
tmp = table(batch:batch, `timestamp`sym`price, [TIMESTAMP, SYMBOL, DOUBLE])
tmp[`timestamp]=take(2012.01.01T00:00:00.000+i, batch)
tmp[`sym]=shuffle("A"+string(1..batch))
tmp[`price]=rand(100.0, batch)
tb.append!(tmp)
}
}
def writeRightTable(mutable tb){
batch = 500
for(i in 1..200){
tmp = table(batch:batch, `timestamp`sym`val, [TIMESTAMP, SYMBOL, DOUBLE])
tmp[`timestamp]=take(2012.01.01T00:00:00.000+i, batch)
tmp[`sym]=shuffle("A"+string(1..batch))
tmp[`val]=rand(100.0, batch)
tb.append!(tmp)
}
}
job1 = submitJob("writeLeft", "", writeLeftTable, leftTable)
job2 = submitJob("writeRight", "", writeRightTable, rightTable)
select count(*) from output order by sym, timestamp
// output: 100000
FILE:references/doc_9582.md
# div
**URL**: https://docs.dolphindb.cn/zh/funcs/d/div.html
**来源**: DolphinDB 官方文档
---
div
语法
div(X, Y)
或
X/Y
详情
返回
X
和
Y
中元素依次相除的结果。当
X
或
Y
是浮点数时,返回一个浮点数。当
X
和
Y
都是整数时,
div
表示整数除法,相当于在除法操作后应用
floor
函数。比如,5/2 返回 2. 如果想要为整数执行“真正”的除法,可以使用
ratio
运算符 "\" 代替。整数常和
mod
运算符一同使用,用来为数据分组。
div
和
mod
的结果应该满足关系式:X=div(X,Y)*Y+mod(X,Y)。
参数
X
和
Y
可以是标量、数据对、向量或矩阵。如果
X
或
Y
的其中一个是数据对、向量、矩阵,另一个必须是具有相同长度或维度的数据对、向量、矩阵。
例子
9/2:5;
// output
4 : 1
11:25/3:4;
// output
3 : 6
x=1 2 3;
x/2;
// output
[0,1,1]
2/x;
// output
[2,1,0]
y=4 5 6;
x/y;
// output
[0,0,0]
y/x;
// output
[4,2,2]
m1=1..6$2:3;
m1;
#0
#1
#2
1
3
5
2
4
6
m1/2;
#0
#1
#2
0
1
2
1
2
3
m2=6..1$2:3;
m2;
#0
#1
#2
6
4
2
5
3
1
m1/m2;
#0
#1
#2
0
0
2
0
1
6
-7/5;
// output
-2
x=-1 2 6;
x/-5;
// output
[0,-1,-2]
FILE:references/doc_9598.md
# cgroup by
**URL**: https://docs.dolphindb.cn/zh/progr/sql/cgroupby.html
**来源**: DolphinDB 官方文档
---
cgroup by
使用cgroup by(cumulative group)子句可进行累计分组计算,第二组的记录包含第一个组的记录,第三个组的记录包含前两组的记录,以此类推。
若SQL语句使用cgroup by子句,其执行顺序如下:
使用过滤条件(若有)
根据cgroup by的列与group by的列(若有)
对select子句中的项目进行分组计算
根据order by的列(必须使用,且必须属于group by列或cgroup by列)对分组计算结果进行排序
计算累计值。若使用group by,则在每个group by组内计算累计值。
注意
:cgroup by子句必须与order by子句一同使用,以在执行累积计算前,将分组计算结果排序。
使用cgroup by的SQL语句只支持以下聚合函数:
sum, sum2, sum3, sum4, prod, max, min, first, last, count,
size, avg, std, var, skew, kurtosis, wsum, wavg, corr, covar, contextCount,
contextSum, contextSum2
.
例子
下例使用cgroup by计算交易量加权平均交易价格(volume weighted average price, 简称vwap)。
t = table(`A`A`A`A`B`B`B`B as sym, 09:30:06 09:30:28 09:31:46 09:31:59 09:30:19 09:30:43 09:31:23 09:31:56 as time, 10 20 10 30 20 40 30 30 as volume, 10.05 10.06 10.07 10.05 20.12 20.13 20.14 20.15 as price);
t;
sym
time
volume
price
A
09:30:06
10
10.05
A
09:30:28
20
10.06
A
09:31:46
10
10.07
A
09:31:59
30
10.05
B
09:30:19
20
20.12
B
09:30:43
40
20.13
B
09:31:23
30
20.14
B
09:31:56
30
20.15
select wavg(price, volume) as vwap from t where sym=`A cgroup by minute(time) as minute order by minute;
time
vwap
09:30m
10.056667
09:31m
10.055714
cgroup by可以与group by配合使用:
select wavg(price, volume) as vwap from t group by sym cgroup by minute(time) as minute order by minute;
sym
minute
vwap
A
09:30m
10.056667
B
09:30m
20.126667
A
09:31m
10.055714
B
09:31m
20.135833
select wavg(price, volume) as vwap from t group by sym cgroup by minute(time) as minute order by sym, minute;
sym
minute
vwap
A
09:30m
10.056667
A
09:31m
10.055714
B
09:30m
20.126667
B
09:31m
20.135833
FILE:references/doc_9599.md
# rowStd
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowStd.html
**来源**: DolphinDB 官方文档
---
rowStd
语法
rowStd(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行元素求样本标准差操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL])
rowStd(m);
// output
[1.858315,1.474223,3.11127]
t1=table(1..5 as x, 10..6 as y, take(3, 5) as z)
t2=table(5..1 as a, 6..10 as b, take(8, 5) as c);
rowStd(t1);
// output
[4.725816,3.785939,2.886751,2.081666,1.527525]
rowStd(t1[`x], t2, 1 1 2 2 2);
// output
[3.114482,3.04959,2.949576,3.316625,3.834058]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2)
select sym,rowStd(price1,price2) as std from t;
sym
std
AAPL
88.833825
MS
15.061374
IBM
14.707821
IBM
15.040161
C
105.175063
相关函数:
rowStdp
,
std
FILE:references/doc_9617.md
# randF
**URL**: https://docs.dolphindb.cn/zh/funcs/r/randF.html
**来源**: DolphinDB 官方文档
---
randF
语法
randF(numeratorDF, denominatorDF, count)
详情
生成指定个数的 F 分布随机数。
参数
numeratorDF
和
denominatorDF
都是正数,表示 F 分布的自由度。
count
是正整数,表示生成的随机数个数。
返回值
长度为
count
的 DOUBLE 类型向量。
例子
randF(2.31, 0.671, 2);
// output
[0.41508, 0.642609]
FILE:references/doc_9636.md
# genericTStateIterate
**URL**: https://docs.dolphindb.cn/zh/funcs/g/genericTStateIterate.html
**来源**: DolphinDB 官方文档
---
genericTStateIterate
语法
genericTStateIterate(T, X, initial, window, func, [leftClosed =
false])
详情
该函数是响应式状态引擎中的函数,基于以时间衡量的窗口进行迭代计算。
假设时间列为
T
,
X
指定为 [X1, X2, ..., Xn],该函数计算结果对应输出表中的列为
factor,初始化字段为
initial
,
window
为 w,迭代函数为 func。
以 Tk 表示第 k 条数据的时间戳,对于第 k 条记录(k = 1, 2 ...),其计算逻辑为:
Tk ∈ [T1, T1+w):factor[k] = initial[k]
其他情况下,第 k+1 条记录对应的窗口为 (Tk-w, Tk] (leftClosed=false) / [Tk-w, Tk]
(leftClosed=true):factor[k] = func(subFactor, X1[k], X2[k], ... , Xn[k]),其中
subFactor 为当前窗口范围内 factor 的值。
注:
数据对用于索引时,不包含右边界的值,即 (k-w):k 的范围是 [k-w, k)。
参数
T
非严格递增的时间类型或整型的向量,且不能包含 NULL 值。注意,时间乱序的数据在计算中会被直接丢弃。
X
表中的字段或对其应用向量函数的计算结果。若不指定,需要置为[];若需要输入多个列变量,需要用元组表示。
initial
用于初始化的列字段,作为初始化窗口内元素的输出,初始化窗口为 [t0, t0 +
window
)(t0
为第一条数据的时间戳,以时间衡量窗口)。
initial
可以是输入表中的字段或对其应用向量函数的计算结果。
window
正整型或 DURATION 标量,表示初始化窗口和历史窗口的长度。当
window
为整数时,其单位与 T 一致。
func
无状态函数,为用户自定义函数,其返回值必须是标量。以部分应用的形式传入。
func
参数个数为 1(历史窗口内的数据)+
X
指定的列数,第一个参数对应历史窗口的元素值,之后的参数依次对应 X
指定列的元素值
。除前述参数外,若
func
包含其他固定的常量参数,则需以部分应用的形式指定。
leftClosed
布尔值,表示历史窗口是否包含左边界的数据,默认为 false。
例子
指定
leftClosed
=false:
// define a function
def myfunc(x, w){
re = sum(x*w)
return re
}
dateTime = 2021.09.09T09:28:00.000 2021.09.09T09:28:30.000 2021.09.09T09:30:00.000 2021.09.09T09:31:00.000 2021.09.09T09:32:00.000
securityID = `600021`600021`600021`600021`600021
volume = 310 280 300 290 240
price = 1.5 1.6 1.7 1.6 1.5
t = table(1:0, `dateTime`securityID`volume`price, [TIMESTAMP, SYMBOL, INT, DOUBLE])
tableInsert(t, dateTime, securityID, volume, price)
output = table(100:0, `securityID`dateTime`factor1, [SYMBOL, TIMESTAMP, DOUBLE])
engine = createReactiveStateEngine(name="test", metrics=[<dateTime>, <genericTStateIterate(dateTime,volume,price,2m,myfunc{,})>], dummyTable=t, outputTable=output, keyColumn=`SecurityID, keepOrder=true)
engine.append!(t)
dropAggregator(`test)
securityID
dateTime
factor1
600021
2021.09.09T09:28:00.000
1.5
600021
2021.09.09T09:28:30.000
1.6
600021
2021.09.09T09:30:00.000
930
600021
2021.09.09T09:31:00.000
270,164
600021
2021.09.09T09:32:00.000
65,062,560
上例计算过程如下:
由于第 1 条数据的时间戳为 09:28:00.000 窗口为 2 min,因此初始化窗口为 [2021.09.09T09:28:00.000,
2021.09.09T09:30:00.000),前 2 条数据均属于该窗口,因此直接输出 price 的值。
第 3 条记录对应的窗口为 (2021.09.09T09:26:30.000, 2021.09.09T09:28:30.000],该历史窗口内的元素为
[1.5, 1.6],当前 volume 的值为 300,因此调用自定义函数 myfunc([1.5, 1.6], 300) = 930;
同理第 4 条记录对应的窗口为 (2021.09.09T09:28:00.000, 2021.09.09T09:30:00.000],该历史窗口内的元素为
[1.6, 930],当前 volume 的值为 290,因此调用自定义函数 myfunc([1.6, 930], 290) = 270164;
以此类推。
指定
leftClosed
=true:
engine = createReactiveStateEngine(name="test", metrics=[<dateTime>, <genericTStateIterate(dateTime,volume,price,2m,myfunc{,},true)>], dummyTable=t, outputTable=output, keyColumn=`SecurityID, keepOrder=true)
securityID
dateTime
factor1
600021
2021.09.09T09:28:00.000
1.5
600021
2021.09.09T09:28:30.000
1.6
600021
2021.09.09T09:30:00.000
930
600021
2021.09.09T09:31:00.000
270,599
600021
2021.09.09T09:32:00.000
65,166,960
上例计算过程如下:
由于第 1 条数据的时间戳为 09:28:00.000 窗口为 2 min,因此初始化窗口为 [2021.09.09T09:28:00.000,
2021.09.09T09:30:00.000),前 2 条数据均属于该窗口,因此直接以 price 的值作为 factor1 的输出。
第 3 条记录对应的窗口为 [2021.09.09T09:26:30.000, 2021.09.09T09:28:30.000],该历史窗口内的元素为
[1.5, 1.6],当前 volume 的值为 300,因此调用自定义函数 myfunc([1.5, 1.6], 300) = 930;
同理第 4 条记录对应的窗口为 [2021.09.09T09:28:00.000, 2021.09.09T09:30:00.000],该历史窗口内的元素为
[1.5, 1.6, 930],当前 volume 的值为 290,因此调用自定义函数 myfunc([1.5, 1.6, 930], 290) =
270599;
以此类推。
相关函数:
genericStateIterate
FILE:references/doc_9639.md
# addMarketHoliday
**URL**: https://docs.dolphindb.cn/zh/funcs/a/addMarketHoliday.html
**来源**: DolphinDB 官方文档
---
addMarketHoliday
语法
addMarketHoliday(marketName, holiday, [dateType = 'holidayDate'])
详情
在线添加一个交易市场节假日
或交易日
文件,通过此文件生成一个交易日历。调用该函数后,在
marketHolidayDir
指定的目录下会生成一个和
marketName
同名的 csv 文件。
注:
该函数只能由管理员调用。
该函数仅对当前节点有效。集群环境中,通过
pnodeRun
调用该函数,使其在其它节点生效。
参数
marketName
字符串标量,表示交易日历标识,例如:国外交易所的 ISO Code、国内交易所简称或自定义交易日历名称。
注:
marketName
必须由4个大写字母组成,且不能与
marketHolidayDir
下的文件名相同。
holiday
DATE 类型向量,表示日期。
当
dateType
='holidayDate' 时,
holiday
需要指定为休市日期,因为系统默认周末为休市日,所以
holiday
只需指定非周末的休市日期。
当
dateType
='tradingDate' 时,
holiday
需要指定为交易日期。
dateType
字符串,用于指定交易日历文件的数据是休市日期还是交易日期。可选值为
‘holidayDate’(默认)或 'tradingDate'。
例子
例1. 以下例子展示如何通过该函数手动添加名为 "DCBA" 的交易日历标识。本例需要添加的数据为非周末的休市日期。
addMarketHoliday("DCBA",2022.01.03 2022.01.05)
运行后,在
/server/marketHoliday/
路径下会新增一个名为
DCBA.csv
的文件,其中包含了已添加的节假日。
图
1
.
DCBA
注:
使用该函数添加已存在于交易日历中的交易日历标识时,会出现
The added market
'<marketName>' already exists.
的提示,说明该交易日历标识已存在于
/server/marketHoliday/
目录下,不需要重复添加。
temporalAdd(2022.01.01,1,"DCBA")
返回:2022.01.04
index = [2022.01.01, 2022.01.02, 2022.01.03, 2022.01.04]
s = indexedSeries(index, 1..4)
s.resample("DCBA", sum);
返回:
label col1
2021.12.31 6
2022.01.04 4
例2. 2024 年2月18日为周日。如果因调休开盘,可以通过指定
dateType
='tradingDate',创建一个交易日历(包含所有易日期)。本例中需要添加的数据为交易日期,包括周末开盘的日期。
tradingDates=[2024.02.08, 2024.02.09, 2024.02.18, 2024.02.19, 2024.02.20, 2024.02.21]
addMarketHoliday(marketName="AAAA", holiday=tradingDates, dateType='tradingDate')
运行以上代码后,在
/server/marketHoliday/
路径下会新增一个名为
AAAA.csv
的文件,包含1列数据,字段名称为 tradingDate,数据为 tradingDates。
temporalAdd(2024.02.09, 1, "AAAA")
返回:2024.02.18
temporalAdd(2024.02.21, 1, "AAAA")
//计算得到的日期如果不在 AAAA.csv 文件中记录,则会报错:The returned date does not exist in trading calendar [AAAA].
FILE:references/doc_9647.md
# module
**URL**: https://docs.dolphindb.cn/zh/progr/statements/module.html
**来源**: DolphinDB 官方文档
---
module
在DolphinDB中,模块是指只包含函数定义的脚本文件。当需要调用一个特定的函数时,可以通过调用含有该函数的模块来实现。通过module语句声明一个模块,该语句位于模块文件的第一行。
模块按层组织。命名结构必须与目录结构相一致。在下面模块声明的例子中,module语句放在了模块文件的首行。
module example::ch9
上述例子中,模块文件路径为<包的根目录>/example/ch9.dos,包的根目录位于<DolphinDB目录>/modules。
我们使用.dos作为模块文件的后缀,是"dolphin script"的缩写。
相关语句:
use
FILE:references/doc_9650.md
# readLines
**URL**: https://docs.dolphindb.cn/zh/funcs/r/readLines.html
**来源**: DolphinDB 官方文档
---
readLines
语法
readLines(handle, [length=1024])
详情
从文件中读取指定行数。如果到达文件尾部或者已经读取指定行数后,函数将返回。
参数
handle
是文件句柄。
length
是从文件中读取的行数。默认的读取行数是1024。
返回值
STRING 类型向量。
例子
timer(10){
x=rand(`IBM`MSFT`GOOG`YHOO`ORCL,10240)
eachRight(writeLine, file("test.txt","w"),x)
fin = file("test.txt")
do{
y=fin.readLine()
} while(!y.isVoid())
fin.close()
};
// output
Time elapsed: 277.548 ms ms
timer(10){
x=rand(`IBM`MSFT`GOOG`YHOO`ORCL,10240)
file("test.txt","w").writeLines(x)
fin = file("test.txt")
do{
y=fin.readLines(1024)
} while(y.size()==1024)
fin.close()
};
// output
Time elapsed: 28.003 ms
FILE:references/doc_9651.md
# sample
**URL**: https://docs.dolphindb.cn/zh/progr/sql/sample.html
**来源**: DolphinDB 官方文档
---
sample
语法
sample(partitionCol, size)
参数
partitionCol
是字符串,表示分区列。
size
是0到1之间的小数或大于0的整数。
详情
sample只能在where语句中使用,随机抽取分区表中的分区。
假设数据库有N个分区,如果 0<size<1,随机抽取int(N*size)个分区,如果size是正整数,随机抽取size个分区。
例子
n=1000000
ID=rand(50, n)
x=rand(1.0, n)
t=table(ID, x)
db=database("dfs://rangedb1", RANGE, 0 10 20 30 40 50)
pt = db.createPartitionedTable(t, `pt, `ID)
pt.append!(t)
pt=loadTable(db,`pt);
pt有5个分区。如果需要随机抽取两个分区,可以使用下面的语句:
x = select * from pt where sample(ID, 0.4);
x = select * from pt where sample(ID, 2);
FILE:references/doc_9657.md
# getStreamingLeader
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getStreamingLeader.html
**来源**: DolphinDB 官方文档
---
getStreamingLeader
语法
getStreamingLeader(groupId)
详情
获取流数据 Raft 组中的 Leader。
参数
groupId
是一个整数,表示流数据 Raft 组的 ID
返回值
字符串标量。
例子
getStreamingLeader(11);
// output: DFS_NODE2
FILE:references/doc_9661.md
# mcount
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mcount.html
**来源**: DolphinDB 官方文档
---
mcount
语法
mcount(X, window, [minPeriods=1])
窗口计算规则请参考:
mFunctions
详情
在给定长度(以元素个数或时间长度衡量)的滑动窗口内统计
X
中的非 NULL 元素个数。
参数
X
是一个向量/矩阵/表/元组(元素为标量或等长向量)/字典。
window
是大于等于 2 的正整型或 DURATION 标量。表示滑动窗口的长度。
注:
在流计算引擎中调用滑动窗口函数时,window 的上限为 102400。
minPeriods
是一个正整数。为滑动窗口中最少包含的观测值数据。
返回值
计算结果为整型,形式同输入参数。
例子
x = 7 4 5 8 9;
mcount(x, 3);
// output: [1,2,3,3,3]
mcount(x, 3, minPeriods=2);
// output: [,2,3,3,3]
x1 =1 2 3 NULL 5;
mcount(x1, 3);
// output: [1,2,3,2,2]
mcount(x1, 3, minPeriods=3);
// output: [,,3,,]
m=matrix(1 2 NULL 4 5, 6 7 8 9 NULL);
m;
#0
#1
1
6
2
7
8
4
9
5
mcount(m,3);
#0
#1
1
1
2
2
2
3
2
3
2
2
s=indexedSeries(date(2020.05.26)+1..8, 3 4 9 NULL 4 6 NULL 8)
mcount(s,4d)
label
col1
2020.05.27
1
2020.05.28
2
2020.05.29
3
2020.05.30
3
2020.05.31
3
2020.06.01
3
2020.06.02
2
2020.06.03
3
mcount(s,1w)
label
col1
2020.05.27
1
2020.05.28
2
2020.05.29
3
2020.05.30
3
2020.05.31
4
2020.06.01
5
2020.06.02
5
2020.06.03
5
相关函数:
count
FILE:references/doc_9663.md
# notIn/NOTIN
**URL**: https://docs.dolphindb.cn/zh/progr/sql/notin.html
**来源**: DolphinDB 官方文档
---
notIn/NOTIN
notIn 是与 in 相反的操作,用于确定指定的值是否与子查询或列表中的值不匹配,其功能等同于
notIn
函数、not in
语句。notIn 支持内存表和分布式表。
语法
select col(s)
from table
where col notIn (value1, value2, ...)
或
select col(s)
from table
where col notIn (subquery)
参数
参数
col(s)
要选择的字段名称。一个或多个多个字段名称或 *(表示所有列)。
table
要查询的表名称。
col
要查询的字段名称。
value1, value2, ...
要查询的值,可以为1个或多个值。
subquery
包含某列结果集的子查询。 该列必须与
col
具有相同的数据类型。
例子
查询 sym 列值不等于 APPL 和 AMZN 的记录。
t = table(`APPL`AMZN`IBM`IBM`APPL`AMZN as sym, 1.8 2.3 3.7 3.1 4.2 2.8 as price);
select * from t where sym notIn (`APPL, `AMZN)
// 等价于 select * from t where sym not in (`APPL, `AMZN)
sym
price
IBM
3.7
IBM
3.1
t1=table(`APPL`AMZN`IBM`IBM`APPL`AMZN as sym, 200 500 300 350 240 580 as vol);
select * from t where sym notIn (select sym from t1 where sym=`IBM)
sym
price
APPL
1.8
AMZN
2.3
APPL
4.2
AMZN
2.8
FILE:references/doc_9665.md
# use
**URL**: https://docs.dolphindb.cn/zh/progr/statements/use.html
**来源**: DolphinDB 官方文档
---
use
要使用一个模块,在模块名前加上"use"关键字。
use example::ch9
使用
use
语句可以调用定义在该模块中的函数。由于不同的模块可以定义相同名字的函数,通过以下规则来区分同名的函数调用:
通过模块命名空间区分函数名。
引用定义在该命名空间的函数。
所有DolphinDB内置函数定义在根模块::下。例如,::add(3,4)指的是根模块下的add函数。
未指明模块命名空间。
如果当前模块定义了被调用的函数,那么该调用指向当前模块中的函数。
如果只有一个已导入的模块中含有被调用的函数,那么该调用指向这个已导入模块中的函数。
如果超过一个以上的已导入模块都包含了被调用的函数,则抛出异常。
如果导入的模块中不包含被调用的函数,搜索根命名空间。如果在根命名空间也没有找到被调用的函数,抛出异常。
2.00.12 版本前,use 语句仅支持调用 .dos 文件;2.00.12 及之后版本,use 语句支持调用 .dos 文件或 .dom 文件。
注意:
若查找目录下存在同名的 .dos 和 .dom 文件,则优先读取 .dos文件。
若要加载的 .dom 文件有依赖其他的文件,则会一并加载。
若要更新已使用 use 加载的 .dom 文件或 .dos 文件,则需要先调用 clearCachedModules 函数清除缓存。
若在 server 初始化时已使用 loadModule 加载 .dom文件或 .dos文件,则启动后再使用 use 加载同名文件将不生效。
自 3.00.0 版本起,支持通过 use 语句切换当前 catalog。使用时,须在 use
后加上“CATALOG”或“catalog”关键字。
use CATALOG catalog1
相关信息:
module
FILE:references/doc_9677.md
# getNodeHost
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getNodeHost.html
**来源**: DolphinDB 官方文档
---
getNodeHost
语法
getNodeHost()
详情
获取本地节点的主机名。该主机名为配置参数
localSite
中定义的 host。
参数
无
返回值
字符串标量。
例子
getNodeHost();
// output: 10.6.0.6
FILE:references/doc_9691.md
# decodeShortGenomeSeq
**URL**: https://docs.dolphindb.cn/zh/funcs/d/decodeShortGenomeSeq.html
**来源**: DolphinDB 官方文档
---
decodeShortGenomeSeq
语法
decodeShortGenomeSeq(X)
别名:
decodeSGS
详情
将经过
encodeShortGenomeSeq
编码的整型数字解码为一个 DNA 序列。
参数
X
整型标量或向量。
返回值
字符串(STRING)或字符串向量(STRING VECTOR)
例子
a=encodeShortGenomeSeq("TCGATCG")
decodeShortGenomeSeq(a)
// output
"TCGATCG"
b=encodeShortGenomeSeq("TCGATCG" "TCGATCGCCC")
decodeShortGenomeSeq(b)
// output
["TCGATCG","TCGATCGCCC"]
// 当输入为空时,返回空字符串。
decodeShortGenomeSeq(int(NULL))
// output
""
// 因"TCGATCG"重复5次后,长度超过了28,所以返回了空的整型向量,再通过 decodeSGS 解码时,会返回为空字符。
c=encodeShortGenomeSeq(repeat("TCGATCG" "TCGAT", 5))
decodeShortGenomeSeq(c)
// output
[,"TCGATTCGATTCGATTCGATTCGAT"]
相关函数:
encodeShortGenomeSeq
,
genShortGenomeSeq
FILE:references/doc_9693.md
# dropStreamTable
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dropStreamTable.html
**来源**: DolphinDB 官方文档
---
dropStreamTable
语法
dropStreamTable(tableName,[force=false])
详情
删除流数据表。如果流数据表启用了持久化,该函数也会将磁盘上持久化的数据删除。
如果流数据表已经持久化到磁盘但是尚未加载到内存,管理员用户可以通过设置参数
force
为 true,直接删除磁盘上的持久化数据。
如果要删除高可用流数据表,只需在 Raft
组中的任意一个数据节点/计算节点上执行该函数即可,其他数据节点/计算节点上名称相同的高可用流数据表也会被删除。
参数
tableName
是一个字符串,表示流数据表的名称。
force
是一个布尔标量,表示是否在内存没有该流数据表时强制删除同名持久化文件。默认值为 false。
返回值
无。
例子
删除普通流数据表:
colNames = `timestamp`sym`qty`price
colTypes = [TIMESTAMP,SYMBOL,INT,DOUBLE]
t=streamTable(1:0,colNames,colTypes)
enableTableShareAndPersistence(t,`trades);
dropStreamTable(`trades);
删除未加载到内存的持久化流数据表:
colNames = `timestamp`sym`qty`price
colTypes = [TIMESTAMP,SYMBOL,INT,DOUBLE]
t=streamTable(1:0,colNames,colTypes)
enableTableShareAndPersistence(t,`trades);
//删除内存中的流数据表
undef(`trades,SHARED)
//删除持久化流表失败
dropStreamTable(`trades)
//dropStreamTable("trades") => Can't find stream table trades
// admin 设置force为true,成功删除
dropStreamTable(tableName=`trades,force=true)
删除高可用流数据表:
colNames = `timestamp`sym`qty`price
colTypes = [TIMESTAMP,SYMBOL,INT,DOUBLE]
t=table(1:0,colNames,colTypes)
haStreamTable(11,t,`trades,100000);
dropStreamTable(`trades);
FILE:references/doc_970.md
# osqp
**URL**: https://docs.dolphindb.cn/zh/funcs/o/osqp.html
**来源**: DolphinDB 官方文档
---
osqp
语法
osqp(q, [P], [A], [lb], [ub])
详情
求二元目标函数在线性约束条件下的最优解。具体模型如下:
参数
q
是目标函数一次项向量。
P
是目标函数的二次项矩阵,且必须是半正定矩阵。
A
是不等式约束的系数矩阵。
lb
是不等式约束的左端向量。
ub
是不等式约束的右端向量。
注:
A
、
lb
、
ub
必须同时指定或同时省略。
lb
和
ub
可以包含空值(NULL),但其长度必须和A的行数匹配。
ub/lb
为空值时,视为正/负无穷,在计算时对应值为 ±10
30
。
返回值
一个元组:
第一个元素是字符串,表示求解状态:
solved :已解决
solved inaccurate:已解决,但结果不精准
primal infeasible:原问题无可行解
dual infeasible:对偶问题无可行解
maximum iterations reached:达到最大迭代次数
run time limit reached:运行超时
problem non convex:问题非凸
interrupted:求解被中断
unsolved:未解决
第二个元素是数值型向量,表示目标函数取到最小值时的数值解。
例子
P = matrix(4e-2 6e-3 -4e-3 0.0, 6e-3 1e-2 0.0 0.0, -4e-3 0.0 2.5e-3 0.0, 0.0 0.0 0.0 0.0)
q = [-2, -4, 2, 3]
A = [1,2,1,1,3,-1,2,1,3,1,-1,1,-2,-4,-5,1]$4:4
l = [,,,1.0]
u = [3.0,2.0,-1.0,1.0]
res = osqp(q, P, A, l, u)
返回:("solved",[-64.364818313795097,368.910318139716082,-548.041799338347459,244.496302999333039])
FILE:references/doc_9706.md
# 主键存储引擎
**URL**: https://docs.dolphindb.cn/zh/db_distr_comp/db/pkey_engine.html
**来源**: DolphinDB 官方文档
---
主键存储引擎
主键存储引擎(PKEY)是提供主键唯一性保证的,支持实时更新和高效查询的存储引擎。该引擎的设计目标是,满足从 OLTP 数据库的主键表 CDC 到 DolphinDB
中进行数据分析的需求。该需求需要存储引擎能够在保持主键唯一性的同时,做到近似实时的、类似 OLTP 的数据插入和更新负载,以及不固定的查询模式(Ad Hoc 查询)。
主键唯一性
目前 DolphinDB 的 TSDB 存储引擎在去重策略为 LAST
的情况下,能满足唯一性的要求。但由于查询时的去重代价较高,且无法使用非主键列的索引,所以不适合需要多种索引结合的 Ad Hoc 查询模式。而 OLAP
存储引擎虽然能最大化查询性能,但由于每次写入都要合并数据,难以做到实时更新。
主流方案介绍
Copy-on-Write
原理
:当数据写入时,将原数据冲突的部分从磁盘读出并合并,然后将合并结果写入磁盘。
优点
:最大化查询性能,查询过程中不需要考虑保证主键唯一性。
缺点
:每次写入都要合并冲突数据,使得更新代价高,不适合频繁更新的场景。
代表系统
:Hudi、Delta Lake、DolphinDB OLAP 存储引擎。
Merge-on-Read
原理
:数据写入时不严格考虑唯一性,不检查新文件是否覆盖旧文件的数据行,采用盲写方式落盘。在数据查询时,再根据查询结果合并可能冲突的新文件,并保留最新主键数据,从而保证主键唯一性。
优点
:写入性能极佳。
缺点
:查询时需要读新文件做去重合并,查询性能优化存在上限,例如无法结合非主键列的索引过滤数据。
代表系统
:ClickHouse、StarRocks 更新表、DolphinDB TSDB 存储引擎。
Merge-on-Write
原理
:引入 delete bitmap 的概念,在数据写入时更新各文件的行删除标记,查询时根据 delete bitmap
直接过滤掉被删除或覆盖的行。
优点
:查询时不需要读取文件做去重,能够有效利用非主键索引来过滤查询结果。支持实时更新的场景。
缺点
:需要更新各个文件的 delete bitmap,牺牲了写入性能。
代表系统
:Hologres、ByteHouse、Doris 主键模型、StarRocks 主键表。
主键引擎方案选择
为实现实时插入和更新,PKEY 存储引擎采用 LSM-Tree 的设计,通过顺序写来保证写入性能。
为实现 Ad Hoc 查询模式,采用 Merge-on-Write 方案,在不影响写入速度的同时,使查询不需要读文件进行去重合并。此外,PKEY
引擎能够利用各种索引来加速查询。
存储结构
PKEY 存储引擎中的数据分别存储在内存和磁盘中。新写入的数据会保存在内存的 Cache Engine 中。当内存数据量达到阈值时,会将数据落盘保存为只读的层文件(称为
Level File)。内存和磁盘上的数据均采用列式存储方式。为了支持高效的主键点查、数据压缩(compaction)以及 delete bitmap (关于
delete bitmap 的详细内容将在”文件结构”一节介绍)更新,内存中的 immutable memtable 和磁盘上的每个 Level File
内部都按照主键顺序排序。存储引擎在新数据写入后,会在后台持续更新 delete bitmap,从而在查询时避免读文件去重的开销。
存储布局
PKEY 存储引擎数据分为内存和磁盘两部分,并由以下几个主要组件构成:
MemTable:新写入的数据会插入到内存表中,内存表分为一个可变内存表和多个不可变内存表。
Stashed Primary Key:当内存中数据达到最大容量时,数据将会落盘。此时引擎会暂存部分数据,用于后续的 delete
bitmap 更新和查询去重。
REDO:预写日志,用于保证事务的原子性和持久性。用户的写入操作会首先将数据写入 redo log 中,然后进入内存表。
META:存储引擎的元数据,包括元信息的 meta.log 和多版本的 delete bitmap 文件。
STORAGE:存储引擎的数据,分为四层,每层存储多个层文件(Level File)。
MemTable
LSM-Tree
的顺序写特性简单来说是将写入和更新操作分为两部分进行:内存插入和文件顺序写。其中内存插入就是写入存储引擎的可变内存表。当可变内存表的数据量达到容量后,会根据主键排序从而形成一个不可变内存表。在
PKEY 引擎中,由 Cache Engine
来维护这两种内存表。由于不可变内存表是有序的,所以主键点查可以通过二分检索来降低复杂度。
Stashed Primary
Key
当内存数据落盘后,引擎会暂存该数据的主键和 CID(commit ID)列,用于 delete bitmap
的后台更新以及查询去重。Stashed Primary Key 采用双缓冲设计,其底层由两个 buffer 组成,每个 buffer 包括两个向量,即主键列和
CID 列。双缓冲设计用于处理后台的 delete bitmap 更新、数据落盘以及查询去重的并发控制,能够消除查询去重的拷贝开销。
Meta
Log
Meta Log 主要存储 PKEY 引擎的文件元信息和 delete bitmap
信息,它的作用是给查询提供某时刻的元信息快照:
文件元信息,包括文件路径、索引信息、各列类型等信息,用于保存分区恢复、事务、数据落盘等文件更改操作。
delete bitmap 信息,包括路径和版本号。
Delete Bitmap
在 PKEY 引擎中,每一个层文件都存在对应的 delete
bitmap,用于指定该文件中某行数据是否被删除或覆盖。delete bitmap 的特点是大小很小,120KB 左右可以存储 100 万行数据的标记。所以
PKEY 存储引擎的一个 delete bitmap 文件可以存储该分区下所有层文件的 delete bitmap。delete bitmap
文件采用多版本方式存储,用于避免查询和写入过程的冲突。具体而言,每一次 delete bitmap 文件的落盘都会以本次数据最大的 flushID
作为快照版本,并由 Meta Log 指定当前最新的 delete bitmap 文件。
Level File
Level
File 在概念上等同于 LevelDB 中的 SSTable。在 Compaction 策略上,PKEY 存储引擎采用 lazy leveling
的设计,即前三层的多个 Level File 之间可能重叠,最后一层的多个 Level File
之间不会重叠。其目的是减少最后一层的读放大以及空间放大。
文件结构
Level
File文件
为了更好地管理 Level File 以及识别 Level File 之间数据的新旧顺序,引擎将每个 Level File
的文件名设计为由三部分组成,分别是 level ID、flush ID 和 sequence number。其中 level ID
指示该文件在逻辑上属于哪一层,flush ID 表示该文件包含的最新数据是来自哪一次落盘,sequence number 则表示该 level file 在所属
sorted run 中的序号。sorted run 是指一组 level file,这些文件之间没有数据重叠,是 flush 或 compaction
的输出。一个文件名的例子比如 1-000000014-001,表示该 level file 存在于第二层,包含 flushID 为 14 的数据,是该
sorted run 中的第二个文件。
Level file内部由六部分组成,如下图所示:
Header:存储该文件的信息,例如最大和最小 CID、各列的类型信息、主键列信息等。
Data Block:数据块,每个数据块最多存储 8192 行数据。文件的每个数据块之间以及数据块内部按主键顺序排序。
Index Block:索引块,目前支持 Bloom Filter 和 Zone Map。
Data Block Index:数据块的索引结构,存储所有数据块的所属列序号、文件偏移量、行数等信息。
Index Block Index:索引块的索引结构,存储所有索引块的类型、列序号、文件偏移量等信息。
Footer:存储 Data Block Index 和 Index Block Index 的文件偏移量。
上述六部分都按照 4KB 对齐,以提高操作系统访问文件块的效率。
Delete Bitmap文件
Delete
bitmap 文件包含了该分区下所有 Level File 的 delete bitmap,其结构如下:
Bitmap:存储某文件的 delete bitmap,内部是一个 01 序列,表示某行是否被删除或覆盖。例如,上图中第一个 bitmap
表示对应 Level File 的第二行、第六行等已被删除或覆盖。
Footer:存储各 bitmap 对应的 Level File 信息以及文件偏移量,包括 Level File 的 level ID、flush
ID 和 sequence number。
存储引擎按照多版本的方式存储 Delete bitmap 文件,从而为查询提供一致的数据快照,其中每个版本由文件名中的 flushID
做区分。Delete bitmap 文件是多版本存储的,每个文件由文件名中的 flush ID 区分。例如 delmap-000000014 是以 flush
ID 为 14 的刷盘数据作为最新数据的各 Level File 的 delete bitmap。meta.log 会记录当前分区最新 delete
bitmap 的 flush ID,每次查询会从元信息中获取最新 delete bitmap 进行去重。
读写流程
数据写入
结合上图从数据传递的视角介绍 PKEY 引擎的写入流程:
写 redo
:写入预写日志,保证事务原子性。
写 cache engine
:当 redo log 写入成功后,写入 cache engine 的 mutable
memtable。
形成 immutable memtable
:当 mutable memtable 中的数据量达到容量(8MB)时,该
memtable 会按主键排序并形成一个 immutable memtable。
后台刷盘
:当 cache engine 中的数据量达到 PKEYCacheEngineSize (默认 1GB)时,PKEY
引擎会触发后台刷盘逻辑,将内存中的所有数据写入磁盘,作为第一层的 Level File。同时,本次刷盘的数据将会存储在 stashed
primary key 中,作为下次 delete bitmap 更新和查询去重的依据。
后台 compaction
:在每次刷盘和 compaction 结束后,后台线程会根据触发条件判断各层是否需要进行
compaction,然后根据文件选取策略进行 compaction
触发条件:检查每层的数据量是否超过阈值,以及每层中被删除或覆盖的行数占总大小的比例。当存在多个层满足触发条件时,会对各层按照一定规则进行评分,进而选择一个分数最高的层进行下一步逻辑。
文件选取策略:从该层中最旧的文件开始,选取互相重叠的 sorted
run,并计算分数做出最优选择。根据触发条件的不同,选取策略的目的倾向也不同:或是倾向于垃圾数据最多的选择,或是倾向于
sorted run 个数最多的选择。
根据文件数量和大小,delete bitmap 更新过程通常比一次 flush 耗时更长。为了在一次 delete bitmap
更新中标记尽可能多的失效行,系统在第 4 步刷盘结束后,会检查 stashed primary key 数据量是否达到阈值
PKEYDeleteBitmapUpdateThreshold(默认值为 100MB),从而触发 delete bitmap 的后台更新。delete
bitmap 后台更新的流程如下:
对每个文件,根据该文件的 zone map 确定需要合并的数据块。
对每个数据块,通过二分法检查并更新 delete bitmap。如果相同主键在 stashed primary key 中 CID
更大,说明该文件的这行需要被标记为删除。
将所有文件的 delete bitmap 写入一个 delete bitmap 文件,并使用 stashed primary key
中最大 flush ID 作为 delete bitmap 的版本号。
数据查询
PKEY 存储引擎的查询过程类似 TSDB KeepLast,区别在于 PKEY 引擎会将谓词条件下推到去重之前,并且能够利用 bloom filter
等索引加速查询。具体的查询流程如下:
获取内存数据
:从 cache engine 中取出所需的列。如果是主键点查,会采用二分查找的方式搜索各个 memtable。
获取元数据版本快照
:从 meta version 中获取 Level File 信息、delete bitmap 信息以及
stashed primary key。
获取磁盘数据
:通过各种索引进行粗过滤,构建各文件的 bitmap 来访问所需的 data block。
使用 bloom filter 过滤:当进行主键点查,或者对存在 bloom filter 索引的列进行等值查询时,会对各个
Level File 进行文件级别的 bloom filter 过滤,找出所有可能存在结果的文件。
使用 zone map 过滤:当进行等值或范围查询时,会对每个 Level File 进行 block
级别的过滤,找出所有满足条件的 block。
使用 delete bitmap 过滤:在上述过滤完成后,将该文件的 delete bitmap 和记录行号的 bitmap
取交集,过滤掉已被删除和覆盖的行。
计算谓词条件结果
:过滤掉不需要的行。
去重
:将查询结果与内存中的 cache engine 和 stashed primary key 进行去重。如果 cache
engine 和 stashed primary key 皆为空,则不需要去重。
返回查询结果
。
数据更新
在 PKEY 引擎中,更新可被视为一次数据查询和写入,具体分为以下步骤:
查询
:根据谓词条件进行一次查询。
修改
:对上述查询结果进行修改。
写入
:按照写入流程插入数据。
数据删除
在 PKEY 引擎中,删除也可被视为一次数据查询和写入,具体分为以下步骤:
查询
:根据谓词条件进行一次查询。
写入
:按照写入流程插入数据,但 CID 将会写入为负数作为删除标记。
PKEY 引擎特点
PKEY 存储引擎在写入和查询性能之间寻求平衡,其特点为:
保证主键唯一性,能做到近实时的更新。
使用主键列进行谓词条件的点查非常高效。
使用非主键列索引的查询效率高。其中 zonemap 能够按块过滤数据,适合时间相关列的过滤查询;bloomfilter
能够按文件过滤数据,适合大基数列的点查询。
当写入数据的吞吐量在一定范围内时,其写入性能接近 TSDB。随吞吐量的增长,主键引擎的写入耗时增长速度高于 TSDB 存储引擎。
PKEY 引擎使用示例
数据库部署
在使用 PKEY 引擎前,可以按需调整系统的配置项,以充分发挥系统的性能。本节主要介绍其中几个重点参数:
PKEYRedoLogDir 和 PKEYMetaLogDir
:为了提高写入效率,建议将 redo log 以及元数据配置在 SSD
盘上。
PKEYCacheEngineSize
:默认是
1G。对于写入压力较大的场景,可以适当调大该值;对于查询性能要求严格的场景,可以调小该值。
若设置过小,写入时可能导致 cache engine 频繁刷盘,影响系统性能。
若设置过大,查询时需要读取 cache engine 数据,但其内部并没有索引信息,且会引入去重开销。
PKEYBlockCacheSize
:PKEY 存储引擎的块缓存容量,默认 1G。查询性能要求严格的场景可以调大该值。
PKEYDeleteBitmapUpdateThreshold
:触发后台 delete bitmap 更新的数据量阈值,默认
100MB。
若设置过小,将导致 delete bitmap 频繁更新,占用磁盘带宽,进而影响查询、cache engine 刷盘及后台
compaction 任务。
若设置过大,则查询的去重开销增加,查询时间延长。过大的设置还会导致重启后的恢复过程变慢。
PKEYStashedPrimaryKeyBufferSize
:设置 PKEY 存储引擎的暂存主键缓冲区的容量,默认
1024MB。该参数在系统面对高写入压力时,能够限制刷盘,从而防止暂存缓冲区无限增长导致 OOM(Out of Memory)的问题。
PKEYBackgroundWorkerPerVolume
:配置每个 Volume 的 PKEY 后台工作线程数。后台工作包括
compaction 和 delete bitmap 更新,默认值为 1。
PKEYCacheFlushWorkerNumPerVolume
:配置每个 Volume 的 PKEY Cache Engine
刷盘工作线程数,默认值为 1。
创建数据库
下述脚本以创建一个组合分区的数据库为例,和其他存储引擎建库时的区别仅在于 engine 设置不同,将 engine 设置为 "PKEY" 表示创建主键引擎数据库
:
dbName="dfs://test_pkey"
db1 = database(, VALUE, 2020.01.01..2021.01.01)
db2 = database(, HASH, [SYMBOL, 100])
db = database(directory=dbName, partitionType=COMPO, partitionScheme=[db1, db2], engine="PKEY")
创建数据表
创建分布式表/维度表时, PKEY 需要设置 primaryKey 这个必选参数。
// 通过函数创建主键引擎表
createPartitionedTable(dbHandle, table, tableName, [partitionColumns],
[compressMethods], [primaryKey], [indexes])
// 通过 SQL 语句创建主键引擎表
create table dbPath.tableName (
schema[columnDescription]
)
[partitioned by partitionColumns],
[primaryKey]
这里以创建一个 PKEY 下的分布式表为例:
tbName = "pt1"
colName = `SecurityID`TradeDate`TradeTime`TradePrice`TradeQty`TradeAmount`BuyNo`SellNo
colType = `SYMBOL`DATE`TIME`DOUBLE`INT`DOUBLE`INT`INT
tbSchema = table(1:0, colName, colType)
// 通过函数创建主键引擎表
db.createPartitionedTable(table=tbSchema, tableName=tbName,
partitionColumns=`TradeDate`SecurityID, primaryKey=`SecurityID`TradeDate`TradeTime,
indexes={"BuyNo": "bloomfilter"})
// 通过 SQL 语句创建主键引擎表
create table "dfs://test_pkey"."pt1"(
SecurityID SYMBOL,
TradeDate DATE,
TradeTime TIME,
TradePrice DOUBLE,
TradeQty INT,
TradeAmount DOUBLE,
BuyNo INT [indexes="bloomfilter"],
SellNo INT
)
partitioned by TradeDate,SecurityID
primaryKey=`SecurityID`TradeDate`TradeTime
其中参数 partitionColumns 表示分区字段,primaryKey 表示该表的主键字段,indexes
表示表中列的索引类型。为提高写入性能和查询效率,应根据数据和业务场景合理设置这几个参数:
合理设置分区字段:
为了确保主键引擎的高效写入,每次批量写入或更新的记录应尽可能集中在少量分区内。有些场景下,分区字段可能是一个递增 id
,或是包含日期等信息的唯一 id。直接以此作为分区列将极大影响写入性能。为了解决这个问题,DolphinDB
特意引入了分区字段上的转换函数,将转换函数的输出作为数据分区的依据。
以包含日期的 id 为例,id 列的格式为
id1_date_id2
,通过自定义函数
myPartitionFunc,提取 id 中的 date ,以此作为分区依据将数据按日期进行分区:
// 定义处理分区列 DateId (形如"475b4_20240101_6d9b2")的函数
def myPartitionFunc(str,a,b) {
return temporalParse(substr(str, a, b),"yyyyMMdd")
}
// partitionColumns 中指定 myPartitionFunc 函数对 DateId 列的数据进行处理
pt = db.createPartitionedTable(table=tb, tableName=`pt,
partitionColumns=["myPartitionFunc(DateId, 6, 8)","SecurityID"],
primaryKey=`SecurityID`DateId`TradeTime,
indexes={"BuyNo": "bloomfilter"})
合理设置主键字段:
包含所有分区字段。
建议有序的主键列优先放在前面,如时间、自增ID等。这些数据在存储上会存放在一起,如果数据相关那么查询效率会比较高。
合理设置索引:
该参数是一个字典,其键和值都是 STRING 类型,分别代表列名和索引类型。例如
indexes={"BuyNo": "bloomfilter"}
表示为 BuyNo
列设置 bloomfilter 索引。
目前支持自定义的 bloomfilter 索引(zonemap
索引每列会自动创建),能在不同场景下加速查询。用户需要合理设置索引,当某种查询真正需要索引时再指定。下表列出了不同索引适用什么场景,以及对应的例子:
索引类型
适用数据
适用负载
举例
BloomFilter
大基数列
点查
select * from pt where id =
"28c9d88b6f67"
ZoneMap
时间相关列
点查和范围查
select * from pt where time >
2024.05.13
下面进一步说明索引的适用场景和效果:
BloomFilter 适合应用于大基数列。数据基数越大,索引效果越好。适合的数据比如身份证ID、订单号、从业务上游同步的外键等。
ZoneMap 适合应用于时间相关列。一批写入的数据越集中,查询效果越好。适合的数据比如订单时间、埋点时间等。因为 ZoneMap
的存储占用很小,所以引擎会自动创建所有列的 ZoneMap。
FILE:references/doc_9707.md
# partial
**URL**: https://docs.dolphindb.cn/zh/funcs/p/partial.html
**来源**: DolphinDB 官方文档
---
partial
语法
partial(func, args...)
详情
创建一个部分应用。
参数
func
是 DolphinDB 中的函数。
args...
是函数的参数。
返回值
一个 FUNCTIONDEF。
例子
partial(add,1)(2);
// output
3
def f(a,b):a pow b
g=partial(f, 2)
g(3);
// output
8
FILE:references/doc_9712.md
# sinh
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sinh.html
**来源**: DolphinDB 官方文档
---
sinh
语法
sinh(X)
详情
返回
X
的双曲正弦。
参数
X
可以是标量、向量或矩阵。
返回值
DOUBLE 类型的标量、向量或矩阵。
例子
sinh 1 2 3;
// output
[1.175201,3.62686,10.017875]
相关函数:
asin
,
acos
,
atan
,
sin
,
cos
,
tan
,
asinh
,
acosh
,
atanh
,
cosh
,
tanh
FILE:references/doc_9714.md
# createWindowJoinEngine
**URL**: https://docs.dolphindb.cn/zh/funcs/c/createWindowJoinEngine.html
**来源**: DolphinDB 官方文档
---
createWindowJoinEngine
语法
createWindowJoinEngine(name, leftTable, rightTable,
outputTable, window, metrics, matchingColumn, [timeColumn],
[useSystemTime=false], [garbageSize = 5000], [maxDelayedTime], [nullFill],
[outputElapsedMicroseconds=false], [sortByTime], [closed],
[cachedTableCapacity=1024], [keyPurgeFreqInSec], [timeoutTrigger])
详情
创建流数据 window join 引擎。返回一个左、右两表实时
window join
后的表对象。
该引擎与 window join 存在以下区别:
window join 仅支持聚合计算,window join 引擎支持聚合计算,也支持非聚合计算。
计算指标中的列未指定表名时,window join 默认取右表列,而 window join 引擎默认取左表列。
注入 window join 引擎左、右两表的数据,根据
matchingColumn
分组。在各分组内,左表的每条记录,都会同右表中一个时间区间(即窗口)内的数据进行连接,并根据指定的
metrics
计算窗口内的数据并输出。
普通窗口(
window
不为 0:0):
右表的计算窗口将由左表当前数据的时间戳和
window
确定。假设左表当前记录的时间戳为 t,
window
为
a:b,则右表时间戳属于 [t+a, t+b] 的数据将与左表当前记录连接并计算输出。
触发计算的规则:
useSystemTime
=false:
同组数据触发:
各分组当前窗口数据的计算将由该窗口结束后的第一条属于该分组的数据触发。触发计算的数据不参与该窗口的计算。
其它分组数据触发:
对于某个分组中未发生计算的窗口,若其窗口右边界 +
maxDelayedTime
<
右表最新收到的任意一个分组数据的时间戳,则该窗口的计算将被新收到的这条数据触发。
useSystemTime
=true:当系统时间到达各分组未发生计算的窗口的右边界时,触发该窗口的计算。
特殊窗口(
window
为 0:0):
右表的计算窗口将由左表当前数据和其上一条数据的时间戳决定。
默认情况下,该窗口左闭右开,
假设左表当前记录的时间戳为 t,上一条记录的时间戳为 t0,则右表计算窗口为 [t0, t)。
可以通过指定参数
closed
= “right”,设置窗口为左开右闭。
触发计算的规则:
useSystemTime
=false:各分组当前窗口数据的计算将由窗口结束后的第一条属于该分组的右表数据触发。
useSystemTime
=true:各个分组收到的左表数据将触发对应分组窗口的数据计算输出。
注:
window
=0:0 时,若
metrics
中指定了非聚合的指标,其输出列必须为对应类型的
array vector。
更多流数据引擎的应用场景说明可以参考
流计算引擎
。
参数
name
必选参数,表示 window join
引擎的名称,作为其在一个数据节点/计算节点上的唯一标识。可包含字母,数字和下划线,但必须以字母开头。
leftTable
表对象。可以不包含数据,但结构必须与输入的流数据表相同。
2.00.9.3 版本开始支持
array vector 类型。
rightTable
表对象。可以不包含数据,但结构必须与输入的流数据表相同。
outputTable
必选参数,为计算结果的输出表。window join 引擎会将计算结果插入该表。
输出表各列的顺序如下:
时间列。其中:
若
useSystemTime
= true,为 TIMESTAMP 类型;
若
useSystemTime
= false,数据类型与
timeColumn
列一致。
连接列。与
matchingColumn
中的列以及其顺序一致,可为多列。
计算结果列。可为多列。
耗时列。若指定
outputElapsedMicroseconds
=
true,则需要增加一个 LONG 类型和一个 INT 类型的列,分别用于存储引擎内部每个 batch
的数据耗时(单位:微秒)和记录数。
window
必选参数,表示滑动窗口区间的整型或 DURATION 数据对,其中左右边界都包含在内。
metrics
以元代码的格式表示计算指标,支持输入元组。有关元代码的更多信息可参考
元编程
。
计算指标可以是一个或多个表达式、系统内置或用户自定义函数。
metrics
内支持调用具有多个返回值的函数,且必须指定列名,例如 <func(price) as
`col1`col2>。
若在
metrics
指定了
leftTable
和
rightTable
中具有相同名称的列,默认取左表的列,可以通过 "tableName.colName"
指定该列来自哪个表。
注:
metrics
中使用的列名大小写不敏感,不要求与输入表的列名大小写保持一致。
当以下函数只计算
rightTable
中的数据列时,window join 引擎对它们进行了优化:sum,
sum2, avg, std, var, corr, covar, wavg, wsum, beta, max, min,
last, first, med, percentile。
matchingColumn
表示连接列的字符串标量/向量/tuple,支持 Integral, Temporal 或
Literal(UUID 除外)类型。
matchingColumn
指定规则为:
只有一个连接列:当左表和右表的连接列名相同时,
matchingColumn
是一个字符串标量,否则是一个长度为 2 的
tuple,例如:左表连接列名为 sym,右表连接列名为 sym1,则
matchingColumn
=
[[`sym],[`sym1]]。
有多个连接列:当左表和右表的连接列名相同时,
matchingColumn
是一个字符串向量,否则是一个长度为 2 的
tuple,例如:左表连接列名为 timestamp, sym,右表连接列名为 timestamp, sym1,则
matchingColumn
= [[`timestamp, `sym], [`timestamp,`sym1]]。
timeColumn
可选参数,当
useSystemTime
= false
时,指定要连接的两个表中时间列的名称。
leftTable
和
rightTable
时间列名称可以不同,但数据类型需保持一致。当
leftTable
和
rightTable
时间列名称不同时,
timeColumn
为一个长度为2的字符串向量。
useSystemTime
可选参数,表示
outputTable
中第一列(时间列)为系统当前时间(
useSystemTime
=
true)或左表的时间列(
useSystemTime
= false)。
garbageSize
可选参数,是正整数,默认值是5,000(单位为行)。随着订阅的流数据不断积累进入 window
join 引擎,存放在内存中的数据会越来越多,这时需要清理不再需要的历史数据。当左/右两表各个分组内的数据行数超过
garbageSize
值时,系统会清理本次计算不需要的历史数据。
maxDelayedTime
可选参数,是正整数,用于触发引擎中长时间未输出的分组数据进行计算。
具体来说,若
(某个分组中未发生计算的窗口右边界) + (maxDelayedTime) <
(右表最新收到的任意一个分组数据的时间戳)
,则这条数据会触发该窗口计算输出。
指定该参数时,必须同时指定 timeColumn,且两者的单位需一致。默认值为3秒,根据
timeColumn
的精度换算。例如,若
timeColumn
的精度是毫秒,则默认值为3000毫秒。
nullFill
和输出表列字段等长且类型一一对应的元组,用于填充以下列中的空值:输出表中包含的左表列、右表列、右表列被聚合计算后的计算结果列。
outputElapsedMicroseconds
布尔值,表示是否输出每个 batch
中数据从注入引擎到计算输出的总耗时,以及每个 batch 包含的总记录数,默认为 false。指定参数
outputElapsedMicroseconds
= true 后,在定义
outputTables
时需要在最后增加两列,详见
outputTable
参数说明。
sortByTime
布尔值,表示是否按全局时间顺序输出数据。默认值为
false,表示不按全局时间输出数据,仅在组内按时间顺序输出数据。注意:当设置 sortByTime=true 时,必须保证输入的左表和右表的数据全局有序,且不可设置
maxDelayedTime
。
closed
字符串,用于确定窗口边界的开闭情况,仅当
window
为 0:0 时有效 。可选值为 ‘left’ 或 ‘right’,默认值为 ‘left’。
closed = ‘left’: 窗口左闭右开。
closed = ‘right’: 窗口左开右闭。此时必须设置 useSystemTime=false 。
cachedTableCapacity
可选参数,为正整数,表示引擎为每个不同的分组分别创建的左缓存表和右缓存表的初始容量(以数据条数计)。默认值为 1024。
keyPurgeFreqInSec
可选参数,为正整数,单位为秒,表示间隔多久检查一次可以清理的分组。
window
=0:0
时不会触发清理。可以清理的分组判断规则如下:
左缓存表无未计算的数据,且
该分组的右缓存表最后一条数据的时间戳 < 右表最新收到的任意一个分组数据的时间戳-
maxDelayedTime - window长度
或
右缓存表为空
,则该分组可以清理。
待清理的分组数大于等于总分组数的 10% 时,触发清理。
timeoutTrigger
可选参数,为布尔标量,表示当右表在较长时间内无数据输入时,是否主动触发计算。开启后可确保所有数据均能在
其窗口的右边界 + [1,3) *
maxDelayedTime
时间范围内触发计算。启用
timeoutTrigger
时,需满足以下条件:
useSystemTime
=false
sortByTime
=false
maxDelayedTime
为正整数。
返回值
返回一个表对象。
例子
share streamTable(1:0, `time`sym`price, [TIMESTAMP, SYMBOL, DOUBLE]) as leftTable
share streamTable(1:0, `time`sym`val, [TIMESTAMP, SYMBOL, DOUBLE]) as rightTable
share table(100:0, `time`sym`factor1`factor2`factor3, [TIMESTAMP, SYMBOL, DOUBLE, DOUBLE, DOUBLE]) as output
nullFill= [2012.01.01T00:00:00.000, `NONE, 0.0, 0.0, 0.0]
wjEngine=createWindowJoinEngine(name="test1", leftTable=leftTable, rightTable=rightTable, outputTable=output, window=-2:2, metrics=<[price,val,sum(val)]>, matchingColumn=`sym, timeColumn=`time, useSystemTime=false,nullFill=nullFill)
subscribeTable(tableName="leftTable", actionName="joinLeft", offset=0, handler=appendForJoin{wjEngine, true}, msgAsTable=true)
subscribeTable(tableName="rightTable", actionName="joinRight", offset=0, handler=appendForJoin{wjEngine, false}, msgAsTable=true)
n=10
tp1=table(take(2012.01.01T00:00:00.000+0..10, 2*n) as time, take(`A, n) join take(`B, n) as sym, take(NULL join rand(10.0, n-1),2*n) as price)
tp1.sortBy!(`time)
leftTable.append!(tp1)
tp2=table(take(2012.01.01T00:00:00.000+0..10, 2*n) as time, take(`A, n) join take(`B, n) as sym, take(double(1..n),2*n) as val)
tp2.sortBy!(`time)
rightTable.append!(tp2)
select * from output where time between 2012.01.01T00:00:00.000:2012.01.01T00:00:00.001
time
sym
factor1
factor2
factor3
2012.01.01T00:00:00.000
A
0
1
6
2012.01.01T00:00:00.000
A
0
2
6
2012.01.01T00:00:00.000
A
0
3
6
2012.01.01T00:00:00.001
A
5.2705
1
10
2012.01.01T00:00:00.001
A
5.2705
2
10
2012.01.01T00:00:00.001
A
5.2705
3
10
2012.01.01T00:00:00.001
A
5.2705
4
10
2012.01.01T00:00:00.000
B
5.2705
2
9
2012.01.01T00:00:00.000
B
5.2705
3
9
2012.01.01T00:00:00.000
B
5.2705
4
9
2012.01.01T00:00:00.001
B
1.0179
2
14
2012.01.01T00:00:00.001
B
1.0179
3
14
2012.01.01T00:00:00.001
B
1.0179
4
14
2012.01.01T00:00:00.001
B
1.0179
5
14
下例展示特殊窗口的计算:
share streamTable(1:0, `time`sym`price, [TIMESTAMP, SYMBOL, DOUBLE]) as leftTable
share streamTable(1:0, `time`sym`val, [TIMESTAMP, SYMBOL, DOUBLE]) as rightTable
v = [1, 5, 10, 15]
tp1=table(2012.01.01T00:00:00.000+v as time, take(`A , 4) as sym, rand(10.0,4) as price)
v = [1, 2, 3, 4, 5, 6, 9, 15]
tp2=table(2012.01.01T00:00:00.000+v as time, take(`A , 8) as sym, rand(10.0,8) as val)
share table(100:0, `time`sym`price`val`sum_val, [TIMESTAMP, SYMBOL, DOUBLE, DOUBLE[], DOUBLE]) as output
wjEngine=createWindowJoinEngine(name="test1", leftTable=leftTable, rightTable=rightTable, outputTable=output, window=0:0, metrics=<[price, val, sum(val)]>, matchingColumn=`sym, timeColumn=`time, useSystemTime=false)
subscribeTable(tableName="leftTable", actionName="joinLeft", offset=0, handler=appendForJoin{wjEngine, true}, msgAsTable=true)
subscribeTable(tableName="rightTable", actionName="joinRight", offset=0, handler=appendForJoin{wjEngine, false}, msgAsTable=true)
leftTable.append!(tp1)
rightTable.append!(tp2)
time
sym
price
val
sum_val
2012.01.01T00:00:00.001
A
8.8252
[]
2012.01.01T00:00:00.005
A
7.1195
[7.495792,9.417891,1.419681,...]
21.3741
2012.01.01T00:00:00.010
A
5.2217
[4.840462,8.086567,3.495306]
16.4223
2012.01.01T00:00:00.015
A
9.2517
[]
当 window=0:0 时,默认情况下,该窗口左闭右开。下例中指定参数
closed
=
"right",将窗口设置为左开右闭。
unsubscribeTable(tableName="leftTable", actionName="joinLeft")
unsubscribeTable(tableName="rightTable", actionName="joinRight")
undef(`leftTable,SHARED)
undef(`rightTable,SHARED)
dropAggregator(name="test1")
share streamTable(1:0, `time`sym`price, [TIMESTAMP, SYMBOL, DOUBLE]) as leftTable
share streamTable(1:0, `time`sym`val, [TIMESTAMP, SYMBOL, DOUBLE]) as rightTable
v1 = [1, 5, 10, 15]
tp1=table(2012.01.01T00:00:00.000+v1 as time, take(`A, 4) as sym, rand(10.0,4) as price)
v2 = [1, 2, 3, 4, 5, 6, 9, 15]
tp2=table(2012.01.01T00:00:00.000+v2 as time, take(`A, 8) as sym, rand(10.0,8) as val)
share table(100:0, `time`sym`price`val`sum_val, [TIMESTAMP, SYMBOL, DOUBLE, DOUBLE[], DOUBLE]) as output
wjEngine=createWindowJoinEngine(name="test1", leftTable=leftTable, rightTable=rightTable, outputTable=output, window=0:0, metrics=<[price, val, sum(val)]>, matchingColumn="sym", timeColumn="time", useSystemTime=false, closed="right")
subscribeTable(tableName="leftTable", actionName="joinLeft", offset=0, handler=appendForJoin{wjEngine, true}, msgAsTable=true)
subscribeTable(tableName="rightTable", actionName="joinRight", offset=0, handler=appendForJoin{wjEngine, false}, msgAsTable=true)
leftTable.append!(tp1)
rightTable.append!(tp2)
sleep(100)
select * from output
返回:
time sym price val sum_val
2012.01.01T00:00:00.001 A 9.7366 [7.8310] 7.831
2012.01.01T00:00:00.005 A 2.6537 [1.8564,4.6238,8.2536,3.1028] 17.8368
2012.01.01T00:00:00.010 A 3.9586 [0.8413,8.0684] 8.9098
下例展示指定
sortByTime
= true 时,引擎将按时间顺序输出数据。
//清理引擎及变量
unsubscribeTable(tableName="leftTable", actionName="joinLeft")
unsubscribeTable(tableName="rightTable", actionName="joinRight")
undef(`leftTable,SHARED)
undef(`rightTable,SHARED)
dropAggregator(name="test1")
//定义引擎
share streamTable(1:0, `time`sym`price, [TIMESTAMP, SYMBOL, DOUBLE]) as leftTable
share streamTable(1:0, `time`sym`val, [TIMESTAMP, SYMBOL, DOUBLE]) as rightTable
share table(100:0, `time`sym`factor1`factor2`factor3, [TIMESTAMP, SYMBOL, DOUBLE, DOUBLE, DOUBLE]) as output
nullFill= [2012.01.01T00:00:00.000, `NONE, 0.0, 0.0, 0.0]
wjEngine=createWindowJoinEngine(name="test1", leftTable=leftTable, rightTable=rightTable, outputTable=output, window=-2:2, metrics=<[price,val,sum(val)]>, matchingColumn=`sym, timeColumn=`time, useSystemTime=false,nullFill=nullFill, sortByTime=true)
//定义数据
subscribeTable(tableName="leftTable", actionName="joinLeft", offset=0, handler=appendForJoin{wjEngine, true}, msgAsTable=true)
subscribeTable(tableName="rightTable", actionName="joinRight", offset=0, handler=appendForJoin{wjEngine, false}, msgAsTable=true)
n=10
tp1=table(take(2012.01.01T00:00:00.000+0..10, 2*n) as time, take(`A, n) join take(`B, n) as sym, take(NULL join rand(10.0, n-1),2*n) as price)
tp1.sortBy!(`time)
leftTable.append!(tp1)
tp2=table(take(2012.01.01T00:00:00.000+0..10, 2*n) as time, take(`A, n) join take(`B, n) as sym, take(double(1..n),2*n) as val)
tp2.sortBy!(`time)
rightTable.append!(tp2)
sleep(100)
select * from output where time between 2012.01.01T00:00:00.000:2012.01.01T00:00:00.001
time
sym
factor1
factor2
factor3
2012.01.01T00:00:00.000
A
0
1
6
2012.01.01T00:00:00.000
A
0
2
6
2012.01.01T00:00:00.000
A
0
3
6
2012.01.01T00:00:00.000
B
3.9389
2
9
2012.01.01T00:00:00.000
B
3.9389
3
9
2012.01.01T00:00:00.000
B
3.9389
4
9
2012.01.01T00:00:00.001
A
3.9389
1
10
2012.01.01T00:00:00.001
A
3.9389
2
10
2012.01.01T00:00:00.001
A
3.9389
3
10
2012.01.01T00:00:00.001
A
3.9389
4
10
2012.01.01T00:00:00.001
B
4.9875
2
14
2012.01.01T00:00:00.001
B
4.9875
3
14
2012.01.01T00:00:00.001
B
4.9875
4
14
2012.01.01T00:00:00.001
B
4.9875
5
14
FILE:references/doc_9726.md
# getSlaveReplicationQueueStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getslavereplicationqueuestatus.html
**来源**: DolphinDB 官方文档
---
getSlaveReplicationQueueStatus
语法
getSlaveReplicationQueueStatus()
详情
获取从集群每个执行队列的任务执行状态。该函数只能由管理员在从集群的控制节点调用。
参数
无
返回值
返回一个表,包含以下字段:
executionSet:任务所属的执行集ID。
queueId:任务所属队列的编号。
unifinishedTasks:队列中未执行的任务数量。
executionGroupId:正在执行任务所属的组号。
executionNode:执行该 group 的数据节点别名。
executionTime:当前 group 已经执行的时间。
status:任务执行状态,包含四种类型:
EXECUTING(正在执行)、FAILED(执行失败)、STOPPED(停止执行)、FINISHED(执行完成)
例子
getSlaveReplicationQueueStatus()
输出返回:
executionSet
queueId
unfinishedTasks
executionGroupId
executionNode
executionTime
status
0
0
0
-1
dnode1
00:00:00.000
FINISHED
0
1
0
-1
dnode2
00:00:00.000
FINISHED
0
2
0
-1
dnode3
00:00:00.000
FINISHED
1
3
0
-1
dnode1
00:00:00.000
FINISHED
1
4
0
-1
dnode2
00:00:00.000
FINISHED
1
5
0
-1
dnode3
00:00:00.000
FINISHED
FILE:references/doc_9734.md
# triggerNodeReport
**URL**: https://docs.dolphindb.cn/zh/funcs/t/triggerNodeReport.html
**来源**: DolphinDB 官方文档
---
triggerNodeReport
语法
triggerNodeReport(nodeAlias, [chunkId])
详情
强制触发别名为
nodeAlias
的节点向控制节点汇报信息,以更新控制节点维护的元数据信息。若指定了
chunkId
参数,则仅上报对应
chunk 信息。
使用场景:该命令用于解决数据节点离线并再次上线后,出现不汇报某些 chunk 信息的问题。
操作步骤如下:
通过命令
getClusterPerf
查看 state
字段,以确定各个节点的存活情况。
通过
getClusterChunksStatus
查看 replicas,
replicaCount 字段,以确定 chunk 的副本信息。
若节点存活,但出现副本数不一致,在 controller 的日志中,搜索对应的
chunkId,并定位出未汇报的数据节点。在该数据节点上调用
triggerNodeReport
强制触发其汇报
chunk 信息。
若此方法失效,建议重启节点。
参数
nodeAlias
字符串,表示节点的别名。
chunkId
可选参数,一个字符串或者字符串向量。表示需要汇报的 chunks 的 ID 值。该参数仅对集群有效。
返回值
无。
FILE:references/doc_9736.md
# sqlDelete
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sqlDelete.html
**来源**: DolphinDB 官方文档
---
sqlDelete
语法
sqlDelete(table, [where], [from])
详情
动态生成 SQL delete 语句的元代码。若需执行生成的元代码,请配合使用
eval
函数。
参数
table
可以是内存表,亦可为分布式表。
where
是元代码,表示 where 条件。
from
是元代码,表示 from 子句。
返回值
CODE 类型标量。
例子
例1. 删除内存表记录
t1=table(`A`B`C as symbol, 10 20 30 as x)
sqlDelete(t1, <symbol=`C>).eval()
t1;
symbol
x
A
10
B
20
例2. 删除分区表记录
if(existsDatabase("dfs://db1")){
dropDatabase("dfs://db1")
}
n=1000000
t=table(take(`A`B`C`D,n) as symbol, rand(10.0, n) as value)
db = database("dfs://db1", VALUE, `A`B`C`D)
Trades = db.createPartitionedTable(t, "Trades", "symbol")
Trades.append!(t)
select count(*) from Trades;
// output: 1000000
Trades=loadTable("dfs://db1", "Trades")
sqlDelete(Trades, <symbol=`A>).eval()
select count(*) from Trades;
// output: 750000
例3. 结合表连接删除记录
t1 = table(1..5 as id, [1,2,2,1,1] as flag)
t2 = table(3..7 as id, [100,200,100,150,100] as profit)
sqlDelete(table=t2, where=<flag=1>, from=<ej(t2,t1,`id)>).eval()
t2
id
profit
3
100
6
150
7
100
FILE:references/doc_9737.md
# endsWith
**URL**: https://docs.dolphindb.cn/zh/funcs/e/endsWith.html
**来源**: DolphinDB 官方文档
---
endsWith
语法
endsWith(X, str)
详情
检查
X
是否以
str
结尾。如果是,返回 true; 否则返回 false。
参数
X
是搜索的目标字符串。它可以是标量或向量。
str
是被搜索的目标字符串。它可以是标量或向量。
返回值
布尔类型标量或向量。
例子
endsWith('ABCDEF!', "F!");
// output
true
endsWith('ABCDEF!', "E!");
// output
false
FILE:references/doc_9747.md
# loess
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loess.html
**来源**: DolphinDB 官方文档
---
loess
语法
loess(X, Y, resampleRule, [closed='left'], [origin='start_day'],
[outputX=false], [bandwidth=0.3], [robustnessIter=4], [accuracy=1e-12])
详情
该函数根据
resampleRule
,
closed
,
origin
确定的采样规则,对
X
进行重采样操作。并根据重采样后的
X
,对
Y
按照局部回归算法进行插值(Loess
Interpolatiion)。
参数
X
严格递增的时间类型向量。
Y
同
X
等长的数值型向量。
resampleRule
一个字符串,可选值请参考
resample
的
rule
参数。
closed
和
origin
同
resample
的
closed
和
origin
参数。
outputX
布尔类型,表示是否输出
X
按照
resampleRule
,
closed
,
origin
重采样后的向量。默认值为 false。
bandwidth
数值型标量,取值范围为(0,1]。对特定点进行 loess 拟合时,计算最小二乘回归时会考虑最接近当前点的这部分源点。
robustnessIter
正整数,表示进行 loess 平滑处理时进行的鲁棒性迭代的次数。
accuracy
一个大于0的数。若鲁棒性迭代过程中的中值残差小于此参数设置值,则停止迭代。
返回值
若不指定
outputX
,仅返回一个对
Y
插值后的向量。若指定
outputX
=
true,则返回一个 tuple,其第一个元素为
X
重采样后的向量,第二个元素为对
Y
插值后的向量。
例子
loess([2016.02.14 00:00:00, 2016.02.15 00:00:00, 2016.02.16 00:00:00], [1.0, 2.0, 4.0], resampleRule=`60min, bandwidth=1)
// output
[1,1.0521,1.104,1.1558,1.2072,1.2582,1.3086,1.3584,1.4074,1.4556,
1.5027,1.5488,1.5937,1.6374,1.6795,1.7202,1.7593,1.7966,1.832,1.8655,
1.897,1.9263,1.9533,1.9779,2,2.0195,2.0366,2.0513,2.0637,2.0739,
2.082,2.0882,2.0926,2.0952,2.0962,2.0957,2.0938,2.0905,2.0861,2.0806,
2.0741,2.0667,2.0586,2.0498,2.0405,2.0308,2.0207,2.0104,2]
FILE:references/doc_9749.md
# deleteGroupMember
**URL**: https://docs.dolphindb.cn/zh/funcs/d/deleteGroupMember.html
**来源**: DolphinDB 官方文档
---
deleteGroupMember
语法
deleteGroupMember(userIds, groupIds)
详情
删除多个组中的同一个成员,或删除同一个组中的多个成员。
注:
该函数只能由管理员在控制节点、数据节点和计算节点运行。
参数
userIds
是表示用户名称的字符串标量或向量。
groupIds
是表示群组名称的字符串标量或向量。
userIds
和
groupIds
不能同时为向量。
返回值
无。
例子
deleteGroupMember(`AlexEdwards`ElizabethRoberts, `production);
FILE:references/doc_9750.md
# loadTable
**URL**: https://docs.dolphindb.cn/zh/funcs/l/loadTable.html
**来源**: DolphinDB 官方文档
---
loadTable
语法
loadTable(database, tableName, [partitions], [memoryMode=false])
详情
将数据加载到内存中。
参数
database
字符串,表示数据库的路径,也可以是数据库句柄。可以是分布式数据库或本地磁盘数据库。
tableName
字符串,表示表的名称,它需要使用反引号(`)或双引号。
partitions
标量或向量,表示要加载的分区。注意,只有本地磁盘数据库支持该参数,分布式数据库不支持该参数。
memoryMode
布尔值,表示是否把数据加载到内存。如果
memoryMode
=false,表示只加载元数据到内存;如果
memoryMode
=true,
表示将实际数据加载到内存。注意,只有本地磁盘数据库支持该参数,分布式数据库不支持该参数。对于分布式数据库,只将元数据加载到内存中。
返回值
对于分布式数据库,返回包含元数据的表对象。
对于本地磁盘数据库,如果
memoryMode
=false,返回包含元数据的表对象;如果
memoryMode
=true,返回包含实际数据的内存分区表。
例子
例1. 分布式数据库
n=1000000
ID=rand(100, n)
dates=2017.08.07..2017.08.11
date=rand(dates, n)
x=rand(10.0, n)
t1=table(ID, date, x);
dbDate = database(, VALUE, 2017.08.07..2017.08.11)
dbID=database(, RANGE, 0 50 100);
db = database("dfs://compoDB", COMPO, [dbDate, dbID]);
pt = db.createPartitionedTable(t1, `pt, `date`ID).append!(t1)
t2=table(0..100 as ID,take(2017.08.07..2017.08.11,101) as date)
dt = db.createTable(t2, `dt).append!(t2)
加载维度表:
tmp = loadTable("dfs://compoDB", `dt)
select count(*) from tmp
count
101
加载分区表:
tmp = loadTable("dfs://compoDB", `pt)
select count(*) from tmp
count
1000000
对于分布式数据库,
loadTable
函数不支持加载指定分区的数据。如果需要将某些分区的数据加载到内存中,可以在 SQL 语句中指定过滤条件。
tmp = loadTable("dfs://compoDB", `pt)
select * from tmp where date=2017.08.07
对于内存的分区表,我们可以执行一些函数,如
update!
,
drop!
,
rename!
,
sortBy!
。
FILE:references/doc_9752.md
# ffill
**URL**: https://docs.dolphindb.cn/zh/funcs/f/ffill.html
**来源**: DolphinDB 官方文档
---
ffill
语法
ffill(obj, [limit])
详情
如果
obj
是向量,则使用空值前最近的非空元素来填充空值。
如果
obj
是数组向量:
对于每一行,如果该行为空,则用该行前最近的非空行填充。
对于某一列中的空值,使用该列中空值前最近的非空元素填充。
如果
obj
是矩阵或表,则对每一列按照上述规则进行填充。
注意:
该函数会生成新的对象,不会改变输入的对象;而函数
ffill!
会改变输入的对象。
参数
obj
可以是向量、数组向量、矩阵或表。
limit
是正整数,表示最大可填充的连续空值个数。
obj
为数组向量时不支持该参数。
返回值
返回填充空缺值后的对象,其类型与形式同
obj
。
例子
例1.
x=1 2 3 NULL NULL NULL 4 5 6
x.ffill();
返回:[1,2,3,3,3,3,4,5,6]
x;
返回:[1,2,3,,,,4,5,6]。由此可见,x 中的空值没有被填充。
例2. 指定参数
limit
x=1 2 3 NULL NULL NULL 4 5 6
x.ffill(1);
返回:[1,2,3,3,,,4,5,6]
x.ffill(2);
x;
返回:[1,2,3,3,3,,4,5,6]
例3. 指定
obj
为一个表.
date=[2012.06.12,2012.06.12,2012.06.13,2012.06.14,2012.06.15]
sym=["IBM","MSFT","IBM","MSFT","MSFT"]
price=[40.56,26.56,,,50.76]
qty=[2200,4500,,5600,]
timestamp=[09:34:07,09:35:26,09:36:42,09:36:51,09:36:59]
t=table(date,timestamp,sym,price,qty);
t;
得到:
date
timestamp
sym
price
qty
2012.06.12
09:34:07
IBM
40.56
2200
2012.06.12
09:35:26
MSFT
26.56
4500
2012.06.13
09:36:42
IBM
2012.06.14
09:36:51
MSFT
5600
2012.06.15
09:36:59
MSFT
50.76
t.ffill();
得到:
date
timestamp
sym
price
qty
2012.06.12
09:34:07
IBM
40.56
2200
2012.06.12
09:35:26
MSFT
26.56
4500
2012.06.13
09:36:42
IBM
26.56
4500
2012.06.14
09:36:51
MSFT
26.56
5600
2012.06.15
09:36:59
MSFT
50.76
5600
select date, timestamp, sym, price.ffill() as price, qty.ffill() as qty from t context by sym;
得到:
date
timestamp
sym
price
qty
2012.06.12
09:34:07
IBM
40.56
2200
2012.06.13
09:36:42
IBM
40.56
2200
2012.06.12
09:35:26
MSFT
26.56
4500
2012.06.14
09:36:51
MSFT
26.56
5600
2012.06.15
09:36:59
MSFT
50.76
5600
下例中,数组向量 x 的第四行为空,因此使用第三行 [6, 7, 8] 对其进行填充;第一列的第二个元素为空,故用该列中其之前的最近的非空元素 1 进行填充。
x = array(INT[], 0).append!([1 2 3, NULL 5, 6 7 8, NULL])
x
// output:[[1,2,3],[NULL,5],[6,7,8],[NULL]]
ffill(x)
// output:[[1,2,3],[1,5],[6,7,8],[6,7,8]]
FILE:references/doc_9759.md
# withdrawMCPPrompts
**URL**: https://docs.dolphindb.cn/zh/funcs/w/withdrawMCPPrompts.html
**来源**: DolphinDB 官方文档
---
withdrawMCPPrompts
语法
withdrawMCPPrompts([names])
详情
撤销已发布的 MCP prompt 模板。
参数
names
可选参数,STRING 类型标量或向量,表示 prompt 模板的名称。
返回值
一个 STRING 类型向量,表示撤销成功的 prompt 模板。
例子
withdrawMCPPrompts("stock_summary")
// output:["stock_summary"]
FILE:references/doc_9760.md
# rowNext
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowNext.html
**来源**: DolphinDB 官方文档
---
rowNext
语法
rowNext(X)
详情
逐行将
X
向左移动一个位置。
参数
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
。
返回值
返回一个数据类型和形式与
X
相同的对象。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL])
rowNext(m)
返回:
col1
col2
col3
1.5
4.9
4.8
2
5.9
a=array(INT[], 0, 10).append!([1 2 3, 4 5, 6 7 8]);
rowNext(a)
//output: [[2,3,00i],[5,00i],[7,8,00i]]
tp = [[1.3,2.5,2.3], [4.1,5.3,6.2]]
tp.setColumnarTuple!()
rowNext(tp)
//output: [[2.5,2.3,00F],[5.3,6.2,00F]]
FILE:references/doc_9765.md
# getTabletsMeta
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getTabletsMeta.html
**来源**: DolphinDB 官方文档
---
getTabletsMeta
语法
getTabletsMeta([chunkPath], [tableName], [diskUsage=false],
[top=1024])
详情
查询当前节点上指定数据表 chunk 的元数据信息。若结合
pnodeRun
函数使用,可返回所有节点上指定数据表的元数据信息。
注:
该函数不会返回记录条数为 0 的 chunk。如需查看,可使用
getClusterChunksStatus
。
参数
chunkPath
是一个或多个 chunk 的 DFS 路径,支持使用通配符“*” ,“?”以及“ %”。“*”
表示匹配任意数量的任意字符,“?”表示匹配单个字符,“%”表示匹配 0,1 或多个字符。
tableName
是字符串,表示数据表名。
diskUsage
是一个 Boolean 值,表示结果是否输出磁盘占用。
top
是一个正整数,表示结果中返回的 chunk 的个数上限。默认值为1024。若不设上限,需将
top
参数设为-1。
返回值
返回一个表,包含以下列:
chunkId:chunk的唯一标识
path:分区的物理路径
dfsPath:分区DFS路径
tableName:表名
version:版本号
rowNum:分区的记录条数
createCids:update/delete表时创建的版本号
latestPhysicalDir:最新版本号(cid)对应的存储数据的临时物理路径
diskUsage:分区占用的磁盘空间,单位为字节。
例子
if(existsDatabase("dfs://testDB")){
dropDatabase("dfs://testDB")
}
db=database("dfs://testDB", VALUE, 1..10)
n=1000000
t=table(rand(1..10, n) as id, rand(100.0, n) as x)
db.createPartitionedTable(t, `pt1, `id).append!(t)
n=2000000
t=table(rand(1..10, n) as id, rand(100.0, n) as x, rand(100, n) as y)
db.createPartitionedTable(t, `pt2, `id).append!(t)
getTabletsMeta("/testDB/%", `pt1, true);
chunkId
path
dfsPath
tableName
version
rowNum
createCids
latestPhysicalDir
diskUsage
dbfd1767-f9ca-689e-4d5e-643b8506e82d
C:\Users\Downl...
/testDB/10/8
pt1
2
100155
[2059]
pt1_2_2059
696295
d221b457-fa7b-5990-4caa-13c99f56f716
C:\Users\Downl...
/testDB/9/8
pt1
2
99703
[2059]
pt1_2_2059
693026
92904d3b-0147-9bb8-4a28-f99525b250e7
C:\Users\Downl...
/testDB/8/8
pt1
2
99791
[2059]
pt1_2_2059
693848
7478c15a-0629-c8ab-47ee-a1d12c3c1cd6
C:\Users\Downl...
/testDB/1/8
pt1
2
100215
[2059]
pt1_2_2059
696932
8bc48c11-86ca-97ac-4ee4-8f829de92cc8
C:\Users\Downl...
/testDB/5/8
pt1
2
100156
[2059]
pt1_2_2059
696584
6b3a0a09-bc64-3bab-4535-344b7316d244
C:\Users\Downl...
/testDB/2/8
pt1
2
100121
[2059]
pt1_2_2059
696303
a7452c44-5d2b-6f82-4150-7bc48e941d64
C:\Users\Downl...
/testDB/4/8
pt1
2
99858
[2059]
pt1_2_2059
696572
a1a375cc-b6c0-29b2-485a-330af7447564
C:\Users\Downl...
/testDB/6/8
pt1
2
100280
[2059]
pt1_2_2059
697596
b04b4c04-6d43-0d8d-4000-6ae88e349eda
C:\Users\Downl...
/testDB/3/8
pt1
2
99858
[2059]
pt1_2_2059
694400
b20df3a7-678b-1cbe-400d-d8e566706682
C:\Users\Downl...
/testDB/7/8
pt1
2
99865
[2059]
pt1_2_2059
6942755
FILE:references/doc_9768.md
# rebalanceChunksWithinDataNode
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rebalanceChunksWithinDataNode.html
**来源**: DolphinDB 官方文档
---
rebalanceChunksWithinDataNode
语法
rebalanceChunksWithinDataNode(nodeAlias, [exec=false], [updatedBeforeDays =
7.0])
详情
一个节点内部增加磁盘卷后,需要调整现有磁盘卷上的数据量,使各个磁盘卷上的数据量达到平衡。该函数用于平衡一个数据节点内各磁盘卷间的数据,返回一个表,显示各磁盘卷间数据平衡计划。
若
exec
为 true,则进行数据平衡;若
exec
为
false,则不进行数据平衡。它只能在集群环境下由管理员在控制节点上执行。
调用该函数进行数据平衡后,可以在控制节点上执行
getRecoveryTaskStatus
查看任务执行的状态。
注:
自 2.00.12 版本起,rebalanceChunksWithinDataNode 支持单节点模式。
调用该函数后,系统会打印 INFO
级别的日志,输出每个磁盘的原始使用率以及平衡后的使用率。日志内容的格式如下:
[rebalance] Change of disk usage rate () expect: 原本占有率 -> 搬运后占有率
[rebalance] Change of disk usage rate (1 / 磁盘数) 磁盘所在IP@磁盘fsid: 原本占有率 -> 搬运后占有率
[rebalance] Change of disk usage rate (2 / 磁盘数) 磁盘所在IP@磁盘fsid: 原本占有率 -> 搬运后占有率
...
参数
nodeAlias
字符串,表示数据节点的别名。
exec
布尔值,表示是否在节点内进行数据平衡。默认值为 false,输出数据平衡的执行计划,并不执行数据迁移。若设置为
true,则系统会执行数据迁移。
updatedBeforeDays
非负浮点数,用于确定可以进行平衡的数据的时间范围,默认值是7,单位是天。表示数据块(chunk)的最后一次写入或更新(修改)时间发生在7天前时,才会进行平衡。
返回值
返回一个表,显示各磁盘卷间数据平衡计划,包含以下列:
列名
含义
chunkId
chunk 的唯一标识
srcVolume
源磁盘卷
destVolume
目标磁盘卷
例子
rebalanceChunksWithinDataNode("node1")
ChunkId
srcVolume
destVolume
82c6eb6c-36ee-b1b6-4a86-ca24d9faaa25
/hdd/hdd1/volumes
/hdd/hdd2/volumes
FILE:references/doc_9774.md
# dynamicGroupCumsum
**URL**: https://docs.dolphindb.cn/zh/funcs/d/dynamicGroupCumsum.html
**来源**: DolphinDB 官方文档
---
dynamicGroupCumsum
语法
dynamicGroupCumsum(cumValue, prevCumValue, membership, prevMembership,
groupCount)
详情
通常一个事件的类别和属性是固定的。但在某些场景下,事件的类别会动态发生变化。如:在实时处理逐笔数据时,进行大小单的统计以对资金流进行分析。用户期望根据某个订单(事件的属性)的累计交易量来判断该订单是大单还是小单(事件的类别)。随着实时数据不断流入,交易量的不断增加,该订单的类别可能从一个小单变成大单。
dynamicGroupCumsum
即可应用在这类场景下,用于统计在一个时间序列下,某个事件指标在不同类别下的累计值。
具体算法如下:
若
membership
=
prevMembership
,统计量不变。
若
membership
≠
prevMembership
,
membership
对应组的统计量加
cumValue
,
prevMembership
对应的组统计量减 prevCumValue。
若
prevMembership
为空值(对应序列的第一条记录),
membership
对应组的统计量加
cumValue
,
prevMembership
无对应组,无需处理。
参数
cumValue
数值型向量,用于记录事件在每个时间戳上对应的累计值。
prevCumValue
数值型向量,其元素可以为空值(对应序列的第一条记录)。用于记录事件在前一个时间戳上对应的累计值。
membership
整型向量,其元素必须是 [0, groupCount) 范围内的整数。用于记录事件在每个时间戳上对应的标签。
prevMembership
整型向量,其元素可以为空值(对应序列的第一条记录)。用于记录事件在前一个时间戳上对应的标签。
groupCount
[2, 8] 之间的一个整数。表示函数返回值(元组)的长度,即需要统计的标签数。
返回值
返回一个长度为
groupCount
的元组,其每个元素是一个与
membership
等长的向量,依次记录了某指标(
cumValue
对应的列)在各标签下的累积和。
注:
元组的下标与标签号一一对应,即标签为 0 的统计结果将输出至元组下标为 0 的向量。
例子
数据预处理:
// 打标签函数
def tag_func(v){
return iif(v <= 5, 0, iif(v <= 10 and v > 5, 1, 2))
// output
}
// 原始数据表
time = take(2022.01.01T09:00:00.000 + 1..3, 6)
sym=`st0`st0`st0`st1`st1`st1
orderNo = `10001`10002`10001`10002`10003`10002
volume = 2 4 6 3 2 9
t = table(sym, time, orderNo, volume)
// 计算累计和并根据阈值打标签
t1 = select *, cumsum(volume) as sumVolume from t context by sym, orderNo
t2 = lj(t, t1,`sym`time`orderNo)
t3 = select sym, time, orderNo, volume, sumVolume, tag_func(sumVolume) as groupId from t2
对于历史数据,可以使用 SQL 语句计算不同组的累计成交量:
t4 = select sym, time, orderNo, prev(groupId) as prevGroupId, groupId, prev(sumVolume) as prevSumVolume, sumVolume from t3 context by sym,orderNo
t5 = lj(t3, t4,`sym`time`orderNo)
re = select sym, time, orderNo, dynamicGroupCumsum(sumVolume, prevSumVolume, groupId, prevGroupId, 3) as `groupId0`groupId1`groupId2 from t5 context by sym
re
sym
time
orderNo
groupId0
groupId1
groupId2
st0
2022.01.01T09:00:00.001
10001
2
0
0
st0
2022.01.01T09:00:00.002
10002
6
0
0
st0
2022.01.01T09:00:00.003
10001
4
8
0
st1
2022.01.01T09:00:00.001
10002
3
0
0
st1
2022.01.01T09:00:00.002
10003
5
0
0
st1
2022.01.01T09:00:00.003
10002
2
0
12
对于实时数据,可以使用流数据引擎计算不同组的累计成交量:
result = table(1000:0, `sym`time`orderNo`groupId0`groupId1`groupId2, [SYMBOL, TIME, SYMBOL,INT,INT,INT])
factor0 = [ <time>, <prev(groupId) as prevGroupId>, <groupId>, <prev(sumVolume) as prevSumVolume>, <sumVolume>]
factor1 = [<time>, <orderNo>, <dynamicGroupCumsum(sumVolume, prevSumVolume, groupId, prevGroupId, 3)>]
dm1 = table(1000:0, `sym`time`orderNo`volume`sumVolume`groupId, [SYMBOL, TIME, SYMBOL,INT, INT,INT])
dm2 = table(1000:0, `sym`orderNo`time`prevGroupId`groupId`prevSumVolume`sumVolume, [SYMBOL, SYMBOL, TIME, INT, INT, INT, INT])
res1 = createReactiveStateEngine(name="reactive_csum", metrics =factor1, dummyTable=dm2, outputTable=result, keyColumn=`sym, keepOrder=true)
res0 = createReactiveStateEngine(name="reactive_prev", metrics =factor0, dummyTable=dm1, outputTable=res1, keyColumn=`sym`orderNo, keepOrder=true)
res0.append!(t3)
select * from result
sym
time
orderNo
groupId0
groupId1
groupId2
st0
2022.01.01T09:00:00.001
10001
2
0
0
st0
2022.01.01T09:00:00.002
10002
6
0
0
st0
2022.01.01T09:00:00.003
10001
4
8
0
st1
2022.01.01T09:00:00.001
10002
3
0
0
st1
2022.01.01T09:00:00.002
10003
5
0
0
st1
2022.01.01T09:00:00.003
10002
2
0
12
dropStreamEngine("reactive_csum")
dropStreamEngine("reactive_prev")
相关函数:
dynamicGroupCumcount
FILE:references/doc_9784.md
# listAllMarkets
**URL**: https://docs.dolphindb.cn/zh/funcs/l/listAllMarkets.html
**来源**: DolphinDB 官方文档
---
listAllMarkets
语法
listAllMarkets()
详情
获取当前节点所有的交易日历。
返回值
一个包含节点上所有交易日历标识的向量。
例子
listAllMarkets()
// ["XTSE","XCSE","XLIM","ADDA","XSTO","XIST","AIXK","SSE","XMIL","XFRA","INE","XMEX","XBUD","XICE","XDUB","SHFE","CMES","XOSL","DCE","CCFX","CFFEX","XIDX","BVMF","XBOG","XKAR","XSAU","XBUE","XTKS","XBSE","XMOS"...]
相关函数:
addMarketHoliday
、
deleteMarketHoliday
FILE:references/doc_9791.md
# percentile
**URL**: https://docs.dolphindb.cn/zh/funcs/p/percentile.html
**来源**: DolphinDB 官方文档
---
percentile
语法
percentile(X, percent, [interpolation='linear'])
详情
若
X
是一个向量,计算其指定的百分位数。与所有其它聚合函数一致,计算时忽略 NULL 值。
若
X
为矩阵,计算每列的指定的百分位数,返回一个向量。
若
X
为表,计算每列的指定的百分位数,返回一个表。
参数
X
是一个向量、矩阵或表。
percent
是 0 到 100 之间的整数或小数。
interpolation
是一个字符串,表示当选中的分位点位于在
X
的第 i 和第 i+1
个元素之间时,采用的插值方法。它具有以下取值:
'linear':
, 其中
'lower':
'higher':
'nearest':
和
之中最接近分位点的数据
'midpoint':
如果没有指定
interpolation
,默认采用 'linear'。
返回值
DOUBLE 类型标量/向量,或一个包含 DOUBLE 类型结果的表。
例子
a=[6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36];
percentile(a,50);
// output
40
percentile(a,54);
// output
40.4
percentile(a,25,"lower");
// output
15
percentile(a,75,"higher");
// output
43
percentile(a,5,"midpoint");
// output
6.5
percentile(a,5,"nearest");
// output
6
m=matrix(1 2 5 3 4, 5 4 1 2 3);
m;
#0
#1
1
5
2
4
5
1
3
2
4
3
percentile(m, 75);
[4,4]
相关函数:
quantile
FILE:references/doc_9797.md
# bondYieldCurveBuilder
**URL**: https://docs.dolphindb.cn/zh/funcs/b/bondYieldCurveBuilder.html
**来源**: DolphinDB 官方文档
---
bondYieldCurveBuilder
语法
bondYieldCurveBuilder(referenceDate, currency, bonds,
terms, quotes, dayCountConvention, [compounding='Compounded'],
[frequency='Annual'], [curveName], [method='Bootstrap'],
[interpMethod='Linear'], [extrapMethod='Flat'])
详情
构建债券收益率曲线,可作为定价时使用的贴现曲线(即期收益率曲线)。
参数
referenceDate
DATE 类型标量,收益率曲线的参考日期。
currency
STRING 类型标量,表示曲线所定义的货币,可选值为:
"CNY":人民币
"USD":美元
"EUR":欧元
"GBP":英镑
"JPY":日元
"HKD":港币
bonds
INSTRUMENT 类型向量,表示用于曲线构建的样本债券,包含各债券的基本信息。不同类型的债券产品所需的关键字段各不相同,详见
债券产品字段要求
。
terms
DURATION 类型的严格递增向量,与
bonds
等长,表示样本券的剩余期限。
quotes
数值类型的向量,与
bonds
等长,表示每只债券在
referenceDate
当日的到期收益率(YTM)报价。
dayCountConvention
STRING 类型标量,表示计息日数规则,可选值为:
"Actual360": 实际/360
"Actual365": 实际/365
"ActualActualISDA":实际/实际,遵循 ISDA(International Swaps and Derivatives
Association,国际掉期及衍生工具协会)规则
"ActualActualISMA": 实际/实际,遵循 ISMA(International Securities Market
Association,国际证券市场协会)规则
compounding
可选参数,STRING 类型标量,表示利率复利方式。可选值为:
"Compounded":默认值,离散复利。
"Simple":简单复利。
"Continuous":连续复利。
frequency
可选参数,STRING
类型标量,表示曲线的频率,用于指定曲线的频率,不影响曲线构建,仅会记录在返回的曲线中,默认值为“Annual”。可选值为:
"Annual":默认值,每年付息一次
"NoFrequency":无计息频率
"Once":到期一次还本付息,仅用于贴现债和零息债
"Semiannual":每半年付息一次
"EveryFourthMonth":每四个月付息一次
"Quarterly":每季度付息一次
"BiMonthly":每两月付息一次
"Monthly":每月付息一次
"EveryFourthWeek":每四周付息一次
"BiWeekly":每两周付息一次
"Weekly":每周付息一次
"Daily":每日付息一次
"Other":其他计息频率
curveName
可选参数,STRING 类型标量,表示生成的曲线名称,默认为空。
method
可选参数,STRING 类型标量,表示曲线构建方法。 可选值为:
"Bootstrap":默认值,拨靴法。
"NS":Nelson-Siegel 模型,至少需要 4 个样本点输入用于曲线构建。
"NSS":Nelson-Siegel-Svensson 模型,至少需要 6 个样本点输入用于曲线构建。
interpMethod
可选参数,STRING 类型标量,表示内插方法。可选值为:
"Linear":默认值,线性插值。
"CubicSpline":三次样条插值。
"CubicHermiteSpline":三次埃尔米特样条插值。
extrapMethod
可选参数,STRING 类型标量,表示外插方法。可选值为:
"Flat":默认值,平插。
"Linear":线性插值。
返回值
MKTDATA 类型对象。
例子
基于2025年8月18日的国债市场数据构建收益率曲线。
bond1 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "DiscountBond",
"version": 0,
"instrumentId": "259916.IB",
"start": 2025.03.13,
"maturity": 2025.09.11,
"issuePrice": 99.2070,
"dayCountConvention": "ActualActualISDA"
}
bond2 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "240021.IB",
"start": 2024.10.25,
"maturity": 2025.10.25,
"issuePrice": 100,
"coupon": 0.0133,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA"
}
bond3 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "250001.IB",
"start": 2025.01.15,
"maturity": 2026.01.15,
"issuePrice": 100,
"coupon": 0.0116,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA"
}
bond4 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "250013.IB",
"start": 2025.07.25,
"maturity": 2026.07.25,
"issuePrice": 100,
"coupon": 0.0133,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA"
}
bond5 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "250012.IB",
"start": 2025.06.15,
"maturity": 2027.06.15,
"issuePrice": 100,
"coupon": 0.0138,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA"
}
bond6 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "250010.IB",
"start": 2025.05.25,
"maturity": 2028.05.25,
"issuePrice": 100,
"coupon": 0.0146,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA"
}
bond7 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "250014.IB",
"start": 2025.07.25,
"maturity": 2030.07.25,
"issuePrice": 100,
"coupon": 0.0155,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA"
}
bond8 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "2500802.IB",
"start": 2025.05.25,
"maturity": 2032.05.25,
"issuePrice": 100,
"coupon": 0.0157,
"frequency": "Annual",
"dayCountConvention": "ActualActualISDA"
}
bond9 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "250011.IB",
"start": 2025.05.25,
"maturity": 2035.05.25,
"issuePrice": 100,
"coupon": 0.0167,
"frequency": "Semiannual",
"dayCountConvention": "ActualActualISDA"
}
bond10 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "2400102.IB",
"start": 2024.08.29,
"maturity": 2039.08.29,
"issuePrice": 100,
"coupon": 0.0225,
"frequency": "Semiannual",
"dayCountConvention": "ActualActualISDA"
}
bond11 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "2500004.IB",
"start": 2025.07.15,
"maturity": 2045.07.15,
"issuePrice": 100,
"coupon": 0.0192,
"frequency": "Semiannual",
"dayCountConvention": "ActualActualISDA"
}
bond12 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "2500005.IB",
"start": 2025.07.15,
"maturity": 2055.07.15,
"issuePrice": 100,
"coupon": 0.019,
"frequency": "Semiannual",
"dayCountConvention": "ActualActualISDA"
}
bond13 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "200007.IB",
"start": 2020.05.25,
"maturity": 2070.05.25,
"issuePrice": 100,
"coupon": 0.0373,
"frequency": "Semiannual",
"dayCountConvention": "ActualActualISDA"
}
bond14 = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "FixedRateBond",
"version": 0,
"instrumentId": "2400003.IB",
"start": 2024.06.15,
"maturity": 2074.06.15,
"issuePrice": 100,
"coupon": 0.0253,
"frequency": "Semiannual",
"dayCountConvention": "ActualActualISDA"
}
referenceDate = 2025.08.18
bondsTmp = [bond1, bond2, bond3, bond4, bond5, bond6, bond7, bond8, bond9,
bond10, bond11, bond12, bond13, bond14]
bonds = parseInstrument(bondsTmp)
本案例参考外汇交易中心标准期限
收盘收益率曲线历史数据下载_中国货币网
,样本券的剩余期限(term)和报价(quote)均为模拟数据。
terms = [1M, 3M, 6M, 1y, 2y, 3y, 5y, 7y, 10y, 15y, 20y, 30y, 40y, 50y]
quotes=[1.3000, 1.3700, 1.3898, 1.3865, 1.4296, 1.4466, 1.6348,
1.7557, 1.7875, 1.9660, 2.1300, 2.1100, 2.1556, 2.1750]/100
// method = "BoostStarp"
bootstrapCurve = bondYieldCurveBuilder(referenceDate, `CNY, bonds, terms, quotes, "ActualActualISDA", method='Bootstrap')
bootstrapCurveDict = extractMktData(bootstrapCurve)
print(bootstrapCurveDict)
// method = "NS"
nsCurve = bondYieldCurveBuilder(referenceDate, `CNY, bonds, terms, quotes, "ActualActualISDA", method='NS')
nsCurveDict = extractMktData(nsCurve)
print(nsCurveDict)
// method = "NSS"
nssCurve = bondYieldCurveBuilder(referenceDate, `CNY, bonds, terms, quotes, "ActualActualISDA", method='NSS')
nssCurveDict=extractMktData(nssCurve)
print(nssCurveDict)
实际应用中,应根据样本券到期日减去曲线参考日期计算剩余期限,并使用实际到期收益率(YTM)报价参与曲线构建,以符合 CFETS 债券收盘估值标准,
债券估值_债券收盘估值_债券动态估值_中国货币网
。
terms2 = array(DURATION)
for(bond in bondsTmp){
term = duration(string(bond["maturity"] - referenceDate)+"d")
terms2.append!(term)
}
quotes2 = [1.2799, 1.3440, 1.3450, 1.3849, 1.4200, 1.4450, 1.6295,
1.7350, 1.7860, 2.0493, 2.1304, 2.1140, 2.1558, 2.1728] / 100
// method = "BoostStarp"
bootstrapCurve2 = bondYieldCurveBuilder(referenceDate, `CNY, bonds, terms2, quotes2, "ActualActualISDA", method='Bootstrap')
bootstrapCurveDict2 = extractMktData(bootstrapCurve2)
print(bootstrapCurveDict2)
// method = "NS"
nsCurve2 = bondYieldCurveBuilder(referenceDate, `CNY, bonds, terms2, quotes2, "ActualActualISDA", method='NS')
nsCurveDict2 = extractMktData(nsCurve2)
print(nsCurveDict2)
// method = "NSS"
nssCurve2 = bondYieldCurveBuilder(referenceDate, `CNY, bonds, terms2, quotes2, "ActualActualISDA",method='NSS')
nssCurveDict2 =extractMktData(nssCurve2)
print(nssCurveDict2)
相关函数:
extractMktData
,
parseInstrument
债券产品字段要求
贴现债
字段名
类型
描述
是否必填
productType
STRING
固定填 "Cash"
是
assetType
STRING
固定填 "Bond"
是
bondType
STRING
固定填 "DiscountBond"
是
nominal
DOUBLE
名义金额,默认值 100
否
instrumentId
STRING
债券代码,如 "259926.IB"
否
start
DATE
起息日
是
maturity
DATE
到期日
是
dayCountConvention
STRING
日期计数惯例,可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
issuePrice
DOUBLE
发行价格
是
currency
STRING
货币,默认为 "CNY"
否
cashFlow
TABLE
债券现金流表
否
discountCurve
STRING
定价时参考的贴现曲线名称,如 "CNY_TRASURY_BOND"
否
spreadCurve
STRING
定价时参考的利差曲线名称
否
subType
STRING
债券子类型,中国债券可选值为:
"TREASURY_BOND":国债
"CENTRAL_BANK_BILL":央行票据
"CDB_BOND":政策性金融债(国开)
"EIBC_BOND":政策性金融债(进出口行)
"ADBC_BOND":政策性金融债(农发行)。
"MTN":中期票据
"CORP_BOND":企业债。
"UNSECURED_CORP_BOND":无担保企业债
"SHORT_FIN_BOND":短期融资券
"NCD":同业存单
"LOC_GOV_BOND":地方政府债
"COMM_BANK_FIN_BOND":商业银行普通金融债
"BANK_SUB_CAP_BOND":商业银行二级资本债
"ABS":资产支持证券
"PPN":非公开发行债
否
creditRating
STRING
信用等级类型,可选值为:"B", "BB", "BBB", "BBB+", "A-", "A", "A+", "AA-",
"AA", "AA+", "AAA-", "AAA", "AAA+"
否
零息债
字段名
类型
描述
是否必填
productType
STRING
固定填 "Cash"
是
assetType
STRING
固定填 "Bond"
是
bondType
STRING
固定填 "ZeroCouponBond"
是
nominal
DOUBLE
名义金额,默认值 100
否
instrumentId
STRING
债券代码,如 "250401.IB"
否
start
DATE
起息日
是
maturity
DATE
到期日
是
coupon
DOUBLE
票面利率,如 0.03 表示 3%
是
frequency
STRING
付息频率
否
dayCountConvention
STRING
日期计数惯例,可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
currency
STRING
货币,默认为 "CNY"
否
cashFlow
TABLE
债券现金流表
否
discountCurve
STRING
定价时参考的贴现曲线名称,如 "CNY_TRASURY_BOND"
否
spreadCurve
STRING
定价时参考的利差曲线名称
否
subType
STRING
债券子类型,中国债券可选值为:
"TREASURY_BOND":国债
"CENTRAL_BANK_BILL":央行票据
"CDB_BOND":政策性金融债(国开)
"EIBC_BOND":政策性金融债(进出口行)
"ADBC_BOND":政策性金融债(农发行)。
"MTN":中期票据
"CORP_BOND":企业债。
"UNSECURED_CORP_BOND":无担保企业债
"SHORT_FIN_BOND":短期融资券
"NCD":同业存单
"LOC_GOV_BOND":地方政府债
"COMM_BANK_FIN_BOND":商业银行普通金融债
"BANK_SUB_CAP_BOND":商业银行二级资本债
"ABS":资产支持证券
"PPN":非公开发行债
否
creditRating
STRING
信用等级类型,可选值为:"B", "BB", "BBB", "BBB+", "A-", "A", "A+", "AA-",
"AA", "AA+", "AAA-", "AAA", "AAA+"
否
固定利率债
字段名
类型
描述
是否必填
productType
STRING
固定填 "Cash"
是
assetType
STRING
固定填 "Bond"
是
bondType
STRING
固定填 "FixedRateBond"
是
nominal
DOUBLE
名义金额,默认值 100
否
instrumentId
STRING
债券代码,如 "250401.IB"
否
start
DATE
起息日
是
maturity
DATE
到期日
是
coupon
DOUBLE
票面利率,如0.03表示3%
是
frequency
STRING
付息频率
是
dayCountConvention
STRING
日期计数惯例,可选 "ActualActualISDA", "ActualActualISMA",
"Actual365", "Actual360"
是
currency
STRING
货币,默认为 "CNY"
否
cashFlow
TABLE
债券现金流表
否
discountCurve
STRING
定价时参考的贴现曲线名称,如 "CNY_TRASURY_BOND"
否
spreadCurve
STRING
定价时参考的利差曲线名称
否
subType
STRING
债券子类型,中国债券可选值为:
"TREASURY_BOND":国债
"CENTRAL_BANK_BILL":央行票据
"CDB_BOND":政策性金融债(国开)
"EIBC_BOND":政策性金融债(进出口行)
"ADBC_BOND":政策性金融债(农发行)。
"MTN":中期票据
"CORP_BOND":企业债。
"UNSECURED_CORP_BOND":无担保企业债
"SHORT_FIN_BOND":短期融资券
"NCD":同业存单
"LOC_GOV_BOND":地方政府债
"COMM_BANK_FIN_BOND":商业银行普通金融债
"BANK_SUB_CAP_BOND":商业银行二级资本债
"ABS":资产支持证券
"PPN":非公开发行债
否
creditRating
STRING
信用等级类型,可选值为:"B", "BB", "BBB", "BBB+", "A-", "A", "A+", "AA-",
"AA", "AA+", "AAA-", "AAA", "AAA+"
否
FILE:references/doc_9815.md
# sum4
**URL**: https://docs.dolphindb.cn/zh/funcs/s/sum4.html
**来源**: DolphinDB 官方文档
---
sum4
语法
sum4(X)
详情
若
X
为向量,返回
X
中所有元素的四次方和。
若
X
为矩阵,计算每列元素的四次方和,返回一个向量。
若
X
为表,计算每列元素的四次方和,返回一个表。
与所有其它聚合函数一致,计算时忽略 NULL 值。
即使
X
的数据类型是 INT 或 LONG,返回结果的数据类型总是 DOUBLE 类型。如果
X
中的所有元素为 NULL,返回的结果为
NULL。
参数
X
可以是标量、向量、矩阵或表。
返回值
返回标量、向量或表。
例子
sum4(1 2 3);
// output
98
sum4(1 NULL NULL);
// output
1
sum4(1.5 4.6 7.8);
// output
4154.3137
m=matrix(1 2 3, 4 5 6);
m;
#0
#1
1
4
2
5
3
6
sum4(m);
// output
[98,2177]
FILE:references/doc_9830.md
# 流式计算算子
**URL**: https://docs.dolphindb.cn/zh/stream/str_operator.html
**来源**: DolphinDB 官方文档
---
流式计算算子
流计算算子可以分为无状态计算和有状态计算。无状态计算是指对输入数据的流式计算不会涉及到历史数据或历史状态,只与当前最新需要处理的这条数据有关。有状态计算是指对输入数据的流式计算与其历史数据和历史状态有关,涉及到状态保存、增量计算优化、避免相同状态重复计算等问题。
DolphinDB 分别实现了无状态算子、有状态算子。本章将详细展开介绍它们。
FILE:references/doc_9832.md
# mul
**URL**: https://docs.dolphindb.cn/zh/funcs/m/mul.html
**来源**: DolphinDB 官方文档
---
mul
语法
mul(X, Y)
或
X*Y
详情
逐个元素地返回
X
和
Y
的乘积。
参数
X
和
Y
可以是标量、数据对、向量或矩阵。如果
X
和
Y
的其中一个是数据对、向量或矩阵,另一个必须是标量或具有相同长度或维度的数据对、向量或矩阵。
返回值
数据类型和形式取决于输入参数的类型和形式:
标量 × 标量:返回一个标量。
向量 × 标量/向量: 返回与输入向量等长的向量。
矩阵 × 标量/向量/矩阵:返回与输入矩阵同维度的矩阵。
例子
1:2*3;
// output:
3 : 6
1:2*3:4;
// output:
3 : 8
x=1 2 3;
x * 2;
// output: [2,4,6]
y=4 5 6;
x * y;
// output: [4,10,18]
m1=1..6$2:3;
m1;
#0
#1
#2
1
3
5
2
4
6
m1*2;
#0
#1
#2
2
6
10
4
8
12
m2=6..1$2:3;
m2;
#0
#1
#2
6
4
2
5
3
1
m1*m2;
#0
#1
#2
6
12
10
10
12
6
FILE:references/doc_9871.md
# quarterEnd
**URL**: https://docs.dolphindb.cn/zh/funcs/q/quarterEnd.html
**来源**: DolphinDB 官方文档
---
quarterEnd
语法
quarterEnd(X, [endingMonth=12], [offset],
[n=1])
详情
返回
X
所在季度的最后一天。每季度包含的月份由参数
endingMonth
决定。
如果指定了
offset
,表示从
offset
开始,结果每隔n个季度更新一次。注意,
offset
和
n
须同时指定,且只有当
n
>1时,
offset
才会生效。
参数
X
可以是 DATE, DATETIME, DATEHOUR, TIMESTAMP 或 NANOTIMESTAMP
类型的标量或向量。
endingMonth
是1到12之间的整数,表示一年的结束月份。默认值是12。
offset
是与
X
类型相同的标量,并且它必须小于等于
X
中的最小值。它是一个可选参数。如果没有指定,
offset
默认为
X
中的最小值。
n
是一个正整数。它是一个可选参数,默认值为1。
返回值
DATE 类型标量或向量。
例子
quarterEnd(2012.06.12);
// output
2012.06.30
quarterEnd(2012.06.13 10:10:10.008,5);
// output
2012.08.31
date=2016.01.12 2016.02.25 2016.05.12 2016.06.28 2016.07.10 2016.08.18 2016.09.02 2016.10.16 2016.11.26 2016.12.30
time = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12,09:38:13]
sym = take(`MSFT,10)
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29 52.38
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800 4500
t1 = table(date, time, sym, qty, price);
select avg(price),sum(qty) from t1 group by quarterEnd(date,12,2016.01.01,2)
quarterEnd_date
avg_price
sum_qty
2016.03.31
39.53
4100
2016.09.30
92.1
18800
2017.03.31
51.33
15800
相关函数:
quarterBegin
,
businessQuarterBegin
,
businessQuarterEnd
FILE:references/doc_9889.md
# rowProd
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowProd.html
**来源**: DolphinDB 官方文档
---
rowProd
语法
rowProd(args...)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行进行元素求乘积操作。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m=matrix([4.5 2.6 1.5, 1.5 4.8 5.9, 4.9 2.0 NULL])
rowProd(m);
// output
[33.075,24.96,8.85]
v1=1 0 2 -2 5
v2=-8 1 2 4 2
rowProd(v1, v2);
// output
[-8,0,4,-8,10]
t=table(`AAPL`MS`IBM`IBM`C as sym, 49.6 29.46 29.52 30.02 174.97 as price1, 175.23 50.76 50.32 51.29 26.23 as price2)
select * from t where rowOr(price1>50, price2>50);
sym
price
AAPL
8691.408
MS
1495.3896
IBM
1485.4464
IBM
1539.7258
C
4589.4631
相关函数:
prod
FILE:references/doc_9893.md
# getTransactionStatus
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getTransactionStatus.html
**来源**: DolphinDB 官方文档
---
getTransactionStatus
语法
getTransactionStatus()
详情
获取事务的状态,该函数只能在数据节点/计算节点执行。
参数
无
返回值
一个表,包含以下列:
tid :事务的 id。
startTime:事务开始的时间。
type:事务涉及到的操作类型,包括 APPEND, DROP, SQLUPDATE, SQLUPSERT, SQLDELETE, FILEOPERATE
和 UNKNOWN。
status:事务当前的状态,包括 BEGIN, COMMIT, COMPLETE, ROLLBACK。
partitionCount:事务涉及到的分区数量。
endTime:事务结束的时间。
elapsedTime:事务持续的时间。
例子
getTransactionStatus()
tid
startTime
type
status
partitionCount
endTime
elapsedTime
3135
2022.06.07 16:19:48.477
APPEND
BEGIN
4
584
3143
2022.06.07 16:11:27.489
APPEND
COMMIT
4
2022.06.07 16:11:33.100
484
FILE:references/doc_99.md
# tmstdp
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tmstdp.html
**来源**: DolphinDB 官方文档
---
tmstdp
语法
tmstdp(T, X, window)
参数说明和窗口计算规则请参考:
tmFunctions
详情
在给定长度(以时间
T
衡量)的滑动窗口内计算
X
的总体标准差。
返回值
DOUBLE 类型向量。
例子
T = 1 1 3 5 8 15 15 20
X = 5 2 4 1 2 8 9 10
m=table(T as t, X as x)
select *, tmstdp(t, x, 3) from m
t
x
tmstdp_t
1
5
0
1
2
1.5
3
4
1.2472
5
1
1.5
8
2
0
15
8
0
15
9
0.5
20
10
0
T = 2021.01.02 2021.01.02 2021.01.04 2021.01.05 2021.01.07 2021.01.08
X = NULL 4 NULL -1 2 4
m = table(T as t,X as x)
select *, tmstdp(t, x, 3d) from m
t
x
tmstdp_t
2021.01.02
2021.01.02
4
0
2021.01.04
0
2021.01.05
-1
0
2021.01.07
2
1.5
2021.01.08
4
1
select *, tmstdp(t, x, 1w) from m
t
x
tmstdp_t
2021.01.02
2021.01.02
4
0
2021.01.04
0
2021.01.05
-1
2.5
2021.01.07
2
2.0548
2021.01.08
4
2.0463
相关函数:
mstdp
,
stdp
FILE:references/doc_990.md
# getInstrumentInstrumentId
**URL**: https://docs.dolphindb.cn/zh/funcs/g/getinstrumentinstrumentid.html
**来源**: DolphinDB 官方文档
---
getInstrumentInstrumentId
语法
getInstrumentInstrumentId(instrument)
详情
根据输入的金融工具,获取该工具的 ID。
参数
instrument
INSTRUMENT 类型标量或向量,表示金融工具。
返回值
STRING 类型标量或向量。
例子
bond = {
"productType": "Cash",
"assetType": "Bond",
"bondType": "DiscountBond",
"version": 0,
"instrumentId": "259924.IB",
"start": 2025.04.17,
"maturity": 2025.07.17,
"issuePrice": 99.664,
"dayCountConvention": "ActualActualISDA"
}
instrument = parseInstrument(bond)
getInstrumentInstrumentId(instrument)
// output: 259924.IB
相关函数:
parseInstrument
、
getInstrumentField
、
getInstrumentKeys
FILE:references/doc_9914.md
# transpose
**URL**: https://docs.dolphindb.cn/zh/funcs/t/transpose.html
**来源**: DolphinDB 官方文档
---
transpose
语法
transpose(X)
别名:
flip(X)
详情
本函数用于转置输入数据
X
:
如果
X
是一个元组,
transpose
函数返回的是一个与
X
中每个向量长度相同的元组,返回结果中的第 n 个元素是由
X
中每个向量的第 n 个值组成的向量。
如果
X
是一个矩阵,
transpose
函数返回
X
的转置矩阵。
如果
X
是一个表,
transpose
函数把表
X
转换为一个有序字典(从 2.00.9 版本开始支持有序字典),表中的列名为 key,每列的值为 value。
如果
X
是一个字典,且 key 是 STRING 类型,
transpose
函数把字典
X
转换为一个表
当value 为标量或等长向量时,表的列名为字典的 key 值,每列的值为对应 value。
当 value 为字典时,表中第一列的列名为 ”key“,其值为
X
的 key 值;后续列的列名为
X
中第一个子字典的键,其值为各子字典中对应的值。若某个子字典中不包含某键,则表中对应值为空值。
注:
不支持将包含超过 32,767 个键的字典转换为表。
如果
X
是一个数组向量或列式元组,transpose 函数将
X
的行和列转置。
参数
X
是一个元组、矩阵、表或字典、数组向量或列式元组。
如果 X 是元组,则元组中的元素须为长度相等的向量。
如果
X
是数组向量或列式元组,则每行包含的元素个数必须相等。
例子
例1.
X
是一个元组。
x=(`A`B`C,1 2 3);
x.transpose();
// output:(("A",1),("B",2),("C",3))
例2.
X
是一个矩阵。
x=1..6 $ 3:2;
x;
#0
#1
1
4
2
5
3
6
transpose x;
#0
#1
#2
1
2
3
4
5
6
例3.
X
是一个表。
timestamp = [09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
sym = `C`MS`MS`MS`IBM`IBM`C`C`C
price= 49.6 29.46 29.52 30.02 174.97 175.23 50.76 50.32 51.29
qty = 2200 1900 2100 3200 6800 5400 1300 2500 8800
t = table(timestamp, sym, qty, price);
t;
timestamp
sym
qty
price
09:34:07
C
2200
49.6
09:36:42
MS
1900
29.46
09:36:51
MS
2100
29.52
09:36:59
MS
3200
30.02
09:32:47
IBM
6800
174.97
09:35:26
IBM
5400
175.23
09:34:16
C
1300
50.76
09:34:26
C
2500
50.32
09:38:12
C
8800
51.29
transpose(t);
/*
timestamp->[09:34:07,09:36:42,09:36:51,09:36:59,09:32:47,09:35:26,09:34:16,09:34:26,09:38:12]
sym->[C,MS,MS,MS,IBM,IBM,C,C,C]
qty->[2200,1900,2100,3200,6800,5400,1300,2500,8800]
price->[49.6,29.46,29.52,30.02,174.97,175.23,50.76,50.32,51.29]
*/
例4.
X
是一个字典。
z=dict(`id`val,[`a`b`c,1 2 3]);
z;
/*
val->[1,2,3]
id->[a,b,c]
*/
transpose(z);
val
id
1
a
2
b
3
c
//当字典的 value 既包含标量又包含向量时,transpose 会重复标量的值以匹配向量的长度
z1=dict(`id`val,[`a,1 2 3]);
z1;
transpose(z1)
val
id
1
a
2
a
3
a
例5.
X
是一个嵌套字典。
d = {'tag1':{'val1':2,'val2':6},'tag2':{'val2':1, 'val3':3}}
d
/*
tag1->
val1->2
val2->6
tag2->
val2->1
val3->3
*/
transpose(d)
key
val1
val2
tag1
2
6
tag2
1
从结果可以看出,转置后的表的列包括 "key" 和第一个子字典的键(val1,val2),“key” 列的值对应字典
d
的键,val1
和 val2 列的值对应子字典中的相应值。由于 tag2 对应的子字典不包含键 val1,故表中对应的值为空值,且键 val3 对应的值会被丢弃。
FILE:references/doc_9919.md
# removeNode
**URL**: https://docs.dolphindb.cn/zh/funcs/r/removenode.html
**来源**: DolphinDB 官方文档
---
removeNode
语法
removeNode(alias, [force=false])
详情
删除集群中名为
alias
的计算节点。仅限 admin 用户调用。
此函数仅适用于 Linux 版本的 server。
参数
alias
STRING 类型的标量或向量,代表需要删除的计算节点的别名。
force
BOOL 类型的标量,表示是否强制删除节点:
当值为 false(默认值)时 ,表示不强制删除,即仅当节点处于关闭状态时才会删除。
当值为 true 时,表示强制删除,如果节点尚未关闭,则集群将会先关闭目标节点,然后再删除。此操作可能导致该节点正在进行的计算任务终止。
例子
删除别名为 "cnode1" 的计算节点,删除前需要手动关闭该节点。
removeNode(alias="cnode1")
强制删除别名为 "cnode2", "cnode3" 的计算节点。
removeNode(alias=`cnode2`cnode3, force=true)
FILE:references/doc_9939.md
# ma
**URL**: https://docs.dolphindb.cn/zh/funcs/m/ma.html
**来源**: DolphinDB 官方文档
---
ma
语法
ma(X, window, maType)
TA-lib 系列函数其他通用参数说明和窗口计算规则请参考:
TA-lib 系列
详情
在给定长度(以元素个数衡量)的滑动窗口内,计算
X
的移动平均,计算公式由
maType
决定。
参数
maType
计算平均线的方法。是一个0-8范围内的整数。各个整数分别表示:0=
sma
, 1=
ema
, 2=
wma
, 3=
dema
, 4=
tema
, 5=
trima
, 6=
kama
, 8=
t3
。注意:暂不支持 7 (mama)。
返回值
DOUBLE 类型向量。
FILE:references/doc_995.md
# rowCorr
**URL**: https://docs.dolphindb.cn/zh/funcs/r/rowCorr.html
**来源**: DolphinDB 官方文档
---
rowCorr
语法
rowCorr(X, Y)
row 系列函数通用参数说明和计算规则请参考:
rowFunctions
详情
逐行计算
X
和
Y
之间的相关性。
返回值
返回一个长度与输入参数行数相同的向量。
例子
m1=matrix(2 -1 4, 8 3 2, 9 0 1)
m2=matrix(8 11 10, 8 17 4, 14 6 4)
rowCorr(m1, m2)
// output
[0.61, 0.7559, 0.9449]
m3=matrix(8 NULL 10, 8 NULL 4, 14 NULL NULL)
rowCorr(m1, m3)
// output
[0.61, , 1]
a=array(DOUBLE[], 0, 10).append!([1 2 3, 4 NULL 5, 6 7 8, NULL 3 10]);
b=array(DOUBLE[], 0, 10).append!([[1.3,1.2, 4], [1.0,1.4, 2], [1.1, 1.4, 3],[1, 4, 7]]);
rowBeta(a, b)
// output
[0.535, 1 , 0.9105, 2.3333]
相关函数:
corr
FILE:references/doc_9957.md
# acosh
**URL**: https://docs.dolphindb.cn/zh/funcs/a/acosh.html
**来源**: DolphinDB 官方文档
---
acosh
语法
acosh(X)
详情
返回
X
的反双曲余弦。
参数
X
可以是标量、向量、矩阵或表。
返回值
返回结果的数据形式与输入保持一致:若输入为标量,返回标量;若输入为向量、矩阵或表,返回相同维度的结果。
例子
acosh(1 2 3);
// output: [0,1.316958,1.762747]
相关函数:
asin
,
acos
,
atan
,
sin
,
cos
,
tan
,
asinh
,
atanh
,
sinh
,
cosh
,
tanh
FILE:references/doc_9972.md
# convertExcelFormula
**URL**: https://docs.dolphindb.cn/zh/funcs/c/convertExcelFormula.html
**来源**: DolphinDB 官方文档
---
convertExcelFormula
语法
convertExcelFormula(formula, colStart, colEnd, rowStart,
rowEnd)
详情
将 Excel 表达式转换为对应的 DolphinDB 表达式。
该函数目前只支持包含四则运算,逻辑运算,聚合函数的转换。
该函数目前不支持对行和列同时操作的表达式的转换。聚合函数对单列进行计算时,如果处理的行数与实际的行数相同,则将该列进行聚合操作;如果处理行数与实际行数不同,则进行移动聚合操作。
参数
formula
是字符串标量或向量,表示 Excel 公式。
colStart
是字符串标量,表示数据在 Excel 中起始列。
colEnd
是字符串标量,表示数据在 Excel 中结束列。
rowStart
是整型标量,表示数据在 Excel 中起始行。
rowStart
值应大于0。
rowEnd
是整型标量,表示数据在 Excel 中起始行。
rowEnd
值应大于等于
rowStart
。
返回值
STRING 类型标量或向量。
例子
convertExcelFormula("A2+B2", "A", "Z", 2, 10);
// output
col0+col1
convertExcelFormula("SUM(A2:C2)", "A", "Z", 2, 10);
// output
rowSum(col0, col1, col2)
convertExcelFormula("SUM(A2)", "A", "Z", 2, 10);
// output
cumsum(col0)
convertExcelFormula("SUM(A2:A5)", "A", "Z", 2, 10);
// output
msum(col0, 4)
convertExcelFormula("SUM(A2:A10)", "A", "Z", 2, 10);
// output
sum(col0)
convertExcelFormula(["=SUM(A1:A10)","IF(A1>0,B1,0"], "A", "D", 1, 10)
// output
["sum(col0)","iif(col0>0,col1,0)"]
FILE:references/doc_9985.md
# tanimoto
**URL**: https://docs.dolphindb.cn/zh/funcs/t/tanimoto.html
**来源**: DolphinDB 官方文档
---
tanimoto
语法
tanimoto(X, Y)
详情
若
X
和
Y
是标量或向量,计算
X
和
Y
之间的谷本距离。
若
X
或
Y
是矩阵,计算每列元素之间的谷本距离,返回一个向量。 注意,若
X
或
Y
同时为索引矩阵或索引序列,会自动对齐标签,返回标签相同的行的计算结果,忽略标签不同的行。
与所有其它聚合函数一致,计算时忽略 NULL 值。
参数
X
和
Y
是长度相同的数值型标量/向量/矩阵。
返回值
DOUBLE 类型标量或向量。
例子
a=[10.5, 11.8, 9]
b=[11.3, 15.1, 8.9]
tanimoto(a,b)
// output
0.029706
s1=indexedSeries(2020.01.01..2020.01.03, 10.4 11.2 9)
s2=indexedSeries(2020.01.01 2020.01.03 2020.01.04, 23.5 31.2 26)
tanimoto(s1,s2)
// output
0.5585
m=matrix(23 56 47, 112 94 59)
m1=matrix(11 15 89, 52 41 63)
tanimoto(m,m1)
// output
[0.40490.3242]
m.rename!(2020.01.01..2020.01.03, `A`B)
m.setIndexedMatrix!()
m1.rename!(2020.01.01 2020.01.03 2020.01.04, `A`B)
m1.setIndexedMatrix!()
tanimoto(m,m1)
// output
[0.5494,0.3225]
相关函数:
rowTanimoto
FILE:references/doc_9996.md
# amortizingFixedRateBondDirtyPrice
**URL**: https://docs.dolphindb.cn/zh/funcs/a/amortizingfixedratebonddirtyprice.html
**来源**: DolphinDB 官方文档
---
amortizingFixedRateBondDirtyPrice
语法
amortizingFixedRateBondDirtyPrice(settlement, maturity, notionals, coupon,
yield, calendar, frequency, [basis=1], [convention="Following"])
详情
amortizingFixedRateBondDirtyPrice
函数计算摊还本金固息债券的含息价格(每 100 面值)。
摊还本金固息债券是一种特殊的固定利率债券。这类债券采用分期还本付息的方式,本金(面值)不是在到期时一次性偿还,而是在债券存续期内按票息支付时间表逐步归还。每期利息支付额会随着未偿还本金的减少而逐渐降低,因为利息计算基于当期的未偿还本金余额。
参数
注:
如果输入参数中,部分为标量,其余为向量时,则会将标量当作与向量长度相同,所有元素值等于该标量的向量。所有向量的长度必须一致。
settlement
DATE 类型标量或向量,表示债券结算日,即债券交易完成并支付金额的日期。
maturity
DATE 类型标量或向量,表示债券到期日,即债券有效期截止时的日期。
notionals
数值向量或数组向量,表示债券每期剩余的本金金额,与每个息票期的数量相同。
coupon
数值标量或向量,表示债券的年息票利率。
yield
数值标量或向量,表示债券的年收益率。
calendar
字符串标量或向量,表示使用的交易日历。具体使用说明请参阅
交易日历
。
frequency
用于指定债券的年付息频率。支持以下两种输入类型:
整型标量或向量:表示每年的付息次数,如 1 表示每年付息 1 次;
DURATION 标量或向量:表示间隔多长时间进行一次付息,如 3M,表示每 3 个月付息一次。
可选值
含义
1 / 1y
表示每年付息 1 次
2 / 6M
表示每年付息 2 次 / 每 6 个月付息 1 次
3 / 4M
表示每年付息 3 次 / 每 4 个月付息 1 次
4 / 3M
表示每年付息 4 次 / 每 3 个月付息 1 次
6 / 2M
表示每年付息 6 次 / 每 2 个月付息 1 次
12 / 1M
表示每年付息 12 次 / 每月付息 1 次
13 / 4w
表示每年付息 13 次 / 每 4 周付息 1 次
26 / 2w
表示每年付息 26 次 / 每 2 周付息 1 次
52 / 1w
表示每年付息 52 次 / 每周付息 1 次
365 / 1d
表示每年付息 365 次 / 每天付息 1 次
basis
可选参数。整型或者字符串标量或向量,表示要使用的日计数基准类型。可选值为:
basis
日计数基准
0 / ‘Thirty360US’
US (NASD) 30/360
1 / 'ActualActual' (默认值)
实际/实际
2 / 'Actual360'
实际/360
3 / 'Actual365'
实际/365
4 / 'Thirty360EU'
欧洲 30/360
convention
可选参数。字符串标量或向量,用于指定如何调整落在非工作日的现金流支付日期。可选值为:
'Following' (默认值):表示选择给定假日后的第一个工作日;
'ModifiedFollowing':表示选择给定假日后的第一个工作日。如果该工作日属于不同的月份,则选择假日前的第一个工作日;
'Preceding':表示选择给定假日前的第一个工作日;
'ModifiedPreceding':表示选择给定假日前的第一个工作日。如果该工作日属于不同的月份,则选择假日后的第一个工作日;
'Unadjusted':表示不作调整;
'HalfMonthModifiedFollowing':表示选择给定假日后的第一个工作日。如果该工作日跨越了月中(15日)或月末,则选择假日前的第一个工作日;
'Nearest':表示选择离给定假日最近的工作日。如果前后工作日距离相同,则默认选择后一个工作日。
返回值
DOUBLE 类型标量。
例子
假设购买日期为 2018 年 1 月 25 日,到期日期为 2022 年 1 月 25 日,债券本金为 100,年息票利率为 3%,年收益率为
2.55%,付息频率为每年一次,且在第 3 个付息期偿还本金 50。债券采用 US (NASD) 30/360
日计数基准,并使用上海证券交易所(XSHG)交易日历进行计算。
settlement = 2018.01.25
maturity = 2022.01.25
notionals = [100,100,100,50]
coupon = 0.03
yield = 0.0255
calendar = `XSHG
frequency = 1
basis = 0
res = amortizingFixedRateBondDirtyPrice(settlement, maturity, notionals, coupon, yield, calendar, frequency, basis)
res;
// 101.487354765248
FILE:references/whitepapers/backtest.md
# DolphinDB 白皮书 中高频策略回测

## 内容
前言. .iii
第 1 章. 中高频回测方案概述. .4
第 2 章. 数据回放与订阅 .6
2.1 单表回放. .7
2.2 多表回放. 9
2.3 回放与订阅处理示例 11
第 3 章. 模拟撮合引擎. 13
3.1 模拟撮合引擎功能介绍 13
3.2 模拟撮合引擎使用示例 15
3.3 开发算法交易策略 17
第 4 章. 回测引擎. 21
4.1 中高频回测引擎功能介绍 21
4.2 编写自定义策略. 22
4.3 回测引擎配置参数. .23
4.4 回测引擎使用注意事项. 25
4.5 使用示例 .25
第 5 章. DolphinScript 编写回测策略 28
5.1 动态网格交易策略回测 .28
5.2 科创版做市策略回测示例. 33
5.3 股票中高频 CTA 策略回测 36
5.4 期货分钟频 CTA 策略回测 37
5.5 银行间债券双边跟随最优价做市策略 .39
第 6 章. Python Parser 编写回测策略. 42
6.1 Python Parser 脚本改写策略回测 42
6.2 Python Parser 和 DolphinScript 的性能对比 43
第 7 章. C++ 编写回测策略. 44
7.1 C++ 策略实现 .45
7.2 C++和 DolphinScript 的性能对比 .48
第 8 章. 总结和展望. 50
第 9 章. 附录 51
## 前言
回测是量化交易投研的一个重要环节。量化策略上线之前,必须通过回测评估策略在历史数据上的表现。中高频策略回测相比于低频策略回测,存在两个新的挑战。首先,数据量增加了几个数量级,无论数据查询或者计算都对性能有更加苛刻的要求。其次,在中高频策略回测中,并不能简单的假设每个订单以当前价格或日终价格全部成交,需要一个模拟撮合引擎来模拟实际的交易过程,例如考虑订单能否成交、成交价格、成交量以及市场冲击等因素。DolphinDB 基于其高性能的分布式存储和计算架构,实现了行情回放、模拟撮合引擎和事件型中高频回测引擎三大核心组件,支持通过 DolphinScript、Python 或 C++语言完成中高频策略的研发和测试,提供了一个性能优异且易扩展的中高频量化交易策略回测解决方案。 目前,DolphinDB 已实现对沪深交易所所有股票标的的多种策略回测支持,包括逐笔+快照、逐笔(逐笔合成快照触发策略)、快照和快照+成交、分钟以及日频行情策略回测。同时,还支持期货和期权的快照、分钟和日频行情,以及银行间现券和融资融券等策略的回测。
## 第 1 章. 中高频回测方案概述
一个量化中高频策略在投入实盘交易之前,都需要使用市场的历史数据来进行回测,以评估交易策略的有效性。一个量化交易回测平台的基本架构如下图所示:

图 1-1 策略回测基本架构
中高频量化交易策略回测平台的实现主要包括三个重要环节:
- 行情数据回放
一个量化策略在用于实际交易时,处理实时数据的程序通常为事件驱动。为了实现使用同一套策略逻辑进行回测和实盘交易,量化策略回测平台一般需要分批获取历史行情数据,并严格按时间排序后注入回测引擎。沪深交易所的中高频行情数据通常包括逐笔委托、逐笔成交、快照等多种类型的数据,每日的数据量在50G左右。 基于3秒快照行情订单撮合时,需要将快照行情数据严格按照时间先后顺序注入引擎;基于逐笔行情对策略生成的订单撮合时,需要同时注入逐笔委托单和逐笔成交单两个数据源,并且严格按照时间顺序和委托单序号先后顺序注入数据,才能准确模拟实际的交易过程。
·委托订单模拟撮合
在中高频策略或者中高频算法交易策略中,我们常常会遇到这样的情况:一些在回测中表现良好的策略或者算法交易策略,一旦应用于实际交易,效果就不如预期。其中一个非常重要的原因是回测和真实交易时的订单撮合情况不同。为了确保策略的委托订单撮合时尽可能模拟真实交易时的订单撮合情况,我们需要在中高频回测过程中引入模拟撮合系统。
·策略开发与策略回测绩效评估
在设计中高频交易策略时,通常会采用一些指标、模型或者机器学习方法来辅助判断市场的趋势,这些指标计算和模型需要丰富的函数库。策略的制定通常需要针对不同的事件,如新行情的出现、订单的成交等,因此开发策略时需要利用多样化的事件函数来应对这些情况。回测系统还应提供包括交易记录、持仓情况、收益信息等在内的全面的回测结果,以便用户深入分析策略的回测表现。 DolphinDB 提供了完整的解决方案,涵盖以下 3 个环节:
- 回放功能:支持将一个或多个不同结构的分布式表中的数据严格按照时间或者按指定多列排序顺序回放到流表中,模拟实时行情数据。
·模拟撮合引擎插件:支持沪深交易所 Level-2 逐笔行情和快照行情,实现了与交易所一致的“价格优先,时间优先”高精度撮合、支持基于多种行情数据的撮合模式、并提供丰富的撮合配置,模拟真实的实盘交易环境。
·回测插件:用户可以在其中自定义指标,支持基于逐笔、快照、分钟和日频行情进行策略回测,获取回测的收益、持仓、交易明细等信息。其中基于逐笔和快照行情进行高精度策略回测,用户可以实现仿真和回测一体化的策略验证。
这 3 个模块化解决方案涵盖了中高频策略回测平台所需的所有环节,整合在一起就构成了 DolphinDB 一站式的中高频策略回测解决方案。这些解决方案与外部解决方案兼容性良好。如果用户已经实现了回测平台中某个环节,DolphinDB 提供的解决方案也可以与其融合成一个完整的回测方案。例如:
1. 用户已实现了基于其他语言的量化交易实盘和中高频回测一体化平台,可以将数据存储在 DolphinDB 中,采用 DolphinDB 的回放功能,将中高频行情数据回放到 C++、Java 和 Python 等客户端,快速对接已有量化交易回测系统。
2. 用户可以采用 DolphinDB 的回放功能和模拟撮合引擎,基于 Swordfish 编写回测系统。
3. 用户可以采用全套 DolphinDB 回测框架,编写 DolphinDB 脚本、Python 和 C++ 三种不同语言的策略代码。

图1-2 中高频策略回测方案的三种实现方式
不同方案的模块部署如图 1-2 所示,其中紫色部分是需要用户实现的模块,蓝色部分为 DolphinDB 内置模块。本文第 2-4 章,我们将分别介绍 DolphinDB 的数据回放、模拟撮合引擎和中高频回测引擎插件。在第 5 章中,我们将实现一些具体的策略,展示如何在实际场景中使用 DolphinDB 中高频策略回测解决方案。
## 第 2 章. 数据回放与订阅
用户的量化策略在生产(交易)环境中运行时,通常由事件驱动处理实时数据。为确保研发和生产使用同一套代码,通常在研发阶段需要将历史数据,严格按照事件发生的时间顺序进行回放,以此模拟交易环境进行回测。在回测时,对数据回放的要求包含以下几点:
・速度快:作为回测的一个环节,为了提高回测效率,能在最短时间内回放完所有数据。
- 支持多种数据:实时数据可能是一自单张表,也可能分布在多张表中,要求具备对多种数据源的支持能力。
- 支持多种部署方式:数据的发布和订阅可以部署在一台服务器上,也能部署在两台不同的服务器上。
- 灵活选择数据源:以类似 SQL 的方式,指定需要回放的数据,方便调试和测试。
针对以上要求,DolphinDB 以流表为中心,建立了一套包含发布、订阅、持久化功能的数据回放方案。上述提及的流表是 DolphinDB 中一种特殊的内存表,能支持同时读写,且只能添加记录,用户不能修改或删除记录。通过开启持久化功能可以将部分记录存盘,同时将其从内存中移除,以免流表内存占用过大。下图展示了方案的整体流程。

图2-1 发布-订阅-消费流程
以流表为中心,整个方案包含三个任务。
1. 发布任务从数据库中取数据,并插入流表顶部,通过多线程执行发布任务以满足对回放性能的要求。
2. 消费者订阅流表后,订阅任务从流表中取数据,分批发给消费者,可以同时满足多个客户端订阅的需求。
3. 为了节省流表对系统内存的占用,通过开启持久化任务,定期将流表尾部的数据迁移到文件中。
DolphinDB 通过以上方案能解决多种回放方式、多种数据源、多种消费方式的需求,并提供以下功能:
·控制回放速率:通过调整回放的速率可以测试不同压力下的系统表现。DolphinDB 支持四种回放速率:
。指定每秒内的回放记录数;
。按时间范围加速N倍回放;
。按两条数据的精确时间间隔加速N倍回放;
。全速回放。
·从指定位置订阅:回测时用户可以从第一条数据开始订阅、从上次消费的位置后面开始订阅或者订阅将来的数据。
·对同一个流表进行多个订阅:用户可以对同一个流表进行多个订阅,每次订阅验证不同的仿真交易,每个订阅可以配置不同的参数和开始位置。
·筛选订阅:用户可以在订阅时指定筛选条件,确保只收到符合条件的数据,这样用户可以在一次回放后,启动多个回测任务,每个任务只回测部分股票。
针对用户回放数据库表的数量不同,分为单表回放和多表回放。下面将分别介绍单表回放、多表回放以及在中高频回测中常见的对回放数据的处理方法。
### 2.1 单表回放
单表回放是将一张表的数据回放到流表中,客户端订阅流表并处理收到的数据。以下是在 Server 中回放和客户端订阅的整体流程和涉及到的关键函数。

图2-2 单表回放-订阅流程
回放的过程包括创建流表、回放和删除流表。创建流表时用户可以开启持久化以节省服务器内存。客户端订阅流表后,解析并处理数据,在收到结束标记时取消订阅。回放过程中用到的函数包含丰富的配置参数,能满足回测过程中的各种需求。
---
//构造和entrust字段一致的流表并开启持久化
colName = ["symbol", "symbolSource", "TradeTime", "sourceType", "orderType",
"price", "qty", "buyNo", "sellNo", "direction", "ChannelNo", "seqNum"]
colType = [SYMBOL, SYMBOL, TIMESTAMP, INT, INT, DOUBLE, LONG,
LONG, LONG, INT, INT, LONG]
enableTableShareAndPersistence(table=streamTable(10000000:0, colName, colType),
tableName=msgStreamName, cacheSize=10000000)
//构造数据源
ds1_chunk = replayDS(sqlObj=<select * from loadTable(dbName,"entrust") where
SecurityID in chunkCodes and date(TradeTime) between startDate:endDate>,
dateColumn=`TradeTime, timeColumn=`TradeTime)
//启动回放
replay(inputTables=ds1_chunk, outputTables=objByName(msgStreamName),
dateColumn=`time, timeColumn=`time)
---
上面的代码片段演示了单表数据回放的核心代码。完整代码请参考附录 2.1 单表回放脚本。用户可以通过将一个 SQL 表达式作为查询的元代码来描述需要回放的数据源,作为参数 sqlObj,传给 replayDS 函数描述需要回放的数据源。然后通过 replay函数,将上述 replayDS 函数返回的数据源列表 ds1_chunk 传递给参数 inputTables,最终将数据回放到指定的输出表(outputTables 参数指定)。由此可见,在 DolphinDB 中进行数据回放,非常简单且灵活。
### 2.2 多表回放
多表回放是将多个不同表的数据写入到同一张流表中,并严格按数据的时间顺序回放。DolphinDB 通过对单表回放接口的扩展就能很好的支持多表回放,简单的说,就是将多个数据源的表序列化为一个BLOB 字段,消费时针对不同数据源再反序列为原来的表。以下是多表回放和单表回放的主要区别:
- 流表结构不同。与单表回放不同,流表与参与回放的表结构没有关系,固定由日期时间 (TradeTime) 、数据源(DataSource)、序列化数据(Data)、排序列 (ChannelNo、ApplSeqNum)组成。流表中的数据会按照日期时间+排序列统一排序,这可以解决回放逐笔委托和逐笔成交时同一时间按照流水号排序的需求。多表回放时,需要将多个数据源排序,因此比单表回放更耗时。
- 反序列化不同。多表回放时,需要根据不同数据源反序列化Data中的内容,比起单表回放,这一步也更耗时。
<table><tr><td colspan="4">entrust</td></tr><tr><td>TradeTime</td><td>ChannelNo</td><td>ApplSeqNum</td><td>OrderQty</td></tr><tr><td>2024.03.01 09:15:00</td><td>1</td><td>101</td><td>500</td></tr><tr><td>2024.03.01 09:15:01</td><td>1</td><td>202</td><td>1000</td></tr></table>
<table><tr><td colspan="4">trade</td></tr><tr><td>TradeTime</td><td>ChannelNo</td><td>ApplSeqNum</td><td>TradeQty</td></tr><tr><td>2024.03.01 09:15:00</td><td>1</td><td>102</td><td>100</td></tr><tr><td>2024.03.01 09:15:01</td><td>1</td><td>201</td><td>400</td></tr></table>
<table><tr><td colspan="5">流表</td></tr><tr><td>TradeTime</td><td>DataSource</td><td>Data</td><td>ChannelNo</td><td>ApplSeqNum</td></tr><tr><td>2024.03.01 09:15:00</td><td>entrust</td><td>BLOB</td><td>1</td><td>101</td></tr><tr><td>2024.03.01 09:15:00</td><td>trade</td><td>BLOB</td><td>1</td><td>102</td></tr><tr><td>2024.03.01 09:15:01</td><td>trade</td><td>BLOB</td><td>1</td><td>201</td></tr><tr><td>2024.03.01 09:15:01</td><td>entrust</td><td>BLOB</td><td>1</td><td>202</td></tr></table>
图2-3 多表数据回放流程
下面的代码片段展示了多表回放的使用方法。完整代码可参看附录 2.2 异构多表数据回放脚本。与单表回放相比,差异主要表现在两个方面。首先,流表的 schema 不同。异构流表回放时,流表的前三个字段类型必须是 TIMESTAMP、SYMBOL 和 BLOB,分别代表消息的时间戳,数据源以及序列化数据,后面又添加了两个用于排序的公共字段 ChannelNo 和 ApplSeqNum。其次,replay 函数的三个参数,inputTables,dateColumn 和 timeColumn,输入为一个字典(字典的每一个键值代表一个表),当所有表的 dateColumn/timeColumn 相同时也可以填入一个值。
---
//构造固定格式流表并开启持久化
colName=`msgTime`msgType`msgBody`symbol`ChannelNo`seqNum
colType= [TIMESTAMP, SYMBOL, BLOB, STRING, INT, LONG]
enableTableShareAndPersistence(table=streamTable(10000000:0, colName, colType),
tableName=msgStreamName, asynWrite=true, compress=true,
cacheSize=1000000000, retentionMinutes=1440, flushMode=0)
//构造entrust/trade/snapshot三张表的数据源
ds1_chunk = replayDS(sqlObj=<select *from loadTable(dbName, "entrust") where
SecurityID in chunkCodes and date(TradeTime) between startDate:endDate>,
dateColumn=`TradeTime, timeColumn=`TradeTime)
ds2_chunk = replayDS(sqlobj=<select * from loadTable(dbName,"trade") where
SecurityID in chunkCodes and date(TradeTime) between startDate:endDate>,
dateColumn=`TradeTime, timeColumn=`TradeTime)
ds3_chunk = replayDS(sqlObj=<select* from
loadTable(dbName,"snapshot") where SecurityID in chunkCodes and
---
date(TradeTime) between startDate:endDate and
time(TradeTime) between startTime:endTime >, dateColumn=`TradeTime,
timeColumn=`TradeTime)
inputDict_chunk = dict(["entrust", "trade","snapshot"],
[ds1_chunk, ds2_chunk, ds3_chunk])
//启动后台回放
jobId = submitJob("replayTest", "code size: " + string(chunkCodes.size()),
replay, inputDict_chunk, objByName(msgStreamName),
`time,`time, , , 1,`ChannelNo`seqNum)
### 2.3 回放与订阅处理示例
DolphinDB 为了满足不同客户的开发需求(譬如开发语言、开发环境、开发目的的不同),基于这套灵活的回放架构,提供了丰富的实现方式。针对回放、订阅和消费的功能,DolphinDB 提供了以下 3 种常用的实现方式:
- C++ SDK,Python SDK,Java SDK 等客户端 SDK。不同 SDK 的功能支持和使用说明参见官方文档《连接器 & API》。
- DolphinDB 插件。插件是可以被 DolphinDB Server 加载的动态库,用户可以通过 C++ 开发动态库, 并在 DolphinDB 中访问插件提供的函数。
- Swordfish 嵌入式数据库。Swordfish 可以视作一个动态库,用户可以通过 C++ 开发应用程序,链接 Swordfish 以运行 DolphinDB 丰富的函数。
我们测试了这三种实现方式,在不同线程数的场景下,单表回放和多表回放的性能。单表回放使用一个交易日 2000 只深交所股票的逐笔委托数据(50,741,836行,5.2G)。多表回放使用一个交易日 2000 只深交所股票的快照、逐笔成交和逐笔委托数据(103,687,651行,5.0G)。统计耗时是从回放开始到订阅数据全部接收完成的时间。测试时,订阅客户端和服务端在同一台机器上运行,其中 C++ SDK 和 Swordfish 的耗时统计中包括与 DolphinDB Server 数据序列化与反序列化的耗时。测试代码参考附录 2.1 单表回放脚本和附录 2.2 异构多表数据回放脚本,测试结果详见表 2-1。
表 2-1 插件、SDK 和 Swordfish三种模式下单表回放和多表回放的性能对比
<table><tr><td>回放模式</td><td>线程数(个)</td><td>DolphinDB 插件总耗时(秒)</td><td>C++ SDK总耗时 (秒)</td><td>Swordfish 总耗时(秒)</td></tr><tr><td rowspan="3">单表回放</td><td>2</td><td>24</td><td>26</td><td>28</td></tr><tr><td>5</td><td>12</td><td>15</td><td>19</td></tr><tr><td>10</td><td>8</td><td>13</td><td>14</td></tr><tr><td rowspan="3">异构多表回放</td><td>2</td><td>193</td><td>205</td><td>198</td></tr><tr><td>5</td><td>100</td><td>111</td><td>112</td></tr><tr><td>10</td><td>72</td><td>78</td><td>79</td></tr></table>
2 - 数据回放与订阅从测试结果不难看出,在回放模式上,单表回放性能比异构多表回放更好,因为单表回放不需要排序合并数据,也不需要拆解数据。在实现方式上,插件性能最好,因为插件直接在 DolphinDB 进程内运行,没有网络开销,而 C++ SDK 和 Swordfish 需要远程连接 DolphinDB 取数据,存在网络开销。多线程并行能够有效提高性能,但并不是线性的提升,因为服务端的数据回放到流表需要一定的耗时。订阅端并行能够更快消费数据,但生产数据受到服务端性能限制。故需要根据实际情况设置线程数,使消费速度与生产速度一致。
表 2-2 DolphinDB 数据回放三种客户端实现方式对比
<table><tr><td>订阅端</td><td>实现方式</td><td>开发需求</td><td>应用场景</td><td>优势</td></tr><tr><td>同一进程内订阅</td><td>DolphinDB 插件</td><td>·熟悉 C++ 代码开发动态库 <br> - 需集成 C++ 资源</td><td>- 对性能有极致要求</td><td>-通过内存传输数据, 没有网络延迟 <br> - 有丰富的 DolphinDB 函数</td></tr><tr><td rowspan="2">不同进程订阅</td><td>C+ +/Java/Pyt hon 等 SDK</td><td>·熟悉 C++/Java/Python 代码开发应用程序 <br> ·需集成其他语言的资源</td><td>·需利用客户端算力</td><td>·支持开发语言丰富 <br> ·应用程序运行更灵活</td></tr><tr><td>Swordfish</td><td>- 熟悉 C++ 开发支持 Swordfish 接口的应用程序 <br> - 需集成 C++ 资源</td><td>·需利用客户端算力 <br> ·对性能有极致要求</td><td>·有丰富的 DolphinDB 函数 <br> ·应用程序运行更灵活</td></tr></table>
DolphinDB 采用发布-订阅-消费的模式,通过与数据库系统紧密集成,实现了单表和多表的数据回放方案。相比其他回放系统,具备如下优势:
- 回放速度快,能充分发挥 DolphinDB 数据库的优势。
- 回放功能丰富,开发简单,通过一套接口,满足单表、多表回放、倍速回放、数据持久化的需求。
- 数据处理时能充分利用 DolphinDB 的丰富函数和模块。
- 能满足多种语言、多种场景的开发需求。
## 第 3 章. 模拟撮合引擎
在中高频策略回测中,不能简单地假设每个订单以当前价格或日终价格全部成交,需要一个模拟撮合引擎来模拟实际的交易过程,例如考虑订单能否成交、成交价格、成交量以及市场冲击等因素。订单撮合时,对模拟撮合引擎的要求包含以下几点:
- 撮合规则与交易所一致:使用中高频逐笔行情时,为了使回测结果和实盘交易中的接近,订单撮合规则应遵照 “价格优先,时间优先” 的原则。
- 支持多种撮合模式:用户可能基于逐笔委托和成交、快照等数据进行撮合,模拟撮合引擎应能根据行情类型调整撮合模式。
- 可灵活调整撮合配置:用户可以根据自己的实际情况,对模拟撮合引擎进行配置。比如,用户可能网络环境不佳,则希望自定义下单的延时,以模拟实盘环境中的下单情况。
针对以上要求,DolphinDB 开发了模拟撮合引擎插件。该插件是一个基于 C++ 开发的动态库,可以在需要时动态加载到 DolphinDB 服务器进程。插件中暴露的函数,可以在 DolphinDB 的脚本中被调用。
### 3.1 模拟撮合引擎功能介绍
不同于 DolphinDB 内置的流数据引擎,模拟撮合引擎以插件的形式提供服务。模拟撮合引擎的主要功能是模拟用户在某个时间点发出订单或取消之前已发出订单的操作,并获取相应的交易结果。一笔委托订单进入模拟撮合引擎,首先会根据订单委托时间+设置的延时与行情时间的先后考虑是否即时与订单薄进行撮合,当订单委托时间+设置的延时大于引擎中最新的行情时间时,委托订单会进入待撮合队列;直到行情时间大于订单委托时间+设置的延时时间时,委托订单与行情订单薄进行撮合订单;未成交的部分订单进入挂单队列等待与新的行情进行订单撮合,具体流程图如下图所示。
3 - 模拟撮合引擎

图 3-1 模拟撮合引擎流程图
模拟撮合引擎以某一天的行情(快照数据或逐笔数据)和用户委托订单(买方或卖方)作为输入,根据订单撮合规则模拟撮合。订单的成交结果(包含部分成交结果、拒绝订单和已撤订单)输出至订单交易明细表,未成交部分等待与后续行情撮合成交或者等待撤单。模拟撮合引擎支持以下功能:
- 支持订单成交比例、延时、订单在行情中的位置信息输出、逐笔或快照行情等设置。
- 多笔同方向的用户委托订单同时撮合时,遵循按照价格优先、时间优先的原则进行撮合成交。
- 支持沪深交易所 Level 2 逐笔和快照行情,分钟和日频行情的股票、债券和基金;支持各商品交易所的期货、期权以及 7*24 小时交易的数字货币。
・行情数据为逐笔数据时,撮合引擎实时合成行情订单薄。当用户委托订单到达时,与订单簿即时匹配并产生成交信息,未成交部分与后续行情委托订单一起,后续按照价格优先、时间优先的原则进行撮合成交。
·行情数据为快照数据时,当用户委托订单到达时,与订单簿即时匹配并产生成交信息,未成交部分根据不同的行情类型,有不同的撮合成交模式。
。快照行情:与最新成交价以及对手方盘口按配置的比例撮合。
。快照+区间成交行情:与最新的区间成交列表以及对手方盘口撮合成交。
从用户委托订单角度来讲,包含了限价订单(Limit Order)、沪深交易所的所有市价订单(Market Order) 和上交所的市价保护订单、撤单(Cancel Order)。委托订单类型与行情数据类型的不同组合对应着不同的撮合规则,详见模拟撮合教程的撮合规则部分。
使用模拟撮合引擎,主要有修改配置文件、定义行情表和用户订单表结构及配置列名映射、定义订单明细等结果表、创建引擎、输入行情与委托订单、查看成交情况等六个步骤,具体配置项详见 模拟撮合接口说明文档。3.2 节中,我们将基于逐笔数据,演示如何使用模拟撮合引擎,并介绍其中重要的配置以及接口。3.3节, 我们将介绍如何在C++编写的策略中调用模拟撮合引擎。
### 3.2 模拟撮合引擎使用示例
为便于理解,我们将模拟撮合引擎的演示代码分成了 6 个步骤。完整的使用示例见附录 3.2 完整示例代码。
步骤一:进行模拟撮合引擎的配置
---
config = dict(STRING, DOUBLE)
config["dataType"] = 0
//行情类别:0表示逐笔,1表示快照,2表示快照+成交数据
config["latency"] = 30 //用户订单时延为30
config["orderBookMatchingRatio"] = 1 //与订单薄匹配时的成交百分比
config["outputQueuePosition"] = 2 //输出订单在真实行情数据位置信息
---
在 config 中, 我们进行如下配置
- dataType 为传入的行情类别,0 表示逐笔,1 表示快照,4 表示分钟频,5 表示日频
- latency 为模拟用户订单从发出到被处理的时延,单位为毫秒。
- orderBookMatchingRatio 为下单成交百分比。
- outputQueuePosition 设置是否输出订单在真实行情数据位置信息。
模拟撮合引擎还提供更多的配置项,可以在 模拟撮合引擎插件接口说明文档 中查阅。
步骤二:根据行情表和用户订单表的表结构来创建相应的列名映射字典
---
dummyQuotationTable = table(1:0, [`symbol,`symbolSource,`time,`sourceType,
`orderType, `price, `qty, `buyNo, `sellNo, `BSFlag, `seqNum], [STRING, STRING,
TIMESTAMP, INT, INT, DOUBLE, LONG, LONG, LONG, LONG, INT, LONG])
quotationColMap = dict( [`symbol,`symbolSource,`timestamp,`sourceType,
`orderType, `price, `qty, `buyNo, `sellNo, `direction, `seqNum],
[`symbol,`symbolSource,`time,`sourceType,`orderType,`price,`qty,
`buyNo, `sellNo, `BSFlag, `seqNum])
dummyUserOrderTable = table(1:0, [`symbol, `time, `orderType, `price,
`qty, `BSFlag, `orderID], [STRING, TIMESTAMP, INT, DOUBLE, LONG, INT, LONG])
userOrderColMap = dict( [`symbol,`timestamp,`orderType,`price,`orderQty,
`direction,`orderId], [`symbol,`time,`orderType,`price,`qty,`BSFlag,`orderID])
---
3 - 模拟撮合引擎
设置模拟撮合引擎内部行情字段与真实的行情字段的映射关系。行情字段名称映射字典 quotationColMap 的key 值是引擎内部的字段名称,value 值是行情相应字段的名称。委托订单字段名称映射字典 userOrderColMap 的 key 值是引擎内部的字段名称,value 值是用户委托订单相应字段名称。从上面的代码中可以看到, orderType 对应的是订单类型, 可以选择限价单、市价单或者是撤单。
步骤三:定义订单明细输出表以及合成的快照输出表
---
orderDetailsOutput= table(10000:0,
[`orderD, `symbol, `direction, `sendTime, `orderPrice,
`orderQty,`tradeTime,`tradePrice,`tradeQty,`orderStatus,`sysReceiveTime,
`openVolumeWithBetterPrice,`openVolumeWithWorsePrice,`openVolumeAtOrderPrice,
`priorOpenVolumeAtOrderPrice], [LONG, STRING, INT, TIMESTAMP, DOUBLE,
LONG, TIMESTAMP, DOUBLE, LONG, INT, NANOTIMESTAMP, LONG, LONG, LONG, LONG, LONG])
snapshotOutput = table(1:0, [`symbol,`timestamp,`avgBidPrice,`avgOfferPrice,
`totalBidQty,`totalOfferQty,`bidPrice,`bidQty,`offerPrice,`offerQty,`lastPrice,
`highPrice,`lowPrice], [STRING, TIMESTAMP, DOUBLE, DOUBLE, LONG, LONG, DOUBLE[],
LONG[], DOUBLE[], LONG[], DOUBLE, DOUBLE, DOUBLE])
---
## 步骤四:设置引擎名称,创建引擎
engine = MatchingEngineSimulator::createMatchEngine(name, exchange, config, dummyQuotationTable, quotationColMap, dummyUserOrderTable, userOrderColMap, orderDetailsOutput, , snapshotOutput)
设置引擎名称、模拟交易所名称、引擎配置项、真实行情表的结构和字段映射字典、委托订单的结构和字段映射字典,以及订单详情输出表和合成快照输出表等相应参数之后,通过接口 createMatchEngine 创建模拟撮合引擎实例。
## 步骤五: 通过 insertMsg 接口向引擎插入行情或者订单
插入委托订单时此函数会返回委托订单的订单号,插入行情时无返回值。
---
MatchingEngineSimulator::insertMsg(engine, msgBody, msgType)
---
## 步骤六:查看成交情况
---
opentable = MatchingEngineSimulator::getOpenOrders(engine)
---
订单详情输出表 (orderDetailsOutput) 如下:
<table><tr><td>orderD</td><td>symbol direction</td><td>sendTime</td><td>orderPrice orderOty</td><td>tradeTime</td><td>tradePrice</td><td>tradeQty</td><td>orderStatus</td><td>sysReceiveTime</td><td>openVolumeWithBetterPrice</td><td>openVolumeWithWorsePrice</td><td>openVolumeAtOrderPrice</td><td>priorOpenVolumeAtOrderPrice</td></tr><tr><td>1</td><td>000001</td><td>2021.01.08T09:34:00.400</td><td>6.00000000 100</td><td>2021.01.08T09:36:00.100</td><td>0.0</td><td>0</td><td></td><td>2024.03.12T22:10:26.217125567</td><td>100</td><td>100</td><td>100</td><td>100</td></tr><tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>2</td><td>000001</td><td>2021.01.08T09:36.00.400</td><td>6.00000000 100</td><td>2021.01.08T09:37:00.100</td><td>0.0</td><td>0</td><td></td><td>2024.03.12T22:10:26.217264207</td><td>0</td><td>100</td><td>0</td><td>0</td></tr><tr><td>2</td><td>000001</td><td>2021.01.08T09:36:00.400</td><td>6.00000000 100</td><td>2021.01.08T09:37:00.100</td><td>6.00000000</td><td>100</td><td></td><td>2024.03.12T22.10:26.217264207</td><td>0</td><td>100</td><td>0</td><td>0</td></tr></table>
## 图3-2 订单详情输出表
每笔订单在订单详情输出表中有 2 条记录,第一条 orderStatus 为 4,代表模拟撮合引擎确认收到用户委托; 第二条 orderStatus 为 1 ,代表用户委托完全成交。
### 3.3 开发算法交易策略
算法交易是指通过计算机程序执行交易决策的一种方法。算法交易策略需要满足低延时和高性能的要求,因此通常使用C++语言来实现算法交易策略。用户可以基于 DolphinDB 的数据回放和模拟撮合引擎功能,快速搭建算法交易策略回测框架,以评估其可靠性。通过这个框架,无需修改 C++ 编写的算法交易策略代码,即可直接应用于实盘中的算法交易订单的执行。
我们以实现 TWAP 算法交易策略为例,介绍如何在插件中调用模拟撮合引擎接口。回放数据的方法与 2.2 节基本相同,本节主要介绍如何在插件里调用模拟撮合引擎。
TWAP ( Time-Weighted Average Price ) 策略的核心思想是将交易量均匀地分散在一段时间内进行交易,以平滑交易对市场的影响。这种策略通过将整个交易量平均分配到一段时间内的多个小交易中,避免了在特定时间点引起市场的剧烈波动。在这个例子中,我们将交易时间,按每30秒一个单位,分成N个区间。然后在每个时间区间的开始时间点,执行两个操作:(1)对上一时刻订单中未成交的订单进行撤单,(2)每次下单量为剩余下单量/剩余的区间数量。
#### 3.3.1 算法交易策略回测框架实现
本节通过一个简单的示例,介绍如何在 DolphinDB 插件中调用模拟撮合引擎接口。本节使用的示例插件是 TWAP 算法交易插件,完整的插件代码将在附件中提供。完整插件及 demo 代码见附录 3.3 模拟撮合引擎算法交易策略回测案例代码。
在编写插件前,用户需要先学习 插件开发教程,以了解插件开发的基本概念和流程。例如在 TWAP 算法交易插件中,通过 getFunctionDef 方法可以获取模拟撮合引擎的函数接口,该方法返回一个函数指针,然后通过 createEngineFunc->call(heap_, args) 来调用该函数。以下是代码示例:
---
string methodName = "MatchingEngineSimulator::createMatchEngine";
FunctionDefSP createEngineFunc =
heap_->currentSession()->getFunctionDef(methodName);
vector<ConstantSP> args = \{...\};
auto engine = createEngineFunc->call(heap_, args);
---
为了便于使用模拟撮合引擎,我们封装了 MatchEngineSimulatorWrapper 类来调用模拟撮合引擎的相关接口,主要接口为 appendQuotationMsg 写入行情数据和 submitOrder 提交订单,均通过调用模拟撮合引擎的 insertMsg 接口实现:
---
ConstantSP MatchEngineSimulatorWrapper::insertMsg(ConstantSP msgBody, int msgId) \{
std::vector<ConstantSP> arguments = \{engine_, msgBody, new Int(msgId)\};
ConstantSP res = insertMsgFunc_->call(heap_, arguments);
return res;
\}
void MatchEngineSimulatorWrapper::appendQuotationMsg(ConstantSP data) \{
insertMsg(data, 1);
\}
VectorSP MatchEngineSimulatorWrapper::submitOrder(ConstantSP data) \{
VectorSP res = insertMsg(data, 2);
---
3 - 模拟撮合引擎
---
return res;
\}
---
本算法交易框架实现逻辑如下:
- 首先创建算法交易回测框架,其中创建一个上交所逐笔行情的模拟撮合引擎。
- TWAP 算法交易策略回测实现逻辑如下:
。当行情时间小于等于算法订单的开始时间 t 时,接收上交所股票逐笔行情数据。
。当行情时间第一次大于算法订单的开始时间 t 时,把接收到行情数据分发给模拟撮合引擎。
。在行情时间第一次大于 t+N*30 秒(N=0,1,…)时,对模拟撮合引擎执行以下操作:
- 对上一时刻订单中未成交的订单进行撤单。
- 每次委托数量为剩余下单量/剩余的区间数量,价格为最新的成交价格。
。接收 t+(N-1)*30 秒到 t+N*30 秒的行情数据,把接收到行情数据分发给模拟撮合引擎。
。重复 以上两个步骤。
。当行情时间大于算法订单的结束时间时,结束算法交易逻辑。
·获取订单成交结果。
为了实现这个逻辑,我们定义了 AlgoOrder (AO) 类。这是这个插件的主要类,包含了构建回测框架、根据策略逻辑处理行情数据等功能。AO 类中,最重要的函数为构造函数 AlgoOrder 和 run 函数。AlgoOrder 函数负责创建模拟撮合引擎,而 run 函数负责根据到来的逐笔委托和成交行情生成订单,并将行情和订单分发到相应的模拟撮合引擎中。伪代码如下:
// 创建引擎
---
engineXSHG = new MatchEngineSimulatorWrapper(market="XSHG", ...)
...
// 输入行情,遍历解析
for (msg in msgs) \{
if (数据为逐笔成交行情或逐笔委托) \{
// 如果快照时间戳变化,写入之前两个快照之间的逐笔数据到引擎
if (全局快照时间戳发生变化) \{
tickBufferMsg = tickDeserializer->getTable();
engineXSHG->appendQuotationMsg(tickBufferMsg)
tickDeserializer->clear();
\}
tickDeserializer->deserialize(msg);
\} else if (数据类型为快照行情) \{
// 如果快照时间戳变化,检查是否执行交易策略
if (全局快照时间戳发生变化) \{
snapshotBufferMsg = tickDeserializer->getTable();
if (msg time in strategy's time) \{
// 遍历未成交的用户订单,撤单
---
openOrders = engineXSHG->getOpenOrders()
orderTable = createCancelOrderXSHG(openOrders)
engineXSHG->submitOrder(orderTable);
\}
// 遍历快照,下单
for (snapshotMsg in snapshotBufferMsg) \{
order = createOrderXSHG(snapshotMsg)
engineXSHG->submitOrder(order);
\}
// 更新策略信息
updateStrategy()
\}
tickDeserializer->clear();
\}
snapshotDeserializer->deserialize(msg);
\} else if (msgType == "END") \{
clearEnv()
\}
return
\}
#### 3.3.2 TWAP 性能测试
实验回放 1 天的深圳市场的股票快照、逐笔委托、逐笔成交数据。TWAP 插件订阅上述三张表的数据完成算法交易。测试结果如表3-1 所示。可以看到,撮合性能具有较好的线性拓展性,即回放+撮合耗时与数据量成正比。同时,撮合性能具有较好的并行拓展性,即回放+撮合耗时与线程数成反比。
表 3-1 TWAP 插件的性能测试结果
<table><tr><td>数据</td><td>数据量</td><td>订单数</td><td>线程数</td><td>回放耗时(秒)</td><td>回放+撮合耗时(秒)</td></tr><tr><td>1天,500 支股票</td><td>25, 553, 988行 <br> (1.4G)</td><td>394,353</td><td>1</td><td>68</td><td>122</td></tr><tr><td>1天,1000 支股票</td><td>51, 191, 848行(2.6G)</td><td>846,976</td><td>1</td><td>141</td><td>243</td></tr><tr><td rowspan="4">1天,2000 支股票</td><td rowspan="4">103, 687, 651行 <br> (5.0G)</td><td rowspan="4">1, 410, 536</td><td>1</td><td>306</td><td>552</td></tr><tr><td>2</td><td>176</td><td>277</td></tr><tr><td>5</td><td>98</td><td>127</td></tr><tr><td>10</td><td>49</td><td>78</td></tr></table>
3 - 模拟撮合引擎
通过本章的介绍可以看到,DolphinDB 的模拟撮合使用 C++语言开发,不仅具备丰富的撮合功能,而且还具备高性能和良好的扩展性。同时,用户可以在自己的 C++回测系统中调用 DolphinDB 模拟撮合引擎,极其灵活。
## 第 4 章. 回测引擎
中高频回测引擎对于验证策略在实盘中的效果必不可少。对中高频回测引擎的要求包含以下几点:
·丰富的策略触发机制:中高频回测中,策略通常是事件驱动的,而一个策略逻辑通常需要涉及多种事件,比如新的行情到来、新的订单成交等等。回测引擎需要提供全面的事件函数,供用户实现不同事件下的策略逻辑。
- 全面的回测结果信息:回测完成之后,用户需要回顾这次回测的表现,比如年化收益、年化波动、夏普比率等;然后进一步观察每日持仓、订单明细等信息,复盘策略。回测引擎需要提供接口,以便客户可以方便地获取这些信息。
针对以上要求,我们基于 DolphinDB 分布式存储和计算、多范式的编程语言和模拟撮合引擎插件,实现了针对沪深交易所的中高频 Level 2 逐笔以及快照行情的事件型回测引擎插件。本章主要介绍 DolphinDB 中高频事件型回测引擎的功能,使用方法将在第 5 章介绍。
### 4.1 中高频回测引擎功能介绍
DolphinDB 中高频回测引擎主要分为四个核心部分:用户自定义策略函数,策略配置与创建,行情数据回放,执行回测引擎获取回测结果。中高频回测引擎以插件的形式提供服务,其逻辑架构如图 4-1 所示。回测的主要工作流程包括:(1)回测引擎接收按时间先后顺序回放的数据流、引擎内部把数据流分发给模拟撮合引擎和相应的行情回调函数,(2)行情回调函数处理策略逻辑并发送委托订单,(3)回测引擎根据策略委托订单进行风控管理,(4)通过风险控制的委托订单发送给模拟撮合引擎进行订单撮合,(5)回测引擎根据订单成交情况实时进行持仓和资金统计管理,策略回测结束返回策略的收益、成交明细等信息。

图 4-1 中高频回测引擎实现框架图
回测引擎支持沪深交易所所有标的的逐笔+快照、逐笔(逐笔合成快照触发策略)、快照和快照+成交、分钟和日频行情策略回测;以及期货和期权的快照、分钟和日频的行情;以及银行间的现券等策略回测。策略委托订单撮合逻辑基于 DolphinDB 模拟撮合引擎,具体见 模拟撮合引擎使用教程。

图 4-2 使用回测引擎流程图
使用 DolphinDB 脚本来编写回测策略,通常包含图 4-2 所示的 5 个步骤。首先,回测引擎提供多个事件函数,包括策略初始化、每日盘前和盘后回调函数、逐笔、快照和K线行情的回调函数、委托和成交回报函数等。用户可以在策略初始中定义指标、在其他相应的回调函数中编写自定义策略。其次,对策略的行情源、资金、订单延时和成交比例等进行配置。再次,根据策略和配置,创建相应的回测引擎。接着,回放数据源、执行回测引擎。最后获取回测的结果。
### 4.2 编写自定义策略
回测引擎采用事件驱动机制。它提供事件函数如表 4-1 所示。事件函数的实现,目前支持三种语言: DolphinDB 内置的脚本语言,通过 Python Parser 实现的 Python 脚本,以及用 C++ 开发的 DolphinDB 插件。这三种方式实现事件函数的案例,分别会在第 5 章, 第 6 章和第 7 章中介绍。
表 4-1 回测引擎提供的事件函数
<table><tr><td>事件函数</td><td>说明</td></tr><tr><td>initialize(mutable contextDict)</td><td>策略初始化函数,只触发一次。参数 contextDict 为逻辑上下文。 <br> 可以在该函数中通过 contextDict <br> 参数初始化一些全局变量,或者订阅指标计算。</td></tr><tr><td>beforeTrading(mutable contextDict)</td><td>盘前回调函数,每日盘前触发一次。可以在该函数中执行当日启动前的准备工作,如订阅行情等。</td></tr><tr><td>onTick(mutable contextDict, msg)</td><td>逐笔行情回调函数,逐笔委托和逐笔成交行情更新时触发。</td></tr><tr><td>onSnapshot(mutable contextDict, msg)</td><td>快照行情回调函数。</td></tr><tr><td>onBar(mutable contextDict, msg)</td><td>中低频行情回调函数。</td></tr><tr><td>onOrder(mutable contextDict, orders)</td><td>委托回报回调函数,每个订单状态发生变化时触发。</td></tr><tr><td>onTrade(mutable contextDict, trades)</td><td>成交回报回调函数,发生成交时触发。</td></tr><tr><td>afterTrading(mutable contextDict)</td><td>策略每日盘后的回调函数,每日盘后触发一次。可以在该函数统计当日的成交、持仓等信息。</td></tr><tr><td>finalize(mutable contextDict)</td><td>策略结束之前回调一次该函数。</td></tr></table>
事件回调函数中的参数 contextDict 为字典类型, 提供策略逻辑上下文。用户的所有自定义变量都可以设置在 contextDict 中。但是引擎会维护这 3 个变量:contextDict.tradeTime 获取行情的最新时间,contextDict.tradeDate 获取当前日期,contextDict.engine 获取回测引擎实例。
用户可以在相应的回调函数中编写策略逻辑实现相应的策略,行情回调函数 onTick、onSnapshot 和 onBar 中的 msg 参数是回测引擎提供的相应行情数据,委托订单回调函数 onOrder 和 onTrade 中的相应订单状态包括委托回报、拒单、撤单和成交等信息。具体字段名称以及字段说明详见回测引擎的接口文档说明。
### 4.3 回测引擎配置参数
回测的开始与结束日期、初始资金、手续费和印花税、行情类型,订单延时和动态分红除权等功能都可以通过参数进行配置。引擎也支持设置深交所科创版逐笔行情前收盘价。在逐笔行情模式下,策略可以实时获取优于或等于委托订单价格的行情中的未成交委托总量等指标。具体详见回测插件接口说明文档。
表 4-2 回测引擎配置参数
<table id="cross-table-1"><tr><td>配置项</td><td>数据类型</td><td>说明</td><td>备注</td></tr><tr><td>startDate</td><td>DATE</td><td>开始日期</td><td>如 2020.01.01</td></tr><tr><td>endDate</td><td>DATE</td><td>结束日期</td><td>如 2024.01.01</td></tr><tr><td>strategyGroup</td><td>STRING</td><td>策略类型</td><td>如股票回测:"stock"</td></tr><tr><td>cash</td><td>DOUBLE</td><td>初始资金</td><td>策略初始资金</td></tr><tr><td>commission</td><td>DOUBLE</td><td>手续费</td><td></td></tr><tr><td>tax</td><td>DOUBLE</td><td>印花税</td><td></td></tr><tr><td>dataType</td><td>INT</td><td>行情类型: <br> 0:逐笔+快照 <br> 1:快照 <br> 2:快照+成交 <br> 3:分钟频率</td><td>frequency>0 and dataType=0 时,行情为逐笔行情。引擎内部合成 frequency <br> 频率的快照行情,合成的快照行情触发 onSnapshot 回调函数</td></tr><tr><td>frequency</td><td>INT</td><td>frequency $> 0$ 时,行情为逐笔行情,引擎内部合成frequency频率的行情触发onSnapshot</td><td>默认为0</td></tr><tr><td>msgAsTable</td><td>BOOL</td><td>行情的数据形式</td><td>table 或 dict</td></tr><tr><td>latency</td><td>INT</td><td>订单延时</td><td>单位:毫秒</td></tr><tr><td>orderBookMatchingRatio</td><td>FLOAT</td><td>与行情订单薄的成交百分比</td><td>默认值 1</td></tr><tr><td>matchingRatio</td><td>FLOAT</td><td>快照行情时,区间成交比例</td><td>默认值 1</td></tr><tr><td>enableSubscriptionToTick Quotes</td><td>BOOL</td><td>是否订阅逐笔行情</td><td>设置为 true 时,需定义 onTick 回调函数</td></tr><tr><td>outputQueuePosition</td><td>INT</td><td>是否需要获取订单在行情中的位置,默认为0; <br> 0:不输出 <br> 1:表示订单撮合成交计算上述指标的时,把最新的一行行情纳入订单薄 <br> 2:表示订单撮合成交计算上述指标的时,把最新的一行行情不纳入订单薄,即统计的是撮合计算前的位置信息</td><td>当订单还没有完全成交时,可以通过 getOpenOrders 接口实时获取优于、次于或等于委托订单价格的行情中的未成交委托总量,以及等于委托订单价格的行情中的未成交委托总量。</td></tr><tr></tr><tr><td>preClosePrice</td><td>TABLE</td><td>前收盘价</td><td>当含有深交所创业版的逐笔行情时,必须设置前收盘价,否则订单撮合结果可能不符合预期。</td></tr><tr><td>stockDividend</td><td>TABLE</td><td>分红除权基本信息表</td><td></td></tr></table>
### 4.4 回测引擎使用注意事项
前面几个小节介绍了回测引擎的功能,事件接口以及主要的参数。本节我们再补充使用回测引擎的一些注意事项和常见问题:
- 一个回测引擎可以同时支持多只股票的回测,只需要同时回放多只股票的行情即可。
·如果策略想并行回测,可以创建多个回测引擎,在脚本中向多个引擎并发插入数据执行回测。
·基于沪深交易所中高频逐笔行情进行策略回测时,支持同时回测沪深两个交易所的股票,引擎内部维护两个交易所的模拟撮合引擎,此时行情中的 symbol 必须带有交易所标识(".XSHG",".XSHE")结尾,例如 "600000.XSHG",否则系统会报错。
- 引擎接收到 symbol 为 "END" 时,表示策略回测结束。
·订阅行情指标时,内部创建了相应的响应式状态引擎,状态因子的编写参考DolphinDB 响应式状态引擎介绍教程。
·目前支持的品种为沪深交易所股票、可转债和基金逐笔、快照、分钟和日频行情,银行间债券的快照行情、期货和期权快照、分钟和日频行情。数字货币回测功能还在开发中,目前可以暂时用通用资产类型来回测。
### 4.5 使用示例
接下来,我们通过一个简单的例子演示如何使用中高频回测引擎进行回测,并介绍其中重要的配置以及接口。 本例中将使用快照数据作为行情。
回测引擎提供多个事件函数,包括策略初始化、每日盘前和盘后回调函数、逐笔、快照和K线行情的回调函数、订单委托和成交回报函数等。用户可以在策略初始化函数中定义指标、在其他相应的回调函数中编写自定义策略逻辑。然后配置相应开始和结束日期,执行策略回测。
完整代码参考附录 4.5 使用示例。
## 步骤一:编写自定义策略
首先在策略初始化回调函数 initialize 中设置策略全局变量或者订阅指标。本例中,定义了 1 个指标 ret,为当前 tick 相比上一个 tick 的收益率。
---
def ret(lastPrice, prevClosePrice)\{
return lastPrice\\prevClosePrice-1
---
4 - 回测引擎
---
\}
def initialize(mutable contextDict)\{
//初始化回调函数
print("initialize")
//订阅快照行情的指标
d=dict(STRING, ANY)
d["ret"]=<ret(lastPrice, prevClosePrice)>
Backtest::subscribeIndicator(contextDict["engine"], "snapshot", d)
\}
---
subscribeIndicator 接口获取回测引擎名、需要计算的数据类型 (如 snapshot、tick 等) 、需要计算的指标字典(key 为指标名,用于之后访问;value 为指标计算的元代码),之后计算结果将传入 onSnapshot 等策略回调函数。
在每日盘前回调交易函数中,可以初始化当日的全局变量或者订阅当日的股票池。这里回测接口 Backtest::setUniverse 可以更换当日股票池。
---
def beforeTrading(mutable contextDict)\{
////每日盘前回调函数
////通过contextDict["tradeDate"]可以获取当日;
print ("beforeTrading: "+contextDict["tradeDate"])
//通过Backtest::setUniverse可以更换当日股票池
Backtest::setUniverse(contextDict["engine"],["000001.XSHE"])
\}
---
快照行情回调函数 onSnapshot,基于快照行情编写策略逻辑,根据行情以及策略信号下达委托买或者委托卖订单。onSnapshot 的 msg 参数,为回测引擎传来的最新快照行情,以及 initialize 中定义的指标计算结果。msg 是一个字典,字典的 key 为股票名,而 value 为这支股票对应的行情信息以及指标计算结果。 比如,msg["000001.XSHE"]["bidPrice"] 返回的是 000001.XSHE 最新十档买价,而 msg["000001.XSHE"] ["ret"]返回的就是最新价相比于前价的收益率。
---
def onSnapshot(mutable contextDict, msg)\{
for( istock in msg.keys())\{
lastPrice=msg[istock]["offerPrice"][0]
qty=msg[istock]["offerQty"][0]
if (msg[istock]["ret"]>0.01)\{
Backtest::submitOrder(contextDict["engine"],
(istock, contextDict["tradeTime"] , 5, lastPrice, qty, 1),"buy")
\}
\}
\}
---
这里的 Backtest::submitOrder 是回测引擎提供的下单接口:
---
Backtest::submitOrder(engine, msg, label="")
//engine 引擎实例
---
//msg:订单信息元组或表,(股票代码, 下单时间, 订单类型, 订单价格, 订单数量, 买卖方向) //label: 可选参数,方便用于对订单进行分类
所以本例中,将根据收益率判断,如果最新价相比于前价涨幅超过1%,则下单 000001.XSHE 的限价买单,下单时间为最新的快照时间,价格为一档卖价,股数为一档卖量。
除了根据行情到来编写相应策略外,中高频回测引擎还支持针对委托订单发生订单状态变化、成交、每日盘后进行账户信息统计、策略结束之前处理相应的业务逻辑等编写相应策略。要了解所有中高频回测引擎支持的事件回调函数,请参阅回测插件接口说明文档。
## 步骤二: 根据策略设置相应的配置参数
以下只是列出了一些配置参数,完整的配置参数列表请参阅 回测插件接口说明文档。
---
userConfig=dict(STRING, ANY)
userConfig["startDate"]= 2022.04.11
userConfig["endDate"]= 2022.04.11
userConfig["strategyGroup"]="stock"
userConfig["frequency"]=0
userConfig["cash"]= 100000000
userConfig["commission"]= 0.00015
userConfig["tax"] = 0.001
//行情类型,0:逐笔+快照,1:快照,2:快照+成交
userConfig["dataType"] = 1
//tick的数据格式,table或dict
userConfig["msgAsTable"]= false
---
步骤三: 创建回测引擎
---
engine=Backtest::createBacktestEngine(strategyName, userConfig,, initialize,
beforeTrading, onTick, onSnapshot, onOrder, onTrade, afterTrading, finalize)
---
步骤四: 执行回测引擎
通过 Backtest::createBacktestEngine 创建回测引擎之后, 可以通过以下方式执行回
测。messageTable 数据为相应的逐笔(逐笔成交和委托或者快照三个数据源)、快照或快照+成交行情数据。行情数据字段和类型说明参考 回测插件的接口文档。
---
Backtest::appendQuotationMsg(engine, messageTable)
---
## 步骤五: 获取回测结果
回测运行结束之后,可以通过相应的接口获取每日持仓、每日权益、收益概述、成交明细和策略中用户自定义的逻辑上下文。回测插件提供的完整回测结果接口可以参阅 回测插件的接口说明文档。下图为本例获得的每日持仓数据:
<table><tr><td>symbol</td><td>tradeDate</td><td>lastDayLongPosition</td><td>lastDayShortPosition</td><td>longPosition</td><td>longPositionAvgPrice</td><td>shortPosition</td><td>shortPositionAvgPrice</td><td>todayBuyVolume</td><td>todayBuyValue</td><td>todaySellVolume</td><td>todaySellValue</td></tr><tr><td>000001.XSHE</td><td>2022.04.11</td><td>0</td><td>0</td><td>2,000</td><td>7.350000000000000000</td><td>0</td><td>0.0</td><td>2,000</td><td>14700.0000000000000000000</td><td></td><td>0.0</td></tr></table>
图 4-3 每日持仓数据
## 第 5 章. DolphinScript 编写回测策略
我们通过动态网格交易策略、科创版做市策略、股票中高频 CTA 策略、和期货分钟频 CTA 策略等 4 个案例展示如何使用内置的 DolphinDB 脚本来编写事件回调函数,深入介绍 DolphinDB 中高频回测引擎的使用。
### 5.1 动态网格交易策略回测
本节通过一个具体的网格交易策略示例,详细展示如何在 DolphinDB 中高频回测引擎中基于快照行情来实现这一策略。传统网格交易策略主要围绕基准价进行买卖操作。每当价格下跌时,在触发点位执行买入操作;每当价格上升时,在触发点位执行卖出操作。这种方法只能应对一般情况下的小范围波动,对于突发的大波动就会显得束手无策,无法捕捉上升趋势,也无法躲避暴跌大行情。 如果在暴跌的时候先减少买入,等行情平稳再买入;在上升趋势暂停卖出,等趋势减缓再卖出,将有效提高网格交易策略的整体收益。
动态网格策略设置网格间距 alpha 和反弹间距 beta,当标的价格触发网格线之后再次触发反弹价格时执行买入或卖出操作。具体策略逻辑:
- 构建网格策略参数:初始价格为策略开盘时的第一个成交价,网格间距 alpha 设置为 2%,反弹间距 beta 设置为 1%,每格的交易金额 M 设置为 10 万。
- 开仓逻辑:标的价格触发基准价之下的第 n 个网格线,等待最新价格从最低价反弹 beta 买入,数量为 (n*M/最新价)。
- 平仓逻辑:标的价格触发基准价之上的第 n 个网格线,等待最新价格从最高价回落 beta 卖出,数量为 (n*M/最新价)。
- 根据开仓或者平仓信号,更新基准价为最新买或卖价格。
#### 5.1.1 网格交易策略实现
行情数据可以使用快照,也可以使用更细精度的逐笔+快照行情。策略初始化函数 initialize 只在创建引擎之后触发一次。可以在初始化函数 initialize 中通过逻辑上下文 contextDict 参数,设置网格策略的参数, 包括网格间距、反弹间距,以及每只标的相应的初始价格基准价等策略回测全局参数。
---
def initialize(mutable contextDict)\{
print("initialize")
// 初始价格
contextDict["initPrice"] = dict(SYMBOL, ANY)
// 网格间距 (百分数)
contextDict["alpha"] = 0.01
// 回落间距 (百分数)
contextDict["beta"] = 0.005
...
\}
---
在快照行情的 onSnapshot 回调函数中,实现策略的主要逻辑。首先,定义一个自定义函数
updateBaseBuyPrice,当最新价格突破新的网格上线或网格下线时,根据最新的网格线更新基准买卖价格, 以及更新当前的最高或最低价格。
---
def updateBaseBuyPrice(istock, lastPrice, basePrice, mutable baseBuyPrice,
mutable baseSellPrice, mutable N, mutable highPrice, mutable lowPrice, alpha,
n, mode=0)\{
//根据最新价和最新的基准价更新网格线和最高或者最低价
baseBuyPrice[istock]=basePrice*(1-alpha)
baseSellPrice[istock]=basePrice*(1+alpha)
N[istock]=n
if(mode==0)\{//买入、卖出等初始化
lowPrice[istock]=0.
highPrice[istock]=10000.
\}
else if(mode==1)\{//下跌,更新下网格线
lowPrice[istock]=lastPrice
highPrice[istock]=10000.
\}
else if(mode==2)\{//上涨,更新上网格线
lowPrice[istock]=0.
highPrice[istock]=lastPrice
\}
\}
---
然后,在 onSnapshot 回调函数中,根据上涨或下跌行情实时更新网格数量和最新的网格线,并记录下跌过程中的最低价和上涨过程中的最高价。当最新价格触发反弹价或者回落价格时,执行买入或卖出相应数量的标的操作,然后动态更新最新价的基准价格。在买入或者卖出时,调用 Backtest::getPosition 接口获取当日的买入或者卖出数量。Backtest::getPosition 接口是引擎提供的实时获取账户买\\卖持仓量,买\\卖成交金额等接口函数,具体返回字段见 回测引擎插件接口说明文档。
完整的策略脚本详见附录 5.1 网格交易策略。
#### 5.1.2 网格交易策略调试
在策略研究过程中,完成策略编写后,通常会使用少量标的进行策略调试与验证。
## 通过 userConfig 对回测进行配置
userConfig=dict(STRING, ANY)
userConfig["startDate"]=startDate
userConfig["endDate"]=endDate
//策略初始资金设置
---
userConfig["cash"]= 100000000
...
---
## 调用 createBacktestEngine 创建回测引擎
engine = Backtest::createBacktestEngine(strategyName, userConfig,, initialize, beforeTrading,, onSnapshot, onOrder, onTrade, afterTrading, finalize)
5 - DolphinScript 编写回测策略
## 调用自定义的 getSnapShotHqData 函数
获取上交所 3 个交易日 10 支 ETF 的快照+成交行情数据
---
snapshotTable = getSnapShotHqData(startDate, endDate, codes,2)
---
## 调用 appendQuotationMsg
将行情传入回测引擎,开始执行回测,并输出策略中的打印信息。
Backtest::appendQuotationMsg(engine, snapshotTable)
$>$ backtest::appendQuotationMsg(engine, messageTable)
initialize
beforeTrading: 2022.04.13
afterTrading: 2022.04.13
beforeTrading: 2022.04.14
afterTrading: 2022.04.14
beforeTrading: 2022.04.15
afterTrading: 2022.04.15
finalized
## 图5-1 策略打印信息
获取策略回测结果包括每日持仓、每日权益、收益概述和订单的成交明细等。
//成交明细
tradeDetails=Backtest::getTradeDetails(engine)
//每日持仓
dailyPosition=Backtest::getDailyPosition(long(engine))
// 可用资金
enableCash=Backtest::getAvailableCash(long(engine))
//日组合指标展示
totalPortfolios=Backtest::getDailyTotalPortfolios(long(engine))
//回测结果综合展示
returnSummary=Backtest::getReturnSummary(long(engine))
<table><tr><td>symbol</td><td>tradeDate</td><td>lastDayLongPosition</td><td>lastDayShortPosition</td><td>IongPosition</td><td>longPositionAvgPrice</td><td>shortPosition</td><td>shortPositionAvgPrice</td><td>todayBuyVolume</td><td>todayBuyValue</td><td>todaySellVolume</td><td>todaySellValue</td></tr><tr><td>501011.XSHG</td><td>2022.04.13</td><td>0</td><td>0</td><td>499,100</td><td>1.18057803</td><td>0</td><td>0.0</td><td>508,100</td><td>599851.70000000</td><td></td><td>0.0</td></tr><tr><td>501011.XSHG</td><td>2022.04.14</td><td>499,100</td><td>0</td><td>500,000</td><td>1.17791561</td><td>0</td><td>0.0</td><td>170,900</td><td>199953.00000000</td><td></td><td>0.0</td></tr><tr><td>501011.XSHG</td><td>2022.04.15</td><td>500,000</td><td>0</td><td>672,600</td><td>1.17255697</td><td>0</td><td>0.0</td><td>344,200</td><td>399955.60000000</td><td></td><td>0.0</td></tr></table>
图5-2 策略回测结果
#### 5.1.3 网格交易策略执行
一般来说,技术指标策略更关注策略的胜率指标,因为胜率越高,策略价值越大。中高频回测行情数据量大, 这里通过并行回测提升策略回测效率。
首先定义函数 runBacktest_snapshot,用于通过快照+成交行情执行策略回测。回测过程包括获取回测开始到回测结束日期的所有交易日,对每个交易日进行策略回测。最后,在回测结束时增加一行 symbol 为 "END" 的消息,表示行情回放结束。回测引擎接收到 "END" 标志后结束回测,并统计策略的收益和胜率等指标。
---
def runBacktest_snapshot(userConfig, initialize, beforeTrading, onTick, onSnapshot,
onOrder, onTrade, afterTrading, finalize, strategyName, startDate, endDate, codes)\{
//快照+成交行情进行策略回测
engine = Backtest::createBacktestEngine(strategyName, userConfig,,
initialize, beforeTrading,, onSnapshot, onOrder, onTrade, afterTrading, finalize)
go
tradeDates=getMarketCalendar("CFFEX", startDate, endDate)
for( idate in tradeDates)\{
messageTable=select iif(substr(SecurityID, 6, 2)=="SH",
strReplace(SecurityID, "SH", ".XSHG"),
strReplace(SecurityID,"SZ",".XSHE")) as symbol,
if(substr(SecurityID,6,2)=="SH","XSHG","XSHE") as symbolSource,
dateTime as timestamp, lastPrice, upperLimitPrice as upLimitPrice,
lowerLimitPrice as downLimitPrice, long(totalBidQty) as totalBidQty,
long(totalOfferQty) as totalOfferQty, bidPrice, bidOrderQty as bidQty,
OfferPrice as offerPrice, offerOrderQty as offeQty,
fixedLengthArrayVector([lastPrice]) as signal, tradePrice2 as tradePrice,
tradeQty2 as tradeQty,0.0 as prevClosePrice from
loadTable("dfs://Level2_tickTrade", 'tickTradeTable)
where SecurityID in codes and date(dateTime) between startDate:endDate and
second(dateTime) between startTime:endTime order by timestamp
Backtest::appendQuotationMsg(engine, messageTable)
\}
//增加回测结束标志
temp=select * from messageTable where timestamp=max(timestamp) limit 1
update temp set symbol="END"
Backtest::appendQuotationMsg(engine, temp)
return engine
\}
---
把股票池分为 $\mathrm{n}$ 份,进行策略并行回测。
---
def runBacktestParallelMode(userConfig, initialize, beforeTrading, onTick,
onSnapshot, onOrder, onTrade, afterTrading, finalize, startDate, endDate, codes,
parallelMode=4, nSize=1)\{
dates=getMarketCalendar("CFFEX", startDate, endDate)
destroyAllBacktestEngine()
jobs = array(STRING, 0, 10)
//把股票分成 n 份,并行
---
5 - DolphinScript 编写回测策略
---
cuts=cut(codes, nSize)
for( icodes in cuts)\{
strategyName=strReplace("backtest"+concat(icodes,""),".","")
jobId=submitJob(strategyName, strategyName+"job", runBacktest_snapshot,
userConfig, initialize, beforeTrading, onTick, onSnapshot, onOrder, onTrade,
afterTrading, finalize, strategyName, min(dates), max(dates), icodes)
jobs=jobs.append!(jobId)
\}
//获取每个引擎的回测结果,并返回,具体代码请见附件
\}
---
选取 2021 年沪深交易所的最活跃 800 只标的并行回测,获取成交明细,分析策略最终的胜率等指标。
// step 1: 策略编写
// step 2: 策略配置
// step 3:把股票分成 n 份,取2021年1月1日到12月31日的数据并行回测,并获取计算结果
startDate=2021.01.01
endDate=2021.12.31
dailyReport, tradeOutputTable, engines, removejobs=runBacktestParallelMode(userConfig,
initialize, beforeTrading,, onSnapshot, onOrder, onTrade, afterTrading, finalize,
startDate, endDate, codes,4, n)
我们选取了 2021 年部分月份上海证券交易所交易最活跃80只标的,行情为快照+区间成交,进行性能测试。 性能测试结果见表 5-1。
表 5-1 动态网格交易策略性能测试结果
<table><tr><td>标的</td><td>数据量</td><td>核数</td><td>数据回放耗时(s)</td><td>执行回测耗时 (s)</td></tr><tr><td>2021 <br> 年上交所交易最活跃的 10 只股票</td><td>8,447,769 行</td><td>1</td><td>18s</td><td>282.6s</td></tr><tr><td>一个交易日 80 只股票</td><td>306,003 行</td><td>1</td><td>0.5s</td><td>6s</td></tr><tr><td>2021 <br> 年上交所交易最活跃的 80 只股票</td><td rowspan="2">70,528,043 行</td><td>8</td><td>16.1s</td><td>247.7s</td></tr><tr><td>2021 <br> 年上交所交易最活跃的 80 只股票</td><td>16</td><td>9.2s</td><td>153.6s</td></tr></table>
从测试结果可以看出,执行回测的耗时和线程数并非是成比例的。这是因为回测引擎是计算密集型的任务,当线程数过多时,增加线程数会引入更多的资源竞争和调度开销,这些额外的开销影响了总体运行的耗时。
### 5.2 科创版做市策略回测示例
做市策略通过赚取买卖价差来获取利润,是中高频交易策略中最主要的策略。由于该策略需要持续地提供报价,当标的出现单边等行情时,做市策略可能会面临存货增加的风险,进而增加策略的风险。因此做市策略通常包括报价管理、持仓对冲管理、风控管理三大模块。报价模块涉及买卖双边的报价设定,以及在单边成交发生时及时撤单并重新报价的操作。持仓管理则包括在持仓大于一定量等情况下进行的平仓操作。
#### 5.2.1 做市策略模型逻辑
以下实现一个简单的做市策略逻辑:
- 策略参数说明
。最小报价金额
。双边报价最大的买卖价差(百分数)
。单边最大的持仓量
。对冲价格偏移量(单位为元)
。当日亏损金额上限
。最新一分钟的价格波动上限
- 双边报价逻辑:当前没有报价时,首先获取最新 tick 盘口的买卖中间价 midPrice = (ask1+bid1)/2,以 min(midPrice-最大的买卖价差/2, bid1)和 max(midPrice+最大的买卖价差/2, ask1) 的价格进行双边报价,报价数量为最小报价金额除以相应的价格
- 对冲模块逻辑:报价订单发生成交时,以成交价加减对冲价格偏移量进行对冲
- 风控模块逻辑:
。当当日亏损金额超过限制时,停止当日报价
。当单边的持仓量超过规定上限时,停止接受新的报价,并进行平仓操作。直到持仓数量减少至单边最大持仓量的四分之一时,重新开始接受报价
。当最新一分钟的价格波动超过设定的上限时,暂定本次报价
#### 5.2.2 做市策略实现
做市策略使用逐笔行情回测,策略信号触发使用快照行情,策略的委托订单撮合使用逐笔行情数据进行高精度的撮合(与行情订单按照价格优先、时间优先原则撮合订单)。
在策略初始化函数 initialize 中设置双边报价最大的买卖价差、报价金额等全局参数,同时订阅行情的最新一分钟的价格波动指标。该函数还有一个 userParam 参数,可通过该外部参数为策略参数赋值。
---
def initialize(mutable contextDict, userParam)\{
print("initialize")
---
5 - DolphinScript 编写回测策略
// 报价模块参数
contextDict["maxBidAskSpread"]=userParam["maxBidAskSpread"]//双边报价最大的买卖价差
...
\}
在 onSnapshot 策略回调函数中,根据风控规则进行买卖双边报价,并在持仓超限时进行平仓逻辑处理。在 onTrade 成交回报回调函数中对成交订单进行对冲。
---
def onTrade(mutable contextDict, trades)\{
// trades 为字典列表
///成交主推回调
///在这里处理对冲模块
hedgeOffsetAmount=contextDict["hedgeAmount"] // 对冲偏移金额
for (itrade in trades)\{
...
///下达对冲单
Backtest::submitOrder(contextDict["engine"], (stock, itrade.tradeTime,
5, price, vol, bsFlag),"hedgeOrder")
\}
\}
---
对科创版做市策略进行回测时,使用逐笔行情进行买卖双边报价,利用逐笔数据进行订单撮合,同时可以设置订单延时等。使用 replay 函数把逐笔成交、逐笔委托和快照数据按顺序异构回放到 tickHqTable 表中,然后可以通过接口 Backtest::appendQuotationMsg(engine, msg) 执行逐笔行情的策略回测。
---
userConfig=dict(STRING, ANY)
//逐笔行情
userConfig["dataType"]=0
//策略参数设置
userParam=dict(STRING, FLOAT)
userParam["maxBidAskSpread"]=0.03//双边报价最大的买卖价差
userParam["quotAmount"]=100000 ///报价金额
...
engine = Backtest::createBacktestEngine(strategyName, userConfig,,
initialize\{, userParam\}, beforeTrading,, onSnapshot, onOrder, onTrade, afterTrading,
finalize)
///开始执行回测
Backtest::appendQuotationMsg(engine, select * from tickHqTable)
---
打印部分成交明细如下
<table><tr><td>orderld</td><td>symbol</td><td>direction</td><td>sendTime</td><td>orderPrice</td><td>orderQty</td><td>tradeTime</td><td>tradePrice</td><td>tradeQty</td><td>orderStatus</td><td>label</td></tr><tr><td>1</td><td>688981.XSHG</td><td>1</td><td>2023.02.01T09:30:00.000</td><td>41.98000000</td><td>2,383</td><td>2023.02.01T09:30:00.170</td><td>0.0</td><td>0</td><td>4</td><td>MakingMakertOrder</td></tr><tr><td>2</td><td>688981.XSHG</td><td>2</td><td>2023.02.01T09:30:00.000</td><td>83.98500000</td><td>1,191</td><td>2023.02.01T09:30:00.170</td><td>0.0</td><td>0</td><td>4</td><td>MakingMakertOrder</td></tr><tr><td>2</td><td>688981.XSHG</td><td>2</td><td>2023.02.01T09:30:00.000</td><td>83.98500000</td><td>1,191</td><td>2023.02.01T09:30:00.120</td><td>41.99000..</td><td>1,191</td><td>1</td><td>MakingMakertOrder</td></tr><tr><td>3</td><td>688981.XSHG</td><td>4</td><td>2023.02.01T09:30:00.170</td><td>41.97000000</td><td>1,191</td><td>2023.02.01T09:30:00.260</td><td>0.0</td><td>0</td><td>4</td><td>hedgeOrder</td></tr><tr><td>1</td><td>688981.XSHG</td><td>1</td><td>2023.02.01T09:30:00.000</td><td>41.98000000</td><td>2,383</td><td>2023.02.01T09:30:00.260</td><td>41.98000..</td><td>45</td><td>0</td><td>MakingMakertOrder</td></tr><tr><td>1</td><td>688981.XSHG</td><td>1</td><td>2023.02.01T09:30:00.000</td><td>41.98000000</td><td>2,383</td><td>2023.02.01T09:30:01.770</td><td>41.98000..</td><td>237</td><td>0</td><td>MakingMakertOrder</td></tr><tr><td>4</td><td>688981.XSHG</td><td>3</td><td>2023.02.01T09:30:01.770</td><td>42.00000000</td><td>282</td><td>2023.02.01T09:30:01.930</td><td>0.0</td><td>0</td><td>4</td><td>hedgeOrder</td></tr><tr><td>1</td><td>688981.XSHG</td><td>1</td><td>2023.02.01T09:30:00.000</td><td>41.98000000</td><td>2,383</td><td>2023.02.01T09:30:02.250</td><td>41.98000..</td><td>200</td><td>0</td><td>MakingMakertOrder</td></tr><tr><td>5</td><td>688981.XSHG</td><td>3</td><td>2023.02.01T09:30:02.250</td><td>42.00000000</td><td>200</td><td>2023.02.01T09:30:02.390</td><td>0.0</td><td>0</td><td>4</td><td>hedgeOrder</td></tr><tr><td>1</td><td>688981.XSHG</td><td>1</td><td>2023.02.01T09:30:00.000</td><td>41.98000000</td><td>2,383</td><td>2023.02.01T09:30:02.750</td><td>41.98000..</td><td>463</td><td>0</td><td>MakingMakertOrder</td></tr><tr><td>1</td><td>688981.XSHG</td><td>1</td><td>2023.02.01T09:30:00.000</td><td>41.98000000</td><td>2,383</td><td>2023.02.01T09:30:02.750</td><td>41.98000..</td><td>537</td><td>0</td><td>MakingMakertOrder</td></tr><tr><td>。</td><td>20000 VIVIE</td><td>E</td><td>000101000000000000</td><td>temperature</td><td>100</td><td></td><td>0.0</td><td>-</td><td>IN</td><td></td></tr></table>
## 图5-3 部分成交明细
科创板做市策略的完整脚本见附录 5.2 科创版做市策略回测脚本。
#### 5.2.3 策略参数寻优
我们可以调整策略参数,包括最大买卖价差、报价金额、对冲偏移金额、风控模块的最大单边持仓上限、当日亏损上限金额和价格波动等指标,以对策略进行优化。对冲偏移金额和价格波动率的参数进行参数寻优的示例如下:
---
// step 3: 并行策略回测
jobs=array(STRING, 0, 10)
codes=(exec distinct(SecurityID) from loadTable("dfs://Level 2_t1","snapshot") where
SecurityID like "68%")[:10]
for(hedgeAmount in [0.01,0.02,0.03,0.04])\{
for(maxVolatility_1m in [0.03,0.04,0.05])\{
//策略参数设置
userParam=dict(STRING, FLOAT)
userParam["maxBidAskSpread"]=0.03//双边报价最大的买卖价差
userParam["quotAmount"]=100000 //报价金额
// 对冲模块参数
userParam["hedgeAmount"]=hedgeAmount//对冲偏移金额
//风控参数
userParam["maxPos"]=2000//最大单边持仓上限
userParam["maxLossAmount"]=200000 //当日亏损上限金额
userParam["maxVolatility_1m"]=maxVolatility_1m //最新一分钟
strategyName="marketMakingStrategy"
strategyName=strategyName+strReplace(concat(each(def(a, b):a+"_"+string(b),
userParam.keys(), userParam.values())),".","")
jobId=submitJob(strategyName, strategyName+"job", runBacktest_tick, userConfig,
initialize\{, userParam\}, beforeTrading,, onSnapshot, onOrder, onTrade,
afterTrading, finalize, strategyName, startDate, endDate, codes)
jobs=jobs.append!(jobId)
\}
\}
---
5 - DolphinScript 编写回测策略
我们对科创板做市策略的参数寻优进行了性能测试。股票池为 2023 年 02 月份 20 个交易日的科创版股票,对策略参数对冲偏移金额分别为 0.01、0.02、0.03、0.04 和最新一分钟的价格波动上限分别为 0.03、0.04、0.05 的总共 12 种场景并行回测,测试结果见表5-2。
表 5-2 科创板做市策略参数寻优性能测试结果
<table><tr><td>标的数量</td><td>数据量</td><td>数据回放平均耗时 (秒)</td><td>回测执行平均耗时 (秒)</td></tr><tr><td>1</td><td>309,588 行</td><td>3.5</td><td>11.4</td></tr><tr><td>100</td><td>34,618,130 行</td><td>184.8</td><td>909.6</td></tr></table>
### 5.3 股票中高频 CTA 策略回测
在中高频交易中,CTA 策略是一种预测价格走势的策略,可以抓住大单的动向。该策略的核心思想是在分析订单流信息或特定事件后,获取短期价格波动的大致方向,利用速度优势提前建仓,等待价格波动到预期水平后平仓。
基于 Level 2 快照数据和逐笔成交数据,实现以下的 CTA 策略逻辑:
•快照数据计算 MACD 指标,当 MACD 指标出现金叉之后,且满足下面两个条件之一时,执行买入:
。基于逐笔成交,成交价的过去 30 秒内的 CCI 指标从下向上突破+100线进入超买区间,并且过去 30 秒的成交量大于 50000 股时,买入 500 股。
。当成交价的过去 30 秒内 CCI 指标从下向上突破-100线时,买入 500股。
- MACD 指标死叉时,卖出
#### 5.3.1 策略实现
首先基于 Level2 快照定义 MACD 指标、基于 Level2 逐笔成交行情定义30秒内的 CCI 和成交量指标。回测引擎内部创建的是状态响应式引擎,因子指标定义的方式,可以具体参考状态响应式引擎用户手册。在策略初始化函数中,首先订阅基于 Level2 快照行情 MACD 指标、订阅基于成交行情的 30 秒的 CCI 和成交量指标。
---
def initialize(mutable contextDict)\{
print("initialize")
//订阅快照行情的指标
d=dict(STRING, ANY)
d["macd"]=<macd(lastPrice,240,520,180)[0]>
d["prevMacd"]=<macd(lastPrice,240,520,180)[1]>
Backtest::subscribeIndicator(contextDict["engine"], "snapshot", d)
d=dict(STRING, ANY)
d["cci"]=<myCCI(price, timestamp, orderType)[0]>
d["prevcci"]=<myCCI(price, timestamp, orderType)[1]>
d["tradeVol30s"]=<tradeVol30s(qty, timestamp, orderType)>
Backtest::subscribeIndicator(contextDict["engine"], "trade", d)
\}
---
在快照行情回调函数 onSnapshot 中,通过获取订阅的 MACD 指标记录买入卖出信号。在逐笔成交行情 onTick 中执行买入操作。
股票中高频 CTA 策略回测的完整脚本见附录 5.3 股票 CTA 策略回测脚本。
#### 5.3.2 性能测试
系统配置同5.2.3测试环境,对以上订阅三个指标的 CTA 策略,选取 2023.02 月份 20 个交易日的部分活跃标的。测试结果见表 5-3。
表 5-3 股票中高频 CTA 策略回测性能测试结果
<table><tr><td>标的数量</td><td>数据量</td><td>测试模式</td><td>总耗时(秒)</td><td>每个引擎数据回放平均耗时(秒)</td><td>每个引擎回测执行平均耗时 (秒)</td></tr><tr><td>1</td><td>309,588 行</td><td>单线程</td><td>11.1</td><td>0.6</td><td>10.5</td></tr><tr><td>50</td><td>18,702,208 行</td><td>按股票分成10 份、10个并行</td><td>163.4</td><td>21.2</td><td>142.2</td></tr></table>
### 5.4 期货分钟频 CTA 策略回测
当期货市场出现剧烈上涨或下行波动时,期货 CTA 策略往往能够有效从中获取收益,其原因主要在于期货资产买卖开的双向交易和 T+0 交易的制度优势,使得 CTA 策略能够快速适应市场环境并且更加直观地捕捉市场变化所带来的机遇。
本节基于 ATR(平均真实范围)和 RSI(相对强弱指数)结合的技术分析指标实现期货 CTA 策略。基于分钟频率数据,实现以下的 CTA 策略逻辑:
- 计算 1 分钟内标的的最高价、最低价与前收盘价的差值的绝对值 TR 指标,然后求得 TR 指标平均值,即 ATR。
- 用过去 10 分钟的收盘价数据计算 RSI 指标。
- 开仓:
。当 RSI 值大于 70 且 ATR 大于其 10 分钟均值时,买入开仓。
。当 RSI 值小于 30 且 ATR 大于其 10 分钟均值时,卖出开仓。
- 止损:
。持有多仓时,K 线达到最高点后,回落 0.004 时,卖平。
。持有空仓时,K 线达到最地点后,反弹 0.004 时,买平。
#### 5.4.1 策略实现
首先基于分钟频行情定义平均真实范围 ATR 和相对强弱 RSI 指标。回测引擎内部创建的是状态响应式引擎, 具体也可以参考状态响应式引擎用户手册定义相应的指标。在策略初始化函数中,首先订阅基于主连复权(平滑)处理之后的最高价、最低价和收盘价行情数据计算 ATR、过去 10 分钟的 ATR 均值指标和 RSI 指标。这里 signal 字段为数组向量,存储的数据分别为主连行情复权之后的最高价,最低价和最新收盘价。
---
def initialize(mutable contextDict)\{
d=dict(STRING, ANY)
d["TR"]=<atr(signal[0], signal[1], signal[2], 14,10)[0]>
d["ATR"]=<atr(signal[0], signal[1], signal[2], 14,10)[1]>
d["RSI"]=<rsi(signal[2], 14)>
Backtest::subscribeIndicator(contextDict["engine"], "kline", d)
\}
---
在 K 线行情回调函数 onBar 中,通过获取订阅的 ATR 和 RSI 指标进行买入卖出信号,在存在多仓或者空仓时,当行情回调时进行相应的止损操作。
---
def onBar(mutable contextDict, msg)\{
//行情回测,编写策略逻辑
for(istock in msg.keys())\{
longPos=Backtest::getPosition(contextDict["engine"], istock).longPosition[0]
shortPos=Backtest::getPosition(contextDict["engine"], istock).shortPosition[0]
price=msg[istock]["close"]
//没有多头持仓,并且多头趋势时,买入
if(longPos<1 and shortPos<1 and msg[istock]["ATR"]>msg[istock]["mATR"] and
msg[istock]["RSI"]>contextDict["buySignalRSI"] and msg[istock]["mATR"]>0)\{
Backtest::submitOrder(contextDict["engine"],
(istock, msg[istock]["symbolSource"], contextDict["tradeTime"],5,
price+0.02, 0., 2, 1, 0),"buyOpen")
contextDict["highPrice"][istock]=price
continue\}
//没有空头持仓,并且空头趋势时,卖出
if(longPos<1 and shortPos<1 and msg[istock]["ATR"]>msg[istock]["mATR"] and
msg[istock]["RSI"]<contextDict["sellSignalRSI"] and msg[istock]["mATR"]>0)\{
Backtest::submitOrder(contextDict["engine"],
(istock, msg[istock]["symbolSource"], contextDict["tradeTime"],5,
price-0.02, 0., 2, 2, 0),"sellOpen")
contextDict["lowPrice"][istock]=price
continue\}
if(longPos>0 and price>contextDict["highPrice"][istock])\{//更新最高价
contextDict["highPrice"][istock]=max(price,
contextDict["highPrice"][istock])\}
else if(longPos>0 and
price<=contextDict["highPrice"][istock]*(1-contextDict["closeLine"]))
\{//平仓
Backtest::submitOrder(contextDict["engine"],
---
---
(istock, msg[istock]["symbolSource"], contextDict["tradeTime"],5,
price-0.02, 0., 2, 3, 0),"sellClose")\}
if(shortPos>0 and price<contextDict["highPrice"][istock])\{//更新最低价
contextDict["lowPrice"][istock]=max(price,
contextDict["lowPrice"][istock]])
else if(shortPos>0 and
price>=contextDict["highPrice"][istock]*(1+contextDict["closeLine"]))\{//平仓
Backtest::submitOrder(contextDict["engine"],
(istock, msg[istock]["symbolSource"], contextDict["tradeTime"],5,
price+0.02, 0., 2, 4, 0),"buyClose")\}
\}
\}
---
创建期货回测时,需要用户配置期货合约的基本信息表,包括期货合约的合约乘数、交易单位、手续费和手续费的计费方式的 (按手数计费或者按成交金额计费) 等,具体配置可见回测引擎接口说明文档。
期货分钟频 CTA 策略回测的完整脚本见附录 5.4 期货 CTA 策略回测脚本。
#### 5.4.2 性能测试
系统配置同5.2.3测试环境,使用 2023 年 2 月份的期货 1 分钟频数据,1 个线程测试结果见表 5-4。
表 5-4 期货分钟频 CTA 策略回测性能测试结果
<table><tr><td>标的数量</td><td>订单数 (笔)</td><td>总耗时 (秒)</td></tr><tr><td>1 只主力合约 1 个月, 12,232 行数据</td><td>19</td><td>0.6</td></tr><tr><td>77 只主力合约 1 个月, 597,316 行数据</td><td>1,792</td><td>24</td></tr></table>
### 5.5 银行间债券双边跟随最优价做市策略
#### 5.5.1 银行间债券回测和撮合引擎介绍
中国债券市场是全球第二大债券市场,存量规模突破 130 万亿元,形成以银行间和交易所市场为主,柜台市场为补充的市场格局。银行间债券市场成立于 1997 年,经过 20 余年发展,市场规模稳步增长,融资功能持续增强,市场参与主体与投资品种不断丰富,金融基础设施不断完善,对外开放稳步推进。截至 2021 年 12 月末,银行间债券市场托管余额近 115 万亿元,年内交易量突破 1400 万亿元,市场参与主体近 3800 家,是中国债券市场最主要的构成部分,是国债、政策性金融债以及同业存单等国际投资者最为关注券种的主要流通市场。
因此,为了满足对于债券回测功能的需求,回测插件基于 DolphinDB 模拟撮合功能也为债券提供了订单撮合的支持,可以基于深度报价快照行情和成交行情数据进行 tick 级策略回测。在回测和撮合上使用了高频数据, 能够更加精准的反映真实的市场波动和成交状况,为策略投研提供更加精确的工具。
5 - DolphinScript 编写回测策略
作为国内债券市场的最重要组成部分,目前 DolphinDB 对于银行间债券品种的支持主要是基于外汇交易中心 X-Bond 匿名点击行情的债券, X-Bond 匿名点击方式是指交易双方提交匿名的限价订单,订单撮合逻辑根据授信情况按照价格优先、时间优先原则自动匹配成交的交易方式。
同时,模拟撮合引擎对于债券也提供了多样的订单方式,订单方向既支持传统的买卖,也可以支持双边同时挂单,方便双边做市商报价的时候使用。另外,除了常见的回测收益风险指标,如收益率,夏普比,波动率,回撤等之外,引擎中也提供了很多债券专有的指标的统计,如持仓总量,应计利息,浮动损益,实际损益,久期,凸性,DV01 等,方便用户对自己的持仓及损益和风险有更加精准的把握。债券回测引擎的具体信息可以详见:MatchingEngineSimulator
#### 5.5.2 策略实现
因为银行间债券市场实行做市商制度,因此本节将以做市策略中最为普遍的双边跟随最优价行情报价做市策略为例,基于X-Bond深度行情,进行策略回测:
首先,加载会侧重所需的对应债券的基础信息表到引擎中取,因为引擎中很多指标的计算都要依赖于基础信息表的信息。这一步骤其实并不是策略编写所必需的,等后续如果工程化实现的过程中,公司it适配之后,就可以定义为函数视图的形式,无需再额外自行导入。
---
def getFICCBondBasicInfo()\{
//加载基础信息表,公司it适配之后,定义为函数视图的形式
basicInfo = table(2:0, `symbol` couponRate`valueDate`maturityDate`frequency,
[STRING, DOUBLE, DATE, DATE, INT])
insert into basicInfo values("230012", 1.65, 2022.01.01, 2024.01.01,1)
insert into basicInfo values("230410", 1.65, 2022.01.01, 2024.01.01,1)
insert into basicInfo values("230311", 1.65, 2022.01.01, 2024.01.01,1)
insert into basicInfo values("230305", 1.65, 2022.01.01, 2024.01.01,1)
return basicInfo
\}
---
其次,在 onTick 事件中,对获取到的多档位的深度行情进行筛选和判断,确认不存在空值和负价等异常行情后,就可以调用 submitOrder 下单接口,将双边跟随的做市订单报价根据买卖一档行情最优价加减一定的点差之后报出去。
---
def onTick(mutable contextDict, msg)\{
/*
230012->tradeTime->2023.09.18T09:02:46.726
symbol->230012
messageSource->cfets
byield->[2.67,2.67,...,]
ayield->[,,,,,,]
bmdEntryPrice->[99.9979,99.9979,...]
amdEntryPrice->[,,,, , ]
bmdEntrySize->[50000000,50000000,...]
amdEntrySize->[, , , , ,]
bsettlType->[2, 2, , , , ]
asettlType->[2, , , , ,]
settlType->[001]
---
---
tradePrice->[00F]
tradeYield->[00F]
tradeQty->[001]
*/
//print("onTick")
//print msg
//Backtest::cancelOrder(contextDict["engine"],,,"baojiea")
for (istock in msg.keys())\{
price=msg[istock]["bmdEntryPrice"][0]
// 先判断 是否存在空值
if(any([price]<=0) or any(isNull([price])))\{
continue
\}
settlType=msg[istock]["bsettlType"][0]
istock=msg[istock]["symbol"]
Backtest::submitOrder(contextDict["engine"],
(istock, contextDict["tradeTime"], 1,
int(settlType), price+0.05, long(1000), 0.0, long(0), 1,1,"X_BOND"),"baojia")
\}
\}
---
#### 5.5.3 性能测试
系统配置同5.2.4测试环境,使用 2023 年 9 月份的 X-Bond 高频深度行情数据,1 个线程测试结果见表 5-5。
表 5-5 银行间债券双边跟随最优价做市策略回测性能测试结果
<table><tr><td>标的个数</td><td>订单数(笔)</td><td>成交数(笔)</td><td>总耗时(秒)</td></tr><tr><td>1 只活跃券 01 个月, 4,537,195 行数据</td><td>459,060</td><td>1001</td><td>16</td></tr><tr><td>4 只活跃券1 个月, 9,740,880 行数据</td><td>985,656</td><td>995</td><td>30</td></tr></table>
## 第 6 章. Python Parser 编写回测策略
Python Parser 是 Python 语言的 DolphinDB 实现。通过 Python Parser,用户可以在 DolphinDB 支持的编程 IDE 中用 Python 语言编写脚本,然后提交给 DolphinDB Server 进行解析执行并得到结果。
在策略研究和回测方面,Python 是一种非常流行的语言。Python 具有易用性和灵活性,能够快速地进行原型开发和回测测试。DolphinDB 的中高频回测引擎也支持使用 Python Parser 实现中高频策略的开发。
Python Parser 完全遵循 Python 语言的标准,包括语法,数据类型,数据结构等。Python Parser 也可以把 DolphinDB 当作一个外部包,调用其数据结构和函数等。这种调用方式完全类似 Python 中调用 numpy 包中的数据结构或函数。但由于 DolphinDB 中的数据结构和数据类型不能与 Python Parser 一一对应,在使用 Python Parser 编写程序时,有一些区别需要注意。
•如果需要使用 DolphinDB 中的数据类型,枚举类型,数据结构和函数,需要加上包的名称,例如 ddb.SYMBOL 表示 DolphinDB 中的 SYMBOL 类型。
- 在调用 DolphinDB 的内置函数时,需要将 Python 中的数据结构通过 toddb 方法转换成 DolphinDB 中的数据结构。下面的例子中,在调用建表函数 createPartitionedTable 时,需要将参数 partitionColumns, compressMethods 和 sortColumns 通过 toddb 方法, 将 Python 中的列表、字典、列表结构分别转换为 DolphinDB 中的向量、字典、向量结构。
---
db.createPartitionedTable(schemaTB, tbName,
partitionColumns=["datetime", "SecurityID"].toddb(),
compressMethods=\{"datetime":"delta"\}.toddb(),
sortColumns=["SecurityID","datetime"].toddb(), keepDuplicates=ddb.ALL)
---
- Python 本身没有数组类型,在 Pyhon Parser 中创建数组向量指定数据类型时,可在 DolphinDB 的数据类型后加上" + 64 ",例如:ddb.DOUBLE + 64。
- Python Parser 中回测插件的函数暂时不支持关键字参数的用法。调用函数时需按照函数定义的参数顺序输入参数,如需使用可省略参数的默认值,在该参数位置上用 “None” 占位。
- 回测引擎中订阅指标时暂时不支持 Python 自定义的函数定义指标,只支持使用 DolphinDB 内置的函数。通过如下方式订阅指标,可以在 onSnapshot 函数中获取最新价的指数加权移动平均值 "ewmMean":
---
d = dict()
d["ewmMean"] = <round(ewmMean(lastPrice, 240, False),4)>
backtest.subscribeIndicator(contextDict["engine"], "snapshot", d.toddb())
---
### 6.1 Python Parser 脚本改写策略回测
5.1 章节的动态网格策略 onSnapshot 回调函数和执行回测的代码,在 Python Parser 中转换如下。在 Python Parser 中,DolphinDB 被以库的形式加载,回测插件也以库的形式被加载。调用回测插件接口时,使用和 Python 一致的 backtest.func 格式,如 backtest.appendQuotationMsg()。
import backtest
import dolphindb as ddb
import pandas as pd
userConfig=dict(STRING, ANY)
userConfig["startDate"]=startDate
userConfig["endDate"]=endDate
//策略初始资金设置
userConfig["cash"]= 100000000
...
engine = backtest.createBacktestEngine(strategyName, userConfig.toddb(), None, initialize, beforeTrading, None, onSnapshot, onOrder, onTrade, afterTrading, finalized)
...
snapshotTable = getSnapShotHqData(startDate, endDate, codes, 2)
backtest.appendQuotationMsg(engine, snapshotTable)
### 6.2 Python Parser 和 DolphinScript 的性能对比
这里使用 Python 语言实现了第 5 章的网格交易、做市商和股票 CTA 这三个策略,具体脚本见附录 6.1 Python parser 策略实现脚本。使用单线程测试了 Python 和 DolphinScript 实现策略的性能。测试结果见表 6-1,这里的时间是策略执行整体的总耗时,包含了行情数据查询和数据处理的耗时。从实验结果可知,DolphinScript 回测性能比 Python 更优。这归根于 Python Parser 大量调用 DolphinScript 内置函数时,需要作数据结构的转换。
表 6-1 Python Parser 和 DolphinScript 实现策略回测时的性能对比
<table><tr><td>策略</td><td>数据量</td><td>Python Parser 耗时 (秒)</td><td>DolphinScript 耗时(秒)</td></tr><tr><td>网格交易策略</td><td>10 只股票 3 个交易日,7.6 万行数据</td><td>7.7</td><td>4.7</td></tr><tr><td>做市商策略</td><td>1 只科创版股票 2 个交易日,2.7 万行数据</td><td>5.8</td><td>4.5</td></tr><tr><td>股票 CTA 策略</td><td>5 只创业板股票 3 个交易日,77 万行数据</td><td>5.5</td><td>3.9</td></tr></table>
## 第 7 章. C++ 编写回测策略
DolphinDB 中高频策略回测引擎已经使用 C++ 来编写实现。如果希望进一步提升中高频策略回测的性能, 可以使用 C++ 来实现事件回调函数。用 C++ 编写回调函数,有两种做法。第一个方法,用 C++ 开发一个 DolphinDB 插件,在插件中实现回测引擎需要的回调函数。第二个方法,自己开发一个 C++ 应用程序,并引入嵌入式版本 Swordfish (也就是以动态库形式封装了 DolphinDB 的核心功能),然后用 C++ 编写事件回调函数,最后在 Swordfish 中加载回测插件。
第二种方法赋予用户更大的灵活性,可以让用 C++ 开发的量化程序与 DolphinDB 紧密的集成,本章采用了第二种实现方法。C++通过 Swordfish 调用回测插件或者 DolphinDB 函数库的架构如图 7-1 所示。

图 7-1 Swordfish 实现策略回测的程序架构图
Swordfish 的提供形式为 C++ 共享库,可以嵌入到用户自定义的 C++ 程序中作为 DolphinDB 的客户端,提供 DolphinDB 丰富的函数供用户直接使用。通过 Swordfish 调用回测插件,可以订阅 DolphinDB Server 上的流表,将流数据写入到回测引擎,输出成交明细等结果。开发者可以在自定义 C++ 程序中使用回测引擎的接口、输出结果,以及调用 DolphinDB 的丰富的函数来实现自己的业务逻辑。
使用 Swordfish 调用回测引擎有的优势包括:
- C++ 本身的性能优势,比 DolphinScript 性能更优。
- 相较于 C++ SDK,SwordFish 可以调用 DolphinDB 的丰富的函数库。
- Swordfish 能够更方便地集成到现有的量化交易系统中以及充分利用本地资源。
### 7.1 C++ 策略实现
C++ 程序通过如下步骤调用并执行回测:
- 初始化 DolphinDB
- 加载模拟撮合和回测插件
- 获取各事件函数的定义
·创建回测引擎
- 获取参与回测的代码列表
- 从远端 DolphinDB 获取行情数据
- 回测结束之后,查看交易明细、每日持仓信息
完整的 C++ 实现代码见附录 7.1 频策略回测案例 Swordfish 代码。
接下来我们将详细介绍每一个步骤。
## 初始化 DolphinDB
要在 C++ 进程内调用 DolphinDB 相关功能,首先需要初始化
---
DolphinDBLib: : initializeRuntime();
---
然后创建或者打开一个数据库,并创建一个到该数据库的连接
---
oltp::DBOption option;
shared_ptr<DB> db = make_shared<DB>("test_db", option);
Connection conn(*db);
---
## 加载模拟撮合和回测插件
connection 类的 execute 可以用来执行 DolphinDB 语句,加载模拟撮合和回测插件。
---
conn.execute("loadPlugin('MatchingEngineSimulator')");
conn.execute("loadPlugin('Backtest')");
---
## 获取各事件函数的定义
如第 4 章所述,创建回测引擎时需要传入各个事件函数,而事件函数中定义了策略的逻辑。我们在 C++ 中提前定义了各个事件函数,具体可以参见附录中的代码。
以 onSnapshot 函数为例,回测引擎需要的 onSnapshot 函数有两个入参,分别是 contextDict 和 msg。msg 中传入的是最新的快照信息。onSnapshot 函数根据最新的快照信息和策略逻辑执行买入卖出操作。买入卖出操作使用如下代码:
7 - C++ 编写回测策略
---
SmartPointer<BacktestEngineWrapper> engine =
new BacktestEngineWrapper(heap, contextDict->getMember("engine"));
engine->submitOrder(istock, contextDict->getMember("tradeTime"), new Int(5),
lastPrice, new Long(qty), new Int(1), new Int(0), "buy");
---
与3.3节类似,我们定义了一个 BackTestEngineWrapper 类,其中包含了和回测插件接
口,如 createBackTestEngine、appendQuotationMsg、submitOrder 等交互的逻辑。
BacktestEngineWrapper 类的构造函数如下:
---
BacktestEngineWrapper::BacktestEngineWrapper(Heap *heap, const string &strategyName,
const DictionarySP &userConfig,
const TableSP &basicInfo,
const FunctionDefSP &initialize,
const FunctionDefSP &beforeTrading,
const FunctionDefSP &onTick,
const FunctionDefSP &onSnapshot,
const FunctionDefSP &onOrder,
const FunctionDefSP &onTrade,
const FunctionDefSP &afterTrading,
const FunctionDefSP &finalized)
: heap_(heap) \{
FunctionDefSP createBacktestEngineFunc =
heap_->currentSession()->getFunctionDef("Backtest::createBacktestEngine");
std::vector<ConstantSP> args = ...;
engine_ = createBacktestEngineFunc->call(heap_, args);
BacktestEngineWrapper::BacktestEngineWrapper(Heap *heap,
ConstantSP rawEngine) : heap_(heap), engine_(rawEngine) \{\}
---
\}
onSnapshot 中使用了第二种构造方式,获取回测引擎实例,然后构造了一个新的 BacktestEngineWrapper 对象, 之后调用 BacktestEngineWrapper 类的 submitOrder 函数进行下单, 代码如下:
---
ConstantSP onSnapshot(Heap *heap, vector<ConstantSP> &arguments) \{
// ...
SmartPointer<BacktestEngineWrapper> engine =
new BacktestEngineWrapper(heap, contextDict->getMember("engine"));
engine->submitOrder(istock, contextDict->getMember("tradeTime"),
new Int(5), lastPrice, new Long(qty), new Int(1), new Int(0), "buy");
// ...
\}
---
submitOrder 函数中调用回测引擎的 submitOrder 接口,实现如下:
---
FunctionDefSP submitOrderFunc =
heap_->currentSession()->getFunctionDef("Backtest::submitOrder");
std::vector<ConstantSP> args = ...
VectorSP ret = submitOrderFunc->call(heap_, args);
---
定义各事件函数之后,我们利用 Util 类中的 createSystemFunction 将其转化为可以作为回测引擎可接受的参数。createSystemFunction 中的第3、4个参数分别为最小参数数量和最大参数数量。因为 initialize、beforeTrading、afterTrading、finalized 只有1个入参,而 onSnapshot、onOrder、 onTrade 函数有2个入参,所以转化逻辑如下:
---
initializeFunc = Util::createSystemFunction("_", initialize, 1, 1, false);
beforeTradingFunc = Util::createSystemFunction("_", beforeTrading, 1, 1, false);
onSnapshotFunc = Util::createSystemFunction("_", onSnapshot, 2, 2, false);
onOrderFunc = Util::createSystemFunction("_", onOrder, 2, 2, false);
onTradeFunc = Util::createSystemFunction("_", onTrade, 2, 2, false);
afterTradingFunc = Util::createSystemFunction("_", afterTrading, 1, 1, false);
finalizedFunc = Util::createSystemFunction("_", finalized, 1, 1, false);
---
## 创建回测引擎
我们通过新建一个 BacktestEngineWrapper 对象来创建回测引擎
---
SmartPointer<BacktestEngineWrapper> engine = new BacktestEngineWrapper( )
conn.getCurrentSession()->getHeap().get(), strategyName, userConfig, basicInfo,
initializeFunc, beforeTradingFunc, onTickFunc, onSnapshotFunc, onOrderFunc,
onTradeFunc, afterTradingFunc, finalizedFunc);
---
如上所示,BacktestEngineWrapper 构造函数中,调用回测插件的 createBacktestEngine 接口,创建回测引擎。
## 获取参与回测的代码列表
用户运行这个程序时可以传入一个存储了代码列表的文本文件的路径,如果不传入,则使用程序内部预先定义的代码列表
---
if (argc > 1) \{
const string codesFilePath = argv[1];
// 需要指定路径,这里指定为当前路径
codes = ExUtil::getCodesFromTextFile(conn, codesFilePath);
\} else \{
codes = ExUtil::createStringVector(\{"127056SZ",...,"128101SZ"\});
\}
---
## 从远程的 DolphinDB Server 获取行情数据
具体步骤为三步:连接到数据所在的 DolphinDB 节点;在该节点创建流表,并订阅该流表;将回测所需的数据回放至该流表。我们将这些步骤封装成了函数,放入了 ExUtil 类中。调用方式如下:
//连接远程DDB服务
ExUtil::connectDdb(conn, ip, port, username, password);
---
// 创建远程流表
ExUtil::createRemoteTable(conn, tableName);
// 订阅远程流表
FunctionDefSP handler = Util::createSystemFunction("_", handleStreamDataWrapper,
1, 1, false);
ExUtil::subscribeRemoteTable(conn, tableName, handler);
// 回放远程流表
ExUtil::replayRemoteTable(conn, tableName, codes, startDate, endDate);
---
其中,handler 函数为订阅的回调函数,会处理来自上游流表的数据。handler 函数由
handleStreamDataWrapper 转化而来,而 handleStreamDataWrapper 调用了 handleStreamData 函数,handleStreamData 函数通过调用 BacktestEngineWrapper 类的 appendQuotationMsg, 调用回测引擎的 appendQuotationMsg 接口:
---
engine->appendQuotationMsg(msg);
---
## 查看交易明细、每日持仓信息
与3.3节类似,我们调用 BacktestEngineWrapper 中的 getTradeDetails、getDailyPosition 接口,查看回测的交易明细、每日持仓信息。
---
std::cout << "getTradeDetails!!!!" << std::endl;
TableSP ret1 = engine->getTradeDetails();
std::cout << ret1->getString() << std::endl;
conn.getCurrentSession()->getHeap()->addItem("ret1", ret1);
std::cout << conn.execute("select count(*) from ret1")->getString() << std::endl;
std::cout << "getDailyPosition!!!!" << std::endl;
TableSP ret2 = engine->getDailyPosition();
std::cout << ret2->getString() << std::endl;
---
### 7.2 C++和 DolphinScript 的性能对比
Swordfish 和 DolphinDB 使用相同的配置,性能测试结果见表 7-1,其中平均耗时去掉了取数据的耗时。可见 Swordfish 回测性能比 DolphinDB 更优,原因是 C++ 采用编译执行,比脚本的解释执行更有性能优势。
表 7-1: Swordfish和 DolphinDB 回测的性能对比
<table><tr><td>环境</td><td>数据量</td><td>平均耗时(秒)</td></tr><tr><td>Swordfish 8 核</td><td>2 天,1000 只标的,逐笔数据(31,473,071 行)</td><td>17.8</td></tr><tr><td>DolphinDB 8 核</td><td>2 天,1000 只标的,逐笔数据(31,473,071 行)</td><td>24.2</td></tr></table>
采用 C++ 后的优势并不是很大,远远小于通常 C++ 语言和脚本语言的差距。原因有两个。首先整个回测的耗时包括了数据回放、模拟撮合和回测引擎三部分。数据回放,模拟撮合以及回测引擎的框架部分,都通过 C++ 开发,两者之间并没有区别,唯一的区别在于事件回调函数部分。其次,回调函数的接口参数和返回值使用的都是 ConstantSP 类型,这是 DolphinDB 脚本中所有数据结构的基类。这种通用结构的创建、调用和销毁操作,相比 C++ 原生的 double、int、指针、数组等基本数据类型,其成本要大很多,从而削弱了 C++ 的性能优势。
## 第 8 章. 总结和展望
本文展示了如何通过 DolphinDB 的回放、回测和模拟撮合模块,构建一个中高频量化策略回测平台,并通过四个具体的回测案例:动态网格交易策略、科创板做市策略,股票中高频 CTA 策略和期货分钟频 CTA 策略, 展示了回测平台的用法和特点:
・性能极佳:如上文所示,回放、模拟撮合引擎、回测引擎皆拥有优异的性能。
·一站式解决方案:DolphinDB 将历史数据回放、模拟撮合引擎、回测引擎这 3 个模块化的功能组合在一起,形成了一个一站式的解决方案。当用户获得了基本的行情数据,只需在 DolphinDB 中就可以完成回测框架的构建,无需依赖于其它程序。
- 扩展性强:各个组成部分模块化的特点,使得它们也可以很容易和外部的解决方案结合。比如:用户已自行搭建了模拟撮合和回测框架,则可结合 DolphinDB 的回放功能,使用中高频历史数据进行回测;用户也可以将其回测框架编写为 DolphinDB 插件或者通过 Swordfish 实现量化交易一体化平台, 使其可以直接调用 DolphinDB 的模拟撮合引擎;用户还可以在C++程序中嵌入 Swordfish,直接使用 DolphinDB 回测引擎,搭建回测框架。
- 灵活的开发语言支持:策略开发支持 C++、DolphinDB 脚本及 Python 语言。C++ 性能最佳,需要处理大规模数据和进行中高频交易时具有优势;而 Python 的语法易于学习和理解,有助于快速原型开发和迭代。而 DolphinDB 的回测解决方案让用户可以根据自身情况进行选择。
- 开发效率高:从第 5 章的 4 个例子可以看出,虽然实现的是不同的策略,但是核心框架都是一致的, 先调用 initialize 初始化策略相关配置及订阅指标,再调用 onSnapshot 等事件函数编写策略,再创建回测引擎,并写入行情开始回测,最后获得相关结果。高效率的框架开发可以让研究员专心于策略的开发。
后续,我们将在功能和性能两个方面继续完善中高频量化策略回测平台。在功能上,支持期权以及数字货币的回测,支持融资融券功能。在性能上,除了优化 C++ 代码提升性能外,将引入 JIT 技术,提升事件回调函数脚本执行的性能。
## 第 9 章. 附录
- 2.1 单表数据回放脚本
。2.1-singleTableReplay.dos
。单表回放到插件,见 plugin_trading_algo.zip 的 countDemo_single.dos
。单表回放到 Swordfish, 见 swordfish_test.zip 的 handleSingleStreamData 方法
。单表回放到 API,见 cplusplus_api_test.zip 的 SingleReplayRunnable 类
- 2.2 异构多表数据回放脚本
。异构多表回放到插件,见 plugin_trading_algo.zip 的 countDemo.dos
。异构多表回放到 Swordfish, 见 swordfish_test.zip 的 handleMultiStreamData 方法
。异构多表回放到 API,见 cplusplus_api_test.zip 的 MultiReplayRunnable 类
- 3.2 完整示例代码:3.2-demo.dos
- 3.3 模拟撮合引擎算法交易策略回测案例代码:
。自定义插件调用模拟撮合引擎实现 TWAP 算法见 plugin_trading_algo.zip 的 algoOrderDemo.dos
- 4.5 完整示例代码:4.5-demo.dos
- 5 策略回测行情数据回放共用脚本以及数据:backtestUtils.dos 和 data.zip
- 5.1 网格策略回测脚本:gridStrategy.dos
- 5.2 科创版做市策略回测脚本:marketMakingStrategy.dos
- 5.3 股票 CTA 策略回测脚本:CTAstrategy.dos
- 5.4 期货 CTA 策略回测脚本:futureCTAStrategy.dos
- 5.5 银行间债券双边跟随最优价做市策略脚本:interbankBonddemo.dos
- 6.1 Python parser 策略实现脚本
- gridStrategy_Python.dos
- marketMakingStrategy_Python.dos
。CTAStrategy_Python.dos
- 7.1 频策略回测案例 Swordfish 代码
。Swordfish 调用回测引擎见 swordfish_backtest.zip
。Swordfish 调用模拟撮合引擎见 swordfish_matchEngineSimulator.zip
FILE:references/whitepapers/database.md
# DolphinDB 白皮书 数据库篇

## 内容
前言. iv
第 1 章. 概述. .5
1.1 典型场景和客户 5
1.2 主要功能和特点 .6
1.3 支持平台和部署 .8
第 2 章. 分布式架构. .9
2.1 集群网络架构. 9
2.2 数据分区机制 10
2.3 分布式事务. 11
2.4 计算与存储分离 13
第 3 章. TSDB 存储引擎. 14
3.1 排序列. 14
3.2 存储结构. 15
3.3 数据压缩. .16
3.4 数据写入 .16
3.5 数据查询 .17
3.6 数据更新及删除 18
3.7 TSDB 适用场景. .19
第 4 章. OLAP 存储引擎 .20
4.1 存储结构. 20
4.2 数据压缩. .21
4.3 数据写入 .21
4.4 数据查询 .21
4.5 数据更新及删除 .21
4.6 OLAP 适用场景. 22
第 5 章. SQL 和库内计算 23
5.1 SQL 23
5.2 多范式编程 24
5.3 分布式计算 25
5.4 实时流处理. 26
第 6 章. 安全与容灾 .28
6.1 高可用 28
6.2 备份恢复 .30
6.3 异步复制. .31
6.4 权限管理. .32
6.5 审计操作. .32
第 7 章. 运维. 34
7.1 运维函数库. 34
内容 | iii
7.2 作业管理. 34
7.4 性能监控. 35
第 8 章. 生态 37
8.1 API. 37
8.3 集成开发环境. 38
8.4 可视化 39
8.5 作业调度工具 39
8.6 信创支持. .40
## 前言
在信息技术的新时代,物联网、大数据、人工智能等新兴领域正以空前的速度推动社会进步,数据成为至关重要的生产要素。DolphinDB,作为一个开创性的分布式时序数据库,专为高效管理时间序列数据而设计。DolphinDB,不仅可以处理 PB 级的结构化数据,更将时间线的查询响应时间缩短至毫秒级,读写速度比传统数据库快百倍。在重塑数据处理速度极限的同时,DolphinDB 重新定义了企业对数据的掌控能力。
DolphinDB 提供的多范式编程语言和丰富的内置函数库,极大地简化了复杂数据分析的过程,使得企业能够以前所未有的速度和精确度进行决策分析,从而在激烈的市场竞争中占据先机。其创新的流处理引擎不仅支持高吞吐量和低延迟的实时数据分析,更通过流批一体的设计显著降低了企业的开发与运维成本。此外,DolphinDB 的分布式架构支持 ACID 事务机制,确保了数据的一致性;其高可用架构和数据恢复技术确保了业务的持续运行。
DolphinDB 不仅为企业提供了一套全方位的海量数据处理解决方案,更以其高吞吐、低延迟、安全可靠的特性赋予企业在市场中快速响应的能力,从而保持并扩大其竞争优势。在数据驱动的未来,DolphinDB 正引领着一场关于数据处理和分析的全新革命。
本白皮书将全面详细地介绍 DolphinDB 数据库,旨在帮助用户全面了解其技术优势和商业价值。主要涵盖以下几个方面:
- 功能特点与平台支持
- 分布式架构与事务支持
- 多模存储引擎及适用场景
- SQL 与库内计算
- 安全与容灾
- 运维与生态
## 第 1 章. 概述
DolphinDB 是由浙江智臾科技有限公司(以下简称智臾科技)自主研发的,基于高性能时序数据库的现代化时序数据处理技术栈,底层代码全部由 C++ 实现。
DolphinDB 以时序数据为主要入口,兼顾多模态数据的存取,支持分布式事务、高可用架构、存算分离灵活扩容等特性,提供强大的批计算引擎、开发便利的低延时流计算引擎,内置功能强大的多范式编程语言和基础函数库,允许用户或第三方通过插件扩展领域特色功能,为金融与物联网等行业用户在时序大数据领域提供一站式的、产研一体的商业化解决方案。
DolphinDB 以其产品能力不断获得国际权威第三方分析机构的关注和认可。2022年,DolphinDB 入选 Gartner 发布的《中国数据库管理系统供应商甄选》报告;2023年,DolphinDB 入选 Gartner 发布的《Hype Cycle for Data, Analytics and Al in China, 2023》、《中国数据库市场指南》报告。此外,根据国际数据库排名机构 DB-Engines 2024年3月的排名,DolphinDB 在全球时序数据库中排名第六、在国内排名第一。
DolphinDB 以其产品能力不断获得国际权威第三方分析机构的关注和认可。2022年,DolphinDB 入选 Gartner 发布的《中国数据库管理系统供应商甄选》报告;2023年,DolphinDB 入选 Gartner 发布的《Hype Cydle for Data, Analytics and Al in China, 2023》、《中国数据库市场指南》报告。此外,根据国际数据库排名机构 DB-Engines 在2023年10月的排名,DolphinDB 在全球时序数据库中排名第六、在国内排名第一。
### 1.1 典型场景和客户
DolphinDB 可应用于涉及时序数据处理的诸多行业和场景,包括银行、券商、公募基金、私募基金、交易所等金融机构的投研、交易和风控场景,以及电力、能源、化工、工业制造、供水、快速消费品等行业的数据存储、分析、设备监控和预警等场景。下图列举了 DolphinDB 的部分代表客户。
1 - 概述
## 图 1. 合作伙伴

### 1.2 主要功能和特点
DolphinDB 分布式时序数据库产品主要特点如下:
## 分布式架构
- 自研的分布式存储机制,数据存储在不同的数据节点上,由控制节点统一管理所有分区的元数据信息, 包括分区和副本信息、分区版本号等,保证各节点上分区数据和副本的一致性,提高集群的容错性和可扩展性。
·提供在线和离线扩展方式、支持横向(添加更多节点)和纵向(增加单个节点的资源)扩展系统、支持数据迁移和再平衡。
- 提供控制节点、数据节点和客户端的高可用方案。
- 提供全面灵活的备份和恢复机制。
- 提供高容错性的异步复制方案。
## 多模存储引擎
・支持内存表和 OLAP、TSDB 分布式存储引擎。分别满足不同场景需求:OLAP 引擎采用列式存储,以实现对海量数据的高效查询,特别适用于读取某列进行聚合分析;TSDB 引擎采用 PAX 行列混存,为海量数据提供高效的点查分析性能。
- 支持事务的 ACID。提供快照级别的隔离机制。
- 支持多种无损数据压缩算法,包括 LZ4、delta-of-delta、zstd、字典压缩等,压缩率可达4:1~10:1。
- 支持分级存储,有效区分热数据和冷数据存储,减少存储成本、提高数据可用性。
## 批计算处理
・使用内嵌的分布式文件系统自动管理分区数据及其副本,为分布式计算提供负载均衡和容错能力。
・内置1500多个函数,亦支持自定义函数,适用于多种应用场景。
- 分布式计算框架集成了多种计算模型,包括 pipeline、map-reduce 和迭代计算。
- SQL 语言与函数、表达式结合,支持向量化计算,可以在数据库中进行复杂的数据分析及运算。
- 充分利用多机多核 CPU 资源,高效并行处理海量数据。
## 流数据处理
·支持通过流数据表进行流数据订阅与发布。
-实现亚毫秒级的信息延迟。
·内置时间序列聚合、横截面处理、响应式状态处理、异常检测、多表关联等流式增量计算引擎,提供滑动窗口、累计窗口、统计函数等算子。可通过串联调用计算引擎构建计算流水线,或借助流数据引擎解析器 (streamEngineParser) 自动构建计算流水线。
- 支持历史数据回放,可以从任意偏移量重放历史数据。
- 支持批流一体。
## 多范式编程语言
- 支持命令式编程、函数式编程、向量编程、SQL 编程和 RPC(远程函数调用)编程,表达能力强。
- 支持 SQL-92 标准,并在此基础上扩展了多种功能,例如 asof 连接、分布式表连接、透视表等。此外,DolphinDB SQL 还兼容 Oracle 和 MySQL 等 SQL 方言。
- Python Parser 支持 Python 的部分原生对象、语法以及 pandas 库的部分功能。这将方便用户在 DolphinDB 客户端中使用 Python 语法来访问和操作 DolphinDB 的数据。
1 - 概述
## 良好生态
・丰富的 API,包括 Python,C++,Java,C#,Go,R,JSON 和 JavaScript 等,为开发人员提供了灵活的接口。
- 多样的插件,包括数据导入导出、金融市场、物联网、消息队列、机器学习等,方便扩展数据库的功能。
·模块化设计,包括技术分析指标库、因子指标库、运维函数库、历史数据导入、行情数据接入模块等, 方便功能代码调用及维护。
### 1.3 支持平台和部署
DolphinDB 支持 Linux 和 Windows 操作系统。我们强烈推荐使用 Linux 系统作为生产环境的部署方案。DolphinDB 支持的操作系统及推荐版本见表1-1。DolphinDB 支持单节点部署和集群部署,支持本地部署和云端部署。数据库进程既可以运行在物理服务器,也可以运行在 Docker 容器或虚拟机环境中。
表 1. DolphinDB 支持的操作系统
<table><tr><td>操作系统</td><td>推荐版本</td></tr><tr><td>CentOS/Redhat</td><td>7.9(经过大量企业级环境验证)</td></tr><tr><td>Ubuntu</td><td>18.04 LTS</td></tr><tr><td>UOS</td><td>v20</td></tr><tr><td>Kylin</td><td>v10</td></tr><tr><td>Windows</td><td>x86</td></tr></table>
## 第 2 章. 分布式架构
DolphinDB是一个分布式的存储和计算系统。分布式存储内部实现多版本管理,保证强一致性,支持分布式事务。分布式计算以分区数据为计算单元,通过多副本实现计算的容错和负载均衡。
### 2.1 集群网络架构
DolphinDB 集群的存储采用 shared-nothing 架构。在这一架构中,集群中的各个节点相互独立,拥有自己独立的计算资源和存储资源,不共享中心资源。元数据文件存储在控制节点上,而分区数据按指定逻辑进行划分,存储在不同的数据节点上。这个逻辑上的文件系统有效地组织了各节点的文件和目录服务,形成了一个全局的目录结构,从而屏蔽了各节点具体物理路径的细节。这个全局的逻辑的目录文件结构,在DolphinDB中称为分布式文件系统(DFS)。由于逻辑文件系统的存在,用户无需关心数据具体存储在哪个物理节点上。不论用户无论从哪个物理节点进行数据访问,路径都是相同的。
DolphinDB 集群支持在物理服务器或虚拟服务器上部署,支持在单服务器或多服务器部署。集群支持灵活增加节点以扩展规模,一个集群可包含数百个节点,支持数千个 CPU 核。
图 2. 集群网络架构

DolphinDB 集群包括以下四种类型的节点:
- 控制节点:DolphinDB 集群的核心部分,负责收集代理节点和数据节点的心跳,监控每个节点的工作状态,管理分布式文件系统的元数据、分配分区位置,并提供对事务的支持。
·代理节点:负责执行控制节点发出的启动和关闭数据节点或计算节点的命令。在一个集群中,每台物理服务器有且仅有一个代理节点。
- 数据节点:既可以存储数据,也可以用于数据的查询和计算。每台物理服务器可以配置多个数据节点。
·计算节点:不存储表数据和元数据,只承担计算相关的任务,负责响应客户端请求并返回结果。适用于数据密集型计算任务。每台物理服务器可以配置多个计算节点。
DolphinDB 分布式集群具备以下优势:
2 - 分布式架构
- 资源得到充分利用:DolphinDB 的数据节点通过 DFS 共享存储,且对数据分割进行了全局优化,实现了数据在各个节点上均匀分布,从而更充分地利用整个集群资源。
- 分区剪枝提高查询效率:DolphinDB 的多列组合分区方案能够支持单表千万级的分区,系统可以根据查询语句进行分区剪枝,以快速确定查询相关的分区和所在的节点,提高了查询的效率。
- 扩展性高:在 DolphinDB 的分布式存储机制中,控制节点统一管理元数据,提高了容错性和可扩展性。
- 便于数据迁移:DolphinDB 的存储逻辑与存储位置分离,可以实现计算和存储的弹性扩展。
·支持高可用:在节点发生故障时,系统也可以根据存储逻辑,自动找到其他节点上的数据副本,保证服务不断线。
DolphinDB 的数据存储是基于底层分布式存储机制构建的,通过元数据管理数据副本。因此,在扩展节点时,不需要对现有数据进行 resharding 操作,也不需要重启集群,新增的数据会直接保存到新的数据节点中。这一特性无需进行大规模数据迁移,极大地简化了扩展集群的过程,也降低了系统维护的复杂性。
DolphinDB 集群既可以采用离线扩展也可以采用在线扩展;既可以通过动态添加服务器实现集群水平扩容, 也可以通过新增磁盘卷来动态扩展数据节点的存储容量。在添加节点或磁盘后,可能出现数据在节点之间分布不均匀的情况。为避免资源浪费,提高系统性能,DolphinDB 允许用户调用函数平衡集群中所有节点间的数据,或平衡一个数据节点内各磁盘卷间的数据。
### 2.2 数据分区机制
分区是进行数据管理和提高分布式存储性能的重要手段之一。通过分区实现对大型表的有效管理。一个合理的分区策略能够仅读取查询所需的数据,以减少扫描的数据量,从而降低系统响应延迟。
DolphinDB 支持最多三个维度的分区,能满足单表百万甚至千万级的分区需求。为了保证每个分区的大小平衡,系统提供了值(VALUE)、范围(RANGE)、哈希(HASH)和列表(LIST)等多种分区方式供用户选择。对于数据量庞大且经常涉及多列的 SQL 查询,DolphinDB 还提供了组合分区,用户可使用2个或3个分区列, 并且每个分区列都支持值、范围、哈希或列表分区。
分区的元数据存储在控制节点,副本数据存储在各个数据节点。分布式文件系统统一管理各个节点的存储空间,分区的规则与分区的存储位置解耦。多个列构成的组合分区,在实现上并没有层次关系,而是进行全局优化。这样一来,分区的粒度更细更均匀,在计算时能充分的利用集群的所有计算资源。DolphinDB 的分区机制具有以下优点:
·系统能够充分利用所有资源。通过选择合适的分区方案,并结合并行计算和分布式计算,系统可以充分利用所有节点来完成通常要在一个节点上完成的任务。若一个任务可以拆分成几个子任务,每个子任务访问不同的分区,可以显著提升效率。
- 提高了系统的可用性。由于分区的副本通常存储在不同的物理节点上,一旦某个分区不可用,系统依然可以调用其他副本分区来确保任务的正常运行。
- 多表可以共享同一个分区机制,在物理存储时实现Co-location,从而具有非常高的连接(Join)效率。
### 2.3 分布式事务
分布式事务是指分布式系统中的事务,一个分布式事务可能涉及到不同节点和分区的操作。参与事务的所有节点的操作,要么全部成功,要么全部回滚,不能出现部分提交的情况。DolphinDB 通过两阶段提交(Two-Phase Commit, 2PC)和多版本并发控制机制(MVCC, Multi-Version Concurrency Control)实现分布式事务,能够确保每个事务的原子性(Atomicity)、数据的一致性(Consistency)、读写操作之间的隔离性 (Isolation)以及已写入数据的持久性(Durability)。
#### 2.3.1 事务基本执行流程
DolphinDB 采用两阶段事务提交机制,每次由事务的发起节点作为协调者(coordinator)推进整个事务的执行流程。
1. 协调者提出请求(例如写入数据),创建一个事务,向控制节点申请事务 ID(tid),得到事务所涉及分区在数据节点上的分布情况。
2. 协调者将数据分发到相应的数据节点,各个数据节点将数据写入磁盘。如果存在某个数据节点数据写入失败,则终止该事务。
3. 协调者准备提交,向控制节点申请 commit id (cid) 。
4. 协调者向控制节点和所有参与事务的数据节点 commit 事务,开始两阶段提交的第一阶段。如果控制节点或任意数据节点 commit 失败,则终止并回滚事务。
5. 协调者向控制节点和所有参与事务的数据节点 complete 事务,开始两阶段提交的第两阶段。不管控制节点或数据节点是否 complete 失败,该事务都结束。如果存在 complete 失败的情况,则通过事务决议和 recovery 机制恢复。
## 图 3. 事务基本执行流程

#### 2.3.2 开启 Redo Log 与 Cache Engine 的事务流程
Redo Log 是确保事务持久性的关键机制,即使在系统崩溃时,也能保障数据一致性。缺乏 Redo Log, 事务的持久性将会受到影响,因为数据库无法记录事务所做的修改,从而无法在故障或崩溃发生时进行恢复。DolphinDB 利用 Redo Log 和 Cache Engine 来确保事务的持久性并提升写入性能。
DolphinDB 重做日志(Redo Log)与 预写式日志(Write-Ahead Logging,WAL)的概念相似,其核心理念是:只有在描述事务更改的日志记录已经刷新到持久化存储介质之后,才对数据库的数据文件进行修改。这样做可以避免在每次提交事务时都需要将数据页刷新到磁盘上,同时可以保证数据库发生宕机时,可以通过日志来恢复数据,所有尚未应用的更改都可以通过日志记录回放并重做。
Cache Engine 是 DolphinDB 中的一种数据写入缓存机制。数据在写入 Redo Log 的同时写入 Cache Engine。在 Cache Engine 中的数据累积到一个阈值或者达到一定时间后,再由 Cache Engine 一次性异步写入数据文件。在一个事务涉及多个分区且数据量较小的情况下,如果每次事务结束都立即写入磁盘,写入效率将会受到影响。而利用 Cache Engine 先将这些事务缓存起来,待累积到一定数量后,以批量的方式一次性写入磁盘,则可以提供较高的压缩比此外,批量顺序写入也有助于提高IO吞吐量,从而有效提升整体系统性能。
图 4. 开启 Redo Log 与 Cache Engine 的事务流程

一旦数据写入磁盘,事务完成,系统首先回收该事务的 Cache Engine 缓存,再回收 Redo Log 中的事务。DolphinDB 提供三种 Cache Engine 中事务的回收机制:定期回收、待缓存数据量达到阈值、或通过函数手动清理。同时提供两种 Redo Log的回收机制:定期回收和文件大小达到阈值时回收。
#### 2.3.4 读写隔离级别
DolphinDB 采用两阶段事务机制,结合多版本并发控制机制(MVCC, Multi-Version Concurrency Control),实现读写快照级别隔离。MVCC 通过保存数据多个事务的数据快照来进行控制,允许同一个数据记录拥有多个不同的版本,记录了一个版本链。每进行一次写入、更新或删除操作,数据的版本号都会增加,
从而确保在用户同时对数据库进行读写操作时,读和写的并发事务能够相互隔离。为了有效管理版本,系统会定期回收版本链。
DolphinDB 的分布式事务提供基于 sid(snapshot id)的快照隔离。结合前文介绍的两阶段提交流程,接下来详细说明 DolphinDB 的读写隔离机制:
1. 协调者创建事务,向控制节点申请事务 tid。
2. 当事务第一次 commit 时,控制节点会生成一个全局递增的 cid,并将其记录在参与事务的所有数据节点上。此时,数据节点会生成一个新的 CHUNK 副本(以“物理表名_tid” 命名),并在该副本上进行数据的操作;为了防止 CHUNK 目录无限增长,数据节点最多保留5个旧版本的 CHUNK 目录,并根据设置的保留时长进行定期回收。
3. 在完成两阶段提交时,控制节点生成一个全局递增的 sid(snapshot id),并将其记录在版本链上。sid 的主要作用是协助控制节点获取已完成事务中的最大 cid 并将该 cid 返回给协调节点。如果我们不引入 sid,在查询时直接使用 cid,存在一个潜在问题,即可能某个事务已经完成,但仍然有另一个小于该事务 cid 的事务尚未完成。这种情况可能导致在查询时无法查到最新的已完成事务的数据。通过引入全局唯一的 sid,确保了所有已完成的事务都能被查询到。
4. 当协调者向控制节点请求查询最新的元数据信息时,控制节点通过当前版本链上的最大 sid,查询到满足小于等于这个 sid 的最新的 cid,并返回给数据节点。对应这个 cid 的 CHUNK 版本即为当前可读的最新版本的 CHUNK 数据。
5. 协调者根据获取的 cid 到相应的数据节点上读取此 cid 对应版本的数据。
### 2.4 计算与存储分离
为了提升 DolphinDB 在高并发读写场景下的性能与稳定性,DolphinDB 在架构上引入了计算节点 (compute node)。计算节点轻量无状态,不存储分布式表数据和元数据文件,只承担数据节点计算相关的职能,负责响应客户端请求并返回结果。针对计算密集型计算任务(如流计算、分布式关联和机器学习等), 集群采用计算与存储分离的部署方案,具备以下优势:
- 保证数据写入和查询的稳定性
对于复杂业务计算,如因子计算和机器学习等,通常需要大量内存资源。这可能导致数据节点由于内存不足而发生内存溢出等问题。如果将计算下沉到计算节点,根据任务将数据从各个数据节点取出到计算节点上的内存中执行计算,可以有效释放数据节点上的内存占用,避免由于后续复杂计算而导致内存消耗增加的问题,从而确保数据节点的写入稳定性。
·降低故障平均修复时间
使用计算节点的集群能显著地降低故障平均修复时间,尽可能地减少对业务的影响。正是由于计算节点不存储和管理分布式数据和元数据,当集群中某一个计算节点出现出现拥塞、无法响应,且无法热修复等情况时,直接重启计算节点即可使其恢复正常服务。重启过程简单,可以在数秒内完成。
DolphinDB 架构实现了计算与存储的分离,通过拓展计算能力,使数据节点专注于高效处理 IO 操作,从而有效提升集群的计算性能,避免计算任务过多对数据写入和读取性能的影响。集群管理者可以根据业务需求和负载情况,灵活地扩展计算和存储资源,实现更精准的资源优化。这一架构设计在保障计算性能的同时,允许集群动态调整,以适应不断变化的业务需求和工作负载。
## 第 3 章. TSDB 存储引擎
TSDB 引擎设计采用经典的 LSMT(Log Structured Merge Tree)模型,并结合了辅助索引的排序列,进一步优化了引擎的性能。LSMT 是一种将数据存储在高效的数据结构中的技术,它将数据按照规定的顺序组织并存储,以便于快速访问和查询。这种数据结构可以有效地处理大量的时间序列数据,提升读写性能。
图 5. TSDB 引擎架构

### 3.1 排序列
排序列(Sort Column)是 TSDB 引擎在一个数据分区内部用以数据排序的多个字段。它在 TSDB 引擎的存储和读取流程中发挥着数据去重和索引的双重作用。在创建表时通过参数 sortColumns 来定义排序列,它的最后一列必须是时间类型,而除了最后一列之外的其他列称为排序键(Sort Key),每个排序键独特值对应的数据按列顺序存储在一起。排序键字段的组合值作为索引键,为数据查询提供了入口,能够迅速定位数据块的位置,从而降低查询时间。在写入过程中,每个事务中的数据会根据排序列进行排序和去重。
### 3.2 存储结构
如上图所示,TSDB 存储引擎采用分层的 LSMT 结构,数据分为两部分:基线数据和增量数据。基线数据是已经被写入和存储在磁盘中的数据,被称作 Level File。增量数据是新写入的还在 Cache Engine 中的数据,它们在一段时间后会被合并到基线数据中。数据首先按分区分组后写入 Cache Engine。Cache Engine 中的数据未被压缩,当缓存的数据量达到刷盘条件时,存储到 Level File 文件中,在转储的过程中对数据进行压缩, 因此 Level File 存储的是压缩后的数据。
Level File 内部采用了行列混存(Partition Attributes Across,简称 PAX),即数据先按照排序键切分数据, 每个排序键对应的数据仍然按列存储,其中每列的数据按照固定行数划分为多个 block,并在 Level File 的尾部记录这些 block 的地址及其对应的排序键信息。block 是最小的查询单元,也是数据压缩的单元,其内部数据按照时间列的顺序排序。
TSDB 核心的存储结构主要是为了减少随机 I/O。新增、删除或者修改数据,都通过追加记录的方式,而不是直接覆盖原有记录,实现快速地写入。通过存储文件中的保存的索引信息,来提升点查性能。
## Level File 分层
TSDB 引擎中的数据存储于 Cache Engine 和磁盘中。当 Cache Engine 中数据达到一定时间或数据量超过一定阈值时,就会被合并存入到磁盘上,以释放内存。磁盘中的数据以 Level File 的形式分层存储,分层组织形式如下:
图 6. Level File 分层

Level File 从 Level 0 到 Level 3 共分为 4 个层级。随着层级的升高,每个 Level File 的文件大小会相应增加。Cache Engine 中的数据被分割为32M大小并压缩后按分区存储到 Level 0 层的 Level File 文件。较低层级的 Level File 文件通过合并生成高层级的 Level File 文件,因此较低层级(Level 0)上的 Level File 文件相对较新,而较高层级的文件相对较旧。
## Level File 合并及数据去重
多次写入后,相同的 sortKey 的数据可能分散在不同的 Level File 里。为减少无效文件数量,TSDB 引擎设计了文件合并的机制,通过合并操作(compaction)可以提高磁盘空间利用率(压缩率提升)以及提升查询性能。
## 合并机制
3 - TSDB 存储引擎
当较低层级的 Level File 的数量超过10个或该层所有 Level File 的大小超过更高一层单个 Level File 文件的大小时,系统会将这些 Level File 合并为更高一层的 Level File。每层 Level File 单个文件的大小参考上文的 Level File 分层组织。
默认情况下,TSDB Level File 文件满足合并要求时,由系统自动触发合并,对用户透明。在某些特殊情况, 可能出现文件过多,却没有合并,DolphinDB 也提供了函数实现手动触发合并。
## 数据去重
TSDB 根据排序列进行去重,建表时通过参数指定去重模式。包含三种去重模式:保留所有数据,仅保留最新数据,仅保留第一条数据。去重发生在写入时数据排序阶段以及 Level File 合并阶段。不同去重机制会对更新操作产生影响:若采用保留所有数据或仅保留第一条数据,则每次更新时都需要将分区数据读取到内存更新后再写回磁盘;若采用仅保留最新数据,则更新数据将以追加的方式写入,真正的更新操作将会在 Level File 合并阶段进行。请注意:
- TSDB 去重策略无法确保磁盘上无冗余,只保证查询时无冗余结果。查询时,读取各 Level File 中排序键对应的数据块,在内存中去重后返回结果。
- DolphinDB 不支持约束。不建议将数据中的主键或唯一约束设置为排序列。因为这样做,会导致每一行都数据都会成为一个索引键,从而索引数据暴增,写入性能和查询性能急剧下降,内存消耗大幅上升。
### 3.3 数据压缩
对数据进行压缩,可以显著地提升数据传输效率和吞吐量。TSDB 支持无损压缩,在数据从 Cache Engine 写入磁盘时进行压缩。支持以下压缩算法:
- 默认采用 LZ4 压缩算法。LZ4 主要针对重复字符进行压缩,压缩率与数据重复频率相关。如果同一列中有较多重复项,LZ4 算法可以获得较高的压缩速度。它侧重于压缩和解压速度,虽然压缩率不是最高的,但解压速度快,适用于需要快速解压的场景。
・zstd 压缩算法:zstd 适用于几乎所有数据类型,其压缩比高于 LZ4,但解压缩速度较 LZ4 慢约1倍。
- delta-of-delta 压缩算法:针对海量时序数据的时间戳都是密集且连续的特点,对时间列采用 delta-of-delta 压缩算法,可以大幅度降低时间戳的存储空间。
- 对于重复次数比较多、唯一值较少且会被比较的字符串,可采用 SYMBOL 类型存储。系统对 SYMBOL 类型数据会使用字典编码,将字符串转化为整型,减少字符串的存储空间。
在实际场景中,譬如金融类无损数据压缩可以达到原数据的10%~25%。
### 3.4 数据写入
TSDB 引擎必须启用 Redo Log 和 Cache Engine。写入时,先写 Redo Log(每个写事务都会产生一个 Redo Log),并写入 Cache Engine,最后由后台线程异步批量写入磁盘。TSDB 采用多线程方式将 Cache Engine 写入磁盘。具体流程如下:
1. 写 Redo: 先将数据写入 TSDB Redo Log。
2. 写 Cache Engine: 写 Redo Log 的同时,将数据写入 TSDB Cache Engine 的 CacheTable,并在 CacheTable 内部完成数据的排序。
图 7. 数据写入

CacheTable 分为两个部分:首先是 write buffer,数据刚写入时会追加到 write buffer 的尾部,该 buffer 的数据是未排序的。当 write buffer 超过 TSDBCacheTableBufferThreshold 的配置值(默认 16384 行),则按照 sortColumns 指定的列排序,转成一个 sorted buffer(只读),同时清空 write buffer。
3. 写磁盘:若某写事务到来时,Cache Engine 中 write buffer + sorted buffer 的总数据量达到 TSDBCacheEngineSize 的设置值,或经过一定时间,系统会将数据按分区写入磁盘 Level 0 层的 Level File 文件中(大小约为32M)。若单次写入磁盘的数据量很大,则会产生多个 Level File 文件; 若写入磁盘的数据量不足32 M,也会写为一个 Level File。Level File 写入后变成只读的文件,下次写入不会再向该文件追加数据。若写入磁盘的过程中,又有新的数据写入 Cache Engine,系统会分配新的 Cache Engine 用来接收写入的数据。在极端情况下,TSDB 的 Cache Engine 内存占用会达到两倍的 TSDBCacheEngineSize 的指定值。
根据步骤 2,3,可以发现数据写入磁盘前先局部排序(sorted buffer),再整体排序,共执行了两次排序操作。实际就是通过分治的思想,提升了排序的效率。
### 3.5 数据查询
相较于 OLAP 引擎,TSDB 引擎引入了索引机制,更适用于点查场景。此外,TSDB 引擎不使用用户态缓存数据,仅使用操作系统的缓存。具体查询流程如下:
1. 分区剪枝:根据查询语句进行分区剪枝,缩窄查询范围。
2. 加载索引:遍历所涉及分区下的所有 Level File,将索引信息加载到内存中。索引信息采用惰性缓存策略,不会在节点启动时立即加载,而是在第一次查询命中该分区时加载。一旦查询命中的分区索引信息被加载到内存,将一直缓存在内存中,除非由于内存不足而被置换。后续查询若涉及该分区则无需重复此步骤,而是直接从内存中读取索引信息。TSDB 提供相关配置项来配置内存中索引区域的大小和 Level File 索引缓存淘汰算法的阈值。
3. 查找内存中的数据:先搜索 TSDB Cache Engine 中的数据。若数据在 write buffer 中,则采用顺序扫描的方式查找;若在 sorted buffer 中,则利用其有序性,采用二分查找。
4. 查找磁盘上的数据:根据索引查找 Level File 中各查询字段的数据块,解压到内存。若查询的过滤条件包含 sortKey 字段,即可根据索引加速查询。
5. 返回查询结果:合并3,4两步的结果并返回。
3 - TSDB 存储引擎
### 3.6 数据更新及删除
## 数据更新
根据去重机制的设置,TSDB 引擎的数据更新操作流程会有所差异。
・若采用保留所有数据或仅保留第一条数据的机制,更新操作的流程与 OLAP 引擎相同。引擎会读出分区下所有 Level File 的数据,在内存中更新对应数据后再次写入新版本目录的 Level File 文件,并删除旧版本的 Level File 文件,该操作的开销非常大。
・若采用仅保留最新数据的机制,更新操作流程与 OLAP 引擎不同。系统将需要更改的数据读取到内存中,修改后直接追加到 Level 0 层级的 Level File 里,不会删除旧文件,也不会产生新的版本目录。旧 Level File 文件将在查询时或手动调用进行合并删除。
## 数据删除
TSDB 引擎支持软删除功能,即删除数据将以追加的方式写入,并附加删除标记,实际的删除操作将在文件合并时执行。
当采用保留所有数据或仅保留第一条数据的机制时,数据删除的流程和数据更新流程基本一致,即按分区读取所有数据,删除后写入一个新版本目录。具体流程如下:
1. 分区剪枝:根据查询语句进行分区剪枝,缩窄查询范围。
2. 查到内存进行删除:取出对应分区所有数据到内存后,根据条件删除数据。
3. 删除后的数据写入数据库:将删除后的数据写入数据库,系统会使用一个新的 CHUNK 目录(默认是 “物理表名_cid”)来保存写入的数据,旧的文件将被定时(默认 30min)回收。
当采用保留最新数据的机制时,可通过参数设置数据删除的流程:
- 建表时设置参数 softDelete=true,则数据删除采用软删除方式,即将待删除的数据读取到内存中,打上删除标记后,以追加的方式写入一个新的 Level File 文件,不会删除旧数据,也不会产生新的版本目录。待删除的数据会在 Level File 文件进行合并时才会删除。
·建表时设置参数 softDelete=false,则数据删除流程同保留所有数据或仅保留第一条数据时的流程相同。
软删除方式因不需要读取整个分区数据,且不会产生新版本目录,可以显著提升删除性能,因此在需要频繁删除数据的场景下,建议开启软删除。
针对不同的数据删除需求,DolphinDB 提供以下方法删除数据:
- 删除整个分区的数据,不保留分区结构。
- 删除分区的数据,保留分区结构。
- 动态生成 SQL delete 语句。
- 删除整个表的数据,不保留表结构。
- 删除整个表的数据,保留表结构。
- 删除整个表的数据,保留表结构。
### 3.7 TSDB 适用场景
TSDB 引擎的综合能力突出,没有明显的短板。对于大多数时序数据处理场景,TSDB 引擎都是首选。与 OLAP 引擎相比,TSDB 引擎在以下场景中的性能表现尤为突出:
·需要快速查询一条或几条时间序列的数据。
- 需要对写入数据进行排序和去重。
- 存储几百几千列的宽表。
- 存储 array vector 和 BLOB 等复杂类型的数据。
- 需要支持数据的更新和删除功能。
## 第 4 章. OLAP 存储引擎
OLAP 引擎适合大规模的数据分析。它采用列式存储,在每个分区内将一列数据保存为一个文件。这种存储策略允许只读取所需的列数据,从而减少不必要的 I/O 操作,显著提高查询速度。
图 8. OLAP 引擎架构

### 4.1 存储结构
OLAP 存储如下图所示,同一列的数据按表中的顺序连续地存放在一起,表的每列构成一个长数组。 数据表中每个分区中的每列都存储在一个单独的数据文件中,数据以追加的方式存储到相应的列文件中,因此,数据写入的顺序决定了它们的存储顺序。这种存储方式具备以下几点优势:
图 9. 存储结构

·高效压缩:由于相同类型的数据通常具有相似的值,按列存储可以更好地利用压缩算法,降低了存储空间需求,从而节省成本。
·大规模数据分析:列式存储非常适用于大规模数据分析,因为查询通常只需要读取一部分列,而不是整行数据,从而提高了查询效率。
### 4.2 数据压缩
OLAP 的压缩类型与 TSDB 类似,但与 TSDB 不同的是,OLAP 按照列文件进行压缩。OLAP 采用增量压缩策略,每次只对新增数据进行压缩,批量写入有助于提升压缩效果。若每次仅写入一行记录,且 Cache Engine 未开启,则存于磁盘的数据不会进行压缩。
### 4.3 数据写入
默认情况下,OLAP 引擎是不开启 Cache Engine 的,此时数据不会在内存中缓存,而是直接写入磁盘。这种设置下,若每次进行小批量写入会极大影响磁盘 I/O 性能以及压缩效果。因此,建议开启 Cache Engine 和 Redo Log,把多次少量的写入缓存起来,在一次文件 I/O 中批量写入,从而在整体上提升系统的写入性能。
OLAP 引擎写入操作支持事务,具备事务 ACID 特性,且通过 MVCC 实现快照隔离级别。
### 4.4 数据查询
OLAP 引擎将每列数据存储为一个列文件,所以读取数据时,只需要从磁盘读取所需要的列文件,解压后加载到内存。
具体流程如下:
1. 根据查询语句进行分区剪枝,缩窄查询范围。
2. 将 where 语句过滤条件中包含的列的数据文件读到内存,并进行过滤。
3. 根据过滤出的列数据,读出其对应的其他列的数据。
这种数据读取方式使得 OLAP 引擎在高吞吐量查询情况下拥有较好的性能。 但若需要更新或删除某条数据,OLAP 会将整个分区数据加载到内存中,再对这条数据进行更新或删除,因此性能开销大。
### 4.5 数据更新及删除
## 数据更新
OLAP 引擎对数据的更新操作流程与 TSDB 引擎设置保留所有数据或仅保留第一条数据机制时的更新流程相同。每次更新,系统都会读出对应分区中相关的列文件,在内存中进行更新,同时创建一个新的版本以存储新的数据。整个过程通过事务来确保数据一致性,并通过 MVCC 保证读取的一致性,对于未变化的列,采用创建硬链接的方式,以提升性能并降低不必要的数据读写。在提交事务之前,其他 SQL 语句仍然访问旧版本的数
4 - OLAP 存储引擎
据,直到更新事务完成。若更新操作涉及多个分区,只要其中某一个分区更新失败,系统会回滚所有分区的修改。
## 数据删除
对于 OLAP 引擎的数据删除操作,其流程与更新操作一致,即按分区读取所有数据,执行删除操作后写入一个新版本的目录。整个过程同样通过事务保证数据一致性,并通过MVCC 保证读取一致性。若删除操作涉及多个分区,只要其中某一个分区删除失败,系统会回滚所有分区的修改。
OLAP 引擎除不支持软删除外,其它数据删除方法与 TSDB 引擎相同。
### 4.6 OLAP 适用场景
相比 TSDB 引擎,OLAP 引擎的存储格式更为简单,数据粒度也更粗。OLAP 引擎以分区为存储单位,每个分区内的每列分别存储一个文件。因此 OLAP 引擎读取整个分区数据或整个分区的某几列数据,非常高效,适合扫描分析大量数据等场景,如:查询所有股票在某个时间段内的交易量等。
## 第 5 章. SQL 和库内计算
DolphinDB 提供了强大而灵活的库内计算能力。不仅支持历史数据的批量计算,还支持实时数据的流式计算。DolphinDB 内置了多范式的脚本语言 DolphinScript,以及超过1500个函数的函数库。大部分的数据处理业务,可以直接在数据库内完成。
### 5.1 SQL
SQL(结构化查询语言)是目前最广泛使用的数据库访问和管理的计算机标准语言。DolphinDB 支持标准 ANSI SQL-92 语法,以及SQL-2003引入的分析函数功能,同时引入了 DolphinDB 独有的方便处理时间序列数据的 SQL 语句。在 DolphinDB 中,查询数据的体验与传统的 SQL 体验一样简洁明了。
DolphinDB 提供了丰富的 SQL 功能,包括:
- 3 种常用的 DDL 语句:CREATE、ALTER、DROP,用于管理数据库结构。
- 5 种常用的 DML 语句:SELECT、EXEC、INSERT、UPDATE、DELETE,用于数据查询与修改操作。
- FROM 子句,用于指定数据来源。
- WHERE 条件,用于筛选数据;INTERVAL 子句对结果进行插值处理。
- 分组和排序子句,如 GROUP BY、CONTEXT BY、PIVOT BY、CGROUP BY、ORDER BY、CSORT。
- 支持 TOP、LIMIT,用于限制返回结果集的行数。
- 常见的条件表达式和运算符:NOT、IS NULL、BETWEEN
AND、EXISTS、IN、ANY、ALL、DISTINCT、WITH、NULLIF 等。
- 支持分析函数(也叫窗口函数):12个聚合函数,3个排序函数,2个分布函数和6个分析函数。
·多表关联查询,包括等值连接、内连接、左(外)连接、左半连接、右(外)连接、全连接、交叉连接, 还支持专为时序数据设计的 ASOF JOIN 和 WINDOW JOIN。
- 直接使用 DolphinDB 大部分内置函数,包括窗口函数(支持嵌套多个窗口)、各种聚合函数(计数、 平均值、求和、最大值、最小值、百分位、中位数、标准差、加权平均、协方差、相关性等),以及在滑动窗口或累计窗口中进行聚合操作。
- 支持自定义函数,增强了灵活性和扩展性。用户自定义的函数无需编译、打包和部署,即可在本节点或分布式环境的 SQL 中使用。
- 支持组合字段(composite column),可将复杂分析函数的多个返回值输出到数据表的一行
- SQL 与分布式计算框架紧密集成,实现库内计算(in-database analytics)变得更加便捷和高效
DolphinDB SQL 具备的强大功能使得从传统数据库迁移到 DolphinDB 的脚本编写变得极为简单,降低了用户的学习曲线。此外,DolphinDB SQL 不仅是数据库管理的一部分,还融合了向量式编程、函数式编程和命令式编程的特性,使其具备处理复杂数据逻辑的能力。在处理复杂的数据分析问题时,无需将数据转移到第三方客户端进行处理,这不仅方便了数据分析人员,同时也显著提高了数据处理的效率。DolphinDB 多范式编程风格为用户提供了更大的灵活性和选择,使其成为应对各种数据分析挑战的有力工具。
### 5.2 多范式编程
DolphinDB 从流行的 Python 和 SQL 语言汲取了灵感,设计了图灵完备的数据分析脚本语言 DolphinScript。DolphinDBScript 支持命令式编程、向量化编程、函数式编程、SQL 编程和元编程等多种编程范式,表达能力强大,可以满足快速开发和建模的需求。
#### 5.2.1 命令式编程
DolphinDB 与主流的脚本语言(Python 和 JavaScript)和编译型强类型语言(C++, C 和 Java)一样,支持命令式编程,也就是通过执行一条一条的语句,实现最终的目标。DolphinDB 支持包括最常用的赋值语句, 分支语句 if..else, 以及循环语句 for 和 do..while 等。
#### 5.2.2 向量化编程
向量化编程是 DolphinDB 中最基本的编程范式。数据结构表、矩阵、元组、列式元组、数组向量、字典和结集合都可以用向量来表示。DolphinDB 中绝大部分函数支持向量作为函数的输入参数,根据输出结果的不同,向量化函数可以分为标量函数,聚合函数和向量函数。
向量化编程具有以下三个主要优点:
·降低脚本解释成本:向量化操作减少了解释器的负担,提高了执行效率,从而加速了脚本的执行速度。
·性能优化:向量化操作使得许多算法可以进行高效优化,大幅提升了性能,特别适用于处理时间序列数据等大规模数据集。
- 代码简洁:使用向量化操作,可以编写更简洁、可读性更高的代码,减少了繁琐的循环和条件判断。
在时间序列数据分析等应用中,通常可以使用向量化编程来处理数据,而 DolphinDB 作为分析型数据库,尤其适用于这种场景。在应用中,脚本尽可能避免使用 for 循环而采用向量化形式,可以更高效地处理和分析大规模数据。
#### 5.2.3 函数化编程
函数式编程是一种声明式编程范式,其核心思想是将计算过程分解为一系列函数调用的链条,每个函数都接受输入并生成输出,而不是通过修改状态或改变变量的值来实现计算。DolphinDB 的函数式编程支持高阶函数 (Higher Order Function)、部分应用(Partial Application)、自定义函数(User-defined Function,或简称 UDF)、Lambda Function、纯函数(Pure Function)和闭包(Closure)。
在 DolphinDB 中,高阶函数是应用广泛且功能强大的编程工具。通过与基础函数的组合,可以赋予基础函数更强大、丰富、易用的运算表达能力。高阶函数中最常用的是函数模式 ( Function Pattern ) 包括: each、loop、eachLeft、eachRight、eachPre、eachPost、cross、accumulate、reduce、byRow、byColumn、 和 contextby。每个模式类高阶函数都有一个对应的模式符号,可以直接附加在一个函数后面,修饰函数。模式符号可以叠用,以表达更复杂的数据处理逻辑。
部分应用是一种编程技术,指的是在调用函数时只传递部分参数,从而生成一个新的函数,该新函数接收剩余的参数。它经常应用于高阶函数和流计算中。使用高阶函数时,通常对某些参数有特定要求,通过部分应用, 可以确保所有参数符合要求。部分应用可以使函数保持状态,能够满足流计算中需要状态的需求。
DolphinDB 允许用户通过自定义函数来扩展现有功能,其提供了两种管理自定义函数的方法:函数视图 (Function View)和模块(Module)。函数视图是封装了访问数据库以及相关计算语句的自定义函数。用户即使不具备读写数据库原始数据的权限,也可通过执行函数视图,间接访问数据库,得到所需计算结果。 模块则是只包含函数定义的脚本文件,可以将大量函数按目录树结构组织在不同模块中。模块可以在系统初始化时预加载,也可以在需要使用时引入。函数视图可以持久化在分布式数据库中,一旦添加即可在任何节点使用,它也兼具了像模块一样按目录进行管理的能力。模块支持以函数视图的方式持久化到集群的各个节点,便于代码的工程化管理。
#### 5.2.4 元编程
元编程是一种编程范式,它使用脚本来创建可以在运行时动态执行的程序代码。元编程的目的是延迟执行代码或者动态创建代码。DolphinDB 支持使用元编程来动态创建表达式,例如函数调用表达式或 SQL 查询表达式。这适合在业务细节无法在编码阶段确定的场景下使用。延迟执行代码通常出现在以下情况下:
- 提供回调函数:元编程可以用于创建回调函数,以便在特定条件下执行代码。
- 为整体性能优化创建条件:有时为了优化整体性能,需要延迟执行某些部分的代码。
·问题描述在编码阶段完成,但问题实际解决在运行时:某些问题在编码阶段描述清楚,但只能在程序运行时动态解决。
DolphinDB 提供了两种元编程方法,一种是使用一对尖括号<>来表示需要延迟执
行的动态代码;另一种是使用函数来创建各种表达式。常用于元编程的函数包括
objByName、sqlCol、sqlColAlias、sql、expr、eval、partial、makeCall 等。这些工具使 DolphinDB 在运行时具备了动态生成和执行代码的能力,从而更好地满足复杂的业务需求。
### 5.3 分布式计算
DolphinDB 的分布式计算框架以分区为计算粒度,这样可与分布式数据库紧密集成。运行时,计算逻辑既可以下推到数据所在节点,也可以将数据传输到计算节点。系统内置了 pipeline、map-reduce 和迭代的 map-reduce 等多种计算模型。
#### 5.3.1 远程过程调用编程
远程过程调用 (Remote Procedure Call) 是分布式系统最常用的基础设施之一。DolphinDB 不仅在其分布式文件系统、分布式数据库和分布式计算框架中采用了自研的 RPC 系统,还允许数据库用户通过 RPC 在远程机器上执行脚本语言。DolphinDB 的 RPC 特性具有以下几个关键点:
- 灵活的远程执行:DolphinDB 的 RPC 支持执行远程机器上已经注册的函数,同时也允许序列化本地自定义的函数到远程节点上执行。在远程执行代码时,权限等同于当前登录用户在本地的权限。
- 多样化的参数类型:RPC 的函数参数可以是常规的标量、向量、数组向量、元组、列式元组、矩阵、集合、字典和表格,同时还可以包括其他函数,包括自定义的函数。
- 连接选项:DolphinDB 的 RPC 支持多种连接选项。您可以选择使用两个节点之间的独占连接 (remoteRun函数),也可以使用集群数据节点之间的共享连接(rpc函数),以适应不同的分布式计算需求。
5 - SQL 和库内计算
DolphinDB 的强大 RPC 功能使得在分布式环境中执行代码变得更加灵活和高效,为分布式数据处理和计算提供了可靠的基础。
#### 5.3.2 数据源
在 DolphinDB 的通用计算框架中,数据源(Data Source)是一种特殊类型的数据对象,用于描述数据元信息。用户可以通过执行数据源获得表、矩阵、向量等数据实体。Data Source 既可以是内置的数据库分区,也可以是外部数据。在 Data Source 之上,可以完成分布式SQL、分布式机器学习以及自定义的分布式批处理计算任务。
#### 5.3.3 分布式 SQL
DolphinDB 的 SQL 支持分布式查询,查询语法与常规 SQL 相同,底层实现使用了map-reduce计算模型。系统根据 WHERE 子句进行分区剪枝,根据关系运算符和逻辑运算符确定相关的分区,然后重写查询,并把新的查询发送到相关分区所在的位置,最后整合所有分区的结果。当查询是分组计算(GROUP BY)时,如果分组字段覆盖了所有分区字段,系统只需对每个相关分区执行查询,然后合并各个查询结果;如没有覆盖全部分区字段,但是聚合函数支持map-reduce,则转写Query进行map-reduce的计算,否则对数据进行重分区。当查询是CONTEXT BY或JOIN时,如果分组字段或关联字段覆盖了所有分区字段,则系统只需对每个相关分区执行查询,否认则对数据进行重分区。
#### 5.3.4 分布式机器学习
DolphinDB 提供了内置的分布式机器学习算法,能在单机或分布式环境下对不同规模的数据执行训练。这些机器学习算法基于数据源的概念和 map-reduce 框架,自动根据给定的数据源,对位于相应结点上的数据进行训练,汇总后生成模型。DolphinDB 实现了一系列常用的机器学习算法,例如最小二乘回归、随机森林、K-平均等,使用户能够方便地完成回归、分类、聚类等任务。
此外,用户也可以基于 map-reduce 框架,自己设计分布式算法。DolphinDB 内置的 mr 函数,接受的参数通常包括数据源、map 函数、reduce 函数、final 函数等。系统会并行地在相应的结点执行 map 函数,并用 reduce 函数和 final 函数汇总,返回最终的计算结果。用户通过脚本自定义这些函数,就能快速开发分布式算法。DolphinDB 还提供了迭代计算的功能,可以弥补传统 map-reduce 框架功 能上的不足。
### 5.4 实时流处理
实时流处理是指将业务系统产生的持续增长的动态数据进行实时的收集、清洗、统计、入库,并对结果进行实时的展示。在金融交易、物联网、互联网/移动互联网等应用场景中,复杂的业务需求对大数据处理的实时性提出了极高的要求,全量查询和计算则无法满足该场景的需求。因此, DolphinDB 精心研发了多种适合流计算场景的引擎,引擎内部采用了增量计算,优化了实时计算的性能。DolphinDB 内置的流数据框架支持流数据的发布、订阅、预处理、实时内存计算、复杂指标的滚动窗口计算等,流数据引擎的计算结果则可以输出到共享内存表、流数据表、消息中间件、数据库、API 等终端,以做进一步的处理。计算复杂表达式时,亦可将多个流数据引擎通过级联的方式合并成一个复杂的数据流拓扑。
DolphinDB 流数据处理系统的优点在于:
- 吞吐量大,低延迟。
- 与时序数据库及数据仓库集成,一站式解决方案。
- 支持使用 SQL 语句进行数据注入和查询分析。
- 支持数据回放、流批一体。
- 支持流计算高可用。
关于 DolphinDB 数据分析和流计算的框架原理及场景应用,请参考《DolphinDB 白皮书:数据分析》和 《DolphinDB 白皮书:流数据》。
### 5.5 函数库
DolphinDB 拥有强大的函数库,目前包含1500多个内置函数,适用于多种数据类型(数值、时间、字符串)、数据结构(向量、矩阵、集合、字典、表)和系统调用(文件、数据库、分布式计算)。这些函数涵盖了数学、统计、逻辑、字符串、时间、数据操作、窗口、连接、高阶、元编程、分布式计算、文件/路径、数据库、流计算、系统管理、批处理作业、定时任务、性能监控和用户权限管理等多个类别。另外,针对时序数据处理中窗口计算的需求,DolphinDB 提供了累积窗口、移动窗口和 TopN 等系列函数。
DolphinDB 内置函数由 C++ 编写,直接嵌入到数据库引擎中,具有高效和稳定的特点。所有内置函数(如非等值连接、移动窗口计算等)都针对应用场景进行了算法优化,大幅提升了性能。
### 5.6 Python Parser
DolphinDB 3.0版本开发了一个原生的 Python 解析器(Python Parser),旨在方便 Python 用户利用他们熟悉的 Python 语法来访问和操作 DolphinDB 的数据,从而更轻松地进行数据分析、处理和可视化。Python Parser 实际上是 Python 语言在 DolphinDB 中的一个实现,它为通过 Python 编写的脚本提供了运行环境。Python Parser 与 DolphinDB 脚本共享对象系统和运行环境,这意味着 Python Parser 可以直接控制 DolphinDB 的存储引擎和计算引擎,并且可以直接使用 DolphinDB 中的内置函数。此外,我们还为 Python Parser 开发了一个名为 'dolphindb' 和 'pandas' 的第三方库,进一步扩展了 Python 用户与 DolphinDB 的交互操作功能。Python Parser 与 DolphinDB 脚本的融合使得 DolphinDB 成为一个更加强大和灵活的数据处理和分析工具。
目前 Python Parser Alpha 版本,支持了 Python 的部分原生对象、语法以及 pandas 库的部分功能:
- Python 对象类型: list, tuple, set, dict。
这些对象可以通过 toddb() 函数转换为 DolphinDB 的向量,元组,集合和字典。转换为 DolphinDB 对象后,可以在 Python Parser 中直接调用 DolphinDB 的内置函数进行计算。
- Python 编程语法:赋值语法(元组赋值、增强赋值等)、编程语法(for, if, while 等)、函数定义 (def, lambda 等)、列表推导式、类(封装函数、重载运算符等)。
- pandas 三个重要的类及对应类的部分方法:DataFrame,Series 和 Index。
## 第 6 章. 安全与容灾
### 6.1 高可用
DolphinDB 提供了分区数据、元数据和客户端的高可用方案,使得数据库节点发生故障或宕机时,数据库依然可以正常运作,保证业务不会中断。
#### 6.1.1 元数据高可用
DolphinDB 控制节点存储的元数据记录了分区分布的节点,版本信息等。在一个集群中可以部署多个控制节点,通过元数据冗余来保证元数据服务不中断。DolphinDB 采用 Raft 协议保证控制节点的高可用性。一个集群中的所有控制节点组成一个 Raft 组,一个 Raft 组中只有一个 Leader,其他都是 Follower。只有 Leader 与数据节点进行交互,当它收到接收数据节点的请求后,先写入本地日志文件中,并向集群中的每一个 Follower 发送同步日志的请求。Follower 接收并持久化 Leader 同步的日志,在 Leader 告知提交后, 提交日志,保证 Leader 和 Follower上元数据的强一致性。如果当前 Leader 宕机,系统会立即选举出新的 Leader 来提供元数据服务。Raft 组能够容忍小于半数的控制节点宕机,只要宕机的控制节点少于半数,集群仍然可以提供服务,因此可以保证控制节点上元数据的一致性。
#### 6.1.2 分区数据高可用
在分布式环境下,为保证数据读写服务的高可用,DolphinDB 会把同一个分区的数据同时写入到集群中的多个不同的节点上。同一个分区在不同节点上的数据拷贝称为副本(Replica)。为了保证数据的强一致性和事务 ACID 特性,DolphinDB采用了轻量、高效且可行的两阶段提交协议(Two-phase Commit)来管理数据副本之间的一致性。这种方式确保了即使某个节点上的数据出现损坏,仍然可以通过访问其他节点上的副本数据来持续提供服务,从而保证了服务的不中断性。同时,针对数据损坏或其它原因导致的副本数据不一致的情况,系统会通过 recovery 机制将数据恢复到一致状态。
#### 6.1.3 客户端高可用
DolphinDB API 提供了强大的自动重连和切换机制,旨在确保与数据节点/计算节点的交互始终保持高可用性。使用 DolphinDB API 与 DolphinDB 的数据节点/计算节点进行交互时,如果连接的节点宕机,API 会尝试自动重新建立连接,若尝试重连失败,API 会自动连接到集群中其他可用的数据节点/计算节点,以保证客户端与服务器之前连接的稳定性。而且切换过程对用户来说是完全透明的,用户不会察觉到当前连接的节点已经发生了切换。
#### 6.1.4 在线恢复
在线恢复 (Online Recovery) 是一种数据恢复技术,用于在分布式文件系统中修复不一致或损坏的数据副本。与传统的离线恢复方法不同,在线恢复可以在数据节点持续写入数据的过程中进行,而不会中断或影响正常的数据处理操作。DolphinDB Online Recovery 技术仅复制副本之间差异的数据,从而减少分区数据恢复的时间。具体流程如下:
1. 当某个数据节点从故障中恢复重启后,会向控制节点汇报自己的分区信息。
2. 控制节点收到数据节点的汇报后,判断需要进行 Recovery,会将需要 Recovery 的分区放入待 Recovery 队列。
3. Recovery 线程从待 Recovery 队列中取出 Recovery 任务,根据收到的汇报来确定 Recovery 的源节点 (数据拷贝的来源)和目标节点,并向源节点发起 Recovery 任务。
4. 源节点收到任务后,开始一次拷贝,即从自身拷贝数据到目标节点,并接收目标节点返回的拷贝结果 (数据拷贝成功或失败)。此过程异步执行,不影响数据库的正常读写。
5. 重复步骤4,直至两个副本之间的差异小于10W行,或者拷贝次数大于5次时,源节点向控制节点发起转换为同步阶段的请求。
6. 控制节点收到请求后,将分区状态设置为 RECOVERING,阻塞写入。由于同步节点需要拷贝的数据量比较少,因此耗时很短,对数据库的影响也很小。
7. 源节点收到转同步成功的回复后,继续拷贝差异的数据。直到数据完全一致,源节点向控制节点汇报 Recovery 任务结束。
8. 控制节点收到 Recovery 任务结束的报告后,更新副本状态为 COMPLETE。此时允许数据写入。
Online Recovery 只复制增量部分数据,能够有效提高恢复性能,且恢复过程不影响生产数据的写入。
以包含一个控制节点和三个数据节点的集群为例。该集群副本数为2,Datanode1 从故障中恢复。通过图示展示 Online Recovery 的过程:
图 10. 在线恢复流程

7.1 源节点同步拷贝差异的数据
6 - 安全与容灾
### 6.2 备份恢复
#### 6.2.1 备份
DolphinDB 采用以分区为单位的数据备份策略,将每个分区备份为一个独立的数据文件,支持全量备份和增量备份。DolphinDB 提供了全面的备份功能和多种备份选项,以满足不同用户的需求:
·通过拷贝文件的方式进行备份:此方式备份直接复制数据并生成相应的元数据文件,无需复杂的数据处理步骤,因此速度快,而且操作简单。它可以实现一键备份整个数据库、一键备份指定的数据表、备份指定的部分或全部分区等功能,满足不同级别的备份需求。该方式支持断点续传,支持同步已修改、新增及删除的分区数据,且可以保证数据一致性。
- 通过 SQL 元代码的方式进行备份:此方式允许用户通过 SQL 语句定义备份过程中的特定逻辑和筛选条件,以满足更精确的备份需求。该备份方式采用序列化的数据处理方式,这可能导致较高的内存消耗和相对较慢的备份速度。该方式支持备份整张表或仅备份满足条件的数据,支持同步已修改或新增的分区数据,但不支持同步已删除的分区数据,不能完全保证数据一致性。
#### 6.2.2 恢复
针对上文提到的备份方式,DolphinDB 也提供了相应的恢复方式,可以实现一键恢复整个数据库、一键恢复整个表、恢复部分分区、恢复已筛选数据等功能。此外,DolphinDB 还提供了额外的恢复功能:
·恢复集群下的所有数据库数据:用户可以通过函数恢复一个集群下所有数据库,这提供了更大范围的数据恢复能力。
·保持名称保持一致或重新命名:恢复后的数据库和表可以选择保持与原数据库和表的名称一致,或者重新命名以适应新的需求。
#### 6.2.3 状态监控
运行备份任务之后,一个非常关键的步骤是验证备份是否成功完成,并确保备份文件的完整性。DolphinDB 提供了多个函数,可以监控备份任务、查看备份信息以及验证备份文件的完整性:
- 允许用户查看指定用户的备份或恢复任务的进度。通过此函数可以了解备份任务的执行情况,以及是否成功完成。
- 查看备份的所有分区的基本信息,包括备份的分区信息、备份时间等关键信息,有助于了解备份的整体情况。
- 查看分布式数据表中某个分区的备份信息,其中包括表的 schema 等关键信息。这对于了解备份的内容和结构非常有帮助。
·检查备份文件的完整性和准确性。通过验证备份文件,您可以确保备份过程中没有发生数据损坏或文件丢失等问题。
### 6.3 异步复制
异步复制将一个集群(称为 Master)的数据和操作异步复制到一个远端服务器的集群(称为 Slave)上。
DolphinDB 的异步复制以数据库作为最基本的操作单元,可以选择对集群中的特定数据库进行同步操作。它通过记录日志和数据持久化等操作来保证在节点宕机时不会丢失数据,从而保证主从集群的数据保持一致性。 同时,异步复制支持灵活的权限管理,只有经授权的用户能够执行复制操作,从而提高数据的安全性。
#### 6.3.1 异步复制原理
DolphinDB 异步复制支持分布式事务,其基本原理如下:在 Master 集群中,每个待同步的事务在提交时, 将同步的数据信息提交,并通过配置选择同步或异步地将事务持久化到磁盘,然后将事务加入到任务发送队列。Slave 集群则从 Master 集群的发送队列中获取任务到本地执行队列,然后并行执行队列中的任务,根据任务内容执行相应的语句,启动事务,并执行两阶段提交。一旦事务完成,Slave 节点标记任务为已完成,并通知 Master。Master 节点收到通知后会从发送队列中回收已完成的任务。
## 异步复制流程
## Master 集群:
1. Master 集群中执行 DDL/DML 操作的数据节点(作为协调节点),在事务 commit 时,将该节点的 IP、port、操作的类型、事务 tid 等信息作为 TaskMeta 一起发送给 Master 集群的控制节点,同时将事务作为 TaskData 异步持久化到该节点上。
2. 控制节点在 commit 时接收到 TaskMeta,并写入事务元数据日志文件。开启 Raft 高可用的集群,通过 Raft 一致性协议确保其他控制节点的日志保持一致。
3. 协调节点提交事务 complete 请求到控制节点。
4. 控制节点 complete 事务,并将 TaskMeta 编号(TaskID)后放到发送队列。
5. 控制节点根据事务操作涉及的分区对事务进行分组,将涉及不同分区的事务放在一组并进行编号。
## Slave 集群:
1. Slave 集群的控制节点定期以 TaskID 作为偏移,到 Master 的控制节点上获取 TaskMeta 到本地任务执行队列。同时向 Master 的控制节点报告最近一批执行成功的 TaskID,以便 Master 从发送队列中回收任务。
2. 控制节点根据队列中组号的大小,顺序地将一组 TaskMeta 对象进行哈希映射,并将它们发送到相应的数据节点。
3. 数据节点收到 TaskMeta 后,根据其中的 sourceIP 和 sourcePort 信息,向主集群相应的数据节点请求 TaskData。
4. 数据节点根据 TaskData 执行对应的语句,在当前节点(协调节点)发起事务,进行两阶段提交。
5. 协调节点向控制节点发送 commit 请求,同时将任务的 TaskID 也发送给控制节点。
6. 控制节点 commit 时,将 TaskID 写入事务元数据日志文件。
6 - 安全与容灾
7. 协调节点向控制节点发送 complete 请求,将 Task 标记为 Finish,完成事务。
8. 如果同一组中的所有 Task 都成功执行,则控制节点会继续推进下一组 Task 执行。直至所有 Task 执行结束。
异步复制主要用于异地容灾备份。当主集群和从集群距离较远或网络带宽有限的情况下,可以使用异步复制技术,保证主集群的数据能够定期同步到从集群。当主集群故障时系统可以快速切换到从集群,确保业务的持续性。
### 6.4 权限管理
DolphinDB 提供了强大、灵活、安全的权限控制系统,以保证数据库的安全性和数据的完整性。控制节点 (controller)作为权限管理中心,使用 RSA 加密方式对用户关键信息进行加密。它具有以下特点:
・提供用户和组角色,方便权限控制:一个用户可以属于多个组,一个组也可以包括多个用户。用户组可以方便地对具有相同权限的用户进行权限配置和管理。
- 提供多种权限控制类别,适应各种场景:DolphinDB 权限类别包含创建/删除/管理数据库、创建/删除指定数据库中的对象、读取/写入/更新/删除指定数据表、运行函数视图/脚本文件、删除作业、执行单元测试、限制用户查询内存的上限。
·丰富的权限控制函数:只有管理员才可设置权限,且只能在控制节点上执行权限类操作。管理员可使用 grant/deny/revoke 命令来设置用户或者组的权限。
- 基于函数视图的权限控制:函数视图提供了一种灵活的方式来控制用户访问数据表,在不给予用户可以阅读数据表所有原始数据的权限的情况下,让用户可以获取由函数视图产生的信息。
·程序调度和流计算中的权限控制:程序调度和流计算在后台运行,很多情况下,没有显式登录,因此权限验证跟用户显式登录的情况有些不同。这两类后台任务都是以创建该任务的用户身份来运行。
• 使用 RSA 对用户关键信息加密:DolphinDB 支持使用 HTTPS 安全协议与 Web 进行通信。DolphinDB 使用服务端证书验证的安全策略。默认情况下,会生成自制证书,客户需要安装服务端的证书,否则浏览器提示不安全连接。
- 支持 SSO,简化登录,方便系统扩展:DolphinDB 提供了用于 SSO 的API 函数,方便 DolphinDB 开发者安全地使用这些接口来对系统进行扩展。
- 权限变更追踪:记录用户/组创建或删除、权限的分配、更改和撤销、角色变更等操作。
### 6.5 审计操作
DolphinDB 可以将对数据库及库内的表的特定操作记录到文件名以 “_audit.log” 结尾的审计日志文件中。 日志中记录了执行操作的用户名称、涉及的数据库和表名、操作的起始时间以及具体的操作内容等信息,为用户提供了便捷的操作审计手段。DolphinDB 的操作审计功能支持以下操作:
表 2. 操作审计功能
<table id="cross-table-1"><tr><td>类型</td><td>操作</td></tr><tr><td>创建数据库</td><td>database 函数,CREATE DATABASE 语句</td></tr><tr></tr><tr><td>创建分布式表</td><td>createPartitionedTable 函数,createDimensionTable 函数,CREATE TABLE 语句</td></tr><tr><td>删除数据</td><td>delete 语句,dropTable 函数,dropPartition 函数,truncate 函数,dropColumns! 函数</td></tr><tr><td>更新数据</td><td>update 语句,upsert! 函数,replaceColumn! 函数</td></tr><tr><td>添加列、删除列</td><td>addColumn 函数,alter 语句,dropColumns! 函数</td></tr><tr><td>修改列名、表名</td><td>rename! 函数,renameTable 函数,</td></tr><tr><td>添加列注释</td><td>setColumnComment</td></tr></table>
## 表 2. 操作审计功能 (续)
DolphinDB 的操作审计功能对系统资源的消耗较小,因此不会影响其运行性能。默认情况下,这一功能处于关闭状态,需要用户通过配置项进行启动或关闭。当开启后,用户可通过特定函数获取详尽的数据库操作信息,包括所有用户的操作或特定用户在特定时间内的特定操作。这些审计日志文件为管理员提供了宝贵的工具,可用来追踪用户活动、监控数据库变化、维护数据完整性,并保障数据安全与合规性。此外,DolphinDB 还设计了灵活的回收机制,允许用户根据实际需求设置审计日志文件的最大保留时间,从而避免审计日志文件的持续增长而造成资源浪费。
## 第 7 章. 运维
### 7.1 运维函数库
为方便数据库管理员更轻松地管理和监控 DolphinDB 集群的性能和数据,DolphinDB 提供了 ops 运维函数库, 实现了以下功能:
- 取消集群中未完成的作业。
·查看数据库磁盘占用情况。
- 关闭不活跃会话。
・获取建库建表语句。
- 强制删除指定数据库正在恢复的分区。
- 获取集群中各个节点的 license 过期时间。在线更新 license。
·根据指定的监控时间和间隔获取集群中各个节点的性能监控信息、获取指定订阅节点的工作线程的状态信息。
- 检查数据库表指定分区的两个副本数据的一致性。
### 7.2 作业管理
作业(Job)是指将 DolphinDB 的一段脚本发送到服务器去执行的任务。作业是 DolphinDB 最基本的执行单位。系统会为作业分配计算资源,并按照优先级和并行度等参数来调度作业的执行,因此合理进行作业管理可以确保系统的高效性和稳定性。
#### 7.2.1 作业类型
作业分为同步作业和异步作业。同步作业会阻塞客户端当前的连接,在当前作业返回之前客户端不能再发送新的作业,适用于对实时性要求较高的场景。
异步作业是在 DolphinDB 后台执行的作业,主要包括:批处理作业、定时作业和流数据作业。这类任务对结果的实时反馈要求较低,系统一般会给予较低的优先级。其中定时作业是指在规定时间以指定频率自动执行作业,它被广泛应用于数据库定时计算分析(如每日休市后分钟级的 K 线计算、每月统计报表生成)、数据库管理(如数据库备份、数据同步)、操作系统管理(如删除过期日志文件)等场景。
#### 7.2.2 作业调度
在 DolphinDB 中,Job 是按照优先级进行调度的,优先级的取值范围为0-9,取值越高优先级则越高。基于作业的优先级,DolphinDB 设计了多级反馈队列来调度作业的执行。具体来说,系统维护了10个队列,分别对应10个优先级。系统总是分配线程资源给高优先级的作业;对于处于相同优先级的作业,系统会以 round-robin 的方式分配线程资源给作业;当一个优先级队列为空的时候,才会处理低优先级的队列中的作业。
一个 Job 可能会被分为多个并行子任务,而处理这些子任务的线程数量取决于 Job 的并行度。并行度可以认为是一种时间片单位。举例来说,在资源比较有限的情况下,如果一个作业的并行度为2,且该作业产生了100个并行子任务,那么系统只会分配2个线程用于子任务的计算,因此需要50轮调度才能完成整个作业的执行。然而,在资源比较充足时,为了充分利用资源,系统会进行优化。如果当前本地执行线程有16个,只有这一个作业在运行,所有线程都处于空闲状态,即使配置的并行度是2,系统也会为其分配16个线程。
当有多个作业时,系统按照作业的优先级来调度子任务,优先级高并行度高的作业会分到更多的计算资源。为了防止处于低优先级的作业长时间等待,DolphinDB 会适当降低作业的优先级。具体的做法是,当一个作业的时间片被执行完毕后,如果存在比其低优先级的作业,那么将会自动降低一级优先级。当优先级到达最低点后, 又回到初始的优先级。因此低优先级的任务迟早会被调度到。
以上调度是 DolphinDB 系统自动完成的,用户无感知。如果需要手动设置作业优先级,可通过以下方法来设置:
- 对于同步作业,其优先级取值为 min(4,通过setMaxJobPrioritysetMaxJobPriority函数设定的该用户最高优先级)。
- 对于通过submitjob提交的批处理作业,系统会给予默认优先级4。用户也可以使用submitjobEx函数来指定优先级。
- 定时任务的优先级设为 4 ,无法改变。
#### 7.2.3 作业取消
DolphinDB 提供了作业取消功能,可以应对以下场景:
·一个作业在执行过程中出现错误或异常时,通过取消作业可以有效地防止进一步的资源浪费。
·一个作业因某种原因需要很长时间才能完成,而用户希望提前取消它,取消作业功能可以满足这一需求。
·在紧急情况下,需要取消正在执行的作业以便立即执行其他紧急任务。
### 7.4 性能监控
DolphinDB 提供了多种性能监控功能,可以帮助用户实时监测系统性能、设置警报,以及提前发现潜在问题,从而有效管理和优化他们的 DolphinDB 环境。监控方式多样:
- 使用内置函数:DolphinDB 提供了多个内置函数,用于获取性能监控度量值。这些函数允许管理员在 DolphinDB 中直接查询性能指标。
- Web 界面:DolphinDB 的 Web 界面提供了部分性能监控度量值的可视化展示,包括内存使用、查询执行时间等。管理员可以通过 Web 界面轻松查看性能数据。
- 第三方系统集成:DolphinDB 支持与第三方系统的集成,如 Prometheus 和 Grafana 等。通过这些工具,管理员可以实现更灵活、强大的性能监控和数据可视化。
通过以上提到的监控方式,灵活组合,可以实现以下功能:
7 - 运维
·资源监控:监控服务器节点的资源使用情况,包括内存、CPU、磁盘等资源的利用率和负载情况。这有助于管理员了解系统的健康状况。
·告警和预警:允许管理员设置告警和预警规则,以便在性能问题或异常情况发生时及时通知管理员。这有助于快速响应问题并采取适当的措施。
·性能监测:实时监视系统的性能指标,如查询响应时间、作业执行情况等。这有助于及时发现性能瓶颈和问题。
- 可视化监控:管理员可以使用工具如 Telegraf 和 Grafana 来采集和可视化性能数据,从而更直观地了解系统状态。这种方式可以实现指标采集、存储、实时处理和展示的一体化监控系统。
DolphinDB 提供了全面的性能监控功能,包括资源监控、告警和预警、实时监测以及可视化监控,以满足不同环境下的需求。管理员可以根据具体情况选择合适的监控方式和工具,以确保 DolphinDB 系统的稳定性和高效性。
## 第 8 章. 生态
DolphinDB 拥有完善、多样、丰富的生态内容,并获得了主流信创生态的兼容认证,使得 DolphinDB 有良好、灵活的集成上游组件并服务下游需求的能力。
### 8.1 API
DolphinDB 支持面向多种编程语言的 API,包括 Python,C++,Java,C#,Go,R,JSON 和 JavaScript 等。通过这些 API,用户可以在自己熟悉的语言环境中执行 DolphinDB 的脚本,查询和操作 DolphinDB 的数据表和分布式表。DolphinDB 数据库的 API 具有高性能,易用性和灵活性的特点,可以满足不同场景和需求的数据分析和处理任务。针对使用率较高的几种 API(Python, C++, Java, C#, Go),总结它们的功能列表如下:
表 3. API 功能
<table><tr><td>功能</td><td>功能介绍</td></tr><tr><td>会话连接</td><td>实现加密(SSL)连接,支持高可用、负载均衡、异步通讯和压缩通讯等。</td></tr><tr><td>数据库操作</td><td>创建数据库、数据表;删除数据表、删除分区、删除列数据、加载分布式表到内存、向表中追加数据等。</td></tr><tr><td>数据上传/写入</td><td>支持上传本地对象到 DolphinDB;支持多种方式写入数据。</td></tr><tr><td>数据下载/读取</td><td>支持从 DolphinDB 中加载数据到本地对象。</td></tr><tr><td>流数据</td><td>支持断线重连、数据过滤、异构流数据表订阅等。</td></tr></table>
更多 API 介绍请查看相关 API 白皮书。
### 8.2 插件
DolphinDB 提供了多达 30 余种插件,涵盖了数据导入导出、金融市场、物联网、消息队列、机器学习等多个领域,极大地扩展了 DolphinDB 在数据迁移、行情数据获取、数据分析等方面的应用能力。在最新版本中,DolphinDB 将所有的插件集成到插件市场中,进一步方便用户快速下载、安装和使用插件。
表 4. 插件列表
<table id="cross-table-2"><tr><td>插件分类</td><td>插件</td></tr><tr><td>数据导入、交互与转换</td><td>aws, feather, hbase, hdf5, hdfs, kdb, matlab, mongodb, mseed, mysql, odbc, parquet</td></tr><tr><td rowspan="2">流数据</td><td>行情数据:amdQuote, insight, nsq</td></tr><tr><td>流计算应用:MatchingEngine</td></tr><tr><td>消息队列</td><td>HttpClient, kafka , mqtt, zmq</td></tr><tr></tr><tr><td>物联网数据处理与传 opc, opcua, signal <br> 输</td><td></td></tr><tr><td>机器学习</td><td>libsvm, xgboost</td></tr><tr><td>其它工具</td><td>py, zlib, gp, formatArrow, orc</td></tr></table>
8 - 生态
## 表 4. 插件列表 (续)
### 8.3 集成开发环境
DolphinDB 提供了集成开发环境(Integrated Development Environment,IDE),包括 VS Code、Web、GUI 等,帮助开发人员更高效地进行数据库应用程序的开发、调试和管理。
## VS Code 插件
VS Code 是由微软开发的一款轻量、高性能且具有极强扩展性的代码编辑器,深受开发者欢迎。为了方便用户进行开发,DolphinDB 开发了 VS Code 插件,使用户能够在 VS Code 中编写和运行 DolphinDB 脚本,执行创建、连接、查看 DolphinDB 数据库等一系列操作。该插件具有以下特点:
- 代码高亮。
- 关键字、常量、内置函数的代码补全、内置函数文档和参数提示。
- 终端展示代码执行结果以及 print 输出。
- 在底栏中展示任务执行状态,点击后可取消作业。
- 在底部面板中展示表格、向量、矩阵等数据结构;在浏览器弹窗中显示表格。
- 在侧边面板中管理多个数据库连接,展示会话变量。
- 脚本调试功能,包括实时追踪、变量值显示和函数调用栈信息。
## Web
Web 集群管理提供了一个通过浏览器对 DolphinDB 集群进行操作的便捷界面。它支持以下功能:
·集群总览:Web 提供了可以查看集群,通过该页面开启或关闭数据节点和计算节点,可以查看并修改各个节点的配置参数,也可以查看各个节点的任务负载、内存和 CPU 使用量等信息。
・交互编程:在该页面可以编写脚本,并在浏览器中查看数据库、变量、数据、日志内容。通过界面上的数据库浏览器,用户可以以低代码的方式创建数据库和数据表、添加列和注释,以及查看已创建数据库及其所属表的信息。
- 查询向导与脚本查询:Web 界面提供了向导查询和脚本查询两种方式。向导查询通过简单的表单填写, 帮助用户设置查询条件,并动态生成 SQL 语句,使用户无需深入了解复杂的 SQL 语法即可轻松查询数据。查询成功后,用户可以直接预览并导出 CSV 格式的结果数据。对于熟悉 SQL 的用户,脚本查询功能允许他们直接在界面上编写和执行 SQL 脚本,灵活自由地查询数据,并同样支持结果的预览和导出。
- 数据面板(Dashboard):Dashboard 是一个功能全面的数据可视化工具,通过直观的图表展现,帮助用户更深入地理解和利用数据。它支持多种图表类型,用户可以根据需求自定义布局、颜色和数据源,实现个性化的数据展示。同时,数据面板还支持实时数据更新,确保用户始终掌握最新的信息。
·作业管理与流计算监控:Web 端的作业管理界面提供了查看、停止和删除作业的功能,方便用户对作业进行统一管理。而流计算监控功能则实时监控各类流计算任务的状态,包括发布订阅状态、引擎状态和流数据表状态等,帮助用户随时掌握流计算任务的运行情况。
GUI
GUI 是 DolphinDB 前期开发的一款基于 Java 的图形化界面工具。它可以在所有支持 Java 的操作系统上运行,包括但不限于 Windows、Linux 以及 Mac 系统。它为用户提供了直观且便捷的操作体验,通过 GUI 可以方便地管理 DolphinDB 脚本、模块,查看运行结果、与数据库进行交互等。GUI 具有快速、功能全面、用户友好的特点,适用于管理和开发 DolphinDB 脚本、模块和数据库交互,以及查看运行结果等。GUI 提供了友好的编程界面,包括文本查找替换、保留字高亮显示、系统函数提示、行号显示、选择部分代码执行、执行结果浏览、日志信息、临时变量浏览和数据库浏览等功能。通过 Project 浏览器,用户可以轻松查看和管理所有项目;通过 Database 浏览器,用户可以查看所有 DFS 数据库及其分区表的模式。
### 8.4 可视化
DolphinDB 自身已集成 Dashboard 提供计算结果、流数据实时可视化的方案。
此外,与众多第三方前端可视化组件集成,提供数据展示、实时监控、BI 报表分析等强大功能。
图 11. DolphinDB 前端可视化支持

### 8.5 作业调度工具
DolphinDB 内置了脚本语言和丰富的函数库,可用于实现数据存储、计算、分析、仿真和监控等任务。当任务较为简单,不存在依赖关系时,可以使用 DolphinDB 内置的 scheduleJob 功能编排作业。当涉及到任务之间复杂依赖关系时,推荐使用 Airflow 和 DolphinScheduler 等专业的作业调度工具。DolphinDB 已经与 Airflow 和 DolphinScheduler 进行了深度集成,构建了一个强大的数据处理和调度系统。
Airflow 是一个可编程、调度和监控工作流的平台,它允许用户定义一组有依赖关系的任务,并按照依赖关系依次执行。通过 DolphinDBOperator,Airflow 可以连接 DolphinDB 数据库,实现数据写入、查询、计算等操作。这使得用户可以在 Airflow 中按照逻辑指定 DolphinDB 任务,实现任务的编排和调度。
8 - 生态
DolphinScheduler 作为一个分布式、易于扩展的任务调度系统,也支持对 DolphinDB 任务的调度。通过将 DolphinDB 集成到 DolphinScheduler 中,用户可以利用 DolphinScheduler 的调度能力,按照任务之间的依赖关系和条件关系进行编排和调度。这样,任务代码和任务之间逻辑关系的分离使得每个部分都能专注于发挥自己的作用,提高了系统的可维护性和灵活性。
DolphinDB 与作业调度平台的结合,可以帮助用户可以更高效地管理数据ETL作业和任务,提升数据处理效率,并推动业务的快速发展和创新。
### 8.6 信创支持
DolphinDB 于2021年入选信创工委会会员单位,对信创生态有较为完善的支持,且运行在信创服务器及系统上较非新创环境无显著性能差异。
图 12. DolphinDB 信创兼容概览

## 信创 CPU 兼容明细
表 5. DolphinDB 信创 CPU 兼容明细表
<table><tr><td>公司名称</td><td>指令集体系</td><td>是否已兼容</td><td>是否有兼容性证书</td><td>平台</td></tr><tr><td>海光</td><td>x86</td><td>是</td><td>是</td><td>海光3000、5000、7000系列</td></tr><tr><td>兆芯</td><td>x86</td><td>是</td><td>是</td><td>兆芯 ZX-C、ZX-C+、KX-5000、KX-6000、KH-20000、 KH-30000系列处理器平台</td></tr><tr><td>龙芯</td><td>MIPS LoongArch</td><td>是</td><td>是</td><td>龙芯3A3000/3B3000/2K1000</td></tr><tr><td>鲲鹏</td><td>ARMv8</td><td>是</td><td>是</td><td>鲲鹏916、鲲鹏920</td></tr></table>
8 - 生态
表 5. DolphinDB 信创 CPU 兼容明细表 (续)
<table><tr><td>公司名称</td><td>指令集体系</td><td>是否已兼容</td><td>是否有兼容性证书</td><td>平台</td></tr><tr><td>飞腾</td><td>ARMv8</td><td>是</td><td>是</td><td>FT-1500A/16、FT-2000+/64、飞腾腾云 S2500处理器平台</td></tr></table>
## 信创操作系统兼容明细
表 6. DolphinDB 信创操作系统兼容明细表
<table><tr><td>系统名称</td><td>是否已兼容</td><td>是否有兼容性证书</td><td>版本</td></tr><tr><td>统信 UOS</td><td>是</td><td>是</td><td>统信服务器操作系统 V20</td></tr><tr><td>银河麒麟 KYLIN</td><td>是</td><td>是</td><td>银河麒麟高级服务器操作系统V10</td></tr><tr><td>中标麒麟 Neokylin</td><td>是</td><td>是</td><td></td></tr><tr><td>浪潮信息 KOS</td><td>是</td><td>是</td><td>浪潮信息KOS V5 x86_64版本 <br> 浪潮信息KOS V5 aarch64版本</td></tr><tr><td>超聚变 FusionOS22</td><td>是</td><td>是</td><td>FusionOS22</td></tr><tr><td>龙蜥 OpenAnolis</td><td>是</td><td>是</td><td></td></tr></table>
FILE:references/whitepapers/streaming.md
# DolphinDB 白皮书 流数据

## 内容
第 1 章. 概述. . iii
1.1 流处理示例. .4
1.2 流处理架构 5
第 2 章. 发布与订阅 .8
2.1 流数据表. .8
2.2 发布与订阅 9
2.3 功能特性. 10
第 3 章. 流计算引擎. 12
3.1 引擎分类. 12
3.2 引擎详解 .13
3.3 功能特性 .27
3.4 流式算子. .28
3.5 流水线处理 28
第 4 章. 流批一体. .31
4.1 历史数据回放 .31
4.2 流批一体实现方案 .34
第 5 章. 流数据运维. .37
5.1 权限管理. 37
5.2 流数据监控. 39
5.3 流数据高可用 41
第 6 章. 流计算 API 及插件 .44
6.1 流计算 API. 44
6.2 流计算插件 45
第 7 章. 场景应用 .46
7.1 金融. 46
7.2 物联网 51
第 8 章. 结语. 55
## DolphinDB 流数据白皮书
流数据是一种持续实时生成且动态变化的时间序列数据,涵盖了金融交易、物联网(IoT)传感器采集、物流运营、零售订单等各类持续生成动态数据的场景。DolphinDB 将时间序列数据库与流数据处理框架无缝集成,不仅可以处理海量的历史数据,还广泛支持了实时数据的流式计算,包括流数据发布与订阅、数据预处理、实时内存计算、复杂指标的窗口计算、异常检测、多数据源实时关联等。借助 DolphinDB,企业可以高效地过滤、关联、分析和可视化大规模实时流数据,从中预测趋势、监测异常,辅助实时决策。
本白皮书旨在介绍 DolphinDB 的流数据处理框架、功能特性及应用场景,主要包括以下几个方面:
- 流数据的概念和特点
- 流数据处理框架及实现
- 流数据操作与功能特性
- 流数据应用场景与案例
## 第 1 章. 概述
### 1.1 流处理示例
首先通过简单的 DolphinDB 脚本介绍流数据的订阅与处理过程。
---
// 创建并共享流数据表 pubTable 与 outputTable
share(streamTable(1:0, `time`id`price`qty, [TIME, SYMBOL, DOUBLE, LONG]),
"pubTable")
share(streamTable(1:0, `time`id`price`qty`amount, [TIME, SYMBOL, DOUBLE, LONG,
DOUBLE]), "outputTable")
go
// 定义流处理方法
def streamProcessFunc(msg)\{
t = select time, id, price, qty, price*qty as amount from msg
outputTable.append!(t)
\}
// 提交流订阅
subscribeTable(tableName="pubTable", actionName="demo1", offset=-1,
handler=streamProcessFunc, msgAsTable=true)
// 注入数据到发布表
insert into pubTable values(09:51:49.581, "GOOG", 2.6, 100)
---
上例演示了 DolphinDB 基本的流订阅流程:
- 首先通过 streamTable 函数创建流数据表 pubTable 作为流数据发布表,outputTable 作为订阅数据的接收表。执行 share 语句实现流数据表会话间共享。
·定义函数 streamProcessFunc 用于计算每条消息价格和数量的乘积得出交易总量,并输出到流数据表 outputTable。
-执行 subscribeTable 函数提交订阅,并指定 streamProcessFunc 为数据处理方法。系统会分配后台线程处理订阅到的数据。
- 向发布表 pubTable 插入数据。数据被推送至消费队列,订阅端后台线程处理数据并将结果推送至输出表 outputTable。
图 1-1 流数据订阅示例

### 1.2 流处理架构
#### 1.2.1 流数据处理
流数据是基于事件持续生成的时间序列数据。与静态有界的历史数据不同,流数据具有以下特点:
- 动态:数据流持续动态生成,流的结束没有明确定义,数据的大小与结构也没有固定限制。
- 有序:每条流数据记录都具有时间戳或者序列号,标识了数据在流中的位置与顺序。
·大规模:流数据通常以高速率生成,数据规模大,对处理引擎的并行处理性能和可扩展性有更高要求。
・强时效:流数据的强时效性要求极低延迟的读取和处理能力,以最大化数据价值,驱动实时业务决策。
流数据处理是指在实时数据流上进行实时计算和分析的过程。与批处理不同,流处理无需等待所有数据全部到位,即可按照时间顺序对数据进行增量处理。这种实时处理方式能够高效利用存储与计算资源,适用于需要快速响应和及时决策的应用场景。
<table><tr><td></td><td>批处理</td><td>流处理</td></tr><tr><td>数据范围</td><td>对数据集中的所有或大部分数据进行查询或处理</td><td>对时间窗口内的数据或对最近的数据记录进行查询或处理</td></tr><tr><td>数据大小</td><td>大批量数据</td><td>单条记录或包含几条记录的小批量数据</td></tr><tr><td>性能</td><td>几分钟至几小时的延迟</td><td>亚毫秒级延迟</td></tr></table>
#### 1.2.2 流处理架构
为实现不同应用场景的业务逻辑,DolphinDB 采用了模块化与可扩展的流处理框架,将核心的流计算组件 (如流数据表、流计算引擎等)设计为可重用的模块。模块可以像积木一样通过发布-订阅的方式灵活组合, 形成功能强大的流水线。此外,DolphinDB 还提供了 1500 多个内置函数,可用作流计算引擎的算子,极大简化了流计算应用的开发过程。同时,用户也可以根据业务需求使用自定义函数实现复杂指标计算,即使是复杂
1 - 概述
的金融算法也可以通过 DolphinDB 的脚本语言灵活实现。此外,JIT 编译等技术的应用也进一步提高了流计算的性能。
## 图 1-2 流数据处理框架

上图展示了 DolphinDB 流数据处理框架。实时数据注入到流数据发布表后可同时供多方订阅消费:
·流数据计算引擎:流数据计算引擎可以订阅流数据进行实时分析。计算结果可以通过可视化平台如 Grafana 进行实时展示,也可以再次发布,供其他数据节点或应用进行二次订阅和事件处理。
・API 客户端:通过 DolphinDB API,第三方客户端如 Python 应用程序可以方便地订阅流数据,进行业务操作。这种灵活的 API 订阅方式使得 DolphinDB 的流数据可以被集成到各种应用场景中,满足多样化的实时数据需求。
·消息中间件:将流数据实时灌注到消息中间件(如 Apache Kafka)的消息队列中,供下游模块订阅程序消费。
- 数据仓库:数据仓库可以订阅并保存流数据,作为分析系统与报表系统的数据源。可以将实时数据用于后续的离线分析和报表生成,实现对历史数据和实时数据的统一分析。
#### 1.2.3 发布/订阅 (Pub/Sub) 模型
DolphinDB 采用了经典的发布/订阅 (Pub/Sub) 通信模型,通过消息队列实现流数据的发布与订阅。该模型将流数据发布端与订阅端解耦,各模块支持独立开发管理,可以增强系统的可拓展性并提升发送者的响应效率。
图 1-3 发布/订阅模型

发布数据:发布端在每个节点上维护一个发布队列。当新的流数据注入到该节点的流数据发布表
时,DolphinDB 会将这些数据推送到相应的消息发布队列,再由发布线程将数据发布到各个订阅端的消费队列。
订阅数据:每个订阅线程对应一个消费队列。订阅成功提交后,每当有新数据写入流数据发布表时,DolphinDB 会主动通知所有订阅方,消费线程从消费队列中获取数据进行增量处理。
## 第 2 章. 发布与订阅
### 2.1 流数据表
#### 2.1.1 创建与删除流数据表
DolphinDB 以流数据表作为实时数据流的载体进行流数据的存储、发布与订阅。流数据表是一种特殊的内存表,包括常规流数据表、键值流数据表与高可用流数据表。流数据表可以视为简化的消息中间件,或是消息中间件中的主题(topic),用户可以向其发布数据,也可以从中订阅数据。
用户可以执行 streamTable 函数创建流数据表。与普通内存表不同,流数据表中的记录支持同时读写, 可以增加记录,但不可修改或删除。使用 share 语句将流数据表共享到所有会话后,表中数据即可被订阅。DolphinDB 支持多个会话中的多个订阅端订阅同一个流数据表。实时数据写入该表后,会向所有订阅该表的订阅端推送数据。
---
colName=["Name","Age"]
colType=["string","int"]
t = streamTable(1:0, colName, colType)
share t as st1
---
通过 streamTable 函数创建的流数据表可以包含重复记录。在订阅多个数据源时,如要避免数据的重复写入,可以使用 keyedStreamTable 函数创建包含主键的键值流数据表。表中主键不包含重复值,如果新写入的数据与已有记录的主键重复,不会更新已有记录。用户也可以使用 haStreamTable 函数创建高可用流数据表,高可用流数据表在日志中持久化了表结构信息,节点重启后不需要重新建表。同时,高可用流数据表也可以通过设置主键过滤重复记录。关于流数据高可用的详细解决方案,请参阅5.3 流数据高可用小节。
用户可以在取消所有订阅后使用 dropStreamTable 删除流数据表。例如,删除上述语句创建的共享流数据表 st1:
---
dropStreamTable(`st1)
---
#### 2.1.2 持久化流数据表
流数据表本质是特殊的内存表,系统在默认情况下会把流数据表的所有数据都保存在内存中。由于流数据持续增长的特性,内存可能会被逐渐耗尽,DolphinDB 因此支持了流数据表持久化功能,用户可将内存中的流数据以异步或同步的方式保存到磁盘中。
要持久化流数据表,首先需要在发布节点设置持久化路径参数 persistenceDir,创建流数据表后执行 enableTableShareAndPersistence 命令共享并持久化流数据表。用户也可以执行 share 语句共享流数据表后再通过 enableTablePersistence 命令持久化流数据表。持久化函数的参数设定可能会影响流数据系统的性能,其中:
·asynWrite 指定是否以异步模式持久化数据到磁盘。采用异步持久化的方式可以提高系统的吞吐量,但是节点重启可能会导致最后几条数据丢失。
- compress 指定是否将持久化的数据压缩后保存到磁盘。数据压缩可以减少磁盘写入量和空间占用。
- cacheSize 限制了流数据表在内存中保留的最大记录数。设置合理的内存占用量可以有效保证数据安全。
- flushMode 表示是否开启同步刷盘。内存中的流数据首先写入操作系统缓存,若开启同步刷盘,一批数据落盘后才会开始下一批数据的写入。
开启流数据表持久化有以下优点:
- 当前最新的一批记录保留在内存中,较早的记录保存在磁盘中,能够有效避免内存不足问题。
- 如发生节点异常重启,用户调用持久化命令会将持久化的流数据重新载入表中。
·流订阅可以从磁盘上保存记录的偏移量重新开始。
下表对比了常规流数据表、共享流数据表与持久化流数据表。
<table><tr><td></td><td>流数据表</td><td>共享流数据表</td><td>持久化流数据表</td></tr><tr><td>生命周期</td><td>当前会话</td><td>当前节点</td><td>重启后仍可加载</td></tr><tr><td>其他会话可见</td><td>否</td><td>是</td><td>是</td></tr><tr><td>可被订阅</td><td>否</td><td>是</td><td>是</td></tr><tr><td>存储方式</td><td>仅内存</td><td>仅内存</td><td>内存和磁盘</td></tr><tr><td>重启后可恢复</td><td>否</td><td>否</td><td>是</td></tr></table>
### 2.2 发布与订阅
#### 2.2.1 发布
DolphinDB 流计算框架采用了发布-订阅的模式。流数据发布首先要定义共享流数据表,实时写入该表的数据将会发布到所有订阅端。流表可部署于 DolphinDB 的数据节点或计算节点上,其所在的节点称为发布节点, 订阅方所在的节点称为订阅节点。例如,通过以下脚本定义并共享流数据表 pubTable:
share streamTable(1:0, `timestamp` temperature, [TIMESTAMP, DOUBLE]) as pubTable
DolphinDB 支持多种方式写入共享流数据表。在研究阶段,用户可以通过 append!或 insert into 语句直接向流数据表写入数据,也可以使用 DolphinDB 内置的 replay 函数将库内历史数据以指定速率回放,模拟流的形式注入流数据表。在实际生产中,可以通过插件将外部数据源产生的记录实时接入流数据表,或通过 DolphinDB API 的写入接口将外部数据写入流数据表。具体使用示例参见 用户手册-实时流数据接入。
#### 2.2.2 订阅
流数据的订阅方和发布方可以处于同一个节点、同一集群中的不同节点、或不同集群中的节点。外部的客户端应用也可以向 DolphinDB 订阅数据。SubExecutor 是 DolphinDB 集群中的消息处理线程,DolphinDB 的一个数据节点或计算节点对应一个进程,每个节点上会有一到多个消息处理线程。若订阅方位于 DolphinDB 节点上,则对应的消费会被分配到后台线程上运行。若订阅方处于外部客户端,则消费运行在外部程序中。
2 - 发布与订阅
## 图 2-1 DolphinDB 订阅模式

在 DolphinDB 中,用户可以通过 subscribeTable 函数订阅流数据表。只需指定表或引擎名称与数据处理方法即可创建订阅关系,函数也提供了丰富的可选参数用于灵活配置订阅。流处理示例小节演示了基本的订阅流程,通过 subscribeTable 提交订阅后,系统会分配一个后台消费线程接收并处理发布表新增的数据,并把处理后的数据推送至输出表。使用 subscribeTable 函数提交订阅脚本编写简单,在内存中直接处理数据, 降低了数据传输和转换的开销。
DolphinDB API 提供了类似 subscribeTable 的流订阅接口,用户可以在第三方客户端(例如 Python 应用程序)直接订阅 DolphinDB 的流数据表。这种订阅模式可以方便地与其他语言集成,将 DolphinDB 中的流数据应用到各种业务场景中,满足多样化的实时数据需求。
用户也可以通过插件订阅外部的消息中间件(如 Apache Kafka,ZeroMQ 等)的数据。例如可以使用 DolphinDB kafka 插件的 subscribe 接口订阅 Kafka 主题。通过插件对接外部消息中间件实现了数据生产与消费者间的解耦的订阅关系,灵活适应各种数据类型与协议。
### 2.3 功能特性
DolphinDB 的流数据订阅实现了以下功能:
·发布数据过滤:支持指定发布表的过滤列与过滤规则,只将符合特定条件的数据发送给订阅者。发布数据的过滤能够有效减少传输的数据量,提高传输的效率。
·自定义起始偏移量:用户在发起订阅时可以通过参数指定任意起始偏移位置,订阅偏移量与流数据表的行数一一对应,订阅可以从指定偏移量的对应位置开始消费。
·本地及远程订阅:DolphinDB 的发布/订阅模型支持本地和远程订阅,订阅者可以在同一台服务器上或不同服务器之间订阅数据,更好地满足分布式数据处理的需求。远程订阅采用了 TCP/IP 通信协议,保证数据传输的可靠性和实时性。
·多方订阅:发布订阅模型允许多个订阅者同时订阅同一个数据流,实现多方同时消费数据的功能。这为数据的共享和多样化的数据处理需求提供了便利。
·断线重连:在流数据传输过程中,如果订阅者因网络故障或其他原因与服务端断开连接,订阅可以自动重连确保数据传输的稳定性。开启断线重连后,订阅端会记录流数据发布的偏移量,连接恢复时订阅端会从偏移量开始重新订阅。
## 第 3 章. 流计算引擎
使用 DolphinDB 处理历史数据时,可以结合 SQL 语句与内置函数进行全量或增量的查询和计算。但实时数据场景要求高效即时处理,全量查询和计算无法满足这种需求。因此,DolphinDB 研发了适合流式处理的计算引擎,在系统内部采用增量计算,优化了实时计算的性能。流计算引擎是 DolphinDB 实时数据处理解决方案的核心组件,可以视作封装的独立计算黑盒,通过向其写入数据触发计算,并将计算结果输出到目标表。DolphinDB 系统内置了十余种流数据计算引擎,本节会详细介绍引擎分类,主要引擎的计算规则与应用场景,并辅以典型示例进行说明。
### 3.1 引擎分类
DolphinDB 流计算引擎提供了灵活的计算方式和丰富的计算功能,适用于多样化的实时数据处理需求。根据参与计算的表数量和类型,流计算引擎可以分为单表计算和多表连接两种类型:
图 3-1 流计算引擎分类

单表计算引擎应用于单个流数据表:
- 分组内时序计算:对数据进行分组,在组内进行逐条计算、窗口聚合或异常检测。
- 跨分组截面计算:对数据进行分组,选取每组的最新数据进行截面计算。
多表连接类似于 SQL 表连接 (JOIN) 操作,用于实时关联两张表。连接引擎的左表都是流数据表,根据右表的类型不同,多表连接可以分为双流关联和维表关联:
·双流关联(右表是流数据表):根据数据的时序关系进行等值或模糊匹配。
- 维表关联(右表可以是流数据表或静态维度表):流数据表实时关联右表快照。
### 3.2 引擎详解
#### 3.2.1 单表计算引擎
## (1)响应式状态引擎(createReactiveStateEngine)
## 计算规则:
响应式状态引擎能够即时响应注入数据,每当有新的数据到达引擎即触发一次计算,并输出一条计算结果。DolphinDB 针对生产业务中常用的状态算子(滑动窗口函数、累积函数、序列相关函数和 topN 相关函数等)进行了优化,采用增量算法大幅提升了这些算子在引擎中的计算效率。在 DolphinDB 提供的内置函数中,响应式状态引擎目前仅支持系统优化过的状态函数;如需实现更加复杂的计算逻辑,用户也可以通过 @state 声明自定义函数封装复杂的状态算子。
## 应用场景:
响应式状态引擎能够快速响应新数据,适用于对单条数据即时响应并实时更新输出计算结果的高频计算场景, 例如:
・金融:实时计算高频因子,如基于快照数据计算股票的短时涨幅等。
•物联网:检测传感器状态的变化,如实时监控温度、湿度、压力等数据指标的波动。
## 使用案例:实时计算 5 分钟涨速
本例通过回放一天的快照行情数据模拟实时数据流,响应式状态引擎实时响应每条输入数据,并基于当前数据计算并输出过去 5 分钟涨速。
---
// 定义流数据发布表与结果输出表
schemaTable = loadTable("dfs://SH_TSDB_snapshot_ArrayVector",
"snapshot").schema().colDefs
share(streamTable(1:0, schemaTable.name, schemaTable.typeString),
`snapshotStreamTable)
share(streamTable(1:0, ["SecurityID", "DateTime", "factor_5min"], [SYMBOL,
TIMESTAMP, DOUBLE]), `changeResultTable)
go
// 定义自定义状态函数
@state
def calculateChange(DateTime, LastPx, lag)\{
PREVLASTPX = tmove(DateTime, LastPx, lag)
return (LastPx - PREVLASTPX) \\ PREVLASTPX
\}
// 定义响应式状态引擎
metrics=<[DateTime, calculateChange(DateTime, LastPx, lag=5m)]>
rse = createReactiveStateEngine(name="calChange", metrics=metrics,
dummyTable=snapshotStreamTable, outputTable=changeResultTable,
keyColumn=`SecurityID)
## // 订阅上游输入表
subscribeTable(tableName="snapshotStreamTable", actionName="snapshotFilter",
offset=-1, handler=rse, msgAsTable=true, hash=0)
// 后台提交回放任务
data = replayDS(sqlObj=<select * from
loadTable("dfs://SH_TSDB_snapshot_ArrayVector", "snapshot") where
date(DateTime)=2021.12.01>, dateColumn=`DateTime, timeColumn=`DateTime,
timeRepartitionSchema=09:00:00 + 0..6 * 60*60)
submitJob("snapshotReplay", "replay snapshot", replay\{inputTables=data,
outputTables=objByName("snapshotStreamTable"), dateColumn=`DateTime,
timeColumn=`DateTime, replayRate=5000, absoluteRate=true\})
---
本例创建了响应式状态引擎,注入引擎的数据按 SecurityID 分组后,根据 metrics 参数指定的计算指标进行计算。@state 标识了自定义状态函数 calculateChange,该指标首先通过 tmove 函数获取 5 分钟前的价格 PREVLASTPX, 再通过 (LastPx - PREVLASTPX) \\ PREVLASTPX 计算涨速。
## (2)时间序列聚合引擎(createTimeSeriesEngine)
## 计算规则:
时间序列聚合引擎以时间度量窗口,根据指定的窗口长度与频率对窗口内的数据进行滑动聚合计算。引擎会根据创建时的参数自动划分和关闭窗口,对窗口内同一个分组内的全部数据应用聚合规则,输出一条结果。
用户可以通过引擎的参数指定基于事件时间 (Event Time) 或系统处理时间 (Processing Time) 的滑动窗口。在股票交易等领域中,实际成交的时刻被记录为事件时间,而引擎处理这些记录的时刻则为系统处理时间。由于通信延迟、调度延迟等因素的影响,事件时间和系统处理时间之间可能存在偏差。在实际应用中,使用系统时间能够提供较低的延迟,而使用事件时间则能确保实盘和回放结果的一致性。
## 应用场景:
时间序列聚合引擎能够快速生成周期性的统计数据,适用于需要基于固定时间窗口分组计算聚合指标的场景, 例如:
- 金融:计算周期性统计指标,如 1 分钟 K 线、 5 分钟 K 线等。
•物联网: 对大量传感器数据进行降采样,如计算设备每 10 分钟内的平均温度。
## 使用案例:计算 1 分钟 K 线
本例通过回放一天的逐笔成交数据模拟实时数据流,使用时间序列聚合引擎生成 1 分钟 K 线和成交量加权平均价格 VWAP。
---
// 创建输入表 tickStream,输出表 OHLCStream
colName =
`SecurityID`TradeTime`TradePrice`TradeQty`TradeAmount`BuyNum`SellNum`TradeIndex`Cha
nnelNo` TradeBSFlag `BizIndex
colType = [SYMBOL, TIMESTAMP, DOUBLE, INT, DOUBLE, INT, INT, INT, INT, SYMBOL, INT]
share(streamTable(1:0, colName, colType), `tickStream)
colName = `TradeTime` SecurityID`OpenPrice`HighPrice`LowPrice`ClosePrice`Vwap
colType = [TIMESTAMP, SYMBOL, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]
share(streamTable(1:0, colName, colType), `OHLCStream)
// 创建时序聚合引擎
aggrMetrics = <[ first(TradePrice), max(TradePrice), min(TradePrice),
last(TradePrice), wavg(TradePrice, TradeQty) ]>
createTimeSeriesEngine(name="OHLCVwap", windowSize=60000,
step=60000, metrics=aggrMetrics, dummyTable=objByName("tickStream"),
outputTable=objByName("OHLCStream"), timeColumn="TradeTime", useSystemTime=false,
keyColumn=`SecurityID, useWindowStartTime=false)
// 订阅 tickStream 表
subscribeTable(tableName="tickStream", actionName="OHLCVwap", offset=-1,
handler=getStreamEngine("OHLCVwap"), msgAsTable=true, batchSize=1000, throttle=1,
hash=0)
## // 回放历史数据
testData = select * from loadTable("dfs://SH_TSDB_tick", "tick")
where date(TradeTime)=2021.12.08, time(TradeTime)>=09:30:00.000,
time(TradeTime)<=10:30:00.000 order by TradeTime, SecurityID
submit]ob("replay", "replay", replay, testData, objByName("tickStream"), `TradeTime,
`TradeTime, 200000, true, 1)
---
本例创建了时间序列聚合引擎 OHLCVwap,指定窗口长度为 1 分钟、步长为 1 分钟的滚动窗口,按 SecurityID 对注入数据分组。参数 metrics 指定了窗口内的聚合规则,分别是价格的高开低收和加权平均值。first 等内置函数在时序聚合引擎内部支持了增量计算,每条数据到来都会计算并更新中间结果,而不是在数据全部到齐、窗口关闭时才进行批量计算。
## (3)日级时间序列聚合引擎(createDailyTimeSeriesEngine)
## 计算规则:
日级时间序列聚合引擎在时序聚合引擎的基础上进一步扩展,除了时序引擎的全部功能外,还可以指定交易时间段,将一个自然日内各个交易时段开始之前的所有未参与计算的数据并入该交易时段的第一个窗口进行计算。
## 应用场景:
日级时序聚合引擎适用于在股票、期货市场等有固定交易时段的场景中,例如:
- 股票:对每个交易时段进行数据聚合,获取开盘价、收盘价等指标。
- 期货:与股票市场类似,可计算每个交易时段的均价、成交量等数据。
## (4)会话窗口引擎(createSessionWindowEngine)
## 计算规则:
会话窗口引擎根据指定事件的活跃频率划分会话窗口,其计算规则和触发计算的方式与时间序列引擎相同。但不同于时间序列引擎具有固定的窗口长度和滑动步长,会话窗口不按固定的频率产生,其窗口长度也是动态变化的。
3 - 流计算引擎
## 应用场景:
会话窗口引擎适用于需要根据事件情况动态划分窗口的场景,例如:
·金融:市场中一次交易会话可以涵盖一段时间内的所有交易操作,而交易活跃的频率可能会受到市场波动的影响,可以统计每个交易会话内的交易指标,如成交量、交易金额等。
• 物联网:统计设备的活跃或不在线时段。例如,统计设备在一天内的活跃时段,或者分析设备在线和离线的模式。
## (5)异常检测引擎(createAnomalyDetectionEngine)
## 计算规则:
异常检测引擎根据指定的条件指标,实时监测流数据,自动筛查并输出符合条件的异常信息。异常检测引擎要求以元代码的形式指定一组用于异常检测判定的布尔表达式,其中可以包含聚合函数、数据列和常量。如指定了聚合指标,也需同步指定聚合计算的窗口长度与计算间隔。下表列举了常见的异常检测指标类型:
<table><tr><td>类型</td><td>示例</td><td>计算规则</td></tr><tr><td>聚合函数 + 常量</td><td>avg(temp) > 60</td><td>将每个窗口的聚合值与常量进行比较</td></tr><tr><td>聚合函数 + 数据列</td><td>temp > percentile(temp, 75)</td><td>将当前窗口的每条记录与上一个窗口的聚合值进行比较</td></tr><tr><td>数据列 + 常量</td><td>temp > 65</td><td>将每条记录与常量进行比较</td></tr></table>
## 应用场景:
异常检测引擎适用于需要实时监控数据并输出异常预警的场景,例如:
- 金融:监控交易记录,检测是否存在异常交易行为,如不合理的交易金额、交易过于频繁等。
·物联网:应用于采集、计算和分析过程中,检测设备传感器数据的异常指标,例如异常温度、湿度等。
## 使用案例:设备异常状态检测
下例使用了异常检测引擎监测设备的异常温度信息。
// 定义流数据表 sensor 接收采集的数据
share streamTable(1:0, `time`temp, [TIMESTAMP, DOUBLE]) as sensor
// 定义异常检测引擎和输出表
share streamTable(1:0, `time` anomalyType` anomalyString, [TIMESTAMP, INT, SYMBOL]) as outputTable
engine = createAnomalyDetectionEngine("engine1", <[temp > 65, temp >
percentile(temp, 75), avg(temp) > 60]>, sensor, outputTable, `time,
, 6, 3)
// 异常检测引擎 engine 订阅流数据表 sensor
subscribeTable(, "sensor", "sensorAnomalyDetection", 0, append!\{engine\}, true)
// 向流数据表 sensor 中写入 10 条数据模拟采集温度
---
timev = 2018.10.08T01:01:01.001 + 1..10
tempv = 59665760635153525655
insert into sensor values(timev, tempv)
---
本例规定了以下异常指标:(1)单次采集的温度超过 65;(2)单次采集的温度超过上一个窗口中 75% 的值;(3)平均温度超过 60。采集的数据推送到流数据表中,异常检测引擎通过订阅流数据表来获取实时数据进行异常检测,并将符合异常指标的数据输出到结果表中。
引擎输出异常信息如下:
横截面引擎对注入数据分组,并取每组数据的最新记录进行计算。横截面引擎主要由两个部分组成:横截面数据
<table><tr><td></td><td>time</td><td>anomalyType</td><td>anomalyString</td></tr><tr><td>0</td><td>2018.10.08 01:01:01.003</td><td>0</td><td>temp > 65</td></tr><tr><td>1</td><td>2018.10.08 01:01:01.003</td><td>1</td><td>temp > percentile(temp, 75)</td></tr><tr><td>2</td><td>2018.10.08 01:01:01.005</td><td>1</td><td>temp > percentile(temp, 75)</td></tr><tr><td>3</td><td>2018.10.08 01:01:01.006</td><td>2</td><td>avg(temp) > 60</td></tr><tr><td>4</td><td>2018.10.08 01:01:01.006</td><td>1</td><td>temp > percentile(temp, 75)</td></tr></table>
5 rows 3 columns table 4
## (6) 横截面引擎 (createCrossSectionalEngine)
计算规则:
横截面引擎对注入数据分组,并取每组数据的最新记录进行计算。横截面引擎主要由两个部分组成:横截面数据表和计算引擎。横截面数据表保存着各个分组的最新记录。计算引擎则包含一组聚合计算表达式和触发器, 根据指定的规则触发对横截面数据表的计算,计算结果将被保存到指定的输出表中。
## 应用场景:
横截面引擎适用于对分组的最新数据进行横向比较和计算,例如:
·金融:基于某个指数所有成分股的最新价格计算该指数的内在价值。
- 工业物联网:对一批设备的最新温度求最值。
## 使用案例:监控各时刻所有股票逐笔成交总额
本例通过回放一天所有股票的逐笔成交总额,通过横截面引擎实时获取交易高峰时段。
// 加载数据
path = "/home/data/csTestData.csv"
data=loadText(path)
colName = extractTextSchema(path).name
colType = extractTextSchema(path).type
3 - 流计算引擎
// 清理流计算环境
dropStreamEngine("csEngineDemo")
unsubscribeTable(tableName=`tick, actionName="csEngineDemo")
## // 定义输入表与输出表
share streamTable(1:0, colName, colType) as tick
share streamTable(1:0, `TradeTime`Amount, [TIMESTAMP, DOUBLE]) as opt
// 创建引擎
csEngine=createCrossSectionalEngine(name="csEngineDemo",
metrics=<[sum(TradeAmount)]>, dummyTable=tick, outputTable=opt,
keyColumn=`Date`SecurityID, triggeringPattern="keyCount", triggeringInterval=1000,
timeColumn=`TradeTime, useSystemTime=false, lastBatchOnly= true)
subscribeTable(tableName='tick', actionName="csEngineDemo", msgAsTable=true,
handler=append!\{csEngine\})
## // 回放历史数据注入引擎
replay(data, tick)
## 本例中输入一天的逐笔成交数据(如图):
<table><tr><td>Date</td><td>SecurityID</td><td>TradeTime</td><td>TradePrice</td><td>TradeQty</td><td>TradeAmount</td><td>BuyNo</td><td>SellNo</td><td>TradeIndex</td><td>ChannelNo</td><td>TradeBSFlag</td><td>BizIndex</td></tr><tr><td>2019.04.02</td><td>601311.SH</td><td>2019.04.02T09:25:00.000</td><td>14.01000000</td><td>300</td><td>4203.00000000</td><td>175,949</td><td>65,893</td><td>311</td><td>3</td><td>'N'</td><td>3,334</td></tr><tr><td>2019.04.02</td><td>601668.SH</td><td>2019.04.02T09:25:00.000</td><td>6.28000000</td><td>300</td><td>1884.00000000</td><td>65,928</td><td>65,929</td><td>2,319</td><td>3</td><td>'N'</td><td>24,232</td></tr><tr><td>2019.04.02</td><td>601997.SH</td><td>2019.04.02T09:25:00.000</td><td>13.39000000</td><td>100</td><td>1339.00000000</td><td>81,474</td><td>81,473</td><td>2,616</td><td>3</td><td>'N'</td><td>25,639</td></tr><tr><td>2019.04.02</td><td>600702.SH</td><td>2019.04.02T09:25:00.000</td><td>33.44000000</td><td>200</td><td>6688.00000000</td><td>73,779</td><td>117,255</td><td>95</td><td>3</td><td>'N'</td><td>1,166</td></tr><tr><td>2019.04.02</td><td>601328.SH</td><td>2019.04.02T09:25:00.000</td><td>6.33000000</td><td>9,300</td><td>58869.000000...</td><td>61,714</td><td>88,703</td><td>2,087</td><td>3</td><td>'N'</td><td>18,094</td></tr><tr><td>2019.04.02</td><td>900957.SH</td><td>2019.04.02T09:25:00.000</td><td>0.76600000</td><td>200</td><td>153.20000000</td><td>1,495</td><td>1,807</td><td>1</td><td>20</td><td>'N'</td><td>94</td></tr><tr><td>2019.04.02</td><td>603517.SH</td><td>2019.04.02T09:25:00.000</td><td>50.98000000</td><td>100</td><td>5098.00000000</td><td>181,507</td><td>160,813</td><td>407</td><td>3</td><td>'N'</td><td>3,562</td></tr><tr><td>2019.04.02</td><td>600111.SH</td><td>2019.04.02T09:25:00.000</td><td>11.55000000</td><td>100</td><td>1155.00000000</td><td>73,774</td><td>23,836</td><td>2,676</td><td>3</td><td>'N'</td><td>28,390</td></tr><tr><td>2019.04.02</td><td>600241.SH</td><td>2019.04.02T09:25:00.000</td><td>7.41000000</td><td>1,300</td><td>9633.00000000</td><td>72,118</td><td>148,402</td><td>1</td><td>3</td><td>'N'</td><td>261</td></tr><tr><td>2019.04.02</td><td>600522.SH</td><td>2019.04.02T09:25:00.000</td><td>10.30000000</td><td>100</td><td>1030.00000000</td><td>73.335</td><td>73,338</td><td>1,884</td><td>3</td><td>'N'</td><td>14,810</td></tr><tr><td>2019.04.02</td><td>601860.SH</td><td>2019.04.02T09:25:00.000</td><td>9.20000000</td><td>500</td><td>4600.00000000</td><td>158.569</td><td>94,187</td><td>131</td><td>6</td><td>'N'</td><td>2,725</td></tr><tr><td>2019.04.02</td><td>600352.SH</td><td>2019.04.02T09:25:00.000</td><td>20.44000000</td><td>300</td><td>6132.00000000</td><td>23</td><td>922</td><td>425</td><td>6</td><td>'N'</td><td>14,700</td></tr><tr><td>2019.04.02</td><td>600928.SH</td><td>2019.04.02T09:25:00.000</td><td>12.21000000</td><td>700</td><td>8547.00000000</td><td>14.711</td><td>8,060</td><td>430</td><td>3</td><td>'N'</td><td>10,900</td></tr><tr><td>2019.04.02</td><td>600128.SH</td><td>2019.04.02T09:25:00.000</td><td>9.47000000</td><td>300</td><td>2841.00000000</td><td>52,805</td><td>74,818</td><td>243</td><td>3</td><td>'N'</td><td>2,107</td></tr></table>
引擎输出如下:

绘制一天中各个交易时间点的交易总额,可见上午 10:00,11:30 前后都呈现了一个交易高峰。
---
AMOUNT = EXEC AMOUNT from OPT
TradeTime = exec TradeTime from opt
plot(Amount, TradeTime)
---

#### 3.2.2 多表连接引擎
## (1)AsofJoin 引擎 (createAsofJoinEngine)
## 关联规则:
Asof Join 引擎按连接列分组,在每个分组内按时间邻近度关联左右表。对于左表的每一条记录,在右表缓存中选取在该条左表记录的时刻之前且最接近(包括时刻相等)的一条记录。在时间序列分析中,模糊临近匹配是一种常见操作。特别是在时间精度较高的场景下,两个表的时间戳往往不会完全匹配。在这种情况下,可以使用 Asof Join 引擎关联两表进行信息整合。
## 应用场景:
Asof Join 引擎主要应用于非等值匹配场景中,可以获取业务相关的最新信息,例如:
·金融:将交易数据与行情数据进行关联,获取特定交易时刻的行情信息。
•物联网:将传感器数据与时间对齐的参考数据关联,实现实时状态监测和分析。
## 使用案例:Asof Join 引擎关联逐笔成交数据和报价数据
由于报价与成交数据发生时间不可能完全一致,往往需要以成交时间为基准找到交易发生前的最近一次报价数据,因此需要以邻近匹配的方式关联两个数据流。
// 创建连接表与输出表
share streamTable(1:0, `Sym`TradeTime`TradePrice, [SYMBOL, TIME, DOUBLE]) as trades share streamTable(1:0, `Sym`Time`Bid1Price`Ask1Price, [SYMBOL, TIME, DOUBLE, DOUBLE]) as snapshot
share streamTable(1:0, `TradeTime`Sym`TradePrice`TradeCost`SnapshotTime, [TIME, SYMBOL, DOUBLE, DOUBLE, TIME]) as output
// 创建 Asof Join 引擎
ajEngine = createAsofJoinEngine(name="asofJoin", leftTable=trades,
rightTable=snapshot, outputTable=output, metrics=<[TradePrice,
abs(TradePrice-(Bid1Price+Ask1Price)/2), snapshot.Time]>, matchingColumn=`Sym,
timeColumn=`TradeTime`Time, useSystemTime=false, delayedTime=1000)
// 订阅左右表
subscribeTable(tableName="trades", actionName="appendLeftStream",
handler=getLeftStream(ajEngine), msgAsTable=true, offset=-1, hash=0)
subscribeTable(tableName="snapshot", actionName="appendRightStream",
handler=getRightStream(ajEngine), msgAsTable=true, offset=-1, hash=1)
// 生成并注入数据
t1 = table(`A`A`B`A`B`B`B as Sym, 10:00:02.000+(1.6)*700 as TradeTime, (3.4 3.5 7.7 3.5 7.5 7.6) as TradePrice)
t2 = table(`A`B`A`B as Sym, 10:00:00.000+(3 3 6 6)*1000 as Time, (3.5 7.6 3.5 7.6) as Bid1Price, (3.5 7.6 3.6 7.6) as Ask1Price)
snapshot.append!(t2)
---
sleep(1500)
trades.append!(t1)
---
上例对每条成交记录匹配一条时刻早于自己的报价记录,输出结果与原始成交记录一一对应。关联得到的结果表如图所示,左表中 7 条数据都有对应的输出。本例在创建引擎时指定了 delayedTime 参数,因此对于分组 B,即使右表 snapshot 中没有比 10:00:06.200 更大的时间戳,左表 trades 中最后一条数据 (B,10:00:06.200, 7.6) 仍然能够在注入引擎 2s 后强制输出。
<table><tr><td></td><td>TradeTime</td><td>Sym</td><td>TradePrice</td><td>TradeCost</td><td>SnapshotTime</td></tr><tr><td>0</td><td>10:00:02.700</td><td>A</td><td>3.40</td><td></td><td></td></tr><tr><td>1</td><td>10:00:03.400</td><td>A</td><td>3.50</td><td>0.00</td><td>10:00:03.000</td></tr><tr><td>2</td><td>10:00:04.800</td><td>A</td><td>3.50</td><td>0.00</td><td>10:00:03.000</td></tr><tr><td>3</td><td>10:00:04.100</td><td>B</td><td>7.70</td><td>0.10</td><td>10:00:03.000</td></tr><tr><td>4</td><td>10:00:05.500</td><td>B</td><td>7.50</td><td>0.10</td><td>10:00:03.000</td></tr><tr><td>5</td><td>10:00:06.200</td><td>B</td><td>7.60</td><td>0.00</td><td>10:00:06.000</td></tr></table>
6 rows 5 columns table output
## (2) Window Join 引擎 (createWindow) JoinEngine)
## 关联规则:
Window Join 引擎根据连接列对数据分组,将每条左表记录与右表在指定窗口内的聚合结果相匹配,适用于关联不同的数据频率的数据源。该引擎的连接机制类似于 SQL WINDOW JOIN,左表按时间邻近关联右表指定时间窗口内的数据,窗口范围由左表中记录的时刻和创建引擎时指定的窗口长度(参数 window)共同决定。
## 应用场景:
使用 Window Join 引擎可以使用窗口内的聚合结果替代单条记录参与数据关联,降低单条匹配结果的偶然性,为业务决策提供更有价值的信息。例如估计个股交易成本时,将交易数据表关联报价数据表的窗口聚合值以获取更合理的报价基准。
## 使用案例:Window Join 引擎融合行情快照与逐笔成交数据
本例在行情快照数据的基础上融合前后两个快照之间的逐笔成交数据,左表为快照,右表为成交数据。
---
// 创建连接表与输出表
share streamTable(1:0, `Sym`TradeTime`Side`TradeQty, [SYMBOL, TIME, INT, LONG]) as
trades
share streamTable(1:0, `Sym`Time`Open`High`Low`Close, [SYMBOL, TIME, DOUBLE, DOUBLE,
DOUBLE, DOUBLE]) as snapshot
share streamTable(1:0,
`Time`Sym`Open`High`Low`Close`BuyQty`SellQty`TradeQtyList`TradeTimeList, [TIME,
SYMBOL, DOUBLE, DOUBLE, DOUBLE, DOUBLE, LONG, LONG, LONG[], TIME[]]) as output
// 创建 Window Join 引擎
wjMetrics = <[Open, High, Low, Close, sum(iif(Side==1, TradeQty, 0)),
sum(iif(Side==2, TradeQty, 0)), TradeQty, TradeTime]>
---
3 - 流计算引擎
fillArray = [00:00:00.000, "", 0, 0, 0, 0, 0, 0, [], []]
wjEngine = createWindowJoinEngine(name="windowJoin", leftTable=snapshot, rightTable=trades, outputTable=output, window=0:0, metrics=wjMetrics, matchingColumn=`Sym, timeColumn=`Time`TradeTime, useSystemTime=false, nullFill=fillArray)
## // 订阅数据
subscribeTable(tableName="snapshot", actionName="appendLeftStream",
handler=getLeftStream(wjEngine), msgAsTable=true, offset=-1, hash=0)
subscribeTable(tableName="trades", actionName="appendRightStream",
handler=getRightStream(wjEngine), msgAsTable=true, offset=-1, hash=1)
## // 注入数据
t1 = table(`A`B`A`B`A`B as Sym, 10:00:00.000+(3 3 6 6 9 9)*1000 as Time, (NULL NULL 3.5 7.6 3.5 7.6) as Open, (3.5 7.6 3.6 7.6 3.6 7.6) as High, (3.5 7.6 3.5 7.6 3.4 7.5) as Low, (3.5 7.6 3.5 7.6 3.6 7.5) as Close)
t2 = table(`A`A`B^A^B`B^B^A^B^A^A as Sym, 10:00:02.000+(1.10)*700 as TradeTime, (12 11 1 1 1 2 1 2 2) as Side, (1..10) * 10 as TradeQty)
trades.append!(t2)
snapshot.append!(t1)
输入数据如下:
<table><tr><td></td><td>Sym</td><td>TradeTime</td><td>Side</td><td>TradeQty</td></tr><tr><td>0</td><td>A</td><td>10:00:02.700</td><td>1</td><td>10</td></tr><tr><td>1</td><td>A</td><td>10:00:03.400</td><td>2</td><td>20</td></tr><tr><td>2</td><td>B</td><td>10:00:04.100</td><td>1</td><td>30</td></tr><tr><td>3</td><td>A</td><td>10:00:04.800</td><td>1</td><td>40</td></tr><tr><td>4</td><td>B</td><td>10:00:05.500</td><td>1</td><td>50</td></tr><tr><td>5</td><td>B</td><td>10:00:06.200</td><td>1</td><td>60</td></tr><tr><td>6</td><td>A</td><td>10:00:06.900</td><td>2</td><td>70</td></tr><tr><td>7</td><td>B</td><td>10:00:07.600</td><td>1</td><td>80</td></tr><tr><td>8</td><td>A</td><td>10:00:08.300</td><td>2</td><td>90</td></tr><tr><td>9</td><td>A</td><td>10:00:09.000</td><td>2</td><td>100</td></tr></table>
10 rows 4 columns (240 B) table trades
<table><tr><td></td><td>Sym</td><td>Time</td><td>Open</td><td>High</td><td>Low</td><td>Close</td></tr><tr><td>0</td><td>A</td><td>10:00:03.000</td><td></td><td>3.50</td><td>3.50</td><td>3.50</td></tr><tr><td>1</td><td>B</td><td>10:00:03.000</td><td></td><td>7.60</td><td>7.60</td><td>7.60</td></tr><tr><td>2</td><td>A</td><td>10:00:06.000</td><td>3.50</td><td>3.60</td><td>3.50</td><td>3.50</td></tr><tr><td>3</td><td>B</td><td>10:00:06.000</td><td>7.60</td><td>7.60</td><td>7.60</td><td>7.60</td></tr><tr><td>4</td><td>A</td><td>10:00:09.000</td><td>3.50</td><td>3.60</td><td>3.40</td><td>3.60</td></tr><tr><td>5</td><td>B</td><td>10:00:09.000</td><td>7.60</td><td>7.60</td><td>7.50</td><td>7.50</td></tr></table>
6 rows 6 columns (280 B) table snapshot
如下图展示的输出结果所示,引擎既可以计算窗口聚合值(如交易总量),也可以以数组向量的形式保留窗口内的全部逐笔成交明细(如最后两个字段)。
<table><tr><td></td><td>Time</td><td>Sym</td><td>Open</td><td>High</td><td>Low</td><td>Close</td><td>BuyQty</td><td>SellQty</td><td>TradeQtyList</td><td>TradeTimeList</td></tr><tr><td>0</td><td>10:00:03.000</td><td>A</td><td>0.00</td><td>3.50</td><td>3.50</td><td>3.50</td><td>10</td><td>0</td><td>[10]</td><td>[10:00:02.700]</td></tr><tr><td>1</td><td>10:00:06.000</td><td>A</td><td>3.50</td><td>3.60</td><td>3.50</td><td>3.50</td><td>40</td><td>20</td><td>[20, 40]</td><td>[10:00:03.400, 10:00:04.800]</td></tr><tr><td>2</td><td>10:00:09.000</td><td>A</td><td>3.50</td><td>3.60</td><td>3.40</td><td>3.60</td><td>0</td><td>160</td><td>[70, 90]</td><td>[10:00:06.900, 10:00:08.300]</td></tr><tr><td>3</td><td>10:00:03.000</td><td>B</td><td>0.00</td><td>7.60</td><td>7.60</td><td>7.60</td><td>0</td><td>0</td><td>0</td><td>0</td></tr><tr><td>4</td><td>10:00:06.000</td><td>B</td><td>7.60</td><td>7.60</td><td>7.60</td><td>7.60</td><td>80</td><td>0</td><td>[30, 50]</td><td>[10:00:04.100, 10:00:05.500]</td></tr></table>
5 rows 10 columns table output
对比结果表与左表输入数据,可以看出左表中分组 B 内时间戳为 10:00:09.000 的数据没有输出,这是因为右表中分组 B 内没有等于或大于 10:00:09.000 的数据,无法触发窗口关闭。为演示目的,本例使用了左表时间(指定参数 useSystem=false)确定窗口并触发计算。在实际生产中,推荐使用系统时间,即指定 useSystemTime=true。接入实时数据时,左表一旦到达引擎便立即输出。这时对于任意一条左表记录,右表窗口包含了前一条左表记录到本条记录之间进入引擎的全部右表数据。
## (3) Equi Join 引擎 (createEquiJoinEngine)
## 关联规则:
Equi Join 引擎将具有相同事件时间频率的数据进行等值关联,一般用于关联两表公共列并汇总表信息。引擎的连接机制类似 SQL 中的 EQUI JOIN,按连接列和时间列等值关联数据源,对于表 A 中的每一条记录,当它成功匹配上表 B 中记录时,引擎将输出一条结果。注意,无论进入引擎的数据无论已关联匹配数据,引擎都会根据指定规则定期清理缓存数据。
## 应用场景:
Equi Join 引擎适用于对不同数据源基于指定字段进行等值拼接,例如:
- 关联日线行情数据和日行情指标数据,进一步测试动态交易策略。
·对逐笔数据和行情快照数据进行实时分钟聚合并拼接两张分钟指标表。
## 使用案例:拼接不同数据源的实时分钟指标
本例使用两个独立的时序聚合引擎对快照和成交数据流做实时聚合,每一分钟的降采样指标分别作为左右表注入 Equi Join 引擎进行数据拼接。
// 创建数据表
share streamTable(1:0, `Sym` TradeTime`Side`TradeQty, [SYMBOL, TIME, INT, LONG]) as trades
share streamTable(1:0, `UpdateTime`Sym`BuyTradeQty`SellTradeQty, [TIME, SYMBOL, LONG, LONG]) as tradesMin
share streamTable(1:0, `Sym`Time`Bid1Price`Bid1Qty, [SYMBOL, TIME, DOUBLE, LONG]) as snapshot
share streamTable(1:0, `UpdateTime`Sym`AvgBid1Amt, [TIME, SYMBOL, DOUBLE]) as snapshotMin
share streamTable(1:0, `UpdateTime`Sym`AvgBid1Amt`BuyTradeQty`SellTradeQty, [TIME, SYMBOL, DOUBLE, LONG, LONG]) as output
// 创建 Equi Join 引擎与时序聚合引擎
3 - 流计算引擎
eqJoinEngine = createEquiJoinEngine(name="EquiJoin", leftTable=tradesMin, rightTable=snapshotMin, outputTable=output, metrics=<[AvgBid1Amt, BuyTradeQty, SellTradeQty]>, matchingColumn=`Sym, timeColumn=`UpdateTime)
tsEngine1 = createTimeSeriesEngine(name="tradesAggr", windowSize=60000, step=60000, metrics=<[sum(iif(Side==1, 0, TradeQty)), sum(iif(Side==2, 0, TradeQty))]>, dummyTable=trades, outputTable=getLeftStream(eqJoinEngine), timeColumn=`TradeTime, keyColumn=`Sym, useSystemTime=false, fill=(0, 0))
tsEngine2 = createTimeSeriesEngine(name="snapshotAggr", windowSize=60000, step=60000, metrics=<[avg(iif(Bid1Price!=NULL, Bid1Price*Bid1Qty, 0 )]>, dummyTable=snapshot, outputTable=getRightStream(eqJoinEngine), timeColumn=`Time, keyColumn=`Sym, useSystemTime=false, fill=(0.0))
// 订阅数据
subscribeTable(tableName="trades", actionName="minAggr", handler=tsEngine1, msgAsTable=true, offset=-1, hash=1)
subscribeTable(tableName="snapshot", actionName="minAggr", handler=tsEngine2, msgAsTable=true, offset=-1, hash=2)
// 注入数据
t1 = table(`A`B`A`B`A`B as Sym, 10:00:52.000+(3 3 6 6 9 9)*1000 as Time, (3.5 7.6
3.6 7.6 3.6 7.6) as Bid1Price, (1000 2000 500 1500 400 1800) as Bid1Qty)
t2 = table(`A`A`B`A`B`B`A`B`B`A as Sym, 10:00:54.000+(1.10)*700 as TradeTime, (1 11 1 1 2 1 2 2) as Side, (1..10) * 10 as TradeQty)
trades.append!(t2)
snapshot.append!(t1)
由于 Equi Join 引擎是等值连接,若时序聚合引擎 1 输出了股票 A 时间戳 9:30 的数据,但时序聚合引擎 2 没有输出股票 A 对应时间的数据,则 Equi Join 引擎不会输出股票 A 时间戳 9:30 的汇总数据。关联结果如下:
<table><tr><td></td><td>UpdateTime</td><td>Sym</td><td>AvgBid1Amt</td><td>BuyTradeQty</td><td>SellTradeQty</td></tr><tr><td>0</td><td>10:01:00.000</td><td>A</td><td>2,650.00</td><td>90</td><td>50</td></tr><tr><td>1</td><td>10:01:00.000</td><td>B</td><td>13,300.00</td><td>0</td><td>220</td></tr></table>
2 rows 5 columns table output
(4) Left Semi Join 引擎 (createLeftSemiJoinEngine)
## 关联规则:
Left Semi Join 引擎的连接机制类似 SQL EQUI JOIN,按连接列等值关联左右表,对于左表中的每一条记录,成功匹配上右表中的记录时,引擎将输出一条结果。未成功匹配的左表的记录将一直由引擎缓存,等待与右表中更新的记录匹配。如果右表中存在多条匹配的记录,用户可以通过参数 updateRightTable 来选择匹配右表的最早或最新一条记录。
## 应用场景:
Left Semi Join 引擎常用于数据关联和过滤场景中,它能够帮助用户快速筛选出左表中与右表相关的记录,而无需返回全部左表和右表的信息。例如:
·金融:对逐笔成交数据补充原始委托信息;关联股票和指数行情并计算其相关性。
## 使用案例:对逐笔成交数据补充原始委托信息
本例基于股票代码和订单号关联逐笔成交与逐笔委托数据,对成交数据补充原始委托信息。每条逐笔成交都匹配对应的委托单,输出结果与原始输入中的逐笔成交记录一一对应。在成功匹配委托信息前,该条逐笔成交记录暂时不输出。以下脚本用两个 Left Semi Join 引擎级联的方式,对成交表 trades 中的卖方委托单、买方委托单依次进行了关联。
## // 创建数据表
share streamTable(1:0, `Sym` BuyNo` SellNo` TradePrice `TradeQty` TradeTime, [SYMBOL, LONG, LONG, DOUBLE, LONG, TIME]) as trades
share streamTable(1:0, `Sym`OrderNo`Side`OrderQty`OrderPrice`OrderTime, [SYMBOL, LONG, INT, LONG, DOUBLE, TIME]) as orders
share streamTable(1:0,
`Sym` SellNo` BuyNo` TradePrice` TradeQty` TradeTime` BuyOrderQty` BuyOrderPrice` BuyOrderT ime, [SYMBOL, LONG, LONG, DOUBLE, LONG, TIME, LONG, DOUBLE, TIME]) as outputTemp share streamTable(1:0,
`Sym`BuyNo`SellNo`TradePrice`TradeQty`TradeTime`BuyOrderQty`BuyOrderPrice`BuyOrderT ime` SellorderQty`SellorderPrice`SellorderTime, [SYMBOL, LONG, LONG, DOUBLE, LONG, TIME, LONG, DOUBLE, TIME, LONG, DOUBLE, TIME]) as output
// 创建 Left Semi Join 引擎
ljEngineBuy=createLeftSemiJoinEngine(name="leftJoinBuy", leftTable=outputTemp, rightTable=orders, outputTable=output, metrics=<[SellNo, TradePrice, TradeQty, TradeTime, BuyOrderQty, BuyOrderPrice, BuyOrderTime, OrderQty, OrderPrice, OrderTime]>, matchingColumn=[`Sym`BuyNo, `Sym`OrderNo])
ljEngineSell=createLeftSemiJoinEngine(name="leftJoinSell", leftTable=trades, rightTable=orders, outputTable=getLeftStream(ljEngineBuy), metrics=<[BuyNo, TradePrice, TradeQty, TradeTime, OrderQty, OrderPrice, OrderTime]>, matchingColumn=[`Sym`SellNo, `Sym`OrderNo])
## // 订阅数据
subscribeTable(tableName="trades", actionName="appendLeftStream",
handler=getLeftStream(1jEngineSell), msgAsTable=true, offset=-1)
subscribeTable(tableName="orders", actionName="appendRightStreamForSell", handler=getRightStream(ljEngineSell), msgAsTable=true, offset=-1)
subscribeTable(tableName="orders", actionName="appendRightStreamForBuy", handler=getRightStream(ljEngineBuy), msgAsTable=true, offset=-1)
## // 构造数据写入发布表
t1 = table(`A`B`B`A as Sym, [2, 5, 5, 6] as BuyNo, [4, 1, 3, 4] as SellNo, [7.6, 3.5, 3.5, 7.6]as TradePrice, [10, 100, 20, 50]as TradeQty, 10:00:00.000+(400 500 500 600) as TradeTime)
t2 = table(`B`A`B`A`B`A as Sym, 1..6 as OrderNo, [2, 1, 2, 2, 1, 1] as Side, [100, 10, 20, 100, 350, 50] as OrderQty, [7.6, 3.5, 7.6, 3.5, 7.6, 3.5] as OrderPrice, 10:00:00.000+(1.6)*100 as OrderTime)
3 - 流计算引擎
---
orders.append!(t2)
trades.append!(t1)
---
上例首先将 trades 和 orders 分为作为左、右表注入引擎 leftJoinSell,以 trades 数据中的卖单号关联 orders 中的对应订单。再将上述引擎的输出直接注入连接引擎的左表,该引擎的右表仍然设置为 orders。trades 数据流中的每一条记录将分别和 orders 数据流中的两条记录关联,进而取得 orders 中的委托量、价、时间等字段,关联得到的结果表如下:
<table><tr><td></td><td>Sym</td><td>BuyNo</td><td>SellNo</td><td>TradePrice</td><td>TradeQty</td><td>TradeTime</td><td>BuyOrderQty</td><td>BuyOrderPrice</td><td>BuyOrderTime</td><td>SellOrderQty</td><td>SellOrderPrice</td><td>SellOrderTime</td></tr><tr><td>0</td><td>A</td><td>2</td><td>4</td><td>7.60</td><td>10</td><td>10:00:00.400</td><td>100</td><td>3.50</td><td>10:00:00.400</td><td>10</td><td>3.50</td><td>10:00:00.200</td></tr><tr><td>1</td><td>A</td><td>6</td><td>4</td><td>7.60</td><td>50</td><td>10:00:00.600</td><td>100</td><td>3.50</td><td>10:00:00.400</td><td>50</td><td>3.50</td><td>10:00:00.600</td></tr><tr><td>2</td><td>B</td><td>5</td><td>1</td><td>3.50</td><td>100</td><td>10:00:00.500</td><td>100</td><td>7.60</td><td>10:00:00.100</td><td>350</td><td>7.60</td><td>10:00:00.500</td></tr><tr><td>3</td><td>B</td><td>5</td><td>3</td><td>3.50</td><td>20</td><td>10:00:00.500</td><td>20</td><td>7.60</td><td>10:00:00.300</td><td>350</td><td>7.60</td><td>10:00:00.500</td></tr></table>
4 rows 12 columns table output
## (5) Lookup Join 引擎 (createLookup JoinEngine)
## 关联规则:
Lookup Join 引擎将实时数据源与一张描述数据源固有属性的表(通常是维度表或不频繁更新的内存表)关联,以补全表信息。引擎内部的连接机制类似于 SQL LEFT JOIN,按连接列等值关联左右表。每一条左表记录注入引擎时会立刻关联当前时刻的右表,不论是否在右表中匹配到连接列一致的记录,引擎都会立刻输出一条结果,若未能匹配上则结果中右表相关的字段为空。
与 Left Semi Join 引擎需要等待匹配才输出的机制不同,每当左表接收一条数据,引擎都会立即触发连接操作,无论是否在右表中找到连接列匹配的记录,Lookup Join 引擎都会立刻输出结果。
## 应用场景:
Lookup Join 引擎主要用于实时数据与描述数据源属性的表关联,可以用来补充数据、进行属性映射和增加维度信息。例如:
- 金融:关联实时的交易价格表和保存汇率信息的维度表,以便对交易进行进一步分析。
## 使用案例:关联实时行情数据和历史日频指标
下例关联了实时行情数据(流数据表)与历史日频指标(不频繁更新的内存表)。
---
share streamTable(1:0, `Sym` Time`Open`High`Low`Close, [SYMBOL, TIME, DOUBLE, DOUBLE, DOUBLE,
DOUBLE, DOUBLE]) as snapshot
historicalData = table(`600020`600068 as Sym, [0.8, 0.2] as PreWeight, [3.39, 6.58]
as PreClose)
share table(1:0, `Sym` Time `Open`High` Low Close`PreWeight` PreClose, [SYMBOL, TIME,
DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]) as output
// 创建引擎
lookupJoinEngine = createLookupJoinEngine(name="lookupJoin", leftTable=snapshot,
rightTable=historicalData, outputTable=output, metrics=<[Time, Open, High, Low,
Close, PreWeight, PreClose]>, matchingColumn=`Sym, checkTimes=1s)
// 订阅数据
---
---
subscribeTable(tableName="snapshot", actionName="appendLeftStream",
handler=getLeftStream(lookupJoinEngine), msgAsTable=true, offset=-1)
// 注入数据
insert into snapshot values(`600020, 09:43:50.000, 3.39, 3.4, 3.35, 3.36)
insert into snapshot values(`600068, 09:43:54.000, 6.58, 6.59, 6.52, 6.53)
insert into snapshot values(`600020, 09:44:30.000, 3.39, 3.4, 3.35, 3.37)
insert into snapshot values(`600020, 09:44:32.000, 3.39, 3.4, 3.35, 3.37)
insert into snapshot values(`600068, 09:44:57.000, 6.58, 6.59, 6.52, 6.54)
insert into snapshot values(`600068, 09:45:00.000, 6.58, 6.59, 6.52, 6.54)
select * from output
---
指定 checkTimes 后,引擎定期同步最新的右表数据。左表每到达一条数据,引擎都会检查是否和右表记录匹配,输出表数据记录数与左表记录数一致。
<table><tr><td></td><td>Sym</td><td>Time</td><td>Open</td><td>High</td><td>Low</td><td>Close</td><td>PreWeight</td><td>PreClose</td></tr><tr><td>0</td><td>600020</td><td>09:43:50.000</td><td>3.39</td><td>3.40</td><td>3.35</td><td>3.36</td><td>0.80</td><td>3.39</td></tr><tr><td>1</td><td>600068</td><td>09:43:54.000</td><td>6.58</td><td>6.59</td><td>6.52</td><td>6.53</td><td>0.20</td><td>6.58</td></tr><tr><td>2</td><td>600020</td><td>09:44:30.000</td><td>3.39</td><td>3.40</td><td>3.35</td><td>3.37</td><td>0.80</td><td>3.39</td></tr><tr><td>3</td><td>600020</td><td>09:44:32.000</td><td>3.39</td><td>3.40</td><td>3.35</td><td>3.37</td><td>0.80</td><td>3.39</td></tr><tr><td>4</td><td>600068</td><td>09:44:57.000</td><td>6.58</td><td>6.59</td><td>6.52</td><td>6.54</td><td>0.20</td><td>6.58</td></tr><tr><td>5</td><td>600068</td><td>09:45:00.000</td><td>6.58</td><td>6.59</td><td>6.52</td><td>6.54</td><td>0.20</td><td>6.58</td></tr></table>
6 rows 8 columns (944 B) table output
### 3.3 功能特性
DolphinDB 内置的流计算引擎具有以下特性:
·支持表接口:流计算引擎均实现了数据表接口,流数据表与引擎之间能够灵活串联形成流处理流水线。
·分组计算:引擎支持按指定键值进行分组计算。用户可以为不同分组的数据应用指定的计算规则并分别进行计算。
·状态计算:有状态计算指需要用到历史状态的计算。流计算引擎内部缓存历史状态并实现了部分算子的增量优化,以便高效地进行实时数据处理。为避免缓存状态不断增长,引擎也提供了自动清理无用历史数据的功能。
·检查点机制:开启引擎快照后,系统会为引擎启用检查点(Checkpoint)机制,定期保存引擎快照。若出现异常情况,可及时将引擎恢复到最新的快照,保证数据的完整性与可用性。
3 - 流计算引擎
·高可用:DolphinDB 基于 Raft 协议实现了流计算引擎高可用。用户在 leader 节点创建流计算引擎后, 系统会同步在 follower 节点创建该引擎,引擎快照也会在节点间同步。如果 leader 节点离线,系统会自动切换到新 leader 节点重新订阅流数据表,恢复到最新快照状态继续实时处理。
・并行执行:当数据流量较大时,用户可以配置订阅节点消息处理的线程数,并行从消息队列中读取并处理数据,提高订阅端的消费效率与吞吐量,确保流数据的实时与高效处理。
### 3.4 流式算子
DolphinDB 内置了丰富的批处理函数,在大部分流计算引擎中可以直接调用定义计算指标,称为流式算子。 在流数据处理中,通常需要在一定时间内存储所接收的事件或中间结果,以供后续的某个时间点(例如收到下一个事件或者经过指定时间后)访问并进行后续处理,此类变量值的变化和计算产生的中间结果统称为状态。 部分流计算引擎内部维护了流数据状态,并针对其应用场景对内置函数的计算进行了增量优化,实现了算子的有状态计算:
·时间序列聚合引擎的算子分为增量计算和全量计算两种:增量计算算子不会保留所有的历史数据, 每当数据到达后更新计算结果与引擎类的变量状态;而全量计算算子(例如自定义聚合函数或未经优化的内置聚合函数)会保留窗口内完整的数据,在窗口关闭时触发全量计算。时序引擎对以下聚合计算算子实现了增量计算优化,显著提升了性能:corr, covar, first, last, max, med, min, percentile, quantile, std, var, sum, sum2, sum3, sum4, wavg, wsum, count, firstNot, ifirstNot, lastNot, ilastNot, imax, imin, nunique, prod, sem, mode, searchK.
- 类似时间序列聚合引擎,Window Join 引擎优化了部分基于右表窗口计算的聚合算子,其中包括: sum, sum2, avg, std, var, corr, covar, wavg, wsum, beta, max, min, last, first, med, percentile.
·响应式状态引擎通常需要通过时序相关的内置函数完成状态获取或者实现相关计算。DolphinDB 针对生产业务中的常见状态算子(滑动窗口函数、累积函数、序列相关函数和 topN 相关函数等)进行优化, 实现了增量算法,大幅提升了计算效率。同时,用户也可以自定义包含 @state 标识的状态函数,在函数定义中调用状态算子,对复杂指标实现有状态计算。
### 3.5 流水线处理
DolphinDB 针对不同场景提供了多种流计算引擎,例如用户可以使用响应式状态引擎访问历史状态数据,通过横截面引擎实时计算截面数据等。对于简单的业务场景,只需使用单一引擎即可解决,而对于一些复杂任务,往往需要将计算过程分解成多个阶段,将多个流计算引擎通过级联的方式合并成一个复杂的数据流拓扑, 共同完成计算任务。
图 3-2 流水线处理

上图中流程 1 以中间流数据表串联两个流计算引擎,通过两次订阅串联了两个引擎的计算,而 DolphinDB 只需一次订阅即可实现引擎多级级联(如流程 2、3 所示),所有的计算均在一个线程中顺序完成。引入流水线处理,不仅可以提高计算性能,还可以实现更为复杂的实时计算逻辑。下文分别介绍手动搭建引擎流水线,以及通过解析引擎 streamEngineParser 实现引擎自动级联。
#### 3.5.1 手动搭建流水线
由于流计算引擎实现了数据表接口,向引擎添加数据可以视作向一个流数据表写入数据,因此可以将两个引擎间的中间流数据表省略,将一个引擎的返回结果作为另一个引擎的输入,串联调用引擎搭建引擎流水线。实时数据首先注入流数据表,订阅该表的流计算引擎会随着实时数据的注入自动完成计算。
下例展示了 World Quant Alpha001 因子在 DolphinDB 中的流水线实现。
Alpha001 因子计算逻辑:rank(Ts_ArgMax(SignedPower((returns<0?
stddev(returns,20):close), 2),5))-0.5
// 创建横截面引擎,计算股票的排序
dummy = table(1:0, `sym`time`maxIndex, [SYMBOL, TIMESTAMP, DOUBLE])
resultTable = streamTable(1:0, `time`sym`factor1, [TIMESTAMP, SYMBOL, DOUBLE])
ccsRank = createCrossSectionalEngine(name="alpha1CCS", metrics=<[sym, rank(maxIndex, percent=true) - 0.5]>, dummyTable=dummy, outputTable=resultTable, keyColumn=`sym, triggeringPattern='keyCount', triggeringInterval=3000, timeColumn=`time,
useSystemTime=false)
@state
def wqAlpha1TS(close)\{
ret = ratios(close) - 1
v = iif(ret < 0, mstd(ret, 20), close)
return mimax(signum(v)*v*v, 5)
---
\}
// 创建响应式状态引擎,输出到横截面引擎 ccsRank
input = table(1:0, `sym`time`close, [SYMBOL, TIMESTAMP, DOUBLE])
rse = createReactiveStateEngine(name="alpha1", metrics=<[time, wqAlpha1TS(close)]>,
dummyTable=input, outputTable=ccsRank, keyColumn="sym")
---
#### 3.5.2 streamEngineParser 自动级联
为降低用户开发脚本的复杂度,DolphinDB 针对只涉及一个分组键的指标计算研发了引擎流水线解析器(streamEngineParser)。手动串联引擎需要定义每一层引擎实例并按照特定顺序进行级联,而使用解析器可以自动解析表达式并构建流水线。用户只需将嵌套因子按规则改写,系统将自动解析各层嵌套涉及的计算逻辑,形成流计算引擎流水线,将数据分发给对应的引擎进行计算,高效实现复杂业务逻辑。streamEngineParser 为只涉及横截面、历史状态、时序窗口三种逻辑嵌套的复杂因子提供了统一的计算入口。其中:
- row 系列函数分发给横截面引擎进行计算;
- rolling 函数分发给时序聚合引擎进行计算;
·其余所有计算分发给响应式状态引擎进行计算。
下例通过 streamEngineParser 计算 Alpha001 因子。解析器基于因子表达式自动识别横截面操作和时间序列操作,形成流水线处理。相比之下,通过解析器自动级联的实现更简洁,指标表达式几乎等同于因子的数学公式,用户无需考虑计算涉及的引擎类型与各层引擎的计算逻辑即可完成复杂因子计算。
---
@state
def wqAlpha1TS(close)\{
ret = ratios(close) - 1
v = iif(ret < 0, mstd(ret, 20), close)
return mimax(signum(v)*v*v, 5)
\}
// 构建计算因子
metrics=<[sym, rowRank(wqAlpha1TS(close), percent=true)- 0.5]>
streamEngine=streamEngineParser(name=`alpha1_parser, metrics=metrics,
dummyTable=input, outputTable=resultTable, keyColumn=`sym, timeColumn=`time,
triggeringPattern='keyCount', triggeringInterval=3000)
---
## 第 4 章. 流批一体
### 4.1 历史数据回放
在 DolphinDB 中,用户可以使用 replay 函数将数据库或者内存表中的历史数据严格按照事件发生的时间顺序写入流数据表,模拟实时注入的数据流,实现历史数据回放。用户可以通过回放功能将同一套代码应用于回测与实盘交易,为量化策略开发和实盘运行提供了便利。
图 4-1 历史数据回放

#### 4.1.1 回放形式
根据输入表到输出表的映射 (mapping), DolphinDB 支持 1 对 1, N 对 N, N 对 1 三种回放形式:
## 1 对 1 单表回放
单表回放,即 1 对 1 回放,是最基础的回放模式,即将一个输入表回放至一个相同表结构的目标表中。
下例演示了将数据库 "dfs://trade" 中的 "trade" 表中 2020 年 12 月 31 日的数据以每秒 1 万条的速度注入目标表 tradeStream 中:
---
tradeDS = replayDS(sqlObj=<select * from loadTable("dfs://trade", "trade") where
Date = 2020.12.31>, dateColumn=`Date, timeColumn=`Time)
replay(inputTables=tradeDS, outputTables=tradeStream, dateColumn=`Date,
timeColumn=`Time, replayRate=10000, absoluteRate=true)
---
## N 对 N 多表回放
replay 也支持 N 张表的同时回放,即 N 对 N 回放,将多张输入表以元组的形式传入 replay,并为每一个输入表分别指定输出表,输出表和输入表一一对应且具有相同的表结构。
下例基于原始数据生成数据源 orderDS, tradeDS, snapshotDS,并分别回放至输出表 orderStream, tradeStream, snapshotStream:
---
orderDS = replayDS(sqlObj=<select * from loadTable("dfs://order", "order") where
Date = 2020.12.31>, dateColumn=`Date, timeColumn=`Time)
tradeDS = replayDS(sqlObj=<select * from loadTable("dfs://trade", "trade") where
Date = 2020.12.31>, dateColumn=`Date, timeColumn=`Time)
snapshotDS = replayDS(sqlObj=<select * from loadTable("dfs://snapshot", "snapshot")
where Date = 2020.12.31>, dateColumn=`Date, timeColumn=`Time)
replay(inputTables=[orderDS, tradeDS, snapshotDS], outputTables=[orderStream,
tradeStream, snapshotStream], dateColumn=`Date, timeColumn=`Time, replayRate=10000,
absoluteRate=true)
---
注意,这种 N 对 N 的回放模式并不能严格保证回放数据的时序关系。一方面,多个输入表同一秒内的数据可能无法按照时间字段先后回放;另一方面,如果由多个消息处理线程分别对 N 个回放输出表进行订阅和消费, 表与表之间的数据的处理顺序关系也很难保证。
## N 对 1 多表回放
为了严格保证数据可以按照时间顺序回放,DolphinDB 引入了 N 对 1 多表回放模式,将多张数据表同时注入一张二进制异构流数据表。异构流数据表和普通流数据表一样可以被订阅消费,即多种结构的数据回放至同一张表中发布,且由同一个线程实时处理,因此保证了数据消费的时序性。
例如,将数据源 orderDS, tradeDS, snapshotDS 统一回放至输出表 messageStream:
---
orderDS = replayDS(sqlObj=<select * from loadTable("dfs://order", "order") where
Date = 2020.12.31>, dateColumn=`Date, timeColumn=`Time)
tradeDS = replayDS(sqlObj=<select * from loadTable("dfs://trade", "trade") where
Date = 2020.12.31>, dateColumn=`Date, timeColumn=`Time)
snapshotDS = replayDS(sqlObj=<select * from loadTable("dfs://snapshot", "snapshot")
where Date = 2020.12.31>, dateColumn=`Date, timeColumn=`Time)
inputDict = dict(["order", "trade", "snapshot"], [orderDS, tradeDS, snapshotDS])
replay(inputTables=inputDict, outputTables=messageStream, dateColumn=`Date,
timeColumn=`Time, replayRate=10000, absoluteRate=true)
---
若要对异构流数据表进行数据处理(如指标计算等)操作,需要将二进制格式的消息内容反序列化为原始结构的数据。DolphinDB 支持流数据分发引擎 streamFilter 反序列化异构流数据表并过滤分发数据;同时,各 API 在流数据订阅功能的基础上,也支持了订阅时指定 StreamDeserializer 对异构流数据表进行反序列化操作。
#### 4.1.2 回放速率
根据参数 replayRate 的不同设定,历史数据可以按照以下速率回放:
- 指定每秒回放记录数:回放的速率基于记录数计算,系统按照每秒 replayRate 条记录进行回放。
- 指定时间跨度回放加速倍数:根据输入表数据的时间跨度加速 replayRate 倍回放,此时每秒回放的记录数是相同的。
- 精确速度回放:根据输入表数据到来的时间截以尽可能精确的速度加速 replayRate 倍回放。
- 全速回放:系统以最快的速率进行回放。
#### 4.1.3 异构回放应用案例
在实际数据分析应用中,通常需要多种不同类型的消息协作。以量化策略研发为例,在生产环境中实时数据的处理通常是由事件驱动的。而为了更好地在研发环境模拟实际交易中的实时数据流,可能需要将逐笔委托、逐笔成交、快照等行情数据同时回放进行关联分析。异构多表回放是准确模拟实盘环境的关键手段,它保证了不同类型数据的绝对时序,从而使策略开发测试中的行为完全复现实盘交易中的处理逻辑。
下例结合股票行情回放展示异构多表回放功能在实际场景中的应用。脚本将逐笔成交数据与快照数据回放至一个异构流数据表,并通过 streamFilter 反序列化、筛选并分发数据,使用 Asof Join 引擎实时关联并计算个股交易成本。
---
// 创建异构流数据表 messageStream
colName = `timestamp`source`msg
colType = [TIMESTAMP, SYMBOL, BLOB]
messageTemp = streamTable(1:0, colName, colType)
enableTableShareAndPersistence(table=messageTemp, tableName="messageStream",
asynWrite=true, compress=true, cacheSize=1000000, retentionMinutes=1440,
flushMode=0, preCache=10000)
messageTemp = NULL
// 创建计算结果输出表 prevailingQuotes
colName =
`TradeTime` SecurityID` Price `TradeQty` BidPX1` OfferPX1` TradeCost` Snapshot Time
colType = [TIME, SYMBOL, DOUBLE, INT, DOUBLE, DOUBLE, DOUBLE, TIME]
prevailingQuotesTemp = streamTable(1:0, colName, colType)
enableTableShareAndPersistence(table=prevailingQuotesTemp,
tableName="prevailingQuotes", asynWrite=true, compress=true, cacheSize=1000000,
retentionMinutes=1440, flushMode=0, preCache=10000)
prevailingQuotesTemp = NULL
## // 创建连接引擎
def createSchemaTable(dbName, tableName)\{
schema = loadTable(dbName, tableName).schema().colDefs
return table(1:0, schema.name, schema.typeString)
\}
tradeSchema = createSchemaTable("dfs://trade", "trade")
snapshotSchema = createSchemaTable("dfs://snapshot", "snapshot")
joinEngine=createAsofJoinEngine(name="tradeJoinSnapshot", leftTable=tradeSchema,
rightTable=snapshotSchema, outputTable=prevailingQuotes, metrics=<[Price,
TradeQty, BidPX1, OfferPX1, abs(Price-(BidPX1+OfferPX1)/2), snapshotSchema.Time]>,
matchingColumn=`SecurityID, timeColumn=`Time, useSystemTime=false, delayedTime=1)
// 创建流计算过滤与分发引擎
def filterAndParseStreamFunc(tradeSchema, snapshotSchema)\{
filter1 = dict(STRING, ANY)
filter1["condition"] = "trade"
filter1["handler"] = getLeftStream(getStreamEngine(`tradeJoinSnapshot))
---
4 - 流批一体
---
filter2 = dict(STRING, ANY)
filter2["condition"] = "snapshot"
filter2["handler"] = getRightStream(getStreamEngine(`tradeJoinSnapshot))
schema = dict(["trade", "snapshot"], [tradeSchema, snapshotSchema])
engine = streamFilter(name="streamFilter", dummyTable=messageStream,
filter=[filter1, filter2], msgSchema=schema)
subscribeTable(tableName="messageStream", actionName="tradeJoinSnapshot",
offset=-1, handler=engine, msgAsTable=true, reconnect=true)
\}
filterAndParseStreamFunc(tradeSchema, snapshotSchema)
// 回放历史数据
def replayStockMarketData()\{
timeRS = cutPoints(09:15:00.000..15:00:00.000, 100)
tradeDS = replayDS(sqlobj=<select * from loadTable("dfs://trade",
"trade") where Date = 2020.12.31>, dateColumn=`Date, timeColumn=`Time,
timeRepartitionSchema=timeRS)
snapshotDS = replayDS(sqlObj=<select * from loadTable("dfs://snapshot",
"snapshot") where Date =2020.12.31>, dateColumn=`Date, timeColumn=`Time,
timeRepartitionSchema=timeRS)
inputDict = dict(["trade", "snapshot"], [tradeDS, snapshotDS])
submitJob("replay", "replay for factor calculation", replay, inputDict,
messageStream, `Date, `Time, 100000, true, 2)
\}
replayStockMarketData()
---
上述脚本读取数据库中的结构不同的数据表进行全速的异构回放,回放通过 submit Job 函数提交后台作业来执行。对于回放产生的流数据表 messageStream,首先通过函数 streamFilter 反序列化,并根据过滤条件处理订阅数据。数据经过筛选处理后,符合条件的 trade 数据被注入到 Asof Join 引擎的左表,snapshot 数据注入到引擎右表,实现数据关联。完整应用脚本与示例数据可参考教程股票行情回放。
### 4.2 流批一体实现方案
流批一体是指将研发环境中基于历史数据建模分析研发的因子表达式直接应用于生产环境的实时数据中,并保证流计算的结果和批量计算完全一致,二者使用同一套代码,称为 “流批一体”。DolphinDB 将历史数据和实时数据分析整合,在研发环境中开发的核心因子表达式可以直接应用于生产环境的实时数据中。实时行情订阅、行情数据收录、交易实时计算、盘后研究建模,全都用同一套代码完成,保证在历史回放和生产交易当中数据完全一致。相比传统的 Python 与 C++ 两套代码的方案,开发上线周期可缩短 90% 以上。在生产环境中,DolphinDB 提供了实时流计算框架。在流计算框架下,用户在投研阶段封装好的基于批量数据开发的因子函数,可以无缝投入交易和投资方面的生产程序中。同时,流计算框架在算法路径上进行了精细的优化,兼顾了高效开发和计算性能的优势。用户无需维护两套代码,节约了开发成本,还规避了两套体系可能带来的批计算与流计算结果不一致的问题。
图 4-2 流批一体实现方案

流批一体在 DolphinDB 中有两种实现方法:
## (1)使用一套核心函数定义或表达式,代入不同的计算引擎实现历史数据或流数据的计算。
流计算引擎可以直接重用批处理(研发阶段)中基于历史数据编写的表达式或函数,避免在生产环境重写代码,降低了维护研发和生产两套代码的负担。DolphinDB 脚本语言的表达式实际上是对因子语义的描述,因子计算的具体实现则交由相应的计算引擎完成。DolphinDB 确保流式计算的结果与批量计算完全一致,因此代码只要在历史数据的批量计算中验证正确,即可保证流数据的实时计算正确,极大降低了实时计算的调试成本。实际应用中,投研批处理阶段定义的因子表达式无需修改,在生产阶段只需创建流式计算引擎指定该指标即可实现增量流计算。
例如,计算每天主买成交量占全部成交量的比例,可以自定义函数 buyTradeRatio:
---
@state
def buyTradeRatio(buyNo, sellNo, tradeQty)\{
return cumsum(iif(buyNo>sellNo, tradeQty, 0))\\cumsum(tradeQty)
\}
---
在批处理模式下,可以使用 SQL 查询,发挥库内并行计算的优势,使用 csort 语句对组内数据按照时间顺序排序:
---
factor = select TradeTime, SecurityID, `buyTradeRatio as
factorname, buyTradeRatio(BuyNo, SellNo, TradeQty) as val from
loadTable("dfs://tick_SH_L2_TSDB","tick_SH_L2_TSDB") where
date(TradeTime)<2020.01.31 and time(TradeTime)>=09:30:00.000 context by SecurityID,
date(TradeTime) csort TradeTime
---
在流处理模式下,可以通过响应式状态引擎指定该因子实现增量计算。在批计算中定义的因子函数
buyTradeRatio,只需增加 @state 标识声明其为状态函数即可在流式计算中复用。通过以下代码创建响应式状态引擎 demo,以 SecurityID 作为分组键,输入的消息格式同内存表 tickStream。
---
tickStream = table(1:0,
`SecurityID` TradeTime` TradePrice `TradeQty` TradeAmount` BuyNo` SellNo,
[SYMBOL, DATETIME, DOUBLE, INT, DOUBLE, LONG, LONG])
result = table(1:0, `SecurityID`TradeTime`Factor, [SYMBOL, DATETIME, DOUBLE])
factors = <[TradeTime, buyTradeRatio(BuyNo, SellNo, TradeQty)]>
---
4 - 流批一体
demoEngine = createReactiveStateEngine(name="demo", metrics=factors, dummyTable=tickStream, outputTable=result, keyColumn="SecurityID")
## (2)回放历史数据模拟实时数据流入,使用流数据计算引擎完成计算。
为确保研发和生产环境使用同一套代码,可以研发阶段需将历史数据严格按照事件发生的时间顺序进行回放, 以此模拟交易环境。使用这种方法计算历史数据的因子值,效率会略逊与基于 SQL 的批量计算。
下例通过用户自定义函数 sum_diff 与内置函数 ema (exponential moving average) 计算高频因子 factor1:
---
def sum_diff(x, y)\{
return (x-y)/(x+y)
\}
factor1 = <ema(1000 * sum_diff(ema(price, 20), ema(price, 40)),10) - ema(1000 *
sum_diff(ema(price, 20), ema(price, 40)), 20)>
// 定义响应式状态引擎实现因子流式计算
share streamTable(1:0, `sym`date`time`price, [STRING, DATE, TIME, DOUBLE]) as
tickStream
result = table(1:0, `sym` factor1, [STRING, DOUBLE])
rse = createReactiveStateEngine(name="reactiveDemo", metrics = factor1,
dummyTable=tickStream, outputTable=result, keyColumn="sym")
subscribeTable(tableName=`tickStream, actionName="factors",
handler=tableInsert\{rse\})
---
回放历史数据模拟实时数据注入引擎触发计算:
---
// 从 trades 表中加载一天的数据,回放到流数据表 tickStream 中
inputDS = replayDS(<select sym, date, time, price from loadTable("dfs://TAQ",
"trades") where date=2021.03.08>, `date, `time, 08:00:00.000 + (1.10) * 3600000)
replay(inputDS, tickStream, `date, `time, 1000, true, 2)
---
## 第 5 章. 流数据运维
### 5.1 权限管理
DolphinDB 为流数据表与引擎引入了灵活且安全的权限管理方案,允许管理员和创建表或引擎的用户对应用权限控制。只有经过授权的用户能够访问特定的流数据,从而维护数据的安全性和完整性。更多有关权限管理的详细内容,请参考权限管理教程。
DolphinDB 提供了 TABLE_READ 和 TABLE_WRITE 权限类型,用于控制流数据表与引擎的读取和写入权限。
---
//创建用户user1, user2
login(`admin, `123456)
createUser(`user1, "pwd111");
createUser(`user2, "pwd222");
//登录用户user1并创建流数据表和引擎
login(`user1, "pwd111")
share streamTable(1:0, `time`sym`volume, [TIMESTAMP, SYMBOL, INT]) as trades
share streamTable(1:0, `time`sym`sumVolume, [TIMESTAMP, SYMBOL, INT]) as output1
engine1 = createTimeSeriesEngine(name="engine1", windowSize=600, step=600,
metrics=<[sum(volume)]>, dummyTable=trades, outputTable=output1, timeColumn=`time,
useSystemTime=false, keyColumn=`sym, garbageSize=50, useWindowStartTime=false)
---
## (1)访问控制
管理员或创建表或引擎的用户可以执行 addAccessControl,对共享流数据表或引擎对象增加访问控制,限制其他用户访问。在创建引擎后若没有执行 addAccessControl,则任何用户对该引擎有访问权限,能够进行写入和注销。
下例中 user1 用户调用 addAccessControl 对表和引擎增加了访问控制:
---
addAccessControl(`trades)
addAccessControl(`output1)
addAccessControl(engine1)
---
用户 user2 读取表 trades 中数据或注入数据到引擎均失败:
---
login(`user2, "pwd222")
select sum(volume) from trades // ERROR: No access to shared table [trades]
insert into engine1 values(2018.10.08T01:01:01.785, A,10) // ERROR: No access to
table [engine1]
---
## (2)权限设置
管理员或创建表或引擎的用户可以通过 grant、revoke 和 deny 命令管理流数据表和流计算引擎的读写权限。
5 - 流数据运维
登录管理员 admin,并赋予用户 user2 引擎的写入权限:
---
login(`admin, `123456)
grant("user2", TABLE_WRITE, "engine1")
---
用户 user2 成功向引擎注入数据:
---
login(`user2, "pwd222")
insert into engine1 values(2018.10.08T01:01:01.785+1.600, take(`A,600),1..600)
---
## (3)流数据订阅
用户订阅流数据时,要求该用户具有发布表的 TABLE_READ 权限。
・若订阅流数据写入流数据表,用户应具有目标表的 TABLE_READ 和 TABLE_WRITE 权限。
例如,用户 user2 订阅表 trades 到 output1,必须具有 trades 表的 TABLE_READ 权限和 output1 表的 TABLE_READ 和 TABLE_WRITE 权限:
---
login(`admin, `123456)
grant("user2", TABLE_READ, "trades")
grant("user2", TABLE_WRITE, "output1")
grant("user2", TABLE_READ, "output1")
login(`user2, "pwd222")
subscribeTable(tableName="trades", actionName="engine1", offset=0,
handler=append!\{output1\}, msgAsTable=true);
---
## ・若订阅流数据写入分布式表,用户应具有目标表的 TABLE_WRITE 权限。
例如,管理员创建分布式数据库 "dfs://valuedb/pt":
---
login(`admin, `123456)
dbName = "dfs://valuedb"
t = table(10000:0, `time`sym`sumVolume, [TIMESTAMP, SYMBOL, INT])
insert into t values(2018.10.08T01:01:01.785+1..600, take(`A,600),1..600)
db=database(dbName, VALUE, 1..10)
pt=db.createPartitionedTable(t, "pt", "sumVolume").append!(t)
---
赋予用户 user2 订阅分布式表的 TABLE_WRITE 权限:
---
grant("user2", TABLE_WRITE,"dfs://valuedb/pt")
---
用户 user2 成功提交订阅:
---
login(`user2, "pwd222")
def saveTradesToDFS(mutable dfsTrades, msg): dfsTrades.append!(msg)
subscribeTable(tableName="trades", actionName="agg1", offset=0,
handler=saveTradesToDFS\{pt\}, msgAsTable=true);
---
### 5.2 流数据监控
#### 5.2.1 状态监控
在 DolphinDB 中提交订阅后,流数据注入实时处理时所有的计算都在后台进行。订阅端可以实时查询发布订阅的状态信息,了解当前订阅的数据流状态,例如数据是否正常传输、订阅是否生效等。用户可以执行 getStreamingStat 函数查询流数据发布、订阅、消费、持久化等每个阶段的状态,全方位监控流数据处理过程。函数返回一个字典,包含以下表格:
- subWorkers:订阅节点的工作线程的状态。
- subConns: 本地订阅节点和发布节点之间的连接状态。
•pubConns:本地发布节点和所有订阅节点之间的连接状态。
- pubTables:流数据表状态。
- persistWorkers:负责持久化流数据表的工作线程的状态。
用户也可以执行 getStreamEngineStat 查看系统中定义的流计算引擎、各个引擎的内存占用等状态。函数返回一个字典,其键为各个引擎类型的名称,值为对应引擎的状态。例如,键 ReactiveStreamEngine 对应的返回表包含了系统中各个响应式状态引擎的状态:
ReactiveStreamEngine->
<table><tr><td>name</td><td>user</td><td>status</td><td>lastErrMsg</td><td>numGroups</td><td>numRows</td><td>numMetrics ... <br> ---</td></tr><tr><td>RSE</td><td>guest</td><td>OK</td><td></td><td>0</td><td>0</td><td>3 ...</td></tr><tr><td>reactiveDemo</td><td>admin</td><td>OK</td><td></td><td>1</td><td>7</td><td>2 ...</td></tr><tr><td>test001</td><td>userA</td><td>OK</td><td></td><td>3</td><td>20</td><td>4 ...</td></tr></table>
自 2.00.11 版本起,DolphinDB 的 Web 管理器新增了独立的流计算监控模块。用户可以点击功能面板里的流计算监控访问该模块,查看并管理流数据发布订阅、流计算引擎与流数据表状态,在面板中统一监控流计算资源使用情况与异常信息。
图 5-1 Web 流计算监控模块

5 - 流数据运维
#### 5.2.2 可视化
DolphinDB 2.00.11 版本在 Web 管理器中内置了 Dashboard 数据面板模块。用户可以搭建多种类型图表的组合面板,订阅多个数据源并将实时数据集中展示在数据面板中,并指定数据更新的频率。数据面板模块访问方便、使用灵活,支持个性化的面板布局与配色方案,能够灵活适配用户的使用习惯,辅助用户高效挖掘数据价值,获得关键业务洞察。下图通过数据面板集中展示了选定标的的实时订单簿行情数据,其中左下角全市场买卖压力指标柱状图展示了全市场的买卖压力相对强度指数,用于观测市场上买方和卖方的力量对比,帮助交易者评估市场的动态,进而制定和调整交易策略。
图 5-2 数据面板展示多种数据指标

除数据面板外,DolphinDB 开发了 Grafana 数据源插件,用户可以在 Grafana 面板中编写查询脚本,基于 WebSocket 与 DolphinDB 进行交互,实现 DolphinDB 数据的可视化,监控 DolphinDB 集群的节点状态、 流数据表状态以及订阅状态。下图展示了通过 Grafana 监控 DolphinDB 数据表中的数据情况,监控每分钟的主买小单资金、主卖小单资金、主买大单资金和主卖大单资金流入情况。
图 5-3 DolphinDB 连接 Grafana 展示流数据

DolphinDB 与 Altair Panopticon 共同搭建了高性能时序数据分析平台,用户能够访问和分析实时流数据、日内累计数据和历史数据,并对接收到的数据实时地进行可视化展示。下图使用 DolphinDB 时序聚合引擎搭配 Panopticon 可视化应用搭建价格分析仪表盘,将 OHLC、移动平均指数、交易量等信息组合在一张图中,快速查看市场整体趋势与关键指标。DolphinDB 和 Panopticon 的流计算引擎支持实时流数据分析或历史数据回放,用户可以选择实时监控或回放任意频率、任意时间段的交易活动。
图 5-4 使用 Altair Panopticon 分析订单簿

### 5.3 流数据高可用
为满足流数据服务不中断的需求,DolphinDB 提供了流数据的高可用功能,保证稳定的数据传输。DolphinDB 中流数据高可用主要通过两种方案实现:基于 Raft 协议的高可用流数据表和单机双路写入。
#### 5.3.1 高可用集群部署
在 DolphinDB 中,用户可以基于 Raft 协议的高可用多副本架构在多个数据或计算节点上部署 Raft 组,数据分布在 Raft 组的各个节点中。在组内任一节点执行函数 haStreamTable 并指定参数 raftGroup 创建高可用流数据表,该表自动在 Raft 组内的节点进行数据同步。
客户端只需订阅 Raft 组中任一节点上的高可用流数据表,并启用订阅的自动重连功能,即可实现高可用。Raft leader 上的高可用流数据表在接收到数据后会自动向订阅端发布。如果 leader 离线,系统会选举出新的 leader 继续发布数据,客户端会自动重新订阅新 leader 上的高可用流数据表。
此外,DolphinDB 也支持了流计算引擎的高可用。若引擎开启高可用(创建时指定参数 raftGroup), 在 leader 节点创建流计算引擎后,系统会同步在 follower 节点同步创建,引擎保存的快照也会同步到 follower。当 leader 节点离线时,会自动切换新的 leader 节点重新订阅流数据表,自动恢复到最新快照的状态,继续处理数据。
图 5-5 高可用流数据表

#### 5.3.2 单机部署
DolphinDB 还提供了基于单机双路计算的高可用解决方案。用户只需在 2 台独立的服务器上各部署一个单机节点,并接入相同的实时行情源、提交相同的实时计算任务,即可实现流数据的双路写入。流数据的实时计算结果可以通过主备模式写入,或写入 DolphinDB 的键值流数据表去重后推送到外部消息中间件或消息总线。

在实际生产环境下,单机部署双路计算的方案能够更好的利用机器资源,只需指定一台高性能机器作为主可用服务器;而由于 Raft 组中 leader 由随机选举产生,必须保证三台性能均衡机器,机器资源要求更高。使用高可用流数据表可能会带来存储空间的浪费和维护副本一致性的耗时开销,相比之下采用双副本的单机模式降低了运维成本,提高了写入性能。
## 第 6 章. 流计算 API 及插件
### 6.1 流计算 API
DolphinDB 支持多种语言的 API,包括 C++, C#, Java, Python, Go, NodeJS, JavaScript 等。外部程序可以通过 DolphinDB API 与 DolphinDB 服务端交互,向 DolphinDB 中的流数据表写入数据并进行流数据处理。同时,DolphinDB API 提供了单线程回调、多线程回调与主线程阻塞式轮询三种流订阅方式,构造订阅对象后, 用户可以 subscribe 接口订阅 DolphinDB 中的流数据表。具体参见 DolphinDB API 白皮书。
常用 DolphinDB API 支持写入或订阅高可用流数据表。在数据写入时指定高可用参数,连接到 server 端 Raft 组中。当 leader 发生异常时,客户端可以重新连接新 leader 并继续写入数据;客户端向 server 的高可用流数据表订阅数据时,也可通过开启自动重订阅实现高可用。leader 上的高可用流数据表会向订阅端发布数据。如果 Raft 组中的 leader 离线,系统会选举出新的 leader 继续发布数据,客户端会自动切换订阅到新 leader 上的高可用流数据表。
下例展示了如何通过 Python API 向 DolphinDB 订阅流数据:
---
import dolphindb as ddb
import numpy as np
import time
s = ddb.Session()
s.connect("192.168.1.113", 8848, "admin", "123456")
s.run("""
share streamTable(1:0, time `sym` price `id, [TIMESTAMP, SYMBOL, DOUBLE, INT]) as trades
""")
#开启流订阅,对于2.0版本的DolphinDB,若版本小于2.00.9,需指定端口
s.enableStreaming()
## #指定订阅数据的处理方法
def handler(lst):
print(lst)
## #订阅流数据
s.subscribe("192.168.1.113", 8848, handler, "trades", "SingleMode", offset=-1)
## #插入模拟数据
s.run("insert into trades values(take(now()), 6),
take(`000005` 600001` 300201` 000908` 600002, 6), rand(1000, 6)/10.0, 1..6)")
time.sleep(3)
## #取消订阅
s.unsubscribe("192.168.1.113", 8848, "trades", "SingleMode")
---
订阅数据输出结果如下:
[numpy.datetime64('2023-03-17T12:06:30.439'), '000905', 36.7, 1]
[numpy.datetime64('2023-03-17T12:06:30.439'), '600001', 80.7, 2]
[numpy.datetime64('2023-03-17T12:06:30.439'), '300201', 68.7, 3]
[numpy.datetime64('2023-03-17T12:06:30.439'), '000908', 52.2, 4]
[numpy.datetime64('2023-03-17T12:06:30.439'), '600002', 45.1, 5]
[numpy.datetime64('2023-03-17T12:06:30.439'), '000905', 55.1, 6]
### 6.2 流计算插件
DolphinDB 支持通过动态加载外部插件来扩展功能,进行实时数据接入与输出。目前 DolphinDB 已经开发提供了丰富的插件,包括历史数据导入,实时数据接入,消息队列对接等。例如,针对金融场景实时数据接入, 目前已经开发并开源了多个插件,用于对接恒生 NSQ、华泰 Insight、华锐 AMD 等行情数据源。用户可以加载这些插件并编写简单的脚本,轻松实现各种实时数据接入需求。此外,DolphinDB 还支持自定义插件的开发,私有的接口及模型能够以插件的形式在 DolphinDB 中运行。
与流计算 API 相比,插件的数据接入方式更加高效,因为插件和 DolphinDB server 在同一进程中运行,数据源直接发送到 server 进程中回调解析;同时,使用已有插件扩展功能时,只需学习 DolphinDB 脚本语言即可实现数据接入逻辑,减少了用户的学习成本。通过插件的方式与 DolphinDB 交互,不但可以做到和 C++ 相同的处理速度,而且使用 DolphinDB 的脚本语言进行业务开发,可以节省 90% 的开发工作量,显著提升开发效率,降低开发成本,极大缩减开发到生产的周期。但需要注意的是,插件不支持高可用。当插件所在节点发生故障时,写入操作可能会失败。与之不同,API 支持高可用,因为应用程序可以迁移到其他可用的节点继续写入数据。
DolphinDB 流数据相关插件列表:
<table><tr><td>插件</td><td>类别</td><td>简介</td></tr><tr><td>amdQuote</td><td>市场行情</td><td>连接 AMD 行情服务器获取行情信息。</td></tr><tr><td>ctp</td><td>市场行情</td><td>对接综合交易平台(Comprehensive Transaction Platform)系统,支持订阅期货市场数据。</td></tr><tr><td>insight</td><td>市场行情</td><td>接华泰 INSIGHT 行情服务软件,获取交易所的行情。</td></tr><tr><td>nsq</td><td>市场行情</td><td>对接恒生 NSQ 极速行情服务软件,获取沪深市场的行情。</td></tr><tr><td>ricequant</td><td>市场行情</td><td>对接米筐(RiceQuant)数据</td></tr><tr><td>kafka</td><td>消息队列</td><td>用于发布或订阅 Kafka 流服务。</td></tr><tr><td>mqtt</td><td>消息队列</td><td>用于向 MQTT 服务器发布或订阅消息。</td></tr><tr><td>zmq</td><td>消息队列</td><td>用于 zmq 消息队列库的请求应答、发布、订阅和管道消息传输。</td></tr><tr><td>MatchingEngine Simulator</td><td>流计算应用</td><td>模拟撮合插件。</td></tr><tr><td>backtest</td><td>流计算应用</td><td>策略回测插件。</td></tr></table>
## 第 7 章. 场景应用
### 7.1 金融
#### 7.1.1 高频因子计算
因子计算是指根据一些预定义的规则或公式,从原始数据中提取出能够反映市场或个股特征的数值。因子可以用于描述市场的风险、收益、价值、动量、质量等方面,也可以用于筛选股票、构建投资组合、评估绩效等目的。DolphinDB 作为分布式计算、实时流计算与分布式存储一体化的高性能时序数据库,适合因子的存储、 计算、建模、回测和实盘交易。
下例基于逐笔成交数据计算过去 $\mathrm{n}$ 分钟主动成交占比。
## 因子计算逻辑:
主动成交占比即主动成交量占总成交量的比例, 其计算公式如下:
\text{ actVolumes}_{t} = \mathop{\sum }\limits_{{i = t - \text{ window }}}^{t}{\text{ tradeQty }}_{i} * {I}_{\text{ buy No } > \text{ sellNo }}$
\text{ totalVolume}_{t} = \mathop{\sum }\limits_{{i = t - \text{ window }}}^{t}{\text{ tradeQty }}_{i}$
\text{ actVolumePercent}_{t} = \frac{{\text{ actVolume }}_{t}}{{\text{ totalVolume }}_{t}}$
其中 actVolume ${}_{\mathrm{t}}$ 表示 t-window 时刻到 t 时刻区间内的主动成交量; totalVolume ${}_{\mathrm{t}}$ 表示 t-window 时刻到 t 时刻区间的总成交量;指示函数 I 含义如下:
$$
{I}_{\text{ buyNo>sellNo }} = \left\{ \begin{matrix} 1,\text{ buyN }{o}_{t} > {\text{ sellNo }}_{t} \\ 0,\text{ others } \end{matrix}\right.
$$
## 实现脚本:
---
// 自定义状态函数 actVolumePercent
@state
def actVolumePercent(tradeTime, tradeQty, buyNo, sellNo, window)\{
return tmsum(tradeTime, iif(buyNo > sellNo, tradeQty, 0), window) \\
tmsum(tradeTime, tradeQty, window)
\}
// 定义输入输出表结构
inputTable = table(1:0,
`securityID`tradeTime`tradePrice`tradeQty`tradeAmount`buyNo`sellNo`tradeBSFlag`trad
eIndex channelNo, [SYMBOL, DATETIME, DOUBLE, INT, DOUBLE, LONG, LONG, SYMBOL, INT, INT])
resultTable = table(10000:0, ["securityID", "tradeTime", "factor"], [SYMBOL,
TIMESTAMP, DOUBLE])
// 创建响应式状态引擎
try\{dropStreamEngine("reactiveDemo")) catch(ex)\{ print(ex) \}
metrics = <[tradeTime, actVolumePercent(tradeTime, tradeQty, buyNo, sellNo, 5m)]>
rse = createReactiveStateEngine(name="reactiveDemo", metrics = metrics,
dummyTable=inputTable, outputTable=resultTable, keyColumn="securityID")
---
以上代码首先通过 @state 标识声明了自定义状态函数 actVolumePercent。由于该因子需要计算过去 n 分钟内的主动成交量与交易总量,在函数定义中使用了内置时间滑动窗口函数 tmsum 指定窗口滑动规则并计算窗口内总和。滑动窗口函数在系统内部进行了增量优化,其计算效率也获得了大幅提升。
然后执行 createReactiveStateEngine 创建响应式状态引擎 reactiveDemo,指定分组键 securityID, 即在引擎中按照股票代码分组。输入引擎的数据结构与 inputTable 一致。数据注入引擎后触发计算指标的计算,参数 metrics 通过元代码指定了直接输出列 tradeTime,并使用已定义的 actVolumePercent 状态函数计算前 5 分钟内的主动成交占比。
## 数据写入:
模拟数据写入引擎,并观察计算结果。
---
// 输入数据
insert into rse values(`000155, 2020.01.01T09:30:00, 30.85, 100, 3085, 4951, 0, `B,
1, 1)
insert into rse values(`000155, 2020.01.01T09:31:00, 30.86, 100, 3086, 4952, 1, `B,
2, 1)
insert into rse values(`000155, 2020.01.01T09:32:00, 30.85, 200, 6170, 5001, 5100,
S, 3, 1)
insert into rse values(`000155, 2020.01.01T09:33:00, 30.83, 100, 3083, 5202, 5204,
S, 4, 1)
insert into rse values(`000155, 2020.01.01T09:34:00, 30.82, 300, 9246, 5506, 5300,
B, 5, 1)
insert into rse values(`000155, 2020.01.01T09:35:00, 30.82, 500, 15410, 5510, 5600,
S, 6, 1)
insert into rse values(`000155, 2020.01.01T09:36:00, 30.87, 800, 24696, 5700, 5600,
B, 7, 1)
// 查看结果
select * from resultTable
---
7 - 场景应用
<table><tr><td></td><td>securityID</td><td>tradeTime</td><td>factor</td></tr><tr><td>0</td><td>000155</td><td>2020.01.01 09:30:00.000</td><td>1.0000</td></tr><tr><td>1</td><td>000155</td><td>2020.01.01 09:31:00.000</td><td>1.0000</td></tr><tr><td>2</td><td>000155</td><td>2020.01.01 09:32:00.000</td><td>0.5000</td></tr><tr><td>3</td><td>000155</td><td>2020.01.01 09:33:00.000</td><td>0.4000</td></tr><tr><td>4</td><td>000155</td><td>2020.01.01 09:34:00.000</td><td>0.6250</td></tr><tr><td>5</td><td>000155</td><td>2020.01.01 09:35:00.000</td><td>0.3333</td></tr><tr><td>6</td><td>000155</td><td>2020.01.01 09:36:00.000</td><td>0.5789</td></tr></table>
7 rows 3 columns table
每一条注入响应式状态引擎的数据会触发一次计算并输出一条对应的结果。引擎根据输入数据的 tradeTime 向前选择 5 分钟的窗口范围,计算过去 5 分钟主动成交占比。
#### 7.1.2 交易实时监控
通过数据库进行交易实时监控是一种有效的金融安全措施,通过实时跟踪交易数据并与历史记录对比,及时检测任何异常活动。不仅可以帮助银行和金融机构检测潜在的信用卡盗刷行为,还可以迅速响应并拦截异常交易,以确保客户的资金和信用卡信息得到充分保护,降低了金融欺诈的风险。
## 信用卡欺诈交易判定规则:
信用卡欺诈交易的一般模式为:先用盗得的信用卡进行很小额度的例如一美元或者更小额度的消费进行测试。 如果测试消费成功,再使用该卡进行大笔消费。一个账户中如果出现小于 \$1 的交易后紧跟着一笔大于 \$500 的交易,且两笔交易的间隔在一分钟之内,认定为欺诈交易。
## 实现脚本:
---
## // 定义输入输出的表结构
inputTable = table(1:0, `accountID`time`amount, [SYMBOL, TIMESTAMP, DOUBLE])
resultTable = table(1:0, `accountID`time`amount`isFraud, [SYMBOL, TIMESTAMP, DOUBLE,
BOOL])
// 自定义状态函数 fraudDetection
@state
def fraudDetection(amount, time, SMALL_AMOUNT=1.0, LARGE_AMOUNT=500.0,
INTERVAL_MINUTE=1)\{
return (time-prev(time))<=INTERVAL_MINUTE*60*1000 and amount>LARGE_AMOUNT and
prev(amount) <SMALL_AMOUNT
\}
// 创建响应式状态引擎
try\{\{ dropStreamEngine("fraudDetectioneEngine")\} catch(ex)\{ print(ex) \}
rse = createReactiveStateEngine(name="fraudDetectioneEngine", metrics
=<[time, amount, fraudDetection(amount, time)]>, dummyTable=inputTable,
outputTable=resultTable, keyColumn="accountID")
---
以上代码通过 @state 标识声明了自定义状态函数 fraudDetection。在函数定义中多次使用了内置状态函数 prev 获取上一行记录,使用内置状态函数时引擎会自动缓存历史状态,而无需用户手动维护。因此 fraudDetection 函数中用与数学表达式近似的语句直观表达了欺诈交易的判定规则。
然后执行 createReactiveStateEngine 创建响应式状态引擎 fraudDetectioneEngine,指定分组键 accountID,即在引擎中按照账户分组,对每个账户的检测是相互独立的。输入引擎的数据结构与 inputTable 一致。数据注入引擎后触发计算指标的计算,参数 metrics 通过元代码指定了直接输出列,并使用已定义的 fraudDetection 状态函数标识每条记录是否为欺诈交易。
## 数据写入:
模拟数据写入引擎,并观察计算结果。
// 输入数据
insert into rse values(`000001, 2020.01.01T13:20:01.000, 25.00)
insert into rse values(`000001, 2020.01.02T09:32:10.000, 0.09)
insert into rse values(`000003, 2020.01.02T09:32:10.100, 25.00)
insert into rse values(`000001, 2020.01.02T09:32:15.590, 510.00)
insert into rse values(`000001, 2020.01.02T09:33:00.710, 6000.00)
insert into rse values(`000001, 2020.01.02T13:18:00.710, 1020.62)
insert into rse values(`000001, 2020.01.02T13:19:00.000, 91.50)
insert into rse values(`000003, 2020.01.02T14:00:00.000, 0.75)
insert into rse values(`000003, 2020.01.02T14:00:12.200, 30.01)
insert into rse values(`000003, 2020.01.02T14:00:56.950, 701.83)
insert into rse values(`000003, 2020.01.02T14:00:00.950, 31.92)
// 查看结果
select * from resultTable
<table><tr><td></td><td>accountID</td><td>time</td><td>amount</td><td>isFraud</td></tr><tr><td>0</td><td>000001</td><td>2020.01.01 13:20:01.000</td><td>25</td><td>false</td></tr><tr><td>1</td><td>000001</td><td>2020.01.02 09:32:10.000</td><td>0.09</td><td>false</td></tr><tr><td>2</td><td>000003</td><td>2020.01.02 09:32:10.100</td><td>25</td><td>false</td></tr><tr><td>3</td><td>000001</td><td>2020.01.02 09:33:00.710</td><td>510</td><td>true</td></tr><tr><td>4</td><td>000001</td><td>2020.01.02 09:33:00.710</td><td>6,000</td><td>false</td></tr><tr><td>5</td><td>000001</td><td>2020.01.02 13:18:00.710</td><td>1,020.62</td><td>false</td></tr><tr><td>6</td><td>000001</td><td>2020.01.02 13:19:00.000</td><td>91.5</td><td>false</td></tr><tr><td>7</td><td>000003</td><td>2020.01.02 14:00:00.000</td><td>0.75</td><td>false</td></tr><tr><td>8</td><td>000003</td><td>2020.01.02 14:00:12.200</td><td>30.01</td><td>false</td></tr><tr><td>9</td><td>000003</td><td>2020.01.02 14:00:56.950</td><td>701.83</td><td>false</td></tr><tr><td>10</td><td>000003</td><td>2020.01.02 14:00:00.950</td><td>31.92</td><td>false</td></tr></table>
11 rows 4 columns table
7 - 场景应用
每一条注入响应式状态引擎的数据会触发一次计算并输出一条对应的结果。在同一个账户内比较两笔相邻交易的时间间隔以及两次交易的金额大小,为每一笔交易打上是否为欺诈交易(isFraud)的标识。
进阶 1: 仅输出认定为欺诈交易的记录
---
## // 定义输入输出的表结构
inputTable = table(1:0, `accountID`time`amount, [SYMBOL, TIMESTAMP, DOUBLE])
resultTable = table(1:0, `accountID`time` amount`isFraud, [SYMBOL, TIMESTAMP, DOUBLE,
BOOL])
// 自定义状态函数 fraudDetection
@state
def fraudDetection(amount, time, SMALL_AMOUNT=1.0, LARGE_AMOUNT=500.0,
INTERVAL_MINUTE=1)\{
return (time-prev(time))<=INTERVAL_MINUTE*60*1000 and amount>LARGE_AMOUNT and
prev(amount)<SMALL_AMOUNT
\}
// 创建响应式状态引擎
try\{ dropStreamEngine("fraudDetectioneEngine")\} catch(ex)\{ print(ex) \}
rse = createReactiveStateEngine(name="fraudDetectioneEngine", metrics
=<[time, amount, fraudDetection(amount, time)]>, dummyTable=inputTable,
outputTable=resultTable, keyColumn="accountID", filter=<fraudDetection(amount,
time)==true>)
---
在创建响应式状态引擎增加指定参数 filter,该参数通过元代码指定了对于引擎输出进行过滤的条件,此处为调用 fraudDetection 状态函数后被标识为欺诈交易的计算结果将被输出。
模拟输入数据并查看结果,此时只有一条标记为欺诈交易的记录被输出。
<table><tr><td></td><td>accountID</td><td>time</td><td>amount</td><td>isFraud</td></tr><tr><td>0</td><td>000001</td><td>2020.01.02 09:32:15.590</td><td>510</td><td>true</td></tr></table>
1 rows 4 columns table
进阶 2: 增强欺诈交易判定规则
## 欺诈交易判定规则:
1. 对于一个账户,如果出现小于 \$1 的交易后紧跟着一笔大于 \$500 的交易,且两笔交易的间隔在一分钟之内,认定为欺诈交易。
2. 对于一个账户,如果发生了上述情况后紧跟着又有一笔或多笔大于 \$500 的交易,且相邻两笔交易的间隔在一分钟之内,同样认定为欺诈交易。
---
## // 定义输入输出的表结构
inputTable = table(1:0, `accountID`time`amount, [SYMBOL, TIMESTAMP, DOUBLE])
resultTable = table(1:0, `accountID`time`amount`isFraud, [SYMBOL, TIMESTAMP, DOUBLE,
BOOL])
// 自定义函数 fraudDetection
def iterateFraudDetection(prevIsFraud, time, prevTime, amount, prevAmount,
SMALL_AMOUNT=1.0, LARGE_AMOUNT=500.0, INTERVAL_MINUTE=1)\{
rule1 = (time-prevTime) <=INTERVAL_MINUTE*60*1000 and amount>LARGE_AMOUNT and
prevAmount<SMALL_AMOUNT
rule2 = (prevIsFraud and (time-prevTime)<=INTERVAL_MINUTE*60*1000 and
amount>LARGE_AMOUNT)
return rule1 or rule2
\}
// 创建响应式状态引擎
try\{ dropStreamEngine("fraudDetectioneEngine")\} catch(ex)\{ print(ex) \}
rse = createReactiveStateEngine(name="fraudDetectioneEngine", metrics =<[time,
amount, genericStateIterate([time, prev(time), amount, prev(amount)],
(iif(cumcount(time)==1, false, NULL)), 0, iterateFraudDetection)]>,
dummyTable=inputTable, outputTable=resultTable, keyColumn="accountID",
filter=< genericStateIterate([time, prev(time), amount, prev(amount)],
(iif(cumcount(time)==1, false, NULL)), 0, iterateFraudDetection)>)
---
判定规则 2 需要用到迭代计算,即当前记录是否为欺诈交易取决于上一条记录的状态。以上代码在引擎的 metrics 中使用内置函数 genericStateIterate 实现迭代计算,对于第一条记录总是判断为 false,即不是欺诈交易,之后的每一条记录的欺诈标识由自定义函数 iterateFraudDetection 计算得到,iterateFraudDetection 函数的第一个参数为上一条交易的欺诈标识,函数体内分别实现了两种判定规则的逻辑,任何一种规则下被判定为 true 则该笔交易都是欺诈交易。
模拟输入数据并查看结果:
<table><tr><td></td><td>accountID</td><td>time</td><td>amount</td><td>isFraud</td></tr><tr><td>0</td><td>000001</td><td>2020.01.02 09:32:15.590</td><td>510</td><td>true</td></tr><tr><td>1</td><td>000001</td><td>2020.01.02 09:33:00.710</td><td>6,000</td><td>true</td></tr></table>
2 rows 4 columns table
### 7.2 物联网
#### 7.2.1 异常检测
在物联网场景下,用户可以通过 DolphinDB 对物联网设备产生的各种传感器数据进行实时监控,如温度、湿度、压力、电压等,并对这些数据进行实时的异常检测、警告通知、故障诊断和预测维护,从而提高物联网系统的安全性和稳定性。同时,用户也可以对物联网系统产生的业务数据进行实时分析,如设备的使用率、能耗、效率等,以及用户的行为、偏好、满意度等,从而提供物联网系统的运营管理和优化建议。
## 场景需求:
现有一个物联网监控系统,其中每个监控传感器每一秒钟采集一次数据。希望实现以下异常检测需求:
7 - 场景应用
- 每3分钟内,若传感器温度出现 2 次 40 摄氏度以上并且 3 次 30 摄氏度以上,系统输出警告信息。
・若传感器网络断开,5 分钟内无数据,系统输出警告信息。
## 实现脚本:
## // 定义流数据表
share streamTable(1:0, `deviceID`ts`temperature, [INT, DATETIME, FLOAT]) as sensor share streamTable(1:0, `time` deviceID` anomalyType` anomalyString, [DATETIME, INT, INT, SYMBOL]) as warningTable
// 创建异常检测引擎
engine1 = createAnomalyDetectionEngine(name="engine1", metrics=<[sum(temperature > 40) > 2 && sum(temperature > 30) > 3]>, dummyTable=sensor,
outputTable=warningTable, timeColumn=`ts, keyColumn=`deviceID , windowSize= 180, step=180)
subscribeTable(tableName="sensor", actionName="sensorAnomalyDetection", offset=0, handler= append!\{engine1\}, msgAsTable=true)
// 创建会话窗口引擎,五分钟无数据则输出结果到告警表中
defg warning1()\{
return 1
\}
defg warning2()\{
return "五分钟无数据"
\}
engine2 =
createSessionWindowEngine(name='engine2', sessionGap=300, metrics=[<warning1()>,<warn ing2()), dummyTable=sensor, outputTable=warningTable, timeColumn=`ts, keyColumn=`device ID, useSessionStartTime=false, forceTriggerTime=301)
subscribeTable(tableName="sensor", actionName="warning", offset=0, handler= append!\{engine2\}, msgAsTable=true)
上述脚本定义并共享了流数据表 sensor 用于接收实时采集的传感器数据,表 warningTable 用于保存异常信息的输出结果。由于本例中只涉及温度指标的监测,发布表结构简化为三列,即传感器编号 deviceID,时间列 ts 和温度列 temperature。
- 为实现第一个温度异常报警需求,在创建异常检测引擎时,设置异常指标为 sum(temperature > 40) > 2 && sum(temperature > 30) > 3 ,分组列为传感器编号 deviceID,数据窗口为 180 秒,计算的时间间隔为 180 秒。
- 为实现第二个长时间无数据报警需求,创建会话窗口引擎并将会话间隔 sessionGap 设定为 300 秒,以判断是否已有五分钟未采集数据。若分组内经过五分钟后仍未接收数据,则关闭当前会话窗口。每个分组内的最后一条数据注入后,经过 forceTriggerTime(本例中为 301 秒),强制触发未计算的窗口进行计算。
## 数据写入:
通过以下脚本模拟写入 2 个设备的温度监控数据:
// 模拟写入流数据表
startTime = 2023.09.01T15:30:00
insert into sensor values (1, startTime+10,43)
insert into sensor values (2, startTime+10,41)
insert into sensor values (1, startTime+15,45)
insert into sensor values (1, startTime+20,35)
insert into sensor values (1, startTime+30,41)
insert into sensor values (1, startTime+120,41)
insert into sensor values (1, startTime+200,25)
// 检查结果
select * from warningTable
模拟数据写入后,查询警告输出表 warningTable,会首先收到设备1温度异常的警告结果。若五分钟后仍未接收数据,结果表中还会输出设备 “五分钟无数据” 的警告信息。
<table><tr><td></td><td>time</td><td>deviceID</td><td>anomalyType</td><td>anomalyString</td></tr><tr><td>0</td><td>2023.09.01 15:33:00</td><td>1</td><td>0</td><td>sum(temperature > 40) > 2 && sum(temperature > 30) > 3</td></tr><tr><td>1</td><td>2023.09.01 15:38:20</td><td>1</td><td>1</td><td>五分钟无数据</td></tr><tr><td>2</td><td>2023.09.01 15:35:00</td><td>2</td><td>1</td><td>五分钟无数据</td></tr></table>
3 rows 4 columns table warningTable
#### 7.2.2 数据降采样
在工业生产中,设备产生的数据经常是成百上千亿条的,但在进行数据处理分析时,关注的仅仅是设备状态的整体趋势,在这种情况下存储全量数据不仅是对存储资源的浪费,也会因为全量数据的规模降低数据分析效率。在此场景下可以通过 DolphinDB 流计算进行实时计算和降采样,提高分析效率并降低存储成本。
## 场景需求:
对收集的设备数据每 10 秒进行一次数据降采样,计算当前窗口的最值并保留最后一秒的原始数据
## 实现脚本:
// 定义流数据表
share streamTable(1:0, `ts`deviceID`value, [DATETIME, INT, FLOAT]) as deviceDate
share streamTable(1:0, `ts`deviceID`value`max`min, [DATETIME, INT, FLOAT, FLOAT, FLOAT, FLOAT])
---
as result
---
// 创建时间序列引擎
tsEngine = createTimeSeriesEngine(name="engine2", windowSize=
10, step=10, metrics=<[last(value), max(value), min(value)]>, dummyTable=deviceDate,
outputTable=result, timeColumn=`ts, keyColumn=`deviceID)
subscribeTable(tableName='deviceDate', actionName='downsample', offset=0, handler=appe
nd!\{tsEngine\}, msgAsTable=true)
7 - 场景应用
以上代码首先创建了两个流数据表,deviceDate 用于接入原始数据,result 用于储存降采样后的数据结果。
执行 createTimeSeriesEngine 创建时间序列引擎 tsEngine 并指定分组键为 deviceID,即在引擎内按照设备 ID 进行分组计算。收集的数据注入时序引擎后每 10 秒触发一次聚合计算,参数 metrics 通过元代码指定了需要进行的聚合操作,即取窗口内的最后一条数据和并求最大、最小值。
由于 DolphinDB 优化了聚合计算算子 last, min 与 max, 实现了引擎中的增量计算,显著提高了数据降采样的性能。
## 数据写入:
模拟数据写入引擎,并观察计算结果。
---
insert into deviceDate values(2023.09.01T00:00:01,1,100)
insert into deviceDate values(2023.09.01T00:00:02,1,101)
insert into deviceDate values(2023.09.01T00:00:05,1,102)
insert into deviceDate values(2023.09.01T00:00:06,1,103)
insert into deviceDate values(2023.09.01T00:00:10,1,104)
insert into deviceDate values(2023.09.01T00:00:11,1,105)
insert into deviceDate values(2023.09.01T00:00:20,1,106)
//查看结果
select * from result
---
模拟数据写入后,查询计算结果表,输出结果如下:
<table><tr><td></td><td>ts</td><td>deviceID</td><td>value</td><td>max</td><td>min</td></tr><tr><td>0</td><td>2023.09.01 00:00:10</td><td>1</td><td>103</td><td>103</td><td>100</td></tr><tr><td>1</td><td>2023.09.01 00:00:20</td><td>1</td><td>105</td><td>105</td><td>104</td></tr></table>
2 rows 5 columns table
## 第 8 章. 结语
DolphinDB 作为集成了分布式计算、实时流计算及分布式存储一体化的高性能时序数据库,为不同领域的流数据处理提供了完备的解决方案。本白皮书从流处理的基本概念出发,介绍了 DolphinDB 流数据处理高性能、低延迟、模块化的核心特性,并通过具体的示例展示了 DolphinDB 流数据处理在不同领域的高效采集、 传输、计算和分析应用。
我们致力于为用户提供更多创新的流数据解决方案,满足多样化的实时数据处理需求,从而发挥流数据处理的最大潜力。在未来的设计路线中,DolphinDB 将持续优化流数据的功能和性能,不断拓展应用领域:
- 支持 UDP 等通信协议,进一步提升流数据传输与处理的实时性并确保数据可靠性;
- 开发复杂事件处理(CEP)流计算引擎,支持实时复杂事件处理;
- 支持基于 SQL 语句的引擎级联解析器,增强流处理流水线的自动化搭建;
- 深度融合流处理与批处理,提升计算精度与准确性。