Giter Club home page Giter Club logo

panifie / pingpong.jl Goto Github PK

View Code? Open in Web Editor NEW
30.0 5.0 6.0 14.16 MB

Cryptocurrency trading bot, and backtesting framework in julia

Home Page: https://panifie.github.io/PingPong.jl/

License: GNU General Public License v3.0

Julia 99.63% Python 0.06% Emacs Lisp 0.06% Dockerfile 0.20% Shell 0.05%
finance backtesting-trading-strategies backtesting ccxt cryptocurrency cryptocurrency-exchanges trading quantitative-trading cryptocurrency-trading-bot trading-bot

pingpong.jl's People

Contributors

femtotrader avatar panbonker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

pingpong.jl's Issues

strictier function signatures

Basically all functions with arguments any combination of Strategy AssetInstance Order Trade etc... have "loose" signatures. Meaning for example that you could call them with arguments where the strategy refers to an exchange, and an asset refers to another...
They would have to be rewritten for example like:

function position!(
    s::IsolatedStrategy{Sim}, ai::MarginInstance, t::PositionTrade{P};
) where {P<:PositionSide}

to

function position!(
    s::Strategy{X,N,E,Isolated,C}, ai::AssetInstance{A,E,Isolated}, t::Trade{O,A,E,P};
) where {X,N,E<:ExchangeID,C,A<:AbstractAsset,O,P<:PositionSide}

Project status

v1

v1 is tagged
The test suite is mostly passing, although there are still 1 or 2 flapping tests.
The pre built images are on the docker registry

v1 will only receive bug fixes and new adhoc functions for better exchange support.

v2

v2 is not currently being worked on, this is a list of things that need to happen for a v2 release and other things that would be nice to have:

required

  • Ccxt gets transpilation support for julia. The main goal of v2 would be to make python optional and not an hard dependency, so all the python ccxt handling would need to be removed
  • Complete wrapping of the interal exchange api into a dedicated ExchangeApi module. Currently it is mostly split into the Exchanges and LiveMode modules. It is fine to model it over the ccxt api but this needs to happen to make ccxt swappable.
  • Dependencies trimming: excluding plotting and optimization which are inevitably dependency heavy we could avoid pulling other packages like DataStructures and instead vendor the used container types. Also telegram support should be made optional.
  • Reduce number of modules: some modules could be merged, like Lang,Misc,TimeTicks Data,Processing SimMode,Executors PaperMode,LiveMode
  • With python made optional, it is worthwhile to perform an analysis for type instabilities using JET.jl

optional

  • With the exchange api wrapped we can (and should) add the hummingbot gateway as addition exchange support
  • Better test suite. Ccxt lacks a self hostable exchange api server for testing purposes which makes it neccessary to test against live exchange testnets this is annoying because of api keys, rate limits, and testnets going down every once in a while, all things causing tests to flap. Also julia mocking seems somewhat buggy, and although we mock some responses in a few tests, mocking can't be used everywhere because we also need to test async behaviour.
  • Overhaul of AssetInstance trades history from a vector of trades to a dataframe, for reasoning see here
  • simplify timeframes package to always and only use Millisecond as time unit
  • reconstructing the orders/trades history from the exchange with leverage and margin. (Currently exchanges don't have apis for position history)
  • rename: (abstract)asset -> (abstract)instrument, assetinstance -> market

Profitability calculator

Some strategies work based on past profitability, so they require a way to calc the profits of previous trades. Because ping pong does not make assumptions about execution of trades (buys and sells are not necessarily interleaved) a module for ensuring that the strategy executes only 1 trade at a time is required. And the method to track profitability should be implemented in such module

deprecate PairData

Remove the PairData type, and instead rely on DataFrames metadata for info.

Packages still missing precompiles

  • Watchers
  • Sim/Paper/Live mode
  • Cli
  • Engine
  • Executors
  • Instances
  • Collections
  • OrderTypes
  • Simulations
  • Stats
  • Strategies
  • Plotting
  • Exchanges
  • Fetch

Performance tweaks

backtest

  • There are many repeated function calls like openat,closeat,etc... that could be memoized
  • Consider either removing getproperty for asset instances and strategies or replace all dot accessors within SimMode with some getfield wrapper function. Because the getproperty accessor is slower than getfield if it is customized
  • an alternative implementation for orders/trades would use arrays instead of structs to be more allocation friendly

watchers

  • StructArrays or TypedTables could be used when fetching (streaming) ohlcv data feeds
  • OHLCV watcher implementations parse the whole python dicts into named tuples (CcxtTrade, CcxtTicker), in cases where full parsing is not required, the python data should be parsed more lazily

other

  • Scour the codebase for lazy use of @view/s on assignments, that should be replaced with copyto! (starting from Data)
  • search/replace Period with FixedPeriod to see if union splitting improves performance
  • Full specialization: many functions signatures are defined over generic types (non fully parametrized), benchmarks are needed to assert if full specialization is worth the extra compilation time / bin size

bn.binancedownload(pairs) raises ERROR: ArgumentError: No symbols found matching SubString{String}["BTC/USDT", "ETH/USDT", "SOL/USDT"]

Hello,

Currently following documentation but

julia> using PingPong

julia> @environment!

julia> s = st.strategy(:Example)
Name: Example (Sim)
Config: No Margin, 10.0(USDT)(Base Size), 100.0(USDT)(Initial Cash)
Universe: 3 instances, 1 exchanges
Trades: 0 ~ 0(longs) ~ 0(shorts) ~ 0(liquidations)
Holdings: 0
Pending buys: 0
Pending sells: 0
USDT: 100.0 (on phemex) (Cash)
USDT: 100.0 (Total)

julia> pairs = im.raw.(s.universe.data.asset)
3-element Vector{SubString{String}}:
 "BTC/USDT"
 "ETH/USDT"
 "SOL/USDT"

julia> using Scrapers: Scrapers as scr

julia> const bn = scr.BinanceData
Scrapers.BinanceData

julia> bn.binancedownload(pairs)
ERROR: ArgumentError: No symbols found matching SubString{String}["BTC/USDT", "ETH/USDT", "SOL/USDT"]
Stacktrace:
 [1] binancedownload(syms::Vector{…}; zi::Data.ZarrInstance{…}, quote_currency::String, reset::Bool, kwargs::@Kwargs{})
   @ Scrapers.BinanceData /pingpong/Scrapers/src/binance.jl:239
 [2] binancedownload(syms::Vector{SubString{String}})
   @ Scrapers.BinanceData /pingpong/Scrapers/src/binance.jl:233
 [3] top-level scope
   @ REPL[7]:1
Some type information was truncated. Use `show(err)` to see complete types.

Missing functionalities

Isolated margin

  • Funding rate estimation (currently we just use higher trading fees)
  • Updating margin of open positions
  • Updating leverage of open positions (and also with pending orders)

Margin

  • borrow/repay

Execution

  • Take profit and stop loss attached to orders

backtest interactivity

The backtest could be made more interactive by either:

  • (terminal) use a progress bar (which we already have used for other things like scrapers)
  • (graphical) update a makie chart in realtime as the backtest progresses

things that I am not particularly happy about

  • The split of buy/sell orders into long/short, which doubles every downstream type into long/short. This is necessary to support hedged position management, but I don't think I will ever implement it since I use isolated, so I might have just chosen to not support it and simplify the types
  • The sign handling for long/short amounts. Initially It was all positive numbers, but then I thought turning the sign negative for shorts would reduce the amount of errors, maybe it did (?) but now a short sell gains "negative cash" and a short buy reduces negative cash to zero 😕
  • The fully "expanded" orders and trades structures, that could be made more array friendly. This is covered here
  • The exchange api creeping into many packages, now ccxt is kind of an hard dep
  • Pythonisms creeping into the exchange api. If ever ccxt gets julia support, the switch to native julia will not be so trivial
  • this issue being a glass half empty kind of issue

Docker container

Make dockerfile with prebuilt packages, consider static compilation

GPUStrategy

The main goal of this would be to allow to backtesting runs on a GPU, and in particular allow to run backtests using online jupyter instances that offer GPU computing like colab or kaggle.
Since we mostly target online notebooks, and they are all nvidia, we would be using CUDA.jl

Making the backtest GPU compatible mostly means building structure adaptors for these types:

  • Strategy
  • Exchange
  • AssetInstance
  • DataFrame
  • Context

The Exchange type is a wrapper for a ccxt exchange, it is already discouraged to call python from a strategy, and the backtest itself never calls any python code, so this is not an issue per se, however it should be made abudantly clear in the documentation that a GPUStrategy cannot use python code.

This is however not enough:
To achieve parallelizability we have to run 1 backtest per GPU core, which means that the strategy has to be implemented as a kernel, in particular the main ping! function and whatever the function calls, needs to be a kernel. Of course we should provide example implementations and warn about the complexities of gpu programming.

POC with all modules merged

A test should be done to compare loading times between a repository version where everything is imported from one main modules and compare it to the current multi project version

Assets types

Symbols are currently parsed through some regex. We could instead query ccxt.market["info"]
Ccxt also provides the feeCurrency but is not necessarily useful for backtesting as much as for live trading

add support for zarr subgroups

currently all arrays are stored in a flat structure in the ZarrInstance main group, whereas they should be saved according to their path in a subgroup

Data management

Currently we only consider the executor under the pingpong model. That is that the strategy has to deal with its own data feeds.

If the pingpong model also accounted for data updates, a pong! call within the strategy could branch into a Watcher instance in live mode and a prefetched dataframe in sim mode.

However since a strategy has always carte blanche, the benefits of managing data for the strategy are very small (we can't manage every piece of data, so managing only a few doesn't improve the status quo).

Moreover the main ping! function works with a timestamp as primary input, so there is never any ambiguity on the time context of execution and whatever data the strategy uses, should already be time context aware because of this.

watchers as abstract types

  • make the Watcher an abstract subtype of the Rocket actor
  • refactor watcher implementations as concrete subtypes of the Watcher abstract type

Simulators

  • Spread: always enabled
  • Slippage: for large trades
  • Market impact: for very large trades

Avoid ccxt candles emulation

Using watchers, when fetching candles, we call fetchOHLCV et similar, but in case candles are emulated we shouldn't call it, and instead process from trades directly since we already do it in other cases. So we have to ensure exc.has["fetchOHCLV"] is not emulated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.