Ptrade下单接口 order,order_target, order_value,order_target_value的区别

量化交易李魔佛 发表了文章 • 0 个评论 • 54 次浏览 • 2022-08-11 23:57 • 来自相关话题

order_target 接口通过持仓数量比较将入参的目标数量转换成需要交易的成交,传入 order
接口

order_value 接口通过 金额/限价 或者 金额/默认最新价 两种方式转换成需要交易的数量,
传入 order 接口

order_target_value 接口通过持仓金额比较得到需要交易的金额, 金额/限价 或者 金额/默
认最新价 两种方式转换成需要交易的数量,传入 order 接口



所以其他几个接口都是对order的封装。
 
order接口的逻辑:
order 接口:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则最新价代替,都是
限价方式报单。
二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就放到未处理订单
队列
三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台
  
  查看全部
order_target 接口通过持仓数量比较将入参的目标数量转换成需要交易的成交,传入 order
接口

order_value 接口通过 金额/限价 或者 金额/默认最新价 两种方式转换成需要交易的数量,
传入 order 接口

order_target_value 接口通过持仓金额比较得到需要交易的金额, 金额/限价 或者 金额/默
认最新价 两种方式转换成需要交易的数量,传入 order 接口



所以其他几个接口都是对order的封装。
 
order接口的逻辑:
order 接口:
一、
先判断 limit_price 是否传入,传入则用传入价格限价,不传入则最新价代替,都是
限价方式报单。

二、
判断隔夜单和交易时间,交易时间(9:10(系统可配)~15:00)范围的订单会马上
加入未处理订单队列,其他订单先放到一个队列,等时间到交易时间就放到未处理订单
队列

三、
未处理订单队列的订单会进行限价判断,如果没有传入限价就按当前最新价处理,
然后报柜台

  
 

去除导流公众号的网站 油猴脚本

网络李魔佛 发表了文章 • 0 个评论 • 48 次浏览 • 2022-08-11 13:26 • 来自相关话题

先安装油猴工具。然后导入下面的油猴脚本
 

去除博客导流公众号
// ==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);
}
});
})(); 查看全部
先安装油猴工具。然后导入下面的油猴脚本
 

去除博客导流公众号
// ==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);
}
});
})();

Ptrade抢新上市的可转债

量化交易李魔佛 发表了文章 • 0 个评论 • 61 次浏览 • 2022-08-11 10:20 • 来自相关话题

更新:早上的单子如期挂上了。只是成交量太少,轮不动我的。不过也好,省点心,不用每次盯盘操作。





 
PS: 也不是每一只都是去抢,还是需要提前判断下。规模小的优先。
更新:早上的单子如期挂上了。只是成交量太少,轮不动我的。不过也好,省点心,不用每次盯盘操作。

20220811002.png

 
PS: 也不是每一只都是去抢,还是需要提前判断下。规模小的优先。

自己写的包在 PTrade 里如何使用的方法有吗?

量化交易李魔佛 发表了文章 • 0 个评论 • 68 次浏览 • 2022-08-08 03:28 • 来自相关话题

自己写的包在 PTrade 里如何使用的方法有吗?
A:和常规 Python 函数调用时一样的,只是需要和你的其它函数放在同一个脚本
中,暂时不支持跨越脚本文件的调用。
 
所以你写的包,都要放着ptrade的策略里面,不能另外保存到一个地方,然后通过 from xxxx import xxxx 这种方式导入。
 
所以有时候你的ptrade文件会臃肿无比。经常复制粘贴。也是无奈之举。 查看全部
自己写的包在 PTrade 里如何使用的方法有吗?
A:和常规 Python 函数调用时一样的,只是需要和你的其它函数放在同一个脚本
中,暂时不支持跨越脚本文件的调用。
 
所以你写的包,都要放着ptrade的策略里面,不能另外保存到一个地方,然后通过 from xxxx import xxxx 这种方式导入。
 
所以有时候你的ptrade文件会臃肿无比。经常复制粘贴。也是无奈之举。

ptrade支持文件的读写吗,Excel 文件可以读写吗

量化交易李魔佛 发表了文章 • 0 个评论 • 55 次浏览 • 2022-08-08 00:01 • 来自相关话题

 
当前支持 csv,xlsx,txt,pkl 等文件的读取,需要手动将对应文件上传到研究环境中,
然后在回测中使用 get_research_path()+”文件名”获取文件路径后进行读取(见下图),
回写文件类似,可使用 pd.to_csv()等函数存储在研究环境指定目录下。
值得注意的是,当前支持单个文件最大为 50M
 





 
模型每天都会更新的,权重文件,能上传吗?
 
可以,注意文件大小的限制。
 
  查看全部
 
当前支持 csv,xlsx,txt,pkl 等文件的读取,需要手动将对应文件上传到研究环境中,
然后在回测中使用 get_research_path()+”文件名”获取文件路径后进行读取(见下图),
回写文件类似,可使用 pd.to_csv()等函数存储在研究环境指定目录下。
值得注意的是,当前支持单个文件最大为 50M
 

img1.png

 
模型每天都会更新的,权重文件,能上传吗?
 
可以,注意文件大小的限制。
 
 

优矿使用的python版本

量化交易李魔佛 发表了文章 • 0 个评论 • 57 次浏览 • 2022-08-07 08:22 • 来自相关话题

应该是变种的python2.7
从底层来看它的报错信息:





 
它是使用python2.7
 
可是异常操作,却可以使用python3的语法
try:
....
except Exception as e:
.....
 
所以有些地方还是得要注意一下 py2和py3的区别
比如py2的字典默认顺序是无序的。(这个有一次调试一个bug耗费了一两个小时,结果发现用了字典,取key,结果发现key的顺序全部是乱的,py3从3.6开始字典的key是有序的)
 
  查看全部
应该是变种的python2.7
从底层来看它的报错信息:

20220807001.png

 
它是使用python2.7
 
可是异常操作,却可以使用python3的语法
try:
....
except Exception as e:
.....
 
所以有些地方还是得要注意一下 py2和py3的区别
比如py2的字典默认顺序是无序的。(这个有一次调试一个bug耗费了一两个小时,结果发现用了字典,取key,结果发现key的顺序全部是乱的,py3从3.6开始字典的key是有序的)
 
 

可转债多因子回测 优矿代码

量化交易李魔佛 发表了文章 • 0 个评论 • 84 次浏览 • 2022-08-06 18:00 • 来自相关话题

可转债里面可用因子很多,一般人最常用的就是溢价率,双低,价格等。
实际运用里面,可以加入很多很多因子,比如正股涨跌幅,正股波动率,转债到期时间,正股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 就可以了。
 
设置好参数后,设置你要回测的时间,持仓周期,持有个数等可调参数。
 
稍等片刻就会有结果了。因子越多,运行时间会增加。一般几分钟就可以得到几年来的回测结果。
 





中途可以查看日志
 
完整代码以及运行流程可到知识星球咨询了解。





  查看全部
可转债里面可用因子很多,一般人最常用的就是溢价率,双低,价格等。
实际运用里面,可以加入很多很多因子,比如正股涨跌幅,正股波动率,转债到期时间,正股ROE等等多大几十个因子。

20220806001.png

 
之前写了一个多因子回测的优矿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日之间的数据)。

20220806003.png

计算波动率具体代码如下;

20220806004.png

 
每个因子写成一个类。
 
这样可以不用修改主代码,就可以无限地添加,修改因子。
# 基类
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


20220806005.png

 
上面是部分过滤因子,也就是不满足的都会被移除。 比如规模大于10亿的会移除。
 
然后得到的结果,进行因子评分。 
# 权重 溢价率、转债价格、正股N天涨幅,正股ROE
weights = {'溢价率': 0, '转债价格': 1, '正股N天涨幅': 0, '正股ROE': 0, '规模': 0}

每个权重赋予一个权重分最高是1,最低是0,如果你想回测 低溢价率 策略,只需要把其他因子的权重全部设置为0,溢价率设置为1即可。双底的话就是 溢价率和价格各为0.5 就可以了。
 
设置好参数后,设置你要回测的时间,持仓周期,持有个数等可调参数。
 
稍等片刻就会有结果了。因子越多,运行时间会增加。一般几分钟就可以得到几年来的回测结果。
 

20220806006.png

中途可以查看日志
 
完整代码以及运行流程可到知识星球咨询了解。

ZSXQ_20220806_180545705.png

 

ptrade策略代码:集合竞价追涨停策略

量化交易李魔佛 发表了文章 • 0 个评论 • 103 次浏览 • 2022-08-04 15:24 • 来自相关话题

这个是示例代码,我们来大体讲解一下: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股,不限价,市价成交。
 
然后就可以点击运行交易。 
 
程序每天都会自动交易。



 
 

  查看全部
这个是示例代码,我们来大体讲解一下:
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可以同时执行多少个实盘策略?

量化交易李魔佛 发表了文章 • 0 个评论 • 104 次浏览 • 2022-08-02 20:41 • 来自相关话题

ptrade里面的策略和回测可以创建无数个,但是,如果要实盘运行的策略,只能同时运行5个。超过5个之后会提示你停止部分运行的策略,才能新增新的策略。





 
而在代码里面,如果多个策略同时运行,需要在代码层面区分不同策略下的单子,不然会造成冲突。比如你第一个策略下的单子,被第二个策略清仓了。
 
那么要如何区分不同策略下单呢?
1. 如果是日内策略,只需要用一个字典dict,记录每次买入记录,每次的卖出标的都要在dict里面。
 
2. 持久化。虽然大部分券商的ptrade都不支持联网,但是,可以使用本地持久化,pickle或者sqlite。保存在云本地。 查看全部
ptrade里面的策略和回测可以创建无数个,但是,如果要实盘运行的策略,只能同时运行5个。超过5个之后会提示你停止部分运行的策略,才能新增新的策略。

20220802001.png

 
而在代码里面,如果多个策略同时运行,需要在代码层面区分不同策略下的单子,不然会造成冲突。比如你第一个策略下的单子,被第二个策略清仓了。
 
那么要如何区分不同策略下单呢?
1. 如果是日内策略,只需要用一个字典dict,记录每次买入记录,每次的卖出标的都要在dict里面。
 
2. 持久化。虽然大部分券商的ptrade都不支持联网,但是,可以使用本地持久化,pickle或者sqlite。保存在云本地。

ptrade如何以指定价格下单?

量化交易李魔佛 发表了文章 • 0 个评论 • 108 次浏览 • 2022-07-30 19:27 • 来自相关话题

在正常handle_data 或者 run_interval 模式下下单,是无法指定价格的。
 
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 查看全部
在正常handle_data 或者 run_interval 模式下下单,是无法指定价格的。
 
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

券商万一免五李魔佛 发表了文章 • 0 个评论 • 248 次浏览 • 2022-07-29 01:00 • 来自相关话题

国盛证券QMT:
【国盛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的方式可以咨询。
 
目前开户费率低,门槛低,提供技术支持与交流。
需要的朋友,可以扫码咨询:

备注开户 查看全部
国盛证券QMT:
【国盛QMT支持 xtquant  qmt mini模式】
 

 
mini模式可以在外部运行,同时可以下载历史tick数据。
xtdata是xtquant库中提供行情相关数据的模块,本模块旨在提供精简直接的数据满足量化交易者的数
据需求,作为python库的形式可以被灵活添加到各种策略脚本中。
主要提供行情数据(历史和实时的K线和分笔)、财务数据、合约基础信息、板块和行业分类信息等通
用的行情数据

可以直接获取level2的数据

20220729001.png

 

使用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代码

量化交易李魔佛 发表了文章 • 0 个评论 • 187 次浏览 • 2022-07-28 11:10 • 来自相关话题

ptrade软件-量化-回测 里,新建策略,复制全文粘贴进去,周期选分钟,再到交易里新增交易。可以参见文末图片。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上看看是否已经有自动申购成功的记录。 查看全部
ptrade软件-量化-回测 里,新建策略,复制全文粘贴进去,周期选分钟,再到交易里新增交易。可以参见文末图片。
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)

交易页面
20220728001.png

程序运行返回代码:

20220728002.png
点击查看大图
 
【如果没有打新额度或者没有开通对应的权限,会显示可收购为0】

底下的成功的是可转债申购成功。

然后可以到券商app上看看是否已经有自动申购成功的记录。

ptrade回测和实盘支持可转债日内tick/分时吗?

可转债李魔佛 发表了文章 • 0 个评论 • 175 次浏览 • 2022-07-25 07:19 • 来自相关话题

是支持的。
 
比如下面的部分代码片段,是用于导出可转债的日内分时数据的。最低颗粒,按照一分钟k线获取。 ptrade里面能够获取到的最小频率单位。
 def initialize(context):
# 初始化策略
g.code_mapper = date_code_mapper()
log.info(g.code_mapper)
g.error_set=set()

def last_n_day(date,n,origin_fmt,target_fmt):
return (datetime.datetime.strptime(date, origin_fmt) - datetime.timedelta(days=n)).strftime(target_fmt)

def post_fix(code):
return code + '.SZ' if code.startswith('12') else code + '.SS'

def handle_data(context, data):
date=context.blotter.current_dt.strftime('%Y%m%d')
if date not in g.code_mapper:
return

security_list=g.code_mapper.get(date)

for code in security_list:
code=post_fix(code)
try:
df = get_history(1, frequency='1m', field=['open' ,'high','low','close'], security_list=code, fq='pre',include=False)
except Exception as e:
if code not in g.error_set:
log.info(e)
log.info('代码获取数据 出错{}'.format(code))
g.error_set.add(code)
continue
df['ticker']=code
g.result.append(df)

def after_trading_end(context, data):
#engine = DBS
db = DBSelector()
conn = db.get_engine()
date=context.blotter.current_dt.strftime('%Y%m%d%H%M')
if len(g.result)==0:
return

df = pd.concat(g.result)
try:
df.to_sql('minute_info',con=conn,if_exists='append')
except Exception as e:
log.info(e)

g.result=

def before_trading_start(context, data):
g.result=
然后在handle_data里面加入相关的order就可以交易了。(上面的代码主要是保存tick/分时数据到mysql,实际并没有进行交易。) 查看全部
是支持的。
 
比如下面的部分代码片段,是用于导出可转债的日内分时数据的。最低颗粒,按照一分钟k线获取。 ptrade里面能够获取到的最小频率单位。
 
def initialize(context):
# 初始化策略
g.code_mapper = date_code_mapper()
log.info(g.code_mapper)
g.error_set=set()

def last_n_day(date,n,origin_fmt,target_fmt):
return (datetime.datetime.strptime(date, origin_fmt) - datetime.timedelta(days=n)).strftime(target_fmt)

def post_fix(code):
return code + '.SZ' if code.startswith('12') else code + '.SS'

def handle_data(context, data):
date=context.blotter.current_dt.strftime('%Y%m%d')
if date not in g.code_mapper:
return

security_list=g.code_mapper.get(date)

for code in security_list:
code=post_fix(code)
try:
df = get_history(1, frequency='1m', field=['open' ,'high','low','close'], security_list=code, fq='pre',include=False)
except Exception as e:
if code not in g.error_set:
log.info(e)
log.info('代码获取数据 出错{}'.format(code))
g.error_set.add(code)
continue
df['ticker']=code
g.result.append(df)

def after_trading_end(context, data):
#engine = DBS
db = DBSelector()
conn = db.get_engine()
date=context.blotter.current_dt.strftime('%Y%m%d%H%M')
if len(g.result)==0:
return

df = pd.concat(g.result)
try:
df.to_sql('minute_info',con=conn,if_exists='append')
except Exception as e:
log.info(e)

g.result=

def before_trading_start(context, data):
g.result=

然后在handle_data里面加入相关的order就可以交易了。(上面的代码主要是保存tick/分时数据到mysql,实际并没有进行交易。)

雪球上的小兵 重仓的融创 现在潜心修炼

投资绫波丽 发表了文章 • 0 个评论 • 155 次浏览 • 2022-07-23 12:53 • 来自相关话题

之前在雪球上了解小兵,主要源于他狂傲装逼的个性,15年之后重仓的融创,收益率可能达到十多倍,中途不确定有没有减仓。

 





2020年还40多元,现在只有4块多。目前还停牌了,复牌后又是腥风血雨的了。

现在已经跌破他的成本线了,色即是空,空即是色。 到头来,做了一轮大过山车,收获了寂寞。
 
现在他在雪球上也不怎么发言。 每天就是徒步, 打坐,修行。
 





 






不过还是挺喜欢他性格,放荡不羁,敢作敢为,不卖理财基金收割粉丝,也不会说自己在融创高位全部抛了,在地位又买回来这样伪大V的假话。
 
一个小兵,一个云蒙,都值得尊佩。
  查看全部
之前在雪球上了解小兵,主要源于他狂傲装逼的个性,15年之后重仓的融创,收益率可能达到十多倍,中途不确定有没有减仓。

 
20220723003.png


2020年还40多元,现在只有4块多。目前还停牌了,复牌后又是腥风血雨的了。

现在已经跌破他的成本线了,色即是空,空即是色。 到头来,做了一轮大过山车,收获了寂寞。
 
现在他在雪球上也不怎么发言。 每天就是徒步, 打坐,修行。
 

20220723001.png

 

20220723002.png


不过还是挺喜欢他性格,放荡不羁,敢作敢为,不卖理财基金收割粉丝,也不会说自己在融创高位全部抛了,在地位又买回来这样伪大V的假话。
 
一个小兵,一个云蒙,都值得尊佩。
 

ciso8601 性能对比 datetime 默认库

python李魔佛 发表了文章 • 0 个评论 • 126 次浏览 • 2022-07-22 12:04 • 来自相关话题

In [1]: import datetime, aniso8601, iso8601, isodate, dateutil.parser, arrow, ciso8601

In [2]: ds = u'2014-01-09T21:48:00.921000'

In [3]: %timeit ciso8601.parse_datetime(ds)
1000000 loops, best of 3: 204 ns per loop

In [4]: %timeit datetime.datetime.strptime(ds, "%Y-%m-%dT%H:%M:%S.%f")
100000 loops, best of 3: 15 µs per loop

In [5]: %timeit dateutil.parser.parse(ds)
10000 loops, best of 3: 122 µs per loop

In [6]: %timeit aniso8601.parse_datetime(ds)
10000 loops, best of 3: 28.9 µs per loop

In [7]: %timeit iso8601.parse_date(ds)
10000 loops, best of 3: 42 µs per loop

In [8]: %timeit isodate.parse_datetime(ds)
10000 loops, best of 3: 69.4 µs per loop

In [9]: %timeit arrow.get(ds).datetime
10000 loops, best of 3: 87 µs per loopIn [1]: import datetime, aniso8601, iso8601, isodate, dateutil.parser, arrow, ciso8601

In [2]: ds = u'2014-01-09T21:48:00.921000+05:30'

In [3]: %timeit ciso8601.parse_datetime(ds)
1000000 loops, best of 3: 525 ns per loop

In [4]: %timeit dateutil.parser.parse(ds)
10000 loops, best of 3: 162 µs per loop

In [5]: %timeit aniso8601.parse_datetime(ds)
10000 loops, best of 3: 36.8 µs per loop

In [6]: %timeit iso8601.parse_date(ds)
10000 loops, best of 3: 53.5 µs per loop

In [7]: %timeit isodate.parse_datetime(ds)
10000 loops, best of 3: 82.6 µs per loop

In [8]: %timeit arrow.get(ds).datetime
10000 loops, best of 3: 104 µs per loop
 

Even with time zone information, ciso8601 is 70x as fast as aniso8601.

Tested on Python 2.7.10 on macOS 10.12.6 using the following modules:

 
 
 ciso8601 是纳秒级别的,如果要对上千万的数据操作,建议使用ciso这个C库。
  查看全部
In [1]: import datetime, aniso8601, iso8601, isodate, dateutil.parser, arrow, ciso8601

In [2]: ds = u'2014-01-09T21:48:00.921000'

In [3]: %timeit ciso8601.parse_datetime(ds)
1000000 loops, best of 3: 204 ns per loop

In [4]: %timeit datetime.datetime.strptime(ds, "%Y-%m-%dT%H:%M:%S.%f")
100000 loops, best of 3: 15 µs per loop

In [5]: %timeit dateutil.parser.parse(ds)
10000 loops, best of 3: 122 µs per loop

In [6]: %timeit aniso8601.parse_datetime(ds)
10000 loops, best of 3: 28.9 µs per loop

In [7]: %timeit iso8601.parse_date(ds)
10000 loops, best of 3: 42 µs per loop

In [8]: %timeit isodate.parse_datetime(ds)
10000 loops, best of 3: 69.4 µs per loop

In [9]: %timeit arrow.get(ds).datetime
10000 loops, best of 3: 87 µs per loop
In [1]: import datetime, aniso8601, iso8601, isodate, dateutil.parser, arrow, ciso8601

In [2]: ds = u'2014-01-09T21:48:00.921000+05:30'

In [3]: %timeit ciso8601.parse_datetime(ds)
1000000 loops, best of 3: 525 ns per loop

In [4]: %timeit dateutil.parser.parse(ds)
10000 loops, best of 3: 162 µs per loop

In [5]: %timeit aniso8601.parse_datetime(ds)
10000 loops, best of 3: 36.8 µs per loop

In [6]: %timeit iso8601.parse_date(ds)
10000 loops, best of 3: 53.5 µs per loop

In [7]: %timeit isodate.parse_datetime(ds)
10000 loops, best of 3: 82.6 µs per loop

In [8]: %timeit arrow.get(ds).datetime
10000 loops, best of 3: 104 µs per loop

 


Even with time zone information, ciso8601 is 70x as fast as aniso8601.

Tested on Python 2.7.10 on macOS 10.12.6 using the following modules:


 
 
 ciso8601 是纳秒级别的,如果要对上千万的数据操作,建议使用ciso这个C库。