본문 바로가기
기타

AWS Batch 파이썬 백테스팅 실행 최종 매뉴얼

by 태짱S2 2025. 9. 26.
반응형

 

AWS Batch 파이썬 백테스팅 실행 최종 매뉴얼

이 매뉴얼은 파이썬 백테스팅 코드를 AWS Batch를 통해 클라우드에서 실행하는 모든 과정을 담고 있습니다. 우리가 함께 겪었던 수많은 시행착오와 해결 방법, 그리고 궁금해했던 모든 질문에 대한 답변을 상세하게 정리했습니다.

목차

1단계: PC 환경 설정

1.1. AWS 계정 생성

모든 AWS 서비스 이용의 첫걸음입니다. AWS 프리티어(무료 등급)에 가입합니다.

1.2. AWS CLI 설치

PC의 명령어 창(cmd)에서 AWS를 제어하는 '리모컨'입니다. 공식 홈페이지에서 Windows용 MSI 설치 파일을 받아 설치합니다.

1.3. IAM 사용자 생성 및 CLI 연동 (매우 중요)

AWS 계정의 '마스터 키'인 루트 계정 대신, 안전한 작업을 위해 권한을 부여받은 '직원용 출입증(IAM 사용자)'을 만들어 사용합니다.

  1. AWS 콘솔 > IAM 서비스 > '사용자' > '사용자 생성'
  2. 사용자 이름(예: `batch-admin`) 지정, '다음' 클릭
  3. 권한 설정 > '기존 정책 직접 연결' > `AdministratorAccess` 검색 후 체크, '다음' 클릭
  4. 사용자 생성을 완료하고, 액세스 키 ID비밀 액세스 키를 안전한 곳에 즉시 저장합니다. (비밀 키는 다시 볼 수 없습니다)
  5. PC의 명령 프롬프트(cmd)에서 aws configure 실행 후, 위 키 정보와 리전(ap-northeast-2), 출력 형식(json)을 입력합니다.
Q&A: 루트 계정으로 로그인하면 안 되나요?

A: 안됩니다. 루트 계정은 보안에 매우 취약하며, 우리가 겪었던 것처럼 일부 최신 AWS 콘솔 기능이 비정상적으로 동작할 수 있습니다. 항상 IAM 사용자로 로그인하는 것이 원칙입니다.

1.4. Docker 설치

파이썬 코드를 어디서든 동일하게 실행될 수 있는 '프로그램 설치 파일(이미지)'로 포장해주는 도구입니다. Docker Desktop을 PC에 설치합니다.

2단계: 파이썬 코드 및 Docker 준비

2.1. 프로젝트 폴더 구성

PC에 `aws-backtest`와 같은 폴더를 만들고, 그 안에 아래 3개의 파일을 준비합니다.

1. main.py (백테스팅 코드)

주요 변수들을 외부에서 '파라미터'로 받아오게 수정해야 합니다.

핵심 수정 사항: `argparse` 사용 및 결과물 저장 경로

아래는 코드 상단의 '사용자 설정 구간'을 파라미터로 받도록 수정한 예시입니다. 또한, 모든 결과 파일은 컨테이너 내부의 /outputs 폴더에 저장되도록 경로를 지정해야 합니다.

# ... import 문들 ...
import argparse

# AWS Batch 환경을 위한 출력 경로 설정
BASE_OUTPUT_PATH = "/outputs"
if not os.path.exists(BASE_OUTPUT_PATH):
    os.makedirs(BASE_OUTPUT_PATH)

# 데이터 캐시 폴더 경로 수정
DATA_CACHE_PATH = os.path.join(BASE_OUTPUT_PATH, "data")
# ...

# -------------------------
# 사용자 설정 구간
# -------------------------
parser = argparse.ArgumentParser(description="Walk-Forward Analysis Backtesting with Customizable Parameters.")
parser.add_argument('--symbol', type=str, required=True, help='The symbol to backtest (e.g., "BTC/USDT:USDT")')
parser.add_argument('--test_months', type=int, default=12, help='Test period in months')
parser.add_argument('--slide_months', type=int, default=3, help='Sliding interval in months')
parser.add_argument('--half_life_days', type=int, default=365*16, help='Half-life for time weighting in days')
args = parser.parse_args()
# ... (변수 할당)

2. requirements.txt (필요 라이브러리 목록)

pandas
numpy
optuna
numba
ccxt
scikit-learn
pytz
matplotlib
python-dateutil
openpyxl

3. Dockerfile (실행 환경 설계도)

FROM python:3.9-slim
WORKDIR /app

# 결과물을 저장할 폴더를 미리 생성 (EFS 연결 지점)
RUN mkdir /outputs

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
ENTRYPOINT ["python", "main.py"]

3단계: AWS 인프라 구축 (ECR, IAM, EFS)

3.1. ECR 리포지토리 생성 (Docker 이미지 창고)

  1. AWS 콘솔 > ECR 서비스 > 리전: 서울(ap-northeast-2) 확인
  2. '리포지토리 생성' > 이름: `backtest-repo` 입력 후 생성

3.2. EFS 파일 시스템 생성 (영구 저장소)

중요: 왜 EFS가 필요한가?

Batch 작업은 일회용 컴퓨터에서 실행됩니다. 작업이 끝나면 컴퓨터와 그 안의 파일은 모두 사라집니다. EFS는 모든 작업이 공유하는 '네트워크 외장 하드' 역할을 하여, 결과 파일(엑셀, 이미지 등)을 영구적으로 보존합니다.

  1. AWS 콘솔 > EFS 서비스 > '파일 시스템 생성'
  2. 이름: `my-backtest-storage`
  3. VPC: 기본 VPC 선택 후 생성 (완료까지 몇 분 소요)
  4. 생성된 파일 시스템 클릭 > '액세스 포인트' 탭 > '액세스 포인트 생성'
  5. 이름: `batch-access-point`
  6. POSIX 사용자 섹션: 사용자 ID `0`, 그룹 ID `0` 입력
  7. 루트 디렉터리 생성 권한 섹션: 소유자 사용자 ID `0`, 소유자 그룹 ID `0`, 권한 `777` 입력
  8. 액세스 포인트 생성을 완료합니다.

3.3. IAM 역할 2개 생성 (Batch용 출입증)

  1. `ecsInstanceRole` (컴퓨터용): IAM > 역할 만들기 > EC2 사용 사례 > `AmazonEC2ContainerServiceforEC2Role` 정책 > 이름 `ecsInstanceRole`
  2. `ecsTaskExecutionRole` (작업 실행용): IAM > 역할 만들기 > Elastic Container Service Task 사용 사례 > `AmazonECSTaskExecutionRolePolicy` 정책 > 이름 `ecsTaskExecutionRole`

4단계: Docker 이미지 빌드 및 ECR 업로드

PC의 명령 프롬프트(cmd)에서 2단계에서 만든 프로젝트 폴더로 이동한 뒤, 아래 명령어들을 순서대로 실행합니다.

REM --- 1. ECR 로그인 (123456789012는 본인 AWS 계정 ID로 변경) ---
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com

REM --- 2. 이미지 빌드 ---
docker build -t backtest-repo .

REM --- 3. 이미지 태그 지정 ---
docker tag backtest-repo:latest 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/backtest-repo:latest

REM --- 4. 이미지 푸시(업로드) ---
docker push 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/backtest-repo:latest

5단계: AWS Batch 인프라 설정

AWS Batch 콘솔에서 실제 작업이 실행될 환경을 구성합니다.

5.1. 컴퓨팅 환경 생성

  1. Batch > '환경' > '생성'
  2. 이름: `final-compute-env`
  3. 허용된 인스턴스 유형: `c7i-flex.large` (본인 계정의 프리 티어 가능 유형)
  4. 최대 vCPU: `2` (사용할 인스턴스 사양에 맞춤)
  5. 스팟 인스턴스 사용: 체크 해제 (프리 티어는 온디맨드를 사용)
  6. 네트워크 설정 등 나머지는 모두 기본값으로 두고 생성 후 VALID 상태가 될 때까지 기다립니다.

5.2. 작업 대기열 생성

  1. '작업 대기열' > '생성' > 이름: `final-job-queue`
  2. 컴퓨팅 환경: `final-compute-env` 연결 후 생성, VALID 상태가 될 때까지 대기

5.3. 작업 정의 생성 (CLI 사용)

EFS 연결은 콘솔에서 설정이 까다로우므로, 아래 JSON 파일을 만들고 CLI로 등록하는 것이 가장 확실합니다.

  1. 프로젝트 폴더에 job-definition.json 파일을 만들고 아래 내용을 붙여넣습니다. (fileSystemId, accessPointId는 본인 EFS 정보로 수정)
    {
        "jobDefinitionName": "final-job-definition",
        "type": "container",
        "containerProperties": {
            "image": "123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/backtest-repo:latest",
            "vcpus": 2,
            "memory": 3800,
            "command": [
                "--symbol", "Ref::symbol",
                "--test_months", "Ref::test_months",
                "--slide_months", "Ref::slide_months",
                "--half_life_days", "Ref::half_life_days"
            ],
            "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
            "volumes": [
                {
                    "name": "efs-storage",
                    "efsVolumeConfiguration": {
                        "fileSystemId": "fs-xxxxxxxxxxxx",
                        "transitEncryption": "ENABLED",
                        "authorizationConfig": {
                            "accessPointId": "fsap-xxxxxxxxxxxx"
                        }
                    }
                }
            ],
            "mountPoints": [{"containerPath": "/outputs", "sourceVolume": "efs-storage"}]
        },
        "parameters": {
            "symbol": "BTC/USDT:USDT",
            "test_months": "12",
            "slide_months": "3",
            "half_life_days": "5840"
        },
        "platformCapabilities": ["EC2"]
    }
  2. 명령 프롬프트(cmd)에서 아래 명령어로 등록합니다.
    aws batch register-job-definition --cli-input-json file://job-definition.json --region ap-northeast-2

6단계: 작업 제출 및 모니터링

6.1. 단일 작업 제출 (CLI 사용)

명령 프롬프트(cmd)를 사용하여 파라미터를 전달하며 작업을 제출합니다.

aws batch submit-job --job-name my-test-run --job-queue final-job-queue --job-definition final-job-definition --region ap-northeast-2 --container-overrides "{\"command\":[\"--symbol\", \"BTC/USDT:USDT\", \"--test_months\", \"6\"]}"

6.2. 상태 확인 및 로그 보기

  1. Batch > '작업' 메뉴에서 작업 상태를 확인합니다. (RUNNABLE → `RUNNING` → `SUCCEEDED`)
  2. 작업 이름을 클릭 > '로그 스트림 이름' 링크를 클릭하면 CloudWatch에서 `print` 출력 결과를 실시간으로 볼 수 있습니다.

7단계: 결과 파일 확인 및 다운로드 (EFS)

EFS는 '네트워크 외장 하드'와 같아서, 파일을 보려면 임시 컴퓨터(EC2)에 연결해야 합니다.

  1. 임시 EC2 인스턴스 시작: EC2 콘솔 > '인스턴스 시작' > 이름: `efs-checker`, 유형: `t3.micro`(프리 티어), 키 페어 선택 후 시작
  2. 인스턴스 연결: 생성된 인스턴스 선택 > '연결' > '연결' 버튼 클릭 (웹 터미널 열림)
  3. EFS 연결 (마운트): 웹 터미널에 아래 명령어들을 순서대로 입력합니다. (fs-xxxxxxxxxxxx는 본인 EFS ID)
    sudo yum install -y amazon-efs-utils
    mkdir efs_files
    sudo mount -t efs fs-xxxxxxxxxxxx:/ efs_files
  4. 파일 목록 확인:
    cd efs_files
    ls -R
    이 명령어로 EFS에 저장된 모든 결과 폴더와 파일을 확인할 수 있습니다.
  5. 파일 내용 확인:
    cd WFA_BTC-USDT-USDT.../  (실제 폴더 이름으로 변경)
    cat WFA_Log_...txt
Q&A: 파일을 PC로 다운로드하려면?

A: 대량의 파일을 쉽게 다운로드하려면, EFS의 내용을 S3 버킷으로 복사(AWS DataSync 사용)한 뒤, PC에서 aws s3 sync 명령어를 사용하는 것이 가장 효율적입니다.

8단계: 대규모 자동화 및 확장

단일 작업이 성공했다면, 이제 수많은 조합을 자동으로 실행할 차례입니다.

8.1. 컴퓨팅 환경 확장

더 많은 작업을 동시에 처리하려면 '컴퓨팅 환경'의 '최대 vCPU' 값을 높여줍니다. (예: `64`). 그러면 작업 정의의 vCPU 요구사항에 맞춰 최대 16개(`64/4=16`)의 작업을 동시에 병렬 처리할 수 있게 됩니다.

8.2. 자동 제출 스크립트 (`.bat` 파일)

수많은 CLI 명령어를 손으로 칠 수 없으므로, 자동 실행 스크립트를 만듭니다. 아래 내용을 `run_all_tests.bat` 파일로 저장(인코딩: **ANSI**)하고 더블클릭하여 실행합니다.

@echo off
setlocal enabledelayedexpansion

REM --- 테스트할 변수 목록 ---
set "COINS=BTC/USDT:USDT ETH/USDT:USDT ADA/USDT:USDT"
set "HALF_LIVES_DAYS=365 730"
set "WFA_COMBOS=12_6 6_3"

REM --- 자동 반복 실행 ---
for %%C in (%COINS%) do (
    for %%H in (%HALF_LIVES_DAYS%) do (
        for %%W in (%WFA_COMBOS%) do (
            for /f "tokens=1,2 delims=_" %%A in ("%%W") do (
                set TEST_MONTHS=%%A
                set SLIDE_MONTHS=%%B
                set SYMBOL=%%C
                set JOB_NAME_SYMBOL=!SYMBOL:/=-!
                set JOB_NAME_SYMBOL=!JOB_NAME_SYMBOL::=-!
                
                aws batch submit-job ^
                    --job-name !JOB_NAME_SYMBOL!-t!TEST_MONTHS!-s!SLIDE_MONTHS!-h%%H ^
                    --job-queue final-job-queue ^
                    --job-definition final-job-definition ^
                    --region ap-northeast-2 ^
                    --container-overrides "{\"command\":[\"--symbol\", \"!SYMBOL!\", \"--test_months\", \"!TEST_MONTHS!\", \"--slide_months\", \"!SLIDE_MONTHS!\", \"--half_life_days\", \"%%H\"]}"
            )
        )
    )
)
echo All jobs submitted.
pause
반응형