MetaTrader 5 Python User Group - メタトレーダーでPythonを使用する方法 - ページ 66

 
Vladimir Karputov:

現在の価格(BidとAsk)はどうなっていますか?フリーズレベル(SYMBOL_TRADE_FREEZE_LEVEL)は何でしたか?

FREEZEレベルについてよくわからない?

買いはアスクプライス、ショートはビッドプライスで行っています。

今、slとtpをハードコーディングしてみました。

ただ、何時間も完璧にBuy and Sellして、その後止まるのが不思議です。

price_ask = mt5.symbol_info_tick(symbol).ask # Buying    

####################

##cONDITION FOR buy

if close_past < close_current and position_type(symbol) != 0 or position_type(symbol) == None:
        mt5.Close(symbol)
        buy(symbol, lot, price_ask, point, digits)
        print('{} LONG Postition bought!'.format(symbol))

####################

##### Function to BUY
def buy(symbol, lot, price, point, digits):
    request_buy = {
        "action": mt5.TRADE_ACTION_DEAL,
        "symbol": symbol,
        "volume": lot,
        "type": mt5.ORDER_TYPE_BUY,
        "price": round(price, digits),
        "sl": round((price - 100 * point),digits),
        "tp": round((price + 300 * point),digits),
        "magic": 234000,
        "comment": "{} Buy.".format(symbol),
        "type_time": mt5.ORDER_TIME_GTC,
        }
    # send a trading request
    result_buy = mt5.order_send(request_buy)
    # check the execution result
    print("1.BUY order send(): by {} {} lots at {}".format(symbol,lot,price));
    if result_buy.retcode != mt5.TRADE_RETCODE_DONE:
        print("2. order_send failed, retcode={}".format(result_buy.retcode))
        # request the result as a dictionary and display it element by element
        result_dict=result_buy._asdict()
        for field in result_dict.keys():
            print("   {}={}".format(field,result_dict[field]))
            # if this is a trading request structure, display it element by element as well
            if field=="request":
                traderequest_dict=result_dict[field]._asdict()
                for tradereq_filed in traderequest_dict:
                    print("       traderequest: {}={}".format(tradereq_filed,traderequest_dict[tradereq_filed]))
    else:
        return result_buy
#########
 
nicholi shen:

スティルは書いている。

if r.retcode != TRADE_RETCODE_REQUOTE and r.retcode != TRADE_RETCODE_PRICE_OFF:
AttributeError: 'NoneType' object has no attribute 'retcode'
.


help worksの例です。
自分の関数で例を使って書いてみました。

if result_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: 'NoneType' オブジェクトには 'retcode' という属性がない

 
IvanDorofeev:

やはり書いてある。

ヘルプにある例で動作します。

私の関数の例を適用すると、こうなります。

ifresult_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: 'NoneType' オブジェクトに 'retcode' 属性がない

result_buy==Noneとなり、値を確認せず、Noneからretcodeを取得しようとしたのですね。

 

MetaTrader5 5.0.31を搭載した新しいMT5-terminalベータ版は、スレッドが完全にロックされるまで、copy_rates_from_pos() の約7700回の呼び出しにしか耐えられない。このバグを実証するために、私はasyncioを使ってタイムアウトを実装しました。タイムアウトはコントロールでは機能しますが、copy_rates_from_posではバグによりスレッドが完全にフリーズしてしまうため、機能しません。

import asyncio
import time

import MetaTrader5 as mt5


async def proof_timeout_works_on_blocking_call():
    loop = asyncio.get_running_loop()
    future = loop.run_in_executor(None, time.sleep, 5.0)
    try:
        await asyncio.wait_for(future, timeout=0.5)
    except asyncio.TimeoutError:
        print("Timeout works as expected for blocking calls!")


async def async_copy_rates(*args, timeout):
    loop = asyncio.get_running_loop()
    future = loop.run_in_executor(None, mt5.copy_rates_from_pos, *args)
    try:
        return await asyncio.wait_for(future, timeout=timeout)
    except asyncio.TimeoutError:
        print(f"async_copy_rates timed out")
        print('mql errors =', *mt5.last_error())
        raise


async def async_last_error():
    loop = asyncio.get_running_loop()
    err = await loop.run_in_executor(None, mt5.last_error)
    return err


async def main():
    await proof_timeout_works_on_blocking_call()
    maxbars = mt5.terminal_info().maxbars
    for i in range(1, maxbars):
        r = await async_copy_rates('EURUSD', mt5.TIMEFRAME_M1, 0, i, timeout=0.5)
        if r is not None:
            print(f'{i} -> {len(r)}')


if __name__ == '__main__':
    mt5.initialize()
    print(mt5.__version__)
    asyncio.run(main())
    mt5.shutdown()
 

接続をシャットダウンして再初期化しても解決しない。

import time

import MetaTrader5 as mt5


def main():
    maxbars = mt5.terminal_info().maxbars
    for i, count in enumerate(range(1000, maxbars), 1):
        for retry in range(5):
            r = mt5.copy_rates_from_pos('EURUSD', mt5.TIMEFRAME_M1, 0, count)
            errno, strerr = mt5.last_error()
            if errno != mt5.RES_S_OK:
                print(strerr)
                print('Reinitialing connection')
                mt5.shutdown()
                time.sleep(1)
                print('Reinitialing connection =', mt5.initialize())
            else:
                print(f"{i} -> {len(r)}")
                break
        else:
            print('maxium retry exceed')
            mt5.shutdown()
            quit()


if __name__ == '__main__':
    mt5.initialize()
    print(mt5.__version__)
    main()
    mt5.shutdown()
 
nicholi shen:

コピー率にバグがあります。何度か投稿したのですが、誰も認めてくれません。

for count in range(maxbars):
    rates = mt5.copy_rates_from_pos('EURUSD', mt5.TIMEFRAME_M1, 0, count)
    errno, strerror = mt5.last_error()
    if errno != mt5.RES_S_OK:
        print(f"Failed on count={count} with strerror={strerror}")
        break

質問:このサイクルは何のためにあるのですか?

 
Vladimir Perervenko:

質問:なぜこのサイクルなのですか?

count "パラメータとしてmaxbarsを要求すると失敗するので、関数を テストするためのユニットテストとして、各反復で要求されたバーの数を増加させる簡単なルーチンを書きました。これは問題なく完了するはずですが、呼べる回数に限りがあることを考えると、信頼性に欠けることになります。

 
nicholi shen:

count "パラメータとしてmaxbarsを要求すると失敗するので、関数を テストするためのユニットテストとして、繰り返しごとに要求されるバーの数を増やす簡単なルーチンを書きました。 これは問題なく完了しますが、有限の回数だけ呼び出せることを考えると、信頼性が低くなります。

この問題は5.0.33で修正され、numpyの配列が自動的に解放されない状態でリリースされました。
 
IvanDorofeev:

スティルは書いている。

if r.retcode != TRADE_RETCODE_REQUOTE and r.retcode != TRADE_RETCODE_PRICE_OFF:
AttributeError: 'NoneType' object has no attribute 'retcode'
.


ヘルプの例
私の関数の例を適用すると、次のようになります。

if result_buy.retcode != mt5.TRADE_RETCODE_DONE:
AttributeError: 'NoneType' オブジェクトには 'retcode' という属性がない

5.0.33にアップデートすると、Buy/Closeスクリプトはそこで修正され、それらはまだNoneとしてエラーを返しますが、例外なしでmt5.last_error()を呼び出してエラーコードを 見ることができます。
 

ckeiderling:

...

mt5.copy_ticks_range () と mt5.copy_rates_range () を使用しても同じ問題が発生します。メモリをクリアするためにカーネルをリセットする必要があるんだ。

...
この問題は5.0.33で修正されました。