DYAMS 0.4__py3-none-any.whl → 0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- DYAMS/__init__.py +24 -0
- DYAMS/api/get_post_investment_product_asset_allocation.py +57 -0
- DYAMS/api/get_post_investment_product_holdings.py +176 -0
- DYAMS/api/get_post_investment_product_list.py +5 -15
- DYAMS/api/get_post_investment_product_net.py +40 -0
- DYAMS/api/get_post_investment_product_performance_indicators.py +47 -0
- DYAMS/api/get_private_asset_net.py +42 -0
- DYAMS/api/heartbeat.py +13 -0
- DYAMS/api/util.py +10 -0
- DYAMS/client.py +20 -14
- DYAMS/enums.py +78 -0
- {dyams-0.4.dist-info → dyams-0.6.dist-info}/METADATA +2 -9
- dyams-0.6.dist-info/RECORD +17 -0
- {dyams-0.4.dist-info → dyams-0.6.dist-info}/WHEEL +1 -1
- DYAMS/api/get_portfolio_holdings.py +0 -77
- dyams-0.4.dist-info/RECORD +0 -10
- {dyams-0.4.dist-info → dyams-0.6.dist-info}/licenses/LICENSE +0 -0
- {dyams-0.4.dist-info → dyams-0.6.dist-info}/top_level.txt +0 -0
DYAMS/__init__.py
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
1
|
from .client import Client
|
|
2
2
|
|
|
3
3
|
__all__ = ['Client']
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_post_investment_product_list(*args, **kwargs):
|
|
7
|
+
return Client.get_instance().get_post_investment_product_list(*args, **kwargs)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_post_investment_product_holdings(*args, **kwargs):
|
|
11
|
+
return Client.get_instance().get_post_investment_product_holdings(*args, **kwargs)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_post_investment_product_performance_indicators(*args, **kwargs):
|
|
15
|
+
return Client.get_instance().get_post_investment_product_performance_indicators(*args, **kwargs)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_post_investment_product_net(*args, **kwargs):
|
|
19
|
+
return Client.get_instance().get_post_investment_product_net(*args, **kwargs)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_post_investment_product_asset_allocation(*args, **kwargs):
|
|
23
|
+
return Client.get_instance().get_post_investment_product_asset_allocation(*args, **kwargs)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_private_asset_net(*args, **kwargs):
|
|
27
|
+
return Client.get_instance().get_private_asset_net(*args, **kwargs)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from .util import get_response_json_with_check
|
|
4
|
+
from ..enums import PenetrateType, WeightType
|
|
5
|
+
|
|
6
|
+
field_mapping = {
|
|
7
|
+
'date': 'date',
|
|
8
|
+
'assetCategory': 'asset_type',
|
|
9
|
+
'weight': 'weight',
|
|
10
|
+
'marketValue': 'position_market_value'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_post_investment_product_asset_allocation(client,
|
|
15
|
+
post_investment_product_id,
|
|
16
|
+
start_date=None,
|
|
17
|
+
end_date=None,
|
|
18
|
+
date=None,
|
|
19
|
+
asset_class="交易属性",
|
|
20
|
+
look_through=PenetrateType.NO_PENETRATE,
|
|
21
|
+
level=1,
|
|
22
|
+
weight_types=WeightType.TOTAL_FILTERED,
|
|
23
|
+
asset_sceening=[]):
|
|
24
|
+
|
|
25
|
+
if date:
|
|
26
|
+
start_date = date
|
|
27
|
+
end_date = date
|
|
28
|
+
elif not start_date or not end_date:
|
|
29
|
+
raise ValueError("start_date and end_date are required")
|
|
30
|
+
|
|
31
|
+
url = f"{client.base_url}/lib/portfolio/v1/positionDistribution"
|
|
32
|
+
data = {
|
|
33
|
+
'accountCode': post_investment_product_id,
|
|
34
|
+
'startDate': start_date,
|
|
35
|
+
'endDate': end_date,
|
|
36
|
+
'penetrateWay': look_through.name if look_through else PenetrateType.NO_PENETRATE,
|
|
37
|
+
'level': level,
|
|
38
|
+
'assetCategoryName': asset_class,
|
|
39
|
+
'ratioAssetType': weight_types.name if weight_types else WeightType.TOTAL_FILTERED,
|
|
40
|
+
'securityTypes': [security_type.name for security_type in asset_sceening]
|
|
41
|
+
}
|
|
42
|
+
headers = client.get_headers()
|
|
43
|
+
try:
|
|
44
|
+
response = requests.post(url, headers=headers, json=data)
|
|
45
|
+
r = get_response_json_with_check(response)
|
|
46
|
+
|
|
47
|
+
rows = []
|
|
48
|
+
for item in r.get('list'):
|
|
49
|
+
row = {}
|
|
50
|
+
for api_field, our_field in field_mapping.items():
|
|
51
|
+
row[our_field] = item.get(api_field, None)
|
|
52
|
+
rows.append(row)
|
|
53
|
+
|
|
54
|
+
df = pd.DataFrame(rows)
|
|
55
|
+
return df
|
|
56
|
+
except Exception as e:
|
|
57
|
+
raise e
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from .util import get_response_json_with_check
|
|
4
|
+
from ..enums import PenetrateType, PositionField
|
|
5
|
+
|
|
6
|
+
default_fields = [
|
|
7
|
+
'assetCategory',
|
|
8
|
+
'date',
|
|
9
|
+
'assetName',
|
|
10
|
+
'assetCode',
|
|
11
|
+
'securityType',
|
|
12
|
+
'exchangeCd',
|
|
13
|
+
'netPrice',
|
|
14
|
+
'aiRate',
|
|
15
|
+
'chg',
|
|
16
|
+
'amount',
|
|
17
|
+
'marketValueLocal',
|
|
18
|
+
'weight',
|
|
19
|
+
'dailyProfitValueLocal',
|
|
20
|
+
'dailyProfitRate',
|
|
21
|
+
'floatingProfitValueLocal',
|
|
22
|
+
'floatingProfitRate',
|
|
23
|
+
'cumulativeProfitValueLocal',
|
|
24
|
+
'cumulativeProfitRate',
|
|
25
|
+
'totalBuyCostLocal',
|
|
26
|
+
'realizedAiLocal',
|
|
27
|
+
'realizedProfitValueLocal',
|
|
28
|
+
'channel',
|
|
29
|
+
'positionTime'
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
field_enum_mapping = {
|
|
33
|
+
PositionField.CLASS: 'assetCategory',
|
|
34
|
+
PositionField.DATE: 'date',
|
|
35
|
+
PositionField.ASSET_NAME: 'assetName',
|
|
36
|
+
PositionField.ASSET_CODE: 'assetCode',
|
|
37
|
+
PositionField.SECURITY_TYPE: 'securityType',
|
|
38
|
+
PositionField.TRADING_MARKET: 'exchangeCd',
|
|
39
|
+
PositionField.CURRENT_CLEAN_PRICE: 'netPrice',
|
|
40
|
+
PositionField.ACCRUED_INTEREST: 'aiRate',
|
|
41
|
+
PositionField.PRICE_CHANGE: 'chg',
|
|
42
|
+
PositionField.POSITION_QUANTITY: 'amount',
|
|
43
|
+
PositionField.POSITION_MARKET_VALUE: 'marketValueLocal',
|
|
44
|
+
PositionField.POSITION_WEIGHT_NET_ASSETS: 'weight',
|
|
45
|
+
PositionField.DAILY_PROFIT_LOSS: 'dailyProfitValueLocal',
|
|
46
|
+
PositionField.DAILY_PROFIT_LOSS_RATE: 'dailyProfitRate',
|
|
47
|
+
PositionField.FLOATING_PROFIT_LOSS: 'floatingProfitValueLocal',
|
|
48
|
+
PositionField.FLOATING_PROFIT_LOSS_RATE: 'floatingProfitRate',
|
|
49
|
+
PositionField.CUMULATIVE_PROFIT_LOSS: 'cumulativeProfitValueLocal',
|
|
50
|
+
PositionField.CUMULATIVE_PROFIT_LOSS_RATE: 'cumulativeProfitRate',
|
|
51
|
+
PositionField.POSITION_COST: 'totalBuyCostLocal',
|
|
52
|
+
PositionField.INTEREST_INCOME: 'realizedAiLocal',
|
|
53
|
+
PositionField.REALIZED_PROFIT_LOSS: 'realizedProfitValueLocal',
|
|
54
|
+
PositionField.MATURITY_DATE: 'dueDate',
|
|
55
|
+
PositionField.TRADING_CHANNEL: 'channel',
|
|
56
|
+
PositionField.POSITION_DIRECTION: 'direction',
|
|
57
|
+
PositionField.LATEST_PRICE: 'price',
|
|
58
|
+
PositionField.POSITION_WEIGHT_TOTAL_ASSETS: 'weightTotal',
|
|
59
|
+
PositionField.POSITION_WEIGHT_TOTAL_COST: 'weightCost',
|
|
60
|
+
PositionField.COST_PRICE: 'buyCost',
|
|
61
|
+
PositionField.AMORTIZED_COST: 'cost',
|
|
62
|
+
PositionField.VALUATION_EXCHANGE_RATE: 'fxRate',
|
|
63
|
+
PositionField.MARKET_QUOTATION_TIME: 'positionTime',
|
|
64
|
+
PositionField.POSITION_BUILDING_DATE: 'holdDate',
|
|
65
|
+
PositionField.ISSUING_ENTITY: 'partyFullName',
|
|
66
|
+
PositionField.REMAINING_MATURITY: 'yearToMaturity',
|
|
67
|
+
PositionField.BOND_RATING_AGENCY: 'nominalRatingInst',
|
|
68
|
+
PositionField.BOND_RATING: 'nominalRating',
|
|
69
|
+
PositionField.MARGIN_REQUIREMENT: 'margin',
|
|
70
|
+
PositionField.CITY: 'city',
|
|
71
|
+
PositionField.PROVINCE: 'province',
|
|
72
|
+
PositionField.ISSUER_RATING_YY: 'instRatingYY',
|
|
73
|
+
PositionField.ISSUER_RATING_DATE: 'instRatingDate',
|
|
74
|
+
PositionField.ISSUER_RATING: 'instRating',
|
|
75
|
+
PositionField.BOND_RATING_DATE: 'nominalRatingDate',
|
|
76
|
+
PositionField.ISSUER_RATING_AGENCY: 'instRatingInst'
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
field_mapping = {
|
|
80
|
+
'assetCategory': 'class',
|
|
81
|
+
'date': 'date',
|
|
82
|
+
'assetName': 'asset_name',
|
|
83
|
+
'assetCode': 'asset_code',
|
|
84
|
+
'securityType': 'security_type',
|
|
85
|
+
'exchangeCd': 'trading_market',
|
|
86
|
+
'netPrice': 'current_clean_price',
|
|
87
|
+
'aiRate': 'accrued_interest',
|
|
88
|
+
'chg': 'price_change',
|
|
89
|
+
'amount': 'position_quantity',
|
|
90
|
+
'marketValueLocal': 'position_market_value',
|
|
91
|
+
'weight': 'position_weight_(net_assets)',
|
|
92
|
+
'dailyProfitValueLocal': 'daily_profit_loss',
|
|
93
|
+
'dailyProfitRate': 'daily_profit_loss_rate',
|
|
94
|
+
'floatingProfitValueLocal': 'floating_profit_loss',
|
|
95
|
+
'floatingProfitRate': 'floating_profit_loss_rate',
|
|
96
|
+
'cumulativeProfitValueLocal': 'cumulative_profit_loss',
|
|
97
|
+
'cumulativeProfitRate': 'cumulative_profit_loss_rate',
|
|
98
|
+
'totalBuyCostLocal': 'position_cost',
|
|
99
|
+
'realizedAiLocal': 'interest_income',
|
|
100
|
+
'realizedProfitValueLocal': 'realized_profit_loss',
|
|
101
|
+
'dueDate': 'maturity_date',
|
|
102
|
+
'channel': 'trading_channel',
|
|
103
|
+
'direction': 'position_direction',
|
|
104
|
+
'price': 'latest_price',
|
|
105
|
+
'weightTotal': 'position_weight_(total_assets)',
|
|
106
|
+
'weightCost': 'position_weight_(total_cost)',
|
|
107
|
+
'buyCost': 'cost_price',
|
|
108
|
+
'cost': 'amortized_cost',
|
|
109
|
+
'fxRate': 'valuation_exchange_rate',
|
|
110
|
+
'positionTime': 'market_quotation_time',
|
|
111
|
+
'holdDate': 'position_building_date',
|
|
112
|
+
'partyFullName': 'issuing_entity',
|
|
113
|
+
'yearToMaturity': 'remaining_maturity',
|
|
114
|
+
'nominalRatingInst': 'bond_rating_agency',
|
|
115
|
+
'nominalRating': 'bond_rating',
|
|
116
|
+
'margin': 'margin_requirement',
|
|
117
|
+
'city': 'city',
|
|
118
|
+
'province': 'province',
|
|
119
|
+
'instRatingYY': 'issuer_rating_(YY)',
|
|
120
|
+
'instRatingDate': 'issuer_rating_date',
|
|
121
|
+
'instRating': 'issuer_rating',
|
|
122
|
+
'nominalRatingDate': 'bond_rating_date',
|
|
123
|
+
'instRatingInst': 'issuer_rating_agency'
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def get_post_investment_product_holdings(client,
|
|
128
|
+
post_investment_product_id,
|
|
129
|
+
start_date=None,
|
|
130
|
+
end_date=None,
|
|
131
|
+
date=None,
|
|
132
|
+
asset_class="交易属性",
|
|
133
|
+
look_through=PenetrateType.NO_PENETRATE,
|
|
134
|
+
level=1,
|
|
135
|
+
fields=[]):
|
|
136
|
+
|
|
137
|
+
if date:
|
|
138
|
+
start_date = date
|
|
139
|
+
end_date = date
|
|
140
|
+
elif not start_date or not end_date:
|
|
141
|
+
raise ValueError("start_date and end_date are required")
|
|
142
|
+
|
|
143
|
+
url = f"{client.base_url}/lib/portfolio/v1/position"
|
|
144
|
+
data = {
|
|
145
|
+
'accountCode': post_investment_product_id,
|
|
146
|
+
'startDate': start_date,
|
|
147
|
+
'endDate': end_date,
|
|
148
|
+
'penetrateWay': look_through.name if look_through else PenetrateType.NO_PENETRATE,
|
|
149
|
+
'level': level,
|
|
150
|
+
'assetCategoryName': asset_class
|
|
151
|
+
}
|
|
152
|
+
headers = client.get_headers()
|
|
153
|
+
try:
|
|
154
|
+
response = requests.post(url, headers=headers, json=data)
|
|
155
|
+
r = get_response_json_with_check(response)
|
|
156
|
+
|
|
157
|
+
if not fields:
|
|
158
|
+
fields = default_fields
|
|
159
|
+
else:
|
|
160
|
+
fields = default_fields + [
|
|
161
|
+
field_enum_mapping[field]
|
|
162
|
+
for field in fields
|
|
163
|
+
if field in field_enum_mapping
|
|
164
|
+
and field_enum_mapping[field] in field_mapping
|
|
165
|
+
and field_enum_mapping[field] not in default_fields
|
|
166
|
+
]
|
|
167
|
+
rows = []
|
|
168
|
+
for item in r.get('list'):
|
|
169
|
+
row = {}
|
|
170
|
+
for field in fields:
|
|
171
|
+
row[field_mapping[field]] = item.get(field, None)
|
|
172
|
+
rows.append(row)
|
|
173
|
+
df = pd.DataFrame(rows)
|
|
174
|
+
return df
|
|
175
|
+
except Exception as e:
|
|
176
|
+
raise e
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import requests
|
|
2
2
|
import pandas as pd
|
|
3
|
+
from .util import get_response_json_with_check
|
|
3
4
|
|
|
4
5
|
field_mapping = {
|
|
5
6
|
'accountName': 'post_investment_product_name', # 产品名称
|
|
@@ -14,7 +15,8 @@ field_mapping = {
|
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
|
|
17
|
-
def get_post_investment_product_list(client,
|
|
18
|
+
def get_post_investment_product_list(client,
|
|
19
|
+
post_investment_product_id=None):
|
|
18
20
|
|
|
19
21
|
url = f"{client.base_url}/lib/portfolio/v1/list"
|
|
20
22
|
headers = client.get_headers()
|
|
@@ -24,28 +26,16 @@ def get_post_investment_product_list(client, post_investment_product_id=None):
|
|
|
24
26
|
|
|
25
27
|
try:
|
|
26
28
|
response = requests.post(url, headers=headers, data=data)
|
|
27
|
-
|
|
28
|
-
response.raise_for_status()
|
|
29
|
-
r = response.json()
|
|
30
|
-
if r.get('code') == 'F00100':
|
|
31
|
-
raise ValueError('rate limit')
|
|
32
|
-
items = r.get('list')
|
|
29
|
+
r = get_response_json_with_check(response)
|
|
33
30
|
|
|
34
31
|
rows = []
|
|
35
|
-
for item in
|
|
32
|
+
for item in r.get('list'):
|
|
36
33
|
row = {}
|
|
37
34
|
for api_field, our_field in field_mapping.items():
|
|
38
35
|
row[our_field] = item.get(api_field, None)
|
|
39
36
|
rows.append(row)
|
|
40
37
|
|
|
41
38
|
df = pd.DataFrame(rows)
|
|
42
|
-
date_fields = ['establishment_date', 'NAV_start_date', 'latest_NAV_date']
|
|
43
|
-
for field in date_fields:
|
|
44
|
-
if field in df.columns:
|
|
45
|
-
try:
|
|
46
|
-
df[field] = pd.to_datetime(df[field], errors='coerce').dt.strftime('%Y-%m-%d')
|
|
47
|
-
except Exception:
|
|
48
|
-
pass
|
|
49
39
|
return df
|
|
50
40
|
except Exception as e:
|
|
51
41
|
raise e
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from .util import get_response_json_with_check
|
|
4
|
+
|
|
5
|
+
field_mapping = {
|
|
6
|
+
'date': '净值日期',
|
|
7
|
+
'unitNav': '单位净值',
|
|
8
|
+
'accumNav': '累计净值',
|
|
9
|
+
'adjustNav': '复权净值'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_post_investment_product_net(client,
|
|
14
|
+
post_investment_product_id,
|
|
15
|
+
start_date,
|
|
16
|
+
end_date):
|
|
17
|
+
|
|
18
|
+
url = f"{client.base_url}/lib/portfolio/v1/nav"
|
|
19
|
+
headers = client.get_headers()
|
|
20
|
+
params = {
|
|
21
|
+
'accountCode': post_investment_product_id,
|
|
22
|
+
'startDate': start_date,
|
|
23
|
+
'endDate': end_date
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
response = requests.get(url, headers=headers, params=params)
|
|
28
|
+
r = get_response_json_with_check(response)
|
|
29
|
+
|
|
30
|
+
rows = []
|
|
31
|
+
for item in r.get('list'):
|
|
32
|
+
row = {}
|
|
33
|
+
for api_field, our_field in field_mapping.items():
|
|
34
|
+
row[our_field] = item.get(api_field, None)
|
|
35
|
+
rows.append(row)
|
|
36
|
+
|
|
37
|
+
df = pd.DataFrame(rows)
|
|
38
|
+
return df
|
|
39
|
+
except Exception as e:
|
|
40
|
+
raise e
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from .util import get_response_json_with_check
|
|
3
|
+
|
|
4
|
+
field_mapping = {
|
|
5
|
+
'accountCode': 'product_id',
|
|
6
|
+
'benchmark': 'benchmark',
|
|
7
|
+
'startDate': 'start_date',
|
|
8
|
+
'endDate': 'end_date',
|
|
9
|
+
'totalReturn': 'cumulative_return',
|
|
10
|
+
'activeReturn': 'active_return',
|
|
11
|
+
'latestWeekReturn': 'recent_week_return',
|
|
12
|
+
'thisWeekReturn': 'weekly_return',
|
|
13
|
+
'latestMonthReturn': 'recent_month_return',
|
|
14
|
+
'thisMonthReturn': 'monthly_return',
|
|
15
|
+
'ytdReturn': 'YTD_return',
|
|
16
|
+
'annualTotalReturn': 'annualized_total_return',
|
|
17
|
+
'annualActiveReturn': 'annualized_active_return',
|
|
18
|
+
'annualTotalRisk': 'annualized_total_risk',
|
|
19
|
+
'annualActiveRisk': 'annualized_active_risk',
|
|
20
|
+
'maxDrawdown': 'maximum_drawdown',
|
|
21
|
+
'sharpRatio': 'sharpe_ratio',
|
|
22
|
+
'infoRatio': 'information_ratio',
|
|
23
|
+
'sortinoRatio': 'sortino_ratio',
|
|
24
|
+
'calmarRatio': 'calmar_ratio'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_post_investment_product_performance_indicators(client,
|
|
29
|
+
post_investment_product_id):
|
|
30
|
+
|
|
31
|
+
url = f"{client.base_url}/lib/portfolio/v1/perf"
|
|
32
|
+
headers = client.get_headers()
|
|
33
|
+
params = {
|
|
34
|
+
'accountCode': post_investment_product_id
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
response = requests.get(url, headers=headers, params=params)
|
|
39
|
+
r = get_response_json_with_check(response)
|
|
40
|
+
|
|
41
|
+
data = {}
|
|
42
|
+
for item in r.get('data').keys():
|
|
43
|
+
data[item] = r.get('data').get(item)
|
|
44
|
+
|
|
45
|
+
return data
|
|
46
|
+
except Exception as e:
|
|
47
|
+
raise e
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from .util import get_response_json_with_check
|
|
4
|
+
|
|
5
|
+
field_mapping = {
|
|
6
|
+
'date': '净值日期',
|
|
7
|
+
'unitNav': '单位净值',
|
|
8
|
+
'accumNav': '累计净值',
|
|
9
|
+
'adjustNav': '复权净值'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_private_asset_net(client,
|
|
14
|
+
product_name=None,
|
|
15
|
+
product_code=None,
|
|
16
|
+
start_date=None,
|
|
17
|
+
end_date=None):
|
|
18
|
+
|
|
19
|
+
url = f"{client.base_url}/lib/asset/v1/nav"
|
|
20
|
+
headers = client.get_headers()
|
|
21
|
+
params = {
|
|
22
|
+
'accountCode': product_code,
|
|
23
|
+
'accountName': product_name,
|
|
24
|
+
'startDate': start_date,
|
|
25
|
+
'endDate': end_date
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
response = requests.get(url, headers=headers, params=params)
|
|
30
|
+
r = get_response_json_with_check(response)
|
|
31
|
+
|
|
32
|
+
rows = []
|
|
33
|
+
for item in r.get('list'):
|
|
34
|
+
row = {}
|
|
35
|
+
for api_field, our_field in field_mapping.items():
|
|
36
|
+
row[our_field] = item.get(api_field, None)
|
|
37
|
+
rows.append(row)
|
|
38
|
+
|
|
39
|
+
df = pd.DataFrame(rows)
|
|
40
|
+
return df
|
|
41
|
+
except Exception as e:
|
|
42
|
+
raise e
|
DYAMS/api/heartbeat.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from .util import get_response_json_with_check
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def heartbeat(client):
|
|
6
|
+
|
|
7
|
+
url = f"{client.base_url}/lib/monitor/v1/heartbeat"
|
|
8
|
+
headers = client.get_headers()
|
|
9
|
+
try:
|
|
10
|
+
response = requests.get(url, headers=headers)
|
|
11
|
+
get_response_json_with_check(response)
|
|
12
|
+
except Exception as e:
|
|
13
|
+
raise e
|
DYAMS/api/util.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
|
|
2
|
+
def get_response_json_with_check(response):
|
|
3
|
+
if response.status_code != 200:
|
|
4
|
+
response.raise_for_status()
|
|
5
|
+
r = response.json()
|
|
6
|
+
if r.get('code') == -403:
|
|
7
|
+
raise Exception("token认证失败")
|
|
8
|
+
if r.get('code') != 'S00000':
|
|
9
|
+
raise Exception(r.get('message'))
|
|
10
|
+
return r
|
DYAMS/client.py
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
|
+
from .api.heartbeat import heartbeat
|
|
1
2
|
from .api.get_post_investment_product_list import get_post_investment_product_list
|
|
2
|
-
from .api.
|
|
3
|
+
from .api.get_post_investment_product_holdings import get_post_investment_product_holdings
|
|
4
|
+
from .api.get_post_investment_product_performance_indicators import get_post_investment_product_performance_indicators
|
|
5
|
+
from .api.get_post_investment_product_net import get_post_investment_product_net
|
|
6
|
+
from .api.get_post_investment_product_asset_allocation import get_post_investment_product_asset_allocation
|
|
7
|
+
from .api.get_private_asset_net import get_private_asset_net
|
|
3
8
|
|
|
4
9
|
|
|
5
10
|
class Client:
|
|
6
11
|
|
|
7
12
|
_instance = None
|
|
8
13
|
|
|
9
|
-
def __new__(cls, *args, **kwargs):
|
|
10
|
-
if cls._instance is None:
|
|
11
|
-
cls._instance = super(Client, cls).__new__(cls)
|
|
12
|
-
cls._instance._initialized = False
|
|
13
|
-
return cls._instance
|
|
14
|
-
|
|
15
14
|
def __init__(self, token='', env='prd'):
|
|
16
|
-
if self._initialized:
|
|
17
|
-
return
|
|
18
15
|
self.token = token
|
|
19
16
|
if env == 'prd':
|
|
20
17
|
self.base_url = "https://gw.datayes.com/aladdin_mof"
|
|
@@ -24,7 +21,14 @@ class Client:
|
|
|
24
21
|
self.base_url = "https://gw.datayes-stg.com/mom_aladdin_stg"
|
|
25
22
|
else:
|
|
26
23
|
raise ValueError("error env")
|
|
27
|
-
self
|
|
24
|
+
heartbeat(self)
|
|
25
|
+
Client._instance = self
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def get_instance():
|
|
29
|
+
if Client._instance is None:
|
|
30
|
+
raise RuntimeError("Client未初始化,请先实例化Client")
|
|
31
|
+
return Client._instance
|
|
28
32
|
|
|
29
33
|
def get_headers(self):
|
|
30
34
|
return {
|
|
@@ -32,8 +36,10 @@ class Client:
|
|
|
32
36
|
'Authorization': f'Bearer {self.token}'
|
|
33
37
|
}
|
|
34
38
|
|
|
35
|
-
def get_post_investment_product_list(self, post_investment_production_id=None):
|
|
36
|
-
return get_post_investment_product_list(self, post_investment_production_id)
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
Client.get_post_investment_product_list = get_post_investment_product_list
|
|
41
|
+
Client.get_post_investment_product_holdings = get_post_investment_product_holdings
|
|
42
|
+
Client.get_post_investment_product_performance_indicators = get_post_investment_product_performance_indicators
|
|
43
|
+
Client.get_post_investment_product_net = get_post_investment_product_net
|
|
44
|
+
Client.get_post_investment_product_asset_allocation = get_post_investment_product_asset_allocation
|
|
45
|
+
Client.get_private_asset_net = get_private_asset_net
|
DYAMS/enums.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class PenetrateType(Enum):
|
|
5
|
+
NO_PENETRATE = "不穿透"
|
|
6
|
+
FOF_QUARTER = "FOF穿透(季报/中报/年报)"
|
|
7
|
+
FOF_SEMI = "FOF穿透(中报/年报)"
|
|
8
|
+
MOM = "MOM穿透"
|
|
9
|
+
ALL = "全部穿透"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PositionField(Enum):
|
|
13
|
+
CLASS = "资产分类"
|
|
14
|
+
DATE = "日期"
|
|
15
|
+
ASSET_NAME = "资产名称"
|
|
16
|
+
ASSET_CODE = "资产代码"
|
|
17
|
+
SECURITY_TYPE = "证券品种"
|
|
18
|
+
TRADING_MARKET = "交易市场"
|
|
19
|
+
CURRENT_CLEAN_PRICE = "当前净价"
|
|
20
|
+
ACCRUED_INTEREST = "应计利息"
|
|
21
|
+
PRICE_CHANGE = "涨跌"
|
|
22
|
+
POSITION_QUANTITY = "持仓数量"
|
|
23
|
+
POSITION_MARKET_VALUE = "持仓市值"
|
|
24
|
+
POSITION_WEIGHT_NET_ASSETS = "持仓权重(净资产)"
|
|
25
|
+
DAILY_PROFIT_LOSS = "当日盈亏"
|
|
26
|
+
DAILY_PROFIT_LOSS_RATE = "当日盈亏率"
|
|
27
|
+
FLOATING_PROFIT_LOSS = "浮动盈亏"
|
|
28
|
+
FLOATING_PROFIT_LOSS_RATE = "浮动盈亏率"
|
|
29
|
+
CUMULATIVE_PROFIT_LOSS = "累计盈亏"
|
|
30
|
+
CUMULATIVE_PROFIT_LOSS_RATE = "累计盈亏率"
|
|
31
|
+
POSITION_COST = "持仓成本"
|
|
32
|
+
INTEREST_INCOME = "利息收入"
|
|
33
|
+
REALIZED_PROFIT_LOSS = "已实现盈亏"
|
|
34
|
+
MATURITY_DATE = "到期日"
|
|
35
|
+
TRADING_CHANNEL = "交易通道"
|
|
36
|
+
POSITION_DIRECTION = "持仓方向"
|
|
37
|
+
LATEST_PRICE = "最新价"
|
|
38
|
+
POSITION_WEIGHT_TOTAL_ASSETS = "持仓权重(总资产)"
|
|
39
|
+
POSITION_WEIGHT_TOTAL_COST = "持仓权重(总成本)"
|
|
40
|
+
COST_PRICE = "成本价格"
|
|
41
|
+
AMORTIZED_COST = "摊薄成本"
|
|
42
|
+
VALUATION_EXCHANGE_RATE = "估值汇率"
|
|
43
|
+
MARKET_QUOTATION_TIME = "行情时间"
|
|
44
|
+
POSITION_BUILDING_DATE = "建仓日期"
|
|
45
|
+
ISSUING_ENTITY = "发行主体"
|
|
46
|
+
REMAINING_MATURITY = "剩余期限"
|
|
47
|
+
BOND_RATING_AGENCY = "债项评级机构"
|
|
48
|
+
BOND_RATING = "债项评级"
|
|
49
|
+
MARGIN_REQUIREMENT = "占用保证金"
|
|
50
|
+
CITY = "城市"
|
|
51
|
+
PROVINCE = "省份"
|
|
52
|
+
ISSUER_RATING_YY = "主体评级(YY)"
|
|
53
|
+
ISSUER_RATING_DATE = "主体评级日期"
|
|
54
|
+
ISSUER_RATING = "主体评级"
|
|
55
|
+
BOND_RATING_DATE = "债项评级日期"
|
|
56
|
+
ISSUER_RATING_AGENCY = "主体评级机构"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class SecurityType(Enum):
|
|
60
|
+
stock = "股票"
|
|
61
|
+
bond = "债券"
|
|
62
|
+
fund = "公募基金"
|
|
63
|
+
future = "期货"
|
|
64
|
+
portfolio = "投后产品"
|
|
65
|
+
private_asset = "资管产品"
|
|
66
|
+
repo = "回购"
|
|
67
|
+
option = "期权"
|
|
68
|
+
margin_trading = "融券"
|
|
69
|
+
cash = "现金"
|
|
70
|
+
debt = "负债"
|
|
71
|
+
other = "其他"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class WeightType(Enum):
|
|
75
|
+
NET_ASSET = "占净资产比"
|
|
76
|
+
TOTAL_COST = "占总成本比"
|
|
77
|
+
TOTAL_ASSET = "占总资产比"
|
|
78
|
+
TOTAL_FILTERED = "占资产总市值比"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DYAMS
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6
|
|
4
4
|
Summary: 通联数据AMS系统数据SDK
|
|
5
5
|
Author-email: songjiangduo <jiangduo.song@datayes.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -11,11 +11,4 @@ Description-Content-Type: text/markdown
|
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Dynamic: license-file
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
### 介绍
|
|
17
|
-
[萝卜投资](https://r.datayes.com/)
|
|
18
|
-
|
|
19
|
-
### 调用示例
|
|
20
|
-
|
|
21
|
-
### api列表
|
|
14
|
+
可用于调取DataYes!pro中的投后组合及私有资产数据
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
DYAMS/__init__.py,sha256=vS1EplSNSpQk9ecUZbKlnkgTurMmZj2exA9OOActxY4,933
|
|
2
|
+
DYAMS/client.py,sha256=x-s7htAgveg8uiI8T8bRGk9xh_56admnjN61AZHUCnA,1930
|
|
3
|
+
DYAMS/enums.py,sha256=rW9y7n1G_eYvPyokSN5OrPAp4-raQWB-hTWH4NIFrC8,2490
|
|
4
|
+
DYAMS/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
DYAMS/api/get_post_investment_product_asset_allocation.py,sha256=QZxK-GUZOyxeT4n6X-Lc0ra05mb10lXABKPM1LF1T6g,2165
|
|
6
|
+
DYAMS/api/get_post_investment_product_holdings.py,sha256=yLdr6gz4pIUrqK_b1LoSAuskEKy-9_ZhulSh27qCqxI,6639
|
|
7
|
+
DYAMS/api/get_post_investment_product_list.py,sha256=lomv2qu04AFQivS2NvenYaLBYn53_P1hyxlBA2m0eJM,1515
|
|
8
|
+
DYAMS/api/get_post_investment_product_net.py,sha256=TWrnKKTp8AGS0Mwe-Wo2t64fXGcVhoFi7ujNjvqPhRo,1103
|
|
9
|
+
DYAMS/api/get_post_investment_product_performance_indicators.py,sha256=EDLz5xswVoBuDETEOXYeUxYu19USZH21rFpMUXaUs6s,1486
|
|
10
|
+
DYAMS/api/get_private_asset_net.py,sha256=os5BzEwpXtQr4_GFJj9-oLmVc6WqxW1IIzJAOzXYrUI,1128
|
|
11
|
+
DYAMS/api/heartbeat.py,sha256=jDjiXRqee4QtGKR7nEoo4VhnlG_wvjT3aMXYizTNt1M,333
|
|
12
|
+
DYAMS/api/util.py,sha256=VVoNbaPTyySwyrGJ60pdUPja2gWUyNBJBxY4l_xRSr8,305
|
|
13
|
+
dyams-0.6.dist-info/licenses/LICENSE,sha256=WOCX9n2629PC9kRp-MvyMGR4DrNHG7_Q1Woo6QotwZ4,1130
|
|
14
|
+
dyams-0.6.dist-info/METADATA,sha256=o97d7zbuzlzsvmI5tV5iHEsdwAxJa7z26iFA7nNVU5g,437
|
|
15
|
+
dyams-0.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
16
|
+
dyams-0.6.dist-info/top_level.txt,sha256=7vYrzyi90ywuwd-c24CKytuWbuILmzcU7kQYCuBu7No,6
|
|
17
|
+
dyams-0.6.dist-info/RECORD,,
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import requests
|
|
2
|
-
import pandas as pd
|
|
3
|
-
|
|
4
|
-
field_mapping = {
|
|
5
|
-
'date': 'date',
|
|
6
|
-
'assetName': 'asset_name',
|
|
7
|
-
'assetCode': 'asset_code',
|
|
8
|
-
'securityType': 'security_type',
|
|
9
|
-
'exchangeCd': 'trading_market',
|
|
10
|
-
'netPrice': 'current_clean_price',
|
|
11
|
-
'aiRate': 'accrued_interest',
|
|
12
|
-
'chg': 'price_change',
|
|
13
|
-
'amount': 'position_quantity',
|
|
14
|
-
'marketValueLocal': 'position_market_value',
|
|
15
|
-
'weight': 'position_weight_(net_assets)',
|
|
16
|
-
'dailyProfitValueLocal': 'daily_profit_loss',
|
|
17
|
-
'dailyProfitRate': 'daily_profit_loss_rate',
|
|
18
|
-
'floatingProfitValueLocal': 'floating_profit_loss',
|
|
19
|
-
'floatingProfitRate': 'floating_profit_loss_rate',
|
|
20
|
-
'cumulativeProfitValueLocal': 'cumulative_profit_loss',
|
|
21
|
-
'cumulativeProfitRate': 'cumulative_profit_loss_rate',
|
|
22
|
-
'totalBuyCostLocal': 'position_cost',
|
|
23
|
-
'realizedAiLocal': 'interest_income',
|
|
24
|
-
'realizedProfitValueLocal': 'realized_profit_loss',
|
|
25
|
-
'dueDate': 'maturity_date',
|
|
26
|
-
'channel': 'trading_channel',
|
|
27
|
-
'direction': 'position_direction',
|
|
28
|
-
'price': 'latest_price',
|
|
29
|
-
'weightTotal': 'position_weight_(total_assets)',
|
|
30
|
-
'weightCost': 'position_weight_(total_cost)',
|
|
31
|
-
'buyCost': 'cost_price',
|
|
32
|
-
'cost': 'amortized_cost',
|
|
33
|
-
'fxRate': 'valuation_exchange_rate',
|
|
34
|
-
'positionTime': 'market_quotation_time',
|
|
35
|
-
'holdDate': 'position_building_date',
|
|
36
|
-
'partyFullName': 'issuing_entity',
|
|
37
|
-
'yearToMaturity': 'remaining_maturity',
|
|
38
|
-
'ytmByBrain': 'YTM_(Cost)',
|
|
39
|
-
'nominalRatingInst': 'bond_rating_agency',
|
|
40
|
-
'nominalRating': 'bond_rating',
|
|
41
|
-
'margin': 'margin_requirement',
|
|
42
|
-
'city': 'city',
|
|
43
|
-
'province': 'province',
|
|
44
|
-
'instRatingYY': 'issuer_rating_(YY)',
|
|
45
|
-
'instRatingDate': 'issuer_rating_date',
|
|
46
|
-
'instRating': 'issuer_rating',
|
|
47
|
-
'nominalRatingDate': 'bond_rating_date',
|
|
48
|
-
'instRatingInst': 'issuer_rating_agency'
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def get_portfolio_holdings(client, account_code, start_date, end_date):
|
|
53
|
-
url = f"{client.base_url}/lib/portfolio/v1/position"
|
|
54
|
-
params = {
|
|
55
|
-
'accountCode': account_code,
|
|
56
|
-
'startDate': start_date,
|
|
57
|
-
'endDate': end_date
|
|
58
|
-
}
|
|
59
|
-
headers = client.get_headers()
|
|
60
|
-
try:
|
|
61
|
-
response = requests.get(url, params=params, headers=headers)
|
|
62
|
-
if response.status_code != 200:
|
|
63
|
-
response.raise_for_status()
|
|
64
|
-
r = response.json()
|
|
65
|
-
if r.get('code') == 'F00100':
|
|
66
|
-
raise ValueError('rate limit')
|
|
67
|
-
items = r.get('list')
|
|
68
|
-
rows = []
|
|
69
|
-
for item in items:
|
|
70
|
-
row = {}
|
|
71
|
-
for api_field, our_field in field_mapping.items():
|
|
72
|
-
row[our_field] = item.get(api_field, None)
|
|
73
|
-
rows.append(row)
|
|
74
|
-
df = pd.DataFrame(rows)
|
|
75
|
-
return df
|
|
76
|
-
except Exception as e:
|
|
77
|
-
raise e
|
dyams-0.4.dist-info/RECORD
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
DYAMS/__init__.py,sha256=GHP58uOsE_7GJsU0Pzh7f5dKbWjdyAjKs7q2WeAwl8I,49
|
|
2
|
-
DYAMS/client.py,sha256=uHJCtmAsWZj5BYBp3BzFbmNMT284PZJP9_TM93Tzn8g,1373
|
|
3
|
-
DYAMS/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
DYAMS/api/get_portfolio_holdings.py,sha256=8_PneJMdyKNYkWWdAkRrVBw1nfxuNMUylAAeCH44hsQ,2720
|
|
5
|
-
DYAMS/api/get_post_investment_product_list.py,sha256=YBwQ5OwJmH1cMeQPbaUeKn5RSrm7HRrY60jI93GBAxw,1922
|
|
6
|
-
dyams-0.4.dist-info/licenses/LICENSE,sha256=WOCX9n2629PC9kRp-MvyMGR4DrNHG7_Q1Woo6QotwZ4,1130
|
|
7
|
-
dyams-0.4.dist-info/METADATA,sha256=M-nEJLkV4VHWAGZvp7afVMc3uiGxWgTQFdlYO46YOjc,487
|
|
8
|
-
dyams-0.4.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
|
9
|
-
dyams-0.4.dist-info/top_level.txt,sha256=7vYrzyi90ywuwd-c24CKytuWbuILmzcU7kQYCuBu7No,6
|
|
10
|
-
dyams-0.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|