L-ATS 3.0 시스템은 크게 아래 두 가지 프로그램으로 구성된다.

Windows Application
OS : Windows 11
개발 환경 : 개인 데스크탑, MS Visual Studio 2019, 이베스트 투자증권 XingAPI
개발 언어 : C#, Winform
운영 환경 : AWS Cloud
LINUX Server Program
OS : CentOS 8.x
개발 환경 : Raspberry Pi, Vim Editor, MariaDB
개발 언어 : python3
운영 환경 : AWS Cloud

 

시스템의 큰 구성은 기존 L-ATS 2.0의 구조를 승계했다.

Windows Application은 매수할 종목의 자동 인식실제 매매 업무를 담당하고 LINUX Server Program은 매수를 위한 종목 정보관리 업무를 담당한다.

 

L-ATS 3.0의 큰 흐름을 도식화 하면 다음과 같다.


L-ATS 3.0.exe
Windows Application
  • 화면 캡처 처리
    • Visual Studio를 통해 C# 프로그래밍으로 화면을 캡쳐하는 방식을 구현하기는 쉽지 않았다.
    • 관련된 예시나 소스는 많지만 원하는 크기, 원하는 위치의 화면을 캡쳐하는 방식의 화면 캡쳐 구현은 존재하지 않았다.
    • 그래서 유용한 정보들을 수집해서 몇가지의 예시 기능을 결합해서 구현했다.
  • 캡쳐된 문자 이미지의 OCR 처리
    • 캡쳐된 화면을 바로 OCR 요청해서 Text로 변환하는 기능을 한다.
    • Apple이나 Google, NAVER에서 제공하는 OCR은 한국어 인식능력이 뛰어나지만 비용적인 측면의 문제가 있었다.
    • 때문에 무료로 사용 가능한 Tessaract OCR을 사용했다. (인식률이 많이 좋아지긴 했지만...부족하다...)
Tessaract OCR의 정확도가 낮지만 그래도 효용성이 있다고 판단한 이유는 하루에 많은 뉴스 종목들 중에 정확히 인식되는 몇몇개 종목에 대해 데이터 분석을 통해 높은 확률로 수익을 낼수 있는 조건을 만든다면 사용해도 무방하다고 생각했다.
  • 이베스트 투자증권 API를 사용한 Trading 처리
    • OCR 결과 Text에서 패턴 분석을 통해 종목명을 추출한다.
패턴 분석을 위해서는 해당 뉴스방에서 어떤 형태의 문자열로 뉴스를 알려주는지 공통점을 찾아내야 한다. 동일한 방법으로 많은 수의 뉴스 분석이 가능하고 종목추출이 가능한 패턴을 분석한다.
    • 추출된 종목명은 LINUX Server Program으로 전송하여 Database에 저장된 종목의 Code 정보를 가져온다.
    • Code 정보를 확보하면 증권사 API를 사용하여 매수 요청한다.
    • 매매 결과 정보를 LINUX Server Program으로 전송하여 파일에 기록할 수 있게 한다.
L-ATS-3.0-Server.py
LINUX Python Program
  • OCR 결과에서 추출한 종목명을 수신한다.
  • 수신한 종목명으로 Database를 조회하여 종목의 존재 여부를 확인하고 존재할 경우 종목 코드를 Windows Application으로 전달한다.
  • 수신한 매매 결과 정보를 모니터링 가능하도록 로그로 기록한다.
stocks_collector.py
LINUX Python Program
  • KRX의 국내 주식 정보를 스크래핑 해온다. (pykrx 모듈 사용)
  • KOSPI, KOSDAQ 주식 정보를 Database에 저장한다.
  • crontab에 등록하여 정해진 시간에 정기적으로 수행하도록 한다.
L-ATS Monitoring (v3.5 구현 예정)
LINUX Python Program | Mobile APP
  • 일일 매매 결과를 요청하고 수신하여 표시한다.
  • 실시간 시스템 처리 로그를 표시한다.

대략적인 시스템 구조와 구현해야 할 기능, 그리고 어떤 모듈들을 사용할지 선정을 완료했다.

현재 Windows 화면 캡쳐와 OCR 처리 테스트 프로그램을 만들고 있는데 테스트가 완료되면 바로 서비스 구축에 들어갈 예정이다. 테스트 프로그램 완성에 따라 하반기에는 전체 솔루션 검증을 진행할 예정이다.

 

Posted by [ 브랜든 ]
,

[Python] Check Validation

Python 2020. 5. 27. 23:23

변수에 대한 유효성 검증은 어떤 개발 언어에서든 동일한 방식으로 구현된다.

 

나의 경우 Library 형태의 함수화하는 걸 즐기는 편이라 여러가지 형태의 변수값 유효성 체크 함수들을

하나의 파일에 모아두고 import하여 사용한다. 

 

 

1. 일반 문자열

  • 조건 : Length

  모든 값들을 Database에 저장한다면 해당 값에 대한 MAX 값이 존재할 것이다. 

  입력한 문자열의 길이가 Database에 할당된 저장 공간보다 크다면 INSERT 작업이 실패날 것이다.

def check_String_Length(min, max, value):
    if len(value) > max or llen(value) < min :
    	return False
    else:
    	return True

2. 숫자 문자열

  • 조건 : Is Decimal?, Range

  숫자로 된 문자열이니 숫자만 입력가능하여야 하며, 숫자이므로 입력 범위가 필요하다.

  예를들면, PORT 번호 같은 경우이다. PORT는 WELL-KNOWN PORT를 제외하고 1024~65535까지 사용가능 하다.

def check_Decimal_And_Range(min, max, value):
    if value.isdecimal() == False:
        return False
     
    if int(value) > max or int(value) < min :
        return False
    else:
        return True

 3. 나열값 (ENUM)

  • 조건 : Length, Range

  ENUM값은 GUI에서는 Select 박스로 구현하면 참 간단하고 쉽다.

  CUI에서는 ENUM List를 별도로(환경설정파일) 관리하여 사용하면 추가/삭제도 편리하다.

enum_list = ['ORACLE', 'MYSQL', 'MSSQL', 'MARIADB', 'DB2']

def check_Enum(enum_list, value):
    if value not in enum_list:
        return False
    else:
        return True

 4. IP Address

 

  입력된 값이 IP 주소 형태인지 확인하는 가장 간단한 법은 Python에서 제공하는 ipaddress 모듈을 사용하는 것이다.

  복잡하게 정규식을 사용하지 않아도 IPv4/IPv6 모두 간단히 확인 가능하다.

import ipaddress

def check_Ip_Address(value, log):
    try:
        ip = ipaddress.ip_address(value) # just ask!!
        log.debug("[{}] is IP{} Address.".format(ip, ip.version))
        return True
    except ValueError:
        return False

5. E-mail Address

 

  SI 사업을 진행하다보니 사용자 정보를 관리해야하는 경우가 발생하여 E-MAIL 주소를 입력받는 경우가 있었다.

  E-MAIL 주소형태는 간단한 정규식으로 가능하다. (구글링하면 많이 나온다..)

import re

def check_Email_Address(value):
    email = re.compile(r'''(
                    ([a-zA-Z0-9._%+-]+)                  # 이메일의 @ 앞부분
                    @
                    ([a-zA-Z0-9.-]+)                     # 이메일의 @ 뒷부분
                    (\.[a-zA-Z]{2,4}))'''. re.VERBOSE)   
    result = email.match(value)
    if result is None:
        return False
    else:
        return True

 

또 뭐가 있을까...

필요할 때마다 만들어서 계속 추가해야겠다.

Posted by [ 브랜든 ]
,

Input Value. 즉, 프로그램 사용자의 입력은 정말 무궁무진하다.

 

이 사용자의 입력에 관해서는 CUI와 GUI는 확연히 큰 차이를 보인다.

 

GUI의 경우, 예를 들면 C# WinForm, HTML/CSS와 같은...

사용자의 입력 Value를 입력 받음과 동시에 제어할 수가 있다.

 

문자열일 경우 Text Box에 길이 제한을 두어 Max 길이 이상 입력이 되지 않게 한다든지...

ENUM의 값을 갖는 경우 Select Box를 만들어 한정된 값 내에서 사용자가 선택하게 한다든지...


이전 회사에서 쓰던 GUI 화면 예시

  •   PFX는 숫자만 입력이 될 것이며 최소 3자리, 최대 15자리까지만 입력이 가능하다.
  •   IDTYPE은 Select Box로 되어 사용자가 정의된 값들만 입력할 수 있다.
  •   DESC는 어떠한 문자도 입력이 가능하고 최대 20자까지만 입력할 수 있다.

하지만 CUI는 사용자가 입력하는 대로 무궁무진하게 입력 받는다.

CUI환경에서는 Input Data Validation(검증) 작업이 무엇보다 중요하며, 시스템 장애를 막을 수 있는 가장 첫번째 관문이다.


 

그럼 System의 어떤 모듈에서 이 작업을 해야 가장 효율적일까?

 

GUI의 경우를 보면 알수 있듯이...당연히 최초 입력값이 생성되는 시점이다.

이전 회사에서는 아래와 같이 하나의 시스템이 대부분 동일한 구조를 갖고 있었다.

 

TCP/IP를 통해 들어오는 특정 Protocol 형식의 패킷이 Application까지 전달되는 과정의 계층 구조

Input Data Validation 작업은 어디서 해야할까?

당연히 Stack 모듈에서 해야하는, 아니 Stack 모듈에서 구현되어야 하는 기본 기능중의 하나이다.. 

그래야 그 위에서 동작하는 모든 Application들이 사용하는 Value들에 대해 의심하지 않고 

사용할 수 있기 때문이다. 

 

Stack 모듈에서 걸러주지 않는다면....?

각각의 Application들이 실제 사용하는 값들만 직접 검증하면....?

만약 100개의 입력값이 있다고 가정해 보자. 하지만 각각의 Application들은 100개 중 일부(약 10개? 15개?)의 

서로 다른 값을 사용한다고 했을 때, 후자가 훨씬 적합해 보이지 않을까? 필요한 것들만 골라서 쓰면 전체적인 작업도 훨씬 줄어 들고.

 

약 20개의 Application이 Stack 위에서 동작한다고 했을 때, 물론 서로 다른 입력값들을 사용할 수 있지만, 일부 필수 값들(Mandatory)은 중복되서 사용할 수 있다. 마치 동일한 상위 클래스를 상속받은 클래스들 처럼....

그렇게 될 경우, Stack 모듈에서 1번만 검증하면 되는 작업을 20개의 Application이 똑같은 값을 다~ 검증하고 있는 셈이 된다. (5개라고 가정한다면...시스템 입장에서는 100개의 입력 값을 검증하는 셈이지 않을까? 다 같은 값인데...). 아무리 봐도 비효율적이다.

 

10년간의 경험적 측면에서의 핵심은 '실수를 최소화 할 수 있는 방향'을 선택하는 것이다.

실수가 없을것 같지...?만! 어디에도 있더라...그리고 언젠가는 장애가 나더라...사람이 만드는 것이니...

더 큰 문제는 그 수많은 값들 중에 어떤 값인지 정확히 알수가 없었다는 것....

(시스템 마다 다르겠지만 1초에 수십만의 패킷이 유입되는 시스템이라면 유입되는 모든 패킷의 Parameter들을 실시간으로 전부 Logging할 수 없으니...H/W 용량도 용량이지만...File Writing 작업이....)

 

이 정도면 Input Data Validation이 귀찮고 하찮은것 같지만 무엇보다 중요하다는 것을 알수 있을 것이다. 

 

그럼 Python으로 Data 검증 함수들을 하나씩 만들어 보자. 

막상 보면 엄청 심플하고 필요 없을 것만 같은 작업이다. 실제로도 간단하고.... 하지만 실전에서는 필수 작업이다.

 

2020/05/27 - [Python] - [Python] Check Validation

'Developer' 카테고리의 다른 글

[Developer] 전역변수  (0) 2020.05.28
[Developer] 개발할 때가 좋았는데.....  (0) 2020.05.25
Posted by [ 브랜든 ]
,