diff --git a/QUANTAXIS/QAARP/QAAccount.py b/QUANTAXIS/QAARP/QAAccount.py index d03d75ade..481f08de8 100755 --- a/QUANTAXIS/QAARP/QAAccount.py +++ b/QUANTAXIS/QAARP/QAAccount.py @@ -250,7 +250,8 @@ def __init__( 'commission', # 手续费 'tax', # 税 'message', # 备注 - 'frozen' # 冻结资金 + 'frozen', # 冻结资金. + 'direction' # 方向 ] ######################################################################## # 信息类: @@ -1108,7 +1109,8 @@ def receive_simpledeal( commission_fee, tax_fee, message, - frozen_money + frozen_money, + trade_towards ] ) diff --git a/QUANTAXIS/QAARP/QARisk.py b/QUANTAXIS/QAARP/QARisk.py index 44f3dbb04..3905a7ef9 100755 --- a/QUANTAXIS/QAARP/QARisk.py +++ b/QUANTAXIS/QAARP/QARisk.py @@ -452,7 +452,7 @@ def beta(self): beta比率 组合的系统性风险 """ try: - res=round( + res = round( float( self.calc_beta( self.profit_pct.dropna(), @@ -463,8 +463,8 @@ def beta(self): ) except: print('贝塔计算错误。。') - res=0 - + res = 0 + return res @property @@ -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': @@ -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 @@ -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] @@ -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: @@ -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: @@ -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): diff --git a/QUANTAXIS/__init__.py b/QUANTAXIS/__init__.py index cb99929aa..9e294adfe 100755 --- a/QUANTAXIS/__init__.py +++ b/QUANTAXIS/__init__.py @@ -31,7 +31,7 @@ 2017/4/8 """ -__version__ = '1.4.1' +__version__ = '1.4.2' __author__ = 'yutiansut' # fetch methods diff --git a/QUANTAXIS_Test/QAARP_Test/mytest_QAAccount.py b/QUANTAXIS_Test/QAARP_Test/mytest_QAAccount.py new file mode 100644 index 000000000..2597e9270 --- /dev/null +++ b/QUANTAXIS_Test/QAARP_Test/mytest_QAAccount.py @@ -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) \ No newline at end of file