Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Pinkfish package
#11
(May-16-2020, 06:33 PM)snippsat Wrote:
Quote:Yes there is,so this a Notebook i run as test.
As you see no errors.

this part I have no errors either, error starts the next section.
#i start to have error after i ran this section. 
tlog.cash = capital

import time
t0 = time.time()

"""
# This is the slowest (2.42 s)
for i in range(len(ts.index)):

    date = ts.index[i]
    high = ts['high'][i]
    low = ts['low'][i]
    close = ts['close'][i]
    sma50 = ts['sma50'][i]
    sma200 = ts['sma200'][i]

# This is still slow (2.53 s)
for i, (index, row) in enumerate(ts.iterrows()):

    date = index
    high = row['high']
    low = row['low']
    close = row['close']
    sma50 = row['sma50']
    sma200 = row['sma200']


# using .at[] is fast (832 ms)
for i, index in enumerate(ts.index):

    date = index
    high = ts.at[index, 'high']
    low = ts.at[index, 'low']
    close = ts.at[index, 'close']
    sma50 = ts.at[index, 'sma50']
    sma200 = ts.at[index, 'sma200']

# using itertuples is fastest for looping (378 ms)
for i, row in enumerate(ts.itertuples()):

    date = row.Index.to_pydatetime()
    high = row.high
    low = row.low
    close = row.close
    sma50 = row.sma50
    sma200 = row.sma200
"""

for i, row in enumerate(ts.itertuples()):

    date = row.Index.to_pydatetime()
    high = row.high; low = row.low; close = row.close
    sma50 = row.sma50; sma200 = row.sma200
    end_flag = True if (i == len(ts) - 1) else False
    shares = 0
    
    # close all positions on last trade day
    if end_flag:
        shares = tlog.exit_trade(date, close)
    # buy
    elif (tlog.num_open_trades() == 0
          and row.sma50 > row.sma200 and ts['sma50'][i-1] <= ts['sma200'][i-1]):

        # enter buy in trade log
        shares = tlog.enter_trade(date, close)  
    # sell
    elif (tlog.num_open_trades() > 0
          and sma50 < sma200 and ts['sma50'][i-1] >= ts['sma200'][i-1]):

        # enter sell in trade log
        shares = tlog.exit_trade(date, close)

    if shares > 0:
        print("{0} BUY  {1} {2} @ {3:.2f}".format(
              date, shares, symbol, close))
    elif shares < 0:
        print("{0} SELL {1} {2} @ {3:.2f}".format(
              date, -shares, symbol, close))

    # record daily balance
    dbal.append(date, high, low, close, tlog.shares, tlog.cash)  

t1 = time.time()
total = t1-t0
print(total)
        
Quote:Some step this will create a virtual environment with conda .
I use cmder but commands are just the same in cmd.
You may need to install git
# Make
G:\Anaconda3\Scripts
λ conda create --name pink_env

# Activate
G:\Anaconda3\Scripts
λ activate pink_env

# Cd to pink
(pink_env) G:\Anaconda3\Scripts
λ cd ..

(pink_env) G:\Anaconda3
λ cd envs\pink_env\

(pink_env) G:\Anaconda3
λ cd envs\pink_env\

# Clone Repo
(pink_env) G:\Anaconda3\envs\pink_env
λ git clone https://github.com/fja05680/pinkfish.git

# Remove these 3 from requirements.txt save as req.txt
importlib-metadata==0.18
empyrical==0.5.3
TA-Lib==0.4.17

# Install req.txt
(pink_env) G:\Anaconda3\envs\pink_env\pinkfish (master)
λ conda install --file req.txt

# new file req1.txt
importlib-metadata==0.18
empyrical==0.5.3

# Install req1.txt with pip
(pink_env) G:\Anaconda3\envs\pink_env\pinkfish (master)
λ pip install -r req1.txt

# Install NoteBook
(pink_env) G:\Anaconda3\envs\pink_env\pinkfish (master)
λ conda install -c conda-forge jupyterlab
From gohlke download TA_Lib‑0.4.18‑cp37‑cp37m‑win_amd64.whl
# Install
(pink_env) G:\Anaconda3\envs\pink_env\pinkfish (master)
λ pip install TA_Lib-0.4.18-cp37-cp37m-win_amd64.whl
Processing g:\anaconda3\envs\pink_env\pinkfish\ta_lib-0.4.18-cp37-cp37m-win_amd64.whl
Installing collected packages: TA-Lib
Successfully installed TA-Lib-0.4.18
Finish Pray
# Start Jupyterlab
(pink_env) G:\Anaconda3\envs\pink_env\pinkfish (master)
λ jupyter lab
does the code above I ran in CMD or I put in as python code in main.ipynb ?
I want to double-check first. So I don't run into the same mistake leads to uninstall the anaconda and re-install it.
Thank you very much for your time.
Reply
#12
(May-17-2020, 04:24 PM)buunaanaa Wrote: does the code above I ran in CMD or I put in as python code in main.ipynb ?
I want to double-check first. So I don't run into the same mistake leads to uninstall the anaconda and re-install it.
All in cmd to the start of jupyterlab.
The point of virtual environment is that you can mess up,and it dos not matter at all.
Then there in no re-install of Anaconda,just delete the environment folder and start over again.
So here is the start in cmd,mess up in this case just delete pink_env1 folder and start over.
You start from Script folder where conda is.
Microsoft Windows [Version 10.0.18362.836]
(c) 2019 Microsoft Corporation. Med enerett.

G:\>cd Anaconda3
G:\Anaconda3>cd Scripts

# Make 
G:\Anaconda3\Scripts>conda create --name pink_env1
Collecting package metadata (repodata.json): done
Solving environment: done

## Package Plan ##

  environment location: G:\Anaconda3\envs\pink_env1



Proceed ([y]/n)? y

Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use
#
#     $ conda activate pink_env1
#
# To deactivate an active environment, use
#
#     $ conda deactivate

# Activate see (pink_env1)
G:\Anaconda3\Scripts>activate pink_env1

# Cd to folder
(pink_env1) G:\Anaconda3\Scripts>cd ..
(pink_env1) G:\Anaconda3>cd envs
(pink_env1) G:\Anaconda3\envs>cd pink_env1

# Now the rest as i posted
(pink_env1) G:\Anaconda3\envs\pink_env1>  
Reply
#13
Quote:Try.
#return pd.isnull(self._tlog).any(1).nonzero()[0]
return pd.isnull(self._tlog).any(1).to_numpy().nonzero()[0]
You have been amazing!!!!
Thank you very much. This one worked.
I just realize after edit and save ***.py file, I had to re-start the Kernel in Jupiter notebook in order to make it work.
I am not sure if that's just me.
Reply
#14
Good then it solved with fixing source code,but this can be painful,so look into virtual environment.
Many of these data science stuff like pinkfish which trow together at one time with the use of 40 third-party libraries.

Then some years later someone try to run this in there main Python installation,then the version pain and error starts Doh
So look into virtual environment conda dos a great job here.
Look at this Post where run the whole R-stack(100 of packages) in a conda environment.

Also not running Anaconda,so do Python now comes with virtual environment build in,look at this post.
Reply
#15
Quote:Yes there is,so this a Notebook i run as test.
As you see no errors.
you have been really helpful. I am going through a painful period.
how can you not get any errors?

in this part
full code is here
in this part
for i, row in enumerate(ts.itertuples()):

    date = row.Index.to_pydatetime()
    high = row.high; low = row.low; close = row.close
    sma50 = row.sma50; sma200 = row.sma200
    end_flag = True if (i == len(ts) - 1) else False
    shares = 0
    
    # close all positions on last trade day
    if end_flag:
        shares = tlog.exit_trade(date, close)
    # buy
    elif (tlog.num_open_trades() == 0
          and row.sma50 > row.sma200 and ts['sma50'][i-1] <= ts['sma200'][i-1]):

        # enter buy in trade log
        shares = tlog.enter_trade(date, close)  
    # sell
    elif (tlog.num_open_trades() > 0
          and sma50 < sma200 and ts['sma50'][i-1] >= ts['sma200'][i-1]):

        # enter sell in trade log
        shares = tlog.exit_trade(date, close)

    if shares > 0:
        print("{0} BUY  {1} {2} @ {3:.2f}".format(
              date, shares, symbol, close))
    elif shares < 0:
        print("{0} SELL {1} {2} @ {3:.2f}".format(
              date, -shares, symbol, close))

    # record daily balance
    dbal.append(date, high, low, close, tlog.shares, tlog.cash)  

t1 = time.time()
total = t1-t0
print(total)
shares = tlog.exit_trade(date, close)

and if we go to the tlog.exit_trade()
"""
trade
---------
Assist with trading
"""

# Use future imports for python 3.0 forward compatibility
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import

# Other imports
import pandas as pd

class TradeLog():
    """ trade log """

    def __init__(self):
        columns = ['entry_date', 'entry_price', 'long_short', 'qty',
                   'exit_date', 'exit_price', 'pl_points', 'pl_cash',
                   'cumul_total']
        self._tlog = pd.DataFrame(columns=columns)
        self.shares = 0

    def calc_shares(self, cash, price):
        """ calculate shares and remaining cash before entry """
        shares = int(cash / price)
        cash = cash - shares * price
        return shares, cash

    def calc_cash(self, cash, price, shares):
        """ calculate cash after exit """
        cash = cash + price*shares
        return cash

    def enter_trade(self, entry_date, entry_price, shares, long_short='long'):
        """ record trade entry in trade log """
        d = {'entry_date':entry_date, 'entry_price':entry_price, 'qty':shares, 
             'long_short':long_short}
        tmp = pd.DataFrame([d], columns=self._tlog.columns)
        self._tlog = self._tlog.append(tmp, ignore_index=True)

        # update shares
        if long_short == 'long':
            self.shares += shares
        else:
            self.shares -=shares

    def _get_open_trades(self):
        """ find the "integer" index of rows with NaN """
        return pd.isnull(self._tlog).any(1).to_numpy().nonzero()[0]
    
    def num_open_trades(self):
        """ return number of open orders, i.e. not closed out """
        return len(self._get_open_trades())

    def exit_trade(self, exit_date, exit_price, shares=-1, long_short='long'):
        """ record trade exit in trade log """

        rows = self._get_open_trades()
        idx = rows[0]

        entry_price = self._tlog['entry_price'][idx]
        shares = self._tlog['qty'][idx] if shares == -1 else shares
        pl_points = exit_price - entry_price
        pl_cash = pl_points * shares
        if idx == 0:
            cumul_total = pl_cash
        else:
            cumul_total = self._tlog.ix[idx - 1, 'cumul_total'] + pl_cash

        self._tlog.ix[idx, 'exit_date'] = exit_date
        self._tlog.ix[idx, 'exit_price'] = exit_price
        self._tlog.ix[idx, 'long_short'] = 'long'
        self._tlog.ix[idx, 'pl_points'] = pl_points
        self._tlog.ix[idx, 'pl_cash'] = pl_cash
        self._tlog.ix[idx, 'cumul_total'] = cumul_total

        # update shares
        if long_short == 'long':
            self.shares -= shares
        else:
            self.shares +=shares
        return idx

    def get_log(self):
        """ return Dataframe """
        return self._tlog

class TradeState:
    OPEN, CLOSE, HOLD, CASH = range(0, 4)

class DailyBal:
    """ Log for daily balance """

    def __init__(self):
        self._l = []  # list of daily balance tuples

    def _balance(self, date, high, low, close, shares, cash, state):
        """ calculates daily balance values """
        if state == TradeState.OPEN:
            # date, high, low, close, cash, state
            t = (date, close*shares + cash, close*shares + cash,
                 close*shares + cash, shares, cash, state)
        elif state == TradeState.CLOSE:
            t = (date, high*shares + cash, low*shares + cash,
                 close*shares + cash, shares, cash, state)
        elif state == TradeState.HOLD:
            t = (date, high*shares + cash, low*shares + cash,
                 close*shares + cash, shares, cash, state)
        elif state == TradeState.CASH:
            t = (date, cash, cash, cash,
                 shares, cash, state)
        return t

    def append(self, date, high, low, close, shares, cash, state):
        t = self._balance(date, high, low, close, shares, cash, state)
        self._l.append(t)

    def get_log(self):
        """ return Dataframe """
        columns = ['date', 'high', 'low', 'close', 'shares', 'cash', 'state']
        dbal = pd.DataFrame(self._l, columns=columns)
        dbal.set_index('date', inplace=True)
        return dbal
we can see the following part
def enter_trade(self, entry_date, entry_price, shares, long_short='long'):
def exit_trade(self, exit_date, exit_price, shares=-1, long_short='long'):

 def enter_trade(self, entry_date, entry_price, shares, long_short='long'):
        """ record trade entry in trade log """
        d = {'entry_date':entry_date, 'entry_price':entry_price, 'qty':shares, 
             'long_short':long_short}
        tmp = pd.DataFrame([d], columns=self._tlog.columns)
        self._tlog = self._tlog.append(tmp, ignore_index=True)

        # update shares
        if long_short == 'long':
            self.shares += shares
        else:
            self.shares -=shares

def exit_trade(self, exit_date, exit_price, shares=-1, long_short='long'):
        """ record trade exit in trade log """
 
        rows = self._get_open_trades()
        idx = rows[0]
 
        entry_price = self._tlog['entry_price'][idx]
        shares = self._tlog['qty'][idx] if shares == -1 else shares
        pl_points = exit_price - entry_price
        pl_cash = pl_points * shares
        if idx == 0:
            cumul_total = pl_cash
        else:
            cumul_total = self._tlog.ix[idx - 1, 'cumul_total'] + pl_cash
 
        self._tlog.ix[idx, 'exit_date'] = exit_date
        self._tlog.ix[idx, 'exit_price'] = exit_price
        self._tlog.ix[idx, 'long_short'] = 'long'
        self._tlog.ix[idx, 'pl_points'] = pl_points
        self._tlog.ix[idx, 'pl_cash'] = pl_cash
        self._tlog.ix[idx, 'cumul_total'] = cumul_total
 
        # update shares
        if long_short == 'long':
            self.shares -= shares
        else:
            self.shares +=shares
        return idx
then I get error
Error:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-21-ef62bb3159a8> in <module> 23 24 # enter buy in trade log ---> 25 shares = tlog.enter_trade(date, close) 26 # sell 27 elif (tlog.num_open_trades() > 0 TypeError: enter_trade() missing 1 required positional argument: 'shares'
if I do this, add shares
#tlog.enter_trade(date, close)
tlog.enter_trade(date, close,shares)

error disappears,
but giving me an error about the shares. TypeError: '<' not supported between instances of 'NoneType' and 'int'y
Reply
#16
(May-16-2020, 06:33 PM)snippsat Wrote:
(May-16-2020, 04:48 PM)buunaanaa Wrote: Is there any alternative ?
Yes there is,so this a Notebook i run as test.
As you see no errors.

Some step this will create a virtual environment with conda .
I use cmder but commands are just the same in cmd.
You may need to install git
# Make
G:\Anaconda3\Scripts
λ conda create --name pink_env

# Activate
G:\Anaconda3\Scripts
λ activate pink_env

# Cd to pink
(pink_env) G:\Anaconda3\Scripts
λ cd ..

(pink_env) G:\Anaconda3
λ cd envs\pink_env\

(pink_env) G:\Anaconda3
λ cd envs\pink_env\

# Clone Repo
(pink_env) G:\Anaconda3\envs\pink_env
λ git clone https://github.com/fja05680/pinkfish.git

# Remove these 3 from requirements.txt save as req.txt
importlib-metadata==0.18
empyrical==0.5.3
TA-Lib==0.4.17

# Install req.txt
(pink_env) G:\Anaconda3\envs\pink_env\pinkfish (master)
λ conda install --file req.txt

# new file req1.txt
importlib-metadata==0.18
empyrical==0.5.3

# Install req1.txt with pip
(pink_env) G:\Anaconda3\envs\pink_env\pinkfish (master)
λ pip install -r req1.txt

# Install NoteBook
(pink_env) G:\Anaconda3\envs\pink_env\pinkfish (master)
λ conda install -c conda-forge jupyterlab
From gohlke download TA_Lib‑0.4.18‑cp37‑cp37m‑win_amd64.whl
# Install
(pink_env) G:\Anaconda3\envs\pink_env\pinkfish (master)
λ pip install TA_Lib-0.4.18-cp37-cp37m-win_amd64.whl
Processing g:\anaconda3\envs\pink_env\pinkfish\ta_lib-0.4.18-cp37-cp37m-win_amd64.whl
Installing collected packages: TA-Lib
Successfully installed TA-Lib-0.4.18
Finish Pray
# Start Jupyterlab
(pink_env) G:\Anaconda3\envs\pink_env\pinkfish (master)
λ jupyter lab

I tried this, at the very last step I got an error

Error:
(pink_env) D:\programs\Anaconda3\envs\pink_env\pinkfish>pip install TA_Lib-0.4.18-cp37-cp37m-win_amd64.whl ERROR: TA_Lib-0.4.18-cp37-cp37m-win_amd64.whl is not a supported wheel on this platform.
Reply
#17
Try the 32-bit version TA_Lib‑0.4.18‑cp37‑cp37m‑win32.whl.
conda is pulling down a full python version so make sure you know which version it is.
You test bye typing python the interpreter start.

(May-18-2020, 05:43 PM)buunaanaa Wrote: how can you not get any errors?

in this part
full code is here
There is some error in golden-cross example,this is i'm not gone look into.
As he has maybe updated pinkfish and not this example,there is some mess in his approach.
You can to post and issue on his GitHub Repo,but 0 people has done this,think is more a personal project for him than a solid package that is meant to be used bye a lot people.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020