닷넷 프레임워크(.NET Framework, 이전 이름: 닷넷)는 마이크로소프트에서 개발한 윈도우 프로그램 개발 및 실행 환경이다. 네트워크 작업, 인터페이스 등의 많은 작업을 캡슐화하였고, 공통 언어 런타임(Common Language Runtime)(CLR)이라는 이름의 가상 머신 위에서 작동한다.

 

 

 

 

Windows10에는 기본적으로 Microsoft.NET\Framework 디렉토리가 설정되어 있다.(예를 들어, c# compiler,,,,,)

#FTP server/client standard tcp program

 

fss_client.c
0.00MB
fss_server.c
0.00MB

 

 

NOT fork

NOT thread

NOT select

STANDARD tcp OK

 

 

비고) 클라이언트소스에 <sys/sendfile.h>에 선언되어진 sendfile 이라는 함수가 유용하게 사용된다.

#거래소 & Koscom 정보분배 Tcp데이타 수신및 처리

 

1. 수신받는 쪽이 서버입니다.

    1.1 거래소 & Koscom은 데이타를 송신하는 역할을 합니다.

    1.2 Ack데이타가 없다.(무조건 수신만 받는 서버의 역할을 담당합니다.) 

    1.2.1 다른 서버&클라이언트 구조와 다르게, Ack데이타가 존재하지 않으므로 수신하는 서버의 하드웨어 스펙과
    수신프로그램의 성능이 중요합니다.

    1.2.2 송신프로그램에서 1000 Record 라는 데이타를 주었는데, 수신프로그램에서

    1000 Record 데이타를 수신 못한다면 수신서버는 제 역할을 못한다고 할수 있습니다.

    1.3 수신서버에서 데이타를 못받게된다면, 송신서버(거래소 & Koscom 정보분배)에서는
    Error를 결과값으로 받게됩니다.

    1.4 Error를 결과값으로 받게되면, 송신서버(거래소 & Koscom 정보분배)담당자는
    연락을 취하는경우가 보통입니다.

    1.5 간략하게 정리하자면, 송신서버(거래소 & Koscom 정보분배)에서는 send라는 함수만 사용하고

    1.6 수신서버에서는 recv함수만 사용하면 되는것입니다.

 

2. 수신받는 데이타가 하나의 레코드가 아닐수 있습니다.

    2.1 최소 1개 레코드에서 n개의 레코드가 될수 있습니다.(호가여러개, 혹은 호가와 체결이 결합되어진 여러개)

    2.2 물론 레코드와 레코드를 분리하는 방법은 수신패킷 내부에 포함되어 있습니다.

 

3. 레코드와 레코드 사이의 구별하는 패킷분리 인자가 보통 3개 존재합니다.

    3.1 0xff, 0x0d, 0x0a 3개의 char변수를 기반으로 분리합니다.

 

4. 레코드한개를 분리해서 처리하도록 합니다.

    4.1 여러개의 레코드에서 한개의 레코드를 추출해서, 처리를 합니다.

        4.1.1 호가 레코드, 1종목 처리

        4.1.2 체결 레코드, 1종목 처리

    4.2 추출한 레코드를 수신프로그램에서 동시에 처리하는것은 바람직 하지 않습니다.

        4.2.1 주로 Queue를 통해서 전송해서 Queue를 읽어들이는 처리프로그램을 따로 작성해야 합니다.

    4.3 Queue통해서 읽어들인 레코드는 주식로직을 통해서 처리합니다.

    4.4 주식로직에 대한 부분은 너무 방대하므로 여기서는 SKIP합니다.

    4.5 수신구조체가 필요합니다.

    4.6 처리구조체가 필요합니다.(수신된 데이타를 전부 보관하는건 비효율적이라고 생각합니다.)

    4.6.1 화면에서 필요한 데이타를 기획해서, 처리구조체를 정의하면 됩니다.

 

5. 처리되어진 데이타는 저장소에 보관합니다.(대량의 데이타이고 빠른 조회를 위해서 메모리 기반으로 많이 저장소를 선택합니다.)

    5.1 Shared Memory가 될수 있습니다.

    5.2 DataBase가 될수 있습니다.

    5.3 File가 될수 있습니다.

 

6. 저장되어진 데이타를 조합해서, 클라이언트로 보내주면,거래소 & Koscom 정보분배 Tcp데이타를 외부에서 볼수 있습니다.

    6.1 Web
    (Request & Response <-> Web Server <-> Was(Tomcat) <-> JNI <-> Jni FrameWork <-> Memory In Server)

    6.2 HTS

    6.3 MTS

 

7. 업무볼륨

    7.1 1-5번까지의 부분은 서버의 역할중에서 10%정도 볼륨이며

    7.2 5-6번까지의 부분이 나머지 90%의 역할을 담당합니다.

 

 

더욱 궁금한부분은 xterm92@naver.com으로 연락부탁드립니다.

 

#Compile

gcc -I/usr/local/jdk1.7.0_79/include -I/usr/local/jdk1.7.0_79/include/linux -I/usr2/sinfo/src/include -I/usr/local/mysql/include -I./../jni_include  -fPIC -g -c -Wall SiseLibJong.c

 

gcc -I/usr/local/jdk1.7.0_79/include -I/usr/local/jdk1.7.0_79/include/linux -I/usr2/sinfo/src/include -I/usr/local/mysql/include -I./../jni_include  -fPIC -g -c -Wall ShmOpJong.c

 

 

#Link(so)

#gcc -shared -fPIC -o libShmJong.so SiseLibJong.so ShmOpJong.so

../util/Common.o /usr2/sinfo/src/util/MEMORY.o /usr2/sinfo/src/util/IPC.o /usr2/sinfo/src/util/STRLIB.o /usr2/sinfo/src/util/FUNC.o -lm -lpthread -lnsl

 

#Link(exe)

#gcc -o exeShmJong SiseLibJong.so ShmOpJong.so

../util/Common.o /usr2/sinfo/src/util/MEMORY.o /usr2/sinfo/src/util/IPC.o /usr2/sinfo/src/util/STRLIB.o /usr2/sinfo/src/util/FUNC.o -lm

-lpthread -lnsl

 

 

 

 

Makefile
0.00MB

 

 

증권사는 전용선을 통해서 UDP데이타를 수신하며

인터넷사업자 & 개인은 인터넷을 통한 TCP데이타를 수신받는다.

 

구축에 대한 문의는 xterm92@naver.com 으로 주세요.

 

 

c_sharp_console_hexa.cs
0.01MB

 

Windows10에서 c#을 이용한 Console Hexa 프로그램(When? - 2021.04.08 final Update)

 

Based By)Microsoft.NET

 

Microsoft 공식 홈페이지

Microsoft는 목표와 가치는 전세계의 사람과 기업이 잠재력을 최대한 발휘할 수 있도록 돕는 것입니다.

www.microsoft.com

 

 

 

 

c# 소스파일에 대한 컴파일할수 있는 환경을 만들었다.

 

Windows10 에는 Microsoft.NET\Framework64\가 자동으로 설정되어 있다. 

 

즉 c#을 사용할수 있다. csc(C# compiler)

 

Windows10 에는 2가지 개발도구가 존재한다.

1. c#

2. WebBrowser 의 JavaScript

 

 

 

docs.microsoft.com/ko-kr/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed

 

설치된 .NET Framework 버전 확인

코드, regedit.exe 또는 PowerShell을 사용하여 Windows 레지스트리를 쿼리하는 방법으로 컴퓨터에 설치된 .NET Framework 버전을 검색합니다.

docs.microsoft.com

 

 

RcvManualData.c
0.02MB
packet.h
0.00MB

 

마지막이 0xff로 끝나는,ㅡㅡ 데이타를 수신할경우에,ㅡㅡㅡㅡㅡㅡㅡㅡ
while(1)
{
    csock = accept();
    while(1)
    {
        recv_len = recv( csock, tmp, sizeof(tmp), 0);
        if(recv_len > 0)
        {
            for(ii=0; ii<recv_len; ii++)
            {
                data[data_len++ ] = tmp[ii];
                if(data_len > 2 && (unsifned char)data[data_len - 1] == (unsigned char)0xff)
                {
                    fprintf(stderr, "%.*s\n", data_len, data);
                    data_len = 0;
                    memset(data, 0x00, sizeof(data));
                }
           }
       }
        else break;
    }
    close(csock);
}

recv_handler.c
0.00MB

fss_send.c
0.00MB

 



#증권정보홈페이지를 만들어보자
#증권정보홈페이지를 만들어보자

https://finance.naver.com/ 

 

네이버 금융

국내 해외 증시 지수, 시장지표, 펀드, 뉴스, 증권사 리서치 등 제공

finance.naver.com

 

동일한 데이타를 보여주는 증권정보홈페이지를 만들어보자

 

1. 준비

1.1 벡엔드 언어:c, Java, Shell Script(Free)

1.2 프론트엔드언어:Java,Jsp,JavaScript,Css,HTML(Free)

1.3 OS : CentOS 6.0(Free)

1.4 DataBase : MySQL(Free)

 

2. 거래소 정보분배에서 TCP데이타 받기(체결,호가등등)

2.1 수신 구조체정의

2.2 소켓프로그램 작성(서버)
     - udp 데이타수신시(증권사,전용선일경우)
     - tcp 데이타 수신시(인터넷포탈,등등)

 

3. 받은 데이타를 메모리(Shared Memory), DB에 저장하기

3.1 저장 구조체정의

3.2 Shared Memory에 저장

3.3 DB에 저장

 

4. 프론트엔드에서 호출할 so파일 생성하기

4.1 호출구조체정의

4.2 so 라이브러리 작성(JAVA에서는 System(IPC등)에 직접 접근할수 없기때문에, c언어로 작성되어진 DLL함수를 통해서 데이타에 접근해야 한다)

4.3 JNI 호출(서버단)

 

5. 프론트엔드 작업하기

5.1 기획및 페이지 디자인

5.2 Java Server Page 작성

5.2 JNI 호출(클라이언트단)

 

6. 웹 브라우져로 테스트

6.1 www.suksu.kr(가칭, 실제구축하게 된다면) 접속시에 홈페이지가 정상으로 호출되는지 체크

 
실제 Web화면 예)
1. 종목정보(005930) - 2016년도 데이타 이용


2. 상승율상위종목 - 2016년도 데이타 이용


위에 대해서 궁금하시면 xterm92@naver.com 으로 연락주시면 상세히 설명드리겠습니다.

 

 

xterm92@naver.com 으로 문의주세요.

APINFQ0020.cs
0.02MB

 

 

 

 

using System;
using System.Collections.Generic;

 

namespace WinHexaExture
{
    public partial class APINFQ0020 : Form
    {

        public APINFQ0020()
        {
            InitializeComponent();
        }

    }

}

 

 

 

비고) Compile & Link By Visual Studio 2019 Professional Edition____

 

 

 

____real_fast_no_ajax_hexa.html
0.02MB

 

 

#AJAX를 사용할 경우에(was 서버를 경우하게 되면), 2인 이상의 네트웍크 헥사를 구성할수 있습니다.

#AJAX를 사용할 경우에(was 서버를 경우하게 되면), 2인 이상의 네트웍크 헥사를 구성할수 있습니다.

주식 매매 체결 순서 설명

주식 체결 순서 원칙에 따르면 다음과 같은 일도 일어 납니다. 보유하고 있던 주식을 10,000원에 매도 주문을 냈는데 10,500원에 매도 되는 일 말입니다.
자주 일어나는 일은 아니지만, 주식 매매 원칙에 따르면 충분히 일어날 수 있는 일입니다.
주식 체결 순서 원칙은 주식 거래가 정규 시장, 동시호가 시간, 시간외 거래 시간 이루어지냐에 따라 조금 차이가 나는데요, 기본이 되는 정규 시장의 원칙부터 알아보겠습니다.

주식 거래는 정규 시장에 주로 이루어 지지만 아래와 같이 정규 거래 시간 외에도 주식을 거래할 수 있는 시간이 있습니다.
    - 정규 시장: 오전 9시 ~ 오후 2시 50분
    - 동시호가 시간: 오전 8시 ~ 오전 9시, 오후 2시 50분 ~ 오후 3시
    - 시간외 매매: 오전 7시 30분 ~ 오전 8시 30분, 오후 3시 ~ 오후 3시 30분, 오후 3시 30분 ~ 오후 6시
정규 시장 전 동시호가 시간과 오전 시간외 매매 시간 일부가 겹치는 것으로 보이지만, 시간외 매매는 정규 시장 거래 창이 아니라 별도의 거래 창에서 이루어 지기 때문에 거래가 겹치는 것은 아닙니다.

정규 시장 주식 체결 순서

가격 우선 → 시간 우선 → 수량 우선 순의 체결 원칙에 따라 매매가 이루어 지는데요, 구체적인 예를 들어 어떻게 이 원칙에 따라 매매가 체결 되는 지는 잠시 후에 알아 보겠습니다.자
정규 시장은 오후 3시까지이지만 마지막 10분 즉 오후 2시 50분에서 3시까지는 동시호가 체결 원칙에 따라 거래가 이루어 집니다. 따라서 가격, 시간, 수량 순의 우선 순위 체결 원직은 오전 9시부터 오후 2시 50분까지의 시간 동안 지켜지는 것이라고 보면 됩니다.

가격 우선 체결 원칙

주식을 사거나 팔 때 시장가로 매매 하기도 하지만, 보통은 매도 호가나 매수 호가를 지정하여 거래를 합니다.
가격 우선 원칙은 매도 호가는 낮은 가격이 높은 가격에 우선하고 매수 호가는 높은 가격이 낮은 가격에 우선한다는 원칙입니다.
이 원칙에 따르게 되면 여러 사람이 매도 호가와 매수 호가를 지정하여 주식을 매매 할 때, 가장 낮은 매도 호가를 부른 사람과 가장 높은 매수 호가를 부를 사람의 거래가 성립되게 됩니다.
이렇게 첫 번째 거래가 성립되고 나면 두 번째로 우선 순위를 갖는 매도자와 매수자와의 거래가 성립되고 또 다음 우선 순위를 갖는 거래가 성립되는 식으로 순차적으로 매매 거래가 체결 됩니다.
말은 이런 식으로 하지만 전산 처리되어 순식간에 체결이 이루어지죠. 물론 매도 우선 순위를 갖는 사람과 매수 우선 순위를 갖는 사람이 있지만 가격 조건이 맞지 않아 거래가 이루어 지지 않는 경우도 있습니다.

아래 예를 통해 구체적으로 살펴 보겠습니다.

어떤 주식에 대해 다음과 같이 매도 호가를 부른 사람 두 명(A와 B), 매수 호가를 부른 사람 두 명(갑과 을)이 있다고 가정해 보겠습니다.

    - A는 100주를 1주당 8,000원에 매도 하려고 하고,
    - B는 50주를 1주당 9,000원에 매도 하고자 함.
    - 갑은 100주를 1주당 10,000원에 매수 하려고 하고,
    - 을은 10주를 1주당 7,000원에 매수 하려고 함.
    - 가격 우선 체결 순서에 따르면 매도자 중에서는 낮은 매도 가격을 낸 A가 우선 순위를 가지고 매수자 중에서는 높은 매수 가격을 제시한 갑이 우선 순위를 가집니다.

A와 갑의 가격 조건을 보니 팔려는 사람(A)보다 사려는 사람(갑)이 비싸게 가격을 제시 했네요. 갑은 1주당 10,000원을 주고 100주는 매입하게 됩니다. A는 1주당 8,000원에 팔려고 했지만 갑 덕분에 1주당 10,000원에 팔 수 있게 되었습니다.
이번에는 다음 우선 순위를 가지는 B와 을의 가격 조건을 검토해 보겠습니다. B는 1주당 9,000원에 팔려고 하지만 을은 7,000원에 매수 하려고 합니다. 두 사람이 직접 만난다면 가격 흥정을 해 볼 수 있겠지만, 정규 주식 시장에서의 거래는 둘이 직접 만나 가격 흥정을 하는 식으로 거래가 성립 되지는 않지요.
그래서 B와 을 사이에는 가격이 맞지 않아 거래가 성립되지 않습니다. 결국 위의 예에서는 A와 갑사이에서만 거래가 성립됩니다.
실제 주식 시장에서는 위의 예 보다 훨씬 더 많은 매도자와 매수자가 있습니다. 따라서 실제 주식 체결 순서는 위 예보다는 좀 더 복잡하지만, 기본 원칙은 위에서 설명한 예와 같습니다.
가격을 기준으로 우선 순위를 가지는 매도자와 매수자를 걸러 내고 둘 사이에 가격이 맞다면 주식 매매가 체결 되고, 그 다음 우선 순위를 가지는 매도자와 매수자 간의 가격 조건을 검토하여 거래 성립 여부를 본 후, 또 그 다음 우선 순위를 가지는 매도자와 매수자의 거래 성립을 판단 하는 식으로 주식 거래가 이루어 집니다.

시간 우선 체결 원칙

앞의 예에서는 A와 B, 갑과 을이 서로 다른 가격을 제시한 것으로 가정했는데요, 만약 매도자들이 서로 같은 가격 또 매수자들이 서로 같은 가격을 제시한다면 어떻게 될까요?
바로 다음과 같은 상황인데요,

    - A: 한주당 8,000원 100주 매도 주문,
    - B: 한주당 8,000원 50주 매도 주문,
    - 갑: 한주당 10,000원 100주 매수 주문
    - 을: 한주당 10,000원 10주 매수 주문

가격이 같기 때문에 가격 우선 원칙을 적용하여 우선 순위를 가지는 사람을 판별할 수 없습니다.
그래서 등장하는 것이 시간 우선 원칙입니다. 즉, A가 B보다 먼저 매도 주문을 냈다면 매도자 중에서는 A가 우선 순위를 가지고 을이 갑보다 먼저 매수 주문을 냈다면 매수자 중에서는 을이 우선 순위를 가지게 되죠.
따라서 먼저 A와 을 사이에 거래가 성립 됩니다. 가격은 을의 매수 주문 가격인 한주당 10,000원이 됩니다. 그런데 을은 10주만 매수 하려 하기 때문에 A의 주식은 일단 10주만 매도 됩니다.
매도자 중에서 A는 아직도 90주(100주-10주)만큼 우선 순위를 가지고 있습니다. 매수자 중에서는 이제 갑만 남았습니다. 갑은 한주당 10,000원으로 A로부터 90주를 매수할 수 있게 됩니다.
갑은 100주를 구입하려 했으니 아직 10주를 구입 못한 상태입니다. 매도자 중에서 A는 팔려는 주식을 모두 팔았으니 이제 B만 남았습니다. 갑은 B로부터 한주당 10,000원으로 10주를 매수 하게 됩니다.

수량 우선 체결 원칙

앞에서 가격 우선 원칙을 살펴 보았고, 가격이 같다면 시간 우선 주식 체결 순서에 따라 거래가 성립 되는 것을 알아 보았습니다.
그런데, 가격도 같고 주문을 낸 시간도 같다면 어떻게 될까요?
이때는 수량 우선 원칙이 적용되게 되는데요, 주문 수량이 많은 사람이 우선한다는 원칙입니다.
다음과 같은 상황을 가정해 보겠습니다. A,B,C 모두 같은 시각에 매도 주문을 내었고, 갑과 을도 같은 시간에 매수 주문을 내었습니다.

    - A: 한주당 8,000원 100주 매도 주문,
    - B: 한주당 8,000원 50주 매도 주문,
    - C: 한주당 8,000원 70주 매도 주문,
    - 갑: 한주당 10,000원 100주 매수 주문,
    - 을: 한주당 10,000원 10주 매수 주문

매도자들이 서로 같은 가격으로 주문을 했고 매수자들도 같은 매수 가격을 제시했으니, 가격 우선 체결 원칙은 적용될 수 없고, 또 같은 시각에 주문을 내었으니 시간 우선 원칙도 적용될 수 없습니다.
이 경우에는 수량 우선 주식 체결 원칙에 따라 거래가 이루어 집니다. 주문 수량이 많은 순으로 우선 순위가 정해 지므로 매도자는 A → C → B, 매수자는 갑 → 을 순으로 우선 순위를 갖게 됩니다.
따라서 갑은 A에게서 100주를 주당 10,000원으로 매수하게 되고, 을은 C로부터 주당 10,000원으로 10주를 매수하게 됩니다.
B는 한 주도 팔지 못하고 C는 70주 중에서 10주만 매도에 성공하게 됩니다.
이상 정규 시장에서의 주식 체결 순서였습니다. 이제 동시호가 시간의 주식 체결은 어떻게 이루어 지는 지 알아 보겠습니다.

동시호가 시간엔 모두 거래가 동시에 이루어 졌다고 가정하여 주식 체결

동시호가 시간은 오전 8시에서 오전 9시까지(장전 동시호가) 한 시간 또 오후 2시 50분에서 오후 3시까지(장 마감 동시호가) 10분간 이루어 집니다.
이 시간에 이루어 지는 매도·매수 주문은 모두 동시에 이루어 진 것으로 간주합니다. 동시(同時)호가라는 이름은 그래서 생긴 것이죠.
어쨌든 이 원칙에 따르면 오전 8시에 낸 주문도 오전 8시 50분에 낸 주문도 같은 시간에 이루어 진 것으로 간주하게 됩니다.
따라서 동시호가 시간의 주식 매매에는 시간 우선 원칙을 적용할 수 없습니다. 가격 우선 원칙을 먼저 적용하고 그 다음에 수량 우선 원칙을 적용하게 되죠.
그런데 일정 시간 동안에 있었던 주식 매매 주문을 같은 시간에 이루어 진 것으로 간주할 경우 , 일정 시점을 끊어서 거래를 체결해 주어야 합니다. 그렇지 않으면 거래가 이루어지지 않겠지요.
그래서 장전 동시호가 시간에 있었던 주문들은 오전 9시에 동시에 이루어 진 것으로 보아 일괄적으로 체결하고 장 마감 동시호가 시간에 있었던 주문들은 오후 3시에 일괄적으로 체결 됩니다.

시초가와 종가

잠시 후에 동시호가 시간의 주식 체결 방식을 구체적으로 알아 볼텐데요, 동시호가 주식 체결 방식에 따라 결정된 주식 가격은 특별한 의미를 가집니다.
즉, 장전 동시호가에서 결정된 주식 가격은 시초가가 되고 장마감 동시호가에서 결정된 주식 가격은 그날의 종가가 됩니다.
어떻게 시초가와 종가가 결정 되는 지는 아래에서 예를 들어 알아 보겠습니다.

동시호가 주식 체결 방식

동시호가 시간에 있었던 주문은 모두 같은 시간에 한 것으로 간주하고 가격 우선 → 수량 우선 체결 원칙이 적용 된다고 했는데요, 정규 시장과 다른 점이 한 가지 더 있습니다.
동시호가 시간의 주문은 가격 우선과 수량 우선 순서로 적용하되 모든 주문을 한꺼번에 체결 하기 때문에 마지막으로 성립되는 거래에서 매수자가 제시한 가격으로 일괄 체결된다는 점이 다릅니다.
아마 말로는 쉽게 이해되지 않을 것 같은데요, 아래의 예를 보면 금방 이해할 수 있습니다.
동시호가 시간 동안 어떤 주식에 대해 매도자와 매수자가 다음과 같이 주문을 했다고 가정해 보겠습니다.

    매도자
    - A: 주당 10,000원에 100주
    - B: 주당 10,100원에 10주
    - C: 주당 10,200원에 30주
    매수자
    - 갑: 주당 10,300에 70주
    - 을: 주당 10,150에 30주
    - 병: 주당 10,150에 50주

가격 → 수량 우선 순서에 따라 매도자는 A → B → C 순으로 우선 순위를 가지고, 매수자는 갑 → 병 → 을 순으로 우선 순위를 가지게 됩니다.
일단 갑과 A 사이에 70주 거래가 가능합니다.

그 다음 우선 순위인 병은 A로부터 30주를 살 수 있고 B로부터 10주를 살 수 있습니다. 여기까지의 상황은 A와 B가 주문을 낸 만큼 모두 팔 수 있고, 갑은 원하는 수만큼 모두 구매 할 수 있으며 병은 원하는 수량 50주 중 40주를 매수할 수 있는 상황입니다.
병이 나머지 10주를 매수하기 위해서는 C로부터 매수해야 하는데 C는 10,200원에 팔기를 원하고 병은 10,150에 매수하기를 원하므로 거래가 성립되지 않습니다.
따라서 마지막으로 성립된 거래는 병과 B사이의 거래고 이 때의 매수 가격은 10,150원입니다. 위 예가 장전 동시호가라면 10,150원이 시초가가 될 것이고 장 마감 동시호가라면 10,150원이 종가가 됩니다.
정규시장이었다면, 갑과 A 사이는 10,300원으로 거래가 되겠지만, 동시호가 시간의 거래 원칙에 따라 갑과 A 사이도 최종 거래 가격인 10,150원으로 거래가 됩니다. 이제 ‘동시호가 시간의 거래는 마지막으로 성립되는 거래에서 매수자가 제시한 가격으로 일괄 체결 된다.’는 말을 이해할 수 있을 것입니다.

장전 동시호가시간 거래할 때 주의할 점

회사 출근 때문에 HTS나 MTS를 이용할 수 없는 직장인이나 비슷한 이유로 장중에 주식 매매를 할 수 없는 경우 오전 8시 ~ 오전 9시 사이에 미리 주문을 내어 놓는 경우가 있습니다.
동시호가 주식 체결 방식에 따라 거래가 성립된다면 9시에 일괄적으로 체결되지만, 자신이 낸 주문이 체결 되지 않았다면 어떻게 될 까요?
장 마감 동시호가 시간에 낸 주문이 체결되지 않는 경우에는 오후 3시에 자동으로 취소가 됩니다만, 장전 동시호가 시간에 낸 주문이 체결 되지 않는 경우는 자동으로 취소가 되지 않습니다.
따라서 체결 되지 않은 (장전 동시호가 시간에 낸) 주문은 오전 9시에 취소 주문을 하는 것이 좋습니다.
물론 주문 내용 그대로 장 중에 매매가 되기를 희망한다면 굳이 취소 주문을 한 후 새로 주문을 낼 필요가 없지만,
주식이라는 것이 장전 분위기와 장 시작한 후의 분위기가 다른 때가 많은 법이니 장전 동시호가 시간에 내었던 주문은 꼭 체결 되었는지 여부를 확인하고 체결되지 않았다면 필요한 조치(그대로 두거나, 취소 주문을 내거나, 아니면 취소 주문후 새로운 조건으로 주문을 내 는 조치)를 취해야 한다는 점을 잊지 마시기 바랍니다.

시간외 거래

시간외 거래는 시간외 종가 매매와 시간외 단일가 매매로 나뉘어 지는데요, 시간외 종가 매매는 전일 종가로만 거래되는 장전 시간외 거래 시간(오전 7시 30분 ~ 오후 8시 30분)와 당일 종가로만 거래되는 장후 시간외 거래 시간(오후 3시 ~ 오후 3시 30분)으로 나누어 집니다.
장후 시간외 거래의 경우는 오후 3시부터 주문을 할 수는 있지만 체결은 오후 3시 10분부터 이루어 집니다.
시간외 단일가 매매는 오후 3시 30분~ 오후 6시 사이에 이루어 지는데요, 당일 종가 기준 ±5% 범위에서 매수 매도 주문을 낼 수 있습니다.
단, 상한가와 하한가를 초과할 수는 없기 때문에 상한가로 마감된 경우에는 상한가~상한가-5%, 하한가로 마감된 경우에는 하한가 ~ 하한가+5% 범위에서 주문을 낼 수 있습니다.
시간외 단일가 매매 체결은 오후 4시 ~ 오후 6시 사이에 10분 단위로 동시호가 방식으로 이루어 집니다.
시간외 거래 주문은 동시호가나 정규장 시간에 이용하는 창이 아니라 별도의 창(증권사에 따라서는 주문 종류 선택으로 하는 곳도 있음)에서 해야 합니다.

주식 체결 순서에 대한 결론

지금까지 정규 주식 시장, 동시호가 시간, 시간외 거래 시간에 주식이 체결 되는 방식에 대해 알아 보았는데요,
주식 체결 순서 원칙은 정규 시장에서 이루어 지는 가격 → 시각 → 수량 우선 원칙입니다. 동시호가 시간과 시간외 거래는 이 원칙의 변용으로 이해하면 됩니다.
체결 순서 기본 원칙에 따라 매도자 입장에서 빨리 매도에 성공하려면 가능한 한 낮은 가격으로 빨리 또 가능한 많은 수량의 주문을 내야 하고 매수자 입장이라면 가능한 한 높은 가격으로 최대한 빨리 많은 수량의 주문을 내야 한다는 것을 알 수 있습니다.
그런데 매도자 입장에서는 최대한 높은 가격으로 팔고 매수자 입장에서는 될 수 있는 한 낮은 가격으로 주식 거래를 체결해야 이익입니다. 가격 우선 체결 원칙은 이와는 반대로 가죠.
시간 우선 체결 원칙 상황도 비슷합니다. 빨리 거래를 성공시키기 위해서는 빨리 주문을 내야 하지만, 주식 투자라는 것이 간을 보아야 할 때가 많습니다.
수량 우선 상황도 비슷하죠. 많은 수량으로 주문을 내야 빨리 거래를 성공 시킬 수 있지만, 보유 주식을 한꺼번에 매도 하는 것보다는 분할 매도 하는 것이 또 분할 매수 하는 것이 일반적인 주식 투자 원칙입니다.
이처럼 주식 체결 순서 원칙은 주식 투자를 통해 수익를 얻으려는 목적과 반대되는 경향이 있다는 점을 염두에 두시기 바랍니다.
물론 주식 투자를 하다 보면 최대한 빨리 팔거나 사야 할 때가 있고 이 때는 주식 체결 순서를 고려하여 주문을 내야 하지만, 그렇지 않은 상황에서는 사실 주식 체결 순서를 그리 민감하게 고민할 필요는 없다는 말씀입니다.
주식 체결 순서 원칙보다는 자신만의 투자 원칙에 집중하는 것이 더 좋다는 생각입니다.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>

#include "tagwire.h"
#include "fssdefine.h"

#define HEADERINDEX 13

int main(int argc, char *argv[])
{
FILE *fp=NULL;
char rbuf[4096 * 2L];

if(argc != 2) return -1;

if((fp=fopen(argv[1], "rt"))==NULL) return -1;

while(1)
{
memset(rbuf, 0x00, sizeof(rbuf));
if(fgets(rbuf, sizeof(rbuf), fp)==NULL) break;
rbuf[strlen(rbuf)-1]=0x00;

        if(memcmp(rbuf+HEADERINDEX,"296=",4)==0)
{
struct TradableInstrument *ie=NULL;

ie = TradableInstrument(rbuf + HEADERINDEX);

if(ie != NULL)
{
//printf("%s", rbuf);
printf("SEQ[%07ld],", kk+1);
printf("MessageID[%.4s],", rbuf+HEADERINDEX);
printf("shortName:[%s],", ie->shortName);
printf("orderBookId:[%ld],", ie->orderBookId);
printf("closingPrice:[%ld],", ie->closingPrice);
printf("isDeleted:[%c],", ie->isDeleted);
printf("upperPriceLimit:[%ld],", ie->upperPriceLimit);
printf("lowerPriceLimit:[%ld],", ie->lowerPriceLimit);
printf("closingDate:[%s]", ie->closingDate);

printf("\n");
}
}
else if(memcmp(rbuf+HEADERINDEX,"496=",4)==0)
{
struct IndexEvent *ie=NULL;

ie = IndexEvent(rbuf + HEADERINDEX);

if(ie != NULL)
{
//printf("%s", rbuf);
printf("SEQ[%07ld],", kk+1);
printf("MessageID[%.4s],", rbuf+HEADERINDEX);
printf("sequenceNumber[%ld],", ie->sequenceNumber);
printf("timeOfEvent[%s]", ie->timeOfEvent);

printf("\n");
}
}
else if(memcmp(rbuf + HEADERINDEX,"140=",3)==0)
{
struct MarketByLevelEvent *ie=NULL;

ie = MarketByLevelEvent(rbuf + HEADERINDEX);

if(ie != NULL)
{
//printf("%s", rbuf);
printf("SEQ[%07ld],", kk+1);
printf("MessageID[%.3s],", rbuf+HEADERINDEX);
printf("timeOfEvent[%s],",ie->timeOfEvent);
printf("orderBook[%ld],",ie->orderBook);
printf("isBid[%c],",ie->isBid);
printf("price[%ld],",ie->price);
printf("volume[%ld],",ie->volume);
printf("correspondingPrice[%ld]",ie->correspondingPrice);

printf("\n");
}
}
else if(memcmp(rbuf + HEADERINDEX,"51=",3)==0)
{
struct OrderBookStateChangeEvent *ie=NULL;

ie = OrderBookStateChangeEvent(rbuf + HEADERINDEX);

if(ie != NULL)
{
//printf("%s", rbuf);
printf("SEQ[%07ld],", kk+1);
printf("MessageID[%.3s],", rbuf+HEADERINDEX);
printf("timeOfEvent:[%s],", ie->timeOfEvent);
printf("orderBookRuleGroup:[%s]", ie->orderBookRuleGroup);

printf("\n");
}
}
else if(memcmp(rbuf + HEADERINDEX,"49=",3)==0)
{
struct TradeEvent *ie=NULL;

ie = TradeEvent(rbuf + HEADERINDEX);

if(ie != NULL)
{
//printf("%s", rbuf);
printf("SEQ[%07ld],", kk+1);
printf("MessageID[%.3s],", rbuf+HEADERINDEX);
printf("timeOfTrade[%s],", ie->timeOfTrade);
printf("orderQty[%ld],", ie->orderQty);
printf("price[%ld],", ie->price);
printf("highPrice[%ld],", ie->highPrice);
printf("lowPrice[%ld],", ie->lowPrice);
printf("totalTurnover[%ld],", ie->totalTurnover);
printf("correspondingPrice[%ld],", ie->correspondingPrice);
printf("tradeId[%s],", ie->tradeId);
printf("dealId[%s]", ie->dealId);

printf("\n");
}
}
else if(memcmp(rbuf + HEADERINDEX,"62=",3)==0)
{
struct AuctionEvent *ie=NULL;

ie = AuctionEvent(rbuf + HEADERINDEX);

if(ie != NULL)
{
//printf("%s", rbuf);
printf("SEQ[%07ld],", kk+1);
printf("MessageID[%.3s],", rbuf+HEADERINDEX);
printf("timeOfEvent[%s],",ie->timeOfEvent);
printf("orderBook[%ld],",ie->orderBook);
printf("calculatedAuctionPrice[%ld],",ie->calculatedAuctionPrice);
printf("matchedQuantity[%ld]",ie->matchedQuantity);

printf("\n");
}
}
}
if(fp != NULL) fclose(fp);
return(0);
}

TCP는 데이터 순서 보장을 위해 한 번에 하나의 Packet만 수신할까?

정답은 X입니다.
많은 데이터를 매번 ACK를 받고 보내기엔 너무 많은 Cost가 필요합니다.
위와 같은 문제를 해결하기 위해 window라는 논리적인 패킷 묶음을 사용합니다.
최소한의 ACK로 데이터 순서를 보장하며 전송을 할 수 있습니다.

 

 

참조문서 내용일부)

Receive socket buffer 크기가 결국은 TCP의 receive window이다. 어느 지점까지는 receive window가 크면 TCP throughput이 증가한다. 예전에는 socket buffer 크기를 애플리케이션이나 운영체제 설정에서 조절하고는 했다. 최신 네트워크 스택은 receive socket buffer 크기, 즉 receive window를 자동으로 조절하는 기능을 가지고 있다.

이후 애플리케이션이 read 시스템 콜을 호출하면 커널 영역으로 전환되고, socket buffer에 있는 데이터를 유저 공간의 메모리로 복사해 간다. 복사한 데이터는 socket buffer에서 제거한다. 그리고 TCP를 호출한다. TCP는 socket buffer에 새로운 공간이 생겼기 때문에 receive window를 증가시킨다. 그리고 프로토콜 상태에 따라 패킷을 전송한다. 패킷 전송이 없으면 시스템 콜이 종료된다.

 


참조)
https://d2.naver.com/helloworld/47667

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char *str = "ffffffaaaabcccddeeeeeffffgghijklmmmmnnnnopppqrstuuuuuvwxxxxxyyyyz";

int index[strlen(str)][2];

int kk, ff;

memset(index,0x00,sizeof(index));

    for(kk=0; kk<strlen(str); kk++)
{
index[kk][0] = *(str+kk);
}

    for(ff=0; ff<strlen(str); ff++)
{
    for(kk=0; kk<strlen(str); kk++)
    {
        if(index[ff][0] == index[kk][0]) index[ff][1]++;
}
}

for(kk=0; kk<strlen(str); kk++)
{
if(index[kk][1] ==1)
printf("[%c]>>>>[%d]\n", index[kk][0], index[kk][1]);
}


return(0);
}


/*
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.

C:\Users\SIHOO\Downloads\example>__11
[b]>>>>[1]
[h]>>>>[1]
[i]>>>>[1]
[j]>>>>[1]
[k]>>>>[1]
[l]>>>>[1]
[o]>>>>[1]
[q]>>>>[1]
[r]>>>>[1]
[s]>>>>[1]
[t]>>>>[1]
[v]>>>>[1]
[w]>>>>[1]
[z]>>>>[1]
*/

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char *str = "ffffffaaaabcccddeeeeeffffgghijklmmmmnnnnopppqrstuuuuuvwxxxxxyyyyz";

int kk, ff;

    if(strlen(str) > 3)
{
kk=0;
if(!( *(str+kk) == *(str+kk+1))) printf("%c", *(str+kk));

for(kk=1; kk<strlen(str) -1; kk++)
{
if(*(str+kk) == *(str+kk+1)) continue;
if(*(str+kk) == *(str+kk-1)) continue;

printf("%c", *(str+kk));
}
if(!( *(str+kk) == *(str+kk-1))) printf("%c", *(str+kk));
}
else
{
if(strlen(str) == 3)
{
kk=0;
     if(!( *(str+kk) == *(str+kk+1))) printf("%c", *(str+kk));

kk++;

ff=0;
if(*(str+kk) == *(str+kk+1)) ff=100;
if(*(str+kk) == *(str+kk-1)) ff=100;
if(ff==0)
{
printf("%c", *(str+kk));
}

kk++;
if(!( *(str+kk) == *(str+kk-1))) printf("%c", *(str+kk));
}
else if(strlen(str) == 2)
{
kk=0;
     if(!( *(str+kk) == *(str+kk+1))) printf("%c", *(str+kk));

kk++;
if(!( *(str+kk) == *(str+kk-1))) printf("%c", *(str+kk));
}
else
{
kk=0;
printf("%c", *(str+kk));
}
}

return(0);
}

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <string.h>

 

#define MAXLINE 9999
#define MAX_SOCK 128

 

int main(int argc, char *argv[]) 
{
FILE *fp=NULL;

char line[MAXLINE], message[MAXLINE+1], filename[MAXLINE+1];
struct sockaddr_in server_addr;
int maxfdp1;
int ____socket; /* 서버와 연결된 소켓번호 */
fd_set read_fds;

int kk=0;

 

if (argc != 4) {

printf("Usage : %s server_ip port filename\n", argv[0]);

printf("%s 127.0.0.1 12572 /usr2/suksu/ftp/BATCH_A0011.dat\n", argv[0]);

exit(0);
}

 

sprintf(filename, "%s", argv[3]);
if((fp=fopen(filename, "rt"))==NULL) exit(0);

/* 소켓 생성 */
if ((____socket = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("Client: Can't open stream socket.\n");
exit(0);
}

 

/* 채팅 서버의 소켓주소 구조체 server_addr 초기화 */
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));

/* 연결요청 */
if (connect(____socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
printf("Client: Can't connect to server.\n");
exit(0);

else 
{
    printf("Connected with server succ!!\n");
}

while (1) 
{
memset(line,0x00,sizeof(line));
if(fgets(line,sizeof(line),fp)==NULL) break;

line[strlen(line)-1]=0x00;

if (send(____socket, line, strlen(line), 0) < 0) 
{
printf("Client: Write error on socket.\n");
break;
}
//printf("%s\n", line);

usleep(4444);
kk++;
}

close(____socket);
if(fp != NULL) fclose(fp);

printf("FileName[%s] :[%05d]\n", filename, kk);
}

 

 

 

+ Recent posts