Skip to content

Commit

Permalink
新增:实现文件名驼峰化选项;非py文件提示确认
Browse files Browse the repository at this point in the history
  • Loading branch information
jim4work committed May 7, 2021
1 parent 52223ff commit df0168b
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ if (owner == null) {
10. 2021-05-07 v1.6.2 新增: 转换保留字 assert
11. 2021-05-07 v1.6.3 新增: 行尾注释先去除再恢复; 新增转换保留字 del; 修复若干 bugs
12. 2021-05-07 v1.6.4 新增: 转换对象属性相关方法 hasattr, getattr, setattr; 界面上增加"文件名改驼峰式"

13. 2021-05-08 v1.6.5 新增:实现文件名驼峰化选项;非py文件提示确认

### TODO 待办事宜
1. Python 语言的列表推导式转换
Expand Down
2 changes: 1 addition & 1 deletion default.aproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<project ver="10" name="py2aardio" libEmbed="true" icon="res\logo.ico" ui="win" output="py2aardio.exe" CompanyName="JimmyCHEN" FileDescription="py2aardio" LegalCopyright="Copyright (C) 2021 JimmyCHEN" ProductName="py2aardio" InternalName="py2aardio" FileVersion="1.4.0.505" ProductVersion="1.4.0.505" publishDir="/dist/" dstrip="false" local="false" ignored="false">
<project ver="10" name="py2aardio" libEmbed="true" icon="res\logo.ico" ui="win" output="py2aardio.exe" CompanyName="JimmyCHEN" FileDescription="py2aardio" LegalCopyright="Copyright (C) 2021 JimmyCHEN" ProductName="py2aardio" InternalName="py2aardio" FileVersion="1.6.4.509" ProductVersion="1.6.4.509" publishDir="/dist/" dstrip="false" local="false" ignored="false">
<file name="main.aardio" path="main.aardio" comment="main.aardio"/>
<folder name="资源文件" path="res" embed="true" local="false" ignored="false"/>
<folder name="窗体文件" path="dlg" comment="目录" embed="true" local="false" ignored="false"/>
Expand Down
Binary file modified dist/py2aardio.exe
Binary file not shown.
35 changes: 30 additions & 5 deletions main.aardio
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ var copyFile = function(fileFullName, cfg) {
}
}

// 文件名驼峰化
var camelizeFilename = function(fileFullName) {
var result = fileFullName;
var path = fsys.getParentDir(result);
var fname = fsys.getFileName(result);
var pattern = `([a-z\d\$])_([a-z])`; //以下划线'_'连接的小写字母文件名
fname = string.replace(fname, pattern, function($1, $2) {
//owner = 原始字符串
return $1 ++ string.upper($2); // file_name.ext -> fileName.ext
});
result = path ++ fname;
//console.debug('camelizeFilename: result='++ result);
return result;
}

var listener = thread.command();
listener.addSourceItem = function(sourceType, item) {
Expand Down Expand Up @@ -172,7 +186,16 @@ mainForm.btnStart.oncommand = function(id, event) {

if (sourceType == 'file') {
thread.command.send('addSourceItem', 'file', srcPath);
var ext = fsys.getExtensionName(srcPath);
if(ext != 'py') {
var answer = mainForm.msgboxTest('该文件(*.'++ext++')不是 python 源文件, 是否继续?');
if(answer != true)
return;
}
cfg.targetFile = getTargetFullName(srcPath); // 通过cfg传入目标文件完全路径
if(cfg.camelizeFile) {
cfg.targetFile = camelizeFilename(cfg.targetFile);
}
convertSingleFile(srcPath, cfg); // 转换单个文件
}
elseif(sourceType == 'dir') {
Expand All @@ -181,20 +204,22 @@ mainForm.btnStart.oncommand = function(id, event) {
fsys.enum(srcPath/*要遍历的目录*/, "*.*"/*指定查询文件名,支持windows掩码*/, function(dir, filename, fileFullName, findData) { //指定触发器
if (filename) { //若是文件
var ext = fsys.getExtensionName(filename);
console.log("src file:" ++ fileFullName);
//console.debug("src file:" ++ fileFullName);
if (ext == 'py') { // 若是 py 文件 则转换格式
//console.debug(fileFullName);
count++;
//console.log("文件:"++filename, ', dir='++dir, ',fileFullName='++fileFullName);
//console.debug("文件:"++filename, ', dir='++dir, ',fileFullName='++fileFullName);
thread.command.send('addSourceItem', 'file', fileFullName);
cfg.targetFile = getTargetFullName(fileFullName); // 通过cfg传入目标文件完全路径
cfg.targetFile = getTargetFullName(fileFullName); // 通过cfg 将目标文件路径传入线程
if(cfg.camelizeFile) {
cfg.targetFile = camelizeFilename(cfg.targetFile);
}
thread.invoke(convertFn, dir, filename, fileFullName, cfg);
}
elseif (cfg.copyOthers) { // 否则,若需复制目录内的其它文件(用于整个工程的整体性转换)
//console.debug(fileFullName);
count++;
thread.command.send('addSourceItem', 'file', fileFullName);
cfg.targetFile = getTargetFullName(fileFullName, false); // 通过cfg传入目标文件完全路径(false=不修改扩展名)
cfg.targetFile = getTargetFullName(fileFullName, false); // 通过cfg 将目标文件路径传入线程(false=不修改扩展名)
thread.invoke(copyFile, fileFullName, cfg);
}
}
Expand Down
147 changes: 147 additions & 0 deletions test/jqFollower.aardio
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// -*- coding: utf-8 -*-
import re;
import datetime; var datetime = datetime.datetime;
import threading; var Thread = threading.Thread;

import ez; var exceptions = ez.exceptions;
import ez.follower; var BaseFollower = ez.follower.BaseFollower;
import ez.log; var logger = ez.log.logger;


class JoinQuantFollower {
this = BaseFollower(...);// 继承的父类 <--请把这行移入类的构造函数 ctor 内! {
LOGIN_PAGE = "https://www.joinquant.com";
LOGIN_API = "https://www.joinquant.com/user/login/doLogin?ajax=1";
TRANSACTION_API =(
"https://www.joinquant.com/algorithm/live/transactionDetail"
);
WEB_REFERER = "https://www.joinquant.com/user/login/index";
WEB_ORIGIN = "https://www.joinquant.com";

createLoginParams = function(user, password, **kwargs) {
params = {
"CyLoginForm[username]": user,
"CyLoginForm[pwd]": password,
"ajax": 1,
};
return params;
}

checkLoginSuccess = function(rep) {
setCookie = rep.headers["set-cookie"];
if (#(setCookie) < 50) {
error exceptions.NotLoginError("登录失败,请检查用户名和密码");
}
this.s.headers.update({"cookie": setCookie});
}

follow = function(
this,
users,
strategies,
trackInterval=1,
tradeCmdExpireSeconds=120,
cmdCache=true,
entrustProp="limit",
sendInterval=0,
) {
/*跟踪joinquant对应的模拟交易,支持多用户多策略
:param users: 支持ez的用户对象,支持使用 [] 指定多个用户
:param strategies: joinquant 的模拟交易地址,支持使用 [] 指定多个模拟交易,
地址类似 https://www.joinquant.com/algorithm/live/index?backtestId=xxx
:param trackInterval: 轮训模拟交易时间,单位为秒
:param tradeCmdExpireSeconds: 交易指令过期时间, 单位为秒
:param cmdCache: 是否读取存储历史执行过的指令,防止重启时重复执行已经交易过的指令
:param entrustProp: 委托方式, 'limit' 为限价,'market' 为市价, 仅在银河实现
:param sendInterval: 交易发送间隔, 默认为0s。调大可防止卖出买入时卖出单没有及时成交导致的买入金额不足
*/
users = this.warpList(users);
strategies = this.warpList(strategies);

if (cmdCache) {
this.loadExpiredCmdCache();
}

this.startTraderThread(
users, tradeCmdExpireSeconds, entrustProp, sendInterval
);

workers = {};
for (strategyUrl in strategies) {
try {
strategyId = this.extractStrategyId(strategyUrl);
strategyName = this.extractStrategyName(strategyUrl);
} catch(e) {
logger.error("抽取交易id和策略名失败, 无效的模拟交易url: %s", strategyUrl);
error;
}
strategyWorker = Thread(
target=this.trackStrategyWorker,
args= {strategyId, strategyName},
kwargs={"interval": trackInterval},
);
strategyWorker.start();
workers.append(strategyWorker);
logger.info("开始跟踪策略: %s", strategyName);
}
for (worker in workers) {
worker.join();
}
}

// @staticmethod;
extractStrategyId = function(strategyUrl) {
return re.search("(?<=backtestId=)\w+", strategyUrl).group();
}

extractStrategyName = function(strategyUrl) {
rep = this.s.get(strategyUrl);
return this.reFind('(?<=title="点击修改策略名称"\>).*(?=\</span)', rep.content.decode("utf8"));
}

createQueryTransactionParams = function(strategy) {
todayStr = datetime.today().strftime("%Y-%m-%d");
params = {"backtestId": strategy, "date": todayStr, "ajax": 1};
return params;
}

extractTransactions = function(history) {
transactions = history["data"]["transaction"];
return transactions;
}

// @staticmethod;
stockShuffleToPrefix = function(stock) {
assert(#(stock) == 11), string.format("stock {} must like 123456.XSHG or 123456.XSHE", stock);
code = stock[:6];
if (stock.find("XSHG") != -1) {
return "sh" + code;
}

if (stock.find("XSHE") != -1) {
return "sz" + code;
}
error TypeError(string.format("not valid stock code {}", code));
}

projectTransactions = function(transactions, **kwargs) {
for (transaction in transactions) {
transaction["amount"] = this.reFind(
"\d+", transaction["amount"], dtype=int
);

timeStr = string.format("{} {}", transaction["date"], transaction["time"]);
transaction["datetime"] = datetime.strptime(
timeStr, "%Y-%m-%d %H:%M"
);

stock = this.reFind("\d{6}\.\w{4}", transaction["stock"]);
transaction["stockCode"] = this.stockShuffleToPrefix(stock);

transaction["action"] =(
"buy" if transaction["transaction"] == "买" else "sell"
)

}
}
}

0 comments on commit df0168b

Please sign in to comment.