国信可以使用miniqmt吗?
之前群里有国信的小伙伴说,国信的mini qmt无法使用的。
所以笔者特意去问了下国信的好友兼营业部经理,但他回复说,个人只要申请,就可以开通mini qmt。如果不申请,是无法使用的,无法连接上去。
但因为开通这个是不用门槛的,可能会有部分不懂的或者不愿意的经理会和客户说不支持,或者需要机构这样话语。
具体情况,具体分析。
1. 国信证券iQuant策略交易平台精简版是指国信证券iQuant策略交易平台更专业快速且简洁的版本,满足股票、期货、期权、基金等全品种交易需求。
2. 风险等级:R4
投资期限:0-1年
投资品种:权益类投资品种如股票、混合型基金、偏股型基金、股票型基金等。
3. 平台使用不收取费用。
具体的申请表如下:
不过申请了这个权限后,只能进行拉取数据,并没有交易权限。。交易权限需要机构才能开通。郁闷,看来国信的miniqmt是无法进行交易的了,只能白嫖点数据。
如果需要文字word版本,
可以到公众号后台回复: 国信mini申请
获取word版本。

或者加微信开通指定的营业部的国信qmt(iquant), 也可以帮你开通mini qmt。

收起阅读 »
github首页Maximum retries exceeded Please add an env variable called PAT_1 with your token
最近登录github后,发现之前显示的状态都不正常了。
正常的时候是这样的:
但现在提示是这样的:
有两个办法可以解决。
1. Set it up yourself using Vercel (requires some step)
2. Use URL provided by others (The easiest step)
翻译成中文:
1. 自己到vercel上部署一个这样的app (复杂)
2. 换一个其他人部署好的链接 (容易)
一般人就别折腾第一种方法了,直接使用第二种方法就好了。
笔者找了一些其他人部署好的链接:
拿去用就可以了:
收起阅读 »
正常的时候是这样的:
但现在提示是这样的:
Something went wrong! file an issue at https://tiny.one/readme-statsMaximum retries exceeded Please add an env variable called PAT_1 with your github token in vercel
有两个办法可以解决。
1. Set it up yourself using Vercel (requires some step)
2. Use URL provided by others (The easiest step)
翻译成中文:
1. 自己到vercel上部署一个这样的app (复杂)
2. 换一个其他人部署好的链接 (容易)
一般人就别折腾第一种方法了,直接使用第二种方法就好了。
笔者找了一些其他人部署好的链接:
拿去用就可以了:
https://github-readme-stats-git-masterrstaa-rickstaa.vercel.app
By Unknown
https://github-readme-stats-ruby-one.vercel.app
By Claudio Tancredi
https://github-readme-stats-ten-gilt.vercel.app
By Unknown
https://github-readme-stats-61 ... l.app
By Fanwang Meng
https://github-readme-stats.zohan.tech
By Zohan Subhash
https://readme-stats.clckblog.space
By Kevin Zhong

目前有万一免五的qmt ptrade量化交易接口的券商吗?
==== 2023-02-03 更新 ======
目前量化qmt 有可以免五的券商了,国信,国元
国元证券万一免五,最低0元起步,免五门槛入金1w,不过开通qmt的门槛是100w
国信证券万一免五,门槛是100门槛,不过如果只是开通qmt(iquant),它的门槛是比较低的,入金2w就可以了
综合来看,如要要用qmt+万一免五,入金要100w的。
目前(截至2023-01-08日) 市场上已经没有可以免五的支持qmt,ptrade的量化交易券商。
当然动辄入金500w-5000W的券商就忽略了,大部分散户是达不到这个资金要求的。
在正常条件下,入金1W 到 50W的范围内,目前多家券商已经停止股票免五了,费率最低是万一, 不过可以在开户后2-6月申请免五。【国金】
或者先把户开了,把量化接口的权限也开了,等到券商可以重新申请免五的时候申请即可。 目前多家券商的营业部老板也承诺了,只要后续免五开放,就可以帮有量化交易权限的用户申请免五。
(最晚大概3月低可以免5)【国盛】
当然如果如果有券商营业部可以支持免五,也可以联系微信自荐,诚意合作。

收起阅读 »
目前量化qmt 有可以免五的券商了,国信,国元
国元证券万一免五,最低0元起步,免五门槛入金1w,不过开通qmt的门槛是100w
国信证券万一免五,门槛是100门槛,不过如果只是开通qmt(iquant),它的门槛是比较低的,入金2w就可以了
综合来看,如要要用qmt+万一免五,入金要100w的。
目前(截至2023-01-08日) 市场上已经没有可以免五的支持qmt,ptrade的量化交易券商。
当然动辄入金500w-5000W的券商就忽略了,大部分散户是达不到这个资金要求的。
在正常条件下,入金1W 到 50W的范围内,目前多家券商已经停止股票免五了,费率最低是万一, 不过可以在开户后2-6月申请免五。【国金】
或者先把户开了,把量化接口的权限也开了,等到券商可以重新申请免五的时候申请即可。 目前多家券商的营业部老板也承诺了,只要后续免五开放,就可以帮有量化交易权限的用户申请免五。
(最晚大概3月低可以免5)【国盛】
当然如果如果有券商营业部可以支持免五,也可以联系微信自荐,诚意合作。

收起阅读 »
ptrade回测结束后执行某个函数,比如保存回测结果
http://ptradeapi.com/#after_trading_end
官方文档只提供一个每天盘后执行的函数,没有函数可以在回测结束后,固定执行某些操作。
比如我回测过程保存的历史交易记录,收益率等,要如何保存? 虽然可以在回测的时候,每个交易日保存一次。
但是这样就需要在回测的时候按照天打开文件,盘后写入一次。 使用一个全局对象操作,显得很啰嗦。
那么有没有办法可以做在回测结束后一次性 保存操作呢?
答案是有的。也很简单。 适用于ptrade,qmt。
https://t.zsxq.com/09yigu5dy

收起阅读 »
官方文档只提供一个每天盘后执行的函数,没有函数可以在回测结束后,固定执行某些操作。
比如我回测过程保存的历史交易记录,收益率等,要如何保存? 虽然可以在回测的时候,每个交易日保存一次。
但是这样就需要在回测的时候按照天打开文件,盘后写入一次。 使用一个全局对象操作,显得很啰嗦。
那么有没有办法可以做在回测结束后一次性 保存操作呢?
答案是有的。也很简单。 适用于ptrade,qmt。
https://t.zsxq.com/09yigu5dy

收起阅读 »
ptrade回测 获取回测当天的分时数据
http://ptradeapi.com/#get_price
ptrade api的文档第3条表明,
也就是用get_price是拿不到回测当天的数据。
比如下面的例子:
返回的数据:
回测日期是2022-12-01日,每天09:36运行,那10根数据。
但返回的数据是昨天的收盘前的10根分时数据。并非当天9:36分开始拿10根bar。
如果把日期数据也固定,
实际拿到的数据是空的,也就是无法拿到当天的数据。
正确的用法:
返回的数据:
欢迎关注公众号
收起阅读 »
ptrade api的文档第3条表明,
3、数据返回内容不包括当天数据。
也就是用get_price是拿不到回测当天的数据。
比如下面的例子:
def initialize(context):
# 初始化策略
run_daily(context, execute, '09:36')
def handle_data(context, data):
pass
def execute(context):
current = context.blotter.current_dt.strftime('%Y-%m-%d')
log.info(current)
security='128025.SZ'
df = get_price(security, start_date=None, end_date=None, frequency='1m', fields=None, fq=None, count=10)
log.info(df)
返回的数据:
2023-01-01 15:31:21 开始运行回测, 策略名称: 四叶草-指定时间价格
2022-12-01 09:36:00 - INFO - 2022-12-01
2022-12-01 09:36:00 - INFO - open high low close volume \
2022-11-30 14:51:00 276.510 276.560 274.626 275.500 217510.0
2022-11-30 14:52:00 275.240 278.638 275.205 278.398 363820.0
2022-11-30 14:53:00 278.485 278.895 276.660 277.479 307570.0
2022-11-30 14:54:00 277.337 278.440 276.660 278.440 239370.0
2022-11-30 14:55:00 279.900 287.113 279.900 287.113 853170.0
2022-11-30 14:56:00 287.113 288.526 286.533 288.125 581860.0
2022-11-30 14:57:00 288.126 291.800 287.909 291.361 523580.0
2022-11-30 14:58:00 291.500 292.980 291.500 291.800 36480.0
2022-11-30 14:59:00 291.800 291.800 291.800 291.800 0.0
2022-11-30 15:00:00 292.510 292.510 292.510 292.510 421398.0
回测日期是2022-12-01日,每天09:36运行,那10根数据。
但返回的数据是昨天的收盘前的10根分时数据。并非当天9:36分开始拿10根bar。
如果把日期数据也固定,
df = get_price(security, start_date='2022-12-01', end_date=None, frequency='1m', fields=None, fq=None, count=10)
实际拿到的数据是空的,也就是无法拿到当天的数据。
正确的用法:
def initialize(context):
# 初始化策略
run_daily(context, execute, '09:36')
def handle_data(context, data):
pass
def execute(context):
current = context.blotter.current_dt.strftime('%Y-%m-%d')
log.info(current)
security='128025.SZ'
count=6
df=get_history(count, frequency='1m', field='close', security_list=security, fq=None, include=False, fill='nan')
log.info(df)
返回的数据:
欢迎关注公众号

Ptrade获取可转债强赎数据
对于强赎的可转债而言,期权价值归0,叠加一个转股压力。类似于股票解禁的效果,导致转债和正股一起下跌。
所以在可转债的策略里面,把强赎的转债排除掉,是一个不错的因子。
但内置的ptrade接口数据并无提供任何转债相关的数据。
不过笔者这里提供了一个自研的数据接口。
http://ptradeapi.com/#%E5%8F%AF%E8%BD%AC%E5%80%BA%E5%BC%BA%E8%B5%8E%E4%B8%8E%E6%95%B0%E6%97%A5%E5%AD%90
方便在ptrade里面调用。
收起阅读 »
所以在可转债的策略里面,把强赎的转债排除掉,是一个不错的因子。
但内置的ptrade接口数据并无提供任何转债相关的数据。
不过笔者这里提供了一个自研的数据接口。
http://ptradeapi.com/#%E5%8F%AF%E8%BD%AC%E5%80%BA%E5%BC%BA%E8%B5%8E%E4%B8%8E%E6%95%B0%E6%97%A5%E5%AD%90
方便在ptrade里面调用。

ubuntu snap 配置不更新新软件
它默认会自动更新软件,非常的烦。
网上的禁用方法
在ubuntu20.04上是没有用的。因为它的snap不是最新的。要在ubuntu22.04上才可以。
在ubuntu 20.04上,
网上说 snap最多只能设置60天内不更新,所以还需要配合crontab,在计划任务里面设置时间。
收起阅读 »
网上的禁用方法
$ snap refresh --hold
error: unknown flag `hold'
在ubuntu20.04上是没有用的。因为它的snap不是最新的。要在ubuntu22.04上才可以。
在ubuntu 20.04上,
$ sudo snap set system refresh.hold="2030-01-01T01:00:00-01:00"
$ sudo snap set system refresh.metered=hold
网上说 snap最多只能设置60天内不更新,所以还需要配合crontab,在计划任务里面设置时间。
收起阅读 »
ubuntu snap 下载指定版本的pycharm goland
之前用的pycharm,goland被snap自动更新,更新到2022.3 , 导致之前的ida-eval-resetter 无法使用。
所以只好回滚到指定的pycharm版本。
使用snap可以下载指定版本的pycharm和goland
上面的命令下载 2021.2/stable的版本的pycharm
那么怎么查看pycharm的版本?
只要在里面挑一个好一点的版本就好了。
收起阅读 »
所以只好回滚到指定的pycharm版本。
使用snap可以下载指定版本的pycharm和goland
sudo snap install pycharm-professional --channel=2021.2/stable --classic
上面的命令下载 2021.2/stable的版本的pycharm
那么怎么查看pycharm的版本?
snap info pycharm-professional
name: pycharm-professional
summary: PyCharm Professional Edition
publisher: jetbrains✓
store-url: https://snapcraft.io/pycharm-professional
contact: https://www.jetbrains.com/pycharm/documentation/
license: unset
description: |
Python IDE for professional developers. Save time while PyCharm takes care of the r
on bigger things and embrace the keyboard-centric approach to get the most of PyCha
productivity features.
commands:
- pycharm-professional
snap-id: Uqpw0ZWqy6Wh4mgaWE0rxgM5tAGCwf4D
tracking: latest/stable
refresh-date: 15 days ago, at 09:57 CST
channels:
latest/stable: 2022.3 2022-12-01 (314) 779MB classic
latest/candidate: 2022.3.1-RC 2022-12-12 (315) 793MB classic
latest/beta: 2022.3.1-RC 2022-12-12 (315) 793MB classic
latest/edge: 2022.3.1-RC 2022-12-12 (315) 793MB classic
2022.3/stable: 2022.3 2022-12-01 (314) 779MB classic
2022.3/candidate: 2022.3.1-RC 2022-12-12 (315) 793MB classic
2022.3/beta: 2022.3.1-RC 2022-12-12 (315) 793MB classic
2022.3/edge: 2022.3.1-RC 2022-12-12 (315) 793MB classic
2022.2/stable: 2022.2.4 2022-11-17 (311) 764MB classic
2022.2/candidate: 2022.2.4 2022-11-17 (311) 764MB classic
2022.2/beta: 2022.2.4 2022-11-17 (311) 764MB classic
2022.2/edge: 2022.2.4 2022-11-17 (311) 764MB classic
2022.1/stable: 2022.1.4 2022-07-21 (295) 759MB classic
2022.1/candidate: 2022.1.4 2022-07-21 (295) 759MB classic
2022.1/beta: 2022.1.4 2022-07-21 (295) 759MB classic
2022.1/edge: 2022.1.4 2022-07-21 (295) 759MB classic
2021.3/stable: 2021.3.3 2022-03-17 (278) 702MB classic
2021.3/candidate: 2021.3.3 2022-03-17 (278) 702MB classic
2021.3/beta: 2021.3.3 2022-03-17 (278) 702MB classic
2021.3/edge: 2021.3.3 2022-03-17 (278) 702MB classic
2021.2/stable: 2021.2.4 2021-12-22 (268) 565MB classic
2021.2/candidate: 2021.2.4 2021-12-22 (268) 565MB classic
2021.2/beta: 2021.2.4 2021-12-22 (268) 565MB classic
2021.2/edge: 2021.2.4 2021-12-22 (268) 565MB classic
2021.1/stable: 2021.1.3 2021-06-30 (248) 530MB classic
2021.1/candidate: 2021.1.3 2021-06-30 (248) 530MB classic
2021.1/beta: 2021.1.3 2021-06-30 (248) 530MB classic
2021.1/edge: 2021.1.3 2021-06-30 (248) 530MB classic
2020.3/stable: 2020.3.5 2021-03-26 (237) 559MB classic
2020.3/candidate: 2020.3.5 2021-03-26 (237) 559MB classic
2020.3/beta: 2020.3.5 2021-03-26 (237) 559MB classic
2020.3/edge: 2020.3.5 2021-03-26 (237) 559MB classic
2020.2/stable: 2020.2.5 2020-12-02 (225) 479MB classic
2020.2/candidate: 2020.2.5 2020-12-02 (225) 479MB classic
2020.2/beta: 2020.2.5 2020-12-02 (225) 479MB classic
2020.2/edge: 2020.2.5 2020-12-02 (225) 479MB classic
2020.1/stable: 2020.1.5 2020-12-02 (224) 465MB classic
2020.1/candidate: 2020.1.5 2020-12-02 (224) 465MB classic
2020.1/beta: 2020.1.5 2020-12-02 (224) 465MB classic
2020.1/edge: 2020.1.5 2020-12-02 (224) 465MB classic
2019.3/stable: 2019.3.5 2020-05-08 (199) 473MB classic
2019.3/candidate: ↑
2019.3/beta: ↑
2019.3/edge: ↑
2019.2/stable: 2019.2.6 2020-02-10 (184) 445MB classic
2019.2/candidate: ↑
2019.2/beta: ↑
2019.2/edge: ↑
2019.1/stable: 2019.1.4 2019-07-30 (148) 394MB classic
2019.1/candidate: ↑
2019.1/beta: ↑
2019.1/edge: ↑
2018.3/stable: 2018.3.7 2019-07-10 (142) 355MB classic
2018.3/candidate: ↑
2018.3/beta: ↑
2018.3/edge: ↑
2018.2/stable: 2018.2.8 2019-04-12 (128) 313MB classic
2018.2/candidate: ↑
2018.2/beta: ↑
2018.2/edge: ↑
2018.1/stable: 2018.1.6 2018-11-15 (101) 314MB classic
2018.1/candidate: ↑
2018.1/beta: ↑
2018.1/edge: ↑
2017.3/stable: 2017.3.7 2018-11-15 (100) 344MB classic
2017.3/candidate: ↑
2017.3/beta: ↑
2017.3/edge: ↑
installed: 2022.3 (314) 779MB classic
只要在里面挑一个好一点的版本就好了。
收起阅读 »
golang mysql count(*) 的写法
mysql最为常用的语句。
使用golang标准库 database/sql 实现:
即可。
收起阅读 »
使用golang标准库 database/sql 实现:
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/lib/pq"
)
func main() {
var count int
db, err := sql.Open("postgres", "user=test password=test dbname=foo sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer db.Close()
row := db.QueryRow("SELECT COUNT(*) FROM table_name")
err := row.Scan(&count)
if err != nil {
log.Fatal(err)
}
fmt.Println(count)
}
即可。
收起阅读 »
golang mysql包 database/sql的基本操作:增删改查 (go sql操作 保存这篇文章就足够了)
如果不是使用gorm,直接操作底层mysql命令,那么最常使用的是 database/sql 这个包了。
下面的是一些常见的操作,如果需要写底层sql语句,使用频率极高,值得收藏。
当然,上面的语句也可以不用Prepare的写法,直接插入进去:
下面的是一些常见的操作,如果需要写底层sql语句,使用频率极高,值得收藏。
/*
* @Author: 30daydo
* @FilePath: /go110/go-012/g012.go
* @Description: Go 数据库基本操作
*/
package main
import (
"database/sql"
"fmt"
"runtime"
_ "github.com/go-sql-driver/mysql"
)
/**
// 创建 user 表
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`name` varchar(50) COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名',
`age` int NOT NULL COMMENT '年龄',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户信息表'
**/
// 全局对象 db
var db *sql.DB
// 定义一个 user 结构体接收数据:
type user struct {
id int
age int
name string
}
// 始化数据库的函数
func initDB() (err error) {
// 构建连接的 dsn 格式是:"用户名:密码@tcp(IP:端口)/数据库?charset=utf8"
dsn := "user:password@tcp(127.0.0.1:3306)/sql_test?charset=utf8mb4&parseTime=True"
// 给全局变量赋值, 注意这里不要使用 :=
db, err = sql.Open("mysql", dsn)
if err != nil {
fmt.Println("初始化数据库失败")
return err
}
// 校验dsn是否正确
fmt.Println("尝试与数据库建立连接...")
err = db.Ping()
if err != nil {
fmt.Println("连接失败")
return err
}
fmt.Println("连接成功")
db.SetMaxOpenConns(2000) // 设置最大打开连接数
db.SetMaxIdleConns(10) // 设置最大空闲连接数
return nil
}
// 插入数据
func insertRow(name string, age int) int64 {
sqlStr := "INSERT INTO user(name, age) VALUES (?,?)"
ret, err := db.Exec(sqlStr, name, age)
if err != nil {
fmt.Printf("插入失败, err: %v\n", err)
return 0
}
// 新插入数据的 id
insertId, err := ret.LastInsertId()
if err != nil {
fmt.Printf("获取新插入数据的 ID 失败, err:%v\n", err)
return 0
}
fmt.Printf("插入成功, ID 为 %d.\n", insertId)
return insertId
}
// 查询单条数据记录
func queryRow(rowId int64) {
sqlStr := "SELECT id, name, age FROM user WHERE id = ?"
var u user
// 确保 QueryRow 之后调用 Scan 方法,释放持有的数据库链接
err := db.QueryRow(sqlStr, rowId).Scan(&u.id, &u.name, &u.age)
if err != nil {
fmt.Printf("未找到记录, 查询失败, err: %v\n", err)
return
}
fmt.Printf("查询数据成功, id: %d name: %s age: %d \n", u.id, u.name, u.age)
}
// 更新数据
func updateRow(rowId int64, newAge int) {
sqlStr := "UPDATE user SET age=? WHERE id = ?"
ret, err := db.Exec(sqlStr, newAge, rowId)
if err != nil {
fmt.Printf("更新失败 , err:%v\n", err)
return
}
// 操作影响的行数
n, err := ret.RowsAffected()
if err != nil {
fmt.Printf("获取影响函数失败, err: %v\n", err)
return
}
fmt.Printf("更新成功, 影响行数为: %d\n", n)
}
// 删除数据
func deleteRow(rowId int64) {
sqlStr := "DELETE FROM user WHERE id = ?"
ret, err := db.Exec(sqlStr, rowId)
if err != nil {
fmt.Printf("删除失败, err: %v\n", err)
return
}
n, err := ret.RowsAffected() // 操作影响的行数
if err != nil {
fmt.Printf("获取影响函数失败, err: %v\n", err)
return
}
fmt.Printf("删除成功, 影响行数为: %d\n", n)
}
// 查询多行
func queryMultiRow() {
sqlStr := "SELECT id, name, age FROM user WHERE id > ?"
rows, err := db.Query(sqlStr, 0)
if err != nil {
fmt.Printf("查询失败, err:%v\n", err)
return
}
// 重要:关闭 rows, 释放持有的数据库链接
defer rows.Close()
// 循环读取结果集中的数据
for rows.Next() {
var u user
err := rows.Scan(&u.id, &u.name, &u.age)
if err != nil {
fmt.Printf("查询多行数据失败, err:%v\n", err)
return
}
fmt.Printf("当前数据 id: %d name: %s age: %d\n", u.id, u.name, u.age)
}
}
func main() {
// 使用内置函数打印
println("Hello", "菜鸟实战")
// 初始化数据库
initDB()
// 插入数据
var id1 = insertRow("唐遇春", 17)
var id2 = insertRow("冯显", 38)
var id3 = insertRow("花千里", 20)
// 查询多行数据
queryMultiRow()
// 更新数据
updateRow(id2, 35)
// 查询单行数据
queryRow(id2)
// 删除数据
deleteRow(id1)
// 查询多行数据
queryMultiRow()
queryRow(id3)
// 当前版本
fmt.Printf("版本: %s \n", runtime.Version())
}
当然,上面的语句也可以不用Prepare的写法,直接插入进去:
func insertDirect() {收起阅读 »
db, err := sql.Open("mysql",
"username:password@tcp(127.0.0.1:3306)/test_db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
sql := "INSERT INTO user(id, name, pwd) VALUES(?, ?, ?)"
res, err := db.Exec(sql, 13, "Jobs", "444555")
checkErr(err)
fmt.Println(res.LastInsertId())
}
宁稳网可转债弹性因子 python回测
利用文章:
https://t.zsxq.com/08779XPlk
的数据和代码,修改原来的代码
还有这里:
如果修改持有个数,天数,修改HOLD_NUM ,和FREQ 即可
得到下面的图:
点击查看大图
"1天,大到小" 收益率 -30%,最大回撤34%
"1天,小到大" 收益率15.74%,最大回撤10.43%
'5天,大到小' 收益率-25%,最大回撤30.71%
'5天,小到大' 收益率7.36%, 最大回撤10.47%
可见弹性按照单天弹性值排名,买入最大的10只,无论按1天还是5天轮动,今天收益率是亏损的;
可见弹性按照单天弹性值排名,买入最小的10只,无论按1天还是5天轮动,今天收益率是盈利的;
如果对数据有疑问,可以到公众号后台留言~
收起阅读 »
https://t.zsxq.com/08779XPlk
的数据和代码,修改原来的代码
df=df.sort_values('税前收益率',ascending=False)
改为
df=df.sort_values('弹性',ascending=False) # 倒序
df=df.sort_values('弹性',ascending=True) # 正序
还有这里:
df = pd.read_excel(full_path)
df['税前收益率'] = df['税前收益率'].map(convert_float)
df['转股价格']=df['转股价格'].astype(float)
df=df[['转债代码','转债名称','转债价格','税前收益率']]
改为:
df['弹性'] = df['弹性'].map(convert_float)
df['转股价格']=df['转股价格'].astype(float)
df=df[['转债代码','转债名称','转债价格','弹性']]
如果修改持有个数,天数,修改HOLD_NUM ,和FREQ 即可
得到下面的图:
点击查看大图
"1天,大到小" 收益率 -30%,最大回撤34%
"1天,小到大" 收益率15.74%,最大回撤10.43%
'5天,大到小' 收益率-25%,最大回撤30.71%
'5天,小到大' 收益率7.36%, 最大回撤10.47%
可见弹性按照单天弹性值排名,买入最大的10只,无论按1天还是5天轮动,今天收益率是亏损的;
可见弹性按照单天弹性值排名,买入最小的10只,无论按1天还是5天轮动,今天收益率是盈利的;
如果对数据有疑问,可以到公众号后台留言~

python父类如何判断子类时候实现了某个方法或者属性赋值
用hasattr内置函数即可
看看下面的例子
obj.run调用的是parent里面的方法。
而parent的run里面调用一个hasattr, 来判断self 是否有get_salary这个函数。
因为self是从子类传进去的,所以self实际是 child的实例。
因为child里面是有get_salary方法(属性)的,所以hasatrr 是返回true, 然后调用子类的self.get_salary
从而程序没有报错。打印正确的返回数据
收起阅读 »
看看下面的例子
class Parent:
def __init__(self):
self.name='parent'
self.age=10
def run(self):
if hasattr(self,'get_salary'):
print('has func')
print(self.get_salary())
class Child(Parent):
def __init__(self):
# self.name='child'
Parent.__init__(self)
self.salary=100
def get_salary(self):
return self.salary
obj = Child()
obj.run()
obj.run调用的是parent里面的方法。
而parent的run里面调用一个hasattr, 来判断self 是否有get_salary这个函数。
因为self是从子类传进去的,所以self实际是 child的实例。
因为child里面是有get_salary方法(属性)的,所以hasatrr 是返回true, 然后调用子类的self.get_salary
从而程序没有报错。打印正确的返回数据
收起阅读 »
Ptrade QMT 哪家费率最便宜,门槛最低?
最近咨询的朋友很多。这里做个汇总,可以节省大家的时间。
笔者只会推荐合适的券商和量化接口给你,而不会推荐坑爹的券商给你。
如果你不信任,绕路即可,莫浪费大家时间。或者你有好的资源或者券商,你也可以推荐给我,可以给你发红包,奖励你提供有用的情报信息。
目前支持ptrade,qmt可以股票可以免五(0.1元起步)的券商,只有国盛,需要的可以找我开。 但是有入金门槛,ptrade门槛30w, qmt 的门槛50w。 国盛的ptrade可以链接外网。其他家的不行。但国盛的qmt不支持运行在云服务器。
其他家的qmt是支持的云服务器的,但国金的qmt会每天自动退出,需要每次手动点击登录,我也写了一个自动登录的小脚本,开完户的朋友可以拿去用用。
门槛低的国信,适合新手使用,但是没有miniqmt,这个东西也不一定适合你。 真的需要这个功能,在qmt里面可以写一段代码,让它把下单接口变成http指令,把下单功能独立出来,也是可以的。不过这个属于进阶功能。 需要的也可以把代码给你。
笔者用过大部分券商的ptrade qmt,所以个人的指导与推荐还是很有指导意见的。 写过的策略也大部分人(99%)多, 平台好坏,坑的多寡,哪里有雷,都已经摸清摸楚。 可以大大节省你们的时间。 当然你也可以忽略,自己去折腾折腾。选ptrade 还是qmt,然后哪个券商,什么费率。
需要开通ptrade - qmt 低门槛 低费率 的 或者可以提供更低费用的资源的可以加微信:

ptrade 接口文档: http://ptradeapi.com
收起阅读 »
笔者只会推荐合适的券商和量化接口给你,而不会推荐坑爹的券商给你。
如果你不信任,绕路即可,莫浪费大家时间。或者你有好的资源或者券商,你也可以推荐给我,可以给你发红包,奖励你提供有用的情报信息。
目前支持ptrade,qmt可以股票可以免五(0.1元起步)的券商,只有国盛,需要的可以找我开。 但是有入金门槛,ptrade门槛30w, qmt 的门槛50w。 国盛的ptrade可以链接外网。其他家的不行。但国盛的qmt不支持运行在云服务器。
其他家的qmt是支持的云服务器的,但国金的qmt会每天自动退出,需要每次手动点击登录,我也写了一个自动登录的小脚本,开完户的朋友可以拿去用用。
门槛低的国信,适合新手使用,但是没有miniqmt,这个东西也不一定适合你。 真的需要这个功能,在qmt里面可以写一段代码,让它把下单接口变成http指令,把下单功能独立出来,也是可以的。不过这个属于进阶功能。 需要的也可以把代码给你。
笔者用过大部分券商的ptrade qmt,所以个人的指导与推荐还是很有指导意见的。 写过的策略也大部分人(99%)多, 平台好坏,坑的多寡,哪里有雷,都已经摸清摸楚。 可以大大节省你们的时间。 当然你也可以忽略,自己去折腾折腾。选ptrade 还是qmt,然后哪个券商,什么费率。
需要开通ptrade - qmt 低门槛 低费率 的 或者可以提供更低费用的资源的可以加微信:

ptrade 接口文档: http://ptradeapi.com
收起阅读 »
Linux 运行resilio (一个跨平台的资源共享类软件)【附pro license】
什么是resilio ?
只需要知道一个分享密钥key,即可同步整个文件夹了,不需要第三方服务器,不受存储空间和流量限制,Resilio Sync的数据不在云端,而是存储在本地,传输速度基本上只受用户网络带宽的制约,它可以支持多人同时同步,而且,越多人对文件夹进行同步,则同步速度越快,没有审查,不过现在已经属于404 的产品了,不过如果找到神key,资源还是蛮丰富的。
安装过程:
1、打开官网下载安装Resilio Sync,国内用户需要自备网络环境。
对于linux , ubuntu,解压后实际只有一个可执行文件,猜测这个很可能是golang写的。因为大部分golang的程序都可以编译成一个文件。
运行后rslsync是在后台运行的。 不会返回访问界面,当然linux下也不会有界面。 需要你打开浏览器, 输入 http://127.0.0.1:8888
就可以看到resilio的内容了。
2、下载Resilio Sync授权文件:ResilioSyncPro.btskey. 附件里面
3、然后解压,解压后文件后缀是btskey,打开安装好的Resilio Sync,打开设置的License界面,点击Apply License
这个时候页面是空的,没有任何空的内容。 这个时候就需要一些神key。因为上面也说了,resilio是通过分享key,来获取资源的。
比如zlibrary,有人共享了不少电子书在某个文件夹里面。 只要找到一个key,你就可以找到一个资源分享的组织。
需要电子书的key,可以关注公众号:

回复:电子书key
可以获取zibibrary 几个T的电子书。
收起阅读 »
只需要知道一个分享密钥key,即可同步整个文件夹了,不需要第三方服务器,不受存储空间和流量限制,Resilio Sync的数据不在云端,而是存储在本地,传输速度基本上只受用户网络带宽的制约,它可以支持多人同时同步,而且,越多人对文件夹进行同步,则同步速度越快,没有审查,不过现在已经属于404 的产品了,不过如果找到神key,资源还是蛮丰富的。
安装过程:
1、打开官网下载安装Resilio Sync,国内用户需要自备网络环境。
对于linux , ubuntu,解压后实际只有一个可执行文件,猜测这个很可能是golang写的。因为大部分golang的程序都可以编译成一个文件。
$ ./rslsync
By using this application, you agree to our Privacy Policy, Terms of Use and End User License Agreement.
https://www.resilio.com/legal/privacy
https://www.resilio.com/legal/terms-of-use
https://www.resilio.com/legal/eula
运行后rslsync是在后台运行的。 不会返回访问界面,当然linux下也不会有界面。 需要你打开浏览器, 输入 http://127.0.0.1:8888
就可以看到resilio的内容了。
2、下载Resilio Sync授权文件:ResilioSyncPro.btskey. 附件里面
3、然后解压,解压后文件后缀是btskey,打开安装好的Resilio Sync,打开设置的License界面,点击Apply License
这个时候页面是空的,没有任何空的内容。 这个时候就需要一些神key。因为上面也说了,resilio是通过分享key,来获取资源的。
比如zlibrary,有人共享了不少电子书在某个文件夹里面。 只要找到一个key,你就可以找到一个资源分享的组织。
需要电子书的key,可以关注公众号:

回复:电子书key
可以获取zibibrary 几个T的电子书。
收起阅读 »
可转债到期收益率因子回测 YTM回测 vs 双低 低溢价 低价策略
最近看到有人发的一些可转债高YTM的回测结果图,说高YTM轮动收益达到年化20%。嗯?高TYM实际上大部分是和低价转债是重叠的,理论和实际收益率都应该不会有这么高的。
自从优矿转为收费后,基本就没有登录过了。现在的回测在本地进行了,宁稳网的可转债数据上有YTM这因子数据,所以这次使用宁稳网的数据回测。也不使用什么第三方框架了,直接手写回测,模拟交易过程。
逻辑就是按照交易日期,读取所有excel数据。保存到一个dataframe里面,然后按照日期对YTM排名。 选出排名N名的进行买入,掉出N名的进行卖出。
数据源
采用宁稳的全表数据,里面有YTM因子
YTM收益率曲线
本地使用python编写回测代码,纯手工,不使用第三方框架。 平时我也多次力荐大家手写,别依赖那些第三方框架,什么vnpy,backtrade,一是特别难用,数据要适配,二是不好调试,除非你对它们的源码特别熟悉。本回测代码和宁稳数据放在个人知识星球,大部分人其实只关心回测结果就够了。
下图是2022年1月1日至11月25日的回测数据。持有10个标的,红色的是1天调仓,蓝色的是5天调仓
5天轮动,2022年的收益率为4.29%,最大回撤6.98% 。
1天轮动,2022年的收益率为9.33%,最大回撤5.32% 。
1天轮动的整体收益率要比5天轮动的高5个点,并且最大回撤也小一点。
持仓日志
从持仓以及调仓日志来看,买入的大部分是低价转债,且部分也是之前有瑕疵,爆过雷的转债。
高YTM轮动 vs 双低,低溢价,低价
接着对比一下几个常规的转债策略,双低,低溢价,低价。
回测条件相同,起始时间2022-01-01,结束时间2022-11-25。
持有10只,5天轮动。
在今年的可转债偏弱的行情下,高YTM轮动在这4个策略里面的收益率是最高的。
低溢价一如既然的高波动,一会ICU,一会蹦迪。但笔者觉得跌到前期最大回撤的位置,低溢价可以考虑介入的。
YTM和低价格的今年回测收益率接近,YTM高了一个点左右,最大回撤接近。 而低溢价还在回撤的途中,目前今年的收益率为-25%,如果轮动频率高一些,低溢价收益率会高一些,强赎的转债基本会被轮入低溢价标的,因为最近半年强赎后的转债像进入了死亡螺旋一样,正股转债一起跌;因此排除强赎转债会对低溢价收益率有不少的提升。
完整代码以及数据请开通星球查收。
收起阅读 »
自从优矿转为收费后,基本就没有登录过了。现在的回测在本地进行了,宁稳网的可转债数据上有YTM这因子数据,所以这次使用宁稳网的数据回测。也不使用什么第三方框架了,直接手写回测,模拟交易过程。
逻辑就是按照交易日期,读取所有excel数据。保存到一个dataframe里面,然后按照日期对YTM排名。 选出排名N名的进行买入,掉出N名的进行卖出。
数据源
采用宁稳的全表数据,里面有YTM因子
YTM收益率曲线
本地使用python编写回测代码,纯手工,不使用第三方框架。 平时我也多次力荐大家手写,别依赖那些第三方框架,什么vnpy,backtrade,一是特别难用,数据要适配,二是不好调试,除非你对它们的源码特别熟悉。本回测代码和宁稳数据放在个人知识星球,大部分人其实只关心回测结果就够了。
下图是2022年1月1日至11月25日的回测数据。持有10个标的,红色的是1天调仓,蓝色的是5天调仓
5天轮动,2022年的收益率为4.29%,最大回撤6.98% 。
1天轮动,2022年的收益率为9.33%,最大回撤5.32% 。
1天轮动的整体收益率要比5天轮动的高5个点,并且最大回撤也小一点。
持仓日志
从持仓以及调仓日志来看,买入的大部分是低价转债,且部分也是之前有瑕疵,爆过雷的转债。
高YTM轮动 vs 双低,低溢价,低价
接着对比一下几个常规的转债策略,双低,低溢价,低价。
回测条件相同,起始时间2022-01-01,结束时间2022-11-25。
持有10只,5天轮动。
在今年的可转债偏弱的行情下,高YTM轮动在这4个策略里面的收益率是最高的。
低溢价一如既然的高波动,一会ICU,一会蹦迪。但笔者觉得跌到前期最大回撤的位置,低溢价可以考虑介入的。
YTM和低价格的今年回测收益率接近,YTM高了一个点左右,最大回撤接近。 而低溢价还在回撤的途中,目前今年的收益率为-25%,如果轮动频率高一些,低溢价收益率会高一些,强赎的转债基本会被轮入低溢价标的,因为最近半年强赎后的转债像进入了死亡螺旋一样,正股转债一起跌;因此排除强赎转债会对低溢价收益率有不少的提升。
完整代码以及数据请开通星球查收。
收起阅读 »
Ptrade多策略如何编写?
多策略需要解决的一个最主要的问题,就是仓位管理。
系统自带的读取仓位函数需要你重写。
目前使用一个类来管理仓位:
初始化部分:
数据需要收盘后保存到文件,数据库也行;不过考虑到大部分ptrade(除了国盛,需要开通的可以联系公众号:可转债量化分析)都没有连接外网功能,所以最简单的方式就是写入文件,纯粹的文本文件。
目前笔者使用json存储
点击查看大图
这样存储有一个好处,就是如果你想中途修改策略持仓,可以直接修改这个文本文件。比如你的策略不小心买入了一只强赎的转债,你想手动卖掉,那么很简单,你只要在这个json文件里面把对应的持仓删除,再把他的市值加到可用资金里面去即可。 用法是相当灵活。
需要完整代码或者指导的朋友可以关注下面公众号和知识星球。


收起阅读 »
系统自带的读取仓位函数需要你重写。
目前使用一个类来管理仓位:
初始化部分:
class PositionManager():
def __init__(self):
if SINGLE_FACTOR not in [1, 2, 3, 4]:
raise ValueError('策略数字有误')
self.strategy = SINGLE_FACTOR
NOTEBOOK_PATH = '/home/fly/notebook/'
# self.filename = NOTEBOOK_PATH + 'S-{}.txt'.format(self.strategy)
self.filename = NOTEBOOK_PATH + personal_define_filename
self.portfolio = self.read()
log.info(self.portfolio)
self.write()
def init_data(self):
js_data = {
'cash': CASH,
'strategy': self.strategy,
'positions': ,
'portfolio_value': None,
'positions_value': None,
'capital_used': None,
'start_date': datetime.datetime.now().strftime('%Y%m%d%H%M%S'),
'current_day': 0,
}
数据需要收盘后保存到文件,数据库也行;不过考虑到大部分ptrade(除了国盛,需要开通的可以联系公众号:可转债量化分析)都没有连接外网功能,所以最简单的方式就是写入文件,纯粹的文本文件。
目前笔者使用json存储
点击查看大图
这样存储有一个好处,就是如果你想中途修改策略持仓,可以直接修改这个文本文件。比如你的策略不小心买入了一只强赎的转债,你想手动卖掉,那么很简单,你只要在这个json文件里面把对应的持仓删除,再把他的市值加到可用资金里面去即可。 用法是相当灵活。
需要完整代码或者指导的朋友可以关注下面公众号和知识星球。


收起阅读 »
Ptrade拆单 分批下单 python代码 可转债/股票
在转债市场,部分转债的流动性很差,有时候连成交100张也需要等待一段时间。
所以如果资金量大,就需要拆单操作。
交易代码部分,如果设置 SPLIT_ORDER_ENABLE = True 即进行拆单操作:
在交易部分:(省略部分不相关代码)
SELL_DIRECTION为卖,值为-1,也是一个常量,传入拆单函数中
拆单函数提取出来:
在可转债实盘中,拆单后每笔下单200张,就是每次200张下一次单,因为有可能不是马上成交,所以还需要一段等待延时,再去下单;不然你的拆单也变得没有意义,因为委托那里都是挂的你的单,并没有被消化掉。
可以看到实盘交易日志,即使拆单为200张一笔,外加一段延时,成交张数也是稀稀拉拉的,出现了不少的部分成交;也就是一次连200张都未成交完成;一笔200张的,部分成交10张,20张,都是有可能的,这也足以说明,可转债的流动性问题,滑点是很难被忽略的。
当然,这是轮动调仓的时候,金额较大的情况下拆单。如果高频交易下就不能这么操作了。
具体怎么写,可以关注个人公众号与知识星球。
知识星球原文:
如需要代写量化策略实盘代码,可以到个人公众号【可转债量化分析】后台留言。

收起阅读 »
所以如果资金量大,就需要拆单操作。
交易代码部分,如果设置 SPLIT_ORDER_ENABLE = True 即进行拆单操作:
在交易部分:(省略部分不相关代码)
if SPLIT_ORDER_ENABLE:BUY_DIRECTION 为买,值是1,一个常量
split_order(code, BUY_DIRECTION, amount)
else:
buy_price = round(buy_price, 3)
ret = order(code, amount, limit_price=buy_price)
SELL_DIRECTION为卖,值为-1,也是一个常量,传入拆单函数中
拆单函数提取出来:
def split_order(code, direction, target_count):常用的操作都类似,写成模块方便下次调用。写多了就是套模块。
'''
拆单
:param code: 股票代码
:param direction: 买:1 卖:-1
:param target_count: 总共要卖的股数
:return:
'''
count = int(target_count / EACH_ORDER_COUNT)
# 例如:560张, 200 张一单, 2次 + 最后一次160 张
remain_count = target_count % EACH_ORDER_COUNT
for i in range(count):
ret = order(code, direction * EACH_ORDER_COUNT)
time.sleep(SPLIT_ORDER_DELAY) # 拆开的单子等待一个时间,再下另外一单
if direction == 1: # 买的时候需要整数,卖则不需要
remain_count = int(remain_count / 10) * 10
if remain_count > 0:
ret = order(code, direction * remain_count)
在可转债实盘中,拆单后每笔下单200张,就是每次200张下一次单,因为有可能不是马上成交,所以还需要一段等待延时,再去下单;不然你的拆单也变得没有意义,因为委托那里都是挂的你的单,并没有被消化掉。
可以看到实盘交易日志,即使拆单为200张一笔,外加一段延时,成交张数也是稀稀拉拉的,出现了不少的部分成交;也就是一次连200张都未成交完成;一笔200张的,部分成交10张,20张,都是有可能的,这也足以说明,可转债的流动性问题,滑点是很难被忽略的。
当然,这是轮动调仓的时候,金额较大的情况下拆单。如果高频交易下就不能这么操作了。
具体怎么写,可以关注个人公众号与知识星球。
知识星球原文:
如需要代写量化策略实盘代码,可以到个人公众号【可转债量化分析】后台留言。

收起阅读 »
Ptrade里写策略坑比较多的地方(一)
总结一些,给过来人少踩些坑
1. 后缀符号不统一
这个是天煞的产品涉及的问题。 好好地代码后缀,比如 深圳市场的 有时候出现 300333.SZ , 有时候结构体里面却会是 300333.XSHE,
比如返回的orders 字典,里面用的是 00333.XSHE,而仓位的结构体 position 里面用的缺失 .sz
类似这样的问题在很多函数里面都有。
2. 部分成交 的主推函数
如果一个订单,部分成交,会先触发部分成交主推; 然后最后一个部分成交,反而会触发全部成交主推。
细想,似乎也是合理的,只是,你在全部成交里面返回的成交数量,实际只是最后一次部分成交的量。
3. 想到再写
更多更新 可以参看个人知识星球或者公众号。

收起阅读 »
1. 后缀符号不统一
这个是天煞的产品涉及的问题。 好好地代码后缀,比如 深圳市场的 有时候出现 300333.SZ , 有时候结构体里面却会是 300333.XSHE,
比如返回的orders 字典,里面用的是 00333.XSHE,而仓位的结构体 position 里面用的缺失 .sz
类似这样的问题在很多函数里面都有。
2. 部分成交 的主推函数
如果一个订单,部分成交,会先触发部分成交主推; 然后最后一个部分成交,反而会触发全部成交主推。
细想,似乎也是合理的,只是,你在全部成交里面返回的成交数量,实际只是最后一次部分成交的量。
3. 想到再写
更多更新 可以参看个人知识星球或者公众号。

收起阅读 »
ubuntu安装z.lua 路径跳转工具
z.lua 是一个快速路径切换工具,它会跟踪你在 shell 下访问过的路径,通过一套称为 Frecent 的机制(源自 FireFox),经过一段简短的学习之后,z.lua 会帮你跳转到所有匹配正则关键字的路径里 Frecent 值最高的那条路径去。
正则将按顺序进行匹配,"z foo bar" 可以匹配到 /foo/bar ,但是不能匹配 /bar/foo。
性能:
性能比 z.sh 快三倍,比 fasd / autojump 快十倍以上。
支持 Posix Shell:bash, zsh, dash, sh, ash, busybox 等等。
支持 Fish Shell,Power Shell 和 Windows cmd。
使用增强匹配算法,更准确的带你去到你想去的地方。
低占用,能够仅在当前路径改变时才更新数据库(将 $_ZL_ADD_ONCE 设成 1)。
交互选择模式,如果有多个匹配结果的话,跳转前允许你进行选择。
集成 fzf (可选),可以用来做可视化选择或者参数补全。
快速跳转到父目录,或者项目根目录,代替反复 “cd ../../.." 。
兼容 lua 5.1, 5.2 和 5.3 以上版本。
自包含且无额外依赖,单个 z.lua 文件完成所有工作。
安装步骤:
官网太蛋疼,没有写好。
下面是个人的安装步骤,在ubuntu20上测试的。
1. 安装lua
sudo apt install lua5.3
2. 下载z.lua脚本
git clone [url]https://github.com/skywind3000/z.lua.git[/url]
你也可以直接到文末下载。 关注公众号,回复 z.lua即可
下载后记录它的 目录:
比如:
/home/root/tool/z.lua
3. 然后配置bash shell
首先,确定你是哪个shell, 不同shell的初始化命令参数不一样:
bash:
在 .bashrc 文件最后加上这一行
eval "$(lua /path/to/z.lua --init bash)"
zsh:
在 .zshrc 文件最后加上这一行
eval "$(lua /path/to/z.lua --init zsh)"
Posix Shells:
在.profile 文件最后一行加入这一行
eval "$(lua /path/to/z.lua --init posix)"
4. 重启shell ,注销系统或者 source ~/.zshrc 激活新的shell
z.lua 要经过cd 进入不同的目录才会生效的。一开始如果输入 z 回车,是没有任何反应的。
查看缓存的目录
z -l
如果没有显示目录,要么你的配置出问题,要么还是你还没有用cd 切换足够多的目录 让lua 保存记录

关注公众号,回复 z.lua 获取 z.lua 安装包
收起阅读 »
Django mysql SSL 证书配置
Django的mysql配置在settings.py 里面
具体配置如下:
具体配置如下:
ca_path = '/etc/ssl/certs/ca-certificates.crt' # 证书地址收起阅读 »
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'wordpress',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1`',
'PORT': 3306,
'OPTIONS': {'ssl':{'KEY': ca_path}}
}
}
SQLAlchemy python数据库实战 【勘误与电子书pdf下载】
SQLAlchemy python数据库实战

勘误:
P64 页:
backref = backref('orders',order_by=id) 应该改为 : backref = backref('orders',order_by=order_id)
P68页:
cookie= relationship('Cookie',uselist=False,order_by=id) 应该改为 : cookie= relationship('Cookie',uselist=False,order_by=order_id)
总体来说,动物书还是不错的。
需要pdf电子书的朋友,可以关注下面公众号,

后台回复:
SQLAlchemy python数据库实战
获取电子书下载链接。
收起阅读 »

勘误:
P64 页:
backref = backref('orders',order_by=id) 应该改为 : backref = backref('orders',order_by=order_id)
P68页:
cookie= relationship('Cookie',uselist=False,order_by=id) 应该改为 : cookie= relationship('Cookie',uselist=False,order_by=order_id)
总体来说,动物书还是不错的。
需要pdf电子书的朋友,可以关注下面公众号,

后台回复:
SQLAlchemy python数据库实战
获取电子书下载链接。
收起阅读 »