Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9d5b979da7 |
0
nextjs/README.md
Normal file
@ -1,3 +0,0 @@
|
||||
## 단어정리
|
||||
|
||||
1.
|
@ -1,24 +0,0 @@
|
||||
### 용어 정리
|
||||
|
||||
1. 수도결제(受渡, settlement): 증권의 매매 거래, 증권과 그 대금을 주고 받는 것. 매매 계약 체결 후 3일째가 되는 날에 수도. 이러한 수도에 의하여 매매 계약을 이행하는 것을 수도 결제라고 하며, 그 거래를 수도 거래라고 한다.
|
||||
|
||||
2. 투자가능금액 =/= 주문가능금액
|
||||
1) 투자가능금액: 계좌 입금금액(현금 중) 투자에 사용할 수 있는 금액. 보유중인 주식, 타 자산 매도하여 얻은 현금 포함될 수 있음. 그러나 결제가 완료되지 않은 거래에서 발생한 금액은 포함되지 않을 수 있음.
|
||||
2) 주문가능금액: 현재 증권 계좌에서 주문을 할 때 실제로 사용할 수 있는 금액. 투자가능금액에서 미체결된 주문의 금액을 차감한 금액일 수 있음.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
n1["출금가능금액"]
|
||||
n2["주문가능금액"]
|
||||
n3["가입상품"]
|
||||
n4["환전신청금액"]
|
||||
```
|
||||
|
||||
3. 예수금
|
||||
|
||||
> 계좌에 주식 거래를 위해 입금한 금액. 예수금을 증거금으로 활용하거나 인출 할 수 있다.
|
||||
|
||||
4. 안전 마진, 잔여 예수금
|
||||
|
||||
> 주식 매수 투자자 보호 및 거래 안정성 계좌에 일부 금액 남기게 설정. 주식 매수 시 발생할 수 있는 불확실한 수수료, 세금, 가격 변동 부족한 금액이 발생하는것 방지 조치
|
||||
> 남겨둔 금액은 수수료 기타 비용 커버 사용, 실제 매매 금액 부족할 때 대비 남기는 금액
|
@ -1,428 +0,0 @@
|
||||
# PBP-CS 모든 프로세스 모음
|
||||
|
||||
> 개발 도중 프로세스 및 코드에 대한 이해도가 낮은 이유로 개발이 어려움을 느끼며 차후 개발에서 개발 속도 및 변경 부작용을 없애고 이해도를 높이고자 이 문서를 작성함
|
||||
|
||||
<br><br>
|
||||
|
||||
### 2024-08-29 (현 하나증권 중심)
|
||||
|
||||
**공병훈 교수**{style="font-style:italic"}는 플랫폼이란 "서로 연결된 관계를 맺으며 가치를 만드는 체계"라는 표현을 사용하였다. 상호의존적인 관계를 형성하며 서로 다른 그룹들간의 상호작요을 쉽게 하여 가치를 창조한다.
|
||||
플랫폼에 대한 자세한 내용은 다음 링크로 확인하면 좋다.
|
||||
<https://brunch.co.kr/@mobility/62>
|
||||
|
||||
<br><br><br>
|
||||
|
||||
## Login -> Assets
|
||||
|
||||
> [로그인]페이지에서 [내 자산]으로 화면이 넘아갈때의 프로세스를 아래 기술한다.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Login --> Assets
|
||||
```
|
||||
|
||||
### - Login
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: src/app/login/page.tsx
|
||||
---
|
||||
classDiagram
|
||||
direction LR
|
||||
class Login{
|
||||
param: ref, sccofnstcd
|
||||
}
|
||||
class LoginTask{
|
||||
onConfirm?(bool: boolean): void; // 로그 인 완료
|
||||
}
|
||||
class CookieInfo{
|
||||
}
|
||||
class Spinner{
|
||||
}
|
||||
Login *-- LoginTask : Component
|
||||
Login *-- CookieInfo : Component
|
||||
Login *-- Spinner : Component
|
||||
Login <-- LoginTask : onConfirmLogin
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
- 로그인 페이지에서 URL파라미터 증권사코드 sccoFnstCd값 받아서 처리
|
||||
<br> <font color='green' size="1"><예)"270 (하나증권)"></font><br>
|
||||
그리고 증권사코드를 localStorage에 저장 저장하는 키는 각 2개임
|
||||
<br> <font color='green' size="1">accessKey, everywhereKey</font><br> accessKey는 웹뷰용 접근 증권사 코드,
|
||||
everywhereKey는 전방위용 접근 증권사 코드 라고한다...
|
||||
|
||||
```javascript
|
||||
if (sccoFnstCd) {
|
||||
localStorage.setItem(accessKey, sccoFnstCd.toString());
|
||||
localStorage.setItem(everywhereKey, sccoFnstCd.toString());
|
||||
} else {
|
||||
localStorage.setItem(accessKey, '');
|
||||
localStorage.setItem(everywhereKey, '');
|
||||
}
|
||||
```
|
||||
|
||||
> <font color="red">ISSUE:</font> 간헐적 백엔드에 270값 안 넘오는 현상 발견됨
|
||||
|
||||
- onConfirmLogin 함수에서는 LoginTask의 onConfirm에 함수 제공.
|
||||
<br><br>
|
||||
|
||||
```javascript
|
||||
const onConfirmLogin = () => {
|
||||
if (ref !== null && ref !== undefined && ref !== '') {
|
||||
router.push(ref);
|
||||
return;
|
||||
}
|
||||
router.push('/assets');
|
||||
}
|
||||
```
|
||||
|
||||
위의 onConfirmLogin에서 브라우저 url param의 ref를 받아서 유무 처리 후 route 처리.
|
||||
|
||||
** 결론적으로 Login 페이지에서 sccoFnstCd(증권사코드)를 localStorage 처리, route처리 하는 기능. {style="color:red"}
|
||||
|
||||
<br><br>
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class LoginTask{
|
||||
counselSeq?: number;
|
||||
onConfirm?(bool: boolean): void; // 로그 인 완료
|
||||
onBack?(): void; // 화면뒤로
|
||||
isTest?: boolean;
|
||||
isMTS?: boolean;
|
||||
----------default set------
|
||||
isTest = false, isMTS = false
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: src/components/task/login/LoginTask.tsx
|
||||
---
|
||||
classDiagram
|
||||
direction LR
|
||||
class LoginTask{
|
||||
}
|
||||
class AlertModal{
|
||||
}
|
||||
class PinNumberLoginTask{
|
||||
onConfirm(): void;
|
||||
onBack(): void;
|
||||
onLoginFail(bool: boolean, idx: number): void;
|
||||
isMTS: boolean;
|
||||
}
|
||||
class ReSignupProcess{
|
||||
onConfirm,
|
||||
onClose,
|
||||
isDeviceChange = false,
|
||||
FailCount,
|
||||
isPasswordInput = false
|
||||
}
|
||||
class SignupProcess{
|
||||
counselSequence?: string;
|
||||
onConfirm?(loginCustomerId: string): void;
|
||||
onClose?(): void;
|
||||
onBack?(): void;
|
||||
}
|
||||
|
||||
LoginTask --> PinNumberLoginTask : 1) defaultLoginOption === 'pinnumber' <br> && !loginFail <br> && !isTest <br> && !isNewUser
|
||||
|
||||
LoginTask --> ReSignupProcess : 2) loginFail <br> && !isTest
|
||||
|
||||
LoginTask --> SignupProcess : 3) isNewUser
|
||||
|
||||
PinNumberLoginTask --> LoginTask : 4) onConfirmLogin() <br> onLoginFail()
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
- isTest가 왜 존재 하는지? (true로 변경시 빈화면 나오게 됨)
|
||||
- defaultLoginOption = process.env.NEXT_PUBLIC_DEFAULT_LOGIN_VIEW
|
||||
<br> # 간편비밀번호 사용 여부 pinnumber or password
|
||||
<br>NEXT_PUBLIC_DEFAULT_LOGIN_VIEW=pinnumber | password
|
||||
<br>현재는 pinnumber
|
||||
|
||||
- 위의 1), 2), 3)을 하나의 함수로 처리하는게 좋을듯 하다.
|
||||
|
||||
4) localStorage의 'KEY'를 가져와서 `getUser` 함수 실행
|
||||
|
||||
<br><br><br>
|
||||
|
||||
#### PinNumberLoginTask로 로그인이 되었을때
|
||||
|
||||
```javascript
|
||||
const onConfirmLogin = async () => {
|
||||
const user = localStorage.getItem(KEY);
|
||||
|
||||
if (user) {
|
||||
const decodeUser = decodeAES(user);
|
||||
await getUser(decodeUser);
|
||||
} else {
|
||||
setAlertModal({
|
||||
title: '로그인 실패',
|
||||
content: (
|
||||
<>
|
||||
아이디가 없습니다. 회원가입을 안하셨다면 회원가입을 하시거나 <br /> 사용 기기를 변경하셨다면 <br /> 본인
|
||||
인증을 해주신 후 <br /> 로그인을 시도 해주세요.
|
||||
</>
|
||||
)
|
||||
});
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
```javascript
|
||||
const getUser = useCallback(
|
||||
async (customerId: string) => {
|
||||
setIsLoading(true);
|
||||
const customer = await getUserInfoApi({
|
||||
customerId,
|
||||
sccoFnstCd: '',
|
||||
role: ''
|
||||
});
|
||||
setIsLoading(false);
|
||||
|
||||
if (isEmptyString(customer.userId)) {
|
||||
const msg = `LocalStorage에 아이디가 존재하고, 간편비밀번호 로그인에 성공했지만, DB에 회원정보가 없음(${customerId})`;
|
||||
commonRecordingLog(recoilFrontEndLog, 'LoginTask', 'api', msg);
|
||||
setAlertModal({
|
||||
title: '로그인 실패',
|
||||
content: '회원정보를 가져올 수 없습니다.\n회원가입을 다시 해주세요.'
|
||||
});
|
||||
} else {
|
||||
await fetch('/api/setSessions', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({customerId: customer.userId, sccoFnstCd})
|
||||
});
|
||||
|
||||
if (fristLoginValue === null || fristLoginValue === undefined) {
|
||||
if (customer.pushStatusDate !== null && customer.pushStatusDate !== undefined) {
|
||||
if (customer.pushStatus === '01') {
|
||||
setToastMessage([
|
||||
{
|
||||
id: getUniqueKey(),
|
||||
text: `${moment(customer.pushStatusDate).format(
|
||||
'YYYY.MM.DD HH:mm'
|
||||
)} 이벤트*혜택 알림 수신에 동의하셨습니다.`,
|
||||
bottom: 70
|
||||
}
|
||||
]);
|
||||
} else {
|
||||
setToastMessage([
|
||||
{
|
||||
id: getUniqueKey(),
|
||||
text: `${moment(customer.pushStatusDate).format(
|
||||
'YYYY.MM.DD HH:mm'
|
||||
)} 이벤트*혜택 알림 수신에 거부하셨습니다.`,
|
||||
bottom: 70
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
localStorage.setItem(firstLoginKey, 'Y');
|
||||
}
|
||||
|
||||
setLoginState(customer);
|
||||
setUserId(customerId || '');
|
||||
const encodeId = encodeAES(customerId);
|
||||
|
||||
localStorage.setItem(KEY, encodeId);
|
||||
onConfirm?.(true);
|
||||
}
|
||||
},
|
||||
[
|
||||
setIsLoading,
|
||||
recoilFrontEndLog,
|
||||
setAlertModal,
|
||||
sccoFnstCd,
|
||||
fristLoginValue,
|
||||
setLoginState,
|
||||
setUserId,
|
||||
KEY,
|
||||
onConfirm,
|
||||
firstLoginKey,
|
||||
setToastMessage
|
||||
]
|
||||
);
|
||||
```
|
||||
|
||||
<br><br>
|
||||
getUserInfoApi API를 호출함 getUserInfo의 내용에 많은 정보가 기록되어 있는 것을 알 수 있음
|
||||
|
||||
```javascript
|
||||
export const getUserInfoApi = async (obj: IUserInfoInput): Promise<IUserInfoOutput> => {
|
||||
return api.get<IUserInfoOutput>('/customer', {customerId: obj.customerId});
|
||||
};
|
||||
```
|
||||
|
||||
```javascript
|
||||
export interface IUserInfoInput {
|
||||
customerId?: string;
|
||||
sccoFnstCd: string;
|
||||
ci?: string;
|
||||
userId?: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
export interface IUserInfoOutput {
|
||||
sccoFnstCd: string; // * 23.11.10 ADD yeong
|
||||
securitiesName: string; // * 23.11.10 ADD yeong
|
||||
userId: string;
|
||||
ci: string;
|
||||
di: string;
|
||||
password: string;
|
||||
mobileNumber: string;
|
||||
birth: string;
|
||||
gender: number;
|
||||
email: string;
|
||||
osType?: string;
|
||||
osPlatform?: string;
|
||||
roles?: string;
|
||||
token?: string;
|
||||
appVersion?: string;
|
||||
userLevel?: string;
|
||||
userName: string;
|
||||
nickName?: string;
|
||||
activeStep: string;
|
||||
joinDate?: string;
|
||||
lastDate?: string;
|
||||
authCode?: string;
|
||||
passwordErrorCount: number;
|
||||
passwordDate: string;
|
||||
investmentPropensity: InvestmentPropensity; // * 23.11.10 ADD yeong
|
||||
customerStatusCode: string; // * 23.11.10 ADD yeong
|
||||
pushStatus: string; // 01 등록, 02 해제
|
||||
pushStatusDate: string;
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
<br><br>
|
||||
정치영팀장의 계정으로 접속하였을때 아래의 값을 출력함
|
||||
|
||||
```json
|
||||
{
|
||||
"securitiesName": "하나증권",
|
||||
"userId": "5000001008",
|
||||
"userName": "정치영",
|
||||
"mobileNumber": "01051670729",
|
||||
"birth": "19790417",
|
||||
"gender": 1,
|
||||
"email": null,
|
||||
"sccoCustomerIdentifyId": null,
|
||||
"remarks": null,
|
||||
"passwordErrorCount": 0,
|
||||
"passwordDate": "2024-08-21 10:51:34",
|
||||
"activeStep": "20",
|
||||
"investmentPropensity": {
|
||||
"investmentPropensityCode": "1",
|
||||
"investmentPropensity": "공격투자형",
|
||||
"lastSurveyDate": "20240826",
|
||||
"remainingDateCount": 361,
|
||||
"validYn": "Y",
|
||||
"todayTryCount": 0
|
||||
},
|
||||
"pushStatus": "01",
|
||||
"pushStatusDate": "2024-08-13 14:28:51"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
- getUserInfoApi의 결과 값을 /api/setSessions로 전달하여 내용을 저장
|
||||
- getUser함수에서 성공하면 LoginTask의 onConfirm을 Login의 onConfirmLogin으로 true를 전달한다.
|
||||
|
||||
```mermaid
|
||||
|
||||
flowchart LR
|
||||
node_1("LoginTask")
|
||||
node_2("Login")
|
||||
node_1 --"onConfirm={true}"--> node_2
|
||||
|
||||
```
|
||||
|
||||
Login에 있는 onConfirmLogin을 실행함으로써 /assets으로 route하게됨
|
||||
|
||||
<br><br>
|
||||
|
||||
### - Assets
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: src/app/assets/page.tsx
|
||||
---
|
||||
classDiagram
|
||||
direction LR
|
||||
class Assets{
|
||||
|
||||
}
|
||||
class AssetMain{
|
||||
|
||||
}
|
||||
class Spinner{
|
||||
|
||||
}
|
||||
class CookieInfo{
|
||||
|
||||
}
|
||||
class Navigation{
|
||||
value: number;
|
||||
}
|
||||
class RequestReplyTask{
|
||||
|
||||
}
|
||||
|
||||
Assets *-- AssetMain : Component
|
||||
Assets *-- Spinner : Component
|
||||
Assets *-- CookieInfo : Component
|
||||
Assets *-- AssetMain : Component
|
||||
Assets *-- Navigation : isOpenNavigation = true <br>Component
|
||||
Assets *-- RequestReplyTask : isOpenRequestReply = true <br>Component
|
||||
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
- 해당 페이지에서 정상적인 경로로 접근했는지 체크함.
|
||||
|
||||
```javascript
|
||||
useEffect(() => {
|
||||
// 정상적인 경로로 접근했는지 체크
|
||||
// 증권사 접근 시 네비게이션 Open, 일반 브라우저 접근 시(랜딩 포함) 네비게이션 Close.
|
||||
const isCorrectAccess = chkCorrectAccess();
|
||||
setIsOpenNavigation(isCorrectAccess || isStandalone);
|
||||
}, []);
|
||||
|
||||
|
||||
// src/util/functions.ts
|
||||
// 정상적인 경로로 접근했는지 체크
|
||||
export const chkCorrectAccess = () => {
|
||||
const companyCodeKey = process.env.NEXT_PUBLIC_ACCESS_COMPANY as string;
|
||||
const companyCode = localStorage.getItem(companyCodeKey);
|
||||
const found = PARTNER_LIST.find((item) => item.companyCode === companyCode);
|
||||
|
||||
if (found) return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
```
|
||||
|
||||
```mermaid
|
||||
|
||||
classDiagram
|
||||
class AssetMain {
|
||||
|
||||
}
|
||||
class BottomModal{
|
||||
|
||||
}
|
||||
class PosNegNumber{
|
||||
|
||||
}
|
||||
|
||||
```
|
@ -1,18 +0,0 @@
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Login{
|
||||
param: ref, sccofnstcd
|
||||
}
|
||||
class LoginTask{
|
||||
counselSeq?: number;
|
||||
onConfirm?(bool: boolean): void; // 로그 인 완료
|
||||
onBack?(): void; // 화면뒤로
|
||||
isTest?: boolean;
|
||||
isMTS?: boolean;
|
||||
}
|
||||
class CookieInfo{
|
||||
}
|
||||
class Spinner{
|
||||
}
|
||||
|
||||
```
|
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 374 KiB |
@ -1,7 +0,0 @@
|
||||
# TEST_하나증권_MTS입점(NEW)
|
||||
|
||||
> Q. 하나증권에 계좌가 없는 준회원이다. ci값은 안넘어 올 수 있는데 이경우 콴텍 전략 마켓은 열어주기로 했다는데 해당 메시지는 화면에서 표시되는건가요? 아니면 백엔드 api?
|
||||
>
|
||||
> W. 준회원의 의미는 하나증권MTS 회원인데 계좌가 없다는 뜻?
|
||||
>
|
||||
>
|
@ -1,37 +0,0 @@
|
||||
## PBP-CS 로그인
|
||||
|
||||
#### 1.TaskProcess
|
||||
>
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Browser{
|
||||
}
|
||||
|
||||
class Login{
|
||||
sccofnstcd: url param;
|
||||
}
|
||||
class LoginTask{
|
||||
counselSeq?: number;
|
||||
onConfirm?(bool: boolean): void; // 로그 인 완료
|
||||
isTest?: boolean;
|
||||
isMTS?: boolean;
|
||||
}
|
||||
class PinNumberLoginTask{
|
||||
onConfirm(): void;
|
||||
onLoginFail(bool: boolean, idx: number): void;
|
||||
isMTS: boolean;
|
||||
}
|
||||
class ReSignupProcess{
|
||||
|
||||
}
|
||||
class Assets{
|
||||
|
||||
}
|
||||
|
||||
Browser --> Login : "/login?ref=&sccofnstcd=270"
|
||||
Login --> LoginTask
|
||||
LoginTask --> Assets :onConfirm={onConfirmLogin}
|
||||
LoginTask --> PinNumberLoginTask
|
||||
LoginTask <-- PinNumberLoginTask
|
||||
```
|
@ -1,7 +0,0 @@
|
||||
## PBP-CS 샘플데이터
|
||||
|
||||
PBP-CS는 현재 하나증권 데이터를 받아서 테스트를 하고 있기 때문에 테스트에 어려움 local, dev에서 각 페이지를 통과할 수 있는 방법을 강구하자는 바임
|
||||
|
||||
### 1. 로그인
|
||||
>
|
||||
> 로그인시 매직키패드 및
|
@ -1,7 +0,0 @@
|
||||
# 자산진단
|
||||
|
||||
## 2024-08-26
|
||||
|
||||
### 자산진단페이지에서 자산 index socre 관련 null 처리
|
||||
>
|
||||
> 2024-08-24 이왕호 부장이 처리한 부분 <font color="red">프론트에서 대응 필요</font>
|
@ -1,116 +0,0 @@
|
||||
**투자자산진단**
|
||||
|
||||
진입시 케이스가 2개로 나누어짐
|
||||
|
||||
## 1. 고객ID로 보유종목 조회하는 경우
|
||||
>
|
||||
> 위의 경우는 하나증권의 하나플러스에서 4408 업무코드로 고객의 데이터를 가지고 진입했을때 사용한다. 이의 API는 <br>[GET] `/counsel/asset/hold`를 사용하고 있다.
|
||||
|
||||
```javascript
|
||||
|
||||
//해당 api의 파라미터
|
||||
export interface IAssetListInputParam {
|
||||
customerId?: string;
|
||||
}
|
||||
|
||||
//해당 api의 결과
|
||||
export interface IGetAssetList {
|
||||
customerName: string;
|
||||
stockList: IStockList[];
|
||||
}
|
||||
```
|
||||
|
||||
## 2. ODS 접근 방식으로 보유종목 조회
|
||||
>
|
||||
> 위의 방법은 하나증권 태블릿 업무 단말인 ODS로 진입했을때 사용하는 경우이다.
|
||||
이 방법은 내부에서 /demo 페이지에서 종목코드, 비중을 입력하고 진입하는 경우와 같다.
|
||||
API는 <br> [GET] `/counsel/asset/hold/url`를 사용하고 있다.
|
||||
|
||||
```markdown
|
||||
https://1qdevpb.quantec.co.kr/odsrelay?data={"accesstoken":"123qweeyyyyddsd","corp_uid":"987654321","sccofnstcd":"270","access":"hanaplus","branchno":"0094","gbn":"ra","accountinfo":{"foto":["AAPL","TXN","A396300","A353200","A009410","A040160","A298020"],"rate":["20","15","10","20","10","15","10"]}}
|
||||
```
|
||||
|
||||
url 파라미터에 담아 화면에 진입할때 foto를 해당 api itemCd만을 사용함
|
||||
|
||||
```javascript
|
||||
//해당 api의 파라미터
|
||||
export interface IAssetListOdsParam {
|
||||
itemCd: string;
|
||||
}
|
||||
|
||||
|
||||
// 해당 api의 결과
|
||||
export interface IGetAssetOdsList {
|
||||
customerName: string;
|
||||
stockList: IStockOdsList[];
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
|
||||
{
|
||||
"itemCd": "AAPL,TXN,A396300,A353200,A009410,A040160,A298020"
|
||||
}
|
||||
|
||||
{
|
||||
"customerName": null,
|
||||
"stockList": [
|
||||
{
|
||||
"shortStockCode": "AAPL",
|
||||
"stockName": "애플",
|
||||
"evaluationAmount": null,
|
||||
"holdingWeight": null,
|
||||
"isinCode": "US0378331005",
|
||||
"inputStockCode": "AAPL"
|
||||
},
|
||||
{
|
||||
"shortStockCode": "TXN",
|
||||
"stockName": "텍사스인스트루먼트",
|
||||
"evaluationAmount": null,
|
||||
"holdingWeight": null,
|
||||
"isinCode": "US8825081040",
|
||||
"inputStockCode": "TXN"
|
||||
},
|
||||
{
|
||||
"shortStockCode": "396300",
|
||||
"stockName": "세아메카닉스",
|
||||
"evaluationAmount": null,
|
||||
"holdingWeight": null,
|
||||
"isinCode": "KR7396300006",
|
||||
"inputStockCode": "A396300"
|
||||
},
|
||||
{
|
||||
"shortStockCode": "353200",
|
||||
"stockName": "대덕전자",
|
||||
"evaluationAmount": null,
|
||||
"holdingWeight": null,
|
||||
"isinCode": "KR7353200009",
|
||||
"inputStockCode": "A353200"
|
||||
},
|
||||
{
|
||||
"shortStockCode": "009410",
|
||||
"stockName": "태영건설",
|
||||
"evaluationAmount": null,
|
||||
"holdingWeight": null,
|
||||
"isinCode": "KR7009410002",
|
||||
"inputStockCode": "A009410"
|
||||
},
|
||||
{
|
||||
"shortStockCode": "040160",
|
||||
"stockName": "누리플렉스",
|
||||
"evaluationAmount": null,
|
||||
"holdingWeight": null,
|
||||
"isinCode": "KR7040160004",
|
||||
"inputStockCode": "A040160"
|
||||
},
|
||||
{
|
||||
"shortStockCode": "298020",
|
||||
"stockName": "효성티앤씨",
|
||||
"evaluationAmount": null,
|
||||
"holdingWeight": null,
|
||||
"isinCode": "KR7298020009",
|
||||
"inputStockCode": "A298020"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
@ -1,441 +0,0 @@
|
||||
**2024-08-12**
|
||||
|
||||
수익률 광고 api (`market/strategy/promotion`)추가로 인하여 `market/strategy/detail` api가 사용되지 않게됨. <br />
|
||||
리포트 strategy/detail 사용하는 부분strategy/promotion으로 대체.
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
`market/strategy/detail`의 response 구조
|
||||
|
||||
```json
|
||||
{
|
||||
"strategyPlan": {
|
||||
"strategyId": "KP0092",
|
||||
"raCode": "RA113143",
|
||||
"portType": "2",
|
||||
"strategyName": "노후 보장 치트키, 연금 추종 전략",
|
||||
"subStrategyName": "콴텍 Q-Shield 국내 EMP4호",
|
||||
"comdType": "KP",
|
||||
"code": "0092",
|
||||
"investTypeCode": "3",
|
||||
"investTypeName": "위험중립형",
|
||||
"strategyDescript": "콴텍으로 노후대비, 참 잘했다 싶어요! 일본 연금기관의 운용 방식처럼 보수적이고 탄탄한 자산배분을 통해 장기적으로 우상향하는 투자 성과를 추구하는 EMP 포트폴리오 전략이에요.",
|
||||
"hashTags": "#연금추종 #자산배분 #장기투자",
|
||||
"investTarket": null,
|
||||
"baseFeeRate": null,
|
||||
"performanceFeeRate": null,
|
||||
"feePaymentMethod": null,
|
||||
"joinTerm": null,
|
||||
"activeYn": null,
|
||||
"referenceInfo": [
|
||||
{
|
||||
"addDesc1": "가입자의 평균 연령은",
|
||||
"addDesc2": "47 세",
|
||||
"emoji": "1F469"
|
||||
},
|
||||
{
|
||||
"addDesc1": "최고령자는",
|
||||
"addDesc2": "57 세",
|
||||
"emoji": "1F474"
|
||||
},
|
||||
{
|
||||
"addDesc1": "평균 투자금액은",
|
||||
"addDesc2": "500 만원",
|
||||
"emoji": "1F4B0"
|
||||
},
|
||||
{
|
||||
"addDesc1": "최고 투자금액은",
|
||||
"addDesc2": "800 만원",
|
||||
"emoji": "1F4B0"
|
||||
}
|
||||
],
|
||||
"strategyDefaultInfo": {
|
||||
"strategyId": "KP0092",
|
||||
"raCode": "RA113143",
|
||||
"portType": "2",
|
||||
"strategyName": "노후 보장 치트키, 연금 추종 전략",
|
||||
"subStrategyName": "콴텍 Q-Shield 국내 EMP4호",
|
||||
"groupTypeCode": "S",
|
||||
"minInvestAmount": "2,000,000원",
|
||||
"maxInvestAmount": "2,000,000원",
|
||||
"defaultFee": "0%",
|
||||
"performanceFee": "15%",
|
||||
"maximumManagement": "규모 제한 없음",
|
||||
"rebalancingTerm": "정기 및 수시 리밸런싱",
|
||||
"investTarket": "한국거래소 상장 ETF 및 기타 예수금",
|
||||
"serviceStartDate": "2022년 9월 19일~",
|
||||
"joinTerm": "계약 체결일로부터 1년|(1년 단위 자동 연장)",
|
||||
"paymentMethod": "원화 (KRW) 현금",
|
||||
"managementPlan1": "한국 상장 ETF로 유니버스 구성",
|
||||
"managementPlan2": "보수적인 관점의 자산배분 전략 활용",
|
||||
"managementPlan3": "콴텍 Q-엔진을 통한 시장 판단 및 위험관리 기능 강화",
|
||||
"managementAlgorithmName": "<b>콴텍 Q-Shield 국내 EMP 4호</b>",
|
||||
"managementAlgorithmRate": "100%",
|
||||
"managementAlgorithmUniverse": "주식 및 채권 ETF(한국 상장)",
|
||||
"managementAlgorithmBenchmark": "MSCI 글로벌 주식+글로벌 채권",
|
||||
"managementAlgorithmCoreFector": "노후보장 치트키&연금추종전략",
|
||||
"managementAlgorithmStyle": "자산배분 블렌드(blend)",
|
||||
"managementAlgorithmRiskManagement": "Q-X 모듈 단계별 현금 비중 조절",
|
||||
"fileUrl": ""
|
||||
}
|
||||
},
|
||||
"strategyInvestTypeInfo": [
|
||||
{
|
||||
"strategyId": "KP0092",
|
||||
"raCode": "RA113143",
|
||||
"portType": "2",
|
||||
"strategyName": "노후 보장 치트키, 연금 추종 전략",
|
||||
"investTypeCode": "2",
|
||||
"investTypeName": "위험중립형",
|
||||
"assetRate": [
|
||||
{
|
||||
"assetsCode": "S",
|
||||
"assetsName": "주식형",
|
||||
"assetsRate": 0.75,
|
||||
"assetsOrder": 1
|
||||
},
|
||||
{
|
||||
"assetsCode": "B",
|
||||
"assetsName": "채권형",
|
||||
"assetsRate": 0,
|
||||
"assetsOrder": 2
|
||||
},
|
||||
{
|
||||
"assetsCode": "G",
|
||||
"assetsName": "실물형",
|
||||
"assetsRate": 0,
|
||||
"assetsOrder": 3
|
||||
},
|
||||
{
|
||||
"assetsCode": "W",
|
||||
"assetsName": "현금(KRW)",
|
||||
"assetsRate": 0.25,
|
||||
"assetsOrder": 4
|
||||
},
|
||||
{
|
||||
"assetsCode": "E",
|
||||
"assetsName": "ETF",
|
||||
"assetsRate": 0,
|
||||
"assetsOrder": 5
|
||||
},
|
||||
{
|
||||
"assetsCode": "F",
|
||||
"assetsName": "펀드",
|
||||
"assetsRate": 0,
|
||||
"assetsOrder": 6
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"strategyId": "KP0093",
|
||||
"raCode": "RA113142",
|
||||
"portType": "2",
|
||||
"strategyName": "노후 보장 치트키, 연금 추종 전략",
|
||||
"investTypeCode": "3",
|
||||
"investTypeName": "안정추구형",
|
||||
"assetRate": [
|
||||
{
|
||||
"assetsCode": "S",
|
||||
"assetsName": "주식형",
|
||||
"assetsRate": 0.5,
|
||||
"assetsOrder": 1
|
||||
},
|
||||
{
|
||||
"assetsCode": "B",
|
||||
"assetsName": "채권형",
|
||||
"assetsRate": 0,
|
||||
"assetsOrder": 2
|
||||
},
|
||||
{
|
||||
"assetsCode": "G",
|
||||
"assetsName": "실물형",
|
||||
"assetsRate": 0,
|
||||
"assetsOrder": 3
|
||||
},
|
||||
{
|
||||
"assetsCode": "W",
|
||||
"assetsName": "현금(KRW)",
|
||||
"assetsRate": 0.5,
|
||||
"assetsOrder": 4
|
||||
},
|
||||
{
|
||||
"assetsCode": "E",
|
||||
"assetsName": "ETF",
|
||||
"assetsRate": 0,
|
||||
"assetsOrder": 5
|
||||
},
|
||||
{
|
||||
"assetsCode": "F",
|
||||
"assetsName": "펀드",
|
||||
"assetsRate": 0,
|
||||
"assetsOrder": 6
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
`market/strategy/promotion` 의 response 구조
|
||||
|
||||
```json
|
||||
{
|
||||
"topInfo": {
|
||||
"strategyId": "KP0011",
|
||||
"strategyName": "파이어족 꿈꾸기",
|
||||
"globalType": "1",
|
||||
"portType": "1",
|
||||
"comdKind": "1",
|
||||
"hashTag": [
|
||||
"#한국중소형",
|
||||
"#실적주",
|
||||
"#시장나침반"
|
||||
],
|
||||
"pubStartDate": "20190211",
|
||||
"baseDate": "20240809",
|
||||
"pubYears": "5.4",
|
||||
"referenceInfo": [
|
||||
{
|
||||
"investType": "2",
|
||||
"title": "누적 수익률",
|
||||
"content": "293.86"
|
||||
},
|
||||
{
|
||||
"investType": "",
|
||||
"title": "알고리즘|공시시작일",
|
||||
"content": "2019.02.11"
|
||||
},
|
||||
{
|
||||
"investType": "",
|
||||
"title": "평균투자금액",
|
||||
"content": "414 만원"
|
||||
},
|
||||
{
|
||||
"investType": "",
|
||||
"title": "최고투자금액",
|
||||
"content": "7,007 만원"
|
||||
}
|
||||
]
|
||||
},
|
||||
"strategyInfo": {
|
||||
"industryInfoList": [
|
||||
{
|
||||
"industryId": "005",
|
||||
"industryName": "식품,음료,담배",
|
||||
"industryImageURL": "https://apidev.quantec.co.kr:8000/v1/img/app/grouping_a_5.png"
|
||||
},
|
||||
{
|
||||
"industryId": "007",
|
||||
"industryName": "자본재",
|
||||
"industryImageURL": "https://apidev.quantec.co.kr:8000/v1/img/app/grouping_a_7.png"
|
||||
},
|
||||
{
|
||||
"industryId": "024",
|
||||
"industryName": "소프트웨어와 서비스",
|
||||
"industryImageURL": "https://apidev.quantec.co.kr:8000/v1/img/app/grouping_a_24.png"
|
||||
}
|
||||
],
|
||||
"testbedName": "콴텍 가치투자 주식형2호",
|
||||
"strategyDescription": "한국 강소기업 중에서 현금을 많이 보유하고 있고, 현금 흐름 개선으로 성장 잠재력이 높은 기업을 위주로 구성한 포트폴리오에요. 투자 위험 대비 높은 기대 수익을 추구하여, 단기 목돈 마련을 원하는 분에게 적합해요.",
|
||||
"recommendedInvestAmount": 3000000,
|
||||
"minInvestAmount": 1500000,
|
||||
"defaultFee": 0,
|
||||
"performanceFee": 15,
|
||||
"maximumManagement": "규모 제한 없음",
|
||||
"rebalancingTerm": "정기 및 수시 리밸런싱",
|
||||
"investTarget": "한국거래소 상장 및 등록 기업의 주권, 기타 예수금",
|
||||
"serviceStartDate": "2022년 4월 1일~",
|
||||
"joinTerm": "계약 체결일로부터 1년|(1년 단위 자동 연장)",
|
||||
"paymentMethod": "원화(KRW)현금",
|
||||
"strategyIndexInfo": {
|
||||
"pubStartDate": "20190211",
|
||||
"baseDate": "20240809",
|
||||
"pubYears": "5.4",
|
||||
"indexInfo": [
|
||||
{
|
||||
"strategyId": "KP0013",
|
||||
"investType": "4",
|
||||
"operationAmount": 3263049,
|
||||
"oneWeekProfitRate": -1.67,
|
||||
"oneMonthProfitRate": -3.16,
|
||||
"threeMonthProfitRate": -4.56,
|
||||
"sixMonthProfitRate": -4.61,
|
||||
"oneYearProfitRate": -2.76,
|
||||
"twoYearProfitRate": 4.57,
|
||||
"threeYearProfitRate": 0.81,
|
||||
"yearExchangeProfitIndex": 9.77,
|
||||
"fullProfitRate": 67.61,
|
||||
"standardDeviation": 0.09,
|
||||
"beta": 0.29,
|
||||
"sharpeRatio": 0.82,
|
||||
"alpha": 0.07,
|
||||
"infoRate": 0.35,
|
||||
"trackError": 0.16,
|
||||
"rewardRate": 3.58,
|
||||
"mdd": -13.6
|
||||
},
|
||||
{
|
||||
"strategyId": "KP0012",
|
||||
"investType": "3",
|
||||
"operationAmount": 4378076,
|
||||
"oneWeekProfitRate": -2.94,
|
||||
"oneMonthProfitRate": -5.64,
|
||||
"threeMonthProfitRate": -8.3,
|
||||
"sixMonthProfitRate": -8.47,
|
||||
"oneYearProfitRate": -6.83,
|
||||
"twoYearProfitRate": 3.58,
|
||||
"threeYearProfitRate": -1.97,
|
||||
"yearExchangeProfitIndex": 14.86,
|
||||
"fullProfitRate": 122.25,
|
||||
"standardDeviation": 0.15,
|
||||
"beta": 0.48,
|
||||
"sharpeRatio": 0.83,
|
||||
"alpha": 0.12,
|
||||
"infoRate": 0.67,
|
||||
"trackError": 0.16,
|
||||
"rewardRate": 2.98,
|
||||
"mdd": -23.73
|
||||
},
|
||||
{
|
||||
"strategyId": "KP0011",
|
||||
"investType": "2",
|
||||
"operationAmount": 2588359,
|
||||
"oneWeekProfitRate": -6.14,
|
||||
"oneMonthProfitRate": -11.54,
|
||||
"threeMonthProfitRate": -16.8,
|
||||
"sixMonthProfitRate": -17.62,
|
||||
"oneYearProfitRate": -16.56,
|
||||
"twoYearProfitRate": -1.86,
|
||||
"threeYearProfitRate": -12.89,
|
||||
"yearExchangeProfitIndex": 25.18,
|
||||
"fullProfitRate": 293.86,
|
||||
"standardDeviation": 0.31,
|
||||
"beta": 0.98,
|
||||
"sharpeRatio": 0.75,
|
||||
"alpha": 0.21,
|
||||
"infoRate": 0.87,
|
||||
"trackError": 0.24,
|
||||
"rewardRate": 1.86,
|
||||
"mdd": -46.8
|
||||
}
|
||||
]
|
||||
},
|
||||
"addDepositPartlyWithdraw": [
|
||||
"납입기간 중 추가입금 가능 (상품별 최소 추가입금 단위 부여)",
|
||||
"일임 운용의 효율을 제고하기 위해 일부 출금|(부분 출금)은 불가하나 중도해지 후 출금 가능",
|
||||
"운용의 효율을 제고하기 위해 일부(부분) 출금은 불가하나 전액 중도해지 후 일부 출금 가능합니다"
|
||||
],
|
||||
"exchangRateHedge": [
|
||||
"국내 원화자산의 환율 변동 위험 없음"
|
||||
],
|
||||
"lawScreeningNo": ""
|
||||
},
|
||||
"managementInfo": {
|
||||
"strategyAssetInfo": [
|
||||
{
|
||||
"strategyId": "KP0011",
|
||||
"investType": "2",
|
||||
"assetInfo": [
|
||||
{
|
||||
"skind": "S",
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"strategyId": "KP0012",
|
||||
"investType": "3",
|
||||
"assetInfo": [
|
||||
{
|
||||
"skind": "S",
|
||||
"weight": 0.5
|
||||
},
|
||||
{
|
||||
"skind": "W",
|
||||
"weight": 0.5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"strategyId": "KP0013",
|
||||
"investType": "4",
|
||||
"assetInfo": [
|
||||
{
|
||||
"skind": "S",
|
||||
"weight": 0.3
|
||||
},
|
||||
{
|
||||
"skind": "W",
|
||||
"weight": 0.7
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"managementPlan": [
|
||||
"한국 중소형주 위주로 유니버스 구성",
|
||||
"기업의 유동성 중심의 종목 픽업과 자산배분 알고리즘 활용",
|
||||
"콴텍 Q-엔진을 통한 시장 판단 및 위험관리 기능 강화"
|
||||
],
|
||||
"managementAlgorithmName": [
|
||||
{
|
||||
"title": "<b>콴텍 가치투자 주식형 2호</b>",
|
||||
"content": "100%"
|
||||
}
|
||||
],
|
||||
"managementAlgorithm": [
|
||||
{
|
||||
"title": "<b>유니버스</b>",
|
||||
"content": "한국 중소형주(mid-small cap)"
|
||||
},
|
||||
{
|
||||
"title": "<b>벤치마크</b>",
|
||||
"content": "코스피 종합지수(KOSPI)"
|
||||
},
|
||||
{
|
||||
"title": "<b>코어팩터</b>",
|
||||
"content": "FCF&Quality 팩터"
|
||||
},
|
||||
{
|
||||
"title": "<b>스타일</b>",
|
||||
"content": "중소형 가치주(value)"
|
||||
},
|
||||
{
|
||||
"title": "<b>위험관리</b>",
|
||||
"content": "Q-X 모듈 단계별 현금 비중 조절"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
## 피드백 상황 2024-08-21
|
||||
|
||||
- 홍광진이사
|
||||
|
||||
1. 최근 1개월과 6개월은 하단의 기간이 이상하고, 1개월, 6개월, 1년 수익률 그래프가 모두 동일합니다.
|
||||
|
||||

|
||||
|
||||
2. 미흡 및 주요 지표 설명은 아래 화면처럼 주의/미흡인 종목들 아래에 확장된 형태로 붙어서 나오는거고 종목도 우수~주의 순서로 정렬되어야 하지 않나요?
|
||||
|
||||

|
||||
|
||||
3. 차트 위의 텍스트 위치 조정도 필요합니다.
|
||||
|
||||

|
||||

|
||||
|
||||
4. 기획팀에서 전달 받은 피드백 ppt파일
|
||||
[기획 수정 요청 ppt 파일](<240821_PB플랫폼 수정요청_리포트.pptx>)
|
||||
|
||||
>> 2024-08-28 우선 데이터 맞추어 놨고 디자인은 차후 수정하겠음
|
Before Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 88 KiB |