Look at the book and if the book is thin (that is to say, even a few hundred dollars worth of crypto would cause price to slip beyond 50+ basis points, submit orders to provide liquidity on that pair.

As price moves, adjust the orders as required, always staying 50-300 basis points away from the mid point of the price quote.

Once I eventually get a fill, post orders at the midpoint price plus 5 or 10 bps of premium to get out of the positions exposure. I'd give up a little profit here just to get out of the position quickly so I can immediately re-post my off-market orders and provide more liquidity. This was because these spikes of price / orders would sometimes come in quick succession.

If another large order joins the book near my limit orders, I couldn't sit further away from the market price than them, as the larger order would absorb the order flow I was trying to capture. So once other large orders on the book were detected, the algo would get in front of them by a few ticks. Sometimes this meant fighting with another trader who was also trying to do the very thing I was doing (competition,) and sometimes this meant we'd just be repricing ourselves until there was not as much profit to be made. How to manage this was a fun meta-game of this strategy.

EDIT: I will give more info on the algo itself in python:

Challenges and how I solved them quick and dirty with python:​

* How do we know the true market price if Coinfield's own price quotes reflect the off market prints? Two ways: pull data from Binance as a reference, and average (smooth out) Coinfields own prices since any given price spike won't affect the average as drastically as natural price movements. Basically.. capture multiple types of quotes from multiple sources and smooth it all out. Here is the logic I used on all incoming quote changes:​

Code: def OnQuote(self): # if any data is missing from the quote feed (ie, not yet populated) just return if type(self.L1[self.data_feed][self.settings["alt_quote"]]['AskPrice']) != str: return if type(self.L1[self.data_feed][self.symbol]['AskPrice']) != str: return fprices = [self.Mid(), self.Last(), ] # adding midpoint and last to recent prices if 'None' not in self.settings['alt_quote']: # alt quote would be an external source like Binance fprices.append(self.rounder(self.Mid(sym=self.settings["alt_quote"])*float(self.settings["ex_rate"]))) if self.inst_fair_price != self.rounder(s.mean(fprices)): self.inst_fair_price = self.rounder(s.mean(fprices)) self.fair_store.append(self.inst_fair_price) self.fair_price = self.rounder(s.mean(self.fair_store)) # don't start until smoothed fair price can be fully calc'd # I can use == here since the fair_store variable is a deque list if len(self.fair_store) == int(self.settings['fair_price_smoothing']): # engage agents that manage orders and positions on each tick once quotes have populated self.Passive_agent() self.Profit_agent() else: self.log.info("Start up, Collecting quotes: {} of {}".format(len(self.fair_store), int(self.settings['fair_price_smoothing'])))

* How can I make the order handling dead simple? How can I have two different agents running in the same thread not step on each other's toes? This one was simple, I just used local variables that other parts of the strategy referenced and used. Here's the first few lines of my profit agent method that worked with some of the strategy object's variables to help manage things. Basically there's order statuses that signal the profit agent's TP orders have been filled or changed and need adjusting:​

Code: def Profit_agent(self): end_game_orders = ['Filled', 'Cancelled', 'Rejected'] if self.nbbo_working_buy_oid: if self.OrderStatus(self.nbbo_working_buy_oid) in end_game_orders: self.passive_working_buy_partial -= float(self.ORD[self.nbbo_working_buy_oid]['FilledSize']) self.nbbo_working_buy_oid = None self.nbbo_working_buy_price = None elif self.rounder(self.fair_price + (self.fair_price * self.bp_aggressive)) > self.nbbo_working_buy_price: self.cancel(self.nbbo_working_buy_oid) else: pass

Obviously the code snippets above are crude and incomplete, but it gives you an idea of how fast I cobbled together something that would do the job. It doesn't need to be elegant, not every job worth doing is worth doing well, it just needs to work.​

​

I’m about to talk about something most traders would keep a secret as long as possible. I’m about to explain, in detail, how even a small retail trader can take advantage of market making and arbitrage strategies in crypto markets.And it starts with a Canadian crypto exchange named Coinfield… Nearly 3 quarters of a year ago I stumbled upon something interesting.XRP --that beloved crypto started by Ripple-- had been making rounds in the news as supporters took to social media and demanded XRP be listed on more crypto exchanges. It was kinda funny, the social media buzz was so strong many thought it was an organized marketing ploy to push XRP, and even gave a nick name to the droves of twitter accounts who’d swarm in whenever XRP was mentioned: the XRP army. But I digress… Some companies took advantage of the social media buzz and started catering to XRP fans by offering special deals for trading in XRP, or heck, even just announcing your company was going to support XRP in one way, shape, for form would get you plenty of attention.Coinfiled jumped in the mix and announced free balance / wallet transfers inbound and outbound so long as they were in XRP. As well, Coinfield offered reduced XRP trading fees when XRP was being traded on their exchange. (This promo has since been adjusted.) It was a good play, and many people retweeted, shared, liked, and projected this across the net, giving Coinfield much exposure (and presumably many new signups.) It also got me to dig a bit deeper into Coinfield’s offering. Being a fellow Canadian and all it was the least I could do.And then I noticed patterns like this:At first I thought this was just a bad data feed. After all, they were using TradingView’s charting library but with their own custom data source, so it’s entirely likely a bad “tick” might pop up here and there should their implementation of TradingView's library be a bit off... But I just knew I had to dig deeper.or here..some trades seemed to be trading away from the prevailing market price around other exchanges. But was it real volume? Or maybe it was just a delayed print? Some other data feed gone bad? Nope, look closely, the lead up to a peek price on any given spike fills earlier prices in the book. These were micro swipes of multiple levels at once!I want to be very clear here. Coinfield wasn’t doing anything bad.. they simply were processing market orders (or marketable limit orders) that were for a size the NBBO couldn’t fill all at once. Punch-happy retail traders were disregarding the liquidity available and just buying/selling blind into the market available. This was (and still is) any market maker’s dream; order flow willing to pay a premium in price to get the liquidity they demand.I manually set out orders to see if I could interact with such order flow just in case it was all a data glitch, and pleasantly I started getting fills!If you’re not following along so far, let me spell it out: Retail (or some other type) of order flow hitting Coinfield's exchange was cutting into the book, and since the underlying price of XRP or other instruments weren’t changing, once you got the fill at seemingly off-market rates, all you had to do was trade out of your new position at the fair market price. Rinse and repeat…I grew my account by 31% within a few weeks just doing this manually and then via an algo with small positions. Given this was a pure arb, and I was just providing liquidity, this return was a very attractive return!This is the PDF account statement Coinfield emails you at the end of each month. All on the same day in February of 2019...This wasXRP/CAD, I also was running this strat on 5 or 6 other pairs that month.Guess what?chart and time of sales examples given in this article are fromThe arb is still going strong as it has been for the last year I've been messing with it.Obviously using a bot to provide liquidity and capture the arb was my best bet, so I wrote one. The bot's logic was very crude and simple:The code I wrote wasn't complicated. It was written in Python and runs on my own custom algo platform that I created from scratch. I won't be providing the full code here for obvious reasons -- seriously, this is a learning experience, take advantage of it and use what I'm telling you here as motivation to grind out a trading algo --but I've described the basic logic in a way that anyone, even a novice, can whip up something comparable in a very short period of time. Coinfield offers a restful API and working with it is pretty simple. However, I do wish they'd create a demo environment for the API; I had to do all my initial development and testing in live markets which isn't always fun. Once you sign up, just request API access via chat and a customer service rep will link you the documentation and details.So why am I telling you all this? Won't this just create more competition and the arb opportunity will be reduced? Sure, I expect a little of that. However, this was a great andexample of something I see many new algo traders talk about but few actually pull off in a practical way. This article was about the process of investigating, planning, and executing a simple butalgo... Put bluntly, many wannabe quants are data mining years worth of historical price data looking for arbs.. only to find false positive and dashed hopes. And yet here we found a pure arb with nothing more than a pair of eyes and some understanding of how exchanges and order matching works. Not to mention the barrier to entry on Coinfield is so minimal just about any retail trader can join in and give it a shot.Will you step up? Will you sign up and start capturing some decent fills? Or are you just going to read yet another crypto article and daydream about trading?This whole example is also a way to look through other exchanges who might be exhibiting the same behavior! This isn't just some crafted article meant to indirectly capture referrals to Coinfield. The process here is the same as I would apply to any exchange should I see the same order flow take place.Want another perk? Sign up for a Coinfield account through this link I hope you found this interesting! Trade well!----I gave up some edge in hopes people can learn from this example, so if you found this helpful or went out and made money with this method and would like to thank me, below are a few donation addresses:35S3bzNRZyWhPganBNRncqjPDq2jTmkHSa0x00099a47b2e0e09b044749D782F05557aF77d29FrL8HjBMEcNwQBbdegJDmBVqhwp3iqj5vN9Thank you,Jack Larkin