커뮤니티

예스스팟 Q&A

답변완료

안녕하세요.

오랜만이네요. 홈피도 바뀌고 단장을 하였네요^^ 다름이 아니라, 아직도 선물신호로 옵션 진입하려면 스팟을 이용해야 하네요. 일전에 부가기능 설정칸에 (선물신호 옵션바로 연결기능) 추가해 주신다고 한 것 같은데. 일년이상된 사항 같은데,늦어도 너무 늦는데요. 작업은 진행중이신지? 언제쯤 가능한지요? 스팟은 영 불편해서요.
프로필 이미지
털보
2013-08-22
1012
글번호 222520
답변완료

수정부탁해요

수고많습니다. 에스스팟Q&A의 577번질문에 대한 예스스탁의 RE에 나와있는 것인데요. 저의 전략으로 신호를 발생시키니 작동은 하는데요. 첨부에 체결중 콜7.0의 매도가 발생하엿는데요. 매매하는 종목들을 공히 2.0이하로, 아울러 현재가+-5호가에 주문이 나갈 수 있게 해 주시면 감사하겠습니다. 추가) 중간에 간혹 신호가 없는데 주문이 나가는 경우가 있고요(테스트전략은 bids&asks를 사용(10분) 첫봉매도,2번째봉매수,3번째봉 매도후 15:00;00에 청산) 15:00:05에 접수오류([check_order_ok] 주문수량을 확인하세요란 메세지가 나오고요. 풋만 청산됩니다. 이건 아마 call240 7.0에 매도한 것을 청산하다 보니,시스템은 콜2개매도,풋1개매도가 잇는걸로 인지하는 루틴이 있나봅니다... bids & asks로 신호가 나올때 아래의 시스템이 2.0이하의 콜과 풋으로 잘 돌아가는지 테스트해 봐 주시면 고맙겠습니다요. 차트에 매수신호 발생하면 2.0 이하 중 가장 큰 풋옵션 매도하고 매도신호 발생하면 2.0 이하 중 가장 큰 콜옵션 매도합니다. 매수청산신호 발생시 신호상 수익이면 풋옵션 매도청산하고 손실이면 행사가의 반대 콜옵션을 매도합니다. 매도청산신호 발생시 신호상 수익이면 콜옵션 매도청산하고 손실이면 행사가의 반대 픗옵션을 매도합니다. 각 청산후 양매도상태이면 손실 100만원 발생하면 모두 청산합니다. 기본틀이므로 테스트 충분히 하신후에 수정보완해 사용하시기 바랍니다. 옵션객체 차트객체 : 객체명 chart1 --> 속송에서 차트아이디 차트와 동일하게 부여 계좌객체 : 객체명 Account1 --> 속성에서 계좌지정 var Start; var UNum; var LNum; var CallCode; var CallPrice; var PutCode; var PutPrice; var CC; var PP; var CallOrderCode; var PutOrderCode; var CallOrderCodeR; var PutOrderCodeR; var BuyEntryPrice; var SellEntryPrice; var BuyStep; var SellStep; function Main_OnStart() { Start = 0; BuyStep = 0; SellStep = 0; Main.SetTimer(1, 10000); } function Chart1_OnRiseSignal(Signal) { UNum = Option.uppersATM; LNum = Option.lowersATM; CallCode = new Array(UNum+LNum+1); PutCode = new Array(UNum+LNum+1); CallPrice = new Array(UNum+LNum+1); PutPrice = new Array(UNum+LNum+1); for (var i = -LNum; i <= UNum; i++) { if (Option.GetCurrent(0, i) <= 2.0) { CallPrice[i+LNum] = Option.GetCurrent(0, i); CallCode[i+LNum] = Option.GetATMCallRecent(i); } else { CallPrice[i+LNum] = -1; CallCode[i+LNum] = -1; } } for (var ii = -UNum; ii <= LNum; ii++) { if (Option.GetCurrent(1, ii) <= 2.0) { PutPrice[ii+UNum] = Option.GetCurrent(1, ii); PutCode[ii+UNum] = Option.GetATMPutRecent(ii); } else { PutPrice[ii+UNum] = -1; PutCode[ii+UNum] = -1; } } //buy신호 발생시 if (Signal.signalKind == 1) { Start = 1; PP = -1; PutOrderCode = -1; PutOrderCodeR = -1; for (var iiii = -UNum; iiii <= LNum; iiii++) { if (PutPrice[iiii+UNum] > PP) { PP = PutPrice[iiii+UNum]; PutOrderCode = PutCode[iiii+UNum]; //2.0이하 중 가장 큰 풋옵션의 종목코드 PutOrderCodeR = Option.GetATMCallRecent(-iiii); //반대 콜옵션의 종목코드 } } if (PP > 0) { Account1.OrderSell(PutOrderCode, 1, 0, 1); BuyEntryPrice = Signal.price; //매수신호시 신호가격 BuyStep = 1; Main.MessageLog("차트신호종류:"+Signal.signalKind+" /종목코드:"+PutOrderCode+" /START:"+Start); } else { Main.MessageLog("차트신호종류:"+Signal.signalKind+" /종목코드: 지정한 가격대 종목이 없음"+" /START:"+Start); } } //exitlong신호 발생시 if ( Start == 1 && Signal.signalKind == 2) { Start = 0; if (PP > 0 && Signal.price > BuyEntryPrice) //차트신호 수익 { Account1.OrderBuy(PutOrderCode, 1, 0, 1); BuyStep = 0; Main.MessageLog("차트신호종류: 수익:"+Signal.signalKind+" /종목코드:"+PutOrderCode+" /START:"+Start); } if (PP > 0 && Signal.price < BuyEntryPrice)//차트신호 손실 { Account1.OrderSell(PutOrderCodeR, 1, 0, 1); BuyStep = 2; Main.MessageLog("차트신호종류 : 손실:"+Signal.signalKind+" /종목코드:"+PutOrderCodeR+" /START:"+Start); } } //sell신호 발생시 if (Signal.signalKind == 3) { Start = -1; CC = -1; CallOrderCode = -1; CallOrderCodeR = -1; for (var iii = -LNum; iii <= UNum; iii++) { if (CallPrice[iii+LNum] > CC) { CC = CallPrice[iii+LNum]; CallOrderCode = CallCode[iii+LNum]; //2.0이하 중 가장큰 콜종목의 종목코드 CallOrderCodeR = Option.GetATMPutRecent(-iii) //반대 풋옵션의 종목코드 } } if (CC > 0) { Account1.OrderSell(CallOrderCode, 1, 0, 1); SellStep = 1; Main.MessageLog("차트신호종류:"+Signal.signalKind+" /종목코드:"+CallOrderCode+" /START:"+Start); } else { Main.MessageLog("차트신호종류:"+Signal.signalKind+" /종목코드: 지정한 가격대 종목이 없음"+" /START:"+Start); } } // Exitshort신호 발생시 if (Start == -1 && Signal.signalKind == 4) { Start = 0; if (CC > 0 && Signal.price < SellEntryPrice)//차트신호수익 { Account1.OrderBuy(CallOrderCode, 1, 0, 1); SellStep = 0; Main.MessageLog("차트신호종류: 수익 : "+Signal.signalKind+" /종목코드:"+CallOrderCode+" /START:"+Start); } if (CC > 0 && Signal.price > SellEntryPrice)//차트신호손실 { Account1.OrderSell(CallOrderCodeR, 1, 0, 1); SellStep = 2; Main.MessageLog("차트신호종류: 손"+Signal.signalKind+" /종목코드:"+CallOrderCodeR+" /START:"+Start); } } } function Main_OnTimer(nEventID) { var d = new Date(); var HHMMDD = d.getHours()*10000+d.getMinutes()*100+d.getSeconds(); if (BuyStep == 2) { var TotalPL = 0; Account1.SetBalanceItem(PutOrderCode, 1); TotalPL = TotalPL + (Account1.Balance.avgUnitCost-Account1.Balance.current)*Account1.Balance.count*500000; Account1.SetBalanceItem(PutOrderCodeR, 1); TotalPL = TotalPL + (Account1.Balance.avgUnitCost-Account1.Balance.current)*Account1.Balance.count*500000; if (TotalPL <= -1000000) { Account1.SetBalanceItem(PutOrderCode, 1); Account1.OrderBuy(Account1.Balance.code, Account1.Balance.count,0,1); Account1.SetBalanceItem(PutOrderCodeR, 1); Account1.OrderBuy(Account1.Balance.code, Account1.Balance.count,0,1); BuyStep = 0; } } if (SellStep == 2) { var TotalPL = 0; Account1.SetBalanceItem(CallOrderCode, 1); TotalPL = TotalPL + (Account1.Balance.avgUnitCost-Account1.Balance.current)*Account1.Balance.count*500000; Account1.SetBalanceItem(CallOrderCodeR, 1); TotalPL = TotalPL + (Account1.Balance.avgUnitCost-Account1.Balance.current)*Account1.Balance.count*500000; if (TotalPL <= -1000000) { SellStep = 0; Account1.SetBalanceItem(CallOrderCode, 1); Account1.OrderBuy(Account1.Balance.code, Account1.Balance.count,0,1); Account1.SetBalanceItem(CallOrderCodeR, 1); Account1.OrderBuy(Account1.Balance.code, Account1.Balance.count,0,1); } } //15시 분에 종목청산 if (nEventID == 1 && HHMMDD >= 150000) { Main.KillTimer(1); if (BuyStep == 2) { Account1.SetBalanceItem(PutOrderCode, 1); Account1.OrderBuy(Account1.Balance.code, Account1.Balance.count,0,1); Account1.SetBalanceItem(PutOrderCodeR, 1); Account1.OrderBuy(Account1.Balance.code, Account1.Balance.count,0,1); BuyStep = 0; } if (SellStep == 2) { Account1.SetBalanceItem(CallOrderCode, 1); Account1.OrderBuy(Account1.Balance.code, Account1.Balance.count,0,1); Account1.SetBalanceItem(CallOrderCodeR, 1); Account1.OrderBuy(Account1.Balance.code, Account1.Balance.count,0,1); SellStep = 0; } } }
프로필 이미지
먼지의추억
2013-08-21
1111
글번호 222519
답변완료

문의드립니다

스팟에서 참조하는 챠트객체의 현재 매수포지션,매도포지션을 알 수 있는 함수는 무엇인가요? 가령 챠트 A에서 진입시그널이 발생해였으나 그 시점에서, 참조하는 다른 챠트 B의 조건을 만족하지 못해 진입을 못한경우 추후에 챠트 B의 진입 조건이 충족되면 과거에 발생한 챠트 A의 진입시그널의 포지션이 살아 있다면, B의 진입 조건이 충족되는 순간 진입하고 싶습니다.
프로필 이미지
재령
2013-08-20
1070
글번호 222518
답변완료

주식 보유종목 손절

안녕하세요. 주식 보유 종목중 5% 손실나면 손절을 시킬 수 있나요? 가능하다면 트레일링스탑 예제로 알려주시면 감사하겠습니다. ^^
프로필 이미지
오토
2013-08-21
1188
글번호 222516
답변완료

Excel로부터 데이터 불러와서 배열에 저장

예스스팟에서 Excel에 저장한 값을 읽어와서 배열에 저장하는 로직을 부탁드리고자 합니다. Excel에는 하나의 시트에 두 컬럼에 데이터를 넣을텐데, 첫번째 칼럼은 숫자이고 두번째 칼럼은 문자열입니다. 열의 개수는 유동적이며 스팟에서 Excel 데이터를 불러올 때 현재 열 개수를 확인해야 합니다.
프로필 이미지
곰탈
2013-08-19
1217
글번호 222514
답변완료

PlaySound

아래와 같이 특정 이벤트 발생할 때 wav 파일 실행하도록 하였는데요. 소리가 나질 않습니다. 파일 경로는 이상이 없고요... 다른 곳에서 소리를 나도록 activate해야 하는 것이 있는지요? Main.PlaySound("C:₩예스트레이더40₩Spot₩Alerted5.wav");
프로필 이미지
곰탈
2013-08-19
1181
글번호 222513
답변완료

문의 드립니다.

예스스팟에서, 차트에서의 진입명 및 청산명을 하나 하나 명확히 구분해서 그 것의 미체결주문, 미결제잔고 등을 처리하려고 합니다. (Signal.name을 이용해서...) 그런데, 보통 Buy, ExitLong, Sell, ExitShort 등에서는, 제가 그 진입 내지 청산명을 정해 주면 되니까 아무 어려움이 없는데, SetStopㅇㅇㅇㅇㅇ과 같이, 강제청산함수들에 의해 청산된 경우는, 청산명을 제가 부여할 수가 없으니, 그런 경우에는 어떻게 해야 스팟에서 강제청산 하나 하나를 구분하여 처리할 수 있을지요? 1. 시스템 성능 보고서에서 볼 수 있는 바와 같이, ExitLong_#?, ExitShort_#? 형태로 청산명이 나타나게 될 때, 그 숫자 ?의 결정 규칙이 있는지요? (즉, a. 단순한 리버스의 경우에 새로운 진입과 동시에 이루어지는 Exit에서, 매수청산되는 경우, b. 단순한 리버스의 경우에 새로운 진입과 동시에 이루어지는 Exit에서, 매도청산되는 경우, c. SetStopLoss에 의해 매수청산되는 경우, d. SetStopLoss에 의해 매도청산되는 경우, e. SetStopTrailing에 의해 매수청산되는 경우, f. SetStopTrailing에 의해 매도청산되는 경우, 이런 여섯가지의 각기 다른 청산들에 대해 ExitLong_#?, ExitShort_#?의 숫자 ?가 정해지는 어떤 명확한 규칙이 있는지요?) (지금 시스템 성능 보고서를 보면, 여러 번 청산이 이루어졌으나, 제가 부여한 청산명 이외의 청산명은 오직 ExitShort_#0 ExitLong_#2 ExitShort_#4 ExitLong_#6 이 네가지만 있습니다. 1, 3, 5, 7, 9 등의 숫자도 없고요... 강제청산은 한 번도 없었던 것으로 보입니다. [강제청산함수들을 다 주석처리해도 결과가 같습니다] 이 네가지 이름이 생기는, 어떤 규칙 같은 것이 있는 것인지요?) 2. 일목요연하게, 또 정확히 규칙적으로 이런 강제청산함수의 청산명을 이용할 수 있는 방법이 없다면, 제가 스스로 이 강제청산함수를 쓰지 말고, AtStop, AtLimit 등을 이용하여 강제청산함수의 내용을 ExitLong, ExitShort로 실행시켜 주는 것 외에는 다른 방법이 없는 것인지가 궁금합니다. 3. 궁극적으로, 강제청산함수들(SetStopㅇㅇㅇㅇㅇ...) 속에서, 파라메터를 추가해서, 청산명을 지정할 수 있도록, 함수들을 수정해 주시면 가장 좋겠다고 생각이 됩니다. 이렇게 함수를 수정(청산명 파라메터 추가)해 주실 수 있으실지요? (이 것은 아마도 스팥 사용자가 늘어날수록 이 강제청산함수 청산명 파라메터 수요가 늘어 날 걸로 예상이 되기 때문에, 필요한 조치가 아닐까 생각됩니다. 스팟이 주문 관리에 가장 강점이 있다고 볼 때, 강제청산함수에 의한 청산신호도 결국 주문신호로서 Signal.kind 2 아니면 4가 될텐데, 이 것에 따른 스팟 주문(OrderBuy와 OrderSell)이, Signal.kind 1 내지 3에 의한 스팟 주문과 실질적으로 구분하기 어려운 상황이라면, 전체적인 스팟 소스를 짜는데 있어서 어려움이 있을 수 있겠고, 그 것은 결국 기존의 Buy, ExitLong, Sell, ExitShort 함수에 따른 진입신호 구분에 더해서, 여러 가지 강제청산함수들에 따른 각각 상이한 청산신호들도 다 이름을 통해 구분할 수 있게 함으로써 주문, 잔고 관리를 좀 더 개선할 수 있게 되지 않을까 생각이 됩니다) 4. 만일 위 3번과 같이 YesLanguage 쪽을 변경하시는 것이 불가능하다면, YesSpot쪽에서, 가령 SetStopLoss로 매수청산되는 경우를 Signal.kind == 5로 하고 SetStopLoss로 매도청산되는 경우를 Signal.kind == 6으로 하고, SetStopTrailing로 매수청산되는 경우를 Signal.kind == 7로 하고 SetStopTrailing로 매도청산되는 경우를 Signal.kind == 8로 하고 ... 하는 식으로 SetStopㅇㅇㅇㅇㅇ... 함수들의 신호 구분을 Signal.kind에서 나타내 줄 수 있게 YesSpot을 변경하실 수는 없을지요? (예스랭귀지 속에서, 각각의 강제청산함수들의 이름을 달리 할 수 있게만 되면 그 게 가장 좋겠다고 생각됩니다. 그 게 아니라면, 적어도 이렇게 신호타입만이라도 예스스팟에서 구분해서 사용할 수 있게 되어도 어느 정도는 지금보다는 좀 더 세분해서 주문을 관리할 수 있게 될 것 같습니다) 감사합니다.
프로필 이미지
즐겁게
2013-08-19
1196
글번호 222511
답변완료

종목객체에 대해 문의드립니다.

1.종목객체에서 "H"나 "L"이 있는데 이것은 무엇을 의미하는 건지 궁금하네요. MarketData1.H 또는 MarketData1.L 이 무엇을 가지고 오는지 알고 싶읍니다. 캔들챠트를 전제로 하지 않고 가격데이터를 가지고 오는 것으로 알고 있는데 어떻게 고가나 저가가 존재 할 수 있는 지 알고 싶읍니다. 2.스팟전략을 운영할 때 디버깅 창에 "NaN"이라는 에러메세지로 추정되는 메세지가 계속해서 뜹니다. 이런 에러 메세지가 뜸에도 불구하고 스팟 전략 전혀 문제가 없이 잘 돌아가고 있읍니다. "NaN"이라는 메세지는 어떤 의미인지 궁금합니다. 늘 답변으로 많은 도움을 주셔서 감사합니다. 수고하세요
프로필 이미지
santus
2013-08-14
1098
글번호 222508
답변완료

문의 드립니다.

항상 친절하신 답변에 깊이 감사드립니다. "스팟으로 이동평균값을 구해서 이용할 수 있는 방법"을 공부하고 있습니다. 제가 알고자 하는 것은, 굳이 차트에서의 이평선 값을 이용하는 것이 아니라, "스팟 자체에서 이평선 값을 구해서 이용하려면 어떻게 하면 되는가" 하는 것입니다. 아래의 3가지 질문을 올리오니, 알려 주시면 대단히 감사하겠습니다. 1. 현재, 차트에서 본다면, 200 이평선 위에 가격이 존재하는데, 이럴 때는 매수포지션만 보유하고, 매도포지션은 생성이 안 되게 하고 싶습니다. 만일 "현재 가격이 200 이평선 위" 수준인데, 잔고에 롱포지션도 없는데 미체결 매도주문이 있다면 그 것이 몇 개든 다 취소하고 싶고, 잔고에 롱포지션이 가령 두 계약이 있다 그러면, 그 것을 매수청산할 수 있도록, 두 계약 매도할 수 있는 미체결 매도주문만 남기고 나머지 미체결 매도주문은 다 취소해 버리고 싶습니다. 가능한 대로 "차트 쪽의 신세를 지지 않고 최대한 스팥 소스를 이용해서, 가격이 200 이동평균값 이상일 때는 미체결 매도주문을 취소"하려면 어떻게 소스를 짜는 것이 좋을지요? 2. 차트에서 매수진입신호가 왔을 때에, "스팟 식으로만 100 이평 값을 구해서 신호가격과 스팟에서의 이평가격을 비교해서 신호가격이 이평가격보다 높아야 스팟으로 매수주문"을 내고, 차트에서 매도진입신호가 왔을 때, "스팟에서 계산한 100 이평값보다 그 매도진입신호가격이 낮아야 스팟으로 매도주문"을 내는 식으로 하려면 어떻게 하면 좋을지요? ((예를 들자면, 차트에서 Buy신호가 발생했을 때에, 그 때 진입신호가격이 가령 245 라고 했을 때, 그 값이 100 이평선 값 위에 있으면, 가령 100 이평 값이 238이라면, 이 때는 실제로 매수주문을 내고, 만일 100 이평선이 그 진입신호가격보다 위라면, 가령 100 이평 값이 251이라면, 이 때는 매수신호를 무시하고 하는 것과 같은 식을, 최대한 차트에서 보내 주는 신호[정보]보다는, 스팥 자체로 해결하는 방법을 알고 싶습니다)) 3. 가급적이면 차트에의 의존을 줄이고 스팟으로 처리하는 비중을 높여 보려고 하는데, 아주 간단한 예로, 차트를 이용하지 않고, "스팟으로만, 가령 50 이평선과 200 이평 골든크로스에 매수, 데드크로스에 매도" 하는 수식을 부탁드리고 싶습니다. 대단히 감사합니다.
프로필 이미지
즐겁게
2013-08-15
1107
글번호 222507
답변완료

예스스탁을 통해 데이터를 불러오고 있는데 문제가 있습니다.

먼저 MarketData 객체의 시가를 불러오는 MarketData.open 값이 시가가 0으로 출력됩니다. 사용된 종목은 kospi200 종합과 연결선물지수 입니다. 또 Option 객체에서 GetOpenByCode()를 통해 시가를 불러오는 데 같은 증상입니다. 테스트는 9시00분 부터 0.1초 주기로 갱신 프로세스를 돌렸지만 0이란 값만 계속 리턴되었습니다. 연결선물지수는 시가를 제대로 받아왔습니다. kospi200 종합과 옵션 최근월물 전체가 다 받지 못하였습니다. 수정 부탁드립니다.
프로필 이미지
절대시스템
2013-08-13
1026
글번호 222504