Compare commits

...

1 Commits

Author SHA1 Message Date
익희 김
9d5b979da7 초기화 2024-09-04 21:56:59 +09:00
29 changed files with 0 additions and 2104 deletions

0
nextjs/README.md Normal file
View File

View File

@ -1,3 +0,0 @@
## 단어정리
1.

View File

@ -1,24 +0,0 @@
### 용어 정리
1. 수도결제(受渡, settlement): 증권의 매매 거래, 증권과 그 대금을 주고 받는 것. 매매 계약 체결 후 3일째가 되는 날에 수도. 이러한 수도에 의하여 매매 계약을 이행하는 것을 수도 결제라고 하며, 그 거래를 수도 거래라고 한다.
2. 투자가능금액 =/= 주문가능금액
1) 투자가능금액: 계좌 입금금액(현금 중) 투자에 사용할 수 있는 금액. 보유중인 주식, 타 자산 매도하여 얻은 현금 포함될 수 있음. 그러나 결제가 완료되지 않은 거래에서 발생한 금액은 포함되지 않을 수 있음.
2) 주문가능금액: 현재 증권 계좌에서 주문을 할 때 실제로 사용할 수 있는 금액. 투자가능금액에서 미체결된 주문의 금액을 차감한 금액일 수 있음.
```mermaid
flowchart TD
n1["출금가능금액"]
n2["주문가능금액"]
n3["가입상품"]
n4["환전신청금액"]
```
3. 예수금
> 계좌에 주식 거래를 위해 입금한 금액. 예수금을 증거금으로 활용하거나 인출 할 수 있다.
4. 안전 마진, 잔여 예수금
> 주식 매수 투자자 보호 및 거래 안정성 계좌에 일부 금액 남기게 설정. 주식 매수 시 발생할 수 있는 불확실한 수수료, 세금, 가격 변동 부족한 금액이 발생하는것 방지 조치
> 남겨둔 금액은 수수료 기타 비용 커버 사용, 실제 매매 금액 부족할 때 대비 남기는 금액

View File

@ -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{
}
```

View File

@ -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{
}
```

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 KiB

View File

@ -1,7 +0,0 @@
# TEST_하나증권_MTS입점(NEW)
> Q. 하나증권에 계좌가 없는 준회원이다. ci값은 안넘어 올 수 있는데 이경우 콴텍 전략 마켓은 열어주기로 했다는데 해당 메시지는 화면에서 표시되는건가요? 아니면 백엔드 api?
>
> W. 준회원의 의미는 하나증권MTS 회원인데 계좌가 없다는 뜻?
>
>

View File

@ -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
```

View File

@ -1,7 +0,0 @@
## PBP-CS 샘플데이터
PBP-CS는 현재 하나증권 데이터를 받아서 테스트를 하고 있기 때문에 테스트에 어려움 local, dev에서 각 페이지를 통과할 수 있는 방법을 강구하자는 바임
### 1. 로그인
>
> 로그인시 매직키패드 및

View File

@ -1,7 +0,0 @@
# 자산진단
## 2024-08-26
### 자산진단페이지에서 자산 index socre 관련 null 처리
>
> 2024-08-24 이왕호 부장이 처리한 부분 <font color="red">프론트에서 대응 필요</font>

View File

@ -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"
}
]
}
```

View File

@ -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년 수익률 그래프가 모두 동일합니다.
![alt text](image.png)
2. 미흡 및 주요 지표 설명은 아래 화면처럼 주의/미흡인 종목들 아래에 확장된 형태로 붙어서 나오는거고 종목도 우수~주의 순서로 정렬되어야 하지 않나요?
![alt text](image-1.png)
3. 차트 위의 텍스트 위치 조정도 필요합니다.
![alt text](image-2.png)
![alt text](image-3.png)
4. 기획팀에서 전달 받은 피드백 ppt파일
[기획 수정 요청 ppt 파일](<240821_PB플랫폼 수정요청_리포트.pptx>)
>> 2024-08-28 우선 데이터 맞추어 놨고 디자인은 차후 수정하겠음

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB