Skip to content

Latest commit

 

History

History
2505 lines (2153 loc) · 49.6 KB

QUANTAXIS回测分析全过程讲解.md

File metadata and controls

2505 lines (2153 loc) · 49.6 KB
import QUANTAXIS as QA
try:
    assert QA.__version__>='1.1.0'
except AssertionError:
    print('pip install QUANTAXIS >= 1.1.0 请升级QUANTAXIS后再运行此示例')
print('首先确定你已经完成了对于QUANTAXIS的基础认知,以及在本地存储完毕了QUANTAXIS的数据库')
首先确定你已经完成了对于QUANTAXIS的基础认知,以及在本地存储完毕了QUANTAXIS的数据库

QUANTAXIS 回测的一些基础知识

QA回测的核心是两个类

QA_BacktestBroker
QA_Account

回测数据的引入/迭代

QA.QA_fetch_stock_day_adv
QA.QA_fetch_stock_min_adv

指标的计算

DataStruct.add_func

对于账户的灵活运用

QA_Account
QA_Risk
QA_Portfolio
QA_PortfolioView
QA_User

STEP1 初始化账户,初始化回测broker

Account=QA.QA_Account()
Broker=QA.QA_BacktestBroker()
import warnings
# # 打印账户的信息
# try:
#     from pprint import  pprint as print
# except:
#     pass
# print(Account.message)

首先讲解Account类:

QA_Account在初始化的时候,可以自己指定很多信息:


    QA_Account(
        strategy_name=None, user_cookie=None, portfolio_cookie=None, account_cookie=None,
        market_type=MARKET_TYPE.STOCK_CN, frequence=FREQUENCE.DAY, broker=BROKER_TYPE.BACKETEST,
        init_hold={}, init_cash=1000000, commission_coeff=0.00025, tax_coeff=0.0015,
        margin_level=False, allow_t0=False, allow_sellopen=False,
        running_environment=RUNNING_ENVIRONMENT.BACKETEST)

        :param [str] strategy_name:  策略名称
        :param [str] user_cookie:   用户cookie
        :param [str] portfolio_cookie: 组合cookie
        :param [str] account_cookie:   账户cookie

        :param [dict] init_hold         初始化时的股票资产
        :param [float] init_cash:         初始化资金
        :param [float] commission_coeff:  交易佣金 :默认 万2.5   float 类型
        :param [float] tax_coeff:         印花税   :默认 千1.5   float 类型

        :param [Bool] margin_level:      保证金比例 默认False
        :param [Bool] allow_t0:          是否允许t+0交易  默认False
        :param [Bool] allow_sellopen:    是否允许卖空开仓  默认False

        :param [QA.PARAM] market_type:   市场类别 默认QA.MARKET_TYPE.STOCK_CN A股股票
        :param [QA.PARAM] frequence:     账户级别 默认日线QA.FREQUENCE.DAY
        :param [QA.PARAM] broker:        BROEKR类 默认回测 QA.BROKER_TYPE.BACKTEST
        :param [QA.PARAM] running_environment 当前运行环境 默认Backtest

        # 2018/06/11 init_assets 从float变为dict,并且不作为输入,作为只读属性
        #  :param [float] init_assets:       初始资产  默认 1000000 元 (100万)
        init_assets:{
            cash: xxx,
            stock: {'000001':2000},
            init_date: '2018-02-05',
            init_datetime: '2018-02-05 15:00:00'
        }
        # 2018/06/11 取消在初始化的时候的cash和history输入
        # :param [list] cash:              可用现金  默认 是 初始资产  list 类型
        # :param [list] history:           交易历史
# 重设账户初始资金

Account.reset_assets(200000)
Account.account_cookie='JCSC_EXAMPLE'
Account.init_assets
{'cash': 200000, 'hold': {}}

Account 有很多方法,暂时不详细展开,我们先直接进入下一步

SETP2:引入回测的市场数据

引入方法非常简单,直接使用QA_fetch_stock_day_adv系列即可

  • code 可以是多种多样的选取方式
1. QA.QA_fetch_stock_list_adv().code.tolist() # 获取全市场的股票代码
2. QA.QA_fetch_stock_block_adv().get_block('云计算').code  # 按版块选取
3. code= ['000001','000002'] # 自己指定
  • 数据获取后,to_qfq() 即可获得前复权数据
data=DataSturct.to_qfq()
# QA.QA_fetch_stock_list_adv().code.tolist()
# QA.QA_fetch_stock_block_adv().get_block('云计算').code
#codelist=QA.QA_fetch_stock_block_adv().get_block('云计算').code
codelist=['000001']
data=QA.QA_fetch_stock_day_adv(codelist,'2017-09-01','2018-05-20')
data
< QA_DataStruct_Stock_day with 1 securities >
data=data.to_qfq()
# data.data

STEP3:计算一些指标

指标的计算可以在回测前,也可以在回测中进行

回测前的计算则是批量计算,效率较高

回测中的计算,效率略低,但代码量较小,易于理解

PS: 指标的相关介绍参见 QUANTAXIS的指标系统

import numpy as np
import pandas as pd
def MACD_JCSC(dataframe,SHORT=12,LONG=26,M=9):
    """
    1.DIF向上突破DEA,买入信号参考。
    
    2.DIF向下跌破DEA,卖出信号参考。
    """
    CLOSE=dataframe.close
    DIFF =QA.EMA(CLOSE,SHORT) - QA.EMA(CLOSE,LONG)
    DEA = QA.EMA(DIFF,M)
    MACD =2*(DIFF-DEA)

    CROSS_JC=QA.CROSS(DIFF,DEA)
    CROSS_SC=QA.CROSS(DEA,DIFF)
    ZERO=0
    return pd.DataFrame({'DIFF':DIFF,'DEA':DEA,'MACD':MACD,'CROSS_JC':CROSS_JC,'CROSS_SC':CROSS_SC,'ZERO':ZERO})
ind=data.add_func(MACD_JCSC)
ind.xs(codelist[0],level=1)['2018-01'].plot()
<matplotlib.axes._subplots.AxesSubplot at 0x1fb23cb9f98>

png

ind.xs(codelist[0],level=1)['2018-01']
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
DIFF DEA MACD CROSS_JC CROSS_SC ZERO
date
2018-01-02 0.110686 0.103225 0.014921 1 0 0
2018-01-03 0.100387 0.102657 -0.004541 0 1 0
2018-01-04 0.084801 0.099086 -0.028570 0 0 0
2018-01-05 0.075607 0.094390 -0.037566 0 0 0
2018-01-08 0.040453 0.083603 -0.086299 0 0 0
2018-01-09 0.022012 0.071285 -0.098545 0 0 0
2018-01-10 0.038391 0.064706 -0.052629 0 0 0
2018-01-11 0.045208 0.060806 -0.031197 0 0 0
2018-01-12 0.061988 0.061043 0.001890 1 0 0
2018-01-15 0.126236 0.074081 0.104309 0 0 0
2018-01-16 0.175134 0.094292 0.161683 0 0 0
2018-01-17 0.213839 0.118201 0.191275 0 0 0
2018-01-18 0.280788 0.150718 0.260139 0 0 0
2018-01-19 0.336418 0.187858 0.297119 0 0 0
2018-01-22 0.347467 0.219780 0.255374 0 0 0
2018-01-23 0.368907 0.249605 0.238603 0 0 0
2018-01-24 0.380702 0.275825 0.209755 0 0 0
2018-01-25 0.350521 0.290764 0.119515 0 0 0
2018-01-26 0.310920 0.294795 0.032249 0 0 0
2018-01-29 0.251630 0.286162 -0.069064 0 1 0
2018-01-30 0.195134 0.267957 -0.145646 0 0 0
2018-01-31 0.180544 0.250474 -0.139859 0 0 0
ind.loc['2018-01',slice(None)]
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
DIFF DEA MACD CROSS_JC CROSS_SC ZERO
date code
2018-01-02 000001 0.110686 0.103225 0.014921 1 0 0
2018-01-03 000001 0.100387 0.102657 -0.004541 0 1 0
2018-01-04 000001 0.084801 0.099086 -0.028570 0 0 0
2018-01-05 000001 0.075607 0.094390 -0.037566 0 0 0
2018-01-08 000001 0.040453 0.083603 -0.086299 0 0 0
2018-01-09 000001 0.022012 0.071285 -0.098545 0 0 0
2018-01-10 000001 0.038391 0.064706 -0.052629 0 0 0
2018-01-11 000001 0.045208 0.060806 -0.031197 0 0 0
2018-01-12 000001 0.061988 0.061043 0.001890 1 0 0
2018-01-15 000001 0.126236 0.074081 0.104309 0 0 0
2018-01-16 000001 0.175134 0.094292 0.161683 0 0 0
2018-01-17 000001 0.213839 0.118201 0.191275 0 0 0
2018-01-18 000001 0.280788 0.150718 0.260139 0 0 0
2018-01-19 000001 0.336418 0.187858 0.297119 0 0 0
2018-01-22 000001 0.347467 0.219780 0.255374 0 0 0
2018-01-23 000001 0.368907 0.249605 0.238603 0 0 0
2018-01-24 000001 0.380702 0.275825 0.209755 0 0 0
2018-01-25 000001 0.350521 0.290764 0.119515 0 0 0
2018-01-26 000001 0.310920 0.294795 0.032249 0 0 0
2018-01-29 000001 0.251630 0.286162 -0.069064 0 1 0
2018-01-30 000001 0.195134 0.267957 -0.145646 0 0 0
2018-01-31 000001 0.180544 0.250474 -0.139859 0 0 0

SETP4:选取回测的开始和结束日期,构建回测

data_forbacktest=data.select_time('2018-01-01','2018-05-01')


for items in data_forbacktest.panel_gen:
    for item in items.security_gen:
        daily_ind=ind.loc[item.index]
        if daily_ind.CROSS_JC.iloc[0]>0:
            order=Account.send_order(
                code=item.code[0], 
                time=item.date[0], 
                amount=1000, 
                towards=QA.ORDER_DIRECTION.BUY, 
                price=0, 
                order_model=QA.ORDER_MODEL.CLOSE, 
                amount_model=QA.AMOUNT_MODEL.BY_AMOUNT
                )
            #print(item.to_json()[0])
            Broker.receive_order(QA.QA_Event(order=order,market_data=item))
            
            
            trade_mes=Broker.query_orders(Account.account_cookie,'filled')
            res=trade_mes.loc[order.account_cookie,order.realorder_id]
            order.trade(res.trade_id,res.trade_price,res.trade_amount,res.trade_time)
        elif daily_ind.CROSS_SC.iloc[0]>0:
            if Account.sell_available.get(item.code[0], 0)>0:
                order=Account.send_order(
                    code=item.code[0], 
                    time=item.date[0], 
                    amount=Account.sell_available.get(item.code[0], 0), 
                    towards=QA.ORDER_DIRECTION.SELL, 
                    price=0, 
                    order_model=QA.ORDER_MODEL.MARKET, 
                    amount_model=QA.AMOUNT_MODEL.BY_AMOUNT
                    )
                Broker.receive_order(QA.QA_Event(order=order,market_data=item))


                trade_mes=Broker.query_orders(Account.account_cookie,'filled')
                res=trade_mes.loc[order.account_cookie,order.realorder_id]
                order.trade(res.trade_id,res.trade_price,res.trade_amount,res.trade_time)
    Account.settle()
            
        #break
receive deal
receive deal
receive deal
receive deal
receive deal
receive deal
receive deal

STEP5: 分析账户

Account.history
[['2018-01-02 00:00:00',
  '000001',
  13.7,
  1000,
  186295.0,
  'Order_FemEzpZ0',
  'Order_FemEzpZ0',
  'Trade_TQzDbd0g',
  'JCSC_EXAMPLE',
  5,
  0,
  None],
 ['2018-01-03 00:00:00',
  '000001',
  13.53,
  -1000,
  199806.47,
  'Order_mnKfLY0M',
  'Order_mnKfLY0M',
  'Trade_ldhSrMYa',
  'JCSC_EXAMPLE',
  5,
  13.530000000000001,
  None],
 ['2018-01-12 00:00:00',
  '000001',
  13.55,
  1000,
  186251.47,
  'Order_nWrOyhV4',
  'Order_nWrOyhV4',
  'Trade_AkSzOM7i',
  'JCSC_EXAMPLE',
  5,
  0,
  None],
 ['2018-01-29 00:00:00',
  '000001',
  13.93,
  -1000,
  200162.54,
  'Order_ygQNXbEJ',
  'Order_ygQNXbEJ',
  'Trade_HW4C7STK',
  'JCSC_EXAMPLE',
  5,
  13.93,
  None],
 ['2018-03-08 00:00:00',
  '000001',
  12.11,
  1000,
  188047.54,
  'Order_osmdlg2w',
  'Order_osmdlg2w',
  'Trade_UpRMLDi9',
  'JCSC_EXAMPLE',
  5,
  0,
  None],
 ['2018-03-26 00:00:00',
  '000001',
  11.03,
  -1000,
  199061.51,
  'Order_07LT6nZE',
  'Order_07LT6nZE',
  'Trade_kQDMnIJH',
  'JCSC_EXAMPLE',
  5,
  11.03,
  None],
 ['2018-04-10 00:00:00',
  '000001',
  11.42,
  1000,
  187636.51,
  'Order_r9Mdl61s',
  'Order_r9Mdl61s',
  'Trade_zA7EdDj0',
  'JCSC_EXAMPLE',
  5,
  0,
  None]]
Account.history_table
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
datetime code price amount cash order_id realorder_id trade_id account_cookie commission tax message
0 2018-01-02 00:00:00 000001 13.70 1000 186295.00 Order_FemEzpZ0 Order_FemEzpZ0 Trade_TQzDbd0g JCSC_EXAMPLE 5 0.00 None
1 2018-01-03 00:00:00 000001 13.53 -1000 199806.47 Order_mnKfLY0M Order_mnKfLY0M Trade_ldhSrMYa JCSC_EXAMPLE 5 13.53 None
2 2018-01-12 00:00:00 000001 13.55 1000 186251.47 Order_nWrOyhV4 Order_nWrOyhV4 Trade_AkSzOM7i JCSC_EXAMPLE 5 0.00 None
3 2018-01-29 00:00:00 000001 13.93 -1000 200162.54 Order_ygQNXbEJ Order_ygQNXbEJ Trade_HW4C7STK JCSC_EXAMPLE 5 13.93 None
4 2018-03-08 00:00:00 000001 12.11 1000 188047.54 Order_osmdlg2w Order_osmdlg2w Trade_UpRMLDi9 JCSC_EXAMPLE 5 0.00 None
5 2018-03-26 00:00:00 000001 11.03 -1000 199061.51 Order_07LT6nZE Order_07LT6nZE Trade_kQDMnIJH JCSC_EXAMPLE 5 11.03 None
6 2018-04-10 00:00:00 000001 11.42 1000 187636.51 Order_r9Mdl61s Order_r9Mdl61s Trade_zA7EdDj0 JCSC_EXAMPLE 5 0.00 None
#pd.concat([Account.daily_hold.reset_index().set_index('date'),pd.Series(data=None,index=pd.to_datetime(Account.trade_range).set_names('date'),name='predrop')],axis=1).ffill().drop(['predrop'],axis=1).reset_index()
Account.daily_cash.cash.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x1fb242d8c88>

png

Account.daily_hold
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
000001
date account_cookie
2018-01-02 JCSC_EXAMPLE 1000.0
2018-01-03 JCSC_EXAMPLE 0.0
2018-01-04 JCSC_EXAMPLE 0.0
2018-01-05 JCSC_EXAMPLE 0.0
2018-01-08 JCSC_EXAMPLE 0.0
2018-01-09 JCSC_EXAMPLE 0.0
2018-01-10 JCSC_EXAMPLE 0.0
2018-01-11 JCSC_EXAMPLE 0.0
2018-01-12 JCSC_EXAMPLE 1000.0
2018-01-15 JCSC_EXAMPLE 1000.0
2018-01-16 JCSC_EXAMPLE 1000.0
2018-01-17 JCSC_EXAMPLE 1000.0
2018-01-18 JCSC_EXAMPLE 1000.0
2018-01-19 JCSC_EXAMPLE 1000.0
2018-01-22 JCSC_EXAMPLE 1000.0
2018-01-23 JCSC_EXAMPLE 1000.0
2018-01-24 JCSC_EXAMPLE 1000.0
2018-01-25 JCSC_EXAMPLE 1000.0
2018-01-26 JCSC_EXAMPLE 1000.0
2018-01-29 JCSC_EXAMPLE 0.0
2018-01-30 JCSC_EXAMPLE 0.0
2018-01-31 JCSC_EXAMPLE 0.0
2018-02-01 JCSC_EXAMPLE 0.0
2018-02-02 JCSC_EXAMPLE 0.0
2018-02-05 JCSC_EXAMPLE 0.0
2018-02-06 JCSC_EXAMPLE 0.0
2018-02-07 JCSC_EXAMPLE 0.0
2018-02-08 JCSC_EXAMPLE 0.0
2018-02-09 JCSC_EXAMPLE 0.0
2018-02-12 JCSC_EXAMPLE 0.0
... ... ...
2018-02-26 JCSC_EXAMPLE 0.0
2018-02-27 JCSC_EXAMPLE 0.0
2018-02-28 JCSC_EXAMPLE 0.0
2018-03-01 JCSC_EXAMPLE 0.0
2018-03-02 JCSC_EXAMPLE 0.0
2018-03-05 JCSC_EXAMPLE 0.0
2018-03-06 JCSC_EXAMPLE 0.0
2018-03-07 JCSC_EXAMPLE 0.0
2018-03-08 JCSC_EXAMPLE 1000.0
2018-03-09 JCSC_EXAMPLE 1000.0
2018-03-12 JCSC_EXAMPLE 1000.0
2018-03-13 JCSC_EXAMPLE 1000.0
2018-03-14 JCSC_EXAMPLE 1000.0
2018-03-15 JCSC_EXAMPLE 1000.0
2018-03-16 JCSC_EXAMPLE 1000.0
2018-03-19 JCSC_EXAMPLE 1000.0
2018-03-20 JCSC_EXAMPLE 1000.0
2018-03-21 JCSC_EXAMPLE 1000.0
2018-03-22 JCSC_EXAMPLE 1000.0
2018-03-23 JCSC_EXAMPLE 1000.0
2018-03-26 JCSC_EXAMPLE 0.0
2018-03-27 JCSC_EXAMPLE 0.0
2018-03-28 JCSC_EXAMPLE 0.0
2018-03-29 JCSC_EXAMPLE 0.0
2018-03-30 JCSC_EXAMPLE 0.0
2018-04-02 JCSC_EXAMPLE 0.0
2018-04-03 JCSC_EXAMPLE 0.0
2018-04-04 JCSC_EXAMPLE 0.0
2018-04-09 JCSC_EXAMPLE 0.0
2018-04-10 JCSC_EXAMPLE 1000.0

64 rows × 1 columns

Risk=QA.QA_Risk(Account)
Risk.message
{'account_cookie': 'JCSC_EXAMPLE',
 'portfolio_cookie': None,
 'user_cookie': None,
 'annualize_return': -0.02,
 'profit': -0.0,
 'max_dropback': 0.01,
 'time_gap': 64,
 'volatility': 0.01,
 'benchmark_code': '000300',
 'bm_annualizereturn': -0.15,
 'bm_profit': -0.03,
 'beta': 1.0,
 'alpha': 0.13,
 'sharpe': -7.0,
 'init_cash': '200000.00',
 'last_assets': '199056.51',
 'total_tax': -38.49,
 'total_commission': -35.0,
 'profit_money': -943.49,
 'assets': [199995.0,
  199806.47,
  199806.47,
  199806.47,
  199806.47,
  199806.47,
  199806.47,
  199806.47,
  199801.47,
  200451.47,
  200451.47,
  200481.47,
  200971.47,
  201051.47,
  200691.47,
  200901.47,
  200891.47,
  200451.47,
  200301.47,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200162.54,
  200157.54,
  200137.54,
  200077.54,
  200067.54,
  199967.54,
  199757.54,
  199687.54,
  199877.54,
  199867.54,
  199947.54,
  199707.54,
  199387.54,
  199061.51,
  199061.51,
  199061.51,
  199061.51,
  199061.51,
  199061.51,
  199061.51,
  199061.51,
  199061.51,
  199056.51],
 'benchmark_assets': [202085.92384573357,
  203272.01801636998,
  204133.28356253446,
  204624.72900047217,
  205683.26489848486,
  207123.98120245922,
  208039.13764674764,
  207929.37820286216,
  208889.03171899606,
  208900.89760482148,
  210543.82837973803,
  210032.11205351513,
  211184.09180240333,
  211875.27965173626,
  214406.66862783392,
  216681.45782295603,
  217041.38969299494,
  215814.7537457882,
  216616.6898628254,
  212696.99224514925,
  210426.65275721162,
  211405.58833781187,
  209922.35260962966,
  211174.69797612482,
  211319.06625366793,
  205126.0626765978,
  200261.54390006946,
  198360.53010844925,
  189886.30998143484,
  192331.17687338853,
  194582.23429685974,
  196131.22680899137,
  200371.79775586433,
  201279.53802151186,
  203619.58958867402,
  200680.80519923565,
  198933.55351143697,
  200191.83182084493,
  198578.56576049206,
  198659.64931363266,
  201055.56942655632,
  199576.78340555867,
  201601.4001745274,
  203147.42621520266,
  204076.92060486352,
  202276.2724308503,
  201390.78070112554,
  202519.02867836278,
  200554.23575043076,
  201435.7721848804,
  201606.34429362134,
  200783.1484644802,
  198770.89199324633,
  193064.88414692934,
  191826.38231389716,
  193476.7292674546,
  189988.6532466794,
  192526.4695775992,
  192746.48287727954,
  192173.95388620123,
  190965.61117964212,
  190588.86930468382,
  190493.44780617073,
  194163.96182151238],
 'timeindex': ['2018-01-02',
  '2018-01-03',
  '2018-01-12',
  '2018-01-29',
  '2018-03-08',
  '2018-03-26',
  '2018-04-10'],
 'totaltimeindex': ['2018-01-02',
  '2018-01-03',
  '2018-01-04',
  '2018-01-05',
  '2018-01-08',
  '2018-01-09',
  '2018-01-10',
  '2018-01-11',
  '2018-01-12',
  '2018-01-15',
  '2018-01-16',
  '2018-01-17',
  '2018-01-18',
  '2018-01-19',
  '2018-01-22',
  '2018-01-23',
  '2018-01-24',
  '2018-01-25',
  '2018-01-26',
  '2018-01-29',
  '2018-01-30',
  '2018-01-31',
  '2018-02-01',
  '2018-02-02',
  '2018-02-05',
  '2018-02-06',
  '2018-02-07',
  '2018-02-08',
  '2018-02-09',
  '2018-02-12',
  '2018-02-13',
  '2018-02-14',
  '2018-02-22',
  '2018-02-23',
  '2018-02-26',
  '2018-02-27',
  '2018-02-28',
  '2018-03-01',
  '2018-03-02',
  '2018-03-05',
  '2018-03-06',
  '2018-03-07',
  '2018-03-08',
  '2018-03-09',
  '2018-03-12',
  '2018-03-13',
  '2018-03-14',
  '2018-03-15',
  '2018-03-16',
  '2018-03-19',
  '2018-03-20',
  '2018-03-21',
  '2018-03-22',
  '2018-03-23',
  '2018-03-26',
  '2018-03-27',
  '2018-03-28',
  '2018-03-29',
  '2018-03-30',
  '2018-04-02',
  '2018-04-03',
  '2018-04-04',
  '2018-04-09',
  '2018-04-10'],
 'ir': -2.0}
Risk.market_value.diff().iloc[-1]
code
000001    11420.0
Name: (2018-04-10 00:00:00, JCSC_EXAMPLE), dtype: float64
Risk.account.cash_table
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
cash datetime date account_cookie
datetime account_cookie
2018-01-02 00:00:00 JCSC_EXAMPLE 186295 2018-01-02 00:00:00 2018-01-02 JCSC_EXAMPLE
2018-01-03 00:00:00 JCSC_EXAMPLE 199806 2018-01-03 00:00:00 2018-01-03 JCSC_EXAMPLE
2018-01-12 00:00:00 JCSC_EXAMPLE 186251 2018-01-12 00:00:00 2018-01-12 JCSC_EXAMPLE
2018-01-29 00:00:00 JCSC_EXAMPLE 200163 2018-01-29 00:00:00 2018-01-29 JCSC_EXAMPLE
2018-03-08 00:00:00 JCSC_EXAMPLE 188048 2018-03-08 00:00:00 2018-03-08 JCSC_EXAMPLE
2018-03-26 00:00:00 JCSC_EXAMPLE 199062 2018-03-26 00:00:00 2018-03-26 JCSC_EXAMPLE
2018-04-10 00:00:00 JCSC_EXAMPLE 187637 2018-04-10 00:00:00 2018-04-10 JCSC_EXAMPLE
z=Account.cash_table.drop_duplicates(subset='date', keep='last').set_index(['date', 'account_cookie'], drop=False)
res=Account.cash_table.drop_duplicates(subset='date', keep='last')

zx=pd.concat([res.set_index('date'),pd.Series(data=None,index=pd.to_datetime(Account.trade_range),name='predrop')],axis=1).ffill().drop(['predrop'],axis=1)
zxx=pd.to_datetime(Account.trade_range)
zxx.set_names('date')
DatetimeIndex(['2018-01-02', '2018-01-03', '2018-01-04', '2018-01-05',
               '2018-01-08', '2018-01-09', '2018-01-10', '2018-01-11',
               '2018-01-12', '2018-01-15', '2018-01-16', '2018-01-17',
               '2018-01-18', '2018-01-19', '2018-01-22', '2018-01-23',
               '2018-01-24', '2018-01-25', '2018-01-26', '2018-01-29',
               '2018-01-30', '2018-01-31', '2018-02-01', '2018-02-02',
               '2018-02-05', '2018-02-06', '2018-02-07', '2018-02-08',
               '2018-02-09', '2018-02-12', '2018-02-13', '2018-02-14',
               '2018-02-22', '2018-02-23', '2018-02-26', '2018-02-27',
               '2018-02-28', '2018-03-01', '2018-03-02', '2018-03-05',
               '2018-03-06', '2018-03-07', '2018-03-08', '2018-03-09',
               '2018-03-12', '2018-03-13', '2018-03-14', '2018-03-15',
               '2018-03-16', '2018-03-19', '2018-03-20', '2018-03-21',
               '2018-03-22', '2018-03-23', '2018-03-26', '2018-03-27',
               '2018-03-28', '2018-03-29', '2018-03-30', '2018-04-02',
               '2018-04-03', '2018-04-04', '2018-04-09', '2018-04-10'],
              dtype='datetime64[ns]', name='date', freq=None)
Account.daily_hold.index.levels[0]
DatetimeIndex(['2018-01-02', '2018-01-03', '2018-01-04', '2018-01-05',
               '2018-01-08', '2018-01-09', '2018-01-10', '2018-01-11',
               '2018-01-12', '2018-01-15', '2018-01-16', '2018-01-17',
               '2018-01-18', '2018-01-19', '2018-01-22', '2018-01-23',
               '2018-01-24', '2018-01-25', '2018-01-26', '2018-01-29',
               '2018-01-30', '2018-01-31', '2018-02-01', '2018-02-02',
               '2018-02-05', '2018-02-06', '2018-02-07', '2018-02-08',
               '2018-02-09', '2018-02-12', '2018-02-13', '2018-02-14',
               '2018-02-22', '2018-02-23', '2018-02-26', '2018-02-27',
               '2018-02-28', '2018-03-01', '2018-03-02', '2018-03-05',
               '2018-03-06', '2018-03-07', '2018-03-08', '2018-03-09',
               '2018-03-12', '2018-03-13', '2018-03-14', '2018-03-15',
               '2018-03-16', '2018-03-19', '2018-03-20', '2018-03-21',
               '2018-03-22', '2018-03-23', '2018-03-26', '2018-03-27',
               '2018-03-28', '2018-03-29', '2018-03-30', '2018-04-02',
               '2018-04-03', '2018-04-04', '2018-04-09', '2018-04-10'],
              dtype='datetime64[ns]', name='date', freq=None)
#pd.Series(data=None,index=Account.trade_range,name='date')
Risk.market_value.sum(axis=1)
date        account_cookie
2018-01-02  JCSC_EXAMPLE      13700.0
2018-01-03  JCSC_EXAMPLE          0.0
2018-01-04  JCSC_EXAMPLE          0.0
2018-01-05  JCSC_EXAMPLE          0.0
2018-01-08  JCSC_EXAMPLE          0.0
2018-01-09  JCSC_EXAMPLE          0.0
2018-01-10  JCSC_EXAMPLE          0.0
2018-01-11  JCSC_EXAMPLE          0.0
2018-01-12  JCSC_EXAMPLE      13550.0
2018-01-15  JCSC_EXAMPLE      14200.0
2018-01-16  JCSC_EXAMPLE      14200.0
2018-01-17  JCSC_EXAMPLE      14230.0
2018-01-18  JCSC_EXAMPLE      14720.0
2018-01-19  JCSC_EXAMPLE      14800.0
2018-01-22  JCSC_EXAMPLE      14440.0
2018-01-23  JCSC_EXAMPLE      14650.0
2018-01-24  JCSC_EXAMPLE      14640.0
2018-01-25  JCSC_EXAMPLE      14200.0
2018-01-26  JCSC_EXAMPLE      14050.0
2018-01-29  JCSC_EXAMPLE          0.0
2018-01-30  JCSC_EXAMPLE          0.0
2018-01-31  JCSC_EXAMPLE          0.0
2018-02-01  JCSC_EXAMPLE          0.0
2018-02-02  JCSC_EXAMPLE          0.0
2018-02-05  JCSC_EXAMPLE          0.0
2018-02-06  JCSC_EXAMPLE          0.0
2018-02-07  JCSC_EXAMPLE          0.0
2018-02-08  JCSC_EXAMPLE          0.0
2018-02-09  JCSC_EXAMPLE          0.0
2018-02-12  JCSC_EXAMPLE          0.0
                               ...   
2018-02-26  JCSC_EXAMPLE          0.0
2018-02-27  JCSC_EXAMPLE          0.0
2018-02-28  JCSC_EXAMPLE          0.0
2018-03-01  JCSC_EXAMPLE          0.0
2018-03-02  JCSC_EXAMPLE          0.0
2018-03-05  JCSC_EXAMPLE          0.0
2018-03-06  JCSC_EXAMPLE          0.0
2018-03-07  JCSC_EXAMPLE          0.0
2018-03-08  JCSC_EXAMPLE      12110.0
2018-03-09  JCSC_EXAMPLE      12090.0
2018-03-12  JCSC_EXAMPLE      12030.0
2018-03-13  JCSC_EXAMPLE      12020.0
2018-03-14  JCSC_EXAMPLE      11920.0
2018-03-15  JCSC_EXAMPLE      11710.0
2018-03-16  JCSC_EXAMPLE      11640.0
2018-03-19  JCSC_EXAMPLE      11830.0
2018-03-20  JCSC_EXAMPLE      11820.0
2018-03-21  JCSC_EXAMPLE      11900.0
2018-03-22  JCSC_EXAMPLE      11660.0
2018-03-23  JCSC_EXAMPLE      11340.0
2018-03-26  JCSC_EXAMPLE          0.0
2018-03-27  JCSC_EXAMPLE          0.0
2018-03-28  JCSC_EXAMPLE          0.0
2018-03-29  JCSC_EXAMPLE          0.0
2018-03-30  JCSC_EXAMPLE          0.0
2018-04-02  JCSC_EXAMPLE          0.0
2018-04-03  JCSC_EXAMPLE          0.0
2018-04-04  JCSC_EXAMPLE          0.0
2018-04-09  JCSC_EXAMPLE          0.0
2018-04-10  JCSC_EXAMPLE      11420.0
Length: 64, dtype: float64
Account.history_table
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
datetime code price amount cash order_id realorder_id trade_id account_cookie commission tax message
0 2018-01-02 00:00:00 000001 13.70 1000 186295.00 Order_FemEzpZ0 Order_FemEzpZ0 Trade_TQzDbd0g JCSC_EXAMPLE 5 0.00 None
1 2018-01-03 00:00:00 000001 13.53 -1000 199806.47 Order_mnKfLY0M Order_mnKfLY0M Trade_ldhSrMYa JCSC_EXAMPLE 5 13.53 None
2 2018-01-12 00:00:00 000001 13.55 1000 186251.47 Order_nWrOyhV4 Order_nWrOyhV4 Trade_AkSzOM7i JCSC_EXAMPLE 5 0.00 None
3 2018-01-29 00:00:00 000001 13.93 -1000 200162.54 Order_ygQNXbEJ Order_ygQNXbEJ Trade_HW4C7STK JCSC_EXAMPLE 5 13.93 None
4 2018-03-08 00:00:00 000001 12.11 1000 188047.54 Order_osmdlg2w Order_osmdlg2w Trade_UpRMLDi9 JCSC_EXAMPLE 5 0.00 None
5 2018-03-26 00:00:00 000001 11.03 -1000 199061.51 Order_07LT6nZE Order_07LT6nZE Trade_kQDMnIJH JCSC_EXAMPLE 5 11.03 None
6 2018-04-10 00:00:00 000001 11.42 1000 187636.51 Order_r9Mdl61s Order_r9Mdl61s Trade_zA7EdDj0 JCSC_EXAMPLE 5 0.00 None
Account.cash_table
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
cash datetime date account_cookie
datetime account_cookie
2018-01-02 00:00:00 JCSC_EXAMPLE 186295 2018-01-02 00:00:00 2018-01-02 JCSC_EXAMPLE
2018-01-03 00:00:00 JCSC_EXAMPLE 199806 2018-01-03 00:00:00 2018-01-03 JCSC_EXAMPLE
2018-01-12 00:00:00 JCSC_EXAMPLE 186251 2018-01-12 00:00:00 2018-01-12 JCSC_EXAMPLE
2018-01-29 00:00:00 JCSC_EXAMPLE 200163 2018-01-29 00:00:00 2018-01-29 JCSC_EXAMPLE
2018-03-08 00:00:00 JCSC_EXAMPLE 188048 2018-03-08 00:00:00 2018-03-08 JCSC_EXAMPLE
2018-03-26 00:00:00 JCSC_EXAMPLE 199062 2018-03-26 00:00:00 2018-03-26 JCSC_EXAMPLE
2018-04-10 00:00:00 JCSC_EXAMPLE 187637 2018-04-10 00:00:00 2018-04-10 JCSC_EXAMPLE
Risk.assets
date
2018-01-02    199995.00
2018-01-03    199806.47
2018-01-04    199806.47
2018-01-05    199806.47
2018-01-08    199806.47
2018-01-09    199806.47
2018-01-10    199806.47
2018-01-11    199806.47
2018-01-12    199801.47
2018-01-15    200451.47
2018-01-16    200451.47
2018-01-17    200481.47
2018-01-18    200971.47
2018-01-19    201051.47
2018-01-22    200691.47
2018-01-23    200901.47
2018-01-24    200891.47
2018-01-25    200451.47
2018-01-26    200301.47
2018-01-29    200162.54
2018-01-30    200162.54
2018-01-31    200162.54
2018-02-01    200162.54
2018-02-02    200162.54
2018-02-05    200162.54
2018-02-06    200162.54
2018-02-07    200162.54
2018-02-08    200162.54
2018-02-09    200162.54
2018-02-12    200162.54
                ...    
2018-02-26    200162.54
2018-02-27    200162.54
2018-02-28    200162.54
2018-03-01    200162.54
2018-03-02    200162.54
2018-03-05    200162.54
2018-03-06    200162.54
2018-03-07    200162.54
2018-03-08    200157.54
2018-03-09    200137.54
2018-03-12    200077.54
2018-03-13    200067.54
2018-03-14    199967.54
2018-03-15    199757.54
2018-03-16    199687.54
2018-03-19    199877.54
2018-03-20    199867.54
2018-03-21    199947.54
2018-03-22    199707.54
2018-03-23    199387.54
2018-03-26    199061.51
2018-03-27    199061.51
2018-03-28    199061.51
2018-03-29    199061.51
2018-03-30    199061.51
2018-04-02    199061.51
2018-04-03    199061.51
2018-04-04    199061.51
2018-04-09    199061.51
2018-04-10    199056.51
Name: 0, Length: 64, dtype: float64
Risk.assets.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x1fb25356160>

png

Risk.benchmark_assets.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x1fb257f74a8>

png

Risk.plot_assets_curve()
<module 'matplotlib.pyplot' from 'C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\pyplot.py'>

png

Risk.plot_dailyhold()
<module 'matplotlib.pyplot' from 'C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\pyplot.py'>

png

Risk.plot_signal()
<module 'matplotlib.pyplot' from 'C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\pyplot.py'>

png

Risk.profit_construct
{'total_buyandsell': -870.0,
 'total_tax': -38.49,
 'total_commission': -35.0,
 'total_profit': -943.49}
Performance=QA.QA_Performance(Account)
Performance.pnl_fifo
<style scoped> .dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
</style>
sell_date buy_date amount sell_price buy_price pnl_ratio pnl_money
code
000001 2018-01-03 2018-01-02 1000 13.53 13.70 -0.012409 -170.0
000001 2018-01-29 2018-01-12 1000 13.93 13.55 0.028044 380.0
000001 2018-03-26 2018-03-08 1000 11.03 12.11 -0.089182 -1080.0
Performance.plot_pnlmoney(Performance.pnl_fifo)
<module 'matplotlib.pyplot' from 'C:\\ProgramData\\Anaconda3\\lib\\site-packages\\matplotlib\\pyplot.py'>

png

STEP6: 存储结果

Account.save()
Risk.save()

STEP7: 查看存储的结果

account_info=QA.QA_fetch_account({'account_cookie':'JCSC_EXAMPLE'})
account=QA.QA_Account().from_message(account_info[0])
account
< QA_Account JCSC_EXAMPLE>