커뮤니티

예스스팟의 주문체결통보 객체가 이상합니다.

프로필 이미지
로봇짱
2021-11-30 13:06:54
902
글번호 154035
답변완료

첨부 이미지

안녕하세요. 언제나 친절한 답변에 감사드립니다. 파이선 등의 외부 프로그램에서 데이터베이스에 명령값 등을 수출하고, 그걸 예스스팟의 데이터베이스 객체로 읽어 예스스팟의 매매를 실행하는 전략을 만들었습니다. 그런데 이 전략을 오일, 골드 종목별로 여러개 띄울때 문제가 생깁니다. 종목별로 데이터베이스 테이블 명과 Chart1 의 종목 등을 변경 적용했을때, 주문체결통보객체(Main_OnNotifyFill)에서 반환값이 전략간 구분이 안가고 모든게 global 변수 처리돼 섞이는 것 같습니다. 주문접수응답 객체(Main_OnOrderResponse)는 종목별 전략 간에 섞이지 않는 것같습니다. 그런데 주문체결통보객체는 종목별 전략 간에 섞입니다. 이게 원래 그런건지 봐주십시오. 감사합니다. 첨부파일의 전략을 오일용으로 하나, 데이터베이스 테이블명과 Chart1 객체 설정을 바꿔서 골드용으로 또 하나 이렇게 전략 2개를 만들고 실행했을때 Main.MessageList 출력을 보면 jumunJunCode 가 종목별로 달라야 하는데 같은것으로 설정되는 문제를 첨부 파일 그림에서 볼 수 있습니다. ##################### 예스스팟 전략 ######################### var tableEreum="YESSPOT_IMSI_OIL"; // 마리아디비 테이블 이름 - 종목별. // 골드 종목시 "YESSPOT_IMSI_GOLD" var sqlSel*ct="0"; var fieldCountVV=0; var sql_rra_positionGo=new Array(); var jnibSuryang=2; var hhPythonPositionBalryung=0; var positionGoSeHengOn=0; var hhDocDoinpositionGoAnneBun=0; var position=0; var hhJnibga=0; var jumunJunCode="0"; var choKkuenHurum=1; var sql_rra=0; var hhGejwaBun=0; var isNormalVV=0; var orderNumVV=0; var orderCountVV=0; function Main_OnStart() { Main.MessageList("계좌번호=",hhGejwaBun); } ////////////////////////// Chart1==AD_position 2틱인. function Chart1_OnBarAppended(nData) { if (nData==1){ if (choKkuenHurum==1){ sqlSel*ct="count(ANNE) from "; sqlSel*ct+=tableEreum; sqlSel*ct+=";"; // Main.MessageList("sqlSel*ct=",sqlSel*ct); DataBase1.Sel*ct(sqlSel*ct,"AD"); sql_rra=DataBase1.GetFieldValue(0); if (sql_rra>=1){ ////////////// 포지션 데이터베이스 읽기 sqlSel*ct="* from "; sqlSel*ct+=tableEreum; sqlSel*ct+=" ORDER BY ANNE DESC LIMIT 1;"; // Main.MessageList("sqlSel*ct=",sqlSel*ct); DataBase1.Sel*ct(sqlSel*ct,"AD"); fieldCountVV=DataBase1.GetFieldCount(); for (var i=0; i<=fieldCountVV-1; i++){ sql_rra_positionGo[i]=DataBase1.GetFieldValue(i); } if (Math.abs(sql_rra_positionGo[4])==1){ choKkuenHurum=2; // 실시간 포지션 수출이 시작됐으면 흐름 2 영구 부여. } } } ////////////// 포지션 데이터베이스 읽기 if (choKkuenHurum==2){ sqlSel*ct="* from "; sqlSel*ct+=tableEreum; sqlSel*ct+=" ORDER BY ANNE DESC LIMIT 1;"; // Main.MessageList("sqlSel*ct=",sqlSel*ct); DataBase1.Sel*ct(sqlSel*ct,"AD"); fieldCountVV=DataBase1.GetFieldCount(); for (var i=0; i<=fieldCountVV-1; i++){ sql_rra_positionGo[i]=DataBase1.GetFieldValue(i); // 결. 배열에 마지막 행 배치한. } hhPythonPositionBalryung=0; hhPythonPositionBalryung=sql_rra_positionGo[4]; ////////////// 포지션 데이터베이스 새행 온 변수 발령 positionGoSeHengOn=0; if (sql_rra_positionGo[0]>hhDocDoinpositionGoAnneBun){ positionGoSeHengOn=1; // 파이썬 포지션 새 포지션 발령 1 부여 hhDocDoinpositionGoAnneBun=sql_rra_positionGo[0]; } Main.MessageList("파이썬 포지션고 새행 온 positionGoSeHengOn=",positionGoSeHengOn); } //////////////////////////// 포지션 진입 if (positionGoSeHengOn==1){ if (position==0){ // 포지션 없을 시 if (hhPythonPositionBalryung==1){ position=1; // 상방 1 hhJnibga=Chart1.GetClose(nData,0); jumunJunCode=Chart1.GetCode(1); Main.MessageList("상방 진입 주문하는"); Account1.OrderBuy(jumunJunCode,jnibSuryang,hhJnibga,2); } else if (hhPythonPositionBalryung==-1){ position=-1; // 하방 -1 hhJnibga=Chart1.GetClose(nData,0); jumunJunCode=Chart1.GetCode(1); Main.MessageList("하방 진입 주문하는"); Account1.OrderSell(jumunJunCode,jnibSuryang,hhJnibga,2); } } else if (position==1){ // 포지션 상방시 if (hhPythonPositionBalryung==10){ position=0; hhJnibga=Chart1.GetClose(nData,0); Main.MessageList("상방 청산 주문하는"); Account1.OrderSell(jumunJunCode,jnibSuryang,hhJnibga,2); } } else if (position==-1){ // 포지션 하방시 if (hhPythonPositionBalryung==-10){ position=0; hhJnibga=Chart1.GetClose(nData,0); Main.MessageList("하방 청산 주문하는"); Account1.OrderBuy(jumunJunCode,jnibSuryang,hhJnibga,2); } } } Main.MessageList("현재 position=",position," hhPythonPositionBalryung=",hhPythonPositionBalryung," jumunJunCode=",jumunJunCode," orderNumVV=",orderNumVV," orderCountVV=",orderCountVV," hhDocDoinpositionGoAnneBun=",hhDocDoinpositionGoAnneBun); } } function Main_OnOrderResponse(OrderResponse) { isNormalVV=OrderResponse.isNormal; orderNumVV=OrderResponse.orderNum; orderCountVV=OrderResponse.orderCount; Account1.SetUnfillOrderNumber(orderNumVV); // 미체결 } function Main_OnNotifyFill(NotifyFill) { jumunJunCode=NotifyFill.code; // 주문 응답시 코드 재부여 } ###################### 데이터베이스 쿼리 ######################### sql="CREATE TABLE yesspot_imsi_oil (ID INT, SDATE INT, STIME BIGINT, C INT, POSITIONBALRYUNG INT, POSITION INT, JANGJUN_GESU INT);" ############# 설명 1. ID 는 행별로 반드시 1증씩 하는 값이 입력돼야 합니다. 2. SDATE, STIME 은 아무 값이 입력돼도 됩니다. 3. POSITIONBALRYUNG 컬럼엔 포지션이 1(매수 진입)이 날시는 1이, 매수 포지션 청산시는 10 이 입력돼야 합니다. 매도 진입시는 -1이 매도 포지션 청산시는 -10 이 입력돼야 합니다. 4. 매수 포지션을 가질 때는 1, 매도 포지션은 -1, 포지션이 없을시는 0 이 입력돼야 합니다. 5. JANGJUN_GESU 는 매번 0 이 입력되면 됩니다. ############# 예시 파이선에서 매수 포지션 진입 명령을 수출할 시. sql="ins*rt into yesspot_imsi_oil values (1, 1234, 1234, 77.02, 1, 1);" 파이선에서 매수 포지션 청산 명령을 수출할 시. sql="ins*rt into yesspot_imsi_oil values (2, 1234, 1234, 77.12, 10, 0);"
시스템
답변 1
프로필 이미지

예스스탁 예스스탁 답변

2021-11-30 14:39:54

안녕하세요 예스스탁입니다. 예 업급하신 내용과 같이 주문응답은 각 전략별로 받게 되지만 체결통보는 전략과 관계없이 모두 수신됩니다. 그러므로 주문응답시 주문번호를 저장하고 수신되는 체결중에 저장한 주문번호와 같은 것으로만 사용하게 구현하셔야 합니다. 일반적으로 식을 작성하실 때 아래와 같은 구조로 작성합니다. 주문함수 동작시 아이디 저장 --> 주문응답 수신시 주문응답의 아이디와 저장한 주문번호와 비교후에 주문번호 저장 --> 체결응답 수신시 저장한 주문번호와 비교해 같은 주문번호 일때를 체크 아래식에서 각 주문함수에 아이디부여된 내용과 주문응답과 체결응답에서 수정된 내용을 참고하시기 바랍니다. var tableEreum="YESSPOT_IMSI_OIL"; // 마리아디비 테이블 이름 - 종목별. // 골드 종목시 "YESSPOT_IMSI_GOLD" var sqlSel*ct="0"; var fieldCountVV=0; var sql_rra_positionGo=new Array(); var jnibSuryang=2; var hhPythonPositionBalryung=0; var positionGoSeHengOn=0; var hhDocDoinpositionGoAnneBun=0; var position=0; var hhJnibga=0; var jumunJunCode="0"; var choKkuenHurum=1; var sql_rra=0; var hhGejwaBun=0; var isNormalVV=0; var orderNumVV=0; var orderCountVV=0; var ID1,ID2,ID3,ID4; var num1,num2,num3,num4; function Main_OnStart() { Main.MessageList("계좌번호=",hhGejwaBun); } ////////////////////////// Chart1==AD_position 2틱인. function Chart1_OnBarAppended(nData) { if (nData==1){ if (choKkuenHurum==1){ sqlSel*ct="count(ANNE) from "; sqlSel*ct+=tableEreum; sqlSel*ct+=";"; // Main.MessageList("sqlSel*ct=",sqlSel*ct); DataBase1.Sel*ct(sqlSel*ct,"AD"); sql_rra=DataBase1.GetFieldValue(0); if (sql_rra>=1){ ////////////// 포지션 데이터베이스 읽기 sqlSel*ct="* from "; sqlSel*ct+=tableEreum; sqlSel*ct+=" ORDER BY ANNE DESC LIMIT 1;"; // Main.MessageList("sqlSel*ct=",sqlSel*ct); DataBase1.Sel*ct(sqlSel*ct,"AD"); fieldCountVV=DataBase1.GetFieldCount(); for (var i=0; i<=fieldCountVV-1; i++){ sql_rra_positionGo[i]=DataBase1.GetFieldValue(i); } if (Math.abs(sql_rra_positionGo[4])==1){ choKkuenHurum=2; // 실시간 포지션 수출이 시작됐으면 흐름 2 영구 부여. } } } ////////////// 포지션 데이터베이스 읽기 if (choKkuenHurum==2){ sqlSel*ct="* from "; sqlSel*ct+=tableEreum; sqlSel*ct+=" ORDER BY ANNE DESC LIMIT 1;"; // Main.MessageList("sqlSel*ct=",sqlSel*ct); DataBase1.Sel*ct(sqlSel*ct,"AD"); fieldCountVV=DataBase1.GetFieldCount(); for (var i=0; i<=fieldCountVV-1; i++){ sql_rra_positionGo[i]=DataBase1.GetFieldValue(i); // 결. 배열에 마지막 행 배치한. } hhPythonPositionBalryung=0; hhPythonPositionBalryung=sql_rra_positionGo[4]; ////////////// 포지션 데이터베이스 새행 온 변수 발령 positionGoSeHengOn=0; if (sql_rra_positionGo[0]>hhDocDoinpositionGoAnneBun){ positionGoSeHengOn=1; // 파이썬 포지션 새 포지션 발령 1 부여 hhDocDoinpositionGoAnneBun=sql_rra_positionGo[0]; } Main.MessageList("파이썬 포지션고 새행 온 positionGoSeHengOn=",positionGoSeHengOn); } //////////////////////////// 포지션 진입 if (positionGoSeHengOn==1){ if (position==0){ // 포지션 없을 시 if (hhPythonPositionBalryung==1){ position=1; // 상방 1 hhJnibga=Chart1.GetClose(nData,0); jumunJunCode=Chart1.GetCode(1); Main.MessageList("상방 진입 주문하는"); ID1 = Account1.OrderBuy(jumunJunCode,jnibSuryang,hhJnibga,2); } else if (hhPythonPositionBalryung==-1){ position=-1; // 하방 -1 hhJnibga=Chart1.GetClose(nData,0); jumunJunCode=Chart1.GetCode(1); Main.MessageList("하방 진입 주문하는"); ID2 = Account1.OrderSell(jumunJunCode,jnibSuryang,hhJnibga,2); } } else if (position==1){ // 포지션 상방시 if (hhPythonPositionBalryung==10){ position=0; hhJnibga=Chart1.GetClose(nData,0); Main.MessageList("상방 청산 주문하는"); ID3 = Account1.OrderSell(jumunJunCode,jnibSuryang,hhJnibga,2); } } else if (position==-1){ // 포지션 하방시 if (hhPythonPositionBalryung==-10){ position=0; hhJnibga=Chart1.GetClose(nData,0); Main.MessageList("하방 청산 주문하는"); ID4 = Account1.OrderBuy(jumunJunCode,jnibSuryang,hhJnibga,2); } } } Main.MessageList("현재 position=",position," hhPythonPositionBalryung=",hhPythonPositionBalryung," jumunJunCode=",jumunJunCode," orderNumVV=",orderNumVV," orderCountVV=",orderCountVV," hhDocDoinpositionGoAnneBun=",hhDocDoinpositionGoAnneBun); } } function Main_OnOrderResponse(OrderResponse) { isNormalVV=OrderResponse.isNormal; orderNumVV=OrderResponse.orderNum; orderCountVV=OrderResponse.orderCount; Account1.SetUnfillOrderNumber(orderNumVV); // 미체결 if (OrderResponse.orderID == ID1) { Main.MessageList("상방 진입 주문 응답"); num1 = OrderResponse.orderNum; } if (OrderResponse.orderID == ID2) { Main.MessageList("하방 진입 주문 응답"); num2 = OrderResponse.orderNum; } if (OrderResponse.orderID == ID3) { Main.MessageList("상방 청산 주문 응답"); num3 = OrderResponse.orderNum; } if (OrderResponse.orderID == ID4) { Main.MessageList("하방 청산 주문 응답"); num4 = OrderResponse.orderNum; } } function Main_OnNotifyFill(NotifyFill) { if (NotifyFill.orderNum == num1) { Main.MessageList("상방 진입 주문 체결"); jumunJunCode=NotifyFill.code; // 주문 응답시 코드 재부여 } if (NotifyFill.orderNum == num2) { Main.MessageList("하방 진입 주문 체결"); jumunJunCode=NotifyFill.code; // 주문 응답시 코드 재부여 } if (NotifyFill.orderNum == num3) { Main.MessageList("상방 청산 주문 체결"); jumunJunCode=NotifyFill.code; // 주문 응답시 코드 재부여 } if (NotifyFill.orderNum == num4) { Main.MessageList("하방 청입 주문 체결"); jumunJunCode=NotifyFill.code; // 주문 응답시 코드 재부여 } } 즐거운 하루되세요 > 로봇짱 님이 쓴 글입니다. > 제목 : 예스스팟의 주문체결통보 객체가 이상합니다. > 안녕하세요. 언제나 친절한 답변에 감사드립니다. 파이선 등의 외부 프로그램에서 데이터베이스에 명령값 등을 수출하고, 그걸 예스스팟의 데이터베이스 객체로 읽어 예스스팟의 매매를 실행하는 전략을 만들었습니다. 그런데 이 전략을 오일, 골드 종목별로 여러개 띄울때 문제가 생깁니다. 종목별로 데이터베이스 테이블 명과 Chart1 의 종목 등을 변경 적용했을때, 주문체결통보객체(Main_OnNotifyFill)에서 반환값이 전략간 구분이 안가고 모든게 global 변수 처리돼 섞이는 것 같습니다. 주문접수응답 객체(Main_OnOrderResponse)는 종목별 전략 간에 섞이지 않는 것같습니다. 그런데 주문체결통보객체는 종목별 전략 간에 섞입니다. 이게 원래 그런건지 봐주십시오. 감사합니다. 첨부파일의 전략을 오일용으로 하나, 데이터베이스 테이블명과 Chart1 객체 설정을 바꿔서 골드용으로 또 하나 이렇게 전략 2개를 만들고 실행했을때 Main.MessageList 출력을 보면 jumunJunCode 가 종목별로 달라야 하는데 같은것으로 설정되는 문제를 첨부 파일 그림에서 볼 수 있습니다. ##################### 예스스팟 전략 ######################### var tableEreum="YESSPOT_IMSI_OIL"; // 마리아디비 테이블 이름 - 종목별. // 골드 종목시 "YESSPOT_IMSI_GOLD" var sqlSel*ct="0"; var fieldCountVV=0; var sql_rra_positionGo=new Array(); var jnibSuryang=2; var hhPythonPositionBalryung=0; var positionGoSeHengOn=0; var hhDocDoinpositionGoAnneBun=0; var position=0; var hhJnibga=0; var jumunJunCode="0"; var choKkuenHurum=1; var sql_rra=0; var hhGejwaBun=0; var isNormalVV=0; var orderNumVV=0; var orderCountVV=0; function Main_OnStart() { Main.MessageList("계좌번호=",hhGejwaBun); } ////////////////////////// Chart1==AD_position 2틱인. function Chart1_OnBarAppended(nData) { if (nData==1){ if (choKkuenHurum==1){ sqlSel*ct="count(ANNE) from "; sqlSel*ct+=tableEreum; sqlSel*ct+=";"; // Main.MessageList("sqlSel*ct=",sqlSel*ct); DataBase1.Sel*ct(sqlSel*ct,"AD"); sql_rra=DataBase1.GetFieldValue(0); if (sql_rra>=1){ ////////////// 포지션 데이터베이스 읽기 sqlSel*ct="* from "; sqlSel*ct+=tableEreum; sqlSel*ct+=" ORDER BY ANNE DESC LIMIT 1;"; // Main.MessageList("sqlSel*ct=",sqlSel*ct); DataBase1.Sel*ct(sqlSel*ct,"AD"); fieldCountVV=DataBase1.GetFieldCount(); for (var i=0; i<=fieldCountVV-1; i++){ sql_rra_positionGo[i]=DataBase1.GetFieldValue(i); } if (Math.abs(sql_rra_positionGo[4])==1){ choKkuenHurum=2; // 실시간 포지션 수출이 시작됐으면 흐름 2 영구 부여. } } } ////////////// 포지션 데이터베이스 읽기 if (choKkuenHurum==2){ sqlSel*ct="* from "; sqlSel*ct+=tableEreum; sqlSel*ct+=" ORDER BY ANNE DESC LIMIT 1;"; // Main.MessageList("sqlSel*ct=",sqlSel*ct); DataBase1.Sel*ct(sqlSel*ct,"AD"); fieldCountVV=DataBase1.GetFieldCount(); for (var i=0; i<=fieldCountVV-1; i++){ sql_rra_positionGo[i]=DataBase1.GetFieldValue(i); // 결. 배열에 마지막 행 배치한. } hhPythonPositionBalryung=0; hhPythonPositionBalryung=sql_rra_positionGo[4]; ////////////// 포지션 데이터베이스 새행 온 변수 발령 positionGoSeHengOn=0; if (sql_rra_positionGo[0]>hhDocDoinpositionGoAnneBun){ positionGoSeHengOn=1; // 파이썬 포지션 새 포지션 발령 1 부여 hhDocDoinpositionGoAnneBun=sql_rra_positionGo[0]; } Main.MessageList("파이썬 포지션고 새행 온 positionGoSeHengOn=",positionGoSeHengOn); } //////////////////////////// 포지션 진입 if (positionGoSeHengOn==1){ if (position==0){ // 포지션 없을 시 if (hhPythonPositionBalryung==1){ position=1; // 상방 1 hhJnibga=Chart1.GetClose(nData,0); jumunJunCode=Chart1.GetCode(1); Main.MessageList("상방 진입 주문하는"); Account1.OrderBuy(jumunJunCode,jnibSuryang,hhJnibga,2); } else if (hhPythonPositionBalryung==-1){ position=-1; // 하방 -1 hhJnibga=Chart1.GetClose(nData,0); jumunJunCode=Chart1.GetCode(1); Main.MessageList("하방 진입 주문하는"); Account1.OrderSell(jumunJunCode,jnibSuryang,hhJnibga,2); } } else if (position==1){ // 포지션 상방시 if (hhPythonPositionBalryung==10){ position=0; hhJnibga=Chart1.GetClose(nData,0); Main.MessageList("상방 청산 주문하는"); Account1.OrderSell(jumunJunCode,jnibSuryang,hhJnibga,2); } } else if (position==-1){ // 포지션 하방시 if (hhPythonPositionBalryung==-10){ position=0; hhJnibga=Chart1.GetClose(nData,0); Main.MessageList("하방 청산 주문하는"); Account1.OrderBuy(jumunJunCode,jnibSuryang,hhJnibga,2); } } } Main.MessageList("현재 position=",position," hhPythonPositionBalryung=",hhPythonPositionBalryung," jumunJunCode=",jumunJunCode," orderNumVV=",orderNumVV," orderCountVV=",orderCountVV," hhDocDoinpositionGoAnneBun=",hhDocDoinpositionGoAnneBun); } } function Main_OnOrderResponse(OrderResponse) { isNormalVV=OrderResponse.isNormal; orderNumVV=OrderResponse.orderNum; orderCountVV=OrderResponse.orderCount; Account1.SetUnfillOrderNumber(orderNumVV); // 미체결 } function Main_OnNotifyFill(NotifyFill) { jumunJunCode=NotifyFill.code; // 주문 응답시 코드 재부여 } ###################### 데이터베이스 쿼리 ######################### sql="CREATE TABLE yesspot_imsi_oil (ID INT, SDATE INT, STIME BIGINT, C INT, POSITIONBALRYUNG INT, POSITION INT, JANGJUN_GESU INT);" ############# 설명 1. ID 는 행별로 반드시 1증씩 하는 값이 입력돼야 합니다. 2. SDATE, STIME 은 아무 값이 입력돼도 됩니다. 3. POSITIONBALRYUNG 컬럼엔 포지션이 1(매수 진입)이 날시는 1이, 매수 포지션 청산시는 10 이 입력돼야 합니다. 매도 진입시는 -1이 매도 포지션 청산시는 -10 이 입력돼야 합니다. 4. 매수 포지션을 가질 때는 1, 매도 포지션은 -1, 포지션이 없을시는 0 이 입력돼야 합니다. 5. JANGJUN_GESU 는 매번 0 이 입력되면 됩니다. ############# 예시 파이선에서 매수 포지션 진입 명령을 수출할 시. sql="ins*rt into yesspot_imsi_oil values (1, 1234, 1234, 77.02, 1, 1);" 파이선에서 매수 포지션 청산 명령을 수출할 시. sql="ins*rt into yesspot_imsi_oil values (2, 1234, 1234, 77.12, 10, 0);"