Files
Nguyen Viet Tuan 6230ed4e3d Add files via upload
2022-07-04 22:39:17 +07:00

208 lines
6.5 KiB
Python

import MetaTrader5 as mt5
import pandas as pd
import numpy as np
import math
import argparse
import configparser
from envs.real_net_env import RealNetEnv, RealNetController
from envs.functions import getState, formatPrice
from agents.models import MA2C
from utils import Predictor
SYMBOL = "EURUSD"
DEVIATION = 20
TIMEFRAME = mt5.TIMEFRAME_H4
VOLUME = 0.03
PERIOD = 11
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('--config-dir', type=str, required=False,
default='config_ma2c_real.ini', help="inference config dir")
parser.add_argument('--port', type=int, required=False,
default=0, help="running port")
parser.add_argument('--policy-type', type=str, required=False, default='default',
help="inference policy type in evaluation: default, stochastic, or deterministic")
parser.add_argument('--position-type', type=dict, required=False,
default={'long': 1, 'short': -1}, help="types of position")
args = parser.parse_args()
return args
def market_order(symbol, volume, order_type):
tick = mt5.symbol_info_tick(symbol)
order_dict = {'long': 0, 'short': 1}
price_dict = {'long': tick.ask, 'short': tick.bid}
request = {
"action": mt5.TRADE_ACTION_DEAL,
"symbol": symbol,
"volume": volume,
"type": order_dict[order_type],
"price": price_dict[order_type],
"deviation": DEVIATION,
"magic": 100,
"comment": "python market order",
"type_time": mt5.ORDER_TIME_GTC,
"type_filling": mt5.ORDER_FILLING_IOC,
}
order_result = mt5.order_send(request)
print(order_result)
return order_result
# function to close an order base don ticket id
def close_order(ticket):
positions = mt5.positions_get()
for pos in positions:
tick = mt5.symbol_info_tick(pos.symbol)
# 0 represents buy, 1 represents sell - inverting order_type to close the position
type_dict = {0: 1, 1: 0}
price_dict = {0: tick.ask, 1: tick.bid}
if pos.ticket == ticket:
request = {
"action": mt5.TRADE_ACTION_DEAL,
"position": pos.ticket,
"symbol": pos.symbol,
"volume": pos.volume,
"type": type_dict[pos.type],
"price": price_dict[pos.type],
"deviation": DEVIATION,
"magic": 100,
"comment": "python close order",
"type_time": mt5.ORDER_TIME_GTC,
"type_filling": mt5.ORDER_FILLING_IOC,
}
order_result = mt5.order_send(request)
print(order_result)
return order_result
return 'Ticket does not exist'
def sigmoid(x):
return 1 / (1 + math.exp(-x))
def _norm_clip_state(x, norm, clip=-1):
x = x / norm
return x if clip < 0 else np.clip(x, 0, clip)
def getState(symbol, timeframe, period, index=1000):
bars = mt5.copy_rates_from_pos(symbol, timeframe, 1, period)
bars_df = pd.DataFrame(bars)
vec = bars_df.close.tolist()
vec = [x*index for x in vec]
res = []
for i in range(period - 1):
res.append(sigmoid(vec[i + 1] - vec[i]))
return np.array(res)
def init_env(config, port=1, naive_policy=False):
if not naive_policy:
return RealNetEnv(config, port=port)
else:
env = RealNetEnv(config, port=port)
policy = RealNetController(env.node_names, env.nodes)
return env, policy
def data_preprocessing(cur_state, norm, clip, agents):
# hard code the state ordering as wave, wait, fp
state = []
# measure the most recent state
norm_cur_state = _norm_clip_state(cur_state, norm, clip)
# get the appropriate state vectors
for _ in agents:
# wave is required in state
cur_state = [norm_cur_state]
state.append(np.concatenate(cur_state))
return state
def main(args):
config_dir = args.config_dir
port = args.port
policy_type = args.policy_type
agent_type = args.position_type
# initialize start value
inventory = {}
open_ticket = {}
for agent in [*agent_type]:
inventory[agent] = []
open_ticket[agent] = []
total_profit = 0
balance_list = []
pre_state = np.array([])
# load config file for env
config = configparser.ConfigParser()
config.read(config_dir)
cur_balance = config['ENV_CONFIG'].getint('balance')
norm = config['ENV_CONFIG'].getfloat('norm_wave')
clip = config['ENV_CONFIG'].getfloat('clip_wave')
# init env
env = init_env(config['ENV_CONFIG'], port)
# load model for agent
# init centralized or multi agent
model = MA2C(env.n_s_ls, env.n_a_ls, env.n_w_ls,
env.n_f_ls, 0, config['MODEL_CONFIG'])
model.load('weights/')
model.reset()
# collect evaluation data
predictor = Predictor(env, model, policy_type=policy_type)
# init mt5
mt5.initialize()
while True:
cur_state = getState(symbol=SYMBOL, timeframe=TIMEFRAME,
period=PERIOD)
if not np.array_equal(cur_state, pre_state):
state = data_preprocessing(cur_state, norm, clip, [*agent_type])
action = predictor.run(state)
print('---ACTION--- :', action)
tick = mt5.symbol_info_tick(SYMBOL)
price_dict = {'long': tick.ask, 'short': tick.bid}
for agent, a in zip([*agent_type], list(action)):
if a == 1:
market_order(SYMBOL, VOLUME, agent)
inventory[agent].append(price_dict[agent])
open_ticket[agent].append(mt5.positions_get()[-1].ticket)
elif a == 2 and len(inventory[agent]) > 0:
close_order(open_ticket[agent].pop(0))
order_price = inventory[agent].pop(0)
profit = (price_dict[agent] - order_price) * \
agent_type[agent] * VOLUME * 100000
total_profit += profit
cur_balance += profit
balance_list.append(round(cur_balance, 2))
print("--------------------------------")
print("Total Profit: " + formatPrice(total_profit))
print('Curent Balance: ' + formatPrice(cur_balance))
print('Balance List', balance_list)
print("--------------------------------")
pre_state = cur_state
if __name__ == '__main__':
args = parse_args()
main(args)