百度搜索居然支持搜索微信公众号了?!
今天搜索了一些内容,发现公众的内容居然显示在百度搜索结果的第一位,有点神奇。估计两个大厂签订了某些合作协议,流量互通了。 其实早就应该开放了,现在很多优质内容都往公众号流入。 但是这些优质内容只有少部分人浏览。 牛人不会有很多时间看别人群,看别人朋友圈,所以他们接触公众号的内容比较少。
这导致微信公众号里面沉淀的内容 在闭环里面得不得很好利用。 比如一些写程序代码的公众号,一般人都是看到好的,收藏起来,然后在PC浏览器上看。 手机屏幕看代码, 体验十分不好的。
同样,百度也多了一个数据源,不至于被csdn和一些内容农场长期霸占首页的搜索结果。
最受影响的应该是搜狗搜索引擎。不过这个搜索引擎也是及其垃圾,以前用来搜索微信公众号内容,只能完全匹配字样,同义词,近义词的搜索效果很差,出来的内容也不知道按照什么排序,往往得不到自己想要的内容。
收起阅读 »
程序员是怎样删除安卓手机的垃圾文件?
有一台vivo的手机,用了也就1-2年,64GB的内部存储已经所剩无几了,并且每次清理垃圾文件,并无法清理一些系统产生的垃圾文件。
以至于手机的的可用空间越来越少,内置的清理垃圾的功能越来越鸡肋。而第三方的垃圾清理应用只会引来更多的垃圾文件。
身为一名程序员,就得用geek一点的方法彻底删除垃圾文件,尽可能地释放系统的空间。
由于平时使用的开发环境是Linux,所以下面环境是在Linux下操作,windows的用户应该也可以在git bash下操作。
手机usb 连接电脑
使用usb线连接linux电脑,不一定要adb的功能,但需要电脑能够识别手机的内部存储即可。
然后点击“内部存储设备”, 在文件内右键,进入Terminal 终端。
执行命令
简单解释一下这个语句。 就是显示当前目录下,第一层目录的占用存储大小情况。-h, human效果,人性化,自动转换文件大小单位。
--max-depth 是显示目录层级数目,如果选择2-3-4等目录,则会把子目录,子子目录的存储大小都显示出来,不过运行数据也会随之变慢。
上面命令一下子就把手机根目录下所有的目录的占用大小都列出来了。可以看到上面红框的地方,是一些缓存没用的东西,我们直接用命令 rm -rf 删除。
或者也可以在文件管理器里面直接删除。
如果有些目录底下有多层目录,那么就是把--max-depth 的值调大一些。 这样就知道他子目录的占用空间情况。
如果只想看看微信文件夹下的空间占用,可以指定目录:
这样就知道哪个目录占用的空间最大,然后点击进去,把没用的目录逐个删除。
经过笔者的测试,使用上述操作后,手机可用存储空间释放了40%的空间。主要是一些app下载的内容,由于app被清理了,结果这些下载内容成了孤立的文件,没有索引到对应的app,一直残留在手机内存。
收起阅读 »
以至于手机的的可用空间越来越少,内置的清理垃圾的功能越来越鸡肋。而第三方的垃圾清理应用只会引来更多的垃圾文件。
身为一名程序员,就得用geek一点的方法彻底删除垃圾文件,尽可能地释放系统的空间。
由于平时使用的开发环境是Linux,所以下面环境是在Linux下操作,windows的用户应该也可以在git bash下操作。
手机usb 连接电脑
使用usb线连接linux电脑,不一定要adb的功能,但需要电脑能够识别手机的内部存储即可。
然后点击“内部存储设备”, 在文件内右键,进入Terminal 终端。
执行命令
du . -h --max-depth=1
简单解释一下这个语句。 就是显示当前目录下,第一层目录的占用存储大小情况。-h, human效果,人性化,自动转换文件大小单位。
--max-depth 是显示目录层级数目,如果选择2-3-4等目录,则会把子目录,子子目录的存储大小都显示出来,不过运行数据也会随之变慢。
上面命令一下子就把手机根目录下所有的目录的占用大小都列出来了。可以看到上面红框的地方,是一些缓存没用的东西,我们直接用命令 rm -rf 删除。
或者也可以在文件管理器里面直接删除。
如果有些目录底下有多层目录,那么就是把--max-depth 的值调大一些。 这样就知道他子目录的占用空间情况。
如果只想看看微信文件夹下的空间占用,可以指定目录:
du /Weixin/ -h --max-depth=3
这样就知道哪个目录占用的空间最大,然后点击进去,把没用的目录逐个删除。
经过笔者的测试,使用上述操作后,手机可用存储空间释放了40%的空间。主要是一些app下载的内容,由于app被清理了,结果这些下载内容成了孤立的文件,没有索引到对应的app,一直残留在手机内存。
收起阅读 »
ubuntu/linux 64位 安装 kdb+ (需要证书授权)附下载地址
kdb+是一款高速小巧的时序数据库。32位的版本个人可以随意使用。
64位的版本需要申请授权证书。
申请后得到邮件,里面会有证书。
还有64位软件下载地址。文件还是小巧,几百k。没想到一个排名第二的时序数据库,体积居然不到1M。
需要kdb+ 64位安装文件,可以到文末获取。
下载下来解压。
比如解压到目录:
~/tool/l64/
目录下有一个文件夹 l64和一个q.k的文件
l64子文件夹下只有一个文件q , 他是一个可执行文件。在linux下的命令行可以直接运行 ./q
然后把证书文件拷贝到目录 ~/tool/l64/
这时如果直接运行 ./q 但是会报错.
这是因为没有设置环境变量。
windows下也需要设置环境部,linux同理也需要。
linux:
export QHOME="/home/root/tool/l64/"
或者放到bashrc文件里面。
正常运行,会显示 q)
kdb+ 64位安装文件获取方式:
关注后 回复 kdb+
收起阅读 »
64位的版本需要申请授权证书。
申请后得到邮件,里面会有证书。
还有64位软件下载地址。文件还是小巧,几百k。没想到一个排名第二的时序数据库,体积居然不到1M。
需要kdb+ 64位安装文件,可以到文末获取。
下载下来解压。
比如解压到目录:
~/tool/l64/
目录下有一个文件夹 l64和一个q.k的文件
l64子文件夹下只有一个文件q , 他是一个可执行文件。在linux下的命令行可以直接运行 ./q
$ ./q提示缺失证书。
KDB+ 4.0 2022.05.11 Copyright (C) 1993-2022 Kx Systems
l64/ 4()core 23934MB xda xda-linux 127.0.1.1
'licence error: k4.lic
然后把证书文件拷贝到目录 ~/tool/l64/
这时如果直接运行 ./q 但是会报错.
$ ./q -p 5001
KDB+ 4.0 2022.05.11 Copyright (C) 1993-2022 Kx Systems
l64/ 4(24)core 23934MB xda xda-linux 127.0.1.1 EXPIRE 2023.07.18 xxxxx@126.com KXCE #
'2022.09.04T11:34:18.272 couldn't connect to license daemon -- exiting
这是因为没有设置环境变量。
windows下也需要设置环境部,linux同理也需要。
linux:
export QHOME="/home/root/tool/l64/"
或者放到bashrc文件里面。
正常运行,会显示 q)
kdb+ 64位安装文件获取方式:
关注后 回复 kdb+
收起阅读 »
从零开始 手撸一个回测框架 (以可转债双低,低溢价为例)
因为优矿大部分可转债接口开始收费了,之前星球上分享的回测代码基本也跑不了。不过在关停转收费之前,已经把所需的数据下载下来,而最近的数据通过集思录补充既可。
Mysql 数据
下面是代码主框架,目前通过之前优矿的导出的csv数据 ,计算 各个因子。 通过不同权重评分,进行轮动。
双低和低溢价选债轮动:
上面是主要框架代码, 根据数据来驱动交易。 可以根据不同的时间日期进行回测交易。不同持有个数,不同轮动功能天数。【完整代码可以常见 知识星球】
运行: python main.py
运行后会自动保存一个excel文件:
并且可以生成收益率曲线图:
完整代码与数据可以参考星球代码:
收起阅读 »
Mysql 数据
下面是代码主框架,目前通过之前优矿的导出的csv数据 ,计算 各个因子。 通过不同权重评分,进行轮动。
class DataFeed:
def __init__(self):
self.csv_path = CSV_PATH
self.position = {}
self.HighValue = 0
self.Start_Cash = 1000000 # 初始资金
self.MyCash = self.Start_Cash
self.Withdraw = 0
self.daily_netvalue =
self.current_day = 0
self.PosValue = 0
self.threshold = 0 # 阈值
self.HighValue = self.Start_Cash
self.date_list, self.source = self.feed()
self.day_count = 0
def unpossibile(self, df, date):
# 剔除当日涨停的转债,买不入
raise_limited_dict = {
'2022-04-08': ['127057', ],
'2022-07-27': ['127065', ],
'2022-07-28': ['127065', ],
}
target_list = raise_limited_dict.get(date, None)
if target_list is None:
return df
return df.drop(index=target_list, axis=1)
def feed(self):
df = pd.read_csv(self.csv_path,
encoding='utf8',
dtype={'tickerEqu': str, 'tickerBond': str, 'secID_x': str},
)
del df['Unnamed: 0']
df['tradeDate'] = pd.to_datetime(df['tradeDate'], format='%Y-%m-%d')
df = df.set_index('tradeDate')
date_set = set(df.index.tolist())
date_list = list(map(lambda x: x.strftime('%Y-%m-%d'), date_set))
date_list.sort()
return date_list, df
def filters(self, df, today):
# 过滤条件,可添加多个条件
df = self.unpossibile(df, today)
return df
def logprint(self, current):
log.info('当前日期{}'.format(current))
def run(self):
for current in self.date_list:
if current < START_DATE or current > END_DATE:
continue
if self.day_count % FREQ != 0:
self.get_daily_netvalue(current)
else:
self.handle_data(current)
self.day_count += 1
self.after_trade()
双低和低溢价选债轮动:
上面是主要框架代码, 根据数据来驱动交易。 可以根据不同的时间日期进行回测交易。不同持有个数,不同轮动功能天数。【完整代码可以常见 知识星球】
运行: python main.py
运行后会自动保存一个excel文件:
并且可以生成收益率曲线图:
完整代码与数据可以参考星球代码:
收起阅读 »
python获取通达信可转债日线和分时数据
昨天看到优矿平台公告,开始对大部分数据获取接口进行收费。
除了优矿,还有哪些可以获取可转债日线,甚至分时tick数据呢?当然笔者压箱底里面还有很多可用数据源的。本文就简单介绍其中一个,下通达信数据源。
安装
使用pip安装第三方库pytdx
分时数据
下面6行python代码, 就可以获取通达信的可转债分时数据。
如果需要遍历当前最新可转债代码,需要结合前面的文章。【注意这代码会定期更新,因网站架构或者字段是不定时变动】
不过前面的接口只能读取800条数据,以一天240条数据计算,只能读取2天多的数据量,对于需要更多数据的朋友来说,肯定不够的。或者有一个办法,把上面代码写成定时任务,就可以每天收盘后自动存储对应的数据。
如果需要更多的历史数据,那么可以使用pytdx的另外一个功能,那就是使用python读取通达信本地数据文件。
先用通达信同步1分钟(或5分钟)数据到本地.
选择沪深京分钟线,当然,其他数据你也可以选择。勾选一分钟线数据或者5分钟线数据,还有日期。不过这里日期会有限制,只能下载100天的1分钟线,或者500天的5分钟线。所以如果长期需要这个数据,你可以每隔一段时间下载一次。
数据保存路径:通达信安装目录的 vipdoc 子目录
如果你需要更久的历史数据,可以到网上找找,下载下来后按照下面代码读取即可。
得到dataframe对象后,接着可以保存为excel,数据库都很简单了。一条语句的事情。
可转债日线数据
当然,能够获取到分钟数据,对于日线数据更加不在话下了。日线数据并没有日期限制,想下多少有多少。
如果想获取正股或者其他股票数据,只需要把代码替换成正股股票代码即可。
如果分钟数据还不满足,还可以使用更小粒度的tick数据。下回有空再继续介绍,敬请关注。
欢迎关注公众号 收起阅读 »
除了优矿,还有哪些可以获取可转债日线,甚至分时tick数据呢?当然笔者压箱底里面还有很多可用数据源的。本文就简单介绍其中一个,下通达信数据源。
安装
使用pip安装第三方库pytdx
pip install pytdx
分时数据
下面6行python代码, 就可以获取通达信的可转债分时数据。
from pytdx.hq import TdxHq_API
api = TdxHq_API()
with api.connect('119.147.212.81', 7709):
data = api.get_security_bars(7, 0, '123045', 0, 240) # 123045 为转债代码 ,240 为获取 240个转债数据
df = api.to_df(data)
df=df.sort_values('datetime')
如果需要遍历当前最新可转债代码,需要结合前面的文章。【注意这代码会定期更新,因网站架构或者字段是不定时变动】
不过前面的接口只能读取800条数据,以一天240条数据计算,只能读取2天多的数据量,对于需要更多数据的朋友来说,肯定不够的。或者有一个办法,把上面代码写成定时任务,就可以每天收盘后自动存储对应的数据。
如果需要更多的历史数据,那么可以使用pytdx的另外一个功能,那就是使用python读取通达信本地数据文件。
先用通达信同步1分钟(或5分钟)数据到本地.
选择沪深京分钟线,当然,其他数据你也可以选择。勾选一分钟线数据或者5分钟线数据,还有日期。不过这里日期会有限制,只能下载100天的1分钟线,或者500天的5分钟线。所以如果长期需要这个数据,你可以每隔一段时间下载一次。
数据保存路径:通达信安装目录的 vipdoc 子目录
比如我的通达信客户端安装在 c:\new_tdx 下,
即
c:\new_tdx\vipdoc\sz\lday\ 下是深圳的日k线数据
c:\new_tdx\vipdoc\sh\lday\ 下是上海的日k线数据
c:\new_tdx\vipdoc\sh\minline\ 下是上海的分钟线数据
c:\new_tdx\vipdoc\sz\minline\ 下是深圳的分钟线数据
如果你需要更久的历史数据,可以到网上找找,下载下来后按照下面代码读取即可。
from pytdx.reader import TdxMinBarReader
path='/home/xda/Downloads/sz128014.lc1'
reader = TdxMinBarReader()
df = reader.get_df(path)
#df.to_excel('tick.xlsx') # 导出为excel
得到dataframe对象后,接着可以保存为excel,数据库都很简单了。一条语句的事情。
可转债日线数据
当然,能够获取到分钟数据,对于日线数据更加不在话下了。日线数据并没有日期限制,想下多少有多少。
api = TdxHq_API()
api = api.connect('119.147.212.81', 7709)
data=api.get_k_data('123045', '2020-05-01', '2022-08-26') # 123045 为可转债代码,可以替换任意代码
data.to_excel('k-line.xlsx')
如果想获取正股或者其他股票数据,只需要把代码替换成正股股票代码即可。
如果分钟数据还不满足,还可以使用更小粒度的tick数据。下回有空再继续介绍,敬请关注。
欢迎关注公众号 收起阅读 »
6行python代码 获取通达信的可转债分时数据
6行python代码 获取通达信的可转债分时数据。
如果需要遍历当前最新可转债代码(集思录),需要结合前面的文章。
公众号:
收起阅读 »
from pytdx.hq import TdxHq_API点击查看大图
api = TdxHq_API()
with api.connect('119.147.212.81', 7709):
data = api.get_security_bars(7, 0, '123045', 0, 240) # 123045 为转债代码 ,240 为获取 240个转债数据
df = api.to_df(data)
df=df.sort_values('datetime')
如果需要遍历当前最新可转债代码(集思录),需要结合前面的文章。
公众号:
收起阅读 »
Ptrade 逆回购+自动申购新股可转债
分享一些最基本的ptrade代码实盘例子。 持续更新,喜欢的朋友请关注本站哦。
本站所有代码均经过实盘验证。
上面代码设定在13:30分申购新股,新债;
在14:57分申购深圳逆回购R-001
喜欢的朋友拿去,欢迎转载。
欢迎关注公众号
收起阅读 »
本站所有代码均经过实盘验证。
# ptrade软件-量化-回测 里,新建策略,复制全文粘贴进去,周期选分钟,再到交易里新增交易
import time
def reverse_repurchase(context):
cash = context.portfolio.cash
amount = int(cash/1000)*10
log.info(amount)
order('131810.SZ', -1*amount) # 深圳逆回购,
def ipo(context):
ipo_stocks_order()
def initialize(context):
g.flag = False
log.info("initialize g.flag=" + str(g.flag) )
run_daily(context, reverse_repurchase, '14:57')
run_daily(context, ipo, '13:30')
def before_trading_start(context, data):
pass
def handle_data(context, data):
pass
def on_order_response(context, order_list):
# 该函数会在委托回报返回时响应
log.info(order_list)
上面代码设定在13:30分申购新股,新债;
在14:57分申购深圳逆回购R-001
喜欢的朋友拿去,欢迎转载。
欢迎关注公众号
收起阅读 »
Ptrade 获取当天可转债代码列表
注意Ptrade版本:2022版,旧版应该不行的。
可以在开盘的时候获取所有可转债列表。
如果需要获取可转债溢价率,评级,剩余规模,强赎等数据,可以调用我之前提供的接口。
需要的可以关注个人星球和公众号。
欢迎关注公众号
收起阅读 »
可以在开盘的时候获取所有可转债列表。
def initialize(context):
run_daily(context, get_trade_cb_list, "9:25")
def before_trading_start(context, data):
# 每日清空,避免取到昨日市场代码表
g.trade_cb_list =
def handle_data(context, data):
pass
# 获取当天可交易的可转债代码列表
def get_trade_cb_list(context):
cb_list = get_cb_list()
cb_snapshot = get_snapshot(cb_list)
# 代码有行情快照并且交易状态不在暂停交易、停盘、长期停盘、退市状态的判定为可交易代码
g.trade_cb_list = [cb_code for cb_code in cb_list if
cb_snapshot.get(cb_code, {}).get("trade_status") not in
[None, "HALT", "SUSP", "STOPT", "DELISTED"]]
log.info("当天可交易的可转债代码列表为:%s" % g.trade_cb_list)
如果需要获取可转债溢价率,评级,剩余规模,强赎等数据,可以调用我之前提供的接口。
需要的可以关注个人星球和公众号。
欢迎关注公众号
收起阅读 »
Ptrade里面的 持久化 (pickle)要求 报错:
关于持久化
为什么要做持久化处理
服务器异常、策略优化等诸多场景,都会使得正在进行的模拟盘和实盘策略存在中断后再重启的需求,但是一旦交易中止后,策略中存储在内存中的全局变量就清空了,因此通过持久化处理为量化交易保驾护航必不可少。
量化框架持久化处理
使用pickle模块保存股票池、账户信息、订单信息、全局变量g定义的变量等内容。
注意事项:
框架会在before_trading_start(隔日开始)、handle_data、after_trading_end事件后触发持久化信息更新及保存操作;
券商升级/环境重启后恢复交易时,框架会先执行策略initialize函数再执行持久化信息恢复操作。
如果持久化信息保存有策略定义的全局对象g中的变量,将会以持久化信息中的变量覆盖掉initialize函数中初始化的该变量。
1 全局变量g中不能被序列化的变量将不会被保存。
您可在initialize中初始化该变量时名字以'__'开头;
2 涉及到IO(打开的文件,实例化的类对象等)的对象是不能被序列化的;
3 全局变量g中以'__'开头的变量为私有变量,持久化时将不会被保存;
示例代码:
其实官方文档说了这么多,实际意思就是 类和涉及IO的 变量 不能序列化,导致不能在g中作为全局变量,如果要作为全局变量,需要 用2个前下划线__ 命名,比如 g.__db = Bond()
class Bond:
pass
不然就会报错:
欢迎关注公众号 收起阅读 »
为什么要做持久化处理
服务器异常、策略优化等诸多场景,都会使得正在进行的模拟盘和实盘策略存在中断后再重启的需求,但是一旦交易中止后,策略中存储在内存中的全局变量就清空了,因此通过持久化处理为量化交易保驾护航必不可少。
量化框架持久化处理
使用pickle模块保存股票池、账户信息、订单信息、全局变量g定义的变量等内容。
注意事项:
框架会在before_trading_start(隔日开始)、handle_data、after_trading_end事件后触发持久化信息更新及保存操作;
券商升级/环境重启后恢复交易时,框架会先执行策略initialize函数再执行持久化信息恢复操作。
如果持久化信息保存有策略定义的全局对象g中的变量,将会以持久化信息中的变量覆盖掉initialize函数中初始化的该变量。
1 全局变量g中不能被序列化的变量将不会被保存。
您可在initialize中初始化该变量时名字以'__'开头;
2 涉及到IO(打开的文件,实例化的类对象等)的对象是不能被序列化的;
3 全局变量g中以'__'开头的变量为私有变量,持久化时将不会被保存;
示例代码:
class Test(object):
count = 5
def print_info(self):
self.count += 1
log.info("a" * self.count)
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
# 初始化无法被序列化类对象,并赋值为私有变量,落地持久化信息时跳过保存该变量
g.__test_class = Test()
def handle_data(context, data):
# 调用私有变量中定义的方法
g.__test_class.print_info()
其实官方文档说了这么多,实际意思就是 类和涉及IO的 变量 不能序列化,导致不能在g中作为全局变量,如果要作为全局变量,需要 用2个前下划线__ 命名,比如 g.__db = Bond()
class Bond:
pass
不然就会报错:
_pickle.PickingError: Can't pick <class 'IOEngine.user_module : attribute loopup
欢迎关注公众号 收起阅读 »
虚拟机 云服务器 运行qmt 方案
点击查看大图
众所周知,部分券商(国盛证券)限制了虚拟机登录QMT。
比如在vmare中安装了QMT,可以在QMT的信息里面看到:
点击查看大图
比如上面的截图, 如果和实体机的设备信息做一个对比,可以看到,虚拟机下的QMT的硬盘序列号(红框的位置) 是空的,而实体物理机下,红框的硬盘序列号 是有内容的。 所以一个办法是尝试修改这个硬盘序列号。
或者换一个支持虚拟机的券商。其实这个限制是券商端定制的功能,部分券商并没有限制虚拟机禁止登陆QMT的。
比如国金证券的QMT,可以在虚拟机或者云服务器上登录。费率也可以万一免五,参考文章:
http://www.30daydo.com/article/44479 收起阅读 »
通过mini qmt xtdata获取tick数据 python代码
def get_tick(code, start_time, end_time, period='tick'):
from xtquant import xtdata
xtdata.download_history_data(code, period=period, start_time=start_time, end_time=end_time)
data = xtdata.get_local_data(field_list=, stock_code=
, period=period, count=10)
result_list = data
df = pd.DataFrame(result_list)
df['time_str'] = df['time'].apply(lambda x: datetime.datetime.fromtimestamp(x / 1000.0))
return df
上面python代码传入一个代码,和初试时间,需要的周期数据(分钟,秒,日等),就可以返回一个dataframe格式的数据了。
欢迎关注公众号 收起阅读 »
Ptrade下单接口 order,order_target, order_value,order_target_value的区别
order_target 接口通过持仓数量比较将入参的目标数量转换成需要交易的成交,传入 order
接口
order_value 接口通过 金额/限价 或者 金额/默认最新价 两种方式转换成需要交易的数量,
传入 order 接口
order_target_value 接口通过持仓金额比较得到需要交易的金额, 金额/限价 或者 金额/默
认最新价 两种方式转换成需要交易的数量,传入 order 接口
所以其他几个接口都是对order的封装。
order接口的逻辑:
order 接口:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则最新价代替,都是
限价方式报单。
二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就放到未处理订单
队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台
欢迎关注公众号 收起阅读 »
去除导流公众号的网站 油猴脚本
先安装油猴工具。然后导入下面的油猴脚本
去除博客导流公众号
绕过openwrite公众号导流
去除博客导流公众号
// ==UserScript==
// @name 去除博客导流公众号
// @namespace http://tampermonkey.net/
// @version 1.0.0
// @description 去除openwrite“博客导流公众号”功能
// @author You
// @include http*://*
// @grant none
// ==/UserScript==
(function() {
'use strict';
destroyBTWPlugin();
function destroyBTWPlugin() {
// 判断是否有插件
const hasBTWPlugin = typeof BTWPlugin == "function"
if (hasBTWPlugin) {
// 获取属性
const plugin = new BTWPlugin().options;
if (plugin) {
// 删除元素
const read_more_wrap = document.getElementById("read-more-wrap")
if (read_more_wrap) {
read_more_wrap.remove();
}
// 删除样式
const ctner = document.getElementById(plugin.id)
if (ctner) {
ctner.removeAttribute("style");
}
}
}
}
})();
绕过openwrite公众号导流
// ==UserScript==收起阅读 »
// @name 绕过openwrite公众号导流
// @namespace http://tampermonkey.net/
// @version 1.6
// @description 去除openwrite“博客导流公众号”功能
// @author GoodbyeNJN
// @license GPLv3
// @match *://*/*
// @grant none
// ==/UserScript==
/**
* openwrite 脚本基本逻辑:
* 函数名和属性名储存在一个数组中(搜索“阅读全文”可定位到),取值时通过对应的索引取出对应的值。
* 先构造一个对象(搜索“const .* = function”可定位到),在下方不远处给它的 prototype 上添加 options 和 init。
* 点击弹窗中的“提交”按钮时,触发回调(搜索“alert”可定位到),解析后具体代码如下:
* function () {
* const val = $("#btw-modal-input").val();
* if (val === "") {
* alert("请输入校验码!");
* $("#btw-modal-input").focus();
* return;
* }
* const { blogId } = btw.options
* const api = "https://my.openwrite.cn/code/check";
* const url = "" + api + "?blogId=" + blogId + "&code=" + val + "";
* $.get(url, function (res) {
* if (res.result === true) {
* localStorage.setItem("TOKEN_" + blogId + "", blogId);
* $("#btw-modal-wrap, #read-more-wrap").remove();
* $("#" + btw.options.id + "").height("");
* } else {
* alert("校验码有误!");
* }
* });
* }
*/
"use strict";
const READ_MORE_ID = "read-more-wrap";
/**
* 判断是否存在插件
*/
const hasBtwPlugin = () => {
const hasBTWPlugin = typeof BTWPlugin === "function";
const hasJquery = typeof $ === "function";
return hasBTWPlugin && hasJquery;
};
/**
* 判断是否存在“阅读全文”按钮
*/
const hasReadMoreBtn = () => {
return !!document.getElementById(READ_MORE_ID);
};
/**
* 获取插件初始化选项
*/
const getOptions = () => {
return (
BTWPlugin.prototype.options || {
id: "container",
blogId: "",
name: "",
qrcode: "",
keyword: "",
}
);
};
/**
* 监听“阅读全文”按钮的出现
* 用于首次触发该脚本且无按钮时,监听后续的按钮出现事件
*/
const listenReadMoreBtnShow = fn => {
const observer = new MutationObserver(mutations =>
mutations.forEach(mutation =>
mutation.addedNodes.forEach(node => {
if (node.id === READ_MORE_ID) {
observer.disconnect();
fn();
}
}),
),
);
const { id } = getOptions();
const parent = document.getElementById(id);
parent && observer.observe(parent, { childList: true });
};
/**
* 监听部分 history 改动事件
* 用于 spa 页面路由变化时自动展示全文
*/
const listenHistoryChange = fn => {
const wrap = type => {
const fn = history[type];
return function (...args) {
const res = fn.apply(this, args);
const e = new Event(type);
e.arguments = args;
window.dispatchEvent(e);
return res;
};
};
history.pushState = wrap("pushState");
history.replaceState = wrap("replaceState");
window.addEventListener("replaceState", fn);
window.addEventListener("pushState", fn);
window.addEventListener("hashchange", fn);
};
/**
* 展示全文
*/
const showHiddenText = () => {
const { id, blogId } = getOptions();
console.log("id:", id);
localStorage.setItem(`TOKEN_${blogId}`, blogId);
$(`#${READ_MORE_ID}`).remove();
$(`#${id}`).height("");
};
(function () {
if (!hasBtwPlugin()) {
return;
}
$().ready(() => {
listenHistoryChange(showHiddenText);
if (hasReadMoreBtn()) {
showHiddenText();
} else {
listenReadMoreBtnShow(showHiddenText);
}
});
})();
可转债多因子回测 优矿代码
可转债里面可用因子很多,一般人最常用的就是溢价率,双低,价格等。
实际运用里面,可以加入很多很多因子,比如正股涨跌幅,正股波动率,转债到期时间,正股ROE等等多大几十个因子。
之前写了一个多因子回测的优矿python代码,用户可以自己修改参数,
比如下面的正股波动率因子,
Bond_Volatility_ENABLE = True 设为True,就是回测过程加入这个因子,设为False就忽略这个因子。
下面的
Bond_Volatility_DAYS 为N天内的正股波动率,一般设置30天,20天内就够了,因为一年之前的即使波动很大,那对当前转债的影响也很小。
TOP_RIPPLE 选择波动率最大的前面N只转债
举个例子,下面转债是根据其对应正股的30天里的波动率选出来的。(当前是8月5日,也就是7月5日到8月5日之间的数据)。
计算波动率具体代码如下;
每个因子写成一个类。
这样可以不用修改主代码,就可以无限地添加,修改因子。
上面是部分过滤因子,也就是不满足的都会被移除。 比如规模大于10亿的会移除。
然后得到的结果,进行因子评分。
每个权重赋予一个权重分最高是1,最低是0,如果你想回测 低溢价率 策略,只需要把其他因子的权重全部设置为0,溢价率设置为1即可。双底的话就是 溢价率和价格各为0.5 就可以了。
设置好参数后,设置你要回测的时间,持仓周期,持有个数等可调参数。
稍等片刻就会有结果了。因子越多,运行时间会增加。一般几分钟就可以得到几年来的回测结果。
中途可以查看日志
完整代码以及运行流程可到知识星球咨询了解。
欢迎关注公众号 收起阅读 »
实际运用里面,可以加入很多很多因子,比如正股涨跌幅,正股波动率,转债到期时间,正股ROE等等多大几十个因子。
之前写了一个多因子回测的优矿python代码,用户可以自己修改参数,
比如下面的正股波动率因子,
Bond_Volatility_ENABLE = True
Bond_Volatility_DAYS = 30
TOP_RIPPLE = 50
Bond_Volatility_LOG_ENABLE = True # 波动率日志开关
Bond_Volatility_ENABLE = True 设为True,就是回测过程加入这个因子,设为False就忽略这个因子。
下面的
Bond_Volatility_DAYS 为N天内的正股波动率,一般设置30天,20天内就够了,因为一年之前的即使波动很大,那对当前转债的影响也很小。
TOP_RIPPLE 选择波动率最大的前面N只转债
举个例子,下面转债是根据其对应正股的30天里的波动率选出来的。(当前是8月5日,也就是7月5日到8月5日之间的数据)。
计算波动率具体代码如下;
每个因子写成一个类。
这样可以不用修改主代码,就可以无限地添加,修改因子。
# 基类
class ConditionFilter:
def filters(self, *args, **kwargs):
if self.enable:
return self.fun(*args, **kwargs)
else:
return True
def fun(self, *args, **kwargs):
# 继承的实现这个函数
raise NotImplemented
上面是部分过滤因子,也就是不满足的都会被移除。 比如规模大于10亿的会移除。
然后得到的结果,进行因子评分。
# 权重 溢价率、转债价格、正股N天涨幅,正股ROE
weights = {'溢价率': 0, '转债价格': 1, '正股N天涨幅': 0, '正股ROE': 0, '规模': 0}
每个权重赋予一个权重分最高是1,最低是0,如果你想回测 低溢价率 策略,只需要把其他因子的权重全部设置为0,溢价率设置为1即可。双底的话就是 溢价率和价格各为0.5 就可以了。
设置好参数后,设置你要回测的时间,持仓周期,持有个数等可调参数。
稍等片刻就会有结果了。因子越多,运行时间会增加。一般几分钟就可以得到几年来的回测结果。
中途可以查看日志
完整代码以及运行流程可到知识星球咨询了解。
欢迎关注公众号 收起阅读 »
ptrade策略代码:集合竞价追涨停策略
这个是示例代码,我们来大体讲解一下:
分解讲解:
initialize是初始化函数,一定要有的函数。在策略运行时首先运行的,而且只会运行一次。
set_universe(g.security) 在把标的代码放进去。这里是 '600570.SS' 记得要有后缀,上证股票用 .SS ,深圳股票用.SZ。
run_daily(context, aggregate_auction_func, time='9:23')
这一行是设定每天运行一次。这个策略是日线级别的,所以每天只要运行一次就可以了。 分别传入3个参数。
第一个参数固定是context,第二个要执行的函数名,记住只能传函数名,不能把括号也加进去,第三个参数,是运行的时间,现在设定在 9:23
那么接下来就是要实现上面那个函数名了: aggregate_auction_func,这个名字可以随意定义
stock = g.security , g是全局变量,用来在上下文中传递数据。这里就是上面的'600570.SS'
snapshot = get_snapshot(stock)
这个就是获取行情数据,当前的价格
up_limit = snapshot[stock]['up_px']
拿到这个标的的涨停价
if float(price) >= float(up_limit):
这个是当前价格大于涨停板价格(主要考虑了四舍五入,用于大号比较安全)
order(g.security, 100, limit_price=up_limit)
这个就是下单函数。
买入100股,不限价,市价成交。
然后就可以点击运行交易。
程序每天都会自动交易。
欢迎关注公众号
收起阅读 »
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
def handle_data(context, data):
pass
分解讲解:
def initialize(context):
# 初始化此策略
# 设置我们要操作的股票池, 这里我们只操作一支股票
g.security = '600570.SS'
set_universe(g.security)
#每天9:23分运行集合竞价处理函数
run_daily(context, aggregate_auction_func, time='9:23')
initialize是初始化函数,一定要有的函数。在策略运行时首先运行的,而且只会运行一次。
set_universe(g.security) 在把标的代码放进去。这里是 '600570.SS' 记得要有后缀,上证股票用 .SS ,深圳股票用.SZ。
run_daily(context, aggregate_auction_func, time='9:23')
这一行是设定每天运行一次。这个策略是日线级别的,所以每天只要运行一次就可以了。 分别传入3个参数。
第一个参数固定是context,第二个要执行的函数名,记住只能传函数名,不能把括号也加进去,第三个参数,是运行的时间,现在设定在 9:23
那么接下来就是要实现上面那个函数名了: aggregate_auction_func,这个名字可以随意定义
def aggregate_auction_func(context):
stock = g.security
#最新价
snapshot = get_snapshot(stock)
price = snapshot[stock]['last_px']
#涨停价
up_limit = snapshot[stock]['up_px']
#如果最新价不小于涨停价,买入
if float(price) >= float(up_limit):
order(g.security, 100, limit_price=up_limit)
stock = g.security , g是全局变量,用来在上下文中传递数据。这里就是上面的'600570.SS'
snapshot = get_snapshot(stock)
这个就是获取行情数据,当前的价格
up_limit = snapshot[stock]['up_px']
拿到这个标的的涨停价
if float(price) >= float(up_limit):
这个是当前价格大于涨停板价格(主要考虑了四舍五入,用于大号比较安全)
order(g.security, 100, limit_price=up_limit)
这个就是下单函数。
买入100股,不限价,市价成交。
然后就可以点击运行交易。
程序每天都会自动交易。
欢迎关注公众号
收起阅读 »
ptrade如何以指定价格下单?
在正常handle_data 或者 run_interval 模式下下单,是无法指定价格的。
order函数:
order_target - 函数
order_value 函数
order_target_value - 函数
order_market 函数
上面几个在handle_data中使用的下单函数,都是无法指定价格的,limit_price 只是用于限价,比如你要卖1000股,limit_price的作用是不要把价格卖出你的目标,至于多少卖,是无法控制的。
但是有一个tick_data函数,专门用于行情交易的,里面可调用的函数也很少。
order_tick - tick行情触发买卖
注意到里面:
limit_price:买卖限价,当输入参数中也包含priceGear时,下单价格以limit_price为主
发现这里面居然可以定义价格下单,所以如果一定要指定价格,就需要使用tick_data 触发。
使用代码:
order函数:
order-按数量买卖
order(security, amount, limit_price=None)
买卖标的。
注意:
由于下述原因,回测中实际买入或者卖出的股票数量有时候可能与委托设置的不一样,针对上述内容调整,系统会在日志中增加警告信息:
根据委托买入数量与价格经计算后的资金数量,大于当前可用资金;
委托卖出数量大于当前可用持仓数量;
每次交易数量只能是100的整数倍,但是卖出所有股票时不受此限制;
股票停牌、股票未上市或者退市、股票不存在;
回测中每天结束时会取消所有未完成交易;
order_target - 函数
order_target(security, amount, limit_price=None)
买卖股票,直到股票最终数量达到指定的amount。
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
参数
security: 股票代码(str);
amount: 期望的最终数量(int);
limit_price:买卖限价(float);
返回
Order对象中的id或者None。如果创建订单成功,则返回Order对象的id,失败则返回None(str)。
order_value 函数
order_value - 指定目标价值买卖
order_value(security, value, limit_price=None)
买卖指定价值为value的股票。
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
order_target_value - 函数
order_target_value - 指定持仓市值买卖
order_target_value(security, value, limit_price=None)
调整股票仓位到value价值
注意:该函数在委托股票时取整100股,委托可转债时取整100张。
order_market 函数
order_market - 按市价进行委托
order_market(security, amount, market_type=None, limit_price=None)
可以使用多种市价类型进行委托。
注意:该函数仅在股票交易模块可用。
上面几个在handle_data中使用的下单函数,都是无法指定价格的,limit_price 只是用于限价,比如你要卖1000股,limit_price的作用是不要把价格卖出你的目标,至于多少卖,是无法控制的。
但是有一个tick_data函数,专门用于行情交易的,里面可调用的函数也很少。
tick_data(可选)里面下单,用的下单函数是
tick_data(context, data)
该函数会每隔3秒执行一次。
注意 :
该函数仅在交易模块可用。
该函数在9:30之后才能执行。
该函数中只能使用order_tick进行对应的下单操作。
order_tick - tick行情触发买卖
order_tick(sid, amount, priceGear='1', limit_price=None)
买卖股票下单,可设定价格档位进行委托
注意:该函数仅在交易模块可用。
参数
sid:股票代码(str);
amount:交易数量,正数表示买入,负数表示卖出(int)
priceGear:盘口档位,level1:1~5买档/-1~-5卖档,level2:1~10买档/-1~-10卖档(str)
limit_price:买卖限价,当输入参数中也包含priceGear时,下单价格以limit_price为主(float);
注意到里面:
limit_price:买卖限价,当输入参数中也包含priceGear时,下单价格以limit_price为主
发现这里面居然可以定义价格下单,所以如果一定要指定价格,就需要使用tick_data 触发。
使用代码:
def initialize(context):收起阅读 »
g.security = "600570.SS"
set_universe(g.security)
def tick_data(context,data):
security = g.security
current_price = eval(data[security]['tick']['bid_grp'][0])[1][0]
if current_price > 56 and current_price < 57:
# 以买一档下单
order_tick(g.security, -100, "1")
# 以卖二档下单
order_tick(g.security, 100, "-2")
# 以指定价格下单
order_tick(g.security, 100, limit_price=56.5)
def handle_data(context, data):
pass
国盛证券qmt mini模式 xtquant
国盛证券QMT:
【国盛QMT支持 xtquant qmt mini模式】
mini模式可以在外部运行,同时可以下载历史tick数据。
可以直接获取level2的数据
使用python代码直接运行,不用在qmt软件里面憋屈地写代码,可直接使用pycharm,vscode编写,且有代码提示,补全,好用多了。
附一个完整的策略例子。
保存为: demo.py
命令行下运行:
python demo.py
开通xtquant的方式可以咨询。
目前开户费率低,门槛低,提供技术支持与交流。
需要的朋友,可以扫码咨询:
备注开户 收起阅读 »
【国盛QMT支持 xtquant qmt mini模式】
mini模式可以在外部运行,同时可以下载历史tick数据。
xtdata是xtquant库中提供行情相关数据的模块,本模块旨在提供精简直接的数据满足量化交易者的数
据需求,作为python库的形式可以被灵活添加到各种策略脚本中。
主要提供行情数据(历史和实时的K线和分笔)、财务数据、合约基础信息、板块和行业分类信息等通
用的行情数据
可以直接获取level2的数据
使用python代码直接运行,不用在qmt软件里面憋屈地写代码,可直接使用pycharm,vscode编写,且有代码提示,补全,好用多了。
附一个完整的策略例子。
保存为: demo.py
命令行下运行:
python demo.py
# 创建策略
#coding=utf-8
from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
from xtquant.xtquant import StockAccount
from xtquant import xtconstant
class MyXtQuantTraderCallback(XtQuantTraderCallback):
def on_disconnected(self):
"""
连接断开
:return:
"""
print("connection lost")
def on_stock_order(self, order):
"""
委托回报推送
:param order: XtOrder对象
:return:
"""
print("on order callback:")
print(order.stock_code, order.order_status, order.order_sysid)
def on_stock_asset(self, asset):
"""
资金变动推送
:param asset: XtAsset对象
:return:
"""
print("on asset callback")
print(asset.account_id, asset.cash, asset.total_asset)
def on_stock_trade(self, trade):
"""
成交变动推送
:param trade: XtTrade对象
:return:
"""
print("on trade callback")
print(trade.account_id, trade.stock_code, trade.order_id)
def on_stock_position(self, position):
"""
持仓变动推送
:param position: XtPosition对象
:return:
"""
print("on position callback")
print(position.stock_code, position.volume)
def on_order_error(self, order_error):
"""
委托失败推送
:param order_error:XtOrderError 对象
:return:
"""
print("on order_error callback")
print(order_error.order_id, order_error.error_id, order_error.error_msg)
def on_cancel_error(self, cancel_error):
"""
撤单失败推送
:param cancel_error: XtCancelError 对象
:return:
"""
print("on cancel_error callback")
print(cancel_error.order_id, cancel_error.error_id,
cancel_error.error_msg)
def on_order_stock_async_response(self, response):
"""
异步下单回报推送
:param response: XtOrderResponse 对象
:return:
"""
print("on_order_stock_async_response")
print(response.account_id, response.order_id, response.seq)
if __name__ == "__main__":
print("demo test")
# path为mini qmt客户端安装目录下userdata_mini路径
path = 'D:\\迅投极速交易终端 睿智融科版\\userdata_mini'
# session_id为会话编号,策略使用方对于不同的Python策略需要使用不同的会话编号
session_id = 123456
xt_trader = XtQuantTrader(path, session_id)
# 创建资金账号为1000000365的证券账号对象
acc = StockAccount('1000000365')
# 创建交易回调类对象,并声明接收回调
callback = MyXtQuantTraderCallback()
xt_trader.register_callback(callback)
# 启动交易线程
xt_trader.start()
# 建立交易连接,返回0表示连接成功
connect_result = xt_trader.connect()
print(connect_result)
# 对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功
subscribe_result = xt_trader.subscribe(acc)
print(subscribe_result)
stock_code = '600000.SH'
# 使用指定价下单,接口返回订单编号,后续可以用于撤单操作以及查询委托状态
print("order using the fix price:")
fix_result_order_id = xt_trader.order_stock(acc, stock_code,
xtconstant.STOCK_BUY, 200, xtconstant.FIX_PRICE, 10.5, 'strategy_name',
'remark')
print(fix_result_order_id)
# 使用订单编号撤单
print("cancel order:")
cancel_order_result = xt_trader.cancel_order_stock(acc, fix_result_order_id)
print(cancel_order_result)
# 使用异步下单接口,接口返回下单请求序号seq,seq可以和on_order_stock_async_response
的委托反馈response对应起来
print("order using async api:")
async_seq = xt_trader.order_stock(acc, stock_code, xtconstant.STOCK_BUY,
200, xtconstant.FIX_PRICE, 10.5, 'strategy_name', 'remark')
print(async_seq)
# 查询证券资产
print("query asset:")
asset = xt_trader.query_stock_asset(acc)
if asset:
print("asset:")
print("cash {0}".format(asset.cash))
# 根据订单编号查询委托
print("query order:")
order = xt_trader.query_stock_order(acc, fix_result_order_id)
if order:
print("order:")
print("order {0}".format(order.order_id))
# 查询当日所有的委托
print("query orders:")
orders = xt_trader.query_stock_orders(acc)
print("orders:", len(orders))
if len(orders) != 0:
print("last order:")
print("{0} {1} {2}".format(orders[-1].stock_code,
orders[-1].order_volume, orders[-1].price))
# 查询当日所有的成交
print("query trade:")
trades = xt_trader.query_stock_trades(acc)
print("trades:", len(trades))
if len(trades) != 0:
print("last trade:")
print("{0} {1} {2}".format(trades[-1].stock_code,
trades[-1].traded_volume, trades[-1].traded_price))
# 查询当日所有的持仓
print("query positions:")
positions = xt_trader.query_stock_positions(acc)
print("positions:", len(positions))
if len(positions) != 0:
print("last position:")
print("{0} {1} {2}".format(positions[-1].account_id,
positions[-1].stock_code, positions[-1].volume))
# 根据股票代码查询对应持仓
print("query position:")
position = xt_trader.query_stock_position(acc, stock_code)
if position:
print("position:")
print("{0} {1} {2}".format(position.account_id, position.stock_code,
position.volume))
# 阻塞线程,接收交易推送
xt_trader.run_forever()
开通xtquant的方式可以咨询。
目前开户费率低,门槛低,提供技术支持与交流。
需要的朋友,可以扫码咨询:
备注开户 收起阅读 »
ptrade每天自动打新 (新股和可转债)附python代码
ptrade软件-量化-回测 里,新建策略,复制全文粘贴进去,周期选分钟,再到交易里新增交易。可以参见文末图片。
交易页面
程序运行返回代码:
点击查看大图
【如果没有打新额度或者没有开通对应的权限,会显示可收购为0】
底下的成功的是可转债申购成功。
然后可以到券商app上看看是否已经有自动申购成功的记录。 收起阅读 »
import time
def initialize(context):
g.flag = False
log.info("initialize g.flag=" + str(g.flag) )
def before_trading_start(context, data):
g.flag = False
log.info("before_trading_start g.flag=" + str(g.flag) )
def handle_data(context, data):
if not g.flag and time.strftime("%H:%M:%S", time.localtime()) > '09:35:00':
# 自动打新
log.info("自动打新")
ipo_stocks_order()
g.flag = True
def on_order_response(context, order_list):
# 该函数会在委托回报返回时响应
log.info(order_list)
交易页面
程序运行返回代码:
点击查看大图
【如果没有打新额度或者没有开通对应的权限,会显示可收购为0】
底下的成功的是可转债申购成功。
然后可以到券商app上看看是否已经有自动申购成功的记录。 收起阅读 »