Skip to content

Commit

Permalink
Merge pull request #1101 from yutiansut/master
Browse files Browse the repository at this point in the history
QAAccount的历史记录存储增加开平标志/ QAPerformance的字段更新改进
  • Loading branch information
yutiansut authored Apr 8, 2019
2 parents 03cf2c2 + 84ad022 commit 9a183ca
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 108 deletions.
6 changes: 4 additions & 2 deletions QUANTAXIS/QAARP/QAAccount.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ def __init__(
'commission', # 手续费
'tax', # 税
'message', # 备注
'frozen' # 冻结资金
'frozen', # 冻结资金.
'direction' # 方向
]
########################################################################
# 信息类:
Expand Down Expand Up @@ -1108,7 +1109,8 @@ def receive_simpledeal(
commission_fee,
tax_fee,
message,
frozen_money
frozen_money,
trade_towards
]
)

Expand Down
231 changes: 126 additions & 105 deletions QUANTAXIS/QAARP/QARisk.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ def beta(self):
beta比率 组合的系统性风险
"""
try:
res=round(
res = round(
float(
self.calc_beta(
self.profit_pct.dropna(),
Expand All @@ -463,8 +463,8 @@ def beta(self):
)
except:
print('贝塔计算错误。。')
res=0
res = 0

return res

@property
Expand Down Expand Up @@ -885,7 +885,7 @@ def __init__(self, target):
self.pnl = self.pnl_fifo

def __repr__(self):
return 'QA_PERFORMANCE ANYLYSIS PLUGIN'
return '< QA_PERFORMANCE ANYLYSIS PLUGIN >'

def set_pnl(self, model='fifo'):
if model == 'fifo':
Expand Down Expand Up @@ -948,28 +948,77 @@ def message(self):
"""

return {
'total_profit': round(self.total_profit, 2), # 总盈利(对于每个单笔而言)
'total_loss': round(self.total_loss, 2), # 总亏损(对于每个单笔而言)
'total_pnl': round(self.total_pnl, 2), # 总盈利/总亏损
'trading_amounts': round(self.trading_amounts, 2), # 交易手数
'profit_amounts': round(self.profit_amounts, 2), # 盈利手数
'loss_amounts': round(self.loss_amounts, 2), # 亏损手数
'even_amounts': round(self.even_amounts, 2), # 持平手数
'profit_precentage': round(self.profit_precentage, 2),
'loss_precentage': round(self.loss_precentage, 2),
'even_precentage': round(self.even_precentage, 2),
'average_profit': round(self.average_profit, 2),
'average_loss': round(self.average_loss, 2),
'average_pnl': round(self.average_pnl, 2),
'max_profit': round(self.max_profit, 2),
'max_loss': round(self.max_loss, 2),
'max_pnl': round(self.max_pnl, 2),
'netprofio_maxloss_ratio': round(self.netprofio_maxloss_ratio, 2),
'continue_profit_amount': round(self.continue_profit_amount, 2),
'continue_loss_amount': round(self.continue_loss_amount, 2),
'average_holdgap': self.average_holdgap,
'average_profitholdgap': self.average_profitholdgap,
'average_losssholdgap': self.average_losssholdgap
'total_profit': round(self.total_profit(self.pnl), 2), # 总盈利(对于每个单笔而言)
'total_loss': round(self.total_loss(self.pnl), 2), # 总亏损(对于每个单笔而言)
'total_pnl': round(self.total_pnl(self.pnl), 2), # 总盈利/总亏损
'trading_amounts': round(self.trading_amounts(self.pnl), 2), # 交易手数
'profit_amounts': round(self.profit_amounts(self.pnl), 2), # 盈利手数
'loss_amounts': round(self.loss_amounts(self.pnl), 2), # 亏损手数
'even_amounts': round(self.even_amounts(self.pnl), 2), # 持平手数
'profit_precentage': round(self.profit_precentage(self.pnl), 2),
'loss_precentage': round(self.loss_precentage(self.pnl), 2),
'even_precentage': round(self.even_precentage(self.pnl), 2),
'average_profit': round(self.average_profit(self.pnl), 2),
'average_loss': round(self.average_loss(self.pnl), 2),
'average_pnl': round(self.average_pnl(self.pnl), 2),
'max_profit': round(self.max_profit(self.pnl), 2),
'max_loss': round(self.max_loss(self.pnl), 2),
'max_pnl': round(self.max_pnl(self.pnl), 2),
'buyopen':{
'netprofio_maxloss_ratio': round(self.netprofio_maxloss_ratio(self.pnl), 2),
'continue_profit_amount': round(self.continue_profit_amount(self.pnl), 2),
'continue_loss_amount': round(self.continue_loss_amount(self.pnl), 2),
'average_holdgap': self.average_holdgap(self.pnl),
'average_profitholdgap': self.average_profitholdgap(self.pnl),
'average_losssholdgap': self.average_losssholdgap(self.pnl),
'total_profit': round(self.total_profit(self.pnl_buyopen), 2), # 总盈利(对于每个单笔而言)
'total_loss': round(self.total_loss(self.pnl_buyopen), 2), # 总亏损(对于每个单笔而言)
'total_pnl': round(self.total_pnl(self.pnl_buyopen), 2), # 总盈利/总亏损
'trading_amounts': round(self.trading_amounts(self.pnl_buyopen), 2), # 交易手数
'profit_amounts': round(self.profit_amounts(self.pnl_buyopen), 2), # 盈利手数
'loss_amounts': round(self.loss_amounts(self.pnl_buyopen), 2), # 亏损手数
'even_amounts': round(self.even_amounts(self.pnl_buyopen), 2), # 持平手数
'profit_precentage': round(self.profit_precentage(self.pnl_buyopen), 2),
'loss_precentage': round(self.loss_precentage(self.pnl_buyopen), 2),
'even_precentage': round(self.even_precentage(self.pnl_buyopen), 2),
'average_profit': round(self.average_profit(self.pnl_buyopen), 2),
'average_loss': round(self.average_loss(self.pnl_buyopen), 2),
'average_pnl': round(self.average_pnl(self.pnl_buyopen), 2),
'max_profit': round(self.max_profit(self.pnl_buyopen), 2),
'max_loss': round(self.max_loss(self.pnl_buyopen), 2),
'max_pnl': round(self.max_pnl(self.pnl_buyopen), 2),
'netprofio_maxloss_ratio': round(self.netprofio_maxloss_ratio(self.pnl_buyopen), 2),
'continue_profit_amount': round(self.continue_profit_amount(self.pnl_buyopen), 2),
'continue_loss_amount': round(self.continue_loss_amount(self.pnl_buyopen), 2),
'average_holdgap': self.average_holdgap(self.pnl_buyopen),
'average_profitholdgap': self.average_profitholdgap(self.pnl_buyopen),
'average_losssholdgap': self.average_losssholdgap(self.pnl_buyopen)
},
'sellopen':
{
'total_profit': round(self.total_profit(self.pnl_sellopen), 2), # 总盈利(对于每个单笔而言)
'total_loss': round(self.total_loss(self.pnl_sellopen), 2), # 总亏损(对于每个单笔而言)
'total_pnl': round(self.total_pnl(self.pnl_sellopen), 2), # 总盈利/总亏损
'trading_amounts': round(self.trading_amounts(self.pnl_sellopen), 2), # 交易手数
'profit_amounts': round(self.profit_amounts(self.pnl_sellopen), 2), # 盈利手数
'loss_amounts': round(self.loss_amounts(self.pnl_sellopen), 2), # 亏损手数
'even_amounts': round(self.even_amounts(self.pnl_sellopen), 2), # 持平手数
'profit_precentage': round(self.profit_precentage(self.pnl_sellopen), 2),
'loss_precentage': round(self.loss_precentage(self.pnl_sellopen), 2),
'even_precentage': round(self.even_precentage(self.pnl_sellopen), 2),
'average_profit': round(self.average_profit(self.pnl_sellopen), 2),
'average_loss': round(self.average_loss(self.pnl_sellopen), 2),
'average_pnl': round(self.average_pnl(self.pnl_sellopen), 2),
'max_profit': round(self.max_profit(self.pnl_sellopen), 2),
'max_loss': round(self.max_loss(self.pnl_sellopen), 2),
'max_pnl': round(self.max_pnl(self.pnl_sellopen), 2),
'netprofio_maxloss_ratio': round(self.netprofio_maxloss_ratio(self.pnl_sellopen), 2),
'continue_profit_amount': round(self.continue_profit_amount(self.pnl_sellopen), 2),
'continue_loss_amount': round(self.continue_loss_amount(self.pnl_sellopen), 2),
'average_holdgap': self.average_holdgap(self.pnl_sellopen),
'average_profitholdgap': self.average_profitholdgap(self.pnl_sellopen),
'average_losssholdgap': self.average_losssholdgap(self.pnl_sellopen)
}
}

@property
Expand Down Expand Up @@ -1127,7 +1176,7 @@ def pnl_lifo(self):
@property
def pnl_buyopen(self):
return self.pnl[self.pnl.if_buyopen]

@property
def pnl_sellopen(self):
return self.pnl[~self.pnl.if_buyopen]
Expand Down Expand Up @@ -1337,91 +1386,68 @@ def save(self):
"""
pass

@property
def profit_pnl(self):
return self.pnl.query('pnl_money>0')
def profit_pnl(self, pnl):
return pnl.query('pnl_money>0')

@property
def loss_pnl(self):
return self.pnl.query('pnl_money<0')
def loss_pnl(self, pnl):
return pnl.query('pnl_money<0')

@property
def even_pnl(self):
return self.pnl.query('pnl_money==0')
def even_pnl(self, pnl):
return pnl.query('pnl_money==0')

@property
def total_profit(self):
return self.profit_pnl.pnl_money.sum()
def total_profit(self, pnl):
return self.profit_pnl(pnl).pnl_money.sum()

@property
def total_loss(self):
return self.loss_pnl.pnl_money.sum()
def total_loss(self, pnl):
return self.loss_pnl(pnl).pnl_money.sum()

@property
def total_pnl(self):
return abs(self.total_profit / self.total_loss)
def total_pnl(self, pnl):
return abs(self.total_profit(pnl) / self.total_loss(pnl))

@property
def trading_amounts(self):
return len(self.pnl)
def trading_amounts(self, pnl):
return len(pnl)

@property
def profit_amounts(self):
return len(self.profit_pnl)
def profit_amounts(self, pnl):
return len(self.profit_pnl(pnl))

@property
def loss_amounts(self):
return len(self.loss_pnl)
def loss_amounts(self, pnl):
return len(self.loss_pnl(pnl))

@property
def even_amounts(self):
return len(self.even_pnl)
def even_amounts(self, pnl):
return len(self.even_pnl(pnl))

@property
def profit_precentage(self):
return self.profit_amounts / self.trading_amounts
def profit_precentage(self, pnl):
return self.profit_amounts(pnl) / self.trading_amounts(pnl)

@property
def loss_precentage(self):
return self.loss_amounts / self.trading_amounts
def loss_precentage(self, pnl):
return self.loss_amounts(pnl) / self.trading_amounts(pnl)

@property
def even_precentage(self):
return self.even_amounts / self.trading_amounts
def even_precentage(self, pnl):
return self.even_amounts(pnl) / self.trading_amounts(pnl)

@property
def average_profit(self):
return self.profit_pnl.pnl_money.mean()
def average_loss(self, pnl):
return self.loss_pnl(pnl).pnl_money.mean()

@property
def average_loss(self):
return self.loss_pnl.pnl_money.mean()
def average_pnl(self, pnl):
return abs(self.average_profit(pnl) / self.average_loss(pnl))

@property
def average_pnl(self):
return abs(self.average_profit / self.average_loss)

@property
def max_profit(self):
return self.profit_pnl.pnl_money.max()
def max_profit(self, pnl):
return self.profit_pnl(pnl).pnl_money.max()

@property
def max_loss(self):
return self.loss_pnl.pnl_money.min()
def max_loss(self, pnl):
return self.loss_pnl(pnl).pnl_money.min()

@property
def max_pnl(self):
return abs(self.max_profit / self.max_loss)
def max_pnl(self, pnl):
return abs(self.max_profit(pnl) / self.max_loss(pnl))

@property
def netprofio_maxloss_ratio(self):
return abs(self.pnl.pnl_money.sum() / self.max_loss)
def netprofio_maxloss_ratio(self, pnl):
return abs(pnl.pnl_money.sum() / self.max_loss(pnl))

@property
def continue_profit_amount(self):
def continue_profit_amount(self, pnl):
w = []
w1 = 0
for _, item in self.pnl.pnl_money.iteritems():
for _, item in pnl.pnl_money.iteritems():
if item > 0:
w1 += 1
elif item < 0:
Expand All @@ -1432,11 +1458,10 @@ def continue_profit_amount(self):
else:
return max(w)

@property
def continue_loss_amount(self):
def continue_loss_amount(self, pnl):
l = []
l1 = 0
for _, item in self.pnl.pnl_money.iteritems():
for _, item in pnl.pnl_money.iteritems():
if item > 0:
l1 += 1
elif item < 0:
Expand All @@ -1447,21 +1472,17 @@ def continue_loss_amount(self):
else:
return max(l)

@property
def average_holdgap(self):
return str(self.pnl.hold_gap.mean())
def average_holdgap(self, pnl):
return str(pnl.hold_gap.mean())

@property
def average_profitholdgap(self):
return str(self.profit_pnl.hold_gap.mean())
def average_profitholdgap(self, pnl):
return str(self.profit_pnl(pnl).hold_gap.mean())

@property
def average_losssholdgap(self):
return str(self.loss_pnl.hold_gap.mean())
def average_losssholdgap(self, pnl):
return str(self.loss_pnl(pnl).hold_gap.mean())

@property
def average_evenholdgap(self):
return self.even_pnl.hold_gap.mean()
def average_evenholdgap(self, pnl):
return self.even_pnl(pnl).hold_gap.mean()

@property
def max_cashused(self):
Expand Down
2 changes: 1 addition & 1 deletion QUANTAXIS/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
2017/4/8
"""

__version__ = '1.4.1'
__version__ = '1.4.2'
__author__ = 'yutiansut'

# fetch methods
Expand Down
45 changes: 45 additions & 0 deletions QUANTAXIS_Test/QAARP_Test/mytest_QAAccount.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# coding:utf-8

import QUANTAXIS as QA
import uuid

user = QA.QA_User(username = 'quantaxis', password= 'quantaxis')

p = user.new_portfolio('test')


ac = p.new_account(account_cookie=str(uuid.uuid4()), market_type=QA.MARKET_TYPE.FUTURE_CN, init_cash=10000)

print('test_BUY/SELL')

ac.receive_simpledeal('RB1905',2800,1, QA.ORDER_DIRECTION.BUY_OPEN,'2019-01-21 09:35:00')

print(ac.hold_available)
ac.receive_simpledeal('RB1905',2803,1, QA.ORDER_DIRECTION.SELL_CLOSE,'2019-01-21 09:45:00')



print('left_cash')

print(ac.cash_available)
print(ac.hold_available)
print(ac.sell_available)

ac.receive_simpledeal('RB1905',2802,1, QA.ORDER_DIRECTION.SELL_OPEN,'2019-01-21 09:55:00')
print(ac.hold_available)
ac.receive_simpledeal('RB1905',2810,1, QA.ORDER_DIRECTION.BUY_CLOSE,'2019-01-21 11:05:00')

print(ac.history_table)

if int(ac.cash[-1]) == 9938:
print('cash is true')


print('TEST PORTFOLIO')

perf = QA.QA_Performance(ac)
print(perf.pnl)

from pprint import pprint

pprint(perf.message)

0 comments on commit 9a183ca

Please sign in to comment.