半裁量ナンピンマーチン補助EA分割決済機能付き ソースコード有り
無料で最後まで読めます。
説明動画です。
ボタン押すとエントリーしてそのあと、内部的にナンピンします。
利確ポイントのライン追加しました。
ドローダウンリダクション
最初のポジション(1番不利なポジション)と最後のポジションを プラスで相殺していくロジック
設定値が10なら、1と10で発動、残り8ポジションでTP到達なら決済 逆行が続きポジションが増加しても、10ポジションが残るまで(8ポジション) 最初と最後のポジションで利益相殺 最後は8ポジションで決済
質問と回答
Q. パネルの数値を変更した場合、暫定的に動作は変更されるがEA自体の設定は変わらないということでしょうか?
A. はい。そうです。永久保存はパラメーターで設定ファイルを保存してください。
Q. パネルのDD Profitの働きは?
A. ナンピンマーチンで一番最初と一番最後のポジションでナンピンマーチンしているような感じです。他のポジションをスルーして、2個のポジションの平均取得単価を計算して、平均取得単価から初期値1000ポイントまで利益が出たら1番最初のポジションと、1番最後のポジションを決済します。
ダウンロードリンク
ウイルス判定されてしまうでのブログからダウンロードするリンク張ります。
https://web-lukes.info/wp-content/uploads/2023/09/DDReduction.zip
出来ないなら以下の記事を参考に自分でコンパイルをお試しください。
ソースコード
//+------------------------------------------------------------------+
//| ProjectName |
//| Copyright 2018, CompanyName |
//| http://www.companyname.net |
//+------------------------------------------------------------------+
#property strict
#include <Controls/Dialog.mqh>
#include <Controls/Button.mqh>
#include <Controls/Label.mqh>
#include <Controls/Edit.mqh>
#include <Controls/CheckBox.mqh>
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class MyDialog : public CAppDialog {
public:
CButton buyButton;
CButton sellButton;
CButton closeAllButton;
CLabel bidLabel;
CLabel askLabel;
CLabel spreadLabel;
CLabel lotSizeLabel;
CEdit orderQuantity;
CEdit takeProfit;
CCheckBox enableStopLoss;
CEdit stopLoss;
CCheckBox enablePartialClose;
CEdit partialCloseTrigger;
CEdit partialClosePrice;
CLabel takeProfitLabel; // New label for take profit
CLabel partialClosePositionLabel; // New label for DD Reduction position number
CLabel partialClosePriceLabel; // New label for DD Reduction price
CLabel nanpinWidthLabel;
CEdit nanpinWidth;
CLabel martingaleMultiplierLabel;
CEdit martingaleMultiplier;
CLabel maxPositionSizeLabel;
CEdit maxPositionSize;
CLabel symbolLabel;
double GetOrderQuantityText() {
return StrToDouble(orderQuantity.Text());
}
double GetTakeProfitText() {
return StrToDouble(takeProfit.Text());
}
bool IsStopLossEnabled() {
return enableStopLoss.Checked();
}
double GetStopLossText() {
return StrToDouble(stopLoss.Text());
}
bool IsPartialCloseEnabled() {
return enablePartialClose.Checked();
}
int GetPartialCloseTriggerText() {
return StrToInteger(partialCloseTrigger.Text());
}
double GetPartialClosePriceText() {
return StrToDouble(partialClosePrice.Text());
}
double GetNanpinWidthText() {
return StrToDouble(nanpinWidth.Text());
}
double GetMartingaleMultiplierText() {
return StrToDouble(martingaleMultiplier.Text());
}
double GetMaxPositionSizeText() {
return StrToDouble(maxPositionSize.Text());
}
virtual bool Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2);
virtual bool OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam);
protected:
bool CreateSellButton(void);
bool CreateBuyButton(void);
bool CreateCloseAllButton(void);
bool CreateOrderQuantity(void);
bool CreateLabels(void);
bool CreateLotSizeLabel(void);
bool CreateTakeProfit(void);
bool CreateEnableStopLoss(void);
bool CreateStopLoss(void);
bool CreateEnablePartialClose(void);
bool CreatePartialCloseTrigger(void);
bool CreatePartialClosePrice(void);
bool CreatetakeProfitLabel(void);
bool CreateTakeProfitLabel(void); // New method for creating take profit label
bool CreatePartialClosePositionLabel(void); // New method for creating DD Reduction position label
bool CreatePartialClosePriceLabel(void); // New method for creating DD Reduction price label
bool CreateNanpinWidthLabel(void);
bool CreateNanpinWidth(void);
bool CreateMartingaleMultiplierLabel(void);
bool CreateMartingaleMultiplier(void);
bool CreateMaxPositionSizeLabel(void);
bool CreateMaxPositionSize(void);
bool CreateSymbolLabel(void);
void OnClickSellButton() {
Print("SELLボタンがクリックされた");
position_entry(1, input_order_quantity); // Sell entry
}
void OnClickBuyButton() {
Print("BUYボタンがクリックされた");
position_entry(0, input_order_quantity); // Buy entry
}
void OnClickCloseAllButton() {
Print("全決済ボタンがクリックされた");
position_close(0); // Close all Buy positions
position_close(1); // Close all Sell positions
}
};
// ボタンのイベントハンドラを含むようにEVENT_MAP_BEGINを更新
EVENT_MAP_BEGIN(MyDialog)
ON_EVENT(ON_CLICK, buyButton, OnClickBuyButton)
ON_EVENT(ON_CLICK, sellButton, OnClickSellButton)
ON_EVENT(ON_CLICK, closeAllButton, OnClickCloseAllButton)
EVENT_MAP_END(CAppDialog)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2) {
if(!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2))
return (false);
if(!CreateSellButton())
return (false);
if(!CreateBuyButton())
return (false);
if(!CreateCloseAllButton())
return (false);
if(!CreateOrderQuantity())
return (false);
if(!CreateLabels())
return (false);
if(!CreateLotSizeLabel())
return (false);
if(!CreateTakeProfit())
return (false);
if(!CreateEnableStopLoss())
return (false);
if(!CreateStopLoss())
return (false);
if(!CreateEnablePartialClose())
return (false);
if(!CreatePartialCloseTrigger())
return (false);
if(!CreatePartialClosePrice())
return (false);
// Add the new label creation methods
if(!CreateTakeProfitLabel())
return (false);
if(!CreatePartialClosePositionLabel())
return (false);
if(!CreatePartialClosePriceLabel())
return (false);
// Add the new control creation methods
if(!CreateNanpinWidthLabel())
return (false);
if(!CreateNanpinWidth())
return (false);
if(!CreateMartingaleMultiplierLabel())
return (false);
if(!CreateMartingaleMultiplier())
return (false);
if(!CreateMaxPositionSizeLabel())
return (false);
if(!CreateMaxPositionSize())
return (false);
if(!CreateSymbolLabel())
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateSellButton(void) {
if(!sellButton.Create(m_chart_id, m_name + "SellButton", m_subwin, 8, 90, 62, 130))
return (false);
if(!sellButton.Text("SELL"))
return (false);
if(!sellButton.Color(clrWhite))
return (false);
if(!sellButton.ColorBackground(clrRed))
return (false);
if(!sellButton.ColorBorder(clrRed))
return (false);
if(!Add(sellButton))
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateBuyButton(void) {
if(!buyButton.Create(m_chart_id, m_name + "BuyButton", m_subwin, 155, 90, 210, 130))
return (false);
if(!buyButton.Text("BUY"))
return (false);
if(!buyButton.Color(clrWhite))
return (false);
if(!buyButton.ColorBackground(clrBlue))
return (false);
if(!buyButton.ColorBorder(clrBlue))
return (false);
if(!Add(buyButton))
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateCloseAllButton(void) {
if(!closeAllButton.Create(m_chart_id, m_name + "CloseAllButton", m_subwin, 70, 100, 145, 130))
return (false);
if(!closeAllButton.Text("CloseAll"))
return (false);
if(!closeAllButton.Color(clrWhite))
return (false);
if(!closeAllButton.ColorBackground(clrDarkGray))
return (false);
if(!closeAllButton.ColorBorder(clrDarkGray))
return (false);
if(!Add(closeAllButton))
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateLotSizeLabel(void) {
if(!lotSizeLabel.Create(m_chart_id, m_name + "LotSizeLabel", m_subwin, 10, 140, 55, 160))
return (false);
if(!lotSizeLabel.Text("LotSize"))
return (false);
if(!Add(lotSizeLabel))
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateTakeProfitLabel(void) {
if(!takeProfitLabel.Create(m_chart_id, m_name + "TakeProfitLabel", m_subwin, 10, 185, 55, 190))
return (false);
if(!takeProfitLabel.Text("TakeProfit"))
return (false);
if(!Add(takeProfitLabel))
return (false);
return (true);
}
string qty = "";
// 以下の位置を調整しました
bool MyDialog::CreateOrderQuantity(void) {
if(!orderQuantity.Create(m_chart_id, m_name + "OrderQuantity", m_subwin, 90, 140, 145, 170))
return (false);
if(!Add(orderQuantity))
return (false);
orderQuantity.Text((string)parameter_input_lot_size);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateSymbolLabel(void) {
if(!symbolLabel.Create(m_chart_id, m_name + "SymbolLabel", m_subwin, 10, 0, 55, 20))
return (false);
if(!symbolLabel.Text(Symbol()))
return (false);
if(!Add(symbolLabel))
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateLabels(void) {
if(!bidLabel.Create(m_chart_id, m_name + "BidLabel", m_subwin, 2, 50, 100, 70))
return (false);
if(!askLabel.Create(m_chart_id, m_name + "AskLabel", m_subwin, 117, 50, 100, 70))
return (false);
if(!spreadLabel.Create(m_chart_id, m_name + "SpreadLabel", m_subwin, 10, 20, 100, 40))
return (false);
if(!Add(bidLabel) || !Add(askLabel) || !Add(spreadLabel))
return (false);
bidLabel.FontSize(13);
askLabel.FontSize(13);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateTakeProfit(void) {
if(!takeProfit.Create(m_chart_id, m_name + "TakeProfit", m_subwin, 130, 180, 200, 210))
return (false);
if(!Add(takeProfit))
return (false);
takeProfit.Text((string) parameter_input_take_profit );
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateEnableStopLoss(void) {
if(!enableStopLoss.Create(m_chart_id, m_name + "EnableStopLoss", m_subwin, 10, 230, 145, 250))
return (false);
if(!enableStopLoss.Text("Stop Loss"))
return (false);
if(!Add(enableStopLoss))
return (false);
if(!enableStopLoss.Checked(parameter_input_enable_stop_loss ))
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateStopLoss(void) {
if(!stopLoss.Create(m_chart_id, m_name + "StopLoss", m_subwin, 130, 225, 200, 255))
return (false);
if(!Add(stopLoss))
return (false);
stopLoss.Text((string)parameter_input_stop_loss );
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateEnablePartialClose(void) {
if(!enablePartialClose.Create(m_chart_id, m_name + "EnablePartialClose", m_subwin, 10, 270, 160, 290))
return (false);
if(!enablePartialClose.Text("DD Reduction"))
return (false);
if(!Add(enablePartialClose))
return (false);
if(!enablePartialClose.Checked(parameter_input_enable_partial_close))
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreatePartialCloseTrigger(void) {
if(!partialCloseTrigger.Create(m_chart_id, m_name + "PartialCloseTrigger", m_subwin, 150, 290, 210, 320))
return (false);
if(!Add(partialCloseTrigger))
return (false);
partialCloseTrigger.Text((string)parameter_input_partial_close_trigger );
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreatePartialClosePrice(void) {
if(!partialClosePrice.Create(m_chart_id, m_name + "PartialClosePrice", m_subwin, 150, 320, 210, 350))
return (false);
if(!Add(partialClosePrice))
return (false);
partialClosePrice.Text((string)parameter_input_partial_close_price );
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreatePartialClosePositionLabel(void) {
if(!partialClosePositionLabel.Create(m_chart_id, m_name + "PartialClosePositionLabel", m_subwin, 10, 290, 55, 325))
return (false);
if(!partialClosePositionLabel.Text("Position Count"))
return (false);
if(!Add(partialClosePositionLabel))
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreatePartialClosePriceLabel(void) {
if(!partialClosePriceLabel.Create(m_chart_id, m_name + "PartialClosePriceLabel", m_subwin, 10, 320, 55, 355))
return (false);
if(!partialClosePriceLabel.Text("DD Take Profit"))
return (false);
if(!Add(partialClosePriceLabel))
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateNanpinWidthLabel(void) {
if(!nanpinWidthLabel.Create(m_chart_id, m_name + "NanpinWidthLabel", m_subwin, 10, 360, 100, 390))
return (false);
if(!nanpinWidthLabel.Text("Nanpin Haba"))
return (false);
if(!Add(nanpinWidthLabel))
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateNanpinWidth(void) {
if(!nanpinWidth.Create(m_chart_id, m_name + "Nanpin Haba", m_subwin, 145, 360, 210, 390))
return (false);
if(!Add(nanpinWidth))
return (false);
nanpinWidth.Text((string)parameter_input_nanpin_width );
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateMartingaleMultiplierLabel(void) {
if(!martingaleMultiplierLabel.Create(m_chart_id, m_name + "MartingaleMultiplierLabel", m_subwin, 10, 395, 100, 420))
return (false);
if(!martingaleMultiplierLabel.Text("Martin Bairitu"))
return (false);
if(!Add(martingaleMultiplierLabel))
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateMartingaleMultiplier(void) {
if(!martingaleMultiplier.Create(m_chart_id, m_name + "MartingaleMultiplier", m_subwin, 145, 395, 210, 425))
return (false);
if(!Add(martingaleMultiplier))
return (false);
martingaleMultiplier.Text((string)parameter_input_martingale_multiplier );
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateMaxPositionSizeLabel(void) {
if(!maxPositionSizeLabel.Create(m_chart_id, m_name + "MaxPositionSizeLabel", m_subwin, 10, 425, 100, 455))
return (false);
if(!maxPositionSizeLabel.Text("Max Position"))
return (false);
if(!Add(maxPositionSizeLabel))
return (false);
return (true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool MyDialog::CreateMaxPositionSize(void) {
if(!maxPositionSize.Create(m_chart_id, m_name + "MaxPositionSize", m_subwin, 145, 425, 210, 455))
return (false);
if(!Add(maxPositionSize))
return (false);
maxPositionSize.Text((string)parameter_input_max_position_size );
return (true);
}
MyDialog dialog;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OnInit() {
if(!dialog.Create(0, "DD Reduction", 0, 20, 120, 254, 630))
return (INIT_FAILED);
if(!dialog.Run())
return (INIT_FAILED);
return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam) {
dialog.ChartEvent(id, lparam, dparam, sparam);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnTick() {
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double spread = (ask - bid) / Point;
dialog.bidLabel.Text(StringFormat("%." + IntegerToString(_Digits) + "f", bid));
dialog.askLabel.Text(StringFormat("%." + IntegerToString(_Digits) + "f", ask));
dialog.spreadLabel.Text(StringFormat("Spread: %.0f", spread));
static double prev_bid = 0;
static double prev_ask = 0;
if(bid > prev_bid) {
dialog.bidLabel.Color(clrBlue);
} else if(bid < prev_bid) {
dialog.bidLabel.Color(clrRed);
} else {
dialog.bidLabel.Color(clrBlack);
}
if(ask > prev_ask) {
dialog.askLabel.Color(clrBlue);
} else if(ask < prev_ask) {
dialog.askLabel.Color(clrRed);
} else {
dialog.askLabel.Color(clrBlack);
}
prev_bid = bid;
prev_ask = ask;
main();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
dialog.Destroy(reason);
}
input double parameter_input_lot_size = 0.01;//ロットサイズ
input int parameter_input_take_profit = 200;//利食い幅(平均取得単価からのPOINT)
input bool parameter_input_enable_stop_loss = false;//金額ストップロスの有効化
input int parameter_input_stop_loss = 30000;//ストップロス(金額指定)
input bool parameter_input_enable_partial_close = false;//ドローダウン時分割決済の有効化
input int parameter_input_partial_close_trigger = 6;//ドローダウン時分割決済の発動ポジション数
input int parameter_input_partial_close_price = 1000;//ドローダウン時分割決済の決済する(平均取得単価からのPOINT)
input int parameter_input_nanpin_width = 200;//ナンピン幅の設定(最後のエントリーからのPOINT)
input double parameter_input_martingale_multiplier = 1.5;//マーチン倍率
input int parameter_input_max_position_size = 10;//ポジション数の制限
input string line_settei = "";//---平均取得単価の線の描画設定---
input bool input_line_on = true;//平均取得単価の線の表示
input int MagicNumber = 456789;
double input_order_quantity = 0;
double input_take_profit = 0;
bool input_enable_stop_loss = false;
double input_stop_loss = 0;
bool input_enable_partial_close = false;
int input_partial_close_trigger = 0;
double input_partial_close_price = 0;
double input_nanpin_width = 0;
double input_martingale_multiplier = 0;
double input_max_position_size = 0;
bool is_close_on = false;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void main() {
//state
input_order_quantity = dialog.GetOrderQuantityText();
input_take_profit = dialog.GetTakeProfitText();
input_enable_stop_loss = dialog.IsStopLossEnabled();
input_stop_loss = dialog.GetStopLossText();
input_enable_partial_close = dialog.IsPartialCloseEnabled();
input_partial_close_trigger = dialog.GetPartialCloseTriggerText();
input_partial_close_price = dialog.GetPartialClosePriceText();
input_nanpin_width = dialog.GetNanpinWidthText();
input_martingale_multiplier = dialog.GetMartingaleMultiplierText();
input_max_position_size = dialog.GetMaxPositionSizeText();
nanpin();
stopLoss();
ddReduction();
if(position_count(0)>0){
if(input_line_on) {
sen(position_average_price(0));
sen2(position_average_price(0) + input_take_profit * _Point);
}
}
if(position_count(1)>0){
if(input_line_on) {
sen(position_average_price(1));
sen2(position_average_price(1) - input_take_profit * _Point);
}
}
}
void sen(double price)
{
string obj_name = "heikin_syutoku_tanka";
int chart_id = 0;
ObjectDelete(chart_id,obj_name);
// オブジェクト削除
ObjectCreate(chart_id,obj_name, // オブジェクト作成
OBJ_HLINE, // オブジェクトタイプ
0, // サブウインドウ番号
0, // 1番目の時間のアンカーポイント
price // 1番目の価格のアンカーポイント
);
ObjectSetInteger(chart_id,obj_name,OBJPROP_COLOR,clrPaleTurquoise); // ラインの色設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_STYLE,STYLE_SOLID); // ラインのスタイル設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_WIDTH,3); // ラインの幅設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_BACK,false); // オブジェクトの背景表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTABLE,true); // オブジェクトの選択可否設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTED,false); // オブジェクトの選択状態
ObjectSetInteger(chart_id,obj_name,OBJPROP_HIDDEN,true); // オブジェクトリスト表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_ZORDER,0); // オブジェクトのチャートクリックイベント優先順位
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void sen2(double price)
{
string obj_name = "kessai_kakaku";
int chart_id = 0;
ObjectDelete(chart_id,obj_name);
// オブジェクト削除
ObjectCreate(chart_id,obj_name, // オブジェクト作成
OBJ_HLINE, // オブジェクトタイプ
0, // サブウインドウ番号
0, // 1番目の時間のアンカーポイント
price // 1番目の価格のアンカーポイント
);
ObjectSetInteger(chart_id,obj_name,OBJPROP_COLOR,clrYellow); // ラインの色設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_STYLE,STYLE_SOLID); // ラインのスタイル設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_WIDTH,3); // ラインの幅設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_BACK,false); // オブジェクトの背景表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTABLE,true); // オブジェクトの選択可否設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_SELECTED,false); // オブジェクトの選択状態
ObjectSetInteger(chart_id,obj_name,OBJPROP_HIDDEN,true); // オブジェクトリスト表示設定
ObjectSetInteger(chart_id,obj_name,OBJPROP_ZORDER,0); // オブジェクトのチャートクリックイベント優先順位
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void ddReduction() {
if(!input_enable_partial_close) {
return;
}
for(int side = 0; side <= 1; side++) {
int positionCount = position_count(side);
if(positionCount >= input_partial_close_trigger) {
double averageEntryPrice = first_last_average_price(side);
double currentPrice = (side == 0) ? Bid : Ask;
if((side == 0 && currentPrice >= averageEntryPrice + input_partial_close_price * _Point) ||
(side == 1 && currentPrice <= averageEntryPrice - input_partial_close_price * _Point)) {
double firstEntryPrice = getFirstEntryPrice(side);
double lastEntryPrice = getLastEntryPrice(side);
position_close_partial(side, firstEntryPrice, lastEntryPrice);
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void position_close_partial(int side, double firstEntryPrice, double lastEntryPrice) {
bool allClosed = false;
while(!allClosed) {
allClosed = true;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderType() == side && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
if(OrderOpenPrice() == firstEntryPrice || OrderOpenPrice() == lastEntryPrice) {
bool res = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0, clrAliceBlue);
if(!res) {
Print("Error in OrderClose: ", GetLastError());
allClosed = false;
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double getFirstEntryPrice(int side) {
double firstEntryPrice = 0;
datetime firstEntryTime = TimeCurrent();
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderType() == side && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
if(OrderOpenTime() < firstEntryTime) {
firstEntryTime = OrderOpenTime();
firstEntryPrice = OrderOpenPrice();
}
}
}
}
return firstEntryPrice;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void stopLoss() {
if(!input_enable_stop_loss) {
return;
}
for(int side = 0; side <= 1; side++) {
double totalProfit = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderType() == side && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
totalProfit += OrderProfit();
}
}
}
if(totalProfit <= -input_stop_loss) {
position_close(side);
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void nanpin() {
for(int side = 0; side <= 1; side++) {
double currentPrice = (side == 1) ? Bid : Ask;
int positionCount = position_count(side);
if(positionCount > 0 && positionCount < input_max_position_size) {
double lastEntryPrice = getLastEntryPrice(side);
double distance = MathAbs(currentPrice - lastEntryPrice);
//ナンピン
if(distance > input_nanpin_width* _Point) {
double maxLotSize = getMaxLotSize(side);
double newLotSize = maxLotSize * input_martingale_multiplier;
if(newLotSize <= 0.02) {
newLotSize = 0.02;
}
if(side==0 && lastEntryPrice > Ask) {
position_entry(side, newLotSize);
}
if(side==1 && lastEntryPrice < Bid) {
position_entry(side, newLotSize);
}
}
}
//利食い
double averagePrice = position_average_price(side);
double takeProfitPrice = (side == 0) ? averagePrice + input_take_profit * _Point : averagePrice - input_take_profit * _Point;
if((side == 0 && currentPrice >= takeProfitPrice) || (side == 1 && currentPrice <= takeProfitPrice)) {
position_close(side);
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double getMaxLotSize(int side) {
double maxLotSize = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderType() == side && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
if(OrderLots() > maxLotSize) {
maxLotSize = OrderLots();
}
}
}
}
return maxLotSize;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double position_average_price(int side) {
double lots_sum = 0;
double price_sum = 0;
double average_price = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
Print("Error in OrderSelect: ", GetLastError());
continue;
}
if(OrderType() == side && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
lots_sum += OrderLots();
price_sum += OrderOpenPrice() * OrderLots();
}
}
if(lots_sum > 0) {
average_price = price_sum / lots_sum;
}
return average_price;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double first_last_average_price(int side) {
double lots_sum = 0;
double price_sum = 0;
double average_price = 0;
double firstEntryPrice = 0;
double lastEntryPrice = 0;
double firstEntryLots = 0;
double lastEntryLots = 0;
datetime firstEntryTime = 0;
datetime lastEntryTime = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
Print("Error in OrderSelect: ", GetLastError());
continue;
}
if(OrderType() == side && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
if(OrderOpenTime() > lastEntryTime) {
lastEntryTime = OrderOpenTime();
lastEntryPrice = OrderOpenPrice();
lastEntryLots = OrderLots();
}
if(OrderOpenTime() < firstEntryTime || firstEntryTime == 0) {
firstEntryTime = OrderOpenTime();
firstEntryPrice = OrderOpenPrice();
firstEntryLots = OrderLots();
}
}
}
lots_sum += firstEntryLots;
lots_sum += lastEntryLots;
price_sum += firstEntryPrice * firstEntryLots;
price_sum += lastEntryPrice * lastEntryLots;
if(lots_sum > 0) {
average_price = price_sum / lots_sum;
}
return average_price;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double getLastEntryPrice(int side) {
double lastEntryPrice = 0;
datetime lastEntryTime = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderType() == side && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
if(OrderOpenTime() > lastEntryTime) {
lastEntryTime = OrderOpenTime();
if(lastEntryPrice == 0) {
lastEntryPrice = OrderOpenPrice();
}
if(OrderType() == 1 && lastEntryPrice < OrderOpenPrice()) {
lastEntryPrice = OrderOpenPrice();
}
if(OrderType() == 0 && lastEntryPrice > OrderOpenPrice()) {
lastEntryPrice = OrderOpenPrice();
}
}
}
}
}
return lastEntryPrice;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int position_count(int side) {
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderType() == side) {
if(OrderSymbol()==Symbol()) {
if(OrderMagicNumber()==MagicNumber) {
count++;
}
}
}
}
}
return count;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void position_close(int side) {
while(position_count(side) > 0) {
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if(OrderType() == side && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
bool res = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0, clrAliceBlue);
if(!res) {
Print("Error in OrderClose: ", GetLastError());
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void position_entry(int side,double lot_size = 0.01) {
if(side==0) {
bool res= OrderSend(NULL,side,lot_size,Ask,0,0,0,"DD Reduction",MagicNumber,0,clrGreen);
}
if(side==1) {
bool res= OrderSend(NULL,side,lot_size,Bid,0,0,0,"DD Reduction",MagicNumber,0,clrRed);
}
}
//+------------------------------------------------------------------+
ここから先は
0字
このマガジンで読み放題です。
FX自動売買開発入門サンプルコードセット
10,000円
EA開発者のためのサンプルコード集
この記事が気に入ったらサポートをしてみませんか?