cpgo

package module
v0.0.0-...-1d9d431 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 14, 2017 License: MIT Imports: 8 Imported by: 0

README

cpgo

=====

cybosplus(증권API) + golang 을 이용하여 투자 분석 및 시스템트레이딩을 할수 있도록 만든 간단한 Wrapper 라이브러리 입니다.

필요한것들

설치

go get github.com/ippoeyeslhw/cpgo

설명

cpgo 는 사이보스플러스를 go언어에서 사용할수 있도록 Wrapping 한 것입니다. go-ole패키지를 기반으로 작성되었습니다.

Import

go-ole패키지를 기반으로 작성되었으므로 많은 부분을 의존합니다. 반드시 임포트하여야합니다.

import (
	ole "github.com/go-ole/go-ole"
	"github.com/ippoeyeslhw/cpgo"
)
프로그램 시작

반드시 cointialize, uncoinitialize 호출 해야합니다.

	ole.CoInitialize(0)
	defer ole.CoUninitialize()
객체생성

도움말을 열어봤을때 좌측에 보이는 주요 네가지 라이브러리인

  • CpDib : 혹은 DSCBO1
  • CpSysDib
  • CpTrade
  • CpUtil

각각에 속하는 coclass들을 "."으로 연결하여 객체를 생성할수 있습니다. Create 메서드로 COM객체 생성을 Release 메서드로 헤제를 할수 있습니다.

	stkmst := &cpgo.CpClass{}
	stkmst.Create("CpDib.StockMst")
	defer stkmst.Release()
주요 인터페이스

기본적인 동작을 위해 구현된 주요 인터페이스 메서드들입니다.

  • SetInputValue : 입력데이터 세팅
  • Request : Non-blocking 요청
  • BlockRequest : Blocking 요청
  • Subscribe : 실시간 수신 요청
  • SubscribeLastest : 실시간 수신 (스냅샷성 데이터) 요청
  • Unsubscribe : 실시간 수신 해지
  • GetHeaderValue : 수신 헤더데이터
  • GetDataValue : 수신 데이터
	stkmst.SetInputValue(0, "A000270")
	stkmst.BlockRequest()
	fmt.Println(stkmst.GetHeaderValue(1).Value())
Property

Property값을 가져오려면 getter를 사용하여야 합니다. 도움말의 Property명에 앞에 Get을 붙인 메서드명을 사용합니다.

	tmp := &CpClass{}
	tmp.Create("CpUtil.CpCybos")
	defer tmp.Release()
	fmt.Println(tmp)

	fmt.Println("isconnect: ", tmp.GetIsConnect().Value())
	fmt.Println("servertype: ", tmp.GetServerType().Value())
	fmt.Println("remain time: ", tmp.GetLimitRequestRemainTime().Value())
이벤트처리

Received 이벤트는 Receiver 인터페이스를 구현하면 됩니다.

type Receiver interface {
	Received(*CpClass)
}

이를 BindEvent 메서드를 사용하여 이벤트를 지정할수 있습니다. 이벤트를 해지하려면 UnbindEvent 메서드를 사용합니다.

type RqTestStruct struct {
}

func (t *RqTestStruct) Received(c *CpClass) {
	fmt.Println(c.GetHeaderValue(1).Value())
	c.UnbindEvent() // 이벤트 바로 헤제
}
//... 생략

	evnt := &RqTestStruct{}
	cpobj.BindEvent(evnt)

PeekMessage 를 기반으로 동작하는 PumpWaitingMessages 함수를 제공합니다. 이를 사용하여 Received이벤트를 수신할때까지 대기할수 있습니다.

for  {
	PumpWaitingMessages()
	time.Sleep(1)
}

예제

통신방식을 기준으로 작성한 몇가지 예제입니다.

BlockRequest사용
package main

import (
	"fmt"

	ole "github.com/go-ole/go-ole"
	"github.com/ippoeyeslhw/cpgo"
)

func main() {
	ole.CoInitialize(0)
	defer ole.CoUninitialize()

	stkmst := &cpgo.CpClass{}
	stkmst.Create("CpDib.StockMst")
	defer stkmst.Release()

	stkmst.SetInputValue(0, "A000270")
	stkmst.BlockRequest()
	fmt.Println(stkmst.GetHeaderValue(1).Value())
}
// 결과:
// 기아차
Request사용
package main

import (
	"fmt"
	"time"

	ole "github.com/go-ole/go-ole"
	"github.com/ippoeyeslhw/cpgo"
)

type ContEvnt struct {
	isDone bool
}

func (s *ContEvnt) Received(c *cpgo.CpClass) {
	count := c.GetHeaderValue(2).Value().(int16) // 수신개수
	fmt.Println("response count: ", count)
	for i := 0; i < int(count); i++ {
		fmt.Println(
			c.GetDataValue(1, i).Value(), // 종목코드
			c.GetDataValue(4, i).Value()) // 내용
	}
	if c.GetContinue().Value() == int32(1) { // 연속데이터 있음
		fmt.Println("next request")
		c.Request() // 재요청
	} else {
		s.isDone = true
	}
}

func main() {
	ole.CoInitialize(0)
	defer ole.CoUninitialize()

	cpmw := &cpgo.CpClass{}
	cpmw.Create("CpSysDib.CpMarketWatch")
	defer cpmw.Release()

	evnt := &ContEvnt{false}
	cpmw.BindEvent(evnt)

	// 연속조회  request 갯수제한 유의
	cpmw.SetInputValue(0, "*") // 전종목
	cpmw.SetInputValue(1, "2") // 공시정보
	cpmw.Request()

	for evnt.isDone == false {
		cpgo.PumpWaitingMessages()
		time.Sleep(1)
	}
	cpmw.UnbindEvent()
}

// 결과:
//response count:  20
//A151910 나노스(주) 주권매매거래정지기간변경(개선기간 부여)
//A043290 케이맥(주) 단일판매ㆍ공급계약체결
//A151910 나노스(주) 기타시장안내(기업심사위원회 심의결과 및 개선기간 부여 안내)
//A900050 중국원양자원유한공사 기타 경영사항(자율공시)(자회사의 주요경영사항)
//A043710 (주)서울리거 기타시장안내(상장적격성 실질심사사유 추가 관련 )
//A065420 (주)에스아이리소스 주권매매거래정지(불성실공시법인 지정)
//A065420 (주)에스아이리소스 불성실공시법인지정(공시불이행)
//A011200 현대상선(주) 전환가액ㆍ신주인수권행사가액ㆍ교환가액의 조정(안내공시)
//A011200 현대상선(주) 전환가액ㆍ신주인수권행사가액ㆍ교환가액의 조정(안내공시)
// ...
// ...
Subscribe 예제
package main

import (
	"fmt"
	"time"

	ole "github.com/go-ole/go-ole"
	"github.com/ippoeyeslhw/cpgo"
)

type SubTestStruct struct {
	cont bool
	cnt  int
}

func (s *SubTestStruct) Received(c *cpgo.CpClass) {

	fmt.Printf("(%f)%d , (%f)%d\n",
		c.GetHeaderValue(14).Value(), // 1차 매수호가
		c.GetHeaderValue(15).Value(), // 1차 매수잔량
		c.GetHeaderValue(25).Value(), // 1차 매도호가
		c.GetHeaderValue(26).Value()) // 1차 매도잔량

	if s.cnt > 100 {
		// 100건이 넘을시 중단
		s.cont = false
	}
	s.cnt++
}

func main() {
	ole.CoInitialize(0)
	defer ole.CoUninitialize()

	tmp := &cpgo.CpClass{}
	tmp.Create("CpSysDib.CmeCurr")
	defer tmp.Release()
	fmt.Println(tmp)

	evnt := &SubTestStruct{true, 0}
	tmp.BindEvent(evnt)
	fmt.Println(tmp)

	// 야간 CME 선물시장 밤에 테스트할것
	tmp.SetInputValue(0, "101L9")
	tmp.Subscribe()

	fmt.Println("sub/pub start")

	for evnt.cont == true {
		cpgo.PumpWaitingMessages()
		time.Sleep(1)
	}
	tmp.Unsubscribe()
	tmp.UnbindEvent()
}

// 결과:
//sub/pub start
//(251.449997)30 , (251.500000)2
//(251.449997)35 , (251.500000)2
//(251.449997)35 , (251.550003)34
//(251.449997)35 , (251.550003)34
//(251.449997)35 , (251.550003)34
//(251.449997)35 , (251.500000)1
// ...
// ...


이벤트수신문제

Subscribe 통신방식으로 이벤트 수신을 지속적으로 받다보면 이벤트 수신이 중간에 끊어졌다가 다시 연결되었다가 하는 현상이 발견됩니다. COM 객체는 이벤트 싱크를 맺은 윈도우 스레드에만 메세지를 전달합니다. Go언어의 스케줄러는 다수의 OS Thread 와 다수의 Goroutine 을 가지고 스케줄링 하여 윈도우 스레드가 중간에 바뀌어 끊어지는 것입니다. 이를 방지하기 위해 윈도우 스레드 함수 Wrapper를 사용할수 있습니다.

type Background func(uintptr) uintptr

uintptr 을 인자로 받고 uintptr을 리턴하는 함수를 선언합니다.

func CreateThread(fnc Background, arg1 uintptr) (ret int32, err error)

함수와 인자로 넘겨줄 값을 넘겨주어 스레드를 생성합니다.

type CmeCurEvnt struct {
}

func (ce *CmeCurEvnt) Received(c *cpgo.CpClass) {
	fmt.Printf("[%v] (%f)%d , (%f)%d\n",
		time.Now(),
		c.GetHeaderValue(14).Value(), // 1차 매수호가
		c.GetHeaderValue(15).Value(), // 1차 매수잔량
		c.GetHeaderValue(25).Value(), // 1차 매도호가
		c.GetHeaderValue(26).Value()) // 1차 매도잔량
}

func loop(p uintptr) uintptr {
	// 윈도우 스레드에서 돌아갈 코드
	ole.CoInitialize(0)
	defer ole.CoUninitialize()

	// create cp class
	tmp := &cpgo.CpClass{}
	tmp.Create("CpSysDib.CmeCurr")
	defer tmp.Release()

	// event binding
	evnt := &CmeCurEvnt{}
	tmp.BindEvent(evnt)
	defer tmp.UnbindEvent()

	// set input values
	tmp.SetInputValue(0, "101M3")
	tmp.Subscribe()
	defer tmp.Unsubscribe()

	for {
		cpgo.PumpWaitingMessages()
		time.Sleep(1)
	}

	return 0
}

func main() {

	// 스레드 생성
	cpgo.CreateThread(loop, 0)

	// 메인스레드 Waiting
	for { 
		time.Sleep(time.Millisecond * 10)
	}
}

Documentation

Overview

cpgo는 go언어에서 사이보스플러스를 연동하기 위한 Wrapper 라이브러리입니다. 이 라이브러리는 go-ole 패키지에 상당히 의존하고 있으므로 반드시 미리 설치해야 합니다.

Index

Constants

This section is empty.

Variables

View Source
var (

	// 이벤트 IID
	IID_IDibEvents, _    = ole.CLSIDFromString("{B8944520-09C3-11D4-8232-00105A7C4F8C}")
	IID_IDibSysEvents, _ = ole.CLSIDFromString("{60D7702A-57BA-4869-AF3F-292FDC909D75}")
	IID_IDibTrEvents, _  = ole.CLSIDFromString("{8B55AD34-73A3-4C33-B8CD-C95ED13823CB}")
	IID_CpCybosEvents, _ = ole.CLSIDFromString("{17F70631-56E5-40FC-B94F-44ADD3A850B1}")

	// CpCybos의 LimitType 값들
	LT_TRADE_REQUEST    = 0
	LT_NONTRADE_REQUEST = 1
	LT_SUBSCRIBE        = 2
)

peekmessage 로드, 이벤트 iid

Functions

func CreateThread

func CreateThread(fnc Background, arg1 uintptr) (ret int32, err error)

윈도우스레드 구현

func PeekMessage

func PeekMessage(msg *ole.Msg, hwnd uint32, MsgFilterMin uint32, MsgFilterMax uint32, RemoveMsg uint32) (ret int32, err error)

PeekMessage 구현

func PumpWaitingMessages

func PumpWaitingMessages() int32

메시지 펌핑 (파이선 pythoncom.PumpWatingMessges 의 golang구현) WM_QUIT 로 종료되었을시 int32(1) 이 리턴됩니다.

Types

type Background

type Background func(uintptr) uintptr

type CpClass

type CpClass struct {
	// contains filtered or unexported fields
}

사이보스플러스 객체

func (*CpClass) BindEvent

func (c *CpClass) BindEvent(callback Receiver)

이벤트를 지정할때 사용합니다. Receiver 인터페이스를 구현한 콜백을 지정하여 이벤트 수신시 콜백을 호출되게 지정할수 있습니다.

func (*CpClass) BlockRequest

func (c *CpClass) BlockRequest()

사이보스플러스 BlockRequest 메서드 Wrapper

func (*CpClass) CodeToFullCode

func (c *CpClass) CodeToFullCode(cod string) (r *ole.VARIANT)

사이보스플러스 CpUtil.CpStockCode CodeToFullCode 메서드 Wrapper

func (*CpClass) CodeToIndex

func (c *CpClass) CodeToIndex(cod string) (r *ole.VARIANT)

사이보스플러스 CpUtil.CpStockCode CodeToIndex 메서드 Wrapper

func (*CpClass) CodeToName

func (c *CpClass) CodeToName(cod string) (r *ole.VARIANT)

사이보스플러스 CpUtil.CpStockCode CodeToName 메서드 Wrapper

func (*CpClass) Create

func (c *CpClass) Create(name string)

사이보스플러스 객체 생성 "Library.coclass" 문자열을 넣어 객체를 생성합니다. "CpDib.StockMst" 와 같은 식으로 사용합니다.

func (*CpClass) FullCodeToCode

func (c *CpClass) FullCodeToCode(fullcod string) (r *ole.VARIANT)

사이보스플러스 CpUtil.CpStockCode FullCodeToCode 메서드 Wrapper

func (*CpClass) FullCodeToName

func (c *CpClass) FullCodeToName(fullcod string) (r *ole.VARIANT)

사이보스플러스 CpUtil.CpStockCode FullCodeToName 메서드 Wrapper

func (*CpClass) GetContinue

func (c *CpClass) GetContinue() (r *ole.VARIANT)

사이보스플러스 Property Getter 메서드입니다. Continue 프로퍼티 값을 얻어옵니다.

func (*CpClass) GetCount

func (c *CpClass) GetCount() (r *ole.VARIANT)

사이보스플러스 CpUtil.CpStockCode GetCount 메서드 Wrapper

func (*CpClass) GetData

func (c *CpClass) GetData(typ int, idx int) (r *ole.VARIANT)

사이보스플러스 CpUtil.CpStockCode GetData 메서드 Wrapper

func (*CpClass) GetDataValue

func (c *CpClass) GetDataValue(typ int, idx int) (result *ole.VARIANT)

사이보스플러스 GetDataValue 메서드 Wrapper

func (*CpClass) GetDibStatus

func (c *CpClass) GetDibStatus() int16

사이보스플러스 GetDibStatus 메서드 Wrapper

func (*CpClass) GetHeaderValue

func (c *CpClass) GetHeaderValue(typ int) (result *ole.VARIANT)

사이보스플러스 GetHeaderValue 메서드 Wrapper

func (*CpClass) GetIsConnect

func (c *CpClass) GetIsConnect() (r *ole.VARIANT)

사이보스플러스 CpUtil.CpCybos ServerType Property getter

func (*CpClass) GetLimitRemainCount

func (c *CpClass) GetLimitRemainCount(typ int) (r *ole.VARIANT)

사이보스플러스 CpUtil.CpCybos GetLimitRemainCount 메서드 Wrapper

func (*CpClass) GetLimitRequestRemainTime

func (c *CpClass) GetLimitRequestRemainTime() (r *ole.VARIANT)

사이보스플러스 CpUtil.CpCybos LimitRequestRemainTime Property getter

func (*CpClass) GetServerType

func (c *CpClass) GetServerType() (r *ole.VARIANT)

사이보스플러스 CpUtil.CpCybos ServerType Property getter

func (*CpClass) NameToCode

func (c *CpClass) NameToCode(nm string) (r *ole.VARIANT)

사이보스플러스 CpUtil.CpStockCode NameToCode 메서드 Wrapper

func (*CpClass) Release

func (c *CpClass) Release()

Create 메서드로 생성한 객체 헤제할떄 사용합니다.

func (*CpClass) Request

func (c *CpClass) Request()

사이보스플러스 BlockRequest 메서드 Wrapper

func (*CpClass) SetInputValue

func (c *CpClass) SetInputValue(typ int, val interface{})

사이보스플러스 SetInputValue 메서드 Wrapper

func (*CpClass) Subscribe

func (c *CpClass) Subscribe()

사이보스플러스 Subscribe 메서드 Wrapper

func (*CpClass) SubscribeLastest

func (c *CpClass) SubscribeLastest()

사이보스플러스 SubscribeLastest 메서드 Wrapper

func (*CpClass) UnbindEvent

func (c *CpClass) UnbindEvent()

지정된 이벤트 헤제

func (*CpClass) Unsubscribe

func (c *CpClass) Unsubscribe()

사이보스플러스 Unsubscribe 메서드 Wrapper

type Receiver

type Receiver interface {
	Received(*CpClass)
}

사이보스플러스의 콜백메서드 인터페이스

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL