Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
R
robo-dividend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
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
wenwen.tang
robo-dividend
Commits
c418191a
Commit
c418191a
authored
Jul 02, 2024
by
wenwen.tang
😕
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
推荐系统
parent
ee438e4e
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
63 additions
and
44 deletions
+63
-44
base_signal.py
rebalance/base_signal.py
+1
-1
robo_rebalance_signal.py
rebalance/dao/robo_rebalance_signal.py
+1
-0
robo_controller.py
web/robo_controller.py
+61
-43
No files found.
rebalance/base_signal.py
View file @
c418191a
...
@@ -52,7 +52,7 @@ class BaseRebalanceSignal(RebalanceSignal, ABC):
...
@@ -52,7 +52,7 @@ class BaseRebalanceSignal(RebalanceSignal, ABC):
date
=
pd
.
to_datetime
(
signal
[
'date'
]
.
replace
(
day
=
transfer_date
))
date
=
pd
.
to_datetime
(
signal
[
'date'
]
.
replace
(
day
=
transfer_date
))
# 说明发生了跨月份问题
# 说明发生了跨月份问题
if
signal
[
'date'
]
.
day
>
transfer_date
:
if
signal
[
'date'
]
.
day
>
transfer_date
:
if
rrs
.
get_count
(
risk
=
PortfoliosRisk
.
FT3
,
effective
=
True
)
>
1
:
if
rrs
.
get_count
(
risk
=
PortfoliosRisk
.
FT3
,
effective
=
True
)
>
0
:
date
=
date
+
pd
.
DateOffset
(
months
=
1
)
date
=
date
+
pd
.
DateOffset
(
months
=
1
)
date
=
date
+
pd
.
DateOffset
(
months
=
frequency
)
date
=
date
+
pd
.
DateOffset
(
months
=
frequency
)
date
=
date
-
timedelta
(
days
=
1
)
date
=
date
-
timedelta
(
days
=
1
)
...
...
rebalance/dao/robo_rebalance_signal.py
View file @
c418191a
...
@@ -10,6 +10,7 @@ __COLUMNS__ = {
...
@@ -10,6 +10,7 @@ __COLUMNS__ = {
'rrs_p_type'
:
'portfolio_type'
,
'rrs_p_type'
:
'portfolio_type'
,
'rrs_p_weight'
:
'portfolio'
,
'rrs_p_weight'
:
'portfolio'
,
'rrs_effective'
:
'effective'
,
'rrs_effective'
:
'effective'
,
'rrs_create_time'
:
'create_time'
,
}
}
...
...
web/robo_controller.py
View file @
c418191a
import
datetime
as
dt
import
datetime
as
dt
import
json
import
json
from
multiprocessing
import
Process
import
logging
from
statistics
import
pstdev
import
pandas
as
pd
import
uvicorn
import
uvicorn
from
apscheduler.schedulers.blocking
import
BlockingScheduler
from
apscheduler.schedulers.asyncio
import
AsyncIOScheduler
from
fastapi
import
FastAPI
from
apscheduler.triggers.date
import
DateTrigger
from
py_jftech
import
prev_workday
,
filter_weekend
,
autowired
from
empyrical
import
sharpe_ratio
,
annual_volatility
from
fastapi
import
FastAPI
,
Request
from
py_jftech
import
prev_workday
,
filter_weekend
,
autowired
,
next_workday
from
starlette.responses
import
JSONResponse
import
main
import
main
from
api
import
DatumType
,
PortfoliosRisk
,
Datum
from
api
import
DatumType
,
PortfoliosRisk
,
Datum
,
RoboReportor
app
=
FastAPI
()
app
=
FastAPI
()
# 创建 AsyncIOScheduler 实例
scheduler
=
AsyncIOScheduler
()
REC_GID
=
'E3886FBA-123B-7890-123E-123456BEEED'
REC_GID
=
'E3886FBA-123B-7890-123E-123456BEEED'
fund_infos
,
cp
,
roi
,
risk
=
None
,
None
,
None
,
None
def
get_today_rec
():
def
get_today_rec
():
...
@@ -33,32 +41,41 @@ def get_last_signal():
...
@@ -33,32 +41,41 @@ def get_last_signal():
@
autowired
@
autowired
def
get_fund_infos
(
datum
:
Datum
=
None
):
def
get_fund_infos
(
datum
:
Datum
=
None
):
return
datum
.
get_datums
(
DatumType
.
FUND
)
global
fund_infos
fund_infos
=
datum
.
get_datums
(
DatumType
.
FUND
)
@
app
.
get
(
"/recommend"
)
async
def
root
():
@
autowired
(
names
=
{
'combo'
:
'hold-report'
})
portfolio
=
get_today_rec
()
def
load_report
(
max_date
=
prev_workday
(
dt
.
date
.
today
()),
min_date
=
None
,
combo
:
RoboReportor
=
None
):
if
portfolio
:
global
cp
,
roi
,
risk
fund_infos
=
get_fund_infos
()
datas
=
pd
.
DataFrame
(
combo
.
load_report
(
max_date
=
max_date
,
min_date
=
min_date
))
datas
.
set_index
(
'date'
,
inplace
=
True
)
datas
=
datas
[
'acc_av'
]
returns
=
round
(
datas
.
pct_change
(),
5
)
cp
=
round
(
sharpe_ratio
(
returns
,
risk_free
=
0
,
period
=
'daily'
,
annualization
=
None
),
2
)
roi
=
round
(
annual_volatility
(
datas
),
1
)
risk
=
round
(
pstdev
(
datas
),
1
)
return
cp
,
roi
,
risk
@
app
.
get
(
"/franklin/prediction_data"
)
async
def
recommend
():
sig
=
get_last_signal
()
if
sig
:
if
not
fund_infos
:
get_fund_infos
()
id_ticker_map
=
{
str
(
info
[
'id'
]):
info
for
info
in
fund_infos
}
id_ticker_map
=
{
str
(
info
[
'id'
]):
info
for
info
in
fund_infos
}
funds
=
json
.
loads
(
portfolio
[
'portfolio'
])
funds
=
json
.
loads
(
sig
[
'portfolio'
])
rec_list
=
[]
rec_list
=
[]
portfolios
=
{
'recomm_guid'
:
REC_GID
}
portfolios
=
{
'recomm_guid'
:
REC_GID
}
data
=
{
'recomm_guid'
:
REC_GID
}
load_report
(
min_date
=
dt
.
date
.
today
()
-
dt
.
timedelta
(
365
))
data
[
'data_date'
]
=
portfolio
[
'date'
]
.
strftime
(
'
%
Y-
%
m-
%
d'
)
data
=
{
'recomm_guid'
:
REC_GID
,
'data_date'
:
sig
[
'date'
]
.
strftime
(
'
%
Y-
%
m-
%
d'
),
data
[
'funds'
]
=
[{
'weight'
:
round
(
weight
*
100
),
'fund_id'
:
id_ticker_map
[
key
][
'ftTicker'
]}
for
key
,
weight
in
'funds'
:
[{
'weight'
:
round
(
weight
*
100
),
'fund_id'
:
id_ticker_map
[
key
][
'ftTicker'
]}
for
key
,
weight
in
funds
.
items
()]
funds
.
items
()],
'creat_date'
:
sig
[
'create_time'
]
.
strftime
(
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S'
),
data
[
'creat_date'
]
=
portfolio
[
'create_time'
]
.
strftime
(
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S'
)
'risk'
:
risk
,
# todo 补全
'rr'
:
round
(
sum
([
id_ticker_map
[
key
][
'risk'
]
*
weight
for
key
,
weight
in
funds
.
items
()]),
2
),
'cp'
:
cp
,
# returns = round(datas.pct_change(), 5)
'roi'
:
roi
}
# data['cp'] = sharpe_ratio(returns, risk_free=0, period='daily', annualization=None),
note
=
{
'last_rec'
:
next_workday
(
sig
[
'date'
])
.
strftime
(
'
%
Y
%
m
%
d'
)}
data
[
'rr'
]
=
0.81
data
[
'roi'
]
=
0.81
data
[
'risk'
]
=
round
(
sum
([
id_ticker_map
[
key
][
'risk'
]
*
weight
for
key
,
weight
in
funds
.
items
()]),
2
)
note
=
{}
sig
=
get_last_signal
()
note
[
'last_reg_reb'
]
=
sig
[
'date'
]
.
strftime
(
'
%
Y-
%
m-
%
d'
)
data
[
'note'
]
=
json
.
dumps
(
note
)
data
[
'note'
]
=
json
.
dumps
(
note
)
portfolios
[
'data'
]
=
data
portfolios
[
'data'
]
=
data
rec_list
.
append
(
portfolios
)
rec_list
.
append
(
portfolios
)
...
@@ -67,28 +84,29 @@ async def root():
...
@@ -67,28 +84,29 @@ async def root():
return
{
'msg'
:
'当日投组未产生,待10:00后获取'
}
return
{
'msg'
:
'当日投组未产生,待10:00后获取'
}
def
start_robo
():
# 其他异常处理程序
@
app
.
exception_handler
(
Exception
)
async
def
general_exception_handler
(
request
:
Request
,
exc
:
Exception
):
# 打印一般错误信息
logging
.
error
(
f
"请求 {request.url} 发生未知错误: {str(exc)}"
)
return
JSONResponse
(
status_code
=
500
,
content
=
{
"errorCode"
:
"500"
,
"errorMsg"
:
str
(
exc
)},
)
# 定义应用启动事件
@
app
.
on_event
(
"startup"
)
async
def
startup_event
():
# 异常情况可以重启跑当天投组
# 异常情况可以重启跑当天投组
current_time
=
dt
.
datetime
.
now
()
current_time
=
dt
.
datetime
.
now
()
target_time
=
dt
.
time
(
10
,
0
)
target_time
=
dt
.
time
(
10
,
0
)
if
current_time
.
time
()
>
target_time
:
if
current_time
.
time
()
>
target_time
:
main
.
start
()
scheduler
.
add_job
(
main
.
start
,
trigger
=
DateTrigger
(
run_date
=
current_time
))
# 开启定时任务,执行实盘
# 开启定时任务,执行实盘
scheduler
=
BlockingScheduler
()
scheduler
.
add_job
(
main
.
start
,
'cron'
,
day_of_week
=
'0-4'
,
hour
=
10
,
minute
=
00
)
scheduler
.
add_job
(
main
.
start
,
'cron'
,
day_of_week
=
'0-4'
,
hour
=
10
,
minute
=
00
)
scheduler
.
start
()
scheduler
.
start
()
def
start_web
():
uvicorn
.
run
(
"robo_controller:app"
,
reload
=
True
,
port
=
8080
)
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
# 开启一个进程执行start_robo()
uvicorn
.
run
(
"robo_controller:app"
,
host
=
"0.0.0.0"
,
port
=
8080
)
p1
=
Process
(
target
=
start_robo
)
p1
.
start
()
# 启动进程2
p2
=
Process
(
target
=
start_web
)
p2
.
start
()
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