커뮤니티

주문접수나 취소시에 그 내역들이 Account객체에 반영되는 메카니즘을 알고 싶습니다

프로필 이미지
김태희
2015-05-27 12:08:22
272
글번호 86422
답변완료
문의1) 증권사 시스템은 사용자가 주문을 낼때 계좌에 예탁금이 충분한지를 체크합니다. 예를들어, 현재 예탁금으로 주문가능한 계약수는 3계약인데, 그 이상을 주문하면 당연히 주문은 실패하겠죠. 이때 주문을 내는데 필요한 금액이 계좌에 예치되어 있는지에대한 판단(즉, 주문가능 여부에 대한 판단)을 사용자PC에서 하는지 증권사 서버에서 하는지 가 궁금해서 제가 다음과 같이 수식을 짜서 테스트 삼아 돌려보았습니다. 실제계좌에 3100만원을 입금시키고 예스스팟에서 자동주문으로 실행하였습니다. 예스트레이더의 통합주문(2101)화면에서 코스피200 선물6월물로 주문가능한 계약수를 확인해보니 3계약까지 가능하더군요. function Main_OnStart() { var i, j, k=0, l, jumunka=250; Main.MessageList("주문시작:"); for (i=0; i<3; i++) { j = Account.OrderBuy(future.code, 1, jumunka, 0); jumunka += 0.05; k = Account.GetTheNumberOfUnfills(); l = Account.GetBalanceETCinfo(29); Main.MessageList(i, j, k, l); } Main.SetTimer(1, 20000); } function Main_OnOrderResponse(OrderResponse) { var x, y; x = Account.GetTheNumberOfUnfills(); y = Account.GetBalanceETCinfo(29); Main.MessageList("OnOrderResponse:", OrderResponse.orderID, OrderResponse.orderNum, OrderResponse.orgOrderNum, OrderResponse.orderPrice, OrderResponse.isNormal, x, y); } function Main_OnTimer(nEventID) { var i, j, k, l, m; Main.KillTimer(1); k = Account.GetTheNumberOfUnfills(); Main.MessageList("주문취소:", k); for (i=0; i<k; i++) { Account.SetUnfillIndex(i); j = Account.OrderCancel(Account.Unfill.orderNum); m = Account.GetTheNumberOfUnfills(); l = Account.GetBalanceETCinfo(29); Main.MessageList("OnTimer:", i, j, m, l); } j = Account.OrderBuy(future.code, 3, 252, 0); m = Account.GetTheNumberOfUnfills(); l = Account.GetBalanceETCinfo(29); Main.MessageList("OnTimer:", 99999, j, m, l); } 실행한 결과는 다음과 같습니다. 주문시작: 0 1 0 31000000 1 2 0 31000000 2 3 0 31000000 OnOrderResponse: 1 437 0 250 ture 1 31000000 OnOrderResponse: 2 438 0 250.05 true 2 31000000 OnOrderResponse: 3 439 0 250.1 true 3 31000000 주문취소: 3 OnTimer: 0 4 3 1071625 OnTimer: 1 5 3 1071625 OnTimer: 2 6 3 1071625 OnTimer: 99999 7 3 1071625 OnOrderResponse: 4 440 437 0 true 2 1071625 OnOrderResponse: 5 441 438 0 true 1 1071625 OnOrderResponse: 6 442 439 0 true 0 1071625 OnOrderResponse: 7 443 0 252 true 1 1071625 근데, 실행결과를 보면 이상한 점들이 있어서 문의드립니다. 신규로 1계약씩 총 3계약을 매수주문을 냄과 동시에 미체결내역 수와 주문가능총액을 MessageList()로 찍어보면 account계좌에 즉각 반영이 안되더군요. OnOrderResponse 이벤트가 발생하고 나서야 그나마 미체결내역 수는 계좌(Account객체)에 반영되는데, 주문가능총액은 여전히 반영이 안된채로 31,000,000원을 그대로 표시해주네요. 주문가능총액도 주문응답을 하나씩 받을때마다 단계적으로 감소해야 될거 같은데 말이죠. 주문가능총액은 타이머로 20초 후에 전체 매수주문에대해 취소주문을 낼 때 쯤에야 1,071,625원이 Account객체에 반영이 된걸 확인할수 있네요 또한 취소주문을 냄과 동시에 미체결 내역수를 찍어봐도 역시 바로 Account객체에 반영이 안되고 3으로 표시됩니다. 취소주문을 1개씩 낼때마다 미체결 내역도 &#8211;1씩 감소해야 정상인데, 그러질 않네요. 근데, 여기서 정말 이상한 점은... 취소주문을 3개를 냈긴 하지만 아직 미체결 내역 수는 3이고, 주문가능 총액은 1,071,625원으로, 주문 취소한 내역이 아직 Account객체에 반영이 안된 상태인데, 3계약 매수주문은 정상적으로 실행이 되더군요. 주문가능총액이 부족하면 3계약 매수주문이 실행이 되선 안될 거 같은데 말이죠. 주문을 내거나 취소시에 미체결 내역 수와 주문가능총액 등이 계좌객체에 바로 반영되는 것도 있고 느리게 반영되는 것도 있고, 이런 식으로 반영되는 시차가 제각각이면...제가 수식으로 주문가능한 계약수를 계산할 때 잘못된 값을 계산할 수도 있을 거 같은데요. 주문가능한 계약수를 계산하려면 주문가능총액 가지고 계산할 수 밖에 없는데, 정확한 반영 여부를 알수가 없다면 문제가 있을 거 같습니다. 그리고, 제가 궁금해 했던...주문을 내는데 필요한 금액이 계좌에 예치되어 있는지에대한 판단, 즉, 주문가능 여부에대한 판단을 사용자PC에서 하는지 증권사 서버에서 하는지에 대해서는 일단 증권사 서버에서 하진 않고 사용자PC에서 하는 거 같군요. 증권사 서버로부터 주문응답(OrderResponse)을 받기도 전에 주문은 즉각적으로 바로 나가는 걸 보면 사용자 PC에서 하는거 같은데, 제 생각이 맞나요? 요약하면, 주문을 내거나 주문취소 등의 행위가 있을 시에 이러한 내역들이 Account객체에 반영되는 메카니즘을 알고 싶습니다. 어떤 방식으로 계좌객체에 반영되는지...전체적인 동작방식이 잘 이해가 안됩니다. 문의2) 이건 다른 문제인데요. 원래 종목객체 추가는 15초당 60회, 주문은 15초당 90회..이렇게 횟수제한이 있는 걸로 알고 있는데, 동시에 여러개의 전략을 실행시키니까 시간제한 오류가 발생하지 않는군요. 예를들어, A전략과 B전략이 둘다 15초당 60번의 종목객체를 추가하도록 수식을 작성한 상태에서 예스스팟에서 2개의 전략을 동시에 실행시키면 A전략과 B전략이 15초당 총 120번의 종목객체를 추가하게 되는데, 실제로 이렇게 실행시켜봤더니 시간제한 오류를 발생시키지 않고 정상적으로 2개 전략이 잘 실행되더군요. 15초당 60회(혹은 90회) 횟수 제한이 예스트레이더의 예스스팟 화면에서 실행되는 전체 전략들을 대상으로 그 횟수가 계산되어 제한이 가해지는게 아니고, 각각의 전략단위로 계산되어 제한이 가해지는 거 같군요. 그러면 동일한 전략을 1개의 전략으로 만들지 않고, 여러개의 전략으로 나누어 만들면 15초당 60회(혹은 90회) 등의 회수제한에 제약됨이 없이 무제한으로 이용할 수 있다는 얘긴데...이렇게 사용해도 되나요? 그러면 증권사에서 시간제한,횟수제한을 둔 의미가 없어지는데....이렇게 전략을 여러개로 나누어 동시에 실행시킬 때 기술적인 혹은 기타 문제점은 없는지 궁금합니다. 그리고, 한가지 더 좀 여쭐게요. 시간제한 오류가 발생하면 전략 수행이 통째로 멈춰버리던데, 제가 20초 후에 타이머를 작성하도록 수식을 짰는데, 그 전에 시간제한 오류가 발생하니까 20초가 지나도 타이머가 작동을 안하네요. 게다가, OnUp dateMarket 이벤트조차도 더 이상 발생을 안합니다. 시간제한 오류가 발생했는데 그와 상관없는 OnUp dateMarket 이벤트가 왜 멈추는지도 잘 이해가 안되고... 원래 시간제한 오류 발생하면 전략 실행이 올스톱 되나요? 이게 시간제한 오류가 발생한 해당 전략만 올스톱되는게 아니라 시간제한이 발생하지 않은 멀쩡하게 잘 실행되던 다른 전략까지 올스톱됩니다. 예스스팟(6131)화면에서 모든 전략들이 빨간색으로 “제한”이란 표시가 뜨면서, 15초가 지나도 그대로 있습니다. 이거 15초가 지나면 제한이 풀려야 되지 않나요? 한 전략에서 시간제한 오류가 발생하더라도 다른 전략에는 영향을 미치면 안될 거 같은데...이거 좀 골치 아프네요. 시간제한 오류가 발생하더라도 15초가 지나면 전략은 다시 정상 수행해야 되지 않나요? 그러니까 내용을 요약하면 이렇습니다. 복수개의 전략들에 대해 원천적으로 각 전략마다 15초동안 60회(혹은 90회)만 종목객체추가나 주문을 내도록 프로그래밍한 후 이 복수개의 전략들을 동시 실행시키면 복수개 전략들 전체로 합산해서 15초당 60회(혹은 90회)를 훨씬 초과하는 종목객체 추가나 주문이 발생하더라도 시간제한 오류가 발생하지 않고 정상 수행되는데, 이렇게 프로그래밍하지 않고 좀 수식을 엉성하게 짜서 한 전략이라도 15초동안 정해진 횟수를 한번이라도 초과하게 되면 횟수초과 하지 않은 다른 전략들까지 수행정지가 된다는 얘기죠.
사용자 함수
답변 1
프로필 이미지

예스스탁 예스스탁 답변

2015-05-27 17:41:30

안녕하세요 예스스탁입니다. 1. 예스스팟은 사용자PC에서 만들어진 가원장의 값을 이용합니다. 가원장은 최초 스팟이 실행되면 원장에서 값을 가져오고 이후에는 수신되는 주문응답, 체결응답으로 갱신이 됩니다. 응답전에는 갱신되지 않습니다. 가원장 항목중 예수금관련 값들은 가원장 자체에서 계산하는 것은 아닙니다. 예스금 항목은 실제 원장이 주문이후 약 5초 이후에 갱신이 됩니다. 마찬가지로 가원장에서 주문응답이 수신되고 5초이후에 원장에서 값을 조회해 와서 갱신해 가게 됩니다. 2. 시간제한 중 시세요청(ReqMarketData)은 각 전략별로 제한됩니다. 그러므로 전략별로 합산하는 것은 아니므로 전략을 나누시면 더 많은 객체 요청이 가능합니다. 시세요청은 지정한 시간(초)가 지나면 제한이 해제 됩니다. 시세요청 제한이 걸려도 다른 이벤트가 멈추거나 하지 않습니다 다만 사용자분이 수식안에서 시간제한이 걸린 이후에 시간제한이 해제된후에 나머지 요청못한 종목을 요청하게 수식으로 작성하셔야 합니다. 시간제한이 걸리면 Main.GetLimitedTime(nKind)함수가 남은 제한시간(초)을 리턴해 줍니다. 남은 초 확인하시고 타이머등으로 해당 시간(초)가 지난이후에 다시 이전에 제한이 걸려서 요청못한 종목부터 다시 요청하게 하셔야 합니다. 주문제한운 걸리시면 주문사고로 판단해서 예스스팟에 걸린 모든 전략이 정지상태가 됩니다. 즐거운 하루되세요 > 김태희 님이 쓴 글입니다. > 제목 : 주문접수나 취소시에 그 내역들이 Account객체에 반영되는 메카니즘을 알고 싶습니다 > 문의1) 증권사 시스템은 사용자가 주문을 낼때 계좌에 예탁금이 충분한지를 체크합니다. 예를들어, 현재 예탁금으로 주문가능한 계약수는 3계약인데, 그 이상을 주문하면 당연히 주문은 실패하겠죠. 이때 주문을 내는데 필요한 금액이 계좌에 예치되어 있는지에대한 판단(즉, 주문가능 여부에 대한 판단)을 사용자PC에서 하는지 증권사 서버에서 하는지 가 궁금해서 제가 다음과 같이 수식을 짜서 테스트 삼아 돌려보았습니다. 실제계좌에 3100만원을 입금시키고 예스스팟에서 자동주문으로 실행하였습니다. 예스트레이더의 통합주문(2101)화면에서 코스피200 선물6월물로 주문가능한 계약수를 확인해보니 3계약까지 가능하더군요. function Main_OnStart() { var i, j, k=0, l, jumunka=250; Main.MessageList("주문시작:"); for (i=0; i<3; i++) { j = Account.OrderBuy(future.code, 1, jumunka, 0); jumunka += 0.05; k = Account.GetTheNumberOfUnfills(); l = Account.GetBalanceETCinfo(29); Main.MessageList(i, j, k, l); } Main.SetTimer(1, 20000); } function Main_OnOrderResponse(OrderResponse) { var x, y; x = Account.GetTheNumberOfUnfills(); y = Account.GetBalanceETCinfo(29); Main.MessageList("OnOrderResponse:", OrderResponse.orderID, OrderResponse.orderNum, OrderResponse.orgOrderNum, OrderResponse.orderPrice, OrderResponse.isNormal, x, y); } function Main_OnTimer(nEventID) { var i, j, k, l, m; Main.KillTimer(1); k = Account.GetTheNumberOfUnfills(); Main.MessageList("주문취소:", k); for (i=0; i<k; i++) { Account.SetUnfillIndex(i); j = Account.OrderCancel(Account.Unfill.orderNum); m = Account.GetTheNumberOfUnfills(); l = Account.GetBalanceETCinfo(29); Main.MessageList("OnTimer:", i, j, m, l); } j = Account.OrderBuy(future.code, 3, 252, 0); m = Account.GetTheNumberOfUnfills(); l = Account.GetBalanceETCinfo(29); Main.MessageList("OnTimer:", 99999, j, m, l); } 실행한 결과는 다음과 같습니다. 주문시작: 0 1 0 31000000 1 2 0 31000000 2 3 0 31000000 OnOrderResponse: 1 437 0 250 ture 1 31000000 OnOrderResponse: 2 438 0 250.05 true 2 31000000 OnOrderResponse: 3 439 0 250.1 true 3 31000000 주문취소: 3 OnTimer: 0 4 3 1071625 OnTimer: 1 5 3 1071625 OnTimer: 2 6 3 1071625 OnTimer: 99999 7 3 1071625 OnOrderResponse: 4 440 437 0 true 2 1071625 OnOrderResponse: 5 441 438 0 true 1 1071625 OnOrderResponse: 6 442 439 0 true 0 1071625 OnOrderResponse: 7 443 0 252 true 1 1071625 근데, 실행결과를 보면 이상한 점들이 있어서 문의드립니다. 신규로 1계약씩 총 3계약을 매수주문을 냄과 동시에 미체결내역 수와 주문가능총액을 MessageList()로 찍어보면 account계좌에 즉각 반영이 안되더군요. OnOrderResponse 이벤트가 발생하고 나서야 그나마 미체결내역 수는 계좌(Account객체)에 반영되는데, 주문가능총액은 여전히 반영이 안된채로 31,000,000원을 그대로 표시해주네요. 주문가능총액도 주문응답을 하나씩 받을때마다 단계적으로 감소해야 될거 같은데 말이죠. 주문가능총액은 타이머로 20초 후에 전체 매수주문에대해 취소주문을 낼 때 쯤에야 1,071,625원이 Account객체에 반영이 된걸 확인할수 있네요 또한 취소주문을 냄과 동시에 미체결 내역수를 찍어봐도 역시 바로 Account객체에 반영이 안되고 3으로 표시됩니다. 취소주문을 1개씩 낼때마다 미체결 내역도 &#8211;1씩 감소해야 정상인데, 그러질 않네요. 근데, 여기서 정말 이상한 점은... 취소주문을 3개를 냈긴 하지만 아직 미체결 내역 수는 3이고, 주문가능 총액은 1,071,625원으로, 주문 취소한 내역이 아직 Account객체에 반영이 안된 상태인데, 3계약 매수주문은 정상적으로 실행이 되더군요. 주문가능총액이 부족하면 3계약 매수주문이 실행이 되선 안될 거 같은데 말이죠. 주문을 내거나 취소시에 미체결 내역 수와 주문가능총액 등이 계좌객체에 바로 반영되는 것도 있고 느리게 반영되는 것도 있고, 이런 식으로 반영되는 시차가 제각각이면...제가 수식으로 주문가능한 계약수를 계산할 때 잘못된 값을 계산할 수도 있을 거 같은데요. 주문가능한 계약수를 계산하려면 주문가능총액 가지고 계산할 수 밖에 없는데, 정확한 반영 여부를 알수가 없다면 문제가 있을 거 같습니다. 그리고, 제가 궁금해 했던...주문을 내는데 필요한 금액이 계좌에 예치되어 있는지에대한 판단, 즉, 주문가능 여부에대한 판단을 사용자PC에서 하는지 증권사 서버에서 하는지에 대해서는 일단 증권사 서버에서 하진 않고 사용자PC에서 하는 거 같군요. 증권사 서버로부터 주문응답(OrderResponse)을 받기도 전에 주문은 즉각적으로 바로 나가는 걸 보면 사용자 PC에서 하는거 같은데, 제 생각이 맞나요? 요약하면, 주문을 내거나 주문취소 등의 행위가 있을 시에 이러한 내역들이 Account객체에 반영되는 메카니즘을 알고 싶습니다. 어떤 방식으로 계좌객체에 반영되는지...전체적인 동작방식이 잘 이해가 안됩니다. 문의2) 이건 다른 문제인데요. 원래 종목객체 추가는 15초당 60회, 주문은 15초당 90회..이렇게 횟수제한이 있는 걸로 알고 있는데, 동시에 여러개의 전략을 실행시키니까 시간제한 오류가 발생하지 않는군요. 예를들어, A전략과 B전략이 둘다 15초당 60번의 종목객체를 추가하도록 수식을 작성한 상태에서 예스스팟에서 2개의 전략을 동시에 실행시키면 A전략과 B전략이 15초당 총 120번의 종목객체를 추가하게 되는데, 실제로 이렇게 실행시켜봤더니 시간제한 오류를 발생시키지 않고 정상적으로 2개 전략이 잘 실행되더군요. 15초당 60회(혹은 90회) 횟수 제한이 예스트레이더의 예스스팟 화면에서 실행되는 전체 전략들을 대상으로 그 횟수가 계산되어 제한이 가해지는게 아니고, 각각의 전략단위로 계산되어 제한이 가해지는 거 같군요. 그러면 동일한 전략을 1개의 전략으로 만들지 않고, 여러개의 전략으로 나누어 만들면 15초당 60회(혹은 90회) 등의 회수제한에 제약됨이 없이 무제한으로 이용할 수 있다는 얘긴데...이렇게 사용해도 되나요? 그러면 증권사에서 시간제한,횟수제한을 둔 의미가 없어지는데....이렇게 전략을 여러개로 나누어 동시에 실행시킬 때 기술적인 혹은 기타 문제점은 없는지 궁금합니다. 그리고, 한가지 더 좀 여쭐게요. 시간제한 오류가 발생하면 전략 수행이 통째로 멈춰버리던데, 제가 20초 후에 타이머를 작성하도록 수식을 짰는데, 그 전에 시간제한 오류가 발생하니까 20초가 지나도 타이머가 작동을 안하네요. 게다가, OnUp dateMarket 이벤트조차도 더 이상 발생을 안합니다. 시간제한 오류가 발생했는데 그와 상관없는 OnUp dateMarket 이벤트가 왜 멈추는지도 잘 이해가 안되고... 원래 시간제한 오류 발생하면 전략 실행이 올스톱 되나요? 이게 시간제한 오류가 발생한 해당 전략만 올스톱되는게 아니라 시간제한이 발생하지 않은 멀쩡하게 잘 실행되던 다른 전략까지 올스톱됩니다. 예스스팟(6131)화면에서 모든 전략들이 빨간색으로 “제한”이란 표시가 뜨면서, 15초가 지나도 그대로 있습니다. 이거 15초가 지나면 제한이 풀려야 되지 않나요? 한 전략에서 시간제한 오류가 발생하더라도 다른 전략에는 영향을 미치면 안될 거 같은데...이거 좀 골치 아프네요. 시간제한 오류가 발생하더라도 15초가 지나면 전략은 다시 정상 수행해야 되지 않나요? 그러니까 내용을 요약하면 이렇습니다. 복수개의 전략들에 대해 원천적으로 각 전략마다 15초동안 60회(혹은 90회)만 종목객체추가나 주문을 내도록 프로그래밍한 후 이 복수개의 전략들을 동시 실행시키면 복수개 전략들 전체로 합산해서 15초당 60회(혹은 90회)를 훨씬 초과하는 종목객체 추가나 주문이 발생하더라도 시간제한 오류가 발생하지 않고 정상 수행되는데, 이렇게 프로그래밍하지 않고 좀 수식을 엉성하게 짜서 한 전략이라도 15초동안 정해진 횟수를 한번이라도 초과하게 되면 횟수초과 하지 않은 다른 전략들까지 수행정지가 된다는 얘기죠.