首页 文章 精选 留言 我的

精选列表

搜索[快速入门],共10006篇文章
优秀的个人博客,低调大师

快速入门ECS快照功能,助力大数据容灾保护

阿里云快照是云盘数据在某个时刻完整的只读拷贝,是一种便捷高效的数据容灾手段,常用于数据备份、制作自定义镜像、应用容灾等。 应用场景 推荐您在以下场景中使用快照: 容灾备份:为云盘创建快照,再使用快照创建云盘获取基础数据,实现同城容灾和异地容灾。 环境复制:使用系统盘快照创建自定义镜像,再使用自定义镜像创建ECS实例,实现环境复制。 数据开发:为数据挖掘、报表查询和开发测试等应用提供近实时的真实生产数据。 提高容错率:出现操作失误时,能及时回滚数据,降低操作风险,实现版本回退。 定期创建快照,避免常见的失误操作。例如,团队成员不慎在云盘上存储了错误的数据、ECS实例被误释放、应用错误导致了数据错误、或者骇客利用应用漏洞恶意删除业务数据等。 执行重要操作前创建一份快照,常见的重要运维操作包括更换操作系统、应用软件升级或业务数据迁移等。 快照类型 快照主要分为本地快照和普通快照,区别在于存储方案的不同。根据不同区别方式,快照可以细分为以下类型: 计费 快照计费项为快照容量,支持按量付费计费方式和购买存储包。更多详情,请参见快照计费方式。 使用限制 有关快照的使用限制及配额,请参见使用限制快照章节。 使用本地快照具有以下限制: 仅ESSD云盘支持创建本地快照。 单块ESSD云盘最多能保留10份本地快照。 使用本地快照创建云盘时,设置的云盘容量不能大于快照大小。 不支持通过自动快照策略创建本地快照。 不支持为加密云盘、共享块存储、本地盘创建本地快照。 优势 相比于传统存储产品的数据快照功能,ECS快照具备以下优势: 相关操作 控制台操作: 创建快照 使用快照创建云盘 使用快照回滚云盘 使用快照创建自定义镜像 使用自定义镜像创建实例 API请参见API概览快照章节。 本文来自 阿里云文档中心 云服务器ECS 快照概述 云栖号在线课堂,每天都有产品技术专家分享立即加入圈子:https://c.tb.cn/F3.Z8gvnK与专家面对面,及时了解课程最新动态!

优秀的个人博客,低调大师

Java多线程 -- 互斥锁/共享锁/读写锁 快速入门

什么是互斥锁? 在访问共享资源之前对进行加锁操作,在访问完成之后进行解锁操作。 加锁后,任何其他试图再次加锁的线程会被阻塞,直到当前进程解锁。 如果解锁时有一个以上的线程阻塞,那么所有该锁上的线程都被编程就绪状态, 第一个变为就绪状态的线程又执行加锁操作,那么其他的线程又会进入等待。 在这种方式下,只有一个线程能够访问被互斥锁保护的资源。 什么是共享锁? 互斥锁要求只能有一个线程访问被保护的资源,共享锁从字面来看也即是允许多个线程共同访问资源。 什么是读写锁? 读写锁既是互斥锁,又是共享锁,read模式是共享,write是互斥(排它锁)的。 读写锁有三种状态:读加锁状态、写加锁状态和不加锁状态 一次只有一个线程可以占有写模式的读写锁,但是多个线程可以同时占有读模式的读写锁。 用ReentrantLock手动实现一个简单的读写锁。 MyReadWriteLock.java /** * Created by Fant.J. */ public class MyReadWriteLock { private Map<String,Object> map = new HashMap<>(); private ReadWriteLock rwl = new ReentrantReadWriteLock(); private Lock r = rwl.readLock(); private Lock w = rwl.writeLock(); public Object get(String key){ try { r.lock(); System.out.println(Thread.currentThread().getName()+"read 操作执行"); Thread.sleep(500); return map.get(key); } catch (InterruptedException e) { e.printStackTrace(); return null; } finally { r.unlock(); System.out.println(Thread.currentThread().getName()+"read 操作结束"); } } public void put(String key,Object value){ try { w.lock(); System.out.println(Thread.currentThread().getName()+"write 操作执行"); Thread.sleep(500); map.put(key,value); } catch (InterruptedException e) { e.printStackTrace(); } finally { w.unlock(); System.out.println(Thread.currentThread().getName()+"write 操作结束"); } } } 测试读读共享(不互斥) /** * Created by Fant.J. */ public class Test { public static void main(String[] args) { MyReadWriteLock myReadWriteLock = new MyReadWriteLock(); myReadWriteLock.put("a","fantj_a"); //读读不互斥(共享) //读写互斥 new Thread(new Runnable() { @Override public void run() { System.out.println(myReadWriteLock.get("a")); } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println(myReadWriteLock.get("a")); } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println(myReadWriteLock.get("a")); } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println(myReadWriteLock.get("a")); } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println(myReadWriteLock.get("a")); } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println(myReadWriteLock.get("a")); } }).start(); } } mainwrite 操作执行 mainwrite 操作结束 Thread-1read 操作执行 Thread-2read 操作执行 Thread-0read 操作执行 Thread-3read 操作执行 Thread-4read 操作执行 Thread-5read 操作执行 Thread-1read 操作结束 Thread-0read 操作结束 Thread-2read 操作结束 Thread-3read 操作结束 fantj_a fantj_a fantj_a fantj_a Thread-4read 操作结束 fantj_a Thread-5read 操作结束 fantj_a 可以看出,中间有很多read操作是并发进行的。 那么我们再看下写写是否有互斥性: /** * 测试 写-写 模式 是互斥的 * Created by Fant.J. */ public class TestWriteWrite { public static void main(String[] args) { MyReadWriteLock myReadWriteLock = new MyReadWriteLock(); new Thread(new Runnable() { @Override public void run() { myReadWriteLock.put("b","fantj_b"); } }).start(); new Thread(new Runnable() { @Override public void run() { myReadWriteLock.put("b","fantj_b"); } }).start(); new Thread(new Runnable() { @Override public void run() { myReadWriteLock.put("b","fantj_b"); } }).start(); new Thread(new Runnable() { @Override public void run() { myReadWriteLock.put("b","fantj_b"); } }).start(); new Thread(new Runnable() { @Override public void run() { myReadWriteLock.put("b","fantj_b"); } }).start(); } } Thread-0write 操作执行 Thread-1write 操作执行 Thread-0write 操作结束 Thread-1write 操作结束 Thread-2write 操作执行 Thread-2write 操作结束 Thread-3write 操作执行 Thread-3write 操作结束 Thread-4write 操作执行 Thread-4write 操作结束 控制台能明显感觉到线程休息的时间。所以它的写-写操作肯定是互斥的。 最后再看看,写-读 操作是否互斥。 写-读互斥 测试 /** * 测试 写-读模式 互斥 * Created by Fant.J. */ public class TestWriteRead { public static void main(String[] args) { MyReadWriteLock myReadWriteLock = new MyReadWriteLock(); //读读不互斥(共享) //读写互斥 new Thread(new Runnable() { @Override public void run() { myReadWriteLock.put("a","fantj_a"); } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println(myReadWriteLock.get("a")); } }).start(); } } Thread-0write 操作执行 Thread-1read 操作执行 Thread-0write 操作结束 Thread-1read 操作结束 fantj_a 控制台可以看到write操作执行后线程被阻塞。直到写释放了锁。 问题分析 问题1:仔细想了想,如果有一种场景,就是用户一直再读,写获取不到锁,那么不就造成脏读吗? 上一章我介绍了公平锁/非公平锁,资源的抢占不就是非公平锁造成的吗,那我们用公平锁把它包装下不就能避免了吗,我做了个简单的实现:(不知道公平锁的可以翻我上章教程) /** * 测试 读写锁 的公平锁 实现 * Created by Fant.J. */ public class TestReadWriteRead { public static void main(String[] args) { ReentrantLock fairLock = new ReentrantLock(true); MyReadWriteLock myReadWriteLock = new MyReadWriteLock(); myReadWriteLock.put("a","fantj_a"); new Thread(new Runnable() { @Override public void run() { fairLock.lock(); System.out.println(myReadWriteLock.get("a")); System.out.println("fair队列长度"+fairLock.getQueueLength()); fairLock.unlock(); } }).start(); new Thread(new Runnable() { @Override public void run() { fairLock.lock(); System.out.println(myReadWriteLock.get("a")); System.out.println("fair队列长度"+fairLock.getQueueLength()); fairLock.unlock(); } }).start(); new Thread(new Runnable() { @Override public void run() { fairLock.lock(); System.out.println(myReadWriteLock.get("a")); System.out.println("fair队列长度"+fairLock.getQueueLength()); fairLock.unlock(); } }).start(); new Thread(new Runnable() { @Override public void run() { fairLock.lock(); myReadWriteLock.put("a","fantj_a_update"); System.out.println("fair队列长度"+fairLock.getQueueLength()); fairLock.unlock(); } }).start(); new Thread(new Runnable() { @Override public void run() { fairLock.lock(); System.out.println(myReadWriteLock.get("a")); System.out.println("fair队列长度"+fairLock.getQueueLength()); fairLock.unlock(); } }).start(); } } mainwrite 操作执行 mainwrite 操作结束 Thread-0read 操作执行 Thread-0read 操作结束 fantj_a fair队列长度4 Thread-1read 操作执行 Thread-1read 操作结束 fantj_a fair队列长度3 Thread-2read 操作执行 Thread-2read 操作结束 fantj_a fair队列长度2 Thread-3write 操作执行 Thread-3write 操作结束 fair队列长度1 Thread-4read 操作执行 Thread-4read 操作结束 fantj_a_update fair队列长度0 如果谁有更好的实现方式(或者java有现成的实现工具类/包),可在评论区留言,我在百度上没有找到读写锁的公平锁实现~~谢谢!

优秀的个人博客,低调大师

Python3快速入门——(7)迭代(iterable)和迭代器

迭代(iterable) #任何可迭代对象都可以作用于for循环,包括我们自定义的数据类型,只要符合迭代条件,就可以使用for循环 d = { 'a' : 1 , 'b' : 2 , 'c' : 3 } #对dict迭代 for k,v in d.items(): # 如果要同时迭代key和value,可以用for k, v in d.items() print (k,v) #默认情况下,dict迭代的是key # 如果要迭代value,可以用for value in d.values() #字符串也是可迭代对象,因此,也可以作用于for循环 #如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断 from collections import Iterable #导入collections模块的Iterable类型 n= isinstance (d,Iterable) print (n) #结果为True,可迭代 #Python内置的 enumerate 函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身 names=[ 'a' , 'b' , 'c' , 'd' ] for i,value in enumerate (names): #for循环同时引用两个变量 print (i,value) for x,y in [( 1 , 2 ),( 3 , 5 ),( 5 , 6 )]: ##for循环同时引用两个变量 print (x,y) 迭代器 可以直接作用于 for 循环的数据类型有以下几种: 一类是 集合数据类型 ,如 list 、 tuple 、 dict 、 set 、 str 等; 一类是 generator ,包括生成器和带 yield 的generator function。 这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable #可以使用isinstance()判断一个对象是否是Iterable对象 from collections import Iterable m= isinstance ([],Iterable) #True #而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值, # 直到最后抛出StopIteration错误表示无法继续返回下一个值了。 #可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator #生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。 #把list、dict、str等Iterable变成Iterator可以使用iter()函数 from collections import Iterator m= isinstance ( iter ( 'abc' ),Iterator) #True 凡是可作用于 for 循环的对象都是 Iterable 类型; 凡是可作用于 next() 函数的对象都是 Iterator 类型,它们表示一个惰性计算的序列; 集合数据类型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,不过可以通过 iter() 函数获得一个 Iterator 对象。 Python的 for 循环本质上就是通过不断调用 next() 函数实现的

优秀的个人博客,低调大师

Python3快速入门——(4)循环结构和判断结构

循环结构 #循环结构 cities=[ "Austin" , "Dallas" , "Houston" ] for city in cities: #for循环 print (city) #通过缩进控制整体结构 i= 0 while i< 3 : #while循环 i+= 1 print (i) for j in range ( 10 ): #range(n)表示从0到n-1的n个数 print (j) cities=[[ "Austin" , "Dallas" , "Houston" ],[ "Haerbin" , "Shanghai" , "Beijing" ]] #list中的元素仍是list for city in cities: print (city) #输出list中的两个list元素 for i in cities: #两层for循环输出两个list中的每个元素 for j in i: print (j) #注意: 如果代码写得有问题,会让程序陷入“死循环”,也就是永远循环下去。这时可以用 Ctrl+C 退出程序,或者强制结束Python进程。 #注意 : Python提供一个 range() 函数,可以生成一个整数序列,再通过 list() 函数可以转换为list #例如: list ( range (5)) 结果为:[0, 1, 2, 3, 4] 判断结构 #选择结构 cat= True #bool类型值 dog= False print ( type (cat)) #<class 'bool'> print ( 8 == 8 ) #True 判断语句 print ( 8 != 8 ) #False print ( 10 >= 5 ) #True sample_rate= 700 if (sample_rate> 50 ): #if语句选择 print (sample_rate) else : print ( 'less lan' )

优秀的个人博客,低调大师

阿里云E-MapReduce快速入门之准备工作

在创建 E-MapReduce 之前,您需要先完成以下准备工作: 1.注册阿里云账号 在申请 E-MapReduce 集群之前,您需要一个阿里云的云账号用于标识您在整个阿里云生态系统中的身份。该账号不仅可以用来申请 E-MapReduce 集群,同时还能够开通阿里云的对象存储服务 OSS、云数据库 RDS等服务。 如果您还没有阿里云的云账号,请参见注册云账号进行申请。 2.创建 Access Key(可选) 由于 E-MapReduce 调用访问的需要,您至少需要创建一个 Access Key,创建步骤如下: 登录阿里云官网。 登录管理控制台。 单击 AccessKeys。 注意:若出现如下提示框,请单击继续使用 Accesskey。 accesskey 提示 单击创建 Access Key,然后再单击同意并创建。 输入短信校验码,单击确定。Access Key 创建成功。 3.开通阿里云 OSS 服务 E-MapReduce 会将您的作业日志和运行日志保存在您的阿里云 OSS 存储空间中,所以需要您开通阿里云 OSS 服务,操作步骤请参见开通 OSS 服务。并在您期望创建集群的相同地域创建Bucket,参见创建Bucket。 4.开通高配机型(可选) 如果您需要在按量的集群中使用8核及8核以上的机型时,需要先在ECS处申请开通。申请高配机型 5.准备足够的余额 目前根据阿里云 ECS 的规则,用户在购买按量付费 ECS 的时候,要保证阿里云账户中至少有 100 元的现金(注意:代金券无效)。因此,在创建按量集群前,请确认您的账户中已至少充值 100 元,否则会创建失败。前往充值 当您使用完成并释放集群以后,在没有ECS或者其他按量产品在使用的情况下,您可以将这100元提现,回到您自己的原有账户中。

优秀的个人博客,低调大师

云服务器 ECS快速入门:远程连接 ECS 实例

远程连接 ECS 实例 阿里云在控制台为您提供了 管理终端,方便您远程连接并管理 ECS 实例。 您也可以使用其他方式远程连接 ECS 实例: 如果是 Linux 实例: 使用 SSH 密钥对连接 Linux 实例 使用远程连接软件或 SSH 命令连接 Linux 实例 如果是 Windows 实例:使用远程连接软件连接 Windows 实例 以下是使用 管理终端 连接 ECS 实例操作步骤的简易说明。 登录 云服务器 ECS 管理控制台。 在左侧导航栏里,单击 实例。 在 实例列表 页上,选择目标地域。 在实例列表里,找到需要连接的实例,在 操作 列,单击 远程连接。 连接 管理终端: 如果这是您第一次连接 管理终端,应按照以下方式连接 管理终端: 在弹出的 远程连接密码 对话框,复制密码。 注意:连接密码仅在第一次连接管理终端时显示一次。如果您以后需要使用

优秀的个人博客,低调大师

201703深圳云栖大会Workshop-云盾WAF快速入门

目标 熟悉Web应用防火墙的架构 配置目标站点接入WAF 测试精准防护和日志检索功能 WAF的接入和防护架构 WAF采用反向代理的接入架构,通过修改防护域名的DNS解析到WAF而将流量牵引到WAF,通过各种防护模块过滤掉恶意流量后,再把正常请求转发回源站。 配置接入WAF 登录阿里云控制台,找到云盾->Web应用防火墙->域名配置,输入相关的域名及源站信息,并点击“添加域名”按钮: 注意事项: 支持配置泛域名,如*.aliyundemo.cn,可以匹配相关的二级域名。当同时配置泛域名和精确域名时,转发和防护策略匹配顺序以精确域名优先 如果有HTTPS站点,务必勾选HTTPS,同时建议勾选HTTP,以应对HTTP跳转等问题,同时需要在稍后上传源站证书和密钥(实验中我们只勾选HTTP) 源站IP可以支持最多20个,WAF会做负载均衡和健康检查,详情见“源站IP负载均衡” 如WAF前面还有CDN、高防等七层代理,务必勾选“是否已使用代理”,这样才能取到客户端真实IP,不然看到的都是上一级代理的IP 添加好域名后,会弹出选择解析方式的弹窗,为了更好的演示接入原理,这里选择手动修改: 配置好域名后,WAF会自动分配给当前域名一个CNAME,可点击域名信息来查看: 接下来我们登录万网控制台,找到对应域名的“域名解析”->“解析设置”,正常情况下会有已经存在的一些解析,如下图: 接下来需要将记录类型改成CNAME,记录值改成WAF控制台提供的CNAME,如下图: 开启日志检索 在刚配置好的域名->业务状态中,找到日志检索并打开: 配置并体验精准防护规则 精准访问控制规则允许用户基于HTTP头部的各个字段自由组合各种访问控制规则: 找到防护域名,点击“防护配置”,进入“精准访问控制规则”即可配置。您可以自由尝试各种条件,匹配的内容大小写不敏感,匹配按照从上到下的优先级。详细的配置方式请参考这里:https://help.aliyun.com/document_detail/42780.html 配置好后一般3分钟内即可生效,您可以手动构造一些请求来验证防护效果,如果匹配中拦截,预期访问会被WAF拦截并弹出405拦截页面: 同时,您也可以在日志检索中看一下拦截的具体请求,以及匹配中访问控制规则的情况: 以上是基本配置和功能演示,您可以结合自身业务特征,尝试更多的防护功能,欢迎随时与我们交流:https://help.aliyun.com/knowledge_detail/44036.html

优秀的个人博客,低调大师

vn.py快速入门7 - 历史数据回测优化

策略已经写好了,下一步就是历史回测:把历史上的价格数据(K线或者Tick),推送给策略去运行交易逻辑,并把策略产生的交易记录下来,最后分析这些回测的交易记录,从而来判断该策略的潜在盈利能力。 在开始之前,先来讲几个量化策略研究中(不管是否用vn.py),需要记住的几条重要原则: 所有量化程序的回测功能,永远都只能尽量接近实盘交易中的各项细节,而无法做到100%一样,关键点在于误差的大小(是否能容忍); 回测效果好的策略,并不能代表实盘交易就一定盈利,可能存在交易成本误差、参数过度拟合、逻辑有未来函数或者市场特征变化(Regime Switch)等原因; 回测效果烂的策略,实盘交易基本可以保证会更烂,绝对不要有侥幸心理。 准备历史数据 要跑历史数据回测,第一步自然就是要先准备好历史数据。这里我们以国内期货数据为例,使用米筐的RQData来下载获取。 RQData目前提供30天的免费试用权限,网站申请非常方便。前往RQData主页 找到上图中的“免费试用”按钮,点击进去后: 根据自己的实际情况填写相应的注册信息,邀请码点击那个白色小问号图标,可以看到没有邀请码情况下的默认输入值(当前是ClOR,注意l是小写的L,而不是大写的i),点击“登录并申请”按钮后,会看到登录框: 选择“验证码登录”,输入手机号验证码后点击“确认登录”按钮,回到上一步的界面,但注意此时底部按钮显示的文字已变为“立即申请试用”: 点击上述按钮后完成试用申请,注意此时有可能出现验证码超时或者其他的错误信息,根据提示重新填写再点击按钮即可。申请成功后会自动弹出开始下载[make.bat]文件(该文件中即包含了申请的试用账号和密码),以及[RQDATA使用说明.pdf]。 使用VS Code打开make.bat文件: 记住其中的name(用户名)以及password(密码),注意密码是一串长达344个字符的密钥,上图中仅截取了很短一部分(别想偷懒,哈哈)。 然后运行VN Station,点击VN Trader Pro,在右侧的上层应用中加载CtaBacktester(CTA回测模块)后启动,在主界面顶部的菜单栏,找到“配置”按钮: 点击后打开VN Trader的全局配置对话框: 将之前已经准备好的RQData用户名和密码,分别填入到rqdata.username和rqdata.password两个字段中,然后点击“确定”按钮,弹出提示重启的对话框。 此时即可关闭VN Trader并重启,点击菜单栏“功能”->“CTA回测”,启动接下来我们要用到的CTA策略回测图形界面: 如果上一步的RQData账号密码配置正确,此时可以在中间底部的日志输出框中看到“RQData数据接口初始化成功”的信息。如果没有就说明配置有问题,回去重来吧。 窗口左上方的一系列编辑框和下拉框,用来控制和管理我们的回测功能。在本地代码编辑框中输入IF88.CFFEX,K线周期选择1m(即1分钟K线),然后选择要下载数据的开始日期和结束日期,点击“下载数据”按钮。 此时CtaBacktester模块就会自动从RQData服务器下载历史数据,并完成数据结构转化后插入到VN Trader的数据库中(默认使用SQLite,数据文件位于.vntrader目录下的database.db),下载完成后同样会在日志输出框中看到相应信息: 运行历史回测 有了历史数据后,我们就可以开始跑历史回测。在左上角的交易策略下拉框里,应该已经能找到上一篇教程我们编写的DemoStrategy,选中后开始配置回测参数。 注意这里我们使用的是中金所股指期货的IF合约,回测时的参数要设置为股指期货所对应的属性。手续费率编辑框中输入0.000025(万0.25),交易滑点输入0.2(即单边成交1跳的滑点成本),合约乘数为300(300元每点),价格跳动也是0.2(股指期货最小价格变动),回测资金我们使用100万。 点击“开始回测”按钮,弹出参数配置对话框: 这里显示的fast_window和slow_window就是之前我们添加到parameters列表中的参数名称,这里我们直接使用默认数值,点击“确定”按钮后,我们的回测引擎就会自动开始执行策略回测的整个流程:加载数据、数据回放、模拟撮合、计算每日盈亏、统计指标、以及最后画出图表: 不出之前的意料,双均线策略的效果差的一塌糊涂,右侧图表的4个子图中: 子图1:资金变化曲线,笔直向下说明稳定亏损 子图2:最大回撤曲线,越来越大说明策略亏损越来越多 子图3:每日盈亏统计,红绿分布平均,但绿色密度更大(亏损) 子图4:盈亏的概率分布图,尖峰在0轴左侧(中位数日期发生亏损) 然后在中间顶部的表格中,可以看到回测相关的一些统计数据: 这策略干了什么事情能亏这么多钱呢,总有很多人会抱着不信邪的态度,此时点击左侧的“成交记录”按钮,可以看到回测过程中的每一笔成交记录: 还不信邪,可以点击“委托记录”按钮查看这些成交具体是由哪些委托触发的: 可以通过“成交记录”中的每条成交对应的委托号,在“委托记录”中找到策略下出的委托。细心的人可能已经发现上面两张图中,某一笔委托的价格和其对应成交的价格并不一致,这是因为我们在策略下单时使用了超价5元(为了保证成交),而回测仿真撮合时则是取了T+1时刻的最优成交价(也是实盘中最可能拿到的价格)。 在“每日盈亏”窗口中,可以看到以逐日盯市规则(期货结算规则),将每日的持仓和成交映射到当日收盘价后的当日整体盈亏情况: 最后,如果还是觉得死活不相信双均线策略怎么可能这么差,点击“K线图表按钮”,可以看到整个回测数据对应的K线图表: 上图中的黄色向上箭头代表多头成交(buy/cover),蓝色向下箭头则代表了空头成交(sell/short),可以通过键盘和鼠标拖动和缩放图表,看到自己想要的部分。 到了这里,是不是已经有点相信了“双均线策略就是垃圾”的说法?实际上从公平角度讲,以上看到的回测信息,并不能充分证明双均线信号的无效性,如果我们: 将手续费和滑点都调为0,这样不考虑交易成本影响 然后在回测时缩小fast_window到3,增大slow_window到80,即让长周期均线变得更加平稳 出来的结果则变成了: 从这张图上看,在不考虑交易成本时,双均线的来回穿插作为一种信号,可能还是有一定的预测效果(尽管也好不到哪里去)。 策略参数优化 实盘用可能是没希望了,但不妨碍我们想来折腾一下,看看在股指1分钟数据上到底怎样的均线组合能起到最好的效果,毕竟之前的3和80两个参数纯粹只是拍脑袋的结果。 假设我们想要看看fast_window,从2到20(步进2),slow_window,从20到100(步进10),参数分别两两组合出来的回测效果,看看能不能找到更好的均线组合。 比较傻的方法就是人工操作,每次将两个参数输入到回测的参数对话框里,然后运行等结果,再把结果记录在Excel表格里最后用来做排序比较。但对于这种机械重复的劳动,电脑比起人的效率要高得多得多,在本质上我们就是分别遍历两个参数的各种可能排列组合,然后针对每组组合,跑完回测并记录其中的关键结果,也就是所谓的“参数优化”。 CtaBacktester模块已经内置了策略参数优化的功能,点击左侧下方的“参数优化”按钮: 在弹出的对话框中,我们把之前的参数想法输入进去: 目标函数就选择最简单的总收益率 fast_window,开始数值为2,结束数值为20,每次步进为2(即2、4、6、8、10...) slow_window,开始数值为20,结束数值为100,每次步进为10(即20、30、40、50、60...) 点击“多进程优化”,使用暴力穷举算法(Brute-Force Algorithm),同时运行多个并行的Python进程,充分利用CPU的核心数量来加快优化速度。 优化完成后,日志信息中会有相应的提示,同时左下角的“优化结果”按钮会亮起: 点击后看到每组参数组合,所对应的目标函数结果: 效果最好的是fast_window为18,slow_window为90,带入到策略回测中运行后: 参数优化大法好!!! 可能在前面铺垫了那么多的情况下(过度拟合风险、双均线信号普通、移除了滑点手续费),你不见得还会脑子里蹦出这么一句话,但不可否认参数优化后的效果提升非常明显。 在本篇教程的最后,希望提醒大家的是:尽管看起来一路点点鼠标就能搞出个漂亮的资金曲线了,但实际上量化策略回测和优化过程中充满了各种各样的地雷。 到目前为止我们所讲述的只是最最基础的操作方法,还远没有涉及到实践经验的内容,这块要么大家用自己的真金白银在交易中慢慢积累,另一个成本更低的选择当然就是关注我们后续的进阶教程了! 了解更多知识,请关注vn.py社区公众号。

优秀的个人博客,低调大师

鸿蒙开发快速入门之:Hi3861 开发板(1)

Hi3861开发板介绍 Hi3861 WLAN模组是一片大约2cm*5cm大小的开发板,是一款高度集成的2.4GHz WLAN SoC芯片,集成IEEE 802.11b/g/n基带和RF(Radio Frequency)电路。支持OpenHarmony,并配套提供开放、易用的开发和调试运行环境。 图 1Hi3861 WLAN模组外观图 另外,Hi3861 WLAN模组还可以通过与Hi3861底板连接,扩充自身的外设能力,底板如下图所示。 图 2Hi3861底板外观图 RF电路包括功率放大器PA(Power Amplifier)、低噪声放大器LNA(Low Noise Amplifier)、RF Balun、天线开关以及电源管理等模块;支持20MHz标准带宽和5MHz/10MHz窄带宽,提供最大72.2Mbit/s物理层速率。 Hi3861 WLAN基带支持正交频分复用(OFDM)技术,并向下兼容直接序列扩频(DSSS)和补码键控(CCK)技术,支持IEEE 802.11 b/g/n协议的各种数据速率。 Hi3861芯片集成高性能32bit微处理器、硬件安全引擎以及丰富的外设接口,外设接口包括SPI(Synchronous Peripheral Interface)、UART(Universal Asynchronous Receiver & Transmitter)、I2C(The Inter Integrated Circuit)、PWM(Pulse Width Modulation)、GPIO(General Purpose Input/Output)和多路ADC(Analog to Digital Converter),同时支持高速SDIO2.0(Secure Digital Input/Output)接口,最高时钟可达50MHz;芯片内置SRAM(Static Random Access Memory)和Flash,可独立运行,并支持在Flash上运行程序。 Hi3861芯片适用于智能家电等物联网智能终端领域。 图 3Hi3861功能框图 资源和约束 Hi3861 WLAN模组资源十分有限,整板共2MB FLASH,352KB RAM。在编写业务代码时,需注意资源使用效率。 开发板规格 表 1Hi3861 WLAN模组规格清单 规格类型 规格清单 通用规格 1×1 2.4GHz频段(ch1~ch14) PHY支持IEEE 802.11b/g/n MAC支持IEEE802.11 d/e/h/i/k/v/w 内置PA和LNA,集成TX/RX Switch、Balun等 支持STA和AP形态,作为AP时最大支持6 个STA接入 支持WFA WPA/WPA2 personal、WPS2.0 支持与BT/BLE芯片共存的2/3/4 线PTA方案 电源电压输入范围:2.3V~3.6V IO电源电压支持1.8V和3.3V 支持RF自校准方案 低功耗: Ultra Deep Sleep模式:5μA@3.3V DTIM1:1.5mA@3.3V DTIM3:0.8mA@3.3V PHY特性 支持IEEE802.11b/g/n单天线所有的数据速率 支持最大速率:72.2Mbps@HT20 MCS7 支持标准20MHz带宽和5M/10M窄带宽 支持STBC 支持Short-GI MAC特性 支持A-MPDU,A-MSDU 支持Blk-ACK 支持QoS,满足不同业务服务质量需求 CPU子系统 高性能 32bit微处理器,最大工作频率160MHz 内嵌SRAM 352KB、ROM 288KB 内嵌 2MB Flash 外围接口 1个SDIO接口、2个SPI接口、2个I2C接口、3个UART接口、15个GPIO接口、7路ADC输入、6路PWM、1个I2S接口(注:上述接口通过复用实现) 外部主晶体频率40M或24M 其他信息 封装:QFN-32,5mm×5mm 工作温度:-40℃~+85℃ OpenHarmony关键特性 OpenHarmony基于Hi3861平台提供了多种开放能力,提供的关键组件如下表所示。 表 2OpenHarmony关键组件列表 组件名 能力介绍 WLAN服务 提供WLAN服务能力。包括:station和hotspot模式的连接、断开、状态查询等。 模组外设控制 提供操作外设的能力。包括:I2C、I2S、ADC、UART、SPI、SDIO、GPIO、PWM、FLASH等。 分布式软总线 在OpenHarmony分布式网络中,提供设备被发现、数据传输的能力。 设备安全绑定 提供在设备互联场景中,数据在设备之间的安全流转的能力。 基础加解密 提供密钥管理、加解密等能力。 系统服务管理 系统服务管理基于面向服务的架构,提供了OpenHarmony统一化的系统服务开发框架。 启动引导 提供系统服务的启动入口标识。在系统服务管理启动时,调用boostrap标识的入口函数,并启动系统服务。 系统属性 提供获取与设置系统属性的能力。 基础库 提供公共基础库能力。包括:文件操作、KV存储管理等。 DFX 提供DFX能力。包括:流水日志、时间打点等。 XTS 提供OpenHarmony生态认证测试套件的集合。

优秀的个人博客,低调大师

Table Store实时数据通道服务Go SDK快速入门

文档 产品简介 官网文档 安装 下载源码包 go get github.com/aliyun/aliyun-tablestore-go-sdk/tunnel 安装依赖 可以在tunnel目录下使用dep安装依赖 dep ensure -v 也可以直接使用go get安装依赖包: go get -u go.uber.org/zap go get github.com/cenkalti/backoff go get github.com/golang/protobuf/proto go get github.com/satori/go.uuid go get github.com/stretchr/testify/assert go get github.com/smartystreets/goconvey/convey go get github.co

优秀的个人博客,低调大师

Python3快速入门——(2)list和tuple(列表和元组)

1、List基础结构 #python中数据类型转换 str_eight= str (8) #整型8装换位字符型'8' str_eight_two="8" int_eight= int (str_eight_two) #字符型转换为整型 float_eight=float(str_eight_two) #字符型转换为浮点型 #python 中的运算符**表示指数 china=10 print(china**2) #结果为100 #List months=[] #声明months为list类型 print(type(months)) #<class 'list'> print(months) #[] 此时list为空 months. append ("January") #向list中添加元素(字符串) months.append("February") months.append(2) #向list中添加元素(整型)向同一个list中可以添加不同类型的元素 print(months) #输出list 结果为:['January', 'February', 2] 2、List索引 int_months=[1,2,3,4,5,6,7,8,9,10,11,12] #声明一个list length= len (int_months) #获取list的长度即有多少个元素 month1=int_months[0] #获取list中的第一个元素,每个list索引是默认从0开始的 month2=int_months[1] #获取list中的第二个元素 index=len(int_months)-1 #获取list最后一个元素的索引 last_value=int_months[index] #获取list最后一个元素 last_value1=int_months[-1] #索引-1代表最后一个元素的索引,-2代表倒数第二个元素的索引 #获取list中的某段元素(切片操作) months=["Jan","Feb","Mar","Apr","May","Jun","Jul"] two_four=months [2:4] #获取索引为2,3的值,不包括索引4的值(取头不取尾),注意索引是从0开始的,输出结果为["Mar","Apr"] three_six=months [3:] #获取索引3以后的所有元素 ['Apr', 'May', 'Jun', 'Jul'] months=[ "Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , "Jul" ] b=months[: 5:2 ] #取前5个元素,每两个取一个 print (b) #结果为['Jan', 'Mar', 'May'] b=months[:: 3 ] #对所有元素,每三个取一个 ;#结果为['Jan', 'Apr', 'Jul'] #字符串也可以用切片操作,只是操作结果仍是字符串 #tuple也可以用切片操作,只是操作的结果仍是tuple 3、list和tuple(列表和元组) list和tuple是Python内置的有序集合,一个可变,一个不可变 #list 列表 classmates=[ "Bob" , "Jim" , "Mar" , "Asia" , "Kry" ] classmates.append( "Bill" ) #往list中追加元素到末尾 classmates.insert( 1 , "Aut" ) #把元素插入到指定的位置,比如索引号为1的位置 classmates.pop() #要删除list末尾的元素,用pop()方法 classmates.pop( 1 ) #要删除指定位置的元素,用pop(i)方法,其中i是索引位置 classmates[ 1 ]= "Git" #要把某个元素替换成别的元素,可以直接赋值给对应的索引位置 #tuple 元组 names=( "Bob" , "Jim" ,[ "Mar" , "Asia" ], "Kry" ) #声明一个元组 #names这个tuple不能变,它也没有append(),insert()这样的方法。其他获取元素的方法和list是一样的 #可以正常地使用names[0],names[-1],但不能赋值成另外的元素 #当定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来,可以为空names=() names[ 2 ][ 0 ]= "X" names[ 2 ][ 1 ]= "Y" print (names) # 结果为('Bob', 'Jim', ['X', 'Y'], 'Kry') #表面上看,tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。 # tuple一开始指向的list并没有改成别的list,所以,tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。即指向'a',就不能改成指向'b',指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!

优秀的个人博客,低调大师

CodePipeline 持续集成/持续交付快速入门-- Node.js篇

本文演示如何使用Codepipeline构建一个Node.js项目并部署到ECS。 资源准备和限制 申请开通AliyunCodePipelineDefaultRole 服务 创建一台ECS(经典网络或VPC均可) 创建一个OSS的bucket 部署目标机器的操作系统:目前支持Ubutu 16.04, 14.04, Centos 7.3, 7.2, 6.8, Alinux 17.1操作系统。 源码地址:目前支持git协议的代码仓库。 在“用户证书”处根据项目配置设置用户凭证,比如github的用户名/密码,容器镜像仓库的用户名/密码,容器服务的证书,CodePipeline会加密存储用户凭证 操作流程 登录CodePipleine 控制台 同意RAM的CodePipeline角色授权 单击UI右上角“新建”,输入项目名称,选择“构建一个NodeJS的软件项目”,并单击“下一步” 配置Repositories添加Git仓库地址及Git验证方式 添加需要构建的代码分支,默认为Master 配置“构建命令” 配置“测试命令”并单击“下一步”如果不需要做单元测试,可以不填写测试命令 部署到ECS 上传构建物到OSS 部署构建物到ECS首先在要部署的ECS上执行下面的命令。 然后单击选择目标ECS并将其移到已选部署目标中 配置“部署命令”,“检查命令”(optional),“回滚命令”(optional)和“工作空间” 点击“下一步”,然后点击“提交” 8.执行构建完成项目配置后,可以单击左侧导航栏中的“立即构建”,开始执行配置中的构建及部署命令您可以在构建队列及构建历史中查看构建状态点击任务,单击“控制台输出”,可以查看日志。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Apache Tomcat

Apache Tomcat

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

Eclipse

Eclipse

Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。