Skip to content

Commit

Permalink
#15 added high freq trading mode tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Guillaume De Saint Martin committed Jul 1, 2018
1 parent 612442d commit 3199465
Show file tree
Hide file tree
Showing 2 changed files with 310 additions and 171 deletions.
214 changes: 43 additions & 171 deletions tests/Trading/Mode/test_daily_trading_mode_creator.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import copy

import ccxt

from config.cst import EvaluatorStates
from config.cst import ExchangeConstantsMarketStatusColumns as Ecmsc
from tests.unit_tests.trading_modes_tests.trading_mode_test_toolkit import check_order_limits, check_linked_order, \
check_orders, check_portfolio, fill_orders
from tests.test_utils.config import load_test_config
from trading.exchanges.exchange_manager import ExchangeManager
from trading.trader.modes import DailyTradingModeCreator
Expand Down Expand Up @@ -121,52 +121,6 @@ def test_can_create_order_unknown_symbols():
EvaluatorStates.NEUTRAL, portfolio)


def _check_order_limits(order, market_status):
symbol_market_limits = market_status[Ecmsc.LIMITS.value]
limit_amount = symbol_market_limits[Ecmsc.LIMITS_AMOUNT.value]
limit_cost = symbol_market_limits[Ecmsc.LIMITS_COST.value]
limit_price = symbol_market_limits[Ecmsc.LIMITS_PRICE.value]

min_quantity = limit_amount[Ecmsc.LIMITS_AMOUNT_MIN.value]
max_quantity = limit_amount[Ecmsc.LIMITS_AMOUNT_MAX.value]
min_cost = limit_cost[Ecmsc.LIMITS_COST_MIN.value]
max_cost = limit_cost[Ecmsc.LIMITS_COST_MAX.value]
min_price = limit_price[Ecmsc.LIMITS_PRICE_MIN.value]
max_price = limit_price[Ecmsc.LIMITS_PRICE_MAX.value]
maximal_price_digits = market_status[Ecmsc.PRECISION.value][Ecmsc.PRECISION_PRICE.value]
maximal_volume_digits = market_status[Ecmsc.PRECISION.value][Ecmsc.PRECISION_AMOUNT.value]
order_cost = order.origin_price*order.origin_quantity

assert order_cost <= max_cost
assert order_cost >= min_cost
assert order.origin_price <= max_price
assert order.origin_price >= min_price
assert str(order.origin_price)[::-1].find(".") <= maximal_price_digits
assert order.origin_quantity <= max_quantity
assert order.origin_quantity >= min_quantity
assert str(order.origin_quantity)[::-1].find(".") <= maximal_volume_digits


def _check_linked_order(order, linked_order, order_type, order_price, market_status):
assert linked_order.exchange == order.exchange
assert linked_order.trader == order.trader
assert linked_order.order_notifier == order.order_notifier
assert linked_order.order_type == order_type
assert linked_order.created_last_price == order.created_last_price
assert linked_order.origin_price == order_price
assert linked_order.linked_orders[0] == order
assert linked_order.created_last_price == order.created_last_price
assert linked_order.currency == order.currency
assert linked_order.currency_total_fees == order.currency_total_fees
assert linked_order.market_total_fees == order.market_total_fees
assert linked_order.filled_price == order.filled_price
assert linked_order.filled_quantity == order.filled_quantity
assert linked_order.linked_to == order
assert linked_order.status == order.status
assert linked_order.symbol == order.symbol
_check_order_limits(order, market_status)


def test_valid_create_new_order():
config, exchange, trader, symbol = _get_tools()
portfolio = trader.get_portfolio()
Expand Down Expand Up @@ -206,10 +160,10 @@ def test_valid_create_new_order():
assert order.is_simulated is True
assert order.linked_to is None

_check_order_limits(order, market_status)
check_order_limits(order, market_status)

assert len(order.linked_orders) == 1
_check_linked_order(order, order.linked_orders[0], TraderOrderType.STOP_LOSS, 6595.8595, market_status)
check_linked_order(order, order.linked_orders[0], TraderOrderType.STOP_LOSS, 6595.8595, market_status)

# valid buy limit order with (price and quantity adapted)
orders = order_creator.create_new_order(-0.65, symbol, exchange, trader, portfolio, EvaluatorStates.LONG)
Expand All @@ -233,7 +187,7 @@ def test_valid_create_new_order():
assert order.is_simulated is True
assert order.linked_to is None

_check_order_limits(order, market_status)
check_order_limits(order, market_status)

# assert len(order.linked_orders) == 1 # check linked orders when it will be developed

Expand All @@ -259,7 +213,7 @@ def test_valid_create_new_order():
assert order.is_simulated is True
assert order.linked_to is None

_check_order_limits(order, market_status)
check_order_limits(order, market_status)

# valid buy market order with (price and quantity adapted)
orders = order_creator.create_new_order(1, symbol, exchange, trader, portfolio, EvaluatorStates.VERY_SHORT)
Expand All @@ -283,7 +237,7 @@ def test_valid_create_new_order():
assert order.is_simulated is True
assert order.linked_to is None

_check_order_limits(order, market_status)
check_order_limits(order, market_status)


def test_invalid_create_new_order():
Expand Down Expand Up @@ -368,10 +322,10 @@ def test_split_create_new_order():
assert adapted_order.is_simulated is True
assert adapted_order.linked_to is None

_check_order_limits(adapted_order, market_status)
check_order_limits(adapted_order, market_status)

assert len(adapted_order.linked_orders) == 1
_check_linked_order(adapted_order, adapted_order.linked_orders[0], TraderOrderType.STOP_LOSS, 6595.8595, market_status)
check_linked_order(adapted_order, adapted_order.linked_orders[0], TraderOrderType.STOP_LOSS, 6595.8595, market_status)

for order in identical_orders:
assert isinstance(order, SellLimitOrder)
Expand All @@ -394,8 +348,8 @@ def test_split_create_new_order():
assert order.linked_to == adapted_order.linked_to
assert len(order.linked_orders) == 1

_check_order_limits(order, market_status)
_check_linked_order(order, order.linked_orders[0], TraderOrderType.STOP_LOSS, 6595.8595, market_status)
check_order_limits(order, market_status)
check_linked_order(order, order.linked_orders[0], TraderOrderType.STOP_LOSS, 6595.8595, market_status)

trader.portfolio.portfolio["USDT"] = {
Portfolio.TOTAL: 20000000000,
Expand Down Expand Up @@ -428,7 +382,7 @@ def test_split_create_new_order():
assert adapted_order.is_simulated is True
assert adapted_order.linked_to is None

_check_order_limits(adapted_order, market_status)
check_order_limits(adapted_order, market_status)

# assert len(order.linked_orders) == 1 # check linked orders when it will be developed

Expand All @@ -452,7 +406,7 @@ def test_split_create_new_order():
assert order.is_simulated == adapted_order.is_simulated
assert order.linked_to == adapted_order.linked_to

_check_order_limits(order, market_status)
check_order_limits(order, market_status)

# assert len(order.linked_orders) == 1 # check linked orders when it will be developed

Expand Down Expand Up @@ -481,77 +435,6 @@ def _reset_portfolio(portfolio):
}


def _check_orders(orders, evaluation, state, nb_orders, market_status):

if state == EvaluatorStates.NEUTRAL:
assert orders is None
else:
if math.isnan(evaluation):
assert orders is None
elif math.isnan(evaluation):
assert orders is None
elif state not in EvaluatorStates:
assert orders is None
else:
assert (not orders and nb_orders == 0) or (len(orders) == nb_orders) \
or ((len(orders) == 0 or len(orders) == 1) and nb_orders == "unknown")
if orders:
order = orders[0]
assert order.status == OrderStatus.OPEN
assert order.is_simulated is True
assert order.linked_to is None
assert order.currency_total_fees == 0
assert order.market_total_fees == 0
assert order.filled_price == 0
assert order.filled_quantity == order.origin_quantity

if state == EvaluatorStates.VERY_SHORT:
assert isinstance(order, SellMarketOrder)
assert order.side == TradeOrderSide.SELL
assert order.order_type == TraderOrderType.SELL_MARKET
elif state == EvaluatorStates.SHORT:
assert isinstance(order, SellLimitOrder)
assert order.side == TradeOrderSide.SELL
assert order.order_type == TraderOrderType.SELL_LIMIT
elif state == EvaluatorStates.VERY_LONG:
assert isinstance(order, BuyMarketOrder)
assert order.side == TradeOrderSide.BUY
assert order.order_type == TraderOrderType.BUY_MARKET
elif state == EvaluatorStates.LONG:
assert isinstance(order, BuyLimitOrder)
assert order.side == TradeOrderSide.BUY
assert order.order_type == TraderOrderType.BUY_LIMIT

_check_order_limits(order, market_status)


def _check_portfolio(portfolio, initial_portfolio, orders, only_positivity=False):
if orders:
orders_market_amount = 0
orders_currency_amount = 0
market = orders[0].market
order_symbol = orders[0].currency
for order in orders:
assert order.market == market
assert order.currency == order_symbol
if order.side == TradeOrderSide.BUY:
orders_market_amount += order.origin_quantity * order.origin_price
else:
orders_currency_amount += order.origin_quantity
for symbol in portfolio.portfolio:
assert portfolio.portfolio[symbol][Portfolio.TOTAL] >= 0
assert portfolio.portfolio[symbol][Portfolio.AVAILABLE] >= 0
if not only_positivity:
if order_symbol == symbol:
assert initial_portfolio[symbol][Portfolio.TOTAL] == portfolio.portfolio[symbol][Portfolio.TOTAL]
assert "{:f}".format(initial_portfolio[symbol][Portfolio.AVAILABLE] - orders_currency_amount) \
== "{:f}".format(portfolio.portfolio[symbol][Portfolio.AVAILABLE])
elif market == symbol:
assert initial_portfolio[market][Portfolio.TOTAL] == portfolio.portfolio[market][Portfolio.TOTAL]
assert "{:f}".format(initial_portfolio[market][Portfolio.AVAILABLE] - orders_market_amount) \
== "{:f}".format(portfolio.portfolio[market][Portfolio.AVAILABLE])


def test_create_order_using_a_lot_of_different_inputs_with_portfolio_reset():
config, exchange, trader, symbol = _get_tools()
portfolio = trader.get_portfolio()
Expand All @@ -568,44 +451,33 @@ def test_create_order_using_a_lot_of_different_inputs_with_portfolio_reset():
_reset_portfolio(portfolio)
# orders are possible
orders = order_creator.create_new_order(evaluation, symbol, exchange, trader, portfolio, state)
_check_orders(orders, evaluation, state, nb_orders, market_status)
_check_portfolio(portfolio, initial_portfolio, orders)
check_orders(orders, evaluation, state, nb_orders, market_status)
check_portfolio(portfolio, initial_portfolio, orders)
# orders are impossible
orders = order_creator.create_new_order(evaluation, min_trigger_market, exchange, trader, portfolio, state)
_check_orders(orders, evaluation, state, 0, market_status)
_check_portfolio(portfolio, initial_portfolio, orders)
check_orders(orders, evaluation, state, 0, market_status)
check_portfolio(portfolio, initial_portfolio, orders)

for evaluation in _get_irrationnal_numbers():
# orders are possible
_reset_portfolio(portfolio)
orders = order_creator.create_new_order(evaluation, symbol, exchange, trader, portfolio, state)
_check_orders(orders, evaluation, state, nb_orders, market_status)
_check_portfolio(portfolio, initial_portfolio, orders)
check_orders(orders, evaluation, state, nb_orders, market_status)
check_portfolio(portfolio, initial_portfolio, orders)
# orders are impossible
orders = order_creator.create_new_order(evaluation, min_trigger_market, exchange, trader, portfolio, state)
_check_orders(orders, evaluation, state, 0, market_status)
_check_portfolio(portfolio, initial_portfolio, orders)
check_orders(orders, evaluation, state, 0, market_status)
check_portfolio(portfolio, initial_portfolio, orders)

_reset_portfolio(portfolio)
# orders are possible
orders = order_creator.create_new_order(math.nan, symbol, exchange, trader, portfolio, state)
_check_orders(orders, math.nan, state, nb_orders, market_status)
_check_portfolio(portfolio, initial_portfolio, orders)
check_orders(orders, math.nan, state, nb_orders, market_status)
check_portfolio(portfolio, initial_portfolio, orders)
# orders are impossible
orders = order_creator.create_new_order(math.nan, min_trigger_market, exchange, trader, portfolio, state)
_check_orders(orders, math.nan, state, 0, market_status)
_check_portfolio(portfolio, initial_portfolio, orders)


def _fill_orders(orders, trader):
if orders:
assert trader.get_order_manager().order_list
for order in orders:
order.filled_price = order.origin_price
order.filled_quantity = order.origin_quantity
trader.notify_order_close(order)
_check_portfolio(trader.portfolio, None, orders, True)
assert len(trader.get_order_manager().order_list) == 0
check_orders(orders, math.nan, state, 0, market_status)
check_portfolio(portfolio, initial_portfolio, orders)


def test_create_order_using_a_lot_of_different_inputs_without_portfolio_reset():
Expand All @@ -624,40 +496,40 @@ def test_create_order_using_a_lot_of_different_inputs_without_portfolio_reset():
for evaluation in _get_evaluations_gradient(gradient_step):
# orders are possible
orders = order_creator.create_new_order(evaluation, symbol, exchange, trader, portfolio, state)
_check_orders(orders, evaluation, state, nb_orders, market_status)
_check_portfolio(portfolio, initial_portfolio, orders, True)
_fill_orders(orders, trader)
check_orders(orders, evaluation, state, nb_orders, market_status)
check_portfolio(portfolio, initial_portfolio, orders, True)
fill_orders(orders, trader)
# orders are impossible
orders = order_creator.create_new_order(evaluation, min_trigger_market, exchange, trader, portfolio, state)
_check_orders(orders, evaluation, state, 0, market_status)
_check_portfolio(portfolio, initial_portfolio, orders, True)
_fill_orders(orders, trader)
check_orders(orders, evaluation, state, 0, market_status)
check_portfolio(portfolio, initial_portfolio, orders, True)
fill_orders(orders, trader)

_reset_portfolio(portfolio)
initial_portfolio = portfolio.portfolio
for state in _get_states_gradient_with_invald_states():
for evaluation in _get_irrationnal_numbers():
# orders are possible
orders = order_creator.create_new_order(evaluation, symbol, exchange, trader, portfolio, state)
_check_orders(orders, evaluation, state, nb_orders, market_status)
_check_portfolio(portfolio, initial_portfolio, orders, True)
_fill_orders(orders, trader)
check_orders(orders, evaluation, state, nb_orders, market_status)
check_portfolio(portfolio, initial_portfolio, orders, True)
fill_orders(orders, trader)
# orders are impossible
orders = order_creator.create_new_order(evaluation, min_trigger_market, exchange, trader, portfolio, state)
_check_orders(orders, evaluation, state, 0, market_status)
_check_portfolio(portfolio, initial_portfolio, orders, True)
_fill_orders(orders, trader)
check_orders(orders, evaluation, state, 0, market_status)
check_portfolio(portfolio, initial_portfolio, orders, True)
fill_orders(orders, trader)

_reset_portfolio(portfolio)
initial_portfolio = portfolio.portfolio
for state in _get_states_gradient_with_invald_states():
# orders are possible
orders = order_creator.create_new_order(math.nan, symbol, exchange, trader, portfolio, state)
_check_orders(orders, math.nan, state, nb_orders, market_status)
_check_portfolio(portfolio, initial_portfolio, orders, True)
_fill_orders(orders, trader)
check_orders(orders, math.nan, state, nb_orders, market_status)
check_portfolio(portfolio, initial_portfolio, orders, True)
fill_orders(orders, trader)
# orders are impossible
orders = order_creator.create_new_order(math.nan, min_trigger_market, exchange, trader, portfolio, state)
_check_orders(orders, math.nan, state, 0, market_status)
_check_portfolio(portfolio, initial_portfolio, orders, True)
_fill_orders(orders, trader)
check_orders(orders, math.nan, state, 0, market_status)
check_portfolio(portfolio, initial_portfolio, orders, True)
fill_orders(orders, trader)
Loading

0 comments on commit 3199465

Please sign in to comment.