GithubHelp home page GithubHelp logo

ascend_work's Introduction

local에서 프로그램 수행 방법

# checkout Master branch
git checkout master

# nest 모듈 설치
yarn add @nestjs/cli

# node-moudle 모듈 설치
yarn 

# 1번 container 수행
nest start data-app

# 2번 container 수행
nest start trade-app

    

목 차
  1. 과제 설명
  2. 기술 스택
  3. 시스템 구조
  4. 프로그램 구조
  5. CI/CD 구성
  6. 데이터 수집
  7. 전략
  8. 모니터링
  9. 이슈
    

과제 설명

  • 전략
    • MA(10), MA(20)부터 파라미터 값을 1씩 증가시킨 MA(110), MA(120)까지의 101개의 간단한 전략 사용
     전략1: MA(10)과 MA(20) BTC/USDT
     전략2: MA(11)과 MA(21) BTC/USDT
     … 
     전략101: MA(110)과 MA(120) BTC/USDT
    
    • golden cross 시 매수, dead cross 시 매도 전략 사용
    • golden cross: 단기 MA가 장기 MA를 돌파하고 올라 갈 때
    • dead cross: 단기 MA가 장기 MA를 뚫고 내려갈 때
  • 데이터 수집
    • 기준 가격 캔들은 1m 사용
    • BTC close price 사용
    • Binance websocket 이용하여 데이터 가져오기
  • CI/CD 구성
    • github action, jenkins, circle CI등 자유롭게 사용
  • 인프라
    • 클라우드 혹은 로컬에 Docker로 배포
  • 모니터링
    • Dash및 그라파나 등 자유롭게 사용
    • 각 전략 별 수익률 및 balance 현황

(back to top)

기술 스택

  • 인프라 : AWS ECS/ECR, ALB,
  • CI/CD : Github actions
  • WAS : nodejs(framework: nestjs)
  • DB : mongoDB Atlas
  • Monitoring : Grafana Sass

(back to top)

시스템 구조

  • Container Cluster로 AWS ECS를 사용했으며 총 1개의 Cluster를 사용
  • 2개의 Container가 배포되며 각각 아래와 같은 목적을 가지고 있음
    • Data Container(가칭) : 바이낸스와 같은 곳에서 Data를 수집 / 전략 수행 / 체결 명령 전달
    • Trade Container(가칭) : Data Container로 부터 체결 명령을 전달받아 실제적으로 체결을 수행

(back to top)

프로그램 구조

  • 2개의 Container가 존재. 그리고 2개의 Container는 많은 부분을 공유. 이에, monorepo 방식으로 설계
  • libs에는 공통으로 사용되는 모듈, 데이터 타입, 그리고 ORM이 존재하며  
    apps 폴더에는 2개의 Container들에 대한 독립적인 로직들이 각각 존재

(back to top)

CI/CD 구성

  • Container마다 필요한 파일들(taskdefinition, workflow)이 존재하며 dockerfile은 공유
  • 아래와 같이 각 Container에 대한 배포 브랜치가 존재
    • Data Container(가칭) : deploy/data
    • Trade Container(가칭) : deploy/trade
  • 각 배포 브랜치에 Merge 시, 배포되도록 git actions 구성

(back to top)

데이터 수집

  • 문제를 정확히 파악하고 진행해야하는데 그렇지 못해 요구하신 사항과 맞지 않는 부분이 있습니다. 양해 부탁 드립니다.
  • websocket으로 특정 페어 BTCUSDT에 대한 구독. Callback 함수에서 데이터 추출 후, 변수에 대입
private async _onMessage(data) {
    const { b, B, a, A } = JSON.parse(data); //데이터 추출
    this.tickData = { bidPrice: b, bidQty: B, askPrice: a, askQty: A };
  }
  • 1분마다 주기적으로 호출하는 함수에서 해당 변수를 queue 등록
    • 최대 120개의 데이터만 저장되며 이때 전략에 대한 판단 후, 트레이트 API 호출
private async checkTrading() {
    const checkFun = async () => {
      if (this.tickData) {
        this.bidAskInfo.push(this.tickData);
        if (this.bidAskInfo.length == this.tickDatanums) {
          this.bidAskInfo.shift();
          this.calStrategy(this.tickData.ask, this.tickData.bid); //#ask: Ask Price, bid : Bid Price
          await this.callTradeAPI();
        }
      }
      // console.log(`elapsed time : ${new Date().getTime() - start}`);
    };

    setInterval(checkFun, 60000); // 1분
  }

(back to top)

전략

  • 101개의 전략에 대해 체결 여부를 판별하며 Map으로 결과를 저장. 이 결과를 참조로 tradeAPI를 호출
  • tradedata 시, 데이터를 보면 상수 값(1)으로 고정. 이에 대한 고민 필요. 우선은 무조건 체결된다는 가정을 전제로 구현
private calStrategy(askPrice: string, bidPrice: string) {
    ...
    ...
    // golden cross : 단기 MA가 장기 MA를 돌파하고 올라갈 때. 그럼 그전은 단기 MA < 장기 MA
    // dead cross :단기 MA가 장기 MA를 뚫고 내려갈 때, 그럼 그전은 단기 MA > 장기 MA
    for (let i = 0; i < this.numStrategies; i++) {
      const key = `Strategy-(${i + 10})`;
      const [shortMA, longMA] = [
        this.getMVfilter(i + 10),
        this.getMVfilter(i + 20),
      ];
      let result = this.resultChkStr.get(key);
      if (result.state === null) {
        //// 변동성 체크 전, state 저장
        result.state =
          shortMA > longMA
            ? State.BIG_SHORT_MA_THAN_LONG_MA
            : State.BIG_LONG_MA_THAN_SHORT_MA;
        this.resultChkStr.set(key, result);
        break;
      } else {
        // Check Golden Cross or Dead Cross
        switch (result.state) {
          case State.BIG_SHORT_MA_THAN_LONG_MA: {
            if (shortMA < longMA) {
              result.execution = true;
              result.state = State.BIG_LONG_MA_THAN_SHORT_MA;
              result.tradeData = {
                price: bidPrice,
                qty: '1',
                side: Side.SELL,
              };
            }
            this.resultChkStr.set(key, result);
            break;
          }
          case State.BIG_LONG_MA_THAN_SHORT_MA: {
            if (shortMA > longMA) {
              result.execution = true;
              result.state = State.BIG_SHORT_MA_THAN_LONG_MA;
              result.tradeData = {
                price: askPrice,
                qty: '1',
                side: Side.BUY,
              };
            }
            this.resultChkStr.set(key, result);
            break;
          }
          default: {
            break;
          }
        }
      }
    }
  }
  • trade 시, quote(socket callback에서 얻은 price/qty)에서 slippage가 발생하지 않는다는 조건으로 구현. (paper account로 spot trading이 잘 되지 않아서요. 간단한 방법으로 상기와 같이 가정하고 구현) 아래 소스를 보시면 되게 간단하죠.^^;;
      @Post('/trade')
    async postTrade(@Body() tradeInfo: TradeData & { tradeId: string }): Promise<{
      status: string;
    }> {
      await this.tradeModel.create({
        tradeId: tradeInfo.tradeId,
        price: tradeInfo.price,
        qty: tradeInfo.qty,
        side: tradeInfo.side == Side.BUY ? 'BUY' : 'SELL',
      });
    
      return {
        status: 'ok',
      };
    }
  • 마지막으로 DB에는 아래와 같이 데이터가 삽입됨  
    image

(back to top)

모니터링

  • 이 부분은 작업을 수행하지 못했습니다.

(back to top)

이슈

  • Container의 통신은 처음 gRPC를 사용했지만, 인프라 배포 시 GRPC 통신 설정에 애로 사항이 있어  
    restAPI 전환
  • Container 간 restAPI 통신 시, Cluster 내에서 통신하는 방법 적용 필요. 현재는 외부로 나갔다가 들어옴
  • trading 시, 체결 수(qty)에 대한 별도 처리 필요
  • binance의 socket session ttl이 24h임. 이에 대한 갱신 로직 추가 필요

(back to top)

ascend_work's People

Contributors

kanghyungmin avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.