English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
시장 수학: 수익, 손실 및 비용

시장 수학: 수익, 손실 및 비용

MetaTrader 5 | 17 5월 2024, 13:34
565 0
Evgeniy Ilin
Evgeniy Ilin

콘텐츠

소개

저는 EA를 개발하면서 손익을 계산할 때 특정 값이 무엇을 의미하는지에 대해서 신경을 쓴 적이 없었습니다. EA를 생성할 때는 이 부분을 자세히 살펴볼 필요가 없습니다. 실제로 MQL5와 심지어 MQL4에도 계산을 수행하는 데 필요한 모든 기능이 포함되어 있어 이 모든 값을 파악해야 할 필요가 없었습니다. 하지만 일정 시간이 지나고 어느 정도 경험이 쌓이면 필연적으로 의문이 생기기 시작합니다. 결국 이전에는 대수롭지 않게 여겼던 세부 사항들이 눈에 들어오기 시작합니다. 조금만 생각해보면 우리는 무엇인지도 모르고 EA를 사용한 격이라는 것을 알 수 있습니다. 인터넷에서 찾은 이 문제에 대한 모든 데이터는 부족하고 구조화되지 않은 것으로 밝혀졌습니다. 그래서 제가 직접 구조화하기로 결정했습니다. 여러분이 이 기사를 읽은 후에는 완전하고 작동하는 수학적 모델을 얻게 될 뿐만 아니라 주문과 관련된 모든 것을 이해하고 올바르게 계산하는 방법을 배우게 됩니다.

주문 수익 또는 손실 계산 방정식

효율적인 트레이딩 시스템을 개발하려면 우선 각각의 주문의 손익이 어떻게 계산되는지 이해해야 합니다. 우리 모두는 자금 관리 시스템을 운용하기 위해 어떻게든 수익과 손실을 계산할 수 있습니다. 누군가는 직관적으로, 누군가는 대략적인 추정으로 운용하지만 거의 모든 EA에는 필요한 모든 것을 계산하는 데 필요한 기능이 있습니다.

EA를 개발하는 것은 우리로 하여금 우리의 생각을 발전시키고 우리가 무엇을 어떻게 계산하고 있는 것인지 이해를 돕습니다. 이는 값진 경험입니다. 이제 본론으로 들어가 보겠습니다. 주문의 수익이 어떻게 계산되는지에 대해서 알아보는 것부터 시작하는 것이 좋습니다. 개인적으로 저는 수익 계산이 본질적으로 매우 복잡하다는 것을 알고 있었습니다. 그러나 어쨌든 수익 계산은 몇 가지 간단한 사항을 기반으로 합니다. 여러분의 이해를 돕기 위해 스프레드, 스왑, 수수료가 존재하지 않는다고 가정해 보겠습니다. 제가 보기에 많은 사람들이 처음에는 이들의 수치를 고려하지 않는거 같습니다. 물론 MQL5 언어에는 OrderCalcProfit과 같이 내장되어 제공되는 함수가 있지만 저는 이 글에서는 모든 사람이 계산되는 내용과 방법을 이해할 수 있도록 기본 사항을 살펴보도록 하겠습니다. 이러한 세심함을 다루는 것에 대해 다소 당황스러운 분들도 계시겠지만 스프레드, 수수료 및 스왑과 같은 매개 변수에 주의를 기울이지 않는 것은 많은 트레이더가 저지르는 치명적인 실수입니다. 이들 각각의 값은 고유한 방식으로 수익 또는 손실에 영향을 미칩니다. 저는 계산에서 모든 것을 고려하고 그러한 작은 것들이 어떻게 여러분에게 도움이 될 수 있는지 보여 드리겠습니다. 스프레드, 수수료 및 스왑을 제외한 주문의 손익입니다:

  • PrBuy = Lot * TickValue * [ ( PE - PS)/Point ] - 매수 주문에 대한 수익
  • PrSell = Lot * TickValue * [ ( PS - PE)/Point ] - 매도 주문에 대한 수익
  • point - 선택한 심볼의 최소 가격 변동 가능 금액
  • TickValue - 가격이 "1" 포인트 이동했을 때 수익이 발생한 포지션의 수익 값
  • PE - 거래 청산 가격(bid)
  • PS - 거래 진입 가격(bid)

MQL5의 Point 및 TickValue와 같은 값은 사전 정의된 변수 수준에서 정의되거나 SymbolInfoDouble 유형 함수의 반환 값 형태로 내장된 기능 내에서 사용할 수 있습니다. 저는 어떤 식으로든 MQL5에 대한 내용을 정기적으로 다룰 것입니다. 왜냐하면 MQL5 또는 특정 기능이 어떻게 만들어졌는지 분석하는 것만으로도 많은 문제의 핵심을 파악할 수 있기 때문입니다.

이제 이 방정식에 대해 조금 더 알아보도록 하겠습니다. 매수 주문은 Ask 가격에 매도 주문은 Bid 가격에 개설됩니다. 따라서 매수 주문은 Bid 가격에 청산되고 매도 주문은 Ask 가격에 청산됩니다. 이를 고려하여 방정식을 다시 작성해 보겠습니다:

  • PrBuy = Lot * TickValue * [ ( Bid2 - Ask1)/Point ] - 매수 주문의 수익
  • PrSell = Lot * TickValue * [ ( Bid1 - Ask2)/Point ] - 매도 주문에 대한 수익
  • Bid1 - 매도 거래 진입 가격
  • Ask1 - 매수 거래 진입 가격
  • Bid2 - 매수 거래 청산 가격
  • Ask2 - 매도 거래 청산 가격

아래 사양의 일부에는 나중에 우리가 필요한 대부분의 데이터가 포함되어 있습니다:

필수 데이터

이는 계산에 필요한 데이터의 일부일 뿐입니다. 나머지 데이터는 내장된 다양한 MQL5 함수를 사용하여 얻을 수 있습니다. USDJPY를 예로 들어보겠습니다. 사실 우리가 코드를 작성하는 데 사양이 필요한 것은 아니지만 이 데이터가 어디에 표시되는지를 이해하면 매우 유용할 수 있습니다.

이번에는 수수료에 대해 살펴보겠습니다. 주문당 수수료는 다양한 방법으로 계산할 수 있지만 어떤 방법이든 결국 거래하는 랏의 백분율로 귀결됩니다. 거래 수수료를 계산하는 다른 방법도 있지만 여기서는 고려하지 않겠습니다. 어차피 우리가 사용할 것은 아니기 때문입니다. 커미션을 계산하는 두 가지 가능한 시나리오를 고려해 보겠습니다. 제 생각으로는 이들 시나리오 정도면 충분하다고 생각합니다. 만약 스왑을 기준으로 하면 스왑을 사용한 예시를 통해 수수료 계산에 적용할 수 있는 또 다른 일반적인 계산 방법인 포인트로 계산하는 방법을 사용할 수도 있습니다.

결과적으로 우리에게는 겉보기에는 서로 다른 두 가지 방법이 있습니다. 그러나 앞으로 살펴볼 것처럼 이러한 방법은 스프레드를 포함하여 동일한 "수수료"의 적용을 인식하는 편리한 형태일 뿐입니다. 다음은 수수료 계산을 위한 두 가지 공식입니다:

  1. Comission = Lot * TickValue * ComissionPoints
  2. Comission = Lot * ContractSize * BidAlpha * ComissionPercent/100

여기에서는 거래 서버에서 정보를 수신하는 내장된 기능으로서의 수준에서 MQL5에 구현된 새로운 값 "ContractSize"를 볼 수 있습니다. 이 값은 가장 중요한 값 중 하나이며 프로그래머의 계산을 단순화하기 위해 자동으로 적용 되는 형태이긴 하지만 모든 손익 계산에 존재합니다. 프로그래머의 입장에서는 이러한 단순화의 타당성을 쉽게 알 수 있습니다. 하지만 현재 우리의 목표는 이 모든 것을 이해하는 것입니다. 이 글의 마지막 부분에서 여러분은 이것이 필요한 이유를 확인할 수 있습니다. 또한 저는 BidAlpha라는 변수를 추가로 도입했습니다. 아래에서 그 의미도 설명하겠습니다. 심볼 사양에 지정된 다음 값들도 표시됩니다:

  • ComissionPoints - 포인트 단위 수수료
  • ComissionPercent - 계약 규모의 백분율로 계산된 수수료
기준 통화 단위의 스왑을 잔고 단위의 스왑으로 변환하려면 BidAlpha 승수가 필요합니다. 여기에는 네 가지의 시나리오가 있습니다:
  1. BidAlpha = 1(기준통화가 입금 통화와 동일한 경우)
  2. BidAlpha = Bid(선택한 심볼의)
  3. BidAlpha = Bid(해당 환율 중 선택한 심볼의 기본 통화는 전환 심볼의 기본 통화와 동일하고 두 번째 통화는 입금 통화와 동일)
  4. BidAlpha = 1/Ask (해당 환율 중, 선택한 심볼의 기준통화가 전환 심볼의 두 번째 통화와 동일하고 기준통화가 입금 통화와 동일한 경우)

실제로 USDCHF 쌍에 계약 사이즈를 적용하면 선택한 쌍의 기본 통화가 USD라는 것이 분명합니다. USD로 예치금이 있다고 가정하면 전환 통화는 USDUSD가 되고 그에 따라 환율은 항상 1이 됩니다. 두 번째 경우는 훨씬 더 간단합니다. 전환율이기도 한 EURUSD 쌍이 있다고 가정하면 해당 Bid 가격이 필요한 값입니다. 세 번째 경우는 다음과 같을 것입니다. 통화가 EURNZD라고 가정해 보겠습니다. 그런 다음 EUR와 USD의 전환율을 찾아야 합니다. EURUSD 환율과 이 환율의 Bid 가격이 필요합니다. 네 번째 경우에는 상황이 조금 더 복잡해집니다. CHFJPY를 선택했다고 가정해 보겠습니다. Forex에는 CHFUSD 환율이 없으므로 전환 통화쌍은 USDCHF라는 것이 분명합니다. 물론 우리가 나름대로 합성 심볼을 만들어 CHFUSD로 작업할 수도 있습니다. 이 경우 우리는 이전 사례를 사용할 수 있습니다. 그러나 실제로는 이 심볼을 뒤집기만 하면 현재 '불편한' 요율의 '1/Ask'와 같은 요율이 됩니다. 사실 우리는 가상의 심볼을 만듭니다. 스왑도 마찬가지입니다. 다른 의문들도 몇 가지 있습니다. 예를 들어 전환기 통화에서 어떤 환율을 사용해야 할까요(Bid, Ask 혹은 Mid)? 이 문제는 현재의 접근 방식으로는 해결할 수 없습니다. 그러나 우리는 이 과정에서 점차 올바른 접근 방식을 마련할 것입니다. 이제 우리가 만들 개선의 방향을 대략적으로나마 정의해 보겠습니다. 이를 위해서는 스프레드, 스왑 및 수수료와 같은 모든 "일종의 과세" 옵션을 고려하여 손익 방정식의 대략적인 첫 번째 버전을 작성해야 합니다.

스왑을 계산할 때도 비슷한 방정식을 사용합니다:

  1. Swap = Lot * TickValue * SwapPoints * SwapCount(StartTime,EndTime)
  2. Swap = Lot * ContractSize * BidAlpha * SwapPercent/100 * SwapCount(StartTime,EndTime)

이 방정식들은 실제로 서로 매우 유사합니다. 유일한 차이점은 특정 승수가 SwapCount 함수의 형태로 여기에 표시되었다는 것입니다. 저에게 용어 사용의 자유를 조금만 허용해 주셨으면 합니다. 스왑은 즉시 청구되지 않고 주문 진입 및 청산 시간에 따라 크기가 달라지기 때문에 저는 이를 "함수"라고 부릅니다. 물론 대략적인 근사치로 우리는 승수 없이도 다음과 같이 작성할 수 있습니다:

  • SimpleCount = MathFloor( (EndTime -StartTime) / ( 24 * 60 * 60 ) )

EndTime과 StartTime이 'datetime' 유형이라고 가정하면 그 차이는 주문 진입 시점과 청산 시점 사이의 시간(초)과 같습니다. 스왑은 하루에 한 번 청구됩니다. 그러므로 여러분은 이 값을 하루의 초 수로 나누기만 하면 됩니다. 이렇게 하면 우리는 스왑 포지션이 어떻게 평가될 수 있는지에 대한 첫 번째 아이디어를 얻을 수 있습니다. 물론 이 방정식은 완벽하지는 않지만 이 함수가 어떤 종류의 함수이고 무엇을 반환하는지에 대한 해답을 제공합니다. 또한 이 방정식은 스왑이 어떻게 계산되는지 (적어도 대략적으로)를 보여줄 수 있습니다. 이 방정식은 포지션을 보유하는 동안 발생한 스왑 횟수를 반환합니다. 마찬가지로 종목 사양의 수수료는 계산 방법을 강제적으로 표시하는 스왑에 대해 가능한 두 가지의 값 중 하나가 됩니다:

  • SwapPoints - 포인트로 단일 포지션 롤오버를 위한 스왑
  • SwapPercent - 단일 포지션 롤오버를 위한 스왑을 계약 규모의 %로 표시합니다.

수수료의 경우 방정식이 더 간단하고 설명이 필요하지 않습니다. 스왑의 경우 모든 것이 훨씬 더 복잡합니다. 그러나 우리는 이러한 단순화의 미묘한 차이와 뉘앙스를 나중에 다룰 것입니다. 먼저 수수료와 스왑을 제외한 손익 방정식을 보다 일관된 형태로 만들어 보겠습니다:

  • PrBuy = Lot * TickValue * [ ( Bid2 - (Bid1+S1*Point))/Point ] - 매수 주문의 수익
  • PrSell = Lot * TickValue * [ ( Bid1 - (Bid2+S2*Point))/Point ] - 매도 주문의 수익
  • S1 - 매수 주문 진입 시 스프레드
  • S2 - 매도 주문 청산 시 스프레드

Ask에는 스프레드와 Bid가 모두 포함됩니다. 스프레드로 인해 발생한 주문의 손익을 분리하여 별도의 합계로 만들어 보겠습니다:

  • PrBuy = Lot * TickValue * [ ( Bid2 – Bid1)/Point ] + ( - Lot * TickValue * S1 ) - 매수 주문의 수익
  • PrSell = Lot * TickValue * [ ( Bid1 – Bid2)/Point ] + ( - Lot * TickValue * S2 ) - 매도 주문의 수익

두 방정식 모두에서 브로커가 부과하는 부분인 특정 수열이 분리되어 있음을 알 수 있습니다. 물론 이것이 전체 금액은 아니지만 적어도 이제 우리가 얻는 것과 브로커가 가져가는 것을 더 명확하게 볼 수 있습니다. 첫 번째 경우 스프레드에 대한 "부과"는 "매수" 포지션에 진입할 때와 두 번째 경우 "매도" 포지션을 청산할 때의 스프레드의 값에 따라 달라집니다. 우리는 항상 진입 시점에 스프레드 형태로 정확히 수익의 일부를 브로커에게 제공하는 것으로 나타났습니다. 실제로 외환 트레이딩을 자세히 살펴보면 매수 포지션을 개시하고 매도 포지션을 청산하는 것은 방정식에 의해 확인되었듯이 같은 행동이라는 것이 분명해집니다. 이 경우

  • S1 - 포지션 진입 시 포인트 스프레드
  • S2 - 포지션 청산 시 포인트 스프레드

이 값은 종합 시세 창에서 볼 수 있는 값과 정확히 일치합니다. 해당 값에 해당하는 내장 SymbolInfoInteger MQL5 함수는 정확히 동일한 값을 반환합니다. 입력 값은 MQL5 도움말에서 찾을 수 있습니다. 이 경우 제 임무는 이러한 방정식을 모든 EA 또는 기타 유용한 MQL5 코드로 즉시 코딩할 수 있도록 MQL5 언어에 연결된 편리한 수학적 계산 모델을 만드는 것입니다. 이제 스왑과 커미션 모두에 해당하는 내용은 다음과 같습니다:

  • SpreadBuy = - Lot * TickValue * S1
  • SpreadSell = - Lot * TickValue * S2

진입과 청산 시 스프레드

일반적으로 스프레드는 매수 시점에 계산되지만 이것이 잘못된 이유를 보여드리겠습니다. 시장 조사를 많이 해본 결과 가장 예측 가능한 포인트 혹은 가격 변동 시점은 '0:00'으로 나타났습니다. 이것은 하루에서 다른 하루로 넘어가는 전환점입니다. 이 점을 주의 깊게 관찰하면 모든 통화쌍에서 거의 동일한 현상, 즉 값이 하락을 향해 점프하는 것을 볼 수 있습니다. 이는 이 시점에서 스프레드가 증가하기 때문에 발생합니다. 점프 뒤에는 동일한 롤백이 이어집니다. 스프레드란 무엇일까요? 스프레드는 Bid와 Ask 사이의 차이입니다. 일반적으로 이러한 격차는 시장의 심도에 따른 결과로 여겨집니다. 시장 심도에 리밋 주문이 많아지면 스프레드는 0이 되는 경향이 있으며 플레이어가 시장을 떠나면 스프레드가 증가하게 됩니다. 이를 시장 심도의 분열이라고 부를 수 있습니다. 언뜻 보기에도 Bid가 여기서 중요한 것은 아니라고 말할 수 있습니다. Ask와 Bid는 근본적으로 동일한 것으로 밝혀졌습니다. 예를 들어 'EURUSD'에서 USDEUR 미러 상품을 구성할 수 있고 Bid가 Ask로, Ask가에서 Bid로 바뀐다고 생각하면 쉽게 이해할 수 있습니다. 간단히 말해 시장 심도를 뒤집는 것입니다.

'Ask' 라인은 일반적으로 차트에 표시되지 않지만 있는 것이 유용할 때도 있습니다:

bid & ask

보시다시피 차트 기간이 늘어남에 따라 Ask와 Bid가 합쳐지기 시작합니다. 이러한 사실로 인해 두 라인을 모두 표시하는 단말기는 없지만 제 개인적으로는 이것이 필요하다고 생각합니다. 그러나 이러한 값의 존재 여부와 그 차이를 아는 것은 EA에서 사용할 수 있는 것들이기 때문에 그다지 중요하지 않습니다. 여기에 Mid를 그리지는 않았지만 이 선이 정확히 Bid와 Ask의 중간이라는 것은 모두가 알고 있을 것입니다. 분명히 높은 기간 동안 이러한 값의 차이는 실제로 역할을하지 않으며 Ask의 존재를 고려할 필요조차없는 것처럼 보입니다. 그러나 실제로는 필요한 것입니다. 이러한 세부 사항은 매우 중요합니다.

이를 염두에 두고 이제 우리는 이러한 변화의 과정에서 시장 심도의 중간은 변하지 않는다고 확실하게 말할 수 있습니다. 이 값은 다음과 같이 계산할 수 있습니다:

  • Mid = (Ask + Bid) / 2

이러한 표현을 고려하고 마지막 방정식을 사용하면 우리는 다음과 같은 사실을 알 수 있습니다:

  • Bid = Mid * 2 – Ask
  • Ask = Mid * 2 - Bid

다음:

  • Bid = Mid * 2 – (Bid + S*Point) = Mid – (S*Point)/2
  • Ask = Mid * 2 – (Ask - S*Point) = Mid + (S*Point)/2

이제 이러한 식을 주문의 손익을 계산하는 원래의 방정식으로 대체할 수 있습니다. 저는 여러부이 이전에 이해하지 못했던 것을 보여드리고 싶었기 때문에 이러한 식이 정확히 이해되도록 하는 것이 중요했습니다. 브로커가 청구하는 금액은 실제로 매수 포인트에만 의존하는 것이 아니라 진입 및 청산 포인트와 모든 포지션에 따라 달라집니다. 여기에 새로이 확장적 정의를 고려할 경우 방정식이 어떻게 변하는지 살펴봅시다. 우리는 다음을 확인할 수 있습니다:

  • PrBuy = Lot * TickValue * [ ( (Mid2 - (S2*Point)/2) - (Mid1 + (S1*Point)/2) ) )/Point ]
  • PrSell = Lot * TickValue * [ ((Mid1 - (S1*Point)/2) - (Mid2 + (S2*Point)/2) ) )/Point ]

적절한 변환을 수행하면 우리는 다음과 같은 결과를 확인할 수 있습니다:

  • PrBuy = Lot * TickValue * [ (Mid2 – Mid1)/Point ] - Lot * TickValue * ( S1/2 + S2/2 )
  • PrSell = Lot * TickValue * [ (Mid1 – Mid2)/Point ] - Lot * TickValue * (S1/2 + S2/2 )

이를 고려하면:

  • Bid1 = Mid1 - (S1*Point)/2
  • Bid2 = Mid2 - (S2*Point)/2
  • Ask1 = Mid1 + (S1*Point)/2
  • Ask2 = Mid2 + (S2*Point)/2

그리고 이 점을 명심하세요:

  • Mid1 - 포지션 진입 시 시장 심도 중간값
  • Mid2 - 포지션 청산 시 시장 심도의 중간값

편의상 스프레드로 인한 손실을 정의하는 음의 합계를 다음과 같이 표시합니다:

  • Spread = -Lot * TickValue * ( (S1*Point)/2 + (S2*Point)/2)

따라서 예를 들어 스프레드, 수수료 및 스왑을 제외한 손익을 나타내는 합계가 다음과 같이 표시됩니다:

  • ProfitIdealBuy = Lot * TickValue * [ (Mid2 - Mid1)/Point ]
  • ProfitIdealSell = Lot * TickValue * [ (Mid1 - Mid2)/Point ]

이제 우리는 스프레드, 수수료, 스왑으로 인한 모든 손실을 고려하여 방정식을 작성할 수 있습니다. 식의 프로토타입부터 시작하겠습니다. 여기서는 스프레드만 고려한 최신 주문 손익 방정식을 기준으로 삼겠습니다:

  • TotalProfitBuy = ProfitIdealBuy + (Spread + Comission + Swap)
  • TotalProfitSell= ProfitIdealSell + (Spread + Comission + Swap)

제가 이 방정식을 맨 처음에 썼어야 했지만 여기서는 이 표현이 더 적절하다고 생각합니다. 모호한 TickValue가 거의 모든 곳에 존재한다는 것을 알 수 있습니다. 주요 질문은 어떻게 TickValue가 계산되는지 그리고 어떻게 하나의 동일한 값을 다른 시점의 계산에 사용할 수 있는지입니다. 타임포인트는 포지션의 진입과 청산을 의미합니다. 이 값은 본질적으로 동적이며 각 거래 심볼마다 다르다는 것을 여러분들 모두 이해하고 있을 것입니다. 이 값을 구성 요소로 분해하지 않으면 우리는 '타깃'이 멀수록 더 큰 오류가 발생하게 됩니다. 즉 이렇게 구한 방정식은 근사치일 뿐입니다. 반면에 이러한 단점이 없는 절대적으로 정확한 방정식이 있습니다. 위에서 얻은 비율이 그 한도가 됩니다. 한도 자체는 다음과 같이 표현될 수 있습니다:

  • Lim[ dP -> 0 ] ( PrBuy(Mid1, Mid1+dP... ) ) = TotalProfitBuy(Mid1, Mid1+dP...)
  • Lim[ dP -> 0 ] ( PrSell(Mid1, Mid1+dP... ) ) = TotalProfitSEll(Mid1, Mid1+dP...)
  • Mid1+dP = Mid2 - 새로운 가격은 이전 가격에서 0이 되려는 델타 경향을 더한 값입니다.
  • TotalProfitBuy = TotalProfitBuy(P1,P2… ) - 결정된 대로 손익은 중간 값 및 기타 여러 값의 함수입니다.
  • TotalProfitSell = TotalProfitSell(P1,P2… ) - 유사

일반적으로 상황을 전반적으로 이해하기 위한 동등한 한도는 여러 가지 방법으로 작성될 수 있습니다. 곱할 필요가 없습니다. 우리의 경우 명확성을 위해 하나면 충분합니다.

우리는 몇 가지 방정식을 얻었고 이 방정식들이 작동하기도 하지만 적용 가능성의 한계는 매우 조건부적 입니다. 다음으로 우리는 이러한 근사 방정식을 수반하는 초기 방정식을 구하는 작업을 진행할 것입니다. 만약 수익 또는 손실의 구성 요소를 알지 못하면 우리는 이러한 방정식을 결코 이해할 수 없습니다. 결과적으로 이러한 방정식은 손익 계산을 위한 가장 정확한 비율을 찾는 데 도움이 될 뿐만 아니라 시장 프로세스의 불균형을 찾아내어 수익을 창출하는 데도 도움이 됩니다.

주문의 손익을 계산하는 가장 정확한 방법

이러한 방정식을 구축하는 방법을 이해하려면 기본 즉 매수 및 매도가 무엇인지 다시 살펴볼 필요가 있습니다. 하지만 먼저 매수는 실제로 돈을 상품으로 교환하는 것을 의미한다는 점을 기억하는 것이 중요합니다. 우리는 다른 통화를 상품으로 볼 수 있습니다. 왜냐하면 통화는 특정 상품을 소유할 수 있는 능력을 상징하기 때문입니다. 그러면 매도는 두 번째 통화를 첫 번째 통화로 교환하는 역방향 과정이라는 것이 분명합니다. 그러나 매수와 매도는 곧 동등한 행위입니다. 한 통화를 다른 통화로 교환하면 어떤 통화를 주고 어떤 통화를 받느냐만 다를 뿐입니다.

이러한 이해와 관련한 정보를 검색하는 동안 저는 이해할 수 없었던 이상한 이론들을 만나게 되었는데 근거 없는 이론들이 많았습니다. 저는 다양한 기술 자료를 연구한 경험이 많은 기술자로서 아주 간단한 두 가지 진실을 발견했습니다. 만약 여러분이 자료가 명확하지 않아 보이고 의문이 드는 경우:

  • 저자가 스스로 완전히 이해하지 못하기 때문에 저자는 그 반대편을 설득하기 위해 최선을 다합니다 (일반적으로 반 논리적 진술을 사용합니다.
  • 불필요한 정보를 숨기기 위해 세부 정보는 의도적으로 생략됩니다.

아래 이미지는 아이디어를 더욱 발전시켜 이해하기 쉽게 설명합니다. 두 가지 유형의 시장가 주문의 진입 및 청산을 보여줍니다:

매수 및 매도

이제 스프레드 섹션과 현재의 섹션이 더 명확해질 것 같습니다. 일반적으로 이 이미지는 이 기사의 전체와 관련이 있지만 특히 이 블록에서 가장 유용합니다.

물론 저는 이들 계산식이 전문적인 문서에 있는 정확한 계산이라고 확신하지만 이 정보를 찾는 것이 여러분만의 정의에서 무엇이 잘못 되었는지를 스스로 추측하는 것보다 더 어렵다는 것은 분명합니다. 이 규칙에 따르면 예를 들어 EURUSD를 매수할 때는 EUR를 매수하고 USD를 매도합니다. 이를 표현해 보겠습니다:

  • EUR = Lot * ContractSize
  • USD = - Ask1 * Lot * ContractSize = - (Bid1 + S1*Point) * Lot * ContractSize

이 경우 매수할 때 기본 통화는 양의 수량이고 두 번째 통화는 음의 수량인 것으로 나타났습니다. 이것이 완전히 말도 안 된다고 생각하는 사람은 저뿐만이 아닐 것입니다. 저는 고민 끝에 비율은 정확하지만 전체적으로는 다소 직관적이지 않은 방식으로 표시된다는 결론에 도달했습니다. 이를 다음과 같이 변경해 보겠습니다... EUR를 매수하려면 다른 통화인 USD가 필요하므로 대차대조표에서 가져오거나 브로커에게서 빌리거나 혹은 두 가지 방법을 모두 사용해야 합니다. 즉 먼저 일부 공유 스토리지에서 USD를 빌려서 가져옵니다. 이 함수는 다음과 같이 보입니다:

  • USD1 = Ask1 * Lot * ContractSize = (Bid1 + S1*Point) * Lot * ContractSize - 이것이 우리가 빌린 금액입니다.
  • EUR1 = Lot * ContractSize - 우리가 구매 시점의 Ask 호가 환율로 차입한 자금으로 구매한 금액입니다.

음수 값은 나중에 표시됩니다. 사실 음수 값이 현재로서는 여기에 있을 수 없습니다. 포지션을 청산하면 음수 값이 표시됩니다. 따라서 포지션이 열려 있으면 포지션은 닫혀져야 합니다. 동일한 랏을 사용하여 매도 작업을 수행해야 합니다. 표준 사항을 준수하는 경우

  • EUR2 = Lot * ContractSize
  • USD2 = Bid2 * Lot * ContractSize

우리는 이미 EUR을 매도하고 USD를 매수한 것으로 나타났습니다. 환전과 관련하여 우리는 빌린 자금을 우리 자신에게서 받은 유로를 다시 빌린 통화로 바꾼다는 사실을 알수 있습니다. 받은 자금에서 빌린 자금을 빼면 이익 또는 손실이 발생합니다:

  • Profit_EUR = EUR1 - EUR2 = 0
  • Profit_USD = USD2 – USD1 = Bid2 * Lot * ContractSize - (Bid1 + S1*Point) * Lot * ContractSize = Lot * ContractSize * ( Bid2 – Bid1 – S1*Point)

EUR은 사라지고 USD만 남아 있게 됩니다. 입금이 USD로 이루어진 경우 결과 통화가 동일하므로 입금 통화로 변환할 필요가 없습니다. 이 방정식은 우리가 처음에 기초로 삼았던 방정식과 매우 유사하지만 수수료와 스왑이 별도로 고려된다는 점이 다릅니다. 이제 이 식을 조금 바꿔 보겠습니다:

  • Profit_USD = Lot * (ContractSize*Point) * [ ( Bid2 – Bid1 – S1*Point) / Point ]

여기서 오른쪽을 Point로 나누고 곱하면 원래의 방정식을 얻을 수 있습니다. 거래 방향에 관계없이 우리가 매도 및 매수를 동시에 한다는 기존의 규칙 체계를 사용하면 우리는 동일한 방정식을 얻을 수 있습니다. 이 경우 빌린 금액에는 빚이 있음을 상징하는 마이너스 기호가 표시되고 구매한 금액에는 더하기 기호가 남게 됩니다. 이러한 시스템에서는 무엇을 어디에서 무엇으로 변경할지 고려할 필요가 없습니다. 이 접근 방식을 사용하여 동일한 작업을 수행해 보겠습니다:

  • EUR1 = Lot * ContractSize
  • USD1 = - Ask1 * Lot * ContractSize = - (Bid1 + S1*Point) * Lot * ContractSize

이것은 매수 입니다. 조치 1.

  • EUR2 = - Lot * ContractSize
  • USD2 = Bid1 * Lot * ContractSize

이것은 매도입니다. 조치 2.

또한 무엇을 어떻게 빼야 할지 우리는 생각할 필요가 없는 것이기 때문에 모든 것이 단순화됩니다. 모든 EUR와 모든 USD를 개별적으로 합산하면 됩니다. 어쨌든 기본 통화는 사라지고 두 번째 통화만 남습니다. 이제 방정식이 이전 방정식과 동일한지 확인해 보겠습니다:

  • Profit_EUR = EUR1 + EUR2 = 0
  • Profit_USD = USD1 + USD2 = - (Bid1 + S1*Point) * Lot * ContractSize + Bid2 * Lot * ContractSize = Lot * ContractSize * ( Bid2 – Bid1 – S1*Point)

모든 심볼의 수익은 기본 통화가 아닌 두 번째 통화로만 인식되며 기본 통화는 전체 개장-종가 주기 동안 항상 사라지는 것으로 나타났습니다. 당연히 모든 것이 매도를 위해 미러링됩니다. 계산을 완료하기 위해 이 모든 것을 작성해 보겠습니다. 이제 EURUSD를 매도한 다음 "매수"를 실행하여 포지션을 청산합니다:

  • EUR1 = - Lot * ContractSize
  • USD1 = Bid1 * Lot * ContractSize

이것은 매도입니다. 조치 1.

  • EUR2 = Lot * ContractSize
  • USD2 = - (Bid2 + S2*Point) * Lot * ContractSize

이것은 매수, 조치 2입니다.

이제 모든 값을 같은 방식으로 추가해 보겠습니다:

  • Profit_EUR = EUR1 + EUR2 = 0
  • Profit_USD = USD1 + USD2 = Bid1 * Lot * ContractSize - (Bid2 + S2*Point) * Lot * ContractSize = Lot * ContractSize * ( Bid1 – Bid2 – S2*Point)

보시다시피 이 방정식은 Bid1과 Bid2가 바뀐다는 점만 다릅니다. 물론 포지션의 청산 시점이 매수 시점이므로 청산 시점의 스프레드가 부과됩니다. 지금까지는 모든 것이 원래의 방정식과 같습니다. 이제 우리가 적어도 심볼의 두 번째 통화(기본 통화가 아닌)가 입금 통화와 일치하는 경우 TickValue가 무엇인지 알 수 있다는 점도 주목할 가치가 있습니다. 이 값의 방정식을 작성해 보겠습니다:

  • TickValue = ContractSize * Point

그러나 이 값은 수익의 통화가 예치금의 통화와 동일한 심볼에만 적합합니다. 하지만 예를 들어 AUDNZD와 같은 교차 환율을 사용한다면 어떨까요? 여기서 가장 중요한 것은 심볼이 아니라 이 값이 항상 입금 통화와 관련하여 계산되고 거래 서버에서 수신된다는 사실입니다. 그러나 우리가 이 방정식을 교차 환율과 관련하여 사용하면 물론 작동을 하기는하지만 예금 통화가 아닌 심볼의 두 번째 통화로 반응하게 됩니다. 이를 입금 통화로 변환하려면 이 값에 특정 비율을 곱해야 하는데 이것이 바로 이전 블록에서 고려한 전환율입니다.

  • TickValueCross = ContractSize * Point * BidAlphaCross

전환율을 계산하는 것은 매우 간단합니다:

  1. 심볼의 두 번째 통화(기본 통화가 아닌)를 확인하세요.
  2. 이 통화와 입금 통화가 포함된 기호를 찾습니다.
  3. 적절한 환율로 환전하세요
  4. 필요한 경우 심볼을 변형합니다(미러 코스).

예를 들어 우리가 EURCHF를 거래하고 USD로 예치금이 있는 경우 초기 수익은 CHF가 되므로 우리는 USDCHF 상품과 해당 환율을 사용할 수 있습니다. 따라서 CHF를 USD로 환전한 다음 USD를 CHF로 매수해야 합니다. 하지만 CHF = PBid * USD이므로 USD = (1/PAsk) * CHF가 됩니다:

  • BidAlphaCross = 1/PAsk

두 번째 예제에는 다른 심볼을 사용해 보도록 하겠습니다. 예를 들어 AUDNZD를 거래하고 NZD로 수익을 얻으면 우리는 NZDUSD 환율을 취할 수 있으며 이 경우 USD = PBid * NZD이므로 우리는 이 환율을 사용할 수 있습니다:

  • BidAlphaCross = PBid

어떻게 이렇게 되는지 알아봅시다. CHF를 USD로 변환하면 "+USD ; -CHF"가 됩니다. 즉 우리는 하나의 통화를 잃고 다른 통화를 얻게 되는 것입니다. 즉 USD를 매수하고 USDCHF 환율로 매도하고 PAsk 가격으로 매도하는 것을 의미하며 실제로는 다음과 같습니다: "USD = (1/PAsk) * CHF". 다음과 같은 방식으로 이해하는 것이 더 쉽습니다. 매수할 때 만약 브로커가 환 운영에서 아무것도 가져 가는 것이 없다면 우리는 원래 보다 조금 더 적은 USD를 받아야합니다. 즉 더 큰 PAsk로 나누면 우리는 1/P보다 작은 값을 얻게 됩니다.

두 번째 경우에는 상황이 반전됩니다. NZD를 USD로 변환하면 "+USD ; -NZD"가 되며, 이는 NZDUSD 환율을 사용하여 PBid 가격으로 매도한다는 의미입니다. "USD = PBid * NZD"에 대해서도 비슷한 비율을 설정해 보겠습니다. 다시 약간 더 나쁜 환율인 "PBid"로 교환이 이루어집니다. 이제 모든 것이 일치합니다. 모든 것이 투명하고 이해하기 쉽습니다. 기본 퍼펙트 비율은 위에서 살펴본 "PMid"라는 점을 명심하세요. 이를 고려할 때 스프레드는 브로커가 교환되는 통화의 형태로 부과하는 비율에 불과하다는 것을 쉽게 이해할 수 있습니다. 따라서 포지션에 진입하든 청산하든 거래할 때마다 스프레드라고 하는 브로커가 부과하는 일종의 환전 세금이 부과됩니다. 이 세금의 나머지는 수수료와 스왑에 포함되어 있습니다.

환율은 필요하지 않으며 수익 통화가 예금 통화와 일치하는 경우에만 비율이 1이 되므로 주요 통화쌍의 경우 비율이 사라지고 모든 통화쌍에 대해 틱 크기가 고정됩니다. 이전 사례에서와 마찬가지로 우리가 거래하는 심볼이 과도기적 비율이될 수 있으므로 다른 심볼 중에서 검색할 필요가 없습니다.

새로운 BidAlphaCross 값이 있다는 것을 고려하여 수수료와 스왑 없이 주문 손익 방정식을 다시 작성합니다:

  • BuyProfit = BidAlphaCross * Lot * ContractSize * ( Bid2 – Bid1 – S1*Point)
  • SellProfit = BidAlphaCross * Lot * ContractSize * ( Bid1 – Bid2 – S2*Point)

다음을 고려합니다:

  • Bid1 = Mid1 - (S1*Point)/2
  • Bid2 = Mid2 - (S2*Point)/2

방정식을 좀 더 시각적인 형태로 다시 작성하여 비율을 Mid로 대체해 보겠습니다:

  • BuyProfit = BidAlphaCross * Lot * ContractSize * ( Mid2 – (S2*Point)/2 – Mid1 + (S1*Point)/2 – S1*Point)
  • SellProfit = BidAlphaCross * Lot * ContractSize * ( Mid1 – (S1*Point)/2 – Mid2 + (S2*Point)/2 – S2*Point)

이 모든 것을 단순화해 보겠습니다:

  • BuyProfit = Lot * BidAlphaCross * ContractSize * Point * [ ( Mid2 – Mid1 )/ Point - ( S1/2 + S2/2 ) ]
  • SellProfit = Lot * BidAlphaCross * ContractSize * Point * [ ( Mid1 – Mid2 )/ Point - ( S1/2 + S2/2 ) ]

더욱 간소화되었습니다:

  • BuyProfit = Lot * TickValueCross * [ ( Mid2 – Mid1 )/ Point ] - Lot * TickValueCross * ( S1/2 + S2/2 )
  • SellProfit = Lot * TickValueCross * [ ( Mid1 – Mid2 )/ Point ] - Lot * TickValueCross * ( S1/2 + S2/2 )

이제 더 쉽고 명확해졌습니다. 저는 스프레드와 관련된 서먼드를 일부러 제거하여 포지션 또는 주문이 얼마나 오래 활성화되어 있는지에 관계없이 이것이 정확히 부과된 값이라는 것을 알 수 있도록 했습니다.

정확한 스왑 계산 함수

이제 스왑 방정식을 명확히 하는 작업이 남아 있습니다. 이 글의 서두에서 설명한 방정식을 다시 한 번 상기해 보겠습니다:

  • Swap = Lot * TickValue * SwapPoints * SwapCount(StartTime,EndTime)
  • Swap = Lot * ContractSize * BidAlpha * SwapPercent/100 * SwapCount(StartTime,EndTime)

지난 블록에서 우리는 TickValue가 한 자리 숫자가 아니며 통화 쌍에 따라 다르게 계산된다는 사실을 알게 되었습니다. 그렇게 결정된 것입니다.

  • TickValue = ContractSize * Point

그러나 이는 수익 통화가 입금 통화와 일치하는 쌍에서만 그렇게 작동합니다. 더 복잡한 경우 우리는 다음과 같은 값을 사용합니다:

  • TickValueCross = ContractSize * Point * BidAlphaCross

여기서 BidAlphaCross는 입금 통화와 선택한 심볼에 따라 다른 값입니다. 이 모든 것은 위에서 정의한대로 입니다. 이를 바탕으로 우리는 표준 상수를 대체하는 첫 번째 버전의 방정식을 다시 작성해야 합니다:

  • Swap = Lot * TickValueCross * SwapPoints * SwapCount(StartTime,EndTime)

하지만 이 방정식은 아직 완벽하지 않습니다. 수수료나 스프레드와 달리 스왑은 포지션이 열려 있는 동안 임의로 많은 횟수만큼 실행될 수 있기 때문입니다. 교차 환율의 경우 각 스왑 발생 시점에 따라 BidAlphaCross 값이 변경되기 때문에 이 값이 약간 달라지게 됩니다. 그러므로 하나의 TickValueCross 값으로는 전체 스왑을 설명하기에 충분하지 않은 것으로 나타났습니다. 두 가지 '과세' 옵션에 대한 스왑을 계산하는 전체 방정식을 작성해 보겠습니다:

  1. Swap = SUMM(1 … D) { Lot * (SwapPoints * K[i]) * TickValueCross[i] } - 교차한 각 포인트 0:00에 대해 포인트 단위로 발생한 모든 스왑의 합계
  2. Swap = SUMM(1 … D) { Lot * ContractSize * BidAlpha[i] * (SwapPercent/100 * K[i]) * } — in %

합산할 배열:

  • K[i] = 1 또는 3 - 비율이 "3"이면 트리플 스왑이 발생한 날임을 의미합니다.
  • TickValueCross[i] - 스왑 포인트의 틱 크기 배열
  • BidAlpha[i] - 스왑 부과 시점의 조정 비율 배열

임의 주문에 대한 스왑 계산의 예를 살펴보겠습니다. 이를 위해 다음과 같은 간단한 표기법을 소개합니다:

  • TickValueCross[i] = T[i]
  • BidAlpha[i] = B[i]
  • K[i] = K[i]

이제 스왑을 합산하는 방법을 그래픽으로 표현해 보겠습니다:

스왑 계산


우리는 주문 손익 계산의 모든 가능한 예시를 분석했습니다.

실용적인 부분

이 섹션에서는 우리는 수학적 모델을 테스트해 볼 것입니다. 특히 저는 수수료와 스왑을 고려하지 않고 손익을 계산하는 문제에 특히 주의를 기울일 것입니다. 기억하실지 모르겠지만 제는 교차 비율로 수익을 계산할 경우 TickValueCross 값을 어느 시점에 계산해야 하는지 궁금하다고 했었습니다. 이 순간이 제가 테스트하려는 전체 모델에서 유일한 불확실성입니다. 이를 위해 먼저 수학적 모델을 사용하여 주문의 손익을 계산하는 데 필요한 모든 기능을 구현하고 전략 테스터에서 테스트 한 후 계산을 거래 내역의 실제 주문 데이터와 비교해 보겠습니다. 최종 목표는 수학적 모델을 테스트하고 동시에 OrderCalcProfit과 같은 MQL5 참조 함수와 비교하는 것입니다.

이 모든 것을 평가하기 위해 네 가지 수량을 소개할 필요가 있습니다:

  1. Real - 기록에서 주문 수익
  2. BasicCalculated - OrderCalcProfit 함수를 사용하여 주문을 개설할 때 계산된 수익과 동일합니다.
  3. CalculatedStart - 수학적 모델을 사용하여 주문을 개시할 때 계산된 수익입니다.
  4. CalculatedEnd - 수학 모델을 사용하여 주문을 청산할 때 계산된 수익입니다.

여기에는 세 가지 유형의 수익 가치 평균 편차가 수반됩니다:

  1. AverageDeviationCalculatedMQL = Summ(0..n-1) [ 100 * MathAbs(BasicCalculated - Real)/MathAbs(Real) ]/ n: MQL5 코드별 상대 수익 편차
  2. AverageDeviationCalculatedStart = Summ(0.. n-1 ) [  100 * MathAbs(CalculatedStartReal)/MathAbs(Real) ] / n : 주문 개시 시 코드에 의한 상대적 수익 편차
  3. AverageDeviationCalculatedEnd =  Summ(0.. n-1 ) [  100 * MathAbs(CalculatedEnd Real)/MathAbs(Real) ] / n : 주문 청산 시 코드에 따른 상대적 수익 편차

이와 유사하게 여러분은 세 가지 유형의 최대 편차를 입력할 수 있습니다:

  1. MaxDeviationCalculatedMQL = Max(0.. n-1 ) [ (100 * MathAbs(BasicCalculated - Real)/MathAbs(Real)) ] - MQL5 코드별 상대 수익 편차
  2. MaxDeviationCalculatedStart =  Max(0.. n-1 ) [  (100 * MathAbs(CalculatedStart Real)/MathAbs(Real)) ]  주문 개시 시 코드에 의한 상대 수익 편차
  3. MaxDeviationCalculatedEnd =  Max(0.. n-1 ) [  (100 * MathAbs(CalculatedEnd Real)/MathAbs(Real)) ]   - 주문 청산 시 코드별 상대 수익 편차

설명:

  • Summ(0..n-1) - 모든 "n" 주문의 모든 상대 편차 합계
  • Max(0..n-1) - 모든 "n" 주문의 최대 상대 편차

우리는 임의의 EA 코드에서 이러한 계산을 구현하여 수학적 모델을 테스트할 수 있습니다. 수익 방정식을 구현하는 것부터 시작하겠습니다. 저는 다음과 같은 방식으로 만들었습니다:

double CalculateProfitTheoretical(string symbol, double lot,double OpenPrice,double ClosePrice,bool bDirection)
   {
   //PrBuy = Lot * TickValueCross * [ ( Bid2 - Ask1 )/Point ]
   //PrSell = Lot * TickValueCross * [ ( Bid1 - Ask2 )/Point ]
   if ( bDirection )
      {
      return lot * TickValueCross(symbol) * ( (ClosePrice-OpenPrice)/SymbolInfoDouble(symbol,SYMBOL_POINT) );
      }
   else
      {
      return lot * TickValueCross(symbol) * ( (OpenPrice-ClosePrice)/SymbolInfoDouble(symbol,SYMBOL_POINT) );
      }   
   }

여기에는 매수와 매도라라는 두 가지 방정식이 하나로 합쳐져 있습니다. "bDirection" 마커가 이를 담당합니다. 틱 크기를 계산하는 추가 함수는 녹색으로 강조 표시됩니다. 저는 다음과 같은 방법으로 구현했습니다:

double TickValueCross(string symbol,int prefixcount=0)
   {
   if ( SymbolValue(symbol) == SymbolBasic() )
      {
      return TickValue(symbol);
      }
   else
      {
      MqlTick last_tick;
      int total=SymbolsTotal(false);//symbols in Market Watch
      for(int i=0;i<total;i++) Symbols[i]=SymbolName(i,false);
      string crossinstrument=FindCrossInstrument(symbol);
      if ( crossinstrument != "" )
         {
         SymbolInfoTick(crossinstrument,last_tick);
         string firstVAL=StringSubstr(crossinstrument,prefixcount,3);
         string secondVAL=StringSubstr(crossinstrument,prefixcount+3,3);
         if ( secondVAL==SymbolBasic() && firstVAL == SymbolValue(symbol) )
            {
             return TickValue(symbol) * last_tick.bid;
            }
         if ( firstVAL==SymbolBasic() && secondVAL == SymbolValue(symbol) )
            {
            return TickValue(symbol) * 1.0/last_tick.ask;
            }         
         }
      else return TickValue(symbol);  
      }
   return 0.0;   
   }

또한 다음과 같은 경우에 대한 두 가지 구현이 내부에 있습니다:

  1. 심볼의 수익 통화는 예치금의 통화와 동일합니다.
  2. 기타 모든 경우(과도기적 요율을 찾는 경우)

두 번째 시나리오도 두 가지 경우로 나뉩니다:

  • 입금 통화는 전환율 상단에 있습니다.
  • 입금 통화는 전환율의 맨 아래에 있습니다.

모든 것이 수학적 모델에 따라 엄격하게 이루어집니다. 마지막 분할을 구현하려면 먼저 전환율을 계산하는 데 적합한 도구를 찾아야 합니다:

string FindCrossInstrument(string symbol,int prefixcount=0)
   {
   string firstVAL;
   string secondVAL;
   for(int i=0;i<ArraySize(Symbols);i++)
      {
      firstVAL=StringSubstr(Symbols[i],prefixcount,3);
      secondVAL=StringSubstr(Symbols[i],prefixcount+3,3);
      if ( secondVAL==SymbolBasic() && firstVAL == SymbolValue(symbol) )
         {
         return Symbols[i];
         }
      if ( firstVAL==SymbolBasic() && secondVAL == SymbolValue(symbol) )
         {
         return Symbols[i];
         }      
      }
   return "";
   }

이렇게 하려면 심볼 이름에서 기본 통화 를 "꺼내는" 방법을 알아야 합니다:

string SymbolValue(string symbol,int prefixcount=0)
   {
   return StringSubstr(symbol,prefixcount+3,3);
   }

그리고 내장된 MQL5 함수를 사용하여 수익 통화를 가져옵니다:

string SymbolBasic()
   {
   return AccountInfoString(ACCOUNT_CURRENCY);
   }

이 모든 것을 첫 매치 전에 모든 종목 시세 심볼의 통화와 비교하세요. 이제 우리는 주문을 개시하고 청산할 때 이 기능을 사용할 수 있습니다. 원하는 경우 아래 첨부 파일에서 나머지 코드를 확인할 수 있습니다. 제가 백테스트 종료 후 편차 계산을 추가했습니다. 편차 계산은 터미널 로그에 기록됩니다. 제가 28개의 주요 통화 쌍과 교차 환율을 모두 테스트하고 그 결과를 표로 작성하여 수학적 모델의 성능을 평가하고 MQL5 구현과 비교할 수 있도록 했습니다. 결과는 세 가지 조건부 블록으로 나뉩니다. 처음 두 개는 다음과 같습니다:

1 & 2 블록

보시다시피 처음 4개의 통화쌍의 경우 수익 통화가 입금 통화와 동일하기 때문에 MQL5와 우리의 구현이 모두 완벽하게 작동합니다. 다음은 기본 통화와 수익 통화가 동일한 세 개의 통화 쌍으로 구성된 블록의 경우입니다. 이 경우 MQL5 구현이 가장 잘 작동하지만 그럼에도 불구하고 주문을 개시 때의 계산 오류가 청산 때의 동일한 오류보다 훨씬 높다는 것은 이미 분명합니다. 이는 주문이 청산되는 순간에 계산이 실제로 수행되어야 함을 간접적으로 보여줍니다. 다른 통화 쌍을 살펴보겠습니다:

블록 3

여기서 저의 기능은 기본 MQL5 기능보다 열등하지 않습니다. 또한 포지션을 청산할 때 수행되는 계산이 항상 훨씬 더 정확하다는 것도 분명합니다. 제가 설명할 수 없는 유일한 것은 두 번째 블록의 첫 번째 줄에 0이 있다는 것입니다. 여러 가지 이유가 있을 수 있지만 그리고 제가 틀릴 수도 있지만 제 모델과 관련이 없는 것 같습니다. 수수료와 스왑에 대한 방정식을 확인하는 것은 필요하지 않다고 생각합니다. 이 방정식에는 특별히 까다로운 것이 없기 때문에 저는 이 방정식에 자신 있습니다.

결론

이 글에서 저는 단편적인 정보를 통해 수학적 모델을 처음부터 만들어 보았습니다. 이 모델에는 주요 통화쌍과 교차 환율에 대한 주문을 계산하는 데 필요한 모든 것이 포함되어 있습니다. 이 모델은 전략 테스터에서 테스트를 거쳤으며 모든 EA, 보조지표 또는 스크립트에서 즉시 사용될 수 있습니다. 사실 이 모델의 적용 범위는 단순히 수익, 손실 또는 비용을 계산하는 것보다 훨씬 더 넓지만 이에 대해서는 다른 글에서 다룰 주제입니다. 표를 작성하는 데 사용한 EA에서 필요한 모든 기능과 사용 예시를 찾을 수 있습니다. EA는 기사에 첨부되어 있습니다. 여러분이 직접 실행하고 결과를 표와 비교해 보시기 바랍니다. 가장 중요한 점은 간단하고 논리적인 '매뉴얼'을 만들 수 있었다는 점입니다.



MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/10211

파일 첨부됨 |
트레이딩을 위한 조합론과 확률 이론(1부): 기본 사항 트레이딩을 위한 조합론과 확률 이론(1부): 기본 사항
이번 시리즈에서는 거래와 가격 책정 과정을 설명하기 위해 확률 이론을 실제로 적용하는 방법에 대해 알아보겠습니다. 첫 번째 기사에서는 조합론과 확률의 기초를 살펴볼 것입니다. 그리고 확률 이론의 틀에서 프랙탈을 적용하는 방법의 첫 번째 예를 분석할 것입니다.
조합과 트레이딩을 위한 확률(5부): 곡선 분석 조합과 트레이딩을 위한 확률(5부): 곡선 분석
저는 이 글에서 여러 상태를 이중 상태 시스템으로 축소할 수 있는지 여부와 그 가능성과 관련된 내용을 진행하기로 했습니다. 이 글의 주요 목적은 확률 이론을 기반으로 확장 가능한 트레이딩 알고리즘의 추가적인 개발에 도움이 될 수 있는 유용한 결론을 분석하고 도출하는 것입니다. 물론 이 주제는 수학과 관련이 있습니다. 하지만 이전 기사의 내용을 고려해 보면 저는 세부적인 정보보다는 일반화된 정보가 더 유용하다고 생각합니다.
트레이딩을 위한 조합론과 확률 이론(2부): 범용 프랙탈 트레이딩을 위한 조합론과 확률 이론(2부): 범용 프랙탈
이 기사에서 우리는 프랙탈에 대해 계속 알아보고 모든 자료를 요약하는 데 집중할 것입니다. 이를 위해 이전의 모든 개발 내용을 간결하게 정리하여 거래에 실제로 적용하기에 편리하고 이해하기 쉬운 형태로 만들 것입니다.
조합론과 트레이딩 확률(4부): 베르누이 논리 조합론과 트레이딩 확률(4부): 베르누이 논리
이 글에서는 잘 알려진 베르누이 기법을 알아보고 이를 트레이딩과 관련한 데이터 배열을 설명하는 데 어떻게 사용할 수 있는지 보여드리겠습니다. 그런 다음 이 모든 것이 스스로 적응하는 트레이딩 시스템을 만드는 데에 사용될 것입니다. 우리는 또한 베르누이 공식의 특별한 경우인 보다 일반적인 알고리즘을 찾아보고 관련된 응용 프로그램을 찾아볼 것입니다.