科技遐想阁

欢迎您来到“科技遐想阁”,一个汇聚技术与非技术文章的丰富平台。

yield是TypeScript(以及JavaScript)中的一个关键字,主要在一个生成器函数中使用。生成器函数是ES6引入的一种特殊类型的函数,它可以在执行过程中被暂停和恢复。

使用yield的生成器函数的特点是:函数体内可以使用yield表达式,返回一个迭代器,每次调用迭代器的next方法,函数会运行到下一个yield表达式处,yield后面的表达式的值,就是返回对象的value属性值。

基础用法

下面是一个基本的例子,用来生成一个简单的数字序列:

1
2
3
4
5
6
7
8
9
10
11
12
function* numberGenerator() {
let i = 0;
while (true) {
yield i++;
}
}

const gen = numberGenerator();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
// 这可以一直执行下去

在上面的例子中,每次调用gen.next()时,生成器函数就会从上次暂停的地方开始运行,直到遇到下一个yield表达式。然后,它将返回一个对象,该对象的value属性值等于yield后面的表达式的值。

产出值和接收值

生成器函数还有一个很有用的特性:它们不仅可以产出(yield)值,还可以接收值。当你调用next()方法并传入一个参数时,该参数会成为上一个yield表达式的值。看下面的例子:

1
2
3
4
5
6
7
8
9
10
function* dialog() {
const name = yield "What is your name?";
const job = yield `Hello, ${name}! What is your job?`;
return `${job}, that sounds interesting!`;
}

const gen = dialog();
console.log(gen.next().value); // What is your name?
console.log(gen.next("Alice").value); // Hello, Alice! What is your job?
console.log(gen.next("Engineer").value); // Engineer, that sounds interesting!

在这个例子中,当我们调用gen.next("Alice")时,"Alice"这个值被发送给生成器,赋值给name变量。同样地,当我们调用gen.next("Engineer")时,"Engineer"被发送给生成器,赋值给job变量。这就是生成器函数的接收值功能。

使用场景

生成器在处理流式数据或大型集合等情况下很有用。它们可以用于创建只在需要时计算其元素的数据结构(懒计算),处理异步操作等。

请注意,这只是关于yield和生成器函数的基本介绍。这是一个复杂且强大的特性,有很多更高级的用法和技巧,需要进一步学习和实践。

向上跳空两只乌鸦

是指开盘价突然高于前一根K线的收市价开盘,然后又支撑不住往下跌,收得一条阴线,然后第二根K线继续录得阴线。由于以前的K线图,阴线都是黑色的,所以并排的连根阴线看上去就像两只黑色乌鸦。而乌鸦又是形容不好的东西,比如我们平时所说“乌鸦嘴”,所以顾名思义,你可以知道两只乌鸦很可能是看空的。

在比较理想的两只乌鸦形态里面,第二根阴线的开盘价理应比第一根的要高,这样这种形态的看跌效力才会比较大。

两只乌鸦形态分析

为什么两只乌鸦会令到大家认为其实看空形态呢?大家可以想想,第一只乌鸦高开,意味着市场多头还在上攻,但后来又收阴下跌。这种情况可以看做只是多头的暂时性撤退,但第二只乌鸦再度高开又再度收阴,那说明什么呢?那说明市场多头开始动摇了,上攻失败了,行情开始要回撤了,市场恐慌情绪开始蔓延。在这种情况下,多头很有可能出现抛售获利的行为。

MACD(移动平均收敛/发散)是一种在金融领域常用的技术分析工具,用于判断资产价格可能的变化趋势。MACD的计算涉及到3个部分:MACD线、信号线和直方图。

  1. MACD线:计算12日EMA(指数移动平均)和26日EMA之间的差值。EMA是一种移动平均线,其中最近的价格数据有更高的权重。
  2. 信号线:MACD线的9日EMA。
  3. 直方图:MACD线和信号线之间的差值。

MACD指标的使用方法:

  1. 零线交叉:当MACD线从下方穿越零线到上方,这通常被看作是一个上升市场的信号,可能是买入的好时机。反之,如果MACD线从上方穿越零线到下方,这可能预示着一个下跌市场,可能是卖出的好时机。

  2. 信号线交叉:当MACD线从下方穿过信号线,这被视为买入信号。反之,如果MACD线从上方穿越信号线,这被看作是卖出信号。

  3. 直方图:如果直方图从负数变为正数,这可能预示着上升趋势。如果直方图从正数变为负数,这可能预示着下降趋势。

虽然MACD可以提供买入和卖出的信号,但它并不是唯一的决定因素。投资者应结合其他技术分析工具以及基本面因素一起做决策。此外,MACD可能不适用于所有的市场环境,特别是在市场震荡的时候,MACD产生的信号可能会有很多噪声。

使用独热编码而不是直接使用4x4的游戏板有几个理由:

  1. 非线性关系:在2048游戏中,格子的值是2的幂次(如2、4、8、16、32等),这是一个非线性关系。例如,格子的值从2到4的跳跃并不等同于从128到256的跳跃,尽管在两种情况下,数字都是翻倍。如果直接使用原始数字作为输入,神经网络可能会误解这种非线性关系。

  2. 稀疏表示:独热编码提供了一种稀疏表示,即大多数元素为0,只有一个元素为1。这种表示形式对于神经网络更容易处理,因为它可以更清楚地看到哪些格子有值(哪个位置的值为1),哪些格子是空的(哪个位置的值为0)。

  3. 规范化:神经网络训练的效果通常会受到输入数据规模的影响。如果直接使用2048游戏板上的数字作为输入,那么输入的规模将在0到2048之间。这种大范围的输入值可能会导致神经网络训练困难。通过使用独热编码,所有的输入值都被规范化为0和1,这可以帮助提高神经网络的训练效率和效果。

以上所述,使用独热编码是为了帮助神经网络更好地理解和学习2048游戏的复杂性。

指数移动平均线(Exponential Moving Average,EMA)是技术分析中一种常见的指标,用于预测市场趋势。EMA 对近期数据赋予更高的权重,因此它反应了市场的最新变化,比较灵敏。

EMA 的计算公式如下:

EMA = (Close - Previous EMA) * (2 / (Selected Time Period + 1)) + Previous EMA

这里,Close 是当前期间的收盘价,Previous EMA 是上一期间的EMA值,Selected Time Period 是你选择的时期长度(例如,如果你正在计算10天的EMA,那么Selected Time Period就是10)。

在具体计算中,第一个 EMA 值通常是采用简单移动平均线(SMA)来计算,然后从第二个值开始按照上述EMA的公式来计算。

使用 EMA 的主要原因是:EMA 的计算方法会对近期的数据赋予更大的权重,这反映了人们对近期市场信息的关注程度通常会超过对旧信息的关注程度。在动态变化的市场中,EMA 可以帮助投资者更快地把握市场的变化趋势。

在实际使用中,EMA 通常用于生成买卖信号,具体来说,当价格线从下方穿过 EMA 线时,可能是买入的信号;当价格线从上方穿过 EMA 线时,可能是卖出的信号。同时,EMA 的斜率也能反映市场的强度,斜率向上说明上涨动力较强,斜率向下说明下跌动力较强。

在C++中,auto关键字是一种让编译器自动推断变量类型的方法。它在C++11版本中引入,可以减少编程时的类型声明负担,提高代码的可读性和可维护性。使用auto时,编译器会自动根据等号右边的初始化表达式推断变量的类型。

下面是auto关键字的一些基本用法:

  1. 基础类型推导:编译器会根据赋值表达式自动推断类型。
1
2
3
4
auto i = 42; // int
auto d = 42.5; // double
auto s = "hello"; // const char*
auto b = true; // bool
  1. 复杂类型推导auto也可以用于复杂的类型,如容器,迭代器等。
1
2
3
4
5
6
std::vector<int> vec = {1, 2, 3, 4, 5};
auto v = vec; // std::vector<int>

for(auto it = vec.begin(); it != vec.end(); ++it) {
// ...
}
  1. 函数返回类型推导:从C++14开始,auto可以用于函数的返回类型推导。
1
2
3
auto func() {
return 42; // The return type of the function is int.
}

然而,需要注意的是,使用auto关键字时,有一些特殊情况:

  • 对于auto引用或常量,类型推导将会包含引用和常量性。
1
2
3
4
int x = 0;
auto& y = x; // y is int&

const auto z = x; // z is const int
  • 对于CV-qualifier,auto的推导可能会去除部分CV-qualifier。如果想保持CV-qualifier,可以使用const autovolatile auto
1
2
3
const char* const p = "Hello";
auto q = p; // q is const char*
const auto r = p; // r is const char* const
  • auto不能用于函数参数类型推导,除非在模板或者泛型lambda中。

  • 从C++17开始,可以用auto在结构体成员中,但这需要在声明时立即初始化。

总的来说,auto关键字在C++编程中是一个非常有用的工具,它可以简化代码并提高类型安全性。然而,需要注意一些特殊情况和使用限制,以避免意外的行为。

最大回撤是投资组合在选定期间从最高点下跌到最低点的百分比。在下面的TypeScript代码中,我们将通过遍历给定投资组合的每一个点来计算最大回撤。这个函数接受一个数组,该数组代表一系列投资组合的价值,然后返回最大回撤值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function calculateMaxDrawdown(portfolioValues: number[]): number {
let maxDrawdown = 0;
let peak = portfolioValues[0];

for (const value of portfolioValues) {
if (value > peak) {
peak = value;
} else {
let drawdown = (peak - value) / peak;
maxDrawdown = Math.max(maxDrawdown, drawdown);
}
}

// 将结果转化为百分比
return maxDrawdown * 100;
}

你可以使用以下样例来测试这个函数:

1
2
let portfolioValues = [100, 120, 100, 80, 120, 150, 130, 150];
console.log(calculateMaxDrawdown(portfolioValues)); // 这将输出 33.33333333333333

在这个例子中,投资组合价值从120下降到80,所以最大回撤是 33.33%。

Node.js 可以通过几种方式与 C++ 配合工作。在 Node.js 中,可以使用C++创建“插件”。这些插件通常是一些性能敏感的操作,或者是访问系统资源和调用底层 API 的功能。在这种情况下,你可以使用 Node.js 的插件 API,或者一个叫做 node-gyp 的构建工具链来编译 C++ 代码。

以下是一种基本的步骤,首先需要安装 node-gyp:

  1. 安装 node-gyp:

    1
    npm install -g node-gyp
  2. 创建一个新的项目文件夹,并在其中创建一个名为 “binding.gyp” 的文件,内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "targets": [
    {
    "target_name": "addon",
    "sources": [ "addon.cc" ]
    }
    ]
    }

这个文件告诉 node-gyp 你的源代码在 “addon.cc” 文件中,你想编译的插件名称为 “addon”。

  1. 在同一个文件夹中,创建一个名为 “addon.cc” 的 C++ 文件,内容如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <node.h>

    namespace demo {
    using v8::FunctionCallbackInfo;
    using v8::Isolate;
    using v8::Local;
    using v8::Object;
    using v8::String;
    using v8::Value;

    void Method(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    args.GetReturnValue().Set(String::NewFromUtf8(isolate, "Hello from C++!").ToLocalChecked());
    }

    void Initialize(Local<Object> exports) {
    NODE_SET_METHOD(exports, "hello", Method);
    }

    NODE_MODULE(addon, Initialize)
    } // namespace demo

此段代码定义了一个名为 “hello” 的函数,它返回一个字符串 “Hello from C++!”。

  1. 编译你的插件:

    1
    node-gyp configure build
  2. 创建一个名为 “index.js” 的文件,调用你的插件:

    1
    2
    3
    const addon = require('./build/Release/addon');

    console.log(addon.hello()); // 输出 "Hello from C++!"

以上,就是基本的使用 Node.js 和 C++ 配合的步骤和示例代码。

需要注意,编写 C++ 插件需要对 C++ 和 V8 的 API 有深入理解,并且需要注意内存管理和错误处理。而且,C++ 插件编译后是二进制代码,可能会和特定的 Node.js 或操作系统版本紧密绑定,这可能会在部署时引起问题。如果你只是想调用一些系统 API 或进行一些简单的计算,可能有更简单的方式,比如直接使用 Node.js 的 child_process 模块调用系统命令或使用 WebAssembly 等。

马尔可夫状态转移函数是用来描述马尔可夫过程中状态之间的转移概率的函数。在马尔可夫过程中,状态的变化是基于概率的,当前状态的转移概率只依赖于前一个状态,而与过去的状态序列无关。

一般而言,马尔可夫状态转移函数可以表示为:

P(Xt+1 = s’ | Xt = s)

其中,Xt表示时间t的状态,s和s’表示具体的状态值。这个函数表示在当前状态为s的情况下,下一个状态Xt+1为s’的概率。

马尔可夫状态转移函数可以用矩阵形式表示为转移概率矩阵P,其中P(i, j)表示在状态i的情况下转移到状态j的概率。对于马尔可夫链来说,转移概率矩阵是一个方阵,每一行的元素之和为1。

马尔可夫状态转移函数在马尔可夫链、隐马尔可夫模型等领域具有广泛的应用。它可以用来描述各种具有马尔可夫性质的系统,例如自然语言处理、时间序列分析等。

np.linalg.svd 是一个在 NumPy 库中的函数,用于执行奇异值分解(Singular Value Decomposition,简称 SVD)。奇异值分解是线性代数中的一种常见技术,用于将一个矩阵分解为三个矩阵的乘积。对于一个 m x n 的矩阵 A,SVD 分解可以表示为:

A = UΣV*

其中,U 是一个 m x m 的正交矩阵,Σ(使用希腊字母 Sigma 表示)是一个 m x n 的对角矩阵,其对角线上的元素是非负的,并按降序排列。这些对角线上的元素被称为奇异值。V* 是 V 的共轭转置,其中 V 是一个 n x n 的正交矩阵。

np.linalg.svd 函数的用法:

1
U, s, Vh = np.linalg.svd(A, full_matrices=True, compute_uv=True, hermitian=False)

参数说明:

  • A: 需要分解的矩阵。
  • full_matrices: 布尔值,如果为 True,则 U 和 V 为正方形矩阵。如果为 False,则输出的 U 和 V 的维数会被缩减。
  • compute_uv: 布尔值,如果为 True,则计算 U 和 V。如果为 False,则只计算奇异值向量 s。
  • hermitian: 布尔值,如果为 True,且输入矩阵是 Hermitian 的,SVD 将使用更加高效的算法。

返回值:

  • U: m x m 的正交矩阵。
  • s: 奇异值向量,长度为 min(m, n)。
  • Vh: n x n 的正交矩阵,是 V 的共轭转置。

现在来举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np

# 创建一个 3x2 的矩阵
A = np.array([[1, 2], [3, 4], [5, 6]])

# 进行奇异值分解
U, s, Vh = np.linalg.svd(A, full_matrices=True, compute_uv=True)

# 输出 U, s, Vh
print("U matrix:")
print(U)
print("\nSingular values:")
print(s)
print("\nV* matrix:")
print(Vh)

在这个例子中,我们对一个 3x2 的矩阵 A 进行奇异值分解。由于 full_matrices 参数设置为 True,U 矩阵的大小是 3x3,V* 矩阵的大小是 2x2。奇异值向量 s 的长度是 2。