답변완료
외가격 옵션 매수
1. 검토사항 (아래 수식)
진입조건(등가격의 합과 차)을 만족했을 때
등가콜과 등가풋 중 절대값이 작은 쪽의 등가격 옵션을 매수하는 수식을 작성해보았습니다.
코딩내용이 맞는지 봐주셨으면 합니다.
2. 요청수식
검토요청한 수식과 진입조건은 똑같습니다. 다만 매수는 등가격이 아니고 1행사가 아래인 외가격1 입니다.
등가콜과 등가풋 중 절대값이 작은 쪽의 외가격1 옵션을 매수합니다.
(판단은 등가격의 합과 차로, 액션은 외가격으로)
익절과 손절과 시간청산은 외가격1옵션으로 처리될 수 있도록 부탁드립니다.
포지션 청산은 다른 전략 미결제가 있으니 case by case 청산입니다.
****************************************************************************
var ID, num;
var Entry, Code;
var Xvol;
var HasExited; // 청산 후 재진입을 방지하는 변수
function Main_OnStart() {
Main.MessageList("Start");
Main.SetTimer(1, 5000); // 기존 타이머 설정 (5초 간격)
Main.SetTimer(2, 1000); // 15시 청산을 위한 타이머 설정 (1초 간격)
Entry = 0; // 초기 Entry 값 설정
HasExited = false; // 초기 재진입 가능 상태
}
function Main_OnTimer(nEventID) {
var d = new Date();
var HHMMSS = d.getHours() * 10000 + d.getMinutes() * 100 + d.getSeconds();
if (nEventID == 1) {
if (!HasExited) { // 재진입 방지 조건 추가
if (HHMMSS >= 84500) {
var CallPrice = Option1.GetCurrent(0, 0);
var PutPrice = Option1.GetCurrent(1, 0);
var CallAsk = Option1.GetAsk(Option1.GetATMCallRecent(0), 5);
var PutAsk = Option1.GetAsk(Option1.GetATMPutRecent(0), 5);
var absCall = Math.abs(CallPrice);
var absPut = Math.abs(PutPrice);
var sum = absCall + absPut;
var diff = Math.abs(absCall - absPut);
// 진입 조건
if (Entry == 0 && sum <= 5.00 && diff <= 2.50) {
if (absCall <= absPut) {
Entry = CallPrice;
Code = Option1.GetATMCallRecent(0);
ID = Account1.OrderBuy(Code, 1, CallAsk, 0);
Xvol = 1;
} else {
Entry = PutPrice;
Code = Option1.GetATMPutRecent(0);
ID = Account1.OrderBuy(Code, 1, PutAsk, 0);
Xvol = 1;
}
}
// 익절/손절 조건
if (Entry > 0 && Xvol > 0) {
var currentPrice = Option1.GetCurrent(Code);
if (currentPrice >= Entry + 0.50 || currentPrice <= Entry - 0.50) {
closePosition();
// 청산 후 매수 재진입 방지
HasExited = true; // 청산 후 재진입 방지
Main.KillTimer(1); // 타이머 1 종료
}
}
}
}
}
if (nEventID == 2) {
// 15시 청산 조건
if (HHMMSS >= 151000 && HHMMSS < 151500) { // 15시 15분에 청산
closePosition();
Main.KillTimer(2); // 타이머 2 종료
}
}
}
function closePosition() {
// 포지션 청산
if (Xvol > 0) {
if (Code) {
Account1.OrderSell(Code, Xvol, Option1.GetBid(Code, 5), 0);
}
}
Entry = 0; // Entry 값 초기화
Code = null; // Code 초기화
Xvol = 0; // 수량 초기화
// HasExited = true; // 청산 후 재진입 방지
}
function Main_OnOrderResponse(OrderResponse) {
// 주문 응답 처리
if (OrderResponse.orderID == ID) {
num = OrderResponse.orderNum;
}
}
답변완료
문의드립니다
안녕하세요 계좌잔고 에 있는데 중복매수되는걸 어떻게 해야하는지 문의드립니다
계좌에 잇다면 pass해야하는데 그걸 어떻게 넣어야 하는지 부탁드립니다
var 진입수량 = 2;
var DH, DH1, DL, DL1;
var BEID, BENM, SEID, SENM;
var CC, C1;
var T;
function Main_OnStart() {
Main.MessageList("Start");
T = 0;
}
function Main_OnU*dateMarket(sItemCode, lU*dateID)
{
if (lU*dateID == 20001) {
C1 = CC;
CC = MarketData1.current;
Main.MessageList("Main_OnU*dateMarket", MarketData1.current);
// 시초가 + 10틱 터치
if (T <= 0 &&
C1 > 0 &&
C1 < MarketData1.open + MarketData1.GetTickSize() * 10 &&
CC >= MarketData1.open + MarketData1.GetTickSize() * 10) {
T = 1;
BEID = Account1.OrderBuy(Main.GetOrderCode(MarketData1.code), 진입수량, MarketData1.current, 2);
Main.MessageList("매수 진입 주문: " + MarketData1.current,+ MarkerDatal.open);
}
// 매수 후 손절, 익절, 미체결 셋팅
if (T == 1)
{
// 손절 셋팅
if (MarketData1.current <= MarketData1.open - MarketData1.GetTickSize() * 8) {
청산수량처리(BENM, 진입수량, "매수 포지션 손절");
T = 0; // 초기화
}
// 익절 셋팅
else if (MarketData1.current >= MarketData1.open + MarketData1.GetTickSize() * 130) {
청산수량처리(BENM, 진입수량, "매수 포지션 익절");
T = 0; // 초기화
}
}
// 시초가 - 10틱 터치
if (T >= 0 &&
C1 > MarketData1.open - MarketData1.GetTickSize() * 10 &&
CC <= MarketData1.open - MarketData1.GetTickSize() * 10) {
T = -1;
SEID = Account1.OrderSell(Main.GetOrderCode(MarketData1.code), 진입수량, MarketData1.current, 2);
Main.MessageList("매도 진입 주문: " + MarketData1.current,+ MarkerDatal.open);
}
// 매도 후 손절, 익절, 미체결 셋팅
if (T == -1) {
// 손절 셋팅
if (MarketData1.current >= MarketData1.open + MarketData1.GetTickSize() * 8) {
청산수량처리(SENM, 진입수량, "매도 포지션 손절");
T = 0; // 초기화
}
// 익절 셋팅
else if (MarketData1.current <= MarketData1.open - MarketData1.GetTickSize() * 130) {
청산수량처리(SENM, 진입수량, "매도 포지션 익절");
T = 0; // 초기화
}
}
}
}
function Main_OnOrderResponse(OrderResponse) {
if (OrderResponse.orderID == BEID) {
BENM = OrderResponse.orderNum;
}
if (OrderResponse.orderID == SEID) {
SENM = OrderResponse.orderNum;
}
}
function 청산수량처리(orderNum, 수량, message) {
Account1.SetUnfillOrderNumber(orderNum);
var 청산수량 = 수량 - Account1.Unfill.count;
if (Account1.Unfill.count > 0) {
Account1.OrderCancel(orderNum);
}
if (청산수량 > 0) {
if (T == 1) {
Account1.OrderSell(Main.GetOrderCode(MarketData1.code), 청산수량, MarketData1.current, 2);
Main.MessageList("매수 포지션 청산: " + MarketData1.current + " (" + message + ")");
} else if (T == -1) {
Account1.OrderBuy(Main.GetOrderCode(MarketData1.code), 청산수량, MarketData1.current, 2);
Main.MessageList("매도 포지션 청산: " + MarketData1.current + " (" + message + ")");
}
}
}
이렇게 되있는데 어떤땐 정상적으로 2계약체결되고 어떤땐 4계약이 체결됩니다
답변완료
주문 수량 오류 -1 문의드립니다.
안녕하세요. 수식작성을 했는데 매수할 때 자꾸 매수가 안되고 주문상태에
주문수량오류 (주문수량:-1)
이라고 뜹니다. 뭐가 잘못 작성 된 것 일까요?
저는 NH증권을 쓰고 매수금액을 주문가능금액의 85프로로 설정하였습니다.
차트에서 신호받아서 매수하진 않고, 검색기에 뜨는 종목을 매수합니다.
한번 봐주시길 바라겠습니다. 감사합니다.
var 타이머간격 = 3;
var 손절 = 0.95;
var 익절 = 1.05;
var OrderList = [];
var MKList = [];
var req;
var 매수금;
function Main_OnStart()
{
//1번 타이머, 3초
Main.SetTimer(1, 타이머간격*1000);
// 오늘 매수한 종목 관리 배열 초기화
MKList = [];
//주문가능현금의 85%
매수금 = Account1.GetBalanceETCinfo(16)*0.85;
//스팟 시작시 잔고평가금액
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 >= 90000 && HHMMSS < 151500)
{
// 종목검색 실행
//조건검색명입력
Main.ReqPowerSearch("전략2");
}
if (nEventID == 1)
{
//계좌전체종목수
var num = Account1.GetTheNumberOfBalances();
//9시~15시 15분 사이
if (HHMMSS >= 90000 && HHMMSS < 151500)
{
//보유종목이 1개 이상
if (num >= 1)
{
//1번 타이머 종료
Main.KillTimer(1);
//계좌리스트의 순서대로 인덱스를1씩증가
for (var i = 0; i < num; i++)
{
//잔고를 셋팅
Account1.SetBalance(i);
//수량이 있고 5%수익이거나 5% 손실이면 시장가 매도
if (Account1.Balance.count > 0 &&
(Account1.Balance.current >= Account1.Balance.avgUnitCost*익절 ||
Account1.Balance.current <= Account1.Balance.avgUnitCost*손절))
{
Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1);
}
}
}
}
//15시 15분이후이면
if (HHMMSS >= 151500)
{
//1번 타이머 종료
Main.KillTimer(1);
//미체결 전체 취소
var Unum = Account1.GetTheNumberOfUnfills()
for(var i = 0; i < Unum; i++)
{
Account1.SetUnfillIndex(i);
if (Account1.Unfill.count > 0)
{
Account1.OrderCancel(Account1.Unfill.orderNum);
}
}
//계좌리스트의 순서대로
for (var i = 0; i < num; i++)
{
//잔고를 셋팅
Account1.SetBalance(i);
if (Account1.Balance.count > 0) //잔고에 수량이 0이상이면
{
Account1.OrderSell(Account1.Balance.code,Account1.Balance.count,0,1); //시장가로매도
}
}
}
}
if (nEventID == 2)
{
Main.ReqMarketData(OrderList[req]);
}
}
function Main_OnRcvItemList(aItemList, nCount) //종목검색완료
{
OrderList = [];
if (nCount >= 1) //1종목 이상 검색되면
{
Main.KillTimer(1);
if (MKList.length == 0) //첫검색이면
{
OrderList = aItemList; //해당 종목코드 모두 종목객체요청 리스트에 추가
}
else //첫검색이 아니면
{
for (var a = 0; a < nCount; a++) //기존종목객체요청리스트에 없는 종목만 선별
{
var Add = true;
for (var b = 0; b < BuyList.length; b++)
{
if (aItemList[a] == BuyList[b].code)
{
Add = false;
}
}
if (Add == true && !IsStockInAccount(aItemList[a]))
{
OrderList.push(aItemList[a]);
}
}
}
}
if (OrderList.length == 0) //종목객체 요청할 종목수가 없으면 종목검색을 위해 타이머 다시 동작
{
Main.SetTimer(1, 타이머간격*1000); //1번타이머재동작
}
else //종목객체 요청할 종목수가 1이상이면
{
req = 0; //요청횟수는 초기값 0
Main.ReqMarketData(OrderList[req]); //요청시작
}
}
function Main_OnRcvMarketData(MarketData) //요청한 종목객체가 만들어지먼
{
if (MarketData.code == OrderList[req])
{
MKList.push(MarketData); //MK배열변수에 순서대로 종목객체저장
// 계좌에 같은 종목이 있는지 확인
if (!IsStockInAccount(MarketData.code)) {
// 계좌에 없는 경우에만 매수
Account1.OrderBuy(MarketData.code,Math.floor(매수금/MarketData.Ask(1)),0,1); // 시장가 주문
Main.MessageList(MarketData.code + " 주식을 매수합니다.");
} else {
Main.MessageList( MarketData.code + " 주식은 이미 계좌에 있으므로 매수하지 않습니다.");
}
req = req+1; //요청횟수 1증가
if (req < OrderList.length) //요청횟수가 요청할종목수 미만이면
{
var aa = Main.ReqMarketData(OrderList[req]); //다음종목 요청
if (aa == -1) //종목객체 제한시간에 걸리면(15초에 60개) 15초 쉬고 다시 요청
{
Main.SetTimer(2, 15000);
}
}
else //모두 요청했으면
{
Main.SetTimer(1, 타이머간격*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 반환
}
답변완료
MarketData1 옵션 매수 다운하이, 하이다운하이
MarketData1에 옵션종목 1개를 선정하여 진입하는 수식입니다.
요청수식 1.
시작 084500
우선순위 1 : 가격이 1.00 보다 작아지고
우선순위 2 : 가격이 1.01 보다 커지면
매수 1계약 지정가 상대5호가
익절 1.00, 손절 0.50
1번 진입하고 1번 청산하면 추가 진입금지
endofday 151500
주의점 : 계좌에는 다른 전략의 미결제들도 있으므로 그것들과 구별하여 청산함.
요청수식 2.
시작 084500
우선순위 1 : 가격이 1.50 보다 커지고
우선순위 2 : 가격이 1.00 보다 작아지고
우선순위 3 : 가격이 1.01 보다 커지면
매수 1계약 지정가 상대5호가
익절 1.00, 손절 0.50
1번 진입하고 1번 청산하면 추가 진입금지
endofday 151500
주의점 : 계좌에는 다른 전략의 미결제들도 있으므로 그것들과 구별하여 청산함.
수식 부탁드립니다.
답변완료
예스스팟 자동주문
아래는 현재 제가 쓰고있는 예스스팟입니다.
현재는 같은종목은 매수치 않게 되어 있는데
이것을 계좌에 있더라도 중복매수되게 고치고 싶습니다.
수정부탁드립니다.
======================================================================
var timer5 = 2; //5초
var 매수금 = 100000;
var OrderList = [];
var MKList = [];
var req;
function Main_OnStart()
{
//1번 타이머, 1초
Main.SetTimer(1, timer5*1000);
// 오늘 매수한 종목 관리 배열 초기화
MKList = [];
Main.MessageList("START");
}
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 > 090000 && HHMMSS < 150000)
{
//종목검색 수행
Main.ReqPowerSearch("60분봉 급소2")
}
if (nEventID == 2)
{
Main.ReqMarketData(OrderList[req]);
}
}
function Main_OnRcvItemList(aItemList, nCount)
{
Main.KillTimer(1);
Main.MessageList("Main_OnRcvItemList:",nCount);
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]);
}
}
}
}
if (OrderList.length == 0)
{
Main.SetTimer(1, timer5*1000);
}
else
{
req = 0;
Main.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(매수금/MarketData.Ask(3)),0,1);
// Account1.OrderBuy(MarketData.code,Math.floor(매수금/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]);
if (aa == -1)
{
Main.SetTimer(2, 15000);
}
}
else
{
Main.SetTimer(1, timer5*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 반환
}