負けてばっかりでとうとう10万円追加入金してしまった。
OANDAは最低1万ロットなので必要証拠金を10万円程度に設定しているので
10万円を下回ると売買できなくなってしまう。
いろんなインディケータで色々試したけど結局は移動平均なんだろうか?難しい。
15万円が1週間で130万円になったというテスト結果。なぜか本番はこうならないんだよねえ。
現在の最新ソースはこれです。だんだん無茶苦茶なソースになってしまった。
//+------------------------------------------------------------------+
//+ MA +
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
#include <Indicators\Trend.mqh>
CTrade c_Trade;
CiMA c_FA;
CiMA c_SL;
input int i_FA_period = 4; //FA期間
input int i_SL_period = 138; //SL期間
input int i_EMA_period = 4; //EMA期間
input double i_FA_diff = 0.007; //FA最大最小反転閾値
input double i_SL_diff = 0.000; //SL前後差
input double i_EMA_diff = 0.000; //EMA最大最小反転閾値
input double i_FA_SL_diff = 0.003; //FA-SL差
input double i_rieki_min = 0.013; //決算時の最低利益
input double i_rikaku = 0.10; //TP(利益確定)
input double i_songiri = 0.10; //SL(損切り)
input double i_ijiritu = 150.0; //証拠金維持率
input bool i_fukuri = true; //ロット数複利計算
input bool i_display = true; //状l態表示
//---広域変数
string g_plus = "+"; //プラス記号
string g_minus = "-"; //マイナス記号
datetime g_order_time = 0; //注文時刻
double g_order_rate = 0.0; //注文レート
double g_trade_rate = 0.0; //c_Tradeに渡すレート
double g_yakujo_rate = 0.0; //注文の約定レート
string g_display_rate = "_display_rate_";
int g_BufferSsize = 4096; //指標バッファサイズ
MqlRates g_RATE[]; //レート
//---統計情報
double g_zandaka_init = 0; //初期の残高
double g_order_volume_last = 0.0; //最終ロット数
int g_torihiki_num = 0; //取引数
int g_torihiki_num_plus = 0; //勝ち数
int g_torihiki_num_minus = 0; //負け数
double g_max_rieki = 0.0; //最大利益
double g_min_rieki = 0.0; //最大損失
double g_son = 0.0; //1取引中の最大損失
double g_son_max = 0.0; //最大損失
long g_max_time = 0; //最大ポジション保有時間
long g_min_time = LONG_MAX; //最小ポジション保有時間
//+--初期処理--------------------------------------------------------+
int OnInit() {
Print(TimeToString(TimeLocal(), TIME_DATE|TIME_SECONDS), " OnInit Start");
ChartSetSymbolPeriod(0, "USDJPY", PERIOD_M1);//チャートをUSDJPY,1分に変更
ChartIndicatorDelete(0, 0, "MA(14)");
ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true); // マウス移動イベントを有効にする
display_in_chart(g_display_rate);
g_zandaka_init = AccountInfoDouble(ACCOUNT_BALANCE);
ArraySetAsSeries(g_RATE, true);
c_FA.Create(_Symbol, _Period, i_FA_period, 0, MODE_LWMA, PRICE_CLOSE);
c_SL.Create(_Symbol, _Period, i_SL_period, 0, MODE_LWMA, PRICE_CLOSE);
c_FA.BufferResize(g_BufferSsize);
c_SL.BufferResize(g_BufferSsize);
PrintFormat("BufferSize = %d", c_FA.BufferSize());
ChartIndicatorAdd(0, 0, c_FA.Handle());
ChartIndicatorAdd(0, 0, c_SL.Handle());
c_EMA.Init(i_EMA_period);
EventSetTimer(10);
kako_up_dn();
PrintFormat("プログラム名 : %s" , __FILE__);
PrintFormat("i_FA_period : %d" , i_FA_period);
PrintFormat("i_SL_period : %d" , i_SL_period);
PrintFormat("i_EMA_period : %d" , i_EMA_period);
PrintFormat("i_FA_diff : %.5f" , i_FA_diff);
PrintFormat("i_SL_diff : %.5f" , i_SL_diff);
PrintFormat("i_EMA_diff : %.5f" , i_EMA_diff);
PrintFormat("i_FA_SL_diff : %.5f" , i_FA_SL_diff);
PrintFormat("i_rieki_min : %.5f" , i_rieki_min);
PrintFormat("i_rikaku : %.5f" , i_rikaku);
PrintFormat("i_songiri : %.5f" , i_songiri);
PrintFormat("i_ijiritu : %.5f" , i_ijiritu);
PrintFormat("i_fukuri : %s" , (string)i_fukuri);
PrintFormat("i_display : %s" , (string)i_display);
PrintFormat("残高 : %.0f円" , g_zandaka_init);
PrintFormat("当初ロット数 : %.1fロット" , calc_rot(SymbolInfoDouble(_Symbol, SYMBOL_ASK)));
PrintFormat("ポイントサイズ : %.5f" , _Point);
PrintFormat("少数点以下桁数 : %d" , _Digits);
return(INIT_SUCCEEDED);
}
//+--終了処理--------------------------------------------------------+
void OnDeinit(const int reason) {
ChartIndicatorDelete (0, 0, ChartIndicatorName(0, 0, 0 ));//作成したインディケータの削除
ChartIndicatorDelete (0, 0, ChartIndicatorName(0, 0, 1 ));//作成したインディケータの削除
//ChartIndicatorDelete(chart_id, sub_window, ChartIndicatorName(chart_id, sub_window, index));//作成したインディケータの削除
display_head ("--delete--");
display_in_chart("--delete--");
display_in_chart("--delete--", g_display_rate);
display_arrow ("--delete--");
PrintFormat("最終ロット数 : %.1fロット" , g_order_volume_last);
PrintFormat("取引数 : %d回" , g_torihiki_num);
PrintFormat("勝ち数 : %d回" , g_torihiki_num_plus);
PrintFormat("負け数 : %d回" , g_torihiki_num_minus);
PrintFormat("最大利益 : %.0f円" , g_max_rieki);
PrintFormat("最大損失 : %.0f円" , g_min_rieki);
PrintFormat("取引中最大損失 : %.0f円" , g_son_max);
PrintFormat("最大時間 : %s" , TimeToString(g_max_time, TIME_SECONDS));
PrintFormat("最小時間 : %s" , TimeToString(g_min_time, TIME_SECONDS));
PrintFormat("損益 : %.0f円" , AccountInfoDouble(ACCOUNT_BALANCE) - g_zandaka_init);
PrintFormat("残高 : %.0f円" , AccountInfoDouble(ACCOUNT_BALANCE));
PrintFormat("プログラム名 : %s" , __FILE__);
Print(TimeToString(TimeLocal(), TIME_DATE|TIME_SECONDS), " OnDeinit End");
}
//+--上昇下降--------------------------------------------------------+
class CPlusMinus {
private:
double min;
double max;
string pm;
string pm_new;
int pm_num;
public:
void CPlusMinus() {
min = 999.999;
max = 000.000;
pm = "";
pm_new = "";
pm_num = 0;
}
void Init(double zengo_sa) {
if (pm == "") {
pm = zengo_sa > 0.0 ? g_plus : g_minus;
}
}
void Update(double rate, double sa) {
pm_new = "";
if (pm == g_plus) {
max = MathMax(max, rate);
if (rate - max < -sa) {
pm = g_minus;
pm_new = pm;
pm_num = 0;
min = rate;
}
} else
if (pm == g_minus) {
min = MathMin(min, rate);
if (rate - min > sa) {
pm = g_plus;
pm_new = pm;
pm_num = 0;
max = rate;
}
}
pm_num++;
}
string GetPM () { return(pm ); }
string GetPM_New() { return(pm_new); }
double GetMin () { return(min ); }
double GetMax () { return(max ); }
double GetNum () { return(pm_num); }
};
CPlusMinus c_PM;
//+--過去の上昇下降--------------------------------------------------+
void kako_up_dn() {
string position = "";
double rate = 0.0;
string sp = " ";
double rieki = 0.0;
double soneki = 0.0;
c_FA.Refresh();
c_SL.Refresh();
CopyRates(_Symbol, _Period, 0, g_BufferSsize, g_RATE);
c_PM.Init(c_FA.Main(g_BufferSsize-2) - c_FA.Main(g_BufferSsize-1));
for (int i=g_BufferSsize-2; i>0; i--) {
c_PM.Update(c_FA.Main(i), i_FA_diff);
if (c_PM.GetPM_New() == g_plus ) display_arrow("", 228, iTime(_Symbol, 0, i), c_FA.Main(i), clrWhite, 0.0);
if (c_PM.GetPM_New() == g_minus) display_arrow("", 230, iTime(_Symbol, 0, i), c_FA.Main(i), clrWhite, 0.0);
double ask = g_RATE[i].close + g_RATE[i].spread / 2000.0;
double bid = g_RATE[i].close - g_RATE[i].spread / 2000.0;
if (position == "買い" && c_PM.GetPM_New() == g_minus && bid - rate > i_rieki_min) {
rieki = g_RATE[i].close - rate - g_RATE[i].spread / 1000.0;
display_in_chart("", sp + StringFormat("%+.3f", rieki), iTime(_Symbol, 0, i), g_RATE[i].close, clrWhite, 90.0);
position = "";
soneki += rieki;
PrintFormat("%s 利益:%.3f 総利益:%.3f", TimeToString(iTime(_Symbol, 0, i) + TimeLocal() - TimeCurrent(), TIME_DATE|TIME_SECONDS), rieki, soneki);
} else
if (position == "売り" && c_PM.GetPM_New() == g_plus && ask - rate < -i_rieki_min) {
rieki = rate - g_RATE[i].close - g_RATE[i].spread / 1000.0;
display_in_chart("", sp + StringFormat("%+.3f", rieki), iTime(_Symbol, 0, i), g_RATE[i].close, clrWhite, 90.0);
position = "";
soneki += rieki;
PrintFormat("%s 利益:%.3f 総利益:%.3f", TimeToString(iTime(_Symbol, 0, i) + TimeLocal() - TimeCurrent(), TIME_DATE|TIME_SECONDS), rieki, soneki);
} else
if (position == "" && c_PM.GetPM_New() == g_plus && c_FA.Main(i) - c_SL.Main(i) > i_FA_SL_diff && c_SL.Main(i) - c_SL.Main(i+1) > i_SL_diff && g_RATE[i].spread < 6) {
position = "買い";
rate = g_RATE[i].close;
display_in_chart("", sp + position, iTime(_Symbol, 0, i), rate, clrWhite, 90.0);
} else
if (position == "" && c_PM.GetPM_New() == g_minus && c_FA.Main(i) - c_SL.Main(i) < -i_FA_SL_diff && c_SL.Main(i) - c_SL.Main(i+1) < -i_SL_diff && g_RATE[i].spread < 6) {
position = "売り";
rate = g_RATE[i].close;
display_in_chart("", sp + position, iTime(_Symbol, 0, i), rate, clrWhite, 90.0);
}
}
display_in_chart(g_display_rate, sp + StringFormat("総利益 %+.3f", soneki), iTime(_Symbol, 0, 0), g_RATE[0].close, clrWhite, 0.0);
}
//+--EMA-------------------------------------------------------------+
class CEMA {
private:
double ema;
double alpha;
public:
void CEMA() {
ema = 0.0;
alpha = 0.0;
}
void Init(int period) {
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double rate = (ask + bid) / 2.0;
ema = rate;
alpha = 2.0 / (period + 1.0);
}
void Update() {
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double rate = (ask + bid) / 2.0;
ema = ema + (rate - ema) * alpha;
}
double GetEMA() { return(ema); }
};
CEMA c_EMA;
//+--タイマー処理----------------------------------------------------+
void OnTimer(void) {
c_EMA.Update();
c_FA.Refresh();
c_SL.Refresh();
bai_bai();
}
//+--ティックデータ処理----------------------------------------------+
/*
void OnTick() {
static long bar_old = 0;
long bar = SeriesInfoInteger(_Symbol, Period(), SERIES_BARS_COUNT);
if (bar != bar_old) {
c_FA.Refresh();
c_SL.Refresh();
bai_bai();
}
bar_old = bar;
}
*/
//+--売買------------------------------------------------------------+
void bai_bai() {
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double rate = (ask + bid) / 2.0;
// c_PM.Update(c_FA.Main(0), i_FA_diff);
c_PM.Update(c_EMA.GetEMA(), i_EMA_diff);
if (c_PM.GetPM_New() == g_plus ) display_arrow("", 228, TimeCurrent(), c_FA.Main(0), clrWhite, 0.0);
if (c_PM.GetPM_New() == g_minus) display_arrow("", 230, TimeCurrent(), c_FA.Main(0), clrWhite, 0.0);
PositionSelect(_Symbol);
if (PositionType() == POSITION_TYPE_BUY && bid - g_trade_rate > i_rieki_min) {
if (c_PM.GetPM_New() == g_minus) {
g_trade_rate = bid;//Tradeに渡すレート
PrintFormat("%s %s ★★★【買い下降決済】 利益( %.3f )残高( %.0f )",
__FILE__, TimeToString(TimeLocal(), TIME_SECONDS), AccountInfoDouble(ACCOUNT_BALANCE));
c_Trade.PositionClose(_Symbol, 1);
rc_check();
}
} else
if (PositionType() == POSITION_TYPE_SELL && ask - g_trade_rate < -i_rieki_min) {
if (c_PM.GetPM_New() == g_plus) {
g_trade_rate = ask;//Tradeに渡すレート
PrintFormat("%s %s ★★★【売り上昇決済】 利益( %.3f )残高( %.0f )",
__FILE__, TimeToString(TimeLocal(), TIME_SECONDS), AccountInfoDouble(ACCOUNT_BALANCE));
c_Trade.PositionClose(_Symbol, 1);
rc_check();
}
} else
if (PositionType() == -1) {
if (TimeCurrent() - g_order_time > 1 && SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) < 6) {
if (c_PM.GetPM() == g_plus && c_FA.Main(0) - c_SL.Main(0) > i_FA_SL_diff && c_SL.Main(0) - c_SL.Main(1) > i_SL_diff) {
g_order_rate = ask;//注文時のレート
g_trade_rate = ask;//Tradeに渡すレート
g_yakujo_rate = 0.0;//注文の約定レート
g_order_time = TimeCurrent();
double sl = NormalizeDouble(ask - i_songiri, (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS));
double tp = NormalizeDouble(ask + i_rikaku , (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS));
PrintFormat("%s %s ★★★【買い注文】 sl( %.3f )tp( %.3f )残高( %.0f )",
__FILE__, TimeToString(TimeLocal(), TIME_SECONDS), sl, tp, AccountInfoDouble(ACCOUNT_BALANCE));
c_Trade.PositionOpen(_Symbol, ORDER_TYPE_BUY , calc_rot(SymbolInfoDouble(_Symbol, SYMBOL_ASK)), ask, sl, tp);
rc_check();
} else
if (c_PM.GetPM() == g_minus && c_FA.Main(0) - c_SL.Main(0) < -i_FA_SL_diff && c_SL.Main(0) - c_SL.Main(1) < -i_SL_diff) {
g_order_rate = bid;//注文時のレート
g_trade_rate = bid;//Tradeに渡すレート
g_yakujo_rate = 0.0;//注文の約定レート
g_order_time = TimeCurrent();
double sl = NormalizeDouble(bid + i_songiri, (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS));
double tp = NormalizeDouble(bid - i_rikaku , (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS));
PrintFormat("%s %s ★★★【売り注文】 sl( %.3f )tp( %.3f )残高( %.0f )",
__FILE__, TimeToString(TimeLocal(), TIME_SECONDS), sl, tp, AccountInfoDouble(ACCOUNT_BALANCE));
c_Trade.PositionOpen(_Symbol, ORDER_TYPE_SELL, calc_rot(SymbolInfoDouble(_Symbol, SYMBOL_BID)), bid, sl, tp);
rc_check();
}
}
}
//---表示
PositionSelect(_Symbol);
g_son = MathMin(g_son , PositionGetDouble(POSITION_PROFIT));
g_son_max = MathMin(g_son_max, PositionGetDouble(POSITION_PROFIT));
display_head(StringFormat("取引数(%d)損益(%.0f)sp(%d)利益(%.0f)",
g_torihiki_num, AccountInfoDouble(ACCOUNT_BALANCE)-g_zandaka_init,
SymbolInfoInteger(_Symbol, SYMBOL_SPREAD),
PositionGetDouble(POSITION_PROFIT)
));
display_in_chart(g_display_rate, StringFormat(" (%s)(%s)", c_PM.GetPM(), c_PM.GetPM_New()), TimeCurrent(), rate);
}
//+--order_type------------------------------------------------------+
ENUM_POSITION_TYPE PositionType() {
PositionSelect(_Symbol);
int pos = PositionsTotal();
if (pos == 1) {
return((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE));
} else
if (pos > 1) {//複数のポジションがあれば全決済して強制終了する
Print("複数のポジションがあれば全決済して強制終了する");
while (pos > 0) {
c_Trade.PositionClose(_Symbol, 0);
rc_check();
PositionSelect(_Symbol);
pos = PositionsTotal();
}
ExpertRemove();//自動売買終了
return(-1);
} else {
return(-1);
}
}
//+--ロット数計算----------------------------------------------------+
double calc_rot(double p_rate) {
static double volume = 0.0;
if (i_fukuri == true || volume == 0.0) {
double zandaka = AccountInfoDouble(ACCOUNT_BALANCE);
double ijiritu = i_ijiritu / 100.0;
double rate = p_rate + i_songiri;// 損切り分だけ高いレートを想定
double rot_su = zandaka * 25.0 / ijiritu / rate / 100000.0; // 売買可能ロット数=(残高*25レバレッジ)÷証拠金維持率÷レート÷100000ロット当たり数量
volume = MathFloor(rot_su * 10.0) / 10.0; // 0.1単位にする
if (volume > 10.0) volume = 10.0; // 最大ロット10.0まで
}
return(volume);
}
//+--注文結果表示----------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans, const MqlTradeRequest &request, const MqlTradeResult &result) {
static ulong order_ticket = 0;
static ENUM_DEAL_TYPE order_type = 0;
static double order_price = 0.0;
static datetime order_time = 0;
if (trans.type == TRADE_TRANSACTION_DEAL_ADD) {
if (trans.position != order_ticket) {
order_ticket = trans.position;
order_type = trans.deal_type;
order_price = trans.price;
g_yakujo_rate = trans.price;
order_time = TimeCurrent();
PrintFormat("%s %s ★★★【注文】 "+
"rate( %.3f )差( %.3f )sl( %.3f )tp( %.3f )"+
"type( %s )position( %d )vol( %.1f )残高( %.0f )",
__FILE__, TimeToString(TimeLocal(), TIME_SECONDS),
order_price, order_price - g_trade_rate, trans.price_sl, trans.price_tp,
EnumToString(order_type), order_ticket, trans.volume, AccountInfoDouble(ACCOUNT_BALANCE));
} else {
double rieki = order_price - trans.price;
if (trans.deal_type == DEAL_TYPE_SELL) rieki = - rieki;
double soneki = trans.volume * rieki * 100000;
string keika = TimeToString(TimeCurrent() - order_time, TIME_SECONDS);
PrintFormat("%s %s ★★★【決済】 "+
"rate( %.3f )差( %.3f )sl( %.3f )tp( %.3f )"+
"type( %s )position( %d )vol( %.1f )"+
"利益( %.3f )損益( %.0f )経過( %s )最大損( %.0f )残高( %.0f )",
__FILE__, TimeToString(TimeLocal(), TIME_SECONDS),
trans.price, trans.price - g_trade_rate, trans.price_sl, trans.price_tp,
EnumToString(trans.deal_type), trans.position, trans.volume,
rieki, soneki, keika, g_son, AccountInfoDouble(ACCOUNT_BALANCE));
long iro = soneki < 0.0 ? clrRed : clrWhite;
display_in_chart("", StringFormat(" %.0f", soneki), TimeCurrent(), trans.price, iro, 90.0);
g_order_volume_last = trans.volume;
g_son = 0.0;
if (soneki >= 0.0) {
g_max_rieki = MathMax(g_max_rieki, soneki);
g_torihiki_num_plus++;
} else {
g_min_rieki = MathMin(g_min_rieki, soneki);
g_torihiki_num_minus++;
}
g_torihiki_num++;
long time_sa = TimeCurrent() - order_time;
g_max_time = MathMax(g_max_time, time_sa);
g_min_time = MathMin(g_min_time, time_sa);
if (time_sa < 2) PrintFormat("%s %s ★★★★★★1秒以内★★★★★★", __FILE__, TimeToString(TimeLocal(), TIME_SECONDS));
Print("-------------------------------------------------------------------------------------------------------------------------");
}
}
}
//+--ヘッダー表示----------------------------------------------------+
void display_head(string str) {
const string name = "_head_";
if (i_display == true) {
if (str != "--delete--") {
ObjectCreate (0, name, OBJ_LABEL, 0, 0, 0.0);//chart_id, name, type, sub_window, time, price
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, ChartGetInteger(0, CHART_WIDTH_IN_PIXELS, 0) / 2);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, 0);//ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, 0) / 2);
ObjectSetString (0, name, OBJPROP_TEXT , str);
ObjectSetInteger(0, name, OBJPROP_COLOR , clrWhite);
ObjectSetInteger(0, name, OBJPROP_CORNER , CORNER_LEFT_UPPER);//原点を左上にする
} else {
ObjectDelete(0, name);
}
ChartRedraw(0);
}
}
//+--チャート内表示--------------------------------------------------+
string display_in_chart(string p_name, string str="", datetime time=0, double rate=0.0, long col=clrWhite, double angle=0.0, int sub_window=0) {
//p_name==""は常にオブジェクトを作成して表示、p_name!=""は指定オブジェクトの再表示、p_name=="delete"はオブジェクトの削除
static long no = 0;
string name = "";
if (i_display == true) {
if (p_name != "--delete--") {
name = p_name;
if (name == "") name = "_in_chart_" + (string)no;
ObjectCreate (0, name, OBJ_TEXT, sub_window, time, rate);//chart_id, name, type, sub_window, time, price
ObjectSetString (0, name, OBJPROP_TEXT , str); //表示する「特殊文字」33~255 HELP>「標準的な定数」>「オブジェクト定数」>「オブジェクト型」>「特殊文字」
ObjectSetInteger(0, name, OBJPROP_COLOR, col); //色
ObjectSetDouble (0, name, OBJPROP_ANGLE, angle); //角度
no++;
} else {
if (str == "") {
for (long i=0; i<no; i++) {
name = "_in_chart_" + (string)i;
ObjectDelete(0, name);
}
} else {
ObjectDelete(0, str);
}
}
ChartRedraw(0);
}
return(name);
}
//+--矢印内表示------------------------------------------------------+
string display_arrow(string p_name, int code=0, datetime time=0, double rate=0.0, long col=clrWhite, double angle=0.0, int sub_window=0) {
static long no = 0;
string name = "";
if (i_display == true) {
if (p_name != "--delete--") {
name = p_name;
if (name == "") name = "_arrow_" + (string)no;
ObjectCreate (0, name, OBJ_ARROW, sub_window, time, rate);//chart_id, name, type, sub_window, time, price
ObjectSetInteger(0, name, OBJPROP_ARROWCODE, code); //矢印の形
ObjectSetInteger(0, name, OBJPROP_COLOR, col); //色
ObjectSetDouble (0, name, OBJPROP_ANGLE, angle); //角度
no++;
} else {
for (long i=0; i<no; i++) {
name = "_arrow_" + (string)i;
ObjectDelete(0, name);
}
}
ChartRedraw(0);
}
return(name);
}
//+--チャートイベント------------------------------------------------+
void OnChartEvent(
const int id, // イベントID
const long& lparam, // long型イベントパラメータ
const double& dparam, // double型イベントパラメータ
const string& sparam) // string型イベントパラメータ
{
const string name = "_display_chart_event_";
static bool disp = true;
if(id == CHARTEVENT_CLICK) {
disp = disp == true ? false : true;
display_in_chart(name, " ", 0, 0.0);
} else
if(id == CHARTEVENT_MOUSE_MOVE) {
if (disp == true) {
int x = (int)lparam;
int y = (int)dparam;
datetime dt = 0;
double price = 0.0;
int window = 0;
static datetime dt_old = 0;
static double price_old = 0.0;
static int window_old = 0;
ChartXYToTimePrice(0, x, y, window, dt, price);
if (dt != dt_old || price != price_old || window != window_old) {
int mouse_bar = iBarShift(_Symbol, Period(), dt);
datetime dt_local = dt + (TimeLocal() - TimeCurrent());
display_in_chart(name, StringFormat(" %s", TimeToString(dt_local, TIME_DATE|TIME_MINUTES)), dt, price);
dt_old = dt;
price_old = price;
window_old = window;
}
}
}
}
//+--リターンコードチェック------------------------------------------+
void rc_check() {
uint rc = c_Trade.ResultRetcode();
if (rc != 10009) { //リクエスト完了。
PrintFormat("%d %s", rc, Code_Str(rc));
if (rc != 10016 && //リクエスト内の無効なストップ。
rc != 10018 && //市場が閉鎖中。
rc != 10027 && //ライアント端末が自動取引を無効化。
rc != 10036) { //指定されたPOSITION_IDENTIFIER を持つポジションがすでに閉鎖。
ExpertRemove();//自動売買終了
}
}
}
//+--リターンコード変換----------------------------------------------+
string Code_Str(uint retcode)
{
switch(retcode) {
case 10004:return("リクオート。"); break;
case 10006:return("リクエストの拒否。"); break;
case 10007:return("トレーダーによるリクエストのキャンセル。"); break;
case 10008:return("注文が出されました。"); break;
case 10009:return("リクエスト完了。"); break;
case 10010:return("リクエストが一部のみ完了。"); break;
case 10011:return("リクエスト処理エラー。"); break;
case 10012:return("リクエストが時間切れでキャンセル。"); break;
case 10013:return("無効なリクエスト。"); break;
case 10014:return("リクエスト内の無効なボリューム。"); break;
case 10015:return("リクエスト内の無効な価格。"); break;
case 10016:return("リクエスト内の無効なストップ。"); break;
case 10017:return("取引が無効化されています。"); break;
case 10018:return("市場が閉鎖中。"); break;
case 10019:return("リクエストを完了するのに資金が不充分。"); break;
case 10020:return("価格変更。"); break;
case 10021:return("リクエスト処理に必要な相場が不在。"); break;
case 10022:return("リクエスト内の無効な注文有効期限。"); break;
case 10023:return("注文状態の変化。"); break;
case 10024:return("頻繁過ぎるリクエスト。"); break;
case 10025:return("リクエストに変更なし。"); break;
case 10026:return("サーバが自動取引を無効化。"); break;
case 10027:return("クライアント端末が自動取引を無効化。"); break;
case 10028:return("リクエストが処理のためにロック中。"); break;
case 10029:return("注文やポジションが凍結。"); break;
case 10030:return("無効な注文充填タイプ。"); break;
case 10031:return("取引サーバに未接続。"); break;
case 10032:return("操作は、ライブ口座のみで許可。"); break;
case 10033:return("未決注文の数が上限に達しました。"); break;
case 10034:return("シンボルの注文やポジションのボリュームが限界に達しました。"); break;
case 10035:return("不正または禁止された注文の種類。"); break;
case 10036:return("指定されたPOSITION_IDENTIFIER を持つポジションがすでに閉鎖。"); break;
case 10038:return("決済ボリュームが現在のポジションのボリュームを超過。"); break;
case 10039:return("指定されたポジションの決済注文が既存。これは、ヘッジシステムでの作業中に発生する可能性があります。•反対のポジションを決済しようとしているときにそのポジションの決済注文が既に存在している場合•ポジションを完全または部分的に決済しようとしているときに既存する決済注文と新しく出された決済注文の合計が現在のポジションボリュームを超えている場合"); break;
case 10040:return("アカウントに同時に存在するポジションの数は、サーバー設定によって制限されます。 限度に達すると、サーバーは出された注文を処理するときにTRADE_RETCODE_LIMIT_POSITIONSエラーを返します。 これは、ポジション会計タイプによって異なる動作につながります。•ネッティング - ポジションの数が考慮されます。 限度に達すると、プラットフォームはその実行によってポジションの数が増加する可能性がある新しい注文の発注を無効にします。 実際には、プラットホームは、既にポジションを有する銘柄についてのみの発注を可能にします。 現在の未決注文は、実行によって現在のポジションの変更につながる可能性がありますがその数を増やすことはできないので考慮されません。•ヘッジング - 未決注文のアクティブ化によって常に新しいポジションが開かれるため、未決注文はポジションとともに考慮されます。限度に達すると、プラットフォームは、成行注文と未決注文の両方での新しい発注を無効にします。"); break;
case 10041:return("未決注文アクティベーションリクエストは却下され、注文はキャンセルされます。"); break;
case 10042:return("銘柄に Only long positions are allowed(買いポジションのみ) (POSITION_TYPE_BUY)のルールが設定されているため、リクエストは却下されます。"); break;
case 10043:return("銘柄に Only short positions are allowed(売りポジションのみ) (POSITION_TYPE_SELL)のルールが設定されているため、リクエストは却下されます。"); break;
case 10044:return("銘柄に Only position closing is allowed(ポジション決済のみ)のルールが設定されているため、リクエストは却下されます。"); break;
case 10045:return("取引口座に Position closing is allowed only by FIFO rule(FIFOによるポジション決済のみ)(ACCOUNT_FIFO_CLOSE=true)のフラグが設定されているため、リクエストは却下されます"); break;
case 10046:return("口座で「単一の銘柄の反対のポジションは無効にする」ルールが設定されているため、リクエストが拒否されます。たとえば、銘柄に買いポジションがある場合、売りポジションを開いたり、売り指値注文を出すことはできません。このルールは口座がヘッジ勘定の場合 (ACCOUNT_MARGIN_MODE=ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)のみ適用されます。"); break;
default:return("TRADE_RETCODE_UNKNOWN="+IntegerToString(retcode)); break;
}
}
//+------------------------------------------------------------------+