6. Market Orders

This section covers market orders, the most simple yet equally important order type.

In [1]:
import fxcmpy
import pandas as pd
import datetime as dt
con = fxcmpy.fxcmpy(config_file='fxcm.cfg')

6.1. Placing Orders

Before one gets started, a check of the open positions might be helpful.

In [2]:
con.get_open_positions().T
Out[2]:

Currently, there are no open positions. To place orders, one can use the methods con.create_market_sell_order() or con.create_market_buy_order(), respectively.

In [3]:
order = con.create_market_sell_order('EUR/USD', 100)
In [4]:
order = con.create_market_buy_order('USD/JPY', 200)

The new open positions table might then look as follows. Two new positions have been created.

In [5]:
con.get_open_positions().T
Out[5]:
0 1
accountId 2815291 2815291
accountName 02815291 02815291
amountK 100 200
close 1.17701 110.152
com 0 0
currency EUR/USD USD/JPY
currencyPoint 10 18.155
grossPL -4 -39.9448
isBuy False True
isDisabled False False
limit 0 0
open 1.17697 110.174
ratePrecision 5 3
roll 0 0
stop 0 0
stopMove 0 0
t 1 1
time 06062018104125 06062018104127
tradeId 178067111 178067131
usedMargin 1300 2000
valueDate
visiblePL -0.4 -2.2

6.2. General Market Orders

fxcmpy allows to place more complex orders, this can be done with the method con.open_trade(). A detailed description of the meaning of the parameters is found in the FXCM API Documentation.

In [6]:
order = con.open_trade(symbol='USD/JPY', is_buy=True,
                       rate=105, is_in_pips=False,
                       amount='1000', time_in_force='GTC',
                       order_type='AtMarket', limit=120)
In [7]:
con.get_open_positions().T
Out[7]:
0 1 2
accountId 2815291 2815291 2815291
accountName 02815291 02815291 02815291
amountK 100 200 1000
close 1.17711 110.152 110.152
com 0 0 0
currency EUR/USD USD/JPY USD/JPY
currencyPoint 10 18.1551 90.7754
grossPL -14 -39.9448 -190.646
isBuy False True True
isDisabled False False False
limit 0 0 120
open 1.17697 110.174 110.173
ratePrecision 5 3 3
roll 0 0 0
stop 0 0 0
stopMove 0 0 0
t 1 1 1
time 06062018104125 06062018104127 06062018104147
tradeId 178067111 178067131 178067210
usedMargin 1300 2000 10000
valueDate
visiblePL -1.4 -2.2 -2.1

6.3. Trade Ids

Every position has the attribute tradeId, here it is the column named tradeId of the DataFrame object returned by con.get_open_positions().

In [8]:
con.get_open_positions()['tradeId']
Out[8]:
0    178067111
1    178067131
2    178067210
Name: tradeId, dtype: object

fxcmpy provides methods to get the trade tradeIds directly.

In [9]:
con.get_open_trade_ids()
Out[9]:
[178067111, 178067131, 178067210]
In [10]:
con.get_closed_trade_ids()
Out[10]:
[178066615,
 178066381,
 178064934,
 178064922,
 167729381,
 144240844,
 97729921,
 97601524,
 97599708]
In [11]:
con.get_all_trade_ids()
Out[11]:
[97599708,
 97601524,
 97729921,
 144240844,
 167729381,
 178064922,
 178064934,
 178066381,
 178066615,
 178067111,
 178067131,
 178067210]

6.4. Editing Market Orders

To modify a trade, you need the tradeId value.

In [12]:
tradeId = con.get_open_trade_ids()[-1]

To change the trade’s stop or limit rate, one can use the change_trade_stop_limit() method.

In [13]:
con.change_trade_stop_limit(tradeId, is_in_pips=False,
                            is_stop=False, rate=115)

As seen below, the limit rate of the last trade has changed to 115.

In [14]:
con.get_open_positions().T
Out[14]:
0 1 2
accountId 2815291 2815291 2815291
accountName 02815291 02815291 02815291
amountK 100 200 1000
close 1.17708 110.144 110.144
com 0 0 0
currency EUR/USD USD/JPY USD/JPY
currencyPoint 10 18.1564 90.782
grossPL -11 -54.4741 -263.292
isBuy False True True
isDisabled False False False
limit 0 0 115
open 1.17697 110.174 110.173
ratePrecision 5 3 3
roll 0 0 0
stop 0 0 0
stopMove 0 0 0
t 1 1 1
time 06062018104125 06062018104127 06062018104147
tradeId 178067111 178067131 178067210
usedMargin 1300 2000 10000
valueDate
visiblePL -1.1 -3 -2.9

6.5. Closing Positions

Positions can be closed individually via the tradeId

In [15]:
con.close_trade(trade_id=tradeId, amount=1000)
In [16]:
con.get_open_positions().T
Out[16]:
0 1
accountId 2815291 2815291
accountName 02815291 02815291
amountK 100 200
close 1.17718 110.145
com 0 0
currency EUR/USD USD/JPY
currencyPoint 10 18.1562
grossPL -21 -52.6579
isBuy False True
isDisabled False False
limit 0 0
open 1.17697 110.174
ratePrecision 5 3
roll 0 0
stop 0 0
stopMove 0 0
t 1 1
time 06062018104125 06062018104127
tradeId 178067111 178067131
usedMargin 1300 2000
valueDate
visiblePL -2.1 -2.9

… or for all positions in an instrument …

In [17]:
con.close_all_for_symbol('EUR/USD')
In [18]:
con.get_open_positions().T
Out[18]:
0
accountId 2815291
accountName 02815291
amountK 200
close 110.146
com 0
currency USD/JPY
currencyPoint 18.156
grossPL -50.8416
isBuy True
isDisabled False
limit 0
open 110.174
ratePrecision 3
roll 0
stop 0
stopMove 0
t 1
time 06062018104127
tradeId 178067131
usedMargin 2000
valueDate
visiblePL -2.8

… or simply for all positions over all instruments.

In [19]:
con.close_all()

After this method call, there are naturally no open positions left.

In [20]:
con.get_open_positions()
Out[20]:

The closed positions are found in the table returned by con.get_closed_postions().

In [21]:
con.get_closed_positions().T
Out[21]:
0 1 2 3 4 5 6 7 8 9 10 11
accountName 02815291 02815291 02815291 02815291 02815291 02815291 02815291 02815291 02815291 02815291 02815291 02815291
amountK 100 1000 200 100 100 300 300 300 300 1000 100 200
close 1.17675 110.141 110.142 1.17663 1.17663 1.34273 1.34273 1.34273 1.34273 110.14 1.17726 110.151
closeTime 06062018103855 06062018103633 06062018103648 06062018103638 06062018103638 06062018101450 06062018101450 06062018101450 06062018101450 06062018104240 06062018104247 06062018104258
com 0 0 0 0 0 0 0 0 0 0 0 0
currency EUR/USD USD/JPY USD/JPY EUR/USD EUR/USD GBP/USD GBP/USD GBP/USD GBP/USD USD/JPY EUR/USD USD/JPY
currencyPoint 10 90.7725 18.1545 10 10 30 30 30 30 90.7725 10 18.1545
grossPL -22 -245.14 -23.61 -30 5493 -5181 -5181 -5181 -5181 -299.62 -29 -41.76
isBuy False True True False False True True True True True False True
open 1.17653 110.168 110.155 1.17633 1.23156 1.36 1.36 1.36 1.36 110.173 1.17697 110.174
openTime 06062018103758 06062018103549 06062018102959 06062018102957 04092018133045 05012018145207 05012018145207 05012018145207 05012018145207 06062018104147 06062018104125 06062018104127
ratePrecision 5 3 3 5 5 5 5 5 5 3 5 3
roll 0 0 0 0 286.36 -821.85 -821.85 -821.85 -821.85 0 0 0
t 2 2 2 2 2 2 2 2 2 2 2 2
tradeId 178066615 178066381 178064934 178064922 167729381 144240844 97729921 97601524 97599708 178067210 178067111 178067131
valueDate
visiblePL -2.2 -2.7 -1.3 -3 549.3 -172.7 -172.7 -172.7 -172.7 -3.3 -2.9 -2.3

6.6. The fxcmpy_open_position Class

For convenience, fxcmpy provides a class called fxcmpy_open_positions. All open positions are stored in the attribute fxcmpy.open_pos, a dictionary with the position’s tradeId as key and the fxcmpy_open_position instance as value. Since there are no open positions left, the dict object is empty.

In [22]:
con.open_pos
Out[22]:
{}

Therefore, create an order …

In [23]:
order = con.create_market_sell_order('EUR/USD', 100)

… to see the fxcmpy_open_position objects in the dict object.

In [24]:
con.open_pos
Out[24]:
{178067413: <fxcmpy.fxcmpy_open_position.fxcmpy_open_position at 0x7f9dd8447f98>}

To get a single fxcmpy_open_position object, one can use con.get_open_position().

In [25]:
tradeId = con.get_open_trade_ids()[0]
In [26]:
pos = con.get_open_position(tradeId)
In [27]:
pos
Out[27]:
<fxcmpy.fxcmpy_open_position.fxcmpy_open_position at 0x7f9dd8447f98>
In [28]:
print(pos)
accountId:        2815291
accountName:      02815291
amountK:          100
close:            1.17731
com:              0
currency:         EUR/USD
currencyPoint:    10
grossPL:          -26
isBuy:            False
isDisabled:       False
limit:            0
open:             1.17705
roll:             0
stop:             0
stopMove:         0
time:             2018-06-06 10:43:12
tradeId:          178067413
usedMargin:       1300
valueDate:
visiblePL:        -2.6

The fxcmpy_open_position object has get methods for all of its attributes, for example:

In [29]:
pos.get_amount()
Out[29]:
100
In [30]:
pos.get_currency()
Out[30]:
'EUR/USD'

Close the position with the pos.close() method.

In [31]:
pos.close()
In [32]:
con.get_open_positions()
Out[32]:
In [33]:
con.close()