ENUM_TIMEFRAMES array_timeframes[]=
{
PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M30,
PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
};
int total=SymbolsTotal(true), total_tf=ArraySize(array_timeframes);
for(int i=0; i<total; i++){
string symbol_name=SymbolName(i,true);
for(int j=0; j<total_tf; j++){
if(IsNewBar(symbol_name,array_timeframes[j])){
Print("Новый бар на ",symbol_name," ",EnumToString(array_timeframes[j]));
}
}
}
のようなものです(MQL5用のコード)。
intOnInit()
{
IsNewBar(); // сбор информации - можно включить здесь, но не обязательноEventSetMillisecondTimer(100);
return(INIT_SUCCEEDED);
}
voidOnDeinit(constint reason)
{
EventKillTimer();
}
voidOnTimer()
{
IsNewBar(); // сбор информации - можно включить здесь, но не обязательно// различные варианты проверки новых баровif(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента"); // режим вывода информацииif(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента"); // режим вывода информации
if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента"); // режим вывода информации
if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD"); // режим вывода информации
if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD"); // режим вывода информации
if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF"); // режим вывода информации
}
voidOnTick()
{
IsNewBar(); // сбор информации - можно включить здесь, но не обязательно// различные варианты проверки новых баровif(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента"); // режим вывода информации
if(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента"); // режим вывода информации
if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента"); // режим вывода информации
if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD"); // режим вывода информации
if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD"); // режим вывода информации
if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF"); // режим вывода информации
}
//+---------------------------------------------------------------------------------------------------+//| Функция определения нового бара по всем ТФ всех инструментов в окне "Обзор рынка" |//| два режима работы: |//| - режим сбора информации, out=false (значение по умолчанию). Достаточно запустить IsNewBar(); |//| - режим вывода информации, out=true |//| tf - период таймфрейма, по умолчанию текущий ТФ (необходим только при выводе информации) |//| Sym - символ инструмента, по умолчанию текущий символ (необходим только при выводе информации) |//+---------------------------------------------------------------------------------------------------+bool IsNewBar(bool out=false, ENUM_TIMEFRAMES tf=PERIOD_CURRENT, string Sym="")
{
staticconstENUM_TIMEFRAMES TF[22]=
{
PERIOD_CURRENT,PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M20,PERIOD_M30,
PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
};
staticbool newbar[];
staticlong acb[]; // array of current barsstaticint N_Sym=0;
if(Sym=="") Sym=Symbol();
int total=SymbolsTotal(true);
int n_cur=-1;
for(int i=0; i<total; i++) if(Sym==SymbolName(i,true)){ n_cur=i; break;}
if(n_cur<0) { Print("данного символа нет в списке MarketWatch(окошко слева - Обзор рынка)"); return(false);}
if(out && N_Sym>0) // если режим вывода информации
{
int curtf=0;
while(TF[curtf]!=tf) curtf++;
return (newbar[n_cur*22+curtf]);
}
// режим сбора информацииif (total!=N_Sym) {ArrayResize(acb,22*total);ArrayInitialize(acb,0); ArrayResize(newbar,22*total); ArrayInitialize(newbar,false); N_Sym=total;}
for(int j=0,j1=0; j<total; j++,j1+=22)
for(int i=0;i<22;i++)
{
long CurBars=SeriesInfoInteger(SymbolName(j,true),TF[i],SERIES_LASTBAR_DATE);
if(acb[j1+i]<CurBars) // пришел новый бар
{
//if (acb[j1+i]>0) Print ("Новый бар: "+SymbolName(j,true)+" "+EnumToString(TF[i]));
acb[j1+i]=CurBars;
newbar[j1+i]=true;
}
else
{
newbar[j1+i]=false;
if(i==1) for(;i<22;i++) newbar[j1+i]=false; // если минутный бар тот же, то нет смысла продолжать проверять старшие ТФ
}
}
return(false);
}
リニア、ノンリニア...またプログラミングでオペラの話をするんですか?
まさか
OKです。あなたの解決策はダニにしか効きません。私のはタイマー式 です。バーアピアランスでタイミングをとるという私のやり方は、欠点があると思いますか?なるほど。こんな感じにしておきましょう。新しいバーフラグを設定する前に、見積書の到着を確認する機能を追加する予定です。関数にもう一つ、シンボルというパラメータを追加してみます。ユーザーは、新しいバーイベントを受信するシンボルを選択し、関数に送信します。この関数は、このシンボルが最後に引用された時刻を チェックします。そして、バーフォーマル登場時刻と見積もり時刻を比較し、イベントフラグを設定します。
まだ勉強を始めたばかりですが、難しさは感じません。
トレーディング、自動売買システム、ストラテジーテストに関するフォーラム
Mt4 サポート終了。
アルチョム・トリシキン さん 2017.09.10 22:27
見積もりの取り方は知っている :)
多通貨プログラムでは -右のシンボルのループ内のタイマで。そして、新しいバー(バーチャルではなく物理的なもの-誤-あなたのように)のオープニングは、最後の引用の時間とその時間をゼロバーのシンボルの時間と比較することによって制御 されています。
一方、あなたは、存在しないかもしれない仮想のバーを、ランダムに作っているのです。週末には存在しないが、本来はあるはずのもの。それが、例として挙げるべき最もシンプルなものです。
それにね、あなただけは、そんなやり方はしないでしょう。それ以外の人は、正しく確実な方法でやっています。しかし、それはもちろん、自分自身の問題でしかありません。
正しい方法を伝え、同じタスクを解決する上で、シンプルなOOPの書き方と複雑な手続き的なひねり方の大きな違いを示したかったのです。
でも、あなたはもっと知っているだろうし、必要ないでしょう。それ以上知っているような顔をする勇気はない。すみません。
問題ありません。文字列操作の比較を保存するためのヘッジ、まあ、顧客がマニアックですべての文字を同時に取引する場合。
しかし、操作やメモリを保存する場所はどこにもないようで、すべてが最小限になっています
void OnTimer(){
Alert(Fn_new_bar("EURUSD", PERIOD_D1)); }
//+------------------------------------------------------------------+
uint Sp_Adler32(string line){
ulong s1 = 1;
ulong s2 = 0;
uint buflength=StringLen(line);
uchar char_array[];
ArrayResize(char_array, buflength,0);
StringToCharArray(line, char_array, 0, -1, CP_ACP);
for (uint n=0; n<buflength; n++){
s1 = (s1 + char_array[n]) % 65521;
s2 = (s2 + s1) % 65521;}
return ((s2 << 16) + s1);}
//+------------------------------------------------------------------+
bool Fn_new_bar(string symb, ENUM_TIMEFRAMES tf){
static datetime st_time[];
static uint st_id[];
//---- set
datetime new_time = iTime(symb, tf, 0); if(new_time==0) return(false);
uint new_id = Sp_Adler32(StringConcatenate(symb,EnumToString(tf)));
datetime old_time = 0;
uint old_id = 0;
//---- find
int size = ArraySize(st_time);
for(int i=0; i<size; i++){
if(st_id[i]!=new_id) continue;
old_id = st_id [i];
old_time = st_time[i];
break;}
//----add new element
if(old_time==0){
ArrayResize(st_time, size+1); st_time[size]=new_time;
ArrayResize(st_id, size+1); st_id [size]=new_id; }
//----
return(old_time>0 && old_time<new_time);}
新しいシンボルとtfのチェックがあり、すべてをチェックするのではなく、必要なものだけをチェックし、無駄な操作がないので、かなり高速に実行できるはずです。
よろしくお願いします。
P.S. ここで追加できる唯一の小さなことは、配列 st_time と st_id が相互に関連しているので、これらを構造体にまとめることです。そうすれば、コード内の配列のインクリメント操作の回数を減らすことができます。
彼のプロシージャルスタイルのコードは、最終的にこのようなループで動作させるという目標があったんです。
のようなものです(MQL5用のコード)。
しかし、何度も言いますが、私はOOPの支持者です。
手続き型プログラミングで何ができないかを示す、本当に残念な例です。
EAで関数を呼び出すのではなく、普遍的なインターフェース(ハンドラ)を書くことが重要です。
ロボットを作成 するタスクは1000個以上ありますが、実はそれぞれのタスクは
1 開放信号を取得する機能
2. 注文受付の機能
3 オーダートラッキングの機能
4) 注文を決済するための信号を受信する機能。
といった具合に。
これらの機能はロボットごとに異なりますが、1000プロジェクト内で繰り返されます。 そのため、機能をユニバーサルモジュールとして組み合わせ、タスクに応じて適切なモジュールを呼び出すことができます。
まあ、これらの機能があれば、他に何もする必要はないんですけどね。この関数の入力パラメータはインタフェースである。複雑になればなるほど、起こりうるエラーの数が増え、プログラマーの作業時間が長くなる。
のようなものです(MQL5のコード)。
でも、繰り返しますが、私はOOPの支持者です。
手続き型プログラミングで何ができないかを示す、実に残念な例といえるでしょう。
原理的にそのような例は あるのでしょうか?自分のものでなくとも?深い疑問があります。2000年代前半に、自分が書いたコードのうち、デバッグされ、動作している行数を数えるのをやめたんです。また、仕事の種類や規模は多岐にわたりますが、自分で授業を作る必要性に遭遇したことはありません。数人分の作業を並列化する必要があるときはプロシージャ型の変数を使うこともありましたが、それ以上はないですね。なぜそうなのか?
ところで、なぜ手続き型プログラミングをOOPに代わるものとして語るのでしょうか。関数型プログラミングhttps://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5: 「いくつかの概念とパラダイムは関数型プログラミングに特有のもので、(オブジェクト指向プログラミングを 含む)命令型プログラミングにはほとんどない」、「関数型プログラムのもう一つの利点は、自動的な プログラミングのための膨大な機会を提供することである」。OOPによって、計算の自動並列化ができないことが判明した。これはもう、非常に重大な欠点と考えるべきで、視点はOOP向きではありません。
原則的に、そのような例は あるのでしょうか?自分のものでなくとも?深い疑問があります。
そのような例がないことは、十分にあり得ると思います。個人的には、OOPの最大のメリットは、大規模なプロジェクトの プログラミングをより便利にし、開発したものを将来的に利用するための便利な仕組みを提供することだと考えています。このことは、これまで何度もここで正論を述べてきた。
単一のインターフェースでは、あらゆる計算タスクのプログラミングに全く適用できないことは、既に述べたとおりである...。インターフェイスの形で美しいものを置くことは、純粋に外見的な処置であり、すでに準備の整ったコードにしか適用できないし、コードのさらなるサポートや改良を妨げることにもなる......。
いいえ。全く適用できない」のではなく、「使う意味がない」のです。
インターフェイスは「既成のコードに適用される純粋な化粧品的な処置」ではない。
その逆で、インターフェースはシステムアーキテクチャの中核をなすものです。そこからデザインが 始まるのです。インターフェイスは「サポートや手戻りを邪魔する」のではなく、「許される境界線を明確にする」ことでサポートや手戻りを助けるのです。インターフェースがないと、この境界を越えて、意図しないところに変更を加えてしまい、計算しにくい誤差が生じやすくなります。
プログラミングに限らず、どんな複雑なシステムも、その部品間の相互作用の基本原理を開発することから始まります。しかし、プログラミングでは、最初のタスクが非常に小さいことが多いので、逆の方向に進みます。まずパーツを書き、それを組み合わせて全体を作るのだが、パーツ同士の相性が悪いということがよくある。ちなみに、「使える変数はすべて使えるようにしたい」というのは、このためである。
isNewBar()関数が全く存在しないはずであることを除けば、問題ないでしょう。こんな些細なことでこんなに踊らされるなんておかしいよ。
これは単なる変数で、単純にバーの時間と比較されます。すべてのケースが成功した場合、この変数には最後に新しいバーの 時間が代入されます。そうでない場合は、すべてのケースに1回だけ試行が割り当てられます。
isNewBar()関数が全く存在しないはずであることを除けば、問題ないでしょう。こんな些細なことでこんなに踊らされるなんておかしいよ。
これは単なる変数で、単純にバーの時間と比較されます。すべてのケースが成功した場合、この変数には最後に新しいバーの 時間が代入されます。そうでない場合は、すべてのケースに1回だけ試行が割り当てられます。
+1