Skip to content

Commit

Permalink
[Feat] 지정 매수/매도호가 이외 가격 지정 시 예약매수/매도 안내 기능 구현
Browse files Browse the repository at this point in the history
- BE에서 설계한 로직 상, 미리 지정해놓은 매수/매도호가 안에서만 거래가 가능한 상황
- 유저가 이외 가격을 지정할 시 즉시 거래 체결이 불가하며, 예약 매수/매도 목록에 포함됨을 안내하는 기능 구현 (indicator 관련 디자인은 추후 수정할 예정)
- 예약 매수/매도 목록의 경우 30분 간격으로 주가 데이터 갱신될 때 지정 호가 여부인지 재점검 하여 지정 호가인 경우 체결처리

Issues #17
  • Loading branch information
novice1993 committed Sep 11, 2023
1 parent 05dde28 commit c40696f
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 28 deletions.
98 changes: 78 additions & 20 deletions client/src/components/StockOrderSection/PriceSetting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useSelector, useDispatch } from "react-redux";
import { styled } from "styled-components";
import { setStockOrderPrice, plusStockOrderPrice, minusStockOrderPrice } from "../../reducer/StockOrderPrice-Reducer";
import { StateProps } from "../../models/stateProps";
import { StockInfoprops } from "../../models/stockInfoProps";
import { StockInfoProps } from "../../models/stockInfoProps";

const priceSettingTitle: string = "가격";
const unitText: string = "원";
Expand All @@ -14,14 +14,53 @@ const PriceSetting = (props: OwnProps) => {
const dispatch = useDispatch();
const orderPrice = useSelector((state: StateProps) => state.stockOrderPrice);

// 가격 조정 관련 타이머 상태
const [priceChangeTimer, setPriceChangeTimer] = useState<NodeJS.Timeout | null>(null);

// 초기 설정값 및 가격 변동폭 설정
const { askp1, askp2, askp3, askp4, askp5 } = stockInfo;
const [priceChangeTimer, setPriceChangeTimer] = useState<NodeJS.Timeout | null>(null);
const sellingPrice = [parseInt(askp1), parseInt(askp2), parseInt(askp3), parseInt(askp4), parseInt(askp5)];
const existSellingPrice = sellingPrice.filter((price) => price !== 0); // price 0인 경우 제거
const defaultPrice = existSellingPrice[0];
const priceInterval = existSellingPrice[1] - existSellingPrice[0];

// 🔴 [TestCode] 거래가능 안내 메세지 테스트 -> 🟢 구현 성공하여 코드 정리할 예정
const orderType = useSelector((state: StateProps) => state.stockOrderType);
const [orderPossibility, setOrderPossibility] = useState(true);

const { bidp1, bidp2, bidp3, bidp4, bidp5 } = stockInfo;
const buyingPrice = [parseInt(bidp1), parseInt(bidp2), parseInt(bidp3), parseInt(bidp4), parseInt(bidp5)];
const existBuyingPrice = buyingPrice.filter((price) => price !== 0); // price 0인 경우 제거

// 거래 가능여부 판별 함수
const handleCheckTradePossibility = () => {
if (orderType) {
// 매수 주문
if (orderPrice !== 0 && !existBuyingPrice.includes(orderPrice)) {
setOrderPossibility(false);
} else {
setOrderPossibility(true);
}
} else {
// 매도 주문
if (orderPrice !== 0 && !existSellingPrice.includes(orderPrice)) {
setOrderPossibility(false);
} else {
setOrderPossibility(true);
}
}
};

useEffect(() => {
handleCheckTradePossibility();
}, [orderPrice]);

// 가격 설정란에서 포커스 제거 -> 안내 메세지 제거
const handleRemoveNoVolumeNotification = () => {
setOrderPossibility(true);
};
// 🔴 [TestCode] 거래가능 안내 메세지 테스트 -> 🟢 구현 성공하여 코드 정리할 예정

// 거래가 증가/감소
const handlePlusOrderPrice = () => {
dispatch(plusStockOrderPrice(priceInterval));
Expand All @@ -31,7 +70,7 @@ const PriceSetting = (props: OwnProps) => {
dispatch(minusStockOrderPrice(priceInterval));
};

// 방향키 입력 시
// 위-아래 방향키 입력 시
const handleInputArrowBtn = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.code === "ArrowUp") {
handlePlusOrderPrice();
Expand Down Expand Up @@ -77,30 +116,43 @@ const PriceSetting = (props: OwnProps) => {
}, [companyId]);

return (
<Container>
<div className="PriceCategoryBox">
<div className="Title">{priceSettingTitle}</div>
</div>
<div className="PriceSettingBox">
<PriceController defaultValue={orderPrice} value={orderPrice} onChange={handleWriteOrderPrice} onKeyDown={handleInputArrowBtn} />
<UnitContent>{unitText}</UnitContent>
<div className="DirectionBox">
<button className="PriceUp" onClick={handlePlusOrderPrice}>
&#8896;
</button>
<button className="PriceDown" onClick={handleMinusOrderPrice}>
&#8897;
</button>
<>
<Container>
<div className="PriceCategoryBox">
<div className="Title">{priceSettingTitle}</div>
</div>
</div>
</Container>
<div className="PriceSettingBox">
<PriceController defaultValue={orderPrice} value={orderPrice} onChange={handleWriteOrderPrice} onKeyDown={handleInputArrowBtn} onFocus={handleCheckTradePossibility} onBlur={handleRemoveNoVolumeNotification} />
<UnitContent>{unitText}</UnitContent>
<div className="DirectionBox">
<button className="PriceUp" onClick={handlePlusOrderPrice} onBlur={handleRemoveNoVolumeNotification}>
&#8896;
</button>
<button className="PriceDown" onClick={handleMinusOrderPrice} onBlur={handleRemoveNoVolumeNotification}>
&#8897;
</button>
</div>
</div>
</Container>

{/* 거래 불가 테스트 */}
{!orderPossibility && (
<NoTradingVolume>
<div className="container">
거래 불가하며 예약 거래 됨을 공지
<div></div>
<div></div>
</div>
</NoTradingVolume>
)}
</>
);
};

export default PriceSetting;

interface OwnProps {
stockInfo: StockInfoprops;
stockInfo: StockInfoProps;
companyId: number;
}

Expand Down Expand Up @@ -192,3 +244,9 @@ const UnitContent = styled.div`
border-bottom: 1px solid darkgray;
background-color: #ffffff;
`;

const NoTradingVolume = styled.div`
position: absolute;
top: 222px;
right: 10px;
`;
8 changes: 4 additions & 4 deletions client/src/hooks/useGetStockData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ const useGetStockData = (companyId: number) => {
const { data, isLoading, error, refetch } = useQuery(`chartData${companyId} ${queryKey}`, () => getChartData(companyId), {
enabled: true,
refetchInterval: autoRefetch ? 60000 * 10 : false, // 정각 혹은 30분에 맞춰서 10분 마다 데이터 리패칭
onSuccess: () => {
console.log(new Date());
console.log(data);
},
// onSuccess: () => {
// console.log(new Date());
// console.log(data);
// },
});

return { stockPrice: data, stockPriceLoading: isLoading, stockPriceError: error };
Expand Down
8 changes: 4 additions & 4 deletions client/src/hooks/useGetStockInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ const useGetStockInfo = (companyId: number) => {
const { data, isLoading, error, refetch } = useQuery(`stockInfo${companyId} ${queryKey}}`, () => getStockInfo(companyId), {
enabled: true,
refetchInterval: autoRefetch ? 60000 * 10 : false, // 정각 혹은 30분에 맞춰서 10분 마다 데이터 리패칭
onSuccess: () => {
console.log(new Date());
console.log(data);
},
// onSuccess: () => {
// console.log(new Date());
// console.log(data);
// },
});

return { stockInfo: data, stockInfoLoading: isLoading, stockInfoError: error };
Expand Down

0 comments on commit c40696f

Please sign in to comment.