답변완료
도와주세요
1.예스랭귀지로 수식작성하여 검증 완료했습니다.(2가지 수식)
예스스팟으로 편집기에 코딩좀 도와 주십시요
*첫번째수식
INPUT : 기간(120);
VAR : A(0),A1(0),A2(0),A3(0),선행1(0),선행2(0);
A=MA(C,기간);
A1=EmA(C,기간);
A2=WMA(C,기간);
A3=(H+L+C)/3;
선행1=(highest(high,9)+lowest(low,9)+highest(high,26)+lowest(low,26))/4;
선행2=(highest(high,52)+lowest(low,52))/2;
IF A[1]>A1[1] && A[1]>A2[1] && A1[1]>A2[1] && CrossUP(A3,A2) && C>O && 선행1[25]<=C && 선행2[25]<=C TheN
Find(1);
*두번째수식
INPUT : 기간1(150),기간2(200),상승률(1.25);
VAR : A(0),B(0),A1(0);
A=EmA(C,기간1);
B=EmA(C,기간2);
A1=Lowest(L,260)[1]*상승률;
IF((A[2]>A[1]&&A>A[1]) OR (B[2]>B[1]&&B>B[1]))&&
(CrossUP(C,A) OR CrossUP(C,B))&&A1>=C TheN
Find(1);
입니다.
부탁드립니다^^
답변완료
매도수식 청산내용 추가
1. 게시판 답변글에다 시간청산내용을 추가해보았습니다. 내용이 맞는지 검토해주십시요.
2. 익절과 손절 내용 추가해주십시요.
- 익절 내용 : 잔고가 +50,000원 되면 모두 청산
- 손절 내용 : 잔고가 -50,000원 되면 모두 청산
3. 한세트 진입하고 청산하면 그 다음 거래는 안한다는 내용을 추가해주십시요.
항상 고맙습니다.
*****************************************************************************
function Main_OnStart()
{
Main.SetTimer(1, 5000); // 5초마다 타이머 이벤트 발생
Main.SetTimer(2, 60000); // 1분마다 타이머 이벤트 발생
}
function Main_OnTimer(nEventID)
{
var d = new Date();
var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds();
if (nEventID == 1) {
if (HHMMSS >= 084600) // 오전 8시 46분
{
Main.KillTimer(1);
C1 = ""; CD1 = -1;
C2 = ""; CD2 = -1;
P1 = ""; PD1 = -1;
P2 = ""; PD2 = -1;
for (var i = -Option1.lowersATM; i <= Option1.uppersATM; i++)
{
if (Option1.GetCurrent(0, i) <= 1.0)
{
if (CD1 == -1 || (CD1 > 0 && 1.0 - Option1.GetCurrent(0, i) < CD1))
{
CD1 = 1.0 - Option1.GetCurrent(0, i);
C1 = Option1.GetATMCallRecent(i);
}
}
if (Option1.GetCurrent(0, i) <= 0.5)
{
if (CD2 == -1 || (CD2 > 0 && 0.5 - Option1.GetCurrent(0, i) < CD2))
{
CD2 = 0.5 - Option1.GetCurrent(0, i);
C2 = Option1.GetATMCallRecent(i);
}
}
if (Option1.GetCurrent(1, -i) <= 1.2)
{
if (PD1 == -1 || (PD1 > 0 && 1.2 - Option1.GetCurrent(1, -i) < PD1))
{
PD1 = 1.2 - Option1.GetCurrent(1, -i);
P1 = Option1.GetATMPutRecent(-i);
}
}
if (Option1.GetCurrent(1, -i) <= 0.5)
{
if (PD2 == -1 || (PD2 > 0 && 0.5 - Option1.GetCurrent(1, -i) < PD2))
{
PD2 = 0.5 - Option1.GetCurrent(1, -i);
P2 = Option1.GetATMPutRecent(-i);
}
}
}
if (C1 != "" && C2 != "")
{
Account1.OrderSell(C1, 1, Option1.GetBid(C1, 5), 0);
Account1.OrderSell(C2, 1, Option1.GetBid(C2, 5), 0);
}
if (P1 != "" && P2 != "")
{
Account1.OrderSell(P1, 1, Option1.GetBid(P1, 5), 0);
Account1.OrderSell(P2, 1, Option1.GetBid(P2, 5), 0);
}
}
}
if (nEventID == 2) {
// 15시 청산 조건
if (HHMMSS >= 150000 && HHMMSS < 150100) { // 15시 1분에 청산
closePositions();
Main.KillTimer(2); // 타이머 2 종료
}
}
}
function closePositions() {
// Call 포지션 청산
if (C1 != "" && C2 != "") {
Account1.OrderBuy(C1, 1, Option1.GetAsk(C1, 5), 0);
Account1.OrderBuy(C2, 1, Option1.GetAsk(C2, 5), 0);
}
// Put 포지션 청산
if (P1 != "" && P2 != "") {
Account1.OrderBuy(P1, 1, Option1.GetAsk(P1, 5), 0);
Account1.OrderBuy(P2, 1, Option1.GetAsk(P2, 5), 0);
}
}
답변완료
수식 추가 수정 부탁드립니다.
안녕하세요.
매번 예스스탁의 커뮤니티를 이용하여 많은 내용들을 배우고 또 질문에 성의 껏 답변해 주심에 감사드립니다.
질문하나 드립니다.
예스스팟에서 아래 스팟 수식을 이용하여 예스랭귀지로 만든 수식으로 파워종목을 만들어 자동 매수하고, 미리 일괄적으로 정해 둔 적절한 수익률과 손절률을 'STOP 주문설정' 창에 셋팅하여 자동 매도를 하고 있는데, 모든 종목의 스텐스가 달라 일정비율의 매도는 비효율적이어서 익과 손절을 적절히 못하고 있습니다.
그래서 파워종목으로 편집한 매도 조건을 포함하여 보유 종목을 대상으로 자동 매도를 하거나, 아니면 간단한 지표 몇가지를 스팟 수식에 추가 설정하여 자동 매도가 되게 만들고 싶습니다.
1. 매수한 보유종목 중 매도조건에 충족되면 자동 매도가 되도록 정하고 싶습니다.
예) 예스랭귀지로 매수[파일명 : MY_BB030]와 매도[파일명 : MY_SS123]의 조건을 편집해서 파워종목 식으로 자동 매수 매도되게 스팟수식을 만든다.
2. 몇 가지 지표들로 매도조건을 정하여 스팟 수식에 포함하여 자동매도 되도록 한다.
예) 특정 주기와 D값을 이용하여 그 볼린저밴드의 상단선을 상향돌파 또는 하향돌파하는 시점에 자동 매도 또는 종가가 5이평 하향돌파 시 자동 매도, 엔벨 상한선이 2일 연속 하락하고 종가가 시가보다 하락하면 자동 매도 등의 간단한 조건을 스팟 수식에 포함하여 자동매도한다.
3. 예스랭귀지와 파워종목 검색식으로 매도 조건의 수식을 만들어서 예스 스팟과 연동되게 하는 스팟에서 추가되는 부분에 대해서도 설명해주시면 고맙겠습니다.
4. 계좌별 보유종목에 적용하여 사용하고자 합니다. 위 1)번과 2)번 조건이 만족되면 자동 매도하는 것입니다.
부탁드립니다.
현재 사용하고 있는 예스스팟 매수매도 수식
--------------------
var M_Buy = 50000000;//종목당 1회 매수금액
var OPEN_T = 90000;
var CLOSE_T = 120000;
var SearchName = "MY_BB030"; //PowerSearch Name
var timer = 10; //매수 매도 초(시간) 간격
var Earning_Rate = 1.12; //계좌평가금액이 스팟시작시 평가금액대비 12% 이상이면 전종목 전량매도
var Trailing_Stop = 0.8; // 전량 손절
var Earning_Sale = 1.12; // 전량 익절
var OrderList = [];
var MKList = [];
var req;
function Main_OnStart()
{
//1번 타이머, "timer" 초
Main.SetTimer(1, timer*1000);
// 오늘 매수한 종목 관리 배열 초기화
MKList = [];
//스팟 시작시 잔고평가금액
V1 = Account1.GetBalanceETCinfo(100);
}
function Main_OnTimer(nEventID)
{
var d = new Date();
YYYYMMDD = d.getFullYear()*10000+(d.getMonth()+1)*100+d.getDate();
HHMMSS = d.getHours()*10000+d.getMinutes()*100+d.getSeconds();
if (nEventID == 1 && HHMMSS >= OPEN_T && HHMMSS < CLOSE_T)
{
//종목검색 수행
Main.ReqPowerSearch(SearchName)
Main.MessageList("ReqPowerSearch1");
}
if (nEventID == 1)
{
//계좌보유종수
var num = Account1.GetTheNumberOfBalances();
//9시~15시 15분 사이
if (HHMMSS >= 90000 && HHMMSS < 151500)
{
//보유종목이 1개 이상
if (num >= 1)
{
//계좌평가금액이 스팟시작시 평가금액대비 12% 이상이면 전종목 전량매도
if (Account1.GetBalanceETCinfo(100) >= V1*Earning_Rate)
{
//1번 타이머 종료
Main.KillTimer(1);
//계좌리스트의 순서대로
for (var i = 0; i < num; i++)
{
//잔고를 셋팅
Account1.SetBalance(i);
//수량이 있고 Earning_Rate(60%)수익이거나 손실이면 시장가 매도
if (Account1.Balance.count > 0)
{
Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1);
}
}
}
else //아니면 개별종목 30% Earning_Sale, -20% Trailing_Stop 체크
{
//계좌리스트의 순서대로
for (var i = 0; i < num; i++)
{
//잔고를 셋팅
Account1.SetBalance(i);
//수량이 있고 "Earning_Sale"수익이거나 "Trailing_Stop" 손실이면 시장가 매도
if (Account1.Balance.count > 0 &&
(Account1.Balance.current >= Account1.Balance.avgUnitCost*Earning_Sale ||
Account1.Balance.current <= Account1.Balance.avgUnitCost*Trailing_Stop))
{
Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1);
}
}
}
}
}
/* 15시 15분 이후이면 계좌의 모든 잔량 시장가 매도 관련 시스템[시작]
15시 15분 이후이면 계좌의 모든 잔량 시장가 매도 관련 시스템[시작]
if (HHMMSS >= 151500)
{
//1번 타이머 종료
Main.KillTimer(1);
//계좌리스트의 순서대로
for (var i = 0; i < num; i++)
{
//잔고를 셋팅
Account1.SetBalance(i);
//수량이 있고 5%수익이거나 5% 손실이면 시장가 매도
if (Account1.Balance.count > 0)
{
Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1);
}
}
}
15시 15분 이후이면 계좌의 모든 잔량 시장가 매도 관련 시스템[시작]
15시 15분 이후이면 계좌의 모든 잔량 시장가 매도 관련 시스템[시작]
*/
}
if (nEventID == 2)
{
Main.ReqMarketData(OrderList[req]);
Main.MessageList("ReqMarketData:",OrderList[req]); ;
}
}
function Main_OnRcvItemList(aItemList, nCount)
{
Main.KillTimer(1);
Main.MessageList("aItemList:",aItemList);
OrderList = [];
if (nCount >= 1)
{
if (MKList.length == 0)
{
OrderList = aItemList;
}
else
{
for (var a = 0; a < nCount; a++)
{
var Add = true;
for (var b = 0; b < MKList.length; b++)
{
if (aItemList[a] == MKList[b].code)
{
Add = false;
}
}
if (Add == true && !IsStockInAccount(aItemList[a]))
{
OrderList.push(aItemList[a]);
}
}
}
}
Main.MessageList("OrderList:",OrderList);
if (OrderList.length == 0)
{
Main.SetTimer(1, timer*1000);
}
else
{
req = 0;
Main.ReqMarketData(OrderList[req]);
Main.MessageList("ReqMarketData:",OrderList[req]); ;
}
}
function Main_OnRcvMarketData(MarketData)
{
if (MarketData.code == OrderList[req])
{
MKList.push(MarketData);
// 계좌에 같은 종목이 있는지 확인
if (!IsStockInAccount(MarketData.code)) {
// 계좌에 없는 경우에만 매수
// Account1.OrderBuy(MarketData.code,1,0,1);
Account1.OrderBuy(MarketData.code,Math.floor(M_Buy/MarketData.Ask(1)),0,1);
// Account1.OrderBuy(MarketData.code,Math.floor(M_Buy/MarketData.Ask(1)),MarketData.Ask(1),0);
//지정가로 주문하고자 하시면 주문함수 내용을 위와 같이 변경하시면 됩니다.
Main.MessageList(MarketData.code + " 주식을 매수합니다.");
} else {
Main.MessageList( MarketData.code + " 주식은 이미 계좌에 있으므로 매수하지 않습니다.");
}
req = req+1;
if (req < OrderList.length)
{
var aa = Main.ReqMarketData(OrderList[req]);
Main.MessageList("ReqMarketData:",OrderList[req]); ;
if (aa == -1)
{
Main.SetTimer(2, 15000);
}
}
else
{
Main.SetTimer(1, timer*1000);
}
}
}
function IsStockInAccount(stockCode) {
// 계좌에 해당 종목이 있는지 확인하는 함수
var numberOfBalances = Account1.GetTheNumberOfBalances();
for (var i = 0; i < numberOfBalances; i++) {
Account1.SetBalance(i);
if (stockCode == Account1.Balance.code) {
return true; // 계좌에 같은 종목이 있으면 true 반환
}
}
return false; // 계좌에 같은 종목이 없으면 false 반환
}
감사합니다.