정확한 주문 금액: Decimal 단위·반올림·실제 잔량
TECH INSIGHT / EXPLAINED
주문과 장부 경계에는 숫자 규약을 명시해야 합니다. 통계 분석에는 이진 float도 유용하지만 정확한 소수 금액이나 단위 정수는 거래소 주문 단위와 회계 규칙을 적용하기 쉽게 만듭니다.
표현과 화면 표시의 차이
Python float는 보통 binary64를 쓰며 0.1을 정확하게 표현하지 못합니다. 포맷으로 잔여 자릿수를 숨겨도 앞선 비교·반올림 판단까지 모두 수정되지는 않습니다. 실제 오차는 크기와 연산에 따라 달라지며 하루 고정 금액만큼 벌어진다고 할 근거는 없습니다. float로 만든 Decimal은 그 근삿값을 보존하므로 경계에서 원래 소수 문자열이나 단위 정수를 읽습니다.
step은 소수 자릿수와 다르다
Decimal.quantize는 지수를 맞추며 임의의 값을 0.05·0.25·5의 배수로 맞춰 주지 않습니다. 아래 예제는 정확한 유리수 몫으로 온전한 step 개수를 구한 뒤 충분한 Decimal 정밀도로 곱합니다. 음수가 아닌 수량과 범위를 제한한 소수 입력을 지원하며 모든 숫자 표현을 처리하는 함수는 아닙니다.
from decimal import Decimal, localcontext
from fractions import Fraction
def floor_step(value_text, step_text):
if not isinstance(value_text,str) or not isinstance(step_text,str):
raise ValueError("decimal strings required")
v, step = Decimal(value_text), Decimal(step_text)
if not v.is_finite() or not step.is_finite() or v < 0 or step <= 0:
raise ValueError("finite nonnegative value and positive step required")
# Bound untrusted input complexity for this teaching example.
for x in (v,step):
if len(x.as_tuple().digits)>40 or abs(x.as_tuple().exponent)>40:
raise ValueError("outside supported precision range")
ratio = Fraction(v)/Fraction(step) # exact integer quotient
ticks = ratio.numerator//ratio.denominator
with localcontext() as ctx:
ctx.prec = max(28,len(str(ticks))+len(step.as_tuple().digits)+2)
return Decimal(ticks)*step
assert Decimal("0.1")+Decimal("0.2") == Decimal("0.3")
assert Decimal("1.23").quantize(Decimal("0.05")) == Decimal("1.23")
assert floor_step("1.23","0.05") == Decimal("1.20")
assert floor_step("0.30000000000000004","0.001") == Decimal("0.300")
print(format(floor_step("1.23","0.05"),"f")) # 1.20반올림 방향은 주문 제약의 표현
매수 지정가 내림은 최대 허용 가격을, 매도 지정가 올림은 최소 허용 가격을 보존합니다. 둘 다 체결 가능성을 낮출 수 있습니다. 반대 호가 쪽으로 지정가를 옮기면 시장성이 높아질 수 있지만 경제적 제약도 바뀝니다. 안전을 위해 무조건 자신에게 불리하게 반올림한다는 보편 규칙은 없습니다.
수량 내림은 원래 수량 초과를 피할 뿐 수수료 여유·가용 잔고·최소/최대 수량·주문 금액 검사를 대체하지 않습니다. 반올림 전에 가격을 int로 만들면 이미 소수부를 잃습니다. 가격 구간마다 호가 단위가 바뀌면 최종 가격이 속한 구간에서도 유효한지 검사하세요.
거래소 규칙도 버전 있는 자료로
Binance Spot에서는 가격·수량 필터와 해당 주문 금액·시장가 규칙을 구분합니다. 실제 filter type과 문서 필드를 읽고 다른 API의 비슷한 필드 이름을 임의로 같은 뜻으로 취급하지 않습니다. 조회 시각과 함께 캐시하고 거절 시 규칙을 재검증하세요. 주문 크기를 몰래 키워 재시도하지 않습니다.
온체인 기본 단위에는 정수를 쓸 수 있지만 토큰별 배율이 다르고 오버플로·나눗셈 반올림 규칙도 필요합니다. Go의 big.Float는 여전히 이진이며 big.Rat는 유리수를 표현합니다. 타입을 골랐다고 변환마다 반올림을 명시할 필요가 사라지지는 않습니다.
임의의 epsilon으로 실제 잔량을 지우지 않기
정확한 정수나 Decimal 장부 수량에는 0과의 정확한 비교가 유효합니다. 분석용 근사 float에는 규모에 맞는 허용 오차를 쓸 수 있지만 최소 주문 수량보다 작다는 업무 상태가 소유량 0을 뜻하지는 않습니다. 잔여 잔고를 명시적으로 대조하세요. 검증된 금액은 해당 엔드포인트가 받는 형식으로 직렬화합니다. 자릿수·주문 단위·총금액은 별도 조건입니다.
공식 자료와 함께 읽기
Python floating point · Python Decimal · Exact rational values · Binance Spot filter specification
내용·예제 검토: 2026-09-29
댓글
댓글 쓰기