1.通达信量化选股第121篇:量价共振涨停抓牛捉妖指标公式源码
2.指标权重建模系列三:白话改进CRITIC法赋权(附Python源码)
3.源码编译 gcc 12
4.字符设备中的负对负的反码几个函数分析
通达信量化选股第121篇:量价共振涨停抓牛捉妖指标公式源码
量价共振指标是量化选股中的重要工具,经过年的应的源码原码研究与实践,程序猿们总结出一套精确的补码逻辑。量价共振指标的负对负的反码输出结论是,当量价线与黑马线发生交叉时,应的源码原码即出现“黄钻石”信号,补码移动护理源码这是负对负的反码买入的绝佳时机。为了提高准确性,应的源码原码还需满足以下几项条件:MACD指标呈现多头排列,补码主升线、负对负的反码黑马线、应的源码原码量价线形成多头排列,补码即“钱袋子”信号,负对负的反码以及量价线穿越黑马线,应的源码原码再次显现“黄钻石”信号。补码
以下是dos游戏 源码量价共振涨停抓牛捉妖主图指标公式源码,用于在图表上直观显示指标的实时表现和信号:
量价共振涨停抓牛捉妖主图指标公式源码
量价共振涨停抓牛捉妖副图指标公式源码提供更深入的分析,帮助投资者更精准地把握市场动态。
量价共振涨停抓牛捉妖副图指标公式源码解读
量价共振擒牛包含三个指标公式,旨在帮助投资者在市场中捕捉到最佳的买入时机。以下是这些指标的代码:
1、黄钻石信号选股代码
2、钱袋子信号选股代码
3、钱袋子+钻石共振选股
指标权重建模系列三:白话改进CRITIC法赋权(附Python源码)
上节回顾
前文讲述了CRITIC法赋权重的基本概念,其中涉及波动度与冲突度两个关键点。波动度指的是同一指标下数据的标准差,冲突度则衡量了指标间的相关性。
数据模型介绍
在数据集中,n个样本,m个指标,数学表达如下:
公式略
对CRITIC方法的idea软件源码改进
改进CRITIC法需聚焦波动度与冲突度。知友反馈指出公式上的不足,经文献研究后,重审并提出改进。
改进波动度计算
为消除量纲影响,改进公式将标准差除以均值,获得无量纲指标。
冲突度改进
原冲突度公式只考虑正相关。改进后,负相关亦视为强相关,调整冲突度计算公式。
改进后权重计算
引入熵权法,通过加权平均,平衡指标重要性与信息量,提升权重准确性与稳定性。
具体实现参考已发布的oneindex源码下载信息熵介绍文章。
Python代码
提供CRITIC法改进版的Python代码实现,便于实践操作。
参考文献
[1] 韩一鸣,徐鹏飞,宫建锋等.基于改进CRITIC-熵权法的电网发展经营综合评价体系研究[J].机电信息,():1-7+.DOI:./j.cnki.cn-/tm....
[2] 弋若兰.我国上市公司信用风险评估研究——基于改进CRITIC熵权组合赋权-TOPSIS模型[J].投资与创业,,():-.
源码编译 gcc
最近对于C++协程的研究促使我决定更新gcc到最新稳定版本.1.0。首先,从gcc官网下载了gcc-.1.0.tar.xz的安装包,通过`tar xf gcc-.1.0.tar.xz`命令解压。
接下来,进入解压后的目录,执行`./contrib/download_prerequisites`脚本来自动下载所需的依赖项,确保编译环境准备就绪。
然后,开始编译过程,通过`./configure`命令,并设置编译选项,如`--prefix=/home/lingzhang/gcc`指定安装路径,遇见app源码`--enable-bootstrap`启用自举编译,`--enable-languages=c,c++`启用C和C++语言支持,`--enable-threads=posix`选择POSIX线程模型,`--enable-checking=release`开启检查以确保质量,`--disable-multilib`禁用多库支持,`--with-system-zlib`使用系统级的zlib库。执行`make`命令开始编译,接着`make install`进行安装。
为了方便后续使用,创建了一个名为gcc.env的环境变量文件,内容为设置环境变量。通过`source gcc.env`来激活这个环境变量,确保gcc.1的正确使用。
最后,验证安装的gcc版本,通过`gcc -v`命令,显示的版本信息确认为.1,至此,gcc .1.0的编译和环境设置已完成。
字符设备中的几个函数分析
1.在内核中, dev_t 类型(在 <linux/types.h>中定义)用来持有设备编号 — 主次部分都包括.其中dev_t 是 位的量, 位用作主编号, 位用作次编号
1 #ifndef _LINUX_TYPES_H
2 #define _LINUX_TYPES_H
3
4 #include <asm/types.h>
5
6 #ifndef __ASSEMBLY__
7 #ifdef __KERNEL__
8
9 #define DECLARE_BITMAP(name,bits) /
unsigned long name[BITS_TO_LONGS(bits)]
#endif
#include <linux/posix_types.h>
#ifdef __KERNEL__
typedef __u __kernel_dev_t;
typedef __kernel_fd_set fd_set;
typedef __kernel_dev_t dev_t; //用来持有设备编号的主次部分
typedef __kernel_ino_t ino_t;
typedef __kernel_mode_t mode_t;
...
2.在 <linux/kdev_t.h>中的一套宏定义. 为获得一个 dev_t 的主或者次编号, 使用:
2.1设备编号的内部表示
MAJOR(dev_t dev);
MINOR(dev_t dev);
2.在有主次编号时, 需要将其转换为一个 dev_t, 可使用:
MKDEV(int major, int minor);
在linux/kdev_t.h中有下了内容
...
4 #define MINORBITS
5 #define MINORMASK ((1U << MINORBITS) - 1)
6
7 #define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
8 #define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
9 #define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))//高为表示主设备号,低位表示次设备号
...
3.分配和释放设备编号register_chrdev_region函数
下面摘自文件fs/char_dev.c内核源代码
/
*** register_chrdev_region() - register a range of device numbers
* @from: the first in the desired range of device numbers; must include
* the major number.
* @count: the number of consecutive device numbers required
* @name: the name of the device or driver.
*
* Return value is zero on success, a negative error code on failure.
*/
int register_chrdev_region(dev_t from, unsigned count, const char *name)
{
struct char_device_struct *cd;
dev_t to = from + count; //计算分配号范围中的最大值+=
dev_t n, next;
for (n = from; n < to; n = next) { /*每次申请个设备号*/
next = MKDEV(MAJOR(n)+1, 0);/*主设备号加一得到的设备号,次设备号为0*/
if (next > to)
next = to;
cd = __register_chrdev_region(MAJOR(n), MINOR(n),
next - n, name);
if (IS_ERR(cd))
goto fail;
}
return 0;
fail:/*当一次分配失败的时候,释放所有已经分配到地设备号*/
to = n;
for (n = from; n < to; n = next) {
next = MKDEV(MAJOR(n)+1, 0);
kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
}
return PTR_ERR(cd);
}
这里, from是要分配的起始设备编号. from 的次编号部分常常是 0, 但是没有要求是那个效果. count是你请求的连续设备编号的总数. 注意, 如果count 太大, 要求的范围可能溢出到下一个次编号;但是只要要求的编号范围可用, 一切都仍然会正确工作. 最后, name 是应当连接到这个编号范围的设备的名子; 它会出现在 /proc/devices 和 sysfs 中.如同大部分内核函数, 如果分配成功进行, register_chrdev_region 的返回值是 0. 出错的情况下, 返回一个负的错误码, 不能存取请求的区域.
4.下面是char_device_struct结构体的信息
fs/char_dev.c
static struct char_device_struct {
struct char_device_struct *next; // 指向散列冲突链表中的下一个元素的指针
unsigned int major; // 主设备号
unsigned int baseminor; // 起始次设备号
int minorct; // 设备编号的范围大小
const char *name; // 处理该设备编号范围内的设备驱动的名称
struct file_operations *fops; // 没有使用
struct cdev *cdev; /* will die指向字符设备驱动程序描述符的指针*/
} *chrdevs[MAX_PROBE_HASH];
/
** Register a single major with a specified minor range.
*
* If major == 0 this functions will dynamically allocate a major and return
* its number.
*
* If major > 0 this function will attempt to reserve the passed range of
* minors and will return zero on success.
*
* Returns a -ve errno on failure.
*/
/
*** 该函数主要是注册注册注册主设备号和次设备号
* major == 0此函数动态分配主设备号
* major > 0 则是申请分配指定的主设备号
* 返回0表示申请成功,返 回负数说明申请失败
*/
static struct char_device_struct
*__register_chrdev_region(unsigned int major, unsigned int baseminor,
int minorct, const char *name)
{ /*以下处理char_device_struct变量的初始化和注册*/
struct char_device_struct *cd, **cp;
int ret = 0;
int i;
//kzalloc()分配内存并且全部初始化为0,
cd = kzalloc(sizeof(struct char_device_struct), GFP_KERNEL);
if (cd == NULL)
//ENOMEM定义在include/asm-generic/error-base.h中,
// #define ENOMEM /* Out of memory */
return ERR_PTR(-ENOMEM);
mutex_lock(&chrdevs_lock);
/* temporary */
if (major == 0) { //下面动态申请主设备号
for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i—) {
//ARRAY_SIZE是定义为ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
//#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
if (chrdevs[i] == NULL)
//chrdevs是内核中已经注册了的设备好设备的一个数组
break;
}
if (i == 0) {
ret = -EBUSY;
goto out;
}
major = i;
ret = major;//这里得到一个位使用的设备号
}
//下面四句是对已经申请到的设备数据结构进行填充
cd->major = major;
cd->baseminor = baseminor;
cd->minorct = minorct;/*申请设备号的个数*/
strlcpy(cd->name, name, sizeof(cd->name));
/*以下部分将char_device_struct变量注册到内核*/
i = major_to_index(major);
for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
if ((*cp)->major > major || //chardevs[i]设备号大于主设备号
((*cp)->major == major &&
(((*cp)->baseminor >= baseminor) || //chardevs[i]主设备号等于主设备号,并且此设备号大于baseminor
((*cp)->baseminor + (*cp)->minorct > baseminor))))
break;
//在字符设备数组中找到现在注册的设备
/* Check for overlapping minor ranges. */
if (*cp && (*cp)->major == major) {
int old_min = (*cp)->baseminor;
int old_max = (*cp)->baseminor + (*cp)->minorct - 1;
int new_min = baseminor;
int new_max = baseminor + minorct - 1;
/* New driver overlaps from the left. */
if (new_max >= old_min && new_max <= old_max) {
ret = -EBUSY;
goto out;
}
/* New driver overlaps from the right. */
if (new_min <= old_max && new_min >= old_min) {
ret = -EBUSY;
goto out;
}
}
/*所申请的设备好号能够满足*/
cd->next = *cp;/*按照主设备号从小到大顺序排列*/
*cp = cd;
mutex_unlock(&chrdevs_lock);
return cd;
out:
mutex_unlock(&chrdevs_lock);
kfree(cd);
return ERR_PTR(ret);
}
以上程序大体上分为两个步骤:
1.char_device_struct类型变量的分配以及初始化~行
2.将char_device_struct变量注册到内核,行页到行
1.char_device_struct类型变量的分配以及初始化
(1)首先,调用 kmalloc 分配一个 char_device_struct 变量cd。
检查返回值,进行错误处理。
(2)将分配的char_device_struct变量的内存区清零memset。
(3)获取chrdevs_lock读写锁,并且关闭中断,禁止内核抢占,write_lock_irq。
(4)如果传入的主设备号major不为0,跳转到第(7)步。
(5)这时,major为0,首先需要分配一个合适的主设备号。
将 i 赋值成 ARRAY_SIZE(chrdevs)-1,其中的 chrdevs 是包含有个char_device_struct *类型的数组,
然后递减 i 的值,直到在chrdevs数组中出现 NULL。当chrdevs数组中不存在空值的时候,
ret = -EBUSY; goto out;
(6)到达这里,就表明主设备号major已经有合法的值了,接着进行char_device_struct变量的初始化。
设置major, baseminor, minorct以及name。
2.将char_device_struct变量注册到内核
(7)将 i 赋值成 major_to_index(major)
将major对取余数,得到可以存放char_device_struct在chrdevs中的索引
(8)进入循环,在chrdevs[i]的链表中找到一个合适位置。
退出循环的条件:
(1)chrdevs[i]为空。
(2)chrdevs[i]的主设备号大于major。
(3)chrdevs[i]的主设备号等于major,但是次设备号大于等于baseminor。
注意:cp = &(*cp)->next,cp是char_device_struct **类型,(*cp)->next是一个char_device_struct
*类型,所以&(*cp)->next,就得到一个char_device_struct **,并且这时候由于是指针,所以
对cp赋值,就相当于对链表中的元素的next字段进行操作。
(9)进行冲突检查,因为退出循环的情况可能造成设备号冲突(产生交集)。
如果*cp不空,并且*cp的major与要申请的major相同,此时,如果(*cp)->baseminor < baseminor + minorct,
就会发生冲突,因为和已经分配了的设备号冲突了。出错就跳转到ret = -EBUSY; goto out;
()到这里,内核可以满足设备号的申请,将cd链接到链表中。
()释放chrdevs_lock读写锁,开中断,开内核抢占。
()返回加入链表的char_device_struct变量cd。
()out出错退出
a.释放chrdevs_lock读写锁,开中断,开内核抢占。
b.释放char_device_struct变量cd,kfree。
c.返回错误信息
下面程序出自fs/char_dev.c
动态申请设备号
...
/
*** alloc_chrdev_region() - register a range of char device numbers
* @dev: output parameter for first assigned number
* @baseminor: first of the requested range of minor numbers
* @count: the number of minor numbers required
* @name: the name of the associated device or driver
*
* Allocates a range of char device numbers. The major number will be
* chosen dynamically, and returned (along with the first minor number)
* in @dev. Returns zero or a negative error code.
*/
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
const char *name)
{
/* dev:
仅仅作为输出参数,成功分配后将保存已分配的第一个设备编号。
baseminor:
被请求的第一个次设备号,通常是0。
count:
所要分配的设备号的个数。
name:
和所分配的设备号范围相对应的设备名称。
b.返回值:
成功返回0,失败返回负的错误编码
*/
struct char_device_struct *cd;
cd = __register_chrdev_region(0, baseminor, count, name);
if (IS_ERR(cd))
return PTR_ERR(cd);
*dev = MKDEV(cd->major, cd->baseminor);
return 0;
}
...