aaa
This commit is contained in:
@@ -1,316 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
|
||||
from ccxt.async_support.base.exchange import Exchange
|
||||
from ccxt.abstract.mt5 import ImplicitAPI
|
||||
import asyncio
|
||||
import hashlib
|
||||
from ccxt.base.types import Any, Balances, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, OrderBooks, Trade, TradingFees, Transaction
|
||||
from typing import List
|
||||
from ccxt.base.errors import ExchangeError
|
||||
from ccxt.base.errors import AuthenticationError
|
||||
from ccxt.base.errors import ArgumentsRequired
|
||||
from ccxt.base.errors import InsufficientFunds
|
||||
from ccxt.base.errors import InvalidOrder
|
||||
from ccxt.base.errors import OrderNotFound
|
||||
from ccxt.base.errors import DDoSProtection
|
||||
from ccxt.base.errors import RateLimitExceeded
|
||||
from ccxt.base.errors import ExchangeNotAvailable
|
||||
from ccxt.base.errors import InvalidNonce
|
||||
from ccxt.base.decimal_to_precision import TICK_SIZE
|
||||
from ccxt.base.precise import Precise
|
||||
|
||||
|
||||
class mt5(Exchange, ImplicitAPI):
|
||||
def describe(self) -> Any:
|
||||
return self.deep_extend(super(mt5, self).describe(), {
|
||||
'id': 'mt5',
|
||||
'name': 'MT5',
|
||||
'countries': ['US'],
|
||||
'version': 'v2025.02.05-05.23',
|
||||
'rateLimit': 1000,
|
||||
'hostname': '43.167.188.220:5000',
|
||||
'pro': True,
|
||||
'options': {
|
||||
'host': '18.163.85.196',
|
||||
'port': 443,
|
||||
},
|
||||
'has': {
|
||||
'CORS': True,
|
||||
'spot': True,
|
||||
'margin': True,
|
||||
'swap': True,
|
||||
'future': True,
|
||||
'option': True,
|
||||
'borrowCrossMargin': True,
|
||||
'cancelAllOrders': True,
|
||||
'cancelAllOrdersAfter': True,
|
||||
'cancelOrder': True,
|
||||
'cancelOrders': True,
|
||||
'cancelOrdersForSymbols': True,
|
||||
'closeAllPositions': False,
|
||||
'closePosition': False,
|
||||
'createConvertTrade': True,
|
||||
'createMarketBuyOrderWithCost': True,
|
||||
'createMarketSellOrderWithCost': True,
|
||||
'createOrder': True,
|
||||
'createOrders': True,
|
||||
'createOrderWithTakeProfitAndStopLoss': True,
|
||||
'createPostOnlyOrder': True,
|
||||
'createReduceOnlyOrder': True,
|
||||
'createStopLimitOrder': True,
|
||||
'createStopLossOrder': True,
|
||||
'createStopMarketOrder': True,
|
||||
'createStopOrder': True,
|
||||
'createTakeProfitOrder': True,
|
||||
'createTrailingAmountOrder': True,
|
||||
'createTriggerOrder': True,
|
||||
'editOrder': True,
|
||||
'editOrders': True,
|
||||
'fetchAllGreeks': True,
|
||||
'fetchBalance': True,
|
||||
'fetchBidsAsks': 'emulated',
|
||||
'fetchBorrowInterest': False, # temporarily disabled, doesn't work
|
||||
'fetchBorrowRateHistories': False,
|
||||
'fetchBorrowRateHistory': False,
|
||||
'fetchCanceledAndClosedOrders': True,
|
||||
'fetchCanceledOrders': True,
|
||||
'fetchClosedOrder': True,
|
||||
'fetchClosedOrders': True,
|
||||
'fetchConvertCurrencies': True,
|
||||
'fetchConvertQuote': True,
|
||||
'fetchConvertTrade': True,
|
||||
'fetchConvertTradeHistory': True,
|
||||
'fetchCrossBorrowRate': True,
|
||||
'fetchCrossBorrowRates': False,
|
||||
'fetchCurrencies': True,
|
||||
'fetchDeposit': False,
|
||||
'fetchDepositAddress': True,
|
||||
'fetchDepositAddresses': False,
|
||||
'fetchDepositAddressesByNetwork': True,
|
||||
'fetchDeposits': True,
|
||||
'fetchDepositWithdrawFee': 'emulated',
|
||||
'fetchDepositWithdrawFees': True,
|
||||
'fetchFundingHistory': True,
|
||||
'fetchFundingRate': 'emulated', # emulated in exchange
|
||||
'fetchFundingRateHistory': True,
|
||||
'fetchFundingRates': True,
|
||||
'fetchGreeks': True,
|
||||
'fetchIndexOHLCV': True,
|
||||
'fetchIsolatedBorrowRate': False,
|
||||
'fetchIsolatedBorrowRates': False,
|
||||
'fetchLedger': True,
|
||||
'fetchLeverage': True,
|
||||
'fetchLeverageTiers': True,
|
||||
'fetchLongShortRatio': False,
|
||||
'fetchLongShortRatioHistory': True,
|
||||
'fetchMarginAdjustmentHistory': False,
|
||||
'fetchMarketLeverageTiers': True,
|
||||
'fetchMarkets': True,
|
||||
'fetchMarkOHLCV': True,
|
||||
'fetchMyLiquidations': True,
|
||||
'fetchMySettlementHistory': True,
|
||||
'fetchMyTrades': True,
|
||||
'fetchOHLCV': True,
|
||||
'fetchOpenInterest': True,
|
||||
'fetchOpenInterestHistory': True,
|
||||
'fetchOpenOrder': True,
|
||||
'fetchOpenOrders': True,
|
||||
'fetchOption': True,
|
||||
'fetchOptionChain': True,
|
||||
'fetchOrder': True,
|
||||
'fetchOrderBook': True,
|
||||
'fetchOrders': False,
|
||||
'fetchOrderTrades': True,
|
||||
'fetchPosition': True,
|
||||
'fetchPositionHistory': 'emulated',
|
||||
'fetchPositions': True,
|
||||
'fetchPositionsHistory': True,
|
||||
'fetchPremiumIndexOHLCV': True,
|
||||
'fetchSettlementHistory': True,
|
||||
'fetchTicker': True,
|
||||
'fetchTickers': True,
|
||||
'fetchTime': True,
|
||||
'fetchTrades': True,
|
||||
'fetchTradingFee': True,
|
||||
'fetchTradingFees': True,
|
||||
'fetchTransactions': False,
|
||||
'fetchTransfers': True,
|
||||
'fetchUnderlyingAssets': False,
|
||||
'fetchVolatilityHistory': True,
|
||||
'fetchWithdrawals': True,
|
||||
'repayCrossMargin': True,
|
||||
'sandbox': True,
|
||||
'setLeverage': True,
|
||||
'setMarginMode': True,
|
||||
'setPositionMode': True,
|
||||
'transfer': True,
|
||||
'withdraw': True,
|
||||
},
|
||||
'timeframes': {
|
||||
'1m': 1,
|
||||
'5m': 5,
|
||||
'15m': 15,
|
||||
'30m': 30,
|
||||
'1h': 60,
|
||||
'4h': 240,
|
||||
'1d': 1440,
|
||||
'1w': 10080,
|
||||
'1M': 43200,
|
||||
},
|
||||
'urls': {
|
||||
'logo': '',
|
||||
'api': {
|
||||
'public': 'http://{hostname}',
|
||||
'private': 'http://{hostname}',
|
||||
},
|
||||
'www': 'http://{hostname}',
|
||||
'doc': ['http://{hostname}/index.html'],
|
||||
},
|
||||
'api': {
|
||||
'public': {
|
||||
'get': {
|
||||
'Ping': 1
|
||||
},
|
||||
},
|
||||
'private': {
|
||||
'get': {
|
||||
'Connect': 10,
|
||||
'CheckConnect': 1,
|
||||
'Disconnect': 1,
|
||||
'Symbols': 1,
|
||||
'ServerTimezone':1,
|
||||
'AccountSummary': 1,
|
||||
'AccountDetails': 1,
|
||||
'SymbolList': 1,
|
||||
'GetQuote': 1,
|
||||
'GetQuoteMany': 1,
|
||||
'MarketWatchMany': 1,
|
||||
'OpenedOrders': 1,
|
||||
'ClosedOrders': 1,
|
||||
'OpenedOrder': 1,
|
||||
'OrderHistory': 1,
|
||||
'PriceHistory': 1,
|
||||
'OrderSend': 1,
|
||||
'OrderModify': 1,
|
||||
'OrderClose': 1,
|
||||
},
|
||||
},
|
||||
'wsEndpoint': {
|
||||
'order': "OnOrderUpdate",
|
||||
'quote': "OnQuote",
|
||||
'orderbook': "OnOrderBook",
|
||||
}
|
||||
},
|
||||
'requiredCredentials': {
|
||||
'apiKey': True,
|
||||
'secret': True,
|
||||
'hostname': True,
|
||||
},
|
||||
'commonCurrencies': {},
|
||||
'exceptions': {
|
||||
'exact': {
|
||||
'Invalid token': AuthenticationError,
|
||||
'Connection failed': ExchangeError,
|
||||
'Invalid symbol': ExchangeError,
|
||||
'Invalid order': InvalidOrder,
|
||||
'Order not found': OrderNotFound,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
async def get_token(self):
|
||||
"""获取或刷新 token - 异步版本"""
|
||||
if self.token and self.token_checked:
|
||||
try:
|
||||
await self.check_connect()
|
||||
return self.token
|
||||
except Exception:
|
||||
# Token 无效,重新连接
|
||||
pass
|
||||
|
||||
# 重新连接获取 token
|
||||
return await self.connect()
|
||||
|
||||
async def connect(self):
|
||||
"""连接到 MT5 账户并获取 token - 异步版本"""
|
||||
request = {
|
||||
'user': self.apiKey,
|
||||
'password': self.secret,
|
||||
'host': self.options['host'],
|
||||
'port': self.options['port'],
|
||||
'connectTimeoutSeconds': 30,
|
||||
}
|
||||
|
||||
print(f"🔧 Debug: Connect request params: {request}")
|
||||
|
||||
response = await self.private_get_connect(request)
|
||||
|
||||
print(f"🔧 Debug: Connect response: {response}")
|
||||
|
||||
self.token = response
|
||||
self.token_checked = True
|
||||
return self.token
|
||||
|
||||
async def check_connect(self):
|
||||
"""检查连接状态 - 异步版本"""
|
||||
request = {
|
||||
'id': await self.get_token(),
|
||||
}
|
||||
return await self.private_get_check_connect(request)
|
||||
|
||||
|
||||
async def fetch_markets(self, params={}):
|
||||
"""获取交易对列表"""
|
||||
|
||||
if not self.token:
|
||||
await self.get_token()
|
||||
request = {
|
||||
'id': self.token,
|
||||
}
|
||||
response = await self.private_get_symbols(self.deep_extend(request, params))
|
||||
|
||||
markets = []
|
||||
if isinstance(response, dict):
|
||||
for symbol, info in response.items():
|
||||
market = self.parse_market(info)
|
||||
if market:
|
||||
markets.append(market)
|
||||
|
||||
return markets
|
||||
|
||||
def parse_market(self, info):
|
||||
"""解析市场信息 - 根据 SymbolInfo 结构修正"""
|
||||
symbol = info.get('currency', '').upper()
|
||||
if not symbol:
|
||||
return None
|
||||
|
||||
return {
|
||||
'id': symbol,
|
||||
'symbol': symbol,
|
||||
'base': symbol[:3] if len(symbol) >= 6 else symbol,
|
||||
'quote': symbol[3:] if len(symbol) >= 6 else 'USD',
|
||||
'active': True,
|
||||
'precision': {
|
||||
'price': info.get('digits', 5),
|
||||
'amount': 2,
|
||||
},
|
||||
'limits': {
|
||||
'amount': {
|
||||
'min': 0.01,
|
||||
'max': None,
|
||||
},
|
||||
'price': {
|
||||
'min': None,
|
||||
'max': None,
|
||||
},
|
||||
'cost': {
|
||||
'min': None,
|
||||
'max': None,
|
||||
},
|
||||
},
|
||||
'info': info,
|
||||
}
|
||||
Reference in New Issue
Block a user