通知设置 新通知
ptrade生产环境在开盘交易时间无法回测,有什么办法可以解决?
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 978 次浏览 • 2023-01-06 12:07
在正式环境下,多个券商的ptrade都无法进行回测。
但也有办法解决。 就是使用ptrade的仿真客户端。 仿真客户端并连接实盘交易。所以没有这个时间的限制。
笔者在几个券商的上的仿真客户端都可以在交易时间使用回测功能。
可能部分仿真客户端需要申请才给开通的。
查看全部
ptrade回测结束后执行某个函数,比如保存回测结果
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 634 次浏览 • 2023-01-01 17:56
官方文档只提供一个每天盘后执行的函数,没有函数可以在回测结束后,固定执行某些操作。
比如我回测过程保存的历史交易记录,收益率等,要如何保存? 虽然可以在回测的时候,每个交易日保存一次。
但是这样就需要在回测的时候按照天打开文件,盘后写入一次。 使用一个全局对象操作,显得很啰嗦。
那么有没有办法可以做在回测结束后一次性 保存操作呢?
答案是有的。也很简单。 适用于ptrade,qmt。
https://t.zsxq.com/09yigu5dy
查看全部
官方文档只提供一个每天盘后执行的函数,没有函数可以在回测结束后,固定执行某些操作。
比如我回测过程保存的历史交易记录,收益率等,要如何保存? 虽然可以在回测的时候,每个交易日保存一次。
但是这样就需要在回测的时候按照天打开文件,盘后写入一次。 使用一个全局对象操作,显得很啰嗦。
那么有没有办法可以做在回测结束后一次性 保存操作呢?
答案是有的。也很简单。 适用于ptrade,qmt。
https://t.zsxq.com/09yigu5dy

ptrade回测 获取回测当天的分时数据
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 797 次浏览 • 2023-01-01 15:45
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 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获取可转债强赎数据
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 1027 次浏览 • 2022-12-21 15:50
所以在可转债的策略里面,把强赎的转债排除掉,是一个不错的因子。
但内置的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 配置不更新新软件
Linux • 马化云 发表了文章 • 0 个评论 • 708 次浏览 • 2022-12-17 14:20
网上的禁用方法
$ 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,在计划任务里面设置时间。
查看全部
网上的禁用方法
$ 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,在计划任务里面设置时间。
pycharm 最新版2022.03 无法使用ida-eval-resetter 插件重置试用日期
python • 马化云 发表了文章 • 0 个评论 • 2040 次浏览 • 2022-12-17 14:10
0x5. 新试用机制
最新的IDE试用需要登录,我们可以任选以下方式中的一种来继续使用重置插件:
使用网络上热心大佬收集总结的key,进入IDE后使用重置插件。
登录账号试用IDE,安装设置好本插件,退出登录账号重启IDE即可。
先安装旧版本IDE,安装设置好本插件,升级IDE到最新版本即可。
不管哪种方法原理都是为了让你进入IDE,以便重置插件接管试用。
2021.3已经彻底不支持离线试用,本重置插件已失效。可以考虑暂缓升级至2021.3!
如果要使用重置日期插件,那么得要把你的pycharm降级到2021.3版本或者以下。
查看全部
ubuntu snap 下载指定版本的pycharm goland
Linux • 李魔佛 发表了文章 • 0 个评论 • 1068 次浏览 • 2022-12-17 13:24
所以只好回滚到指定的pycharm版本。
使用snap可以下载指定版本的pycharm和goland
sudo snap install pycharm-professional --channel=2021.2/stable --classic
上面的命令下载 2021.2/stable的版本的pycharm
那么怎么查看pycharm的版本?snap info pycharm-professionalname: 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
只要在里面挑一个好一点的版本就好了。
查看全部
所以只好回滚到指定的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(*) 的写法
Golang • 马化云 发表了文章 • 0 个评论 • 1006 次浏览 • 2022-12-15 22:17
使用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标准库 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操作 保存这篇文章就足够了)
Golang • 马化云 发表了文章 • 0 个评论 • 993 次浏览 • 2022-12-15 12:06
下面的是一些常见的操作,如果需要写底层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())
} 查看全部
下面的是一些常见的操作,如果需要写底层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回测
可转债 • 李魔佛 发表了文章 • 0 个评论 • 1458 次浏览 • 2022-12-04 18:43
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天轮动,今天收益率是盈利的;
如果对数据有疑问,可以到公众号后台留言~ 查看全部
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父类如何判断子类时候实现了某个方法或者属性赋值
python • 李魔佛 发表了文章 • 0 个评论 • 801 次浏览 • 2022-12-04 10:47
看看下面的例子 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
从而程序没有报错。打印正确的返回数据
查看全部
看看下面的例子
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 哪家费率最便宜,门槛最低?
券商万一免五 • 绫波丽 发表了文章 • 0 个评论 • 3383 次浏览 • 2022-11-27 19:09
笔者只会推荐合适的券商和量化接口给你,而不会推荐坑爹的券商给你。
如果你不信任,绕路即可,莫浪费大家时间。或者你有好的资源或者券商,你也可以推荐给我,可以给你发红包,奖励你提供有用的情报信息。
目前支持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】
Linux • 马化云 发表了文章 • 0 个评论 • 1230 次浏览 • 2022-11-27 18:38
只需要知道一个分享密钥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的电子书。
查看全部
只需要知道一个分享密钥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 双低 低溢价 低价策略
可转债 • 李魔佛 发表了文章 • 0 个评论 • 1001 次浏览 • 2022-11-26 16:51
自从优矿转为收费后,基本就没有登录过了。现在的回测在本地进行了,宁稳网的可转债数据上有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 • 李魔佛 发表了文章 • 0 个评论 • 1152 次浏览 • 2022-11-16 11:33
系统自带的读取仓位函数需要你重写。
目前使用一个类来管理仓位:
初始化部分: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文件里面把对应的持仓删除,再把他的市值加到可用资金里面去即可。 用法是相当灵活。
需要完整代码或者指导的朋友可以关注下面公众号和知识星球。
查看全部
系统自带的读取仓位函数需要你重写。
目前使用一个类来管理仓位:
初始化部分:
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代码 可转债/股票
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 1063 次浏览 • 2022-11-10 00:35
所以如果资金量大,就需要拆单操作。
交易代码部分,如果设置 SPLIT_ORDER_ENABLE = True 即进行拆单操作:
在交易部分:(省略部分不相关代码) if SPLIT_ORDER_ENABLE:
split_order(code, BUY_DIRECTION, amount)
else:
buy_price = round(buy_price, 3)
ret = order(code, amount, limit_price=buy_price)BUY_DIRECTION 为买,值是1,一个常量
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张,都是有可能的,这也足以说明,可转债的流动性问题,滑点是很难被忽略的。
当然,这是轮动调仓的时候,金额较大的情况下拆单。如果高频交易下就不能这么操作了。
具体怎么写,可以关注个人公众号与知识星球。
知识星球原文:
如需要代写量化策略实盘代码,可以到个人公众号【可转债量化分析】后台留言。
查看全部
所以如果资金量大,就需要拆单操作。
交易代码部分,如果设置 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张,都是有可能的,这也足以说明,可转债的流动性问题,滑点是很难被忽略的。
当然,这是轮动调仓的时候,金额较大的情况下拆单。如果高频交易下就不能这么操作了。
具体怎么写,可以关注个人公众号与知识星球。
知识星球原文:
如需要代写量化策略实盘代码,可以到个人公众号【可转债量化分析】后台留言。

akshare获取reits数据,搞笑,数据源测试过没有呀,没有集思录会员还没获取?
python爬虫 • 李魔佛 发表了文章 • 0 个评论 • 869 次浏览 • 2022-11-07 21:52
限量: 单次返回所有 REITs 的基本信息数据
估计是旧的,以前游客就可以获取到数据的了。现在就不行了。
然后另外一个获取东财的函数,获取了20个就完事了。
结果人间现在超过20家,获取的数据都不全的。
akshare,用的还是有点糟心。长期来看,还是自己写靠谱,有些坑,你第一次用就可以发现,但是有些坑,却是埋在那里,像个定时炸弹。
akshare的代码:
查看全部
Ptrade里写策略坑比较多的地方(一)
Ptrade • 李魔佛 发表了文章 • 0 个评论 • 1068 次浏览 • 2022-11-03 11:26
1. 后缀符号不统一
这个是天煞的产品涉及的问题。 好好地代码后缀,比如 深圳市场的 有时候出现 300333.SZ , 有时候结构体里面却会是 300333.XSHE,
比如返回的orders 字典,里面用的是 00333.XSHE,而仓位的结构体 position 里面用的缺失 .sz
类似这样的问题在很多函数里面都有。
2. 部分成交 的主推函数
如果一个订单,部分成交,会先触发部分成交主推; 然后最后一个部分成交,反而会触发全部成交主推。
细想,似乎也是合理的,只是,你在全部成交里面返回的成交数量,实际只是最后一次部分成交的量。
3. 想到再写
更多更新 可以参看个人知识星球或者公众号。
查看全部
1. 后缀符号不统一
这个是天煞的产品涉及的问题。 好好地代码后缀,比如 深圳市场的 有时候出现 300333.SZ , 有时候结构体里面却会是 300333.XSHE,
比如返回的orders 字典,里面用的是 00333.XSHE,而仓位的结构体 position 里面用的缺失 .sz
类似这样的问题在很多函数里面都有。
2. 部分成交 的主推函数
如果一个订单,部分成交,会先触发部分成交主推; 然后最后一个部分成交,反而会触发全部成交主推。
细想,似乎也是合理的,只是,你在全部成交里面返回的成交数量,实际只是最后一次部分成交的量。
3. 想到再写
更多更新 可以参看个人知识星球或者公众号。

DBeaver中建表 报错: Incorrect table definition; there can be ony one auto column and it must be
数据库 • 马化云 发表了文章 • 0 个评论 • 1221 次浏览 • 2022-10-26 10:00
在DBeaver中建表,建了一列主键,自增的,保存。报错。
错误原因:
Incorrect table definition; there can be only one auto column and it must be defined as a key
需要设置改为为主键。
设置地方:
在约束关系那里,选定一个主键即可!
查看全部
银河双子星能否在虚拟机和云主机运行
券商万一免五 • 李魔佛 发表了文章 • 0 个评论 • 1185 次浏览 • 2022-10-19 10:19
如果需要在服务器运行一些自动化定时脚本程序,需要券商软件支持在虚拟机运行才可以。
因为云主机都是虚拟化出来的,都属于虚拟机一类。
下载了在本地的vmware player测试了一下,发现银河双子星不能在虚拟机下运行。
点击查看大图
悲催。。只能换成同花顺的通用下单委托程序。
银河万一免五开户,门槛低。
(政策随时变,趁有免五的时候赶紧开了)
需要的联系。
查看全部
macbook m1版本 兼容性问题
Linux • 马化云 发表了文章 • 0 个评论 • 885 次浏览 • 2022-10-18 11:36
比如你有个软件依赖旧版本的postgresql,那么就没有办法在m1上搞个旧版本的postgresql了,不过新版的postgresql是支持的。
这种向前兼容性很差的问题,如果对于项目,日常高频使用软件里有旧版应用,应该会挺难受,只能早一些替代方案。
查看全部
ubuntu安装z.lua 路径跳转工具
Linux • 马化云 发表了文章 • 0 个评论 • 1101 次浏览 • 2022-10-15 17:06
正则将按顺序进行匹配,"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 安装包
查看全部
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 证书配置
数据库 • 马化云 发表了文章 • 0 个评论 • 1044 次浏览 • 2022-10-13 15:35
具体配置如下:
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}}
}
} 查看全部
具体配置如下:
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}}
}
}
银河证券万一免五 低门槛开户
券商万一免五 • 绫波丽 发表了文章 • 0 个评论 • 2036 次浏览 • 2022-10-11 15:10
银河证券 全国营业部数量最多;目前有国庆活动,可以低费率万一免五开户,名额不多,时间有限。
需要的朋友就赶紧来开一波了。 错过这一轮要等很久的了。
具体费率 股票万一免五
基金etf lof 万0.6
可转债费率十万分之五
基金转债也是免五的。
银河证券app 的自带条件单也越来越丰富,目前是除了华宝智投外 第二好用的条件单证券,也有网格自动下单。
如果需要量化,可以开通GMatrix,电脑端的量化操作软件,更加丰富的条件单设置。
Gmatrix设置界面,条件单
需要可以加微信咨询开户:
钓鱼的非城勿扰 查看全部
SQLAlchemy python数据库实战 【勘误与电子书pdf下载】
书籍 • 马化云 发表了文章 • 0 个评论 • 800 次浏览 • 2022-10-10 23:56
勘误:
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数据库实战
获取电子书下载链接。
SQLAlchemy mysql ssl证书 连接
数据库 • 马化云 发表了文章 • 0 个评论 • 866 次浏览 • 2022-10-09 20:50
需要加上参数:
connect_args,加上ssl路径。
from sqlalchemy import create_engine
ca_path = '/etc/ssl/certs/ca-certificates.crt' # linux 证书路径
ssl_args = {'ssl_ca': ca_path}
engine = create_engine('mysql+pymysql://root:password@127.0.01:3306/wordpressdb?charset=utf8',
echo = True,
connect_args=ssl_args
) 查看全部
需要加上参数:
connect_args,加上ssl路径。
from sqlalchemy import create_engine
ca_path = '/etc/ssl/certs/ca-certificates.crt' # linux 证书路径
ssl_args = {'ssl_ca': ca_path}
engine = create_engine('mysql+pymysql://root:password@127.0.01:3306/wordpressdb?charset=utf8',
echo = True,
connect_args=ssl_args
)
python社工库合集
网络安全 • 马化云 发表了文章 • 0 个评论 • 1356 次浏览 • 2022-10-08 17:30
这个项目太吓人了,输入 id,就能把互联网上你的相关账号全部扒出来,而且不仅仅是简单的 id 匹配,你的用户资料字段也会被匹配,而且连 pornhub/xvideo 账号都有。
使用方法(python):
# install from pypi
pip3 install maigret
# usage
maigret username
个人亲测了一下,这个库主要针对国内外一些大型的网站进行扫描,得到的结果还是很准的。
如果有专门针对国内网站的库,欢迎留言回复~
查看全部
https://github.com/soxoj/maigret
这个项目太吓人了,输入 id,就能把互联网上你的相关账号全部扒出来,而且不仅仅是简单的 id 匹配,你的用户资料字段也会被匹配,而且连 pornhub/xvideo 账号都有。
使用方法(python):
# install from pypi
pip3 install maigret
# usage
maigret username
个人亲测了一下,这个库主要针对国内外一些大型的网站进行扫描,得到的结果还是很准的。
如果有专门针对国内网站的库,欢迎留言回复~
influxdb什么都没有做,数据目录占用很大磁盘空间
数据库 • 李魔佛 发表了文章 • 0 个评论 • 1571 次浏览 • 2022-10-08 10:11
后面就没有怎么导入数据。
结果最近硬盘一直警报,说空间不够了。
经过一番排查,发现是influxdb的数据目录很大,有接近100GB。
默认目录在这里:
/var/lib/influxdb/engine/data
停止服务:
sudo systemctl restart influxdb
不过这样下次系统重启,influxdb还是会自动重启。还需要把服务给禁用掉。
update-rc.d influxdb remove
如果没有报错,就成功了。
查看全部
后面就没有怎么导入数据。
结果最近硬盘一直警报,说空间不够了。
经过一番排查,发现是influxdb的数据目录很大,有接近100GB。
默认目录在这里:
/var/lib/influxdb/engine/data
停止服务:
sudo systemctl restart influxdb
不过这样下次系统重启,influxdb还是会自动重启。还需要把服务给禁用掉。
update-rc.d influxdb remove
如果没有报错,就成功了。
把抖音的小姐姐舞蹈视频的背景音乐静音了,瞬间觉得她们好傻
闲聊 • 马化云 发表了文章 • 0 个评论 • 872 次浏览 • 2022-10-06 17:23
PS: 找到了一个视频接口,猜测是哪个爬虫项目的。可以不断的获取新的抖音小姐姐视频。后面因为硬盘空间不够就停掉了。