1 Star 0 Fork 0

DTC2 / simsummary

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
simsummary.py 10.14 KB
一键复制 编辑 原始数据 按行查看 历史
DTC2 提交于 2019-03-16 16:10 . Init
#!/usr/bin/python
# coding:utf8
import argparse
import sys
import const
import re
import math
const.MARGIN_MULTIPLIER = 10000
const.MARGIN_CS_MULTIPLIER = 100
const.LONGSHORT_SCALE = 1000000
const.PNL_SCALE = 1000000
#display standard yearly statistics from pnl file
(p, t, f, sdate, edate, booksize) = (None, "yearly", "short",-1,-1,-1.0)
parser = argparse.ArgumentParser(description='Example with long option names',formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-p', action="store", dest="p",type=str,default=None)
parser.add_argument('-t', action="store", dest="t",type=str,default=t)
parser.add_argument('-f', action="store", dest="f",type=str,default=f)
parser.add_argument('-s', action="store", dest="sdate",type=int,default=sdate)
parser.add_argument('-e', action="store", dest="edate",type=int,default=edate)
parser.add_argument('-b', action="store", dest="booksize",type=float,default=booksize)
if('p' in dir()):
if len(sys.argv) < 2:
print("Usage: simsummary.py pnl_file\n")
sys.exit(-1)
elif len(sys.argv) == 2:
p = sys.argv[1]
else:
results = parser.parse_args()
p = results.__dict__["p"]
t = results.__dict__["t"]
sdate = results.__dict__["sdate"]
edate = results.__dict__["edate"]
booksize = results.__dict__["booksize"]
DD_start = 0
DD_setst = 0
DD_sum = 0
XX_last = 0
ldate = 0
with open(p, 'r') as file:#打开文件
off = -50 #设置偏移量
while True:
file.seek(off, 2) #seek(off, 2)表示文件指针:从文件末尾(2)开始向前50个字符(-50)
lines = file.readlines() #读取文件指针范围内所有行
if len(lines) >= 2: #判断是否最后至少有两行,这样保证了最后一行是完整的
last_line = lines[-1] #取最后一行
break
#如果off为50时得到的readlines只有一行内容,那么不能保证最后一行是完整的
#所以off翻倍重新运行,直到readlines不止一行
off *= 2
lastline = last_line.split('\t')
srecent = int(lastline[0]) - 20000
stats = dict()
def doStats(XX, date, pnl, long, short, ret, sh_hld, sh_trd, b_share, t_share):
if not stats.has_key(XX):
stats.setdefault(XX, dict())
if stats[XX].has_key('dates'):
stats[XX]['dates'].append(int(date))
else:
stats[XX].setdefault('dates',[int(date)])
curr_ret = pnl / booksize * 2 if booksize > 0 else ret
if stats[XX].has_key('pnl'):
stats[XX]['pnl']+=float(pnl)
else:
stats[XX].setdefault('pnl', 0)
if stats[XX].has_key('long'):
stats[XX]['long']+=float(long)
else:
stats[XX].setdefault('long', 0)
if stats[XX].has_key('short'):
stats[XX]['short']+=float(short)
else:
stats[XX].setdefault('short', 0)
if stats[XX].has_key('sh_hld'):
stats[XX]['sh_hld']+=float(sh_hld)
else:
stats[XX].setdefault('sh_hld', 0)
if stats[XX].has_key('sh_trd'):
stats[XX]['sh_trd']+=float(sh_trd)
else:
stats[XX].setdefault('sh_trd', 0)
if stats[XX].has_key('avg_ret'):
stats[XX]['avg_ret']+=float(curr_ret)
else:
stats[XX].setdefault('avg_ret', 0)
if stats[XX].has_key('b_sh'):
stats[XX]['b_sh']+=float(b_share)
else:
stats[XX].setdefault('b_sh', 0)
if stats[XX].has_key('t_sh'):
stats[XX]['t_sh']+=float(t_share)
else:
stats[XX].setdefault('t_sh', 0)
if long != 0 or short != 0 or booksize > 0:
if stats[XX].has_key('days'):
stats[XX]['days']+=1
else:
stats[XX].setdefault('days',0)
print(stats[XX]['days'])
if stats[XX].has_key('xsy'):
stats[XX]['xsy']+=float(curr_ret)
else:
stats[XX].setdefault('xsy', 0.0)
if stats[XX].has_key('xsyy'):
stats[XX]['xsyy']+=float(curr_ret) ** 2
else:
stats[XX].setdefault('xsyy', 0.0)
if pnl > 0:
if stats[XX].has_key('up_days'):
stats[XX]['up_days']+=1
else:
stats[XX].setdefault('up_days', 0)
if not stats.has_key('mm_sum'):
stats[XX].setdefault('mm_sum', 0)
stats[XX].setdefault('mm_cnt', 0)
stats[XX].setdefault('up_months', 0)
if not stats.has_key('ww_sum'):
stats[XX].setdefault('ww_sum', 0)
stats[XX].setdefault('ww_cnt', 0)
stats[XX].setdefault('up_weeks', 0)
if not stats.has_key('drawdown'):
stats[XX].setdefault('drawdown', 0)
stats[XX].setdefault('dd_start', 0)
stats[XX].setdefault('dd_end', 0)
finalTimeHash = dict()
goodLong = dict()
goodShort = dict()
def canUpdate(date,long,short):
if not goodLong.has_key('date') or not goodShort.has_key('date'):
return 1
else:
curr_diff = abs(abs(long) + abs(short) - booksize)
target_diff = abs(abs(goodLong['date']) + abs(goodShort['date']) - booksize)
if(curr_diff <= target_diff):
return 1
return 0
with open(p) as F:
for line in F:
date, pnl, long, short,_,_,_,_,_,_ = line[:-1].split('\t')
if len(date) < 9:
break
date_ = date[0:8]
finalTimeHash[date_] = date #overwrite
if booksize > 0 and canUpdate(date_,long,short) > 0:
goodLong[date_] = long
goodShort[date_] = short
with open(p) as F:
for l in F:
date, pnl, long, short, ret, sh_hld, sh_trd, b_share, t_share,_ = l[:-1].split('\t')
date_ = date[0:8]
if (sdate > 0 and date_ < sdate) or (edate > 0 and date_ > edate):
continue
if finalTimeHash.has_key(date_) and date != finalTimeHash[date_]:
continue
date = date[0:8]
XX = date[0:4]
if t == "monthly":
XX = date[0:6]
long = float(goodLong[date_]) if booksize > 0 else float(long)
short = float(goodShort[date_]) if booksize > 0 else float(short)
doStats(XX,date,pnl,long,short, ret, sh_hld, sh_trd, b_share, t_share)
doStats("ALL",date,pnl,long,short, ret, sh_hld, sh_trd, b_share, t_share)
if date > srecent:
doStats("RECENT",date,pnl,long,short, ret, sh_hld, sh_trd, b_share, t_share)
#drawdowns
if DD_setst:
DD_start = date
DD_setst = 0
DD_sum += float(pnl)
if DD_sum >= 0:
DD_sum = 0
DD_start = date
DD_setst = 1
if DD_sum < stats[XX]['drawdown']:
stats[XX]['drawdown'] = DD_sum
stats[XX]['dd_start'] = DD_start
stats[XX]['dd_end'] = date
if DD_sum < stats['ALL']['drawdown']:
stats['ALL']['drawdown'] = DD_sum
stats['ALL']['dd_start'] = DD_start
stats['ALL']['dd_end'] = date
if date > srecent and DD_sum < stats['RECENT']['drawdown']:
stats['RECENT']['drawdown'] = DD_sum
stats['RECENT']['dd_start'] = DD_start
stats['RECENT']['dd_end'] = date
ldate = date
XX_last = XX
matchObj = re.match(r'long', f, re.I)
if matchObj:
print("%17s %7s %8s %7s %7s %7s %14s %7s %7s %7s %7s %7s %7s %7s %7s\n" % ("dates","long(M)","short(M)","pnl(M)","%ret","%tvr","shrp(IR)","%dd","%win","up_days","up_weeks","up_months","bpmrgn","csmrgn","fitness"))
else:
print("%17s %7s %8s %7s %7s %7s %14s %5s %5s %6s %6s %7s\n" % ("dates","long(M)","short(M)","pnl(M)","%ret","%tvr","shrp(IR)","%dd","%win","bpmrgn","csmrgn","fitness"))
stats.keys().sort()
for XX in stats.keys():
matchObject = re.match(r'ALL', XX, re.M)
if (matchObject):
print("\n")
d = stats[XX]['days']
if(d is not None and d > 0):
long = stats[XX]['long'] / d
short = stats[XX]['short'] / d
ret = stats[XX]['avg_ret'] / d * 250.0
perwin = stats[XX]['up_days'] / d * 100.0
turnover = stats[XX]['sh_trd'] / booksize / d if booksize > 0 else (stats[XX]['sh_trd'] / stats[XX]['sh_hld'] if stats[XX]['sh_hld'] > 0 else 0)
drawdown = stats[XX]['drawdown'] / long * -100 if long > 0 else 0 # percent of long side
avg = 0
std = 0
ir = 0
if (d > 0):
avg = stats[XX]['xsy'] / d
if (d > 2):
std = math.sqrt(1 / (d - 1) * (stats[XX]['xsyy'] - stats[XX]['xsy'] * stats[XX]['xsy'] / d))
if (std > 0):
ir = avg / std
fitness = ir / turnover if turnover > 0 else 0
printIr = "%0.3f(%0.3f)" % (ir * math.sqrt(252), ir)
#calc margin
margin = const.MARGIN_MULTIPLIER * stats[XX]['pnl'] / stats[XX]['sh_trd'] if stats[XX]['sh_trd'] != 0 else "NaN"
margin_cs = const.MARGIN_CS_MULTIPLIER * stats[XX]['pnl'] / stats[XX]['t_sh'] if stats[XX]['t_sh'] != 0 else "NaN"
matchObj2 = re.match(r'long', f, re.I)
if(matchObj2):
print("%8d-%8d %7.2f %8.2f %7.3f %7.2f %7.2f %14s %7.2f %7.2f %7d %7.2f %7.3f %7.3f\n" % (stats[XX]['dates'][0],stats[XX]['dates'][-1],long * 1.0 / +const.LONGSHORT_SCALE, short * 1.0 / +const.LONGSHORT_SCALE, stats[XX]['pnl'] * 1.0 / const.PNL_SCALE,float(ret) * 100,turnover * 100,printIr, drawdown, perwin, stats[XX]['up_days'],stats[XX]['up_weeks'],stats[XX]['up_months'],margin,margin_cs,ir * math.sqrt(252) * math.sqrt(abs(float(ret)) / turnover)))
else:
print("%8d-%8d %7.2f %8.2f %7.3f %7.2f %7.2f %14s %5.2f %5.2f %6.2f %6.3f %7.3f\n" % (stats[XX]['dates'][0],stats[XX]['dates'][-1],long * 1.0 / +const.LONGSHORT_SCALE, short * 1.0 / +const.LONGSHORT_SCALE, stats[XX]['pnl'] * 1.0 / const.PNL_SCALE, float(ret) * 100,turnover * 100,printIr, drawdown, perwin, margin,margin_cs,ir * math.sqrt(252) * math.sqrt(abs(float(ret)) / turnover)))
Python
1
https://gitee.com/zymITsky/simsummary.git
git@gitee.com:zymITsky/simsummary.git
zymITsky
simsummary
simsummary
master

搜索帮助