A JavaScript framework to easily operate in global financial markets.
Mida is designed to:
- Trade financial assets such as stocks, crypto, forex or commodities;
- Operate with any broker and exchange using only JavaScript/TypeScript;
- Automate and backtest trading strategies through expert advisors;
- Analyze markets and prices with indicators and analysis interfaces.
Furthermore, Mida is free and open source, join the Discord community.
The easiest way to start out with Mida is cloning the sample project.
git clone https://github.com/Reiryoku-Technologies/Mida-Boilerplate.git
The sample project contains an example of broker login and ticks listener.
How to login into a MetaTrader 5 broker account.
const { MidaBroker } = require("@reiryoku/mida");
const myAccount = await MidaBroker.login("MT5", {
id: "foo",
password: "bar",
serverName: "FooBar",
});
How to login into an independent broker account.
const { MidaBroker } = require("@reiryoku/mida");
const myAccount = await MidaBroker.login("ICMarkets", {
email: "[email protected]",
id: "foo",
password: "bar",
});
More examples
How to login into a MetaTrader 5 broker account with errors handler.
const {
MidaBroker,
MidaBrokerErrorType,
} = require("@reiryoku/mida");
let myAccount;
try {
myAccount = await MidaBroker.login("MT5", {
id: "foo",
password: "bar",
serverName: "FooBar",
});
}
catch (error) {
switch (error.type) {
case MidaBrokerErrorType.INVALID_LOGIN_CREDENTIALS:
console.log("The login credentials are wrong!");
break;
case MidaBrokerErrorType.TIMEOUT:
console.log("The MetaTrader 5 servers failed to respond!");
break;
}
}
How top open a long position for Bitcoin against USD.
const { MidaBrokerOrderType } = require("@reiryoku/mida");
const myOrder = await myAccount.placeOrder({
symbol: "BTCUSD",
type: MidaBrokerOrderType.BUY,
lots: 1,
});
console.log(myOrder.ticket);
console.log(myOrder.openPrice);
How to open a short position for EUR against USD.
const { MidaBrokerOrderType } = require("@reiryoku/mida");
const myOrder = await myAccount.placeOrder({
symbol: "EURUSD",
type: MidaBrokerOrderType.SELL,
lots: 0.1,
});
console.log(myOrder.ticket);
console.log(myOrder.openPrice);
More examples
How to open a short position for Apple stocks with errors handler.
const {
MidaBrokerOrderType,
MidaBrokerErrorType,
} = require("@reiryoku/mida");
let myOrder;
try {
myOrder = await myAccount.placeOrder({
symbol: "#AAPL",
type: MidaBrokerOrderType.SELL,
lots: 1,
});
}
catch (error) {
switch (error.type) {
case MidaBrokerErrorType.MARKET_CLOSED:
console.log("#AAPL market is closed!");
break;
case MidaBrokerErrorType.NOT_ENOUGH_MONEY:
console.log("You don't have enough money in your account!");
break;
case MidaBrokerErrorType.INVALID_SYMBOL:
console.log("Your broker account doesn't support trading Apple stocks.");
break;
}
}
In case you don't want to handle errors you can use tryPlaceOrder
which returns undefined
in case of error.
const myOrder = await myAccount.tryPlaceOrder({
symbol: "#AAPL",
type: MidaBrokerOrderType.SELL,
lots: 1,
});
if (!myOrder) {
console.log("Order not placed.");
}
In addition, canPlaceOrder
or getPlaceOrderObstacles
can be used to know if an order can be placed without errors.
Due to the high volatility of financial markets, these methods can't guarantee that the order is going to be placed without errors being thrown.
const orderDirectives = {
symbol: "#AAPL",
type: MidaBrokerOrderType.SELL,
lots: 1,
};
// => true | false
const canPlaceOrder = await myAccount.canPlaceOrder(orderDirectives);
// => MidaBrokerErrorType[]
const placeOrderObstacles = await myAccount.getPlaceOrderObstacles(orderDirectives);
if (placeOrderObstacles.includes(MidaBrokerErrorType.MARKET_CLOSED)) {
console.log("#AAPL market is closed!");
}
if (placeOrderObstacles.includes(MidaBrokerErrorType.NOT_ENOUGH_MONEY)) {
console.log("You don't have enough money in your account!");
}
How to open a long position for GBP against USD with stop loss and take profit.
const { MidaBrokerOrderType } = require("@reiryoku/mida");
const symbol = "GBPUSD";
const lastTick = await myAccount.getSymbolLastTick(symbol);
const myOrder = await myAccount.placeOrder({
symbol,
type: MidaBrokerOrderType.BUY,
lots: 0.1,
stopLoss: lastTick.bid - 0.0010, // <= SL 10 pips
takeProfit: lastTick.bid + 0.0030, // <= TP 30 pips
});
How to retrieve a symbol.
const symbol = await myAccount.getSymbol("#AAPL");
if (!symbol) {
console.log("Apple stocks are not available for this account!");
}
else {
console.log(symbol.digits);
console.log(symbol.leverage);
}
How to get the price of a symbol.
const symbol = await myAccount.getSymbol("BTCUSD");
const price = await symbol.getBid();
console.log(`Bitcoin price is ${price} dollars.`);
How to listen the ticks of a symbol.
const symbol = await myAccount.getSymbol("#GME");
symbol.on("tick", (event) => {
const tick = event.descriptor.tick;
console.log(`GameStop share price is now ${tick.bid} dollars.`);
});
How to create an expert advisor.
const {
MidaExpertAdvisor,
MidaTimeframeType,
} = require("@reiryoku/mida");
class MyExpertAdvisor extends MidaExpertAdvisor {
constructor (brokerAccount) {
super({ brokerAccount, });
}
async configure () {
this.watchSymbol("EURUSD");
}
async onTick (tick) {
// Implement your strategy.
}
async onPeriod (period) {
if (period.timeframe === MidaTimeframeType.H1) {
console.log(`New H1 candlestick with open price => ${period.open}.`);
}
}
}
How to execute an expert advisor.
const { MidaBroker } = require("@reiryoku/mida");
const { MyExpertAdvisor } = require("./my-expert-advisor");
const myAccount = await MidaBroker.login(/* ... */);
const myAdvisor = new MyExpertAdvisor({ brokerAccount: myAccount, });
myAdvisor.on("order-open", (event) => console.log(`New order opened with ticket => ${event.descriptor.ticket}`));
myAdvisor.start();
Examples of technical market analysis.
How to get the candlesticks of a symbol (in the code candlesticks and bars are generally referred as periods).
const { MidaTimeframeType } = require("@reiryoku/mida");
const periods = await myAccount.getSymbolPeriods("EURUSD", MidaTimeframeType.M30);
const lastPeriod = periods[periods.length - 1];
console.log("Last candlestick start time: " + lastPeriod.startTime);
console.log("Last candlestick OHLC: " + lastPeriod.ohlc);
console.log("Last candlestick close price: " + lastPeriod.close);
How to calculate the RSI indicator for Bitcoin on H1 chart.
const {
MidaIndicator,
MidaTimeframeType,
} = require("@reiryoku/mida");
const periods = await myAccount.getSymbolPeriods("BTCUSD", MidaTimeframeType.H1);
const relativeStrengthIndex = await MidaIndicator.calculate("RSI", {
prices: periods.map((period) => period.close),
length: 14,
});
How to calculate the Bollinger Bands indicator for Ethereum on M5 chart.
const {
MidaIndicator,
MidaTimeframeType,
} = require("@reiryoku/mida");
const periods = await myAccount.getSymbolPeriods("ETHUSD", MidaTimeframeType.M5);
const bollingerBands = await MidaIndicator.calculate("BollingerBands", {
prices: periods.map((period) => period.close),
length: 20,
});
Playground is a local broker created for paper trading and backtesting. To use Playground first add the plugin to your dependencies.
{
"dependencies": {
"@reiryoku/mida": "1.0.0",
"@reiryoku/mida-playground": "1.0.0"
}
}
const {
Mida,
MidaBroker,
} = require("@reiryoku/mida");
// Use the Mida Playground plugin.
Mida.use(require("@reiryoku/mida-playground"));
const myAccount = await MidaBroker.login("Playground", {
id: "test", // The account id.
localDate: new Date("2020-04-23"), // The broker local date.
currency: "USD", // The account currency.
balance: 10000, // The account initial balance.
negativeBalanceProtection: true,
});
// Used to listen any market ticks.
myAccount.on("tick", (event) => {
const tick = event.descriptor.tick;
console.log(`New tick for ${tick.symbol} => ${tick.bid} | ${tick.ask}`);
});
// Used to elapse a given amount of time in the local date, this will trigger ticks.
await myAccount.elapseTime(60 * 10); // 60 seconds * 10 = 10 minutes.
console.log(myAccount.localDate); // The local date is now 2020-04-23 00:10:00.
If you have created an expert advisor, you can easily backtest it by just assigning the playground broker to it.
import { MyExpertAdvisor } from "./my-expert-advisor";
const myAdvisor = new MyExpertAdvisor({ brokerAccount: myAccount, });
await myAdvisor.start();
await myAccount.elapseTime(60 * 60 * 24); // Elapse 1 hour, this will trigger ticks and candles.
console.log(myAdvisor.orders); // The orders created by the EA in one hour.
Operating in CFDs/Forex is highly speculative and carries a high level of risk. It's possible to lose all your capital. These products may not be suitable for everyone, you should ensure that you understand the risks involved. Furthermore, Mida is not responsible for commissions or other taxes applied to your operations, they depend on your broker, and any technical inconvenience that may lead to money loss, for example a stop loss not being set.
Nowadays MQL is a procedural technology and a barrier between modern traders and algorithmic trading. The mission of Mida is allowing anyone to operate in financial markets without advanced programming skills or specific computer requirements. Furthermore, Mida allows operating with MetaTrader accounts without installing MetaTrader (which is available only for Windows OS).
The author and maintainer of the project is Vasile Pește ([email protected]).