Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
PyFund
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
陈涛
PyFund
Commits
31a6c4c7
Commit
31a6c4c7
authored
Jun 12, 2023
by
陈涛
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加重新计算净值接口,修改净值记录接口
parent
005d98bf
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
100 additions
and
48 deletions
+100
-48
nav.py
api/nav.py
+58
-8
nav.py
service/nav.py
+42
-40
No files found.
api/nav.py
View file @
31a6c4c7
import
datetime
import
datetime
from
typing
import
Optional
from
fastapi
import
APIRouter
,
Depends
from
fastapi
import
APIRouter
,
Depends
,
Query
,
Body
from
fastapi.background
import
BackgroundTasks
from
motor.core
import
AgnosticCollection
from
motor.core
import
AgnosticCollection
from
dependencies
import
get_nav_collect
,
get_fund_collect
from
dependencies
import
get_nav_collect
from
model
import
SortParams
,
FilterTime
,
Page
,
PageResponse
,
Response
from
model
import
SortParams
,
FilterTime
,
Page
,
PageResponse
,
Response
from
model.fund
import
StakingFundNav
from
model.fund
import
StakingFundNav
from
service.nav
import
calculate_nav
from
service.nav
import
calculate_nav
,
build_fund_nav
router
=
APIRouter
()
router
=
APIRouter
()
@
router
.
get
(
"/{fund_id}/"
,
response_model
=
PageResponse
[
StakingFundNav
],
summary
=
"查询净值记录"
)
@
router
.
get
(
"/{fund_id}/"
,
response_model
=
PageResponse
[
StakingFundNav
],
summary
=
"查询净值记录"
)
async
def
nav
(
async
def
get_
nav
(
fund_id
:
str
,
fund_id
:
str
,
sort_by
:
SortParams
=
Depends
(
SortParams
),
sort_by
:
SortParams
=
Depends
(
SortParams
),
filter_time
:
FilterTime
=
Depends
(
FilterTime
),
filter_time
:
FilterTime
=
Depends
(
FilterTime
),
...
@@ -34,8 +34,58 @@ async def nav(
...
@@ -34,8 +34,58 @@ async def nav(
@
router
.
post
(
"/{fund_id}/"
,
response_model
=
Response
[
StakingFundNav
],
summary
=
"插入净值记录"
)
@
router
.
post
(
"/{fund_id}/"
,
response_model
=
Response
[
StakingFundNav
],
summary
=
"插入净值记录"
)
async
def
insert_nav
(
async
def
insert_nav
(
fund_id
:
str
,
fund_id
:
str
,
calc_time
:
datetime
.
datetime
,
calc_time
:
Optional
[
datetime
.
datetime
]
=
Query
(
default
=
None
,
title
=
"时间"
)
,
):
):
fund_nav
=
await
calculate_nav
(
fund_id
=
fund_id
,
calc_time
=
calc_time
)
fund_nav
=
await
calculate_nav
(
fund_id
=
fund_id
,
calc_time
=
calc_time
)
if
calc_time
else
await
calculate_nav
(
fund_id
)
response
=
Response
[
StakingFundNav
](
data
=
fund_nav
)
response
=
Response
[
StakingFundNav
](
data
=
fund_nav
)
return
response
return
response
@
router
.
post
(
"/"
,
response_model
=
Response
[
bool
],
summary
=
"新增净值记录"
)
async
def
create_nav
(
fund_id
:
str
=
Body
(
...
,
title
=
"基金id"
),
record_date
:
datetime
.
datetime
=
Body
(
...
,
title
=
"记录日期"
),
nav
:
float
=
Body
(
...
,
title
=
"净值"
),
fund_share
:
float
=
Body
(
...
,
title
=
"份额"
),
fund_collect
:
AgnosticCollection
=
Depends
(
get_fund_collect
),
nav_collect
:
AgnosticCollection
=
Depends
(
get_nav_collect
),
):
fund_data
=
await
fund_collect
.
find
({
"id"
:
fund_id
})
fund_nav
=
build_fund_nav
(
fund_data
,
record_date
,
fund_share
,
nav
)
insert
=
await
nav_collect
.
insert_one
(
fund_nav
)
response
=
Response
(
data
=
insert
.
acknowledged
)
return
response
@
router
.
put
(
"/{nav_id}/"
,
response_model
=
Response
[
int
],
summary
=
"修改净值记录"
)
async
def
update_nav
(
nav_id
:
str
,
fund_id
:
str
=
Body
(
...
,
title
=
"基金id"
),
record_date
:
datetime
.
datetime
=
Body
(
...
,
title
=
"记录日期"
),
nav
:
float
=
Body
(
...
,
title
=
"净值"
),
fund_share
:
float
=
Body
(
...
,
title
=
"份额"
),
fund_collect
:
AgnosticCollection
=
Depends
(
get_fund_collect
),
nav_collect
:
AgnosticCollection
=
Depends
(
get_nav_collect
),
):
update_result
=
await
nav_collect
.
update_one
(
{
"id"
:
nav_id
,
"fund_id"
:
fund_id
},
{
"$set"
:
{
"record_date"
:
record_date
,
"nav"
:
nav
,
"fund_share"
:
fund_share
}}
)
response
=
Response
(
data
=
update_result
.
modified_count
)
return
response
@
router
.
put
(
"/recalculate/{fund_id}/"
,
response_model
=
Response
[
bool
],
summary
=
"重新计算净值"
)
async
def
recalculate_nav
(
fund_id
:
str
,
background_task
:
BackgroundTasks
,
start
:
datetime
.
datetime
=
Query
(
...
,
title
=
"开始时间"
),
end
:
datetime
.
datetime
=
Query
(
None
,
title
=
"结束时间"
),
):
end
=
end
or
datetime
.
datetime
.
utcnow
()
delta
=
end
-
start
for
i
in
range
(
delta
.
days
+
1
):
date
=
start
+
datetime
.
timedelta
(
days
=
i
)
background_task
.
add_task
(
calculate_nav
,
fund_id
=
fund_id
,
calc_time
=
date
,
update_fund
=
False
)
response
=
Response
(
data
=
True
)
return
response
service/nav.py
View file @
31a6c4c7
import
datetime
import
datetime
import
time
import
uuid
import
uuid
import
pytz
import
pytz
from
loguru
import
logger
from
loguru
import
logger
from
pymongo
import
ReturnDocument
from
dependencies
import
get_fund_collect
,
get_cmc_price_redis
,
get_hour_price_collect
,
get_bill_collect
,
\
from
dependencies
import
get_fund_collect
,
get_cmc_price_redis
,
get_hour_price_collect
,
get_bill_collect
,
\
get_nav_collect
get_nav_collect
...
@@ -11,17 +13,36 @@ from service.beacon import BeaconChaService
...
@@ -11,17 +13,36 @@ from service.beacon import BeaconChaService
from
service.price
import
get_price
from
service.price
import
get_price
async
def
calculate_nav
(
fund_id
,
calc_time
:
datetime
.
datetime
=
None
,
beach_service
=
BeaconChaService
()):
def
build_fund_nav
(
fund_data
:
dict
,
record_date
,
total_fund_share
,
net_value
):
fund_nav
=
{}
for
key
,
value
in
fund_data
.
items
():
if
key
==
"_id"
:
continue
elif
key
==
"id"
:
fund_nav
[
"fund_id"
]
=
value
fund_nav
[
"id"
]
=
uuid
.
uuid1
()
.
__str__
()
else
:
fund_nav
[
key
]
=
value
fund_nav
.
update
(
{
"record_date"
:
record_date
,
"fund_share"
:
total_fund_share
,
"nav"
:
net_value
,
"update_time"
:
int
(
time
.
time
())})
return
fund_nav
async
def
calculate_nav
(
fund_id
,
calc_time
:
datetime
.
datetime
=
None
,
beach_service
=
BeaconChaService
(),
update_fund
=
True
):
# todo 测试
# todo 测试
calc_time
=
calc_time
.
replace
(
minute
=
0
,
second
=
0
,
microsecond
=
0
,
tzinfo
=
pytz
.
UTC
)
if
calc_time
else
datetime
.
datetime
.
utcnow
()
.
replace
(
minute
=
0
,
second
=
0
,
microsecond
=
0
,
tzinfo
=
pytz
.
UTC
)
from
main
import
app
from
main
import
app
fund_collect
=
get_fund_collect
(
app
.
state
.
mongodb_manager
)
fund_collect
=
get_fund_collect
(
app
.
state
.
mongodb_manager
)
nav_collect
=
get_nav_collect
(
app
.
state
.
mongodb_manager
)
logger
.
info
(
f
'[定时任务开始执行] [计算净值] {fund_id} '
)
logger
.
info
(
f
'[定时任务开始执行] [计算净值] {fund_id} '
)
fund_data
=
await
fund_collect
.
find_one
({
'id'
:
fund_id
,
'fund_status'
:
FundStatus
.
active
.
value
})
# 判断当天是否有净值记录,如果有则根据
fund_record
=
await
fund_collect
.
find_one
({
'id'
:
fund_id
,
'fund_status'
:
FundStatus
.
active
.
value
})
record_date
=
(
calc_time
or
datetime
.
datetime
.
utcnow
())
.
replace
(
hour
=
0
,
minute
=
0
,
second
=
0
,
microsecond
=
0
,
tzinfo
=
pytz
.
UTC
)
if
fund_record
[
"settlement_time"
]
==
"00:00"
or
fund_record
[
"settlement_time"
]
==
"0:00"
:
record_date
-=
datetime
.
timedelta
(
days
=
1
)
nav_record
=
await
nav_collect
.
find_one
({
"fund_id"
:
fund_id
,
"record_date"
:
record_date
})
fund_data
=
nav_record
or
fund_record
amount
=
{}
amount
=
{}
# 查询asset资产
# 查询asset资产
for
key
,
value
in
fund_data
[
'assets'
]
.
items
():
for
key
,
value
in
fund_data
[
'assets'
]
.
items
():
...
@@ -29,7 +50,7 @@ async def calculate_nav(fund_id, calc_time: datetime.datetime = None, beach_serv
...
@@ -29,7 +50,7 @@ async def calculate_nav(fund_id, calc_time: datetime.datetime = None, beach_serv
amount
[
key
]
+=
value
amount
[
key
]
+=
value
# 查询在途资产
# 查询在途资产
for
key
,
value
in
fund_data
[
'assets'
]
.
items
():
for
key
,
value
in
fund_data
[
'
pending_
assets'
]
.
items
():
amount
.
setdefault
(
key
,
0
)
amount
.
setdefault
(
key
,
0
)
amount
[
key
]
+=
value
amount
[
key
]
+=
value
...
@@ -72,36 +93,17 @@ async def calculate_nav(fund_id, calc_time: datetime.datetime = None, beach_serv
...
@@ -72,36 +93,17 @@ async def calculate_nav(fund_id, calc_time: datetime.datetime = None, beach_serv
-
item
[
"fund_share"
]
if
item
[
"bill_type"
]
==
"redemption"
else
item
[
"fund_share"
]
for
item
in
result
)
-
item
[
"fund_share"
]
if
item
[
"bill_type"
]
==
"redemption"
else
item
[
"fund_share"
]
for
item
in
result
)
value
=
sum
(
nav
.
values
())
value
=
sum
(
nav
.
values
())
net_value
=
round
(
value
/
total_fund_share
,
2
)
if
total_fund_share
>
0
else
fund_data
[
"base_nav"
]
net_value
=
round
(
value
/
total_fund_share
,
2
)
if
total_fund_share
>
0
else
fund_data
[
"base_nav"
]
await
fund_collect
.
update_one
({
'id'
:
fund_id
},
{
"$set"
:
{
"nva"
:
net_value
}})
if
update_fund
:
nav_collect
=
get_nav_collect
(
app
.
state
.
mongodb_manager
)
await
fund_collect
.
update_one
({
'id'
:
fund_id
},
{
"$set"
:
{
"nav"
:
net_value
}})
date
=
calc_time
.
replace
(
hour
=
0
,
minute
=
0
,
second
=
0
,
microsecond
=
0
,
tzinfo
=
pytz
.
UTC
)
if
calc_time
else
datetime
.
datetime
.
utcnow
()
.
replace
(
hour
=
0
,
minute
=
0
,
second
=
0
,
microsecond
=
0
,
tzinfo
=
pytz
.
UTC
)
if
fund_data
[
"settlement_time"
]
==
"00:00"
:
date
-=
datetime
.
timedelta
(
days
=
1
)
nav_record
=
await
nav_collect
.
find_one
({
"fund_id"
:
fund_id
,
"record_date"
:
date
})
if
nav_record
:
if
nav_record
:
error
=
f
'重复净值记录 [{nav_record}] [mongo] [{date}]'
fund_nav
=
nav_record
.
copy
()
logger
.
error
(
error
)
fund_nav
.
update
({
"record_date"
:
record_date
,
"fund_share"
:
total_fund_share
,
"nav"
:
net_value
,
"update_time"
:
int
(
time
.
time
())})
raise
Exception
(
error
)
else
:
fund_nav
=
{}
fund_nav
=
build_fund_nav
(
fund_record
,
record_date
,
total_fund_share
,
net_value
)
for
key
,
value
in
fund_data
.
items
():
update_record
=
await
nav_collect
.
find_one_and_update
(
if
key
==
"_id"
:
{
"fund_id"
:
fund_id
,
"record_date"
:
record_date
},
continue
{
"$set"
:
fund_nav
},
elif
key
==
"id"
:
upsert
=
True
,
fund_nav
[
"fund_id"
]
=
value
return_document
=
ReturnDocument
.
AFTER
fund_nav
[
"id"
]
=
uuid
.
uuid1
()
.
__str__
()
)
else
:
return
update_record
fund_nav
[
key
]
=
value
fund_nav
[
"record_date"
]
=
date
fund_nav
[
"fund_share"
]
=
total_fund_share
fund_nav
[
"nav"
]
=
net_value
insert
=
await
nav_collect
.
insert_one
(
fund_nav
)
if
not
insert
.
acknowledged
:
error
=
f
'写入净值记录失败 [{fund_nav}] [mongo] [{date}]'
logger
.
error
(
error
)
raise
Exception
(
error
)
return
fund_nav
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment